::: Area #157 (comp.sys.acorn.programmer) Message: #39434 (Read 7 times, has 0 replies, 4716 bytes) Date : Thu Jan 28 21:26:05 1999 From : Rik Griffin of fidonet#2:254/27.2 To : All Subject: Re: Wimptask modules Message-ID: <19990128.212605.71@cheesey.demon.co.uk> In article , Jeremy@unforgettable.com (Jeremy Poulter) wrote: > Cheers, I should have specified that I was using C, any ideas? Assuming you're also using CMHG ... In your cmhg file specify something like this: initialisation-code: initialise finalisation-code: finalise module-is-runnable: service-call-handler: service_handler &11 &27 &49 &4a &7e command-keyword-table: cmd_handler Desktop_MyModule(help-text: "Do not use Desktop_MyModule. Use *Desktop instead"), C code: int Quit = 0; int Task_Handle = 0; int Wimp_Version = 0; int Wimp_Messages[] = { /* wimp message list terminated by 0, for example: */ Wimp_MPreQuit, Wimp_MQuit } /* do initialisation stuff (not Wimp). Called in SVC mode */ _kernel_oserror *initialise(char *cmd_tail, int podule, void *pw) { /* whatever you need to do */ return NULL; } /* called to shut down the module. Eg when RMKill is used. If */ /* the wimp task is active, that needs to be killed too. */ /* Also called in SVC mode. */ _kernel_oserror *finalise(int fatal, int podule, void *pw) { if (Task_Handle > 0) wimp_close_down(Task_Handle); Task_Handle = 0; return NULL; } /* Called to start the Wimp part of the module, eg when */ /* OS_Module 2 (Enter) is called. Called in User mode. */ int main(int argc, char *argv[]) { _kernel_swi_regs r; WimpPollBlock block; _kernel_oserror *e; int event; if (Task_Handle > 0) wimp_close_down(Task_Handle); Task_Handle = 0; if ((e = wimp_initialise("MyModule", Wimp_Messages, &Wimp_Version, &Task_Handle)) != NULL) goto fail; /* set our required Wimp slot size */ r.r[0] = 32*1024; // 32 k r.r[1] = -1; if ((e = _kernel_swi(Wimp_SlotSize, &r, &r)) != NULL) return e; /* now go into a Poll loop */ while (!Quit) { if ((e = wimp_poll(Poll_Mask, &block, NULL, &event)) != NULL) goto fail2; switch (event) { case Wimp_ENull: /* blah blah */ break; /* handle whatever wimp events you need to here */ } } if (Task_Handle > 0) wimp_close_down(Task_Handle); Task_Handle = 0; exit(EXIT_SUCCESS); fail: fprintf(stderr, "error from wimp_init: %s\n", e->errmess); exit(EXIT_FAILURE); fail2: fprintf(stderr, "error from wimp_poll: %s\n", e->errmess); exit(EXIT_FAILURE); } /* service call handler function. Called in SVC mode */ void service_handler(int number, _kernel_swi_regs *r, void *pw) { switch (number) { case Service_Memory: if (r->r[2] == (int)Image__RO_Base) { r->r[1] = 0; // 0 to prevent app space remapping } break; case Service_StartWimp: if (Task_Handle == 0) { Task_Handle = -1; r->r[0] = (int)"Desktop_MyModule"; // start wimp task r->r[1] = 0; // claim service call } break; case Service_StartedWimp: if (Task_Handle == -1) Task_Handle = 0; break; case Service_Reset: Task_Handle = 0; break; case Service_ShutDown: finalise(1, 0, NULL); break; } } _kernel_oserror *cmd_handler(char *arg_string, int argc, int cmd_no, void *pw) { int l, i; _kernel_oserror *e = NULL; switch (cmd_no) { case 0: { /* this command tells us to start our wimp task */ /* by calling OS_Module Enter on ourself */ _kernel_swi_regs r; r.r[0] = 2; r.r[1] = (int) "MyModule"; r.r[2] = (int) arg_string; e = _kernel_swi(OS_Module, &r, &r); } break; default : /* bad command */ break; } return e; } In assembler: EXPORT Image__RO_Base IMPORT |Image$$RO$$Base| Image__RO_Base DCD |Image$$RO$$Base| I hope all that makes sense. The code is snipped (with minor alterations) from a working module of mine. However, I don't guarantee that it's correct, merely that it works for me! :) You'll need to define a few macros and write a few SWI veneers (or use Acorn's WimpLib) to get that code working. If anyone has any comments, I'd be glad to hear them. -- "This moment hangs, like your ragged hair." Celebrate - Fields of the Nephilim --- EchoMaker 0.49 # Origin: Squeaky Software (mouse@cheesey.demon.co.uk) * Origin: The Arcade BBS Usenet News Gateway (2:254/27.2)