1*4882a593Smuzhiyun
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun
4*4882a593Smuzhiyun Copyright 1993, 1998 The Open Group
5*4882a593Smuzhiyun Copyright (C) Colin Harrison 2005-2008
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun Permission to use, copy, modify, distribute, and sell this software and its
8*4882a593Smuzhiyun documentation for any purpose is hereby granted without fee, provided that
9*4882a593Smuzhiyun the above copyright notice appear in all copies and that both that
10*4882a593Smuzhiyun copyright notice and this permission notice appear in supporting
11*4882a593Smuzhiyun documentation.
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun The above copyright notice and this permission notice shall be included
14*4882a593Smuzhiyun in all copies or substantial portions of the Software.
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17*4882a593Smuzhiyun OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18*4882a593Smuzhiyun MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19*4882a593Smuzhiyun IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
20*4882a593Smuzhiyun OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21*4882a593Smuzhiyun ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22*4882a593Smuzhiyun OTHER DEALINGS IN THE SOFTWARE.
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun Except as contained in this notice, the name of The Open Group shall
25*4882a593Smuzhiyun not be used in advertising or otherwise to promote the sale, use or
26*4882a593Smuzhiyun other dealings in this Software without prior written authorization
27*4882a593Smuzhiyun from The Open Group.
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun */
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #ifdef HAVE_XWIN_CONFIG_H
32*4882a593Smuzhiyun #include <xwin-config.h>
33*4882a593Smuzhiyun #endif
34*4882a593Smuzhiyun #include "win.h"
35*4882a593Smuzhiyun #include "winmsg.h"
36*4882a593Smuzhiyun #include "winconfig.h"
37*4882a593Smuzhiyun #include "winprefs.h"
38*4882a593Smuzhiyun #include "X11/Xlocale.h"
39*4882a593Smuzhiyun #ifdef DPMSExtension
40*4882a593Smuzhiyun #include "dpmsproc.h"
41*4882a593Smuzhiyun #endif
42*4882a593Smuzhiyun #ifdef __CYGWIN__
43*4882a593Smuzhiyun #include <mntent.h>
44*4882a593Smuzhiyun #endif
45*4882a593Smuzhiyun #if defined(WIN32)
46*4882a593Smuzhiyun #include "xkbsrv.h"
47*4882a593Smuzhiyun #endif
48*4882a593Smuzhiyun #ifdef RELOCATE_PROJECTROOT
49*4882a593Smuzhiyun #pragma push_macro("Status")
50*4882a593Smuzhiyun #undef Status
51*4882a593Smuzhiyun #define Status wStatus
52*4882a593Smuzhiyun #include <shlobj.h>
53*4882a593Smuzhiyun #pragma pop_macro("Status")
54*4882a593Smuzhiyun typedef WINAPI HRESULT(*SHGETFOLDERPATHPROC) (HWND hwndOwner,
55*4882a593Smuzhiyun int nFolder,
56*4882a593Smuzhiyun HANDLE hToken,
57*4882a593Smuzhiyun DWORD dwFlags, LPTSTR pszPath);
58*4882a593Smuzhiyun #endif
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun #include "winmonitors.h"
61*4882a593Smuzhiyun #include "nonsdk_extinit.h"
62*4882a593Smuzhiyun #include "pseudoramiX/pseudoramiX.h"
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun #include "glx_extinit.h"
65*4882a593Smuzhiyun #ifdef XWIN_GLX_WINDOWS
66*4882a593Smuzhiyun #include "glx/glwindows.h"
67*4882a593Smuzhiyun #include "dri/windowsdri.h"
68*4882a593Smuzhiyun #endif
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun /*
71*4882a593Smuzhiyun * References to external symbols
72*4882a593Smuzhiyun */
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun /*
75*4882a593Smuzhiyun * Function prototypes
76*4882a593Smuzhiyun */
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun void
79*4882a593Smuzhiyun winLogCommandLine(int argc, char *argv[]);
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun void
82*4882a593Smuzhiyun winLogVersionInfo(void);
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun Bool
85*4882a593Smuzhiyun winValidateArgs(void);
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun #ifdef RELOCATE_PROJECTROOT
88*4882a593Smuzhiyun const char *winGetBaseDir(void);
89*4882a593Smuzhiyun #endif
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun /*
92*4882a593Smuzhiyun * For the depth 24 pixmap we default to 32 bits per pixel, but
93*4882a593Smuzhiyun * we change this pixmap format later if we detect that the display
94*4882a593Smuzhiyun * is going to be running at 24 bits per pixel.
95*4882a593Smuzhiyun *
96*4882a593Smuzhiyun * FIXME: On second thought, don't DIBs only support 32 bits per pixel?
97*4882a593Smuzhiyun * DIBs are the underlying bitmap used for DirectDraw surfaces, so it
98*4882a593Smuzhiyun * seems that all pixmap formats with depth 24 would be 32 bits per pixel.
99*4882a593Smuzhiyun * Confirm whether depth 24 DIBs can have 24 bits per pixel, then remove/keep
100*4882a593Smuzhiyun * the bits per pixel adjustment and update this comment to reflect the
101*4882a593Smuzhiyun * situation. Harold Hunt - 2002/07/02
102*4882a593Smuzhiyun */
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun static PixmapFormatRec g_PixmapFormats[] = {
105*4882a593Smuzhiyun {1, 1, BITMAP_SCANLINE_PAD},
106*4882a593Smuzhiyun {4, 8, BITMAP_SCANLINE_PAD},
107*4882a593Smuzhiyun {8, 8, BITMAP_SCANLINE_PAD},
108*4882a593Smuzhiyun {15, 16, BITMAP_SCANLINE_PAD},
109*4882a593Smuzhiyun {16, 16, BITMAP_SCANLINE_PAD},
110*4882a593Smuzhiyun {24, 32, BITMAP_SCANLINE_PAD},
111*4882a593Smuzhiyun {32, 32, BITMAP_SCANLINE_PAD}
112*4882a593Smuzhiyun };
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun static const ExtensionModule xwinExtensions[] = {
115*4882a593Smuzhiyun #ifdef GLXEXT
116*4882a593Smuzhiyun #ifdef XWIN_WINDOWS_DRI
117*4882a593Smuzhiyun { WindowsDRIExtensionInit, "Windows-DRI", &noDriExtension },
118*4882a593Smuzhiyun #endif
119*4882a593Smuzhiyun #endif
120*4882a593Smuzhiyun };
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun /*
123*4882a593Smuzhiyun * XwinExtensionInit
124*4882a593Smuzhiyun * Initialises Xwin-specific extensions.
125*4882a593Smuzhiyun */
126*4882a593Smuzhiyun static
XwinExtensionInit(void)127*4882a593Smuzhiyun void XwinExtensionInit(void)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun #ifdef XWIN_GLX_WINDOWS
130*4882a593Smuzhiyun if (g_fNativeGl) {
131*4882a593Smuzhiyun /* install the native GL provider */
132*4882a593Smuzhiyun glxWinPushNativeProvider();
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun #endif
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun LoadExtensionList(xwinExtensions, ARRAY_SIZE(xwinExtensions), TRUE);
137*4882a593Smuzhiyun }
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun #if defined(DDXBEFORERESET)
140*4882a593Smuzhiyun /*
141*4882a593Smuzhiyun * Called right before KillAllClients when the server is going to reset,
142*4882a593Smuzhiyun * allows us to shutdown our seperate threads cleanly.
143*4882a593Smuzhiyun */
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun void
ddxBeforeReset(void)146*4882a593Smuzhiyun ddxBeforeReset(void)
147*4882a593Smuzhiyun {
148*4882a593Smuzhiyun winDebug("ddxBeforeReset - Hello\n");
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun winClipboardShutdown();
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun #endif
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun #if INPUTTHREAD
155*4882a593Smuzhiyun /** This function is called in Xserver/os/inputthread.c when starting
156*4882a593Smuzhiyun the input thread. */
157*4882a593Smuzhiyun void
ddxInputThreadInit(void)158*4882a593Smuzhiyun ddxInputThreadInit(void)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun #endif
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun int
main(int argc,char * argv[],char * envp[])164*4882a593Smuzhiyun main(int argc, char *argv[], char *envp[])
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun int iReturn;
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun /* Create & acquire the termination mutex */
169*4882a593Smuzhiyun iReturn = pthread_mutex_init(&g_pmTerminating, NULL);
170*4882a593Smuzhiyun if (iReturn != 0) {
171*4882a593Smuzhiyun ErrorF("ddxMain - pthread_mutex_init () failed: %d\n", iReturn);
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun iReturn = pthread_mutex_lock(&g_pmTerminating);
175*4882a593Smuzhiyun if (iReturn != 0) {
176*4882a593Smuzhiyun ErrorF("ddxMain - pthread_mutex_lock () failed: %d\n", iReturn);
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun return dix_main(argc, argv, envp);
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun /* See Porting Layer Definition - p. 57 */
183*4882a593Smuzhiyun void
ddxGiveUp(enum ExitCode error)184*4882a593Smuzhiyun ddxGiveUp(enum ExitCode error)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun int i;
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun #if CYGDEBUG
189*4882a593Smuzhiyun winDebug("ddxGiveUp\n");
190*4882a593Smuzhiyun #endif
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun /* Perform per-screen deinitialization */
193*4882a593Smuzhiyun for (i = 0; i < g_iNumScreens; ++i) {
194*4882a593Smuzhiyun /* Delete the tray icon */
195*4882a593Smuzhiyun if (!g_ScreenInfo[i].fNoTrayIcon && g_ScreenInfo[i].pScreen)
196*4882a593Smuzhiyun winDeleteNotifyIcon(winGetScreenPriv(g_ScreenInfo[i].pScreen));
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun /* Unload libraries for taskbar grouping */
200*4882a593Smuzhiyun winPropertyStoreDestroy();
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun /* Notify the worker threads we're exiting */
203*4882a593Smuzhiyun winDeinitMultiWindowWM();
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun #ifdef HAS_DEVWINDOWS
206*4882a593Smuzhiyun /* Close our handle to our message queue */
207*4882a593Smuzhiyun if (g_fdMessageQueue != WIN_FD_INVALID) {
208*4882a593Smuzhiyun /* Close /dev/windows */
209*4882a593Smuzhiyun close(g_fdMessageQueue);
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun /* Set the file handle to invalid */
212*4882a593Smuzhiyun g_fdMessageQueue = WIN_FD_INVALID;
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun #endif
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun if (!g_fLogInited) {
217*4882a593Smuzhiyun g_pszLogFile = LogInit(g_pszLogFile, ".old");
218*4882a593Smuzhiyun g_fLogInited = TRUE;
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun LogClose(error);
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun /*
223*4882a593Smuzhiyun * At this point we aren't creating any new screens, so
224*4882a593Smuzhiyun * we are guaranteed to not need the DirectDraw functions.
225*4882a593Smuzhiyun */
226*4882a593Smuzhiyun winReleaseDDProcAddresses();
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun /* Free concatenated command line */
229*4882a593Smuzhiyun free(g_pszCommandLine);
230*4882a593Smuzhiyun g_pszCommandLine = NULL;
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun /* Remove our keyboard hook if it is installed */
233*4882a593Smuzhiyun winRemoveKeyboardHookLL();
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun /* Tell Windows that we want to end the app */
236*4882a593Smuzhiyun PostQuitMessage(0);
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun {
239*4882a593Smuzhiyun int iReturn = pthread_mutex_unlock(&g_pmTerminating);
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun winDebug("ddxGiveUp - Releasing termination mutex\n");
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun if (iReturn != 0) {
244*4882a593Smuzhiyun ErrorF("winMsgWindowProc - pthread_mutex_unlock () failed: %d\n",
245*4882a593Smuzhiyun iReturn);
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun winDebug("ddxGiveUp - End\n");
250*4882a593Smuzhiyun }
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun /* See Porting Layer Definition - p. 57 */
253*4882a593Smuzhiyun void
AbortDDX(enum ExitCode error)254*4882a593Smuzhiyun AbortDDX(enum ExitCode error)
255*4882a593Smuzhiyun {
256*4882a593Smuzhiyun #if CYGDEBUG
257*4882a593Smuzhiyun winDebug("AbortDDX\n");
258*4882a593Smuzhiyun #endif
259*4882a593Smuzhiyun ddxGiveUp(error);
260*4882a593Smuzhiyun }
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun #ifdef __CYGWIN__
263*4882a593Smuzhiyun /* hasmntopt is currently not implemented for cygwin */
264*4882a593Smuzhiyun static const char *
winCheckMntOpt(const struct mntent * mnt,const char * opt)265*4882a593Smuzhiyun winCheckMntOpt(const struct mntent *mnt, const char *opt)
266*4882a593Smuzhiyun {
267*4882a593Smuzhiyun const char *s;
268*4882a593Smuzhiyun size_t len;
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun if (mnt == NULL)
271*4882a593Smuzhiyun return NULL;
272*4882a593Smuzhiyun if (opt == NULL)
273*4882a593Smuzhiyun return NULL;
274*4882a593Smuzhiyun if (mnt->mnt_opts == NULL)
275*4882a593Smuzhiyun return NULL;
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun len = strlen(opt);
278*4882a593Smuzhiyun s = strstr(mnt->mnt_opts, opt);
279*4882a593Smuzhiyun if (s == NULL)
280*4882a593Smuzhiyun return NULL;
281*4882a593Smuzhiyun if ((s == mnt->mnt_opts || *(s - 1) == ',') &&
282*4882a593Smuzhiyun (s[len] == 0 || s[len] == ','))
283*4882a593Smuzhiyun return (char *) opt;
284*4882a593Smuzhiyun return NULL;
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun static void
winCheckMount(void)288*4882a593Smuzhiyun winCheckMount(void)
289*4882a593Smuzhiyun {
290*4882a593Smuzhiyun FILE *mnt;
291*4882a593Smuzhiyun struct mntent *ent;
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun enum { none = 0, sys_root, user_root, sys_tmp, user_tmp }
294*4882a593Smuzhiyun level = none, curlevel;
295*4882a593Smuzhiyun BOOL binary = TRUE;
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun mnt = setmntent("/etc/mtab", "r");
298*4882a593Smuzhiyun if (mnt == NULL) {
299*4882a593Smuzhiyun ErrorF("setmntent failed");
300*4882a593Smuzhiyun return;
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun while ((ent = getmntent(mnt)) != NULL) {
304*4882a593Smuzhiyun BOOL sys = (winCheckMntOpt(ent, "user") != NULL);
305*4882a593Smuzhiyun BOOL root = (strcmp(ent->mnt_dir, "/") == 0);
306*4882a593Smuzhiyun BOOL tmp = (strcmp(ent->mnt_dir, "/tmp") == 0);
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun if (sys) {
309*4882a593Smuzhiyun if (root)
310*4882a593Smuzhiyun curlevel = sys_root;
311*4882a593Smuzhiyun else if (tmp)
312*4882a593Smuzhiyun curlevel = sys_tmp;
313*4882a593Smuzhiyun else
314*4882a593Smuzhiyun continue;
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun else {
317*4882a593Smuzhiyun if (root)
318*4882a593Smuzhiyun curlevel = user_root;
319*4882a593Smuzhiyun else if (tmp)
320*4882a593Smuzhiyun curlevel = user_tmp;
321*4882a593Smuzhiyun else
322*4882a593Smuzhiyun continue;
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun if (curlevel <= level)
326*4882a593Smuzhiyun continue;
327*4882a593Smuzhiyun level = curlevel;
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun if ((winCheckMntOpt(ent, "binary") == NULL) &&
330*4882a593Smuzhiyun (winCheckMntOpt(ent, "binmode") == NULL))
331*4882a593Smuzhiyun binary = FALSE;
332*4882a593Smuzhiyun else
333*4882a593Smuzhiyun binary = TRUE;
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun if (endmntent(mnt) != 1) {
337*4882a593Smuzhiyun ErrorF("endmntent failed");
338*4882a593Smuzhiyun return;
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun if (!binary)
342*4882a593Smuzhiyun winMsg(X_WARNING, "/tmp mounted in textmode\n");
343*4882a593Smuzhiyun }
344*4882a593Smuzhiyun #else
345*4882a593Smuzhiyun static void
winCheckMount(void)346*4882a593Smuzhiyun winCheckMount(void)
347*4882a593Smuzhiyun {
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun #endif
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun #ifdef RELOCATE_PROJECTROOT
352*4882a593Smuzhiyun const char *
winGetBaseDir(void)353*4882a593Smuzhiyun winGetBaseDir(void)
354*4882a593Smuzhiyun {
355*4882a593Smuzhiyun static BOOL inited = FALSE;
356*4882a593Smuzhiyun static char buffer[MAX_PATH];
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun if (!inited) {
359*4882a593Smuzhiyun char *fendptr;
360*4882a593Smuzhiyun HMODULE module = GetModuleHandle(NULL);
361*4882a593Smuzhiyun DWORD size = GetModuleFileName(module, buffer, sizeof(buffer));
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun if (sizeof(buffer) > 0)
364*4882a593Smuzhiyun buffer[sizeof(buffer) - 1] = 0;
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun fendptr = buffer + size;
367*4882a593Smuzhiyun while (fendptr > buffer) {
368*4882a593Smuzhiyun if (*fendptr == '\\' || *fendptr == '/') {
369*4882a593Smuzhiyun *fendptr = 0;
370*4882a593Smuzhiyun break;
371*4882a593Smuzhiyun }
372*4882a593Smuzhiyun fendptr--;
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun inited = TRUE;
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun return buffer;
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun #endif
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun static void
winFixupPaths(void)381*4882a593Smuzhiyun winFixupPaths(void)
382*4882a593Smuzhiyun {
383*4882a593Smuzhiyun BOOL changed_fontpath = FALSE;
384*4882a593Smuzhiyun MessageType font_from = X_DEFAULT;
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun #ifdef RELOCATE_PROJECTROOT
387*4882a593Smuzhiyun const char *basedir = winGetBaseDir();
388*4882a593Smuzhiyun size_t basedirlen = strlen(basedir);
389*4882a593Smuzhiyun #endif
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun #ifdef READ_FONTDIRS
392*4882a593Smuzhiyun {
393*4882a593Smuzhiyun /* Open fontpath configuration file */
394*4882a593Smuzhiyun FILE *fontdirs = fopen(ETCX11DIR "/font-dirs", "rt");
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun if (fontdirs != NULL) {
397*4882a593Smuzhiyun char buffer[256];
398*4882a593Smuzhiyun int needs_sep = TRUE;
399*4882a593Smuzhiyun int comment_block = FALSE;
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun /* get default fontpath */
402*4882a593Smuzhiyun char *fontpath = strdup(defaultFontPath);
403*4882a593Smuzhiyun size_t size = strlen(fontpath);
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun /* read all lines */
406*4882a593Smuzhiyun while (!feof(fontdirs)) {
407*4882a593Smuzhiyun size_t blen;
408*4882a593Smuzhiyun char *hashchar;
409*4882a593Smuzhiyun char *str;
410*4882a593Smuzhiyun int has_eol = FALSE;
411*4882a593Smuzhiyun
412*4882a593Smuzhiyun /* read one line */
413*4882a593Smuzhiyun str = fgets(buffer, sizeof(buffer), fontdirs);
414*4882a593Smuzhiyun if (str == NULL) /* stop on error or eof */
415*4882a593Smuzhiyun break;
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun if (strchr(str, '\n') != NULL)
418*4882a593Smuzhiyun has_eol = TRUE;
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun /* check if block is continued comment */
421*4882a593Smuzhiyun if (comment_block) {
422*4882a593Smuzhiyun /* ignore all input */
423*4882a593Smuzhiyun *str = 0;
424*4882a593Smuzhiyun blen = 0;
425*4882a593Smuzhiyun if (has_eol) /* check if line ended in this block */
426*4882a593Smuzhiyun comment_block = FALSE;
427*4882a593Smuzhiyun }
428*4882a593Smuzhiyun else {
429*4882a593Smuzhiyun /* find comment character. ignore all trailing input */
430*4882a593Smuzhiyun hashchar = strchr(str, '#');
431*4882a593Smuzhiyun if (hashchar != NULL) {
432*4882a593Smuzhiyun *hashchar = 0;
433*4882a593Smuzhiyun if (!has_eol) /* mark next block as continued comment */
434*4882a593Smuzhiyun comment_block = TRUE;
435*4882a593Smuzhiyun }
436*4882a593Smuzhiyun }
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun /* strip whitespaces from beginning */
439*4882a593Smuzhiyun while (*str == ' ' || *str == '\t')
440*4882a593Smuzhiyun str++;
441*4882a593Smuzhiyun
442*4882a593Smuzhiyun /* get size, strip whitespaces from end */
443*4882a593Smuzhiyun blen = strlen(str);
444*4882a593Smuzhiyun while (blen > 0 && (str[blen - 1] == ' ' ||
445*4882a593Smuzhiyun str[blen - 1] == '\t' ||
446*4882a593Smuzhiyun str[blen - 1] == '\n')) {
447*4882a593Smuzhiyun str[--blen] = 0;
448*4882a593Smuzhiyun }
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun /* still something left to add? */
451*4882a593Smuzhiyun if (blen > 0) {
452*4882a593Smuzhiyun size_t newsize = size + blen;
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun /* reserve one character more for ',' */
455*4882a593Smuzhiyun if (needs_sep)
456*4882a593Smuzhiyun newsize++;
457*4882a593Smuzhiyun
458*4882a593Smuzhiyun /* allocate memory */
459*4882a593Smuzhiyun if (fontpath == NULL)
460*4882a593Smuzhiyun fontpath = malloc(newsize + 1);
461*4882a593Smuzhiyun else
462*4882a593Smuzhiyun fontpath = realloc(fontpath, newsize + 1);
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun /* add separator */
465*4882a593Smuzhiyun if (needs_sep) {
466*4882a593Smuzhiyun fontpath[size] = ',';
467*4882a593Smuzhiyun size++;
468*4882a593Smuzhiyun needs_sep = FALSE;
469*4882a593Smuzhiyun }
470*4882a593Smuzhiyun
471*4882a593Smuzhiyun /* mark next line as new entry */
472*4882a593Smuzhiyun if (has_eol)
473*4882a593Smuzhiyun needs_sep = TRUE;
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun /* add block */
476*4882a593Smuzhiyun strncpy(fontpath + size, str, blen);
477*4882a593Smuzhiyun fontpath[newsize] = 0;
478*4882a593Smuzhiyun size = newsize;
479*4882a593Smuzhiyun }
480*4882a593Smuzhiyun }
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun /* cleanup */
483*4882a593Smuzhiyun fclose(fontdirs);
484*4882a593Smuzhiyun defaultFontPath = strdup(fontpath);
485*4882a593Smuzhiyun free(fontpath);
486*4882a593Smuzhiyun changed_fontpath = TRUE;
487*4882a593Smuzhiyun font_from = X_CONFIG;
488*4882a593Smuzhiyun }
489*4882a593Smuzhiyun }
490*4882a593Smuzhiyun #endif /* READ_FONTDIRS */
491*4882a593Smuzhiyun #ifdef RELOCATE_PROJECTROOT
492*4882a593Smuzhiyun {
493*4882a593Smuzhiyun const char *libx11dir = PROJECTROOT "/lib/X11";
494*4882a593Smuzhiyun size_t libx11dir_len = strlen(libx11dir);
495*4882a593Smuzhiyun char *newfp = NULL;
496*4882a593Smuzhiyun size_t newfp_len = 0;
497*4882a593Smuzhiyun const char *endptr, *ptr, *oldptr = defaultFontPath;
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun endptr = oldptr + strlen(oldptr);
500*4882a593Smuzhiyun ptr = strchr(oldptr, ',');
501*4882a593Smuzhiyun if (ptr == NULL)
502*4882a593Smuzhiyun ptr = endptr;
503*4882a593Smuzhiyun while (ptr != NULL) {
504*4882a593Smuzhiyun size_t oldfp_len = (ptr - oldptr);
505*4882a593Smuzhiyun size_t newsize = oldfp_len;
506*4882a593Smuzhiyun char *newpath = malloc(newsize + 1);
507*4882a593Smuzhiyun
508*4882a593Smuzhiyun strncpy(newpath, oldptr, newsize);
509*4882a593Smuzhiyun newpath[newsize] = 0;
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun if (strncmp(libx11dir, newpath, libx11dir_len) == 0) {
512*4882a593Smuzhiyun char *compose;
513*4882a593Smuzhiyun
514*4882a593Smuzhiyun newsize = newsize - libx11dir_len + basedirlen;
515*4882a593Smuzhiyun compose = malloc(newsize + 1);
516*4882a593Smuzhiyun strcpy(compose, basedir);
517*4882a593Smuzhiyun strncat(compose, newpath + libx11dir_len, newsize - basedirlen);
518*4882a593Smuzhiyun compose[newsize] = 0;
519*4882a593Smuzhiyun free(newpath);
520*4882a593Smuzhiyun newpath = compose;
521*4882a593Smuzhiyun }
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun oldfp_len = newfp_len;
524*4882a593Smuzhiyun if (oldfp_len > 0)
525*4882a593Smuzhiyun newfp_len++; /* space for separator */
526*4882a593Smuzhiyun newfp_len += newsize;
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun if (newfp == NULL)
529*4882a593Smuzhiyun newfp = malloc(newfp_len + 1);
530*4882a593Smuzhiyun else
531*4882a593Smuzhiyun newfp = realloc(newfp, newfp_len + 1);
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun if (oldfp_len > 0) {
534*4882a593Smuzhiyun strcpy(newfp + oldfp_len, ",");
535*4882a593Smuzhiyun oldfp_len++;
536*4882a593Smuzhiyun }
537*4882a593Smuzhiyun strcpy(newfp + oldfp_len, newpath);
538*4882a593Smuzhiyun
539*4882a593Smuzhiyun free(newpath);
540*4882a593Smuzhiyun
541*4882a593Smuzhiyun if (*ptr == 0) {
542*4882a593Smuzhiyun oldptr = ptr;
543*4882a593Smuzhiyun ptr = NULL;
544*4882a593Smuzhiyun }
545*4882a593Smuzhiyun else {
546*4882a593Smuzhiyun oldptr = ptr + 1;
547*4882a593Smuzhiyun ptr = strchr(oldptr, ',');
548*4882a593Smuzhiyun if (ptr == NULL)
549*4882a593Smuzhiyun ptr = endptr;
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun }
552*4882a593Smuzhiyun
553*4882a593Smuzhiyun defaultFontPath = strdup(newfp);
554*4882a593Smuzhiyun free(newfp);
555*4882a593Smuzhiyun changed_fontpath = TRUE;
556*4882a593Smuzhiyun }
557*4882a593Smuzhiyun #endif /* RELOCATE_PROJECTROOT */
558*4882a593Smuzhiyun if (changed_fontpath)
559*4882a593Smuzhiyun winMsg(font_from, "FontPath set to \"%s\"\n", defaultFontPath);
560*4882a593Smuzhiyun
561*4882a593Smuzhiyun #ifdef RELOCATE_PROJECTROOT
562*4882a593Smuzhiyun if (getenv("XKEYSYMDB") == NULL) {
563*4882a593Smuzhiyun char buffer[MAX_PATH];
564*4882a593Smuzhiyun
565*4882a593Smuzhiyun snprintf(buffer, sizeof(buffer), "XKEYSYMDB=%s\\XKeysymDB", basedir);
566*4882a593Smuzhiyun buffer[sizeof(buffer) - 1] = 0;
567*4882a593Smuzhiyun putenv(buffer);
568*4882a593Smuzhiyun }
569*4882a593Smuzhiyun if (getenv("XERRORDB") == NULL) {
570*4882a593Smuzhiyun char buffer[MAX_PATH];
571*4882a593Smuzhiyun
572*4882a593Smuzhiyun snprintf(buffer, sizeof(buffer), "XERRORDB=%s\\XErrorDB", basedir);
573*4882a593Smuzhiyun buffer[sizeof(buffer) - 1] = 0;
574*4882a593Smuzhiyun putenv(buffer);
575*4882a593Smuzhiyun }
576*4882a593Smuzhiyun if (getenv("XLOCALEDIR") == NULL) {
577*4882a593Smuzhiyun char buffer[MAX_PATH];
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun snprintf(buffer, sizeof(buffer), "XLOCALEDIR=%s\\locale", basedir);
580*4882a593Smuzhiyun buffer[sizeof(buffer) - 1] = 0;
581*4882a593Smuzhiyun putenv(buffer);
582*4882a593Smuzhiyun }
583*4882a593Smuzhiyun if (getenv("HOME") == NULL) {
584*4882a593Smuzhiyun char buffer[MAX_PATH + 5];
585*4882a593Smuzhiyun
586*4882a593Smuzhiyun strncpy(buffer, "HOME=", 5);
587*4882a593Smuzhiyun
588*4882a593Smuzhiyun /* query appdata directory */
589*4882a593Smuzhiyun if (SHGetFolderPathA
590*4882a593Smuzhiyun (NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0,
591*4882a593Smuzhiyun buffer + 5) == 0) {
592*4882a593Smuzhiyun putenv(buffer);
593*4882a593Smuzhiyun }
594*4882a593Smuzhiyun else {
595*4882a593Smuzhiyun winMsg(X_ERROR, "Can not determine HOME directory\n");
596*4882a593Smuzhiyun }
597*4882a593Smuzhiyun }
598*4882a593Smuzhiyun if (!g_fLogFileChanged) {
599*4882a593Smuzhiyun static char buffer[MAX_PATH];
600*4882a593Smuzhiyun DWORD size = GetTempPath(sizeof(buffer), buffer);
601*4882a593Smuzhiyun
602*4882a593Smuzhiyun if (size && size < sizeof(buffer)) {
603*4882a593Smuzhiyun snprintf(buffer + size, sizeof(buffer) - size,
604*4882a593Smuzhiyun "XWin.%s.log", display);
605*4882a593Smuzhiyun buffer[sizeof(buffer) - 1] = 0;
606*4882a593Smuzhiyun g_pszLogFile = buffer;
607*4882a593Smuzhiyun winMsg(X_DEFAULT, "Logfile set to \"%s\"\n", g_pszLogFile);
608*4882a593Smuzhiyun }
609*4882a593Smuzhiyun }
610*4882a593Smuzhiyun {
611*4882a593Smuzhiyun static char xkbbasedir[MAX_PATH];
612*4882a593Smuzhiyun
613*4882a593Smuzhiyun snprintf(xkbbasedir, sizeof(xkbbasedir), "%s\\xkb", basedir);
614*4882a593Smuzhiyun if (sizeof(xkbbasedir) > 0)
615*4882a593Smuzhiyun xkbbasedir[sizeof(xkbbasedir) - 1] = 0;
616*4882a593Smuzhiyun XkbBaseDirectory = xkbbasedir;
617*4882a593Smuzhiyun XkbBinDirectory = basedir;
618*4882a593Smuzhiyun }
619*4882a593Smuzhiyun #endif /* RELOCATE_PROJECTROOT */
620*4882a593Smuzhiyun }
621*4882a593Smuzhiyun
622*4882a593Smuzhiyun void
OsVendorInit(void)623*4882a593Smuzhiyun OsVendorInit(void)
624*4882a593Smuzhiyun {
625*4882a593Smuzhiyun /* Re-initialize global variables on server reset */
626*4882a593Smuzhiyun winInitializeGlobals();
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun winFixupPaths();
629*4882a593Smuzhiyun
630*4882a593Smuzhiyun #ifdef DDXOSVERRORF
631*4882a593Smuzhiyun if (!OsVendorVErrorFProc)
632*4882a593Smuzhiyun OsVendorVErrorFProc = OsVendorVErrorF;
633*4882a593Smuzhiyun #endif
634*4882a593Smuzhiyun
635*4882a593Smuzhiyun if (!g_fLogInited) {
636*4882a593Smuzhiyun /* keep this order. If LogInit fails it calls Abort which then calls
637*4882a593Smuzhiyun * ddxGiveUp where LogInit is called again and creates an infinite
638*4882a593Smuzhiyun * recursion. If we set g_fLogInited to TRUE before the init we
639*4882a593Smuzhiyun * avoid the second call
640*4882a593Smuzhiyun */
641*4882a593Smuzhiyun g_fLogInited = TRUE;
642*4882a593Smuzhiyun g_pszLogFile = LogInit(g_pszLogFile, ".old");
643*4882a593Smuzhiyun
644*4882a593Smuzhiyun }
645*4882a593Smuzhiyun LogSetParameter(XLOG_FLUSH, 1);
646*4882a593Smuzhiyun LogSetParameter(XLOG_VERBOSITY, g_iLogVerbose);
647*4882a593Smuzhiyun LogSetParameter(XLOG_FILE_VERBOSITY, g_iLogVerbose);
648*4882a593Smuzhiyun
649*4882a593Smuzhiyun /* Log the version information */
650*4882a593Smuzhiyun if (serverGeneration == 1)
651*4882a593Smuzhiyun winLogVersionInfo();
652*4882a593Smuzhiyun
653*4882a593Smuzhiyun winCheckMount();
654*4882a593Smuzhiyun
655*4882a593Smuzhiyun /* Add a default screen if no screens were specified */
656*4882a593Smuzhiyun if (g_iNumScreens == 0) {
657*4882a593Smuzhiyun winDebug("OsVendorInit - Creating default screen 0\n");
658*4882a593Smuzhiyun
659*4882a593Smuzhiyun /*
660*4882a593Smuzhiyun * We need to initialize the default screen 0 if no -screen
661*4882a593Smuzhiyun * arguments were processed.
662*4882a593Smuzhiyun *
663*4882a593Smuzhiyun * Add a screen 0 using the defaults set by winInitializeDefaultScreens()
664*4882a593Smuzhiyun * and any additional default screen parameters given
665*4882a593Smuzhiyun */
666*4882a593Smuzhiyun winInitializeScreens(1);
667*4882a593Smuzhiyun
668*4882a593Smuzhiyun /* We have to flag this as an explicit screen, even though it isn't */
669*4882a593Smuzhiyun g_ScreenInfo[0].fExplicitScreen = TRUE;
670*4882a593Smuzhiyun }
671*4882a593Smuzhiyun
672*4882a593Smuzhiyun /* Work out what the default emulate3buttons setting should be, and apply
673*4882a593Smuzhiyun it if nothing was explicitly specified */
674*4882a593Smuzhiyun {
675*4882a593Smuzhiyun int mouseButtons = GetSystemMetrics(SM_CMOUSEBUTTONS);
676*4882a593Smuzhiyun int j;
677*4882a593Smuzhiyun
678*4882a593Smuzhiyun for (j = 0; j < g_iNumScreens; j++) {
679*4882a593Smuzhiyun if (g_ScreenInfo[j].iE3BTimeout == WIN_E3B_DEFAULT) {
680*4882a593Smuzhiyun if (mouseButtons < 3) {
681*4882a593Smuzhiyun static Bool reportOnce = TRUE;
682*4882a593Smuzhiyun
683*4882a593Smuzhiyun g_ScreenInfo[j].iE3BTimeout = WIN_DEFAULT_E3B_TIME;
684*4882a593Smuzhiyun if (reportOnce) {
685*4882a593Smuzhiyun reportOnce = FALSE;
686*4882a593Smuzhiyun winMsg(X_PROBED,
687*4882a593Smuzhiyun "Windows reports only %d mouse buttons, defaulting to -emulate3buttons\n",
688*4882a593Smuzhiyun mouseButtons);
689*4882a593Smuzhiyun }
690*4882a593Smuzhiyun }
691*4882a593Smuzhiyun else {
692*4882a593Smuzhiyun g_ScreenInfo[j].iE3BTimeout = WIN_E3B_OFF;
693*4882a593Smuzhiyun }
694*4882a593Smuzhiyun }
695*4882a593Smuzhiyun }
696*4882a593Smuzhiyun }
697*4882a593Smuzhiyun
698*4882a593Smuzhiyun /* Work out what the default resize setting should be, and apply it if it
699*4882a593Smuzhiyun was not explicitly specified */
700*4882a593Smuzhiyun {
701*4882a593Smuzhiyun int j;
702*4882a593Smuzhiyun for (j = 0; j < g_iNumScreens; j++) {
703*4882a593Smuzhiyun if (g_ScreenInfo[j].iResizeMode == resizeDefault) {
704*4882a593Smuzhiyun if (g_ScreenInfo[j].fFullScreen)
705*4882a593Smuzhiyun g_ScreenInfo[j].iResizeMode = resizeNotAllowed;
706*4882a593Smuzhiyun else
707*4882a593Smuzhiyun g_ScreenInfo[j].iResizeMode = resizeWithRandr;
708*4882a593Smuzhiyun }
709*4882a593Smuzhiyun }
710*4882a593Smuzhiyun }
711*4882a593Smuzhiyun }
712*4882a593Smuzhiyun
713*4882a593Smuzhiyun static void
winUseMsg(void)714*4882a593Smuzhiyun winUseMsg(void)
715*4882a593Smuzhiyun {
716*4882a593Smuzhiyun ErrorF("\n");
717*4882a593Smuzhiyun ErrorF("\n");
718*4882a593Smuzhiyun ErrorF(EXECUTABLE_NAME " Device Dependent Usage:\n");
719*4882a593Smuzhiyun ErrorF("\n");
720*4882a593Smuzhiyun
721*4882a593Smuzhiyun ErrorF("-[no]clipboard\n"
722*4882a593Smuzhiyun "\tEnable [disable] the clipboard integration. Default is enabled.\n");
723*4882a593Smuzhiyun
724*4882a593Smuzhiyun ErrorF("-clipupdates num_boxes\n"
725*4882a593Smuzhiyun "\tUse a clipping region to constrain shadow update blits to\n"
726*4882a593Smuzhiyun "\tthe updated region when num_boxes, or more, are in the\n"
727*4882a593Smuzhiyun "\tupdated region.\n");
728*4882a593Smuzhiyun
729*4882a593Smuzhiyun #ifdef XWIN_XF86CONFIG
730*4882a593Smuzhiyun ErrorF("-config\n" "\tSpecify a configuration file.\n");
731*4882a593Smuzhiyun
732*4882a593Smuzhiyun ErrorF("-configdir\n" "\tSpecify a configuration directory.\n");
733*4882a593Smuzhiyun #endif
734*4882a593Smuzhiyun
735*4882a593Smuzhiyun ErrorF("-depth bits_per_pixel\n"
736*4882a593Smuzhiyun "\tSpecify an optional bitdepth to use in fullscreen mode\n"
737*4882a593Smuzhiyun "\twith a DirectDraw engine.\n");
738*4882a593Smuzhiyun
739*4882a593Smuzhiyun ErrorF("-[no]emulate3buttons [timeout]\n"
740*4882a593Smuzhiyun "\tEmulate 3 button mouse with an optional timeout in\n"
741*4882a593Smuzhiyun "\tmilliseconds.\n");
742*4882a593Smuzhiyun
743*4882a593Smuzhiyun #ifdef XWIN_EMULATEPSEUDO
744*4882a593Smuzhiyun ErrorF("-emulatepseudo\n"
745*4882a593Smuzhiyun "\tCreate a depth 8 PseudoColor visual when running in\n"
746*4882a593Smuzhiyun "\tdepths 15, 16, 24, or 32, collectively known as TrueColor\n"
747*4882a593Smuzhiyun "\tdepths. The PseudoColor visual does not have correct colors,\n"
748*4882a593Smuzhiyun "\tand it may crash, but it at least allows you to run your\n"
749*4882a593Smuzhiyun "\tapplication in TrueColor modes.\n");
750*4882a593Smuzhiyun #endif
751*4882a593Smuzhiyun
752*4882a593Smuzhiyun ErrorF("-engine engine_type_id\n"
753*4882a593Smuzhiyun "\tOverride the server's automatically selected engine type:\n"
754*4882a593Smuzhiyun "\t\t1 - Shadow GDI\n"
755*4882a593Smuzhiyun "\t\t4 - Shadow DirectDraw4 Non-Locking\n"
756*4882a593Smuzhiyun );
757*4882a593Smuzhiyun
758*4882a593Smuzhiyun ErrorF("-fullscreen\n" "\tRun the server in fullscreen mode.\n");
759*4882a593Smuzhiyun
760*4882a593Smuzhiyun ErrorF("-[no]hostintitle\n"
761*4882a593Smuzhiyun "\tIn multiwindow mode, add remote host names to window titles.\n");
762*4882a593Smuzhiyun
763*4882a593Smuzhiyun ErrorF("-ignoreinput\n" "\tIgnore keyboard and mouse input.\n");
764*4882a593Smuzhiyun
765*4882a593Smuzhiyun #ifdef XWIN_XF86CONFIG
766*4882a593Smuzhiyun ErrorF("-keyboard\n"
767*4882a593Smuzhiyun "\tSpecify a keyboard device from the configuration file.\n");
768*4882a593Smuzhiyun #endif
769*4882a593Smuzhiyun
770*4882a593Smuzhiyun ErrorF("-[no]keyhook\n"
771*4882a593Smuzhiyun "\tGrab special Windows keypresses like Alt-Tab or the Menu "
772*4882a593Smuzhiyun "key.\n");
773*4882a593Smuzhiyun
774*4882a593Smuzhiyun ErrorF("-lesspointer\n"
775*4882a593Smuzhiyun "\tHide the windows mouse pointer when it is over any\n"
776*4882a593Smuzhiyun "\t" EXECUTABLE_NAME
777*4882a593Smuzhiyun " window. This prevents ghost cursors appearing when\n"
778*4882a593Smuzhiyun "\tthe Windows cursor is drawn on top of the X cursor\n");
779*4882a593Smuzhiyun
780*4882a593Smuzhiyun ErrorF("-logfile filename\n" "\tWrite log messages to <filename>.\n");
781*4882a593Smuzhiyun
782*4882a593Smuzhiyun ErrorF("-logverbose verbosity\n"
783*4882a593Smuzhiyun "\tSet the verbosity of log messages. [NOTE: Only a few messages\n"
784*4882a593Smuzhiyun "\trespect the settings yet]\n"
785*4882a593Smuzhiyun "\t\t0 - only print fatal error.\n"
786*4882a593Smuzhiyun "\t\t1 - print additional configuration information.\n"
787*4882a593Smuzhiyun "\t\t2 - print additional runtime information [default].\n"
788*4882a593Smuzhiyun "\t\t3 - print debugging and tracing information.\n");
789*4882a593Smuzhiyun
790*4882a593Smuzhiyun ErrorF("-[no]multimonitors or -[no]multiplemonitors\n"
791*4882a593Smuzhiyun "\tUse the entire virtual screen if multiple\n"
792*4882a593Smuzhiyun "\tmonitors are present.\n");
793*4882a593Smuzhiyun
794*4882a593Smuzhiyun ErrorF("-multiwindow\n" "\tRun the server in multi-window mode.\n");
795*4882a593Smuzhiyun
796*4882a593Smuzhiyun #ifdef XWIN_MULTIWINDOWEXTWM
797*4882a593Smuzhiyun ErrorF("-mwextwm\n"
798*4882a593Smuzhiyun "\tRun the server in multi-window external window manager mode.\n");
799*4882a593Smuzhiyun #endif
800*4882a593Smuzhiyun
801*4882a593Smuzhiyun ErrorF("-nodecoration\n"
802*4882a593Smuzhiyun "\tDo not draw a window border, title bar, etc. Windowed\n"
803*4882a593Smuzhiyun "\tmode only.\n");
804*4882a593Smuzhiyun
805*4882a593Smuzhiyun ErrorF("-nounicodeclipboard\n"
806*4882a593Smuzhiyun "\tDo not use Unicode clipboard even if on a NT-based platform.\n");
807*4882a593Smuzhiyun
808*4882a593Smuzhiyun ErrorF("-[no]primary\n"
809*4882a593Smuzhiyun "\tWhen clipboard integration is enabled, map the X11 PRIMARY selection\n"
810*4882a593Smuzhiyun "\tto the Windows clipboard. Default is enabled.\n");
811*4882a593Smuzhiyun
812*4882a593Smuzhiyun ErrorF("-refresh rate_in_Hz\n"
813*4882a593Smuzhiyun "\tSpecify an optional refresh rate to use in fullscreen mode\n"
814*4882a593Smuzhiyun "\twith a DirectDraw engine.\n");
815*4882a593Smuzhiyun
816*4882a593Smuzhiyun ErrorF("-resize=none|scrollbars|randr"
817*4882a593Smuzhiyun "\tIn windowed mode, [don't] allow resizing of the window. 'scrollbars'\n"
818*4882a593Smuzhiyun "\tmode gives the window scrollbars as needed, 'randr' mode uses the RANR\n"
819*4882a593Smuzhiyun "\textension to resize the X screen. 'randr' is the default.\n");
820*4882a593Smuzhiyun
821*4882a593Smuzhiyun ErrorF("-rootless\n" "\tRun the server in rootless mode.\n");
822*4882a593Smuzhiyun
823*4882a593Smuzhiyun ErrorF("-screen scr_num [width height [x y] | [[WxH[+X+Y]][@m]] ]\n"
824*4882a593Smuzhiyun "\tEnable screen scr_num and optionally specify a width and\n"
825*4882a593Smuzhiyun "\theight and initial position for that screen. Additionally\n"
826*4882a593Smuzhiyun "\ta monitor number can be specified to start the server on,\n"
827*4882a593Smuzhiyun "\tat which point, all coordinates become relative to that\n"
828*4882a593Smuzhiyun "\tmonitor. Examples:\n"
829*4882a593Smuzhiyun "\t -screen 0 800x600+100+100@2 ; 2nd monitor offset 100,100 size 800x600\n"
830*4882a593Smuzhiyun "\t -screen 0 1024x768@3 ; 3rd monitor size 1024x768\n"
831*4882a593Smuzhiyun "\t -screen 0 @1 ; on 1st monitor using its full resolution (the default)\n");
832*4882a593Smuzhiyun
833*4882a593Smuzhiyun ErrorF("-swcursor\n"
834*4882a593Smuzhiyun "\tDisable the usage of the Windows cursor and use the X11 software\n"
835*4882a593Smuzhiyun "\tcursor instead.\n");
836*4882a593Smuzhiyun
837*4882a593Smuzhiyun ErrorF("-[no]trayicon\n"
838*4882a593Smuzhiyun "\tDo not create a tray icon. Default is to create one\n"
839*4882a593Smuzhiyun "\ticon per screen. You can globally disable tray icons with\n"
840*4882a593Smuzhiyun "\t-notrayicon, then enable it for specific screens with\n"
841*4882a593Smuzhiyun "\t-trayicon for those screens.\n");
842*4882a593Smuzhiyun
843*4882a593Smuzhiyun ErrorF("-[no]unixkill\n" "\tCtrl+Alt+Backspace exits the X Server.\n");
844*4882a593Smuzhiyun
845*4882a593Smuzhiyun #ifdef XWIN_GLX_WINDOWS
846*4882a593Smuzhiyun ErrorF("-[no]wgl\n"
847*4882a593Smuzhiyun "\tEnable the GLX extension to use the native Windows WGL interface for hardware-accelerated OpenGL\n");
848*4882a593Smuzhiyun #endif
849*4882a593Smuzhiyun
850*4882a593Smuzhiyun ErrorF("-[no]winkill\n" "\tAlt+F4 exits the X Server.\n");
851*4882a593Smuzhiyun
852*4882a593Smuzhiyun ErrorF("-xkblayout XKBLayout\n"
853*4882a593Smuzhiyun "\tEquivalent to XKBLayout in XF86Config files.\n"
854*4882a593Smuzhiyun "\tFor example: -xkblayout de\n");
855*4882a593Smuzhiyun
856*4882a593Smuzhiyun ErrorF("-xkbmodel XKBModel\n"
857*4882a593Smuzhiyun "\tEquivalent to XKBModel in XF86Config files.\n");
858*4882a593Smuzhiyun
859*4882a593Smuzhiyun ErrorF("-xkboptions XKBOptions\n"
860*4882a593Smuzhiyun "\tEquivalent to XKBOptions in XF86Config files.\n");
861*4882a593Smuzhiyun
862*4882a593Smuzhiyun ErrorF("-xkbrules XKBRules\n"
863*4882a593Smuzhiyun "\tEquivalent to XKBRules in XF86Config files.\n");
864*4882a593Smuzhiyun
865*4882a593Smuzhiyun ErrorF("-xkbvariant XKBVariant\n"
866*4882a593Smuzhiyun "\tEquivalent to XKBVariant in XF86Config files.\n"
867*4882a593Smuzhiyun "\tFor example: -xkbvariant nodeadkeys\n");
868*4882a593Smuzhiyun }
869*4882a593Smuzhiyun
870*4882a593Smuzhiyun /* See Porting Layer Definition - p. 57 */
871*4882a593Smuzhiyun void
ddxUseMsg(void)872*4882a593Smuzhiyun ddxUseMsg(void)
873*4882a593Smuzhiyun {
874*4882a593Smuzhiyun /* Set a flag so that FatalError won't give duplicate warning message */
875*4882a593Smuzhiyun g_fSilentFatalError = TRUE;
876*4882a593Smuzhiyun
877*4882a593Smuzhiyun winUseMsg();
878*4882a593Smuzhiyun
879*4882a593Smuzhiyun /* Log file will not be opened for UseMsg unless we open it now */
880*4882a593Smuzhiyun if (!g_fLogInited) {
881*4882a593Smuzhiyun g_pszLogFile = LogInit(g_pszLogFile, ".old");
882*4882a593Smuzhiyun g_fLogInited = TRUE;
883*4882a593Smuzhiyun }
884*4882a593Smuzhiyun LogClose(EXIT_NO_ERROR);
885*4882a593Smuzhiyun
886*4882a593Smuzhiyun /* Notify user where UseMsg text can be found. */
887*4882a593Smuzhiyun if (!g_fNoHelpMessageBox)
888*4882a593Smuzhiyun winMessageBoxF("The " PROJECT_NAME " help text has been printed to "
889*4882a593Smuzhiyun "%s.\n"
890*4882a593Smuzhiyun "Please open %s to read the help text.\n",
891*4882a593Smuzhiyun MB_ICONINFORMATION, g_pszLogFile, g_pszLogFile);
892*4882a593Smuzhiyun }
893*4882a593Smuzhiyun
894*4882a593Smuzhiyun /* See Porting Layer Definition - p. 20 */
895*4882a593Smuzhiyun /*
896*4882a593Smuzhiyun * Do any global initialization, then initialize each screen.
897*4882a593Smuzhiyun *
898*4882a593Smuzhiyun * NOTE: We use ddxProcessArgument, so we don't need to touch argc and argv
899*4882a593Smuzhiyun */
900*4882a593Smuzhiyun
901*4882a593Smuzhiyun void
InitOutput(ScreenInfo * pScreenInfo,int argc,char * argv[])902*4882a593Smuzhiyun InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
903*4882a593Smuzhiyun {
904*4882a593Smuzhiyun int i;
905*4882a593Smuzhiyun
906*4882a593Smuzhiyun if (serverGeneration == 1)
907*4882a593Smuzhiyun XwinExtensionInit();
908*4882a593Smuzhiyun
909*4882a593Smuzhiyun /* Log the command line */
910*4882a593Smuzhiyun winLogCommandLine(argc, argv);
911*4882a593Smuzhiyun
912*4882a593Smuzhiyun #if CYGDEBUG
913*4882a593Smuzhiyun winDebug("InitOutput\n");
914*4882a593Smuzhiyun #endif
915*4882a593Smuzhiyun
916*4882a593Smuzhiyun /* Validate command-line arguments */
917*4882a593Smuzhiyun if (serverGeneration == 1 && !winValidateArgs()) {
918*4882a593Smuzhiyun FatalError("InitOutput - Invalid command-line arguments found. "
919*4882a593Smuzhiyun "Exiting.\n");
920*4882a593Smuzhiyun }
921*4882a593Smuzhiyun
922*4882a593Smuzhiyun #ifdef XWIN_XF86CONFIG
923*4882a593Smuzhiyun /* Try to read the xorg.conf-style configuration file */
924*4882a593Smuzhiyun if (!winReadConfigfile())
925*4882a593Smuzhiyun winErrorFVerb(1, "InitOutput - Error reading config file\n");
926*4882a593Smuzhiyun #else
927*4882a593Smuzhiyun winMsg(X_INFO, "xorg.conf is not supported\n");
928*4882a593Smuzhiyun winMsg(X_INFO, "See http://x.cygwin.com/docs/faq/cygwin-x-faq.html "
929*4882a593Smuzhiyun "for more information\n");
930*4882a593Smuzhiyun winConfigFiles();
931*4882a593Smuzhiyun #endif
932*4882a593Smuzhiyun
933*4882a593Smuzhiyun /* Load preferences from XWinrc file */
934*4882a593Smuzhiyun LoadPreferences();
935*4882a593Smuzhiyun
936*4882a593Smuzhiyun /* Setup global screen info parameters */
937*4882a593Smuzhiyun pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
938*4882a593Smuzhiyun pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
939*4882a593Smuzhiyun pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
940*4882a593Smuzhiyun pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
941*4882a593Smuzhiyun pScreenInfo->numPixmapFormats = ARRAY_SIZE(g_PixmapFormats);
942*4882a593Smuzhiyun
943*4882a593Smuzhiyun /* Describe how we want common pixmap formats padded */
944*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(g_PixmapFormats); i++) {
945*4882a593Smuzhiyun pScreenInfo->formats[i] = g_PixmapFormats[i];
946*4882a593Smuzhiyun }
947*4882a593Smuzhiyun
948*4882a593Smuzhiyun /* Load pointers to DirectDraw functions */
949*4882a593Smuzhiyun winGetDDProcAddresses();
950*4882a593Smuzhiyun
951*4882a593Smuzhiyun /* Detect supported engines */
952*4882a593Smuzhiyun winDetectSupportedEngines();
953*4882a593Smuzhiyun /* Load libraries for taskbar grouping */
954*4882a593Smuzhiyun winPropertyStoreInit();
955*4882a593Smuzhiyun
956*4882a593Smuzhiyun /* Store the instance handle */
957*4882a593Smuzhiyun g_hInstance = GetModuleHandle(NULL);
958*4882a593Smuzhiyun
959*4882a593Smuzhiyun /* Create the messaging window */
960*4882a593Smuzhiyun if (serverGeneration == 1)
961*4882a593Smuzhiyun winCreateMsgWindowThread();
962*4882a593Smuzhiyun
963*4882a593Smuzhiyun /* Initialize each screen */
964*4882a593Smuzhiyun for (i = 0; i < g_iNumScreens; ++i) {
965*4882a593Smuzhiyun /* Initialize the screen */
966*4882a593Smuzhiyun if (-1 == AddScreen(winScreenInit, argc, argv)) {
967*4882a593Smuzhiyun FatalError("InitOutput - Couldn't add screen %d", i);
968*4882a593Smuzhiyun }
969*4882a593Smuzhiyun }
970*4882a593Smuzhiyun
971*4882a593Smuzhiyun /*
972*4882a593Smuzhiyun Unless full xinerama has been explicitly enabled, register all native screens with pseudoramiX
973*4882a593Smuzhiyun */
974*4882a593Smuzhiyun if (!noPanoramiXExtension)
975*4882a593Smuzhiyun noPseudoramiXExtension = TRUE;
976*4882a593Smuzhiyun
977*4882a593Smuzhiyun if ((g_ScreenInfo[0].fMultipleMonitors) && !noPseudoramiXExtension)
978*4882a593Smuzhiyun {
979*4882a593Smuzhiyun int pass;
980*4882a593Smuzhiyun
981*4882a593Smuzhiyun PseudoramiXExtensionInit();
982*4882a593Smuzhiyun
983*4882a593Smuzhiyun /* Add primary monitor on pass 0, other monitors on pass 1, to ensure
984*4882a593Smuzhiyun the primary monitor is first in XINERAMA list */
985*4882a593Smuzhiyun for (pass = 0; pass < 2; pass++)
986*4882a593Smuzhiyun {
987*4882a593Smuzhiyun int iMonitor;
988*4882a593Smuzhiyun
989*4882a593Smuzhiyun for (iMonitor = 1; ; iMonitor++)
990*4882a593Smuzhiyun {
991*4882a593Smuzhiyun struct GetMonitorInfoData data;
992*4882a593Smuzhiyun QueryMonitor(iMonitor, &data);
993*4882a593Smuzhiyun if (data.bMonitorSpecifiedExists)
994*4882a593Smuzhiyun {
995*4882a593Smuzhiyun MONITORINFO mi;
996*4882a593Smuzhiyun mi.cbSize = sizeof(MONITORINFO);
997*4882a593Smuzhiyun
998*4882a593Smuzhiyun if (GetMonitorInfo(data.monitorHandle, &mi))
999*4882a593Smuzhiyun {
1000*4882a593Smuzhiyun /* pass == 1 XOR primary monitor flags is set */
1001*4882a593Smuzhiyun if ((!(pass == 1)) != (!(mi.dwFlags & MONITORINFOF_PRIMARY)))
1002*4882a593Smuzhiyun {
1003*4882a593Smuzhiyun /*
1004*4882a593Smuzhiyun Note the screen origin in a normalized coordinate space where (0,0) is at the top left
1005*4882a593Smuzhiyun of the native virtual desktop area
1006*4882a593Smuzhiyun */
1007*4882a593Smuzhiyun data.monitorOffsetX = data.monitorOffsetX - GetSystemMetrics(SM_XVIRTUALSCREEN);
1008*4882a593Smuzhiyun data.monitorOffsetY = data.monitorOffsetY - GetSystemMetrics(SM_YVIRTUALSCREEN);
1009*4882a593Smuzhiyun
1010*4882a593Smuzhiyun winDebug ("InitOutput - screen %d added at virtual desktop coordinate (%d,%d) (pseudoramiX) \n",
1011*4882a593Smuzhiyun iMonitor-1, data.monitorOffsetX, data.monitorOffsetY);
1012*4882a593Smuzhiyun
1013*4882a593Smuzhiyun PseudoramiXAddScreen(data.monitorOffsetX, data.monitorOffsetY,
1014*4882a593Smuzhiyun data.monitorWidth, data.monitorHeight);
1015*4882a593Smuzhiyun }
1016*4882a593Smuzhiyun }
1017*4882a593Smuzhiyun }
1018*4882a593Smuzhiyun else
1019*4882a593Smuzhiyun break;
1020*4882a593Smuzhiyun }
1021*4882a593Smuzhiyun }
1022*4882a593Smuzhiyun }
1023*4882a593Smuzhiyun
1024*4882a593Smuzhiyun xorgGlxCreateVendor();
1025*4882a593Smuzhiyun
1026*4882a593Smuzhiyun /* Generate a cookie used by internal clients for authorization */
1027*4882a593Smuzhiyun if (g_fXdmcpEnabled || g_fAuthEnabled)
1028*4882a593Smuzhiyun winGenerateAuthorization();
1029*4882a593Smuzhiyun
1030*4882a593Smuzhiyun /* Perform some one time initialization */
1031*4882a593Smuzhiyun if (1 == serverGeneration) {
1032*4882a593Smuzhiyun /*
1033*4882a593Smuzhiyun * setlocale applies to all threads in the current process.
1034*4882a593Smuzhiyun * Apply locale specified in LANG environment variable.
1035*4882a593Smuzhiyun */
1036*4882a593Smuzhiyun setlocale(LC_ALL, "");
1037*4882a593Smuzhiyun }
1038*4882a593Smuzhiyun
1039*4882a593Smuzhiyun #if CYGDEBUG || YES
1040*4882a593Smuzhiyun winDebug("InitOutput - Returning.\n");
1041*4882a593Smuzhiyun #endif
1042*4882a593Smuzhiyun }
1043