21 #include "../../SDL_internal.h"
23 #if SDL_VIDEO_DRIVER_X11
25 #include <sys/types.h>
34 #include "../../core/unix/SDL_poll.h"
35 #include "../../events/SDL_events_c.h"
36 #include "../../events/SDL_mouse_c.h"
37 #include "../../events/SDL_touch_c.h"
48 #ifndef _NET_WM_MOVERESIZE_SIZE_TOPLEFT
49 #define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
52 #ifndef _NET_WM_MOVERESIZE_SIZE_TOP
53 #define _NET_WM_MOVERESIZE_SIZE_TOP 1
56 #ifndef _NET_WM_MOVERESIZE_SIZE_TOPRIGHT
57 #define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
60 #ifndef _NET_WM_MOVERESIZE_SIZE_RIGHT
61 #define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
64 #ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT
65 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
68 #ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOM
69 #define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
72 #ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT
73 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
76 #ifndef _NET_WM_MOVERESIZE_SIZE_LEFT
77 #define _NET_WM_MOVERESIZE_SIZE_LEFT 7
80 #ifndef _NET_WM_MOVERESIZE_MOVE
81 #define _NET_WM_MOVERESIZE_MOVE 8
93 static void X11_ReadProperty(SDL_x11Prop *
p, Display *disp, Window
w, Atom prop)
95 unsigned char *ret=
NULL;
99 unsigned long bytes_left;
103 if (ret != 0) X11_XFree(ret);
104 X11_XGetWindowProperty(disp, w, prop, 0, bytes_fetch, False, AnyPropertyType, &type, &fmt, &count, &bytes_left, &ret);
105 bytes_fetch += bytes_left;
106 }
while (bytes_left != 0);
116 static Atom X11_PickTarget(Display *disp, Atom list[],
int list_count)
121 for (i=0; i < list_count && request == None; i++) {
122 name = X11_XGetAtomName(disp, list[i]);
133 static Atom X11_PickTargetFromAtoms(Display *disp, Atom a0, Atom a1, Atom a2)
137 if (a0 != None) atom[count++] = a0;
138 if (a1 != None) atom[count++] = a1;
139 if (a2 != None) atom[count++] = a2;
140 return X11_PickTarget(disp, atom, count);
143 struct KeyRepeatCheckData
149 static Bool X11_KeyRepeatCheckIfEvent(Display *display, XEvent *chkev,
152 struct KeyRepeatCheckData *
d = (
struct KeyRepeatCheckData *) arg;
153 if (chkev->type == KeyPress &&
154 chkev->xkey.keycode == d->event->xkey.keycode &&
155 chkev->xkey.time - d->event->xkey.time < 2)
163 static SDL_bool X11_KeyRepeat(Display *display, XEvent *
event)
166 struct KeyRepeatCheckData d;
169 if (X11_XPending(display))
170 X11_XCheckIfEvent(display, &dummyev, X11_KeyRepeatCheckIfEvent,
176 X11_IsWheelEvent(Display * display,XEvent * event,
int * xticks,
int * yticks)
183 switch (event->xbutton.button) {
184 case 4: *yticks = 1;
return SDL_TRUE;
185 case 5: *yticks = -1;
return SDL_TRUE;
186 case 6: *xticks = 1;
return SDL_TRUE;
187 case 7: *xticks = -1;
return SDL_TRUE;
206 static int X11_URIDecode(
char *
buf,
int len) {
209 if (buf ==
NULL || len < 0) {
216 for (ri = 0, wi = 0, di = 0; ri < len && wi <
len; ri += 1) {
219 if (buf[ri] ==
'%') {
228 }
else if (di == 1 || di == 2) {
230 char isa = buf[ri] >=
'a' && buf[ri] <=
'f';
231 char isA = buf[ri] >=
'A' && buf[ri] <=
'F';
232 char isn = buf[ri] >=
'0' && buf[ri] <=
'9';
233 if (!(isa || isA || isn)) {
236 for (sri = ri - di; sri <= ri; sri += 1) {
251 decode |= (buf[ri] + off) << (2 - di) * 4;
269 static char* X11_URIToLocal(
char* uri) {
273 if (memcmp(uri,
"file:/",6) == 0) uri += 6;
274 else if (strstr(uri,
":/") !=
NULL)
return file;
276 local = uri[0] !=
'/' || (uri[0] !=
'\0' && uri[1] ==
'/');
279 if (!local && uri[0] ==
'/' && uri[2] !=
'/') {
280 char* hostname_end = strchr(uri+1,
'/');
281 if (hostname_end !=
NULL) {
282 char hostname[ 257 ];
283 if (gethostname(hostname, 255) == 0) {
284 hostname[ 256 ] =
'\0';
285 if (memcmp(uri+1, hostname, hostname_end - (uri+1)) == 0) {
286 uri = hostname_end + 1;
295 X11_URIDecode(file, 0);
305 #if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS
306 static void X11_HandleGenericEvent(
SDL_VideoData *videodata, XEvent *xev)
310 if (X11_XGetEventData(videodata->
display, cookie)) {
312 X11_XFreeEventData(videodata->
display, cookie);
318 X11_GetNumLockModifierMask(
_THIS)
321 Display *display = viddata->
display;
322 unsigned num_mask = 0;
324 XModifierKeymap *xmods;
327 xmods = X11_XGetModifierMapping(display);
328 n = xmods->max_keypermod;
329 for(i = 3; i < 8; i++) {
330 for(
j = 0;
j <
n;
j++) {
331 KeyCode kc = xmods->modifiermap[i * n +
j];
338 X11_XFreeModifiermap(xmods);
344 X11_ReconcileKeyboardState(
_THIS)
347 Display *display = viddata->
display;
353 const Uint8 *keyboardState;
355 X11_XQueryKeymap(display, keys);
358 if (X11_XQueryPointer(display, DefaultRootWindow(display), &junk_window, &junk_window, &x, &
y, &x, &
y, &
mask)) {
364 for (keycode = 0; keycode < 256; ++keycode) {
366 SDL_bool x11KeyPressed = (keys[keycode / 8] & (1 << (keycode % 8))) != 0;
369 if (x11KeyPressed && !sdlKeyPressed) {
371 }
else if (!x11KeyPressed && sdlKeyPressed) {
382 printf(
"window %p: Dispatching FocusIn\n", data);
385 X11_ReconcileKeyboardState(
_this);
386 #ifdef X_HAVE_UTF8_STRING
388 X11_XSetICFocus(data->
ic);
400 printf(
"window %p: Dispatching FocusOut\n", data);
409 #ifdef X_HAVE_UTF8_STRING
411 X11_XUnsetICFocus(data->
ic);
438 Display *display = viddata->
display;
442 X11_XUngrabPointer(display, 0L);
445 evt.xclient.type = ClientMessage;
446 evt.xclient.window = data->
xwindow;
447 evt.xclient.message_type = X11_XInternAtom(display,
"_NET_WM_MOVERESIZE", True);
448 evt.xclient.format = 32;
449 evt.xclient.data.l[0] =
window->x + point->
x;
450 evt.xclient.data.l[1] =
window->y + point->
y;
451 evt.xclient.data.l[2] = _NET_WM_MOVERESIZE_MOVE;
452 evt.xclient.data.l[3] = Button1;
453 evt.xclient.data.l[4] = 0;
454 X11_XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &evt);
456 X11_XSync(display, 0);
464 Display *display = viddata->
display;
467 if (direction < _NET_WM_MOVERESIZE_SIZE_TOPLEFT || direction > _NET_WM_MOVERESIZE_SIZE_LEFT)
471 X11_XUngrabPointer(display, 0L);
474 evt.xclient.type = ClientMessage;
475 evt.xclient.window = data->
xwindow;
476 evt.xclient.message_type = X11_XInternAtom(display,
"_NET_WM_MOVERESIZE", True);
477 evt.xclient.format = 32;
478 evt.xclient.data.l[0] =
window->x + point->
x;
479 evt.xclient.data.l[1] =
window->y + point->
y;
480 evt.xclient.data.l[2] = direction;
481 evt.xclient.data.l[3] = Button1;
482 evt.xclient.data.l[4] = 0;
483 X11_XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &evt);
485 X11_XSync(display, 0);
494 const SDL_Point point = { xev->xbutton.
x, xev->xbutton.y };
496 static const int directions[] = {
497 _NET_WM_MOVERESIZE_SIZE_TOPLEFT, _NET_WM_MOVERESIZE_SIZE_TOP,
498 _NET_WM_MOVERESIZE_SIZE_TOPRIGHT, _NET_WM_MOVERESIZE_SIZE_RIGHT,
499 _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT, _NET_WM_MOVERESIZE_SIZE_BOTTOM,
500 _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT, _NET_WM_MOVERESIZE_SIZE_LEFT
505 InitiateWindowMove(
_this, data, &point);
527 X11_UpdateUserTime(
SDL_WindowData *data,
const unsigned long latest)
529 if (latest && (latest != data->
user_time)) {
531 Display *display = videodata->
display;
533 XA_CARDINAL, 32, PropModeReplace,
534 (
const unsigned char *) &latest, 1);
536 printf(
"window %p: updating _NET_WM_USER_TIME to %lu\n", data, latest);
543 X11_HandleClipboardEvent(
_THIS,
const XEvent *xevent)
546 Display *display = videodata->
display;
551 switch (xevent->type) {
553 case SelectionRequest: {
554 const XSelectionRequestEvent *req = &xevent->xselectionrequest;
557 unsigned long nbytes;
558 unsigned long overflow;
559 unsigned char *seln_data;
562 printf(
"window CLIPBOARD: SelectionRequest (requestor = %ld, target = %ld)\n",
563 req->requestor, req->target);
567 sevent.xany.type = SelectionNotify;
568 sevent.xselection.selection = req->selection;
569 sevent.xselection.target = None;
570 sevent.xselection.property = None;
571 sevent.xselection.requestor = req->requestor;
572 sevent.xselection.time = req->time;
577 if (X11_XGetWindowProperty(display, DefaultRootWindow(display),
579 &sevent.xselection.target, &seln_format, &nbytes,
580 &overflow, &seln_data) == Success) {
582 Atom XA_TARGETS = X11_XInternAtom(display,
"TARGETS", 0);
583 if (sevent.xselection.target == req->target) {
584 X11_XChangeProperty(display, req->requestor, req->property,
585 sevent.xselection.target, seln_format, PropModeReplace,
587 sevent.xselection.property = req->property;
588 }
else if (XA_TARGETS == req->target) {
589 Atom SupportedFormats[] = { XA_TARGETS, sevent.xselection.target };
590 X11_XChangeProperty(display, req->requestor, req->property,
591 XA_ATOM, 32, PropModeReplace,
592 (
unsigned char*)SupportedFormats,
594 sevent.xselection.property = req->property;
595 sevent.xselection.target = XA_TARGETS;
597 X11_XFree(seln_data);
599 X11_XSendEvent(display, req->requestor, False, 0, &sevent);
600 X11_XSync(display, False);
604 case SelectionNotify: {
606 printf(
"window CLIPBOARD: SelectionNotify (requestor = %ld, target = %ld)\n",
607 xevent->xselection.requestor, xevent->xselection.target);
613 case SelectionClear: {
615 Atom XA_CLIPBOARD = X11_XInternAtom(display,
"CLIPBOARD", 0);
618 printf(
"window CLIPBOARD: SelectionClear (requestor = %ld, target = %ld)\n",
619 xevent->xselection.requestor, xevent->xselection.target);
622 if (xevent->xselectionclear.selection == XA_PRIMARY ||
623 (XA_CLIPBOARD != None && xevent->xselectionclear.selection == XA_CLIPBOARD)) {
633 X11_DispatchEvent(
_THIS)
640 KeyCode orig_keycode;
641 XClientMessageEvent
m;
650 X11_XNextEvent(display, &xevent);
655 orig_event_type = xevent.type;
656 if (orig_event_type == KeyPress || orig_event_type == KeyRelease) {
657 orig_keycode = xevent.xkey.keycode;
663 if (X11_XFilterEvent(&xevent, None) == True) {
665 printf(
"Filtered event type = %d display = %d window = %d\n",
666 xevent.type, xevent.xany.display, xevent.xany.window);
672 #if defined(HAVE_IBUS_IBUS_H) || defined(HAVE_FCITX_FRONTEND_H)
677 if (orig_event_type == KeyPress) {
693 wmmsg.
msg.
x11.event = xevent;
697 #if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS
698 if(xevent.type == GenericEvent) {
699 X11_HandleGenericEvent(videodata, &xevent);
705 printf(
"type = %d display = %d window = %d\n",
706 xevent.type, xevent.xany.display, xevent.xany.window);
711 X11_HandleClipboardEvent(
_this, &xevent);
727 if (xevent.type == KeymapNotify) {
729 X11_ReconcileKeyboardState(
_this);
731 }
else if (xevent.type == MappingNotify) {
733 const int request = xevent.xmapping.request;
736 printf(
"window %p: MappingNotify!\n", data);
738 if ((request == MappingKeyboard) || (request == MappingModifier)) {
739 X11_XRefreshKeyboardMapping(&xevent.xmapping);
748 switch (xevent.type) {
754 printf(
"window %p: EnterNotify! (%d,%d,%d)\n", data,
757 xevent.xcrossing.mode);
758 if (xevent.xcrossing.mode == NotifyGrab)
759 printf(
"Mode: NotifyGrab\n");
760 if (xevent.xcrossing.mode == NotifyUngrab)
761 printf(
"Mode: NotifyUngrab\n");
765 mouse->
last_x = xevent.xcrossing.x;
766 mouse->
last_y = xevent.xcrossing.y;
776 printf(
"window %p: LeaveNotify! (%d,%d,%d)\n", data,
779 xevent.xcrossing.mode);
780 if (xevent.xcrossing.mode == NotifyGrab)
781 printf(
"Mode: NotifyGrab\n");
782 if (xevent.xcrossing.mode == NotifyUngrab)
783 printf(
"Mode: NotifyUngrab\n");
789 if (xevent.xcrossing.mode != NotifyGrab &&
790 xevent.xcrossing.mode != NotifyUngrab &&
791 xevent.xcrossing.detail != NotifyInferior) {
799 if (xevent.xfocus.mode == NotifyGrab || xevent.xfocus.mode == NotifyUngrab) {
802 printf(
"window %p: FocusIn (NotifyGrab/NotifyUngrab, ignoring)\n", data);
807 if (xevent.xfocus.detail == NotifyInferior) {
809 printf(
"window %p: FocusIn (NotifierInferior, ignoring)\n", data);
814 printf(
"window %p: FocusIn!\n", data);
820 X11_DispatchFocusIn(
_this, data);
833 if (xevent.xfocus.mode == NotifyGrab || xevent.xfocus.mode == NotifyUngrab) {
836 printf(
"window %p: FocusOut (NotifyGrab/NotifyUngrab, ignoring)\n", data);
840 if (xevent.xfocus.detail == NotifyInferior) {
843 printf(
"window %p: FocusOut (NotifierInferior, ignoring)\n", data);
848 printf(
"window %p: FocusOut!\n", data);
854 X11_DispatchFocusOut(
_this, data);
866 KeyCode keycode = xevent.xkey.keycode;
867 KeySym keysym = NoSymbol;
873 printf(
"window %p: KeyPress (X11 keycode = 0x%X)\n", data, xevent.xkey.keycode);
877 int min_keycode, max_keycode;
878 X11_XDisplayKeycodes(display, &min_keycode, &max_keycode);
881 "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",
882 keycode, keycode - min_keycode, keysym,
883 X11_XKeysymToString(keysym));
888 #ifdef X_HAVE_UTF8_STRING
890 X11_Xutf8LookupString(data->
ic, &xevent.xkey, text,
sizeof(text),
893 X11_XLookupString(&xevent.xkey, text,
sizeof(text), &keysym,
NULL);
896 X11_XLookupString(&xevent.xkey, text,
sizeof(text), &keysym,
NULL);
904 if (!handled_by_ime) {
914 X11_UpdateUserTime(data, xevent.xkey.time);
920 KeyCode keycode = xevent.xkey.keycode;
923 printf(
"window %p: KeyRelease (X11 keycode = 0x%X)\n", data, xevent.xkey.keycode);
925 if (X11_KeyRepeat(display, &xevent)) {
936 printf(
"window %p: UnmapNotify!\n", data);
938 X11_DispatchUnmapNotify(data);
945 printf(
"window %p: MapNotify!\n", data);
947 X11_DispatchMapNotify(data);
952 case ConfigureNotify:{
954 printf(
"window %p: ConfigureNotify! (position: %d,%d, size: %dx%d)\n", data,
955 xevent.xconfigure.x, xevent.xconfigure.y,
956 xevent.xconfigure.width, xevent.xconfigure.height);
959 if (!xevent.xconfigure.send_event) {
960 unsigned int NumChildren;
961 Window ChildReturn, Root, Parent;
964 X11_XQueryTree(data->
videodata->
display, xevent.xconfigure.window, &Root, &Parent, &Children, &NumChildren);
965 X11_XTranslateCoordinates(xevent.xconfigure.display,
966 Parent, DefaultRootWindow(xevent.xconfigure.display),
967 xevent.xconfigure.x, xevent.xconfigure.y,
968 &xevent.xconfigure.x, &xevent.xconfigure.y,
975 xevent.xconfigure.x, xevent.xconfigure.y);
986 xevent.xconfigure.width,
987 xevent.xconfigure.height);
996 static int xdnd_version=0;
998 if (xevent.xclient.message_type == videodata->
XdndEnter) {
1000 SDL_bool use_list = xevent.xclient.data.l[1] & 1;
1002 xdnd_version = (xevent.xclient.data.l[1] >> 24);
1003 #ifdef DEBUG_XEVENTS
1004 printf(
"XID of source window : %ld\n", data->
xdnd_source);
1005 printf(
"Protocol version to use : %d\n", xdnd_version);
1006 printf(
"More then 3 data types : %d\n", (
int) use_list);
1014 data->
xdnd_req = X11_PickTarget(display, (Atom*)p.data, p.count);
1018 data->
xdnd_req = X11_PickTargetFromAtoms(display, xevent.xclient.data.l[2], xevent.xclient.data.l[3], xevent.xclient.data.l[4]);
1021 else if (xevent.xclient.message_type == videodata->
XdndPosition) {
1023 #ifdef DEBUG_XEVENTS
1025 if(xdnd_version >= 2) {
1026 act = xevent.xclient.data.l[4];
1028 printf(
"Action requested by user is : %s\n", X11_XGetAtomName(display , act));
1033 memset(&
m, 0,
sizeof(XClientMessageEvent));
1034 m.type = ClientMessage;
1035 m.display = xevent.xclient.display;
1036 m.window = xevent.xclient.data.l[0];
1045 X11_XSendEvent(display, xevent.xclient.data.l[0], False, NoEventMask, (XEvent*)&
m);
1046 X11_XFlush(display);
1048 else if(xevent.xclient.message_type == videodata->
XdndDrop) {
1051 memset(&
m, 0,
sizeof(XClientMessageEvent));
1052 m.type = ClientMessage;
1053 m.display = xevent.xclient.display;
1054 m.window = xevent.xclient.data.l[0];
1060 X11_XSendEvent(display, xevent.xclient.data.l[0], False, NoEventMask, (XEvent*)&
m);
1063 if(xdnd_version >= 1) {
1070 else if ((xevent.xclient.message_type == videodata->
WM_PROTOCOLS) &&
1071 (xevent.xclient.format == 32) &&
1072 (xevent.xclient.data.l[0] == videodata->
_NET_WM_PING)) {
1073 Window root = DefaultRootWindow(display);
1075 #ifdef DEBUG_XEVENTS
1076 printf(
"window %p: _NET_WM_PING\n", data);
1078 xevent.xclient.window = root;
1079 X11_XSendEvent(display, root, False, SubstructureRedirectMask | SubstructureNotifyMask, &xevent);
1083 else if ((xevent.xclient.message_type == videodata->
WM_PROTOCOLS) &&
1084 (xevent.xclient.format == 32) &&
1087 #ifdef DEBUG_XEVENTS
1088 printf(
"window %p: WM_DELETE_WINDOW\n", data);
1093 else if ((xevent.xclient.message_type == videodata->
WM_PROTOCOLS) &&
1094 (xevent.xclient.format == 32) &&
1097 #ifdef DEBUG_XEVENTS
1098 printf(
"window %p: WM_TAKE_FOCUS\n", data);
1108 #ifdef DEBUG_XEVENTS
1109 printf(
"window %p: Expose (count = %d)\n", data, xevent.xexpose.count);
1119 printf(
"window %p: X11 motion: %d,%d\n", data, xevent.xmotion.x, xevent.xmotion.y);
1128 int xticks = 0, yticks = 0;
1129 #ifdef DEBUG_XEVENTS
1130 printf(
"window %p: ButtonPress (X11 button = %d)\n", data, xevent.xbutton.button);
1132 if (X11_IsWheelEvent(display,&xevent,&xticks, &yticks)) {
1136 int button = xevent.xbutton.button;
1137 if(button == Button1) {
1138 if (ProcessHitTest(
_this, data, &xevent)) {
1143 else if(button > 7) {
1149 const int X11_FOCUS_CLICK_TIMEOUT = 10;
1155 if (!ignore_click) {
1159 X11_UpdateUserTime(data, xevent.xbutton.time);
1163 case ButtonRelease:{
1164 int button = xevent.xbutton.button;
1166 int xticks = 0, yticks = 0;
1167 #ifdef DEBUG_XEVENTS
1168 printf(
"window %p: ButtonRelease (X11 button = %d)\n", data, xevent.xbutton.button);
1170 if (!X11_IsWheelEvent(display, &xevent, &xticks, &yticks)) {
1180 case PropertyNotify:{
1181 #ifdef DEBUG_XEVENTS
1182 unsigned char *propdata;
1183 int status, real_format;
1185 unsigned long items_read, items_left;
1187 char *name = X11_XGetAtomName(display, xevent.xproperty.atom);
1189 printf(
"window %p: PropertyNotify: %s %s time=%lu\n", data, name, (xevent.xproperty.state == PropertyDelete) ?
"deleted" :
"changed", xevent.xproperty.time);
1193 status = X11_XGetWindowProperty(display, data->
xwindow, xevent.xproperty.atom, 0L, 8192L, False, AnyPropertyType, &real_type, &real_format, &items_read, &items_left, &propdata);
1194 if (status == Success && items_read > 0) {
1195 if (real_type == XA_INTEGER) {
1196 int *
values = (
int *)propdata;
1199 for (i = 0; i < items_read; i++) {
1200 printf(
" %d", values[i]);
1203 }
else if (real_type == XA_CARDINAL) {
1204 if (real_format == 32) {
1208 for (i = 0; i < items_read; i++) {
1209 printf(
" %d", values[i]);
1212 }
else if (real_format == 16) {
1216 for (i = 0; i < items_read; i++) {
1217 printf(
" %d", values[i]);
1220 }
else if (real_format == 8) {
1224 for (i = 0; i < items_read; i++) {
1225 printf(
" %d", values[i]);
1229 }
else if (real_type == XA_STRING ||
1231 printf(
"{ \"%s\" }\n", propdata);
1232 }
else if (real_type == XA_ATOM) {
1233 Atom *atoms = (Atom *)propdata;
1236 for (i = 0; i < items_read; i++) {
1237 char *atomname = X11_XGetAtomName(display, atoms[i]);
1239 printf(
" %s", atomname);
1240 X11_XFree(atomname);
1245 char *atomname = X11_XGetAtomName(display, real_type);
1246 printf(
"Unknown type: %ld (%s)\n", real_type, atomname ? atomname :
"UNKNOWN");
1248 X11_XFree(atomname);
1252 if (status == Success) {
1253 X11_XFree(propdata);
1265 data->
user_time = xevent.xproperty.time;
1278 if (flags & SDL_WINDOW_HIDDEN) {
1279 X11_DispatchUnmapNotify(data);
1281 X11_DispatchMapNotify(data);
1286 if (flags & SDL_WINDOW_MAXIMIZED) {
1304 unsigned long nitems, bytes_after;
1305 unsigned char *property;
1306 if (X11_XGetWindowProperty(display, data->
xwindow, videodata->
_NET_FRAME_EXTENTS, 0, 16, 0, XA_CARDINAL, &type, &format, &nitems, &bytes_after, &property) == Success) {
1307 if (type != None && nitems == 4) {
1310 data->
border_top = (int) ((
long*)property)[2];
1313 X11_XFree(property);
1315 #ifdef DEBUG_XEVENTS
1323 case SelectionNotify: {
1324 Atom
target = xevent.xselection.target;
1325 #ifdef DEBUG_XEVENTS
1326 printf(
"window %p: SelectionNotify (requestor = %ld, target = %ld)\n", data,
1327 xevent.xselection.requestor, xevent.xselection.target);
1332 X11_ReadProperty(&p, display, data->
xwindow, videodata->
PRIMARY);
1334 if (p.format == 8) {
1336 char* name = X11_XGetAtomName(display, target);
1337 char *token = strtok((
char *) p.data,
"\r\n");
1338 while (token !=
NULL) {
1341 }
else if (
SDL_strcmp(
"text/uri-list", name)==0) {
1342 char *fn = X11_URIToLocal(token);
1347 token = strtok(
NULL,
"\r\n");
1355 m.type = ClientMessage;
1356 m.display = display;
1363 X11_XSendEvent(display, data->
xdnd_source, False, NoEventMask, (XEvent*)&
m);
1365 X11_XSync(display, False);
1371 #ifdef DEBUG_XEVENTS
1372 printf(
"window %p: Unhandled event %d\n", data, xevent.type);
1380 X11_HandleFocusChanges(
_THIS)
1392 X11_DispatchFocusIn(
_this, data);
1394 X11_DispatchFocusOut(
_this, data);
1404 X11_Pending(Display * display)
1407 X11_XFlush(display);
1408 if (X11_XEventsQueued(display, QueuedAlready)) {
1414 return (X11_XPending(display));
1437 X11_XResetScreenSaver(data->
display);
1440 SDL_DBus_ScreensaverTickle();
1448 while (X11_Pending(data->
display)) {
1449 X11_DispatchEvent(
_this);
1459 X11_HandleFocusChanges(
_this);
1466 #if SDL_VIDEO_DRIVER_X11_XSCRNSAVER
1469 int major_version, minor_version;
1478 SDL_DBus_ScreensaverTickle();
1482 #if SDL_VIDEO_DRIVER_X11_XSCRNSAVER
1483 if (SDL_X11_HAVE_XSS) {
1485 if (!X11_XScreenSaverQueryExtension(data->
display, &dummy, &dummy) ||
1486 !X11_XScreenSaverQueryVersion(data->
display,
1487 &major_version, &minor_version) ||
1488 major_version < 1 || (major_version == 1 && minor_version < 1)) {
1493 X11_XResetScreenSaver(data->
display);
void SDL_IME_SetFocus(SDL_bool focused)
void X11_PumpEvents(_THIS)
SDL_Mouse * SDL_GetMouse(void)
int SDL_IOReady(int fd, SDL_bool forWrite, int timeoutMS)
void SDL_SetKeyboardFocus(SDL_Window *window)
Uint32 X11_GetNetWMState(_THIS, Window xwindow)
GLint GLint GLint GLint GLint x
SDL_bool relative_mode_warp
GLuint GLuint GLsizei count
int SDL_SendDropFile(SDL_Window *window, const char *file)
struct wl_display * display
The structure that defines a point.
void SDL_IME_UpdateTextRect(SDL_Rect *rect)
SDL_WindowData ** windowlist
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, int data2)
void SDL_SetMouseFocus(SDL_Window *window)
#define SDL_GetKeyboardFocus
union SDL_SysWMmsg::@16 msg
SDL_bool selection_waiting
int SDL_SendDropComplete(SDL_Window *window)
int SDL_SendSysWMEvent(SDL_SysWMmsg *message)
GLuint const GLchar * name
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
#define SDL_GetHintBoolean
#define SDL_VERSION(x)
Macro to determine SDL version program was compiled against.
static SDL_VideoDevice * _this
SDL_HitTestResult
Possible return values from the SDL_HitTest callback.
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
GLenum GLsizei GLsizei GLint * values
Uint32 screensaver_activity
Uint32 pending_focus_time
int SDL_SendDropText(SDL_Window *window, const char *text)
#define SDL_GetEventState(type)
#define SDL_GetKeyboardState
void X11_SuspendScreenSaver(_THIS)
KeySym X11_KeyCodeToSym(_THIS, KeyCode, unsigned char group)
int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 ** d
struct SDL_VideoData * videodata
int SDL_SendClipboardUpdate(void)
int SDL_SendKeyboardText(const char *text)
GLubyte GLubyte GLubyte GLubyte w
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
GLint GLint GLint GLint GLint GLint y
void X11_UpdateKeymap(_THIS)
GLenum GLuint GLenum GLsizei const GLchar * buf
void SDL_IME_PumpEvents()
void SDL_ToggleModState(const SDL_Keymod modstate, const SDL_bool toggle)
#define SDL_assert(condition)
int SDL_SendMouseWheel(SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction)
Atom X11_GetSDLCutBufferClipboardType(Display *display)
static char text[MAX_TEXT_LENGTH]
struct SDL_SysWMmsg::@16::@17 x11
int SDL_SendKeymapChangedEvent(void)
EGLSurface EGLNativeWindowType * window
#define PENDING_FOCUS_TIME
The type used to identify a window.
XConfigureEvent last_xconfigure
GLuint GLuint GLsizei GLenum type
SDL_bool suspend_screensaver
#define SDL_arraysize(array)
Uint32 last_focus_event_time
#define SDL_TEXTINPUTEVENT_TEXT_SIZE
Uint32 last_mode_change_deadline
#define SDL_TICKS_PASSED(A, B)
Compare SDL ticks values, and return true if A has passed B.
#define SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH
Allow mouse click events when clicking to focus an SDL window.
PendingFocusEnum pending_focus
int SDL_SendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
SDL_Scancode
The SDL keyboard scancode representation.