1142 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			1142 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C
		
	
	
	
 | 
						||
/*
 | 
						||
 | 
						||
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 XWIN_CLIPBOARD
 | 
						||
#include "X11/Xlocale.h"
 | 
						||
#endif
 | 
						||
#ifdef DPMSExtension
 | 
						||
#include "dpmsproc.h"
 | 
						||
#endif
 | 
						||
#ifdef __CYGWIN__
 | 
						||
#include <mntent.h>
 | 
						||
#endif
 | 
						||
#if defined(WIN32)
 | 
						||
#include "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 char *			g_pszCommandLine;
 | 
						||
extern Bool			g_fSilentFatalError;
 | 
						||
 | 
						||
extern const char *		g_pszLogFile;
 | 
						||
extern Bool			g_fLogFileChanged;
 | 
						||
extern int			g_iLogVerbose;
 | 
						||
Bool				g_fLogInited;
 | 
						||
 | 
						||
extern Bool			g_fXdmcpEnabled;
 | 
						||
extern Bool			g_fAuthEnabled;
 | 
						||
#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;                     
 | 
						||
extern Bool                     g_fNativeGl;
 | 
						||
 | 
						||
/*
 | 
						||
 * 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)
 | 
						||
	{
 | 
						||
	  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
 | 
						||
 | 
						||
void
 | 
						||
ddxPushProviders(void)
 | 
						||
{
 | 
						||
#ifdef XWIN_GLX_WINDOWS
 | 
						||
  if (g_fNativeGl)
 | 
						||
    {
 | 
						||
      /* install the native GL provider */
 | 
						||
      glxWinPushNativeProvider();
 | 
						||
    }
 | 
						||
#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) {
 | 
						||
    g_pszLogFile = 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 = (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;
 | 
						||
  }
 | 
						||
  
 | 
						||
 if (!binary) 
 | 
						||
   winMsg(X_WARNING, "/tmp mounted in 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 (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);
 | 
						||
        }
 | 
						||
    }
 | 
						||
    {
 | 
						||
        static char xkbbasedir[MAX_PATH];
 | 
						||
 | 
						||
        snprintf(xkbbasedir, sizeof(xkbbasedir), "%s\\xkb", 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");
 | 
						||
#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_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_MULTIWINDOWEXTWM
 | 
						||
  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 ("-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 ("-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 ("-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");
 | 
						||
 | 
						||
#ifdef XWIN_GLX_WINDOWS
 | 
						||
  ErrorF ("-[no]wgl\n"
 | 
						||
	  "\tEnable the GLX extension to use the native Windows WGL interface for accelerated OpenGL\n");
 | 
						||
#endif
 | 
						||
 | 
						||
  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 ();
 | 
						||
 | 
						||
  /* 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);
 | 
						||
 | 
						||
#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, "xorg.conf 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)
 | 
						||
 | 
						||
  /* 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.
 | 
						||
       */
 | 
						||
      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 (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 > 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;
 | 
						||
}
 |