C the WIMP

1. Registration time....

The RISC OS WIMP system is addressed using SWI calls (SWI stands for software interupt). These SWI commands cover just about every single part of the RISC OS system from screen to filer to memory and then some more!.

The SWI commands normally require arguments (or parameters) to be passed to them. The arguments are passed in something known as a register. In the normal course of proceedings, there are only 13 registers (r0 to r12) ever needed. There are another 3 (r13 - r15) which are never normally used, except in some very special circumstances.

In BASIC, a SWI would be called using something along the lines of

SYS "OS_File",5,filename$ TO ,,,,r4%

This would tell the machine to call OS_File with r0=5, r1 = filename to look at and on exit from the routine, the length of the file is returned into r4%.

There are two ways to call this in C

kernel_swi_regs regs;

regs.r[0]=5;

regs.r[1]=filename;

_kernel_swi (OS_File,&regs,&regs);

r4=regs.r[4];

or

_swi(OS_File,_IN(0)|_IN(1)|_OUT(4),5,filename,&file_size);

It's not hard to see which will be the one in use here!

At this point, unless you already have them, I would suggest getting hold of a copy of the PRMs (programmers reference manuals) or the StrongHelp OS file.

When programming the WIMP or even when not programming the WIMP, these are essential if you're serious about it.

Both of these _swi calls require the non-ANSI header file "swis.h". This file exists in both GCC (inside of the !Unixlib) and in Acorn C/C++. This header file creates the swis used by the machine.

The problem here though is that the "swis.h" will go out of date as more swis are added. This is where you can either create your own header file, or use a ready made one such as Desklib or !OSLib provide. These keep up with the new swis added to the OS and are also a lot more flexible than the standard Acorn or GCC headers (this is only my opinion!).

I suppose that from here on in, quite a lot of the material will be RISC OS only - the swi commands are RISC OS specific and therefore no good for Mac or PC machines. This means that for porting to other platforms, the files should be as well documented as possible - that said, I'm yet to see a well documented source code from either a Mac or PC which requires a WIMP system!

A word of thanks

This series would not have been possible without having first read and gone through (sometimes quite a few times) the brilliant book "Wimp Programming for All on Acorn RISC Computers" by Calcraft and Wrigley and to Roger Darlington at University of Salford for the loan of this book. I am indebted to Joseph Heenan for proof reading the entire series for me.

Thanks.

Unlike the C from the Top series where there are a plethora of texts available, WIMP programming books for RISC OS machines are somewhat thin on the ground - the Wimp Programming for All dates back to 1993. I don't think it is still available as RISC Developments are no more, but you may strike lucky at a library. An alternative is that the entire book is now on CD from R-Comp. It is on the RISC User In a Nutshell CD.

Though it is written for BASIC, as you will have already seen, C and BASIC V share a great deal of the same structures, so the conversion from C to BASIC can be quite simple. I've attempted not to do a direct conversion though.

The WIMP - what is it?

WIMP stands for Windows - Icon - Mouse - Pull down menus. On the RISCOS platform, this refers to the Window Manager module (currently under OS 4 at version 4.15 - there is a new version of the Window Manager available at the RISCOS Ltd website). The RISC OS wimp system is a great example of a GUI (pronounced gooey). There are plenty of GUIs around (such as Windows and MacOS), but none, in my opinion, touch that on the RISC OS platform. You click on an icon and the program responds, quickly and efficiently. Even under OS2 the Acorn WIMP system is better than WinNT4 under most circumstances!.

What sets the RISC OS wimp aside from the likes of Windows is the ability to truely multitask (though Microsoft frequently boast Windows can multitask - the truth is that Windows can't but the DOS side can).

The RISC OS wimp system works like this. The program is written, compiled and run. A window comes up and waits for something to happen. This something is called an event. If no event is forth coming, it is known as a NULL event.

The multitasking ability works like this.

Say you have 5 programs running at any one time - all are on screen. The processor looks at application 1 and sees that only NULL events are being returned. This means the processor doesn't have to do anything with application 1. The processor looks at application 2. Again NULL events are returned so it's on to application 3 and so on. If any of the applications return an event code, the processor acts, but acts so quickly (even on the ARM 3 this happens quickly) that you don't notice - the system multi-tasks.

There is something worth noting here, that is the types of applications possible.

First we have a single task application.

This is a non WIMP application and typically runs in either a task window or from the * prompt when you press F12.

Next we have a "type 2" application.

These use the WIMP but when processing information, act as single task applications, locking the WIMP to multitask. Programs created using WimpBASIC are type 2 applications.

The third is a fully WIMP and multi-tasking application (such as Impression and TechWriter).

Using SWIs

In one of the first C from the Top tutorials, I talked about RISC OS machines using a buffered input system and that there was a non-standard PC library called Conio.h which did things like wait for a key press.

We have the same, OS_ReadC. A simple example of using an OS call such as ReadC is given below - note, it is still a CLA program, but you can now see what I mean that in some instances, a simple single tasking program helps with the understanding of how something works!

#include <stdio.h>

#include "swis.h"

int main(void)

{

int return_code;

printf("Press any key\n");

_swi(OS_ReadC,_IN(0)|_OUT(0),0,&return_code);

if (return_code>32)

printf("Thank you. You have just pressed the %c key\n",return_code);

else

{

if (return_code==32)

printf("Thank you, you have pressed the space bar\n");

else

printf("Thank you for pressing the return key\n");

}

return 0;

}

What is this _IN(0) lark?

The method for calling a SWI should be

SYS "SWI_NAME",r0,r1,r2,r3...r12 TO r0,r1,r2,r3...r12

As for most SWI calls, not all 12 registers are used for data in or data out, the format is truncated to just using the registers required. The TO indicated that values are returned from the called to module. Again, if you're only interested in (say) r4, the SWI past the TO can be truncated to look like this :

the absence of the registers not required are just indicated by the correct number of commas (for clarity, I've included what should be there as well).

This is quite messy and it is also very simple to make mistakes (one comma short and you read back r3, one too many and you get r5 - neither you want). This is where the _IN and _OUT come in.

You say which SWI is to be called and then the values to be passed and read. Using the same example, if r0 to r3 had to be sent to the module and r4 and r7 to be read back, the call would look like

_swi(some call,_IN(0)|_IN(1)|_IN(2)|_IN(3)|_OUT(4)|_OUT(7),0,1,2,3

,&r4,&r7);

the possibility of the errors by using the comma separator has gone. The only error that can now be made is the wrong data being passed to the module in the first place.

What else can OS calls do?

Everything. That was simple. Alright, they can't feed the dog, make a coffee or tuck your son in at night, but for your machine, they can do anything.

Why use C for programs and not BASIC?

It's swings and round-abouts. While BASIC V is the most powerful BASIC available, it's has it's detractors such as being (relatively) slow, but has the large attractor of it's string handling capabilities.

That said, BASIC doesn't lend itself very much to being a modular programming language (i.e. using libraries of commonly used functions). While there are BASIC libraries such as Justin Fletcher's JFShared, they are few and far between. C is the opposite.

Without having the likes of !OSLib or DeskLib (these are just two of many PD libraries available of common RISC OS C function libraries and will be covered later), a simple header file (called openwin.h) can be constructed and included in any part of your program by just #includeing it. The .h file would look like this

typedef struct win_open {

int vis_x_min;

int vis_y_min;

int vis_x_max;

int vis_y_max;

int x_scroll;

int y_scroll;

int open_behind;

int win_flags;

} win_open;

and in the main code

win_open *open_win;

open_win=malloc(sizeof(win_open));

followed by an appropriate check to see if this much memory can be assigned.

This means that as soon as you've got your library together, application building can be very rapid.

That about wraps things up for this introduction. Next time, we'll get down to some hard stuff, such as starting a program.

Until then, using the StrongHelp OS manual, try constructing some simple CLI/Singletask programs for yourself. You will find it very useful.