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"
47 #ifndef _NET_WM_MOVERESIZE_SIZE_TOPLEFT
48 #define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
51 #ifndef _NET_WM_MOVERESIZE_SIZE_TOP
52 #define _NET_WM_MOVERESIZE_SIZE_TOP 1
55 #ifndef _NET_WM_MOVERESIZE_SIZE_TOPRIGHT
56 #define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
59 #ifndef _NET_WM_MOVERESIZE_SIZE_RIGHT
60 #define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
63 #ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT
64 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
67 #ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOM
68 #define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
71 #ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT
72 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
75 #ifndef _NET_WM_MOVERESIZE_SIZE_LEFT
76 #define _NET_WM_MOVERESIZE_SIZE_LEFT 7
79 #ifndef _NET_WM_MOVERESIZE_MOVE
80 #define _NET_WM_MOVERESIZE_MOVE 8
92 static void X11_ReadProperty(SDL_x11Prop *
p, Display *disp, Window
w, Atom prop)
94 unsigned char *ret=
NULL;
98 unsigned long bytes_left;
102 if (ret != 0) X11_XFree(ret);
103 X11_XGetWindowProperty(disp,
w, prop, 0, bytes_fetch, False, AnyPropertyType, &
type, &fmt, &
count, &bytes_left, &ret);
104 bytes_fetch += bytes_left;
105 }
while (bytes_left != 0);
115 static Atom X11_PickTarget(Display *disp, Atom list[],
int list_count)
120 for (
i=0;
i < list_count && request == None;
i++) {
121 name = X11_XGetAtomName(disp, list[
i]);
132 static Atom X11_PickTargetFromAtoms(Display *disp, Atom a0, Atom a1, Atom a2)
136 if (a0 != None) atom[
count++] = a0;
137 if (a1 != None) atom[
count++] = a1;
138 if (a2 != None) atom[
count++] = a2;
139 return X11_PickTarget(disp, atom,
count);
142 struct KeyRepeatCheckData
148 static Bool X11_KeyRepeatCheckIfEvent(Display *display, XEvent *chkev,
151 struct KeyRepeatCheckData *
d = (
struct KeyRepeatCheckData *) arg;
152 if (chkev->type == KeyPress &&
153 chkev->xkey.keycode ==
d->event->xkey.keycode &&
154 chkev->xkey.time -
d->event->xkey.time < 2)
162 static SDL_bool X11_KeyRepeat(Display *display, XEvent *
event)
165 struct KeyRepeatCheckData
d;
168 if (X11_XPending(display))
169 X11_XCheckIfEvent(display, &dummyev, X11_KeyRepeatCheckIfEvent,
175 X11_IsWheelEvent(Display * display,XEvent *
event,
int * xticks,
int * yticks)
182 switch (
event->xbutton.button) {
183 case 4: *yticks = 1;
return SDL_TRUE;
184 case 5: *yticks = -1;
return SDL_TRUE;
185 case 6: *xticks = 1;
return SDL_TRUE;
186 case 7: *xticks = -1;
return SDL_TRUE;
205 static int X11_URIDecode(
char *
buf,
int len) {
215 for (ri = 0, wi = 0, di = 0; ri <
len && wi <
len; ri += 1) {
218 if (
buf[ri] ==
'%') {
227 }
else if (di == 1 || di == 2) {
229 char isa =
buf[ri] >=
'a' &&
buf[ri] <=
'f';
230 char isA =
buf[ri] >=
'A' &&
buf[ri] <=
'F';
231 char isn =
buf[ri] >=
'0' &&
buf[ri] <=
'9';
232 if (!(isa || isA || isn)) {
235 for (sri = ri - di; sri <= ri; sri += 1) {
250 decode |= (
buf[ri] + off) << (2 - di) * 4;
268 static char* X11_URIToLocal(
char* uri) {
272 if (memcmp(uri,
"file:/",6) == 0) uri += 6;
273 else if (strstr(uri,
":/") !=
NULL)
return file;
275 local = uri[0] !=
'/' || (uri[0] !=
'\0' && uri[1] ==
'/');
278 if (!local && uri[0] ==
'/' && uri[2] !=
'/') {
279 char* hostname_end = strchr(uri+1,
'/');
280 if (hostname_end !=
NULL) {
281 char hostname[ 257 ];
282 if (gethostname(hostname, 255) == 0) {
283 hostname[ 256 ] =
'\0';
284 if (memcmp(uri+1, hostname, hostname_end - (uri+1)) == 0) {
285 uri = hostname_end + 1;
294 X11_URIDecode(file, 0);
304 #if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS
305 static void X11_HandleGenericEvent(
SDL_VideoData *videodata, XEvent *xev)
309 if (X11_XGetEventData(videodata->
display, cookie)) {
321 wmmsg.
msg.
x11.event = *xev;
325 X11_XFreeEventData(videodata->
display, cookie);
331 X11_GetNumLockModifierMask(
_THIS)
334 Display *display = viddata->
display;
335 unsigned num_mask = 0;
337 XModifierKeymap *xmods;
340 xmods = X11_XGetModifierMapping(display);
341 n = xmods->max_keypermod;
342 for(
i = 3;
i < 8;
i++) {
343 for(
j = 0;
j <
n;
j++) {
344 KeyCode kc = xmods->modifiermap[
i *
n +
j];
351 X11_XFreeModifiermap(xmods);
357 X11_ReconcileKeyboardState(
_THIS)
360 Display *display = viddata->
display;
366 const Uint8 *keyboardState;
368 X11_XQueryKeymap(display, keys);
371 if (X11_XQueryPointer(display, DefaultRootWindow(display), &junk_window, &junk_window, &
x, &
y, &
x, &
y, &
mask)) {
377 for (keycode = 0; keycode < 256; ++keycode) {
379 SDL_bool x11KeyPressed = (keys[keycode / 8] & (1 << (keycode % 8))) != 0;
382 if (x11KeyPressed && !sdlKeyPressed) {
384 }
else if (!x11KeyPressed && sdlKeyPressed) {
395 printf(
"window %p: Dispatching FocusIn\n",
data);
398 X11_ReconcileKeyboardState(
_this);
399 #ifdef X_HAVE_UTF8_STRING
401 X11_XSetICFocus(
data->ic);
413 printf(
"window %p: Dispatching FocusOut\n",
data);
422 #ifdef X_HAVE_UTF8_STRING
424 X11_XUnsetICFocus(
data->ic);
455 Display *display = viddata->
display;
459 X11_XUngrabPointer(display, 0L);
462 evt.xclient.type = ClientMessage;
463 evt.xclient.window =
data->xwindow;
464 evt.xclient.message_type = X11_XInternAtom(display,
"_NET_WM_MOVERESIZE", True);
465 evt.xclient.format = 32;
466 evt.xclient.data.l[0] =
window->x + point->
x;
467 evt.xclient.data.l[1] =
window->y + point->
y;
468 evt.xclient.data.l[2] = _NET_WM_MOVERESIZE_MOVE;
469 evt.xclient.data.l[3] = Button1;
470 evt.xclient.data.l[4] = 0;
471 X11_XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &evt);
473 X11_XSync(display, 0);
481 Display *display = viddata->
display;
484 if (direction < _NET_WM_MOVERESIZE_SIZE_TOPLEFT || direction > _NET_WM_MOVERESIZE_SIZE_LEFT)
488 X11_XUngrabPointer(display, 0L);
491 evt.xclient.type = ClientMessage;
492 evt.xclient.window =
data->xwindow;
493 evt.xclient.message_type = X11_XInternAtom(display,
"_NET_WM_MOVERESIZE", True);
494 evt.xclient.format = 32;
495 evt.xclient.data.l[0] =
window->x + point->
x;
496 evt.xclient.data.l[1] =
window->y + point->
y;
497 evt.xclient.data.l[2] = direction;
498 evt.xclient.data.l[3] = Button1;
499 evt.xclient.data.l[4] = 0;
500 X11_XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &evt);
502 X11_XSync(display, 0);
511 const SDL_Point point = { xev->xbutton.
x, xev->xbutton.y };
513 static const int directions[] = {
514 _NET_WM_MOVERESIZE_SIZE_TOPLEFT, _NET_WM_MOVERESIZE_SIZE_TOP,
515 _NET_WM_MOVERESIZE_SIZE_TOPRIGHT, _NET_WM_MOVERESIZE_SIZE_RIGHT,
516 _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT, _NET_WM_MOVERESIZE_SIZE_BOTTOM,
517 _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT, _NET_WM_MOVERESIZE_SIZE_LEFT
546 if (latest && (latest !=
data->user_time)) {
548 Display *display = videodata->
display;
550 XA_CARDINAL, 32, PropModeReplace,
551 (
const unsigned char *) &latest, 1);
553 printf(
"window %p: updating _NET_WM_USER_TIME to %lu\n",
data, latest);
555 data->user_time = latest;
560 X11_HandleClipboardEvent(
_THIS,
const XEvent *xevent)
563 Display *display = videodata->
display;
568 switch (xevent->type) {
570 case SelectionRequest: {
571 const XSelectionRequestEvent *req = &xevent->xselectionrequest;
574 unsigned long nbytes;
575 unsigned long overflow;
576 unsigned char *seln_data;
579 printf(
"window CLIPBOARD: SelectionRequest (requestor = %ld, target = %ld)\n",
580 req->requestor, req->target);
584 sevent.xany.type = SelectionNotify;
585 sevent.xselection.selection = req->selection;
586 sevent.xselection.target = None;
587 sevent.xselection.property = None;
588 sevent.xselection.requestor = req->requestor;
589 sevent.xselection.time = req->time;
594 if (X11_XGetWindowProperty(display, DefaultRootWindow(display),
596 &sevent.xselection.target, &seln_format, &nbytes,
597 &overflow, &seln_data) == Success) {
599 Atom XA_TARGETS = X11_XInternAtom(display,
"TARGETS", 0);
600 if (sevent.xselection.target == req->target) {
601 X11_XChangeProperty(display, req->requestor, req->property,
602 sevent.xselection.target, seln_format, PropModeReplace,
604 sevent.xselection.property = req->property;
605 }
else if (XA_TARGETS == req->target) {
606 Atom SupportedFormats[] = { XA_TARGETS, sevent.xselection.target };
607 X11_XChangeProperty(display, req->requestor, req->property,
608 XA_ATOM, 32, PropModeReplace,
609 (
unsigned char*)SupportedFormats,
611 sevent.xselection.property = req->property;
612 sevent.xselection.target = XA_TARGETS;
614 X11_XFree(seln_data);
616 X11_XSendEvent(display, req->requestor, False, 0, &sevent);
617 X11_XSync(display, False);
621 case SelectionNotify: {
623 printf(
"window CLIPBOARD: SelectionNotify (requestor = %ld, target = %ld)\n",
624 xevent->xselection.requestor, xevent->xselection.target);
630 case SelectionClear: {
632 Atom XA_CLIPBOARD = X11_XInternAtom(display,
"CLIPBOARD", 0);
635 printf(
"window CLIPBOARD: SelectionClear (requestor = %ld, target = %ld)\n",
636 xevent->xselection.requestor, xevent->xselection.target);
639 if (xevent->xselectionclear.selection == XA_PRIMARY ||
640 (XA_CLIPBOARD != None && xevent->xselectionclear.selection == XA_CLIPBOARD)) {
649 isMapNotify(Display *display, XEvent *ev, XPointer arg)
653 unmap = (XUnmapEvent*) arg;
655 return ev->type == MapNotify &&
656 ev->xmap.window == unmap->window &&
657 ev->xmap.serial == unmap->serial;
661 isReparentNotify(Display *display, XEvent *ev, XPointer arg)
665 unmap = (XUnmapEvent*) arg;
667 return ev->type == ReparentNotify &&
668 ev->xreparent.window == unmap->window &&
669 ev->xreparent.serial == unmap->serial;
673 X11_DispatchEvent(
_THIS)
680 KeyCode orig_keycode;
681 XClientMessageEvent
m;
690 X11_XNextEvent(display, &xevent);
695 orig_event_type = xevent.type;
696 if (orig_event_type == KeyPress || orig_event_type == KeyRelease) {
697 orig_keycode = xevent.xkey.keycode;
703 if (X11_XFilterEvent(&xevent, None) == True) {
705 printf(
"Filtered event type = %d display = %d window = %d\n",
706 xevent.type, xevent.xany.display, xevent.xany.window);
712 #if defined(HAVE_IBUS_IBUS_H) || defined(HAVE_FCITX)
717 if (orig_event_type == KeyPress) {
727 #if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS
728 if(xevent.type == GenericEvent) {
729 X11_HandleGenericEvent(videodata, &xevent);
740 wmmsg.
msg.
x11.event = xevent;
745 printf(
"type = %d display = %d window = %d\n",
746 xevent.type, xevent.xany.display, xevent.xany.window);
751 X11_HandleClipboardEvent(
_this, &xevent);
767 if (xevent.type == KeymapNotify) {
769 X11_ReconcileKeyboardState(
_this);
771 }
else if (xevent.type == MappingNotify) {
773 const int request = xevent.xmapping.request;
776 printf(
"window %p: MappingNotify!\n",
data);
778 if ((request == MappingKeyboard) || (request == MappingModifier)) {
779 X11_XRefreshKeyboardMapping(&xevent.xmapping);
788 switch (xevent.type) {
794 printf(
"window %p: EnterNotify! (%d,%d,%d)\n",
data,
797 xevent.xcrossing.mode);
798 if (xevent.xcrossing.mode == NotifyGrab)
799 printf(
"Mode: NotifyGrab\n");
800 if (xevent.xcrossing.mode == NotifyUngrab)
801 printf(
"Mode: NotifyUngrab\n");
805 mouse->
last_x = xevent.xcrossing.x;
806 mouse->
last_y = xevent.xcrossing.y;
816 printf(
"window %p: LeaveNotify! (%d,%d,%d)\n",
data,
819 xevent.xcrossing.mode);
820 if (xevent.xcrossing.mode == NotifyGrab)
821 printf(
"Mode: NotifyGrab\n");
822 if (xevent.xcrossing.mode == NotifyUngrab)
823 printf(
"Mode: NotifyUngrab\n");
829 if (xevent.xcrossing.mode != NotifyGrab &&
830 xevent.xcrossing.mode != NotifyUngrab &&
831 xevent.xcrossing.detail != NotifyInferior) {
839 if (xevent.xfocus.mode == NotifyGrab || xevent.xfocus.mode == NotifyUngrab) {
842 printf(
"window %p: FocusIn (NotifyGrab/NotifyUngrab, ignoring)\n",
data);
847 if (xevent.xfocus.detail == NotifyInferior || xevent.xfocus.detail == NotifyPointer) {
849 printf(
"window %p: FocusIn (NotifyInferior/NotifyPointer, ignoring)\n",
data);
854 printf(
"window %p: FocusIn!\n",
data);
859 data->pending_focus_time = 0;
873 if (xevent.xfocus.mode == NotifyGrab || xevent.xfocus.mode == NotifyUngrab) {
876 printf(
"window %p: FocusOut (NotifyGrab/NotifyUngrab, ignoring)\n",
data);
880 if (xevent.xfocus.detail == NotifyInferior || xevent.xfocus.detail == NotifyPointer) {
885 printf(
"window %p: FocusOut (NotifyInferior/NotifyPointer, ignoring)\n",
data);
890 printf(
"window %p: FocusOut!\n",
data);
895 data->pending_focus_time = 0;
908 KeyCode keycode = xevent.xkey.keycode;
909 KeySym keysym = NoSymbol;
915 printf(
"window %p: KeyPress (X11 keycode = 0x%X)\n",
data, xevent.xkey.keycode);
919 int min_keycode, max_keycode;
920 X11_XDisplayKeycodes(display, &min_keycode, &max_keycode);
923 "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",
924 keycode, keycode - min_keycode, keysym,
925 X11_XKeysymToString(keysym));
930 #ifdef X_HAVE_UTF8_STRING
932 X11_Xutf8LookupString(
data->ic, &xevent.xkey,
text,
sizeof(
text),
935 X11_XLookupString(&xevent.xkey,
text,
sizeof(
text), &keysym,
NULL);
938 X11_XLookupString(&xevent.xkey,
text,
sizeof(
text), &keysym,
NULL);
946 if (!handled_by_ime) {
956 X11_UpdateUserTime(
data, xevent.xkey.time);
962 KeyCode keycode = xevent.xkey.keycode;
965 printf(
"window %p: KeyRelease (X11 keycode = 0x%X)\n",
data, xevent.xkey.keycode);
967 if (X11_KeyRepeat(display, &xevent)) {
980 printf(
"window %p: UnmapNotify!\n",
data);
983 if (X11_XCheckIfEvent(display, &ev, &isReparentNotify, (XPointer)&xevent.xunmap)) {
984 X11_XCheckIfEvent(display, &ev, &isMapNotify, (XPointer)&xevent.xunmap);
986 X11_DispatchUnmapNotify(
data);
994 printf(
"window %p: MapNotify!\n",
data);
996 X11_DispatchMapNotify(
data);
1001 case ConfigureNotify:{
1002 #ifdef DEBUG_XEVENTS
1003 printf(
"window %p: ConfigureNotify! (position: %d,%d, size: %dx%d)\n",
data,
1004 xevent.xconfigure.x, xevent.xconfigure.y,
1005 xevent.xconfigure.width, xevent.xconfigure.height);
1008 if (!xevent.xconfigure.send_event) {
1009 unsigned int NumChildren;
1010 Window ChildReturn, Root, Parent;
1013 X11_XQueryTree(
data->videodata->display, xevent.xconfigure.window, &Root, &Parent, &Children, &NumChildren);
1014 X11_XTranslateCoordinates(xevent.xconfigure.display,
1015 Parent, DefaultRootWindow(xevent.xconfigure.display),
1016 xevent.xconfigure.x, xevent.xconfigure.y,
1017 &xevent.xconfigure.x, &xevent.xconfigure.y,
1021 if (xevent.xconfigure.x !=
data->last_xconfigure.x ||
1022 xevent.xconfigure.y !=
data->last_xconfigure.y) {
1024 xevent.xconfigure.x, xevent.xconfigure.y);
1032 if (xevent.xconfigure.width !=
data->last_xconfigure.width ||
1033 xevent.xconfigure.height !=
data->last_xconfigure.height) {
1035 xevent.xconfigure.width,
1036 xevent.xconfigure.height);
1038 data->last_xconfigure = xevent.xconfigure;
1043 case ClientMessage:{
1045 static int xdnd_version=0;
1047 if (xevent.xclient.message_type == videodata->
XdndEnter) {
1049 SDL_bool use_list = xevent.xclient.data.l[1] & 1;
1050 data->xdnd_source = xevent.xclient.data.l[0];
1051 xdnd_version = (xevent.xclient.data.l[1] >> 24);
1052 #ifdef DEBUG_XEVENTS
1053 printf(
"XID of source window : %ld\n",
data->xdnd_source);
1054 printf(
"Protocol version to use : %d\n", xdnd_version);
1055 printf(
"More then 3 data types : %d\n", (
int) use_list);
1063 data->xdnd_req = X11_PickTarget(display, (Atom*)
p.data,
p.count);
1067 data->xdnd_req = X11_PickTargetFromAtoms(display, xevent.xclient.data.l[2], xevent.xclient.data.l[3], xevent.xclient.data.l[4]);
1070 else if (xevent.xclient.message_type == videodata->
XdndPosition) {
1072 #ifdef DEBUG_XEVENTS
1074 if(xdnd_version >= 2) {
1075 act = xevent.xclient.data.l[4];
1077 printf(
"Action requested by user is : %s\n", X11_XGetAtomName(display , act));
1082 memset(&
m, 0,
sizeof(XClientMessageEvent));
1083 m.type = ClientMessage;
1084 m.display = xevent.xclient.display;
1085 m.window = xevent.xclient.data.l[0];
1088 m.data.l[0] =
data->xwindow;
1089 m.data.l[1] = (
data->xdnd_req != None);
1094 X11_XSendEvent(display, xevent.xclient.data.l[0], False, NoEventMask, (XEvent*)&
m);
1095 X11_XFlush(display);
1097 else if(xevent.xclient.message_type == videodata->
XdndDrop) {
1098 if (
data->xdnd_req == None) {
1100 memset(&
m, 0,
sizeof(XClientMessageEvent));
1101 m.type = ClientMessage;
1102 m.display = xevent.xclient.display;
1103 m.window = xevent.xclient.data.l[0];
1106 m.data.l[0] =
data->xwindow;
1109 X11_XSendEvent(display, xevent.xclient.data.l[0], False, NoEventMask, (XEvent*)&
m);
1112 if(xdnd_version >= 1) {
1119 else if ((xevent.xclient.message_type == videodata->
WM_PROTOCOLS) &&
1120 (xevent.xclient.format == 32) &&
1121 (xevent.xclient.data.l[0] == videodata->
_NET_WM_PING)) {
1122 Window root = DefaultRootWindow(display);
1124 #ifdef DEBUG_XEVENTS
1125 printf(
"window %p: _NET_WM_PING\n",
data);
1127 xevent.xclient.window = root;
1128 X11_XSendEvent(display, root, False, SubstructureRedirectMask | SubstructureNotifyMask, &xevent);
1132 else if ((xevent.xclient.message_type == videodata->
WM_PROTOCOLS) &&
1133 (xevent.xclient.format == 32) &&
1136 #ifdef DEBUG_XEVENTS
1137 printf(
"window %p: WM_DELETE_WINDOW\n",
data);
1142 else if ((xevent.xclient.message_type == videodata->
WM_PROTOCOLS) &&
1143 (xevent.xclient.format == 32) &&
1146 #ifdef DEBUG_XEVENTS
1147 printf(
"window %p: WM_TAKE_FOCUS\n",
data);
1157 #ifdef DEBUG_XEVENTS
1158 printf(
"window %p: Expose (count = %d)\n",
data, xevent.xexpose.count);
1168 printf(
"window %p: X11 motion: %d,%d\n",
data, xevent.xmotion.x, xevent.xmotion.y);
1177 int xticks = 0, yticks = 0;
1178 #ifdef DEBUG_XEVENTS
1179 printf(
"window %p: ButtonPress (X11 button = %d)\n",
data, xevent.xbutton.button);
1181 if (X11_IsWheelEvent(display,&xevent,&xticks, &yticks)) {
1185 int button = xevent.xbutton.button;
1187 if (ProcessHitTest(
_this,
data, &xevent)) {
1197 if (
data->last_focus_event_time) {
1198 const int X11_FOCUS_CLICK_TIMEOUT = 10;
1202 data->last_focus_event_time = 0;
1204 if (!ignore_click) {
1208 X11_UpdateUserTime(
data, xevent.xbutton.time);
1212 case ButtonRelease:{
1213 int button = xevent.xbutton.button;
1215 int xticks = 0, yticks = 0;
1216 #ifdef DEBUG_XEVENTS
1217 printf(
"window %p: ButtonRelease (X11 button = %d)\n",
data, xevent.xbutton.button);
1219 if (!X11_IsWheelEvent(display, &xevent, &xticks, &yticks)) {
1229 case PropertyNotify:{
1230 #ifdef DEBUG_XEVENTS
1231 unsigned char *propdata;
1232 int status, real_format;
1234 unsigned long items_read, items_left;
1236 char *
name = X11_XGetAtomName(display, xevent.xproperty.atom);
1238 printf(
"window %p: PropertyNotify: %s %s time=%lu\n",
data,
name, (xevent.xproperty.state == PropertyDelete) ?
"deleted" :
"changed", xevent.xproperty.time);
1242 status = X11_XGetWindowProperty(display,
data->xwindow, xevent.xproperty.atom, 0L, 8192L, False, AnyPropertyType, &real_type, &real_format, &items_read, &items_left, &propdata);
1243 if (status == Success && items_read > 0) {
1244 if (real_type == XA_INTEGER) {
1245 int *
values = (
int *)propdata;
1248 for (
i = 0;
i < items_read;
i++) {
1252 }
else if (real_type == XA_CARDINAL) {
1253 if (real_format == 32) {
1257 for (
i = 0;
i < items_read;
i++) {
1261 }
else if (real_format == 16) {
1265 for (
i = 0;
i < items_read;
i++) {
1269 }
else if (real_format == 8) {
1273 for (
i = 0;
i < items_read;
i++) {
1278 }
else if (real_type == XA_STRING ||
1280 printf(
"{ \"%s\" }\n", propdata);
1281 }
else if (real_type == XA_ATOM) {
1282 Atom *atoms = (Atom *)propdata;
1285 for (
i = 0;
i < items_read;
i++) {
1286 char *atomname = X11_XGetAtomName(display, atoms[
i]);
1288 printf(
" %s", atomname);
1289 X11_XFree(atomname);
1294 char *atomname = X11_XGetAtomName(display, real_type);
1295 printf(
"Unknown type: %ld (%s)\n", real_type, atomname ? atomname :
"UNKNOWN");
1297 X11_XFree(atomname);
1301 if (status == Success) {
1302 X11_XFree(propdata);
1313 if (!
data->user_time) {
1314 data->user_time = xevent.xproperty.time;
1317 if (xevent.xproperty.atom ==
data->videodata->_NET_WM_STATE) {
1328 X11_DispatchUnmapNotify(
data);
1330 X11_DispatchMapNotify(
data);
1353 unsigned long nitems, bytes_after;
1354 unsigned char *property;
1355 if (X11_XGetWindowProperty(display,
data->xwindow, videodata->
_NET_FRAME_EXTENTS, 0, 16, 0, XA_CARDINAL, &
type, &
format, &nitems, &bytes_after, &property) == Success) {
1356 if (
type != None && nitems == 4) {
1357 data->border_left = (
int) ((
long*)property)[0];
1358 data->border_right = (
int) ((
long*)property)[1];
1359 data->border_top = (
int) ((
long*)property)[2];
1360 data->border_bottom = (
int) ((
long*)property)[3];
1362 X11_XFree(property);
1364 #ifdef DEBUG_XEVENTS
1365 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);
1372 case SelectionNotify: {
1373 Atom
target = xevent.xselection.target;
1374 #ifdef DEBUG_XEVENTS
1375 printf(
"window %p: SelectionNotify (requestor = %ld, target = %ld)\n",
data,
1376 xevent.xselection.requestor, xevent.xselection.target);
1381 X11_ReadProperty(&
p, display,
data->xwindow, videodata->
PRIMARY);
1383 if (
p.format == 8) {
1384 char *saveptr =
NULL;
1385 char *
name = X11_XGetAtomName(display,
target);
1387 char *token =
SDL_strtokr((
char *)
p.data,
"\r\n", &saveptr);
1388 while (token !=
NULL) {
1392 char *fn = X11_URIToLocal(token);
1407 m.type = ClientMessage;
1408 m.display = display;
1409 m.window =
data->xdnd_source;
1412 m.data.l[0] =
data->xwindow;
1415 X11_XSendEvent(display,
data->xdnd_source, False, NoEventMask, (XEvent*)&
m);
1417 X11_XSync(display, False);
1423 #ifdef DEBUG_XEVENTS
1424 printf(
"window %p: Unhandled event %d\n",
data, xevent.type);
1432 X11_HandleFocusChanges(
_THIS)
1456 X11_Pending(Display * display)
1459 X11_XFlush(display);
1460 if (X11_XEventsQueued(display, QueuedAlready)) {
1466 return (X11_XPending(display));
1478 if (
data->last_mode_change_deadline) {
1480 data->last_mode_change_deadline = 0;
1487 if (!
data->screensaver_activity ||
1489 X11_XResetScreenSaver(
data->display);
1492 SDL_DBus_ScreensaverTickle();
1495 data->screensaver_activity = now;
1500 while (X11_Pending(
data->display)) {
1501 X11_DispatchEvent(
_this);
1511 X11_HandleFocusChanges(
_this);
1518 #if SDL_VIDEO_DRIVER_X11_XSCRNSAVER
1521 int major_version, minor_version;
1530 SDL_DBus_ScreensaverTickle();
1534 #if SDL_VIDEO_DRIVER_X11_XSCRNSAVER
1535 if (SDL_X11_HAVE_XSS) {
1537 if (!X11_XScreenSaverQueryExtension(
data->display, &dummy, &dummy) ||
1538 !X11_XScreenSaverQueryVersion(
data->display,
1539 &major_version, &minor_version) ||
1540 major_version < 1 || (major_version == 1 && minor_version < 1)) {
1545 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)
SDL_Mouse * SDL_GetMouse(void)
void SDL_SetMouseFocus(SDL_Window *window)
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)
void SDL_UpdateWindowGrab(SDL_Window *window)
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 in i)
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)
#define PENDING_FOCUS_TIME
Uint32 X11_GetNetWMState(_THIS, Window xwindow)
EGLSurface EGLNativeWindowType * window
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld endif[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld_src SRC pixld MASK if DST_R else pixld DST_R endif if
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
SDL_bool relative_mode_warp
The structure that defines a point (integer)
union SDL_SysWMmsg::@8 msg
struct SDL_SysWMmsg::@8::@9 x11
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]
typedef int(__stdcall *FARPROC)()