diff options
Diffstat (limited to 'Source/3rdParty/SDL2/src/video/x11/SDL_x11events.c')
-rw-r--r-- | Source/3rdParty/SDL2/src/video/x11/SDL_x11events.c | 1500 |
1 files changed, 0 insertions, 1500 deletions
diff --git a/Source/3rdParty/SDL2/src/video/x11/SDL_x11events.c b/Source/3rdParty/SDL2/src/video/x11/SDL_x11events.c deleted file mode 100644 index d293a5e..0000000 --- a/Source/3rdParty/SDL2/src/video/x11/SDL_x11events.c +++ /dev/null @@ -1,1500 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_VIDEO_DRIVER_X11 - -#include <sys/types.h> -#include <sys/time.h> -#include <signal.h> -#include <unistd.h> -#include <limits.h> /* For INT_MAX */ - -#include "SDL_x11video.h" -#include "SDL_x11touch.h" -#include "SDL_x11xinput2.h" -#include "../../core/unix/SDL_poll.h" -#include "../../events/SDL_events_c.h" -#include "../../events/SDL_mouse_c.h" -#include "../../events/SDL_touch_c.h" - -#include "SDL_hints.h" -#include "SDL_timer.h" -#include "SDL_syswm.h" -#include "SDL_assert.h" - -#include <stdio.h> - -/*#define DEBUG_XEVENTS*/ - -#ifndef _NET_WM_MOVERESIZE_SIZE_TOPLEFT -#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0 -#endif - -#ifndef _NET_WM_MOVERESIZE_SIZE_TOP -#define _NET_WM_MOVERESIZE_SIZE_TOP 1 -#endif - -#ifndef _NET_WM_MOVERESIZE_SIZE_TOPRIGHT -#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2 -#endif - -#ifndef _NET_WM_MOVERESIZE_SIZE_RIGHT -#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3 -#endif - -#ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT -#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4 -#endif - -#ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOM -#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5 -#endif - -#ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT -#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6 -#endif - -#ifndef _NET_WM_MOVERESIZE_SIZE_LEFT -#define _NET_WM_MOVERESIZE_SIZE_LEFT 7 -#endif - -#ifndef _NET_WM_MOVERESIZE_MOVE -#define _NET_WM_MOVERESIZE_MOVE 8 -#endif - -typedef struct { - unsigned char *data; - int format, count; - Atom type; -} SDL_x11Prop; - -/* Reads property - Must call X11_XFree on results - */ -static void X11_ReadProperty(SDL_x11Prop *p, Display *disp, Window w, Atom prop) -{ - unsigned char *ret=NULL; - Atom type; - int fmt; - unsigned long count; - unsigned long bytes_left; - int bytes_fetch = 0; - - do { - if (ret != 0) X11_XFree(ret); - X11_XGetWindowProperty(disp, w, prop, 0, bytes_fetch, False, AnyPropertyType, &type, &fmt, &count, &bytes_left, &ret); - bytes_fetch += bytes_left; - } while (bytes_left != 0); - - p->data=ret; - p->format=fmt; - p->count=count; - p->type=type; -} - -/* Find text-uri-list in a list of targets and return it's atom - if available, else return None */ -static Atom X11_PickTarget(Display *disp, Atom list[], int list_count) -{ - Atom request = None; - char *name; - int i; - for (i=0; i < list_count && request == None; i++) { - name = X11_XGetAtomName(disp, list[i]); - if ((SDL_strcmp("text/uri-list", name) == 0) || (SDL_strcmp("text/plain", name) == 0)) { - request = list[i]; - } - X11_XFree(name); - } - return request; -} - -/* Wrapper for X11_PickTarget for a maximum of three targets, a special - case in the Xdnd protocol */ -static Atom X11_PickTargetFromAtoms(Display *disp, Atom a0, Atom a1, Atom a2) -{ - int count=0; - Atom atom[3]; - if (a0 != None) atom[count++] = a0; - if (a1 != None) atom[count++] = a1; - if (a2 != None) atom[count++] = a2; - return X11_PickTarget(disp, atom, count); -} - -struct KeyRepeatCheckData -{ - XEvent *event; - SDL_bool found; -}; - -static Bool X11_KeyRepeatCheckIfEvent(Display *display, XEvent *chkev, - XPointer arg) -{ - struct KeyRepeatCheckData *d = (struct KeyRepeatCheckData *) arg; - if (chkev->type == KeyPress && - chkev->xkey.keycode == d->event->xkey.keycode && - chkev->xkey.time - d->event->xkey.time < 2) - d->found = SDL_TRUE; - return False; -} - -/* Check to see if this is a repeated key. - (idea shamelessly lifted from GII -- thanks guys! :) - */ -static SDL_bool X11_KeyRepeat(Display *display, XEvent *event) -{ - XEvent dummyev; - struct KeyRepeatCheckData d; - d.event = event; - d.found = SDL_FALSE; - if (X11_XPending(display)) - X11_XCheckIfEvent(display, &dummyev, X11_KeyRepeatCheckIfEvent, - (XPointer) &d); - return d.found; -} - -static SDL_bool -X11_IsWheelEvent(Display * display,XEvent * event,int * xticks,int * yticks) -{ - /* according to the xlib docs, no specific mouse wheel events exist. - However, the defacto standard is that the vertical wheel is X buttons - 4 (up) and 5 (down) and a horizontal wheel is 6 (left) and 7 (right). */ - - /* Xlib defines "Button1" through 5, so we just use literals here. */ - switch (event->xbutton.button) { - case 4: *yticks = 1; return SDL_TRUE; - case 5: *yticks = -1; return SDL_TRUE; - case 6: *xticks = 1; return SDL_TRUE; - case 7: *xticks = -1; return SDL_TRUE; - default: break; - } - return SDL_FALSE; -} - -/* Decodes URI escape sequences in string buf of len bytes - (excluding the terminating NULL byte) in-place. Since - URI-encoded characters take three times the space of - normal characters, this should not be an issue. - - Returns the number of decoded bytes that wound up in - the buffer, excluding the terminating NULL byte. - - The buffer is guaranteed to be NULL-terminated but - may contain embedded NULL bytes. - - On error, -1 is returned. - */ -static int X11_URIDecode(char *buf, int len) { - int ri, wi, di; - char decode = '\0'; - if (buf == NULL || len < 0) { - errno = EINVAL; - return -1; - } - if (len == 0) { - len = SDL_strlen(buf); - } - for (ri = 0, wi = 0, di = 0; ri < len && wi < len; ri += 1) { - if (di == 0) { - /* start decoding */ - if (buf[ri] == '%') { - decode = '\0'; - di += 1; - continue; - } - /* normal write */ - buf[wi] = buf[ri]; - wi += 1; - continue; - } else if (di == 1 || di == 2) { - char off = '\0'; - char isa = buf[ri] >= 'a' && buf[ri] <= 'f'; - char isA = buf[ri] >= 'A' && buf[ri] <= 'F'; - char isn = buf[ri] >= '0' && buf[ri] <= '9'; - if (!(isa || isA || isn)) { - /* not a hexadecimal */ - int sri; - for (sri = ri - di; sri <= ri; sri += 1) { - buf[wi] = buf[sri]; - wi += 1; - } - di = 0; - continue; - } - /* itsy bitsy magicsy */ - if (isn) { - off = 0 - '0'; - } else if (isa) { - off = 10 - 'a'; - } else if (isA) { - off = 10 - 'A'; - } - decode |= (buf[ri] + off) << (2 - di) * 4; - if (di == 2) { - buf[wi] = decode; - wi += 1; - di = 0; - } else { - di += 1; - } - continue; - } - } - buf[wi] = '\0'; - return wi; -} - -/* Convert URI to local filename - return filename if possible, else NULL -*/ -static char* X11_URIToLocal(char* uri) { - char *file = NULL; - SDL_bool local; - - if (memcmp(uri,"file:/",6) == 0) uri += 6; /* local file? */ - else if (strstr(uri,":/") != NULL) return file; /* wrong scheme */ - - local = uri[0] != '/' || (uri[0] != '\0' && uri[1] == '/'); - - /* got a hostname? */ - if (!local && uri[0] == '/' && uri[2] != '/') { - char* hostname_end = strchr(uri+1, '/'); - if (hostname_end != NULL) { - char hostname[ 257 ]; - if (gethostname(hostname, 255) == 0) { - hostname[ 256 ] = '\0'; - if (memcmp(uri+1, hostname, hostname_end - (uri+1)) == 0) { - uri = hostname_end + 1; - local = SDL_TRUE; - } - } - } - } - if (local) { - file = uri; - /* Convert URI escape sequences to real characters */ - X11_URIDecode(file, 0); - if (uri[1] == '/') { - file++; - } else { - file--; - } - } - return file; -} - -#if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS -static void X11_HandleGenericEvent(SDL_VideoData *videodata, XEvent *xev) -{ - /* event is a union, so cookie == &event, but this is type safe. */ - XGenericEventCookie *cookie = &xev->xcookie; - if (X11_XGetEventData(videodata->display, cookie)) { - X11_HandleXinput2Event(videodata, cookie); - X11_XFreeEventData(videodata->display, cookie); - } -} -#endif /* SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS */ - -static unsigned -X11_GetNumLockModifierMask(_THIS) -{ - SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; - Display *display = viddata->display; - unsigned num_mask = 0; - int i, j; - XModifierKeymap *xmods; - unsigned n; - - xmods = X11_XGetModifierMapping(display); - n = xmods->max_keypermod; - for(i = 3; i < 8; i++) { - for(j = 0; j < n; j++) { - KeyCode kc = xmods->modifiermap[i * n + j]; - if (viddata->key_layout[kc] == SDL_SCANCODE_NUMLOCKCLEAR) { - num_mask = 1 << i; - break; - } - } - } - X11_XFreeModifiermap(xmods); - - return num_mask; -} - -static void -X11_ReconcileKeyboardState(_THIS) -{ - SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; - Display *display = viddata->display; - char keys[32]; - int keycode; - Window junk_window; - int x, y; - unsigned int mask; - const Uint8 *keyboardState; - - X11_XQueryKeymap(display, keys); - - /* Sync up the keyboard modifier state */ - if (X11_XQueryPointer(display, DefaultRootWindow(display), &junk_window, &junk_window, &x, &y, &x, &y, &mask)) { - SDL_ToggleModState(KMOD_CAPS, (mask & LockMask) != 0); - SDL_ToggleModState(KMOD_NUM, (mask & X11_GetNumLockModifierMask(_this)) != 0); - } - - keyboardState = SDL_GetKeyboardState(0); - for (keycode = 0; keycode < 256; ++keycode) { - SDL_Scancode scancode = viddata->key_layout[keycode]; - SDL_bool x11KeyPressed = (keys[keycode / 8] & (1 << (keycode % 8))) != 0; - SDL_bool sdlKeyPressed = keyboardState[scancode] == SDL_PRESSED; - - if (x11KeyPressed && !sdlKeyPressed) { - SDL_SendKeyboardKey(SDL_PRESSED, scancode); - } else if (!x11KeyPressed && sdlKeyPressed) { - SDL_SendKeyboardKey(SDL_RELEASED, scancode); - } - } -} - - -static void -X11_DispatchFocusIn(_THIS, SDL_WindowData *data) -{ -#ifdef DEBUG_XEVENTS - printf("window %p: Dispatching FocusIn\n", data); -#endif - SDL_SetKeyboardFocus(data->window); - X11_ReconcileKeyboardState(_this); -#ifdef X_HAVE_UTF8_STRING - if (data->ic) { - X11_XSetICFocus(data->ic); - } -#endif -#ifdef SDL_USE_IME - SDL_IME_SetFocus(SDL_TRUE); -#endif -} - -static void -X11_DispatchFocusOut(_THIS, SDL_WindowData *data) -{ -#ifdef DEBUG_XEVENTS - printf("window %p: Dispatching FocusOut\n", data); -#endif - /* If another window has already processed a focus in, then don't try to - * remove focus here. Doing so will incorrectly remove focus from that - * window, and the focus lost event for this window will have already - * been dispatched anyway. */ - if (data->window == SDL_GetKeyboardFocus()) { - SDL_SetKeyboardFocus(NULL); - } -#ifdef X_HAVE_UTF8_STRING - if (data->ic) { - X11_XUnsetICFocus(data->ic); - } -#endif -#ifdef SDL_USE_IME - SDL_IME_SetFocus(SDL_FALSE); -#endif -} - -static void -X11_DispatchMapNotify(SDL_WindowData *data) -{ - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0); - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESTORED, 0, 0); -} - -static void -X11_DispatchUnmapNotify(SDL_WindowData *data) -{ - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0); - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); -} - -static void -InitiateWindowMove(_THIS, const SDL_WindowData *data, const SDL_Point *point) -{ - SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; - SDL_Window* window = data->window; - Display *display = viddata->display; - XEvent evt; - - /* !!! FIXME: we need to regrab this if necessary when the drag is done. */ - X11_XUngrabPointer(display, 0L); - X11_XFlush(display); - - evt.xclient.type = ClientMessage; - evt.xclient.window = data->xwindow; - evt.xclient.message_type = X11_XInternAtom(display, "_NET_WM_MOVERESIZE", True); - evt.xclient.format = 32; - evt.xclient.data.l[0] = window->x + point->x; - evt.xclient.data.l[1] = window->y + point->y; - evt.xclient.data.l[2] = _NET_WM_MOVERESIZE_MOVE; - evt.xclient.data.l[3] = Button1; - evt.xclient.data.l[4] = 0; - X11_XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &evt); - - X11_XSync(display, 0); -} - -static void -InitiateWindowResize(_THIS, const SDL_WindowData *data, const SDL_Point *point, int direction) -{ - SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; - SDL_Window* window = data->window; - Display *display = viddata->display; - XEvent evt; - - if (direction < _NET_WM_MOVERESIZE_SIZE_TOPLEFT || direction > _NET_WM_MOVERESIZE_SIZE_LEFT) - return; - - /* !!! FIXME: we need to regrab this if necessary when the drag is done. */ - X11_XUngrabPointer(display, 0L); - X11_XFlush(display); - - evt.xclient.type = ClientMessage; - evt.xclient.window = data->xwindow; - evt.xclient.message_type = X11_XInternAtom(display, "_NET_WM_MOVERESIZE", True); - evt.xclient.format = 32; - evt.xclient.data.l[0] = window->x + point->x; - evt.xclient.data.l[1] = window->y + point->y; - evt.xclient.data.l[2] = direction; - evt.xclient.data.l[3] = Button1; - evt.xclient.data.l[4] = 0; - X11_XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &evt); - - X11_XSync(display, 0); -} - -static SDL_bool -ProcessHitTest(_THIS, const SDL_WindowData *data, const XEvent *xev) -{ - SDL_Window *window = data->window; - - if (window->hit_test) { - const SDL_Point point = { xev->xbutton.x, xev->xbutton.y }; - const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data); - static const int directions[] = { - _NET_WM_MOVERESIZE_SIZE_TOPLEFT, _NET_WM_MOVERESIZE_SIZE_TOP, - _NET_WM_MOVERESIZE_SIZE_TOPRIGHT, _NET_WM_MOVERESIZE_SIZE_RIGHT, - _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT, _NET_WM_MOVERESIZE_SIZE_BOTTOM, - _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT, _NET_WM_MOVERESIZE_SIZE_LEFT - }; - - switch (rc) { - case SDL_HITTEST_DRAGGABLE: - InitiateWindowMove(_this, data, &point); - return SDL_TRUE; - - case SDL_HITTEST_RESIZE_TOPLEFT: - case SDL_HITTEST_RESIZE_TOP: - case SDL_HITTEST_RESIZE_TOPRIGHT: - case SDL_HITTEST_RESIZE_RIGHT: - case SDL_HITTEST_RESIZE_BOTTOMRIGHT: - case SDL_HITTEST_RESIZE_BOTTOM: - case SDL_HITTEST_RESIZE_BOTTOMLEFT: - case SDL_HITTEST_RESIZE_LEFT: - InitiateWindowResize(_this, data, &point, directions[rc - SDL_HITTEST_RESIZE_TOPLEFT]); - return SDL_TRUE; - - default: return SDL_FALSE; - } - } - - return SDL_FALSE; -} - -static void -X11_UpdateUserTime(SDL_WindowData *data, const unsigned long latest) -{ - if (latest && (latest != data->user_time)) { - SDL_VideoData *videodata = data->videodata; - Display *display = videodata->display; - X11_XChangeProperty(display, data->xwindow, videodata->_NET_WM_USER_TIME, - XA_CARDINAL, 32, PropModeReplace, - (const unsigned char *) &latest, 1); -#ifdef DEBUG_XEVENTS - printf("window %p: updating _NET_WM_USER_TIME to %lu\n", data, latest); -#endif - data->user_time = latest; - } -} - -static void -X11_HandleClipboardEvent(_THIS, const XEvent *xevent) -{ - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; - Display *display = videodata->display; - - SDL_assert(videodata->clipboard_window != None); - SDL_assert(xevent->xany.window == videodata->clipboard_window); - - switch (xevent->type) { - /* Copy the selection from our own CUTBUFFER to the requested property */ - case SelectionRequest: { - const XSelectionRequestEvent *req = &xevent->xselectionrequest; - XEvent sevent; - int seln_format; - unsigned long nbytes; - unsigned long overflow; - unsigned char *seln_data; - -#ifdef DEBUG_XEVENTS - printf("window CLIPBOARD: SelectionRequest (requestor = %ld, target = %ld)\n", - req->requestor, req->target); -#endif - - SDL_zero(sevent); - sevent.xany.type = SelectionNotify; - sevent.xselection.selection = req->selection; - sevent.xselection.target = None; - sevent.xselection.property = None; /* tell them no by default */ - sevent.xselection.requestor = req->requestor; - sevent.xselection.time = req->time; - - /* !!! FIXME: We were probably storing this on the root window - because an SDL window might go away...? but we don't have to do - this now (or ever, really). */ - if (X11_XGetWindowProperty(display, DefaultRootWindow(display), - X11_GetSDLCutBufferClipboardType(display), 0, INT_MAX/4, False, req->target, - &sevent.xselection.target, &seln_format, &nbytes, - &overflow, &seln_data) == Success) { - /* !!! FIXME: cache atoms */ - Atom XA_TARGETS = X11_XInternAtom(display, "TARGETS", 0); - if (sevent.xselection.target == req->target) { - X11_XChangeProperty(display, req->requestor, req->property, - sevent.xselection.target, seln_format, PropModeReplace, - seln_data, nbytes); - sevent.xselection.property = req->property; - } else if (XA_TARGETS == req->target) { - Atom SupportedFormats[] = { XA_TARGETS, sevent.xselection.target }; - X11_XChangeProperty(display, req->requestor, req->property, - XA_ATOM, 32, PropModeReplace, - (unsigned char*)SupportedFormats, - SDL_arraysize(SupportedFormats)); - sevent.xselection.property = req->property; - sevent.xselection.target = XA_TARGETS; - } - X11_XFree(seln_data); - } - X11_XSendEvent(display, req->requestor, False, 0, &sevent); - X11_XSync(display, False); - } - break; - - case SelectionNotify: { -#ifdef DEBUG_XEVENTS - printf("window CLIPBOARD: SelectionNotify (requestor = %ld, target = %ld)\n", - xevent->xselection.requestor, xevent->xselection.target); -#endif - videodata->selection_waiting = SDL_FALSE; - } - break; - - case SelectionClear: { - /* !!! FIXME: cache atoms */ - Atom XA_CLIPBOARD = X11_XInternAtom(display, "CLIPBOARD", 0); - -#ifdef DEBUG_XEVENTS - printf("window CLIPBOARD: SelectionClear (requestor = %ld, target = %ld)\n", - xevent->xselection.requestor, xevent->xselection.target); -#endif - - if (xevent->xselectionclear.selection == XA_PRIMARY || - (XA_CLIPBOARD != None && xevent->xselectionclear.selection == XA_CLIPBOARD)) { - SDL_SendClipboardUpdate(); - } - } - break; - } -} - - -static void -X11_DispatchEvent(_THIS) -{ - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; - Display *display; - SDL_WindowData *data; - XEvent xevent; - int orig_event_type; - KeyCode orig_keycode; - XClientMessageEvent m; - int i; - - if (!videodata) { - return; - } - display = videodata->display; - - SDL_zero(xevent); /* valgrind fix. --ryan. */ - X11_XNextEvent(display, &xevent); - - /* Save the original keycode for dead keys, which are filtered out by - the XFilterEvent() call below. - */ - orig_event_type = xevent.type; - if (orig_event_type == KeyPress || orig_event_type == KeyRelease) { - orig_keycode = xevent.xkey.keycode; - } else { - orig_keycode = 0; - } - - /* filter events catchs XIM events and sends them to the correct handler */ - if (X11_XFilterEvent(&xevent, None) == True) { -#if 0 - printf("Filtered event type = %d display = %d window = %d\n", - xevent.type, xevent.xany.display, xevent.xany.window); -#endif - /* Make sure dead key press/release events are sent */ - /* But only if we're using one of the DBus IMEs, otherwise - some XIM IMEs will generate duplicate events */ - if (orig_keycode) { -#if defined(HAVE_IBUS_IBUS_H) || defined(HAVE_FCITX_FRONTEND_H) - SDL_Scancode scancode = videodata->key_layout[orig_keycode]; - videodata->filter_code = orig_keycode; - videodata->filter_time = xevent.xkey.time; - - if (orig_event_type == KeyPress) { - SDL_SendKeyboardKey(SDL_PRESSED, scancode); - } else { - SDL_SendKeyboardKey(SDL_RELEASED, scancode); - } -#endif - } - return; - } - - /* Send a SDL_SYSWMEVENT if the application wants them */ - if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) { - SDL_SysWMmsg wmmsg; - - SDL_VERSION(&wmmsg.version); - wmmsg.subsystem = SDL_SYSWM_X11; - wmmsg.msg.x11.event = xevent; - SDL_SendSysWMEvent(&wmmsg); - } - -#if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS - if(xevent.type == GenericEvent) { - X11_HandleGenericEvent(videodata, &xevent); - return; - } -#endif - -#if 0 - printf("type = %d display = %d window = %d\n", - xevent.type, xevent.xany.display, xevent.xany.window); -#endif - - if ((videodata->clipboard_window != None) && - (videodata->clipboard_window == xevent.xany.window)) { - X11_HandleClipboardEvent(_this, &xevent); - return; - } - - data = NULL; - if (videodata && videodata->windowlist) { - for (i = 0; i < videodata->numwindows; ++i) { - if ((videodata->windowlist[i] != NULL) && - (videodata->windowlist[i]->xwindow == xevent.xany.window)) { - data = videodata->windowlist[i]; - break; - } - } - } - if (!data) { - /* The window for KeymapNotify, etc events is 0 */ - if (xevent.type == KeymapNotify) { - if (SDL_GetKeyboardFocus() != NULL) { - X11_ReconcileKeyboardState(_this); - } - } else if (xevent.type == MappingNotify) { - /* Has the keyboard layout changed? */ - const int request = xevent.xmapping.request; - -#ifdef DEBUG_XEVENTS - printf("window %p: MappingNotify!\n", data); -#endif - if ((request == MappingKeyboard) || (request == MappingModifier)) { - X11_XRefreshKeyboardMapping(&xevent.xmapping); - } - - X11_UpdateKeymap(_this); - SDL_SendKeymapChangedEvent(); - } - return; - } - - switch (xevent.type) { - - /* Gaining mouse coverage? */ - case EnterNotify:{ - SDL_Mouse *mouse = SDL_GetMouse(); -#ifdef DEBUG_XEVENTS - printf("window %p: EnterNotify! (%d,%d,%d)\n", data, - xevent.xcrossing.x, - xevent.xcrossing.y, - xevent.xcrossing.mode); - if (xevent.xcrossing.mode == NotifyGrab) - printf("Mode: NotifyGrab\n"); - if (xevent.xcrossing.mode == NotifyUngrab) - printf("Mode: NotifyUngrab\n"); -#endif - SDL_SetMouseFocus(data->window); - - mouse->last_x = xevent.xcrossing.x; - mouse->last_y = xevent.xcrossing.y; - - if (!mouse->relative_mode) { - SDL_SendMouseMotion(data->window, 0, 0, xevent.xcrossing.x, xevent.xcrossing.y); - } - } - break; - /* Losing mouse coverage? */ - case LeaveNotify:{ -#ifdef DEBUG_XEVENTS - printf("window %p: LeaveNotify! (%d,%d,%d)\n", data, - xevent.xcrossing.x, - xevent.xcrossing.y, - xevent.xcrossing.mode); - if (xevent.xcrossing.mode == NotifyGrab) - printf("Mode: NotifyGrab\n"); - if (xevent.xcrossing.mode == NotifyUngrab) - printf("Mode: NotifyUngrab\n"); -#endif - if (!SDL_GetMouse()->relative_mode) { - SDL_SendMouseMotion(data->window, 0, 0, xevent.xcrossing.x, xevent.xcrossing.y); - } - - if (xevent.xcrossing.mode != NotifyGrab && - xevent.xcrossing.mode != NotifyUngrab && - xevent.xcrossing.detail != NotifyInferior) { - SDL_SetMouseFocus(NULL); - } - } - break; - - /* Gaining input focus? */ - case FocusIn:{ - if (xevent.xfocus.mode == NotifyGrab || xevent.xfocus.mode == NotifyUngrab) { - /* Someone is handling a global hotkey, ignore it */ -#ifdef DEBUG_XEVENTS - printf("window %p: FocusIn (NotifyGrab/NotifyUngrab, ignoring)\n", data); -#endif - break; - } - - if (xevent.xfocus.detail == NotifyInferior) { -#ifdef DEBUG_XEVENTS - printf("window %p: FocusIn (NotifierInferior, ignoring)\n", data); -#endif - break; - } -#ifdef DEBUG_XEVENTS - printf("window %p: FocusIn!\n", data); -#endif - if (!videodata->last_mode_change_deadline) /* no recent mode changes */ - { - data->pending_focus = PENDING_FOCUS_NONE; - data->pending_focus_time = 0; - X11_DispatchFocusIn(_this, data); - } - else - { - data->pending_focus = PENDING_FOCUS_IN; - data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_TIME; - } - data->last_focus_event_time = SDL_GetTicks(); - } - break; - - /* Losing input focus? */ - case FocusOut:{ - if (xevent.xfocus.mode == NotifyGrab || xevent.xfocus.mode == NotifyUngrab) { - /* Someone is handling a global hotkey, ignore it */ -#ifdef DEBUG_XEVENTS - printf("window %p: FocusOut (NotifyGrab/NotifyUngrab, ignoring)\n", data); -#endif - break; - } - if (xevent.xfocus.detail == NotifyInferior) { - /* We still have focus if a child gets focus */ -#ifdef DEBUG_XEVENTS - printf("window %p: FocusOut (NotifierInferior, ignoring)\n", data); -#endif - break; - } -#ifdef DEBUG_XEVENTS - printf("window %p: FocusOut!\n", data); -#endif - if (!videodata->last_mode_change_deadline) /* no recent mode changes */ - { - data->pending_focus = PENDING_FOCUS_NONE; - data->pending_focus_time = 0; - X11_DispatchFocusOut(_this, data); - } - else - { - data->pending_focus = PENDING_FOCUS_OUT; - data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_TIME; - } - } - break; - - /* Key press? */ - case KeyPress:{ - KeyCode keycode = xevent.xkey.keycode; - KeySym keysym = NoSymbol; - char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; - Status status = 0; - SDL_bool handled_by_ime = SDL_FALSE; - -#ifdef DEBUG_XEVENTS - printf("window %p: KeyPress (X11 keycode = 0x%X)\n", data, xevent.xkey.keycode); -#endif -#if 1 - if (videodata->key_layout[keycode] == SDL_SCANCODE_UNKNOWN && keycode) { - int min_keycode, max_keycode; - X11_XDisplayKeycodes(display, &min_keycode, &max_keycode); - keysym = X11_KeyCodeToSym(_this, keycode, xevent.xkey.state >> 13); - fprintf(stderr, - "The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL forums/mailing list <https://discourse.libsdl.org/> X11 KeyCode %d (%d), X11 KeySym 0x%lX (%s).\n", - keycode, keycode - min_keycode, keysym, - X11_XKeysymToString(keysym)); - } -#endif - /* */ - SDL_zero(text); -#ifdef X_HAVE_UTF8_STRING - if (data->ic) { - X11_Xutf8LookupString(data->ic, &xevent.xkey, text, sizeof(text), - &keysym, &status); - } else { - X11_XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL); - } -#else - X11_XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL); -#endif - -#ifdef SDL_USE_IME - if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){ - handled_by_ime = SDL_IME_ProcessKeyEvent(keysym, keycode); - } -#endif - if (!handled_by_ime) { - /* Don't send the key if it looks like a duplicate of a filtered key sent by an IME */ - if (xevent.xkey.keycode != videodata->filter_code || xevent.xkey.time != videodata->filter_time) { - SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]); - } - if(*text) { - SDL_SendKeyboardText(text); - } - } - - X11_UpdateUserTime(data, xevent.xkey.time); - } - break; - - /* Key release? */ - case KeyRelease:{ - KeyCode keycode = xevent.xkey.keycode; - -#ifdef DEBUG_XEVENTS - printf("window %p: KeyRelease (X11 keycode = 0x%X)\n", data, xevent.xkey.keycode); -#endif - if (X11_KeyRepeat(display, &xevent)) { - /* We're about to get a repeated key down, ignore the key up */ - break; - } - SDL_SendKeyboardKey(SDL_RELEASED, videodata->key_layout[keycode]); - } - break; - - /* Have we been iconified? */ - case UnmapNotify:{ -#ifdef DEBUG_XEVENTS - printf("window %p: UnmapNotify!\n", data); -#endif - X11_DispatchUnmapNotify(data); - } - break; - - /* Have we been restored? */ - case MapNotify:{ -#ifdef DEBUG_XEVENTS - printf("window %p: MapNotify!\n", data); -#endif - X11_DispatchMapNotify(data); - } - break; - - /* Have we been resized or moved? */ - case ConfigureNotify:{ -#ifdef DEBUG_XEVENTS - printf("window %p: ConfigureNotify! (position: %d,%d, size: %dx%d)\n", data, - xevent.xconfigure.x, xevent.xconfigure.y, - xevent.xconfigure.width, xevent.xconfigure.height); -#endif - /* Real configure notify events are relative to the parent, synthetic events are absolute. */ - if (!xevent.xconfigure.send_event) { - unsigned int NumChildren; - Window ChildReturn, Root, Parent; - Window * Children; - /* Translate these coodinates back to relative to root */ - X11_XQueryTree(data->videodata->display, xevent.xconfigure.window, &Root, &Parent, &Children, &NumChildren); - X11_XTranslateCoordinates(xevent.xconfigure.display, - Parent, DefaultRootWindow(xevent.xconfigure.display), - xevent.xconfigure.x, xevent.xconfigure.y, - &xevent.xconfigure.x, &xevent.xconfigure.y, - &ChildReturn); - } - - if (xevent.xconfigure.x != data->last_xconfigure.x || - xevent.xconfigure.y != data->last_xconfigure.y) { - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED, - xevent.xconfigure.x, xevent.xconfigure.y); -#ifdef SDL_USE_IME - if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){ - /* Update IME candidate list position */ - SDL_IME_UpdateTextRect(NULL); - } -#endif - } - if (xevent.xconfigure.width != data->last_xconfigure.width || - xevent.xconfigure.height != data->last_xconfigure.height) { - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED, - xevent.xconfigure.width, - xevent.xconfigure.height); - } - data->last_xconfigure = xevent.xconfigure; - } - break; - - /* Have we been requested to quit (or another client message?) */ - case ClientMessage:{ - - static int xdnd_version=0; - - if (xevent.xclient.message_type == videodata->XdndEnter) { - - SDL_bool use_list = xevent.xclient.data.l[1] & 1; - data->xdnd_source = xevent.xclient.data.l[0]; - xdnd_version = (xevent.xclient.data.l[1] >> 24); -#ifdef DEBUG_XEVENTS - printf("XID of source window : %ld\n", data->xdnd_source); - printf("Protocol version to use : %d\n", xdnd_version); - printf("More then 3 data types : %d\n", (int) use_list); -#endif - - if (use_list) { - /* fetch conversion targets */ - SDL_x11Prop p; - X11_ReadProperty(&p, display, data->xdnd_source, videodata->XdndTypeList); - /* pick one */ - data->xdnd_req = X11_PickTarget(display, (Atom*)p.data, p.count); - X11_XFree(p.data); - } else { - /* pick from list of three */ - data->xdnd_req = X11_PickTargetFromAtoms(display, xevent.xclient.data.l[2], xevent.xclient.data.l[3], xevent.xclient.data.l[4]); - } - } - else if (xevent.xclient.message_type == videodata->XdndPosition) { - -#ifdef DEBUG_XEVENTS - Atom act= videodata->XdndActionCopy; - if(xdnd_version >= 2) { - act = xevent.xclient.data.l[4]; - } - printf("Action requested by user is : %s\n", X11_XGetAtomName(display , act)); -#endif - - - /* reply with status */ - memset(&m, 0, sizeof(XClientMessageEvent)); - m.type = ClientMessage; - m.display = xevent.xclient.display; - m.window = xevent.xclient.data.l[0]; - m.message_type = videodata->XdndStatus; - m.format=32; - m.data.l[0] = data->xwindow; - m.data.l[1] = (data->xdnd_req != None); - m.data.l[2] = 0; /* specify an empty rectangle */ - m.data.l[3] = 0; - m.data.l[4] = videodata->XdndActionCopy; /* we only accept copying anyway */ - - X11_XSendEvent(display, xevent.xclient.data.l[0], False, NoEventMask, (XEvent*)&m); - X11_XFlush(display); - } - else if(xevent.xclient.message_type == videodata->XdndDrop) { - if (data->xdnd_req == None) { - /* say again - not interested! */ - memset(&m, 0, sizeof(XClientMessageEvent)); - m.type = ClientMessage; - m.display = xevent.xclient.display; - m.window = xevent.xclient.data.l[0]; - m.message_type = videodata->XdndFinished; - m.format=32; - m.data.l[0] = data->xwindow; - m.data.l[1] = 0; - m.data.l[2] = None; /* fail! */ - X11_XSendEvent(display, xevent.xclient.data.l[0], False, NoEventMask, (XEvent*)&m); - } else { - /* convert */ - if(xdnd_version >= 1) { - X11_XConvertSelection(display, videodata->XdndSelection, data->xdnd_req, videodata->PRIMARY, data->xwindow, xevent.xclient.data.l[2]); - } else { - X11_XConvertSelection(display, videodata->XdndSelection, data->xdnd_req, videodata->PRIMARY, data->xwindow, CurrentTime); - } - } - } - else if ((xevent.xclient.message_type == videodata->WM_PROTOCOLS) && - (xevent.xclient.format == 32) && - (xevent.xclient.data.l[0] == videodata->_NET_WM_PING)) { - Window root = DefaultRootWindow(display); - -#ifdef DEBUG_XEVENTS - printf("window %p: _NET_WM_PING\n", data); -#endif - xevent.xclient.window = root; - X11_XSendEvent(display, root, False, SubstructureRedirectMask | SubstructureNotifyMask, &xevent); - break; - } - - else if ((xevent.xclient.message_type == videodata->WM_PROTOCOLS) && - (xevent.xclient.format == 32) && - (xevent.xclient.data.l[0] == videodata->WM_DELETE_WINDOW)) { - -#ifdef DEBUG_XEVENTS - printf("window %p: WM_DELETE_WINDOW\n", data); -#endif - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0); - break; - } - else if ((xevent.xclient.message_type == videodata->WM_PROTOCOLS) && - (xevent.xclient.format == 32) && - (xevent.xclient.data.l[0] == videodata->WM_TAKE_FOCUS)) { - -#ifdef DEBUG_XEVENTS - printf("window %p: WM_TAKE_FOCUS\n", data); -#endif - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_TAKE_FOCUS, 0, 0); - break; - } - } - break; - - /* Do we need to refresh ourselves? */ - case Expose:{ -#ifdef DEBUG_XEVENTS - printf("window %p: Expose (count = %d)\n", data, xevent.xexpose.count); -#endif - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0); - } - break; - - case MotionNotify:{ - SDL_Mouse *mouse = SDL_GetMouse(); - if(!mouse->relative_mode || mouse->relative_mode_warp) { -#ifdef DEBUG_MOTION - printf("window %p: X11 motion: %d,%d\n", data, xevent.xmotion.x, xevent.xmotion.y); -#endif - - SDL_SendMouseMotion(data->window, 0, 0, xevent.xmotion.x, xevent.xmotion.y); - } - } - break; - - case ButtonPress:{ - int xticks = 0, yticks = 0; -#ifdef DEBUG_XEVENTS - printf("window %p: ButtonPress (X11 button = %d)\n", data, xevent.xbutton.button); -#endif - if (X11_IsWheelEvent(display,&xevent,&xticks, &yticks)) { - SDL_SendMouseWheel(data->window, 0, (float) xticks, (float) yticks, SDL_MOUSEWHEEL_NORMAL); - } else { - SDL_bool ignore_click = SDL_FALSE; - int button = xevent.xbutton.button; - if(button == Button1) { - if (ProcessHitTest(_this, data, &xevent)) { - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); - break; /* don't pass this event on to app. */ - } - } - else if(button > 7) { - /* X button values 4-7 are used for scrolling, so X1 is 8, X2 is 9, ... - => subtract (8-SDL_BUTTON_X1) to get value SDL expects */ - button -= (8-SDL_BUTTON_X1); - } - if (data->last_focus_event_time) { - const int X11_FOCUS_CLICK_TIMEOUT = 10; - if (!SDL_TICKS_PASSED(SDL_GetTicks(), data->last_focus_event_time + X11_FOCUS_CLICK_TIMEOUT)) { - ignore_click = !SDL_GetHintBoolean(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, SDL_FALSE); - } - data->last_focus_event_time = 0; - } - if (!ignore_click) { - SDL_SendMouseButton(data->window, 0, SDL_PRESSED, button); - } - } - X11_UpdateUserTime(data, xevent.xbutton.time); - } - break; - - case ButtonRelease:{ - int button = xevent.xbutton.button; - /* The X server sends a Release event for each Press for wheels. Ignore them. */ - int xticks = 0, yticks = 0; -#ifdef DEBUG_XEVENTS - printf("window %p: ButtonRelease (X11 button = %d)\n", data, xevent.xbutton.button); -#endif - if (!X11_IsWheelEvent(display, &xevent, &xticks, &yticks)) { - if (button > 7) { - /* see explanation at case ButtonPress */ - button -= (8-SDL_BUTTON_X1); - } - SDL_SendMouseButton(data->window, 0, SDL_RELEASED, button); - } - } - break; - - case PropertyNotify:{ -#ifdef DEBUG_XEVENTS - unsigned char *propdata; - int status, real_format; - Atom real_type; - unsigned long items_read, items_left; - - char *name = X11_XGetAtomName(display, xevent.xproperty.atom); - if (name) { - printf("window %p: PropertyNotify: %s %s time=%lu\n", data, name, (xevent.xproperty.state == PropertyDelete) ? "deleted" : "changed", xevent.xproperty.time); - X11_XFree(name); - } - - status = X11_XGetWindowProperty(display, data->xwindow, xevent.xproperty.atom, 0L, 8192L, False, AnyPropertyType, &real_type, &real_format, &items_read, &items_left, &propdata); - if (status == Success && items_read > 0) { - if (real_type == XA_INTEGER) { - int *values = (int *)propdata; - - printf("{"); - for (i = 0; i < items_read; i++) { - printf(" %d", values[i]); - } - printf(" }\n"); - } else if (real_type == XA_CARDINAL) { - if (real_format == 32) { - Uint32 *values = (Uint32 *)propdata; - - printf("{"); - for (i = 0; i < items_read; i++) { - printf(" %d", values[i]); - } - printf(" }\n"); - } else if (real_format == 16) { - Uint16 *values = (Uint16 *)propdata; - - printf("{"); - for (i = 0; i < items_read; i++) { - printf(" %d", values[i]); - } - printf(" }\n"); - } else if (real_format == 8) { - Uint8 *values = (Uint8 *)propdata; - - printf("{"); - for (i = 0; i < items_read; i++) { - printf(" %d", values[i]); - } - printf(" }\n"); - } - } else if (real_type == XA_STRING || - real_type == videodata->UTF8_STRING) { - printf("{ \"%s\" }\n", propdata); - } else if (real_type == XA_ATOM) { - Atom *atoms = (Atom *)propdata; - - printf("{"); - for (i = 0; i < items_read; i++) { - char *atomname = X11_XGetAtomName(display, atoms[i]); - if (atomname) { - printf(" %s", atomname); - X11_XFree(atomname); - } - } - printf(" }\n"); - } else { - char *atomname = X11_XGetAtomName(display, real_type); - printf("Unknown type: %ld (%s)\n", real_type, atomname ? atomname : "UNKNOWN"); - if (atomname) { - X11_XFree(atomname); - } - } - } - if (status == Success) { - X11_XFree(propdata); - } -#endif /* DEBUG_XEVENTS */ - - /* Take advantage of this moment to make sure user_time has a - valid timestamp from the X server, so if we later try to - raise/restore this window, _NET_ACTIVE_WINDOW can have a - non-zero timestamp, even if there's never been a mouse or - key press to this window so far. Note that we don't try to - set _NET_WM_USER_TIME here, though. That's only for legit - user interaction with the window. */ - if (!data->user_time) { - data->user_time = xevent.xproperty.time; - } - - if (xevent.xproperty.atom == data->videodata->_NET_WM_STATE) { - /* Get the new state from the window manager. - Compositing window managers can alter visibility of windows - without ever mapping / unmapping them, so we handle that here, - because they use the NETWM protocol to notify us of changes. - */ - const Uint32 flags = X11_GetNetWMState(_this, xevent.xproperty.window); - const Uint32 changed = flags ^ data->window->flags; - - if ((changed & SDL_WINDOW_HIDDEN) || (changed & SDL_WINDOW_FULLSCREEN)) { - if (flags & SDL_WINDOW_HIDDEN) { - X11_DispatchUnmapNotify(data); - } else { - X11_DispatchMapNotify(data); - } - } - - if (changed & SDL_WINDOW_MAXIMIZED) { - if (flags & SDL_WINDOW_MAXIMIZED) { - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MAXIMIZED, 0, 0); - } else { - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESTORED, 0, 0); - } - } - } else if (xevent.xproperty.atom == videodata->XKLAVIER_STATE) { - /* Hack for Ubuntu 12.04 (etc) that doesn't send MappingNotify - events when the keyboard layout changes (for example, - changing from English to French on the menubar's keyboard - icon). Since it changes the XKLAVIER_STATE property, we - notice and reinit our keymap here. This might not be the - right approach, but it seems to work. */ - X11_UpdateKeymap(_this); - SDL_SendKeymapChangedEvent(); - } else if (xevent.xproperty.atom == videodata->_NET_FRAME_EXTENTS) { - Atom type; - int format; - unsigned long nitems, bytes_after; - unsigned char *property; - if (X11_XGetWindowProperty(display, data->xwindow, videodata->_NET_FRAME_EXTENTS, 0, 16, 0, XA_CARDINAL, &type, &format, &nitems, &bytes_after, &property) == Success) { - if (type != None && nitems == 4) { - data->border_left = (int) ((long*)property)[0]; - data->border_right = (int) ((long*)property)[1]; - data->border_top = (int) ((long*)property)[2]; - data->border_bottom = (int) ((long*)property)[3]; - } - X11_XFree(property); - - #ifdef DEBUG_XEVENTS - printf("New _NET_FRAME_EXTENTS: left=%d right=%d, top=%d, bottom=%d\n", data->border_left, data->border_right, data->border_top, data->border_bottom); - #endif - } - } - } - break; - - case SelectionNotify: { - Atom target = xevent.xselection.target; -#ifdef DEBUG_XEVENTS - printf("window %p: SelectionNotify (requestor = %ld, target = %ld)\n", data, - xevent.xselection.requestor, xevent.xselection.target); -#endif - if (target == data->xdnd_req) { - /* read data */ - SDL_x11Prop p; - X11_ReadProperty(&p, display, data->xwindow, videodata->PRIMARY); - - if (p.format == 8) { - /* !!! FIXME: don't use strtok here. It's not reentrant and not in SDL_stdinc. */ - char* name = X11_XGetAtomName(display, target); - char *token = strtok((char *) p.data, "\r\n"); - while (token != NULL) { - if (SDL_strcmp("text/plain", name)==0) { - SDL_SendDropText(data->window, token); - } else if (SDL_strcmp("text/uri-list", name)==0) { - char *fn = X11_URIToLocal(token); - if (fn) { - SDL_SendDropFile(data->window, fn); - } - } - token = strtok(NULL, "\r\n"); - } - SDL_SendDropComplete(data->window); - } - X11_XFree(p.data); - - /* send reply */ - SDL_memset(&m, 0, sizeof(XClientMessageEvent)); - m.type = ClientMessage; - m.display = display; - m.window = data->xdnd_source; - m.message_type = videodata->XdndFinished; - m.format = 32; - m.data.l[0] = data->xwindow; - m.data.l[1] = 1; - m.data.l[2] = videodata->XdndActionCopy; - X11_XSendEvent(display, data->xdnd_source, False, NoEventMask, (XEvent*)&m); - - X11_XSync(display, False); - } - } - break; - - default:{ -#ifdef DEBUG_XEVENTS - printf("window %p: Unhandled event %d\n", data, xevent.type); -#endif - } - break; - } -} - -static void -X11_HandleFocusChanges(_THIS) -{ - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; - int i; - - if (videodata && videodata->windowlist) { - for (i = 0; i < videodata->numwindows; ++i) { - SDL_WindowData *data = videodata->windowlist[i]; - if (data && data->pending_focus != PENDING_FOCUS_NONE) { - Uint32 now = SDL_GetTicks(); - if (SDL_TICKS_PASSED(now, data->pending_focus_time)) { - if (data->pending_focus == PENDING_FOCUS_IN) { - X11_DispatchFocusIn(_this, data); - } else { - X11_DispatchFocusOut(_this, data); - } - data->pending_focus = PENDING_FOCUS_NONE; - } - } - } - } -} -/* Ack! X11_XPending() actually performs a blocking read if no events available */ -static int -X11_Pending(Display * display) -{ - /* Flush the display connection and look to see if events are queued */ - X11_XFlush(display); - if (X11_XEventsQueued(display, QueuedAlready)) { - return (1); - } - - /* More drastic measures are required -- see if X is ready to talk */ - if (SDL_IOReady(ConnectionNumber(display), SDL_FALSE, 0)) { - return (X11_XPending(display)); - } - - /* Oh well, nothing is ready .. */ - return (0); -} - -void -X11_PumpEvents(_THIS) -{ - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; - - if (data->last_mode_change_deadline) { - if (SDL_TICKS_PASSED(SDL_GetTicks(), data->last_mode_change_deadline)) { - data->last_mode_change_deadline = 0; /* assume we're done. */ - } - } - - /* Update activity every 30 seconds to prevent screensaver */ - if (_this->suspend_screensaver) { - const Uint32 now = SDL_GetTicks(); - if (!data->screensaver_activity || - SDL_TICKS_PASSED(now, data->screensaver_activity + 30000)) { - X11_XResetScreenSaver(data->display); - -#if SDL_USE_LIBDBUS - SDL_DBus_ScreensaverTickle(); -#endif - - data->screensaver_activity = now; - } - } - - /* Keep processing pending events */ - while (X11_Pending(data->display)) { - X11_DispatchEvent(_this); - } - -#ifdef SDL_USE_IME - if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){ - SDL_IME_PumpEvents(); - } -#endif - - /* FIXME: Only need to do this when there are pending focus changes */ - X11_HandleFocusChanges(_this); -} - - -void -X11_SuspendScreenSaver(_THIS) -{ -#if SDL_VIDEO_DRIVER_X11_XSCRNSAVER - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; - int dummy; - int major_version, minor_version; -#endif /* SDL_VIDEO_DRIVER_X11_XSCRNSAVER */ - -#if SDL_USE_LIBDBUS - if (SDL_DBus_ScreensaverInhibit(_this->suspend_screensaver)) { - return; - } - - if (_this->suspend_screensaver) { - SDL_DBus_ScreensaverTickle(); - } -#endif - -#if SDL_VIDEO_DRIVER_X11_XSCRNSAVER - if (SDL_X11_HAVE_XSS) { - /* X11_XScreenSaverSuspend was introduced in MIT-SCREEN-SAVER 1.1 */ - if (!X11_XScreenSaverQueryExtension(data->display, &dummy, &dummy) || - !X11_XScreenSaverQueryVersion(data->display, - &major_version, &minor_version) || - major_version < 1 || (major_version == 1 && minor_version < 1)) { - return; - } - - X11_XScreenSaverSuspend(data->display, _this->suspend_screensaver); - X11_XResetScreenSaver(data->display); - } -#endif -} - -#endif /* SDL_VIDEO_DRIVER_X11 */ - -/* vi: set ts=4 sw=4 expandtab: */ |