4 * Copyright 1994 Alexandre Julliard
12 /* #include <locale.h> */
13 #ifdef MALLOC_DEBUGGING
17 #include <X11/Xresource.h>
18 #include <X11/Xutil.h>
19 #include <X11/Xlocale.h>
20 #include <X11/cursorfont.h>
30 #include "registers.h"
33 #define DEBUG_DEFINE_VARIABLES
38 const char people
[] = "Wine is available thanks to the work of "
39 "Bob Amstadt, Dag Asheim, Martin Ayotte, Ross Biro, Uwe Bonnes, Erik Bos, "
40 "Fons Botman, John Brezak, Andrew Bulhak, John Burton, "
41 "Niels de Carpentier, Roman Dolejsi, Frans van Dorsselaer, Paul Falstad, "
42 "Olaf Flebbe, Peter Galbavy, Ramon Garcia, Hans de Graaff, "
43 "Charles M. Hannum, John Harvey, Cameron Heide, Jochen Hoenicke, "
44 "Onno Hovers, Jeffrey Hsu, Miguel de Icaza, Jukka Iivonen, "
45 "Alexandre Julliard, Jochen Karrer, Andreas Kirschbaum, Albrecht Kleine, "
46 "Jon Konrath, Alex Korobka, Greg Kreider, Anand Kumria, Scott A. Laird, "
47 "Martin von Loewis, Kenneth MacDonald, Peter MacDonald, William Magro, "
48 "Juergen Marquardt, Marcus Meissner, Graham Menhennitt, David Metcalfe, "
49 "Steffen Moeller, Philippe De Muyter, Itai Nahshon, Michael Patra, "
50 "Jim Peterson, Robert Pouliot, Keith Reynolds, John Richardson, "
51 "Johannes Ruscheinski, Thomas Sandford, Constantine Sapuntzakis, "
52 "Daniel Schepler, Ulrich Schmid, Bernd Schmidt, Yngvi Sigurjonsson, "
53 "Rick Sladkey, William Smith, Erik Svendsen, Tristan Tarrant, "
54 "Andrew Taylor, Duncan C Thomson, Goran Thyni, Jimmy Tirtawangsa, "
55 "Jon Tombs, Linus Torvalds, Gregory Trubetskoy, Michael Veksler, "
56 "Sven Verdoolaege, Eric Warnke, Manfred Weichel, Morten Welinder, "
57 "Jan Willamowius, Carl Williams, Karl Guenter Wuensch, Eric Youngdale, "
58 "and James Youngman. ";
60 const WINE_LANGUAGE_DEF Languages
[] =
62 {"En",0x0409}, /* LANG_En */
63 {"Es",0x040A}, /* LANG_Es */
64 {"De",0x0407}, /* LANG_De */
65 {"No",0x0414}, /* LANG_No */
66 {"Fr",0x0400}, /* LANG_Fr */
67 {"Fi",0x040B}, /* LANG_Fi */
68 {"Da",0x0406}, /* LANG_Da */
69 {"Cz",0x0405}, /* LANG_Cz */
70 {"Eo", 0}, /* LANG_Eo */ /* FIXME languageid */
71 {"It",0x0410}, /* LANG_It */
72 {"Ko",0x0412}, /* LANG_Ko */
76 WORD WINE_LanguageId
= 0;
78 #define WINE_CLASS "Wine" /* Class name for resources */
80 #define WINE_APP_DEFAULTS "/usr/lib/X11/app-defaults/Wine"
82 typedef struct tagENVENTRY
{
86 struct tagENVENTRY
*Prev
;
87 struct tagENVENTRY
*Next
;
88 } ENVENTRY
, *LPENVENTRY
;
90 LPENVENTRY lpEnvList
= NULL
;
95 int screenWidth
= 0, screenHeight
= 0; /* Desktop window dimensions */
96 int screenDepth
= 0; /* Screen depth to use */
97 int desktopX
= 0, desktopY
= 0; /* Desktop window position (if any) */
100 OSVERSIONINFO32A getVersionEx
;
102 struct options Options
=
103 { /* default options */
104 NULL
, /* desktopGeometry */
105 NULL
, /* programName */
106 FALSE
, /* usePrivateMap */
107 FALSE
, /* useFixedMap */
108 FALSE
, /* synchronous */
109 FALSE
, /* backing store */
110 SW_SHOWNORMAL
, /* cmdShow */
112 FALSE
, /* AllowReadOnly */
113 MODE_ENHANCED
, /* Enhanced mode */
114 FALSE
, /* IPC enabled */
116 DEFAULT_LANG
, /* Default language */
120 FALSE
, /* Managed windows */
121 FALSE
/* Perfect graphics */
125 static XrmOptionDescRec optionsTable
[] =
127 { "-backingstore", ".backingstore", XrmoptionNoArg
, (caddr_t
)"on" },
128 { "-desktop", ".desktop", XrmoptionSepArg
, (caddr_t
)NULL
},
129 { "-depth", ".depth", XrmoptionSepArg
, (caddr_t
)NULL
},
130 { "-display", ".display", XrmoptionSepArg
, (caddr_t
)NULL
},
131 { "-iconic", ".iconic", XrmoptionNoArg
, (caddr_t
)"on" },
132 { "-ipc", ".ipc", XrmoptionNoArg
, (caddr_t
)"off"},
133 { "-language", ".language", XrmoptionSepArg
, (caddr_t
)"En" },
134 { "-name", ".name", XrmoptionSepArg
, (caddr_t
)NULL
},
135 { "-perfect", ".perfect", XrmoptionNoArg
, (caddr_t
)"on" },
136 { "-privatemap", ".privatemap", XrmoptionNoArg
, (caddr_t
)"on" },
137 { "-fixedmap", ".fixedmap", XrmoptionNoArg
, (caddr_t
)"on" },
138 { "-synchronous", ".synchronous", XrmoptionNoArg
, (caddr_t
)"on" },
139 { "-debug", ".debug", XrmoptionNoArg
, (caddr_t
)"on" },
140 { "-debugmsg", ".debugmsg", XrmoptionSepArg
, (caddr_t
)NULL
},
141 { "-dll", ".dll", XrmoptionSepArg
, (caddr_t
)NULL
},
142 { "-allowreadonly", ".allowreadonly", XrmoptionNoArg
, (caddr_t
)"on" },
143 { "-mode", ".mode", XrmoptionSepArg
, (caddr_t
)NULL
},
144 { "-managed", ".managed", XrmoptionNoArg
, (caddr_t
)"off"},
145 { "-winver", ".winver", XrmoptionSepArg
, (caddr_t
)NULL
}
148 #define NB_OPTIONS (sizeof(optionsTable) / sizeof(optionsTable[0]))
151 "Usage: %s [options] program_name [arguments]\n" \
154 " -allowreadonly Read only files may be opened in write mode\n" \
155 " -backingstore Turn on backing store\n" \
156 " -debug Enter debugger before starting application\n" \
157 " -debugmsg name Turn debugging-messages on or off\n" \
158 " -depth n Change the depth to use for multiple-depth screens\n" \
159 " -desktop geom Use a desktop window of the given geometry\n" \
160 " -display name Use the specified display\n" \
161 " -dll name Enable or disable built-in DLLs\n" \
162 " -fixedmap Use a \"standard\" color map\n" \
163 " -iconic Start as an icon\n" \
164 " -ipc Enable IPC facilities\n" \
165 " -language xx Set the language (one of En,Es,De,No,Fr,Fi,Da,Cz,Eo,It,Ko)\n" \
166 " -managed Allow the window manager to manage created windows\n" \
167 " -mode mode Start Wine in a particular mode (standard or enhanced)\n" \
168 " -name name Set the application name\n" \
169 " -perfect Favor correctness over speed for graphical operations\n" \
170 " -privatemap Use a private color map\n" \
171 " -synchronous Turn on synchronous display mode\n" \
172 " -winver Version to imitate (one of win31,win95,nt351)\n"
176 /***********************************************************************
180 static void MAIN_Usage( char *name
)
182 fprintf( stderr
, USAGE
, name
);
188 /***********************************************************************
189 * MAIN_GetProgramName
191 * Get the program name. The name is specified by (in order of precedence):
192 * - the option '-name'.
193 * - the environment variable 'WINE_NAME'.
194 * - the last component of argv[0].
196 static char *MAIN_GetProgramName( int argc
, char *argv
[] )
201 for (i
= 1; i
< argc
-1; i
++)
202 if (!strcmp( argv
[i
], "-name" )) return argv
[i
+1];
203 if ((p
= getenv( "WINE_NAME" )) != NULL
) return p
;
204 if ((p
= strrchr( argv
[0], '/' )) != NULL
) return p
+1;
209 /***********************************************************************
212 * Fetch the value of resource 'name' using the correct instance name.
213 * 'name' must begin with '.' or '*'
215 static int MAIN_GetResource( XrmDatabase db
, char *name
, XrmValue
*value
)
217 char *buff_instance
, *buff_class
;
221 buff_instance
= (char *)xmalloc(strlen(Options
.programName
)+strlen(name
)+1);
222 buff_class
= (char *)xmalloc( strlen(WINE_CLASS
) + strlen(name
) + 1 );
224 strcpy( buff_instance
, Options
.programName
);
225 strcat( buff_instance
, name
);
226 strcpy( buff_class
, WINE_CLASS
);
227 strcat( buff_class
, name
);
228 retval
= XrmGetResource( db
, buff_instance
, buff_class
, &dummy
, value
);
229 free( buff_instance
);
235 /***********************************************************************
238 * Turns specific debug messages on or off, according to "options".
239 * Returns TRUE if parsing was successful
243 BOOL
ParseDebugOptions(char *options
)
246 if (strlen(options
)<3)
250 if ((*options
!='+')&&(*options
!='-'))
252 if (strchr(options
,','))
253 l
=strchr(options
,',')-options
;
256 if (!lstrncmpi32A(options
+1,"all",l
-1))
259 for (i
=0;i
<sizeof(debug_msg_enabled
)/sizeof(short);i
++)
260 debug_msg_enabled
[i
]=(*options
=='+');
265 for (i
=0;i
<sizeof(debug_msg_enabled
)/sizeof(short);i
++)
266 if (debug_msg_name
&& (!lstrncmpi32A(options
+1,debug_msg_name
[i
],l
-1)))
268 debug_msg_enabled
[i
]=(*options
=='+');
271 if (i
==sizeof(debug_msg_enabled
)/sizeof(short))
276 while((*options
==',')&&(*(++options
)));
286 /***********************************************************************
287 * MAIN_ParseLanguageOption
289 * Parse -language option.
291 static void MAIN_ParseLanguageOption( char *arg
)
293 const WINE_LANGUAGE_DEF
*p
= Languages
;
295 Options
.language
= LANG_En
; /* First language */
298 if (!lstrcmpi32A( p
->name
, arg
))
300 WINE_LanguageId
= p
->langid
;
305 fprintf( stderr
, "Invalid language specified '%s'. Supported languages are: ", arg
);
306 for (p
= Languages
; p
->name
; p
++) fprintf( stderr
, "%s ", p
->name
);
307 fprintf( stderr
, "\n" );
312 /***********************************************************************
313 * MAIN_ParseModeOption
315 * Parse -mode option.
317 static void MAIN_ParseModeOption( char *arg
)
319 if (!lstrcmpi32A("enhanced", arg
)) Options
.mode
= MODE_ENHANCED
;
320 else if (!lstrcmpi32A("standard", arg
)) Options
.mode
= MODE_STANDARD
;
323 fprintf(stderr
, "Invalid mode '%s' specified.\n", arg
);
324 fprintf(stderr
, "Valid modes are: 'standard', 'enhanced' (default).\n");
329 /**********************************************************************
332 static void MAIN_ParseVersion( char *arg
)
334 /* If you add any other options,
335 verify the values you return on the real thing */
336 if(strcmp(arg
,"win31")==0)
338 getVersion16
= 0x06160A03;
339 /* FIXME: My Win32s installation failed to execute the
340 MSVC 4 test program. So check these values */
341 getVersion32
= 0x80000A03;
342 getVersionEx
.dwMajorVersion
=3;
343 getVersionEx
.dwMinorVersion
=10;
344 getVersionEx
.dwBuildNumber
=0;
345 getVersionEx
.dwPlatformId
=VER_PLATFORM_WIN32s
;
346 strcpy(getVersionEx
.szCSDVersion
,"Win32s 1.3");
348 else if(strcmp(arg
, "win95")==0)
350 getVersion16
= 0x07005F03;
351 getVersion32
= 0xC0000004;
352 getVersionEx
.dwMajorVersion
=4;
353 getVersionEx
.dwMinorVersion
=0;
354 getVersionEx
.dwBuildNumber
=0x40003B6;
355 getVersionEx
.dwPlatformId
=VER_PLATFORM_WIN32_WINDOWS
;
356 strcpy(getVersionEx
.szCSDVersion
,"");
358 else if(strcmp(arg
, "nt351")==0)
360 getVersion16
= 0x05000A03;
361 getVersion32
= 0x04213303;
362 getVersionEx
.dwMajorVersion
=3;
363 getVersionEx
.dwMinorVersion
=51;
364 getVersionEx
.dwBuildNumber
=0x421;
365 getVersionEx
.dwPlatformId
=VER_PLATFORM_WIN32_NT
;
366 strcpy(getVersionEx
.szCSDVersion
,"Service Pack 2");
368 else fprintf(stderr
, "Unknown winver system code - ignored\n");
371 /***********************************************************************
374 * Parse command line options and open display.
376 static void MAIN_ParseOptions( int *argc
, char *argv
[] )
378 char *display_name
= NULL
;
380 XrmDatabase db
= XrmGetFileDatabase(WINE_APP_DEFAULTS
);
384 Options
.programName
= MAIN_GetProgramName( *argc
, argv
);
386 /* Get display name from command line */
387 for (i
= 1; i
< *argc
- 1; i
++)
388 if (!strcmp( argv
[i
], "-display" ))
390 display_name
= argv
[i
+1];
395 /* Need to assemble command line and pass it to WinMain */
397 if (*argc
< 2 || lstrcmpi32A(argv
[1], "-h") == 0)
398 MAIN_Usage( argv
[0] );
403 if (display_name
== NULL
&&
404 MAIN_GetResource( db
, ".display", &value
)) display_name
= value
.addr
;
406 if (!(display
= XOpenDisplay( display_name
)))
408 fprintf( stderr
, "%s: Can't open display: %s\n",
409 argv
[0], display_name
? display_name
: "(none specified)" );
413 /* Merge file and screen databases */
414 if ((xrm_string
= XResourceManagerString( display
)) != NULL
)
416 XrmDatabase display_db
= XrmGetStringDatabase( xrm_string
);
417 XrmMergeDatabases( display_db
, &db
);
420 /* Parse command line */
421 XrmParseCommand( &db
, optionsTable
, NB_OPTIONS
,
422 Options
.programName
, argc
, argv
);
424 /* Get all options */
425 if (MAIN_GetResource( db
, ".iconic", &value
))
426 Options
.cmdShow
= SW_SHOWMINIMIZED
;
427 if (MAIN_GetResource( db
, ".privatemap", &value
))
428 Options
.usePrivateMap
= TRUE
;
429 if (MAIN_GetResource( db
, ".fixedmap", &value
))
430 Options
.useFixedMap
= TRUE
;
431 if (MAIN_GetResource( db
, ".synchronous", &value
))
432 Options
.synchronous
= TRUE
;
433 if (MAIN_GetResource( db
, ".backingstore", &value
))
434 Options
.backingstore
= TRUE
;
435 if (MAIN_GetResource( db
, ".debug", &value
))
436 Options
.debug
= TRUE
;
437 if (MAIN_GetResource( db
, ".allowreadonly", &value
))
438 Options
.allowReadOnly
= TRUE
;
439 if (MAIN_GetResource( db
, ".ipc", &value
))
441 if (MAIN_GetResource( db
, ".perfect", &value
))
442 Options
.perfectGraphics
= TRUE
;
443 if (MAIN_GetResource( db
, ".depth", &value
))
444 screenDepth
= atoi( value
.addr
);
445 if (MAIN_GetResource( db
, ".desktop", &value
))
446 Options
.desktopGeometry
= value
.addr
;
447 if (MAIN_GetResource( db
, ".language", &value
))
448 MAIN_ParseLanguageOption( (char *)value
.addr
);
449 if (MAIN_GetResource( db
, ".managed", &value
))
450 Options
.managed
= TRUE
;
451 if (MAIN_GetResource( db
, ".mode", &value
))
452 MAIN_ParseModeOption( (char *)value
.addr
);
455 if (MAIN_GetResource( db
, ".debugoptions", &value
))
456 ParseDebugOptions((char*)value
.addr
);
458 if (MAIN_GetResource( db
, ".debugmsg", &value
))
460 #ifndef DEBUG_RUNTIME
461 fprintf(stderr
,"%s: Option \"-debugmsg\" not implemented.\n" \
462 " Recompile with DEBUG_RUNTIME in include/stddebug.h defined.\n",
466 if (ParseDebugOptions((char*)value
.addr
)==FALSE
)
469 fprintf(stderr
,"%s: Syntax: -debugmsg +xxx,... or -debugmsg -xxx,...\n",argv
[0]);
470 fprintf(stderr
,"Example: -debugmsg +all,-heap turn on all messages except heap messages\n");
471 fprintf(stderr
,"Available message types:\n");
472 fprintf(stderr
,"%-9s ","all");
473 for(i
=0;i
<sizeof(debug_msg_enabled
)/sizeof(short);i
++)
474 if(debug_msg_name
[i
])
475 fprintf(stderr
,"%-9s%c",debug_msg_name
[i
],
476 (((i
+2)%8==0)?'\n':' '));
477 fprintf(stderr
,"\n\n");
483 if(MAIN_GetResource( db
, ".dll", &value
))
486 if (!BUILTIN_ParseDLLOptions( (char*)value
.addr
))
488 fprintf(stderr
,"%s: Syntax: -dll +xxx,... or -dll -xxx,...\n",argv
[0]);
489 fprintf(stderr
,"Example: -dll -ole2 Do not use emulated OLE2.DLL\n");
490 fprintf(stderr
,"Available DLLs:\n");
495 fprintf(stderr
,"-dll not supported in libwine\n");
499 if(MAIN_GetResource( db
, ".winver", &value
))
500 MAIN_ParseVersion( (char*)value
.addr
);
504 /***********************************************************************
507 static void MAIN_CreateDesktop( int argc
, char *argv
[] )
510 unsigned int width
= 640, height
= 480; /* Default size = 640x480 */
511 char *name
= "Wine desktop";
512 XSizeHints
*size_hints
;
514 XClassHint
*class_hints
;
515 XSetWindowAttributes win_attr
;
516 XTextProperty window_name
;
517 Atom XA_WM_DELETE_WINDOW
;
519 flags
= XParseGeometry( Options
.desktopGeometry
,
520 &desktopX
, &desktopY
, &width
, &height
);
522 screenHeight
= height
;
526 win_attr
.event_mask
= ExposureMask
| KeyPressMask
| KeyReleaseMask
|
527 PointerMotionMask
| ButtonPressMask
|
528 ButtonReleaseMask
| EnterWindowMask
|
530 win_attr
.cursor
= XCreateFontCursor( display
, XC_top_left_arrow
);
532 rootWindow
= XCreateWindow( display
, DefaultRootWindow(display
),
533 desktopX
, desktopY
, width
, height
, 0,
534 CopyFromParent
, InputOutput
, CopyFromParent
,
535 CWEventMask
| CWCursor
, &win_attr
);
537 /* Set window manager properties */
539 size_hints
= XAllocSizeHints();
540 wm_hints
= XAllocWMHints();
541 class_hints
= XAllocClassHint();
542 if (!size_hints
|| !wm_hints
|| !class_hints
)
544 fprintf( stderr
, "Not enough memory for window manager hints.\n" );
547 size_hints
->min_width
= size_hints
->max_width
= width
;
548 size_hints
->min_height
= size_hints
->max_height
= height
;
549 size_hints
->flags
= PMinSize
| PMaxSize
;
550 if (flags
& (XValue
| YValue
)) size_hints
->flags
|= USPosition
;
551 if (flags
& (WidthValue
| HeightValue
)) size_hints
->flags
|= USSize
;
552 else size_hints
->flags
|= PSize
;
554 wm_hints
->flags
= InputHint
| StateHint
;
555 wm_hints
->input
= True
;
556 wm_hints
->initial_state
= NormalState
;
557 class_hints
->res_name
= argv
[0];
558 class_hints
->res_class
= "Wine";
560 XStringListToTextProperty( &name
, 1, &window_name
);
561 XSetWMProperties( display
, rootWindow
, &window_name
, &window_name
,
562 argv
, argc
, size_hints
, wm_hints
, class_hints
);
563 XA_WM_DELETE_WINDOW
= XInternAtom( display
, "WM_DELETE_WINDOW", False
);
564 XSetWMProtocols( display
, rootWindow
, &XA_WM_DELETE_WINDOW
, 1 );
567 XFree( class_hints
);
571 XMapWindow( display
, rootWindow
);
575 XKeyboardState keyboard_state
;
577 /***********************************************************************
580 static void MAIN_SaveSetup(void)
582 XGetKeyboardControl(display
, &keyboard_state
);
585 /***********************************************************************
588 static void MAIN_RestoreSetup(void)
590 XKeyboardControl keyboard_value
;
592 keyboard_value
.key_click_percent
= keyboard_state
.key_click_percent
;
593 keyboard_value
.bell_percent
= keyboard_state
.bell_percent
;
594 keyboard_value
.bell_pitch
= keyboard_state
.bell_pitch
;
595 keyboard_value
.bell_duration
= keyboard_state
.bell_duration
;
596 keyboard_value
.auto_repeat_mode
= keyboard_state
.global_auto_repeat
;
598 XChangeKeyboardControl(display
, KBKeyClickPercent
| KBBellPercent
|
599 KBBellPitch
| KBBellDuration
| KBAutoRepeatMode
, &keyboard_value
);
603 static void called_at_exit(void)
610 /***********************************************************************
613 * Wine initialisation and command-line parsing
615 BOOL32
MAIN_WineInit( int *argc
, char *argv
[] )
621 extern int _WinMain(int argc
, char **argv
);
623 #ifdef MALLOC_DEBUGGING
627 if (!(trace
= getenv("MALLOC_TRACE")))
629 fprintf( stderr
, "MALLOC_TRACE not set. No trace generated\n" );
633 fprintf( stderr
, "malloc trace goes to %s\n", trace
);
641 setlocale(LC_CTYPE
,"");
642 gettimeofday( &tv
, NULL
);
643 MSG_WineStartTicks
= (tv
.tv_sec
* 1000) + (tv
.tv_usec
/ 1000);
647 MAIN_ParseOptions( argc
, argv
);
649 if (Options
.desktopGeometry
&& Options
.managed
)
651 fprintf( stderr
, "%s: -managed and -desktop options cannot be used together\n",
652 Options
.programName
);
656 screen
= DefaultScreenOfDisplay( display
);
657 screenWidth
= WidthOfScreen( screen
);
658 screenHeight
= HeightOfScreen( screen
);
659 if (screenDepth
) /* -depth option specified */
661 depth_list
= XListDepths(display
,DefaultScreen(display
),&depth_count
);
662 for (i
= 0; i
< depth_count
; i
++)
663 if (depth_list
[i
] == screenDepth
) break;
665 if (i
>= depth_count
)
667 fprintf( stderr
, "%s: Depth %d not supported on this screen.\n",
668 Options
.programName
, screenDepth
);
672 else screenDepth
= DefaultDepthOfScreen( screen
);
673 if (Options
.synchronous
) XSynchronize( display
, True
);
674 if (Options
.desktopGeometry
) MAIN_CreateDesktop( *argc
, argv
);
675 else rootWindow
= DefaultRootWindow( display
);
678 atexit(called_at_exit
);
683 /***********************************************************************
684 * MessageBeep (USER.104)
686 void MessageBeep(WORD i
)
692 /***********************************************************************
695 BOOL32
Beep( DWORD dwFreq
, DWORD dwDur
)
697 /* dwFreq and dwDur are ignored by Win95 */
703 /***********************************************************************
704 * GetVersion16 (KERNEL.3)
706 LONG
GetVersion16(void)
708 if (getVersion16
) return getVersion16
;
709 return MAKELONG( WINVERSION
, WINDOSVER
);
713 /***********************************************************************
716 LONG
GetVersion32(void)
718 if (getVersion32
) return getVersion32
;
719 return MAKELONG( 4, DOSVERSION
);
723 /***********************************************************************
726 BOOL32
GetVersionEx32A(OSVERSIONINFO32A
*v
)
728 if(v
->dwOSVersionInfoSize
!=sizeof(OSVERSIONINFO32A
))
730 fprintf(stddeb
,"wrong OSVERSIONINFO size from app");
735 /* Return something like NT 3.5 */
736 v
->dwMajorVersion
= 3;
737 v
->dwMinorVersion
= 5;
738 v
->dwBuildNumber
= 42;
739 v
->dwPlatformId
= VER_PLATFORM_WIN32_NT
;
740 strcpy(v
->szCSDVersion
, "Wine is not an emulator");
743 v
->dwMajorVersion
= getVersionEx
.dwMajorVersion
;
744 v
->dwMinorVersion
= getVersionEx
.dwMinorVersion
;
745 v
->dwBuildNumber
= getVersionEx
.dwBuildNumber
;
746 v
->dwPlatformId
= getVersionEx
.dwPlatformId
;
747 strcpy(v
->szCSDVersion
, getVersionEx
.szCSDVersion
);
752 /***********************************************************************
755 BOOL32
GetVersionEx32W(OSVERSIONINFO32W
*v
)
758 if(v
->dwOSVersionInfoSize
!=sizeof(OSVERSIONINFO32W
))
760 fprintf(stddeb
,"wrong OSVERSIONINFO size from app");
763 v1
.dwOSVersionInfoSize
=sizeof(v1
);
764 GetVersionEx32A(&v1
);
765 v
->dwMajorVersion
= v1
.dwMajorVersion
;
766 v
->dwMinorVersion
= v1
.dwMinorVersion
;
767 v
->dwBuildNumber
= v1
.dwBuildNumber
;
768 v
->dwPlatformId
= v1
.dwPlatformId
;
769 lstrcpyAtoW( v
->szCSDVersion
, v1
.szCSDVersion
);
773 /***********************************************************************
774 * GetWinFlags (KERNEL.132)
776 LONG
GetWinFlags(void)
778 static const long cpuflags
[5] =
779 { WF_CPU086
, WF_CPU186
, WF_CPU286
, WF_CPU386
, WF_CPU486
};
783 /* There doesn't seem to be any Pentium flag. */
785 long cpuflag
= cpuflags
[MIN (runtime_cpu (), 4)];
787 long cpuflag
= cpuflags
[4];
790 switch(Options
.mode
) {
792 result
= (WF_STANDARD
| cpuflag
| WF_PMODE
| WF_80x87
);
796 result
= (WF_ENHANCED
| cpuflag
| WF_PMODE
| WF_80x87
| WF_PAGING
);
800 fprintf(stderr
, "Unknown mode set? This shouldn't happen. Check GetWinFlags()!\n");
803 if( getVersionEx
.dwPlatformId
== VER_PLATFORM_WIN32_NT
)
804 result
|= 0x4000; /* undocumented WF_WINNT */
808 /***********************************************************************
809 * SetEnvironment (GDI.132)
811 int SetEnvironment(LPCSTR lpPortName
, LPCSTR lpEnviron
, WORD nCount
)
814 LPENVENTRY lpEnv
= lpEnvList
;
815 dprintf_env(stddeb
, "SetEnvironment('%s', '%s', %d) !\n",
816 lpPortName
, lpEnviron
, nCount
);
817 if (lpPortName
== NULL
) return -1;
818 while (lpEnv
!= NULL
) {
819 if (lpEnv
->Name
!= NULL
&& strcmp(lpEnv
->Name
, lpPortName
) == 0) {
820 if (nCount
== 0 || lpEnviron
== NULL
) {
821 if (lpEnv
->Prev
!= NULL
) lpEnv
->Prev
->Next
= lpEnv
->Next
;
822 if (lpEnv
->Next
!= NULL
) lpEnv
->Next
->Prev
= lpEnv
->Prev
;
826 dprintf_env(stddeb
, "SetEnvironment() // entry deleted !\n");
830 lpEnv
->Value
= malloc(nCount
);
831 if (lpEnv
->Value
== NULL
) {
832 dprintf_env(stddeb
, "SetEnvironment() // Error allocating entry value !\n");
835 memcpy(lpEnv
->Value
, lpEnviron
, nCount
);
836 lpEnv
->wSize
= nCount
;
837 dprintf_env(stddeb
, "SetEnvironment() // entry modified !\n");
840 if (lpEnv
->Next
== NULL
) break;
843 if (nCount
== 0 || lpEnviron
== NULL
) return -1;
844 dprintf_env(stddeb
, "SetEnvironment() // new entry !\n");
845 lpNewEnv
= malloc(sizeof(ENVENTRY
));
846 if (lpNewEnv
== NULL
) {
847 dprintf_env(stddeb
, "SetEnvironment() // Error allocating new entry !\n");
850 if (lpEnvList
== NULL
) {
851 lpEnvList
= lpNewEnv
;
852 lpNewEnv
->Prev
= NULL
;
856 lpEnv
->Next
= lpNewEnv
;
857 lpNewEnv
->Prev
= lpEnv
;
859 lpNewEnv
->Next
= NULL
;
860 lpNewEnv
->Name
= malloc(strlen(lpPortName
) + 1);
861 if (lpNewEnv
->Name
== NULL
) {
862 dprintf_env(stddeb
, "SetEnvironment() // Error allocating entry name !\n");
865 strcpy(lpNewEnv
->Name
, lpPortName
);
866 lpNewEnv
->Value
= malloc(nCount
);
867 if (lpNewEnv
->Value
== NULL
) {
868 dprintf_env(stddeb
, "SetEnvironment() // Error allocating entry value !\n");
871 memcpy(lpNewEnv
->Value
, lpEnviron
, nCount
);
872 lpNewEnv
->wSize
= nCount
;
877 /***********************************************************************
878 * SetEnvironmentVariable32A (KERNEL32.484)
880 BOOL32
SetEnvironmentVariable32A( LPCSTR lpName
, LPCSTR lpValue
)
884 rc
= SetEnvironment(lpName
, lpValue
, lpValue
?(strlen(lpValue
)+1):0);
885 return (rc
>0)?TRUE
:FALSE
;
889 /***********************************************************************
890 * SetEnvironmentVariable32W (KERNEL32.485)
892 BOOL32
SetEnvironmentVariable32W( LPCWSTR lpName
, LPCWSTR lpValue
)
894 LPSTR lpNameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpName
);
895 LPSTR lpValueA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpValue
);
896 BOOL32 ret
= SetEnvironmentVariable32A(lpNameA
,lpValueA
);
897 HeapFree( GetProcessHeap(), 0, lpNameA
);
898 HeapFree( GetProcessHeap(), 0, lpValueA
);
903 /***********************************************************************
904 * GetEnvironment (GDI.134)
906 int GetEnvironment(LPSTR lpPortName
, LPSTR lpEnviron
, WORD nMaxSiz
)
909 LPENVENTRY lpEnv
= lpEnvList
;
911 dprintf_env(stddeb
, "GetEnvironment('%s', '%s', %d) !\n",
912 lpPortName
, lpEnviron
, nMaxSiz
);
913 while (lpEnv
!= NULL
) {
914 if (lpEnv
->Name
!= NULL
&& strcmp(lpEnv
->Name
, lpPortName
) == 0) {
915 if( lpEnviron
== NULL
) return lpEnv
->wSize
;
916 nCount
= MIN(nMaxSiz
, lpEnv
->wSize
);
917 memcpy(lpEnviron
, lpEnv
->Value
, nCount
);
918 dprintf_env(stddeb
, "GetEnvironment() // found '%s' !\n", lpEnv
->Value
);
923 dprintf_env(stddeb
, "GetEnvironment() // not found !\n");
927 /***********************************************************************
928 * GetEnvironmentVariable32A (KERNEL32.213)
930 DWORD
GetEnvironmentVariable32A( LPSTR lpName
, LPSTR lpValue
, DWORD size
)
932 return GetEnvironment(lpName
, lpValue
, size
);
935 /***********************************************************************
936 * GetEnvironmentVariable32W (KERNEL32.214)
938 DWORD
GetEnvironmentVariable32W( LPWSTR nameW
, LPWSTR valW
, DWORD size
)
940 LPSTR name
= HEAP_strdupWtoA( GetProcessHeap(), 0, nameW
);
941 LPSTR val
= valW
? HeapAlloc( GetProcessHeap(), 0, size
) : NULL
;
942 DWORD res
= GetEnvironment( name
, val
, size
);
943 HeapFree( GetProcessHeap(), 0, name
);
946 lstrcpyAtoW( valW
, val
);
947 HeapFree( GetProcessHeap(), 0, val
);
952 /***********************************************************************
953 * GetEnvironmentStrings (KERNEL32.210)
955 LPVOID
GetEnvironmentStrings(void)
959 char *envtable
, *envptr
;
961 /* Count the total number of bytes we'll need for the string
962 * table. Include the trailing nuls and the final double nul.
968 if(lpEnv
->Name
!= NULL
)
970 count
+= strlen(lpEnv
->Name
) + 1;
971 count
+= strlen(lpEnv
->Value
) + 1;
976 envtable
= malloc(count
);
984 if(lpEnv
->Name
!= NULL
)
986 count
= sprintf(envptr
, "%s=%s", lpEnv
->Name
, lpEnv
->Value
);
998 LPVOID
GetEnvironmentStringsW(void)
1002 char *envtable
, *envptr
;
1005 /* Count the total number of bytes we'll need for the string
1006 * table. Include the trailing nuls and the final double nul.
1010 while(lpEnv
!= NULL
)
1012 if(lpEnv
->Name
!= NULL
)
1014 count
+= strlen(lpEnv
->Name
) + 1;
1015 count
+= strlen(lpEnv
->Value
) + 1;
1017 lpEnv
= lpEnv
->Next
;
1021 envtable
= malloc(count
);
1027 while(lpEnv
!= NULL
)
1029 if(lpEnv
->Name
!= NULL
)
1031 count
= sprintf(envptr
, "%s=%s", lpEnv
->Name
, lpEnv
->Value
);
1032 envptr
+= count
+ 1;
1034 lpEnv
= lpEnv
->Next
;
1039 wenvtable
= malloc(2*len
);
1040 for(count
=0;count
<len
;count
++)
1041 wenvtable
[count
]=(WCHAR
)envtable
[count
];
1047 void FreeEnvironmentStringsA(void *e
)
1052 void FreeEnvironmentStringsW(void* e
)
1057 /***********************************************************************
1058 * GetTimerResolution (USER.14)
1060 LONG
GetTimerResolution(void)
1065 /***********************************************************************
1066 * SystemParametersInfo32A (USER32.539)
1068 BOOL32
SystemParametersInfo32A( UINT32 uAction
, UINT32 uParam
,
1069 LPVOID lpvParam
, UINT32 fuWinIni
)
1071 return SystemParametersInfo16(uAction
,uParam
,lpvParam
,fuWinIni
);
1075 /***********************************************************************
1076 * SystemParametersInfo16 (USER.483)
1078 BOOL16
SystemParametersInfo16( UINT16 uAction
, UINT16 uParam
,
1079 LPVOID lpvParam
, UINT16 fuWinIni
)
1083 XKeyboardState keyboard_state
;
1084 XKeyboardControl keyboard_value
;
1090 XGetKeyboardControl(display
, &keyboard_state
);
1091 if (keyboard_state
.bell_percent
== 0)
1092 *(BOOL
*) lpvParam
= FALSE
;
1094 *(BOOL
*) lpvParam
= TRUE
;
1098 *(INT
*)lpvParam
= GetSystemMetrics( SM_CXFRAME
);
1101 case SPI_GETFASTTASKSWITCH
:
1102 if ( GetProfileInt32A( "windows", "CoolSwitch", 1 ) == 1 )
1103 *(BOOL
*) lpvParam
= TRUE
;
1105 *(BOOL
*) lpvParam
= FALSE
;
1108 case SPI_GETGRIDGRANULARITY
:
1109 *(INT
*) lpvParam
= GetProfileInt32A( "desktop",
1114 case SPI_GETICONTITLEWRAP
:
1115 *(BOOL
*) lpvParam
= GetProfileInt32A( "desktop",
1120 case SPI_GETKEYBOARDDELAY
:
1121 *(INT
*) lpvParam
= GetProfileInt32A( "keyboard",
1122 "KeyboardDelay", 1 );
1125 case SPI_GETKEYBOARDSPEED
:
1126 *(WORD
*) lpvParam
= GetProfileInt32A( "keyboard",
1131 case SPI_GETMENUDROPALIGNMENT
:
1132 *(BOOL
*) lpvParam
= GetSystemMetrics( SM_MENUDROPALIGNMENT
); /* XXX check this */
1135 case SPI_GETSCREENSAVEACTIVE
:
1136 if ( GetProfileInt32A( "windows", "ScreenSaveActive", 1 ) == 1 )
1137 *(BOOL
*) lpvParam
= TRUE
;
1139 *(BOOL
*) lpvParam
= FALSE
;
1142 case SPI_GETSCREENSAVETIMEOUT
:
1143 /* FIXME GetProfileInt( "windows", "ScreenSaveTimeout", 300 ); */
1144 XGetScreenSaver(display
, &timeout
, &temp
,&temp
,&temp
);
1145 *(INT
*) lpvParam
= timeout
* 1000;
1148 case SPI_ICONHORIZONTALSPACING
:
1149 /* FIXME Get/SetProfileInt */
1150 if (lpvParam
== NULL
)
1151 /*SetSystemMetrics( SM_CXICONSPACING, uParam )*/ ;
1153 *(INT
*) lpvParam
= GetSystemMetrics( SM_CXICONSPACING
);
1156 case SPI_ICONVERTICALSPACING
:
1157 /* FIXME Get/SetProfileInt */
1158 if (lpvParam
== NULL
)
1159 /*SetSystemMetrics( SM_CYICONSPACING, uParam )*/ ;
1161 *(INT
*) lpvParam
= GetSystemMetrics(SM_CYICONSPACING
);
1166 keyboard_value
.bell_percent
= -1;
1168 keyboard_value
.bell_percent
= 0;
1169 XChangeKeyboardControl(display
, KBBellPercent
,
1173 case SPI_SETSCREENSAVEACTIVE
:
1175 XActivateScreenSaver(display
);
1177 XResetScreenSaver(display
);
1180 case SPI_SETSCREENSAVETIMEOUT
:
1181 XSetScreenSaver(display
, uParam
, 60, DefaultBlanking
,
1185 case SPI_SETDESKWALLPAPER
:
1186 return (SetDeskWallPaper32((LPSTR
) lpvParam
));
1189 case SPI_SETDESKPATTERN
:
1190 if ((INT16
)uParam
== -1) {
1191 GetProfileString32A("Desktop", "Pattern",
1192 "170 85 170 85 170 85 170 85",
1193 buffer
, sizeof(buffer
) );
1194 return (DESKTOP_SetPattern((LPSTR
) buffer
));
1196 return (DESKTOP_SetPattern((LPSTR
) lpvParam
));
1199 case SPI_GETICONTITLELOGFONT
:
1201 /* FIXME GetProfileString32A( "?", "?", "?" ) */
1202 LPLOGFONT16 lpLogFont
= (LPLOGFONT16
)lpvParam
;
1203 lpLogFont
->lfHeight
= 10;
1204 lpLogFont
->lfWidth
= 0;
1205 lpLogFont
->lfEscapement
= lpLogFont
->lfOrientation
= 0;
1206 lpLogFont
->lfWeight
= FW_NORMAL
;
1207 lpLogFont
->lfItalic
= FALSE
;
1208 lpLogFont
->lfStrikeOut
= FALSE
;
1209 lpLogFont
->lfUnderline
= FALSE
;
1210 lpLogFont
->lfCharSet
= ANSI_CHARSET
;
1211 lpLogFont
->lfOutPrecision
= OUT_DEFAULT_PRECIS
;
1212 lpLogFont
->lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
1213 lpLogFont
->lfPitchAndFamily
= DEFAULT_PITCH
| FF_SWISS
;
1217 case SPI_LANGDRIVER
:
1219 case SPI_SETDOUBLECLKHEIGHT
:
1220 case SPI_SETDOUBLECLICKTIME
:
1221 case SPI_SETDOUBLECLKWIDTH
:
1222 case SPI_SETFASTTASKSWITCH
:
1223 case SPI_SETKEYBOARDDELAY
:
1224 case SPI_SETKEYBOARDSPEED
:
1225 fprintf(stderr
, "SystemParametersInfo: option %d ignored.\n", uAction
);
1228 case SPI_GETWORKAREA
:
1229 SetRect16( (RECT16
*)lpvParam
, 0, 0,
1230 GetSystemMetrics( SM_CXSCREEN
),
1231 GetSystemMetrics( SM_CYSCREEN
) );
1235 fprintf(stderr
, "SystemParametersInfo: unknown option %d.\n", uAction
);
1241 /***********************************************************************
1242 * SystemParametersInfo32W (USER32.540)
1244 BOOL32
SystemParametersInfo32W( UINT32 uAction
, UINT32 uParam
,
1245 LPVOID lpvParam
, UINT32 fuWinIni
)
1251 case SPI_SETDESKWALLPAPER
:
1254 lstrcpynWtoA(buffer
,(LPWSTR
)lpvParam
,sizeof(buffer
));
1255 return SetDeskWallPaper32(buffer
);
1257 return SetDeskWallPaper32(NULL
);
1259 case SPI_SETDESKPATTERN
:
1260 if ((INT
) uParam
== -1)
1262 GetProfileString32A("Desktop", "Pattern",
1263 "170 85 170 85 170 85 170 85",
1264 buffer
, sizeof(buffer
) );
1265 return (DESKTOP_SetPattern((LPSTR
) buffer
));
1269 lstrcpynWtoA(buffer
,(LPWSTR
)lpvParam
,sizeof(buffer
));
1270 return DESKTOP_SetPattern(buffer
);
1272 return DESKTOP_SetPattern(NULL
);
1274 case SPI_GETICONTITLELOGFONT
:
1276 /* FIXME GetProfileString32A( "?", "?", "?" ) */
1277 LPLOGFONT32W lpLogFont
= (LPLOGFONT32W
)lpvParam
;
1278 lpLogFont
->lfHeight
= 10;
1279 lpLogFont
->lfWidth
= 0;
1280 lpLogFont
->lfEscapement
= lpLogFont
->lfOrientation
= 0;
1281 lpLogFont
->lfWeight
= FW_NORMAL
;
1282 lpLogFont
->lfItalic
= lpLogFont
->lfStrikeOut
= lpLogFont
->lfUnderline
= FALSE
;
1283 lpLogFont
->lfCharSet
= ANSI_CHARSET
;
1284 lpLogFont
->lfOutPrecision
= OUT_DEFAULT_PRECIS
;
1285 lpLogFont
->lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
1286 lpLogFont
->lfPitchAndFamily
= DEFAULT_PITCH
| FF_SWISS
;
1291 return SystemParametersInfo32A(uAction
,uParam
,lpvParam
,fuWinIni
);
1298 /***********************************************************************
1301 void Copy(LPVOID lpSource
, LPVOID lpDest
, WORD nBytes
)
1303 memcpy(lpDest
, lpSource
, nBytes
);
1306 /***********************************************************************
1307 * SWAPMOUSEBUTTON (USER.186)
1309 BOOL
SwapMouseButton(BOOL fSwap
)
1311 return 0; /* don't swap */
1314 /***********************************************************************
1315 * FileCDR (KERNEL.130)
1317 void FileCDR(FARPROC16 x
)
1319 printf("FileCDR(%8x)\n", (int) x
);
1322 /***********************************************************************
1323 * GetWinDebugInfo (KERNEL.355)
1325 BOOL
GetWinDebugInfo(WINDEBUGINFO
*lpwdi
, UINT flags
)
1327 printf("GetWinDebugInfo(%8lx,%d) stub returning 0\n", (unsigned long)lpwdi
, flags
);
1328 /* 0 means not in debugging mode/version */
1329 /* Can this type of debugging be used in wine ? */
1330 /* Constants: WDI_OPTIONS WDI_FILTER WDI_ALLOCBREAK */
1334 /***********************************************************************
1335 * GetWinDebugInfo (KERNEL.355)
1337 BOOL
SetWinDebugInfo(WINDEBUGINFO
*lpwdi
)
1339 printf("SetWinDebugInfo(%8lx) stub returning 0\n", (unsigned long)lpwdi
);
1340 /* 0 means not in debugging mode/version */
1341 /* Can this type of debugging be used in wine ? */
1342 /* Constants: WDI_OPTIONS WDI_FILTER WDI_ALLOCBREAK */