static void update_desktop_fullscreen( unsigned int width, unsigned int height) { Display *display = thread_display(); XEvent xev; if (!display || root_window == DefaultRootWindow( display )) return; xev.xclient.type = ClientMessage; xev.xclient.window = root_window; xev.xclient.message_type = x11drv_atom(_NET_WM_STATE); xev.xclient.serial = 0; xev.xclient.display = display; xev.xclient.send_event = True; xev.xclient.format = 32; if (width == max_width && height == max_height) xev.xclient.data.l[0] = _NET_WM_STATE_ADD; else xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE; xev.xclient.data.l[1] = x11drv_atom(_NET_WM_STATE_FULLSCREEN); xev.xclient.data.l[2] = 0; xev.xclient.data.l[3] = 1; TRACE("action=%li\n", xev.xclient.data.l[0]); XSendEvent( display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev ); xev.xclient.data.l[1] = x11drv_atom(_NET_WM_STATE_MAXIMIZED_VERT); xev.xclient.data.l[2] = x11drv_atom(_NET_WM_STATE_MAXIMIZED_HORZ); XSendEvent( display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev ); }
/*********************************************************************** * X11DRV_create_desktop * * Create the X11 desktop window for the desktop mode. */ BOOL CDECL X11DRV_create_desktop( UINT width, UINT height ) { XSetWindowAttributes win_attr; Window win; Display *display = thread_init_display(); TRACE( "%u x %u\n", width, height ); /* Create window */ win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | EnterWindowMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | FocusChangeMask; win_attr.cursor = XCreateFontCursor( display, XC_top_left_arrow ); if (default_visual.visual != DefaultVisual( display, DefaultScreen(display) )) win_attr.colormap = XCreateColormap( display, DefaultRootWindow(display), default_visual.visual, AllocNone ); else win_attr.colormap = None; win = XCreateWindow( display, DefaultRootWindow(display), 0, 0, width, height, 0, default_visual.depth, InputOutput, default_visual.visual, CWEventMask | CWCursor | CWColormap, &win_attr ); if (!win) return FALSE; if (width == screen_width && height == screen_height) { TRACE("setting desktop to fullscreen\n"); XChangeProperty( display, win, x11drv_atom(_NET_WM_STATE), XA_ATOM, 32, PropModeReplace, (unsigned char*)&x11drv_atom(_NET_WM_STATE_FULLSCREEN), 1); } XFlush( display ); X11DRV_init_desktop( win, width, height ); return TRUE; }
static void query_work_area( RECT *rc_work ) { Atom type; int format; unsigned long count, remaining; long *work_area; if (!XGetWindowProperty( gdi_display, DefaultRootWindow(gdi_display), x11drv_atom(_NET_WORKAREA), 0, ~0, False, XA_CARDINAL, &type, &format, &count, &remaining, (unsigned char **)&work_area )) { if (type == XA_CARDINAL && format == 32 && count >= 4) { SetRect( rc_work, work_area[0], work_area[1], work_area[0] + work_area[2], work_area[1] + work_area[3] ); } XFree( work_area ); } }
/********************************************************************** * EVENT_DropURLs * * drop items are separated by \n * each item is prefixed by its mime type * * event->data.l[3], event->data.l[4] contains drop x,y position */ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event ) { unsigned long data_length; unsigned long aux_long, drop_len = 0; unsigned char *p_data = NULL; /* property data */ char *p_drop = NULL; char *p, *next; int x, y; DROPFILES *lpDrop; HDROP hDrop; union { Atom atom_aux; int i; Window w_aux; unsigned int u; } u; /* unused */ if (!(GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES)) return; wine_tsx11_lock(); XGetWindowProperty( event->display, DefaultRootWindow(event->display), x11drv_atom(DndSelection), 0, 65535, FALSE, AnyPropertyType, &u.atom_aux, &u.i, &data_length, &aux_long, &p_data); wine_tsx11_unlock(); if (aux_long) WARN("property too large, truncated!\n"); TRACE("urls=%s\n", p_data); if( !aux_long && p_data) { /* don't bother if > 64K */ /* calculate length */ p = (char*) p_data; next = strchr(p, '\n'); while (p) { if (next) *next=0; if (strncmp(p,"file:",5) == 0 ) { INT len = GetShortPathNameA( p+5, NULL, 0 ); if (len) drop_len += len + 1; } if (next) { *next = '\n'; p = next + 1; next = strchr(p, '\n'); } else { p = NULL; } } if( drop_len && drop_len < 65535 ) { wine_tsx11_lock(); XQueryPointer( event->display, root_window, &u.w_aux, &u.w_aux, &x, &y, &u.i, &u.i, &u.u); wine_tsx11_unlock(); drop_len += sizeof(DROPFILES) + 1; hDrop = GlobalAlloc( GMEM_SHARE, drop_len ); lpDrop = (DROPFILES *) GlobalLock( hDrop ); if( lpDrop ) { WND *pDropWnd = WIN_GetPtr( hWnd ); lpDrop->pFiles = sizeof(DROPFILES); lpDrop->pt.x = (INT)x; lpDrop->pt.y = (INT)y; lpDrop->fNC = ( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left) || y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top) || x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) || y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) ); lpDrop->fWide = FALSE; p_drop = (char*)(lpDrop + 1); WIN_ReleasePtr(pDropWnd); } /* create message content */ if (p_drop) { p = (char*) p_data; next = strchr(p, '\n'); while (p) { if (next) *next=0; if (strncmp(p,"file:",5) == 0 ) { INT len = GetShortPathNameA( p+5, p_drop, 65535 ); if (len) { TRACE("drop file %s as %s\n", p+5, p_drop); p_drop += len+1; } else { WARN("can't convert file %s to dos name\n", p+5); } } else { WARN("unknown mime type %s\n", p); } if (next) { *next = '\n'; p = next + 1; next = strchr(p, '\n'); } else { p = NULL; } *p_drop = '\0'; } GlobalUnlock(hDrop); PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L ); } } wine_tsx11_lock(); if( p_data ) XFree(p_data); wine_tsx11_unlock(); } }
/********************************************************************** * EVENT_DropFromOffix * * don't know if it still works (last Changlog is from 96/11/04) */ static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event ) { unsigned long data_length; unsigned long aux_long; unsigned char* p_data = NULL; Atom atom_aux; int x, y, dummy; BOOL bAccept; Window win, w_aux_root, w_aux_child; WND* pWnd; HWND hScope = hWnd; win = X11DRV_get_whole_window(hWnd); wine_tsx11_lock(); XQueryPointer( event->display, win, &w_aux_root, &w_aux_child, &x, &y, &dummy, &dummy, (unsigned int*)&aux_long); wine_tsx11_unlock(); pWnd = WIN_GetPtr(hWnd); /* find out drop point and drop window */ if( x < 0 || y < 0 || x > (pWnd->rectWindow.right - pWnd->rectWindow.left) || y > (pWnd->rectWindow.bottom - pWnd->rectWindow.top) ) { bAccept = pWnd->dwExStyle & WS_EX_ACCEPTFILES; x = 0; y = 0; } else { POINT pt = { x, y }; HWND hwndDrop = find_drop_window( hWnd, &pt ); if (hwndDrop) { x = pt.x; y = pt.y; hScope = hwndDrop; bAccept = TRUE; } else { bAccept = FALSE; } } WIN_ReleasePtr(pWnd); if (!bAccept) return; wine_tsx11_lock(); XGetWindowProperty( event->display, DefaultRootWindow(event->display), x11drv_atom(DndSelection), 0, 65535, FALSE, AnyPropertyType, &atom_aux, &dummy, &data_length, &aux_long, &p_data); wine_tsx11_unlock(); if( !aux_long && p_data) /* don't bother if > 64K */ { char *p = (char *)p_data; char *p_drop; aux_long = 0; while( *p ) /* calculate buffer size */ { INT len = GetShortPathNameA( p, NULL, 0 ); if (len) aux_long += len + 1; p += strlen(p) + 1; } if( aux_long && aux_long < 65535 ) { HDROP hDrop; DROPFILES *lpDrop; aux_long += sizeof(DROPFILES) + 1; hDrop = GlobalAlloc( GMEM_SHARE, aux_long ); lpDrop = (DROPFILES*)GlobalLock( hDrop ); if( lpDrop ) { WND *pDropWnd = WIN_GetPtr( hScope ); lpDrop->pFiles = sizeof(DROPFILES); lpDrop->pt.x = x; lpDrop->pt.y = y; lpDrop->fNC = ( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left) || y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top) || x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) || y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) ); lpDrop->fWide = FALSE; WIN_ReleasePtr(pDropWnd); p_drop = (char *)(lpDrop + 1); p = (char *)p_data; while(*p) { if (GetShortPathNameA( p, p_drop, aux_long - (p_drop - (char *)lpDrop) )) p_drop += strlen( p_drop ) + 1; p += strlen(p) + 1; } *p_drop = '\0'; PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L ); } } } wine_tsx11_lock(); if( p_data ) XFree(p_data); wine_tsx11_unlock(); }
/********************************************************************** * handle_wm_protocols */ static void handle_wm_protocols( HWND hwnd, XClientMessageEvent *event ) { Atom protocol = (Atom)event->data.l[0]; if (!protocol) return; if (protocol == x11drv_atom(WM_DELETE_WINDOW)) { /* Ignore the delete window request if the window has been disabled * and we are in managed mode. This is to disallow applications from * being closed by the window manager while in a modal state. */ if (IsWindowEnabled(hwnd)) { HMENU hSysMenu; if (GetClassLongW(hwnd, GCL_STYLE) & CS_NOCLOSE) return; hSysMenu = GetSystemMenu(hwnd, FALSE); if (hSysMenu) { UINT state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND); if (state == 0xFFFFFFFF || (state & (MF_DISABLED | MF_GRAYED))) return; } PostMessageW( hwnd, WM_X11DRV_DELETE_WINDOW, 0, 0 ); } } else if (protocol == x11drv_atom(WM_TAKE_FOCUS)) { Time event_time = (Time)event->data.l[1]; HWND last_focus = x11drv_thread_data()->last_focus; TRACE( "got take focus msg for %p, enabled=%d, visible=%d (style %08lx), focus=%p, active=%p, fg=%p, last=%p\n", hwnd, IsWindowEnabled(hwnd), IsWindowVisible(hwnd), GetWindowLongW(hwnd, GWL_STYLE), GetFocus(), GetActiveWindow(), GetForegroundWindow(), last_focus ); if (can_activate_window(hwnd)) { /* simulate a mouse click on the caption to find out * whether the window wants to be activated */ LRESULT ma = SendMessageW( hwnd, WM_MOUSEACTIVATE, (WPARAM)GetAncestor( hwnd, GA_ROOT ), MAKELONG(HTCAPTION,WM_LBUTTONDOWN) ); if (ma != MA_NOACTIVATEANDEAT && ma != MA_NOACTIVATE) set_focus( hwnd, event_time ); else TRACE( "not setting focus to %p (%lx), ma=%ld\n", hwnd, event->window, ma ); } else { hwnd = GetFocus(); if (hwnd) hwnd = GetAncestor( hwnd, GA_ROOT ); if (!hwnd) hwnd = GetActiveWindow(); if (!hwnd) hwnd = last_focus; if (hwnd && can_activate_window(hwnd)) set_focus( hwnd, event_time ); } } else if (protocol == x11drv_atom(_NET_WM_PING)) { XClientMessageEvent xev; xev = *event; TRACE("NET_WM Ping\n"); wine_tsx11_lock(); xev.window = DefaultRootWindow(xev.display); XSendEvent(xev.display, xev.window, False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent*)&xev); wine_tsx11_unlock(); /* this line is semi-stolen from gtk2 */ TRACE("NET_WM Pong\n"); } }