!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
HTMLEdit v3 Logo

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.

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

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