winex11: Moved the WM_SYSCOMMAND handling to window.c.

This commit is contained in:
Alexandre Julliard 2008-04-17 16:13:34 +02:00
parent 64e8128409
commit 24dbaa0856
2 changed files with 134 additions and 134 deletions

View File

@ -50,6 +50,18 @@
WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
#define _NET_WM_MOVERESIZE_SIZE_TOP 1
#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
#define _NET_WM_MOVERESIZE_SIZE_LEFT 7
#define _NET_WM_MOVERESIZE_MOVE 8
#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD 9
#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10
/* X context to associate a hwnd to an X window */
XContext winContext = 0;
@ -1640,3 +1652,125 @@ int X11DRV_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
return TRUE;
}
/***********************************************************************
* is_netwm_supported
*/
static BOOL is_netwm_supported( Display *display, Atom atom )
{
static Atom *net_supported;
static int net_supported_count = -1;
int i;
wine_tsx11_lock();
if (net_supported_count == -1)
{
Atom type;
int format;
unsigned long count, remaining;
if (!XGetWindowProperty( display, DefaultRootWindow(display), x11drv_atom(_NET_SUPPORTED), 0,
~0UL, False, XA_ATOM, &type, &format, &count,
&remaining, (unsigned char **)&net_supported ))
net_supported_count = get_property_size( format, count ) / sizeof(Atom);
else
net_supported_count = 0;
}
wine_tsx11_unlock();
for (i = 0; i < net_supported_count; i++)
if (net_supported[i] == atom) return TRUE;
return FALSE;
}
/***********************************************************************
* SysCommand (X11DRV.@)
*
* Perform WM_SYSCOMMAND handling.
*/
LRESULT X11DRV_SysCommand( HWND hwnd, WPARAM wparam, LPARAM lparam )
{
WPARAM hittest = wparam & 0x0f;
DWORD dwPoint;
int x, y, dir;
XEvent xev;
Display *display = thread_display();
struct x11drv_win_data *data;
if (!(data = X11DRV_get_win_data( hwnd ))) return -1;
if (!data->whole_window || !data->managed || !data->mapped) return -1;
switch (wparam & 0xfff0)
{
case SC_MOVE:
if (!hittest) dir = _NET_WM_MOVERESIZE_MOVE_KEYBOARD;
else dir = _NET_WM_MOVERESIZE_MOVE;
break;
case SC_SIZE:
/* windows without WS_THICKFRAME are not resizable through the window manager */
if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_THICKFRAME)) return -1;
switch (hittest)
{
case WMSZ_LEFT: dir = _NET_WM_MOVERESIZE_SIZE_LEFT; break;
case WMSZ_RIGHT: dir = _NET_WM_MOVERESIZE_SIZE_RIGHT; break;
case WMSZ_TOP: dir = _NET_WM_MOVERESIZE_SIZE_TOP; break;
case WMSZ_TOPLEFT: dir = _NET_WM_MOVERESIZE_SIZE_TOPLEFT; break;
case WMSZ_TOPRIGHT: dir = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT; break;
case WMSZ_BOTTOM: dir = _NET_WM_MOVERESIZE_SIZE_BOTTOM; break;
case WMSZ_BOTTOMLEFT: dir = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT; break;
case WMSZ_BOTTOMRIGHT: dir = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT; break;
default: dir = _NET_WM_MOVERESIZE_SIZE_KEYBOARD; break;
}
break;
case SC_KEYMENU:
/* prevent a simple ALT press+release from activating the system menu,
* as that can get confusing on managed windows */
if ((WCHAR)lparam) return -1; /* got an explicit char */
if (GetMenu( hwnd )) return -1; /* window has a real menu */
if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_SYSMENU)) return -1; /* no system menu */
TRACE( "ignoring SC_KEYMENU wp %lx lp %lx\n", wparam, lparam );
return 0;
default:
return -1;
}
if (IsZoomed(hwnd)) return -1;
if (!is_netwm_supported( display, x11drv_atom(_NET_WM_MOVERESIZE) ))
{
TRACE( "_NET_WM_MOVERESIZE not supported\n" );
return -1;
}
dwPoint = GetMessagePos();
x = (short)LOWORD(dwPoint);
y = (short)HIWORD(dwPoint);
TRACE("hwnd %p, x %d, y %d, dir %d\n", hwnd, x, y, dir);
xev.xclient.type = ClientMessage;
xev.xclient.window = X11DRV_get_whole_window(hwnd);
xev.xclient.message_type = x11drv_atom(_NET_WM_MOVERESIZE);
xev.xclient.serial = 0;
xev.xclient.display = display;
xev.xclient.send_event = True;
xev.xclient.format = 32;
xev.xclient.data.l[0] = x; /* x coord */
xev.xclient.data.l[1] = y; /* y coord */
xev.xclient.data.l[2] = dir; /* direction */
xev.xclient.data.l[3] = 1; /* button */
xev.xclient.data.l[4] = 0; /* unused */
/* need to ungrab the pointer that may have been automatically grabbed
* with a ButtonPress event */
wine_tsx11_lock();
XUngrabPointer( display, CurrentTime );
XSendEvent(display, root_window, False, SubstructureNotifyMask, &xev);
wine_tsx11_unlock();
return 0;
}

View File

@ -42,18 +42,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
#define SWP_AGG_NOPOSCHANGE \
(SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE | SWP_NOZORDER)
#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
#define _NET_WM_MOVERESIZE_SIZE_TOP 1
#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
#define _NET_WM_MOVERESIZE_SIZE_LEFT 7
#define _NET_WM_MOVERESIZE_MOVE 8 /* movement only */
#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD 9 /* size via keyboard */
#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 /* move via keyboard */
#define _NET_WM_STATE_REMOVE 0
#define _NET_WM_STATE_ADD 1
#define _NET_WM_STATE_TOGGLE 2
@ -609,125 +597,3 @@ void X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
SetWindowPos( hwnd, 0, x, y, cx, cy, flags );
}
/***********************************************************************
* is_netwm_supported
*/
static BOOL is_netwm_supported( Display *display, Atom atom )
{
static Atom *net_supported;
static int net_supported_count = -1;
int i;
wine_tsx11_lock();
if (net_supported_count == -1)
{
Atom type;
int format;
unsigned long count, remaining;
if (!XGetWindowProperty( display, DefaultRootWindow(display), x11drv_atom(_NET_SUPPORTED), 0,
~0UL, False, XA_ATOM, &type, &format, &count,
&remaining, (unsigned char **)&net_supported ))
net_supported_count = get_property_size( format, count ) / sizeof(Atom);
else
net_supported_count = 0;
}
wine_tsx11_unlock();
for (i = 0; i < net_supported_count; i++)
if (net_supported[i] == atom) return TRUE;
return FALSE;
}
/***********************************************************************
* SysCommand (X11DRV.@)
*
* Perform WM_SYSCOMMAND handling.
*/
LRESULT X11DRV_SysCommand( HWND hwnd, WPARAM wparam, LPARAM lparam )
{
WPARAM hittest = wparam & 0x0f;
DWORD dwPoint;
int x, y, dir;
XEvent xev;
Display *display = thread_display();
struct x11drv_win_data *data;
if (!(data = X11DRV_get_win_data( hwnd ))) return -1;
if (!data->whole_window || !data->managed || !data->mapped) return -1;
switch (wparam & 0xfff0)
{
case SC_MOVE:
if (!hittest) dir = _NET_WM_MOVERESIZE_MOVE_KEYBOARD;
else dir = _NET_WM_MOVERESIZE_MOVE;
break;
case SC_SIZE:
/* windows without WS_THICKFRAME are not resizable through the window manager */
if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_THICKFRAME)) return -1;
switch (hittest)
{
case WMSZ_LEFT: dir = _NET_WM_MOVERESIZE_SIZE_LEFT; break;
case WMSZ_RIGHT: dir = _NET_WM_MOVERESIZE_SIZE_RIGHT; break;
case WMSZ_TOP: dir = _NET_WM_MOVERESIZE_SIZE_TOP; break;
case WMSZ_TOPLEFT: dir = _NET_WM_MOVERESIZE_SIZE_TOPLEFT; break;
case WMSZ_TOPRIGHT: dir = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT; break;
case WMSZ_BOTTOM: dir = _NET_WM_MOVERESIZE_SIZE_BOTTOM; break;
case WMSZ_BOTTOMLEFT: dir = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT; break;
case WMSZ_BOTTOMRIGHT: dir = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT; break;
default: dir = _NET_WM_MOVERESIZE_SIZE_KEYBOARD; break;
}
break;
case SC_KEYMENU:
/* prevent a simple ALT press+release from activating the system menu,
* as that can get confusing on managed windows */
if ((WCHAR)lparam) return -1; /* got an explicit char */
if (GetMenu( hwnd )) return -1; /* window has a real menu */
if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_SYSMENU)) return -1; /* no system menu */
TRACE( "ignoring SC_KEYMENU wp %lx lp %lx\n", wparam, lparam );
return 0;
default:
return -1;
}
if (IsZoomed(hwnd)) return -1;
if (!is_netwm_supported( display, x11drv_atom(_NET_WM_MOVERESIZE) ))
{
TRACE( "_NET_WM_MOVERESIZE not supported\n" );
return -1;
}
dwPoint = GetMessagePos();
x = (short)LOWORD(dwPoint);
y = (short)HIWORD(dwPoint);
TRACE("hwnd %p, x %d, y %d, dir %d\n", hwnd, x, y, dir);
xev.xclient.type = ClientMessage;
xev.xclient.window = X11DRV_get_whole_window(hwnd);
xev.xclient.message_type = x11drv_atom(_NET_WM_MOVERESIZE);
xev.xclient.serial = 0;
xev.xclient.display = display;
xev.xclient.send_event = True;
xev.xclient.format = 32;
xev.xclient.data.l[0] = x; /* x coord */
xev.xclient.data.l[1] = y; /* y coord */
xev.xclient.data.l[2] = dir; /* direction */
xev.xclient.data.l[3] = 1; /* button */
xev.xclient.data.l[4] = 0; /* unused */
/* need to ungrab the pointer that may have been automatically grabbed
* with a ButtonPress event */
wine_tsx11_lock();
XUngrabPointer( display, CurrentTime );
XSendEvent(display, root_window, False, SubstructureNotifyMask, &xev);
wine_tsx11_unlock();
return 0;
}