Implement support for gadgets receiving input

Implementation is changed. For each 32-bit gadget, there is now a wrapper
64-bit gadget installed on 64-bit window. Such gadget receives events from
64-bit Intuition and then forwards them to 32-bit gadget.

NOTE: handling of forwarded messages needs to happen on 31-bit stack,
because this calls into 32-bit gadget. Thus NewStackSwap is used in
GadgetWrapperClass_Dispatcher.
This commit is contained in:
deadwood 2024-04-07 12:34:43 +02:00
parent 2c6eac1a1a
commit 922d26b461
4 changed files with 513 additions and 3 deletions

View File

@ -107,6 +107,20 @@ void abiv0_UnlockLayer(struct LayerV0 *layer, struct LibraryV0 *LayersBaseV0)
}
MAKE_PROXY_ARG_2(UnlockLayer)
void abiv0_EndUpdate(struct LayerV0 *l, UWORD flag, struct LibraryV0 *LayersBaseV0)
{
struct LayerProxy *proxy = (struct LayerProxy *)l;
EndUpdate(proxy->native, flag);
}
MAKE_PROXY_ARG_3(EndUpdate)
LONG abiv0_BeginUpdate(struct LayerV0 *l, struct LibraryV0 *LayersBaseV0)
{
struct LayerProxy *proxy = (struct LayerProxy *)l;
BeginUpdate(proxy->native);
}
MAKE_PROXY_ARG_3(BeginUpdate)
void abiv0_GetSysTime(struct timeval *dest, struct LibraryV0 *TimerBaseV0)
{
return GetSysTime(dest);
@ -172,6 +186,8 @@ LONG_FUNC run_emulation()
__AROS_SETVECADDRV0(abiv0LayersBase, 23, (APTR32)(IPTR)proxy_UnlockLayerInfo);
__AROS_SETVECADDRV0(abiv0LayersBase, 16, (APTR32)(IPTR)proxy_LockLayer);
__AROS_SETVECADDRV0(abiv0LayersBase, 17, (APTR32)(IPTR)proxy_UnlockLayer);
__AROS_SETVECADDRV0(abiv0LayersBase, 14, (APTR32)(IPTR)proxy_EndUpdate);
__AROS_SETVECADDRV0(abiv0LayersBase, 13, (APTR32)(IPTR)proxy_BeginUpdate);
NewRawDoFmt("%s:Libs32/partial/cybergraphics.library", RAWFMTFUNC_STRING, path, SYSNAME);
BPTR cgfxseg = LoadSeg32(path, DOSBase);

View File

@ -242,4 +242,135 @@ struct NewWindowV0
UWORD Type;
};
/***** Gadgets *****/
struct GadgetV0
{
APTR32 NextGadget;
WORD LeftEdge;
WORD TopEdge;
WORD Width;
WORD Height;
UWORD Flags; /* see below */
UWORD Activation; /* see below */
UWORD GadgetType; /* see below */
APTR32 GadgetRender;
APTR32 SelectRender;
APTR32 GadgetText;
ULONG MutualExclude; /* OBSOLETE */
APTR32 SpecialInfo;
UWORD GadgetID;
APTR32 UserData;
};
#define STACKEDV0 __attribute__((aligned(4)))
struct gpRenderV0
{
STACKEDV0 ULONG MethodID; /* GM_RENDER */
STACKEDV0 APTR32 gpr_GInfo; /* see <intuition/cghooks.h> */
STACKEDV0 APTR32 gpr_RPort; /* RastPort (see <graphics/rastport.h>) to
render into. */
STACKEDV0 LONG gpr_Redraw; /* see below */
};
struct gpLayoutV0
{
STACKEDV0 ULONG MethodID; /* GM_LAYOUT */
STACKEDV0 APTR32 gpl_GInfo; /* see <intuition/cghooks.h> */
/* Boolean that indicated, if this method was invoked, when you are added
to a window (TRUE) or if it is called, because the window was resized
(FALSE). */
STACKEDV0 ULONG gpl_Initial;
};
struct gpHitTestV0
{
STACKEDV0 ULONG MethodID; /* GM_HITEST or GM_HELPTEST */
STACKEDV0 APTR32 gpht_GInfo; /* see <intuition/cghooks.h> */
/* These values are relative to the gadget select box for GM_HITTEST. For
GM_HELPTEST they are relative to the bounding box (which is often
equal to the select box). */
STACKEDV0 struct
{
STACKEDV0 WORD X;
STACKEDV0 WORD Y;
} gpht_Mouse;
};
struct gpInputV0
{
STACKEDV0 ULONG MethodID; /* GM_GOACTIVE or GM_HANDLEINPUT */
STACKEDV0 APTR32 gpi_GInfo; /* see <intuition/cghooks.h> */
/* Pointer to the InputEvent (see <devices/inputevent.h>) that caused
the method to be invoked. */
STACKEDV0 APTR32 gpi_IEvent;
/* Pointer to a variable that is to be set by the gadget class, if
GMR_VERIFY is returned. The lower 16 bits of this value are returned
in the Code field of the IntuiMessage (see <intuition/intuition.h>)
passed back to the application. */
STACKEDV0 APTR32 gpi_Termination;
/* This struct defines the current mouse position, relative to the
gadgets' bounding box. */
STACKEDV0 struct
{
STACKEDV0 WORD X;
STACKEDV0 WORD Y;
} gpi_Mouse;
/* Pointer to TabletData structure (see <intuition/intuition.h>) or NULL,
if this input event did not originate from a tablet that is capable of
sending IESUBCLASS_NEWTABLET events. */
STACKEDV0 APTR32 gpi_TabletData;
};
struct gpGoInactiveV0
{
STACKEDV0 ULONG MethodID; /* GM_GOINACTIVE */
STACKEDV0 APTR32 gpgi_GInfo; /* see <intuition/cghooks.h> */
/* Boolean field to indicate, who wanted the gadget to go inactive. If
this is 1 this method was sent, because intution wants the gadget to
go inactive, if it is 0, it was the gadget itself that wanted it. */
STACKEDV0 ULONG gpgi_Abort;
};
struct InputEventV0
{
APTR32 ie_NextEvent;
UBYTE ie_Class; /* see below for definitions */
UBYTE ie_SubClass; /* see below for definitions */
UWORD ie_Code; /* see below for definitions */
UWORD ie_Qualifier; /* see below for definitions */
union
{
struct
{
WORD ie_x;
WORD ie_y;
} ie_xy;
APTR32 ie_addr;
struct
{
UBYTE ie_prev1DownCode;
UBYTE ie_prev1DownQual;
UBYTE ie_prev2DownCode;
UBYTE ie_prev2DownQual;
} ie_dead;
} ie_position;
/* This is guaranteed to be increasing with time, but not guaranteed
to contain absolute time */
struct timeval32 ie_TimeStamp;
};
#endif

View File

@ -9,4 +9,13 @@ struct TagItemV0
ULONG ti_Data;
} __attribute__((packed));
/* A callback Hook */
struct HookV0
{
struct MinNodeV0 h_MinNode;
APTR32 h_Entry; /* Main entry point */
APTR32 h_SubEntry; /* Secondary entry point */
APTR32 h_Data; /* Whatever you want */
};
#endif

View File

@ -361,6 +361,8 @@ struct WindowV0 *abiv0_OpenWindowTagList(struct NewWindowV0 *newWindow, struct T
struct WindowProxy *proxy = abiv0_AllocMem(sizeof(struct WindowProxy), MEMF_CLEAR, Intuition_SysBaseV0);
proxy->native = wndnative;
proxy->base.WindowPort = 0xBAADF00D;
proxy->base.RPort = (APTR32)(IPTR)makeRastPortV0(proxy->native->RPort);
syncWindowV0(proxy);
@ -492,7 +494,8 @@ static struct MessageV0 *IntuiMessage_translate(struct Message *native)
if (imsg->Class == IDCMP_CLOSEWINDOW || imsg->Class == IDCMP_INTUITICKS || imsg->Class == IDCMP_MOUSEMOVE ||
imsg->Class == IDCMP_REFRESHWINDOW || imsg->Class == IDCMP_MOUSEBUTTONS || imsg->Class == IDCMP_NEWSIZE ||
imsg->Class == IDCMP_CHANGEWINDOW || imsg->Class == IDCMP_INACTIVEWINDOW)
imsg->Class == IDCMP_CHANGEWINDOW || imsg->Class == IDCMP_INACTIVEWINDOW || imsg->Class == IDCMP_GADGETUP ||
imsg->Class == IDCMP_ACTIVEWINDOW)
{
struct IntuiMessageV0 *v0msg = abiv0_AllocMem(sizeof(struct IntuiMessageV0), MEMF_CLEAR, Intuition_SysBaseV0);
@ -510,6 +513,14 @@ static struct MessageV0 *IntuiMessage_translate(struct Message *native)
v0msg->Seconds = imsg->Seconds;
v0msg->Micros = imsg->Micros;
if (imsg->Class == IDCMP_GADGETUP)
{
struct Gadget *nativeg = (struct Gadget *)imsg->IAddress;
// hacky way of struct GadgetWrapperData *data = INST_DATA(CLASS, self);data->wrapped
struct GadgetV0 *v0g = (struct GadgetV0 *)(*(IPTR *)((char *)nativeg + 0x80));
v0msg->IAddress = (APTR32)(IPTR)v0g;
}
/* Store original message in Node of v0msg for now */
*((IPTR *)&v0msg->ExecMessage.mn_Node) = (IPTR)imsg;
syncWindowV0((struct WindowProxy *)proxy);
@ -538,6 +549,9 @@ BOOL abiv0_ModifyIDCMP(struct WindowV0 *window, ULONG flags, struct LibraryV0 *I
winproxy->native->UserPort = NULL;
}
// TODO: instead of duplicating logic on 32-bit side call original function
winproxy->base.IDCMPFlags = flags;
return ModifyIDCMP(winproxy->native, flags);
}
MAKE_PROXY_ARG_2(ModifyIDCMP);
@ -620,6 +634,57 @@ APTR abiv0_NewObjectA(struct IClass *classPtr, UBYTE *classID, struct TagItemV0
}
MAKE_PROXY_ARG_4(NewObjectA)
struct IClass *gadgetwrappercl;
struct GadgetWrapperData
{
struct GadgetV0 *wrapped;
};
UWORD abiv0_AddGList(struct WindowV0 *window, struct GadgetV0 *gadget, ULONG position, LONG numGad, APTR /*struct RequesterV0 **/requester,
struct LibraryV0 *IntuitionBaseV0)
{
struct WindowProxy *winproxy = (struct WindowProxy *)window;
struct Gadget *gadPrev = NULL, *gadFirst = NULL;
for ( ; gadget && numGad; gadget = (APTR)(IPTR)gadget->NextGadget, numGad--)
{
struct Gadget *gwrapper = NewObjectA(gadgetwrappercl, NULL, NULL);
struct GadgetWrapperData *data = INST_DATA(gadgetwrappercl, gwrapper);
data->wrapped = gadget;
gwrapper->Flags = gadget->Flags;
gwrapper->Activation = gadget->Activation;
gwrapper->TopEdge = gadget->TopEdge;
gwrapper->LeftEdge = gadget->LeftEdge;
gwrapper->Width = gadget->Width;
gwrapper->Height = gadget->Height;
gwrapper->GadgetID = gadget->GadgetID;
gwrapper->GadgetType = gadget->GadgetType;
if (gadFirst == NULL) gadFirst = gwrapper;
if (gadPrev != NULL) gadPrev->NextGadget = gwrapper;
gadPrev = gwrapper;
}
bug("abiv0_AddGList: STUB\n");
return AddGList(winproxy->native, gadFirst, position, numGad, NULL);
}
MAKE_PROXY_ARG_6(AddGList)
void abiv0_RefreshGList(struct GadgetV0 *gadgets, struct WindowV0 *window, APTR /*struct Requester **/requester, LONG numGad,
struct LibraryV0 *IntuitionBaseV0)
{
bug("abiv0_RefreshGList: STUB\n");
}
MAKE_PROXY_ARG_5(RefreshGList)
UWORD abiv0_RemoveGList(struct WindowV0 *remPtr, struct GadgetV0 *gadget, LONG numGad, struct LibraryV0 *IntuitionBaseV0)
{
bug("abiv0_RemoveGList: STUB\n");
}
MAKE_PROXY_ARG_4(RemoveGList)
struct LibraryV0 *shallow_InitResident32(struct ResidentV0 *resident, BPTR segList, struct ExecBaseV0 *SysBaseV0);
BPTR LoadSeg32 (CONST_STRPTR name, struct DosLibrary *DOSBase);
struct ResidentV0 * findResident(BPTR seg, CONST_STRPTR name);
@ -629,6 +694,290 @@ extern ULONG* segclassesinitlist;
extern ULONG *seginitlist;
extern CONST_STRPTR SYSNAME;
struct _ObjectV0
{
struct MinNodeV0 o_Node; /* PRIVATE */
APTR32 o_Class;
};
#define _OBJV0(obj) ((struct _ObjectV0 *)(obj))
#define _OBJECTV0(obj) (_OBJV0(obj) - 1)
#define OCLASSV0(obj) ((_OBJECTV0(obj))->o_Class)
ULONG abiv0_DoMethodA(APTR object, APTR message)
{
struct HookV0 *clhook = (struct HookV0 *)(IPTR)OCLASSV0(object);
__asm__ volatile (
"pushq %%rbx\n"
"subq $12, %%rsp\n"
"movl %3, %%eax\n"
"movl %%eax, 8(%%rsp)\n"
"movl %2, %%eax\n"
"movl %%eax, 4(%%rsp)\n"
"movl %1, %%eax\n"
"movl %%eax, (%%rsp)\n"
"movl %0, %%eax\n"
ENTER32
"call *%%eax\n"
ENTER64
"addq $12, %%rsp\n"
"popq %%rbx\n"
"leave\n"
"ret\n"
::"m"(clhook->h_Entry), "m"(clhook), "m"(object), "m"(message) : "%rax", "%rcx");
}
/*
* Messages are processed on 31bit stack. This is needed for case where 64-bit Intuition input handler issues a call that is
* the forwarded to 32-bit gadget method. This method needs to be executed on 31-bit stack, not on original stack.
*/
static IPTR process_message_on_31bit_stack(struct IClass *CLASS, Object *self, Msg message)
{
struct GadgetWrapperData *data = INST_DATA(CLASS, self);
struct Gadget *nativeg = (struct Gadget *)self;
switch (message->MethodID)
{
case OM_NEW: return DoSuperMethodA(CLASS, self, message);
// case OM_SET: case OM_UPDATE: return (IPTR)GroupGClass__OM_SET(CLASS, (Object *)self, (Msg) message);
// case OM_DISPOSE: return (IPTR)GroupGClass__OM_DISPOSE(CLASS, (Object *)self, (Msg) message);
// case OM_ADDMEMBER: return (IPTR)GroupGClass__OM_ADDMEMBER(CLASS, (Object *)self, (Msg) message);
// case OM_REMMEMBER: return (IPTR)GroupGClass__OM_REMMEMBER(CLASS, (Object *)self, (Msg) message);
case GM_HITTEST:
{
struct gpHitTest *nativemsg = (struct gpHitTest *)message;
struct GadgetV0 *v0g = data->wrapped;
struct gpHitTestV0 *v0msg = abiv0_AllocMem(sizeof(struct gpHitTestV0), MEMF_CLEAR, Intuition_SysBaseV0);
struct GadgetInfoV0 *v0gi = abiv0_AllocMem(sizeof(struct GadgetInfoV0), MEMF_CLEAR, Intuition_SysBaseV0);
v0gi->gi_Domain = nativemsg->gpht_GInfo->gi_Domain;
v0msg->MethodID = nativemsg->MethodID;
v0msg->gpht_GInfo = (APTR32)(IPTR)v0gi;
v0msg->gpht_Mouse.X = nativemsg->gpht_Mouse.X;
v0msg->gpht_Mouse.Y = nativemsg->gpht_Mouse.Y;
IPTR ret = (IPTR)abiv0_DoMethodA(data->wrapped, v0msg);
abiv0_FreeMem(v0gi, sizeof(struct GadgetInfoV0), Intuition_SysBaseV0);
abiv0_FreeMem(v0msg, sizeof(struct gpHitTestV0), Intuition_SysBaseV0);
return ret;
}
case GM_GOACTIVE:
{
struct gpInput *nativemsg = (struct gpInput *)message;
struct GadgetV0 *v0g = data->wrapped;
struct gpInputV0 *v0msg = abiv0_AllocMem(sizeof(struct gpInputV0), MEMF_CLEAR, Intuition_SysBaseV0);
struct GadgetInfoV0 *v0gi = abiv0_AllocMem(sizeof(struct GadgetInfoV0), MEMF_CLEAR, Intuition_SysBaseV0);
v0gi->gi_Domain = nativemsg->gpi_GInfo->gi_Domain;
v0gi->gi_RastPort = (APTR32)(IPTR)makeRastPortV0(nativemsg->gpi_GInfo->gi_RastPort);
if (nativemsg->gpi_GInfo->gi_Screen == g_nativescreen)
{
v0gi->gi_Screen = (APTR32)(IPTR)g_v0screen;
}
else asm("int3");
v0msg->MethodID = nativemsg->MethodID;
v0msg->gpi_GInfo = (APTR32)(IPTR)v0gi;
v0msg->gpi_Mouse.X = nativemsg->gpi_Mouse.X;
v0msg->gpi_Mouse.Y = nativemsg->gpi_Mouse.Y;
IPTR ret = (IPTR)abiv0_DoMethodA(data->wrapped, v0msg);
nativeg->Flags = v0g->Flags;
nativeg->Activation = v0g->Activation;
nativeg->TopEdge = v0g->TopEdge;
nativeg->LeftEdge = v0g->LeftEdge;
nativeg->Width = v0g->Width;
nativeg->Height = v0g->Height;
nativeg->GadgetID = v0g->GadgetID;
nativeg->GadgetType = v0g->GadgetType;
abiv0_FreeMem(v0gi, sizeof(struct GadgetInfoV0), Intuition_SysBaseV0);
abiv0_FreeMem(v0msg, sizeof(struct gpInputV0), Intuition_SysBaseV0);
return ret;
}
case GM_HANDLEINPUT:
{
struct gpInput *nativemsg = (struct gpInput *)message;
struct GadgetV0 *v0g = data->wrapped;
LONG gpi_Termination = *nativemsg->gpi_Termination;
struct gpInputV0 *v0msg = abiv0_AllocMem(sizeof(struct gpInputV0), MEMF_CLEAR, Intuition_SysBaseV0);
struct GadgetInfoV0 *v0gi = abiv0_AllocMem(sizeof(struct GadgetInfoV0), MEMF_CLEAR, Intuition_SysBaseV0);
struct InputEventV0 *v0ie = abiv0_AllocMem(sizeof(struct InputEventV0), MEMF_CLEAR, Intuition_SysBaseV0);
v0gi->gi_Domain = nativemsg->gpi_GInfo->gi_Domain;
v0gi->gi_RastPort = (APTR32)(IPTR)makeRastPortV0(nativemsg->gpi_GInfo->gi_RastPort);
if (nativemsg->gpi_GInfo->gi_Screen == g_nativescreen)
{
v0gi->gi_Screen = (APTR32)(IPTR)g_v0screen;
}
else asm("int3");
v0ie->ie_Class = nativemsg->gpi_IEvent->ie_Class;
v0ie->ie_SubClass = nativemsg->gpi_IEvent->ie_SubClass;
v0ie->ie_Code = nativemsg->gpi_IEvent->ie_Code;
v0ie->ie_Qualifier = nativemsg->gpi_IEvent->ie_Qualifier;
v0ie->ie_TimeStamp = nativemsg->gpi_IEvent->ie_TimeStamp;
v0msg->MethodID = nativemsg->MethodID;
v0msg->gpi_GInfo = (APTR32)(IPTR)v0gi;
v0msg->gpi_IEvent = (APTR32)(IPTR)v0ie;
v0msg->gpi_Mouse.X = nativemsg->gpi_Mouse.X;
v0msg->gpi_Mouse.Y = nativemsg->gpi_Mouse.Y;
v0msg->gpi_Termination = (APTR32)(IPTR)&gpi_Termination;
IPTR ret = (IPTR)abiv0_DoMethodA(data->wrapped, v0msg);
nativeg->Flags = v0g->Flags;
nativeg->Activation = v0g->Activation;
nativeg->TopEdge = v0g->TopEdge;
nativeg->LeftEdge = v0g->LeftEdge;
nativeg->Width = v0g->Width;
nativeg->Height = v0g->Height;
nativeg->GadgetID = v0g->GadgetID;
nativeg->GadgetType = v0g->GadgetType;
*nativemsg->gpi_Termination = gpi_Termination;
abiv0_FreeMem(v0ie, sizeof(struct InputEventV0), Intuition_SysBaseV0);
abiv0_FreeMem(v0gi, sizeof(struct GadgetInfoV0), Intuition_SysBaseV0);
abiv0_FreeMem(v0msg, sizeof(struct gpInputV0), Intuition_SysBaseV0);
return ret;
}
case GM_GOINACTIVE:
{
struct gpGoInactive *nativemsg = (struct gpGoInactive *)message;
struct gpGoInactiveV0 *v0msg = abiv0_AllocMem(sizeof(struct gpGoInactiveV0), MEMF_CLEAR, Intuition_SysBaseV0);
v0msg->MethodID = nativemsg->MethodID;
v0msg->gpgi_Abort = nativemsg->gpgi_Abort;
IPTR ret = (IPTR)abiv0_DoMethodA(data->wrapped, v0msg);
abiv0_FreeMem(v0msg, sizeof(struct gpGoInactiveV0), Intuition_SysBaseV0);
return ret;
}
case GM_LAYOUT:
{
struct gpLayout *nativemsg = (struct gpLayout *)message;
struct GadgetV0 *v0g = data->wrapped;
struct gpLayoutV0 *v0msg = abiv0_AllocMem(sizeof(struct gpLayoutV0), MEMF_CLEAR, Intuition_SysBaseV0);
struct GadgetInfoV0 *v0gi = abiv0_AllocMem(sizeof(struct GadgetInfoV0), MEMF_CLEAR, Intuition_SysBaseV0);
v0gi->gi_Domain = nativemsg->gpl_GInfo->gi_Domain;
v0gi->gi_Window = (APTR32)(IPTR)wmGetByWindow(nativemsg->gpl_GInfo->gi_Window);
v0msg->MethodID = nativemsg->MethodID;
v0msg->gpl_GInfo = (APTR32)(IPTR)v0gi;
v0msg->gpl_Initial = nativemsg->gpl_Initial;
IPTR ret = (IPTR)abiv0_DoMethodA(data->wrapped, v0msg);
nativeg->Flags = v0g->Flags;
nativeg->Activation = v0g->Activation;
nativeg->TopEdge = v0g->TopEdge;
nativeg->LeftEdge = v0g->LeftEdge;
nativeg->Width = v0g->Width;
nativeg->Height = v0g->Height;
nativeg->GadgetID = v0g->GadgetID;
nativeg->GadgetType = v0g->GadgetType;
abiv0_FreeMem(v0gi, sizeof(struct GadgetInfoV0), Intuition_SysBaseV0);
abiv0_FreeMem(v0msg, sizeof(struct gpLayoutV0), Intuition_SysBaseV0);
return ret;
}
case GM_RENDER:
{
struct gpRender *nativemsg = (struct gpRender *)message;
struct GadgetV0 *v0g = data->wrapped;
struct gpRenderV0 *v0msg = abiv0_AllocMem(sizeof(struct gpRenderV0), MEMF_CLEAR, Intuition_SysBaseV0);
struct GadgetInfoV0 *v0gi = abiv0_AllocMem(sizeof(struct GadgetInfoV0), MEMF_CLEAR, Intuition_SysBaseV0);
struct LayerProxy *lproxy = abiv0_AllocMem(sizeof(struct LayerProxy), MEMF_CLEAR, Intuition_SysBaseV0);
struct DrawInfoV0 *v0dri = abiv0_AllocMem(sizeof(struct DrawInfoV0), MEMF_CLEAR, Intuition_SysBaseV0);
v0dri->dri_Pens = (APTR32)(IPTR)abiv0_AllocMem(NUMDRIPENS * sizeof(UWORD), MEMF_CLEAR, Intuition_SysBaseV0);
CopyMem(nativemsg->gpr_GInfo->gi_DrInfo->dri_Pens, (APTR)(IPTR)v0dri->dri_Pens, NUMDRIPENS * sizeof(UWORD));
lproxy->native = nativemsg->gpr_GInfo->gi_Layer;
syncLayerV0(lproxy);
v0gi->gi_Domain = nativemsg->gpr_GInfo->gi_Domain;
v0gi->gi_Layer = (APTR32)(IPTR)lproxy;
v0gi->gi_DrInfo = (APTR32)(IPTR)v0dri;
v0gi->gi_Window = (APTR32)(IPTR)wmGetByWindow(nativemsg->gpr_GInfo->gi_Window);
if (nativemsg->gpr_GInfo->gi_Screen == g_nativescreen)
{
v0gi->gi_Screen = (APTR32)(IPTR)g_v0screen;
}
else asm("int3");
v0msg->MethodID = nativemsg->MethodID;
v0msg->gpr_Redraw = nativemsg->gpr_Redraw;
v0msg->gpr_GInfo = (APTR32)(IPTR)v0gi;
v0msg->gpr_RPort = (APTR32)(IPTR)makeRastPortV0(nativemsg->gpr_RPort);
IPTR ret = (IPTR)abiv0_DoMethodA(data->wrapped, v0msg);
abiv0_FreeMem((APTR)(IPTR)v0msg->gpr_RPort, sizeof(struct RastPortV0), Intuition_SysBaseV0);
abiv0_FreeMem((APTR)(IPTR)v0dri->dri_Pens, NUMDRIPENS * sizeof(UWORD), Intuition_SysBaseV0);
abiv0_FreeMem(v0dri, sizeof(struct DrawInfoV0), Intuition_SysBaseV0);
abiv0_FreeMem(lproxy, sizeof(struct LayerProxy), Intuition_SysBaseV0);
abiv0_FreeMem(v0gi, sizeof(struct GadgetInfoV0), Intuition_SysBaseV0);
abiv0_FreeMem(v0msg, sizeof(struct gpRenderV0), Intuition_SysBaseV0);
return ret;
}
default:
asm("int3");
return DoSuperMethodA(CLASS, self, message);
}
return (IPTR) NULL;
}
BOOPSI_DISPATCHER(IPTR, GadgetWrapperClass_Dispatcher, CLASS, self, message)
{
static APTR stack31bit = NULL;
struct StackSwapStruct sss;
struct StackSwapArgs ssa;
if (stack31bit == NULL) stack31bit = AllocMem(64 * 1024, MEMF_CLEAR | MEMF_31BIT);
sss.stk_Lower = stack31bit;
sss.stk_Upper = sss.stk_Lower + 64 * 1024;
sss.stk_Pointer = sss.stk_Upper;
ssa.Args[0] = (IPTR)CLASS;
ssa.Args[1] = (IPTR)self;
ssa.Args[2] = (IPTR)message;
return NewStackSwap(&sss, process_message_on_31bit_stack, &ssa);
}
BOOPSI_DISPATCHER_END
static void init_gadget_wrapper_class()
{
gadgetwrappercl = MakeClass(NULL, GADGETCLASS, NULL, sizeof(struct GadgetWrapperData), 0);
gadgetwrappercl->cl_Dispatcher.h_Entry = (APTR)GadgetWrapperClass_Dispatcher;
gadgetwrappercl->cl_Dispatcher.h_SubEntry = NULL;
}
void init_intuition(struct ExecBaseV0 *SysBaseV0)
{
TEXT path[64];
@ -689,13 +1038,16 @@ void init_intuition(struct ExecBaseV0 *SysBaseV0)
__AROS_SETVECADDRV0(abiv0IntuitionBase, 93, (APTR32)(IPTR)proxy_ObtainGIRPort);
__AROS_SETVECADDRV0(abiv0IntuitionBase, 145, intuitionjmp[165 - 145]); // DoNotify
__AROS_SETVECADDRV0(abiv0IntuitionBase, 77, (APTR32)(IPTR)proxy_ActivateGadget);
__AROS_SETVECADDRV0(abiv0IntuitionBase, 73, intuitionjmp[165 - 73]); // AddGList
__AROS_SETVECADDRV0(abiv0IntuitionBase, 73, (APTR32)(IPTR)proxy_AddGList);
__AROS_SETVECADDRV0(abiv0IntuitionBase, 135, intuitionjmp[165 - 135]); // DoGadgetMethodA
__AROS_SETVECADDRV0(abiv0IntuitionBase, 72, intuitionjmp[165 - 72]); // RefreshGList
__AROS_SETVECADDRV0(abiv0IntuitionBase, 72, (APTR32)(IPTR)proxy_RefreshGList);
__AROS_SETVECADDRV0(abiv0IntuitionBase, 69, (APTR32)(IPTR)proxy_LockIBase);
__AROS_SETVECADDRV0(abiv0IntuitionBase, 70, (APTR32)(IPTR)proxy_UnlockIBase);
__AROS_SETVECADDRV0(abiv0IntuitionBase, 94, (APTR32)(IPTR)proxy_ReleaseGIRPort);
__AROS_SETVECADDRV0(abiv0IntuitionBase, 103, (APTR32)(IPTR)proxy_DrawImageState);
__AROS_SETVECADDRV0(abiv0IntuitionBase, 74, (APTR32)(IPTR)proxy_RemoveGList);
__AROS_SETVECADDRV0(abiv0IntuitionBase, 146, intuitionjmp[165 - 146]); // FreeICData
__AROS_SETVECADDRV0(abiv0IntuitionBase, 41, intuitionjmp[165 - 41]); // ScreenToBack
/* Call CLASSESINIT_LIST */
ULONG pos = 1;
@ -719,4 +1071,6 @@ void init_intuition(struct ExecBaseV0 *SysBaseV0)
/* Set internal Intuition pointer of utility */
*(ULONG *)((IPTR)abiv0IntuitionBase + 0x60) = (APTR32)(IPTR)abiv0_DOS_OpenLibrary("utility.library", 0L, SysBaseV0);
*(ULONG *)((IPTR)abiv0IntuitionBase + 0x64) = (APTR32)(IPTR)abiv0_DOS_OpenLibrary("graphics.library", 0L, SysBaseV0);
init_gadget_wrapper_class();
}