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
393 lines
9.2 KiB
C
393 lines
9.2 KiB
C
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;
|
||
}
|