Release 971130

Sat Nov 29 12:35:26 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [if1632/builtin.c]
	Build a complete PE header for builtin Win32 modules.

	* [loader/pe_image.c] [loader/module.c]
	HMODULE32 now points to the loading address of the module. There
	is no longer a separate PE_MODULE structure.

Fri Nov 28 11:21:47 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [ole/*][configure.in][Makefile.in][include/interfaces.h]
	  [if1632/olesvr32.spec][if1632/olecli32.spec]
	New directory, moved OLE stuff there.
	new .spec files for olecli32,olesvr32, some stubs added.

	* [misc/shell.c]
	Added support for extracting icons from PE dlls.

	* [misc/shellord.c][if1632/shell32.spec]
	Added a huge heap of ordinal only exported shell functions
	(will work only in Win95).

	* [loader/task.c]
	Hack to make MakeProcInstance16 work in all cases (mplayer.exe).

	* [win32/string32.c][include/string32.h]
	Obsolete, removed.

	* [windows/keyboard.c]
	Added *RegisterHotkey.

	* [objects/font.c][objects/text.c]
	Added GetFontLanguageInfo, GetTextCharsetInfo.

Wed Nov 26 18:10:40 1997  Uwe Bonnes  <bon@elektron.ikp.physik.tu-darmstadt.de>

	* [misc/network.c]
	In WNetGetConnection16 return the Drive label and not the DOS-Cwd.
	Makes Wordview 6 start on a network connected machine.

	* [controls/status.c]
	Catch a Null pointer in SW_SetText.

	* [files/dos_fs.c]
 	Add NT5 functions GetLongPathName32.

	* [files/file.c]
	Make GetTempFileName16 accept drive 0 (Current Drive) too.
	Handle more errors and be more verbose in FILE_SetDosError, fix
	an error in DeleteFile32W

	* [memory/virtual.c]
	Implement FlushViewOfFile.

	* [misc/crtdll]
	Implement _rotl and splitpath and add a stub for 
	_abnormal_termination.

	* [misc/printdrv.c]
	Stub for EnumPrinters32A.

	* [win32/newfns]
	Add Stub for QueryPerformanceFrequency, change return value
	for QueryPerformanceCounter.
 	Add stub for DeviceIoControl.

Tue Nov 25 15:55:01 1997 Martin Boehme <boehme@informatik.mu-luebeck.de>

	* [controls/combo.c] [controls/edit.c] [windows/defwnd.c]
	  [windows/winpos.c] [windows/win.c]
	Removed WIN_NO_REDRAW flag.

Tue Nov 25 13:20:35 1997  Douglas Ridgway <ridgway@taiga.v-wave.com>

	* [graphics/x11drv/bitblt.c]
	Fixed memory leak in BITBLT_GetDstArea.

Sun Nov 23 14:05:23 1997  Andreas Mohr <100.30936@germany.net>

	* [files/directory.c]
	Export windows system directory to environment.

	* [if1632/Makefile.in] [if1632/builtin.c] [if1632/w32skrnl.spec]
	  [if1632/win32s16.spec] [misc/w32scomb.c] [misc/w32skrnl.c]
	Added Win32s DLLs W32SKRNL and WIN32S16.

	* [if1632/kernel32.spec] [loader/module.c]
	Added misc functions for Win32s.

	* [if1632/kernel.spec] [loader/task.c]
	Added DefineHandleTable().

	* [scheduler/process.c]
	Fixed SetEnvironmentVariable32A() to avoid heap corruption.

Sat Nov 22 14:11:42 1997  Kristian Nielsen  <kristian.nielsen@risoe.dk>

	* [windows/painting.c]
	Fix leak in BeginPaint16() for CS_PARENTDC windows where the
	update region was not properly released.

Thu Nov 20 03:55:29 1997  Gordon Chaffee <chaffee@CS.Berkeley.EDU>

	* [loader/pe_image.c]
	Implemented forwarded DLL functions.

	* [objects/dib.c]
	Added support for 16- and 32-bit mode DIBs.
	Support negative bitmap heights.

	* [win32/process.c]
	Added stub for CreateProcess32W.

	* [win32/security.c] [include/ntdll.h]
	Added stubs for LookupAccountSid32A/W.

	* [scheduler/process.c]
	Use the size specified in the PE header for the process heap.

Mon Nov 17 00:53:35 1997  Len White <phreak@cgocable.net>

	* [msdos/int3d.c]
	New file. Stubs for int3d.

Sun Nov 16 12:30:00 PST 1997  Jason Schonberg  <schon@mti.sgi.com>

	* [include/aspi.h]
	Changed comment style from C++ to C.
diff --git a/objects/cursoricon.c b/objects/cursoricon.c
index 569b6ab..a9a7a06 100644
--- a/objects/cursoricon.c
+++ b/objects/cursoricon.c
@@ -1258,9 +1258,10 @@
  *
  * FIXME: exact parameter sizes
  */
-UINT16 WINAPI LookupIconIdFromDirectoryEx16( CURSORICONDIR *dir, BOOL16 bIcon,
+INT16 WINAPI LookupIconIdFromDirectoryEx16( LPBYTE xdir, BOOL16 bIcon,
 	     INT16 width, INT16 height, UINT16 cFlag )
 {
+    CURSORICONDIR	*dir = (CURSORICONDIR*)xdir;
     UINT16 retVal = 0;
     if( dir && !dir->idReserved && (dir->idType & 3) )
     {
@@ -1285,16 +1286,16 @@
 /**********************************************************************
  *          LookupIconIdFromDirectoryEx32       (USER32.379)
  */
-INT32 WINAPI LookupIconIdFromDirectoryEx32( CURSORICONDIR *dir, BOOL32 bIcon,
+INT32 WINAPI LookupIconIdFromDirectoryEx32( LPBYTE dir, BOOL32 bIcon,
              INT32 width, INT32 height, UINT32 cFlag )
 {
     return LookupIconIdFromDirectoryEx16( dir, bIcon, width, height, cFlag );
 }
 
 /**********************************************************************
- *          LookupIconIdFromDirectory		(USER32.378)
+ *          LookupIconIdFromDirectory		(USER.???)
  */
-INT32 WINAPI LookupIconIdFromDirectory( CURSORICONDIR *dir, BOOL32 bIcon )
+INT16 WINAPI LookupIconIdFromDirectory16( LPBYTE dir, BOOL16 bIcon )
 {
     return LookupIconIdFromDirectoryEx16( dir, bIcon, 
 	   bIcon ? SYSMETRICS_CXICON : SYSMETRICS_CXCURSOR,
@@ -1302,14 +1303,24 @@
 }
 
 /**********************************************************************
+ *          LookupIconIdFromDirectory		(USER32.378)
+ */
+INT32 WINAPI LookupIconIdFromDirectory32( LPBYTE dir, BOOL32 bIcon )
+{
+    return LookupIconIdFromDirectoryEx32( dir, bIcon, 
+	   bIcon ? SYSMETRICS_CXICON : SYSMETRICS_CXCURSOR,
+	   bIcon ? SYSMETRICS_CYICON : SYSMETRICS_CYCURSOR, bIcon ? 0 : LR_MONOCHROME );
+}
+
+/**********************************************************************
  *	    GetIconID    (USER.455)
  */
 WORD WINAPI GetIconID( HGLOBAL16 hResource, DWORD resType )
 {
-    CURSORICONDIR *lpDir = (CURSORICONDIR *)GlobalLock16(hResource);
+    LPBYTE lpDir = (LPBYTE)GlobalLock16(hResource);
 
     dprintf_cursor( stddeb, "GetIconID: hRes=%04x, entries=%i\n",
-                    hResource, lpDir ? lpDir->idCount : 0);
+                    hResource, lpDir ? ((CURSORICONDIR*)lpDir)->idCount : 0);
 
     switch(resType)
     {
diff --git a/objects/dib.c b/objects/dib.c
index 88cb033..3c1be2e 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -27,7 +27,7 @@
 {
     DC               *dc;
     LPCVOID           bits;
-    DWORD             lines;
+    int               lines;
     DWORD             infoWidth;
     WORD              depth;
     WORD              infoBpp;
@@ -145,7 +145,7 @@
  * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
  */
 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
-                              DWORD *height, WORD *bpp )
+                              int *height, WORD *bpp )
 {
     if (header->biSize == sizeof(BITMAPINFOHEADER))
     {
@@ -235,50 +235,66 @@
     return colorMapping;
 }
 
+/***********************************************************************
+ *           DIB_SetImageBits_1_Line
+ *
+ * Handles a single line of 1 bit data.
+ */
+static void DIB_SetImageBits_1_Line(DWORD dstwidth, int *colors,
+				    XImage *bmpImage, int h, const BYTE *bits)
+{
+    BYTE pix;
+    DWORD i, x;
+
+    for (i = dstwidth/8, x = 0; (i > 0); i--)
+    {
+	pix = *bits++;
+	XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
+	XPutPixel( bmpImage, x++, h, colors[(pix >> 6) & 1] );
+	XPutPixel( bmpImage, x++, h, colors[(pix >> 5) & 1] );
+	XPutPixel( bmpImage, x++, h, colors[(pix >> 4) & 1] );
+	XPutPixel( bmpImage, x++, h, colors[(pix >> 3) & 1] );
+	XPutPixel( bmpImage, x++, h, colors[(pix >> 2) & 1] );
+	XPutPixel( bmpImage, x++, h, colors[(pix >> 1) & 1] );
+	XPutPixel( bmpImage, x++, h, colors[pix & 1] );
+    }
+    pix = *bits;
+    switch(dstwidth & 7)
+    {
+    case 7: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
+    case 6: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
+    case 5: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
+    case 4: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
+    case 3: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
+    case 2: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
+    case 1: XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
+    }
+}
 
 /***********************************************************************
  *           DIB_SetImageBits_1
  *
  * SetDIBits for a 1-bit deep DIB.
  */
-static void DIB_SetImageBits_1( DWORD lines, const BYTE *srcbits,
+static void DIB_SetImageBits_1( int lines, const BYTE *srcbits,
                                 DWORD srcwidth, DWORD dstwidth,
                                 int *colors, XImage *bmpImage )
 {
-    DWORD i, x;
-    BYTE pix;
-    const BYTE *bits = srcbits;
+    int h;
 
     /* 32 bit aligned */
     DWORD linebytes = ((srcwidth + 31) & ~31) / 8;
 
-    while (lines--)
-    {
-	for (i = dstwidth/8, x = 0; (i > 0); i--)
-	{
-	    pix = *bits++;
-	    XPutPixel( bmpImage, x++, lines, colors[pix >> 7] );
-	    XPutPixel( bmpImage, x++, lines, colors[(pix >> 6) & 1] );
-	    XPutPixel( bmpImage, x++, lines, colors[(pix >> 5) & 1] );
-	    XPutPixel( bmpImage, x++, lines, colors[(pix >> 4) & 1] );
-	    XPutPixel( bmpImage, x++, lines, colors[(pix >> 3) & 1] );
-	    XPutPixel( bmpImage, x++, lines, colors[(pix >> 2) & 1] );
-	    XPutPixel( bmpImage, x++, lines, colors[(pix >> 1) & 1] );
-	    XPutPixel( bmpImage, x++, lines, colors[pix & 1] );
+    if (lines > 0) {
+	for (h = lines-1; h >=0; h--) {
+	    DIB_SetImageBits_1_Line(dstwidth, colors, bmpImage, h, srcbits);
+	    srcbits += linebytes;
 	}
-	pix = *bits;
-	switch(dstwidth & 7)
-	{
-	case 7: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
-	case 6: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
-	case 5: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
-	case 4: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
-	case 3: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
-	case 2: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
-	case 1: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] );
+    } else {
+	for (h = 0; h < lines; h++) {
+	    DIB_SetImageBits_1_Line(dstwidth, colors, bmpImage, h, srcbits);
+	    srcbits += linebytes;
 	}
-	srcbits += linebytes;
-	bits	 = srcbits;
     }
 }
 
@@ -288,27 +304,39 @@
  *
  * SetDIBits for a 4-bit deep DIB.
  */
-static void DIB_SetImageBits_4( DWORD lines, const BYTE *srcbits,
+static void DIB_SetImageBits_4( int lines, const BYTE *srcbits,
                                 DWORD srcwidth, DWORD dstwidth,
                                 int *colors, XImage *bmpImage )
 {
     DWORD i, x;
+    int h;
     const BYTE *bits = srcbits;
   
     /* 32 bit aligned */
     DWORD linebytes = ((srcwidth+7)&~7)/2;
 
-    while (lines--)
-    {
-	for (i = dstwidth/2, x = 0; i > 0; i--)
-	{
-	    BYTE pix = *bits++;
-	    XPutPixel( bmpImage, x++, lines, colors[pix >> 4] );
-	    XPutPixel( bmpImage, x++, lines, colors[pix & 0x0f] );
+    if (lines > 0) {
+	for (h = lines-1; h >= 0; h--) {
+	    for (i = dstwidth/2, x = 0; i > 0; i--) {
+		BYTE pix = *bits++;
+		XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
+		XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
+	    }
+	    if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
+	    srcbits += linebytes;
+	    bits	 = srcbits;
 	}
-        if (dstwidth & 1) XPutPixel( bmpImage, x, lines, colors[*bits >> 4] );
-        srcbits += linebytes;
-        bits	 = srcbits;
+    } else {
+	for (h = 0; h < lines; h++) {
+	    for (i = dstwidth/2, x = 0; i > 0; i--) {
+		BYTE pix = *bits++;
+		XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
+		XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
+	    }
+	    if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
+	    srcbits += linebytes;
+	    bits	 = srcbits;
+	}
     }
 }
 
@@ -324,7 +352,7 @@
  *
  * SetDIBits for a 4-bit deep compressed DIB.
  */
-static void DIB_SetImageBits_RLE4( DWORD lines, const BYTE *bits, DWORD width,
+static void DIB_SetImageBits_RLE4( int lines, const BYTE *bits, DWORD width,
                                 DWORD dstwidth, int *colors, XImage *bmpImage )
 {
 	int x = 0, c, length;
@@ -384,22 +412,32 @@
  *
  * SetDIBits for an 8-bit deep DIB.
  */
-static void DIB_SetImageBits_8( DWORD lines, const BYTE *srcbits,
-                                DWORD srcwidth, DWORD dstwidth,
+static void DIB_SetImageBits_8( int lines, const BYTE *srcbits,
+				DWORD srcwidth, DWORD dstwidth,
                                 int *colors, XImage *bmpImage )
 {
     DWORD x;
+    int h;
     const BYTE *bits = srcbits;
 
     /* align to 32 bit */
     DWORD linebytes = (srcwidth + 3) & ~3;
 
-    while (lines--)
-    {
-	for (x = 0; x < dstwidth; x++)
-	    XPutPixel( bmpImage, x, lines, colors[*bits++] );
-        srcbits += linebytes;
-        bits     = srcbits;
+    if (lines > 0) {
+	for (h = lines - 1; h >= 0; h--) {
+	    for (x = 0; x < dstwidth; x++, bits++) {
+		XPutPixel( bmpImage, x, h, colors[*bits] );
+	    }
+	    bits = (srcbits += linebytes);
+	}
+    } else {
+	lines = -lines;
+	for (h = 0; h < lines; h++) {
+	    for (x = 0; x < dstwidth; x++, bits++) {
+		XPutPixel( bmpImage, x, h, colors[*bits] );
+	    }
+	    bits = (srcbits += linebytes);
+	}
     }
 }
 
@@ -434,7 +472,7 @@
   RleDelta	= 2		/* Delta */
 };
   
-static void DIB_SetImageBits_RLE8( DWORD lines, const BYTE *bits, DWORD width,
+static void DIB_SetImageBits_RLE8( int lines, const BYTE *bits, DWORD width,
                                 DWORD dstwidth, int *colors, XImage *bmpImage )
 {
     int x;			/* X-positon on each line.  Increases. */
@@ -583,29 +621,123 @@
 
 
 /***********************************************************************
+ *           DIB_SetImageBits_16
+ *
+ * SetDIBits for a 16-bit deep DIB.
+ */
+static void DIB_SetImageBits_16( int lines, const BYTE *srcbits,
+                                 DWORD srcwidth, DWORD dstwidth,
+				 DC *dc, XImage *bmpImage )
+{
+    DWORD x;
+    LPWORD ptr;
+    WORD val;
+    int h;
+    BYTE r, g, b;
+  
+    /* align to 32 bit */
+    DWORD linebytes = (srcwidth * 2 + 3) & ~3;
+
+    ptr = (LPWORD) srcbits;
+    if (lines > 0) {
+	for (h = lines - 1; h >= 0; h--) {
+	    for (x = 0; x < dstwidth; x++, ptr++) {
+		val = *ptr;
+		r = (BYTE) ((val & 0x7c00) >> 7);
+		g = (BYTE) ((val & 0x03e0) >> 2);
+		b = (BYTE) ((val & 0x001f) << 3);
+		XPutPixel( bmpImage, x, h,
+			   COLOR_ToPhysical(dc, RGB(r,g,b)) );
+	    }
+	    ptr = (LPWORD) (srcbits += linebytes);
+	}
+    } else {
+	lines = -lines;
+	for (h = 0; h < lines; h++) {
+	    for (x = 0; x < dstwidth; x++, ptr++) {
+		val = *ptr;
+		r = (BYTE) ((val & 0x7c00) >> 7);
+		g = (BYTE) ((val & 0x03e0) >> 2);
+		b = (BYTE) ((val & 0x001f) << 3);
+		XPutPixel( bmpImage, x, h,
+			   COLOR_ToPhysical(dc, RGB(r,g,b)) );
+	    }
+	    ptr = (LPWORD) (srcbits += linebytes);
+	}
+    }
+}
+
+
+/***********************************************************************
  *           DIB_SetImageBits_24
  *
  * SetDIBits for a 24-bit deep DIB.
  */
-static void DIB_SetImageBits_24( DWORD lines, const BYTE *srcbits,
+static void DIB_SetImageBits_24( int lines, const BYTE *srcbits,
                                  DWORD srcwidth, DWORD dstwidth,
 				 DC *dc, XImage *bmpImage )
 {
     DWORD x;
     const BYTE *bits = srcbits;
+    int h;
   
     /* align to 32 bit */
     DWORD linebytes = (srcwidth * 3 + 3) & ~3;
 
     /* "bits" order is reversed for some reason */
 
-    while (lines--)
-    {
-	for (x = 0; x < dstwidth; x++, bits += 3)
-	    XPutPixel( bmpImage, x, lines, 
-		       COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])) );
+    if (lines > 0) {
+	for (h = lines - 1; h >= 0; h--) {
+	    for (x = 0; x < dstwidth; x++, bits += 3) {
+		XPutPixel( bmpImage, x, h, 
+			   COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
+	    }
+	    bits = (srcbits += linebytes);
+	}
+    } else {
+	lines = -lines;
+	for (h = 0; h < lines; h++) {
+	    for (x = 0; x < dstwidth; x++, bits += 3) {
+		XPutPixel( bmpImage, x, h,
+			   COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
+	    }
+	    bits = (srcbits += linebytes);
+	}
+    }
+}
 
-        bits = (srcbits += linebytes);
+
+/***********************************************************************
+ *           DIB_SetImageBits_32
+ *
+ * SetDIBits for a 32-bit deep DIB.
+ */
+static void DIB_SetImageBits_32( int lines, const BYTE *srcbits,
+                                 DWORD srcwidth, DWORD dstwidth,
+				 DC *dc, XImage *bmpImage )
+{
+    DWORD x;
+    const BYTE *bits = srcbits;
+    int h;
+  
+    DWORD linebytes = (srcwidth * 4);
+
+    if (lines > 0) {
+	for (h = lines - 1; h >= 0; h--) {
+	    for (x = 0; x < dstwidth; x++, bits += 4) {
+		XPutPixel( bmpImage, x, h, 
+			   COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
+	    }
+	    bits = (srcbits += linebytes);
+	}
+    } else {
+	for (h = 0; h < lines; h++) {
+	    for (x = 0; x < dstwidth; x++, bits += 4) {
+		XPutPixel( bmpImage, x, h,
+			   COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
+	    }
+	    bits = (srcbits += linebytes);
+	}
     }
 }
 
@@ -621,6 +753,7 @@
     int *colorMapping;
     XImage *bmpImage;
     DWORD compression = 0;
+    int lines;
 
     if (descr->info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
         compression = descr->info->bmiHeader.biCompression;
@@ -635,7 +768,9 @@
     if( descr->dc->w.flags & DC_DIRTY ) CLIPPING_UpdateGCRegion(descr->dc);
 
       /* Transfer the pixels */
-    XCREATEIMAGE(bmpImage, descr->infoWidth, descr->lines, descr->depth );
+    lines = descr->lines;
+    if (lines < 0) lines = -lines;
+    XCREATEIMAGE(bmpImage, descr->infoWidth, lines, descr->depth );
 
     switch(descr->infoBpp)
     {
@@ -657,10 +792,19 @@
 	else DIB_SetImageBits_8( descr->lines, descr->bits, descr->infoWidth,
                                  descr->width, colorMapping, bmpImage );
 	break;
+    case 15:
+    case 16:
+	DIB_SetImageBits_16( descr->lines, descr->bits, descr->infoWidth,
+			     descr->width, descr->dc, bmpImage);
+	break;
     case 24:
 	DIB_SetImageBits_24( descr->lines, descr->bits, descr->infoWidth,
                              descr->width, descr->dc, bmpImage );
 	break;
+    case 32:
+	DIB_SetImageBits_32( descr->lines, descr->bits, descr->infoWidth,
+                             descr->width, descr->dc, bmpImage);
+	break;
     default:
         fprintf( stderr, "Invalid depth %d for SetDIBits!\n", descr->infoBpp );
         break;
@@ -670,7 +814,7 @@
                descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
                descr->width, descr->height );
     XDestroyImage( bmpImage );
-    return descr->lines;
+    return lines;
 }
 
 
@@ -732,7 +876,7 @@
 {
     DIB_SETIMAGEBITS_DESCR descr;
     BITMAPOBJ * bmp;
-    DWORD height;
+    int height, tmpheight;
     INT32 result;
 
       /* Check parameters */
@@ -755,6 +899,8 @@
         GDI_HEAP_UNLOCK( hdc );
         return 0;
     }
+    tmpheight = height;
+    if (height < 0) height = -height;
     if (!lines || (startscan >= height))
     {
         GDI_HEAP_UNLOCK( hbitmap );
@@ -764,7 +910,7 @@
     if (startscan + lines > height) lines = height - startscan;
 
     descr.bits      = bits;
-    descr.lines     = lines;
+    descr.lines     = tmpheight >= 0 ? lines : -lines;
     descr.depth     = bmp->bitmap.bmBitsPixel;
     descr.info      = info;
     descr.coloruse  = coloruse;
@@ -807,7 +953,8 @@
 {
     DIB_SETIMAGEBITS_DESCR descr;
     DC * dc;
-    DWORD width, height;
+    DWORD width;
+    int height, tmpheight;
 
       /* Check parameters */
 
@@ -820,6 +967,8 @@
     if (DIB_GetBitmapInfo( &info->bmiHeader, &width,
                            &height, &descr.infoBpp ) == -1)
         return 0;
+    tmpheight = height;
+    if (height < 0) height = -height;
     if (!lines || (startscan >= height)) return 0;
     if (startscan + lines > height) lines = height - startscan;
     if (ySrc < startscan) ySrc = startscan;
@@ -834,7 +983,7 @@
 
     descr.dc        = dc;
     descr.bits      = bits;
-    descr.lines     = lines;
+    descr.lines     = tmpheight >= 0 ? lines : -lines;
     descr.infoWidth = width;
     descr.depth     = dc->w.bitsPerPixel;
     descr.info      = info;
@@ -851,7 +1000,92 @@
     return CALL_LARGE_STACK( DIB_SetImageBits, &descr );
 }
 
+/***********************************************************************
+ *           SetDIBColorTable32    (GDI32.311)
+ */
+UINT32 WINAPI SetDIBColorTable32( HDC32 hdc, UINT32 startpos, UINT32 entries,
+				  RGBQUAD *colors )
+{
+    DC * dc;
+    PALETTEENTRY * palEntry;
+    PALETTEOBJ * palette;
+    RGBQUAD *end;
 
+    dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) 
+    {
+	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
+	if (!dc) return 0;
+    }
+
+    if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
+    {
+        return 0;
+    }
+
+    /* Transfer color info */
+    
+    if (dc->w.bitsPerPixel <= 8) {
+	palEntry = palette->logpalette.palPalEntry + startpos;
+	if (startpos + entries > (1 << dc->w.bitsPerPixel)) {
+	    entries = (1 << dc->w.bitsPerPixel) - startpos;
+	}
+	for (end = colors + entries; colors < end; palEntry++, colors++)
+	{
+	    palEntry->peRed   = colors->rgbRed;
+	    palEntry->peGreen = colors->rgbGreen;
+	    palEntry->peBlue  = colors->rgbBlue;
+	}
+    } else {
+	entries = 0;
+    }
+    GDI_HEAP_UNLOCK( dc->w.hPalette );
+    return entries;
+}
+
+/***********************************************************************
+ *           GetDIBColorTable32    (GDI32.169)
+ */
+UINT32 WINAPI GetDIBColorTable32( HDC32 hdc, UINT32 startpos, UINT32 entries,
+				  RGBQUAD *colors )
+{
+    DC * dc;
+    PALETTEENTRY * palEntry;
+    PALETTEOBJ * palette;
+    RGBQUAD *end;
+
+    dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) 
+    {
+	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
+	if (!dc) return 0;
+    }
+
+    if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
+    {
+        return 0;
+    }
+
+    /* Transfer color info */
+    
+    if (dc->w.bitsPerPixel <= 8) {
+	palEntry = palette->logpalette.palPalEntry + startpos;
+	if (startpos + entries > (1 << dc->w.bitsPerPixel)) {
+	    entries = (1 << dc->w.bitsPerPixel) - startpos;
+	}
+	for (end = colors + entries; colors < end; palEntry++, colors++)
+	{
+	    colors->rgbRed      = palEntry->peRed;
+	    colors->rgbGreen    = palEntry->peGreen;
+	    colors->rgbBlue     = palEntry->peBlue;
+	    colors->rgbReserved = 0;
+	}
+    } else {
+	entries = 0;
+    }
+    GDI_HEAP_UNLOCK( dc->w.hPalette );
+    return entries;
+}
 
 /***********************************************************************
  *           GetDIBits16    (GDI.441)
@@ -1018,6 +1252,18 @@
 		   bbits += pad;
 		}
 		break;
+	   case 32:
+		for( y = yend - 1; (int)y >= (int)startscan; y-- )
+		{
+		   *bbits = 0;
+		   for( x = 0; x < xend; x++ ) {
+		   	unsigned long pixel=XGetPixel( bmpImage, x, y);
+			*bbits++ = (pixel >>16) & 0xff;
+			*bbits++ = (pixel >> 8) & 0xff;
+			*bbits++ =  pixel       & 0xff;
+		   }
+		}
+		break;
 	   default:
 	   	fprintf(stderr,"GetDIBits*: unsupported depth %d\n",
 			info->bmiHeader.biBitCount
@@ -1069,10 +1315,12 @@
 {
     HBITMAP32 handle;
     BOOL32 fColor;
-    DWORD width, height;
+    DWORD width;
+    int height;
     WORD bpp;
 
     if (DIB_GetBitmapInfo( header, &width, &height, &bpp ) == -1) return 0;
+    if (height < 0) height = -height;
 
     /* Check if we should create a monochrome or color bitmap. */
     /* We create a monochrome bitmap only if it has exactly 2  */
diff --git a/objects/font.c b/objects/font.c
index f65f016..124663e 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -1189,3 +1189,21 @@
     return TRUE;
 }
 
+
+/*************************************************************************
+ *             GetFontLanguageInfo   (GDI32.182)
+ */
+DWORD WINAPI GetFontLanguageInfo32(HDC32 hdc) {
+	/* return value 0 is correct for most cases anyway */
+	fprintf(stderr,"GetFontLanguageInfo:stub!\n");
+	return 0;
+}
+
+/*************************************************************************
+ *             GetFontLanguageInfo   (GDI.616)
+ */
+DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
+	/* return value 0 is correct for most cases anyway */
+	fprintf(stderr,"GetFontLanguageInfo:stub!\n");
+	return 0;
+}
diff --git a/objects/text.c b/objects/text.c
index 7844d8a..04f8f8b 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -636,7 +636,7 @@
 }
 
 /***********************************************************************
- *           GetTextCharset    (USER32.226) (USER.612)
+ *           GetTextCharset    (GDI32.226) (GDI.612)
  */
 INT32 WINAPI GetTextCharset32(HDC32 hdc)
 {
@@ -648,3 +648,15 @@
 {
     return GetTextCharset32(hdc);
 }
+
+/***********************************************************************
+ *           GetTextCharsetInfo    (GDI32.381)
+ */
+INT32 WINAPI GetTextCharsetInfo(HDC32 hdc,LPCHARSETINFO csi,DWORD flags)
+{
+    fprintf(stdnimp,"GetTextCharsetInfo(0x%x,%p,%08lx), stub!\n",hdc,csi,flags);
+    csi->ciCharset = DEFAULT_CHARSET;
+    csi->ciACP = GetACP();
+    /* ... fill fontstruct too ... */
+    return DEFAULT_CHARSET;
+}