/* * Drucker Accessory * * - Druckeranpassung entsprechend PRINTER.DOT * - Druckvorgang geschieht im Hintergrund * - Druckparameter (Standardeinstellung in PRINTER.RSC) * Anzahl auszudruckender Zeilen pro Seite * Zeilenabstand n (n/72 inch) * Tabulator */ #include #include #include #include "printer.h" #define byte unsigned char #define BUFLEN 16000 int gl_apid; int menu_id; int msg[8]; /* Ereignispuffer */ int active; /* Druck in Arbeit ? */ byte *buffer; /* Eingabepuffer */ long buf_size; /* Groesse des Puffers */ long contents; /* Inhalt des Puffers */ long file_size; /* restliche Dateilaenge */ int fh; /* File handle */ char path[64]; /* Dateiname */ int line = 1; /* aktuelle Druckzeile */ int page; /* Zeilen pro Seite */ int spacing; /* Zeilenabstand */ int tabs; /* Tabulator Einstellung */ int final_ff; /* Formfeed am Ende */ char *no_memory, *open_error, *interrupt; OBJECT *form; char *_line; resources () { no_memory = "[2][Not enough memory available ... ][ Ok ]"; open_error = "[3][Can't open specified file ... ][ Cancel ]"; interrupt = "[1][The program is already active !][ Ok | Cancel ]"; if (!rsrc_load ("PRINTER.RSC")) { page = 58; spacing = 12; tabs = 8; return; } rsrc_gaddr (R_TREE, LAYOUT, &form); _line = ((TEDINFO*)(form+L_INF)->ob_spec)->te_ptext; final_ff = (form+F_FF)->ob_state & CHECKED; page = atoi (((TEDINFO*)(form+P_INF)->ob_spec)->te_ptext); spacing = atoi (((TEDINFO*)(form+S_INF)->ob_spec)->te_ptext); tabs = atoi (((TEDINFO*)(form+T_INF)->ob_spec)->te_ptext); } /* * Konvertierungstabelle einlesen */ int *convert; /* -> Tabelle von Zeigern auf code_table */ byte *code_table; /* Ersetzungszeichen */ read_tab () { register int fh; register long size; if ((fh = Fopen ("printer.dot", 0)) < 0) return; if (convert = (int*) Malloc (size = Fseek (0L, fh, 2))) { code_table = (byte*)(convert + 256); Fseek (0L, fh, 0); Fread (fh, size, convert); } else form_alert (1, no_memory); Fclose (fh); } /* * H a u p t p r o g r a m m */ main () { appl_init(); resources(); read_tab(); menu_id = menu_register (gl_apid, " Print File"); while (TRUE) { evnt_mesag (msg); if (msg[0] == AC_OPEN && msg[4] == menu_id) read_file (); } } /* * Auszudruckende Datei einlesen */ read_file () { if (! file_select (path, "*.*")) /* Cancel ? */ return; if ((fh = Fopen (path, 0)) < 0) { form_alert (1, open_error); return; } file_size = Fseek (0L, fh, 2); buf_size = file_size < BUFLEN ? file_size : BUFLEN; while (!(buffer = (byte*) Malloc (buf_size))) if ((buf_size = (long) Malloc (-1L)) < 200) { form_alert (1, no_memory); Fclose (fh); return; } Fseek (0L, fh, 0); contents = 0; /* Puffer ist noch leer */ accessory(); Fclose (fh); } /* * accessory */ accessory () { layout(); if (active) { out (0x1B); out ('A'); out (spacing); /* Set line spacing */ out (0x1B); out ('2'); print_file (); } Mfree (buffer); } /* * Objekt - Darstellung */ int _x, _y, _w, _h; center (tree) OBJECT *tree; { form_center (tree, &_x, &_y, &_w, &_h); } dial (i) int i; { form_dial (i, 0,0,0,0, _x,_y,_w,_h); } draw (tree, index) OBJECT *tree; int index; { objc_draw (tree, index, 9, _x,_y,_w,_h); } change (tree, index, state) OBJECT *tree; int index, state; { objc_change (tree, index, 0, _x,_y,_w,_h, state, 1); } /* * Layout bestimmen */ layout () { register OBJECT *obj; register int *value; register int index, n; register int exit = FALSE; n = active ? HIDETREE : SELECTABLE | EXIT; active = TRUE; /* Druckjob wird gestartet */ if (!(obj = form)) return (FALSE); /* kein Resource File vorhanden */ itoa (line, _line); (obj+L_LF)->ob_flags = n; (obj+L_FF)->ob_flags = n; center (obj); wind_update (BEG_UPDATE); dial (0); draw (obj, 0); while (!exit) { n = 1; switch (index = form_do (obj, 0)) { case CANCEL : active = FALSE; case PRINT : exit = TRUE; (obj+index)->ob_state = NORMAL; break; case L_LF : change (obj, L_LF, NORMAL); if (!Bcostat(0)) break; if (line++ < page) { prt_char ('\r'); prt_char ('\n'); goto L_draw; } case L_FF : change (obj, L_FF, NORMAL); if (!Bcostat(0)) break; line = 1; prt_char ('\f'); L_draw : itoa (line, _line); draw (obj, L_INF); break; case F_FF : (obj+F_FF)->ob_state = final_ff ^= CHECKED; draw (obj, F_FF); break; case P_DOWN : n = -1; case P_UP : value = &page; index = P_INF; goto set_value; case S_DOWN : n = -1; case S_UP : value = &spacing; index = S_INF; goto set_value; case T_DOWN : n = -1; case T_UP : value = &tabs; index = T_INF; set_value : n += *value; if (n < 1 || n > 99) break; *value = n; itoa (n, ((TEDINFO*)(obj+index)->ob_spec)->te_ptext); draw (obj, index); break; } } dial (3); wind_update (END_UPDATE); return (TRUE); } /* * In den Eingabepuffer einlesen */ read_buffer () { contents = buf_size < file_size ? buf_size : file_size; Fread (fh, contents, buffer); } /* * Datei ausdrucken */ print_file () { register byte *s = buffer; register int next_tab = 0; register int c; while (active) { if (--contents < 0) { /* Puffer leer ? */ if (file_size <= 0) break; /* Datei ist leer */ read_buffer(); s = buffer; continue; } c = *s++; /* Naechstes Zeichen */ file_size--; if (--next_tab <= 0) next_tab = tabs; if (c == '\t') { /* Tabulator */ do prt_char (' '); while (--next_tab > 0); continue; } if (c == '\n') { /* Neue Zeile */ line++; next_tab = 0; if (line > page) c = '\f'; } if (c == '\f') { /* Seitenvorschub */ line = 1; next_tab = 0; } prt_char (c); } if (final_ff && active && c != '\f') prt_char ('\f'); active = FALSE; } /* * Ein Zeichen ausgeben (eventuell Konvertierung) */ prt_char (c) int c; { register byte *code; register int k; if (!convert || (k = convert[c]) < 0) { out (c); /* keine Konvertierung */ return; } code = code_table + k; k = *code++; while (--k > 0) out (*code++); /* Ausgabe der Ersatzzeichen */ } /* * Ein Byte ausdrucken */ out (c) int c; { int n = 0; while (active) { if (Bcostat(0)) { /* Drucker bereit */ Cprnout (c); return; } if (n < 10) n++; else pause (); } } /* * Pause einlegen */ pause () { int event, ret; event = evnt_multi (MU_MESAG | MU_TIMER, 0,0,0, 0,0,0,0,0, 0,0,0,0,0, msg, 0, 0, &ret, &ret, &ret, &ret, &ret, &ret); if (event & MU_MESAG && msg[0] == AC_OPEN && msg[4] == menu_id) if (!layout() && form_alert (1, interrupt) == 2) active = FALSE; }