diff --git a/graphics/ttydrv/Makefile.in b/graphics/ttydrv/Makefile.in
index ee2454bc280e214761cf60152a7343663bff0e7c..e5d8650a42d693996edc9a7e04e32c876a2b5ee0 100644
--- a/graphics/ttydrv/Makefile.in
+++ b/graphics/ttydrv/Makefile.in
@@ -10,6 +10,8 @@ C_SRCS = \
 	bitmap.c \
 	brush.c \
 	clipping.c \
+	dc.c \
+	dib.c \
 	font.c \
 	graphics.c \
 	init.c \
diff --git a/graphics/ttydrv/bitmap.c b/graphics/ttydrv/bitmap.c
index a6be6c8f85968396b22b61e15a2c33a3b1b31549..75e07e00246c6cae90baee0424e3e961d58bb724 100644
--- a/graphics/ttydrv/bitmap.c
+++ b/graphics/ttydrv/bitmap.c
@@ -6,56 +6,63 @@
 
 #include "bitmap.h"
 #include "dc.h"
-#include "debugtools.h"
 #include "ttydrv.h"
+#include "winbase.h"
+#include "debugtools.h"
 
 DEFAULT_DEBUG_CHANNEL(ttydrv)
 
-/**********************************************************************
- *		TTYDRV_BITMAP_CreateDIBSection
- */
-HBITMAP TTYDRV_BITMAP_CreateDIBSection(
-  DC *dc, BITMAPINFO *bmi, UINT usage, 
-  LPVOID *bits, HANDLE section, DWORD offset)
-{
-  return (HBITMAP) NULL;
-}
+/**********************************************************************/
 
-/**********************************************************************
- *		TTYDRV_BITMAP_CreateDIBSection16
- */
-HBITMAP16 TTYDRV_DIB_CreateDIBSection16(
-  DC *dc, BITMAPINFO *bmi, UINT16 usage,
-  SEGPTR *bits, HANDLE section, DWORD offset)
-{
-  return (HBITMAP16) NULL;
-}
+static LONG TTYDRV_DC_GetBitmapBits(BITMAPOBJ *bitmap, void *bits, LONG count);
+static LONG TTYDRV_DC_SetBitmapBits(BITMAPOBJ *bitmap, void *bits, LONG count);
 
-/**********************************************************************
- *		TTYDRV_BITMAP_SetDIBits
+/***********************************************************************
+ *		TTYDRV_DC_AllocBitmap
  */
-INT TTYDRV_BITMAP_SetDIBits(
-  BITMAPOBJ *bmp, DC *dc, UINT startscan, UINT lines, 
-  LPCVOID bits, const BITMAPINFO *info, UINT coloruse, HBITMAP hbitmap)
+TTYDRV_PHYSBITMAP *TTYDRV_DC_AllocBitmap(BITMAPOBJ *bitmap)
 {
-  return 0;
-}
+  TTYDRV_PHYSBITMAP *physBitmap;
+  
+  if(!(bitmap->DDBitmap = HeapAlloc(GetProcessHeap(), 0, sizeof(DDBITMAP)))) {
+    ERR("Can't alloc DDBITMAP\n");
+    return NULL;
+  }
+ 
+  if(!(physBitmap = HeapAlloc(GetProcessHeap(), 0, sizeof(TTYDRV_PHYSBITMAP)))) {
+    ERR("Can't alloc TTYDRV_PHYSBITMAP\n");
+    HeapFree(GetProcessHeap(), 0, bitmap->DDBitmap);
+    return NULL;
+  }
 
-/**********************************************************************
- *		TTYDRV_BITMAP_GetDIBits
- */
-INT TTYDRV_BITMAP_GetDIBits(
-  BITMAPOBJ *bmp, DC *dc, UINT startscan, UINT lines, 
-  LPVOID bits, BITMAPINFO *info, UINT coloruse, HBITMAP hbitmap)
-{
-  return 0;
+  bitmap->DDBitmap->physBitmap = physBitmap;
+  bitmap->DDBitmap->funcs = DRIVER_FindDriver("DISPLAY");
+
+  return physBitmap;
 }
 
-/**********************************************************************
- *		TTYDRV_BITMAP_DeleteDIBSection
+/***********************************************************************
+ *           TTYDRV_DC_BitmapBits
  */
-void TTYDRV_BITMAP_DeleteDIBSection(BITMAPOBJ *bmp)
+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;
 }
 
 /***********************************************************************
@@ -63,8 +70,28 @@ void TTYDRV_BITMAP_DeleteDIBSection(BITMAPOBJ *bmp)
  */
 BOOL TTYDRV_DC_CreateBitmap(HBITMAP hbitmap)
 {
-  FIXME("(0x%04x): stub\n", 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;
 }
 
@@ -73,21 +100,78 @@ BOOL TTYDRV_DC_CreateBitmap(HBITMAP hbitmap)
  */
 BOOL TTYDRV_DC_BITMAP_DeleteObject(HBITMAP hbitmap, BITMAPOBJ *bitmap)
 {
-  FIXME("(0x%04x, %p): stub\n", hbitmap, bitmap);
+  TRACE("(0x%04x, %p)\n", hbitmap, bitmap);
 
+  HeapFree(GetProcessHeap(), 0, bitmap->DDBitmap->physBitmap);
+  HeapFree(GetProcessHeap(), 0, bitmap->DDBitmap);
+  bitmap->DDBitmap = 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)
 {
-  FIXME("(%p, 0x%04x, %p): stub\n", dc, hbitmap, bitmap);
+  HBITMAP hPreviousBitmap;
+
+  TRACE("(%p, 0x%04x, %p)\n", dc, hbitmap, bitmap);
 
   if(!(dc->w.flags & DC_MEMORY)) 
     return NULL;
 
-  return NULL;
+  /* Assure that the bitmap device dependent */
+  if(!bitmap->DDBitmap && !TTYDRV_DC_CreateBitmap(hbitmap))
+    return NULL;
+
+  if(bitmap->DDBitmap->funcs != dc->funcs) {
+    ERR("Trying to select a non-TTY DDB into a TTY DC\n");
+    return NULL;
+  }
+
+  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 NULL;
+
+    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;
+}
diff --git a/graphics/ttydrv/brush.c b/graphics/ttydrv/brush.c
index 23df2f0f6204f6763d91a3e874c70b79e3923509..86c27246a2b988cb3efa9b6cc227c540601dac2e 100644
--- a/graphics/ttydrv/brush.c
+++ b/graphics/ttydrv/brush.c
@@ -16,7 +16,12 @@ DEFAULT_DEBUG_CHANNEL(ttydrv)
  */
 HBRUSH TTYDRV_DC_BRUSH_SelectObject(DC *dc, HBRUSH hbrush, BRUSHOBJ *brush)
 {
-  FIXME("(%p, 0x%08x, %p): stub\n", dc, hbrush, brush);
+  HBRUSH hPreviousBrush;
 
-  return NULL;
+  TRACE("(%p, 0x%04x, %p)\n", dc, hbrush, brush);
+
+  hPreviousBrush = dc->w.hBrush;
+  dc->w.hBrush = hbrush;
+
+  return hPreviousBrush;
 }
diff --git a/graphics/ttydrv/clipping.c b/graphics/ttydrv/clipping.c
index 184b3faa1db4035eb536c652101f8244e7c17cd2..386722eadc54ff225b9b383a273baee790f86788 100644
--- a/graphics/ttydrv/clipping.c
+++ b/graphics/ttydrv/clipping.c
@@ -15,7 +15,7 @@ DEFAULT_DEBUG_CHANNEL(ttydrv)
  */
 void TTYDRV_DC_SetDeviceClipping(DC *dc)
 {
-  FIXME("(%p): stub\n", dc);
+  TRACE("(%p)\n", dc);
 }
 
 
diff --git a/graphics/ttydrv/dc.c b/graphics/ttydrv/dc.c
new file mode 100644
index 0000000000000000000000000000000000000000..63948dce68b09aa1a317a5bfcf2ad29c4c7dd6f0
--- /dev/null
+++ b/graphics/ttydrv/dc.c
@@ -0,0 +1,105 @@
+/*
+ * TTY DC driver
+ *
+ * Copyright 1999 Patrik Stridvall
+ */
+
+#include "config.h"
+
+#include "gdi.h"
+#include "bitmap.h"
+#include "dc.h"
+#include "monitor.h"
+#include "ttydrv.h"
+#include "winbase.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(ttydrv)
+
+/**********************************************************************/
+
+extern DeviceCaps TTYDRV_DC_DevCaps;
+
+/***********************************************************************
+ *	     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){
+#ifdef HAVE_LIBCURSES
+    physDev->window = NULL;
+#endif /* defined(HAVE_LIBCURSES) */
+    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 {
+#ifdef HAVE_LIBCURSES
+    physDev->window = TTYDRV_MONITOR_GetCursesRootWindow(&MONITOR_PrimaryMonitor);
+#endif /* defined(HAVE_LIBCURSES) */
+    physDev->cellWidth = TTYDRV_MONITOR_GetCellWidth(&MONITOR_PrimaryMonitor);
+    physDev->cellHeight = TTYDRV_MONITOR_GetCellHeight(&MONITOR_PrimaryMonitor);
+    
+    dc->w.bitsPerPixel = MONITOR_GetDepth(&MONITOR_PrimaryMonitor);
+    
+    dc->w.totalExtent.left   = 0;
+    dc->w.totalExtent.top    = 0;
+    dc->w.totalExtent.right  = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
+    dc->w.totalExtent.bottom = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
+    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;
+}
+
diff --git a/graphics/ttydrv/dib.c b/graphics/ttydrv/dib.c
new file mode 100644
index 0000000000000000000000000000000000000000..1b6ce4df0bb135258d761515902ee9c2d3a6c38a
--- /dev/null
+++ b/graphics/ttydrv/dib.c
@@ -0,0 +1,89 @@
+/*
+ * TTY DC dib
+ *
+ * Copyright 1999 Patrik Stridvall
+ */
+
+#include "bitmap.h"
+#include "dc.h"
+#include "ttydrv.h"
+#include "winbase.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(ttydrv)
+
+/***********************************************************************
+ *		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/graphics/ttydrv/font.c b/graphics/ttydrv/font.c
index c0d900be62f9eec3dbf6d044f3ea43271cd988fe..937b5c444802509b7087f71392b450a6c7788118 100644
--- a/graphics/ttydrv/font.c
+++ b/graphics/ttydrv/font.c
@@ -37,7 +37,7 @@ BOOL TTYDRV_DC_GetTextExtentPoint(DC *dc, LPCSTR str, INT count,
 {
   TTYDRV_PDEVICE *physDev = (TTYDRV_PDEVICE *) dc->physDev;
 
-  FIXME("(%p, %s, %d, %p): semistub\n", dc, debugstr_an(str,count), count, size);
+  TRACE("(%p, %s, %d, %p)\n", dc, debugstr_an(str, count), count, size);
 
   size->cx = count * physDev->cellWidth;
   size->cy = physDev->cellHeight;
@@ -52,7 +52,7 @@ BOOL TTYDRV_DC_GetTextMetrics(DC *dc, LPTEXTMETRICA lptm)
 {
   TTYDRV_PDEVICE *physDev = (TTYDRV_PDEVICE *) dc->physDev;
 
-  FIXME("(%p, %p): stub\n", dc, lptm);
+  TRACE("(%p, %p)\n", dc, lptm);
 
   lptm->tmHeight = physDev->cellHeight;
   lptm->tmAscent = 0;
@@ -83,7 +83,12 @@ BOOL TTYDRV_DC_GetTextMetrics(DC *dc, LPTEXTMETRICA lptm)
  */
 HFONT TTYDRV_DC_FONT_SelectObject(DC* dc, HFONT hfont, FONTOBJ *font)
 {
-  FIXME("(%p, 0x%08x, %p): stub\n", dc, hfont, font);
+  HFONT hPreviousFont;
 
-  return NULL;
+  TRACE("(%p, 0x%04x, %p)\n", dc, hfont, font);
+
+  hPreviousFont = dc->w.hFont;
+  dc->w.hFont = hfont;
+
+  return hPreviousFont;
 }
diff --git a/graphics/ttydrv/graphics.c b/graphics/ttydrv/graphics.c
index 4a5f35ad58592117b451367a79f3073ec6b5e024..f2bff6a4787b8f2aeb38b74e8edce8c7ac6d509d 100644
--- a/graphics/ttydrv/graphics.c
+++ b/graphics/ttydrv/graphics.c
@@ -79,6 +79,9 @@ BOOL TTYDRV_DC_LineTo(DC *dc, INT x, INT y)
 
   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;
@@ -98,9 +101,9 @@ BOOL TTYDRV_DC_LineTo(DC *dc, INT x, INT y)
 
   wmove(physDev->window, row1, col1);
   if(col1 == col2) {
-    wvline(physDev->window, '|', row2-row1);
+    wvline(physDev->window, ACS_VLINE, row2-row1);
   } else if(row1 == row2) {
-    whline(physDev->window, '-', col2-col1);
+    whline(physDev->window, ACS_HLINE, col2-col1);
   } else {
     FIXME("Diagonal line drawing not yet supported\n");
   }
@@ -197,6 +200,9 @@ BOOL TTYDRV_DC_Rectangle(DC *dc, INT left, INT top, INT right, INT bottom)
 
   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;
@@ -214,21 +220,21 @@ BOOL TTYDRV_DC_Rectangle(DC *dc, INT left, INT top, INT right, INT bottom)
   } 
 
   wmove(physDev->window, row1, col1);
-  whline(physDev->window, '-', col2-col1);
+  whline(physDev->window, ACS_HLINE, col2-col1);
 
   wmove(physDev->window, row1, col2);
-  wvline(physDev->window, '|', row2-row1);
+  wvline(physDev->window, ACS_VLINE, row2-row1);
 
   wmove(physDev->window, row2, col1);
-  whline(physDev->window, '-', col2-col1);
+  whline(physDev->window, ACS_HLINE, col2-col1);
 
   wmove(physDev->window, row1, col1);
-  wvline(physDev->window, '|', row2-row1);
+  wvline(physDev->window, ACS_VLINE, row2-row1);
 
-  mvwaddch(physDev->window, row1, col1, '+');
-  mvwaddch(physDev->window, row1, col2, '+');
-  mvwaddch(physDev->window, row2, col2, '+');
-  mvwaddch(physDev->window, row2, col1, '+');
+  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);
 
@@ -278,10 +284,13 @@ COLORREF TTYDRV_DC_SetPixel(DC *dc, INT x, INT y, COLORREF color)
 
   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, '.');
+  mvwaddch(physDev->window, row, col, ACS_BULLET);
   wrefresh(physDev->window);
 
   return RGB(0,0,0); /* FIXME: Always returns black */
diff --git a/graphics/ttydrv/init.c b/graphics/ttydrv/init.c
index 079d46444803461b130d84f411a7491f032c794e..efb03a37b20c5fb443d6b5731ca5d2bfb647aa5d 100644
--- a/graphics/ttydrv/init.c
+++ b/graphics/ttydrv/init.c
@@ -1,7 +1,7 @@
 /*
  * TTY driver
  *
- * Copyright 1998 Patrik Stridvall
+ * Copyright 1998-1999 Patrik Stridvall
  */
 
 #include "config.h"
@@ -10,9 +10,6 @@
 #include "bitmap.h"
 #include "color.h"
 #include "dc.h"
-#include "heap.h"
-#include "monitor.h"
-#include "palette.h"
 #include "ttydrv.h"
 #include "debugtools.h"
 
@@ -27,7 +24,7 @@ static const DC_FUNCTIONS TTYDRV_DC_Driver =
   NULL,                /* pArcTo */
   NULL,                /* pBeginPath */
   TTYDRV_DC_BitBlt,    /* pBitBlt */
-  NULL,                /* pBitmapBits */
+  TTYDRV_DC_BitmapBits,/* pBitmapBits */
   TTYDRV_DC_Chord,     /* pChord */
   NULL,                /* pCloseFigure */
   TTYDRV_DC_CreateBitmap, /* pCreateBitmap */
@@ -88,7 +85,7 @@ static const DC_FUNCTIONS TTYDRV_DC_Driver =
   TTYDRV_DC_SetBkColor, /* pSetBkColor */
   NULL,                /* pSetBkMode */
   TTYDRV_DC_SetDeviceClipping, /* pSetDeviceClipping */
-  NULL,                /* pSetDIBitsToDevice */
+  TTYDRV_DC_SetDIBitsToDevice, /* pSetDIBitsToDevice */
   NULL,                /* pSetMapMode (optional) */
   NULL,                /* pSetMapperFlags */
   TTYDRV_DC_SetPixel,  /* pSetPixel */
@@ -193,87 +190,3 @@ 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;
-
-  FIXME("(%p, %s, %s, %s, %p): semistub\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){
-#ifdef HAVE_LIBCURSES
-    physDev->window = NULL;
-#endif /* defined(HAVE_LIBCURSES) */
-    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 {
-#ifdef HAVE_LIBCURSES
-    physDev->window = TTYDRV_MONITOR_GetCursesRootWindow(&MONITOR_PrimaryMonitor);
-#endif /* defined(HAVE_LIBCURSES) */
-    physDev->cellWidth = TTYDRV_MONITOR_GetCellWidth(&MONITOR_PrimaryMonitor);
-    physDev->cellHeight = TTYDRV_MONITOR_GetCellHeight(&MONITOR_PrimaryMonitor);
-    
-    dc->w.bitsPerPixel = MONITOR_GetDepth(&MONITOR_PrimaryMonitor);
-    
-    dc->w.totalExtent.left   = 0;
-    dc->w.totalExtent.top    = 0;
-    dc->w.totalExtent.right  = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
-    dc->w.totalExtent.bottom = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
-    dc->w.hVisRgn            = CreateRectRgnIndirect( &dc->w.totalExtent );    
-  }
-
-  return TRUE;
-}
-
-
-/**********************************************************************
- *	     TTYDRV_DC_DeleteDC
- */
-BOOL TTYDRV_DC_DeleteDC(DC *dc)
-{
-  FIXME("(%p): semistub\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;
-}
diff --git a/graphics/ttydrv/objects.c b/graphics/ttydrv/objects.c
index 421361a6fc9cbc9a46157843d8c581f37929ab6c..ddc410d604c94114cb04ab1cbb46d8cd4c6f0d9b 100644
--- a/graphics/ttydrv/objects.c
+++ b/graphics/ttydrv/objects.c
@@ -53,7 +53,7 @@ HGDIOBJ TTYDRV_DC_SelectObject(DC *dc, HGDIOBJ handle)
       result = (HGDIOBJ) SelectClipRgn(dc->hSelf, handle);
       break;
     default:
-      ERR("unknown magic (0x%04x)\n", ptr->wMagic);
+      ERR("handle (0x%04x) has unknown magic (0x%04x)\n", handle, ptr->wMagic);
   }
 
   GDI_HEAP_UNLOCK(handle);
@@ -83,7 +83,7 @@ BOOL TTYDRV_DC_DeleteObject(HGDIOBJ handle)
       result = TRUE;
       break;
     default:
-      ERR("unknown magic (0x%04x)\n", ptr->wMagic);   
+      ERR("handle (0x%04x) has unknown magic (0x%04x)\n", handle, ptr->wMagic);   
       result = FALSE;
   }
 
diff --git a/graphics/ttydrv/oembitmap.c b/graphics/ttydrv/oembitmap.c
index f4f0611c35be16f9a553aca2455983b85e70688f..f67b04a587cbd2e2a4d6ecd9c684dc09eb97475a 100644
--- a/graphics/ttydrv/oembitmap.c
+++ b/graphics/ttydrv/oembitmap.c
@@ -5,36 +5,52 @@
  */
 
 #include "bitmap.h"
-#include "debugtools.h"
 #include "ttydrv.h"
+#include "debugtools.h"
 
 DEFAULT_DEBUG_CHANNEL(ttydrv)
 
 /**********************************************************************
- *		TTYDRV_DC_LoadOEMResource
+ *		TTYDRV_DC_LoadOEMBitmap
  */
-HANDLE TTYDRV_DC_LoadOEMResource(WORD resid, WORD type)
+static HANDLE TTYDRV_DC_LoadOEMBitmap(WORD resid)
 {
   HBITMAP hbitmap;
-  BITMAPOBJ *bmpObjPtr;
 
-  FIXME("(%d, %d): semistub\n", resid, type);
+  TRACE("(%d)\n", resid);
  
-  if(!(hbitmap = GDI_AllocObject(sizeof(BITMAPOBJ), BITMAP_MAGIC)))
-    return (HANDLE) NULL;
-  
-  bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LOCK(hbitmap);
-  bmpObjPtr->size.cx = 0;
-  bmpObjPtr->size.cy = 0;
-  bmpObjPtr->bitmap.bmType       = 0;
-  bmpObjPtr->bitmap.bmWidth      = 0;
-  bmpObjPtr->bitmap.bmHeight     = 0;
-  bmpObjPtr->bitmap.bmWidthBytes = 0;
-  bmpObjPtr->bitmap.bmPlanes     = 0;
-  bmpObjPtr->bitmap.bmBitsPixel  = 0;
-  bmpObjPtr->bitmap.bmBits       = NULL;
-  bmpObjPtr->dib                 = NULL;
-  
-  GDI_HEAP_UNLOCK( hbitmap );
+  hbitmap = CreateBitmap(1, 1, 1, 1, NULL);
+  TTYDRV_DC_CreateBitmap(hbitmap);
+
   return hbitmap;
 }
+
+/**********************************************************************
+ *		TTYDRV_DC_LoadOEMCursorIcon
+ */
+static HANDLE TTYDRV_DC_LoadOEMCursorIcon(WORD resid, BOOL bCursor)
+{
+  return (HANDLE) NULL;
+}
+
+/**********************************************************************
+ *		TTYDRV_DC_LoadOEMResource
+ */
+HANDLE TTYDRV_DC_LoadOEMResource(WORD resid, WORD type)
+{
+  switch(type)
+  {
+    case OEM_BITMAP:
+      return TTYDRV_DC_LoadOEMBitmap(resid);
+    case OEM_CURSOR:
+      return TTYDRV_DC_LoadOEMCursorIcon(resid, TRUE);
+    case OEM_ICON:
+      return TTYDRV_DC_LoadOEMCursorIcon(resid, FALSE);
+    default:
+      ERR("unknown type (%d)\n", type);
+  }
+
+  return (HANDLE) NULL;
+}
+
+
diff --git a/graphics/ttydrv/palette.c b/graphics/ttydrv/palette.c
index bff9309d6b54ab598174e872f9b1494bae650136..7010775de7e80bd901186821501b47bb97a7e201 100644
--- a/graphics/ttydrv/palette.c
+++ b/graphics/ttydrv/palette.c
@@ -94,7 +94,7 @@ int TTYDRV_PALETTE_SetMapping(
  */
 int TTYDRV_PALETTE_UpdateMapping(PALETTEOBJ *palPtr)
 {
-  FIXME("(%p): stub\n", palPtr);
+  TRACE("(%p)\n", palPtr);
 
   return 0;
 }
diff --git a/graphics/ttydrv/pen.c b/graphics/ttydrv/pen.c
index db09794e6e90f32bbf32ea089ef09c975aa7c5ce..45fed40ca78570b5d58852db658ff7eb5962e0ee 100644
--- a/graphics/ttydrv/pen.c
+++ b/graphics/ttydrv/pen.c
@@ -16,7 +16,12 @@ DEFAULT_DEBUG_CHANNEL(ttydrv)
  */
 HPEN TTYDRV_DC_PEN_SelectObject(DC *dc, HBRUSH hpen, PENOBJ *pen)
 {
-  FIXME("(%p, 0x%08x, %p): stub\n", dc, hpen, pen);
+  HPEN hPreviousPen;
 
-  return NULL;
+  TRACE("(%p, 0x%04x, %p)\n", dc, hpen, pen);
+
+  hPreviousPen = dc->w.hPen;
+  dc->w.hPen = hpen;
+
+  return hPreviousPen;
 }
diff --git a/graphics/ttydrv/text.c b/graphics/ttydrv/text.c
index 396bb0a28cb874f06da06798d496aa76a96630c9..04ccf4820e6d808528dad49f32250357537c1be7 100644
--- a/graphics/ttydrv/text.c
+++ b/graphics/ttydrv/text.c
@@ -25,9 +25,12 @@ BOOL TTYDRV_DC_ExtTextOut(DC *dc, INT x, INT y, UINT flags,
   TTYDRV_PDEVICE *physDev = (TTYDRV_PDEVICE *) dc->physDev;
   INT row, col;
 
-  FIXME("(%p, %d, %d, 0x%08x, %p, %s, %d, %p): semistub\n",
+  TRACE("(%p, %d, %d, 0x%08x, %p, %s, %d, %p)\n",
 	dc, x, y, flags, lpRect, debugstr_a(str), count, lpDx);
 
+  if(!physDev->window)
+    return FALSE;
+
   /* FIXME: Is this really correct? */
   if(dc->w.textAlign & TA_UPDATECP) {
     x = dc->w.CursPosX;
diff --git a/include/ttydrv.h b/include/ttydrv.h
index 621220a9db74bb6ed2144e416decd057aeebb7f6..49497780777b5281527633cb53080c39a2b5729d 100644
--- a/include/ttydrv.h
+++ b/include/ttydrv.h
@@ -58,7 +58,14 @@ typedef struct {
   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);
@@ -92,6 +99,7 @@ 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 */
 
diff --git a/windows/ttydrv/main.c b/windows/ttydrv/main.c
index f3ccb61d7bc145e111fc6e144df545e596160a6b..455e49c145a64c00689d042addca54b8ccf45a29 100644
--- a/windows/ttydrv/main.c
+++ b/windows/ttydrv/main.c
@@ -37,9 +37,6 @@ BOOL TTYDRV_USER_Initialize(void)
  */
 void TTYDRV_USER_Finalize(void)
 {
-#ifdef HAVE_LIBCURSES
-  endwin();
-#endif /* defined(HAVE_LIBCURSES) */
 }
 
 /**************************************************************************
diff --git a/windows/ttydrv/monitor.c b/windows/ttydrv/monitor.c
index 07cf236e67d55061c397a3a560e2866c1f420940..fb0d702c64ad0cd4e3883a4873607ac53827ec31 100644
--- a/windows/ttydrv/monitor.c
+++ b/windows/ttydrv/monitor.c
@@ -68,8 +68,10 @@ void TTYDRV_MONITOR_Initialize(MONITOR *pMonitor)
 
 #ifdef HAVE_LIBCURSES
   pTTYMonitor->rootWindow = initscr();
-  werase(pTTYMonitor->rootWindow);
-  wrefresh(pTTYMonitor->rootWindow);
+  if(pTTYMonitor->rootWindow) {
+    werase(pTTYMonitor->rootWindow);
+    wrefresh(pTTYMonitor->rootWindow);
+  }
 
   getmaxyx(pTTYMonitor->rootWindow, rows, cols);
 #else /* defined(HAVE_LIBCURSES) */
@@ -87,7 +89,16 @@ void TTYDRV_MONITOR_Initialize(MONITOR *pMonitor)
  */
 void TTYDRV_MONITOR_Finalize(MONITOR *pMonitor)
 {
-  HeapFree(SystemHeap, 0, pMonitor->pDriverData);
+  TTYDRV_MONITOR_DATA *pTTYMonitor =
+    (TTYDRV_MONITOR_DATA *) pMonitor->pDriverData;
+
+#ifdef HAVE_LIBCURSES
+  if(pTTYMonitor->rootWindow) {
+     endwin();
+  }
+#endif /* defined(HAVE_LIBCURSES) */
+
+  HeapFree(SystemHeap, 0, pTTYMonitor);
 }
 
 /***********************************************************************
diff --git a/windows/ttydrv/wnd.c b/windows/ttydrv/wnd.c
index 4d662bf6b0ec7159203e9c05fe4b6709f246295b..27b9a27fe66035c09e76bee4852160942655be5d 100644
--- a/windows/ttydrv/wnd.c
+++ b/windows/ttydrv/wnd.c
@@ -118,7 +118,8 @@ BOOL TTYDRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BO
   if(cs->style & WS_CHILD)
     return TRUE;
 
-  rootWindow = TTYDRV_WND_GetCursesRootWindow(wndPtr);
+  if(!(rootWindow = TTYDRV_WND_GetCursesRootWindow(wndPtr)))
+    return FALSE;
 
   window = subwin(rootWindow, cs->cy/cellHeight, cs->cx/cellWidth,
 		  cs->y/cellHeight, cs->x/cellWidth);
@@ -230,14 +231,14 @@ void TTYDRV_WND_ScrollWindow(
  */
 void TTYDRV_WND_SetDrawable(WND *wndPtr, DC *dc, WORD flags, BOOL bSetClipOrigin)
 {
-  FIXME("(%p, %p, %d, %d): semistub\n", wndPtr, dc, flags, bSetClipOrigin);
+  TRACE("(%p, %p, %d, %d)\n", wndPtr, dc, flags, bSetClipOrigin);
 
-  if (!wndPtr)  {
-    /* Get a DC for the whole screen */
+  /* FIXME: Should be done in the common code instead */
+  if(!wndPtr)  {
     dc->w.DCOrgX = 0;
     dc->w.DCOrgY = 0;
   } else {
-    if (flags & DCX_WINDOW) {
+    if(flags & DCX_WINDOW) {
       dc->w.DCOrgX = wndPtr->rectWindow.left;
       dc->w.DCOrgY = wndPtr->rectWindow.top;
     } else {