diff --git a/Makefile.in b/Makefile.in
index 1f529eb10942553a675b66964233fa1ca107ab55..d08e80d314c358a7a06b01ab169d16741589aa6d 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -39,16 +39,11 @@ LIBRARIES = \
 # Sub-directories to run make depend/clean into
 SUBDIRS = \
 	console \
-	controls \
 	debugger \
 	dlls \
 	dlls/ntdll \
 	documentation \
 	files \
-	graphics \
-	graphics/enhmetafiledrv \
-	graphics/metafiledrv \
-	graphics/win16drv \
 	if1632 \
 	include \
 	library \
@@ -60,7 +55,6 @@ SUBDIRS = \
 	misc \
 	miscemu \
 	msdos \
-	objects \
 	ole \
 	programs \
 	relay32 \
@@ -69,8 +63,7 @@ SUBDIRS = \
 	server \
 	tools \
 	unicode \
-	win32 \
-	windows
+	win32
 
 # Sub-directories to run make install into
 INSTALLSUBDIRS = \
@@ -83,14 +76,9 @@ INSTALLSUBDIRS = \
 	unicode
 
 LIBOBJS = \
-	controls/controls.o \
 	console/console.o \
 	dlls/ntdll/ntdll.o \
 	files/files.o \
-	graphics/graphics.o \
-	graphics/enhmetafiledrv/enhmetafiledrv.o \
-	graphics/metafiledrv/metafiledrv.o \
-	graphics/win16drv/win16drv.o \
 	if1632/if1632.o \
 	loader/loader.o \
 	loader/ne/ne.o \
@@ -98,13 +86,11 @@ LIBOBJS = \
 	memory/memory.o \
 	misc/misc.o \
 	msdos/msdos.o \
-	objects/objects.o \
 	ole/ole.o \
 	relay32/relay32.o \
 	resources/resources.o \
 	scheduler/scheduler.o \
-	win32/win32.o \
-	windows/windows.o
+	win32/win32.o
 
 EMUOBJS = \
 	miscemu/miscemu.o
diff --git a/dlls/gdi/.cvsignore b/dlls/gdi/.cvsignore
index 025013cb277c9a9b1005ed5a84198d42356fa4b3..9e9ece2d00735ca13892de66b7879742b1ea78e4 100644
--- a/dlls/gdi/.cvsignore
+++ b/dlls/gdi/.cvsignore
@@ -2,4 +2,5 @@
 *.spec.glue.s
 Makefile
 libgdi32.so.1.0
+printdrv.glue.c
 thunk.glue.c
diff --git a/dlls/gdi/Makefile.in b/dlls/gdi/Makefile.in
index 7680164624e2a0dfea5ddd0af3257ba2ba4b6bfb..96036b9b0f3fa70bcf66e5878eeabc515bb5edb1 100644
--- a/dlls/gdi/Makefile.in
+++ b/dlls/gdi/Makefile.in
@@ -9,12 +9,30 @@ ALTNAMES  = gdi dispdib wing
 C_SRCS = \
 	bidi16.c \
 	gdi_main.c \
+	printdrv.c \
 	thunk.c \
 	wing.c
 
-GLUE = thunk.c
+GLUE = printdrv.c thunk.c
+
+EXTRA_OBJS = \
+	$(TOPOBJDIR)/graphics/graphics.o \
+	$(TOPOBJDIR)/graphics/enhmetafiledrv/enhmetafiledrv.o \
+	$(TOPOBJDIR)/graphics/metafiledrv/metafiledrv.o \
+	$(TOPOBJDIR)/graphics/win16drv/win16drv.o \
+	$(TOPOBJDIR)/objects/objects.o
+
+SUBDIRS = \
+	$(TOPOBJDIR)/graphics \
+	$(TOPOBJDIR)/graphics/enhmetafiledrv \
+	$(TOPOBJDIR)/graphics/metafiledrv \
+	$(TOPOBJDIR)/graphics/win16drv \
+	$(TOPOBJDIR)/objects
 
 @MAKE_DLL_RULES@
 
+$(EXTRA_OBJS): $(TOOLSUBDIRS) dummy
+	@cd `dirname $@` && $(MAKE) `basename $@`
+
 ### Dependencies:
 
diff --git a/misc/printdrv.c b/dlls/gdi/printdrv.c
similarity index 100%
rename from misc/printdrv.c
rename to dlls/gdi/printdrv.c
diff --git a/dlls/kernel/toolhelp.spec b/dlls/kernel/toolhelp.spec
index 3e6eb16028cf4f7a40e5423f491ec1b9ca91c3af..071968aad702230cef7246d283fd0f2a66ee14ac 100644
--- a/dlls/kernel/toolhelp.spec
+++ b/dlls/kernel/toolhelp.spec
@@ -21,8 +21,11 @@ owner	kernel32
 66 pascal16 StackTraceFirst(ptr word) StackTraceFirst16
 67 pascal16 StackTraceCSIPFirst(ptr word word word word) StackTraceCSIPFirst16
 68 pascal16 StackTraceNext(ptr) StackTraceNext16
-69 pascal16 ClassFirst(ptr) ClassFirst16
-70 pascal16 ClassNext(ptr) ClassNext16
+#69 pascal16 ClassFirst(ptr) ClassFirst16
+#70 pascal16 ClassNext(ptr) ClassNext16
+#FIXME: window classes are USER objects
+69 stub ClassFirst
+70 stub ClassNext
 71 pascal16 SystemHeapInfo(ptr) SystemHeapInfo16
 72 pascal16 MemManInfo(ptr) MemManInfo16
 73 pascal16 NotifyRegister(word segptr word) NotifyRegister16
diff --git a/dlls/user/Makefile.in b/dlls/user/Makefile.in
index 22f489aee0562a082abe217bf8c0eab83a908047..3fccf8a9ded948f3c70b288a427d4602a53c5c60 100644
--- a/dlls/user/Makefile.in
+++ b/dlls/user/Makefile.in
@@ -24,7 +24,18 @@ RC_SRCS = \
 
 GLUE = thunk.c
 
+EXTRA_OBJS = \
+	$(TOPOBJDIR)/controls/controls.o \
+	$(TOPOBJDIR)/windows/windows.o
+
+SUBDIRS = \
+	$(TOPOBJDIR)/controls \
+	$(TOPOBJDIR)/windows
+
 @MAKE_DLL_RULES@
 
+$(EXTRA_OBJS): $(TOOLSUBDIRS) dummy
+	@cd `dirname $@` && $(MAKE) `basename $@`
+
 ### Dependencies:
 
diff --git a/misc/Makefile.in b/misc/Makefile.in
index 424f38dd369bd5903cab5a86aef3948de54187ec..28efe29778fb0c313fae23fc4bd39c73c6169752 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -17,15 +17,12 @@ C_SRCS = \
 	main.c \
 	options.c \
 	port.c \
-	printdrv.c \
 	registry.c \
 	system.c \
 	tweak.c \
 	version.c \
 	wsprintf.c
 
-GLUE = printdrv.c
-
 all: $(MODULE).o
 
 @MAKE_RULES@
diff --git a/msdos/int09.c b/msdos/int09.c
index c68f4ca1551dd2741a2e3c6daf52e9243eeac43c..9278d94ca8f37feedf026ac653a0c123ae2c7e03 100644
--- a/msdos/int09.c
+++ b/msdos/int09.c
@@ -28,7 +28,6 @@ typedef struct {
 void WINAPI INT_Int09Handler( CONTEXT86 *context )
 {
   BYTE ascii, scan = INT_Int09ReadScan(&ascii);
-  UINT vkey = MapVirtualKeyA(scan&0x7f, 1);
   BYTE ch[2];
   int cnt, c2;
 
@@ -39,8 +38,13 @@ void WINAPI INT_Int09Handler( CONTEXT86 *context )
       ch[0] = ascii;
       cnt = 1;
     } else {
+#if 0  /* FIXME: cannot call USER functions here */
+      UINT vkey = MapVirtualKeyA(scan&0x7f, 1);
       /* as in TranslateMessage, windows/input.c */
       cnt = ToAscii(vkey, scan, QueueKeyStateTable, (LPWORD)ch, 0);
+#else
+      cnt = 0;
+#endif
     }
     if (cnt>0) {
       for (c2=0; c2<cnt; c2++)
diff --git a/msdos/int16.c b/msdos/int16.c
index e98a7fdc9344ca068779e0cfb5f65f03bc3a9989..f86be1352d0aa3466dbb265b8fb1e30d99996ac2 100644
--- a/msdos/int16.c
+++ b/msdos/int16.c
@@ -58,6 +58,7 @@ void WINAPI INT_Int16Handler( CONTEXT86 *context )
    case 0x02: /* Get Shift Flags */      
       AL_reg(context) = 0;
 
+#if 0  /* FIXME: cannot call USER functions here */
       if (GetAsyncKeyState(VK_RSHIFT))
           AL_reg(context) |= 0x01;
       if (GetAsyncKeyState(VK_LSHIFT))
@@ -74,6 +75,7 @@ void WINAPI INT_Int16Handler( CONTEXT86 *context )
           AL_reg(context) |= 0x40;
       if (GetAsyncKeyState(VK_INSERT))
           AL_reg(context) |= 0x80;
+#endif
       TRACE("Get Shift Flags: returning 0x%02x\n", AL_reg(context));
       break;
 
diff --git a/scheduler/thread.c b/scheduler/thread.c
index 7d200bdd40e982288ace8997c496beca2049dd98..2555778eeefd56d633e6b609751dc1ce0756ccb1 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -765,6 +765,7 @@ BOOL WINAPI AttachThreadInput(
     DWORD idAttachTo, /* [in] Thread to attach to */
     BOOL fAttach)   /* [in] Attach or detach */
 {
+#if 0  /* FIXME: cannot call USER functions here */
     MESSAGEQUEUE *pSrcMsgQ = 0, *pTgtMsgQ = 0;
     BOOL16 bRet = 0;
 
@@ -829,6 +830,10 @@ CLEANUP:
         QUEUE_Unlock( pTgtMsgQ );
     
     return bRet;
+#endif
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    FIXME( "broken for now\n" );
+    return FALSE;
 }
 
 /**********************************************************************
diff --git a/win32/console.c b/win32/console.c
index 0127d06f9494fb8786fe83bdb5497de427b0d881..35a67331ca8cdffb269c676e97616128f977a559 100644
--- a/win32/console.c
+++ b/win32/console.c
@@ -97,6 +97,7 @@ CONSOLE_string_to_IR( HANDLE hConsoleInput,unsigned char *buf,int len) {
 		ir.Event.KeyEvent.dwControlKeyState|=LEFT_ALT_PRESSED;
 		inchar &= ~0x80;
 	    }
+#if 0  /* FIXME: cannot call USER functions here */
 	    ir.Event.KeyEvent.wVirtualKeyCode = VkKeyScan16(inchar);
 	    if (ir.Event.KeyEvent.wVirtualKeyCode & 0x0100)
 		ir.Event.KeyEvent.dwControlKeyState|=SHIFT_PRESSED;
@@ -108,6 +109,10 @@ CONSOLE_string_to_IR( HANDLE hConsoleInput,unsigned char *buf,int len) {
 	    	ir.Event.KeyEvent.wVirtualKeyCode & 0x00ff,
 		0 /* VirtualKeyCodes to ScanCode */
 	    );
+#else
+	    ir.Event.KeyEvent.wVirtualKeyCode = 0;
+	    ir.Event.KeyEvent.wVirtualScanCode = 0;
+#endif
 	    ir.Event.KeyEvent.uChar.AsciiChar = inchar;
 
 	    if ((inchar==127)||(inchar=='\b')) { /* backspace */
@@ -140,10 +145,15 @@ CONSOLE_string_to_IR( HANDLE hConsoleInput,unsigned char *buf,int len) {
 	    ir.Event.KeyEvent.bKeyDown		= 1;
 	    ir.Event.KeyEvent.wRepeatCount	= 0;
 
+#if 0  /* FIXME: cannot call USER functions here */
 	    ir.Event.KeyEvent.wVirtualKeyCode	= VkKeyScan16(27);
 	    ir.Event.KeyEvent.wVirtualScanCode	= MapVirtualKey16(
 	    	ir.Event.KeyEvent.wVirtualKeyCode,0
 	    );
+#else
+	    ir.Event.KeyEvent.wVirtualKeyCode	= VK_ESCAPE;
+	    ir.Event.KeyEvent.wVirtualScanCode	= 1;
+#endif
 	    ir.Event.KeyEvent.dwControlKeyState = 0;
 	    ir.Event.KeyEvent.uChar.AsciiChar	= 27;
 	    assert(WriteConsoleInputA( hConsoleInput, &ir, 1, &junk ));
@@ -225,7 +235,11 @@ CONSOLE_string_to_IR( HANDLE hConsoleInput,unsigned char *buf,int len) {
 	    }
 	    if (scancode) {
 		ir.Event.KeyEvent.wVirtualScanCode = scancode;
+#if 0  /* FIXME: cannot call USER functions here */
 		ir.Event.KeyEvent.wVirtualKeyCode = MapVirtualKey16(scancode,1);
+#else
+		ir.Event.KeyEvent.wVirtualKeyCode = 0;
+#endif
 		assert(WriteConsoleInputA( hConsoleInput, &ir, 1, &junk ));
 		ir.Event.KeyEvent.bKeyDown		= 0;
 		assert(WriteConsoleInputA( hConsoleInput, &ir, 1, &junk ));