From 2744c0195a29637d3401929e2fd011b14fd3a093 Mon Sep 17 00:00:00 2001 From: Damian Kaczmarek Date: Tue, 27 May 2014 14:41:16 -0400 Subject: [PATCH] Initial work on X11 implementation of SDL_SetWindowDragAreas(). --- src/video/x11/SDL_x11events.c | 48 +++++++++++++++++++++++++++++++++++ src/video/x11/SDL_x11video.c | 1 + src/video/x11/SDL_x11window.c | 6 +++++ src/video/x11/SDL_x11window.h | 1 + 4 files changed, 56 insertions(+) diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index 50e73946d5b75..db6a301d1cca6 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -272,6 +272,51 @@ X11_DispatchUnmapNotify(SDL_WindowData *data) SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); } +static void +InitiateWindowMove(SDL_Window *window) +{ + SDL_SysWMinfo info; + SDL_VERSION(&info.version); + SDL_GetWindowWMInfo(window, &info); + Display *display = info.info.x11.display; + + int bx, by, dx, dy; + SDL_GetWindowPosition(window, &bx, &by); + SDL_GetMouseState(&dx, &dy); + X11_XUngrabPointer(display, 0L); + X11_XFlush(display); + + XEvent evt; + evt.xclient.type = ClientMessage; + evt.xclient.window = info.info.x11.window; + evt.xclient.message_type = X11_XInternAtom(display, "_NET_WM_MOVERESIZE", False); + evt.xclient.format = 32; + evt.xclient.data.l[0] = bx + dx; + evt.xclient.data.l[1] = by + dy; + evt.xclient.data.l[2] = 8; /* _NET_WM_MOVERESIZE_MOVE */ + evt.xclient.data.l[3] = Button1; + evt.xclient.data.l[4] = 0; + X11_XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &evt); + + X11_XSync(display, 0); +} + +static void +ProcessDragArea(SDL_WindowData* data) +{ + SDL_Window* window = data->window; + SDL_Mouse* mouse = SDL_GetMouse(); + int i; + const int num_areas = window->num_drag_areas; + const SDL_Point point = {mouse->x, mouse->y}; + const SDL_Rect *areas = window->drag_areas; + for(i = 0;i < num_areas;++i) { + if (SDL_PointInRect(&point, &areas[i])) { + InitiateWindowMove(window); + } + } +} + static void X11_DispatchEvent(_THIS) { @@ -709,6 +754,9 @@ X11_DispatchEvent(_THIS) if (X11_IsWheelEvent(display,&xevent,&ticks)) { SDL_SendMouseWheel(data->window, 0, 0, ticks); } else { + if(xevent.xbutton.button == SDL_BUTTON_LEFT) { + ProcessDragArea(data); + } SDL_SendMouseButton(data->window, 0, SDL_PRESSED, xevent.xbutton.button); } } diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index ca9faee31e8f8..4cece018eff8f 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -457,6 +457,7 @@ X11_CreateDevice(int devindex) device->UpdateWindowFramebuffer = X11_UpdateWindowFramebuffer; device->DestroyWindowFramebuffer = X11_DestroyWindowFramebuffer; device->GetWindowWMInfo = X11_GetWindowWMInfo; + device->SetWindowDragAreas = X11_SetWindowDragAreas; device->shape_driver.CreateShaper = X11_CreateShaper; device->shape_driver.SetWindowShape = X11_SetWindowShape; diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index b4de15be89a77..2c0c9e41b0a1e 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -1444,6 +1444,12 @@ X11_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) } } +int +X11_SetWindowDragAreas(SDL_Window *window, const SDL_Rect *areas, int num_areas) +{ + return 0; // nothing to do, will be handled in event handler +} + #endif /* SDL_VIDEO_DRIVER_X11 */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/x11/SDL_x11window.h b/src/video/x11/SDL_x11window.h index cf0d7f799c8f3..6a00c1a667083 100644 --- a/src/video/x11/SDL_x11window.h +++ b/src/video/x11/SDL_x11window.h @@ -93,6 +93,7 @@ extern void X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void X11_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool X11_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); +extern int X11_SetWindowDragAreas(SDL_Window *window, const SDL_Rect *areas, int num_areas); #endif /* _SDL_x11window_h */