Commit 28c3a1ba authored by Alexandre Julliard's avatar Alexandre Julliard

Moved graphics initialisation to the x11drv/ttydrv dll init code.

Merged event, keyboard and mouse drivers into USER driver.
parent c03da668
......@@ -16,9 +16,6 @@
#include "win.h"
#include "wine/winuser16.h"
/**********************************************************************/
DESKTOP_DRIVER *DESKTOP_Driver = NULL;
/***********************************************************************
* DESKTOP_IsSingleWindow
......
......@@ -43,7 +43,7 @@
#include "dinput.h"
#include "display.h"
#include "input.h"
#include "keyboard.h"
#include "user.h"
#include "message.h"
#include "mouse.h"
#include "sysmetrics.h"
......@@ -782,7 +782,7 @@ static HRESULT WINAPI SysKeyboardAImpl_GetDeviceState(
LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr
)
{
return KEYBOARD_Driver->pGetDIState(len, ptr)?DI_OK:E_FAIL;
return USER_Driver->pGetDIState(len, ptr)?DI_OK:E_FAIL;
}
static HRESULT WINAPI SysKeyboardAImpl_GetDeviceData(
......@@ -797,7 +797,7 @@ static HRESULT WINAPI SysKeyboardAImpl_GetDeviceData(
TRACE("(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
This,dodsize,dod,entries,entries?*entries:0,flags);
ret=KEYBOARD_Driver->pGetDIData(
ret=USER_Driver->pGetDIData(
This->keystate, dodsize, dod, entries, flags)?DI_OK:E_FAIL;
for (i=0;i<*entries;i++) {
dod[i].dwTimeStamp = GetTickCount();
......@@ -816,11 +816,11 @@ static HRESULT WINAPI SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface)
KEYBOARD_CONFIG no_auto;
/* Save the original config */
KEYBOARD_Driver->pGetKeyboardConfig(&(This->initial_config));
USER_Driver->pGetKeyboardConfig(&(This->initial_config));
/* Now, remove auto-repeat */
no_auto.auto_repeat = FALSE;
KEYBOARD_Driver->pSetKeyboardConfig(&no_auto, WINE_KEYBOARD_CONFIG_AUTO_REPEAT);
USER_Driver->pSetKeyboardConfig(&no_auto, WINE_KEYBOARD_CONFIG_AUTO_REPEAT);
This->acquired = 1;
}
......@@ -835,7 +835,7 @@ static HRESULT WINAPI SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface)
if (This->acquired == 1) {
/* Restore the original configuration */
KEYBOARD_Driver->pSetKeyboardConfig(&(This->initial_config), 0xFFFFFFFF);
USER_Driver->pSetKeyboardConfig(&(This->initial_config), 0xFFFFFFFF);
This->acquired = 0;
} else {
ERR("Unacquiring a not-acquired device !!!\n");
......
......@@ -9,10 +9,10 @@
#include "display.h"
#include "mouse.h"
#include "windef.h"
#include "message.h"
#include "user.h"
#include "wine/winuser16.h"
DEFAULT_DEBUG_CHANNEL(cursor)
DEFAULT_DEBUG_CHANNEL(cursor);
/***********************************************************************
* DISPLAY_Inquire (DISPLAY.101)
......@@ -30,7 +30,7 @@ WORD WINAPI DISPLAY_Inquire(LPCURSORINFO lpCursorInfo)
*/
VOID WINAPI DISPLAY_SetCursor( struct tagCURSORICONINFO *lpCursor )
{
MOUSE_Driver->pSetCursor(lpCursor);
USER_Driver->pSetCursor(lpCursor);
}
/***********************************************************************
......@@ -38,7 +38,7 @@ VOID WINAPI DISPLAY_SetCursor( struct tagCURSORICONINFO *lpCursor )
*/
VOID WINAPI DISPLAY_MoveCursor( WORD wAbsX, WORD wAbsY )
{
MOUSE_Driver->pMoveCursor(wAbsX, wAbsY);
USER_Driver->pMoveCursor(wAbsX, wAbsY);
}
/***********************************************************************
......@@ -70,6 +70,6 @@ DWORD WINAPI DISPLAY_GetDriverResourceID( WORD wQueriedResID, LPSTR lpsResName )
*/
VOID WINAPI UserRepaintDisable16( BOOL16 disable )
{
EVENT_Driver->pUserRepaintDisable( disable );
USER_Driver->pUserRepaintDisable( disable );
}
......@@ -13,18 +13,17 @@
#include "module.h"
#include "mouse.h"
#include "monitor.h"
#include "user.h"
#include "windef.h"
#include "wingdi.h"
#include "winuser.h"
#include "win.h"
#include "wine/winbase16.h"
DEFAULT_DEBUG_CHANNEL(event)
DEFAULT_DEBUG_CHANNEL(event);
/**********************************************************************/
MOUSE_DRIVER *MOUSE_Driver = NULL;
static LPMOUSE_EVENT_PROC DefMouseEventProc = NULL;
/***********************************************************************
......@@ -57,10 +56,10 @@ VOID WINAPI MOUSE_Enable(LPMOUSE_EVENT_PROC lpMouseEventProc)
/* Now initialize the mouse driver */
if (initDone == FALSE)
{
MOUSE_Driver->pInit();
{
USER_Driver->pInitMouse();
initDone = TRUE;
}
}
}
static VOID WINAPI MOUSE_CallMouseEventProc( FARPROC16 proc,
......@@ -127,11 +126,11 @@ void MOUSE_SendEvent( DWORD mouseStatus, DWORD posX, DWORD posY,
wme.hWnd = hWnd;
wme.keyState = keyState;
MOUSE_Driver->pEnableWarpPointer(FALSE);
USER_Driver->pEnableWarpPointer(FALSE);
/* To avoid deadlocks, we have to suspend all locks on windows structures
before the program control is passed to the mouse driver */
iWndsLocks = WIN_SuspendWndsLock();
DefMouseEventProc( mouseStatus, posX, posY, 0, (DWORD)&wme );
WIN_RestoreWndsLock(iWndsLocks);
MOUSE_Driver->pEnableWarpPointer(TRUE);
USER_Driver->pEnableWarpPointer(TRUE);
}
name ttydrv
type win32
init TTYDRV_Init
import gdi32.dll
......@@ -4,19 +4,68 @@
#include <stdio.h>
#include "winbase.h"
#include "clipboard.h"
#include "gdi.h"
#include "user.h"
#include "message.h"
#include "monitor.h"
#include "mouse.h"
#include "ttydrv.h"
#include "user.h"
#include "win.h"
static USER_DRIVER user_driver =
{
/* event functions */
TTYDRV_EVENT_Synchronize,
TTYDRV_EVENT_CheckFocus,
TTYDRV_EVENT_UserRepaintDisable,
/* keyboard functions */
TTYDRV_KEYBOARD_Init,
TTYDRV_KEYBOARD_VkKeyScan,
TTYDRV_KEYBOARD_MapVirtualKey,
TTYDRV_KEYBOARD_GetKeyNameText,
TTYDRV_KEYBOARD_ToAscii,
TTYDRV_KEYBOARD_GetBeepActive,
TTYDRV_KEYBOARD_SetBeepActive,
TTYDRV_KEYBOARD_Beep,
TTYDRV_KEYBOARD_GetDIState,
TTYDRV_KEYBOARD_GetDIData,
TTYDRV_KEYBOARD_GetKeyboardConfig,
TTYDRV_KEYBOARD_SetKeyboardConfig,
/* mouse functions */
TTYDRV_MOUSE_Init,
TTYDRV_MOUSE_SetCursor,
TTYDRV_MOUSE_MoveCursor,
TTYDRV_MOUSE_EnableWarpPointer
};
/***********************************************************************
* TTYDRV initialisation routine
*/
BOOL WINAPI TTYDRV_Init( HINSTANCE hinst, DWORD reason, LPVOID reserved )
{
if (reason == DLL_PROCESS_ATTACH)
switch(reason)
{
GDI_Driver = &TTYDRV_GDI_Driver;
USER_Driver = &TTYDRV_USER_Driver;
case DLL_PROCESS_ATTACH:
USER_Driver = &user_driver;
CLIPBOARD_Driver = &TTYDRV_CLIPBOARD_Driver;
MONITOR_Driver = &TTYDRV_MONITOR_Driver;
WND_Driver = &TTYDRV_WND_Driver;
TTYDRV_MONITOR_Initialize( &MONITOR_PrimaryMonitor );
TTYDRV_GDI_Initialize();
break;
case DLL_PROCESS_DETACH:
TTYDRV_GDI_Finalize();
TTYDRV_MONITOR_Finalize( &MONITOR_PrimaryMonitor );
USER_Driver = NULL;
CLIPBOARD_Driver = NULL;
MONITOR_Driver = NULL;
WND_Driver = NULL;
break;
}
return TRUE;
}
name x11drv
type win32
init X11DRV_Init
import gdi32.dll
/*
* X11DRV initialization code
*
* Copyright 1998 Patrik Stridvall
* Copyright 2000 Alexandre Julliard
*/
#include <stdio.h>
#include <stdlib.h>
#include "ts_xlib.h"
#include "winbase.h"
#include "clipboard.h"
#include "debugtools.h"
#include "gdi.h"
#include "monitor.h"
#include "options.h"
#include "user.h"
#include "win.h"
#include "x11drv.h"
static USER_DRIVER user_driver =
{
/* event functions */
X11DRV_EVENT_Synchronize,
X11DRV_EVENT_CheckFocus,
X11DRV_EVENT_UserRepaintDisable,
/* keyboard functions */
X11DRV_KEYBOARD_Init,
X11DRV_KEYBOARD_VkKeyScan,
X11DRV_KEYBOARD_MapVirtualKey,
X11DRV_KEYBOARD_GetKeyNameText,
X11DRV_KEYBOARD_ToAscii,
X11DRV_KEYBOARD_GetBeepActive,
X11DRV_KEYBOARD_SetBeepActive,
X11DRV_KEYBOARD_Beep,
X11DRV_KEYBOARD_GetDIState,
X11DRV_KEYBOARD_GetDIData,
X11DRV_KEYBOARD_GetKeyboardConfig,
X11DRV_KEYBOARD_SetKeyboardConfig,
/* mouse functions */
X11DRV_MOUSE_Init,
X11DRV_MOUSE_SetCursor,
X11DRV_MOUSE_MoveCursor,
X11DRV_MOUSE_EnableWarpPointer
};
static XKeyboardState keyboard_state;
Display *display;
/***********************************************************************
* error_handler
*/
static int error_handler(Display *display, XErrorEvent *error_evt)
{
DebugBreak(); /* force an entry in the debugger */
return 0;
}
/***********************************************************************
* X11DRV process initialisation routine
*/
static void process_attach(void)
{
USER_Driver = &user_driver;
CLIPBOARD_Driver = &X11DRV_CLIPBOARD_Driver;
MONITOR_Driver = &X11DRV_MONITOR_Driver;
WND_Driver = &X11DRV_WND_Driver;
/* We need this before calling any Xlib function */
InitializeCriticalSection( &X11DRV_CritSection );
MakeCriticalSectionGlobal( &X11DRV_CritSection );
putenv("XKB_DISABLE="); /* Disable XKB extension if present. */
/* 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( error_handler );
if (Options.desktopGeometry && Options.managed) Options.managed = FALSE;
/* initialize monitor */
X11DRV_MONITOR_Initialize( &MONITOR_PrimaryMonitor );
/* initialize GDI */
X11DRV_GDI_Initialize();
/* save keyboard setup */
TSXGetKeyboardControl(display, &keyboard_state);
/* initialize event handling */
X11DRV_EVENT_Init();
}
/***********************************************************************
* X11DRV process termination routine
*/
static void process_detach(void)
{
/* restore keyboard setup */
XKeyboardControl keyboard_value;
keyboard_value.key_click_percent = keyboard_state.key_click_percent;
keyboard_value.bell_percent = keyboard_state.bell_percent;
keyboard_value.bell_pitch = keyboard_state.bell_pitch;
keyboard_value.bell_duration = keyboard_state.bell_duration;
keyboard_value.auto_repeat_mode = keyboard_state.global_auto_repeat;
XChangeKeyboardControl(display, KBKeyClickPercent | KBBellPercent |
KBBellPitch | KBBellDuration | KBAutoRepeatMode, &keyboard_value);
/* cleanup GDI */
X11DRV_GDI_Finalize();
#if 0 /* FIXME */
/* cleanup monitor */
X11DRV_MONITOR_Finalize( &MONITOR_PrimaryMonitor );
/* close the display */
XCloseDisplay( display );
display = NULL;
USER_Driver = NULL;
CLIPBOARD_Driver = NULL;
MONITOR_Driver = NULL;
WND_Driver = NULL;
#endif
}
/***********************************************************************
* X11DRV initialisation routine
*/
BOOL WINAPI X11DRV_Init( HINSTANCE hinst, DWORD reason, LPVOID reserved )
{
if (reason == DLL_PROCESS_ATTACH)
static int process_count;
switch(reason)
{
GDI_Driver = &X11DRV_GDI_Driver;
USER_Driver = &X11DRV_USER_Driver;
case DLL_PROCESS_ATTACH:
if (!process_count++) process_attach();
break;
case DLL_PROCESS_DETACH:
if (!--process_count) process_detach();
break;
}
return TRUE;
}
......@@ -112,12 +112,6 @@ static const DC_FUNCTIONS TTYDRV_DC_Driver =
};
GDI_DRIVER TTYDRV_GDI_Driver =
{
TTYDRV_GDI_Initialize,
TTYDRV_GDI_Finalize
};
BITMAP_DRIVER TTYDRV_BITMAP_Driver =
{
TTYDRV_BITMAP_SetDIBits,
......
......@@ -126,12 +126,6 @@ static const DC_FUNCTIONS X11DRV_Funcs =
NULL /* pWidenPath */
};
GDI_DRIVER X11DRV_GDI_Driver =
{
X11DRV_GDI_Initialize,
X11DRV_GDI_Finalize
};
BITMAP_DRIVER X11DRV_BITMAP_Driver =
{
X11DRV_DIB_SetDIBits,
......
......@@ -9,7 +9,6 @@
#include "windef.h"
struct tagDESKTOP_DRIVER;
struct tagMONITOR;
typedef struct tagDESKTOP
......@@ -18,18 +17,9 @@ typedef struct tagDESKTOP
HBITMAP hbitmapWallPaper;
SIZE bitmapSize;
BOOL fTileWallPaper;
struct tagMONITOR *pPrimaryMonitor;
struct tagDESKTOP_DRIVER *pDriver; /* Desktop driver */
void *pDriverData; /* Desktop driver data */
struct tagMONITOR *pPrimaryMonitor;
} DESKTOP;
typedef struct tagDESKTOP_DRIVER {
void (*pInitialize)(struct tagDESKTOP *pDesktop);
void (*pFinalize)(struct tagDESKTOP *pDesktop);
} DESKTOP_DRIVER;
extern DESKTOP_DRIVER *DESKTOP_Driver;
extern BOOL DESKTOP_IsSingleWindow(void);
extern int DESKTOP_GetScreenWidth(void);
extern int DESKTOP_GetScreenHeight(void);
......
......@@ -9,8 +9,6 @@
#include "windef.h"
struct DIDEVICEOBJECTDATA;
#include "pshpack1.h"
typedef struct _KBINFO
{
......@@ -31,28 +29,6 @@ VOID WINAPI KEYBOARD_Disable(VOID);
/* Wine internals */
#define WINE_KEYBOARD_CONFIG_AUTO_REPEAT 0x00000001
typedef struct tagKEYBOARD_CONFIG {
BOOL auto_repeat;
} KEYBOARD_CONFIG;
typedef struct tagKEYBOARD_DRIVER {
void (*pInit)(void);
WORD (*pVkKeyScan)(CHAR);
UINT16 (*pMapVirtualKey)(UINT16, UINT16);
INT16 (*pGetKeyNameText)(LONG, LPSTR, INT16);
INT16 (*pToAscii)(UINT16, UINT16, LPBYTE, LPVOID, UINT16);
BOOL (*pGetBeepActive)(void);
void (*pSetBeepActive)(BOOL);
void (*pBeep)(void);
BOOL (*pGetDIState)(DWORD, LPVOID);
BOOL (*pGetDIData)(BYTE *, DWORD, struct DIDEVICEOBJECTDATA *, LPDWORD, DWORD);
void (*pGetKeyboardConfig)(KEYBOARD_CONFIG *);
void (*pSetKeyboardConfig)(KEYBOARD_CONFIG *, DWORD);
} KEYBOARD_DRIVER;
extern KEYBOARD_DRIVER *KEYBOARD_Driver;
extern BOOL KEYBOARD_GetBeepActive(void);
extern void KEYBOARD_SetBeepActive(BOOL bActivate);
extern void KEYBOARD_Beep(void);
......
......@@ -26,16 +26,6 @@ extern BOOL TIMER_GetTimerMsg( struct tagMSG *msg, HWND hwnd,
HQUEUE16 hQueue, BOOL remove );
/* event.c */
typedef struct tagEVENT_DRIVER {
BOOL (*pInit)(void);
void (*pSynchronize)(void);
BOOL (*pCheckFocus)(void);
void (*pUserRepaintDisable)(BOOL);
} EVENT_DRIVER;
extern EVENT_DRIVER *EVENT_Driver;
extern BOOL EVENT_Init( void );
extern void EVENT_Synchronize( void );
extern BOOL EVENT_CheckFocus( void );
......
......@@ -32,8 +32,6 @@ extern MONITOR_DRIVER *MONITOR_Driver;
extern MONITOR MONITOR_PrimaryMonitor;
extern void MONITOR_Initialize(MONITOR *pMonitor);
extern void MONITOR_Finalize(MONITOR *pMonitor);
extern BOOL MONITOR_IsSingleWindow(MONITOR *pMonitor);
extern int MONITOR_GetWidth(MONITOR *pMonitor);
extern int MONITOR_GetHeight(MONITOR *pMonitor);
......
......@@ -34,15 +34,6 @@ VOID WINAPI MOUSE_Disable(VOID);
/* Wine internals */
typedef struct tagMOUSE_DRIVER {
VOID (*pInit)(VOID);
VOID (*pSetCursor)(struct tagCURSORICONINFO *);
VOID (*pMoveCursor)(WORD, WORD);
LONG (*pEnableWarpPointer)(BOOL);
} MOUSE_DRIVER;
extern MOUSE_DRIVER *MOUSE_Driver;
#define WINE_MOUSEEVENT_MAGIC ( ('M'<<24)|('A'<<16)|('U'<<8)|'S' )
typedef struct _WINE_MOUSEEVENT
{
......
......@@ -114,11 +114,6 @@ extern BOOL TTYDRV_PALETTE_IsDark(int pixel);
* TTY USER driver
*/
extern struct tagUSER_DRIVER TTYDRV_USER_Driver;
extern BOOL TTYDRV_USER_Initialize(void);
extern void TTYDRV_USER_Finalize(void);
/* TTY clipboard driver */
extern struct tagCLIPBOARD_DRIVER TTYDRV_CLIPBOARD_Driver;
......@@ -134,31 +129,18 @@ extern void TTYDRV_CLIPBOARD_ResetOwner(struct tagWND *pWnd, BOOL bFooBar);
/* TTY desktop driver */
extern struct tagDESKTOP_DRIVER TTYDRV_DESKTOP_Driver;
#ifdef HAVE_LIBCURSES
extern WINDOW *TTYDRV_DESKTOP_GetCursesRootWindow(struct tagDESKTOP *pDesktop);
#endif /* defined(HAVE_LIBCURSES) */
extern void TTYDRV_DESKTOP_Initialize(struct tagDESKTOP *pDesktop);
extern void TTYDRV_DESKTOP_Finalize(struct tagDESKTOP *pDesktop);
extern int TTYDRV_DESKTOP_GetScreenWidth(struct tagDESKTOP *pDesktop);
extern int TTYDRV_DESKTOP_GetScreenHeight(struct tagDESKTOP *pDesktop);
extern int TTYDRV_DESKTOP_GetScreenDepth(struct tagDESKTOP *pDesktop);
/* TTY event driver */
extern struct tagEVENT_DRIVER TTYDRV_EVENT_Driver;
extern BOOL TTYDRV_EVENT_Init(void);
extern void TTYDRV_EVENT_Synchronize(void);
extern BOOL TTYDRV_EVENT_CheckFocus(void);
extern void TTYDRV_EVENT_UserRepaintDisable(BOOL bDisable);
/* TTY keyboard driver */
extern struct tagKEYBOARD_DRIVER TTYDRV_KEYBOARD_Driver;
extern void TTYDRV_KEYBOARD_Init(void);
extern WORD TTYDRV_KEYBOARD_VkKeyScan(CHAR cChar);
extern UINT16 TTYDRV_KEYBOARD_MapVirtualKey(UINT16 wCode, UINT16 wMapType);
......@@ -209,8 +191,6 @@ extern void TTYDRV_MONITOR_SetScreenSaveTimeout(struct tagMONITOR *pMonitor, int
/* TTY mouse driver */
extern struct tagMOUSE_DRIVER TTYDRV_MOUSE_Driver;
extern void TTYDRV_MOUSE_Init();
extern void TTYDRV_MOUSE_SetCursor(struct tagCURSORICONINFO *lpCursor);
extern void TTYDRV_MOUSE_MoveCursor(WORD wAbsX, WORD wAbsY);
......
......@@ -29,9 +29,37 @@ extern WORD USER_HeapSel;
#define USUD_LOCALHEAP 0x0004
#define USUD_FIRSTCLASS 0x0005
struct tagCURSORICONINFO;
struct DIDEVICEOBJECTDATA;
#define WINE_KEYBOARD_CONFIG_AUTO_REPEAT 0x00000001
typedef struct tagKEYBOARD_CONFIG {
BOOL auto_repeat;
} KEYBOARD_CONFIG;
typedef struct tagUSER_DRIVER {
BOOL (*pInitialize)(void);
void (*pFinalize)(void);
/* event functions */
void (*pSynchronize)(void);
BOOL (*pCheckFocus)(void);
void (*pUserRepaintDisable)(BOOL);
/* keyboard functions */
void (*pInitKeyboard)(void);
WORD (*pVkKeyScan)(CHAR);
UINT16 (*pMapVirtualKey)(UINT16, UINT16);
INT16 (*pGetKeyNameText)(LONG, LPSTR, INT16);
INT16 (*pToAscii)(UINT16, UINT16, LPBYTE, LPVOID, UINT16);
BOOL (*pGetBeepActive)(void);
void (*pSetBeepActive)(BOOL);
void (*pBeep)(void);
BOOL (*pGetDIState)(DWORD, LPVOID);
BOOL (*pGetDIData)(BYTE *, DWORD, struct DIDEVICEOBJECTDATA *, LPDWORD, DWORD);
void (*pGetKeyboardConfig)(KEYBOARD_CONFIG *);
void (*pSetKeyboardConfig)(KEYBOARD_CONFIG *, DWORD);
/* mouse functions */
void (*pInitMouse)(void);
void (*pSetCursor)(struct tagCURSORICONINFO *);
void (*pMoveCursor)(WORD, WORD);
LONG (*pEnableWarpPointer)(BOOL);
} USER_DRIVER;
extern USER_DRIVER *USER_Driver;
......
......@@ -275,8 +275,6 @@ extern void X11DRV_DIB_DeleteDIBSection(struct tagBITMAPOBJ *bmp);
* X11 GDI driver
*/
extern struct tagGDI_DRIVER X11DRV_GDI_Driver;
BOOL X11DRV_GDI_Initialize(void);
void X11DRV_GDI_Finalize(void);
......@@ -312,15 +310,10 @@ extern BOOL X11DRV_PALETTE_IsDark(int pixel);
* X11 USER driver
*/
extern struct tagUSER_DRIVER X11DRV_USER_Driver;
extern Display *display;
extern Screen *X11DRV_GetXScreen(void);
extern Window X11DRV_GetXRootWindow(void);
extern BOOL X11DRV_USER_Initialize(void);
extern void X11DRV_USER_Finalize(void);
/* X11 clipboard driver */
extern struct tagCLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver;
......@@ -343,27 +336,13 @@ extern void X11DRV_CLIPBOARD_ReleaseSelection(Atom selType, Window w, HWND hwnd)
/* X11 desktop driver */
extern struct tagDESKTOP_DRIVER X11DRV_DESKTOP_Driver;
typedef struct _X11DRV_DESKTOP_DATA {
int dummy;
} X11DRV_DESKTOP_DATA;
struct tagDESKTOP;
extern Screen *X11DRV_DESKTOP_GetXScreen(struct tagDESKTOP *pDesktop);
extern Window X11DRV_DESKTOP_GetXRootWindow(struct tagDESKTOP *pDesktop);
extern void X11DRV_DESKTOP_Initialize(struct tagDESKTOP *pDesktop);
extern void X11DRV_DESKTOP_Finalize(struct tagDESKTOP *pDesktop);
extern int X11DRV_DESKTOP_GetScreenWidth(struct tagDESKTOP *pDesktop);
extern int X11DRV_DESKTOP_GetScreenHeight(struct tagDESKTOP *pDesktop);
extern int X11DRV_DESKTOP_GetScreenDepth(struct tagDESKTOP *pDesktop);
/* X11 event driver */
extern struct tagEVENT_DRIVER X11DRV_EVENT_Driver;
extern WORD X11DRV_EVENT_XStateToKeyState( int state ) ;
extern BOOL X11DRV_EVENT_Init(void);
......@@ -384,8 +363,6 @@ void X11DRV_EVENT_SetDGAStatus(HWND hwnd, int event_base) ;
/* X11 keyboard driver */
extern struct tagKEYBOARD_DRIVER X11DRV_KEYBOARD_Driver;
extern void X11DRV_KEYBOARD_Init(void);
extern WORD X11DRV_KEYBOARD_VkKeyScan(CHAR cChar);
extern UINT16 X11DRV_KEYBOARD_MapVirtualKey(UINT16 wCode, UINT16 wMapType);
......@@ -431,8 +408,6 @@ extern void X11DRV_MONITOR_SetScreenSaveTimeout(struct tagMONITOR *pMonitor, int
/* X11 mouse driver */
extern struct tagMOUSE_DRIVER X11DRV_MOUSE_Driver;
extern void X11DRV_MOUSE_Init();
extern void X11DRV_MOUSE_SetCursor(struct tagCURSORICONINFO *lpCursor);
extern void X11DRV_MOUSE_MoveCursor(WORD wAbsX, WORD wAbsY);
......
......@@ -110,9 +110,6 @@ BOOL MAIN_MainInit( int argc, char *argv[], BOOL win32 )
if (!LoadLibraryA( "x11drv" )) return FALSE;
/* Initialize event handling */
if (!EVENT_Init()) return FALSE;
SHELL_InitRegistrySaving();
return TRUE;
......
......@@ -6,12 +6,6 @@
#include "config.h"
#ifndef X_DISPLAY_MISSING
#include "x11drv.h"
#else /* !defined(X_DISPLAY_MISSING) */
#include "ttydrv.h"
#endif /* !defined(X_DISPLAY_MISSING) */
#include <locale.h>
#include <ctype.h>
#include <stdlib.h>
......@@ -640,11 +634,6 @@ void MAIN_ParseLanguageOption( const char *arg )
*/
static void called_at_exit(void)
{
if (GDI_Driver)
GDI_Driver->pFinalize();
if (USER_Driver)
USER_Driver->pFinalize();
CONSOLE_Close();
}
......
......@@ -338,10 +338,6 @@ BOOL GDI_Init(void)
ReadFontInformation("SystemFixed", &SystemFixedFont, 0, systemIsBold, 0, 0, 0);
ReadFontInformation("DefaultGui", &DefaultGuiFont, 0, 0, 0, 0, 0);
/* Initialize drivers */
GDI_Driver->pInitialize();
/* Create default palette */
/* DR well *this* palette can't be moveable (?) */
......
......@@ -7,30 +7,10 @@
#include "message.h"
#include "user.h"
#include "x11drv.h"
#include "ttydrv.h"
#include "monitor.h"
#include "win.h"
#include "debugtools.h"
DECLARE_DEBUG_CHANNEL(event)
/**********************************************************************/
EVENT_DRIVER *EVENT_Driver = NULL;
/***********************************************************************
* EVENT_Init
*
* Initialize input event handling
*/
BOOL EVENT_Init(void)
{
USER_Driver->pInitialize();
MONITOR_Initialize(&MONITOR_PrimaryMonitor);
return EVENT_Driver->pInit();
}
DECLARE_DEBUG_CHANNEL(event);
/***********************************************************************
* EVENT_Synchronize
......@@ -40,7 +20,7 @@ BOOL EVENT_Init(void)
void EVENT_Synchronize( void )
{
int iWndsLocks = WIN_SuspendWndsLock();
EVENT_Driver->pSynchronize();
USER_Driver->pSynchronize();
WIN_RestoreWndsLock(iWndsLocks);
}
......@@ -49,7 +29,7 @@ void EVENT_Synchronize( void )
*/
BOOL EVENT_CheckFocus(void)
{
return EVENT_Driver->pCheckFocus();
return USER_Driver->pCheckFocus();
}
......
......@@ -20,6 +20,7 @@
#include "win.h"
#include "heap.h"
#include "keyboard.h"
#include "user.h"
#include "message.h"
#include "callback.h"
#include "builtin16.h"
......@@ -32,8 +33,6 @@ DECLARE_DEBUG_CHANNEL(event)
/**********************************************************************/
KEYBOARD_DRIVER *KEYBOARD_Driver = NULL;
static LPKEYBD_EVENT_PROC DefKeybEventProc = NULL;
LPBYTE pKeyStateTable = NULL;
......@@ -67,7 +66,7 @@ VOID WINAPI KEYBOARD_Enable( LPKEYBD_EVENT_PROC lpKeybEventProc,
/* all states to false */
memset( lpKeyState, 0, 256 );
if (!initDone) KEYBOARD_Driver->pInit();
if (!initDone) USER_Driver->pInitKeyboard();
initDone = TRUE;
}
......@@ -181,7 +180,7 @@ DWORD WINAPI OemKeyScan(WORD wOemChar)
WORD WINAPI VkKeyScan16(CHAR cChar)
{
return KEYBOARD_Driver->pVkKeyScan(cChar);
return USER_Driver->pVkKeyScan(cChar);
}
/******************************************************************************
......@@ -214,7 +213,7 @@ INT16 WINAPI GetKeyboardType16(INT16 nTypeFlag)
*/
UINT16 WINAPI MapVirtualKey16(UINT16 wCode, UINT16 wMapType)
{
return KEYBOARD_Driver->pMapVirtualKey(wCode,wMapType);
return USER_Driver->pMapVirtualKey(wCode,wMapType);
}
/****************************************************************************
......@@ -231,7 +230,7 @@ INT16 WINAPI GetKBCodePage16(void)
*/
INT16 WINAPI GetKeyNameText16(LONG lParam, LPSTR lpBuffer, INT16 nSize)
{
return KEYBOARD_Driver->pGetKeyNameText(lParam, lpBuffer, nSize);
return USER_Driver->pGetKeyNameText(lParam, lpBuffer, nSize);
}
/****************************************************************************
......@@ -255,9 +254,7 @@ INT16 WINAPI GetKeyNameText16(LONG lParam, LPSTR lpBuffer, INT16 nSize)
INT16 WINAPI ToAscii16(UINT16 virtKey,UINT16 scanCode, LPBYTE lpKeyState,
LPVOID lpChar, UINT16 flags)
{
return KEYBOARD_Driver->pToAscii(
virtKey, scanCode, lpKeyState, lpChar, flags
);
return USER_Driver->pToAscii( virtKey, scanCode, lpKeyState, lpChar, flags );
}
/***********************************************************************
......@@ -265,7 +262,7 @@ INT16 WINAPI ToAscii16(UINT16 virtKey,UINT16 scanCode, LPBYTE lpKeyState,
*/
BOOL KEYBOARD_GetBeepActive()
{
return KEYBOARD_Driver->pGetBeepActive();
return USER_Driver->pGetBeepActive();
}
/***********************************************************************
......@@ -273,7 +270,7 @@ BOOL KEYBOARD_GetBeepActive()
*/
void KEYBOARD_SetBeepActive(BOOL bActivate)
{
KEYBOARD_Driver->pSetBeepActive(bActivate);
USER_Driver->pSetBeepActive(bActivate);
}
/***********************************************************************
......@@ -281,6 +278,6 @@ void KEYBOARD_SetBeepActive(BOOL bActivate)
*/
void KEYBOARD_Beep(void)
{
KEYBOARD_Driver->pBeep();
USER_Driver->pBeep();
}
......@@ -38,22 +38,6 @@ static MONITOR *MONITOR_GetMonitor(HMONITOR hMonitor)
#endif
/***********************************************************************
* MONITOR_Initialize
*/
void MONITOR_Initialize(MONITOR *pMonitor)
{
MONITOR_Driver->pInitialize(pMonitor);
}
/***********************************************************************
* MONITOR_Finalize
*/
void MONITOR_Finalize(MONITOR *pMonitor)
{
MONITOR_Driver->pFinalize(pMonitor);
}
/***********************************************************************
* MONITOR_IsSingleWindow
*/
BOOL MONITOR_IsSingleWindow(MONITOR *pMonitor)
......
......@@ -25,51 +25,3 @@ WINDOW *TTYDRV_DESKTOP_GetCursesRootWindow(DESKTOP *pDesktop)
return TTYDRV_MONITOR_GetCursesRootWindow(pDesktop->pPrimaryMonitor);
}
#endif /* defined(HAVE_LIBCURSES) */
/***********************************************************************
* TTYDRV_DESKTOP_Initialize
*/
void TTYDRV_DESKTOP_Initialize(DESKTOP *pDesktop)
{
TRACE("(%p): stub\n", pDesktop);
pDesktop->pPrimaryMonitor = &MONITOR_PrimaryMonitor;
}
/***********************************************************************
* TTYDRV_DESKTOP_Finalize
*/
void TTYDRV_DESKTOP_Finalize(DESKTOP *pDesktop)
{
TRACE("(%p): stub\n", pDesktop);
}
/***********************************************************************
* TTYDRV_DESKTOP_GetScreenWidth
*
* Return the width of the screen associated to the desktop.
*/
int TTYDRV_DESKTOP_GetScreenWidth(DESKTOP *pDesktop)
{
return MONITOR_GetWidth(pDesktop->pPrimaryMonitor);
}
/***********************************************************************
* TTYDRV_DESKTOP_GetScreenHeight
*
* Return the width of the screen associated to the desktop.
*/
int TTYDRV_DESKTOP_GetScreenHeight(DESKTOP *pDesktop)
{
return MONITOR_GetHeight(pDesktop->pPrimaryMonitor);
}
/***********************************************************************
* TTYDRV_DESKTOP_GetScreenDepth
*
* Return the depth of the screen associated to the desktop.
*/
int TTYDRV_DESKTOP_GetScreenDepth(DESKTOP *pDesktop)
{
return MONITOR_GetDepth(pDesktop->pPrimaryMonitor);
}
......@@ -7,14 +7,6 @@
#include "ttydrv.h"
/***********************************************************************
* TTYDRV_EVENT_Init
*/
BOOL TTYDRV_EVENT_Init(void)
{
return TRUE;
}
/***********************************************************************
* TTYDRV_EVENT_Synchronize
*/
void TTYDRV_EVENT_Synchronize( void )
......
......@@ -5,21 +5,11 @@
*/
#include "clipboard.h"
#include "desktop.h"
#include "keyboard.h"
#include "message.h"
#include "monitor.h"
#include "mouse.h"
#include "user.h"
#include "win.h"
#include "ttydrv.h"
USER_DRIVER TTYDRV_USER_Driver =
{
TTYDRV_USER_Initialize,
TTYDRV_USER_Finalize
};
CLIPBOARD_DRIVER TTYDRV_CLIPBOARD_Driver =
{
TTYDRV_CLIPBOARD_Acquire,
......@@ -32,36 +22,6 @@ CLIPBOARD_DRIVER TTYDRV_CLIPBOARD_Driver =
TTYDRV_CLIPBOARD_ResetOwner
};
DESKTOP_DRIVER TTYDRV_DESKTOP_Driver =
{
TTYDRV_DESKTOP_Initialize,
TTYDRV_DESKTOP_Finalize
};
EVENT_DRIVER TTYDRV_EVENT_Driver =
{
TTYDRV_EVENT_Init,
TTYDRV_EVENT_Synchronize,
TTYDRV_EVENT_CheckFocus,
TTYDRV_EVENT_UserRepaintDisable
};
KEYBOARD_DRIVER TTYDRV_KEYBOARD_Driver =
{
TTYDRV_KEYBOARD_Init,
TTYDRV_KEYBOARD_VkKeyScan,
TTYDRV_KEYBOARD_MapVirtualKey,
TTYDRV_KEYBOARD_GetKeyNameText,
TTYDRV_KEYBOARD_ToAscii,
TTYDRV_KEYBOARD_GetBeepActive,
TTYDRV_KEYBOARD_SetBeepActive,
TTYDRV_KEYBOARD_Beep,
TTYDRV_KEYBOARD_GetDIState,
TTYDRV_KEYBOARD_GetDIData,
TTYDRV_KEYBOARD_GetKeyboardConfig,
TTYDRV_KEYBOARD_SetKeyboardConfig
};
MONITOR_DRIVER TTYDRV_MONITOR_Driver =
{
TTYDRV_MONITOR_Initialize,
......@@ -76,14 +36,6 @@ MONITOR_DRIVER TTYDRV_MONITOR_Driver =
TTYDRV_MONITOR_SetScreenSaveTimeout
};
MOUSE_DRIVER TTYDRV_MOUSE_Driver =
{
TTYDRV_MOUSE_Init,
TTYDRV_MOUSE_SetCursor,
TTYDRV_MOUSE_MoveCursor,
TTYDRV_MOUSE_EnableWarpPointer
};
WND_DRIVER TTYDRV_WND_Driver =
{
TTYDRV_WND_Initialize,
......
......@@ -5,6 +5,7 @@
*/
#include "dinput.h"
#include "user.h"
#include "keyboard.h"
#include "ttydrv.h"
......
......@@ -16,25 +16,3 @@
#include "ttydrv.h"
#include "win.h"
/***********************************************************************
* TTYDRV_USER_Initialize
*/
BOOL TTYDRV_USER_Initialize(void)
{
CLIPBOARD_Driver = &TTYDRV_CLIPBOARD_Driver;
DESKTOP_Driver = &TTYDRV_DESKTOP_Driver;
EVENT_Driver = &TTYDRV_EVENT_Driver;
KEYBOARD_Driver = &TTYDRV_KEYBOARD_Driver;
MONITOR_Driver = &TTYDRV_MONITOR_Driver;
MOUSE_Driver = &TTYDRV_MOUSE_Driver;
WND_Driver = &TTYDRV_WND_Driver;
return TRUE;
}
/***********************************************************************
* TTYDRV_USER_Finalize
*/
void TTYDRV_USER_Finalize(void)
{
}
......@@ -20,6 +20,7 @@
#include "hook.h"
#include "menu.h"
#include "message.h"
#include "monitor.h"
#include "nonclient.h"
#include "queue.h"
#include "winpos.h"
......@@ -602,10 +603,9 @@ BOOL WIN_CreateDesktopWindow(void)
pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
pDesktop = (DESKTOP *) pWndDesktop->wExtra;
pDesktop->pDriver = DESKTOP_Driver;
pWndDesktop->pDriver = WND_Driver;
pDesktop->pPrimaryMonitor = &MONITOR_PrimaryMonitor;
pDesktop->pDriver->pInitialize(pDesktop);
pWndDesktop->pDriver = WND_Driver;
pWndDesktop->pDriver->pInitialize(pWndDesktop);
pWndDesktop->next = NULL;
......
......@@ -37,49 +37,4 @@ Window X11DRV_DESKTOP_GetXRootWindow(DESKTOP *pDesktop)
return X11DRV_MONITOR_GetXRootWindow(pDesktop->pPrimaryMonitor);
}
/***********************************************************************
* X11DRV_DESKTOP_Initialize
*/
void X11DRV_DESKTOP_Initialize(DESKTOP *pDesktop)
{
pDesktop->pPrimaryMonitor = &MONITOR_PrimaryMonitor;
}
/***********************************************************************
* X11DRV_DESKTOP_Finalize
*/
void X11DRV_DESKTOP_Finalize(DESKTOP *pDesktop)
{
}
/***********************************************************************
* X11DRV_DESKTOP_GetScreenWidth
*
* Return the width of the screen associated to the desktop.
*/
int X11DRV_DESKTOP_GetScreenWidth(DESKTOP *pDesktop)
{
return MONITOR_GetWidth(pDesktop->pPrimaryMonitor);
}
/***********************************************************************
* X11DRV_DESKTOP_GetScreenHeight
*
* Return the width of the screen associated to the desktop.
*/
int X11DRV_DESKTOP_GetScreenHeight(DESKTOP *pDesktop)
{
return MONITOR_GetHeight(pDesktop->pPrimaryMonitor);
}
/***********************************************************************
* X11DRV_DESKTOP_GetScreenDepth
*
* Return the depth of the screen associated to the desktop.
*/
int X11DRV_DESKTOP_GetScreenDepth(DESKTOP *pDesktop)
{
return MONITOR_GetDepth(pDesktop->pPrimaryMonitor);
}
#endif /* X_DISPLAY_MISSING */
......@@ -9,21 +9,11 @@
#ifndef X_DISPLAY_MISSING
#include "clipboard.h"
#include "desktop.h"
#include "keyboard.h"
#include "message.h"
#include "monitor.h"
#include "mouse.h"
#include "user.h"
#include "win.h"
#include "x11drv.h"
USER_DRIVER X11DRV_USER_Driver =
{
X11DRV_USER_Initialize,
X11DRV_USER_Finalize
};
CLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver =
{
X11DRV_CLIPBOARD_Acquire,
......@@ -36,36 +26,6 @@ CLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver =
X11DRV_CLIPBOARD_ResetOwner
};
DESKTOP_DRIVER X11DRV_DESKTOP_Driver =
{
X11DRV_DESKTOP_Initialize,
X11DRV_DESKTOP_Finalize
};
EVENT_DRIVER X11DRV_EVENT_Driver =
{
X11DRV_EVENT_Init,
X11DRV_EVENT_Synchronize,
X11DRV_EVENT_CheckFocus,
X11DRV_EVENT_UserRepaintDisable
};
KEYBOARD_DRIVER X11DRV_KEYBOARD_Driver =
{
X11DRV_KEYBOARD_Init,
X11DRV_KEYBOARD_VkKeyScan,
X11DRV_KEYBOARD_MapVirtualKey,
X11DRV_KEYBOARD_GetKeyNameText,
X11DRV_KEYBOARD_ToAscii,
X11DRV_KEYBOARD_GetBeepActive,
X11DRV_KEYBOARD_SetBeepActive,
X11DRV_KEYBOARD_Beep,
X11DRV_KEYBOARD_GetDIState,
X11DRV_KEYBOARD_GetDIData,
X11DRV_KEYBOARD_GetKeyboardConfig,
X11DRV_KEYBOARD_SetKeyboardConfig
};
MONITOR_DRIVER X11DRV_MONITOR_Driver =
{
X11DRV_MONITOR_Initialize,
......@@ -80,14 +40,6 @@ MONITOR_DRIVER X11DRV_MONITOR_Driver =
X11DRV_MONITOR_SetScreenSaveTimeout
};
MOUSE_DRIVER X11DRV_MOUSE_Driver =
{
X11DRV_MOUSE_Init,
X11DRV_MOUSE_SetCursor,
X11DRV_MOUSE_MoveCursor,
X11DRV_MOUSE_EnableWarpPointer
};
WND_DRIVER X11DRV_WND_Driver =
{
X11DRV_WND_Initialize,
......
......@@ -26,6 +26,7 @@
#include "wine/winuser16.h"
#include "dinput.h"
#include "debugtools.h"
#include "user.h"
#include "keyboard.h"
#include "message.h"
#include "winnls.h"
......@@ -34,7 +35,6 @@
DEFAULT_DEBUG_CHANNEL(keyboard)
DECLARE_DEBUG_CHANNEL(key)
DECLARE_DEBUG_CHANNEL(x11drv)
DECLARE_DEBUG_CHANNEL(dinput)
extern BYTE InputKeyStateTable[256];
......@@ -1474,7 +1474,7 @@ BOOL X11DRV_KEYBOARD_GetDIState(DWORD len, LPVOID ptr)
}
return TRUE;
}
WARN_(x11drv)("whoops, X11DRV_KEYBOARD_GetState got len %ld?\n", len);
WARN("whoops, X11DRV_KEYBOARD_GetState got len %ld?\n", len);
return TRUE;
}
......
......@@ -32,15 +32,6 @@
#include "windef.h"
#include "x11drv.h"
/**********************************************************************/
static void X11DRV_USER_SaveSetup(void);
static void X11DRV_USER_RestoreSetup(void);
/**********************************************************************/
static XKeyboardState X11DRV_XKeyboardState;
Display *display;
/***********************************************************************
* X11DRV_GetXScreen
......@@ -62,90 +53,4 @@ 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
*/
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 );
putenv("XKB_DISABLE="); /* Disable XKB extension if present. */
/* 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;
}
/***********************************************************************
* X11DRV_USER_Finalize
*/
void X11DRV_USER_Finalize(void)
{
X11DRV_USER_RestoreSetup();
}
/***********************************************************************
* X11DRV_USER_SaveSetup
*/
static void X11DRV_USER_SaveSetup()
{
TSXGetKeyboardControl(display, &X11DRV_XKeyboardState);
}
/***********************************************************************
* X11DRV_USER_RestoreSetup
*/
static 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 */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment