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 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4 | SOURCE TREE STRUCTURE |
| 5 | ===================== |
| 6 | |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 7 | The Wine source tree is loosely based on the original Windows modules. |
| 8 | Most of the source is concerned with implementing the Wine API, although |
| 9 | there are also various tools, documentation, sample Winelib code, and |
| 10 | code specific to the binary loader. |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 11 | |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 12 | Wine API directories: |
| 13 | --------------------- |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 14 | |
| 15 | KERNEL: |
| 16 | |
| 17 | files/ - file I/O |
| 18 | loader/ - Win16-, Win32-binary loader |
| 19 | memory/ - memory management |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 20 | msdos/ - DOS features and BIOS calls (interrupts) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 21 | scheduler/ - process and thread management |
| 22 | |
| 23 | GDI: |
| 24 | |
| 25 | graphics/ - graphics drivers |
| 26 | graphics/x11drv/ - X11 display driver |
| 27 | graphics/metafiledrv/ - metafile driver |
| 28 | objects/ - logical objects |
| 29 | |
| 30 | USER: |
| 31 | |
| 32 | controls/ - built-in widgets |
| 33 | resources/ - built-in dialog resources |
| 34 | windows/ - window management |
| 35 | |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 36 | Other DLLs: |
| 37 | |
| 38 | dlls/*/ - Other system DLLs implemented by Wine |
| 39 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 40 | Miscellaneous: |
| 41 | |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 42 | misc/ - shell, registry, winsock, etc. |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 43 | multimedia/ - multimedia driver |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 44 | ipc/ - SysV IPC based interprocess communication |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 45 | win32/ - misc Win32 functions |
| 46 | |
| 47 | Tools: |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 48 | ------ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 49 | |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 50 | rc/ - old resource compiler |
| 51 | tools/ - relay code builder, new rc, etc. |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 52 | documentation/ - some documentation |
| 53 | |
| 54 | |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 55 | Binary loader specific directories: |
| 56 | ----------------------------------- |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 57 | |
| 58 | debugger/ - built-in debugger |
| 59 | if1632/ - relay code |
| 60 | miscemu/ - hardware instruction emulation |
| 61 | graphics/win16drv/ - Win16 printer driver |
| 62 | |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 63 | Winelib specific directories: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 64 | ----------------------------- |
| 65 | |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 66 | library/ - Required code for programs using Winelib |
| 67 | libtest/ - Small samples and tests |
| 68 | programs/ - Extended samples / system utilities |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 69 | |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 70 | IMPLEMENTING NEW API CALLS |
| 71 | ========================== |
| 72 | |
| 73 | This is the simple version, and covers only Win32. Win16 is slightly uglier, |
| 74 | because of the Pascal heritage and the segmented memory model. |
| 75 | |
| 76 | All of the Win32 APIs known to Wine are listed in [relay32/*.spec]. An |
| 77 | unimplemented call will look like (from gdi32.spec) |
| 78 | 269 stub PolyBezierTo |
| 79 | To implement this call, you need to do the following four things. |
| 80 | |
| 81 | 1. Find the appropriate parameters for the call, and add a prototype to |
| 82 | [include/windows.h]. In this case, it might look like |
| 83 | BOOL32 WINAPI PolyBezierTo32(HDC32, LPCVOID, DWORD); |
| 84 | #define PolyBezierTo WINELIB_NAME(PolyBezierTo) |
| 85 | Note the use of the #define for Winelib. See below for discussion of |
| 86 | function naming conventions. |
| 87 | |
| 88 | 2. Modify the .spec file to tell Wine that the function has an |
| 89 | implementation, what the parameters look like and what Wine function |
| 90 | to use for the implementation. In Win32, things are simple--everything |
| 91 | is 32-bits. However, the relay code handles pointers and pointers to |
| 92 | strings slightly differently, so you should use 'str' and 'wstr' for |
| 93 | strings, 'ptr' for other pointer types, and 'long' for everything else. |
| 94 | 269 stdcall PolyBezierTo(long ptr long) PolyBezierTo32 |
| 95 | The 'PolyBezierTo32' at the end of the line is which Wine function to use |
| 96 | for the implementation. |
| 97 | |
| 98 | 3. Implement the function as a stub. Once you add the function to the .spec |
| 99 | file, you must add the function to the Wine source before it will link. |
| 100 | Add a function called 'PolyBezierTo32' somewhere. Good things to put |
| 101 | into a stub: |
| 102 | o a correct prototype, including the WINAPI |
| 103 | o header comments, including full documentation for the function and |
| 104 | arguments |
| 105 | o A FIXME message and an appropriate return value are good things to |
| 106 | put in a stub. |
| 107 | |
| 108 | /************************************************************ |
| 109 | * PolyBezierTo32 (GDI32.269) Draw many Bezier curves |
| 110 | * |
| 111 | * BUGS |
| 112 | * Unimplemented |
| 113 | */ |
| 114 | BOOL32 WINAPI PolyBezierTo32(HDC32 hdc, LPCVOID p, DWORD count) { |
| 115 | /* tell the user they've got a substandard implementation */ |
| 116 | FIXME(gdi, ":(%x,%p,%d): stub\n", hdc, p, count); |
| 117 | /* some programs may be able to compensate, |
| 118 | if they know what happened */ |
| 119 | SetLastError(ERROR_CALL_NOT_IMPLEMENTED); |
| 120 | return FALSE; /* error value */ |
| 121 | } |
| 122 | |
| 123 | 4. Implement and test the function. |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 124 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 125 | MEMORY AND SEGMENTS |
| 126 | =================== |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 127 | |
| 128 | NE (Win16) executables consist of multiple segments. The Wine loader |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 129 | loads each segment into a unique location in the Wine processes memory |
| 130 | and assigns a selector to that segment. Because of this, it's not |
| 131 | possible to exchange addresses freely between 16-bit and 32-bit code. |
| 132 | Addresses used by 16-bit code are segmented addresses (16:16), formed |
| 133 | by a 16-bit selector and a 16-bit offset. Those used by the Wine code |
| 134 | are regular 32-bit linear addresses. |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 135 | |
Alexandre Julliard | 1e37a18 | 1996-08-18 16:21:52 +0000 | [diff] [blame] | 136 | There are four ways to obtain a segmented pointer: |
| 137 | - Use the SEGPTR_* macros in include/heap.h (recommended). |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 138 | - Allocate a block of memory from the global heap and use |
| 139 | WIN16_GlobalLock to get its segmented address. |
| 140 | - Allocate a block of memory from a local heap, and build the |
| 141 | segmented address from the local heap selector (see the |
| 142 | USER_HEAP_* macros for an example of this). |
| 143 | - Declare the argument as 'segptr' instead of 'ptr' in the spec file |
| 144 | for a given API function. |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 145 | |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 146 | Once you have a segmented pointer, it must be converted to a linear |
| 147 | pointer before you can use it from 32-bit code. This can be done with |
| 148 | the PTR_SEG_TO_LIN() and PTR_SEG_OFF_TO_LIN() macros. The linear |
| 149 | pointer can then be used freely with standard Unix functions like |
| 150 | memcpy() etc. without worrying about 64k boundaries. Note: there's no |
| 151 | easy way to convert back from a linear to a segmented address. |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 152 | |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 153 | In most cases, you don't need to worry about segmented address, as the |
| 154 | conversion is made automatically by the callback code and the API |
| 155 | functions only see linear addresses. However, in some cases it is |
| 156 | necessary to manipulate segmented addresses; the most frequent cases |
| 157 | are: |
| 158 | - API functions that return a pointer |
| 159 | - lParam of Windows messages that point to a structure |
| 160 | - Pointers contained inside structures accessed by 16-bit code. |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 161 | |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 162 | It is usually a good practice to used the type 'SEGPTR' for segmented |
| 163 | pointers, instead of something like 'LPSTR' or 'char *'. As SEGPTR is |
| 164 | defined as a DWORD, you'll get a compilation warning if you mistakenly |
| 165 | use it as a regular 32-bit pointer. |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 166 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 167 | |
Alexandre Julliard | 2d93d00 | 1996-05-21 15:01:41 +0000 | [diff] [blame] | 168 | STRUCTURE PACKING |
| 169 | ================= |
| 170 | |
| 171 | Under Windows, data structures are tightly packed, i.e. there is no |
| 172 | padding between structure members. On the other hand, by default gcc |
| 173 | aligns structure members (e.g. WORDs are on a WORD boundary, etc.). |
| 174 | This means that a structure like |
| 175 | |
| 176 | struct { BYTE x; WORD y; }; |
| 177 | |
| 178 | will take 3 bytes under Windows, but 4 with gcc, because gcc will add a |
| 179 | dummy byte between x and y. To have the correct layout for structures |
| 180 | used by Windows code, you need to use the WINE_PACKED attribute; so you |
| 181 | would declare the above structure like this: |
| 182 | |
| 183 | struct { BYTE x; WORD y WINE_PACKED; }; |
| 184 | |
| 185 | You have to do this every time a structure member is not aligned |
| 186 | correctly under Windows (i.e. a WORD not on an even address, or a |
| 187 | DWORD on a address that is not a multiple of 4). |
| 188 | |
| 189 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 190 | NAMING CONVENTIONS FOR API FUNCTIONS AND TYPES |
| 191 | ============================================== |
| 192 | |
| 193 | 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] | 194 | code, the following convention must be used in naming all API |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 195 | functions and types. If the Windows API uses the name 'xxx', the Wine |
| 196 | code must use: |
| 197 | |
| 198 | - 'xxx16' for the 16-bit version, |
| 199 | - 'xxx32' for the 32-bit version when no ASCII/Unicode strings are |
| 200 | involved, |
| 201 | - 'xxx32A' for the 32-bit version with ASCII strings, |
| 202 | - 'xxx32W' for the 32-bit version with Unicode strings. |
| 203 | |
| 204 | You should then use the macros WINELIB_NAME[_AW](xxx) or |
| 205 | DECL_WINELIB_TYPE[_AW](xxx) (defined in include/wintypes.h) to define |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 206 | the correct 'xxx' function or type for Winelib. When compiling Wine |
| 207 | itself, 'xxx' is _not_ defined, meaning that code inside of Wine must |
| 208 | always specify explicitly the 16-bit or 32-bit version. |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 209 | |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 210 | If 'xxx' is the same in Win16 and Win32, or if 'xxx' is Win16 only, |
| 211 | you can simply use the same name as Windows, i.e. just 'xxx'. If |
| 212 | 'xxx' is Win32 only, you can use 'xxx' if there are no strings |
| 213 | involved, otherwise you must use the 'xxx32A' and 'xxx32W' forms. |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 214 | |
| 215 | Examples: |
| 216 | |
| 217 | typedef short INT16; |
| 218 | typedef int INT32; |
| 219 | DECL_WINELIB_TYPE(INT); |
| 220 | |
| 221 | typedef struct { /* Win32 ASCII data structure */ } WNDCLASS32A; |
| 222 | typedef struct { /* Win32 Unicode data structure */ } WNDCLASS32W; |
| 223 | typedef struct { /* Win16 data structure */ } WNDCLASS16; |
| 224 | DECL_WINELIB_TYPE_AW(WNDCLASS); |
| 225 | |
| 226 | ATOM RegisterClass16( WNDCLASS16 * ); |
| 227 | ATOM RegisterClass32A( WNDCLASS32A * ); |
| 228 | ATOM RegisterClass32W( WNDCLASS32W * ); |
| 229 | #define RegisterClass WINELIB_NAME_AW(RegisterClass) |
| 230 | |
| 231 | The Winelib user can then say: |
| 232 | |
| 233 | INT i; |
| 234 | WNDCLASS wc = { ... }; |
| 235 | RegisterClass( &wc ); |
| 236 | |
| 237 | and this will use the correct declaration depending on the definition |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 238 | of the symbols WINELIB and UNICODE. |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 239 | |
| 240 | |
| 241 | API ENTRY POINTS |
| 242 | ================ |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 243 | |
| 244 | Because Win16 programs use a 16-bit stack and because they can only |
| 245 | call 16:16 addressed functions, all API entry points must be at low |
| 246 | address offsets and must have the arguments translated and moved to |
| 247 | Wines 32-bit stack. This task is handled by the code in the "if1632" |
| 248 | directory. To define a new API entry point handler you must place a |
| 249 | new entry in the appropriate API specification file. These files are |
Alexandre Julliard | ca22b33 | 1996-07-12 19:02:39 +0000 | [diff] [blame] | 250 | named *.spec. For example, the API specification file for the USER |
| 251 | DLL is contained in the file user.spec. These entries are processed |
| 252 | by the "build" program to create an assembly file containing the entry |
| 253 | 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] | 254 | documented in the file "tools/build-spec.txt". |
| 255 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 256 | |
| 257 | DEBUG MESSAGES |
| 258 | ============== |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 259 | |
| 260 | To display a message only during debugging, you normally write something |
| 261 | like this: |
| 262 | |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 263 | TRACE(win,"abc..."); or |
| 264 | FIXME(win,"abc..."); or |
| 265 | WARN(win,"abc..."); or |
| 266 | ERR(win,"abc..."); |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 267 | |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 268 | depending on the seriousness of the problem. (documentation/degug-msgs |
| 269 | explains when it is appropriate to use each of them) |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 270 | |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 271 | These macros are defined in include/debug.h. The macro-definitions are |
| 272 | generated by the shell-script tools/make_debug. It scans the source |
| 273 | code for symbols of this forms and puts the necessary macro |
| 274 | definitions in include/debug.h and include/debugdefs.h. These macros |
| 275 | test whether the debugging "channel" associated with the first |
| 276 | argument of these macros (win in the above example) is enabled and |
| 277 | thus decide whether to actually display the text. In addition you can |
| 278 | change the types of displayed messages by supplying the "-debugmsg" |
| 279 | option to Wine. If your debugging code is more complex than just |
| 280 | printf, you can use the symbols TRACE_ON(xxx), WARN_ON(xxx), |
| 281 | ERR_ON(xxx) and FIXME_ON(xxx) as well. These are true when channel xxx |
| 282 | is enabled, either permanent or in the command line. Thus, you can |
| 283 | write: |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 284 | |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 285 | if(TRACE_ON(win))DumpSomeStructure(&str); |
Alexandre Julliard | 234bc24 | 1994-12-10 13:02:28 +0000 | [diff] [blame] | 286 | |
Alexandre Julliard | 234bc24 | 1994-12-10 13:02:28 +0000 | [diff] [blame] | 287 | 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] | 288 | 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] | 289 | eliminate the dead code. |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 290 | |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 291 | 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] | 292 | e.g. TRACE(win32). |
| 293 | |
| 294 | For more info about debugging messages, read: |
| 295 | |
| 296 | documentation/debug-msgs |
| 297 | |
Alexandre Julliard | 23946ad | 1997-06-16 17:43:53 +0000 | [diff] [blame] | 298 | |
| 299 | MORE INFO |
| 300 | ========= |
| 301 | |
Alexandre Julliard | 33072e1 | 1997-06-29 18:08:02 +0000 | [diff] [blame] | 302 | 1. There is a FREE online version of the MSDN library (including |
| 303 | documentation for the Win32 API) on http://www.microsoft.com/msdn/ |
Alexandre Julliard | 23946ad | 1997-06-16 17:43:53 +0000 | [diff] [blame] | 304 | |
Alexandre Julliard | 33072e1 | 1997-06-29 18:08:02 +0000 | [diff] [blame] | 305 | 2. http://www.sonic.net/~undoc/bookstore.html |
Alexandre Julliard | 23946ad | 1997-06-16 17:43:53 +0000 | [diff] [blame] | 306 | |
Alexandre Julliard | 33072e1 | 1997-06-29 18:08:02 +0000 | [diff] [blame] | 307 | 3. In 1993 Dr. Dobbs Journal published a column called "Undocumented Corner". |
| 308 | |
| 309 | 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] | 310 | |