winprocarg.c revision 35c4bbdf
1/*
2
3Copyright 1993, 1998  The Open Group
4Copyright (C) Colin Harrison 2005-2008
5
6Permission to use, copy, modify, distribute, and sell this software and its
7documentation for any purpose is hereby granted without fee, provided that
8the above copyright notice appear in all copies and that both that
9copyright notice and this permission notice appear in supporting
10documentation.
11
12The above copyright notice and this permission notice shall be included
13in all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
19OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21OTHER DEALINGS IN THE SOFTWARE.
22
23Except as contained in this notice, the name of The Open Group shall
24not be used in advertising or otherwise to promote the sale, use or
25other dealings in this Software without prior written authorization
26from The Open Group.
27
28*/
29
30#ifdef HAVE_XWIN_CONFIG_H
31#include <xwin-config.h>
32#endif
33
34#ifdef HAVE_SYS_UTSNAME_H
35#include <sys/utsname.h>
36#endif
37
38#include <../xfree86/common/xorgVersion.h>
39#include "win.h"
40#include "winconfig.h"
41#include "winmsg.h"
42#include "winmonitors.h"
43
44#ifdef XWIN_CLIPBOARD
45#include "winclipboard/winclipboard.h"
46#endif
47
48/*
49 * Function prototypes
50 */
51
52void
53 winLogCommandLine(int argc, char *argv[]);
54
55void
56 winLogVersionInfo(void);
57
58/*
59 * Process arguments on the command line
60 */
61
62static int iLastScreen = -1;
63static winScreenInfo defaultScreenInfo;
64
65static void
66winInitializeScreenDefaults(void)
67{
68    DWORD dwWidth, dwHeight;
69    static Bool fInitializedScreenDefaults = FALSE;
70
71    /* Bail out early if default screen has already been initialized */
72    if (fInitializedScreenDefaults)
73        return;
74
75    /* Zero the memory used for storing the screen info */
76    memset(&defaultScreenInfo, 0, sizeof(winScreenInfo));
77
78    /* Get default width and height */
79    /*
80     * NOTE: These defaults will cause the window to cover only
81     * the primary monitor in the case that we have multiple monitors.
82     */
83    dwWidth = GetSystemMetrics(SM_CXSCREEN);
84    dwHeight = GetSystemMetrics(SM_CYSCREEN);
85
86    winErrorFVerb(2,
87                  "winInitializeScreenDefaults - primary monitor w %d h %d\n",
88                  (int) dwWidth, (int) dwHeight);
89
90    /* Set a default DPI, if no '-dpi' option was used */
91    if (monitorResolution == 0) {
92        HDC hdc = GetDC(NULL);
93
94        if (hdc) {
95            int dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
96            int dpiY = GetDeviceCaps(hdc, LOGPIXELSY);
97
98            winErrorFVerb(2,
99                          "winInitializeScreenDefaults - native DPI x %d y %d\n",
100                          dpiX, dpiY);
101
102            monitorResolution = dpiY;
103            ReleaseDC(NULL, hdc);
104        }
105        else {
106            winErrorFVerb(1,
107                          "winInitializeScreenDefaults - Failed to retrieve native DPI, falling back to default of %d DPI\n",
108                          WIN_DEFAULT_DPI);
109            monitorResolution = WIN_DEFAULT_DPI;
110        }
111    }
112
113    defaultScreenInfo.iMonitor = 1;
114    defaultScreenInfo.hMonitor = MonitorFromWindow(NULL, MONITOR_DEFAULTTOPRIMARY);
115    defaultScreenInfo.dwWidth = dwWidth;
116    defaultScreenInfo.dwHeight = dwHeight;
117    defaultScreenInfo.dwUserWidth = dwWidth;
118    defaultScreenInfo.dwUserHeight = dwHeight;
119    defaultScreenInfo.fUserGaveHeightAndWidth =
120        WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH;
121    defaultScreenInfo.fUserGavePosition = FALSE;
122    defaultScreenInfo.dwBPP = WIN_DEFAULT_BPP;
123    defaultScreenInfo.dwClipUpdatesNBoxes = WIN_DEFAULT_CLIP_UPDATES_NBOXES;
124#ifdef XWIN_EMULATEPSEUDO
125    defaultScreenInfo.fEmulatePseudo = WIN_DEFAULT_EMULATE_PSEUDO;
126#endif
127    defaultScreenInfo.dwRefreshRate = WIN_DEFAULT_REFRESH;
128    defaultScreenInfo.pfb = NULL;
129    defaultScreenInfo.fFullScreen = FALSE;
130    defaultScreenInfo.fDecoration = TRUE;
131#ifdef XWIN_MULTIWINDOWEXTWM
132    defaultScreenInfo.fMWExtWM = FALSE;
133    defaultScreenInfo.fInternalWM = FALSE;
134#endif
135    defaultScreenInfo.fRootless = FALSE;
136#ifdef XWIN_MULTIWINDOW
137    defaultScreenInfo.fMultiWindow = FALSE;
138#endif
139#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
140    defaultScreenInfo.fMultiMonitorOverride = FALSE;
141#endif
142    defaultScreenInfo.fMultipleMonitors = FALSE;
143    defaultScreenInfo.fLessPointer = FALSE;
144    defaultScreenInfo.iResizeMode = resizeWithRandr;
145    defaultScreenInfo.fNoTrayIcon = FALSE;
146    defaultScreenInfo.iE3BTimeout = WIN_E3B_DEFAULT;
147    defaultScreenInfo.fUseWinKillKey = WIN_DEFAULT_WIN_KILL;
148    defaultScreenInfo.fUseUnixKillKey = WIN_DEFAULT_UNIX_KILL;
149    defaultScreenInfo.fIgnoreInput = FALSE;
150    defaultScreenInfo.fExplicitScreen = FALSE;
151
152    /* Note that the default screen has been initialized */
153    fInitializedScreenDefaults = TRUE;
154}
155
156static void
157winInitializeScreen(int i)
158{
159    winErrorFVerb(3, "winInitializeScreen - %d\n", i);
160
161    /* Initialize default screen values, if needed */
162    winInitializeScreenDefaults();
163
164    /* Copy the default screen info */
165    g_ScreenInfo[i] = defaultScreenInfo;
166
167    /* Set the screen number */
168    g_ScreenInfo[i].dwScreen = i;
169}
170
171void
172winInitializeScreens(int maxscreens)
173{
174    int i;
175
176    winErrorFVerb(3, "winInitializeScreens - %i\n", maxscreens);
177
178    if (maxscreens > g_iNumScreens) {
179        /* Reallocate the memory for DDX-specific screen info */
180        g_ScreenInfo =
181            realloc(g_ScreenInfo, maxscreens * sizeof(winScreenInfo));
182
183        /* Set default values for any new screens */
184        for (i = g_iNumScreens; i < maxscreens; i++)
185            winInitializeScreen(i);
186
187        /* Keep a count of the number of screens */
188        g_iNumScreens = maxscreens;
189    }
190}
191
192/* See Porting Layer Definition - p. 57 */
193/*
194 * INPUT
195 * argv: pointer to an array of null-terminated strings, one for
196 *   each token in the X Server command line; the first token
197 *   is 'XWin.exe', or similar.
198 * argc: a count of the number of tokens stored in argv.
199 * i: a zero-based index into argv indicating the current token being
200 *   processed.
201 *
202 * OUTPUT
203 * return: return the number of tokens processed correctly.
204 *
205 * NOTE
206 * When looking for n tokens, check that i + n is less than argc.  Or,
207 *   you may check if i is greater than or equal to argc, in which case
208 *   you should display the UseMsg () and return 0.
209 */
210
211/* Check if enough arguments are given for the option */
212#define CHECK_ARGS(count) if (i + count >= argc) { UseMsg (); return 0; }
213
214/* Compare the current option with the string. */
215#define IS_OPTION(name) (strcmp (argv[i], name) == 0)
216
217int
218ddxProcessArgument(int argc, char *argv[], int i)
219{
220    static Bool s_fBeenHere = FALSE;
221    winScreenInfo *screenInfoPtr = NULL;
222
223    /* Initialize once */
224    if (!s_fBeenHere) {
225#ifdef DDXOSVERRORF
226        /*
227         * This initialises our hook into VErrorF () for catching log messages
228         * that are generated before OsInit () is called.
229         */
230        OsVendorVErrorFProc = OsVendorVErrorF;
231#endif
232
233        s_fBeenHere = TRUE;
234
235        /* Initialize only if option is not -help */
236        if (!IS_OPTION("-help") && !IS_OPTION("-h") && !IS_OPTION("--help") &&
237            !IS_OPTION("-version") && !IS_OPTION("--version")) {
238
239            /* Log the version information */
240            winLogVersionInfo();
241
242            /* Log the command line */
243            winLogCommandLine(argc, argv);
244
245            /*
246             * Initialize default screen settings.  We have to do this before
247             * OsVendorInit () gets called, otherwise we will overwrite
248             * settings changed by parameters such as -fullscreen, etc.
249             */
250            winErrorFVerb(2, "ddxProcessArgument - Initializing default "
251                          "screens\n");
252            winInitializeScreenDefaults();
253        }
254    }
255
256#if CYGDEBUG
257    winDebug("ddxProcessArgument - arg: %s\n", argv[i]);
258#endif
259
260    /*
261     * Look for the '-help' and similar options
262     */
263    if (IS_OPTION("-help") || IS_OPTION("-h") || IS_OPTION("--help")) {
264        /* Reset logfile. We don't need that helpmessage in the logfile */
265        g_pszLogFile = NULL;
266        g_fNoHelpMessageBox = TRUE;
267        UseMsg();
268        exit(0);
269        return 1;
270    }
271
272    if (IS_OPTION("-version") || IS_OPTION("--version")) {
273        /* Reset logfile. We don't need that versioninfo in the logfile */
274        g_pszLogFile = NULL;
275        winLogVersionInfo();
276        exit(0);
277        return 1;
278    }
279
280    /*
281     * Look for the '-screen scr_num [width height]' argument
282     */
283    if (IS_OPTION("-screen")) {
284        int iArgsProcessed = 1;
285        int nScreenNum;
286        int iWidth, iHeight, iX, iY;
287        int iMonitor;
288
289#if CYGDEBUG
290        winDebug("ddxProcessArgument - screen - argc: %d i: %d\n", argc, i);
291#endif
292
293        /* Display the usage message if the argument is malformed */
294        if (i + 1 >= argc) {
295            return 0;
296        }
297
298        /* Grab screen number */
299        nScreenNum = atoi(argv[i + 1]);
300
301        /* Validate the specified screen number */
302        if (nScreenNum < 0) {
303            ErrorF("ddxProcessArgument - screen - Invalid screen number %d\n",
304                   nScreenNum);
305            UseMsg();
306            return 0;
307        }
308
309        /*
310           Initialize default values for any new screens
311
312           Note that default values can't change after a -screen option is
313           seen, so it's safe to do this for each screen as it is introduced
314         */
315        winInitializeScreens(nScreenNum + 1);
316
317        /* look for @m where m is monitor number */
318        if (i + 2 < argc && 1 == sscanf(argv[i + 2], "@%d", (int *) &iMonitor)) {
319            struct GetMonitorInfoData data;
320
321            if (!QueryMonitor(iMonitor, &data)) {
322                ErrorF
323                    ("ddxProcessArgument - screen - Querying monitors failed\n");
324            }
325            else if (data.bMonitorSpecifiedExists == TRUE) {
326                winErrorFVerb(2,
327                              "ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n",
328                              iMonitor);
329                iArgsProcessed = 3;
330                g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = FALSE;
331                g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE;
332                g_ScreenInfo[nScreenNum].iMonitor = iMonitor;
333                g_ScreenInfo[nScreenNum].hMonitor = data.monitorHandle;
334                g_ScreenInfo[nScreenNum].dwWidth = data.monitorWidth;
335                g_ScreenInfo[nScreenNum].dwHeight = data.monitorHeight;
336                g_ScreenInfo[nScreenNum].dwUserWidth = data.monitorWidth;
337                g_ScreenInfo[nScreenNum].dwUserHeight = data.monitorHeight;
338                g_ScreenInfo[nScreenNum].dwInitialX = data.monitorOffsetX;
339                g_ScreenInfo[nScreenNum].dwInitialY = data.monitorOffsetY;
340            }
341            else {
342                /* monitor does not exist, error out */
343                ErrorF
344                    ("ddxProcessArgument - screen - Invalid monitor number %d\n",
345                     iMonitor);
346                UseMsg();
347                exit(0);
348                return 0;
349            }
350        }
351
352        /* Look for 'WxD' or 'W D' */
353        else if (i + 2 < argc
354                 && 2 == sscanf(argv[i + 2], "%dx%d",
355                                (int *) &iWidth, (int *) &iHeight)) {
356            winErrorFVerb(2,
357                          "ddxProcessArgument - screen - Found ``WxD'' arg\n");
358            iArgsProcessed = 3;
359            g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = TRUE;
360            g_ScreenInfo[nScreenNum].dwWidth = iWidth;
361            g_ScreenInfo[nScreenNum].dwHeight = iHeight;
362            g_ScreenInfo[nScreenNum].dwUserWidth = iWidth;
363            g_ScreenInfo[nScreenNum].dwUserHeight = iHeight;
364            /* Look for WxD+X+Y */
365            if (2 == sscanf(argv[i + 2], "%*dx%*d+%d+%d",
366                            (int *) &iX, (int *) &iY)) {
367                winErrorFVerb(2,
368                              "ddxProcessArgument - screen - Found ``X+Y'' arg\n");
369                g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE;
370                g_ScreenInfo[nScreenNum].dwInitialX = iX;
371                g_ScreenInfo[nScreenNum].dwInitialY = iY;
372
373                /* look for WxD+X+Y@m where m is monitor number. take X,Y to be offsets from monitor's root position */
374                if (1 == sscanf(argv[i + 2], "%*dx%*d+%*d+%*d@%d",
375                                (int *) &iMonitor)) {
376                    struct GetMonitorInfoData data;
377
378                    if (!QueryMonitor(iMonitor, &data)) {
379                        ErrorF
380                            ("ddxProcessArgument - screen - Querying monitors failed\n");
381                    }
382                    else if (data.bMonitorSpecifiedExists == TRUE) {
383                        g_ScreenInfo[nScreenNum].iMonitor = iMonitor;
384                        g_ScreenInfo[nScreenNum].hMonitor = data.monitorHandle;
385                        g_ScreenInfo[nScreenNum].dwInitialX +=
386                            data.monitorOffsetX;
387                        g_ScreenInfo[nScreenNum].dwInitialY +=
388                            data.monitorOffsetY;
389                    }
390                    else {
391                        /* monitor does not exist, error out */
392                        ErrorF
393                            ("ddxProcessArgument - screen - Invalid monitor number %d\n",
394                             iMonitor);
395                        UseMsg();
396                        exit(0);
397                        return 0;
398                    }
399
400                }
401            }
402
403            /* look for WxD@m where m is monitor number */
404            else if (1 == sscanf(argv[i + 2], "%*dx%*d@%d", (int *) &iMonitor)) {
405                struct GetMonitorInfoData data;
406
407                if (!QueryMonitor(iMonitor, &data)) {
408                    ErrorF
409                        ("ddxProcessArgument - screen - Querying monitors failed\n");
410                }
411                else if (data.bMonitorSpecifiedExists == TRUE) {
412                    winErrorFVerb(2,
413                                  "ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n",
414                                  iMonitor);
415                    g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE;
416                    g_ScreenInfo[nScreenNum].iMonitor = iMonitor;
417                    g_ScreenInfo[nScreenNum].hMonitor = data.monitorHandle;
418                    g_ScreenInfo[nScreenNum].dwInitialX = data.monitorOffsetX;
419                    g_ScreenInfo[nScreenNum].dwInitialY = data.monitorOffsetY;
420                }
421                else {
422                    /* monitor does not exist, error out */
423                    ErrorF
424                        ("ddxProcessArgument - screen - Invalid monitor number %d\n",
425                         iMonitor);
426                    UseMsg();
427                    exit(0);
428                    return 0;
429                }
430
431            }
432        }
433        else if (i + 3 < argc && 1 == sscanf(argv[i + 2], "%d", (int *) &iWidth)
434                 && 1 == sscanf(argv[i + 3], "%d", (int *) &iHeight)) {
435            winErrorFVerb(2,
436                          "ddxProcessArgument - screen - Found ``W D'' arg\n");
437            iArgsProcessed = 4;
438            g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = TRUE;
439            g_ScreenInfo[nScreenNum].dwWidth = iWidth;
440            g_ScreenInfo[nScreenNum].dwHeight = iHeight;
441            g_ScreenInfo[nScreenNum].dwUserWidth = iWidth;
442            g_ScreenInfo[nScreenNum].dwUserHeight = iHeight;
443            if (i + 5 < argc && 1 == sscanf(argv[i + 4], "%d", (int *) &iX)
444                && 1 == sscanf(argv[i + 5], "%d", (int *) &iY)) {
445                winErrorFVerb(2,
446                              "ddxProcessArgument - screen - Found ``X Y'' arg\n");
447                iArgsProcessed = 6;
448                g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE;
449                g_ScreenInfo[nScreenNum].dwInitialX = iX;
450                g_ScreenInfo[nScreenNum].dwInitialY = iY;
451            }
452        }
453        else {
454            winErrorFVerb(2,
455                          "ddxProcessArgument - screen - Did not find size arg. "
456                          "dwWidth: %d dwHeight: %d\n",
457                          (int) g_ScreenInfo[nScreenNum].dwWidth,
458                          (int) g_ScreenInfo[nScreenNum].dwHeight);
459            iArgsProcessed = 2;
460            g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = FALSE;
461        }
462
463        /* Flag that this screen was explicity specified by the user */
464        g_ScreenInfo[nScreenNum].fExplicitScreen = TRUE;
465
466        /*
467         * Keep track of the last screen number seen, as parameters seen
468         * before a screen number apply to all screens, whereas parameters
469         * seen after a screen number apply to that screen number only.
470         */
471        iLastScreen = nScreenNum;
472
473        return iArgsProcessed;
474    }
475
476    /*
477     * Is this parameter attached to a screen or global?
478     *
479     * If the parameter is for all screens (appears before
480     * any -screen option), store it in the default screen
481     * info
482     *
483     * If the parameter is for a single screen (appears
484     * after a -screen option), store it in the screen info
485     * for that screen
486     *
487     */
488    if (iLastScreen == -1) {
489        screenInfoPtr = &defaultScreenInfo;
490    }
491    else {
492        screenInfoPtr = &(g_ScreenInfo[iLastScreen]);
493    }
494
495    /*
496     * Look for the '-engine n' argument
497     */
498    if (IS_OPTION("-engine")) {
499        DWORD dwEngine = 0;
500        CARD8 c8OnBits = 0;
501
502        /* Display the usage message if the argument is malformed */
503        if (++i >= argc) {
504            UseMsg();
505            return 0;
506        }
507
508        /* Grab the argument */
509        dwEngine = atoi(argv[i]);
510
511        /* Count the one bits in the engine argument */
512        c8OnBits = winCountBits(dwEngine);
513
514        /* Argument should only have a single bit on */
515        if (c8OnBits != 1) {
516            UseMsg();
517            return 0;
518        }
519
520        screenInfoPtr->dwEnginePreferred = dwEngine;
521
522        /* Indicate that we have processed the argument */
523        return 2;
524    }
525
526    /*
527     * Look for the '-fullscreen' argument
528     */
529    if (IS_OPTION("-fullscreen")) {
530#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
531        if (!screenInfoPtr->fMultiMonitorOverride)
532            screenInfoPtr->fMultipleMonitors = FALSE;
533#endif
534        screenInfoPtr->fFullScreen = TRUE;
535
536        /* Indicate that we have processed this argument */
537        return 1;
538    }
539
540    /*
541     * Look for the '-lesspointer' argument
542     */
543    if (IS_OPTION("-lesspointer")) {
544        screenInfoPtr->fLessPointer = TRUE;
545
546        /* Indicate that we have processed this argument */
547        return 1;
548    }
549
550    /*
551     * Look for the '-nodecoration' argument
552     */
553    if (IS_OPTION("-nodecoration")) {
554#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
555        if (!screenInfoPtr->fMultiMonitorOverride)
556            screenInfoPtr->fMultipleMonitors = FALSE;
557#endif
558        screenInfoPtr->fDecoration = FALSE;
559
560        /* Indicate that we have processed this argument */
561        return 1;
562    }
563
564#ifdef XWIN_MULTIWINDOWEXTWM
565    /*
566     * Look for the '-mwextwm' argument
567     */
568    if (IS_OPTION("-mwextwm")) {
569        if (!screenInfoPtr->fMultiMonitorOverride)
570            screenInfoPtr->fMultipleMonitors = TRUE;
571        screenInfoPtr->fMWExtWM = TRUE;
572
573        /* Indicate that we have processed this argument */
574        return 1;
575    }
576    /*
577     * Look for the '-internalwm' argument
578     */
579    if (IS_OPTION("-internalwm")) {
580        if (!screenInfoPtr->fMultiMonitorOverride)
581            screenInfoPtr->fMultipleMonitors = TRUE;
582        screenInfoPtr->fMWExtWM = TRUE;
583        screenInfoPtr->fInternalWM = TRUE;
584
585        /* Indicate that we have processed this argument */
586        return 1;
587    }
588#endif
589
590    /*
591     * Look for the '-rootless' argument
592     */
593    if (IS_OPTION("-rootless")) {
594#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
595        if (!screenInfoPtr->fMultiMonitorOverride)
596            screenInfoPtr->fMultipleMonitors = FALSE;
597#endif
598        screenInfoPtr->fRootless = TRUE;
599
600        /* Indicate that we have processed this argument */
601        return 1;
602    }
603
604#ifdef XWIN_MULTIWINDOW
605    /*
606     * Look for the '-multiwindow' argument
607     */
608    if (IS_OPTION("-multiwindow")) {
609#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
610        if (!screenInfoPtr->fMultiMonitorOverride)
611            screenInfoPtr->fMultipleMonitors = TRUE;
612#endif
613        screenInfoPtr->fMultiWindow = TRUE;
614
615        /* Indicate that we have processed this argument */
616        return 1;
617    }
618#endif
619
620    /*
621     * Look for the '-multiplemonitors' argument
622     */
623    if (IS_OPTION("-multiplemonitors")
624        || IS_OPTION("-multimonitors")) {
625#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
626        screenInfoPtr->fMultiMonitorOverride = TRUE;
627#endif
628        screenInfoPtr->fMultipleMonitors = TRUE;
629
630        /* Indicate that we have processed this argument */
631        return 1;
632    }
633
634    /*
635     * Look for the '-nomultiplemonitors' argument
636     */
637    if (IS_OPTION("-nomultiplemonitors")
638        || IS_OPTION("-nomultimonitors")) {
639#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
640        screenInfoPtr->fMultiMonitorOverride = TRUE;
641#endif
642        screenInfoPtr->fMultipleMonitors = FALSE;
643
644        /* Indicate that we have processed this argument */
645        return 1;
646    }
647
648    /*
649     * Look for the '-scrollbars' argument
650     */
651    if (IS_OPTION("-scrollbars")) {
652
653        screenInfoPtr->iResizeMode = resizeWithScrollbars;
654
655        /* Indicate that we have processed this argument */
656        return 1;
657    }
658
659    /*
660     * Look for the '-resize' argument
661     */
662    if (IS_OPTION("-resize") || IS_OPTION("-noresize") ||
663        (strncmp(argv[i], "-resize=", strlen("-resize=")) == 0)) {
664        winResizeMode mode;
665
666        if (IS_OPTION("-resize"))
667            mode = resizeWithRandr;
668        else if (IS_OPTION("-noresize"))
669            mode = notAllowed;
670        else if (strncmp(argv[i], "-resize=", strlen("-resize=")) == 0) {
671            char *option = argv[i] + strlen("-resize=");
672
673            if (strcmp(option, "randr") == 0)
674                mode = resizeWithRandr;
675            else if (strcmp(option, "scrollbars") == 0)
676                mode = resizeWithScrollbars;
677            else if (strcmp(option, "none") == 0)
678                mode = notAllowed;
679            else {
680                ErrorF("ddxProcessArgument - resize - Invalid resize mode %s\n",
681                       option);
682                return 0;
683            }
684        }
685        else {
686            ErrorF("ddxProcessArgument - resize - Invalid resize option %s\n",
687                   argv[i]);
688            return 0;
689        }
690
691        screenInfoPtr->iResizeMode = mode;
692
693        /* Indicate that we have processed this argument */
694        return 1;
695    }
696
697#ifdef XWIN_CLIPBOARD
698    /*
699     * Look for the '-clipboard' argument
700     */
701    if (IS_OPTION("-clipboard")) {
702        /* Now the default, we still accept the arg for backwards compatibility */
703        g_fClipboard = TRUE;
704
705        /* Indicate that we have processed this argument */
706        return 1;
707    }
708
709    /*
710     * Look for the '-noclipboard' argument
711     */
712    if (IS_OPTION("-noclipboard")) {
713        g_fClipboard = FALSE;
714
715        /* Indicate that we have processed this argument */
716        return 1;
717    }
718
719    /*
720     * Look for the '-primary' argument
721     */
722    if (IS_OPTION("-primary")) {
723        fPrimarySelection = TRUE;
724
725        /* Indicate that we have processed this argument */
726        return 1;
727    }
728
729    /*
730     * Look for the '-noprimary' argument
731     */
732    if (IS_OPTION("-noprimary")) {
733        fPrimarySelection = FALSE;
734
735        /* Indicate that we have processed this argument */
736        return 1;
737    }
738#endif
739
740    /*
741     * Look for the '-ignoreinput' argument
742     */
743    if (IS_OPTION("-ignoreinput")) {
744        screenInfoPtr->fIgnoreInput = TRUE;
745
746        /* Indicate that we have processed this argument */
747        return 1;
748    }
749
750    /*
751     * Look for the '-emulate3buttons' argument
752     */
753    if (IS_OPTION("-emulate3buttons")) {
754        int iArgsProcessed = 1;
755        int iE3BTimeout = WIN_DEFAULT_E3B_TIME;
756
757        /* Grab the optional timeout value */
758        if (i + 1 < argc && 1 == sscanf(argv[i + 1], "%d", &iE3BTimeout)) {
759            /* Indicate that we have processed the next argument */
760            iArgsProcessed++;
761        }
762        else {
763            /*
764             * sscanf () won't modify iE3BTimeout if it doesn't find
765             * the specified format; however, I want to be explicit
766             * about setting the default timeout in such cases to
767             * prevent some programs (me) from getting confused.
768             */
769            iE3BTimeout = WIN_DEFAULT_E3B_TIME;
770        }
771
772        screenInfoPtr->iE3BTimeout = iE3BTimeout;
773
774        /* Indicate that we have processed this argument */
775        return iArgsProcessed;
776    }
777
778    /*
779     * Look for the '-noemulate3buttons' argument
780     */
781    if (IS_OPTION("-noemulate3buttons")) {
782        screenInfoPtr->iE3BTimeout = WIN_E3B_OFF;
783
784        /* Indicate that we have processed this argument */
785        return 1;
786    }
787
788    /*
789     * Look for the '-depth n' argument
790     */
791    if (IS_OPTION("-depth")) {
792        DWORD dwBPP = 0;
793
794        /* Display the usage message if the argument is malformed */
795        if (++i >= argc) {
796            UseMsg();
797            return 0;
798        }
799
800        /* Grab the argument */
801        dwBPP = atoi(argv[i]);
802
803        screenInfoPtr->dwBPP = dwBPP;
804
805        /* Indicate that we have processed the argument */
806        return 2;
807    }
808
809    /*
810     * Look for the '-refresh n' argument
811     */
812    if (IS_OPTION("-refresh")) {
813        DWORD dwRefreshRate = 0;
814
815        /* Display the usage message if the argument is malformed */
816        if (++i >= argc) {
817            UseMsg();
818            return 0;
819        }
820
821        /* Grab the argument */
822        dwRefreshRate = atoi(argv[i]);
823
824        screenInfoPtr->dwRefreshRate = dwRefreshRate;
825
826        /* Indicate that we have processed the argument */
827        return 2;
828    }
829
830    /*
831     * Look for the '-clipupdates num_boxes' argument
832     */
833    if (IS_OPTION("-clipupdates")) {
834        DWORD dwNumBoxes = 0;
835
836        /* Display the usage message if the argument is malformed */
837        if (++i >= argc) {
838            UseMsg();
839            return 0;
840        }
841
842        /* Grab the argument */
843        dwNumBoxes = atoi(argv[i]);
844
845        screenInfoPtr->dwClipUpdatesNBoxes = dwNumBoxes;
846
847        /* Indicate that we have processed the argument */
848        return 2;
849    }
850
851#ifdef XWIN_EMULATEPSEUDO
852    /*
853     * Look for the '-emulatepseudo' argument
854     */
855    if (IS_OPTION("-emulatepseudo")) {
856        screenInfoPtr->fEmulatePseudo = TRUE;
857
858        /* Indicate that we have processed this argument */
859        return 1;
860    }
861#endif
862
863    /*
864     * Look for the '-nowinkill' argument
865     */
866    if (IS_OPTION("-nowinkill")) {
867        screenInfoPtr->fUseWinKillKey = FALSE;
868
869        /* Indicate that we have processed this argument */
870        return 1;
871    }
872
873    /*
874     * Look for the '-winkill' argument
875     */
876    if (IS_OPTION("-winkill")) {
877        screenInfoPtr->fUseWinKillKey = TRUE;
878
879        /* Indicate that we have processed this argument */
880        return 1;
881    }
882
883    /*
884     * Look for the '-nounixkill' argument
885     */
886    if (IS_OPTION("-nounixkill")) {
887        screenInfoPtr->fUseUnixKillKey = FALSE;
888
889        /* Indicate that we have processed this argument */
890        return 1;
891    }
892
893    /*
894     * Look for the '-unixkill' argument
895     */
896    if (IS_OPTION("-unixkill")) {
897        screenInfoPtr->fUseUnixKillKey = TRUE;
898
899        /* Indicate that we have processed this argument */
900        return 1;
901    }
902
903    /*
904     * Look for the '-notrayicon' argument
905     */
906    if (IS_OPTION("-notrayicon")) {
907        screenInfoPtr->fNoTrayIcon = TRUE;
908
909        /* Indicate that we have processed this argument */
910        return 1;
911    }
912
913    /*
914     * Look for the '-trayicon' argument
915     */
916    if (IS_OPTION("-trayicon")) {
917        screenInfoPtr->fNoTrayIcon = FALSE;
918
919        /* Indicate that we have processed this argument */
920        return 1;
921    }
922
923    /*
924     * Look for the '-fp' argument
925     */
926    if (IS_OPTION("-fp")) {
927        CHECK_ARGS(1);
928        g_cmdline.fontPath = argv[++i];
929        return 0;               /* Let DIX parse this again */
930    }
931
932    /*
933     * Look for the '-query' argument
934     */
935    if (IS_OPTION("-query")) {
936        CHECK_ARGS(1);
937        g_fXdmcpEnabled = TRUE;
938        g_pszQueryHost = argv[++i];
939        return 0;               /* Let DIX parse this again */
940    }
941
942    /*
943     * Look for the '-auth' argument
944     */
945    if (IS_OPTION("-auth")) {
946        g_fAuthEnabled = TRUE;
947        return 0;               /* Let DIX parse this again */
948    }
949
950    /*
951     * Look for the '-indirect' or '-broadcast' arguments
952     */
953    if (IS_OPTION("-indirect")
954        || IS_OPTION("-broadcast")) {
955        g_fXdmcpEnabled = TRUE;
956        return 0;               /* Let DIX parse this again */
957    }
958
959    /*
960     * Look for the '-config' argument
961     */
962    if (IS_OPTION("-config")
963        || IS_OPTION("-xf86config")) {
964        CHECK_ARGS(1);
965#ifdef XWIN_XF86CONFIG
966        g_cmdline.configFile = argv[++i];
967#else
968        winMessageBoxF("The %s option is not supported in this "
969                       "release.\n"
970                       "Ignoring this option and continuing.\n",
971                       MB_ICONINFORMATION, argv[i]);
972#endif
973        return 2;
974    }
975
976    /*
977     * Look for the '-configdir' argument
978     */
979    if (IS_OPTION("-configdir")) {
980        CHECK_ARGS(1);
981#ifdef XWIN_XF86CONFIG
982        g_cmdline.configDir = argv[++i];
983#else
984        winMessageBoxF("The %s option is not supported in this "
985                       "release.\n"
986                       "Ignoring this option and continuing.\n",
987                       MB_ICONINFORMATION, argv[i]);
988#endif
989        return 2;
990    }
991
992    /*
993     * Look for the '-keyboard' argument
994     */
995    if (IS_OPTION("-keyboard")) {
996#ifdef XWIN_XF86CONFIG
997        CHECK_ARGS(1);
998        g_cmdline.keyboard = argv[++i];
999#else
1000        winMessageBoxF("The -keyboard option is not supported in this "
1001                       "release.\n"
1002                       "Ignoring this option and continuing.\n",
1003                       MB_ICONINFORMATION);
1004#endif
1005        return 2;
1006    }
1007
1008    /*
1009     * Look for the '-logfile' argument
1010     */
1011    if (IS_OPTION("-logfile")) {
1012        CHECK_ARGS(1);
1013        g_pszLogFile = argv[++i];
1014#ifdef RELOCATE_PROJECTROOT
1015        g_fLogFileChanged = TRUE;
1016#endif
1017        return 2;
1018    }
1019
1020    /*
1021     * Look for the '-logverbose' argument
1022     */
1023    if (IS_OPTION("-logverbose")) {
1024        CHECK_ARGS(1);
1025        g_iLogVerbose = atoi(argv[++i]);
1026        return 2;
1027    }
1028
1029#ifdef XWIN_CLIPBOARD
1030    /*
1031     * Look for the '-nounicodeclipboard' argument
1032     */
1033    if (IS_OPTION("-nounicodeclipboard")) {
1034        g_fUnicodeClipboard = FALSE;
1035        /* Indicate that we have processed the argument */
1036        return 1;
1037    }
1038#endif
1039
1040    if (IS_OPTION("-xkbrules")) {
1041        CHECK_ARGS(1);
1042        g_cmdline.xkbRules = argv[++i];
1043        return 2;
1044    }
1045    if (IS_OPTION("-xkbmodel")) {
1046        CHECK_ARGS(1);
1047        g_cmdline.xkbModel = argv[++i];
1048        return 2;
1049    }
1050    if (IS_OPTION("-xkblayout")) {
1051        CHECK_ARGS(1);
1052        g_cmdline.xkbLayout = argv[++i];
1053        return 2;
1054    }
1055    if (IS_OPTION("-xkbvariant")) {
1056        CHECK_ARGS(1);
1057        g_cmdline.xkbVariant = argv[++i];
1058        return 2;
1059    }
1060    if (IS_OPTION("-xkboptions")) {
1061        CHECK_ARGS(1);
1062        g_cmdline.xkbOptions = argv[++i];
1063        return 2;
1064    }
1065
1066    if (IS_OPTION("-keyhook")) {
1067        g_fKeyboardHookLL = TRUE;
1068        return 1;
1069    }
1070
1071    if (IS_OPTION("-nokeyhook")) {
1072        g_fKeyboardHookLL = FALSE;
1073        return 1;
1074    }
1075
1076    if (IS_OPTION("-swcursor")) {
1077        g_fSoftwareCursor = TRUE;
1078        return 1;
1079    }
1080
1081    if (IS_OPTION("-silent-dup-error")) {
1082        g_fSilentDupError = TRUE;
1083        return 1;
1084    }
1085
1086    if (IS_OPTION("-wgl")) {
1087        g_fNativeGl = TRUE;
1088        return 1;
1089    }
1090
1091    if (IS_OPTION("-nowgl")) {
1092        g_fNativeGl = FALSE;
1093        return 1;
1094    }
1095
1096    if (IS_OPTION("-hostintitle")) {
1097        g_fHostInTitle = TRUE;
1098        return 1;
1099    }
1100
1101    if (IS_OPTION("-nohostintitle")) {
1102        g_fHostInTitle = FALSE;
1103        return 1;
1104    }
1105
1106    return 0;
1107}
1108
1109/*
1110 * winLogCommandLine - Write entire command line to the log file
1111 */
1112
1113void
1114winLogCommandLine(int argc, char *argv[])
1115{
1116    int i;
1117    int iSize = 0;
1118    int iCurrLen = 0;
1119
1120#define CHARS_PER_LINE 60
1121
1122    /* Bail if command line has already been logged */
1123    if (g_pszCommandLine)
1124        return;
1125
1126    /* Count how much memory is needed for concatenated command line */
1127    for (i = 0, iCurrLen = 0; i < argc; ++i)
1128        if (argv[i]) {
1129            /* Adds two characters for lines that overflow */
1130            if ((strlen(argv[i]) < CHARS_PER_LINE
1131                 && iCurrLen + strlen(argv[i]) > CHARS_PER_LINE)
1132                || strlen(argv[i]) > CHARS_PER_LINE) {
1133                iCurrLen = 0;
1134                iSize += 2;
1135            }
1136
1137            /* Add space for item and trailing space */
1138            iSize += strlen(argv[i]) + 1;
1139
1140            /* Update current line length */
1141            iCurrLen += strlen(argv[i]);
1142        }
1143
1144    /* Allocate memory for concatenated command line */
1145    g_pszCommandLine = malloc(iSize + 1);
1146    if (!g_pszCommandLine)
1147        FatalError("winLogCommandLine - Could not allocate memory for "
1148                   "command line string.  Exiting.\n");
1149
1150    /* Set first character to concatenated command line to null */
1151    g_pszCommandLine[0] = '\0';
1152
1153    /* Loop through all args */
1154    for (i = 0, iCurrLen = 0; i < argc; ++i) {
1155        /* Add a character for lines that overflow */
1156        if ((strlen(argv[i]) < CHARS_PER_LINE
1157             && iCurrLen + strlen(argv[i]) > CHARS_PER_LINE)
1158            || strlen(argv[i]) > CHARS_PER_LINE) {
1159            iCurrLen = 0;
1160
1161            /* Add line break if it fits */
1162            strncat(g_pszCommandLine, "\n ", iSize - strlen(g_pszCommandLine));
1163        }
1164
1165        strncat(g_pszCommandLine, argv[i], iSize - strlen(g_pszCommandLine));
1166        strncat(g_pszCommandLine, " ", iSize - strlen(g_pszCommandLine));
1167
1168        /* Save new line length */
1169        iCurrLen += strlen(argv[i]);
1170    }
1171
1172    ErrorF("XWin was started with the following command line:\n\n"
1173           "%s\n\n", g_pszCommandLine);
1174}
1175
1176/*
1177 * winLogVersionInfo - Log version information
1178 */
1179
1180void
1181winLogVersionInfo(void)
1182{
1183    static Bool s_fBeenHere = FALSE;
1184
1185    if (s_fBeenHere)
1186        return;
1187    s_fBeenHere = TRUE;
1188
1189    ErrorF("Welcome to the XWin X Server\n");
1190    ErrorF("Vendor: %s\n", XVENDORNAME);
1191    ErrorF("Release: %d.%d.%d.%d\n", XORG_VERSION_MAJOR,
1192           XORG_VERSION_MINOR, XORG_VERSION_PATCH, XORG_VERSION_SNAP);
1193#ifdef HAVE_SYS_UTSNAME_H
1194    {
1195        struct utsname name;
1196
1197        if (uname(&name) >= 0) {
1198            ErrorF("OS: %s %s %s %s %s\n", name.sysname, name.nodename,
1199                   name.release, name.version, name.machine);
1200        }
1201    }
1202#endif
1203    winOS();
1204    if (strlen(BUILDERSTRING))
1205        ErrorF("%s\n", BUILDERSTRING);
1206    ErrorF("Contact: %s\n", BUILDERADDR);
1207    ErrorF("\n");
1208}
1209