Release 941017
[wine/gsoc-2012-control.git] / if1632 / callback.c
blob3d69c34652fb1f7c097e1406ea70c2f6d1bc6fc2
1 #ifndef WINELIB
2 static char RCSId[] = "$Id: wine.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
3 static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include "windows.h"
8 #include "callback.h"
9 #include "wine.h"
10 #include "segmem.h"
11 #include <setjmp.h>
12 #include "dlls.h"
13 extern SEGDESC Segments[];
14 extern unsigned short IF1632_Saved16_ss;
15 extern unsigned long IF1632_Saved16_ebp;
16 extern unsigned long IF1632_Saved16_esp;
17 extern unsigned short IF1632_Saved32_ss;
18 extern unsigned long IF1632_Saved32_ebp;
19 extern unsigned long IF1632_Saved32_esp;
21 extern struct segment_descriptor_s *MakeProcThunks;
23 struct thunk_s
25 int used;
26 unsigned char thunk[10];
29 static __inline__ int Is16bitAddress(void *address)
31 return ((unsigned int) address
32 >= (((FIRST_SELECTOR << 3) | 0x0007) << 16));
35 /**********************************************************************
36 * PushOn16
38 static void
39 PushOn16(int size, unsigned int value)
41 char *p = (char *) (((unsigned int)IF1632_Saved16_ss << 16) +
42 (IF1632_Saved16_esp & 0xffff));
43 if (size)
45 unsigned long *lp = (unsigned long *) p - 1;
47 *lp = value;
48 IF1632_Saved16_esp -= 4;
50 else
52 unsigned short *sp = (unsigned short *) p - 1;
54 *sp = value;
55 IF1632_Saved16_esp -= 2;
59 /**********************************************************************
60 * FindDataSegmentForCode
62 static unsigned short
63 FindDataSegmentForCode(unsigned long csip)
65 unsigned int seg_idx;
67 seg_idx = (unsigned short) (csip >> 19);
68 return Segments[seg_idx].owner;
71 /**********************************************************************
72 * CallBack16
74 int
75 CallBack16(void *func, int n_args, ...)
77 va_list ap;
78 int i;
79 int arg_type, arg_value;
81 va_start(ap, n_args);
83 for (i = 0; i < n_args; i++)
85 arg_type = va_arg(ap, int);
86 arg_value = va_arg(ap, int);
87 PushOn16(arg_type, arg_value);
90 va_end(ap);
92 return CallTo16((unsigned int) func,
93 FindDataSegmentForCode((unsigned long) func));
96 /**********************************************************************
97 * CALLBACK_MakeProcInstance
99 void *
100 CALLBACK_MakeProcInstance(void *func, int instance)
102 int handle;
103 void *new_func;
104 struct thunk_s *tp;
105 int i;
107 tp = (struct thunk_s *) MakeProcThunks->base_addr;
108 for (i = 0; i < 0x10000 / sizeof(*tp); i++, tp++)
109 if (!tp->used)
110 break;
112 if (tp->used)
113 return (void *) 0;
115 tp->thunk[0] = 0xb8;
116 tp->thunk[1] = (unsigned char) instance;
117 tp->thunk[2] = (unsigned char) (instance >> 8);
118 tp->thunk[3] = 0x8e;
119 tp->thunk[4] = 0xd8;
120 tp->thunk[5] = 0xea;
121 memcpy(&tp->thunk[6], &func, 4);
122 tp->used = 1;
124 return tp->thunk;
127 /**********************************************************************
128 * FreeProcInstance (KERNEL.52)
130 void FreeProcInstance(FARPROC func)
132 int handle;
133 void *new_func;
134 struct thunk_s *tp;
135 int i;
137 tp = (struct thunk_s *) MakeProcThunks->base_addr;
138 for (i = 0; i < 0x10000 / sizeof(*tp); i++, tp++)
140 if ((void *) tp->thunk == (void *) func)
142 tp->used = 0;
143 break;
148 /**********************************************************************
149 * GetCodeHandle (KERNEL.93)
151 HANDLE GetCodeHandle( FARPROC proc )
153 struct thunk_s *tp = (struct thunk_s *)proc;
155 /* Return the code segment containing 'proc'. */
156 /* Not sure if this is really correct (shouldn't matter that much). */
157 printf( "STUB: GetCodeHandle(%p) returning %x\n",
158 tp->thunk[8] + (tp->thunk[9] << 8) );
159 return tp->thunk[8] + (tp->thunk[9] << 8);
163 /**********************************************************************
164 * CallWindowProc (USER.122)
166 LONG CallWindowProc( WNDPROC func, HWND hwnd, WORD message,
167 WORD wParam, LONG lParam )
169 SpyMessage(hwnd, message, wParam, lParam);
171 if (HIWORD((LONG)func) == WINE_CODE_SELECTOR)
173 static struct dll_table_entry_s *user_tab = NULL;
174 void *address = (void *) ((LONG) func & 0xffff);
176 if (user_tab == NULL)
177 user_tab = FindDLLTable("USER");
179 /* DefWindowProc */
180 if (user_tab[107].address == address)
181 return DefWindowProc(hwnd, message, wParam, lParam);
183 /* DefDlgProc */
184 else if (user_tab[308].address == address)
185 return DefDlgProc(hwnd, message, wParam, lParam);
187 /* DefMDIChildProc */
188 else if (user_tab[447].address == address)
189 return DefMDIChildProc(hwnd, message, wParam, lParam);
191 /* default */
192 else
194 fprintf(stderr, "wine: Unknown wine callback %08x\n", func);
195 exit(1);
198 else if (Is16bitAddress(func))
200 #ifdef DEBUG_CALLBACK
201 printf("CallWindowProc // 16bit func=%08X !\n", func);
202 #endif
203 PushOn16( CALLBACK_SIZE_WORD, hwnd );
204 PushOn16( CALLBACK_SIZE_WORD, message );
205 PushOn16( CALLBACK_SIZE_WORD, wParam );
206 PushOn16( CALLBACK_SIZE_LONG, lParam );
207 return CallTo16((unsigned int) func,
208 FindDataSegmentForCode((unsigned long) func));
210 else
212 #ifdef DEBUG_CALLBACK
213 printf("CallWindowProc // 32bit func=%08X !\n", func);
214 #endif
215 return (*func)(hwnd, message, wParam, lParam);
219 /**********************************************************************
220 * CallLineDDAProc
222 void CallLineDDAProc(FARPROC func, short xPos, short yPos, long lParam)
224 if (Is16bitAddress(func))
226 PushOn16( CALLBACK_SIZE_WORD, xPos );
227 PushOn16( CALLBACK_SIZE_WORD, yPos );
228 PushOn16( CALLBACK_SIZE_LONG, lParam );
229 CallTo16((unsigned int) func,
230 FindDataSegmentForCode((unsigned long) func));
232 else
234 (*func)(xPos, yPos, lParam);
238 /**********************************************************************
239 * CallHookProc
241 DWORD CallHookProc( HOOKPROC func, short code, WPARAM wParam, LPARAM lParam )
243 if (Is16bitAddress(func))
245 PushOn16( CALLBACK_SIZE_WORD, code );
246 PushOn16( CALLBACK_SIZE_WORD, wParam );
247 PushOn16( CALLBACK_SIZE_LONG, lParam );
248 return CallTo16((unsigned int) func,
249 FindDataSegmentForCode((unsigned long) func));
251 else
253 return (*func)( code, wParam, lParam );
257 /**********************************************************************
258 * CallGrayStringProc
260 BOOL CallGrayStringProc(FARPROC func, HDC hdc, LPARAM lParam, INT cch )
262 if (Is16bitAddress(func))
264 PushOn16( CALLBACK_SIZE_WORD, hdc );
265 PushOn16( CALLBACK_SIZE_LONG, lParam );
266 PushOn16( CALLBACK_SIZE_WORD, cch );
267 return CallTo16((unsigned int) func,
268 FindDataSegmentForCode((unsigned long) func));
270 else
272 return (*func)( hdc, lParam, cch );
276 /* ------------------------------------------------------------------------ */
278 * The following functions realize the Catch/Throw functionality.
279 * My thought is to use the setjmp, longjmp combination to do the
280 * major part of this one. All I have to remember, in addition to
281 * whatever the jmp_buf contains, is the contents of the 16-bit
282 * sp, bp and ss. I do this by storing them in the structure passed
283 * to me by the 16-bit program (including my own jmp_buf...).
284 * Hopefully there isn't any program that modifies the contents!
285 * Bad thing: I have to save part of the stack, since this will
286 * get reused on the next call after my return, leaving it in an
287 * undefined state.
289 #define STACK_DEPTH_16 28
291 struct special_buffer {
292 jmp_buf buffer;
293 long regs [6];
294 char stack_part [STACK_DEPTH_16];
295 } *sb;
297 int Catch (LPCATCHBUF cbuf)
299 WORD retval;
300 jmp_buf *tmp_jmp;
301 char *stack16 = (char *) (((unsigned int)IF1632_Saved16_ss << 16) +
302 (IF1632_Saved16_esp & 0xffff));
304 sb = malloc (sizeof (struct special_buffer));
306 sb -> regs [0] = IF1632_Saved16_esp;
307 sb -> regs [1] = IF1632_Saved16_ebp;
308 sb -> regs [2] = IF1632_Saved16_ss & 0xffff;
309 sb -> regs [3] = IF1632_Saved32_esp;
310 sb -> regs [4] = IF1632_Saved32_ebp;
311 sb -> regs [5] = IF1632_Saved32_ss & 0xffff;
312 memcpy (sb -> stack_part, stack16, STACK_DEPTH_16);
313 tmp_jmp = &sb -> buffer;
314 *((struct special_buffer **)cbuf) = sb;
316 if ((retval = setjmp (*tmp_jmp)))
318 IF1632_Saved16_esp = sb -> regs [0];
319 IF1632_Saved16_ebp = sb -> regs [1];
320 IF1632_Saved16_ss = sb -> regs [2] & 0xffff;
321 IF1632_Saved32_esp = sb -> regs [3];
322 IF1632_Saved32_ebp = sb -> regs [4];
323 IF1632_Saved32_ss = sb -> regs [5] & 0xffff;
324 stack16 = (char *) (((unsigned int)IF1632_Saved16_ss << 16) +
325 (IF1632_Saved16_esp & 0xffff));
327 memcpy (stack16, sb -> stack_part, STACK_DEPTH_16);
328 #ifdef DEBUG_CATCH
329 printf ("Been thrown here: %d, retval = %d\n", sb, retval);
330 #endif
331 free ((void *) sb);
332 return (retval);
333 } else {
334 #ifdef DEBUG_CATCH
335 printf ("Will somtime get thrown here: %d\n", sb);
336 #endif
337 return (retval);
341 void Throw (LPCATCHBUF cbuf, int val)
343 sb = *((struct special_buffer **)cbuf);
344 #ifdef DEBUG_CATCH
345 printf ("Throwing to: %d\n", sb);
346 #endif
347 longjmp (sb -> buffer, val);
349 #endif /* !WINELIB */