| /* |
| * 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 "debugtools.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" |
| |
| /**********************************************************************/ |
| |
| 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"}, |
| { "-noxshm", ".noxshm", 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 ))) |
| { |
| 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, ".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 |
| MESSAGE("%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 ? |
| */ |
| 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, ".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) |
| { |
| 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() |
| { |
| 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 */ |