InitOutput.c 30.6 KB
Newer Older
1

Jeremy Huddleston's avatar
Jeremy Huddleston committed
2
3
4
/*

Copyright 1993, 1998  The Open Group
5
Copyright (C) Colin Harrison 2005-2008
Jeremy Huddleston's avatar
Jeremy Huddleston committed
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

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
#ifdef __CYGWIN__
#include <mntent.h>
#endif
Daniel Stone's avatar
Daniel Stone committed
44
45
#if defined(WIN32)
#include "xkbsrv.h"
Jeremy Huddleston's avatar
Jeremy Huddleston committed
46
47
#endif
#ifdef RELOCATE_PROJECTROOT
48
49
50
#pragma push_macro("Status")
#undef Status
#define Status wStatus
Jeremy Huddleston's avatar
Jeremy Huddleston committed
51
#include <shlobj.h>
52
#pragma pop_macro("Status")
53
54
55
56
typedef WINAPI HRESULT(*SHGETFOLDERPATHPROC) (HWND hwndOwner,
                                              int nFolder,
                                              HANDLE hToken,
                                              DWORD dwFlags, LPTSTR pszPath);
Jeremy Huddleston's avatar
Jeremy Huddleston committed
57
#endif
58
59
60
61
62

#include "winmonitors.h"
#include "nonsdk_extinit.h"
#include "pseudoramiX/pseudoramiX.h"

63
#include "glx_extinit.h"
64
65
#ifdef XWIN_GLX_WINDOWS
#include "glx/glwindows.h"
Jon Turney's avatar
Jon Turney committed
66
#include "dri/windowsdri.h"
67
#endif
68
#include "winauth.h"
69

Jeremy Huddleston's avatar
Jeremy Huddleston committed
70
71
72
73
74
75
76
77
78
/*
 * References to external symbols
 */

/*
 * Function prototypes
 */

void
79
 winLogCommandLine(int argc, char *argv[]);
Jeremy Huddleston's avatar
Jeremy Huddleston committed
80
81

void
82
 winLogVersionInfo(void);
Jeremy Huddleston's avatar
Jeremy Huddleston committed
83
84

Bool
85
 winValidateArgs(void);
Jeremy Huddleston's avatar
Jeremy Huddleston committed
86
87

#ifdef RELOCATE_PROJECTROOT
88
const char *winGetBaseDir(void);
Jeremy Huddleston's avatar
Jeremy Huddleston committed
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#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[] = {
105
106
107
108
109
110
111
    {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}
Jeremy Huddleston's avatar
Jeremy Huddleston committed
112
113
};

114
115
static Bool noDriExtension;

Jon Turney's avatar
Jon Turney committed
116
117
static const ExtensionModule xwinExtensions[] = {
#ifdef GLXEXT
Jon Turney's avatar
Jon Turney committed
118
119
120
#ifdef XWIN_WINDOWS_DRI
  { WindowsDRIExtensionInit, "Windows-DRI", &noDriExtension },
#endif
Jon Turney's avatar
Jon Turney committed
121
122
123
124
125
126
127
128
129
#endif
};

/*
 * XwinExtensionInit
 * Initialises Xwin-specific extensions.
 */
static
void XwinExtensionInit(void)
Jon Turney's avatar
Jon Turney committed
130
131
{
#ifdef XWIN_GLX_WINDOWS
132
    if (g_fNativeGl) {
133
134
        /* install the native GL provider */
        glxWinPushNativeProvider();
Jon Turney's avatar
Jon Turney committed
135
136
    }
#endif
Jon Turney's avatar
Jon Turney committed
137

138
    LoadExtensionList(xwinExtensions, ARRAY_SIZE(xwinExtensions), TRUE);
Jon Turney's avatar
Jon Turney committed
139
}
Jeremy Huddleston's avatar
Jeremy Huddleston committed
140
141
142
143

#if defined(DDXBEFORERESET)
/*
 * Called right before KillAllClients when the server is going to reset,
Alan Coopersmith's avatar
Alan Coopersmith committed
144
 * allows us to shutdown our separate threads cleanly.
Jeremy Huddleston's avatar
Jeremy Huddleston committed
145
146
147
 */

void
148
ddxBeforeReset(void)
Jeremy Huddleston's avatar
Jeremy Huddleston committed
149
{
150
    winDebug("ddxBeforeReset - Hello\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
151

152
    winClipboardShutdown();
Jeremy Huddleston's avatar
Jeremy Huddleston committed
153
154
155
}
#endif

156
157
158
159
160
161
162
163
164
#if INPUTTHREAD
/** This function is called in Xserver/os/inputthread.c when starting
    the input thread. */
void
ddxInputThreadInit(void)
{
}
#endif

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
int
main(int argc, char *argv[], char *envp[])
{
    int iReturn;

    /* Create & acquire the termination mutex */
    iReturn = pthread_mutex_init(&g_pmTerminating, NULL);
    if (iReturn != 0) {
        ErrorF("ddxMain - pthread_mutex_init () failed: %d\n", iReturn);
    }

    iReturn = pthread_mutex_lock(&g_pmTerminating);
    if (iReturn != 0) {
        ErrorF("ddxMain - pthread_mutex_lock () failed: %d\n", iReturn);
    }

    return dix_main(argc, argv, envp);
}

Jeremy Huddleston's avatar
Jeremy Huddleston committed
184
185
/* See Porting Layer Definition - p. 57 */
void
186
ddxGiveUp(enum ExitCode error)
Jeremy Huddleston's avatar
Jeremy Huddleston committed
187
{
188
    int i;
Jeremy Huddleston's avatar
Jeremy Huddleston committed
189
190

#if CYGDEBUG
191
    winDebug("ddxGiveUp\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
192
193
#endif

194
195
196
197
198
    /* 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));
Jeremy Huddleston's avatar
Jeremy Huddleston committed
199
200
    }

201
202
203
    /* Unload libraries for taskbar grouping */
    winPropertyStoreDestroy();

204
205
    /* Notify the worker threads we're exiting */
    winDeinitMultiWindowWM();
Jeremy Huddleston's avatar
Jeremy Huddleston committed
206
207

#ifdef HAS_DEVWINDOWS
208
209
210
211
    /* Close our handle to our message queue */
    if (g_fdMessageQueue != WIN_FD_INVALID) {
        /* Close /dev/windows */
        close(g_fdMessageQueue);
Jeremy Huddleston's avatar
Jeremy Huddleston committed
212

213
214
        /* Set the file handle to invalid */
        g_fdMessageQueue = WIN_FD_INVALID;
Jeremy Huddleston's avatar
Jeremy Huddleston committed
215
216
217
    }
#endif

218
    if (!g_fLogInited) {
219
        g_pszLogFile = LogInit(g_pszLogFile, ".old");
220
221
222
        g_fLogInited = TRUE;
    }
    LogClose(error);
Jeremy Huddleston's avatar
Jeremy Huddleston committed
223

224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
    /*
     * At this point we aren't creating any new screens, so
     * we are guaranteed to not need the DirectDraw functions.
     */
    winReleaseDDProcAddresses();

    /* 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);
239
240
241
242

    {
        int iReturn = pthread_mutex_unlock(&g_pmTerminating);

243
244
        winDebug("ddxGiveUp - Releasing termination mutex\n");

245
246
247
248
249
250
251
        if (iReturn != 0) {
            ErrorF("winMsgWindowProc - pthread_mutex_unlock () failed: %d\n",
                   iReturn);
        }
    }

    winDebug("ddxGiveUp - End\n");
252
}
Jeremy Huddleston's avatar
Jeremy Huddleston committed
253
254
255

#ifdef __CYGWIN__
/* hasmntopt is currently not implemented for cygwin */
256
257
static const char *
winCheckMntOpt(const struct mntent *mnt, const char *opt)
Jeremy Huddleston's avatar
Jeremy Huddleston committed
258
259
260
{
    const char *s;
    size_t len;
261

Jeremy Huddleston's avatar
Jeremy Huddleston committed
262
263
264
265
266
267
268
269
270
271
272
    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;
273
274
275
    if ((s == mnt->mnt_opts || *(s - 1) == ',') &&
        (s[len] == 0 || s[len] == ','))
        return (char *) opt;
Jeremy Huddleston's avatar
Jeremy Huddleston committed
276
277
278
279
280
281
    return NULL;
}

static void
winCheckMount(void)
{
282
283
284
285
286
287
288
289
290
291
292
    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;
Jeremy Huddleston's avatar
Jeremy Huddleston committed
293
    }
294
295

    while ((ent = getmntent(mnt)) != NULL) {
296
        BOOL sys = (winCheckMntOpt(ent, "user") != NULL);
297
298
299
        BOOL root = (strcmp(ent->mnt_dir, "/") == 0);
        BOOL tmp = (strcmp(ent->mnt_dir, "/tmp") == 0);

300
        if (sys) {
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
            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;
Jeremy Huddleston's avatar
Jeremy Huddleston committed
331
332
    }

333
334
    if (!binary)
        winMsg(X_WARNING, "/tmp mounted in textmode\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
335
336
337
}
#else
static void
338
winCheckMount(void)
Jeremy Huddleston's avatar
Jeremy Huddleston committed
339
340
341
342
343
{
}
#endif

#ifdef RELOCATE_PROJECTROOT
344
const char *
Jeremy Huddleston's avatar
Jeremy Huddleston committed
345
346
347
348
winGetBaseDir(void)
{
    static BOOL inited = FALSE;
    static char buffer[MAX_PATH];
349
350

    if (!inited) {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
351
352
353
        char *fendptr;
        HMODULE module = GetModuleHandle(NULL);
        DWORD size = GetModuleFileName(module, buffer, sizeof(buffer));
354

Jeremy Huddleston's avatar
Jeremy Huddleston committed
355
        if (sizeof(buffer) > 0)
356
357
            buffer[sizeof(buffer) - 1] = 0;

Jeremy Huddleston's avatar
Jeremy Huddleston committed
358
        fendptr = buffer + size;
359
360
        while (fendptr > buffer) {
            if (*fendptr == '\\' || *fendptr == '/') {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
361
362
363
364
365
366
367
368
369
370
371
372
                *fendptr = 0;
                break;
            }
            fendptr--;
        }
        inited = TRUE;
    }
    return buffer;
}
#endif

static void
373
winFixupPaths(void)
Jeremy Huddleston's avatar
Jeremy Huddleston committed
374
375
376
{
    BOOL changed_fontpath = FALSE;
    MessageType font_from = X_DEFAULT;
377

Jeremy Huddleston's avatar
Jeremy Huddleston committed
378
379
380
381
382
383
384
385
386
#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");
387
388

        if (fontdirs != NULL) {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
389
            char buffer[256];
390
            int needs_sep = TRUE;
Jeremy Huddleston's avatar
Jeremy Huddleston committed
391
392
            int comment_block = FALSE;

Jon Turney's avatar
Jon Turney committed
393
            /* get default fontpath */
394
            char *fontpath = strdup(defaultFontPath);
Jeremy Huddleston's avatar
Jeremy Huddleston committed
395
396
397
            size_t size = strlen(fontpath);

            /* read all lines */
398
            while (!feof(fontdirs)) {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
399
400
401
402
403
404
405
                size_t blen;
                char *hashchar;
                char *str;
                int has_eol = FALSE;

                /* read one line */
                str = fgets(buffer, sizeof(buffer), fontdirs);
406
                if (str == NULL)        /* stop on error or eof */
Jeremy Huddleston's avatar
Jeremy Huddleston committed
407
408
409
410
411
412
                    break;

                if (strchr(str, '\n') != NULL)
                    has_eol = TRUE;

                /* check if block is continued comment */
413
                if (comment_block) {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
414
                    /* ignore all input */
415
416
417
                    *str = 0;
                    blen = 0;
                    if (has_eol)        /* check if line ended in this block */
Jeremy Huddleston's avatar
Jeremy Huddleston committed
418
419
                        comment_block = FALSE;
                }
420
                else {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
421
422
                    /* find comment character. ignore all trailing input */
                    hashchar = strchr(str, '#');
423
                    if (hashchar != NULL) {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
424
                        *hashchar = 0;
425
                        if (!has_eol)   /* mark next block as continued comment */
Jeremy Huddleston's avatar
Jeremy Huddleston committed
426
427
428
429
430
431
432
433
                            comment_block = TRUE;
                    }
                }

                /* strip whitespaces from beginning */
                while (*str == ' ' || *str == '\t')
                    str++;

434
                /* get size, strip whitespaces from end */
Jeremy Huddleston's avatar
Jeremy Huddleston committed
435
                blen = strlen(str);
436
437
438
                while (blen > 0 && (str[blen - 1] == ' ' ||
                                    str[blen - 1] == '\t' ||
                                    str[blen - 1] == '\n')) {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
439
440
441
                    str[--blen] = 0;
                }

442
443
                /* still something left to add? */
                if (blen > 0) {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
444
                    size_t newsize = size + blen;
445

Jeremy Huddleston's avatar
Jeremy Huddleston committed
446
447
448
449
450
451
                    /* reserve one character more for ',' */
                    if (needs_sep)
                        newsize++;

                    /* allocate memory */
                    if (fontpath == NULL)
452
                        fontpath = malloc(newsize + 1);
Jeremy Huddleston's avatar
Jeremy Huddleston committed
453
                    else
454
                        fontpath = realloc(fontpath, newsize + 1);
Jeremy Huddleston's avatar
Jeremy Huddleston committed
455
456

                    /* add separator */
457
                    if (needs_sep) {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
                        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 */
475
            fclose(fontdirs);
476
            defaultFontPath = strdup(fontpath);
Jeremy Huddleston's avatar
Jeremy Huddleston committed
477
478
479
480
481
            free(fontpath);
            changed_fontpath = TRUE;
            font_from = X_CONFIG;
        }
    }
482
#endif                          /* READ_FONTDIRS */
Jeremy Huddleston's avatar
Jeremy Huddleston committed
483
484
485
486
487
488
489
490
491
492
493
494
#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;
495
        while (ptr != NULL) {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
496
497
498
            size_t oldfp_len = (ptr - oldptr);
            size_t newsize = oldfp_len;
            char *newpath = malloc(newsize + 1);
499

Jeremy Huddleston's avatar
Jeremy Huddleston committed
500
501
502
            strncpy(newpath, oldptr, newsize);
            newpath[newsize] = 0;

503
            if (strncmp(libx11dir, newpath, libx11dir_len) == 0) {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
504
                char *compose;
505

Jeremy Huddleston's avatar
Jeremy Huddleston committed
506
                newsize = newsize - libx11dir_len + basedirlen;
507
                compose = malloc(newsize + 1);
Jeremy Huddleston's avatar
Jeremy Huddleston committed
508
509
510
511
512
513
514
515
516
                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)
517
                newfp_len++;    /* space for separator */
Jeremy Huddleston's avatar
Jeremy Huddleston committed
518
519
520
521
522
523
524
            newfp_len += newsize;

            if (newfp == NULL)
                newfp = malloc(newfp_len + 1);
            else
                newfp = realloc(newfp, newfp_len + 1);

525
            if (oldfp_len > 0) {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
526
527
528
529
530
531
532
                strcpy(newfp + oldfp_len, ",");
                oldfp_len++;
            }
            strcpy(newfp + oldfp_len, newpath);

            free(newpath);

533
            if (*ptr == 0) {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
534
535
                oldptr = ptr;
                ptr = NULL;
536
537
            }
            else {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
538
539
540
541
542
                oldptr = ptr + 1;
                ptr = strchr(oldptr, ',');
                if (ptr == NULL)
                    ptr = endptr;
            }
543
        }
Jeremy Huddleston's avatar
Jeremy Huddleston committed
544

545
        defaultFontPath = strdup(newfp);
Jeremy Huddleston's avatar
Jeremy Huddleston committed
546
547
548
        free(newfp);
        changed_fontpath = TRUE;
    }
549
#endif                          /* RELOCATE_PROJECTROOT */
Jeremy Huddleston's avatar
Jeremy Huddleston committed
550
    if (changed_fontpath)
551
        winMsg(font_from, "FontPath set to \"%s\"\n", defaultFontPath);
Jeremy Huddleston's avatar
Jeremy Huddleston committed
552
553

#ifdef RELOCATE_PROJECTROOT
554
    if (getenv("XKEYSYMDB") == NULL) {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
555
        char buffer[MAX_PATH];
556
557
558

        snprintf(buffer, sizeof(buffer), "XKEYSYMDB=%s\\XKeysymDB", basedir);
        buffer[sizeof(buffer) - 1] = 0;
Jeremy Huddleston's avatar
Jeremy Huddleston committed
559
560
        putenv(buffer);
    }
561
    if (getenv("XERRORDB") == NULL) {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
562
        char buffer[MAX_PATH];
563
564
565

        snprintf(buffer, sizeof(buffer), "XERRORDB=%s\\XErrorDB", basedir);
        buffer[sizeof(buffer) - 1] = 0;
Jeremy Huddleston's avatar
Jeremy Huddleston committed
566
567
        putenv(buffer);
    }
568
    if (getenv("XLOCALEDIR") == NULL) {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
569
        char buffer[MAX_PATH];
570
571
572

        snprintf(buffer, sizeof(buffer), "XLOCALEDIR=%s\\locale", basedir);
        buffer[sizeof(buffer) - 1] = 0;
Jeremy Huddleston's avatar
Jeremy Huddleston committed
573
574
        putenv(buffer);
    }
575
    if (getenv("HOME") == NULL) {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
576
        char buffer[MAX_PATH + 5];
577

Jeremy Huddleston's avatar
Jeremy Huddleston committed
578
579
580
        strncpy(buffer, "HOME=", 5);

        /* query appdata directory */
581
582
583
        if (SHGetFolderPathA
            (NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0,
             buffer + 5) == 0) {
Jeremy Huddleston's avatar
Jeremy Huddleston committed
584
            putenv(buffer);
585
586
587
        }
        else {
            winMsg(X_ERROR, "Can not determine HOME directory\n");
588
        }
Jeremy Huddleston's avatar
Jeremy Huddleston committed
589
590
591
592
    }
    if (!g_fLogFileChanged) {
        static char buffer[MAX_PATH];
        DWORD size = GetTempPath(sizeof(buffer), buffer);
593
594
595
596
597

        if (size && size < sizeof(buffer)) {
            snprintf(buffer + size, sizeof(buffer) - size,
                     "XWin.%s.log", display);
            buffer[sizeof(buffer) - 1] = 0;
Jeremy Huddleston's avatar
Jeremy Huddleston committed
598
            g_pszLogFile = buffer;
599
            winMsg(X_DEFAULT, "Logfile set to \"%s\"\n", g_pszLogFile);
Jeremy Huddleston's avatar
Jeremy Huddleston committed
600
601
602
603
604
605
606
        }
    }
    {
        static char xkbbasedir[MAX_PATH];

        snprintf(xkbbasedir, sizeof(xkbbasedir), "%s\\xkb", basedir);
        if (sizeof(xkbbasedir) > 0)
607
            xkbbasedir[sizeof(xkbbasedir) - 1] = 0;
Jeremy Huddleston's avatar
Jeremy Huddleston committed
608
        XkbBaseDirectory = xkbbasedir;
609
        XkbBinDirectory = basedir;
Jeremy Huddleston's avatar
Jeremy Huddleston committed
610
    }
611
#endif                          /* RELOCATE_PROJECTROOT */
Jeremy Huddleston's avatar
Jeremy Huddleston committed
612
613
614
}

void
615
OsVendorInit(void)
Jeremy Huddleston's avatar
Jeremy Huddleston committed
616
{
617
618
    /* Re-initialize global variables on server reset */
    winInitializeGlobals();
Jeremy Huddleston's avatar
Jeremy Huddleston committed
619

620
    winFixupPaths();
Jeremy Huddleston's avatar
Jeremy Huddleston committed
621
622

#ifdef DDXOSVERRORF
623
624
    if (!OsVendorVErrorFProc)
        OsVendorVErrorFProc = OsVendorVErrorF;
Jeremy Huddleston's avatar
Jeremy Huddleston committed
625
626
#endif

627
628
    if (!g_fLogInited) {
        /* keep this order. If LogInit fails it calls Abort which then calls
Peter Hutterer's avatar
Peter Hutterer committed
629
630
631
         * 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
632
633
         */
        g_fLogInited = TRUE;
634
635
        g_pszLogFile = LogInit(g_pszLogFile, ".old");

636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
    }
    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;
Jeremy Huddleston's avatar
Jeremy Huddleston committed
662
663
    }

664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
    /* Work out what the default emulate3buttons setting should be, and apply
       it if nothing was explicitly specified */
    {
        int mouseButtons = GetSystemMetrics(SM_CMOUSEBUTTONS);
        int j;

        for (j = 0; j < g_iNumScreens; j++) {
            if (g_ScreenInfo[j].iE3BTimeout == WIN_E3B_DEFAULT) {
                if (mouseButtons < 3) {
                    static Bool reportOnce = TRUE;

                    g_ScreenInfo[j].iE3BTimeout = WIN_DEFAULT_E3B_TIME;
                    if (reportOnce) {
                        reportOnce = FALSE;
                        winMsg(X_PROBED,
                               "Windows reports only %d mouse buttons, defaulting to -emulate3buttons\n",
                               mouseButtons);
                    }
                }
                else {
                    g_ScreenInfo[j].iE3BTimeout = WIN_E3B_OFF;
                }
            }
        }
    }
689
690
691
692
693
694
695
696
697
698
699
700
701
702

    /* Work out what the default resize setting should be, and apply it if it
     was not explicitly specified */
    {
        int j;
        for (j = 0; j < g_iNumScreens; j++) {
            if (g_ScreenInfo[j].iResizeMode == resizeDefault) {
                if (g_ScreenInfo[j].fFullScreen)
                    g_ScreenInfo[j].iResizeMode = resizeNotAllowed;
                else
                    g_ScreenInfo[j].iResizeMode = resizeWithRandr;
                }
        }
    }
703
}
Jeremy Huddleston's avatar
Jeremy Huddleston committed
704
705

static void
706
winUseMsg(void)
Jeremy Huddleston's avatar
Jeremy Huddleston committed
707
{
708
709
710
711
    ErrorF("\n");
    ErrorF("\n");
    ErrorF(EXECUTABLE_NAME " Device Dependent Usage:\n");
    ErrorF("\n");
712

713
714
    ErrorF("-[no]clipboard\n"
           "\tEnable [disable] the clipboard integration. Default is enabled.\n");
715

716
717
718
719
    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");
720

721
722
    ErrorF("-[no]compositealpha\n"
           "\tX windows with per-pixel alpha are composited into the Windows desktop.\n");
723
724
725
726
727
    ErrorF("-[no]compositewm\n"
           "\tUse the Composite extension to keep a bitmap image of each top-level\n"
           "\tX window, so window contents which are occluded show correctly in\n"
           "\ttask bar and task switcher previews.\n");

728
#ifdef XWIN_XF86CONFIG
729
    ErrorF("-config\n" "\tSpecify a configuration file.\n");
730

731
    ErrorF("-configdir\n" "\tSpecify a configuration directory.\n");
732
733
#endif

734
735
736
    ErrorF("-depth bits_per_pixel\n"
           "\tSpecify an optional bitdepth to use in fullscreen mode\n"
           "\twith a DirectDraw engine.\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
737

738
739
740
    ErrorF("-[no]emulate3buttons [timeout]\n"
           "\tEmulate 3 button mouse with an optional timeout in\n"
           "\tmilliseconds.\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
741

742
#ifdef XWIN_EMULATEPSEUDO
743
744
745
746
747
748
    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");
749
750
#endif

751
752
753
754
755
    ErrorF("-engine engine_type_id\n"
           "\tOverride the server's automatically selected engine type:\n"
           "\t\t1 - Shadow GDI\n"
           "\t\t4 - Shadow DirectDraw4 Non-Locking\n"
        );
Jeremy Huddleston's avatar
Jeremy Huddleston committed
756

757
    ErrorF("-fullscreen\n" "\tRun the server in fullscreen mode.\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
758

759
    ErrorF("-[no]hostintitle\n"
760
761
           "\tIn multiwindow mode, add remote host names to window titles.\n");

762
763
    ErrorF("-icon icon_specifier\n" "\tSet screen window icon in windowed mode.\n");

764
    ErrorF("-ignoreinput\n" "\tIgnore keyboard and mouse input.\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
765

766
#ifdef XWIN_XF86CONFIG
767
768
    ErrorF("-keyboard\n"
           "\tSpecify a keyboard device from the configuration file.\n");
769
770
#endif

771
772
773
    ErrorF("-[no]keyhook\n"
           "\tGrab special Windows keypresses like Alt-Tab or the Menu "
           "key.\n");
774

775
776
777
778
779
    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");
780

781
    ErrorF("-logfile filename\n" "\tWrite log messages to <filename>.\n");
782

783
784
785
786
787
788
789
    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");
790

791
792
793
    ErrorF("-[no]multimonitors or -[no]multiplemonitors\n"
           "\tUse the entire virtual screen if multiple\n"
           "\tmonitors are present.\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
794

795
    ErrorF("-multiwindow\n" "\tRun the server in multi-window mode.\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
796

797
798
799
    ErrorF("-nodecoration\n"
           "\tDo not draw a window border, title bar, etc.  Windowed\n"
           "\tmode only.\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
800

801
802
803
    ErrorF("-[no]primary\n"
           "\tWhen clipboard integration is enabled, map the X11 PRIMARY selection\n"
           "\tto the Windows clipboard. Default is enabled.\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
804

805
806
807
808
    ErrorF("-refresh rate_in_Hz\n"
           "\tSpecify an optional refresh rate to use in fullscreen mode\n"
           "\twith a DirectDraw engine.\n");

809
    ErrorF("-resize=none|scrollbars|randr\n"
810
811
           "\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"
812
           "\textension to resize the X screen.  'randr' is the default.\n");
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836

    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. 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("-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");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
837

Jon Turney's avatar
Jon Turney committed
838
#ifdef XWIN_GLX_WINDOWS
839
    ErrorF("-[no]wgl\n"
840
           "\tEnable the GLX extension to use the native Windows WGL interface for hardware-accelerated OpenGL\n");
Jon Turney's avatar
Jon Turney committed
841
842
#endif

843
    ErrorF("-[no]winkill\n" "\tAlt+F4 exits the X Server.\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
844

845
846
847
    ErrorF("-xkblayout XKBLayout\n"
           "\tEquivalent to XKBLayout in XF86Config files.\n"
           "\tFor example: -xkblayout de\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
848

849
850
    ErrorF("-xkbmodel XKBModel\n"
           "\tEquivalent to XKBModel in XF86Config files.\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
851

852
853
    ErrorF("-xkboptions XKBOptions\n"
           "\tEquivalent to XKBOptions in XF86Config files.\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
854

855
856
    ErrorF("-xkbrules XKBRules\n"
           "\tEquivalent to XKBRules in XF86Config files.\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
857

858
859
860
    ErrorF("-xkbvariant XKBVariant\n"
           "\tEquivalent to XKBVariant in XF86Config files.\n"
           "\tFor example: -xkbvariant nodeadkeys\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
861
862
863
864
865
866
}

/* See Porting Layer Definition - p. 57 */
void
ddxUseMsg(void)
{
867
868
869
870
871
872
873
    /* 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) {
874
        g_pszLogFile = LogInit(g_pszLogFile, ".old");
875
876
877
878
879
880
881
882
883
884
        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);
Jeremy Huddleston's avatar
Jeremy Huddleston committed
885
886
887
888
889
}

/* See Porting Layer Definition - p. 20 */
/*
 * Do any global initialization, then initialize each screen.
Peter Hutterer's avatar
Peter Hutterer committed
890
 *
Jeremy Huddleston's avatar
Jeremy Huddleston committed
891
892
893
894
 * NOTE: We use ddxProcessArgument, so we don't need to touch argc and argv
 */

void
895
InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
Jeremy Huddleston's avatar
Jeremy Huddleston committed
896
{
897
    int i;
Jeremy Huddleston's avatar
Jeremy Huddleston committed
898

899
900
    if (serverGeneration == 1)
        XwinExtensionInit();
Jon Turney's avatar
Jon Turney committed
901

902
903
    /* Log the command line */
    winLogCommandLine(argc, argv);
Jeremy Huddleston's avatar
Jeremy Huddleston committed
904
905

#if CYGDEBUG
906
    winDebug("InitOutput\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
907
908
#endif

909
910
911
912
    /* Validate command-line arguments */
    if (serverGeneration == 1 && !winValidateArgs()) {
        FatalError("InitOutput - Invalid command-line arguments found.  "
                   "Exiting.\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
913
914
915
    }

#ifdef XWIN_XF86CONFIG
916
917
918
    /* Try to read the xorg.conf-style configuration file */
    if (!winReadConfigfile())
        winErrorFVerb(1, "InitOutput - Error reading config file\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
919
#else
920
921
922
923
    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();
Jeremy Huddleston's avatar
Jeremy Huddleston committed
924
925
#endif

926
927
928
929
    /* Load preferences from XWinrc file */
    LoadPreferences();

    /* Setup global screen info parameters */
930
931
932
933
    pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
    pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
    pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
    pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
934
    pScreenInfo->numPixmapFormats = ARRAY_SIZE(g_PixmapFormats);
935
936

    /* Describe how we want common pixmap formats padded */
937
    for (i = 0; i < ARRAY_SIZE(g_PixmapFormats); i++) {
938
        pScreenInfo->formats[i] = g_PixmapFormats[i];
Jeremy Huddleston's avatar
Jeremy Huddleston committed
939
940
    }

941
942
    /* Load pointers to DirectDraw functions */
    winGetDDProcAddresses();
Jeremy Huddleston's avatar
Jeremy Huddleston committed
943

944
945
    /* Detect supported engines */
    winDetectSupportedEngines();
946
947
    /* Load libraries for taskbar grouping */
    winPropertyStoreInit();
Jeremy Huddleston's avatar
Jeremy Huddleston committed
948

949
950
951
    /* Store the instance handle */
    g_hInstance = GetModuleHandle(NULL);

952
953
954
955
    /* Create the messaging window */
    if (serverGeneration == 1)
        winCreateMsgWindowThread();

956
957
958
959
960
961
    /* 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);
        }
Jeremy Huddleston's avatar
Jeremy Huddleston committed
962
963
    }

964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
  /*
     Unless full xinerama has been explicitly enabled, register all native screens with pseudoramiX
  */
  if (!noPanoramiXExtension)
      noPseudoramiXExtension = TRUE;

  if ((g_ScreenInfo[0].fMultipleMonitors) && !noPseudoramiXExtension)
    {
      int pass;

      PseudoramiXExtensionInit();

      /* Add primary monitor on pass 0, other monitors on pass 1, to ensure
       the primary monitor is first in XINERAMA list */
      for (pass = 0; pass < 2; pass++)
        {
          int iMonitor;

          for (iMonitor = 1; ; iMonitor++)
            {
              struct GetMonitorInfoData data;
985
              if (QueryMonitor(iMonitor, &data))
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
                {
                  MONITORINFO mi;
                  mi.cbSize = sizeof(MONITORINFO);

                  if (GetMonitorInfo(data.monitorHandle, &mi))
                    {
                      /* pass == 1 XOR primary monitor flags is set */
                      if ((!(pass == 1)) != (!(mi.dwFlags & MONITORINFOF_PRIMARY)))
                        {
                          /*
                            Note the screen origin in a normalized coordinate space where (0,0) is at the top left
                            of the native virtual desktop area
                          */
                          data.monitorOffsetX = data.monitorOffsetX - GetSystemMetrics(SM_XVIRTUALSCREEN);
                          data.monitorOffsetY = data.monitorOffsetY - GetSystemMetrics(SM_YVIRTUALSCREEN);

                          winDebug ("InitOutput - screen %d added at virtual desktop coordinate (%d,%d) (pseudoramiX) \n",
                                    iMonitor-1, data.monitorOffsetX, data.monitorOffsetY);

                          PseudoramiXAddScreen(data.monitorOffsetX, data.monitorOffsetY,
                                               data.monitorWidth, data.monitorHeight);
                        }
                    }
                }
              else
                break;
            }
        }
    }

Jon Turney's avatar
Jon Turney committed
1016
1017
    xorgGlxCreateVendor();

1018
1019
1020
1021
    /* Generate a cookie used by internal clients for authorization */
    if (g_fXdmcpEnabled || g_fAuthEnabled)
        winGenerateAuthorization();

Jeremy Huddleston's avatar
Jeremy Huddleston committed
1022
1023

#if CYGDEBUG || YES
1024
    winDebug("InitOutput - Returning.\n");
Jeremy Huddleston's avatar
Jeremy Huddleston committed
1025
1026
#endif
}