Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 1 | This document should help new developers get started. Like all of Wine, it |
| 2 | is a work in progress. |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 3 | |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 4 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 5 | SOURCE TREE STRUCTURE |
| 6 | ===================== |
| 7 | |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 8 | The Wine source tree is loosely based on the original Windows modules. |
| 9 | Most of the source is concerned with implementing the Wine API, although |
| 10 | there are also various tools, documentation, sample Winelib code, and |
| 11 | code specific to the binary loader. |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 12 | |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 13 | Wine API directories: |
| 14 | --------------------- |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 15 | |
| 16 | KERNEL: |
| 17 | |
| 18 | files/ - file I/O |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 19 | memory/ - memory management |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 20 | scheduler/ - process and thread management |
Sylvain Petreolle | 2028110 | 2002-05-06 20:08:43 +0000 | [diff] [blame] | 21 | winnls/ - National Language Support configuration files |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 22 | |
| 23 | GDI: |
| 24 | |
| 25 | graphics/ - graphics drivers |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 26 | x11drv/ - X11 display driver |
| 27 | win16drv/ -> see below |
| 28 | ttydrv/ - tty display driver |
| 29 | psdrv/ - PostScript graphics driver |
Eric Pouech | 19dc208 | 1999-10-31 22:15:58 +0000 | [diff] [blame] | 30 | metafiledrv/ - metafile driver |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 31 | enhmetafiledrv/ - enhanced metafile driver |
Sylvain Petreolle | 2028110 | 2002-05-06 20:08:43 +0000 | [diff] [blame] | 32 | wing/ - WinG (for games) internface |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 33 | objects/ - logical objects |
| 34 | |
| 35 | USER: |
| 36 | |
| 37 | controls/ - built-in widgets |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 38 | resources/ - built-in menu and message box resources |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 39 | windows/ - window management |
| 40 | |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 41 | Other DLLs: |
| 42 | |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 43 | dlls/ - Other system DLLs implemented by Wine |
| 44 | advapi32/ - crypto, systeminfo, security, eventlogging |
Sylvain Petreolle | 2028110 | 2002-05-06 20:08:43 +0000 | [diff] [blame] | 45 | avicap32/ |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 46 | avifil32/ - COM object to play AVI files |
| 47 | comctl32/ - common controls |
| 48 | commdlg/ - common dialog boxes (both 16 & 32 bit) |
Jon Griffiths | 1db20bf | 2001-01-10 23:59:25 +0000 | [diff] [blame] | 49 | crtdll/ - Old C runtime library |
Sylvain Petreolle | 2028110 | 2002-05-06 20:08:43 +0000 | [diff] [blame] | 50 | crypt32/ |
| 51 | dciman32/ |
| 52 | ddraw/ - DirectX ddraw |
| 53 | dinput/ - DirectX dinput |
| 54 | dplay/ - DirectX dplay |
Eric Pouech | 19dc208 | 1999-10-31 22:15:58 +0000 | [diff] [blame] | 55 | dplayx/ - DirectX dplayx |
| 56 | dsound/ - DirectX dsound |
Sylvain Petreolle | 2028110 | 2002-05-06 20:08:43 +0000 | [diff] [blame] | 57 | glu32/ |
| 58 | icmp/ |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 59 | imagehlp/ - PE (Portable Executable) Image Helper lib |
Eric Pouech | 19dc208 | 1999-10-31 22:15:58 +0000 | [diff] [blame] | 60 | imm32/ |
| 61 | lzexpand/ - Liv-Zempel compression/decompression |
| 62 | mpr/ - Multi-Protocol Router (interface to various |
| 63 | network transport protocols) |
| 64 | msacm/ - audio compression manager (multimedia) (16 bit) |
| 65 | msacm32/ - audio compression manager (multimedia) (32 bit) |
Sylvain Petreolle | 2028110 | 2002-05-06 20:08:43 +0000 | [diff] [blame] | 66 | msdmo/ |
| 67 | msimg32/ |
| 68 | msisys/ |
Eric Pouech | 19dc208 | 1999-10-31 22:15:58 +0000 | [diff] [blame] | 69 | msnet/ |
Sylvain Petreolle | 2028110 | 2002-05-06 20:08:43 +0000 | [diff] [blame] | 70 | msrle32 |
| 71 | msvcrt/ - 16 bit C runtime library |
| 72 | msvcrt20/ - 32 bit C runtime library |
Eric Pouech | 19dc208 | 1999-10-31 22:15:58 +0000 | [diff] [blame] | 73 | msvideo/ - 16 bit video manager |
Sylvain Petreolle | 2028110 | 2002-05-06 20:08:43 +0000 | [diff] [blame] | 74 | netapi32/ |
| 75 | ntdll/ - NT implementation of kernel calls |
| 76 | odbc32/ |
Andreas Mohr | 7bed696 | 2001-09-19 22:34:38 +0000 | [diff] [blame] | 77 | ole32/ - 32 bit OLE 2.0 libraries |
Eric Pouech | 19dc208 | 1999-10-31 22:15:58 +0000 | [diff] [blame] | 78 | oleaut32/ - 32 bit OLE 2.0 automation |
| 79 | olecli/ - 16 bit OLE client |
| 80 | oledlg/ - OLE 2.0 user interface support |
Sylvain Petreolle | 2028110 | 2002-05-06 20:08:43 +0000 | [diff] [blame] | 81 | olepro32/ - 32 bit OLE 2.0 automation |
Eric Pouech | 19dc208 | 1999-10-31 22:15:58 +0000 | [diff] [blame] | 82 | olesvr/ - 16 bit OLE server |
Sylvain Petreolle | 2028110 | 2002-05-06 20:08:43 +0000 | [diff] [blame] | 83 | opengl32/ - OpenGL implementation |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 84 | psapi/ - process status API |
Sylvain Petreolle | 2028110 | 2002-05-06 20:08:43 +0000 | [diff] [blame] | 85 | qcap/ |
| 86 | quartz/ |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 87 | rasapi32/ - remote access server API |
Sylvain Petreolle | 2028110 | 2002-05-06 20:08:43 +0000 | [diff] [blame] | 88 | richedit/ |
| 89 | rpcrt4/ |
| 90 | serialui/ |
| 91 | setupapi/ |
| 92 | shdocvw/ |
| 93 | shfolder/ |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 94 | shell32/ - COM object implementing shell views |
Sylvain Petreolle | 2028110 | 2002-05-06 20:08:43 +0000 | [diff] [blame] | 95 | shlwapi/ |
| 96 | sti/ |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 97 | tapi32/ - telephone API |
Sylvain Petreolle | 2028110 | 2002-05-06 20:08:43 +0000 | [diff] [blame] | 98 | url |
| 99 | urlmon |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 100 | ver/ - File Installation Library (16 bit) |
| 101 | version/ - File Installation Library (32 bit) |
Sylvain Petreolle | 2028110 | 2002-05-06 20:08:43 +0000 | [diff] [blame] | 102 | win32s/ |
| 103 | win87em/ - 80387 math-emulation |
Eric Pouech | 19dc208 | 1999-10-31 22:15:58 +0000 | [diff] [blame] | 104 | winaspi/ - 16 bit Advanced SCSI Peripheral Interface |
Sylvain Petreolle | 2028110 | 2002-05-06 20:08:43 +0000 | [diff] [blame] | 105 | winedos/ - DOS features and BIOS calls (interrupts) |
Eric Pouech | 19dc208 | 1999-10-31 22:15:58 +0000 | [diff] [blame] | 106 | winmm/ - multimedia (16 & 32 bit) |
| 107 | mciXXX/ - various MCI drivers |
Sylvain Petreolle | 2028110 | 2002-05-06 20:08:43 +0000 | [diff] [blame] | 108 | midimap/- midi mapper |
| 109 | wavemap/- audio mapper |
Chris Morgan | 9b0ba7c | 2002-03-21 01:38:19 +0000 | [diff] [blame] | 110 | winearts/ - ARTS audio driver |
Eric Pouech | 19dc208 | 1999-10-31 22:15:58 +0000 | [diff] [blame] | 111 | wineoss/- MM driver for OSS systems |
Sylvain Petreolle | 2028110 | 2002-05-06 20:08:43 +0000 | [diff] [blame] | 112 | winnls/ - National Language Support |
| 113 | winsock/ |
| 114 | wsock32/ |
| 115 | winspool/ - Printing & Print Spooler |
| 116 | wintrust/ |
Eric Pouech | 19dc208 | 1999-10-31 22:15:58 +0000 | [diff] [blame] | 117 | wnaspi32/ - 32 bit ASPI |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 118 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 119 | Miscellaneous: |
| 120 | |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 121 | misc/ - shell, registry, winsock, etc. |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 122 | ipc/ - SysV IPC based interprocess communication |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 123 | win32/ - misc Win32 functions |
| 124 | |
| 125 | Tools: |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 126 | ------ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 127 | |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 128 | tools/ - relay code builder, new rc, bugreport |
| 129 | generator, wineconfigurator, etc. |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 130 | documentation/ - some documentation |
| 131 | |
| 132 | |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 133 | Binary loader specific directories: |
| 134 | ----------------------------------- |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 135 | |
| 136 | debugger/ - built-in debugger |
| 137 | if1632/ - relay code |
| 138 | miscemu/ - hardware instruction emulation |
| 139 | graphics/win16drv/ - Win16 printer driver |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 140 | server/ - the main, controlling thread of wine |
| 141 | tsx11/ - thread-safe X11 wrappers (auto generated) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 142 | |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 143 | Winelib specific directories: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 144 | ----------------------------- |
| 145 | |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 146 | library/ - Required code for programs using Winelib |
| 147 | libtest/ - Small samples and tests |
| 148 | programs/ - Extended samples / system utilities |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 149 | |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 150 | |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 151 | IMPLEMENTING NEW API CALLS |
| 152 | ========================== |
| 153 | |
| 154 | This is the simple version, and covers only Win32. Win16 is slightly uglier, |
| 155 | because of the Pascal heritage and the segmented memory model. |
| 156 | |
| 157 | All of the Win32 APIs known to Wine are listed in [relay32/*.spec]. An |
| 158 | unimplemented call will look like (from gdi32.spec) |
| 159 | 269 stub PolyBezierTo |
| 160 | To implement this call, you need to do the following four things. |
| 161 | |
| 162 | 1. Find the appropriate parameters for the call, and add a prototype to |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 163 | the correct header file. In this case, that means [include/wingdi.h], |
| 164 | and it might look like |
Alexandre Julliard | 9f69d89 | 1999-02-26 12:33:21 +0000 | [diff] [blame] | 165 | BOOL WINAPI PolyBezierTo(HDC, LPCVOID, DWORD); |
| 166 | If the function has both an ASCII and a Unicode version, you need to |
| 167 | define both and add a #define WINELIB_NAME_AW declaration. See below |
| 168 | for discussion of function naming conventions. |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 169 | |
| 170 | 2. Modify the .spec file to tell Wine that the function has an |
| 171 | implementation, what the parameters look like and what Wine function |
| 172 | to use for the implementation. In Win32, things are simple--everything |
| 173 | is 32-bits. However, the relay code handles pointers and pointers to |
| 174 | strings slightly differently, so you should use 'str' and 'wstr' for |
| 175 | strings, 'ptr' for other pointer types, and 'long' for everything else. |
Alexandre Julliard | 9f69d89 | 1999-02-26 12:33:21 +0000 | [diff] [blame] | 176 | 269 stdcall PolyBezierTo(long ptr long) PolyBezierTo |
| 177 | The 'PolyBezierTo' at the end of the line is which Wine function to use |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 178 | for the implementation. |
| 179 | |
| 180 | 3. Implement the function as a stub. Once you add the function to the .spec |
| 181 | file, you must add the function to the Wine source before it will link. |
Alexandre Julliard | 9f69d89 | 1999-02-26 12:33:21 +0000 | [diff] [blame] | 182 | Add a function called 'PolyBezierTo' somewhere. Good things to put |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 183 | into a stub: |
| 184 | o a correct prototype, including the WINAPI |
| 185 | o header comments, including full documentation for the function and |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 186 | arguments (see documentation/README.documentation) |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 187 | o A FIXME message and an appropriate return value are good things to |
| 188 | put in a stub. |
| 189 | |
| 190 | /************************************************************ |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 191 | * PolyBezierTo (GDI32.269) |
| 192 | * |
| 193 | * Draw many Bezier curves |
| 194 | * |
| 195 | * RETURNS |
| 196 | * nonzero on success or zero on faillure |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 197 | * |
| 198 | * BUGS |
| 199 | * Unimplemented |
| 200 | */ |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 201 | BOOL WINAPI PolyBezierTo(HDC hdc, /* handle to device context */ |
| 202 | LPCVOID p, /* ptr to array of Point structs */ |
| 203 | DWORD count /* nr of points in array */ |
| 204 | ) |
| 205 | { |
| 206 | /* tell the user they've got a substandard implementation */ |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 207 | FIXME(gdi, ":(%x,%p,%d): stub\n", hdc, p, count); |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 208 | |
| 209 | /* some programs may be able to compensate, |
| 210 | * if they know what happened |
| 211 | */ |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 212 | SetLastError(ERROR_CALL_NOT_IMPLEMENTED); |
| 213 | return FALSE; /* error value */ |
| 214 | } |
| 215 | |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 216 | 4. Implement and test the rest of the function. |
| 217 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 218 | |
Eric Pouech | 19dc208 | 1999-10-31 22:15:58 +0000 | [diff] [blame] | 219 | IMPLEMENTING A NEW DLL |
| 220 | ====================== |
| 221 | |
Eric Pouech | 31b41cf | 1999-12-05 02:16:24 +0000 | [diff] [blame] | 222 | Generic directions |
| 223 | ------------------ |
| 224 | |
Eric Pouech | 19dc208 | 1999-10-31 22:15:58 +0000 | [diff] [blame] | 225 | Apart from writing the set of needed .c files, you also need to do the |
| 226 | following: |
| 227 | |
| 228 | 1. Create a directory <MyDll> where to store the implementation of |
| 229 | the DLL. |
| 230 | |
| 231 | If the DLL exists under Windows as both 16 and 32 bit DLL, you can |
| 232 | either create one directory for each, or have a single directory |
| 233 | with both implementations. |
| 234 | |
| 235 | This (those) directory(ies) have to be put under the dlls/ |
| 236 | directory in Wine tree structure. |
| 237 | |
| 238 | 2. Create the Makefile.in in the ./dlls/<MyDll>/ directory. You can |
| 239 | copy an existing Makefile.in from another ./dlls/ subdirectory. |
| 240 | |
| 241 | You need at least to change the MODULE, SPEC_SRCS, and C_SRCS |
| 242 | macros. |
| 243 | |
| 244 | 3. Add the directory (and the generated .o file for the module) in: |
| 245 | + ./configure.in (in AC_OUTPUT macro at the end of the file to |
| 246 | trigger the Makefile generation), |
| 247 | + ./Makefile.in (in LIBSUBDIRS and LIBOBJS macros) |
Eric Pouech | 31b41cf | 1999-12-05 02:16:24 +0000 | [diff] [blame] | 248 | + ./dlls/Makefile.in (in SUBDIRS macro) |
Eric Pouech | 19dc208 | 1999-10-31 22:15:58 +0000 | [diff] [blame] | 249 | |
| 250 | 4. You can now regenerate ./configure file (with 'make configure') |
| 251 | and the various Makefiles (with 'configure; make depend') (run |
| 252 | from the top of Wine's tree). |
| 253 | |
| 254 | You shall now have a Makefile file in ./dlls/<MyDll>/ |
| 255 | |
| 256 | 5. You now need to declare the DLL in the module lists. This is done |
| 257 | by adding the corresponding descriptor in ./if1632/builtin.c if |
| 258 | your DLL is 16 bit (resp. ./relay32/builtin.c for a 32 bit DLL) |
| 259 | (or both if your directory contains the dual 16/32 |
| 260 | implementations). |
| 261 | |
| 262 | Note: the name of the descriptor is based on the module name, not |
| 263 | on the file name (they are the same in most of the case, but for |
| 264 | some DLLs it's not the case). |
| 265 | |
| 266 | 6. You also need to define the loadorder for the created DLL |
Eric Pouech | 31b41cf | 1999-12-05 02:16:24 +0000 | [diff] [blame] | 267 | (./wine.ini and ./loader/loadorder.c). Usually, "native,builtin" |
Eric Pouech | 19dc208 | 1999-10-31 22:15:58 +0000 | [diff] [blame] | 268 | is ok. If you have written a paired 16/32 bit implementation, don't |
| 269 | forget to define it also in those files. |
| 270 | |
| 271 | 7. Create the .spec file for the DLL export points in your |
| 272 | directory. Refer to 'Implementation of new API calls' earlier in |
| 273 | this document for more information on this part. |
| 274 | |
Eric Pouech | 31b41cf | 1999-12-05 02:16:24 +0000 | [diff] [blame] | 275 | 8. Don't forget the .cvsignore file. The .cvsignore contain (on a per |
| 276 | directory basis) all the files generated by the compilation |
| 277 | process, why cvs shall ignore when processing the dir. |
| 278 | *.o is in there by default, but in Wine case you will find: |
| 279 | - Makefile (generated from Makefile.in) |
| 280 | - *.spec.c: those c files are generated by tools/build from the |
| 281 | .spec file |
| 282 | - when thunking down to 16 bit DLLs, you'll get some others (.glue.c) |
| 283 | - result of .y => .c translation (by yacc or bison) |
| 284 | - result of .rc compilation |
| 285 | - ... |
| 286 | For a simple DLL, listing in .cvsignore Makefile and |
| 287 | <MyDll>.spec.c will do. |
Eric Pouech | 19dc208 | 1999-10-31 22:15:58 +0000 | [diff] [blame] | 288 | |
| 289 | 9. You can now start adding .c files. |
| 290 | |
| 291 | 10. For the .h files, if they are standard Windows one, put them in |
| 292 | include/. If they are linked to *your* implementation of the DLL, |
| 293 | put them in your newly created directory. |
| 294 | |
Eric Pouech | 31b41cf | 1999-12-05 02:16:24 +0000 | [diff] [blame] | 295 | Debug channels |
| 296 | -------------- |
| 297 | |
Eric Pouech | 19dc208 | 1999-10-31 22:15:58 +0000 | [diff] [blame] | 298 | If you need to create a new debug channel, just add the |
| 299 | DECLARE_DEBUG_CHANNEL to your .c file(s) and rerun |
| 300 | tools/make_debug. When sending out your patch, you don't need to |
Andreas Mohr | 7bed696 | 2001-09-19 22:34:38 +0000 | [diff] [blame] | 301 | provide neither ./configure nor the ./include/debugdefs.h diffs. Just |
Eric Pouech | 19dc208 | 1999-10-31 22:15:58 +0000 | [diff] [blame] | 302 | indicate that those files need to be regenerated. |
| 303 | |
Eric Pouech | 31b41cf | 1999-12-05 02:16:24 +0000 | [diff] [blame] | 304 | Resources |
| 305 | --------- |
| 306 | |
| 307 | If you also need to add resources to your DLL, the create the .rc |
| 308 | file. Since, the .rc file will be translated into a .s file, and then |
| 309 | compiled as a .o file, its basename must be different from the |
| 310 | basename of any .c file. |
| 311 | Add to your ./dlls/<MyDll>/Makefile.in, in the RC_SRCS macro, the list |
| 312 | of .rc files to add to the DLL. You may also have to add the following |
| 313 | directives |
| 314 | 1/ to tell gnumake to translate .rc into .s files, |
| 315 | $(RC_SRCS:.rc=.s): $(WRC) |
| 316 | 2/ to give some parameters to wrc for helping the translation. |
| 317 | WRCEXTRA = -s -p$(MODULE) |
| 318 | |
| 319 | See dlls/comctl32/ for an example of this. |
| 320 | |
| 321 | Thunking |
| 322 | -------- |
| 323 | |
| 324 | If you're building a 16 & 32 bit DLLs pair, then from the 32 bit code |
| 325 | you might need to call 16 bit routine. The way to do it to add in the |
| 326 | code, fragments like: |
| 327 | /* ### Start build ### */ |
| 328 | extern WORD CALLBACK <PREFIX>_CallTo16_word_wwlll(FARPROC16,WORD,WORD,LONG,LONG,LONG); |
| 329 | /* ### stop build ### */ |
| 330 | Where <PREFIX>_ is an internal prefix for your module. The first |
| 331 | parameter is always of type FARPROC16. Then, you can get the regular |
| 332 | list of parameters. The _word_wwlll indicates the type of return (long |
| 333 | or word) and the size of the parameters (here l=>long, w=>word; which |
| 334 | maps to WORD,WORD,LONG,LONG,LONG. |
| 335 | You can put several functions between the Start/Stop build pair. |
| 336 | |
| 337 | You can also read tools/build.txt for more details on this. |
| 338 | |
| 339 | Then, add to ./dlls/<MyDll>/Makefile.in to the macro GLUE the list of |
| 340 | .c files containing the /* ### Start build ### */ directives. |
| 341 | |
| 342 | See dlls/winmm/ for an example of this. |
| 343 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 344 | MEMORY AND SEGMENTS |
| 345 | =================== |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 346 | |
| 347 | NE (Win16) executables consist of multiple segments. The Wine loader |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 348 | loads each segment into a unique location in the Wine processes memory |
| 349 | and assigns a selector to that segment. Because of this, it's not |
| 350 | possible to exchange addresses freely between 16-bit and 32-bit code. |
| 351 | Addresses used by 16-bit code are segmented addresses (16:16), formed |
| 352 | by a 16-bit selector and a 16-bit offset. Those used by the Wine code |
| 353 | are regular 32-bit linear addresses. |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 354 | |
Alexandre Julliard | 1e37a18 | 1996-08-18 16:21:52 +0000 | [diff] [blame] | 355 | There are four ways to obtain a segmented pointer: |
| 356 | - Use the SEGPTR_* macros in include/heap.h (recommended). |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 357 | - Allocate a block of memory from the global heap and use |
| 358 | WIN16_GlobalLock to get its segmented address. |
| 359 | - Allocate a block of memory from a local heap, and build the |
| 360 | segmented address from the local heap selector (see the |
| 361 | USER_HEAP_* macros for an example of this). |
| 362 | - Declare the argument as 'segptr' instead of 'ptr' in the spec file |
| 363 | for a given API function. |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 364 | |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 365 | Once you have a segmented pointer, it must be converted to a linear |
| 366 | pointer before you can use it from 32-bit code. This can be done with |
| 367 | the PTR_SEG_TO_LIN() and PTR_SEG_OFF_TO_LIN() macros. The linear |
| 368 | pointer can then be used freely with standard Unix functions like |
| 369 | memcpy() etc. without worrying about 64k boundaries. Note: there's no |
| 370 | easy way to convert back from a linear to a segmented address. |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 371 | |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 372 | In most cases, you don't need to worry about segmented address, as the |
| 373 | conversion is made automatically by the callback code and the API |
| 374 | functions only see linear addresses. However, in some cases it is |
| 375 | necessary to manipulate segmented addresses; the most frequent cases |
| 376 | are: |
| 377 | - API functions that return a pointer |
| 378 | - lParam of Windows messages that point to a structure |
| 379 | - Pointers contained inside structures accessed by 16-bit code. |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 380 | |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 381 | It is usually a good practice to used the type 'SEGPTR' for segmented |
| 382 | pointers, instead of something like 'LPSTR' or 'char *'. As SEGPTR is |
| 383 | defined as a DWORD, you'll get a compilation warning if you mistakenly |
| 384 | use it as a regular 32-bit pointer. |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 385 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 386 | |
Alexandre Julliard | 2d93d00 | 1996-05-21 15:01:41 +0000 | [diff] [blame] | 387 | STRUCTURE PACKING |
| 388 | ================= |
| 389 | |
| 390 | Under Windows, data structures are tightly packed, i.e. there is no |
| 391 | padding between structure members. On the other hand, by default gcc |
| 392 | aligns structure members (e.g. WORDs are on a WORD boundary, etc.). |
| 393 | This means that a structure like |
| 394 | |
| 395 | struct { BYTE x; WORD y; }; |
| 396 | |
| 397 | will take 3 bytes under Windows, but 4 with gcc, because gcc will add a |
| 398 | dummy byte between x and y. To have the correct layout for structures |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 399 | used by Windows code, you need to embed the struct within two special |
| 400 | #include's which will take care of the packing for you: |
| 401 | |
| 402 | #include "pshpack1.h" |
Eric Pouech | 19dc208 | 1999-10-31 22:15:58 +0000 | [diff] [blame] | 403 | struct { BYTE x; WORD y; }; |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 404 | #include "poppack1.h" |
| 405 | |
| 406 | For alignment on a 2-byte boundary, there is a "pshpack2.h", etc. |
| 407 | |
| 408 | The use of the WINE_PACKED attribute is obsolete. Please remove these |
| 409 | in favour of the above solution. |
| 410 | Using WINE_PACKED, you would declare the above structure like this: |
Alexandre Julliard | 2d93d00 | 1996-05-21 15:01:41 +0000 | [diff] [blame] | 411 | |
| 412 | struct { BYTE x; WORD y WINE_PACKED; }; |
| 413 | |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 414 | You had to do this every time a structure member is not aligned |
Alexandre Julliard | 2d93d00 | 1996-05-21 15:01:41 +0000 | [diff] [blame] | 415 | correctly under Windows (i.e. a WORD not on an even address, or a |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 416 | DWORD on a address that was not a multiple of 4). |
Alexandre Julliard | 2d93d00 | 1996-05-21 15:01:41 +0000 | [diff] [blame] | 417 | |
| 418 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 419 | NAMING CONVENTIONS FOR API FUNCTIONS AND TYPES |
| 420 | ============================================== |
| 421 | |
| 422 | In order to support both Win16 and Win32 APIs within the same source |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 423 | code, the following convention must be used in naming all API |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 424 | functions and types. If the Windows API uses the name 'xxx', the Wine |
| 425 | code must use: |
| 426 | |
Alexandre Julliard | 9f69d89 | 1999-02-26 12:33:21 +0000 | [diff] [blame] | 427 | - 'xxx16' for the Win16 version, |
| 428 | - 'xxx' for the Win32 version when no ASCII/Unicode strings are |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 429 | involved, |
Alexandre Julliard | 9f69d89 | 1999-02-26 12:33:21 +0000 | [diff] [blame] | 430 | - 'xxxA' for the Win32 version with ASCII strings, |
| 431 | - 'xxxW' for the Win32 version with Unicode strings. |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 432 | |
Alexandre Julliard | 9f69d89 | 1999-02-26 12:33:21 +0000 | [diff] [blame] | 433 | If the function has both ASCII and Unicode version, you should then |
| 434 | use the macros WINELIB_NAME_AW(xxx) or DECL_WINELIB_TYPE_AW(xxx) |
Jim Aston | 0768424 | 1999-07-18 13:28:59 +0000 | [diff] [blame] | 435 | (defined in include/windef.h) to define the correct 'xxx' function |
Alexandre Julliard | 9f69d89 | 1999-02-26 12:33:21 +0000 | [diff] [blame] | 436 | or type for Winelib. When compiling Wine itself, 'xxx' is _not_ |
| 437 | defined, meaning that code inside of Wine must always specify |
| 438 | explicitly the ASCII or Unicode version. |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 439 | |
Alexandre Julliard | 9f69d89 | 1999-02-26 12:33:21 +0000 | [diff] [blame] | 440 | If 'xxx' is the same in Win16 and Win32, you can simply use the same |
| 441 | name as Windows, i.e. just 'xxx'. If 'xxx' is Win16 only, you could |
| 442 | use the name as is, but it's preferable to use 'xxx16' to make it |
| 443 | clear it is a Win16 function. |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 444 | |
| 445 | Examples: |
| 446 | |
Alexandre Julliard | 9f69d89 | 1999-02-26 12:33:21 +0000 | [diff] [blame] | 447 | typedef struct { /* Win32 ASCII data structure */ } WNDCLASSA; |
| 448 | typedef struct { /* Win32 Unicode data structure */ } WNDCLASSW; |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 449 | typedef struct { /* Win16 data structure */ } WNDCLASS16; |
| 450 | DECL_WINELIB_TYPE_AW(WNDCLASS); |
| 451 | |
| 452 | ATOM RegisterClass16( WNDCLASS16 * ); |
Alexandre Julliard | 9f69d89 | 1999-02-26 12:33:21 +0000 | [diff] [blame] | 453 | ATOM RegisterClassA( WNDCLASSA * ); |
| 454 | ATOM RegisterClassW( WNDCLASSW * ); |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 455 | #define RegisterClass WINELIB_NAME_AW(RegisterClass) |
| 456 | |
| 457 | The Winelib user can then say: |
| 458 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 459 | WNDCLASS wc = { ... }; |
| 460 | RegisterClass( &wc ); |
| 461 | |
| 462 | and this will use the correct declaration depending on the definition |
Alexandre Julliard | 9f69d89 | 1999-02-26 12:33:21 +0000 | [diff] [blame] | 463 | of the UNICODE symbol. |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 464 | |
| 465 | |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 466 | NAMING CONVENTIONS FOR NON-API FUNCTIONS AND TYPES |
| 467 | ================================================== |
| 468 | |
| 469 | Functions and data which are internal to your code (or at least shouldn't be |
Francois Gouget | e550ebe | 2000-12-02 20:17:13 +0000 | [diff] [blame] | 470 | visible to any Winelib or Windows program) should be preceded by |
Klaas van Gend | 0a7aa16 | 1999-06-05 11:52:46 +0000 | [diff] [blame] | 471 | an identifier to the module: |
| 472 | |
| 473 | Examples: |
| 474 | |
| 475 | ENUMPRINTERS_GetDWORDFromRegistryA() (in dlls/winspool/info.c) |
| 476 | IAVIFile_fnRelease() (in dlls/avifil32/avifile.c) |
| 477 | X11DRV_CreateDC() (in graphics/x11drv/init.c) |
| 478 | TIMER_Init() (implemented in windows/timer.c, |
| 479 | used in loader/main.c ) |
| 480 | |
| 481 | if you need prototypes for these, there are a few possibilities: |
| 482 | - within same source file only: |
| 483 | put the prototypes at the top of your file and mark them as prototypes. |
| 484 | - within the same module: |
| 485 | create a header file within the subdirectory where that module resides, |
| 486 | e.g. graphics/ddraw_private.h |
| 487 | - from a totally different module, or for use in winelib: |
| 488 | put your header file entry in /include/wine/ |
| 489 | but be careful not to clutter this directory! |
| 490 | under no circumstances, you should add non-api calls to the standard |
| 491 | windoze include files. Unfortunately, this is often the case, e.g. |
| 492 | the above example of TIMER_Init is defined in include/message.h |
| 493 | |
| 494 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 495 | API ENTRY POINTS |
| 496 | ================ |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 497 | |
| 498 | Because Win16 programs use a 16-bit stack and because they can only |
| 499 | call 16:16 addressed functions, all API entry points must be at low |
| 500 | address offsets and must have the arguments translated and moved to |
| 501 | Wines 32-bit stack. This task is handled by the code in the "if1632" |
| 502 | directory. To define a new API entry point handler you must place a |
| 503 | new entry in the appropriate API specification file. These files are |
Alexandre Julliard | ca22b33 | 1996-07-12 19:02:39 +0000 | [diff] [blame] | 504 | named *.spec. For example, the API specification file for the USER |
| 505 | DLL is contained in the file user.spec. These entries are processed |
| 506 | by the "build" program to create an assembly file containing the entry |
| 507 | point code for each API call. The format of the *.spec files is |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 508 | documented in the file "tools/build-spec.txt". |
| 509 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 510 | |
| 511 | DEBUG MESSAGES |
| 512 | ============== |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 513 | |
| 514 | To display a message only during debugging, you normally write something |
| 515 | like this: |
| 516 | |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 517 | TRACE(win,"abc..."); or |
| 518 | FIXME(win,"abc..."); or |
| 519 | WARN(win,"abc..."); or |
| 520 | ERR(win,"abc..."); |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 521 | |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 522 | depending on the seriousness of the problem. (documentation/degug-msgs |
| 523 | explains when it is appropriate to use each of them) |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 524 | |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 525 | These macros are defined in include/debug.h. The macro-definitions are |
| 526 | generated by the shell-script tools/make_debug. It scans the source |
| 527 | code for symbols of this forms and puts the necessary macro |
| 528 | definitions in include/debug.h and include/debugdefs.h. These macros |
| 529 | test whether the debugging "channel" associated with the first |
| 530 | argument of these macros (win in the above example) is enabled and |
| 531 | thus decide whether to actually display the text. In addition you can |
| 532 | change the types of displayed messages by supplying the "-debugmsg" |
| 533 | option to Wine. If your debugging code is more complex than just |
| 534 | printf, you can use the symbols TRACE_ON(xxx), WARN_ON(xxx), |
| 535 | ERR_ON(xxx) and FIXME_ON(xxx) as well. These are true when channel xxx |
| 536 | is enabled, either permanent or in the command line. Thus, you can |
| 537 | write: |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 538 | |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 539 | if(TRACE_ON(win))DumpSomeStructure(&str); |
Alexandre Julliard | 234bc24 | 1994-12-10 13:02:28 +0000 | [diff] [blame] | 540 | |
Alexandre Julliard | 234bc24 | 1994-12-10 13:02:28 +0000 | [diff] [blame] | 541 | Don't worry about the inefficiency of the test. If it is permanently |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 542 | disabled (that is TRACE_ON(win) is 0 at compile time), the compiler will |
Alexandre Julliard | 234bc24 | 1994-12-10 13:02:28 +0000 | [diff] [blame] | 543 | eliminate the dead code. |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 544 | |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 545 | You have to start tools/make_debug only if you introduced a new macro, |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 546 | e.g. TRACE(win32). |
| 547 | |
| 548 | For more info about debugging messages, read: |
| 549 | |
| 550 | documentation/debug-msgs |
| 551 | |
Alexandre Julliard | 23946ad | 1997-06-16 17:43:53 +0000 | [diff] [blame] | 552 | |
| 553 | MORE INFO |
| 554 | ========= |
| 555 | |
Alexandre Julliard | 33072e1 | 1997-06-29 18:08:02 +0000 | [diff] [blame] | 556 | 1. There is a FREE online version of the MSDN library (including |
| 557 | documentation for the Win32 API) on http://www.microsoft.com/msdn/ |
Alexandre Julliard | 23946ad | 1997-06-16 17:43:53 +0000 | [diff] [blame] | 558 | |
Alexandre Julliard | 33072e1 | 1997-06-29 18:08:02 +0000 | [diff] [blame] | 559 | 2. http://www.sonic.net/~undoc/bookstore.html |
Alexandre Julliard | 23946ad | 1997-06-16 17:43:53 +0000 | [diff] [blame] | 560 | |
Alexandre Julliard | 33072e1 | 1997-06-29 18:08:02 +0000 | [diff] [blame] | 561 | 3. In 1993 Dr. Dobbs Journal published a column called "Undocumented Corner". |
| 562 | |
| 563 | 4. You might want to check out BYTE from December 1983 as well :-) |
Alexandre Julliard | 23946ad | 1997-06-16 17:43:53 +0000 | [diff] [blame] | 564 | |