mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-02 13:27:35 +00:00
c7c217b31c
Sun Apr 12 12:22:23 1997 Andreas Mohr <100.30936@germany.net> * [files/drive.c] Fixed "no free space" problem with partition sizes between 1 and 2 GB (cluster_sectors may not exceed 0x40). * [windows/msgbox.c] [if1632/user.spec] [include/windows.h] Implemented MessageBoxIndirect16, corrected MSGBOXPARAMS16. * [loader/task.c] DOS environment strings may never exceed 127 chars -> truncate Unix environment strings if necessary. Sun Apr 12 02:51:44 1998 Dimitrie O. Paun <dimi@mail.cs.toronto.edu> * [files/*.c] All fprintf statements were converted to appropriate debug messages. * [tools/find_debug_channels] Updated comments at the beginning of the file. Sat Apr 11 15:27:21 1998 Alexandre Julliard <julliard@lrc.epfl.ch> * [loader/module.c] [loader/task.c] [scheduler/process.c] Moved some code around to prepare the ground for CreateProcess(). * [memory/environ.c] [loader/task.c] Moved Win32 environment strings functions to environ.c. Unified Win16 and Win32 environment management. * [scheduler/handle.c] [scheduler/k32obj.c] [scheduler/*.c] Implemented handle inheritance and DuplicateHandle(). * [scheduler/thread.c] Create a 16-bit stack for all threads. * [windows/dialog.c] Implemented DIALOGEX resource format. Fri Apr 10 20:21:51 1998 Marcus Meissner <marcus@mud.de> * [configure.in][include/acconfig.h][*/*][multimedia/*] Cleaned up the OSS detection stuff, added some more checks for headerfiles/functions. Removed a lot of OS specific #ifdefs. Lots of dependend multimedia cleanups. * [loader/pe_image.c] Enhanced comment, added missing reference count increase. * [ole/compobj.c] Replaced broken StringFromGUID2 by working one. * [misc/winsock.c] SO_LINGER uses unsigned 16 bit in Win16 and Win32, but unsigned int (32bit) for UNIX. * [memory/global.c] Allow realloc for lockcount 1 too. Fri Apr 10 15:27:34 1998 Morten Welinder <terra@diku.dk> * [graphics/x11drv/text.c] Handle control characters in trace. Ignore terminating newline. * [multimedia/init.c] (MULTIMEDIA_Init): Correct allocations. * [tools/examine-relay] Tidy up. * [windows/syscolor.c] Change highlight colour from lightblue to lightgray. This looks correct for menus. Fri Apr 10 01:49:58 1998 Douglas Ridgway <ridgway@winehq.com> * [configure.in] [Make.rules.in] Add check for c2man before using it. Fri Apr 10 02:59:21 1998 Douglas Ridgway <ridgway@winehq.com> * [DEVELOPERS-HINTS] Simple description of adding API calls. * [include/wintypes.h] [include/windows.h] Get rid of Winelib16, avoid declaring some illegal functions in Winelib, add prototypes for some enhanced metafile functions, fix GetTextExtentPoint32 declarations. * [relay32/gdi32.spec] [objects/enhmetafile.c] Cosmetic and functional improvements. * [include/wincon.h] [programs/view/*] Fixes, improved compatibility with native compilers. Thu Apr 9 15:48:49 1998 Ulrich Weigand <weigand@informatik.uni-erlangen.de> * [win32/kernel32.c] Implemented FT_Thunk / FT_Prolog / FT_Exit / FT_PrologPrime. Fixed Common32ThkLS thunk function. * [tools/build.c] [relay32/relay386.c] [if1632/relay.c] Changed relay code to allow register functions to modify stack layout. * [memory/selector.c] Implemented AllocMappedBuffer / FreeMappedBuffer. * [relay32/kernel32.spec] [if1632/kernel.spec] [win32/ordinals.c] Added names for undocumented functions. * [loader/module.c] Bugfix: LoadLibrary16 should *not* silently load 32-bit DLL. Thu Apr 9 03:54:58 1998 Jim Peterson <jspeter@birch.ee.vt.edu> * [windows/keyboard.c] Fix an erroneous test in TranslateAccelerator{16,32} for the end of the accelerator table. Thu Apr 8 20:36:28 1998 Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de> * [misc/crtdll.c] Implement getenv. * [misc/commdlg.c] Make Get[Save/Open]FileName work in most situations. * [misc/lstr.c] Use wvsprintf32A instead of vsprintf in FormatMessage32X * [misc/version] Make NT3.50 a recognised version * [graphics/x11drv/graphics.c] Change the algorithme to draw arcs * [loader/resource.c] Return an empty buffer in LoadString32A if no resource found. * [win32/code_page.c] Try harder to get the right size in MultiByteToWideChar. * [win32/process.c] Call WinExec32 for CreateProcess32A. * [windows/user.c] Install default Int0 Handler in InitApp(). Thu Apr 8 19:29:48 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de> * [misc/imagelist.c] Preliminary fix for drawing selected images. Various improvements. * [controls/progress.c][include/progress.c][include/commctrl.h] Added progress bar messages and styles for IE4.01 (dll version 4.72) compatibility. Fixed led size problem. * [controls/updown.c][include/commctrl.h] Added UDM_GETRANGE32 and UDM_SETRANGE32. * [objects/oembitmaps.c][include/windows.h][include/bitmaps/*] Added Win95 icons and fixed Win95 cursor and restore button bug. Now they should be visible. Sorry!!! * [relay32/comctl32.spec] Added most missing function names. Tue Apr 6 18:48:36 1998 Matthew Becker <mbecker@glasscity.net> * [objects/font.c] [if1632/gdi.spec] GetOutlineTextMetrics: stub * [objects/text.c] GetTextCharset should just call GetTextCharsetInfo. * [misc/mpr.c] [relay32/mpr.spec] WNetCachePassword: stub * [scheduler/thread.c] [relay32/user32.spec] AttachThreadInput: stub Updated documentation. * [objects/palette.c] Updated documentation. Tue Mar 31 17:06:30 1998 James Juran <jrj120@psu.edu> * [*/*.c] Finished fixing USER32 ordinal numbers in function documentation. Mon Mar 30 20:27:38 1998 Morten Welinder <terra@diku.dk> * [misc/debugstr.c] [include/debugstr.h] Moved _dumpstr from relay32/relay386.c. Improved control character handling. * [msdos/int21.c] Implement 215E00 -- get machine name. * [windows/winpos.c] SetWindowPos32: Make an extra sync when mapping managed windows. This makes sure the reconfigure event has been handled. See Mshearts' what's-your-name window. Mon Mar 30 01:13:50 1998 Alexander V. Lukyanov <lav@long.yar.ru> * [Makefile.in] Install includes from TOPSRCDIR.
304 lines
11 KiB
Text
304 lines
11 KiB
Text
This is intended to be a document to help new developers get started.
|
|
Existing developers should feel free to add their comments.
|
|
|
|
SOURCE TREE STRUCTURE
|
|
=====================
|
|
|
|
Source tree is loosely based on the original Windows modules. Most
|
|
directories are shared between the binary emulator and the library.
|
|
|
|
Shared directories:
|
|
-------------------
|
|
|
|
KERNEL:
|
|
|
|
files/ - file I/O
|
|
loader/ - Win16-, Win32-binary loader
|
|
memory/ - memory management
|
|
msdos/ - DOS and BIOS emulation
|
|
scheduler/ - process and thread management
|
|
|
|
GDI:
|
|
|
|
graphics/ - graphics drivers
|
|
graphics/x11drv/ - X11 display driver
|
|
graphics/metafiledrv/ - metafile driver
|
|
objects/ - logical objects
|
|
|
|
USER:
|
|
|
|
controls/ - built-in widgets
|
|
resources/ - built-in dialog resources
|
|
windows/ - window management
|
|
|
|
Miscellaneous:
|
|
|
|
misc/ - shell, registry, winsock, etc...
|
|
multimedia/ - multimedia driver
|
|
ipc/ - SysV IPC management
|
|
win32/ - misc Win32 functions
|
|
|
|
Tools:
|
|
|
|
rc/ - resource compiler
|
|
tools/ - relay code builder + misc tools
|
|
documentation/ - some documentation
|
|
|
|
|
|
Emulator-specific directories:
|
|
------------------------------
|
|
|
|
debugger/ - built-in debugger
|
|
if1632/ - relay code
|
|
miscemu/ - hardware instruction emulation
|
|
graphics/win16drv/ - Win16 printer driver
|
|
|
|
Winelib-specific directories:
|
|
-----------------------------
|
|
|
|
library/ - Winelib-specific routines (should disappear)
|
|
programs/ - utilities (Progman, WinHelp)
|
|
libtest/ - Winelib test samples
|
|
|
|
IMPLEMENTING NEW API CALLS
|
|
==========================
|
|
|
|
This is the simple version, and covers only Win32. Win16 is slightly uglier,
|
|
because of the Pascal heritage and the segmented memory model.
|
|
|
|
All of the Win32 APIs known to Wine are listed in [relay32/*.spec]. An
|
|
unimplemented call will look like (from gdi32.spec)
|
|
269 stub PolyBezierTo
|
|
To implement this call, you need to do the following four things.
|
|
|
|
1. Find the appropriate parameters for the call, and add a prototype to
|
|
[include/windows.h]. In this case, it might look like
|
|
BOOL32 WINAPI PolyBezierTo32(HDC32, LPCVOID, DWORD);
|
|
#define PolyBezierTo WINELIB_NAME(PolyBezierTo)
|
|
Note the use of the #define for Winelib. See below for discussion of
|
|
function naming conventions.
|
|
|
|
2. Modify the .spec file to tell Wine that the function has an
|
|
implementation, what the parameters look like and what Wine function
|
|
to use for the implementation. In Win32, things are simple--everything
|
|
is 32-bits. However, the relay code handles pointers and pointers to
|
|
strings slightly differently, so you should use 'str' and 'wstr' for
|
|
strings, 'ptr' for other pointer types, and 'long' for everything else.
|
|
269 stdcall PolyBezierTo(long ptr long) PolyBezierTo32
|
|
The 'PolyBezierTo32' at the end of the line is which Wine function to use
|
|
for the implementation.
|
|
|
|
3. Implement the function as a stub. Once you add the function to the .spec
|
|
file, you must add the function to the Wine source before it will link.
|
|
Add a function called 'PolyBezierTo32' somewhere. Good things to put
|
|
into a stub:
|
|
o a correct prototype, including the WINAPI
|
|
o header comments, including full documentation for the function and
|
|
arguments
|
|
o A FIXME message and an appropriate return value are good things to
|
|
put in a stub.
|
|
|
|
/************************************************************
|
|
* PolyBezierTo32 (GDI32.269) Draw many Bezier curves
|
|
*
|
|
* BUGS
|
|
* Unimplemented
|
|
*/
|
|
BOOL32 WINAPI PolyBezierTo32(HDC32 hdc, LPCVOID p, DWORD count) {
|
|
/* tell the user they've got a substandard implementation */
|
|
FIXME(gdi, ":(%x,%p,%d): stub\n", hdc, p, count);
|
|
/* some programs may be able to compensate,
|
|
if they know what happened */
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
return FALSE; /* error value */
|
|
}
|
|
|
|
4. Implement and test the function.
|
|
|
|
MEMORY AND SEGMENTS
|
|
===================
|
|
|
|
NE (Win16) executables consist of multiple segments. The Wine loader
|
|
loads each segment into a unique location in the Wine processes memory
|
|
and assigns a selector to that segment. Because of this, it's not
|
|
possible to exchange addresses freely between 16-bit and 32-bit code.
|
|
Addresses used by 16-bit code are segmented addresses (16:16), formed
|
|
by a 16-bit selector and a 16-bit offset. Those used by the Wine code
|
|
are regular 32-bit linear addresses.
|
|
|
|
There are four ways to obtain a segmented pointer:
|
|
- Use the SEGPTR_* macros in include/heap.h (recommended).
|
|
- Allocate a block of memory from the global heap and use
|
|
WIN16_GlobalLock to get its segmented address.
|
|
- Allocate a block of memory from a local heap, and build the
|
|
segmented address from the local heap selector (see the
|
|
USER_HEAP_* macros for an example of this).
|
|
- Declare the argument as 'segptr' instead of 'ptr' in the spec file
|
|
for a given API function.
|
|
|
|
Once you have a segmented pointer, it must be converted to a linear
|
|
pointer before you can use it from 32-bit code. This can be done with
|
|
the PTR_SEG_TO_LIN() and PTR_SEG_OFF_TO_LIN() macros. The linear
|
|
pointer can then be used freely with standard Unix functions like
|
|
memcpy() etc. without worrying about 64k boundaries. Note: there's no
|
|
easy way to convert back from a linear to a segmented address.
|
|
|
|
In most cases, you don't need to worry about segmented address, as the
|
|
conversion is made automatically by the callback code and the API
|
|
functions only see linear addresses. However, in some cases it is
|
|
necessary to manipulate segmented addresses; the most frequent cases
|
|
are:
|
|
- API functions that return a pointer
|
|
- lParam of Windows messages that point to a structure
|
|
- Pointers contained inside structures accessed by 16-bit code.
|
|
|
|
It is usually a good practice to used the type 'SEGPTR' for segmented
|
|
pointers, instead of something like 'LPSTR' or 'char *'. As SEGPTR is
|
|
defined as a DWORD, you'll get a compilation warning if you mistakenly
|
|
use it as a regular 32-bit pointer.
|
|
|
|
|
|
STRUCTURE PACKING
|
|
=================
|
|
|
|
Under Windows, data structures are tightly packed, i.e. there is no
|
|
padding between structure members. On the other hand, by default gcc
|
|
aligns structure members (e.g. WORDs are on a WORD boundary, etc.).
|
|
This means that a structure like
|
|
|
|
struct { BYTE x; WORD y; };
|
|
|
|
will take 3 bytes under Windows, but 4 with gcc, because gcc will add a
|
|
dummy byte between x and y. To have the correct layout for structures
|
|
used by Windows code, you need to use the WINE_PACKED attribute; so you
|
|
would declare the above structure like this:
|
|
|
|
struct { BYTE x; WORD y WINE_PACKED; };
|
|
|
|
You have to do this every time a structure member is not aligned
|
|
correctly under Windows (i.e. a WORD not on an even address, or a
|
|
DWORD on a address that is not a multiple of 4).
|
|
|
|
|
|
NAMING CONVENTIONS FOR API FUNCTIONS AND TYPES
|
|
==============================================
|
|
|
|
In order to support both Win16 and Win32 APIs within the same source
|
|
code, as well as share the include files between the emulator and the
|
|
library, the following convention must be used in naming all API
|
|
functions and types. If the Windows API uses the name 'xxx', the Wine
|
|
code must use:
|
|
|
|
- 'xxx16' for the 16-bit version,
|
|
- 'xxx32' for the 32-bit version when no ASCII/Unicode strings are
|
|
involved,
|
|
- 'xxx32A' for the 32-bit version with ASCII strings,
|
|
- 'xxx32W' for the 32-bit version with Unicode strings.
|
|
|
|
You should then use the macros WINELIB_NAME[_AW](xxx) or
|
|
DECL_WINELIB_TYPE[_AW](xxx) (defined in include/wintypes.h) to define
|
|
the correct 'xxx' function or type for Winelib. When compiling the
|
|
emulator, 'xxx' is _not_ defined, meaning that you must always specify
|
|
explicitly whether you want the 16-bit or 32-bit version.
|
|
|
|
If 'xxx' is the same in Win16 and Win32, or if 'xxx' is Win16 only,
|
|
you can simply use the same name as Windows, i.e. just 'xxx'. If
|
|
'xxx' is Win32 only, you can use 'xxx' if there are no strings
|
|
involved, otherwise you must use the 'xxx32A' and 'xxx32W' forms.
|
|
|
|
Examples:
|
|
|
|
typedef short INT16;
|
|
typedef int INT32;
|
|
DECL_WINELIB_TYPE(INT);
|
|
|
|
typedef struct { /* Win32 ASCII data structure */ } WNDCLASS32A;
|
|
typedef struct { /* Win32 Unicode data structure */ } WNDCLASS32W;
|
|
typedef struct { /* Win16 data structure */ } WNDCLASS16;
|
|
DECL_WINELIB_TYPE_AW(WNDCLASS);
|
|
|
|
ATOM RegisterClass16( WNDCLASS16 * );
|
|
ATOM RegisterClass32A( WNDCLASS32A * );
|
|
ATOM RegisterClass32W( WNDCLASS32W * );
|
|
#define RegisterClass WINELIB_NAME_AW(RegisterClass)
|
|
|
|
The Winelib user can then say:
|
|
|
|
INT i;
|
|
WNDCLASS wc = { ... };
|
|
RegisterClass( &wc );
|
|
|
|
and this will use the correct declaration depending on the definition
|
|
of the symbols WINELIB and UNICODE.
|
|
|
|
|
|
API ENTRY POINTS
|
|
================
|
|
|
|
Because Win16 programs use a 16-bit stack and because they can only
|
|
call 16:16 addressed functions, all API entry points must be at low
|
|
address offsets and must have the arguments translated and moved to
|
|
Wines 32-bit stack. This task is handled by the code in the "if1632"
|
|
directory. To define a new API entry point handler you must place a
|
|
new entry in the appropriate API specification file. These files are
|
|
named *.spec. For example, the API specification file for the USER
|
|
DLL is contained in the file user.spec. These entries are processed
|
|
by the "build" program to create an assembly file containing the entry
|
|
point code for each API call. The format of the *.spec files is
|
|
documented in the file "tools/build-spec.txt".
|
|
|
|
|
|
DEBUG MESSAGES
|
|
==============
|
|
|
|
To display a message only during debugging, you normally write something
|
|
like this:
|
|
|
|
TRACE(win,"abc..."); or
|
|
FIXME(win,"abc..."); or
|
|
WARN(win,"abc..."); or
|
|
ERR(win,"abc...");
|
|
|
|
depending on the seriousness of the problem. (documentation/degug-msgs
|
|
explains when it is appropriate to use each of them)
|
|
|
|
These macros are defined in include/debug.h. The macro-definitions are
|
|
generated by the shell-script tools/make_debug. It scans the source
|
|
code for symbols of this forms and puts the necessary macro
|
|
definitions in include/debug.h and include/debugdefs.h. These macros
|
|
test whether the debugging "channel" associated with the first
|
|
argument of these macros (win in the above example) is enabled and
|
|
thus decide whether to actually display the text. In addition you can
|
|
change the types of displayed messages by supplying the "-debugmsg"
|
|
option to Wine. If your debugging code is more complex than just
|
|
printf, you can use the symbols TRACE_ON(xxx), WARN_ON(xxx),
|
|
ERR_ON(xxx) and FIXME_ON(xxx) as well. These are true when channel xxx
|
|
is enabled, either permanent or in the command line. Thus, you can
|
|
write:
|
|
|
|
if(TRACE_ON(win))DumpSomeStructure(&str);
|
|
|
|
Don't worry about the inefficiency of the test. If it is permanently
|
|
disabled (that is TRACE_ON(win) is 0 at compile time), the compiler will
|
|
eliminate the dead code.
|
|
|
|
You have to start tools/make_debug only if you introduced a new macro,
|
|
e.g. TRACE(win32).
|
|
|
|
For more info about debugging messages, read:
|
|
|
|
documentation/debug-msgs
|
|
|
|
|
|
MORE INFO
|
|
=========
|
|
|
|
1. There is a FREE online version of the MSDN library (including
|
|
documentation for the Win32 API) on http://www.microsoft.com/msdn/
|
|
|
|
2. http://www.sonic.net/~undoc/bookstore.html
|
|
|
|
3. In 1993 Dr. Dobbs Journal published a column called "Undocumented Corner".
|
|
|
|
4. You might want to check out BYTE from December 1983 as well :-)
|
|
|