2006-07-27 06:53:23 +00:00
/*
2011-04-08 13:03:26 -07:00
Simple DirectMedia Layer
2014-02-02 00:53:27 -08:00
Copyright ( C ) 1997 - 2014 Sam Lantinga < slouken @ libsdl . org >
2006-07-27 06:53:23 +00:00
2011-04-08 13:03:26 -07:00
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 .
2006-07-27 06:53:23 +00:00
2011-04-08 13:03:26 -07:00
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 :
2006-07-27 06:53:23 +00:00
2011-04-08 13:03:26 -07:00
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 .
2006-07-27 06:53:23 +00:00
*/
2013-11-24 23:56:17 -05:00
# include "../../SDL_internal.h"
2006-07-27 06:53:23 +00:00
2011-03-12 13:21:57 -08:00
# if SDL_VIDEO_DRIVER_X11
2006-10-01 02:28:41 +00:00
# include <sys/types.h>
# include <sys/time.h>
2010-05-09 20:47:22 -07:00
# include <signal.h>
2006-10-01 02:28:41 +00:00
# include <unistd.h>
2010-07-20 00:05:32 -07:00
# include <limits.h> /* For INT_MAX */
2006-10-01 02:28:41 +00:00
2006-07-27 06:53:23 +00:00
# include "SDL_x11video.h"
2010-12-30 13:21:39 -08:00
# include "SDL_x11touch.h"
2012-05-31 13:37:02 +03:00
# include "SDL_x11xinput2.h"
2006-07-27 06:53:23 +00:00
# include "../../events/SDL_events_c.h"
2009-01-01 07:59:08 +00:00
# include "../../events/SDL_mouse_c.h"
2010-05-28 01:26:52 -04:00
# include "../../events/SDL_touch_c.h"
2006-07-27 06:53:23 +00:00
2010-05-09 20:47:22 -07:00
# include "SDL_timer.h"
2009-09-05 07:33:54 +00:00
# include "SDL_syswm.h"
2010-05-28 01:26:52 -04:00
# include <stdio.h>
2014-06-05 00:45:16 -04:00
# 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
2014-05-27 15:47:25 -04:00
# ifndef _NET_WM_MOVERESIZE_MOVE
2014-06-05 00:45:16 -04:00
# define _NET_WM_MOVERESIZE_MOVE 8
2014-05-27 15:47:25 -04:00
# endif
2013-03-13 21:41:43 -07:00
typedef struct {
2013-05-18 14:17:52 -07:00
unsigned char * data ;
int format , count ;
Atom type ;
2013-03-13 21:41:43 -07:00
} SDL_x11Prop ;
/* Reads property
2013-10-18 01:36:41 -04:00
Must call X11_XFree on results
2013-03-13 21:41:43 -07:00
*/
2013-05-18 14:17:52 -07:00
static void X11_ReadProperty ( SDL_x11Prop * p , Display * disp , Window w , Atom prop )
2013-03-13 21:41:43 -07:00
{
unsigned char * ret = NULL ;
Atom type ;
int fmt ;
unsigned long count ;
unsigned long bytes_left ;
2013-05-18 14:17:52 -07:00
int bytes_fetch = 0 ;
2013-03-13 21:41:43 -07:00
do {
2013-10-18 01:36:41 -04:00
if ( ret ! = 0 ) X11_XFree ( ret ) ;
X11_XGetWindowProperty ( disp , w , prop , 0 , bytes_fetch , False , AnyPropertyType , & type , & fmt , & count , & bytes_left , & ret ) ;
2013-03-13 21:41:43 -07:00
bytes_fetch + = bytes_left ;
} while ( bytes_left ! = 0 ) ;
2013-05-18 14:17:52 -07:00
2013-03-13 21:41:43 -07:00
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 + + ) {
2013-10-18 01:36:41 -04:00
name = X11_XGetAtomName ( disp , list [ i ] ) ;
2013-03-13 21:41:43 -07:00
if ( strcmp ( " text/uri-list " , name ) = = 0 ) request = list [ i ] ;
2013-10-18 01:36:41 -04:00
X11_XFree ( name ) ;
2013-03-13 21:41:43 -07:00
}
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 ) ;
}
2013-08-21 09:47:10 -03:00
/* #define DEBUG_XEVENTS */
2012-09-27 13:22:34 -07:00
2013-07-20 13:11:40 -04:00
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 ;
}
2010-07-21 21:47:12 -07:00
/* 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 )
{
2013-07-20 13:11:40 -04:00
XEvent dummyev ;
struct KeyRepeatCheckData d ;
d . event = event ;
d . found = SDL_FALSE ;
2013-10-18 01:36:41 -04:00
if ( X11_XPending ( display ) )
X11_XCheckIfEvent ( display , & dummyev , X11_KeyRepeatCheckIfEvent ,
2013-07-20 13:11:40 -04:00
( XPointer ) & d ) ;
return d . found ;
}
2010-07-21 21:47:12 -07:00
2013-07-20 13:11:40 -04:00
static Bool X11_IsWheelCheckIfEvent ( Display * display , XEvent * chkev ,
XPointer arg )
{
XEvent * event = ( XEvent * ) arg ;
2013-09-27 23:35:17 -07:00
/* we only handle buttons 4 and 5 - false positive avoidance */
2013-07-20 13:11:40 -04:00
if ( chkev - > type = = ButtonRelease & &
2013-09-27 23:35:17 -07:00
( event - > xbutton . button = = Button4 | | event - > xbutton . button = = Button5 ) & &
2013-07-20 13:11:40 -04:00
chkev - > xbutton . button = = event - > xbutton . button & &
chkev - > xbutton . time = = event - > xbutton . time )
return True ;
return False ;
2010-07-21 21:47:12 -07:00
}
Fixed bug 1173 (No mouse wheel event on linux/x11)
Matthias 2011-03-20 23:07:02 PDT
On X11, SDL 1.3 does not generate a mouse wheel event. Instead, button
down/buttton up events are generated by SDL. After looking at the code in
SDL_x11events.c, I assume this is due to the fact that X11 does not have a
dedicated mouse wheel event.
I did a little research on the behavior of mouse wheel events on X11 systems.
Apparently, mouse wheel events generate a button down/button up event with the
same time, i.e. with exact same timestamp.
Attached you can find my changes to SDL_x11events.c, which generates SDL mouse
wheel events for those button down events that have a button release event
immediately following it (for the same button, and with the same timestamp).
I did have to make an assumption: As standard X11 implementations know only 5
buttons, I have mapped Button4 to "wheel up" (i.e. +1), and Button5 to "wheel
down" (i.e. -1).
Note that if you include this patch, no SDL button down/up events will be
generated on X11 platforms for mouse wheel events (which is probably a
significant change for those that have programmed their code to work with
them).
2011-04-05 09:35:56 -07:00
static SDL_bool X11_IsWheelEvent ( Display * display , XEvent * event , int * ticks )
{
2013-07-20 13:11:40 -04:00
XEvent relevent ;
2013-10-18 01:36:41 -04:00
if ( X11_XPending ( display ) ) {
Fixed bug 1173 (No mouse wheel event on linux/x11)
Matthias 2011-03-20 23:07:02 PDT
On X11, SDL 1.3 does not generate a mouse wheel event. Instead, button
down/buttton up events are generated by SDL. After looking at the code in
SDL_x11events.c, I assume this is due to the fact that X11 does not have a
dedicated mouse wheel event.
I did a little research on the behavior of mouse wheel events on X11 systems.
Apparently, mouse wheel events generate a button down/button up event with the
same time, i.e. with exact same timestamp.
Attached you can find my changes to SDL_x11events.c, which generates SDL mouse
wheel events for those button down events that have a button release event
immediately following it (for the same button, and with the same timestamp).
I did have to make an assumption: As standard X11 implementations know only 5
buttons, I have mapped Button4 to "wheel up" (i.e. +1), and Button5 to "wheel
down" (i.e. -1).
Note that if you include this patch, no SDL button down/up events will be
generated on X11 platforms for mouse wheel events (which is probably a
significant change for those that have programmed their code to work with
them).
2011-04-05 09:35:56 -07:00
/* according to the xlib docs, no specific mouse wheel events exist.
however , mouse wheel events trigger a button press and a button release
immediately . thus , checking if the same button was released at the same
2013-05-18 14:17:52 -07:00
time as it was pressed , should be an adequate hack to derive a mouse
2013-09-27 23:35:17 -07:00
wheel event .
However , there is broken and unusual hardware out there . . .
- False positive : a button for which a release event is
generated ( or synthesised ) immediately .
- False negative : a wheel which , when rolled , doesn ' t have
a release event generated immediately . */
2013-10-18 01:36:41 -04:00
if ( X11_XCheckIfEvent ( display , & relevent , X11_IsWheelCheckIfEvent ,
2013-07-20 13:11:40 -04:00
( XPointer ) event ) ) {
Fixed bug 1173 (No mouse wheel event on linux/x11)
Matthias 2011-03-20 23:07:02 PDT
On X11, SDL 1.3 does not generate a mouse wheel event. Instead, button
down/buttton up events are generated by SDL. After looking at the code in
SDL_x11events.c, I assume this is due to the fact that X11 does not have a
dedicated mouse wheel event.
I did a little research on the behavior of mouse wheel events on X11 systems.
Apparently, mouse wheel events generate a button down/button up event with the
same time, i.e. with exact same timestamp.
Attached you can find my changes to SDL_x11events.c, which generates SDL mouse
wheel events for those button down events that have a button release event
immediately following it (for the same button, and with the same timestamp).
I did have to make an assumption: As standard X11 implementations know only 5
buttons, I have mapped Button4 to "wheel up" (i.e. +1), and Button5 to "wheel
down" (i.e. -1).
Note that if you include this patch, no SDL button down/up events will be
generated on X11 platforms for mouse wheel events (which is probably a
significant change for those that have programmed their code to work with
them).
2011-04-05 09:35:56 -07:00
/* by default, X11 only knows 5 buttons. on most 3 button + wheel mouse,
Button4 maps to wheel up , Button5 maps to wheel down . */
if ( event - > xbutton . button = = Button4 ) {
* ticks = 1 ;
}
2012-01-08 00:36:32 -05:00
else if ( event - > xbutton . button = = Button5 ) {
Fixed bug 1173 (No mouse wheel event on linux/x11)
Matthias 2011-03-20 23:07:02 PDT
On X11, SDL 1.3 does not generate a mouse wheel event. Instead, button
down/buttton up events are generated by SDL. After looking at the code in
SDL_x11events.c, I assume this is due to the fact that X11 does not have a
dedicated mouse wheel event.
I did a little research on the behavior of mouse wheel events on X11 systems.
Apparently, mouse wheel events generate a button down/button up event with the
same time, i.e. with exact same timestamp.
Attached you can find my changes to SDL_x11events.c, which generates SDL mouse
wheel events for those button down events that have a button release event
immediately following it (for the same button, and with the same timestamp).
I did have to make an assumption: As standard X11 implementations know only 5
buttons, I have mapped Button4 to "wheel up" (i.e. +1), and Button5 to "wheel
down" (i.e. -1).
Note that if you include this patch, no SDL button down/up events will be
generated on X11 platforms for mouse wheel events (which is probably a
significant change for those that have programmed their code to work with
them).
2011-04-05 09:35:56 -07:00
* ticks = - 1 ;
}
return SDL_TRUE ;
}
}
return SDL_FALSE ;
}
2014-06-15 18:31:30 -07:00
/* 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 .
*/
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 ;
}
2013-03-13 21:41:43 -07:00
/* Convert URI to local filename
return filename if possible , else NULL
*/
static char * X11_URIToLocal ( char * uri ) {
char * file = NULL ;
2013-08-21 10:12:16 -03:00
SDL_bool local ;
2013-03-13 21:41:43 -07:00
if ( memcmp ( uri , " file:/ " , 6 ) = = 0 ) uri + = 6 ; /* local file? */
else if ( strstr ( uri , " :/ " ) ! = NULL ) return file ; /* wrong scheme */
2013-08-21 10:12:16 -03:00
local = uri [ 0 ] ! = ' / ' | | ( uri [ 0 ] ! = ' \0 ' & & uri [ 1 ] = = ' / ' ) ;
2013-03-13 21:41:43 -07:00
/* 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 ;
2014-06-15 18:31:30 -07:00
/* Convert URI escape sequences to real characters */
X11_URIDecode ( file , 0 ) ;
2013-03-13 21:41:43 -07:00
if ( uri [ 1 ] = = ' / ' ) {
file + + ;
} else {
file - - ;
}
}
return file ;
}
2012-05-30 11:25:35 -04:00
# if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS
static void X11_HandleGenericEvent ( SDL_VideoData * videodata , XEvent event )
{
2013-07-11 12:26:18 -04:00
/* event is a union, so cookie == &event, but this is type safe. */
XGenericEventCookie * cookie = & event . xcookie ;
2013-10-18 01:36:41 -04:00
if ( X11_XGetEventData ( videodata - > display , cookie ) ) {
2013-05-23 18:45:14 -04:00
X11_HandleXinput2Event ( videodata , cookie ) ;
2013-10-18 01:36:41 -04:00
X11_XFreeEventData ( videodata - > display , cookie ) ;
2013-05-23 18:45:14 -04:00
}
2012-05-30 11:25:35 -04:00
}
# endif /* SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS */
2012-09-28 14:01:55 -07:00
static void
X11_DispatchFocusIn ( SDL_WindowData * data )
{
# ifdef DEBUG_XEVENTS
printf ( " window %p: Dispatching FocusIn \n " , data ) ;
# endif
SDL_SetKeyboardFocus ( data - > window ) ;
# ifdef X_HAVE_UTF8_STRING
if ( data - > ic ) {
2013-10-18 01:36:41 -04:00
X11_XSetICFocus ( data - > ic ) ;
2012-09-28 14:01:55 -07:00
}
# endif
2014-08-19 23:17:28 +01:00
# ifdef SDL_USE_IBUS
SDL_IBus_SetFocus ( SDL_TRUE ) ;
# endif
2012-09-28 14:01:55 -07:00
}
static void
X11_DispatchFocusOut ( SDL_WindowData * data )
{
# ifdef DEBUG_XEVENTS
printf ( " window %p: Dispatching FocusOut \n " , data ) ;
# endif
2013-11-03 09:55:27 -08:00
/* 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 ) ;
}
2012-09-28 14:01:55 -07:00
# ifdef X_HAVE_UTF8_STRING
if ( data - > ic ) {
2013-10-18 01:36:41 -04:00
X11_XUnsetICFocus ( data - > ic ) ;
2012-09-28 14:01:55 -07:00
}
# endif
2014-08-19 23:17:28 +01:00
# ifdef SDL_USE_IBUS
SDL_IBus_SetFocus ( SDL_FALSE ) ;
# endif
2012-09-28 14:01:55 -07:00
}
2012-09-27 23:55:38 -07:00
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 ) ;
}
2012-05-30 11:25:35 -04:00
2014-05-27 14:41:16 -04:00
static void
2014-05-27 15:40:03 -04:00
InitiateWindowMove ( _THIS , const SDL_WindowData * data , const SDL_Point * point )
2014-05-27 14:41:16 -04:00
{
2014-05-27 15:40:03 -04:00
SDL_VideoData * viddata = ( SDL_VideoData * ) _this - > driverdata ;
SDL_Window * window = data - > window ;
Display * display = viddata - > display ;
2014-06-25 17:13:43 -04:00
XEvent evt ;
2014-05-27 15:40:03 -04:00
/* !!! FIXME: we need to regrab this if necessary when the drag is done. */
2014-05-27 14:41:16 -04:00
X11_XUngrabPointer ( display , 0L ) ;
X11_XFlush ( display ) ;
evt . xclient . type = ClientMessage ;
2014-05-27 15:40:03 -04:00
evt . xclient . window = data - > xwindow ;
2014-06-05 00:45:16 -04:00
evt . xclient . message_type = X11_XInternAtom ( display , " _NET_WM_MOVERESIZE " , True ) ;
2014-05-27 14:41:16 -04:00
evt . xclient . format = 32 ;
2014-05-27 15:40:03 -04:00
evt . xclient . data . l [ 0 ] = window - > x + point - > x ;
evt . xclient . data . l [ 1 ] = window - > y + point - > y ;
2014-05-27 15:47:25 -04:00
evt . xclient . data . l [ 2 ] = _NET_WM_MOVERESIZE_MOVE ;
2014-05-27 14:41:16 -04:00
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 ) ;
}
2014-06-05 00:45:16 -04:00
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 ;
2014-06-25 17:13:43 -04:00
XEvent evt ;
2014-06-05 00:45:16 -04:00
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 ) ;
}
2014-05-27 15:40:03 -04:00
static SDL_bool
2014-05-28 01:22:47 -04:00
ProcessHitTest ( _THIS , const SDL_WindowData * data , const XEvent * xev )
2014-05-27 14:41:16 -04:00
{
2014-05-28 01:22:47 -04:00
SDL_Window * window = data - > window ;
2014-06-05 00:45:16 -04:00
SDL_bool ret = SDL_FALSE ;
2014-05-27 15:40:03 -04:00
2014-05-28 01:22:47 -04:00
if ( window - > hit_test ) {
2014-05-27 15:40:03 -04:00
const SDL_Point point = { xev - > xbutton . x , xev - > xbutton . y } ;
2014-05-28 01:22:47 -04:00
const SDL_HitTestResult rc = window - > hit_test ( window , & point , window - > hit_test_data ) ;
2014-06-05 00:45:16 -04:00
switch ( rc ) {
case SDL_HITTEST_DRAGGABLE : {
InitiateWindowMove ( _this , data , & point ) ;
ret = SDL_TRUE ;
}
break ;
case SDL_HITTEST_RESIZE_TOPLEFT : {
InitiateWindowResize ( _this , data , & point , _NET_WM_MOVERESIZE_SIZE_TOPLEFT ) ;
ret = SDL_TRUE ;
}
break ;
case SDL_HITTEST_RESIZE_TOP : {
InitiateWindowResize ( _this , data , & point , _NET_WM_MOVERESIZE_SIZE_TOP ) ;
ret = SDL_TRUE ;
}
break ;
case SDL_HITTEST_RESIZE_TOPRIGHT : {
InitiateWindowResize ( _this , data , & point , _NET_WM_MOVERESIZE_SIZE_TOPRIGHT ) ;
ret = SDL_TRUE ;
}
break ;
case SDL_HITTEST_RESIZE_RIGHT : {
InitiateWindowResize ( _this , data , & point , _NET_WM_MOVERESIZE_SIZE_RIGHT ) ;
ret = SDL_TRUE ;
}
break ;
case SDL_HITTEST_RESIZE_BOTTOMRIGHT : {
InitiateWindowResize ( _this , data , & point , _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT ) ;
ret = SDL_TRUE ;
}
break ;
case SDL_HITTEST_RESIZE_BOTTOM : {
InitiateWindowResize ( _this , data , & point , _NET_WM_MOVERESIZE_SIZE_BOTTOM ) ;
ret = SDL_TRUE ;
}
break ;
case SDL_HITTEST_RESIZE_BOTTOMLEFT : {
InitiateWindowResize ( _this , data , & point , _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT ) ;
ret = SDL_TRUE ;
}
break ;
case SDL_HITTEST_RESIZE_LEFT : {
InitiateWindowResize ( _this , data , & point , _NET_WM_MOVERESIZE_SIZE_LEFT ) ;
ret = SDL_TRUE ;
}
break ;
default :
break ;
2014-05-27 14:41:16 -04:00
}
}
2014-05-27 15:40:03 -04:00
2014-06-05 00:45:16 -04:00
return ret ;
2014-05-27 14:41:16 -04:00
}
2014-09-11 19:24:42 -07:00
static void
ReconcileKeyboardState ( _THIS , const SDL_WindowData * data )
{
SDL_VideoData * viddata = ( SDL_VideoData * ) _this - > driverdata ;
Display * display = viddata - > display ;
char keys [ 32 ] ;
int keycode = 0 ;
X11_XQueryKeymap ( display , keys ) ;
while ( keycode < 256 ) {
if ( keys [ keycode / 8 ] & ( 1 < < ( keycode % 8 ) ) ) {
SDL_SendKeyboardKey ( SDL_PRESSED , viddata - > key_layout [ keycode ] ) ;
} else {
SDL_SendKeyboardKey ( SDL_RELEASED , viddata - > key_layout [ keycode ] ) ;
}
keycode + + ;
}
}
2006-07-27 06:53:23 +00:00
static void
X11_DispatchEvent ( _THIS )
{
SDL_VideoData * videodata = ( SDL_VideoData * ) _this - > driverdata ;
2010-07-13 23:11:10 -07:00
Display * display = videodata - > display ;
2006-07-27 06:53:23 +00:00
SDL_WindowData * data ;
XEvent xevent ;
2013-11-10 14:48:44 -08:00
int orig_event_type ;
KeyCode orig_keycode ;
2013-08-21 10:12:16 -03:00
XClientMessageEvent m ;
2013-11-10 14:48:44 -08:00
int i ;
2006-07-27 06:53:23 +00:00
SDL_zero ( xevent ) ; /* valgrind fix. --ryan. */
2013-10-18 01:36:41 -04:00
X11_XNextEvent ( display , & xevent ) ;
2006-07-27 06:53:23 +00:00
2013-11-10 14:48:44 -08:00
/* 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 */
2013-10-18 01:36:41 -04:00
if ( X11_XFilterEvent ( & xevent , None ) = = True ) {
2008-03-07 23:57:15 +00:00
#if 0
2008-03-14 18:17:49 +00:00
printf ( " Filtered event type = %d display = %d window = %d \n " ,
xevent . type , xevent . xany . display , xevent . xany . window ) ;
2008-03-07 20:54:11 +00:00
# endif
2013-11-10 14:48:44 -08:00
if ( orig_keycode ) {
/* Make sure dead key press/release events are sent */
2014-06-04 10:56:43 -07:00
/* Actually, don't do this because it causes double-delivery
of some keys on Ubuntu 14.04 ( bug 2526 )
2013-11-10 14:48:44 -08:00
SDL_Scancode scancode = videodata - > key_layout [ orig_keycode ] ;
if ( orig_event_type = = KeyPress ) {
SDL_SendKeyboardKey ( SDL_PRESSED , scancode ) ;
} else {
SDL_SendKeyboardKey ( SDL_RELEASED , scancode ) ;
}
2014-06-04 10:56:43 -07:00
*/
2013-11-10 14:48:44 -08:00
}
2008-03-07 20:54:11 +00:00
return ;
}
2006-07-27 06:53:23 +00:00
/* Send a SDL_SYSWMEVENT if the application wants them */
2010-03-25 01:08:26 -07:00
if ( SDL_GetEventState ( SDL_SYSWMEVENT ) = = SDL_ENABLE ) {
2006-07-27 06:53:23 +00:00
SDL_SysWMmsg wmmsg ;
SDL_VERSION ( & wmmsg . version ) ;
wmmsg . subsystem = SDL_SYSWM_X11 ;
2011-01-20 16:05:59 -08:00
wmmsg . msg . x11 . event = xevent ;
2006-07-27 06:53:23 +00:00
SDL_SendSysWMEvent ( & wmmsg ) ;
}
2012-05-30 11:25:35 -04:00
# if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS
if ( xevent . type = = GenericEvent ) {
X11_HandleGenericEvent ( videodata , xevent ) ;
return ;
}
# endif
2012-09-27 13:52:07 -07:00
#if 0
printf ( " type = %d display = %d window = %d \n " ,
xevent . type , xevent . xany . display , xevent . xany . window ) ;
# endif
2006-07-27 06:53:23 +00:00
data = NULL ;
2008-03-07 17:20:37 +00:00
if ( videodata & & videodata - > windowlist ) {
for ( i = 0 ; i < videodata - > numwindows ; + + i ) {
if ( ( videodata - > windowlist [ i ] ! = NULL ) & &
2010-01-21 06:21:52 +00:00
( videodata - > windowlist [ i ] - > xwindow = = xevent . xany . window ) ) {
2008-03-07 17:20:37 +00:00
data = videodata - > windowlist [ i ] ;
break ;
}
2006-07-27 06:53:23 +00:00
}
}
if ( ! data ) {
return ;
}
2010-07-13 23:11:10 -07:00
2006-07-27 06:53:23 +00:00
switch ( xevent . type ) {
/* Gaining mouse coverage? */
case EnterNotify : {
# ifdef DEBUG_XEVENTS
2012-09-28 14:01:55 -07:00
printf ( " window %p: EnterNotify! (%d,%d,%d) \n " , data ,
2010-07-20 00:05:32 -07:00
xevent . xcrossing . x ,
xevent . xcrossing . y ,
2009-06-11 20:08:33 +00:00
xevent . xcrossing . mode ) ;
2006-07-27 06:53:23 +00:00
if ( xevent . xcrossing . mode = = NotifyGrab )
printf ( " Mode: NotifyGrab \n " ) ;
if ( xevent . xcrossing . mode = = NotifyUngrab )
printf ( " Mode: NotifyUngrab \n " ) ;
# endif
2010-05-09 20:47:22 -07:00
SDL_SetMouseFocus ( data - > window ) ;
2013-04-23 18:47:32 -07:00
if ( ! SDL_GetMouse ( ) - > relative_mode ) {
SDL_SendMouseMotion ( data - > window , 0 , 0 , xevent . xcrossing . x , xevent . xcrossing . y ) ;
}
2006-07-27 06:53:23 +00:00
}
break ;
/* Losing mouse coverage? */
case LeaveNotify : {
# ifdef DEBUG_XEVENTS
2012-09-28 14:01:55 -07:00
printf ( " window %p: LeaveNotify! (%d,%d,%d) \n " , data ,
2010-07-20 00:05:32 -07:00
xevent . xcrossing . x ,
xevent . xcrossing . y ,
2009-06-11 20:08:33 +00:00
xevent . xcrossing . mode ) ;
2006-07-27 06:53:23 +00:00
if ( xevent . xcrossing . mode = = NotifyGrab )
printf ( " Mode: NotifyGrab \n " ) ;
if ( xevent . xcrossing . mode = = NotifyUngrab )
printf ( " Mode: NotifyUngrab \n " ) ;
# endif
2013-04-22 18:14:55 -07:00
if ( ! SDL_GetMouse ( ) - > relative_mode ) {
SDL_SendMouseMotion ( data - > window , 0 , 0 , xevent . xcrossing . x , xevent . xcrossing . y ) ;
}
2010-07-20 00:05:32 -07:00
if ( xevent . xcrossing . mode ! = NotifyGrab & &
xevent . xcrossing . mode ! = NotifyUngrab & &
xevent . xcrossing . detail ! = NotifyInferior ) {
2010-05-09 20:47:22 -07:00
SDL_SetMouseFocus ( NULL ) ;
2006-07-27 06:53:23 +00:00
}
}
break ;
/* Gaining input focus? */
case FocusIn : {
2013-11-10 20:38:50 -03:00
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 ;
}
2012-11-07 08:49:59 -08:00
if ( xevent . xfocus . detail = = NotifyInferior ) {
# ifdef DEBUG_XEVENTS
printf ( " window %p: FocusIn (NotifierInferior, ignoring) \n " , data ) ;
# endif
break ;
}
2006-07-27 06:53:23 +00:00
# ifdef DEBUG_XEVENTS
2012-09-28 14:01:55 -07:00
printf ( " window %p: FocusIn! \n " , data ) ;
2006-07-27 06:53:23 +00:00
# endif
2012-11-07 11:13:28 -08:00
if ( data - > pending_focus = = PENDING_FOCUS_OUT & &
data - > window = = SDL_GetKeyboardFocus ( ) ) {
2014-09-11 19:24:42 -07:00
ReconcileKeyboardState ( _this , data ) ;
2012-11-07 11:13:28 -08:00
}
2012-09-28 14:01:55 -07:00
data - > pending_focus = PENDING_FOCUS_IN ;
data - > pending_focus_time = SDL_GetTicks ( ) + PENDING_FOCUS_IN_TIME ;
2006-07-27 06:53:23 +00:00
}
break ;
/* Losing input focus? */
case FocusOut : {
2013-11-10 20:38:50 -03:00
if ( xevent . xfocus . mode = = NotifyGrab | | xevent . xfocus . mode = = NotifyUngrab ) {
2013-11-10 14:33:01 -08:00
/* Someone is handling a global hotkey, ignore it */
# ifdef DEBUG_XEVENTS
2013-11-10 20:38:50 -03:00
printf ( " window %p: FocusOut (NotifyGrab/NotifyUngrab, ignoring) \n " , data ) ;
2013-11-10 14:33:01 -08:00
# endif
break ;
}
2012-11-07 08:49:59 -08:00
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 ;
}
2006-07-27 06:53:23 +00:00
# ifdef DEBUG_XEVENTS
2012-09-28 14:01:55 -07:00
printf ( " window %p: FocusOut! \n " , data ) ;
2006-07-27 06:53:23 +00:00
# endif
2012-09-28 14:01:55 -07:00
data - > pending_focus = PENDING_FOCUS_OUT ;
data - > pending_focus_time = SDL_GetTicks ( ) + PENDING_FOCUS_OUT_TIME ;
2006-07-27 06:53:23 +00:00
}
break ;
/* Generated upon EnterWindow and FocusIn */
case KeymapNotify : {
# ifdef DEBUG_XEVENTS
2012-09-28 14:01:55 -07:00
printf ( " window %p: KeymapNotify! \n " , data ) ;
2006-07-27 06:53:23 +00:00
# endif
/* FIXME:
X11_SetKeyboardState ( SDL_Display , xevent . xkeymap . key_vector ) ;
*/
}
break ;
2008-02-07 15:31:09 +00:00
/* Has the keyboard layout changed? */
case MappingNotify : {
# ifdef DEBUG_XEVENTS
2012-09-28 14:01:55 -07:00
printf ( " window %p: MappingNotify! \n " , data ) ;
2008-02-07 15:31:09 +00:00
# endif
2008-02-07 16:00:29 +00:00
X11_UpdateKeymap ( _this ) ;
2008-02-07 15:31:09 +00:00
}
break ;
2006-07-27 06:53:23 +00:00
/* Key press? */
case KeyPress : {
KeyCode keycode = xevent . xkey . keycode ;
2008-01-15 22:37:17 +00:00
KeySym keysym = NoSymbol ;
2008-02-07 16:00:29 +00:00
char text [ SDL_TEXTINPUTEVENT_TEXT_SIZE ] ;
2008-03-07 20:54:11 +00:00
Status status = 0 ;
2014-08-19 23:17:28 +01:00
SDL_bool handled_by_ime = SDL_FALSE ;
2006-07-27 06:53:23 +00:00
# ifdef DEBUG_XEVENTS
2012-09-28 14:01:55 -07:00
printf ( " window %p: KeyPress (X11 keycode = 0x%X) \n " , data , xevent . xkey . keycode ) ;
2006-07-27 06:53:23 +00:00
# endif
2010-07-18 01:00:01 -07:00
# if 1
2013-08-12 22:00:21 -07:00
if ( videodata - > key_layout [ keycode ] = = SDL_SCANCODE_UNKNOWN & & keycode ) {
2008-02-07 15:31:09 +00:00
int min_keycode , max_keycode ;
2013-10-18 01:36:41 -04:00
X11_XDisplayKeycodes ( display , & min_keycode , & max_keycode ) ;
2012-05-31 19:23:30 +03:00
# if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
2013-10-18 01:36:41 -04:00
keysym = X11_XkbKeycodeToKeysym ( display , keycode , 0 , 0 ) ;
2012-05-31 19:23:30 +03:00
# else
2010-07-13 23:11:10 -07:00
keysym = XKeycodeToKeysym ( display , keycode , 0 ) ;
2012-05-31 19:23:30 +03:00
# endif
2008-01-12 18:07:06 +00:00
fprintf ( stderr ,
2010-07-19 23:29:45 -07:00
" The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL mailing list <sdl@libsdl.org> X11 KeyCode %d (%d), X11 KeySym 0x%lX (%s). \n " ,
2008-02-07 15:31:09 +00:00
keycode , keycode - min_keycode , keysym ,
2013-10-18 01:36:41 -04:00
X11_XKeysymToString ( keysym ) ) ;
2006-07-27 06:53:23 +00:00
}
2008-01-12 18:07:06 +00:00
# endif
2008-03-07 20:54:11 +00:00
/* */
2008-02-07 15:31:09 +00:00
SDL_zero ( text ) ;
2008-03-07 20:54:11 +00:00
# ifdef X_HAVE_UTF8_STRING
if ( data - > ic ) {
2013-10-18 01:36:41 -04:00
X11_Xutf8LookupString ( data - > ic , & xevent . xkey , text , sizeof ( text ) ,
2008-09-01 16:04:20 +00:00
& keysym , & status ) ;
2008-03-07 20:54:11 +00:00
}
# else
2008-02-07 16:00:29 +00:00
XLookupString ( & xevent . xkey , text , sizeof ( text ) , & keysym , NULL ) ;
2008-03-07 20:54:11 +00:00
# endif
2014-06-18 20:11:39 +01:00
# ifdef SDL_USE_IBUS
if ( SDL_GetEventState ( SDL_TEXTINPUT ) = = SDL_ENABLE ) {
2014-08-19 23:17:28 +01:00
if ( ! ( handled_by_ime = SDL_IBus_ProcessKeyEvent ( keysym , keycode ) ) ) {
2014-06-18 20:11:39 +01:00
# endif
if ( * text ) {
SDL_SendKeyboardText ( text ) ;
}
# ifdef SDL_USE_IBUS
}
}
2014-08-19 23:17:28 +01:00
# endif
if ( ! handled_by_ime ) {
2014-06-18 20:11:39 +01:00
SDL_SendKeyboardKey ( SDL_PRESSED , videodata - > key_layout [ keycode ] ) ;
2008-01-15 22:37:17 +00:00
}
2014-08-19 23:17:28 +01:00
2006-07-27 06:53:23 +00:00
}
break ;
/* Key release? */
case KeyRelease : {
KeyCode keycode = xevent . xkey . keycode ;
# ifdef DEBUG_XEVENTS
2012-09-28 14:01:55 -07:00
printf ( " window %p: KeyRelease (X11 keycode = 0x%X) \n " , data , xevent . xkey . keycode ) ;
2006-07-27 06:53:23 +00:00
# endif
2010-07-21 21:47:12 -07:00
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 ] ) ;
2006-07-27 06:53:23 +00:00
}
break ;
/* Have we been iconified? */
case UnmapNotify : {
# ifdef DEBUG_XEVENTS
2012-09-28 14:01:55 -07:00
printf ( " window %p: UnmapNotify! \n " , data ) ;
2006-07-27 06:53:23 +00:00
# endif
2012-09-27 23:55:38 -07:00
X11_DispatchUnmapNotify ( data ) ;
2006-07-27 06:53:23 +00:00
}
break ;
/* Have we been restored? */
case MapNotify : {
# ifdef DEBUG_XEVENTS
2012-09-28 14:01:55 -07:00
printf ( " window %p: MapNotify! \n " , data ) ;
2006-07-27 06:53:23 +00:00
# endif
2012-09-27 23:55:38 -07:00
X11_DispatchMapNotify ( data ) ;
2006-07-27 06:53:23 +00:00
}
break ;
/* Have we been resized or moved? */
case ConfigureNotify : {
# ifdef DEBUG_XEVENTS
2012-10-03 13:37:44 -07:00
printf ( " window %p: ConfigureNotify! (position: %d,%d, size: %dx%d) \n " , data ,
xevent . xconfigure . x , xevent . xconfigure . y ,
2006-07-27 06:53:23 +00:00
xevent . xconfigure . width , xevent . xconfigure . height ) ;
# endif
2013-10-20 17:23:43 +02:00
long border_left = 0 ;
long border_top = 0 ;
if ( data - > xwindow ) {
2013-10-20 09:58:37 -07:00
Atom _net_frame_extents = X11_XInternAtom ( display , " _NET_FRAME_EXTENTS " , 0 ) ;
Fixed bug 2502 - Memory leak inside SDL_x11events.c -> X11_DispatchEvent(_THIS)
bojko_1000
Code @566:
if (data->xwindow) {
Atom _net_frame_extents = X11_XInternAtom(display, "_NET_FRAME_EXTENTS", 0);
Atom type = None;
int format;
unsigned long nitems = 0, bytes_after;
unsigned char *property;
X11_XGetWindowProperty(display, data->xwindow,
_net_frame_extents, 0, 16, 0,
XA_CARDINAL, &type, &format,
&nitems, &bytes_after, &property);
if (type != None && nitems == 4)
{
border_left = ((long*)property)[0];
border_right = ((long*)property)[1];
border_top = ((long*)property)[2];
border_bottom = ((long*)property)[3];
}
}
Code after _the fix_:
if (data->xwindow) {
Atom _net_frame_extents = X11_XInternAtom(display, "_NET_FRAME_EXTENTS", 0);
Atom type = None;
int format;
unsigned long nitems = 0, bytes_after;
unsigned char *property;
X11_XGetWindowProperty(display, data->xwindow,
_net_frame_extents, 0, 16, 0,
XA_CARDINAL, &type, &format,
&nitems, &bytes_after, &property);
if (type != None && nitems == 4)
{
border_left = ((long*)property)[0];
border_right = ((long*)property)[1];
border_top = ((long*)property)[2];
border_bottom = ((long*)property)[3];
}
X11_XFree(property);
}
I have found that leak with valgrind.
2014-04-17 20:02:11 -07:00
Atom type ;
2013-10-20 17:23:43 +02:00
int format ;
Fixed bug 2502 - Memory leak inside SDL_x11events.c -> X11_DispatchEvent(_THIS)
bojko_1000
Code @566:
if (data->xwindow) {
Atom _net_frame_extents = X11_XInternAtom(display, "_NET_FRAME_EXTENTS", 0);
Atom type = None;
int format;
unsigned long nitems = 0, bytes_after;
unsigned char *property;
X11_XGetWindowProperty(display, data->xwindow,
_net_frame_extents, 0, 16, 0,
XA_CARDINAL, &type, &format,
&nitems, &bytes_after, &property);
if (type != None && nitems == 4)
{
border_left = ((long*)property)[0];
border_right = ((long*)property)[1];
border_top = ((long*)property)[2];
border_bottom = ((long*)property)[3];
}
}
Code after _the fix_:
if (data->xwindow) {
Atom _net_frame_extents = X11_XInternAtom(display, "_NET_FRAME_EXTENTS", 0);
Atom type = None;
int format;
unsigned long nitems = 0, bytes_after;
unsigned char *property;
X11_XGetWindowProperty(display, data->xwindow,
_net_frame_extents, 0, 16, 0,
XA_CARDINAL, &type, &format,
&nitems, &bytes_after, &property);
if (type != None && nitems == 4)
{
border_left = ((long*)property)[0];
border_right = ((long*)property)[1];
border_top = ((long*)property)[2];
border_bottom = ((long*)property)[3];
}
X11_XFree(property);
}
I have found that leak with valgrind.
2014-04-17 20:02:11 -07:00
unsigned long nitems , bytes_after ;
2013-10-20 17:23:43 +02:00
unsigned char * property ;
Fixed bug 2502 - Memory leak inside SDL_x11events.c -> X11_DispatchEvent(_THIS)
bojko_1000
Code @566:
if (data->xwindow) {
Atom _net_frame_extents = X11_XInternAtom(display, "_NET_FRAME_EXTENTS", 0);
Atom type = None;
int format;
unsigned long nitems = 0, bytes_after;
unsigned char *property;
X11_XGetWindowProperty(display, data->xwindow,
_net_frame_extents, 0, 16, 0,
XA_CARDINAL, &type, &format,
&nitems, &bytes_after, &property);
if (type != None && nitems == 4)
{
border_left = ((long*)property)[0];
border_right = ((long*)property)[1];
border_top = ((long*)property)[2];
border_bottom = ((long*)property)[3];
}
}
Code after _the fix_:
if (data->xwindow) {
Atom _net_frame_extents = X11_XInternAtom(display, "_NET_FRAME_EXTENTS", 0);
Atom type = None;
int format;
unsigned long nitems = 0, bytes_after;
unsigned char *property;
X11_XGetWindowProperty(display, data->xwindow,
_net_frame_extents, 0, 16, 0,
XA_CARDINAL, &type, &format,
&nitems, &bytes_after, &property);
if (type != None && nitems == 4)
{
border_left = ((long*)property)[0];
border_right = ((long*)property)[1];
border_top = ((long*)property)[2];
border_bottom = ((long*)property)[3];
}
X11_XFree(property);
}
I have found that leak with valgrind.
2014-04-17 20:02:11 -07:00
if ( X11_XGetWindowProperty ( display , data - > xwindow ,
_net_frame_extents , 0 , 16 , 0 ,
XA_CARDINAL , & type , & format ,
& nitems , & bytes_after , & property ) = = Success ) {
if ( type ! = None & & nitems = = 4 )
{
border_left = ( ( long * ) property ) [ 0 ] ;
border_top = ( ( long * ) property ) [ 2 ] ;
}
X11_XFree ( property ) ;
2013-10-23 13:43:17 -07:00
}
2013-10-20 17:23:43 +02:00
}
2012-10-03 13:37:44 -07:00
if ( xevent . xconfigure . x ! = data - > last_xconfigure . x | |
xevent . xconfigure . y ! = data - > last_xconfigure . y ) {
SDL_SendWindowEvent ( data - > window , SDL_WINDOWEVENT_MOVED ,
2013-10-20 17:23:43 +02:00
xevent . xconfigure . x - border_left ,
xevent . xconfigure . y - border_top ) ;
2014-06-18 20:11:39 +01:00
# ifdef SDL_USE_IBUS
if ( SDL_GetEventState ( SDL_TEXTINPUT ) = = SDL_ENABLE ) {
/* Update IBus candidate list position */
SDL_IBus_UpdateTextRect ( NULL ) ;
}
# endif
2012-10-03 13:37:44 -07:00
}
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 ;
2006-07-27 06:53:23 +00:00
}
break ;
/* Have we been requested to quit (or another client message?) */
case ClientMessage : {
2013-03-13 21:41:43 -07:00
int xdnd_version = 0 ;
2013-05-18 14:17:52 -07:00
2013-03-13 21:41:43 -07:00
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 ) ;
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 ) ;
2013-10-18 01:36:41 -04:00
X11_XFree ( p . data ) ;
2013-03-13 21:41:43 -07:00
} 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 ) {
2013-05-18 14:17:52 -07:00
2013-03-13 21:41:43 -07:00
/* 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 */
2013-05-18 14:17:52 -07:00
2013-10-18 01:36:41 -04:00
X11_XSendEvent ( display , xevent . xclient . data . l [ 0 ] , False , NoEventMask , ( XEvent * ) & m ) ;
X11_XFlush ( display ) ;
2013-03-13 21:41:43 -07:00
}
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! */
2013-10-18 01:36:41 -04:00
X11_XSendEvent ( display , xevent . xclient . data . l [ 0 ] , False , NoEventMask , ( XEvent * ) & m ) ;
2013-03-13 21:41:43 -07:00
} else {
/* convert */
if ( xdnd_version > = 1 ) {
2013-10-18 01:36:41 -04:00
X11_XConvertSelection ( display , videodata - > XdndSelection , data - > xdnd_req , videodata - > PRIMARY , data - > xwindow , xevent . xclient . data . l [ 2 ] ) ;
2013-03-13 21:41:43 -07:00
} else {
2013-10-18 01:36:41 -04:00
X11_XConvertSelection ( display , videodata - > XdndSelection , data - > xdnd_req , videodata - > PRIMARY , data - > xwindow , CurrentTime ) ;
2013-03-13 21:41:43 -07:00
}
}
}
else if ( ( xevent . xclient . message_type = = videodata - > WM_PROTOCOLS ) & &
2012-11-02 15:22:37 -04:00
( xevent . xclient . format = = 32 ) & &
( xevent . xclient . data . l [ 0 ] = = videodata - > _NET_WM_PING ) ) {
2012-11-06 10:34:47 -08:00
Window root = DefaultRootWindow ( display ) ;
2012-11-02 15:22:37 -04:00
# ifdef DEBUG_XEVENTS
printf ( " window %p: _NET_WM_PING \n " , data ) ;
# endif
xevent . xclient . window = root ;
2013-10-18 01:36:41 -04:00
X11_XSendEvent ( display , root , False , SubstructureRedirectMask | SubstructureNotifyMask , & xevent ) ;
2012-11-02 15:22:37 -04:00
break ;
}
else if ( ( xevent . xclient . message_type = = videodata - > WM_PROTOCOLS ) & &
2012-11-02 14:15:21 -04:00
( xevent . xclient . format = = 32 ) & &
2006-07-27 06:53:23 +00:00
( xevent . xclient . data . l [ 0 ] = = videodata - > WM_DELETE_WINDOW ) ) {
2012-11-02 15:22:37 -04:00
# ifdef DEBUG_XEVENTS
printf ( " window %p: WM_DELETE_WINDOW \n " , data ) ;
# endif
2010-01-21 06:21:52 +00:00
SDL_SendWindowEvent ( data - > window , SDL_WINDOWEVENT_CLOSE , 0 , 0 ) ;
2012-11-02 15:22:37 -04:00
break ;
2006-07-27 06:53:23 +00:00
}
}
break ;
/* Do we need to refresh ourselves? */
case Expose : {
# ifdef DEBUG_XEVENTS
2012-09-28 14:01:55 -07:00
printf ( " window %p: Expose (count = %d) \n " , data , xevent . xexpose . count ) ;
2006-07-27 06:53:23 +00:00
# endif
2010-01-21 06:21:52 +00:00
SDL_SendWindowEvent ( data - > window , SDL_WINDOWEVENT_EXPOSED , 0 , 0 ) ;
2006-07-27 06:53:23 +00:00
}
break ;
2010-05-09 20:47:22 -07:00
case MotionNotify : {
2013-05-18 14:17:52 -07:00
SDL_Mouse * mouse = SDL_GetMouse ( ) ;
2013-12-23 17:37:22 -08:00
if ( ! mouse - > relative_mode | | mouse - > relative_mode_warp ) {
2008-08-25 06:33:00 +00:00
# ifdef DEBUG_MOTION
2012-09-28 14:01:55 -07:00
printf ( " window %p: X11 motion: %d,%d \n " , xevent . xmotion . x , xevent . xmotion . y ) ;
2008-08-25 06:33:00 +00:00
# endif
2012-05-30 11:25:35 -04:00
2013-03-02 20:44:16 -08:00
SDL_SendMouseMotion ( data - > window , 0 , 0 , xevent . xmotion . x , xevent . xmotion . y ) ;
2012-05-30 11:25:35 -04:00
}
2010-05-09 20:47:22 -07:00
}
break ;
case ButtonPress : {
Fixed bug 1173 (No mouse wheel event on linux/x11)
Matthias 2011-03-20 23:07:02 PDT
On X11, SDL 1.3 does not generate a mouse wheel event. Instead, button
down/buttton up events are generated by SDL. After looking at the code in
SDL_x11events.c, I assume this is due to the fact that X11 does not have a
dedicated mouse wheel event.
I did a little research on the behavior of mouse wheel events on X11 systems.
Apparently, mouse wheel events generate a button down/button up event with the
same time, i.e. with exact same timestamp.
Attached you can find my changes to SDL_x11events.c, which generates SDL mouse
wheel events for those button down events that have a button release event
immediately following it (for the same button, and with the same timestamp).
I did have to make an assumption: As standard X11 implementations know only 5
buttons, I have mapped Button4 to "wheel up" (i.e. +1), and Button5 to "wheel
down" (i.e. -1).
Note that if you include this patch, no SDL button down/up events will be
generated on X11 platforms for mouse wheel events (which is probably a
significant change for those that have programmed their code to work with
them).
2011-04-05 09:35:56 -07:00
int ticks = 0 ;
2013-03-02 20:44:16 -08:00
if ( X11_IsWheelEvent ( display , & xevent , & ticks ) ) {
SDL_SendMouseWheel ( data - > window , 0 , 0 , ticks ) ;
} else {
2014-05-27 15:40:03 -04:00
if ( xevent . xbutton . button = = Button1 ) {
2014-05-28 01:22:47 -04:00
if ( ProcessHitTest ( _this , data , & xevent ) ) {
2014-05-27 15:40:03 -04:00
break ; /* don't pass this event on to app. */
}
2014-05-27 14:41:16 -04:00
}
2013-03-02 20:44:16 -08:00
SDL_SendMouseButton ( data - > window , 0 , SDL_PRESSED , xevent . xbutton . button ) ;
Fixed bug 1173 (No mouse wheel event on linux/x11)
Matthias 2011-03-20 23:07:02 PDT
On X11, SDL 1.3 does not generate a mouse wheel event. Instead, button
down/buttton up events are generated by SDL. After looking at the code in
SDL_x11events.c, I assume this is due to the fact that X11 does not have a
dedicated mouse wheel event.
I did a little research on the behavior of mouse wheel events on X11 systems.
Apparently, mouse wheel events generate a button down/button up event with the
same time, i.e. with exact same timestamp.
Attached you can find my changes to SDL_x11events.c, which generates SDL mouse
wheel events for those button down events that have a button release event
immediately following it (for the same button, and with the same timestamp).
I did have to make an assumption: As standard X11 implementations know only 5
buttons, I have mapped Button4 to "wheel up" (i.e. +1), and Button5 to "wheel
down" (i.e. -1).
Note that if you include this patch, no SDL button down/up events will be
generated on X11 platforms for mouse wheel events (which is probably a
significant change for those that have programmed their code to work with
them).
2011-04-05 09:35:56 -07:00
}
2010-05-09 20:47:22 -07:00
}
break ;
case ButtonRelease : {
2013-03-02 20:44:16 -08:00
SDL_SendMouseButton ( data - > window , 0 , SDL_RELEASED , xevent . xbutton . button ) ;
2010-05-09 20:47:22 -07:00
}
break ;
2010-07-13 23:11:10 -07:00
case PropertyNotify : {
# ifdef DEBUG_XEVENTS
2010-07-14 00:08:46 -07:00
unsigned char * propdata ;
int status , real_format ;
Atom real_type ;
unsigned long items_read , items_left , i ;
2013-10-18 01:36:41 -04:00
char * name = X11_XGetAtomName ( display , xevent . xproperty . atom ) ;
2010-07-13 23:11:10 -07:00
if ( name ) {
2012-09-28 14:01:55 -07:00
printf ( " window %p: PropertyNotify: %s %s \n " , data , name , ( xevent . xproperty . state = = PropertyDelete ) ? " deleted " : " changed " ) ;
2013-10-18 01:36:41 -04:00
X11_XFree ( name ) ;
2010-07-13 23:11:10 -07:00
}
2013-10-18 01:36:41 -04:00
status = X11_XGetWindowProperty ( display , data - > xwindow , xevent . xproperty . atom , 0L , 8192L , False , AnyPropertyType , & real_type , & real_format , & items_read , & items_left , & propdata ) ;
2010-07-19 23:29:45 -07:00
if ( status = = Success & & items_read > 0 ) {
2010-07-14 00:08:46 -07:00
if ( real_type = = XA_INTEGER ) {
int * values = ( int * ) propdata ;
printf ( " { " ) ;
2010-07-13 23:11:10 -07:00
for ( i = 0 ; i < items_read ; i + + ) {
2010-07-14 00:08:46 -07:00
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 ] ) ;
2010-07-13 23:11:10 -07:00
}
2010-07-14 00:08:46 -07:00
printf ( " } \n " ) ;
} else if ( real_format = = 16 ) {
Uint16 * values = ( Uint16 * ) propdata ;
printf ( " { " ) ;
for ( i = 0 ; i < items_read ; i + + ) {
printf ( " %d " , values [ i ] ) ;
2010-07-13 23:11:10 -07:00
}
2010-07-14 00:08:46 -07:00
printf ( " } \n " ) ;
} else if ( real_format = = 8 ) {
Uint8 * values = ( Uint8 * ) propdata ;
printf ( " { " ) ;
for ( i = 0 ; i < items_read ; i + + ) {
printf ( " %d " , values [ i ] ) ;
2010-07-13 23:11:10 -07:00
}
2010-07-14 00:08:46 -07:00
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 + + ) {
2013-10-18 01:36:41 -04:00
char * name = X11_XGetAtomName ( display , atoms [ i ] ) ;
2010-07-14 00:08:46 -07:00
if ( name ) {
printf ( " %s " , name ) ;
2013-10-18 01:36:41 -04:00
X11_XFree ( name ) ;
2010-07-13 23:11:10 -07:00
}
}
2010-07-14 00:08:46 -07:00
printf ( " } \n " ) ;
} else {
2013-10-18 01:36:41 -04:00
char * name = X11_XGetAtomName ( display , real_type ) ;
2010-07-14 00:08:46 -07:00
printf ( " Unknown type: %ld (%s) \n " , real_type , name ? name : " UNKNOWN " ) ;
if ( name ) {
2013-10-18 01:36:41 -04:00
X11_XFree ( name ) ;
2010-07-14 00:08:46 -07:00
}
2010-07-13 23:11:10 -07:00
}
}
2012-09-27 23:55:38 -07:00
if ( status = = Success ) {
2013-10-18 01:36:41 -04:00
X11_XFree ( propdata ) ;
2012-09-27 23:55:38 -07:00
}
# endif /* DEBUG_XEVENTS */
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 .
*/
2012-09-28 01:51:51 -07:00
Uint32 flags = X11_GetNetWMState ( _this , xevent . xproperty . window ) ;
2014-08-18 18:16:45 -07:00
if ( ( flags ^ data - > window - > flags ) & SDL_WINDOW_HIDDEN | |
( flags ^ data - > window - > flags ) & SDL_WINDOW_FULLSCREEN ) {
2012-09-27 23:55:38 -07:00
if ( flags & SDL_WINDOW_HIDDEN ) {
X11_DispatchUnmapNotify ( data ) ;
} else {
X11_DispatchMapNotify ( data ) ;
}
}
}
2010-07-13 23:11:10 -07:00
}
break ;
2010-07-12 00:36:55 -07:00
/* Copy the selection from XA_CUT_BUFFER0 to the requested property */
case SelectionRequest : {
XSelectionRequestEvent * req ;
XEvent sevent ;
int seln_format ;
unsigned long nbytes ;
unsigned long overflow ;
unsigned char * seln_data ;
req = & xevent . xselectionrequest ;
# ifdef DEBUG_XEVENTS
2012-09-28 14:01:55 -07:00
printf ( " window %p: SelectionRequest (requestor = %ld, target = %ld) \n " , data ,
2010-07-12 00:36:55 -07:00
req - > requestor , req - > target ) ;
# endif
2010-07-14 07:25:07 -07:00
SDL_zero ( sevent ) ;
2010-07-14 00:08:46 -07:00
sevent . xany . type = SelectionNotify ;
2010-07-12 00:36:55 -07:00
sevent . xselection . selection = req - > selection ;
sevent . xselection . target = None ;
sevent . xselection . property = None ;
sevent . xselection . requestor = req - > requestor ;
sevent . xselection . time = req - > time ;
2013-10-18 01:36:41 -04:00
if ( X11_XGetWindowProperty ( display , DefaultRootWindow ( display ) ,
2010-07-12 00:36:55 -07:00
XA_CUT_BUFFER0 , 0 , INT_MAX / 4 , False , req - > target ,
& sevent . xselection . target , & seln_format , & nbytes ,
& overflow , & seln_data ) = = Success ) {
2013-10-18 01:36:41 -04:00
Atom XA_TARGETS = X11_XInternAtom ( display , " TARGETS " , 0 ) ;
2010-07-12 00:36:55 -07:00
if ( sevent . xselection . target = = req - > target ) {
2013-10-18 01:36:41 -04:00
X11_XChangeProperty ( display , req - > requestor , req - > property ,
2010-07-12 00:36:55 -07:00
sevent . xselection . target , seln_format , PropModeReplace ,
seln_data , nbytes ) ;
sevent . xselection . property = req - > property ;
2013-03-22 11:42:31 -07:00
} else if ( XA_TARGETS = = req - > target ) {
Atom SupportedFormats [ ] = { sevent . xselection . target , XA_TARGETS } ;
2013-10-18 01:36:41 -04:00
X11_XChangeProperty ( display , req - > requestor , req - > property ,
2013-03-22 11:42:31 -07:00
XA_ATOM , 32 , PropModeReplace ,
( unsigned char * ) SupportedFormats ,
sizeof ( SupportedFormats ) / sizeof ( * SupportedFormats ) ) ;
sevent . xselection . property = req - > property ;
2010-07-12 00:36:55 -07:00
}
2013-10-18 01:36:41 -04:00
X11_XFree ( seln_data ) ;
2010-07-12 00:36:55 -07:00
}
2013-10-18 01:36:41 -04:00
X11_XSendEvent ( display , req - > requestor , False , 0 , & sevent ) ;
X11_XSync ( display , False ) ;
2010-07-12 00:36:55 -07:00
}
break ;
case SelectionNotify : {
# ifdef DEBUG_XEVENTS
2012-09-28 14:01:55 -07:00
printf ( " window %p: SelectionNotify (requestor = %ld, target = %ld) \n " , data ,
2010-07-12 00:36:55 -07:00
xevent . xselection . requestor , xevent . xselection . target ) ;
# endif
2013-03-13 21:41:43 -07:00
Atom target = xevent . xselection . target ;
if ( target = = data - > xdnd_req ) {
/* read data */
SDL_x11Prop p ;
X11_ReadProperty ( & p , display , data - > xwindow , videodata - > PRIMARY ) ;
2013-05-18 14:17:52 -07:00
2013-07-10 21:57:31 -07:00
if ( p . format = = 8 ) {
2013-03-13 21:41:43 -07:00
SDL_bool expect_lf = SDL_FALSE ;
char * start = NULL ;
char * scan = ( char * ) p . data ;
char * fn ;
char * uri ;
int length = 0 ;
while ( p . count - - ) {
if ( ! expect_lf ) {
2013-07-10 21:57:31 -07:00
if ( * scan = = 0x0D ) {
2013-03-13 21:41:43 -07:00
expect_lf = SDL_TRUE ;
2013-07-10 21:57:31 -07:00
}
if ( start = = NULL ) {
2013-03-13 21:41:43 -07:00
start = scan ;
length = 0 ;
}
length + + ;
} else {
2013-07-10 21:57:31 -07:00
if ( * scan = = 0x0A & & length > 0 ) {
uri = SDL_malloc ( length - - ) ;
SDL_memcpy ( uri , start , length ) ;
uri [ length ] = ' \0 ' ;
2013-03-13 21:41:43 -07:00
fn = X11_URIToLocal ( uri ) ;
2013-07-10 21:57:31 -07:00
if ( fn ) {
SDL_SendDropFile ( fn ) ;
}
SDL_free ( uri ) ;
2013-03-13 21:41:43 -07:00
}
expect_lf = SDL_FALSE ;
start = NULL ;
}
scan + + ;
}
}
2013-05-18 14:17:52 -07:00
2013-10-18 01:36:41 -04:00
X11_XFree ( p . data ) ;
2013-05-18 14:17:52 -07:00
2013-03-13 21:41:43 -07:00
/* send reply */
2013-07-10 21:57:31 -07:00
SDL_memset ( & m , 0 , sizeof ( XClientMessageEvent ) ) ;
2013-03-13 21:41:43 -07:00
m . type = ClientMessage ;
m . display = display ;
m . window = data - > xdnd_source ;
m . message_type = videodata - > XdndFinished ;
2013-07-10 21:57:31 -07:00
m . format = 32 ;
2013-03-13 21:41:43 -07:00
m . data . l [ 0 ] = data - > xwindow ;
m . data . l [ 1 ] = 1 ;
m . data . l [ 2 ] = videodata - > XdndActionCopy ;
2013-10-18 01:36:41 -04:00
X11_XSendEvent ( display , data - > xdnd_source , False , NoEventMask , ( XEvent * ) & m ) ;
2013-05-18 14:17:52 -07:00
2013-10-18 01:36:41 -04:00
X11_XSync ( display , False ) ;
2013-05-18 14:17:52 -07:00
2013-03-13 21:41:43 -07:00
} else {
videodata - > selection_waiting = SDL_FALSE ;
}
2010-07-12 00:36:55 -07:00
}
break ;
2010-05-09 20:47:22 -07:00
default : {
2006-07-27 06:53:23 +00:00
# ifdef DEBUG_XEVENTS
2012-09-28 14:01:55 -07:00
printf ( " window %p: Unhandled event %d \n " , data , xevent . type ) ;
2006-07-27 06:53:23 +00:00
# endif
}
break ;
}
}
2012-09-28 14:01:55 -07:00
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 ( ) ;
2013-10-20 20:42:55 -07:00
if ( SDL_TICKS_PASSED ( now , data - > pending_focus_time ) ) {
2012-09-28 14:01:55 -07:00
if ( data - > pending_focus = = PENDING_FOCUS_IN ) {
X11_DispatchFocusIn ( data ) ;
} else {
X11_DispatchFocusOut ( data ) ;
}
data - > pending_focus = PENDING_FOCUS_NONE ;
}
}
}
}
}
2013-10-18 01:36:41 -04:00
/* Ack! X11_XPending() actually performs a blocking read if no events available */
2010-06-26 08:56:48 -07:00
static int
2006-07-27 06:53:23 +00:00
X11_Pending ( Display * display )
{
/* Flush the display connection and look to see if events are queued */
2013-10-18 01:36:41 -04:00
X11_XFlush ( display ) ;
if ( X11_XEventsQueued ( display , QueuedAlready ) ) {
2006-07-27 06:53:23 +00:00
return ( 1 ) ;
}
/* More drastic measures are required -- see if X is ready to talk */
{
static struct timeval zero_time ; /* static == 0 */
int x11_fd ;
fd_set fdset ;
x11_fd = ConnectionNumber ( display ) ;
FD_ZERO ( & fdset ) ;
FD_SET ( x11_fd , & fdset ) ;
if ( select ( x11_fd + 1 , & fdset , NULL , NULL , & zero_time ) = = 1 ) {
2013-10-18 01:36:41 -04:00
return ( X11_XPending ( display ) ) ;
2006-07-27 06:53:23 +00:00
}
}
/* Oh well, nothing is ready .. */
return ( 0 ) ;
}
void
X11_PumpEvents ( _THIS )
{
SDL_VideoData * data = ( SDL_VideoData * ) _this - > driverdata ;
2009-01-12 06:19:05 +00:00
/* Update activity every 30 seconds to prevent screensaver */
if ( _this - > suspend_screensaver ) {
Uint32 now = SDL_GetTicks ( ) ;
if ( ! data - > screensaver_activity | |
2013-10-20 20:42:55 -07:00
SDL_TICKS_PASSED ( now , data - > screensaver_activity + 30000 ) ) {
2013-10-18 01:36:41 -04:00
X11_XResetScreenSaver ( data - > display ) ;
2012-12-28 03:46:55 -05:00
2014-06-18 20:11:39 +01:00
# if SDL_USE_LIBDBUS
SDL_DBus_ScreensaverTickle ( ) ;
# endif
2012-12-28 03:46:55 -05:00
2009-01-12 06:19:05 +00:00
data - > screensaver_activity = now ;
}
2013-05-18 14:17:52 -07:00
}
2009-01-12 06:19:05 +00:00
2014-06-18 20:11:39 +01:00
# ifdef SDL_USE_IBUS
if ( SDL_GetEventState ( SDL_TEXTINPUT ) = = SDL_ENABLE ) {
SDL_IBus_PumpEvents ( ) ;
}
# endif
2006-07-27 06:53:23 +00:00
/* Keep processing pending events */
while ( X11_Pending ( data - > display ) ) {
X11_DispatchEvent ( _this ) ;
}
2012-09-28 14:01:55 -07:00
/* FIXME: Only need to do this when there are pending focus changes */
X11_HandleFocusChanges ( _this ) ;
2006-07-27 06:53:23 +00:00
}
2009-01-12 08:26:24 +00:00
2006-07-27 06:53:23 +00:00
void
2009-01-12 06:19:05 +00:00
X11_SuspendScreenSaver ( _THIS )
2006-07-27 06:53:23 +00:00
{
2011-02-28 09:01:53 -08:00
# if SDL_VIDEO_DRIVER_X11_XSCRNSAVER
2009-01-12 06:19:05 +00:00
SDL_VideoData * data = ( SDL_VideoData * ) _this - > driverdata ;
int dummy ;
int major_version , minor_version ;
2014-03-02 14:59:06 -05:00
# endif /* SDL_VIDEO_DRIVER_X11_XSCRNSAVER */
2006-07-27 06:53:23 +00:00
2014-03-02 14:59:06 -05:00
# if SDL_USE_LIBDBUS
2014-06-18 20:11:39 +01:00
if ( SDL_DBus_ScreensaverInhibit ( _this - > suspend_screensaver ) ) {
2014-03-02 14:59:06 -05:00
return ;
}
if ( _this - > suspend_screensaver ) {
2014-06-18 20:11:39 +01:00
SDL_DBus_ScreensaverTickle ( ) ;
2014-03-02 14:59:06 -05:00
}
# endif
# if SDL_VIDEO_DRIVER_X11_XSCRNSAVER
2009-01-12 08:26:24 +00:00
if ( SDL_X11_HAVE_XSS ) {
2013-10-18 01:36:41 -04:00
/* X11_XScreenSaverSuspend was introduced in MIT-SCREEN-SAVER 1.1 */
if ( ! X11_XScreenSaverQueryExtension ( data - > display , & dummy , & dummy ) | |
! X11_XScreenSaverQueryVersion ( data - > display ,
2009-01-12 08:26:24 +00:00
& major_version , & minor_version ) | |
major_version < 1 | | ( major_version = = 1 & & minor_version < 1 ) ) {
return ;
}
2006-07-27 06:53:23 +00:00
2013-10-18 01:36:41 -04:00
X11_XScreenSaverSuspend ( data - > display , _this - > suspend_screensaver ) ;
X11_XResetScreenSaver ( data - > display ) ;
2006-07-27 06:53:23 +00:00
}
2009-01-12 08:26:24 +00:00
# endif
2006-07-27 06:53:23 +00:00
}
2011-03-12 13:21:57 -08:00
# endif /* SDL_VIDEO_DRIVER_X11 */
2006-07-27 06:53:23 +00:00
/* vi: set ts=4 sw=4 expandtab: */