/* NECquik Version 1.2D
   -------------------
   Ein Utility für NEC-
   Drucker und Kompatible.
   Bietet die Möglichkeit,
   schnell mal per Knopf-
   druck Druckerparameter
   zu verändern (und noch
   ein paar Extras,die das
   Printer Device nicht
   zuläßt).
   --------------------
   Diese Version © 21.8.88 by Tim Pietzcker Software
*/

#include <intuition/intuition.h>
#include <graphics/gfxbase.h>
#include <stdio.h>
#include <exec/types.h>

#define QUAL 1l   /* Gadget-IDs */
#define ENHA 2l
#define ITAL 3l
#define UNDE 4l
#define USER 5l
#define STYL 6l
#define LMAR 7l
#define RMAR 8l
#define RESE 9l
#define PRIN 10l
#define DOUB 11l
#define HORI 12l
#define VERT 13l
#define SPEC 14l
#define LINE 15l
#define FEED 16l
#define SEND 17l
#define OK   18l
#define CLR  19l
#define TEXT 20l
#define CLOS 21l

/* jetzt definiere ich alle Steuercodes als Variablen
   => Anpassung an andere Drucker zumindest teilweise möglich.
   Erstes Byte: Anzahl der nachfolgenden Steuerzeichen */

char cquon [] = { 3,27,'x',1 };  /* LQ on */
char cquoff[] = { 3,27,'x',0 };  /* Draft on */
char cenon [] = { 2,27,'E' };    /* Enhanced Printing on */
char cenoff[] = { 2,27,'F' };    /*     "        "    off */
char citon [] = { 2,27,'4' };    /* Italics on */
char citoff[] = { 2,27,'5' };    /*    "    off */
char cunon [] = { 3,27,'-',1 };  /* Underline on */
char cunoff[] = { 3,27,'-',0 };  /*     "     off */
char cuson [] = { 6,27,'p',1,27,'%',1 };  /* Userdefined font on */
char cusoff[] = { 6,27,'%',0,27,'p',0 };  /*       "      "   off */
char cstyl [] = { 2,27,'!' };    /* Print style : 0-255 */
char clmar [] = { 2,27,'l' };    /* Left margin : 0-255 */
char crmar [] = { 2,27,'Q' };    /* Right margin: 0-255 */
char crese [] = { 2,28,64 };     /* Reset Printer */
char cpr10 [] = { 3,18,27,'P' }; /* 10 cpi (18=condensed print off) */
char cpr12 [] = { 3,18,27,'M' }; /* 12 cpi */
char cpr15 [] = { 3,18,27,'g' }; /* 15 cpi */
char cpr17 [] = { 4,27,'P',27,15 }; /* 17 cpi */
char cpr20 [] = { 4,27,'M',27,15 }; /* 20 cpi */
char cdoon [] = { 2,27,'G' };    /* Double-strike on */
char cdooff[] = { 2,27,'H' };    /*       "       off */
char chori [] = { 2,28,'E' };    /* Horiz.Enlargement ; then Char 0-2 */
char cvert [] = { 2,28,'V' };    /*  Vert.     "      ; then Char 0-1 */
char csuper[] = { 3,27,'S',0 };  /* Superscript on */
char csub  [] = { 3,27,'S',1 };  /* Subscript on */
char cspoff[] = { 2,27,'T' };    /* Cancel super/subscript */
char cline [] = { 2,27,'3' };    /* Set Line feed to n/180" ;n 0-255 */
char cfeed [] = { 1,10,13 }; /* Line Feed (4.: Carriage Return) */

UBYTE hexbuf[21]="1B 70 01",textbuf[80]="Schicke Text zum Drucker !",
      stylbuf[4]="0",lmarbuf[4]="1",rmarbuf[4]="80",linebuf[4]="25",
      feedbuf[4]="5",undobuf[80]; /* String gadget buffers */

char prclosed=0;  /* Kontrollflag, ob Drucker offen ist */
char ctrl[] = { 0,0,1,0,2,0 };
char hexp[] = { 1,16 };
UBYTE st[2][4]= { "aus"," an" };
UBYTE sp[3][12]= { "        aus","  Hochdruck"," Indexdruck" };
UBYTE qu[2][8]= { "Schnell","  Schön" };
FILE *fopen(),*printer;
UBYTE comment[4][31] = { "NECquik © `88 Tim Pietzcker  ",
                         "Bitte Wert zwischen 0 & 255! ",
                         "Bitte Drucker bereit machen! ",
                         "Bitte Drucker öffnen !!      " };
short AutoRequest();                   /* Deklaration der Bibliotheks- */
struct IntuitionBase *IntuitionBase;   /* Routinen und Strukturen etc. */
struct GfxBase       *GfxBase;
struct Library       *OpenLibrary();
struct Window        *OpenWindow(),*MyWindow;
struct RastPort      *rp;
struct IntuiMessage  *GetMsg(),*msg;
struct TextAttr      MyFont =
     { (UBYTE *)"topaz.font",TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT };

/* jetzt kommen alle 20 Gadgets (Texte,Borders,StringInfos etc.pp.) */

struct IntuiText tQUAL =
   { 1,0,JAM1,0,1,&MyFont,(UBYTE *)"Schrift:",NULL };
struct IntuiText tENHA =
   { 1,0,JAM1,0,1,&MyFont,(UBYTE *)"Fettdruck :",NULL };
struct IntuiText tITAL =
   { 1,0,JAM1,0,1,&MyFont,(UBYTE *)"Kursiv    :",NULL };
struct IntuiText tUNDE =
   { 1,0,JAM1,0,1,&MyFont,(UBYTE *)"Unterstrich:",NULL };
struct IntuiText tUSER =
   { 1,0,JAM1,0,1,&MyFont,(UBYTE *)"User Font :",NULL };
struct IntuiText tRESE =
   { 3,0,JAM1,0,1,&MyFont,(UBYTE *)" Drucker-Reset",NULL };
struct IntuiText tPRIN =
   { 1,0,JAM1,0,1,&MyFont,(UBYTE *)"Druckweite :",NULL };
struct IntuiText tDOUB =
   { 1,0,JAM1,0,1,&MyFont,(UBYTE *)"Schattendruck  :",NULL };
struct IntuiText tHORI =
   { 1,0,JAM1,0,1,&MyFont,(UBYTE *)"Horiz.Vergrößerung:",NULL };
struct IntuiText tVERT =
   { 1,0,JAM1,0,1,&MyFont,(UBYTE *)"Vert. Vergrößerung:",NULL };
struct IntuiText tSPEC =
   { 1,0,JAM1,0,1,&MyFont,(UBYTE *)"Spezial :",NULL };
struct IntuiText tOK =
   { 1,0,JAM1,5,1,&MyFont,(UBYTE *)"OK",NULL };
struct IntuiText tCLR =
   { 1,0,JAM1,2,1,&MyFont,(UBYTE *)"Clr",NULL };
struct IntuiText tSTYL =
   { 1,0,JAM1,-96,0,&MyFont,(UBYTE *)"Druckart   ",NULL };
struct IntuiText tLMAR =
   { 1,0,JAM1,-60,0,&MyFont,(UBYTE *)"Ränder",NULL };
struct IntuiText tLINE1 =
   { 1,0,JAM1,-110,0,&MyFont,(UBYTE *)"Zeilenabstand",NULL };
struct IntuiText tLINE =
   { 1,0,JAM1,30,0,&MyFont,(UBYTE *)"/180\042",&tLINE1 };
struct IntuiText tFEED1 =
   { 1,0,JAM1,-88,0,&MyFont,(UBYTE *)"Vorschub ",NULL };
struct IntuiText tFEED =
   { 1,0,JAM1,36,0,&MyFont,(UBYTE *)"Zeilen",&tFEED1 };
struct IntuiText tSEND =
   { 1,0,JAM1,-72,0,&MyFont,(UBYTE *)"Hexacode",NULL };
struct IntuiText tCLOS =
   { 1,0,JAM1,0,1,&MyFont,(UBYTE *)"Drucker  :",NULL };
struct IntuiText tPOS =
   { 1,0,COMPLEMENT,5,3,&MyFont,(UBYTE *)" ENDE ",NULL };
struct IntuiText tNEG =
   { 1,0,COMPLEMENT,5,3,&MyFont,(UBYTE *)" NEIN! ",NULL };
struct IntuiText tBODY =
   { 1,0,COMPLEMENT,22,6,&MyFont,(UBYTE *)"Wollen Sie wirklich aufhören?",
      NULL };

SHORT Koord1[] = { -3,-1, 123,-1, 123,9, 124,9, 124,-1, 124,9, -3,9,
                   -3,-1, -4,-1, -4,9 };
SHORT Koord2[] = { -3,-2, 27,-2, 27,8, 28,8, 28,-2, 28,8, -3,8,
                   -3,-2, -4,-2, -4,8 };
SHORT Koord3[] = { -3,-1, 171,-1, 171,9, 172,9, 172,-1, 172,9, -3,9,
                   -3,-1, -4,-1, -4,9 };
SHORT Koord4[] = { -3,-2, 99,-2, 99,8, 100,8, 100,-2, 100,8, -3,8,
                   -3,-2, -4,-2, -4,8 };
SHORT Koord5[] = { -3,-2, 307,-2, 307,8, 308,8, 308,-2, 308,8, -3,8,
                   -3,-2, -4,-2, -4,8 };
SHORT Koord6[] = { -3,-1, 27,-1, 27,9, 28,9, 28,-1, 28,9, -3,9,
                   -3,-1, -4,-1, -4,9 };

struct Border Border1 =
   { 0l,0l,1l,0l,JAM1,10l,Koord1,NULL };
struct Border Border2 =
   { 0l,0l,1l,0l,JAM1,10l,Koord2,NULL };
struct Border Border3 =
   { 0l,0l,1l,0l,JAM1,10l,Koord3,NULL };
struct Border Border4 =
   { 0l,0l,1l,0l,JAM1,10l,Koord4,NULL };
struct Border Border5 =
   { 0l,0l,1l,0l,JAM1,10l,Koord5,NULL };
struct Border Border6 =
   { 0l,0l,1l,0l,JAM1,10l,Koord6,NULL };

struct StringInfo siSTYL =
   { stylbuf,undobuf,NULL,4l,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
struct StringInfo siLMAR =
   { lmarbuf,undobuf,NULL,4l,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
struct StringInfo siRMAR =
   { rmarbuf,undobuf,NULL,4l,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
struct StringInfo siLINE =
   { linebuf,undobuf,NULL,4l,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
struct StringInfo siFEED =
   { feedbuf,undobuf,NULL,4l,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
struct StringInfo siSEND =
   { hexbuf,undobuf,NULL,20l,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
struct StringInfo siTEXT =
   { textbuf,undobuf,NULL,80l,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };

struct Gadget gTEXT =
   { NULL,8,112,304,9,GADGHCOMP,RELVERIFY,STRGADGET,
      (APTR)&Border5,NULL,NULL,NULL,(APTR)&siTEXT,TEXT,NULL };
struct Gadget gCLOS =
   { &gTEXT,100,123,120,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
      (APTR)&Border1,NULL,&tCLOS,NULL,NULL,CLOS,NULL };
struct Gadget gOK =
   { &gCLOS,288,123,24,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
      (APTR)&Border6,NULL,&tOK,NULL,NULL,OK,NULL };
struct Gadget gCLR =
   { &gOK,8,123,24,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
      (APTR)&Border6,NULL,&tCLR,NULL,NULL,CLR,NULL };
struct Gadget gRESE =
   { &gCLR,8,99,120,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
      (APTR)&Border1,NULL,&tRESE,NULL,NULL,RESE,NULL };
struct Gadget gSEND =
   { &gRESE,216,100,96,9,GADGHCOMP,RELVERIFY,STRGADGET,
      (APTR)&Border4,NULL,&tSEND,NULL,(APTR)&siSEND,SEND,NULL };
struct Gadget gLMAR =
   { &gSEND,68,88,24,9,GADGHCOMP,RELVERIFY|LONGINT,STRGADGET,
      (APTR)&Border2,NULL,&tLMAR,NULL,(APTR)&siLMAR,LMAR,NULL };
struct Gadget gRMAR =
   { &gLMAR,104,88,24,9,GADGHCOMP,RELVERIFY|LONGINT,STRGADGET,
      (APTR)&Border2,NULL,NULL,NULL,(APTR)&siRMAR,RMAR,NULL };
struct Gadget gFEED =
   { &gRMAR,232,88,24,9,GADGHCOMP,RELVERIFY|LONGINT,STRGADGET,
      (APTR)&Border2,NULL,&tFEED,NULL,(APTR)&siFEED,FEED,NULL };
struct Gadget gSTYL =
   { &gFEED,104,76,24,9,GADGHCOMP,RELVERIFY|LONGINT,STRGADGET,
      (APTR)&Border2,NULL,&tSTYL,NULL,(APTR)&siSTYL,STYL,NULL };
struct Gadget gLINE =
   { &gSTYL,247,76,24,9,GADGHCOMP,RELVERIFY|LONGINT,STRGADGET,
      (APTR)&Border2,NULL,&tLINE,NULL,(APTR)&siLINE,LINE,NULL };
struct Gadget gUSER =
   { &gLINE,8,63,120,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
      (APTR)&Border1,NULL,&tUSER,NULL,NULL,USER,NULL };
struct Gadget gSPEC =
   { &gUSER,144,63,168,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
      (APTR)&Border3,NULL,&tSPEC,NULL,NULL,SPEC,NULL };
struct Gadget gUNDE =
   { &gSPEC,8,51,120,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
      (APTR)&Border1,NULL,&tUNDE,NULL,NULL,UNDE,NULL };
struct Gadget gVERT =
   { &gUNDE,144,51,168,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
      (APTR)&Border3,NULL,&tVERT,NULL,NULL,VERT,NULL };
struct Gadget gITAL =
   { &gVERT,8,39,120,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
      (APTR)&Border1,NULL,&tITAL,NULL,NULL,ITAL,NULL };
struct Gadget gHORI =
   { &gITAL,144,39,168,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
      (APTR)&Border3,NULL,&tHORI,NULL,NULL,HORI,NULL };
struct Gadget gENHA =
   { &gHORI,8,27,120,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
      (APTR)&Border1,NULL,&tENHA,NULL,NULL,ENHA,NULL };
struct Gadget gDOUB =
   { &gENHA,144,27,168,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
      (APTR)&Border3,NULL,&tDOUB,NULL,NULL,DOUB,NULL };
struct Gadget gQUAL =
   { &gDOUB,8,15,120,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
      (APTR)&Border1,NULL,&tQUAL,NULL,NULL,QUAL,NULL };
struct Gadget gPRIN =
   { &gQUAL,144,15,168,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
      (APTR)&Border3,NULL,&tPRIN,NULL,NULL,PRIN,NULL };

/* So,das waren die Gadgets */

struct NewWindow TheWindow =
{
   20,0,             /* links oben */
   320,136,          /* Breite,Höhe */
   3,2,              /* Detail-,Blockpen */
   GADGETUP|CLOSEWINDOW,     /* IDCMP-Flags */
   WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|SMART_REFRESH|ACTIVATE, /* Flags */
   &gPRIN,           /* First Gadget */
   NULL,             /* Checkmark */
   (UBYTE *)"NECquik © `88 Tim Pietzcker  ",  /* Titel */
   NULL,NULL,
   0,0,0,0,
   WBENCHSCREEN
};

open_w()
{
   if((IntuitionBase = (struct IntuitionBase *)
      OpenLibrary("intuition.library",0l))==NULL) exit(FALSE);
   if((GfxBase = (struct GfxBase *)
      OpenLibrary("graphics.library",0l))==NULL) exit(FALSE);
   if((MyWindow = OpenWindow(&TheWindow))==NULL) exit(FALSE);
   rp = MyWindow->RPort;
}

print_error(i)    /* Ändere den Windowtitel,wenn ein Fehler auftritt */
int i;
{
   long c;
   DisplayBeep(MyWindow->WScreen);
   SetWindowTitles(MyWindow,comment[i],-1l);
   for(c=0;c<100000;c++);
   SetWindowTitles(MyWindow,comment[0],-1l);
}

check_value(string)  /* Werte in LONGINT-Gadgets müssen >=0 und <256 sein */
char *string;
{
   int r;
   r=atoi(string);
   if (r<0 || r>255) return (-1);
   return(r);
}

open_prt()     /* nur um das Printer Device zu laden,damit die eingestellten
                  Parameter nicht wieder rückgängig gemacht werden,sobald
                  etwas zu PRT: geschickt wird */
{
   if ((printer=fopen("PRT:","w"))==NULL) return (2);
   send_out(&cspoff[1],cspoff[0]);
   fclose(printer);
   return(0);
}

open_par()     /* über PAR: werden die Daten geschickt */
{
   long i;
   if ((printer=fopen("PAR:","w"))!=NULL) return(0);
   else
   {
      print_error(2);
      for(i=0;i<500000;i++);
      return (2);
   }
}

send_out(string,length)    /* Diese Routine schickt Strings zum Drucker */
char *string,length;
{
   char i;
   int error;
   if (prclosed) return(3);   /* Printer wurde geschlossen ? */
   for (i=0;i<length;i++)
   {
      error=fputc(string[i],printer);
      if (error == -1) return (2);
   }
   return(0);
}

hex_to_char(string)        /* Formt eine Zeichenkette in Zahlen/Chars um */
char *string;
{
   int pow=0,i,count=0;
   char out[11];
   for (i=0;i<=11;i++) out[i]=0;
   for (i=0;string[i];i++)
   {
      switch (string[i])
      {
         case 'F':
         case 'f':
            pow=1-pow;
            out[count]|=15*hexp[pow];
            if (pow==0) count++;
            break;
         case 'E':
         case 'e':
            pow=1-pow;
            out[count]|=14*hexp[pow];
            if (pow==0) count++;
            break;
         case 'D':
         case 'd':
            pow=1-pow;
            out[count]|=13*hexp[pow];
            if (pow==0) count++;
            break;
         case 'C':
         case 'c':
            pow=1-pow;
            out[count]|=12*hexp[pow];
            if (pow==0) count++;
            break;
         case 'B':
         case 'b':
            pow=1-pow;
            out[count]|=11*hexp[pow];
            if (pow==0) count++;
            break;
         case 'A':
         case 'a':
            pow=1-pow;
            out[count]|=10*hexp[pow];
            if (pow==0) count++;
            break;
         case '9':
            pow=1-pow;
            out[count]|=9*hexp[pow];
            if (pow==0) count++;
            break;
         case '8':
            pow=1-pow;
            out[count]|=8*hexp[pow];
            if (pow==0) count++;
            break;
         case '7':
            pow=1-pow;
            out[count]|=7*hexp[pow];
            if (pow==0) count++;
            break;
         case '6':
            pow=1-pow;
            out[count]|=6*hexp[pow];
            if (pow==0) count++;
            break;
         case '5':
            pow=1-pow;
            out[count]|=5*hexp[pow];
            if (pow==0) count++;
            break;
         case '4':
            pow=1-pow;
            out[count]|=4*hexp[pow];
            if (pow==0) count++;
            break;
         case '3':
            pow=1-pow;
            out[count]|=3*hexp[pow];
            if (pow==0) count++;
            break;
         case '2':
            pow=1-pow;
            out[count]|=2*hexp[pow];
            if (pow==0) count++;
            break;
         case '1':
            pow=1-pow;
            out[count]|=hexp[pow];
            if (pow==0) count++;
            break;
         case '0':
            pow=1-pow;
            if (pow==0) count++;
            break;
         default:
            break;
      }
   }
   if (pow) count++;
   return(send_out(out,count));
}

init_w()    /* initialisiere die Gadgets */
{
   SetDrMd(rp,JAM2);
   SetAPen(rp,1l);
   Move(rp,72l,22l);
   Text(rp,(UBYTE *)"  Schön",7l);
   Move(rp,104l,34l);
   Text(rp,(UBYTE *)"aus",3l);
   Move(rp,104l,46l);
   Text(rp,(UBYTE *)"aus",3l);
   Move(rp,104l,58l);
   Text(rp,(UBYTE *)"aus",3l);
   Move(rp,104l,70l);
   Text(rp,(UBYTE *)"aus",3l);
   Move(rp,264l,22l);
   Text(rp,(UBYTE *)"10 cpi",6l);
   Move(rp,288l,34l);
   Text(rp,(UBYTE *)"aus",3l);
   Move(rp,304l,46l);
   Text(rp,(UBYTE *)"0",1l);
   Move(rp,304l,58l);
   Text(rp,(UBYTE *)"0",1l);
   Move(rp,224l,70l);
   Text(rp,(UBYTE *)"        aus",11l);
   Move(rp,196l,130l);
   Text(rp,(UBYTE *)" an",3l);
}

end()
{
   if (prclosed==0) fclose(printer);
   CloseWindow(MyWindow);
   CloseLibrary(GfxBase);
   CloseLibrary(IntuitionBase);
   exit(TRUE);
}

toggle_gadget(var,string1,string2)
char *var,*string1,*string2;
{
   int er;
   *var=1- *var;
   if (*var) er=send_out(&string1[1],string1[0]);
   else er=send_out(&string2[1],string2[0]);
   if (er)
   {
      print_error(er);
      *var=1- *var;
      return(0);
   }
   return(1);
}

change_width(string,text)
char *string,*text;
{
   int er;
   er=send_out(&string[1],string[0]);
   if (er) {  print_error(er);  return(0);   }
   else Move(rp,264l,22l),Text(rp,(UBYTE *)text,6l);
   fflush(printer);
   return(1);
}

send_longint(string,buffer)
char *string,*buffer;
{
   char cha;
   int er;
   cha=check_value(buffer);
   if (cha==-1) { print_error(1);
                  return;
                }
   er=send_out(&string[1],string[0]);
   if (er) { print_error(er);
             return;
           }
   er=send_out(&cha,1);
   if (er) print_error(er);
}

main()
{
   char cha,clo=0,qua=1,enh=0,ita=0,und=0,
        use=0,pri=0,dou=0,hor=0,ver=0,spe=0;
   short result;
   int er,i;
   open_w();
   init_w();
   while (open_prt()) print_error(2);  /* Ist Drucker an? */
   while (open_par());                 /* Ausgabekanal öffnen */

   for (;;)
   {
      Wait(1l << MyWindow->UserPort->mp_SigBit);
      while ((msg=GetMsg(MyWindow->UserPort))!=NULL)
      {
         switch(msg->Class)
         {
            case CLOSEWINDOW:
               if ((result=AutoRequest(MyWindow,&tBODY,&tPOS,&tNEG,NULL,
                           NULL,300l,50l))==TRUE) end();
               break;
            case GADGETUP:
               switch (((struct Gadget *)(msg->IAddress))->GadgetID)
               {
                  case QUAL:
                     if (toggle_gadget(&qua,cquon,cquoff))
                        Move(rp,72l,22l),Text(rp,qu[qua],7l);
                     break;
                  case ENHA:
                     if (toggle_gadget(&enh,cenon,cenoff))
                        Move(rp,104l,34l),Text(rp,st[enh],3l);
                     break;
                  case ITAL:
                     if (toggle_gadget(&ita,citon,citoff))
                        Move(rp,104l,46l),Text(rp,st[ita],3l);
                     break;
                  case UNDE:
                     if (toggle_gadget(&und,cunon,cunoff))
                        Move(rp,104l,58l),Text(rp,st[und],3l);
                     break;
                  case USER:
                     if (toggle_gadget(&use,cuson,cusoff))
                        Move(rp,104l,70l),Text(rp,st[use],3l);
                     if (prclosed==0) fflush(printer);
                     break;
                  case DOUB:
                     if (toggle_gadget(&dou,cdoon,cdooff))
                        Move(rp,288l,34l),Text(rp,st[dou],3l);
                     break;
                  case RESE:
                     er=send_out(&crese[1],crese[0]);
                     if (er) print_error(er);
                     else { init_w(),qua=1,enh=0,ita=0,und=0,use=0,pri=0;
                            dou=0,hor=0,ver=0,spe=0; }
                     if (prclosed==0) fflush(printer);
                     break;
                  case PRIN:
                     pri=(pri+1)%5;
                     switch (pri)
                     {
                        case 0:
                           if(change_width(cpr10,"10 cpi")==0)
                              pri=(pri+4)%5;
                           break;
                        case 1:
                           if(change_width(cpr12,"12 cpi")==0)
                              pri=(pri+4)%5;
                           break;
                        case 2:
                           if(change_width(cpr15,"15 cpi")==0)
                              pri=(pri+4)%5;
                           break;
                        case 3:
                           if(change_width(cpr17,"17 cpi")==0)
                              pri=(pri+4)%5;
                           break;
                        case 4:
                           if(change_width(cpr20,"20 cpi")==0)
                              pri=(pri+4)%5;
                           break;
                     }
                     break;
                  case HORI:
                     er=send_out(&chori[1],chori[0]);
                     if (er) { print_error(er);
                               break;
                             }
                     hor=(hor+1)%3;
                     switch (hor)
                     {
                        case 0:
                           er=send_out(ctrl,1);
                           if (er) print_error(2);
                           else Move(rp,304l,46l),Text(rp,"0",1l);
                           break;
                        case 1:
                           er=send_out(&ctrl[2],1);
                           if (er) print_error(2);
                           else Move(rp,304l,46l),Text(rp,"1",1l);
                           break;
                        case 2:
                           er=send_out(&ctrl[4],1);
                           if (er) print_error(2);
                           else Move(rp,304l,46l),Text(rp,"2",1l);
                           break;
                     }
                     break;
                  case VERT:
                     er=send_out(&cvert[1],cvert[0]);
                     if (er) { print_error(er);
                               break;
                             }
                     ver=1-ver;
                     if(ver==0) {
                        er=send_out(ctrl,1);
                        if (er) print_error(2);
                        else Move(rp,304l,58l),Text(rp,"0",1l);
                     }
                     else {
                        er=send_out(&ctrl[2],1);
                        if (er) print_error(2);
                        else Move(rp,304l,58l),Text(rp,"1",1l);
                     }
                     break;
                  case SPEC:
                     spe=(1+spe)%3;
                     switch (spe)
                     {
                        case 0:
                           er=send_out(&cspoff[1],cspoff[0]);
                           if (er) print_error(er),spe=(spe+2)%3;
                           else Move(rp,224l,70l),Text(rp,sp[spe],11l);
                           break;
                        case 1:
                           er=send_out(&csuper[1],csuper[0]);
                           if (er) print_error(er),spe=(spe+2)%3;
                           else Move(rp,224l,70l),Text(rp,sp[spe],11l);
                           break;
                        case 2:
                           er=send_out(&csub[1],csub[0]);
                           if (er) print_error(er),spe=(spe+2)%3;
                           else Move(rp,224l,70l),Text(rp,sp[spe],11l);
                           break;
                     }
                     break;
                  case STYL:
                     send_longint(cstyl,stylbuf);
                     break;
                  case LMAR:
                     send_longint(clmar,lmarbuf);
                     break;
                  case RMAR:
                     send_longint(crmar,rmarbuf);
                     break;
                  case LINE:
                     send_longint(cline,linebuf);
                     break;
                  case FEED:
                     cha=check_value(feedbuf);
                     if (cha==-1) { print_error(1);
                                    break;
                                  }
                     for (i=1;i<=(int)cha;i++)
                     {
                        er=send_out(&cfeed[1],cfeed[0]);
                        if (er) { print_error(er);
                               break;
                             }
                     }
                     if (prclosed==0) fflush(printer);
                     break;
                  case SEND:
                     er=hex_to_char(hexbuf);
                     if (er) print_error(er);
                     if (prclosed==0) fflush(printer);
                     break;
                  case OK:
                     i=0;
                     while (textbuf[i]) i++;
                     er=send_out(textbuf,(char)i);
                     if (er) print_error(er);
                     send_out(&cfeed[1],2);
                     if (prclosed==0) fflush(printer);
                     break;
                  case CLR:
                     for(i=0;i<80;i++) textbuf[i]=0;
                     RefreshGadgets(&gTEXT,MyWindow,NULL);
                     break;
                  case CLOS:
                     clo=1-clo;
                     if (clo) fclose(printer),prclosed=1;
                     else
                     {
                        while(open_par());
                        prclosed=0;
                     }
                     Move(rp,196l,130l),Text(rp,st[1-clo],3l);
                     break;
                  default:
                     break;
               }
               break;
            default:
               break;
         }
         ReplyMsg(msg);
      }
   }
}
