Release 960314
[wine.git] / misc / main.c
blobeb198857dccd2a336fc297629bbbc1210346ed09
1 /*
2 * Main function.
4 * Copyright 1994 Alexandre Julliard
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <ctype.h>
12 #include <locale.h>
13 #ifdef MALLOC_DEBUGGING
14 #include <malloc.h>
15 #endif
16 #include <X11/Xlib.h>
17 #include <X11/Xresource.h>
18 #include <X11/Xutil.h>
19 #include <X11/cursorfont.h>
20 #include "wine.h"
21 #include "message.h"
22 #include "msdos.h"
23 #include "windows.h"
24 #include "winsock.h"
25 #include "options.h"
26 #include "desktop.h"
27 #include "shell.h"
28 #include "dlls.h"
29 #define DEBUG_DEFINE_VARIABLES
30 #include "stddebug.h"
31 #include "debug.h"
32 #include "xmalloc.h"
34 const char people[] = "Wine is available thanks to the work of "
35 "Bob Amstadt, Dag Asheim, Martin Ayotte, Ross Biro, Erik Bos, "
36 "Fons Botman, John Brezak, Andrew Bulhak, John Burton, Paul Falstad, "
37 "Olaf Flebbe, Peter Galbavy, Ramon Garcia, Hans de Graaff, "
38 "Charles M. Hannum, Cameron Heide, Jochen Hoenicke, Jeffrey Hsu, "
39 "Miguel de Icaza, Alexandre Julliard, Jon Konrath, Scott A. Laird, "
40 "Martin von Loewis, Kenneth MacDonald, Peter MacDonald, William Magro, "
41 "Marcus Meissner, Graham Menhennitt, David Metcalfe, Michael Patra, "
42 "John Richardson, Johannes Ruscheinski, Thomas Sandford, "
43 "Constantine Sapuntzakis, Daniel Schepler, Bernd Schmidt, "
44 "Yngvi Sigurjonsson, Rick Sladkey, William Smith, Erik Svendsen, "
45 "Goran Thyni, Jimmy Tirtawangsa, Jon Tombs, Linus Torvalds, "
46 "Gregory Trubetskoy, Michael Veksler, Morten Welinder, Jan Willamowius, "
47 "Carl Williams, Karl Guenter Wuensch, Eric Youngdale, and James Youngman.";
49 static const char *langNames[] =
51 "En", /* LANG_En */
52 "Es", /* LANG_Es */
53 "De", /* LANG_De */
54 "No", /* LANG_No */
55 "Fr", /* LANG_Fr */
56 "Fi", /* LANG_Fi */
57 "Da", /* LANG_Da */
58 "Cz", /* LANG_Cz */
59 "Eo", /* LANG_Eo */
60 NULL
63 #define WINE_CLASS "Wine" /* Class name for resources */
65 typedef struct tagENVENTRY {
66 LPSTR Name;
67 LPSTR Value;
68 WORD wSize;
69 struct tagENVENTRY *Prev;
70 struct tagENVENTRY *Next;
71 } ENVENTRY, *LPENVENTRY;
73 LPENVENTRY lpEnvList = NULL;
75 Display *display;
76 Screen *screen;
77 Window rootWindow;
78 int screenWidth = 0, screenHeight = 0; /* Desktop window dimensions */
79 int screenDepth = 0; /* Screen depth to use */
80 int desktopX = 0, desktopY = 0; /* Desktop window position (if any) */
82 struct options Options =
83 { /* default options */
84 NULL, /* desktopGeometry */
85 NULL, /* programName */
86 FALSE, /* usePrivateMap */
87 FALSE, /* useFixedMap */
88 FALSE, /* synchronous */
89 FALSE, /* backing store */
90 SW_SHOWNORMAL, /* cmdShow */
91 FALSE,
92 FALSE, /* AllowReadOnly */
93 MODE_ENHANCED, /* Enhanced mode */
94 FALSE, /* IPC enabled */
95 #ifdef DEFAULT_LANG
96 DEFAULT_LANG, /* Default language */
97 #else
98 LANG_En,
99 #endif
100 FALSE /* Managed windows */
104 static XrmOptionDescRec optionsTable[] =
106 { "-backingstore", ".backingstore", XrmoptionNoArg, (caddr_t)"on" },
107 { "-desktop", ".desktop", XrmoptionSepArg, (caddr_t)NULL },
108 { "-depth", ".depth", XrmoptionSepArg, (caddr_t)NULL },
109 { "-display", ".display", XrmoptionSepArg, (caddr_t)NULL },
110 { "-iconic", ".iconic", XrmoptionNoArg, (caddr_t)"on" },
111 { "-ipc", ".ipc", XrmoptionNoArg, (caddr_t)"off"},
112 { "-language", ".language", XrmoptionSepArg, (caddr_t)"En" },
113 { "-name", ".name", XrmoptionSepArg, (caddr_t)NULL },
114 { "-privatemap", ".privatemap", XrmoptionNoArg, (caddr_t)"on" },
115 { "-fixedmap", ".fixedmap", XrmoptionNoArg, (caddr_t)NULL },
116 { "-synchronous", ".synchronous", XrmoptionNoArg, (caddr_t)"on" },
117 { "-debug", ".debug", XrmoptionNoArg, (caddr_t)"on" },
118 { "-debugmsg", ".debugmsg", XrmoptionSepArg, (caddr_t)NULL },
119 { "-dll", ".dll", XrmoptionSepArg, (caddr_t)NULL },
120 { "-allowreadonly", ".allowreadonly", XrmoptionNoArg, (caddr_t)"on" },
121 { "-mode", ".mode", XrmoptionSepArg, (caddr_t)NULL },
122 { "-managed", ".managed", XrmoptionNoArg, (caddr_t)"off"}
125 #define NB_OPTIONS (sizeof(optionsTable) / sizeof(optionsTable[0]))
127 #define USAGE \
128 "Usage: %s [options] program_name [arguments]\n" \
129 "\n" \
130 "Options:\n" \
131 " -allowreadonly Read only files may be opened in write mode\n" \
132 " -backingstore Turn on backing store\n" \
133 " -debug Enter debugger before starting application\n" \
134 " -debugmsg name Turn debugging-messages on or off\n" \
135 " -depth n Change the depth to use for multiple-depth screens\n" \
136 " -desktop geom Use a desktop window of the given geometry\n" \
137 " -display name Use the specified display\n" \
138 " -dll name Enable or disable built-in DLLs\n" \
139 " -fixedmap Use a \"standard\" color map\n" \
140 " -iconic Start as an icon\n" \
141 " -ipc Enable IPC facilities\n" \
142 " -language xx Set the language (one of En,Es,De,No,Fr,Fi,Da,Cz,Eo)\n" \
143 " -managed Allow the window manager to manage created windows\n" \
144 " -mode mode Start Wine in a particular mode (standard or enhanced)\n" \
145 " -name name Set the application name\n" \
146 " -privatemap Use a private color map\n" \
147 " -synchronous Turn on synchronous display mode\n"
151 /***********************************************************************
152 * MAIN_Usage
154 #ifndef WINELIB32
155 static void MAIN_Usage( char *name )
157 fprintf( stderr, USAGE, name );
158 exit(1);
160 #endif
163 /***********************************************************************
164 * MAIN_GetProgramName
166 * Get the program name. The name is specified by (in order of precedence):
167 * - the option '-name'.
168 * - the environment variable 'WINE_NAME'.
169 * - the last component of argv[0].
171 static char *MAIN_GetProgramName( int argc, char *argv[] )
173 int i;
174 char *p;
176 for (i = 1; i < argc-1; i++)
177 if (!strcmp( argv[i], "-name" )) return argv[i+1];
178 if ((p = getenv( "WINE_NAME" )) != NULL) return p;
179 if ((p = strrchr( argv[0], '/' )) != NULL) return p+1;
180 return argv[0];
184 /***********************************************************************
185 * MAIN_GetResource
187 * Fetch the value of resource 'name' using the correct instance name.
188 * 'name' must begin with '.' or '*'
190 static int MAIN_GetResource( XrmDatabase db, char *name, XrmValue *value )
192 char *buff_instance, *buff_class;
193 char *dummy;
194 int retval;
196 buff_instance = (char *)xmalloc(strlen(Options.programName)+strlen(name)+1);
197 buff_class = (char *)xmalloc( strlen(WINE_CLASS) + strlen(name) + 1 );
199 strcpy( buff_instance, Options.programName );
200 strcat( buff_instance, name );
201 strcpy( buff_class, WINE_CLASS );
202 strcat( buff_class, name );
203 retval = XrmGetResource( db, buff_instance, buff_class, &dummy, value );
204 free( buff_instance );
205 free( buff_class );
206 return retval;
210 /***********************************************************************
211 * ParseDebugOptions
213 * Turns specific debug messages on or off, according to "options".
214 * Returns TRUE if parsing was successfull
216 #ifdef DEBUG_RUNTIME
218 BOOL ParseDebugOptions(char *options)
220 int l;
221 if (strlen(options)<3)
222 return FALSE;
225 if ((*options!='+')&&(*options!='-'))
226 return FALSE;
227 if (strchr(options,','))
228 l=strchr(options,',')-options;
229 else
230 l=strlen(options);
231 if (!lstrncmpi(options+1,"all",l-1))
233 int i;
234 for (i=0;i<sizeof(debug_msg_enabled)/sizeof(short);i++)
235 debug_msg_enabled[i]=(*options=='+');
237 else
239 int i;
240 for (i=0;i<sizeof(debug_msg_enabled)/sizeof(short);i++)
241 if (debug_msg_name && (!lstrncmpi(options+1,debug_msg_name[i],l-1)))
243 debug_msg_enabled[i]=(*options=='+');
244 break;
246 if (i==sizeof(debug_msg_enabled)/sizeof(short))
247 return FALSE;
249 options+=l;
251 while((*options==',')&&(*(++options)));
252 if (*options)
253 return FALSE;
254 else
255 return TRUE;
258 #endif
260 #ifndef WINELIB
261 /***********************************************************************
262 * MAIN_ParseDLLOptions
264 * Set runtime DLL usage flags
266 static BOOL MAIN_ParseDLLOptions(char *options)
268 int l;
269 int i;
270 if (strlen(options)<3)
271 return FALSE;
274 if ((*options!='+')&&(*options!='-'))
275 return FALSE;
276 if (strchr(options,','))
277 l=strchr(options,',')-options;
278 else l=strlen(options);
279 for (i=0;i<N_BUILTINS;i++)
280 if (!lstrncmpi(options+1,dll_builtin_table[i].name,l-1))
282 dll_builtin_table[i].used = (*options=='+');
283 break;
285 if (i==N_BUILTINS)
286 return FALSE;
287 options+=l;
289 while((*options==',')&&(*(++options)));
290 if (*options)
291 return FALSE;
292 else
293 return TRUE;
295 #endif
299 /***********************************************************************
300 * MAIN_ParseLanguageOption
302 * Parse -language option.
304 static void MAIN_ParseLanguageOption( char *arg )
306 const char **p = langNames;
308 Options.language = LANG_En; /* First language */
309 for (p = langNames; *p; p++)
311 if (!lstrcmpi( *p, arg )) return;
312 Options.language++;
314 fprintf( stderr, "Invalid language specified '%s'. Supported languages are: ", arg );
315 for (p = langNames; *p; p++) fprintf( stderr, "%s ", *p );
316 fprintf( stderr, "\n" );
317 exit(1);
321 /***********************************************************************
322 * MAIN_ParseModeOption
324 * Parse -mode option.
326 static void MAIN_ParseModeOption( char *arg )
328 if (!lstrcmpi("enhanced", arg)) Options.mode = MODE_ENHANCED;
329 else if (!lstrcmpi("standard", arg)) Options.mode = MODE_STANDARD;
330 else
332 fprintf(stderr, "Invalid mode '%s' specified.\n", arg);
333 fprintf(stderr, "Valid modes are: 'standard', 'enhanced' (default).\n");
334 exit(1);
339 /***********************************************************************
340 * MAIN_ParseOptions
342 * Parse command line options and open display.
344 static void MAIN_ParseOptions( int *argc, char *argv[] )
346 char *display_name;
347 XrmValue value;
348 XrmDatabase db = XrmGetFileDatabase("/usr/lib/X11/app-defaults/Wine");
350 /* Parse command line */
351 Options.programName = MAIN_GetProgramName( *argc, argv );
352 XrmParseCommand( &db, optionsTable, NB_OPTIONS,
353 Options.programName, argc, argv );
355 #ifdef WINELIB
356 /* Need to assemble command line and pass it to WinMain */
357 #else
358 if (*argc < 2 || lstrcmpi(argv[1], "-h") == 0)
359 MAIN_Usage( argv[0] );
360 #endif
362 /* Open display */
364 if (MAIN_GetResource( db, ".display", &value )) display_name = value.addr;
365 else display_name = NULL;
367 if (!(display = XOpenDisplay( display_name )))
369 fprintf( stderr, "%s: Can't open display: %s\n",
370 argv[0], display_name ? display_name : "(none specified)" );
371 exit(1);
374 /* Get all options */
375 if (MAIN_GetResource( db, ".iconic", &value ))
376 Options.cmdShow = SW_SHOWMINIMIZED;
377 if (MAIN_GetResource( db, ".privatemap", &value ))
378 Options.usePrivateMap = TRUE;
379 if (MAIN_GetResource( db, ".fixedmap", &value ))
380 Options.useFixedMap = TRUE;
381 if (MAIN_GetResource( db, ".synchronous", &value ))
382 Options.synchronous = TRUE;
383 if (MAIN_GetResource( db, ".backingstore", &value ))
384 Options.backingstore = TRUE;
385 if (MAIN_GetResource( db, ".debug", &value ))
386 Options.debug = TRUE;
387 if (MAIN_GetResource( db, ".allowreadonly", &value ))
388 Options.allowReadOnly = TRUE;
389 if (MAIN_GetResource( db, ".ipc", &value ))
390 Options.ipc = TRUE;
391 if (MAIN_GetResource( db, ".depth", &value))
392 screenDepth = atoi( value.addr );
393 if (MAIN_GetResource( db, ".desktop", &value))
394 Options.desktopGeometry = value.addr;
395 if (MAIN_GetResource( db, ".language", &value))
396 MAIN_ParseLanguageOption( (char *)value.addr );
397 if (MAIN_GetResource( db, ".managed", &value))
398 Options.managed = TRUE;
399 if (MAIN_GetResource( db, ".mode", &value))
400 MAIN_ParseModeOption( (char *)value.addr );
402 #ifdef DEBUG_RUNTIME
403 if (MAIN_GetResource( db, ".debugoptions", &value))
404 ParseDebugOptions((char*)value.addr);
405 #endif
406 if (MAIN_GetResource( db, ".debugmsg", &value))
408 #ifndef DEBUG_RUNTIME
409 fprintf(stderr,"%s: Option \"-debugmsg\" not implemented.\n" \
410 " Recompile with DEBUG_RUNTIME in include/stddebug.h defined.\n",
411 argv[0]);
412 exit(1);
413 #else
414 if (ParseDebugOptions((char*)value.addr)==FALSE)
416 int i;
417 fprintf(stderr,"%s: Syntax: -debugmsg +xxx,... or -debugmsg -xxx,...\n",argv[0]);
418 fprintf(stderr,"Example: -debugmsg +all,-heap turn on all messages except heap messages\n");
419 fprintf(stderr,"Available message types:\n");
420 fprintf(stderr,"%-9s ","all");
421 for(i=0;i<sizeof(debug_msg_enabled)/sizeof(short);i++)
422 if(debug_msg_name[i])
423 fprintf(stderr,"%-9s%c",debug_msg_name[i],
424 (((i+2)%8==0)?'\n':' '));
425 fprintf(stderr,"\n\n");
426 exit(1);
428 #endif
431 if(MAIN_GetResource( db, ".dll", &value))
432 #ifndef WINELIB
433 if(MAIN_ParseDLLOptions((char*)value.addr)==FALSE)
435 int i;
436 fprintf(stderr,"%s: Syntax: -dll +xxx,... or -dll -xxx,...\n",argv[0]);
437 fprintf(stderr,"Example: -dll -ole2 Do not use emulated OLE2.DLL\n");
438 fprintf(stderr,"Available DLLs\n");
439 for(i=0;i<N_BUILTINS;i++)
440 fprintf(stderr,"%-9s%c",dll_builtin_table[i].name,
441 (((i+2)%8==0)?'\n':' '));
442 fprintf(stderr,"\n\n");
443 exit(1);
445 #else
446 fprintf(stderr,"-dll not supported in libwine\n");
447 #endif
451 /***********************************************************************
452 * MAIN_CreateDesktop
454 static void MAIN_CreateDesktop( int argc, char *argv[] )
456 int flags;
457 unsigned int width = 640, height = 480; /* Default size = 640x480 */
458 char *name = "Wine desktop";
459 XSizeHints *size_hints;
460 XWMHints *wm_hints;
461 XClassHint *class_hints;
462 XSetWindowAttributes win_attr;
463 XTextProperty window_name;
464 Atom XA_WM_DELETE_WINDOW;
466 flags = XParseGeometry( Options.desktopGeometry,
467 &desktopX, &desktopY, &width, &height );
468 screenWidth = width;
469 screenHeight = height;
471 /* Create window */
473 win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
474 PointerMotionMask | ButtonPressMask |
475 ButtonReleaseMask | EnterWindowMask |
476 StructureNotifyMask;
477 win_attr.cursor = XCreateFontCursor( display, XC_top_left_arrow );
479 rootWindow = XCreateWindow( display, DefaultRootWindow(display),
480 desktopX, desktopY, width, height, 0,
481 CopyFromParent, InputOutput, CopyFromParent,
482 CWEventMask | CWCursor, &win_attr );
484 /* Set window manager properties */
486 size_hints = XAllocSizeHints();
487 wm_hints = XAllocWMHints();
488 class_hints = XAllocClassHint();
489 if (!size_hints || !wm_hints || !class_hints)
491 fprintf( stderr, "Not enough memory for window manager hints.\n" );
492 exit(1);
494 size_hints->min_width = size_hints->max_width = width;
495 size_hints->min_height = size_hints->max_height = height;
496 size_hints->flags = PMinSize | PMaxSize;
497 if (flags & (XValue | YValue)) size_hints->flags |= USPosition;
498 if (flags & (WidthValue | HeightValue)) size_hints->flags |= USSize;
499 else size_hints->flags |= PSize;
501 wm_hints->flags = InputHint | StateHint;
502 wm_hints->input = True;
503 wm_hints->initial_state = NormalState;
504 class_hints->res_name = argv[0];
505 class_hints->res_class = "Wine";
507 XStringListToTextProperty( &name, 1, &window_name );
508 XSetWMProperties( display, rootWindow, &window_name, &window_name,
509 argv, argc, size_hints, wm_hints, class_hints );
510 XA_WM_DELETE_WINDOW = XInternAtom( display, "WM_DELETE_WINDOW", False );
511 XSetWMProtocols( display, rootWindow, &XA_WM_DELETE_WINDOW, 1 );
512 XFree( size_hints );
513 XFree( wm_hints );
514 XFree( class_hints );
516 /* Map window */
518 XMapWindow( display, rootWindow );
522 XKeyboardState keyboard_state;
524 /***********************************************************************
525 * MAIN_SaveSetup
527 static void MAIN_SaveSetup(void)
529 XGetKeyboardControl(display, &keyboard_state);
532 /***********************************************************************
533 * MAIN_RestoreSetup
535 static void MAIN_RestoreSetup(void)
537 XKeyboardControl keyboard_value;
539 keyboard_value.key_click_percent = keyboard_state.key_click_percent;
540 keyboard_value.bell_percent = keyboard_state.bell_percent;
541 keyboard_value.bell_pitch = keyboard_state.bell_pitch;
542 keyboard_value.bell_duration = keyboard_state.bell_duration;
543 keyboard_value.auto_repeat_mode = keyboard_state.global_auto_repeat;
545 XChangeKeyboardControl(display, KBKeyClickPercent | KBBellPercent |
546 KBBellPitch | KBBellDuration | KBAutoRepeatMode, &keyboard_value);
550 static void called_at_exit(void)
552 MAIN_RestoreSetup();
553 WSACleanup();
556 /***********************************************************************
557 * main
559 #if defined(WINELIB) && defined(WINELIBDLL)
560 int _wine_main (int argc, char *argv[])
561 #else
562 int main( int argc, char *argv[] )
563 #endif
565 int ret_val;
566 int depth_count, i;
567 int *depth_list;
568 struct timeval tv;
570 extern int _WinMain(int argc, char **argv);
572 #ifdef MALLOC_DEBUGGING
573 char *trace;
575 mcheck(NULL);
576 if (!(trace = getenv("MALLOC_TRACE")))
578 fprintf( stderr, "MALLOC_TRACE not set. No trace generated\n" );
580 else
582 fprintf( stderr, "malloc trace goes to %s\n", trace );
583 mtrace();
585 #endif
587 setbuf(stdout,NULL);
588 setbuf(stderr,NULL);
590 setlocale(LC_CTYPE,"");
591 gettimeofday( &tv, NULL);
592 MSG_WineStartTicks = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
594 XrmInitialize();
596 MAIN_ParseOptions( &argc, argv );
598 SHELL_Init();
599 SHELL_LoadRegistry();
601 screen = DefaultScreenOfDisplay( display );
602 screenWidth = WidthOfScreen( screen );
603 screenHeight = HeightOfScreen( screen );
604 if (screenDepth) /* -depth option specified */
606 depth_list = XListDepths(display,DefaultScreen(display),&depth_count);
607 for (i = 0; i < depth_count; i++)
608 if (depth_list[i] == screenDepth) break;
609 XFree( depth_list );
610 if (i >= depth_count)
612 fprintf( stderr, "%s: Depth %d not supported on this screen.\n",
613 Options.programName, screenDepth );
614 exit(1);
617 else screenDepth = DefaultDepthOfScreen( screen );
618 if (Options.synchronous) XSynchronize( display, True );
619 if (Options.desktopGeometry) MAIN_CreateDesktop( argc, argv );
620 else rootWindow = DefaultRootWindow( display );
622 MAIN_SaveSetup();
623 atexit(called_at_exit);
625 ret_val = _WinMain( argc, argv );
627 return ret_val;
630 /***********************************************************************
631 * MessageBeep (USER.104)
633 void MessageBeep(WORD i)
635 XBell(display, 100);
638 /***********************************************************************
639 * GetVersion (KERNEL.3)
641 LONG GetVersion(void)
643 return MAKELONG( WINVERSION, WINDOSVER );
646 /***********************************************************************
647 * GetWinFlags (KERNEL.132)
649 LONG GetWinFlags(void)
651 static const long cpuflags[5] =
652 { WF_CPU086, WF_CPU186, WF_CPU286, WF_CPU386, WF_CPU486 };
654 long result = 0;
656 /* There doesn't seem to be any Pentium flag. */
657 #ifndef WINELIB
658 long cpuflag = cpuflags[MIN (runtime_cpu (), 4)];
659 #else
660 long cpuflag = cpuflags[4];
661 #endif
663 switch(Options.mode) {
664 case MODE_STANDARD:
665 result = (WF_STANDARD | cpuflag | WF_PMODE | WF_80x87);
666 break;
668 case MODE_ENHANCED:
669 result = (WF_ENHANCED | cpuflag | WF_PMODE | WF_80x87 | WF_PAGING);
670 break;
672 default:
673 fprintf(stderr, "Unknown mode set? This shouldn't happen. Check GetWinFlags()!\n");
674 break;
677 return result;
680 /***********************************************************************
681 * SetEnvironment (GDI.132)
683 int SetEnvironment(LPSTR lpPortName, LPSTR lpEnviron, WORD nCount)
685 LPENVENTRY lpNewEnv;
686 LPENVENTRY lpEnv = lpEnvList;
687 dprintf_env(stddeb, "SetEnvironment('%s', '%s', %d) !\n",
688 lpPortName, lpEnviron, nCount);
689 if (lpPortName == NULL) return -1;
690 while (lpEnv != NULL) {
691 if (lpEnv->Name != NULL && strcmp(lpEnv->Name, lpPortName) == 0) {
692 if (nCount == 0 || lpEnviron == NULL) {
693 if (lpEnv->Prev != NULL) lpEnv->Prev->Next = lpEnv->Next;
694 if (lpEnv->Next != NULL) lpEnv->Next->Prev = lpEnv->Prev;
695 free(lpEnv->Value);
696 free(lpEnv->Name);
697 free(lpEnv);
698 dprintf_env(stddeb, "SetEnvironment() // entry deleted !\n");
699 return -1;
701 free(lpEnv->Value);
702 lpEnv->Value = malloc(nCount);
703 if (lpEnv->Value == NULL) {
704 dprintf_env(stddeb, "SetEnvironment() // Error allocating entry value !\n");
705 return 0;
707 memcpy(lpEnv->Value, lpEnviron, nCount);
708 lpEnv->wSize = nCount;
709 dprintf_env(stddeb, "SetEnvironment() // entry modified !\n");
710 return nCount;
712 if (lpEnv->Next == NULL) break;
713 lpEnv = lpEnv->Next;
715 if (nCount == 0 || lpEnviron == NULL) return -1;
716 dprintf_env(stddeb, "SetEnvironment() // new entry !\n");
717 lpNewEnv = malloc(sizeof(ENVENTRY));
718 if (lpNewEnv == NULL) {
719 dprintf_env(stddeb, "SetEnvironment() // Error allocating new entry !\n");
720 return 0;
722 if (lpEnvList == NULL) {
723 lpEnvList = lpNewEnv;
724 lpNewEnv->Prev = NULL;
726 else
728 lpEnv->Next = lpNewEnv;
729 lpNewEnv->Prev = lpEnv;
731 lpNewEnv->Next = NULL;
732 lpNewEnv->Name = malloc(strlen(lpPortName) + 1);
733 if (lpNewEnv->Name == NULL) {
734 dprintf_env(stddeb, "SetEnvironment() // Error allocating entry name !\n");
735 return 0;
737 strcpy(lpNewEnv->Name, lpPortName);
738 lpNewEnv->Value = malloc(nCount);
739 if (lpNewEnv->Value == NULL) {
740 dprintf_env(stddeb, "SetEnvironment() // Error allocating entry value !\n");
741 return 0;
743 memcpy(lpNewEnv->Value, lpEnviron, nCount);
744 lpNewEnv->wSize = nCount;
745 return nCount;
748 /***********************************************************************
749 * SetEnvironmentVariableA (KERNEL32.484)
751 BOOL SetEnvironmentVariableA(LPSTR lpName, LPSTR lpValue)
753 int rc;
755 rc = SetEnvironment(lpName, lpValue, strlen(lpValue) + 1);
756 return (rc > 0) ? 1 : 0;
759 /***********************************************************************
760 * GetEnvironment (GDI.134)
762 int GetEnvironment(LPSTR lpPortName, LPSTR lpEnviron, WORD nMaxSiz)
764 WORD nCount;
765 LPENVENTRY lpEnv = lpEnvList;
766 dprintf_env(stddeb, "GetEnvironment('%s', '%s', %d) !\n",
767 lpPortName, lpEnviron, nMaxSiz);
768 while (lpEnv != NULL) {
769 if (lpEnv->Name != NULL && strcmp(lpEnv->Name, lpPortName) == 0) {
770 nCount = MIN(nMaxSiz, lpEnv->wSize);
771 memcpy(lpEnviron, lpEnv->Value, nCount);
772 dprintf_env(stddeb, "GetEnvironment() // found '%s' !\n", lpEnviron);
773 return nCount;
775 lpEnv = lpEnv->Next;
777 dprintf_env(stddeb, "GetEnvironment() // not found !\n");
778 return 0;
781 /***********************************************************************
782 * GetEnvironmentVariableA (KERNEL32.213)
784 DWORD GetEnvironmentVariableA(LPSTR lpName, LPSTR lpValue, DWORD size)
786 return GetEnvironment(lpName, lpValue, size);
789 /***********************************************************************
790 * GetEnvironmentStrings (KERNEL32.210)
792 LPVOID GetEnvironmentStrings(void)
794 int count;
795 LPENVENTRY lpEnv;
796 char *envtable, *envptr;
798 /* Count the total number of bytes we'll need for the string
799 * table. Include the trailing nuls and the final double nul.
801 count = 1;
802 lpEnv = lpEnvList;
803 while(lpEnv != NULL)
805 if(lpEnv->Name != NULL)
807 count += strlen(lpEnv->Name) + 1;
808 count += strlen(lpEnv->Value) + 1;
810 lpEnv = lpEnv->Next;
813 envtable = malloc(count);
814 if(envtable)
816 lpEnv = lpEnvList;
817 envptr = envtable;
819 while(lpEnv != NULL)
821 if(lpEnv->Name != NULL)
823 count = sprintf(envptr, "%s=%s", lpEnv->Name, lpEnv->Value);
824 envptr += count + 1;
826 lpEnv = lpEnv->Next;
828 *envptr = '\0';
831 return envtable;
834 /***********************************************************************
835 * GetTimerResolution (USER.14)
837 LONG GetTimerResolution(void)
839 return (1000);
842 /***********************************************************************
843 * SystemParametersInfo (USER.483)
845 BOOL SystemParametersInfo (UINT uAction, UINT uParam, LPVOID lpvParam, UINT fuWinIni)
847 int timeout, temp;
848 char buffer[256];
849 XKeyboardState keyboard_state;
850 XKeyboardControl keyboard_value;
853 fprintf(stderr, "SystemParametersInfo: action %d, param %x, flag %x\n",
854 uAction, uParam, fuWinIni);
856 switch (uAction) {
857 case SPI_GETBEEP:
858 XGetKeyboardControl(display, &keyboard_state);
859 if (keyboard_state.bell_percent == 0)
860 *(BOOL *) lpvParam = FALSE;
861 else
862 *(BOOL *) lpvParam = TRUE;
863 break;
865 case SPI_GETBORDER:
866 *(INT *) lpvParam = 1;
867 break;
869 case SPI_GETFASTTASKSWITCH:
870 *(BOOL *) lpvParam = FALSE;
871 break;
873 case SPI_GETGRIDGRANULARITY:
874 *(INT *) lpvParam = 1;
875 break;
877 case SPI_GETICONTITLEWRAP:
878 *(BOOL *) lpvParam = FALSE;
879 break;
881 case SPI_GETKEYBOARDDELAY:
882 *(INT *) lpvParam = 1;
883 break;
885 case SPI_GETKEYBOARDSPEED:
886 *(WORD *) lpvParam = 30;
887 break;
889 case SPI_GETMENUDROPALIGNMENT:
890 *(BOOL *) lpvParam = FALSE;
891 break;
893 case SPI_GETSCREENSAVEACTIVE:
894 *(BOOL *) lpvParam = FALSE;
895 break;
897 case SPI_GETSCREENSAVETIMEOUT:
898 XGetScreenSaver(display, &timeout, &temp,&temp,&temp);
899 *(INT *) lpvParam = timeout * 1000;
900 break;
902 case SPI_ICONHORIZONTALSPACING:
903 if (lpvParam == NULL)
904 fprintf(stderr, "SystemParametersInfo: Horizontal icon spacing set to %d\n.", uParam);
905 else
906 *(INT *) lpvParam = 50;
907 break;
909 case SPI_ICONVERTICALSPACING:
910 if (lpvParam == NULL)
911 fprintf(stderr, "SystemParametersInfo: Vertical icon spacing set to %d\n.", uParam);
912 else
913 *(INT *) lpvParam = 50;
914 break;
916 case SPI_SETBEEP:
917 if (uParam == TRUE)
918 keyboard_value.bell_percent = -1;
919 else
920 keyboard_value.bell_percent = 0;
921 XChangeKeyboardControl(display, KBBellPercent,
922 &keyboard_value);
923 break;
925 case SPI_SETSCREENSAVEACTIVE:
926 if (uParam == TRUE)
927 XActivateScreenSaver(display);
928 else
929 XResetScreenSaver(display);
930 break;
932 case SPI_SETSCREENSAVETIMEOUT:
933 XSetScreenSaver(display, uParam, 60, DefaultBlanking,
934 DefaultExposures);
935 break;
937 case SPI_SETDESKWALLPAPER:
938 return (SetDeskWallPaper((LPSTR) lpvParam));
939 break;
941 case SPI_SETDESKPATTERN:
942 if ((INT) uParam == -1) {
943 GetProfileString("Desktop", "Pattern",
944 "170 85 170 85 170 85 170 85",
945 buffer, sizeof(buffer) );
946 return (DESKTOP_SetPattern((LPSTR) buffer));
947 } else
948 return (DESKTOP_SetPattern((LPSTR) lpvParam));
949 break;
951 case SPI_GETICONTITLELOGFONT:
953 LPLOGFONT lpLogFont = (LPLOGFONT)lpvParam;
954 lpLogFont->lfHeight = 10;
955 lpLogFont->lfWidth = 0;
956 lpLogFont->lfEscapement = lpLogFont->lfOrientation = 0;
957 lpLogFont->lfWeight = FW_NORMAL;
958 lpLogFont->lfItalic = lpLogFont->lfStrikeOut = lpLogFont->lfUnderline = FALSE;
959 lpLogFont->lfCharSet = ANSI_CHARSET;
960 lpLogFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
961 lpLogFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
962 lpLogFont->lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
963 break;
965 case SPI_LANGDRIVER:
966 case SPI_SETBORDER:
967 case SPI_SETDOUBLECLKHEIGHT:
968 case SPI_SETDOUBLECLICKTIME:
969 case SPI_SETDOUBLECLKWIDTH:
970 case SPI_SETFASTTASKSWITCH:
971 case SPI_SETKEYBOARDDELAY:
972 case SPI_SETKEYBOARDSPEED:
973 fprintf(stderr, "SystemParametersInfo: option %d ignored.\n", uParam);
974 break;
976 default:
977 fprintf(stderr, "SystemParametersInfo: unknown option %d.\n", uParam);
978 break;
980 return 1;
983 /***********************************************************************
984 * HMEMCPY (KERNEL.348)
986 void hmemcpy(LPVOID hpvDest, LPCVOID hpvSource, LONG cbCopy)
988 memcpy(hpvDest, hpvSource, cbCopy);
991 /***********************************************************************
992 * COPY (GDI.250)
994 void Copy(LPVOID lpSource, LPVOID lpDest, WORD nBytes)
996 memcpy(lpDest, lpSource, nBytes);
999 /***********************************************************************
1000 * SWAPMOUSEBUTTON (USER.186)
1002 BOOL SwapMouseButton(BOOL fSwap)
1004 return 0; /* don't swap */
1007 /***********************************************************************
1008 * FileCDR (KERNEL.130)
1010 void FileCDR(FARPROC x)
1012 printf("FileCDR(%8x)\n", (int) x);
1015 /***********************************************************************
1016 * GetWinDebugInfo (KERNEL.355)
1018 BOOL GetWinDebugInfo(WINDEBUGINFO FAR* lpwdi, UINT flags)
1020 printf("GetWinDebugInfo(%8lx,%d) stub returning 0\n", (unsigned long)lpwdi, flags);
1021 /* 0 means not in debugging mode/version */
1022 /* Can this type of debugging be used in wine ? */
1023 /* Constants: WDI_OPTIONS WDI_FILTER WDI_ALLOCBREAK */
1024 return 0;
1027 /***********************************************************************
1028 * GetWinDebugInfo (KERNEL.355)
1030 BOOL SetWinDebugInfo(WINDEBUGINFO FAR* lpwdi)
1032 printf("SetWinDebugInfo(%8lx) stub returning 0\n", (unsigned long)lpwdi);
1033 /* 0 means not in debugging mode/version */
1034 /* Can this type of debugging be used in wine ? */
1035 /* Constants: WDI_OPTIONS WDI_FILTER WDI_ALLOCBREAK */
1036 return 0;