| /* |
| * Window related functions |
| * |
| * Copyright 1993 Alexandre Julliard |
| */ |
| |
| static char Copyright[] = "Copyright Alexandre Julliard, 1993"; |
| |
| #include <X11/Intrinsic.h> |
| #include <X11/StringDefs.h> |
| #include <X11/Core.h> |
| #include <X11/Shell.h> |
| #include <X11/Xaw/Box.h> |
| |
| #include "class.h" |
| #include "win.h" |
| #include "heap.h" |
| |
| extern Display * XT_display; |
| |
| |
| static HWND firstWindow = 0; |
| |
| |
| /*********************************************************************** |
| * WIN_FindWndPtr |
| * |
| * Return a pointer to the WND structure corresponding to a HWND. |
| * The caller must GlobalUnlock the pointer. |
| */ |
| WND * WIN_FindWndPtr( HWND hwnd ) |
| { |
| WND * ptr; |
| |
| if (!hwnd) return NULL; |
| ptr = (WND *) GlobalLock( hwnd ); |
| if (ptr->dwMagic != WND_MAGIC) |
| { |
| GlobalUnlock( hwnd ); |
| return NULL; |
| } |
| return ptr; |
| } |
| |
| |
| /*********************************************************************** |
| * WIN_FindWinToRepaint |
| * |
| * Find a window that needs repaint. |
| */ |
| HWND WIN_FindWinToRepaint( HWND hwnd ) |
| { |
| WND * wndPtr; |
| |
| if (!hwnd) hwnd = firstWindow; |
| while (hwnd) |
| { |
| if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; |
| if (wndPtr->hrgnUpdate) return hwnd; |
| if (wndPtr->hwndChild) |
| { |
| HWND child; |
| if ((child = WIN_FindWinToRepaint( wndPtr->hwndChild ))) |
| return child; |
| } |
| hwnd = wndPtr->hwndNext; |
| } |
| return 0; |
| } |
| |
| |
| /*********************************************************************** |
| * CreateWindow (USER.41) |
| */ |
| HWND CreateWindow( LPSTR className, LPSTR windowName, |
| DWORD style, short x, short y, short width, short height, |
| HWND parent, HMENU menu, HANDLE instance, LPSTR data ) |
| { |
| HANDLE class, hwnd; |
| CLASS *classPtr; |
| WND *wndPtr, *parentPtr = NULL; |
| CREATESTRUCT *createStruct; |
| HANDLE hcreateStruct; |
| int wmcreate; |
| Widget parentWidget = 0; |
| |
| #ifdef DEBUG_WIN |
| printf( "CreateWindow: %s %s %d,%d %dx%d\n", className, windowName, x, y, width, height ); |
| #endif |
| |
| if (x == CW_USEDEFAULT) x = 0; |
| if (y == CW_USEDEFAULT) y = 0; |
| if (width == CW_USEDEFAULT) width = 600; |
| if (height == CW_USEDEFAULT) height = 400; |
| |
| /* Find the parent and class */ |
| |
| if (parent) |
| { |
| /* Check if parent is valid */ |
| parentPtr = WIN_FindWndPtr( parent ); |
| if (!parentPtr) return 0; |
| } |
| else if (style & WS_CHILD) return 0; /* WS_CHILD needs a parent */ |
| |
| if (!(class = CLASS_FindClassByName( className, &classPtr ))) |
| { |
| GlobalUnlock( parent ); |
| return 0; |
| } |
| |
| /* Create the window structure */ |
| |
| hwnd = GlobalAlloc( GMEM_MOVEABLE, sizeof(WND)+classPtr->wc.cbWndExtra ); |
| if (!hwnd) |
| { |
| GlobalUnlock( parent ); |
| return 0; |
| } |
| |
| /* Fill the structure */ |
| |
| wndPtr = (WND *) GlobalLock( hwnd ); |
| wndPtr->hwndNext = 0; |
| wndPtr->hwndChild = 0; |
| wndPtr->dwMagic = WND_MAGIC; |
| wndPtr->hwndParent = parent; |
| wndPtr->hwndOwner = parent; /* What else? */ |
| wndPtr->hClass = class; |
| wndPtr->hInstance = instance; |
| wndPtr->rectClient.left = x; |
| wndPtr->rectClient.top = y; |
| wndPtr->rectClient.right = x + width; |
| wndPtr->rectClient.bottom = y + height; |
| wndPtr->rectWindow = wndPtr->rectClient; |
| wndPtr->hrgnUpdate = 0; |
| wndPtr->hwndLastActive = 0; |
| wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc; |
| wndPtr->dwStyle = style; |
| wndPtr->hDCE = 0; |
| wndPtr->hmenuSystem = 0; |
| wndPtr->wIDmenu = menu; |
| wndPtr->flags = 0; |
| if (classPtr->wc.cbWndExtra) |
| memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra ); |
| classPtr->cWindows++; |
| |
| /* Insert the window in the linked list */ |
| |
| if (parent) |
| { |
| wndPtr->hwndNext = parentPtr->hwndChild; |
| parentPtr->hwndChild = hwnd; |
| } |
| else /* Top-level window */ |
| { |
| wndPtr->hwndNext = firstWindow; |
| firstWindow = hwnd; |
| } |
| |
| /* Create the widgets */ |
| |
| if (style & WS_CHILD) |
| { |
| wndPtr->shellWidget = 0; |
| wndPtr->winWidget = XtVaCreateManagedWidget(className, |
| coreWidgetClass, |
| parentPtr->winWidget, |
| XtNx, x, |
| XtNy, y, |
| XtNwidth, width, |
| XtNheight, height, |
| NULL ); |
| } |
| else |
| { |
| wndPtr->shellWidget = XtVaAppCreateShell(className, |
| windowName, |
| topLevelShellWidgetClass, |
| XT_display, |
| XtNx, x, |
| XtNy, y, |
| NULL ); |
| wndPtr->compositeWidget = XtVaCreateManagedWidget(className, |
| formWidgetClass, |
| wndPtr->shellWidget, |
| NULL ); |
| if (wndPtr->wIDmenu == 0) |
| { |
| wndPtr->menuBarPtr = MENU_CreateMenuBar(wndPtr->compositeWidget, |
| instance, hwnd, |
| classPtr->wc.lpszMenuName, |
| width); |
| wndPtr->wIDmenu = |
| GlobalHandleFromPointer(wndPtr->menuBarPtr->firstItem); |
| } |
| else |
| { |
| wndPtr->menuBarPtr = MENU_UseMenu(wndPtr->compositeWidget, |
| instance, hwnd, |
| wndPtr->wIDmenu, width); |
| } |
| |
| if (wndPtr->menuBarPtr != NULL) |
| { |
| wndPtr->winWidget = |
| XtVaCreateManagedWidget(className, |
| compositeWidgetClass, |
| wndPtr->compositeWidget, |
| XtNwidth, width, |
| XtNheight, height, |
| XtNfromVert, |
| wndPtr->menuBarPtr->menuBarWidget, |
| XtNvertDistance, 4, |
| NULL ); |
| } |
| else |
| { |
| wndPtr->winWidget = |
| XtVaCreateManagedWidget(className, |
| compositeWidgetClass, |
| wndPtr->compositeWidget, |
| XtNwidth, width, |
| XtNheight, height, |
| NULL ); |
| } |
| } |
| |
| /* Send the WM_CREATE message */ |
| |
| hcreateStruct = GlobalAlloc( GMEM_MOVEABLE, sizeof(CREATESTRUCT) ); |
| createStruct = (CREATESTRUCT *) GlobalLock( hcreateStruct ); |
| createStruct->lpCreateParams = data; |
| createStruct->hInstance = instance; |
| createStruct->hMenu = menu; |
| createStruct->hwndParent = parent; |
| createStruct->cx = width; |
| createStruct->cy = height; |
| createStruct->x = x; |
| createStruct->y = y; |
| createStruct->style = style; |
| createStruct->lpszName = windowName; |
| createStruct->lpszClass = className; |
| createStruct->dwExStyle = 0; |
| |
| wmcreate = CallWindowProc( wndPtr->lpfnWndProc, hwnd, |
| WM_CREATE, 0, (LONG) createStruct ); |
| GlobalUnlock( hcreateStruct ); |
| GlobalFree( hcreateStruct ); |
| |
| if (wmcreate == -1) |
| { |
| /* Abort window creation */ |
| if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget ); |
| else XtDestroyWidget( wndPtr->winWidget ); |
| GlobalUnlock( parent ); |
| GlobalUnlock( hwnd ); |
| GlobalFree( hwnd ); |
| return 0; |
| } |
| |
| EVENT_AddHandlers( wndPtr->winWidget, hwnd ); |
| |
| if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW ); |
| |
| GlobalUnlock( parent ); |
| GlobalUnlock( hwnd ); |
| return hwnd; |
| } |
| |
| /*********************************************************************** |
| * DestroyWindow (USER.53) |
| */ |
| BOOL DestroyWindow( HWND hwnd ) |
| { |
| WND *wndPtr, *parentPtr; |
| CLASS * classPtr; |
| |
| wndPtr = WIN_FindWndPtr( hwnd ); |
| if (!wndPtr) return FALSE; |
| |
| if (wndPtr->hwndParent) |
| { |
| parentPtr = WIN_FindWndPtr( wndPtr->hwndParent ); |
| printf( "INTERNAL ERROR: DestroyWindow: Invalid window parent\n" ); |
| return FALSE; |
| } |
| |
| classPtr = CLASS_FindClassPtr( wndPtr->hClass ); |
| if (!classPtr) |
| { |
| printf( "INTERNAL ERROR: DestroyWindow: Invalid window class\n" ); |
| return FALSE; |
| } |
| |
| SendMessage( hwnd, WM_DESTROY, 0, 0 ); |
| |
| /* Destroy all children */ |
| |
| /* ........... */ |
| |
| /* Remove the window from the linked list */ |
| |
| /* ........... */ |
| |
| /* Destroy the window */ |
| |
| if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget ); |
| else XtDestroyWidget( wndPtr->winWidget ); |
| classPtr->cWindows--; |
| if (wndPtr->hwndParent) GlobalUnlock( wndPtr->hwndParent ); |
| GlobalUnlock( hwnd ); |
| GlobalFree( hwnd ); |
| return TRUE; |
| } |
| |
| |
| /*********************************************************************** |
| * GetClientRect (USER.33) |
| */ |
| void GetClientRect( HWND hwnd, LPRECT rect ) |
| { |
| int width, height; |
| WND * wndPtr = WIN_FindWndPtr( hwnd ); |
| |
| rect->left = rect->top = rect->right = rect->bottom = 0; |
| if (wndPtr) |
| { |
| XtVaGetValues(wndPtr->winWidget, |
| XtNwidth, &width, |
| XtNheight, &height, |
| NULL ); |
| GlobalUnlock( hwnd ); |
| rect->right = width & 0xffff; |
| rect->bottom = height & 0xffff; |
| } |
| } |
| |
| |
| /*********************************************************************** |
| * ShowWindow (USER.42) |
| */ |
| BOOL ShowWindow( HWND hwnd, int cmd ) |
| { |
| int width, height; |
| |
| WND * wndPtr = WIN_FindWndPtr( hwnd ); |
| if (wndPtr) |
| { |
| if (wndPtr->shellWidget) XtRealizeWidget( wndPtr->shellWidget ); |
| GlobalUnlock( hwnd ); |
| XtVaGetValues(wndPtr->winWidget, |
| XtNwidth, &width, |
| XtNheight, &height, |
| NULL ); |
| SendMessage( hwnd, WM_SIZE, SIZE_RESTORED, |
| (width & 0xffff) | (height << 16) ); |
| SendMessage( hwnd, WM_SHOWWINDOW, TRUE, 0 ); |
| } |
| return TRUE; |
| } |
| |
| |
| /*********************************************************************** |
| * UpdateWindow (USER.124) |
| */ |
| void UpdateWindow( HWND hwnd ) |
| { |
| if (GetUpdateRect( hwnd, NULL, FALSE )) |
| SendMessage( hwnd, WM_PAINT, 0, 0 ); |
| } |
| |
| /********************************************************************** |
| * GetMenu (USER.157) |
| */ |
| HMENU GetMenu( HWND hwnd ) |
| { |
| WND *wndPtr; |
| HMENU hmenu; |
| |
| wndPtr = WIN_FindWndPtr(hwnd); |
| if (wndPtr == NULL) |
| return 0; |
| |
| hmenu = wndPtr->wIDmenu; |
| |
| GlobalUnlock(hwnd); |
| return hmenu; |
| } |
| |
| /********************************************************************** |
| * SetMenu (USER.158) |
| */ |
| BOOL SetMenu(HWND hwnd, HMENU hmenu) |
| { |
| WND *wndPtr; |
| |
| wndPtr = WIN_FindWndPtr(hwnd); |
| if (wndPtr == NULL) |
| return FALSE; |
| |
| if (wndPtr->dwStyle & WS_CHILD) |
| { |
| GlobalUnlock(hwnd); |
| return FALSE; |
| } |
| |
| if (wndPtr->menuBarPtr != NULL) |
| { |
| XtVaSetValues(wndPtr->winWidget, XtNfromVert, NULL, NULL); |
| MENU_CollapseMenu(wndPtr->menuBarPtr); |
| } |
| |
| wndPtr->menuBarPtr = MENU_UseMenu(wndPtr->compositeWidget, |
| wndPtr->hInstance, hwnd, hmenu, |
| wndPtr->rectClient.right - |
| wndPtr->rectClient.left); |
| |
| if (wndPtr->menuBarPtr != NULL) |
| { |
| XtVaSetValues(wndPtr->winWidget, |
| XtNfromVert, wndPtr->menuBarPtr->menuBarWidget, |
| XtNvertDistance, 4, |
| NULL); |
| } |
| else |
| { |
| if (wndPtr->wIDmenu != 0) |
| { |
| wndPtr->menuBarPtr = MENU_UseMenu(wndPtr->compositeWidget, |
| wndPtr->hInstance, hwnd, |
| wndPtr->wIDmenu, |
| wndPtr->rectClient.right - |
| wndPtr->rectClient.left); |
| } |
| |
| GlobalUnlock(hwnd); |
| return FALSE; |
| } |
| |
| GlobalUnlock(hwnd); |
| return TRUE; |
| } |