Release 940804
[wine/gsoc-2012-control.git] / if1632 / callback.c
blob3d9fefc24f4340c1eaa60740f852d9bc49e85ac4
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 /**********************************************************************
30 * PushOn16
32 static void
33 PushOn16(int size, unsigned int value)
35 char *p = (char *) (((unsigned int)IF1632_Saved16_ss << 16) +
36 (IF1632_Saved16_esp & 0xffff));
37 if (size)
39 unsigned long *lp = (unsigned long *) p - 1;
41 *lp = value;
42 IF1632_Saved16_esp -= 4;
44 else
46 unsigned short *sp = (unsigned short *) p - 1;
48 *sp = value;
49 IF1632_Saved16_esp -= 2;
53 /**********************************************************************
54 * FindDataSegmentForCode
56 static unsigned short
57 FindDataSegmentForCode(unsigned long csip)
59 unsigned int seg_idx;
61 seg_idx = (unsigned short) (csip >> 19);
62 return Segments[seg_idx].owner;
65 /**********************************************************************
66 * CallBack16
68 int
69 CallBack16(void *func, int n_args, ...)
71 va_list ap;
72 int i;
73 int arg_type, arg_value;
75 va_start(ap, n_args);
77 for (i = 0; i < n_args; i++)
79 arg_type = va_arg(ap, int);
80 arg_value = va_arg(ap, int);
81 PushOn16(arg_type, arg_value);
84 va_end(ap);
86 return CallTo16((unsigned int) func,
87 FindDataSegmentForCode((unsigned long) func));
90 /**********************************************************************
91 * CALLBACK_MakeProcInstance
93 void *
94 CALLBACK_MakeProcInstance(void *func, int instance)
96 int handle;
97 void *new_func;
98 struct thunk_s *tp;
99 int i;
101 tp = (struct thunk_s *) MakeProcThunks->base_addr;
102 for (i = 0; i < 0x10000 / sizeof(*tp); i++, tp++)
103 if (!tp->used)
104 break;
106 if (tp->used)
107 return (void *) 0;
109 tp->thunk[0] = 0xb8;
110 tp->thunk[1] = (unsigned char) instance;
111 tp->thunk[2] = (unsigned char) (instance >> 8);
112 tp->thunk[3] = 0x8e;
113 tp->thunk[4] = 0xd8;
114 tp->thunk[5] = 0xea;
115 memcpy(&tp->thunk[6], &func, 4);
116 tp->used = 1;
118 return tp->thunk;
121 /**********************************************************************
122 * FreeProcInstance (KERNEL.52)
124 void FreeProcInstance(FARPROC func)
126 int handle;
127 void *new_func;
128 struct thunk_s *tp;
129 int i;
131 tp = (struct thunk_s *) MakeProcThunks->base_addr;
132 for (i = 0; i < 0x10000 / sizeof(*tp); i++, tp++)
134 if ((void *) tp->thunk == (void *) func)
136 tp->used = 0;
137 break;
142 /**********************************************************************
143 * CallWindowProc (USER.122)
145 LONG CallWindowProc( FARPROC func, HWND hwnd, WORD message,
146 WORD wParam, LONG lParam )
148 SpyMessage(hwnd, message, wParam, lParam);
150 if (HIWORD((LONG)func) == WINE_CODE_SELECTOR)
152 static struct dll_table_entry_s *user_tab = NULL;
153 void *address = (void *) ((LONG) func & 0xffff);
155 if (user_tab == NULL)
156 user_tab = FindDLLTable("USER");
158 /* DefWindowProc */
159 if (user_tab[107].address == address)
160 return DefWindowProc(hwnd, message, wParam, lParam);
162 /* DefDlgProc */
163 else if (user_tab[308].address == address)
164 return DefDlgProc(hwnd, message, wParam, lParam);
166 /* DefMDIChildProc */
167 else if (user_tab[447].address == address)
168 return DefMDIChildProc(hwnd, message, wParam, lParam);
170 /* default */
171 else
173 fprintf(stderr, "wine: Unknown wine callback %08x\n", func);
174 exit(1);
177 else if (Is16bitAddress(func))
179 #ifdef DEBUG_CALLBACK
180 printf("CallWindowProc // 16bit func=%08X !\n", func);
181 #endif
182 PushOn16( CALLBACK_SIZE_WORD, hwnd );
183 PushOn16( CALLBACK_SIZE_WORD, message );
184 PushOn16( CALLBACK_SIZE_WORD, wParam );
185 PushOn16( CALLBACK_SIZE_LONG, lParam );
186 return CallTo16((unsigned int) func,
187 FindDataSegmentForCode((unsigned long) func));
189 else
191 #ifdef DEBUG_CALLBACK
192 printf("CallWindowProc // 32bit func=%08X !\n", func);
193 #endif
194 return (*func)(hwnd, message, wParam, lParam);
198 /**********************************************************************
199 * CallLineDDAProc
201 void CallLineDDAProc(FARPROC func, short xPos, short yPos, long lParam)
203 if (Is16bitAddress(func))
205 PushOn16( CALLBACK_SIZE_WORD, xPos );
206 PushOn16( CALLBACK_SIZE_WORD, yPos );
207 PushOn16( CALLBACK_SIZE_LONG, lParam );
208 CallTo16((unsigned int) func,
209 FindDataSegmentForCode((unsigned long) func));
211 else
213 (*func)(xPos, yPos, lParam);
217 /**********************************************************************
218 * CallHookProc
220 DWORD CallHookProc( HOOKPROC func, short code, WPARAM wParam, LPARAM lParam )
222 if (Is16bitAddress(func))
224 PushOn16( CALLBACK_SIZE_WORD, code );
225 PushOn16( CALLBACK_SIZE_WORD, wParam );
226 PushOn16( CALLBACK_SIZE_LONG, lParam );
227 return CallTo16((unsigned int) func,
228 FindDataSegmentForCode((unsigned long) func));
230 else
232 return (*func)( code, wParam, lParam );
236 /**********************************************************************
237 * CallGrayStringProc
239 BOOL CallGrayStringProc(FARPROC func, HDC hdc, LPARAM lParam, INT cch )
241 if (Is16bitAddress(func))
243 PushOn16( CALLBACK_SIZE_WORD, hdc );
244 PushOn16( CALLBACK_SIZE_LONG, lParam );
245 PushOn16( CALLBACK_SIZE_WORD, cch );
246 return CallTo16((unsigned int) func,
247 FindDataSegmentForCode((unsigned long) func));
249 else
251 return (*func)( hdc, lParam, cch );
255 /* ------------------------------------------------------------------------ */
257 * The following functions realize the Catch/Throw functionality.
258 * My thought is to use the setjmp, longjmp combination to do the
259 * major part of this one. All I have to remember, in addition to
260 * whatever the jmp_buf contains, is the contents of the 16-bit
261 * sp, bp and ss. I do this by storing them in the structure passed
262 * to me by the 16-bit program (including my own jmp_buf...).
263 * Hopefully there isn't any program that modifies the contents!
264 * Bad thing: I have to save part of the stack, since this will
265 * get reused on the next call after my return, leaving it in an
266 * undefined state.
268 #define STACK_DEPTH_16 28
270 struct special_buffer {
271 jmp_buf buffer;
272 long regs [6];
273 char stack_part [STACK_DEPTH_16];
274 } *sb;
276 int Catch (LPCATCHBUF cbuf)
278 WORD retval;
279 jmp_buf *tmp_jmp;
280 char *stack16 = (char *) (((unsigned int)IF1632_Saved16_ss << 16) +
281 (IF1632_Saved16_esp & 0xffff));
283 sb = malloc (sizeof (struct special_buffer));
285 sb -> regs [0] = IF1632_Saved16_esp;
286 sb -> regs [1] = IF1632_Saved16_ebp;
287 sb -> regs [2] = IF1632_Saved16_ss & 0xffff;
288 sb -> regs [3] = IF1632_Saved32_esp;
289 sb -> regs [4] = IF1632_Saved32_ebp;
290 sb -> regs [5] = IF1632_Saved32_ss & 0xffff;
291 memcpy (sb -> stack_part, stack16, STACK_DEPTH_16);
292 tmp_jmp = &sb -> buffer;
293 *((struct special_buffer **)cbuf) = sb;
295 if ((retval = setjmp (*tmp_jmp)))
297 IF1632_Saved16_esp = sb -> regs [0];
298 IF1632_Saved16_ebp = sb -> regs [1];
299 IF1632_Saved16_ss = sb -> regs [2] & 0xffff;
300 IF1632_Saved32_esp = sb -> regs [3];
301 IF1632_Saved32_ebp = sb -> regs [4];
302 IF1632_Saved32_ss = sb -> regs [5] & 0xffff;
303 stack16 = (char *) (((unsigned int)IF1632_Saved16_ss << 16) +
304 (IF1632_Saved16_esp & 0xffff));
306 memcpy (stack16, sb -> stack_part, STACK_DEPTH_16);
307 #ifdef DEBUG_CATCH
308 printf ("Been thrown here: %d, retval = %d\n", sb, retval);
309 #endif
310 free ((void *) sb);
311 return (retval);
312 } else {
313 #ifdef DEBUG_CATCH
314 printf ("Will somtime get thrown here: %d\n", sb);
315 #endif
316 return (retval);
320 void Throw (LPCATCHBUF cbuf, int val)
322 sb = *((struct special_buffer **)cbuf);
323 #ifdef DEBUG_CATCH
324 printf ("Throwing to: %d\n", sb);
325 #endif
326 longjmp (sb -> buffer, val);
328 #endif /* !WINELIB */