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