| Current Path : /var/www/html/prashantkr/TurboC/TCWIN45/SOURCE/OWL/ |
| Current File : /var/www/html/prashantkr/TurboC/TCWIN45/SOURCE/OWL/OWL.CPP |
//----------------------------------------------------------------------------
// ObjectWindows
// (C) Copyright 1991, 1994 by Borland International, All Rights Reserved
//
// Internal object thunk creation & maintanance.
//----------------------------------------------------------------------------
#include <owl/owlpch.h>
#include <owl/window.h>
#include <dos.h>
#include <mem.h>
#if defined(BI_PLAT_WIN32)
# include <stddef.h>
#endif
LRESULT FAR PASCAL _export StdWndProc(HWND, uint, WPARAM, LPARAM);
TProcInstance StdWndProcInstance((FARPROC)StdWndProc);
//
// Creation window pointer for InitWndProc
//
TWindow* _OWLDATA CreationWindow = 0;
void _OWLFUNC
SetCreationWindow(TWindow* w)
{
CreationWindow = w;
}
uint16 far _OWLFUNC
OWLGetVersion()
{
return OWLVersion;
}
//
// Initial WndProc called when an Owl window is first created.
// Subclasses the window function by installing the thunk then calls the
// thunk to get this first message to the window.
//
LRESULT CALLBACK __export
InitWndProc(HWND hWindow, uint message, WPARAM wParam, LPARAM lParam)
{
// If there's no creation window, i.e. we'll be aliasing a resource,
// then we can't do anything now. Create() will take care of it later
//
if (!CreationWindow)
return ::DefWindowProc(hWindow, message, wParam, lParam);
// install "DefWindowProc" as the window function BEFORE we request the
// subclassings; otherwise it looks like we subclassed "InitWndProc"
//
CreationWindow->HWindow = hWindow;
#if defined(BI_PLAT_WIN32)
CreationWindow->DefaultProc = (WNDPROC)GetProcAddress(
(HINSTANCE)GetModuleHandle("USER32"), "DefWindowProcA");
#else
CreationWindow->DefaultProc = ::DefWindowProc;
#endif
// Get the thunk & then zero out creation window so that it is not
// inadvertently used.
//
WNDPROC thunk = CreationWindow->GetThunk();
CreationWindow = 0;
// Set the thunk as the window proc, & call it with this first message.
//
SetWindowLong(hWindow, GWL_WNDPROC, uint32(thunk));
return (*(WNDPROC)(thunk))(hWindow, message, wParam, lParam);
}
//
// Win32 version of the instance thunking mechanism
//
#if defined(BI_PLAT_WIN32)
struct TInstanceThunk {
char Call;
int Offset;
PROC WndProcPtr;
TWindow* Window;
char Code[6];
};
static const int CODEDISP = offsetof(TInstanceThunk, Code) -
offsetof(TInstanceThunk, WndProcPtr);
WNDPROC
CreateInstanceThunk(TWindow* w)
{
TInstanceThunk* thunk = new TInstanceThunk;
thunk->Call = 0xE8; // CALL rel32
thunk->Offset = CODEDISP; // relative displacement to Code[5]
thunk->WndProcPtr = StdWndProcInstance;
thunk->Window = w;
//
// POP ECX
//
// pop return address of call into ecx (address of member "WndProcPtr")
//
thunk->Code[0] = 0x59;
//
// MOV EAX,[ECX+4]
//
// load "Window" into ebx
//
thunk->Code[1] = 0x8B; // MOV r32,r/m32
thunk->Code[2] = 0x41; // eax,disp8[ECX]
thunk->Code[3] = 0x04; // +4
//
// JMP [ECX]
//
// jump to window function StdWndProc
//
thunk->Code[4] = 0xFF; // JMP r/m32
thunk->Code[5] = 0x21; // [ECX]
return (WNDPROC)thunk;
}
void
FreeInstanceThunk(WNDPROC proc)
{
delete (TInstanceThunk*)proc;
}
//
// Win16 version of the instance thunking mechanism
//
#elif defined(BI_PLAT_WIN16)
//
// AllocCSToDSAlias was not declared in windows.h
//
extern "C" uint16 FAR PASCAL AllocCSToDSAlias(uint16);
struct TInstanceThunk {
char Code;
uint16 Offset;
union Ptr {
struct TInstanceThunk far* Next;
TWindow far* Window;
} ptr;
};
struct TThunkBlock {
uint16 Next;
char Code[5];
void far* WndProcPtr;
struct TInstanceThunk Thunks[34];
};
static uint16 ThunkBlockList = 0;
static TInstanceThunk far* ThunkFreeList = 0;
WNDPROC
CreateInstanceThunk(TWindow* w)
{
char blockCode[5];
TThunkBlock far* block;
TInstanceThunk far* thunk;
WNDPROC objInstance;
// POP BX
blockCode[0] = 0x5b;
// LES BX, CS:[BX]
blockCode[1] = 0x2e;
blockCode[2] = 0xc4;
blockCode[3] = 0x1f;
// JMP FAR StdWndProc
blockCode[4] = 0xea;
if (!ThunkFreeList) {
block = (TThunkBlock far*)GlobalLock(GlobalAlloc(GMEM_FIXED | GMEM_SHARE | GMEM_NOT_BANKED,
sizeof(TThunkBlock)));
block->Next = ThunkBlockList;
memcpy(block->Code, blockCode, 5);
block->WndProcPtr = (void far*)StdWndProcInstance;
thunk = block->Thunks;
do {
thunk->Code = 0xE8;
thunk->Offset = (2 - 3) - FP_OFF(thunk);
thunk->ptr.Next = ThunkFreeList;
ThunkFreeList = thunk;
thunk = (TInstanceThunk far*)MK_FP(
FP_SEG(thunk),
FP_OFF(thunk)+sizeof(TInstanceThunk)
);
} while (FP_OFF(thunk) != sizeof(TThunkBlock));
ThunkBlockList = FP_SEG(block);
PrestoChangoSelector(FP_SEG(block), FP_SEG(block));
}
objInstance = (WNDPROC)ThunkFreeList;
thunk = (TInstanceThunk far*)MK_FP(AllocCSToDSAlias(FP_SEG(ThunkFreeList)),
FP_OFF(ThunkFreeList));
ThunkFreeList = thunk->ptr.Next;
thunk->ptr.Window = (TWindow far*)w;
FreeSelector(FP_SEG(thunk));
return objInstance;
}
void
FreeInstanceThunk(WNDPROC p)
{
TInstanceThunk far* thunk = (TInstanceThunk far*)MK_FP(AllocCSToDSAlias(FP_SEG(p)),
FP_OFF(p));
thunk->ptr.Next = ThunkFreeList;
FreeSelector(FP_SEG(thunk));
ThunkFreeList = (TInstanceThunk far*)p;
}
#endif // BI_PLAT_XXX