From 9508a382f8a9f241dab097d921b6d290c1c3a776 Mon Sep 17 00:00:00 2001 From: Kaleb Keithley Date: Fri, 14 Nov 2003 16:48:57 +0000 Subject: Initial revision --- hw/xwin/InitInput.c | 148 +++ hw/xwin/InitOutput.c | 1261 ++++++++++++++++++++++++ hw/xwin/X.ico | Bin 0 -> 4710 bytes hw/xwin/XWin.man | 129 +++ hw/xwin/XWin.rc | 60 ++ hw/xwin/ddraw.h | 2094 ++++++++++++++++++++++++++++++++++++++++ hw/xwin/win.h | 1427 +++++++++++++++++++++++++++ hw/xwin/winallpriv.c | 181 ++++ hw/xwin/winblock.c | 76 ++ hw/xwin/winclip.c | 40 + hw/xwin/winclipboard.h | 158 +++ hw/xwin/winclipboardinit.c | 117 +++ hw/xwin/winclipboardtextconv.c | 153 +++ hw/xwin/winclipboardthread.c | 463 +++++++++ hw/xwin/winclipboardunicode.c | 68 ++ hw/xwin/winclipboardwndproc.c | 86 ++ hw/xwin/winclipboardxevents.c | 722 ++++++++++++++ hw/xwin/wincmap.c | 631 ++++++++++++ hw/xwin/winconfig.c | 949 ++++++++++++++++++ hw/xwin/winconfig.h | 332 +++++++ hw/xwin/wincreatewnd.c | 541 +++++++++++ hw/xwin/wincursor.c | 84 ++ hw/xwin/winengine.c | 309 ++++++ hw/xwin/winerror.c | 73 ++ hw/xwin/winfillsp.c | 537 +++++++++++ hw/xwin/winfont.c | 50 + hw/xwin/wingc.c | 418 ++++++++ hw/xwin/wingetsp.c | 164 ++++ hw/xwin/winkeybd.c | 707 ++++++++++++++ hw/xwin/winkeybd.h | 398 ++++++++ hw/xwin/winmisc.c | 147 +++ hw/xwin/winmouse.c | 295 ++++++ hw/xwin/winms.h | 61 ++ hw/xwin/winmsg.c | 119 +++ hw/xwin/winmsg.h | 72 ++ hw/xwin/winmultiwindowwindow.c | 1574 ++++++++++++++++++++++++++++++ hw/xwin/winmultiwindowwm.c | 907 +++++++++++++++++ hw/xwin/winnativegdi.c | 454 +++++++++ hw/xwin/winpfbdd.c | 636 ++++++++++++ hw/xwin/winpixmap.c | 206 ++++ hw/xwin/winpntwin.c | 45 + hw/xwin/winpolyline.c | 43 + hw/xwin/winregistry.c | 66 ++ hw/xwin/winscrinit.c | 739 ++++++++++++++ hw/xwin/winsetsp.c | 344 +++++++ hw/xwin/winshaddd.c | 1362 ++++++++++++++++++++++++++ hw/xwin/winshadddnl.c | 1288 ++++++++++++++++++++++++ hw/xwin/winshadgdi.c | 1158 ++++++++++++++++++++++ hw/xwin/winwakeup.c | 57 ++ hw/xwin/winwindow.c | 463 +++++++++ hw/xwin/winwindow.h | 118 +++ hw/xwin/winwndproc.c | 1131 ++++++++++++++++++++++ 52 files changed, 23661 insertions(+) create mode 100644 hw/xwin/InitInput.c create mode 100644 hw/xwin/InitOutput.c create mode 100644 hw/xwin/X.ico create mode 100644 hw/xwin/XWin.man create mode 100644 hw/xwin/XWin.rc create mode 100644 hw/xwin/ddraw.h create mode 100644 hw/xwin/win.h create mode 100644 hw/xwin/winallpriv.c create mode 100644 hw/xwin/winblock.c create mode 100644 hw/xwin/winclip.c create mode 100644 hw/xwin/winclipboard.h create mode 100644 hw/xwin/winclipboardinit.c create mode 100644 hw/xwin/winclipboardtextconv.c create mode 100644 hw/xwin/winclipboardthread.c create mode 100644 hw/xwin/winclipboardunicode.c create mode 100644 hw/xwin/winclipboardwndproc.c create mode 100644 hw/xwin/winclipboardxevents.c create mode 100644 hw/xwin/wincmap.c create mode 100644 hw/xwin/winconfig.c create mode 100644 hw/xwin/winconfig.h create mode 100644 hw/xwin/wincreatewnd.c create mode 100644 hw/xwin/wincursor.c create mode 100644 hw/xwin/winengine.c create mode 100644 hw/xwin/winerror.c create mode 100644 hw/xwin/winfillsp.c create mode 100644 hw/xwin/winfont.c create mode 100644 hw/xwin/wingc.c create mode 100644 hw/xwin/wingetsp.c create mode 100644 hw/xwin/winkeybd.c create mode 100644 hw/xwin/winkeybd.h create mode 100644 hw/xwin/winmisc.c create mode 100644 hw/xwin/winmouse.c create mode 100644 hw/xwin/winms.h create mode 100644 hw/xwin/winmsg.c create mode 100644 hw/xwin/winmsg.h create mode 100644 hw/xwin/winmultiwindowwindow.c create mode 100644 hw/xwin/winmultiwindowwm.c create mode 100644 hw/xwin/winnativegdi.c create mode 100644 hw/xwin/winpfbdd.c create mode 100644 hw/xwin/winpixmap.c create mode 100644 hw/xwin/winpntwin.c create mode 100644 hw/xwin/winpolyline.c create mode 100644 hw/xwin/winregistry.c create mode 100644 hw/xwin/winscrinit.c create mode 100644 hw/xwin/winsetsp.c create mode 100644 hw/xwin/winshaddd.c create mode 100644 hw/xwin/winshadddnl.c create mode 100644 hw/xwin/winshadgdi.c create mode 100644 hw/xwin/winwakeup.c create mode 100644 hw/xwin/winwindow.c create mode 100644 hw/xwin/winwindow.h create mode 100644 hw/xwin/winwndproc.c (limited to 'hw/xwin') diff --git a/hw/xwin/InitInput.c b/hw/xwin/InitInput.c new file mode 100644 index 000000000..a9f69aad5 --- /dev/null +++ b/hw/xwin/InitInput.c @@ -0,0 +1,148 @@ +/* $TOG: InitInput.c /main/12 1998/02/10 13:23:52 kaleb $ */ +/* + + Copyright 1993, 1998 The Open Group + + Permission to use, copy, modify, distribute, and sell this software and its + documentation for any purpose is hereby granted without fee, provided that + the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation. + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + 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 OPEN GROUP 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 Open Group 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 Open Group. + +*/ +/* $XFree86: xc/programs/Xserver/hw/xwin/InitInput.c,v 1.12 2003/02/12 15:01:38 alanh Exp $ */ + +#include "win.h" + +CARD32 g_c32LastInputEventTime = 0; + + +/* Called from dix/devices.c */ +/* + * All of our keys generate up and down transition notifications, + * so all of our keys can be used as modifiers. + * + * An example of a modifier is mapping the A key to the Control key. + * A has to be a legal modifier. I think. + */ + +Bool +LegalModifier (unsigned int uiKey, DevicePtr pDevice) +{ + return TRUE; +} + + +/* Called from dix/dispatch.c */ +/* + * Run through the Windows message queue(s) one more time. + * Tell mi to dequeue the events that we have sent it. + */ +void +ProcessInputEvents (void) +{ +#if 0 + ErrorF ("ProcessInputEvents\n"); +#endif + + mieqProcessInputEvents (); + miPointerUpdate (); + +#if 0 + ErrorF ("ProcessInputEvents - returning\n"); +#endif +} + + +int +TimeSinceLastInputEvent () +{ + if (g_c32LastInputEventTime == 0) + g_c32LastInputEventTime = GetTickCount (); + return GetTickCount () - g_c32LastInputEventTime; +} + + +/* See Porting Layer Definition - p. 17 */ +void +InitInput (int argc, char *argv[]) +{ + DeviceIntPtr pMouse, pKeyboard; + +#if CYGDEBUG + ErrorF ("InitInput\n"); +#endif + + pMouse = AddInputDevice (winMouseProc, TRUE); + pKeyboard = AddInputDevice (winKeybdProc, TRUE); + + RegisterPointerDevice (pMouse); + RegisterKeyboardDevice (pKeyboard); + + miRegisterPointerDevice (screenInfo.screens[0], pMouse); + mieqInit ((DevicePtr)pKeyboard, (DevicePtr)pMouse); + + /* Initialize the mode key states */ + winInitializeModeKeyStates (); + + /* Only open the windows message queue device once */ + if (g_fdMessageQueue == WIN_FD_INVALID) + { + /* Open a file descriptor for the Windows message queue */ + g_fdMessageQueue = open (WIN_MSG_QUEUE_FNAME, O_RDONLY); + + if (g_fdMessageQueue == -1) + { + FatalError ("InitInput - Failed opening %s\n", + WIN_MSG_QUEUE_FNAME); + } + + /* Add the message queue as a device to wait for in WaitForSomething */ + AddEnabledDevice (g_fdMessageQueue); + } + +#if CYGDEBUG + ErrorF ("InitInput - returning\n"); +#endif +} + + +#ifdef XTESTEXT1 +void +XTestGenerateEvent (int dev_type, int keycode, int keystate, + int mousex, int mousey) +{ + ErrorF ("XTestGenerateEvent\n"); +} + + +void +XTestGetPointerPos (short *fmousex, short *fmousey) +{ + ErrorF ("XTestGetPointerPos\n"); +} + + +void +XTestJumpPointer (int jx, int jy, int dev_type) +{ + ErrorF ("XTestJumpPointer\n"); +} +#endif + diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c new file mode 100644 index 000000000..c434e58d1 --- /dev/null +++ b/hw/xwin/InitOutput.c @@ -0,0 +1,1261 @@ +/* $TOG: InitOutput.c /main/20 1998/02/10 13:23:56 kaleb $ */ +/* + +Copyright 1993, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +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 OPEN GROUP 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 Open Group 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 Open Group. + +*/ +/* $XFree86: xc/programs/Xserver/hw/xwin/InitOutput.c,v 1.32 2003/02/12 15:01:38 alanh Exp $ */ + +#include "win.h" +#include "winconfig.h" + + +/* + * General global variables + */ + +int g_iNumScreens = 0; +winScreenInfo g_ScreenInfo[MAXSCREENS]; +int g_iLastScreen = -1; +int g_fdMessageQueue = WIN_FD_INVALID; +int g_iScreenPrivateIndex = -1; +int g_iCmapPrivateIndex = -1; +int g_iGCPrivateIndex = -1; +int g_iPixmapPrivateIndex = -1; +int g_iWindowPrivateIndex = -1; +unsigned long g_ulServerGeneration = 0; +Bool g_fInitializedDefaultScreens = FALSE; +FILE *g_pfLog = NULL; +DWORD g_dwEnginesSupported = 0; +HINSTANCE g_hInstance = 0; +HWND g_hDlgDepthChange = NULL; +Bool g_fCalledSetLocale = FALSE; + + +/* + * Global variables for dynamically loaded libraries and + * their function pointers + */ + +HMODULE g_hmodDirectDraw = NULL; +FARPROC g_fpDirectDrawCreate = NULL; +FARPROC g_fpDirectDrawCreateClipper = NULL; + +HMODULE g_hmodCommonControls = NULL; +FARPROC g_fpTrackMouseEvent = (FARPROC) (void (*)())NoopDDA; + + +/* Function prototypes */ + +#ifdef DDXOSVERRORF +void OsVendorVErrorF (const char *pszFormat, va_list va_args); +#endif + + +/* + * For the depth 24 pixmap we default to 32 bits per pixel, but + * we change this pixmap format later if we detect that the display + * is going to be running at 24 bits per pixel. + * + * FIXME: On second thought, don't DIBs only support 32 bits per pixel? + * DIBs are the underlying bitmap used for DirectDraw surfaces, so it + * seems that all pixmap formats with depth 24 would be 32 bits per pixel. + * Confirm whether depth 24 DIBs can have 24 bits per pixel, then remove/keep + * the bits per pixel adjustment and update this comment to reflect the + * situation. Harold Hunt - 2002/07/02 + */ + +static PixmapFormatRec g_PixmapFormats[] = { + { 1, 1, BITMAP_SCANLINE_PAD }, + { 4, 8, BITMAP_SCANLINE_PAD }, + { 8, 8, BITMAP_SCANLINE_PAD }, + { 15, 16, BITMAP_SCANLINE_PAD }, + { 16, 16, BITMAP_SCANLINE_PAD }, + { 24, 32, BITMAP_SCANLINE_PAD }, +#ifdef RENDER + { 32, 32, BITMAP_SCANLINE_PAD } +#endif +}; + +const int NUMFORMATS = sizeof (g_PixmapFormats) / sizeof (g_PixmapFormats[0]); + + +void +winInitializeDefaultScreens (void) +{ + int i; + DWORD dwWidth, dwHeight; + + /* Bail out early if default screens have already been initialized */ + if (g_fInitializedDefaultScreens) + return; + + /* Zero the memory used for storing the screen info */ + ZeroMemory (g_ScreenInfo, MAXSCREENS * sizeof (winScreenInfo)); + + /* Get default width and height */ + /* + * NOTE: These defaults will cause the window to cover only + * the primary monitor in the case that we have multiple monitors. + */ + dwWidth = GetSystemMetrics (SM_CXSCREEN); + dwHeight = GetSystemMetrics (SM_CYSCREEN); + + ErrorF ("winInitializeDefaultScreens - w %d h %d\n", dwWidth, dwHeight); + + /* Set a default DPI, if no parameter was passed */ + if (monitorResolution == 0) + monitorResolution = WIN_DEFAULT_DPI; + + for (i = 0; i < MAXSCREENS; ++i) + { + g_ScreenInfo[i].dwScreen = i; + g_ScreenInfo[i].dwWidth = dwWidth; + g_ScreenInfo[i].dwHeight = dwHeight; + g_ScreenInfo[i].dwUserWidth = dwWidth; + g_ScreenInfo[i].dwUserHeight = dwHeight; + g_ScreenInfo[i].fUserGaveHeightAndWidth + = WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH; + g_ScreenInfo[i].dwBPP = WIN_DEFAULT_BPP; + g_ScreenInfo[i].dwClipUpdatesNBoxes = WIN_DEFAULT_CLIP_UPDATES_NBOXES; + g_ScreenInfo[i].fEmulatePseudo = WIN_DEFAULT_EMULATE_PSEUDO; + g_ScreenInfo[i].dwRefreshRate = WIN_DEFAULT_REFRESH; + g_ScreenInfo[i].pfb = NULL; + g_ScreenInfo[i].fFullScreen = FALSE; + g_ScreenInfo[i].fDecoration = TRUE; + g_ScreenInfo[i].fRootless = FALSE; + g_ScreenInfo[i].fMultiWindow = FALSE; + g_ScreenInfo[i].fMultipleMonitors = FALSE; + g_ScreenInfo[i].fClipboard = FALSE; + g_ScreenInfo[i].fLessPointer = FALSE; + g_ScreenInfo[i].fScrollbars = FALSE; + g_ScreenInfo[i].iE3BTimeout = WIN_E3B_OFF; + g_ScreenInfo[i].dwWidth_mm = (dwWidth / WIN_DEFAULT_DPI) + * 25.4; + g_ScreenInfo[i].dwHeight_mm = (dwHeight / WIN_DEFAULT_DPI) + * 25.4; + g_ScreenInfo[i].fUseWinKillKey = WIN_DEFAULT_WIN_KILL; + g_ScreenInfo[i].fUseUnixKillKey = WIN_DEFAULT_UNIX_KILL; + g_ScreenInfo[i].fIgnoreInput = FALSE; + g_ScreenInfo[i].fExplicitScreen = FALSE; + } + + /* Signal that the default screens have been initialized */ + g_fInitializedDefaultScreens = TRUE; + + ErrorF ("winInitializeDefaultScreens - Returning\n"); +} + + +/* See Porting Layer Definition - p. 57 */ +void +ddxGiveUp() +{ +#if CYGDEBUG + ErrorF ("ddxGiveUp\n"); +#endif + + /* Close our handle to our message queue */ + if (g_fdMessageQueue != WIN_FD_INVALID) + { + /* Close /dev/windows */ + close (g_fdMessageQueue); + + /* Set the file handle to invalid */ + g_fdMessageQueue = WIN_FD_INVALID; + } + + /* Close the log file handle */ + if (g_pfLog != NULL) + { + /* Close log file */ + fclose (g_pfLog); + + /* Set the file handle to invalid */ + g_pfLog = NULL; + } + + /* + * At this point we aren't creating any new screens, so + * we are guaranteed to not need the DirectDraw functions. + */ + if (g_hmodDirectDraw != NULL) + { + FreeLibrary (g_hmodDirectDraw); + g_hmodDirectDraw = NULL; + g_fpDirectDrawCreate = NULL; + g_fpDirectDrawCreateClipper = NULL; + } + + /* Unload our TrackMouseEvent funtion pointer */ + if (g_hmodCommonControls != NULL) + { + FreeLibrary (g_hmodCommonControls); + g_hmodCommonControls = NULL; + g_fpTrackMouseEvent = (FARPROC) (void (*)())NoopDDA; + } + + /* Tell Windows that we want to end the app */ + PostQuitMessage (0); +} + + +/* See Porting Layer Definition - p. 57 */ +void +AbortDDX (void) +{ +#if CYGDEBUG + ErrorF ("AbortDDX\n"); +#endif + ddxGiveUp (); +} + + +void +OsVendorInit (void) +{ +#ifdef DDXOSVERRORF + if (!OsVendorVErrorFProc) + OsVendorVErrorFProc = OsVendorVErrorF; + + /* Open log file if not yet open */ + if (g_pfLog == NULL) + g_pfLog = fopen (WIN_LOG_FNAME, "w"); +#endif + + /* Add a default screen if no screens were specified */ + if (g_iNumScreens == 0) + { + ErrorF ("OsVendorInit - Creating bogus screen 0\n"); + + /* + * We need to initialize default screens if no arguments + * were processed. Otherwise, the default screens would + * already have been initialized by ddxProcessArgument (). + */ + winInitializeDefaultScreens (); + + /* + * Add a screen 0 using the defaults set by + * winInitializeDefaultScreens () and any additional parameters + * processed by ddxProcessArgument (). + */ + g_iNumScreens = 1; + g_iLastScreen = 0; + + /* We have to flag this as an explicit screen, even though it isn't */ + g_ScreenInfo[0].fExplicitScreen = TRUE; + } +} + + +/* See Porting Layer Definition - p. 57 */ +void +ddxUseMsg (void) +{ + ErrorF ("-depth bits_per_pixel\n" + "\tSpecify an optional bitdepth to use in fullscreen mode\n" + "\twith a DirectDraw engine.\n"); + + ErrorF ("-emulate3buttons [timeout]\n" + "\tEmulate 3 button mouse with an optional timeout in\n" + "\tmilliseconds.\n"); + + ErrorF ("-engine engine_type_id\n" + "\tOverride the server's automatically selected engine type:\n" + "\t\t1 - Shadow GDI\n" + "\t\t2 - Shadow DirectDraw\n" + "\t\t4 - Shadow DirectDraw4 Non-Locking\n" + "\t\t16 - Native GDI - experimental\n"); + + ErrorF ("-fullscreen\n" + "\tRun the server in fullscreen mode.\n"); + + ErrorF ("-refresh rate_in_Hz\n" + "\tSpecify an optional refresh rate to use in fullscreen mode\n" + "\twith a DirectDraw engine.\n"); + + ErrorF ("-screen scr_num [width height]\n" + "\tEnable screen scr_num and optionally specify a width and\n" + "\theight for that screen.\n"); + + ErrorF ("-lesspointer\n" + "\tHide the windows mouse pointer when it is over an inactive\n" + "\tXFree86 window. This prevents ghost cursors appearing where\n" + "\tthe Windows cursor is drawn overtop of the X cursor\n"); + + ErrorF ("-nodecoration\n" + "\tDo not draw a window border, title bar, etc. Windowed\n" + "\tmode only.\n"); + + ErrorF ("-rootless\n" + "\tEXPERIMENTAL: Run the server in pseudo-rootless mode.\n"); + + ErrorF ("-multiwindow\n" + "\tEXPERIMENTAL: Run the server in multi-window mode.\n"); + + ErrorF ("-multiplemonitors\n" + "\tEXPERIMENTAL: Use the entire virtual screen if multiple\n" + "\tmonitors are present.\n"); + + ErrorF ("-clipboard\n" + "\tEXPERIMENTAL: Run the clipboard integration module.\n"); + + ErrorF ("-scrollbars\n" + "\tIn windowed mode, allow screens bigger than the Windows desktop.\n" + "\tMoreover, if the window has decorations, one can now resize\n" + "\tit.\n"); + + ErrorF ("-clipupdates num_boxes\n" + "\tUse a clipping region to constrain shadow update blits to\n" + "\tthe updated region when num_boxes, or more, are in the\n" + "\tupdated region. Currently supported only by `-engine 1'.\n"); + + ErrorF ("-emulatepseudo\n" + "\tCreate a depth 8 PseudoColor visual when running in\n" + "\tdepths 15, 16, 24, or 32, collectively known as TrueColor\n" + "\tdepths. The PseudoColor visual does not have correct colors,\n" + "\tand it may crash, but it at least allows you to run your\n" + "\tapplication in TrueColor modes.\n"); + + ErrorF ("-[no]unixkill\n" + "\tCtrl+Alt+Backspace exits the X Server.\n"); + + ErrorF ("-[no]winkill\n" + "\tAlt+F4 exits the X Server.\n"); + + ErrorF ("-xf86config\n" + "\tSpecify a configuration file.\n"); + + ErrorF ("-keyboard\n" + "\tSpecify a keyboard device from the configuration file.\n"); +} + + +/* See Porting Layer Definition - p. 57 */ +/* + * INPUT + * argv: pointer to an array of null-terminated strings, one for + * each token in the X Server command line; the first token + * is 'XWin.exe', or similar. + * argc: a count of the number of tokens stored in argv. + * i: a zero-based index into argv indicating the current token being + * processed. + * + * OUTPUT + * return: return the number of tokens processed correctly. + * + * NOTE + * When looking for n tokens, check that i + n is less than argc. Or, + * you may check if i is greater than or equal to argc, in which case + * you should display the UseMsg () and return 0. + */ + +/* Check if enough arguments are given for the option */ +#define CHECK_ARGS(count) if (i + count >= argc) { UseMsg (); return 0; } + +/* Compare the current option with the string. */ +#define IS_OPTION(name) (strcmp (argv[i], name) == 0) + +int +ddxProcessArgument (int argc, char *argv[], int i) +{ + static Bool s_fBeenHere = FALSE; + + /* Initialize once */ + if (!s_fBeenHere) + { +#ifdef DDXOSVERRORF + /* + * This initialises our hook into VErrorF () for catching log messages + * that are generated before OsInit () is called. + */ + OsVendorVErrorFProc = OsVendorVErrorF; + + /* Open log file if not yet open */ + if (g_pfLog == NULL) + g_pfLog = fopen (WIN_LOG_FNAME, "w"); +#endif + + s_fBeenHere = TRUE; + + /* + * Initialize default screen settings. We have to do this before + * OsVendorInit () gets called, otherwise we will overwrite + * settings changed by parameters such as -fullscreen, etc. + */ + ErrorF ("ddxProcessArgument - Initializing default screens\n"); + winInitializeDefaultScreens (); + } + +#if CYGDEBUG + ErrorF ("ddxProcessArgument - arg: %s\n", argv[i]); +#endif + + /* + * Look for the '-screen scr_num [width height]' argument + */ + if (strcmp (argv[i], "-screen") == 0) + { + int iArgsProcessed = 1; + int nScreenNum; + int iWidth, iHeight; + +#if CYGDEBUG + ErrorF ("ddxProcessArgument - screen - argc: %d i: %d\n", + argc, i); +#endif + + /* Display the usage message if the argument is malformed */ + if (i + 1 >= argc) + { + return 0; + } + + /* Grab screen number */ + nScreenNum = atoi (argv[i + 1]); + + /* Validate the specified screen number */ + if (nScreenNum < 0 || nScreenNum >= MAXSCREENS) + { + ErrorF ("ddxProcessArgument - screen - Invalid screen number %d\n", + nScreenNum); + UseMsg (); + return 0; + } + + /* Look for 'WxD' or 'W D' */ + if (i + 2 < argc + && 2 == sscanf (argv[i + 2], "%dx%d", + (int *) &iWidth, + (int *) &iHeight)) + { + ErrorF ("ddxProcessArgument - screen - Found ``WxD'' arg\n"); + iArgsProcessed = 3; + g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = TRUE; + g_ScreenInfo[nScreenNum].dwWidth = iWidth; + g_ScreenInfo[nScreenNum].dwHeight = iHeight; + g_ScreenInfo[nScreenNum].dwUserWidth = iWidth; + g_ScreenInfo[nScreenNum].dwUserHeight = iHeight; + } + else if (i + 3 < argc + && 1 == sscanf (argv[i + 2], "%d", + (int *) &iWidth) + && 1 == sscanf (argv[i + 3], "%d", + (int *) &iHeight)) + { + ErrorF ("ddxProcessArgument - screen - Found ``W D'' arg\n"); + iArgsProcessed = 4; + g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = TRUE; + g_ScreenInfo[nScreenNum].dwWidth = iWidth; + g_ScreenInfo[nScreenNum].dwHeight = iHeight; + g_ScreenInfo[nScreenNum].dwUserWidth = iWidth; + g_ScreenInfo[nScreenNum].dwUserHeight = iHeight; + } + else + { + ErrorF ("ddxProcessArgument - screen - Did not find size arg. " + "dwWidth: %d dwHeight: %d\n", + g_ScreenInfo[nScreenNum].dwWidth, + g_ScreenInfo[nScreenNum].dwHeight); + iArgsProcessed = 2; + g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = FALSE; + } + + /* Calculate the screen width and height in millimeters */ + if (g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth) + { + g_ScreenInfo[nScreenNum].dwWidth_mm + = (g_ScreenInfo[nScreenNum].dwWidth + / monitorResolution) * 25.4; + g_ScreenInfo[nScreenNum].dwHeight_mm + = (g_ScreenInfo[nScreenNum].dwHeight + / monitorResolution) * 25.4; + } + + /* Flag that this screen was explicity specified by the user */ + g_ScreenInfo[nScreenNum].fExplicitScreen = TRUE; + + /* + * Keep track of the last screen number seen, as parameters seen + * before a screen number apply to all screens, whereas parameters + * seen after a screen number apply to that screen number only. + */ + g_iLastScreen = nScreenNum; + + /* Keep a count of the number of screens */ + ++g_iNumScreens; + + return iArgsProcessed; + } + + /* + * Look for the '-engine n' argument + */ + if (strcmp (argv[i], "-engine") == 0) + { + DWORD dwEngine = 0; + CARD8 c8OnBits = 0; + + /* Display the usage message if the argument is malformed */ + if (++i >= argc) + { + UseMsg (); + return 0; + } + + /* Grab the argument */ + dwEngine = atoi (argv[i]); + + /* Count the one bits in the engine argument */ + c8OnBits = winCountBits (dwEngine); + + /* Argument should only have a single bit on */ + if (c8OnBits != 1) + { + UseMsg (); + return 0; + } + + /* Is this parameter attached to a screen or global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].dwEnginePreferred = dwEngine; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].dwEnginePreferred = dwEngine; + } + + /* Indicate that we have processed the argument */ + return 2; + } + + /* + * Look for the '-fullscreen' argument + */ + if (strcmp (argv[i], "-fullscreen") == 0) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fFullScreen = TRUE; + + /* + * No scrollbars in fullscreen mode. Later, we may want to have + * a fullscreen with a bigger virtual screen? + */ + g_ScreenInfo[j].fScrollbars = FALSE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fFullScreen = TRUE; + + /* + * No scrollbars in fullscreen mode. Later, we may want to have + * a fullscreen with a bigger virtual screen? + */ + g_ScreenInfo[g_iLastScreen].fScrollbars = FALSE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-lesspointer' argument + */ + if (strcmp (argv[i], "-lesspointer") == 0) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fLessPointer = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fLessPointer = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-nodecoration' argument + */ + if (strcmp (argv[i], "-nodecoration") == 0) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fDecoration = FALSE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fDecoration = FALSE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-rootless' argument + */ + if (strcmp (argv[i], "-rootless") == 0) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fRootless = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fRootless = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-multiwindow' argument + */ + if (strcmp (argv[i], "-multiwindow") == 0) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fMultiWindow = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fMultiWindow = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-multiplemonitors' argument + */ + if (strcmp (argv[i], "-multiplemonitors") == 0 + || strcmp (argv[i], "-multimonitors") == 0) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fMultipleMonitors = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fMultipleMonitors = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-scrollbars' argument + */ + if (strcmp (argv[i], "-scrollbars") == 0) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + /* No scrollbar in fullscreen mode */ + if (!g_ScreenInfo[j].fFullScreen) + g_ScreenInfo[j].fScrollbars = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + if (!g_ScreenInfo[g_iLastScreen].fFullScreen) + { + /* No scrollbar in fullscreen mode */ + g_ScreenInfo[g_iLastScreen].fScrollbars = TRUE; + } + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-clipboard' argument + */ + if (strcmp (argv[i], "-clipboard") == 0) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fClipboard = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fClipboard = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-ignoreinput' argument + */ + if (strcmp (argv[i], "-ignoreinput") == 0) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fIgnoreInput = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fIgnoreInput = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-emulate3buttons' argument + */ + if (strcmp (argv[i], "-emulate3buttons") == 0) + { + int iArgsProcessed = 1; + int iE3BTimeout = WIN_DEFAULT_E3B_TIME; + + /* Grab the optional timeout value */ + if (i + 1 < argc + && 1 == sscanf (argv[i + 1], "%d", + &iE3BTimeout)) + { + /* Indicate that we have processed the next argument */ + iArgsProcessed++; + } + else + { + /* + * sscanf () won't modify iE3BTimeout if it doesn't find + * the specified format; however, I want to be explicit + * about setting the default timeout in such cases to + * prevent some programs (me) from getting confused. + */ + iE3BTimeout = WIN_DEFAULT_E3B_TIME; + } + + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].iE3BTimeout = iE3BTimeout; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].iE3BTimeout = iE3BTimeout; + } + + /* Indicate that we have processed this argument */ + return iArgsProcessed; + } + + /* + * Look for the '-depth n' argument + */ + if (strcmp (argv[i], "-depth") == 0) + { + DWORD dwBPP = 0; + + /* Display the usage message if the argument is malformed */ + if (++i >= argc) + { + UseMsg (); + return 0; + } + + /* Grab the argument */ + dwBPP = atoi (argv[i]); + + /* Is this parameter attached to a screen or global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].dwBPP = dwBPP; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].dwBPP = dwBPP; + } + + /* Indicate that we have processed the argument */ + return 2; + } + + /* + * Look for the '-refresh n' argument + */ + if (strcmp (argv[i], "-refresh") == 0) + { + DWORD dwRefreshRate = 0; + + /* Display the usage message if the argument is malformed */ + if (++i >= argc) + { + UseMsg (); + return 0; + } + + /* Grab the argument */ + dwRefreshRate = atoi (argv[i]); + + /* Is this parameter attached to a screen or global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].dwRefreshRate = dwRefreshRate; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].dwRefreshRate = dwRefreshRate; + } + + /* Indicate that we have processed the argument */ + return 2; + } + + /* + * Look for the '-clipupdates num_boxes' argument + */ + if (strcmp (argv[i], "-clipupdates") == 0) + { + DWORD dwNumBoxes = 0; + + /* Display the usage message if the argument is malformed */ + if (++i >= argc) + { + UseMsg (); + return 0; + } + + /* Grab the argument */ + dwNumBoxes = atoi (argv[i]); + + /* Is this parameter attached to a screen or global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].dwClipUpdatesNBoxes = dwNumBoxes; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].dwClipUpdatesNBoxes = dwNumBoxes; + } + + /* Indicate that we have processed the argument */ + return 2; + } + + /* + * Look for the '-emulatepseudo' argument + */ + if (strcmp (argv[i], "-emulatepseudo") == 0) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fEmulatePseudo = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fEmulatePseudo = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-nowinkill' argument + */ + if (strcmp (argv[i], "-nowinkill") == 0) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fUseWinKillKey = FALSE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fUseWinKillKey = FALSE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-winkill' argument + */ + if (strcmp (argv[i], "-winkill") == 0) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fUseWinKillKey = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fUseWinKillKey = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-nounixkill' argument + */ + if (strcmp (argv[i], "-nounixkill") == 0) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fUseUnixKillKey = FALSE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fUseUnixKillKey = FALSE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-unixkill' argument + */ + if (strcmp (argv[i], "-unixkill") == 0) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fUseUnixKillKey = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fUseUnixKillKey = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-fp' argument + */ + if (IS_OPTION ("-fp")) + { + CHECK_ARGS (1); + g_cmdline.fontPath = argv[++i]; + return 0; /* Let DIX parse this again */ + } + + /* + * Look for the '-co' argument + */ + if (IS_OPTION ("-co")) + { + CHECK_ARGS (1); + g_cmdline.rgbPath = argv[++i]; + return 0; /* Let DIX parse this again */ + } + + /* + * Look for the '-xf86config' argument + */ + if (IS_OPTION ("-xf86config")) + { + CHECK_ARGS (1); + g_cmdline.configFile = argv[++i]; + return 2; + } + + /* + * Look for the '-keyboard' argument + */ + if (IS_OPTION ("-keyboard")) + { + CHECK_ARGS (1); + g_cmdline.keyboard = argv[++i]; + return 2; + } + + return 0; +} + + +#ifdef DDXTIME /* from ServerOSDefines */ +CARD32 +GetTimeInMillis (void) +{ + return GetTickCount (); +} +#endif /* DDXTIME */ + + +/* See Porting Layer Definition - p. 20 */ +/* + * Do any global initialization, then initialize each screen. + * + * NOTE: We use ddxProcessArgument, so we don't need to touch argc and argv + */ + +void +InitOutput (ScreenInfo *screenInfo, int argc, char *argv[]) +{ + int i; + int iMaxConsecutiveScreen = 0; + +#if CYGDEBUG + ErrorF ("InitOutput\n"); +#endif + + /* Try to read the XF86Config-style configuration file */ + if (!winReadConfigfile ()) + ErrorF ("InitOutput - Error reading config file\n"); + + /* Setup global screen info parameters */ + screenInfo->imageByteOrder = IMAGE_BYTE_ORDER; + screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD; + screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; + screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER; + screenInfo->numPixmapFormats = NUMFORMATS; + + /* Describe how we want common pixmap formats padded */ + for (i = 0; i < NUMFORMATS; i++) + { + screenInfo->formats[i] = g_PixmapFormats[i]; + } + + /* Load pointers to DirectDraw functions */ + winGetDDProcAddresses (); + + /* Detect supported engines */ + winDetectSupportedEngines (); + + /* Load common controls library */ + g_hmodCommonControls = LoadLibraryEx ("comctl32.dll", NULL, 0); + + /* Load TrackMouseEvent function pointer */ + g_fpTrackMouseEvent = GetProcAddress (g_hmodCommonControls, + "_TrackMouseEvent"); + if (g_fpTrackMouseEvent == NULL) + { + ErrorF ("InitOutput - Could not get pointer to function\n" + "\t_TrackMouseEvent in comctl32.dll. Try installing\n" + "\tInternet Explorer 3.0 or greater if you have not\n" + "\talready.\n"); + + /* Free the library since we won't need it */ + FreeLibrary (g_hmodCommonControls); + g_hmodCommonControls = NULL; + + /* Set function pointer to point to no operation function */ + g_fpTrackMouseEvent = (FARPROC) (void (*)())NoopDDA; + } + + /* + * Check for a malformed set of -screen parameters. + * Examples of malformed parameters: + * XWin -screen 1 + * XWin -screen 0 -screen 2 + * XWin -screen 1 -screen 2 + */ + for (i = 0; i < MAXSCREENS; i++) + { + if (g_ScreenInfo[i].fExplicitScreen) + iMaxConsecutiveScreen = i + 1; + } + ErrorF ("InitOutput - g_iNumScreens: %d iMaxConsecutiveScreen: %d\n", + g_iNumScreens, iMaxConsecutiveScreen); + if (g_iNumScreens < iMaxConsecutiveScreen) + FatalError ("InitOutput - Malformed set of screen parameter(s). " + "Screens must be specified consecutively starting with " + "screen 0. That is, you cannot have only a screen 1, nor " + "could you have screen 0 and screen 2. You instead must have " + "screen 0, or screen 0 and screen 1, respectively. Of " + "you can specify as many screens as you want from 0 up to " + "%d.\n", MAXSCREENS - 1); + + /* Store the instance handle */ + g_hInstance = GetModuleHandle (NULL); + + /* Initialize each screen */ + for (i = 0; i < g_iNumScreens; i++) + { + /* Initialize the screen */ + if (-1 == AddScreen (winScreenInit, argc, argv)) + { + FatalError ("InitOutput - Couldn't add screen %d", i); + } + } + +#if CYGDEBUG || YES + ErrorF ("InitOutput - Returning.\n"); +#endif +} diff --git a/hw/xwin/X.ico b/hw/xwin/X.ico new file mode 100644 index 000000000..26e2cf947 Binary files /dev/null and b/hw/xwin/X.ico differ diff --git a/hw/xwin/XWin.man b/hw/xwin/XWin.man new file mode 100644 index 000000000..09bdcd235 --- /dev/null +++ b/hw/xwin/XWin.man @@ -0,0 +1,129 @@ +.\" $XFree86: xc/programs/Xserver/hw/xwin/XWin.man,v 1.6 2002/10/17 08:18:21 alanh Exp $ +.TH XWIN 1 __vendorversion__ +.SH NAME +XWin \- X Server for the Cygwin environment on Microsoft Windows +.SH SYNOPSIS +.B XWin +[ options ] ... +.SH DESCRIPTION +.I XWin +is an X Server for the X Window System on the Cygwin environment +running on Microsoft Windows. +.SH OPTIONS +.PP +In addition to the normal server options described in the \fIXserver(1)\fP +manual page, \fIXWin\fP accepts the following command line switches: +.TP 8 +.B "\-depth \fIdepth\fP" +Specify the color depth, in bits per pixel, to use when running in +fullscreen with a DirectDraw engine. This parameter is ignored if +\fB\-fullscreen\fP is not specified. +.TP 8 +.B "\-emulate3buttons \fItimeout\fP" +Emulate a three button mouse; pressing both buttons within +.I timeout +milliseconds causes an emulated middle button press. The default +.I timeout +is 50 milliseconds. +.TP 8 +.B "\-engine \fIengine_type_id\fP" +Override the server's automatically supported engine type. This +parameter will be ignored if the specified engine type is not +supported on the current system. The supported engine type ids are 1 +- Shadow GDI, 2 - Shadow DirectDraw, and 4 - Shadow DirectDraw4. +Additionally, there is a barely functional experimental engine type id +16 - Native GDI. +.TP 8 +.B \-fullscreen +Run the server in fullscreen mode, as opposed to the default windowed +mode. +.TP 8 +.B "\-refresh \fIrate_in_Hz\fP" +Specify an optional refresh rate to use when running in +fullscreen with a DirectDraw engine. This parameter is ignored if +\fB\-fullscreen\fP is not specified. +.TP 8 +.B "\-screen \fIscreen_number\fP \fIwidth\fP \fIheight\fP" +Sets the display resolution for the X server to use on screen +.I screen_number. +.TP 8 +.B \-nodecoration +Draw the Cygwin/XFree86 window without a border or title bar. +.TP 8 +.B \-rootless +EXPERIMENTAL: Run Cygwin/XFree86 in pseduo-rootless mode. +.TP 8 +.B \-lesspointer +Hide the Windows mouse pointer when over an inactive XFree86 window +.TP 8 +.B \-scrollbars +In windowed mode, allow screens bigger than the Windows desktop. +Moreover, if the window has decorations, one can now resize it. +.TP 8 +.B "\-clipupdates \fInum_boxes\fP" +Specify an optional threshold, above which the boxes in a shadow +update operation will be collected into a GDI clipping region. The +clipping region is then used to do a single bit block transfer that is +constrained to the updated area by the clipping region. There is some +overhead involved in creating, installing, destroying, and removing +the clipping region, thus there may not be much benefit for a small +number of boxes (less than 10). It is even possible that this +functionality does not provide a benefit at any number of boxes; we +can only determine the usefullness of this feature through testing. +This parameter works in conjunction with engines 1, 2, and 4 (Shadow +GDI, Shadow DirectDraw, and Shadow DirectDraw Non-Locking, +respectively). +.TP 8 +.B \-emulatepseudo +Create a depth 8 PseudoColor visual when running in depths 15, 16, 24, +or 32, collectively known as TrueColor depths. The PseudoColor visual +does not have correct colors, and it may crash, but it at least allows +you to run your PseudoColor application in TrueColor modes. +.TP 8 +.B \-[no]unixkill +Ctrl+Alt+Backspace exits the X Server +.TP 8 +.B \-[no]winkill +Alt+F4 exits the X Server +.SH "SEE ALSO" +.PP +X(__miscmansuffix__), Xserver(1), xdm(1), xinit(1) +.SH BUGS +.I XWin +and this man page still have many limitations. Some of the more obvious +ones are: +.br +- The display mode can not be changed once the X server has started. +.PP +.SH AUTHORS +XFree86 was originally ported to Cygwin by Dakshinamurthy Karra, +Dr. Peter Busch, John Fortin, and Suhaib Siddiqi. +.I XWin +is maintained by the Cygwin/XFree86 project, with hosting services +provided by RedHat. +.PP +The following members, in alphabetical order by last name, of the +Cygwin/XFree86 Team contributed to the XFree86 4.1.0 release: +.PP +Robert Collins - Cygwin developer, miscellaneous +.br +Christopher Faylor - Management of hosting services, general +programming guru +.br +Alexander Gottwald - AltGr handling for non-U.S. keyboards +.br +Alan Hourihane - XFree86 developer, patch reviewer, general programming guru +.br +Pierre A Humblet - Debugging of socket-related crashes, developer +.br +Harold L Hunt II - Project leader, lead developer, documentation, +and website updates +.br +Suhaib Siddiqi - Originator of the project + + + + + + + diff --git a/hw/xwin/XWin.rc b/hw/xwin/XWin.rc new file mode 100644 index 000000000..73533ba4e --- /dev/null +++ b/hw/xwin/XWin.rc @@ -0,0 +1,60 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/XWin.rc,v 1.1 2002/10/17 08:18:21 alanh Exp $ */ + +#include "resource.h" + + +/* + * Dialogs + */ + +DEPTH_CHANGE_BOX DIALOG DISCARDABLE 32, 32, 180, 100 +STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE +FONT 8, "MS Sans Serif" +CAPTION "Cygwin/XFree86" +BEGIN + DEFPUSHBUTTON "Dismiss", IDOK, 66, 80, 50, 14 + CTEXT "Cygwin/XFree86", IDC_STATIC, 40, 12, 100, 8 + CTEXT "Disruptive screen configuration change.", IDC_STATIC, 7, 40, 166, 8 + CTEXT "Restore previous resolution to use Cygwin/XFree86.", IDC_STATIC, 7, 52, 166, 8 +END + + +/* + * Menus + */ + + +/* + * Icons + */ + +IDI_XWIN ICON DISCARDABLE "X.ico" diff --git a/hw/xwin/ddraw.h b/hw/xwin/ddraw.h new file mode 100644 index 000000000..b67a556b5 --- /dev/null +++ b/hw/xwin/ddraw.h @@ -0,0 +1,2094 @@ +/* $XFree86: xc/programs/Xserver/hw/xwin/ddraw.h,v 1.4 2001/07/29 22:08:15 tsi Exp $ */ + +#ifndef __WINE_DDRAW_H +#define __WINE_DDRAW_H + +#include +#include +#include "obj_base.h" + +#ifdef NONAMELESSUNION +#ifndef DUMMYUNIONNAME1 +#define DUMMYUNIONNAME1 u1 +#endif +#endif + +# ifdef UNICODE +# define WINELIB_NAME_AW(func) func##W +# else +# define WINELIB_NAME_AW(func) func##A +# endif /* UNICODE */ +#define DECL_WINELIB_TYPE_AW(type) typedef WINELIB_NAME_AW(type) type; + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +#ifndef DIRECTDRAW_VERSION +#define DIRECTDRAW_VERSION 0x0700 +#endif /* DIRECTDRAW_VERSION */ + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_GUID( CLSID_DirectDraw, 0xD7B70EE0,0x4340,0x11CF,0xB0,0x63,0x00,0x20,0xAF,0xC2,0xCD,0x35 ); +DEFINE_GUID( CLSID_DirectDraw7, 0x3C305196,0x50DB,0x11D3,0x9C,0xFE,0x00,0xC0,0x4F,0xD9,0x30,0xC5 ); +DEFINE_GUID( CLSID_DirectDrawClipper, 0x593817A0,0x7DB3,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xb9,0x33,0x56 ); +DEFINE_GUID( IID_IDirectDraw, 0x6C14DB80,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); +DEFINE_GUID( IID_IDirectDraw2, 0xB3A6F3E0,0x2B43,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56 ); +DEFINE_GUID( IID_IDirectDraw4, 0x9c59509a,0x39bd,0x11d1,0x8c,0x4a,0x00,0xc0,0x4f,0xd9,0x30,0xc5 ); +DEFINE_GUID( IID_IDirectDraw7, 0x15e65ec0,0x3b9c,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b ); +DEFINE_GUID( IID_IDirectDrawSurface, 0x6C14DB81,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); +DEFINE_GUID( IID_IDirectDrawSurface2, 0x57805885,0x6eec,0x11cf,0x94,0x41,0xa8,0x23,0x03,0xc1,0x0e,0x27 ); +DEFINE_GUID( IID_IDirectDrawSurface3, 0xDA044E00,0x69B2,0x11D0,0xA1,0xD5,0x00,0xAA,0x00,0xB8,0xDF,0xBB ); +DEFINE_GUID( IID_IDirectDrawSurface4, 0x0B2B8630,0xAD35,0x11D0,0x8E,0xA6,0x00,0x60,0x97,0x97,0xEA,0x5B ); +DEFINE_GUID( IID_IDirectDrawSurface7, 0x06675a80,0x3b9b,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b ); +DEFINE_GUID( IID_IDirectDrawPalette, 0x6C14DB84,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); +DEFINE_GUID( IID_IDirectDrawClipper, 0x6C14DB85,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); +DEFINE_GUID( IID_IDirectDrawColorControl,0x4B9F0EE0,0x0D7E,0x11D0,0x9B,0x06,0x00,0xA0,0xC9,0x03,0xA3,0xB8 ); +DEFINE_GUID( IID_IDirectDrawGammaControl,0x69C11C3E,0xB46B,0x11D1,0xAD,0x7A,0x00,0xC0,0x4F,0xC2,0x9B,0x4E ); + +typedef struct IDirectDraw IDirectDraw,*LPDIRECTDRAW; +typedef struct IDirectDraw2 IDirectDraw2,*LPDIRECTDRAW2; +typedef struct IDirectDraw4 IDirectDraw4,*LPDIRECTDRAW4; +typedef struct IDirectDraw7 IDirectDraw7,*LPDIRECTDRAW7; +typedef struct IDirectDrawClipper IDirectDrawClipper,*LPDIRECTDRAWCLIPPER; +typedef struct IDirectDrawPalette IDirectDrawPalette,*LPDIRECTDRAWPALETTE; +typedef struct IDirectDrawSurface IDirectDrawSurface,*LPDIRECTDRAWSURFACE; +typedef struct IDirectDrawSurface2 IDirectDrawSurface2,*LPDIRECTDRAWSURFACE2; +typedef struct IDirectDrawSurface3 IDirectDrawSurface3,*LPDIRECTDRAWSURFACE3; +typedef struct IDirectDrawSurface4 IDirectDrawSurface4,*LPDIRECTDRAWSURFACE4; +typedef struct IDirectDrawSurface7 IDirectDrawSurface7,*LPDIRECTDRAWSURFACE7; +typedef struct IDirectDrawColorControl IDirectDrawColorControl,*LPDIRECTDRAWCOLORCONTROL; +typedef struct IDirectDrawGammaControl IDirectDrawGammaControl,*LPDIRECTDRAWGAMMACONTROL; + + +#define DDENUMRET_CANCEL 0 +#define DDENUMRET_OK 1 + +#define DD_OK 0 + + +#define _FACDD 0x876 +#define MAKE_DDHRESULT( code ) MAKE_HRESULT( 1, _FACDD, code ) + +#define DDERR_ALREADYINITIALIZED MAKE_DDHRESULT( 5 ) +#define DDERR_CANNOTATTACHSURFACE MAKE_DDHRESULT( 10 ) +#define DDERR_CANNOTDETACHSURFACE MAKE_DDHRESULT( 20 ) +#define DDERR_CURRENTLYNOTAVAIL MAKE_DDHRESULT( 40 ) +#define DDERR_EXCEPTION MAKE_DDHRESULT( 55 ) +#define DDERR_GENERIC E_FAIL +#define DDERR_HEIGHTALIGN MAKE_DDHRESULT( 90 ) +#define DDERR_INCOMPATIBLEPRIMARY MAKE_DDHRESULT( 95 ) +#define DDERR_INVALIDCAPS MAKE_DDHRESULT( 100 ) +#define DDERR_INVALIDCLIPLIST MAKE_DDHRESULT( 110 ) +#define DDERR_INVALIDMODE MAKE_DDHRESULT( 120 ) +#define DDERR_INVALIDOBJECT MAKE_DDHRESULT( 130 ) +#define DDERR_INVALIDPARAMS E_INVALIDARG +#define DDERR_INVALIDPIXELFORMAT MAKE_DDHRESULT( 145 ) +#define DDERR_INVALIDRECT MAKE_DDHRESULT( 150 ) +#define DDERR_LOCKEDSURFACES MAKE_DDHRESULT( 160 ) +#define DDERR_NO3D MAKE_DDHRESULT( 170 ) +#define DDERR_NOALPHAHW MAKE_DDHRESULT( 180 ) +#define DDERR_NOSTEREOHARDWARE MAKE_DDHRESULT( 181 ) +#define DDERR_NOSURFACELEFT MAKE_DDHRESULT( 182 ) +#define DDERR_NOCLIPLIST MAKE_DDHRESULT( 205 ) +#define DDERR_NOCOLORCONVHW MAKE_DDHRESULT( 210 ) +#define DDERR_NOCOOPERATIVELEVELSET MAKE_DDHRESULT( 212 ) +#define DDERR_NOCOLORKEY MAKE_DDHRESULT( 215 ) +#define DDERR_NOCOLORKEYHW MAKE_DDHRESULT( 220 ) +#define DDERR_NODIRECTDRAWSUPPORT MAKE_DDHRESULT( 222 ) +#define DDERR_NOEXCLUSIVEMODE MAKE_DDHRESULT( 225 ) +#define DDERR_NOFLIPHW MAKE_DDHRESULT( 230 ) +#define DDERR_NOGDI MAKE_DDHRESULT( 240 ) +#define DDERR_NOMIRRORHW MAKE_DDHRESULT( 250 ) +#define DDERR_NOTFOUND MAKE_DDHRESULT( 255 ) +#define DDERR_NOOVERLAYHW MAKE_DDHRESULT( 260 ) +#define DDERR_OVERLAPPINGRECTS MAKE_DDHRESULT( 270 ) +#define DDERR_NORASTEROPHW MAKE_DDHRESULT( 280 ) +#define DDERR_NOROTATIONHW MAKE_DDHRESULT( 290 ) +#define DDERR_NOSTRETCHHW MAKE_DDHRESULT( 310 ) +#define DDERR_NOT4BITCOLOR MAKE_DDHRESULT( 316 ) +#define DDERR_NOT4BITCOLORINDEX MAKE_DDHRESULT( 317 ) +#define DDERR_NOT8BITCOLOR MAKE_DDHRESULT( 320 ) +#define DDERR_NOTEXTUREHW MAKE_DDHRESULT( 330 ) +#define DDERR_NOVSYNCHW MAKE_DDHRESULT( 335 ) +#define DDERR_NOZBUFFERHW MAKE_DDHRESULT( 340 ) +#define DDERR_NOZOVERLAYHW MAKE_DDHRESULT( 350 ) +#define DDERR_OUTOFCAPS MAKE_DDHRESULT( 360 ) +#define DDERR_OUTOFMEMORY E_OUTOFMEMORY +#define DDERR_OUTOFVIDEOMEMORY MAKE_DDHRESULT( 380 ) +#define DDERR_OVERLAYCANTCLIP MAKE_DDHRESULT( 382 ) +#define DDERR_OVERLAYCOLORKEYONLYONEACTIVE MAKE_DDHRESULT( 384 ) +#define DDERR_PALETTEBUSY MAKE_DDHRESULT( 387 ) +#define DDERR_COLORKEYNOTSET MAKE_DDHRESULT( 400 ) +#define DDERR_SURFACEALREADYATTACHED MAKE_DDHRESULT( 410 ) +#define DDERR_SURFACEALREADYDEPENDENT MAKE_DDHRESULT( 420 ) +#define DDERR_SURFACEBUSY MAKE_DDHRESULT( 430 ) +#define DDERR_CANTLOCKSURFACE MAKE_DDHRESULT( 435 ) +#define DDERR_SURFACEISOBSCURED MAKE_DDHRESULT( 440 ) +#define DDERR_SURFACELOST MAKE_DDHRESULT( 450 ) +#define DDERR_SURFACENOTATTACHED MAKE_DDHRESULT( 460 ) +#define DDERR_TOOBIGHEIGHT MAKE_DDHRESULT( 470 ) +#define DDERR_TOOBIGSIZE MAKE_DDHRESULT( 480 ) +#define DDERR_TOOBIGWIDTH MAKE_DDHRESULT( 490 ) +#define DDERR_UNSUPPORTED E_NOTIMPL +#define DDERR_UNSUPPORTEDFORMAT MAKE_DDHRESULT( 510 ) +#define DDERR_UNSUPPORTEDMASK MAKE_DDHRESULT( 520 ) +#define DDERR_INVALIDSTREAM MAKE_DDHRESULT( 521 ) +#define DDERR_VERTICALBLANKINPROGRESS MAKE_DDHRESULT( 537 ) +#define DDERR_WASSTILLDRAWING MAKE_DDHRESULT( 540 ) +#define DDERR_DDSCAPSCOMPLEXREQUIRED MAKE_DDHRESULT( 542 ) +#define DDERR_XALIGN MAKE_DDHRESULT( 560 ) +#define DDERR_INVALIDDIRECTDRAWGUID MAKE_DDHRESULT( 561 ) +#define DDERR_DIRECTDRAWALREADYCREATED MAKE_DDHRESULT( 562 ) +#define DDERR_NODIRECTDRAWHW MAKE_DDHRESULT( 563 ) +#define DDERR_PRIMARYSURFACEALREADYEXISTS MAKE_DDHRESULT( 564 ) +#define DDERR_NOEMULATION MAKE_DDHRESULT( 565 ) +#define DDERR_REGIONTOOSMALL MAKE_DDHRESULT( 566 ) +#define DDERR_CLIPPERISUSINGHWND MAKE_DDHRESULT( 567 ) +#define DDERR_NOCLIPPERATTACHED MAKE_DDHRESULT( 568 ) +#define DDERR_NOHWND MAKE_DDHRESULT( 569 ) +#define DDERR_HWNDSUBCLASSED MAKE_DDHRESULT( 570 ) +#define DDERR_HWNDALREADYSET MAKE_DDHRESULT( 571 ) +#define DDERR_NOPALETTEATTACHED MAKE_DDHRESULT( 572 ) +#define DDERR_NOPALETTEHW MAKE_DDHRESULT( 573 ) +#define DDERR_BLTFASTCANTCLIP MAKE_DDHRESULT( 574 ) +#define DDERR_NOBLTHW MAKE_DDHRESULT( 575 ) +#define DDERR_NODDROPSHW MAKE_DDHRESULT( 576 ) +#define DDERR_OVERLAYNOTVISIBLE MAKE_DDHRESULT( 577 ) +#define DDERR_NOOVERLAYDEST MAKE_DDHRESULT( 578 ) +#define DDERR_INVALIDPOSITION MAKE_DDHRESULT( 579 ) +#define DDERR_NOTAOVERLAYSURFACE MAKE_DDHRESULT( 580 ) +#define DDERR_EXCLUSIVEMODEALREADYSET MAKE_DDHRESULT( 581 ) +#define DDERR_NOTFLIPPABLE MAKE_DDHRESULT( 582 ) +#define DDERR_CANTDUPLICATE MAKE_DDHRESULT( 583 ) +#define DDERR_NOTLOCKED MAKE_DDHRESULT( 584 ) +#define DDERR_CANTCREATEDC MAKE_DDHRESULT( 585 ) +#define DDERR_NODC MAKE_DDHRESULT( 586 ) +#define DDERR_WRONGMODE MAKE_DDHRESULT( 587 ) +#define DDERR_IMPLICITLYCREATED MAKE_DDHRESULT( 588 ) +#define DDERR_NOTPALETTIZED MAKE_DDHRESULT( 589 ) +#define DDERR_UNSUPPORTEDMODE MAKE_DDHRESULT( 590 ) +#define DDERR_NOMIPMAPHW MAKE_DDHRESULT( 591 ) +#define DDERR_INVALIDSURFACETYPE MAKE_DDHRESULT( 592 ) +#define DDERR_NOOPTIMIZEHW MAKE_DDHRESULT( 600 ) +#define DDERR_NOTLOADED MAKE_DDHRESULT( 601 ) +#define DDERR_NOFOCUSWINDOW MAKE_DDHRESULT( 602 ) +#define DDERR_NOTONMIPMAPSUBLEVEL MAKE_DDHRESULT( 603 ) +#define DDERR_DCALREADYCREATED MAKE_DDHRESULT( 620 ) +#define DDERR_NONONLOCALVIDMEM MAKE_DDHRESULT( 630 ) +#define DDERR_CANTPAGELOCK MAKE_DDHRESULT( 640 ) +#define DDERR_CANTPAGEUNLOCK MAKE_DDHRESULT( 660 ) +#define DDERR_NOTPAGELOCKED MAKE_DDHRESULT( 680 ) +#define DDERR_MOREDATA MAKE_DDHRESULT( 690 ) +#define DDERR_EXPIRED MAKE_DDHRESULT( 691 ) +#define DDERR_TESTFINISHED MAKE_DDHRESULT( 692 ) +#define DDERR_NEWMODE MAKE_DDHRESULT( 693 ) +#define DDERR_D3DNOTINITIALIZED MAKE_DDHRESULT( 694 ) +#define DDERR_VIDEONOTACTIVE MAKE_DDHRESULT( 695 ) +#define DDERR_NOMONITORINFORMATION MAKE_DDHRESULT( 696 ) +#define DDERR_NODRIVERSUPPORT MAKE_DDHRESULT( 697 ) +#define DDERR_DEVICEDOESNTOWNSURFACE MAKE_DDHRESULT( 699 ) +#define DDERR_NOTINITIALIZED CO_E_NOTINITIALIZED + +/* dwFlags for Blt* */ +#define DDBLT_ALPHADEST 0x00000001 +#define DDBLT_ALPHADESTCONSTOVERRIDE 0x00000002 +#define DDBLT_ALPHADESTNEG 0x00000004 +#define DDBLT_ALPHADESTSURFACEOVERRIDE 0x00000008 +#define DDBLT_ALPHAEDGEBLEND 0x00000010 +#define DDBLT_ALPHASRC 0x00000020 +#define DDBLT_ALPHASRCCONSTOVERRIDE 0x00000040 +#define DDBLT_ALPHASRCNEG 0x00000080 +#define DDBLT_ALPHASRCSURFACEOVERRIDE 0x00000100 +#define DDBLT_ASYNC 0x00000200 +#define DDBLT_COLORFILL 0x00000400 +#define DDBLT_DDFX 0x00000800 +#define DDBLT_DDROPS 0x00001000 +#define DDBLT_KEYDEST 0x00002000 +#define DDBLT_KEYDESTOVERRIDE 0x00004000 +#define DDBLT_KEYSRC 0x00008000 +#define DDBLT_KEYSRCOVERRIDE 0x00010000 +#define DDBLT_ROP 0x00020000 +#define DDBLT_ROTATIONANGLE 0x00040000 +#define DDBLT_ZBUFFER 0x00080000 +#define DDBLT_ZBUFFERDESTCONSTOVERRIDE 0x00100000 +#define DDBLT_ZBUFFERDESTOVERRIDE 0x00200000 +#define DDBLT_ZBUFFERSRCCONSTOVERRIDE 0x00400000 +#define DDBLT_ZBUFFERSRCOVERRIDE 0x00800000 +#define DDBLT_WAIT 0x01000000 +#define DDBLT_DEPTHFILL 0x02000000 +#define DDBLT_DONOTWAIT 0x08000000 + +/* dwTrans for BltFast */ +#define DDBLTFAST_NOCOLORKEY 0x00000000 +#define DDBLTFAST_SRCCOLORKEY 0x00000001 +#define DDBLTFAST_DESTCOLORKEY 0x00000002 +#define DDBLTFAST_WAIT 0x00000010 +#define DDBLTFAST_DONOTWAIT 0x00000020 + +/* dwFlags for Flip */ +#define DDFLIP_WAIT 0x00000001 +#define DDFLIP_EVEN 0x00000002 /* only valid for overlay */ +#define DDFLIP_ODD 0x00000004 /* only valid for overlay */ +#define DDFLIP_NOVSYNC 0x00000008 +#define DDFLIP_STEREO 0x00000010 +#define DDFLIP_DONOTWAIT 0x00000020 + +/* dwFlags for GetBltStatus */ +#define DDGBS_CANBLT 0x00000001 +#define DDGBS_ISBLTDONE 0x00000002 + +/* dwFlags for IDirectDrawSurface7::GetFlipStatus */ +#define DDGFS_CANFLIP 1L +#define DDGFS_ISFLIPDONE 2L + +/* dwFlags for IDirectDrawSurface7::SetPrivateData */ +#define DDSPD_IUNKNOWNPTR 1L +#define DDSPD_VOLATILE 2L + +/* DDSCAPS.dwCaps */ +/* reserved1, was 3d capable */ +#define DDSCAPS_RESERVED1 0x00000001 +/* surface contains alpha information */ +#define DDSCAPS_ALPHA 0x00000002 +/* this surface is a backbuffer */ +#define DDSCAPS_BACKBUFFER 0x00000004 +/* complex surface structure */ +#define DDSCAPS_COMPLEX 0x00000008 +/* part of surface flipping structure */ +#define DDSCAPS_FLIP 0x00000010 +/* this surface is the frontbuffer surface */ +#define DDSCAPS_FRONTBUFFER 0x00000020 +/* this is a plain offscreen surface */ +#define DDSCAPS_OFFSCREENPLAIN 0x00000040 +/* overlay */ +#define DDSCAPS_OVERLAY 0x00000080 +/* palette objects can be created and attached to us */ +#define DDSCAPS_PALETTE 0x00000100 +/* primary surface (the one the user looks at currently)(right eye)*/ +#define DDSCAPS_PRIMARYSURFACE 0x00000200 +/* primary surface for left eye */ +#define DDSCAPS_PRIMARYSURFACELEFT 0x00000400 +/* surface exists in systemmemory */ +#define DDSCAPS_SYSTEMMEMORY 0x00000800 +/* surface can be used as a texture */ +#define DDSCAPS_TEXTURE 0x00001000 +/* surface may be destination for 3d rendering */ +#define DDSCAPS_3DDEVICE 0x00002000 +/* surface exists in videomemory */ +#define DDSCAPS_VIDEOMEMORY 0x00004000 +/* surface changes immediately visible */ +#define DDSCAPS_VISIBLE 0x00008000 +/* write only surface */ +#define DDSCAPS_WRITEONLY 0x00010000 +/* zbuffer surface */ +#define DDSCAPS_ZBUFFER 0x00020000 +/* has its own DC */ +#define DDSCAPS_OWNDC 0x00040000 +/* surface should be able to receive live video */ +#define DDSCAPS_LIVEVIDEO 0x00080000 +/* should be able to have a hw codec decompress stuff into it */ +#define DDSCAPS_HWCODEC 0x00100000 +/* mode X (320x200 or 320x240) surface */ +#define DDSCAPS_MODEX 0x00200000 +/* one mipmap surface (1 level) */ +#define DDSCAPS_MIPMAP 0x00400000 +#define DDSCAPS_RESERVED2 0x00800000 +/* memory allocation delayed until Load() */ +#define DDSCAPS_ALLOCONLOAD 0x04000000 +/* Indicates that the surface will receive data from a video port */ +#define DDSCAPS_VIDEOPORT 0x08000000 +/* surface is in local videomemory */ +#define DDSCAPS_LOCALVIDMEM 0x10000000 +/* surface is in nonlocal videomemory */ +#define DDSCAPS_NONLOCALVIDMEM 0x20000000 +/* surface is a standard VGA mode surface (NOT ModeX) */ +#define DDSCAPS_STANDARDVGAMODE 0x40000000 +/* optimized? surface */ +#define DDSCAPS_OPTIMIZED 0x80000000 + +typedef struct _DDSCAPS { + DWORD dwCaps; /* capabilities of surface wanted */ +} DDSCAPS,*LPDDSCAPS; + +/* DDSCAPS2.dwCaps2 */ +/* indicates the surface will receive data from a video port using + deinterlacing hardware. */ +#define DDSCAPS2_HARDWAREDEINTERLACE 0x00000002 +/* indicates the surface will be locked very frequently. */ +#define DDSCAPS2_HINTDYNAMIC 0x00000004 +/* indicates surface can be re-ordered or retiled on load() */ +#define DDSCAPS2_HINTSTATIC 0x00000008 +/* indicates surface to be managed by directdraw/direct3D */ +#define DDSCAPS2_TEXTUREMANAGE 0x00000010 +/* reserved bits */ +#define DDSCAPS2_RESERVED1 0x00000020 +#define DDSCAPS2_RESERVED2 0x00000040 +/* indicates surface will never be locked again */ +#define DDSCAPS2_OPAQUE 0x00000080 +/* set at CreateSurface() time to indicate antialising will be used */ +#define DDSCAPS2_HINTANTIALIASING 0x00000100 +/* set at CreateSurface() time to indicate cubic environment map */ +#define DDSCAPS2_CUBEMAP 0x00000200 +/* face flags for cube maps */ +#define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400 +#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800 +#define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000 +#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000 +#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000 +#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000 +/* specifies all faces of a cube for CreateSurface() */ +#define DDSCAPS2_CUBEMAP_ALLFACES ( DDSCAPS2_CUBEMAP_POSITIVEX |\ + DDSCAPS2_CUBEMAP_NEGATIVEX |\ + DDSCAPS2_CUBEMAP_POSITIVEY |\ + DDSCAPS2_CUBEMAP_NEGATIVEY |\ + DDSCAPS2_CUBEMAP_POSITIVEZ |\ + DDSCAPS2_CUBEMAP_NEGATIVEZ ) +/* set for mipmap sublevels on DirectX7 and later. ignored by CreateSurface() */ +#define DDSCAPS2_MIPMAPSUBLEVEL 0x00010000 +/* indicates texture surface to be managed by Direct3D *only* */ +#define DDSCAPS2_D3DTEXTUREMANAGE 0x00020000 +/* indicates managed surface that can safely be lost */ +#define DDSCAPS2_DONOTPERSIST 0x00040000 +/* indicates surface is part of a stereo flipping chain */ +#define DDSCAPS2_STEREOSURFACELEFT 0x00080000 + +typedef struct _DDSCAPS2 { + DWORD dwCaps; /* capabilities of surface wanted */ + DWORD dwCaps2; /* additional capabilities */ + DWORD dwCaps3; /* reserved capabilities */ + DWORD dwCaps4; /* more reserved capabilities */ +} DDSCAPS2,*LPDDSCAPS2; + +#define DD_ROP_SPACE (256/32) /* space required to store ROP array */ + +typedef struct _DDCAPS_DX7 /* DirectX 7 version of caps struct */ +{ + DWORD dwSize; /* size of the DDDRIVERCAPS structure */ + DWORD dwCaps; /* driver specific capabilities */ + DWORD dwCaps2; /* more driver specific capabilites */ + DWORD dwCKeyCaps; /* color key capabilities of the surface */ + DWORD dwFXCaps; /* driver specific stretching and effects capabilites */ + DWORD dwFXAlphaCaps; /* alpha driver specific capabilities */ + DWORD dwPalCaps; /* palette capabilities */ + DWORD dwSVCaps; /* stereo vision capabilities */ + DWORD dwAlphaBltConstBitDepths; /* DDBD_2,4,8 */ + DWORD dwAlphaBltPixelBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaBltSurfaceBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaOverlayConstBitDepths; /* DDBD_2,4,8 */ + DWORD dwAlphaOverlayPixelBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwZBufferBitDepths; /* DDBD_8,16,24,32 */ + DWORD dwVidMemTotal; /* total amount of video memory */ + DWORD dwVidMemFree; /* amount of free video memory */ + DWORD dwMaxVisibleOverlays; /* maximum number of visible overlays */ + DWORD dwCurrVisibleOverlays; /* current number of visible overlays */ + DWORD dwNumFourCCCodes; /* number of four cc codes */ + DWORD dwAlignBoundarySrc; /* source rectangle alignment */ + DWORD dwAlignSizeSrc; /* source rectangle byte size */ + DWORD dwAlignBoundaryDest; /* dest rectangle alignment */ + DWORD dwAlignSizeDest; /* dest rectangle byte size */ + DWORD dwAlignStrideAlign; /* stride alignment */ + DWORD dwRops[DD_ROP_SPACE]; /* ROPS supported */ + DDSCAPS ddsOldCaps; /* old DDSCAPS - superceded for DirectX6+ */ + DWORD dwMinOverlayStretch; /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxOverlayStretch; /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMinLiveVideoStretch; /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxLiveVideoStretch; /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMinHwCodecStretch; /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxHwCodecStretch; /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwReserved1; + DWORD dwReserved2; + DWORD dwReserved3; + DWORD dwSVBCaps; /* driver specific capabilities for System->Vmem blts */ + DWORD dwSVBCKeyCaps; /* driver color key capabilities for System->Vmem blts */ + DWORD dwSVBFXCaps; /* driver FX capabilities for System->Vmem blts */ + DWORD dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */ + DWORD dwVSBCaps; /* driver specific capabilities for Vmem->System blts */ + DWORD dwVSBCKeyCaps; /* driver color key capabilities for Vmem->System blts */ + DWORD dwVSBFXCaps; /* driver FX capabilities for Vmem->System blts */ + DWORD dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */ + DWORD dwSSBCaps; /* driver specific capabilities for System->System blts */ + DWORD dwSSBCKeyCaps; /* driver color key capabilities for System->System blts */ + DWORD dwSSBFXCaps; /* driver FX capabilities for System->System blts */ + DWORD dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */ + DWORD dwMaxVideoPorts; /* maximum number of usable video ports */ + DWORD dwCurrVideoPorts; /* current number of video ports used */ + DWORD dwSVBCaps2; /* more driver specific capabilities for System->Vmem blts */ + DWORD dwNLVBCaps; /* driver specific capabilities for non-local->local vidmem blts */ + DWORD dwNLVBCaps2; /* more driver specific capabilities non-local->local vidmem blts */ + DWORD dwNLVBCKeyCaps; /* driver color key capabilities for non-local->local vidmem blts */ + DWORD dwNLVBFXCaps; /* driver FX capabilities for non-local->local blts */ + DWORD dwNLVBRops[DD_ROP_SPACE]; /* ROPS supported for non-local->local blts */ + DDSCAPS2 ddsCaps; /* surface capabilities */ +} DDCAPS_DX7,*LPDDCAPS_DX7; + +typedef struct _DDCAPS_DX6 /* DirectX 6 version of caps struct */ +{ + DWORD dwSize; /* size of the DDDRIVERCAPS structure */ + DWORD dwCaps; /* driver specific capabilities */ + DWORD dwCaps2; /* more driver specific capabilites */ + DWORD dwCKeyCaps; /* color key capabilities of the surface */ + DWORD dwFXCaps; /* driver specific stretching and effects capabilites */ + DWORD dwFXAlphaCaps; /* alpha driver specific capabilities */ + DWORD dwPalCaps; /* palette capabilities */ + DWORD dwSVCaps; /* stereo vision capabilities */ + DWORD dwAlphaBltConstBitDepths; /* DDBD_2,4,8 */ + DWORD dwAlphaBltPixelBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaBltSurfaceBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaOverlayConstBitDepths; /* DDBD_2,4,8 */ + DWORD dwAlphaOverlayPixelBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwZBufferBitDepths; /* DDBD_8,16,24,32 */ + DWORD dwVidMemTotal; /* total amount of video memory */ + DWORD dwVidMemFree; /* amount of free video memory */ + DWORD dwMaxVisibleOverlays; /* maximum number of visible overlays */ + DWORD dwCurrVisibleOverlays; /* current number of visible overlays */ + DWORD dwNumFourCCCodes; /* number of four cc codes */ + DWORD dwAlignBoundarySrc; /* source rectangle alignment */ + DWORD dwAlignSizeSrc; /* source rectangle byte size */ + DWORD dwAlignBoundaryDest; /* dest rectangle alignment */ + DWORD dwAlignSizeDest; /* dest rectangle byte size */ + DWORD dwAlignStrideAlign; /* stride alignment */ + DWORD dwRops[DD_ROP_SPACE]; /* ROPS supported */ + DDSCAPS ddsOldCaps; /* old DDSCAPS - superceded for DirectX6+ */ + DWORD dwMinOverlayStretch; /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxOverlayStretch; /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMinLiveVideoStretch; /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxLiveVideoStretch; /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMinHwCodecStretch; /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxHwCodecStretch; /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwReserved1; + DWORD dwReserved2; + DWORD dwReserved3; + DWORD dwSVBCaps; /* driver specific capabilities for System->Vmem blts */ + DWORD dwSVBCKeyCaps; /* driver color key capabilities for System->Vmem blts */ + DWORD dwSVBFXCaps; /* driver FX capabilities for System->Vmem blts */ + DWORD dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */ + DWORD dwVSBCaps; /* driver specific capabilities for Vmem->System blts */ + DWORD dwVSBCKeyCaps; /* driver color key capabilities for Vmem->System blts */ + DWORD dwVSBFXCaps; /* driver FX capabilities for Vmem->System blts */ + DWORD dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */ + DWORD dwSSBCaps; /* driver specific capabilities for System->System blts */ + DWORD dwSSBCKeyCaps; /* driver color key capabilities for System->System blts */ + DWORD dwSSBFXCaps; /* driver FX capabilities for System->System blts */ + DWORD dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */ + DWORD dwMaxVideoPorts; /* maximum number of usable video ports */ + DWORD dwCurrVideoPorts; /* current number of video ports used */ + DWORD dwSVBCaps2; /* more driver specific capabilities for System->Vmem blts */ + DWORD dwNLVBCaps; /* driver specific capabilities for non-local->local vidmem blts */ + DWORD dwNLVBCaps2; /* more driver specific capabilities non-local->local vidmem blts */ + DWORD dwNLVBCKeyCaps; /* driver color key capabilities for non-local->local vidmem blts */ + DWORD dwNLVBFXCaps; /* driver FX capabilities for non-local->local blts */ + DWORD dwNLVBRops[DD_ROP_SPACE]; /* ROPS supported for non-local->local blts */ + /* and one new member for DirectX 6 */ + DDSCAPS2 ddsCaps; /* surface capabilities */ +} DDCAPS_DX6,*LPDDCAPS_DX6; + +typedef struct _DDCAPS_DX5 /* DirectX5 version of caps struct */ +{ + DWORD dwSize; /* size of the DDDRIVERCAPS structure */ + DWORD dwCaps; /* driver specific capabilities */ + DWORD dwCaps2; /* more driver specific capabilites */ + DWORD dwCKeyCaps; /* color key capabilities of the surface */ + DWORD dwFXCaps; /* driver specific stretching and effects capabilites */ + DWORD dwFXAlphaCaps; /* alpha driver specific capabilities */ + DWORD dwPalCaps; /* palette capabilities */ + DWORD dwSVCaps; /* stereo vision capabilities */ + DWORD dwAlphaBltConstBitDepths; /* DDBD_2,4,8 */ + DWORD dwAlphaBltPixelBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaBltSurfaceBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaOverlayConstBitDepths; /* DDBD_2,4,8 */ + DWORD dwAlphaOverlayPixelBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwZBufferBitDepths; /* DDBD_8,16,24,32 */ + DWORD dwVidMemTotal; /* total amount of video memory */ + DWORD dwVidMemFree; /* amount of free video memory */ + DWORD dwMaxVisibleOverlays; /* maximum number of visible overlays */ + DWORD dwCurrVisibleOverlays; /* current number of visible overlays */ + DWORD dwNumFourCCCodes; /* number of four cc codes */ + DWORD dwAlignBoundarySrc; /* source rectangle alignment */ + DWORD dwAlignSizeSrc; /* source rectangle byte size */ + DWORD dwAlignBoundaryDest; /* dest rectangle alignment */ + DWORD dwAlignSizeDest; /* dest rectangle byte size */ + DWORD dwAlignStrideAlign; /* stride alignment */ + DWORD dwRops[DD_ROP_SPACE]; /* ROPS supported */ + DDSCAPS ddsCaps; /* DDSCAPS structure has all the general capabilities */ + DWORD dwMinOverlayStretch; /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxOverlayStretch; /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMinLiveVideoStretch; /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxLiveVideoStretch; /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMinHwCodecStretch; /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxHwCodecStretch; /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwReserved1; + DWORD dwReserved2; + DWORD dwReserved3; + DWORD dwSVBCaps; /* driver specific capabilities for System->Vmem blts */ + DWORD dwSVBCKeyCaps; /* driver color key capabilities for System->Vmem blts */ + DWORD dwSVBFXCaps; /* driver FX capabilities for System->Vmem blts */ + DWORD dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */ + DWORD dwVSBCaps; /* driver specific capabilities for Vmem->System blts */ + DWORD dwVSBCKeyCaps; /* driver color key capabilities for Vmem->System blts */ + DWORD dwVSBFXCaps; /* driver FX capabilities for Vmem->System blts */ + DWORD dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */ + DWORD dwSSBCaps; /* driver specific capabilities for System->System blts */ + DWORD dwSSBCKeyCaps; /* driver color key capabilities for System->System blts */ + DWORD dwSSBFXCaps; /* driver FX capabilities for System->System blts */ + DWORD dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */ + /* the following are the new DirectX 5 members */ + DWORD dwMaxVideoPorts; /* maximum number of usable video ports */ + DWORD dwCurrVideoPorts; /* current number of video ports used */ + DWORD dwSVBCaps2; /* more driver specific capabilities for System->Vmem blts */ + DWORD dwNLVBCaps; /* driver specific capabilities for non-local->local vidmem blts */ + DWORD dwNLVBCaps2; /* more driver specific capabilities non-local->local vidmem blts */ + DWORD dwNLVBCKeyCaps; /* driver color key capabilities for non-local->local vidmem blts */ + DWORD dwNLVBFXCaps; /* driver FX capabilities for non-local->local blts */ + DWORD dwNLVBRops[DD_ROP_SPACE]; /* ROPS supported for non-local->local blts */ +} DDCAPS_DX5,*LPDDCAPS_DX5; + +typedef struct _DDCAPS_DX3 /* DirectX3 version of caps struct */ +{ + DWORD dwSize; /* size of the DDDRIVERCAPS structure */ + DWORD dwCaps; /* driver specific capabilities */ + DWORD dwCaps2; /* more driver specific capabilites */ + DWORD dwCKeyCaps; /* color key capabilities of the surface */ + DWORD dwFXCaps; /* driver specific stretching and effects capabilites */ + DWORD dwFXAlphaCaps; /* alpha driver specific capabilities */ + DWORD dwPalCaps; /* palette capabilities */ + DWORD dwSVCaps; /* stereo vision capabilities */ + DWORD dwAlphaBltConstBitDepths; /* DDBD_2,4,8 */ + DWORD dwAlphaBltPixelBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaBltSurfaceBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaOverlayConstBitDepths; /* DDBD_2,4,8 */ + DWORD dwAlphaOverlayPixelBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwZBufferBitDepths; /* DDBD_8,16,24,32 */ + DWORD dwVidMemTotal; /* total amount of video memory */ + DWORD dwVidMemFree; /* amount of free video memory */ + DWORD dwMaxVisibleOverlays; /* maximum number of visible overlays */ + DWORD dwCurrVisibleOverlays; /* current number of visible overlays */ + DWORD dwNumFourCCCodes; /* number of four cc codes */ + DWORD dwAlignBoundarySrc; /* source rectangle alignment */ + DWORD dwAlignSizeSrc; /* source rectangle byte size */ + DWORD dwAlignBoundaryDest; /* dest rectangle alignment */ + DWORD dwAlignSizeDest; /* dest rectangle byte size */ + DWORD dwAlignStrideAlign; /* stride alignment */ + DWORD dwRops[DD_ROP_SPACE]; /* ROPS supported */ + DDSCAPS ddsCaps; /* DDSCAPS structure has all the general capabilities */ + DWORD dwMinOverlayStretch; /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxOverlayStretch; /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMinLiveVideoStretch; /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxLiveVideoStretch; /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMinHwCodecStretch; /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxHwCodecStretch; /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwReserved1; + DWORD dwReserved2; + DWORD dwReserved3; + DWORD dwSVBCaps; /* driver specific capabilities for System->Vmem blts */ + DWORD dwSVBCKeyCaps; /* driver color key capabilities for System->Vmem blts */ + DWORD dwSVBFXCaps; /* driver FX capabilities for System->Vmem blts */ + DWORD dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */ + DWORD dwVSBCaps; /* driver specific capabilities for Vmem->System blts */ + DWORD dwVSBCKeyCaps; /* driver color key capabilities for Vmem->System blts */ + DWORD dwVSBFXCaps; /* driver FX capabilities for Vmem->System blts */ + DWORD dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */ + DWORD dwSSBCaps; /* driver specific capabilities for System->System blts */ + DWORD dwSSBCKeyCaps; /* driver color key capabilities for System->System blts */ + DWORD dwSSBFXCaps; /* driver FX capabilities for System->System blts */ + DWORD dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */ + DWORD dwReserved4; + DWORD dwReserved5; + DWORD dwReserved6; +} DDCAPS_DX3,*LPDDCAPS_DX3; + +/* set caps struct according to DIRECTDRAW_VERSION */ + +#if DIRECTDRAW_VERSION <= 0x300 +typedef DDCAPS_DX3 DDCAPS; +#elif DIRECTDRAW_VERSION <= 0x500 +typedef DDCAPS_DX5 DDCAPS; +#elif DIRECTDRAW_VERSION <= 0x600 +typedef DDCAPS_DX6 DDCAPS; +#else +typedef DDCAPS_DX7 DDCAPS; +#endif + +typedef DDCAPS *LPDDCAPS; + +/* DDCAPS.dwCaps */ +#define DDCAPS_3D 0x00000001 +#define DDCAPS_ALIGNBOUNDARYDEST 0x00000002 +#define DDCAPS_ALIGNSIZEDEST 0x00000004 +#define DDCAPS_ALIGNBOUNDARYSRC 0x00000008 +#define DDCAPS_ALIGNSIZESRC 0x00000010 +#define DDCAPS_ALIGNSTRIDE 0x00000020 +#define DDCAPS_BLT 0x00000040 +#define DDCAPS_BLTQUEUE 0x00000080 +#define DDCAPS_BLTFOURCC 0x00000100 +#define DDCAPS_BLTSTRETCH 0x00000200 +#define DDCAPS_GDI 0x00000400 +#define DDCAPS_OVERLAY 0x00000800 +#define DDCAPS_OVERLAYCANTCLIP 0x00001000 +#define DDCAPS_OVERLAYFOURCC 0x00002000 +#define DDCAPS_OVERLAYSTRETCH 0x00004000 +#define DDCAPS_PALETTE 0x00008000 +#define DDCAPS_PALETTEVSYNC 0x00010000 +#define DDCAPS_READSCANLINE 0x00020000 +#define DDCAPS_STEREOVIEW 0x00040000 +#define DDCAPS_VBI 0x00080000 +#define DDCAPS_ZBLTS 0x00100000 +#define DDCAPS_ZOVERLAYS 0x00200000 +#define DDCAPS_COLORKEY 0x00400000 +#define DDCAPS_ALPHA 0x00800000 +#define DDCAPS_COLORKEYHWASSIST 0x01000000 +#define DDCAPS_NOHARDWARE 0x02000000 +#define DDCAPS_BLTCOLORFILL 0x04000000 +#define DDCAPS_BANKSWITCHED 0x08000000 +#define DDCAPS_BLTDEPTHFILL 0x10000000 +#define DDCAPS_CANCLIP 0x20000000 +#define DDCAPS_CANCLIPSTRETCHED 0x40000000 +#define DDCAPS_CANBLTSYSMEM 0x80000000 + +/* DDCAPS.dwCaps2 */ +#define DDCAPS2_CERTIFIED 0x00000001 +#define DDCAPS2_NO2DDURING3DSCENE 0x00000002 +#define DDCAPS2_VIDEOPORT 0x00000004 +#define DDCAPS2_AUTOFLIPOVERLAY 0x00000008 +#define DDCAPS2_CANBOBINTERLEAVED 0x00000010 +#define DDCAPS2_CANBOBNONINTERLEAVED 0x00000020 +#define DDCAPS2_COLORCONTROLOVERLAY 0x00000040 +#define DDCAPS2_COLORCONTROLPRIMARY 0x00000080 +#define DDCAPS2_CANDROPZ16BIT 0x00000100 +#define DDCAPS2_NONLOCALVIDMEM 0x00000200 +#define DDCAPS2_NONLOCALVIDMEMCAPS 0x00000400 +#define DDCAPS2_NOPAGELOCKREQUIRED 0x00000800 +#define DDCAPS2_WIDESURFACES 0x00001000 +#define DDCAPS2_CANFLIPODDEVEN 0x00002000 +#define DDCAPS2_CANBOBHARDWARE 0x00004000 +#define DDCAPS2_COPYFOURCC 0x00008000 +#define DDCAPS2_PRIMARYGAMMA 0x00020000 +#define DDCAPS2_CANRENDERWINDOWED 0x00080000 +#define DDCAPS2_CANCALIBRATEGAMMA 0x00100000 +#define DDCAPS2_FLIPINTERVAL 0x00200000 +#define DDCAPS2_FLIPNOVSYNC 0x00400000 +#define DDCAPS2_CANMANAGETEXTURE 0x00800000 +#define DDCAPS2_TEXMANINNONLOCALVIDMEM 0x01000000 +#define DDCAPS2_STEREO 0x02000000 +#define DDCAPS2_SYSTONONLOCAL_AS_SYSTOLOCAL 0x04000000 + + +/* Set/Get Colour Key Flags */ +#define DDCKEY_COLORSPACE 0x00000001 /* Struct is single colour space */ +#define DDCKEY_DESTBLT 0x00000002 /* To be used as dest for blt */ +#define DDCKEY_DESTOVERLAY 0x00000004 /* To be used as dest for CK overlays */ +#define DDCKEY_SRCBLT 0x00000008 /* To be used as src for blt */ +#define DDCKEY_SRCOVERLAY 0x00000010 /* To be used as src for CK overlays */ + +typedef struct _DDCOLORKEY +{ + DWORD dwColorSpaceLowValue;/* low boundary of color space that is to + * be treated as Color Key, inclusive + */ + DWORD dwColorSpaceHighValue;/* high boundary of color space that is + * to be treated as Color Key, inclusive + */ +} DDCOLORKEY,*LPDDCOLORKEY; + +/* ddCKEYCAPS bits */ +#define DDCKEYCAPS_DESTBLT 0x00000001 +#define DDCKEYCAPS_DESTBLTCLRSPACE 0x00000002 +#define DDCKEYCAPS_DESTBLTCLRSPACEYUV 0x00000004 +#define DDCKEYCAPS_DESTBLTYUV 0x00000008 +#define DDCKEYCAPS_DESTOVERLAY 0x00000010 +#define DDCKEYCAPS_DESTOVERLAYCLRSPACE 0x00000020 +#define DDCKEYCAPS_DESTOVERLAYCLRSPACEYUV 0x00000040 +#define DDCKEYCAPS_DESTOVERLAYONEACTIVE 0x00000080 +#define DDCKEYCAPS_DESTOVERLAYYUV 0x00000100 +#define DDCKEYCAPS_SRCBLT 0x00000200 +#define DDCKEYCAPS_SRCBLTCLRSPACE 0x00000400 +#define DDCKEYCAPS_SRCBLTCLRSPACEYUV 0x00000800 +#define DDCKEYCAPS_SRCBLTYUV 0x00001000 +#define DDCKEYCAPS_SRCOVERLAY 0x00002000 +#define DDCKEYCAPS_SRCOVERLAYCLRSPACE 0x00004000 +#define DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV 0x00008000 +#define DDCKEYCAPS_SRCOVERLAYONEACTIVE 0x00010000 +#define DDCKEYCAPS_SRCOVERLAYYUV 0x00020000 +#define DDCKEYCAPS_NOCOSTOVERLAY 0x00040000 + +typedef struct _DDPIXELFORMAT { + DWORD dwSize; /* 0: size of structure */ + DWORD dwFlags; /* 4: pixel format flags */ + DWORD dwFourCC; /* 8: (FOURCC code) */ + union { + DWORD dwRGBBitCount; /* C: how many bits per pixel */ + DWORD dwYUVBitCount; /* C: how many bits per pixel */ + DWORD dwZBufferBitDepth; /* C: how many bits for z buffers */ + DWORD dwAlphaBitDepth; /* C: how many bits for alpha channels*/ + DWORD dwLuminanceBitCount; + DWORD dwBumpBitCount; + } DUMMYUNIONNAME1; + union { + DWORD dwRBitMask; /* 10: mask for red bit*/ + DWORD dwYBitMask; /* 10: mask for Y bits*/ + DWORD dwStencilBitDepth; + DWORD dwLuminanceBitMask; + DWORD dwBumpDuBitMask; + } DUMMYUNIONNAME2; + union { + DWORD dwGBitMask; /* 14: mask for green bits*/ + DWORD dwUBitMask; /* 14: mask for U bits*/ + DWORD dwZBitMask; + DWORD dwBumpDvBitMask; + } DUMMYUNIONNAME3; + union { + DWORD dwBBitMask; /* 18: mask for blue bits*/ + DWORD dwVBitMask; /* 18: mask for V bits*/ + DWORD dwStencilBitMask; + DWORD dwBumpLuminanceBitMask; + } DUMMYUNIONNAME4; + union { + DWORD dwRGBAlphaBitMask; /* 1C: mask for alpha channel */ + DWORD dwYUVAlphaBitMask; /* 1C: mask for alpha channel */ + DWORD dwLuminanceAlphaBitMask; + DWORD dwRGBZBitMask; /* 1C: mask for Z channel */ + DWORD dwYUVZBitMask; /* 1C: mask for Z channel */ + } DUMMYUNIONNAME5; + /* 20: next structure */ +} DDPIXELFORMAT,*LPDDPIXELFORMAT; + +/* DDCAPS.dwFXCaps */ +#define DDFXCAPS_BLTALPHA 0x00000001 +#define DDFXCAPS_OVERLAYALPHA 0x00000004 +#define DDFXCAPS_BLTARITHSTRETCHYN 0x00000010 +#define DDFXCAPS_BLTARITHSTRETCHY 0x00000020 +#define DDFXCAPS_BLTMIRRORLEFTRIGHT 0x00000040 +#define DDFXCAPS_BLTMIRRORUPDOWN 0x00000080 +#define DDFXCAPS_BLTROTATION 0x00000100 +#define DDFXCAPS_BLTROTATION90 0x00000200 +#define DDFXCAPS_BLTSHRINKX 0x00000400 +#define DDFXCAPS_BLTSHRINKXN 0x00000800 +#define DDFXCAPS_BLTSHRINKY 0x00001000 +#define DDFXCAPS_BLTSHRINKYN 0x00002000 +#define DDFXCAPS_BLTSTRETCHX 0x00004000 +#define DDFXCAPS_BLTSTRETCHXN 0x00008000 +#define DDFXCAPS_BLTSTRETCHY 0x00010000 +#define DDFXCAPS_BLTSTRETCHYN 0x00020000 +#define DDFXCAPS_OVERLAYARITHSTRETCHY 0x00040000 +#define DDFXCAPS_OVERLAYARITHSTRETCHYN 0x00000008 +#define DDFXCAPS_OVERLAYSHRINKX 0x00080000 +#define DDFXCAPS_OVERLAYSHRINKXN 0x00100000 +#define DDFXCAPS_OVERLAYSHRINKY 0x00200000 +#define DDFXCAPS_OVERLAYSHRINKYN 0x00400000 +#define DDFXCAPS_OVERLAYSTRETCHX 0x00800000 +#define DDFXCAPS_OVERLAYSTRETCHXN 0x01000000 +#define DDFXCAPS_OVERLAYSTRETCHY 0x02000000 +#define DDFXCAPS_OVERLAYSTRETCHYN 0x04000000 +#define DDFXCAPS_OVERLAYMIRRORLEFTRIGHT 0x08000000 +#define DDFXCAPS_OVERLAYMIRRORUPDOWN 0x10000000 + +#define DDFXCAPS_OVERLAYFILTER DDFXCAPS_OVERLAYARITHSTRETCHY + +/* DDCAPS.dwFXAlphaCaps */ +#define DDFXALPHACAPS_BLTALPHAEDGEBLEND 0x00000001 +#define DDFXALPHACAPS_BLTALPHAPIXELS 0x00000002 +#define DDFXALPHACAPS_BLTALPHAPIXELSNEG 0x00000004 +#define DDFXALPHACAPS_BLTALPHASURFACES 0x00000008 +#define DDFXALPHACAPS_BLTALPHASURFACESNEG 0x00000010 +#define DDFXALPHACAPS_OVERLAYALPHAEDGEBLEND 0x00000020 +#define DDFXALPHACAPS_OVERLAYALPHAPIXELS 0x00000040 +#define DDFXALPHACAPS_OVERLAYALPHAPIXELSNEG 0x00000080 +#define DDFXALPHACAPS_OVERLAYALPHASURFACES 0x00000100 +#define DDFXALPHACAPS_OVERLAYALPHASURFACESNEG 0x00000200 + +/* DDCAPS.dwPalCaps */ +#define DDPCAPS_4BIT 0x00000001 +#define DDPCAPS_8BITENTRIES 0x00000002 +#define DDPCAPS_8BIT 0x00000004 +#define DDPCAPS_INITIALIZE 0x00000008 +#define DDPCAPS_PRIMARYSURFACE 0x00000010 +#define DDPCAPS_PRIMARYSURFACELEFT 0x00000020 +#define DDPCAPS_ALLOW256 0x00000040 +#define DDPCAPS_VSYNC 0x00000080 +#define DDPCAPS_1BIT 0x00000100 +#define DDPCAPS_2BIT 0x00000200 +#define DDPCAPS_ALPHA 0x00000400 + +/* DDCAPS.dwSVCaps */ +/* the first 4 of these are now obsolete */ +#if DIRECTDRAW_VERSION >= 0x700 /* FIXME: I'm not sure when this switch occured */ +#define DDSVCAPS_RESERVED1 0x00000001 +#define DDSVCAPS_RESERVED2 0x00000002 +#define DDSVCAPS_RESERVED3 0x00000004 +#define DDSVCAPS_RESERVED4 0x00000008 +#else +#define DDSVCAPS_ENIGMA 0x00000001 +#define DDSVCAPS_FLICKER 0x00000002 +#define DDSVCAPS_REDBLUE 0x00000004 +#define DDSVCAPS_SPLIT 0x00000008 +#endif +#define DDSVCAPS_STEREOSEQUENTIAL 0x00000010 + +/* BitDepths */ +#define DDBD_1 0x00004000 +#define DDBD_2 0x00002000 +#define DDBD_4 0x00001000 +#define DDBD_8 0x00000800 +#define DDBD_16 0x00000400 +#define DDBD_24 0x00000200 +#define DDBD_32 0x00000100 + +/* DDOVERLAYFX.dwDDFX */ +#define DDOVERFX_ARITHSTRETCHY 0x00000001 +#define DDOVERFX_MIRRORLEFTRIGHT 0x00000002 +#define DDOVERFX_MIRRORUPDOWN 0x00000004 + +/* UpdateOverlay flags */ +#define DDOVER_ALPHADEST 0x00000001 +#define DDOVER_ALPHADESTCONSTOVERRIDE 0x00000002 +#define DDOVER_ALPHADESTNEG 0x00000004 +#define DDOVER_ALPHADESTSURFACEOVERRIDE 0x00000008 +#define DDOVER_ALPHAEDGEBLEND 0x00000010 +#define DDOVER_ALPHASRC 0x00000020 +#define DDOVER_ALPHASRCCONSTOVERRIDE 0x00000040 +#define DDOVER_ALPHASRCNEG 0x00000080 +#define DDOVER_ALPHASRCSURFACEOVERRIDE 0x00000100 +#define DDOVER_HIDE 0x00000200 +#define DDOVER_KEYDEST 0x00000400 +#define DDOVER_KEYDESTOVERRIDE 0x00000800 +#define DDOVER_KEYSRC 0x00001000 +#define DDOVER_KEYSRCOVERRIDE 0x00002000 +#define DDOVER_SHOW 0x00004000 +#define DDOVER_ADDDIRTYRECT 0x00008000 +#define DDOVER_REFRESHDIRTYRECTS 0x00010000 +#define DDOVER_REFRESHALL 0x00020000 +#define DDOVER_DDFX 0x00080000 +#define DDOVER_AUTOFLIP 0x00100000 +#define DDOVER_BOB 0x00200000 +#define DDOVER_OVERRIDEBOBWEAVE 0x00400000 +#define DDOVER_INTERLEAVED 0x00800000 + +/* DDCOLORKEY.dwFlags */ +#define DDPF_ALPHAPIXELS 0x00000001 +#define DDPF_ALPHA 0x00000002 +#define DDPF_FOURCC 0x00000004 +#define DDPF_PALETTEINDEXED4 0x00000008 +#define DDPF_PALETTEINDEXEDTO8 0x00000010 +#define DDPF_PALETTEINDEXED8 0x00000020 +#define DDPF_RGB 0x00000040 +#define DDPF_COMPRESSED 0x00000080 +#define DDPF_RGBTOYUV 0x00000100 +#define DDPF_YUV 0x00000200 +#define DDPF_ZBUFFER 0x00000400 +#define DDPF_PALETTEINDEXED1 0x00000800 +#define DDPF_PALETTEINDEXED2 0x00001000 +#define DDPF_ZPIXELS 0x00002000 +#define DDPF_STENCILBUFFER 0x00004000 +#define DDPF_ALPHAPREMULT 0x00008000 +#define DDPF_LUMINANCE 0x00020000 +#define DDPF_BUMPLUMINANCE 0x00040000 +#define DDPF_BUMPDUDV 0x00080000 + +/* SetCooperativeLevel dwFlags */ +#define DDSCL_FULLSCREEN 0x00000001 +#define DDSCL_ALLOWREBOOT 0x00000002 +#define DDSCL_NOWINDOWCHANGES 0x00000004 +#define DDSCL_NORMAL 0x00000008 +#define DDSCL_EXCLUSIVE 0x00000010 +#define DDSCL_ALLOWMODEX 0x00000040 +#define DDSCL_SETFOCUSWINDOW 0x00000080 +#define DDSCL_SETDEVICEWINDOW 0x00000100 +#define DDSCL_CREATEDEVICEWINDOW 0x00000200 +#define DDSCL_MULTITHREADED 0x00000400 +#define DDSCL_FPUSETUP 0x00000800 +#define DDSCL_FPUPRESERVE 0x00001000 + + +/* DDSURFACEDESC.dwFlags */ +#define DDSD_CAPS 0x00000001 +#define DDSD_HEIGHT 0x00000002 +#define DDSD_WIDTH 0x00000004 +#define DDSD_PITCH 0x00000008 +#define DDSD_BACKBUFFERCOUNT 0x00000020 +#define DDSD_ZBUFFERBITDEPTH 0x00000040 +#define DDSD_ALPHABITDEPTH 0x00000080 +#define DDSD_LPSURFACE 0x00000800 +#define DDSD_PIXELFORMAT 0x00001000 +#define DDSD_CKDESTOVERLAY 0x00002000 +#define DDSD_CKDESTBLT 0x00004000 +#define DDSD_CKSRCOVERLAY 0x00008000 +#define DDSD_CKSRCBLT 0x00010000 +#define DDSD_MIPMAPCOUNT 0x00020000 +#define DDSD_REFRESHRATE 0x00040000 +#define DDSD_LINEARSIZE 0x00080000 +#define DDSD_TEXTURESTAGE 0x00100000 +#define DDSD_FVF 0x00200000 +#define DDSD_SRCVBHANDLE 0x00400000 +#define DDSD_ALL 0x007ff9ee + +/* EnumSurfaces flags */ +#define DDENUMSURFACES_ALL 0x00000001 +#define DDENUMSURFACES_MATCH 0x00000002 +#define DDENUMSURFACES_NOMATCH 0x00000004 +#define DDENUMSURFACES_CANBECREATED 0x00000008 +#define DDENUMSURFACES_DOESEXIST 0x00000010 + +/* SetDisplayMode flags */ +#define DDSDM_STANDARDVGAMODE 0x00000001 + +/* EnumDisplayModes flags */ +#define DDEDM_REFRESHRATES 0x00000001 +#define DDEDM_STANDARDVGAMODES 0x00000002 + +/* WaitForVerticalDisplay flags */ + +#define DDWAITVB_BLOCKBEGIN 0x00000001 +#define DDWAITVB_BLOCKBEGINEVENT 0x00000002 +#define DDWAITVB_BLOCKEND 0x00000004 + +typedef struct _DDSURFACEDESC +{ + DWORD dwSize; /* 0: size of the DDSURFACEDESC structure*/ + DWORD dwFlags; /* 4: determines what fields are valid*/ + DWORD dwHeight; /* 8: height of surface to be created*/ + DWORD dwWidth; /* C: width of input surface*/ + union { + LONG lPitch; /* 10: distance to start of next line (return value only)*/ + DWORD dwLinearSize; + } DUMMYUNIONNAME1; + DWORD dwBackBufferCount;/* 14: number of back buffers requested*/ + union { + DWORD dwMipMapCount;/* 18:number of mip-map levels requested*/ + DWORD dwZBufferBitDepth;/*18: depth of Z buffer requested*/ + DWORD dwRefreshRate;/* 18:refresh rate (used when display mode is described)*/ + } DUMMYUNIONNAME2; + DWORD dwAlphaBitDepth;/* 1C:depth of alpha buffer requested*/ + DWORD dwReserved; /* 20:reserved*/ + LPVOID lpSurface; /* 24:pointer to the associated surface memory*/ + DDCOLORKEY ddckCKDestOverlay;/* 28: CK for dest overlay use*/ + DDCOLORKEY ddckCKDestBlt; /* 30: CK for destination blt use*/ + DDCOLORKEY ddckCKSrcOverlay;/* 38: CK for source overlay use*/ + DDCOLORKEY ddckCKSrcBlt; /* 40: CK for source blt use*/ + DDPIXELFORMAT ddpfPixelFormat;/* 48: pixel format description of the surface*/ + DDSCAPS ddsCaps; /* 68: direct draw surface caps */ +} DDSURFACEDESC,*LPDDSURFACEDESC; + +typedef struct _DDSURFACEDESC2 +{ + DWORD dwSize; /* 0: size of the DDSURFACEDESC structure*/ + DWORD dwFlags; /* 4: determines what fields are valid*/ + DWORD dwHeight; /* 8: height of surface to be created*/ + DWORD dwWidth; /* C: width of input surface*/ + union { + LONG lPitch; /*10: distance to start of next line (return value only)*/ + DWORD dwLinearSize; /*10: formless late-allocated optimized surface size */ + } DUMMYUNIONNAME1; + DWORD dwBackBufferCount;/* 14: number of back buffers requested*/ + union { + DWORD dwMipMapCount;/* 18:number of mip-map levels requested*/ + DWORD dwRefreshRate;/* 18:refresh rate (used when display mode is described)*/ + DWORD dwSrcVBHandle;/* 18:source used in VB::Optimize */ + } DUMMYUNIONNAME2; + DWORD dwAlphaBitDepth;/* 1C:depth of alpha buffer requested*/ + DWORD dwReserved; /* 20:reserved*/ + LPVOID lpSurface; /* 24:pointer to the associated surface memory*/ + union { + DDCOLORKEY ddckCKDestOverlay; /* 28: CK for dest overlay use*/ + DWORD dwEmptyFaceColor; /* 28: color for empty cubemap faces */ + } DUMMYUNIONNAME3; + DDCOLORKEY ddckCKDestBlt; /* 30: CK for destination blt use*/ + DDCOLORKEY ddckCKSrcOverlay;/* 38: CK for source overlay use*/ + DDCOLORKEY ddckCKSrcBlt; /* 40: CK for source blt use*/ + + union { + DDPIXELFORMAT ddpfPixelFormat;/* 48: pixel format description of the surface*/ + DWORD dwFVF; /* 48: vertex format description of vertex buffers */ + } DUMMYUNIONNAME4; + DDSCAPS2 ddsCaps; /* 68: DDraw surface caps */ + DWORD dwTextureStage; /* 78: stage in multitexture cascade */ +} DDSURFACEDESC2,*LPDDSURFACEDESC2; + +/* DDCOLORCONTROL.dwFlags */ +#define DDCOLOR_BRIGHTNESS 0x00000001 +#define DDCOLOR_CONTRAST 0x00000002 +#define DDCOLOR_HUE 0x00000004 +#define DDCOLOR_SATURATION 0x00000008 +#define DDCOLOR_SHARPNESS 0x00000010 +#define DDCOLOR_GAMMA 0x00000020 +#define DDCOLOR_COLORENABLE 0x00000040 + +typedef struct { + DWORD dwSize; + DWORD dwFlags; + LONG lBrightness; + LONG lContrast; + LONG lHue; + LONG lSaturation; + LONG lSharpness; + LONG lGamma; + LONG lColorEnable; + DWORD dwReserved1; +} DDCOLORCONTROL,*LPDDCOLORCONTROL; + +typedef struct { + WORD red[256]; + WORD green[256]; + WORD blue[256]; +} DDGAMMARAMP,*LPDDGAMMARAMP; + +typedef BOOL CALLBACK (*LPDDENUMCALLBACKA)(GUID *, LPSTR, LPSTR, LPVOID); +typedef BOOL CALLBACK (*LPDDENUMCALLBACKW)(GUID *, LPWSTR, LPWSTR, LPVOID); +DECL_WINELIB_TYPE_AW(LPDDENUMCALLBACK) + +typedef HRESULT CALLBACK (*LPDDENUMMODESCALLBACK)(LPDDSURFACEDESC, LPVOID); +typedef HRESULT CALLBACK (*LPDDENUMMODESCALLBACK2)(LPDDSURFACEDESC2, LPVOID); +typedef HRESULT CALLBACK (*LPDDENUMSURFACESCALLBACK)(LPDIRECTDRAWSURFACE, LPDDSURFACEDESC, LPVOID); +typedef HRESULT CALLBACK (*LPDDENUMSURFACESCALLBACK2)(LPDIRECTDRAWSURFACE4, LPDDSURFACEDESC2, LPVOID); +typedef HRESULT CALLBACK (*LPDDENUMSURFACESCALLBACK7)(LPDIRECTDRAWSURFACE7, LPDDSURFACEDESC2, LPVOID); + +typedef BOOL CALLBACK (*LPDDENUMCALLBACKEXA)(GUID *, LPSTR, LPSTR, LPVOID, HMONITOR); +typedef BOOL CALLBACK (*LPDDENUMCALLBACKEXW)(GUID *, LPWSTR, LPWSTR, LPVOID, HMONITOR); +DECL_WINELIB_TYPE_AW(LPDDENUMCALLBACKEX) + +HRESULT WINAPI DirectDrawEnumerateExA( LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags); +HRESULT WINAPI DirectDrawEnumerateExW( LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags); +#define DirectDrawEnumerateEx WINELIB_NAME_AW(DirectDrawEnumerateEx) + +/* flags for DirectDrawEnumerateEx */ +#define DDENUM_ATTACHEDSECONDARYDEVICES 0x00000001 +#define DDENUM_DETACHEDSECONDARYDEVICES 0x00000002 +#define DDENUM_NONDISPLAYDEVICES 0x00000004 + +/* flags for DirectDrawCreate or IDirectDraw::Initialize */ +#define DDCREATE_HARDWAREONLY 1L +#define DDCREATE_EMULATIONONLY 2L + +typedef struct _DDBLTFX +{ + DWORD dwSize; /* size of structure */ + DWORD dwDDFX; /* FX operations */ + DWORD dwROP; /* Win32 raster operations */ + DWORD dwDDROP; /* Raster operations new for DirectDraw */ + DWORD dwRotationAngle; /* Rotation angle for blt */ + DWORD dwZBufferOpCode; /* ZBuffer compares */ + DWORD dwZBufferLow; /* Low limit of Z buffer */ + DWORD dwZBufferHigh; /* High limit of Z buffer */ + DWORD dwZBufferBaseDest; /* Destination base value */ + DWORD dwZDestConstBitDepth; /* Bit depth used to specify Z constant for destination */ + union + { + DWORD dwZDestConst; /* Constant to use as Z buffer for dest */ + LPDIRECTDRAWSURFACE lpDDSZBufferDest; /* Surface to use as Z buffer for dest */ + } DUMMYUNIONNAME1; + DWORD dwZSrcConstBitDepth; /* Bit depth used to specify Z constant for source */ + union + { + DWORD dwZSrcConst; /* Constant to use as Z buffer for src */ + LPDIRECTDRAWSURFACE lpDDSZBufferSrc; /* Surface to use as Z buffer for src */ + } DUMMYUNIONNAME2; + DWORD dwAlphaEdgeBlendBitDepth; /* Bit depth used to specify constant for alpha edge blend */ + DWORD dwAlphaEdgeBlend; /* Alpha for edge blending */ + DWORD dwReserved; + DWORD dwAlphaDestConstBitDepth; /* Bit depth used to specify alpha constant for destination */ + union + { + DWORD dwAlphaDestConst; /* Constant to use as Alpha Channel */ + LPDIRECTDRAWSURFACE lpDDSAlphaDest; /* Surface to use as Alpha Channel */ + } DUMMYUNIONNAME3; + DWORD dwAlphaSrcConstBitDepth; /* Bit depth used to specify alpha constant for source */ + union + { + DWORD dwAlphaSrcConst; /* Constant to use as Alpha Channel */ + LPDIRECTDRAWSURFACE lpDDSAlphaSrc; /* Surface to use as Alpha Channel */ + } DUMMYUNIONNAME4; + union + { + DWORD dwFillColor; /* color in RGB or Palettized */ + DWORD dwFillDepth; /* depth value for z-buffer */ + DWORD dwFillPixel; /* pixel val for RGBA or RGBZ */ + LPDIRECTDRAWSURFACE lpDDSPattern; /* Surface to use as pattern */ + } DUMMYUNIONNAME5; + DDCOLORKEY ddckDestColorkey; /* DestColorkey override */ + DDCOLORKEY ddckSrcColorkey; /* SrcColorkey override */ +} DDBLTFX,*LPDDBLTFX; + +/* dwDDFX */ +/* arithmetic stretching along y axis */ +#define DDBLTFX_ARITHSTRETCHY 0x00000001 +/* mirror on y axis */ +#define DDBLTFX_MIRRORLEFTRIGHT 0x00000002 +/* mirror on x axis */ +#define DDBLTFX_MIRRORUPDOWN 0x00000004 +/* do not tear */ +#define DDBLTFX_NOTEARING 0x00000008 +/* 180 degrees clockwise rotation */ +#define DDBLTFX_ROTATE180 0x00000010 +/* 270 degrees clockwise rotation */ +#define DDBLTFX_ROTATE270 0x00000020 +/* 90 degrees clockwise rotation */ +#define DDBLTFX_ROTATE90 0x00000040 +/* dwZBufferLow and dwZBufferHigh specify limits to the copied Z values */ +#define DDBLTFX_ZBUFFERRANGE 0x00000080 +/* add dwZBufferBaseDest to every source z value before compare */ +#define DDBLTFX_ZBUFFERBASEDEST 0x00000100 + +typedef struct _DDOVERLAYFX +{ + DWORD dwSize; /* size of structure */ + DWORD dwAlphaEdgeBlendBitDepth; /* Bit depth used to specify constant for alpha edge blend */ + DWORD dwAlphaEdgeBlend; /* Constant to use as alpha for edge blend */ + DWORD dwReserved; + DWORD dwAlphaDestConstBitDepth; /* Bit depth used to specify alpha constant for destination */ + union + { + DWORD dwAlphaDestConst; /* Constant to use as alpha channel for dest */ + LPDIRECTDRAWSURFACE lpDDSAlphaDest; /* Surface to use as alpha channel for dest */ + } DUMMYUNIONNAME1; + DWORD dwAlphaSrcConstBitDepth; /* Bit depth used to specify alpha constant for source */ + union + { + DWORD dwAlphaSrcConst; /* Constant to use as alpha channel for src */ + LPDIRECTDRAWSURFACE lpDDSAlphaSrc; /* Surface to use as alpha channel for src */ + } DUMMYUNIONNAME2; + DDCOLORKEY dckDestColorkey; /* DestColorkey override */ + DDCOLORKEY dckSrcColorkey; /* DestColorkey override */ + DWORD dwDDFX; /* Overlay FX */ + DWORD dwFlags; /* flags */ +} DDOVERLAYFX,*LPDDOVERLAYFX; + +typedef struct _DDBLTBATCH +{ + LPRECT lprDest; + LPDIRECTDRAWSURFACE lpDDSSrc; + LPRECT lprSrc; + DWORD dwFlags; + LPDDBLTFX lpDDBltFx; +} DDBLTBATCH,*LPDDBLTBATCH; + +#define MAX_DDDEVICEID_STRING 512 + +typedef struct tagDDDEVICEIDENTIFIER { + char szDriver[MAX_DDDEVICEID_STRING]; + char szDescription[MAX_DDDEVICEID_STRING]; + LARGE_INTEGER liDriverVersion; + DWORD dwVendorId; + DWORD dwDeviceId; + DWORD dwSubSysId; + DWORD dwRevision; + GUID guidDeviceIdentifier; +} DDDEVICEIDENTIFIER, * LPDDDEVICEIDENTIFIER; + +typedef struct tagDDDEVICEIDENTIFIER2 { + char szDriver[MAX_DDDEVICEID_STRING]; /* user readable driver name */ + char szDescription[MAX_DDDEVICEID_STRING]; /* user readable description */ + LARGE_INTEGER liDriverVersion; /* driver version */ + DWORD dwVendorId; /* vendor ID, zero if unknown */ + DWORD dwDeviceId; /* chipset ID, zero if unknown */ + DWORD dwSubSysId; /* board ID, zero if unknown */ + DWORD dwRevision; /* chipset version, zero if unknown */ + GUID guidDeviceIdentifier; /* unique ID for this driver/chipset combination */ + DWORD dwWHQLLevel; /* Windows Hardware Quality Lab certification level */ +} DDDEVICEIDENTIFIER2, * LPDDDEVICEIDENTIFIER2; + +/***************************************************************************** + * IDirectDrawPalette interface + */ +#define ICOM_INTERFACE IDirectDrawPalette +#define IDirectDrawPalette_METHODS \ + ICOM_METHOD1(HRESULT,GetCaps, LPDWORD,lpdwCaps) \ + ICOM_METHOD4(HRESULT,GetEntries, DWORD,dwFlags, DWORD,dwBase, DWORD,dwNumEntries, LPPALETTEENTRY,lpEntries) \ + ICOM_METHOD3(HRESULT,Initialize, LPDIRECTDRAW,lpDD, DWORD,dwFlags, LPPALETTEENTRY,lpDDColorTable) \ + ICOM_METHOD4(HRESULT,SetEntries, DWORD,dwFlags, DWORD,dwStartingEntry, DWORD,dwCount, LPPALETTEENTRY,lpEntries) +#define IDirectDrawPalette_IMETHODS \ + IUnknown_IMETHODS \ + IDirectDrawPalette_METHODS +ICOM_DEFINE(IDirectDrawPalette,IUnknown) +#undef ICOM_INTERFACE + + /*** IUnknown methods ***/ +#define IDirectDrawPalette_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDirectDrawPalette_AddRef(p) ICOM_CALL (AddRef,p) +#define IDirectDrawPalette_Release(p) ICOM_CALL (Release,p) + /*** IDirectDrawPalette methods ***/ +#define IDirectDrawPalette_GetCaps(p,a) ICOM_CALL1(GetCaps,p,a) +#define IDirectDrawPalette_GetEntries(p,a,b,c,d) ICOM_CALL4(GetEntries,p,a,b,c,d) +#define IDirectDrawPalette_Initialize(p,a,b,c) ICOM_CALL3(Initialize,p,a,b,c) +#define IDirectDrawPalette_SetEntries(p,a,b,c,d) ICOM_CALL4(SetEntries,p,a,b,c,d) + + +/***************************************************************************** + * IDirectDrawClipper interface + */ +#define ICOM_INTERFACE IDirectDrawClipper +#define IDirectDrawClipper_METHODS \ + ICOM_METHOD3(HRESULT,GetClipList, LPRECT,lpRect, LPRGNDATA,lpClipList, LPDWORD,lpdwSize) \ + ICOM_METHOD1(HRESULT,GetHWnd, HWND*,lphWnd) \ + ICOM_METHOD2(HRESULT,Initialize, LPDIRECTDRAW,lpDD, DWORD,dwFlags) \ + ICOM_METHOD1(HRESULT,IsClipListChanged, BOOL*,lpbChanged) \ + ICOM_METHOD2(HRESULT,SetClipList, LPRGNDATA,lpClipList, DWORD,dwFlags) \ + ICOM_METHOD2(HRESULT,SetHWnd, DWORD,dwFlags, HWND,hWnd) +#define IDirectDrawClipper_IMETHODS \ + IUnknown_IMETHODS \ + IDirectDrawClipper_METHODS +ICOM_DEFINE(IDirectDrawClipper,IUnknown) +#undef ICOM_INTERFACE + + /*** IUnknown methods ***/ +#define IDirectDrawClipper_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDirectDrawClipper_AddRef(p) ICOM_CALL (AddRef,p) +#define IDirectDrawClipper_Release(p) ICOM_CALL (Release,p) + /*** IDirectDrawClipper methods ***/ +#define IDirectDrawClipper_GetClipList(p,a,b,c) ICOM_CALL3(GetClipList,p,a,b,c) +#define IDirectDrawClipper_GetHWnd(p,a) ICOM_CALL1(GetHWnd,p,a) +#define IDirectDrawClipper_Initialize(p,a,b) ICOM_CALL2(Initialize,p,a,b) +#define IDirectDrawClipper_IsClipListChanged(p,a) ICOM_CALL1(IsClipListChanged,p,a) +#define IDirectDrawClipper_SetClipList(p,a,b) ICOM_CALL2(SetClipList,p,a,b) +#define IDirectDrawClipper_SetHWnd(p,a,b) ICOM_CALL2(SetHWnd,p,a,b) + + +/***************************************************************************** + * IDirectDraw interface + */ +#define ICOM_INTERFACE IDirectDraw +#define IDirectDraw_METHODS \ + ICOM_METHOD (HRESULT,Compact) \ + ICOM_METHOD3(HRESULT,CreateClipper, DWORD,dwFlags, LPDIRECTDRAWCLIPPER*,lplpDDClipper, IUnknown*,pUnkOuter) \ + ICOM_METHOD4(HRESULT,CreatePalette, DWORD,dwFlags, LPPALETTEENTRY,lpColorTable, LPDIRECTDRAWPALETTE*,lplpDDPalette, IUnknown*,pUnkOuter) \ + ICOM_METHOD3(HRESULT,CreateSurface, LPDDSURFACEDESC,lpDDSurfaceDesc, LPDIRECTDRAWSURFACE*,lplpDDSurface, IUnknown*,pUnkOuter) \ + ICOM_METHOD2(HRESULT,DuplicateSurface, LPDIRECTDRAWSURFACE,lpDDSurface, LPDIRECTDRAWSURFACE*,lplpDupDDSurface) \ + ICOM_METHOD4(HRESULT,EnumDisplayModes, DWORD,dwFlags, LPDDSURFACEDESC,lpDDSurfaceDesc, LPVOID,lpContext, LPDDENUMMODESCALLBACK,lpEnumModesCallback) \ + ICOM_METHOD4(HRESULT,EnumSurfaces, DWORD,dwFlags, LPDDSURFACEDESC,lpDDSD, LPVOID,lpContext, LPDDENUMSURFACESCALLBACK,lpEnumSurfacesCallback) \ + ICOM_METHOD (HRESULT,FlipToGDISurface) \ + ICOM_METHOD2(HRESULT,GetCaps, LPDDCAPS,lpDDDriverCaps, LPDDCAPS,lpDDHELCaps) \ + ICOM_METHOD1(HRESULT,GetDisplayMode, LPDDSURFACEDESC,lpDDSurfaceDesc) \ + ICOM_METHOD2(HRESULT,GetFourCCCodes, LPDWORD,lpNumCodes, LPDWORD,lpCodes) \ + ICOM_METHOD1(HRESULT,GetGDISurface, LPDIRECTDRAWSURFACE*,lplpGDIDDSurface) \ + ICOM_METHOD1(HRESULT,GetMonitorFrequency, LPDWORD,lpdwFrequency) \ + ICOM_METHOD1(HRESULT,GetScanLine, LPDWORD,lpdwScanLine) \ + ICOM_METHOD1(HRESULT,GetVerticalBlankStatus, BOOL*,lpbIsInVB) \ + ICOM_METHOD1(HRESULT,Initialize, GUID*,lpGUID) \ + ICOM_METHOD (HRESULT,RestoreDisplayMode) \ + ICOM_METHOD2(HRESULT,SetCooperativeLevel, HWND,hWnd, DWORD,dwFlags) \ + ICOM_METHOD3(HRESULT,SetDisplayMode, DWORD,, DWORD,, DWORD,) \ + ICOM_METHOD2(HRESULT,WaitForVerticalBlank, DWORD,dwFlags, HANDLE,hEvent) +#define IDirectDraw_IMETHODS \ + IUnknown_IMETHODS \ + IDirectDraw_METHODS +ICOM_DEFINE(IDirectDraw,IUnknown) +#undef ICOM_INTERFACE + + /*** IUnknown methods ***/ +#define IDirectDraw_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDirectDraw_AddRef(p) ICOM_CALL (AddRef,p) +#define IDirectDraw_Release(p) ICOM_CALL (Release,p) + /*** IDirectDraw methods ***/ +#define IDirectDraw_Compact(p) ICOM_CALL (Compact,p) +#define IDirectDraw_CreateClipper(p,a,b,c) ICOM_CALL3(CreateClipper,p,a,b,c) +#define IDirectDraw_CreatePalette(p,a,b,c,d) ICOM_CALL4(CreatePalette,p,a,b,c,d) +#define IDirectDraw_CreateSurface(p,a,b,c) ICOM_CALL3(CreateSurface,p,a,b,c) +#define IDirectDraw_DuplicateSurface(p,a,b) ICOM_CALL2(DuplicateSurface,p,a,b) +#define IDirectDraw_EnumDisplayModes(p,a,b,c,d) ICOM_CALL4(EnumDisplayModes,p,a,b,c,d) +#define IDirectDraw_EnumSurfaces(p,a,b,c,d) ICOM_CALL4(EnumSurfaces,p,a,b,c,d) +#define IDirectDraw_FlipToGDISurface(p) ICOM_CALL (FlipToGDISurface,p) +#define IDirectDraw_GetCaps(p,a,b) ICOM_CALL2(GetCaps,p,a,b) +#define IDirectDraw_GetDisplayMode(p,a) ICOM_CALL1(GetDisplayMode,p,a) +#define IDirectDraw_GetFourCCCodes(p,a,b) ICOM_CALL2(GetFourCCCodes,p,a,b) +#define IDirectDraw_GetGDISurface(p,a) ICOM_CALL1(GetGDISurface,p,a) +#define IDirectDraw_GetMonitorFrequency(p,a) ICOM_CALL1(GetMonitorFrequency,p,a) +#define IDirectDraw_GetScanLine(p,a) ICOM_CALL1(GetScanLine,p,a) +#define IDirectDraw_GetVerticalBlankStatus(p,a) ICOM_CALL1(GetVerticalBlankStatus,p,a) +#define IDirectDraw_Initialize(p,a) ICOM_CALL1(Initialize,p,a) +#define IDirectDraw_RestoreDisplayMode(p) ICOM_CALL (RestoreDisplayMode,p) +#define IDirectDraw_SetCooperativeLevel(p,a,b) ICOM_CALL2(SetCooperativeLevel,p,a,b) +#define IDirectDraw_SetDisplayMode(p,a,b,c) ICOM_CALL3(SetDisplayMode,p,a,b,c) +#define IDirectDraw_WaitForVerticalBlank(p,a,b) ICOM_CALL2(WaitForVerticalBlank,p,a,b) + + +/* flags for Lock() */ +#define DDLOCK_SURFACEMEMORYPTR 0x00000000 +#define DDLOCK_WAIT 0x00000001 +#define DDLOCK_EVENT 0x00000002 +#define DDLOCK_READONLY 0x00000010 +#define DDLOCK_WRITEONLY 0x00000020 +#define DDLOCK_NOSYSLOCK 0x00000800 + + +/***************************************************************************** + * IDirectDraw2 interface + */ +/* Note: IDirectDraw2 cannot derive from IDirectDraw because the number of + * arguments of SetDisplayMode has changed ! + */ +#define ICOM_INTERFACE IDirectDraw2 +#define IDirectDraw2_METHODS \ +/*0c*/ ICOM_METHOD (HRESULT,Compact) \ +/*10*/ ICOM_METHOD3(HRESULT,CreateClipper, DWORD,dwFlags, LPDIRECTDRAWCLIPPER*,lplpDDClipper, IUnknown*,pUnkOuter) \ +/*14*/ ICOM_METHOD4(HRESULT,CreatePalette, DWORD,dwFlags, LPPALETTEENTRY,lpColorTable, LPDIRECTDRAWPALETTE*,lplpDDPalette, IUnknown*,pUnkOuter) \ +/*18*/ ICOM_METHOD3(HRESULT,CreateSurface, LPDDSURFACEDESC,lpDDSurfaceDesc, LPDIRECTDRAWSURFACE2*,lplpDDSurface, IUnknown*,pUnkOuter) \ +/*1c*/ ICOM_METHOD2(HRESULT,DuplicateSurface, LPDIRECTDRAWSURFACE2,lpDDSurface, LPDIRECTDRAWSURFACE2*,lplpDupDDSurface) \ +/*20*/ ICOM_METHOD4(HRESULT,EnumDisplayModes, DWORD,dwFlags, LPDDSURFACEDESC,lpDDSurfaceDesc, LPVOID,lpContext, LPDDENUMMODESCALLBACK,lpEnumModesCallback) \ +/*24*/ ICOM_METHOD4(HRESULT,EnumSurfaces, DWORD,dwFlags, LPDDSURFACEDESC,lpDDSD, LPVOID,lpContext, LPDDENUMSURFACESCALLBACK,lpEnumSurfacesCallback) \ +/*28*/ ICOM_METHOD (HRESULT,FlipToGDISurface) \ +/*2c*/ ICOM_METHOD2(HRESULT,GetCaps, LPDDCAPS,lpDDDriverCaps, LPDDCAPS,lpDDHELCaps) \ +/*30*/ ICOM_METHOD1(HRESULT,GetDisplayMode, LPDDSURFACEDESC,lpDDSurfaceDesc) \ +/*34*/ ICOM_METHOD2(HRESULT,GetFourCCCodes, LPDWORD,lpNumCodes, LPDWORD,lpCodes) \ +/*38*/ ICOM_METHOD1(HRESULT,GetGDISurface, LPDIRECTDRAWSURFACE2*,lplpGDIDDSurface) \ +/*3c*/ ICOM_METHOD1(HRESULT,GetMonitorFrequency, LPDWORD,lpdwFrequency) \ +/*40*/ ICOM_METHOD1(HRESULT,GetScanLine, LPDWORD,lpdwScanLine) \ +/*44*/ ICOM_METHOD1(HRESULT,GetVerticalBlankStatus, BOOL*,lpbIsInVB) \ +/*48*/ ICOM_METHOD1(HRESULT,Initialize, GUID*,lpGUID) \ +/*4c*/ ICOM_METHOD (HRESULT,RestoreDisplayMode) \ +/*50*/ ICOM_METHOD2(HRESULT,SetCooperativeLevel, HWND,hWnd, DWORD,dwFlags) \ +/*54*/ ICOM_METHOD5(HRESULT,SetDisplayMode, DWORD,dwWidth, DWORD,dwHeight, DWORD,dwBPP, DWORD,dwRefreshRate, DWORD,dwFlags) \ +/*58*/ ICOM_METHOD2(HRESULT,WaitForVerticalBlank, DWORD,dwFlags, HANDLE,hEvent) \ + /* added in v2 */ \ +/*5c*/ ICOM_METHOD3(HRESULT,GetAvailableVidMem, LPDDSCAPS,lpDDCaps, LPDWORD,lpdwTotal, LPDWORD,lpdwFree) +#define IDirectDraw2_IMETHODS \ + IUnknown_IMETHODS \ + IDirectDraw2_METHODS +ICOM_DEFINE(IDirectDraw2,IUnknown) +#undef ICOM_INTERFACE + + /*** IUnknown methods ***/ +#define IDirectDraw2_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDirectDraw2_AddRef(p) ICOM_CALL (AddRef,p) +#define IDirectDraw2_Release(p) ICOM_CALL (Release,p) + /*** IDirectDraw methods ***/ +#define IDirectDraw2_Compact(p) ICOM_CALL (Compact,p) +#define IDirectDraw2_CreateClipper(p,a,b,c) ICOM_CALL3(CreateClipper,p,a,b,c) +#define IDirectDraw2_CreatePalette(p,a,b,c,d) ICOM_CALL4(CreatePalette,p,a,b,c,d) +#define IDirectDraw2_CreateSurface(p,a,b,c) ICOM_CALL3(CreateSurface,p,a,b,c) +#define IDirectDraw2_DuplicateSurface(p,a,b) ICOM_CALL2(DuplicateSurface,p,a,b) +#define IDirectDraw2_EnumDisplayModes(p,a,b,c,d) ICOM_CALL4(EnumDisplayModes,p,a,b,c,d) +#define IDirectDraw2_EnumSurfaces(p,a,b,c,d) ICOM_CALL4(EnumSurfaces,p,a,b,c,d) +#define IDirectDraw2_FlipToGDISurface(p) ICOM_CALL (FlipToGDISurface,p) +#define IDirectDraw2_GetCaps(p,a,b) ICOM_CALL2(GetCaps,p,a,b) +#define IDirectDraw2_GetDisplayMode(p,a) ICOM_CALL1(GetDisplayMode,p,a) +#define IDirectDraw2_GetFourCCCodes(p,a,b) ICOM_CALL2(GetFourCCCodes,p,a,b) +#define IDirectDraw2_GetGDISurface(p,a) ICOM_CALL1(GetGDISurface,p,a) +#define IDirectDraw2_GetMonitorFrequency(p,a) ICOM_CALL1(GetMonitorFrequency,p,a) +#define IDirectDraw2_GetScanLine(p,a) ICOM_CALL1(GetScanLine,p,a) +#define IDirectDraw2_GetVerticalBlankStatus(p,a) ICOM_CALL1(GetVerticalBlankStatus,p,a) +#define IDirectDraw2_Initialize(p,a) ICOM_CALL1(Initialize,p,a) +#define IDirectDraw2_RestoreDisplayMode(p) ICOM_CALL (RestoreDisplayMode,p) +#define IDirectDraw2_SetCooperativeLevel(p,a,b) ICOM_CALL2(SetCooperativeLevel,p,a,b) +#define IDirectDraw2_SetDisplayMode(p,a,b,c,d,e) ICOM_CALL5(SetDisplayMode,p,a,b,c,d,e) +#define IDirectDraw2_WaitForVerticalBlank(p,a,b) ICOM_CALL2(WaitForVerticalBlank,p,a,b) +/*** IDirectDraw2 methods ***/ +#define IDirectDraw2_GetAvailableVidMem(p,a,b,c) ICOM_CALL3(GetAvailableVidMem,p,a,b,c) + + +/***************************************************************************** + * IDirectDraw4 interface + */ +#define ICOM_INTERFACE IDirectDraw4 +#define IDirectDraw4_METHODS \ +/*0c*/ ICOM_METHOD (HRESULT,Compact) \ +/*10*/ ICOM_METHOD3(HRESULT,CreateClipper, DWORD,dwFlags, LPDIRECTDRAWCLIPPER*,lplpDDClipper, IUnknown*,pUnkOuter) \ +/*14*/ ICOM_METHOD4(HRESULT,CreatePalette, DWORD,dwFlags, LPPALETTEENTRY,lpColorTable, LPDIRECTDRAWPALETTE*,lplpDDPalette, IUnknown*,pUnkOuter) \ +/*18*/ ICOM_METHOD3(HRESULT,CreateSurface, LPDDSURFACEDESC2,lpDDSurfaceDesc, LPDIRECTDRAWSURFACE4*,lplpDDSurface, IUnknown*,pUnkOuter) \ +/*1c*/ ICOM_METHOD2(HRESULT,DuplicateSurface, LPDIRECTDRAWSURFACE4,lpDDSurface, LPDIRECTDRAWSURFACE4*,lplpDupDDSurface) \ +/*20*/ ICOM_METHOD4(HRESULT,EnumDisplayModes, DWORD,dwFlags, LPDDSURFACEDESC2,lpDDSurfaceDesc, LPVOID,lpContext, LPDDENUMMODESCALLBACK2,lpEnumModesCallback) \ +/*24*/ ICOM_METHOD4(HRESULT,EnumSurfaces, DWORD,dwFlags, LPDDSURFACEDESC2,lpDDSD, LPVOID,lpContext, LPDDENUMSURFACESCALLBACK2,lpEnumSurfacesCallback) \ +/*28*/ ICOM_METHOD (HRESULT,FlipToGDISurface) \ +/*2c*/ ICOM_METHOD2(HRESULT,GetCaps, LPDDCAPS,lpDDDriverCaps, LPDDCAPS,lpDDHELCaps) \ +/*30*/ ICOM_METHOD1(HRESULT,GetDisplayMode, LPDDSURFACEDESC2,lpDDSurfaceDesc) \ +/*34*/ ICOM_METHOD2(HRESULT,GetFourCCCodes, LPDWORD,lpNumCodes, LPDWORD,lpCodes) \ +/*38*/ ICOM_METHOD1(HRESULT,GetGDISurface, LPDIRECTDRAWSURFACE4*,lplpGDIDDSurface) \ +/*3c*/ ICOM_METHOD1(HRESULT,GetMonitorFrequency, LPDWORD,lpdwFrequency) \ +/*40*/ ICOM_METHOD1(HRESULT,GetScanLine, LPDWORD,lpdwScanLine) \ +/*44*/ ICOM_METHOD1(HRESULT,GetVerticalBlankStatus, BOOL*,lpbIsInVB) \ +/*48*/ ICOM_METHOD1(HRESULT,Initialize, GUID*,lpGUID) \ +/*4c*/ ICOM_METHOD (HRESULT,RestoreDisplayMode) \ +/*50*/ ICOM_METHOD2(HRESULT,SetCooperativeLevel, HWND,hWnd, DWORD,dwFlags) \ +/*54*/ ICOM_METHOD5(HRESULT,SetDisplayMode, DWORD,dwWidth, DWORD,dwHeight, DWORD,dwBPP, DWORD,dwRefreshRate, DWORD,dwFlags) \ +/*58*/ ICOM_METHOD2(HRESULT,WaitForVerticalBlank, DWORD,dwFlags, HANDLE,hEvent) \ + /* added in v2 */ \ +/*5c*/ ICOM_METHOD3(HRESULT,GetAvailableVidMem, LPDDSCAPS2,lpDDCaps, LPDWORD,lpdwTotal, LPDWORD,lpdwFree) \ + /* added in v4 */ \ + ICOM_METHOD2(HRESULT,GetSurfaceFromDC, HDC,, LPDIRECTDRAWSURFACE4*,) \ + ICOM_METHOD (HRESULT,RestoreAllSurfaces) \ + ICOM_METHOD (HRESULT,TestCooperativeLevel) \ + ICOM_METHOD2(HRESULT,GetDeviceIdentifier, LPDDDEVICEIDENTIFIER,, DWORD,) +#define IDirectDraw4_IMETHODS \ + IUnknown_IMETHODS \ + IDirectDraw4_METHODS +ICOM_DEFINE(IDirectDraw4,IUnknown) +#undef ICOM_INTERFACE + + /*** IUnknown methods ***/ +#define IDirectDraw4_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDirectDraw4_AddRef(p) ICOM_CALL (AddRef,p) +#define IDirectDraw4_Release(p) ICOM_CALL (Release,p) + /*** IDirectDraw methods ***/ +#define IDirectDraw4_Compact(p) ICOM_CALL (Compact,p) +#define IDirectDraw4_CreateClipper(p,a,b,c) ICOM_CALL3(CreateClipper,p,a,b,c) +#define IDirectDraw4_CreatePalette(p,a,b,c,d) ICOM_CALL4(CreatePalette,p,a,b,c,d) +#define IDirectDraw4_CreateSurface(p,a,b,c) ICOM_CALL3(CreateSurface,p,a,b,c) +#define IDirectDraw4_DuplicateSurface(p,a,b) ICOM_CALL2(DuplicateSurface,p,a,b) +#define IDirectDraw4_EnumDisplayModes(p,a,b,c,d) ICOM_CALL4(EnumDisplayModes,p,a,b,c,d) +#define IDirectDraw4_EnumSurfaces(p,a,b,c,d) ICOM_CALL4(EnumSurfaces,p,a,b,c,d) +#define IDirectDraw4_FlipToGDISurface(p) ICOM_CALL (FlipToGDISurface,p) +#define IDirectDraw4_GetCaps(p,a,b) ICOM_CALL2(GetCaps,p,a,b) +#define IDirectDraw4_GetDisplayMode(p,a) ICOM_CALL1(GetDisplayMode,p,a) +#define IDirectDraw4_GetFourCCCodes(p,a,b) ICOM_CALL2(GetFourCCCodes,p,a,b) +#define IDirectDraw4_GetGDISurface(p,a) ICOM_CALL1(GetGDISurface,p,a) +#define IDirectDraw4_GetMonitorFrequency(p,a) ICOM_CALL1(GetMonitorFrequency,p,a) +#define IDirectDraw4_GetScanLine(p,a) ICOM_CALL1(GetScanLine,p,a) +#define IDirectDraw4_GetVerticalBlankStatus(p,a) ICOM_CALL1(GetVerticalBlankStatus,p,a) +#define IDirectDraw4_Initialize(p,a) ICOM_CALL1(Initialize,p,a) +#define IDirectDraw4_RestoreDisplayMode(p) ICOM_CALL (RestoreDisplayMode,p) +#define IDirectDraw4_SetCooperativeLevel(p,a,b) ICOM_CALL2(SetCooperativeLevel,p,a,b) +#define IDirectDraw4_SetDisplayMode(p,a,b,c,d,e) ICOM_CALL5(SetDisplayMode,p,a,b,c,d,e) +#define IDirectDraw4_WaitForVerticalBlank(p,a,b) ICOM_CALL2(WaitForVerticalBlank,p,a,b) +/*** IDirectDraw2 methods ***/ +#define IDirectDraw4_GetAvailableVidMem(p,a,b,c) ICOM_CALL3(GetAvailableVidMem,p,a,b,c) +/*** IDirectDraw4 methods ***/ +#define IDirectDraw4_GetSurfaceFromDC(p,a,b) ICOM_CALL2(GetSurfaceFromDC,p,a,b) +#define IDirectDraw4_RestoreAllSurfaces(pc) ICOM_CALL (RestoreAllSurfaces,p) +#define IDirectDraw4_TestCooperativeLevel(p) ICOM_CALL (TestCooperativeLevel,p) +#define IDirectDraw4_GetDeviceIdentifier(p,a,b) ICOM_CALL2(GetDeviceIdentifier,p,a,b) + + +/***************************************************************************** + * IDirectDraw7 interface + */ +/* Note: IDirectDraw7 cannot derive from IDirectDraw4; it is even documented + * as not interchangeable with earlier DirectDraw interfaces. + */ +#define ICOM_INTERFACE IDirectDraw7 +#define IDirectDraw7_METHODS \ +/*0c*/ ICOM_METHOD (HRESULT,Compact) \ +/*10*/ ICOM_METHOD3(HRESULT,CreateClipper, DWORD,dwFlags, LPDIRECTDRAWCLIPPER*,lplpDDClipper, IUnknown*,pUnkOuter) \ +/*14*/ ICOM_METHOD4(HRESULT,CreatePalette, DWORD,dwFlags, LPPALETTEENTRY,lpColorTable, LPDIRECTDRAWPALETTE*,lplpDDPalette, IUnknown*,pUnkOuter) \ +/*18*/ ICOM_METHOD3(HRESULT,CreateSurface, LPDDSURFACEDESC2,lpDDSurfaceDesc, LPDIRECTDRAWSURFACE7*,lplpDDSurface, IUnknown*,pUnkOuter) \ +/*1c*/ ICOM_METHOD2(HRESULT,DuplicateSurface, LPDIRECTDRAWSURFACE7,lpDDSurface, LPDIRECTDRAWSURFACE7*,lplpDupDDSurface) \ +/*20*/ ICOM_METHOD4(HRESULT,EnumDisplayModes, DWORD,dwFlags, LPDDSURFACEDESC2,lpDDSurfaceDesc, LPVOID,lpContext, LPDDENUMMODESCALLBACK2,lpEnumModesCallback) \ +/*24*/ ICOM_METHOD4(HRESULT,EnumSurfaces, DWORD,dwFlags, LPDDSURFACEDESC2,lpDDSD, LPVOID,lpContext, LPDDENUMSURFACESCALLBACK7,lpEnumSurfacesCallback) \ +/*28*/ ICOM_METHOD (HRESULT,FlipToGDISurface) \ +/*2c*/ ICOM_METHOD2(HRESULT,GetCaps, LPDDCAPS,lpDDDriverCaps, LPDDCAPS,lpDDHELCaps) \ +/*30*/ ICOM_METHOD1(HRESULT,GetDisplayMode, LPDDSURFACEDESC2,lpDDSurfaceDesc) \ +/*34*/ ICOM_METHOD2(HRESULT,GetFourCCCodes, LPDWORD,lpNumCodes, LPDWORD,lpCodes) \ +/*38*/ ICOM_METHOD1(HRESULT,GetGDISurface, LPDIRECTDRAWSURFACE7*,lplpGDIDDSurface) \ +/*3c*/ ICOM_METHOD1(HRESULT,GetMonitorFrequency, LPDWORD,lpdwFrequency) \ +/*40*/ ICOM_METHOD1(HRESULT,GetScanLine, LPDWORD,lpdwScanLine) \ +/*44*/ ICOM_METHOD1(HRESULT,GetVerticalBlankStatus, BOOL*,lpbIsInVB) \ +/*48*/ ICOM_METHOD1(HRESULT,Initialize, GUID*,lpGUID) \ +/*4c*/ ICOM_METHOD (HRESULT,RestoreDisplayMode) \ +/*50*/ ICOM_METHOD2(HRESULT,SetCooperativeLevel, HWND,hWnd, DWORD,dwFlags) \ +/*54*/ ICOM_METHOD5(HRESULT,SetDisplayMode, DWORD,dwWidth, DWORD,dwHeight, DWORD,dwBPP, DWORD,dwRefreshRate, DWORD,dwFlags) \ +/*58*/ ICOM_METHOD2(HRESULT,WaitForVerticalBlank, DWORD,dwFlags, HANDLE,hEvent) \ + /* added in v2 */ \ +/*5c*/ ICOM_METHOD3(HRESULT,GetAvailableVidMem, LPDDSCAPS2,lpDDCaps, LPDWORD,lpdwTotal, LPDWORD,lpdwFree) \ + /* added in v4 */ \ +/*60*/ ICOM_METHOD2(HRESULT,GetSurfaceFromDC, HDC,, LPDIRECTDRAWSURFACE7*,) \ +/*64*/ ICOM_METHOD (HRESULT,RestoreAllSurfaces) \ +/*68*/ ICOM_METHOD (HRESULT,TestCooperativeLevel) \ +/*6c*/ ICOM_METHOD2(HRESULT,GetDeviceIdentifier, LPDDDEVICEIDENTIFIER2,, DWORD,) \ + /* added in v7 */ \ +/*70*/ ICOM_METHOD3(HRESULT,StartModeTest, LPSIZE,, DWORD,, DWORD,) \ +/*74*/ ICOM_METHOD2(HRESULT,EvaluateMode, DWORD,, DWORD *,) +#define IDirectDraw7_IMETHODS \ + IUnknown_IMETHODS \ + IDirectDraw7_METHODS +ICOM_DEFINE(IDirectDraw7,IUnknown) +#undef ICOM_INTERFACE + + /*** IUnknown methods ***/ +#define IDirectDraw7_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDirectDraw7_AddRef(p) ICOM_CALL (AddRef,p) +#define IDirectDraw7_Release(p) ICOM_CALL (Release,p) + /*** IDirectDraw methods ***/ +#define IDirectDraw7_Compact(p) ICOM_CALL (Compact,p) +#define IDirectDraw7_CreateClipper(p,a,b,c) ICOM_CALL3(CreateClipper,p,a,b,c) +#define IDirectDraw7_CreatePalette(p,a,b,c,d) ICOM_CALL4(CreatePalette,p,a,b,c,d) +#define IDirectDraw7_CreateSurface(p,a,b,c) ICOM_CALL3(CreateSurface,p,a,b,c) +#define IDirectDraw7_DuplicateSurface(p,a,b) ICOM_CALL2(DuplicateSurface,p,a,b) +#define IDirectDraw7_EnumDisplayModes(p,a,b,c,d) ICOM_CALL4(EnumDisplayModes,p,a,b,c,d) +#define IDirectDraw7_EnumSurfaces(p,a,b,c,d) ICOM_CALL4(EnumSurfaces,p,a,b,c,d) +#define IDirectDraw7_FlipToGDISurface(p) ICOM_CALL (FlipToGDISurface,p) +#define IDirectDraw7_GetCaps(p,a,b) ICOM_CALL2(GetCaps,p,a,b) +#define IDirectDraw7_GetDisplayMode(p,a) ICOM_CALL1(GetDisplayMode,p,a) +#define IDirectDraw7_GetFourCCCodes(p,a,b) ICOM_CALL2(GetFourCCCodes,p,a,b) +#define IDirectDraw7_GetGDISurface(p,a) ICOM_CALL1(GetGDISurface,p,a) +#define IDirectDraw7_GetMonitorFrequency(p,a) ICOM_CALL1(GetMonitorFrequency,p,a) +#define IDirectDraw7_GetScanLine(p,a) ICOM_CALL1(GetScanLine,p,a) +#define IDirectDraw7_GetVerticalBlankStatus(p,a) ICOM_CALL1(GetVerticalBlankStatus,p,a) +#define IDirectDraw7_Initialize(p,a) ICOM_CALL1(Initialize,p,a) +#define IDirectDraw7_RestoreDisplayMode(p) ICOM_CALL (RestoreDisplayMode,p) +#define IDirectDraw7_SetCooperativeLevel(p,a,b) ICOM_CALL2(SetCooperativeLevel,p,a,b) +#define IDirectDraw7_SetDisplayMode(p,a,b,c,d,e) ICOM_CALL5(SetDisplayMode,p,a,b,c,d,e) +#define IDirectDraw7_WaitForVerticalBlank(p,a,b) ICOM_CALL2(WaitForVerticalBlank,p,a,b) +/*** added in IDirectDraw2 ***/ +#define IDirectDraw7_GetAvailableVidMem(p,a,b,c) ICOM_CALL3(GetAvailableVidMem,p,a,b,c) +/*** added in IDirectDraw4 ***/ +#define IDirectDraw7_GetSurfaceFromDC(p,a,b) ICOM_CALL2(GetSurfaceFromDC,p,a,b) +#define IDirectDraw7_RestoreAllSurfaces(p) ICOM_CALL (RestoreAllSurfaces,p) +#define IDirectDraw7_TestCooperativeLevel(p) ICOM_CALL (TestCooperativeLevel,p) +#define IDirectDraw7_GetDeviceIdentifier(p,a,b) ICOM_CALL2(GetDeviceIdentifier,p,a,b) +/*** added in IDirectDraw 7 ***/ +#define IDirectDraw7_StartModeTest(p,a,b,c) ICOM_CALL3(StartModeTest,p,a,b,c) +#define IDirectDraw7_EvaluateMode(p,a,b) ICOM_CALL2(EvaluateMode,p,a,b) + + +/***************************************************************************** + * IDirectDrawSurface interface + */ +#define ICOM_INTERFACE IDirectDrawSurface +#define IDirectDrawSurface_METHODS \ +/*0c*/ ICOM_METHOD1(HRESULT,AddAttachedSurface, LPDIRECTDRAWSURFACE,lpDDSAttachedSurface) \ +/*10*/ ICOM_METHOD1(HRESULT,AddOverlayDirtyRect, LPRECT,lpRect) \ +/*14*/ ICOM_METHOD5(HRESULT,Blt, LPRECT,lpDestRect, LPDIRECTDRAWSURFACE,lpDDSrcSurface, LPRECT,lpSrcRect, DWORD,dwFlags, LPDDBLTFX,lpDDBltFx) \ +/*18*/ ICOM_METHOD3(HRESULT,BltBatch, LPDDBLTBATCH,lpDDBltBatch, DWORD,dwCount, DWORD,dwFlags) \ +/*1c*/ ICOM_METHOD5(HRESULT,BltFast, DWORD,dwX, DWORD,dwY, LPDIRECTDRAWSURFACE,lpDDSrcSurface, LPRECT,lpSrcRect, DWORD,dwTrans) \ +/*20*/ ICOM_METHOD2(HRESULT,DeleteAttachedSurface, DWORD,dwFlags, LPDIRECTDRAWSURFACE,lpDDSAttachedSurface) \ +/*24*/ ICOM_METHOD2(HRESULT,EnumAttachedSurfaces, LPVOID,lpContext, LPDDENUMSURFACESCALLBACK,lpEnumSurfacesCallback) \ +/*28*/ ICOM_METHOD3(HRESULT,EnumOverlayZOrders, DWORD,dwFlags, LPVOID,lpContext, LPDDENUMSURFACESCALLBACK,lpfnCallback) \ +/*2c*/ ICOM_METHOD2(HRESULT,Flip, LPDIRECTDRAWSURFACE,lpDDSurfaceTargetOverride, DWORD,dwFlags) \ +/*30*/ ICOM_METHOD2(HRESULT,GetAttachedSurface, LPDDSCAPS,lpDDSCaps, LPDIRECTDRAWSURFACE*,lplpDDAttachedSurface) \ +/*34*/ ICOM_METHOD1(HRESULT,GetBltStatus, DWORD,dwFlags) \ +/*38*/ ICOM_METHOD1(HRESULT,GetCaps, LPDDSCAPS,lpDDSCaps) \ +/*3c*/ ICOM_METHOD1(HRESULT,GetClipper, LPDIRECTDRAWCLIPPER*,lplpDDClipper) \ +/*40*/ ICOM_METHOD2(HRESULT,GetColorKey, DWORD,dwFlags, LPDDCOLORKEY,lpDDColorKey) \ +/*44*/ ICOM_METHOD1(HRESULT,GetDC, HDC*,lphDC) \ +/*48*/ ICOM_METHOD1(HRESULT,GetFlipStatus, DWORD,dwFlags) \ +/*4c*/ ICOM_METHOD2(HRESULT,GetOverlayPosition, LPLONG,lplX, LPLONG,lplY) \ +/*50*/ ICOM_METHOD1(HRESULT,GetPalette, LPDIRECTDRAWPALETTE*,lplpDDPalette) \ +/*54*/ ICOM_METHOD1(HRESULT,GetPixelFormat, LPDDPIXELFORMAT,lpDDPixelFormat) \ +/*58*/ ICOM_METHOD1(HRESULT,GetSurfaceDesc, LPDDSURFACEDESC,lpDDSurfaceDesc) \ +/*5c*/ ICOM_METHOD2(HRESULT,Initialize, LPDIRECTDRAW,lpDD, LPDDSURFACEDESC,lpDDSurfaceDesc) \ +/*60*/ ICOM_METHOD (HRESULT,IsLost) \ +/*64*/ ICOM_METHOD4(HRESULT,Lock, LPRECT,lpDestRect, LPDDSURFACEDESC,lpDDSurfaceDesc, DWORD,dwFlags, HANDLE,hEvent) \ +/*68*/ ICOM_METHOD1(HRESULT,ReleaseDC, HDC,hDC) \ +/*6c*/ ICOM_METHOD (HRESULT,Restore) \ +/*70*/ ICOM_METHOD1(HRESULT,SetClipper, LPDIRECTDRAWCLIPPER,lpDDClipper) \ +/*74*/ ICOM_METHOD2(HRESULT,SetColorKey, DWORD,dwFlags, LPDDCOLORKEY,lpDDColorKey) \ +/*78*/ ICOM_METHOD2(HRESULT,SetOverlayPosition, LONG,lX, LONG,lY) \ +/*7c*/ ICOM_METHOD1(HRESULT,SetPalette, LPDIRECTDRAWPALETTE,lpDDPalette) \ +/*80*/ ICOM_METHOD1(HRESULT,Unlock, LPVOID,lpSurfaceData) \ +/*84*/ ICOM_METHOD5(HRESULT,UpdateOverlay, LPRECT,lpSrcRect, LPDIRECTDRAWSURFACE,lpDDDestSurface, LPRECT,lpDestRect, DWORD,dwFlags, LPDDOVERLAYFX,lpDDOverlayFx) \ +/*88*/ ICOM_METHOD1(HRESULT,UpdateOverlayDisplay, DWORD,dwFlags) \ +/*8c*/ ICOM_METHOD2(HRESULT,UpdateOverlayZOrder, DWORD,dwFlags, LPDIRECTDRAWSURFACE,lpDDSReference) +#define IDirectDrawSurface_IMETHODS \ + IUnknown_IMETHODS \ + IDirectDrawSurface_METHODS +ICOM_DEFINE(IDirectDrawSurface,IUnknown) +#undef ICOM_INTERFACE + + /*** IUnknown methods ***/ +#define IDirectDrawSurface_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDirectDrawSurface_AddRef(p) ICOM_CALL (AddRef,p) +#define IDirectDrawSurface_Release(p) ICOM_CALL (Release,p) + /*** IDirectDrawSurface methods ***/ +#define IDirectDrawSurface_AddAttachedSurface(p,a) ICOM_CALL1(AddAttachedSurface,p,a) +#define IDirectDrawSurface_AddOverlayDirtyRect(p,a) ICOM_CALL1(AddOverlayDirtyRect,p,a) +#define IDirectDrawSurface_Blt(p,a,b,c,d,e) ICOM_CALL5(Blt,p,a,b,c,d,e) +#define IDirectDrawSurface_BltBatch(p,a,b,c) ICOM_CALL3(BltBatch,p,a,b,c) +#define IDirectDrawSurface_BltFast(p,a,b,c,d,e) ICOM_CALL5(BltFast,p,a,b,c,d,e) +#define IDirectDrawSurface_DeleteAttachedSurface(p,a,b) ICOM_CALL2(DeleteAttachedSurface,p,a,b) +#define IDirectDrawSurface_EnumAttachedSurfaces(p,a,b) ICOM_CALL2(EnumAttachedSurfaces,p,a,b) +#define IDirectDrawSurface_EnumOverlayZOrders(p,a,b,c) ICOM_CALL3(EnumOverlayZOrders,p,a,b,c) +#define IDirectDrawSurface_Flip(p,a,b) ICOM_CALL2(Flip,p,a,b) +#define IDirectDrawSurface_GetAttachedSurface(p,a,b) ICOM_CALL2(GetAttachedSurface,p,a,b) +#define IDirectDrawSurface_GetBltStatus(p,a) ICOM_CALL1(GetBltStatus,p,a) +#define IDirectDrawSurface_GetCaps(p,a) ICOM_CALL1(GetCaps,p,a) +#define IDirectDrawSurface_GetClipper(p,a) ICOM_CALL1(GetClipper,p,a) +#define IDirectDrawSurface_GetColorKey(p,a,b) ICOM_CALL2(GetColorKey,p,a,b) +#define IDirectDrawSurface_GetDC(p,a) ICOM_CALL1(GetDC,p,a) +#define IDirectDrawSurface_GetFlipStatus(p,a) ICOM_CALL1(GetFlipStatus,p,a) +#define IDirectDrawSurface_GetOverlayPosition(p,a,b) ICOM_CALL2(GetOverlayPosition,p,a,b) +#define IDirectDrawSurface_GetPalette(p,a) ICOM_CALL1(GetPalette,p,a) +#define IDirectDrawSurface_GetPixelFormat(p,a) ICOM_CALL1(GetPixelFormat,p,a) +#define IDirectDrawSurface_GetSurfaceDesc(p,a) ICOM_CALL1(GetSurfaceDesc,p,a) +#define IDirectDrawSurface_Initialize(p,a,b) ICOM_CALL2(Initialize,p,a,b) +#define IDirectDrawSurface_IsLost(p) ICOM_CALL (IsLost,p) +#define IDirectDrawSurface_Lock(p,a,b,c,d) ICOM_CALL4(Lock,p,a,b,c,d) +#define IDirectDrawSurface_ReleaseDC(p,a) ICOM_CALL1(ReleaseDC,p,a) +#define IDirectDrawSurface_Restore(p) ICOM_CALL (Restore,p) +#define IDirectDrawSurface_SetClipper(p,a) ICOM_CALL1(SetClipper,p,a) +#define IDirectDrawSurface_SetColorKey(p,a,b) ICOM_CALL2(SetColorKey,p,a,b) +#define IDirectDrawSurface_SetOverlayPosition(p,a,b) ICOM_CALL2(SetOverlayPosition,p,a,b) +#define IDirectDrawSurface_SetPalette(p,a) ICOM_CALL1(SetPalette,p,a) +#define IDirectDrawSurface_Unlock(p,a) ICOM_CALL1(Unlock,p,a) +#define IDirectDrawSurface_UpdateOverlay(p,a,b,c,d,e) ICOM_CALL5(UpdateOverlay,p,a,b,c,d,e) +#define IDirectDrawSurface_UpdateOverlayDisplay(p,a) ICOM_CALL1(UpdateOverlayDisplay,p,a) +#define IDirectDrawSurface_UpdateOverlayZOrder(p,a,b) ICOM_CALL2(UpdateOverlayZOrder,p,a,b) + + +/***************************************************************************** + * IDirectDrawSurface2 interface + */ +/* Cannot inherit from IDirectDrawSurface because the LPDIRECTDRAWSURFACE parameters + * have been converted to LPDIRECTDRAWSURFACE2. + */ +#define ICOM_INTERFACE IDirectDrawSurface2 +#define IDirectDrawSurface2_METHODS \ + ICOM_METHOD1(HRESULT,AddAttachedSurface, LPDIRECTDRAWSURFACE2,lpDDSAttachedSurface) \ + ICOM_METHOD1(HRESULT,AddOverlayDirtyRect, LPRECT,lpRect) \ + ICOM_METHOD5(HRESULT,Blt, LPRECT,lpDestRect, LPDIRECTDRAWSURFACE2,lpDDSrcSurface, LPRECT,lpSrcRect, DWORD,dwFlags, LPDDBLTFX,lpDDBltFx) \ + ICOM_METHOD3(HRESULT,BltBatch, LPDDBLTBATCH,lpDDBltBatch, DWORD,dwCount, DWORD,dwFlags) \ + ICOM_METHOD5(HRESULT,BltFast, DWORD,dwX, DWORD,dwY, LPDIRECTDRAWSURFACE2,lpDDSrcSurface, LPRECT,lpSrcRect, DWORD,dwTrans) \ + ICOM_METHOD2(HRESULT,DeleteAttachedSurface, DWORD,dwFlags, LPDIRECTDRAWSURFACE2,lpDDSAttachedSurface) \ + ICOM_METHOD2(HRESULT,EnumAttachedSurfaces, LPVOID,lpContext, LPDDENUMSURFACESCALLBACK,lpEnumSurfacesCallback) \ + ICOM_METHOD3(HRESULT,EnumOverlayZOrders, DWORD,dwFlags, LPVOID,lpContext, LPDDENUMSURFACESCALLBACK,lpfnCallback) \ + ICOM_METHOD2(HRESULT,Flip, LPDIRECTDRAWSURFACE2,lpDDSurfaceTargetOverride, DWORD,dwFlags) \ + ICOM_METHOD2(HRESULT,GetAttachedSurface, LPDDSCAPS,lpDDSCaps, LPDIRECTDRAWSURFACE2*,lplpDDAttachedSurface) \ + ICOM_METHOD1(HRESULT,GetBltStatus, DWORD,dwFlags) \ + ICOM_METHOD1(HRESULT,GetCaps, LPDDSCAPS,lpDDSCaps) \ + ICOM_METHOD1(HRESULT,GetClipper, LPDIRECTDRAWCLIPPER*,lplpDDClipper) \ + ICOM_METHOD2(HRESULT,GetColorKey, DWORD,dwFlags, LPDDCOLORKEY,lpDDColorKey) \ + ICOM_METHOD1(HRESULT,GetDC, HDC*,lphDC) \ + ICOM_METHOD1(HRESULT,GetFlipStatus, DWORD,dwFlags) \ + ICOM_METHOD2(HRESULT,GetOverlayPosition, LPLONG,lplX, LPLONG,lplY) \ + ICOM_METHOD1(HRESULT,GetPalette, LPDIRECTDRAWPALETTE*,lplpDDPalette) \ + ICOM_METHOD1(HRESULT,GetPixelFormat, LPDDPIXELFORMAT,lpDDPixelFormat) \ + ICOM_METHOD1(HRESULT,GetSurfaceDesc, LPDDSURFACEDESC,lpDDSurfaceDesc) \ + ICOM_METHOD2(HRESULT,Initialize, LPDIRECTDRAW,lpDD, LPDDSURFACEDESC,lpDDSurfaceDesc) \ + ICOM_METHOD (HRESULT,IsLost) \ + ICOM_METHOD4(HRESULT,Lock, LPRECT,lpDestRect, LPDDSURFACEDESC,lpDDSurfaceDesc, DWORD,dwFlags, HANDLE,hEvent) \ + ICOM_METHOD1(HRESULT,ReleaseDC, HDC,hDC) \ + ICOM_METHOD (HRESULT,Restore) \ + ICOM_METHOD1(HRESULT,SetClipper, LPDIRECTDRAWCLIPPER,lpDDClipper) \ + ICOM_METHOD2(HRESULT,SetColorKey, DWORD,dwFlags, LPDDCOLORKEY,lpDDColorKey) \ + ICOM_METHOD2(HRESULT,SetOverlayPosition, LONG,lX, LONG,lY) \ + ICOM_METHOD1(HRESULT,SetPalette, LPDIRECTDRAWPALETTE,lpDDPalette) \ + ICOM_METHOD1(HRESULT,Unlock, LPVOID,lpSurfaceData) \ + ICOM_METHOD5(HRESULT,UpdateOverlay, LPRECT,lpSrcRect, LPDIRECTDRAWSURFACE2,lpDDDestSurface, LPRECT,lpDestRect, DWORD,dwFlags, LPDDOVERLAYFX,lpDDOverlayFx) \ + ICOM_METHOD1(HRESULT,UpdateOverlayDisplay, DWORD,dwFlags) \ + ICOM_METHOD2(HRESULT,UpdateOverlayZOrder, DWORD,dwFlags, LPDIRECTDRAWSURFACE2,lpDDSReference) \ + /* added in v2 */ \ + ICOM_METHOD1(HRESULT,GetDDInterface, LPVOID*,lplpDD) \ + ICOM_METHOD1(HRESULT,PageLock, DWORD,dwFlags) \ + ICOM_METHOD1(HRESULT,PageUnlock, DWORD,dwFlags) +#define IDirectDrawSurface2_IMETHODS \ + IUnknown_IMETHODS \ + IDirectDrawSurface2_METHODS +ICOM_DEFINE(IDirectDrawSurface2,IUnknown) +#undef ICOM_INTERFACE + + /*** IUnknown methods ***/ +#define IDirectDrawSurface2_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDirectDrawSurface2_AddRef(p) ICOM_CALL (AddRef,p) +#define IDirectDrawSurface2_Release(p) ICOM_CALL (Release,p) +/*** IDirectDrawSurface methods (almost) ***/ +#define IDirectDrawSurface2_AddAttachedSurface(p,a) ICOM_CALL1(AddAttachedSurface,p,a) +#define IDirectDrawSurface2_AddOverlayDirtyRect(p,a) ICOM_CALL1(AddOverlayDirtyRect,p,a) +#define IDirectDrawSurface2_Blt(p,a,b,c,d,e) ICOM_CALL5(Blt,p,a,b,c,d,e) +#define IDirectDrawSurface2_BltBatch(p,a,b,c) ICOM_CALL3(BltBatch,p,a,b,c) +#define IDirectDrawSurface2_BltFast(p,a,b,c,d,e) ICOM_CALL5(BltFast,p,a,b,c,d,e) +#define IDirectDrawSurface2_DeleteAttachedSurface(p,a,b) ICOM_CALL2(DeleteAttachedSurface,p,a,b) +#define IDirectDrawSurface2_EnumAttachedSurfaces(p,a,b) ICOM_CALL2(EnumAttachedSurfaces,p,a,b) +#define IDirectDrawSurface2_EnumOverlayZOrders(p,a,b,c) ICOM_CALL3(EnumOverlayZOrders,p,a,b,c) +#define IDirectDrawSurface2_Flip(p,a,b) ICOM_CALL2(Flip,p,a,b) +#define IDirectDrawSurface2_GetAttachedSurface(p,a,b) ICOM_CALL2(GetAttachedSurface,p,a,b) +#define IDirectDrawSurface2_GetBltStatus(p,a) ICOM_CALL1(GetBltStatus,p,a) +#define IDirectDrawSurface2_GetCaps(p,a) ICOM_CALL1(GetCaps,p,a) +#define IDirectDrawSurface2_GetClipper(p,a) ICOM_CALL1(GetClipper,p,a) +#define IDirectDrawSurface2_GetColorKey(p,a,b) ICOM_CALL2(GetColorKey,p,a,b) +#define IDirectDrawSurface2_GetDC(p,a) ICOM_CALL1(GetDC,p,a) +#define IDirectDrawSurface2_GetFlipStatus(p,a) ICOM_CALL1(GetFlipStatus,p,a) +#define IDirectDrawSurface2_GetOverlayPosition(p,a,b) ICOM_CALL2(GetOverlayPosition,p,a,b) +#define IDirectDrawSurface2_GetPalette(p,a) ICOM_CALL1(GetPalette,p,a) +#define IDirectDrawSurface2_GetPixelFormat(p,a) ICOM_CALL1(GetPixelFormat,p,a) +#define IDirectDrawSurface2_GetSurfaceDesc(p,a) ICOM_CALL1(GetSurfaceDesc,p,a) +#define IDirectDrawSurface2_Initialize(p,a,b) ICOM_CALL2(Initialize,p,a,b) +#define IDirectDrawSurface2_IsLost(p) ICOM_CALL (IsLost,p) +#define IDirectDrawSurface2_Lock(p,a,b,c,d) ICOM_CALL4(Lock,p,a,b,c,d) +#define IDirectDrawSurface2_ReleaseDC(p,a) ICOM_CALL1(ReleaseDC,p,a) +#define IDirectDrawSurface2_Restore(p) ICOM_CALL (Restore,p) +#define IDirectDrawSurface2_SetClipper(p,a) ICOM_CALL1(SetClipper,p,a) +#define IDirectDrawSurface2_SetColorKey(p,a,b) ICOM_CALL2(SetColorKey,p,a,b) +#define IDirectDrawSurface2_SetOverlayPosition(p,a,b) ICOM_CALL2(SetOverlayPosition,p,a,b) +#define IDirectDrawSurface2_SetPalette(p,a) ICOM_CALL1(SetPalette,p,a) +#define IDirectDrawSurface2_Unlock(p,a) ICOM_CALL1(Unlock,p,a) +#define IDirectDrawSurface2_UpdateOverlay(p,a,b,c,d,e) ICOM_CALL5(UpdateOverlay,p,a,b,c,d,e) +#define IDirectDrawSurface2_UpdateOverlayDisplay(p,a) ICOM_CALL1(UpdateOverlayDisplay,p,a) +#define IDirectDrawSurface2_UpdateOverlayZOrder(p,a,b) ICOM_CALL2(UpdateOverlayZOrder,p,a,b) +/*** IDirectDrawSurface2 methods ***/ +#define IDirectDrawSurface2_GetDDInterface(p,a) ICOM_CALL1(GetDDInterface,p,a) +#define IDirectDrawSurface2_PageLock(p,a) ICOM_CALL1(PageLock,p,a) +#define IDirectDrawSurface2_PageUnlock(p,a) ICOM_CALL1(PageUnlock,p,a) + + +/***************************************************************************** + * IDirectDrawSurface3 interface + */ +/* Cannot inherit from IDirectDrawSurface2 because the LPDIRECTDRAWSURFACE2 parameters + * have been converted to LPDIRECTDRAWSURFACE3. + */ +#define ICOM_INTERFACE IDirectDrawSurface3 +#define IDirectDrawSurface3_METHODS \ + ICOM_METHOD1(HRESULT,AddAttachedSurface, LPDIRECTDRAWSURFACE3,lpDDSAttachedSurface) \ + ICOM_METHOD1(HRESULT,AddOverlayDirtyRect, LPRECT,lpRect) \ + ICOM_METHOD5(HRESULT,Blt, LPRECT,lpDestRect, LPDIRECTDRAWSURFACE3,lpDDSrcSurface, LPRECT,lpSrcRect, DWORD,dwFlags, LPDDBLTFX,lpDDBltFx) \ + ICOM_METHOD3(HRESULT,BltBatch, LPDDBLTBATCH,lpDDBltBatch, DWORD,dwCount, DWORD,dwFlags) \ + ICOM_METHOD5(HRESULT,BltFast, DWORD,dwX, DWORD,dwY, LPDIRECTDRAWSURFACE3,lpDDSrcSurface, LPRECT,lpSrcRect, DWORD,dwTrans) \ + ICOM_METHOD2(HRESULT,DeleteAttachedSurface, DWORD,dwFlags, LPDIRECTDRAWSURFACE3,lpDDSAttachedSurface) \ + ICOM_METHOD2(HRESULT,EnumAttachedSurfaces, LPVOID,lpContext, LPDDENUMSURFACESCALLBACK,lpEnumSurfacesCallback) \ + ICOM_METHOD3(HRESULT,EnumOverlayZOrders, DWORD,dwFlags, LPVOID,lpContext, LPDDENUMSURFACESCALLBACK,lpfnCallback) \ + ICOM_METHOD2(HRESULT,Flip, LPDIRECTDRAWSURFACE3,lpDDSurfaceTargetOverride, DWORD,dwFlags) \ + ICOM_METHOD2(HRESULT,GetAttachedSurface, LPDDSCAPS,lpDDSCaps, LPDIRECTDRAWSURFACE3*,lplpDDAttachedSurface) \ + ICOM_METHOD1(HRESULT,GetBltStatus, DWORD,dwFlags) \ + ICOM_METHOD1(HRESULT,GetCaps, LPDDSCAPS,lpDDSCaps) \ + ICOM_METHOD1(HRESULT,GetClipper, LPDIRECTDRAWCLIPPER*,lplpDDClipper) \ + ICOM_METHOD2(HRESULT,GetColorKey, DWORD,dwFlags, LPDDCOLORKEY,lpDDColorKey) \ + ICOM_METHOD1(HRESULT,GetDC, HDC*,lphDC) \ + ICOM_METHOD1(HRESULT,GetFlipStatus, DWORD,dwFlags) \ + ICOM_METHOD2(HRESULT,GetOverlayPosition, LPLONG,lplX, LPLONG,lplY) \ + ICOM_METHOD1(HRESULT,GetPalette, LPDIRECTDRAWPALETTE*,lplpDDPalette) \ + ICOM_METHOD1(HRESULT,GetPixelFormat, LPDDPIXELFORMAT,lpDDPixelFormat) \ + ICOM_METHOD1(HRESULT,GetSurfaceDesc, LPDDSURFACEDESC,lpDDSurfaceDesc) \ + ICOM_METHOD2(HRESULT,Initialize, LPDIRECTDRAW,lpDD, LPDDSURFACEDESC,lpDDSurfaceDesc) \ + ICOM_METHOD (HRESULT,IsLost) \ + ICOM_METHOD4(HRESULT,Lock, LPRECT,lpDestRect, LPDDSURFACEDESC,lpDDSurfaceDesc, DWORD,dwFlags, HANDLE,hEvent) \ + ICOM_METHOD1(HRESULT,ReleaseDC, HDC,hDC) \ + ICOM_METHOD (HRESULT,Restore) \ + ICOM_METHOD1(HRESULT,SetClipper, LPDIRECTDRAWCLIPPER,lpDDClipper) \ + ICOM_METHOD2(HRESULT,SetColorKey, DWORD,dwFlags, LPDDCOLORKEY,lpDDColorKey) \ + ICOM_METHOD2(HRESULT,SetOverlayPosition, LONG,lX, LONG,lY) \ + ICOM_METHOD1(HRESULT,SetPalette, LPDIRECTDRAWPALETTE,lpDDPalette) \ + ICOM_METHOD1(HRESULT,Unlock, LPVOID,lpSurfaceData) \ + ICOM_METHOD5(HRESULT,UpdateOverlay, LPRECT,lpSrcRect, LPDIRECTDRAWSURFACE3,lpDDDestSurface, LPRECT,lpDestRect, DWORD,dwFlags, LPDDOVERLAYFX,lpDDOverlayFx) \ + ICOM_METHOD1(HRESULT,UpdateOverlayDisplay, DWORD,dwFlags) \ + ICOM_METHOD2(HRESULT,UpdateOverlayZOrder, DWORD,dwFlags, LPDIRECTDRAWSURFACE3,lpDDSReference) \ + /* added in v2 */ \ + ICOM_METHOD1(HRESULT,GetDDInterface, LPVOID*,lplpDD) \ + ICOM_METHOD1(HRESULT,PageLock, DWORD,dwFlags) \ + ICOM_METHOD1(HRESULT,PageUnlock, DWORD,dwFlags) \ + /* added in v3 */ \ + ICOM_METHOD2(HRESULT,SetSurfaceDesc, LPDDSURFACEDESC,lpDDSD, DWORD,dwFlags) +#define IDirectDrawSurface3_IMETHODS \ + IUnknown_IMETHODS \ + IDirectDrawSurface3_METHODS +ICOM_DEFINE(IDirectDrawSurface3,IUnknown) +#undef ICOM_INTERFACE + + /*** IUnknown methods ***/ +#define IDirectDrawSurface3_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDirectDrawSurface3_AddRef(p) ICOM_CALL (AddRef,p) +#define IDirectDrawSurface3_Release(p) ICOM_CALL (Release,p) +/*** IDirectDrawSurface methods (almost) ***/ +#define IDirectDrawSurface3_AddAttachedSurface(p,a) ICOM_CALL1(AddAttachedSurface,p,a) +#define IDirectDrawSurface3_AddOverlayDirtyRect(p,a) ICOM_CALL1(AddOverlayDirtyRect,p,a) +#define IDirectDrawSurface3_Blt(p,a,b,c,d,e) ICOM_CALL5(Blt,p,a,b,c,d,e) +#define IDirectDrawSurface3_BltBatch(p,a,b,c) ICOM_CALL3(BltBatch,p,a,b,c) +#define IDirectDrawSurface3_BltFast(p,a,b,c,d,e) ICOM_CALL5(BltFast,p,a,b,c,d,e) +#define IDirectDrawSurface3_DeleteAttachedSurface(p,a,b) ICOM_CALL2(DeleteAttachedSurface,p,a,b) +#define IDirectDrawSurface3_EnumAttachedSurfaces(p,a,b) ICOM_CALL2(EnumAttachedSurfaces,p,a,b) +#define IDirectDrawSurface3_EnumOverlayZOrders(p,a,b,c) ICOM_CALL3(EnumOverlayZOrders,p,a,b,c) +#define IDirectDrawSurface3_Flip(p,a,b) ICOM_CALL2(Flip,p,a,b) +#define IDirectDrawSurface3_GetAttachedSurface(p,a,b) ICOM_CALL2(GetAttachedSurface,p,a,b) +#define IDirectDrawSurface3_GetBltStatus(p,a) ICOM_CALL1(GetBltStatus,p,a) +#define IDirectDrawSurface3_GetCaps(p,a) ICOM_CALL1(GetCaps,p,a) +#define IDirectDrawSurface3_GetClipper(p,a) ICOM_CALL1(GetClipper,p,a) +#define IDirectDrawSurface3_GetColorKey(p,a,b) ICOM_CALL2(GetColorKey,p,a,b) +#define IDirectDrawSurface3_GetDC(p,a) ICOM_CALL1(GetDC,p,a) +#define IDirectDrawSurface3_GetFlipStatus(p,a) ICOM_CALL1(GetFlipStatus,p,a) +#define IDirectDrawSurface3_GetOverlayPosition(p,a,b) ICOM_CALL2(GetOverlayPosition,p,a,b) +#define IDirectDrawSurface3_GetPalette(p,a) ICOM_CALL1(GetPalette,p,a) +#define IDirectDrawSurface3_GetPixelFormat(p,a) ICOM_CALL1(GetPixelFormat,p,a) +#define IDirectDrawSurface3_GetSurfaceDesc(p,a) ICOM_CALL1(GetSurfaceDesc,p,a) +#define IDirectDrawSurface3_Initialize(p,a,b) ICOM_CALL2(Initialize,p,a,b) +#define IDirectDrawSurface3_IsLost(p) ICOM_CALL (IsLost,p) +#define IDirectDrawSurface3_Lock(p,a,b,c,d) ICOM_CALL4(Lock,p,a,b,c,d) +#define IDirectDrawSurface3_ReleaseDC(p,a) ICOM_CALL1(ReleaseDC,p,a) +#define IDirectDrawSurface3_Restore(p) ICOM_CALL (Restore,p) +#define IDirectDrawSurface3_SetClipper(p,a) ICOM_CALL1(SetClipper,p,a) +#define IDirectDrawSurface3_SetColorKey(p,a,b) ICOM_CALL2(SetColorKey,p,a,b) +#define IDirectDrawSurface3_SetOverlayPosition(p,a,b) ICOM_CALL2(SetOverlayPosition,p,a,b) +#define IDirectDrawSurface3_SetPalette(p,a) ICOM_CALL1(SetPalette,p,a) +#define IDirectDrawSurface3_Unlock(p,a) ICOM_CALL1(Unlock,p,a) +#define IDirectDrawSurface3_UpdateOverlay(p,a,b,c,d,e) ICOM_CALL5(UpdateOverlay,p,a,b,c,d,e) +#define IDirectDrawSurface3_UpdateOverlayDisplay(p,a) ICOM_CALL1(UpdateOverlayDisplay,p,a) +#define IDirectDrawSurface3_UpdateOverlayZOrder(p,a,b) ICOM_CALL2(UpdateOverlayZOrder,p,a,b) +/*** IDirectDrawSurface2 methods ***/ +#define IDirectDrawSurface3_GetDDInterface(p,a) ICOM_CALL1(GetDDInterface,p,a) +#define IDirectDrawSurface3_PageLock(p,a) ICOM_CALL1(PageLock,p,a) +#define IDirectDrawSurface3_PageUnlock(p,a) ICOM_CALL1(PageUnlock,p,a) +/*** IDirectDrawSurface3 methods ***/ +#define IDirectDrawSurface3_SetSurfaceDesc(p,a,b) ICOM_CALL2(SetSurfaceDesc,p,a,b) + + +/***************************************************************************** + * IDirectDrawSurface4 interface + */ +/* Cannot inherit from IDirectDrawSurface2 because DDSCAPS changed to DDSCAPS2. + */ +#define ICOM_INTERFACE IDirectDrawSurface4 +#define IDirectDrawSurface4_METHODS \ + ICOM_METHOD1(HRESULT,AddAttachedSurface, LPDIRECTDRAWSURFACE4,lpDDSAttachedSurface) \ + ICOM_METHOD1(HRESULT,AddOverlayDirtyRect, LPRECT,lpRect) \ + ICOM_METHOD5(HRESULT,Blt, LPRECT,lpDestRect, LPDIRECTDRAWSURFACE4,lpDDSrcSurface, LPRECT,lpSrcRect, DWORD,dwFlags, LPDDBLTFX,lpDDBltFx) \ + ICOM_METHOD3(HRESULT,BltBatch, LPDDBLTBATCH,lpDDBltBatch, DWORD,dwCount, DWORD,dwFlags) \ + ICOM_METHOD5(HRESULT,BltFast, DWORD,dwX, DWORD,dwY, LPDIRECTDRAWSURFACE4,lpDDSrcSurface, LPRECT,lpSrcRect, DWORD,dwTrans) \ + ICOM_METHOD2(HRESULT,DeleteAttachedSurface, DWORD,dwFlags, LPDIRECTDRAWSURFACE4,lpDDSAttachedSurface) \ + ICOM_METHOD2(HRESULT,EnumAttachedSurfaces, LPVOID,lpContext, LPDDENUMSURFACESCALLBACK,lpEnumSurfacesCallback) \ + ICOM_METHOD3(HRESULT,EnumOverlayZOrders, DWORD,dwFlags, LPVOID,lpContext, LPDDENUMSURFACESCALLBACK,lpfnCallback) \ + ICOM_METHOD2(HRESULT,Flip, LPDIRECTDRAWSURFACE4,lpDDSurfaceTargetOverride, DWORD,dwFlags) \ + ICOM_METHOD2(HRESULT,GetAttachedSurface, LPDDSCAPS2,lpDDSCaps, LPDIRECTDRAWSURFACE4*,lplpDDAttachedSurface) \ + ICOM_METHOD1(HRESULT,GetBltStatus, DWORD,dwFlags) \ + ICOM_METHOD1(HRESULT,GetCaps, LPDDSCAPS2,lpDDSCaps) \ + ICOM_METHOD1(HRESULT,GetClipper, LPDIRECTDRAWCLIPPER*,lplpDDClipper) \ + ICOM_METHOD2(HRESULT,GetColorKey, DWORD,dwFlags, LPDDCOLORKEY,lpDDColorKey) \ + ICOM_METHOD1(HRESULT,GetDC, HDC*,lphDC) \ + ICOM_METHOD1(HRESULT,GetFlipStatus, DWORD,dwFlags) \ + ICOM_METHOD2(HRESULT,GetOverlayPosition, LPLONG,lplX, LPLONG,lplY) \ + ICOM_METHOD1(HRESULT,GetPalette, LPDIRECTDRAWPALETTE*,lplpDDPalette) \ + ICOM_METHOD1(HRESULT,GetPixelFormat, LPDDPIXELFORMAT,lpDDPixelFormat) \ + ICOM_METHOD1(HRESULT,GetSurfaceDesc, LPDDSURFACEDESC,lpDDSurfaceDesc) \ + ICOM_METHOD2(HRESULT,Initialize, LPDIRECTDRAW,lpDD, LPDDSURFACEDESC,lpDDSurfaceDesc) \ + ICOM_METHOD (HRESULT,IsLost) \ + ICOM_METHOD4(HRESULT,Lock, LPRECT,lpDestRect, LPDDSURFACEDESC,lpDDSurfaceDesc, DWORD,dwFlags, HANDLE,hEvent) \ + ICOM_METHOD1(HRESULT,ReleaseDC, HDC,hDC) \ + ICOM_METHOD (HRESULT,Restore) \ + ICOM_METHOD1(HRESULT,SetClipper, LPDIRECTDRAWCLIPPER,lpDDClipper) \ + ICOM_METHOD2(HRESULT,SetColorKey, DWORD,dwFlags, LPDDCOLORKEY,lpDDColorKey) \ + ICOM_METHOD2(HRESULT,SetOverlayPosition, LONG,lX, LONG,lY) \ + ICOM_METHOD1(HRESULT,SetPalette, LPDIRECTDRAWPALETTE,lpDDPalette) \ + ICOM_METHOD1(HRESULT,Unlock, LPRECT,lpSurfaceData) \ + ICOM_METHOD5(HRESULT,UpdateOverlay, LPRECT,lpSrcRect, LPDIRECTDRAWSURFACE4,lpDDDestSurface, LPRECT,lpDestRect, DWORD,dwFlags, LPDDOVERLAYFX,lpDDOverlayFx) \ + ICOM_METHOD1(HRESULT,UpdateOverlayDisplay, DWORD,dwFlags) \ + ICOM_METHOD2(HRESULT,UpdateOverlayZOrder, DWORD,dwFlags, LPDIRECTDRAWSURFACE4,lpDDSReference) \ + /* added in v2 */ \ + ICOM_METHOD1(HRESULT,GetDDInterface, LPVOID*,lplpDD) \ + ICOM_METHOD1(HRESULT,PageLock, DWORD,dwFlags) \ + ICOM_METHOD1(HRESULT,PageUnlock, DWORD,dwFlags) \ + /* added in v3 */ \ + ICOM_METHOD2(HRESULT,SetSurfaceDesc, LPDDSURFACEDESC,lpDDSD, DWORD,dwFlags) \ + /* added in v4 */ \ + ICOM_METHOD4(HRESULT,SetPrivateData, REFGUID,, LPVOID,, DWORD,, DWORD,) \ + ICOM_METHOD3(HRESULT,GetPrivateData, REFGUID,, LPVOID,, LPDWORD,) \ + ICOM_METHOD1(HRESULT,FreePrivateData, REFGUID,) \ + ICOM_METHOD1(HRESULT,GetUniquenessValue, LPDWORD,) \ + ICOM_METHOD (HRESULT,ChangeUniquenessValue) +#define IDirectDrawSurface4_IMETHODS \ + IUnknown_IMETHODS \ + IDirectDrawSurface4_METHODS +ICOM_DEFINE(IDirectDrawSurface4,IUnknown) +#undef ICOM_INTERFACE + + /*** IUnknown methods ***/ +#define IDirectDrawSurface4_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDirectDrawSurface4_AddRef(p) ICOM_CALL (AddRef,p) +#define IDirectDrawSurface4_Release(p) ICOM_CALL (Release,p) +/*** IDirectDrawSurface (almost) methods ***/ +#define IDirectDrawSurface4_AddAttachedSurface(p,a) ICOM_CALL1(AddAttachedSurface,p,a) +#define IDirectDrawSurface4_AddOverlayDirtyRect(p,a) ICOM_CALL1(AddOverlayDirtyRect,p,a) +#define IDirectDrawSurface4_Blt(p,a,b,c,d,e) ICOM_CALL5(Blt,p,a,b,c,d,e) +#define IDirectDrawSurface4_BltBatch(p,a,b,c) ICOM_CALL3(BltBatch,p,a,b,c) +#define IDirectDrawSurface4_BltFast(p,a,b,c,d,e) ICOM_CALL5(BltFast,p,a,b,c,d,e) +#define IDirectDrawSurface4_DeleteAttachedSurface(p,a,b) ICOM_CALL2(DeleteAttachedSurface,p,a,b) +#define IDirectDrawSurface4_EnumAttachedSurfaces(p,a,b) ICOM_CALL2(EnumAttachedSurfaces,p,a,b) +#define IDirectDrawSurface4_EnumOverlayZOrders(p,a,b,c) ICOM_CALL3(EnumOverlayZOrders,p,a,b,c) +#define IDirectDrawSurface4_Flip(p,a,b) ICOM_CALL2(Flip,p,a,b) +#define IDirectDrawSurface4_GetAttachedSurface(p,a,b) ICOM_CALL2(GetAttachedSurface,p,a,b) +#define IDirectDrawSurface4_GetBltStatus(p,a) ICOM_CALL1(GetBltStatus,p,a) +#define IDirectDrawSurface4_GetCaps(p,a) ICOM_CALL1(GetCaps,p,a) +#define IDirectDrawSurface4_GetClipper(p,a) ICOM_CALL1(GetClipper,p,a) +#define IDirectDrawSurface4_GetColorKey(p,a,b) ICOM_CALL2(GetColorKey,p,a,b) +#define IDirectDrawSurface4_GetDC(p,a) ICOM_CALL1(GetDC,p,a) +#define IDirectDrawSurface4_GetFlipStatus(p,a) ICOM_CALL1(GetFlipStatus,p,a) +#define IDirectDrawSurface4_GetOverlayPosition(p,a,b) ICOM_CALL2(GetOverlayPosition,p,a,b) +#define IDirectDrawSurface4_GetPalette(p,a) ICOM_CALL1(GetPalette,p,a) +#define IDirectDrawSurface4_GetPixelFormat(p,a) ICOM_CALL1(GetPixelFormat,p,a) +#define IDirectDrawSurface4_GetSurfaceDesc(p,a) ICOM_CALL1(GetSurfaceDesc,p,a) +#define IDirectDrawSurface4_Initialize(p,a,b) ICOM_CALL2(Initialize,p,a,b) +#define IDirectDrawSurface4_IsLost(p) ICOM_CALL (IsLost,p) +#define IDirectDrawSurface4_Lock(p,a,b,c,d) ICOM_CALL4(Lock,p,a,b,c,d) +#define IDirectDrawSurface4_ReleaseDC(p,a) ICOM_CALL1(ReleaseDC,p,a) +#define IDirectDrawSurface4_Restore(p) ICOM_CALL (Restore,p) +#define IDirectDrawSurface4_SetClipper(p,a) ICOM_CALL1(SetClipper,p,a) +#define IDirectDrawSurface4_SetColorKey(p,a,b) ICOM_CALL2(SetColorKey,p,a,b) +#define IDirectDrawSurface4_SetOverlayPosition(p,a,b) ICOM_CALL2(SetOverlayPosition,p,a,b) +#define IDirectDrawSurface4_SetPalette(p,a) ICOM_CALL1(SetPalette,p,a) +#define IDirectDrawSurface4_Unlock(p,a) ICOM_CALL1(Unlock,p,a) +#define IDirectDrawSurface4_UpdateOverlay(p,a,b,c,d,e) ICOM_CALL5(UpdateOverlay,p,a,b,c,d,e) +#define IDirectDrawSurface4_UpdateOverlayDisplay(p,a) ICOM_CALL1(UpdateOverlayDisplay,p,a) +#define IDirectDrawSurface4_UpdateOverlayZOrder(p,a,b) ICOM_CALL2(UpdateOverlayZOrder,p,a,b) +/*** IDirectDrawSurface2 methods ***/ +#define IDirectDrawSurface4_GetDDInterface(p,a) ICOM_CALL1(GetDDInterface,p,a) +#define IDirectDrawSurface4_PageLock(p,a) ICOM_CALL1(PageLock,p,a) +#define IDirectDrawSurface4_PageUnlock(p,a) ICOM_CALL1(PageUnlock,p,a) +/*** IDirectDrawSurface3 methods ***/ +#define IDirectDrawSurface4_SetSurfaceDesc(p,a,b) ICOM_CALL2(SetSurfaceDesc,p,a,b) +/*** IDirectDrawSurface4 methods ***/ +#define IDirectDrawSurface4_SetPrivateData(p,a,b,c,d) ICOM_CALL4(SetPrivateData,p,a,b,c,d) +#define IDirectDrawSurface4_GetPrivateData(p,a,b,c) ICOM_CALL3(GetPrivateData,p,a,b,c) +#define IDirectDrawSurface4_FreePrivateData(p,a) ICOM_CALL1(FreePrivateData,p,a) +#define IDirectDrawSurface4_GetUniquenessValue(p,a) ICOM_CALL1(GetUniquenessValue,p,a) +#define IDirectDrawSurface4_ChangeUniquenessValue(p) ICOM_CALL (ChangeUniquenessValue,p) + + +/***************************************************************************** + * IDirectDrawSurface7 interface + */ +#define ICOM_INTERFACE IDirectDrawSurface7 +#define IDirectDrawSurface7_METHODS \ + ICOM_METHOD1(HRESULT,AddAttachedSurface, LPDIRECTDRAWSURFACE7,lpDDSAttachedSurface) \ + ICOM_METHOD1(HRESULT,AddOverlayDirtyRect, LPRECT,lpRect) \ + ICOM_METHOD5(HRESULT,Blt, LPRECT,lpDestRect, LPDIRECTDRAWSURFACE7,lpDDSrcSurface, LPRECT,lpSrcRect, DWORD,dwFlags, LPDDBLTFX,lpDDBltFx) \ + ICOM_METHOD3(HRESULT,BltBatch, LPDDBLTBATCH,lpDDBltBatch, DWORD,dwCount, DWORD,dwFlags) \ + ICOM_METHOD5(HRESULT,BltFast, DWORD,dwX, DWORD,dwY, LPDIRECTDRAWSURFACE7,lpDDSrcSurface, LPRECT,lpSrcRect, DWORD,dwTrans) \ + ICOM_METHOD2(HRESULT,DeleteAttachedSurface, DWORD,dwFlags, LPDIRECTDRAWSURFACE7,lpDDSAttachedSurface) \ + ICOM_METHOD2(HRESULT,EnumAttachedSurfaces, LPVOID,lpContext, LPDDENUMSURFACESCALLBACK7,lpEnumSurfacesCallback) \ + ICOM_METHOD3(HRESULT,EnumOverlayZOrders, DWORD,dwFlags, LPVOID,lpContext, LPDDENUMSURFACESCALLBACK7,lpfnCallback) \ + ICOM_METHOD2(HRESULT,Flip, LPDIRECTDRAWSURFACE7,lpDDSurfaceTargetOverride, DWORD,dwFlags) \ + ICOM_METHOD2(HRESULT,GetAttachedSurface, LPDDSCAPS2,lpDDSCaps, LPDIRECTDRAWSURFACE7*,lplpDDAttachedSurface) \ + ICOM_METHOD1(HRESULT,GetBltStatus, DWORD,dwFlags) \ + ICOM_METHOD1(HRESULT,GetCaps, LPDDSCAPS2,lpDDSCaps) \ + ICOM_METHOD1(HRESULT,GetClipper, LPDIRECTDRAWCLIPPER*,lplpDDClipper) \ + ICOM_METHOD2(HRESULT,GetColorKey, DWORD,dwFlags, LPDDCOLORKEY,lpDDColorKey) \ + ICOM_METHOD1(HRESULT,GetDC, HDC*,lphDC) \ + ICOM_METHOD1(HRESULT,GetFlipStatus, DWORD,dwFlags) \ + ICOM_METHOD2(HRESULT,GetOverlayPosition, LPLONG,lplX, LPLONG,lplY) \ + ICOM_METHOD1(HRESULT,GetPalette, LPDIRECTDRAWPALETTE*,lplpDDPalette) \ + ICOM_METHOD1(HRESULT,GetPixelFormat, LPDDPIXELFORMAT,lpDDPixelFormat) \ + ICOM_METHOD1(HRESULT,GetSurfaceDesc, LPDDSURFACEDESC2,lpDDSurfaceDesc) \ + ICOM_METHOD2(HRESULT,Initialize, LPDIRECTDRAW,lpDD, LPDDSURFACEDESC2,lpDDSurfaceDesc) \ + ICOM_METHOD (HRESULT,IsLost) \ + ICOM_METHOD4(HRESULT,Lock, LPRECT,lpDestRect, LPDDSURFACEDESC2,lpDDSurfaceDesc, DWORD,dwFlags, HANDLE,hEvent) \ + ICOM_METHOD1(HRESULT,ReleaseDC, HDC,hDC) \ + ICOM_METHOD (HRESULT,Restore) \ + ICOM_METHOD1(HRESULT,SetClipper, LPDIRECTDRAWCLIPPER,lpDDClipper) \ + ICOM_METHOD2(HRESULT,SetColorKey, DWORD,dwFlags, LPDDCOLORKEY,lpDDColorKey) \ + ICOM_METHOD2(HRESULT,SetOverlayPosition, LONG,lX, LONG,lY) \ + ICOM_METHOD1(HRESULT,SetPalette, LPDIRECTDRAWPALETTE,lpDDPalette) \ + ICOM_METHOD1(HRESULT,Unlock, LPRECT,lpSurfaceData) \ + ICOM_METHOD5(HRESULT,UpdateOverlay, LPRECT,lpSrcRect, LPDIRECTDRAWSURFACE7,lpDDDestSurface, LPRECT,lpDestRect, DWORD,dwFlags, LPDDOVERLAYFX,lpDDOverlayFx) \ + ICOM_METHOD1(HRESULT,UpdateOverlayDisplay, DWORD,dwFlags) \ + ICOM_METHOD2(HRESULT,UpdateOverlayZOrder, DWORD,dwFlags, LPDIRECTDRAWSURFACE7,lpDDSReference) \ + /* added in v2 */ \ + ICOM_METHOD1(HRESULT,GetDDInterface, LPVOID*,lplpDD) \ + ICOM_METHOD1(HRESULT,PageLock, DWORD,dwFlags) \ + ICOM_METHOD1(HRESULT,PageUnlock, DWORD,dwFlags) \ + /* added in v3 */ \ + ICOM_METHOD2(HRESULT,SetSurfaceDesc, LPDDSURFACEDESC2,lpDDSD, DWORD,dwFlags) \ + /* added in v4 */ \ + ICOM_METHOD4(HRESULT,SetPrivateData, REFGUID,, LPVOID,, DWORD,, DWORD,) \ + ICOM_METHOD3(HRESULT,GetPrivateData, REFGUID,, LPVOID,, LPDWORD,) \ + ICOM_METHOD1(HRESULT,FreePrivateData, REFGUID,) \ + ICOM_METHOD1(HRESULT,GetUniquenessValue, LPDWORD,) \ + ICOM_METHOD (HRESULT,ChangeUniquenessValue) \ + /* added in v7 */ \ + ICOM_METHOD1(HRESULT,SetPriority, DWORD,prio) \ + ICOM_METHOD1(HRESULT,GetPriority, LPDWORD,prio) \ + ICOM_METHOD1(HRESULT,SetLOD, DWORD,lod) \ + ICOM_METHOD1(HRESULT,GetLOD, LPDWORD,lod) +#define IDirectDrawSurface7_IMETHODS \ + IUnknown_IMETHODS \ + IDirectDrawSurface7_METHODS +ICOM_DEFINE(IDirectDrawSurface7,IUnknown) +#undef ICOM_INTERFACE + + /*** IUnknown methods ***/ +#define IDirectDrawSurface7_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDirectDrawSurface7_AddRef(p) ICOM_CALL (AddRef,p) +#define IDirectDrawSurface7_Release(p) ICOM_CALL (Release,p) +/*** IDirectDrawSurface (almost) methods ***/ +#define IDirectDrawSurface7_AddAttachedSurface(p,a) ICOM_CALL1(AddAttachedSurface,p,a) +#define IDirectDrawSurface7_AddOverlayDirtyRect(p,a) ICOM_CALL1(AddOverlayDirtyRect,p,a) +#define IDirectDrawSurface7_Blt(p,a,b,c,d,e) ICOM_CALL5(Blt,p,a,b,c,d,e) +#define IDirectDrawSurface7_BltBatch(p,a,b,c) ICOM_CALL3(BltBatch,p,a,b,c) +#define IDirectDrawSurface7_BltFast(p,a,b,c,d,e) ICOM_CALL5(BltFast,p,a,b,c,d,e) +#define IDirectDrawSurface7_DeleteAttachedSurface(p,a,b) ICOM_CALL2(DeleteAttachedSurface,p,a,b) +#define IDirectDrawSurface7_EnumAttachedSurfaces(p,a,b) ICOM_CALL2(EnumAttachedSurfaces,p,a,b) +#define IDirectDrawSurface7_EnumOverlayZOrders(p,a,b,c) ICOM_CALL3(EnumOverlayZOrders,p,a,b,c) +#define IDirectDrawSurface7_Flip(p,a,b) ICOM_CALL2(Flip,p,a,b) +#define IDirectDrawSurface7_GetAttachedSurface(p,a,b) ICOM_CALL2(GetAttachedSurface,p,a,b) +#define IDirectDrawSurface7_GetBltStatus(p,a) ICOM_CALL1(GetBltStatus,p,a) +#define IDirectDrawSurface7_GetCaps(p,a) ICOM_CALL1(GetCaps,p,a) +#define IDirectDrawSurface7_GetClipper(p,a) ICOM_CALL1(GetClipper,p,a) +#define IDirectDrawSurface7_GetColorKey(p,a,b) ICOM_CALL2(GetColorKey,p,a,b) +#define IDirectDrawSurface7_GetDC(p,a) ICOM_CALL1(GetDC,p,a) +#define IDirectDrawSurface7_GetFlipStatus(p,a) ICOM_CALL1(GetFlipStatus,p,a) +#define IDirectDrawSurface7_GetOverlayPosition(p,a,b) ICOM_CALL2(GetOverlayPosition,p,a,b) +#define IDirectDrawSurface7_GetPalette(p,a) ICOM_CALL1(GetPalette,p,a) +#define IDirectDrawSurface7_GetPixelFormat(p,a) ICOM_CALL1(GetPixelFormat,p,a) +#define IDirectDrawSurface7_GetSurfaceDesc(p,a) ICOM_CALL1(GetSurfaceDesc,p,a) +#define IDirectDrawSurface7_Initialize(p,a,b) ICOM_CALL2(Initialize,p,a,b) +#define IDirectDrawSurface7_IsLost(p) ICOM_CALL (IsLost,p) +#define IDirectDrawSurface7_Lock(p,a,b,c,d) ICOM_CALL4(Lock,p,a,b,c,d) +#define IDirectDrawSurface7_ReleaseDC(p,a) ICOM_CALL1(ReleaseDC,p,a) +#define IDirectDrawSurface7_Restore(p) ICOM_CALL (Restore,p) +#define IDirectDrawSurface7_SetClipper(p,a) ICOM_CALL1(SetClipper,p,a) +#define IDirectDrawSurface7_SetColorKey(p,a,b) ICOM_CALL2(SetColorKey,p,a,b) +#define IDirectDrawSurface7_SetOverlayPosition(p,a,b) ICOM_CALL2(SetOverlayPosition,p,a,b) +#define IDirectDrawSurface7_SetPalette(p,a) ICOM_CALL1(SetPalette,p,a) +#define IDirectDrawSurface7_Unlock(p,a) ICOM_CALL1(Unlock,p,a) +#define IDirectDrawSurface7_UpdateOverlay(p,a,b,c,d,e) ICOM_CALL5(UpdateOverlay,p,a,b,c,d,e) +#define IDirectDrawSurface7_UpdateOverlayDisplay(p,a) ICOM_CALL1(UpdateOverlayDisplay,p,a) +#define IDirectDrawSurface7_UpdateOverlayZOrder(p,a,b) ICOM_CALL2(UpdateOverlayZOrder,p,a,b) +/*** IDirectDrawSurface2 methods ***/ +#define IDirectDrawSurface7_GetDDInterface(p,a) ICOM_CALL1(GetDDInterface,p,a) +#define IDirectDrawSurface7_PageLock(p,a) ICOM_CALL1(PageLock,p,a) +#define IDirectDrawSurface7_PageUnlock(p,a) ICOM_CALL1(PageUnlock,p,a) +/*** IDirectDrawSurface3 methods ***/ +#define IDirectDrawSurface7_SetSurfaceDesc(p,a,b) ICOM_CALL2(SetSurfaceDesc,p,a,b) +/*** IDirectDrawSurface4 methods ***/ +#define IDirectDrawSurface7_SetPrivateData(p,a,b,c,d) ICOM_CALL4(SetPrivateData,p,a,b,c,d) +#define IDirectDrawSurface7_GetPrivateData(p,a,b,c) ICOM_CALL3(GetPrivateData,p,a,b,c) +#define IDirectDrawSurface7_FreePrivateData(p,a) ICOM_CALL1(FreePrivateData,p,a) +#define IDirectDrawSurface7_GetUniquenessValue(p,a) ICOM_CALL1(GetUniquenessValue,p,a) +#define IDirectDrawSurface7_ChangeUniquenessValue(p) ICOM_CALL (ChangeUniquenessValue,p) +/*** IDirectDrawSurface7 methods ***/ +#define IDirectDrawSurface7_SetPriority(p,a) ICOM_CALL1(SetPriority,p,a) +#define IDirectDrawSurface7_GetPriority(p,a) ICOM_CALL1(GetPriority,p,a) +#define IDirectDrawSurface7_SetLOD(p,a) ICOM_CALL1(SetLOD,p,a) +#define IDirectDrawSurface7_GetLOD(p,a) ICOM_CALL1(GetLOD,p,a) + +/***************************************************************************** + * IDirectDrawColorControl interface + */ +#define ICOM_INTERFACE IDirectDrawColorControl +#define IDirectDrawColorControl_METHODS \ + ICOM_METHOD1(HRESULT,GetColorControls, LPDDCOLORCONTROL,lpColorControl) \ + ICOM_METHOD1(HRESULT,SetColorControls, LPDDCOLORCONTROL,lpColorControl) +#define IDirectDrawColorControl_IMETHODS \ + IUnknown_IMETHODS \ + IDirectDrawColorControl_METHODS +ICOM_DEFINE(IDirectDrawColorControl,IUnknown) +#undef ICOM_INTERFACE + + /*** IUnknown methods ***/ +#define IDirectDrawColorControl_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDirectDrawColorControl_AddRef(p) ICOM_CALL (AddRef,p) +#define IDirectDrawColorControl_Release(p) ICOM_CALL (Release,p) + /*** IDirectDrawColorControl methods ***/ +#define IDirectDrawColorControl_GetColorControls(p,a) ICOM_CALL(GetColorControls,p,a) +#define IDirectDrawColorControl_SetColorControls(p,a) ICOM_CALL(SetColorControls,p,a) + +/***************************************************************************** + * IDirectDrawGammaControl interface + */ +#define ICOM_INTERFACE IDirectDrawGammaControl +#define IDirectDrawGammaControl_METHODS \ + ICOM_METHOD2(HRESULT,GetGammaRamp, DWORD,dwFlags, LPDDGAMMARAMP,lpGammaRamp) \ + ICOM_METHOD2(HRESULT,SetGammaRamp, DWORD,dwFlags, LPDDGAMMARAMP,lpGammaRamp) +#define IDirectDrawGammaControl_IMETHODS \ + IUnknown_IMETHODS \ + IDirectDrawGammaControl_METHODS +ICOM_DEFINE(IDirectDrawGammaControl,IUnknown) +#undef ICOM_INTERFACE + + /*** IUnknown methods ***/ +#define IDirectDrawGammaControl_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDirectDrawGammaControl_AddRef(p) ICOM_CALL (AddRef,p) +#define IDirectDrawGammaControl_Release(p) ICOM_CALL (Release,p) + /*** IDirectDrawGammaControl methods ***/ +#define IDirectDrawGammaControl_GetGammaRamp(p,a,b) ICOM_CALL(GetGammaRamp,p,a,b) +#define IDirectDrawGammaControl_SetGammaRamp(p,a,b) ICOM_CALL(SetGammaRamp,p,a,b) + + +HRESULT WINAPI DirectDrawCreate(LPGUID,LPDIRECTDRAW*,LPUNKNOWN); +HRESULT WINAPI DirectDrawCreateEx(LPGUID,LPVOID*,REFIID,LPUNKNOWN); +HRESULT WINAPI DirectDrawEnumerateA(LPDDENUMCALLBACKA,LPVOID); +HRESULT WINAPI DirectDrawEnumerateW(LPDDENUMCALLBACKW,LPVOID); +#define DirectDrawEnumerate WINELIB_NAME_AW(DirectDrawEnumerate) +HRESULT WINAPI DirectDrawCreateClipper(DWORD,LPDIRECTDRAWCLIPPER*,LPUNKNOWN); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_DDRAW_H */ diff --git a/hw/xwin/win.h b/hw/xwin/win.h new file mode 100644 index 000000000..684e98cc1 --- /dev/null +++ b/hw/xwin/win.h @@ -0,0 +1,1427 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + * Kensuke Matsuzaki + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/win.h,v 1.34 2003/02/12 15:01:38 alanh Exp $ */ + +#ifndef _WIN_H_ +#define _WIN_H_ + + +#ifndef NO +#define NO 0 +#endif +#ifndef YES +#define YES 1 +#endif + +/* + * Build toggles for experimental features + */ +#define WIN_NATIVE_GDI_SUPPORT YES +#define WIN_LAYER_SUPPORT NO +#define WIN_NEW_KEYBOARD_SUPPORT NO +#define WIN_EMULATE_PSEUDO_SUPPORT YES +#define WIN_UPDATE_STATS NO + +/* Turn debug messages on or off */ +#define CYGDEBUG NO + +#define NEED_EVENTS + +#define WIN_DEFAULT_BPP 0 +#define WIN_DEFAULT_WHITEPIXEL 255 +#define WIN_DEFAULT_BLACKPIXEL 0 +#define WIN_DEFAULT_LINEBIAS 0 +#define WIN_DEFAULT_E3B_TIME 50 /* milliseconds */ +#define WIN_DEFAULT_DPI 75 +#define WIN_DEFAULT_REFRESH 0 +#define WIN_DEFAULT_WIN_KILL TRUE +#define WIN_DEFAULT_UNIX_KILL FALSE +#define WIN_DEFAULT_CLIP_UPDATES_NBOXES 0 +#define WIN_DEFAULT_EMULATE_PSEUDO FALSE +#define WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH FALSE + +#define WIN_DIB_MAXIMUM_SIZE 0x08000000 /* 16 MB on Windows 95, 98, Me */ +#define WIN_DIB_MAXIMUM_SIZE_MB (WIN_DIB_MAXIMUM_SIZE / 8 / 1024 / 1024) + +/* + * Windows only supports 256 color palettes + */ +#define WIN_NUM_PALETTE_ENTRIES 256 + +/* + * Number of times to call Restore in an attempt to restore the primary surface + */ +#define WIN_REGAIN_SURFACE_RETRIES 1 + +/* + * Build a supported display depths mask by shifting one to the left + * by the number of bits in the supported depth. + */ +#define WIN_SUPPORTED_BPPS ( (1 << (32 - 1)) | (1 << (24 - 1)) \ + | (1 << (16 - 1)) | (1 << (15 - 1)) \ + | (1 << ( 8 - 1))) +#define WIN_CHECK_DEPTH YES + +#define WIN_E3B_OFF -1 +#define WIN_E3B_TIMER_ID 1 +#define WIN_FD_INVALID -1 + +#define WIN_SERVER_NONE 0x0L /* 0 */ +#define WIN_SERVER_SHADOW_GDI 0x1L /* 1 */ +#define WIN_SERVER_SHADOW_DD 0x2L /* 2 */ +#define WIN_SERVER_SHADOW_DDNL 0x4L /* 4 */ +#define WIN_SERVER_PRIMARY_DD 0x8L /* 8 */ +#define WIN_SERVER_NATIVE_GDI 0x10L /* 16 */ + +#define AltMapIndex Mod1MapIndex +#define NumLockMapIndex Mod2MapIndex +#define AltLangMapIndex Mod3MapIndex +#define KanaMapIndex Mod4MapIndex +#define ScrollLockMapIndex Mod5MapIndex + +#define WIN_MOD_LALT 0x00000001 +#define WIN_MOD_RALT 0x00000002 +#define WIN_MOD_LCONTROL 0x00000004 +#define WIN_MOD_RCONTROL 0x00000008 + +#define WIN_24BPP_MASK_RED 0x00FF0000 +#define WIN_24BPP_MASK_GREEN 0x0000FF00 +#define WIN_24BPP_MASK_BLUE 0x000000FF + +#define WIN_MAX_KEYS_PER_KEY 4 + +#include +#include +#include +#include +#include + +#include + +#ifdef HAS_MMAP +#include +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif /* MAP_FILE */ +#endif /* HAS_MMAP */ + +#include "X.h" +#include "Xproto.h" +#include "Xos.h" +#include "Xprotostr.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "pixmap.h" +#include "region.h" +#include "regionstr.h" +#include "gcstruct.h" +#include "colormap.h" +#include "colormapst.h" +#include "miscstruct.h" +#include "servermd.h" +#include "windowstr.h" +#include "mi.h" +#include "micmap.h" +#include "migc.h" +#include "mifillarc.h" +#include "mifpoly.h" +#include "mibstore.h" +#include "input.h" +#include "mipointer.h" +#include "keysym.h" +#include "mibstore.h" +#include "micoord.h" +#include "dix.h" +#include "miline.h" +#include "shadow.h" +#include "fb.h" +#include "layer.h" + +#ifdef RENDER +#include "mipict.h" +#include "picturestr.h" +#endif + +#ifdef RANDR +#include "randrstr.h" +#endif + +/* + * Windows headers + */ +#include "winms.h" + + +/* + * Multi-Window Window Manager header + */ + +#include "winwindow.h" + + +/* Cygwin's winuser.h does not define VK_KANA as of 28Mar2001 */ +/* NOTE: Cygwin's winuser.h was fixed shortly after 28Mar2001. */ +#ifndef VK_KANA +#define VK_KANA 15 +#endif + + +/* + * Debugging macros + */ + +#if CYGDEBUG +#define DEBUG_MSG(str,...) \ +if (fDebugProcMsg) \ +{ \ + char *pszTemp; \ + int iLength; \ + \ + iLength = sprintf (NULL, str, ##__VA_ARGS__); \ + \ + pszTemp = malloc (iLength + 1); \ + \ + sprintf (pszTemp, str, ##__VA_ARGS__); \ + \ + MessageBox (NULL, pszTemp, szFunctionName, MB_OK); \ + \ + free (pszTemp); \ +} +#else +#define DEBUG_MSG(str,...) +#endif + +#if CYGDEBUG || YES +#define DEBUG_FN_NAME(str) PTSTR szFunctionName = str +#else +#define DEBUG_FN_NAME(str) +#endif + +#if CYGDEBUG || YES +#define DEBUGVARS BOOL fDebugProcMsg = FALSE +#else +#define DEBUGVARS +#endif + +#if CYGDEBUG || YES +#define DEBUGPROC_MSG fDebugProcMsg = TRUE +#else +#define DEBUGPROC_MSG +#endif + +/* We use xor this macro for detecting toggle key state changes */ +#define WIN_XOR(a,b) ((!(a) && (b)) || ((a) && !(b))) + + +/* + * Typedefs for engine dependent function pointers + */ + +typedef Bool (*winAllocateFBProcPtr)(ScreenPtr); + +typedef void (*winShadowUpdateProcPtr)(ScreenPtr, shadowBufPtr); + +typedef Bool (*winCloseScreenProcPtr)(int, ScreenPtr); + +typedef Bool (*winInitVisualsProcPtr)(ScreenPtr); + +typedef Bool (*winAdjustVideoModeProcPtr)(ScreenPtr); + +typedef Bool (*winCreateBoundingWindowProcPtr)(ScreenPtr); + +typedef Bool (*winFinishScreenInitProcPtr)(int, ScreenPtr, int, char **); + +typedef Bool (*winBltExposedRegionsProcPtr)(ScreenPtr); + +typedef Bool (*winActivateAppProcPtr)(ScreenPtr); + +typedef Bool (*winRedrawScreenProcPtr)(ScreenPtr pScreen); + +typedef Bool (*winRealizeInstalledPaletteProcPtr)(ScreenPtr pScreen); + +typedef Bool (*winInstallColormapProcPtr)(ColormapPtr pColormap); + +typedef Bool (*winStoreColorsProcPtr)(ColormapPtr pmap, + int ndef, xColorItem *pdefs); + +typedef Bool (*winCreateColormapProcPtr)(ColormapPtr pColormap); + +typedef Bool (*winDestroyColormapProcPtr)(ColormapPtr pColormap); + +typedef Bool (*winHotKeyAltTabProcPtr)(ScreenPtr); + +typedef Bool (*winCreatePrimarySurfaceProcPtr)(ScreenPtr); + +typedef Bool (*winReleasePrimarySurfaceProcPtr)(ScreenPtr); + + +/* + * GC (graphics context) privates + */ + +typedef struct +{ + HDC hdc; + HDC hdcMem; +} winPrivGCRec, *winPrivGCPtr; + + +/* + * Pixmap privates + */ + +typedef struct +{ + HDC hdcSelected; + HBITMAP hBitmap; + BYTE *pbBits; + DWORD dwScanlineBytes; + BITMAPINFOHEADER *pbmih; +} winPrivPixmapRec, *winPrivPixmapPtr; + + +/* + * Colormap privates + */ + +typedef struct +{ + HPALETTE hPalette; + LPDIRECTDRAWPALETTE lpDDPalette; + RGBQUAD rgbColors[WIN_NUM_PALETTE_ENTRIES]; + PALETTEENTRY peColors[WIN_NUM_PALETTE_ENTRIES]; +} winPrivCmapRec, *winPrivCmapPtr; + + +#if WIN_NEW_KEYBOARD_SUPPORT +/* + * Keyboard event structure + */ + +typedef struct +{ + DWORD dwXKeycodes[WIN_MAX_KEYS_PER_KEY]; + DWORD dwReleaseModifiers; +} winKeyEventsRec, *winKeyEventsPtr; + +#endif /* WIN_NEW_KEYBOARD_SUPPORT */ + +/* + * Screen information structure that we need before privates are available + * in the server startup sequence. + */ + +typedef struct +{ + ScreenPtr pScreen; + + /* Did the user specify a height and width? */ + Bool fUserGaveHeightAndWidth; + + DWORD dwScreen; + DWORD dwUserWidth; + DWORD dwUserHeight; + DWORD dwWidth; + DWORD dwHeight; + DWORD dwWidth_mm; + DWORD dwHeight_mm; + DWORD dwPaddedWidth; + + /* + * dwStride is the number of whole pixels that occupy a scanline, + * including those pixels that are not displayed. This is basically + * a rounding up of the width. + */ + DWORD dwStride; + + /* Offset of the screen in the window when using scrollbars */ + DWORD dwXOffset; + DWORD dwYOffset; + + DWORD dwBPP; + DWORD dwDepth; + DWORD dwRefreshRate; + char *pfb; + XWDColor *pXWDCmap; + XWDFileHeader *pXWDHeader; + DWORD dwEngine; + DWORD dwEnginePreferred; + DWORD dwClipUpdatesNBoxes; + Bool fEmulatePseudo; + Bool fFullScreen; + Bool fDecoration; + Bool fRootless; + Bool fMultiWindow; + Bool fMultipleMonitors; + Bool fClipboard; + Bool fLessPointer; + Bool fScrollbars; + int iE3BTimeout; + /* Windows (Alt+F4) and Unix (Ctrl+Alt+Backspace) Killkey */ + Bool fUseWinKillKey; + Bool fUseUnixKillKey; + Bool fIgnoreInput; + + /* Did the user explicitly set this screen? */ + Bool fExplicitScreen; +} winScreenInfo, *winScreenInfoPtr; + + +/* + * Screen privates + */ + +typedef struct _winPrivScreenRec +{ + winScreenInfoPtr pScreenInfo; + + Bool fEnabled; + Bool fClosed; + Bool fActive; + Bool fBadDepth; + + int iDeltaZ; + + CloseScreenProcPtr CloseScreen; + + DWORD dwRedMask; + DWORD dwGreenMask; + DWORD dwBlueMask; + DWORD dwBitsPerRGB; + + DWORD dwModeKeyStates; + + /* Clipboard support */ + pthread_t ptClipboardProc; + +#if 0 + HWND hwndNextViewer; + void *display; + int window; +#endif + + /* Last width, height, and depth of the Windows display */ + DWORD dwLastWindowsWidth; + DWORD dwLastWindowsHeight; + DWORD dwLastWindowsBitsPixel; + + /* Layer support */ +#if WIN_LAYER_SUPPORT + DWORD dwLayerKind; + LayerPtr pLayer; +#endif + + /* Palette management */ + ColormapPtr pcmapInstalled; + + /* Pointer to the root visual so we only have to look it up once */ + VisualPtr pRootVisual; + + /* 3 button emulation variables */ + int iE3BCachedPress; + Bool fE3BFakeButton2Sent; + + /* Privates used by shadow fb GDI server */ + HBITMAP hbmpShadow; + HDC hdcScreen; + HDC hdcShadow; + HWND hwndScreen; + + /* Privates used by shadow fb and primary fb DirectDraw servers */ + LPDIRECTDRAW pdd; + LPDIRECTDRAWSURFACE2 pddsPrimary; + LPDIRECTDRAW2 pdd2; + + /* Privates used by shadow fb DirectDraw server */ + LPDIRECTDRAWSURFACE2 pddsShadow; + LPDDSURFACEDESC pddsdShadow; + + /* Privates used by primary fb DirectDraw server */ + LPDIRECTDRAWSURFACE2 pddsOffscreen; + LPDDSURFACEDESC pddsdOffscreen; + LPDDSURFACEDESC pddsdPrimary; + + /* Privates used by shadow fb DirectDraw Nonlocking server */ + LPDIRECTDRAW4 pdd4; + LPDIRECTDRAWSURFACE4 pddsShadow4; + LPDIRECTDRAWSURFACE4 pddsPrimary4; + + /* Privates used by both shadow fb DirectDraw servers */ + LPDIRECTDRAWCLIPPER pddcPrimary; + + /* Privates used by multi-window server */ + pthread_t ptWMProc; + void *pWMInfo; + + /* Privates used for any module running in a seperate thread */ + pthread_mutex_t pmServerStarted; + Bool fServerStarted; + + /* Engine specific functions */ + winAllocateFBProcPtr pwinAllocateFB; + winShadowUpdateProcPtr pwinShadowUpdate; + winCloseScreenProcPtr pwinCloseScreen; + winInitVisualsProcPtr pwinInitVisuals; + winAdjustVideoModeProcPtr pwinAdjustVideoMode; + winCreateBoundingWindowProcPtr pwinCreateBoundingWindow; + winFinishScreenInitProcPtr pwinFinishScreenInit; + winBltExposedRegionsProcPtr pwinBltExposedRegions; + winActivateAppProcPtr pwinActivateApp; + winRedrawScreenProcPtr pwinRedrawScreen; + winRealizeInstalledPaletteProcPtr pwinRealizeInstalledPalette; + winInstallColormapProcPtr pwinInstallColormap; + winStoreColorsProcPtr pwinStoreColors; + winCreateColormapProcPtr pwinCreateColormap; + winDestroyColormapProcPtr pwinDestroyColormap; + winHotKeyAltTabProcPtr pwinHotKeyAltTab; + winCreatePrimarySurfaceProcPtr pwinCreatePrimarySurface; + winReleasePrimarySurfaceProcPtr pwinReleasePrimarySurface; + + /* Window Procedures for Rootless mode */ + CreateWindowProcPtr CreateWindow; + DestroyWindowProcPtr DestroyWindow; + PositionWindowProcPtr PositionWindow; + ChangeWindowAttributesProcPtr ChangeWindowAttributes; + RealizeWindowProcPtr RealizeWindow; + UnrealizeWindowProcPtr UnrealizeWindow; + ValidateTreeProcPtr ValidateTree; + PostValidateTreeProcPtr PostValidateTree; + WindowExposuresProcPtr WindowExposures; + PaintWindowBackgroundProcPtr PaintWindowBackground; + PaintWindowBorderProcPtr PaintWindowBorder; + CopyWindowProcPtr CopyWindow; + ClearToBackgroundProcPtr ClearToBackground; + ClipNotifyProcPtr ClipNotify; + RestackWindowProcPtr RestackWindow; + ReparentWindowProcPtr ReparentWindow; +#ifdef SHAPE + SetShapeProcPtr SetShape; +#endif +} winPrivScreenRec; + + +/* + * Extern declares for general global variables + */ + +extern winScreenInfo g_ScreenInfo[]; +extern miPointerScreenFuncRec g_winPointerCursorFuncs; +extern DWORD g_dwEvents; +extern int g_fdMessageQueue; +extern int g_iScreenPrivateIndex; +extern int g_iCmapPrivateIndex; +extern int g_iGCPrivateIndex; +extern int g_iPixmapPrivateIndex; +extern int g_iWindowPrivateIndex; +extern unsigned long g_ulServerGeneration; +extern CARD32 g_c32LastInputEventTime; +extern DWORD g_dwEnginesSupported; +extern HINSTANCE g_hInstance; +extern HWND g_hDlgDepthChange; + + +/* + * Extern declares for dynamically loaded libraries and function pointers + */ + +extern HMODULE g_hmodDirectDraw; +extern FARPROC g_fpDirectDrawCreate; +extern FARPROC g_fpDirectDrawCreateClipper; + +extern HMODULE g_hmodCommonControls; +extern FARPROC g_fpTrackMouseEvent; + + +/* + * Screen privates macros + */ + +#define winGetScreenPriv(pScreen) \ + ((winPrivScreenPtr) (pScreen)->devPrivates[g_iScreenPrivateIndex].ptr) + +#define winSetScreenPriv(pScreen,v) \ + ((pScreen)->devPrivates[g_iScreenPrivateIndex].ptr = (pointer) v) + +#define winScreenPriv(pScreen) \ + winPrivScreenPtr pScreenPriv = winGetScreenPriv(pScreen) + + +/* + * Colormap privates macros + */ + +#define winGetCmapPriv(pCmap) \ + ((winPrivCmapPtr) (pCmap)->devPrivates[g_iCmapPrivateIndex].ptr) + +#define winSetCmapPriv(pCmap,v) \ + ((pCmap)->devPrivates[g_iCmapPrivateIndex].ptr = (pointer) v) + +#define winCmapPriv(pCmap) \ + winPrivCmapPtr pCmapPriv = winGetCmapPriv(pCmap) + + +/* + * GC privates macros + */ + +#define winGetGCPriv(pGC) \ + ((winPrivGCPtr) (pGC)->devPrivates[g_iGCPrivateIndex].ptr) + +#define winSetGCPriv(pGC,v) \ + ((pGC)->devPrivates[g_iGCPrivateIndex].ptr = (pointer) v) + +#define winGCPriv(pGC) \ + winPrivGCPtr pGCPriv = winGetGCPriv(pGC) + + +/* + * Pixmap privates macros + */ + +#define winGetPixmapPriv(pPixmap) \ + ((winPrivPixmapPtr) (pPixmap)->devPrivates[g_iPixmapPrivateIndex].ptr) + +#define winSetPixmapPriv(pPixmap,v) \ + ((pPixmap)->devPrivates[g_iPixmapPrivateIndex].ptr = (pointer) v) + +#define winPixmapPriv(pPixmap) \ + winPrivPixmapPtr pPixmapPriv = winGetPixmapPriv(pPixmap) + + +/* + * Window privates macros + */ + +#define winGetWindowPriv(pWin) \ + ((winPrivWinPtr) (pWin)->devPrivates[g_iWindowPrivateIndex].ptr) + +#define winSetWindowPriv(pWin,v) \ + ((pWin)->devPrivates[g_iWindowPrivateIndex].ptr = (pointer) v) + +#define winWindowPriv(pWin) \ + winPrivWinPtr pWinPriv = winGetWindowPriv(pWin) + + +/* + * FIXME: Windows mouse wheel macro; should be in Cygwin w32api headers. + * Has been fixed after May 05, 2001. Remove this section after the + * fixed headers are in distribution. + */ + +#ifndef GET_WHEEL_DELTA_WPARAM +#define GET_WHEEL_DELTA_WPARAM(wparam) ((short)HIWORD (wparam)) +#endif /* GET_WHEEL_DELTA_WPARAM */ + + +/* + * FIXME: Windows shell API defines. Should be in w32api shellapi.h + */ + +#ifndef ABS_AUTOHIDE +#define ABS_AUTOHIDE 0x00000001 +#endif +#ifndef ABS_ALWAYSONTOP +#define ABS_ALWAYSONTOP 0x00000002 +#endif + + +/* + * BEGIN DDX and DIX Function Prototypes + */ + + +/* + * winallpriv.c + */ + +Bool +winAllocatePrivates (ScreenPtr pScreen); + +Bool +winInitCmapPrivates (ColormapPtr pCmap); + +Bool +winAllocateCmapPrivates (ColormapPtr pCmap); + + +/* + * winblock.c + */ + +void +winBlockHandler (int nScreen, + pointer pBlockData, + pointer pTimeout, + pointer pReadMask); + + +/* + * winclip.c + */ + +RegionPtr +winPixmapToRegionNativeGDI (PixmapPtr pPix); + + +/* + * winclipboardinit.c + */ + +Bool +winInitClipboard (pthread_t *ptClipboardProc, + pthread_mutex_t *ppmServerStarted, + DWORD dwScreen); + + +/* + * wincmap.c + */ + +int +winListInstalledColormaps (ScreenPtr pScreen, Colormap *pmaps); + +void +winStoreColors (ColormapPtr pmap, int ndef, xColorItem *pdefs); + +void +winInstallColormap (ColormapPtr pmap); + +void +winUninstallColormap (ColormapPtr pmap); + +void +winResolveColor (unsigned short *pred, + unsigned short *pgreen, + unsigned short *pblue, + VisualPtr pVisual); + +Bool +winCreateColormap (ColormapPtr pmap); + +void +winDestroyColormap (ColormapPtr pmap); + +int +winExpandDirectColors (ColormapPtr pmap, int ndef, + xColorItem *indefs, xColorItem *outdefs); + +Bool +winCreateDefColormap (ScreenPtr pScreen); + +Bool +winSetVisualTypesNativeGDI (int nDepth, int nVisuals, int nBitsPerRGB); + +void +winClearVisualTypes (void); + + +/* + * wincreatewnd.c + */ + +Bool +winCreateBoundingWindowFullScreen (ScreenPtr pScreen); + +Bool +winCreateBoundingWindowWindowed (ScreenPtr pScreen); + + +/* + * wincursor.c + */ + +void +winPointerWarpCursor (ScreenPtr pScreen, int x, int y); + +Bool +winCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y); + +void +winCrossScreen (ScreenPtr pScreen, Bool fEntering); + + +/* + * winengine.c + */ + +void +winDetectSupportedEngines (); + +Bool +winSetEngine (ScreenPtr pScreen); + +Bool +winGetDDProcAddresses (); + + +/* + * winerror.c + */ + +void +OSVenderVErrorF (const char *pszFormat, va_list va_args); + + +/* + * winfillsp.c + */ + +void +winFillSpansNativeGDI (DrawablePtr pDrawable, + GCPtr pGC, + int nSpans, + DDXPointPtr pPoints, + int *pWidths, + int fSorted); + + +/* + * winfont.c + */ + +Bool +winRealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont); + +Bool +winUnrealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont); + + +/* + * wingc.c + */ + +Bool +winCreateGCNativeGDI (GCPtr pGC); + +void +winChangeGCNativeGDI (GCPtr pGC, unsigned long ulChanges); + +void +winPadPixmapNativdGDI (PixmapPtr pPixmap); + +void +winValidateGCNativeGDI (GCPtr pGC, + unsigned long changes, + DrawablePtr pDrawable); + +void +winCopyGCNativeGDI (GCPtr pGCsrc, unsigned long ulMask, GCPtr pGCdst); + +void +winDestroyGCNativeGDI (GCPtr pGC); + +void +winChangeClipNativeGDI (GCPtr pGC, int nType, pointer pValue, int nRects); + +void +winDestroyClipNativeGDI (GCPtr pGC); + +void +winCopyClipNativeGDI (GCPtr pGCdst, GCPtr pGCsrc); + + +/* + * wingetsp.c + */ + +void +winGetSpansNativeGDI (DrawablePtr pDrawable, + int wMax, + DDXPointPtr pPoints, + int *pWidths, + int nSpans, + char *pDst); + + +/* + * winkeybd.c + */ + +#if WIN_NEW_KEYBOARD_SUPPORT +winKeyEventsRec +winTranslateKey (DWORD dwVirtualKey, DWORD dwKeyData); +#else +void +winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode); +#endif + +void +winGetKeyMappings (KeySymsPtr pKeySyms, CARD8 *pModMap); + +void +winKeybdBell (int iPercent, DeviceIntPtr pDeviceInt, + pointer pCtrl, int iClass); + +void +winKeybdCtrl (DeviceIntPtr pDevice, KeybdCtrl *pCtrl); + +int +winKeybdProc (DeviceIntPtr pDeviceInt, int iState); + +void +winInitializeModeKeyStates (void); + +void +winStoreModeKeyStates (ScreenPtr pScreen); + +void +winRestoreModeKeyStates (ScreenPtr pScreen); + +Bool +winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam); + +void +winKeybdReleaseKeys (); + +void +winSendKeyEvent (DWORD dwKey, Bool fDown); + +#if WIN_NEW_KEYBOARD_SUPPORT +void +winProcessKeyEvent (DWORD dwVirtKey, DWORD dwKeyData); +#endif + + +/* + * winlayer.c + */ + +#if WIN_LAYER_SUPPORT + +LayerPtr +winLayerCreate (ScreenPtr pScreen); + +int +winLayerAdd (WindowPtr pWindow, pointer value); + +int +winLayerRemove (WindowPtr pWindow, pointer value); + +#ifdef RANDR +Bool +winRandRGetInfo (ScreenPtr pScreen, Rotation *pRotations); + +Bool +winRandRSetConfig (ScreenPtr pScreen, + Rotation rotateKind, + RRScreenSizePtr pSize); + +Bool +winRandRInit (ScreenPtr pScreen); +#endif /* RANDR */ +#endif /* WIN_LAYER_SUPPORT */ + + +/* + * winmisc.c + */ + +void +winQueryBestSizeNativeGDI (int class, unsigned short *pWidth, + unsigned short *pHeight, ScreenPtr pScreen); + +CARD8 +winCountBits (DWORD dw); + +Bool +winUpdateFBPointer (ScreenPtr pScreen, void *pbits); + +BOOL +winPaintBackground (HWND hwnd, COLORREF colorref); + + +/* + * winmouse.c + */ + +void +winMouseCtrl (DeviceIntPtr pDevice, PtrCtrl *pCtrl); + +int +winMouseProc (DeviceIntPtr pDeviceInt, int iState); + +int +winMouseWheel (ScreenPtr pScreen, int iDeltaZ); + +void +winMouseButtonsSendEvent (int iEventType, int iButton); + +int +winMouseButtonsHandle (ScreenPtr pScreen, + int iEventType, int iButton, + WPARAM wParam); + + +/* + * winnativegdi.c + */ + +HBITMAP +winCreateDIBNativeGDI (int iWidth, int iHeight, int iDepth, + BYTE **ppbBits, BITMAPINFO **ppbmi); + +Bool +winAllocateFBNativeGDI (ScreenPtr pScreen); + +void +winShadowUpdateNativeGDI (ScreenPtr pScreen, + shadowBufPtr pBuf); + +Bool +winCloseScreenNativeGDI (int nIndex, ScreenPtr pScreen); + +Bool +winInitVisualsNativeGDI (ScreenPtr pScreen); + +Bool +winAdjustVideoModeNativeGDI (ScreenPtr pScreen); + +Bool +winBltExposedRegionsNativeGDI (ScreenPtr pScreen); + +Bool +winActivateAppNativeGDI (ScreenPtr pScreen); + +Bool +winSetEngineFunctionsNativeGDI (ScreenPtr pScreen); + +Bool +winRedrawScreenNativeGDI (ScreenPtr pScreen); + +Bool +winRealizeInstalledPaletteNativeGDI (ScreenPtr pScreen); + +Bool +winInstallColormapNativeGDI (ColormapPtr pColormap); + +Bool +winStoreColorsNativeGDI (ColormapPtr pmap, + int ndef, + xColorItem *pdefs); + +Bool +winCreateColormapNativeGDI (ColormapPtr pColormap); + +Bool +winDestroyColormapNativeGDI (ColormapPtr pColormap); + + + +/* + * winpfbddd.c + */ + +Bool +winAllocateFBPrimaryDD (ScreenPtr pScreen); + +Bool +winCloseScreenPrimaryDD (int nIndex, ScreenPtr pScreen); + +Bool +winInitVisualsPrimaryDD (ScreenPtr pScreen); + +Bool +winAdjustVideoModePrimaryDD (ScreenPtr pScreen); + +Bool +winActivateAppPrimaryDD (ScreenPtr pScreen); + +Bool +winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen); + +Bool +winHotKeyAltTabPrimaryDD (ScreenPtr pScreen); + + +/* + * winpixmap.c + */ + +PixmapPtr +winCreatePixmapNativeGDI (ScreenPtr pScreen, int width, int height, int depth); + +Bool +winDestroyPixmapNativeGDI (PixmapPtr pPixmap); + +void +winXRotatePixmapNativeGDI (PixmapPtr pPix, int rw); + +void +winYRotatePixmapNativeGDI (PixmapPtr pPix, int rh); + +void +winCopyRotatePixmapNativeGDI (PixmapPtr psrcPix, PixmapPtr *ppdstPix, + int xrot, int yrot); + +Bool +winModifyPixmapHeaderNativeGDI (PixmapPtr pPixmap, + int iWidth, int iHeight, + int iDepth, + int iBitsPerPixel, + int devKind, + pointer pPixData); + + +/* + * winpntwin.c + */ + +void +winPaintWindowNativeGDI (WindowPtr pWin, RegionPtr pRegion, int what); + + +/* + * winpolyline.c + */ + +void +winPolyLineNativeGDI (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ppt); + + +/* + * winscrinit.c + */ + +Bool +winScreenInit (int index, + ScreenPtr pScreen, + int argc, char **argv); + +Bool +winFinishScreenInitFB (int index, + ScreenPtr pScreen, + int argc, char **argv); + +Bool +winFinishScreenInitNativeGDI (int index, + ScreenPtr pScreen, + int argc, char **argv); + +Bool +winSaveScreen (ScreenPtr pScreen, int on); + +PixmapPtr +winGetWindowPixmap (WindowPtr pWin); + +void +winSetWindowPixmap (WindowPtr pWin, PixmapPtr pPix); + + +/* + * winsetsp.c + */ + +void +winSetSpansNativeGDI (DrawablePtr pDrawable, + GCPtr pGC, + char *pSrc, + DDXPointPtr pPoints, + int *pWidth, + int nSpans, + int fSorted); + +/* + * winshaddd.c + */ + +Bool +winAllocateFBShadowDD (ScreenPtr pScreen); + +void +winShadowUpdateDD (ScreenPtr pScreen, + shadowBufPtr pBuf); + +Bool +winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen); + +Bool +winInitVisualsShadowDD (ScreenPtr pScreen); + +Bool +winAdjustVideoModeShadowDD (ScreenPtr pScreen); + +Bool +winBltExposedRegionsShadowDD (ScreenPtr pScreen); + +Bool +winActivateAppShadowDD (ScreenPtr pScreen); + +Bool +winSetEngineFunctionsShadowDD (ScreenPtr pScreen); + +Bool +winRedrawScreenShadowDD (ScreenPtr pScreen); + +Bool +winRealizeInstalledPaletteShadowDD (ScreenPtr pScreen); + +Bool +winInstallColormapShadowDD (ColormapPtr pColormap); + +Bool +winStoreColorsShadowDD (ColormapPtr pmap, + int ndef, + xColorItem *pdefs); + +Bool +winCreateColormapShadowDD (ColormapPtr pColormap); + +Bool +winDestroyColormapShadowDD (ColormapPtr pColormap); + +Bool +winCreatePrimarySurfaceShadowDD (ScreenPtr pScreen); + +Bool +winReleasePrimarySurfaceShadowDD (ScreenPtr pScreen); + + +/* + * winshadddnl.c + */ + +Bool +winAllocateFBShadowDDNL (ScreenPtr pScreen); + +void +winShadowUpdateDDNL (ScreenPtr pScreen, + shadowBufPtr pBuf); + +Bool +winCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen); + +Bool +winInitVisualsShadowDDNL (ScreenPtr pScreen); + +Bool +winAdjustVideoModeShadowDDNL (ScreenPtr pScreen); + +Bool +winBltExposedRegionsShadowDDNL (ScreenPtr pScreen); + +Bool +winActivateAppShadowDDNL (ScreenPtr pScreen); + +Bool +winSetEngineFunctionsShadowDDNL (ScreenPtr pScreen); + +Bool +winRedrawScreenShadowDDNL (ScreenPtr pScreen); + +Bool +winRealizeInstalledPaletteShadowDDNL (ScreenPtr pScreen); + +Bool +winInstallColormapShadowDDNL (ColormapPtr pColormap); + +Bool +winStoreColorsShadowDDNL (ColormapPtr pmap, + int ndef, + xColorItem *pdefs); + +Bool +winCreateColormapShadowDDNL (ColormapPtr pColormap); + +Bool +winDestroyColormapShadowDDNL (ColormapPtr pColormap); + +Bool +winCreatePrimarySurfaceShadowDDNL (ScreenPtr pScreen); + +Bool +winReleasePrimarySurfaceShadowDDNL (ScreenPtr pScreen); + + +/* + * winshadgdi.c + */ + +Bool +winAllocateFBShadowGDI (ScreenPtr pScreen); + +void +winShadowUpdateGDI (ScreenPtr pScreen, + shadowBufPtr pBuf); + +Bool +winCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen); + +Bool +winInitVisualsShadowGDI (ScreenPtr pScreen); + +Bool +winAdjustVideoModeShadowGDI (ScreenPtr pScreen); + +Bool +winActivateAppShadowGDI (ScreenPtr pScreen); + +Bool +winRedrawScreenShadowGDI (ScreenPtr pScreen); + +Bool +winSetEngineFunctionsShadowGDI (ScreenPtr pScreen); + +Bool +winRealizeInstalledPaletteShadowGDI (ScreenPtr pScreen); + +Bool +winInstallColormapShadowGDI (ColormapPtr pColormap); + +Bool +winStoreColorsShadowGDI (ColormapPtr pmap, + int ndef, + xColorItem *pdefs); + +Bool +winCreateColormapShadowGDI (ColormapPtr pColormap); + +Bool +winDestroyColormapShadowGDI (ColormapPtr pColormap); + + +/* + * winwakeup.c + */ + +void +winWakeupHandler (int nScreen, + pointer pWakeupData, + unsigned long ulResult, + pointer pReadmask); + + +/* + * winwindow.c + */ + +Bool +winCreateWindowNativeGDI (WindowPtr pWin); + +Bool +winDestroyWindowNativeGDI (WindowPtr pWin); + +Bool +winPositionWindowNativeGDI (WindowPtr pWin, int x, int y); + +void +winCopyWindowNativeGDI (WindowPtr pWin, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc); + +Bool +winChangeWindowAttributesNativeGDI (WindowPtr pWin, unsigned long mask); + +Bool +winUnmapWindowNativeGDI (WindowPtr pWindow); + +Bool +winMapWindowNativeGDI (WindowPtr pWindow); + +Bool +winCreateWindowPRootless (WindowPtr pWindow); + +Bool +winDestroyWindowPRootless (WindowPtr pWindow); + +Bool +winPositionWindowPRootless (WindowPtr pWindow, int x, int y); + +Bool +winChangeWindowAttributesPRootless (WindowPtr pWindow, unsigned long mask); + +Bool +winUnmapWindowPRootless (WindowPtr pWindow); + +Bool +winMapWindowPRootless (WindowPtr pWindow); + +#ifdef SHAPE +void +winSetShapePRootless (WindowPtr pWindow); +#endif + + +/* + * winmultiwindowwindow.c + */ + +Bool +winCreateWindowMultiWindow (WindowPtr pWindow); + +Bool +winDestroyWindowMultiWindow (WindowPtr pWindow); + +Bool +winPositionWindowMultiWindow (WindowPtr pWindow, int x, int y); + +Bool +winChangeWindowAttributesMultiWindow (WindowPtr pWindow, unsigned long mask); + +Bool +winUnmapWindowMultiWindow (WindowPtr pWindow); + +Bool +winMapWindowMultiWindow (WindowPtr pWindow); + +void +winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent); + +void +winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib); + +#ifdef SHAPE +void +winSetShapeMultiWindow (WindowPtr pWindow); +#endif + + +/* + * winwndproc.c + */ + +LRESULT CALLBACK +winWindowProc (HWND hWnd, UINT message, + WPARAM wParam, LPARAM lParam); + + +/* + * END DDX and DIX Function Prototypes + */ + +#endif /* _WIN_H_ */ + diff --git a/hw/xwin/winallpriv.c b/hw/xwin/winallpriv.c new file mode 100644 index 000000000..a27309598 --- /dev/null +++ b/hw/xwin/winallpriv.c @@ -0,0 +1,181 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Keith Packard, MIT X Consortium + * Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winallpriv.c,v 1.12 2002/10/31 23:04:39 alanh Exp $ */ + +#include "win.h" + + + +/* See Porting Layer Definition - p. 58 */ +/* + * Allocate indexes for the privates that we use. + * Allocate memory directly for the screen privates. + * Reserve space in GCs and Pixmaps for our privates. + * Colormap privates are handled in winAllocateCmapPrivates () + */ + +Bool +winAllocatePrivates (ScreenPtr pScreen) +{ + winPrivScreenPtr pScreenPriv; + +#if CYGDEBUG + ErrorF ("winAllocateScreenPrivates - g_ulServerGeneration: %d " + "serverGeneration: %d\n", + g_ulServerGeneration, serverGeneration); +#endif + + /* We need a new slot for our privates if the screen gen has changed */ + if (g_ulServerGeneration != serverGeneration) + { + /* Get an index that we can store our privates at */ + g_iScreenPrivateIndex = AllocateScreenPrivateIndex (); + g_iGCPrivateIndex = AllocateGCPrivateIndex (); + g_iPixmapPrivateIndex = AllocatePixmapPrivateIndex (); + g_iWindowPrivateIndex = AllocateWindowPrivateIndex (); + + g_ulServerGeneration = serverGeneration; + } + + /* Allocate memory for the screen private structure */ + pScreenPriv = (winPrivScreenPtr) malloc (sizeof (winPrivScreenRec)); + if (!pScreenPriv) + { + ErrorF ("winAllocateScreenPrivates - malloc () failed\n"); + return FALSE; + } + + /* Initialize the memory of the private structure */ + ZeroMemory (pScreenPriv, sizeof (winPrivScreenRec)); + + /* Intialize private structure members */ + pScreenPriv->fActive = TRUE; + + /* Save the screen private pointer */ + winSetScreenPriv (pScreen, pScreenPriv); + + /* Reserve GC memory for our privates */ + if (!AllocateGCPrivate (pScreen, g_iGCPrivateIndex, + sizeof (winPrivGCRec))) + { + ErrorF ("winAllocatePrivates - AllocateGCPrivate () failed\n"); + return FALSE; + } + + /* Reserve Pixmap memory for our privates */ + if (!AllocatePixmapPrivate (pScreen, g_iPixmapPrivateIndex, + sizeof (winPrivPixmapRec))) + { + ErrorF ("winAllocatePrivates - AllocatePixmapPrivates () failed\n"); + return FALSE; + } + + /* Reserve Window memory for our privates */ + if (!AllocateWindowPrivate (pScreen, g_iWindowPrivateIndex, + sizeof (winPrivWinRec))) + { + ErrorF ("winAllocatePrivates () - AllocateWindowPrivates () failed\n"); + return FALSE; + } + + return TRUE; +} + + +/* + * Colormap privates may be allocated after the default colormap has + * already been created for some screens. This initialization procedure + * is called for each default colormap that is found. + */ + +Bool +winInitCmapPrivates (ColormapPtr pcmap) +{ +#if CYGDEBUG + ErrorF ("winInitCmapPrivates\n"); +#endif + + /* + * I see no way that this function can do anything useful + * with only a ColormapPtr. We don't have the index for + * our dev privates yet, so we can't really initialize + * anything. Perhaps I am misunderstanding the purpose + * of this function. + */ + + return TRUE; +} + + +/* + * Allocate memory for our colormap privates + */ + +Bool +winAllocateCmapPrivates (ColormapPtr pCmap) +{ + winPrivCmapPtr pCmapPriv; + static unsigned long s_ulPrivateGeneration = 0; + +#if CYGDEBUG + ErrorF ("winAllocateCmapPrivates\n"); +#endif + + /* Get a new privates index when the server generation changes */ + if (s_ulPrivateGeneration != serverGeneration) + { + /* Get an index that we can store our privates at */ + g_iCmapPrivateIndex = AllocateColormapPrivateIndex (winInitCmapPrivates); + + /* Save the new server generation */ + s_ulPrivateGeneration = serverGeneration; + } + + /* Allocate memory for our private structure */ + pCmapPriv = (winPrivCmapPtr) malloc (sizeof (winPrivCmapRec)); + if (!pCmapPriv) + { + ErrorF ("winAllocateCmapPrivates - malloc () failed\n"); + return FALSE; + } + + /* Initialize the memory of the private structure */ + ZeroMemory (pCmapPriv, sizeof (winPrivCmapRec)); + + /* Save the cmap private pointer */ + winSetCmapPriv (pCmap, pCmapPriv); + +#if CYGDEBUG + ErrorF ("winAllocateCmapPrivates - Returning\n"); +#endif + + return TRUE; +} diff --git a/hw/xwin/winblock.c b/hw/xwin/winblock.c new file mode 100644 index 000000000..45d509fea --- /dev/null +++ b/hw/xwin/winblock.c @@ -0,0 +1,76 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winblock.c,v 1.6 2003/02/12 15:01:38 alanh Exp $ */ + +#include "win.h" + +/* See Porting Layer Definition - p. 6 */ +void +winBlockHandler (int nScreen, + pointer pBlockData, + pointer pTimeout, + pointer pReadMask) +{ + winScreenPriv((ScreenPtr)pBlockData); + MSG msg; + + /* Signal threaded modules to begin */ + if (pScreenPriv != NULL && !pScreenPriv->fServerStarted) + { + int iReturn; + + ErrorF ("winBlockHandler - Releasing pmServerStarted\n"); + + /* Flag that modules are to be started */ + pScreenPriv->fServerStarted = TRUE; + + /* Unlock the mutex for threaded modules */ + iReturn = pthread_mutex_unlock (&pScreenPriv->pmServerStarted); + if (iReturn != 0) + { + ErrorF ("winBlockHandler - pthread_mutex_unlock () failed: %d\n", + iReturn); + goto winBlockHandler_ProcessMessages; + } + + ErrorF ("winBlockHandler - pthread_mutex_unlock () returned\n"); + } + +winBlockHandler_ProcessMessages: + + /* Process all messages on our queue */ + while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + { + if (g_hDlgDepthChange == 0 || !IsDialogMessage (g_hDlgDepthChange, &msg)) + { + DispatchMessage (&msg); + } + } +} diff --git a/hw/xwin/winclip.c b/hw/xwin/winclip.c new file mode 100644 index 000000000..a829e8eb9 --- /dev/null +++ b/hw/xwin/winclip.c @@ -0,0 +1,40 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winclip.c,v 1.2 2001/06/04 13:04:41 alanh Exp $ */ + +#include "win.h" + +/* Look at mfb/mfbclip.c for sample implementation */ +RegionPtr +winPixmapToRegionNativeGDI (PixmapPtr pPix) +{ + ErrorF ("winPixmapToRegion()\n"); + return NULL; +} diff --git a/hw/xwin/winclipboard.h b/hw/xwin/winclipboard.h new file mode 100644 index 000000000..6e6cf44a9 --- /dev/null +++ b/hw/xwin/winclipboard.h @@ -0,0 +1,158 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold Hunt + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winclipboard.h,v 1.1 2003/02/12 15:01:38 alanh Exp $ */ + + +#ifndef _WINCLIPBOARD_H_ +#define _WINCLIPBOARD_H_ + +/* Standard library headers */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* X headers */ +#include "X.h" +#include "Xatom.h" +/* NOTE: For some unknown reason, including Xproto.h solves + * tons of problems with including windows.h. Unknowns reasons + * are usually bad, so someone should investigate this. + */ +#include "Xproto.h" +#include "Xutil.h" +#include "Xlocale.h" + +/* Fixups to prevent collisions between Windows and X headers */ +#define ATOM DWORD + +/* Windows headers */ +#include + + +/* Clipboard module constants */ +#define WIN_CLIPBOARD_WINDOW_CLASS "xwinclip" +#define WIN_CLIPBOARD_WINDOW_TITLE "xwinclip" +#define WIN_MSG_QUEUE_FNAME "/dev/windows" +#define WIN_CONNECT_RETRIES 3 +#define WIN_CONNECT_DELAY 4 +#define WIN_JMP_OKAY 0 +#define WIN_JMP_ERROR_IO 2 + +/* + * Argument structure for Clipboard module main thread + */ + +typedef struct _ClipboardProcArgRec { + DWORD dwScreen; + pthread_mutex_t *ppmServerStarted; +} ClipboardProcArgRec, *ClipboardProcArgPtr; + + +/* + * References to external symbols + */ + +extern char *display; +extern void ErrorF (const char* /*f*/, ...); + + +/* + * winclipboardinit.c + */ + +Bool +winInitClipboard (pthread_t *ptClipboardProc, + pthread_mutex_t *ppmServerStarted, + DWORD dwScreen); + +HWND +winClipboardCreateMessagingWindow (); + + +/* + * winclipboardtextconv.c + */ + +void +winClipboardDOStoUNIX (char *pszData, int iLength); + +void +winClipboardUNIXtoDOS (unsigned char **ppszData, int iLength); + + +/* + * winclipboardthread.c + */ + +void * +winClipboardProc (void *pArg); + + +/* + * winclipboardunicode.c + */ + +Bool +winClipboardDetectUnicodeSupport (); + + +/* + * winclipboardwndproc.c + */ + +BOOL +winClipboardFlushWindowsMessageQueue (HWND hwnd); + +LRESULT CALLBACK +winClipboardWindowProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam); + + +/* + * winclipboardxevents.c + */ + +Bool +winClipboardFlushXEvents (HWND hwnd, + Atom atomClipboard, + Atom atomLocalProperty, + Atom atomUTF8String, + Atom atomCompoundText, + Atom atomTargets, + Atom atomDeleteWindow, + int iWindow, + Display *pDisplay, + Bool fUnicodeSupport); +#endif diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c new file mode 100644 index 000000000..22c068c48 --- /dev/null +++ b/hw/xwin/winclipboardinit.c @@ -0,0 +1,117 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winclipboardinit.c,v 1.1 2003/02/12 15:01:38 alanh Exp $ */ + +#include "winclipboard.h" + + +/* + * Intialize the Clipboard module + */ + +Bool +winInitClipboard (pthread_t *ptClipboardProc, + pthread_mutex_t *ppmServerStarted, + DWORD dwScreen) +{ + ClipboardProcArgPtr pArg; + + ErrorF ("winInitClipboard ()\n"); + + /* Allocate the parameter structure */ + pArg = (ClipboardProcArgPtr) malloc (sizeof (ClipboardProcArgRec)); + if (pArg == NULL) + { + ErrorF ("winInitClipboard - malloc for ClipboardProcArgRec failed.\n"); + return FALSE; + } + + /* Setup the argument structure for the thread function */ + pArg->dwScreen = dwScreen; + pArg->ppmServerStarted = ppmServerStarted; + + /* Spawn a thread for the Clipboard module */ + if (pthread_create (ptClipboardProc, NULL, winClipboardProc, pArg)) + { + /* Bail if thread creation failed */ + ErrorF ("winInitClipboard - pthread_create failed.\n"); + return FALSE; + } + + return TRUE; +} + + +/* + * Create the Windows window that we use to recieve Windows messages + */ + +HWND +winClipboardCreateMessagingWindow () +{ + WNDCLASS wc; + HWND hwnd; + + /* Setup our window class */ + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = winClipboardWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = GetModuleHandle (NULL); + wc.hIcon = 0; + wc.hCursor = 0; + wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = WIN_CLIPBOARD_WINDOW_CLASS; + RegisterClass (&wc); + + /* Create the window */ + hwnd = CreateWindowExA (0, /* Extended styles */ + WIN_CLIPBOARD_WINDOW_CLASS,/* Class name */ + WIN_CLIPBOARD_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); + + /* I'm not sure, but we may need to call this to start message processing */ + ShowWindow (hwnd, SW_HIDE); + + /* Similarly, we may need a call to this even though we don't paint */ + UpdateWindow (hwnd); + + return hwnd; +} diff --git a/hw/xwin/winclipboardtextconv.c b/hw/xwin/winclipboardtextconv.c new file mode 100644 index 000000000..f97681c5f --- /dev/null +++ b/hw/xwin/winclipboardtextconv.c @@ -0,0 +1,153 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winclipboardtextconv.c,v 1.1 2003/02/12 15:01:38 alanh Exp $ */ + +#include "win.h" +#include +#include + + +/* + * Convert \r\n to \n + * + * NOTE: This was heavily inspired by, if not down right stolen from, + * Cygwin's winsup/cygwin/fhandler.cc/fhandler_base::read () + */ + +void +winClipboardDOStoUNIX (char *pszSrc, int iLength) +{ + char *pszDest = pszSrc; + char *pszEnd = pszSrc + iLength; + + /* Loop until the last character */ + while (pszSrc < pszEnd) + { + /* Copy the current source character to current destination character */ + *pszDest = *pszSrc; + + /* Advance to the next source character */ + pszSrc++; + + /* Don't advance the destination character if we need to drop an \r */ + if (*pszDest != '\r' || *pszSrc != '\n') + pszDest++; + } + + /* Move the terminating null */ + *pszDest = '\0'; +} + + +/* + * Convert \n to \r\n + */ + +void +winClipboardUNIXtoDOS (unsigned char **ppszData, int iLength) +{ + int iNewlineCount = 0; + unsigned char *pszSrc = *ppszData; + unsigned char *pszEnd = pszSrc + iLength; + unsigned char *pszDest = NULL, *pszDestBegin = NULL; + +#if 0 + ErrorF ("UNIXtoDOS () - Original data:\n%s\n", *ppszData); +#endif + + /* Count \n characters without leading \r */ + while (pszSrc < pszEnd) + { + /* Skip ahead two character if found set of \r\n */ + if (*pszSrc == '\r' && pszSrc + 1 < pszEnd && *(pszSrc + 1) == '\n') + { + pszSrc += 2; + continue; + } + + /* Increment the count if found naked \n */ + if (*pszSrc == '\n') + { + iNewlineCount++; + } + + pszSrc++; + } + + /* Return if no naked \n's */ + if (iNewlineCount == 0) + return; + + /* Allocate a new string */ + pszDestBegin = pszDest = malloc (iLength + iNewlineCount + 1); + + /* Set source pointer to beginning of data string */ + pszSrc = *ppszData; + + /* Loop through all characters in source string */ + while (pszSrc < pszEnd) + { + /* Copy line endings that are already valid */ + if (*pszSrc == '\r' && pszSrc + 1 < pszEnd && *(pszSrc + 1) == '\n') + { + *pszDest = *pszSrc; + *(pszDest + 1) = *(pszSrc + 1); + pszDest += 2; + pszSrc += 2; + continue; + } + + /* Add \r to naked \n's */ + if (*pszSrc == '\n') + { + *pszDest = '\r'; + *(pszDest + 1) = *pszSrc; + pszDest += 2; + pszSrc += 1; + continue; + } + + /* Copy normal characters */ + *pszDest = *pszSrc; + pszSrc++; + pszDest++; + } + + /* Put terminating null at end of new string */ + *pszDest = '\0'; + + /* Swap string pointers */ + free (*ppszData); + *ppszData = pszDestBegin; + +#if 0 + ErrorF ("UNIXtoDOS () - Final string:\n%s\n", pszDestBegin); +#endif +} diff --git a/hw/xwin/winclipboardthread.c b/hw/xwin/winclipboardthread.c new file mode 100644 index 000000000..ce4590b98 --- /dev/null +++ b/hw/xwin/winclipboardthread.c @@ -0,0 +1,463 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winclipboardthread.c,v 1.1 2003/02/12 15:01:38 alanh Exp $ */ + +#include "winclipboard.h" + +/* + * References to external symbols + */ + +extern Bool g_fCalledSetLocale; + + +/* + * Global variables + */ + +static jmp_buf g_jmpEntry; + + +/* + * Local function prototypes + */ + +static int +winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr); + +static int +winClipboardIOErrorHandler (Display *pDisplay); + + +/* + * Main thread function + */ + +void * +winClipboardProc (void *pArg) +{ + Atom atomClipboard, atomClipboardManager; + 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 szDisplay[512]; + int i; + ClipboardProcArgPtr pProcArg = (ClipboardProcArgPtr) pArg; + + ErrorF ("winClipboardProc - Hello\n"); + + /* Check that argument pointer is not invalid */ + if (pArg == NULL) + { + ErrorF ("winClipboardProc - pArg is NULL, bailing.\n"); + pthread_exit (NULL); + } + + ErrorF ("winClipboardProc - Calling pthread_mutex_lock ()\n"); + + /* Grab our garbage mutex to satisfy pthread_cond_wait */ + iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted); + if (iReturn != 0) + { + ErrorF ("winClipboardProc - pthread_mutex_lock () failed: %d\n", + iReturn); + pthread_exit (NULL); + } + + ErrorF ("winClipboardProc - pthread_mutex_lock () returned.\n"); + + /* Do we have Unicode support? */ + fUnicodeSupport = winClipboardDetectUnicodeSupport (); + + /* Set the current locale? What does this do? */ + if (fUnicodeSupport && !g_fCalledSetLocale) + { + ErrorF ("winClipboardProc - Calling setlocale ()\n"); + if (!setlocale (LC_ALL, "")) + { + ErrorF ("winClipboardProc - setlocale () error\n"); + pthread_exit (NULL); + } + ErrorF ("winClipboardProc - setlocale () returned\n"); + + /* See if X supports the current locale */ + if (XSupportsLocale () == False) + { + ErrorF ("winClipboardProc - Locale not supported by X\n"); + pthread_exit (NULL); + } + } + + /* Flag that we have called setlocale */ + g_fCalledSetLocale = TRUE; + + /* Release the garbage mutex */ + pthread_mutex_unlock (pProcArg->ppmServerStarted); + + ErrorF ("winClipboardProc - pthread_mutex_unlock () returned.\n"); + + /* Allow multiple threads to access Xlib */ + if (XInitThreads () == 0) + { + ErrorF ("winClipboardProc - XInitThreads failed.\n"); + pthread_exit (NULL); + } + + ErrorF ("winClipboardProc - XInitThreads () returned.\n"); + + /* Set jump point for Error exits */ + iReturn = setjmp (g_jmpEntry); + + /* Check if we should continue operations */ + if (iReturn != WIN_JMP_ERROR_IO + && iReturn != WIN_JMP_OKAY) + { + /* setjmp returned an unknown value, exit */ + ErrorF ("winClipboardProc - setjmp returned: %d exiting\n", + iReturn); + pthread_exit (NULL); + } + else if (iReturn == WIN_JMP_ERROR_IO) + { + ErrorF ("winClipboardProc - setjmp returned and hwnd: %08x\n", hwnd); + } + + /* Initialize retry count */ + iRetries = 0; + +#if 0 + /* Setup the display connection string x */ + snprintf (szDisplay, 512, "127.0.0.1:%s.%d", display, pProcArg->dwScreen); +#else + /* Setup the display connection string x */ + snprintf (szDisplay, 512, ":%s.%d", display, pProcArg->dwScreen); +#endif + + /* Print the display connection string */ + ErrorF ("winClipboardProc - DISPLAY=%s\n", szDisplay); + + /* Open the X display */ + do + { + pDisplay = XOpenDisplay (szDisplay); + if (pDisplay == NULL) + { + ErrorF ("winClipboardProc - Could not open display, " + "try: %d, sleeping: %d\n", + iRetries + 1, WIN_CONNECT_DELAY); + ++iRetries; + sleep (WIN_CONNECT_DELAY); + continue; + } + else + break; + } + while (pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES); + + /* Make sure that the display opened */ + if (pDisplay == NULL) + { + ErrorF ("winClipboardProc - Failed opening the display, giving up\n"); + pthread_exit (NULL); + } + + ErrorF ("winClipboardProc - XOpenDisplay () returned and " + "successfully opened the display.\n"); + + /* Create Windows messaging window */ + hwnd = winClipboardCreateMessagingWindow (); + + /* Get our connection number */ + iConnectionNumber = ConnectionNumber (pDisplay); + + /* Open a file descriptor for the windows message queue */ + fdMessageQueue = open (WIN_MSG_QUEUE_FNAME, O_RDONLY); + if (fdMessageQueue == -1) + { + ErrorF ("winClipboardProc - Failed opening %s\n", WIN_MSG_QUEUE_FNAME); + pthread_exit (NULL); + } + + /* Find max of our file descriptors */ + iMaxDescriptor = max (fdMessageQueue, iConnectionNumber) + 1; + + /* Select event types to watch */ + if (XSelectInput (pDisplay, + DefaultRootWindow (pDisplay), + SubstructureNotifyMask | + StructureNotifyMask | + PropertyChangeMask) == BadWindow) + ErrorF ("winClipboardProc - XSelectInput generated BadWindow " + "on RootWindow\n\n"); + + /* Create a messaging window */ + iWindow = XCreateSimpleWindow (pDisplay, + DefaultRootWindow (pDisplay), + 1, 1, + 500, 500, + 0, + BlackPixel (pDisplay, 0), + BlackPixel (pDisplay, 0)); + if (iWindow == 0) + { + ErrorF ("winClipboardProc - Could not create a window\n"); + pthread_exit (NULL); + } + + /* 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 */ + XSetErrorHandler (winClipboardErrorHandler); + XSetIOErrorHandler (winClipboardIOErrorHandler); + + /* Create an atom for CLIPBOARD_MANAGER */ + atomClipboardManager = XInternAtom (pDisplay, "CLIPBOARD_MANAGER", False); + if (atomClipboardManager == None) + { + ErrorF ("winClipboardProc - Could not create CLIPBOARD_MANAGER atom\n"); + pthread_exit (NULL); + } + + /* Assert ownership of CLIPBOARD_MANAGER */ + iReturn = XSetSelectionOwner (pDisplay, atomClipboardManager, + iWindow, CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow) + { + ErrorF ("winClipboardProc - Could not set CLIPBOARD_MANAGER owner\n"); + pthread_exit (NULL); + } + + /* Create an atom for CLIPBOARD */ + atomClipboard = XInternAtom (pDisplay, "CLIPBOARD", False); + if (atomClipboard == None) + { + ErrorF ("winClipboardProc - Could not create CLIPBOARD atom\n"); + pthread_exit (NULL); + } + + /* Assert ownership of CLIPBOARD */ + iReturn = XSetSelectionOwner (pDisplay, atomClipboard, + iWindow, CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow) + { + ErrorF ("winClipboardProc - Could not set CLIPBOARD owner\n"); + pthread_exit (NULL); + } + + /* Assert ownership of PRIMARY */ + iReturn = XSetSelectionOwner (pDisplay, XA_PRIMARY, + iWindow, CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow) + { + ErrorF ("winClipboardProc - Could not set PRIMARY owner\n"); + pthread_exit (NULL); + } + + /* Local property to hold pasted data */ + atomLocalProperty = XInternAtom (pDisplay, "CYGX_CUT_BUFFER", False); + if (atomLocalProperty == None) + { + ErrorF ("winClipboardProc - Could not create CYGX_CUT_BUFFER atom\n"); + pthread_exit (NULL); + } + + /* Create an atom for UTF8_STRING */ + atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False); + if (atomUTF8String == None) + { + ErrorF ("winClipboardProc - Could not create UTF8_STRING atom\n"); + pthread_exit (NULL); + } + + /* Create an atom for COMPOUND_TEXT */ + atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False); + if (atomCompoundText == None) + { + ErrorF ("winClipboardProc - Could not create COMPOUND_TEXT atom\n"); + pthread_exit (NULL); + } + + /* Create an atom for TARGETS */ + atomTargets = XInternAtom (pDisplay, "TARGETS", False); + if (atomTargets == None) + { + ErrorF ("winClipboardProc - Could not create TARGETS atom\n"); + pthread_exit (NULL); + } + + /* 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. + */ + winClipboardFlushXEvents (hwnd, + atomClipboard, + atomLocalProperty, + atomUTF8String, + atomCompoundText, + atomTargets, + atomDeleteWindow, + iWindow, + pDisplay, + fUnicodeSupport); + + /* Pre-flush Windows messages */ + if (!winClipboardFlushWindowsMessageQueue (hwnd)) + return 0; + + /* Loop for X events */ + while (1) + { + /* Setup the file descriptor set */ + /* + * NOTE: You have to do this before every call to select + * because select modifies the mask to indicate + * which descriptors are ready. + */ + FD_ZERO (&fdsRead); + FD_SET (fdMessageQueue, &fdsRead); + FD_SET (iConnectionNumber, &fdsRead); + + /* 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 */ + if (iReturn <= 0) + { + ErrorF ("winClipboardProc - Call to select () failed: %d. " + "Bailing.\n", iReturn); + break; + } + + /* Branch on which descriptor became active */ + if (FD_ISSET (iConnectionNumber, &fdsRead)) + { + /* X event ready */ +#if 0 + ErrorF ("winClipboardProc - X event ready\n"); +#endif + + /* Process X events */ + /* Exit when we see that server is shutting down */ + fReturn = winClipboardFlushXEvents (hwnd, + atomClipboard, + atomLocalProperty, + atomUTF8String, + atomCompoundText, + atomTargets, + atomDeleteWindow, + iWindow, + pDisplay, + fUnicodeSupport); + if (!fReturn) + { + ErrorF ("winClipboardProc - Caught WM_DELETE_WINDOW - " + "shutting down\n"); + break; + } + } + + /* Check for Windows event ready */ + if (FD_ISSET (fdMessageQueue, &fdsRead)) + { + /* Windows event ready */ +#if 0 + ErrorF ("winClipboardProc - Windows event ready\n"); +#endif + + /* Process Windows messages */ + if (!winClipboardFlushWindowsMessageQueue (hwnd)) + break; + } + } + + return 0; +} + + +/* + * winClipboardErrorHandler - Our application specific error handler + */ + +static int +winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr) +{ + char pszErrorMsg[100]; + + XGetErrorText (pDisplay, + pErr->error_code, + pszErrorMsg, + sizeof (pszErrorMsg)); + ErrorF ("winClipboardErrorHandler - ERROR: \n\t%s\n", pszErrorMsg); + + if (pErr->error_code==BadWindow + || pErr->error_code==BadMatch + || pErr->error_code==BadDrawable) + { + pthread_exit (NULL); + } + + pthread_exit (NULL); + + return 0; +} + + +/* + * winClipboardIOErrorHandler - Our application specific IO error handler + */ + +static int +winClipboardIOErrorHandler (Display *pDisplay) +{ + printf ("\nwinClipboardIOErrorHandler!\n\n"); + + /* Restart at the main entry point */ + longjmp (g_jmpEntry, WIN_JMP_ERROR_IO); + + return 0; +} diff --git a/hw/xwin/winclipboardunicode.c b/hw/xwin/winclipboardunicode.c new file mode 100644 index 000000000..fdbcb8e69 --- /dev/null +++ b/hw/xwin/winclipboardunicode.c @@ -0,0 +1,68 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winclipboardunicode.c,v 1.1 2003/02/12 15:01:38 alanh Exp $ */ + +#include "win.h" + + +/* + * Determine whether we suport Unicode or not. + * NOTE: Currently, just check if we are on an NT-based platform or not. + */ + +Bool +winClipboardDetectUnicodeSupport () +{ + 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 */ + ErrorF ("DetectUnicodeSupport - Windows NT/2000/XP\n"); + fReturn = TRUE; + break; + + case VER_PLATFORM_WIN32_WINDOWS: + /* Engine 4 is supported on NT only */ + ErrorF ("DetectUnicodeSupport - Windows 95/98/Me\n"); + fReturn = FALSE; + break; + } + + return fReturn; +} diff --git a/hw/xwin/winclipboardwndproc.c b/hw/xwin/winclipboardwndproc.c new file mode 100644 index 000000000..d27bb4861 --- /dev/null +++ b/hw/xwin/winclipboardwndproc.c @@ -0,0 +1,86 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winclipboardwndproc.c,v 1.1 2003/02/12 15:01:38 alanh Exp $ */ + +#include "winclipboard.h" + + +/* + * Process a given Windows message + */ + +LRESULT CALLBACK +winClipboardWindowProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam) +{ + /* Branch on message type */ + switch (message) + { + case WM_DESTROY: + PostQuitMessage (0); + return 0; + + case WM_CREATE: +#if 0 + ErrorF ("WindowProc - WM_CREATE\n"); +#endif + return 0; + } + + /* Let Windows perform default processing for unhandled messages */ + return DefWindowProc (hwnd, message, wParam, lParam); +} + + +/* + * Process any pending Windows messages + */ + +BOOL +winClipboardFlushWindowsMessageQueue (HWND hwnd) +{ + MSG msg; + + /* Flush the messaging window queue */ + /* NOTE: Do not pass the hwnd of our messaging window to PeekMessage, + * as this will filter out many non-window-specific messages that + * are sent to our thread, such as WM_QUIT. + */ + while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + { + /* Dispatch the message if not WM_QUIT */ + if (msg.message == WM_QUIT) + return FALSE; + else + DispatchMessage (&msg); + } + + return TRUE; +} diff --git a/hw/xwin/winclipboardxevents.c b/hw/xwin/winclipboardxevents.c new file mode 100644 index 000000000..a09c7c185 --- /dev/null +++ b/hw/xwin/winclipboardxevents.c @@ -0,0 +1,722 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winclipboardxevents.c,v 1.1 2003/02/12 15:01:38 alanh Exp $ */ + +#include "winclipboard.h" + + +/* + * Process any pending X events + */ + +Bool +winClipboardFlushXEvents (HWND hwnd, + Atom atomClipboard, + Atom atomLocalProperty, + Atom atomUTF8String, + Atom atomCompoundText, + Atom atomTargets, + Atom atomDeleteWindow, + int iWindow, + Display *pDisplay, + Bool fUnicodeSupport) +{ + Atom atomReturnType; + int iReturnFormat; + unsigned long ulReturnItems; + XTextProperty xtpText; + XEvent event; + XSelectionEvent eventSelection; + unsigned long ulReturnBytesLeft; + unsigned char *pszReturnData = NULL; + char *pszGlobalData = NULL; + int iReturn; + HGLOBAL hGlobal; + Bool fReturn = TRUE; + XICCEncodingStyle xiccesStyle; + int iUTF8; + char *pszUTF8 = NULL; + char *pszTextList[2]; + int iCount; + char **ppszTextList = NULL; + wchar_t *pwszUnicodeStr = NULL; + int iUnicodeLen = 0; + + /* Process all pending events */ + while (XPending (pDisplay)) + { + /* Get the next event - will not block because one is ready */ + XNextEvent (pDisplay, &event); + + /* Branch on the event type */ + switch (event.type) + { + case ClientMessage: + if (event.xclient.data.l[0] == atomDeleteWindow) + { + ErrorF ("\nReceived WM_DELETE_WINDOW\n\n"); + fReturn = FALSE; + } + else + ErrorF ("\nUnknown ClientMessage\n\n"); + break; + + case SelectionClear: + /* Request the lost selection contents */ + iReturn = XConvertSelection (pDisplay, + event.xselectionclear.selection, + atomCompoundText, + atomLocalProperty, + iWindow, + CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow) + { + ErrorF ("SelectionClear - XConvertSelection () failed\n"); + pthread_exit (NULL); + } + break; + + + /* + * SelectionRequest + */ + + case SelectionRequest: +#if 0 + char *pszAtomName = NULL + + ErrorF ("SelectionRequest - target %d\n", + event.xselectionrequest.target); + + pszAtomName = XGetAtomName (pDisplay, + event.xselectionrequest.target); + ErrorF ("SelectionRequest - Target atom name %s\n", pszAtomName); + XFree (pszAtomName); + pszAtomName = NULL; +#endif + + /* Abort if invalid target type */ + if (event.xselectionrequest.target != XA_STRING + && event.xselectionrequest.target != atomUTF8String + && event.xselectionrequest.target != atomCompoundText + && event.xselectionrequest.target != atomTargets) + { + /* Setup selection notify event */ + eventSelection.type = SelectionNotify; + eventSelection.send_event = True; + eventSelection.display = pDisplay; + eventSelection.requestor = event.xselectionrequest.requestor; + eventSelection.selection = event.xselectionrequest.selection; + eventSelection.target = event.xselectionrequest.target; + eventSelection.property = None; + eventSelection.time = event.xselectionrequest.time; + + /* Notify the requesting window that the operation is complete */ + iReturn = XSendEvent (pDisplay, + eventSelection.requestor, + False, + 0L, + (XEvent *) &eventSelection); + if (iReturn == BadValue || iReturn == BadWindow) + { + ErrorF ("SelectionRequest - XSendEvent () failed\n"); + pthread_exit (NULL); + } + + break; + } + + /* Handle targets type of request */ + if (event.xselectionrequest.target == atomTargets) + { + Atom atomTargetArr[4] = {atomTargets, + atomCompoundText, + atomUTF8String, + XA_STRING}; + + /* Try to change the property */ + iReturn = XChangeProperty (pDisplay, + event.xselectionrequest.requestor, + event.xselectionrequest.property, + event.xselectionrequest.target, + 8, + PropModeReplace, + (char *) atomTargetArr, + sizeof (atomTargetArr)); + if (iReturn == BadAlloc + || iReturn == BadAtom + || iReturn == BadMatch + || iReturn == BadValue + || iReturn == BadWindow) + { + ErrorF ("SelectionRequest - XChangeProperty failed: %d\n", + iReturn); + } + + /* Setup selection notify xevent */ + eventSelection.type = SelectionNotify; + eventSelection.send_event = True; + eventSelection.display = pDisplay; + eventSelection.requestor = event.xselectionrequest.requestor; + eventSelection.selection = event.xselectionrequest.selection; + eventSelection.target = event.xselectionrequest.target; + eventSelection.property = event.xselectionrequest.property; + eventSelection.time = event.xselectionrequest.time; + + /* + * Notify the requesting window that + * the operation has completed + */ + iReturn = XSendEvent (pDisplay, + eventSelection.requestor, + False, + 0L, + (XEvent *) &eventSelection); + if (iReturn == BadValue || iReturn == BadWindow) + { + ErrorF ("SelectionRequest - XSendEvent () failed\n"); + } + break; + } + + /* Access the clipboard */ + if (!OpenClipboard (hwnd)) + { + ErrorF ("SelectionRequest - OpenClipboard () failed: %08x\n", + GetLastError ()); + pthread_exit (NULL); + } + + /* Setup the string style */ + if (event.xselectionrequest.target == XA_STRING) + xiccesStyle = XStringStyle; + else if (event.xselectionrequest.target == atomUTF8String) + xiccesStyle = XUTF8StringStyle; + else if (event.xselectionrequest.target == atomCompoundText) + xiccesStyle = XCompoundTextStyle; + else + xiccesStyle = XStringStyle; + + /* + * FIXME: Can't pass CF_UNICODETEXT on Windows 95/98/Me + */ + + /* Get a pointer to the clipboard text */ + if (fUnicodeSupport) + hGlobal = GetClipboardData (CF_UNICODETEXT); + else + hGlobal = GetClipboardData (CF_TEXT); + if (!hGlobal) + { + ErrorF ("SelectionRequest - GetClipboardData () failed: %08x\n", + GetLastError ()); + pthread_exit (NULL); + } + pszGlobalData = (char *) GlobalLock (hGlobal); + + /* Convert the Unicode string to UTF8 (MBCS) */ + if (fUnicodeSupport) + { + iUTF8 = WideCharToMultiByte (CP_UTF8, + 0, + (LPCWSTR)pszGlobalData, + -1, + NULL, + 0, + NULL, + NULL); + pszUTF8 = (char *) malloc (iUTF8); /* Don't need +1 */ + WideCharToMultiByte (CP_UTF8, + 0, + (LPCWSTR)pszGlobalData, + -1, + pszUTF8, + iUTF8, + NULL, + NULL); + } + + /* Convert DOS string to UNIX string */ + if (fUnicodeSupport) + { + winClipboardDOStoUNIX (pszUTF8, strlen (pszUTF8)); + + /* Setup our text list */ + pszTextList[0] = pszUTF8; + pszTextList[1] = NULL; + + /* Initialize the text property */ + xtpText.value = NULL; + + /* Create the text property from the text list */ + iReturn = Xutf8TextListToTextProperty (pDisplay, + pszTextList, + 1, + xiccesStyle, + &xtpText); + if (iReturn == XNoMemory || iReturn == XLocaleNotSupported) + { + ErrorF ("SelectionRequest - Xutf8TextListToTextProperty " + "failed: %d\n", + iReturn); + exit(1); + } + + /* Free the UTF8 string */ + free (pszUTF8); + } + else + winClipboardDOStoUNIX (pszGlobalData, strlen (pszGlobalData)); + + /* + * FIXME: Pass pszGlobalData and strlen (pszGlobalData( + * on 1 byte, pass xtpText.value and xtpText.nitems + * on 2 byte. + */ + + /* Copy the clipboard text to the requesting window */ + if (fUnicodeSupport) + iReturn = XChangeProperty (pDisplay, + event.xselectionrequest.requestor, + event.xselectionrequest.property, + event.xselectionrequest.target, + 8, + PropModeReplace, + xtpText.value, + xtpText.nitems); + else + iReturn = XChangeProperty (pDisplay, + event.xselectionrequest.requestor, + event.xselectionrequest.property, + event.xselectionrequest.target, + 8, + PropModeReplace, + pszGlobalData, + strlen (pszGlobalData)); + if (iReturn == BadAlloc || iReturn == BadAtom + || iReturn == BadMatch || iReturn == BadValue + || iReturn == BadWindow) + { + ErrorF ("SelectionRequest - XChangeProperty failed: %d\n", + iReturn); + pthread_exit (NULL); + } + + /* Release the clipboard data */ + GlobalUnlock (hGlobal); + pszGlobalData = NULL; + CloseClipboard (); + + /* FIXME: Don't clean up on 1 byte. */ + if (fUnicodeSupport) + { + XFree (xtpText.value); + xtpText.value = NULL; + } + + /* Setup selection notify event */ + eventSelection.type = SelectionNotify; + eventSelection.send_event = True; + eventSelection.display = pDisplay; + eventSelection.requestor = event.xselectionrequest.requestor; + eventSelection.selection = event.xselectionrequest.selection; + eventSelection.target = event.xselectionrequest.target; + eventSelection.property = event.xselectionrequest.property; + eventSelection.time = event.xselectionrequest.time; + + /* Notify the requesting window that the operation has completed */ + iReturn = XSendEvent (pDisplay, + eventSelection.requestor, + False, + 0L, + (XEvent *) &eventSelection); + if (iReturn == BadValue || iReturn == BadWindow) + { + ErrorF ("SelectionRequest - XSendEvent () failed\n"); + pthread_exit (NULL); + } + break; + + + /* + * SelectionNotify + */ + + case SelectionNotify: +#if 0 + ErrorF ("SelectionNotify\n"); +#endif + { + char *pszAtomName; + + pszAtomName = XGetAtomName (pDisplay, + event.xselection.selection); + + ErrorF ("SelectionNotify - ATOM: %s\n", + pszAtomName); + + XFree (pszAtomName); + } + +#if 0 + /* + * TEMP: Bail if selection is anything other than CLIPBOARD + */ + + if (event.xselection.selection != atomClipboard) + break; +#endif + + /* + * + * What are we doing here? + * + */ + if (fUnicodeSupport) + { + if (event.xselection.property == None) + { + if(event.xselection.target == XA_STRING) + { +#if 0 + ErrorF ("SelectionNotify XA_STRING\n"); +#endif + return fReturn; + } + else if (event.xselection.target == atomUTF8String) + { + ErrorF ("SelectionNotify UTF8\n"); + iReturn = XConvertSelection (pDisplay, + event.xselection.selection, + XA_STRING, + atomLocalProperty, + iWindow, + CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow) + { + ErrorF ("SelectionNotify - XConvertSelection () " + "failed\n"); + pthread_exit (NULL); + } + return fReturn; + } + else if (event.xselection.target == atomCompoundText) + { + ErrorF ("SelectionNotify CompoundText\n"); + iReturn = XConvertSelection (pDisplay, + event.xselection.selection, + atomUTF8String, + atomLocalProperty, + iWindow, + CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow) + { + ErrorF ("SelectionNotify - XConvertSelection () " + "failed\n"); + pthread_exit (NULL); + } + return fReturn; + } + else + { + ErrorF("Unknown format\n"); + return fReturn; + } + } + } + + /* Retrieve the size of the stored data */ + if (fUnicodeSupport) + iReturn = XGetWindowProperty (pDisplay, + iWindow, + atomLocalProperty, + 0, + 0, /* Don't get data, just size */ + False, + AnyPropertyType, + &xtpText.encoding, + &xtpText.format, + &xtpText.nitems, + &ulReturnBytesLeft, + &xtpText.value); + else + iReturn = XGetWindowProperty (pDisplay, + iWindow, + atomLocalProperty, + 0, + 0, /* Don't get data, just size */ + False, + AnyPropertyType, + &atomReturnType, + &iReturnFormat, + &ulReturnItems, + &ulReturnBytesLeft, + &pszReturnData); + if (iReturn != Success) + { + ErrorF ("SelectionNotify - XGetWindowProperty () failed\n"); + pthread_exit (NULL); + } + +#if 0 + if (fUnicodeSupport) + ErrorF ("SelectionNotify - returned data %d left %d\n", + xtpText.nitems, ulReturnBytesLeft); + else + ErrorF ("SelectionNotify - returned data %d left %d\n", + ulReturnItems, ulReturnBytesLeft); +#endif + + /* Request the selection data */ + if (fUnicodeSupport) + iReturn = XGetWindowProperty (pDisplay, + iWindow, + atomLocalProperty, + 0, + ulReturnBytesLeft, + False, + AnyPropertyType, + &xtpText.encoding, + &xtpText.format, + &xtpText.nitems, + &ulReturnBytesLeft, + &xtpText.value); + else + iReturn = XGetWindowProperty (pDisplay, + iWindow, + atomLocalProperty, + 0, + ulReturnBytesLeft, + False, + AnyPropertyType, + &atomReturnType, + &iReturnFormat, + &ulReturnItems, + &ulReturnBytesLeft, + &pszReturnData); + if (iReturn != Success) + { + ErrorF ("SelectionNotify - XGetWindowProperty () failed\n"); + pthread_exit (NULL); + } + + if (fUnicodeSupport) + { +#if 0 + char *pszAtomName = NULL; + + ErrorF ("SelectionNotify - returned data %d left %d\n", + prop.nitems, ulReturnBytesLeft); + + pszAtomName = XGetAtomName(pDisplay, prop.encoding); + ErrorF ("Notify atom name %s\n", pszAtomName); + XFree (pszAtomName); + pszAtomName = NULL; +#endif + + /* Convert the text property to a text list */ + Xutf8TextPropertyToTextList (pDisplay, + &xtpText, + &ppszTextList, + &iCount); + if (iCount > 0) + { + pszReturnData = malloc (strlen (ppszTextList[0]) + 1); + strcpy (pszReturnData, ppszTextList[0]); + } + else + { + pszReturnData = malloc (1); + pszReturnData[0] = 0; + } + + /* Free the data returned from XGetWindowProperty */ + XFreeStringList (ppszTextList); + XFree (xtpText.value); + } + + /* Convert the X clipboard string to DOS format */ + winClipboardUNIXtoDOS (&pszReturnData, strlen (pszReturnData)); + + if (fUnicodeSupport) + { + /* Find out how much space needed to convert MBCS to Unicode */ + iUnicodeLen = MultiByteToWideChar (CP_UTF8, + 0, + pszReturnData, + -1, + NULL, + 0); + + /* Allocate memory for the Unicode string */ + pwszUnicodeStr + = (wchar_t*) malloc (sizeof (wchar_t) * (iUnicodeLen + 1)); + + /* Do the actual conversion */ + MultiByteToWideChar (CP_UTF8, + 0, + pszReturnData, + -1, + pwszUnicodeStr, + iUnicodeLen); + } + + /* Access the Windows clipboard */ + if (!OpenClipboard (hwnd)) + { + ErrorF ("OpenClipboard () failed: %08x\n", GetLastError ()); + pthread_exit (NULL); + } + + /* Take ownership of the Window clipboard */ + if (!EmptyClipboard ()) + { + ErrorF ("EmptyClipboard () failed: %08x\n", GetLastError ()); + pthread_exit (NULL); + } + + /* Allocate global memory for the X clipboard data */ + if (fUnicodeSupport) + hGlobal = GlobalAlloc (GMEM_MOVEABLE, + sizeof (wchar_t) * (iUnicodeLen + 1)); + else + hGlobal = GlobalAlloc (GMEM_MOVEABLE, strlen (pszReturnData) + 1); + + /* Obtain a pointer to the global memory */ + pszGlobalData = GlobalLock (hGlobal); + if (pszGlobalData == NULL) + { + ErrorF ("Could not lock global memory for clipboard transfer\n"); + pthread_exit (NULL); + } + + /* Copy the returned string into the global memory */ + if (fUnicodeSupport) + memcpy (pszGlobalData, + pwszUnicodeStr, + sizeof (wchar_t) * (iUnicodeLen + 1)); + else + strcpy (pszGlobalData, pszReturnData); + + /* Free the data returned from XGetWindowProperty */ + if (fUnicodeSupport) + { + free (pwszUnicodeStr); + pwszUnicodeStr = NULL; + } + else + { + XFree (pszReturnData); + pszReturnData = NULL; + } + + /* Release the pointer to the global memory */ + GlobalUnlock (hGlobal); + pszGlobalData = NULL; + + /* Push the selection data to the Windows clipboard */ + if (fUnicodeSupport) + SetClipboardData (CF_UNICODETEXT, hGlobal); + else + SetClipboardData (CF_TEXT, hGlobal); + + /* + * NOTE: Do not try to free pszGlobalData, it is owned by + * Windows after the call to SetClipboardData (). + */ + + /* Release the clipboard */ + if (!CloseClipboard ()) + { + ErrorF ("CloseClipboard () failed: %08x\n", GetLastError ()); + pthread_exit (NULL); + } + + /* Reassert ownership of the selection */ + iReturn = XSetSelectionOwner (pDisplay, + event.xselection.selection, + iWindow, CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow) + { + char *pszAtomName = NULL; + + pszAtomName = XGetAtomName (pDisplay, + event.xselection.selection); + ErrorF ("SelectionNotify - Could not reassert ownership " + "of selection ATOM: %s\n", pszAtomName); + XFree (pszAtomName); + pszAtomName = NULL; + pthread_exit (NULL); + } + else + { +#if 0 + char *pszAtomName = NULL; + + pszAtomName = XGetAtomName (pDisplay, + event.xselection.selection); + ErrorF ("SelectionNotify - Reasserted ownership of ATOM: %s\n", + pszAtomName); + XFree (pszAtomName); + pszAtomName = NULL; +#endif + } +#if 0 + /* Reassert ownership of the CLIPBOARD */ + iReturn = XSetSelectionOwner (pDisplay, + atomClipboard, + iWindow, CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow) + { + ErrorF ("Could not reassert ownership of selection\n"); + pthread_exit (NULL); + } +#endif + break; + +#if 0 + case CreateNotify: + ErrorF ("FlushXEvents - CreateNotify parent: %ld\twindow: %ld\n", + event.xcreatewindow.parent, event.xcreatewindow.window); + break; + + case DestroyNotify: + ErrorF ("FlushXEvents - DestroyNotify window: %ld\tevent: %ld\n", + event.xdestroywindow.window, event.xdestroywindow.event); + break; +#endif + + default: + break; + } + } + + return fReturn; +} diff --git a/hw/xwin/wincmap.c b/hw/xwin/wincmap.c new file mode 100644 index 000000000..4fb89a2fd --- /dev/null +++ b/hw/xwin/wincmap.c @@ -0,0 +1,631 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/wincmap.c,v 1.10 2002/10/17 08:18:22 alanh Exp $ */ + +#include "win.h" + + +/* See Porting Layer Definition - p. 30 */ +/* + * Walk the list of installed colormaps, filling the pmaps list + * with the resource ids of the installed maps, and return + * a count of the total number of installed maps. + */ +int +winListInstalledColormaps (ScreenPtr pScreen, Colormap *pmaps) +{ + winScreenPriv(pScreen); + + /* + * There will only be one installed colormap, so we only need + * to return one id, and the count of installed maps will always + * be one. + */ + *pmaps = pScreenPriv->pcmapInstalled->mid; + return 1; +} + + +/* See Porting Layer Definition - p. 30 */ +/* See Programming Windows - p. 663 */ +void +winInstallColormap (ColormapPtr pColormap) +{ + ScreenPtr pScreen = pColormap->pScreen; + winScreenPriv(pScreen); + ColormapPtr oldpmap = pScreenPriv->pcmapInstalled; + +#if CYGDEBUG + ErrorF ("winInstallColormap\n"); +#endif + + /* Did the colormap actually change? */ + if (pColormap != oldpmap) + { +#if CYGDEBUG + ErrorF ("winInstallColormap - Colormap has changed, attempt " + "to install.\n"); +#endif + + /* Was there a previous colormap? */ + if (oldpmap != (ColormapPtr) None) + { + /* There was a previous colormap; tell clients it is gone */ + WalkTree (pColormap->pScreen, TellLostMap, (char *)&oldpmap->mid); + } + + /* Install new colormap */ + pScreenPriv->pcmapInstalled = pColormap; + WalkTree (pColormap->pScreen, TellGainedMap, (char *)&pColormap->mid); + + /* Call the engine specific colormap install procedure */ + if (!((*pScreenPriv->pwinInstallColormap) (pColormap))) + { + ErrorF ("winInstallColormap - Screen specific colormap install " + "procedure failed. Continuing, but colors may be " + "messed up from now on.\n"); + } + } + + /* Save a pointer to the newly installed colormap */ + pScreenPriv->pcmapInstalled = pColormap; +} + + +/* See Porting Layer Definition - p. 30 */ +void +winUninstallColormap (ColormapPtr pmap) +{ + winScreenPriv(pmap->pScreen); + ColormapPtr curpmap = pScreenPriv->pcmapInstalled; + +#if CYGDEBUG + ErrorF ("winUninstallColormap\n"); +#endif + + /* Is the colormap currently installed? */ + if (pmap != curpmap) + { + /* Colormap not installed, nothing to do */ + return; + } + + /* Clear the installed colormap flag */ + pScreenPriv->pcmapInstalled = NULL; + + /* + * NOTE: The default colormap does not get "uninstalled" before + * it is destroyed. + */ + + /* Install the default cmap in place of the cmap to be uninstalled */ + if (pmap->mid != pmap->pScreen->defColormap) + { + curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap, + RT_COLORMAP); + (*pmap->pScreen->InstallColormap) (curpmap); + } +} + + +/* See Porting Layer Definition - p. 30 */ +void +winStoreColors (ColormapPtr pmap, + int ndef, + xColorItem *pdefs) +{ + ScreenPtr pScreen = pmap->pScreen; + winScreenPriv(pScreen); + winCmapPriv(pmap); + int i; + unsigned short nRed, nGreen, nBlue; + +#if CYGDEBUG + if (ndef != 1) + ErrorF ("winStoreColors - ndef: %d\n", + ndef); +#endif + + /* Save the new colors in the colormap privates */ + for (i = 0; i < ndef; ++i) + { + /* Adjust the colors from the X color spec to the Windows color spec */ + nRed = pdefs[i].red >> 8; + nGreen = pdefs[i].green >> 8; + nBlue = pdefs[i].blue >> 8; + + /* Copy the colors to a palette entry table */ + pCmapPriv->peColors[pdefs[0].pixel + i].peRed = nRed; + pCmapPriv->peColors[pdefs[0].pixel + i].peGreen = nGreen; + pCmapPriv->peColors[pdefs[0].pixel + i].peBlue = nBlue; + + /* Copy the colors to a RGBQUAD table */ + pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbRed = nRed; + pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbGreen = nGreen; + pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbBlue = nBlue; + +#if CYGDEBUG + ErrorF ("winStoreColors - nRed %d nGreen %d nBlue %d\n", + nRed, nGreen, nBlue); +#endif + } + + /* Call the engine specific store colors procedure */ + if (!((pScreenPriv->pwinStoreColors) (pmap, ndef, pdefs))) + { + ErrorF ("winStoreColors - Engine cpecific color storage procedure " + "failed. Continuing, but colors may be messed up from now " + "on.\n"); + } +} + + +/* See Porting Layer Definition - p. 30 */ +void +winResolveColor (unsigned short *pred, + unsigned short *pgreen, + unsigned short *pblue, + VisualPtr pVisual) +{ +#if CYGDEBUG + ErrorF ("winResolveColor ()\n"); +#endif + + miResolveColor (pred, pgreen, pblue, pVisual); +} + + +/* See Porting Layer Definition - p. 29 */ +Bool +winCreateColormap (ColormapPtr pmap) +{ + winPrivCmapPtr pCmapPriv = NULL; + ScreenPtr pScreen = pmap->pScreen; + winScreenPriv(pScreen); + +#if CYGDEBUG + ErrorF ("winCreateColormap\n"); +#endif + + /* Allocate colormap privates */ + if (!winAllocateCmapPrivates (pmap)) + { + ErrorF ("winCreateColorma - Couldn't allocate cmap privates\n"); + return FALSE; + } + + /* Get a pointer to the newly allocated privates */ + pCmapPriv = winGetCmapPriv (pmap); + + /* + * FIXME: This is some evil hackery to help in handling some X clients + * that expect the top pixel to be white. This "help" only lasts until + * some client overwrites the top colormap entry. + * + * We don't want to actually allocate the top entry, as that causes + * problems with X clients that need 7 planes (128 colors) in the default + * colormap, such as Magic 7.1. + */ + pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbRed = 255; + pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbGreen = 255; + pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbBlue = 255; + pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peRed = 255; + pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peGreen = 255; + pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peBlue = 255; + + /* Call the engine specific colormap initialization procedure */ + if (!((*pScreenPriv->pwinCreateColormap) (pmap))) + { + ErrorF ("winCreateColormap - Engine specific colormap creation " + "procedure failed. Aborting.\n"); + return FALSE; + } + + return TRUE; +} + + +/* See Porting Layer Definition - p. 29, 30 */ +void +winDestroyColormap (ColormapPtr pColormap) +{ + winScreenPriv(pColormap->pScreen); + winCmapPriv(pColormap); + + /* Call the engine specific colormap destruction procedure */ + if (!((*pScreenPriv->pwinDestroyColormap) (pColormap))) + { + ErrorF ("winDestroyColormap - Engine specific colormap destruction " + "procedure failed. Continuing, but it is possible that memory " + "was leaked, or that colors will be messed up from now on.\n"); + } + + /* Free the colormap privates */ + free (pCmapPriv); + winSetCmapPriv (pColormap, NULL); + +#if CYGDEBUG + ErrorF ("winDestroyColormap - Returning\n"); +#endif +} + + +int +winExpandDirectColors (ColormapPtr pmap, int ndef, + xColorItem *indefs, xColorItem *outdefs) +{ + ErrorF ("\nwinExpandDirectColors\n"); + return miExpandDirectColors (pmap, ndef, indefs, outdefs); +} + + +/* + * Internal function to load the palette used by the Shadow DIB + */ + +static +Bool +winGetPaletteDIB (ScreenPtr pScreen, ColormapPtr pcmap) +{ + winScreenPriv(pScreen); + int i; + Pixel pixel; /* Pixel == CARD32 */ + CARD16 nRed, nGreen, nBlue; /* CARD16 == unsigned short */ + UINT uiColorsRetrieved = 0; + RGBQUAD rgbColors[WIN_NUM_PALETTE_ENTRIES]; + + /* Get the color table for the screen */ + uiColorsRetrieved = GetDIBColorTable (pScreenPriv->hdcScreen, + 0, + WIN_NUM_PALETTE_ENTRIES, + rgbColors); + if (uiColorsRetrieved == 0) + { + ErrorF ("winGetPaletteDIB - Could not retrieve screen color table\n"); + return FALSE; + } + +#if CYGDEBUG + ErrorF ("winGetPaletteDIB - Retrieved %d colors from DIB\n", + uiColorsRetrieved); +#endif + + /* Set the DIB color table to the default screen palette */ + if (SetDIBColorTable (pScreenPriv->hdcShadow, + 0, + uiColorsRetrieved, + rgbColors) == 0) + { + ErrorF ("winGetPaletteDIB - SetDIBColorTable () failed\n"); + return FALSE; + } + + /* Alloc each color in the DIB color table */ + for (i = 0; i < uiColorsRetrieved; ++i) + { + pixel = i; + + /* Extract the color values for current palette entry */ + nRed = rgbColors[i].rgbRed << 8; + nGreen = rgbColors[i].rgbGreen << 8; + nBlue = rgbColors[i].rgbBlue << 8; + +#if CYGDEBUG + ErrorF ("winGetPaletteDIB - Allocating a color: %d; " + "%d %d %d\n", + pixel, nRed, nGreen, nBlue); +#endif + + /* Allocate a entry in the X colormap */ + if (AllocColor (pcmap, + &nRed, + &nGreen, + &nBlue, + &pixel, + 0) != Success) + { + ErrorF ("winGetPaletteDIB - AllocColor () failed, pixel %d\n", + i); + return FALSE; + } + + if (i != pixel + || nRed != rgbColors[i].rgbRed + || nGreen != rgbColors[i].rgbGreen + || nBlue != rgbColors[i].rgbBlue) + { + ErrorF ("winGetPaletteDIB - Got: %d; " + "%d %d %d\n", + pixel, nRed, nGreen, nBlue); + } + + /* FIXME: Not sure that this bit is needed at all */ + pcmap->red[i].co.local.red = nRed; + pcmap->red[i].co.local.green = nGreen; + pcmap->red[i].co.local.blue = nBlue; + } + + /* System is using a colormap */ + /* Set the black and white pixel indices */ + pScreen->whitePixel = uiColorsRetrieved - 1; + pScreen->blackPixel = 0; + + return TRUE; +} + + +/* + * Internal function to load the standard system palette being used by GDI + */ + +static +Bool +winGetPaletteDD (ScreenPtr pScreen, ColormapPtr pcmap) +{ + int i; + Pixel pixel; /* Pixel == CARD32 */ + CARD16 nRed, nGreen, nBlue; /* CARD16 == unsigned short */ + UINT uiSystemPaletteEntries; + LPPALETTEENTRY ppeColors = NULL; + HDC hdc = NULL; + + /* Get a DC to obtain the default palette */ + hdc = GetDC (NULL); + if (hdc == NULL) + { + ErrorF ("winGetPaletteDD - Couldn't get a DC\n"); + return FALSE; + } + + /* Get the number of entries in the system palette */ + uiSystemPaletteEntries = GetSystemPaletteEntries (hdc, + 0, 0, NULL); + if (uiSystemPaletteEntries == 0) + { + ErrorF ("winGetPaletteDD - Unable to determine number of " + "system palette entries\n"); + return FALSE; + } + +#if CYGDEBUG + ErrorF ("winGetPaletteDD - uiSystemPaletteEntries %d\n", + uiSystemPaletteEntries); +#endif + + /* Allocate palette entries structure */ + ppeColors = malloc (uiSystemPaletteEntries * sizeof (PALETTEENTRY)); + if (ppeColors == NULL) + { + ErrorF ("winGetPaletteDD - malloc () for colormap failed\n"); + return FALSE; + } + + /* Get system palette entries */ + GetSystemPaletteEntries (hdc, + 0, uiSystemPaletteEntries, ppeColors); + + /* Allocate an X colormap entry for every system palette entry */ + for (i = 0; i < uiSystemPaletteEntries; ++i) + { + pixel = i; + + /* Extract the color values for current palette entry */ + nRed = ppeColors[i].peRed << 8; + nGreen = ppeColors[i].peGreen << 8; + nBlue = ppeColors[i].peBlue << 8; +#if CYGDEBUG + ErrorF ("winGetPaletteDD - Allocating a color: %d; " + "%d %d %d\n", + pixel, nRed, nGreen, nBlue); +#endif + if (AllocColor (pcmap, + &nRed, + &nGreen, + &nBlue, + &pixel, + 0) != Success) + { + ErrorF ("winGetPaletteDD - AllocColor () failed, pixel %d\n", + i); + free (ppeColors); + ppeColors = NULL; + return FALSE; + } + + pcmap->red[i].co.local.red = nRed; + pcmap->red[i].co.local.green = nGreen; + pcmap->red[i].co.local.blue = nBlue; + } + + /* System is using a colormap */ + /* Set the black and white pixel indices */ + pScreen->whitePixel = uiSystemPaletteEntries - 1; + pScreen->blackPixel = 0; + + /* Free colormap */ + if (ppeColors != NULL) + { + free (ppeColors); + ppeColors = NULL; + } + + /* Free the DC */ + if (hdc != NULL) + { + ReleaseDC (NULL, hdc); + hdc = NULL; + } + + return TRUE; +} + + +/* + * Install the standard fb colormap, or the GDI colormap, + * depending on the current screen depth. + */ + +Bool +winCreateDefColormap (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + unsigned short zero = 0, ones = 0xFFFF; + VisualPtr pVisual = pScreenPriv->pRootVisual; + ColormapPtr pcmap = NULL; + Pixel wp, bp; + +#if CYGDEBUG + ErrorF ("winCreateDefColormap\n"); +#endif + + /* Use standard fb colormaps for non palettized color modes */ + if (pScreenInfo->dwBPP > 8) + { + ErrorF ("winCreateDefColormap - Deferring to " \ + "fbCreateDefColormap ()\n"); + return fbCreateDefColormap (pScreen); + } + + /* + * AllocAll for non-Dynamic visual classes, + * AllocNone for Dynamic visual classes. + */ + + /* + * Dynamic visual classes allow the colors of the color map + * to be changed by clients. + */ + +#if CYGDEBUG + ErrorF ("winCreateDefColormap - defColormap: %d\n", + pScreen->defColormap); +#endif + + /* Allocate an X colormap, owned by client 0 */ + if (CreateColormap (pScreen->defColormap, + pScreen, + pVisual, + &pcmap, + (pVisual->class & DynamicClass) ? AllocNone : AllocAll, + 0) != Success) + { + ErrorF ("winCreateDefColormap - CreateColormap failed\n"); + return FALSE; + } + if (pcmap == NULL) + { + ErrorF ("winCreateDefColormap - Colormap could not be created\n"); + return FALSE; + } + +#if CYGDEBUG + ErrorF ("winCreateDefColormap - Created a colormap\n"); +#endif + + /* Branch on the visual class */ + if (!(pVisual->class & DynamicClass)) + { + /* Branch on engine type */ + if (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI) + { + /* Load the colors being used by the Shadow DIB */ + if (!winGetPaletteDIB (pScreen, pcmap)) + { + ErrorF ("winCreateDefColormap - Couldn't get DIB colors\n"); + return FALSE; + } + } + else + { + /* Load the colors from the default system palette */ + if (!winGetPaletteDD (pScreen, pcmap)) + { + ErrorF ("winCreateDefColormap - Couldn't get colors " + "for DD\n"); + return FALSE; + } + } + } + else + { + wp = pScreen->whitePixel; + bp = pScreen->blackPixel; + + /* Allocate a black and white pixel */ + if ((AllocColor (pcmap, &ones, &ones, &ones, &wp, 0) != + Success) + || + (AllocColor (pcmap, &zero, &zero, &zero, &bp, 0) != + Success)) + { + ErrorF ("winCreateDefColormap - Couldn't allocate bp or wp\n"); + return FALSE; + } + + pScreen->whitePixel = wp; + pScreen->blackPixel = bp; + +#if 0 + /* Have to reserve first 10 and last ten pixels in DirectDraw windowed */ + if (pScreenInfo->dwEngine != WIN_SERVER_SHADOW_GDI) + { + int k; + Pixel p; + + for (k = 1; k < 10; ++k) + { + p = k; + if (AllocColor (pcmap, &ones, &ones, &ones, &p, 0) != Success) + FatalError ("Foo!\n"); + } + + for (k = 245; k < 255; ++k) + { + p = k; + if (AllocColor (pcmap, &zero, &zero, &zero, &p, 0) != Success) + FatalError ("Baz!\n"); + } + } +#endif + } + + /* Install the created colormap */ + (*pScreen->InstallColormap)(pcmap); + +#if CYGDEBUG + ErrorF ("winCreateDefColormap - Returning\n"); +#endif + + return TRUE; +} diff --git a/hw/xwin/winconfig.c b/hw/xwin/winconfig.c new file mode 100644 index 000000000..bc336527c --- /dev/null +++ b/hw/xwin/winconfig.c @@ -0,0 +1,949 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Alexander Gottwald + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winconfig.c,v 1.1 2002/10/17 08:18:22 alanh Exp $ */ + +#include "win.h" +#include "winconfig.h" +#include "winmsg.h" +#include "globals.h" + +#ifdef XKB +#define XKB_IN_SERVER +#include "XKBsrv.h" +#endif + +#ifndef CONFIGPATH +#define CONFIGPATH "%A," "%R," \ + "/etc/X11/%R," "%P/etc/X11/%R," \ + "%E," "%F," \ + "/etc/X11/%F," "%P/etc/X11/%F," \ + "%D/%X," \ + "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \ + "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \ + "%P/etc/X11/%X," \ + "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \ + "%P/lib/X11/%X" +#endif + +XF86ConfigPtr g_xf86configptr = NULL; +WinCmdlineRec g_cmdline = { + NULL, /* configFile */ + NULL, /* fontPath */ + NULL, /* rgbPath */ + NULL, /* keyboard */ +#ifdef XKB + FALSE, /* noXkbExtension */ + NULL, /* xkbMap */ +#endif + NULL, /* screenname */ + NULL, /* mousename */ + FALSE, /* emulate3Buttons */ + 0 /* emulate3Timeout */ +}; + +winInfoRec g_winInfo = { + { /* keyboard */ + 0, /* leds */ + 500, /* delay */ + 30 /* rate */ +#ifdef XKB + } + , + { /* xkb */ + FALSE, /* disable */ + NULL, /* rules */ + NULL, /* model */ + NULL, /* layout */ + NULL, /* variant */ + NULL, /* options */ + NULL, /* initialMap */ + NULL, /* keymap */ + NULL, /* types */ + NULL, /* compat */ + NULL, /* keycodes */ + NULL, /* symbols */ + NULL /* geometry */ +#endif + } + , + { + FALSE, + 50} +}; + +serverLayoutRec g_winConfigLayout; + +static Bool ParseOptionValue (int scrnIndex, pointer options, + OptionInfoPtr p); +static Bool configLayout (serverLayoutPtr, XF86ConfLayoutPtr, char *); +static Bool configImpliedLayout (serverLayoutPtr, XF86ConfScreenPtr); +static Bool GetBoolValue (OptionInfoPtr p, const char *s); + +#define NULL_IF_EMPTY(x) (winNameCompare(x,"")?x:NULL) + + +Bool +winReadConfigfile () +{ + Bool retval = TRUE; + const char *filename; + + MessageType from = X_DEFAULT; + char *xf86ConfigFile = NULL; + + if (g_cmdline.configFile) + { + from = X_CMDLINE; + xf86ConfigFile = g_cmdline.configFile; + } + + /* Parse config file into data structure */ + + filename = xf86openConfigFile (CONFIGPATH, xf86ConfigFile, PROJECTROOT); + if (filename) + { + winMsg (from, "Using config file: \"%s\"\n", filename); + } + else + { + winMsg (X_ERROR, "Unable to locate/open config file"); + if (xf86ConfigFile) + ErrorF (": \"%s\"", xf86ConfigFile); + ErrorF ("\n"); + return FALSE; + } + if ((g_xf86configptr = xf86readConfigFile ()) == NULL) + { + winMsg (X_ERROR, "Problem parsing the config file\n"); + return FALSE; + } + xf86closeConfigFile (); + + winMsg (X_NONE, "Markers: "); + winMsg (X_PROBED, "probed, "); + winMsg (X_CONFIG, "from config file, "); + winMsg (X_DEFAULT, "default setting,\n "); + winMsg (X_CMDLINE, "from command line, "); + winMsg (X_NOTICE, "notice, "); + winMsg (X_INFO, "informational,\n "); + winMsg (X_WARNING, "warning, "); + winMsg (X_ERROR, "error, "); + winMsg (X_UNKNOWN, "unknown.\n"); + + /* set options from data structure */ + + if (g_xf86configptr->conf_layout_lst == NULL || g_cmdline.screenname != NULL) + { + if (g_cmdline.screenname == NULL) + { + winMsg (X_WARNING, + "No Layout section. Using the first Screen section.\n"); + } + if (!configImpliedLayout (&g_winConfigLayout, + g_xf86configptr->conf_screen_lst)) + { + winMsg (X_ERROR, "Unable to determine the screen layout\n"); + return FALSE; + } + } + else + { + /* Check if layout is given in the config file */ + if (g_xf86configptr->conf_flags != NULL) + { + char *dfltlayout = NULL; + pointer optlist = g_xf86configptr->conf_flags->flg_option_lst; + + if (optlist && winFindOption (optlist, "defaultserverlayout")) + dfltlayout = + winSetStrOption (optlist, "defaultserverlayout", NULL); + + if (!configLayout (&g_winConfigLayout, + g_xf86configptr->conf_layout_lst, + dfltlayout)) + { + winMsg (X_ERROR, "Unable to determine the screen layout\n"); + return FALSE; + } + } + else + { + if (!configLayout (&g_winConfigLayout, + g_xf86configptr->conf_layout_lst, + NULL)) + { + winMsg (X_ERROR, "Unable to determin the screen layout\n"); + return FALSE; + } + } + } + + /* setup special config files */ + winConfigFiles (); + return retval; +} + + +/* Set the keyboard configuration */ + +Bool +winConfigKeyboard (DeviceIntPtr pDevice) +{ + XF86ConfInputPtr kbd = NULL; + XF86ConfInputPtr input_list = NULL; + MessageType from = X_DEFAULT; + MessageType kbdfrom = X_CONFIG; + + /* Setup defaults */ +#ifdef XKB + g_winInfo.xkb.disable = FALSE; +# ifdef PC98 /* japanese */ /* not implemented */ + g_winInfo.xkb.rules = "xfree98"; + g_winInfo.xkb.model = "pc98"; + g_winInfo.xkb.layout = "nex/jp"; + g_winInfo.xkb.variant = NULL; + g_winInfo.xkb.options = NULL; +# else + g_winInfo.xkb.rules = "xfree86"; + g_winInfo.xkb.model = "pc101"; + g_winInfo.xkb.layout = "us"; + g_winInfo.xkb.variant = NULL; + g_winInfo.xkb.options = NULL; +# endif /* PC98 */ + g_winInfo.xkb.initialMap = NULL; + g_winInfo.xkb.keymap = NULL; + g_winInfo.xkb.types = NULL; + g_winInfo.xkb.compat = NULL; + g_winInfo.xkb.keycodes = NULL; + g_winInfo.xkb.symbols = NULL; + g_winInfo.xkb.geometry = NULL; +#endif /* XKB */ + + /* parse the configuration */ + + if (g_cmdline.keyboard) + kbdfrom = X_CMDLINE; + + /* + * Until the layout code is finished, I search for the keyboard + * device and configure the server with it. + */ + + if (g_xf86configptr != NULL) + input_list = g_xf86configptr->conf_input_lst; + + while (input_list != NULL) + { + if (winNameCompare (input_list->inp_driver, "keyboard") == 0) + { + /* Check if device name matches requested name */ + if (g_cmdline.keyboard && winNameCompare (input_list->inp_identifier, + g_cmdline.keyboard)) + continue; + kbd = input_list; + } + input_list = input_list->list.next; + } + + if (kbd != NULL) + { + if (kbd->inp_identifier) + winMsg (kbdfrom, "Using keyboard \"%s\" as primary keyboard\n", + kbd->inp_identifier); + +#ifdef XKB + from = X_DEFAULT; + if (g_cmdline.noXkbExtension) + { + from = X_CMDLINE; + g_winInfo.xkb.disable = TRUE; + } + else if (kbd->inp_option_lst) + { + int b = winSetBoolOption (kbd->inp_option_lst, "XkbDisable", FALSE); + if (b) + { + from = X_CONFIG; + g_winInfo.xkb.disable = TRUE; + } + } + if (g_winInfo.xkb.disable) + { + winMsg (from, "XkbExtension disabled\n"); + } + else + { + char *s; + + if ((s = winSetStrOption (kbd->inp_option_lst, "XkbRules", NULL))) + { + g_winInfo.xkb.rules = NULL_IF_EMPTY (s); + winMsg (X_CONFIG, "XKB: rules: \"%s\"\n", s); + } + + if ((s = winSetStrOption (kbd->inp_option_lst, "XkbModel", NULL))) + { + g_winInfo.xkb.model = NULL_IF_EMPTY (s); + winMsg (X_CONFIG, "XKB: model: \"%s\"\n", s); + } + + if ((s = winSetStrOption (kbd->inp_option_lst, "XkbLayout", NULL))) + { + g_winInfo.xkb.layout = NULL_IF_EMPTY (s); + winMsg (X_CONFIG, "XKB: layout: \"%s\"\n", s); + } + + if ((s = winSetStrOption (kbd->inp_option_lst, "XkbVariant", NULL))) + { + g_winInfo.xkb.variant = NULL_IF_EMPTY (s); + winMsg (X_CONFIG, "XKB: variant: \"%s\"\n", s); + } + + if ((s = winSetStrOption (kbd->inp_option_lst, "XkbOptions", NULL))) + { + g_winInfo.xkb.options = NULL_IF_EMPTY (s); + winMsg (X_CONFIG, "XKB: options: \"%s\"\n", s); + } + + from = X_CMDLINE; + if (!XkbInitialMap) + { + s = + winSetStrOption (kbd->inp_option_lst, "XkbInitialMap", NULL); + if (s) + { + XkbInitialMap = NULL_IF_EMPTY (s); + from = X_CONFIG; + } + } + + if ((s = winSetStrOption (kbd->inp_option_lst, "XkbKeymap", NULL))) + { + g_winInfo.xkb.keymap = NULL_IF_EMPTY (s); + winMsg (X_CONFIG, "XKB: keymap: \"%s\" " + " (overrides other XKB settings)\n", s); + } + + if ((s = winSetStrOption (kbd->inp_option_lst, "XkbCompat", NULL))) + { + g_winInfo.xkb.compat = NULL_IF_EMPTY (s); + winMsg (X_CONFIG, "XKB: compat: \"%s\"\n", s); + } + + if ((s = winSetStrOption (kbd->inp_option_lst, "XkbTypes", NULL))) + { + g_winInfo.xkb.types = NULL_IF_EMPTY (s); + winMsg (X_CONFIG, "XKB: types: \"%s\"\n", s); + } + + if ( + (s = + winSetStrOption (kbd->inp_option_lst, "XkbKeycodes", NULL))) + { + g_winInfo.xkb.keycodes = NULL_IF_EMPTY (s); + winMsg (X_CONFIG, "XKB: keycodes: \"%s\"\n", s); + } + + if ( + (s = + winSetStrOption (kbd->inp_option_lst, "XkbGeometry", NULL))) + { + g_winInfo.xkb.geometry = NULL_IF_EMPTY (s); + winMsg (X_CONFIG, "XKB: geometry: \"%s\"\n", s); + } + + if ((s = winSetStrOption (kbd->inp_option_lst, "XkbSymbols", NULL))) + { + g_winInfo.xkb.symbols = NULL_IF_EMPTY (s); + winMsg (X_CONFIG, "XKB: symbols: \"%s\"\n", s); + } + } +#endif + } + else + { + winMsg (X_ERROR, "No primary keyboard configured\n"); + winMsg (X_DEFAULT, "Using compiletime defaults for keyboard\n"); + } + + return TRUE; +} + + +Bool +winConfigMouse (DeviceIntPtr pDevice) +{ + MessageType mousefrom = X_CONFIG; + XF86ConfInputPtr mouse = NULL; + XF86ConfInputPtr input_list = NULL; + + if (g_cmdline.mouse) + mousefrom = X_CMDLINE; + + if (g_xf86configptr != NULL) + input_list = g_xf86configptr->conf_input_lst; + + while (input_list != NULL) + { + if (winNameCompare (input_list->inp_driver, "mouse") == 0) + { + /* Check if device name matches requested name */ + if (g_cmdline.mouse && winNameCompare (input_list->inp_identifier, + g_cmdline.mouse)) + continue; + mouse = input_list; + } + input_list = input_list->list.next; + } + + if (mouse != NULL) + { + if (mouse->inp_identifier) + winMsg (mousefrom, "Using pointer \"%s\" as primary pointer\n", + mouse->inp_identifier); + + g_winInfo.pointer.emulate3Buttons = + winSetBoolOption (mouse->inp_option_lst, "Emulate3Buttons", FALSE); + if (g_cmdline.emulate3buttons) + g_winInfo.pointer.emulate3Buttons = g_cmdline.emulate3buttons; + + g_winInfo.pointer.emulate3Timeout = + winSetIntOption (mouse->inp_option_lst, "Emulate3Timeout", 50); + if (g_cmdline.emulate3timeout) + g_winInfo.pointer.emulate3Timeout = g_cmdline.emulate3timeout; + } + else + { + winMsg (X_ERROR, "No primary pointer configured\n"); + winMsg (X_DEFAULT, "Using compiletime defaults for pointer\n"); + } + + return TRUE; +} + + +Bool +winConfigFiles () +{ + MessageType from; + XF86ConfFilesPtr filesptr = NULL; + + /* set some shortcuts */ + if (g_xf86configptr != NULL) + { + filesptr = g_xf86configptr->conf_files; + } + + + /* Fontpath */ + from = X_DEFAULT; + + if (g_cmdline.fontPath) + { + from = X_CMDLINE; + defaultFontPath = g_cmdline.fontPath; + } + else if (filesptr != NULL && filesptr->file_fontpath) + { + from = X_CONFIG; + defaultFontPath = xstrdup (filesptr->file_fontpath); + } + winMsg (from, "FontPath set to \"%s\"\n", defaultFontPath); + + /* RGBPath */ + from = X_DEFAULT; + if (g_cmdline.rgbPath) + { + from = X_CMDLINE; + rgbPath = g_cmdline.rgbPath; + } + else if (filesptr != NULL && filesptr->file_rgbpath) + { + from = X_CONFIG; + rgbPath = xstrdup (filesptr->file_rgbpath); + } + winMsg (from, "RgbPath set to \"%s\"\n", rgbPath); + + return TRUE; +} + + +Bool +winConfigOptions () +{ + return TRUE; +} + + +Bool +winConfigScreens () +{ + return TRUE; +} + + +char * +winSetStrOption (pointer optlist, const char *name, char *deflt) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_STRING; + if (ParseOptionValue (-1, optlist, &o)) + deflt = o.value.str; + if (deflt) + return xstrdup (deflt); + else + return NULL; +} + + +int +winSetBoolOption (pointer optlist, const char *name, int deflt) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_BOOLEAN; + if (ParseOptionValue (-1, optlist, &o)) + deflt = o.value.bool; + return deflt; +} + + +int +winSetIntOption (pointer optlist, const char *name, int deflt) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_INTEGER; + if (ParseOptionValue (-1, optlist, &o)) + deflt = o.value.num; + return deflt; +} + + +double +winSetRealOption (pointer optlist, const char *name, double deflt) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_REAL; + if (ParseOptionValue (-1, optlist, &o)) + deflt = o.value.realnum; + return deflt; +} + + +/* + * Compare two strings for equality. This is caseinsensitive and + * The characters '_', ' ' (space) and '\t' (tab) are treated as + * not existing. + */ + +int +winNameCompare (const char *s1, const char *s2) +{ + char c1, c2; + + if (!s1 || *s1 == 0) + { + if (!s2 || *s2 == 0) + return 0; + else + return 1; + } + + while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') + s1++; + while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') + s2++; + + c1 = (isupper (*s1) ? tolower (*s1) : *s1); + c2 = (isupper (*s2) ? tolower (*s2) : *s2); + + while (c1 == c2) + { + if (c1 == 0) + return 0; + s1++; + s2++; + + while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') + s1++; + while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') + s2++; + + c1 = (isupper (*s1) ? tolower (*s1) : *s1); + c2 = (isupper (*s2) ? tolower (*s2) : *s2); + } + return (c1 - c2); +} + + +/* + * Find the named option in the list. + * @return the pointer to the option record, or NULL if not found. + */ + +XF86OptionPtr +winFindOption (XF86OptionPtr list, const char *name) +{ + while (list) + { + if (winNameCompare (list->opt_name, name) == 0) + return list; + list = list->list.next; + } + return NULL; +} + + +/* + * Find the Value of an named option. + * @return The option value or NULL if not found. + */ + +char * +winFindOptionValue (XF86OptionPtr list, const char *name) +{ + list = winFindOption (list, name); + if (list) + { + if (list->opt_val) + return (list->opt_val); + else + return ""; + } + return (NULL); +} + + +/* + * Parse the option. + */ + +static Bool +ParseOptionValue (int scrnIndex, pointer options, OptionInfoPtr p) +{ + char *s, *end; + + if ((s = winFindOptionValue (options, p->name)) != NULL) + { + switch (p->type) + { + case OPTV_INTEGER: + if (*s == '\0') + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires an integer value\n", + p->name); + p->found = FALSE; + } + else + { + p->value.num = strtoul (s, &end, 0); + if (*end == '\0') + { + p->found = TRUE; + } + else + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires an integer value\n", + p->name); + p->found = FALSE; + } + } + break; + case OPTV_STRING: + if (*s == '\0') + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires an string value\n", p->name); + p->found = FALSE; + } + else + { + p->value.str = s; + p->found = TRUE; + } + break; + case OPTV_ANYSTR: + p->value.str = s; + p->found = TRUE; + break; + case OPTV_REAL: + if (*s == '\0') + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires a floating point value\n", + p->name); + p->found = FALSE; + } + else + { + p->value.realnum = strtod (s, &end); + if (*end == '\0') + { + p->found = TRUE; + } + else + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires a floating point value\n", + p->name); + p->found = FALSE; + } + } + break; + case OPTV_BOOLEAN: + if (GetBoolValue (p, s)) + { + p->found = TRUE; + } + else + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires a boolean value\n", p->name); + p->found = FALSE; + } + break; + case OPTV_FREQ: + if (*s == '\0') + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires a frequency value\n", + p->name); + p->found = FALSE; + } + else + { + double freq = strtod (s, &end); + int units = 0; + + if (end != s) + { + p->found = TRUE; + if (!winNameCompare (end, "Hz")) + units = 1; + else if (!winNameCompare (end, "kHz") || + !winNameCompare (end, "k")) + units = 1000; + else if (!winNameCompare (end, "MHz") || + !winNameCompare (end, "M")) + units = 1000000; + else + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires a frequency value\n", + p->name); + p->found = FALSE; + } + if (p->found) + freq *= (double) units; + } + else + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires a frequency value\n", + p->name); + p->found = FALSE; + } + if (p->found) + { + p->value.freq.freq = freq; + p->value.freq.units = units; + } + } + break; + case OPTV_NONE: + /* Should never get here */ + p->found = FALSE; + break; + } + if (p->found) + { + winDrvMsgVerb (scrnIndex, X_CONFIG, 2, "Option \"%s\"", p->name); + if (!(p->type == OPTV_BOOLEAN && *s == 0)) + { + winErrorFVerb (2, " \"%s\"", s); + } + winErrorFVerb (2, "\n"); + } + } + else if (p->type == OPTV_BOOLEAN) + { + /* Look for matches with options with or without a "No" prefix. */ + char *n, *newn; + OptionInfoRec opt; + + n = winNormalizeName (p->name); + if (!n) + { + p->found = FALSE; + return FALSE; + } + if (strncmp (n, "no", 2) == 0) + { + newn = n + 2; + } + else + { + free (n); + n = malloc (strlen (p->name) + 2 + 1); + if (!n) + { + p->found = FALSE; + return FALSE; + } + strcpy (n, "No"); + strcat (n, p->name); + newn = n; + } + if ((s = winFindOptionValue (options, newn)) != NULL) + { + if (GetBoolValue (&opt, s)) + { + p->value.bool = !opt.value.bool; + p->found = TRUE; + } + else + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires a boolean value\n", newn); + p->found = FALSE; + } + } + else + { + p->found = FALSE; + } + if (p->found) + { + winDrvMsgVerb (scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn); + if (*s != 0) + { + winErrorFVerb (2, " \"%s\"", s); + } + winErrorFVerb (2, "\n"); + } + free (n); + } + else + { + p->found = FALSE; + } + return p->found; +} + + +static Bool +configLayout (serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout, + char *default_layout) +{ +#if 0 +#pragma warn UNIMPLEMENTED +#endif + return TRUE; +} + + +static Bool +configImpliedLayout (serverLayoutPtr servlayoutp, + XF86ConfScreenPtr conf_screen) +{ +#if 0 +#pragma warn UNIMPLEMENTED +#endif + return TRUE; +} + + +static Bool +GetBoolValue (OptionInfoPtr p, const char *s) +{ + if (*s == 0) + { + p->value.bool = TRUE; + } + else + { + if (winNameCompare (s, "1") == 0) + p->value.bool = TRUE; + else if (winNameCompare (s, "on") == 0) + p->value.bool = TRUE; + else if (winNameCompare (s, "true") == 0) + p->value.bool = TRUE; + else if (winNameCompare (s, "yes") == 0) + p->value.bool = TRUE; + else if (winNameCompare (s, "0") == 0) + p->value.bool = FALSE; + else if (winNameCompare (s, "off") == 0) + p->value.bool = FALSE; + else if (winNameCompare (s, "false") == 0) + p->value.bool = FALSE; + else if (winNameCompare (s, "no") == 0) + p->value.bool = FALSE; + } + return TRUE; +} + + +char * +winNormalizeName (const char *s) +{ + char *ret, *q; + const char *p; + + if (s == NULL) + return NULL; + + ret = malloc (strlen (s) + 1); + for (p = s, q = ret; *p != 0; p++) + { + switch (*p) + { + case '_': + case ' ': + case '\t': + continue; + default: + if (isupper (*p)) + *q++ = tolower (*p); + else + *q++ = *p; + } + } + *q = '\0'; + return ret; +} diff --git a/hw/xwin/winconfig.h b/hw/xwin/winconfig.h new file mode 100644 index 000000000..d3099b373 --- /dev/null +++ b/hw/xwin/winconfig.h @@ -0,0 +1,332 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Alexander Gottwald + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winconfig.h,v 1.1 2002/10/17 08:18:22 alanh Exp $ */ +#ifndef __WIN_CONFIG_H__ +#define __WIN_CONFIG_H__ + +#include "win.h" +#include "../xfree86/parser/xf86Parser.h" + + +/* These are taken from hw/xfree86/common/xf86str.h */ + +typedef struct +{ + CARD32 red, green, blue; +} +rgb; + + +typedef struct +{ + float red, green, blue; +} +Gamma; + + +typedef struct +{ + char *identifier; + char *vendor; + char *board; + char *chipset; + char *ramdac; + char *driver; + struct _confscreenrec *myScreenSection; + Bool claimed; + Bool active; + Bool inUse; + int videoRam; + int textClockFreq; + pointer options; + int screen; /* For multi-CRTC cards */ +} +GDevRec, *GDevPtr; + + +typedef struct +{ + char *identifier; + char *driver; + pointer commonOptions; + pointer extraOptions; +} +IDevRec, *IDevPtr; + + +typedef struct +{ + int frameX0; + int frameY0; + int virtualX; + int virtualY; + int depth; + int fbbpp; + rgb weight; + rgb blackColour; + rgb whiteColour; + int defaultVisual; + char **modes; + pointer options; +} +DispRec, *DispPtr; + + +typedef struct _confxvportrec +{ + char *identifier; + pointer options; +} +confXvPortRec, *confXvPortPtr; + + +typedef struct _confxvadaptrec +{ + char *identifier; + int numports; + confXvPortPtr ports; + pointer options; +} +confXvAdaptorRec, *confXvAdaptorPtr; + + +typedef struct _confscreenrec +{ + char *id; + int screennum; + int defaultdepth; + int defaultbpp; + int defaultfbbpp; + GDevPtr device; + int numdisplays; + DispPtr displays; + int numxvadaptors; + confXvAdaptorPtr xvadaptors; + pointer options; +} +confScreenRec, *confScreenPtr; + + +typedef enum +{ + PosObsolete = -1, + PosAbsolute = 0, + PosRightOf, + PosLeftOf, + PosAbove, + PosBelow, + PosRelative +} +PositionType; + + +typedef struct _screenlayoutrec +{ + confScreenPtr screen; + char *topname; + confScreenPtr top; + char *bottomname; + confScreenPtr bottom; + char *leftname; + confScreenPtr left; + char *rightname; + confScreenPtr right; + PositionType where; + int x; + int y; + char *refname; + confScreenPtr refscreen; +} +screenLayoutRec, *screenLayoutPtr; + + +typedef struct _serverlayoutrec +{ + char *id; + screenLayoutPtr screens; + GDevPtr inactives; + IDevPtr inputs; + pointer options; +} +serverLayoutRec, *serverLayoutPtr; + + +/* + * winconfig.c + */ + +typedef struct +{ + /* Files */ + char *configFile; + char *fontPath; + char *rgbPath; + /* input devices - keyboard */ + char *keyboard; +#ifdef XKB + Bool noXkbExtension; + char *xkbMap; +#endif + /* layout */ + char *screenname; + /* mouse settings */ + char *mouse; + Bool emulate3buttons; + long emulate3timeout; +} +WinCmdlineRec, *WinCmdlinePtr; + + +extern WinCmdlineRec g_cmdline; + +extern XF86ConfigPtr g_xf86configptr; +extern serverLayoutRec g_winConfigLayout; + + +/* + * Function prototypes + */ + +Bool winReadConfigfile (void); +Bool winConfigFiles (void); +Bool winConfigOptions (void); +Bool winConfigScreens (void); +Bool winConfigKeyboard (DeviceIntPtr pDevice); +Bool winConfigMouse (DeviceIntPtr pDevice); + + +typedef struct +{ + double freq; + int units; +} +OptFrequency; + + +typedef union +{ + unsigned long num; + char *str; + double realnum; + Bool bool; + OptFrequency freq; +} +ValueUnion; + + +typedef enum +{ + OPTV_NONE = 0, + OPTV_INTEGER, + OPTV_STRING, /* a non-empty string */ + OPTV_ANYSTR, /* Any string, including an empty one */ + OPTV_REAL, + OPTV_BOOLEAN, + OPTV_FREQ +} +OptionValueType; + + +typedef enum +{ + OPTUNITS_HZ = 1, + OPTUNITS_KHZ, + OPTUNITS_MHZ +} +OptFreqUnits; + + +typedef struct +{ + int token; + const char *name; + OptionValueType type; + ValueUnion value; + Bool found; +} +OptionInfoRec, *OptionInfoPtr; + + +/* + * Function prototypes + */ + +char *winSetStrOption (pointer optlist, const char *name, char *deflt); +int winSetBoolOption (pointer optlist, const char *name, int deflt); +int winSetIntOption (pointer optlist, const char *name, int deflt); +double winSetRealOption (pointer optlist, const char *name, double deflt); + +XF86OptionPtr winFindOption (XF86OptionPtr list, const char *name); +char *winFindOptionValue (XF86OptionPtr list, const char *name); +int winNameCompare (const char *s1, const char *s2); +char *winNormalizeName (const char *s); + + +typedef struct +{ + struct + { + long leds; + long delay; + long rate; + } + keyboard; +#ifdef XKB + struct + { + Bool disable; + char *rules; + char *model; + char *layout; + char *variant; + char *options; + char *initialMap; + char *keymap; + char *types; + char *compat; + char *keycodes; + char *symbols; + char *geometry; + } + xkb; +#endif + struct + { + Bool emulate3Buttons; + long emulate3Timeout; + } + pointer; +} +winInfoRec, *winInfoPtr; + + +extern winInfoRec g_winInfo; + +#endif diff --git a/hw/xwin/wincreatewnd.c b/hw/xwin/wincreatewnd.c new file mode 100644 index 000000000..3c725f248 --- /dev/null +++ b/hw/xwin/wincreatewnd.c @@ -0,0 +1,541 @@ +/* + *Copyright (C) 1994-2001 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/wincreatewnd.c,v 1.5 2003/02/12 15:01:38 alanh Exp $ */ + +#include "win.h" +#include "shellapi.h" + + +/* + * Local function prototypes + */ + +static Bool +winGetWorkArea (RECT *prcWorkArea, winScreenInfo *pScreenInfo); + +static Bool +winAdjustForAutoHide (RECT *prcWorkArea); + + +/* + * Create a full screen window + */ + +Bool +winCreateBoundingWindowFullScreen (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + int iWidth = pScreenInfo->dwWidth; + int iHeight = pScreenInfo->dwHeight; + HWND *phwnd = &pScreenPriv->hwndScreen; + WNDCLASS wc; + +#if CYGDEBUG + ErrorF ("winCreateBoundingWindowFullScreen\n"); +#endif + + /* Setup our window class */ + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = winWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = g_hInstance; + wc.hIcon = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN)); + wc.hCursor = 0; + wc.hbrBackground = 0; + wc.lpszMenuName = NULL; + wc.lpszClassName = WINDOW_CLASS; + RegisterClass (&wc); + + /* Create the window */ + *phwnd = CreateWindowExA (WS_EX_TOPMOST, /* Extended styles */ + WINDOW_CLASS, /* Class name */ + WINDOW_TITLE, /* Window name */ + WS_POPUP, + 0, /* Horizontal position */ + 0, /* Vertical position */ + iWidth, /* Right edge */ + iHeight, /* Bottom edge */ + (HWND) NULL, /* No parent or owner window */ + (HMENU) NULL, /* No menu */ + GetModuleHandle (NULL),/* Instance handle */ + pScreenPriv); /* ScreenPrivates */ + + /* Branch on the server engine */ + switch (pScreenInfo->dwEngine) + { + case WIN_SERVER_SHADOW_GDI: + /* Show the window */ + ShowWindow (*phwnd, SW_SHOWMAXIMIZED); + break; + + default: + /* Hide the window */ + ShowWindow (*phwnd, SW_SHOWNORMAL); + break; + } + + /* Send first paint message */ + UpdateWindow (*phwnd); + + /* Attempt to bring our window to the top of the display */ + BringWindowToTop (*phwnd); + + return TRUE; +} + + +/* + * Create our primary Windows display window + */ + +Bool +winCreateBoundingWindowWindowed (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + int iWidth = pScreenInfo->dwUserWidth; + int iHeight = pScreenInfo->dwUserHeight; + HWND *phwnd = &pScreenPriv->hwndScreen; + WNDCLASS wc; + RECT rcClient, rcWorkArea; + DWORD dwWindowStyle; + + ErrorF ("winCreateBoundingWindowWindowed - User w: %d h: %d\n", + pScreenInfo->dwUserWidth, pScreenInfo->dwUserHeight); + ErrorF ("winCreateBoundingWindowWindowed - Current w: %d h: %d\n", + pScreenInfo->dwWidth, pScreenInfo->dwHeight); + + /* Set the common window style flags */ + dwWindowStyle = WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX; + + /* Decorated or undecorated window */ + if (pScreenInfo->fDecoration + && !pScreenInfo->fRootless + && !pScreenInfo->fMultiWindow) + { + dwWindowStyle |= WS_CAPTION; + if (pScreenInfo->fScrollbars) + dwWindowStyle |= WS_THICKFRAME | WS_MAXIMIZEBOX; + } + else + dwWindowStyle |= WS_POPUP; + + /* Setup our window class */ + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = winWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = g_hInstance; + wc.hIcon = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN)); + wc.hCursor = 0; + wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = WINDOW_CLASS; + RegisterClass (&wc); + + /* Get size of work area */ + winGetWorkArea (&rcWorkArea, pScreenInfo); + + /* Adjust for auto-hide taskbars */ + winAdjustForAutoHide (&rcWorkArea); + + /* Did the user specify a height and width? */ + if (pScreenInfo->fUserGaveHeightAndWidth) + { + /* User gave a desired height and width, try to accomodate */ +#if CYGDEBUG + ErrorF ("winCreateBoundingWindowWindowed - User gave height " + "and width\n"); +#endif + + /* Adjust the window width and height for borders and title bar */ + if (pScreenInfo->fDecoration + && !pScreenInfo->fRootless + && !pScreenInfo->fMultiWindow) + { +#if CYGDEBUG + ErrorF ("winCreateBoundingWindowWindowed - Window has decoration\n"); +#endif + /* Are we using scrollbars? */ + if (pScreenInfo->fScrollbars) + { +#if CYGDEBUG + ErrorF ("winCreateBoundingWindowWindowed - Window has " + "scrollbars\n"); +#endif + + iWidth += 2 * GetSystemMetrics (SM_CXSIZEFRAME); + iHeight += 2 * GetSystemMetrics (SM_CYSIZEFRAME) + + GetSystemMetrics (SM_CYCAPTION); + } + else + { +#if CYGDEBUG + ErrorF ("winCreateBoundingWindowWindowed - Window does not have " + "scrollbars\n"); +#endif + + iWidth += 2 * GetSystemMetrics (SM_CXFIXEDFRAME); + iHeight += 2 * GetSystemMetrics (SM_CYFIXEDFRAME) + + GetSystemMetrics (SM_CYCAPTION); + } + } + else + { + /* + * User gave a width and height but also said no decoration. + * In this case we have to ignore the requested width and height + * and instead use the largest possible window that we can. + */ + if (pScreenInfo->fMultipleMonitors) + { + iWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN); + iHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN); + } + else + { + iWidth = GetSystemMetrics (SM_CXSCREEN); + iHeight = GetSystemMetrics (SM_CYSCREEN); + } + } + } + else + { + /* By default, we are creating a window that is as large as possible */ +#if CYGDEBUG + ErrorF ("winCreateBoundingWindowWindowed - User did not give " + "height and width\n"); +#endif + /* Defaults are wrong if we have multiple monitors */ + if (pScreenInfo->fMultipleMonitors) + { + iWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN); + iHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN); + } + } + + /* Clean up the scrollbars flag, if necessary */ + if ((!pScreenInfo->fDecoration + || pScreenInfo->fRootless + || pScreenInfo->fMultiWindow) + && pScreenInfo->fScrollbars) + { + /* We cannot have scrollbars if we do not have a window border */ + pScreenInfo->fScrollbars = FALSE; + } + + /* Trim window width to fit work area */ + if (iWidth > (rcWorkArea.right - rcWorkArea.left)) + iWidth = rcWorkArea.right - rcWorkArea.left; + + /* Trim window height to fit work area */ + if (iHeight >= (rcWorkArea.bottom - rcWorkArea.top)) + iHeight = rcWorkArea.bottom - rcWorkArea.top; + +#if CYGDEBUG + ErrorF ("winCreateBoundingWindowWindowed - Adjusted width: %d "\ + "height: %d\n", + iWidth, iHeight); +#endif + + /* Create the window */ + *phwnd = CreateWindowExA (0, /* Extended styles */ + WINDOW_CLASS, /* Class name */ + WINDOW_TITLE, /* Window name */ + dwWindowStyle, + rcWorkArea.left, /* Horizontal position */ + rcWorkArea.top, /* Vertical position */ + iWidth, /* Right edge */ + iHeight, /* Bottom edge */ + (HWND) NULL, /* No parent or owner window */ + (HMENU) NULL, /* No menu */ + GetModuleHandle (NULL),/* Instance handle */ + pScreenPriv); /* ScreenPrivates */ + if (*phwnd == NULL) + { + ErrorF ("winCreateBoundingWindowWindowed - CreateWindowEx () failed\n"); + return FALSE; + } + +#if CYGDEBUG + ErrorF ("winCreateBoundingWindowWindowed - CreateWindowEx () returned\n"); +#endif + + /* Get the client area coordinates */ + if (!GetClientRect (*phwnd, &rcClient)) + { + ErrorF ("winCreateBoundingWindowWindowed - GetClientRect () " + "failed\n"); + return FALSE; + } + + ErrorF ("winCreateBoundingWindowWindowed - WindowClient " + "w %ld h %ld r %ld l %ld b %ld t %ld\n", + rcClient.right - rcClient.left, + rcClient.bottom - rcClient.top, + rcClient.right, rcClient.left, + rcClient.bottom, rcClient.top); + + /* We adjust the visual size if the user did not specify it */ + if (!(pScreenInfo->fScrollbars && pScreenInfo->fUserGaveHeightAndWidth)) + { + /* + * User did not give a height and width with scrollbars enabled, + * so we will resize the underlying visual to be as large as + * the initial view port (page size). This way scrollbars will + * not appear until the user shrinks the window, if they ever do. + * + * NOTE: We have to store the viewport size here because + * the user may have an autohide taskbar, which would + * cause the viewport size to be one less in one dimension + * than the viewport size that we calculated by subtracting + * the size of the borders and caption. + */ + pScreenInfo->dwWidth = rcClient.right - rcClient.left; + pScreenInfo->dwHeight = rcClient.bottom - rcClient.top; + } + +#if 0 + /* + * NOTE: For the uninitiated, the page size is the number of pixels + * that we can display in the x or y direction at a time and the + * range is the total number of pixels in the x or y direction that we + * have available to display. In other words, the page size is the + * size of the window area minus the space the caption, borders, and + * scrollbars (if any) occupy, and the range is the size of the + * underlying X visual. Notice that, contrary to what some of the + * MSDN Library arcticles lead you to believe, the windows + * ``client area'' size does not include the scrollbars. In other words, + * the whole client area size that is reported to you is drawable by + * you; you do not have to subtract the size of the scrollbars from + * the client area size, and if you did it would result in the size + * of the scrollbars being double counted. + */ + + /* Setup scrollbar page and range, if scrollbars are enabled */ + if (pScreenInfo->fScrollbars) + { + SCROLLINFO si; + + /* Initialize the scrollbar info structure */ + si.cbSize = sizeof (si); + si.fMask = SIF_RANGE | SIF_PAGE; + si.nMin = 0; + + /* Setup the width range and page size */ + si.nMax = pScreenInfo->dwWidth - 1; + si.nPage = rcClient.right - rcClient.left; + ErrorF ("winCreateBoundingWindowWindowed - HORZ nMax: %d nPage :%d\n", + si.nMax, si.nPage); + SetScrollInfo (*phwnd, SB_HORZ, &si, TRUE); + + /* Setup the height range and page size */ + si.nMax = pScreenInfo->dwHeight - 1; + si.nPage = rcClient.bottom - rcClient.top; + ErrorF ("winCreateBoundingWindowWindowed - VERT nMax: %d nPage :%d\n", + si.nMax, si.nPage); + SetScrollInfo (*phwnd, SB_VERT, &si, TRUE); + } +#endif + + /* Show the window */ + if (pScreenInfo->fMultiWindow) + ShowWindow (*phwnd, SW_SHOWMINNOACTIVE); + else + ShowWindow (*phwnd, SW_SHOWNORMAL); + if (!UpdateWindow (*phwnd)) + { + ErrorF ("winCreateBoundingWindowWindowed - UpdateWindow () failed\n"); + return FALSE; + } + + /* Attempt to bring our window to the top of the display */ + if (!BringWindowToTop (*phwnd)) + { + ErrorF ("winCreateBoundingWindowWindowed - BringWindowToTop () " + "failed\n"); + return FALSE; + } + + /* Paint window background blue */ + if (pScreenInfo->dwEngine == WIN_SERVER_NATIVE_GDI) + winPaintBackground (*phwnd, RGB (0x00, 0x00, 0xFF)); + + ErrorF ("winCreateBoundingWindowWindowed - Returning\n"); + + return TRUE; +} + + +/* + * Find the work area of all attached monitors + */ + +static Bool +winGetWorkArea (RECT *prcWorkArea, winScreenInfo *pScreenInfo) +{ + int iPrimaryWidth, iPrimaryHeight; + int iWidth, iHeight; + int iLeft, iTop; + int iPrimaryNonWorkAreaWidth, iPrimaryNonWorkAreaHeight; + + /* SPI_GETWORKAREA only gets the work area of the primary screen. */ + SystemParametersInfo (SPI_GETWORKAREA, 0, prcWorkArea, 0); + + /* Bail out here if we aren't using multiple monitors */ + if (!pScreenInfo->fMultipleMonitors) + return TRUE; + + ErrorF ("winGetWorkArea - Original WorkArea: %d %d %d %d\n", + prcWorkArea->top, prcWorkArea->left, + prcWorkArea->bottom, prcWorkArea->right); + + /* Get size of full virtual screen */ + iWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN); + iHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN); + + ErrorF ("winGetWorkArea - Virtual screen is %d x %d\n", iWidth, iHeight); + + /* Get origin of full virtual screen */ + iLeft = GetSystemMetrics (SM_XVIRTUALSCREEN); + iTop = GetSystemMetrics (SM_YVIRTUALSCREEN); + + ErrorF ("winGetWorkArea - Virtual screen origin is %d, %d\n", iLeft, iTop); + + /* Get size of primary screen */ + iPrimaryWidth = GetSystemMetrics (SM_CXSCREEN); + iPrimaryHeight = GetSystemMetrics (SM_CYSCREEN); + + ErrorF ("winGetWorkArea - Primary screen is %d x %d\n", + iPrimaryWidth, iPrimaryHeight); + + /* Work out how much of the primary screen we aren't using */ + iPrimaryNonWorkAreaWidth = iPrimaryWidth - (prcWorkArea->right - + prcWorkArea->left); + iPrimaryNonWorkAreaHeight = iPrimaryHeight - (prcWorkArea->bottom + - prcWorkArea->top); + + /* Update the rectangle to include all monitors */ + if (iLeft < 0) + { + prcWorkArea->left = iLeft; + } + if (iTop < 0) + { + prcWorkArea->top = iTop; + } + prcWorkArea->right = prcWorkArea->left + iWidth - + iPrimaryNonWorkAreaWidth; + prcWorkArea->bottom = prcWorkArea->top + iHeight - + iPrimaryNonWorkAreaHeight; + + ErrorF ("winGetWorkArea - Adjusted WorkArea for multiple " + "monitors: %d %d %d %d\n", + prcWorkArea->top, prcWorkArea->left, + prcWorkArea->bottom, prcWorkArea->right); + + return TRUE; +} + + +/* + * Adjust the client area so that any auto-hide toolbars + * will work correctly. + */ + +static Bool +winAdjustForAutoHide (RECT *prcWorkArea) +{ + APPBARDATA abd; + HWND hwndAutoHide; + + ErrorF ("winAdjustForAutoHide - Original WorkArea: %d %d %d %d\n", + prcWorkArea->top, prcWorkArea->left, + prcWorkArea->bottom, prcWorkArea->right); + + /* Find out if the Windows taskbar is set to auto-hide */ + ZeroMemory (&abd, sizeof (abd)); + abd.cbSize = sizeof (abd); + if (SHAppBarMessage (ABM_GETSTATE, &abd) & ABS_AUTOHIDE) + ErrorF ("winAdjustForAutoHide - Taskbar is auto hide\n"); + + /* Look for a TOP auto-hide taskbar */ + abd.uEdge = ABE_TOP; + hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd); + if (hwndAutoHide != NULL) + { + ErrorF ("winAdjustForAutoHide - Found TOP auto-hide taskbar\n"); + prcWorkArea->top += 1; + } + + /* Look for a LEFT auto-hide taskbar */ + abd.uEdge = ABE_LEFT; + hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd); + if (hwndAutoHide != NULL) + { + ErrorF ("winAdjustForAutoHide - Found LEFT auto-hide taskbar\n"); + prcWorkArea->left += 1; + } + + /* Look for a BOTTOM auto-hide taskbar */ + abd.uEdge = ABE_BOTTOM; + hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd); + if (hwndAutoHide != NULL) + { + ErrorF ("winAdjustForAutoHide - Found BOTTOM auto-hide taskbar\n"); + prcWorkArea->bottom -= 1; + } + + /* Look for a RIGHT auto-hide taskbar */ + abd.uEdge = ABE_RIGHT; + hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd); + if (hwndAutoHide != NULL) + { + ErrorF ("winAdjustForAutoHide - Found RIGHT auto-hide taskbar\n"); + prcWorkArea->right -= 1; + } + + ErrorF ("winAdjustForAutoHide - Adjusted WorkArea: %d %d %d %d\n", + prcWorkArea->top, prcWorkArea->left, + prcWorkArea->bottom, prcWorkArea->right); + +#if 0 + /* Obtain the task bar window dimensions */ + abd.hWnd = hwndAutoHide; + hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETTASKBARPOS, &abd); + ErrorF ("hwndAutoHide %08x abd.hWnd %08x %d %d %d %d\n", + hwndAutoHide, abd.hWnd, + abd.rc.top, abd.rc.left, abd.rc.bottom, abd.rc.right); +#endif + + return TRUE; +} diff --git a/hw/xwin/wincursor.c b/hw/xwin/wincursor.c new file mode 100644 index 000000000..cd12bb632 --- /dev/null +++ b/hw/xwin/wincursor.c @@ -0,0 +1,84 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/wincursor.c,v 1.5 2002/07/05 09:19:26 alanh Exp $ */ + +#include "win.h" + +miPointerScreenFuncRec g_winPointerCursorFuncs = +{ + winCursorOffScreen, + winCrossScreen, + winPointerWarpCursor +}; + + +void +winPointerWarpCursor (ScreenPtr pScreen, int x, int y) +{ + winScreenPriv(pScreen); + RECT rcClient; + + /* Only update the Windows cursor position if we are active */ + if (pScreenPriv->hwndScreen == GetForegroundWindow ()) + { + /* Get the client area coordinates */ + GetClientRect (pScreenPriv->hwndScreen, &rcClient); + + /* Translate the client area coords to screen coords */ + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&rcClient, + 2); + + /* + * Update the Windows cursor position so that we don't + * immediately warp back to the current position. + */ + SetCursorPos (rcClient.left + x, rcClient.top + y); + } + + /* Call the mi warp procedure to do the actual warping in X. */ + miPointerWarpCursor (pScreen, x, y); +} + +Bool +winCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y) +{ + return FALSE; +} + +void +winCrossScreen (ScreenPtr pScreen, Bool fEntering) +{ +} + diff --git a/hw/xwin/winengine.c b/hw/xwin/winengine.c new file mode 100644 index 000000000..aff90bdaf --- /dev/null +++ b/hw/xwin/winengine.c @@ -0,0 +1,309 @@ +/* + *Copyright (C) 1994-2001 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winengine.c,v 1.4 2003/02/12 15:01:38 alanh Exp $ */ + +#include "win.h" + + +/* + * Detect engines supported by current Windows version + * DirectDraw version and hardware + */ + +void +winDetectSupportedEngines () +{ + OSVERSIONINFO osvi; + + /* Initialize the engine support flags */ + g_dwEnginesSupported = WIN_SERVER_SHADOW_GDI; + +#if WIN_NATIVE_GDI_SUPPORT + g_dwEnginesSupported |= WIN_SERVER_NATIVE_GDI; +#endif + + /* 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 */ + ErrorF ("winDetectSupportedEngines - Windows NT/2000/XP\n"); + break; + + case VER_PLATFORM_WIN32_WINDOWS: + /* Engine 4 is supported on NT only */ + ErrorF ("winDetectSupportedEngines - Windows 95/98/Me\n"); + break; + } + + /* Do we have DirectDraw? */ + if (g_hmodDirectDraw != NULL) + { + LPDIRECTDRAW lpdd = NULL; + LPDIRECTDRAW4 lpdd4 = NULL; + HRESULT ddrval; + + /* Was the DirectDrawCreate function found? */ + if (g_fpDirectDrawCreate == NULL) + { + /* No DirectDraw support */ + return; + } + + /* DirectDrawCreate exists, try to call it */ + /* Create a DirectDraw object, store the address at lpdd */ + ddrval = (*g_fpDirectDrawCreate) (NULL, + (void**) &lpdd, + NULL); + if (FAILED (ddrval)) + { + /* No DirectDraw support */ + ErrorF ("winDetectSupportedEngines - DirectDraw not installed\n"); + return; + } + else + { + /* We have DirectDraw */ + ErrorF ("winDetectSupportedEngines - DirectDraw installed\n"); + g_dwEnginesSupported |= WIN_SERVER_SHADOW_DD; + + /* Allow PrimaryDD engine if NT */ + if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) + { + g_dwEnginesSupported |= WIN_SERVER_PRIMARY_DD; + ErrorF ("winDetectSupportedEngines - Allowing PrimaryDD\n"); + } + } + + /* Try to query for DirectDraw4 interface */ + ddrval = IDirectDraw_QueryInterface (lpdd, + &IID_IDirectDraw4, + (LPVOID*) &lpdd4); + if (SUCCEEDED (ddrval)) + { + /* We have DirectDraw4 */ + ErrorF ("winDetectSupportedEngines - DirectDraw4 installed\n"); + g_dwEnginesSupported |= WIN_SERVER_SHADOW_DDNL; + } + + /* Cleanup DirectDraw interfaces */ + if (lpdd4 != NULL) + IDirectDraw_Release (lpdd4); + if (lpdd != NULL) + IDirectDraw_Release (lpdd); + } + + ErrorF ("winDetectSupportedEngines - Returning, supported engines %08x\n", + g_dwEnginesSupported); +} + + +/* + * Set the engine type, depending on the engines + * supported for this screen, and whether the user + * suggested an engine type + */ + +Bool +winSetEngine (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HDC hdc; + DWORD dwBPP; + + /* Get a DC */ + hdc = GetDC (NULL); + if (hdc == NULL) + { + ErrorF ("winSetEngine - Couldn't get an HDC\n"); + return FALSE; + } + + /* + * pScreenInfo->dwBPP may be 0 to indicate that the current screen + * depth is to be used. Thus, we must query for the current display + * depth here. + */ + dwBPP = GetDeviceCaps (hdc, BITSPIXEL); + + /* Release the DC */ + ReleaseDC (NULL, hdc); + hdc = NULL; + + /* ShadowGDI is the only engine that supports windowed PseudoColor */ + if (dwBPP == 8 && !pScreenInfo->fFullScreen) + { + ErrorF ("winSetEngine - Windowed && PseudoColor => ShadowGDI\n"); + pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; + + /* Set engine function pointers */ + winSetEngineFunctionsShadowGDI (pScreen); + return TRUE; + } + + /* ShadowGDI is the only engine that supports Multi Window Mode */ + if (pScreenInfo->fMultiWindow) + { + ErrorF ("winSetEngine - Multi Window => ShadowGDI\n"); + pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; + + /* Set engine function pointers */ + winSetEngineFunctionsShadowGDI (pScreen); + return TRUE; + } + + /* If the user's choice is supported, we'll use that */ + if (g_dwEnginesSupported & pScreenInfo->dwEnginePreferred) + { + ErrorF ("winSetEngine - Using user's preference: %d\n", + pScreenInfo->dwEnginePreferred); + pScreenInfo->dwEngine = pScreenInfo->dwEnginePreferred; + + /* Setup engine function pointers */ + switch (pScreenInfo->dwEngine) + { + case WIN_SERVER_SHADOW_GDI: + winSetEngineFunctionsShadowGDI (pScreen); + break; + case WIN_SERVER_SHADOW_DD: + winSetEngineFunctionsShadowDD (pScreen); + break; + case WIN_SERVER_SHADOW_DDNL: + winSetEngineFunctionsShadowDDNL (pScreen); + break; + case WIN_SERVER_PRIMARY_DD: + winSetEngineFunctionsPrimaryDD (pScreen); + break; + case WIN_SERVER_NATIVE_GDI: + winSetEngineFunctionsNativeGDI (pScreen); + break; + default: + FatalError ("winSetEngine - Invalid engine type\n"); + } + return TRUE; + } + + /* ShadowDDNL has good performance, so why not */ + if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DDNL) + { + ErrorF ("winSetEngine - Using Shadow DirectDraw NonLocking\n"); + pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DDNL; + + /* Set engine function pointers */ + winSetEngineFunctionsShadowDDNL (pScreen); + return TRUE; + } + + /* ShadowDD is next in line */ + if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DD) + { + ErrorF ("winSetEngine - Using Shadow DirectDraw\n"); + pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DD; + + /* Set engine function pointers */ + winSetEngineFunctionsShadowDD (pScreen); + return TRUE; + } + + /* ShadowGDI is next in line */ + if (g_dwEnginesSupported & WIN_SERVER_SHADOW_GDI) + { + ErrorF ("winSetEngine - Using Shadow GDI DIB\n"); + pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; + + /* Set engine function pointers */ + winSetEngineFunctionsShadowGDI (pScreen); + return TRUE; + } + + return TRUE; +} + + +/* + * Get procedure addresses for DirectDrawCreate and DirectDrawCreateClipper + */ + +Bool +winGetDDProcAddresses () +{ + Bool fReturn = TRUE; + + /* Load the DirectDraw library */ + g_hmodDirectDraw = LoadLibraryEx ("ddraw.dll", NULL, 0); + if (g_hmodDirectDraw == NULL) + { + ErrorF ("winGetDDProcAddresses - Could not load ddraw.dll\n"); + fReturn = TRUE; + goto winGetDDProcAddresses_Exit; + } + + /* Try to get the DirectDrawCreate address */ + g_fpDirectDrawCreate = GetProcAddress (g_hmodDirectDraw, + "DirectDrawCreate"); + if (g_fpDirectDrawCreate == NULL) + { + ErrorF ("winGetDDProcAddresses - Could not get DirectDrawCreate " + "address\n"); + fReturn = TRUE; + goto winGetDDProcAddresses_Exit; + } + + /* Try to get the DirectDrawCreateClipper address */ + g_fpDirectDrawCreateClipper = GetProcAddress (g_hmodDirectDraw, + "DirectDrawCreateClipper"); + if (g_fpDirectDrawCreateClipper == NULL) + { + ErrorF ("winGetDDProcAddresses - Could not get " + "DirectDrawCreateClipper address\n"); + fReturn = FALSE; + goto winGetDDProcAddresses_Exit; + } + + /* + * Note: Do not unload ddraw.dll here. Do it in GiveUp + */ + + winGetDDProcAddresses_Exit: + /* Unload the DirectDraw library if we failed to initialize */ + if (!fReturn && g_hmodDirectDraw != NULL) + { + FreeLibrary (g_hmodDirectDraw); + g_hmodDirectDraw = NULL; + } + + return fReturn; +} diff --git a/hw/xwin/winerror.c b/hw/xwin/winerror.c new file mode 100644 index 000000000..c18f10dde --- /dev/null +++ b/hw/xwin/winerror.c @@ -0,0 +1,73 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winerror.c,v 1.4 2003/02/12 15:01:38 alanh Exp $ */ + +#include "win.h" + +extern FILE *g_pfLog; + +#ifdef DDXOSVERRORF +void +OsVendorVErrorF (const char *pszFormat, va_list va_args) +{ + static pthread_mutex_t s_pmPrinting = PTHREAD_MUTEX_INITIALIZER; + + /* Check we opened the log file first */ + if (g_pfLog == NULL) return; + + /* Lock the printing mutex */ + pthread_mutex_lock (&s_pmPrinting); + + /* Print the error message to a log file, could be stderr */ + vfprintf (g_pfLog, pszFormat, va_args); + + /* Flush after every write, to make updates show up quickly */ + fflush (g_pfLog); + + /* Unlock the printing mutex */ + pthread_mutex_unlock (&s_pmPrinting); +} +#endif + + +/* + * os/util.c/FatalError () calls our vendor ErrorF, so the message + * from a FatalError will be logged. Thus, the message for the + * fatal error is not passed to this function. + * + * Attempt to do last-ditch, safe, important cleanup here. + */ +#ifdef DDXOSFATALERROR +void +OsVendorFatalError (void) +{ + +} +#endif diff --git a/hw/xwin/winfillsp.c b/hw/xwin/winfillsp.c new file mode 100644 index 000000000..faf9c67fc --- /dev/null +++ b/hw/xwin/winfillsp.c @@ -0,0 +1,537 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winfillsp.c,v 1.9 2001/11/01 12:19:40 alanh Exp $ */ + +#include "win.h" + +/* See Porting Layer Definition - p. 54 */ +void +winFillSpansNativeGDI (DrawablePtr pDrawable, + GCPtr pGC, + int iSpans, + DDXPointPtr pPoints, + int *piWidths, + int fSorted) +{ + winGCPriv(pGC); + int iSpan; + DDXPointPtr pPoint = NULL; + int *piWidth = 0; + HBITMAP hbmpOrig = NULL, hbmpOrigStipple = NULL; + PixmapPtr pPixmap = NULL; + winPrivPixmapPtr pPixmapPriv = NULL; + HBITMAP hbmpFilledStipple = NULL, hbmpMaskedForeground = NULL; + PixmapPtr pStipple = NULL; + winPrivPixmapPtr pStipplePriv = NULL; + PixmapPtr pTile = NULL; + winPrivPixmapPtr pTilePriv = NULL; + HBRUSH hbrushStipple = NULL; + HDC hdcStipple = NULL; + BYTE *pbbitsFilledStipple = NULL; + int iX; + DEBUG_FN_NAME("winFillSpans"); + DEBUGVARS; + DEBUGPROC_MSG; + + /* Branch on the type of drawable we have */ + switch (pDrawable->type) + { + case DRAWABLE_PIXMAP: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP\n"); +#if 0 + /* Branch on the raster operation type */ + switch (pGC->alu) + { + case GXclear: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP - GXclear\n"); + break; + case GXand: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP - GXand\n"); + break; + case GXandReverse: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP - GXandReverse\n"); + break; + case GXcopy: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP - GXcopy\n"); + break; + case GXandInverted: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP - GXandInverted\n"); + break; + case GXnoop: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP - GXnoop\n"); + break; + case GXxor: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP - GXxor\n"); + break; + case GXor: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP - GXor\n"); + break; + case GXnor: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP - GXnor\n"); + break; + case GXequiv: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP - GXequiv\n"); + break; + case GXinvert: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP - GXinvert\n"); + break; + case GXorReverse: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP - GXorReverse\n"); + break; + case GXcopyInverted: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP - GXcopyInverted\n"); + break; + case GXorInverted: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP - GXorInverted\n"); + break; + case GXnand: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP - GXnand\n"); + break; + case GXset: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP - GXset\n"); + break; + default: + FatalError ("winFillSpans - DRAWABLE_PIXMAP - Unknown ROP\n"); + break; + } +#endif + + /* Get a pixmap pointer from the drawable pointer, and fetch privates */ + pPixmap = (PixmapPtr) pDrawable; + pPixmapPriv = winGetPixmapPriv (pPixmap); + + /* Select the drawable pixmap into memory hdc */ + hbmpOrig = SelectObject (pGCPriv->hdcMem, pPixmapPriv->hBitmap); + if (hbmpOrig == NULL) + FatalError ("winFillSpans - DRAWABLE_PIXMAP - " + "SelectObject () failed on pPixmapPriv->hBitmap\n"); + + /* Branch on the fill type */ + switch (pGC->fillStyle) + { + case FillSolid: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP - FillSolid %08x\n", + pDrawable); + + /* + * REMOVE - Visual verification only. + */ + BitBlt (pGCPriv->hdc, + pDrawable->width, pDrawable->height, + pDrawable->width, pDrawable->height, + pGCPriv->hdcMem, + 0, 0, + SRCCOPY); + DEBUG_MSG ("FillSolid - Original bitmap"); + + /* Enumerate spans */ + for (iSpan = 0; iSpan < iSpans; ++iSpan) + { + /* Get pointers to the current span location and width */ + pPoint = pPoints + iSpan; + piWidth = piWidths + iSpan; + + /* Display some useful information */ + ErrorF ("(%dx%dx%d) (%d,%d) fg: %d bg: %d w: %d\n", + pDrawable->width, pDrawable->height, pDrawable->depth, + pPoint->x, pPoint->y, + pGC->fgPixel, pGC->bgPixel, + *piWidth); + + /* Draw the requested line */ + MoveToEx (pGCPriv->hdcMem, pPoint->x, pPoint->y, NULL); + LineTo (pGCPriv->hdcMem, pPoint->x + *piWidth, pPoint->y); + } + + /* + * REMOVE - Visual verification only. + */ + BitBlt (pGCPriv->hdc, + pDrawable->width * 2, pDrawable->height, + pDrawable->width, pDrawable->height, + pGCPriv->hdcMem, + 0, 0, + SRCCOPY); + DEBUG_MSG ("FillSolid - Filled bitmap"); + + + /* Push the drawable pixmap out of the GC HDC */ + SelectObject (pGCPriv->hdcMem, hbmpOrig); + break; + + case FillStippled: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP - FillStippled %08x\n", + pDrawable); + + /* + * FIXME: Assuming that pGC->patOrg.x = pGC->patOrg.y = 0 + */ + + pStipple = pGC->stipple; + pStipplePriv = winGetPixmapPriv (pStipple); + + /* Create a memory DC to hold the stipple */ + hdcStipple = CreateCompatibleDC (pGCPriv->hdc); + + /* Create a destination sized compatible bitmap */ + hbmpFilledStipple = winCreateDIBNativeGDI (pDrawable->width, + pDrawable->height, + pDrawable->depth, + &pbbitsFilledStipple, + NULL); + + /* Select the stipple bitmap into the stipple DC */ + hbmpOrigStipple = SelectObject (hdcStipple, hbmpFilledStipple); + if (hbmpOrigStipple == NULL) + FatalError ("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - " + "SelectObject () failed on hbmpFilledStipple\n"); + + /* Create a pattern brush from the original stipple */ + hbrushStipple = CreatePatternBrush (pStipplePriv->hBitmap); + + /* Select the original stipple brush into the stipple DC */ + SelectObject (hdcStipple, hbrushStipple); + + /* PatBlt the original stipple to the filled stipple */ + PatBlt (hdcStipple, + 0, 0, + pDrawable->width, pDrawable->height, + PATCOPY); + + /* + * REMOVE - Visual verification only. + */ + BitBlt (pGCPriv->hdc, + pDrawable->width, 0, + pDrawable->width, pDrawable->height, + hdcStipple, + 0, 0, + SRCCOPY); + DEBUG_MSG("Filled a drawable-sized stipple"); + + /* + * Mask out the bits from the drawable that are being preserved; + * hbmpFilledStipple now contains the preserved original bits. + */ + BitBlt (hdcStipple, + 0, 0, + pDrawable->width, pDrawable->height, + pGCPriv->hdcMem, + 0, 0, + SRCERASE); + + /* + * REMOVE - Visual verification only. + */ + BitBlt (pGCPriv->hdc, + pDrawable->width * 2, 0, + pDrawable->width, pDrawable->height, + hdcStipple, + 0, 0, + SRCCOPY); + DEBUG_MSG("Preserved original bits"); + + /* + * Create a destination sized compatible bitmap to hold + * the masked foreground color. + */ + hbmpMaskedForeground = winCreateDIBNativeGDI (pDrawable->width, + pDrawable->height, + pDrawable->depth, + NULL, + NULL); + + /* + * Select the masked foreground bitmap into the default memory DC; + * this should pop the drawable bitmap out of the default DC. + */ + if (SelectObject (pGCPriv->hdcMem, hbmpMaskedForeground) == NULL) + FatalError ("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - " + "SelectObject () failed on hbmpMaskedForeground\n"); + + /* Free the original drawable */ + DeleteObject (pPixmapPriv->hBitmap); + pPixmapPriv->hBitmap = NULL; + pPixmapPriv->pbBits = NULL; + + /* Select the stipple brush into the default memory DC */ + SelectObject (pGCPriv->hdcMem, hbrushStipple); + + /* Create the masked foreground bitmap using the original stipple */ + PatBlt (pGCPriv->hdcMem, + 0, 0, + pDrawable->width, pDrawable->height, + PATCOPY); + + /* + * REMOVE - Visual verification only. + */ + BitBlt (pGCPriv->hdc, + pDrawable->width * 3, 0, + pDrawable->width, pDrawable->height, + pGCPriv->hdcMem, + 0, 0, + SRCCOPY); + DEBUG_MSG("Masked foreground bitmap"); + + /* + * Combine the masked foreground with the masked drawable; + * hbmpFilledStipple will contain the drawable stipple filled + * with the current foreground color + */ + BitBlt (hdcStipple, + 0, 0, + pDrawable->width, pDrawable->height, + pGCPriv->hdcMem, + 0, 0, + SRCPAINT); + + /* + * REMOVE - Visual verification only. + */ + BitBlt (pGCPriv->hdc, + pDrawable->width * 4, 0, + pDrawable->width, pDrawable->height, + hdcStipple, + 0, 0, + SRCCOPY); + DEBUG_MSG("Completed stipple"); + + /* Release the stipple DC */ + SelectObject (hdcStipple, hbmpOrig); + DeleteDC (hdcStipple); + + /* Pop the stipple pattern brush out of the default mem DC */ + SelectObject (pGCPriv->hdcMem, GetStockObject (WHITE_BRUSH)); + + /* Destroy the original stipple pattern brush */ + DeleteObject (hbrushStipple); + + /* Clear the memory DC */ + SelectObject (pGCPriv->hdcMem, hbmpOrig); + + /* Free the masked foreground bitmap */ + DeleteObject (hbmpMaskedForeground); + + /* Point the drawable to the new bitmap */ + pPixmapPriv->hBitmap = hbmpFilledStipple; + pPixmapPriv->pbBits = pbbitsFilledStipple; + break; + + case FillTiled: + FatalError ("\nwinFillSpans - DRAWABLE_PIXMAP - FillTiled\n\n"); + break; + + case FillOpaqueStippled: + FatalError ("winFillSpans - DRAWABLE_PIXMAP - OpaqueStippled\n"); + break; + + default: + FatalError ("winFillSpans - DRAWABLE_PIXMAP - Unknown " + "fillStyle\n"); + break; + } + break; + + case DRAWABLE_WINDOW: + /* Branch on fill style */ + switch (pGC->fillStyle) + { + case FillSolid: + ErrorF ("\nwinFillSpans - DRAWABLE_WINDOW - FillSolid\n\n"); + + /* Enumerate spans */ + for (iSpan = 0; iSpan < iSpans; ++iSpan) + { + /* Get pointers to the current span location and width */ + pPoint = pPoints + iSpan; + piWidth = piWidths + iSpan; + + /* Display some useful information */ + ErrorF ("(%dx%dx%d) (%d,%d) fg: %d bg: %d w: %d\n", + pDrawable->width, pDrawable->height, pDrawable->depth, + pPoint->x, pPoint->y, + pGC->fgPixel, pGC->bgPixel, + *piWidth); + + /* Draw the requested line */ + MoveToEx (pGCPriv->hdc, pPoint->x, pPoint->y, NULL); + LineTo (pGCPriv->hdc, pPoint->x + *piWidth, pPoint->y); + } + break; + + case FillStippled: + FatalError ("winFillSpans - DRAWABLE_WINDOW - FillStippled\n\n"); + break; + + case FillTiled: + ErrorF ("\nwinFillSpans - DRAWABLE_WINDOW - FillTiled\n\n"); + + /* Get a pixmap pointer from the tile pointer, and fetch privates */ + pTile = (PixmapPtr) pGC->tile.pixmap; + pTilePriv = winGetPixmapPriv (pTile); + + /* Select the tile into a DC */ + hbmpOrig = SelectObject (pGCPriv->hdcMem, pTilePriv->hBitmap); + if (hbmpOrig == NULL) + FatalError ("winFillSpans - DRAWABLE_WINDOW - FillTiled - " + "SelectObject () failed on pTilePric->hBitmap\n"); + + /* Enumerate spans */ + for (iSpan = 0; iSpan < iSpans; ++iSpan) + { + /* Get pointers to the current span location and width */ + pPoint = pPoints + iSpan; + piWidth = piWidths + iSpan; + + for (iX = 0; iX < *piWidth; iX += pTile->drawable.width) + { + /* Blit the tile to the screen, one line at a time */ + BitBlt (pGCPriv->hdc, + pPoint->x + iX, pPoint->y, + pTile->drawable.width, 1, + pGCPriv->hdcMem, + 0, pPoint->y % pTile->drawable.height, + SRCCOPY); + } + } + + /* Push the drawable pixmap out of the GC HDC */ + SelectObject (pGCPriv->hdcMem, hbmpOrig); + +#if 0 + DEBUG_MSG("Completed tile fill"); +#endif + break; + + case FillOpaqueStippled: + FatalError ("winFillSpans - DRAWABLE_WINDOW - " + "OpaqueStippled\n"); + break; + + default: + FatalError ("winFillSpans - DRAWABLE_WINDOW - Unknown " + "fillStyle\n"); + } + + /* Branch on the raster operation type */ + switch (pGC->alu) + { + case GXclear: + ErrorF ("winFillSpans - DRAWABLE_WINDOW - GXclear\n"); + break; + case GXand: + ErrorF ("winFillSpans - DRAWABLE_WINDOW - GXand\n"); + break; + case GXandReverse: + ErrorF ("winFillSpans - DRAWABLE_WINDOW - GXandReverse\n"); + break; + case GXcopy: + ErrorF ("winFillSpans - DRAWABLE_WINDOW - GXcopy\n"); + break; + case GXandInverted: + ErrorF ("winFillSpans - DRAWABLE_WINDOW - GXandInverted\n"); + break; + case GXnoop: + ErrorF ("winFillSpans - DRAWABLE_WINDOW - GXnoop\n"); + break; + case GXxor: + ErrorF ("winFillSpans - DRAWABLE_WINDOW - GXxor\n"); + break; + case GXor: + ErrorF ("winFillSpans - DRAWABLE_WINDOW - GXor\n"); + break; + case GXnor: + ErrorF ("winFillSpans - DRAWABLE_WINDOW - GXnor\n"); + break; + case GXequiv: + ErrorF ("winFillSpans - DRAWABLE_WINDOW - GXequiv\n"); + break; + case GXinvert: + ErrorF ("winFillSpans - DRAWABLE_WINDOW - GXinvert\n"); + break; + case GXorReverse: + ErrorF ("winFillSpans - DRAWABLE_WINDOW - GXorReverse\n"); + break; + case GXcopyInverted: + ErrorF ("winFillSpans - DRAWABLE_WINDOW - GXcopyInverted\n"); + break; + case GXorInverted: + ErrorF ("winFillSpans - DRAWABLE_WINDOW - GXorInverted\n"); + break; + case GXnand: + ErrorF ("winFillSpans - DRAWABLE_WINDOW - GXnand\n"); + break; + case GXset: + ErrorF ("winFillSpans - DRAWABLE_WINDOW - GXset\n"); + break; + default: + ErrorF ("winFillSpans - DRAWABLE_WINDOW - Unknown ROP\n"); + break; + } + break; + + case UNDRAWABLE_WINDOW: + FatalError ("winFillSpans - UNDRAWABLE_WINDOW\n\n"); + + switch (pGC->fillStyle) + { + case FillSolid: + ErrorF ("\nwinFillSpans - UNDRAWABLE_WINDOW - FillSolid\n\n"); + break; + + case FillStippled: + ErrorF ("\nwinFillSpans - UNDRAWABLE_WINDOW - FillStippled\n\n"); + break; + + case FillTiled: + ErrorF ("\nwinFillSpans - UNDRAWABLE_WINDOW - FillTiled\n\n"); + break; + + case FillOpaqueStippled: + FatalError ("winFillSpans () - UNDRAWABLE_WINDOW - " + "OpaqueStippled\n"); + break; + + default: + FatalError ("winFillSpans () - UNDRAWABLE_WINDOW - Unknown " + "fillStyle\n"); + } + break; + + case DRAWABLE_BUFFER: + FatalError ("winFillSpansNativeGDI - DRAWABLE_BUFFER\n"); + break; + + default: + FatalError ("winFillSpansNativeGDI - Unknown drawable type\n"); + break; + } +} diff --git a/hw/xwin/winfont.c b/hw/xwin/winfont.c new file mode 100644 index 000000000..b249d8643 --- /dev/null +++ b/hw/xwin/winfont.c @@ -0,0 +1,50 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winfont.c,v 1.2 2001/06/04 13:04:41 alanh Exp $ */ + +#include "win.h" + +/* See Porting Layer Definition - p. 32 */ +/* See mfb/mfbfont.c - mfbRealizeFont() - which is empty :) */ +Bool +winRealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont) +{ + ErrorF ("winRealizeFont()\n"); + return TRUE; +} + +/* See Porting Layer Definition - p. 32 */ +/* See mfb/mfbfont.c - mfbUnrealizeFont() - which is empty :) */ +Bool +winUnrealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont) +{ + ErrorF ("winUnrealizeFont()\n"); + return TRUE; +} diff --git a/hw/xwin/wingc.c b/hw/xwin/wingc.c new file mode 100644 index 000000000..6ad58d8ed --- /dev/null +++ b/hw/xwin/wingc.c @@ -0,0 +1,418 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/wingc.c,v 1.10 2001/10/30 15:39:09 alanh Exp $ */ + +#include "win.h" + +#if 0 +/* GC Handling Routines */ +const GCFuncs winGCFuncs = { + winValidateGCNativeGDI, + winChangeGCNativeGDI, + winCopyGCNativeGDI, + winDestroyGCNativeGDI, + winChangeClipNativeGDI, + winDestroyClipNativeGDI, + winCopyClipNativeGDI, +}; +#else +const GCFuncs winGCFuncs = { + winValidateGCNativeGDI, + winChangeGCNativeGDI, + winCopyGCNativeGDI, + winDestroyGCNativeGDI, + miChangeClip, + miDestroyClip, + miCopyClip, +}; +#endif + +/* Drawing Primitives */ +const GCOps winGCOps = { + winFillSpansNativeGDI, + winSetSpansNativeGDI, + miPutImage, + miCopyArea, + miCopyPlane, + miPolyPoint, + winPolyLineNativeGDI, + miPolySegment, + miPolyRectangle, + miPolyArc, + miFillPolygon, + miPolyFillRect, + miPolyFillArc, + miPolyText8, + miPolyText16, + miImageText8, + miImageText16, + miImageGlyphBlt, + miPolyGlyphBlt, + miPushPixels +#ifdef NEED_LINEHELPER + ,NULL +#endif +}; + + +/* See Porting Layer Definition - p. 45 */ +/* See mfb/mfbgc.c - mfbCreateGC() */ +/* See Strategies for Porting - pp. 15, 16 */ +Bool +winCreateGCNativeGDI (GCPtr pGC) +{ + winPrivGCPtr pGCPriv = NULL; + winPrivScreenPtr pScreenPriv = NULL; + + ErrorF ("winCreateGCNativeGDI () depth: %d\n", + pGC->depth); + + pGC->clientClip = NULL; + pGC->clientClipType = CT_NONE; + + pGC->ops = (GCOps *) &winGCOps; + pGC->funcs = (GCFuncs *) &winGCFuncs; + + /* + * Setting miTranslate to 1 causes the coordinates passed to + * FillSpans, GetSpans, and SetSpans to be screen relative, rather + * than drawable relative. + * + * miTranslate was set to 0 prior to 2001-08-17. + */ + pGC->miTranslate = 1; + + /* Allocate privates for this GC */ + pGCPriv = winGetGCPriv (pGC); + if (pGCPriv == NULL) + { + ErrorF ("winCreateGCNativeGDI () - Privates pointer was NULL\n"); + return FALSE; + } + + /* Copy the screen DC to the local privates */ + pScreenPriv = winGetScreenPriv (pGC->pScreen); + pGCPriv->hdc = pScreenPriv->hdcScreen; + + /* Allocate a memory DC for the GC */ + pGCPriv->hdcMem = CreateCompatibleDC (pGCPriv->hdc); + + return TRUE; +} + + +/* See Porting Layer Definition - p. 45 */ +void +winChangeGCNativeGDI (GCPtr pGC, unsigned long ulChanges) +{ +#if CYGDEBUG + ErrorF ("winChangeGCNativeGDI () - Doing nothing\n"); +#endif +} + + +void +winValidateGCNativeGDI (GCPtr pGC, + unsigned long ulChanges, + DrawablePtr pDrawable) +{ + winGCPriv(pGC); + HBITMAP hbmpOrig = NULL; + PixmapPtr pPixmap = NULL; + winPrivPixmapPtr pPixmapPriv = NULL; + RGBQUAD rgbColors[2] = {{0, 0, 0, 0}, {0, 0, 0, 0}}; + PixmapPtr pStipple = NULL; + winPrivPixmapPtr pStipplePriv = NULL; + int i; + DEBUG_FN_NAME("winValidateGC"); + DEBUGVARS; + DEBUGPROC_MSG; + + /* Branch on drawable type */ + switch (pDrawable->type) + { + case DRAWABLE_PIXMAP: + /* Branch on the fill style */ + switch (pGC->fillStyle) + { + case FillSolid: + ErrorF ("winValidateGC - DRAWABLE_PIXMAP - FillSolid\n"); + + /* Select a stock pen */ + if (pDrawable->depth == 1 && pGC->fgPixel) + { + ErrorF ("winValidateGC - Selecting WHITE_PEN\n"); + SelectObject (pGCPriv->hdcMem, GetStockObject (WHITE_PEN)); + } + else if (pDrawable->depth == 1 && !pGC->fgPixel) + { + ErrorF ("winValidateGC - Selecting BLACK_PEN\n"); + SelectObject (pGCPriv->hdcMem, GetStockObject (BLACK_PEN)); + } + else if (pGC->fgPixel) + { + ErrorF ("winValidateGC - Selecting custom pen: %d\n", + pGC->fgPixel); + /* + * FIXME: So far I've only seen a white pen selected here. + */ +#if 1 + SelectObject (pGCPriv->hdcMem, GetStockObject (WHITE_PEN)); +#else + /* FIXME: This leaks a pen */ + SelectObject (pGCPriv->hdcMem, + CreatePen (PS_SOLID, 0, pGC->fgPixel)); +#endif + } + else + { + ErrorF ("winValidateGC - Selecting BLACK_PEN\n"); + SelectObject (pGCPriv->hdcMem, GetStockObject (BLACK_PEN)); + } + break; + + case FillStippled: + ErrorF ("winValidateGC - DRAWABLE_PIXMAP - FillStippled\n"); + /* + * NOTE: Setting the brush color has no effect on DIB fills. + * You need to set the stipple bitmap's color table instead. + */ +#if 1 + /* Pick the white color index */ + if (pGC->fgPixel) + i = 1; + else + i = 0; + + /* Set the white color, black is default */ + rgbColors[i].rgbRed = 255; + rgbColors[i].rgbGreen = 255; + rgbColors[i].rgbBlue = 255; + + /* Get stipple and privates pointers */ + pStipple = pGC->stipple; + pStipplePriv = winGetPixmapPriv (pStipple); + + /* Select the stipple bitmap */ + hbmpOrig = SelectObject (pGCPriv->hdcMem, pStipplePriv->hBitmap); + + /* Set the stipple color table */ + SetDIBColorTable (pGCPriv->hdcMem, 0, 2, rgbColors); + + /* Pop the stipple out of the hdc */ + SelectObject (pGCPriv->hdcMem, hbmpOrig); + +#else + /* Set the foreground color for the stipple fill */ + if (pGC->fgPixel == 0x1) + { + SetTextColor (pGCPriv->hdcMem, RGB(0x00, 0x00, 0x00)); + } + else if (pGC->fgPixel == 0xFFFF) + { + SetTextColor (pGCPriv->hdcMem, RGB(0xFF, 0xFF, 0xFF)); + } + else + { + SetTextColor (pGCPriv->hdcMem, RGB(0x00, 0x00, 0x00)); + } + SetBkColor (pGCPriv->hdcMem, RGB(0x00, 0x00, 0x00)); +#endif + break; + + case FillOpaqueStippled: + FatalError ("winValidateGC - DRAWABLE_PIXMAP - " + "FillOpaqueStippled\n"); + break; + + case FillTiled: + FatalError ("winValidateGC - DRAWABLE_PIXMAP - FillTiled\n"); + break; + + default: + FatalError ("winValidateGC - DRAWABLE_PIXMAP - Unknown fill " + "style\n"); + break; + } + break; + + case DRAWABLE_WINDOW: + /* Branch on the fill style */ + switch (pGC->fillStyle) + { + case FillTiled: + ErrorF ("winValidateGC - DRAWABLE_WINDOW - FillTiled\n"); + /* + * Do nothing here for now. Select the tile bitmap into the + * appropriate DC in the drawing function. + */ + + /* + * BEGIN REMOVE - Visual verification only. + */ + /* Get pixmap and privates pointers for the tile */ + pPixmap = pGC->tile.pixmap; + pPixmapPriv = winGetPixmapPriv (pPixmap); + + /* Push the tile into the GC's DC */ + hbmpOrig = SelectObject (pGCPriv->hdcMem, pPixmapPriv->hBitmap); + if (hbmpOrig == NULL) + FatalError ("winValidateGC - DRAWABLE_WINDOW - FillTiled - " + "SelectObject () failed on pPixmapPriv->hBitmap\n"); + + /* Blit the tile to a remote area of the screen */ + BitBlt (pGCPriv->hdc, + 64, 64, + pGC->tile.pixmap->drawable.width, + pGC->tile.pixmap->drawable.height, + pGCPriv->hdcMem, + 0, 0, + SRCCOPY); + DEBUG_MSG ("Blitted the tile to a remote area of the screen"); + + /* Pop the tile out of the GC's DC */ + SelectObject (pGCPriv->hdcMem, hbmpOrig); + /* + * END REMOVE - Visual verification only. + */ + break; + + case FillStippled: + FatalError ("winValidateGC - DRAWABLE_WINDOW - FillStippled\n"); + break; + + case FillOpaqueStippled: + FatalError ("winValidateGC - DRAWABLE_WINDOW - " + "FillOpaqueStippled\n"); + break; + + case FillSolid: + ErrorF ("winValidateGC - DRAWABLE_WINDOW - FillSolid\n"); + + /* Select a stock pen */ + if (pDrawable->depth == 1 && pGC->fgPixel) + { + ErrorF ("winValidateGC - Selecting WHITE_PEN\n"); + SelectObject (pGCPriv->hdc, GetStockObject (WHITE_PEN)); + } + else if (pDrawable->depth == 1 && !pGC->fgPixel) + { + ErrorF ("winValidateGC - Selecting BLACK_PEN\n"); + SelectObject (pGCPriv->hdc, GetStockObject (BLACK_PEN)); + } + else if (pGC->fgPixel) + { + ErrorF ("winValidateGC - Selecting custom pen: %d\n", + pGC->fgPixel); + /* + * FIXME: So far I've only seen a white pen selected here. + */ + SelectObject (pGCPriv->hdc, GetStockObject (WHITE_PEN)); + } + else + { + ErrorF ("winValidateGC - Selecting BLACK_PEN\n"); + SelectObject (pGCPriv->hdc, GetStockObject (BLACK_PEN)); + } + break; + + default: + FatalError ("winValidateGC - DRAWABLE_WINDOW - Unknown fill " + "style\n"); + break; + } + break; + + case UNDRAWABLE_WINDOW: + ErrorF ("\nwinValidateGC - UNDRAWABLE_WINDOW\n\n"); + break; + + case DRAWABLE_BUFFER: + FatalError ("winValidateGC - DRAWABLE_BUFFER\n"); + break; + + default: + FatalError ("winValidateGC - Unknown drawable type\n"); + break; + } +} + + +/* See Porting Layer Definition - p. 46 */ +void +winCopyGCNativeGDI (GCPtr pGCsrc, unsigned long ulMask, GCPtr pGCdst) +{ + +} + + +/* See Porting Layer Definition - p. 46 */ +void +winDestroyGCNativeGDI (GCPtr pGC) +{ + winGCPriv(pGC); + + /* Free the memory DC */ + if (pGCPriv->hdcMem != NULL) + { + DeleteDC (pGCPriv->hdcMem); + pGCPriv->hdcMem = NULL; + } + + /* Invalidate the screen DC pointer */ + pGCPriv->hdc = NULL; + + /* Invalidate the GC privates pointer */ + winSetGCPriv (pGC, NULL); +} + + +/* See Porting Layer Definition - p. 46 */ +void +winChangeClipNativeGDI (GCPtr pGC, int nType, pointer pValue, int nRects) +{ + +} + + +/* See Porting Layer Definition - p. 47 */ +void +winDestroyClipNativeGDI (GCPtr pGC) +{ + +} + + +/* See Porting Layer Definition - p. 47 */ +void +winCopyClipNativeGDI (GCPtr pGCdst, GCPtr pGCsrc) +{ + +} diff --git a/hw/xwin/wingetsp.c b/hw/xwin/wingetsp.c new file mode 100644 index 000000000..637debb9e --- /dev/null +++ b/hw/xwin/wingetsp.c @@ -0,0 +1,164 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/wingetsp.c,v 1.7 2001/11/01 12:19:40 alanh Exp $ */ + +#include "win.h" + +/* See Porting Layer Definition - p. 55 */ +void +winGetSpansNativeGDI (DrawablePtr pDrawable, + int nMax, + DDXPointPtr pPoints, + int *piWidths, + int iSpans, + char *pDsts) +{ + PixmapPtr pPixmap = NULL; + winPrivPixmapPtr pPixmapPriv = NULL; + int iSpan; + DDXPointPtr pPoint = NULL; + int *piWidth = NULL; + char *pDst = pDsts; + int iBytesToCopy; + HBITMAP hbmpWindow, hbmpOrig; + BYTE *pbWindow = NULL; + HDC hdcMem; + ScreenPtr pScreen = pDrawable->pScreen; + winScreenPriv(pScreen); + int iByteWidth; + + /* Branch on the drawable type */ + switch (pDrawable->type) + { + case DRAWABLE_PIXMAP: + ErrorF ("winGetSpans - DRAWABLE_PIXMAP %08x\n", + pDrawable); + + pPixmap = (PixmapPtr) pDrawable; + pPixmapPriv = winGetPixmapPriv (pPixmap); + + /* Loop through spans */ + for (iSpan = 0; iSpan < iSpans; ++iSpan) + { + pPoint = pPoints + iSpan; + piWidth = piWidths + iSpan; + + iBytesToCopy = PixmapBytePad (*piWidth, pDrawable->depth); + + memcpy (pDst, + pPixmapPriv->pbBits + + pPixmapPriv->dwScanlineBytes * pPoint->y, + iBytesToCopy); + + ErrorF ("(%dx%dx%d) (%d,%d) w: %d\n", + pDrawable->width, pDrawable->height, pDrawable->depth, + pPoint->x, pPoint->y, *piWidth); + + /* Calculate offset of next bit destination */ + pDst += 4 * ((*piWidth + 31) / 32); + } + break; + + case DRAWABLE_WINDOW: + ErrorF ("winGetSpans - DRAWABLE_WINDOW\n"); + + /* + * FIXME: Making huge assumption here that we are copying the + * area behind where the cursor will be displayed. We already + * know the size of the cursor, so this works, for now. + */ + + /* Create a bitmap to blit the window data to */ + hbmpWindow = winCreateDIBNativeGDI (*piWidths, + *piWidths, + pDrawable->depth, + &pbWindow, + NULL); + + /* Open a memory HDC */ + hdcMem = CreateCompatibleDC (NULL); + + /* Select the window bitmap */ + hbmpOrig = SelectObject (hdcMem, hbmpWindow); + + /* Transfer the window bits to the window bitmap */ + BitBlt (hdcMem, + 0, 0, + *piWidths, *piWidths, /* FIXME: Assuming square region */ + pScreenPriv->hdcScreen, + pPoints->x, pPoints->y, + SRCCOPY); + + /* Pop the window bitmap out of the HDC */ + SelectObject (hdcMem, hbmpOrig); + + /* Delete the memory HDC */ + DeleteDC (hdcMem); + hdcMem = NULL; + + iByteWidth = PixmapBytePad (*piWidths, pDrawable->depth); + + /* Loop through spans */ + for (iSpan = 0; iSpan < iSpans; ++iSpan) + { + pPoint = pPoints + iSpan; + piWidth = piWidths + iSpan; + + iBytesToCopy = PixmapBytePad (*piWidth, pDrawable->depth); + + memcpy (pDst, + pbWindow + iByteWidth * (pPoint->y - pPoints->y), + iBytesToCopy); + + ErrorF ("(%dx%dx%d) (%d,%d) w: %d\n", + pDrawable->width, pDrawable->height, pDrawable->depth, + pPoint->x, pPoint->y, *piWidth); + + /* Calculate offset of next bit destination */ + pDst += 4 * ((*piWidth + 31) / 32); + } + + /* Delete the window bitmap */ + DeleteObject (hbmpWindow); + break; + + case UNDRAWABLE_WINDOW: + FatalError ("winGetSpans - UNDRAWABLE_WINDOW\n"); + break; + + case DRAWABLE_BUFFER: + FatalError ("winGetSpans - DRAWABLE_BUFFER\n"); + break; + + default: + FatalError ("winGetSpans - Unknown drawable type\n"); + break; + } +} diff --git a/hw/xwin/winkeybd.c b/hw/xwin/winkeybd.c new file mode 100644 index 000000000..20df053c2 --- /dev/null +++ b/hw/xwin/winkeybd.c @@ -0,0 +1,707 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winkeybd.c,v 1.12 2002/10/17 08:18:22 alanh Exp $ */ + + +#include "win.h" +#include "winkeybd.h" +#include "winconfig.h" + +#ifdef XKB +#define XKB_IN_SERVER +#include "XKBsrv.h" +#endif + +static Bool g_winKeyState[NUM_KEYCODES]; + + +#if WIN_NEW_KEYBOARD_SUPPORT + +const unsigned int MaxKeysPerKey = 4; + +void +winProcessKeyEvent (DWORD dwVirtualKey, DWORD dwKeyData) +{ + Bool fDown = ((dwKeyData & 0x80000000) == 0); + winKeyEventsRec kerEvent; + int i; + + /* Get the key events */ + kerEvent = winTranslateKey (dwVirtualKey, dwKeyData); + + if (kerEvent.dwReleaseModifiers & WIN_MOD_LCONTROL) + winSendKeyEvent (XK_Control_L, FALSE); + if (kerEvent.dwReleaseModifiers & WIN_MOD_RCONTROL) + winSendKeyEvent (XK_Control_R, FALSE); + if (kerEvent.dwReleaseModifiers & WIN_MOD_LALT) + winSendKeyEvent (XK_Alt_L, FALSE); + if (kerEvent.dwReleaseModifiers & WIN_MOD_RALT) + winSendKeyEvent (XK_Alt_R, FALSE); + + for (i = 0; kerEvent.dwXKeycodes[i] != XK_VoidSymbol; ++i) + winSendKeyEvent (kerEvent.dwXKeycodes[i], fDown); + + if (kerEvent.dwReleaseModifiers & WIN_MOD_LCONTROL) + winSendKeyEvent (XK_Control_L, FALSE); + if (kerEvent.dwReleaseModifiers & WIN_MOD_RCONTROL) + winSendKeyEvent (XK_Control_R, TRUE); + if (kerEvent.dwReleaseModifiers & WIN_MOD_LALT) + winSendKeyEvent (XK_Alt_L, FALSE); + if (kerEvent.dwReleaseModifiers & WIN_MOD_RALT) + winSendKeyEvent (XK_Alt_R, TRUE); + +} + + +winKeyEventsRec +winTranslateKey (DWORD dwVirtualKey, DWORD dwKeyData) +{ + winKeyEventsRec kerEvents; + Bool fExtended = ((HIWORD (dwKeyData) & KF_EXTENDED) != 0); + int i; + DWORD dwNumEvents = 0; + BYTE bKeyboardState[256]; + int iReturn; + unsigned char cAscii[4]; + + /* Remap extended modifiers to the right version of that key. */ + if (fExtended) + { + switch (dwVirtualKey) + { + case VK_MENU: + dwVirtualKey = VK_RMENU; + break; + + case VK_CONTROL: + dwVirtualKey = VK_RCONTROL; + break; + } + } + + /* Initialize the modifiers to release flag */ + kerEvents.dwReleaseModifiers = 0; + + /* Look up the current virtual key code in the translation table */ + for (i = 0; i < g_winKeymapEntries; ++i) + { + /* Did we find a mapping? */ + if (winKeymap[i].dwVirtualKey == dwVirtualKey) + { + /* Mapping found, we have at least one event now */ + kerEvents.dwXKeycodes[dwNumEvents] = winKeymap[i].dwXKey; + break; + } + } + + + /* Break out early, if we found the key in the translation table */ + if (dwNumEvents != 0) + { + /* Terminate the last of the key events with a void symbol */ + kerEvents.dwXKeycodes[dwNumEvents] = XK_VoidSymbol; + return kerEvents; + } + + /* Get the state of all keyboard keys */ + GetKeyboardState (bKeyboardState); + + /* Try to convert the key to ASCII */ + iReturn = ToAscii (dwVirtualKey, 0, bKeyboardState, (WORD *) cAscii, 0); + + /* + * Left Control and Alt pressed, combined with a valid result + * from ToAscii means that we have found the Windows version of AltGr. + */ + if ((bKeyboardState[VK_MENU] & 0x80) && (bKeyboardState[VK_CONTROL] & 0x80) + && (iReturn >= 1) + && (((cAscii[0] >= 32) && (cAscii[0] <= 126)) + || (cAscii[0] >= 160))) + { + /* These three calls will return 0 on Windows 95/98/Me */ + if ((GetKeyState (VK_LCONTROL) & KF_UP)) + kerEvents.dwReleaseModifiers |= WIN_MOD_LCONTROL; + if ((GetKeyState (VK_LMENU) & KF_UP)) + kerEvents.dwReleaseModifiers |= WIN_MOD_LALT; + if ((GetKeyState (VK_RMENU) & KF_UP)) + kerEvents.dwReleaseModifiers |= WIN_MOD_RALT; + + /* Windows 95/98/Me handling - pop all of them */ + if (kerEvents.dwReleaseModifiers == 0) + kerEvents.dwReleaseModifiers + = WIN_MOD_LCONTROL | WIN_MOD_LALT | WIN_MOD_RALT; + + /* Copy the string of character events */ + for (i = 0; i < iReturn; ++i) + kerEvents.dwXKeycodes[dwNumEvents++] = cAscii[i]; + } + + /* Handle non Ctrl+Alt cases*/ + if (dwNumEvents == 0) + { + bKeyboardState[VK_CONTROL] = 0; + bKeyboardState[VK_LCONTROL] = 0; + bKeyboardState[VK_RCONTROL] = 0; + + iReturn = ToAscii (dwVirtualKey, 0, bKeyboardState, (WORD *)cAscii, 0); + if (iReturn < 0) + { + switch (cAscii[0]) + { + case '`': + kerEvents.dwXKeycodes[dwNumEvents++] = XK_dead_grave; + break; + + case '\'': + kerEvents.dwXKeycodes[dwNumEvents++] = XK_dead_acute; + break; + + case '~': + kerEvents.dwXKeycodes[dwNumEvents++] = XK_dead_tilde; + break; + + case '^': + kerEvents.dwXKeycodes[dwNumEvents++] = XK_dead_circumflex; + break; + } + } + + /* Send what we've got if its a printable character */ + if (iReturn >= 1) + for (i = 0; i < iReturn; ++i) + kerEvents.dwXKeycodes[dwNumEvents++] = cAscii[i]; + } + + + /* Terminate the last of the key events with a void symbol */ + kerEvents.dwXKeycodes[dwNumEvents] = XK_VoidSymbol; + return kerEvents; +} + + +#else /* WIN_NEW_KEYBOARD_SUPPORT */ + + +/* + * Translate a Windows WM_[SYS]KEY(UP/DOWN) message + * into an ASCII scan code. + * + * We do this ourselves, rather than letting Windows handle it, + * because Windows tends to munge the handling of special keys, + * like AltGr on European keyboards. + */ + +void +winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode) +{ + int iKeyFixup = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 1]; + int iKeyFixupEx = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 2]; + + /* Branch on special extended, special non-extended, or normal key */ + if ((HIWORD (lParam) & KF_EXTENDED) && iKeyFixupEx) + *piScanCode = iKeyFixupEx; + else if (iKeyFixup) + *piScanCode = iKeyFixup; + else + *piScanCode = LOBYTE (HIWORD (lParam)); +} + +#endif /* WIN_NEW_KEYBOARD_SUPPORT */ + + +/* + * We call this function from winKeybdProc when we are + * initializing the keyboard. + */ + +void +winGetKeyMappings (KeySymsPtr pKeySyms, CARD8 *pModMap) +{ + int i; + KeySym *pMap = map; + KeySym *pKeySym; + + /* + * Initialize all key states to up... which may not be true + * but it is close enough. + */ + ZeroMemory (g_winKeyState, sizeof (g_winKeyState[0]) * NUM_KEYCODES); + + /* MAP_LENGTH is defined in Xserver/include/input.h to be 256 */ + for (i = 0; i < MAP_LENGTH; i++) + pModMap[i] = NoSymbol; /* make sure it is restored */ + + /* Loop through all valid entries in the key symbol table */ + for (pKeySym = pMap, i = MIN_KEYCODE; + i < (MIN_KEYCODE + NUM_KEYCODES); + i++, pKeySym += GLYPHS_PER_KEY) + { + switch (*pKeySym) + { + case XK_Shift_L: + case XK_Shift_R: + pModMap[i] = ShiftMask; + break; + + case XK_Control_L: + case XK_Control_R: + pModMap[i] = ControlMask; + break; + + case XK_Caps_Lock: + pModMap[i] = LockMask; + break; + + case XK_Alt_L: + case XK_Alt_R: + pModMap[i] = AltMask; + break; + +#if !WIN_NEW_KEYBOARD_SUPPORT + case XK_Num_Lock: + pModMap[i] = NumLockMask; + break; + + case XK_Scroll_Lock: + pModMap[i] = ScrollLockMask; + break; + + /* Hirigana/Katakana toggle */ + case XK_Kana_Lock: + case XK_Kana_Shift: + pModMap[i] = KanaMask; + break; +#endif + + /* alternate toggle for multinational support */ + case XK_Mode_switch: + pModMap[i] = AltLangMask; + break; + } + } + + pKeySyms->map = (KeySym *) pMap; + pKeySyms->mapWidth = GLYPHS_PER_KEY; + pKeySyms->minKeyCode = MIN_KEYCODE; + pKeySyms->maxKeyCode = MAX_KEYCODE; +} + + +/* Ring the keyboard bell (system speaker on PCs) */ +void +winKeybdBell (int iPercent, DeviceIntPtr pDeviceInt, + pointer pCtrl, int iClass) +{ + /* + * We can't use Beep () here because it uses the PC speaker + * on NT/2000. MessageBeep (MB_OK) will play the default system + * sound on systems with a sound card or it will beep the PC speaker + * on systems that do not have a sound card. + */ + MessageBeep (MB_OK); +} + + +/* Change some keyboard configuration parameters */ +void +winKeybdCtrl (DeviceIntPtr pDevice, KeybdCtrl *pCtrl) +{ + +} + + +/* + * See Porting Layer Definition - p. 18 + * winKeybdProc is known as a DeviceProc. + */ + +int +winKeybdProc (DeviceIntPtr pDeviceInt, int iState) +{ + KeySymsRec keySyms; + CARD8 modMap[MAP_LENGTH]; + DevicePtr pDevice = (DevicePtr) pDeviceInt; +#ifdef XKB + XkbComponentNamesRec names; +#endif + + switch (iState) + { + case DEVICE_INIT: + winConfigKeyboard (pDeviceInt); + + winGetKeyMappings (&keySyms, modMap); + +#ifdef XKB + /* FIXME: Maybe we should use winGetKbdLeds () here? */ + defaultKeyboardControl.leds = g_winInfo.keyboard.leds; +#else + defaultKeyboardControl.leds = g_winInfo.keyboard.leds; +#endif + +#ifdef XKB + if (g_winInfo.xkb.disable) + { +#endif + InitKeyboardDeviceStruct (pDevice, + &keySyms, + modMap, + winKeybdBell, + winKeybdCtrl); +#ifdef XKB + } + else + { + + if (XkbInitialMap) + { + names.keymap = XkbInitialMap; + names.keycodes = NULL; + names.types = NULL; + names.compat = NULL; + names.symbols = NULL; + names.geometry = NULL; + } + else + { + names.keymap = g_winInfo.xkb.keymap; + names.keycodes = g_winInfo.xkb.keycodes; + names.types = g_winInfo.xkb.types; + names.compat = g_winInfo.xkb.compat; + names.symbols = g_winInfo.xkb.symbols; + names.geometry = g_winInfo.xkb.geometry; + } + + ErrorF("Rules = \"%s\" Model = \"%s\" Layout = \"%s\"" + " Variant = \"%s\" Options = \"%s\"\n", + g_winInfo.xkb.rules, g_winInfo.xkb.model, + g_winInfo.xkb.layout, g_winInfo.xkb.variant, + g_winInfo.xkb.options); + + XkbSetRulesDflts (g_winInfo.xkb.rules, g_winInfo.xkb.model, + g_winInfo.xkb.layout, g_winInfo.xkb.variant, + g_winInfo.xkb.options); + XkbInitKeyboardDeviceStruct (pDeviceInt, &names, &keySyms, + modMap, winKeybdBell, winKeybdCtrl); + } +#endif + break; + case DEVICE_ON: + pDevice->on = TRUE; + break; + + case DEVICE_CLOSE: + case DEVICE_OFF: + pDevice->on = FALSE; + break; + } + + return Success; +} + + +/* + * Detect current mode key states upon server startup. + * + * Simulate a press and release of any key that is currently + * toggled. + */ + +void +winInitializeModeKeyStates (void) +{ +#if !WIN_NEW_KEYBOARD_SUPPORT + /* Restore NumLock */ + if (GetKeyState (VK_NUMLOCK) & 0x0001) + { + winSendKeyEvent (KEY_NumLock, TRUE); + winSendKeyEvent (KEY_NumLock, FALSE); + } + + /* Restore CapsLock */ + if (GetKeyState (VK_CAPITAL) & 0x0001) + { + winSendKeyEvent (KEY_CapsLock, TRUE); + winSendKeyEvent (KEY_CapsLock, FALSE); + } + + /* Restore ScrollLock */ + if (GetKeyState (VK_SCROLL) & 0x0001) + { + winSendKeyEvent (KEY_ScrollLock, TRUE); + winSendKeyEvent (KEY_ScrollLock, FALSE); + } + + /* Restore KanaLock */ + if (GetKeyState (VK_KANA) & 0x0001) + { + winSendKeyEvent (KEY_HKTG, TRUE); + winSendKeyEvent (KEY_HKTG, FALSE); + } +#endif +} + + +/* + * We have to store the last state of each mode + * key before we lose the keyboard focus. + */ + +void +winStoreModeKeyStates (ScreenPtr pScreen) +{ +#if !WIN_NEW_KEYBOARD_SUPPORT + winScreenPriv(pScreen); + + /* Initialize all mode key states to off */ + pScreenPriv->dwModeKeyStates = 0x0L; + + pScreenPriv->dwModeKeyStates |= + (GetKeyState (VK_NUMLOCK) & 0x0001) << NumLockMapIndex; + + pScreenPriv->dwModeKeyStates |= + (GetKeyState (VK_SCROLL) & 0x0001) << ScrollLockMapIndex; + + pScreenPriv->dwModeKeyStates |= + (GetKeyState (VK_CAPITAL) & 0x0001) << LockMapIndex; + + pScreenPriv->dwModeKeyStates |= + (GetKeyState (VK_KANA) & 0x0001) << KanaMapIndex; +#endif +} + + +/* + * Upon regaining the keyboard focus we must + * resynchronize our internal mode key states + * with the actual state of the keys. + */ + +void +winRestoreModeKeyStates (ScreenPtr pScreen) +{ +#if !WIN_NEW_KEYBOARD_SUPPORT + winScreenPriv(pScreen); + DWORD dwKeyState; + + /* + * NOTE: The C XOR operator, ^, will not work here because it is + * a bitwise operator, not a logical operator. C does not + * have a logical XOR operator, so we use a macro instead. + */ + + /* Has the key state changed? */ + dwKeyState = GetKeyState (VK_NUMLOCK) & 0x0001; + if (WIN_XOR (pScreenPriv->dwModeKeyStates & NumLockMask, dwKeyState)) + { + winSendKeyEvent (KEY_NumLock, TRUE); + winSendKeyEvent (KEY_NumLock, FALSE); + } + + /* Has the key state changed? */ + dwKeyState = GetKeyState (VK_CAPITAL) & 0x0001; + if (WIN_XOR (pScreenPriv->dwModeKeyStates & LockMask, dwKeyState)) + { + winSendKeyEvent (KEY_CapsLock, TRUE); + winSendKeyEvent (KEY_CapsLock, FALSE); + } + + /* Has the key state changed? */ + dwKeyState = GetKeyState (VK_SCROLL) & 0x0001; + if (WIN_XOR (pScreenPriv->dwModeKeyStates & ScrollLockMask, dwKeyState)) + { + winSendKeyEvent (KEY_ScrollLock, TRUE); + winSendKeyEvent (KEY_ScrollLock, FALSE); + } + + /* Has the key state changed? */ + dwKeyState = GetKeyState (VK_KANA) & 0x0001; + if (WIN_XOR (pScreenPriv->dwModeKeyStates & KanaMask, dwKeyState)) + { + winSendKeyEvent (KEY_HKTG, TRUE); + winSendKeyEvent (KEY_HKTG, FALSE); + } +#endif +} + + +#if !WIN_NEW_KEYBOARD_SUPPORT +/* + * Look for the lovely fake Control_L press/release generated by Windows + * when AltGr is pressed/released on a non-U.S. keyboard. + */ + +Bool +winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam) +{ + MSG msgNext; + LONG lTime; + Bool fReturn; + + /* + * Fake Ctrl_L presses will be followed by an Alt_R keypress + * with the same timestamp as the Ctrl_L press. + */ + if (message == WM_KEYDOWN + && wParam == VK_CONTROL + && (HIWORD (lParam) & KF_EXTENDED) == 0) + { + /* Got a Ctrl_L press */ + + /* Get time of current message */ + lTime = GetMessageTime (); + + /* Look for fake Ctrl_L preceeding an Alt_R press. */ + fReturn = PeekMessage (&msgNext, NULL, + WM_KEYDOWN, WM_KEYDOWN, + PM_NOREMOVE); + + /* Is next press an Alt_R with the same timestamp? */ + if (fReturn && msgNext.wParam == VK_MENU + && msgNext.time == lTime + && (HIWORD (msgNext.lParam) & KF_EXTENDED)) + { + /* + * Next key press is Alt_R with same timestamp as current + * Ctrl_L message. Therefore, this Ctrl_L press is a fake + * event, so discard it. + */ + return TRUE; + } + } + + /* + * Fake Ctrl_L releases will be followed by an Alt_R release + * with the same timestamp as the Ctrl_L release. + */ + if ((message == WM_KEYUP || message == WM_SYSKEYUP) + && wParam == VK_CONTROL + && (HIWORD (lParam) & KF_EXTENDED) == 0) + { + /* Got a Ctrl_L release */ + + /* Get time of current message */ + lTime = GetMessageTime (); + + /* Look for fake Ctrl_L release preceeding an Alt_R release. */ + fReturn = PeekMessage (&msgNext, NULL, + WM_KEYUP, WM_SYSKEYUP, + PM_NOREMOVE); + + /* Is next press an Alt_R with the same timestamp? */ + if (fReturn + && (msgNext.message == WM_KEYUP + || msgNext.message == WM_SYSKEYUP) + && msgNext.wParam == VK_MENU + && msgNext.time == lTime + && (HIWORD (msgNext.lParam) & KF_EXTENDED)) + { + /* + * Next key release is Alt_R with same timestamp as current + * Ctrl_L message. Therefore, this Ctrl_L release is a fake + * event, so discard it. + */ + return TRUE; + } + } + + /* Not a fake control left press/release */ + return FALSE; +} +#endif /* WIN_NEW_KEYBOARD_SUPPORT */ + + +/* + * Lift any modifier keys that are pressed + */ + +void +winKeybdReleaseKeys () +{ +#if !WIN_NEW_KEYBOARD_SUPPORT +#if 0 /* Old function that just pops modifiers */ + /* Verify that the mi input system has been initialized */ + if (g_fdMessageQueue == WIN_FD_INVALID) + return; + + winSendKeyEvent (KEY_Alt, FALSE); + winSendKeyEvent (KEY_AltLang, FALSE); + winSendKeyEvent (KEY_LCtrl, FALSE); + winSendKeyEvent (KEY_RCtrl, FALSE); + winSendKeyEvent (KEY_ShiftL, FALSE); + winSendKeyEvent (KEY_ShiftR, FALSE); +#else /* New function that pops all keys */ + int i; + + /* Verify that the mi input system has been initialized */ + if (g_fdMessageQueue == WIN_FD_INVALID) + return; + + /* Pop any pressed keys */ + for (i = 0; i < NUM_KEYCODES; ++i) + { + if (g_winKeyState[i]) winSendKeyEvent (i, FALSE); + } +#endif +#endif +} + + +/* + * Take a raw X key code and send an up or down event for it. + * + * Thanks to VNC for inspiration, though it is a simple function. + */ + +void +winSendKeyEvent (DWORD dwKey, Bool fDown) +{ + xEvent xCurrentEvent; + + /* + * When alt-tabing between screens we can get phantom key up messages + * Here we only pass them through it we think we should! + */ + if (g_winKeyState[dwKey] == FALSE && fDown == FALSE) return; + + /* Update the keyState map */ + g_winKeyState[dwKey] = fDown; + + ZeroMemory (&xCurrentEvent, sizeof (xCurrentEvent)); + + xCurrentEvent.u.u.type = fDown ? KeyPress : KeyRelease; + xCurrentEvent.u.keyButtonPointer.time = + g_c32LastInputEventTime = GetTickCount (); + xCurrentEvent.u.u.detail = dwKey + MIN_KEYCODE; + mieqEnqueue (&xCurrentEvent); +} diff --git a/hw/xwin/winkeybd.h b/hw/xwin/winkeybd.h new file mode 100644 index 000000000..0822b0e5f --- /dev/null +++ b/hw/xwin/winkeybd.h @@ -0,0 +1,398 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winkeybd.h,v 1.3 2002/07/05 09:19:26 alanh Exp $ */ + +/* + * We need symbols for the scan codes of keys. + */ +#include "../xfree86/common/atKeynames.h" + + +/* + * Include the standard XFree86 ASCII keymap. + * + * This header declares a static KeySym array called 'map'. + */ +#include "../xfree86/common/xf86Keymap.h" + + +#if WIN_NEW_KEYBOARD_SUPPORT + +/* Define the keymap structure */ +typedef struct +{ + DWORD dwVirtualKey; + DWORD dwXKey; +} winKeymappingRec, *winKeymappingPtr; + +static const winKeymappingRec +winKeymap[] = { + {VK_BACK, XK_BackSpace}, + {VK_TAB, XK_Tab}, + {VK_CLEAR, XK_Clear}, + {VK_RETURN, XK_Return}, + {VK_LSHIFT, XK_Shift_L}, + {VK_RSHIFT, XK_Shift_R}, + {VK_SHIFT, XK_Shift_L}, + {VK_LCONTROL, XK_Control_L}, + {VK_RCONTROL, XK_Control_R}, + {VK_CONTROL, XK_Control_L}, + {VK_LMENU, XK_Alt_L}, + {VK_RMENU, XK_Alt_R}, + {VK_MENU, XK_Alt_L}, + {VK_PAUSE, XK_Pause}, + {VK_CAPITAL, XK_Caps_Lock}, + {VK_ESCAPE, XK_Escape}, + {VK_SPACE, XK_space}, + {VK_PRIOR, XK_Page_Up}, + {VK_NEXT, XK_Page_Down}, + {VK_END, XK_End}, + {VK_HOME, XK_Home}, + {VK_LEFT, XK_Left}, + {VK_UP, XK_Up}, + {VK_RIGHT, XK_Right}, + {VK_DOWN, XK_Down}, + {VK_SELECT, XK_Select}, + {VK_EXECUTE, XK_Execute}, + {VK_SNAPSHOT, XK_Print}, + {VK_INSERT, XK_Insert}, + {VK_DELETE, XK_Delete}, + {VK_HELP, XK_Help}, + {VK_NUMPAD0, XK_KP_0}, + {VK_NUMPAD1, XK_KP_1}, + {VK_NUMPAD2, XK_KP_2}, + {VK_NUMPAD3, XK_KP_3}, + {VK_NUMPAD4, XK_KP_4}, + {VK_NUMPAD5, XK_KP_5}, + {VK_NUMPAD6, XK_KP_6}, + {VK_NUMPAD7, XK_KP_7}, + {VK_NUMPAD8, XK_KP_8}, + {VK_NUMPAD9, XK_KP_9}, + {VK_MULTIPLY, XK_KP_Multiply}, + {VK_ADD, XK_KP_Add}, + {VK_SEPARATOR, XK_KP_Separator}, // often comma + {VK_SUBTRACT, XK_KP_Subtract}, + {VK_DECIMAL, XK_KP_Decimal}, + {VK_DIVIDE, XK_KP_Divide}, + {VK_F1, XK_F1}, + {VK_F2, XK_F2}, + {VK_F3, XK_F3}, + {VK_F4, XK_F4}, + {VK_F5, XK_F5}, + {VK_F6, XK_F6}, + {VK_F7, XK_F7}, + {VK_F8, XK_F8}, + {VK_F9, XK_F9}, + {VK_F10, XK_F10}, + {VK_F11, XK_F11}, + {VK_F12, XK_F12}, + {VK_F13, XK_F13}, + {VK_F14, XK_F14}, + {VK_F15, XK_F15}, + {VK_F16, XK_F16}, + {VK_F17, XK_F17}, + {VK_F18, XK_F18}, + {VK_F19, XK_F19}, + {VK_F20, XK_F20}, + {VK_F21, XK_F21}, + {VK_F22, XK_F22}, + {VK_F23, XK_F23}, + {VK_F24, XK_F24}, + {VK_NUMLOCK, XK_Num_Lock}, + {VK_SCROLL, XK_Scroll_Lock} +}; + +static int g_winKeymapEntries = sizeof (winKeymap) / sizeof (winKeymappingRec); + +#else /* WIN_NEW_KEYBOARD_SUPPORT */ + +#define WIN_KEYMAP_COLS 3 + +const int +g_iKeyMap [] = { + /* count Windows VK, ASCII, ASCII when extended VK */ + /* 0 */ 0, 0, 0, + /* 1 */ 0, 0, 0, + /* 2 */ 0, 0, 0, + /* 3 */ VK_CANCEL, 0, KEY_Break, + /* 4 */ 0, 0, 0, + /* 5 */ 0, 0, 0, + /* 6 */ 0, 0, 0, + /* 7 */ 0, 0, 0, + /* 8 */ 0, 0, 0, + /* 9 */ 0, 0, 0, + /* 10 */ 0, 0, 0, + /* 11 */ 0, 0, 0, + /* 12 */ 0, 0, 0, + /* 13 */ VK_RETURN, 0, KEY_KP_Enter, + /* 14 */ 0, 0, 0, + /* 15 */ 0, 0, 0, + /* 16 */ VK_SHIFT, KEY_ShiftL, KEY_ShiftR, + /* 17 */ VK_CONTROL, 0, KEY_RCtrl, + /* 18 */ VK_MENU, 0, KEY_AltLang, + /* 19 */ VK_PAUSE, KEY_Pause, 0, + /* 20 */ 0, 0, 0, + /* 21 */ 0, 0, 0, + /* 22 */ 0, 0, 0, + /* 23 */ 0, 0, 0, + /* 24 */ 0, 0, 0, + /* 25 */ 0, 0, 0, + /* 26 */ 0, 0, 0, + /* 27 */ 0, 0, 0, + /* 28 */ 0, 0, 0, + /* 29 */ 0, 0, 0, + /* 30 */ 0, 0, 0, + /* 31 */ 0, 0, 0, + /* 32 */ 0, 0, 0, + /* 33 */ VK_PRIOR, 0, KEY_PgUp, + /* 34 */ VK_NEXT, 0, KEY_PgDown, + /* 35 */ VK_END, 0, KEY_End, + /* 36 */ VK_HOME, 0, KEY_Home, + /* 37 */ VK_LEFT, 0, KEY_Left, + /* 38 */ VK_UP, 0, KEY_Up, + /* 39 */ VK_RIGHT, 0, KEY_Right, + /* 40 */ VK_DOWN, 0, KEY_Down, + /* 41 */ 0, 0, 0, + /* 42 */ 0, 0, 0, + /* 43 */ 0, 0, 0, + /* 44 */ VK_SNAPSHOT, 0, KEY_Print, + /* 45 */ VK_INSERT, 0, KEY_Insert, + /* 46 */ VK_DELETE, 0, KEY_Delete, + /* 47 */ 0, 0, 0, + /* 48 */ 0, 0, 0, + /* 49 */ 0, 0, 0, + /* 50 */ 0, 0, 0, + /* 51 */ 0, 0, 0, + /* 52 */ 0, 0, 0, + /* 53 */ 0, 0, 0, + /* 54 */ 0, 0, 0, + /* 55 */ 0, 0, 0, + /* 56 */ 0, 0, 0, + /* 57 */ 0, 0, 0, + /* 58 */ 0, 0, 0, + /* 59 */ 0, 0, 0, + /* 60 */ 0, 0, 0, + /* 61 */ 0, 0, 0, + /* 62 */ 0, 0, 0, + /* 63 */ 0, 0, 0, + /* 64 */ 0, 0, 0, + /* 65 */ 0, 0, 0, + /* 66 */ 0, 0, 0, + /* 67 */ 0, 0, 0, + /* 68 */ 0, 0, 0, + /* 69 */ 0, 0, 0, + /* 70 */ 0, 0, 0, + /* 71 */ 0, 0, 0, + /* 72 */ 0, 0, 0, + /* 73 */ 0, 0, 0, + /* 74 */ 0, 0, 0, + /* 75 */ 0, 0, 0, + /* 76 */ 0, 0, 0, + /* 77 */ 0, 0, 0, + /* 78 */ 0, 0, 0, + /* 79 */ 0, 0, 0, + /* 80 */ 0, 0, 0, + /* 81 */ 0, 0, 0, + /* 82 */ 0, 0, 0, + /* 83 */ 0, 0, 0, + /* 84 */ 0, 0, 0, + /* 85 */ 0, 0, 0, + /* 86 */ 0, 0, 0, + /* 87 */ 0, 0, 0, + /* 88 */ 0, 0, 0, + /* 89 */ 0, 0, 0, + /* 90 */ 0, 0, 0, + /* 91 */ 0, 0, 0, + /* 92 */ 0, 0, 0, + /* 93 */ 0, 0, 0, + /* 94 */ 0, 0, 0, + /* 95 */ 0, 0, 0, + /* 96 */ 0, 0, 0, + /* 97 */ 0, 0, 0, + /* 98 */ 0, 0, 0, + /* 99 */ 0, 0, 0, + /* 100 */ 0, 0, 0, + /* 101 */ 0, 0, 0, + /* 102 */ 0, 0, 0, + /* 103 */ 0, 0, 0, + /* 104 */ 0, 0, 0, + /* 105 */ 0, 0, 0, + /* 106 */ 0, 0, 0, + /* 107 */ 0, 0, 0, + /* 108 */ 0, 0, 0, + /* 109 */ 0, 0, 0, + /* 110 */ 0, 0, 0, + /* 111 */ VK_DIVIDE, 0, KEY_KP_Divide, + /* 112 */ 0, 0, 0, + /* 113 */ 0, 0, 0, + /* 114 */ 0, 0, 0, + /* 115 */ 0, 0, 0, + /* 116 */ 0, 0, 0, + /* 117 */ 0, 0, 0, + /* 118 */ 0, 0, 0, + /* 119 */ 0, 0, 0, + /* 120 */ 0, 0, 0, + /* 121 */ 0, 0, 0, + /* 122 */ 0, 0, 0, + /* 123 */ 0, 0, 0, + /* 124 */ 0, 0, 0, + /* 125 */ 0, 0, 0, + /* 126 */ 0, 0, 0, + /* 127 */ 0, 0, 0, + /* 128 */ 0, 0, 0, + /* 129 */ 0, 0, 0, + /* 130 */ 0, 0, 0, + /* 131 */ 0, 0, 0, + /* 132 */ 0, 0, 0, + /* 133 */ 0, 0, 0, + /* 134 */ 0, 0, 0, + /* 135 */ 0, 0, 0, + /* 136 */ 0, 0, 0, + /* 137 */ 0, 0, 0, + /* 138 */ 0, 0, 0, + /* 139 */ 0, 0, 0, + /* 140 */ 0, 0, 0, + /* 141 */ 0, 0, 0, + /* 142 */ 0, 0, 0, + /* 143 */ 0, 0, 0, + /* 144 */ 0, 0, 0, + /* 145 */ 0, 0, 0, + /* 146 */ 0, 0, 0, + /* 147 */ 0, 0, 0, + /* 148 */ 0, 0, 0, + /* 149 */ 0, 0, 0, + /* 150 */ 0, 0, 0, + /* 151 */ 0, 0, 0, + /* 152 */ 0, 0, 0, + /* 153 */ 0, 0, 0, + /* 154 */ 0, 0, 0, + /* 155 */ 0, 0, 0, + /* 156 */ 0, 0, 0, + /* 157 */ 0, 0, 0, + /* 158 */ 0, 0, 0, + /* 159 */ 0, 0, 0, + /* 160 */ 0, 0, 0, + /* 161 */ 0, 0, 0, + /* 162 */ 0, 0, 0, + /* 163 */ 0, 0, 0, + /* 164 */ 0, 0, 0, + /* 165 */ 0, 0, 0, + /* 166 */ 0, 0, 0, + /* 167 */ 0, 0, 0, + /* 168 */ 0, 0, 0, + /* 169 */ 0, 0, 0, + /* 170 */ 0, 0, 0, + /* 171 */ 0, 0, 0, + /* 172 */ 0, 0, 0, + /* 173 */ 0, 0, 0, + /* 174 */ 0, 0, 0, + /* 175 */ 0, 0, 0, + /* 176 */ 0, 0, 0, + /* 177 */ 0, 0, 0, + /* 178 */ 0, 0, 0, + /* 179 */ 0, 0, 0, + /* 180 */ 0, 0, 0, + /* 181 */ 0, 0, 0, + /* 182 */ 0, 0, 0, + /* 183 */ 0, 0, 0, + /* 184 */ 0, 0, 0, + /* 185 */ 0, 0, 0, + /* 186 */ 0, 0, 0, + /* 187 */ 0, 0, 0, + /* 188 */ 0, 0, 0, + /* 189 */ 0, 0, 0, + /* 190 */ 0, 0, 0, + /* 191 */ 0, 0, 0, + /* 192 */ 0, 0, 0, + /* 193 */ 0, 0, 0, + /* 194 */ 0, 0, 0, + /* 195 */ 0, 0, 0, + /* 196 */ 0, 0, 0, + /* 197 */ 0, 0, 0, + /* 198 */ 0, 0, 0, + /* 199 */ 0, 0, 0, + /* 200 */ 0, 0, 0, + /* 201 */ 0, 0, 0, + /* 202 */ 0, 0, 0, + /* 203 */ 0, 0, 0, + /* 204 */ 0, 0, 0, + /* 205 */ 0, 0, 0, + /* 206 */ 0, 0, 0, + /* 207 */ 0, 0, 0, + /* 208 */ 0, 0, 0, + /* 209 */ 0, 0, 0, + /* 210 */ 0, 0, 0, + /* 211 */ 0, 0, 0, + /* 212 */ 0, 0, 0, + /* 213 */ 0, 0, 0, + /* 214 */ 0, 0, 0, + /* 215 */ 0, 0, 0, + /* 216 */ 0, 0, 0, + /* 217 */ 0, 0, 0, + /* 218 */ 0, 0, 0, + /* 219 */ 0, 0, 0, + /* 220 */ 0, 0, 0, + /* 221 */ 0, 0, 0, + /* 222 */ 0, 0, 0, + /* 223 */ 0, 0, 0, + /* 224 */ 0, 0, 0, + /* 225 */ 0, 0, 0, + /* 226 */ 0, 0, 0, + /* 227 */ 0, 0, 0, + /* 228 */ 0, 0, 0, + /* 229 */ 0, 0, 0, + /* 230 */ 0, 0, 0, + /* 231 */ 0, 0, 0, + /* 232 */ 0, 0, 0, + /* 233 */ 0, 0, 0, + /* 234 */ 0, 0, 0, + /* 235 */ 0, 0, 0, + /* 236 */ 0, 0, 0, + /* 237 */ 0, 0, 0, + /* 238 */ 0, 0, 0, + /* 239 */ 0, 0, 0, + /* 240 */ 0, 0, 0, + /* 241 */ 0, 0, 0, + /* 242 */ 0, 0, 0, + /* 243 */ 0, 0, 0, + /* 244 */ 0, 0, 0, + /* 245 */ 0, 0, 0, + /* 246 */ 0, 0, 0, + /* 247 */ 0, 0, 0, + /* 248 */ 0, 0, 0, + /* 249 */ 0, 0, 0, + /* 250 */ 0, 0, 0, + /* 251 */ 0, 0, 0, + /* 252 */ 0, 0, 0, + /* 253 */ 0, 0, 0, + /* 254 */ 0, 0, 0, + /* 255 */ 0, 0, 0 +}; +#endif /* WIN_NEW_KEYBOARD_SUPPORT */ diff --git a/hw/xwin/winmisc.c b/hw/xwin/winmisc.c new file mode 100644 index 000000000..ea8303ea9 --- /dev/null +++ b/hw/xwin/winmisc.c @@ -0,0 +1,147 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winmisc.c,v 1.6 2002/07/05 09:19:26 alanh Exp $ */ + +#include "win.h" + + +/* See Porting Layer Definition - p. 33 */ +/* + * Called by clients, returns the best size for a cursor, tile, or + * stipple, specified by class (sometimes called kind) + */ + +void +winQueryBestSizeNativeGDI (int class, unsigned short *pWidth, + unsigned short *pHeight, ScreenPtr pScreen) +{ + ErrorF ("winQueryBestSizeNativeGDI\n"); +} + + +/* + * Count the number of one bits in a color mask. + */ + +CARD8 +winCountBits (DWORD dw) +{ + DWORD dwBits = 0; + + while (dw) + { + dwBits += (dw & 1); + dw >>= 1; + } + + return dwBits; +} + + +/* + * Modify the screen pixmap to point to the new framebuffer address + */ + +Bool +winUpdateFBPointer (ScreenPtr pScreen, void *pbits) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Location of shadow framebuffer has changed */ + pScreenInfo->pfb = pbits; + + /* Update the screen pixmap */ + if (!(*pScreen->ModifyPixmapHeader) (pScreen->devPrivate, + pScreen->width, + pScreen->height, + pScreen->rootDepth, + BitsPerPixel (pScreen->rootDepth), + PixmapBytePad (pScreenInfo->dwStride, + pScreenInfo->dwBPP), + pScreenInfo->pfb)) + { + FatalError ("winUpdateFramebufferPointer - Failed modifying "\ + "screen pixmap\n"); + } + + return TRUE; +} + + +/* + * Paint the window background with the specified color + */ + +BOOL +winPaintBackground (HWND hwnd, COLORREF colorref) +{ + HDC hdc; + HBRUSH hbrush; + RECT rect; + + /* Create an hdc */ + hdc = GetDC (hwnd); + if (hdc == NULL) + { + printf ("gdiWindowProc - GetDC failed\n"); + exit (1); + } + + /* Create and select blue brush */ + hbrush = CreateSolidBrush (colorref); + if (hbrush == NULL) + { + printf ("gdiWindowProc - CreateSolidBrush failed\n"); + exit (1); + } + + /* Get window extents */ + if (GetClientRect (hwnd, &rect) == FALSE) + { + printf ("gdiWindowProc - GetClientRect failed\n"); + exit (1); + } + + /* Fill window with blue brush */ + if (FillRect (hdc, &rect, hbrush) == 0) + { + printf ("gdiWindowProc - FillRect failed\n"); + exit (1); + } + + /* Delete blue brush */ + DeleteObject (hbrush); + + /* Release the hdc */ + ReleaseDC (hwnd, hdc); + + return TRUE; +} diff --git a/hw/xwin/winmouse.c b/hw/xwin/winmouse.c new file mode 100644 index 000000000..8c9439bfd --- /dev/null +++ b/hw/xwin/winmouse.c @@ -0,0 +1,295 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winmouse.c,v 1.4 2001/10/29 21:10:24 alanh Exp $ */ + +#include "win.h" + +void +winMouseCtrl (DeviceIntPtr pDevice, PtrCtrl *pCtrl) +{ +} + + +/* + * See Porting Layer Definition - p. 18 + * This is known as a DeviceProc + */ + +int +winMouseProc (DeviceIntPtr pDeviceInt, int iState) +{ + CARD8 map[6]; + DevicePtr pDevice = (DevicePtr) pDeviceInt; + + switch (iState) + { + case DEVICE_INIT: + map[1] = 1; + map[2] = 2; + map[3] = 3; + map[4] = 4; + map[5] = 5; + InitPointerDeviceStruct (pDevice, + map, + 5, /* Buttons 4 and 5 are mouse wheel events */ + miPointerGetMotionEvents, + winMouseCtrl, + miPointerGetMotionBufferSize ()); + break; + + case DEVICE_ON: + pDevice->on = TRUE; + break; + + case DEVICE_CLOSE: + case DEVICE_OFF: + pDevice->on = FALSE; + break; + } + return Success; +} + + +/* Handle the mouse wheel */ +int +winMouseWheel (ScreenPtr pScreen, int iDeltaZ) +{ + winScreenPriv(pScreen); + xEvent xCurrentEvent; + + /* Button4 = WheelUp */ + /* Button5 = WheelDown */ + + /* Do we have any previous delta stored? */ + if ((pScreenPriv->iDeltaZ > 0 + && iDeltaZ > 0) + || (pScreenPriv->iDeltaZ < 0 + && iDeltaZ < 0)) + { + /* Previous delta and of same sign as current delta */ + iDeltaZ += pScreenPriv->iDeltaZ; + pScreenPriv->iDeltaZ = 0; + } + else + { + /* + * Previous delta of different sign, or zero. + * We will set it to zero for either case, + * as blindly setting takes just as much time + * as checking, then setting if necessary :) + */ + pScreenPriv->iDeltaZ = 0; + } + + /* + * Only process this message if the wheel has moved further than + * WHEEL_DELTA + */ + if (iDeltaZ >= WHEEL_DELTA || (-1 * iDeltaZ) >= WHEEL_DELTA) + { + pScreenPriv->iDeltaZ = 0; + + /* Figure out how many whole deltas of the wheel we have */ + iDeltaZ /= WHEEL_DELTA; + } + else + { + /* + * Wheel has not moved past WHEEL_DELTA threshold; + * we will store the wheel delta until the threshold + * has been reached. + */ + pScreenPriv->iDeltaZ = iDeltaZ; + return 0; + } + + /* Set the button to indicate up or down wheel delta */ + if (iDeltaZ > 0) + { + xCurrentEvent.u.u.detail = Button4; + } + else + { + xCurrentEvent.u.u.detail = Button5; + } + + /* + * Flip iDeltaZ to positive, if negative, + * because always need to generate a *positive* number of + * button clicks for the Z axis. + */ + if (iDeltaZ < 0) + { + iDeltaZ *= -1; + } + + /* Generate X input messages for each wheel delta we have seen */ + while (iDeltaZ--) + { + /* Push the wheel button */ + xCurrentEvent.u.u.type = ButtonPress; + xCurrentEvent.u.keyButtonPointer.time + = g_c32LastInputEventTime = GetTickCount (); + mieqEnqueue (&xCurrentEvent); + + /* Release the wheel button */ + xCurrentEvent.u.u.type = ButtonRelease; + xCurrentEvent.u.keyButtonPointer.time + = g_c32LastInputEventTime = GetTickCount (); + mieqEnqueue (&xCurrentEvent); + } + + return 0; +} + + +/* + * Enqueue a mouse button event + */ + +void +winMouseButtonsSendEvent (int iEventType, int iButton) +{ + xEvent xCurrentEvent; + + /* Load an xEvent and enqueue the event */ + xCurrentEvent.u.u.type = iEventType; + xCurrentEvent.u.u.detail = iButton; + xCurrentEvent.u.keyButtonPointer.time + = g_c32LastInputEventTime = GetTickCount (); + mieqEnqueue (&xCurrentEvent); +} + + +/* + * Decide what to do with a Windows mouse message + */ + +int +winMouseButtonsHandle (ScreenPtr pScreen, + int iEventType, int iButton, + WPARAM wParam) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Send button events right away if emulate 3 buttons is off */ + if (pScreenInfo->iE3BTimeout == WIN_E3B_OFF) + { + /* Emulate 3 buttons is off, send the button event */ + winMouseButtonsSendEvent (iEventType, iButton); + return 0; + } + + /* Emulate 3 buttons is on, let the fun begin */ + if (iEventType == ButtonPress + && pScreenPriv->iE3BCachedPress == 0 + && !pScreenPriv->fE3BFakeButton2Sent) + { + /* + * Button was pressed, no press is cached, + * and there is no fake button 2 release pending. + */ + + /* Store button press type */ + pScreenPriv->iE3BCachedPress = iButton; + + /* + * Set a timer to send this button press if the other button + * is not pressed within the timeout time. + */ + SetTimer (pScreenPriv->hwndScreen, + WIN_E3B_TIMER_ID, + pScreenInfo->iE3BTimeout, + NULL); + } + else if (iEventType == ButtonPress + && pScreenPriv->iE3BCachedPress != 0 + && pScreenPriv->iE3BCachedPress != iButton + && !pScreenPriv->fE3BFakeButton2Sent) + { + /* + * Button press is cached, other button was pressed, + * and there is no fake button 2 release pending. + */ + + /* Mouse button was cached and other button was pressed */ + KillTimer (pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID); + pScreenPriv->iE3BCachedPress = 0; + + /* Send fake middle button */ + winMouseButtonsSendEvent (ButtonPress, Button2); + + /* Indicate that a fake middle button event was sent */ + pScreenPriv->fE3BFakeButton2Sent = TRUE; + } + else if (iEventType == ButtonRelease + && pScreenPriv->iE3BCachedPress == iButton) + { + /* + * Cached button was released before timer ran out, + * and before the other mouse button was pressed. + */ + KillTimer (pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID); + pScreenPriv->iE3BCachedPress = 0; + + /* Send cached press, then send release */ + winMouseButtonsSendEvent (ButtonPress, iButton); + winMouseButtonsSendEvent (ButtonRelease, iButton); + } + else if (iEventType == ButtonRelease + && pScreenPriv->fE3BFakeButton2Sent + && !(wParam & MK_LBUTTON) + && !(wParam & MK_RBUTTON)) + { + /* + * Fake button 2 was sent and both mouse buttons have now been released + */ + pScreenPriv->fE3BFakeButton2Sent = FALSE; + + /* Send middle mouse button release */ + winMouseButtonsSendEvent (ButtonRelease, Button2); + } + else if (iEventType == ButtonRelease + && pScreenPriv->iE3BCachedPress == 0 + && !pScreenPriv->fE3BFakeButton2Sent) + { + /* + * Button was release, no button is cached, + * and there is no fake button 2 release is pending. + */ + winMouseButtonsSendEvent (ButtonRelease, iButton); + } + + return 0; +} diff --git a/hw/xwin/winms.h b/hw/xwin/winms.h new file mode 100644 index 000000000..17454487d --- /dev/null +++ b/hw/xwin/winms.h @@ -0,0 +1,61 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winms.h,v 1.2 2001/04/18 17:14:06 dawes Exp $ */ + +#ifndef _WINMS_H_ +#define _WINMS_H_ + +#undef MINSHORT +#undef MAXSHORT +#undef CARD8 +#undef INT32 +#undef ATOM + +#define NONAMELESSUNION +#define DIRECTDRAW_VERSION 0x0300 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#include +#include + +#include "obj_base.h" +#include "ddraw.h" + +/* + * Undefine unneeded Windows symbols that conflict + * with X symbols + */ + +#undef CreateWindow +#undef FreeResource + +#endif /* _WINMS_H_ */ diff --git a/hw/xwin/winmsg.c b/hw/xwin/winmsg.c new file mode 100644 index 000000000..35342c359 --- /dev/null +++ b/hw/xwin/winmsg.c @@ -0,0 +1,119 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Alexander Gottwald + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winmsg.c,v 1.1 2002/10/17 08:18:22 alanh Exp $ */ + +#include "win.h" +#include "winmsg.h" +#include + +#ifndef VERBOSE_LEVEL +#define VERBOSE_LEVEL 4 +#endif + + +void winVMsg (int, MessageType, int verb, const char *, va_list); + + +void +winVMsg (int scrnIndex, MessageType type, int verb, const char *format, + va_list ap) +{ + const char *prefix = NULL; + + if (verb && verb > VERBOSE_LEVEL) + return; + +#undef __msg +#define __msg(name,string) case name: prefix = string; break; +#undef _msg +#define _msg(name,string) __msg(name,string) + switch (type) + { + MESSAGE_STRINGS default:prefix = NULL; + break; + } +#undef __msg +#undef _msg + + if (prefix != NULL) + ErrorF ("%s ", prefix); + VErrorF (format, ap); +} + + +void +winDrvMsg (int scrnIndex, MessageType type, const char *format, ...) +{ + va_list ap; + va_start (ap, format); + winVMsg (scrnIndex, type, 0, format, ap); + va_end (ap); +} + + +void +winMsg (MessageType type, const char *format, ...) +{ + va_list ap; + va_start (ap, format); + winVMsg (0, type, 0, format, ap); + va_end (ap); +} + + +void +winDrvMsgVerb (int scrnIndex, MessageType type, int verb, const char *format, + ...) +{ + va_list ap; + va_start (ap, format); + winVMsg (scrnIndex, type, verb, format, ap); + va_end (ap); +} + + +void +winMsgVerb (MessageType type, int verb, const char *format, ...) +{ + va_list ap; + va_start (ap, format); + winVMsg (0, type, verb, format, ap); + va_end (ap); +} + + +void +winErrorFVerb (int verb, const char *format, ...) +{ + va_list ap; + va_start (ap, format); + winVMsg (0, X_NONE, verb, format, ap); + va_end (ap); +} diff --git a/hw/xwin/winmsg.h b/hw/xwin/winmsg.h new file mode 100644 index 000000000..c873d4beb --- /dev/null +++ b/hw/xwin/winmsg.h @@ -0,0 +1,72 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Alexander Gottwald + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winmsg.h,v 1.1 2002/10/17 08:18:22 alanh Exp $ */ + +#ifndef __WIN_MSG_H__ +#define __WIN_MSG_H__ + + +#define __msg_name(name,string) name +#define __msg(name,string) __msg_name(name,string) +#define _msg(name,string) __msg(name,string), + +#define MESSAGE_STRINGS \ + _msg(X_PROBED,"(--)" /* Value was probed */)\ + _msg(X_CONFIG,"(**)" /* Value was given in the config file */)\ + _msg(X_DEFAULT,"(==)" /* Value is a default */)\ + _msg(X_CMDLINE,"(++)" /* Value was given on the command line */)\ + _msg(X_NOTICE,"(!!)" /* Notice */) \ + _msg(X_ERROR,"(EE)" /* Error message */) \ + _msg(X_WARNING,"(WW)" /* Warning message */) \ + _msg(X_INFO,"(II)" /* Informational message */) \ + _msg(X_UNKNOWN,"(?""?)" /* Unknown, trigraph fix */) \ + _msg(X_NONE,NULL /* No prefix */) \ + __msg(X_NOT_IMPLEMENTED,"(NI)" /* Not implemented */) + +typedef enum +{ + MESSAGE_STRINGS +} +MessageType; + + +/* + * Function prototypes + */ + +void winDrvMsgVerb (int scrnIndex, + MessageType type, int verb, const char *format, ...); +void winDrvMsg (int scrnIndex, MessageType type, const char *format, ...); +void winMsgVerb (MessageType type, int verb, const char *format, ...); +void winMsg (MessageType type, const char *format, ...); + +void winErrorFVerb (int verb, const char *format, ...); + +#endif diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c new file mode 100644 index 000000000..57d209e2a --- /dev/null +++ b/hw/xwin/winmultiwindowwindow.c @@ -0,0 +1,1574 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Kensuke Matsuzaki + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winmultiwindowwindow.c,v 1.1 2003/02/12 15:01:38 alanh Exp $ */ + +#include "win.h" +#include "dixevents.h" + + +/* + * Prototypes for local functions + */ + +static void +winCreateWindowsWindow (WindowPtr pWin); + +static void +winDestroyWindowsWindow (WindowPtr pWin); + +static void +winUpdateWindowsWindow (WindowPtr pWin); + +static XID +winGetWindowID (WindowPtr pWin); + +static void +SendConfigureNotify (WindowPtr pWin); + +static +void +winUpdateRgn (WindowPtr pWindow); + +#ifdef SHAPE +static +void +winReshape (WindowPtr pWin); +#endif + + +/* + * Local globals + */ + +static UINT s_nIDPollingMouse = 2; + +#if 0 +static BOOL s_fMoveByX = FALSE; +#endif + + +/* + * Constant defines + */ + + +#define MOUSE_POLLING_INTERVAL 500 +#define WIN_MULTIWINDOW_SHAPE YES + +/* + * Macros + */ + +#define SubSend(pWin) \ + ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask) + +#define StrSend(pWin) \ + ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask) + +#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent)) + + +/* + * CreateWindow - See Porting Layer Definition - p. 37 + */ + +Bool +winCreateWindowMultiWindow (WindowPtr pWin) +{ + Bool fResult = TRUE; + winWindowPriv(pWin); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winCreateWindowMultiWindow - pWin: %08x\n", pWin); +#endif + + /* Call any wrapped CreateWindow function */ + if (winGetScreenPriv(pWin->drawable.pScreen)->CreateWindow) + fResult = winGetScreenPriv(pWin->drawable.pScreen)->CreateWindow (pWin); + + /* Initialize some privates values */ + pWinPriv->hRgn = NULL; + pWinPriv->hWnd = NULL; + pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen); + pWinPriv->fXKilled = FALSE; + + return fResult; +} + + +/* + * DestroyWindow - See Porting Layer Definition - p. 37 + */ + +Bool +winDestroyWindowMultiWindow (WindowPtr pWin) +{ + Bool fResult = TRUE; + winWindowPriv(pWin); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winDestroyWindowMultiWindow - pWin: %08x\n", pWin); +#endif + + /* Call any wrapped DestroyWindow function */ + if (winGetScreenPriv(pWin->drawable.pScreen)->DestroyWindow) + fResult = winGetScreenPriv(pWin->drawable.pScreen)->DestroyWindow (pWin); + + /* Flag that the window has been destroyed */ + pWinPriv->fXKilled = TRUE; + + /* Kill the MS Windows window associated with this window */ + winDestroyWindowsWindow (pWin); + + return fResult; +} + + +/* + * PositionWindow - See Porting Layer Definition - p. 37 + */ + +Bool +winPositionWindowMultiWindow (WindowPtr pWin, int x, int y) +{ + Bool fResult = TRUE; + int iX, iY, iWidth, iHeight, iBorder; + winWindowPriv(pWin); + HWND hWnd = pWinPriv->hWnd; + RECT rcNew; + RECT rcOld; +#if CYGMULTIWINDOW_DEBUG + RECT rcClient; + RECT *lpRc; +#endif + DWORD dwExStyle; + DWORD dwStyle; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winPositionWindowMultiWindow - pWin: %08x\n", pWin); +#endif + + /* Call any wrapped PositionWindow function */ + if (winGetScreenPriv(pWin->drawable.pScreen)->PositionWindow) + fResult = winGetScreenPriv(pWin->drawable.pScreen)->PositionWindow (pWin, x, y); + + /* Bail out if the Windows window handle is bad */ + if (!hWnd) + return fResult; + + /* Get the Windows window style and extended style */ + dwExStyle = GetWindowLongPtr (hWnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (hWnd, GWL_STYLE); + + /* Get the width of the X window border */ + iBorder = wBorderWidth (pWin); + + /* Get the X and Y location of the X window */ + iX = pWin->drawable.x; + iY = pWin->drawable.y; + + /* Get the height and width of the X window */ + iWidth = pWin->drawable.width; + iHeight = pWin->drawable.height; + + /* Store the origin, height, and width in a rectangle structure */ + SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight); + +#if CYGMULTIWINDOW_DEBUG + lpRc = &rcNew; + ErrorF ("winPositionWindowMultiWindow - (%d ms)drawable (%d, %d)-(%d, %d)\n", + GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); +#endif + + /* + * Calculate the required size of the Windows window rectangle, + * given the size of the Windows window client area. + */ + AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle); + + /* Get a rectangle describing the old Windows window */ + GetWindowRect (hWnd, &rcOld); + +#if CYGMULTIWINDOW_DEBUG + /* Get a rectangle describing the Windows window client area */ + GetClientRect (hWnd, &rcClient); + + lpRc = &rcNew; + ErrorF ("winPositionWindowMultiWindow - (%d ms)rcNew (%d, %d)-(%d, %d)\n", + GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); + + lpRc = &rcOld; + ErrorF ("winPositionWindowMultiWindow - (%d ms)rcOld (%d, %d)-(%d, %d)\n", + GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); + + lpRc = &rcClient; + ErrorF ("(%d ms)rcClient (%d, %d)-(%d, %d)\n", + GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); +#endif + + /* Check if the old rectangle and new rectangle are the same */ + if (!EqualRect (&rcNew, &rcOld)) + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winPositionWindowMultiWindow - Need to move\n"); +#endif + + /* Change the position and dimensions of the Windows window */ + MoveWindow (hWnd, + rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, + TRUE); + } + else + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winPositionWindowMultiWindow - Not need to move\n"); +#endif + } + + return fResult; +} + + +/* + * ChangeWindowAttributes - See Porting Layer Definition - p. 37 + */ + +Bool +winChangeWindowAttributesMultiWindow (WindowPtr pWin, unsigned long mask) +{ + Bool fResult = TRUE; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winChangeWindowAttributesMultiWindow - pWin: %08x\n", pWin); +#endif + + /* Call any wrapped ChangeWindowAttributes function */ + if (winGetScreenPriv(pWin->drawable.pScreen)->ChangeWindowAttributes) + fResult = winGetScreenPriv(pWin->drawable.pScreen)->ChangeWindowAttributes (pWin, mask); + + /* + * NOTE: We do not currently need to do anything here. + */ + + return fResult; +} + + +/* + * UnmapWindow - See Porting Layer Definition - p. 37 + * Also referred to as UnrealizeWindow + */ + +Bool +winUnmapWindowMultiWindow (WindowPtr pWin) +{ + Bool fResult = TRUE; + winWindowPriv(pWin); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winUnmapWindowMultiWindow - pWin: %08x\n", pWin); +#endif + + /* Call any wrapped UnrealizeWindow function */ + if (winGetScreenPriv(pWin->drawable.pScreen)->UnrealizeWindow) + fResult = winGetScreenPriv(pWin->drawable.pScreen)->UnrealizeWindow (pWin); + + /* Flag that the window has been killed */ + pWinPriv->fXKilled = TRUE; + + /* Destroy the Windows window associated with this X window */ + winDestroyWindowsWindow (pWin); + + return fResult; +} + + +/* + * MapWindow - See Porting Layer Definition - p. 37 + * Also referred to as RealizeWindow + */ + +Bool +winMapWindowMultiWindow (WindowPtr pWin) +{ + Bool fResult = TRUE; + winWindowPriv(pWin); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winMapWindowMultiWindow - pWin: %08x\n", pWin); +#endif + + /* Call any wrapped RealizeWindow function */ + if (winGetScreenPriv(pWin->drawable.pScreen)->RealizeWindow) + fResult = winGetScreenPriv(pWin->drawable.pScreen)->RealizeWindow (pWin); + + /* Flag that this window has not been destroyed */ + pWinPriv->fXKilled = FALSE; + + /* Refresh/redisplay the Windows window associated with this X window */ + winUpdateWindowsWindow (pWin); + +#if WIN_MULTIWINDOW_SHAPE + winReshape (pWin); + winUpdateRgn (pWin); +#endif + + return fResult; +} + + +/* + * ReparentWindow - See Porting Layer Definition - p. 42 + */ + +void +winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent) +{ +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winReparentMultiWindow - pWin: %08x\n", pWin); +#endif + + /* Call any wrapped ReparentWindow function */ + if (winGetScreenPriv(pWin->drawable.pScreen)->ReparentWindow) + winGetScreenPriv(pWin->drawable.pScreen)->ReparentWindow (pWin, + pPriorParent); + + /* Update the Windows window associated with this X window */ + winUpdateWindowsWindow (pWin); +} + + +/* + * RestackWindow - Shuffle the z-order of a window + */ + +void +winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib) +{ + WindowPtr pPrevWin; + UINT uFlags; + HWND hInsertAfter; + winWindowPriv(pWin); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winRestackMultiWindow - %08x\n", pWin); +#endif + + /* Call any wrapped RestackWindow function */ + if (winGetScreenPriv(pWin->drawable.pScreen)->RestackWindow) + winGetScreenPriv(pWin->drawable.pScreen)->RestackWindow (pWin, + pOldNextSib); + + /* Bail out if no window privates or window handle is invalid */ + if (!pWinPriv || !pWinPriv->hWnd) + return; + + /* Get a pointer to our previous sibling window */ + pPrevWin = pWin->prevSib; + + /* + * Look for a sibling window with + * valid privates and window handle + */ + while (pPrevWin + && !winGetWindowPriv(pPrevWin) + && !winGetWindowPriv(pPrevWin)->hWnd) + pPrevWin = pPrevWin->prevSib; + + /* Check if we found a valid sibling */ + if (pPrevWin) + { + /* Valid sibling - get handle to insert window after */ + hInsertAfter = winGetWindowPriv(pPrevWin)->hWnd; + uFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE; + } + else + { + /* No valid sibling - make this window the top window */ + hInsertAfter = HWND_TOP; + uFlags = SWP_NOMOVE | SWP_NOSIZE; + } + + /* Perform the restacking operation in Windows */ + SetWindowPos (pWinPriv->hWnd, + hInsertAfter, + 0, 0, + 0, 0, + uFlags); +} + + +/* + * SetShape - See Porting Layer Definition - p. 42 + */ + +#ifdef SHAPE +void +winSetShapeMultiWindow (WindowPtr pWin) +{ +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winSetShapeMultiWindow - pWin: %08x\n", pWin); +#endif + + /* Call any wrapped SetShape function */ + if (winGetScreenPriv(pWin->drawable.pScreen)->SetShape) + winGetScreenPriv(pWin->drawable.pScreen)->SetShape (pWin); + + /* + * NOTE: We do not currently do anything here. + */ + +#if WIN_MULTIWINDOW_SHAPE + winReshape (pWin); + winUpdateRgn (pWin); +#endif + + return; +} +#endif + + +/* + * winUpdateRgn - Local function to update a Windows window region + */ + +static +void +winUpdateRgn (WindowPtr pWin) +{ +#if 1 + SetWindowRgn (winGetWindowPriv(pWin)->hWnd, + winGetWindowPriv(pWin)->hRgn, TRUE); +#endif +} + + +/* + * winReshape - Computes the composite clipping region for a window + */ + +#ifdef SHAPE +static +void +winReshape (WindowPtr pWin) +{ + int nRects; + ScreenPtr pScreen = pWin->drawable.pScreen; + RegionRec rrNewShape; + BoxPtr pShape, pRects, pEnd; + HRGN hRgn, hRgnRect; + winWindowPriv(pWin); + +#if CYGDEBUG + ErrorF ("winReshape ()\n"); +#endif + + /* Bail if the window is the root window */ + if (pWin->parent == NULL) + return; + + /* Bail if the window is not top level */ + if (pWin->parent->parent != NULL) + return; + + /* Bail if Windows window handle is invalid */ + if (pWinPriv->hWnd == NULL) + return; + + /* Free any existing window region stored in the window privates */ + if (pWinPriv->hRgn != NULL) + { + DeleteObject (pWinPriv->hRgn); + pWinPriv->hRgn = NULL; + } + + /* Bail if the window has no bounding region defined */ + if (!wBoundingShape (pWin)) + return; + + REGION_INIT(pScreen, &rrNewShape, NullBox, 0); + REGION_COPY(pScreen, &rrNewShape, wBoundingShape(pWin)); + REGION_TRANSLATE(pScreen, + &rrNewShape, + pWin->borderWidth, + pWin->borderWidth); + + nRects = REGION_NUM_RECTS(&rrNewShape); + pShape = REGION_RECTS(&rrNewShape); + + /* Don't do anything if there are no rectangles in the region */ + if (nRects > 0) + { + RECT rcClient; + RECT rcWindow; + int iOffsetX, iOffsetY; + + /* Get client rectangle */ + if (!GetClientRect (pWinPriv->hWnd, &rcClient)) + { + ErrorF ("winReshape - GetClientRect failed, bailing: %d\n", + GetLastError ()); + return; + } + + /* Translate client rectangle coords to screen coords */ + /* NOTE: Only transforms top and left members */ + ClientToScreen (pWinPriv->hWnd, (LPPOINT) &rcClient); + + /* Get window rectangle */ + if (!GetWindowRect (pWinPriv->hWnd, &rcWindow)) + { + ErrorF ("winReshape - GetWindowRect failed, bailing: %d\n", + GetLastError ()); + return; + } + + /* Calculate offset from window upper-left to client upper-left */ + iOffsetX = rcClient.left - rcWindow.left; + iOffsetY = rcClient.top - rcWindow.top; + + /* Create initial Windows region for title bar */ + /* FIXME: Mean, nasty, ugly hack!!! */ + hRgn = CreateRectRgn (0, 0, rcWindow.right, iOffsetY); + if (hRgn == NULL) + { + ErrorF ("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) " + "failed: %d\n", + 0, 0, rcWindow.right, iOffsetY, GetLastError ()); + } + + /* Loop through all rectangles in the X region */ + for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++) + { + /* Create a Windows region for the X rectangle */ + hRgnRect = CreateRectRgn (pRects->x1 + iOffsetX - 1, + pRects->y1 + iOffsetY - 1, + pRects->x2 + iOffsetX - 1, + pRects->y2 + iOffsetY - 1); + if (hRgnRect == NULL) + { + ErrorF ("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) " + "failed: %d\n" + "\tx1: %d x2: %d xOff: %d y1: %d y2: %d yOff: %d\n", + pRects->x1 + iOffsetX - 1, + pRects->y1 + iOffsetY - 1, + pRects->x2 + iOffsetX - 1, + pRects->y2 + iOffsetY - 1, + GetLastError (), + pRects->x1, pRects->x2, iOffsetX, + pRects->y1, pRects->y2, iOffsetY); + } + + /* Merge the Windows region with the accumulated region */ + if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) + { + ErrorF ("winReshape - CombineRgn () failed: %d\n", + GetLastError ()); + } + + /* Delete the temporary Windows region */ + DeleteObject (hRgnRect); + } + + /* Save a handle to the composite region in the window privates */ + pWinPriv->hRgn = hRgn; + } + + REGION_UNINIT(pScreen, &rrNewShape); + + return; +} +#endif + + +/* + * winTopLevelWindowProc - Window procedure for all top-level Windows windows. + */ + +LRESULT CALLBACK +winTopLevelWindowProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam) +{ + POINT ptMouse; + HDC hdcUpdate; + PAINTSTRUCT ps; + WindowPtr pWin = NULL; + winPrivWinPtr pWinPriv = NULL; + ScreenPtr s_pScreen = NULL; + winPrivScreenPtr s_pScreenPriv = NULL; + winScreenInfo *s_pScreenInfo = NULL; + HWND hwndScreen = NULL; + DrawablePtr pDraw = NULL; + int iX, iY, iWidth, iHeight, iBorder; + winWMMessageRec wmMsg; + static Bool s_fTracking = FALSE; + static Bool s_fCursor = TRUE; + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pWin = GetProp (hwnd, WIN_WINDOW_PROP)) != NULL) + { + /* Our X window pointer is valid */ + + /* Get pointers to the drawable and the screen */ + pDraw = &pWin->drawable; + s_pScreen = pWin->drawable.pScreen; + + /* Get a pointer to our window privates */ + pWinPriv = winGetWindowPriv(pWin); + + /* Get pointers to our screen privates and screen info */ + s_pScreenPriv = pWinPriv->pScreenPriv; + s_pScreenInfo = s_pScreenPriv->pScreenInfo; + + /* Get the handle for our screen-sized window */ + /* NOTE: This will be going away at some point, right? Harold Hunt - 2003/01/15 */ + hwndScreen = s_pScreenPriv->hwndScreen; + + /* */ + wmMsg.msg = 0; + wmMsg.hwndWindow = hwnd; + wmMsg.iWindow = (Window)GetProp (hwnd, WIN_WID_PROP); + +#if 1 + wmMsg.iX = pWinPriv->iX; + wmMsg.iY = pWinPriv->iY; + wmMsg.iWidth = pWinPriv->iWidth; + wmMsg.iHeight = pWinPriv->iHeight; +#else + wmMsg.iX = pDraw.x; + wmMsg.iY = pDraw.y; + wmMsg.iWidth = pDraw.width; + wmMsg.iHeight = pDraw.height; +#endif + + +#if 0 + /* + * Print some debugging information + */ + + ErrorF ("hWnd %08X\n", hwnd); + ErrorF ("pWin %08X\n", pWin); + ErrorF ("pDraw %08X\n", pDraw); + ErrorF ("\ttype %08X\n", pWin->drawable.type); + ErrorF ("\tclass %08X\n", pWin->drawable.class); + ErrorF ("\tdepth %08X\n", pWin->drawable.depth); + ErrorF ("\tbitsPerPixel %08X\n", pWin->drawable.bitsPerPixel); + ErrorF ("\tid %08X\n", pWin->drawable.id); + ErrorF ("\tx %08X\n", pWin->drawable.x); + ErrorF ("\ty %08X\n", pWin->drawable.y); + ErrorF ("\twidth %08X\n", pWin->drawable.width); + ErrorF ("\thenght %08X\n", pWin->drawable.height); + ErrorF ("\tpScreen %08X\n", pWin->drawable.pScreen); + ErrorF ("\tserialNumber %08X\n", pWin->drawable.serialNumber); + ErrorF ("g_iWindowPrivateIndex %d\n", g_iWindowPrivateIndex); + ErrorF ("pWinPriv %08X\n", pWinPriv); + ErrorF ("s_pScreenPriv %08X\n", s_pScreenPriv); + ErrorF ("s_pScreenInfo %08X\n", s_pScreenInfo); + ErrorF ("hwndScreen %08X\n", hwndScreen); +#endif + } + + + + /* Branch on message type */ + switch (message) + { + case WM_CREATE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_CREATE\n"); +#endif + + /* */ + SetProp (hwnd, + WIN_WINDOW_PROP, + (HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams); + + /* */ + SetProp (hwnd, + WIN_WID_PROP, + (HANDLE)winGetWindowID (((LPCREATESTRUCT) lParam)->lpCreateParams)); + return 0; + + case WM_PAINT: + /* Only paint if our window handle is valid */ + if (hwndScreen == NULL) + break; + + /* BeginPaint gives us an hdc that clips to the invalidated region */ + hdcUpdate = BeginPaint (hwnd, &ps); + +#if 0 + /* NOTE: Doesn't appear to be used - Harold Hunt - 2003/01/15 */ + /* Get the dimensions of the client area */ + GetClientRect (hwnd, &rcClient); +#endif + + /* Get the position and dimensions of the window */ + iBorder = wBorderWidth (pWin); + iX = pWin->drawable.x; + iY = pWin->drawable.y; + iWidth = pWin->drawable.width; + iHeight = pWin->drawable.height; + + /* Try to copy from the shadow buffer */ + if (!BitBlt (hdcUpdate, + 0, 0, + iWidth, iHeight, + s_pScreenPriv->hdcShadow, + iX, iY, + SRCCOPY)) + { + LPVOID lpMsgBuf; + + /* Display a fancy error message */ + FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError (), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, NULL); + + ErrorF ("winTopLevelWindowProc - BitBlt failed: %s\n", + (LPSTR)lpMsgBuf); + LocalFree (lpMsgBuf); + } + + /* EndPaint frees the DC */ + EndPaint (hwndScreen, &ps); + return 0; + + +#if 1 + case WM_MOUSEMOVE: + /* Unpack the client area mouse coordinates */ + ptMouse.x = GET_X_LPARAM(lParam); + ptMouse.y = GET_Y_LPARAM(lParam); + + /* Translate the client area mouse coordinates to screen coordinates */ + ClientToScreen (hwnd, &ptMouse); + + /* We can't do anything without privates */ + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* Has the mouse pointer crossed screens? */ + if (s_pScreen != miPointerCurrentScreen ()) + miPointerSetNewScreen (s_pScreenInfo->dwScreen, + ptMouse.x - s_pScreenInfo->dwXOffset, + ptMouse.y - s_pScreenInfo->dwYOffset); + + /* Are we tracking yet? */ + if (!s_fTracking) + { + TRACKMOUSEEVENT tme; + + /* Setup data structure */ + ZeroMemory (&tme, sizeof (tme)); + tme.cbSize = sizeof (tme); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = hwnd; + + /* Call the tracking function */ + if (!(*g_fpTrackMouseEvent) (&tme)) + ErrorF ("winTopLevelWindowProc - _TrackMouseEvent failed\n"); + + /* Flag that we are tracking now */ + s_fTracking = TRUE; + } + + /* Hide or show the Windows mouse cursor */ + if (s_fCursor) + { + /* Hide Windows cursor */ + s_fCursor = FALSE; + ShowCursor (FALSE); + KillTimer (hwnd, s_nIDPollingMouse); + } + + /* Deliver absolute cursor position to X Server */ + miPointerAbsoluteCursor (ptMouse.x - s_pScreenInfo->dwXOffset, + ptMouse.y - s_pScreenInfo->dwYOffset, + g_c32LastInputEventTime = GetTickCount ()); + return 0; + + case WM_NCMOUSEMOVE: + /* + * We break instead of returning 0 since we need to call + * DefWindowProc to get the mouse cursor changes + * and min/max/close button highlighting in Windows XP. + * The Platform SDK says that you should return 0 if you + * process this message, but it fails to mention that you + * will give up any default functionality if you do return 0. + */ + + /* We can't do anything without privates */ + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* Non-client mouse movement, show Windows cursor */ + if (!s_fCursor) + { + s_fCursor = TRUE; + ShowCursor (TRUE); + SetTimer (hwnd, s_nIDPollingMouse, MOUSE_POLLING_INTERVAL, NULL); + } + break; + + case WM_MOUSELEAVE: + /* Mouse has left our client area */ + + /* Flag that we are no longer tracking */ + s_fTracking = FALSE; + + /* Show the mouse cursor, if necessary */ + if (!s_fCursor) + { + s_fCursor = TRUE; + ShowCursor (TRUE); + SetTimer (hwnd, s_nIDPollingMouse, MOUSE_POLLING_INTERVAL, NULL); + } + return 0; + + case WM_LBUTTONDBLCLK: + case WM_LBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam); + + case WM_LBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam); + + case WM_MBUTTONDBLCLK: + case WM_MBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam); + + case WM_MBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam); + + case WM_RBUTTONDBLCLK: + case WM_RBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam); + + case WM_RBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam); + +#else + + case WM_MOUSEMOVE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_MOUSEMOVE*\n"); +#endif + + /* Unpack the client area mouse coordinates */ + ptMouse.x = GET_X_LPARAM(lParam); + ptMouse.y = GET_Y_LPARAM(lParam); + + /* Translate the client area mouse coordinates to screen coordinates */ + ClientToScreen (hwnd, &ptMouse); + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, MAKELONG(ptMouse.x, ptMouse.y)); + return 0; + + case WM_NCMOUSEMOVE: + case WM_LBUTTONDBLCLK: + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_MBUTTONDBLCLK: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_RBUTTONDBLCLK: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + case WM_MOUSELEAVE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_*BUTTON*\n"); +#endif + + /* Pass the message to the root window */ + SendMessage(hwndScreen, message, wParam, MAKELONG(ptMouse.x, ptMouse.y)); + return 0; +#endif + + case WM_MOUSEWHEEL: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_MOUSEWHEEL\n"); +#endif + + /* Pass the message to the root window */ + SendMessage(hwndScreen, message, wParam, lParam); + return 0; + + case WM_SYSKEYDOWN: + case WM_SYSKEYUP: + case WM_SYSDEADCHAR: + case WM_KEYDOWN: + case WM_KEYUP: + case WM_DEADCHAR: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_*KEY*\n"); +#endif + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; + + case WM_HOTKEY: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_HOTKEY\n"); +#endif + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; + + +#if 1 + case WM_ACTIVATE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_ACTIVATE\n"); +#endif + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + + /* Bail if inactivating */ + if (LOWORD(wParam) == WA_INACTIVE) + return 0; + + /* Check if the current window is the active window in Windows */ + if (GetActiveWindow () == hwnd) + { + /* Tell our Window Manager thread to raise the window */ + wmMsg.msg = WM_WM_RAISE; + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + } + + /* Tell our Window Manager thread to activate the window */ + wmMsg.msg = WM_WM_ACTIVATE; + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + + return 0; + + case WM_ACTIVATEAPP: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_ACTIVATEAPP\n"); +#endif + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; +#endif + + + case WM_CLOSE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_CLOSE\n"); +#endif + /* Branch on if the window was killed in X already */ + if (pWinPriv->fXKilled) + { + /* Window was killed, go ahead and destroy the window */ + DestroyWindow (hwnd); + } + else + { + /* Tell our Window Manager thread to kill the window */ + wmMsg.msg = WM_WM_KILL; + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + } + return 0; + + case WM_DESTROY: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_DESTROY\n"); +#endif + + /* Branch on if the window was killed in X already */ + if (pWinPriv && !pWinPriv->fXKilled) + { + ErrorF ("winTopLevelWindowProc - WM_DESTROY - WM_WM_KILL\n"); + + /* Tell our Window Manager thread to kill the window */ + wmMsg.msg = WM_WM_KILL; + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + } + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_DESTROY\n"); +#endif + break; + + case WM_MOVE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_MOVE - %d ms\n", GetTickCount ()); +#endif + + /* Bail if Windows window is not actually moving */ + if (pWinPriv->iX == (short) LOWORD(lParam) + && pWinPriv->iY == (short) HIWORD(lParam)) + break; + + /* Get new position */ + pWinPriv->iX = (short) LOWORD(lParam); + pWinPriv->iY = (short) HIWORD(lParam); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\t(%d, %d)\n", pWinPriv->iX, pWinPriv->iY); +#endif + + /* Notify the X client that its window is moving */ + if (SubStrSend(pWin, pWin->parent)) + SendConfigureNotify (pWin); + + /* Tell X that the window is moving */ + (s_pScreen->MoveWindow) (pWin, + (int)(short) LOWORD(lParam) - wBorderWidth (pWin), + (int)(short) HIWORD(lParam) - wBorderWidth (pWin), + pWin->nextSib, + VTMove); + return 0; + + case WM_SHOWWINDOW: + /* Bail out if the window is being hidden */ + if (!wParam) + return 0; + + /* Tell X to map the window */ + MapWindow (pWin, wClient(pWin)); + + /* */ + if (!pWin->overrideRedirect) + { + DWORD dwExStyle; + DWORD dwStyle; + RECT rcNew; + int iDx, iDy; + + /* Flag that this window needs to be made active when clicked */ + SetProp (hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1); + + /* Get the standard and extended window style information */ + dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE); + + /* */ + if (dwExStyle != WS_EX_APPWINDOW) + { + /* Setup a rectangle with the X window position and size */ + SetRect (&rcNew, + pWinPriv->iX, + pWinPriv->iY, + pWinPriv->iX + pWinPriv->iWidth, + pWinPriv->iY + pWinPriv->iHeight); + +#if 0 + ErrorF ("winTopLevelWindowProc - (%d, %d)-(%d, %d)\n", + rcNew.left, rcNew.top, + rcNew.right, rcNew.bottom); +#endif + + /* */ + AdjustWindowRectEx (&rcNew, + WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW, + FALSE, + WS_EX_APPWINDOW); + + /* Calculate position deltas */ + iDx = pWinPriv->iX - rcNew.left; + iDy = pWinPriv->iY - rcNew.top; + + /* Calculate new rectangle */ + rcNew.left += iDx; + rcNew.right += iDx; + rcNew.top += iDy; + rcNew.bottom += iDy; + +#if 0 + ErrorF ("winTopLevelWindowProc - (%d, %d)-(%d, %d)\n", + rcNew.left, rcNew.top, + rcNew.right, rcNew.bottom); +#endif + + /* Set the window extended style flags */ + SetWindowLongPtr (hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW); + + /* Set the window standard style flags */ + SetWindowLongPtr (hwnd, GWL_STYLE, WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW); + + /* Positon the Windows window */ + SetWindowPos (hwnd, HWND_TOP, + rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, + SWP_NOMOVE | SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE); + + /* Bring the Window window to the foreground */ + SetForegroundWindow (hwnd); + } + } + + /* Setup the Window Manager message */ + wmMsg.msg = WM_WM_MAP; + wmMsg.iWidth = pWinPriv->iWidth; + wmMsg.iHeight = pWinPriv->iHeight; + + /* Tell our Window Manager thread to map the window */ + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + + /* Setup the Window Manager message */ + wmMsg.msg = WM_WM_RAISE; + + /* Tell our Window Manager thread to raise the window */ + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + return 0; + + case WM_SIZE: + /* see dix/window.c */ + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_SIZE - %d ms\n", GetTickCount ()); +#endif + + switch (wParam) + { + case SIZE_MINIMIZED: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tSIZE_MINIMIZED\n"); +#endif + + wmMsg.msg = WM_WM_LOWER; + + /* Tell our Window Manager thread to lower the window */ + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + break; + + case SIZE_RESTORED: + case SIZE_MAXIMIZED: + if (pWinPriv->iWidth == (short) LOWORD(lParam) + && pWinPriv->iHeight == (short) HIWORD(lParam)) + break; + + /* Get the dimensions of the Windows window */ + pWinPriv->iWidth = (short) LOWORD(lParam); + pWinPriv->iHeight = (short) HIWORD(lParam); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\t(%d, %d)\n", pWinPriv->iWidth, pWinPriv->iHeight); +#endif + + /* Check if resize events are redirected */ + if ((pWin->eventMask | wOtherEventMasks (pWin)) & ResizeRedirectMask) + { + xEvent eventT; + + /* Setup the X event structure */ + eventT.u.u.type = ResizeRequest; + eventT.u.resizeRequest.window = pWin->drawable.id; + eventT.u.resizeRequest.width = pWinPriv->iWidth; + eventT.u.resizeRequest.height = pWinPriv->iHeight; + + /* */ + if (MaybeDeliverEventsToClient (pWin, &eventT, 1, + ResizeRedirectMask, + wClient(pWin)) == 1) + break; + } + + /* Notify the X client that its window is being resized */ + if (SubStrSend (pWin, pWin->parent)) + SendConfigureNotify (pWin); + + /* Tell the X server that the window is being resized */ + (s_pScreen->ResizeWindow) (pWin, + pWinPriv->iX - wBorderWidth (pWin), + pWinPriv->iY - wBorderWidth (pWin), + pWinPriv->iWidth, + pWinPriv->iHeight, + pWin->nextSib); + + /* Tell X to redraw the exposed portions of the window */ + { + RegionRec temp; + + /* Get the region describing the X window clip list */ + REGION_INIT(s_pScreen, &temp, NullBox, 0); + REGION_COPY(s_pScreen, &temp, &pWin->clipList); + + /* Expose the clipped region */ + (*s_pScreen->WindowExposures) (pWin, &temp, NullRegion); + + /* Free the region */ + REGION_UNINIT(s_pScreen, &temp); + } + break; + +#if 0 + case SIZE_MAXIMIZED: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tSIZE_MAXIMIZED\n"); +#endif + + /* Get the dimensions of the window */ + pWinPriv->iWidth = (int)(short) LOWORD(lParam); + pWinPriv->iHeight = (int)(short) HIWORD(lParam); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\t(%d, %d)\n", pWinPriv->iWidth, pWinPriv->iHeight); +#endif + + /* */ + if ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask) + { + xEvent eventT; + + eventT.u.u.type = ResizeRequest; + eventT.u.resizeRequest.window = pWin->drawable.id; + eventT.u.resizeRequest.width = pWinPriv->iWidth; + eventT.u.resizeRequest.height = pWinPriv->iHeight; + if (MaybeDeliverEventsToClient (pWin, &eventT, 1, + ResizeRedirectMask, + wClient(pWin)) == 1); + } + + + (s_pScreen->ResizeWindow) (pWin, + pWinPriv->iX - wBorderWidth (pWin), + pWinPriv->iY - wBorderWidth (pWin), + pWinPriv->iWidth, + pWinPriv->iHeight, + pWin->nextSib); + break; +#endif + + default: + break; + } + return 0; + + case WM_MOUSEACTIVATE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_MOUSEACTIVATE\n"); +#endif + + /* Check if this window needs to be made active when clicked */ + if (!GetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP)) + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_MOUSEACTIVATE - MA_NOACTIVATE\n"); +#endif + + /* */ + return MA_NOACTIVATE; + } + break; + + case WM_TIMER: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_TIMER - %d ms\n", GetTickCount ()); +#endif + + /* Branch on the type of timer event that fired */ + if (wParam == s_nIDPollingMouse) + { + POINT point; + + /* Get the current position of the mouse cursor */ + GetCursorPos (&point); + + /* Deliver absolute cursor position to X Server */ + miPointerAbsoluteCursor (point.x, point.y, + g_c32LastInputEventTime = GetTickCount ()); + } + else + { + ErrorF ("winTopLevelWindowProc - Unknown WM_TIMER\n"); + } + return 0; + + default: + break; + } + + return DefWindowProc (hwnd, message, wParam, lParam); +} + + +/* + * winCreateWindowsWindow - Create a Windows window associated with an X window + */ + +static void +winCreateWindowsWindow (WindowPtr pWin) +{ + int iX, iY; + int iWidth; + int iHeight; + int iBorder; + HWND hWnd; + WNDCLASS wc; + winWindowPriv(pWin); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin); +#endif + + iBorder = wBorderWidth (pWin); + + iX = pWin->drawable.x; + iY = pWin->drawable.y; + + iWidth = pWin->drawable.width; + iHeight = pWin->drawable.height; + + /* Setup our window class */ + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = winTopLevelWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = g_hInstance; + wc.hIcon = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN)); + wc.hCursor = 0; + wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = WINDOW_CLASS_X; + RegisterClass (&wc); + + /* Create the window */ + hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */ + WINDOW_CLASS_X, /* Class name */ + WINDOW_TITLE_X, /* Window name */ + WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, + iX, /* Horizontal position */ + iY, /* Vertical position */ + iWidth, /* Right edge */ + iHeight, /* Bottom edge */ + (HWND) NULL, /* No parent or owner window */ + (HMENU) NULL, /* No menu */ + GetModuleHandle (NULL), /* Instance handle */ + pWin); /* ScreenPrivates */ + if (hWnd == NULL) + { + ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n", + GetLastError ()); + } + + pWinPriv->hWnd = hWnd; + + + SetProp (pWinPriv->hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin)); + + /* Flag that this Windows window handles its own activation */ + SetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0); +} + + +/* + * winDestroyWindowsWindow - Destroy a Windows window associated with an X window + */ + +static void +winDestroyWindowsWindow (WindowPtr pWin) +{ + MSG msg; + winWindowPriv(pWin); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winDestroyWindowsWindow\n"); +#endif + + + /* Bail out if the Windows window handle is invalid */ + if (pWinPriv->hWnd == NULL) + return; + + + SetProp (pWinPriv->hWnd, WIN_WINDOW_PROP, 0); + + DestroyWindow (pWinPriv->hWnd); + + pWinPriv->hWnd = NULL; + + /* Process all messages on our queue */ + while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + { + if (g_hDlgDepthChange == 0 || !IsDialogMessage (g_hDlgDepthChange, &msg)) + { + DispatchMessage (&msg); + } + } + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("-winDestroyWindowsWindow\n"); +#endif +} + + +/* + * winUpdateWindowsWindow - Redisplay/redraw a Windows window associated with an X window + */ + +static void +winUpdateWindowsWindow (WindowPtr pWin) +{ + winWindowPriv(pWin); + HWND hWnd = pWinPriv->hWnd; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winUpdateWindowsWindow\n"); +#endif + + /* Check if the Windows window's parents have been destroyed */ + if (pWin->parent != NULL + && pWin->parent->parent == NULL + && pWin->mapped) + { + /* Create the Windows window if it has been destroyed */ + if (hWnd == NULL) + { + winCreateWindowsWindow (pWin); + assert (pWinPriv->hWnd != NULL); + } + + /* Display the window without activating it */ + ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE); + + /* Send first paint message */ + UpdateWindow (pWinPriv->hWnd); + } + else if (hWnd != NULL) + { + /* Destroy the Windows window if its parents are destroyed */ + winDestroyWindowsWindow (pWin); + assert (pWinPriv->hWnd == NULL); + } + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("-winUpdateWindowsWindow\n"); +#endif +} + + + + + + + + +typedef struct { + pointer value; + XID id; +} WindowIDPairRec, *WindowIDPairPtr; + + + + + +/* + * winFindWindow - + */ + +static void +winFindWindow (pointer value, XID id, pointer cdata) +{ + WindowIDPairPtr wi = (WindowIDPairPtr)cdata; + + if (value == wi->value) + { + wi->id = id; + } +} + + +/* + * winGetWindowID - + */ + +static XID +winGetWindowID (WindowPtr pWin) +{ + WindowIDPairRec wi = {pWin, 0}; + ClientPtr c = wClient(pWin); + + /* */ + FindClientResourcesByType (c, RT_WINDOW, winFindWindow, &wi); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winGetWindowID - Window ID: %d\n", wi.id); +#endif + + return wi.id; +} + + +/* + * SendConfigureNotify - + */ + +static void +SendConfigureNotify(WindowPtr pWin) +{ + xEvent event; + winWindowPriv(pWin); + + event.u.u.type = ConfigureNotify; + event.u.configureNotify.window = pWin->drawable.id; + + if (pWin->nextSib) + event.u.configureNotify.aboveSibling = pWin->nextSib->drawable.id; + else + event.u.configureNotify.aboveSibling = None; + + event.u.configureNotify.x = pWinPriv->iX - wBorderWidth (pWin); + event.u.configureNotify.y = pWinPriv->iY - wBorderWidth (pWin); + + event.u.configureNotify.width = pWinPriv->iWidth; + event.u.configureNotify.height = pWinPriv->iHeight; + + event.u.configureNotify.borderWidth = wBorderWidth (pWin); + + event.u.configureNotify.override = pWin->overrideRedirect; + + /* */ + DeliverEvents (pWin, &event, 1, NullWindow); +} diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c new file mode 100644 index 000000000..ab4dd27f6 --- /dev/null +++ b/hw/xwin/winmultiwindowwm.c @@ -0,0 +1,907 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Kensuke Matsuzaki + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winmultiwindowwm.c,v 1.1 2003/02/12 15:01:38 alanh Exp $ */ + +/* X headers */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Fixups to prevent collisions between Windows and X headers */ +#define ATOM DWORD + +/* Windows headers */ +#include + +/* Local headers */ +#include "winwindow.h" + + +/* + * Constant defines + */ + +#define WIN_CONNECT_RETRIES 5 +#define WIN_CONNECT_DELAY 5 +#define WIN_MSG_QUEUE_FNAME "/dev/windows" +#define WM_WM_X_EVENT 1 +#define WIN_JMP_OKAY 0 +#define WIN_JMP_ERROR_IO 2 + + +/* + * Local structures + */ + +typedef struct _WMMsgNodeRec { + winWMMessageRec msg; + struct _WMMsgNodeRec *pNext; +} WMMsgNodeRec, *WMMsgNodePtr; + +typedef struct _WMMsgQueueRec { + struct _WMMsgNodeRec *pHead; + struct _WMMsgNodeRec *pTail; + pthread_mutex_t pmMutex; + pthread_cond_t pcNotEmpty; +} WMMsgQueueRec, *WMMsgQueuePtr; + +typedef struct _WMInfo { + Display *pDisplay; + WMMsgQueueRec wmMsgQueue; + Atom atmWmProtos; + Atom atmWmDelete; +} WMInfoRec, *WMInfoPtr; + +typedef struct _WMProcArgRec { + DWORD dwScreen; + WMInfoPtr pWMInfo; + pthread_mutex_t *ppmServerStarted; +} WMProcArgRec, *WMProcArgPtr; + + +/* + * References to external symbols + */ + +extern char *display; +extern void ErrorF (const char* /*f*/, ...); +extern Bool g_fCalledSetLocale; + + +/* + * Prototypes for local functions + */ + +static void +PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode); + +static WMMsgNodePtr +PopMessage (WMMsgQueuePtr pQueue); + +static Bool +InitQueue (WMMsgQueuePtr pQueue); + +static void +GetWindowName (Display * pDpy, Window iWin, char **ppName); + +static int +SendXMessage (Display *pDisplay, Window iWin, Atom atmType, long nData); + +static void* +winMultiWindowWMProc (void* pArg); + +static Bool +FlushXEvents (WMInfoPtr pWMInfo); + +static int +winMultiWindowWMErrorHandler (Display *pDisp, XErrorEvent *e); + +static void +winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg); + +static int +winMutliWindowWMIOErrorHandler (Display *pDisplay); + + +/* + * Local globals + */ + +static int g_nQueueSize; +static jmp_buf g_jmpEntry; + + + +/* + * PushMessage - Push a message onto the queue + */ + +static void +PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode) +{ + + /* Lock the queue mutex */ + pthread_mutex_lock (&pQueue->pmMutex); + + pNode->pNext = NULL; + + if (pQueue->pTail != NULL) + { + pQueue->pTail->pNext = pNode; + } + pQueue->pTail = pNode; + + if (pQueue->pHead == NULL) + { + pQueue->pHead = pNode; + } + + +#if 0 + switch (pNode->msg.msg) + { + case WM_WM_MOVE: + ErrorF ("\tWM_WM_MOVE\n"); + break; + case WM_WM_RAISE: + ErrorF ("\tWM_WM_RAISE\n"); + break; + case WM_WM_LOWER: + ErrorF ("\tWM_WM_RAISE\n"); + break; + case WM_WM_MAP: + ErrorF ("\tWM_WM_MAP\n"); + break; + case WM_WM_UNMAP: + ErrorF ("\tWM_WM_UNMAP\n"); + break; + case WM_WM_KILL: + ErrorF ("\tWM_WM_KILL\n"); + break; + default: + ErrorF ("Unknown Message.\n"); + break; + } +#endif + + /* Increase the count of elements in the queue by one */ + ++g_nQueueSize; + + /* Release the queue mutex */ + pthread_mutex_unlock (&pQueue->pmMutex); + + /* Signal that the queue is not empty */ + pthread_cond_signal (&pQueue->pcNotEmpty); +} + + +#if 0 +/* + * QueueSize - Return the size of the queue + */ + +static int +QueueSize (WMMsgQueuePtr pQueue) +{ + WMMsgNodePtr pNode; + int nSize = 0; + + /* Loop through all elements in the queue */ + for (pNode = pQueue->pHead; pNode != NULL; pNode = pNode->pNext) + ++nSize; + + return nSize; +} +#endif + + +/* + * PopMessage - + */ + +static WMMsgNodePtr +PopMessage (WMMsgQueuePtr pQueue) +{ + WMMsgNodePtr pNode; + + /* Lock the queue mutex */ + pthread_mutex_lock (&pQueue->pmMutex); + + /* Wait for --- */ + while (pQueue->pHead == NULL) + { + pthread_cond_wait (&pQueue->pcNotEmpty, &pQueue->pmMutex); + } + + pNode = pQueue->pHead; + if (pQueue->pHead != NULL) + { + pQueue->pHead = pQueue->pHead->pNext; + } + + if (pQueue->pTail == pNode) + { + pQueue->pTail = NULL; + } + + /* Drop the number of elements in the queue by one */ + --g_nQueueSize; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("Queue Size %d %d\n", g_nQueueSize, QueueSize(pQueue)); +#endif + + /* Release the queue mutex */ + pthread_mutex_unlock (&pQueue->pmMutex); + + return pNode; +} + + +#if 0 +/* + * HaveMessage - + */ + +static Bool +HaveMessage (WMMsgQueuePtr pQueue, UINT msg, Window iWindow) +{ + WMMsgNodePtr pNode; + + for (pNode = pQueue->pHead; pNode != NULL; pNode = pNode->pNext) + { + if (pNode->msg.msg==msg && pNode->msg.iWindow==iWindow) + return True; + } + + return False; +} +#endif + + +/* + * InitQueue - Initialize the Window Manager message queue + */ + +static +Bool +InitQueue (WMMsgQueuePtr pQueue) +{ + /* Check if the pQueue pointer is NULL */ + if (pQueue == NULL) + { + ErrorF ("InitQueue - pQueue is NULL. Exiting.\n"); + return FALSE; + } + + /* Set the head and tail to NULL */ + pQueue->pHead = NULL; + pQueue->pTail = NULL; + + /* There are no elements initially */ + g_nQueueSize = 0; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("InitQueue - Queue Size %d %d\n", g_nQueueSize, QueueSize(pQueue)); +#endif + + ErrorF ("InitQueue - Calling pthread_mutex_init\n"); + + /* Create synchronization objects */ + pthread_mutex_init (&pQueue->pmMutex, NULL); + + ErrorF ("InitQueue - pthread_mutex_init returned\n"); + ErrorF ("InitQueue - Calling pthread_cond_init\n"); + + pthread_cond_init (&pQueue->pcNotEmpty, NULL); + + ErrorF ("InitQueue - pthread_cond_init returned\n"); + + return TRUE; +} + + +/* + * GetWindowName - + */ + +static void +GetWindowName (Display *pDisplay, Window iWin, char **ppName) +{ + int nResult, nNum; + char **ppList; + XTextProperty xtpName; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("GetWindowName\n"); +#endif + + /* Intialize ppName to NULL */ + *ppName = NULL; + + /* Try to get --- */ + nResult = XGetWMName (pDisplay, iWin, &xtpName); + if (!nResult || !xtpName.value || !xtpName.nitems) + { + ErrorF ("GetWindowName - XGetWMName failed. No name.\n"); + return; + } + + /* */ + if (xtpName.encoding == XA_STRING) + { + /* */ + if (xtpName.value) + { + *ppName = strdup ((char*)xtpName.value); + XFree (xtpName.value); + } + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("XA_STRING %s\n", *ppName); +#endif + } + else + { + XmbTextPropertyToTextList (pDisplay, &xtpName, &ppList, &nNum); + + /* */ + if (nNum && *ppList) + { + XFree (xtpName.value); + *ppName = strdup (*ppList); + XFreeStringList (ppList); + } + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("%s %s\n", XGetAtomName (pDisplay, xtpName.encoding), *ppName); +#endif + } + + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("-GetWindowName\n"); +#endif +} + + +/* + * Send a message to the X server from the WM thread + */ + +static int +SendXMessage (Display *pDisplay, Window iWin, Atom atmType, long nData) +{ + XEvent e; + + /* Prepare the X event structure */ + e.type = ClientMessage; + e.xclient.window = iWin; + e.xclient.message_type = atmType; + e.xclient.format = 32; + e.xclient.data.l[0] = nData; + e.xclient.data.l[1] = CurrentTime; + + /* Send the event to X */ + return XSendEvent (pDisplay, iWin, False, NoEventMask, &e); +} + + +/* + * winMultiWindowWMProc + */ + +static void * +winMultiWindowWMProc (void *pArg) +{ + WMProcArgPtr pProcArg = (WMProcArgPtr)pArg; + WMInfoPtr pWMInfo = pProcArg->pWMInfo; + + /* Initialize the Window Manager */ + winInitMultiWindowWM (pWMInfo, pProcArg); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winMultiWindowWMProc ()\n"); +#endif + + /* Loop until we explicity break out */ + for (;;) + { + WMMsgNodePtr pNode; + + /* Pop a message off of our queue */ + pNode = PopMessage (&pWMInfo->wmMsgQueue); + if (pNode == NULL) + { + /* Bail if PopMessage returns without a message */ + /* NOTE: Remember that PopMessage is a blocking function. */ + ErrorF ("winMultiWindowWMProc - Queue is Empty?\n"); + pthread_exit (NULL); + } + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winMultiWindowWMProc - %d ms MSG: %d ID: %d\n", + GetTickCount (), (int)pNode->msg.msg, (int)pNode->msg.dwID); +#endif + + /* Branch on the message type */ + switch (pNode->msg.msg) + { +#if 0 + case WM_WM_MOVE: + ErrorF ("\tWM_WM_MOVE\n"); + break; + + case WM_WM_SIZE: + ErrorF ("\tWM_WM_SIZE\n"); + break; +#endif + + case WM_WM_RAISE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_RAISE\n"); +#endif + + /* Raise the window */ + XRaiseWindow (pWMInfo->pDisplay, pNode->msg.iWindow); + break; + + case WM_WM_LOWER: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_LOWER\n"); +#endif + + /* Lower the window */ + XLowerWindow (pWMInfo->pDisplay, pNode->msg.iWindow); + break; + + case WM_WM_MAP: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_MAP\n"); +#endif + { + XWindowAttributes attr; + char *pszName; +#if 0 + XWMHints *pHints; +#endif + + /* Get the window attributes */ + XGetWindowAttributes (pWMInfo->pDisplay, + pNode->msg.iWindow, + &attr); + if (!attr.override_redirect) + { + /* Set the Windows window name */ + GetWindowName(pWMInfo->pDisplay, pNode->msg.iWindow, &pszName); + SetWindowText (pNode->msg.hwndWindow, pszName); + free (pszName); + } + } + break; + + case WM_WM_UNMAP: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_UNMAP\n"); +#endif + + /* Unmap the window */ + XUnmapWindow(pWMInfo->pDisplay, pNode->msg.iWindow); + break; + + case WM_WM_KILL: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_KILL\n"); +#endif + { + int i, n, found = 0; + Atom *protocols; + + /* --- */ + if (XGetWMProtocols (pWMInfo->pDisplay, + pNode->msg.iWindow, + &protocols, + &n)) + { + for (i = 0; i < n; ++i) + if (protocols[i] == pWMInfo->atmWmDelete) + ++found; + + XFree (protocols); + } + + /* --- */ + if (found) + SendXMessage (pWMInfo->pDisplay, + pNode->msg.iWindow, + pWMInfo->atmWmProtos, + pWMInfo->atmWmDelete); + else + XKillClient (pWMInfo->pDisplay, + pNode->msg.iWindow); + } + break; + + case WM_WM_ACTIVATE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_ACTIVATE\n"); +#endif + + /* Set the input focus */ + XSetInputFocus (pWMInfo->pDisplay, + pNode->msg.iWindow, + RevertToPointerRoot, + CurrentTime); + break; + + case WM_WM_X_EVENT: + /* Process all X events in the Window Manager event queue */ + FlushXEvents (pWMInfo); + break; + + default: + ErrorF ("winMultiWindowWMProc - Unknown Message.\n"); + pthread_exit (NULL); + break; + } + + /* Free the retrieved message */ + free (pNode); + + /* Flush any pending events on our display */ + XFlush (pWMInfo->pDisplay); + } + + /* Free the condition variable */ + pthread_cond_destroy (&pWMInfo->wmMsgQueue.pcNotEmpty); + + /* Free the mutex variable */ + pthread_mutex_destroy (&pWMInfo->wmMsgQueue.pmMutex); + + /* Free the passed-in argument */ + free (pProcArg); + +#if CYGMULTIWINDOW_DEBUG + ErrorF("-winMultiWindowWMProc ()\n"); +#endif +} + + +/* + * FlushXEvents - Process any pending X events + */ + +static Bool +FlushXEvents (WMInfoPtr pWMInfo) +{ + XEvent event; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("FlushXEvents ()\n"); +#endif + + /* Process all pending events */ + while (XPending (pWMInfo->pDisplay)) + { + /* Get the next event - will not block because one is ready */ + XNextEvent (pWMInfo->pDisplay, &event); + +#if 0 + /* Branch on the event type */ + switch (event.type) + { + } +#endif + } + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("-FlushXEvents ()\n"); +#endif + + return True; +} + + +/* + * 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 ("ChangeWindowAttributes BadAccess.\n"); + pthread_exit (NULL); + } + + XGetErrorText (pDisplay, + pErr->error_code, + pszErrorMsg, + sizeof (pszErrorMsg)); + ErrorF ("ERROR: %s\n", pszErrorMsg); + + if (pErr->error_code==BadWindow + || pErr->error_code==BadMatch + || pErr->error_code==BadDrawable) + { + pthread_exit (NULL); + } + + pthread_exit (NULL); + return 0; +} + + +/* + * winInitWM - Entry point for the X server to spawn + * the Window Manager thread. Called from + * winscrinit.c/winFinishScreenInitFB (). + */ + +Bool +winInitWM (void **ppWMInfo, + pthread_t *ptWMProc, + pthread_mutex_t *ppmServerStarted, + int dwScreen) +{ + WMProcArgPtr pArg = (WMProcArgPtr)malloc (sizeof(WMProcArgRec)); + WMInfoPtr pWMInfo = (WMInfoPtr)malloc (sizeof(WMInfoRec)); + + /* Bail if the input parameters are bad */ + if (pArg == NULL || pWMInfo == NULL) + { + ErrorF ("winInitWM - malloc fail.\n"); + return FALSE; + } + + /* Set a return pointer to the Window Manager info structure */ + *ppWMInfo = pWMInfo; + + /* Setup the argument structure for the thread function */ + pArg->dwScreen = dwScreen; + pArg->pWMInfo = pWMInfo; + pArg->ppmServerStarted = ppmServerStarted; + + /* Intialize the message queue */ + if (!InitQueue (&pWMInfo->wmMsgQueue)) + { + ErrorF ("winInitWM - InitQueue () failed.\n"); + return FALSE; + } + + /* Spawn a thread for the Window Manager */ + if (pthread_create (ptWMProc, NULL, winMultiWindowWMProc, pArg)) + { + /* Bail if thread creation failed */ + ErrorF ("winInitWM - pthread_create failed.\n"); + return FALSE; + } + +#if CYGDEBUG || YES + ErrorF ("winInitWM - Returning.\n"); +#endif + + return TRUE; +} + + +/* + * winInitMultiWindowWM - + */ + +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"); + pthread_exit (NULL); + } + + ErrorF ("winInitMultiWindowWM - Calling pthread_mutex_lock ()\n"); + + /* Grab our garbage mutex to satisfy pthread_cond_wait */ + iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted); + if (iReturn != 0) + { + ErrorF ("winInitMultiWindowWM - pthread_mutex_lock () failed: %d\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) + { + 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); + } + } + + /* Flag that we have called setlocale */ + g_fCalledSetLocale = TRUE; + + /* Release the garbage mutex */ + pthread_mutex_unlock (pProcArg->ppmServerStarted); + + ErrorF ("winInitMultiWindowWM - pthread_mutex_unlock () returned.\n"); + + /* Allow multiple threads to access Xlib */ + if (XInitThreads () == 0) + { + ErrorF ("winInitMultiWindowWM - XInitThreads () failed.\n"); + pthread_exit (NULL); + } + + ErrorF ("winInitMultiWindowWM - XInitThreads () returned.\n"); + + /* Set jump point for Error exits */ + iReturn = setjmp (g_jmpEntry); + + /* 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", + iReturn); + pthread_exit (NULL); + } + else if (iReturn == WIN_JMP_ERROR_IO) + { + ErrorF ("winInitMultiWindowWM - setjmp returned WIN_JMP_ERROR_IO\n"); + } + + /* Setup the display connection string x */ + snprintf (pszDisplay, 512, "127.0.0.1:%s.%d", display, pProcArg->dwScreen); + + /* Print the display connection string */ + ErrorF ("winInitMultiWindowWM - DISPLAY=%s\n", pszDisplay); + + /* Open the X display */ + do + { + /* Try to open the display */ + pWMInfo->pDisplay = XOpenDisplay (pszDisplay); + if (pWMInfo->pDisplay == NULL) + { + ErrorF ("winInitMultiWindowWM - Could not open display, try: %d, " + "sleeping: %d\n\f", + iRetries + 1, WIN_CONNECT_DELAY); + ++iRetries; + sleep (WIN_CONNECT_DELAY); + continue; + } + else + break; + } + while (pWMInfo->pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES); + + /* Make sure that the display opened */ + if (pWMInfo->pDisplay == NULL) + { + ErrorF ("winInitMultiWindowWM - Failed opening the display, " + "giving up.\n\f"); + 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, + "WM_PROTOCOLS", + False); + pWMInfo->atmWmDelete = XInternAtom (pWMInfo->pDisplay, + "WM_DELETE_WINDOW", + False); +} + + +/* + * winSendMessageToWM - Send a message from the X thread to the WM thread + */ + +void +winSendMessageToWM (void *pWMInfo, winWMMessagePtr pMsg) +{ + WMMsgNodePtr pNode; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winSendMessageToWM ()\n"); +#endif + + pNode = (WMMsgNodePtr)malloc(sizeof(WMMsgNodeRec)); + if (pNode != NULL) + { + memcpy (&pNode->msg, pMsg, sizeof(winWMMessageRec)); + PushMessage (&((WMInfoPtr)pWMInfo)->wmMsgQueue, pNode); + } +} + + +/* + * winMutliWindowWMIOErrorHandler - Our application specific IO error handler + */ + +static int +winMutliWindowWMIOErrorHandler (Display *pDisplay) +{ + printf ("\nwinMutliWindowWMIOErrorHandler!\n\n"); + + /* Restart at the main entry point */ + longjmp (g_jmpEntry, WIN_JMP_ERROR_IO); + + return 0; +} diff --git a/hw/xwin/winnativegdi.c b/hw/xwin/winnativegdi.c new file mode 100644 index 000000000..5fe8b4f38 --- /dev/null +++ b/hw/xwin/winnativegdi.c @@ -0,0 +1,454 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winnativegdi.c,v 1.13 2002/10/17 08:18:22 alanh Exp $ */ + +#include "win.h" + +Bool +winAllocateFBNativeGDI (ScreenPtr pScreen) +{ + FatalError ("winAllocateFBNativeGDI\n"); + + return TRUE; +} + +/* + * We wrap whatever CloseScreen procedure was specified by fb; + * a pointer to said procedure is stored in our privates. + */ +Bool +winCloseScreenNativeGDI (int nIndex, ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + ErrorF ("winCloseScreenNativeGDI - Freeing screen resources\n"); + + /* Flag that the screen is closed */ + pScreenPriv->fClosed = TRUE; + pScreenPriv->fActive = FALSE; + + /* + * NOTE: mi doesn't use a CloseScreen procedure, so we do not + * need to call a wrapped procedure here. + */ + + /* Delete the window property */ + RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); + + ErrorF ("winCloseScreenNativeGDI - Destroying window\n"); + + /* Kill our window */ + if (pScreenPriv->hwndScreen) + { + DestroyWindow (pScreenPriv->hwndScreen); + pScreenPriv->hwndScreen = NULL; + } + + /* Invalidate our screeninfo's pointer to the screen */ + pScreenInfo->pScreen = NULL; + + /* Free the screen privates for this screen */ + free (pScreenPriv); + + ErrorF ("winCloseScreenNativeGDI - Returning\n"); + + return TRUE; +} + + +void +winShadowUpdateNativeGDI (ScreenPtr pScreen, + shadowBufPtr pBuf) +{ + FatalError ("winShadowUpdateNativeGDI\n"); + return; +} + + +Bool +winInitVisualsNativeGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Set the bitsPerRGB and bit masks */ + switch (pScreenInfo->dwDepth) + { + case 24: + pScreenPriv->dwBitsPerRGB = 8; + pScreenPriv->dwRedMask = 0x00FF0000; + pScreenPriv->dwGreenMask = 0x0000FF00; + pScreenPriv->dwBlueMask = 0x000000FF; + break; + + case 16: + pScreenPriv->dwBitsPerRGB = 6; + pScreenPriv->dwRedMask = 0xF800; + pScreenPriv->dwGreenMask = 0x07E0; + pScreenPriv->dwBlueMask = 0x001F; + break; + + case 15: + pScreenPriv->dwBitsPerRGB = 5; + pScreenPriv->dwRedMask = 0x7C00; + pScreenPriv->dwGreenMask = 0x03E0; + pScreenPriv->dwBlueMask = 0x001F; + break; + + case 8: + pScreenPriv->dwBitsPerRGB = 8; + pScreenPriv->dwRedMask = 0; + pScreenPriv->dwGreenMask = 0; + pScreenPriv->dwBlueMask = 0; + break; + + default: + ErrorF ("winInitVisualsNativeGDI - Unknown screen depth\n"); + return FALSE; + break; + } + + /* Tell the user how many bits per RGB we are using */ + ErrorF ("winInitVisualsNativeGDI - Using dwBitsPerRGB: %d\n", + pScreenPriv->dwBitsPerRGB); + + /* Create a single visual according to the Windows screen depth */ + switch (pScreenInfo->dwDepth) + { + case 24: + case 16: + case 15: + if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, + TrueColorMask, + pScreenPriv->dwBitsPerRGB, + TrueColor, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisuals - miSetVisualTypesAndMasks failed\n"); + return FALSE; + } + break; + + case 8: + ErrorF ("winInitVisuals - Calling miSetVisualTypesAndMasks\n"); + if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, + StaticColorMask, + pScreenPriv->dwBitsPerRGB, + StaticColor, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisuals - miSetVisualTypesAndMasks failed\n"); + return FALSE; + } + break; + + default: + ErrorF ("winInitVisualsNativeGDI - Unknown screen depth\n"); + return FALSE; + } + +#if 1 + ErrorF ("winInitVisualsNativeGDI - Returning\n"); +#endif + + return TRUE; +} + + +/* Adjust the video mode */ +Bool +winAdjustVideoModeNativeGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HDC hdc = NULL; + DWORD dwBPP; + + hdc = GetDC (NULL); + + /* We're in serious trouble if we can't get a DC */ + if (hdc == NULL) + { + ErrorF ("winAdjustVideoModeNativeGDI - GetDC () failed\n"); + return FALSE; + } + + /* Query GDI for current display depth */ + dwBPP = GetDeviceCaps (hdc, BITSPIXEL); + + /* GDI cannot change the screen depth */ + if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP) + { + /* No -depth parameter passed, let the user know the depth being used */ + ErrorF ("winAdjustVideoModeNativeGDI - Using Windows display " + "depth of %d bits per pixel\n", dwBPP); + + /* Use GDI's depth */ + pScreenInfo->dwBPP = dwBPP; + } + else if (dwBPP != pScreenInfo->dwBPP) + { + /* Warn user if GDI depth is different than -depth parameter */ + ErrorF ("winAdjustVideoModeNativeGDI - Command line bpp: %d, "\ + "using bpp: %d\n", pScreenInfo->dwBPP, dwBPP); + + /* We'll use GDI's depth */ + pScreenInfo->dwBPP = dwBPP; + } + + /* Release our DC */ + ReleaseDC (NULL, hdc); + + return TRUE; +} + + +Bool +winActivateAppNativeGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* + * Are we active? + * Are we fullscreen? + */ + if (pScreenPriv != NULL + && pScreenPriv->fActive + && pScreenInfo->fFullScreen) + { + /* + * Activating, attempt to bring our window + * to the top of the display + */ + ShowWindow (pScreenPriv->hwndScreen, SW_RESTORE); + } + + /* + * Are we inactive? + * Are we fullscreen? + */ + if (pScreenPriv != NULL + && !pScreenPriv->fActive + && pScreenInfo->fFullScreen) + { + /* + * Deactivating, stuff our window onto the + * task bar. + */ + ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE); + } + + return TRUE; +} + + +HBITMAP +winCreateDIBNativeGDI (int iWidth, int iHeight, int iDepth, + BYTE **ppbBits, BITMAPINFO **ppbmi) +{ + BITMAPINFOHEADER *pbmih = NULL; + HBITMAP hBitmap = NULL; + BITMAPINFO *pbmi = NULL; + + /* Don't create an invalid bitmap */ + if (iWidth == 0 + || iHeight == 0 + || iDepth == 0) + { + ErrorF ("\nwinCreateDIBNativeGDI - Invalid specs w %d h %d d %d\n\n", + iWidth, iHeight, iDepth); + return NULL; + } + + /* Allocate bitmap info header */ + pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) + + 256 * sizeof (RGBQUAD)); + if (pbmih == NULL) + { + ErrorF ("winCreateDIBNativeGDI - malloc () failed\n"); + return FALSE; + } + ZeroMemory (pbmih, sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD)); + + /* Describe bitmap to be created */ + pbmih->biSize = sizeof (BITMAPINFOHEADER); + pbmih->biWidth = iWidth; + pbmih->biHeight = -iHeight; + pbmih->biPlanes = 1; + pbmih->biBitCount = iDepth; + pbmih->biCompression = BI_RGB; + pbmih->biSizeImage = 0; + pbmih->biXPelsPerMeter = 0; + pbmih->biYPelsPerMeter = 0; + pbmih->biClrUsed = 0; + pbmih->biClrImportant = 0; + + /* Setup color table for mono DIBs */ + if (iDepth == 1) + { + pbmi = (BITMAPINFO*) pbmih; + pbmi->bmiColors[1].rgbBlue = 255; + pbmi->bmiColors[1].rgbGreen = 255; + pbmi->bmiColors[1].rgbRed = 255; + } + + /* Create a DIB with a bit pointer */ + hBitmap = CreateDIBSection (NULL, + (BITMAPINFO *) pbmih, + DIB_RGB_COLORS, + (void **) ppbBits, + NULL, + 0); + if (hBitmap == NULL) + { + ErrorF ("winCreateDIBNativeGDI - CreateDIBSection () failed\n"); + return NULL; + } + + /* Free the bitmap info header memory */ + if (ppbmi != NULL) + { + /* Store the address of the BMIH in the ppbmih parameter */ + *ppbmi = (BITMAPINFO *) pbmih; + } + else + { + free (pbmih); + pbmih = NULL; + } + + return hBitmap; +} + + +Bool +winBltExposedRegionsNativeGDI (ScreenPtr pScreen) +{ + + return TRUE; +} + + +Bool +winRedrawScreenNativeGDI (ScreenPtr pScreen) +{ + FatalError ("winRedrawScreenNativeGDI\n"); + return TRUE; +} + + +Bool +winRealizeInstalledPaletteNativeGDI (ScreenPtr pScreen) +{ + FatalError ("winRealizeInstalledPaletteNativeGDI\n"); + return TRUE; +} + + +Bool +winInstallColormapNativeGDI (ColormapPtr pColormap) +{ + FatalError ("winInstallColormapNativeGDI\n"); + return TRUE; +} + + +Bool +winStoreColorsNativeGDI (ColormapPtr pmap, + int ndef, + xColorItem *pdefs) +{ + FatalError ("winStoreColorsNativeGDI\n"); + return TRUE; +} + + +Bool +winCreateColormapNativeGDI (ColormapPtr pColormap) +{ + FatalError ("winCreateColormapNativeGDI\n"); + return TRUE; +} + + +Bool +winDestroyColormapNativeGDI (ColormapPtr pColormap) +{ + FatalError ("winDestroyColormapNativeGDI\n"); + return TRUE; +} + + +/* Set engine specific funtions */ +Bool +winSetEngineFunctionsNativeGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Set our pointers */ + pScreenPriv->pwinAllocateFB = winAllocateFBNativeGDI; + pScreenPriv->pwinShadowUpdate = winShadowUpdateNativeGDI; + pScreenPriv->pwinCloseScreen = winCloseScreenNativeGDI; + pScreenPriv->pwinInitVisuals = winInitVisualsNativeGDI; + pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeNativeGDI; + if (pScreenInfo->fFullScreen) + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen; + else + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; + pScreenPriv->pwinFinishScreenInit = winFinishScreenInitNativeGDI; + /* + * WARNING: Do not set the BltExposedRegions procedure pointer to anything + * other than NULL until a working painting procedure is in place. + * Else, winWindowProc will get stuck in an infinite loop because + * Windows expects the BeginPaint and EndPaint functions to be called + * before a WM_PAINT message can be removed from the queue. We are + * using NULL here as a signal for winWindowProc that it should + * not signal that the WM_PAINT message has been processed. + */ + pScreenPriv->pwinBltExposedRegions = NULL; + pScreenPriv->pwinActivateApp = winActivateAppNativeGDI; + pScreenPriv->pwinRedrawScreen = winRedrawScreenNativeGDI; + pScreenPriv->pwinRealizeInstalledPalette = + winRealizeInstalledPaletteNativeGDI; + pScreenPriv->pwinInstallColormap = winInstallColormapNativeGDI; + pScreenPriv->pwinStoreColors = winStoreColorsNativeGDI; + pScreenPriv->pwinCreateColormap = winCreateColormapNativeGDI; + pScreenPriv->pwinDestroyColormap = winDestroyColormapNativeGDI; + pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)())NoopDDA; + + return TRUE; +} diff --git a/hw/xwin/winpfbdd.c b/hw/xwin/winpfbdd.c new file mode 100644 index 000000000..59d22247e --- /dev/null +++ b/hw/xwin/winpfbdd.c @@ -0,0 +1,636 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winpfbdd.c,v 1.17 2002/10/17 08:18:22 alanh Exp $ */ + +#include "win.h" + + +/* + * Create a DirectDraw primary surface + */ + +Bool +winAllocateFBPrimaryDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HRESULT ddrval = DD_OK; + DDSURFACEDESC ddsd; + DDSURFACEDESC *pddsdPrimary = NULL; + DDSURFACEDESC *pddsdOffscreen = NULL; + RECT rcClient; + + ErrorF ("winAllocateFBPrimaryDD\n"); + + /* Get client area location in screen coords */ + GetClientRect (pScreenPriv->hwndScreen, &rcClient); + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&rcClient, 2); + + /* Create a DirectDraw object, store the address at lpdd */ + ddrval = (*g_fpDirectDrawCreate) (NULL, &pScreenPriv->pdd, NULL); + if (ddrval != DD_OK) + FatalError ("winAllocateFBPrimaryDD - Could not start DirectDraw\n"); + + /* Get a DirectDraw2 interface pointer */ + ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd, + &IID_IDirectDraw2, + (LPVOID*) &pScreenPriv->pdd2); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDD - Failed DD2 query: %08x\n", + ddrval); + return FALSE; + } + + + ErrorF ("winAllocateFBPrimaryDD - Created and initialized DD\n"); + + /* Are we windowed or fullscreen? */ + if (pScreenInfo->fFullScreen) + { + /* Full screen mode */ + ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, + pScreenPriv->hwndScreen, + DDSCL_FULLSCREEN + | DDSCL_EXCLUSIVE); + if (FAILED (ddrval)) + FatalError ("winAllocateFBPrimaryDD - Could not set " + "cooperative level\n"); + + /* Change the video mode to the mode requested */ + ddrval = IDirectDraw2_SetDisplayMode (pScreenPriv->pdd2, + pScreenInfo->dwWidth, + pScreenInfo->dwHeight, + pScreenInfo->dwBPP, + pScreenInfo->dwRefreshRate, + 0); + if (FAILED (ddrval)) + FatalError ("winAllocateFBPrimaryDD - Could not set " + "full screen display mode\n"); + } + else + { + /* Windowed mode */ + ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, + pScreenPriv->hwndScreen, + DDSCL_NORMAL); + if (FAILED (ddrval)) + FatalError ("winAllocateFBPrimaryDD - Could not set " + "cooperative level\n"); + } + + /* Describe the primary surface */ + ZeroMemory (&ddsd, sizeof (ddsd)); + ddsd.dwSize = sizeof (ddsd); + ddsd.dwFlags = DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + + /* Create the primary surface */ + ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2, + &ddsd, + &pScreenPriv->pddsPrimary, + NULL); + if (FAILED (ddrval)) + FatalError ("winAllocateFBPrimaryDD - Could not create primary " + "surface %08x\n", ddrval); + + ErrorF ("winAllocateFBPrimaryDD - Created primary\n"); + + /* Allocate a DD surface description for our screen privates */ + pddsdPrimary = pScreenPriv->pddsdPrimary + = malloc (sizeof (DDSURFACEDESC)); + if (pddsdPrimary == NULL) + FatalError ("winAllocateFBPrimaryDD - Could not allocate surface " + "description memory\n"); + ZeroMemory (pddsdPrimary, sizeof (*pddsdPrimary)); + pddsdPrimary->dwSize = sizeof (*pddsdPrimary); + + /* Describe the offscreen surface to be created */ + /* + * NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface, + * as drawing, locking, and unlocking take forever + * with video memory surfaces. In addition, + * video memory is a somewhat scarce resource, + * so you shouldn't be allocating video memory when + * you have the option of using system memory instead. + */ + ZeroMemory (&ddsd, sizeof (ddsd)); + ddsd.dwSize = sizeof (ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + ddsd.dwHeight = pScreenInfo->dwHeight; + ddsd.dwWidth = pScreenInfo->dwWidth; + + /* Create the shadow surface */ + ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2, + &ddsd, + &pScreenPriv->pddsOffscreen, + NULL); + if (ddrval != DD_OK) + FatalError ("winAllocateFBPrimaryDD - Could not create shadow " + "surface\n"); + + ErrorF ("winAllocateFBPrimaryDD - Created offscreen\n"); + + /* Allocate a DD surface description for our screen privates */ + pddsdOffscreen = pScreenPriv->pddsdOffscreen + = malloc (sizeof (DDSURFACEDESC)); + if (pddsdOffscreen == NULL) + FatalError ("winAllocateFBPrimaryDD - Could not allocate surface " + "description memory\n"); + ZeroMemory (pddsdOffscreen, sizeof (*pddsdOffscreen)); + pddsdOffscreen->dwSize = sizeof (*pddsdOffscreen); + + ErrorF ("winAllocateFBPrimaryDD - Locking primary\n"); + + /* Lock the primary surface */ + ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsPrimary, + pScreenInfo->fFullScreen ? NULL:&rcClient, + pddsdPrimary, + DDLOCK_WAIT, + NULL); + if (ddrval != DD_OK || pddsdPrimary->lpSurface == NULL) + FatalError ("winAllocateFBPrimaryDD - Could not lock " + "primary surface\n"); + + ErrorF ("winAllocateFBPrimaryDD - Locked primary\n"); + + /* We don't know how to deal with anything other than RGB */ + if (!(pddsdPrimary->ddpfPixelFormat.dwFlags & DDPF_RGB)) + FatalError ("winAllocateFBPrimaryDD - Color format other than RGB\n"); + + /* Grab the pitch from the surface desc */ + pScreenInfo->dwStride = (pddsdPrimary->u1.lPitch * 8) + / pScreenInfo->dwBPP; + + /* Save the pointer to our surface memory */ + pScreenInfo->pfb = pddsdPrimary->lpSurface; + + /* Grab the color depth and masks from the surface description */ + pScreenPriv->dwRedMask = pddsdPrimary->ddpfPixelFormat.u2.dwRBitMask; + pScreenPriv->dwGreenMask = pddsdPrimary->ddpfPixelFormat.u3.dwGBitMask; + pScreenPriv->dwBlueMask = pddsdPrimary->ddpfPixelFormat.u4.dwBBitMask; + + ErrorF ("winAllocateFBPrimaryDD - Returning\n"); + + return TRUE; +} + + +/* + * Call the wrapped CloseScreen function. + * + * Free our resources and private structures. + */ + +Bool +winCloseScreenPrimaryDD (int nIndex, ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + Bool fReturn; + + ErrorF ("winCloseScreenPrimaryDD - Freeing screen resources\n"); + + /* Flag that the screen is closed */ + pScreenPriv->fClosed = TRUE; + pScreenPriv->fActive = FALSE; + + /* Call the wrapped CloseScreen procedure */ + pScreen->CloseScreen = pScreenPriv->CloseScreen; + fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); + + /* Delete the window property */ + RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); + + /* Free the offscreen surface, if there is one */ + if (pScreenPriv->pddsOffscreen) + { + IDirectDrawSurface2_Unlock (pScreenPriv->pddsOffscreen, NULL); + IDirectDrawSurface2_Release (pScreenPriv->pddsOffscreen); + pScreenPriv->pddsOffscreen = NULL; + } + + /* Release the primary surface, if there is one */ + if (pScreenPriv->pddsPrimary) + { + IDirectDrawSurface2_Unlock (pScreenPriv->pddsPrimary, NULL); + IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary); + pScreenPriv->pddsPrimary = NULL; + } + + /* Free the DirectDraw object, if there is one */ + if (pScreenPriv->pdd) + { + IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd); + IDirectDraw2_Release (pScreenPriv->pdd); + pScreenPriv->pdd = NULL; + } + + /* Kill our window */ + if (pScreenPriv->hwndScreen) + { + DestroyWindow (pScreenPriv->hwndScreen); + pScreenPriv->hwndScreen = NULL; + } + + /* Kill our screeninfo's pointer to the screen */ + pScreenInfo->pScreen = NULL; + + /* Invalidate the ScreenInfo's fb pointer */ + pScreenInfo->pfb = NULL; + + /* Free the screen privates for this screen */ + free ((pointer) pScreenPriv); + + return fReturn; +} + + +/* + * Tell mi what sort of visuals we need. + * + * Generally we only need one visual, as our screen can only + * handle one format at a time, I believe. You may want + * to verify that last sentence. + */ + +Bool +winInitVisualsPrimaryDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + DWORD dwRedBits, dwGreenBits, dwBlueBits; + + /* Count the number of ones in each color mask */ + dwRedBits = winCountBits (pScreenPriv->dwRedMask); + dwGreenBits = winCountBits (pScreenPriv->dwGreenMask); + dwBlueBits = winCountBits (pScreenPriv->dwBlueMask); + + /* Store the maximum number of ones in a color mask as the bitsPerRGB */ + if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits) + pScreenPriv->dwBitsPerRGB = dwRedBits; + else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits) + pScreenPriv->dwBitsPerRGB = dwGreenBits; + else + pScreenPriv->dwBitsPerRGB = dwBlueBits; + + ErrorF ("winInitVisualsPrimaryDD - Masks: %08x %08x %08x bpRGB: %d\n", + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask, + pScreenPriv->dwBitsPerRGB); + + /* Create a single visual according to the Windows screen depth */ + switch (pScreenInfo->dwDepth) + { + case 24: + case 16: + case 15: + if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, + TrueColorMask, + pScreenPriv->dwBitsPerRGB, + TrueColor, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsPrimaryDD - " + "miSetVisualTypesAndMasks failed\n"); + return FALSE; + } + break; + + case 8: +#if CYGDEBUG + ErrorF ("winInitVisuals - Calling miSetVisualTypesAndMasks\n"); +#endif /* CYGDEBUG */ + if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, + PseudoColorMask, + pScreenPriv->dwBitsPerRGB, + PseudoColor, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsPrimaryDD - " + "miSetVisualTypesAndMasks failed\n"); + return FALSE; + } +#if CYGDEBUG + ErrorF ("winInitVisualsPrimaryDD - Returned from " + "miSetVisualTypesAndMasks\n"); +#endif /* CYGDEBUG */ + break; + + default: + ErrorF ("winInitVisualsPrimaryDD - Unknown screen depth\n"); + return FALSE; + } + + ErrorF ("winInitVisualsPrimaryDD - Returning\n"); + + return TRUE; +} + + +Bool +winAdjustVideoModePrimaryDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HDC hdc = NULL; + DWORD dwBPP; + + /* We're in serious trouble if we can't get a DC */ + hdc = GetDC (NULL); + if (hdc == NULL) + { + ErrorF ("winAdjustVideoModePrimaryDD - GetDC failed\n"); + return FALSE; + } + + /* Query GDI for current display depth */ + dwBPP = GetDeviceCaps (hdc, BITSPIXEL); + + /* DirectDraw can only change the depth in fullscreen mode */ + if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP) + { + /* No -depth parameter passed, let the user know the depth being used */ + ErrorF ("winAdjustVideoModePrimaryDD - Using Windows display " + "depth of %d bits per pixel\n", dwBPP); + + /* Use GDI's depth */ + pScreenInfo->dwBPP = dwBPP; + } + else if (pScreenInfo->fFullScreen + && pScreenInfo->dwBPP != dwBPP) + { + /* FullScreen, and GDI depth differs from -depth parameter */ + ErrorF ("winAdjustVideoModePrimaryDD - FullScreen, using command " + "line depth: %d\n", pScreenInfo->dwBPP); + } + else if (dwBPP != pScreenInfo->dwBPP) + { + /* Windowed, and GDI depth differs from -depth parameter */ + ErrorF ("winAdjustVideoModePrimaryDD - Windowed, command line " + "depth: %d, using depth: %d\n", + pScreenInfo->dwBPP, dwBPP); + + /* We'll use GDI's depth */ + pScreenInfo->dwBPP = dwBPP; + } + + /* Release our DC */ + ReleaseDC (NULL, hdc); + + return TRUE; +} + + +/* + * We need to blit our offscreen fb to + * the screen when we are activated, and we need to point + * the fb code back to the primary surface memory. + */ + +Bool +winActivateAppPrimaryDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + RECT rcSrc, rcClient; + HRESULT ddrval = DD_OK; + + /* Check for errors */ + if (pScreenPriv == NULL + || pScreenPriv->pddsPrimary == NULL + || pScreenPriv->pddsOffscreen == NULL) + return FALSE; + + /* Check for do-nothing */ + if (!pScreenPriv->fActive) + return TRUE; + + /* We are activating */ + ddrval = IDirectDrawSurface2_IsLost (pScreenPriv->pddsOffscreen); + if (ddrval == DD_OK) + { + IDirectDrawSurface2_Unlock (pScreenPriv->pddsOffscreen, + NULL); + /* + * We don't check for an error from Unlock, because it + * doesn't matter if the Unlock failed. + */ + } + + /* Restore both surfaces, just cause I like it that way */ + IDirectDrawSurface2_Restore (pScreenPriv->pddsOffscreen); + IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary); + + /* Get client area in screen coords */ + GetClientRect (pScreenPriv->hwndScreen, &rcClient); + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&rcClient, 2); + + /* Setup a source rectangle */ + rcSrc.left = 0; + rcSrc.top = 0; + rcSrc.right = pScreenInfo->dwWidth; + rcSrc.bottom = pScreenInfo->dwHeight; + + ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, + &rcClient, + pScreenPriv->pddsOffscreen, + &rcSrc, + DDBLT_WAIT, + NULL); + if (ddrval != DD_OK) + FatalError ("winActivateAppPrimaryDD () - Failed blitting offscreen " + "surface to primary surface %08x\n", ddrval); + + /* Lock the primary surface */ + ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsPrimary, + &rcClient, + pScreenPriv->pddsdPrimary, + DDLOCK_WAIT, + NULL); + if (ddrval != DD_OK + || pScreenPriv->pddsdPrimary->lpSurface == NULL) + FatalError ("winActivateAppPrimaryDD () - Could not lock " + "primary surface\n"); + + /* Notify FB of the new memory pointer */ + winUpdateFBPointer (pScreen, + pScreenPriv->pddsdPrimary->lpSurface); + + /* + * Register the Alt-Tab combo as a hotkey so we can copy + * the primary framebuffer before the display mode changes + */ + RegisterHotKey (pScreenPriv->hwndScreen, 1, MOD_ALT, 9); + + return TRUE; +} + + +/* + * Handle the Alt+Tab hotkey. + * + * We need to save the primary fb to an offscreen fb when + * we get deactivated, and point the fb code at the offscreen + * fb for the duration of the deactivation. + */ + +Bool +winHotKeyAltTabPrimaryDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + RECT rcClient, rcSrc; + HRESULT ddrval = DD_OK; + + ErrorF ("\nwinHotKeyAltTabPrimaryDD\n\n"); + + /* Alt+Tab was pressed, we will lose focus very soon */ + pScreenPriv->fActive = FALSE; + + /* Check for error conditions */ + if (pScreenPriv->pddsPrimary == NULL + || pScreenPriv->pddsOffscreen == NULL) + return FALSE; + + /* Get client area in screen coords */ + GetClientRect (pScreenPriv->hwndScreen, &rcClient); + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&rcClient, 2); + + /* Did we loose the primary surface? */ + ddrval = IDirectDrawSurface2_IsLost (pScreenPriv->pddsPrimary); + if (ddrval == DD_OK) + { + ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsPrimary, + NULL); + if (FAILED (ddrval)) + FatalError ("winHotKeyAltTabPrimaryDD - Failed unlocking primary " + "surface\n"); + } + + /* Setup a source rectangle */ + rcSrc.left = 0; + rcSrc.top = 0; + rcSrc.right = pScreenInfo->dwWidth; + rcSrc.bottom = pScreenInfo->dwHeight; + + /* Blit the primary surface to the offscreen surface */ + ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsOffscreen, + NULL, /* should be rcDest */ + pScreenPriv->pddsPrimary, + NULL, + DDBLT_WAIT, + NULL); + if (ddrval == DDERR_SURFACELOST) + { + IDirectDrawSurface2_Restore (pScreenPriv->pddsOffscreen); + IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary); + + /* Blit the primary surface to the offscreen surface */ + ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsOffscreen, + NULL, + pScreenPriv->pddsPrimary, + NULL, + DDBLT_WAIT, + NULL); + if (FAILED (ddrval)) + FatalError ("winHotKeyAltTabPrimaryDD - Failed blitting primary " + "surface to offscreen surface: %08x\n", + ddrval); + } + else + { + FatalError ("winHotKeyAltTabPrimaryDD - Unknown error from " + "Blt: %08dx\n", ddrval); + } + + /* Lock the offscreen surface */ + ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsOffscreen, + NULL, + pScreenPriv->pddsdOffscreen, + DDLOCK_WAIT, + NULL); + if (ddrval != DD_OK + || pScreenPriv->pddsdPrimary->lpSurface == NULL) + FatalError ("winHotKeyAltTabPrimaryDD - Could not lock " + "offscreen surface\n"); + + /* Notify FB of the new memory pointer */ + winUpdateFBPointer (pScreen, + pScreenPriv->pddsdOffscreen->lpSurface); + + /* Unregister our hotkey */ + UnregisterHotKey (pScreenPriv->hwndScreen, 1); + + return TRUE; +} + + +/* Set engine specific functions */ +Bool +winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Set our pointers */ + pScreenPriv->pwinAllocateFB = winAllocateFBPrimaryDD; + pScreenPriv->pwinShadowUpdate + = (winShadowUpdateProcPtr) (void (*)())NoopDDA; + pScreenPriv->pwinCloseScreen = winCloseScreenPrimaryDD; + pScreenPriv->pwinInitVisuals = winInitVisualsPrimaryDD; + pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModePrimaryDD; + if (pScreenInfo->fFullScreen) + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen; + else + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; + pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB; + pScreenPriv->pwinBltExposedRegions + = (winBltExposedRegionsProcPtr) (void (*)())NoopDDA; + pScreenPriv->pwinActivateApp = winActivateAppPrimaryDD; + pScreenPriv->pwinHotKeyAltTab = winHotKeyAltTabPrimaryDD; + + return TRUE; +} diff --git a/hw/xwin/winpixmap.c b/hw/xwin/winpixmap.c new file mode 100644 index 000000000..519acedf5 --- /dev/null +++ b/hw/xwin/winpixmap.c @@ -0,0 +1,206 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: drewry, september 1986 + * Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winpixmap.c,v 1.10 2002/10/17 08:18:24 alanh Exp $ */ + +#include "win.h" + +/* See Porting Layer Definition - p. 34 */ +/* See mfb/mfbpixmap.c - mfbCreatePixmap() */ +PixmapPtr +winCreatePixmapNativeGDI (ScreenPtr pScreen, + int iWidth, int iHeight, + int iDepth) +{ + winPrivPixmapPtr pPixmapPriv = NULL; + PixmapPtr pPixmap = NULL; + + /* Allocate pixmap memory */ + pPixmap = AllocatePixmap (pScreen, 0); + if (!pPixmap) + { + ErrorF ("winCreatePixmapNativeGDI () - Couldn't allocate a pixmap\n"); + return NullPixmap; + } + + ErrorF ("winCreatePixmap () - w %d h %d d %d bw %d\n", + iWidth, iHeight, iDepth, + PixmapBytePad (iWidth, iDepth)); + + /* Setup pixmap values */ + pPixmap->drawable.type = DRAWABLE_PIXMAP; + pPixmap->drawable.class = 0; + pPixmap->drawable.pScreen = pScreen; + pPixmap->drawable.depth = iDepth; + pPixmap->drawable.bitsPerPixel = BitsPerPixel (iDepth); + pPixmap->drawable.id = 0; + pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + pPixmap->drawable.x = 0; + pPixmap->drawable.y = 0; + pPixmap->drawable.width = iWidth; + pPixmap->drawable.height = iHeight; + pPixmap->devKind = 0; + pPixmap->refcnt = 1; + pPixmap->devPrivate.ptr = NULL; + + /* Pixmap privates are allocated by AllocatePixmap */ + pPixmapPriv = winGetPixmapPriv (pPixmap); + + /* Initialize pixmap privates */ + pPixmapPriv->hBitmap = NULL; + pPixmapPriv->hdcSelected = NULL; + pPixmapPriv->pbBits = NULL; + pPixmapPriv->dwScanlineBytes = PixmapBytePad (iWidth, iDepth); + + /* Check for zero width or height pixmaps */ + if (iWidth == 0 || iHeight == 0) + { + /* Don't allocate a real pixmap, just set fields and return */ + return pPixmap; + } + + /* Create a DIB for the pixmap */ + pPixmapPriv->hBitmap = winCreateDIBNativeGDI (iWidth, iHeight, iDepth, + &pPixmapPriv->pbBits, + (BITMAPINFO **) &pPixmapPriv->pbmih); + +#if CYGDEBUG + ErrorF ("winCreatePixmap () - Created a pixmap %08x, %dx%dx%d, for " \ + "screen: %08x\n", + pPixmapPriv->hBitmap, iWidth, iHeight, iDepth, pScreen); +#endif + + return pPixmap; +} + + +/* + * See Porting Layer Definition - p. 35 + * + * See mfb/mfbpixmap.c - mfbDestroyPixmap() + */ + +Bool +winDestroyPixmapNativeGDI (PixmapPtr pPixmap) +{ + winPrivPixmapPtr pPixmapPriv = NULL; + + ErrorF ("winDestroyPixmapNativeGDI ()\n"); + + /* Bail early if there is not a pixmap to destroy */ + if (pPixmap == NULL) + { + ErrorF ("winDestroyPixmapNativeGDI () - No pixmap to destroy\n"); + return TRUE; + } + + /* Get a handle to the pixmap privates */ + pPixmapPriv = winGetPixmapPriv (pPixmap); + + ErrorF ("winDestroyPixmapNativeGDI - pPixmapPriv->hBitmap: %08x\n", + pPixmapPriv->hBitmap); + + /* Decrement reference count, return if nonzero */ + --pPixmap->refcnt; + if (pPixmap->refcnt != 0) + return TRUE; + + /* Free GDI bitmap */ + if (pPixmapPriv->hBitmap) DeleteObject (pPixmapPriv->hBitmap); + + /* Free the bitmap info header memory */ + if (pPixmapPriv->pbmih != NULL) + { + free (pPixmapPriv->pbmih); + pPixmapPriv->pbmih = NULL; + } + + /* Free the pixmap memory */ + free (pPixmap); + pPixmap = NULL; + + return TRUE; +} + + +/* + * Not used yet + */ + +Bool +winModifyPixmapHeaderNativeGDI (PixmapPtr pPixmap, + int iWidth, int iHeight, + int iDepth, + int iBitsPerPixel, + int devKind, + pointer pPixData) +{ + FatalError ("winModifyPixmapHeaderNativeGDI ()\n"); + return TRUE; +} + + +/* + * Not used yet. + * See cfb/cfbpixmap.c + */ + +void +winXRotatePixmapNativeGDI (PixmapPtr pPix, int rw) +{ + ErrorF ("winXRotatePixmap()\n"); + /* fill in this function, look at CFB */ +} + + +/* + * Not used yet. + * See cfb/cfbpixmap.c + */ +void +winYRotatePixmapNativeGDI (PixmapPtr pPix, int rh) +{ + ErrorF ("winYRotatePixmap()\n"); + /* fill in this function, look at CFB */ +} + + +/* + * Not used yet. + * See cfb/cfbpixmap.c + */ + +void +winCopyRotatePixmapNativeGDI (PixmapPtr psrcPix, PixmapPtr *ppdstPix, + int xrot, int yrot) +{ + ErrorF ("winCopyRotatePixmap()\n"); + /* fill in this function, look at CFB */ +} diff --git a/hw/xwin/winpntwin.c b/hw/xwin/winpntwin.c new file mode 100644 index 000000000..d28929d67 --- /dev/null +++ b/hw/xwin/winpntwin.c @@ -0,0 +1,45 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winpntwin.c,v 1.2 2001/06/04 13:04:41 alanh Exp $ */ + +#include "win.h" + +/* See Porting Layer Definition - p. 39 + * Sometimes implemented as two functions: + * PaintWindowBackground (nKind = PW_BACKGROUND) + * PaintWindowBorder (nKind = PW_BORDER) + */ +void +winPaintWindowNativeGDI (WindowPtr pWin, + RegionPtr pRegion, + int nKind) +{ + ErrorF ("winPaintWindow()\n"); +} diff --git a/hw/xwin/winpolyline.c b/hw/xwin/winpolyline.c new file mode 100644 index 000000000..194ecfe46 --- /dev/null +++ b/hw/xwin/winpolyline.c @@ -0,0 +1,43 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winpolyline.c,v 1.3 2001/09/13 08:25:45 alanh Exp $ */ + +#include "win.h" + +/* See Porting Layer Definition - p. 50 */ +void +winPolyLineNativeGDI (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ppt) +{ + FatalError ("winPolyLine()\n"); +} diff --git a/hw/xwin/winregistry.c b/hw/xwin/winregistry.c new file mode 100644 index 000000000..b31fcf641 --- /dev/null +++ b/hw/xwin/winregistry.c @@ -0,0 +1,66 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winregistry.c,v 1.1 2002/07/05 09:19:26 alanh Exp $ */ + +#include "win.h" + + +DWORD +winGetRegistryDWORD (HKEY hkey, char *pszRegistryKey) +{ + HKEY hkResult; + DWORD dwDisposition; + + RegCreateKeyEx (hkey, + pszRegistryKey, + 0, + '\0', + REG_OPTION_NON_VOLATILE, + KEY_READ, + NULL, + &hkResult, + &dwDisposition); + + if (dwDisposition == REG_CREATED_NEW_KEY) + { + ErrorF ("winGetRegistryDWORD - Created new key: %s\n", pszRegistryKey); + } + else if (dwDisposition == REG_OPENED_EXISTING_KEY) + { + ErrorF ("winGetRegistryDWORD - Opened existing key: %s\n", + pszRegistryKey); + } + + /* Free the registry key handle */ + RegCloseKey (hkResult); + hkResult = NULL; + + return 0; +} diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c new file mode 100644 index 000000000..41811d253 --- /dev/null +++ b/hw/xwin/winscrinit.c @@ -0,0 +1,739 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + * Kensuke Matsuzaki + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winscrinit.c,v 1.26 2003/02/12 15:01:38 alanh Exp $ */ + +#include "win.h" + + +/* + * Determine what type of screen we are initializing + * and call the appropriate procedure to intiailize + * that type of screen. + */ + +Bool +winScreenInit (int index, + ScreenPtr pScreen, + int argc, char **argv) +{ + winScreenInfoPtr pScreenInfo = &g_ScreenInfo[index]; + winPrivScreenPtr pScreenPriv; + HDC hdc; + +#if CYGDEBUG + ErrorF ("winScreenInit - dwWidth: %d dwHeight: %d\n", + pScreenInfo->dwWidth, pScreenInfo->dwHeight); +#endif + + /* Allocate privates for this screen */ + if (!winAllocatePrivates (pScreen)) + { + ErrorF ("winScreenInit - Couldn't allocate screen privates\n"); + return FALSE; + } + + /* Get a pointer to the privates structure that was allocated */ + pScreenPriv = winGetScreenPriv (pScreen); + + /* Save a pointer to this screen in the screen info structure */ + pScreenInfo->pScreen = pScreen; + + /* Save a pointer to the screen info in the screen privates structure */ + /* This allows us to get back to the screen info from a screen pointer */ + pScreenPriv->pScreenInfo = pScreenInfo; + + /* + * Determine which engine to use. + * + * NOTE: This is done once per screen because each screen possibly has + * a preferred engine specified on the command line. + */ + if (!winSetEngine (pScreen)) + { + ErrorF ("winScreenInit - winSetEngine () failed\n"); + return FALSE; + } + + /* Adjust the video mode for our engine type */ + if (!(*pScreenPriv->pwinAdjustVideoMode) (pScreen)) + { + ErrorF ("winScreenInit - winAdjustVideoMode () failed\n"); + return FALSE; + } + + /* Check for supported display depth */ + if (!(WIN_SUPPORTED_BPPS & (1 << (pScreenInfo->dwBPP - 1)))) + { + ErrorF ("winScreenInit - Unsupported display depth: %d\n" \ + "Change your Windows display depth to 15, 16, 24, or 32 bits " + "per pixel.\n", + pScreenInfo->dwBPP); + ErrorF ("winScreenInit - Supported depths: %08x\n", + WIN_SUPPORTED_BPPS); +#if WIN_CHECK_DEPTH + return FALSE; +#endif + } + + /* + * Check that all monitors have the same display depth if we are using + * multiple monitors + */ + if (pScreenInfo->fMultipleMonitors + && !GetSystemMetrics (SM_SAMEDISPLAYFORMAT)) + { + ErrorF ("winScreenInit - Monitors do not all have same pixel format / " + "display depth.\n" + "Using primary display only.\n"); + pScreenInfo->fMultipleMonitors = FALSE; + } + + /* Create display window */ + if (!(*pScreenPriv->pwinCreateBoundingWindow) (pScreen)) + { + ErrorF ("winScreenInit - pwinCreateBoundingWindow () " + "failed\n"); + return FALSE; + } + + /* Get a device context */ + hdc = GetDC (pScreenPriv->hwndScreen); + + /* Store the initial height, width, and depth of the display */ + /* Are we using multiple monitors? */ + if (pScreenInfo->fMultipleMonitors) + { + pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN); + pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN); + + /* + * In this case, some of the defaults set in + * winInitializeDefaultScreens () are not correct ... + */ + if (!pScreenInfo->fUserGaveHeightAndWidth) + { + pScreenInfo->dwWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN); + pScreenInfo->dwHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN); + pScreenInfo->dwWidth_mm = (pScreenInfo->dwWidth / + WIN_DEFAULT_DPI) * 25.4; + pScreenInfo->dwHeight_mm = (pScreenInfo->dwHeight / + WIN_DEFAULT_DPI) * 25.4; + } + } + else + { + pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN); + pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN); + } + + /* Save the original bits per pixel */ + pScreenPriv->dwLastWindowsBitsPixel = GetDeviceCaps (hdc, BITSPIXEL); + + /* Release the device context */ + ReleaseDC (pScreenPriv->hwndScreen, hdc); + + /* Clear the visuals list */ + miClearVisualTypes (); + + /* Set the padded screen width */ + pScreenInfo->dwPaddedWidth = PixmapBytePad (pScreenInfo->dwWidth, + pScreenInfo->dwBPP); + + /* Call the engine dependent screen initialization procedure */ + if (!((*pScreenPriv->pwinFinishScreenInit) (index, pScreen, argc, argv))) + { + ErrorF ("winScreenInit - winFinishScreenInit () failed\n"); + return FALSE; + } + +#if CYGDEBUG || YES + ErrorF ("winScreenInit - returning\n"); +#endif + + return TRUE; +} + + +/* See Porting Layer Definition - p. 20 */ +Bool +winFinishScreenInitFB (int index, + ScreenPtr pScreen, + int argc, char **argv) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + VisualPtr pVisual = NULL; + char *pbits = NULL; + int iReturn; + +#if WIN_LAYER_SUPPORT + pScreenPriv->dwLayerKind = LAYER_SHADOW; +#endif + + /* Create framebuffer */ + if (!(*pScreenPriv->pwinAllocateFB) (pScreen)) + { + ErrorF ("winFinishScreenInitFB - Could not allocate framebuffer\n"); + return FALSE; + } + + /* + * Grab the number of bits that are used to represent color in each pixel. + */ + if (pScreenInfo->dwBPP == 8) + pScreenInfo->dwDepth = 8; + else + pScreenInfo->dwDepth = winCountBits (pScreenPriv->dwRedMask) + + winCountBits (pScreenPriv->dwGreenMask) + + winCountBits (pScreenPriv->dwBlueMask); + + ErrorF ("winFinishScreenInitFB - Masks: %08x %08x %08x\n", + pScreenPriv->dwRedMask, pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask); + + /* Init visuals */ + if (!(*pScreenPriv->pwinInitVisuals) (pScreen)) + { + ErrorF ("winFinishScreenInitFB - winInitVisuals failed\n"); + return FALSE; + } + + /* Setup a local variable to point to the framebuffer */ + pbits = pScreenInfo->pfb; + + /* Apparently we need this for the render extension */ + miSetPixmapDepths (); + + /* Start fb initialization */ + if (!fbSetupScreen (pScreen, + pScreenInfo->pfb, + pScreenInfo->dwWidth, pScreenInfo->dwHeight, + monitorResolution, monitorResolution, + pScreenInfo->dwStride, + pScreenInfo->dwBPP)) + { + ErrorF ("winFinishScreenInitFB - fbSetupScreen failed\n"); + return FALSE; + } + + /* Override default colormap routines if visual class is dynamic */ + if (pScreenInfo->dwDepth == 8 + && (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI + || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL + && pScreenInfo->fFullScreen) + || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD + && pScreenInfo->fFullScreen))) + { + pScreen->CreateColormap = winCreateColormap; + pScreen->DestroyColormap = winDestroyColormap; + pScreen->InstallColormap = winInstallColormap; + pScreen->UninstallColormap = winUninstallColormap; + pScreen->ListInstalledColormaps = winListInstalledColormaps; + pScreen->StoreColors = winStoreColors; + pScreen->ResolveColor = winResolveColor; + + /* + * NOTE: Setting whitePixel to 255 causes Magic 7.1 to allocate its + * own colormap, as it cannot allocate 7 planes in the default + * colormap. Setting whitePixel to 1 allows Magic to get 7 + * planes in the default colormap, so it doesn't create its + * own colormap. This latter situation is highly desireable, + * as it keeps the Magic window viewable when switching to + * other X clients that use the default colormap. + */ + pScreen->blackPixel = 0; + pScreen->whitePixel = 1; + } + + /* Place our save screen function */ + pScreen->SaveScreen = winSaveScreen; + + /* Backing store functions */ + /* + * FIXME: Backing store support still doesn't seem to be working. + */ + pScreen->BackingStoreFuncs.SaveAreas = fbSaveAreas; + pScreen->BackingStoreFuncs.RestoreAreas = fbRestoreAreas; + + /* Finish fb initialization */ + if (!fbFinishScreenInit (pScreen, + pScreenInfo->pfb, + pScreenInfo->dwWidth, pScreenInfo->dwHeight, + monitorResolution, monitorResolution, + pScreenInfo->dwStride, + pScreenInfo->dwBPP)) + { + ErrorF ("winFinishScreenInitFB - fbFinishScreenInit failed\n"); + return FALSE; + } + + /* Save a pointer to the root visual */ + for (pVisual = pScreen->visuals; + pVisual->vid != pScreen->rootVisual; + pVisual++); + pScreenPriv->pRootVisual = pVisual; + + /* + * Setup points to the block and wakeup handlers. Pass a pointer + * to the current screen as pWakeupdata. + */ + pScreen->BlockHandler = winBlockHandler; + pScreen->WakeupHandler = winWakeupHandler; + pScreen->blockData = pScreen; + pScreen->wakeupData = pScreen; + +#ifdef RENDER + /* Render extension initialization, calls miPictureInit */ + if (!fbPictureInit (pScreen, NULL, 0)) + { + ErrorF ("winFinishScreenInitFB - fbPictureInit () failed\n"); + return FALSE; + } +#endif + +#if WIN_LAYER_SUPPORT + /* KDrive does LayerStartInit right after fbPictureInit */ + if (!LayerStartInit (pScreen)) + { + ErrorF ("winFinishScreenInitFB - LayerStartInit () failed\n"); + return FALSE; + } + + /* Not sure what we're adding to shadow, but add it anyway */ + if (!shadowAdd (pScreen, 0, pScreenPriv->pwinShadowUpdate, NULL, 0, 0)) + { + ErrorF ("winFinishScreenInitFB - shadowAdd () failed\n"); + return FALSE; + } + + /* KDrive does LayerFinishInit right after LayerStartInit */ + if (!LayerFinishInit (pScreen)) + { + ErrorF ("winFinishScreenInitFB - LayerFinishInit () failed\n"); + return FALSE; + } + + /* KDrive does LayerCreate right after LayerFinishInit */ + pScreenPriv->pLayer = winLayerCreate (pScreen); + if (!pScreenPriv->pLayer) + { + ErrorF ("winFinishScreenInitFB - winLayerCreate () failed\n"); + return FALSE; + } + + /* KDrive does RandRInit right after LayerCreate */ +#ifdef RANDR + if (pScreenInfo->dwDepth != 8 && !winRandRInit (pScreen)) + { + ErrorF ("winFinishScreenInitFB - winRandRInit () failed\n"); + return FALSE; + } +#endif +#endif + + /* + * Backing store support should reduce network traffic and increase + * performance. + */ + miInitializeBackingStore (pScreen); + + /* KDrive does miDCInitialize right after miInitializeBackingStore */ + /* Setup the cursor routines */ +#if CYGDEBUG + ErrorF ("winFinishScreenInitFB - Calling miDCInitialize ()\n"); +#endif + miDCInitialize (pScreen, &g_winPointerCursorFuncs); + + /* KDrive does winCreateDefColormap right after miDCInitialize */ + /* Create a default colormap */ +#if CYGDEBUG + ErrorF ("winFinishScreenInitFB - Calling winCreateDefColormap ()\n"); +#endif + if (!winCreateDefColormap (pScreen)) + { + ErrorF ("winFinishScreenInitFB - Could not create colormap\n"); + return FALSE; + } + +#if !WIN_LAYER_SUPPORT + /* Initialize the shadow framebuffer layer */ + if (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI + || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD + || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL) + { +#if CYGDEBUG + ErrorF ("winFinishScreenInitFB - Calling shadowInit ()\n"); +#endif + if (!shadowInit (pScreen, + pScreenPriv->pwinShadowUpdate, + NULL)) + { + ErrorF ("winFinishScreenInitFB - shadowInit () failed\n"); + return FALSE; + } + } +#endif + + + /* Handle pseudo-rootless mode */ + if (pScreenInfo->fRootless) + { + /* Define the WRAP macro temporarily for local use */ +#define WRAP(a) \ + if (pScreen->a) { \ + pScreenPriv->a = pScreen->a; \ + } else { \ + ErrorF("null screen fn " #a "\n"); \ + pScreenPriv->a = NULL; \ + } + + /* Save a pointer to each lower-level window procedure */ + WRAP(CreateWindow); + WRAP(DestroyWindow); + WRAP(RealizeWindow); + WRAP(UnrealizeWindow); + WRAP(PositionWindow); + WRAP(ChangeWindowAttributes); +#ifdef SHAPE + WRAP(SetShape); +#endif + + /* Assign pseudo-rootless window procedures to be top level procedures */ + pScreen->CreateWindow = winCreateWindowPRootless; + pScreen->DestroyWindow = winDestroyWindowPRootless; + pScreen->PositionWindow = winPositionWindowPRootless; + pScreen->ChangeWindowAttributes = winChangeWindowAttributesPRootless; + pScreen->RealizeWindow = winMapWindowPRootless; + pScreen->UnrealizeWindow = winUnmapWindowPRootless; +#ifdef SHAPE + pScreen->SetShape = winSetShapePRootless; +#endif + + /* Undefine the WRAP macro, as it is not needed elsewhere */ +#undef WRAP + } + /* Handle multi window mode */ + else if (pScreenInfo->fMultiWindow) + { + /* Define the WRAP macro temporarily for local use */ +#define WRAP(a) \ + if (pScreen->a) { \ + pScreenPriv->a = pScreen->a; \ + } else { \ + ErrorF("null screen fn " #a "\n"); \ + pScreenPriv->a = NULL; \ + } + + /* Save a pointer to each lower-level window procedure */ + WRAP(CreateWindow); + WRAP(DestroyWindow); + WRAP(RealizeWindow); + WRAP(UnrealizeWindow); + WRAP(PositionWindow); + WRAP(ChangeWindowAttributes); + WRAP(ReparentWindow); + WRAP(RestackWindow); +#ifdef SHAPE + WRAP(SetShape); +#endif + + /* Assign multi-window window procedures to be top level procedures */ + pScreen->CreateWindow = winCreateWindowMultiWindow; + pScreen->DestroyWindow = winDestroyWindowMultiWindow; + pScreen->PositionWindow = winPositionWindowMultiWindow; + pScreen->ChangeWindowAttributes = winChangeWindowAttributesMultiWindow; + pScreen->RealizeWindow = winMapWindowMultiWindow; + pScreen->UnrealizeWindow = winUnmapWindowMultiWindow; + pScreen->ReparentWindow = winReparentWindowMultiWindow; + pScreen->RestackWindow = winRestackWindowMultiWindow; +#ifdef SHAPE + pScreen->SetShape = winSetShapeMultiWindow; +#endif + + /* Undefine the WRAP macro, as it is not needed elsewhere */ +#undef WRAP + } + + /* Wrap either fb's or shadow's CloseScreen with our CloseScreen */ + pScreenPriv->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = pScreenPriv->pwinCloseScreen; + + /* Create a mutex for modules in seperate threads to wait for */ + iReturn = pthread_mutex_init (&pScreenPriv->pmServerStarted, NULL); + if (iReturn != 0) + { + ErrorF ("winFinishScreenInitFB - pthread_mutex_init () failed: %d\n", + iReturn); + return FALSE; + } + + /* Own the mutex for modules in seperate threads */ + iReturn = pthread_mutex_lock (&pScreenPriv->pmServerStarted); + if (iReturn != 0) + { + ErrorF ("winFinishScreenInitFB - pthread_mutex_lock () failed: %d\n", + iReturn); + return FALSE; + } + + /* Set the ServerStarted flag to false */ + pScreenPriv->fServerStarted = FALSE; + +#if CYGDEBUG || YES + if (pScreenInfo->fMultiWindow) + ErrorF ("winFinishScreenInitFB - Calling winInitWM.\n"); +#endif + + /* Initialize multi window mode */ + if (pScreenInfo->fMultiWindow + && !winInitWM (&pScreenPriv->pWMInfo, + &pScreenPriv->ptWMProc, + &pScreenPriv->pmServerStarted, + pScreenInfo->dwScreen)) + { + ErrorF ("winFinishScreenInitFB - winInitWM () failed.\n"); + return FALSE; + } + +#if CYGDEBUG || YES + if (pScreenInfo->fClipboard) + ErrorF ("winFinishScreenInitFB - Calling winInitClipboard.\n"); +#endif + + /* Initialize the clipboard manager */ + if (pScreenInfo->fClipboard + && !winInitClipboard (&pScreenPriv->ptClipboardProc, + &pScreenPriv->pmServerStarted, + pScreenInfo->dwScreen)) + { + ErrorF ("winFinishScreenInitFB - winClipboardInit () failed.\n"); + return FALSE; + } + + /* Tell the server that we are enabled */ + pScreenPriv->fEnabled = TRUE; + + /* Tell the server that we have a valid depth */ + pScreenPriv->fBadDepth = FALSE; + +#if CYGDEBUG || YES + ErrorF ("winFinishScreenInitFB - returning\n"); +#endif + + return TRUE; +} + + +/* + * + * + * + * + * TEST CODE BELOW - NOT USED IN NORMAL COMPILATION + * + * + * + * + * + */ + + +/* See Porting Layer Definition - p. 20 */ + +Bool +winFinishScreenInitNativeGDI (int index, + ScreenPtr pScreen, + int argc, char **argv) +{ + winScreenPriv(pScreen); + winScreenInfoPtr pScreenInfo = &g_ScreenInfo[index]; + VisualPtr pVisuals = NULL; + DepthPtr pDepths = NULL; + VisualID rootVisual = 0; + int nVisuals = 0, nDepths = 0, nRootDepth = 0; + + /* Ignore user input (mouse, keyboard) */ + pScreenInfo->fIgnoreInput = TRUE; + + /* Get device contexts for the screen and shadow bitmap */ + pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); + if (pScreenPriv->hdcScreen == NULL) + FatalError ("winFinishScreenInitNativeGDI - Couldn't get a DC\n"); + + /* Init visuals */ + if (!(*pScreenPriv->pwinInitVisuals) (pScreen)) + { + ErrorF ("winFinishScreenInitNativeGDI - pwinInitVisuals failed\n"); + return FALSE; + } + + /* Initialize the mi visuals */ + if (!miInitVisuals (&pVisuals, &pDepths, &nVisuals, &nDepths, &nRootDepth, + &rootVisual, + ((unsigned long)1 << (pScreenInfo->dwDepth - 1)), 8, + TrueColor)) + { + ErrorF ("winFinishScreenInitNativeGDI - miInitVisuals () failed\n"); + return FALSE; + } + + /* Initialize the CloseScreen procedure pointer */ + pScreen->CloseScreen = NULL; + + /* Initialize the mi code */ + if (!miScreenInit (pScreen, + NULL, /* No framebuffer */ + pScreenInfo->dwWidth, pScreenInfo->dwHeight, + monitorResolution, monitorResolution, + pScreenInfo->dwWidth, + nRootDepth, nDepths, pDepths, rootVisual, + nVisuals, pVisuals)) + { + ErrorF ("winFinishScreenInitNativeGDI - miScreenInit failed\n"); + return FALSE; + } + + /* + * Register our block and wakeup handlers; these procedures + * process messages in our Windows message queue; specifically, + * they process mouse and keyboard input. + */ + pScreen->BlockHandler = winBlockHandler; + pScreen->WakeupHandler = winWakeupHandler; + pScreen->blockData = pScreen; + pScreen->wakeupData = pScreen; + + /* Place our save screen function */ + pScreen->SaveScreen = winSaveScreen; + + /* Pixmaps */ + pScreen->CreatePixmap = winCreatePixmapNativeGDI; + pScreen->DestroyPixmap = winDestroyPixmapNativeGDI; + + /* Other Screen Routines */ + pScreen->QueryBestSize = winQueryBestSizeNativeGDI; + pScreen->SaveScreen = winSaveScreen; + pScreen->GetImage = miGetImage; + pScreen->GetSpans = winGetSpansNativeGDI; + + /* Window Procedures */ + pScreen->CreateWindow = winCreateWindowNativeGDI; + pScreen->DestroyWindow = winDestroyWindowNativeGDI; + pScreen->PositionWindow = winPositionWindowNativeGDI; + pScreen->ChangeWindowAttributes = winChangeWindowAttributesNativeGDI; + pScreen->RealizeWindow = winMapWindowNativeGDI; + pScreen->UnrealizeWindow = winUnmapWindowNativeGDI; + + /* Paint window */ + pScreen->PaintWindowBackground = miPaintWindow; + pScreen->PaintWindowBorder = miPaintWindow; + pScreen->CopyWindow = winCopyWindowNativeGDI; + + /* Fonts */ + pScreen->RealizeFont = winRealizeFontNativeGDI; + pScreen->UnrealizeFont = winUnrealizeFontNativeGDI; + + /* GC */ + pScreen->CreateGC = winCreateGCNativeGDI; + + /* Colormap Routines */ + pScreen->CreateColormap = miInitializeColormap; + pScreen->DestroyColormap = (DestroyColormapProcPtr) (void (*)()) NoopDDA; + pScreen->InstallColormap = miInstallColormap; + pScreen->UninstallColormap = miUninstallColormap; + pScreen->ListInstalledColormaps = miListInstalledColormaps; + pScreen->StoreColors = (StoreColorsProcPtr) (void (*)()) NoopDDA; + pScreen->ResolveColor = miResolveColor; + + /* Bitmap */ + pScreen->BitmapToRegion = winPixmapToRegionNativeGDI; + + ErrorF ("winFinishScreenInitNativeGDI - calling miDCInitialize\n"); + + /* Set the default white and black pixel positions */ + pScreen->whitePixel = pScreen->blackPixel = (Pixel) 0; + + /* Initialize the cursor */ + if (!miDCInitialize (pScreen, &g_winPointerCursorFuncs)) + { + ErrorF ("winFinishScreenInitNativeGDI - miDCInitialize failed\n"); + return FALSE; + } + + /* Create a default colormap */ + if (!miCreateDefColormap (pScreen)) + { + ErrorF ("winFinishScreenInitNativeGDI - miCreateDefColormap () " + "failed\n"); + return FALSE; + } + + ErrorF ("winFinishScreenInitNativeGDI - miCreateDefColormap () " + "returned\n"); + + /* mi doesn't use a CloseScreen procedure, so no need to wrap */ + pScreen->CloseScreen = pScreenPriv->pwinCloseScreen; + + /* Tell the server that we are enabled */ + pScreenPriv->fEnabled = TRUE; + + ErrorF ("winFinishScreenInitNativeGDI - Successful addition of " + "screen %08x\n", + pScreen); + + return TRUE; +} + + +/* See Porting Layer Definition - p. 33 */ +Bool +winSaveScreen (ScreenPtr pScreen, int on) +{ + return TRUE; +} + + +PixmapPtr +winGetWindowPixmap (WindowPtr pwin) +{ + ErrorF ("winGetWindowPixmap ()\n"); + return NULL; +} + + +void +winSetWindowPixmap (WindowPtr pwin, PixmapPtr pPix) +{ + ErrorF ("winSetWindowPixmap ()\n"); +} diff --git a/hw/xwin/winsetsp.c b/hw/xwin/winsetsp.c new file mode 100644 index 000000000..657a7af50 --- /dev/null +++ b/hw/xwin/winsetsp.c @@ -0,0 +1,344 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winsetsp.c,v 1.7 2001/11/01 12:19:42 alanh Exp $ */ + +#include "win.h" + +/* See Porting Layer Definition - p. 55 */ +void +winSetSpansNativeGDI (DrawablePtr pDrawable, + GCPtr pGC, + char *pSrcs, + DDXPointPtr pPoints, + int *piWidths, + int iSpans, + int fSorted) +{ + winGCPriv(pGC); + PixmapPtr pPixmap = NULL; + winPrivPixmapPtr pPixmapPriv = NULL; + int iSpan; + int *piWidth = NULL; + DDXPointPtr pPoint = NULL; + char *pSrc = pSrcs; + HDC hdcMem; + BITMAPINFOHEADER *pbmih; + HBITMAP hBitmap = NULL; + HBITMAP hbmpOrig = NULL; + DEBUG_FN_NAME("winSetSpans"); + DEBUGVARS; + DEBUGPROC_MSG; + + /* Branch on the drawable type */ + switch (pDrawable->type) + { + case DRAWABLE_PIXMAP: + pPixmap = (PixmapPtr) pDrawable; + pPixmapPriv = winGetPixmapPriv (pPixmap); + + /* Select the drawable pixmap into a DC */ + hbmpOrig = SelectObject (pGCPriv->hdcMem, pPixmapPriv->hBitmap); + if (hbmpOrig == NULL) + FatalError ("winSetSpans - DRAWABLE_PIXMAP - SelectObject () " + "failed on pPixmapPriv->hBitmap\n"); + + /* Branch on the raster operation type */ + switch (pGC->alu) + { + case GXclear: + FatalError ("winSetSpans - DRAWABLE_PIXMAP - GXclear\n"); + break; + + case GXand: + FatalError ("winSetSpans - DRAWABLE_PIXMAP - GXand\n"); + break; + + case GXandReverse: + FatalError ("winSetSpans - DRAWABLE_PIXMAP - GXandReverse\n"); + break; + + case GXcopy: + ErrorF ("winSetSpans - DRAWABLE_PIXMAP - GXcopy %08x\n", + pDrawable); + + /* Loop through spans */ + for (iSpan = 0; iSpan < iSpans; ++iSpan) + { + piWidth = piWidths + iSpan; + pPoint = pPoints + iSpan; + + /* Blast the bits to the drawable */ + SetDIBits (pGCPriv->hdcMem, + pPixmapPriv->hBitmap, + pPoint->y, 1, + pSrc, + (BITMAPINFO *) pPixmapPriv->pbmih, + 0); + + /* Display some useful information */ + ErrorF ("(%dx%dx%d) (%d,%d) w: %d ps: %08x\n", + pDrawable->width, pDrawable->height, pDrawable->depth, + pPoint->x, pPoint->y, *piWidth, pSrc); + + /* Calculate offset of next bit source */ + pSrc += 4 * ((*piWidth + 31) / 32); + } + + /* + * REMOVE - Visual verification only. + */ + BitBlt (pGCPriv->hdc, + pDrawable->width * 2, pDrawable->height, + pDrawable->width, pDrawable->height, + pGCPriv->hdcMem, + 0, 0, + SRCCOPY); + DEBUG_MSG ("DRAWABLE_PIXMAP - GXcopy"); + break; + + case GXandInverted: + FatalError ("winSetSpans - DRAWABLE_PIXMAP - GXandInverted\n"); + break; + + case GXnoop: + FatalError ("winSetSpans - DRAWABLE_PIXMAP - GXnoop\n"); + break; + + case GXxor: + FatalError ("winSetSpans - DRAWABLE_PIXMAP - GXxor\n"); + break; + + case GXor: + FatalError ("winSetSpans - DRAWABLE_PIXMAP - GXor\n"); + break; + + case GXnor: + FatalError ("winSetSpans - DRAWABLE_PIXMAP - GXnor\n"); + break; + + case GXequiv: + FatalError ("winSetSpans - DRAWABLE_PIXMAP - GXequiv\n"); + break; + + case GXinvert: + ErrorF ("winSetSpans - DRAWABLE_PIXMAP - GXinvert %08x\n", + pDrawable); + + /* Create a temporary DC */ + hdcMem = CreateCompatibleDC (NULL); + + /* Loop through spans */ + for (iSpan = 0; iSpan < iSpans; ++iSpan) + { + piWidth = piWidths + iSpan; + pPoint = pPoints + iSpan; + + /* Create a one-line DIB for the bit data */ + hBitmap = winCreateDIBNativeGDI (*piWidth, 1, pDrawable->depth, + NULL, (BITMAPINFO **) &pbmih); + + /* Select the span line line bitmap into the temporary DC */ + hbmpOrig = SelectObject (hdcMem, hBitmap); + + /* Blast bit data to the one-line DIB */ + SetDIBits (hdcMem, hBitmap, + 0, 1, + pSrc, + (BITMAPINFO *) pbmih, + DIB_RGB_COLORS); + + /* Blit the span line to the drawable */ + BitBlt (pGCPriv->hdcMem, + pPoint->x, pPoint->y, + *piWidth, 1, + hdcMem, + 0, 0, + NOTSRCCOPY); + + /* + * REMOVE - Visual verification only. + */ + BitBlt (pGCPriv->hdc, + pDrawable->width, pDrawable->height + pPoint->y, + *piWidth, 1, + hdcMem, + 0, 0, + SRCCOPY); + + /* Display some useful information */ + ErrorF ("(%dx%dx%d) (%d,%d) w: %d ps: %08x\n", + pDrawable->width, pDrawable->height, pDrawable->depth, + pPoint->x, pPoint->y, *piWidth, pSrc); + + /* Calculate offset of next bit source */ + pSrc += 4 * ((*piWidth + 31) / 32); + + /* Pop the span line bitmap out of the memory DC */ + SelectObject (hdcMem, hbmpOrig); + + /* Free the temporary bitmap */ + DeleteObject (hBitmap); + hBitmap = NULL; + } + + /* + * REMOVE - Visual verification only. + */ + DEBUG_MSG ("DRAWABLE_PIXMAP - GXinvert - Prior to invert"); + BitBlt (pGCPriv->hdc, + pDrawable->width * 2, pDrawable->height, + pDrawable->width, pDrawable->height, + pGCPriv->hdcMem, + 0, 0, + SRCCOPY); + DEBUG_MSG ("DRAWABLE_PIXMAP - GXinvert - Finished invert"); + + /* Release the scratch DC */ + DeleteDC (hdcMem); + break; + + case GXorReverse: + FatalError ("winSetSpans - DRAWABLE_PIXMAP - GXorReverse\n"); + break; + + case GXcopyInverted: + FatalError ("winSetSpans - DRAWABLE_PIXMAP - GXcopyInverted\n"); + break; + + case GXorInverted: + FatalError ("winSetSpans - DRAWABLE_PIXMAP - GXorInverted\n"); + break; + + case GXnand: + FatalError ("winSetSpans - DRAWABLE_PIXMAP - GXnand\n"); + break; + + case GXset: + FatalError ("winSetSpans - DRAWABLE_PIXMAP - GXset\n"); + break; + + default: + FatalError ("winSetSpans - DRAWABLE_PIXMAP - Unknown ROP\n"); + break; + } + + /* Push the drawable pixmap out of the GC HDC */ + SelectObject (pGCPriv->hdcMem, hbmpOrig); + break; + + case DRAWABLE_WINDOW: + FatalError ("\nwinSetSpansNativeGDI - DRAWABLE_WINDOW\n\n"); + + /* Branch on the raster operation type */ + switch (pGC->alu) + { + case GXclear: + ErrorF ("winSetSpans () - DRAWABLE_WINDOW - GXclear\n"); + break; + + case GXand: + ErrorF ("winSetSpans () - DRAWABLE_WINDOW - GXand\n"); + break; + + case GXandReverse: + ErrorF ("winSetSpans () - DRAWABLE_WINDOW - GXandReverse\n"); + break; + + case GXcopy: + ErrorF ("winSetSpans () - DRAWABLE_WINDOW - GXcopy\n"); + break; + + case GXandInverted: + ErrorF ("winSetSpans () - DRAWABLE_WINDOW - GXandInverted\n"); + break; + + case GXnoop: + ErrorF ("winSetSpans () - DRAWABLE_WINDOW - GXnoop\n"); + break; + + case GXxor: + ErrorF ("winSetSpans () - DRAWABLE_WINDOW - GXxor\n"); + break; + + case GXor: + ErrorF ("winSetSpans () - DRAWABLE_WINDOW - GXor\n"); + break; + + case GXnor: + ErrorF ("winSetSpans () - DRAWABLE_WINDOW - GXnor\n"); + break; + + case GXequiv: + ErrorF ("winSetSpans () - DRAWABLE_WINDOW - GXequiv\n"); + break; + + case GXinvert: + ErrorF ("winSetSpans () - DRAWABLE_WINDOW - GXinvert\n"); + break; + + case GXorReverse: + ErrorF ("winSetSpans () - DRAWABLE_WINDOW - GXorReverse\n"); + break; + + case GXcopyInverted: + ErrorF ("winSetSpans () - DRAWABLE_WINDOW - GXcopyInverted\n"); + break; + + case GXorInverted: + ErrorF ("winSetSpans () - DRAWABLE_WINDOW - GXorInverted\n"); + break; + + case GXnand: + ErrorF ("winSetSpans () - DRAWABLE_WINDOW - GXnand\n"); + break; + + case GXset: + ErrorF ("winSetSpans () - DRAWABLE_WINDOW - GXset\n"); + break; + + default: + ErrorF ("winSetSpans () - DRAWABLE_WINDOW - Unknown ROP\n"); + break; + } + break; + + case UNDRAWABLE_WINDOW: + FatalError ("\nwinSetSpansNativeGDI - UNDRAWABLE_WINDOW\n\n"); + break; + + case DRAWABLE_BUFFER: + FatalError ("\nwinSetSpansNativeGDI - DRAWABLE_BUFFER\n\n"); + break; + + default: + FatalError ("\nwinSetSpansNativeGDI - Unknown drawable type\n\n"); + break; + } +} diff --git a/hw/xwin/winshaddd.c b/hw/xwin/winshaddd.c new file mode 100644 index 000000000..9c14ebf34 --- /dev/null +++ b/hw/xwin/winshaddd.c @@ -0,0 +1,1362 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winshaddd.c,v 1.23 2003/02/12 15:01:38 alanh Exp $ */ + +#include "win.h" + +/* + * FIXME: Headers are broken, DEFINE_GUID doesn't work correctly, + * so we have to redefine it here. + */ +#ifdef DEFINE_GUID +#undef DEFINE_GUID +#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) GUID_EXT const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} +#endif /* DEFINE_GUID */ + + +/* + * FIXME: Headers are broken, IID_IDirectDraw4 has to be defined + * here manually. Should be handled by ddraw.h + */ +#ifndef IID_IDirectDraw2 +DEFINE_GUID( IID_IDirectDraw2,0xB3A6F3E0,0x2B43,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56 ); +#endif /* IID_IDirectDraw2 */ + + +/* + * Create the primary surface and attach the clipper. + * Used for both the initial surface creation and during + * WM_DISPLAYCHANGE messages. + */ + +Bool +winCreatePrimarySurfaceShadowDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + HRESULT ddrval = DD_OK; + DDSURFACEDESC ddsd; + + /* Describe the primary surface */ + ZeroMemory (&ddsd, sizeof (ddsd)); + ddsd.dwSize = sizeof (ddsd); + ddsd.dwFlags = DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + + /* Create the primary surface */ + ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2, + &ddsd, + &pScreenPriv->pddsPrimary, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winCreatePrimarySurfaceShadowDD - Could not create primary " + "surface: %08x\n", ddrval); + return FALSE; + } + +#if CYGDEBUG + ErrorF ("winCreatePrimarySurfaceShadowDD - Created primary surface\n"); +#endif + + /* + * Attach a clipper to the primary surface that will clip our blits to our + * display window. + */ + ddrval = IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary, + pScreenPriv->pddcPrimary); + if (FAILED (ddrval)) + { + ErrorF ("winCreatePrimarySurfaceShadowDD - Primary attach clipper " + "failed: %08x\n", + ddrval); + return FALSE; + } + +#if CYGDEBUG + ErrorF ("winCreatePrimarySurfaceShadowDD - Attached clipper to " + "primary surface\n"); +#endif + + /* Everything was correct */ + return TRUE; +} + + +/* + * Detach the clipper and release the primary surface. + * Called from WM_DISPLAYCHANGE. + */ + +Bool +winReleasePrimarySurfaceShadowDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + + ErrorF ("winReleasePrimarySurfaceShadowDD - Hello\n"); + + /* Release the primary surface and clipper, if they exist */ + if (pScreenPriv->pddsPrimary) + { + /* + * Detach the clipper from the primary surface. + * NOTE: We do this explicity for clarity. The Clipper is not released. + */ + IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary, + NULL); + + ErrorF ("winReleasePrimarySurfaceShadowDD - Detached clipper\n"); + + /* Release the primary surface */ + IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary); + pScreenPriv->pddsPrimary = NULL; + } + + ErrorF ("winReleasePrimarySurfaceShadowDD - Released primary surface\n"); + + return TRUE; +} + + +/* + * Create a DirectDraw surface for the shadow framebuffer; also create + * a primary surface object so we can blit to the display. + * + * Install a DirectDraw clipper on our primary surface object + * that clips our blits to the unobscured client area of our display window. + */ + +Bool +winAllocateFBShadowDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HRESULT ddrval = DD_OK; + DDSURFACEDESC ddsd; + DDSURFACEDESC *pddsdShadow = NULL; + +#if CYGDEBUG + ErrorF ("winAllocateFBShadowDD\n"); +#endif + + /* Create a clipper */ + ddrval = (*g_fpDirectDrawCreateClipper) (0, + &pScreenPriv->pddcPrimary, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDD - Could not create clipper: %08x\n", + ddrval); + return FALSE; + } + +#if CYGDEBUG + ErrorF ("winAllocateFBShadowDD - Created a clipper\n"); +#endif + + /* Get a device context for the screen */ + pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); + + /* Attach the clipper to our display window */ + ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary, + 0, + pScreenPriv->hwndScreen); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDD - Clipper not attached to " + "window: %08x\n", + ddrval); + return FALSE; + } + +#if CYGDEBUG + ErrorF ("winAllocateFBShadowDD - Attached clipper to window\n"); +#endif + + /* Create a DirectDraw object, store the address at lpdd */ + ddrval = (*g_fpDirectDrawCreate) (NULL, &pScreenPriv->pdd, NULL); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDD - Could not start DirectDraw: %08x\n", + ddrval); + return FALSE; + } + +#if CYGDEBUG + ErrorF ("winAllocateFBShadowDD () - Created and initialized DD\n"); +#endif + + /* Get a DirectDraw2 interface pointer */ + ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd, + &IID_IDirectDraw2, + (LPVOID*) &pScreenPriv->pdd2); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDD - Failed DD2 query: %08x\n", + ddrval); + return FALSE; + } + + /* Are we full screen? */ + if (pScreenInfo->fFullScreen) + { + DDSURFACEDESC ddsdCurrent; + DWORD dwRefreshRateCurrent = 0; + HDC hdc = NULL; + + /* Set the cooperative level to full screen */ + ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, + pScreenPriv->hwndScreen, + DDSCL_EXCLUSIVE + | DDSCL_FULLSCREEN); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDD - Could not set " + "cooperative level: %08x\n", + ddrval); + return FALSE; + } + + /* + * We only need to get the current refresh rate for comparison + * if a refresh rate has been passed on the command line. + */ + if (pScreenInfo->dwRefreshRate != 0) + { + ZeroMemory (&ddsdCurrent, sizeof (ddsdCurrent)); + ddsdCurrent.dwSize = sizeof (ddsdCurrent); + + /* Get information about current display settings */ + ddrval = IDirectDraw2_GetDisplayMode (pScreenPriv->pdd2, + &ddsdCurrent); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDD - Could not get current " + "refresh rate: %08x. Continuing.\n", + ddrval); + dwRefreshRateCurrent = 0; + } + else + { + /* Grab the current refresh rate */ + dwRefreshRateCurrent = ddsdCurrent.u2.dwRefreshRate; + } + } + + /* Clean up the refresh rate */ + if (dwRefreshRateCurrent == pScreenInfo->dwRefreshRate) + { + /* + * Refresh rate is non-specified or equal to current. + */ + pScreenInfo->dwRefreshRate = 0; + } + + /* Grab a device context for the screen */ + hdc = GetDC (NULL); + if (hdc == NULL) + { + ErrorF ("winAllocateFBShadowDD - GetDC () failed\n"); + return FALSE; + } + + /* Only change the video mode when different than current mode */ + if (!pScreenInfo->fMultipleMonitors + && (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN) + || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN) + || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL) + || pScreenInfo->dwRefreshRate != 0)) + { + ErrorF ("winAllocateFBShadowDD - Changing video mode\n"); + + /* Change the video mode to the mode requested */ + ddrval = IDirectDraw2_SetDisplayMode (pScreenPriv->pdd2, + pScreenInfo->dwWidth, + pScreenInfo->dwHeight, + pScreenInfo->dwBPP, + pScreenInfo->dwRefreshRate, + 0); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDD - Could not set "\ + "full screen display mode: %08x\n", + ddrval); + return FALSE; + } + } + else + { + ErrorF ("winAllocateFBShadowDD - Not changing video mode\n"); + } + + /* Release our DC */ + ReleaseDC (NULL, hdc); + hdc = NULL; + } + else + { + /* Set the cooperative level for windowed mode */ + ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, + pScreenPriv->hwndScreen, + DDSCL_NORMAL); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDD - Could not set "\ + "cooperative level: %08x\n", + ddrval); + return FALSE; + } + } + + /* Create the primary surface */ + if (!winCreatePrimarySurfaceShadowDD (pScreen)) + { + ErrorF ("winAllocateFBShadowDD - winCreatePrimarySurfaceShadowDD " + "failed\n"); + return FALSE; + } + + /* Describe the shadow surface to be created */ + /* NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface, + * as drawing, locking, and unlocking take forever + * with video memory surfaces. In addition, + * video memory is a somewhat scarce resource, + * so you shouldn't be allocating video memory when + * you have the option of using system memory instead. + */ + ZeroMemory (&ddsd, sizeof (ddsd)); + ddsd.dwSize = sizeof (ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + ddsd.dwHeight = pScreenInfo->dwHeight; + ddsd.dwWidth = pScreenInfo->dwWidth; + + /* Create the shadow surface */ + ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2, + &ddsd, + &pScreenPriv->pddsShadow, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDD - Could not create shadow "\ + "surface: %08x\n", ddrval); + return FALSE; + } + +#if CYGDEBUG + ErrorF ("winAllocateFBShadowDD - Created shadow\n"); +#endif + + /* Allocate a DD surface description for our screen privates */ + pddsdShadow = pScreenPriv->pddsdShadow = malloc (sizeof (DDSURFACEDESC)); + if (pddsdShadow == NULL) + { + ErrorF ("winAllocateFBShadowDD - Could not allocate surface "\ + "description memory\n"); + return FALSE; + } + ZeroMemory (pddsdShadow, sizeof (*pddsdShadow)); + pddsdShadow->dwSize = sizeof (*pddsdShadow); + +#if CYGDEBUG + ErrorF ("winAllocateFBShadowDD - Locking shadow\n"); +#endif + + /* Lock the shadow surface */ + ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, + NULL, + pddsdShadow, + DDLOCK_WAIT, + NULL); + if (FAILED (ddrval) || pddsdShadow->lpSurface == NULL) + { + ErrorF ("winAllocateFBShadowDD - Could not lock shadow "\ + "surface: %08x\n", ddrval); + return FALSE; + } + +#if CYGDEBUG + ErrorF ("winAllocateFBShadowDD - Locked shadow\n"); +#endif + + /* We don't know how to deal with anything other than RGB */ + if (!(pddsdShadow->ddpfPixelFormat.dwFlags & DDPF_RGB)) + { + ErrorF ("winAllocateFBShadowDD - Color format other than RGB\n"); + return FALSE; + } + + /* Grab the pitch from the surface desc */ + pScreenInfo->dwStride = (pddsdShadow->u1.lPitch * 8) + / pScreenInfo->dwBPP; + + /* Save the pointer to our surface memory */ + pScreenInfo->pfb = pddsdShadow->lpSurface; + + /* Grab the color depth and masks from the surface description */ + pScreenPriv->dwRedMask = pddsdShadow->ddpfPixelFormat.u2.dwRBitMask; + pScreenPriv->dwGreenMask = pddsdShadow->ddpfPixelFormat.u3.dwGBitMask; + pScreenPriv->dwBlueMask = pddsdShadow->ddpfPixelFormat.u4.dwBBitMask; + +#if CYGDEBUG + ErrorF ("winAllocateFBShadowDD - Returning\n"); +#endif + + return TRUE; +} + + +/* + * Transfer the damaged regions of the shadow framebuffer to the display. + */ + +void +winShadowUpdateDD (ScreenPtr pScreen, + shadowBufPtr pBuf) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + RegionPtr damage = &pBuf->damage; + HRESULT ddrval = DD_OK; + RECT rcDest, rcSrc; + POINT ptOrigin; + DWORD dwBox = REGION_NUM_RECTS (damage); + BoxPtr pBox = REGION_RECTS (damage); + HRGN hrgnTemp = NULL, hrgnCombined = NULL; + + /* + * Return immediately if the app is not active + * and we are fullscreen, or if we have a bad display depth + */ + if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) + || pScreenPriv->fBadDepth) return; + + /* Get the origin of the window in the screen coords */ + ptOrigin.x = pScreenInfo->dwXOffset; + ptOrigin.y = pScreenInfo->dwYOffset; + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&ptOrigin, 1); + + /* Unlock the shadow surface, so we can blit */ + ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL); + if (FAILED (ddrval)) + { + ErrorF ("winShadowUpdateProcDD - Unlock failed\n"); + return; + } + + /* + * Handle small regions with multiple blits, + * handle large regions by creating a clipping region and + * doing a single blit constrained to that clipping region. + */ + if (pScreenInfo->dwClipUpdatesNBoxes == 0 + || dwBox < pScreenInfo->dwClipUpdatesNBoxes) + { + /* Loop through all boxes in the damaged region */ + while (dwBox--) + { + /* Assign damage box to source rectangle */ + rcSrc.left = pBox->x1; + rcSrc.top = pBox->y1; + rcSrc.right = pBox->x2; + rcSrc.bottom = pBox->y2; + + /* Calculate destination rectange */ + rcDest.left = ptOrigin.x + rcSrc.left; + rcDest.top = ptOrigin.y + rcSrc.top; + rcDest.right = ptOrigin.x + rcSrc.right; + rcDest.bottom = ptOrigin.y + rcSrc.bottom; + + /* Blit the damaged areas */ + ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, + &rcDest, + pScreenPriv->pddsShadow, + &rcSrc, + DDBLT_WAIT, + NULL); + + /* Get a pointer to the next box */ + ++pBox; + } + } + else + { + BoxPtr pBoxExtents = REGION_EXTENTS (pScreen, damage); + + /* Compute a GDI region from the damaged region */ + hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); + dwBox--; + pBox++; + while (dwBox--) + { + hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); + CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR); + DeleteObject (hrgnTemp); + pBox++; + } + + /* Install the GDI region as a clipping region */ + SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined); + DeleteObject (hrgnCombined); + hrgnCombined = NULL; + + /* Calculating a bounding box for the source is easy */ + rcSrc.left = pBoxExtents->x1; + rcSrc.top = pBoxExtents->y1; + rcSrc.right = pBoxExtents->x2; + rcSrc.bottom = pBoxExtents->y2; + + /* Calculating a bounding box for the destination is trickier */ + rcDest.left = ptOrigin.x + rcSrc.left; + rcDest.top = ptOrigin.y + rcSrc.top; + rcDest.right = ptOrigin.x + rcSrc.right; + rcDest.bottom = ptOrigin.y + rcSrc.bottom; + + /* Our Blt should be clipped to the invalidated region */ + ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, + &rcDest, + pScreenPriv->pddsShadow, + &rcSrc, + DDBLT_WAIT, + NULL); + + /* Reset the clip region */ + SelectClipRgn (pScreenPriv->hdcScreen, NULL); + } + + /* Relock the shadow surface */ + ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, + NULL, + pScreenPriv->pddsdShadow, + DDLOCK_WAIT, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winShadowUpdateProcDD - Lock failed\n"); + return; + } + + /* Has our memory pointer changed? */ + if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface) + { + ErrorF ("winShadowUpdateProcDD - Memory location of the shadow " + "surface has changed, trying to update the root window " + "pixmap header to point to the new address. If you get " + "this message and Cygwin/XFree86 freezes or crashes " + "after this message then send a problem report and your " + "/tmp/XWin.log file to cygwin-xfree@cygwin.com\n"); + + /* Location of shadow framebuffer has changed */ + pScreenInfo->pfb = pScreenPriv->pddsdShadow->lpSurface; + + /* Update the screen pixmap */ + if (!(*pScreen->ModifyPixmapHeader)(pScreen->devPrivate, + pScreen->width, + pScreen->height, + pScreen->rootDepth, + BitsPerPixel (pScreen->rootDepth), + PixmapBytePad (pScreenInfo->dwStride, + pScreenInfo->dwBPP), + pScreenInfo->pfb)) + { + ErrorF ("winShadowUpdateProcDD - Bits changed, could not " + "notify fb.\n"); + return; + } + } +} + + +/* + * Call the wrapped CloseScreen function. + * + * Free our resources and private structures. + */ + +Bool +winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + Bool fReturn; + +#if CYGDEBUG + ErrorF ("winCloseScreenShadowDD - Freeing screen resources\n"); +#endif + + /* Flag that the screen is closed */ + pScreenPriv->fClosed = TRUE; + pScreenPriv->fActive = FALSE; + + /* Call the wrapped CloseScreen procedure */ + pScreen->CloseScreen = pScreenPriv->CloseScreen; + fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); + + /* Free the screen DC */ + ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen); + + /* Delete the window property */ + RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); + + /* Free the shadow surface, if there is one */ + if (pScreenPriv->pddsShadow) + { + IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL); + IDirectDrawSurface2_Release (pScreenPriv->pddsShadow); + pScreenPriv->pddsShadow = NULL; + } + + /* Detach the clipper from the primary surface and release the clipper. */ + if (pScreenPriv->pddcPrimary) + { + /* Detach the clipper */ + IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary, + NULL); + + /* Release the clipper object */ + IDirectDrawClipper_Release (pScreenPriv->pddcPrimary); + pScreenPriv->pddcPrimary = NULL; + } + + /* Release the primary surface, if there is one */ + if (pScreenPriv->pddsPrimary) + { + IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary); + pScreenPriv->pddsPrimary = NULL; + } + + /* Free the DirectDraw2 object, if there is one */ + if (pScreenPriv->pdd2) + { + IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd2); + IDirectDraw2_Release (pScreenPriv->pdd2); + pScreenPriv->pdd2 = NULL; + } + + /* Free the DirectDraw object, if there is one */ + if (pScreenPriv->pdd) + { + IDirectDraw_Release (pScreenPriv->pdd); + pScreenPriv->pdd = NULL; + } + + /* Kill our window */ + if (pScreenPriv->hwndScreen) + { + DestroyWindow (pScreenPriv->hwndScreen); + pScreenPriv->hwndScreen = NULL; + } + + /* Destroy the thread startup mutex */ + pthread_mutex_destroy (&pScreenPriv->pmServerStarted); + + /* Kill our screeninfo's pointer to the screen */ + pScreenInfo->pScreen = NULL; + + /* Invalidate the ScreenInfo's fb pointer */ + pScreenInfo->pfb = NULL; + + /* Free the screen privates for this screen */ + free ((pointer) pScreenPriv); + + return fReturn; +} + + +/* + * Tell mi what sort of visuals we need. + * + * Generally we only need one visual, as our screen can only + * handle one format at a time, I believe. You may want + * to verify that last sentence. + */ + +Bool +winInitVisualsShadowDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + DWORD dwRedBits, dwGreenBits, dwBlueBits; + + /* Count the number of ones in each color mask */ + dwRedBits = winCountBits (pScreenPriv->dwRedMask); + dwGreenBits = winCountBits (pScreenPriv->dwGreenMask); + dwBlueBits = winCountBits (pScreenPriv->dwBlueMask); + + /* Store the maximum number of ones in a color mask as the bitsPerRGB */ + if (dwRedBits == 0 || dwGreenBits == 0 || dwBlueBits == 0) + pScreenPriv->dwBitsPerRGB = 8; + else if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits) + pScreenPriv->dwBitsPerRGB = dwRedBits; + else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits) + pScreenPriv->dwBitsPerRGB = dwGreenBits; + else + pScreenPriv->dwBitsPerRGB = dwBlueBits; + + ErrorF ("winInitVisualsShadowDD - Masks %08x %08x %08x BPRGB %d d %d " + "bpp %d\n", + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask, + pScreenPriv->dwBitsPerRGB, + pScreenInfo->dwDepth, + pScreenInfo->dwBPP); + + /* Create a single visual according to the Windows screen depth */ + switch (pScreenInfo->dwDepth) + { + case 24: + case 16: + case 15: +#if defined(XFree86Server) + /* Create the real visual */ + if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, + TrueColorMask, + pScreenPriv->dwBitsPerRGB, + TrueColor, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsShadowDD - miSetVisualTypesAndMasks " + "failed for TrueColor\n"); + return FALSE; + } + +#if WIN_EMULATE_PSEUDO_SUPPORT + if (!pScreenInfo->fEmulatePseudo) + break; + + /* Setup a pseudocolor visual */ + if (!miSetVisualTypesAndMasks (8, + PseudoColorMask, + 8, + -1, + 0, + 0, + 0)) + { + ErrorF ("winInitVisualsShadowDD - miSetVisualTypesAndMasks " + "failed for PseudoColor\n"); + return FALSE; + } +#endif +#else /* XFree86Server */ + /* Create the real visual */ + if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth, + TrueColorMask, + pScreenPriv->dwBitsPerRGB, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsShadowDD - fbSetVisualTypesAndMasks " + "failed for TrueColor\n"); + return FALSE; + } + +#if WIN_EMULATE_PSEUDO_SUPPORT + if (!pScreenInfo->fEmulatePseudo) + break; + + /* Setup a pseudocolor visual */ + if (!fbSetVisualTypesAndMasks (8, + PseudoColorMask, + 8, + 0, + 0, + 0)) + { + ErrorF ("winInitVisualsShadowDD - fbSetVisualTypesAndMasks " + "failed for PseudoColor\n"); + return FALSE; + } +#endif +#endif /* XFree86Server */ + break; + + case 8: +#if defined(XFree86Server) + if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, + pScreenInfo->fFullScreen + ? PseudoColorMask : StaticColorMask, + pScreenPriv->dwBitsPerRGB, + pScreenInfo->fFullScreen + ? PseudoColor : StaticColor, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsShadowDD - miSetVisualTypesAndMasks " + "failed\n"); + return FALSE; + } +#else /* XFree86Server */ + if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth, + pScreenInfo->fFullScreen + ? PseudoColorMask : StaticColorMask, + pScreenPriv->dwBitsPerRGB, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsShadowDD - fbSetVisualTypesAndMasks " + "failed\n"); + return FALSE; + } +#endif /* XFree86Server */ + break; + + default: + ErrorF ("winInitVisualsShadowDD - Unknown screen depth\n"); + return FALSE; + } + +#if CYGDEBUG + ErrorF ("winInitVisualsShadowDD - Returning\n"); +#endif + + return TRUE; +} + + +/* + * Adjust the user proposed video mode + */ + +Bool +winAdjustVideoModeShadowDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HDC hdc = NULL; + DWORD dwBPP; + + /* We're in serious trouble if we can't get a DC */ + hdc = GetDC (NULL); + if (hdc == NULL) + { + ErrorF ("winAdjustVideoModeShadowDD - GetDC () failed\n"); + return FALSE; + } + + /* Query GDI for current display depth */ + dwBPP = GetDeviceCaps (hdc, BITSPIXEL); + + /* DirectDraw can only change the depth in fullscreen mode */ + if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP) + { + /* No -depth parameter passed, let the user know the depth being used */ + ErrorF ("winAdjustVideoModeShadowDD - Using Windows display " + "depth of %d bits per pixel\n", dwBPP); + + /* Use GDI's depth */ + pScreenInfo->dwBPP = dwBPP; + } + else if (pScreenInfo->fFullScreen + && pScreenInfo->dwBPP != dwBPP) + { + /* FullScreen, and GDI depth differs from -depth parameter */ + ErrorF ("winAdjustVideoModeShadowDD - FullScreen, using command line " + "bpp: %d\n", pScreenInfo->dwBPP); + } + else if (dwBPP != pScreenInfo->dwBPP) + { + /* Windowed, and GDI depth differs from -depth parameter */ + ErrorF ("winAdjustVideoModeShadowDD - Windowed, command line bpp: " + "%d, using bpp: %d\n", pScreenInfo->dwBPP, dwBPP); + + /* We'll use GDI's depth */ + pScreenInfo->dwBPP = dwBPP; + } + + /* See if the shadow bitmap will be larger than the DIB size limit */ + if (pScreenInfo->dwWidth * pScreenInfo->dwHeight * pScreenInfo->dwBPP + >= WIN_DIB_MAXIMUM_SIZE) + { + ErrorF ("winAdjustVideoModeShadowDD - Requested DirectDraw surface " + "will be larger than %d MB. The surface may fail to be " + "allocated on Windows 95, 98, or Me, due to a %d MB limit in " + "DIB size. This limit does not apply to Windows NT/2000, and " + "this message may be ignored on those platforms.\n", + WIN_DIB_MAXIMUM_SIZE_MB, WIN_DIB_MAXIMUM_SIZE_MB); + } + + /* Release our DC */ + ReleaseDC (NULL, hdc); + return TRUE; +} + + +/* + * Blt exposed regions to the screen + */ + +Bool +winBltExposedRegionsShadowDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + RECT rcSrc, rcDest; + POINT ptOrigin; + HDC hdcUpdate = NULL; + PAINTSTRUCT ps; + HRESULT ddrval = DD_OK; + Bool fReturn = TRUE; + Bool fLocked = TRUE; + int i; + + /* BeginPaint gives us an hdc that clips to the invalidated region */ + hdcUpdate = BeginPaint (pScreenPriv->hwndScreen, &ps); + if (hdcUpdate == NULL) + { + ErrorF ("winBltExposedRegionsShadowDD - BeginPaint () returned " + "a NULL device context handle. Aborting blit attempt.\n"); + return FALSE; + } + + /* Unlock the shadow surface, so we can blit */ + ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL); + if (FAILED (ddrval)) + { + fReturn = FALSE; + goto winBltExposedRegionsShadowDD_Exit; + } + else + { + /* Flag that we have unlocked the shadow surface */ + fLocked = FALSE; + } + + /* Get the origin of the window in the screen coords */ + ptOrigin.x = pScreenInfo->dwXOffset; + ptOrigin.y = pScreenInfo->dwYOffset; + + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&ptOrigin, 1); + rcDest.left = ptOrigin.x; + rcDest.right = ptOrigin.x + pScreenInfo->dwWidth; + rcDest.top = ptOrigin.y; + rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight; + + /* Source can be enter shadow surface, as Blt should clip */ + rcSrc.left = 0; + rcSrc.top = 0; + rcSrc.right = pScreenInfo->dwWidth; + rcSrc.bottom = pScreenInfo->dwHeight; + + /* Try to regain the primary surface and blit again if we've lost it */ + for (i = 0; i <= WIN_REGAIN_SURFACE_RETRIES; ++i) + { + /* Our Blt should be clipped to the invalidated region */ + ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, + &rcDest, + pScreenPriv->pddsShadow, + &rcSrc, + DDBLT_WAIT, + NULL); + if (ddrval == DDERR_SURFACELOST) + { + /* Surface was lost */ + ErrorF ("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Blt " + "reported that the primary surface was lost, " + "trying to restore, retry: %d\n", i + 1); + + /* Try to restore the surface, once */ + ddrval = IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary); + ErrorF ("winBltExposedRegionsShadowDDNL - " + "IDirectDrawSurface2_Restore returned: "); + if (ddrval == DD_OK) + continue; + else if (ddrval == DDERR_WRONGMODE) + ErrorF ("DDERR_WRONGMODE\n"); + else if (ddrval == DDERR_INCOMPATIBLEPRIMARY) + ErrorF ("DDERR_INCOMPATIBLEPRIMARY\n"); + else if (ddrval == DDERR_UNSUPPORTED) + ErrorF ("DDERR_UNSUPPORTED\n"); + else if (ddrval == DDERR_INVALIDPARAMS) + ErrorF ("DDERR_INVALIDPARAMS\n"); + else if (ddrval == DDERR_INVALIDOBJECT) + ErrorF ("DDERR_INVALIDOBJECT\n"); + else + ErrorF ("unknown error: %08x\n", ddrval); + + /* Loop around to try the blit one more time */ + continue; + } + else if (FAILED (ddrval)) + { + fReturn = FALSE; + ErrorF ("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Blt " + "failed, but surface not lost: %08x %d\n", ddrval, ddrval); + goto winBltExposedRegionsShadowDD_Exit; + } + else + { + /* Success, stop looping */ + break; + } + } + + /* Relock the shadow surface */ + ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, + NULL, + pScreenPriv->pddsdShadow, + DDLOCK_WAIT, + NULL); + if (FAILED (ddrval)) + { + fReturn = FALSE; + ErrorF ("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Lock " + "failed\n"); + goto winBltExposedRegionsShadowDD_Exit; + } + else + { + /* Indicate that we have relocked the shadow surface */ + fLocked = TRUE; + } + + /* Has our memory pointer changed? */ + if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface) + winUpdateFBPointer (pScreen, + pScreenPriv->pddsdShadow->lpSurface); + + winBltExposedRegionsShadowDD_Exit: + /* EndPaint frees the DC */ + if (hdcUpdate != NULL) + EndPaint (pScreenPriv->hwndScreen, &ps); + + /* + * Relock the surface if it is not locked. We don't care if locking fails, + * as it will cause the server to shutdown within a few more operations. + */ + if (!fLocked) + { + IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, + NULL, + pScreenPriv->pddsdShadow, + DDLOCK_WAIT, + NULL); + + /* Has our memory pointer changed? */ + if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface) + winUpdateFBPointer (pScreen, + pScreenPriv->pddsdShadow->lpSurface); + + fLocked = TRUE; + } + return fReturn; +} + + +/* + * Do any engine-specific appliation-activation processing + */ + +Bool +winActivateAppShadowDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + + /* + * Do we have a surface? + * Are we active? + * Are we fullscreen? + */ + if (pScreenPriv != NULL + && pScreenPriv->pddsPrimary != NULL + && pScreenPriv->fActive) + { + /* Primary surface was lost, restore it */ + IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary); + } + + return TRUE; +} + + +/* + * Reblit the shadow framebuffer to the screen. + */ + +Bool +winRedrawScreenShadowDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HRESULT ddrval = DD_OK; + RECT rcSrc, rcDest; + POINT ptOrigin; + + /* Get the origin of the window in the screen coords */ + ptOrigin.x = pScreenInfo->dwXOffset; + ptOrigin.y = pScreenInfo->dwYOffset; + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&ptOrigin, 1); + rcDest.left = ptOrigin.x; + rcDest.right = ptOrigin.x + pScreenInfo->dwWidth; + rcDest.top = ptOrigin.y; + rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight; + + /* Source can be entire shadow surface, as Blt should clip for us */ + rcSrc.left = 0; + rcSrc.top = 0; + rcSrc.right = pScreenInfo->dwWidth; + rcSrc.bottom = pScreenInfo->dwHeight; + + /* Redraw the whole window, to take account for the new colors */ + ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, + &rcDest, + pScreenPriv->pddsShadow, + &rcSrc, + DDBLT_WAIT, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winRedrawScreenShadowDD - IDirectDrawSurface_Blt () " + "failed: %08x\n", + ddrval); + } + + return TRUE; +} + + +/* + * Realize the currently installed colormap + */ + +Bool +winRealizeInstalledPaletteShadowDD (ScreenPtr pScreen) +{ + return TRUE; +} + + +/* + * Install the specified colormap + */ + +Bool +winInstallColormapShadowDD (ColormapPtr pColormap) +{ + ScreenPtr pScreen = pColormap->pScreen; + winScreenPriv(pScreen); + winCmapPriv(pColormap); + HRESULT ddrval = DD_OK; + + /* Install the DirectDraw palette on the primary surface */ + ddrval = IDirectDrawSurface2_SetPalette (pScreenPriv->pddsPrimary, + pCmapPriv->lpDDPalette); + if (FAILED (ddrval)) + { + ErrorF ("winInstallColormapShadowDD - Failed installing the " + "DirectDraw palette.\n"); + return FALSE; + } + + /* Save a pointer to the newly installed colormap */ + pScreenPriv->pcmapInstalled = pColormap; + + return TRUE; +} + + +/* + * Store the specified colors in the specified colormap + */ + +Bool +winStoreColorsShadowDD (ColormapPtr pColormap, + int ndef, + xColorItem *pdefs) +{ + ScreenPtr pScreen = pColormap->pScreen; + winScreenPriv(pScreen); + winCmapPriv(pColormap); + ColormapPtr curpmap = pScreenPriv->pcmapInstalled; + HRESULT ddrval = DD_OK; + + /* Put the X colormap entries into the Windows logical palette */ + ddrval = IDirectDrawPalette_SetEntries (pCmapPriv->lpDDPalette, + 0, + pdefs[0].pixel, + ndef, + pCmapPriv->peColors + + pdefs[0].pixel); + if (FAILED (ddrval)) + { + ErrorF ("winStoreColorsShadowDDNL - SetEntries () failed\n"); + return FALSE; + } + + /* Don't install the DirectDraw palette if the colormap is not installed */ + if (pColormap != curpmap) + { + return TRUE; + } + + if (!winInstallColormapShadowDD (pColormap)) + { + ErrorF ("winStoreColorsShadowDDNL - Failed installing colormap\n"); + return FALSE; + } + + return TRUE; +} + + +/* + * Colormap initialization procedure + */ + +Bool +winCreateColormapShadowDD (ColormapPtr pColormap) +{ + HRESULT ddrval = DD_OK; + ScreenPtr pScreen = pColormap->pScreen; + winScreenPriv(pScreen); + winCmapPriv(pColormap); + + /* Create a DirectDraw palette */ + ddrval = IDirectDraw2_CreatePalette (pScreenPriv->pdd, + DDPCAPS_8BIT | DDPCAPS_ALLOW256, + pCmapPriv->peColors, + &pCmapPriv->lpDDPalette, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winCreateColormapShadowDDNL - CreatePalette failed\n"); + return FALSE; + } + + return TRUE; +} + + +/* + * Colormap destruction procedure + */ + +Bool +winDestroyColormapShadowDD (ColormapPtr pColormap) +{ + winScreenPriv(pColormap->pScreen); + winCmapPriv(pColormap); + HRESULT ddrval = DD_OK; + + /* + * Is colormap to be destroyed the default? + * + * Non-default colormaps should have had winUninstallColormap + * called on them before we get here. The default colormap + * will not have had winUninstallColormap called on it. Thus, + * we need to handle the default colormap in a special way. + */ + if (pColormap->flags & IsDefault) + { +#if CYGDEBUG + ErrorF ("winDestroyColormapShadowDDNL - Destroying default " + "colormap\n"); +#endif + + /* + * FIXME: Walk the list of all screens, popping the default + * palette out of each screen device context. + */ + + /* Pop the palette out of the primary surface */ + ddrval = IDirectDrawSurface2_SetPalette (pScreenPriv->pddsPrimary, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winDestroyColormapShadowDDNL - Failed freeing the " + "default colormap DirectDraw palette.\n"); + return FALSE; + } + + /* Clear our private installed colormap pointer */ + pScreenPriv->pcmapInstalled = NULL; + } + + /* Release the palette */ + IDirectDrawPalette_Release (pCmapPriv->lpDDPalette); + + /* Invalidate the colormap privates */ + pCmapPriv->lpDDPalette = NULL; + + return TRUE; +} + + +/* + * Set engine specific functions + */ + +Bool +winSetEngineFunctionsShadowDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Set our pointers */ + pScreenPriv->pwinAllocateFB = winAllocateFBShadowDD; + pScreenPriv->pwinShadowUpdate = winShadowUpdateDD; + pScreenPriv->pwinCloseScreen = winCloseScreenShadowDD; + pScreenPriv->pwinInitVisuals = winInitVisualsShadowDD; + pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowDD; + if (pScreenInfo->fFullScreen) + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen; + else + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; + pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB; + pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowDD; + pScreenPriv->pwinActivateApp = winActivateAppShadowDD; + pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowDD; + pScreenPriv->pwinRealizeInstalledPalette + = winRealizeInstalledPaletteShadowDD; + pScreenPriv->pwinInstallColormap = winInstallColormapShadowDD; + pScreenPriv->pwinStoreColors = winStoreColorsShadowDD; + pScreenPriv->pwinCreateColormap = winCreateColormapShadowDD; + pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowDD; + pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)())NoopDDA; + pScreenPriv->pwinCreatePrimarySurface = winCreatePrimarySurfaceShadowDD; + pScreenPriv->pwinReleasePrimarySurface = winReleasePrimarySurfaceShadowDD; + + return TRUE; +} + diff --git a/hw/xwin/winshadddnl.c b/hw/xwin/winshadddnl.c new file mode 100644 index 000000000..69396a79b --- /dev/null +++ b/hw/xwin/winshadddnl.c @@ -0,0 +1,1288 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winshadddnl.c,v 1.24 2003/02/12 15:01:38 alanh Exp $ */ + +#include "win.h" + +/* + * FIXME: Headers are broken, DEFINE_GUID doesn't work correctly, + * so we have to redefine it here. + */ +#ifdef DEFINE_GUID +#undef DEFINE_GUID +#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) GUID_EXT const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} +#endif /* DEFINE_GUID */ + +/* + * FIXME: Headers are broken, IID_IDirectDraw4 has to be defined + * here manually. Should be handled by ddraw.h + */ +#ifndef IID_IDirectDraw4 +DEFINE_GUID( IID_IDirectDraw4, 0x9c59509a,0x39bd,0x11d1,0x8c,0x4a,0x00,0xc0,0x4f,0xd9,0x30,0xc5 ); +#endif /* IID_IDirectDraw4 */ + + +/* + * Create the primary surface and attach the clipper. + * Used for both the initial surface creation and during + * WM_DISPLAYCHANGE messages. + */ + +Bool +winCreatePrimarySurfaceShadowDDNL (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + HRESULT ddrval = DD_OK; + DDSURFACEDESC2 ddsd; + + ErrorF ("winCreatePrimarySurfaceShadowDDNL - Creating primary surface\n"); + + /* Describe the primary surface */ + ZeroMemory (&ddsd, sizeof (ddsd)); + ddsd.dwSize = sizeof (ddsd); + ddsd.dwFlags = DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + + /* Create the primary surface */ + ddrval = IDirectDraw4_CreateSurface (pScreenPriv->pdd4, + &ddsd, + &pScreenPriv->pddsPrimary4, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winCreatePrimarySurfaceShadowDDNL - Could not create primary " + "surface: %08x\n", + ddrval); + return FALSE; + } + +#if 1 + ErrorF ("winCreatePrimarySurfaceShadowDDNL - Created primary surface\n"); +#endif + + /* Attach our clipper to our primary surface handle */ + ddrval = IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4, + pScreenPriv->pddcPrimary); + if (FAILED (ddrval)) + { + ErrorF ("winCreatePrimarySurfaceShadowDDNL - Primary attach clipper " + "failed: %08x\n", + ddrval); + return FALSE; + } + +#if 1 + ErrorF ("winCreatePrimarySurfaceShadowDDNL - Attached clipper to primary " + "surface\n"); +#endif + + /* Everything was correct */ + return TRUE; +} + + +/* + * Detach the clipper and release the primary surface. + * Called from WM_DISPLAYCHANGE. + */ + +Bool +winReleasePrimarySurfaceShadowDDNL (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + + ErrorF ("winReleasePrimarySurfaceShadowDDNL - Hello\n"); + + /* Release the primary surface and clipper, if they exist */ + if (pScreenPriv->pddsPrimary4) + { + /* + * Detach the clipper from the primary surface. + * NOTE: We do this explicity for clarity. The Clipper is not released. + */ + IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4, + NULL); + + ErrorF ("winReleasePrimarySurfaceShadowDDNL - Detached clipper\n"); + + /* Release the primary surface */ + IDirectDrawSurface4_Release (pScreenPriv->pddsPrimary4); + pScreenPriv->pddsPrimary4 = NULL; + } + + ErrorF ("winReleasePrimarySurfaceShadowDDNL - Released primary surface\n"); + + return TRUE; +} + + +/* + * Create a DirectDraw surface for the shadow framebuffer; also create + * a primary surface object so we can blit to the display. + * + * Install a DirectDraw clipper on our primary surface object + * that clips our blits to the unobscured client area of our display window. + */ + +Bool +winAllocateFBShadowDDNL (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HRESULT ddrval = DD_OK; + DDSURFACEDESC2 ddsdShadow; + char *lpSurface = NULL; + DDPIXELFORMAT ddpfPrimary; + +#if CYGDEBUG + ErrorF ("winAllocateFBShadowDDNL - w %d h %d d %d\n", + pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwDepth); +#endif + + /* Allocate memory for our shadow surface */ + lpSurface = malloc (pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight); + if (lpSurface == NULL) + { + ErrorF ("winAllocateFBShadowDDNL - Could not allocate bits\n"); + return FALSE; + } + + /* + * Initialize the framebuffer memory so we don't get a + * strange display at startup + */ + ZeroMemory (lpSurface, pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight); + + /* Create a clipper */ + ddrval = (*g_fpDirectDrawCreateClipper) (0, + &pScreenPriv->pddcPrimary, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Could not attach clipper: %08x\n", + ddrval); + return FALSE; + } + +#if CYGDEBUG + ErrorF ("winAllocateFBShadowDDNL - Created a clipper\n"); +#endif + + /* Get a device context for the screen */ + pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); + + /* Attach the clipper to our display window */ + ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary, + 0, + pScreenPriv->hwndScreen); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Clipper not attached " + "to window: %08x\n", + ddrval); + return FALSE; + } + +#if CYGDEBUG + ErrorF ("winAllocateFBShadowDDNL - Attached clipper to window\n"); +#endif + + /* Create a DirectDraw object, store the address at lpdd */ + ddrval = (*g_fpDirectDrawCreate) (NULL, + (LPDIRECTDRAW*) &pScreenPriv->pdd, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Could not start " + "DirectDraw: %08x\n", + ddrval); + return FALSE; + } + +#if CYGDEBUG + ErrorF ("winAllocateFBShadowDDNL - Created and initialized DD\n"); +#endif + + /* Get a DirectDraw4 interface pointer */ + ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd, + &IID_IDirectDraw4, + (LPVOID*) &pScreenPriv->pdd4); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Failed DD4 query: %08x\n", + ddrval); + return FALSE; + } + + /* Are we full screen? */ + if (pScreenInfo->fFullScreen) + { + DDSURFACEDESC2 ddsdCurrent; + DWORD dwRefreshRateCurrent = 0; + HDC hdc = NULL; + + /* Set the cooperative level to full screen */ + ddrval = IDirectDraw4_SetCooperativeLevel (pScreenPriv->pdd4, + pScreenPriv->hwndScreen, + DDSCL_EXCLUSIVE + | DDSCL_FULLSCREEN); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Could not set " + "cooperative level: %08x\n", + ddrval); + return FALSE; + } + + /* + * We only need to get the current refresh rate for comparison + * if a refresh rate has been passed on the command line. + */ + if (pScreenInfo->dwRefreshRate != 0) + { + ZeroMemory (&ddsdCurrent, sizeof (ddsdCurrent)); + ddsdCurrent.dwSize = sizeof (ddsdCurrent); + + /* Get information about current display settings */ + ddrval = IDirectDraw4_GetDisplayMode (pScreenPriv->pdd4, + &ddsdCurrent); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Could not get current " + "refresh rate: %08x. Continuing.\n", + ddrval); + dwRefreshRateCurrent = 0; + } + else + { + /* Grab the current refresh rate */ + dwRefreshRateCurrent = ddsdCurrent.u2.dwRefreshRate; + } + } + + /* Clean up the refresh rate */ + if (dwRefreshRateCurrent == pScreenInfo->dwRefreshRate) + { + /* + * Refresh rate is non-specified or equal to current. + */ + pScreenInfo->dwRefreshRate = 0; + } + + /* Grab a device context for the screen */ + hdc = GetDC (NULL); + if (hdc == NULL) + { + ErrorF ("winAllocateFBShadowDDNL - GetDC () failed\n"); + return FALSE; + } + + /* Only change the video mode when different than current mode */ + if (!pScreenInfo->fMultipleMonitors + && (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN) + || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN) + || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL) + || pScreenInfo->dwRefreshRate != 0)) + { + ErrorF ("winAllocateFBShadowDDNL - Changing video mode\n"); + + /* Change the video mode to the mode requested */ + ddrval = IDirectDraw4_SetDisplayMode (pScreenPriv->pdd4, + pScreenInfo->dwWidth, + pScreenInfo->dwHeight, + pScreenInfo->dwBPP, + pScreenInfo->dwRefreshRate, + 0); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Could not set " + "full screen display mode: %08x\n", + ddrval); + return FALSE; + } + } + else + { + ErrorF ("winAllocateFBShadowDDNL - Not changing video mode\n"); + } + + /* Release our DC */ + ReleaseDC (NULL, hdc); + hdc = NULL; + } + else + { + /* Set the cooperative level for windowed mode */ + ddrval = IDirectDraw4_SetCooperativeLevel (pScreenPriv->pdd4, + pScreenPriv->hwndScreen, + DDSCL_NORMAL); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Could not set " + "cooperative level: %08x\n", + ddrval); + return FALSE; + } + } + + /* Create the primary surface */ + if (!winCreatePrimarySurfaceShadowDDNL (pScreen)) + { + ErrorF ("winAllocateFBShadowDDNL - winCreatePrimarySurfaceShadowDDNL " + "failed\n"); + return FALSE; + } + + /* Get primary surface's pixel format */ + ZeroMemory (&ddpfPrimary, sizeof (ddpfPrimary)); + ddpfPrimary.dwSize = sizeof (ddpfPrimary); + ddrval = IDirectDrawSurface4_GetPixelFormat (pScreenPriv->pddsPrimary4, + &ddpfPrimary); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Could not get primary " + "pixformat: %08x\n", + ddrval); + return FALSE; + } + +#if CYGDEBUG + ErrorF ("winAllocateFBShadowDDNL - Primary masks: %08x %08x %08x " + "dwRGBBitCount: %d\n", + ddpfPrimary.u2.dwRBitMask, + ddpfPrimary.u3.dwGBitMask, + ddpfPrimary.u4.dwBBitMask, + ddpfPrimary.u1.dwRGBBitCount); +#endif + + /* Describe the shadow surface to be created */ + /* + * NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface, + * as drawing, locking, and unlocking take forever + * with video memory surfaces. In addition, + * video memory is a somewhat scarce resource, + * so you shouldn't be allocating video memory when + * you have the option of using system memory instead. + */ + ZeroMemory (&ddsdShadow, sizeof (ddsdShadow)); + ddsdShadow.dwSize = sizeof (ddsdShadow); + ddsdShadow.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH + | DDSD_LPSURFACE | DDSD_PITCH | DDSD_PIXELFORMAT; + ddsdShadow.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + ddsdShadow.dwHeight = pScreenInfo->dwHeight; + ddsdShadow.dwWidth = pScreenInfo->dwWidth; + ddsdShadow.u1.lPitch = pScreenInfo->dwPaddedWidth; + ddsdShadow.lpSurface = lpSurface; + ddsdShadow.u4.ddpfPixelFormat = ddpfPrimary; + + ErrorF ("winAllocateFBShadowDDNL - lPitch: %d\n", + pScreenInfo->dwPaddedWidth); + + /* Create the shadow surface */ + ddrval = IDirectDraw4_CreateSurface (pScreenPriv->pdd4, + &ddsdShadow, + &pScreenPriv->pddsShadow4, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Could not create shadow " + "surface: %08x\n", ddrval); + return FALSE; + } + +#if CYGDEBUG || YES + ErrorF ("winAllocateFBShadowDDNL - Created shadow pitch: %d\n", + ddsdShadow.u1.lPitch); +#endif + + /* Grab the pitch from the surface desc */ + pScreenInfo->dwStride = (ddsdShadow.u1.lPitch * 8) + / pScreenInfo->dwBPP; + +#if CYGDEBUG || YES + ErrorF ("winAllocateFBShadowDDNL - Created shadow stride: %d\n", + pScreenInfo->dwStride); +#endif + + /* Save the pointer to our surface memory */ + pScreenInfo->pfb = lpSurface; + + /* Grab the masks from the surface description */ + pScreenPriv->dwRedMask = ddsdShadow.u4.ddpfPixelFormat.u2.dwRBitMask; + pScreenPriv->dwGreenMask = ddsdShadow.u4.ddpfPixelFormat.u3.dwGBitMask; + pScreenPriv->dwBlueMask = ddsdShadow.u4.ddpfPixelFormat.u4.dwBBitMask; + +#if CYGDEBUG + ErrorF ("winAllocateFBShadowDDNL - Returning\n"); +#endif + + return TRUE; +} + + +/* + * Transfer the damaged regions of the shadow framebuffer to the display. + */ + +void +winShadowUpdateDDNL (ScreenPtr pScreen, + shadowBufPtr pBuf) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + RegionPtr damage = &pBuf->damage; + HRESULT ddrval = DD_OK; + RECT rcDest, rcSrc; + POINT ptOrigin; + DWORD dwBox = REGION_NUM_RECTS (damage); + BoxPtr pBox = REGION_RECTS (damage); + HRGN hrgnTemp = NULL, hrgnCombined = NULL; + + /* + * Return immediately if the app is not active + * and we are fullscreen, or if we have a bad display depth + */ + if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) + || pScreenPriv->fBadDepth) return; + + /* Get the origin of the window in the screen coords */ + ptOrigin.x = pScreenInfo->dwXOffset; + ptOrigin.y = pScreenInfo->dwYOffset; + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&ptOrigin, 1); + + /* + * Handle small regions with multiple blits, + * handle large regions by creating a clipping region and + * doing a single blit constrained to that clipping region. + */ + if (pScreenInfo->dwClipUpdatesNBoxes == 0 + || dwBox < pScreenInfo->dwClipUpdatesNBoxes) + { + /* Loop through all boxes in the damaged region */ + while (dwBox--) + { + /* Assign damage box to source rectangle */ + rcSrc.left = pBox->x1; + rcSrc.top = pBox->y1; + rcSrc.right = pBox->x2; + rcSrc.bottom = pBox->y2; + + /* Calculate destination rectangle */ + rcDest.left = ptOrigin.x + rcSrc.left; + rcDest.top = ptOrigin.y + rcSrc.top; + rcDest.right = ptOrigin.x + rcSrc.right; + rcDest.bottom = ptOrigin.y + rcSrc.bottom; + + /* Blit the damaged areas */ + ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4, + &rcDest, + pScreenPriv->pddsShadow4, + &rcSrc, + DDBLT_WAIT, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winShadowUpdateDDNL - IDirectDrawSurface4_Blt () " + "failed: %08x\n", + ddrval); + } + + /* Get a pointer to the next box */ + ++pBox; + } + } + else + { + BoxPtr pBoxExtents = REGION_EXTENTS (pScreen, damage); + + /* Compute a GDI region from the damaged region */ + hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); + dwBox--; + pBox++; + while (dwBox--) + { + hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); + CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR); + DeleteObject (hrgnTemp); + pBox++; + } + + /* Install the GDI region as a clipping region */ + SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined); + DeleteObject (hrgnCombined); + hrgnCombined = NULL; + +#if CYGDEBUG + ErrorF ("winShadowUpdateDDNL - be x1 %d y1 %d x2 %d y2 %d\n", + pBoxExtents->x1, pBoxExtents->y1, + pBoxExtents->x2, pBoxExtents->y2); +#endif + + /* Calculating a bounding box for the source is easy */ + rcSrc.left = pBoxExtents->x1; + rcSrc.top = pBoxExtents->y1; + rcSrc.right = pBoxExtents->x2; + rcSrc.bottom = pBoxExtents->y2; + + /* Calculating a bounding box for the destination is trickier */ + rcDest.left = ptOrigin.x + rcSrc.left; + rcDest.top = ptOrigin.y + rcSrc.top; + rcDest.right = ptOrigin.x + rcSrc.right; + rcDest.bottom = ptOrigin.y + rcSrc.bottom; + + /* Our Blt should be clipped to the invalidated region */ + ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4, + &rcDest, + pScreenPriv->pddsShadow4, + &rcSrc, + DDBLT_WAIT, + NULL); + + /* Reset the clip region */ + SelectClipRgn (pScreenPriv->hdcScreen, NULL); + } +} + + +/* + * Call the wrapped CloseScreen function. + * + * Free our resources and private structures. + */ + +Bool +winCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + Bool fReturn; + +#if CYGDEBUG + ErrorF ("winCloseScreenShadowDDNL - Freeing screen resources\n"); +#endif + + /* Flag that the screen is closed */ + pScreenPriv->fClosed = TRUE; + pScreenPriv->fActive = FALSE; + + /* Call the wrapped CloseScreen procedure */ + pScreen->CloseScreen = pScreenPriv->CloseScreen; + fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); + + /* Free the screen DC */ + ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen); + + /* Delete the window property */ + RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); + + /* Free the shadow surface, if there is one */ + if (pScreenPriv->pddsShadow4) + { + IDirectDrawSurface4_Release (pScreenPriv->pddsShadow4); + free (pScreenInfo->pfb); + pScreenInfo->pfb = NULL; + pScreenPriv->pddsShadow4 = NULL; + } + + /* Detach the clipper from the primary surface and release the clipper. */ + if (pScreenPriv->pddcPrimary) + { + /* Detach the clipper */ + IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4, + NULL); + + /* Release the clipper object */ + IDirectDrawClipper_Release (pScreenPriv->pddcPrimary); + pScreenPriv->pddcPrimary = NULL; + } + + /* Release the primary surface, if there is one */ + if (pScreenPriv->pddsPrimary4) + { + IDirectDrawSurface4_Release (pScreenPriv->pddsPrimary4); + pScreenPriv->pddsPrimary4 = NULL; + } + + /* Free the DirectDraw4 object, if there is one */ + if (pScreenPriv->pdd4) + { + IDirectDraw4_RestoreDisplayMode (pScreenPriv->pdd4); + IDirectDraw4_Release (pScreenPriv->pdd4); + pScreenPriv->pdd4 = NULL; + } + + /* Free the DirectDraw object, if there is one */ + if (pScreenPriv->pdd) + { + IDirectDraw_Release (pScreenPriv->pdd); + pScreenPriv->pdd = NULL; + } + + /* Kill our window */ + if (pScreenPriv->hwndScreen) + { + DestroyWindow (pScreenPriv->hwndScreen); + pScreenPriv->hwndScreen = NULL; + } + + /* Destroy the thread startup mutex */ + pthread_mutex_destroy (&pScreenPriv->pmServerStarted); + + /* Kill our screeninfo's pointer to the screen */ + pScreenInfo->pScreen = NULL; + + /* Invalidate the ScreenInfo's fb pointer */ + pScreenInfo->pfb = NULL; + + /* Free the screen privates for this screen */ + free ((pointer) pScreenPriv); + + return fReturn; +} + + +/* + * Tell mi what sort of visuals we need. + * + * Generally we only need one visual, as our screen can only + * handle one format at a time, I believe. You may want + * to verify that last sentence. + */ + +Bool +winInitVisualsShadowDDNL (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + DWORD dwRedBits, dwGreenBits, dwBlueBits; + + /* Count the number of ones in each color mask */ + dwRedBits = winCountBits (pScreenPriv->dwRedMask); + dwGreenBits = winCountBits (pScreenPriv->dwGreenMask); + dwBlueBits = winCountBits (pScreenPriv->dwBlueMask); + + /* Store the maximum number of ones in a color mask as the bitsPerRGB */ + if (dwRedBits == 0 || dwGreenBits == 0 || dwBlueBits == 0) + pScreenPriv->dwBitsPerRGB = 8; + else if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits) + pScreenPriv->dwBitsPerRGB = dwRedBits; + else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits) + pScreenPriv->dwBitsPerRGB = dwGreenBits; + else + pScreenPriv->dwBitsPerRGB = dwBlueBits; + + ErrorF ("winInitVisualsShadowDDNL - Masks %08x %08x %08x BPRGB %d d %d " + "bpp %d\n", + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask, + pScreenPriv->dwBitsPerRGB, + pScreenInfo->dwDepth, + pScreenInfo->dwBPP); + + /* Create a single visual according to the Windows screen depth */ + switch (pScreenInfo->dwDepth) + { + case 24: + case 16: + case 15: +#if defined(XFree86Server) + /* Setup the real visual */ + if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, + TrueColorMask, + pScreenPriv->dwBitsPerRGB, + -1, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks " + "failed for TrueColor\n"); + return FALSE; + } + +#if WIN_EMULATE_PSEUDO_SUPPORT + if (!pScreenInfo->fEmulatePseudo) + break; + + /* Setup a pseudocolor visual */ + if (!miSetVisualTypesAndMasks (8, + PseudoColorMask, + 8, + -1, + 0, + 0, + 0)) + { + ErrorF ("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks " + "failed for PseudoColor\n"); + return FALSE; + } +#endif +#else /* XFree86Server */ + /* Setup the real visual */ + if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth, + TrueColorMask, + pScreenPriv->dwBitsPerRGB, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsShadowDDNL - fbSetVisualTypesAndMasks " + "failed for TrueColor\n"); + return FALSE; + } + +#if WIN_EMULATE_PSEUDO_SUPPORT + if (!pScreenInfo->fEmulatePseudo) + break; + + /* Setup a pseudocolor visual */ + if (!fbSetVisualTypesAndMasks (8, + PseudoColorMask, + 8, + 0, + 0, + 0)) + { + ErrorF ("winInitVisualsShadowDDNL - fbSetVisualTypesAndMasks " + "failed for PseudoColor\n"); + return FALSE; + } +#endif +#endif /* XFree86Server */ + break; + + case 8: +#if defined(XFree86Server) + if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, + pScreenInfo->fFullScreen + ? PseudoColorMask : StaticColorMask, + pScreenPriv->dwBitsPerRGB, + pScreenInfo->fFullScreen + ? PseudoColor : StaticColor, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks " + "failed\n"); + return FALSE; + } +#else /* XFree86Server */ + if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth, + pScreenInfo->fFullScreen + ? PseudoColorMask : StaticColorMask, + pScreenPriv->dwBitsPerRGB, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsShadowDDNL - fbSetVisualTypesAndMasks " + "failed\n"); + return FALSE; + } +#endif /* XFree86Server */ + break; + + default: + ErrorF ("winInitVisualsShadowDDNL - Unknown screen depth\n"); + return FALSE; + } + +#if CYGDEBUG + ErrorF ("winInitVisualsShadowDDNL - Returning\n"); +#endif + + return TRUE; +} + + +/* + * Adjust the user proposed video mode + */ + +Bool +winAdjustVideoModeShadowDDNL (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HDC hdc = NULL; + DWORD dwBPP; + + /* We're in serious trouble if we can't get a DC */ + hdc = GetDC (NULL); + if (hdc == NULL) + { + ErrorF ("winAdjustVideoModeShadowDDNL - GetDC () failed\n"); + return FALSE; + } + + /* Query GDI for current display depth */ + dwBPP = GetDeviceCaps (hdc, BITSPIXEL); + + /* DirectDraw can only change the depth in fullscreen mode */ + if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP) + { + /* No -depth parameter passed, let the user know the depth being used */ + ErrorF ("winAdjustVideoModeShadowDDNL - Using Windows display " + "depth of %d bits per pixel\n", dwBPP); + + /* Use GDI's depth */ + pScreenInfo->dwBPP = dwBPP; + } + else if (pScreenInfo->fFullScreen + && pScreenInfo->dwBPP != dwBPP) + { + /* FullScreen, and GDI depth differs from -depth parameter */ + ErrorF ("winAdjustVideoModeShadowDDNL - FullScreen, using command " + "line bpp: %d\n", pScreenInfo->dwBPP); + } + else if (dwBPP != pScreenInfo->dwBPP) + { + /* Windowed, and GDI depth differs from -depth parameter */ + ErrorF ("winAdjustVideoModeShadowDDNL - Windowed, command line " + "bpp: %d, using bpp: %d\n", + pScreenInfo->dwBPP, dwBPP); + + /* We'll use GDI's depth */ + pScreenInfo->dwBPP = dwBPP; + } + + /* See if the shadow bitmap will be larger than the DIB size limit */ + if (pScreenInfo->dwWidth * pScreenInfo->dwHeight * pScreenInfo->dwBPP + >= WIN_DIB_MAXIMUM_SIZE) + { + ErrorF ("winAdjustVideoModeShadowDDNL - Requested DirectDraw surface " + "will be larger than %d MB. The surface may fail to be " + "allocated on Windows 95, 98, or Me, due to a %d MB limit in " + "DIB size. This limit does not apply to Windows NT/2000, and " + "this message may be ignored on those platforms.\n", + WIN_DIB_MAXIMUM_SIZE_MB, WIN_DIB_MAXIMUM_SIZE_MB); + } + + /* Release our DC */ + ReleaseDC (NULL, hdc); + + return TRUE; +} + + +/* + * Blt exposed regions to the screen + */ + +Bool +winBltExposedRegionsShadowDDNL (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + RECT rcSrc, rcDest; + POINT ptOrigin; + HDC hdcUpdate; + PAINTSTRUCT ps; + HRESULT ddrval = DD_OK; + Bool fReturn = TRUE; + int i; + + /* BeginPaint gives us an hdc that clips to the invalidated region */ + hdcUpdate = BeginPaint (pScreenPriv->hwndScreen, &ps); + if (hdcUpdate == NULL) + { + fReturn = FALSE; + ErrorF ("winBltExposedRegionsShadowDDNL - BeginPaint () returned " + "a NULL device context handle. Aborting blit attempt.\n"); + goto winBltExposedRegionsShadowDDNL_Exit; + } + + /* Get the origin of the window in the screen coords */ + ptOrigin.x = pScreenInfo->dwXOffset; + ptOrigin.y = pScreenInfo->dwYOffset; + + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&ptOrigin, 1); + rcDest.left = ptOrigin.x; + rcDest.right = ptOrigin.x + pScreenInfo->dwWidth; + rcDest.top = ptOrigin.y; + rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight; + + /* Source can be entire shadow surface, as Blt should clip for us */ + rcSrc.left = 0; + rcSrc.top = 0; + rcSrc.right = pScreenInfo->dwWidth; + rcSrc.bottom = pScreenInfo->dwHeight; + + /* Try to regain the primary surface and blit again if we've lost it */ + for (i = 0; i <= WIN_REGAIN_SURFACE_RETRIES; ++i) + { + /* Our Blt should be clipped to the invalidated region */ + ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4, + &rcDest, + pScreenPriv->pddsShadow4, + &rcSrc, + DDBLT_WAIT, + NULL); + if (ddrval == DDERR_SURFACELOST) + { + /* Surface was lost */ + ErrorF ("winBltExposedRegionsShadowDDNL - IDirectDrawSurface4_Blt " + "reported that the primary surface was lost, " + "trying to restore, retry: %d\n", i + 1); + + /* Try to restore the surface, once */ + + ddrval = IDirectDrawSurface4_Restore (pScreenPriv->pddsPrimary4); + ErrorF ("winBltExposedRegionsShadowDDNL - " + "IDirectDrawSurface4_Restore returned: "); + if (ddrval == DD_OK) + continue; + else if (ddrval == DDERR_WRONGMODE) + ErrorF ("DDERR_WRONGMODE\n"); + else if (ddrval == DDERR_INCOMPATIBLEPRIMARY) + ErrorF ("DDERR_INCOMPATIBLEPRIMARY\n"); + else if (ddrval == DDERR_UNSUPPORTED) + ErrorF ("DDERR_UNSUPPORTED\n"); + else if (ddrval == DDERR_INVALIDPARAMS) + ErrorF ("DDERR_INVALIDPARAMS\n"); + else if (ddrval == DDERR_INVALIDOBJECT) + ErrorF ("DDERR_INVALIDOBJECT\n"); + else + ErrorF ("unknown error: %08x\n", ddrval); + + /* Loop around to try the blit one more time */ + continue; + } + else if (FAILED (ddrval)) + { + fReturn = FALSE; + ErrorF ("winBltExposedRegionsShadowDDNL - IDirectDrawSurface4_Blt " + "failed, but surface not lost: %08x %d\n", ddrval, ddrval); + goto winBltExposedRegionsShadowDDNL_Exit; + } + else + { + /* Success, stop looping */ + break; + } + } + + winBltExposedRegionsShadowDDNL_Exit: + /* EndPaint frees the DC */ + if (hdcUpdate != NULL) + EndPaint (pScreenPriv->hwndScreen, &ps); + return fReturn; +} + + +/* + * Do any engine-specific appliation-activation processing + */ + +Bool +winActivateAppShadowDDNL (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + + /* + * Do we have a surface? + * Are we active? + * Are we full screen? + */ + if (pScreenPriv != NULL + && pScreenPriv->pddsPrimary4 != NULL + && pScreenPriv->fActive) + { + /* Primary surface was lost, restore it */ + IDirectDrawSurface4_Restore (pScreenPriv->pddsPrimary4); + } + + return TRUE; +} + + +/* + * Reblit the shadow framebuffer to the screen. + */ + +Bool +winRedrawScreenShadowDDNL (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HRESULT ddrval = DD_OK; + RECT rcSrc, rcDest; + POINT ptOrigin; + + /* Get the origin of the window in the screen coords */ + ptOrigin.x = pScreenInfo->dwXOffset; + ptOrigin.y = pScreenInfo->dwYOffset; + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&ptOrigin, 1); + rcDest.left = ptOrigin.x; + rcDest.right = ptOrigin.x + pScreenInfo->dwWidth; + rcDest.top = ptOrigin.y; + rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight; + + /* Source can be entire shadow surface, as Blt should clip for us */ + rcSrc.left = 0; + rcSrc.top = 0; + rcSrc.right = pScreenInfo->dwWidth; + rcSrc.bottom = pScreenInfo->dwHeight; + + /* Redraw the whole window, to take account for the new colors */ + ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4, + &rcDest, + pScreenPriv->pddsShadow4, + &rcSrc, + DDBLT_WAIT, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winRedrawScreenShadowDDNL - IDirectDrawSurface4_Blt () " + "failed: %08x\n", + ddrval); + } + + return TRUE; +} + + +/* + * Realize the currently installed colormap + */ + +Bool +winRealizeInstalledPaletteShadowDDNL (ScreenPtr pScreen) +{ + return TRUE; +} + + +/* + * Install the specified colormap + */ + +Bool +winInstallColormapShadowDDNL (ColormapPtr pColormap) +{ + ScreenPtr pScreen = pColormap->pScreen; + winScreenPriv(pScreen); + winCmapPriv(pColormap); + HRESULT ddrval = DD_OK; + + /* Install the DirectDraw palette on the primary surface */ + ddrval = IDirectDrawSurface4_SetPalette (pScreenPriv->pddsPrimary4, + pCmapPriv->lpDDPalette); + if (FAILED (ddrval)) + { + ErrorF ("winInstallColormapShadowDDNL - Failed installing the " + "DirectDraw palette.\n"); + return FALSE; + } + + /* Save a pointer to the newly installed colormap */ + pScreenPriv->pcmapInstalled = pColormap; + + return TRUE; +} + + +/* + * Store the specified colors in the specified colormap + */ + +Bool +winStoreColorsShadowDDNL (ColormapPtr pColormap, + int ndef, + xColorItem *pdefs) +{ + ScreenPtr pScreen = pColormap->pScreen; + winScreenPriv(pScreen); + winCmapPriv(pColormap); + ColormapPtr curpmap = pScreenPriv->pcmapInstalled; + HRESULT ddrval = DD_OK; + + /* Put the X colormap entries into the Windows logical palette */ + ddrval = IDirectDrawPalette_SetEntries (pCmapPriv->lpDDPalette, + 0, + pdefs[0].pixel, + ndef, + pCmapPriv->peColors + + pdefs[0].pixel); + if (FAILED (ddrval)) + { + ErrorF ("winStoreColorsShadowDDNL - SetEntries () failed\n"); + return FALSE; + } + + /* Don't install the DirectDraw palette if the colormap is not installed */ + if (pColormap != curpmap) + { + return TRUE; + } + + if (!winInstallColormapShadowDDNL (pColormap)) + { + ErrorF ("winStoreColorsShadowDDNL - Failed installing colormap\n"); + return FALSE; + } + + return TRUE; +} + + +/* + * Colormap initialization procedure + */ + +Bool +winCreateColormapShadowDDNL (ColormapPtr pColormap) +{ + HRESULT ddrval = DD_OK; + ScreenPtr pScreen = pColormap->pScreen; + winScreenPriv(pScreen); + winCmapPriv(pColormap); + + /* Create a DirectDraw palette */ + ddrval = IDirectDraw4_CreatePalette (pScreenPriv->pdd4, + DDPCAPS_8BIT | DDPCAPS_ALLOW256, + pCmapPriv->peColors, + &pCmapPriv->lpDDPalette, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winCreateColormapShadowDDNL - CreatePalette failed\n"); + return FALSE; + } + + return TRUE; +} + + +/* + * Colormap destruction procedure + */ + +Bool +winDestroyColormapShadowDDNL (ColormapPtr pColormap) +{ + winScreenPriv(pColormap->pScreen); + winCmapPriv(pColormap); + HRESULT ddrval = DD_OK; + + /* + * Is colormap to be destroyed the default? + * + * Non-default colormaps should have had winUninstallColormap + * called on them before we get here. The default colormap + * will not have had winUninstallColormap called on it. Thus, + * we need to handle the default colormap in a special way. + */ + if (pColormap->flags & IsDefault) + { +#if CYGDEBUG + ErrorF ("winDestroyColormapShadowDDNL - Destroying default " + "colormap\n"); +#endif + + /* + * FIXME: Walk the list of all screens, popping the default + * palette out of each screen device context. + */ + + /* Pop the palette out of the primary surface */ + ddrval = IDirectDrawSurface4_SetPalette (pScreenPriv->pddsPrimary4, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winDestroyColormapShadowDDNL - Failed freeing the " + "default colormap DirectDraw palette.\n"); + return FALSE; + } + + /* Clear our private installed colormap pointer */ + pScreenPriv->pcmapInstalled = NULL; + } + + /* Release the palette */ + IDirectDrawPalette_Release (pCmapPriv->lpDDPalette); + + /* Invalidate the colormap privates */ + pCmapPriv->lpDDPalette = NULL; + + return TRUE; +} + + +/* + * Set pointers to our engine specific functions + */ + +Bool +winSetEngineFunctionsShadowDDNL (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Set our pointers */ + pScreenPriv->pwinAllocateFB = winAllocateFBShadowDDNL; + pScreenPriv->pwinShadowUpdate = winShadowUpdateDDNL; + pScreenPriv->pwinCloseScreen = winCloseScreenShadowDDNL; + pScreenPriv->pwinInitVisuals = winInitVisualsShadowDDNL; + pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowDDNL; + if (pScreenInfo->fFullScreen) + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen; + else + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; + pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB; + pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowDDNL; + pScreenPriv->pwinActivateApp = winActivateAppShadowDDNL; + pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowDDNL; + pScreenPriv->pwinRealizeInstalledPalette + = winRealizeInstalledPaletteShadowDDNL; + pScreenPriv->pwinInstallColormap = winInstallColormapShadowDDNL; + pScreenPriv->pwinStoreColors = winStoreColorsShadowDDNL; + pScreenPriv->pwinCreateColormap = winCreateColormapShadowDDNL; + pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowDDNL; + pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)())NoopDDA; + pScreenPriv->pwinCreatePrimarySurface = winCreatePrimarySurfaceShadowDDNL; + pScreenPriv->pwinReleasePrimarySurface = winReleasePrimarySurfaceShadowDDNL; + + return TRUE; +} + + diff --git a/hw/xwin/winshadgdi.c b/hw/xwin/winshadgdi.c new file mode 100644 index 000000000..d2f72f20d --- /dev/null +++ b/hw/xwin/winshadgdi.c @@ -0,0 +1,1158 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winshadgdi.c,v 1.22 2003/02/12 15:01:38 alanh Exp $ */ + +#include "win.h" + +/* + * Local function prototypes + */ + +BOOL CALLBACK +winRedrawAllProcShadowGDI (HWND hwnd, LPARAM lParam); + + +/* + * Internal function to get the DIB format that is compatible with the screen + */ + +static +Bool +winQueryScreenDIBFormat (ScreenPtr pScreen, BITMAPINFOHEADER *pbmih) +{ + winScreenPriv(pScreen); + HBITMAP hbmp; +#if CYGDEBUG + LPDWORD pdw = NULL; +#endif + + /* Create a memory bitmap compatible with the screen */ + hbmp = CreateCompatibleBitmap (pScreenPriv->hdcScreen, 1, 1); + if (hbmp == NULL) + { + ErrorF ("winQueryScreenDIBFormat - CreateCompatibleBitmap failed\n"); + return FALSE; + } + + /* Initialize our bitmap info header */ + ZeroMemory (pbmih, sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD)); + pbmih->biSize = sizeof (BITMAPINFOHEADER); + + /* Get the biBitCount */ + if (!GetDIBits (pScreenPriv->hdcScreen, + hbmp, + 0, 1, + NULL, + (BITMAPINFO*) pbmih, + DIB_RGB_COLORS)) + { + ErrorF ("winQueryScreenDIBFormat - First call to GetDIBits failed\n"); + DeleteObject (hbmp); + return FALSE; + } + +#if CYGDEBUG + /* Get a pointer to bitfields */ + pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); + + ErrorF ("winQueryScreenDIBFormat - First call masks: %08x %08x %08x\n", + pdw[0], pdw[1], pdw[2]); +#endif + + /* Get optimal color table, or the optimal bitfields */ + if (!GetDIBits (pScreenPriv->hdcScreen, + hbmp, + 0, 1, + NULL, + (BITMAPINFO*)pbmih, + DIB_RGB_COLORS)) + { + ErrorF ("winQueryScreenDIBFormat - Second call to GetDIBits " + "failed\n"); + DeleteObject (hbmp); + return FALSE; + } + + /* Free memory */ + DeleteObject (hbmp); + + return TRUE; +} + + +/* + * Internal function to determine the GDI bits per rgb and bit masks + */ + +static +Bool +winQueryRGBBitsAndMasks (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + BITMAPINFOHEADER *pbmih = NULL; + Bool fReturn = TRUE; + LPDWORD pdw = NULL; + DWORD dwRedBits, dwGreenBits, dwBlueBits; + + /* Color masks for 8 bpp are standardized */ + if (GetDeviceCaps (pScreenPriv->hdcScreen, RASTERCAPS) & RC_PALETTE) + { + /* + * RGB BPP for 8 bit palletes is always 8 + * and the color masks are always 0. + */ + pScreenPriv->dwBitsPerRGB = 8; + pScreenPriv->dwRedMask = 0x0L; + pScreenPriv->dwGreenMask = 0x0L; + pScreenPriv->dwBlueMask = 0x0L; + return TRUE; + } + + /* Color masks for 24 bpp are standardized */ + if (GetDeviceCaps (pScreenPriv->hdcScreen, PLANES) + * GetDeviceCaps (pScreenPriv->hdcScreen, BITSPIXEL) == 24) + { + ErrorF ("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) " + "returned 24 for the screen. Using default 24bpp masks.\n"); + + /* 8 bits per primary color */ + pScreenPriv->dwBitsPerRGB = 8; + + /* Set screen privates masks */ + pScreenPriv->dwRedMask = WIN_24BPP_MASK_RED; + pScreenPriv->dwGreenMask = WIN_24BPP_MASK_GREEN; + pScreenPriv->dwBlueMask = WIN_24BPP_MASK_BLUE; + + return TRUE; + } + + /* Allocate a bitmap header and color table */ + pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) + + 256 * sizeof (RGBQUAD)); + if (pbmih == NULL) + { + ErrorF ("winQueryRGBBitsAndMasks - malloc failed\n"); + return FALSE; + } + + /* Get screen description */ + if (winQueryScreenDIBFormat (pScreen, pbmih)) + { + /* Get a pointer to bitfields */ + pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); + +#if CYGDEBUG + ErrorF ("winQueryRGBBitsAndMasks - Masks: %08x %08x %08x\n", + pdw[0], pdw[1], pdw[2]); +#endif + + /* Count the number of bits in each mask */ + dwRedBits = winCountBits (pdw[0]); + dwGreenBits = winCountBits (pdw[1]); + dwBlueBits = winCountBits (pdw[2]); + + /* Find maximum bits per red, green, blue */ + if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits) + pScreenPriv->dwBitsPerRGB = dwRedBits; + else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits) + pScreenPriv->dwBitsPerRGB = dwGreenBits; + else + pScreenPriv->dwBitsPerRGB = dwBlueBits; + + /* Set screen privates masks */ + pScreenPriv->dwRedMask = pdw[0]; + pScreenPriv->dwGreenMask = pdw[1]; + pScreenPriv->dwBlueMask = pdw[2]; + } + else + { + ErrorF ("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n"); + free (pbmih); + fReturn = FALSE; + } + + /* Free memory */ + free (pbmih); + + return fReturn; +} + + +/* + * Redraw all ---? + */ + +BOOL CALLBACK +winRedrawAllProcShadowGDI (HWND hwnd, LPARAM lParam) +{ + char strClassName[100]; + + if (GetClassName (hwnd, strClassName, 100)) + { + if(strcmp (WINDOW_CLASS_X, strClassName) == 0) + { + InvalidateRect (hwnd, NULL, FALSE); + UpdateWindow (hwnd); + } + } + return TRUE; +} + + +/* + * Allocate a DIB for the shadow framebuffer GDI server + */ + +Bool +winAllocateFBShadowGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + BITMAPINFOHEADER *pbmih = NULL; + DIBSECTION dibsection; + Bool fReturn = TRUE; + + /* Get device contexts for the screen and shadow bitmap */ + pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); + pScreenPriv->hdcShadow = CreateCompatibleDC (pScreenPriv->hdcScreen); + + /* Allocate bitmap info header */ + pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) + + 256 * sizeof (RGBQUAD)); + if (pbmih == NULL) + { + ErrorF ("winAllocateFBShadowGDI - malloc () failed\n"); + return FALSE; + } + + /* Query the screen format */ + fReturn = winQueryScreenDIBFormat (pScreen, pbmih); + + /* Describe shadow bitmap to be created */ + pbmih->biWidth = pScreenInfo->dwWidth; + pbmih->biHeight = -pScreenInfo->dwHeight; + + ErrorF ("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d " + "depth: %d\n", + pbmih->biWidth, -pbmih->biHeight, pbmih->biBitCount); + + /* Create a DI shadow bitmap with a bit pointer */ + pScreenPriv->hbmpShadow = CreateDIBSection (pScreenPriv->hdcScreen, + (BITMAPINFO *) pbmih, + DIB_RGB_COLORS, + (VOID**) &pScreenInfo->pfb, + NULL, + 0); + if (pScreenPriv->hbmpShadow == NULL || pScreenInfo->pfb == NULL) + { + ErrorF ("winAllocateFBShadowGDI - CreateDIBSection failed\n"); + return FALSE; + } + else + { +#if CYGDEBUG + ErrorF ("winAllocateFBShadowGDI - Shadow buffer allocated\n"); +#endif + } + + /* Get information about the bitmap that was allocated */ + GetObject (pScreenPriv->hbmpShadow, + sizeof (dibsection), + &dibsection); + +#if CYGDEBUG || YES + /* Print information about bitmap allocated */ + ErrorF ("winAllocateFBShadowGDI - Dibsection width: %d height: %d " + "depth: %d size image: %d\n", + dibsection.dsBmih.biWidth, dibsection.dsBmih.biHeight, + dibsection.dsBmih.biBitCount, + dibsection.dsBmih.biSizeImage); +#endif + + /* Select the shadow bitmap into the shadow DC */ + SelectObject (pScreenPriv->hdcShadow, + pScreenPriv->hbmpShadow); + +#if CYGDEBUG + ErrorF ("winAllocateFBShadowGDI - Attempting a shadow blit\n"); +#endif + + /* Do a test blit from the shadow to the screen, I think */ + fReturn = BitBlt (pScreenPriv->hdcScreen, + 0, 0, + pScreenInfo->dwWidth, pScreenInfo->dwHeight, + pScreenPriv->hdcShadow, + 0, 0, + SRCCOPY); + if (fReturn) + { +#if CYGDEBUG + ErrorF ("winAllocateFBShadowGDI - Shadow blit success\n"); +#endif + } + else + { + ErrorF ("winAllocateFBShadowGDI - Shadow blit failure\n"); + return FALSE; + } + + /* Set screeninfo stride */ + pScreenInfo->dwStride = ((dibsection.dsBmih.biSizeImage + / dibsection.dsBmih.biHeight) + * 8) / pScreenInfo->dwBPP; + +#if CYGDEBUG || YES + ErrorF ("winAllocateFBShadowGDI - Created shadow stride: %d\n", + pScreenInfo->dwStride); +#endif + + /* See if the shadow bitmap will be larger than the DIB size limit */ + if (pScreenInfo->dwWidth * pScreenInfo->dwHeight * pScreenInfo->dwBPP + >= WIN_DIB_MAXIMUM_SIZE) + { + ErrorF ("winAllocateFBShadowGDI - Requested DIB (bitmap) " + "will be larger than %d MB. The surface may fail to be " + "allocated on Windows 95, 98, or Me, due to a %d MB limit in " + "DIB size. This limit does not apply to Windows NT/2000, and " + "this message may be ignored on those platforms.\n", + WIN_DIB_MAXIMUM_SIZE_MB, WIN_DIB_MAXIMUM_SIZE_MB); + } + + /* Determine our color masks */ + if (!winQueryRGBBitsAndMasks (pScreen)) + { + ErrorF ("winAllocateFBShadowGDI - winQueryRGBBitsAndMasks failed\n"); + return FALSE; + } + + /* Redraw all windows */ + if (pScreenInfo->fMultiWindow) EnumWindows(winRedrawAllProcShadowGDI, 0); + + return fReturn; +} + + +/* + * Blit the damaged regions of the shadow fb to the screen + */ + +void +winShadowUpdateGDI (ScreenPtr pScreen, + shadowBufPtr pBuf) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + RegionPtr damage = &pBuf->damage; + DWORD dwBox = REGION_NUM_RECTS (damage); + BoxPtr pBox = REGION_RECTS (damage); + int x, y, w, h; + HRGN hrgnTemp = NULL, hrgnCombined = NULL; +#if WIN_UPDATE_STATS + static DWORD s_dwNonUnitRegions = 0; + static DWORD s_dwTotalUpdates = 0; + static DWORD s_dwTotalBoxes = 0; +#endif + + /* + * Return immediately if the app is not active + * and we are fullscreen, or if we have a bad display depth + */ + if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) + || pScreenPriv->fBadDepth) return; + +#if WIN_UPDATE_STATS + ++s_dwTotalUpdates; + s_dwTotalBoxes += dwBox; + + if (dwBox != 1) + { + ++s_dwNonUnitRegions; + ErrorF ("winShadowUpdatGDI - dwBox: %d\n", dwBox); + } + + if ((s_dwTotalUpdates % 100) == 0) + ErrorF ("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d " + "nu: %d tu: %d\n", + (s_dwNonUnitRegions * 100) / s_dwTotalUpdates, + s_dwTotalBoxes / s_dwTotalUpdates, + s_dwNonUnitRegions, s_dwTotalUpdates); +#endif /* WIN_UPDATE_STATS */ + + /* + * Handle small regions with multiple blits, + * handle large regions by creating a clipping region and + * doing a single blit constrained to that clipping region. + */ + if (pScreenInfo->dwClipUpdatesNBoxes == 0 + || dwBox < pScreenInfo->dwClipUpdatesNBoxes) + { + /* Loop through all boxes in the damaged region */ + while (dwBox--) + { + /* + * Calculate x offset, y offset, width, and height for + * current damage box + */ + x = pBox->x1; + y = pBox->y1; + w = pBox->x2 - pBox->x1; + h = pBox->y2 - pBox->y1; + + BitBlt (pScreenPriv->hdcScreen, + x, y, + w, h, + pScreenPriv->hdcShadow, + x, y, + SRCCOPY); + + /* Get a pointer to the next box */ + ++pBox; + } + } + else + { + BoxPtr pBoxExtents = REGION_EXTENTS (pScreen, damage); + + /* Compute a GDI region from the damaged region */ + hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); + dwBox--; + pBox++; + while (dwBox--) + { + hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); + CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR); + DeleteObject (hrgnTemp); + pBox++; + } + + /* Install the GDI region as a clipping region */ + SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined); + DeleteObject (hrgnCombined); + hrgnCombined = NULL; + + /* + * Blit the shadow buffer to the screen, + * constrained to the clipping region. + */ + BitBlt (pScreenPriv->hdcScreen, + pBoxExtents->x1, pBoxExtents->y1, + pBoxExtents->x2 - pBoxExtents->x1, + pBoxExtents->y2 - pBoxExtents->y1, + pScreenPriv->hdcShadow, + pBoxExtents->x1, pBoxExtents->y1, + SRCCOPY); + + /* Reset the clip region */ + SelectClipRgn (pScreenPriv->hdcScreen, NULL); + } + + /* Redraw all windows */ + if (pScreenInfo->fMultiWindow) EnumWindows(winRedrawAllProcShadowGDI, 0); +} + + +/* See Porting Layer Definition - p. 33 */ +/* + * We wrap whatever CloseScreen procedure was specified by fb; + * a pointer to said procedure is stored in our privates. + */ + +Bool +winCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + Bool fReturn; + +#if CYGDEBUG + ErrorF ("winCloseScreenShadowGDI - Freeing screen resources\n"); +#endif + + /* Flag that the screen is closed */ + pScreenPriv->fClosed = TRUE; + pScreenPriv->fActive = FALSE; + + /* Call the wrapped CloseScreen procedure */ + pScreen->CloseScreen = pScreenPriv->CloseScreen; + fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); + + /* Delete the window property */ + RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); + + /* Free the shadow DC; which allows the bitmap to be freed */ + DeleteDC (pScreenPriv->hdcShadow); + + /* Free the shadow bitmap */ + DeleteObject (pScreenPriv->hbmpShadow); + + /* Free the screen DC */ + ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen); + + /* Kill our window */ + if (pScreenPriv->hwndScreen) + { + DestroyWindow (pScreenPriv->hwndScreen); + pScreenPriv->hwndScreen = NULL; + } + + /* Destroy the thread startup mutex */ + pthread_mutex_destroy (&pScreenPriv->pmServerStarted); + + /* Invalidate our screeninfo's pointer to the screen */ + pScreenInfo->pScreen = NULL; + + /* Invalidate the ScreenInfo's fb pointer */ + pScreenInfo->pfb = NULL; + + /* Free the screen privates for this screen */ + free ((pointer) pScreenPriv); + + return fReturn; +} + + +/* + * Tell mi what sort of visuals we need. + * + * Generally we only need one visual, as our screen can only + * handle one format at a time, I believe. You may want + * to verify that last sentence. + */ + +Bool +winInitVisualsShadowGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Display debugging information */ + ErrorF ("winInitVisualsShadowGDI - Masks %08x %08x %08x BPRGB %d d %d " + "bpp %d\n", + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask, + pScreenPriv->dwBitsPerRGB, + pScreenInfo->dwDepth, + pScreenInfo->dwBPP); + + /* Create a single visual according to the Windows screen depth */ + switch (pScreenInfo->dwDepth) + { + case 24: + case 16: + case 15: +#if defined(XFree86Server) + /* Setup the real visual */ + if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, + TrueColorMask, + pScreenPriv->dwBitsPerRGB, + -1, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " + "failed\n"); + return FALSE; + } + +#if WIN_EMULATE_PSEUDO_SUPPORT + if (!pScreenInfo->fEmulatePseudo) + break; + + /* Setup a pseudocolor visual */ + if (!miSetVisualTypesAndMasks (8, + PseudoColorMask, + 8, + -1, + 0, + 0, + 0)) + { + ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " + "failed for PseudoColor\n"); + return FALSE; + } +#endif +#else /* XFree86Server */ + /* Setup the real visual */ + if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth, + TrueColorMask, + pScreenPriv->dwBitsPerRGB, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsShadowGDI - fbSetVisualTypesAndMasks " + "failed for TrueColor\n"); + return FALSE; + } + +#if WIN_EMULATE_PSEUDO_SUPPORT + if (!pScreenInfo->fEmulatePseudo) + break; + + /* Setup a pseudocolor visual */ + if (!fbSetVisualTypesAndMasks (8, + PseudoColorMask, + 8, + 0, + 0, + 0)) + { + ErrorF ("winInitVisualsShadowGDI - fbSetVisualTypesAndMasks " + "failed for PseudoColor\n"); + return FALSE; + } +#endif +#endif /* XFree86Server */ + break; + + case 8: +#if defined(XFree86Server) + if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, + PseudoColorMask, + pScreenPriv->dwBitsPerRGB, + PseudoColor, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " + "failed\n"); + return FALSE; + } +#else /* XFree86Server */ + if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth, + PseudoColorMask, + pScreenPriv->dwBitsPerRGB, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsShadowGDI - fbSetVisualTypesAndMasks " + "failed\n"); + return FALSE; + } +#endif + break; + + default: + ErrorF ("winInitVisualsShadowGDI - Unknown screen depth\n"); + return FALSE; + } + +#if CYGDEBUG + ErrorF ("winInitVisualsShadowGDI - Returning\n"); +#endif + + return TRUE; +} + + +/* + * Adjust the proposed video mode + */ + +Bool +winAdjustVideoModeShadowGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HDC hdc; + DWORD dwBPP; + + hdc = GetDC (NULL); + + /* We're in serious trouble if we can't get a DC */ + if (hdc == NULL) + { + ErrorF ("winAdjustVideoModeShadowGDI - GetDC () failed\n"); + return FALSE; + } + + /* Query GDI for current display depth */ + dwBPP = GetDeviceCaps (hdc, BITSPIXEL); + + /* GDI cannot change the screen depth */ + if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP) + { + /* No -depth parameter passed, let the user know the depth being used */ + ErrorF ("winAdjustVideoModeShadowGDI - Using Windows display " + "depth of %d bits per pixel\n", dwBPP); + + /* Use GDI's depth */ + pScreenInfo->dwBPP = dwBPP; + } + else if (dwBPP != pScreenInfo->dwBPP) + { + /* Warn user if GDI depth is different than -depth parameter */ + ErrorF ("winAdjustVideoModeShadowGDI - Command line bpp: %d, "\ + "using bpp: %d\n", pScreenInfo->dwBPP, dwBPP); + + /* We'll use GDI's depth */ + pScreenInfo->dwBPP = dwBPP; + } + + /* Release our DC */ + ReleaseDC (NULL, hdc); + hdc = NULL; + + return TRUE; +} + + +/* + * Blt exposed regions to the screen + */ + +Bool +winBltExposedRegionsShadowGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + winPrivCmapPtr pCmapPriv = NULL; + HDC hdcUpdate; + PAINTSTRUCT ps; + + /* BeginPaint gives us an hdc that clips to the invalidated region */ + hdcUpdate = BeginPaint (pScreenPriv->hwndScreen, &ps); + + /* Realize the palette, if we have one */ + if (pScreenPriv->pcmapInstalled != NULL) + { + pCmapPriv = winGetCmapPriv (pScreenPriv->pcmapInstalled); + + SelectPalette (hdcUpdate, pCmapPriv->hPalette, FALSE); + RealizePalette (hdcUpdate); + } + + /* Our BitBlt will be clipped to the invalidated region */ + BitBlt (hdcUpdate, + 0, 0, + pScreenInfo->dwWidth, pScreenInfo->dwHeight, + pScreenPriv->hdcShadow, + 0, 0, + SRCCOPY); + + /* EndPaint frees the DC */ + EndPaint (pScreenPriv->hwndScreen, &ps); + + /* Redraw all windows */ + if (pScreenInfo->fMultiWindow) EnumWindows(winRedrawAllProcShadowGDI, 0); + + return TRUE; +} + + +/* + * Do any engine-specific appliation-activation processing + */ + +Bool +winActivateAppShadowGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + +#if CYGDEBUG + ErrorF ("winActivateAppShadowGDI\n"); +#endif + + /* + * Are we active? + * Are we fullscreen? + */ + if (pScreenPriv->fActive + && pScreenInfo->fFullScreen) + { + /* + * Activating, attempt to bring our window + * to the top of the display + */ + ShowWindow (pScreenPriv->hwndScreen, SW_RESTORE); + } + else if (!pScreenPriv->fActive + && pScreenInfo->fFullScreen) + { + /* + * Deactivating, stuff our window onto the + * task bar. + */ + ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE); + } + +#if CYGDEBUG + ErrorF ("winActivateAppShadowGDI - Returning\n"); +#endif + + return TRUE; +} + + +/* + * Reblit the shadow framebuffer to the screen. + */ + +Bool +winRedrawScreenShadowGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Redraw the whole window, to take account for the new colors */ + BitBlt (pScreenPriv->hdcScreen, + 0, 0, + pScreenInfo->dwWidth, pScreenInfo->dwHeight, + pScreenPriv->hdcShadow, + 0, 0, + SRCCOPY); + + /* Redraw all windows */ + if (pScreenInfo->fMultiWindow) EnumWindows(winRedrawAllProcShadowGDI, 0); + return TRUE; +} + + +/* + * Realize the currently installed colormap + */ + +Bool +winRealizeInstalledPaletteShadowGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winPrivCmapPtr pCmapPriv = NULL; + +#if CYGDEBUG + ErrorF ("winRealizeInstalledPaletteShadowGDI\n"); +#endif + + /* Don't do anything if there is not a colormap */ + if (pScreenPriv->pcmapInstalled == NULL) + { +#if CYGDEBUG + ErrorF ("winRealizeInstalledPaletteShadowGDI - No colormap " + "installed\n"); +#endif + return TRUE; + } + + pCmapPriv = winGetCmapPriv (pScreenPriv->pcmapInstalled); + + /* Realize our palette for the screen */ + if (RealizePalette (pScreenPriv->hdcScreen) == GDI_ERROR) + { + ErrorF ("winRealizeInstalledPaletteShadowGDI - RealizePalette () " + "failed\n"); + return FALSE; + } + + /* Set the DIB color table */ + if (SetDIBColorTable (pScreenPriv->hdcShadow, + 0, + WIN_NUM_PALETTE_ENTRIES, + pCmapPriv->rgbColors) == 0) + { + ErrorF ("winRealizeInstalledPaletteShadowGDI - SetDIBColorTable () " + "failed\n"); + return FALSE; + } + + return TRUE; +} + + +/* + * Install the specified colormap + */ + +Bool +winInstallColormapShadowGDI (ColormapPtr pColormap) +{ + ScreenPtr pScreen = pColormap->pScreen; + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + winCmapPriv(pColormap); + + /* + * Tell Windows to install the new colormap + */ + if (SelectPalette (pScreenPriv->hdcScreen, + pCmapPriv->hPalette, + FALSE) == NULL) + { + ErrorF ("winInstallColormapShadowGDI - SelectPalette () failed\n"); + return FALSE; + } + + /* Realize the palette */ + if (GDI_ERROR == RealizePalette (pScreenPriv->hdcScreen)) + { + ErrorF ("winInstallColormapShadowGDI - RealizePalette () failed\n"); + return FALSE; + } + + /* Set the DIB color table */ + if (SetDIBColorTable (pScreenPriv->hdcShadow, + 0, + WIN_NUM_PALETTE_ENTRIES, + pCmapPriv->rgbColors) == 0) + { + ErrorF ("winInstallColormapShadowGDI - SetDIBColorTable () failed\n"); + return FALSE; + } + + /* Redraw the whole window, to take account for the new colors */ + BitBlt (pScreenPriv->hdcScreen, + 0, 0, + pScreenInfo->dwWidth, pScreenInfo->dwHeight, + pScreenPriv->hdcShadow, + 0, 0, + SRCCOPY); + + /* Save a pointer to the newly installed colormap */ + pScreenPriv->pcmapInstalled = pColormap; + + /* Redraw all windows */ + if (pScreenInfo->fMultiWindow) EnumWindows(winRedrawAllProcShadowGDI, 0); + + return TRUE; +} + + +/* + * Store the specified colors in the specified colormap + */ + +Bool +winStoreColorsShadowGDI (ColormapPtr pColormap, + int ndef, + xColorItem *pdefs) +{ + ScreenPtr pScreen = pColormap->pScreen; + winScreenPriv(pScreen); + winCmapPriv(pColormap); + ColormapPtr curpmap = pScreenPriv->pcmapInstalled; + + /* Put the X colormap entries into the Windows logical palette */ + if (SetPaletteEntries (pCmapPriv->hPalette, + pdefs[0].pixel, + ndef, + pCmapPriv->peColors + pdefs[0].pixel) == 0) + { + ErrorF ("winStoreColorsShadowGDI - SetPaletteEntries () failed\n"); + return FALSE; + } + + /* Don't install the Windows palette if the colormap is not installed */ + if (pColormap != curpmap) + { + return TRUE; + } + + /* Try to install the newly modified colormap */ + if (!winInstallColormapShadowGDI (pColormap)) + { + ErrorF ("winInstallColormapShadowGDI - winInstallColormapShadowGDI " + "failed\n"); + return FALSE; + } + +#if 0 + /* Tell Windows that the palette has changed */ + RealizePalette (pScreenPriv->hdcScreen); + + /* Set the DIB color table */ + if (SetDIBColorTable (pScreenPriv->hdcShadow, + pdefs[0].pixel, + ndef, + pCmapPriv->rgbColors + pdefs[0].pixel) == 0) + { + ErrorF ("winInstallColormapShadowGDI - SetDIBColorTable () failed\n"); + return FALSE; + } + + /* Save a pointer to the newly installed colormap */ + pScreenPriv->pcmapInstalled = pColormap; +#endif + + return TRUE; +} + + +/* + * Colormap initialization procedure + */ + +Bool +winCreateColormapShadowGDI (ColormapPtr pColormap) +{ + LPLOGPALETTE lpPaletteNew = NULL; + DWORD dwEntriesMax; + VisualPtr pVisual; + HPALETTE hpalNew = NULL; + winCmapPriv(pColormap); + + /* Get a pointer to the visual that the colormap belongs to */ + pVisual = pColormap->pVisual; + + /* Get the maximum number of palette entries for this visual */ + dwEntriesMax = pVisual->ColormapEntries; + + /* Allocate a Windows logical color palette with max entries */ + lpPaletteNew = malloc (sizeof (LOGPALETTE) + + (dwEntriesMax - 1) * sizeof (PALETTEENTRY)); + if (lpPaletteNew == NULL) + { + ErrorF ("winCreateColormapShadowGDI - Couldn't allocate palette " + "with %d entries\n", + dwEntriesMax); + return FALSE; + } + + /* Zero out the colormap */ + ZeroMemory (lpPaletteNew, sizeof (LOGPALETTE) + + (dwEntriesMax - 1) * sizeof (PALETTEENTRY)); + + /* Set the logical palette structure */ + lpPaletteNew->palVersion = 0x0300; + lpPaletteNew->palNumEntries = dwEntriesMax; + + /* Tell Windows to create the palette */ + hpalNew = CreatePalette (lpPaletteNew); + if (hpalNew == NULL) + { + ErrorF ("winCreateColormapShadowGDI - CreatePalette () failed\n"); + free (lpPaletteNew); + return FALSE; + } + + /* Save the Windows logical palette handle in the X colormaps' privates */ + pCmapPriv->hPalette = hpalNew; + + /* Free the palette initialization memory */ + free (lpPaletteNew); + + return TRUE; +} + + +/* + * Colormap destruction procedure + */ + +Bool +winDestroyColormapShadowGDI (ColormapPtr pColormap) +{ + winScreenPriv(pColormap->pScreen); + winCmapPriv(pColormap); + + /* + * Is colormap to be destroyed the default? + * + * Non-default colormaps should have had winUninstallColormap + * called on them before we get here. The default colormap + * will not have had winUninstallColormap called on it. Thus, + * we need to handle the default colormap in a special way. + */ + if (pColormap->flags & IsDefault) + { +#if CYGDEBUG + ErrorF ("winDestroyColormapShadowGDI - Destroying default " + "colormap\n"); +#endif + + /* + * FIXME: Walk the list of all screens, popping the default + * palette out of each screen device context. + */ + + /* Pop the palette out of the device context */ + SelectPalette (pScreenPriv->hdcScreen, + GetStockObject (DEFAULT_PALETTE), + FALSE); + + /* Clear our private installed colormap pointer */ + pScreenPriv->pcmapInstalled = NULL; + } + + /* Try to delete the logical palette */ + if (DeleteObject (pCmapPriv->hPalette) == 0) + { + ErrorF ("winDestroyColormap - DeleteObject () failed\n"); + return FALSE; + } + + /* Invalidate the colormap privates */ + pCmapPriv->hPalette = NULL; + + return TRUE; +} + + +/* + * Set engine specific funtions + */ + +Bool +winSetEngineFunctionsShadowGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Set our pointers */ + pScreenPriv->pwinAllocateFB = winAllocateFBShadowGDI; + pScreenPriv->pwinShadowUpdate = winShadowUpdateGDI; + pScreenPriv->pwinCloseScreen = winCloseScreenShadowGDI; + pScreenPriv->pwinInitVisuals = winInitVisualsShadowGDI; + pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowGDI; + if (pScreenInfo->fFullScreen) + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen; + else + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; + pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB; + pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowGDI; + pScreenPriv->pwinActivateApp = winActivateAppShadowGDI; + pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowGDI; + pScreenPriv->pwinRealizeInstalledPalette = + winRealizeInstalledPaletteShadowGDI; + pScreenPriv->pwinInstallColormap = winInstallColormapShadowGDI; + pScreenPriv->pwinStoreColors = winStoreColorsShadowGDI; + pScreenPriv->pwinCreateColormap = winCreateColormapShadowGDI; + pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowGDI; + pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)())NoopDDA; + pScreenPriv->pwinCreatePrimarySurface + = (winCreatePrimarySurfaceProcPtr) (void (*)())NoopDDA; + pScreenPriv->pwinReleasePrimarySurface + = (winReleasePrimarySurfaceProcPtr) (void (*)())NoopDDA; + + return TRUE; +} diff --git a/hw/xwin/winwakeup.c b/hw/xwin/winwakeup.c new file mode 100644 index 000000000..37e062fa6 --- /dev/null +++ b/hw/xwin/winwakeup.c @@ -0,0 +1,57 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winwakeup.c,v 1.6 2002/10/17 08:18:25 alanh Exp $ */ + +#include "win.h" + +/* See Porting Layer Definition - p. 7 */ +void +winWakeupHandler (int nScreen, + pointer pWakeupData, + unsigned long ulResult, + pointer pReadmask) +{ + winScreenPriv((ScreenPtr)pWakeupData); + MSG msg; + + /* Process all messages on our queue */ + while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + { + if (g_hDlgDepthChange == 0 || !IsDialogMessage (g_hDlgDepthChange, &msg)) + { + DispatchMessage (&msg); + } + } +} + + diff --git a/hw/xwin/winwindow.c b/hw/xwin/winwindow.c new file mode 100644 index 000000000..b2469c30a --- /dev/null +++ b/hw/xwin/winwindow.c @@ -0,0 +1,463 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Harold L Hunt II + * Kensuke Matsuzaki + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winwindow.c,v 1.6 2003/02/12 15:01:38 alanh Exp $ */ + +#include "win.h" + +/* + * Prototypes for local functions + */ + +static int +winAddRgn (WindowPtr pWindow, pointer data); + +static +void +winUpdateRgn (WindowPtr pWindow); + +#ifdef SHAPE +static +void +winReshape (WindowPtr pWin); +#endif + + +/* See Porting Layer Definition - p. 37 */ +/* See mfb/mfbwindow.c - mfbCreateWindow() */ + +Bool +winCreateWindowNativeGDI (WindowPtr pWin) +{ + ErrorF ("winCreateWindowNativeGDI ()\n"); + return TRUE; +} + + +/* See Porting Layer Definition - p. 37 */ +/* See mfb/mfbwindow.c - mfbDestroyWindow() */ + +Bool +winDestroyWindowNativeGDI (WindowPtr pWin) +{ + ErrorF ("winDestroyWindowNativeGDI ()\n"); + return TRUE; +} + + +/* See Porting Layer Definition - p. 37 */ +/* See mfb/mfbwindow.c - mfbPositionWindow() */ + +Bool +winPositionWindowNativeGDI (WindowPtr pWin, int x, int y) +{ + ErrorF ("winPositionWindowNativeGDI ()\n"); + return TRUE; +} + + +/* See Porting Layer Definition - p. 39 */ +/* See mfb/mfbwindow.c - mfbCopyWindow() */ + +void +winCopyWindowNativeGDI (WindowPtr pWin, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc) +{ + ErrorF ("winCopyWindowNativeGDI ()\n"); +} + + +/* See Porting Layer Definition - p. 37 */ +/* See mfb/mfbwindow.c - mfbChangeWindowAttributes() */ + +Bool +winChangeWindowAttributesNativeGDI (WindowPtr pWin, unsigned long mask) +{ + ErrorF ("winChangeWindowAttributesNativeGDI ()\n"); + return TRUE; +} + + +/* See Porting Layer Definition - p. 37 + * Also referred to as UnrealizeWindow + */ + +Bool +winUnmapWindowNativeGDI (WindowPtr pWindow) +{ + ErrorF ("winUnmapWindowNativeGDI ()\n"); + /* This functions is empty in the CFB, + * we probably won't need to do anything + */ + return TRUE; +} + + +/* See Porting Layer Definition - p. 37 + * Also referred to as RealizeWindow + */ + +Bool +winMapWindowNativeGDI (WindowPtr pWindow) +{ + ErrorF ("winMapWindowNativeGDI ()\n"); + /* This function is empty in the CFB, + * we probably won't need to do anything + */ + return TRUE; + +} + + +/* See Porting Layer Definition - p. 37 */ +/* See mfb/mfbwindow.c - mfbCreateWindow() */ + +Bool +winCreateWindowPRootless (WindowPtr pWin) +{ + Bool fResult = FALSE; + winWindowPriv(pWin); + +#if CYGDEBUG + ErrorF ("winCreateWindowPRootless ()\n"); +#endif + + fResult = winGetScreenPriv(pWin->drawable.pScreen)->CreateWindow(pWin); + + pWinPriv->hRgn = NULL; + /*winUpdateRgn (pWin);*/ + + return fResult; +} + + +/* See Porting Layer Definition - p. 37 */ +/* See mfb/mfbwindow.c - mfbDestroyWindow() */ + +Bool +winDestroyWindowPRootless (WindowPtr pWin) +{ + Bool fResult = FALSE; + winWindowPriv(pWin); + +#if CYGDEBUG + ErrorF ("winDestroyWindowPRootless ()\n"); +#endif + + fResult = winGetScreenPriv(pWin->drawable.pScreen)->DestroyWindow(pWin); + + if (pWinPriv->hRgn != NULL) + { + DeleteObject(pWinPriv->hRgn); + pWinPriv->hRgn = NULL; + } + + winUpdateRgn (pWin); + + return fResult; +} + + +/* See Porting Layer Definition - p. 37 */ +/* See mfb/mfbwindow.c - mfbPositionWindow() */ + +Bool +winPositionWindowPRootless (WindowPtr pWin, int x, int y) +{ + Bool fResult = FALSE; + +#if CYGDEBUG + ErrorF ("winPositionWindowPRootless ()\n"); +#endif + + fResult = winGetScreenPriv(pWin->drawable.pScreen)->PositionWindow(pWin, x, y); + + winUpdateRgn (pWin); + + return fResult; +} + + +/* See Porting Layer Definition - p. 37 */ +/* See mfb/mfbwindow.c - mfbChangeWindowAttributes() */ + +Bool +winChangeWindowAttributesPRootless (WindowPtr pWin, unsigned long mask) +{ + Bool fResult = FALSE; + +#if CYGDEBUG + ErrorF ("winChangeWindowAttributesPRootless ()\n"); +#endif + + fResult = winGetScreenPriv(pWin->drawable.pScreen)->ChangeWindowAttributes(pWin, mask); + + winUpdateRgn (pWin); + + return fResult; +} + + +/* See Porting Layer Definition - p. 37 + * Also referred to as UnrealizeWindow + */ + +Bool +winUnmapWindowPRootless (WindowPtr pWin) +{ + Bool fResult = FALSE; + winWindowPriv(pWin); + +#if CYGDEBUG + ErrorF ("winUnmapWindowPRootless ()\n"); +#endif + + fResult = winGetScreenPriv(pWin->drawable.pScreen)->UnrealizeWindow(pWin); + + if (pWinPriv->hRgn != NULL) + { + DeleteObject(pWinPriv->hRgn); + pWinPriv->hRgn = NULL; + } + + winUpdateRgn (pWin); + + return fResult; +} + + +/* See Porting Layer Definition - p. 37 + * Also referred to as RealizeWindow + */ + +Bool +winMapWindowPRootless (WindowPtr pWin) +{ + Bool fResult = FALSE; + +#if CYGDEBUG + ErrorF ("winMapWindowPRootless ()\n"); +#endif + + fResult = winGetScreenPriv(pWin->drawable.pScreen)->RealizeWindow(pWin); + + winReshape (pWin); + + winUpdateRgn (pWin); + + return fResult; +} + + +#ifdef SHAPE +void +winSetShapePRootless (WindowPtr pWin) +{ +#if CYGDEBUG + ErrorF ("winSetShapePRootless ()\n"); +#endif + + winGetScreenPriv(pWin->drawable.pScreen)->SetShape(pWin); + + winReshape (pWin); + winUpdateRgn (pWin); + + return; +} +#endif + + +/* + * Local function for adding a region to the Windows window region + */ + +static +int +winAddRgn (WindowPtr pWin, pointer data) +{ + int iX, iY, iWidth, iHeight, iBorder; + HRGN hRgn = *(HRGN*)data; + HRGN hRgnWin; + winWindowPriv(pWin); + + /* If pWin is not Root */ + if (pWin->parent != NULL) + { +#if CYGDEBUG + ErrorF ("winAddRgn ()\n"); +#endif + if (pWin->mapped) + { + iBorder = wBorderWidth (pWin); + + iX = pWin->drawable.x - iBorder; + iY = pWin->drawable.y - iBorder; + + iWidth = pWin->drawable.width + iBorder * 2; + iHeight = pWin->drawable.height + iBorder * 2; + + hRgnWin = CreateRectRgn (0, 0, iWidth, iHeight); + + if (hRgnWin == NULL) + { + ErrorF ("winAddRgn - CreateRectRgn () failed\n"); + ErrorF (" Rect %d %d %d %d\n", + iX, iY, iX + iWidth, iY + iHeight); + } + + if (pWinPriv->hRgn) + { + if (CombineRgn (hRgnWin, hRgnWin, pWinPriv->hRgn, RGN_AND) + == ERROR) + { + ErrorF ("winAddRgn - CombineRgn () failed\n"); + } + } + + OffsetRgn (hRgnWin, iX, iY); + + if (CombineRgn (hRgn, hRgn, hRgnWin, RGN_OR) == ERROR) + { + ErrorF ("winAddRgn - CombineRgn () failed\n"); + } + + DeleteObject (hRgnWin); + } + return WT_DONTWALKCHILDREN; + } + else + { + return WT_WALKCHILDREN; + } +} + + +/* + * Local function to update the Windows window's region + */ + +static +void +winUpdateRgn (WindowPtr pWin) +{ + HRGN hRgn = CreateRectRgn (0, 0, 0, 0); + + if (hRgn != NULL) + { + WalkTree (pWin->drawable.pScreen, winAddRgn, &hRgn); + SetWindowRgn (winGetScreenPriv(pWin->drawable.pScreen)->hwndScreen, + hRgn, TRUE); + } + else + { + ErrorF ("winUpdateRgn - CreateRectRgn failed.\n"); + } +} + + +#ifdef SHAPE +static +void +winReshape (WindowPtr pWin) +{ + int nRects; + ScreenPtr pScreen = pWin->drawable.pScreen; + RegionRec rrNewShape; + BoxPtr pShape, pRects, pEnd; + HRGN hRgn, hRgnRect; + winWindowPriv(pWin); + +#if CYGDEBUG + ErrorF ("winReshape ()\n"); +#endif + + /* Bail if the window is the root window */ + if (pWin->parent == NULL) + return; + + /* Bail if the window is not top level */ + if (pWin->parent->parent != NULL) + return; + + /* Free any existing window region stored in the window privates */ + if (pWinPriv->hRgn != NULL) + { + DeleteObject (pWinPriv->hRgn); + pWinPriv->hRgn = NULL; + } + + /* Bail if the window has no bounding region defined */ + if (!wBoundingShape (pWin)) + return; + + REGION_INIT(pScreen, &rrNewShape, NullBox, 0); + REGION_COPY(pScreen, &rrNewShape, wBoundingShape(pWin)); + REGION_TRANSLATE(pScreen, &rrNewShape, pWin->borderWidth, + pWin->borderWidth); + + nRects = REGION_NUM_RECTS(&rrNewShape); + pShape = REGION_RECTS(&rrNewShape); + + if (nRects > 0) + { + /* Create initial empty Windows region */ + hRgn = CreateRectRgn (0, 0, 0, 0); + + /* Loop through all rectangles in the X region */ + for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++) + { + /* Create a Windows region for the X rectangle */ + hRgnRect = CreateRectRgn (pRects->x1, pRects->y1, + pRects->x2, pRects->y2); + if (hRgnRect == NULL) + { + ErrorF("winReshape - CreateRectRgn() failed\n"); + } + + /* Merge the Windows region with the accumulated region */ + if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) + { + ErrorF("winReshape - CombineRgn() failed\n"); + } + + /* Delete the temporary Windows region */ + DeleteObject (hRgnRect); + } + + /* Save a handle to the composite region in the window privates */ + pWinPriv->hRgn = hRgn; + } + + REGION_UNINIT(pScreen, &rrNewShape); + + return; +} +#endif diff --git a/hw/xwin/winwindow.h b/hw/xwin/winwindow.h new file mode 100644 index 000000000..d828b4c70 --- /dev/null +++ b/hw/xwin/winwindow.h @@ -0,0 +1,118 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Kensuke Matsuzaki + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winwindow.h,v 1.1 2003/02/12 15:01:38 alanh Exp $ */ + + +#ifndef _WINWINDOW_H_ +#define _WINWINDOW_H_ + +#ifndef NO +#define NO 0 +#endif +#ifndef YES +#define YES 1 +#endif + +/* Constant strings */ +#define WINDOW_CLASS "cygwin/xfree86 rl" +#define WINDOW_TITLE "Cygwin/XFree86 rl" +#define WIN_SCR_PROP "cyg_screen_prop_rl" +#define WINDOW_CLASS_X "cygwin/xfree86 X rl" +#define WINDOW_TITLE_X "Cygwin/XFree86 X rl" +#define WIN_WINDOW_PROP "cyg_window_prop_rl" +#define WIN_MSG_QUEUE_FNAME "/dev/windows" +#define WIN_LOG_FNAME "/tmp/XWinrl.log" +#define WIN_WID_PROP "cyg_wid_prop_rl" +#define WIN_NEEDMANAGE_PROP "cyg_override_redirect_prop_rl" +#define CYGMULTIWINDOW_DEBUG NO + +typedef struct _winPrivScreenRec *winPrivScreenPtr; + +/* + * Window privates + */ + +typedef struct +{ + DWORD dwDummy; + HRGN hRgn; + HWND hWnd; + winPrivScreenPtr pScreenPriv; + int iX; + int iY; + int iWidth; + int iHeight; + Bool fXKilled; +} winPrivWinRec, *winPrivWinPtr; + +typedef struct _winWMMessageRec{ + DWORD dwID; + DWORD msg; + int iWindow; + HWND hwndWindow; + int iX, iY; + int iWidth, iHeight; +} winWMMessageRec, *winWMMessagePtr; + +/* + * winrootlesswm.c + */ +#define WM_WM_MOVE (WM_USER + 1) +#define WM_WM_SIZE (WM_USER + 2) +#define WM_WM_RAISE (WM_USER + 3) +#define WM_WM_LOWER (WM_USER + 4) +#define WM_WM_MAP (WM_USER + 5) +#define WM_WM_UNMAP (WM_USER + 6) +#define WM_WM_KILL (WM_USER + 7) +#define WM_WM_ACTIVATE (WM_USER + 8) + +#define WMMSG_MSG 10 + + +/* + * winmultiwindowwm.c + */ + +void +winSendMessageToWM (void *pWMInfo, winWMMessagePtr msg); + +Bool +winInitWM (void **ppWMInfo, + pthread_t *ptWMProc, +#if 0 + pthread_cond_t *ppcServerStarted, +#endif + pthread_mutex_t *ppmServerStarted, +#if 0 + Bool *pfServerStarted, +#endif + int dwScreen); + +#endif diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c new file mode 100644 index 000000000..6aa29316d --- /dev/null +++ b/hw/xwin/winwndproc.c @@ -0,0 +1,1131 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *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 + *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. + * + * Authors: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + * MATSUZAKI Kensuke + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winwndproc.c,v 1.24 2003/02/12 15:01:38 alanh Exp $ */ + +#include "win.h" +#include + +BOOL CALLBACK +winChangeDepthDlgProc (HWND hDialog, UINT message, + WPARAM wParam, LPARAM lParam); + + +/* + * Called by winWakeupHandler + * Processes current Windows message + */ + +LRESULT CALLBACK +winWindowProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam) +{ + static winPrivScreenPtr s_pScreenPriv = NULL; + static winScreenInfo *s_pScreenInfo = NULL; + static ScreenPtr s_pScreen = NULL; + static HWND s_hwndLastPrivates = NULL; + static HINSTANCE s_hInstance; + static Bool s_fCursor = TRUE; + static Bool s_fTracking = FALSE; + static unsigned long s_ulServerGeneration = 0; + int iScanCode; + int i; + + /* Watch for server regeneration */ + if (g_ulServerGeneration != s_ulServerGeneration) + { + /* Store new server generation */ + s_ulServerGeneration = g_ulServerGeneration; + } + + /* Only retrieve new privates pointers if window handle is null or changed */ + if ((s_pScreenPriv == NULL || hwnd != s_hwndLastPrivates) + && (s_pScreenPriv = GetProp (hwnd, WIN_SCR_PROP)) != NULL) + { +#if CYGDEBUG + ErrorF ("winWindowProc - Setting privates handle\n"); +#endif + s_pScreenInfo = s_pScreenPriv->pScreenInfo; + s_pScreen = s_pScreenInfo->pScreen; + s_hwndLastPrivates = hwnd; + } + else if (s_pScreenPriv == NULL) + { + /* For safety, handle case that should never happen */ + s_pScreenInfo = NULL; + s_pScreen = NULL; + s_hwndLastPrivates = NULL; + } + + /* Branch on message type */ + switch (message) + { + case WM_CREATE: +#if CYGDEBUG + ErrorF ("winWindowProc - WM_CREATE\n"); +#endif + + /* + * Add a property to our display window that references + * this screens' privates. + * + * This allows the window procedure to refer to the + * appropriate window DC and shadow DC for the window that + * it is processing. We use this to repaint exposed + * areas of our display window. + */ + s_pScreenPriv = ((LPCREATESTRUCT) lParam)->lpCreateParams; + s_hInstance = ((LPCREATESTRUCT) lParam)->hInstance; + s_pScreenInfo = s_pScreenPriv->pScreenInfo; + s_pScreen = s_pScreenInfo->pScreen; + s_hwndLastPrivates = hwnd; + SetProp (hwnd, WIN_SCR_PROP, s_pScreenPriv); + + /* Store the mode key states so restore doesn't try to restore them */ + winStoreModeKeyStates (s_pScreen); + return 0; + + case WM_DISPLAYCHANGE: + /* We cannot handle a display mode change during initialization */ + if (s_pScreenInfo == NULL) + FatalError ("winWindowProc - WM_DISPLAYCHANGE - The display " + "mode changed while we were intializing. This is " + "very bad and unexpected. Exiting.\n"); + + /* + * We do not care about display changes with + * fullscreen DirectDraw engines, because those engines set + * their own mode when they become active. + */ + if (s_pScreenInfo->fFullScreen + && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD + || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL + || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD)) + { + /* + * Store the new display dimensions and depth. + * We do this here for future compatibility in case we + * ever allow switching from fullscreen to windowed mode. + */ + s_pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN); + s_pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN); + s_pScreenPriv->dwLastWindowsBitsPixel + = GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL); + break; + } + + ErrorF ("winWindowProc - WM_DISPLAYCHANGE - orig bpp: %d, last bpp: %d, " + "new bpp: %d\n", + s_pScreenInfo->dwBPP, + s_pScreenPriv->dwLastWindowsBitsPixel, + wParam); + + ErrorF ("winWindowProc - WM_DISPLAYCHANGE - new width: %d " + "new height: %d\n", + LOWORD (lParam), HIWORD (lParam)); + + /* + * TrueColor --> TrueColor depth changes are disruptive for: + * Windowed: + * Shadow DirectDraw + * Shadow DirectDraw Non-Locking + * Primary DirectDraw + * + * TrueColor --> TrueColor depth changs are non-optimal for: + * Windowed: + * Shadow GDI + * + * FullScreen: + * Shadow GDI + * + * TrueColor --> PseudoColor or vice versa are disruptive for: + * Windowed: + * Shadow DirectDraw + * Shadow DirectDraw Non-Locking + * Primary DirectDraw + * Shadow GDI + */ + + /* + * Check for a disruptive change in depth. + * We can only display a message for a disruptive depth change, + * we cannot do anything to correct the situation. + */ + if ((s_pScreenInfo->dwBPP != wParam) + && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD + || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL + || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD)) + { + /* Cannot display the visual until the depth is restored */ + ErrorF ("winWindowProc - Disruptive change in depth\n"); + + /* Check if the dialog box already exists */ + if (g_hDlgDepthChange != NULL) + { + ErrorF ("winWindowProc - Dialog box already exists\n"); + + /* Dialog box already exists, just display it */ + ShowWindow (g_hDlgDepthChange, SW_SHOWDEFAULT); + } + else + { + /* + * Display a notification to the user that the visual + * will not be displayed until the Windows display depth + * is restored to the original value. + */ + g_hDlgDepthChange = CreateDialogParam (s_hInstance, + "DEPTH_CHANGE_BOX", + hwnd, + winChangeDepthDlgProc, + (int) s_pScreenPriv); + + /* Show the dialog box */ + ShowWindow (g_hDlgDepthChange, SW_SHOW); + + ErrorF ("winWindowProc - DialogBox returned: %d\n", + g_hDlgDepthChange); + ErrorF ("winWindowProc - GetLastError: %d\n", GetLastError ()); + + /* Minimize the display window */ + ShowWindow (hwnd, SW_MINIMIZE); + + /* Flag that we have an invalid screen depth */ + s_pScreenPriv->fBadDepth = TRUE; + + /* + * TODO: Redisplay the dialog box if it is not + * currently displayed. + */ + } + } + else + { + /* Flag that we have a valid screen depth */ + s_pScreenPriv->fBadDepth = FALSE; + } + + /* + * Check for a change in display dimensions. + * We can simply recreate the same-sized primary surface when + * the display dimensions change. + */ + if (s_pScreenPriv->dwLastWindowsWidth != LOWORD (lParam) + || s_pScreenPriv->dwLastWindowsHeight != HIWORD (lParam)) + { + /* + * NOTE: The non-DirectDraw engines set the ReleasePrimarySurface + * and CreatePrimarySurface function pointers to point + * to the no operation function, NoopDDA. This allows us + * to blindly call these functions, even if they are not + * relevant to the current engine (e.g., Shadow GDI). + */ + +#if CYGDEBUG + ErrorF ("winWindowProc - WM_DISPLAYCHANGE - Dimensions changed\n"); +#endif + + /* Release the old primary surface */ + (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen); + +#if CYGDEBUG + ErrorF ("winWindowProc - WM_DISPLAYCHANGE - Released " + "primary surface\n"); +#endif + + /* Create the new primary surface */ + (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen); + +#if CYGDEBUG + ErrorF ("winWindowProc - WM_DISPLAYCHANGE - Recreated " + "primary surface\n"); +#endif + } + else + { +#if CYGDEBUG + ErrorF ("winWindowProc - WM_DISPLAYCHANGE - Dimensions did not " + "change\n"); +#endif + } + + /* Store the new display dimensions and depth */ + s_pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN); + s_pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN); + s_pScreenPriv->dwLastWindowsBitsPixel + = GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL); + break; + + case WM_SIZE: + { + SCROLLINFO si; + RECT rcWindow; + int iWidth, iHeight; + +#if CYGDEBUG + ErrorF ("winWindowProc - WM_SIZE\n"); +#endif + + /* Break if we do not use scrollbars */ + if (!s_pScreenInfo->fScrollbars + || !s_pScreenInfo->fDecoration + || s_pScreenInfo->fRootless + || s_pScreenInfo->fMultiWindow + || s_pScreenInfo->fFullScreen) + break; + + /* No need to resize if we get minimized */ + if (wParam == SIZE_MINIMIZED) + return 0; + + /* + * Get the size of the whole window, including client area, + * scrollbars, and non-client area decorations (caption, borders). + * We do this because we need to check if the client area + * without scrollbars is large enough to display the whole visual. + * The new client area size passed by lParam already subtracts + * the size of the scrollbars if they are currently displayed. + * So checking is LOWORD(lParam) == visual_width and + * HIWORD(lParam) == visual_height will never tell us to hide + * the scrollbars because the client area would always be too small. + * GetClientRect returns the same sizes given by lParam, so we + * cannot use GetClientRect either. + */ + GetWindowRect (hwnd, &rcWindow); + iWidth = rcWindow.right - rcWindow.left; + iHeight = rcWindow.bottom - rcWindow.top; + + ErrorF ("winWindowProc - WM_SIZE - window w: %d h: %d, " + "new client area w: %d h: %d\n", + iWidth, iHeight, LOWORD (lParam), HIWORD (lParam)); + + /* Subtract the frame size from the window size. */ + iWidth -= 2 * GetSystemMetrics (SM_CXSIZEFRAME); + iHeight -= (2 * GetSystemMetrics (SM_CYSIZEFRAME) + + GetSystemMetrics (SM_CYCAPTION)); + + /* + * Update scrollbar page sizes. + * NOTE: If page size == range, then the scrollbar is + * automatically hidden. + */ + + /* Is the naked client area large enough to show the whole visual? */ + if (iWidth < s_pScreenInfo->dwWidth + || iHeight < s_pScreenInfo->dwHeight) + { + /* Client area too small to display visual, use scrollbars */ + iWidth -= GetSystemMetrics (SM_CXVSCROLL); + iHeight -= GetSystemMetrics (SM_CYHSCROLL); + } + + /* Set the horizontal scrollbar page size */ + si.cbSize = sizeof (si); + si.fMask = SIF_PAGE | SIF_RANGE; + si.nMin = 0; + si.nMax = s_pScreenInfo->dwWidth - 1; + si.nPage = iWidth; + SetScrollInfo (hwnd, SB_HORZ, &si, TRUE); + + /* Set the vertical scrollbar page size */ + si.cbSize = sizeof (si); + si.fMask = SIF_PAGE | SIF_RANGE; + si.nMin = 0; + si.nMax = s_pScreenInfo->dwHeight - 1; + si.nPage = iHeight; + SetScrollInfo (hwnd, SB_VERT, &si, TRUE); + + /* + * NOTE: Scrollbars may have moved if they were at the + * far right/bottom, so we query their current position. + */ + + /* Get the horizontal scrollbar position and set the offset */ + si.cbSize = sizeof (si); + si.fMask = SIF_POS; + GetScrollInfo (hwnd, SB_HORZ, &si); + s_pScreenInfo->dwXOffset = -si.nPos; + + /* Get the vertical scrollbar position and set the offset */ + si.cbSize = sizeof (si); + si.fMask = SIF_POS; + GetScrollInfo (hwnd, SB_VERT, &si); + s_pScreenInfo->dwYOffset = -si.nPos; + } + return 0; + + case WM_VSCROLL: + { + SCROLLINFO si; + int iVertPos; + +#if CYGDEBUG + ErrorF ("winWindowProc - WM_VSCROLL\n"); +#endif + + /* Get vertical scroll bar info */ + si.cbSize = sizeof (si); + si.fMask = SIF_ALL; + GetScrollInfo (hwnd, SB_VERT, &si); + + /* Save the vertical position for comparison later */ + iVertPos = si.nPos; + + /* + * Don't forget: + * moving the scrollbar to the DOWN, scroll the content UP + */ + switch (LOWORD(wParam)) + { + case SB_TOP: + si.nPos = si.nMin; + break; + + case SB_BOTTOM: + si.nPos = si.nMax - si.nPage + 1; + break; + + case SB_LINEUP: + si.nPos -= 1; + break; + + case SB_LINEDOWN: + si.nPos += 1; + break; + + case SB_PAGEUP: + si.nPos -= si.nPage; + break; + + case SB_PAGEDOWN: + si.nPos += si.nPage; + break; + + case SB_THUMBTRACK: + si.nPos = si.nTrackPos; + break; + + default: + break; + } + + /* + * We retrieve the position after setting it, + * because Windows may adjust it. + */ + si.fMask = SIF_POS; + SetScrollInfo (hwnd, SB_VERT, &si, TRUE); + GetScrollInfo (hwnd, SB_VERT, &si); + + /* Scroll the window if the position has changed */ + if (si.nPos != iVertPos) + { + /* Save the new offset for bit block transfers, etc. */ + s_pScreenInfo->dwYOffset = -si.nPos; + + /* Change displayed region in the window */ + ScrollWindowEx (hwnd, + 0, + iVertPos - si.nPos, + NULL, + NULL, + NULL, + NULL, + SW_INVALIDATE); + + /* Redraw the window contents */ + UpdateWindow (hwnd); + } + } + return 0; + + case WM_HSCROLL: + { + SCROLLINFO si; + int iHorzPos; + +#if CYGDEBUG + ErrorF ("winWindowProc - WM_HSCROLL\n"); +#endif + + /* Get horizontal scroll bar info */ + si.cbSize = sizeof (si); + si.fMask = SIF_ALL; + GetScrollInfo (hwnd, SB_HORZ, &si); + + /* Save the horizontal position for comparison later */ + iHorzPos = si.nPos; + + /* + * Don't forget: + * moving the scrollbar to the RIGHT, scroll the content LEFT + */ + switch (LOWORD(wParam)) + { + case SB_LEFT: + si.nPos = si.nMin; + break; + + case SB_RIGHT: + si.nPos = si.nMax - si.nPage + 1; + break; + + case SB_LINELEFT: + si.nPos -= 1; + break; + + case SB_LINERIGHT: + si.nPos += 1; + break; + + case SB_PAGELEFT: + si.nPos -= si.nPage; + break; + + case SB_PAGERIGHT: + si.nPos += si.nPage; + break; + + case SB_THUMBTRACK: + si.nPos = si.nTrackPos; + break; + + default: + break; + } + + /* + * We retrieve the position after setting it, + * because Windows may adjust it. + */ + si.fMask = SIF_POS; + SetScrollInfo (hwnd, SB_HORZ, &si, TRUE); + GetScrollInfo (hwnd, SB_HORZ, &si); + + /* Scroll the window if the position has changed */ + if (si.nPos != iHorzPos) + { + /* Save the new offset for bit block transfers, etc. */ + s_pScreenInfo->dwXOffset = -si.nPos; + + /* Change displayed region in the window */ + ScrollWindowEx (hwnd, + iHorzPos - si.nPos, + 0, + NULL, + NULL, + NULL, + NULL, + SW_INVALIDATE); + + /* Redraw the window contents */ + UpdateWindow (hwnd); + } + } + return 0; + + case WM_GETMINMAXINFO: + { + MINMAXINFO *pMinMaxInfo = (MINMAXINFO *) lParam; + int iCaptionHeight; + int iBorderHeight, iBorderWidth; + +#if CYGDEBUG + ErrorF ("winWindowProc - WM_GETMINMAXINFO - pScreenInfo: %08x\n", + s_pScreenInfo); +#endif + + /* Can't do anything without screen info */ + if (s_pScreenInfo == NULL + || !s_pScreenInfo->fScrollbars + || s_pScreenInfo->fFullScreen + || !s_pScreenInfo->fDecoration + || s_pScreenInfo->fRootless + || s_pScreenInfo->fMultiWindow) + break; + + /* + * Here we can override the maximum tracking size, which + * is the largest size that can be assigned to our window + * via the sizing border. + */ + + /* + * FIXME: Do we only need to do this once, since our visual size + * does not change? Does Windows store this value statically + * once we have set it once? + */ + + /* Get the border and caption sizes */ + iCaptionHeight = GetSystemMetrics (SM_CYCAPTION); + iBorderWidth = 2 * GetSystemMetrics (SM_CXSIZEFRAME); + iBorderHeight = 2 * GetSystemMetrics (SM_CYSIZEFRAME); + + /* Allow the full visual to be displayed */ + pMinMaxInfo->ptMaxTrackSize.x + = s_pScreenInfo->dwWidth + iBorderWidth; + pMinMaxInfo->ptMaxTrackSize.y + = s_pScreenInfo->dwHeight + iBorderHeight + iCaptionHeight; + } + return 0; + + case WM_ERASEBKGND: +#if CYGDEBUG + ErrorF ("winWindowProc - WM_ERASEBKGND\n"); +#endif + /* + * Pretend that we did erase the background but we don't care, + * the application uses the full window estate. This avoids some + * flickering when resizing. + */ + return TRUE; + + case WM_PAINT: +#if CYGDEBUG + ErrorF ("winWindowProc - WM_PAINT\n"); +#endif + /* Only paint if we have privates and the server is enabled */ + if (s_pScreenPriv == NULL + || !s_pScreenPriv->fEnabled + || (s_pScreenInfo->fFullScreen && !s_pScreenPriv->fActive) + || s_pScreenPriv->fBadDepth) + { + /* We don't want to paint */ + break; + } + + /* Break out here if we don't have a valid paint routine */ + if (s_pScreenPriv->pwinBltExposedRegions == NULL) + break; + + /* Call the engine dependent repainter */ + (*s_pScreenPriv->pwinBltExposedRegions) (s_pScreen); + return 0; + + case WM_PALETTECHANGED: + { +#if CYGDEBUG + ErrorF ("winWindowProc - WM_PALETTECHANGED\n"); +#endif + /* + * Don't process if we don't have privates or a colormap, + * or if we have an invalid depth. + */ + if (s_pScreenPriv == NULL + || s_pScreenPriv->pcmapInstalled == NULL + || s_pScreenPriv->fBadDepth) + break; + + /* Return if we caused the palette to change */ + if ((HWND) wParam == hwnd) + { + /* Redraw the screen */ + (*s_pScreenPriv->pwinRedrawScreen) (s_pScreen); + return 0; + } + + /* Reinstall the windows palette */ + (*s_pScreenPriv->pwinRealizeInstalledPalette) (s_pScreen); + + /* Redraw the screen */ + (*s_pScreenPriv->pwinRedrawScreen) (s_pScreen); + return 0; + } + + case WM_MOUSEMOVE: + /* We can't do anything without privates */ + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* Has the mouse pointer crossed screens? */ + if (s_pScreen != miPointerCurrentScreen ()) + miPointerSetNewScreen (s_pScreenInfo->dwScreen, + GET_X_LPARAM(lParam)-s_pScreenInfo->dwXOffset, + GET_Y_LPARAM(lParam)-s_pScreenInfo->dwYOffset); + + /* Are we tracking yet? */ + if (!s_fTracking) + { + TRACKMOUSEEVENT tme; + + /* Setup data structure */ + ZeroMemory (&tme, sizeof (tme)); + tme.cbSize = sizeof (tme); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = hwnd; + + /* Call the tracking function */ + if (!(*g_fpTrackMouseEvent) (&tme)) + ErrorF ("winWindowProc - _TrackMouseEvent failed\n"); + + /* Flag that we are tracking now */ + s_fTracking = TRUE; + } + + /* Hide or show the Windows mouse cursor */ + if (s_fCursor && (s_pScreenPriv->fActive || s_pScreenInfo->fLessPointer)) + { + /* Hide Windows cursor */ + s_fCursor = FALSE; + ShowCursor (FALSE); + } + else if (!s_fCursor && !s_pScreenPriv->fActive + && !s_pScreenInfo->fLessPointer) + { + /* Show Windows cursor */ + s_fCursor = TRUE; + ShowCursor (TRUE); + } + + /* Deliver absolute cursor position to X Server */ + miPointerAbsoluteCursor (GET_X_LPARAM(lParam)-s_pScreenInfo->dwXOffset, + GET_Y_LPARAM(lParam)-s_pScreenInfo->dwYOffset, + g_c32LastInputEventTime = GetTickCount ()); + return 0; + + case WM_NCMOUSEMOVE: + /* + * We break instead of returning 0 since we need to call + * DefWindowProc to get the mouse cursor changes + * and min/max/close button highlighting in Windows XP. + * The Platform SDK says that you should return 0 if you + * process this message, but it fails to mention that you + * will give up any default functionality if you do return 0. + */ + + /* We can't do anything without privates */ + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* Non-client mouse movement, show Windows cursor */ + if (!s_fCursor) + { + s_fCursor = TRUE; + ShowCursor (TRUE); + } + break; + + case WM_MOUSELEAVE: + /* Mouse has left our client area */ + + /* Flag that we are no longer tracking */ + s_fTracking = FALSE; + + /* Show the mouse cursor, if necessary */ + if (!s_fCursor) + { + s_fCursor = TRUE; + ShowCursor (TRUE); + } + return 0; + + case WM_LBUTTONDBLCLK: + case WM_LBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + if (s_pScreenInfo->fRootless) SetCapture (hwnd); + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam); + + case WM_LBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + if (s_pScreenInfo->fRootless) ReleaseCapture (); + return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam); + + case WM_MBUTTONDBLCLK: + case WM_MBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + if (s_pScreenInfo->fRootless) SetCapture (hwnd); + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam); + + case WM_MBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + if (s_pScreenInfo->fRootless) ReleaseCapture (); + return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam); + + case WM_RBUTTONDBLCLK: + case WM_RBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + if (s_pScreenInfo->fRootless) SetCapture (hwnd); + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam); + + case WM_RBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + if (s_pScreenInfo->fRootless) ReleaseCapture (); + return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam); + + case WM_TIMER: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* Branch on the timer id */ + switch (wParam) + { + case WIN_E3B_TIMER_ID: + /* Send delayed button press */ + winMouseButtonsSendEvent (ButtonPress, + s_pScreenPriv->iE3BCachedPress); + + /* Kill this timer */ + KillTimer (s_pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID); + + /* Clear screen privates flags */ + s_pScreenPriv->iE3BCachedPress = 0; + break; + } + return 0; + + case WM_CTLCOLORSCROLLBAR: + FatalError ("winWindowProc - WM_CTLCOLORSCROLLBAR - We are not " + "supposed to get this message. Exiting.\n"); + return 0; + + case WM_MOUSEWHEEL: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; +#if CYGDEBUG + ErrorF ("winWindowProc - WM_MOUSEWHEEL\n"); +#endif + winMouseWheel (s_pScreen, GET_WHEEL_DELTA_WPARAM(wParam)); + break; + + case WM_SETFOCUS: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* Restore the state of all mode keys */ + winRestoreModeKeyStates (s_pScreen); + return 0; + + case WM_KILLFOCUS: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* Store the state of all mode keys */ + winStoreModeKeyStates (s_pScreen); + + /* Release any pressed keys */ + winKeybdReleaseKeys (); + return 0; + +#if WIN_NEW_KEYBOARD_SUPPORT + case WM_SYSKEYDOWN: + case WM_KEYDOWN: + case WM_SYSKEYUP: + case WM_KEYUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* Don't process keys if we are not active */ + if (!s_pScreenPriv->fActive) + return 0; + + winProcessKeyEvent ((DWORD)wParam, (DWORD) lParam); + return 0; + + case WM_DEADCHAR: + case WM_SYSDEADCHAR: + return 0; + +#else /* WIN_NEW_KEYBOARD_SUPPORT */ + case WM_SYSKEYDOWN: + case WM_KEYDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* + * FIXME: Catching Alt-F4 like this is really terrible. This should + * be generalized to handle other Windows keyboard signals. Actually, + * the list keys to catch and the actions to perform when caught should + * be configurable; that way user's can customize the keys that they + * need to have passed through to their window manager or apps, or they + * can remap certain actions to new key codes that do not conflict + * with the X apps that they are using. Yeah, that'll take awhile. + */ + if ((s_pScreenInfo->fUseWinKillKey && wParam == VK_F4 + && (GetKeyState (VK_MENU) & 0x8000)) + || (s_pScreenInfo->fUseUnixKillKey && wParam == VK_BACK + && (GetKeyState (VK_MENU) & 0x8000) + && (GetKeyState (VK_CONTROL) & 0x8000))) + { + /* + * Better leave this message here, just in case some unsuspecting + * user enters Alt + F4 and is surprised when the application + * quits. + */ + ErrorF ("winWindowProc - WM_*KEYDOWN - Closekey hit, quitting\n"); + + /* Tell our message queue to give up */ + PostMessage (hwnd, WM_CLOSE, 0, 0); + return 0; + } + + /* + * Don't do anything for the Windows keys, as focus will soon + * be returned to Windows. We may be able to trap the Windows keys, + * but we should determine if that is desirable before doing so. + */ + if (wParam == VK_LWIN || wParam == VK_RWIN) + break; + + /* Discard fake Ctrl_L presses that precede AltGR on non-US keyboards */ + if (winIsFakeCtrl_L (message, wParam, lParam)) + return 0; + + /* Send the key event(s) */ + winTranslateKey (wParam, lParam, &iScanCode); + for (i = 0; i < LOWORD(lParam); ++i) + winSendKeyEvent (iScanCode, TRUE); + return 0; + + case WM_SYSKEYUP: + case WM_KEYUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* + * Don't do anything for the Windows keys, as focus will soon + * be returned to Windows. We may be able to trap the Windows keys, + * but we should determine if that is desirable before doing so. + */ + if (wParam == VK_LWIN || wParam == VK_RWIN) + break; + + /* Ignore the fake Ctrl_L that follows an AltGr release */ + if (winIsFakeCtrl_L (message, wParam, lParam)) + return 0; + + /* Enqueue a keyup event */ + winTranslateKey (wParam, lParam, &iScanCode); + winSendKeyEvent (iScanCode, FALSE); + return 0; +#endif /* WIN_NEW_KEYBOARD_SUPPORT */ + + case WM_HOTKEY: + if (s_pScreenPriv == NULL) + break; + + /* Call the engine-specific hot key handler */ + (*s_pScreenPriv->pwinHotKeyAltTab) (s_pScreen); + return 0; + + case WM_ACTIVATE: + if (s_pScreenPriv == NULL + || s_pScreenInfo->fIgnoreInput) + break; + + /* TODO: Override display of window when we have a bad depth */ + if (LOWORD(wParam) != WA_INACTIVE && s_pScreenPriv->fBadDepth) + { + ErrorF ("winWindowProc - WM_ACTIVATE - Bad depth, trying " + "to override window activation\n"); + + /* Minimize the window */ + ShowWindow (hwnd, SW_MINIMIZE); + + /* Display dialog box */ + if (g_hDlgDepthChange != NULL) + { + /* Make the existing dialog box active */ + SetActiveWindow (g_hDlgDepthChange); + } + else + { + /* TODO: Recreate the dialog box and bring to the top */ + ShowWindow (g_hDlgDepthChange, SW_SHOWDEFAULT); + } + + /* Don't do any other processing of this message */ + return 0; + } + + + +#if CYGDEBUG + ErrorF ("winWindowProc - WM_ACTIVATE\n"); +#endif + + /* + * Focus is being changed to another window. + * The other window may or may not belong to + * our process. + */ + + /* Clear any lingering wheel delta */ + s_pScreenPriv->iDeltaZ = 0; + + /* Reshow the Windows mouse cursor if we are being deactivated */ + if (LOWORD(wParam) == WA_INACTIVE + && !s_fCursor) + { + /* Show Windows cursor */ + s_fCursor = TRUE; + ShowCursor (TRUE); + } + return 0; + + case WM_ACTIVATEAPP: + if (s_pScreenPriv == NULL + || s_pScreenInfo->fIgnoreInput) + break; + +#if CYGDEBUG + ErrorF ("winWindowProc - WM_ACTIVATEAPP\n"); +#endif + + /* Activate or deactivate */ + s_pScreenPriv->fActive = wParam; + + /* Reshow the Windows mouse cursor if we are being deactivated */ + if (!s_pScreenPriv->fActive + && !s_fCursor) + { + /* Show Windows cursor */ + s_fCursor = TRUE; + ShowCursor (TRUE); + } + + /* Call engine specific screen activation/deactivation function */ + (*s_pScreenPriv->pwinActivateApp) (s_pScreen); + return 0; + + case WM_CLOSE: + /* Tell X that we are giving up */ + GiveUp (0); + return 0; + } + + return DefWindowProc (hwnd, message, wParam, lParam); +} + + +/* + * Process messages for the dialog that is displayed for + * disruptive screen depth changes. + */ + +BOOL CALLBACK +winChangeDepthDlgProc (HWND hwndDialog, UINT message, + WPARAM wParam, LPARAM lParam) +{ + static winPrivScreenPtr s_pScreenPriv = NULL; + static winScreenInfo *s_pScreenInfo = NULL; + static ScreenPtr s_pScreen = NULL; + +#if CYGDEBUG + ErrorF ("winChangeDepthDlgProc\n"); +#endif + + /* Branch on message type */ + switch (message) + { + case WM_INITDIALOG: +#if CYGDEBUG + ErrorF ("winChangeDepthDlgProc - WM_INITDIALOG\n"); +#endif + + /* Store pointers to private structures for future use */ + s_pScreenPriv = (winPrivScreenPtr) lParam; + s_pScreenInfo = s_pScreenPriv->pScreenInfo; + s_pScreen = s_pScreenInfo->pScreen; + +#if CYGDEBUG + ErrorF ("winChangeDepthDlgProc - WM_INITDIALG - s_pScreenPriv: %08x, " + "s_pScreenInfo: %08x, s_pScreen: %08x\n", + s_pScreenPriv, s_pScreenInfo, s_pScreen); +#endif + +#if CYGDEBUG + ErrorF ("winChangeDepthDlgProc - WM_INITDIALOG - orig bpp: %d, " + "last bpp: %d\n", + s_pScreenInfo->dwBPP, + s_pScreenPriv->dwLastWindowsBitsPixel); +#endif + return TRUE; + + case WM_DISPLAYCHANGE: +#if CYGDEBUG + ErrorF ("winChangeDepthDlgProc - WM_DISPLAYCHANGE - orig bpp: %d, " + "last bpp: %d, new bpp: %d\n", + s_pScreenInfo->dwBPP, + s_pScreenPriv->dwLastWindowsBitsPixel, + wParam); +#endif + + /* Dismiss the dialog if the display returns to the original depth */ + if (wParam == s_pScreenInfo->dwBPP) + { + ErrorF ("winChangeDelthDlgProc - wParam == s_pScreenInfo->dwBPP\n"); + + /* Depth has been restored, dismiss dialog */ + DestroyWindow (g_hDlgDepthChange); + g_hDlgDepthChange = NULL; + + /* Flag that we have a valid screen depth */ + s_pScreenPriv->fBadDepth = FALSE; + } + return TRUE; + + case WM_COMMAND: + switch (LOWORD (wParam)) + { + case IDOK: + case IDCANCEL: + ErrorF ("winChangeDepthDlgProc - WM_COMMAND - IDOK or IDCANCEL\n"); + + /* + * User dismissed the dialog, hide it until the + * display mode is restored. + */ + ShowWindow (g_hDlgDepthChange, SW_HIDE); + return TRUE; + } + break; + + case WM_CLOSE: + ErrorF ("winChangeDepthDlgProc - WM_CLOSE\n"); + + /* + * User dismissed the dialog, hide it until the + * display mode is restored. + */ + ShowWindow (g_hDlgDepthChange, SW_HIDE); + return TRUE; + } + + return FALSE; +} -- cgit v1.2.3