diff --git a/dlls/ddraw/ddraw_main.c b/dlls/ddraw/ddraw_main.c
index 5e5936b6ff56fd23edf64077d5b93969994b3a51..0ab3ed7f8c7ed5d6af5e661e04a5914a99926c31 100644
--- a/dlls/ddraw/ddraw_main.c
+++ b/dlls/ddraw/ddraw_main.c
@@ -174,6 +174,11 @@ static XF86VidModeModeInfo *orig_mode = NULL;
 static int XShmErrorFlag = 0;
 #endif
 
+static inline BOOL get_option( const char *name, BOOL def )
+{
+    return PROFILE_GetWineIniBool( "x11drv", name, def );
+}
+
 static BYTE
 DDRAW_DGA_Available(void)
 {
@@ -185,7 +190,7 @@ DDRAW_DGA_Available(void)
 	if (return_value != 0xFF)
 	  return return_value;
 	
-   	if (Options.noDGA) {
+   	if (!get_option( "UseDGA", 1 )) {
 	  return_value = 0;
      	  return 0;
 	}
@@ -4118,7 +4123,7 @@ static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
         }
 	TRACE("Setting drawable to %ld\n", This->d.drawable);
 
-	if (Options.DXGrab) {
+	if (get_option( "DXGrab", 0 )) {
 	    /* Confine cursor movement (risky, but the user asked for it) */
 	    TSXGrabPointer(display, This->d.drawable, True, 0, GrabModeAsync, GrabModeAsync, This->d.drawable, None, CurrentTime);
 	}
@@ -5488,24 +5493,19 @@ static HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnk
 
 static BOOL
 DDRAW_XSHM_Available(void)
-   {
+{
 #ifdef HAVE_LIBXXSHM
-  if (TSXShmQueryExtension(display))
-      {
-      int major, minor;
-      Bool shpix;
-
-      if ((TSXShmQueryVersion(display, &major, &minor, &shpix)) &&
-	  (Options.noXSHM != 1))
-	return 1;
-      else
-	return 0;
+    if (get_option( "UseXShm", 1 ))
+    {
+        if (TSXShmQueryExtension(display))
+        {
+            int major, minor;
+            Bool shpix;
+            if (TSXShmQueryVersion(display, &major, &minor, &shpix)) return TRUE;
+        }
     }
-    else
-    return 0;
-#else
-  return 0;
 #endif
+    return FALSE;
 }
 
 static HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
diff --git a/documentation/wine.man.in b/documentation/wine.man.in
index fcadc0d2a48b1c95f6124b352e6843763925ae46..6aa3bd84ea1f1d7eea8612551fd4ac69c249b8ec 100644
--- a/documentation/wine.man.in
+++ b/documentation/wine.man.in
@@ -153,9 +153,6 @@ For more information on debugging messages, see the file
 in the source distribution.
 .RE
 .TP
-.I -depth n
-Change the depth to use for multiple-depth screens
-.TP
 .I -desktop geom
 Use a desktop window of the given geometry, e.g. "640x480"
 .TP
@@ -216,12 +213,6 @@ It, Ko, Kw, No, Pl, Pt, Ru, Sk, Sv, Wa)
 Create each top-level window as a properly managed X window instead of
 creating our own "sticky" window.
 .TP
-.I -name name
-Set the application name
-.TP
-.I -privatemap
-Use a private color map
-.TP
 .I -synchronous
 Turn on synchronous display mode. Useful for debugging X11 graphics problems.
 .TP
diff --git a/graphics/x11drv/bitblt.c b/graphics/x11drv/bitblt.c
index c6179059a15ed5f2bcf74a53396d36e850b865cf..2e5d24966e51ad6dd0cd8bc982339e83a73623d2 100644
--- a/graphics/x11drv/bitblt.c
+++ b/graphics/x11drv/bitblt.c
@@ -523,6 +523,18 @@ main()
 #endif  /* BITBLT_TEST */
 
 
+/***********************************************************************
+ *           perfect_graphics
+ *
+ * Favor correctness or speed?
+ */
+static inline int perfect_graphics(void)
+{
+    static int perfect = -1;
+    if (perfect == -1) perfect = PROFILE_GetWineIniBool( "x11drv", "PerfectGraphics", 0 );
+    return perfect;
+}
+
 /***********************************************************************
  *           BITBLT_StretchRow
  *
@@ -1207,7 +1219,7 @@ static BOOL BITBLT_InternalStretchBlt( DC *dcDst, INT xDst, INT yDst,
 
     case DSTINVERT:  /* 0x55 */
         if ((dcDst->w.bitsPerPixel == 1) || !X11DRV_PALETTE_PaletteToXPixel ||
-            !Options.perfectGraphics)
+            !perfect_graphics())
         {
             XSetFunction( display, physDevDst->gc, GXinvert );
 
@@ -1231,7 +1243,7 @@ static BOOL BITBLT_InternalStretchBlt( DC *dcDst, INT xDst, INT yDst,
         break;
 
     case PATINVERT:  /* 0x5a */
-	if (Options.perfectGraphics) break;
+	if (perfect_graphics()) break;
         if (X11DRV_SetupGCForBrush( dcDst ))
         {
             XSetFunction( display, physDevDst->gc, GXxor );
@@ -1241,7 +1253,7 @@ static BOOL BITBLT_InternalStretchBlt( DC *dcDst, INT xDst, INT yDst,
         return TRUE;
 
     case 0xa50065:
-	if (Options.perfectGraphics) break;
+	if (perfect_graphics()) break;
 	if (X11DRV_SetupGCForBrush( dcDst ))
 	{
 	    XSetFunction( display, physDevDst->gc, GXequiv );
diff --git a/graphics/x11drv/palette.c b/graphics/x11drv/palette.c
index 3be89c7f078e8f319998af3f587d63b720e10009..53a03294a1f429d8ddf874b6c56a4db914bf0cf5 100644
--- a/graphics/x11drv/palette.c
+++ b/graphics/x11drv/palette.c
@@ -120,7 +120,7 @@ BOOL X11DRV_PALETTE_Init(void)
 	X11DRV_PALETTE_PaletteFlags |= X11DRV_PALETTE_VIRTUAL;
     case GrayScale:
     case PseudoColor:
-	if (Options.usePrivateMap)
+	if (PROFILE_GetWineIniBool( "x11drv", "PrivateColorMap", 0 ))
 	{
 	    XSetWindowAttributes win_attr;
 
@@ -316,7 +316,7 @@ static BOOL X11DRV_PALETTE_BuildSharedMap(void)
 
    /* read "AllocSystemColors" from wine.conf */
 
-   COLOR_max = PROFILE_GetWineIniInt( "options", "AllocSystemColors", 256);
+   COLOR_max = PROFILE_GetWineIniInt( "x11drv", "AllocSystemColors", 256);
    if (COLOR_max > 256) COLOR_max = 256;
    else if (COLOR_max < 20) COLOR_max = 20;
    TRACE("%d colors configured.\n", COLOR_max);
diff --git a/include/main.h b/include/main.h
index 9265c4e10365cf8a589b07e00489880548e211e9..4bb987914571a0a72945652227fa1430c549d004 100644
--- a/include/main.h
+++ b/include/main.h
@@ -7,14 +7,12 @@
 
 #include "windef.h"
 
-extern void MAIN_Usage(char*);
 extern BOOL MAIN_MainInit( int *argc, char *argv[], BOOL win32 );
 extern BOOL MAIN_WineInit( int *argc, char *argv[] );
 extern HINSTANCE MAIN_WinelibInit( int *argc, char *argv[] );
 extern int MAIN_GetLanguageID(char*lang, char*country, char*charset, char*dialect);
-extern BOOL MAIN_ParseDebugOptions(char *options);
-
-extern void MAIN_ParseLanguageOption( char *arg );
+extern void MAIN_ParseDebugOptions(const char *options);
+extern void MAIN_ParseLanguageOption( const char *arg );
 
 extern BOOL RELAY_Init(void);
 extern void THUNK_InitCallout(void);
diff --git a/include/options.h b/include/options.h
index eee20198bc431c8de5a85ae483acbbd4ab5e3622..8bd15f8b50749e84f915810eaf3f17c880d49c0b 100644
--- a/include/options.h
+++ b/include/options.h
@@ -55,29 +55,26 @@ extern const WINE_LANGUAGE_DEF Languages[];
 
 struct options
 {
-    int  *argc;
+    int    argc;
     char **argv;
     char * desktopGeometry; /* NULL when no desktop */
-    char * programName;     /* To use when loading resources */
+    char * display;         /* display name */
     char  *dllFlags;        /* -dll flags (hack for Winelib support) */
-    int    usePrivateMap;
     int    synchronous;     /* X synchronous mode */
     int    debug;
     int    failReadOnly;    /* Opening a read only file will fail
 			       if write access is requested */
     WINE_LANGUAGE language; /* Current language */
     int    managed;	    /* Managed windows */
-    int    perfectGraphics; /* Favor correctness over speed for graphics */
-    int    noDGA;           /* Disable XFree86 DGA extensions */
-    int    noXSHM;          /* Disable use of XSHM extension */
-    int    DXGrab;          /* Enable DirectX mouse grab */
     char * configFileName;  /* Command line config file */
-    int screenDepth;
 };
 
 extern struct options Options;
 extern const char *argv0;
 
+extern void OPTIONS_Usage(void) WINE_NORETURN;
+extern void OPTIONS_ParseOptions( int argc, char *argv[] );
+
 /* Profile functions */
 
 extern const char *PROFILE_GetConfigDir(void);
diff --git a/include/shell.h b/include/shell.h
index d5db64dad99ac5f348c985bfa0b2c3da10474a4e..31e909d218af27ce961939855755595465cb33ae 100644
--- a/include/shell.h
+++ b/include/shell.h
@@ -15,7 +15,7 @@ extern "C" {
 */
 extern void SHELL_LoadRegistry(void);
 extern void SHELL_SaveRegistry(void);
-extern void SHELL_Init(void);
+extern void SHELL_InitRegistrySaving(void);
 
 /* global functions used from shell32 */
 extern HINSTANCE SHELL_FindExecutable(LPCSTR,LPCSTR ,LPSTR);
diff --git a/loader/main.c b/loader/main.c
index 8439b3f856690d7781c4af0ef5a8a61eef7bdf46..f525c1931e68890342138c6f0b77bf8c8b773b9c 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -95,9 +95,6 @@ BOOL MAIN_MainInit( int *argc, char *argv[], BOOL win32 )
     /* Initialize DOS memory */
     if (!DOSMEM_Init(0)) return FALSE;
 
-    /* Initialize event handling */
-    if (!EVENT_Init()) return FALSE;
-
     /* Initialize communications */
     COMM_Init();
 
@@ -111,6 +108,11 @@ BOOL MAIN_MainInit( int *argc, char *argv[], BOOL win32 )
     if (!LoadLibrary16( "KRNL386.EXE" )) return FALSE;
     if (!LoadLibraryA( "KERNEL32" )) return FALSE;
 
+    /* Initialize event handling */
+    if (!EVENT_Init()) return FALSE;
+
+    SHELL_InitRegistrySaving();
+
     return TRUE;
 }
 
diff --git a/misc/Makefile.in b/misc/Makefile.in
index ea6c14837b73beed36392303b9b435dc4e434121..1c6b8c4f8f98c70815a59d9ee4584ea0e33c1257 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -17,6 +17,7 @@ C_SRCS = \
 	lstr.c \
 	main.c \
 	network.c \
+	options.c \
 	port.c \
 	printdrv.c \
 	registry.c \
diff --git a/misc/main.c b/misc/main.c
index 740aa9915811235890af6c0c4d4003e942e3f7ce..805eb448fcce5b5e4a50506de530c9f1616691e7 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -94,93 +94,24 @@ struct options Options =
     0,              /* argc */
     NULL,           /* argv */
     NULL,           /* desktopGeometry */
-    NULL,           /* programName */
+    NULL,           /* display */
     NULL,           /* dllFlags */
-    FALSE,          /* usePrivateMap */
     FALSE,          /* synchronous */
-    FALSE,
+    FALSE,          /* debug */
     FALSE,          /* failReadOnly */
-#ifdef DEFAULT_LANG
-    DEFAULT_LANG,   /* Default language */
-#else
-    LANG_En,
-#endif
+    0,              /* language */
     FALSE,          /* Managed windows */
-    FALSE,          /* Perfect graphics */
-    FALSE,          /* No DGA */
-    FALSE,          /* No XSHM */
-    FALSE,          /* DXGrab */
-    NULL,           /* Alternate config file name */
-    0               /* screenDepth */
+    NULL            /* Alternate config file name */
 };
 
 const char *argv0;
 
-static const char szUsage[] =
-  "Options:\n"
-  "    -config name    Specify config file to use\n"
-  "    -debug          Enter debugger before starting application\n"
-  "    -debugmsg name  Turn debugging-messages on or off\n"
-  "    -depth n        Change the depth to use for multiple-depth screens\n"
-  "    -desktop geom   Use a desktop window of the given geometry\n"
-  "    -display name   Use the specified display\n"
-  "    -dll name       Enable or disable built-in DLLs\n"
-  "    -failreadonly   Read only files may not be opened in write mode\n"
-  "    -help           Show this help message\n"
-  "    -language xx    Set the language (one of Br,Ca,Cs,Cy,Da,De,En,Eo,Es,Fi,Fr,Ga,Gd,Gv\n"
-  "                    Hu,It,Ja,Ko,Kw,Nl,No,Pl,Pt,Sk,Sv,Ru,Wa)\n"
-  "    -managed        Allow the window manager to manage created windows\n"
-  "    -name name      Set the application name\n"
-  "    -nodga          Disable XFree86 DGA extensions\n"
-  "    -noxshm         Disable XSHM extension\n"
-  "    -dxgrab         Enable DirectX mouse grab\n"
-  "    -perfect        Favor correctness over speed for graphical operations\n"
-  "    -privatemap     Use a private color map\n"
-  "    -synchronous    Turn on synchronous display mode\n"
-  "    -version        Display the Wine version\n"
-  "    -winver         Version to imitate (one of win31,win95,nt351,nt40)\n"
-  "    -dosver         DOS version to imitate (x.xx, e.g. 6.22). Only valid with -winver win31\n"
-  ;
-
-/***********************************************************************
- *           MAIN_Usage
- */
-void MAIN_Usage( char *name )
-{
-    MESSAGE( WINE_RELEASE_INFO "\nUsage:  %s [options] \"program_name [arguments]\"\n\n", name );
-    write( 2, szUsage, sizeof(szUsage)-1 );  /* too large for MESSAGE() */
-    ExitProcess(1);
-}
-
-/***********************************************************************
- *           MAIN_GetProgramName
- *
- * Get the program name. The name is specified by (in order of precedence):
- * - the option '-name'.
- * - the environment variable 'WINE_NAME'.
- * - the last component of argv[0].
- */
-static char *MAIN_GetProgramName( int argc, char *argv[] )
-{
-    int i;
-    char *p;
-
-    for (i = 1; i < argc-1; i++)
-	if (!strcmp( argv[i], "-name" )) return argv[i+1];
-    if ((p = getenv( "WINE_NAME" )) != NULL) return p;
-    if ((p = strrchr( argv[0], '/' )) != NULL) return p+1;
-    return argv[0];
-}
-
 /***********************************************************************
  *          MAIN_ParseDebugOptions
  *
  *  Turns specific debug messages on or off, according to "options".
- *  
- *  RETURNS
- *    TRUE if parsing was successful
  */
-BOOL MAIN_ParseDebugOptions(char *options)
+void MAIN_ParseDebugOptions( const char *arg )
 {
   /* defined in relay32/relay386.c */
   extern char **debug_relay_includelist;
@@ -192,9 +123,11 @@ BOOL MAIN_ParseDebugOptions(char *options)
   int i;
   int l, cls, dotracerelay = TRACE_ON(relay);
 
+  char *options = strdup(arg);
+
   l = strlen(options);
-  if (l<2)
-    return FALSE;
+  if (l<2) goto error;
+
   if (options[l-1]=='\n') options[l-1]='\0';
   do
   {
@@ -295,12 +228,11 @@ BOOL MAIN_ParseDebugOptions(char *options)
   if (dotracerelay != TRACE_ON(relay))
   	BUILTIN32_SwitchRelayDebug( TRACE_ON(relay) );
 
-  if (!*options)
-    return TRUE;
+  if (!*options) return;
 
  error:  
   MESSAGE("%s: Syntax: -debugmsg [class]+xxx,...  or "
-      "-debugmsg [class]-xxx,...\n",Options.argv[0]);
+      "-debugmsg [class]-xxx,...\n",argv0);
   MESSAGE("Example: -debugmsg +all,warn-heap\n"
       "  turn on all messages except warning heap messages\n");
   MESSAGE("Special case: -debugmsg +relay=DLL:DLL.###:FuncName\n"
@@ -321,7 +253,6 @@ BOOL MAIN_ParseDebugOptions(char *options)
 	  (((i+2)%8==0)?'\n':' '));
   MESSAGE("\n\n");
   ExitProcess(1);
-  return FALSE;
 }
 
 /***********************************************************************
@@ -684,15 +615,10 @@ end_MAIN_GetLanguageID:
  *
  * Parse -language option.
  */
-void MAIN_ParseLanguageOption( char *arg )
+void MAIN_ParseLanguageOption( const char *arg )
 {
     const WINE_LANGUAGE_DEF *p = Languages;
 
-/* for compatibility whith non-iso names previously used */
-    if (!strcmp("Sw",arg)) { strcpy(arg,"Sv"); FIXME_(system)("use 'Sv' instead of 'Sw'\n");}
-    if (!strcmp("Cz",arg)) { strcpy(arg,"Cs"); FIXME_(system)("use 'Cs' instead of 'Cz'\n");}
-    if (!strcmp("Po",arg)) { strcpy(arg,"Pt"); FIXME_(system)("use 'Pt' instead of 'Po'\n");}
-
     Options.language = LANG_Xx;  /* First (dummy) language */
     for (;p->name;p++)
     {
@@ -710,42 +636,6 @@ void MAIN_ParseLanguageOption( char *arg )
 }
 
 
-/***********************************************************************
- *           MAIN_ParseOptions
- *
- * Parse command line options and open display.
- */
-static void MAIN_ParseOptions( int *argc, char *argv[] )
-{
-    int i;
-    char *pcDot;
-
-    Options.argc = argc;
-    Options.argv = argv;
-    Options.programName = MAIN_GetProgramName( *argc, argv );
-
-    /* initialise Options.language to 0 to tell "no language choosen yet" */
-    Options.language = 0;
-  
-    /* make sure there is no "." in Options.programName to confuse the X
-       resource database lookups */
-    if ((pcDot = strchr(Options.programName, '.'))) *pcDot = '\0';
-
-    for (i = 1; i < *argc; i++)
-    {
-        if (!strcmp( argv[i], "-v" ) || !strcmp( argv[i], "-version" ))
-        {
-            MESSAGE( "%s\n", WINE_RELEASE_INFO );
-            ExitProcess(0);
-        }
-        if (!strcmp( argv[i], "-h" ) || !strcmp( argv[i], "-help" ))
-        {
-            MAIN_Usage(argv[0]);
-            ExitProcess(0);
-        }
-    }
-}
-
 /***********************************************************************
  *           called_at_exit
  */
@@ -790,7 +680,7 @@ BOOL MAIN_WineInit( int *argc, char *argv[] )
     gettimeofday( &tv, NULL);
     MSG_WineStartTicks = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
     
-    MAIN_ParseOptions(argc, argv);
+    OPTIONS_ParseOptions( *argc, argv );
 
 #ifndef X_DISPLAY_MISSING
     USER_Driver = &X11DRV_USER_Driver;
diff --git a/misc/options.c b/misc/options.c
new file mode 100644
index 0000000000000000000000000000000000000000..c86e7d4f41c1fefdd7683428bcd5fa26b59942ee
--- /dev/null
+++ b/misc/options.c
@@ -0,0 +1,203 @@
+/*
+ * Option parsing
+ *
+ * Copyright 2000 Alexandre Julliard
+ */
+
+#include "config.h"
+#include <string.h>
+
+#include "winbase.h"
+#include "main.h"
+#include "options.h"
+#include "version.h"
+#include "debugtools.h"
+
+struct option
+{
+    const char *longname;
+    char        shortname;
+    int         has_arg;
+    void      (*func)( const char *arg );
+    const char *usage;
+};
+
+static void do_config( const char *arg );
+static void do_debug( const char *arg );
+static void do_desktop( const char *arg );
+static void do_display( const char *arg );
+static void do_dll( const char *arg );
+static void do_failreadonly( const char *arg );
+static void do_help( const char *arg );
+static void do_managed( const char *arg );
+static void do_synchronous( const char *arg );
+static void do_version( const char *arg );
+
+static const struct option option_table[] =
+{
+    { "config",       0, 1, do_config,
+      "--config name    Specify config file to use" },
+    { "debug",        0, 0, do_debug,
+      "--debug          Enter debugger before starting application" },
+    { "debugmsg",     0, 1, MAIN_ParseDebugOptions,
+      "--debugmsg name  Turn debugging-messages on or off" },
+    { "desktop",      0, 1, do_desktop,
+      "--desktop geom   Use a desktop window of the given geometry" },
+    { "display",      0, 1, do_display,
+      "--display name   Use the specified display" },
+    { "dll",          0, 1, do_dll,
+      "--dll name       Enable or disable built-in DLLs" },
+    { "dosver",       0, 1, VERSION_ParseDosVersion,
+      "--dosver x.xx    DOS version to imitate (e.g. 6.22). Only valid with --winver win31" },
+    { "failreadonly", 0, 0, do_failreadonly,
+      "--failreadonly   Read only files may not be opened in write mode" },
+    { "help",       'h', 0, do_help,
+      "--help,-h        Show this help message" },
+    { "language",     0, 1, MAIN_ParseLanguageOption,
+      "--language xx    Set the language (one of Br,Ca,Cs,Cy,Da,De,En,Eo,Es,Fi,Fr,Ga,Gd,Gv\n"
+      "                    Hu,It,Ja,Ko,Kw,Nl,No,Pl,Pt,Sk,Sv,Ru,Wa)" },
+    { "managed",      0, 0, do_managed,
+      "--managed        Allow the window manager to manage created windows" },
+    { "synchronous",  0, 0, do_synchronous,
+      "--synchronous    Turn on synchronous display mode" },
+    { "version",    'v', 0, do_version,
+      "--version,-v     Display the Wine version" },
+    { "winver",       0, 1, VERSION_ParseWinVersion,
+      "--winver         Version to imitate (one of win31,win95,nt351,nt40)" },
+    { NULL, }  /* terminator */
+};
+
+
+static void do_help( const char *arg )
+{
+    OPTIONS_Usage();
+}
+
+static void do_version( const char *arg )
+{
+    MESSAGE( "%s\n", WINE_RELEASE_INFO );
+    ExitProcess(0);
+}
+
+static void do_synchronous( const char *arg )
+{
+    Options.synchronous = TRUE;
+}
+
+static void do_debug( const char *arg )
+{
+    Options.debug = TRUE;
+}
+
+static void do_failreadonly( const char *arg )
+{
+    Options.failReadOnly = TRUE;
+}
+
+static void do_desktop( const char *arg )
+{
+    Options.desktopGeometry = strdup( arg );
+}
+
+static void do_display( const char *arg )
+{
+    Options.display = strdup( arg );
+}
+
+static void do_dll( const char *arg )
+{
+    if (Options.dllFlags)
+    {
+        /* don't overwrite previous value. Should we
+         * automatically add the ',' between multiple DLLs ?
+         */
+        MESSAGE("Only one -dll flag is allowed. Use ',' between multiple DLLs\n");
+        ExitProcess(1);
+    }
+    Options.dllFlags = strdup( arg );
+}
+
+static void do_managed( const char *arg )
+{
+    Options.managed = TRUE;
+}
+
+static void do_config( const char *arg )
+{
+    Options.configFileName = strdup( arg );
+}
+
+static inline void remove_options( int *argc, char *argv[], int pos, int count )
+{
+    while ((argv[pos] = argv[pos+count])) pos++;
+    *argc -= count;
+}
+
+/***********************************************************************
+ *              OPTIONS_Usage
+ */
+void OPTIONS_Usage(void)
+{
+    const struct option *opt;
+    MESSAGE( "Usage: %s [options] \"program_name [arguments]\"\n\n", argv0 );
+    MESSAGE( "Options:\n" );
+    for (opt = option_table; opt->longname; opt++) MESSAGE( "   %s\n", opt->usage );
+    ExitProcess(0);
+}
+
+/***********************************************************************
+ *              OPTIONS_ParseOptions
+ */
+void OPTIONS_ParseOptions( int argc, char *argv[] )
+{
+    const struct option *opt;
+    int i;
+
+    for (i = 1; argv[i]; i++)
+    {
+        char *p = argv[i];
+        if (*p++ != '-') continue;  /* not an option */
+        if (*p && !p[1]) /* short name */
+        {
+            if (*p == '-') break; /* "--" option */
+            for (opt = option_table; opt->longname; opt++) if (opt->shortname == *p) break;
+        }
+        else  /* long name */
+        {
+            if (*p == '-') p++;
+            /* check for the long name */
+            for (opt = option_table; opt->longname; opt++)
+                if (!strcmp( p, opt->longname )) break;
+        }
+        if (!opt->longname) continue;
+
+        if (opt->has_arg && argv[i+1])
+        {
+            opt->func( argv[i+1] );
+            remove_options( &argc, argv, i, 2 );
+        }
+        else
+        {
+            opt->func( "" );
+            remove_options( &argc, argv, i, 1 );
+        }
+        i--;
+    }
+
+    /* check if any option remains */
+    for (i = 1; argv[i]; i++)
+    {
+        if (!strcmp( argv[i], "--" ))
+        {
+            remove_options( &argc, argv, i, 1 );
+            break;
+        }
+        if (argv[i][0] == '-')
+        {
+            MESSAGE( "Unknown option '%s'\n", argv[i] );
+            OPTIONS_Usage();
+        }
+    }
+    Options.argc = argc;
+    Options.argv = argv;
+}
diff --git a/misc/registry.c b/misc/registry.c
index f43e1571f62c05b6e295fbfa1f1519e049f2e35d..93306689d7c8db9692db190dee90b51cc96dae52 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -1561,7 +1561,6 @@ static void SetLoadLevel(int level)
 
 void SHELL_LoadRegistry( void )
 {
-  int	save_timeout;
   char	*fn, *home;
   HKEY	hkey;
   char windir[MAX_PATHNAME_LEN];
@@ -1787,28 +1786,14 @@ void SHELL_LoadRegistry( void )
       free (fn);
   }
   
-  /* 
-   * Make sure the update mode is there
-   */
-  if (ERROR_SUCCESS==RegCreateKey16(HKEY_CURRENT_USER,KEY_REGISTRY,&hkey)) 
-  {
-    DWORD	junk,type,len;
-    char	data[5];
-
-    len=4;
-    if ((	RegQueryValueExA(
-            hkey,
-            VAL_SAVEUPDATED,
-            &junk,
-            &type,
-            data,
-            &len) != ERROR_SUCCESS) || (type != REG_SZ))
-    {
-      RegSetValueExA(hkey,VAL_SAVEUPDATED,0,REG_SZ,"yes",4);
-    }
+}
 
-    RegCloseKey(hkey);
-  }
+/* start the periodic saving timer */
+void SHELL_InitRegistrySaving(void)
+{
+  int	save_timeout;
+
+  if (!CLIENT_IsBootThread()) return;
 
   if ((save_timeout = PROFILE_GetWineIniInt( "registry", "PeriodicSave", 0 )))
   {
diff --git a/misc/version.c b/misc/version.c
index 7a4a223239f253a1fcb22c9677ffd6d11a10fc2f..1ebfc43cd4229d94c4320ebfe8525a46f3862b42 100644
--- a/misc/version.c
+++ b/misc/version.c
@@ -128,6 +128,7 @@ void VERSION_ParseWinVersion( const char *arg )
     for (i = 0; i < NB_WINDOWS_VERSIONS; i++)
         MESSAGE(" '%s'%c", WinVersionNames[i],
 	    (i == NB_WINDOWS_VERSIONS - 1) ? '\n' : ',' );
+    ExitProcess(1);
 }
 
 
@@ -144,7 +145,10 @@ void VERSION_ParseDosVersion( const char *arg )
                      (hi<<8) + lo);
     }
     else
-        fprintf( stderr, "-dosver: Wrong version format. Use \"-dosver x.xx\"\n");
+    {
+        MESSAGE("--dosver: Wrong version format. Use \"--dosver x.xx\"\n");
+        ExitProcess(1);
+    }
 }
 
 /**********************************************************************
diff --git a/miscemu/main.c b/miscemu/main.c
index 98478f842ef890792e0e374c16d5fb0bd3acb850..8d413c85e657c817244029aad27cc82bc43d3851 100644
--- a/miscemu/main.c
+++ b/miscemu/main.c
@@ -18,10 +18,30 @@
 #include "wine/exception.h"
 #include "debugtools.h"
 
-static int MAIN_argc;
-static char **MAIN_argv;
+extern DWORD DEBUG_WinExec(LPCSTR lpCmdLine, int sw);
 
-extern DWORD DEBUG_WinExec(LPSTR lpCmdLine, int sw);
+
+static BOOL exec_program( LPCSTR cmdline )
+{
+    HINSTANCE handle;
+
+    if (Options.debug) 
+        handle = DEBUG_WinExec( cmdline, SW_SHOWNORMAL );
+    else
+        handle = WinExec( cmdline, SW_SHOWNORMAL );
+       
+    if (handle < 32) 
+    {
+        MESSAGE( "%s: can't exec '%s': ", argv0, cmdline );
+        switch (handle) 
+        {
+        case  2: MESSAGE("file not found\n" ); break;
+        case 11: MESSAGE("invalid exe file\n" ); break;
+        default: MESSAGE("error=%d\n", handle ); break;
+        }
+    }
+    return (handle >= 32);
+}
 
 /***********************************************************************
  *           Main loop of initial task
@@ -29,10 +49,8 @@ extern DWORD DEBUG_WinExec(LPSTR lpCmdLine, int sw);
 void MAIN_EmulatorRun( void )
 {
     char startProg[256], defProg[256];
-    HINSTANCE handle;
     int i, tasks = 0;
     MSG msg;
-    BOOL err_msg = FALSE;
 
     /* Load system DLLs into the initial process (and initialize them) */
     if (   !LoadLibrary16("GDI.EXE" ) || !LoadLibraryA("GDI32.DLL" )
@@ -48,55 +66,28 @@ void MAIN_EmulatorRun( void )
     /* Call InitApp for initial task */
     Callout.InitApp16( MapHModuleLS( 0 ) );
 
-    /* Add the Default Program if no program on the command line */
-    if (!MAIN_argv[1])
-    {
-        PROFILE_GetWineIniString( "programs", "Default", "",
-                                  defProg, sizeof(defProg) );
-        if (defProg[0]) MAIN_argv[MAIN_argc++] = defProg;
-    }
-    
     /* Add the Startup Program to the run list */
     PROFILE_GetWineIniString( "programs", "Startup", "", 
 			       startProg, sizeof(startProg) );
-    if (startProg[0]) MAIN_argv[MAIN_argc++] = startProg;
+    if (startProg[0]) tasks += exec_program( startProg );
 
-    /* Abort if no executable on command line */
-    if (MAIN_argc <= 1) 
+    /* Add the Default Program if no program on the command line */
+    if (!Options.argv[1])
     {
-    	MAIN_Usage(MAIN_argv[0]);
-        ExitProcess( 1 );
+        PROFILE_GetWineIniString( "programs", "Default", "",
+                                  defProg, sizeof(defProg) );
+        if (defProg[0]) tasks += exec_program( defProg );
+        else if (!tasks && !startProg[0]) OPTIONS_Usage();
     }
-
-    /* Load and run executables given on command line */
-    for (i = 1; i < MAIN_argc; i++)
+    else
     {
-       if (Options.debug) 
-       {
-	  handle = DEBUG_WinExec( MAIN_argv[i], SW_SHOWNORMAL );
-       } else {
-	  handle = WinExec( MAIN_argv[i], SW_SHOWNORMAL );
-       }
-       
-       if (handle < 32) 
-       {
-	    err_msg = TRUE;
-	    MESSAGE("wine: can't exec '%s': ", MAIN_argv[i]);
-	    switch (handle) 
-	    {
-	    case  2: MESSAGE("file not found\n" ); break;
-	    case 11: MESSAGE("invalid exe file\n" ); break;
-	    default: MESSAGE("error=%d\n", handle ); break;
-	    }
+        /* Load and run executables given on command line */
+        for (i = 1; Options.argv[i]; i++)
+        {
+            tasks += exec_program( Options.argv[i] );
         }
-	else tasks++;
-    }
-
-    if (!tasks)
-    {
-	if (!err_msg) MESSAGE("wine: no executable file found.\n" );
-        ExitProcess( 0 );
     }
+    if (!tasks) ExitProcess( 0 );
 
     /* Start message loop for desktop window */
 
@@ -119,7 +110,6 @@ int main( int argc, char *argv[] )
 
     /* Initialize everything */
     if (!MAIN_MainInit( &argc, argv, FALSE )) return 1;
-    MAIN_argc = argc; MAIN_argv = argv;
 
     /* Create initial task */
     if ( !(pModule = NE_GetPtr( GetModuleHandle16( "KERNEL" ) )) ) return 1;
diff --git a/windows/x11drv/main.c b/windows/x11drv/main.c
index 7cacbc2b797ecad661394c155d6a8ba6649e4ce2..6e10dbe6ec0e265c6f02e02ea4e69446ed51e406 100644
--- a/windows/x11drv/main.c
+++ b/windows/x11drv/main.c
@@ -36,41 +36,8 @@
 
 /**********************************************************************/
 
-void X11DRV_USER_ParseOptions(int *argc, char *argv[]);
-void X11DRV_USER_Create(void);
-void X11DRV_USER_SaveSetup(void);
-void X11DRV_USER_RestoreSetup(void);
-
-/**********************************************************************/
-
-#define WINE_CLASS        "Wine"    /* Class name for resources */
-#define WINE_APP_DEFAULTS "/usr/lib/X11/app-defaults/Wine"
-
-static XrmOptionDescRec optionsTable[] =
-{
-    { "-desktop",       ".desktop",         XrmoptionSepArg, (caddr_t)NULL },
-    { "-depth",         ".depth",           XrmoptionSepArg, (caddr_t)NULL },
-    { "-display",       ".display",         XrmoptionSepArg, (caddr_t)NULL },
-    { "-iconic",        ".iconic",          XrmoptionNoArg,  (caddr_t)"on" },
-    { "-language",      ".language",        XrmoptionSepArg, (caddr_t)"En" },
-    { "-name",          ".name",            XrmoptionSepArg, (caddr_t)NULL },
-    { "-perfect",       ".perfect",         XrmoptionNoArg,  (caddr_t)"on" },
-    { "-privatemap",    ".privatemap",      XrmoptionNoArg,  (caddr_t)"on" },
-    { "-synchronous",   ".synchronous",     XrmoptionNoArg,  (caddr_t)"on" },
-    { "-debug",         ".debug",           XrmoptionNoArg,  (caddr_t)"on" },
-    { "-debugmsg",      ".debugmsg",        XrmoptionSepArg, (caddr_t)NULL },
-    { "-dll",           ".dll",             XrmoptionSepArg, (caddr_t)NULL },
-    { "-failreadonly",  ".failreadonly",    XrmoptionNoArg,  (caddr_t)"on" },
-    { "-managed",       ".managed",         XrmoptionNoArg,  (caddr_t)"off"},
-    { "-winver",        ".winver",          XrmoptionSepArg, (caddr_t)NULL },
-    { "-config",        ".config",          XrmoptionSepArg, (caddr_t)NULL },
-    { "-nodga",         ".nodga",           XrmoptionNoArg,  (caddr_t)"off"},
-    { "-noxshm",        ".noxshm",          XrmoptionNoArg,  (caddr_t)"off"},
-    { "-dxgrab",        ".dxgrab",          XrmoptionNoArg,  (caddr_t)"on" },
-    { "-dosver",        ".dosver",          XrmoptionSepArg, (caddr_t)NULL }
-};
-
-#define NB_OPTIONS  (sizeof(optionsTable) / sizeof(optionsTable[0]))
+static void X11DRV_USER_SaveSetup(void);
+static void X11DRV_USER_RestoreSetup(void);
 
 /**********************************************************************/
 
@@ -97,6 +64,15 @@ Window X11DRV_GetXRootWindow()
   return X11DRV_MONITOR_GetXRootWindow(&MONITOR_PrimaryMonitor);
 }
 
+/***********************************************************************
+ *		X11DRV_USER_ErrorHandler
+ */
+static int X11DRV_USER_ErrorHandler(Display *display, XErrorEvent *error_evt)
+{
+    DebugBreak();  /* force an entry in the debugger */
+    return 0;
+}
+
 /***********************************************************************
  *              X11DRV_USER_Initialize
  */
@@ -114,12 +90,28 @@ BOOL X11DRV_USER_Initialize(void)
   InitializeCriticalSection( &X11DRV_CritSection );
   MakeCriticalSectionGlobal( &X11DRV_CritSection );
   
-  TSXrmInitialize();
-  
   putenv("XKB_DISABLE="); /* Disable XKB extension if present. */
 
-  X11DRV_USER_ParseOptions( Options.argc, Options.argv );
-  X11DRV_USER_Create();
+  /* Open display */
+  
+  if (!(display = TSXOpenDisplay( Options.display )))
+  {
+      MESSAGE( "%s: Can't open display: %s\n",
+               argv0, Options.display ? Options.display : "(none specified)" );
+      ExitProcess(1);
+  }
+  
+  /* tell the libX11 that we will do input method handling ourselves
+   * that keep libX11 from doing anything whith dead keys, allowing Wine
+   * to have total control over dead keys, that is this line allows
+   * them to work in Wine, even whith a libX11 including the dead key
+   * patches from Th.Quinot (http://Web.FdN.FR/~tquinot/dead-keys.en.html)
+   */
+  TSXOpenIM(display,NULL,NULL,NULL);
+
+  if (Options.synchronous) XSetErrorHandler( X11DRV_USER_ErrorHandler );
+  if (Options.desktopGeometry && Options.managed) Options.managed = FALSE;
+
   X11DRV_USER_SaveSetup();
 
   return TRUE;
@@ -149,162 +141,10 @@ void X11DRV_USER_EndDebugging(void)
 {
 }
 
-/***********************************************************************
- *		 X11DRV_USER_GetResource
- *
- * Fetch the value of resource 'name' using the correct instance name.
- * 'name' must begin with '.' or '*'
- */
-static int X11DRV_USER_GetResource( XrmDatabase db, char *name, XrmValue *value )
-{
-  char *buff_instance, *buff_class;
-  char *dummy;
-  int retval;
-  
-  buff_instance = (char *)xmalloc(strlen(Options.programName)+strlen(name)+1);
-  buff_class    = (char *)xmalloc( strlen(WINE_CLASS) + strlen(name) + 1 );
-    
-  strcpy( buff_instance, Options.programName );
-  strcat( buff_instance, name );
-  strcpy( buff_class, WINE_CLASS );
-  strcat( buff_class, name );
-  retval = TSXrmGetResource( db, buff_instance, buff_class, &dummy, value );
-  free( buff_instance );
-  free( buff_class );
-  return retval;
-}
-
-/***********************************************************************
- *              X11DRV_USER_ParseOptions
- * Parse command line options and open display.
- */
-void X11DRV_USER_ParseOptions(int *argc, char *argv[])
-{
-  int i;
-  char *display_name = NULL;
-  XrmValue value;
-  XrmDatabase db = TSXrmGetFileDatabase(WINE_APP_DEFAULTS);
-  char *xrm_string;
-
-  /* Get display name from command line */
-  for (i = 1; i < *argc; i++)
-    {
-      if (!strcmp( argv[i], "-display" )) display_name = argv[i+1];
-    }
-
-  /* Open display */
-  
-  if (display_name == NULL &&
-      X11DRV_USER_GetResource( db, ".display", &value )) display_name = value.addr;
-  
-  if (!(display = TSXOpenDisplay( display_name )))
-    {
-      MESSAGE( "%s: Can't open display: %s\n",
-	   argv[0], display_name ? display_name : "(none specified)" );
-      exit(1);
-    }
-  
-  /* tell the libX11 that we will do input method handling ourselves
-   * that keep libX11 from doing anything whith dead keys, allowing Wine
-   * to have total control over dead keys, that is this line allows
-   * them to work in Wine, even whith a libX11 including the dead key
-   * patches from Th.Quinot (http://Web.FdN.FR/~tquinot/dead-keys.en.html)
-   */
-  TSXOpenIM(display,NULL,NULL,NULL);
-  
-  /* Merge file and screen databases */
-  if ((xrm_string = TSXResourceManagerString( display )) != NULL)
-    {
-      XrmDatabase display_db = TSXrmGetStringDatabase( xrm_string );
-      TSXrmMergeDatabases( display_db, &db );
-    }
-  
-  /* Parse command line */
-  TSXrmParseCommand( &db, optionsTable, NB_OPTIONS,
-		     Options.programName, argc, argv );
-  
-  /* Get all options */
-  if (X11DRV_USER_GetResource( db, ".privatemap", &value ))
-    Options.usePrivateMap = TRUE;
-  if (X11DRV_USER_GetResource( db, ".synchronous", &value ))
-    Options.synchronous = TRUE;
-  if (X11DRV_USER_GetResource( db, ".debug", &value ))
-    Options.debug = TRUE;
-  if (X11DRV_USER_GetResource( db, ".failreadonly", &value ))
-    Options.failReadOnly = TRUE;
-  if (X11DRV_USER_GetResource( db, ".perfect", &value ))
-    Options.perfectGraphics = TRUE;
-  if (X11DRV_USER_GetResource( db, ".depth", &value))
-    Options.screenDepth = atoi( value.addr );
-  if (X11DRV_USER_GetResource( db, ".desktop", &value))
-    Options.desktopGeometry = value.addr;
-  if (X11DRV_USER_GetResource( db, ".language", &value))
-    MAIN_ParseLanguageOption( (char *)value.addr );
-  if (X11DRV_USER_GetResource( db, ".managed", &value))
-    Options.managed = TRUE;
-  if (X11DRV_USER_GetResource( db, ".debugoptions", &value))
-    MAIN_ParseDebugOptions((char*)value.addr);
-  if (X11DRV_USER_GetResource( db, ".debugmsg", &value))
-    MAIN_ParseDebugOptions((char*)value.addr);
-  
-  if (X11DRV_USER_GetResource( db, ".dll", &value))
-  {
-      if (Options.dllFlags)
-      {
-          /* don't overwrite previous value. Should we
-           * automatically add the ',' between multiple DLLs ?
-           */
-          MESSAGE("Only one -dll flag is allowed. Use ',' between multiple DLLs\n");
-      }
-      else Options.dllFlags = xstrdup((char *)value.addr);
-  }
-  
-  if (X11DRV_USER_GetResource( db, ".winver", &value))
-    VERSION_ParseWinVersion( (char*)value.addr );
-  if (X11DRV_USER_GetResource( db, ".dosver", &value))
-    VERSION_ParseDosVersion( (char*)value.addr );
-  if (X11DRV_USER_GetResource( db, ".config", &value))
-    Options.configFileName = xstrdup((char *)value.addr);
-  if (X11DRV_USER_GetResource( db, ".nodga", &value))
-    Options.noDGA = TRUE;
-  if (X11DRV_USER_GetResource( db, ".noxshm", &value))
-    Options.noXSHM = TRUE;
-  if (X11DRV_USER_GetResource( db, ".dxgrab", &value))
-    Options.DXGrab = TRUE;
-}
-
-/***********************************************************************
- *		X11DRV_USER_ErrorHandler
- */
-static int X11DRV_USER_ErrorHandler(Display *display, XErrorEvent *error_evt)
-{
-    DebugBreak();  /* force an entry in the debugger */
-    return 0;
-}
-
-/***********************************************************************
- *		X11DRV_USER_Create
- */
-void X11DRV_USER_Create()
-{
-  if (Options.synchronous) XSetErrorHandler( X11DRV_USER_ErrorHandler );
-  
-  if (Options.desktopGeometry && Options.managed)
-    {
-#if 0
-      MESSAGE( "%s: -managed and -desktop options cannot be used together\n",
-	   Options.programName );
-      exit(1);
-#else
-      Options.managed = FALSE;
-#endif
-    }
-}
-
 /***********************************************************************
  *           X11DRV_USER_SaveSetup
  */
-void X11DRV_USER_SaveSetup()
+static void X11DRV_USER_SaveSetup()
 {
   TSXGetKeyboardControl(display, &X11DRV_XKeyboardState);
 }
@@ -312,7 +152,7 @@ void X11DRV_USER_SaveSetup()
 /***********************************************************************
  *           X11DRV_USER_RestoreSetup
  */
-void X11DRV_USER_RestoreSetup()
+static void X11DRV_USER_RestoreSetup()
 {
   XKeyboardControl keyboard_value;
   
diff --git a/windows/x11drv/monitor.c b/windows/x11drv/monitor.c
index 049967d595303656f2691253b07aa951f11046b4..1972c1876691d26928b7d1d68fb07ac7bd8a8ba0 100644
--- a/windows/x11drv/monitor.c
+++ b/windows/x11drv/monitor.c
@@ -119,7 +119,7 @@ static void X11DRV_MONITOR_CreateDesktop(MONITOR *pMonitor)
 
   TSXStringListToTextProperty( &name, 1, &window_name );
   TSXSetWMProperties( display, pX11Monitor->rootWindow, &window_name, &window_name,
-                      Options.argv, *Options.argc, size_hints, wm_hints, class_hints );
+                      Options.argv, Options.argc, size_hints, wm_hints, class_hints );
   XA_WM_DELETE_WINDOW = TSXInternAtom( display, "WM_DELETE_WINDOW", False );
   TSXSetWMProtocols( display, pX11Monitor->rootWindow, &XA_WM_DELETE_WINDOW, 1 );
   TSXFree( size_hints );
@@ -149,8 +149,8 @@ void X11DRV_MONITOR_Initialize(MONITOR *pMonitor)
   pX11Monitor->width   = WidthOfScreen( pX11Monitor->screen );
   pX11Monitor->height  = HeightOfScreen( pX11Monitor->screen );
 
-  pX11Monitor->depth   = Options.screenDepth;
-  if (pX11Monitor->depth)  /* -depth option specified */
+  pX11Monitor->depth   = PROFILE_GetWineIniInt( "x11drv", "ScreenDepth", 0 );
+  if (pX11Monitor->depth)  /* depth specified */
     {
       depth_list = TSXListDepths(display, DefaultScreen(display), &depth_count);
       for (i = 0; i < depth_count; i++)
@@ -158,8 +158,7 @@ void X11DRV_MONITOR_Initialize(MONITOR *pMonitor)
       TSXFree( depth_list );
       if (i >= depth_count)
 	{
-	  MESSAGE( "%s: Depth %d not supported on this screen.\n",
-	       Options.programName, pX11Monitor->depth );
+	  MESSAGE( "%s: Depth %d not supported on this screen.\n", argv0, pX11Monitor->depth );
 	  exit(1);
 	}
     }
diff --git a/wine.ini b/wine.ini
index d5a8ecb2c610da8352f03b0ae979a70215f00d0d..b2e37409207bca466f94d046544794522da4d4ae 100644
--- a/wine.ini
+++ b/wine.ini
@@ -88,8 +88,21 @@ system, display, wprocs	= builtin
 wineps			= builtin
 icmp                    = builtin
 
-[options]
-AllocSystemColors=100
+[x11drv]
+; Number of colors to allocate from the system palette
+AllocSystemColors = 100
+; Use a private color map
+PrivateColorMap = N
+; Favor correctness over speed in some graphics operations
+PerfectGraphics = N
+; Color depth to use on multi-depth screens
+;;ScreenDepth = 16
+; Use XFree86 DGA extension if present
+UseDGA = Y
+; Use XShm extension if present
+UseXShm = Y
+; Enable DirectX mouse grab
+DXGrab = N
 
 [fonts]
 ;Read documentation/fonts before adding aliases