/* ** ra_appwindow.c ** ** Example code to demonstrate how ** AppWindows and AppMessages ** are done in ReAction. ** ** By Daniel "Trixie" Jedlicka ** ** ** */ #include #include #include #include #include #include #include #include #define MINVERSION 52 #define FNAME_MAX 2048 /* object identifiers */ enum { OID_WINDOW, OID_LAYOUT, OID_BUTTON, OID_LAST }; struct Library *IntuitionBase, *UtilityBase; struct IntuitionIFace *IIntuition; /* class library bases */ struct ClassLibrary *WindowBase, *LayoutBase, *ButtonBase; /* class pointers */ Class *WindowClass, *LayoutClass, *ButtonClass; Object *objects[OID_LAST]; /* object pointer field */ struct MsgPort *winAppPort; /* window AppPort */ struct Hook *appMsgHook; /* AppMessage hook */ /* ************************************* hook function ************************************** */ static void appmessage_func(struct Hook *hook, Object *winObj, struct AppMessage *appMsg) { struct WBArg *argPtr = NULL; struct Window *window = NULL; char fileName[FNAME_MAX]; if ( appMsg->am_Type == AMTYPE_APPWINDOW ) { if ( (appMsg->am_Class == AMCLASSICON_Open) && (appMsg->am_NumArgs > 0) ) { /* Obtain the Intuition window pointer from the window object. */ IIntuition->GetAttrs(winObj, WINDOW_Window, (uint32 *)&window, TAG_END); IIntuition->ActivateWindow(window); /* Obtain the file name from the AppMessage. */ argPtr = appMsg->am_ArgList; IDOS->NameFromLock(argPtr->wa_Lock, fileName, FNAME_MAX); IDOS->AddPart(fileName, argPtr->wa_Name, FNAME_MAX); /* Change the gadget text to the file name. */ IIntuition->SetGadgetAttrs((struct Gadget *)objects[OID_BUTTON], window, NULL, GA_Text, fileName, TAG_END); } } } /* ************************************** input loop **************************************** */ void handle_input(Object *winObj) { struct Window *window = NULL; uint32 sigMask = 0, sigGot = 0, result = 0; uint16 code = 0; BOOL done = FALSE; /* Obtain window pointer and signal mask from the window object. */ IIntuition->GetAttrs(winObj, WINDOW_Window, (uint32 *)&window, WINDOW_SigMask, &sigMask, TAG_END); while ( !done ) { sigGot = IExec->Wait(sigMask); while ( (result = IIntuition->IDoMethod(winObj, WM_HANDLEINPUT, &code)) != WMHI_LASTMSG ) { switch (result & WMHI_CLASSMASK) { case WMHI_CLOSEWINDOW: done = TRUE; break; case WMHI_ICONIFY: if ( (IIntuition->IDoMethod(winObj, WM_ICONIFY, NULL)) ) window = NULL; break; case WMHI_UNICONIFY: if ( !(window = (struct Window *)IIntuition->IDoMethod(winObj, WM_OPEN, NULL)) ) done = TRUE; break; } } } } /* ***************************************** main ******************************************* */ int main(void) { struct Window *window = NULL; int errCode = RETURN_FAIL; /* Open libraries and the Intuition interface. */ IntuitionBase = IExec->OpenLibrary("intuition.library", MINVERSION); UtilityBase = IExec->OpenLibrary("utility.library", MINVERSION); if ( ! IntuitionBase || !UtilityBase ) goto cleanup; IIntuition = (APTR)IExec->GetInterface(IntuitionBase, "main", 1L, NULL); /* Open the ReAction classes we need. */ WindowBase = IIntuition->OpenClass("window.class", MINVERSION, &WindowClass); LayoutBase = IIntuition->OpenClass("gadgets/layout.gadget", MINVERSION, &LayoutClass); ButtonBase = IIntuition->OpenClass("gadgets/button.gadget", MINVERSION, &ButtonClass); if ( ! UtilityBase || !WindowBase || !LayoutBase || !ButtonBase ) goto cleanup; /* Create messageport for window iconification and AppWindow messages. */ if ( !(winAppPort = (struct MsgPort *)IExec->AllocSysObject(ASOT_PORT, NULL)) ) goto cleanup; /* Initialize the AppMessage hook. */ if ( !(appMsgHook = (struct Hook *)IExec->AllocSysObjectTags(ASOT_HOOK, ASOHOOK_Entry, appmessage_func, ASOHOOK_Subentry, NULL, ASOHOOK_Data, NULL, TAG_END)) ) goto cleanup; /* Create the window object. You do not normally have to specify window dimensions but we want a big button here so... The button is read-only and does not do anything, it just works as a display zone for the file name. */ if ( (objects[OID_WINDOW] = IIntuition->NewObject(WindowClass, NULL, WA_Title, "ReAction AppWindow", WA_DragBar, TRUE, WA_CloseGadget, TRUE, WA_SizeGadget, TRUE, WA_DragBar, TRUE, WA_DepthGadget, TRUE, WA_Activate, TRUE, WA_InnerWidth, 320, WA_InnerHeight, 200, WINDOW_Position, WPOS_CENTERSCREEN, WINDOW_AppPort, winAppPort, WINDOW_AppWindow, TRUE, WINDOW_AppMsgHook, appMsgHook, WINDOW_IconifyGadget, TRUE, WINDOW_Layout, objects[OID_LAYOUT] = IIntuition->NewObject(LayoutClass, NULL, LAYOUT_Orientation, LAYOUT_ORIENT_VERT, LAYOUT_SpaceOuter, TRUE, LAYOUT_DeferLayout, TRUE, LAYOUT_AddChild, objects[OID_BUTTON] = IIntuition->NewObject(ButtonClass, NULL, GA_ID, OID_BUTTON, GA_ReadOnly, TRUE, GA_Text, "Drop a file icon here!", TAG_END), TAG_END), TAG_END)) ) { /* Open the window. */ if ( (window = (struct Window *)IIntuition->IDoMethod(objects[OID_WINDOW], WM_OPEN, NULL)) ) { /* Enter the input loop. */ handle_input(objects[OID_WINDOW]); /* Close the window when we're done. */ IIntuition->IDoMethod(objects[OID_WINDOW], WM_CLOSE); errCode = RETURN_OK; } /* And dispose of the window object. */ IIntuition->DisposeObject(objects[OID_WINDOW]); } cleanup: /* Free resources. */ if (appMsgHook) IExec->FreeSysObject(ASOT_HOOK, appMsgHook); if (winAppPort) IExec->FreeSysObject(ASOT_PORT, winAppPort); if (ButtonBase) IIntuition->CloseClass(ButtonBase); if (LayoutBase) IIntuition->CloseClass(LayoutBase); if (WindowBase) IIntuition->CloseClass(WindowBase); if (IIntuition) IExec->DropInterface((struct Interface *)IIntuition); if (IntuitionBase) IExec->CloseLibrary(IntuitionBase); if (UtilityBase) IExec->CloseLibrary(UtilityBase); return errCode; }