diff options
Diffstat (limited to 'xorg-server/hw/xwin/InitOutput.c')
-rw-r--r-- | xorg-server/hw/xwin/InitOutput.c | 2240 |
1 files changed, 1120 insertions, 1120 deletions
diff --git a/xorg-server/hw/xwin/InitOutput.c b/xorg-server/hw/xwin/InitOutput.c index f79132c42..3c2f22d73 100644 --- a/xorg-server/hw/xwin/InitOutput.c +++ b/xorg-server/hw/xwin/InitOutput.c @@ -1,1120 +1,1120 @@ -
-/*
-
-Copyright 1993, 1998 The Open Group
-Copyright (C) Colin Harrison 2005-2008
-
-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 DPMSExtension
-#include "dpmsproc.h"
-#endif
-#include <locale.h>
-#ifdef __CYGWIN__
-#include <mntent.h>
-#endif
-#if defined(WIN32)
-#include "xkbsrv.h"
-#endif
-#ifdef RELOCATE_PROJECTROOT
-#undef Status
-#include <shlobj.h>
-typedef HRESULT (__stdcall * SHGETFOLDERPATHPROC)(
- HWND hwndOwner,
- int nFolder,
- HANDLE hToken,
- DWORD dwFlags,
- LPSTR pszPath
-);
-#endif
-
-/*
- * References to external symbols
- */
-#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
-
-
-/*
- module handle for dynamically loaded comctl32 library
-*/
-static HMODULE g_hmodCommonControls = NULL;
-
-/*
- * Function prototypes
- */
-
-#ifdef XWIN_CLIPBOARD
-static void
-winClipboardShutdown (void);
-#endif
-
-#if defined(DDXOSVERRORF)
-void
-OsVendorVErrorF (const char *pszFormat, va_list va_args);
-#endif
-
-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 },
- { 32, 32, BITMAP_SCANLINE_PAD }
-};
-
-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)
- {
- g_fClipboardStarted=FALSE; /* This is to avoid dead-locls caused by the clipboard thread still doing some stuff */
- 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);
-
- 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 (enum ExitCode error)
-{
- int i;
-
- winDebug ("ddxGiveUp\n");
-
- /* 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) {
- g_pszLogFile = LogInit (g_pszLogFile, NULL);
- g_fLogInited = TRUE;
- }
- LogClose (error);
-
- /*
- * At this point we aren't creating any new screens, so
- * we are guaranteed to not need the DirectDraw functions.
- */
- winReleaseDDProcAddresses();
-
- /* Unload our TrackMouseEvent function pointer */
- if (g_hmodCommonControls != NULL)
- {
- FreeLibrary (g_hmodCommonControls);
- g_hmodCommonControls = NULL;
- g_fpTrackMouseEvent = (FARPROC) (void (*)(void))NoopDDA;
- }
-
- /* Free concatenated command line */
- 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 (enum ExitCode error)
-{
- winDebug ("AbortDDX\n");
- ddxGiveUp (error);
-}
-
-#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 = (winCheckMntOpt(ent, "user") != NULL);
- 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, "binary") == NULL) &&
- (winCheckMntOpt(ent, "binmode") == NULL))
- binary = FALSE;
- else
- binary = TRUE;
- }
-
- if (endmntent(mnt) != 1)
- {
- ErrorF("endmntent failed");
- return;
- }
-
-#ifdef WINDBG
- if (!binary)
- winDebug("/tmp mounted in textmode\n");
-#endif
-}
-#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 */
-#if defined WIN32 && defined __MINGW32__
- static Bool once = False;
- char buffer[MAX_PATH];
- snprintf(buffer, sizeof(buffer), "%s\\font-dirs", basedir);
- buffer[sizeof(buffer)-1] = 0;
- FILE *fontdirs = fopen(buffer, "rt");
- if (once) fontdirs = NULL;
- else once = True;
-#else
- FILE *fontdirs = fopen(ETCX11DIR "/font-dirs", "rt");
-#endif
- if (fontdirs != NULL)
- {
- char buffer[256];
- int needs_sep = TRUE;
- int comment_block = FALSE;
-
- /* get default fontpath */
- char *fontpath = strdup(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 = strdup(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 = strdup(newfp);
- free(newfp);
- changed_fontpath = TRUE;
- }
-#endif /* RELOCATE_PROJECTROOT */
- if (changed_fontpath)
- winDebug ("FontPath set to \"%s\"\n", defaultFontPath);
-
-#ifdef RELOCATE_PROJECTROOT
- 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("XHOSTPREFIX") == NULL)
- {
- char buffer[MAX_PATH];
- snprintf(buffer, sizeof(buffer), "XHOSTPREFIX=%s\\X",
- 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
- {
- ErrorF ("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,
- "VCXSrv.%s.log", display);
- buffer[sizeof(buffer)-1] = 0;
- g_pszLogFile = buffer;
- GetLongPathName(buffer, buffer, MAX_PATH);
- winDebug ("Logfile set to \"%s\"\n", g_pszLogFile);
- }
- }
- {
- static char xkbbasedir[MAX_PATH];
-
- snprintf(xkbbasedir, sizeof(xkbbasedir), "%s\\xkbdata", basedir);
- if (sizeof(xkbbasedir) > 0)
- xkbbasedir[sizeof(xkbbasedir)-1] = 0;
- XkbBaseDirectory = xkbbasedir;
- XkbBinDirectory = basedir;
- }
-#endif /* RELOCATE_PROJECTROOT */
-}
-
-void
-OsVendorInit (void)
-{
- /* Re-initialize global variables on server reset */
- winInitializeGlobals ();
-
- 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;
- g_pszLogFile = LogInit (g_pszLogFile, NULL);
- }
- LogSetParameter (XLOG_FLUSH, 1);
- LogSetParameter (XLOG_VERBOSITY, g_iLogVerbose);
- LogSetParameter (XLOG_FILE_VERBOSITY, g_iLogVerbose);
-
- /* 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 default screen 0\n");
-
- /*
- * We need to initialize the default screen 0 if no -screen
- * arguments were processed.
- *
- * Add a screen 0 using the defaults set by winInitializeDefaultScreens()
- * and any additional default screen parameters given
- */
- winInitializeScreens(1);
-
- /* We have to flag this as an explicit screen, even though it isn't */
- g_ScreenInfo[0].fExplicitScreen = TRUE;
- }
-}
-
-
-static void
-winUseMsg (void)
-{
- ErrorF("\n");
- ErrorF("\n");
- ErrorF(EXECUTABLE_NAME " Device Dependent Usage:\n");
- ErrorF("\n");
-
-#ifdef XWIN_CLIPBOARD
- ErrorF ("-[no]clipboard\n"
- "\tEnable [disable] the clipboard integration. Default is enabled.\n");
- ErrorF ("-[no]clipboardprimary\n"
- "\t[Do not] map the PRIMARY selection to the windows clipboard.\n"
- "\tThe CLIPBOARD selection is always mapped if -clipboard is enabled.\n"
- "\tDefault is mapped.\n");
-#endif
-
- 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.\n");
-
-#ifdef XWIN_XF86CONFIG
- ErrorF ("-config\n"
- "\tSpecify a configuration file.\n");
-
- ErrorF ("-configdir\n"
- "\tSpecify a configuration directory.\n");
-#endif
-
- 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");
-
-#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 ("-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_PRIMARYFB
- "\t\t8 - Primary DirectDraw - obsolete\n"
-#endif
-#ifdef XWIN_NATIVEGDI
- "\t\t16 - Native GDI - experimental\n"
-#endif
- );
-
- ErrorF ("-fullscreen\n"
- "\tRun the server in fullscreen mode.\n");
-
- ErrorF ("-ignoreinput\n"
- "\tIgnore keyboard and mouse input.\n");
-
-#ifdef XWIN_MULTIWINDOWINTWM
- ErrorF ("-internalwm\n"
- "\tRun the internal window manager.\n");
-#endif
-
-#ifdef XWIN_XF86CONFIG
- ErrorF ("-keyboard\n"
- "\tSpecify a keyboard device from the configuration file.\n");
-#endif
-
- ErrorF ("-[no]keyhook\n"
- "\tGrab special Windows keypresses like Alt-Tab or the Menu "
- "key.\n");
-
- ErrorF ("-lesspointer\n"
- "\tHide the windows mouse pointer when it is over any\n"
- "\t" EXECUTABLE_NAME " window. This prevents ghost cursors appearing when\n"
- "\tthe Windows cursor is drawn on top of the X cursor\n");
-
- ErrorF ("-logfile filename\n"
- "\tWrite log messages to <filename>.\n");
-
- ErrorF ("-logverbose verbosity\n"
- "\tSet the verbosity of log messages. [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]multimonitors or -[no]multiplemonitors\n"
- "\tUse the entire virtual screen if multiple\n"
- "\tmonitors are present.\n");
-
-#ifdef XWIN_MULTIWINDOW
- ErrorF ("-multiwindow\n"
- "\tRun the server in multi-window mode.\n");
-#endif
-
-#ifdef XWIN_MULTIWINDOWEXTWM
- ErrorF ("-mwextwm\n"
- "\tRun the server in multi-window external window manager mode.\n");
-#endif
-
- ErrorF ("-nodecoration\n"
- "\tDo not draw a window border, title bar, etc. Windowed\n"
- "\tmode only.\n");
-
-#ifdef XWIN_CLIPBOARD
- ErrorF ("-nounicodeclipboard\n"
- "\tDo not use Unicode clipboard even if on a NT-based platform.\n");
-#endif
-
- ErrorF ("-refresh rate_in_Hz\n"
- "\tSpecify an optional refresh rate to use in fullscreen mode\n"
- "\twith a DirectDraw engine.\n");
-
- ErrorF ("-resize=none|scrollbars|randr"
- "\tIn windowed mode, [don't] allow resizing of the window. 'scrollbars'\n"
- "\tmode gives the window scrollbars as needed, 'randr' mode uses the RANR\n"
- "\textension to resize the X screen.\n");
-
- ErrorF ("-rootless\n"
- "\tRun the server in rootless mode.\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 ("-silent-dup-error\n"
- "\tIf another instance of " EXECUTABLE_NAME " with the same display number is running\n"
- "\texit silently and don't display any error message.\n");
-
- ErrorF ("-swcursor\n"
- "\tDisable the usage of the Windows cursor and use the X11 software\n"
- "\tcursor instead.\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 ("-[no]unixkill\n"
- "\tCtrl+Alt+Backspace exits the X Server.\n");
-
- ErrorF ("-[no]wgl\n"
- "\tEnable the GLX extension to use the native Windows WGL interface for accelerated OpenGL\n");
-
- ErrorF ("-[no]winkill\n"
- "\tAlt+F4 exits the X Server.\n");
-
- ErrorF ("-xkblayout XKBLayout\n"
- "\tEquivalent to XKBLayout in XF86Config files.\n"
- "\tFor example: -xkblayout de\n");
-
- ErrorF ("-xkbmodel XKBModel\n"
- "\tEquivalent to XKBModel in XF86Config files.\n");
-
- ErrorF ("-xkboptions XKBOptions\n"
- "\tEquivalent to XKBOptions in XF86Config files.\n");
-
- ErrorF ("-xkbrules XKBRules\n"
- "\tEquivalent to XKBRules in XF86Config files.\n");
-
- ErrorF ("-xkbvariant XKBVariant\n"
- "\tEquivalent to XKBVariant in XF86Config files.\n"
- "\tFor example: -xkbvariant nodeadkeys\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) {
- g_pszLogFile = LogInit (g_pszLogFile, NULL);
- g_fLogInited = TRUE;
- }
- LogClose (EXIT_NO_ERROR);
-
- /* Notify user where UseMsg text can be found.*/
- if (!g_fNoHelpMessageBox)
- winMessageBoxF ("The " PROJECT_NAME " help text has been printed to "
- "%s.\n"
- "Please open %s to read the help text.\n",
- MB_ICONINFORMATION, g_pszLogFile, g_pszLogFile);
-}
-
-/* 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);
-
- winDebug ("InitOutput\n");
-
- /* 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 ())
- ErrorF ("InitOutput - Error reading config file\n");
-#else
- 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)
- {
- 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 (*)(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)
-
- /* Generate a cookie used by internal clients for authorization */
- if (g_fXdmcpEnabled || g_fAuthEnabled)
- winGenerateAuthorization ();
-
- /* Perform some one time initialization */
- if (1 == serverGeneration)
- {
- /*
- * setlocale applies to all threads in the current process.
- * Apply locale specified in LANG environment variable.
- */
- if (!setlocale (LC_ALL, ""))
- {
- ErrorF ("setlocale failed.\n");
- }
-
- /* See if X supports the current locale */
- if (XSupportsLocale () == FALSE)
- {
- ErrorF ("Warning: Locale not supported by X, falling back to 'C' locale.\n");
- setlocale(LC_ALL, "C");
- }
-
- }
-#endif
-
- winDebug ("InitOutput - Returning.\n");
-}
-
-
-/*
- * 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 (void)
-{
- int nDisp;
- HANDLE mutex;
- char name[MAX_PATH];
- char * pszPrefix = '\0';
- OSVERSIONINFO osvi = {0};
-
- /* Check display range */
- nDisp = atoi (display);
- if (nDisp < 0 || nDisp > 59535)
- {
- 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 - "
- "VCXsrv, Xming or Cygwin/X is already running on display %d\n",
- nDisp);
- return FALSE;
- }
-
- return TRUE;
-}
+ +/* + +Copyright 1993, 1998 The Open Group +Copyright (C) Colin Harrison 2005-2008 + +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 DPMSExtension +#include "dpmsproc.h" +#endif +#include <locale.h> +#ifdef __CYGWIN__ +#include <mntent.h> +#endif +#if defined(WIN32) +#include "xkbsrv.h" +#endif +#ifdef RELOCATE_PROJECTROOT +#undef Status +#include <shlobj.h> +typedef HRESULT (__stdcall * SHGETFOLDERPATHPROC)( + HWND hwndOwner, + int nFolder, + HANDLE hToken, + DWORD dwFlags, + LPSTR pszPath +); +#endif + +/* + * References to external symbols + */ +#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 + + +/* + module handle for dynamically loaded comctl32 library +*/ +static HMODULE g_hmodCommonControls = NULL; + +/* + * Function prototypes + */ + +#ifdef XWIN_CLIPBOARD +static void +winClipboardShutdown (void); +#endif + +#if defined(DDXOSVERRORF) +void +OsVendorVErrorF (const char *pszFormat, va_list va_args); +#endif + +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 }, + { 32, 32, BITMAP_SCANLINE_PAD } +}; + +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) + { + g_fClipboardStarted=FALSE; /* This is to avoid dead-locls caused by the clipboard thread still doing some stuff */ + 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); + + 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 (enum ExitCode error) +{ + int i; + + winDebug ("ddxGiveUp\n"); + + /* 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) { + g_pszLogFile = LogInit (g_pszLogFile, NULL); + g_fLogInited = TRUE; + } + LogClose (error); + + /* + * At this point we aren't creating any new screens, so + * we are guaranteed to not need the DirectDraw functions. + */ + winReleaseDDProcAddresses(); + + /* Unload our TrackMouseEvent function pointer */ + if (g_hmodCommonControls != NULL) + { + FreeLibrary (g_hmodCommonControls); + g_hmodCommonControls = NULL; + g_fpTrackMouseEvent = (FARPROC) (void (*)(void))NoopDDA; + } + + /* Free concatenated command line */ + 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 (enum ExitCode error) +{ + winDebug ("AbortDDX\n"); + ddxGiveUp (error); +} + +#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 = (winCheckMntOpt(ent, "user") != NULL); + 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, "binary") == NULL) && + (winCheckMntOpt(ent, "binmode") == NULL)) + binary = FALSE; + else + binary = TRUE; + } + + if (endmntent(mnt) != 1) + { + ErrorF("endmntent failed"); + return; + } + +#ifdef WINDBG + if (!binary) + winDebug("/tmp mounted in textmode\n"); +#endif +} +#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 */ +#if defined WIN32 && defined __MINGW32__ + static Bool once = False; + char buffer[MAX_PATH]; + snprintf(buffer, sizeof(buffer), "%s\\font-dirs", basedir); + buffer[sizeof(buffer)-1] = 0; + FILE *fontdirs = fopen(buffer, "rt"); + if (once) fontdirs = NULL; + else once = True; +#else + FILE *fontdirs = fopen(ETCX11DIR "/font-dirs", "rt"); +#endif + if (fontdirs != NULL) + { + char buffer[256]; + int needs_sep = TRUE; + int comment_block = FALSE; + + /* get default fontpath */ + char *fontpath = strdup(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 = strdup(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 = strdup(newfp); + free(newfp); + changed_fontpath = TRUE; + } +#endif /* RELOCATE_PROJECTROOT */ + if (changed_fontpath) + winDebug ("FontPath set to \"%s\"\n", defaultFontPath); + +#ifdef RELOCATE_PROJECTROOT + 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("XHOSTPREFIX") == NULL) + { + char buffer[MAX_PATH]; + snprintf(buffer, sizeof(buffer), "XHOSTPREFIX=%s\\X", + 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 + { + ErrorF ("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, + "VCXSrv.%s.log", display); + buffer[sizeof(buffer)-1] = 0; + g_pszLogFile = buffer; + GetLongPathName(buffer, buffer, MAX_PATH); + winDebug ("Logfile set to \"%s\"\n", g_pszLogFile); + } + } + { + static char xkbbasedir[MAX_PATH]; + + snprintf(xkbbasedir, sizeof(xkbbasedir), "%s\\xkbdata", basedir); + if (sizeof(xkbbasedir) > 0) + xkbbasedir[sizeof(xkbbasedir)-1] = 0; + XkbBaseDirectory = xkbbasedir; + XkbBinDirectory = basedir; + } +#endif /* RELOCATE_PROJECTROOT */ +} + +void +OsVendorInit (void) +{ + /* Re-initialize global variables on server reset */ + winInitializeGlobals (); + + 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; + g_pszLogFile = LogInit (g_pszLogFile, NULL); + } + LogSetParameter (XLOG_FLUSH, 1); + LogSetParameter (XLOG_VERBOSITY, g_iLogVerbose); + LogSetParameter (XLOG_FILE_VERBOSITY, g_iLogVerbose); + + /* 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 default screen 0\n"); + + /* + * We need to initialize the default screen 0 if no -screen + * arguments were processed. + * + * Add a screen 0 using the defaults set by winInitializeDefaultScreens() + * and any additional default screen parameters given + */ + winInitializeScreens(1); + + /* We have to flag this as an explicit screen, even though it isn't */ + g_ScreenInfo[0].fExplicitScreen = TRUE; + } +} + + +static void +winUseMsg (void) +{ + ErrorF("\n"); + ErrorF("\n"); + ErrorF(EXECUTABLE_NAME " Device Dependent Usage:\n"); + ErrorF("\n"); + +#ifdef XWIN_CLIPBOARD + ErrorF ("-[no]clipboard\n" + "\tEnable [disable] the clipboard integration. Default is enabled.\n"); + ErrorF ("-[no]clipboardprimary\n" + "\t[Do not] map the PRIMARY selection to the windows clipboard.\n" + "\tThe CLIPBOARD selection is always mapped if -clipboard is enabled.\n" + "\tDefault is mapped.\n"); +#endif + + 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.\n"); + +#ifdef XWIN_XF86CONFIG + ErrorF ("-config\n" + "\tSpecify a configuration file.\n"); + + ErrorF ("-configdir\n" + "\tSpecify a configuration directory.\n"); +#endif + + 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"); + +#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 ("-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_PRIMARYFB + "\t\t8 - Primary DirectDraw - obsolete\n" +#endif +#ifdef XWIN_NATIVEGDI + "\t\t16 - Native GDI - experimental\n" +#endif + ); + + ErrorF ("-fullscreen\n" + "\tRun the server in fullscreen mode.\n"); + + ErrorF ("-ignoreinput\n" + "\tIgnore keyboard and mouse input.\n"); + +#ifdef XWIN_MULTIWINDOWINTWM + ErrorF ("-internalwm\n" + "\tRun the internal window manager.\n"); +#endif + +#ifdef XWIN_XF86CONFIG + ErrorF ("-keyboard\n" + "\tSpecify a keyboard device from the configuration file.\n"); +#endif + + ErrorF ("-[no]keyhook\n" + "\tGrab special Windows keypresses like Alt-Tab or the Menu " + "key.\n"); + + ErrorF ("-lesspointer\n" + "\tHide the windows mouse pointer when it is over any\n" + "\t" EXECUTABLE_NAME " window. This prevents ghost cursors appearing when\n" + "\tthe Windows cursor is drawn on top of the X cursor\n"); + + ErrorF ("-logfile filename\n" + "\tWrite log messages to <filename>.\n"); + + ErrorF ("-logverbose verbosity\n" + "\tSet the verbosity of log messages. [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]multimonitors or -[no]multiplemonitors\n" + "\tUse the entire virtual screen if multiple\n" + "\tmonitors are present.\n"); + +#ifdef XWIN_MULTIWINDOW + ErrorF ("-multiwindow\n" + "\tRun the server in multi-window mode.\n"); +#endif + +#ifdef XWIN_MULTIWINDOWEXTWM + ErrorF ("-mwextwm\n" + "\tRun the server in multi-window external window manager mode.\n"); +#endif + + ErrorF ("-nodecoration\n" + "\tDo not draw a window border, title bar, etc. Windowed\n" + "\tmode only.\n"); + +#ifdef XWIN_CLIPBOARD + ErrorF ("-nounicodeclipboard\n" + "\tDo not use Unicode clipboard even if on a NT-based platform.\n"); +#endif + + ErrorF ("-refresh rate_in_Hz\n" + "\tSpecify an optional refresh rate to use in fullscreen mode\n" + "\twith a DirectDraw engine.\n"); + + ErrorF ("-resize=none|scrollbars|randr" + "\tIn windowed mode, [don't] allow resizing of the window. 'scrollbars'\n" + "\tmode gives the window scrollbars as needed, 'randr' mode uses the RANR\n" + "\textension to resize the X screen.\n"); + + ErrorF ("-rootless\n" + "\tRun the server in rootless mode.\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 ("-silent-dup-error\n" + "\tIf another instance of " EXECUTABLE_NAME " with the same display number is running\n" + "\texit silently and don't display any error message.\n"); + + ErrorF ("-swcursor\n" + "\tDisable the usage of the Windows cursor and use the X11 software\n" + "\tcursor instead.\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 ("-[no]unixkill\n" + "\tCtrl+Alt+Backspace exits the X Server.\n"); + + ErrorF ("-[no]wgl\n" + "\tEnable the GLX extension to use the native Windows WGL interface for accelerated OpenGL\n"); + + ErrorF ("-[no]winkill\n" + "\tAlt+F4 exits the X Server.\n"); + + ErrorF ("-xkblayout XKBLayout\n" + "\tEquivalent to XKBLayout in XF86Config files.\n" + "\tFor example: -xkblayout de\n"); + + ErrorF ("-xkbmodel XKBModel\n" + "\tEquivalent to XKBModel in XF86Config files.\n"); + + ErrorF ("-xkboptions XKBOptions\n" + "\tEquivalent to XKBOptions in XF86Config files.\n"); + + ErrorF ("-xkbrules XKBRules\n" + "\tEquivalent to XKBRules in XF86Config files.\n"); + + ErrorF ("-xkbvariant XKBVariant\n" + "\tEquivalent to XKBVariant in XF86Config files.\n" + "\tFor example: -xkbvariant nodeadkeys\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) { + g_pszLogFile = LogInit (g_pszLogFile, NULL); + g_fLogInited = TRUE; + } + LogClose (EXIT_NO_ERROR); + + /* Notify user where UseMsg text can be found.*/ + if (!g_fNoHelpMessageBox) + winMessageBoxF ("The " PROJECT_NAME " help text has been printed to " + "%s.\n" + "Please open %s to read the help text.\n", + MB_ICONINFORMATION, g_pszLogFile, g_pszLogFile); +} + +/* 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); + + winDebug ("InitOutput\n"); + + /* 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 ()) + ErrorF ("InitOutput - Error reading config file\n"); +#else + 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) + { + 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 (*)(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) + + /* Generate a cookie used by internal clients for authorization */ + if (g_fXdmcpEnabled || g_fAuthEnabled) + winGenerateAuthorization (); + + /* Perform some one time initialization */ + if (1 == serverGeneration) + { + /* + * setlocale applies to all threads in the current process. + * Apply locale specified in LANG environment variable. + */ + if (!setlocale (LC_ALL, "")) + { + ErrorF ("setlocale failed.\n"); + } + + /* See if X supports the current locale */ + if (XSupportsLocale () == FALSE) + { + ErrorF ("Warning: Locale not supported by X, falling back to 'C' locale.\n"); + setlocale(LC_ALL, "C"); + } + + } +#endif + + winDebug ("InitOutput - Returning.\n"); +} + + +/* + * 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 (void) +{ + int nDisp; + HANDLE mutex; + char name[MAX_PATH]; + char * pszPrefix = '\0'; + OSVERSIONINFO osvi = {0}; + + /* Check display range */ + nDisp = atoi (display); + if (nDisp < 0 || nDisp > 59535) + { + 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 - " + "VCXsrv, Xming or Cygwin/X is already running on display %d\n", + nDisp); + return FALSE; + } + + return TRUE; +} |