/* EDIMAP Un éditeur de table de clavier * * Version 1.0 de Septembre 1988 par Gilles Gamesh * * * Ce programme se compile sous Aztec 3.6 avec le makefile suivant : * * CFLAGS = +Iedimap.inc +l +x3 * * OBJS = edimap.o lit_map.o * # ---------------------------------------------------------------- * edimap : $(OBJS) * ln -o $@ $(OBJS) -lc32 * * edimap.inc : edimap.h * cc -A +Hedimap.inc edimap.h +l +x3 * * edimap.o : edimap.c gadgets.h func.h edimap.inc * * lit_map.o : lit_map.c func.h edimap.inc * * * Le code n'est peut-être pas du meilleur C mais il marche, certaines * étrangetées peuvent être du à mon incompréhension de certains points * de la table ou à certains bugs du système. * * */ #include "edimap.h" #include "gadgets.h" #include "func.h" char usage[] = "\tEdimap v1.0\nUsage: Edimap keymap_name"; /*-----------------------------------------------------------------*/ void main(argc, argv) int argc; UBYTE *argv[]; { struct FileHandle *f_in; UWORD *pword; int taille, i; ULONG longtab, nb_str; ULONG *pnb_str, *deb_p_str; ULONG Class; USHORT Code, Qualifier; BOOL encore = TRUE, flgraw = TRUE, flgsave = FALSE; struct Gadget *pMGad; USHORT pMGadID; if (argc == 2) { if (argv[1][0] == '?') { puts(usage); exit(); } else strncpy(nom,argv[1],31); } else { puts(usage); exit(); } if ((buf_p = (struct P_String *)AllocMem(sizeof(struct P_String)*P_SIZE, MEMF_CLEAR)) == NULL) { printf(pas_de_place); exit(1); } if ((buffer = (struct P_String *)AllocMem(sizeof(struct P_String)*P_SIZE, MEMF_CLEAR)) == NULL) { printf(pas_de_place); goto error1; } if ((alstrflag = (UBYTE *)AllocMem(sizeof(UBYTE)*P_SIZE, MEMF_CLEAR)) == NULL) { printf(pas_de_place); goto error2; } /*printf("filebuf %lx\n",filebuf);*/ if ((f_in = Open(nom,MODE_OLDFILE)) == NULL) { printf("Je ne peux trouver le fichier %s\n",nom); goto error3; } taille = Seek(f_in,0L,OFFSET_END); taille = Seek(f_in,0L,OFFSET_BEGINNING); /* printf("taille %d\n",taille);*/ if (taille == 0L) { printf("Fichier vide\n"); goto error3bis; } if ((filebuf = (UBYTE *)AllocMem(taille+1,0L)) == NULL) { printf(pas_de_place); goto error3bis; } if (Read(f_in,filebuf,taille) <= NULL) { printf("Je ne peux lire ce fichier\n"); goto error4; } if ((IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0L)) == NULL) goto error4; if ((GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0L)) == NULL) goto error5; if (!(window = (struct Window *)OpenWindow(&newWindow))) { printf("Je ne peux ouvrir la fenètre\n"); goto error6; } wRPort = window->RPort; /*printf("taille %x,1er %lx\n",taille,*((LONG *)filebuf));*/ if (lit_table()) { printf("Ce n'est pas une table de clavier\n"); goto error7; } question.IText =(UBYTE *)MTapez; PrintIText(wRPort,&question,0L,0L); while (encore == TRUE) { Wait(1 << window->UserPort->mp_SigBit); while (Message = (struct IntuiMessage *)GetMsg(window->UserPort)) { Class = Message->Class; Code = Message->Code; Qualifier = Message->Qualifier; ReplyMsg(Message); pMGad = (struct Gadget *)Message->IAddress; pMGadID = pMGad->GadgetID; if (!(flgraw) && !(flgsave)) { question.IText =(UBYTE *)BlancLigne; PrintIText(wRPort,&question,0L,0L); } switch (Class) { case RAWKEY : if ((Code < 0x60) && flgraw) { flgraw = FALSE; flgsave = FALSE; question.IText =(UBYTE *)BlancLigne; PrintIText(wRPort,&question,0L,0L); if (etape == MAL_FINI) { etape = 0; question.IText =(UBYTE *)BlancLigne; PrintIText(wRPort,&question,100L,100L); } affichegad(ON); LoType = (Code<0x40) ? TRUE : FALSE; key_rel = (Code<0x40) ? Code : Code-0x40; key_abs = Code; initkey(); decodekey(); ajustgad(qual); } break; case GADGETUP: switch (pMGadID) { case G_SHIFT: modifyGad(KCF_SHIFT,G_SHIFT); break; case G_CTRL: modifyGad(KCF_CONTROL,G_CTRL); break; case G_ALT: modifyGad(KCF_ALT,G_ALT); break; case G_DEAD: priorGad(KCF_DEAD,KCF_STRING); break; case G_STRING: priorGad(KCF_STRING,KCF_DEAD); break; case G_OK: /* OK */ ajustkey(); if (invalide) { CopyMem(txt_err[-invalide-1],MErreur+POS_ERR,3L); question.IText =(UBYTE *)MErreur; PrintIText(wRPort,&question,0L,0L); invalide = FAUX; break; } modifie = TRUE; case G_ABORT: /* RESET */ question.IText =(UBYTE *)MTapez; PrintIText(wRPort,&question,0L,0L); flgraw = TRUE; affichegad(OFF); break; case G_SAVE: flgraw = FALSE; flgsave = TRUE; etape=NOM_DU_FICHIER; quel_noms(); break; case G_NOM: PrintIText(wRPort,&Blanc_Txt,0L,TNSTRG); if (etape == NOM_DU_FICHIER) { etape=NOM_DE_LA_TABLE; quel_noms(); } else if (etape == NOM_DE_LA_TABLE) { etape=ECRITURE; quel_noms(); } if (etape >= FINI) { if (etape == FINI) etape = 0; question.IText =(UBYTE *)MFClose; PrintIText(wRPort,&question,0L,0L); flgraw = TRUE; OnGadget(&SaveGad,window,0L); OffGadget(&OkGad,window,0L); /* pour rafraichir */ } break; } break; case CLOSEWINDOW : if (modifie) { question.IText =(UBYTE *)MSortie; PrintIText(wRPort,&question,0L,0L); modifie = FALSE; } else encore = FALSE; } } } error7: CloseWindow(window); error6: CloseLibrary(GfxBase); error5: CloseLibrary(IntuitionBase); error4: FreeMem(filebuf,taille+1); error3bis: Close(f_in); error3: FreeMem((char *)alstrflag,(long)sizeof(UBYTE)*P_SIZE); error2: FreeMem((char *)buffer,(long)sizeof(struct P_String)*P_SIZE); error1: FreeMem((char *)buf_p,(long)sizeof(struct P_String)*P_SIZE); } /*----------------------------------------*/ /* Cette fonction sélecte les 'qualifier gadgets' et ajoute les * 'string gadgets' conormément aux flags passés en argument */ void ajustgad(flg) UBYTE flg; { UBYTE vanille = (flg == KC_VANILLA); strdead = qual & (KCF_DEAD | KCF_STRING); AddGadget(window,&StringGad[b_N],-1L); if (flg & KCF_SHIFT) { selectGad(&TogGad[G_SHIFT],G_SHIFT,ON); AddGadget(window,&StringGad[b_S],-1L); } else if (flg & KCF_CONTROL && flg & KCF_ALT) AddGadget(window,&StringGad[b_CA],-1L); if (flg & KCF_ALT) { selectGad(&TogGad[G_ALT],G_ALT,ON); AddGadget(window,&StringGad[b_A],-1L); } if (flg & KCF_CONTROL) { selectGad(&TogGad[G_CTRL],G_CTRL,ON); if (!(vanille)) AddGadget(window,&StringGad[b_C],-1L); } if (flg & KCF_SHIFT && flg & KCF_ALT) AddGadget(window,&StringGad[b_SA],-1L); if (flg & KCF_CONTROL && flg & KCF_SHIFT && !(vanille)) { AddGadget(window,&StringGad[b_CS],-1L); } if ((flg & KC_VANILLA)==KC_VANILLA) { if (strdead) { AddGadget(window,&StringGad[b_CSA],-1L); AddGadget(window,&StringGad[b_CA],-1L); } else { AffGadget(&StringGad[b_C],b_C); AffGadget(&StringGad[b_CS],b_CS); } } RefreshGadgets(&StringGad[b_N],window,0L); if (flg & KCF_DEAD) { selectGad(&TogGad[G_DEAD],G_DEAD,ON); selectGad(&TogGad[G_STRING],G_STRING,OFF); } if (flg & KCF_STRING) { selectGad(&TogGad[G_STRING],G_STRING,ON); selectGad(&TogGad[G_DEAD],G_DEAD,OFF); } } /*----------------------------------------*/ /* Cette fonction affiche l'image d'un pseudo 'string gadget' */ AffGadget(unGadget,code) struct Gadget *unGadget; int code; { static struct IntuiText unText = {3,0,JAM1,LSTRG};/* init debut */ unText.TopEdge = unGadget->TopEdge; unText.IText = unGadget->GadgetText->IText; PrintIText(wRPort,&unText,-LSTRG+4L,0L); unText.IText = StrBuf[code]; PrintIText(wRPort,&unText,0L,0L); } /*----------------------------------------*/ /* Cette fonction effaces tous les 'string gadgets' */ void deleteSgadgets(onoff) BOOL onoff; { int i; for (i=b_N; i<=b_CSA; i++) RemoveGadget(window,&StringGad[i]); if (!(onoff)) { for (i=b_N; i<=b_CSA; i++) StrBuf[i][0] = '\0'; } for (i=b_N; i<=b_CSA; i++) PrintIText(wRPort,&Blanc_Txt,0L,TSTRG+HSTRG*i); } /*----------------------------------------*/ /* Change les selections de gadgets entre le mode édition et commande */ affichegad(onoff) BOOL onoff; { int i; if (onoff) { cleargadgets(); OnGadget(&AbortGad,window,0L); OffGadget(&SaveGad,window,0L); OnGadget(&OkGad,window,0L); /* RefreshGadgets(&OkGad,window,0L);*/ } else { cleargadgets(); deleteSgadgets(OFF); OffGadget(&AbortGad,window,0L); OnGadget(&SaveGad,window,0L); OffGadget(&OkGad,window,0L); for (i=G_SHIFT; i<=G_DEAD; i++) selectGad(&TogGad[i],i,OFF); /* RefreshGadgets(&OkGad,window,0L);*/ } } /*----------------------------------------*/ /* efface les gadgets de l'écran */ cleargadgets() { SetAPen(window->RPort,0L); RectFill(window->RPort,LGAD-10L,HEIGHT+BGAD-2L,WIDTH-20L,HEIGHT-2L); SetAPen(window->RPort,1L); } /*----------------------------------------*/ /* sélecte ou déselecte un gadget, un certaine gymnastique a été * nécessaire à cause d'un bug qui bascule l'affichage du fond d'un * 'toggle gadget' à chaque refresh */ void selectGad(pGad,pos,onoff) struct Gadget *pGad; BOOL onoff; int pos; { int deja_selecte = 0; RemoveGadget(window,pGad); deja_selecte = pGad->Flags & SELECTED; if (onoff) { if (!(deja_selecte)) { pGad->Flags |= SELECTED; RefreshGList(pGad,window,0L,1L); } } else { if (deja_selecte) { RefreshGList(pGad,window,0L,1L);/* eteint centre */ pGad->Flags &= ~SELECTED; RefreshGList(pGad,window,0L,1L);/* eteint bordure */ } } AddGadget(window,pGad,(long)(pos+3)); } /*----------------------------------------*/ /* Si STRING pas DEAD et vice versa */ void priorGad(gadoui,gadnon) ULONG gadoui, gadnon; { UWORD i; qual &= ~(gadnon); if (qual & gadoui) qual &= ~(gadoui); else qual |= gadoui; deleteSgadgets(OFF); /* for (i=b_N; i<=b_CSA; ++i) StrBuf[i][0] = 0;*/ ajustgad(qual); } /*----------------------------------------*/ /* on a cliqué et sélecté le gadget du type 'type' */ void modifyGad(un_qual,type) ULONG un_qual; int type; { int flg; deleteSgadgets(ON); flg = TogGad[type].Flags; qual &= ~(un_qual); if (flg == SELECTED) qual |= un_qual; StrBuf[b_CSA][0] = 0; switch(un_qual) { case KCF_SHIFT: StrBuf[b_S][0] = 0; StrBuf[b_CS][0] = 0; StrBuf[b_SA][0] = 0; break; case KCF_CONTROL: StrBuf[b_C][0] = 0; StrBuf[b_CA][0] = 0; StrBuf[b_CS][0] = 0; break; case KCF_ALT: StrBuf[b_A][0]= 0; StrBuf[b_SA][0] = 0; StrBuf[b_CA][0] = 0; break; } ajustgad(qual); } /*----------------------------------------*/ /* on ajuste le codage de la touche aux valeurs demandées */ void ajustkey() { UBYTE strcode[257]; /*buffer où on encode la touche */ int nb, i; /*printf("j'ajuste la key %x\n",key_abs);*/ nb = encodekey(strcode); if (invalide) return; if (alstrflag[key_abs]) /* si on a alloue un buffer a la touche */ { free(buf_p[key_abs].p); /* on le libere */ alstrflag[key_abs] = 0; } buf_p[key_abs].l = 0; buf_p[key_abs].p = NULL; if (nb) /* c'est string ou dead */ { buf_p[key_abs].p = (UBYTE *)calloc(nb,1); buf_p[key_abs].l = nb; alstrflag[key_abs] = TRUE; /* marque buffer alloue */ CopyMem(strcode,buf_p[key_abs].p,(long)nb); } else { for (i=0; i<4 ;++i) Tkey.trad[i] = strcode[i]; if (LoType) { keymap.km_LoKeyMap[key_rel] = Tkey.longtrad ; } else { keymap.km_HiKeyMap[key_rel] = Tkey.longtrad ; } } if (LoType) { keymap.km_LoKeyMapTypes[key_rel] = qual; setbitqual(keymap.km_LoCapsable,key_rel,caps); getbitqual(keymap.km_LoRepeatable,key_rel,repet); } else { keymap.km_HiKeyMapTypes[key_rel] = qual; setbitqual(keymap.km_HiCapsable,key_rel,caps); getbitqual(keymap.km_HiRepeatable,key_rel,repet); } } /*----------------------------------------*/ /* on initialise le codage initial de la touche */ void initkey() { if (LoType) { qual = keymap.km_LoKeyMapTypes[key_rel] ; strdead = qual & (KCF_DEAD | KCF_STRING); if (strdead) Tkey.str = (UBYTE *)(buf_p[key_abs].p); else Tkey.longtrad = keymap.km_LoKeyMap[key_rel] ; caps = getbitqual(keymap.km_LoCapsable,key_rel); repet = getbitqual(keymap.km_LoRepeatable,key_rel); } else { qual = keymap.km_HiKeyMapTypes[key_rel] ; strdead = qual & (KCF_DEAD | KCF_STRING); if (strdead) Tkey.str = (UBYTE *)(buf_p[key_abs].p); else Tkey.longtrad = keymap.km_HiKeyMap[key_rel] ; caps = getbitqual(keymap.km_HiCapsable,key_rel); repet = getbitqual(keymap.km_HiRepeatable,key_rel); } } /*----------------------------------------*/ /* on retourne le qualifier de la touche k */ getbitqual(table,k) UBYTE *table; USHORT k; { UBYTE n; n = table[k/8]; return(n & (1 << (k%8))); } /*----------------------------------------*/ /* on modifie le qualifier de la touche k */ void setbitqual(table,k,onoff) UBYTE *table; USHORT k; BOOL onoff; { UBYTE n; n = table[k/8]; table[k/8] = onoff ? (n | (1 << (k%8))) : (n & (~(1 << (k%8)))); } /*----------------------------------------*/ /* on affiche le codage de la touche selectée */ void decodekey() { UBYTE *p, *pi; USHORT i; p = pi = Tkey.str; if (!(qual)) decodele(b_N,Tkey.trad,0); else if (qual & KCF_DEAD) /* dead */ { decodedead(pi,p,b_N); p += 2; for (i=b_S; i<=b_CSA; i++) { if ((qual & i) == i) decodedead(pi,p,i); p += 2; } } else if (qual & KCF_STRING) /* string */ { decodestr(pi,p,b_N,KCF_STRING); p += 2; for (i=b_S; i<=b_CSA; i++) { if ((qual & i) == i) decodestr(pi,p,i,KCF_STRING); p += 2; } } else { decodele(b_N,Tkey.trad,0); if (qual == KCF_SHIFT) decodele(b_S,Tkey.trad,1); else if (qual == KCF_ALT) decodele(b_A,Tkey.trad,1); else if (qual == KCF_CONTROL) decodele(b_C,Tkey.trad,1); else if (qual == (KCF_CONTROL+KCF_ALT)) { decodele(b_A,Tkey.trad,1); decodele(b_C,Tkey.trad,2); decodele(b_CA,Tkey.trad,3); } else if (qual == (KCF_CONTROL+KCF_SHIFT)) { decodele(b_S,Tkey.trad,1); decodele(b_C,Tkey.trad,2); decodele(b_CS,Tkey.trad,3); } else if ((qual & (KCF_SHIFT+KCF_ALT)) == (KCF_SHIFT+KCF_ALT)) { decodele(b_S,Tkey.trad,1); decodele(b_A,Tkey.trad,2); decodele(b_SA,Tkey.trad,3); } if (qual == KC_VANILLA) { decodele(b_C,Tkey.trad,4); decodele(b_CS,Tkey.trad,5); } } } /*-------------------------------------------*/ /* on decode le contenu de la touche pour le qualifier 'cod' */ void decodele(cod,k,n) UBYTE *k; int cod,n; { UBYTE b, *p; p = StrBuf[cod]; b = k[3-n%4]; if (n==7) b = *k; else if (n>3) b &= 0x9f; if (b & 0x60) {*p++ = '\''; *p++ = b; *p++ = '\''; *p = '\0';} else sprintf(p,"%02x",b); } /*-------------------------------------------*/ /* on decode le string de la touche pour le qualifier 'cod' pour une * chaine ou une dead(able) key (flag dans diag) */ void decodestr(deb,k,cod,diac) UBYTE *deb, *k; int cod; ULONG diac; { UBYTE *p, *s, n; char flgaff = '\0'; USHORT i; s = StrBuf[cod]; n = *k; p = deb + *(k+1); for (i=0; i,"); s += 6;} else { sprintf(s,"%02x",*p); s += 2; *s++ = ',';} } } if (flgaff) *s++ = flgaff; else --s; if (diac == KCF_DEAD) { *s++ = ','; *s++ = '('; for (i=0; i<5; i++) *s++ = *p++; *s++ = ')'; } *s = '\0'; } /*-------------------------------------------*/ /* on decode une dead(able) key */ void decodedead(deb,p,cod) UBYTE *deb, *p; int cod; { if (*p == 0) decodele(cod,++p,7); else if (*p == DPF_MOD) decodestr(deb,p,cod,KCF_DEAD); else if (*p == DPF_DEAD) decodeacc(deb,p,cod); } /*-------------------------------------------*/ /* on décode les accents des 'dead key' */ void decodeacc(deb,p,cod) UBYTE *deb, *p; int cod; { UBYTE *s; static UBYTE accent[] = {0xb4, 0x60, 0x5e, 0x7e, 0xa8}; s = StrBuf[cod]; *s++ = '('; *s++ = accent[(*(p+1) & 7)-1]; *s++ = ')'; *s = '\0'; } /*----------------------------------------*/ /* on encode la touche conformément aux souhaits de l'utilisateur */ int encodekey(strcode) UBYTE *strcode; { UBYTE *pstr, *p; USHORT i; short n; UBYTE vanille; invalide = FAUX; /* a priori pas d'erreur */ for (i = 0; i<256 ; ++i) strcode[i] = 0; pstr = strcode; vanille = qual & KC_VANILLA; if (!(qual)) encodele(b_N,pstr,0); /* si qual=0 touche Normale */ else if (strdead = qual & (KCF_DEAD | KCF_STRING)) /* dead */ { for (n=1, i=b_S; i<=b_CSA; i++) if ((qual & i) == i) n++; /* calcule offset */ p = pstr + 2*n; { for (i=b_N; i<=b_CSA; i++) { if ((qual & i) == i) encodestr(i,&pstr,&p,strcode); } } n = p - strcode; } else { encodele(b_N,pstr,0); if (qual == KCF_SHIFT) encodele(b_S,pstr,1); else if (qual == KCF_ALT) encodele(b_A,pstr,1); else if (qual == KCF_CONTROL) encodele(b_C,pstr,1); else if (qual == (KCF_CONTROL+KCF_ALT)) { encodele(b_A,pstr,1); encodele(b_C,pstr,2); encodele(b_CA,pstr,3); } else if (qual == (KCF_CONTROL+KCF_SHIFT)) { encodele(b_S,pstr,1); encodele(b_C,pstr,2); encodele(b_CS,pstr,3); } else if ((qual & (KCF_SHIFT+KCF_ALT)) == (KCF_SHIFT+KCF_ALT)) { encodele(b_S,pstr,1); encodele(b_A,pstr,2); encodele(b_SA,pstr,3); } /* if (qual == KC_VANILLA) { encodele(b_C,pstr,4); encodele(b_CS,pstr,5); } */ } return (strdead ? n : 0); } /*-------------------------------------------*/ /* on encode le string demandé et vérifie sa validité */ void encodestr(cod,plong,ptexte,pdeb) int cod; UBYTE **plong, /* la ou on va mettre la longueur du string */ **ptexte, /* la ou on met le texte du string */ *pdeb; /* buffer d'encodage */ { UBYTE *p, c; int nb=0 , off, invacode; int tampon; invacode = -(cod+1); p = StrBuf[cod]; /* string a coder */ off = *ptexte - pdeb; if (strdead == KCF_STRING) { nb = form(p,*ptexte,'s'); *(*plong)++ = nb; *(*plong)++ = off; *ptexte += nb; } else /* dead or deadeable */ { if (*p == '(') /* dead */ { if (p[2] == ')') /* dead key */ { *(*plong)++ = DPF_DEAD; if ((tampon = queldead(p[1])) == ERROR) { invalide = invacode; return; } else { *(*plong)++ = tampon; return; } } else /* ne doit pas commencer par parenthese */ { invalide = invacode; return; } } else if (strlen(p) > 3) /* deadable */ { nb=form(p,*ptexte,'d') ; /* le code de reference */ *(*plong)++ = DPF_MOD; *(*plong)++ = off; *ptexte += nb; } else /* caractère normal */ { *(*plong)++ = 0; nb=form(p,*plong,'c'); ++(*plong); } } if (nb < 0) invalide = invacode; return; } /*-------------------------------------------*/ /* on recherche le type d'accent demandé */ queldead(c) UBYTE c; { switch(c) { case 0xB4: case '\'': return(1); case '`': return(2); case '^': return(3); case '~': return(4); case 0xA8: case '"': return(5); default: return(ERROR); } } /*-------------------------------------------*/ /* on encode sur 4 bytes les codes demandés * on met en k le code traduit demande pour cod avec decalage n * si n > 3 control (shift) pour vanilla (n'est plus utilisé) */ void encodele(cod,k,n) UBYTE *k; int cod,n; { UBYTE b, *p; int nb, invacode; invacode = -(cod+1); p = StrBuf[cod]; if ((nb = form(p,&b,'c')) < 0) {invalide = invacode; return;} /* if (n>3) b &= 0x9f; k[3-n%4] = b; */ k[3-n] = b; return; } /*-------------------------------------------*/ /* deformatte string s en d avec specifs f */ /* 'c' copie le car 'x' ou dont le code ascii hexa est donné * 'd' copie le car et les 5 dead-codes suivants entre () ')' * 'a' parse un string de la forme 41,,'m toto',0D,0A */ form(s,d,f) UBYTE *s, *d; char f; { char strin = '\0'; int b=0; UBYTE *memd; short i; memd = d; switch(f) { case 'c': if (*s == '\'') { *d++ = *++s; ++s; if (*s++ != '\'') return ERROR; } else { b = axtoi(&s); if (b < 256) *d++ = b; else return ERROR; } while (*s == ' ') ++s; /* des blancs sont authorises a la fin */ if (*s) return ERROR; /* mais rien d'autre */ break; case 'd' : if (*s == '\'') { *d++ = *++s; ++s; if (*s++ != '\'') return ERROR; } else { b = axtoi(&s); if (b < 256) *d++ = b; else return ERROR; } while (*s == ' ') ++s; if (*s++ != ',') return ERROR; while (*s == ' ') ++s; if (*s++ == '(') { for (i=0; i<5; i++) *d++ = *s++; if (*s++ != ')') return ERROR; } else return ERROR; while (*s == ' ') ++s; /* des blancs sont authorises a la fin */ if (*s) return ERROR; /* mais rien d'autre */ break; case 'a': break; case 's': --s; /* predecremente pour pouvoir incrementer */ while (*(++s)) switch(*s) { case '\'': case '"': if (strin == *s) strin = '\0'; else if (!(strin)) strin = *s; else *d++ = *s; break; case ',': if (!(strin)) break; else *d++ = *s; break; default: if (strin) *d++ = *s; else { if (!(strncmp(s,"",4))) { *d++ = 0x9b; s += 4; } else { b = axtoi(&s); while (*s == ' ') ++s; if (*s && (*s != ',')) return ERROR; --s; /* pour tester le 0 au coup suivant */ if (b < 256 && b >= 0) *d++ = b; else return (ERROR); } } break; } } return (strin ? ERROR : d-memd); } /*------------------------------------------ */ /* traduit une chaine hexa en un entier */ axtoi(pp) char **pp; { char *p; int i = 0; p = *pp; while (isspace(*p)) p++; while (isxdigit(*p)) { i = i * 16 +(isdigit(*p) ? *p - '0' : (*p & 0x5f) - 55); p++; } *pp = p; return i; } /*------------------------------------------ */ /* gère la demande des noms de fichier et de table */ quel_noms() { UBYTE *p; int l; question.IText =(UBYTE *)BlancLigne; PrintIText(wRPort,&question,0L,0L); switch(etape) { case NOM_DU_FICHIER: OffGadget(&SaveGad,window,0L); cleargadgets(); question.IText =(UBYTE *)"Nom du fichier à sauver ?"; PrintIText(wRPort,&question,0L,0L); if (p=index(nom,'.')) l = p-nom; else l = strlen(nom); strncpy(NomStrBuf,nom,l); NomStrBuf[l]='\0'; strcat(NomStrBuf,".map"); Nom_strinfo.BufferPos = l+4; AddGadget(window,&NomGad,-1L); RefreshGadgets(&NomGad,window,0L); ActivateGadget(&NomGad,window,0L); break; case NOM_DE_LA_TABLE: RemoveGadget(window,&NomGad); if (*NomStrBuf == 0) goto inval; strcpy(nom_fich,NomStrBuf); question.IText =(UBYTE *)"Nom de la table de clavier ?"; PrintIText(wRPort,&question,0L,0L); if (p=index(NomStrBuf,'.')) { l = p-NomStrBuf; *p = '\0'; } else l = strlen(NomStrBuf); Nom_strinfo.BufferPos = l; AddGadget(window,&NomGad,-1L); RefreshGadgets(&NomGad,window,0L); ActivateGadget(&NomGad,window,0L); break; case ECRITURE: RemoveGadget(window,&NomGad); if (*NomStrBuf == 0) { question.IText =(UBYTE *)"Nom INVALIDE,"; goto inval; } if (ecr_table(nom_fich,NomStrBuf)) { question.IText =(UBYTE *)"Pb d'écriture,"; goto inval; } modifie = FALSE; etape = FINI; break; } return; inval: PrintIText(wRPort,&question,100L,100L); question.IText =(UBYTE *)"le fichier N'est PAS sauvé"; PrintIText(wRPort,&question,220L,100L); etape = MAL_FINI; return; }