21#include "../../SDL_internal.h"
23#if SDL_VIDEO_DRIVER_X11
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
93static 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);
116static 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]);
133static 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);
143struct KeyRepeatCheckData
149static 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)
163static SDL_bool X11_KeyRepeat(Display *display, XEvent *
event)
166 struct KeyRepeatCheckData
d;
169 if (X11_XPending(display))
170 X11_XCheckIfEvent(display, &dummyev, X11_KeyRepeatCheckIfEvent,
176X11_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;
206static int X11_URIDecode(
char *
buf,
int len) {
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;
269static 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
306static void X11_HandleGenericEvent(
SDL_VideoData *videodata, XEvent *xev)
310 if (X11_XGetEventData(videodata->
display, cookie)) {
326 X11_XFreeEventData(videodata->
display, cookie);
332X11_GetNumLockModifierMask(
_THIS)
335 Display *display = viddata->
display;
336 unsigned num_mask = 0;
338 XModifierKeymap *xmods;
341 xmods = X11_XGetModifierMapping(display);
342 n = xmods->max_keypermod;
343 for(
i = 3;
i < 8;
i++) {
344 for(
j = 0;
j <
n;
j++) {
345 KeyCode kc = xmods->modifiermap[
i *
n +
j];
352 X11_XFreeModifiermap(xmods);
358X11_ReconcileKeyboardState(
_THIS)
361 Display *display = viddata->
display;
367 const Uint8 *keyboardState;
369 X11_XQueryKeymap(display, keys);
372 if (X11_XQueryPointer(display, DefaultRootWindow(display), &junk_window, &junk_window, &
x, &
y, &
x, &
y, &
mask)) {
378 for (keycode = 0; keycode < 256; ++keycode) {
380 SDL_bool x11KeyPressed = (keys[keycode / 8] & (1 << (keycode % 8))) != 0;
383 if (x11KeyPressed && !sdlKeyPressed) {
385 }
else if (!x11KeyPressed && sdlKeyPressed) {
396 printf(
"window %p: Dispatching FocusIn\n",
data);
399 X11_ReconcileKeyboardState(
_this);
400#ifdef X_HAVE_UTF8_STRING
402 X11_XSetICFocus(
data->ic);
414 printf(
"window %p: Dispatching FocusOut\n",
data);
423#ifdef X_HAVE_UTF8_STRING
425 X11_XUnsetICFocus(
data->ic);
452 Display *display = viddata->
display;
456 X11_XUngrabPointer(display, 0L);
459 evt.xclient.type = ClientMessage;
460 evt.xclient.window =
data->xwindow;
461 evt.xclient.message_type = X11_XInternAtom(display,
"_NET_WM_MOVERESIZE", True);
462 evt.xclient.format = 32;
463 evt.xclient.data.l[0] =
window->x + point->
x;
464 evt.xclient.data.l[1] =
window->y + point->
y;
465 evt.xclient.data.l[2] = _NET_WM_MOVERESIZE_MOVE;
466 evt.xclient.data.l[3] = Button1;
467 evt.xclient.data.l[4] = 0;
468 X11_XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &evt);
470 X11_XSync(display, 0);
478 Display *display = viddata->
display;
481 if (direction < _NET_WM_MOVERESIZE_SIZE_TOPLEFT || direction > _NET_WM_MOVERESIZE_SIZE_LEFT)
485 X11_XUngrabPointer(display, 0L);
488 evt.xclient.type = ClientMessage;
489 evt.xclient.window =
data->xwindow;
490 evt.xclient.message_type = X11_XInternAtom(display,
"_NET_WM_MOVERESIZE", True);
491 evt.xclient.format = 32;
492 evt.xclient.data.l[0] =
window->x + point->
x;
493 evt.xclient.data.l[1] =
window->y + point->
y;
494 evt.xclient.data.l[2] = direction;
495 evt.xclient.data.l[3] = Button1;
496 evt.xclient.data.l[4] = 0;
497 X11_XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &evt);
499 X11_XSync(display, 0);
508 const SDL_Point point = { xev->xbutton.
x, xev->xbutton.y };
510 static const int directions[] = {
511 _NET_WM_MOVERESIZE_SIZE_TOPLEFT, _NET_WM_MOVERESIZE_SIZE_TOP,
512 _NET_WM_MOVERESIZE_SIZE_TOPRIGHT, _NET_WM_MOVERESIZE_SIZE_RIGHT,
513 _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT, _NET_WM_MOVERESIZE_SIZE_BOTTOM,
514 _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT, _NET_WM_MOVERESIZE_SIZE_LEFT
543 if (latest && (latest !=
data->user_time)) {
545 Display *display = videodata->
display;
547 XA_CARDINAL, 32, PropModeReplace,
548 (
const unsigned char *) &latest, 1);
550 printf(
"window %p: updating _NET_WM_USER_TIME to %lu\n",
data, latest);
552 data->user_time = latest;
557X11_HandleClipboardEvent(
_THIS,
const XEvent *xevent)
560 Display *display = videodata->
display;
565 switch (xevent->type) {
567 case SelectionRequest: {
568 const XSelectionRequestEvent *req = &xevent->xselectionrequest;
571 unsigned long nbytes;
572 unsigned long overflow;
573 unsigned char *seln_data;
576 printf(
"window CLIPBOARD: SelectionRequest (requestor = %ld, target = %ld)\n",
577 req->requestor, req->target);
581 sevent.xany.type = SelectionNotify;
582 sevent.xselection.selection = req->selection;
583 sevent.xselection.target = None;
584 sevent.xselection.property = None;
585 sevent.xselection.requestor = req->requestor;
586 sevent.xselection.time = req->time;
591 if (X11_XGetWindowProperty(display, DefaultRootWindow(display),
593 &sevent.xselection.target, &seln_format, &nbytes,
594 &overflow, &seln_data) == Success) {
596 Atom XA_TARGETS = X11_XInternAtom(display,
"TARGETS", 0);
597 if (sevent.xselection.target == req->target) {
598 X11_XChangeProperty(display, req->requestor, req->property,
599 sevent.xselection.target, seln_format, PropModeReplace,
601 sevent.xselection.property = req->property;
602 }
else if (XA_TARGETS == req->target) {
603 Atom SupportedFormats[] = { XA_TARGETS, sevent.xselection.target };
604 X11_XChangeProperty(display, req->requestor, req->property,
605 XA_ATOM, 32, PropModeReplace,
606 (
unsigned char*)SupportedFormats,
608 sevent.xselection.property = req->property;
609 sevent.xselection.target = XA_TARGETS;
611 X11_XFree(seln_data);
613 X11_XSendEvent(display, req->requestor, False, 0, &sevent);
614 X11_XSync(display, False);
618 case SelectionNotify: {
620 printf(
"window CLIPBOARD: SelectionNotify (requestor = %ld, target = %ld)\n",
621 xevent->xselection.requestor, xevent->xselection.target);
627 case SelectionClear: {
629 Atom XA_CLIPBOARD = X11_XInternAtom(display,
"CLIPBOARD", 0);
632 printf(
"window CLIPBOARD: SelectionClear (requestor = %ld, target = %ld)\n",
633 xevent->xselection.requestor, xevent->xselection.target);
636 if (xevent->xselectionclear.selection == XA_PRIMARY ||
637 (XA_CLIPBOARD != None && xevent->xselectionclear.selection == XA_CLIPBOARD)) {
647X11_DispatchEvent(
_THIS)
654 KeyCode orig_keycode;
655 XClientMessageEvent
m;
664 X11_XNextEvent(display, &xevent);
669 orig_event_type = xevent.type;
670 if (orig_event_type == KeyPress || orig_event_type == KeyRelease) {
671 orig_keycode = xevent.xkey.keycode;
677 if (X11_XFilterEvent(&xevent, None) == True) {
679 printf(
"Filtered event type = %d display = %d window = %d\n",
680 xevent.type, xevent.xany.display, xevent.xany.window);
686#if defined(HAVE_IBUS_IBUS_H) || defined(HAVE_FCITX_FRONTEND_H)
691 if (orig_event_type == KeyPress) {
701#if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS
702 if(xevent.type == GenericEvent) {
703 X11_HandleGenericEvent(videodata, &xevent);
719 printf(
"type = %d display = %d window = %d\n",
720 xevent.type, xevent.xany.display, xevent.xany.window);
725 X11_HandleClipboardEvent(
_this, &xevent);
741 if (xevent.type == KeymapNotify) {
743 X11_ReconcileKeyboardState(
_this);
745 }
else if (xevent.type == MappingNotify) {
747 const int request = xevent.xmapping.request;
750 printf(
"window %p: MappingNotify!\n",
data);
752 if ((request == MappingKeyboard) || (request == MappingModifier)) {
753 X11_XRefreshKeyboardMapping(&xevent.xmapping);
762 switch (xevent.type) {
768 printf(
"window %p: EnterNotify! (%d,%d,%d)\n",
data,
771 xevent.xcrossing.mode);
772 if (xevent.xcrossing.mode == NotifyGrab)
773 printf(
"Mode: NotifyGrab\n");
774 if (xevent.xcrossing.mode == NotifyUngrab)
775 printf(
"Mode: NotifyUngrab\n");
779 mouse->
last_x = xevent.xcrossing.x;
780 mouse->
last_y = xevent.xcrossing.y;
790 printf(
"window %p: LeaveNotify! (%d,%d,%d)\n",
data,
793 xevent.xcrossing.mode);
794 if (xevent.xcrossing.mode == NotifyGrab)
795 printf(
"Mode: NotifyGrab\n");
796 if (xevent.xcrossing.mode == NotifyUngrab)
797 printf(
"Mode: NotifyUngrab\n");
803 if (xevent.xcrossing.mode != NotifyGrab &&
804 xevent.xcrossing.mode != NotifyUngrab &&
805 xevent.xcrossing.detail != NotifyInferior) {
813 if (xevent.xfocus.mode == NotifyGrab || xevent.xfocus.mode == NotifyUngrab) {
816 printf(
"window %p: FocusIn (NotifyGrab/NotifyUngrab, ignoring)\n",
data);
821 if (xevent.xfocus.detail == NotifyInferior) {
823 printf(
"window %p: FocusIn (NotifierInferior, ignoring)\n",
data);
828 printf(
"window %p: FocusIn!\n",
data);
833 data->pending_focus_time = 0;
847 if (xevent.xfocus.mode == NotifyGrab || xevent.xfocus.mode == NotifyUngrab) {
850 printf(
"window %p: FocusOut (NotifyGrab/NotifyUngrab, ignoring)\n",
data);
854 if (xevent.xfocus.detail == NotifyInferior) {
857 printf(
"window %p: FocusOut (NotifierInferior, ignoring)\n",
data);
862 printf(
"window %p: FocusOut!\n",
data);
867 data->pending_focus_time = 0;
880 KeyCode keycode = xevent.xkey.keycode;
881 KeySym keysym = NoSymbol;
887 printf(
"window %p: KeyPress (X11 keycode = 0x%X)\n",
data, xevent.xkey.keycode);
891 int min_keycode, max_keycode;
892 X11_XDisplayKeycodes(display, &min_keycode, &max_keycode);
895 "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",
896 keycode, keycode - min_keycode, keysym,
897 X11_XKeysymToString(keysym));
902#ifdef X_HAVE_UTF8_STRING
904 X11_Xutf8LookupString(
data->ic, &xevent.xkey,
text,
sizeof(
text),
907 X11_XLookupString(&xevent.xkey,
text,
sizeof(
text), &keysym,
NULL);
910 X11_XLookupString(&xevent.xkey,
text,
sizeof(
text), &keysym,
NULL);
918 if (!handled_by_ime) {
928 X11_UpdateUserTime(
data, xevent.xkey.time);
934 KeyCode keycode = xevent.xkey.keycode;
937 printf(
"window %p: KeyRelease (X11 keycode = 0x%X)\n",
data, xevent.xkey.keycode);
939 if (X11_KeyRepeat(display, &xevent)) {
950 printf(
"window %p: UnmapNotify!\n",
data);
952 X11_DispatchUnmapNotify(
data);
959 printf(
"window %p: MapNotify!\n",
data);
961 X11_DispatchMapNotify(
data);
966 case ConfigureNotify:{
968 printf(
"window %p: ConfigureNotify! (position: %d,%d, size: %dx%d)\n",
data,
969 xevent.xconfigure.x, xevent.xconfigure.y,
970 xevent.xconfigure.width, xevent.xconfigure.height);
973 if (!xevent.xconfigure.send_event) {
974 unsigned int NumChildren;
975 Window ChildReturn, Root, Parent;
978 X11_XQueryTree(
data->videodata->display, xevent.xconfigure.window, &Root, &Parent, &Children, &NumChildren);
979 X11_XTranslateCoordinates(xevent.xconfigure.display,
980 Parent, DefaultRootWindow(xevent.xconfigure.display),
981 xevent.xconfigure.x, xevent.xconfigure.y,
982 &xevent.xconfigure.x, &xevent.xconfigure.y,
986 if (xevent.xconfigure.x !=
data->last_xconfigure.x ||
987 xevent.xconfigure.y !=
data->last_xconfigure.y) {
989 xevent.xconfigure.x, xevent.xconfigure.y);
997 if (xevent.xconfigure.width !=
data->last_xconfigure.width ||
998 xevent.xconfigure.height !=
data->last_xconfigure.height) {
1000 xevent.xconfigure.width,
1001 xevent.xconfigure.height);
1003 data->last_xconfigure = xevent.xconfigure;
1008 case ClientMessage:{
1010 static int xdnd_version=0;
1012 if (xevent.xclient.message_type == videodata->
XdndEnter) {
1014 SDL_bool use_list = xevent.xclient.data.l[1] & 1;
1015 data->xdnd_source = xevent.xclient.data.l[0];
1016 xdnd_version = (xevent.xclient.data.l[1] >> 24);
1018 printf(
"XID of source window : %ld\n",
data->xdnd_source);
1019 printf(
"Protocol version to use : %d\n", xdnd_version);
1020 printf(
"More then 3 data types : %d\n", (
int) use_list);
1028 data->xdnd_req = X11_PickTarget(display, (Atom*)
p.data,
p.count);
1032 data->xdnd_req = X11_PickTargetFromAtoms(display, xevent.xclient.data.l[2], xevent.xclient.data.l[3], xevent.xclient.data.l[4]);
1035 else if (xevent.xclient.message_type == videodata->
XdndPosition) {
1039 if(xdnd_version >= 2) {
1040 act = xevent.xclient.data.l[4];
1042 printf(
"Action requested by user is : %s\n", X11_XGetAtomName(display , act));
1047 memset(&
m, 0,
sizeof(XClientMessageEvent));
1048 m.type = ClientMessage;
1049 m.display = xevent.xclient.display;
1050 m.window = xevent.xclient.data.l[0];
1053 m.data.l[0] =
data->xwindow;
1054 m.data.l[1] = (
data->xdnd_req != None);
1059 X11_XSendEvent(display, xevent.xclient.data.l[0], False, NoEventMask, (XEvent*)&
m);
1060 X11_XFlush(display);
1062 else if(xevent.xclient.message_type == videodata->
XdndDrop) {
1063 if (
data->xdnd_req == None) {
1065 memset(&
m, 0,
sizeof(XClientMessageEvent));
1066 m.type = ClientMessage;
1067 m.display = xevent.xclient.display;
1068 m.window = xevent.xclient.data.l[0];
1071 m.data.l[0] =
data->xwindow;
1074 X11_XSendEvent(display, xevent.xclient.data.l[0], False, NoEventMask, (XEvent*)&
m);
1077 if(xdnd_version >= 1) {
1084 else if ((xevent.xclient.message_type == videodata->
WM_PROTOCOLS) &&
1085 (xevent.xclient.format == 32) &&
1086 (xevent.xclient.data.l[0] == videodata->
_NET_WM_PING)) {
1087 Window root = DefaultRootWindow(display);
1090 printf(
"window %p: _NET_WM_PING\n",
data);
1092 xevent.xclient.window = root;
1093 X11_XSendEvent(display, root, False, SubstructureRedirectMask | SubstructureNotifyMask, &xevent);
1097 else if ((xevent.xclient.message_type == videodata->
WM_PROTOCOLS) &&
1098 (xevent.xclient.format == 32) &&
1102 printf(
"window %p: WM_DELETE_WINDOW\n",
data);
1107 else if ((xevent.xclient.message_type == videodata->
WM_PROTOCOLS) &&
1108 (xevent.xclient.format == 32) &&
1112 printf(
"window %p: WM_TAKE_FOCUS\n",
data);
1123 printf(
"window %p: Expose (count = %d)\n",
data, xevent.xexpose.count);
1133 printf(
"window %p: X11 motion: %d,%d\n",
data, xevent.xmotion.x, xevent.xmotion.y);
1142 int xticks = 0, yticks = 0;
1144 printf(
"window %p: ButtonPress (X11 button = %d)\n",
data, xevent.xbutton.button);
1146 if (X11_IsWheelEvent(display,&xevent,&xticks, &yticks)) {
1150 int button = xevent.xbutton.button;
1152 if (ProcessHitTest(
_this,
data, &xevent)) {
1162 if (
data->last_focus_event_time) {
1163 const int X11_FOCUS_CLICK_TIMEOUT = 10;
1167 data->last_focus_event_time = 0;
1169 if (!ignore_click) {
1173 X11_UpdateUserTime(
data, xevent.xbutton.time);
1177 case ButtonRelease:{
1178 int button = xevent.xbutton.button;
1180 int xticks = 0, yticks = 0;
1182 printf(
"window %p: ButtonRelease (X11 button = %d)\n",
data, xevent.xbutton.button);
1184 if (!X11_IsWheelEvent(display, &xevent, &xticks, &yticks)) {
1194 case PropertyNotify:{
1196 unsigned char *propdata;
1197 int status, real_format;
1199 unsigned long items_read, items_left;
1201 char *
name = X11_XGetAtomName(display, xevent.xproperty.atom);
1203 printf(
"window %p: PropertyNotify: %s %s time=%lu\n",
data,
name, (xevent.xproperty.state == PropertyDelete) ?
"deleted" :
"changed", xevent.xproperty.time);
1207 status = X11_XGetWindowProperty(display,
data->xwindow, xevent.xproperty.atom, 0L, 8192L, False, AnyPropertyType, &real_type, &real_format, &items_read, &items_left, &propdata);
1208 if (status == Success && items_read > 0) {
1209 if (real_type == XA_INTEGER) {
1210 int *
values = (
int *)propdata;
1213 for (
i = 0;
i < items_read;
i++) {
1217 }
else if (real_type == XA_CARDINAL) {
1218 if (real_format == 32) {
1222 for (
i = 0;
i < items_read;
i++) {
1226 }
else if (real_format == 16) {
1230 for (
i = 0;
i < items_read;
i++) {
1234 }
else if (real_format == 8) {
1238 for (
i = 0;
i < items_read;
i++) {
1243 }
else if (real_type == XA_STRING ||
1245 printf(
"{ \"%s\" }\n", propdata);
1246 }
else if (real_type == XA_ATOM) {
1247 Atom *atoms = (Atom *)propdata;
1250 for (
i = 0;
i < items_read;
i++) {
1251 char *atomname = X11_XGetAtomName(display, atoms[
i]);
1253 printf(
" %s", atomname);
1254 X11_XFree(atomname);
1259 char *atomname = X11_XGetAtomName(display, real_type);
1260 printf(
"Unknown type: %ld (%s)\n", real_type, atomname ? atomname :
"UNKNOWN");
1262 X11_XFree(atomname);
1266 if (status == Success) {
1267 X11_XFree(propdata);
1278 if (!
data->user_time) {
1279 data->user_time = xevent.xproperty.time;
1282 if (xevent.xproperty.atom ==
data->videodata->_NET_WM_STATE) {
1293 X11_DispatchUnmapNotify(
data);
1295 X11_DispatchMapNotify(
data);
1318 unsigned long nitems, bytes_after;
1319 unsigned char *property;
1320 if (X11_XGetWindowProperty(display,
data->xwindow, videodata->
_NET_FRAME_EXTENTS, 0, 16, 0, XA_CARDINAL, &
type, &
format, &nitems, &bytes_after, &property) == Success) {
1321 if (
type != None && nitems == 4) {
1322 data->border_left = (int) ((
long*)property)[0];
1323 data->border_right = (int) ((
long*)property)[1];
1324 data->border_top = (int) ((
long*)property)[2];
1325 data->border_bottom = (int) ((
long*)property)[3];
1327 X11_XFree(property);
1329 #ifdef DEBUG_XEVENTS
1330 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);
1337 case SelectionNotify: {
1338 Atom
target = xevent.xselection.target;
1340 printf(
"window %p: SelectionNotify (requestor = %ld, target = %ld)\n",
data,
1341 xevent.xselection.requestor, xevent.xselection.target);
1346 X11_ReadProperty(&
p, display,
data->xwindow, videodata->
PRIMARY);
1348 if (
p.format == 8) {
1350 char*
name = X11_XGetAtomName(display,
target);
1351 char *token = strtok((
char *)
p.data,
"\r\n");
1352 while (token !=
NULL) {
1356 char *fn = X11_URIToLocal(token);
1361 token = strtok(
NULL,
"\r\n");
1369 m.type = ClientMessage;
1370 m.display = display;
1371 m.window =
data->xdnd_source;
1374 m.data.l[0] =
data->xwindow;
1377 X11_XSendEvent(display,
data->xdnd_source, False, NoEventMask, (XEvent*)&
m);
1379 X11_XSync(display, False);
1386 printf(
"window %p: Unhandled event %d\n",
data, xevent.type);
1394X11_HandleFocusChanges(
_THIS)
1418X11_Pending(Display * display)
1421 X11_XFlush(display);
1422 if (X11_XEventsQueued(display, QueuedAlready)) {
1428 return (X11_XPending(display));
1440 if (
data->last_mode_change_deadline) {
1442 data->last_mode_change_deadline = 0;
1449 if (!
data->screensaver_activity ||
1451 X11_XResetScreenSaver(
data->display);
1454 SDL_DBus_ScreensaverTickle();
1457 data->screensaver_activity = now;
1462 while (X11_Pending(
data->display)) {
1463 X11_DispatchEvent(
_this);
1473 X11_HandleFocusChanges(
_this);
1480#if SDL_VIDEO_DRIVER_X11_XSCRNSAVER
1483 int major_version, minor_version;
1492 SDL_DBus_ScreensaverTickle();
1496#if SDL_VIDEO_DRIVER_X11_XSCRNSAVER
1497 if (SDL_X11_HAVE_XSS) {
1499 if (!X11_XScreenSaverQueryExtension(
data->display, &dummy, &dummy) ||
1500 !X11_XScreenSaverQueryVersion(
data->display,
1501 &major_version, &minor_version) ||
1502 major_version < 1 || (major_version == 1 && minor_version < 1)) {
1507 X11_XResetScreenSaver(
data->display);
#define SDL_assert(condition)
int SDL_SendClipboardUpdate(void)
int SDL_SendDropText(SDL_Window *window, const char *text)
int SDL_SendDropFile(SDL_Window *window, const char *file)
int SDL_SendDropComplete(SDL_Window *window)
#define SDL_GetKeyboardFocus
#define SDL_GetKeyboardState
#define SDL_GetHintBoolean
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
int SDL_SendKeymapChangedEvent(void)
int SDL_SendSysWMEvent(SDL_SysWMmsg *message)
#define SDL_TEXTINPUTEVENT_TEXT_SIZE
#define SDL_GetEventState(type)
#define SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH
Allow mouse click events when clicking to focus an SDL window.
void SDL_IME_PumpEvents()
void SDL_IME_UpdateTextRect(SDL_Rect *rect)
void SDL_IME_SetFocus(SDL_bool focused)
SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
void SDL_ToggleModState(const SDL_Keymod modstate, const SDL_bool toggle)
void SDL_SetKeyboardFocus(SDL_Window *window)
int SDL_SendKeyboardText(const char *text)
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
int SDL_SendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
void SDL_SetMouseFocus(SDL_Window *window)
SDL_Mouse * SDL_GetMouse(void)
int SDL_SendMouseWheel(SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction)
int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
GLint GLint GLint GLint GLint GLint y
GLuint GLuint GLsizei count
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLint GLint GLint GLint GLint x
GLuint GLuint GLsizei GLenum type
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
GLenum GLsizei GLsizei GLint * values
GLuint const GLchar * name
GLenum GLuint GLenum GLsizei const GLchar * buf
GLubyte GLubyte GLubyte GLubyte w
int SDL_IOReady(int fd, SDL_bool forWrite, int timeoutMS)
SDL_Scancode
The SDL keyboard scancode representation.
@ SDL_SCANCODE_NUMLOCKCLEAR
#define SDL_arraysize(array)
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
#define SDL_TICKS_PASSED(A, B)
Compare SDL ticks values, and return true if A has passed B.
#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.
@ SDL_HITTEST_RESIZE_LEFT
@ SDL_HITTEST_RESIZE_TOPRIGHT
@ SDL_HITTEST_RESIZE_BOTTOM
@ SDL_HITTEST_RESIZE_BOTTOMRIGHT
@ SDL_HITTEST_RESIZE_BOTTOMLEFT
@ SDL_HITTEST_RESIZE_RIGHT
@ SDL_HITTEST_RESIZE_TOPLEFT
@ SDL_WINDOWEVENT_RESIZED
@ SDL_WINDOWEVENT_HIT_TEST
@ SDL_WINDOWEVENT_TAKE_FOCUS
@ SDL_WINDOWEVENT_MINIMIZED
@ SDL_WINDOWEVENT_MAXIMIZED
@ SDL_WINDOWEVENT_RESTORED
@ SDL_WINDOWEVENT_EXPOSED
int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, int data2)
Atom X11_GetSDLCutBufferClipboardType(Display *display)
void X11_SuspendScreenSaver(_THIS)
void X11_PumpEvents(_THIS)
void X11_UpdateKeymap(_THIS)
KeySym X11_KeyCodeToSym(_THIS, KeyCode, unsigned char group)
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)
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)
#define PENDING_FOCUS_TIME
Uint32 X11_GetNetWMState(_THIS, Window xwindow)
EGLSurface EGLNativeWindowType * window
SDL_bool relative_mode_warp
The structure that defines a point (integer)
struct SDL_SysWMmsg::@15::@16 x11
union SDL_SysWMmsg::@15 msg
SDL_bool selection_waiting
SDL_WindowData ** windowlist
Uint32 last_mode_change_deadline
struct wl_display * display
SDL_bool suspend_screensaver
The type used to identify a window.
static char text[MAX_TEXT_LENGTH]