!TopTen
A quick access to recently opened documents
Current release is v0.6.9 of June 4th, 2003, bug reports and comments welcome.
Author: Benoît GILON
Archive ZIP files to download
Foreword
!TopTen is a simple application I wrote after having studied the !Smartdir module by Tony Houghton described in CAUGers issue (Vol. 5 Issue 2 - January 1998). I also wanted to write a sample application which could be of some use to any user on the Acorn platform so the idea of developing !TopTen was born.
!TopTen, unlike the Acorn !TinyDir application and the Acorn Pinboard system, is more like the "recent documents" sub-menu in the Start menu of the Windows 95/NT 4.0 shell and therefore behaves like a FIFO (first in, first out) stack of document references.
- !TopTen offers a window for setting preferences; it saves the user preferences in a separate file on the fly and/or upon application exit.
- !TopTen reads a file which holds the "history documents references" upon starting and saves the FIFO components in that file when the application quits.
- !TopTen itself is made of two components:
- A module named TopTenSupport which installs a post-poll WIMP filter which shows a particular interest in events of type UserMessage, UserMessageRecorderd and UserMessageAcknowledge and for messages Data_Open, Data_Load and Data_LoadAck, as soon as the module has gathered enough data, it store a non zero value to a memory word which an application (!TopTen) has declared as its PollWord.
- A WIMP task (!TopTen itself) which collects all the relevant informations and updates its internal structures (among them the "History document menu").
- At any time, the user can set the maximum number of entries in the internal FIFO stack;
- He can also make the program forget any future user action on some special objets (applications and directories) so that the stack will not fill up.
- He can also limit the display width of the documeent references to their trailing part up to a given level;
- He can also choose to start a document with the application which processed the document at last time instead of simply issuing a Filer_Run on this document. A point to note is that !topTen can then try to boot the application before issuing a Filer_Run on the document (whatever deep the application directory is stored in the File system hierarchy). This option is still under development and not yet available for public release.
- !TopTen iconbar menu has a new entry (Freeze/Unfreeze) which allows a user to (de|re)activate the !TopTen processing of new document openings in the desktop environment (another way to limit the document history menu filling process).
- !TopTen is an Acorn toolbox based application.
Implementation
Module recognition and pollword address computing
When the application is started, it has to compute the module's "pollword" address which is near the top of the module instance's private area.
Include file, part of the !TopTen WIMP task project
typedef struct
{
const char mark[8];
int pollword;
int my_ref;
int your_ref;
int my_tsk;
int your_tsk;
enum {
IDLE= 0,
WAITING,
RAISED
} state;
int file_type;
char *path_name;
size_t mlen1;
} tvpoll;
#ifdef MODMAN
#define EXT
#else
#define EXT extern
#endif
EXT _kernel_oserror *mod_init(void);
EXT tvpoll *pvpoll; /* Address of structure in the Module instance's private area */
EXT int *ppollword; /* Address of pollword */
#undef EXT
C module management file, part of the !TopTen WIMP task management
#define MODMAN
#include "ui.h"
static const char modname[] = "TopTenSupport";
static const char mark[] = "Gotcha";
...
_kernel_oserror *mod_init(void)
{
_kernel_swi_regs r;
_kernel_oserror *p;
char *pmem;
size_t imot;
r.r[0]= 18;
r.r[1]= (int) modname;
p= _kernel_swi(OS_Module, &r, &r);
if(!p) {
atexit(mod_finalize);
pmem= (char *) r.r[4];
/* Don't go further than 512 words from the top of the area */
for(imot= 0; imot < 512; imot++, pmem+= 4)
if(!memcmp(pmem, mark, sizeof(mark) - 1)) break;
/* return "Unable to find module's mark" error if required */
if(imot == 512) return (_kernel_oserror *) &monerr0;
pvpoll= (tvpoll *) (pmem - offsetof(tvpoll, mark));
ppollword= &(pvpoll->pollword);
}
return p;
}
Somewhere in the TopTenSupport module code
static struct
{
const char mark[8];
int pollword;
int my_ref;
int your_ref;
int my_tsk;
int your_tsk;
enum {
IDLE= 0,
WAITING,
RAISED
} state;
int file_type;
char *path_name;
size_t mlen1;
} vpoll =
{
"Gotcha", 0, 0, 0, 0, 0, IDLE,
0, NULL, 0
};
Dynamic creation of menu entries from a RAM template
The function below is called whenever a new entry in the "document history" menu is to be created.
static void new_fname(const char *const path_name, const int file_type, const int tskapp)
{
static MenuTemplateEntry mte =
{
0,
-1, /* ComponentId */
NULL, 0,
NULL, NULL,
0, 0,
NULL, 0
};
char buffer[256];
_kernel_oserror *p;
/* Allocate a new structure for storing the new document reference's properties */
tfname *pfn= (tfname *) malloc(sizeof(tfname));
char *ppath;
if(!pfn) return;
pfn->ppathname= ppath= malloc(strlen(path_name) + 1);
if(!ppath) {
free(pfn);
return;
}
/* The function below is useless for now but will serve in a next release of !TopTen */
ppath= get_leaf(strcpy(ppath, path_name));
pfn->ftype= file_type;
pfn->appname= NULL;
mte.text= ppath;
mte.max_text= strlen(path_name) + 1;
if(pformhstring)
{
/* Setup automatic reply to Help_Request messages */
sprintf(buffer, pformhstring, path_name, file_type);
mte.max_entry_help= strlen(buffer) + 1;
mte.help_message= buffer;
}
p= menu_add_entry(0, fmenuoid, Menu_AddEntryAtEnd, (char *) &mte, &(pfn->cid));
if(p) {
free(pfn->ppathname);
free(pfn);
return;
}
AddTail((struct List *) &fnamelist, (struct Node *) &pfn->mnode);
/* If first time this function is called, then grey out the Open entry (originally greyed) */
if(!nitems++) (void) menu_set_fade(0, ibarmenuoid, KOPENENTRY, 0);
}
Other "what could be" areas of interest
- The module leaf is in charge of returning the trailing part from a fully qualified pathname according to the directory level (user adjustable in the !TopTen choices window).
- New feature of v0.6.5: !TopTen implements a mechanism for internationalizing applications which run under all Acorn toolbox modules' versions known to Mankind as I write. Hélas, the last release takes into account the territory instead of the country as for the previous toolbox releases: I had to write a somewhat tricky procedure to reach the goal. SetRes.c is the name of the related module and is stored in the Topten's Support subdirectory. One of the entry parameters to the toolbox_initialize function becomes "<TopTenR$Dir>" instead of "<TopTen$Dir>". The module SetRes'function is to set this environment variable.
to be continued
Some issues to sort out
While testing !TopTen, I found out that some applications behave badly (IMHO) under the Acorn WIMP sky, when receiving a UserMessageRecorded message which action code is DataLoad or Data_Open from a task like the filer, they do not reply with a DataLoadAck message, but just send a UsermessageAcknowledge to the Wimp so that the original message won't be bounced back to the filer task.
Here are the faulty applications:
to be continued