Removed old resource compiler.

This commit is contained in:
Alexandre Julliard 2000-04-09 18:35:07 +00:00
parent 87a2f8df86
commit d1735c6198
11 changed files with 0 additions and 1653 deletions

View File

@ -1,5 +0,0 @@
Makefile
lex.yy.c
winerc
y.tab.c
y.tab.h

View File

@ -1,28 +0,0 @@
DEFS = -D__WINE__
TOPSRCDIR = @top_srcdir@
TOPOBJDIR = ..
SRCDIR = @srcdir@
VPATH = @srcdir@
PROGRAMS = winerc@PROGEXT@
MODULE = none
C_SRCS = winerc.c
EXTRA_SRCS = parser.y parser.l
EXTRA_OBJS = y.tab.o lex.yy.o
all: $(PROGRAMS)
depend:: y.tab.h
@MAKE_RULES@
$(PROGRAMS): $(OBJS)
$(CC) $(CFLAGS) -o winerc@PROGEXT@ $(OBJS) $(LEXLIB)
y.tab.c y.tab.h: parser.y
$(YACC) -d -t $(SRCDIR)/parser.y
lex.yy.c: parser.l
$(LEX) -8 -I $(SRCDIR)/parser.l
### Dependencies:

View File

@ -1,37 +0,0 @@
This is winerc, the resource compiler for the Wine project. It takes the
same input as rc.exe, but generates C files as output. These C files can
be linked together with the application, which can access the resource
data directly instead of using FindResource/LoadResource/LockResource.
The generated C code contains arrays, which represent the resource as if
it was obtained from LoadResource. A table to map resource names to
pointers is also available.
Primary applications are the resources of sysres.dll and a future
commdlg.dll, but the use in the library version is possible as well.
The expected advantage of using winerc over sysres.dll is a speed
improvement, however, actual data to support that claim are not
available. The use of winerc might also simplify the source code. For
example, the system menu is managed in the function CopySysMenu
(controls/menu.c). A winerc-based implementation would just call
return LoadMenuIndirect(_Sysres_SYSMENU);
As the resources are already in the Wine image, they are loaded on
demand as any other part of a Unix executable image.
Current State
This is the first release of winerc. It is alpha software, as the rest
of Wine is. If you use it for replacing sysres.dll, or if you write
other parts of Wine which require resource (like commdlg), you will
probably notice a loss in stability. This is especially true for cursor
and icon resources, as they are unlikely to work at all. See the TODO
file for details.
Copying
The license for Wine applies for winerc as well. Read the files LICENSE
and WARRANTY in the current or any future distribution for details. You
can change any source files, and you can add your own copyright notice,
as long as you leave the existing copyrights intact.
Bug Reports and Fixes
If you find a bug in winerc, you can report it to me,
martin@cs.csufresno.edu (Martin von Loewis) or to
comp.emulators.ms-windows.wine. If you can fix the bug, send the diffs
and ChangeLog entry to julliard@lrc.epfl.ch (Alexandre Julliard).

View File

@ -1,19 +0,0 @@
This release of winerc contains a resource script for sysres.dll,
obtained by saving it as RC in Borland's Resource Workshop. Obsolete
or duplicate resources where removed. If you find that I deleted to
little or to much, drop me a note.
You are encouraged to create sysres dumps using your favoured resource
editor. If the output cannot be compiled, or the generated C code is
different from mine, report this as a bug. When comparing the results,
note that only the order might be different, which is not considered a
bug.
systest.c is a Windows program which shows how to use winerc generated
resources. Compile it with your Windows compiler, and link it with
sysres.c. It also shows how to prevent curious people from spying your
bitmaps, dialogs, and menus :-)
Deleted resources:
Bitmap: OBMCLOSE
Menu: 1, 0xF140+2
Dialog: 0XF140+3, EXCLAMATION_MSGBOX, QUESTION_MSGBOX, STOP_MSGBOX
Icon: SYSIDI_STOPICON

63
rc/TODO
View File

@ -1,63 +0,0 @@
1. User interface
- use GNU's long_getopt
- allow to pass input and output files via command line
- add options for various not-yet-implemented features (Unicode, Win32
format, non-native/native alignment and endianness, compact output
format)
2. Input format
- improve input file processing
Currently, certain pre- and postprocessing is required. winerc
should accept an arbitrary resource script and generate the C file
with as little intermediate files as possible. I'm not sure how to
handle the symbols from windows.h. There are certain options:
* winerc predefines the symbols via the cpp command line
* windows.h is #include'd, and the resulting C code is dropped
(Should winerc do C parsing here?)
* a stripped-down version of windows.h is included,
generated by "grep '^#' windows.h"
* windows.h #ifdef's every C code with _RC_INVOKED
(commercial solution)
- complete input syntax
The goal here is to support every existing resource file which is
accepted by another resource compiler, not to put as much fancy
features into the compiler as possible. Every correct resource file
which generates a parse error can be reported as a bug, a problem
analysis and a fix would be appreciated.
3. Output file format
- add missing resources (fonts, versioninfo, stringtables,rcdata)
- check style handling
The semantics of control and dialog styles is somewhat poorly
documented. For example, I couldn't find a reference that every
control has the WS_VISIBLE and WS_CHILD style, even if they are
not specified. What other styles are considered default?
The existance of default styles implies support for disabling these,
unlike any other proper programming language,
NOT WS_VISIBLE | WS_GROUP
does *not* mean ~WS_VISIBLE, but WS_CHILD|WS_GROUP (in C semantics).
What other strange semantics are there?
- check cursor and icon handling
At the moment, the .CUR and .ICO files are copied byte-by-byte into
the C array. This is probably wrong, as there are things like cursor
and icon groups. In which way should they be present in a Wine image?
Should we have arrays for every cursor, as well as the cursor group?
Is one cursor per group enough, in the context of X? If so, do we
still need the group?
- create a more compact output file
The current format is well-suited for debugging, as one can easily
match it with a resource' hex dump. A more compact format would use
strings instead of integer lists. A clever algorithm for embedding
values <32 and >127 is required.
- platform independence
Currently, the lay-out of the resources is just as it is in Win3.1 -
packed structures, little endian. Although this format can be used
on any architecture, aligned data and native endianness would speed-up
the resource manipulation and simplify the code. OTOH, this would
break applications that rely on the lay-out. All this is of interest
for the library version only.
- Win32 support
4. Programming Style
- memory management
No memory is freed in the current implementation.

View File

@ -1,108 +0,0 @@
/*
*
* Copyright Martin von Loewis, 1994
*
*/
/* resource types */
enum rt {acc,bmp,cur,dlg,fnt,ico,men,rdt,str};
/* generic resource
Bytes can be inserted at arbitrary positions, the data field (res)
grows as required. As the dialog header contains the number of
controls, this number is generated in num_entries. If n_type if 0,
the resource name is i_name, and s_name otherwise. Top level
resources are linked via next. All gen_res objects are linked via
g_prev, g_next for debugging purposes. space is the length of res,
size is the used part of res.
As most bison rules are right recursive, new items are usually
inserted at the beginning
*/
typedef struct gen_res{
int size,space;
int num_entries;
enum rt type;
union{
int i_name;
char* s_name;
}n;
int n_type; /*0 - integer, 1 = string*/
struct gen_res *next;
struct gen_res *g_prev,*g_next;
unsigned char res[0];
} gen_res;
/* control/dialog style. or collects styles, and collects NOT styles */
typedef struct rc_style{
int and, or;
}rc_style;
/* create a new resource */
gen_res *new_res(void);
/* double the space of the resource */
gen_res* grow(gen_res*);
/* insert byte array at the beginning, increase count */
gen_res* insert_at_beginning(gen_res*,char*,int);
/* insert byte array at offset */
gen_res* insert_bytes(gen_res*,char*,int,int);
/* delete bytes at offset */
gen_res* delete_bytes(gen_res*,int,int);
/* create a new style */
rc_style* new_style(void);
/* convert \t to tab etc. */
char* parse_c_string(char*);
/* get the resources type, convert dlg to "DIALOG" and so on */
char* get_typename(gen_res*);
gen_res* add_accelerator(int,int,int,gen_res*);
gen_res* add_string_accelerator(char*,int,int,gen_res*);
gen_res* add_ascii_accelerator(int,int,int,gen_res*);
gen_res* add_vk_accelerator(int,int,int,gen_res*);
gen_res* new_dialog(void);
gen_res* dialog_style(rc_style*,gen_res*);
int dialog_get_menu(gen_res*);
int dialog_get_class(gen_res*);
int dialog_get_caption(gen_res*);
int dialog_get_fontsize(gen_res*);
gen_res* dialog_caption(char*,gen_res*);
gen_res* dialog_font(short,char*,gen_res*);
gen_res* dialog_class(char*,gen_res*);
gen_res* dialog_menu_id(short,gen_res*);
gen_res* dialog_menu_str(char*,gen_res*);
gen_res* create_control_desc(int,int,int,int,int,rc_style*);
gen_res* label_control_desc(char*,gen_res*);
gen_res* create_generic_control(char*,int,char*,rc_style*,int,int,int,int);
gen_res* add_control(int,int,gen_res*,gen_res*);
gen_res* add_icon(char*,int,int,int,gen_res*,gen_res*);
gen_res* add_generic_control(gen_res*,gen_res*);
gen_res* make_dialog(gen_res*,int,int,int,int,gen_res*);
gen_res *hex_to_raw(char*,gen_res*);
gen_res *int_to_raw(int,gen_res*);
gen_res *make_font(gen_res*);
gen_res *make_raw(gen_res*);
gen_res *make_bitmap(gen_res*);
gen_res *make_icon(gen_res*);
gen_res *make_cursor(gen_res*);
gen_res *load_file(char*);
gen_res *add_menuitem(char*,int,int,gen_res*);
gen_res *add_popup(char*,short,gen_res*,gen_res*);
gen_res *make_menu(gen_res*);
gen_res *add_resource(gen_res*,gen_res*);
void add_str_tbl_elm(int,char*);
void create_output(gen_res*);
void set_out_file(char*);
#define CT_BUTTON 0x80
#define CT_EDIT 0x81
#define CT_STATIC 0x82
#define CT_LISTBOX 0x83
#define CT_SCROLLBAR 0x84
#define CT_COMBOBOX 0x85
extern int verbose;

View File

@ -1,85 +0,0 @@
/* -*-C-*-
*
* Copyright Martin von Loewis, 1994
*
*/
%{
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "parser.h"
#include "y.tab.h"
#define YY_NO_UNPUT
int line_number=1;
%}
%%
ACCELERATORS return ACCELERATORS;
ALT return ALT;
ASCII return ASCII;
BEGIN return tBEGIN;
BITMAP return tBITMAP;
CAPTION return CAPTION;
CHECKBOX return CHECKBOX;
CHECKED return CHECKED;
CLASS return CLASS;
COMBOBOX return COMBOBOX;
CONTROL return CONTROL;
CTEXT return CTEXT;
CURSOR return CURSOR;
DEFPUSHBUTTON return DEFPUSHBUTTON;
DIALOG return DIALOG;
DISCARDABLE return DISCARDABLE;
EDITTEXT return EDITTEXT;
END return tEND;
FIXED return tFIXED;
FONT return FONT;
GRAYED return GRAYED;
GROUPBOX return GROUPBOX;
HELP return HELP;
ICON return ICON;
INACTIVE return INACTIVE;
LISTBOX return LISTBOX;
LTEXT return LTEXT;
MENU return MENU;
MENUBARBREAK return MENUBARBREAK;
MENUBREAK return MENUBREAK;
MENUITEM return MENUITEM;
MOVEABLE return MOVEABLE;
LOADONCALL return LOADONCALL;
NOINVERT return NOINVERT;
NOT return NOT;
NUMBER return NUMBER;
POPUP return POPUP;
PRELOAD return PRELOAD;
PUSHBUTTON return PUSHBUTTON;
PURE return PURE;
RADIOBUTTON return RADIOBUTTON;
RCDATA return RCDATA;
RTEXT return RTEXT;
SCROLLBAR return SCROLLBAR;
SHIFT return SHIFT;
SEPARATOR return SEPARATOR;
STRING return tSTRING;
STRINGTABLE return STRINGTABLE;
STYLE return STYLE;
VERSIONINFO return VERSIONINFO;
VIRTKEY return VIRTKEY;
\{ return tBEGIN;
\} return tEND;
[+-]?[0-9]+ yylval.num=atoi(yytext);return NUMBER;
0x[0-9A-Fa-f]+L? yylval.num=strtoul(yytext,0,16);return NUMBER;
[A-Za-z][A-Za-z_0-9]* yylval.str=strdup(yytext);return IDENT;
\"[^"]*\" yylval.str=parse_c_string(yytext);return tSTRING;
\'[^']*\' yylval.str=strdup(yytext+1);return SINGLE_QUOTED;
\n { line_number++; }
[ \t\r] ;
. return yytext[0];
%%
#ifndef yywrap
int yywrap(void) { return 1; }
#endif

View File

@ -1,228 +0,0 @@
%{
/*
*
* Copyright Martin von Loewis, 1994
*/
#include <stdio.h>
#include <stdlib.h>
#include "parser.h"
#include "windows.h"
int yylex(void);
int yyerror(const char *s);
%}
%union{
gen_res *res;
char *str;
int num;
struct rc_style *style;
}
%token <num> NUMBER
%token <str> tSTRING SINGLE_QUOTED IDENT
%token ACCELERATORS ALT ASCII tBEGIN tBITMAP CAPTION CHECKBOX CHECKED
%token CLASS COMBOBOX CONTROL CTEXT CURSOR DEFPUSHBUTTON DIALOG
%token DISCARDABLE EDITTEXT tEND tFIXED FONT GRAYED GROUPBOX HELP ICON
%token IDENT INACTIVE LISTBOX LTEXT MENU MENUBARBREAK MENUBREAK MENUITEM
%token MOVEABLE LOADONCALL NOINVERT NOT NOT_SUPPORTED POPUP PRELOAD
%token PURE PUSHBUTTON RADIOBUTTON RCDATA RTEXT SCROLLBAR SHIFT SEPARATOR
%token SINGLE_QUOTED tSTRING STRINGTABLE STYLE VERSIONINFO VIRTKEY
%type <res> resource_file resource resources resource_definition accelerators
%type <res> events bitmap cursor dialog dlg_attributes controls
%type <res> generic_control labeled_control control_desc font icon
%type <res> iconinfo menu menu_body item_definitions rcdata raw_data raw_elements
%type <res> stringtable strings versioninfo
%type <num> acc_options item_options
%type <style> style style_elm optional_style
%%
resource_file: resources {create_output($1);}
/*resources are put into a linked list*/
resources: {$$=0;}
|resource resources {$$=add_resource($1,$2);}
;
/* get the name for a single resource*/
resource: NUMBER resource_definition
{$$=$2;$$->n.i_name=$1;$$->n_type=0;
if(verbose)fprintf(stderr,"Got %s %d\n",get_typename($2),$1);
}
| IDENT resource_definition
{$$=$2;$$->n.s_name=$1;$$->n_type=1;
if(verbose)fprintf(stderr,"Got %s %s\n",get_typename($2),$1);
}
| stringtable
{$$=$1; /* <-- should be NULL */
if(verbose)fprintf(stderr,"Got STRINGTABLE\n");
}
;
/* get the value for a single resource*/
resource_definition: accelerators {$$=$1;}
| bitmap {$$=$1;}
| cursor {$$=$1;}
| dialog {$$=$1;}
| font {$$=$1;}
| icon {$$=$1;}
| menu {$$=$1;}
| rcdata {$$=$1;}
| versioninfo {$$=$1;}
;
/* have to use tBEGIN because BEGIN is predefined */
accelerators: ACCELERATORS load_and_memoption tBEGIN events tEND {$$=$4;$$->type=acc;}
/* the events are collected in a gen_res, as the accelerator resource is just
an array of events */
events: {$$=new_res();}
| tSTRING ',' NUMBER acc_options events
{$$=add_string_accelerator($1,$3,$4,$5);}
| NUMBER ',' NUMBER ',' ASCII acc_options events
{$$=add_ascii_accelerator($1,$3,$6,$7);}
| NUMBER ',' NUMBER ',' VIRTKEY acc_options events
{$$=add_vk_accelerator($1,$3,$6,$7);}
acc_options: {$$=0;}
| ',' NOINVERT acc_options {$$=$3|2;}
| ',' ALT acc_options {$$=$3|16;}
| ',' SHIFT acc_options {$$=$3|4;}
| ',' CONTROL acc_options {$$=$3|8;}
bitmap: tBITMAP load_and_memoption tSTRING {$$=make_bitmap(load_file($3));}
| tBITMAP load_and_memoption raw_data {$$=make_bitmap($3);}
/* load and memory options are ignored */
load_and_memoption: | lamo load_and_memoption
lamo: PRELOAD | LOADONCALL | tFIXED | MOVEABLE | DISCARDABLE | PURE
cursor: CURSOR load_and_memoption tSTRING {$$=make_cursor(load_file($3));}
|CURSOR load_and_memoption raw_data {$$=make_cursor($3);}
dialog: DIALOG load_and_memoption NUMBER ',' NUMBER ',' NUMBER ',' NUMBER
dlg_attributes
tBEGIN controls tEND
{$$=make_dialog($10,$3,$5,$7,$9,$12);}
dlg_attributes: {$$=new_dialog();}
| STYLE style dlg_attributes
{$$=dialog_style($2,$3);}
| CAPTION tSTRING dlg_attributes
{$$=dialog_caption($2,$3);}
| FONT NUMBER ',' tSTRING dlg_attributes
{$$=dialog_font($2,$4,$5);}
| CLASS tSTRING dlg_attributes
{$$=dialog_class($2,$3);}
| MENU tSTRING dlg_attributes
{$$=dialog_menu_str($2,$3);}
| MENU NUMBER dlg_attributes
{$$=dialog_menu_id($2,$3);}
/* the controls are collected into a gen_res, and finally the dialog header
is put at the beginning */
controls: {$$=new_res();}
| CHECKBOX labeled_control controls
{$$=add_control(CT_BUTTON, BS_CHECKBOX, $2, $3);}
| COMBOBOX control_desc controls
{$$=add_control(CT_COMBOBOX, 0, $2, $3);}
| CONTROL generic_control controls
{$$=add_generic_control($2, $3);}
| CTEXT labeled_control controls
{$$=add_control(CT_STATIC, SS_CENTER, $2, $3);}
| DEFPUSHBUTTON labeled_control controls
{$$=add_control(CT_BUTTON, BS_DEFPUSHBUTTON, $2, $3);}
| EDITTEXT control_desc controls
{$$=add_control(CT_EDIT, 0, $2, $3);}
| GROUPBOX labeled_control controls
{$$=add_control(CT_BUTTON, BS_GROUPBOX, $2, $3);}
/*special treatment for icons, as the extent is optional*/
| ICON tSTRING ',' NUMBER ',' NUMBER ',' NUMBER iconinfo controls
{$$=add_icon($2, $4, $6, $8, $9, $10);}
| LISTBOX control_desc controls
{$$=add_control(CT_LISTBOX, 0, $2, $3);}
| LTEXT labeled_control controls
{$$=add_control(CT_STATIC, SS_LEFT, $2, $3);}
| PUSHBUTTON labeled_control controls
{$$=add_control(CT_BUTTON, BS_PUSHBUTTON, $2, $3);}
| RADIOBUTTON labeled_control controls
{$$=add_control(CT_BUTTON, BS_RADIOBUTTON, $2, $3);}
| RTEXT labeled_control controls
{$$=add_control(CT_STATIC, SS_RIGHT, $2, $3);}
| SCROLLBAR control_desc controls
{$$=add_control(CT_SCROLLBAR, 0, $2, $3);}
labeled_control: tSTRING ',' control_desc {$$=label_control_desc($1,$3);}
control_desc: NUMBER ',' NUMBER ',' NUMBER ',' NUMBER ',' NUMBER optional_style
{$$=create_control_desc($1,$3,$5,$7,$9,$10);}
optional_style: {$$=0;}|
',' style {$$=$2;}
iconinfo: /*set extent and style to 0 if they are not provided */
{$$=create_control_desc(0,0,0,0,0,0);}
/* x and y are overwritten later */
| ',' NUMBER ',' NUMBER optional_style
{$$=create_control_desc(0,0,0,$2,$4,$5);}
generic_control: tSTRING ',' NUMBER ',' tSTRING ',' style ',' NUMBER
',' NUMBER ',' NUMBER ',' NUMBER
{$$=create_generic_control($1,$3,$5,$7,$9,$11,$13,$15);}
font: FONT load_and_memoption tSTRING {$$=make_font(load_file($3));}
icon: ICON load_and_memoption tSTRING {$$=make_icon(load_file($3));}
| ICON load_and_memoption raw_data {$$=make_icon($3);}
menu: MENU load_and_memoption menu_body {$$=make_menu($3);}
/* menu items are collected in a gen_res and prefixed with the menu header*/
menu_body: tBEGIN item_definitions tEND {$$=$2;}
item_definitions: {$$=new_res();}
| MENUITEM tSTRING ',' NUMBER item_options item_definitions
{$$=add_menuitem($2,$4,$5,$6);}
| MENUITEM SEPARATOR item_definitions
{$$=add_menuitem("",0,0,$3);}
| POPUP tSTRING item_options menu_body item_definitions
{$$=add_popup($2,$3,$4,$5);}
item_options: {$$=0;}
| ',' CHECKED item_options {$$=$3|MF_CHECKED;}
| ',' GRAYED item_options {$$=$3|MF_GRAYED;}
| ',' HELP item_options {$$=$3|MF_HELP;}
| ',' INACTIVE item_options {$$=$3|MF_DISABLED;}
| ',' MENUBARBREAK item_options {$$=$3|MF_MENUBARBREAK;}
| ',' MENUBREAK item_options {$$=$3|MF_MENUBREAK;}
rcdata: RCDATA load_and_memoption raw_data {$$=make_raw($3);}
raw_data: tBEGIN raw_elements tEND {$$=$2;}
raw_elements: SINGLE_QUOTED {$$=hex_to_raw($1,new_res());}
| NUMBER {$$=int_to_raw($1,new_res());}
| SINGLE_QUOTED raw_elements {$$=hex_to_raw($1,$2);}
| NUMBER ',' raw_elements {$$=int_to_raw($1,$3);}
stringtable: STRINGTABLE load_and_memoption tBEGIN strings tEND
{$$=$4;}
strings: {$$=0;}|
NUMBER tSTRING strings {$$=0;add_str_tbl_elm($1,$2);}
versioninfo: VERSIONINFO NOT_SUPPORTED {$$=0;}
/* NOT x | NOT y | a | b means (a|b)& ~x & ~y
NOT is used to disable default styles */
style: {$$=new_style();}
| style_elm {$$=$1;}
| style_elm '|' style
{$$=$1;$$->or|=$3->or;$$->and&=$3->and;free($3);}
style_elm: NUMBER {$$=new_style();$$->or=$1;}
| NOT NUMBER {$$=new_style();$$->and=~($2);}
| '(' style ')' {$$=$2;}
%%
extern int line_number;
extern char* yytext;
int yyerror( const char *s )
{
fprintf(stderr,"stdin:%d: %s before '%s'\n",line_number,s,yytext);
return 0;
}

View File

@ -1,109 +0,0 @@
#include <windows.h>
LRESULT CALLBACK _export WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
BOOL CALLBACK _export DlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
HINSTANCE hInst;
HMENU hMenu,dummy;
extern char sysres_MENU_SYSMENU[],sysres_BITMAP_WINELOGO[],sysres_DIALOG_2[];
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int cmdShow)
{
MSG msg;
WNDCLASS wcHdumpClass;
HWND hWndMain;
hInst=hInstance;
/* Define the window class for this application. */
wcHdumpClass.lpszClassName = "WrcTestClass";
wcHdumpClass.hInstance = hInstance;
wcHdumpClass.lpfnWndProc = WndProc;
wcHdumpClass.hCursor = 0;
wcHdumpClass.hIcon = 0;
wcHdumpClass.lpszMenuName = 0;
wcHdumpClass.hbrBackground = GetStockObject(WHITE_BRUSH);
wcHdumpClass.style = CS_HREDRAW | CS_VREDRAW;
wcHdumpClass.cbClsExtra = 0;
wcHdumpClass.cbWndExtra = 0;
RegisterClass(&wcHdumpClass);
hWndMain = CreateWindow("WrcTestClass","WrcTest",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, /* x window location */
CW_USEDEFAULT, /* y */
CW_USEDEFAULT, /* cx and size */
CW_USEDEFAULT, /* cy */
NULL, /* no parent for this window */
NULL, /* use the class menu */
hInstance, /* who created this window */
NULL /* no parms to pass on */
);
ShowWindow(hWndMain,SW_SHOW);
UpdateWindow(hWndMain);
hMenu=LoadMenuIndirect(sysres_MENU_SYSMENU);
/* see Q75254 on how to create a popup menu via LoadMenuIndirect */
dummy=CreateMenu();
InsertMenu(dummy,0,MF_POPUP,hMenu,NULL);
hMenu=GetSubMenu(dummy,0);
while (GetMessage(&msg, NULL, NULL, NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return(msg.wParam);
}
LRESULT CALLBACK _export WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
POINT ptCurrent;
switch(message)
{
case WM_LBUTTONDOWN:
ptCurrent=MAKEPOINT(lParam);
ClientToScreen(hWnd,&ptCurrent);
TrackPopupMenu(hMenu,0,ptCurrent.x,ptCurrent.y,0,hWnd,0);
break;
case WM_PAINT:
{ PAINTSTRUCT ps;
BITMAPINFO *bm=sysres_BITMAP_WINELOGO;
char *bits=bm;
bits+=bm->bmiHeader.biSize;
bits+=(1<<bm->bmiHeader.biBitCount)*sizeof(RGBQUAD);
BeginPaint(hWnd,&ps);
SetDIBitsToDevice(ps.hdc,0,0,bm->bmiHeader.biWidth,
bm->bmiHeader.biHeight,0,0,0,bm->bmiHeader.biHeight,
bits,bm,DIB_RGB_COLORS);
EndPaint(hWnd,&ps);
break;
}
case WM_COMMAND:
CreateDialogIndirect(hInst,sysres_DIALOG_2,hWnd,DlgProc);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:return DefWindowProc(hWnd,message,wParam,lParam);
}
return 0L;
}
BOOL CALLBACK _export DlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_INITDIALOG:
return 1;
case WM_COMMAND:
DestroyWindow(hWnd);
return 0;
}
return 0;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

View File

@ -1,971 +0,0 @@
/*
*
* Copyright Martin von Loewis, 1994
*
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include "windows.h"
#include "wine/winuser16.h"
#include "parser.h"
char usage[]="winerc -bdvc -p prefix -o outfile < infile \n"
" -b Create a C array from a binary .res file\n"
" -c Add 'const' prefix to C constants\n"
" -d Output debugging information\n"
" -h Also generate a .h file\n"
" -p prefix Give a prefix for the generated names\n"
" -v Show each resource as it is processed\n"
" -o file Output to file.c and file.h\n"
" -w 16|32 Select win16 or win32 output\n";
/*might be overwritten by command line*/
char *prefix="_Resource";
int win32=1;
int verbose,constant;
gen_res* g_start;
static FILE *header = NULL, *code = NULL;
int transform_binary_file(void);
int yyparse(void);
static void *xmalloc (size_t size)
{
void *res;
res = malloc (size ? size : 1);
if (res == NULL)
{
fprintf (stderr, "Virtual memory exhausted.\n");
exit (1);
}
return res;
}
int main(int argc,char *argv[])
{
extern int yydebug;
extern char* optarg;
int optc,lose = 0, ret, binary = 0, output_header = 0;
char output_name[256];
while((optc=getopt(argc,argv,"bcdhp:vo:w:"))!=EOF)
switch(optc)
{
/* bison will print state transitions on stderr */
case 'b':binary=1;
break;
case 'd':yydebug=1;
setbuf(stdout,0);
setbuf(stderr,0);
break;
case 'h':output_header=1; break;
case 'p':prefix=strdup(optarg); break;
case 'c':constant=1;break;
case 'v':verbose=1;
setbuf(stderr,0);
break;
case 'o':sprintf(output_name,"%s.c",optarg); break;
case 'w':if(!strcmp(optarg,"16"))win32=0;
else if(!strcmp(optarg,"32"))win32=1;
else lose++;
break;
default: lose++;break;
}
if(lose)return fprintf(stderr,usage),1;
if (output_name[0])
{
code = fopen( output_name, "w" );
if (output_header)
{
output_name[strlen(output_name)-1] = 'h';
header = fopen( output_name, "w" );
}
}
if (!code) code = stdout;
if(binary)
ret=transform_binary_file();
else
ret=yyparse();
if (header) fclose(header);
fclose(code);
if (ret) /* There was an error */
{
if (header) unlink( output_name );
output_name[strlen(output_name)-1] = 'c';
unlink( output_name );
}
return ret;
}
int transform_binary_file()
{
int i,c;
if (header) fprintf(header,"#define APPLICATION_HAS_RESOURCES 1\n");
fprintf(code,"char _Application_resources[]={");
for(i=0;;i++)
{
c=getchar();
if(c==-1)break;
if(i%16==0)fputc('\n',code);
fprintf(code,"%3d,",c);
}
fprintf(code,"\n 0};\nint _Application_resources_size=%d;\n",i);
return 0;
}
/* SunOS' memcpy is wrong for overlapping arrays */
char *save_memcpy(char *d,char* s,int l)
{
if(d<s)
for(;l;l--)*d++=*s++;
else
for(d+=l-1,s+=l-1;l;l--)*d--=*s--;
return d;
}
/*allow unaligned access*/
void put_WORD(unsigned char* p,WORD w)
{
*p=w&0xFF;
*(p+1)=w>>8;
}
void put_DWORD(unsigned char* p,DWORD d)
{
put_WORD(p,d&0xFFFF);
put_WORD(p+2,d>>16);
}
WORD get_WORD(unsigned char* p)
{
return *p|(*(p+1)<<8);
}
DWORD get_DWORD(unsigned char* p)
{
return get_WORD(p)|(get_WORD(p+2)<<16);
}
/*create a new gen_res, initial size 100*/
gen_res *new_res()
{ gen_res* ret=xmalloc(sizeof(gen_res)+100);
int i;
for(i=0;i<sizeof(gen_res)+100;i++)*((char*)ret+i)='\0';
ret->g_next=g_start;
ret->g_prev=0;
g_start=ret;
ret->space=100;
return ret;
}
/*double the space*/
gen_res* grow(gen_res* res)
{
res=realloc(res,sizeof(gen_res)+2*res->space);
if(!res)
fprintf(stderr,"Out of memory\n"),exit(1);
if(!res->g_prev)g_start=res;
else res->g_prev->g_next=res;
if(res->g_next)res->g_next->g_prev=res;
res->space=2*res->space;
return res;
}
/* insert bytes at offset 0, increase num_entries */
gen_res* insert_at_beginning(gen_res* res,char* entry,int size)
{
while(res->size+size>res->space)res=grow(res);
save_memcpy(res->res+size,res->res,res->size);
save_memcpy(res->res,entry,size);
res->size+=size;
res->num_entries++;
return res;
}
/* insert length characters from bytes into res, starting at start */
gen_res* insert_bytes(gen_res* res,char* bytes,int start,int length)
{
while(res->size+length>res->space)res=grow(res);
save_memcpy(res->res+start+length,res->res+start,res->size-start);
save_memcpy(res->res+start,bytes,length);
res->size+=length;
return res;
}
/* insert string into res, starting at start */
gen_res* insert_string(gen_res* res,unsigned char* string,int start,int terminating0)
{
unsigned char* p;
int lengthA = strlen(string) + (terminating0 ? 1 : 0);
int length = (win32 ? 2 : 1) * lengthA;
while(res->size+length>res->space)res=grow(res);
save_memcpy(res->res+start+length,res->res+start,res->size-start);
p=res->res+start;
while(lengthA--)
if (win32)
{
put_WORD(p, *string++);
p+=2;
}
else
*p++=*string++;
res->size+=length;
return res;
}
/* insert string at offset 0, increase num_entries */
gen_res* insert_string_at_beginning(gen_res* res,char* entry,int terminating0)
{
res=insert_string(res,entry,0,terminating0);
res->num_entries++;
return res;
}
/*delete len bytes from res, starting at start*/
gen_res* delete_bytes(gen_res* res,int start,int len)
{
save_memcpy(res->res+start,res->res+start+len,res->size-start-len);
res->size-=len;
return res;
}
/*create a new style*/
rc_style *new_style()
{
rc_style *ret=xmalloc(sizeof(rc_style));
/*initially, no bits have to be reset*/
ret->and=-1;
/*initially, no bits are set*/
ret->or=WS_CHILD | WS_VISIBLE;
return ret;
}
/* entries are inserted at the beginning, starting from the last one */
gen_res* add_accelerator(int ev, int id, int flags, gen_res* prev)
{
char accel_entry[5];
if(prev->num_entries==0)flags|=0x80; /* last entry */
accel_entry[0]=flags;
put_WORD(accel_entry+1,ev);
put_WORD(accel_entry+3,id);
return insert_at_beginning(prev,accel_entry,5);
}
/* create an integer from the event, taking things as "^c" into account
add this as new entry */
gen_res* add_string_accelerator(char *ev, int id, int flags, gen_res* prev)
{
int event;
if(*ev=='^')
event=ev[1]-'a';
else
event=ev[0];
return add_accelerator(event,id,flags,prev);
}
/*is there a difference between ASCII and VIRTKEY accelerators? */
gen_res* add_ascii_accelerator(int ev, int id, int flags, gen_res* prev)
{
return add_accelerator(ev,id,flags,prev);
}
gen_res* add_vk_accelerator(int ev, int id, int flags, gen_res* prev)
{
return add_accelerator(ev,id,flags,prev);
}
/* create a new dialog header, set all items to 0 */
gen_res* new_dialog()
{ gen_res* ret=new_res();
ret->size=win32?24:16; /*all strings "\0", no font*/
return ret;
}
/* the STYLE option was specified */
gen_res* dialog_style(rc_style* style, gen_res* attr)
{
/* default dialog styles? Do we need style->and? */
/* DS_SETFONT might have been specified before */
put_DWORD(attr->res,get_DWORD(attr->res)|style->or);
return attr;
}
/* menu name is at offset 13 (win32: 18) */
int dialog_get_menu(gen_res* attr)
{
return win32?18:13;
}
/* the class is after the menu name */
int dialog_get_class(gen_res* attr)
{
int offs=dialog_get_menu(attr);
while(attr->res[offs]||(win32&&attr->res[offs+1]))offs+=win32?2:1;
offs+=win32?2:1;
return offs;
}
/* the caption is after the class */
int dialog_get_caption(gen_res* attr)
{
int offs=dialog_get_class(attr);
while(attr->res[offs]||(win32&&attr->res[offs+1]))offs+=win32?2:1;
offs+=win32?2:1;
return offs;
}
/* the fontsize, if present, is after the caption, followed by the font name */
int dialog_get_fontsize(gen_res* attr)
{
int offs=dialog_get_caption(attr);
while(attr->res[offs]||(win32&&attr->res[offs+1]))offs+=win32?2:1;
offs+=win32?2:1;
return offs;
}
/* the CAPTION option was specified */
gen_res* dialog_caption(char* cap, gen_res*attr)
{
/* we don't need the terminating 0 as it's already there */
return insert_string(attr,cap,dialog_get_caption(attr),0);
}
/* the FONT option was specified, set the DS_SETFONT flag */
gen_res* dialog_font(short size,char* font,gen_res *attr)
{
char c_size[2];
int offs=dialog_get_fontsize(attr);
put_DWORD(attr->res,get_DWORD(attr->res)|DS_SETFONT);
put_WORD(c_size,size);
attr=insert_bytes(attr,c_size,offs,2);
offs+=2;
/* as there is no font name by default, copy the '\0' */
return insert_string(attr,font,offs,1);
}
gen_res* dialog_class(char* cap, gen_res*attr)
{
return insert_string(attr,cap,dialog_get_class(attr),0);
}
gen_res* dialog_menu_id(short nr, gen_res*attr)
{
char c_nr[2];
int offs=dialog_get_menu(attr);
attr->res[offs] = 0xff;
if (win32) attr->res[offs+1] = 0xff;
put_WORD(c_nr,nr);
return insert_bytes(attr,c_nr,offs+(win32?2:1),2);
}
gen_res* dialog_menu_str(char* cap, gen_res*attr)
{
return insert_string(attr,cap,dialog_get_menu(attr),0);
}
/* set the dialogs id, position, extent, and style */
gen_res* create_control_desc(int id,int x,int y,int cx, int cy,rc_style *style)
{ gen_res* ret=new_res();
int s=WS_VISIBLE|WS_CHILD; /*defaults styles for any control*/
if(win32)
{
if(style)s=(s|style->or)&style->and;
put_DWORD(ret->res+0,s);
/* FIXME */
/* put_WORD(ret->res+4, exStyle); */
put_WORD(ret->res+8,x);
put_WORD(ret->res+10,y);
put_WORD(ret->res+12,cx);
put_WORD(ret->res+14,cy);
put_WORD(ret->res+16,id);
ret->size=24; /*empty strings, unused byte*/
}
else
{
put_WORD(ret->res+0,x);
put_WORD(ret->res+2,y);
put_WORD(ret->res+4,cx);
put_WORD(ret->res+6,cy);
put_WORD(ret->res+8,id);
if(style)s=(s|style->or)&style->and;
put_DWORD(ret->res+10,s);
ret->size=17; /*empty strings, unused byte*/
}
return ret;
}
/* insert the control's label */
gen_res* label_control_desc(char* label,gen_res* cd)
{
int offs;
if(win32) {
if(get_WORD(cd->res+18)==0xffff)offs=20; /* one-character class */
else {
for(offs=18;get_WORD(cd->res+offs);offs+=2);
offs+=2;
}
}
else {
if(cd->res[14]&0x80)offs=15; /* one-character class */
else {
for(offs=14;cd->res[offs];offs++);
offs++;
}
}
return insert_string(cd,label,offs,0);
}
/* a CONTROL was specified */
gen_res* create_generic_control(char* label,int id,char* class,
rc_style*style,int x,int y,int cx,int cy)
{ gen_res* ret=new_res();
int s=WS_VISIBLE|WS_CHILD; /*default styles for any control*/
if(style)s=(s|style->or)&style->and;
if(win32)
{
WORD cl;
put_DWORD(ret->res+0,s);
/* FIXME */
/* put_DWORD(ret->res+4,exstyle->or); */
put_WORD(ret->res+8,x);
put_WORD(ret->res+10,y);
put_WORD(ret->res+12,cx);
put_WORD(ret->res+14,cy);
put_WORD(ret->res+16,id);
ret->size=24;
ret=insert_string(ret,label,20,0);
/* is it a predefined class? */
cl=0;
if(!strcasecmp(class,"BUTTON"))cl=CT_BUTTON;
if(!strcasecmp(class,"EDIT"))cl=CT_EDIT;
if(!strcasecmp(class,"STATIC"))cl=CT_STATIC;
if(!strcasecmp(class,"LISTBOX"))cl=CT_LISTBOX;
if(!strcasecmp(class,"SCROLLBAR"))cl=CT_SCROLLBAR;
if(!strcasecmp(class,"COMBOBOX"))cl=CT_COMBOBOX;
if(cl) {
char ffff[2]={0xff, 0xff};
ret=insert_bytes(ret,ffff,18,2);
put_WORD(ret->res+20,cl);
}
else ret=insert_string(ret,class,18,0);
}
else
{
char cl;
put_WORD(ret->res+0,x);
put_WORD(ret->res+2,y);
put_WORD(ret->res+4,cx);
put_WORD(ret->res+6,cy);
put_WORD(ret->res+8,id);
put_DWORD(ret->res+10,s);
ret->size=17;
ret=insert_string(ret,label,15,0);
/* is it a predefined class? */
cl=0;
if(!strcasecmp(class,"BUTTON"))cl=CT_BUTTON;
if(!strcasecmp(class,"EDIT"))cl=CT_EDIT;
if(!strcasecmp(class,"STATIC"))cl=CT_STATIC;
if(!strcasecmp(class,"LISTBOX"))cl=CT_LISTBOX;
if(!strcasecmp(class,"SCROLLBAR"))cl=CT_SCROLLBAR;
if(!strcasecmp(class,"COMBOBOX"))cl=CT_COMBOBOX;
if(cl)ret->res[14]=cl;
else ret=insert_string(ret,class,14,0);
}
return ret;
}
/* insert cd into rest, set the type, add flags */
gen_res* add_control(int type,int flags,gen_res*cd,gen_res* rest)
{
char zeros[4]={0,0,0,0};
if(win32)
{
char ffff[2]={0xff, 0xff};
put_DWORD(cd->res+0,get_DWORD(cd->res+0)|flags);
cd=insert_bytes(cd,ffff,18,2);
put_WORD(cd->res+20,type);
}
else
{
put_DWORD(cd->res+10,get_DWORD(cd->res+10)|flags);
cd->res[14]=type;
}
/* WIN32: First control is on dword boundary */
if(win32 && cd->size%4)
cd=insert_bytes(cd,zeros,cd->size,4-cd->size%4);
return insert_at_beginning(rest,cd->res,cd->size);
}
/* an ICON control was specified, whf contains width, height, and flags */
gen_res* add_icon(char* name,int id,int x,int y,gen_res* whf,gen_res* rest)
{
if (win32)
{
put_WORD(whf->res+8,x);
put_WORD(whf->res+10,y);
put_WORD(whf->res+16,id);
}
else
{
put_WORD(whf->res+0,x);
put_WORD(whf->res+2,y);
put_WORD(whf->res+8,id);
}
whf=label_control_desc(name,whf);
return add_control(CT_STATIC,SS_ICON,whf,rest);
}
/* insert the generic control into rest */
gen_res* add_generic_control(gen_res* ctl, gen_res* rest)
{
char zeros[4]={0,0,0,0};
/* WIN32: Control is on dword boundary */
if(win32 && ctl->size%4)
ctl=insert_bytes(ctl,zeros,ctl->size,4-ctl->size%4);
return insert_at_beginning(rest,ctl->res,ctl->size);
}
/* create a dialog resource by inserting the header into the controls.
Set position and extent */
gen_res* make_dialog(gen_res* header,int x,int y,int cx,int cy,gen_res* ctls)
{
char zeros[4]={0,0,0,0};
if(win32)
{
put_WORD(header->res+8, ctls->num_entries);
header->type=dlg;
put_WORD(header->res+10,x);
put_WORD(header->res+12,y);
put_WORD(header->res+14,cx);
put_WORD(header->res+16,cy);
}
else
{
header->res[4]=ctls->num_entries;
header->type=dlg;
put_WORD(header->res+5,x);
put_WORD(header->res+7,y);
put_WORD(header->res+9,cx);
put_WORD(header->res+11,cy);
}
/* WIN32: First control is on dword boundary */
if(win32 && header->size%4)
header=insert_bytes(header,zeros,header->size,4-header->size%4);
return insert_bytes(header,ctls->res,header->size,ctls->size);
}
/* create {0x15,0x16,0xFF} from '15 16 FF' */
gen_res *hex_to_raw(char *hex, gen_res*rest)
{
char r2[16];
int i;
for(i=0;*hex!='\'';i++)r2[i]=strtoul(hex,&hex,16);
return insert_bytes(rest,r2,0,i);
}
/* create a bitmap resource */
gen_res *make_bitmap(gen_res* res)
{
res=delete_bytes(res,0,14); /* skip bitmap file header*/
res->type=bmp;
return res;
}
gen_res *make_icon(gen_res* res)
{
res->type=ico;
return res;
}
gen_res *make_cursor(gen_res* res)
{
res->type=cur;
return res;
}
/* load resource bytes from the file name */
gen_res *load_file(char* name)
{
gen_res *res;
struct stat st;
int f=open(name,O_RDONLY);
if(f<0)
{
perror(name);
exit(1);
}
fstat(f,&st);
res=new_res();
while(res->space<st.st_size)res=grow(res);
read(f,res->res,st.st_size);
res->size=st.st_size;
close(f);
return res;
}
/* insert a normal menu item into res, starting from the last item */
gen_res *add_menuitem(char* name,int id,int flags,gen_res *res)
{
char item[4];
if(res->num_entries==0)flags|=MF_END;
put_WORD(item,flags);
put_WORD(item+2,id);
res=insert_string_at_beginning(res,name,1);
res=insert_bytes(res,item,0,4);
return res;
}
/* insert a popup item into res */
gen_res *add_popup(char *name,short flags, gen_res* body, gen_res*res)
{
char c_flags[2];
flags|=MF_POPUP;
if(res->num_entries==0)flags|=MF_END;
put_WORD(c_flags,flags);
res=insert_at_beginning(res,body->res,body->size);
res=insert_string(res,name,0,1);
res=insert_bytes(res,c_flags,0,2);
return res;
}
/* prefix the menu header into res */
gen_res *make_menu(gen_res* res)
{
static char header[4]={0,0,0,0};
res=insert_at_beginning(res,header,4);
res->type=men;
return res;
}
/* link top-level resources */
gen_res *add_resource(gen_res* first,gen_res *rest)
{
if(first)
{
first->next=rest;
return first;
}
else
return rest;
}
typedef struct str_tbl_elm{
int group;
struct str_tbl_elm *next;
char* strings[16];
} str_tbl_elm;
str_tbl_elm* string_table=NULL; /* sorted by group */
void add_str_tbl_elm(int id,char* str)
{
int group=(id>>4)+1;
int idx=id & 0x000f;
str_tbl_elm** elm=&string_table;
while(*elm && (*elm)->group<group) elm=&(*elm)->next;
if(!*elm || (*elm)->group!=group)
{
int i;
str_tbl_elm* new=xmalloc(sizeof(str_tbl_elm));
for(i=0; i<16; i++) new->strings[i] = NULL;
new->group=group;
new->next=*elm;
*elm=new;
}
(*elm)->strings[idx]=str;
}
gen_res* add_string_table(gen_res* t)
{
str_tbl_elm* ste;
int size,i;
gen_res* res;
unsigned char* p;
unsigned char* q;
if(!string_table) return t;
for(ste=string_table; ste; ste=ste->next)
{
for(size=0,i=0; i<16; i++)
size += (win32 ? 2 : 1) * (ste->strings[i] ? strlen(ste->strings[i])+1 : 1);
res=new_res();
while(res->space<size)res=grow(res);
res->type=str;
res->n.i_name=ste->group;
res->n_type=0;
res->size=size;
if (win32)
for(p=res->res,i=0; i<16; i++)
if((q=ste->strings[i])==NULL)
{
put_WORD(p, 0);
p+=2;
}
else
{
put_WORD(p, strlen(q));
p+=2;
while(*q)
{
put_WORD(p, *q++);
p+=2;
}
}
else
for(p=res->res,i=0; i<16; i++)
if((q=ste->strings[i])==NULL)
*p++ = 0;
else
{
*p++ = strlen(q);
while(*q) *p++ = *q++;
}
t=add_resource(res,t);
}
return t;
}
char *get_typename(gen_res* t)
{
switch(t->type){
case acc:return "ACCELERATOR";
case bmp:return "BITMAP";
case cur:return "CURSOR";
case dlg:return "DIALOG";
case fnt:return "FONT";
case ico:return "ICON";
case men:return "MENU";
case rdt:return "RCDATA";
case str:return "STRINGTABLE";
default: return "UNKNOWN";
}
}
/* create strings like _Sysres_DIALOG_2 */
char *get_resource_name(gen_res*it)
{
static char buf[1000];
if(it->n_type)
sprintf(buf,"%s_%s_%s",prefix,get_typename(it),it->n.s_name);
else
sprintf(buf,"%s_%s_%d",prefix,get_typename(it),it->n.i_name);
return buf;
}
#define ISCONSTANT (constant ? "const " : "")
/* create the final output */
void create_output(gen_res* top)
{
gen_res *it;
top=add_string_table(top);
/* Generate the header */
if (header)
{
fprintf( header,
"/*\n"
" * This file is automatically generated. Do not edit!\n"
" */\n\n"
"#ifndef __%s_H\n"
"#define __%s_H\n\n"
"struct resource;\n\n",
prefix, prefix );
/* Declare the resources */
for (it=top;it;it=it->next)
fprintf( header,"extern %sstruct resource %s;\n",
ISCONSTANT, get_resource_name(it) );
fprintf( header,"\nextern %sstruct resource * %s%s_Table[];\n\n",
ISCONSTANT, ISCONSTANT, prefix );
fprintf( header, "#endif /* __%s_H */\n", prefix );
}
/* Print the resources bytes */
fprintf( code, "/*\n"
" * This file is automatically generated. Do not edit!\n"
" */\n\n"
"struct resource {\n"
"\tint id;\n"
"\tint type;\n"
"\tconst char *name;\n"
"\tconst unsigned char* bytes;\n"
"\tunsigned size;\n"
"};\n\n" );
for(it=top;it;it=it->next)
{
int i;
fprintf( code, "static %sunsigned char %s__bytes[]%s = {\n",
ISCONSTANT, get_resource_name(it),
win32?"\n__attribute__ ((aligned (4)))":"");
for (i=0;i<it->size-1;i++)
{
fprintf(code,"0x%02x, ",it->res[i]);
if ((i&7)==7)fputc('\n',code);
}
fprintf(code,"0x%02x };\n\n",it->res[i]);
}
/* Print the resources names */
if (win32)
for(it=top;it;it=it->next)
{
int i;
char s_buffer[20], *s_name=s_buffer;
if(it->n_type) s_name=it->n.s_name;
else sprintf(s_name,"@%d",it->n.i_name);
fprintf( code, "static %sunsigned char %s__name[] = {\n",
ISCONSTANT, get_resource_name(it) );
for (i=0;*s_name;i++,s_name++)
{
fprintf(code,"0x%02x, 0x00, ",*s_name);
if ((i&3)==3)fputc('\n',code);
}
fprintf(code,"0x00, 0x00};\n\n");
}
/* Print the resources */
for (it=top;it;it=it->next)
{
int type;
switch(it->type)
{
case acc:type=(int)RT_ACCELERATOR16;break;
case bmp:type=(int)RT_BITMAP16;break;
case cur:type=(int)RT_CURSOR16;break;
case dlg:type=(int)RT_DIALOG16;break;
case fnt:type=(int)RT_FONT16;break;
case ico:type=(int)RT_ICON16;break;
case men:type=(int)RT_MENU16;break;
case rdt:type=(int)RT_RCDATA16;break;
case str:type=(int)RT_STRING16;break;
default:fprintf(stderr,"Unknown restype\n");type=-1;break;
}
if(win32)
{
if(it->n_type)
fprintf(code,"%sstruct resource %s = {0,%d,%s__name,%s__bytes,%d};\n",
ISCONSTANT, get_resource_name(it), type, get_resource_name(it),
get_resource_name(it), it->size );
else
fprintf(code,"%sstruct resource %s = {%d,%d,%s__name,%s__bytes,%d};\n",
ISCONSTANT, get_resource_name(it), it->n.i_name, type,
get_resource_name(it), get_resource_name(it), it->size );
}
else
{
if(it->n_type)
fprintf(code,"%sstruct resource %s = {0,%d,\"%s\",%s__bytes,%d};\n",
ISCONSTANT, get_resource_name(it), type, it->n.s_name,
get_resource_name(it), it->size );
else
fprintf(code,"%sstruct resource %s = {%d,%d,\"@%d\",%s__bytes,%d};\n",
ISCONSTANT, get_resource_name(it), it->n.i_name, type,
it->n.i_name, get_resource_name(it), it->size );
}
}
/* Print the resource table (NULL terminated) */
fprintf(code,"\n%sstruct resource * %s%s_Table[] = {\n",
ISCONSTANT, ISCONSTANT, prefix);
for (it=top;it;it=it->next)
fprintf( code, " &%s,\n", get_resource_name(it) );
fprintf( code, " 0\n};\n\n\n" );
/* Perform autoregistration */
fprintf( code,
"#ifndef __WINE__\n"
"#if defined(__GNUC__) && ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 7)))\n"
"static void DoIt(void) __attribute__((constructor));\n"
"#else\n"
"static void DoIt(void);\n"
"void LIBWINE_Register_%s(void) { DoIt(); }\n"
"#endif\n"
"static void DoIt(void)\n"
"{\n"
"\textern void LIBRES_RegisterResources(const struct resource* const * Res);\n"
"\tLIBRES_RegisterResources(%s_Table);\n"
"}\n\n"
"#endif /* __WINE__ */\n"
,prefix,prefix);
}
gen_res* make_font(gen_res* res)
{
fprintf(stderr,"Fonts not supported\n");
return NULL;
}
gen_res* make_raw(gen_res* res)
{
fprintf(stderr,"RCData not supported\n");
return NULL;
}
gen_res* int_to_raw(int i,gen_res* res)
{
fprintf(stderr,"IntToRaw not supported\n");
return NULL;
}
/* translate "Hello,\\tworld!\\10" to "Hello,\tworld!\n" */
char *parse_c_string(char *in)
{
char *out=xmalloc(strlen(in)-1);
char *it;
char tmp[5],*tend;
for(it=out,in++;*in;in++)
if(*in=='\\')
switch(*++in)
{case 't':*it++='\t';break;
case 'r':*it++='\r';break;
case 'n':*it++='\n';break;
case 'a':*it++='\a';break;
case '0':
memset(tmp,0,5);/*make sure it doesn't use more than 4 chars*/
memcpy(tmp,in,4);
*it++=strtoul(tmp,&tend,0);
in+=tend-tmp-1;
break;
case '1':case '2':case '3':case '4':case '5':
case '6':case '7':case '8':case '9':
memset(tmp,0,5);
memcpy(tmp,in,3);
*it++=strtoul(tmp,&tend,10);
in+=tend-tmp-1;
break;
case 'x':
memset(tmp,0,5);
memcpy(tmp,++in,2);
*it++=strtoul(tmp,&tend,16);
in+=tend-tmp-1;
break;
default:*it++=*in;
}
else
*it++=*in;
*(it-1)='\0';
return out;
}