Release 940804
[wine/gsoc-2012-control.git] / misc / main.c
blob4479cdc0033ca583286e0bd4fa2d77208d0b5b39
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 <locale.h>
13 #include <X11/Xlib.h>
14 #include <X11/Xresource.h>
15 #include <X11/Xutil.h>
16 #include <X11/cursorfont.h>
17 #include "msdos.h"
18 #include "windows.h"
19 #include "options.h"
20 #include "prototypes.h"
21 #include "texts.h"
23 #define WINE_CLASS "Wine" /* Class name for resources */
25 typedef struct tagENVENTRY {
26 LPSTR Name;
27 LPSTR Value;
28 WORD wSize;
29 struct tagENVENTRY *Prev;
30 struct tagENVENTRY *Next;
31 } ENVENTRY;
32 typedef ENVENTRY *LPENVENTRY;
34 LPENVENTRY lpEnvList = NULL;
36 Display * XT_display; /* To be removed */
38 Display *display;
39 Screen *screen;
40 Window rootWindow;
41 int screenWidth = 0, screenHeight = 0; /* Desktop window dimensions */
42 int screenDepth = 0; /* Screen depth to use */
43 int desktopX = 0, desktopY = 0; /* Desktop window position (if any) */
45 char *ProgramName; /* Used by resource.c with WINELIB */
46 extern ButtonTexts ButtonText;
48 struct options Options =
49 { /* default options */
50 NULL, /* spyFilename */
51 NULL, /* desktopGeometry */
52 NULL, /* programName */
53 FALSE, /* usePrivateMap */
54 FALSE, /* synchronous */
55 FALSE, /* no backing store */
56 SW_SHOWNORMAL, /* cmdShow */
57 FALSE
61 static XrmOptionDescRec optionsTable[] =
63 { "-desktop", ".desktop", XrmoptionSepArg, (caddr_t)NULL },
64 { "-depth", ".depth", XrmoptionSepArg, (caddr_t)NULL },
65 { "-display", ".display", XrmoptionSepArg, (caddr_t)NULL },
66 { "-iconic", ".iconic", XrmoptionNoArg, (caddr_t)"on" },
67 { "-name", ".name", XrmoptionSepArg, (caddr_t)NULL },
68 { "-privatemap", ".privatemap", XrmoptionNoArg, (caddr_t)"on" },
69 { "-synchronous", ".synchronous", XrmoptionNoArg, (caddr_t)"on" },
70 { "-nobackingstore",".nobackingstore", XrmoptionNoArg, (caddr_t)"on" },
71 { "-spy", ".spy", XrmoptionSepArg, (caddr_t)NULL },
72 { "-debug", ".debug", XrmoptionNoArg, (caddr_t)"on" },
73 { "-relaydbg", ".relaydbg", XrmoptionNoArg, (caddr_t)"on" }
76 #define NB_OPTIONS (sizeof(optionsTable) / sizeof(optionsTable[0]))
78 #define USAGE \
79 "Usage: %s [options] program_name [arguments]\n" \
80 "\n" \
81 "Options:\n" \
82 " -depth n Change the depth to use for multiple-depth screens\n" \
83 " -desktop geom Use a desktop window of the given geometry\n" \
84 " -display name Use the specified display\n" \
85 " -iconic Start as an icon\n" \
86 " -debug Enter debugger before starting application\n" \
87 " -name name Set the application name\n" \
88 " -privatemap Use a private color map\n" \
89 " -synchronous Turn on synchronous display mode\n" \
90 " -nobackingstore Turn off backing store\n" \
91 " -spy file Turn on message spying to the specified file\n" \
92 " -relaydbg Display call relay information\n"
95 /***********************************************************************
96 * MAIN_Usage
98 static void MAIN_Usage( char *name )
100 fprintf( stderr, USAGE, name );
101 exit(1);
105 /***********************************************************************
106 * MAIN_GetProgramName
108 * Get the program name. The name is specified by (in order of precedence):
109 * - the option '-name'.
110 * - the environment variable 'WINE_NAME'.
111 * - the last component of argv[0].
113 static char *MAIN_GetProgramName( int argc, char *argv[] )
115 int i;
116 char *p;
118 for (i = 1; i < argc-1; i++)
119 if (!strcmp( argv[i], "-name" )) return argv[i+1];
120 if ((p = getenv( "WINE_NAME" )) != NULL) return p;
121 if ((p = strrchr( argv[0], '/' )) != NULL) return p+1;
122 return argv[0];
126 /***********************************************************************
127 * MAIN_GetResource
129 * Fetch the value of resource 'name' using the correct instance name.
130 * 'name' must begin with '.' or '*'
132 static int MAIN_GetResource( XrmDatabase db, char *name, XrmValue *value )
134 char *buff_instance, *buff_class;
135 char *dummy;
136 int retval;
138 buff_instance = (char *)malloc(strlen(Options.programName)+strlen(name)+1);
139 buff_class = (char *)malloc( strlen(WINE_CLASS) + strlen(name) + 1 );
141 strcpy( buff_instance, Options.programName );
142 strcat( buff_instance, name );
143 strcpy( buff_class, WINE_CLASS );
144 strcat( buff_class, name );
145 retval = XrmGetResource( db, buff_instance, buff_class, &dummy, value );
146 free( buff_instance );
147 free( buff_class );
148 return retval;
152 /***********************************************************************
153 * MAIN_GetButtonText
155 * Fetch the value of resource 'name' using the correct instance name.
156 * 'name' must begin with '.' or '*'
158 * The address of the string got from the XResoure is stored in Button.Label.
159 * The corresponding hotkey is taken from this string.
162 static void MAIN_GetButtonText( XrmDatabase db, char *name, ButtonDesc *Button)
164 XrmValue value;
165 char Hotkey;
166 char *i;
168 if (MAIN_GetResource( db, name, &value))
170 Button->Label = value.addr;
171 i = strchr(Button->Label,'&');
172 if ( i == NULL )
173 Button->Hotkey = '\0';
174 else if ( i++ == '\0' )
175 Button->Hotkey = '\0';
176 else
177 Button->Hotkey = *i;
179 Button->Hotkey = toupper(Button->Hotkey);
182 /***********************************************************************
183 * MAIN_GetAllButtonTexts
185 * Read all Button-labels from X11-resources if they exist.
188 static void MAIN_GetAllButtonTexts(XrmDatabase db)
190 MAIN_GetButtonText(db, ".YesLabel", &ButtonText.Yes);
191 MAIN_GetButtonText(db, ".NoLabel", &ButtonText.No);
192 MAIN_GetButtonText(db, ".OkLabel", &ButtonText.Ok);
193 MAIN_GetButtonText(db, ".CancelLabel", &ButtonText.Cancel);
194 MAIN_GetButtonText(db, ".AbortLabel", &ButtonText.Abort);
195 MAIN_GetButtonText(db, ".RetryLabel", &ButtonText.Retry);
196 MAIN_GetButtonText(db, ".IgnoreLabel", &ButtonText.Ignore);
197 MAIN_GetButtonText(db, ".CancelLabel", &ButtonText.Cancel);
200 /***********************************************************************
201 * MAIN_ParseOptions
203 * Parse command line options and open display.
205 static void MAIN_ParseOptions( int *argc, char *argv[] )
207 char *display_name;
208 XrmValue value;
209 XrmDatabase db = NULL;
211 /* Parse command line */
212 Options.programName = MAIN_GetProgramName( *argc, argv );
213 XrmParseCommand( &db, optionsTable, NB_OPTIONS,
214 Options.programName, argc, argv );
216 #ifdef WINELIB
217 /* Need to assemble command line and pass it to WinMain */
218 #else
219 if (*argc < 2 || strcasecmp(argv[1], "-h") == 0)
220 MAIN_Usage( argv[0] );
221 #endif
223 /* Open display */
225 if (MAIN_GetResource( db, ".display", &value )) display_name = value.addr;
226 else display_name = NULL;
228 if (!(display = XOpenDisplay( display_name )))
230 fprintf( stderr, "%s: Can't open display: %s\n",
231 argv[0], display_name ? display_name : "" );
232 exit(1);
235 /* Use app-defaults */
236 display->db = db;
238 /* Get all options */
239 if (MAIN_GetResource( db, ".iconic", &value ))
240 Options.cmdShow = SW_SHOWMINIMIZED;
241 if (MAIN_GetResource( db, ".privatemap", &value ))
242 Options.usePrivateMap = TRUE;
243 if (MAIN_GetResource( db, ".synchronous", &value ))
244 Options.synchronous = TRUE;
245 if (MAIN_GetResource( db, ".nobackingstore", &value ))
246 Options.nobackingstore = TRUE;
247 if (MAIN_GetResource( db, ".relaydbg", &value ))
248 Options.relay_debug = TRUE;
249 if (MAIN_GetResource( db, ".debug", &value ))
250 Options.debug = TRUE;
251 if (MAIN_GetResource( db, ".spy", &value))
252 Options.spyFilename = value.addr;
253 if (MAIN_GetResource( db, ".depth", &value))
254 screenDepth = atoi( value.addr );
255 if (MAIN_GetResource( db, ".desktop", &value))
256 Options.desktopGeometry = value.addr;
258 /* MAIN_GetAllButtonTexts(db); */
263 /***********************************************************************
264 * MAIN_CreateDesktop
266 static void MAIN_CreateDesktop( int argc, char *argv[] )
268 int flags;
269 unsigned int width = 640, height = 480; /* Default size = 640x480 */
270 char *name = "Wine desktop";
271 XSizeHints size_hints;
272 XWMHints wm_hints;
273 XClassHint class_hints;
274 XSetWindowAttributes win_attr;
275 XTextProperty window_name;
277 flags = XParseGeometry( Options.desktopGeometry,
278 &desktopX, &desktopY, &width, &height );
279 screenWidth = width;
280 screenHeight = height;
282 /* Create window */
284 win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
285 PointerMotionMask | ButtonPressMask |
286 ButtonReleaseMask | EnterWindowMask |
287 StructureNotifyMask;
288 win_attr.cursor = XCreateFontCursor( display, XC_top_left_arrow );
290 rootWindow = XCreateWindow( display, DefaultRootWindow(display),
291 desktopX, desktopY, width, height, 0,
292 CopyFromParent, InputOutput, CopyFromParent,
293 CWEventMask | CWCursor, &win_attr );
295 /* Set window manager properties */
297 size_hints.min_width = size_hints.max_width = width;
298 size_hints.min_height = size_hints.max_height = height;
299 size_hints.flags = PMinSize | PMaxSize;
300 if (flags & (XValue | YValue)) size_hints.flags |= USPosition;
301 if (flags & (WidthValue | HeightValue)) size_hints.flags |= USSize;
302 else size_hints.flags |= PSize;
304 wm_hints.flags = InputHint | StateHint;
305 wm_hints.input = True;
306 wm_hints.initial_state = NormalState;
307 class_hints.res_name = argv[0];
308 class_hints.res_class = "Wine";
310 XStringListToTextProperty( &name, 1, &window_name );
311 XSetWMProperties( display, rootWindow, &window_name, &window_name,
312 argv, argc, &size_hints, &wm_hints, &class_hints );
314 /* Map window */
316 XMapWindow( display, rootWindow );
320 XKeyboardState keyboard_state;
322 /***********************************************************************
323 * MAIN_SaveSetup
325 static void MAIN_SaveSetup(void)
327 XGetKeyboardControl(display, &keyboard_state);
330 /***********************************************************************
331 * MAIN_RestoreSetup
333 static void MAIN_RestoreSetup(void)
335 XKeyboardControl keyboard_value;
337 keyboard_value.key_click_percent = keyboard_state.key_click_percent;
338 keyboard_value.bell_percent = keyboard_state.bell_percent;
339 keyboard_value.bell_pitch = keyboard_state.bell_pitch;
340 keyboard_value.bell_duration = keyboard_state.bell_duration;
341 keyboard_value.auto_repeat_mode = keyboard_state.global_auto_repeat;
343 XChangeKeyboardControl(display, KBKeyClickPercent | KBBellPercent |
344 KBBellPitch | KBBellDuration | KBAutoRepeatMode, &keyboard_value);
347 static void called_at_exit(void)
349 Comm_DeInit();
350 sync_profiles();
351 MAIN_RestoreSetup();
352 WSACleanup();
355 /***********************************************************************
356 * main
358 int main( int argc, char *argv[] )
360 int ret_val;
361 int depth_count, i;
362 int *depth_list;
364 setlocale(LC_CTYPE,"");
366 XrmInitialize();
368 MAIN_ParseOptions( &argc, argv );
370 screen = DefaultScreenOfDisplay( display );
371 screenWidth = WidthOfScreen( screen );
372 screenHeight = HeightOfScreen( screen );
373 XT_display = display;
374 if (screenDepth) /* -depth option specified */
376 depth_list = XListDepths(display,DefaultScreen(display),&depth_count);
377 for (i = 0; i < depth_count; i++)
378 if (depth_list[i] == screenDepth) break;
379 XFree( depth_list );
380 if (i >= depth_count)
382 fprintf( stderr, "%s: Depth %d not supported on this screen.\n",
383 Options.programName, screenDepth );
384 exit(1);
387 else screenDepth = DefaultDepthOfScreen( screen );
388 if (Options.synchronous) XSynchronize( display, True );
389 if (Options.desktopGeometry) MAIN_CreateDesktop( argc, argv );
390 else rootWindow = DefaultRootWindow( display );
392 ProgramName = argv [0];
393 MAIN_SaveSetup();
394 DOS_InitFS();
395 Comm_Init();
396 #ifndef WINELIB
397 INT21_Init();
398 #endif
399 #ifndef sparc
400 atexit(called_at_exit);
401 #else
402 on_exit (called_at_exit, 0);
403 #endif
405 ret_val = _WinMain( argc, argv );
407 return ret_val;
410 /***********************************************************************
411 * MessageBeep (USER.104)
413 void MessageBeep(WORD i)
415 XBell(display, 100);
418 /***********************************************************************
419 * GetVersion (KERNEL.3)
421 LONG GetVersion(void)
423 return( 0x03300a03 ); /* dos 3.30 & win 3.10 */
426 /***********************************************************************
427 * GetWinFlags (KERNEL.132)
429 LONG GetWinFlags(void)
431 return (WF_STANDARD | WF_CPU286 | WF_PMODE | WF_80x87);
434 /***********************************************************************
435 * SetEnvironment (GDI.132)
437 int SetEnvironment(LPSTR lpPortName, LPSTR lpEnviron, WORD nCount)
439 LPENVENTRY lpNewEnv;
440 LPENVENTRY lpEnv = lpEnvList;
441 printf("SetEnvironnement('%s', '%s', %d) !\n",
442 lpPortName, lpEnviron, nCount);
443 if (lpPortName == NULL) return -1;
444 while (lpEnv != NULL) {
445 if (lpEnv->Name != NULL && strcmp(lpEnv->Name, lpPortName) == 0) {
446 if (nCount == 0 || lpEnviron == NULL) {
447 if (lpEnv->Prev != NULL) lpEnv->Prev->Next = lpEnv->Next;
448 if (lpEnv->Next != NULL) lpEnv->Next->Prev = lpEnv->Prev;
449 free(lpEnv->Value);
450 free(lpEnv->Name);
451 free(lpEnv);
452 printf("SetEnvironnement() // entry deleted !\n");
453 return -1;
455 free(lpEnv->Value);
456 lpEnv->Value = malloc(nCount);
457 if (lpNewEnv->Value == NULL) {
458 printf("SetEnvironment() // Error allocating entry value !\n");
459 return 0;
461 memcpy(lpEnv->Value, lpEnviron, nCount);
462 lpEnv->wSize = nCount;
463 printf("SetEnvironnement() // entry modified !\n");
464 return nCount;
466 if (lpEnv->Next == NULL) break;
467 lpEnv = lpEnv->Next;
469 if (nCount == 0 || lpEnviron == NULL) return -1;
470 printf("SetEnvironnement() // new entry !\n");
471 lpNewEnv = malloc(sizeof(ENVENTRY));
472 if (lpNewEnv == NULL) {
473 printf("SetEnvironment() // Error allocating new entry !\n");
474 return 0;
476 if (lpEnvList == NULL) {
477 lpEnvList = lpNewEnv;
478 lpNewEnv->Prev = NULL;
480 else {
481 lpEnv->Next = lpNewEnv;
482 lpNewEnv->Prev = lpEnv;
484 lpNewEnv->Next = NULL;
485 lpNewEnv->Name = malloc(strlen(lpPortName) + 1);
486 if (lpNewEnv->Name == NULL) {
487 printf("SetEnvironment() // Error allocating entry name !\n");
488 return 0;
490 strcpy(lpNewEnv->Name, lpPortName);
491 lpNewEnv->Value = malloc(nCount);
492 if (lpNewEnv->Value == NULL) {
493 printf("SetEnvironment() // Error allocating entry value !\n");
494 return 0;
496 memcpy(lpNewEnv->Value, lpEnviron, nCount);
497 lpNewEnv->wSize = nCount;
498 return nCount;
501 /***********************************************************************
502 * GetEnvironment (GDI.134)
504 int GetEnvironment(LPSTR lpPortName, LPSTR lpEnviron, WORD nMaxSiz)
506 WORD nCount;
507 LPENVENTRY lpEnv = lpEnvList;
508 printf("GetEnvironnement('%s', '%s', %d) !\n",
509 lpPortName, lpEnviron, nMaxSiz);
510 while (lpEnv != NULL) {
511 if (lpEnv->Name != NULL && strcmp(lpEnv->Name, lpPortName) == 0) {
512 nCount = min(nMaxSiz, lpEnv->wSize);
513 memcpy(lpEnviron, lpEnv->Value, nCount);
514 printf("GetEnvironnement() // found '%s' !\n", lpEnviron);
515 return nCount;
517 lpEnv = lpEnv->Next;
519 printf("GetEnvironnement() // not found !\n");
520 return 0;
523 /***********************************************************************
524 * GetTimerResolution (USER.14)
526 LONG GetTimerResolution(void)
528 return (1000);
531 /***********************************************************************
532 * SystemParametersInfo (USER.483)
534 BOOL SystemParametersInfo (UINT uAction, UINT uParam, void FAR *lpvParam, UINT fuWinIni)
536 int timeout, temp;
537 char buffer[256];
538 XKeyboardState keyboard_state;
539 XKeyboardControl keyboard_value;
542 fprintf(stderr, "SystemParametersInfo: action %d, param %x, flag %x\n",
543 uAction, uParam, fuWinIni);
545 switch (uAction) {
546 case SPI_GETBEEP:
547 XGetKeyboardControl(display, &keyboard_state);
548 if (keyboard_state.bell_percent == 0)
549 *(BOOL *) lpvParam = FALSE;
550 else
551 *(BOOL *) lpvParam = TRUE;
552 break;
554 case SPI_GETBORDER:
555 *(INT *) lpvParam = 1;
556 break;
558 case SPI_GETFASTTASKSWITCH:
559 *(BOOL *) lpvParam = FALSE;
560 break;
562 case SPI_GETGRIDGRANULARITY:
563 *(INT *) lpvParam = 1;
564 break;
566 case SPI_GETICONTITLEWRAP:
567 *(BOOL *) lpvParam = FALSE;
568 break;
570 case SPI_GETKEYBOARDDELAY:
571 *(INT *) lpvParam = 1;
572 break;
574 case SPI_GETKEYBOARDSPEED:
575 *(WORD *) lpvParam = 30;
576 break;
578 case SPI_GETMENUDROPALIGNMENT:
579 *(BOOL *) lpvParam = FALSE;
580 break;
582 case SPI_GETSCREENSAVEACTIVE:
583 *(BOOL *) lpvParam = FALSE;
584 break;
586 case SPI_GETSCREENSAVETIMEOUT:
587 XGetScreenSaver(display, &timeout, &temp,&temp,&temp);
588 *(INT *) lpvParam = timeout * 1000;
589 break;
591 case SPI_ICONHORIZONTALSPACING:
592 if (lpvParam == NULL)
593 fprintf(stderr, "SystemParametersInfo: Horizontal icon spacing set to %d\n.", uParam);
594 else
595 *(INT *) lpvParam = 50;
596 break;
598 case SPI_ICONVERTICALSPACING:
599 if (lpvParam == NULL)
600 fprintf(stderr, "SystemParametersInfo: Vertical icon spacing set to %d\n.", uParam);
601 else
602 *(INT *) lpvParam = 50;
603 break;
605 case SPI_SETBEEP:
606 if (uParam == TRUE)
607 keyboard_value.bell_percent = -1;
608 else
609 keyboard_value.bell_percent = 0;
610 XChangeKeyboardControl(display, KBBellPercent,
611 &keyboard_value);
612 break;
614 case SPI_SETSCREENSAVEACTIVE:
615 if (uParam == TRUE)
616 XActivateScreenSaver(display);
617 else
618 XResetScreenSaver(display);
619 break;
621 case SPI_SETSCREENSAVETIMEOUT:
622 XSetScreenSaver(display, uParam, 60, DefaultBlanking,
623 DefaultExposures);
624 break;
626 case SPI_SETDESKWALLPAPER:
627 return (SetDeskWallPaper((LPSTR) lpvParam));
628 break;
630 case SPI_SETDESKPATTERN:
631 if ((INT) uParam == -1) {
632 GetProfileString("Desktop", "Pattern",
633 "170 85 170 85 170 85 170 85",
634 buffer, sizeof(buffer) );
635 return (DESKTOP_SetPattern((LPSTR) buffer));
636 } else
637 return (DESKTOP_SetPattern((LPSTR) lpvParam));
638 break;
640 case SPI_LANGDRIVER:
641 case SPI_SETBORDER:
642 case SPI_SETDOUBLECLKHEIGHT:
643 case SPI_SETDOUBLECLICKTIME:
644 case SPI_SETDOUBLECLKWIDTH:
645 case SPI_SETFASTTASKSWITCH:
646 case SPI_SETKEYBOARDDELAY:
647 case SPI_SETKEYBOARDSPEED:
648 fprintf(stderr, "SystemParametersInfo: option %d ignored.\n", uParam);
649 break;
651 default:
652 fprintf(stderr, "SystemParametersInfo: unknown option %d.\n", uParam);
653 break;
655 return 1;
658 /***********************************************************************
659 * HMEMCPY (KERNEL.348)
661 void hmemcpy(void FAR *hpvDest, const void FAR *hpvSource, long cbCopy)
663 memcpy(hpvDest, hpvSource, cbCopy);
666 /***********************************************************************
667 * COPY (GDI.250)
669 void Copy(LPVOID lpSource, LPVOID lpDest, WORD nBytes)
671 memcpy(lpDest, lpSource, nBytes);
674 /***********************************************************************
675 * SWAPMOUSEBUTTON (USER.186)
677 BOOL SwapMouseButton(BOOL fSwap)
679 return 0; /* don't swap */
682 /***********************************************************************
683 * ISROMMODULE (KERNEL.323)
685 BOOL IsRomModule(HANDLE x)
687 /* I don't know the prototype, I assume that it returns true
688 if the dll is located in rom */
690 return FALSE;