Release 0.3.0

Fri Sep  3 11:52:18 1993  Bob Amstadt

	* [windows/timer.c]
	Changed to use CallWindowProc() rather directly calling callback.

	* [windows/event.c]
	Implemented SetCapture() and ReleaseCapture()

	* [windows/keyboard.c]
	Created stub for GetKeyState()

	* [objects/linedda.c]
	Created stub for LineDDA()

	* [if1632/callback.c]
	Created callback handler for LineDDA callback procedure.

	* [if1632/callback.c]
	Created FreeProcInstance()

Fri Sep  3 08:36:52 1993  David Metcalfe

	* [loader/signal.c]
	Patch to and code for INT 1A

Thu Sep  2 00:31:54 1993  Alexandre Julliard

	* [objects/font.c] [objects/text.c]
	More text support: implemented justification and underlining.

	* [windows/clipping.c] [objects/clipping.c]
	Moved low-level clipping functions to objects/clipping.c.

	* [windows/clipping.c] [windows/event.c] [windows/message.c]
	Implemented window update regions.

	* [windows/dc.c] [objects/dcvalues.c]
	Moved some device-independent DC functions to objects/dcvalues.c.

	* [windows/graphics.c]
	Implemented InvertRect() and GetPixel().

Sat Aug 28 08:40:23 1993  Eric Youngdale

	* [include/neexe.h] [loader/wine.c]
	Added code to handle relocation type 4.

	* [loader/signal.h] [loader/wine.c] [loader/selector.c]
	Added support for dos interrupts.

Thu 26 Aug 19:15:00 1993  Eric Youngdale

	* [loader/selector.c]
	Fixed bug dealing with loading DLLs.

Thu Aug 26 19:22:40 1993  Alexandre Julliard

        * [include/gdi.h] [objects/font.c] [windows/dc.c]
        Beginning of real font support.

        * [windows/graphics.c]
        Implemented PatBlt().

        * [memory/global.c]
        Corrected a bug with linked list handling in GlobalAlloc().

        * [objects/bitmap.c]
        Corrected a bug in BITMAP_SelectObject().

Tue Aug 24 19:22:40 1993  David Metcalfe

        * [controls/Command*] [controls/Label*] [controls[MenuButto*]
	  [controls/SmeMenuButt*]
	Change code to support & as a special character in menu item text.

Tue Aug 24 19:22:40 1993  Alexandre Julliard

	* [include/gdi.h] [windows/dc.c]
	Heavily modified the DC structure for better device-independence.

	* [objects/bitmap.c]
	Implemented bitmap dimensions.

	* [windows/dc.c] [windows/dce.c]
	Implemented DC state saving and restoring.

	* [windows/dc.c]
	Implemented ROP mode.

	* [windows/graphics.c]
	Implemented FillRect().

Mon Aug 23 22:08:34 1993  Bob Amstadt  (bob at pooh)

	* [misc/xt.c]
	Fixed bug in InvalidateRect().  Solitaire attempted to
	clear window before it was realized.

	* [loader/resource.c]
	Began rewrite of LoadBitmap().

	* [loader/wine.c]
	Fixed code which set Argv and Argc global variables.

	* [loader/selector.c]
	Added code to set up command line arguments.

	* [include/neexe.h]
	Fixed error in PSP structure.

Tue Aug 17 20:41:12 1993  Alexandre Julliard

	* [include/gdi.h] [windows/dc.c]
	Implemented device capabilities.

	* [objects/region.c]
	Implemented EqualRgn() and CombineRgn().

	* [windows/clipping.c]
	Implemented Save/RestoreVisRgn().

	* [windows/graphics.c]
	Implemented PaintRgn() and FillRgn().

	* [windows/mapping.c]
	Implemented mapping modes.

Tue Aug 10 14:07:38 1993  Alexandre Julliard

	* [if1632/user.spec] [misc/rect.c]
	Implemented rectangle API functions.

	* [if1632/gdi.spec] [include/gdi.h] [objects/region.c]
	Implemented regions.

	* [windows/class.c]
	Corrected a typo in UnregisterClass().

	* [windows/clipping.c] [windows/dc.c]
	Implemented DC clipping and visible region.

Tue Aug 10 20:57:56 1993  Bob Amstadt  (bob at pooh)

	* [controls/menu.c] [windows/win.c]
	SetMenu(), GetMenu(), CheckMenuItem() implemented

Thu Aug  5 22:33:22 1993  Bob Amstadt  (bob at pooh)

	* [controls/menu.c] [windows/win.c]
	Many improvements menus.  LoadMenu() should work.

Wed Aug  4 14:55:36 1993  Alexandre Julliard

        * [objects/dib.c]
        Started the implementation of device-independent bitmaps.

        * [objects/bitmap.c]
        Added support for multiple bitmap depths.

        * [objects/brush.c]
        Implemented pattern brushes.

        * [windows/dc.c] [windows/graphics.c]
        Implemented some GDI graphics primitives.

Tue Aug  3 21:16:47 1993  Bob Amstadt  (bob at pooh)

	* [controls/menu.c] [windows/win.c] [include/menu.h]
	Code to load class menus from executable file.

	* [if1632/user.spec]
	Fixed specification of SendMessage() and PostMessage.

Mon Jul 26 21:53:24 1993  Alexandre Julliard

	* [if1632/call.S]
	Corrected a bug in KERNEL_InitTask().

	* [include/windows.h]
	Added a lot of constants.

	* [loader/selector.c]
	Corrected a bug in segment allocation in CreateSelectors().

	* [objects/bitmap.c]
	Implemented SelectObject() for bitmaps.

	* [objects/brush.c]
	Implemented hatched brushes and SelectObject().

	* [objects/gdiobj.c]
	Removed linked list (not needed).

	* [objects/palette.c]
	Implemented system palette creation and misc. palette API functions.

	* [windows/timer.c]
	Implemented timers.

	* [windows/dc.c]
	Implemented memory device contexts.

Tue Jul 20 10:38:59 1993  Bob Amstadt  (bob at pooh)

        * [dos.c]
	Split DOS3Call() out of kernel.c.  Added support for get date
	and time functions.

	* [call.S]
	Added function ReturnFromRegisterFunc() to allow DOS calls
	to return values in registers.

	* [regfunc.h]
	Macros to access registers saved on stack.

Tue Jul 20 10:38:59 1993  Alexandre Julliard

        * [win.c]
        Corrected allocation of the WM_CREATE data structure.

        * [dce.c] [dce.h]
        Implemented DCE handling.

        * [bitmap.c] [brush.c] [dc.c] [font.c] [gdi.h] [gdi.spec] 
          [gdiobj.c] [palette.c] [pen.c]
        Implemented the GDI objects data structures and allocation.

        * [windows.h]
        Added several structures and constants for GDI objects.

Mon Jul 19 12:51:10 1993  Bob Amstadt  (bob at pooh)

	* [ldtlib.c]
	Modified system calls to match Linus' new interface for
	the LDT modification.

	* [win.c]
	Fixed bug with WM_CREATE message.

	* [heap.c] [kernel.spec]
	Completed local heap allocation functions.

	* [global.c]
	Created function GlobalQuickAlloc() for easy allocation from DLLs
diff --git a/loader/resource.c b/loader/resource.c
new file mode 100644
index 0000000..f469a48
--- /dev/null
+++ b/loader/resource.c
@@ -0,0 +1,393 @@
+static char RCSId[] = "$Id: resource.c,v 1.4 1993/07/04 04:04:21 root Exp root $";
+static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "prototypes.h"
+#include "neexe.h"
+#include "windows.h"
+#include "gdi.h"
+
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+
+/**********************************************************************
+ *					ConvertCoreBitmap
+ */
+HBITMAP
+ConvertCoreBitmap( HDC hdc, BITMAPCOREHEADER * image )
+{
+    BITMAPINFO * bmpInfo;
+    HBITMAP hbitmap;
+    char * bits;
+    int i, size, n_colors;
+    
+    n_colors = 1 << image->bcBitCount;
+
+    if (image->bcBitCount < 24)
+    {
+	size = sizeof(BITMAPINFOHEADER) + n_colors * sizeof(RGBQUAD);	
+	bits = (char *) (image + 1) + (n_colors * sizeof(RGBTRIPLE));
+    }
+    else
+    {
+	size = sizeof(BITMAPINFOHEADER);
+	bits = (char *) (image + 1);
+    }
+    bmpInfo = (BITMAPINFO *) malloc( size );
+
+    bmpInfo->bmiHeader.biSize          = sizeof(BITMAPINFOHEADER);
+    bmpInfo->bmiHeader.biWidth         = image->bcWidth;
+    bmpInfo->bmiHeader.biHeight        = image->bcHeight;
+    bmpInfo->bmiHeader.biPlanes        = image->bcPlanes;
+    bmpInfo->bmiHeader.biBitCount      = image->bcBitCount;
+    bmpInfo->bmiHeader.biCompression   = 0;
+    bmpInfo->bmiHeader.biSizeImage     = 0;
+    bmpInfo->bmiHeader.biXPelsPerMeter = 0;
+    bmpInfo->bmiHeader.biYPelsPerMeter = 0;
+    bmpInfo->bmiHeader.biClrUsed       = 0;
+    bmpInfo->bmiHeader.biClrImportant  = 0;
+
+    if (image->bcBitCount < 24)
+    {
+	RGBTRIPLE * oldMap = (RGBTRIPLE *)(image + 1);
+	RGBQUAD * newMap = bmpInfo->bmiColors;
+	for (i = 0; i < n_colors; i++, oldMap++, newMap++)
+	{
+	    newMap->rgbRed      = oldMap->rgbtRed;
+	    newMap->rgbGreen    = oldMap->rgbtGreen;
+	    newMap->rgbBlue     = oldMap->rgbtBlue;
+	    newMap->rgbReserved = 0;
+	}
+    }
+
+    hbitmap = CreateDIBitmap( hdc, &bmpInfo->bmiHeader, CBM_INIT,
+			      bits, bmpInfo, DIB_RGB_COLORS );
+    free( bmpInfo );
+    return hbitmap;
+}
+
+/**********************************************************************
+ *					ConvertInfoBitmap
+ */
+HBITMAP
+ConvertInfoBitmap( HDC hdc, BITMAPINFO * image )
+{
+    char * bits = ((char *)image) + DIB_BitmapInfoSize(image, DIB_RGB_COLORS);
+    return CreateDIBitmap( hdc, &image->bmiHeader, CBM_INIT,
+			   bits, image, DIB_RGB_COLORS );
+} 
+
+/**********************************************************************
+ *					FindResourceByNumber
+ */
+int
+FindResourceByNumber(struct resource_nameinfo_s *result_p,
+		     int type_id, int resource_id)
+{
+    struct resource_typeinfo_s typeinfo;
+    struct resource_nameinfo_s nameinfo;
+    unsigned short size_shift;
+    int i;
+
+    /*
+     * Move to beginning of resource table.
+     */
+    lseek(CurrentNEFile, (CurrentMZHeader->ne_offset +
+			  CurrentNEHeader->resource_tab_offset), SEEK_SET);
+    
+    /*
+     * Read block size.
+     */
+    if (read(CurrentNEFile, &size_shift, sizeof(size_shift)) != 
+	sizeof(size_shift))
+    {
+	return -1;
+    }
+    
+    /*
+     * Find resource.
+     */
+    typeinfo.type_id = 0xffff;
+    while (typeinfo.type_id != 0)
+    {
+	if (read(CurrentNEFile, &typeinfo, sizeof(typeinfo)) !=
+	    sizeof(typeinfo))
+	{
+	    return -1;
+	}
+	if (typeinfo.type_id != 0)
+	{
+	    for (i = 0; i < typeinfo.count; i++)
+	    {
+		if (read(CurrentNEFile, &nameinfo, sizeof(nameinfo)) != 
+		    sizeof(nameinfo))
+		{
+		    return -1;
+		}
+
+#if defined(DEBUG_RESOURCE) && defined(VERBOSE_DEBUG)
+		if (type_id == typeinfo.type_id)
+		{
+		    printf("FindResource: type id = %d, resource id = %x\n",
+			   type_id, nameinfo.id);
+		}
+#endif
+		if ((type_id == -1 || typeinfo.type_id == type_id) &&
+		    nameinfo.id == resource_id)
+		{
+		    memcpy(result_p, &nameinfo, sizeof(nameinfo));
+		    return size_shift;
+		}
+	    }
+	}
+    }
+    
+    return -1;
+}
+
+/**********************************************************************
+ *					FindResourceByName
+ */
+int
+FindResourceByName(struct resource_nameinfo_s *result_p,
+		     int type_id, char *resource_name)
+{
+    struct resource_typeinfo_s typeinfo;
+    struct resource_nameinfo_s nameinfo;
+    unsigned short size_shift;
+    off_t old_pos, new_pos;
+    unsigned char nbytes;
+    char name[256];
+    int i;
+
+    /*
+     * Move to beginning of resource table.
+     */
+    lseek(CurrentNEFile, (CurrentMZHeader->ne_offset +
+			  CurrentNEHeader->resource_tab_offset), SEEK_SET);
+    
+    /*
+     * Read block size.
+     */
+    if (read(CurrentNEFile, &size_shift, sizeof(size_shift)) != 
+	sizeof(size_shift))
+    {
+	return -1;
+    }
+    
+    /*
+     * Find resource.
+     */
+    typeinfo.type_id = 0xffff;
+    while (typeinfo.type_id != 0)
+    {
+	if (read(CurrentNEFile, &typeinfo, sizeof(typeinfo)) !=
+	    sizeof(typeinfo))
+	{
+	    return -1;
+	}
+	if (typeinfo.type_id == type_id || type_id == -1)
+	{
+	    for (i = 0; i < typeinfo.count; i++)
+	    {
+		if (read(CurrentNEFile, &nameinfo, sizeof(nameinfo)) != 
+		    sizeof(nameinfo))
+		{
+		    return -1;
+		}
+
+		if (nameinfo.id & 0x8000)
+		    continue;
+		
+		old_pos = lseek(CurrentNEFile, 0, SEEK_CUR);
+		new_pos = (CurrentMZHeader->ne_offset +
+			   CurrentNEHeader->resource_tab_offset +
+			   nameinfo.id);
+		lseek(CurrentNEFile, new_pos, SEEK_SET);
+		read(CurrentNEFile, &nbytes, 1);
+		read(CurrentNEFile, name, nbytes);
+		lseek(CurrentNEFile, old_pos, SEEK_SET);
+		name[nbytes] = '\0';
+
+		if (strcasecmp(name, resource_name) == 0)
+		{
+		    memcpy(result_p, &nameinfo, sizeof(nameinfo));
+		    return size_shift;
+		}
+	    }
+	}
+    }
+    
+    return -1;
+}
+
+/**********************************************************************
+ *					LoadString
+ */
+int
+LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen)
+{
+    struct resource_nameinfo_s nameinfo;
+    unsigned short target_id;
+    unsigned char string_length;
+    int size_shift;
+    int string_num;
+    int i;
+
+#ifdef DEBUG_RESOURCE
+    printf("LoadString: instance = %04x, id = %d, "
+	   "buffer = %08x, length = %d\n",
+	   instance, resource_id, buffer, buflen);
+#endif
+    
+    /*
+     * Find string entry.
+     */
+    target_id = (resource_id >> 4) + 0x8001;
+    string_num = resource_id & 0x000f;
+
+    size_shift = FindResourceByNumber(&nameinfo, NE_RSCTYPE_STRING, target_id);
+    if (size_shift == -1)
+	return 0;
+    
+    lseek(CurrentNEFile, (int) nameinfo.offset << size_shift, SEEK_SET);
+
+    for (i = 0; i < string_num; i++)
+    {
+	read(CurrentNEFile, &string_length, 1);
+	lseek(CurrentNEFile, string_length, SEEK_CUR);
+    }
+			
+    read(CurrentNEFile, &string_length, 1);
+    i = MIN(string_length, buflen - 1);
+    read(CurrentNEFile, buffer, i);
+    buffer[i] = '\0';
+#ifdef DEBUG_RESOURCE
+    printf("            '%s'\n", buffer);
+#endif
+    return i;
+}
+
+/**********************************************************************
+ *					LoadIcon
+ */
+HICON
+LoadIcon(HANDLE instance, LPSTR icon_name)
+{
+    return 0;
+}
+
+/**********************************************************************
+ *					LoadCursor
+ */
+HCURSOR
+LoadCursor(HANDLE instance, LPSTR cursor_name)
+{
+    return 0;
+}
+
+/**********************************************************************
+ *					RSC_LoadResource
+ */
+HANDLE
+RSC_LoadResource(int instance, char *rsc_name, int type, int *image_size_ret)
+{
+    struct resource_nameinfo_s nameinfo;
+    HANDLE hmem;
+    void *image;
+    int image_size;
+    int size_shift;
+    
+    /*
+     * Built-in resources
+     */
+    if (instance == 0)
+    {
+	return 0;
+    }
+    /*
+     * Get resource by ordinal
+     */
+    else if (((int) rsc_name & 0xffff0000) == 0)
+    {
+	size_shift = FindResourceByNumber(&nameinfo, type,
+					  (int) rsc_name | 0x8000);
+    }
+    /*
+     * Get resource by name
+     */
+    else
+    {
+	size_shift = FindResourceByName(&nameinfo, type, rsc_name);
+    }
+    if (size_shift == -1)
+	return 0;
+
+    /*
+     * Read resource.
+     */
+    lseek(CurrentNEFile, ((int) nameinfo.offset << size_shift), SEEK_SET);
+
+    image_size = nameinfo.length << size_shift;
+    if (image_size_ret != NULL)
+	*image_size_ret = image_size;
+    
+    hmem = GlobalAlloc(GMEM_MOVEABLE, image_size);
+    image = GlobalLock(hmem);
+    if (image == NULL || read(CurrentNEFile, image, image_size) != image_size)
+    {
+	GlobalFree(hmem);
+	return 0;
+    }
+
+    GlobalUnlock(hmem);
+    return hmem;
+}
+
+/**********************************************************************
+ *					RSC_LoadMenu
+ */
+HANDLE
+RSC_LoadMenu(HANDLE instance, LPSTR menu_name)
+{
+    return RSC_LoadResource(instance, menu_name, NE_RSCTYPE_MENU, NULL);
+}
+
+/**********************************************************************
+ *					LoadBitmap
+ */
+HBITMAP
+LoadBitmap(HANDLE instance, LPSTR bmp_name)
+{
+    HBITMAP hbitmap;
+    HANDLE rsc_mem;
+    HDC hdc;
+    long *lp;
+    int image_size;
+
+#ifdef DEBUG_RESOURCE
+    printf("LoadBitmap: instance = %04x, name = %08x\n",
+	   instance, bmp_name);
+#endif
+    
+    if (!(hdc = GetDC( 0 ))) return 0;
+
+    rsc_mem = RSC_LoadResource(instance, bmp_name, NE_RSCTYPE_BITMAP, 
+			       &image_size);
+    lp = (long *) GlobalLock(rsc_mem);
+    if (lp == NULL)
+    {
+	GlobalFree(rsc_mem);
+	return 0;
+    }
+
+    if (*lp == sizeof(BITMAPCOREHEADER))
+	hbitmap = ConvertCoreBitmap( hdc, (BITMAPCOREHEADER *) lp );
+    else if (*lp == sizeof(BITMAPINFOHEADER))
+	hbitmap = ConvertInfoBitmap( hdc, (BITMAPINFO *) lp );
+    else hbitmap = 0;
+
+    GlobalFree(rsc_mem);
+    ReleaseDC( 0, hdc );
+    return hbitmap;
+}