4 * Copyright 1994 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1994";
15 #include <X11/Xresource.h>
16 #include <X11/Xutil.h>
17 #include <X11/cursorfont.h>
21 #include "prototypes.h"
23 #define DEBUG_DEFINE_VARIABLES
27 #define WINE_CLASS "Wine" /* Class name for resources */
29 typedef struct tagENVENTRY
{
33 struct tagENVENTRY
*Prev
;
34 struct tagENVENTRY
*Next
;
36 typedef ENVENTRY
*LPENVENTRY
;
38 LPENVENTRY lpEnvList
= NULL
;
43 int screenWidth
= 0, screenHeight
= 0; /* Desktop window dimensions */
44 int screenDepth
= 0; /* Screen depth to use */
45 int desktopX
= 0, desktopY
= 0; /* Desktop window position (if any) */
47 extern ButtonTexts ButtonText
;
49 struct options Options
=
50 { /* default options */
51 NULL
, /* spyFilename */
52 NULL
, /* desktopGeometry */
53 NULL
, /* programName */
54 FALSE
, /* usePrivateMap */
55 FALSE
, /* synchronous */
56 FALSE
, /* backing store */
57 SW_SHOWNORMAL
, /* cmdShow */
62 static XrmOptionDescRec optionsTable
[] =
64 { "-backingstore", ".backingstore", XrmoptionNoArg
, (caddr_t
)"on" },
65 { "-desktop", ".desktop", XrmoptionSepArg
, (caddr_t
)NULL
},
66 { "-depth", ".depth", XrmoptionSepArg
, (caddr_t
)NULL
},
67 { "-display", ".display", XrmoptionSepArg
, (caddr_t
)NULL
},
68 { "-iconic", ".iconic", XrmoptionNoArg
, (caddr_t
)"on" },
69 { "-name", ".name", XrmoptionSepArg
, (caddr_t
)NULL
},
70 { "-privatemap", ".privatemap", XrmoptionNoArg
, (caddr_t
)"on" },
71 { "-synchronous", ".synchronous", XrmoptionNoArg
, (caddr_t
)"on" },
72 { "-spy", ".spy", XrmoptionSepArg
, (caddr_t
)NULL
},
73 { "-debug", ".debug", XrmoptionNoArg
, (caddr_t
)"on" },
74 { "-relaydbg", ".relaydbg", XrmoptionNoArg
, (caddr_t
)"on" },
75 { "-debugmsg", ".debugmsg", XrmoptionSepArg
, (caddr_t
)NULL
}
78 #define NB_OPTIONS (sizeof(optionsTable) / sizeof(optionsTable[0]))
81 "Usage: %s [options] program_name [arguments]\n" \
84 " -depth n Change the depth to use for multiple-depth screens\n" \
85 " -desktop geom Use a desktop window of the given geometry\n" \
86 " -display name Use the specified display\n" \
87 " -iconic Start as an icon\n" \
88 " -debug Enter debugger before starting application\n" \
89 " -name name Set the application name\n" \
90 " -privatemap Use a private color map\n" \
91 " -synchronous Turn on synchronous display mode\n" \
92 " -backingstore Turn on backing store\n" \
93 " -spy file Turn on message spying to the specified file\n" \
94 " -relaydbg Display call relay information\n" \
95 " -debugmsg name Turn debugging-messages on or off\n"
98 /***********************************************************************
101 static void MAIN_Usage( char *name
)
103 fprintf( stderr
, USAGE
, name
);
108 /***********************************************************************
109 * MAIN_GetProgramName
111 * Get the program name. The name is specified by (in order of precedence):
112 * - the option '-name'.
113 * - the environment variable 'WINE_NAME'.
114 * - the last component of argv[0].
116 static char *MAIN_GetProgramName( int argc
, char *argv
[] )
121 for (i
= 1; i
< argc
-1; i
++)
122 if (!strcmp( argv
[i
], "-name" )) return argv
[i
+1];
123 if ((p
= getenv( "WINE_NAME" )) != NULL
) return p
;
124 if ((p
= strrchr( argv
[0], '/' )) != NULL
) return p
+1;
129 /***********************************************************************
132 * Fetch the value of resource 'name' using the correct instance name.
133 * 'name' must begin with '.' or '*'
135 static int MAIN_GetResource( XrmDatabase db
, char *name
, XrmValue
*value
)
137 char *buff_instance
, *buff_class
;
141 buff_instance
= (char *)malloc(strlen(Options
.programName
)+strlen(name
)+1);
142 buff_class
= (char *)malloc( strlen(WINE_CLASS
) + strlen(name
) + 1 );
144 strcpy( buff_instance
, Options
.programName
);
145 strcat( buff_instance
, name
);
146 strcpy( buff_class
, WINE_CLASS
);
147 strcat( buff_class
, name
);
148 retval
= XrmGetResource( db
, buff_instance
, buff_class
, &dummy
, value
);
149 free( buff_instance
);
155 /***********************************************************************
158 * Fetch the value of resource 'name' using the correct instance name.
159 * 'name' must begin with '.' or '*'
161 * The address of the string got from the XResoure is stored in Button.Label.
162 * The corresponding hotkey is taken from this string.
165 static void MAIN_GetButtonText( XrmDatabase db
, char *name
, ButtonDesc
*Button
)
171 if (MAIN_GetResource( db
, name
, &value
))
173 Button
->Label
= value
.addr
;
174 i
= strchr(Button
->Label
,'&');
176 Button
->Hotkey
= '\0';
177 else if ( i
++ == '\0' )
178 Button
->Hotkey
= '\0';
182 Button
->Hotkey
= toupper(Button
->Hotkey
);
185 /***********************************************************************
186 * MAIN_GetAllButtonTexts
188 * Read all Button-labels from X11-resources if they exist.
191 static void MAIN_GetAllButtonTexts(XrmDatabase db
)
193 MAIN_GetButtonText(db
, ".YesLabel", &ButtonText
.Yes
);
194 MAIN_GetButtonText(db
, ".NoLabel", &ButtonText
.No
);
195 MAIN_GetButtonText(db
, ".OkLabel", &ButtonText
.Ok
);
196 MAIN_GetButtonText(db
, ".CancelLabel", &ButtonText
.Cancel
);
197 MAIN_GetButtonText(db
, ".AbortLabel", &ButtonText
.Abort
);
198 MAIN_GetButtonText(db
, ".RetryLabel", &ButtonText
.Retry
);
199 MAIN_GetButtonText(db
, ".IgnoreLabel", &ButtonText
.Ignore
);
200 MAIN_GetButtonText(db
, ".CancelLabel", &ButtonText
.Cancel
);
203 /***********************************************************************
206 * Parse command line options and open display.
208 static void MAIN_ParseOptions( int *argc
, char *argv
[] )
212 XrmDatabase db
= NULL
;
214 /* Parse command line */
215 Options
.programName
= MAIN_GetProgramName( *argc
, argv
);
216 XrmParseCommand( &db
, optionsTable
, NB_OPTIONS
,
217 Options
.programName
, argc
, argv
);
220 /* Need to assemble command line and pass it to WinMain */
222 if (*argc
< 2 || strcasecmp(argv
[1], "-h") == 0)
223 MAIN_Usage( argv
[0] );
228 if (MAIN_GetResource( db
, ".display", &value
)) display_name
= value
.addr
;
229 else display_name
= NULL
;
231 if (!(display
= XOpenDisplay( display_name
)))
233 fprintf( stderr
, "%s: Can't open display: %s\n",
234 argv
[0], display_name
? display_name
: "" );
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
, ".backingstore", &value
))
246 Options
.backingstore
= 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
;
257 if (MAIN_GetResource( db
, ".debugmsg", &value
))
259 #ifndef DEBUG_RUNTIME
260 fprintf(stderr
,"%s: Option \"-debugmsg\" not implemented.\n" \
261 " Recompile with DEBUG_RUNTIME in include/stddebug.h defined.\n",
265 char *p
=(char*)value
.addr
;
268 if ((*p
!='+')&&(*p
!='-'))
270 if (!strcasecmp(p
+1,"all"))
273 for (i
=0;i
<sizeof(debug_msg_enabled
)/sizeof(short);i
++)
274 debug_msg_enabled
[i
]=(*p
=='+');
279 for (i
=0;i
<sizeof(debug_msg_enabled
)/sizeof(short);i
++)
280 if (debug_msg_name
&& (!strcasecmp(p
+1,debug_msg_name
[i
])))
282 debug_msg_enabled
[i
]=(*p
=='+');
285 if (i
==sizeof(debug_msg_enabled
)/sizeof(short))
288 fprintf(stderr
,"%s: Syntax: -debugmsg +xxx or -debugmsg -xxx with xxx one of\n",argv
[0]);
289 fprintf(stderr
,"%-9s ","all");
290 for(i
=0;i
<sizeof(debug_msg_enabled
)/sizeof(short);i
++)
291 if(debug_msg_name
[i
])
292 fprintf(stderr
,"%-9s%c",debug_msg_name
[i
],
293 (((i
+2)%8==0)?'\n':' '));
294 fprintf(stderr
,"\n\n");
301 /* MAIN_GetAllButtonTexts(db); */
306 /***********************************************************************
309 static void MAIN_CreateDesktop( int argc
, char *argv
[] )
312 unsigned int width
= 640, height
= 480; /* Default size = 640x480 */
313 char *name
= "Wine desktop";
314 XSizeHints size_hints
;
316 XClassHint class_hints
;
317 XSetWindowAttributes win_attr
;
318 XTextProperty window_name
;
320 flags
= XParseGeometry( Options
.desktopGeometry
,
321 &desktopX
, &desktopY
, &width
, &height
);
323 screenHeight
= height
;
327 win_attr
.event_mask
= ExposureMask
| KeyPressMask
| KeyReleaseMask
|
328 PointerMotionMask
| ButtonPressMask
|
329 ButtonReleaseMask
| EnterWindowMask
|
331 win_attr
.cursor
= XCreateFontCursor( display
, XC_top_left_arrow
);
333 rootWindow
= XCreateWindow( display
, DefaultRootWindow(display
),
334 desktopX
, desktopY
, width
, height
, 0,
335 CopyFromParent
, InputOutput
, CopyFromParent
,
336 CWEventMask
| CWCursor
, &win_attr
);
338 /* Set window manager properties */
340 size_hints
.min_width
= size_hints
.max_width
= width
;
341 size_hints
.min_height
= size_hints
.max_height
= height
;
342 size_hints
.flags
= PMinSize
| PMaxSize
;
343 if (flags
& (XValue
| YValue
)) size_hints
.flags
|= USPosition
;
344 if (flags
& (WidthValue
| HeightValue
)) size_hints
.flags
|= USSize
;
345 else size_hints
.flags
|= PSize
;
347 wm_hints
.flags
= InputHint
| StateHint
;
348 wm_hints
.input
= True
;
349 wm_hints
.initial_state
= NormalState
;
350 class_hints
.res_name
= argv
[0];
351 class_hints
.res_class
= "Wine";
353 XStringListToTextProperty( &name
, 1, &window_name
);
354 XSetWMProperties( display
, rootWindow
, &window_name
, &window_name
,
355 argv
, argc
, &size_hints
, &wm_hints
, &class_hints
);
359 XMapWindow( display
, rootWindow
);
363 XKeyboardState keyboard_state
;
365 /***********************************************************************
368 static void MAIN_SaveSetup(void)
370 XGetKeyboardControl(display
, &keyboard_state
);
373 /***********************************************************************
376 static void MAIN_RestoreSetup(void)
378 XKeyboardControl keyboard_value
;
380 keyboard_value
.key_click_percent
= keyboard_state
.key_click_percent
;
381 keyboard_value
.bell_percent
= keyboard_state
.bell_percent
;
382 keyboard_value
.bell_pitch
= keyboard_state
.bell_pitch
;
383 keyboard_value
.bell_duration
= keyboard_state
.bell_duration
;
384 keyboard_value
.auto_repeat_mode
= keyboard_state
.global_auto_repeat
;
386 XChangeKeyboardControl(display
, KBKeyClickPercent
| KBBellPercent
|
387 KBBellPitch
| KBBellDuration
| KBAutoRepeatMode
, &keyboard_value
);
390 static void called_at_exit(void)
399 /***********************************************************************
402 int main( int argc
, char *argv
[] )
408 setlocale(LC_CTYPE
,"");
412 MAIN_ParseOptions( &argc
, argv
);
414 screen
= DefaultScreenOfDisplay( display
);
415 screenWidth
= WidthOfScreen( screen
);
416 screenHeight
= HeightOfScreen( screen
);
417 if (screenDepth
) /* -depth option specified */
419 depth_list
= XListDepths(display
,DefaultScreen(display
),&depth_count
);
420 for (i
= 0; i
< depth_count
; i
++)
421 if (depth_list
[i
] == screenDepth
) break;
423 if (i
>= depth_count
)
425 fprintf( stderr
, "%s: Depth %d not supported on this screen.\n",
426 Options
.programName
, screenDepth
);
430 else screenDepth
= DefaultDepthOfScreen( screen
);
431 if (Options
.synchronous
) XSynchronize( display
, True
);
432 if (Options
.desktopGeometry
) MAIN_CreateDesktop( argc
, argv
);
433 else rootWindow
= DefaultRootWindow( display
);
442 atexit(called_at_exit
);
444 on_exit (called_at_exit
, 0);
447 ret_val
= _WinMain( argc
, argv
);
452 /***********************************************************************
453 * MessageBeep (USER.104)
455 void MessageBeep(WORD i
)
460 /***********************************************************************
461 * GetVersion (KERNEL.3)
463 LONG
GetVersion(void)
465 return( 0x03300a03 ); /* dos 3.30 & win 3.10 */
468 /***********************************************************************
469 * GetWinFlags (KERNEL.132)
471 LONG
GetWinFlags(void)
473 return (WF_STANDARD
| WF_CPU286
| WF_PMODE
| WF_80x87
);
476 /***********************************************************************
477 * SetEnvironment (GDI.132)
479 int SetEnvironment(LPSTR lpPortName
, LPSTR lpEnviron
, WORD nCount
)
482 LPENVENTRY lpEnv
= lpEnvList
;
483 printf("SetEnvironnement('%s', '%s', %d) !\n",
484 lpPortName
, lpEnviron
, nCount
);
485 if (lpPortName
== NULL
) return -1;
486 while (lpEnv
!= NULL
) {
487 if (lpEnv
->Name
!= NULL
&& strcmp(lpEnv
->Name
, lpPortName
) == 0) {
488 if (nCount
== 0 || lpEnviron
== NULL
) {
489 if (lpEnv
->Prev
!= NULL
) lpEnv
->Prev
->Next
= lpEnv
->Next
;
490 if (lpEnv
->Next
!= NULL
) lpEnv
->Next
->Prev
= lpEnv
->Prev
;
494 printf("SetEnvironnement() // entry deleted !\n");
498 lpEnv
->Value
= malloc(nCount
);
499 if (lpNewEnv
->Value
== NULL
) {
500 printf("SetEnvironment() // Error allocating entry value !\n");
503 memcpy(lpEnv
->Value
, lpEnviron
, nCount
);
504 lpEnv
->wSize
= nCount
;
505 printf("SetEnvironnement() // entry modified !\n");
508 if (lpEnv
->Next
== NULL
) break;
511 if (nCount
== 0 || lpEnviron
== NULL
) return -1;
512 printf("SetEnvironnement() // new entry !\n");
513 lpNewEnv
= malloc(sizeof(ENVENTRY
));
514 if (lpNewEnv
== NULL
) {
515 printf("SetEnvironment() // Error allocating new entry !\n");
518 if (lpEnvList
== NULL
) {
519 lpEnvList
= lpNewEnv
;
520 lpNewEnv
->Prev
= NULL
;
523 lpEnv
->Next
= lpNewEnv
;
524 lpNewEnv
->Prev
= lpEnv
;
526 lpNewEnv
->Next
= NULL
;
527 lpNewEnv
->Name
= malloc(strlen(lpPortName
) + 1);
528 if (lpNewEnv
->Name
== NULL
) {
529 printf("SetEnvironment() // Error allocating entry name !\n");
532 strcpy(lpNewEnv
->Name
, lpPortName
);
533 lpNewEnv
->Value
= malloc(nCount
);
534 if (lpNewEnv
->Value
== NULL
) {
535 printf("SetEnvironment() // Error allocating entry value !\n");
538 memcpy(lpNewEnv
->Value
, lpEnviron
, nCount
);
539 lpNewEnv
->wSize
= nCount
;
543 /***********************************************************************
544 * GetEnvironment (GDI.134)
546 int GetEnvironment(LPSTR lpPortName
, LPSTR lpEnviron
, WORD nMaxSiz
)
549 LPENVENTRY lpEnv
= lpEnvList
;
550 printf("GetEnvironnement('%s', '%s', %d) !\n",
551 lpPortName
, lpEnviron
, nMaxSiz
);
552 while (lpEnv
!= NULL
) {
553 if (lpEnv
->Name
!= NULL
&& strcmp(lpEnv
->Name
, lpPortName
) == 0) {
554 nCount
= min(nMaxSiz
, lpEnv
->wSize
);
555 memcpy(lpEnviron
, lpEnv
->Value
, nCount
);
556 printf("GetEnvironnement() // found '%s' !\n", lpEnviron
);
561 printf("GetEnvironnement() // not found !\n");
565 /***********************************************************************
566 * GetTimerResolution (USER.14)
568 LONG
GetTimerResolution(void)
573 /***********************************************************************
574 * SystemParametersInfo (USER.483)
576 BOOL
SystemParametersInfo (UINT uAction
, UINT uParam
, void FAR
*lpvParam
, UINT fuWinIni
)
580 XKeyboardState keyboard_state
;
581 XKeyboardControl keyboard_value
;
584 fprintf(stderr
, "SystemParametersInfo: action %d, param %x, flag %x\n",
585 uAction
, uParam
, fuWinIni
);
589 XGetKeyboardControl(display
, &keyboard_state
);
590 if (keyboard_state
.bell_percent
== 0)
591 *(BOOL
*) lpvParam
= FALSE
;
593 *(BOOL
*) lpvParam
= TRUE
;
597 *(INT
*) lpvParam
= 1;
600 case SPI_GETFASTTASKSWITCH
:
601 *(BOOL
*) lpvParam
= FALSE
;
604 case SPI_GETGRIDGRANULARITY
:
605 *(INT
*) lpvParam
= 1;
608 case SPI_GETICONTITLEWRAP
:
609 *(BOOL
*) lpvParam
= FALSE
;
612 case SPI_GETKEYBOARDDELAY
:
613 *(INT
*) lpvParam
= 1;
616 case SPI_GETKEYBOARDSPEED
:
617 *(WORD
*) lpvParam
= 30;
620 case SPI_GETMENUDROPALIGNMENT
:
621 *(BOOL
*) lpvParam
= FALSE
;
624 case SPI_GETSCREENSAVEACTIVE
:
625 *(BOOL
*) lpvParam
= FALSE
;
628 case SPI_GETSCREENSAVETIMEOUT
:
629 XGetScreenSaver(display
, &timeout
, &temp
,&temp
,&temp
);
630 *(INT
*) lpvParam
= timeout
* 1000;
633 case SPI_ICONHORIZONTALSPACING
:
634 if (lpvParam
== NULL
)
635 fprintf(stderr
, "SystemParametersInfo: Horizontal icon spacing set to %d\n.", uParam
);
637 *(INT
*) lpvParam
= 50;
640 case SPI_ICONVERTICALSPACING
:
641 if (lpvParam
== NULL
)
642 fprintf(stderr
, "SystemParametersInfo: Vertical icon spacing set to %d\n.", uParam
);
644 *(INT
*) lpvParam
= 50;
649 keyboard_value
.bell_percent
= -1;
651 keyboard_value
.bell_percent
= 0;
652 XChangeKeyboardControl(display
, KBBellPercent
,
656 case SPI_SETSCREENSAVEACTIVE
:
658 XActivateScreenSaver(display
);
660 XResetScreenSaver(display
);
663 case SPI_SETSCREENSAVETIMEOUT
:
664 XSetScreenSaver(display
, uParam
, 60, DefaultBlanking
,
668 case SPI_SETDESKWALLPAPER
:
669 return (SetDeskWallPaper((LPSTR
) lpvParam
));
672 case SPI_SETDESKPATTERN
:
673 if ((INT
) uParam
== -1) {
674 GetProfileString("Desktop", "Pattern",
675 "170 85 170 85 170 85 170 85",
676 buffer
, sizeof(buffer
) );
677 return (DESKTOP_SetPattern((LPSTR
) buffer
));
679 return (DESKTOP_SetPattern((LPSTR
) lpvParam
));
684 case SPI_SETDOUBLECLKHEIGHT
:
685 case SPI_SETDOUBLECLICKTIME
:
686 case SPI_SETDOUBLECLKWIDTH
:
687 case SPI_SETFASTTASKSWITCH
:
688 case SPI_SETKEYBOARDDELAY
:
689 case SPI_SETKEYBOARDSPEED
:
690 fprintf(stderr
, "SystemParametersInfo: option %d ignored.\n", uParam
);
694 fprintf(stderr
, "SystemParametersInfo: unknown option %d.\n", uParam
);
700 /***********************************************************************
701 * HMEMCPY (KERNEL.348)
703 void hmemcpy(void FAR
*hpvDest
, const void FAR
*hpvSource
, long cbCopy
)
705 memcpy(hpvDest
, hpvSource
, cbCopy
);
708 /***********************************************************************
711 void Copy(LPVOID lpSource
, LPVOID lpDest
, WORD nBytes
)
713 memcpy(lpDest
, lpSource
, nBytes
);
716 /***********************************************************************
717 * SWAPMOUSEBUTTON (USER.186)
719 BOOL
SwapMouseButton(BOOL fSwap
)
721 return 0; /* don't swap */
724 /***********************************************************************
725 * ISROMMODULE (KERNEL.323)
727 BOOL
IsRomModule(HANDLE x
)
729 /* I don't know the prototype, I assume that it returns true
730 if the dll is located in rom */
735 /***********************************************************************
736 * FileCDR (KERNEL.130)
738 void FileCDR(FARPROC x
)
740 printf("FileCDR(%8x)\n", (int) x
);