winmsgwindow.c revision 35c4bbdf
1848b8605Smrg/* 2848b8605Smrg * Copyright (C) Jon TURNEY 2011 3848b8605Smrg * 4848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5848b8605Smrg * copy of this software and associated documentation files (the "Software"), 6848b8605Smrg * to deal in the Software without restriction, including without limitation 7848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 9848b8605Smrg * Software is furnished to do so, subject to the following conditions: 10848b8605Smrg * 11848b8605Smrg * The above copyright notice and this permission notice (including the next 12848b8605Smrg * paragraph) shall be included in all copies or substantial portions of the 13848b8605Smrg * Software. 14848b8605Smrg * 15848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19848b8605Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20848b8605Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21848b8605Smrg * DEALINGS IN THE SOFTWARE. 22848b8605Smrg * 23848b8605Smrg */ 24848b8605Smrg 25848b8605Smrg#ifdef HAVE_XWIN_CONFIG_H 26848b8605Smrg#include <xwin-config.h> 27848b8605Smrg#endif 28848b8605Smrg 29848b8605Smrg#include "win.h" 30848b8605Smrg 31b8e80941Smrg/* 32848b8605Smrg * This is the messaging window, a hidden top-level window. We never do anything 33848b8605Smrg * with it, but other programs may send messages to it. 34b8e80941Smrg */ 35848b8605Smrg 36848b8605Smrg/* 37848b8605Smrg * winMsgWindowProc - Window procedure for msg window 38848b8605Smrg */ 39848b8605Smrg 40848b8605Smrgstatic 41848b8605SmrgLRESULT CALLBACK 42848b8605SmrgwinMsgWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 43b8e80941Smrg{ 44848b8605Smrg#if CYGDEBUG 45b8e80941Smrg winDebugWin32Message("winMsgWindowProc", hwnd, message, wParam, lParam); 46b8e80941Smrg#endif 47b8e80941Smrg 48b8e80941Smrg switch (message) { 49b8e80941Smrg case WM_ENDSESSION: 50b8e80941Smrg if (!wParam) 51848b8605Smrg return 0; /* shutdown is being cancelled */ 52b8e80941Smrg 53848b8605Smrg /* 54848b8605Smrg Send a WM_GIVEUP message to the X server thread so it wakes up if 55848b8605Smrg blocked in select(), performs GiveUp(), and then notices that GiveUp() 56848b8605Smrg has set the DE_TERMINATE flag so exits the msg dispatch loop. 57848b8605Smrg */ 58848b8605Smrg { 59848b8605Smrg ScreenPtr pScreen = screenInfo.screens[0]; 60848b8605Smrg 61848b8605Smrg winScreenPriv(pScreen); 62848b8605Smrg PostMessage(pScreenPriv->hwndScreen, WM_GIVEUP, 0, 0); 63b8e80941Smrg } 64848b8605Smrg 65b8e80941Smrg /* 66b8e80941Smrg This process will be terminated by the system almost immediately 67b8e80941Smrg after the last thread with a message queue returns from processing 68b8e80941Smrg WM_ENDSESSION, so we cannot rely on any code executing after this 69b8e80941Smrg message is processed and need to wait here until ddxGiveUp() is called 70848b8605Smrg and releases the termination mutex to guarantee that the lock file and 71848b8605Smrg unix domain sockets have been removed 72b8e80941Smrg 73848b8605Smrg ofc, Microsoft doesn't document this under WM_ENDSESSION, you are supposed 74b8e80941Smrg to read the source of CRSS to find out how it works :-) 75b8e80941Smrg 76848b8605Smrg http://blogs.msdn.com/b/michen/archive/2008/04/04/application-termination-when-user-logs-off.aspx 77b8e80941Smrg */ 78b8e80941Smrg { 79848b8605Smrg int iReturn = pthread_mutex_lock(&g_pmTerminating); 80b8e80941Smrg 81b8e80941Smrg if (iReturn != 0) { 82b8e80941Smrg ErrorF("winMsgWindowProc - pthread_mutex_lock () failed: %d\n", 83b8e80941Smrg iReturn); 84b8e80941Smrg } 85b8e80941Smrg winDebug 86b8e80941Smrg ("winMsgWindowProc - WM_ENDSESSION termination lock acquired\n"); 87848b8605Smrg } 88b8e80941Smrg 89b8e80941Smrg return 0; 90b8e80941Smrg } 91b8e80941Smrg 92848b8605Smrg return DefWindowProc(hwnd, message, wParam, lParam); 93b8e80941Smrg} 94848b8605Smrg 95848b8605Smrgstatic HWND 96b8e80941SmrgwinCreateMsgWindow(void) 97848b8605Smrg{ 98848b8605Smrg HWND hwndMsg; 99848b8605Smrg 100848b8605Smrg // register window class 101848b8605Smrg { 102848b8605Smrg WNDCLASSEX wcx; 103848b8605Smrg 104848b8605Smrg wcx.cbSize = sizeof(WNDCLASSEX); 105b8e80941Smrg wcx.style = CS_HREDRAW | CS_VREDRAW; 106848b8605Smrg wcx.lpfnWndProc = winMsgWindowProc; 107b8e80941Smrg wcx.cbClsExtra = 0; 108b8e80941Smrg wcx.cbWndExtra = 0; 109b8e80941Smrg wcx.hInstance = g_hInstance; 110b8e80941Smrg wcx.hIcon = NULL; 111b8e80941Smrg wcx.hCursor = 0; 112b8e80941Smrg wcx.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); 113b8e80941Smrg wcx.lpszMenuName = NULL; 114b8e80941Smrg wcx.lpszClassName = WINDOW_CLASS_X_MSG; 115b8e80941Smrg wcx.hIconSm = NULL; 116b8e80941Smrg RegisterClassEx(&wcx); 117b8e80941Smrg } 118b8e80941Smrg 119b8e80941Smrg // Create the msg window. 120b8e80941Smrg hwndMsg = CreateWindowEx(0, // no extended styles 121b8e80941Smrg WINDOW_CLASS_X_MSG, // class name 122b8e80941Smrg "XWin Msg Window", // window name 123b8e80941Smrg WS_OVERLAPPEDWINDOW, // overlapped window 124b8e80941Smrg CW_USEDEFAULT, // default horizontal position 125b8e80941Smrg CW_USEDEFAULT, // default vertical position 126b8e80941Smrg CW_USEDEFAULT, // default width 127b8e80941Smrg CW_USEDEFAULT, // default height 128b8e80941Smrg (HWND) NULL, // no parent or owner window 129b8e80941Smrg (HMENU) NULL, // class menu used 130b8e80941Smrg GetModuleHandle(NULL), // instance handle 131848b8605Smrg NULL); // no window creation data 132b8e80941Smrg 133b8e80941Smrg if (!hwndMsg) { 134b8e80941Smrg ErrorF("winCreateMsgWindow - Create msg window failed\n"); 135b8e80941Smrg return NULL; 136b8e80941Smrg } 137b8e80941Smrg 138b8e80941Smrg winDebug("winCreateMsgWindow - Created msg window hwnd 0x%p\n", hwndMsg); 139b8e80941Smrg 140b8e80941Smrg return hwndMsg; 141b8e80941Smrg} 142b8e80941Smrg 143b8e80941Smrgstatic void * 144b8e80941SmrgwinMsgWindowThreadProc(void *arg) 145b8e80941Smrg{ 146b8e80941Smrg HWND hwndMsg; 147b8e80941Smrg 148b8e80941Smrg winDebug("winMsgWindowThreadProc - Hello\n"); 149b8e80941Smrg 150b8e80941Smrg hwndMsg = winCreateMsgWindow(); 151b8e80941Smrg if (hwndMsg) { 152848b8605Smrg MSG msg; 153848b8605Smrg 154b8e80941Smrg /* Pump the msg window message queue */ 155b8e80941Smrg while (GetMessage(&msg, hwndMsg, 0, 0) > 0) { 156b8e80941Smrg#if CYGDEBUG 157b8e80941Smrg winDebugWin32Message("winMsgWindowThread", msg.hwnd, msg.message, 158b8e80941Smrg msg.wParam, msg.lParam); 159b8e80941Smrg#endif 160b8e80941Smrg DispatchMessage(&msg); 161b8e80941Smrg } 162848b8605Smrg } 163848b8605Smrg 164848b8605Smrg winDebug("winMsgWindowThreadProc - Exit\n"); 165848b8605Smrg 166848b8605Smrg return NULL; 167848b8605Smrg} 168848b8605Smrg 169848b8605SmrgBool 170848b8605SmrgwinCreateMsgWindowThread(void) 171848b8605Smrg{ 172848b8605Smrg pthread_t ptMsgWindowThreadProc; 173848b8605Smrg 174848b8605Smrg /* Spawn a thread for the msg window */ 175848b8605Smrg if (pthread_create(&ptMsgWindowThreadProc, 176848b8605Smrg NULL, winMsgWindowThreadProc, NULL)) { 177b8e80941Smrg /* Bail if thread creation failed */ 178848b8605Smrg ErrorF("winCreateMsgWindow - pthread_create failed.\n"); 179848b8605Smrg return FALSE; 180848b8605Smrg } 181848b8605Smrg 182848b8605Smrg return TRUE; 183848b8605Smrg} 184848b8605Smrg