1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00
wine/if1632/callback.c
Alexandre Julliard 3ed37e0869 Release 941107
Sun Nov  6 18:52:04 1994  Alexandre Julliard  (julliard@lamisun.epfl.ch)

	* [objects/oembitmap.c]  (New file)
	Added possibility to use .xpm files for OEM bitmaps.

	* [include/bitmaps/obm*]  (New files)
	Redrawn all OEM bitmaps in xpm format.

	* [objects/font.c]
	Add space for internal leading when using a negative font height.
	Stubs for AddFontResource() and RemoveFontResource().
	Fix in FONT_Init() for uninitialised default font.

	* [windows/dialog.c]
	Make font height negative as it is really a point size and not a
	pixel size; dialogs using 8-point fonts look better now.

	* [windows/graphics.c]
	Fixed the fix :-) for Pie() to make it work for Arc() and Chord() also.

	* [windows/nonclient.c]
	A few changes for new OEM bitmaps.

Sun Nov  6 18:22:18 1994  Michael Patra  <micky@marie.physik.tu-berlin.de>

	* [windows/class.c]
	The names of local classes have to be stored using GlobalAtom*.
	Otherwise they couldn't be accessed from other modules (e.g. BWCC) 

	* [if1632/call.S]
	CallTo16(cx): It's possible to set the contents of the cx-register.

	* [loader/ne_image.c]
	InitNEDLL(): The size of the local heap is now passed in the cx-
	register when initializing a DLL.

	* [memory/heap.c]
	LocalInit(): The case start==0 is now handled in the way it should.

	* [windows/win.c]
	GetWindowLong(): If the adress of the windows function is requested
	it's no longer returned if it's within the Wine code (and therefore
	unreachable by a windows program). This makes Borland's OWL happy.

	* [controls/edit.c]
	EDIT_GetStr(): Added handling for off<0.

Sun Nov  6 17:37:14 1994  Chris Jones  <chrisj@ichips.intel.com>

	* [loader/library.c]
	Fixed infinite loop bug when two DLLs refer to each other (fixes
	hangup of Quicken during loading).

Thu Nov 04 12:00:00 1994  Jan Willamowius  (jan@janhh.sh.sub.de)

	* [misc/dos_fs.c]
	Bug fix: The size of a disk an the available space
	is now returned in bytes instead of (incorrectly)
	KBytes.

Thu Nov 03 12:00:00 1994  Jan Willamowius  (jan@janhh.sh.sub.de)

	* [windows/graphics.c]
	Bug fix: Pie segments are now filled with correct brush.

Thu Nov  3 10:40:09 1994  Martin von Loewis  (martin@cs.csufresno.edu)

        * [Imakefile]
        generate rc.o before loader.o

        * [controls/menu.c]
        CopySysMenu: generate SYSMENU on the fly, eliminate hSysMenu

        * [include/resource.h]
        Add struct ResourceTable

        * [loader/bitmap.h]
        Load system bitmaps from sysresbmTable

        * [misc/clipboard.c]
          [windows/event.c]
        IsClipboardFormatAvailable,EVENT_SelectionRequest: bug fixes
        
        * [rc/Imakefile]
        generate rc.o from sysres.o and sysresbm.o. Added -lfl

        * [rc/rc.y]
        change style handling to allow ( S1 | S2 ) | S3

        * [rc/sysres.rc]
          [rc/sysresbm.rc]
        Put bitmaps and icons to sysresbm, everything else to sysres

        * [rc/winerc.c]
          [rc/winerc.h]
        Added -o, -c flags. New function set_out_file. Output to files.

        * [windows/dialog.c]
        DialogBoxIndirectPtr, DialogBoxIndirectParamPtr: New functions 

        * [windows/nonclient.c]
        Create AboutWine dialog from template pointer
1994-11-07 18:20:42 +00:00

337 lines
8.6 KiB
C

#ifndef WINELIB
static char RCSId[] = "$Id: wine.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
#include <stdio.h>
#include <stdlib.h>
#include "windows.h"
#include "callback.h"
#include "wine.h"
#include "segmem.h"
#include <setjmp.h>
#include "dlls.h"
#include "stddebug.h"
/* #define DEBUG_CALLBACK */
/* #undef DEBUG_CALLBACK */
#include "debug.h"
extern SEGDESC Segments[];
extern unsigned short IF1632_Saved16_ss;
extern unsigned long IF1632_Saved16_ebp;
extern unsigned long IF1632_Saved16_esp;
extern unsigned short IF1632_Saved32_ss;
extern unsigned long IF1632_Saved32_ebp;
extern unsigned long IF1632_Saved32_esp;
extern struct segment_descriptor_s *MakeProcThunks;
struct thunk_s
{
int used;
unsigned char thunk[10];
};
/**********************************************************************
* PushOn16
*/
static void
PushOn16(int size, unsigned int value)
{
char *p = (char *) (((unsigned int)IF1632_Saved16_ss << 16) +
(IF1632_Saved16_esp & 0xffff));
if (size)
{
unsigned long *lp = (unsigned long *) p - 1;
*lp = value;
IF1632_Saved16_esp -= 4;
}
else
{
unsigned short *sp = (unsigned short *) p - 1;
*sp = value;
IF1632_Saved16_esp -= 2;
}
}
/**********************************************************************
* FindDataSegmentForCode
*/
static unsigned short
FindDataSegmentForCode(unsigned long csip)
{
unsigned int seg_idx;
seg_idx = (unsigned short) (csip >> 19);
return Segments[seg_idx].owner;
}
/**********************************************************************
* CallBack16
*/
int
CallBack16(void *func, int n_args, ...)
{
va_list ap;
int i;
int arg_type, arg_value;
va_start(ap, n_args);
for (i = 0; i < n_args; i++)
{
arg_type = va_arg(ap, int);
arg_value = va_arg(ap, int);
PushOn16(arg_type, arg_value);
}
va_end(ap);
return CallTo16((unsigned int) func,
FindDataSegmentForCode((unsigned long) func));
}
/**********************************************************************
* CALLBACK_MakeProcInstance
*/
void *
CALLBACK_MakeProcInstance(void *func, int instance)
{
struct thunk_s *tp;
int i;
tp = (struct thunk_s *) MakeProcThunks->base_addr;
for (i = 0; i < 0x10000 / sizeof(*tp); i++, tp++)
if (!tp->used)
break;
if (tp->used)
return (void *) 0;
tp->thunk[0] = 0xb8;
tp->thunk[1] = (unsigned char) instance;
tp->thunk[2] = (unsigned char) (instance >> 8);
tp->thunk[3] = 0x8e;
tp->thunk[4] = 0xd8;
tp->thunk[5] = 0xea;
memcpy(&tp->thunk[6], &func, 4);
tp->used = 1;
return tp->thunk;
}
/**********************************************************************
* FreeProcInstance (KERNEL.52)
*/
void FreeProcInstance(FARPROC func)
{
struct thunk_s *tp;
int i;
tp = (struct thunk_s *) MakeProcThunks->base_addr;
for (i = 0; i < 0x10000 / sizeof(*tp); i++, tp++)
{
if ((void *) tp->thunk == (void *) func)
{
tp->used = 0;
break;
}
}
}
/**********************************************************************
* GetCodeHandle (KERNEL.93)
*/
HANDLE GetCodeHandle( FARPROC proc )
{
struct thunk_s *tp = (struct thunk_s *)proc;
/* Return the code segment containing 'proc'. */
/* Not sure if this is really correct (shouldn't matter that much). */
printf( "STUB: GetCodeHandle(%p) returning %x\n",
proc, tp->thunk[8] + (tp->thunk[9] << 8) );
return tp->thunk[8] + (tp->thunk[9] << 8);
}
/**********************************************************************
* CallWindowProc (USER.122)
*/
LONG CallWindowProc( WNDPROC func, HWND hwnd, WORD message,
WORD wParam, LONG lParam )
{
SpyMessage(hwnd, message, wParam, lParam);
if (HIWORD((LONG)func) == WINE_CODE_SELECTOR)
{
static struct dll_table_entry_s *user_tab = NULL;
void *address = (void *) ((LONG) func & 0xffff);
if (user_tab == NULL)
user_tab = FindDLLTable("USER");
/* DefWindowProc */
if (user_tab[107].address == address)
return DefWindowProc(hwnd, message, wParam, lParam);
/* DefDlgProc */
else if (user_tab[308].address == address)
return DefDlgProc(hwnd, message, wParam, lParam);
/* DefMDIChildProc */
else if (user_tab[447].address == address)
return DefMDIChildProc(hwnd, message, wParam, lParam);
/* default */
else
{
fprintf(stderr, "wine: Unknown wine callback %08x\n", func);
exit(1);
}
}
else if (IS_16_BIT_ADDRESS(func))
{
dprintf_callback(stddeb, "CallWindowProc // 16bit func=%p !\n", func);
PushOn16( CALLBACK_SIZE_WORD, hwnd );
PushOn16( CALLBACK_SIZE_WORD, message );
PushOn16( CALLBACK_SIZE_WORD, wParam );
PushOn16( CALLBACK_SIZE_LONG, lParam );
return CallTo16((unsigned int) func,
FindDataSegmentForCode((unsigned long) func));
}
else
{
dprintf_callback(stddeb, "CallWindowProc // 32bit func=%08X !\n", func);
return (*func)(hwnd, message, wParam, lParam);
}
}
/**********************************************************************
* CallLineDDAProc
*/
void CallLineDDAProc(FARPROC func, short xPos, short yPos, long lParam)
{
if (IS_16_BIT_ADDRESS(func))
{
PushOn16( CALLBACK_SIZE_WORD, xPos );
PushOn16( CALLBACK_SIZE_WORD, yPos );
PushOn16( CALLBACK_SIZE_LONG, lParam );
CallTo16((unsigned int) func,
FindDataSegmentForCode((unsigned long) func));
}
else
{
(*func)(xPos, yPos, lParam);
}
}
/**********************************************************************
* CallHookProc
*/
DWORD CallHookProc( HOOKPROC func, short code, WPARAM wParam, LPARAM lParam )
{
if (IS_16_BIT_ADDRESS(func))
{
PushOn16( CALLBACK_SIZE_WORD, code );
PushOn16( CALLBACK_SIZE_WORD, wParam );
PushOn16( CALLBACK_SIZE_LONG, lParam );
return CallTo16((unsigned int) func,
FindDataSegmentForCode((unsigned long) func));
}
else
{
return (*func)( code, wParam, lParam );
}
}
/**********************************************************************
* CallGrayStringProc
*/
BOOL CallGrayStringProc(FARPROC func, HDC hdc, LPARAM lParam, INT cch )
{
if (IS_16_BIT_ADDRESS(func))
{
PushOn16( CALLBACK_SIZE_WORD, hdc );
PushOn16( CALLBACK_SIZE_LONG, lParam );
PushOn16( CALLBACK_SIZE_WORD, cch );
return CallTo16((unsigned int) func,
FindDataSegmentForCode((unsigned long) func));
}
else
{
return (*func)( hdc, lParam, cch );
}
}
/* ------------------------------------------------------------------------ */
/*
* The following functions realize the Catch/Throw functionality.
* My thought is to use the setjmp, longjmp combination to do the
* major part of this one. All I have to remember, in addition to
* whatever the jmp_buf contains, is the contents of the 16-bit
* sp, bp and ss. I do this by storing them in the structure passed
* to me by the 16-bit program (including my own jmp_buf...).
* Hopefully there isn't any program that modifies the contents!
* Bad thing: I have to save part of the stack, since this will
* get reused on the next call after my return, leaving it in an
* undefined state.
*/
#define STACK_DEPTH_16 28
struct special_buffer {
jmp_buf buffer;
long regs [6];
char stack_part [STACK_DEPTH_16];
} *sb;
int Catch (LPCATCHBUF cbuf)
{
WORD retval;
jmp_buf *tmp_jmp;
char *stack16 = (char *) (((unsigned int)IF1632_Saved16_ss << 16) +
(IF1632_Saved16_esp & 0xffff));
sb = malloc (sizeof (struct special_buffer));
sb -> regs [0] = IF1632_Saved16_esp;
sb -> regs [1] = IF1632_Saved16_ebp;
sb -> regs [2] = IF1632_Saved16_ss & 0xffff;
sb -> regs [3] = IF1632_Saved32_esp;
sb -> regs [4] = IF1632_Saved32_ebp;
sb -> regs [5] = IF1632_Saved32_ss & 0xffff;
memcpy (sb -> stack_part, stack16, STACK_DEPTH_16);
tmp_jmp = &sb -> buffer;
*((struct special_buffer **)cbuf) = sb;
if ((retval = setjmp (*tmp_jmp)))
{
IF1632_Saved16_esp = sb -> regs [0];
IF1632_Saved16_ebp = sb -> regs [1];
IF1632_Saved16_ss = sb -> regs [2] & 0xffff;
IF1632_Saved32_esp = sb -> regs [3];
IF1632_Saved32_ebp = sb -> regs [4];
IF1632_Saved32_ss = sb -> regs [5] & 0xffff;
stack16 = (char *) (((unsigned int)IF1632_Saved16_ss << 16) +
(IF1632_Saved16_esp & 0xffff));
memcpy (stack16, sb -> stack_part, STACK_DEPTH_16);
dprintf_catch (stddeb, "Been thrown here: %d, retval = %d\n",
sb, retval);
free ((void *) sb);
return (retval);
} else {
dprintf_catch (stddeb, "Will somtime get thrown here: %d\n", sb);
return (retval);
}
}
void Throw (LPCATCHBUF cbuf, int val)
{
sb = *((struct special_buffer **)cbuf);
dprintf_catch (stddeb, "Throwing to: %d\n", sb);
longjmp (sb -> buffer, val);
}
#endif /* !WINELIB */