Release 940510
[wine.git] / misc / main.c
blobd5784f3f2544324f01646f72bc8991d425e5e6cb
1 /*
2 * Main function.
4 * Copyright 1994 Alexandre Julliard
5 */
7 static char Copyright[] = "Copyright Alexandre Julliard, 1994";
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <X11/Xlib.h>
13 #include <X11/Xresource.h>
14 #include <X11/Xutil.h>
15 #include <X11/cursorfont.h>
16 #include "msdos.h"
17 #include "windows.h"
18 #include "options.h"
19 #include "prototypes.h"
21 #define WINE_CLASS "Wine" /* Class name for resources */
23 Display * XT_display; /* To be removed */
24 Screen * XT_screen; /* To be removed */
26 Display *display;
27 Screen *screen;
28 Window rootWindow;
29 int screenWidth = 0, screenHeight = 0; /* Desktop window dimensions */
30 int screenDepth = 0; /* Screen depth to use */
31 int desktopX = 0, desktopY = 0; /* Desktop window position (if any) */
33 char *ProgramName; /* Used by resource.c with WINELIB */
35 struct options Options =
36 { /* default options */
37 NULL, /* spyFilename */
38 NULL, /* desktopGeometry */
39 NULL, /* programName */
40 FALSE, /* usePrivateMap */
41 FALSE, /* synchronous */
42 SW_SHOWNORMAL, /* cmdShow */
43 FALSE
47 static XrmOptionDescRec optionsTable[] =
49 { "-desktop", ".desktop", XrmoptionSepArg, (caddr_t)NULL },
50 { "-depth", ".depth", XrmoptionSepArg, (caddr_t)NULL },
51 { "-display", ".display", XrmoptionSepArg, (caddr_t)NULL },
52 { "-iconic", ".iconic", XrmoptionNoArg, (caddr_t)"on" },
53 { "-name", ".name", XrmoptionSepArg, (caddr_t)NULL },
54 { "-privatemap", ".privatemap", XrmoptionNoArg, (caddr_t)"on" },
55 { "-synchronous", ".synchronous", XrmoptionNoArg, (caddr_t)"on" },
56 { "-spy", ".spy", XrmoptionSepArg, (caddr_t)NULL },
57 { "-debug", ".debug", XrmoptionNoArg, (caddr_t)"on" },
58 { "-relaydbg", ".relaydbg", XrmoptionNoArg, (caddr_t)"on" }
61 #define NB_OPTIONS (sizeof(optionsTable) / sizeof(optionsTable[0]))
63 #define USAGE \
64 "Usage: %s [options] program_name [arguments]\n" \
65 "\n" \
66 "Options:\n" \
67 " -depth n Change the depth to use for multiple-depth screens\n" \
68 " -desktop geom Use a desktop window of the given geometry\n" \
69 " -display name Use the specified display\n" \
70 " -iconic Start as an icon\n" \
71 " -debug Enter debugger before starting application\n" \
72 " -name name Set the application name\n" \
73 " -privatemap Use a private color map\n" \
74 " -synchronous Turn on synchronous display mode\n" \
75 " -spy file Turn on message spying to the specified file\n" \
76 " -relaydbg Display call relay information\n"
79 /***********************************************************************
80 * MAIN_Usage
82 static void MAIN_Usage( char *name )
84 fprintf( stderr, USAGE, name );
85 exit(1);
89 /***********************************************************************
90 * MAIN_GetProgramName
92 * Get the program name. The name is specified by (in order of precedence):
93 * - the option '-name'.
94 * - the environment variable 'WINE_NAME'.
95 * - the last component of argv[0].
97 static char *MAIN_GetProgramName( int argc, char *argv[] )
99 int i;
100 char *p;
102 for (i = 1; i < argc-1; i++)
103 if (!strcmp( argv[i], "-name" )) return argv[i+1];
104 if ((p = getenv( "WINE_NAME" )) != NULL) return p;
105 if ((p = strrchr( argv[0], '/' )) != NULL) return p+1;
106 return argv[0];
110 /***********************************************************************
111 * MAIN_GetResource
113 * Fetch the value of resource 'name' using the correct instance name.
114 * 'name' must begin with '.' or '*'
116 static int MAIN_GetResource( XrmDatabase db, char *name, XrmValue *value )
118 char *buff_instance, *buff_class;
119 char *dummy;
120 int retval;
122 buff_instance = (char *)malloc(strlen(Options.programName)+strlen(name)+1);
123 buff_class = (char *)malloc( strlen(WINE_CLASS) + strlen(name) + 1 );
125 strcpy( buff_instance, Options.programName );
126 strcat( buff_instance, name );
127 strcpy( buff_class, WINE_CLASS );
128 strcat( buff_class, name );
129 retval = XrmGetResource( db, buff_instance, buff_class, &dummy, value );
130 free( buff_instance );
131 free( buff_class );
132 return retval;
136 /***********************************************************************
137 * MAIN_ParseOptions
139 * Parse command line options and open display.
141 static void MAIN_ParseOptions( int *argc, char *argv[] )
143 char *display_name;
144 XrmValue value;
145 XrmDatabase db = NULL;
147 /* Parse command line */
149 Options.programName = MAIN_GetProgramName( *argc, argv );
150 XrmParseCommand( &db, optionsTable, NB_OPTIONS,
151 Options.programName, argc, argv );
152 #ifdef WINELIB
153 /* Need to assemble command line and pass it to WinMain */
154 #else
155 if (*argc < 2 || strcasecmp(argv[1], "-h") == 0)
156 MAIN_Usage( argv[0] );
157 #endif
159 /* Open display */
161 if (MAIN_GetResource( db, ".display", &value )) display_name = value.addr;
162 else display_name = NULL;
164 if (!(display = XOpenDisplay( display_name )))
166 fprintf( stderr, "%s: Can't open display: %s\n",
167 argv[0], display_name ? display_name : "" );
168 exit(1);
171 /* Get all options */
173 if (MAIN_GetResource( db, ".iconic", &value ))
174 Options.cmdShow = SW_SHOWMINIMIZED;
175 if (MAIN_GetResource( db, ".privatemap", &value ))
176 Options.usePrivateMap = TRUE;
177 if (MAIN_GetResource( db, ".synchronous", &value ))
178 Options.synchronous = TRUE;
179 if (MAIN_GetResource( db, ".relaydbg", &value ))
180 Options.relay_debug = TRUE;
181 if (MAIN_GetResource( db, ".debug", &value ))
182 Options.debug = TRUE;
183 if (MAIN_GetResource( db, ".spy", &value))
184 Options.spyFilename = value.addr;
185 if (MAIN_GetResource( db, ".depth", &value))
186 screenDepth = atoi( value.addr );
187 if (MAIN_GetResource( db, ".desktop", &value))
188 Options.desktopGeometry = value.addr;
192 /***********************************************************************
193 * MAIN_CreateDesktop
195 static void MAIN_CreateDesktop( int argc, char *argv[] )
197 int flags;
198 unsigned int width = 640, height = 480; /* Default size = 640x480 */
199 char *name = "Wine desktop";
200 XSizeHints size_hints;
201 XWMHints wm_hints;
202 XClassHint class_hints;
203 XSetWindowAttributes win_attr;
204 XTextProperty window_name;
206 flags = XParseGeometry( Options.desktopGeometry,
207 &desktopX, &desktopY, &width, &height );
208 screenWidth = width;
209 screenHeight = height;
211 /* Create window */
213 win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
214 PointerMotionMask | ButtonPressMask |
215 ButtonReleaseMask | EnterWindowMask |
216 StructureNotifyMask;
217 win_attr.cursor = XCreateFontCursor( display, XC_top_left_arrow );
219 rootWindow = XCreateWindow( display, DefaultRootWindow(display),
220 desktopX, desktopY, width, height, 0,
221 CopyFromParent, InputOutput, CopyFromParent,
222 CWEventMask | CWCursor, &win_attr );
224 /* Set window manager properties */
226 size_hints.min_width = size_hints.max_width = width;
227 size_hints.min_height = size_hints.max_height = height;
228 size_hints.flags = PMinSize | PMaxSize;
229 if (flags & (XValue | YValue)) size_hints.flags |= USPosition;
230 if (flags & (WidthValue | HeightValue)) size_hints.flags |= USSize;
231 else size_hints.flags |= PSize;
233 wm_hints.flags = InputHint | StateHint;
234 wm_hints.input = True;
235 wm_hints.initial_state = NormalState;
236 class_hints.res_name = argv[0];
237 class_hints.res_class = "Wine";
239 XStringListToTextProperty( &name, 1, &window_name );
240 XSetWMProperties( display, rootWindow, &window_name, &window_name,
241 argv, argc, &size_hints, &wm_hints, &class_hints );
243 /* Map window */
245 XMapWindow( display, rootWindow );
249 XKeyboardState keyboard_state;
251 /***********************************************************************
252 * MAIN_SaveSetup
254 static void MAIN_SaveSetup(void)
256 XGetKeyboardControl(display, &keyboard_state);
259 /***********************************************************************
260 * MAIN_RestoreSetup
262 static void MAIN_RestoreSetup(void)
264 XKeyboardControl keyboard_value;
266 keyboard_value.key_click_percent = keyboard_state.key_click_percent;
267 keyboard_value.bell_percent = keyboard_state.bell_percent;
268 keyboard_value.bell_pitch = keyboard_state.bell_pitch;
269 keyboard_value.bell_duration = keyboard_state.bell_duration;
270 keyboard_value.auto_repeat_mode = keyboard_state.global_auto_repeat;
272 XChangeKeyboardControl(display, KBKeyClickPercent | KBBellPercent |
273 KBBellPitch | KBBellDuration | KBAutoRepeatMode, &keyboard_value);
276 static void called_at_exit(void)
278 Comm_DeInit();
279 sync_profiles();
280 MAIN_RestoreSetup();
281 WSACleanup();
284 /***********************************************************************
285 * main
287 int main( int argc, char *argv[] )
289 int ret_val;
290 int depth_count, i;
291 int *depth_list;
293 XrmInitialize();
295 MAIN_ParseOptions( &argc, argv );
297 screen = DefaultScreenOfDisplay( display );
298 screenWidth = WidthOfScreen( screen );
299 screenHeight = HeightOfScreen( screen );
300 XT_display = display;
301 XT_screen = screen;
302 if (screenDepth) /* -depth option specified */
304 depth_list = XListDepths(display,DefaultScreen(display),&depth_count);
305 for (i = 0; i < depth_count; i++)
306 if (depth_list[i] == screenDepth) break;
307 XFree( depth_list );
308 if (i >= depth_count)
310 fprintf( stderr, "%s: Depth %d not supported on this screen.\n",
311 Options.programName, screenDepth );
312 exit(1);
315 else screenDepth = DefaultDepthOfScreen( screen );
316 if (Options.synchronous) XSynchronize( display, True );
317 if (Options.desktopGeometry) MAIN_CreateDesktop( argc, argv );
318 else rootWindow = DefaultRootWindow( display );
320 ProgramName = argv [0];
321 MAIN_SaveSetup();
322 DOS_InitFS();
323 Comm_Init();
325 #ifndef sunos
326 atexit(called_at_exit);
327 #endif
329 ret_val = _WinMain( argc, argv );
331 #ifdef sunos
332 called_at_exit();
333 #endif
335 return ret_val;
338 /***********************************************************************
339 * MessageBeep (USER.104)
341 void MessageBeep(WORD i)
343 XBell(display, 100);
346 /***********************************************************************
347 * GetVersion (KERNEL.3)
349 LONG GetVersion(void)
351 return( 0x03300a03 ); /* dos 3.30 & win 3.10 */
354 /***********************************************************************
355 * GetWinFlags (KERNEL.132)
357 LONG GetWinFlags(void)
359 return (WF_STANDARD | WF_CPU286 | WF_PMODE | WF_80x87);
362 /***********************************************************************
363 * GetTimerResolution (USER.14)
365 LONG GetTimerResolution(void)
367 return (1000);
370 /***********************************************************************
371 * SystemParametersInfo (USER.483)
373 BOOL SystemParametersInfo (UINT uAction, UINT uParam, void FAR *lpvParam, UINT fuWinIni)
375 int timeout, temp;
376 char buffer[256];
377 XKeyboardState keyboard_state;
378 XKeyboardControl keyboard_value;
381 fprintf(stderr, "SystemParametersInfo: action %d, param %x, flag %x\n",
382 uAction, uParam, fuWinIni);
384 switch (uAction) {
385 case SPI_GETBEEP:
386 XGetKeyboardControl(display, &keyboard_state);
387 if (keyboard_state.bell_percent == 0)
388 *(BOOL *) lpvParam = FALSE;
389 else
390 *(BOOL *) lpvParam = TRUE;
391 break;
393 case SPI_GETBORDER:
394 *(INT *) lpvParam = 1;
395 break;
397 case SPI_GETFASTTASKSWITCH:
398 *(BOOL *) lpvParam = FALSE;
399 break;
401 case SPI_GETGRIDGRANULARITY:
402 *(INT *) lpvParam = 1;
403 break;
405 case SPI_GETICONTITLEWRAP:
406 *(BOOL *) lpvParam = FALSE;
407 break;
409 case SPI_GETKEYBOARDDELAY:
410 *(INT *) lpvParam = 1;
411 break;
413 case SPI_GETKEYBOARDSPEED:
414 *(WORD *) lpvParam = 30;
415 break;
417 case SPI_GETMENUDROPALIGNMENT:
418 *(BOOL *) lpvParam = FALSE;
419 break;
421 case SPI_GETSCREENSAVEACTIVE:
422 *(BOOL *) lpvParam = FALSE;
423 break;
425 case SPI_GETSCREENSAVETIMEOUT:
426 XGetScreenSaver(display, &timeout, &temp,&temp,&temp);
427 *(INT *) lpvParam = timeout * 1000;
428 break;
430 case SPI_ICONHORIZONTALSPACING:
431 if (lpvParam == NULL)
432 fprintf(stderr, "SystemParametersInfo: Horizontal icon spacing set to %d\n.", uParam);
433 else
434 *(INT *) lpvParam = 50;
435 break;
437 case SPI_ICONVERTICALSPACING:
438 if (lpvParam == NULL)
439 fprintf(stderr, "SystemParametersInfo: Vertical icon spacing set to %d\n.", uParam);
440 else
441 *(INT *) lpvParam = 50;
442 break;
444 case SPI_SETBEEP:
445 if (uParam == TRUE)
446 keyboard_value.bell_percent = -1;
447 else
448 keyboard_value.bell_percent = 0;
449 XChangeKeyboardControl(display, KBBellPercent,
450 &keyboard_value);
451 break;
453 case SPI_SETSCREENSAVEACTIVE:
454 if (uParam == TRUE)
455 XActivateScreenSaver(display);
456 else
457 XResetScreenSaver(display);
458 break;
460 case SPI_SETSCREENSAVETIMEOUT:
461 XSetScreenSaver(display, uParam, 60, DefaultBlanking,
462 DefaultExposures);
463 break;
465 case SPI_SETDESKWALLPAPER:
466 return (SetDeskWallPaper((LPSTR) lpvParam));
467 break;
469 case SPI_SETDESKPATTERN:
470 if ((INT) uParam == -1) {
471 GetProfileString("Desktop", "Pattern",
472 "170 85 170 85 170 85 170 85",
473 buffer, sizeof(buffer) );
474 return (DESKTOP_SetPattern((LPSTR) buffer));
475 } else
476 return (DESKTOP_SetPattern((LPSTR) lpvParam));
477 break;
479 case SPI_LANGDRIVER:
480 case SPI_SETBORDER:
481 case SPI_SETDOUBLECLKHEIGHT:
482 case SPI_SETDOUBLECLICKTIME:
483 case SPI_SETDOUBLECLKWIDTH:
484 case SPI_SETFASTTASKSWITCH:
485 case SPI_SETKEYBOARDDELAY:
486 case SPI_SETKEYBOARDSPEED:
487 fprintf(stderr, "SystemParametersInfo: option %d ignored.\n", uParam);
488 break;
490 default:
491 fprintf(stderr, "SystemParametersInfo: unknown option %d.\n", uParam);
492 break;
494 return 1;
497 /***********************************************************************
498 * HMEMCPY (KERNEL.348)
500 void hmemcpy(void FAR *hpvDest, const void FAR *hpvSource, long cbCopy)
502 memcpy(hpvDest, hpvSource, cbCopy);
505 /***********************************************************************
506 * COPY (GDI.250)
508 void Copy(LPVOID lpSource, LPVOID lpDest, WORD nBytes)
510 memcpy(lpDest, lpSource, nBytes);
513 /***********************************************************************
514 * SWAPMOUSEBUTTON (USER.186)
516 BOOL SwapMouseButton(BOOL fSwap)
518 return 0; /* don't swap */