wine/loader/resource.c
Alexandre Julliard 3f2abfaa0a Release 940815
Tue Aug  9 23:58:29 MET DST 1994	<erik@hacktic.nl>

	* [misc/file.c]
	OpenFile(): Completly rewritten.

	* [miscemu/int21.c]
	CreateFile(): Fixed wrong mode in call to open.
	OpenExistingFile(): Implemented file sharing.
	FindNext(): Fixed.
	CreateNewFile(): Fixed wrong mode in call to open.
	fLock(): Added to handle record locking.
	GetFileAttribute(): Added.
	As a result, AH = 0x5c, 0x09, and 0x0b were changed.

	* [miscemu/int2f.c]
	AH = 0x10: SHARE installation check
 
	* [loader/resource.c]
	AccessResource(): Fixed. A new file descriptor will be returned by
	every call to AccessResource().

	* [windows/utility.c]
	wvsprintf(): Fixed.

	* [controls/menu.c]
	FindMenuItem(): Fixed (handling for nPos == -1 added).	

	* [windows/win.c]
	CreateWindowEx(): Added call to WINPOS_GetMinMaxInfo.

	* [Configure]
	Added two options for a processor emulator that might be
	plugged in later..

	* [loader/task.c] [include/toolhelp.h] [if1632/toolhelp.spec]
	CreateNewTask() stores real modulename instead of 'TASKxxxx'.
	Added TaskFirst(), TaskNext(), TaskFindHandle().

	* [memory/global.c]
	Added stub for MemManInfo().

	* [objects/text.c]
	Added stub for GetTabbedTextExt().

	* [miscemu/*]
	Changed all references to registers. Please don't access
 	the context structure.
	fix for GetSystemTime() by <jspeter@birch.ee.vt.edu> added.

	* [misc/lstr.c]
	Fixed bug in AnsiUpper() & AnsiLower().

	* [misc/winsocket.c]
	bugfix in getsockopt()/setsockopt(): winsock uses different values
	than unix.

	* [objects/dib.c]
	Added DIB_SetImageBits_RLE[48] to support compressed bitmaps.

Mon Aug  8 21:12:33 1994  David Metcalfe <david@prism.demon.co.uk>

	* [controls/edit.c]
	Added support for WM_COPY, WM_CUT and WM_PASTE messages.

	* [windows/dialog.c] [windows/defdlg.c] [include/dialog.h]
	Modified dialog code to create new heap for edit controls
	unless DS_LOCALEDIT style is set.

Thu Aug  4 18:50:56 1994  Alexandre Julliard  (julliard@lamisun.epfl.ch)

	* [controls/button.c] [controls/edit.c] [controls/static.c]
	Removed unneeded GlobalUnlock() calls.

	* [controls/menu.c] [include/menu.h]
	Lots of changes, fixed a lot of old bugs and introduced a lot of
	new ones :-)
	- Changed message loop to use MSG_GetInternalMessage().
	- Fixed a bug that caused the main window to lose activation when
	  displaying a menu.
	- Correctly send initialisation messages (WM_INITMENUPOPUP).
	- Implemented EndMenu() and LookupMenuHandle().
	- Changed internal structures to be as compatible as possible with
	  MS-Windows.
	- Allocated everything on the USER heap instead of the global heap.
	- Prefixed all internal function names with MENU_ and declared
	  them static.
	- Moved "About Wine..." handling to NC_HandleSysCommand().
	- Multi-line menus should now work correctly.

	* [loader/resource.c] [objects/bitmap.c]
	Added the possibility to create OEM bitmaps directly as X bitmaps.

	* [objects/dcvalues.c] [windows/dc.c]
	Fixed GetDCOrg() to return screen coordinates.

	* [windows/message.c]
	Fixed double-click checks when the message is not removed from the
	queue.
	Fixed MSG_GetInternalMessage() to send WM_ENTERIDLE messages.

	* [windows/nonclient.c]
	Bug fix in system menu hit-test calculation.
	A few changes for new menu functions.

Thu Aug 11 17:51:02 1994  Thomas Sandford <t.d.g.sandford@bradford.ac.uk>

        * [controls/edit.c]
        Bug fix in Edit_NCCreateMessage
        es->textlen was being used before being set

        * [controls/menu.c]
        Bug fix in MENU_DrawMenuItem
        don't try to write text if NULL pointer passed
1994-08-16 15:43:11 +00:00

1250 lines
31 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "arch.h"
#include "prototypes.h"
#include "windows.h"
#include "gdi.h"
#include "wine.h"
#include "icon.h"
#include "accel.h"
#include "dlls.h"
/* #define DEBUG_RESOURCE */
#define MIN(a,b) ((a) < (b) ? (a) : (b))
typedef struct resource_s
{
struct resource_s *next;
HANDLE info_mem;
int size_shift;
struct resource_nameinfo_s nameinfo;
HANDLE rsc_mem;
} RESOURCE;
static int ResourceFd = -1;
static HANDLE ResourceInst = 0;
static struct w_files *ResourceFileInfo = NULL;
static RESOURCE *Top = NULL;
extern HINSTANCE hSysRes;
extern HBITMAP BITMAP_LoadOEMBitmap( WORD id ); /* objects/bitmap.c */
HANDLE RSC_LoadResource(int instance, char *rsc_name, int type,
int *image_size_ret);
void RSC_LoadNameTable(void);
extern char *ProgramName;
/**********************************************************************
* RSC_LoadNameTable
*/
#ifndef WINELIB
void
RSC_LoadNameTable()
{
struct resource_typeinfo_s typeinfo;
struct resource_nameinfo_s nameinfo;
unsigned short size_shift;
RESNAMTAB *top, *new;
char read_buf[1024];
char *p;
int i;
unsigned short len;
off_t rtoff;
off_t saved_pos;
top = NULL;
/*
* Move to beginning of resource table.
*/
rtoff = (ResourceFileInfo->mz_header->ne_offset +
ResourceFileInfo->ne_header->resource_tab_offset);
lseek(ResourceFd, rtoff, SEEK_SET);
/*
* Read block size.
*/
if (read(ResourceFd, &size_shift, sizeof(size_shift)) !=
sizeof(size_shift))
{
return;
}
size_shift = CONV_SHORT(size_shift);
/*
* Find resource.
*/
typeinfo.type_id = 0xffff;
while (typeinfo.type_id != 0)
{
if (!load_typeinfo (ResourceFd, &typeinfo))
break;
if (typeinfo.type_id == 0)
break;
if (typeinfo.type_id == 0x800f)
{
for (i = 0; i < typeinfo.count; i++)
{
if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) !=
sizeof(nameinfo))
{
break;
}
saved_pos = lseek(ResourceFd, 0, SEEK_CUR);
lseek(ResourceFd, (long) nameinfo.offset << size_shift,
SEEK_SET);
read(ResourceFd, &len, sizeof(len));
while (len)
{
new = (RESNAMTAB *) GlobalQuickAlloc(sizeof(*new));
new->next = top;
top = new;
read(ResourceFd, &new->type_ord, 2);
read(ResourceFd, &new->id_ord, 2);
read(ResourceFd, read_buf, len - 6);
p = read_buf + strlen(read_buf) + 1;
strncpy(new->id, p, MAX_NAME_LENGTH);
new->id[MAX_NAME_LENGTH - 1] = '\0';
read(ResourceFd, &len, sizeof(len));
}
lseek(ResourceFd, saved_pos, SEEK_SET);
}
break;
}
else
{
lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
}
}
ResourceFileInfo->resnamtab = top;
}
#endif /* WINELIB */
/**********************************************************************
* OpenResourceFile
*/
int
OpenResourceFile(HANDLE instance)
{
struct w_files *w;
char *res_file;
if (ResourceInst == instance)
return ResourceFd;
w = GetFileInfo(instance);
if (w == NULL)
return -1;
ResourceFileInfo = w;
res_file = w->filename;
if (ResourceFd >= 0)
close(ResourceFd);
ResourceInst = instance;
ResourceFd = open (res_file, O_RDONLY);
#if 1
#ifndef WINELIB
if (w->resnamtab == (RESNAMTAB *) -1)
{
RSC_LoadNameTable();
}
#endif
#endif
#ifdef DEBUG_RESOURCE
printf("OpenResourceFile(%04X) // file='%s' hFile=%04X !\n",
instance, w->filename, ResourceFd);
#endif
return ResourceFd;
}
/**********************************************************************
* 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 );
}
#ifndef WINELIB
load_typeinfo (int fd, struct resource_typeinfo_s *typeinfo)
{
return read (fd, typeinfo, sizeof (*typeinfo)) == sizeof (*typeinfo);
}
#endif
int
type_match(int type_id1, int type_id2, int fd, off_t off)
{
off_t old_pos;
unsigned char c;
size_t nbytes;
char name[256];
if (type_id1 == -1)
return 1;
if ((type_id1 & 0xffff0000) == 0) {
if ((type_id2 & 0x8000) == 0)
return 0;
return (type_id1 & 0x000f) == (type_id2 & 0x000f);
}
if ((type_id2 & 0x8000) != 0)
return 0;
#ifdef DEBUG_RESOURCE
printf("type_compare: type_id2=%04X !\n", type_id2);
#endif
old_pos = lseek(fd, 0, SEEK_CUR);
lseek(fd, off + type_id2, SEEK_SET);
read(fd, &c, 1);
nbytes = CONV_CHAR_TO_LONG (c);
#ifdef DEBUG_RESOURCE
printf("type_compare: namesize=%d\n", nbytes);
#endif
read(fd, name, nbytes);
lseek(fd, old_pos, SEEK_SET);
name[nbytes] = '\0';
#ifdef DEBUG_RESOURCE
printf("type_compare: name=`%s'\n", name);
#endif
return strcasecmp((char *) type_id1, name) == 0;
}
/**********************************************************************
* 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;
off_t rtoff;
/*
* Move to beginning of resource table.
*/
rtoff = (ResourceFileInfo->mz_header->ne_offset +
ResourceFileInfo->ne_header->resource_tab_offset);
lseek(ResourceFd, rtoff, SEEK_SET);
/*
* Read block size.
*/
if (read(ResourceFd, &size_shift, sizeof(size_shift)) !=
sizeof(size_shift))
{
printf("FindResourceByNumber (%s) bad block size !\n", resource_id);
return -1;
}
size_shift = CONV_SHORT(size_shift);
/*
* Find resource.
*/
for (;;) {
if (!load_typeinfo (ResourceFd, &typeinfo)){
printf("FindResourceByNumber (%X) bad typeinfo size !\n", resource_id);
return -1;
}
#ifdef DEBUG_RESOURCE
printf("FindResourceByNumber type=%X count=%d searched=%d \n",
typeinfo.type_id, typeinfo.count, type_id);
#endif
if (typeinfo.type_id == 0) break;
if (type_match(type_id, typeinfo.type_id, ResourceFd, rtoff)) {
for (i = 0; i < typeinfo.count; i++) {
#ifndef WINELIB
if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) !=
sizeof(nameinfo))
#else
if (!load_nameinfo (ResourceFd, &nameinfo))
#endif
{
printf("FindResourceByNumber (%X) bad nameinfo size !\n", resource_id);
return -1;
}
#ifdef DEBUG_RESOURCE
printf("FindResource: search type=%X id=%X // type=%X id=%X\n",
type_id, resource_id, typeinfo.type_id, nameinfo.id);
#endif
if (nameinfo.id == resource_id) {
memcpy(result_p, &nameinfo, sizeof(nameinfo));
return size_shift;
}
}
}
else {
lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
}
}
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;
off_t rtoff;
/*
* Check for loaded name table.
*/
if (ResourceFileInfo->resnamtab != NULL)
{
RESNAMTAB *e;
for (e = ResourceFileInfo->resnamtab; e != NULL; e = e->next)
{
if (e->type_ord == (type_id & 0x000f) &&
strcasecmp(e->id, resource_name) == 0)
{
return FindResourceByNumber(result_p, type_id, e->id_ord);
}
}
return -1;
}
/*
* Move to beginning of resource table.
*/
rtoff = (ResourceFileInfo->mz_header->ne_offset +
ResourceFileInfo->ne_header->resource_tab_offset);
lseek(ResourceFd, rtoff, SEEK_SET);
/*
* Read block size.
*/
if (read(ResourceFd, &size_shift, sizeof(size_shift)) !=
sizeof(size_shift))
{
printf("FindResourceByName (%s) bad block size !\n", resource_name);
return -1;
}
size_shift = CONV_SHORT (size_shift);
/*
* Find resource.
*/
for (;;)
{
if (!load_typeinfo (ResourceFd, &typeinfo))
{
printf("FindResourceByName (%s) bad typeinfo size !\n", resource_name);
return -1;
}
#ifdef DEBUG_RESOURCE
printf("FindResourceByName typeinfo.type_id=%X count=%d type_id=%X\n",
typeinfo.type_id, typeinfo.count, type_id);
#endif
if (typeinfo.type_id == 0) break;
if (type_match(type_id, typeinfo.type_id, ResourceFd, rtoff))
{
for (i = 0; i < typeinfo.count; i++)
{
#ifndef WINELIB
if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) !=
sizeof(nameinfo))
#else
if (!load_nameinfo (ResourceFd, &nameinfo))
#endif
{
printf("FindResourceByName (%s) bad nameinfo size !\n", resource_name);
return -1;
}
/*
if ((nameinfo.id & 0x8000) != 0) continue;
*/
#ifdef DEBUG_RESOURCE
printf("FindResourceByName // nameinfo.id=%04X !\n", nameinfo.id);
#endif
old_pos = lseek(ResourceFd, 0, SEEK_CUR);
new_pos = rtoff + nameinfo.id;
lseek(ResourceFd, new_pos, SEEK_SET);
read(ResourceFd, &nbytes, 1);
#ifdef DEBUG_RESOURCE
printf("FindResourceByName // namesize=%d !\n", nbytes);
#endif
nbytes = CONV_CHAR_TO_LONG (nbytes);
read(ResourceFd, name, nbytes);
lseek(ResourceFd, old_pos, SEEK_SET);
name[nbytes] = '\0';
#ifdef DEBUG_RESOURCE
printf("FindResourceByName type_id=%X (%d of %d) name='%s' resource_name='%s'\n",
typeinfo.type_id, i + 1, typeinfo.count,
name, resource_name);
#endif
if (strcasecmp(name, resource_name) == 0)
{
memcpy(result_p, &nameinfo, sizeof(nameinfo));
return size_shift;
}
}
}
else {
lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
}
}
return -1;
}
/**********************************************************************
* GetRsrcCount [internal]
*/
int GetRsrcCount(HINSTANCE hInst, int type_id)
{
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;
off_t rtoff;
if (hInst == 0) return 0;
#ifdef DEBUG_RESOURCE
printf("GetRsrcCount hInst=%04X typename=%08X\n", hInst, type_id);
#endif
if (OpenResourceFile(hInst) < 0) return 0;
/*
* Move to beginning of resource table.
*/
rtoff = (ResourceFileInfo->mz_header->ne_offset +
ResourceFileInfo->ne_header->resource_tab_offset);
lseek(ResourceFd, rtoff, SEEK_SET);
/*
* Read block size.
*/
if (read(ResourceFd, &size_shift, sizeof(size_shift)) != sizeof(size_shift)) {
printf("GetRsrcCount // bad block size !\n");
return -1;
}
size_shift = CONV_SHORT (size_shift);
for (;;) {
if (!load_typeinfo (ResourceFd, &typeinfo)) {
printf("GetRsrcCount // bad typeinfo size !\n");
return 0;
}
#ifdef DEBUG_RESOURCE
printf("GetRsrcCount // typeinfo.type_id=%X count=%d type_id=%X\n",
typeinfo.type_id, typeinfo.count, type_id);
#endif
if (typeinfo.type_id == 0) break;
if (type_match(type_id, typeinfo.type_id, ResourceFd, rtoff)) {
return typeinfo.count;
}
else {
lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
}
}
return 0;
}
/**********************************************************************
* LoadIcon [USER.174]
*/
HICON LoadIcon(HANDLE instance, LPSTR icon_name)
{
HICON hIcon;
HANDLE rsc_mem;
WORD *lp;
ICONDESCRIP *lpicodesc;
ICONALLOC *lpico;
int width, height;
BITMAPINFO *bmi;
BITMAPINFOHEADER *bih;
RGBQUAD *rgbq;
HBITMAP hBitMap;
HDC hMemDC;
HDC hMemDC2;
HDC hdc;
int i, j, image_size;
#ifdef DEBUG_RESOURCE
printf("LoadIcon: instance = %04x, name = %08x\n",
instance, icon_name);
#endif
if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
if (instance == (HANDLE)NULL) instance = hSysRes;
rsc_mem = RSC_LoadResource(instance, icon_name, NE_RSCTYPE_GROUP_ICON,
&image_size);
if (rsc_mem == (HANDLE)NULL) {
printf("LoadIcon / Icon %04X not Found !\n", icon_name);
ReleaseDC(GetDesktopWindow(), hdc);
return 0;
}
lp = (WORD *)GlobalLock(rsc_mem);
if (lp == NULL) {
GlobalFree(rsc_mem);
ReleaseDC(GetDesktopWindow(), hdc);
return 0;
}
lpicodesc = (ICONDESCRIP *)(lp + 3);
hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024);
if (hIcon == (HICON)NULL) {
GlobalFree(rsc_mem);
ReleaseDC(GetDesktopWindow(), hdc);
return 0;
}
lpico = (ICONALLOC *)GlobalLock(hIcon);
lpico->descriptor = *lpicodesc;
width = lpicodesc->Width;
height = lpicodesc->Height;
GlobalUnlock(rsc_mem);
GlobalFree(rsc_mem);
rsc_mem = RSC_LoadResource(instance,
MAKEINTRESOURCE(lpicodesc->icoDIBOffset),
NE_RSCTYPE_ICON, &image_size);
if (rsc_mem == (HANDLE)NULL) {
printf("LoadIcon / Icon %04X Bitmaps not Found !\n", icon_name);
ReleaseDC(GetDesktopWindow(), hdc);
return 0;
}
lp = (WORD *)GlobalLock(rsc_mem);
if (lp == NULL) {
GlobalFree(rsc_mem);
ReleaseDC(GetDesktopWindow(), hdc);
return 0;
}
bmi = (BITMAPINFO *)lp;
bih = (BITMAPINFOHEADER *)lp;
rgbq = &bmi->bmiColors[0];
bih->biHeight = bih->biHeight / 2;
/*
printf("LoadIcon / image_size=%d width=%d height=%d bih->biBitCount=%d bih->biSizeImage=%ld\n",
image_size, width, height, bih->biBitCount, bih->biSizeImage);
*/
if (bih->biSize == sizeof(BITMAPINFOHEADER))
lpico->hBitmap = ConvertInfoBitmap(hdc, (BITMAPINFO *)bih);
else
lpico->hBitmap = 0;
bih->biBitCount = 1;
bih->biClrUsed = bih->biClrImportant = 2;
rgbq[0].rgbBlue = 0xFF;
rgbq[0].rgbGreen = 0xFF;
rgbq[0].rgbRed = 0xFF;
rgbq[0].rgbReserved = 0x00;
rgbq[1].rgbBlue = 0x00;
rgbq[1].rgbGreen = 0x00;
rgbq[1].rgbRed = 0x00;
rgbq[1].rgbReserved = 0x00;
if (bih->biSizeImage == 0) {
if (bih->biCompression != BI_RGB) {
printf("Unknown size for compressed Icon bitmap.\n");
GlobalFree(rsc_mem);
ReleaseDC(GetDesktopWindow(), hdc);
return 0;
}
bih->biSizeImage = (bih->biWidth * bih->biHeight * bih->biBitCount
+ 7) / 8;
}
lpico->hBitMask = CreateDIBitmap(hdc, bih, CBM_INIT,
(LPSTR)lp + bih->biSizeImage - sizeof(BITMAPINFOHEADER) / 2 - 4,
(BITMAPINFO *)bih, DIB_RGB_COLORS );
GlobalUnlock(rsc_mem);
GlobalFree(rsc_mem);
hMemDC = CreateCompatibleDC(hdc);
hMemDC2 = CreateCompatibleDC(hdc);
SelectObject(hMemDC, lpico->hBitmap);
SelectObject(hMemDC2, lpico->hBitMask);
BitBlt(hMemDC, 0, 0, bih->biWidth, bih->biHeight, hMemDC2, 0, 0, SRCINVERT);
DeleteDC(hMemDC);
DeleteDC(hMemDC2);
ReleaseDC(GetDesktopWindow(), hdc);
GlobalUnlock(hIcon);
#ifdef DEBUG_RESOURCE
printf("LoadIcon Alloc hIcon=%X\n", hIcon);
#endif
return hIcon;
}
/**********************************************************************
* DestroyIcon [USER.457]
*/
BOOL DestroyIcon(HICON hIcon)
{
ICONALLOC *lpico;
if (hIcon == (HICON)NULL) return FALSE;
lpico = (ICONALLOC *)GlobalLock(hIcon);
if (lpico->hBitmap != (HBITMAP)NULL) DeleteObject(lpico->hBitmap);
GlobalFree(hIcon);
return TRUE;
}
/**********************************************************************
* LoadAccelerators [USER.177]
*/
HANDLE LoadAccelerators(HANDLE instance, LPSTR lpTableName)
{
HANDLE hAccel;
HANDLE rsc_mem;
BYTE *lp;
ACCELHEADER *lpAccelTbl;
int i, image_size, n;
#ifdef DEBUG_ACCEL
if (((LONG)lpTableName & 0xFFFF0000L) == 0L)
printf("LoadAccelerators: instance = %04X, name = %08X\n",
instance, lpTableName);
else
printf("LoadAccelerators: instance = %04X, name = '%s'\n",
instance, lpTableName);
#endif
if (instance == (HANDLE)NULL) instance = hSysRes;
rsc_mem = RSC_LoadResource(instance, lpTableName, NE_RSCTYPE_ACCELERATOR,
&image_size);
if (rsc_mem == (HANDLE)NULL) {
printf("LoadAccelerators / AccelTable %04X not Found !\n", lpTableName);
return 0;
}
lp = (BYTE *)GlobalLock(rsc_mem);
if (lp == NULL) {
GlobalFree(rsc_mem);
return 0;
}
#ifdef DEBUG_ACCEL
printf("LoadAccelerators / image_size=%d\n", image_size);
#endif
n = image_size/5;
hAccel = GlobalAlloc(GMEM_MOVEABLE,
sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel);
lpAccelTbl->wCount = 0;
for (i = 0; i < n; i++) {
lpAccelTbl->tbl[i].type = *(lp++);
lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
lp += 2;
lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
lp += 2;
if (lpAccelTbl->tbl[i].wEvent == 0) break;
#ifdef DEBUG_ACCEL
printf("Accelerator #%u / event=%04X id=%04X type=%02X \n",
i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval,
lpAccelTbl->tbl[i].type);
#endif
lpAccelTbl->wCount++;
}
GlobalUnlock(hAccel);
GlobalUnlock(rsc_mem);
GlobalFree(rsc_mem);
return hAccel;
}
/**********************************************************************
* TranslateAccelerator [USER.178]
*/
int TranslateAccelerator(HWND hWnd, HANDLE hAccel, LPMSG msg)
{
ACCELHEADER *lpAccelTbl;
int i, image_size;
if (hAccel == 0 || msg == NULL) return 0;
if (msg->message != WM_KEYDOWN &&
msg->message != WM_KEYUP &&
msg->message != WM_CHAR) return 0;
#ifdef DEBUG_ACCEL
printf("TranslateAccelerators hAccel=%04X !\n", hAccel);
#endif
lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel);
for (i = 0; i < lpAccelTbl->wCount; i++) {
if (lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) {
if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
msg->message == WM_KEYDOWN) {
if ((lpAccelTbl->tbl[i].type & SHIFT_ACCEL) &&
!(GetKeyState(VK_SHIFT) & 0xf)) {
GlobalUnlock(hAccel);
return 0;
}
if ((lpAccelTbl->tbl[i].type & CONTROL_ACCEL) &&
!(GetKeyState(VK_CONTROL) & 0xf)) {
GlobalUnlock(hAccel);
return 0;
}
if ((lpAccelTbl->tbl[i].type & ALT_ACCEL) &&
!(GetKeyState(VK_MENU) & 0xf)) {
GlobalUnlock(hAccel);
return 0;
}
SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
GlobalUnlock(hAccel);
return 1;
}
if (msg->message == WM_KEYUP) return 1;
}
else {
if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
msg->message == WM_CHAR) {
SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
GlobalUnlock(hAccel);
return 1;
}
}
}
GlobalUnlock(hAccel);
return 0;
}
/**********************************************************************
* FindResource [KERNEL.60]
*/
HANDLE FindResource(HANDLE instance, LPSTR resource_name, LPSTR type_name)
{
RESOURCE *r;
HANDLE rh;
int type;
if (instance == 0)
return 0;
#ifdef DEBUG_RESOURCE
printf("FindResource hInst=%04X typename=%08X resname=%08X\n",
instance, type_name, resource_name);
#endif
if (OpenResourceFile(instance) < 0)
return 0;
rh = GlobalAlloc(GMEM_MOVEABLE, sizeof(*r));
if (rh == 0)
return 0;
r = (RESOURCE *)GlobalLock(rh);
r->next = Top;
Top = r;
r->info_mem = rh;
r->rsc_mem = 0;
if (((int) type_name & 0xffff0000) == 0)
{
type = (int) type_name;
}
else if (type_name[0] == '\0')
{
type = -1;
}
else if (type_name[0] == '#')
{
type = atoi(type_name + 1);
}
else
{
type = (int) type_name;
}
if (((int) resource_name & 0xffff0000) == 0)
{
r->size_shift = FindResourceByNumber(&r->nameinfo, type,
(int) resource_name | 0x8000);
}
else if (resource_name[0] == '\0')
{
r->size_shift = FindResourceByNumber(&r->nameinfo, type, -1);
}
else if (resource_name[0] == '#')
{
r->size_shift = FindResourceByNumber(&r->nameinfo, type,
atoi(resource_name + 1));
}
else
{
r->size_shift = FindResourceByName(&r->nameinfo, type, resource_name);
}
if (r->size_shift == -1)
{
printf("FindResource hInst=%04X typename=%08X resname=%08X not found!\n",
instance, type_name, resource_name);
GlobalFree(rh);
return 0;
}
return rh;
}
/**********************************************************************
* AllocResource [KERNEL.66]
*/
HANDLE AllocResource(HANDLE instance, HANDLE hResInfo, DWORD dwSize)
{
RESOURCE *r;
int image_size;
if (instance == 0)
return 0;
if (OpenResourceFile(instance) < 0)
return 0;
r = (RESOURCE *)GlobalLock(hResInfo);
if (r == NULL)
return 0;
image_size = r->nameinfo.length << r->size_shift;
if (dwSize == 0)
r->rsc_mem = GlobalAlloc(GMEM_MOVEABLE, image_size);
else
r->rsc_mem = GlobalAlloc(GMEM_MOVEABLE, dwSize);
GlobalUnlock(hResInfo);
return r->rsc_mem;
}
/**********************************************************************
* LoadResource [KERNEL.61]
*/
HANDLE LoadResource(HANDLE instance, HANDLE hResInfo)
{
RESOURCE *r;
int image_size;
void *image;
HANDLE h;
if (instance == 0)
return 0;
if (OpenResourceFile(instance) < 0)
return 0;
r = (RESOURCE *)GlobalLock(hResInfo);
if (r == NULL)
return 0;
image_size = r->nameinfo.length << r->size_shift;
h = r->rsc_mem = GlobalAlloc(GMEM_MOVEABLE, image_size);
image = GlobalLock(h);
lseek(ResourceFd, ((int) r->nameinfo.offset << r->size_shift), SEEK_SET);
if (image == NULL || read(ResourceFd, image, image_size) != image_size)
{
GlobalFree(h);
GlobalUnlock(hResInfo);
return 0;
}
GlobalUnlock(h);
GlobalUnlock(hResInfo);
return h;
}
/**********************************************************************
* LockResource [KERNEL.62]
*/
LPSTR LockResource(HANDLE hResData)
{
return GlobalLock(hResData);
}
/**********************************************************************
* FreeResource [KERNEL.63]
*/
HANDLE FreeResource(HANDLE hResData)
{
RESOURCE *r, *rp;
for (r = rp = Top; r != NULL; r = r->next)
{
if (r->info_mem == hResData)
{
if (rp != NULL)
rp->next = r->next;
else
Top = r->next;
GlobalFree(r->rsc_mem);
GlobalFree(r->info_mem);
return 0;
}
rp = r;
}
return hResData;
}
/**********************************************************************
* AccessResource [KERNEL.64]
*/
int AccessResource(HANDLE instance, HANDLE hResInfo)
{
int resfile, image_size;
RESOURCE *r;
/* #ifdef DEBUG_RESOURCE */
printf("AccessResource(%04X, %04X);\n", instance, hResInfo);
/* #endif */
if (instance == 0)
return -1;
if ((resfile = OpenResourceFile(instance)) < 0)
return -1;
if ((r = (RESOURCE *)GlobalLock(hResInfo)) == NULL)
return -1;
lseek(resfile, ((int) r->nameinfo.offset << r->size_shift), SEEK_SET);
GlobalUnlock(hResInfo);
return dup(resfile);
}
/**********************************************************************
* SizeofResource [KERNEL.65]
*/
WORD SizeofResource(HANDLE instance, HANDLE hResInfo)
{
int image_size;
RESOURCE *r;
/* #ifdef DEBUG_RESOURCE */
printf("SizeofResource(%04X, %04X);\n", instance, hResInfo);
/* #endif */
if (instance == 0)
return 0;
if ((r = (RESOURCE *)GlobalLock(hResInfo)) == NULL)
return 0;
image_size = r->nameinfo.length << r->size_shift;
GlobalUnlock(hResInfo);
/* #ifdef DEBUG_RESOURCE */
printf("SizeofResource return %d\n", image_size);
/* #endif */
return image_size;
}
/**********************************************************************
* 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;
}
else if (OpenResourceFile(instance) < 0)
return 0;
/*
* Get resource by ordinal
*/
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) {
if ((LONG)rsc_name >= 0x00010000L)
printf("RSC_LoadResource inst (%x)/ Resource '%s' not Found !\n", instance, rsc_name);
else
printf("RSC_LoadResource inst (%x)/ Resource '0x%X' not Found !\n", instance, rsc_name);
return 0;
}
/*
* Read resource.
*/
lseek(ResourceFd, ((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 = GlobalLinearLock(hmem);
if (image == NULL || read(ResourceFd, image, image_size) != image_size)
{
GlobalFree(hmem);
return 0;
}
GlobalLinearUnlock(hmem);
return hmem;
}
/**********************************************************************
* LoadString
*/
int
LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen)
{
HANDLE hmem;
int rsc_size;
unsigned char *p;
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
hmem = RSC_LoadResource(instance, (char *) ((resource_id >> 4) + 1),
NE_RSCTYPE_STRING, &rsc_size);
if (hmem == 0)
return 0;
p = GlobalLock(hmem);
string_num = resource_id & 0x000f;
for (i = 0; i < string_num; i++)
p += *p + 1;
i = MIN(buflen - 1, *p);
if (i > 0) {
memcpy(buffer, p + 1, i);
buffer[i] = '\0';
}
else {
if (buflen > 1) {
buffer[0] = '\0';
return 0;
}
printf("LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
printf("LoadString // and try to obtain string '%s'\n", p + 1);
}
GlobalFree(hmem);
#ifdef DEBUG_RESOURCE
printf("LoadString // '%s' copied !\n", buffer);
#endif
return i;
}
/**********************************************************************
* RSC_LoadMenu
*/
HANDLE
RSC_LoadMenu(HANDLE instance, LPSTR menu_name)
{
#ifdef DEBUG_RESOURCE
printf("RSC_LoadMenu: instance = %04x, name = '%s'\n",
instance, menu_name);
#endif
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;
int size;
#ifdef DEBUG_RESOURCE
printf("LoadBitmap: instance = %04x, name = %08x\n",
instance, bmp_name);
#endif
if (!instance)
{
/* Try to create an OEM bitmap */
hbitmap = BITMAP_LoadOEMBitmap( ((int)bmp_name) & 0xffff );
if (hbitmap) return hbitmap;
/* Failed -> load it from sysres.dll */
instance = hSysRes;
}
rsc_mem = RSC_LoadResource(instance, bmp_name, NE_RSCTYPE_BITMAP,
&image_size);
if (rsc_mem == (HANDLE)NULL) {
printf("LoadBitmap / BitMap %04X not Found !\n", bmp_name);
return 0;
}
lp = (long *) GlobalLinearLock(rsc_mem);
if (!(hdc = GetDC(0))) lp = NULL;
if (lp == NULL)
{
GlobalFree(rsc_mem);
return 0;
}
size = CONV_LONG (*lp);
if (size == sizeof(BITMAPCOREHEADER)){
CONV_BITMAPCOREHEADER (lp);
hbitmap = ConvertCoreBitmap( hdc, (BITMAPCOREHEADER *) lp );
} else if (size == sizeof(BITMAPINFOHEADER)){
CONV_BITMAPINFO (lp);
hbitmap = ConvertInfoBitmap( hdc, (BITMAPINFO *) lp );
} else hbitmap = 0;
GlobalFree(rsc_mem);
ReleaseDC( 0, hdc );
return hbitmap;
}
/**********************************************************************
* CreateIcon [USER.407]
*/
HICON CreateIcon(HANDLE hInstance, int nWidth, int nHeight,
BYTE nPlanes, BYTE nBitsPixel, LPSTR lpANDbits,
LPSTR lpXORbits)
{
HICON hIcon;
ICONALLOC *lpico;
#ifdef DEBUG_RESOURCE
printf("CreateIcon: hInstance = %04x, nWidth = %08x, nHeight = %08x \n",
hInstance, nWidth, nHeight);
printf(" nPlanes = %04x, nBitsPixel = %04x,",nPlanes, nBitsPixel);
printf(" lpANDbits= %04x, lpXORbits = %04x, \n",lpANDbits, lpXORbits);
#endif
if (hInstance == (HANDLE)NULL) {
printf("CreateIcon / hInstance %04x not Found!\n",hInstance);
return 0;
}
hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024);
if (hIcon == (HICON)NULL) {
printf("Can't allocate memory for Icon in CreateIcon\n");
return 0;
}
lpico= (ICONALLOC *)GlobalLock(hIcon);
lpico->descriptor.Width=nWidth;
lpico->descriptor.Height=nHeight;
lpico->descriptor.ColorCount=16; /* Dummy Value */
lpico->descriptor.Reserved1=0;
lpico->descriptor.Reserved2=nPlanes;
lpico->descriptor.Reserved3=nWidth*nHeight;
/* either nPlanes and/or nBitCount is set to one */
lpico->descriptor.icoDIBSize=nWidth*nHeight*nPlanes*nBitsPixel;
lpico->descriptor.icoDIBOffset=0;
if( !(lpico->hBitmap=CreateBitmap(nWidth, nHeight, nPlanes, nBitsPixel,
lpXORbits)) ) {
printf("CreateIcon: couldn't create the XOR bitmap\n");
return(0);
}
/* the AND BitMask is always monochrome */
if( !(lpico->hBitMask=CreateBitmap(nWidth, nHeight, 1, 1, lpANDbits)) ) {
printf("CreateIcon: couldn't create the AND bitmap\n");
return(0);
}
GlobalUnlock(hIcon);
#ifdef DEBUG_RESOURCE
printf("CreateIcon Alloc hIcon=%X\n", hIcon);
#endif
return hIcon;
}