4 * Copyright 1994 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1994";
14 #include <X11/Xresource.h>
15 #include <X11/Xutil.h>
16 #include <X11/cursorfont.h>
20 #include "prototypes.h"
23 #define WINE_CLASS "Wine" /* Class name for resources */
25 typedef struct tagENVENTRY
{
29 struct tagENVENTRY
*Prev
;
30 struct tagENVENTRY
*Next
;
32 typedef ENVENTRY
*LPENVENTRY
;
34 LPENVENTRY lpEnvList
= NULL
;
36 Display
* XT_display
; /* To be removed */
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 */
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]))
79 "Usage: %s [options] program_name [arguments]\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 /***********************************************************************
98 static void MAIN_Usage( char *name
)
100 fprintf( stderr
, USAGE
, name
);
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
[] )
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;
126 /***********************************************************************
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
;
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
);
152 /***********************************************************************
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
)
168 if (MAIN_GetResource( db
, name
, &value
))
170 Button
->Label
= value
.addr
;
171 i
= strchr(Button
->Label
,'&');
173 Button
->Hotkey
= '\0';
174 else if ( i
++ == '\0' )
175 Button
->Hotkey
= '\0';
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 /***********************************************************************
203 * Parse command line options and open display.
205 static void MAIN_ParseOptions( int *argc
, char *argv
[] )
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
);
217 /* Need to assemble command line and pass it to WinMain */
219 if (*argc
< 2 || strcasecmp(argv
[1], "-h") == 0)
220 MAIN_Usage( argv
[0] );
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
: "" );
235 /* Use app-defaults */
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 /***********************************************************************
266 static void MAIN_CreateDesktop( int argc
, char *argv
[] )
269 unsigned int width
= 640, height
= 480; /* Default size = 640x480 */
270 char *name
= "Wine desktop";
271 XSizeHints size_hints
;
273 XClassHint class_hints
;
274 XSetWindowAttributes win_attr
;
275 XTextProperty window_name
;
277 flags
= XParseGeometry( Options
.desktopGeometry
,
278 &desktopX
, &desktopY
, &width
, &height
);
280 screenHeight
= height
;
284 win_attr
.event_mask
= ExposureMask
| KeyPressMask
| KeyReleaseMask
|
285 PointerMotionMask
| ButtonPressMask
|
286 ButtonReleaseMask
| EnterWindowMask
|
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
);
316 XMapWindow( display
, rootWindow
);
320 XKeyboardState keyboard_state
;
322 /***********************************************************************
325 static void MAIN_SaveSetup(void)
327 XGetKeyboardControl(display
, &keyboard_state
);
330 /***********************************************************************
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)
355 /***********************************************************************
358 int main( int argc
, char *argv
[] )
364 setlocale(LC_CTYPE
,"");
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;
380 if (i
>= depth_count
)
382 fprintf( stderr
, "%s: Depth %d not supported on this screen.\n",
383 Options
.programName
, screenDepth
);
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];
400 atexit(called_at_exit
);
402 on_exit (called_at_exit
, 0);
405 ret_val
= _WinMain( argc
, argv
);
410 /***********************************************************************
411 * MessageBeep (USER.104)
413 void MessageBeep(WORD i
)
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
)
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
;
452 printf("SetEnvironnement() // entry deleted !\n");
456 lpEnv
->Value
= malloc(nCount
);
457 if (lpNewEnv
->Value
== NULL
) {
458 printf("SetEnvironment() // Error allocating entry value !\n");
461 memcpy(lpEnv
->Value
, lpEnviron
, nCount
);
462 lpEnv
->wSize
= nCount
;
463 printf("SetEnvironnement() // entry modified !\n");
466 if (lpEnv
->Next
== NULL
) break;
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");
476 if (lpEnvList
== NULL
) {
477 lpEnvList
= lpNewEnv
;
478 lpNewEnv
->Prev
= NULL
;
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");
490 strcpy(lpNewEnv
->Name
, lpPortName
);
491 lpNewEnv
->Value
= malloc(nCount
);
492 if (lpNewEnv
->Value
== NULL
) {
493 printf("SetEnvironment() // Error allocating entry value !\n");
496 memcpy(lpNewEnv
->Value
, lpEnviron
, nCount
);
497 lpNewEnv
->wSize
= nCount
;
501 /***********************************************************************
502 * GetEnvironment (GDI.134)
504 int GetEnvironment(LPSTR lpPortName
, LPSTR lpEnviron
, WORD nMaxSiz
)
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
);
519 printf("GetEnvironnement() // not found !\n");
523 /***********************************************************************
524 * GetTimerResolution (USER.14)
526 LONG
GetTimerResolution(void)
531 /***********************************************************************
532 * SystemParametersInfo (USER.483)
534 BOOL
SystemParametersInfo (UINT uAction
, UINT uParam
, void FAR
*lpvParam
, UINT fuWinIni
)
538 XKeyboardState keyboard_state
;
539 XKeyboardControl keyboard_value
;
542 fprintf(stderr
, "SystemParametersInfo: action %d, param %x, flag %x\n",
543 uAction
, uParam
, fuWinIni
);
547 XGetKeyboardControl(display
, &keyboard_state
);
548 if (keyboard_state
.bell_percent
== 0)
549 *(BOOL
*) lpvParam
= FALSE
;
551 *(BOOL
*) lpvParam
= TRUE
;
555 *(INT
*) lpvParam
= 1;
558 case SPI_GETFASTTASKSWITCH
:
559 *(BOOL
*) lpvParam
= FALSE
;
562 case SPI_GETGRIDGRANULARITY
:
563 *(INT
*) lpvParam
= 1;
566 case SPI_GETICONTITLEWRAP
:
567 *(BOOL
*) lpvParam
= FALSE
;
570 case SPI_GETKEYBOARDDELAY
:
571 *(INT
*) lpvParam
= 1;
574 case SPI_GETKEYBOARDSPEED
:
575 *(WORD
*) lpvParam
= 30;
578 case SPI_GETMENUDROPALIGNMENT
:
579 *(BOOL
*) lpvParam
= FALSE
;
582 case SPI_GETSCREENSAVEACTIVE
:
583 *(BOOL
*) lpvParam
= FALSE
;
586 case SPI_GETSCREENSAVETIMEOUT
:
587 XGetScreenSaver(display
, &timeout
, &temp
,&temp
,&temp
);
588 *(INT
*) lpvParam
= timeout
* 1000;
591 case SPI_ICONHORIZONTALSPACING
:
592 if (lpvParam
== NULL
)
593 fprintf(stderr
, "SystemParametersInfo: Horizontal icon spacing set to %d\n.", uParam
);
595 *(INT
*) lpvParam
= 50;
598 case SPI_ICONVERTICALSPACING
:
599 if (lpvParam
== NULL
)
600 fprintf(stderr
, "SystemParametersInfo: Vertical icon spacing set to %d\n.", uParam
);
602 *(INT
*) lpvParam
= 50;
607 keyboard_value
.bell_percent
= -1;
609 keyboard_value
.bell_percent
= 0;
610 XChangeKeyboardControl(display
, KBBellPercent
,
614 case SPI_SETSCREENSAVEACTIVE
:
616 XActivateScreenSaver(display
);
618 XResetScreenSaver(display
);
621 case SPI_SETSCREENSAVETIMEOUT
:
622 XSetScreenSaver(display
, uParam
, 60, DefaultBlanking
,
626 case SPI_SETDESKWALLPAPER
:
627 return (SetDeskWallPaper((LPSTR
) lpvParam
));
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
));
637 return (DESKTOP_SetPattern((LPSTR
) lpvParam
));
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
);
652 fprintf(stderr
, "SystemParametersInfo: unknown option %d.\n", uParam
);
658 /***********************************************************************
659 * HMEMCPY (KERNEL.348)
661 void hmemcpy(void FAR
*hpvDest
, const void FAR
*hpvSource
, long cbCopy
)
663 memcpy(hpvDest
, hpvSource
, cbCopy
);
666 /***********************************************************************
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 */