| /* |
| * X11 windows driver |
| * |
| * Copyright 1993, 1994 Alexandre Julliard |
| * Copyright 1998 Patrik Stridvall |
| */ |
| |
| #include <string.h> |
| #include <X11/Xatom.h> |
| #include "ts_xlib.h" |
| #include "color.h" |
| #include "display.h" |
| #include "dce.h" |
| #include "options.h" |
| #include "message.h" |
| #include "win.h" |
| #include "windows.h" |
| #include "x11drv.h" |
| |
| static BOOL32 X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCT32A *cs, BOOL32 bUnicode); |
| static WND *X11DRV_WND_SetParent(WND *wndPtr, WND *pWndParent); |
| |
| WND_DRIVER X11DRV_WND_Driver = |
| { |
| X11DRV_WND_CreateWindow, |
| X11DRV_WND_SetParent |
| }; |
| |
| extern Cursor DISPLAY_XCursor; /* Current X cursor */ |
| |
| /********************************************************************** |
| * X11DRV_WND_CreateWindow [Internal] |
| */ |
| static BOOL32 X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCT32A *cs, BOOL32 bUnicode) |
| { |
| /* Create the X window (only for top-level windows, and then only */ |
| /* when there's no desktop window) */ |
| |
| if (!(cs->style & WS_CHILD) && (rootWindow == DefaultRootWindow(display))) |
| { |
| XSetWindowAttributes win_attr; |
| |
| if (Options.managed && ((cs->style & (WS_DLGFRAME | WS_THICKFRAME)) || |
| (cs->dwExStyle & WS_EX_DLGMODALFRAME))) |
| { |
| win_attr.event_mask = ExposureMask | KeyPressMask | |
| KeyReleaseMask | PointerMotionMask | |
| ButtonPressMask | ButtonReleaseMask | |
| FocusChangeMask | StructureNotifyMask; |
| win_attr.override_redirect = FALSE; |
| wndPtr->flags |= WIN_MANAGED; |
| } |
| else |
| { |
| win_attr.event_mask = ExposureMask | KeyPressMask | |
| KeyReleaseMask | PointerMotionMask | |
| ButtonPressMask | ButtonReleaseMask | |
| FocusChangeMask; |
| win_attr.override_redirect = TRUE; |
| } |
| win_attr.colormap = COLOR_GetColormap(); |
| win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful; |
| win_attr.save_under = ((classPtr->style & CS_SAVEBITS) != 0); |
| win_attr.cursor = DISPLAY_XCursor; |
| wndPtr->window = TSXCreateWindow( display, rootWindow, cs->x, cs->y, |
| cs->cx, cs->cy, 0, CopyFromParent, |
| InputOutput, CopyFromParent, |
| CWEventMask | CWOverrideRedirect | |
| CWColormap | CWCursor | CWSaveUnder | |
| CWBackingStore, &win_attr ); |
| |
| if ((wndPtr->flags & WIN_MANAGED) && |
| (cs->dwExStyle & WS_EX_DLGMODALFRAME)) |
| { |
| XSizeHints* size_hints = TSXAllocSizeHints(); |
| |
| if (size_hints) |
| { |
| size_hints->min_width = size_hints->max_width = cs->cx; |
| size_hints->min_height = size_hints->max_height = cs->cy; |
| size_hints->flags = (PSize | PMinSize | PMaxSize); |
| TSXSetWMSizeHints( display, wndPtr->window, size_hints, |
| XA_WM_NORMAL_HINTS ); |
| TSXFree(size_hints); |
| } |
| } |
| |
| if (cs->hwndParent) /* Get window owner */ |
| { |
| Window win = WIN_GetXWindow( cs->hwndParent ); |
| if (win) TSXSetTransientForHint( display, wndPtr->window, win ); |
| } |
| EVENT_RegisterWindow( wndPtr ); |
| } |
| return TRUE; |
| } |
| |
| /***************************************************************** |
| * X11DRV_WND_SetParent [Internal] |
| */ |
| static WND *X11DRV_WND_SetParent(WND *wndPtr, WND *pWndParent) |
| { |
| if( wndPtr && pWndParent && (wndPtr != WIN_GetDesktop()) ) |
| { |
| WND* pWndPrev = wndPtr->parent; |
| |
| if( pWndParent != pWndPrev ) |
| { |
| BOOL32 bFixupDCE = IsWindowVisible32(wndPtr->hwndSelf); |
| |
| if ( wndPtr->window ) |
| { |
| /* Toplevel window needs to be reparented. Used by Tk 8.0 */ |
| |
| TSXDestroyWindow( display, wndPtr->window ); |
| wndPtr->window = None; |
| } |
| else if( bFixupDCE ) |
| DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow ); |
| |
| WIN_UnlinkWindow(wndPtr->hwndSelf); |
| wndPtr->parent = pWndParent; |
| |
| /* FIXME: Create an X counterpart for reparented top-level windows |
| * when not in the desktop mode. */ |
| |
| if ( pWndParent != WIN_GetDesktop() ) wndPtr->dwStyle |= WS_CHILD; |
| WIN_LinkWindow(wndPtr->hwndSelf, HWND_BOTTOM); |
| |
| if( bFixupDCE ) |
| { |
| DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow ); |
| UpdateWindow32(wndPtr->hwndSelf); |
| } |
| } |
| return pWndPrev; |
| } /* failure */ |
| return 0; |
| } |