diff options
Diffstat (limited to 'platform/x11')
-rw-r--r-- | platform/x11/context_gl_x11.cpp | 26 | ||||
-rw-r--r-- | platform/x11/context_gl_x11.h | 8 | ||||
-rw-r--r-- | platform/x11/godot_x11.cpp | 8 | ||||
-rw-r--r-- | platform/x11/joystick_linux.cpp | 6 | ||||
-rw-r--r-- | platform/x11/key_mapping_x11.cpp | 76 | ||||
-rw-r--r-- | platform/x11/key_mapping_x11.h | 2 | ||||
-rw-r--r-- | platform/x11/os_x11.cpp | 258 | ||||
-rw-r--r-- | platform/x11/os_x11.h | 14 |
8 files changed, 202 insertions, 196 deletions
diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp index 89bd5f58ff..9f987e1376 100644 --- a/platform/x11/context_gl_x11.cpp +++ b/platform/x11/context_gl_x11.cpp @@ -41,7 +41,7 @@ typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display*, GLXFBConfig, GLXContext, Bool, const int*); -struct ContextGL_X11_Private { +struct ContextGL_X11_Private { ::GLXContext glx_context; }; @@ -76,13 +76,13 @@ static GLWrapperFuncPtr wrapper_get_proc_address(const char* p_function) { Error ContextGL_X11::initialize() { - + GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = NULL; - + // const char *extensions = glXQueryExtensionsString(x11_display, DefaultScreen(x11_display)); - + glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB"); - + ERR_FAIL_COND_V( !glXCreateContextAttribsARB, ERR_UNCONFIGURED ); @@ -94,13 +94,13 @@ Error ContextGL_X11::initialize() { GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 24, - None + None }; int fbcount; GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs, &fbcount); ERR_FAIL_COND_V(!fbc,ERR_UNCONFIGURED); - + XVisualInfo *vi = glXGetVisualFromFBConfig(x11_display, fbc[0]); XSetWindowAttributes swa; @@ -140,7 +140,7 @@ Error ContextGL_X11::initialize() { GLX_CONTEXT_MINOR_VERSION_ARB, 0, None }; - + p->glx_context = glXCreateContextAttribsARB(x11_display, fbc[0], NULL, true, context_attribs); ERR_FAIL_COND_V(!p->glx_context,ERR_UNCONFIGURED); } @@ -150,7 +150,7 @@ Error ContextGL_X11::initialize() { /* glWrapperInit(wrapper_get_proc_address); glFlush(); - + glXSwapBuffers(x11_display,x11_window); */ //glXMakeCurrent(x11_display, None, NULL); @@ -165,14 +165,14 @@ int ContextGL_X11::get_window_width() { XWindowAttributes xwa; XGetWindowAttributes(x11_display,x11_window,&xwa); - + return xwa.width; } int ContextGL_X11::get_window_height() { XWindowAttributes xwa; XGetWindowAttributes(x11_display,x11_window,&xwa); - + return xwa.height; } @@ -181,9 +181,9 @@ ContextGL_X11::ContextGL_X11(::Display *p_x11_display,::Window &p_x11_window,con default_video_mode=p_default_video_mode; x11_display=p_x11_display; - + opengl_3_context=p_opengl_3_context; - + double_buffer=false; direct_render=false; glx_minor=glx_major=0; diff --git a/platform/x11/context_gl_x11.h b/platform/x11/context_gl_x11.h index 56404d0fae..c77fb3e333 100644 --- a/platform/x11/context_gl_x11.h +++ b/platform/x11/context_gl_x11.h @@ -50,22 +50,22 @@ class ContextGL_X11 : public ContextGL { OS::VideoMode default_video_mode; // ::Colormap x11_colormap; ::Display *x11_display; - ::Window& x11_window; + ::Window& x11_window; bool double_buffer; bool direct_render; int glx_minor,glx_major; bool opengl_3_context; public: - virtual void release_current(); - virtual void make_current(); + virtual void release_current(); + virtual void make_current(); virtual void swap_buffers(); virtual int get_window_width(); virtual int get_window_height(); virtual Error initialize(); - ContextGL_X11(::Display *p_x11_display,::Window &p_x11_window,const OS::VideoMode& p_default_video_mode,bool p_opengl_3_context); + ContextGL_X11(::Display *p_x11_display,::Window &p_x11_window,const OS::VideoMode& p_default_video_mode,bool p_opengl_3_context); ~ContextGL_X11(); }; diff --git a/platform/x11/godot_x11.cpp b/platform/x11/godot_x11.cpp index ee83da25c1..c500f939c4 100644 --- a/platform/x11/godot_x11.cpp +++ b/platform/x11/godot_x11.cpp @@ -30,16 +30,16 @@ #include "os_x11.h" int main(int argc, char* argv[]) { - + OS_X11 os; - + Error err = Main::setup(argv[0],argc-1,&argv[1]); if (err!=OK) return 255; - + if (Main::start()) os.run(); // it is actually the OS that decides how to run Main::cleanup(); - + return os.get_exit_code(); } diff --git a/platform/x11/joystick_linux.cpp b/platform/x11/joystick_linux.cpp index 9a52c4ff36..0615f33f96 100644 --- a/platform/x11/joystick_linux.cpp +++ b/platform/x11/joystick_linux.cpp @@ -429,6 +429,12 @@ uint32_t joystick_linux::process_joysticks(uint32_t p_event_id) { for (int j = 0; j < len; j++) { input_event &ev = events[j]; + + // ev may be tainted and out of MAX_KEY range, which will cause + // joy->key_map[ev.code] to crash + if( ev.code < 0 || ev.code >= MAX_KEY ) + return p_event_id; + switch (ev.type) { case EV_KEY: p_event_id = input->joy_button(p_event_id, i, joy->key_map[ev.code], ev.value); diff --git a/platform/x11/key_mapping_x11.cpp b/platform/x11/key_mapping_x11.cpp index 46f1483767..190d6925dd 100644 --- a/platform/x11/key_mapping_x11.cpp +++ b/platform/x11/key_mapping_x11.cpp @@ -32,14 +32,14 @@ /***** SCAN CODE CONVERSION ******/ struct _XTranslatePair { - + KeySym keysym; unsigned int keycode; }; -static _XTranslatePair _xkeysym_to_keycode[]={ +static _XTranslatePair _xkeysym_to_keycode[]={ // misc keys - + { XK_Escape, KEY_ESCAPE }, { XK_Tab, KEY_TAB }, { XK_ISO_Left_Tab, KEY_BACKTAB }, @@ -136,8 +136,8 @@ static _XTranslatePair _xkeysym_to_keycode[]={ { XK_F14, KEY_F14}, { XK_F15, KEY_F15}, { XK_F16, KEY_F16}, - - // media keys + + // media keys { XF86XK_Back, KEY_BACK }, { XF86XK_Forward, KEY_FORWARD }, { XF86XK_Stop, KEY_STOP }, @@ -146,7 +146,7 @@ static _XTranslatePair _xkeysym_to_keycode[]={ { XF86XK_AudioMedia, KEY_LAUNCHMEDIA }, { XF86XK_OpenURL, KEY_OPENURL }, { XF86XK_HomePage, KEY_HOMEPAGE }, - { XF86XK_Search, KEY_SEARCH }, + { XF86XK_Search, KEY_SEARCH }, { XF86XK_AudioLowerVolume, KEY_VOLUMEDOWN }, { XF86XK_AudioMute, KEY_VOLUMEMUTE }, { XF86XK_AudioRaiseVolume, KEY_VOLUMEUP }, @@ -155,13 +155,13 @@ static _XTranslatePair _xkeysym_to_keycode[]={ { XF86XK_AudioPrev, KEY_MEDIAPREVIOUS }, { XF86XK_AudioNext, KEY_MEDIANEXT }, { XF86XK_AudioRecord, KEY_MEDIARECORD }, - + // launch keys { XF86XK_Mail, KEY_LAUNCHMAIL }, { XF86XK_MyComputer, KEY_LAUNCH0 }, { XF86XK_Calculator, KEY_LAUNCH1 }, { XF86XK_Standby, KEY_STANDBY }, - + { XF86XK_Launch0, KEY_LAUNCH2 }, { XF86XK_Launch1, KEY_LAUNCH3 }, { XF86XK_Launch2, KEY_LAUNCH4 }, @@ -176,41 +176,41 @@ static _XTranslatePair _xkeysym_to_keycode[]={ { XF86XK_LaunchB, KEY_LAUNCHD }, { XF86XK_LaunchC, KEY_LAUNCHE }, { XF86XK_LaunchD, KEY_LAUNCHF }, - + {0, 0 } }; unsigned int KeyMappingX11::get_keycode(KeySym p_keysym) { - + // kinda bruteforce.. could optimize. - + if (p_keysym<0x100) // Latin 1, maps 1-1 return p_keysym; - + // look for special key for(int idx=0;_xkeysym_to_keycode[idx].keysym!=0;idx++) { - + if (_xkeysym_to_keycode[idx].keysym==p_keysym) return _xkeysym_to_keycode[idx].keycode; } - + return 0; } KeySym KeyMappingX11::get_keysym(unsigned int p_code) { - + // kinda bruteforce.. could optimize. - + if (p_code<0x100) // Latin 1, maps 1-1 return p_code; - + // look for special key for(int idx=0;_xkeysym_to_keycode[idx].keysym!=0;idx++) { - + if (_xkeysym_to_keycode[idx].keycode==p_code) return _xkeysym_to_keycode[idx].keysym; } - + return 0; } @@ -220,13 +220,13 @@ KeySym KeyMappingX11::get_keysym(unsigned int p_code) { // Tables taken from FOX toolkit struct _XTranslateUnicodePair { - + KeySym keysym; unsigned int unicode; }; enum { - + _KEYSYM_MAX=759 }; @@ -992,7 +992,7 @@ static _XTranslateUnicodePair _xkeysym_to_unicode[_KEYSYM_MAX] = { }; unsigned int KeyMappingX11::get_unicode_from_keysym(KeySym p_keysym) { - + /* Latin-1 */ if (p_keysym>=0x20 && p_keysym<=0x7e) return p_keysym; @@ -1001,13 +1001,13 @@ unsigned int KeyMappingX11::get_unicode_from_keysym(KeySym p_keysym) { // keypad to latin1 is easy if (p_keysym>=0xffaa && p_keysym<=0xffb9) return p_keysym-0xff80; - + /* Unicode (may be present)*/ - - if((p_keysym&0xff000000)==0x01000000) + + if((p_keysym&0xff000000)==0x01000000) return p_keysym&0x00ffffff; - - int middle,low=0,high=_KEYSYM_MAX-1; + + int middle,low=0,high=_KEYSYM_MAX-1; do { middle=(high+low)/2; if ( _xkeysym_to_unicode[middle].keysym==p_keysym) @@ -1017,19 +1017,19 @@ unsigned int KeyMappingX11::get_unicode_from_keysym(KeySym p_keysym) { else high=middle-1; } while (high>=low); - + return 0; - + } struct _XTranslateUnicodePairReverse { - + unsigned int unicode; KeySym keysym; }; enum { - + _UNICODE_MAX=750 }; @@ -1783,20 +1783,20 @@ static _XTranslateUnicodePairReverse _unicode_to_xkeysym[_UNICODE_MAX] = { { 0x0EF4, 0x3184 }, { 0x0EF5, 0x3186 }, { 0x0EF6, 0x318D }, - { 0x0EF7, 0x318E } + { 0x0EF7, 0x318E } }; KeySym KeyMappingX11::get_keysym_from_unicode(unsigned int p_unicode) { - + /* Latin 1 */ - + if (p_unicode>=0x20 && p_unicode<=0x7e) return p_unicode; - + if (p_unicode>=0xa0 && p_unicode<=0xff) return p_unicode; - - int middle,low=0,high=_UNICODE_MAX-1; + + int middle,low=0,high=_UNICODE_MAX-1; do { middle=(high+low)/2; if ( _unicode_to_xkeysym[middle].keysym==p_unicode) @@ -1806,7 +1806,7 @@ KeySym KeyMappingX11::get_keysym_from_unicode(unsigned int p_unicode) { else high=middle-1; } while (high>=low); - + // if not found, let's hope X understands it as unicode return p_unicode|0x01000000; } diff --git a/platform/x11/key_mapping_x11.h b/platform/x11/key_mapping_x11.h index 979d8a112f..e3aede8388 100644 --- a/platform/x11/key_mapping_x11.h +++ b/platform/x11/key_mapping_x11.h @@ -48,7 +48,7 @@ public: static KeySym get_keysym(unsigned int p_code); static unsigned int get_unicode_from_keysym(KeySym p_keysym); static KeySym get_keysym_from_unicode(unsigned int p_unicode); - + }; diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index e5591810e7..f60610693f 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -109,15 +109,15 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi if (get_render_thread_mode()==RENDER_SEPARATE_THREAD) { XInitThreads(); } - + /** XLIB INITIALIZATION **/ x11_display = XOpenDisplay(NULL); - + char * modifiers = XSetLocaleModifiers ("@im=none"); ERR_FAIL_COND( modifiers == NULL ); - + xim = XOpenIM (x11_display, NULL, NULL, NULL); - + if (xim == NULL) { WARN_PRINT("XOpenIM failed"); @@ -130,19 +130,19 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi if (imvalret != NULL || xim_styles == NULL) { fprintf (stderr, "Input method doesn't support any styles\n"); } - + if (xim_styles) { xim_style = 0L; for (int i=0;i<xim_styles->count_styles;i++) { - + if (xim_styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing)) { - + xim_style = xim_styles->supported_styles[i]; break; } } - + XFree (xim_styles); } XFree( imvalret ); @@ -225,7 +225,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi } else { XGetWindowAttributes(x11_display,x11_window,&xwa); } - xsh->min_width = xwa.width; + xsh->min_width = xwa.width; xsh->max_width = xwa.width; xsh->min_height = xwa.height; xsh->max_height = xwa.height; @@ -282,7 +282,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi spatial_sound_2d_server = memnew( SpatialSound2DServerSW ); spatial_sound_2d_server->init(); - + ERR_FAIL_COND(!visual_server); ERR_FAIL_COND(x11_window==0); @@ -302,7 +302,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi ColormapChangeMask | OwnerGrabButtonMask; XChangeWindowAttributes(x11_display, x11_window,CWEventMask,&new_attr); - + XClassHint* classHint; /* set the titlebar name */ @@ -317,19 +317,19 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi XSetClassHint(x11_display, x11_window, classHint); XFree(classHint); - wm_delete = XInternAtom(x11_display, "WM_DELETE_WINDOW", true); + wm_delete = XInternAtom(x11_display, "WM_DELETE_WINDOW", true); XSetWMProtocols(x11_display, x11_window, &wm_delete, 1); - + if (xim && xim_style) { - + xic = XCreateIC (xim,XNInputStyle, xim_style,XNClientWindow,x11_window,XNFocusWindow, x11_window, (char*)NULL); } else { - + xic=NULL; WARN_PRINT("XCreateIC couldn't create xic"); - } + } XcursorSetTheme(x11_display,"default"); cursor_size = XcursorGetDefaultSize(x11_display); @@ -459,7 +459,7 @@ void OS_X11::finalize() { visual_server->finish(); memdelete(visual_server); memdelete(rasterizer); - + physics_server->finish(); memdelete(physics_server); @@ -474,10 +474,10 @@ void OS_X11::finalize() { #endif for(int i=0;i<CURSOR_MAX;i++) { if( cursors[i] != None ) - XFreeCursor( x11_display, cursors[i] ); + XFreeCursor( x11_display, cursors[i] ); if( img[i] != NULL ) XcursorImageDestroy( img[i] ); - }; + }; XDestroyIC( xic ); XCloseIM( xim ); @@ -486,7 +486,7 @@ void OS_X11::finalize() { if (xmbstring) memfree(xmbstring); - + args.clear(); } @@ -630,7 +630,7 @@ int OS_X11::get_screen_count() const { int event_base, error_base; const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base); if( !ext_okay ) return 0; - + int count; XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count); XFree(xsi); @@ -647,7 +647,7 @@ int OS_X11::get_current_screen() const { Point2i pos = get_screen_position(i); Size2i size = get_screen_size(i); if( (x >= pos.x && x <pos.x + size.width) && (y >= pos.y && y < pos.y + size.height) ) - return i; + return i; } return 0; } @@ -655,7 +655,7 @@ int OS_X11::get_current_screen() const { void OS_X11::set_current_screen(int p_screen) { int count = get_screen_count(); if(p_screen >= count) return; - + if( current_videomode.fullscreen ) { Point2i position = get_screen_position(p_screen); Size2i size = get_screen_size(p_screen); @@ -677,13 +677,13 @@ Point2 OS_X11::get_screen_position(int p_screen) const { if( !ext_okay ) { return Point2i(0,0); } - + int count; XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count); if( p_screen >= count ) { return Point2i(0,0); } - + Point2i position = Point2i(xsi[p_screen].x_org, xsi[p_screen].y_org); XFree(xsi); @@ -696,11 +696,11 @@ Size2 OS_X11::get_screen_size(int p_screen) const { int event_base, error_base; const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base); if( !ext_okay ) return Size2i(0,0); - + int count; XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count); if( p_screen >= count ) return Size2i(0,0); - + Size2i size = Point2i(xsi[p_screen].width, xsi[p_screen].height); XFree(xsi); return size; @@ -714,12 +714,12 @@ Point2 OS_X11::get_window_position() const { int screen = get_current_screen(); Point2i screen_position = get_screen_position(screen); - return Point2i(x-screen_position.x, y-screen_position.y); + return Point2i(x-screen_position.x, y-screen_position.y); } void OS_X11::set_window_position(const Point2& p_position) { // Using EWMH -- Extended Window Manager Hints - // to get the size of the decoration + // to get the size of the decoration #if 0 Atom property = XInternAtom(x11_display,"_NET_FRAME_EXTENTS", True); Atom type; @@ -742,17 +742,17 @@ void OS_X11::set_window_position(const Point2& p_position) { &len, &remaining, &data - ); + ); long left = 0L; long top = 0L; if( result == Success ) { long *extends = (long *) data; - + left = extends[0]; top = extends[2]; - + XFree(data); } @@ -794,7 +794,7 @@ void OS_X11::set_window_resizable(bool p_enabled) { if(!p_enabled) { XWindowAttributes xwa; XGetWindowAttributes(x11_display,x11_window,&xwa); - xsh->min_width = xwa.width; + xsh->min_width = xwa.width; xsh->max_width = xwa.width; xsh->min_height = xwa.height; xsh->max_height = xwa.height; @@ -821,7 +821,7 @@ void OS_X11::set_window_minimized(bool p_enabled) { xev.xclient.data.l[0] = p_enabled ? WM_IconicState : WM_NormalState; XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); - + //XEvent xev; Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); Atom wm_hidden = XInternAtom(x11_display, "_NET_WM_STATE_HIDDEN", False); @@ -834,7 +834,7 @@ void OS_X11::set_window_minimized(bool p_enabled) { xev.xclient.data.l[0] = _NET_WM_STATE_ADD; xev.xclient.data.l[1] = wm_hidden; - XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); + XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); } bool OS_X11::is_window_minimized() const { @@ -863,14 +863,14 @@ bool OS_X11::is_window_minimized() const { if( result == Success ) { long *state = (long *) data; - if( state[0] == WM_IconicState ) + if( state[0] == WM_IconicState ) return true; } return false; } void OS_X11::set_window_maximized(bool p_enabled) { - // Using EWMH -- Extended Window Manager Hints + // Using EWMH -- Extended Window Manager Hints XEvent xev; Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); Atom wm_max_horz = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); @@ -928,7 +928,7 @@ bool OS_X11::is_window_maximized() const { &data ); - if(result == Success) { + if(result == Success) { Atom *atoms = (Atom*) data; Atom wm_max_horz = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); Atom wm_max_vert = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_VERT", False); @@ -952,65 +952,65 @@ bool OS_X11::is_window_maximized() const { InputModifierState OS_X11::get_key_modifier_state(unsigned int p_x11_state) { - + InputModifierState state; - + state.shift = (p_x11_state&ShiftMask); state.control = (p_x11_state&ControlMask); state.alt = (p_x11_state&Mod1Mask /*|| p_x11_state&Mod5Mask*/); //altgr should not count as alt state.meta = (p_x11_state&Mod4Mask); - + return state; } unsigned int OS_X11::get_mouse_button_state(unsigned int p_x11_state) { unsigned int state=0; - + if (p_x11_state&Button1Mask) { - + state|=1<<0; } if (p_x11_state&Button3Mask) { - + state|=1<<1; } if (p_x11_state&Button2Mask) { - + state|=1<<2; } - + if (p_x11_state&Button4Mask) { - + state|=1<<3; } if (p_x11_state&Button5Mask) { - + state|=1<<4; } last_button_state=state; return state; } - + void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { - + // X11 functions don't know what const is XKeyEvent *xkeyevent = p_event; - + // This code was pretty difficult to write. // The docs stink and every toolkit seems to - // do it in a different way. - + // do it in a different way. + /* Phase 1, obtain a proper keysym */ - + // This was also very difficult to figure out. // You'd expect you could just use Keysym provided by - // XKeycodeToKeysym to obtain internationalized - // input.. WRONG!! + // XKeycodeToKeysym to obtain internationalized + // input.. WRONG!! // you must use XLookupString (???) which not only wastes // cycles generating an unnecesary string, but also // still works in half the cases. (won't handle deadkeys) @@ -1019,57 +1019,57 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { // So.. then you have to chosse which of both results // you want to keep. // This is a real bizarreness and cpu waster. - + KeySym keysym_keycode=0; // keysym used to find a keycode KeySym keysym_unicode=0; // keysym used to find unicode - + // XLookupString returns keysyms usable as nice scancodes/ char str[256+1]; XLookupString(xkeyevent, str, 256, &keysym_keycode, NULL); - + // Meanwhile, XLookupString returns keysyms useful for unicode. - - + + if (!xmbstring) { // keep a temporary buffer for the string xmbstring=(char*)memalloc(sizeof(char)*8); xmblen=8; - } - + } + if (xkeyevent->type == KeyPress && xic) { Status status; do { - + int mnbytes = XmbLookupString (xic, xkeyevent, xmbstring, xmblen - 1, &keysym_unicode, &status); xmbstring[mnbytes] = '\0'; if (status == XBufferOverflow) { xmblen = mnbytes + 1; xmbstring = (char*)memrealloc (xmbstring, xmblen); - } + } } while (status == XBufferOverflow); - } + } + - /* Phase 2, obtain a pigui keycode from the keysym */ - + // KeyMappingX11 just translated the X11 keysym to a PIGUI // keysym, so it works in all platforms the same. unsigned int keycode = KeyMappingX11::get_keycode(keysym_keycode); - + /* Phase 3, obtain an unicode character from the keysym */ - + // KeyMappingX11 also translates keysym to unicode. // It does a binary search on a table to translate - // most properly. + // most properly. //print_line("keysym_unicode: "+rtos(keysym_unicode)); unsigned int unicode = keysym_unicode>0? KeyMappingX11::get_unicode_from_keysym(keysym_unicode):0; - + /* Phase 4, determine if event must be filtered */ - + // This seems to be a side-effect of using XIM. // XEventFilter looks like a core X11 funciton, // but it's actually just used to see if we must @@ -1078,47 +1078,47 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { // Guess it was a design problem of the extension bool keypress = xkeyevent->type == KeyPress; - + if (xkeyevent->type == KeyPress && xic) { if (XFilterEvent((XEvent*)xkeyevent, x11_window)) - return; + return; } - + if (keycode==0 && unicode==0) return; /* Phase 5, determine modifier mask */ - + // No problems here, except I had no way to // know Mod1 was ALT and Mod4 was META (applekey/winkey) // just tried Mods until i found them. //print_line("mod1: "+itos(xkeyevent->state&Mod1Mask)+" mod 5: "+itos(xkeyevent->state&Mod5Mask)); - + InputModifierState state = get_key_modifier_state(xkeyevent->state); - + /* Phase 6, determine echo character */ - + // Echo characters in X11 are a keyrelease and a keypress // one after the other with the (almot) same timestamp. // To detect them, i use XPeekEvent and check that their // difference in time is below a treshold. - + if (xkeyevent->type != KeyPress) { - + // make sure there are events pending, // so this call won't block. if (XPending(x11_display)>0) { XEvent peek_event; XPeekEvent(x11_display, &peek_event); - - // I'm using a treshold of 5 msecs, + + // I'm using a treshold of 5 msecs, // since sometimes there seems to be a little // jitter. I'm still not convinced that all this approach // is correct, but the xorg developers are // not very helpful today. - + ::Time tresh=ABS(peek_event.xkey.time-xkeyevent->time); if (peek_event.type == KeyPress && tresh<5 ) { KeySym rk; @@ -1130,16 +1130,16 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { return; //ignore current, echo next } } - + // use the time from peek_event so it always works } - - // save the time to check for echo when keypress happens + + // save the time to check for echo when keypress happens } - - + + /* Phase 7, send event to Window */ - + InputEvent event; event.ID=++event_id; event.type = InputEvent::KEY; @@ -1234,24 +1234,24 @@ void OS_X11::process_xevents() { case ConfigureNotify: /* call resizeGLScene only if our window-size changed */ - - if ((event.xconfigure.width == current_videomode.width) && + + if ((event.xconfigure.width == current_videomode.width) && (event.xconfigure.height == current_videomode.height)) break; - + current_videomode.width=event.xconfigure.width; current_videomode.height=event.xconfigure.height; break; case ButtonPress: case ButtonRelease: { - + /* exit in case of a mouse button press */ last_timestamp=event.xbutton.time; if (mouse_mode==MOUSE_MODE_CAPTURED) { event.xbutton.x=last_mouse_pos.x; event.xbutton.y=last_mouse_pos.y; } - + InputEvent mouse_event; mouse_event.ID=++event_id; mouse_event.type = InputEvent::MOUSE_BUTTON; @@ -1267,31 +1267,31 @@ void OS_X11::process_xevents() { mouse_event.mouse_button.button_index=3; else if (mouse_event.mouse_button.button_index==3) mouse_event.mouse_button.button_index=2; - + mouse_event.mouse_button.pressed=(event.type==ButtonPress); if (event.type==ButtonPress && event.xbutton.button==1) { - + uint64_t diff = get_ticks_usec()/1000 - last_click_ms; if (diff<400 && Point2(last_click_pos).distance_to(Point2(event.xbutton.x,event.xbutton.y))<5) { - + last_click_ms=0; last_click_pos = Point2(-100,-100); - mouse_event.mouse_button.doubleclick=true; + mouse_event.mouse_button.doubleclick=true; mouse_event.ID=++event_id; - + } else { - last_click_ms+=diff; + last_click_ms+=diff; last_click_pos = Point2(event.xbutton.x,event.xbutton.y); } - } + } input->parse_input_event( mouse_event); - - } break; + + } break; case MotionNotify: { // FUCK YOU X11 API YOU SERIOUSLY GROSS ME OUT @@ -1304,7 +1304,7 @@ void OS_X11::process_xevents() { // PLEASE DO ME A FAVOR AND DIE DROWNED IN A FECAL // MOUNTAIN BECAUSE THAT'S WHERE YOU BELONG. - + while(true) { if (mouse_mode==MOUSE_MODE_CAPTURED && event.xmotion.x==current_videomode.width/2 && event.xmotion.y==current_videomode.height/2) { //this is likely the warp event since it was warped here @@ -1326,7 +1326,7 @@ void OS_X11::process_xevents() { } last_timestamp=event.xmotion.time; - + // Motion is also simple. // A little hack is in order // to be able to send relative motion events. @@ -1359,13 +1359,13 @@ void OS_X11::process_xevents() { 0,0,0,0, (int)center.x, (int)center.y); #endif } - + if (!last_mouse_pos_valid) { - + last_mouse_pos=pos; last_mouse_pos_valid=true; } - + Point2i rel = pos - last_mouse_pos; #ifdef NEW_WM_API @@ -1379,7 +1379,7 @@ void OS_X11::process_xevents() { motion_event.ID=++event_id; motion_event.type=InputEvent::MOUSE_MOTION; motion_event.device=0; - + motion_event.mouse_motion.mod = get_key_modifier_state(event.xmotion.state); motion_event.mouse_motion.button_mask = get_mouse_button_state(event.xmotion.state); motion_event.mouse_motion.x=pos.x; @@ -1392,23 +1392,23 @@ void OS_X11::process_xevents() { motion_event.mouse_motion.relative_x=rel.x; motion_event.mouse_motion.relative_y=rel.y; - + last_mouse_pos=pos; // printf("rel: %d,%d\n", rel.x, rel.y ); - + input->parse_input_event( motion_event); - - } break; - case KeyPress: + + } break; + case KeyPress: case KeyRelease: { last_timestamp=event.xkey.time; - + // key event is a little complex, so // it will be handled in it's own function. handle_key_event( (XKeyEvent*)&event ); - } break; + } break; case SelectionRequest: { XSelectionRequestEvent *req; @@ -1455,8 +1455,8 @@ void OS_X11::process_xevents() { } break; - case ClientMessage: - + case ClientMessage: + if ((unsigned int)event.xclient.data.l[0]==(unsigned int)wm_delete) main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST); break; @@ -1464,7 +1464,7 @@ void OS_X11::process_xevents() { break; } } - + XFlush(x11_display); if (do_mouse_warp) { @@ -1472,7 +1472,7 @@ void OS_X11::process_xevents() { XWarpPointer(x11_display, None, x11_window, 0,0,0,0, (int)current_videomode.width/2, (int)current_videomode.height/2); - /* + /* Window root, child; int root_x, root_y; int win_x, win_y; @@ -1753,19 +1753,19 @@ void OS_X11::set_icon(const Image& p_icon) { void OS_X11::run() { force_quit = false; - + if (!main_loop) return; - + main_loop->init(); - + // uint64_t last_ticks=get_ticks_usec(); - + // int frames=0; // uint64_t frame=0; - + while (!force_quit) { - + process_xevents(); // get rid of pending events #ifdef JOYDEV_ENABLED event_id = joystick->process_joysticks(event_id); @@ -1773,7 +1773,7 @@ void OS_X11::run() { if (Main::iteration()==true) break; }; - + main_loop->finish(); } diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 0891e4b8eb..d9a5b1688c 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -78,7 +78,7 @@ class OS_X11 : public OS_Unix { VideoMode current_videomode; List<String> args; Window x11_window; - MainLoop *main_loop; + MainLoop *main_loop; ::Display* x11_display; char *xmbstring; int xmblen; @@ -93,7 +93,7 @@ class OS_X11 : public OS_Unix { uint64_t last_click_ms; unsigned int event_id; uint32_t last_button_state; - + PhysicsServer *physics_server; unsigned int get_mouse_button_state(unsigned int p_x11_state); InputModifierState get_key_modifier_state(unsigned int p_x11_state); @@ -101,7 +101,7 @@ class OS_X11 : public OS_Unix { MouseMode mouse_mode; Point2i center; - + void handle_key_event(XKeyEvent *p_event,bool p_echo=false); void process_xevents(); virtual void delete_main_loop(); @@ -154,16 +154,16 @@ class OS_X11 : public OS_Unix { protected: virtual int get_video_driver_count() const; - virtual const char * get_video_driver_name(int p_driver) const; + virtual const char * get_video_driver_name(int p_driver) const; virtual VideoMode get_default_video_mode() const; virtual int get_audio_driver_count() const; virtual const char * get_audio_driver_name(int p_driver) const; - virtual void initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver); + virtual void initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver); virtual void finalize(); - virtual void set_main_loop( MainLoop * p_main_loop ); + virtual void set_main_loop( MainLoop * p_main_loop ); public: @@ -183,7 +183,7 @@ public: virtual void set_icon(const Image& p_icon); virtual MainLoop *get_main_loop() const; - + virtual bool can_draw() const; virtual void set_clipboard(const String& p_text); |