Started on an implementation of Win64 for use on 64 bit platforms.
[wine] / tools / make_X11wrappers
1 #!/usr/bin/perl -w
2
3 # Create threads safe wrappers around X11 calls.
4 #
5 # Copyright 1998 Kristian Nielsen.
6 #
7
8 # FIXME: This does not do full C prototype parsing, but relies on
9 # knowledge on how the X11 include files are formatted. It will
10 # probably need to be modified for new include files. It also fails
11 # for certain prototypes (notably those with function pointer
12 # arguments or results), so these must be added manually. And it
13 # relies on a fixed location of X11 includes (/usr/X11R6/include/).
14 #
15 # This program expects to be run from Wine's main directory.
16
17 $X11_include_dir = "/usr/X11R6/include";
18 $outdir = "tsx11";
19 $wantfile = "$outdir/X11_calls";
20 @dolist = ("Xlib", "Xresource", "Xutil", "xpm", "XShm", "xf86dga", "xf86vmode");
21
22 # First read list of wanted function names.
23
24 open(WANT, $wantfile) || die "open";
25 while(<WANT>) {
26     next if /^\s*\#/;           # Skip comment lines.
27     next if /^\s*$/;            # Skip empty lines.
28     if(/^\s*([a-zA-Z0-9_]+)\s*$/) {
29         $want{$1} = 1;
30     } else {
31         die "syntax error in file '$wantfile', in line '$_'";
32     }
33 }
34 close(WANT);
35
36 foreach $name (@dolist) {
37
38     $ucname = uc $name;
39     $lcname = lc $name;
40
41     $outfile = "/ts_$lcname";
42     open(OUTC, ">$outdir/$outfile.c") || die "open";
43     open(OUTH, ">include/$outfile.h") || die "open";
44
45     $x11_incl = "";
46     $extensions_dir = "";
47     $pre_file = "";
48     $post_file = "";
49     if($name eq "Xutil" || $name eq "Xresource" || $name eq "XShm") {
50         $x11_incl = "#include <X11/Xlib.h>\n";
51         # For Xutil, we need X11/Xresource.h for XUniqueContext().
52         $x11_incl .= "#include <X11/Xresource.h>\n" if $name eq "Xutil";
53     }
54     if($name eq "xf86dga")  {
55         $x11_incl = "#include <X11/Xlib.h>\n";
56         $extensions_dir = "extensions/";
57         $pre_file = "#ifdef HAVE_LIBXXF86DGA\n";
58         $post_file = "#endif /* defined(HAVE_LIBXXF86DGA) */\n";
59     }
60     if($name eq "XShm") {
61         $extensions_dir = "extensions/";
62         $pre_file = "#ifdef HAVE_LIBXXSHM\n";
63         $post_file = "#endif /* defined(HAVE_LIBXXSHM) */\n";
64     }
65     if($name eq "xpm") {
66         $pre_file = "#ifdef HAVE_LIBXXPM\n";
67         $post_file = "#endif /* defined(HAVE_LIBXXPM) */\n";
68     }
69     if($name eq "xf86vmode") {
70         $x11_incl = "#include <X11/Xlib.h>\n";
71         $extensions_dir = "extensions/";
72         $pre_file = "#include \"windef.h\"\n#ifdef HAVE_LIBXXF86VM\n#define XMD_H\n#include \"basetsd.h\"\n";
73         $post_file = "#endif /* defined(HAVE_LIBXXF86VM) */\n";
74     }
75
76     print OUTH <<END;
77 /*
78  * Thread safe wrappers around $name calls.
79  * Always include this file instead of <X11/$name.h>.
80  * This file was generated automatically by tools/make_X11wrappers
81  *
82  * Copyright 1998 Kristian Nielsen
83  */
84
85 #ifndef __WINE_TS_$ucname\_H
86 #define __WINE_TS_$ucname\_H
87
88 #include "config.h"
89
90 #ifndef X_DISPLAY_MISSING
91
92 $pre_file
93 $x11_incl#include <X11/$extensions_dir$name.h>
94
95 END
96
97     print OUTC <<END;
98 /*
99  * Thread safe wrappers around $name calls.
100  * This file was generated automatically by tools/make_X11wrappers
101  * DO NOT EDIT!
102  */
103
104 #include "config.h"
105
106 #ifndef X_DISPLAY_MISSING
107
108 $pre_file
109 $x11_incl#include <X11/$extensions_dir$name.h>
110 #include "debugtools.h"
111 #include "x11drv.h"
112
113 DEFAULT_DEBUG_CHANNEL(x11)
114 END
115
116     if($name eq "xpm") {        # Handle as special case.
117         output_fn("XpmCreatePixmapFromData", "int",
118                   "Display *, Drawable, char **, Pixmap *, Pixmap *, XpmAttributes *",
119                   "Display *a0, Drawable a1, char **a2, Pixmap *a3, Pixmap *a4, XpmAttributes *a5",
120                   "a0, a1, a2, a3, a4, a5");
121         output_fn("XpmAttributesSize", "int", "void", "void", "");
122     } elsif($name eq "XShm") {
123         output_fn("XShmQueryExtension", "Bool",
124                   "Display *", "Display *a0", "a0");
125         output_fn("XShmQueryVersion", "Bool",
126                   "Display *, int *, int *, Bool *", 
127                   "Display *a0, int *a1, int *a2, Bool *a3", "a0, a1, a2, a3");
128         output_fn("XShmPixmapFormat", "int",
129                   "Display *", "Display *a0", "a0");
130         output_fn("XShmAttach", Status,
131                   "Display *, XShmSegmentInfo *",
132                   "Display *a0, XShmSegmentInfo *a1", "a0, a1");
133         output_fn("XShmDetach", Status,
134                   "Display *, XShmSegmentInfo *",
135                   "Display *a0, XShmSegmentInfo *a1", "a0, a1");
136         output_fn("XShmPutImage", Status,
137                   "Display *, Drawable, GC, XImage *, int, int, int, int, unsigned int, unsigned int, Bool",
138                   "Display *a0, Drawable a1, GC a2, XImage *a3, int a4, int a5, int a6, int a7, unsigned int a8, unsigned int a9, Bool a10", "a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10");
139         output_fn("XShmGetImage", Status,
140                   "Display *, Drawable, XImage *, int, int, unsigned long",
141                   "Display *a0, Drawable a1, XImage *a2, int a3, int a4, unsigned long a5", 
142                   "a0, a1, a2, a3, a4, a5");
143         output_fn("XShmCreateImage", "XImage *",
144                   "Display *, Visual *, unsigned int, int, char *, XShmSegmentInfo *, unsigned int, unsigned int",
145                   "Display *a0, Visual *a1, unsigned int a2, int a3, char *a4, XShmSegmentInfo *a5, unsigned int a6, unsigned int a7",
146                   "a0, a1, a2, a3, a4, a5, a6, a7");
147         output_fn("XShmCreatePixmap", "Pixmap",
148                   "Display *, Drawable, char *, XShmSegmentInfo *, unsigned int, unsigned int, unsigned int",
149                   "Display *a0, Drawable a1, char *a2, XShmSegmentInfo *a3, unsigned int a4, unsigned int a5, unsigned int a6",
150                   "a0, a1, a2, a3, a4, a5, a6");
151     } elsif($name eq "xf86dga") {
152         output_fn("XF86DGAQueryVersion",Bool,
153                 "Display*,int*,int*",
154                 "Display*a0,int*a1,int*a2",
155                 "a0,a1,a2"
156         );
157         output_fn("XF86DGAQueryExtension",Bool,
158                 "Display*,int*,int*",
159                 "Display*a0,int*a1,int*a2",
160                 "a0,a1,a2"
161         );
162         output_fn("XF86DGAGetVideo",Status,
163                 "Display*,int,char**,int*,int*,int*",
164                 "Display*a0,int a1,char**a2,int*a3,int*a4,int*a5",
165                 "a0,a1,a2,a3,a4,a5"
166         );
167         output_fn("XF86DGADirectVideo",Status,
168                 "Display*,int,int",
169                 "Display*a0,int a1,int a2",
170                 "a0,a1,a2"
171         );
172         output_fn("XF86DGAGetViewPortSize",Status,
173                 "Display*,int,int*,int*",
174                 "Display*a0,int a1,int *a2,int *a3",
175                 "a0,a1,a2,a3"
176         );
177         output_fn("XF86DGASetViewPort",Status,
178                 "Display*,int,int,int",
179                 "Display*a0,int a1,int a2,int a3",
180                 "a0,a1,a2,a3"
181         );
182         output_fn("XF86DGAInstallColormap",Status,
183                 "Display*,int,Colormap",
184                 "Display*a0,int a1,Colormap a2",
185                 "a0,a1,a2"
186         );
187         output_fn("XF86DGAQueryDirectVideo",Status,
188                 "Display*,int,int*",
189                 "Display*a0,int a1,int *a2",
190                 "a0,a1,a2"
191         );
192         output_fn("XF86DGAViewPortChanged",Status,
193                 "Display*,int,int",
194                 "Display*a0,int a1,int a2",
195                 "a0,a1,a2"
196         );
197     } elsif($name eq "xf86vmode") {
198         output_fn("XF86VidModeQueryVersion",Bool,
199                 "Display*,int*,int*",
200                 "Display*a0,int*a1,int*a2",
201                 "a0,a1,a2"
202         );
203         output_fn("XF86VidModeQueryExtension",Bool,
204                 "Display*,int*,int*",
205                 "Display*a0,int*a1,int*a2",
206                 "a0,a2,a2"
207         );
208         output_fn("XF86VidModeGetModeLine",Bool,
209                 "Display*,int,int*,XF86VidModeModeLine*",
210                 "Display*a0,int a1,int*a2,XF86VidModeModeLine*a3",
211                 "a0,a1,a2,a3"
212         );
213         output_fn("XF86VidModeGetAllModeLines",Bool,
214                 "Display*,int,int*,XF86VidModeModeInfo***",
215                 "Display*a0,int a1,int*a2,XF86VidModeModeInfo***a3",
216                 "a0,a1,a2,a3"
217         );
218         output_fn("XF86VidModeAddModeLine",Bool,
219                 "Display*,int,XF86VidModeModeInfo*,XF86VidModeModeInfo*",
220                 "Display*a0,int a1,XF86VidModeModeInfo*a2,XF86VidModeModeInfo*a3",
221                 "a0,a1,a2,a3"
222         );
223         output_fn("XF86VidModeDeleteModeLine",Bool,
224                 "Display*,int,XF86VidModeModeInfo*",
225                 "Display*a0,int a1,XF86VidModeModeInfo*a2",
226                 "a0,a1,a2"
227         );
228         output_fn("XF86VidModeModModeLine",Bool,
229                 "Display*,int,XF86VidModeModeLine*",
230                 "Display*a0,int a1,XF86VidModeModeLine*a2",
231                 "a0,a1,a2"
232         );
233         output_fn("XF86VidModeValidateModeLine",Status,
234                 "Display*,int,XF86VidModeModeInfo*",
235                 "Display*a0,int a1,XF86VidModeModeInfo*a2",
236                 "a0,a1,a2"
237         );
238         output_fn("XF86VidModeSwitchMode",Bool,
239                 "Display*,int,int",
240                 "Display*a0,int a1,int a2",
241                 "a0,a1,a2"
242         );
243         output_fn("XF86VidModeSwitchToMode",Bool,
244                 "Display*,int,XF86VidModeModeInfo*",
245                 "Display*a0,int a1,XF86VidModeModeInfo*a2",
246                 "a0,a1,a2"
247         );
248         output_fn("XF86VidModeLockModeSwitch",Bool,
249                 "Display*,int,int",
250                 "Display*a0,int a1,int a2",
251                 "a0,a1,a2"
252         );
253         output_fn("XF86VidModeGetMonitor",Bool,
254                 "Display*,int,XF86VidModeMonitor*",
255                 "Display*a0,int a1,XF86VidModeMonitor*a2",
256                 "a0,a1,a2"
257         );
258         output_fn("XF86VidModeGetViewPort",Bool,
259                 "Display*,int,int*,int*",
260                 "Display*a0,int a1,int*a2,int*a3",
261                 "a0,a1,a2,a3"
262         );
263         output_fn("XF86VidModeSetViewPort",Bool,
264                 "Display*,int,int,int",
265                 "Display*a0,int a1,int a2,int a3",
266                 "a0,a1,a2,a3"
267         );      
268     } else {
269         open(IN, "echo \"$x11_incl#include <X11/$extensions_dir$name.h>\" | gcc -L$X11_include_dir -E - | grep -v '^[ \t]*\$'|") || die "open";
270
271       PROTO: while(<IN>) {
272           if(m'extern\s+([^()]*)\b([a-zA-Z0-9_]+)\s*\(') {
273               $result_type = $1;
274               $fn_name = $2;
275               $result_type = "int" if $result_type =~ /^\s*$/;
276               @args = ();
277               while(<IN>) {
278                   last if m'\)\s*;';
279                   # Give up on vararg functions and function pointer args.
280                   if(m'\.\.\.|\(\*\)') {
281                       undef $fn_name;
282                       last;
283                   }
284                   if(m'\s*([^,]*[^, \t])\s*(,?\n)') {
285                       $args[$#args+1] = $1;
286                       if ($1 =~ /char\s*\[/) { # small hack for XQueryKeymap
287                         $args[$#args] = "char*";
288                       }
289                   }
290               }
291               # Skip if vararg, function pointer arg, or not needed.
292               next unless $fn_name;
293               next unless $want{$fn_name} && $want{$fn_name} == 1;
294
295               # Special case for no arguments (which is specified as "void").
296               if($#args == 0 && $args[0] eq "void") {
297                   @args = ();
298               }
299               $proto = "";
300               $formals = "";
301               $actuals = "";
302               for($i = 0; $i <= $#args; $i++) {
303                   $comma = $i < $#args ? ", " : "";
304                   $proto .= "$args[$i]$comma";
305                   $formals .= "$args[$i] a$i$comma";
306                   $actuals .= "a$i$comma";
307               }
308               $proto = $formals = "void" if $#args == -1;
309               output_fn($fn_name, $result_type, $proto, $formals, $actuals);
310           }
311       }
312     }
313
314     if($name eq "Xlib") {
315         raw_output_fn("XSynchronize", "int (*r)(Display *)",
316                   "int (*TSXSynchronize(Display *, Bool))(Display *)",
317                   "int (*TSXSynchronize(Display *a0, Bool a1))(Display *)",
318                   "a0, a1");
319         print OUTC "\nextern void _XInitImageFuncPtrs(XImage *);\n";
320         output_fn("_XInitImageFuncPtrs", "void", "XImage *", "XImage *a0", "a0");
321     } elsif($name eq "Xutil") {
322         output_fn("XDestroyImage", "int",
323                   "struct _XImage *", "struct _XImage *a0", "a0");
324         output_fn("XGetPixel", "unsigned long",
325                   "struct _XImage *, int, int",
326                   "struct _XImage *a0, int a1, int a2",
327                   "a0, a1, a2");
328         output_fn("XPutPixel", "int",
329                   "struct _XImage *, int, int, unsigned long",
330                   "struct _XImage *a0, int a1, int a2, unsigned long a3",
331                   "a0, a1, a2, a3");
332         output_fn("XSubImage", "struct _XImage *",
333                   "struct _XImage *, int, int, unsigned int, unsigned int",
334                   "struct _XImage *a0, int a1, int a2, unsigned int a3, unsigned int a4",
335                   "a0, a1, a2, a3, a4");
336         output_fn("XAddPixel", "int",
337                   "struct _XImage *, long",
338                   "struct _XImage *a0, long a1", "a0, a1");
339         output_fn("XUniqueContext", "XContext", "void", "void", "");
340     }
341
342     print OUTH <<END;
343
344 $post_file
345 #endif /* !defined(X_DISPLAY_MISSING) */
346
347 #endif /* __WINE_TS_$ucname\_H */
348 END
349     print OUTC <<END;
350
351 $post_file
352 #endif /* !defined(X_DISPLAY_MISSING) */
353 END
354
355
356
357 }
358
359 foreach $i (keys %want) {
360     if($want{$i} == 1) {
361         print "Unresolved: $i\n";
362     }
363 }
364
365
366 sub output_fn {
367     # Example call:
368     # output_fn("main", "int", "int, char **", "int a0, char **a1", "a0, a1")
369     #
370
371     my ($fn_name, $result_type, $protos, $formals, $actuals) = @_;
372
373     return raw_output_fn($fn_name,
374                          $result_type =~ /^\s*void\s*$/ ? "" : "$result_type r",
375                          "$result_type TS$fn_name($protos)",
376                          "$result_type TS$fn_name($formals)",
377                          $actuals);
378 }
379
380 sub raw_output_fn {
381     # Example call:
382     # output_fn("main", "int r", "int main(int, char **)", "int main(int a0, char **a1)", "a0, a1")
383     #
384
385     my ($fn_name, $resultdecl, $protodecl, $defdecl, $actuals) = @_;
386
387     return undef unless $want{$fn_name} && $want{$fn_name} == 1;
388
389     print OUTC "\n$defdecl\n";
390     print OUTH "extern $protodecl;\n";
391 #    print OUTH "#define $fn_name TS$fn_name\n";
392     print OUTC "{\n";
393     print OUTC "  $resultdecl;\n" if $resultdecl;
394     print OUTC "  TRACE(\"Call $fn_name\\n\");\n";
395     print OUTC "  EnterCriticalSection( &X11DRV_CritSection );\n";
396     print OUTC "  ";
397     print OUTC "r = " if $resultdecl;
398     print OUTC "$fn_name($actuals);\n";
399     print OUTC "  LeaveCriticalSection( &X11DRV_CritSection );\n";
400     print OUTC "  TRACE(\"Ret $fn_name\\n\");\n";
401     print OUTC "  return r;\n" if $resultdecl;
402     print OUTC "}\n";
403     $want{$fn_name} = 2;
404     return 1;
405 }