diff options
Diffstat (limited to 'hw/xwin/winmultiwindowwm.c')
-rw-r--r-- | hw/xwin/winmultiwindowwm.c | 424 |
1 files changed, 276 insertions, 148 deletions
diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c index f77a40476..786b4e001 100644 --- a/hw/xwin/winmultiwindowwm.c +++ b/hw/xwin/winmultiwindowwm.c @@ -51,8 +51,15 @@ #include <windows.h> /* Local headers */ +#include "obj_base.h" +#include "ddraw.h" #include "winwindow.h" +extern void winDebug(const char *format, ...); + +#ifndef CYGDEBUG +#define CYGDEBUG NO +#endif /* * Constant defines @@ -79,6 +86,7 @@ typedef struct _WMMsgQueueRec { struct _WMMsgNodeRec *pTail; pthread_mutex_t pmMutex; pthread_cond_t pcNotEmpty; + int nQueueSize; } WMMsgQueueRec, *WMMsgQueuePtr; typedef struct _WMInfo { @@ -96,9 +104,9 @@ typedef struct _WMProcArgRec { } WMProcArgRec, *WMProcArgPtr; typedef struct _XMsgProcArgRec { - Display *pDisplay; - DWORD dwScreen; - WMInfoPtr pWMInfo; + Display *pDisplay; + DWORD dwScreen; + WMInfoPtr pWMInfo; pthread_mutex_t *ppmServerStarted; } XMsgProcArgRec, *XMsgProcArgPtr; @@ -109,8 +117,6 @@ typedef struct _XMsgProcArgRec { extern char *display; extern void ErrorF (const char* /*f*/, ...); -extern Bool g_fCalledSetLocale; -extern Bool g_fCalledXInitThreads; /* @@ -139,26 +145,40 @@ static void* winMultiWindowWMProc (void* pArg); static int -winMultiWindowWMErrorHandler (Display *pDisp, XErrorEvent *e); +winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr); + +static int +winMultiWindowWMIOErrorHandler (Display *pDisplay); static void * winMultiWindowXMsgProc (void *pArg); +static int +winMultiWindowXMsgProcErrorHandler (Display *pDisplay, XErrorEvent *pErr); + +static int +winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay); + +static int +winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr); + static void winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg); -static int -winMutliWindowWMIOErrorHandler (Display *pDisplay); +#if 0 +static void +PreserveWin32Stack(WMInfoPtr pWMInfo, Window iWindow, UINT direction); +#endif /* * Local globals */ -static int g_nQueueSize; -static jmp_buf g_jmpEntry; +static jmp_buf g_jmpWMEntry; +static jmp_buf g_jmpXMsgProcEntry; static Bool g_shutdown = FALSE; - +static Bool redirectError = FALSE; /* @@ -214,7 +234,7 @@ PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode) #endif /* Increase the count of elements in the queue by one */ - ++g_nQueueSize; + ++(pQueue->nQueueSize); /* Release the queue mutex */ pthread_mutex_unlock (&pQueue->pmMutex); @@ -274,10 +294,10 @@ PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo) } /* Drop the number of elements in the queue by one */ - --g_nQueueSize; + --(pQueue->nQueueSize); #if CYGMULTIWINDOW_DEBUG - ErrorF ("Queue Size %d %d\n", g_nQueueSize, QueueSize(pQueue)); + ErrorF ("Queue Size %d %d\n", pQueue->nQueueSize, QueueSize(pQueue)); #endif /* Release the queue mutex */ @@ -328,10 +348,11 @@ InitQueue (WMMsgQueuePtr pQueue) pQueue->pTail = NULL; /* There are no elements initially */ - g_nQueueSize = 0; + pQueue->nQueueSize = 0; #if CYGMULTIWINDOW_DEBUG - ErrorF ("InitQueue - Queue Size %d %d\n", g_nQueueSize, QueueSize(pQueue)); + ErrorF ("InitQueue - Queue Size %d %d\n", pQueue->nQueueSize, + QueueSize(pQueue)); #endif ErrorF ("InitQueue - Calling pthread_mutex_init\n"); @@ -399,10 +420,10 @@ GetWindowName (Display *pDisplay, Window iWin, char **ppName) /* */ if (nNum && ppList && *ppList) { - XFree (xtpName.value); *ppName = strdup (*ppList); XFreeStringList (ppList); } + XFree (xtpName.value); #if CYGMULTIWINDOW_DEBUG ErrorF ("GetWindowName - %s %s\n", @@ -410,7 +431,6 @@ GetWindowName (Display *pDisplay, Window iWin, char **ppName) #endif } - #if CYGMULTIWINDOW_DEBUG ErrorF ("GetWindowName - Returning\n"); #endif @@ -499,6 +519,74 @@ UpdateName (WMInfoPtr pWMInfo, Window iWindow) } +#if 0 +/* + * Fix up any differences between the X11 and Win32 window stacks + * starting at the window passed in + */ +static void +PreserveWin32Stack(WMInfoPtr pWMInfo, Window iWindow, UINT direction) +{ + Atom atmType; + int fmtRet; + unsigned long items, remain; + HWND hWnd, *retHwnd; + DWORD myWinProcID, winProcID; + Window xWindow; + WINDOWPLACEMENT wndPlace; + + hWnd = NULL; + /* See if we can get the cached HWND for this window... */ + if (XGetWindowProperty (pWMInfo->pDisplay, + iWindow, + pWMInfo->atmPrivMap, + 0, + 1, + False, + pWMInfo->atmPrivMap, + &atmType, + &fmtRet, + &items, + &remain, + (unsigned char **) &retHwnd) == Success) + { + if (retHwnd) + { + hWnd = *retHwnd; + XFree (retHwnd); + } + } + + if (!hWnd) return; + + GetWindowThreadProcessId (hWnd, &myWinProcID); + hWnd = GetNextWindow (hWnd, direction); + + while (hWnd) { + GetWindowThreadProcessId (hWnd, &winProcID); + if (winProcID == myWinProcID) + { + wndPlace.length = sizeof(WINDOWPLACEMENT); + GetWindowPlacement (hWnd, &wndPlace); + if ( !(wndPlace.showCmd==SW_HIDE || + wndPlace.showCmd==SW_MINIMIZE) ) + { + xWindow = (Window)GetProp (hWnd, WIN_WID_PROP); + if (xWindow) + { + if (direction==GW_HWNDPREV) + XRaiseWindow (pWMInfo->pDisplay, xWindow); + else + XLowerWindow (pWMInfo->pDisplay, xWindow); + } + } + } + hWnd = GetNextWindow(hWnd, direction); + } +} +#endif /* PreserveWin32Stack */ + + /* * winMultiWindowWMProc */ @@ -527,7 +615,7 @@ winMultiWindowWMProc (void *pArg) { /* Bail if PopMessage returns without a message */ /* NOTE: Remember that PopMessage is a blocking function. */ - ErrorF ("winMultiWindowWMProc - Queue is Empty?\n"); + ErrorF ("winMultiWindowWMProc - Queue is Empty? Exiting.\n"); pthread_exit (NULL); } @@ -553,9 +641,11 @@ winMultiWindowWMProc (void *pArg) #if CYGMULTIWINDOW_DEBUG ErrorF ("\tWM_WM_RAISE\n"); #endif - /* Raise the window */ XRaiseWindow (pWMInfo->pDisplay, pNode->msg.iWindow); +#if 0 + PreserveWin32Stack (pWMInfo, pNode->msg.iWindow, GW_HWNDPREV); +#endif break; case WM_WM_LOWER: @@ -582,6 +672,10 @@ winMultiWindowWMProc (void *pArg) 1); UpdateName (pWMInfo, pNode->msg.iWindow); winUpdateIcon (pNode->msg.iWindow); +#if 0 + /* Handles the case where there are AOT windows above it in W32 */ + PreserveWin32Stack (pWMInfo, pNode->msg.iWindow, GW_HWNDPREV); +#endif break; case WM_WM_UNMAP: @@ -652,7 +746,7 @@ winMultiWindowWMProc (void *pArg) break; default: - ErrorF ("winMultiWindowWMProc - Unknown Message.\n"); + ErrorF ("winMultiWindowWMProc - Unknown Message. Exiting.\n"); pthread_exit (NULL); break; } @@ -680,48 +774,7 @@ winMultiWindowWMProc (void *pArg) /* - * winMultiWindowWMErrorHandler - Our application specific error handler - */ - -static int -winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr) -{ - char pszErrorMsg[100]; - - if (pErr->request_code == X_ChangeWindowAttributes - && pErr->error_code == BadAccess) - { - ErrorF ("winMultiWindowWMErrorHandler - ChangeWindowAttributes " - "BadAccess.\n"); -#if 0 - pthread_exit (NULL); -#endif - return 0; - } - - XGetErrorText (pDisplay, - pErr->error_code, - pszErrorMsg, - sizeof (pszErrorMsg)); - ErrorF ("winMultiWindowWMErrorHandler - ERROR: %s\n", pszErrorMsg); - - if (pErr->error_code == BadWindow - || pErr->error_code == BadMatch - || pErr->error_code == BadDrawable) - { -#if 0 - pthread_exit (NULL); -#endif - return 0; - } - - pthread_exit (NULL); - return 0; -} - - -/* - * + * X message procedure */ static void * @@ -743,7 +796,7 @@ winMultiWindowXMsgProc (void *pArg) /* Check that argument pointer is not invalid */ if (pProcArg == NULL) { - ErrorF ("winMultiWindowXMsgProc - pProcArg is NULL, bailing.\n"); + ErrorF ("winMultiWindowXMsgProc - pProcArg is NULL. Exiting.\n"); pthread_exit (NULL); } @@ -753,27 +806,27 @@ winMultiWindowXMsgProc (void *pArg) iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted); if (iReturn != 0) { - ErrorF ("winMultiWindowXMsgProc - pthread_mutex_lock () failed: %d\n", + ErrorF ("winMultiWindowXMsgProc - pthread_mutex_lock () failed: %d. " + "Exiting.\n", iReturn); pthread_exit (NULL); } ErrorF ("winMultiWindowXMsgProc - pthread_mutex_lock () returned.\n"); - /* Only call XInitThreads once for the whole process */ - if (!g_fCalledXInitThreads) + /* Allow multiple threads to access Xlib */ + if (XInitThreads () == 0) { - /* Allow multiple threads to access Xlib */ - if (XInitThreads () == 0) - { - ErrorF ("winMultiWindowXMsgProc - XInitThreads () failed.\n"); - pthread_exit (NULL); - } - - /* Flag that XInitThreads has been called */ - g_fCalledXInitThreads = TRUE; + ErrorF ("winMultiWindowXMsgProc - XInitThreads () failed. Exiting.\n"); + pthread_exit (NULL); + } - ErrorF ("winMultiWindowXMsgProc - XInitThreads () returned.\n"); + /* See if X supports the current locale */ + if (XSupportsLocale () == False) + { + ErrorF ("winMultiWindowXMsgProc - Locale not supported by X. " + "Exiting.\n"); + pthread_exit (NULL); } /* Release the server started mutex */ @@ -781,6 +834,28 @@ winMultiWindowXMsgProc (void *pArg) ErrorF ("winMultiWindowXMsgProc - pthread_mutex_unlock () returned.\n"); + /* Set jump point for IO Error exits */ + iReturn = setjmp (g_jmpXMsgProcEntry); + + /* Check if we should continue operations */ + if (iReturn != WIN_JMP_ERROR_IO + && iReturn != WIN_JMP_OKAY) + { + /* setjmp returned an unknown value, exit */ + ErrorF ("winInitMultiWindowXMsgProc - setjmp returned: %d. Exiting.\n", + iReturn); + pthread_exit (NULL); + } + else if (iReturn == WIN_JMP_ERROR_IO) + { + ErrorF ("winInitMultiWindowXMsgProc - Caught IO Error. Exiting.\n"); + pthread_exit (NULL); + } + + /* Install our error handler */ + XSetErrorHandler (winMultiWindowXMsgProcErrorHandler); + XSetIOErrorHandler (winMultiWindowXMsgProcIOErrorHandler); + /* Setup the display connection string x */ snprintf (pszDisplay, 512, "127.0.0.1:%s.%d", display, (int)pProcArg->dwScreen); @@ -788,6 +863,7 @@ winMultiWindowXMsgProc (void *pArg) /* Print the display connection string */ ErrorF ("winMultiWindowXMsgProc - DISPLAY=%s\n", pszDisplay); + /* Initialize retry count */ iRetries = 0; /* Open the X display */ @@ -812,21 +888,28 @@ winMultiWindowXMsgProc (void *pArg) /* Make sure that the display opened */ if (pProcArg->pDisplay == NULL) { - ErrorF ("winMultiWindowXMsgProcwinInitMultiWindowWM - " - "Failed opening the display, giving up.\n\f"); + ErrorF ("winMultiWindowXMsgProc - Failed opening the display. " + "Exiting.\n"); pthread_exit (NULL); } ErrorF ("winMultiWindowXMsgProc - XOpenDisplay () returned and " "successfully opened the display.\n"); - - /* Install our error handler */ - XSetErrorHandler (winMultiWindowWMErrorHandler); - XSetIOErrorHandler (winMutliWindowWMIOErrorHandler); - XSelectInput (pProcArg->pDisplay, - RootWindow(pProcArg->pDisplay, pProcArg->dwScreen), - SubstructureNotifyMask); + /* Check if another window manager is already running */ + redirectError = FALSE; + XSetErrorHandler (winRedirectErrorHandler); + XSelectInput(pProcArg->pDisplay, + RootWindow (pProcArg->pDisplay, pProcArg->dwScreen), + SubstructureNotifyMask | ButtonPressMask); + XSync (pProcArg->pDisplay, 0); + XSetErrorHandler (winMultiWindowXMsgProcErrorHandler); + if (redirectError) + { + ErrorF ("winMultiWindowXMsgProc - " + "another window manager is running. Exiting.\n"); + pthread_exit (NULL); + } /* Set up the supported icon sizes */ xis = XAllocIconSize (); @@ -924,10 +1007,15 @@ winInitWM (void **ppWMInfo, /* Bail if the input parameters are bad */ if (pArg == NULL || pWMInfo == NULL) { - ErrorF ("winInitWM - malloc fail.\n"); + ErrorF ("winInitWM - malloc failed.\n"); return FALSE; } + /* Zero the allocated memory */ + ZeroMemory (pArg, sizeof (WMProcArgRec)); + ZeroMemory (pWMInfo, sizeof (WMInfoRec)); + ZeroMemory (pXMsgArg, sizeof (XMsgProcArgRec)); + /* Set a return pointer to the Window Manager info structure */ *ppWMInfo = pWMInfo; @@ -963,7 +1051,7 @@ winInitWM (void **ppWMInfo, } #if CYGDEBUG || YES - ErrorF ("winInitWM - Returning.\n"); + winDebug ("winInitWM - Returning.\n"); #endif return TRUE; @@ -971,26 +1059,22 @@ winInitWM (void **ppWMInfo, /* - * winInitMultiWindowWM - + * Window manager thread - setup */ -Bool -winClipboardDetectUnicodeSupport (); - static void winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg) { int iRetries = 0; char pszDisplay[512]; int iReturn; - Bool fUnicodeSupport; ErrorF ("winInitMultiWindowWM - Hello\n"); /* Check that argument pointer is not invalid */ if (pProcArg == NULL) { - ErrorF ("winInitMultiWindowWM - pProcArg is NULL, bailing.\n"); + ErrorF ("winInitMultiWindowWM - pProcArg is NULL. Exiting.\n"); pthread_exit (NULL); } @@ -1000,52 +1084,26 @@ winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg) iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted); if (iReturn != 0) { - ErrorF ("winInitMultiWindowWM - pthread_mutex_lock () failed: %d\n", + ErrorF ("winInitMultiWindowWM - pthread_mutex_lock () failed: %d. " + "Exiting.\n", iReturn); pthread_exit (NULL); } ErrorF ("winInitMultiWindowWM - pthread_mutex_lock () returned.\n"); - /* Do we have Unicode support? */ - fUnicodeSupport = winClipboardDetectUnicodeSupport (); - - /* Set the current locale? What does this do? */ - if (fUnicodeSupport && !g_fCalledSetLocale) + /* Allow multiple threads to access Xlib */ + if (XInitThreads () == 0) { - ErrorF ("winInitMultiWindowWM - Calling setlocale ()\n"); - if (!setlocale (LC_ALL, "")) - { - ErrorF ("winInitMultiWindowWM - setlocale () error\n"); - pthread_exit (NULL); - } - ErrorF ("winInitMultiWindowWM - setlocale () returned\n"); - - /* See if X supports the current locale */ - if (XSupportsLocale () == False) - { - ErrorF ("winInitMultiWindowWM - Locale not supported by X\n"); - pthread_exit (NULL); - } + ErrorF ("winInitMultiWindowWM - XInitThreads () failed. Exiting.\n"); + pthread_exit (NULL); } - /* Flag that we have called setlocale */ - g_fCalledSetLocale = TRUE; - - /* Only call XInitThreads once for the whole process */ - if (!g_fCalledXInitThreads) + /* See if X supports the current locale */ + if (XSupportsLocale () == False) { - /* Allow multiple threads to access Xlib */ - if (XInitThreads () == 0) - { - ErrorF ("winInitMultiWindowWM - XInitThreads () failed.\n"); - pthread_exit (NULL); - } - - /* Flag that XInitThreads has been called */ - g_fCalledXInitThreads = TRUE; - - ErrorF ("winInitMultiWindowWM - XInitThreads () returned.\n"); + ErrorF ("winInitMultiWindowWM - Locale not supported by X. Exiting.\n"); + pthread_exit (NULL); } /* Release the server started mutex */ @@ -1054,28 +1112,27 @@ winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg) ErrorF ("winInitMultiWindowWM - pthread_mutex_unlock () returned.\n"); /* Set jump point for IO Error exits */ - iReturn = setjmp (g_jmpEntry); + iReturn = setjmp (g_jmpWMEntry); /* Check if we should continue operations */ if (iReturn != WIN_JMP_ERROR_IO && iReturn != WIN_JMP_OKAY) { /* setjmp returned an unknown value, exit */ - ErrorF ("winInitMultiWindowWM - setjmp returned: %d exiting\n", + ErrorF ("winInitMultiWindowWM - setjmp returned: %d. Exiting.\n", iReturn); pthread_exit (NULL); } - else if (g_shutdown) - { - /* Shutting down, the X server severed out connection! */ - ErrorF ("winInitMultiWindowWM - Detected shutdown in progress\n"); - pthread_exit (NULL); - } else if (iReturn == WIN_JMP_ERROR_IO) { - ErrorF ("winInitMultiWindowWM - setjmp returned WIN_JMP_ERROR_IO\n"); + ErrorF ("winInitMultiWindowWM - Caught IO Error. Exiting.\n"); + pthread_exit (NULL); } + /* Install our error handler */ + XSetErrorHandler (winMultiWindowWMErrorHandler); + XSetIOErrorHandler (winMultiWindowWMIOErrorHandler); + /* Setup the display connection string x */ snprintf (pszDisplay, 512, @@ -1108,17 +1165,14 @@ winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg) /* Make sure that the display opened */ if (pWMInfo->pDisplay == NULL) { - ErrorF ("winInitMultiWindowWM - Failed opening the display, " - "giving up.\n\f"); + ErrorF ("winInitMultiWindowWM - Failed opening the display. " + "Exiting.\n"); pthread_exit (NULL); } ErrorF ("winInitMultiWindowWM - XOpenDisplay () returned and " "successfully opened the display.\n"); - /* Install our error handler */ - XSetErrorHandler (winMultiWindowWMErrorHandler); - XSetIOErrorHandler (winMutliWindowWMIOErrorHandler); /* Create some atoms */ pWMInfo->atmWmProtos = XInternAtom (pWMInfo->pDisplay, @@ -1156,22 +1210,96 @@ winSendMessageToWM (void *pWMInfo, winWMMessagePtr pMsg) /* - * winMutliWindowWMIOErrorHandler - Our application specific IO error handler + * Window manager error handler + */ + +static int +winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr) +{ + char pszErrorMsg[100]; + + if (pErr->request_code == X_ChangeWindowAttributes + && pErr->error_code == BadAccess) + { + ErrorF ("winMultiWindowWMErrorHandler - ChangeWindowAttributes " + "BadAccess.\n"); + return 0; + } + + XGetErrorText (pDisplay, + pErr->error_code, + pszErrorMsg, + sizeof (pszErrorMsg)); + ErrorF ("winMultiWindowWMErrorHandler - ERROR: %s\n", pszErrorMsg); + + return 0; +} + + +/* + * Window manager IO error handler */ static int -winMutliWindowWMIOErrorHandler (Display *pDisplay) +winMultiWindowWMIOErrorHandler (Display *pDisplay) { - printf ("\nwinMutliWindowWMIOErrorHandler!\n\n"); + ErrorF ("\nwinMultiWindowWMIOErrorHandler!\n\n"); /* Restart at the main entry point */ - longjmp (g_jmpEntry, WIN_JMP_ERROR_IO); + longjmp (g_jmpWMEntry, WIN_JMP_ERROR_IO); return 0; } /* + * X message procedure error handler + */ + +static int +winMultiWindowXMsgProcErrorHandler (Display *pDisplay, XErrorEvent *pErr) +{ + char pszErrorMsg[100]; + + XGetErrorText (pDisplay, + pErr->error_code, + pszErrorMsg, + sizeof (pszErrorMsg)); + ErrorF ("winMultiWindowXMsgProcErrorHandler - ERROR: %s\n", pszErrorMsg); + + return 0; +} + + +/* + * X message procedure IO error handler + */ + +static int +winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay) +{ + ErrorF ("\nwinMultiWindowXMsgProcIOErrorHandler!\n\n"); + + /* Restart at the main entry point */ + longjmp (g_jmpXMsgProcEntry, WIN_JMP_ERROR_IO); + + return 0; +} + + +/* + * Catch RedirectError to detect other window manager running + */ + +static int +winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr) +{ + redirectError = TRUE; + return 0; +} + + +/* * Notify the MWM thread we're exiting and not to reconnect */ |