Fixed ANSI compabillity.
[wine] / misc / callback.c
1 /*
2  * Function callbacks for the library
3  *
4  * Copyright 1997 Alexandre Julliard
5  */
6
7 #include <assert.h>
8 #include "winuser.h"
9 #include "callback.h"
10 #include "task.h"
11 #include "syslevel.h"
12 #include "cursoricon.h"
13 #include "user.h"
14 #include "queue.h"
15 #include "debug.h"
16 #include "win.h"
17
18 DEFAULT_DEBUG_CHANNEL(relay)
19
20
21 /**********************************************************************
22  *           CALLBACK_CallWndProc
23  */
24 static LRESULT WINAPI CALLBACK_CallWndProc( WNDPROC16 proc, HWND16 hwnd,
25                                             UINT16 msg, WPARAM16 wParam,
26                                             LPARAM lParam )
27 {
28     LRESULT retvalue;
29     int iWndsLocks;
30
31     /* To avoid any deadlocks, all the locks on the windows structures
32        must be suspended before the control is passed to the application */
33     iWndsLocks = WIN_SuspendWndsLock();
34     retvalue = proc( hwnd, msg, wParam, lParam );
35     WIN_RestoreWndsLock(iWndsLocks);
36     return retvalue;
37 }
38
39
40 /**********************************************************************
41  *           CALLBACK_CallRegisterProc
42  */
43 static LONG WINAPI CALLBACK_CallRegisterProc( CONTEXT *context, INT offset)
44 {
45     ERR(relay, "Cannot call a register proc in Winelib\n" );
46     assert( FALSE );
47     return 0;
48 }
49
50
51 /**********************************************************************
52  *           CALLBACK_CallDriverProc
53  */
54 static LRESULT WINAPI CALLBACK_CallDriverProc( DRIVERPROC16 proc, DWORD dwId,
55                                                HDRVR16 hdrvr, UINT16 msg,
56                                                LPARAM lp1, LPARAM lp2 )
57 {
58     return proc( dwId, hdrvr, msg, lp1, lp2 );
59 }
60
61
62 /**********************************************************************
63  *           CALLBACK_CallDriverCallback
64  */
65 static LRESULT WINAPI CALLBACK_CallDriverCallback( FARPROC16 proc,
66                                                    HANDLE16 hDev, UINT16 msg,
67                                                    DWORD dwUser, LPARAM lp1,
68                                                    LPARAM lp2 )
69 {
70     return proc( hDev, msg, dwUser, lp1, lp2 );
71 }
72
73
74 /**********************************************************************
75  *           CALLBACK_CallTimeFuncProc
76  */
77 static LRESULT WINAPI CALLBACK_CallTimeFuncProc( FARPROC16 proc, WORD id,
78                                                  UINT16 msg, DWORD dwUser,
79                                                  LPARAM lp1, LPARAM lp2 )
80 {
81     return proc( id, msg, dwUser, lp1, lp2 );
82 }
83
84
85 /**********************************************************************
86  *           CALLBACK_CallWindowsExitProc
87  */
88 static INT16 WINAPI CALLBACK_CallWindowsExitProc( FARPROC16 proc, INT16 type)
89 {
90     return proc( type );
91 }
92
93
94 /**********************************************************************
95  *           CALLBACK_CallWordBreakProc
96  */
97 static INT16 WINAPI CALLBACK_CallWordBreakProc( EDITWORDBREAKPROC16 proc,
98                                                 SEGPTR text, INT16 word,
99                                                 INT16 len, INT16 action )
100 {
101     return proc( (LPSTR)text, word, len, action );
102 }
103
104
105 /**********************************************************************
106  *           CALLBACK_CallBootAppProc
107  */
108 static void WINAPI CALLBACK_CallBootAppProc( FARPROC16 proc, HANDLE16 module,
109                                              HFILE16 file )
110 {
111     proc( module, file );
112 }
113
114
115 /**********************************************************************
116  *           CALLBACK_CallLoadAppSegProc
117  */
118 static WORD WINAPI CALLBACK_CallLoadAppSegProc( FARPROC16 proc,
119                                                 HANDLE16 module, HFILE16 file,
120                                                 WORD seg )
121 {
122     return proc( module, file, seg );
123 }
124
125
126 /**********************************************************************
127  *           CALLBACK_CallLocalNotifyFunc
128  */
129 static WORD WINAPI CALLBACK_CallLocalNotifyFunc( FARPROC16 proc,
130                                                  WORD wMsg, HLOCAL16 hMem,
131                                                  WORD wArg )
132 {
133     return proc( wMsg, hMem, wArg );
134 }
135
136
137 /**********************************************************************
138  *           CALLBACK_CallResourceHandlerProc
139  */
140 static HGLOBAL16 WINAPI CALLBACK_CallResourceHandlerProc( FARPROC16 proc,
141                                                           HGLOBAL16 hMemObj, 
142                                                           HMODULE16 hModule,
143                                                           HRSRC16 hRsrc )
144 {
145     ERR( relay, "Cannot call a 16-bit resource handler in Winelib\n" );
146     assert( FALSE );
147     return 0;
148 }
149
150
151 /**********************************************************************
152  *           CALLBACK_CallASPIPostProc
153  */
154 static LRESULT WINAPI CALLBACK_CallASPIPostProc( FARPROC16 proc, SEGPTR ptr )
155 {
156     return proc( ptr );
157 }
158
159
160 /**********************************************************************
161  *           CALLBACK_CallWOWCallbackProc
162  */
163 static DWORD WINAPI CALLBACK_CallWOWCallbackProc( FARPROC16 proc, DWORD dw )
164 {
165     return proc( dw );
166 }
167
168 /**********************************************************************
169  *           CALLBACK_CallWOWCallback16Ex
170  *
171  * WCB16_MAX_CBARGS (16) is the maximum number of args.
172  *
173  * Can call functions using CDECL or PASCAL calling conventions. The CDECL
174  * ones are reversed (not 100% sure about that).
175  */
176 static BOOL WINAPI CALLBACK_CallWOWCallback16Ex( 
177         FARPROC16 proc, DWORD dwFlags, DWORD cbArgs, LPVOID xargs,LPDWORD pdwret
178 ) {
179     LPDWORD     args = (LPDWORD)xargs;
180     DWORD       ret,i;
181
182     if (dwFlags == WCB16_CDECL) {
183         /* swap the arguments */
184         args = HeapAlloc(GetProcessHeap(),0,cbArgs*sizeof(DWORD));
185         for (i=0;i<cbArgs;i++)
186                 args[i] = ((DWORD*)xargs)[cbArgs-i-1];
187     }
188     switch (cbArgs) {
189     case 0: ret = proc();break;
190     case 1: ret = proc(args[0]);break;
191     case 2: ret = proc(args[0],args[1]);break;
192     case 3: ret = proc(args[0],args[1],args[2]);break;
193     case 4: ret = proc(args[0],args[1],args[2],args[3]);break;
194     case 5: ret = proc(args[0],args[1],args[2],args[3],args[4]);break;
195     case 6: ret = proc(args[0],args[1],args[2],args[3],args[4],args[5]);
196             break;
197     case 7: ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
198                     args[6]
199             );
200             break;
201     case 8: ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
202                     args[6],args[7]
203             );
204             break;
205     case 9: ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
206                     args[6],args[7],args[8]
207             );
208             break;
209     case 10:ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
210                     args[6],args[7],args[8],args[9]
211             );
212             break;
213     case 11:ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
214                     args[6],args[7],args[8],args[9],args[10]
215             );
216             break;
217     case 12:ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
218                     args[6],args[7],args[8],args[9],args[10],args[11]
219             );
220             break;
221     case 13:ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
222                     args[6],args[7],args[8],args[9],args[10],args[11],
223                     args[12]
224             );
225             break;
226     case 14:ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
227                     args[6],args[7],args[8],args[9],args[10],args[11],
228                     args[12],args[13]
229             );
230             break;
231     case 15:ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
232                     args[6],args[7],args[8],args[9],args[10],args[11],
233                     args[12],args[13],args[14]
234             );
235             break;
236     case 16:ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
237                     args[6],args[7],args[8],args[9],args[10],args[11],
238                     args[12],args[13],args[14],args[15]
239             );
240             break;
241     default:
242             WARN(relay,"(%ld) arguments not supported.\n",cbArgs);
243             if (dwFlags == WCB16_CDECL)
244                 HeapFree(GetProcessHeap(),0,args);
245             return FALSE;
246     }
247     if (dwFlags == WCB16_CDECL)
248         HeapFree(GetProcessHeap(),0,args);
249     if (pdwret) 
250         *pdwret = ret;
251     return TRUE;
252 }
253
254 /**********************************************************************
255  *           CALLBACK_CallUTProc
256  */
257 static DWORD WINAPI CALLBACK_CallUTProc( FARPROC16 proc, DWORD w1, DWORD w2 )
258 {
259     ERR( relay, "Cannot call a UT thunk proc in Winelib\n" );
260     assert( FALSE );
261     return 0;
262 }
263
264 /**********************************************************************
265  *           CALLBACK_CallTaskRescheduleProc
266  */
267 static BOOL WINAPI CALLBACK_CallTaskRescheduleProc( void )
268 {
269     BOOL pending;
270
271     SYSLEVEL_EnterWin16Lock();
272     pending = TASK_Reschedule();
273     SYSLEVEL_LeaveWin16Lock();
274
275     return pending;
276 }
277
278
279 /**********************************************************************
280  *           CALLBACK_WinelibTable
281  *
282  * The callbacks function table for Winelib
283  */
284 static const CALLBACKS_TABLE CALLBACK_WinelibTable =
285 {
286     CALLBACK_CallRegisterProc,        /* CallRegisterShortProc */
287     CALLBACK_CallRegisterProc,        /* CallRegisterLongProc */
288     CALLBACK_CallTaskRescheduleProc,  /* CallTaskRescheduleProc */
289     NULL,                             /* CallFrom16WndProc */
290     CALLBACK_CallWndProc,             /* CallWndProc */
291     CALLBACK_CallDriverProc,          /* CallDriverProc */
292     CALLBACK_CallDriverCallback,      /* CallDriverCallback */
293     CALLBACK_CallTimeFuncProc,        /* CallTimeFuncProc */
294     CALLBACK_CallWindowsExitProc,     /* CallWindowsExitProc */
295     CALLBACK_CallWordBreakProc,       /* CallWordBreakProc */
296     CALLBACK_CallBootAppProc,         /* CallBootAppProc */
297     CALLBACK_CallLoadAppSegProc,      /* CallLoadAppSegProc */
298     CALLBACK_CallLocalNotifyFunc,     /* CallLocalNotifyFunc */
299     CALLBACK_CallResourceHandlerProc, /* CallResourceHandlerProc */
300     CALLBACK_CallWOWCallbackProc,     /* CallWOWCallbackProc */
301     CALLBACK_CallWOWCallback16Ex,     /* CallWOWCallback16Ex */
302     CALLBACK_CallUTProc,              /* CallUTProc */
303     CALLBACK_CallASPIPostProc,        /* CallASPIPostProc */
304     /* The graphics driver callbacks are never used in Winelib */
305     NULL,                             /* CallDrvControlProc */
306     NULL,                             /* CallDrvEnableProc */
307     NULL,                             /* CallDrvEnumDFontsProc */
308     NULL,                             /* CallDrvEnumObjProc */
309     NULL,                             /* CallDrvOutputProc */
310     NULL,                             /* CallDrvRealizeProc */
311     NULL,                             /* CallDrvStretchBltProc */
312     NULL,                             /* CallDrvExtTextOutProc */
313     NULL,                             /* CallDrvGetCharWidth */
314     NULL                              /* CallDrvAbortProc */
315 };
316
317 const CALLBACKS_TABLE *Callbacks = &CALLBACK_WinelibTable;
318
319
320 /**********************************************************************
321  *           CALLOUT_Table
322  *
323  * The callout function table for Winelib
324  */
325
326 CALLOUT_TABLE Callout = 
327 {
328     PeekMessage16, PeekMessageA, PeekMessageW,
329     GetMessage16, GetMessageA, GetMessageW,
330     SendMessage16, SendMessageA, SendMessageW,
331     PostMessage16, PostMessageA, PostMessageW,
332     PostAppMessage16, PostThreadMessageA, PostThreadMessageW,
333     TranslateMessage16, TranslateMessage,
334     DispatchMessage16, DispatchMessageA, DispatchMessageW,
335     RedrawWindow16, RedrawWindow,
336     UserSignalProc,
337     InitApp16, InitThreadInput16,
338     UserYield16,
339     CURSORICON_Destroy
340 };
341