!TopTen

Un accès rapide aux documents récemment ouverts
La version actuelle est v0.6.9 du 4 Juin 2003, rapports d'anomalie et commentaires sont les bienvenus.
Auteur: Benoît GILON
HTMLEdit v3 Logo

Fichiers archive ZIP à charger


Présentation

!TopTen est une application simple que j'ai écris après l'étude du module !SmartDir de Tony Houghton décrit dans le numéro de Caugers (Vol. 5 N° 2 - Janvier 1998). Je voulais aussi écrire une application exemple qui pourrait être de quelque utilité pout tout utilisateur de plate-forme RISC OS; Ainsi est né !TopTen.
!TopTen, contrairement de l'application !TinyDir d'Acorn ou du système "PinBoard" de RiscOS 3.1, trouve son "frère jumeau" dans l'entrée de menu "Documents" du menu "Démarrer" du shell Windows 95/NT 4.0 et par conséquent se comporte comme une pile FIFO (premier entré, premier sorti) de références de documents.

Implémentation

Reconnaissance du module et détermination de l'addresse du PollWord

Lors du démarrage de l'application, cette dernière a besoin de connaitre l'adresse du "PollWord" du module, ce dernier se trouvant proche du sommet de la zone privée de l'instance du module.

Fichier Include, faisant partie du composant "tâche WIMP" de !TopTen

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

Fichier C chargé de la communication avec le module ToptenSupport

#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;
}

Quelque part dans le code du module ToptenSupport

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
        };

Création dynamique d'entrée de menu à partir d'un canevas en mémoire

Cette fonction est appelée dès que une entrée dans le menu "historique" est à créer.
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);
}

Autres points d'intérêt potentiels

à suivre

Quelques problèmes survenus lors du développement de !TopTen

J'ai découvert que certaines applications sous WIMP n'adoptaient pas un comportement tout à fait conforme au protocole standard Acorn, lorsque ces dernières reçoivent un message UserMessageRecorded avec un code action DataLoad ou Data_Open provenant d'une tâche comme le Filer, elles ne répondaient pas à ce dernier avec un message dont l'action est DataLoadAck mais se contentaient de renvoyer un message UsermessageAcknowledge au WIMP de sorte que le message original ne soit pas retourné tel quel à la tache Filer.
Voici quelles sont les applications en cause: à suivre

Points d'amélioration (prévus pour la v0.7.5)

à suivre