Merged clipboard driver into USER driver.
Moved all ttydrv source files to dlls/ttydrv.
Load functions pointer for the USER driver from the graphics driver
dll with GetProcAddress.

diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
index 0de9dc9..85cbdfa 100644
--- a/dlls/dinput/dinput_main.c
+++ b/dlls/dinput/dinput_main.c
@@ -787,7 +787,7 @@
 	LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr
 )
 {
-	return USER_Driver->pGetDIState(len, ptr)?DI_OK:E_FAIL;
+	return USER_Driver.pGetDIState(len, ptr)?DI_OK:E_FAIL;
 }
 
 static HRESULT WINAPI SysKeyboardAImpl_GetDeviceData(
@@ -802,7 +802,7 @@
 	TRACE("(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
 	      This,dodsize,dod,entries,entries?*entries:0,flags);
 
-	ret=USER_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();
@@ -821,11 +821,11 @@
 	  KEYBOARD_CONFIG no_auto;
 	  
 	  /* Save the original config */
-	  USER_Driver->pGetKeyboardConfig(&(This->initial_config));
+	  USER_Driver.pGetKeyboardConfig(&(This->initial_config));
 	  
 	  /* Now, remove auto-repeat */
 	  no_auto.auto_repeat = FALSE;
-	  USER_Driver->pSetKeyboardConfig(&no_auto, WINE_KEYBOARD_CONFIG_AUTO_REPEAT);
+	  USER_Driver.pSetKeyboardConfig(&no_auto, WINE_KEYBOARD_CONFIG_AUTO_REPEAT);
 
 	  This->acquired = 1;
 	}
@@ -840,7 +840,7 @@
 
 	if (This->acquired == 1) {
 	  /* Restore the original configuration */
-	  USER_Driver->pSetKeyboardConfig(&(This->initial_config), 0xFFFFFFFF);
+	  USER_Driver.pSetKeyboardConfig(&(This->initial_config), 0xFFFFFFFF);
 	  This->acquired = 0;
 	} else {
 	  ERR("Unacquiring a not-acquired device !!!\n");
@@ -1431,7 +1431,7 @@
       point.x = This->win_centerX;
       point.y = This->win_centerY;
       MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
-      USER_Driver->pMoveCursor( point.x, point.y );
+      USER_Driver.pMoveCursor( point.x, point.y );
       This->need_warp = WARP_STARTED;
     }
 
@@ -1493,7 +1493,7 @@
     point.x = This->win_centerX;
     point.y = This->win_centerY;
     MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
-    USER_Driver->pMoveCursor( point.x, point.y );
+    USER_Driver.pMoveCursor( point.x, point.y );
 
     This->need_warp = WARP_STARTED;
   }
@@ -1560,7 +1560,7 @@
     point.y = This->win_centerY;
     MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
 
-    USER_Driver->pMoveCursor( point.x, point.y );
+    USER_Driver.pMoveCursor( point.x, point.y );
 
     This->need_warp = WARP_STARTED;
   }
diff --git a/dlls/ttydrv/Makefile.in b/dlls/ttydrv/Makefile.in
index 24bb230..c2a88df 100644
--- a/dlls/ttydrv/Makefile.in
+++ b/dlls/ttydrv/Makefile.in
@@ -8,20 +8,16 @@
 IMPORTS   = user32 gdi32 kernel32
 
 C_SRCS = \
-	ttydrv_main.c
-
-EXTRA_OBJS = \
-	$(TOPOBJDIR)/graphics/ttydrv/ttydrv.o \
-	$(TOPOBJDIR)/windows/ttydrv/ttydrv.o
-
-SUBDIRS = \
-	$(TOPOBJDIR)/graphics/ttydrv \
-	$(TOPOBJDIR)/windows/ttydrv
+	bitmap.c \
+	dc.c \
+	graphics.c \
+	objects.c \
+	palette.c \
+	ttydrv_main.c \
+	user.c \
+	wnd.c
 
 @MAKE_DLL_RULES@
 
-$(EXTRA_OBJS): $(TOOLSUBDIRS) dummy
-	@cd `dirname $@` && $(MAKE) `basename $@`
-
 ### Dependencies:
 
diff --git a/dlls/ttydrv/bitmap.c b/dlls/ttydrv/bitmap.c
new file mode 100644
index 0000000..ddcc670
--- /dev/null
+++ b/dlls/ttydrv/bitmap.c
@@ -0,0 +1,246 @@
+/*
+ * TTY bitmap driver
+ *
+ * Copyright 1999 Patrik Stridvall
+ */
+
+#include "bitmap.h"
+#include "dc.h"
+#include "ttydrv.h"
+#include "winbase.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(ttydrv);
+
+/**********************************************************************/
+
+static LONG TTYDRV_DC_GetBitmapBits(BITMAPOBJ *bitmap, void *bits, LONG count);
+static LONG TTYDRV_DC_SetBitmapBits(BITMAPOBJ *bitmap, void *bits, LONG count);
+
+/***********************************************************************
+ *		TTYDRV_DC_AllocBitmap
+ */
+TTYDRV_PHYSBITMAP *TTYDRV_DC_AllocBitmap(BITMAPOBJ *bitmap)
+{
+  TTYDRV_PHYSBITMAP *physBitmap;
+  
+  if(!(physBitmap = HeapAlloc(GetProcessHeap(), 0, sizeof(TTYDRV_PHYSBITMAP)))) {
+    ERR("Can't alloc TTYDRV_PHYSBITMAP\n");
+    return NULL;
+  }
+
+  bitmap->physBitmap = physBitmap;
+  bitmap->funcs = DRIVER_FindDriver("DISPLAY");
+
+  return physBitmap;
+}
+
+/***********************************************************************
+ *           TTYDRV_DC_BitmapBits
+ */
+LONG TTYDRV_DC_BitmapBits(HBITMAP hbitmap, void *bits, LONG count, WORD flags)
+{
+  BITMAPOBJ *bitmap;
+  LONG result;
+
+  if(!(bitmap = (BITMAPOBJ *) GDI_GetObjPtr(hbitmap, BITMAP_MAGIC)))
+    return FALSE;
+  
+  if(flags == DDB_GET)
+    result = TTYDRV_DC_GetBitmapBits(bitmap, bits, count);
+  else if(flags == DDB_SET)
+    result = TTYDRV_DC_SetBitmapBits(bitmap, bits, count);
+  else {
+    ERR("Unknown flags value %d\n", flags);
+    result = 0;
+  }
+  
+  GDI_HEAP_UNLOCK(hbitmap);
+  return result;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_CreateBitmap
+ */
+BOOL TTYDRV_DC_CreateBitmap(HBITMAP hbitmap)
+{
+  TTYDRV_PHYSBITMAP *physBitmap;
+  BITMAPOBJ *bitmap;
+
+  TRACE("(0x%04x)\n", hbitmap);
+
+  if(!(bitmap = (BITMAPOBJ *) GDI_GetObjPtr(hbitmap, BITMAP_MAGIC)))
+    return FALSE;
+  
+  if(!(physBitmap = TTYDRV_DC_AllocBitmap(bitmap))) {
+    GDI_HEAP_UNLOCK(hbitmap);
+    return FALSE;
+  }
+ 
+  /* Set bitmap bits */
+  if(bitmap->bitmap.bmBits) { 
+    TTYDRV_DC_BitmapBits(hbitmap, bitmap->bitmap.bmBits,
+			 bitmap->bitmap.bmHeight * bitmap->bitmap.bmWidthBytes,
+			 DDB_SET );
+  }
+
+  GDI_HEAP_UNLOCK(hbitmap);
+  
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_BITMAP_DeleteObject
+ */
+BOOL TTYDRV_DC_BITMAP_DeleteObject(HBITMAP hbitmap, BITMAPOBJ *bitmap)
+{
+  TRACE("(0x%04x, %p)\n", hbitmap, bitmap);
+
+  HeapFree(GetProcessHeap(), 0, bitmap->physBitmap);
+  bitmap->physBitmap = NULL;
+  bitmap->funcs = NULL;
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_GetBitmapBits
+ */
+static LONG TTYDRV_DC_GetBitmapBits(BITMAPOBJ *bitmap, void *bits, LONG count)
+{
+  FIXME("(%p, %p, %ld): stub\n", bitmap, bits, count);
+
+  memset(bits, 0, count);
+
+  return count;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_BITMAP_SelectObject
+ */
+HBITMAP TTYDRV_DC_BITMAP_SelectObject(DC *dc, HBITMAP hbitmap, BITMAPOBJ *bitmap)
+{
+  HBITMAP hPreviousBitmap;
+
+  TRACE("(%p, 0x%04x, %p)\n", dc, hbitmap, bitmap);
+
+  if(!(dc->w.flags & DC_MEMORY)) 
+    return 0;
+
+  /* Assure that the bitmap device dependent */
+  if(!bitmap->physBitmap && !TTYDRV_DC_CreateBitmap(hbitmap))
+    return 0;
+
+  if(bitmap->funcs != dc->funcs) {
+    ERR("Trying to select a non-TTY DDB into a TTY DC\n");
+    return 0;
+  }
+
+  dc->w.totalExtent.left   = 0;
+  dc->w.totalExtent.top    = 0;
+  dc->w.totalExtent.right  = bitmap->bitmap.bmWidth;
+  dc->w.totalExtent.bottom = bitmap->bitmap.bmHeight;
+
+  /* FIXME: Should be done in the common code instead */
+  if(dc->w.hVisRgn) {
+    SetRectRgn(dc->w.hVisRgn, 0, 0,
+	       bitmap->bitmap.bmWidth, bitmap->bitmap.bmHeight);
+  } else { 
+    HRGN hrgn;
+
+    if(!(hrgn = CreateRectRgn(0, 0, bitmap->bitmap.bmWidth, bitmap->bitmap.bmHeight)))
+      return 0;
+
+    dc->w.hVisRgn = hrgn;
+  }
+
+  hPreviousBitmap = dc->w.hBitmap;
+  dc->w.hBitmap = hbitmap;
+
+  return hPreviousBitmap;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_SetBitmapBits
+ */
+static LONG TTYDRV_DC_SetBitmapBits(BITMAPOBJ *bitmap, void *bits, LONG count)
+{
+  FIXME("(%p, %p, %ld): semistub\n", bitmap, bits, count);
+
+  return count;
+}
+
+/***********************************************************************
+ *		TTYDRV_BITMAP_CreateDIBSection
+ */
+HBITMAP TTYDRV_BITMAP_CreateDIBSection(
+  DC *dc, BITMAPINFO *bmi, UINT usage,
+  LPVOID *bits, HANDLE section, DWORD offset)
+{
+  FIXME("(%p, %p, %u, %p, 0x%04x, %ld): stub\n",
+	dc, bmi, usage, bits, section, offset);
+
+  return (HBITMAP) NULL;
+}
+
+/**********************************************************************
+ *		TTYDRV_BITMAP_CreateDIBSection16
+ */
+HBITMAP16 TTYDRV_DIB_CreateDIBSection16(
+  DC *dc, BITMAPINFO *bmi, UINT16 usage,
+  SEGPTR *bits, HANDLE section, DWORD offset)
+{
+  FIXME("(%p, %p, %u, %p, 0x%04x, %ld): stub\n",
+	dc, bmi, usage, bits, section, offset);
+
+  return (HBITMAP16) NULL;
+}
+
+/***********************************************************************
+ *		TTYDRV_BITMAP_DeleteDIBSection
+ */
+void TTYDRV_BITMAP_DeleteDIBSection(BITMAPOBJ *bmp)
+{
+  FIXME("(%p): stub\n", bmp);
+}
+
+/***********************************************************************
+ *		TTYDRV_BITMAP_GetDIBits
+ */
+INT TTYDRV_BITMAP_GetDIBits(
+  BITMAPOBJ *bmp, DC *dc, UINT startscan, UINT lines, 
+  LPVOID bits, BITMAPINFO *info, UINT coloruse, HBITMAP hbitmap)
+{
+  FIXME("(%p, %p, %u, %u, %p, %p, %u, 0x%04x): stub\n",
+	bmp, dc, startscan, lines, bits, info, coloruse, hbitmap);
+
+  return 0;
+}
+
+
+/***********************************************************************
+ *		TTYDRV_BITMAP_SetDIBits
+ */
+INT TTYDRV_BITMAP_SetDIBits(
+  BITMAPOBJ *bmp, DC *dc, UINT startscan, UINT lines, 
+  LPCVOID bits, const BITMAPINFO *info, UINT coloruse, HBITMAP hbitmap)
+{
+  FIXME("(%p, %p, %u, %u, %p, %p, %u, 0x%04x): stub\n",
+	bmp, dc, startscan, lines, bits, info, coloruse, hbitmap);
+
+  return 0;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_SetDIBitsToDevice
+ */
+INT TTYDRV_DC_SetDIBitsToDevice(DC *dc, INT xDest, INT yDest, DWORD cx,
+				DWORD cy, INT xSrc, INT ySrc,
+				UINT startscan, UINT lines, LPCVOID bits,
+				const BITMAPINFO *info, UINT coloruse)
+{
+  FIXME("(%p, %d, %d, %ld, %ld, %d, %d, %u, %u, %p, %p, %u): stub\n",
+	dc, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, bits, info, coloruse);
+
+  return 0;
+}
diff --git a/dlls/ttydrv/dc.c b/dlls/ttydrv/dc.c
new file mode 100644
index 0000000..0467fbb
--- /dev/null
+++ b/dlls/ttydrv/dc.c
@@ -0,0 +1,280 @@
+/*
+ * TTY DC driver
+ *
+ * Copyright 1999 Patrik Stridvall
+ */
+
+#include "config.h"
+
+#include "gdi.h"
+#include "bitmap.h"
+#include "dc.h"
+#include "palette.h"
+#include "ttydrv.h"
+#include "winbase.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(ttydrv);
+
+/**********************************************************************/
+
+static const DC_FUNCTIONS TTYDRV_DC_Driver =
+{
+  NULL,                /* pAbortDoc */
+  NULL,                /* pAbortPath */
+  NULL,                /* pAngleArc */
+  TTYDRV_DC_Arc,       /* pArc */
+  NULL,                /* pArcTo */
+  NULL,                /* pBeginPath */
+  TTYDRV_DC_BitBlt,    /* pBitBlt */
+  TTYDRV_DC_BitmapBits,/* pBitmapBits */
+  NULL,                /* pChoosePixelFormat */
+  TTYDRV_DC_Chord,     /* pChord */
+  NULL,                /* pCloseFigure */
+  TTYDRV_DC_CreateBitmap, /* pCreateBitmap */
+  TTYDRV_DC_CreateDC,  /* pCreateDC */
+  NULL,                /* pCreateDIBSection */
+  NULL,                /* pCreateDIBSection16 */
+  TTYDRV_DC_DeleteDC,  /* pDeleteDC */
+  TTYDRV_DC_DeleteObject, /* pDeleteObject */
+  NULL,                /* pDescribePixelFormat */
+  NULL,                /* pDeviceCapabilities */
+  TTYDRV_DC_Ellipse,   /* pEllipse */
+  NULL,                /* pEndDoc */
+  NULL,                /* pEndPage */
+  NULL,                /* pEndPath */
+  NULL,                /* pEnumDeviceFonts */
+  TTYDRV_DC_Escape,    /* pEscape */
+  NULL,                /* pExcludeClipRect */
+  NULL,                /* pExtDeviceMode */
+  TTYDRV_DC_ExtFloodFill, /* pExtFloodFill */
+  TTYDRV_DC_ExtTextOut, /* pExtTextOut */
+  NULL,                /* pFillPath */
+  NULL,                /* pFillRgn */
+  NULL,                /* pFlattenPath */
+  NULL,                /* pFrameRgn */
+  TTYDRV_DC_GetCharWidth, /* pGetCharWidth */
+  NULL,                /* pGetDCOrgEx */
+  TTYDRV_DC_GetPixel,  /* pGetPixel */
+  NULL,                /* pGetPixelFormat */
+  TTYDRV_DC_GetTextExtentPoint, /* pGetTextExtentPoint */
+  TTYDRV_DC_GetTextMetrics,  /* pGetTextMetrics */
+  NULL,                /* pIntersectClipRect */
+  NULL,                /* pIntersectVisRect */
+  TTYDRV_DC_LineTo,    /* pLineTo */
+  NULL,                /* pMoveToEx */
+  NULL,                /* pOffsetClipRgn */
+  NULL,                /* pOffsetViewportOrg (optional) */
+  NULL,                /* pOffsetWindowOrg (optional) */
+  TTYDRV_DC_PaintRgn,  /* pPaintRgn */
+  TTYDRV_DC_PatBlt,    /* pPatBlt */
+  TTYDRV_DC_Pie,       /* pPie */
+  NULL,                /* pPolyBezier */
+  NULL,                /* pPolyBezierTo */
+  NULL,                /* pPolyDraw */
+  TTYDRV_DC_PolyPolygon, /* pPolyPolygon */
+  TTYDRV_DC_PolyPolyline, /* pPolyPolyline */
+  TTYDRV_DC_Polygon,   /* pPolygon */
+  TTYDRV_DC_Polyline,  /* pPolyline */
+  NULL,                /* pPolylineTo */
+  NULL,                /* pRealizePalette */
+  TTYDRV_DC_Rectangle, /* pRectangle */
+  NULL,                /* pRestoreDC */
+  TTYDRV_DC_RoundRect, /* pRoundRect */
+  NULL,                /* pSaveDC */
+  NULL,                /* pScaleViewportExt (optional) */
+  NULL,                /* pScaleWindowExt (optional) */
+  NULL,                /* pSelectClipPath */
+  NULL,                /* pSelectClipRgn */
+  TTYDRV_DC_SelectObject, /* pSelectObject */
+  NULL,                /* pSelectPalette */
+  TTYDRV_DC_SetBkColor, /* pSetBkColor */
+  NULL,                /* pSetBkMode */
+  TTYDRV_DC_SetDeviceClipping, /* pSetDeviceClipping */
+  TTYDRV_DC_SetDIBitsToDevice, /* pSetDIBitsToDevice */
+  NULL,                /* pSetMapMode (optional) */
+  NULL,                /* pSetMapperFlags */
+  TTYDRV_DC_SetPixel,  /* pSetPixel */
+  NULL,                /* pSetPixelFormat */
+  NULL,                /* pSetPolyFillMode */
+  NULL,                /* pSetROP2 */
+  NULL,                /* pSetRelAbs */
+  NULL,                /* pSetStretchBltMode */
+  NULL,                /* pSetTextAlign */
+  NULL,                /* pSetTextCharacterExtra */
+  TTYDRV_DC_SetTextColor, /* pSetTextColor */
+  NULL,                /* pSetTextJustification */
+  NULL,                /* pSetViewportExt (optional) */
+  NULL,                /* pSetViewportOrg (optional) */
+  NULL,                /* pSetWindowExt (optional) */
+  NULL,                /* pSetWindowOrg (optional) */
+  NULL,                /* pStartDoc */
+  NULL,                /* pStartPage */
+  TTYDRV_DC_StretchBlt, /* pStretchBlt */
+  NULL,                /* pStretchDIBits */
+  NULL,                /* pStrokeAndFillPath */
+  NULL,                /* pStrokePath */
+  NULL,                /* pSwapBuffers */
+  NULL                 /* pWidenPath */
+};
+
+
+BITMAP_DRIVER TTYDRV_BITMAP_Driver =
+{
+  TTYDRV_BITMAP_SetDIBits,
+  TTYDRV_BITMAP_GetDIBits,
+  TTYDRV_BITMAP_DeleteDIBSection
+};
+
+PALETTE_DRIVER TTYDRV_PALETTE_Driver = 
+{
+  TTYDRV_PALETTE_SetMapping,
+  TTYDRV_PALETTE_UpdateMapping,
+  TTYDRV_PALETTE_IsDark
+};
+
+/* FIXME: Adapt to the TTY driver. Copied from the X11 driver */
+
+DeviceCaps TTYDRV_DC_DevCaps = {
+/* version */		0, 
+/* technology */	DT_RASDISPLAY,
+/* size, resolution */	0, 0, 0, 0, 0, 
+/* device objects */	1, 16 + 6, 16, 0, 0, 100, 0,	
+/* curve caps */	CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES |
+			CC_WIDE | CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT,
+/* line caps */		LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
+			LC_STYLED | LC_WIDESTYLED | LC_INTERIORS,
+/* polygon caps */	PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON |
+			PC_SCANLINE | PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS,
+/* text caps */		0,
+/* regions */		CP_REGION,
+/* raster caps */	RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 |
+			RC_DI_BITMAP | RC_DIBTODEV | RC_BIGFONT | RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS,
+/* aspects */		36, 36, 51,
+/* pad1 */		{ 0 },
+/* log pixels */	0, 0, 
+/* pad2 */		{ 0 },
+/* palette size */	0,
+/* ..etc */		0, 0
+};
+
+/**********************************************************************
+ *	     TTYDRV_GDI_Initialize
+ */
+BOOL TTYDRV_GDI_Initialize(void)
+{
+  BITMAP_Driver = &TTYDRV_BITMAP_Driver;
+  PALETTE_Driver = &TTYDRV_PALETTE_Driver;
+
+  TTYDRV_DC_DevCaps.version = 0x300;
+  TTYDRV_DC_DevCaps.horzSize = 0;    /* FIXME: Screen width in mm */
+  TTYDRV_DC_DevCaps.vertSize = 0;    /* FIXME: Screen height in mm */
+  TTYDRV_DC_DevCaps.horzRes = 640;   /* FIXME: Screen width in pixel */
+  TTYDRV_DC_DevCaps.vertRes = 480;   /* FIXME: Screen height in pixel */
+  TTYDRV_DC_DevCaps.bitsPixel = 1;   /* FIXME: Bits per pixel */
+  TTYDRV_DC_DevCaps.sizePalette = 256; /* FIXME: ??? */
+  
+  /* Resolution will be adjusted during the font init */
+  
+  TTYDRV_DC_DevCaps.logPixelsX = (int) (TTYDRV_DC_DevCaps.horzRes * 25.4 / TTYDRV_DC_DevCaps.horzSize);
+  TTYDRV_DC_DevCaps.logPixelsY = (int) (TTYDRV_DC_DevCaps.vertRes * 25.4 / TTYDRV_DC_DevCaps.vertSize);
+ 
+  if(!TTYDRV_PALETTE_Initialize())
+    return FALSE;
+
+  return DRIVER_RegisterDriver( "DISPLAY", &TTYDRV_DC_Driver );
+}
+
+/**********************************************************************
+ *	     TTYDRV_GDI_Finalize
+ */
+void TTYDRV_GDI_Finalize(void)
+{
+    TTYDRV_PALETTE_Finalize();
+}
+
+/***********************************************************************
+ *	     TTYDRV_DC_CreateDC
+ */
+BOOL TTYDRV_DC_CreateDC(DC *dc, LPCSTR driver, LPCSTR device,
+			LPCSTR output, const DEVMODEA *initData)
+{
+  TTYDRV_PDEVICE *physDev;
+  BITMAPOBJ *bmp;
+
+  TRACE("(%p, %s, %s, %s, %p)\n",
+    dc, debugstr_a(driver), debugstr_a(device), 
+    debugstr_a(output), initData);
+
+  dc->physDev = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+			  sizeof(TTYDRV_PDEVICE));  
+  if(!dc->physDev) {
+    ERR("Can't allocate physDev\n");
+    return FALSE;
+  }
+  physDev = (TTYDRV_PDEVICE *) dc->physDev;
+  
+  dc->w.devCaps = &TTYDRV_DC_DevCaps;
+
+  if(dc->w.flags & DC_MEMORY){
+    physDev->window = NULL;
+    physDev->cellWidth = 1;
+    physDev->cellHeight = 1;
+
+    TTYDRV_DC_CreateBitmap(dc->w.hBitmap);
+    bmp = (BITMAPOBJ *) GDI_GetObjPtr(dc->w.hBitmap, BITMAP_MAGIC);
+				   
+    dc->w.bitsPerPixel = bmp->bitmap.bmBitsPixel;
+    
+    dc->w.totalExtent.left   = 0;
+    dc->w.totalExtent.top    = 0;
+    dc->w.totalExtent.right  = bmp->bitmap.bmWidth;
+    dc->w.totalExtent.bottom = bmp->bitmap.bmHeight;
+    dc->w.hVisRgn            = CreateRectRgnIndirect( &dc->w.totalExtent );
+    
+    GDI_HEAP_UNLOCK( dc->w.hBitmap );
+  } else {
+    physDev->window = TTYDRV_GetRootWindow();
+    physDev->cellWidth = cell_width;
+    physDev->cellHeight = cell_height;
+    
+    dc->w.bitsPerPixel       = 1;
+    dc->w.totalExtent.left   = 0;
+    dc->w.totalExtent.top    = 0;
+    dc->w.totalExtent.right  = cell_width * screen_cols;
+    dc->w.totalExtent.bottom = cell_height * screen_rows;
+    dc->w.hVisRgn            = CreateRectRgnIndirect( &dc->w.totalExtent );    
+  }
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *	     TTYDRV_DC_DeleteDC
+ */
+BOOL TTYDRV_DC_DeleteDC(DC *dc)
+{
+  TRACE("(%p)\n", dc);
+
+  HeapFree( GetProcessHeap(), 0, dc->physDev );
+  dc->physDev = NULL;
+  
+  return TRUE;
+}
+
+/***********************************************************************
+ *           TTYDRV_DC_Escape
+ */
+INT TTYDRV_DC_Escape(DC *dc, INT nEscape, INT cbInput,
+		     SEGPTR lpInData, SEGPTR lpOutData)
+{
+  return 0;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_SetDeviceClipping
+ */
+void TTYDRV_DC_SetDeviceClipping(DC *dc)
+{
+  TRACE("(%p)\n", dc);
+}
diff --git a/dlls/ttydrv/graphics.c b/dlls/ttydrv/graphics.c
new file mode 100644
index 0000000..049bd88
--- /dev/null
+++ b/dlls/ttydrv/graphics.c
@@ -0,0 +1,470 @@
+/*
+ * TTY DC graphics
+ *
+ * Copyright 1999 Patrik Stridvall
+ */
+
+#include "config.h"
+
+#include "dc.h"
+#include "heap.h"
+#include "debugtools.h"
+#include "ttydrv.h"
+
+DEFAULT_DEBUG_CHANNEL(ttydrv);
+
+/***********************************************************************
+ *		TTYDRV_DC_Arc
+ */
+BOOL TTYDRV_DC_Arc(DC *dc, INT left, INT top, INT right, INT bottom,
+		   INT xstart, INT ystart, INT xend, INT yend)
+{
+  FIXME("(%p, %d, %d, %d, %d, %d, %d, %d, %d): stub\n",
+	dc, left, top, right, bottom, xstart, ystart, xend, yend);
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_Chord
+ */
+BOOL TTYDRV_DC_Chord(DC *dc, INT left, INT top, INT right, INT bottom,
+		     INT xstart, INT ystart, INT xend, INT yend)
+{
+  FIXME("(%p, %d, %d, %d, %d, %d, %d, %d, %d): stub\n",
+	dc, left, top, right, bottom, xstart, ystart, xend, yend);
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_Ellipse
+ */
+BOOL TTYDRV_DC_Ellipse(DC *dc, INT left, INT top, INT right, INT bottom)
+{
+  FIXME("(%p, %d, %d, %d, %d): stub\n",
+	dc, left, top, right, bottom);
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_ExtFloodFill
+ */
+BOOL TTYDRV_DC_ExtFloodFill(DC *dc, INT x, INT y,
+			    COLORREF color, UINT fillType)
+{
+  FIXME("(%p, %d, %d, 0x%08lx, %u): stub\n", dc, x, y, color, fillType);
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_GetPixel
+ */
+COLORREF TTYDRV_DC_GetPixel(DC *dc, INT x, INT y)
+{
+  FIXME("(%p, %d, %d): stub\n", dc, x, y);
+
+  return RGB(0,0,0); /* FIXME: Always returns black */
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_LineTo
+ */
+BOOL TTYDRV_DC_LineTo(DC *dc, INT x, INT y)
+{
+#ifdef WINE_CURSES
+  TTYDRV_PDEVICE *physDev = (TTYDRV_PDEVICE *) dc->physDev;
+  INT row1, col1, row2, col2;
+
+  TRACE("(%p, %d, %d)\n", dc, x, y);
+
+  if(!physDev->window)
+    return FALSE;
+
+  row1 = (dc->w.DCOrgY + XLPTODP(dc, dc->w.CursPosY)) / physDev->cellHeight;
+  col1 = (dc->w.DCOrgX + XLPTODP(dc, dc->w.CursPosX)) / physDev->cellWidth;
+  row2 = (dc->w.DCOrgY + XLPTODP(dc, y)) / physDev->cellHeight;
+  col2 = (dc->w.DCOrgX + XLPTODP(dc, x)) / physDev->cellWidth;
+
+  if(row1 > row2) {
+    INT tmp = row1;
+    row1 = row2;
+    row2 = tmp; 
+  } 
+
+  if(col1 > col2) {
+    INT tmp = col1;
+    col1 = col2;
+    col2 = tmp; 
+  } 
+
+  wmove(physDev->window, row1, col1);
+  if(col1 == col2) {
+    wvline(physDev->window, ACS_VLINE, row2-row1);
+  } else if(row1 == row2) {
+    whline(physDev->window, ACS_HLINE, col2-col1);
+  } else {
+    FIXME("Diagonal line drawing not yet supported\n");
+  }
+  wrefresh(physDev->window);
+
+  return TRUE;
+#else /* defined(WINE_CURSES) */
+  FIXME("(%p, %d, %d): stub\n", dc, x, y);
+
+  return TRUE;
+#endif /* defined(WINE_CURSES) */
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_PaintRgn
+ */
+BOOL TTYDRV_DC_PaintRgn(DC *dc, HRGN hrgn)
+{
+  FIXME("(%p, 0x%04x): stub\n", dc, hrgn);
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_Pie
+ */
+BOOL TTYDRV_DC_Pie(DC *dc, INT left, INT top, INT right, INT bottom,
+		   INT xstart, INT ystart, INT xend, INT yend)
+{
+  FIXME("(%p, %d, %d, %d, %d, %d, %d, %d, %d): stub\n",
+	dc, left, top, right, bottom, xstart, ystart, xend, yend);
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_Polygon
+ */
+BOOL TTYDRV_DC_Polygon(DC *dc, const POINT* pt, INT count)
+{
+  FIXME("(%p, %p, %d): stub\n", dc, pt, count);
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_Polyline
+ */
+BOOL TTYDRV_DC_Polyline(DC *dc, const POINT* pt, INT count)
+{
+  FIXME("(%p, %p, %d): stub\n", dc, pt, count);
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_PolyPolygon
+ */
+BOOL TTYDRV_DC_PolyPolygon(DC *dc, const POINT* pt, const INT* counts, UINT polygons)
+{
+  FIXME("(%p, %p, %p, %u): stub\n", dc, pt, counts, polygons);
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_PolyPolyline
+ */
+BOOL TTYDRV_DC_PolyPolyline(DC *dc, const POINT* pt, const DWORD* counts, DWORD polylines)
+{
+  FIXME("(%p, %p, %p, %lu): stub\n", dc, pt, counts, polylines);
+  
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_Rectangle
+ */
+BOOL TTYDRV_DC_Rectangle(DC *dc, INT left, INT top, INT right, INT bottom)
+{
+#ifdef WINE_CURSES
+  TTYDRV_PDEVICE *physDev = (TTYDRV_PDEVICE *) dc->physDev;
+  INT row1, col1, row2, col2;
+
+  TRACE("(%p, %d, %d, %d, %d)\n", dc, left, top, right, bottom);
+
+  if(!physDev->window)
+    return FALSE;
+
+  row1 = (dc->w.DCOrgY + XLPTODP(dc, top)) / physDev->cellHeight;
+  col1 = (dc->w.DCOrgX + XLPTODP(dc, left)) / physDev->cellWidth;
+  row2 = (dc->w.DCOrgY + XLPTODP(dc, bottom)) / physDev->cellHeight;
+  col2 = (dc->w.DCOrgX + XLPTODP(dc, right)) / physDev->cellWidth;
+
+  if(row1 > row2) {
+    INT tmp = row1;
+    row1 = row2;
+    row2 = tmp; 
+  } 
+  if(col1 > col2) {
+    INT tmp = col1;
+    col1 = col2;
+    col2 = tmp; 
+  } 
+
+  wmove(physDev->window, row1, col1);
+  whline(physDev->window, ACS_HLINE, col2-col1);
+
+  wmove(physDev->window, row1, col2);
+  wvline(physDev->window, ACS_VLINE, row2-row1);
+
+  wmove(physDev->window, row2, col1);
+  whline(physDev->window, ACS_HLINE, col2-col1);
+
+  wmove(physDev->window, row1, col1);
+  wvline(physDev->window, ACS_VLINE, row2-row1);
+
+  mvwaddch(physDev->window, row1, col1, ACS_ULCORNER);
+  mvwaddch(physDev->window, row1, col2, ACS_URCORNER);
+  mvwaddch(physDev->window, row2, col2, ACS_LRCORNER);
+  mvwaddch(physDev->window, row2, col1, ACS_LLCORNER);
+
+  wrefresh(physDev->window);
+
+  return TRUE;
+#else /* defined(WINE_CURSES) */
+  FIXME("(%p, %d, %d, %d, %d): stub\n", dc, left, top, right, bottom);
+
+  return TRUE;
+#endif /* defined(WINE_CURSES) */
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_RoundRect
+ */
+BOOL TTYDRV_DC_RoundRect(DC *dc, INT left, INT top, INT right,
+			 INT bottom, INT ell_width, INT ell_height)
+{
+  FIXME("(%p, %d, %d, %d, %d, %d, %d): stub\n", 
+	dc, left, top, right, bottom, ell_width, ell_height);
+  
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_SetBkColor
+ */
+COLORREF TTYDRV_DC_SetBkColor(DC *dc, COLORREF color)
+{
+  COLORREF oldColor;
+
+  TRACE("(%p, 0x%08lx)\n", dc, color);  
+
+  oldColor = dc->w.backgroundColor;
+  dc->w.backgroundColor = color;
+
+  return oldColor;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_SetPixel
+ */
+COLORREF TTYDRV_DC_SetPixel(DC *dc, INT x, INT y, COLORREF color)
+{
+#ifdef WINE_CURSES
+  TTYDRV_PDEVICE *physDev = (TTYDRV_PDEVICE *) dc->physDev;
+  INT row, col;
+
+  TRACE("(%p, %d, %d, 0x%08lx)\n", dc, x, y, color);
+
+  if(!physDev->window)
+    return FALSE;
+
+  row = (dc->w.DCOrgY + XLPTODP(dc, y)) / physDev->cellHeight;
+  col = (dc->w.DCOrgX + XLPTODP(dc, x)) / physDev->cellWidth;
+
+  mvwaddch(physDev->window, row, col, ACS_BULLET);
+  wrefresh(physDev->window);
+
+  return RGB(0,0,0); /* FIXME: Always returns black */
+#else /* defined(WINE_CURSES) */
+  FIXME("(%p, %d, %d, 0x%08lx): stub\n", dc, x, y, color);
+
+  return RGB(0,0,0); /* FIXME: Always returns black */
+#endif /* defined(WINE_CURSES) */
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_SetTextColor
+ */
+COLORREF TTYDRV_DC_SetTextColor(DC *dc, COLORREF color)
+{
+  COLORREF oldColor;
+
+  TRACE("(%p, 0x%08lx)\n", dc, color);
+  
+  oldColor = dc->w.textColor;
+  dc->w.textColor = color;
+  
+  return oldColor;
+}
+
+
+/***********************************************************************
+ *		TTYDRV_DC_BitBlt
+ */
+BOOL TTYDRV_DC_BitBlt(DC *dcDst, INT xDst, INT yDst,
+		      INT width, INT height, DC *dcSrc,
+		      INT xSrc, INT ySrc, DWORD rop)
+{
+  FIXME("(%p, %d, %d, %d, %d, %p, %d, %d, %lu): stub\n",
+	dcDst, xDst, yDst, width, height, 
+        dcSrc, xSrc, ySrc, rop
+  );
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_PatBlt
+ */
+BOOL TTYDRV_DC_PatBlt(DC *dc, INT left, INT top,
+		      INT width, INT height, DWORD rop)
+{
+  FIXME("(%p, %d, %d, %d, %d, %lu): stub\n",
+	dc, left, top, width, height, rop
+  );
+
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_StretchBlt
+ */
+BOOL TTYDRV_DC_StretchBlt(DC *dcDst, INT xDst, INT yDst,
+			  INT widthDst, INT heightDst,
+			  DC *dcSrc, INT xSrc, INT ySrc,
+			  INT widthSrc, INT heightSrc, DWORD rop)
+{
+  FIXME("(%p, %d, %d, %d, %d, %p, %d, %d, %d, %d, %lu): stub\n",
+	dcDst, xDst, yDst, widthDst, heightDst,
+	dcSrc, xSrc, ySrc, widthSrc, heightSrc, rop
+  );
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_ExtTextOut
+ */
+BOOL TTYDRV_DC_ExtTextOut(DC *dc, INT x, INT y, UINT flags,
+			  const RECT *lpRect, LPCWSTR str, UINT count,
+			  const INT *lpDx)
+{
+#ifdef WINE_CURSES
+  TTYDRV_PDEVICE *physDev = (TTYDRV_PDEVICE *) dc->physDev;
+  INT row, col;
+  LPSTR ascii;
+
+  TRACE("(%p, %d, %d, 0x%08x, %p, %s, %d, %p)\n",
+	dc, x, y, flags, lpRect, debugstr_wn(str, count), count, lpDx);
+
+  if(!physDev->window)
+    return FALSE;
+
+  /* FIXME: Is this really correct? */
+  if(dc->w.textAlign & TA_UPDATECP) {
+    x = dc->w.CursPosX;
+    y = dc->w.CursPosY;
+  }
+
+  x = XLPTODP(dc, x);
+  y = YLPTODP(dc, y);
+  
+  row = (dc->w.DCOrgY + y) / physDev->cellHeight;
+  col = (dc->w.DCOrgX + x) / physDev->cellWidth;
+  ascii = HeapAlloc( GetProcessHeap(), 0, count+1 );
+  lstrcpynWtoA(ascii, str, count+1);
+  mvwaddnstr(physDev->window, row, col, ascii, count);
+  HeapFree( GetProcessHeap(), 0, ascii );
+  wrefresh(physDev->window);
+
+  if(dc->w.textAlign & TA_UPDATECP) {
+    dc->w.CursPosX += count * physDev->cellWidth;
+    dc->w.CursPosY += physDev->cellHeight;
+  }
+
+  return TRUE;
+#else /* defined(WINE_CURSES) */
+  FIXME("(%p, %d, %d, 0x%08x, %p, %s, %d, %p): stub\n",
+	dc, x, y, flags, lpRect, debugstr_wn(str,count), count, lpDx);
+
+  return TRUE;
+#endif /* defined(WINE_CURSES) */
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_GetCharWidth
+ */
+BOOL TTYDRV_DC_GetCharWidth(DC *dc, UINT firstChar, UINT lastChar,
+			    LPINT buffer)
+{
+  UINT c;
+  TTYDRV_PDEVICE *physDev = (TTYDRV_PDEVICE *) dc->physDev;
+
+  FIXME("(%p, %u, %u, %p): semistub\n", dc, firstChar, lastChar, buffer);
+
+  for(c=firstChar; c<=lastChar; c++) {
+    buffer[c-firstChar] = physDev->cellWidth;
+  }
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_GetTextExtentPoint
+ */
+BOOL TTYDRV_DC_GetTextExtentPoint(DC *dc, LPCWSTR str, INT count,
+				  LPSIZE size)
+{
+  TTYDRV_PDEVICE *physDev = (TTYDRV_PDEVICE *) dc->physDev;
+
+  TRACE("(%p, %s, %d, %p)\n", dc, debugstr_wn(str, count), count, size);
+
+  size->cx = count * physDev->cellWidth;
+  size->cy = physDev->cellHeight;
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_GetTextMetrics
+ */
+BOOL TTYDRV_DC_GetTextMetrics(DC *dc, LPTEXTMETRICA lptm)
+{
+  TTYDRV_PDEVICE *physDev = (TTYDRV_PDEVICE *) dc->physDev;
+
+  TRACE("(%p, %p)\n", dc, lptm);
+
+  lptm->tmHeight = physDev->cellHeight;
+  lptm->tmAscent = 0;
+  lptm->tmDescent = 0;
+  lptm->tmInternalLeading = 0;
+  lptm->tmExternalLeading = 0;
+  lptm->tmAveCharWidth = physDev->cellWidth; 
+  lptm->tmMaxCharWidth = physDev->cellWidth;
+  lptm->tmWeight = FW_MEDIUM;
+  lptm->tmOverhang = 0;
+  lptm->tmDigitizedAspectX = physDev->cellWidth;
+  lptm->tmDigitizedAspectY = physDev->cellHeight;
+  lptm->tmFirstChar = 32;
+  lptm->tmLastChar = 255;
+  lptm->tmDefaultChar = 0;
+  lptm->tmBreakChar = 32;
+  lptm->tmItalic = FALSE;
+  lptm->tmUnderlined = FALSE;
+  lptm->tmStruckOut = FALSE;
+  lptm->tmPitchAndFamily = TMPF_FIXED_PITCH|TMPF_DEVICE;
+  lptm->tmCharSet = ANSI_CHARSET;
+
+  return TRUE;
+}
diff --git a/dlls/ttydrv/objects.c b/dlls/ttydrv/objects.c
new file mode 100644
index 0000000..f85dcc3
--- /dev/null
+++ b/dlls/ttydrv/objects.c
@@ -0,0 +1,135 @@
+/*
+ * TTY DC objects
+ *
+ * Copyright 1999 Patrik Stridvall
+ */
+
+#include "bitmap.h"
+#include "brush.h"
+#include "dc.h"
+#include "font.h"
+#include "gdi.h"
+#include "pen.h"
+#include "ttydrv.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(ttydrv);
+
+/**********************************************************************/
+
+extern HBITMAP TTYDRV_DC_BITMAP_SelectObject(DC *dc, HBITMAP hbitmap, BITMAPOBJ *bitmap);
+extern BOOL TTYDRV_DC_BITMAP_DeleteObject(HBITMAP hbitmap, BITMAPOBJ *bitmap);
+
+
+/***********************************************************************
+ *		TTYDRV_DC_BRUSH_SelectObject
+ */
+static HBRUSH TTYDRV_DC_BRUSH_SelectObject(DC *dc, HBRUSH hbrush, BRUSHOBJ *brush)
+{
+  HBRUSH hPreviousBrush;
+
+  TRACE("(%p, 0x%04x, %p)\n", dc, hbrush, brush);
+
+  hPreviousBrush = dc->w.hBrush;
+  dc->w.hBrush = hbrush;
+
+  return hPreviousBrush;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_FONT_SelectObject
+ */
+static HFONT TTYDRV_DC_FONT_SelectObject(DC* dc, HFONT hfont, FONTOBJ *font)
+{
+  HFONT hPreviousFont;
+
+  TRACE("(%p, 0x%04x, %p)\n", dc, hfont, font);
+
+  hPreviousFont = dc->w.hFont;
+  dc->w.hFont = hfont;
+
+  return hPreviousFont;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_PEN_SelectObject
+ */
+static HPEN TTYDRV_DC_PEN_SelectObject(DC *dc, HBRUSH hpen, PENOBJ *pen)
+{
+  HPEN hPreviousPen;
+
+  TRACE("(%p, 0x%04x, %p)\n", dc, hpen, pen);
+
+  hPreviousPen = dc->w.hPen;
+  dc->w.hPen = hpen;
+
+  return hPreviousPen;
+}
+
+/***********************************************************************
+ *		TTYDRV_DC_SelectObject
+ */
+HGDIOBJ TTYDRV_DC_SelectObject(DC *dc, HGDIOBJ handle)
+{
+  GDIOBJHDR *ptr = GDI_GetObjPtr(handle, MAGIC_DONTCARE);
+  HGDIOBJ result = 0;
+
+  if(!ptr) return 0;
+
+  switch(ptr->wMagic) 
+  {
+    case BITMAP_MAGIC:
+      result = TTYDRV_DC_BITMAP_SelectObject(dc, handle, (BITMAPOBJ *) ptr);
+      break;
+    case BRUSH_MAGIC:
+      result = TTYDRV_DC_BRUSH_SelectObject(dc, handle, (BRUSHOBJ *) ptr);
+      break;
+    case FONT_MAGIC:
+      result = TTYDRV_DC_FONT_SelectObject(dc, handle, (FONTOBJ *) ptr);	  
+      break;
+    case PEN_MAGIC:
+      result = TTYDRV_DC_PEN_SelectObject(dc, handle, (PENOBJ *) ptr);
+      break;
+    case REGION_MAGIC:
+      /* FIXME: Shouldn't be handled here */
+      result = (HGDIOBJ) SelectClipRgn(dc->hSelf, handle);
+      break;
+    default:
+      ERR("handle (0x%04x) has unknown magic (0x%04x)\n", handle, ptr->wMagic);
+  }
+
+  GDI_HEAP_UNLOCK(handle);
+    
+  return result;
+}
+
+/***********************************************************************
+ *           TTYDRV_DC_DeleteObject
+ */
+BOOL TTYDRV_DC_DeleteObject(HGDIOBJ handle)
+{
+  GDIOBJHDR *ptr = GDI_GetObjPtr(handle, MAGIC_DONTCARE);
+  BOOL result;
+  
+  if(!ptr) return FALSE;
+     
+  switch(ptr->wMagic)
+  {
+    case BITMAP_MAGIC:
+      result = TTYDRV_DC_BITMAP_DeleteObject(handle, (BITMAPOBJ *) ptr);
+      break;
+    case BRUSH_MAGIC:
+    case FONT_MAGIC:
+    case PEN_MAGIC:
+    case REGION_MAGIC:
+      result = TRUE;
+      break;
+    default:
+      ERR("handle (0x%04x) has unknown magic (0x%04x)\n", handle, ptr->wMagic);   
+      result = FALSE;
+  }
+
+  GDI_HEAP_UNLOCK(handle);
+
+  return result;
+}
diff --git a/dlls/ttydrv/palette.c b/dlls/ttydrv/palette.c
new file mode 100644
index 0000000..ec558f5
--- /dev/null
+++ b/dlls/ttydrv/palette.c
@@ -0,0 +1,114 @@
+/*
+ * TTY palette driver
+ *
+ * Copyright 1999 Patrik Stridvall
+ */
+
+#include <stdlib.h>
+
+#include "color.h"
+#include "debugtools.h"
+#include "palette.h"
+#include "winbase.h"
+#include "ttydrv.h"
+
+DEFAULT_DEBUG_CHANNEL(ttydrv);
+
+/**********************************************************************/
+
+extern DeviceCaps TTYDRV_DC_DevCaps;
+
+extern PALETTEENTRY *COLOR_sysPal;
+extern int COLOR_gapStart;
+extern int COLOR_gapEnd;
+extern int COLOR_gapFilled;
+extern int COLOR_max;
+
+extern const PALETTEENTRY COLOR_sysPalTemplate[NB_RESERVED_COLORS]; 
+
+/***********************************************************************
+ *	     TTYDRV_PALETTE_Initialize
+ */
+BOOL TTYDRV_PALETTE_Initialize(void)
+{
+  int i;
+
+  TRACE("(void)\n");
+
+  COLOR_sysPal = (PALETTEENTRY *) HeapAlloc(GetProcessHeap(), 0, sizeof(PALETTEENTRY) * TTYDRV_DC_DevCaps.sizePalette);
+  if(COLOR_sysPal == NULL) {
+    WARN("No memory to create system palette!");
+    return FALSE;
+  }
+
+  for(i=0; i < TTYDRV_DC_DevCaps.sizePalette; i++ ) {
+    const PALETTEENTRY *src;
+    PALETTEENTRY *dst = &COLOR_sysPal[i];
+
+    if(i < NB_RESERVED_COLORS/2) {
+      src = &COLOR_sysPalTemplate[i];
+    } else if(i >= TTYDRV_DC_DevCaps.sizePalette - NB_RESERVED_COLORS/2) {
+      src = &COLOR_sysPalTemplate[NB_RESERVED_COLORS + i - TTYDRV_DC_DevCaps.sizePalette];
+    } else {
+      PALETTEENTRY pe = { 0, 0, 0, 0 };
+      src = &pe;
+    }
+
+    if((src->peRed + src->peGreen + src->peBlue) <= 0xB0) {
+      dst->peRed = 0;
+      dst->peGreen = 0;  
+      dst->peBlue = 0;
+      dst->peFlags = PC_SYS_USED;
+    } else {
+      dst->peRed = 255;  
+      dst->peGreen= 255;  
+      dst->peBlue = 255;
+      dst->peFlags = PC_SYS_USED;
+    }    
+  }
+
+  COLOR_gapStart = NB_RESERVED_COLORS/2;
+  COLOR_gapEnd = NB_RESERVED_COLORS/2;
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *	     TTYDRV_PALETTE_Finalize
+ *
+ */
+void TTYDRV_PALETTE_Finalize(void)
+{
+  TRACE("(void)\n");
+}
+
+/***********************************************************************
+ *           TTYDRV_PALETTE_SetMapping
+ */
+int TTYDRV_PALETTE_SetMapping(
+  PALETTEOBJ *palPtr, UINT uStart, UINT uNum, BOOL mapOnly)
+{
+  FIXME("(%p, %u, %u, %d): stub\n", palPtr, uStart, uNum, mapOnly);
+
+  return 0;
+}
+
+/***********************************************************************
+ *           TTYDRV_PALETTE_UpdateMapping
+ */
+int TTYDRV_PALETTE_UpdateMapping(PALETTEOBJ *palPtr)
+{
+  TRACE("(%p)\n", palPtr);
+
+  return 0;
+}
+
+/***********************************************************************
+ *           TTYDRV_PALETTE_IsDark
+ */
+int TTYDRV_PALETTE_IsDark(int pixel)
+{
+  FIXME("(%d): stub\n", pixel);
+
+  return 0;
+}
diff --git a/dlls/ttydrv/ttydrv.h b/dlls/ttydrv/ttydrv.h
new file mode 100644
index 0000000..04046ff
--- /dev/null
+++ b/dlls/ttydrv/ttydrv.h
@@ -0,0 +1,160 @@
+/*
+ * TTY driver definitions
+ */
+
+#ifndef __WINE_TTYDRV_H
+#define __WINE_TTYDRV_H
+
+#include "config.h"
+
+#undef ERR
+#ifdef HAVE_NCURSES_H
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
+#endif
+
+#include "windef.h"
+#include "wingdi.h"
+#include "wine/winuser16.h"
+#include "wine/wingdi16.h"
+#include "user.h"
+
+struct tagBITMAPOBJ;
+struct tagCLASS;
+struct tagDC;
+struct tagDESKTOP;
+struct tagPALETTEOBJ;
+struct tagWND;
+struct tagCURSORICONINFO;
+struct tagCREATESTRUCTA;
+struct tagWINDOWPOS;
+struct tagKEYBOARD_CONFIG;
+struct DIDEVICEOBJECTDATA;
+
+#if defined(HAVE_LIBCURSES) || defined(HAVE_LIBNCURSES)
+#define WINE_CURSES
+#endif
+
+/**************************************************************************
+ * TTY GDI driver
+ */
+
+extern struct tagGDI_DRIVER TTYDRV_GDI_Driver;
+
+extern BOOL TTYDRV_GDI_Initialize(void);
+extern void TTYDRV_GDI_Finalize(void);
+
+/* TTY GDI bitmap driver */
+
+extern HBITMAP TTYDRV_BITMAP_CreateDIBSection(struct tagDC *dc, BITMAPINFO *bmi, UINT usage, LPVOID *bits, HANDLE section, DWORD offset);
+extern HBITMAP16 TTYDRV_BITMAP_CreateDIBSection16(struct tagDC *dc, BITMAPINFO *bmi, UINT16 usage, SEGPTR *bits, HANDLE section, DWORD offset);
+
+extern INT TTYDRV_BITMAP_SetDIBits(struct tagBITMAPOBJ *bmp, struct tagDC *dc, UINT startscan, UINT lines, LPCVOID bits, const BITMAPINFO *info, UINT coloruse, HBITMAP hbitmap);
+extern INT TTYDRV_BITMAP_GetDIBits(struct tagBITMAPOBJ *bmp, struct tagDC *dc, UINT startscan, UINT lines, LPVOID bits, BITMAPINFO *info, UINT coloruse, HBITMAP hbitmap);
+extern void TTYDRV_BITMAP_DeleteDIBSection(struct tagBITMAPOBJ *bmp);
+
+#ifndef WINE_CURSES
+typedef struct { int dummy; } WINDOW;
+#endif
+
+typedef struct {
+  WINDOW *window;
+  int cellWidth;
+  int cellHeight;
+} TTYDRV_PDEVICE;
+
+typedef struct {
+  int dummy; /* FIXME: Remove later */
+} TTYDRV_PHYSBITMAP;
+
+extern BOOL TTYDRV_DC_CreateBitmap(HBITMAP hbitmap);
+
+extern BOOL TTYDRV_DC_Arc(struct tagDC *dc, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend);
+extern LONG TTYDRV_DC_BitmapBits(HBITMAP hbitmap, void *bits, LONG count, WORD flags);
+extern BOOL TTYDRV_DC_CreateBitmap(HBITMAP hbitmap);
+extern BOOL TTYDRV_DC_CreateDC(struct tagDC *dc, LPCSTR driver, LPCSTR device, LPCSTR output, const DEVMODEA *initData);
+extern BOOL TTYDRV_DC_DeleteDC(struct tagDC *dc);
+extern BOOL TTYDRV_DC_DeleteObject(HGDIOBJ handle);
+extern BOOL TTYDRV_DC_BitBlt(struct tagDC *dcDst, INT xDst, INT yDst, INT width, INT height, struct tagDC *dcSrc, INT xSrc, INT ySrc, DWORD rop);
+extern BOOL TTYDRV_DC_Chord(struct tagDC *dc, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend);
+extern BOOL TTYDRV_DC_Ellipse(struct tagDC *dc, INT left, INT top, INT right, INT bottom);
+extern INT TTYDRV_DC_Escape(struct tagDC *dc, INT nEscape, INT cbInput, SEGPTR lpInData, SEGPTR lpOutData);
+extern BOOL TTYDRV_DC_ExtFloodFill(struct tagDC *dc, INT x, INT y, COLORREF color, UINT fillType);
+extern BOOL TTYDRV_DC_ExtTextOut(struct tagDC *dc, INT x, INT y, UINT flags, const RECT *lpRect, LPCWSTR str, UINT count, const INT *lpDx);
+extern BOOL TTYDRV_DC_GetCharWidth(struct tagDC *dc, UINT firstChar, UINT lastChar, LPINT buffer);
+extern COLORREF TTYDRV_DC_GetPixel(struct tagDC *dc, INT x, INT y);
+
+extern BOOL TTYDRV_DC_GetTextExtentPoint(struct tagDC *dc, LPCWSTR str, INT count, LPSIZE size);
+extern BOOL TTYDRV_DC_GetTextMetrics(struct tagDC *dc, TEXTMETRICA *metrics);
+extern BOOL TTYDRV_DC_LineTo(struct tagDC *dc, INT x, INT y);
+extern BOOL TTYDRV_DC_PaintRgn(struct tagDC *dc, HRGN hrgn);
+extern BOOL TTYDRV_DC_PatBlt(struct tagDC *dc, INT left, INT top, INT width, INT height, DWORD rop);
+extern BOOL TTYDRV_DC_Pie(struct tagDC *dc, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend);
+extern BOOL TTYDRV_DC_Polygon(struct tagDC *dc, const POINT* pt, INT count);
+extern BOOL TTYDRV_DC_Polyline(struct tagDC *dc, const POINT* pt, INT count);
+extern BOOL TTYDRV_DC_PolyPolygon(struct tagDC *dc, const POINT* pt, const INT* counts, UINT polygons);
+extern BOOL TTYDRV_DC_PolyPolyline(struct tagDC *dc, const POINT* pt, const DWORD* counts, DWORD polylines);
+extern BOOL TTYDRV_DC_Rectangle(struct tagDC *dc, INT left, INT top, INT right, INT bottom);
+extern BOOL TTYDRV_DC_RoundRect(struct tagDC *dc, INT left, INT top, INT right, INT bottom, INT ell_width, INT ell_height);
+extern void TTYDRV_DC_SetDeviceClipping(struct tagDC *dc);
+extern HGDIOBJ TTYDRV_DC_SelectObject(struct tagDC *dc, HGDIOBJ handle);
+extern COLORREF TTYDRV_DC_SetBkColor(struct tagDC *dc, COLORREF color);
+extern COLORREF TTYDRV_DC_SetPixel(struct tagDC *dc, INT x, INT y, COLORREF color);
+extern COLORREF TTYDRV_DC_SetTextColor(struct tagDC *dc, COLORREF color);
+extern BOOL TTYDRV_DC_StretchBlt(struct tagDC *dcDst, INT xDst, INT yDst, INT widthDst, INT heightDst, struct tagDC *dcSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, DWORD rop);
+INT TTYDRV_DC_SetDIBitsToDevice(struct tagDC *dc, INT xDest, INT yDest, DWORD cx, DWORD cy, INT xSrc, INT ySrc, UINT startscan, UINT lines, LPCVOID bits, const BITMAPINFO *info, UINT coloruse);
+
+/* TTY GDI palette driver */
+
+extern struct tagPALETTE_DRIVER TTYDRV_PALETTE_Driver;
+
+extern BOOL TTYDRV_PALETTE_Initialize(void);
+extern void TTYDRV_PALETTE_Finalize(void);
+
+extern int TTYDRV_PALETTE_SetMapping(struct tagPALETTEOBJ *palPtr, UINT uStart, UINT uNum, BOOL mapOnly);
+extern int TTYDRV_PALETTE_UpdateMapping(struct tagPALETTEOBJ *palPtr);
+extern BOOL TTYDRV_PALETTE_IsDark(int pixel);
+
+/**************************************************************************
+ * TTY USER driver
+ */
+
+extern int cell_width;
+extern int cell_height;
+extern int screen_rows;
+extern int screen_cols;
+extern WINDOW *root_window;
+static inline WINDOW *TTYDRV_GetRootWindow(void) { return root_window; }
+
+/* TTY windows driver */
+
+extern struct tagWND_DRIVER TTYDRV_WND_Driver;
+
+typedef struct tagTTYDRV_WND_DATA {
+  WINDOW *window;
+} TTYDRV_WND_DATA;
+
+WINDOW *TTYDRV_WND_GetCursesWindow(struct tagWND *wndPtr);
+
+extern HANDLE TTYDRV_LoadOEMResource(WORD resid, WORD type);
+
+extern void TTYDRV_WND_Initialize(struct tagWND *wndPtr);
+extern void TTYDRV_WND_Finalize(struct tagWND *wndPtr);
+extern BOOL TTYDRV_WND_CreateDesktopWindow(struct tagWND *wndPtr, struct tagCLASS *classPtr, BOOL bUnicode);
+extern BOOL TTYDRV_WND_CreateWindow(struct tagWND *wndPtr, struct tagCLASS *classPtr, struct tagCREATESTRUCTA *cs, BOOL bUnicode);
+extern BOOL TTYDRV_WND_DestroyWindow(struct tagWND *pWnd);
+extern struct tagWND *TTYDRV_WND_SetParent(struct tagWND *wndPtr, struct tagWND *pWndParent);
+extern void TTYDRV_WND_ForceWindowRaise(struct tagWND *pWnd);
+extern void TTYDRV_WND_SetWindowPos(struct tagWND *wndPtr, const struct tagWINDOWPOS *winpos, BOOL bSMC_SETXPOS);
+extern void TTYDRV_WND_SetText(struct tagWND *wndPtr, LPCWSTR text);
+extern void TTYDRV_WND_SetFocus(struct tagWND *wndPtr);
+extern void TTYDRV_WND_PreSizeMove(struct tagWND *wndPtr);
+extern void TTYDRV_WND_PostSizeMove(struct tagWND *wndPtr);
+extern void TTYDRV_WND_ScrollWindow(struct tagWND *wndPtr, HDC hdc, INT dx, INT dy, const RECT *clipRect, BOOL bUpdate);
+extern void TTYDRV_WND_SetDrawable(struct tagWND *wndPtr, HDC hdc, WORD flags, BOOL bSetClipOrigin);
+extern BOOL TTYDRV_WND_SetHostAttr(struct tagWND *wndPtr, INT haKey, INT value);
+extern BOOL TTYDRV_WND_IsSelfClipping(struct tagWND *wndPtr);
+extern void TTYDRV_WND_SetWindowRgn(struct tagWND *wndPtr, HRGN hrgnWnd);
+
+#endif /* !defined(__WINE_TTYDRV_H) */
diff --git a/dlls/ttydrv/ttydrv.spec b/dlls/ttydrv/ttydrv.spec
index 1ae7142..fae6f66 100644
--- a/dlls/ttydrv/ttydrv.spec
+++ b/dlls/ttydrv/ttydrv.spec
@@ -5,3 +5,38 @@
 import	user32.dll
 import	gdi32.dll
 import	kernel32.dll
+
+# USER driver
+
+@ cdecl Synchronize() TTYDRV_Synchronize
+@ cdecl CheckFocus() TTYDRV_CheckFocus
+@ cdecl UserRepaintDisable(long) TTYDRV_UserRepaintDisable
+@ cdecl InitKeyboard() TTYDRV_InitKeyboard
+@ cdecl VkKeyScan(long) TTYDRV_VkKeyScan
+@ cdecl MapVirtualKey(long long) TTYDRV_MapVirtualKey
+@ cdecl GetKeyNameText(long str long) TTYDRV_GetKeyNameText
+@ cdecl ToAscii(long long ptr ptr long) TTYDRV_ToAscii
+@ cdecl GetBeepActive() TTYDRV_GetBeepActive
+@ cdecl SetBeepActive(long) TTYDRV_SetBeepActive
+@ cdecl Beep() TTYDRV_Beep
+@ cdecl GetDIState(long ptr) TTYDRV_GetDIState
+@ cdecl GetDIData(ptr long ptr ptr long) TTYDRV_GetDIData
+@ cdecl GetKeyboardConfig(ptr) TTYDRV_GetKeyboardConfig
+@ cdecl SetKeyboardConfig(ptr long) TTYDRV_SetKeyboardConfig
+@ cdecl InitMouse(ptr) TTYDRV_InitMouse
+@ cdecl SetCursor(ptr) TTYDRV_SetCursor
+@ cdecl MoveCursor(long long) TTYDRV_MoveCursor
+@ cdecl GetScreenSaveActive() TTYDRV_GetScreenSaveActive
+@ cdecl SetScreenSaveActive(long) TTYDRV_SetScreenSaveActive
+@ cdecl GetScreenSaveTimeout() TTYDRV_GetScreenSaveTimeout
+@ cdecl SetScreenSaveTimeout(long) TTYDRV_SetScreenSaveTimeout
+@ cdecl LoadOEMResource(long long) TTYDRV_LoadOEMResource
+@ cdecl IsSingleWindow() TTYDRV_IsSingleWindow
+@ cdecl AcquireClipboard() TTYDRV_AcquireClipboard
+@ cdecl ReleaseClipboard() TTYDRV_ReleaseClipboard
+@ cdecl SetClipboardData(long) TTYDRV_SetClipboardData
+@ cdecl GetClipboardData(long) TTYDRV_GetClipboardData
+@ cdecl IsClipboardFormatAvailable(long) TTYDRV_IsClipboardFormatAvailable
+@ cdecl RegisterClipboardFormat(str) TTYDRV_RegisterClipboardFormat
+@ cdecl IsSelectionOwner() TTYDRV_IsSelectionOwner
+@ cdecl ResetSelectionOwner(ptr long) TTYDRV_ResetSelectionOwner
diff --git a/dlls/ttydrv/ttydrv_main.c b/dlls/ttydrv/ttydrv_main.c
index 7b3b6ff..67ed429 100644
--- a/dlls/ttydrv/ttydrv_main.c
+++ b/dlls/ttydrv/ttydrv_main.c
@@ -8,7 +8,6 @@
 
 #include "winbase.h"
 #include "wine/winbase16.h"
-#include "clipboard.h"
 #include "gdi.h"
 #include "message.h"
 #include "user.h"
@@ -18,40 +17,6 @@
 
 DEFAULT_DEBUG_CHANNEL(ttydrv);
 
-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,
-    /* screen saver functions */
-    TTYDRV_GetScreenSaveActive,
-    TTYDRV_SetScreenSaveActive,
-    TTYDRV_GetScreenSaveTimeout,
-    TTYDRV_SetScreenSaveTimeout,
-    /* resource functions */
-    TTYDRV_LoadOEMResource,
-    /* windowing functions */
-    TTYDRV_IsSingleWindow
-};
-
 int cell_width = 8;
 int cell_height = 8;
 int screen_rows = 50;  /* default value */
@@ -64,8 +29,6 @@
  */
 static void process_attach(void)
 {
-    USER_Driver      = &user_driver;
-    CLIPBOARD_Driver = &TTYDRV_CLIPBOARD_Driver;
     WND_Driver       = &TTYDRV_WND_Driver;
 
 #ifdef WINE_CURSES
@@ -95,8 +58,6 @@
     if (root_window) endwin();
 #endif  /* WINE_CURSES */
 
-    USER_Driver      = NULL;
-    CLIPBOARD_Driver = NULL;
     WND_Driver       = NULL;
 }
 
@@ -120,52 +81,3 @@
     }
     return TRUE;
 }
-
-
-/***********************************************************************
- *              TTYDRV_GetScreenSaveActive
- *
- * Returns the active status of the screen saver
- */
-BOOL TTYDRV_GetScreenSaveActive(void)
-{
-    return FALSE;
-}
-
-/***********************************************************************
- *              TTYDRV_SetScreenSaveActive
- *
- * Activate/Deactivate the screen saver
- */
-void TTYDRV_SetScreenSaveActive(BOOL bActivate)
-{
-    FIXME("(%d): stub\n", bActivate);
-}
-
-/***********************************************************************
- *              TTYDRV_GetScreenSaveTimeout
- *
- * Return the screen saver timeout
- */
-int TTYDRV_GetScreenSaveTimeout(void)
-{
-    return 0;
-}
-
-/***********************************************************************
- *              TTYDRV_SetScreenSaveTimeout
- *
- * Set the screen saver timeout
- */
-void TTYDRV_SetScreenSaveTimeout(int nTimeout)
-{
-    FIXME("(%d): stub\n", nTimeout);
-}
-
-/***********************************************************************
- *              TTYDRV_IsSingleWindow
- */
-BOOL TTYDRV_IsSingleWindow(void)
-{
-    return TRUE;
-}
diff --git a/dlls/ttydrv/user.c b/dlls/ttydrv/user.c
new file mode 100644
index 0000000..90b17f0
--- /dev/null
+++ b/dlls/ttydrv/user.c
@@ -0,0 +1,287 @@
+/*
+ * TTYDRV USER driver functions
+ *
+ * Copyright 1998 Patrik Stridvall
+ */
+
+#include "dinput.h"
+#include "gdi.h"
+#include "ttydrv.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(ttydrv);
+
+/***********************************************************************
+ *		TTYDRV_Synchronize
+ */
+void TTYDRV_Synchronize( void )
+{
+}
+
+/***********************************************************************
+ *		TTYDRV_CheckFocus
+ */
+BOOL TTYDRV_CheckFocus(void)
+{
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_UserRepaintDisable
+ */
+void TTYDRV_UserRepaintDisable( BOOL bDisable )
+{
+}
+
+
+/***********************************************************************
+ *		TTYDRV_InitKeyboard
+ */
+void TTYDRV_InitKeyboard(void)
+{
+}
+
+/***********************************************************************
+ *		TTYDRV_VkKeyScan
+ */
+WORD TTYDRV_VkKeyScan(CHAR cChar)
+{
+  return 0;
+}
+
+/***********************************************************************
+ *		TTYDRV_MapVirtualKey
+ */
+UINT16 TTYDRV_MapVirtualKey(UINT16 wCode, UINT16 wMapType)
+{
+  return 0;
+}
+
+/***********************************************************************
+ *		TTYDRV_GetKeyNameText
+ */
+INT16 TTYDRV_GetKeyNameText( LONG lParam, LPSTR lpBuffer, INT16 nSize )
+{  
+  if(lpBuffer && nSize)
+    {
+      *lpBuffer = 0;
+    }
+  return 0;
+}
+
+/***********************************************************************
+ *		TTYDRV_ToAscii
+ */
+INT16 TTYDRV_ToAscii( UINT16 virtKey, UINT16 scanCode,
+                      LPBYTE lpKeyState, LPVOID lpChar, UINT16 flags )
+{
+  return 0;
+}
+
+/***********************************************************************
+ *		TTYDRV_GetBeepActive
+ */
+BOOL TTYDRV_GetBeepActive(void)
+{
+  return FALSE;
+}
+
+/***********************************************************************
+ *		TTYDRV_SetBeepActive
+ */
+void TTYDRV_SetBeepActive(BOOL bActivate)
+{
+}
+
+/***********************************************************************
+ *		TTYDRV_Beep
+ */
+void TTYDRV_Beep(void)
+{
+}
+
+/***********************************************************************
+ *		TTYDRV_GetDIState
+ */
+BOOL TTYDRV_GetDIState(DWORD len, LPVOID ptr)
+{
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_GetDIData
+ */
+BOOL TTYDRV_GetDIData( BYTE *keystate, DWORD dodsize, LPDIDEVICEOBJECTDATA dod,
+                       LPDWORD entries, DWORD flags )
+{
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_GetKeyboardConfig
+ */
+void TTYDRV_GetKeyboardConfig(KEYBOARD_CONFIG *cfg)
+{
+}
+
+/***********************************************************************
+ *		TTYDRV_SetKeyboardConfig
+ */
+extern void TTYDRV_SetKeyboardConfig(KEYBOARD_CONFIG *cfg, DWORD mask)
+{
+}
+
+/***********************************************************************
+ *           TTYDRV_InitMouse
+ */
+void TTYDRV_InitMouse(LPMOUSE_EVENT_PROC proc)
+{
+}
+
+/***********************************************************************
+ *		TTYDRV_SetCursor
+ */
+void TTYDRV_SetCursor( struct tagCURSORICONINFO *lpCursor )
+{
+}
+
+/***********************************************************************
+ *		TTYDRV_MoveCursor
+ */
+void TTYDRV_MoveCursor(WORD wAbsX, WORD wAbsY)
+{
+}
+
+/***********************************************************************
+ *              TTYDRV_GetScreenSaveActive
+ *
+ * Returns the active status of the screen saver
+ */
+BOOL TTYDRV_GetScreenSaveActive(void)
+{
+    return FALSE;
+}
+
+/***********************************************************************
+ *              TTYDRV_SetScreenSaveActive
+ *
+ * Activate/Deactivate the screen saver
+ */
+void TTYDRV_SetScreenSaveActive(BOOL bActivate)
+{
+    FIXME("(%d): stub\n", bActivate);
+}
+
+/***********************************************************************
+ *              TTYDRV_GetScreenSaveTimeout
+ *
+ * Return the screen saver timeout
+ */
+int TTYDRV_GetScreenSaveTimeout(void)
+{
+    return 0;
+}
+
+/***********************************************************************
+ *              TTYDRV_SetScreenSaveTimeout
+ *
+ * Set the screen saver timeout
+ */
+void TTYDRV_SetScreenSaveTimeout(int nTimeout)
+{
+    FIXME("(%d): stub\n", nTimeout);
+}
+
+/**********************************************************************
+ *		TTYDRV_LoadOEMResource
+ */
+HANDLE TTYDRV_LoadOEMResource(WORD resid, WORD type)
+{
+  HBITMAP hbitmap;
+  switch(type)
+  {
+    case OEM_BITMAP:
+        hbitmap = CreateBitmap(1, 1, 1, 1, NULL);
+        TTYDRV_DC_CreateBitmap(hbitmap);
+        return hbitmap;
+    case OEM_CURSOR:
+    case OEM_ICON:
+        break;
+    default:
+      ERR("unknown type (%d)\n", type);
+  }
+  return 0;
+}
+
+/***********************************************************************
+ *              TTYDRV_IsSingleWindow
+ */
+BOOL TTYDRV_IsSingleWindow(void)
+{
+    return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_AcquireClipboard
+ */
+void TTYDRV_AcquireClipboard(void)
+{
+}
+
+/***********************************************************************
+ *		TTYDRV_ReleaseClipboard
+ */
+void TTYDRV_ReleaseClipboard(void)
+{
+}
+
+/***********************************************************************
+ *		TTYDRV_SetClipboardData
+ */
+void TTYDRV_SetClipboardData(UINT wFormat)
+{
+}
+
+/***********************************************************************
+ *		TTYDRV_GetClipboardData
+ */
+BOOL TTYDRV_GetClipboardData(UINT wFormat)
+{
+  return FALSE;
+}
+
+/***********************************************************************
+ *		TTYDRV_IsClipboardFormatAvailable
+ */
+BOOL TTYDRV_IsClipboardFormatAvailable(UINT wFormat)
+{
+  return FALSE;
+}
+
+/**************************************************************************
+ *		TTYDRV_RegisterClipboardFormat
+ *
+ * Registers a custom clipboard format
+ * Returns: TRUE - new format registered, FALSE - Format already registered
+ */
+BOOL TTYDRV_RegisterClipboardFormat( LPCSTR FormatName )
+{
+  return TRUE;
+}
+
+/**************************************************************************
+ *		TTYDRV_IsSelectionOwner
+ *
+ * Returns: TRUE - We(WINE) own the selection, FALSE - Selection not owned by us
+ */
+BOOL TTYDRV_IsSelectionOwner(void)
+{
+    return FALSE;
+}
+
+/***********************************************************************
+ *		TTYDRV_ResetSelectionOwner
+ */
+void TTYDRV_ResetSelectionOwner(struct tagWND *pWnd, BOOL bFooBar)
+{
+}
diff --git a/dlls/ttydrv/wnd.c b/dlls/ttydrv/wnd.c
new file mode 100644
index 0000000..a3acb7e
--- /dev/null
+++ b/dlls/ttydrv/wnd.c
@@ -0,0 +1,275 @@
+/*
+ * TTY window driver
+ *
+ * Copyright 1998,1999 Patrik Stridvall
+ */
+
+#include "config.h"
+
+#include "class.h"
+#include "dc.h"
+#include "heap.h"
+#include "ttydrv.h"
+#include "win.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(ttydrv);
+
+WND_DRIVER TTYDRV_WND_Driver =
+{
+  TTYDRV_WND_Initialize,
+  TTYDRV_WND_Finalize,
+  TTYDRV_WND_CreateDesktopWindow,
+  TTYDRV_WND_CreateWindow,
+  TTYDRV_WND_DestroyWindow,
+  TTYDRV_WND_SetParent,
+  TTYDRV_WND_ForceWindowRaise,
+  TTYDRV_WND_SetWindowPos,
+  TTYDRV_WND_SetText,
+  TTYDRV_WND_SetFocus,
+  TTYDRV_WND_PreSizeMove,
+  TTYDRV_WND_PostSizeMove,
+  TTYDRV_WND_ScrollWindow,
+  TTYDRV_WND_SetDrawable,
+  TTYDRV_WND_SetHostAttr,
+  TTYDRV_WND_IsSelfClipping,
+  TTYDRV_WND_SetWindowRgn
+};
+
+
+/***********************************************************************
+ *		TTYDRV_WND_GetCursesWindow
+ *
+ * Return the Curses window associated to a window.
+ */
+WINDOW *TTYDRV_WND_GetCursesWindow(WND *wndPtr)
+{
+    return wndPtr && wndPtr->pDriverData ? 
+      ((TTYDRV_WND_DATA *) wndPtr->pDriverData)->window : 0;
+}
+
+/**********************************************************************
+ *		TTYDRV_WND_Initialize
+ */
+void TTYDRV_WND_Initialize(WND *wndPtr)
+{
+  TTYDRV_WND_DATA *pWndDriverData = 
+    (TTYDRV_WND_DATA *) HeapAlloc(SystemHeap, 0, sizeof(TTYDRV_WND_DATA));
+
+  TRACE("(%p)\n", wndPtr);
+
+  wndPtr->pDriverData = (void *) pWndDriverData;
+
+  pWndDriverData->window = NULL;
+}
+
+/**********************************************************************
+ *		TTYDRV_WND_Finalize
+ */
+void TTYDRV_WND_Finalize(WND *wndPtr)
+{
+  TTYDRV_WND_DATA *pWndDriverData =
+    (TTYDRV_WND_DATA *) wndPtr->pDriverData;
+
+  TRACE("(%p)\n", wndPtr);
+
+  if(!pWndDriverData) {
+    ERR("WND already destroyed\n");
+    return;
+  }
+
+  if(pWndDriverData->window) {
+    ERR("WND destroyed without destroying the associated Curses Windows");
+  }
+
+  HeapFree(SystemHeap, 0, pWndDriverData);
+  wndPtr->pDriverData = NULL;
+}
+
+/**********************************************************************
+ *		TTYDRV_WND_CreateDesktopWindow
+ */
+BOOL TTYDRV_WND_CreateDesktopWindow(WND *wndPtr, CLASS *classPtr, BOOL bUnicode)
+{
+  TTYDRV_WND_DATA *pWndDriverData =
+    (TTYDRV_WND_DATA *) wndPtr->pDriverData;
+
+  TRACE("(%p, %p, %d)\n", wndPtr, classPtr, bUnicode);
+
+  if(!pWndDriverData) { ERR("WND never initialized\n"); return FALSE; }
+
+  pWndDriverData->window = TTYDRV_GetRootWindow();
+  return TRUE;
+}
+
+/**********************************************************************
+ *		TTYDRV_WND_CreateWindow
+ */
+BOOL TTYDRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BOOL bUnicode)
+{
+#ifdef WINE_CURSES
+  WINDOW *window;
+  INT cellWidth=8, cellHeight=8; /* FIXME: Hardcoded */
+
+  TRACE("(%p, %p, %p, %d)\n", wndPtr, classPtr, cs, bUnicode);
+
+  /* Only create top-level windows */
+  if(cs->style & WS_CHILD)
+    return TRUE;
+
+  window = subwin(TTYDRV_GetRootWindow(), cs->cy/cellHeight, cs->cx/cellWidth,
+		  cs->y/cellHeight, cs->x/cellWidth);
+  werase(window);
+  wrefresh(window);
+		  
+  return TRUE;
+#else /* defined(WINE_CURSES) */
+  FIXME("(%p, %p, %p, %d): stub\n", wndPtr, classPtr, cs, bUnicode);
+
+  return TRUE;
+#endif /* defined(WINE_CURSES) */
+}
+
+/***********************************************************************
+ *		TTYDRV_WND_DestroyWindow
+ */
+BOOL TTYDRV_WND_DestroyWindow(WND *wndPtr)
+{
+#ifdef WINE_CURSES
+  WINDOW *window;
+
+  TRACE("(%p)\n", wndPtr);
+
+  window = TTYDRV_WND_GetCursesWindow(wndPtr);
+  if(window && window != TTYDRV_GetRootWindow()) {
+    delwin(window);
+  }
+
+  return TRUE;
+#else /* defined(WINE_CURSES) */
+  FIXME("(%p): stub\n", wndPtr);
+
+  return TRUE;
+#endif /* defined(WINE_CURSES) */
+}
+
+/*****************************************************************
+ *		TTYDRV_WND_SetParent
+ */
+WND *TTYDRV_WND_SetParent(WND *wndPtr, WND *pWndParent)
+{
+  FIXME("(%p, %p): stub\n", wndPtr, pWndParent);
+
+  return NULL;
+}
+
+/***********************************************************************
+ *		TTYDRV_WND_ForceWindowRaise
+ */
+void TTYDRV_WND_ForceWindowRaise(WND *wndPtr)
+{
+  FIXME("(%p): stub\n", wndPtr);
+}
+
+/***********************************************************************
+ *           TTYDRV_WINPOS_SetWindowPos
+ */
+void TTYDRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS *winpos, BOOL bSMC_SETXPOS)
+{
+  FIXME("(%p, %p, %d): stub\n", wndPtr, winpos, bSMC_SETXPOS);
+}
+
+/*****************************************************************
+ *		TTYDRV_WND_SetText
+ */
+void TTYDRV_WND_SetText(WND *wndPtr, LPCWSTR text)
+{
+  FIXME("(%p, %s): stub\n", wndPtr, debugstr_w(text));
+}
+
+/*****************************************************************
+ *		TTYDRV_WND_SetFocus
+ */
+void TTYDRV_WND_SetFocus(WND *wndPtr)
+{
+  FIXME("(%p): stub\n", wndPtr);
+}
+
+/*****************************************************************
+ *		TTYDRV_WND_PreSizeMove
+ */
+void TTYDRV_WND_PreSizeMove(WND *wndPtr)
+{
+  FIXME("(%p): stub\n", wndPtr);
+}
+
+/*****************************************************************
+ *		 TTYDRV_WND_PostSizeMove
+ */
+void TTYDRV_WND_PostSizeMove(WND *wndPtr)
+{
+  FIXME("(%p): stub\n", wndPtr);
+}
+
+/*****************************************************************
+ *		 TTYDRV_WND_ScrollWindow
+ */
+void TTYDRV_WND_ScrollWindow( WND *wndPtr, HDC hdc, INT dx, INT dy, 
+                              const RECT *clipRect, BOOL bUpdate)
+{
+  FIXME("(%p, %x, %d, %d, %p, %d): stub\n", 
+	wndPtr, hdc, dx, dy, clipRect, bUpdate);
+}
+
+/***********************************************************************
+ *		TTYDRV_WND_SetDrawable
+ */
+void TTYDRV_WND_SetDrawable(WND *wndPtr, HDC hdc, WORD flags, BOOL bSetClipOrigin)
+{
+    DC *dc = DC_GetDCPtr( hdc );
+    if (!dc) return;
+    TRACE("(%p, %p, %d, %d)\n", wndPtr, dc, flags, bSetClipOrigin);
+
+  /* FIXME: Should be done in the common code instead */
+  if(!wndPtr)  {
+    dc->w.DCOrgX = 0;
+    dc->w.DCOrgY = 0;
+  } else {
+    if(flags & DCX_WINDOW) {
+      dc->w.DCOrgX = wndPtr->rectWindow.left;
+      dc->w.DCOrgY = wndPtr->rectWindow.top;
+    } else {
+      dc->w.DCOrgX = wndPtr->rectClient.left;
+      dc->w.DCOrgY = wndPtr->rectClient.top;
+    }
+  }
+  GDI_HEAP_UNLOCK( hdc );
+}
+
+/***********************************************************************
+ *              TTYDRV_WND_SetHostAttr
+ */
+BOOL TTYDRV_WND_SetHostAttr(WND *wndPtr, INT attr, INT value)
+{
+  FIXME("(%p): stub\n", wndPtr);
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *		TTYDRV_WND_IsSelfClipping
+ */
+BOOL TTYDRV_WND_IsSelfClipping(WND *wndPtr)
+{
+  FIXME("(%p): semistub\n", wndPtr);
+
+  return FALSE;
+}
+
+/***********************************************************************
+ *		TTYDRV_WND_SetWindowRgn
+ */
+void TTYDRV_WND_SetWindowRgn(struct tagWND *wndPtr, HRGN hrgnWnd)
+{
+}
+
diff --git a/dlls/user/display.c b/dlls/user/display.c
index 5eb9ad7..822174a 100644
--- a/dlls/user/display.c
+++ b/dlls/user/display.c
@@ -36,7 +36,7 @@
  */
 VOID WINAPI DISPLAY_SetCursor( struct tagCURSORICONINFO *lpCursor )
 {
-    USER_Driver->pSetCursor(lpCursor);
+    USER_Driver.pSetCursor(lpCursor);
 }
 
 /***********************************************************************
@@ -44,7 +44,7 @@
  */
 VOID WINAPI DISPLAY_MoveCursor( WORD wAbsX, WORD wAbsY )
 {
-    USER_Driver->pMoveCursor(wAbsX, wAbsY);
+    USER_Driver.pMoveCursor(wAbsX, wAbsY);
 }
 
 /***********************************************************************
@@ -76,6 +76,6 @@
  */
 VOID WINAPI UserRepaintDisable16( BOOL16 disable )
 {
-    USER_Driver->pUserRepaintDisable( disable );
+    USER_Driver.pUserRepaintDisable( disable );
 }
 
diff --git a/dlls/user/mouse.c b/dlls/user/mouse.c
index a74a8a3..1d8371d 100644
--- a/dlls/user/mouse.c
+++ b/dlls/user/mouse.c
@@ -63,7 +63,7 @@
 {
     THUNK_Free( (FARPROC)DefMouseEventProc );
     DefMouseEventProc = lpMouseEventProc;
-    USER_Driver->pInitMouse( lpMouseEventProc );
+    USER_Driver.pInitMouse( lpMouseEventProc );
 }
 
 static VOID WINAPI MOUSE_CallMouseEventProc( FARPROC16 proc,
@@ -100,5 +100,5 @@
 {
     THUNK_Free( (FARPROC)DefMouseEventProc );
     DefMouseEventProc = 0;
-    USER_Driver->pInitMouse( 0 );
+    USER_Driver.pInitMouse( 0 );
 }
diff --git a/dlls/user/user_main.c b/dlls/user/user_main.c
index f64a202..3d717ee 100644
--- a/dlls/user/user_main.c
+++ b/dlls/user/user_main.c
@@ -22,6 +22,15 @@
 #include "win.h"
 #include "debugtools.h"
 
+DEFAULT_DEBUG_CHANNEL(graphics);
+
+USER_DRIVER USER_Driver;
+
+static HMODULE graphics_driver;
+
+#define GET_USER_FUNC(name) \
+   if (!(USER_Driver.p##name = (void*)GetProcAddress( graphics_driver, #name ))) \
+      FIXME("%s not found in graphics driver\n", #name)
 
 /* load the graphics driver */
 static BOOL load_driver(void)
@@ -41,11 +50,45 @@
         strcpy( buffer, "x11drv" );  /* default value */
     RegCloseKey( hkey );
 
-    if (!LoadLibraryA( buffer ))
+    if (!(graphics_driver = LoadLibraryA( buffer )))
     {
         MESSAGE( "Could not load graphics driver '%s'\n", buffer );
         return FALSE;
     }
+
+    GET_USER_FUNC(Synchronize);
+    GET_USER_FUNC(CheckFocus);
+    GET_USER_FUNC(UserRepaintDisable);
+    GET_USER_FUNC(InitKeyboard);
+    GET_USER_FUNC(VkKeyScan);
+    GET_USER_FUNC(MapVirtualKey);
+    GET_USER_FUNC(GetKeyNameText);
+    GET_USER_FUNC(ToAscii);
+    GET_USER_FUNC(GetBeepActive);
+    GET_USER_FUNC(SetBeepActive);
+    GET_USER_FUNC(Beep);
+    GET_USER_FUNC(GetDIState);
+    GET_USER_FUNC(GetDIData);
+    GET_USER_FUNC(GetKeyboardConfig);
+    GET_USER_FUNC(SetKeyboardConfig);
+    GET_USER_FUNC(InitMouse);
+    GET_USER_FUNC(SetCursor);
+    GET_USER_FUNC(MoveCursor);
+    GET_USER_FUNC(GetScreenSaveActive);
+    GET_USER_FUNC(SetScreenSaveActive);
+    GET_USER_FUNC(GetScreenSaveTimeout);
+    GET_USER_FUNC(SetScreenSaveTimeout);
+    GET_USER_FUNC(LoadOEMResource);
+    GET_USER_FUNC(IsSingleWindow);
+    GET_USER_FUNC(AcquireClipboard);
+    GET_USER_FUNC(ReleaseClipboard);
+    GET_USER_FUNC(SetClipboardData);
+    GET_USER_FUNC(GetClipboardData);
+    GET_USER_FUNC(IsClipboardFormatAvailable);
+    GET_USER_FUNC(RegisterClipboardFormat);
+    GET_USER_FUNC(IsSelectionOwner);
+    GET_USER_FUNC(ResetSelectionOwner);
+
     return TRUE;
 }
 
@@ -115,7 +158,7 @@
     MOUSE_Enable( mouse_event );
 
     /* Start processing X events */
-    USER_Driver->pUserRepaintDisable( FALSE );
+    USER_Driver.pUserRepaintDisable( FALSE );
 
     return TRUE;
 }
diff --git a/dlls/x11drv/x11drv.spec b/dlls/x11drv/x11drv.spec
index 9fb6d95..535ff47 100644
--- a/dlls/x11drv/x11drv.spec
+++ b/dlls/x11drv/x11drv.spec
@@ -5,3 +5,38 @@
 import	user32.dll
 import	gdi32.dll
 import	kernel32.dll
+
+# USER driver
+
+@ cdecl Synchronize() X11DRV_Synchronize
+@ cdecl CheckFocus() X11DRV_CheckFocus
+@ cdecl UserRepaintDisable(long) X11DRV_UserRepaintDisable
+@ cdecl InitKeyboard() X11DRV_InitKeyboard
+@ cdecl VkKeyScan(long) X11DRV_VkKeyScan
+@ cdecl MapVirtualKey(long long) X11DRV_MapVirtualKey
+@ cdecl GetKeyNameText(long str long) X11DRV_GetKeyNameText
+@ cdecl ToAscii(long long ptr ptr long) X11DRV_ToAscii
+@ cdecl GetBeepActive() X11DRV_GetBeepActive
+@ cdecl SetBeepActive(long) X11DRV_SetBeepActive
+@ cdecl Beep() X11DRV_Beep
+@ cdecl GetDIState(long ptr) X11DRV_GetDIState
+@ cdecl GetDIData(ptr long ptr ptr long) X11DRV_GetDIData
+@ cdecl GetKeyboardConfig(ptr) X11DRV_GetKeyboardConfig
+@ cdecl SetKeyboardConfig(ptr long) X11DRV_SetKeyboardConfig
+@ cdecl InitMouse(ptr) X11DRV_InitMouse
+@ cdecl SetCursor(ptr) X11DRV_SetCursor
+@ cdecl MoveCursor(long long) X11DRV_MoveCursor
+@ cdecl GetScreenSaveActive() X11DRV_GetScreenSaveActive
+@ cdecl SetScreenSaveActive(long) X11DRV_SetScreenSaveActive
+@ cdecl GetScreenSaveTimeout() X11DRV_GetScreenSaveTimeout
+@ cdecl SetScreenSaveTimeout(long) X11DRV_SetScreenSaveTimeout
+@ cdecl LoadOEMResource(long long) X11DRV_LoadOEMResource
+@ cdecl IsSingleWindow() X11DRV_IsSingleWindow
+@ cdecl AcquireClipboard() X11DRV_AcquireClipboard
+@ cdecl ReleaseClipboard() X11DRV_ReleaseClipboard
+@ cdecl SetClipboardData(long) X11DRV_SetClipboardData
+@ cdecl GetClipboardData(long) X11DRV_GetClipboardData
+@ cdecl IsClipboardFormatAvailable(long) X11DRV_IsClipboardFormatAvailable
+@ cdecl RegisterClipboardFormat(str) X11DRV_RegisterClipboardFormat
+@ cdecl IsSelectionOwner() X11DRV_IsSelectionOwner
+@ cdecl ResetSelectionOwner(ptr long) X11DRV_ResetSelectionOwner
diff --git a/dlls/x11drv/x11drv_main.c b/dlls/x11drv/x11drv_main.c
index 03cfbf5..3326c1a 100644
--- a/dlls/x11drv/x11drv_main.c
+++ b/dlls/x11drv/x11drv_main.c
@@ -20,7 +20,6 @@
 #include "winreg.h"
 
 #include "callback.h"
-#include "clipboard.h"
 #include "debugtools.h"
 #include "gdi.h"
 #include "options.h"
@@ -31,40 +30,6 @@
 
 DEFAULT_DEBUG_CHANNEL(x11drv);
 
-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,
-    /* screen saver functions */
-    X11DRV_GetScreenSaveActive,
-    X11DRV_SetScreenSaveActive,
-    X11DRV_GetScreenSaveTimeout,
-    X11DRV_SetScreenSaveTimeout,
-    /* resource functions */
-    X11DRV_LoadOEMResource,
-    /* windowing functions */
-    X11DRV_IsSingleWindow
-};
-
 static XKeyboardState keyboard_state;
 
 Display *display;
@@ -249,8 +214,6 @@
  */
 static void process_attach(void)
 {
-    USER_Driver      = &user_driver;
-    CLIPBOARD_Driver = &X11DRV_CLIPBOARD_Driver;
     WND_Driver       = &X11DRV_WND_Driver;
 
     setup_options();
@@ -344,8 +307,6 @@
     XCloseDisplay( display );
     display = NULL;
 
-    USER_Driver      = NULL;
-    CLIPBOARD_Driver = NULL;
     WND_Driver       = NULL;
 #endif
 }