Experiments with StrongED – 1

posted in: Software | 0

StrongED has been a popular text editor for RISC OS for three decades. It comes with a huge range of features.

The aim of this series, Experiments with StrongED, is to demonstrate how to create new features. Which version of StrongED you are using yourself should not matter very much. I am in fact using version 4.70a10.

StrongED uses different modes. When you click Select on StrongED’s iconbar-icon an empty StrongED window opens in BaseMode, the default mode. upon which most other modes are based.

You can see a list of the modes available to you already if you click on the iconbar-icon with Adjust. But actually you can define your own modes, for your own special purposes, and this will be the first thing that we demonstrate here. We will call the new mode Trial. You could call it anything else, subject to the rules of RISC OS filenaming. Initially it will not have any special properties apart from those furnished by BaseMode. The point of it is to have something to experiment with.

  1. Click SHIFT-Select on StrongED’s iconbar icon or, if you have version 4.70, click Menu on it and select Open config->UserPrefs. This opens the UserPrefs directory. Create a directory called Trial in UserPrefs.Modes.
  2. In it create an empty textfile called ModeFile.
  3. From the iconbar-icon menu click Rescan dir -> Modes.

You should now find that you have a new mode called Trial available. You should be able to change to it by selecting Change Mode from the submenu appearing when you select the bottom item of a StrongED window’s menu.

Now suppose we want any textfile that starts with the phrase #! trial at the beginning of its first line to be loaded into the Trial mode on being doubleclicked. To ensure this create a textfile called ModeWhen in the directory !StrED_cfg.UserPrefs.Modes.Trial containing

Rules Include
fff, ** ; _trial
End

Match
--->_trial->---><"#!" {White} "trial"
End

The red characters indicate use of the tab key. This is an example of StrongED’s command language, which is described in the Help files that come with StrongED. You will note that Trial mode looks exactly like BaseMode. To give it extra icons along the top or extra entries in its menus we will have to put something in its Modefile. However, if you open a StrongED window in Trial mode, click Menu and go to

Trial->Open Choices 

and save your choices you will see that the Trial directory in !StrED_cfg.UserPrefs.Modes has gained two files: Choices and ColoursStd. These store your choices. So even without giving Trial mode any extra functionality you can still use it to try out alternative effects.

BaseMode is the default mode. In fact I use a non-standard BaseMode because I do not use spell-checking or the Speech module and I prefer a minimalist user-interface to the maximalism of a jumbo-jet cockpit. It is a matter of personal taste.

The point is, StrongED lets you choose. I have been using a non-standard BaseMode for many years and through many versions of StrongED. However, I realize that my own way of using StrongED is very different from other people’s, so I am going to have to rely on plenty of feedback from them. I tend to have only one or two StrongED windows open at a time – minimalism again. But some people have lots of windows open simultaneously. You can drag a directory of textfiles onto the iconbar icon and all will be opened. StrongED provides many facilities for searching, editing and moving between multiple files.

Programming with RiscLua: Remarks on a little WIMP program

posted in: Programming, Software | 1

Gavin Wraith of RiscLua fame takes us through writing WIMP programs in RiscLua. WIMP, if you’re unfamilar with it stands for Windows, Icons, Menus and Pointers, there’s a nicely written intro to WIMP located here if you’d like to learn more about it.

Is this the shortest WIMP program possible?

local task, QUIT in require “task”
local greet = task “briefly”
greet.handler[0] = QUIT
greet:init ( )
greet:alert “hello and goodbye”
greet:run ( )

Here is what it produces… —->

All it does is display an alert box saying hello and goodbye. This is not much, but it will serve as a peg on which to hang some remarks. To run it you need RiscLua, which can be download from here. You may also need the Shared C Library if your system doesn’t have it already.

Once these are installed, create a textfile containing the above program, save it to a file with filetype Lua, and doubleclick on the file’s icon.

To explain this program we need to rehearse some ideas about Lua. It has a special value, called nil whose job is to be different from all other values. It is the value of an undefined expression. A proper value is one that is not nil .

Lua has a single datastructure, the table . BASIC and C let you access memory, so that you can define datastructures by means of arrays and pointers.

By contrast Lua forbids such access, on the grounds of security and portability, but offers the single notion of tables instead. How tables are implemented is not the programmer’s business. You could say that BASIC’s arrays are a bit like tables, except that…

  • The indices, or keys , of a table do not have to be integers. They can be any proper value. Keys in the same table must be distinct. You can have empty tables, with no keys. A table can have itself as one of its keys.
  • The values of a table at an index can be any proper value, including the table itself.
  • Tables can grow or contract dynamically. They do not have to be declared before use.

A statement x = { } creates an empty table. A statement x[key] = value will create a key for the table x with the given value, or update an existing key’s value. A key can be deleted from a table by setting its value to nil.

You can create a table with pre-assigned keys and values with a statement of the form.

x = { [key_1] = val_1, . . . , [key_n] = val_n }

Note that each use of matched braces creates a different table…

x = { }
y = x
print ( x == y ) --> true

but

x = { }
y = { }
print ( x == y ) --> false

It is useful to picture an assignment a[k] = b, where a and b are tables like this:

If we think of the tables as (not necessarily connected) blobs of memory then a key can be thought of as a reference – a pointer. It should be clear how datastructures can be realised in Lua, mimicking anything defined in C using structs and pointers, even though Lua does not permit explicit memory access.

When a key of a table is a string that can be the name of a variable (so does not contain spaces or other forbidden signs) Lua provides a special syntax, whereby x[“foo”] can be written more succinctly as x.foo and inside braces [“foo”] = y can be written as foo = y.

Of course, this looks just like an ordinary assignment. Indeed, global variables are held in a table, so all assignments in Lua are either to local variables or to keys in a table. When tables are used to bundle up values, the table is often referred to as a library.

When x.foo is a function the expression:

x.foo (foo, . . . )

can be written as

x:foo ( . . . )

This notation is handy for implementing notions of object-oriented programming. Note that there is no separate function x:foo and no separate colon operator. It is just a shorthand.

An expression of the form:

{ a_1, . . . ,a_n}

is interpreted as

{ [1] = a_1, . . . , [n] = a_n }

Another notational convention is that if single arguments are literal strings, or are enclosed in braces, then the parentheses round them may be omitted. Examples of this usage can be seen in lines 1,2 and 5 of the program.

Libraries may well be defined in separate files, holding C code or Lua code. The same function, require , is used for loading in both cases. When called with the library file’s name as argument it first checks to see whether the library has already been loaded. If it has it returns that library, as a table.

Otherwise it searches for the library file in the directories specified by the system variables LUA_PATH and LUA_CPATH, and if successful it compiles the code and returns the library as a table. If it fails, it returns nil . So libraries do not get loaded twice, unnecessarily.

The little word in is a useful one. The first line:

local task, QUIT in require "task"

is equivalent to

local lib = require "task"
local task, QUIT = lib.task, lib.QUIT

Do not be put off by the use of the same word task in three different settings

  • as a filename
  • as a key in a table
  • as a local variable

The value QUIT is a handler function. That is to say, it takes as first argument a wimp-task. If it returns nil the wimp-task continues, otherwise the wimp-task will close down. In the second line the function task is used to define a table called greet. This is our wimp-task. It has the title briefly .Wimp-tasks come equipped with special keys

  • init registers the wimp-task with the task-manager.
  • run hands execution over to the task-manager. This can only be called in the last line of the program, since it does not return. It can only be used after init has been called.
  • handler an array of handler functions indexed by wimp-event codes to describe what happens when execution is passed back to the wimp-task by the task-manager.
  • alert runs an auxiliary wimp-task to display a message.

Note how the order of the statements in the program does not strictly reflect the order in which things happen. This is typical of wimp programs, as they have to share execution with the task-manager. In the diagram below the blue blob indicates the wimp-task, the purple blob the task-manager, and the arrows show the transfer of control.


A wimp-task will generally display things on the screen. As far as RISC OS is concerned we can say that a location is an icon in a window.

There are special windows, the desktop and the iconbar, and a window’s work area may count as a special icon. But generally a location is a pair (window, icon).

A window is identified by its window handle , a number assigned by the window manager when the window is created. An icon is identified by a number, the ordinal (starting with 0) of its data in its window’s block. A trigger is a user-action that can take place at a location: typically a click or a drag, into or from.

A WIMP program must specify what happens when a trigger is activated at a location.

This is often described as registering a handler for the trigger. In the RiscLua wimp libraries triggers start with the prefix on_ . For example, can you guess what this might mean?

mytask:register (window, icon)
{
on_Menu = menu.open (icon_menu);
on_Select = mytask:myclickHandler ( );
on_DragSelect = dragobject:start (drag_icon);
}

Menus and drag-objects are all defined by tables, of course.

When I first came across Lua, in 2001, it was clear that it would be a good candidate for porting to RISC OS. This is because it grew out of a software project for PetroBras, the Brazilian state oil company, which did not have a large budget; so the software had to run on a multiplicity of systems.

Portability, therefore, was one of Lua’s primary design goals. In fact Lua is designed to compile on any system with an ANSI C compiler.

What I wanted to do was extend Lua with features that would allow it to access RISC OS, just as BBC BASIC can with its SYS command. There were two difficulties: arithmetic and memory access. The ARM CPUs that RISC OS was designed for had no floating point arithmetic in hardware; RISC OS uses 32-bit integers everywhere.

Lua has for its default doubles, 64-bit floating point numbers. So earlier versions of RiscLua were compiled with 32-bit integers as the standard number type. With version 5.3 of Lua it became easier to cater for the arithmetic side of things. However, on the RISC OS side, only GCC currently supports floating point hardware for the newer ARM CPUs.

The memory access problem is a dichotomy: Lua was designed to prevent it, RISC OS was designed to require it. BASIC’s SYS command would be of little use without DIM, ?, ! and $. It took me some while to find out how to get round the dichotomy properly.

Eventually the modifications needed to marry Lua with RISC OS were put in a single library called riscos . I decided to make its syntax follow closely that of BASIC’s, with sys, dim, ?, !, $ , so that those who are familiar with BBC BASIC should feel at home.

There are some extra twists: dimmed blocks of memory can be collected as garbage when no longer needed, and there are more flexible ways of reading strings from such blocks. Keep in mind that Lua implements strings in a fashion totally different from BASIC. Lua strings are immutable values. Comparison of strings in Lua is as quick as comparison of numbers.

Where BASIC has operators ?, !, $ RiscLua has tables. The byte at an address x is ?[x] . It is as if there were a table ? with addresses for keys and bytes for values. Actually this is an illusion concocted by using metatables , a cunning feature unique to Lua, that allows a certain amount of control over syntax.

From the start I wanted to implement libraries to make wimp programming easier. But I held back, hoping that other people would have a go, reluctant to commit others to something that would almost certainly need updating.

Some brave souls did go ahead: Michael Gerbracht produced LuaFox and Stephan Kleinert produced Mitosis, which both use the toolbox.

It became apparent to me that certain features of Lua, that functions are first-class citizens and that it has lexical scoping, were a huge advantage for hiding the complexities of WIMP programming, and that languages, like BASIC and C, which lack them are at a grave disadvantage.

The whole point of a library, of course, is to hide the implementation details of useful general purpose values, so that wheels do not have to be reinvented. I hope that what this little program does is clear, even if how it does it is not. Note that an explicit number only occurs in the program once, on the third line; 0 is the null wimp-event code (a magic number).

There are no SWIs mentioned, nor the buffers needed for passing data between the wimp-task and the task-manager. RiscLua is well-adapted for implementing abstract notions, such as wimp-task , but, equally important, it is well adapted for hiding detail within libraries.

The same applies to other RiscLua libraries dealing with templates, windows, menus and draggable icons. See here for more details. The libraries in their present form are by no means complete. They are intended as a showcase for what is possible. But I have held off from further development, partly out of idleness and partly because I know that development without feedback can be wasted effort.

A look at package management on RISC OS

posted in: Software | 1

download-1Over the last few years there’s been a dramatic shift from fragmented software distribution to individual software developers offering their programs for purchase or download via distribution channels, better known as App stores or Marketplaces.

The rise of mobile platforms such as iOS and Android have played a huge part in this, and although it’s progressed the quality of distribution channels, these types of places have always been present in a number of Unix and Linux operating systems in the form of package managers.

Historically, RISC OS software followed the same path as software on Windows – if you needed to get a specific piece of software, you found it online or read about it somewhere then you went to the developer to get a copy.

The last few years has seen the emergence of package managers in an attempt to centralise and simplify software distribution on the platform, for the most part I’d say it’s worked too. The success of package management is probably more important for an operating system like RISC OS because there just aren’t enough media outlets – blogs, news portals, magazines etc. that can pull off across-the-board coverage of everything that’s out there.

In a nutshell, package managers are a way of handling software installation, updates, and uninstallation in a centralised, non-biased way. Often, software depends upon other software to properly run. Package management deals with such dependencies, installing what you need to run a program when you’re installing that program. RISC OS in itself is quite modular in the way it works, and the software that runs on it isn’t any different – common dependencies include the Shared C Library and Tinct.

The main difference with package managers on RISC OS is that they are very passive as to where you install software on your system. Generally, package managers on other operating systems, especially Unix-like systems, tend to only use fixed locations for installing software. RISC OS systems don’t follow the same kind of location standards as on other operating systems, the location of most files vary depending on the user’s preferences.

There are two package managers currently available, Pling Store from R-Comp includes a mixture of free and commercial software – while RiskPkg (and the Packman front-end) primarily consists of free and open source programs.

The benefit to installing applications on RISC OS via a package manager apart from not having to manually source each application from the developer’s website, is it’s ease-of-use. It may not be much of an issue for veteran RISC OS users, but for someone who has never used the operating system before, it may be tricky having to download a Zip file or another archive type then have to use (and potentially source then install) a program that can open that file – SparkPlug for example.

If you haven’t looked at package management on RISC OS before, I highly recommend you do. Both RiscPkg and Pling Store are very usable. Packman, a front-end for RiscPkg is also very easy-to-use.

What’s great with Pling Store in particular is its ability to take credit/debit card payments through the application itself, which is great especially considering that if you were to try and make an online purchase via a web browser on RISC OS, it won’t be able to actually display the site in order for you to make the purchase.

Package Managers

1 2 3 4 5 6 7 25