| /* | |
| * X11 main driver | |
| * | |
| * Copyright 1998 Patrik Stridvall | |
| * | |
| */ | |
| #include "config.h" | |
| #ifndef X_DISPLAY_MISSING | |
| #include <X11/Xlocale.h> | |
| #include "ts_xlib.h" | |
| #include "ts_xresource.h" | |
| #include "ts_xutil.h" | |
| #include <signal.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <unistd.h> | |
| #include "clipboard.h" | |
| #include "console.h" | |
| #include "debug.h" | |
| #include "desktop.h" | |
| #include "keyboard.h" | |
| #include "main.h" | |
| #include "message.h" | |
| #include "monitor.h" | |
| #include "mouse.h" | |
| #include "options.h" | |
| #include "win.h" | |
| #include "windef.h" | |
| #include "x11drv.h" | |
| #include "xmalloc.h" | |
| #include "version.h" | |
| #include "win.h" | |
| /**********************************************************************/ | |
| 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[] = | |
| { | |
| { "-backingstore", ".backingstore", XrmoptionNoArg, (caddr_t)"on" }, | |
| { "-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" }, | |
| { "-fixedmap", ".fixedmap", 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" }, | |
| { "-mode", ".mode", XrmoptionSepArg, (caddr_t)NULL }, | |
| { "-managed", ".managed", XrmoptionNoArg, (caddr_t)"off"}, | |
| { "-winver", ".winver", XrmoptionSepArg, (caddr_t)NULL }, | |
| { "-config", ".config", XrmoptionSepArg, (caddr_t)NULL }, | |
| { "-nodga", ".nodga", XrmoptionNoArg, (caddr_t)"off"}, | |
| { "-console", ".console", XrmoptionSepArg, (caddr_t)NULL }, | |
| { "-dosver", ".dosver", XrmoptionSepArg, (caddr_t)NULL } | |
| }; | |
| #define NB_OPTIONS (sizeof(optionsTable) / sizeof(optionsTable[0])) | |
| /**********************************************************************/ | |
| static XKeyboardState X11DRV_XKeyboardState; | |
| Display *display; | |
| /*********************************************************************** | |
| * X11DRV_GetXScreen | |
| * | |
| * Return the X screen associated to the current desktop. | |
| */ | |
| Screen *X11DRV_GetXScreen() | |
| { | |
| return X11DRV_MONITOR_GetXScreen(&MONITOR_PrimaryMonitor); | |
| } | |
| /*********************************************************************** | |
| * X11DRV_GetXRootWindow | |
| * | |
| * Return the X display associated to the current desktop. | |
| */ | |
| Window X11DRV_GetXRootWindow() | |
| { | |
| return X11DRV_MONITOR_GetXRootWindow(&MONITOR_PrimaryMonitor); | |
| } | |
| /*********************************************************************** | |
| * X11DRV_USER_Initialize | |
| */ | |
| BOOL X11DRV_USER_Initialize(void) | |
| { | |
| CLIPBOARD_Driver = &X11DRV_CLIPBOARD_Driver; | |
| DESKTOP_Driver = &X11DRV_DESKTOP_Driver; | |
| EVENT_Driver = &X11DRV_EVENT_Driver; | |
| KEYBOARD_Driver = &X11DRV_KEYBOARD_Driver; | |
| MONITOR_Driver = &X11DRV_MONITOR_Driver; | |
| MOUSE_Driver = &X11DRV_MOUSE_Driver; | |
| WND_Driver = &X11DRV_WND_Driver; | |
| /* We need this before calling any Xlib function */ | |
| 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(); | |
| X11DRV_USER_SaveSetup(); | |
| return TRUE; | |
| } | |
| /*********************************************************************** | |
| * X11DRV_USER_Finalize | |
| */ | |
| void X11DRV_USER_Finalize(void) | |
| { | |
| X11DRV_USER_RestoreSetup(); | |
| } | |
| /************************************************************************** | |
| * X11DRV_USER_BeginDebugging | |
| */ | |
| void X11DRV_USER_BeginDebugging(void) | |
| { | |
| TSXUngrabServer(display); | |
| TSXFlush(display); | |
| } | |
| /************************************************************************** | |
| * X11DRV_USER_EndDebugging | |
| */ | |
| 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 ))) | |
| { | |
| MSG( "%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, ".iconic", &value )) | |
| Options.cmdShow = SW_SHOWMINIMIZED; | |
| if (X11DRV_USER_GetResource( db, ".privatemap", &value )) | |
| Options.usePrivateMap = TRUE; | |
| if (X11DRV_USER_GetResource( db, ".fixedmap", &value )) | |
| Options.useFixedMap = TRUE; | |
| if (X11DRV_USER_GetResource( db, ".synchronous", &value )) | |
| Options.synchronous = TRUE; | |
| if (X11DRV_USER_GetResource( db, ".backingstore", &value )) | |
| Options.backingstore = 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, ".mode", &value)) | |
| MAIN_ParseModeOption( (char *)value.addr ); | |
| if (X11DRV_USER_GetResource( db, ".debugoptions", &value)) | |
| MAIN_ParseDebugOptions((char*)value.addr); | |
| if (X11DRV_USER_GetResource( db, ".debugmsg", &value)) | |
| { | |
| #ifndef DEBUG_RUNTIME | |
| MSG("%s: Option \"-debugmsg\" not implemented.\n" \ | |
| " Recompile with DEBUG_RUNTIME in include/debugtools.h defined.\n", | |
| argv[0]); | |
| exit(1); | |
| #else | |
| MAIN_ParseDebugOptions((char*)value.addr); | |
| #endif | |
| } | |
| if (X11DRV_USER_GetResource( db, ".dll", &value)) | |
| { | |
| if (Options.dllFlags) | |
| { | |
| /* don't overwrite previous value. Should we | |
| * automatically add the ',' between multiple DLLs ? | |
| */ | |
| MSG("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, ".console", &value)) | |
| driver.driver_list = xstrdup((char *)value.addr); | |
| else | |
| driver.driver_list = CONSOLE_DEFAULT_DRIVER; | |
| } | |
| /*********************************************************************** | |
| * X11DRV_USER_ErrorHandler | |
| */ | |
| static int X11DRV_USER_ErrorHandler(Display *display, XErrorEvent *error_evt) | |
| { | |
| kill( getpid(), SIGHUP ); /* 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 | |
| MSG( "%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() | |
| { | |
| TSXGetKeyboardControl(display, &X11DRV_XKeyboardState); | |
| } | |
| /*********************************************************************** | |
| * X11DRV_USER_RestoreSetup | |
| */ | |
| void X11DRV_USER_RestoreSetup() | |
| { | |
| XKeyboardControl keyboard_value; | |
| keyboard_value.key_click_percent = X11DRV_XKeyboardState.key_click_percent; | |
| keyboard_value.bell_percent = X11DRV_XKeyboardState.bell_percent; | |
| keyboard_value.bell_pitch = X11DRV_XKeyboardState.bell_pitch; | |
| keyboard_value.bell_duration = X11DRV_XKeyboardState.bell_duration; | |
| keyboard_value.auto_repeat_mode = X11DRV_XKeyboardState.global_auto_repeat; | |
| XChangeKeyboardControl(display, KBKeyClickPercent | KBBellPercent | | |
| KBBellPitch | KBBellDuration | KBAutoRepeatMode, &keyboard_value); | |
| } | |
| #endif /* X_DISPLAY_MISSING */ |