summaryrefslogtreecommitdiff
path: root/xserver/hw/xwin/InitOutput.c
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-26 18:24:03 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-26 18:24:03 +0000
commitd3670d5856b59bfb45682bbfc29e6f1d0ccbea57 (patch)
tree7cc2005c59191b981a2056bcffa9d75fdf2e0d0e /xserver/hw/xwin/InitOutput.c
parent04f51aaa1f5b0cac419d2891812446c790b9c581 (diff)
Importing xserver from X.Org 7.2RC2
Diffstat (limited to 'xserver/hw/xwin/InitOutput.c')
-rw-r--r--xserver/hw/xwin/InitOutput.c1162
1 files changed, 1162 insertions, 0 deletions
diff --git a/xserver/hw/xwin/InitOutput.c b/xserver/hw/xwin/InitOutput.c
new file mode 100644
index 000000000..b64eee9c7
--- /dev/null
+++ b/xserver/hw/xwin/InitOutput.c
@@ -0,0 +1,1162 @@
+/* $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.
+
+*/
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+#include "winmsg.h"
+#include "winconfig.h"
+#include "winprefs.h"
+#ifdef XWIN_CLIPBOARD
+#include "X11/Xlocale.h"
+#endif
+#ifdef DPMSExtension
+#include "dpmsproc.h"
+#endif
+#ifdef __CYGWIN__
+#include <mntent.h>
+#endif
+#if defined(XKB) && defined(WIN32)
+#include <X11/extensions/XKBsrv.h>
+#endif
+#ifdef RELOCATE_PROJECTROOT
+#include <shlobj.h>
+typedef HRESULT (*SHGETFOLDERPATHPROC)(
+ HWND hwndOwner,
+ int nFolder,
+ HANDLE hToken,
+ DWORD dwFlags,
+ LPTSTR pszPath
+);
+#endif
+
+
+/*
+ * References to external symbols
+ */
+
+extern int g_iNumScreens;
+extern winScreenInfo g_ScreenInfo[];
+extern int g_iLastScreen;
+extern char * g_pszCommandLine;
+extern Bool g_fSilentFatalError;
+
+extern char * g_pszLogFile;
+extern Bool g_fLogFileChanged;
+extern int g_iLogVerbose;
+Bool g_fLogInited;
+
+extern Bool g_fXdmcpEnabled;
+#ifdef HAS_DEVWINDOWS
+extern int g_fdMessageQueue;
+#endif
+extern const char * g_pszQueryHost;
+extern HINSTANCE g_hInstance;
+
+#ifdef XWIN_CLIPBOARD
+extern Bool g_fUnicodeClipboard;
+extern Bool g_fClipboardLaunched;
+extern Bool g_fClipboardStarted;
+extern pthread_t g_ptClipboardProc;
+extern HWND g_hwndClipboard;
+extern Bool g_fClipboard;
+#endif
+
+extern HMODULE g_hmodDirectDraw;
+extern FARPROC g_fpDirectDrawCreate;
+extern FARPROC g_fpDirectDrawCreateClipper;
+
+extern HMODULE g_hmodCommonControls;
+extern FARPROC g_fpTrackMouseEvent;
+extern Bool g_fNoHelpMessageBox;
+extern Bool g_fSilentDupError;
+
+
+/*
+ * Function prototypes
+ */
+
+#ifdef XWIN_CLIPBOARD
+static void
+winClipboardShutdown (void);
+#endif
+
+#if defined(DDXOSVERRORF)
+void
+OsVendorVErrorF (const char *pszFormat, va_list va_args);
+#endif
+
+void
+winInitializeDefaultScreens (void);
+
+static Bool
+winCheckDisplayNumber (void);
+
+void
+winLogCommandLine (int argc, char *argv[]);
+
+void
+winLogVersionInfo (void);
+
+Bool
+winValidateArgs (void);
+
+#ifdef RELOCATE_PROJECTROOT
+const char *
+winGetBaseDir(void);
+#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]);
+
+#ifdef XWIN_CLIPBOARD
+static void
+winClipboardShutdown (void)
+{
+ /* Close down clipboard resources */
+ if (g_fClipboard && g_fClipboardLaunched && g_fClipboardStarted)
+ {
+ /* Synchronously destroy the clipboard window */
+ if (g_hwndClipboard != NULL)
+ {
+ SendMessage (g_hwndClipboard, WM_DESTROY, 0, 0);
+ /* NOTE: g_hwndClipboard is set to NULL in winclipboardthread.c */
+ }
+ else
+ return;
+
+ /* Wait for the clipboard thread to exit */
+ pthread_join (g_ptClipboardProc, NULL);
+
+ g_fClipboardLaunched = FALSE;
+ g_fClipboardStarted = FALSE;
+
+ winDebug ("winClipboardShutdown - Clipboard thread has exited.\n");
+ }
+}
+#endif
+
+
+#if defined(DDXBEFORERESET)
+/*
+ * Called right before KillAllClients when the server is going to reset,
+ * allows us to shutdown our seperate threads cleanly.
+ */
+
+void
+ddxBeforeReset (void)
+{
+ winDebug ("ddxBeforeReset - Hello\n");
+
+#ifdef XWIN_CLIPBOARD
+ winClipboardShutdown ();
+#endif
+}
+#endif
+
+
+/* See Porting Layer Definition - p. 57 */
+void
+ddxGiveUp (void)
+{
+ int i;
+
+#if CYGDEBUG
+ winDebug ("ddxGiveUp\n");
+#endif
+
+ /* Perform per-screen deinitialization */
+ for (i = 0; i < g_iNumScreens; ++i)
+ {
+ /* Delete the tray icon */
+ if (!g_ScreenInfo[i].fNoTrayIcon && g_ScreenInfo[i].pScreen)
+ winDeleteNotifyIcon (winGetScreenPriv (g_ScreenInfo[i].pScreen));
+ }
+
+#ifdef XWIN_MULTIWINDOW
+ /* Notify the worker threads we're exiting */
+ winDeinitMultiWindowWM ();
+#endif
+
+#ifdef HAS_DEVWINDOWS
+ /* 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;
+ }
+#endif
+
+ if (!g_fLogInited) {
+ LogInit (g_pszLogFile, NULL);
+ g_fLogInited = TRUE;
+ }
+ LogClose ();
+
+ /*
+ * 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 (*)(void))NoopDDA;
+ }
+
+ /* Free concatenated command line */
+ if (g_pszCommandLine)
+ {
+ free (g_pszCommandLine);
+ g_pszCommandLine = NULL;
+ }
+
+ /* Remove our keyboard hook if it is installed */
+ winRemoveKeyboardHookLL ();
+
+ /* Tell Windows that we want to end the app */
+ PostQuitMessage (0);
+}
+
+
+/* See Porting Layer Definition - p. 57 */
+void
+AbortDDX (void)
+{
+#if CYGDEBUG
+ winDebug ("AbortDDX\n");
+#endif
+ ddxGiveUp ();
+}
+
+#ifdef __CYGWIN__
+/* hasmntopt is currently not implemented for cygwin */
+static const char *winCheckMntOpt(const struct mntent *mnt, const char *opt)
+{
+ const char *s;
+ size_t len;
+ if (mnt == NULL)
+ return NULL;
+ if (opt == NULL)
+ return NULL;
+ if (mnt->mnt_opts == NULL)
+ return NULL;
+
+ len = strlen(opt);
+ s = strstr(mnt->mnt_opts, opt);
+ if (s == NULL)
+ return NULL;
+ if ((s == mnt->mnt_opts || *(s-1) == ',') && (s[len] == 0 || s[len] == ','))
+ return (char *)opt;
+ return NULL;
+}
+
+static void
+winCheckMount(void)
+{
+ FILE *mnt;
+ struct mntent *ent;
+
+ enum { none = 0, sys_root, user_root, sys_tmp, user_tmp }
+ level = none, curlevel;
+ BOOL binary = TRUE;
+
+ mnt = setmntent("/etc/mtab", "r");
+ if (mnt == NULL)
+ {
+ ErrorF("setmntent failed");
+ return;
+ }
+
+ while ((ent = getmntent(mnt)) != NULL)
+ {
+ BOOL system = (strcmp(ent->mnt_type, "system") == 0);
+ BOOL root = (strcmp(ent->mnt_dir, "/") == 0);
+ BOOL tmp = (strcmp(ent->mnt_dir, "/tmp") == 0);
+
+ if (system)
+ {
+ if (root)
+ curlevel = sys_root;
+ else if (tmp)
+ curlevel = sys_tmp;
+ else
+ continue;
+ }
+ else
+ {
+ if (root)
+ curlevel = user_root;
+ else if (tmp)
+ curlevel = user_tmp;
+ else
+ continue;
+ }
+
+ if (curlevel <= level)
+ continue;
+ level = curlevel;
+
+ if (winCheckMntOpt(ent, "binmode") == NULL)
+ binary = 0;
+ else
+ binary = 1;
+ }
+
+ if (endmntent(mnt) != 1)
+ {
+ ErrorF("endmntent failed");
+ return;
+ }
+
+ if (!binary)
+ winMsg(X_WARNING, "/tmp mounted int textmode\n");
+}
+#else
+static void
+winCheckMount(void)
+{
+}
+#endif
+
+#ifdef RELOCATE_PROJECTROOT
+const char *
+winGetBaseDir(void)
+{
+ static BOOL inited = FALSE;
+ static char buffer[MAX_PATH];
+ if (!inited)
+ {
+ char *fendptr;
+ HMODULE module = GetModuleHandle(NULL);
+ DWORD size = GetModuleFileName(module, buffer, sizeof(buffer));
+ if (sizeof(buffer) > 0)
+ buffer[sizeof(buffer)-1] = 0;
+
+ fendptr = buffer + size;
+ while (fendptr > buffer)
+ {
+ if (*fendptr == '\\' || *fendptr == '/')
+ {
+ *fendptr = 0;
+ break;
+ }
+ fendptr--;
+ }
+ inited = TRUE;
+ }
+ return buffer;
+}
+#endif
+
+static void
+winFixupPaths (void)
+{
+ BOOL changed_fontpath = FALSE;
+ MessageType font_from = X_DEFAULT;
+#ifdef RELOCATE_PROJECTROOT
+ const char *basedir = winGetBaseDir();
+ size_t basedirlen = strlen(basedir);
+#endif
+
+#ifdef READ_FONTDIRS
+ {
+ /* Open fontpath configuration file */
+ FILE *fontdirs = fopen(ETCX11DIR "/font-dirs", "rt");
+ if (fontdirs != NULL)
+ {
+ char buffer[256];
+ int needs_sep = TRUE;
+ int comment_block = FALSE;
+
+ /* get defautl fontpath */
+ char *fontpath = xstrdup(defaultFontPath);
+ size_t size = strlen(fontpath);
+
+ /* read all lines */
+ while (!feof(fontdirs))
+ {
+ size_t blen;
+ char *hashchar;
+ char *str;
+ int has_eol = FALSE;
+
+ /* read one line */
+ str = fgets(buffer, sizeof(buffer), fontdirs);
+ if (str == NULL) /* stop on error or eof */
+ break;
+
+ if (strchr(str, '\n') != NULL)
+ has_eol = TRUE;
+
+ /* check if block is continued comment */
+ if (comment_block)
+ {
+ /* ignore all input */
+ *str = 0;
+ blen = 0;
+ if (has_eol) /* check if line ended in this block */
+ comment_block = FALSE;
+ }
+ else
+ {
+ /* find comment character. ignore all trailing input */
+ hashchar = strchr(str, '#');
+ if (hashchar != NULL)
+ {
+ *hashchar = 0;
+ if (!has_eol) /* mark next block as continued comment */
+ comment_block = TRUE;
+ }
+ }
+
+ /* strip whitespaces from beginning */
+ while (*str == ' ' || *str == '\t')
+ str++;
+
+ /* get size, strip whitespaces from end */
+ blen = strlen(str);
+ while (blen > 0 && (str[blen-1] == ' ' ||
+ str[blen-1] == '\t' || str[blen-1] == '\n'))
+ {
+ str[--blen] = 0;
+ }
+
+ /* still something left to add? */
+ if (blen > 0)
+ {
+ size_t newsize = size + blen;
+ /* reserve one character more for ',' */
+ if (needs_sep)
+ newsize++;
+
+ /* allocate memory */
+ if (fontpath == NULL)
+ fontpath = malloc(newsize+1);
+ else
+ fontpath = realloc(fontpath, newsize+1);
+
+ /* add separator */
+ if (needs_sep)
+ {
+ fontpath[size] = ',';
+ size++;
+ needs_sep = FALSE;
+ }
+
+ /* mark next line as new entry */
+ if (has_eol)
+ needs_sep = TRUE;
+
+ /* add block */
+ strncpy(fontpath + size, str, blen);
+ fontpath[newsize] = 0;
+ size = newsize;
+ }
+ }
+
+ /* cleanup */
+ fclose(fontdirs);
+ defaultFontPath = xstrdup(fontpath);
+ free(fontpath);
+ changed_fontpath = TRUE;
+ font_from = X_CONFIG;
+ }
+ }
+#endif /* READ_FONTDIRS */
+#ifdef RELOCATE_PROJECTROOT
+ {
+ const char *libx11dir = PROJECTROOT "/lib/X11";
+ size_t libx11dir_len = strlen(libx11dir);
+ char *newfp = NULL;
+ size_t newfp_len = 0;
+ const char *endptr, *ptr, *oldptr = defaultFontPath;
+
+ endptr = oldptr + strlen(oldptr);
+ ptr = strchr(oldptr, ',');
+ if (ptr == NULL)
+ ptr = endptr;
+ while (ptr != NULL)
+ {
+ size_t oldfp_len = (ptr - oldptr);
+ size_t newsize = oldfp_len;
+ char *newpath = malloc(newsize + 1);
+ strncpy(newpath, oldptr, newsize);
+ newpath[newsize] = 0;
+
+
+ if (strncmp(libx11dir, newpath, libx11dir_len) == 0)
+ {
+ char *compose;
+ newsize = newsize - libx11dir_len + basedirlen;
+ compose = malloc(newsize + 1);
+ strcpy(compose, basedir);
+ strncat(compose, newpath + libx11dir_len, newsize - basedirlen);
+ compose[newsize] = 0;
+ free(newpath);
+ newpath = compose;
+ }
+
+ oldfp_len = newfp_len;
+ if (oldfp_len > 0)
+ newfp_len ++; /* space for separator */
+ newfp_len += newsize;
+
+ if (newfp == NULL)
+ newfp = malloc(newfp_len + 1);
+ else
+ newfp = realloc(newfp, newfp_len + 1);
+
+ if (oldfp_len > 0)
+ {
+ strcpy(newfp + oldfp_len, ",");
+ oldfp_len++;
+ }
+ strcpy(newfp + oldfp_len, newpath);
+
+ free(newpath);
+
+ if (*ptr == 0)
+ {
+ oldptr = ptr;
+ ptr = NULL;
+ } else
+ {
+ oldptr = ptr + 1;
+ ptr = strchr(oldptr, ',');
+ if (ptr == NULL)
+ ptr = endptr;
+ }
+ }
+
+ defaultFontPath = xstrdup(newfp);
+ free(newfp);
+ changed_fontpath = TRUE;
+ }
+#endif /* RELOCATE_PROJECTROOT */
+ if (changed_fontpath)
+ winMsg (font_from, "FontPath set to \"%s\"\n", defaultFontPath);
+
+#ifdef RELOCATE_PROJECTROOT
+ if (1) {
+ const char *libx11dir = "/usr/X11R6/lib/X11";
+ size_t libx11dir_len = strlen(libx11dir);
+
+ if (strncmp(libx11dir, rgbPath, libx11dir_len) == 0)
+ {
+ size_t newsize = strlen(rgbPath) - libx11dir_len + basedirlen;
+ char *compose = malloc(newsize + 1);
+ strcpy(compose, basedir);
+ strcat(compose, rgbPath + libx11dir_len);
+ compose[newsize] = 0;
+ rgbPath = xstrdup (compose);
+ free (compose);
+
+ winMsg (X_DEFAULT, "RgbPath set to \"%s\"\n", rgbPath);
+ }
+ }
+
+ if (getenv("XKEYSYMDB") == NULL)
+ {
+ char buffer[MAX_PATH];
+ snprintf(buffer, sizeof(buffer), "XKEYSYMDB=%s\\XKeysymDB",
+ basedir);
+ buffer[sizeof(buffer)-1] = 0;
+ putenv(buffer);
+ }
+ if (getenv("XERRORDB") == NULL)
+ {
+ char buffer[MAX_PATH];
+ snprintf(buffer, sizeof(buffer), "XERRORDB=%s\\XErrorDB",
+ basedir);
+ buffer[sizeof(buffer)-1] = 0;
+ putenv(buffer);
+ }
+ if (getenv("XLOCALEDIR") == NULL)
+ {
+ char buffer[MAX_PATH];
+ snprintf(buffer, sizeof(buffer), "XLOCALEDIR=%s\\locale",
+ basedir);
+ buffer[sizeof(buffer)-1] = 0;
+ putenv(buffer);
+ }
+ if (getenv("HOME") == NULL)
+ {
+ HMODULE shfolder;
+ SHGETFOLDERPATHPROC shgetfolderpath = NULL;
+ char buffer[MAX_PATH + 5];
+ strncpy(buffer, "HOME=", 5);
+
+ /* Try to load SHGetFolderPath from shfolder.dll and shell32.dll */
+
+ shfolder = LoadLibrary("shfolder.dll");
+ /* fallback to shell32.dll */
+ if (shfolder == NULL)
+ shfolder = LoadLibrary("shell32.dll");
+
+ /* resolve SHGetFolderPath */
+ if (shfolder != NULL)
+ shgetfolderpath = (SHGETFOLDERPATHPROC)GetProcAddress(shfolder, "SHGetFolderPathA");
+
+ /* query appdata directory */
+ if (shgetfolderpath &&
+ shgetfolderpath(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, NULL, 0,
+ buffer + 5) == 0)
+ {
+ putenv(buffer);
+ } else
+ {
+ winMsg (X_ERROR, "Can not determine HOME directory\n");
+ }
+ if (shfolder != NULL)
+ FreeLibrary(shfolder);
+ }
+ if (!g_fLogFileChanged) {
+ static char buffer[MAX_PATH];
+ DWORD size = GetTempPath(sizeof(buffer), buffer);
+ if (size && size < sizeof(buffer))
+ {
+ snprintf(buffer + size, sizeof(buffer) - size,
+ "XWin.%s.log", display);
+ buffer[sizeof(buffer)-1] = 0;
+ g_pszLogFile = buffer;
+ winMsg (X_DEFAULT, "Logfile set to \"%s\"\n", g_pszLogFile);
+ }
+ }
+#ifdef XKB
+ {
+ static char xkbbasedir[MAX_PATH];
+
+ snprintf(xkbbasedir, sizeof(xkbbasedir), "%s\\xkb", basedir);
+ if (sizeof(xkbbasedir) > 0)
+ xkbbasedir[sizeof(xkbbasedir)-1] = 0;
+ XkbBaseDirectory = xkbbasedir;
+ }
+#endif /* XKB */
+#endif /* RELOCATE_PROJECTROOT */
+}
+
+void
+OsVendorInit (void)
+{
+ /* Re-initialize global variables on server reset */
+ winInitializeGlobals ();
+
+ LogInit (NULL, NULL);
+ LogSetParameter (XLOG_VERBOSITY, g_iLogVerbose);
+
+ winFixupPaths();
+
+#ifdef DDXOSVERRORF
+ if (!OsVendorVErrorFProc)
+ OsVendorVErrorFProc = OsVendorVErrorF;
+#endif
+
+ if (!g_fLogInited) {
+ /* keep this order. If LogInit fails it calls Abort which then calls
+ * ddxGiveUp where LogInit is called again and creates an infinite
+ * recursion. If we set g_fLogInited to TRUE before the init we
+ * avoid the second call
+ */
+ g_fLogInited = TRUE;
+ LogInit (g_pszLogFile, NULL);
+ }
+ LogSetParameter (XLOG_FLUSH, 1);
+ LogSetParameter (XLOG_VERBOSITY, g_iLogVerbose);
+ LogSetParameter (XLOG_FILE_VERBOSITY, 1);
+
+ /* Log the version information */
+ if (serverGeneration == 1)
+ winLogVersionInfo ();
+
+ winCheckMount();
+
+ /* Add a default screen if no screens were specified */
+ if (g_iNumScreens == 0)
+ {
+ winDebug ("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;
+ }
+}
+
+
+static void
+winUseMsg (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"
+#ifdef XWIN_NATIVEGDI
+ "\t\t16 - Native GDI - experimental\n"
+#endif
+ );
+
+ 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 [x y] | [[WxH[+X+Y]][@m]] ]\n"
+ "\tEnable screen scr_num and optionally specify a width and\n"
+ "\theight and initial position for that screen. Additionally\n"
+ "\ta monitor number can be specified to start the server on,\n"
+ "\tat which point, all coordinates become relative to that\n"
+ "\tmonitor (Not for Windows NT4 and 95). Examples:\n"
+ "\t -screen 0 800x600+100+100@2 ; 2nd monitor offset 100,100 size 800x600\n"
+ "\t -screen 0 1024x768@3 ; 3rd monitor size 1024x768\n"
+ "\t -screen 0 @1 ; on 1st monitor using its full resolution (the default)\n");
+
+ ErrorF ("-lesspointer\n"
+ "\tHide the windows mouse pointer when it is over an inactive\n"
+ "\t" PROJECT_NAME " 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");
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+ ErrorF ("-mwextwm\n"
+ "\tRun the server in multi-window external window manager mode.\n");
+
+ ErrorF ("-internalwm\n"
+ "\tRun the internal window manager.\n");
+#endif
+
+ ErrorF ("-rootless\n"
+ "\tRun the server in rootless mode.\n");
+
+#ifdef XWIN_MULTIWINDOW
+ ErrorF ("-multiwindow\n"
+ "\tRun the server in multi-window mode.\n");
+#endif
+
+ ErrorF ("-multiplemonitors\n"
+ "\tEXPERIMENTAL: Use the entire virtual screen if multiple\n"
+ "\tmonitors are present.\n");
+
+#ifdef XWIN_CLIPBOARD
+ ErrorF ("-clipboard\n"
+ "\tRun the clipboard integration module.\n"
+ "\tDo not use at the same time as 'xwinclip'.\n");
+
+ ErrorF ("-nounicodeclipboard\n"
+ "\tDo not use Unicode clipboard even if NT-based platform.\n");
+#endif
+
+ 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 ("-[no]trayicon\n"
+ "\tDo not create a tray icon. Default is to create one\n"
+ "\ticon per screen. You can globally disable tray icons with\n"
+ "\t-notrayicon, then enable it for specific screens with\n"
+ "\t-trayicon for those screens.\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");
+
+#ifdef XWIN_EMULATEPSEUDO
+ 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");
+#endif
+
+ ErrorF ("-[no]unixkill\n"
+ "\tCtrl+Alt+Backspace exits the X Server.\n");
+
+ ErrorF ("-[no]winkill\n"
+ "\tAlt+F4 exits the X Server.\n");
+
+#ifdef XWIN_XF86CONFIG
+ ErrorF ("-config\n"
+ "\tSpecify a configuration file.\n");
+
+ ErrorF ("-keyboard\n"
+ "\tSpecify a keyboard device from the configuration file.\n");
+#endif
+
+#ifdef XKB
+ ErrorF ("-xkbrules XKBRules\n"
+ "\tEquivalent to XKBRules in XF86Config files.\n");
+
+ ErrorF ("-xkbmodel XKBModel\n"
+ "\tEquivalent to XKBModel in XF86Config files.\n");
+
+ ErrorF ("-xkblayout XKBLayout\n"
+ "\tEquivalent to XKBLayout in XF86Config files.\n"
+ "\tFor example: -xkblayout de\n");
+
+ ErrorF ("-xkbvariant XKBVariant\n"
+ "\tEquivalent to XKBVariant in XF86Config files.\n"
+ "\tFor example: -xkbvariant nodeadkeys\n");
+
+ ErrorF ("-xkboptions XKBOptions\n"
+ "\tEquivalent to XKBOptions in XF86Config files.\n");
+#endif
+
+ ErrorF ("-logfile filename\n"
+ "\tWrite logmessages to <filename> instead of /tmp/Xwin.log.\n");
+
+ ErrorF ("-logverbose verbosity\n"
+ "\tSet the verbosity of logmessages. [NOTE: Only a few messages\n"
+ "\trespect the settings yet]\n"
+ "\t\t0 - only print fatal error.\n"
+ "\t\t1 - print additional configuration information.\n"
+ "\t\t2 - print additional runtime information [default].\n"
+ "\t\t3 - print debugging and tracing information.\n");
+
+ ErrorF ("-[no]keyhook\n"
+ "\tGrab special windows key combinations like Alt-Tab or the Menu "
+ "key.\n These keys are discarded by default.\n");
+
+ ErrorF ("-swcursor\n"
+ "\tDisable the usage of the windows cursor and use the X11 software "
+ "cursor instead\n");
+}
+
+/* See Porting Layer Definition - p. 57 */
+void
+ddxUseMsg(void)
+{
+ /* Set a flag so that FatalError won't give duplicate warning message */
+ g_fSilentFatalError = TRUE;
+
+ winUseMsg();
+
+ /* Log file will not be opened for UseMsg unless we open it now */
+ if (!g_fLogInited) {
+ LogInit (g_pszLogFile, NULL);
+ g_fLogInited = TRUE;
+ }
+ LogClose ();
+
+ /* Notify user where UseMsg text can be found.*/
+ if (!g_fNoHelpMessageBox)
+ winMessageBoxF ("The " PROJECT_NAME " help text has been printed to "
+ "/tmp/XWin.log.\n"
+ "Please open /tmp/XWin.log to read the help text.\n",
+ MB_ICONINFORMATION);
+}
+
+/* ddxInitGlobals - called by |InitGlobals| from os/util.c */
+void ddxInitGlobals(void)
+{
+}
+
+/* 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;
+
+ /* Log the command line */
+ winLogCommandLine (argc, argv);
+
+#if CYGDEBUG
+ winDebug ("InitOutput\n");
+#endif
+
+ /* Validate command-line arguments */
+ if (serverGeneration == 1 && !winValidateArgs ())
+ {
+ FatalError ("InitOutput - Invalid command-line arguments found. "
+ "Exiting.\n");
+ }
+
+ /* Check for duplicate invocation on same display number.*/
+ if (serverGeneration == 1 && !winCheckDisplayNumber ())
+ {
+ if (g_fSilentDupError)
+ g_fSilentFatalError = TRUE;
+ FatalError ("InitOutput - Duplicate invocation on display "
+ "number: %s. Exiting.\n", display);
+ }
+
+#ifdef XWIN_XF86CONFIG
+ /* Try to read the xorg.conf-style configuration file */
+ if (!winReadConfigfile ())
+ winErrorFVerb (1, "InitOutput - Error reading config file\n");
+#else
+ winMsg(X_INFO, "XF86Config is not supported\n");
+ winMsg(X_INFO, "See http://x.cygwin.com/docs/faq/cygwin-x-faq.html "
+ "for more information\n");
+ winConfigFiles ();
+#endif
+
+ /* Load preferences from XWinrc file */
+ LoadPreferences();
+
+ /* 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)
+ {
+ winErrorFVerb (1, "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 (*)(void))NoopDDA;
+ }
+
+ /* 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 defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
+
+#if defined(XCSECURITY)
+ /* Generate a cookie used by internal clients for authorization */
+ if (g_fXdmcpEnabled)
+ winGenerateAuthorization ();
+#endif
+
+ /* Perform some one time initialization */
+ if (1 == serverGeneration)
+ {
+ /*
+ * setlocale applies to all threads in the current process.
+ * Apply locale specified in LANG environment variable.
+ */
+ setlocale (LC_ALL, "");
+ }
+#endif
+
+#if CYGDEBUG || YES
+ winDebug ("InitOutput - Returning.\n");
+#endif
+}
+
+
+/*
+ * winCheckDisplayNumber - Check if another instance of Cygwin/X is
+ * already running on the same display number. If no one exists,
+ * make a mutex to prevent new instances from running on the same display.
+ *
+ * return FALSE if the display number is already used.
+ */
+
+static Bool
+winCheckDisplayNumber ()
+{
+ int nDisp;
+ HANDLE mutex;
+ char name[MAX_PATH];
+ char * pszPrefix = '\0';
+ OSVERSIONINFO osvi = {0};
+
+ /* Check display range */
+ nDisp = atoi (display);
+ if (nDisp < 0 || nDisp > 65535)
+ {
+ ErrorF ("winCheckDisplayNumber - Bad display number: %d\n", nDisp);
+ return FALSE;
+ }
+
+ /* Set first character of mutex name to null */
+ name[0] = '\0';
+
+ /* Get operating system version information */
+ osvi.dwOSVersionInfoSize = sizeof (osvi);
+ GetVersionEx (&osvi);
+
+ /* Want a mutex shared among all terminals on NT > 4.0 */
+ if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT
+ && osvi.dwMajorVersion >= 5)
+ {
+ pszPrefix = "Global\\";
+ }
+
+ /* Setup Cygwin/X specific part of name */
+ snprintf (name, sizeof(name), "%sCYGWINX_DISPLAY:%d", pszPrefix, nDisp);
+
+ /* Windows automatically releases the mutex when this process exits */
+ mutex = CreateMutex (NULL, FALSE, name);
+ if (!mutex)
+ {
+ 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),
+ (LPTSTR) &lpMsgBuf,
+ 0, NULL);
+ ErrorF ("winCheckDisplayNumber - CreateMutex failed: %s\n",
+ (LPSTR)lpMsgBuf);
+ LocalFree (lpMsgBuf);
+
+ return FALSE;
+ }
+ if (GetLastError () == ERROR_ALREADY_EXISTS)
+ {
+ ErrorF ("winCheckDisplayNumber - "
+ PROJECT_NAME " is already running on display %d\n",
+ nDisp);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#ifdef DPMSExtension
+Bool DPMSSupported(void)
+{
+ return FALSE;
+}
+
+void DPMSSet(int level)
+{
+ return;
+}
+
+int DPMSGet(int *plevel)
+{
+ return 0;
+}
+#endif