31#if !(defined(_ANDROID))
39#include <libFreeWRL.h>
42#include <X11/cursorfont.h>
54int quadbuff_stereo_mode;
66XSetWindowAttributes attr;
67unsigned long mask = 0;
70long event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask |
71 ButtonMotionMask | ButtonReleaseMask |
72 ExposureMask | StructureNotifyMask |
80int oldx = 0, oldy = 0;
82XF86VidModeModeInfo **vmode_modes = NULL;
83int vmode_mode_selected = -1;
88static int mode_cmp(
const void *pa,
const void *pb)
90 XF86VidModeModeInfo *a = *(XF86VidModeModeInfo**)pa;
91 XF86VidModeModeInfo *b = *(XF86VidModeModeInfo**)pb;
92 if(a->hdisplay > b->hdisplay)
return -1;
93 return b->vdisplay - a->vdisplay;
96void fv_switch_to_mode(
int i)
98 if ((!vmode_modes) || (i<0)) {
99 ERROR_MSG(
"fv_switch_to_mode: no valid mode available.\n");
103 vmode_mode_selected = i;
105 win_width = vmode_modes[i]->hdisplay;
106 win_height = vmode_modes[i]->vdisplay;
107 TRACE_MSG(
"fv_switch_to_mode: mode selected: %d (%d,%d).\n",
108 vmode_mode_selected, win_width, win_height);
109 XF86VidModeSwitchToMode(Xdpy, Xscreen, vmode_modes[i]);
110 XF86VidModeSetViewPort(Xdpy, Xscreen, 0, 0);
117XVisualInfo *fv_find_best_visual()
119 XVisualInfo *vi = NULL;
120#define DEFAULT_COMPONENT_WEIGHT 5
127 static int attribs[100] = {
130 GLX_RED_SIZE, DEFAULT_COMPONENT_WEIGHT,
131 GLX_GREEN_SIZE, DEFAULT_COMPONENT_WEIGHT,
132 GLX_BLUE_SIZE, DEFAULT_COMPONENT_WEIGHT,
133 GLX_ALPHA_SIZE, DEFAULT_COMPONENT_WEIGHT,
134 GLX_DEPTH_SIZE, DEFAULT_COMPONENT_WEIGHT,
138 if (shutterGlasses) {
141 system(STEREOCOMMAND);
145 if ((shutterGlasses) && (quadbuff_stereo_mode == 0)) {
146 TRACE_MSG(
"Warning: No quadbuffer stereo visual found !");
147 TRACE_MSG(
"On SGI IRIX systems read 'man setmon' or 'man xsetmon'\n");
150 quadbuff_stereo_mode = 0;
152 vi = glXChooseVisual(Xdpy, Xscreen, attribs);
156static int fv_catch_XLIB(Display *disp, XErrorEvent *err)
158 static int XLIB_errors = 0;
159 static char error_msg[4096];
161 XGetErrorText(disp, err->error_code, error_msg,
sizeof(error_msg));
163 ERROR_MSG(
"FreeWRL caught an XLib error !\n"
164 " Display: %s (%p)\n"
168 XDisplayName(NULL), disp, err->error_code,
169 error_msg, err->request_code);
172 if (XLIB_errors > 20) {
173 ERROR_MSG(
"FreeWRL - too many XLib errors (%d>20), exiting...\n", XLIB_errors);
179int fv_create_colormap()
181 colormap = XCreateColormap(Xdpy, RootWindow(Xdpy, Xvi->screen),Xvi->visual, AllocNone);
191void fv_resetGeometry()
193#ifdef HAVE_XF86_VMODE
197 XF86VidModeGetAllModeLines(Xdpy, Xscreen, &vmode_nb_modes, &vmode_modes);
200 for (i=0; i < vmode_nb_modes; i++) {
201 if ((vmode_modes[i]->hdisplay == oldx) && (vmode_modes[i]->vdisplay==oldy)) {
207 XF86VidModeSwitchToMode(Xdpy, Xscreen, vmode_modes[oldMode]);
208 XF86VidModeSetViewPort(Xdpy, Xscreen, 0, 0);
228 display = getenv(
"DISPLAY");
229 Xdpy = XOpenDisplay(display);
231 ERROR_MSG(
"can't open display %s.\n", display);
238 XSetErrorHandler(fv_catch_XLIB);
240 Xscreen = DefaultScreen(Xdpy);
241 Xroot_window = RootWindow(Xdpy,Xscreen);
245 Xvi = fv_find_best_visual();
247 ERROR_MSG(
"FreeWRL can not find an appropriate visual from GLX\n");
254#ifdef HAVE_XF86_VMODE
256 if (vmode_modes == NULL) {
257 if (XF86VidModeGetAllModeLines(Xdpy, Xscreen, &vmode_nb_modes, &vmode_modes) == 0) {
258 ERROR_MSG(
"can`t get mode lines through XF86VidModeGetAllModeLines.\n");
261 qsort(vmode_modes, vmode_nb_modes,
sizeof(XF86VidModeModeInfo*), mode_cmp);
263 for (i = 0; i < vmode_nb_modes; i++) {
264 if (vmode_modes[i]->hdisplay <= win_width && vmode_modes[i]->vdisplay <= win_height) {
265 fv_switch_to_mode(i);
274 fv_create_colormap();
288bool fv_create_GLcontext()
290 int direct_rendering = TRUE;
294#if defined(TARGET_X11) || defined(TARGET_MOTIF)
296 GLcx = glXCreateContext(Xdpy, Xvi, NULL, direct_rendering);
298 ERROR_MSG(
"can't create OpenGL context.\n");
301 if (glXIsDirect(Xdpy, GLcx)) {
302 TRACE_MSG(
"glX: direct rendering enabled\n");
309 GLXContext share_context;
310 int direct_rendering = TRUE;
311 share_context = NULL;
312 if(share) share_context = share->context;
316#if defined(TARGET_X11) || defined(TARGET_MOTIF)
318 GLcx = glXCreateContext(Xdpy, Xvi, share_context, direct_rendering);
320 ERROR_MSG(
"can't create OpenGL context.\n");
323 if (glXIsDirect(Xdpy, GLcx)) {
324 TRACE_MSG(
"glX: direct rendering enabled\n");
333bool fv_bind_GLcontext()
337#if defined(TARGET_X11) || defined(TARGET_MOTIF)
339 ERROR_MSG(
"window not initialized, can't initialize OpenGL context.\n");
342 if (!glXMakeCurrent(Xdpy, GLwin, GLcx)) {
346 ERROR_MSG(
"fv_bind_GLcontext: can't set OpenGL context for this thread %d , glGetError=%d).\n", fw_thread_id(), glGetError());
364 arrowc = XCreateFontCursor(Xdpy,XC_arrow);
365 sensorc = XCreateFontCursor(Xdpy,XC_hand1);
372void setCursor(
int ccurse)
375 case SCURSE: cursor = sensorc;
break;
376 case ACURSE: cursor = arrowc;
break;
378 DEBUG_MSG(
"setCursor: invalid value for ccurse: %d\n", ccurse);
380 XDefineCursor(Xdpy, GLwin, cursor);
385 XStoreName(Xdpy, Xwin, getWindowTitle());
386 XSetIconName(Xdpy, Xwin, getWindowTitle());
400 if (!fv_open_display()) {
401 printf(
"open_display failed\n");
405 if (!fv_create_GLcontext1(share)) {
406 printf(
"create_GLcontext failed\n");
409 fv_create_main_window(params);
413 params->context = GLcx;
414 params->display = Xdpy;
417 params->surface = (
void*) GLwin;
425 glXMakeCurrent(d->display,
430 glXSwapBuffers(d->display,
431 (Window) d->surface);
434#define TRY_MAINLOOP_STUFF_HERE 1
435#ifdef TRY_MAINLOOP_STUFF_HERE
437#define PHOME_KEY XK_Home
438#define PPGDN_KEY XK_Page_Down
439#define PLEFT_KEY XK_Left
440#define PEND_KEY XK_End
442#define PRIGHT_KEY XK_Right
443#define PPGUP_KEY XK_Page_Up
444#define PDOWN_KEY XK_Down
446#define PF12_KEY XK_F12
447#define PALT_KEY XK_Alt_L
448#define PALT_KEYR XK_Alt_R
449#define PCTL_KEY XK_Control_L
450#define PCTL_KEYR XK_Control_R
451#define PSFT_KEY XK_Shift_L
452#define PSFT_KEYR XK_Shift_R
453#define PDEL_KEY XK_Delete
454#define PNUM0 XK_KP_Insert
455#define PNUM1 XK_KP_End
456#define PNUM2 XK_KP_Down
457#define PNUM3 XK_KP_Page_Down
458#define PNUM4 XK_KP_Left
459#define PNUM5 XK_KP_Begin
460#define PNUM6 XK_KP_Right
461#define PNUM7 XK_KP_Home
462#define PNUM8 XK_KP_Up
463#define PNUM9 XK_KP_Page_Up
464#define PNUMDEC XK_KP_Delete
507int platform2web3dActionKeyLINUX(
int platformKey)
512 if(platformKey >= PF1_KEY && platformKey <= PF12_KEY)
513 key = platformKey - PF1_KEY + F1_KEY;
518 key = HOME_KEY;
break;
520 key = END_KEY;
break;
522 key = PGDN_KEY;
break;
524 key = PGUP_KEY;
break;
528 key = DOWN_KEY;
break;
530 key = LEFT_KEY;
break;
532 key = RIGHT_KEY;
break;
534 key = DEL_KEY;
break;
537 key = ALT_KEY;
break;
540 key = CTL_KEY;
break;
543 key = SFT_KEY;
break;
573void handle_Xevents(XEvent event) {
577 KeySym ks, ksraw, ksupper, kslower;
580 int keysyms_per_keycode_return;
583 int actionKey, windex;
591 switch (event.type) {
592 case ConfigureNotify: printf (
"Event: ConfigureNotify\n");
break;
593 case ClientMessage: printf (
"Event: ClientMessage\n");
break;
594 case KeyPress: printf (
"Event: KeyPress\n");
break;
595 case KeyRelease: printf (
"Event: KeyRelease\n");
break;
596 case ButtonPress: printf (
"Event: ButtonPress\n");
break;
597 case ButtonRelease: printf (
"Event: ButtonRelease\n");
break;
598 case MotionNotify: printf (
"Event: MotionNotify\n");
break;
599 case MapNotify: printf (
"Event: MapNotify\n");
break;
600 case UnmapNotify: printf (
"Event: *****UnmapNotify\n");
break;
601 default: printf (
"event, unknown %d\n", event.type);
605 windex = fwl_hwnd_to_windex( (
void *)event.xany.window);
610 case ConfigureNotify:
615 fwl_setScreenDim1 (event.xconfigure.width,event.xconfigure.height,windex);
620 if (event.xclient.data.l[0] == WM_DELETE_WINDOW && !RUNNINGASPLUGIN) {
622 printf(
"---XClient sent wmDeleteMessage, quitting freewrl\n");
624 fwl_doQuit(__FILE__,__LINE__);
629 XLookupString(&event.xkey,buf,
sizeof(buf),&ks,0);
666 buf[0]=(char)ks;buf[1]=
'\0';
668 DEBUG_XEV(
"Key type = %s\n", (event.type == KeyPress ?
"KEY PRESS" :
"KEY RELEASE"));
675 keysym = XGetKeyboardMapping(event.xkey.display,
676 event.xkey.keycode, 1, &keysyms_per_keycode_return);
680 XConvertCase(ksraw,&kslower,&ksupper);
683 if(event.type == KeyRelease && !IsModifierKey(ks)
684 && !IsFunctionKey(ks) && !IsMiscFunctionKey(ks) && !IsCursorKey(ks)){
685 fwl_do_rawKeyPress((
int)ks,1);
689 actionKey = platform2web3dActionKeyLINUX(ksraw);
691 fwl_do_rawKeyPress(actionKey,event.type+10);
693 fwl_do_rawKeyPress(ksraw,event.type);
698 cursorStyle = fwl_handle_mouse(event.type,event.xbutton.button,event.xbutton.x,event.xbutton.y,windex);
699 setCursor(cursorStyle);
724 if (XPending(Xdpy)) {
725 XPeekEvent(Xdpy,&nextevent);
726 if (nextevent.type==MotionNotify) {
break;
730 cursorStyle = fwl_handle_mouse(event.type,event.xbutton.button,event.xbutton.x,event.xbutton.y,windex);
731 setCursor(cursorStyle);