diff options
Diffstat (limited to 'xwinclip.c')
-rw-r--r-- | xwinclip.c | 589 |
1 files changed, 299 insertions, 290 deletions
@@ -1,5 +1,7 @@ /* *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. + *Copyright (C) Colin Harrison 2005-2008 * *Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -15,126 +17,121 @@ *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - *Except as contained in this notice, the name of the XFree86 Project - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from the XFree86 Project. + *Except as contained in this notice, the name of the copyright holder(s) + *and author(s) shall not be used in advertising or otherwise to promote + *the sale, use or other dealings in this Software without prior written + *authorization from the copyright holder(s) and author(s). * * Authors: Harold L Hunt II + * Colin Harrison */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif /* Standard library headers */ #include <assert.h> #include <stdio.h> #include <stdlib.h> -#include <signal.h> +#include <fcntl.h> +#include <sys/param.h> +#include <unistd.h> +#ifndef HAS_WINSOCK #include <errno.h> +#endif +#include <setjmp.h> +#include <pthread.h> /* X headers */ #include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/Xos.h> #include <X11/Xatom.h> -#include <X11/keysym.h> #ifdef X_LOCALE #include <X11/Xlocale.h> #else /* X_LOCALE */ #include <locale.h> #endif /* X_LOCALE */ - - -/* Fixups to prevent collisions between Windows and X headers */ -#undef MINSHORT -#undef MAXSHORT - -/* Flags for Windows header options */ -#define NONAMELESSUNION -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif +#include <X11/extensions/Xfixes.h> /* Windows headers */ -#include <windows.h> -#include <windowsx.h> +#include <X11/Xwindows.h> -/* Other headers */ -#include <setjmp.h> +/* Local headers */ +#include "textconv.h" +#include "wndproc.h" +#include "xevents.h" +#include "debug.h" /* Application constants */ #define WINDOW_CLASS "xwinclip" #define WINDOW_TITLE "xwinclip" #define WIN_MSG_QUEUE_FNAME "/dev/windows" -#define WIN_USE_SELECT 1 + #define WIN_CONNECT_RETRIES 3 #define WIN_CONNECT_DELAY 4 -#define WIN_JMP_OKAY 0 -#define WIN_JMP_ERROR_IO 2 +/* + * Local variables + */ -/* Local headers */ -#include "textconv.h" -#include "wndproc.h" -#include "xevents.h" - +static jmp_buf g_jmpEntry; +static XIOErrorHandler g_ClipboardOldIOErrorHandler; +static pthread_t g_ClipboardProcThread; /* * Global variables */ -jmp_buf g_jmpEntry; -Bool g_fUnicodeClipboard = TRUE; - +int xfixes_event_base; +int xfixes_error_base; /* - * Function prototypes + * Local function prototypes */ -HWND -CreateMessagingWindow (); - -Bool -UnicodeSupport (); +static HWND +CreateMessagingWindow (Display *display, Window window); +void +ClipboardProc(Bool fUnicodeSupport, char *pszDisplay); /* - * Local functions + * ClipboardErrorHandler - Our application specific error handler */ - -#if 0 -void -handle_kill (int i) +static int +ClipboardErrorHandler(Display *pDisplay, XErrorEvent *pErr) { - printf ("\nhandle_kill!\n\n"); -} + char pszErrorMsg[100]; -int -error_handler (Display *pDisplay, XErrorEvent *pErrorEvent) -{ - printf ("\nerror_handler!\n\n"); + XGetErrorText(pDisplay, pErr->error_code, pszErrorMsg, sizeof(pszErrorMsg)); + winError("ClipboardErrorHandler - ERROR: %s Serial: %lu, Request Code: %d, Minor Code: %d\n", + pszErrorMsg, pErr->serial, pErr->request_code, pErr->minor_code); return 0; } -#endif -int -error_handler_io (Display *pDisplay) +/* + * ClipboardIOErrorHandler - Our application specific IO error handler + */ +static int +ClipboardIOErrorHandler(Display *pDisplay) { - printf ("\nerror_handler_io!\n\n"); - - /* Restart at the main entry point */ - longjmp (g_jmpEntry, WIN_JMP_ERROR_IO); - - return 0; -} + winError("ClipboardIOErrorHandler!\n"); + if (pthread_equal(pthread_self(), g_ClipboardProcThread)) { + /* Restart at the main entry point */ + longjmp(g_jmpEntry, 2); + } -Atom atomClipboard, atomClipboardManager; + if (g_ClipboardOldIOErrorHandler) + g_ClipboardOldIOErrorHandler(pDisplay); + return 0; +} /* * Main function @@ -143,25 +140,9 @@ Atom atomClipboard, atomClipboardManager; int main (int argc, char *argv[]) { -#if 0 - Atom atomClipboard, atomClipboardManager; -#endif - Atom atomLocalProperty, atomCompoundText; - Atom atomUTF8String, atomTargets; - int iReturn; - HWND hwnd = NULL; - int iConnectionNumber; - int fdMessageQueue; - fd_set fdsRead; - int iMaxDescriptor; - Display *pDisplay; - Window iWindow; - Atom atomDeleteWindow; - Bool fReturn; - int iRetries; - Bool fUnicodeSupport; - char *pszDisplay = NULL; int i; + char *pszDisplay = NULL; + Bool fUnicodeClipboard = TRUE; /* Parse command-line parameters */ for (i = 1; i < argc; ++i) @@ -178,76 +159,92 @@ main (int argc, char *argv[]) i++; continue; } + /* Look for -nounicodeclipboard */ if (!strcmp (argv[i], "-nounicodeclipboard")) { - g_fUnicodeClipboard = FALSE; + fUnicodeClipboard = FALSE; continue; } - + /* Yack when we find a parameter that we don't know about */ printf ("Unknown parameter: %s\nExiting.\n", argv[i]); exit (1); } - /* Set jump point for IO Error exits */ - iReturn = setjmp (g_jmpEntry); - - /* Check if we should continue operations */ - if (iReturn != WIN_JMP_ERROR_IO - && iReturn != WIN_JMP_OKAY) + /* Do we have Unicode support? */ + if (fUnicodeClipboard) { - /* setjmp returned an unknown value, exit */ - printf ("setjmp returned: %d exiting\n", - iReturn); - exit (1); + printf ("Unicode clipboard I/O\n"); } - else if (iReturn == WIN_JMP_ERROR_IO) + else { - printf ("setjmp returned and hwnd: %08x\n", (unsigned int)hwnd); + printf ("Non Unicode clipboard I/O\n"); } - /* Initialize retry count */ - iRetries = 0; - - /* Do we have Unicode support? */ - fUnicodeSupport = g_fUnicodeClipboard && UnicodeSupport (); - if (fUnicodeSupport) + /* Set the current locale? What does this do? */ + if (!setlocale (LC_ALL, "")) { - printf ("Unicode clipboard I/O\n"); + printf ("setlocale() error\n"); + exit (1); } - else + + /* See if X supports the current locale */ + if (XSupportsLocale () == False) { - printf ("Non Unicode clipboard I/O\n"); + printf ("Locale not supported by X\n"); + exit (1); } -#if 0 - /* Specify our signal handlers */ - signal (SIGQUIT, handle_kill); + ClipboardProc(fUnicodeClipboard, pszDisplay); + + return 0; +} + +void +ClipboardProc(Bool fUnicodeSupport, char *pszDisplay) +{ + Atom atomLocalProperty, atomCompoundText; + Atom atomUTF8String, atomTargets; + Atom atomClipboard; + int iReturn; + HWND hwnd = NULL; + int iConnectionNumber = 0; +#ifdef HAS_DEVWINDOWS + int fdMessageQueue = 0; +#else + struct timeval tvTimeout; #endif + fd_set fdsRead; + int iMaxDescriptor; + Display *pDisplay = NULL; + Window iWindow = None; + int iRetries; + int iSelectError; + + /* Initialize retry count */ + iRetries = 0; + + /* Set error handler */ + XSetErrorHandler(ClipboardErrorHandler); + g_ClipboardProcThread = pthread_self(); + g_ClipboardOldIOErrorHandler = XSetIOErrorHandler(ClipboardIOErrorHandler); + + /* Set jump point for error exits */ + if (setjmp(g_jmpEntry)) { + winError("ClipboardProc - setjmp returned for IO Error Handler.\n"); + /* Cleanup and exit */ + goto ClipboardProc_Done; + } - /* Set the current locale? What does this do? */ - if (!setlocale (LC_ALL, "")) - { - printf ("setlocale() error\n"); - exit (1); - } - - /* See if X supports the current locale */ - if (XSupportsLocale () == False) - { - printf ("Locale not supported by X\n"); - exit (1); - } - /* Open the X display */ do { pDisplay = XOpenDisplay (pszDisplay); if (pDisplay == NULL) { - printf ("Could not open display, try: %d, sleeping: %d\n", - iRetries + 1, WIN_CONNECT_DELAY); + winError ("Could not open display, try: %d, sleeping: %d\n", + iRetries + 1, WIN_CONNECT_DELAY); ++iRetries; sleep (WIN_CONNECT_DELAY); continue; @@ -260,34 +257,29 @@ main (int argc, char *argv[]) /* Make sure that the display opened */ if (pDisplay == NULL) { - printf ("Failed opening the display, giving up\n"); - return 1; + winError ("Failed opening the display, giving up\n"); + return; } - /* Create Windows messaging window */ - hwnd = CreateMessagingWindow (); - /* Get our connection number */ iConnectionNumber = ConnectionNumber (pDisplay); +#ifdef HAS_DEVWINDOWS /* Open a file descriptor for the windows message queue */ - fdMessageQueue = open (WIN_MSG_QUEUE_FNAME, O_RDONLY); - if (fdMessageQueue == -1) - { - printf ("Failed opening %s\n", WIN_MSG_QUEUE_FNAME); - exit (1); - } + fdMessageQueue = open(WIN_MSG_QUEUE_FNAME, O_RDONLY); + if (fdMessageQueue == -1) { + winError ("Failed opening %s\n", WIN_MSG_QUEUE_FNAME); + exit (1); + } /* Find max of our file descriptors */ - iMaxDescriptor = max (fdMessageQueue, iConnectionNumber) + 1; + iMaxDescriptor = MAX(fdMessageQueue, iConnectionNumber) + 1; +#else + iMaxDescriptor = iConnectionNumber + 1; +#endif - /* Select event types to watch */ - if (XSelectInput (pDisplay, - DefaultRootWindow (pDisplay), - SubstructureNotifyMask | - StructureNotifyMask | - PropertyChangeMask) == BadWindow) - printf ("XSelectInput generated BadWindow on RootWindow\n\n"); + if (!XFixesQueryExtension(pDisplay, &xfixes_event_base, &xfixes_error_base)) + winError ("XFixes extension not present\n"); /* Create a messaging window */ iWindow = XCreateSimpleWindow (pDisplay, @@ -299,91 +291,70 @@ main (int argc, char *argv[]) BlackPixel (pDisplay, 0)); if (iWindow == 0) { - printf ("Could not create a window\n"); + winError ("Could not create an X window\n"); exit (1); } -#if 0 /* Print out our window number */ - printf ("Window number: %d\n", iWindow); -#endif + winDebug("Window number: 0x%x\n", iWindow); -#if 0 - /* Display the messaging window, as a test */ - XMapWindow (pDisplay, iWindow); -#endif - - /* ChangeWindowAttributes can change own window's event mask */ -#if 0 - attrib.event_mask = StructureNotifyMask; - iReturn = XChangeWindowAttributes (pDisplay, iWindow, CWEventMask, &attrib); - if (iReturn == BadWindow) - printf ("XChangeWindowAttributes gave BadWindow\n"); - else if (iReturn == BadAccess) - printf ("XChangeWindowAttributes gave BadAccess\n"); - else if (iReturn == BadValue) - printf ("XChangeWindowAttributes gave BadValue\n"); -#endif - - /* This looks like our only hope for getting a message before shutdown */ - /* Register for WM_DELETE_WINDOW message from window manager */ - atomDeleteWindow = XInternAtom (pDisplay, "WM_DELETE_WINDOW", False); - XSetWMProtocols (pDisplay, iWindow, &atomDeleteWindow, 1); - - /* Set error handler */ -#if 0 - XSetErrorHandler (error_handler); -#endif - XSetIOErrorHandler (error_handler_io); + XStoreName(pDisplay, iWindow, "xwinclip"); - /* Create an atom for CLIPBOARD_MANAGER */ - atomClipboardManager = XInternAtom (pDisplay, "CLIPBOARD_MANAGER", False); - if (atomClipboardManager == None) - { - printf ("Could not create CLIPBOARD_MANAGER atom\n"); - exit (1); - } + /* Select event types to watch */ + if (XSelectInput(pDisplay, iWindow, PropertyChangeMask) == BadWindow) + winError("XSelectInput generated BadWindow on messaging window\n"); + + XFixesSelectSelectionInput (pDisplay, + iWindow, + XA_PRIMARY, + XFixesSetSelectionOwnerNotifyMask | + XFixesSelectionWindowDestroyNotifyMask | + XFixesSelectionClientCloseNotifyMask); + + XFixesSelectSelectionInput (pDisplay, + iWindow, + XInternAtom (pDisplay, "CLIPBOARD", False), + XFixesSetSelectionOwnerNotifyMask | + XFixesSelectionWindowDestroyNotifyMask | + XFixesSelectionClientCloseNotifyMask); - /* Assert ownership of CLIPBOARD_MANAGER */ - iReturn = XSetSelectionOwner (pDisplay, atomClipboardManager, - iWindow, CurrentTime); - if (iReturn == BadAtom || iReturn == BadWindow) - { - printf ("Could not set CLIPBOARD_MANAGER owner\n"); - exit (1); - } + /* Create Windows messaging window */ + hwnd = CreateMessagingWindow (pDisplay, iWindow); /* Create an atom for CLIPBOARD */ atomClipboard = XInternAtom (pDisplay, "CLIPBOARD", False); if (atomClipboard == None) { - printf ("Could not create CLIPBOARD atom\n"); + winError ("Could not create CLIPBOARD atom\n"); exit (1); } - /* Assert ownership of CLIPBOARD */ - iReturn = XSetSelectionOwner (pDisplay, atomClipboard, - iWindow, CurrentTime); - if (iReturn == BadAtom || iReturn == BadWindow) - { - printf ("Could not set CLIPBOARD owner\n"); + /* Assert ownership of selections if Win32 clipboard is owned */ + if (NULL != GetClipboardOwner()) { + /* PRIMARY */ + iReturn = XSetSelectionOwner(pDisplay, XA_PRIMARY, + iWindow, CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow || + XGetSelectionOwner(pDisplay, XA_PRIMARY) != iWindow) { + winError("Could not set PRIMARY owner\n"); exit (1); } - /* Assert ownership of PRIMARY */ - iReturn = XSetSelectionOwner (pDisplay, XA_PRIMARY, - iWindow, CurrentTime); - if (iReturn == BadAtom || iReturn == BadWindow) - { - printf ("Could not set PRIMARY owner\n"); + /* CLIPBOARD */ + iReturn = XSetSelectionOwner(pDisplay, atomClipboard, + iWindow, CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow || + XGetSelectionOwner(pDisplay, atomClipboard) != iWindow) { + winError("Could not set CLIPBOARD owner\n"); exit (1); } + } - /* Local property to hold pasted data */ + /* Create an atom for Local property to hold pasted data */ atomLocalProperty = XInternAtom (pDisplay, "CYGX_CUT_BUFFER", False); if (atomLocalProperty == None) { - printf ("Could not create CYGX_CUT_BUFFER atom\n"); + winError ("Could not create CYGX_CUT_BUFFER atom\n"); exit (1); } @@ -391,7 +362,7 @@ main (int argc, char *argv[]) atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False); if (atomUTF8String == None) { - printf ("Could not create UTF8_STRING atom\n"); + winError ("Could not create UTF8_STRING atom\n"); exit (1); } @@ -399,7 +370,7 @@ main (int argc, char *argv[]) atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False); if (atomCompoundText == None) { - printf ("Could not create COMPOUND_TEXT atom\n"); + winError ("Could not create COMPOUND_TEXT atom\n"); exit (1); } @@ -407,24 +378,27 @@ main (int argc, char *argv[]) atomTargets = XInternAtom (pDisplay, "TARGETS", False); if (atomTargets == None) { - printf ("Could not create TARGETS atom\n"); + winError ("Could not create TARGETS atom\n"); exit (1); } /* Pre-flush X events */ - /* + /* * NOTE: Apparently you'll freeze if you don't do this, * because there may be events in local data structures * already. */ FlushXEvents (hwnd, atomLocalProperty, atomUTF8String, - atomCompoundText, atomTargets, atomDeleteWindow, + atomCompoundText, atomTargets, iWindow, pDisplay, fUnicodeSupport); /* Pre-flush Windows messages */ if (!FlushWindowsMessageQueue (hwnd)) - return 0; + { + winError("ClipboardFlushWindowsMessageQueue failed\n"); + return; + } /* Loop for X events */ while (1) @@ -436,143 +410,178 @@ main (int argc, char *argv[]) * which descriptors are ready. */ FD_ZERO (&fdsRead); - FD_SET (fdMessageQueue, &fdsRead); FD_SET (iConnectionNumber, &fdsRead); +#ifdef HAS_DEVWINDOWS + FD_SET (fdMessageQueue, &fdsRead); +#else + tvTimeout.tv_sec = 0; + tvTimeout.tv_usec = 100; +#endif /* Wait for a Windows event or an X event */ iReturn = select (iMaxDescriptor, /* Highest fds number */ &fdsRead, /* Read mask */ NULL, /* No write mask */ NULL, /* No exception mask */ - NULL); /* No timeout */ +#ifdef HAS_DEVWINDOWS + NULL /* No timeout */ +#else + &tvTimeout /* Set timeout */ +#endif + ); + +#ifndef HAS_WINSOCK + iSelectError = errno; +#else + iSelectError = WSAGetLastError(); +#endif + if (iReturn <= 0) { - printf ("Call to select () failed: %d. Bailing.\n", iReturn); +#ifndef HAS_WINSOCK + if (iSelectError == EINTR) +#else + if (iSelectError == WSAEINTR) +#endif + continue; + + winError ("Call to select () failed: %d. Bailing.\n", iReturn); break; } - + + winDebug("select returned %d\n", iReturn); + /* Branch on which descriptor became active */ if (FD_ISSET (iConnectionNumber, &fdsRead)) { /* X event ready */ -#if 0 - printf ("X event ready\n"); -#endif + winDebug("X connection ready, pumping X event queue\n"); /* Process X events */ /* Exit when we see that server is shutting down */ - fReturn = FlushXEvents (hwnd, + iReturn = FlushXEvents (hwnd, atomLocalProperty, atomUTF8String, atomCompoundText, atomTargets, - atomDeleteWindow, iWindow, pDisplay, fUnicodeSupport); - if (!fReturn) - { - printf ("Caught WM_DELETE_WINDOW - shutting down\n"); + + if (WIN_XEVENTS_SHUTDOWN == iReturn) + { + winError ("Trapped shutdown event, exiting main loop.\n"); break; } } +#ifdef HAS_DEVWINDOWS /* Check for Windows event ready */ if (FD_ISSET (fdMessageQueue, &fdsRead)) - { - /* Windows event ready */ -#if 0 - printf ("Windows event ready\n"); +#else + if (1) +#endif + { + /* Windows event ready */ + winDebug ("/dev/windows ready, pumping Windows message queue\n"); + + /* Process Windows messages */ + if (!FlushWindowsMessageQueue (hwnd)) + { + winError("FlushWindowsMessageQueue trapped WM_QUIT message, exiting main loop.\n"); + break; + } + } + +#ifdef HAS_DEVWINDOWS + if (!(FD_ISSET(iConnectionNumber, &fdsRead)) && + !(FD_ISSET(fdMessageQueue, &fdsRead))) { + winDebug("Spurious wake\n"); + } #endif - - /* Process Windows messages */ - if (!FlushWindowsMessageQueue (hwnd)) - break; - } } - return 0; -} +ClipboardProc_Done: + /* Close our Windows window */ + if (hwnd) { + /* Destroy the Window window (hwnd) */ + winDebug("Destroy Windows window\n"); + PostMessage(hwnd, WM_DESTROY, 0, 0); + FlushWindowsMessageQueue(hwnd); + } + + /* Close our X window */ + if (pDisplay && iWindow) { + iReturn = XDestroyWindow(pDisplay, iWindow); + if (iReturn == BadWindow) + winError("XDestroyWindow returned BadWindow.\n"); + else + winError("XDestroyWindow succeeded.\n"); + } + +#ifdef HAS_DEVWINDOWS + /* Close our Win32 message handle */ + if (fdMessageQueue) + close(fdMessageQueue); +#endif + + /* Close our X display */ + if (pDisplay) { + XCloseDisplay(pDisplay); + } + + // XXX: should return a value to indicate if this is a shutdown exit or error... +} /* * Create the Windows window that we use to recieve Windows messages */ -HWND -CreateMessagingWindow () +static HWND +CreateMessagingWindow (Display *display, Window window) { - WNDCLASS wc; - HWND hwnd; + WNDCLASSEX wc; + HWND hwnd; /* Setup our window class */ + wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; - wc.hInstance = GetModuleHandle (NULL); + wc.hInstance = GetModuleHandle(NULL); wc.hIcon = 0; wc.hCursor = 0; - wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); + wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = WINDOW_CLASS; - RegisterClass (&wc); + wc.hIconSm = 0; + RegisterClassEx(&wc); + + WindowCreationParams wcp; + wcp.pClipboardDisplay = display; + wcp.iClipboardWindow = window; /* Create the window */ - hwnd = CreateWindowExA (0, /* Extended styles */ - WINDOW_CLASS, /* Class name */ - WINDOW_TITLE, /* Window name */ - WS_OVERLAPPED, /* Not visible anyway */ - CW_USEDEFAULT, /* Horizontal position */ - CW_USEDEFAULT, /* Vertical position */ - CW_USEDEFAULT, /* Right edge */ - CW_USEDEFAULT, /* Bottom edge */ - (HWND) NULL, /* No parent or owner window */ - (HMENU) NULL, /* No menu */ - GetModuleHandle (NULL),/* Instance handle */ - NULL); /* ScreenPrivates */ - assert (hwnd != NULL); + hwnd = CreateWindowExA(0, /* Extended styles */ + WINDOW_CLASS, /* Class name */ + WINDOW_TITLE, /* Window name */ + WS_OVERLAPPED, /* Not visible anyway */ + CW_USEDEFAULT, /* Horizontal position */ + CW_USEDEFAULT, /* Vertical position */ + CW_USEDEFAULT, /* Right edge */ + CW_USEDEFAULT, /* Bottom edge */ + (HWND) NULL, /* No parent or owner window */ + (HMENU) NULL, /* No menu */ + GetModuleHandle(NULL), /* Instance handle */ + &wcp); /* Creation data */ + assert(hwnd != NULL); /* I'm not sure, but we may need to call this to start message processing */ - ShowWindow (hwnd, SW_HIDE); + ShowWindow(hwnd, SW_HIDE); /* Similarly, we may need a call to this even though we don't paint */ - UpdateWindow (hwnd); + UpdateWindow(hwnd); return hwnd; } - - -/* - * Determine whether we suport Unicode or not. - * NOTE: Currently, just check if we are on an NT-based platform or not. - */ - -Bool -UnicodeSupport () -{ - Bool fReturn = FALSE; - OSVERSIONINFO osvi; - - /* Get operating system version information */ - ZeroMemory (&osvi, sizeof (osvi)); - osvi.dwOSVersionInfoSize = sizeof (osvi); - GetVersionEx (&osvi); - - /* Branch on platform ID */ - switch (osvi.dwPlatformId) - { - case VER_PLATFORM_WIN32_NT: - /* Engine 4 is supported on NT only */ - printf ("UnicodeSupport - Windows NT/2000/XP\n"); - fReturn = TRUE; - break; - - case VER_PLATFORM_WIN32_WINDOWS: - /* Engine 4 is supported on NT only */ - printf ("UnicodeSupport - Windows 95/98/Me\n"); - fReturn = FALSE; - break; - } - - return fReturn; -} |