It seems I missed a directory when doing the __FreeBSD__ -> __DragonFly__
[dragonfly.git] / usr.sbin / pcvt / fontedit / fontedit.c
1 /*
2  * fontedit
3  *      Fonteditor for VT220
4  *
5  *  BUGS:
6  *      o Cursor motion is less than optimal (but who cares at 9600),
7  *
8  *  COMPILE:
9  *      cc -O fontedit.c -o fontedit
10  *      (use Makefile)
11  *
12  *      Copyright (c) 1987 by Greg Franks.
13  *
14  *      Permission is granted to do anything you want with this program
15  *      except claim that you wrote it.
16  *
17  *
18  *      REVISION HISTORY:
19  *
20  *      Nov 21, 1987 - Fixed man page to say "Fontedit" instead of "Top"
21  *      Nov 22, 1987 - Added BSD Compatible ioctl, turned cursor on/off
22  *                     - eap@bucsf.bu.edu
23  *
24  * $DragonFly: src/usr.sbin/pcvt/fontedit/Attic/fontedit.c,v 1.2 2004/02/10 02:59:42 rob Exp $
25  */
26
27 void clear_screen();
28 #include <stdio.h>
29 #ifdef SYSV
30 #include <sys/termio.h>
31 #endif SYSV
32 #ifdef BSD
33 #include <sys/ioctl.h>
34 #endif BSD
35 #if defined (__NetBSD__) || defined (__DragonFly__)
36 #include <sys/termios.h>
37 #include <sys/ioctl.h>
38 #endif /* __NetBSD__ || __DragonFly__ */
39 #include <signal.h>
40
41 #ifdef CURFIX
42 #define CURSORON  "\033[?25h"
43 #define CURSOROFF "\033[?25l"
44 #endif CURFIX
45
46 #define MAX_ROWS        10
47 #define MAX_COLS        8
48
49 typedef enum { false, true } bool;
50
51 #define KEY_FIND        0x0100
52 #define KEY_INSERT      0x0101
53 #define KEY_REMOVE      0x0102
54 #define KEY_SELECT      0x0103
55 #define KEY_PREV        0x0104
56 #define KEY_NEXT        0x0105
57 #define KEY_F6          0X0106
58 #define KEY_F7          0x0107
59 #define KEY_F8          0x0108
60 #define KEY_F9          0x0109
61 #define KEY_F10         0x010a
62 #define KEY_F11         0x010b
63 #define KEY_F12         0x010c
64 #define KEY_F13         0x010d
65 #define KEY_F14         0x010e
66 #define KEY_HELP        0x010f
67 #define KEY_DO          0x0110
68 #define KEY_F17         0x0111
69 #define KEY_F18         0x0112
70 #define KEY_F19         0x0113
71 #define KEY_F20         0x0114
72 #define KEY_UP          0x0115
73 #define KEY_DOWN        0x0116
74 #define KEY_RIGHT       0x0117
75 #define KEY_LEFT        0x0118
76
77 /*
78  * Position of main drawing screen.
79  */
80
81 #define ROW_OFFSET      3
82 #define COL_OFFSET      10
83
84 /*
85  * Position of the DRCS table.
86  */
87
88 #define TABLE_ROW       4
89 #define TABLE_COL       50
90
91 /*
92  *
93  */
94
95 #define ERROR_ROW       20
96 #define ERROR_COL       40
97
98 bool    display_table[MAX_ROWS][MAX_COLS];
99
100 #define TOTAL_ENTRIES   (128 - 32)
101 #define SIXELS_PER_CHAR 16
102
103 char    font_table[TOTAL_ENTRIES][SIXELS_PER_CHAR];
104 unsigned int    current_entry;
105
106 #ifdef SYSV
107 struct termio old_stty, new_stty;
108 #endif SYSV
109 #ifdef BSD
110 struct sgttyb old_stty, new_stty;
111 #endif BSD
112 #if defined (__NetBSD__) || defined (__DragonFly__)
113 struct termios old_stty, new_stty;
114 #endif /* __NetBSD__ || __DragonFly__ */
115 FILE * font_file = (FILE *)0;
116
117
118 /*
119  * Interrupt
120  *      Exit gracefully.
121  */
122
123 interrupt()
124 {
125         void clear_screen();
126 #ifdef CURFIX
127         printf("%s\n",CURSORON);
128 #endif CURFIX
129 #ifdef SYSV
130         ioctl( 0, TCSETA, &old_stty );
131 #endif SYSV
132 #ifdef BSD
133         ioctl( 0, TIOCSETP, &old_stty );
134 #endif BSD
135 #if defined (__NetBSD__) || defined (__DragonFly__)
136         ioctl( 0, TIOCSETA, &old_stty );
137 #endif /* __NetBSD__ || __DragonFly__ */
138         clear_screen();
139         exit( 0 );
140 }
141
142
143 /*
144  * Main
145  *      Grab input/output file and call main command processor.
146  */
147
148 main( argc, argv )
149 int argc;
150 char *argv[];
151 {
152         void command(), init_restore(), clear_screen();
153         void save_table(), get_table(), extract_entry();
154
155         if ( argc != 2 ) {
156                 fprintf( stderr, "usage: fontedit filename\n" );
157                 exit( 1 );
158         }
159
160         printf( "Press HELP for help\n" );
161         printf( "\033P1;1;2{ @\033\\" );        /* Clear font buffer    */
162         fflush( stdout );
163         sleep( 1 );                     /* Let terminal catch up        */
164                                         /* otherwise we get frogs       */
165
166         if ( ( font_file = fopen( argv[1], "r" ) ) == (FILE *)0 ) {
167                 if ( ( font_file = fopen( argv[1], "w" ) ) == (FILE *)0 ) {
168                         fprintf( stderr, "Cannot create file %s \n", argv[1] );
169                         exit( 1 );
170                 }
171         }
172         fclose( font_file );
173
174         if ( ( font_file = fopen( argv[1], "r" ) ) != (FILE *)0 ) {
175                 get_table( font_file );
176                 fclose( font_file );
177         }
178
179         if ( ( font_file = fopen( argv[1], "r+" ) ) == (FILE *)0 ) {
180                 fprintf( stderr, "Cannot open %s for writing\n", argv[1] );
181                 exit( 1 );
182         }
183 #ifdef CURFIX
184         printf("%s\n",CURSOROFF);
185 #endif CURFIX
186 #ifdef SYSV
187         ioctl( 0, TCGETA, &old_stty );
188 #endif SYSV
189 #ifdef BSD
190         ioctl( 0, TIOCGETP, &old_stty );
191 #endif BSD
192 #if defined (__NetBSD__) || defined (__DragonFly__)
193         ioctl( 0, TIOCGETA, &old_stty );
194 #endif /* __NetBSD__ || __DragonFly__ */
195         signal( SIGINT, (void *) interrupt );
196         new_stty = old_stty;
197 #ifdef SYSV
198         new_stty.c_lflag &= ~ICANON;
199         new_stty.c_cc[VMIN] = 1;
200         ioctl( 0, TCSETA, &new_stty );
201 #endif SYSV
202 #if defined (__NetBSD__) || defined (__DragonFly__)
203         new_stty.c_lflag &= ~ICANON;
204         new_stty.c_lflag &= ~ECHO;
205         new_stty.c_cc[VMIN] = 1;
206         ioctl( 0, TIOCSETA, &new_stty );
207 #endif /* __NetBSD__ || __DragonFly__ */
208 #ifdef BSD
209         new_stty.sg_flags |= CBREAK;
210         new_stty.sg_flags &= ~ECHO;
211         ioctl( 0, TIOCSETP, &new_stty );
212 #endif BSD
213         current_entry = 1;
214         extract_entry( current_entry );
215         init_restore();
216         command();
217 #ifdef SYSV
218         ioctl( 0, TCSETA, &old_stty );
219 #endif SYSV
220 #ifdef BSD
221         ioctl( 0, TIOCSETP, &old_stty );
222 #endif BSD
223 #if defined (__NetBSD__) || defined (__DragonFly__)
224         ioctl( 0, TIOCSETA, &old_stty );
225 #endif /* __NetBSD__ || __DragonFly__ */
226         clear_screen();
227
228         /* Overwrite the old file. */
229
230         fseek( font_file, 0L, 0 );
231         save_table( font_file );
232         fclose( font_file );
233 #ifdef CURFIX
234         printf("%s\n",CURSORON);
235 #endif CURFIX
236 }
237
238
239
240 /*
241  * Command
242  *      Process a function key.
243  *
244  *      The user cannot fill in slots 0 or 95 (space and del respecitively).
245  */
246
247 void
248 command()
249 {
250         register int c;
251         register int row, col;
252         register int i, j;
253         bool change, error, override;
254
255         void build_entry(), extract_entry(), send_entry(), print_entry();
256         void highlight(), draw_current(), init_restore(), help();
257         void warning();
258
259         change = false;
260         error = false;
261         override = false;
262         row = 0; col = 0;
263         highlight( row, col, true );
264
265         for ( ;; ) {
266                 c = get_key();
267                 highlight( row, col, false );   /* turn cursor off      */
268
269                 if ( error ) {
270                         move ( ERROR_ROW, ERROR_COL );
271                         printf( "\033[K" );             /* Clear error message  */
272                         move ( ERROR_ROW+1, ERROR_COL );
273                         printf( "\033[K" );             /* Clear error message  */
274                         error = false;
275                 } else {
276                         override = false;
277                 }
278
279                 switch ( c ) {
280
281                 case KEY_FIND:          /* update DRCS  */
282                         if ( !change && !override ) {
283                                 warning( "No changes to save" );
284                                 override = true;
285                                 error = true;
286                         } else {
287                                 build_entry( current_entry );
288                                 send_entry( current_entry );
289                                 print_entry( current_entry, true );
290                                 change = false;
291                         }
292                         break;
293
294                 case KEY_F6:            /* Turn on pixel        */
295                         change = true;
296                         display_table[row][col] = true;
297                         highlight( row, col, false );
298                         col = ( col + 1 ) % MAX_COLS;
299                         if ( col == 0 )
300                                 row = ( row + 1 ) % MAX_ROWS;
301                         break;
302
303                 case KEY_F7:            /* Turn off pixel       */
304                         change = true;
305                         display_table[row][col] = false;
306                         highlight( row, col, false );
307                         col = ( col + 1 ) % MAX_COLS;
308                         if ( col == 0 )
309                                 row = ( row + 1 ) % MAX_ROWS;
310                         break;
311
312                 case KEY_INSERT:        /* Insert a blank row   */
313                         change = true;
314                         for ( j = 0; j < MAX_COLS; ++j ) {
315                                 for ( i = MAX_ROWS - 1; i > row; --i ) {
316                                         display_table[i][j] = display_table[i-1][j];
317                                 }
318                                 display_table[row][j] = false;
319                         }
320                         draw_current();
321                         break;
322
323                 case KEY_REMOVE:        /* Remove a row */
324                         change = true;
325                         for ( j = 0; j < MAX_COLS; ++j ) {
326                                 for ( i = row; i < MAX_ROWS - 1; ++i ) {
327                                         display_table[i][j] = display_table[i+1][j];
328                                 }
329                                 display_table[MAX_ROWS-1][j] = false;
330                         }
331                         draw_current();
332                         break;
333
334                 case KEY_F13:           /* Clear buffer */
335                         if ( change && !override ) {
336                                 warning( "Changes not saved" );
337                                 error = true;
338                                 override = true;
339                         } else {
340                                 for ( j = 0; j < MAX_COLS; ++j ) {
341                                         for ( i = 0; i < MAX_ROWS; ++i ) {
342                                                 display_table[i][j] = false;
343                                         }
344                                 }
345                                 draw_current();
346                         }
347                         break;
348
349                 case KEY_SELECT:        /* Select font from DRCS        */
350                         if ( change && !override ) {
351                                 warning( "Changes not saved" );
352                                 error = true;
353                                 override = true;
354                         } else {
355                                 extract_entry( current_entry );
356                                 draw_current();
357                         }
358                         break;
359
360                 case KEY_PREV:          /* Move to prev entry in DRCS   */
361                         if ( change && !override ) {
362                                 warning( "Changes not saved" );
363                                 override = true;
364                                 error = true;
365                         } else {
366                                 print_entry( current_entry, false );
367                                 current_entry = current_entry - 1;
368                                 if ( current_entry == 0 )
369                                         current_entry = TOTAL_ENTRIES - 2;
370                                 print_entry( current_entry, true );
371                         }
372                         break;
373
374                 case KEY_NEXT:          /* Move to next entry in DRCS   */
375                         if ( change && !override ) {
376                                 warning( "Changes not saved" );
377                                 override = true;
378                                 error = true;
379                         } else {
380                                 print_entry( current_entry, false );
381                                 current_entry = current_entry + 1;
382                                 if ( current_entry  == TOTAL_ENTRIES - 1 )
383                                         current_entry = 1;
384                                 print_entry( current_entry, true );
385                         }
386                         break;
387
388                 case KEY_UP:            /* UP one row.                  */
389                         if ( row == 0 )
390                                 row = MAX_ROWS;
391                         row = row - 1;
392                         break;
393
394                 case KEY_DOWN:          /* Guess.                       */
395                         row = ( row + 1 ) % MAX_ROWS;
396                         break;
397
398                 case KEY_RIGHT:
399                         col = ( col + 1 ) % MAX_COLS;
400                         break;
401
402                 case KEY_LEFT:
403                         if ( col == 0 )
404                                 col = MAX_COLS;
405                         col = col - 1;
406                         break;
407
408                 case KEY_HELP:          /* Display helpful info         */
409                         clear_screen();
410                         help();
411                         c = getchar();
412                         init_restore();
413                         break;
414
415                 case '\004':            /* All done!                    */
416                         return;
417
418                 case '\f':              /* Redraw display               */
419                         init_restore();
420                         break;
421
422                 default:                /* user is a klutzy  typist     */
423                         move ( ERROR_ROW, ERROR_COL );
424                         printf( "Unknown key: " );
425                         if ( c < 0x20 ) {
426                                 printf( "^%c", c );
427                         } else if ( c < 0x0100 ) {
428                                 printf( "%c", c );
429                         } else {
430                                 printf( "0x%04x", c );
431                         }
432                         fflush( stdout );
433                         error = true;
434                 }
435
436                 highlight( row, col, true );    /* turn cursor on       */
437         }
438 }
439
440
441
442 char *key_table[]       = {
443         "\033[1~",              /* Find         */
444         "\033[2~",              /* Insert       */
445         "\033[3~",              /* Remove       */
446         "\033[4~",              /* Select       */
447         "\033[5~",              /* Prev         */
448         "\033[6~",              /* Next         */
449         "\033[17~",
450         "\033[18~",
451         "\033[19~",
452         "\033[20~",
453         "\033[21~",
454         "\033[23~",
455         "\033[24~",
456         "\033[25~",
457         "\033[26~",
458         "\033[28~",
459         "\033[29~",
460         "\033[31~",
461         "\033[32~",
462         "\033[33~",
463         "\033[34~",
464         "\033[A",
465         "\033[B",
466         "\033[C",
467         "\033[D",
468         (char *)0 };
469
470 /*
471  * get_key
472  *      Convert VT220 escape sequence into something more reasonable.
473  */
474
475 int
476 get_key()
477 {
478         register char   *p;
479         char    s[10];
480         register int i, j;
481
482         p = s;
483         for ( i = 0; i < 10; ++i ) {
484                 *p = getchar();
485                 if ( i == 0 && *p != '\033' )
486                         return( (int)*p );      /* Not an escape sequence */
487                 if ( *p != '\033' && *p < 0x0020 )
488                         return( (int)*p );      /* Control character    */
489                 *++p = '\0';                    /* Null terminate       */
490                 for ( j = 0; key_table[j]; ++j ) {
491                         if ( strcmp( s, key_table[j] ) == 0 ) {
492                                 return( j | 0x0100 );
493                             }
494                 }
495         }
496         return( -1 );
497 }
498
499
500
501 /*
502  * pad
503  *      Emit nulls so that the terminal can catch up.
504  */
505
506 pad()
507 {
508         int i;
509
510         for ( i = 0; i < 20; ++i )
511                 putchar( '\000' );
512         fflush( stdout );
513 }
514
515
516
517 /*
518  * init_restore
519  *      refresh the main display table.
520  */
521
522 void
523 init_restore()
524 {
525         register int row, col;
526         register int i;
527
528         void  draw_current(), clear_screen(), print_entry();
529
530         clear_screen();
531
532         for ( col = 0; col < MAX_COLS; ++col ) {
533                 move( ROW_OFFSET - 2, col * 3 + COL_OFFSET + 1 );
534                 printf( "%d", col );
535         }
536         move( ROW_OFFSET - 1, COL_OFFSET );
537         printf( "+--+--+--+--+--+--+--+--+" );
538         move( ROW_OFFSET + MAX_ROWS * 2, COL_OFFSET );
539         printf( "+--+--+--+--+--+--+--+--+" );
540
541         for ( row = 0; row < MAX_ROWS; ++row ) {
542                 if ( row != 0 && row != 7 )  {
543                         move( row * 2 + ROW_OFFSET, COL_OFFSET - 2 );
544                         printf( "%d|", row );
545                         move( row * 2 + ROW_OFFSET + 1, COL_OFFSET - 1 );
546                         printf( "|" );
547                         move( row * 2 + ROW_OFFSET, COL_OFFSET + MAX_COLS * 3 );
548                         printf( "|" );
549                         move( row * 2 + ROW_OFFSET + 1, COL_OFFSET + MAX_COLS * 3 );
550                         printf( "|" );
551                 } else {
552                         move( row * 2 + ROW_OFFSET, COL_OFFSET - 2 );
553                         printf( "%d*", row );
554                         move( row * 2 + ROW_OFFSET + 1, COL_OFFSET - 1 );
555                         printf( "*" );
556                         move( row * 2 + ROW_OFFSET, COL_OFFSET + MAX_COLS * 3 );
557                         printf( "*" );
558                         move( row * 2 + ROW_OFFSET + 1, COL_OFFSET + MAX_COLS * 3 );
559                         printf( "*" );
560                 }
561         }
562         draw_current();
563
564         move( TABLE_ROW - 1, TABLE_COL - 1 );
565         printf( "+-+-+-+-+-+-+-+-+-+-+-+-+" );
566         move( TABLE_ROW + 8 * 2 - 1, TABLE_COL - 1 );
567         printf( "+-+-+-+-+-+-+-+-+-+-+-+-+" );
568         for ( i = 0; i < 8; ++i ) {
569                 move ( TABLE_ROW + i * 2, TABLE_COL - 1 );
570                 printf( "|" );
571                 move ( TABLE_ROW + i * 2 + 1, TABLE_COL - 1 );
572                 printf( "+" );
573                 move ( TABLE_ROW + i * 2, TABLE_COL + 12 * 2 - 1);
574                 printf( "|" );
575                 move ( TABLE_ROW + i * 2 + 1, TABLE_COL +12 * 2 - 1);
576                 printf( "+" );
577         }
578         for ( i = 0; i < TOTAL_ENTRIES; ++i )
579                 print_entry( i, (i == current_entry) ? true : false );
580 }
581
582
583
584 /*
585  * draw_current
586  *      Draw the complete current entry.
587  */
588
589 void
590 draw_current()
591 {
592         register int row, col;
593
594         printf( "\033)0" );             /* Special graphics in G1       */
595         printf( "\016" );               /* Lock in G1 (SO)              */
596
597         for ( row = 0; row < MAX_ROWS; ++row ) {
598                 for ( col = 0; col < MAX_COLS; ++col ) {
599                         if ( display_table[row][col] ) {
600                                 move( row * 2 + ROW_OFFSET,     col * 3 + COL_OFFSET );
601                                 printf( "\141\141\141" );
602                                 move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET );
603                                 printf( "\141\141\141" );
604                         } else {
605                                 move( row * 2 + ROW_OFFSET,     col * 3 + COL_OFFSET );
606                                 printf( "   " );        /* erase splat  */
607                                 move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET );
608                                 printf( "   " );        /* erase splat  */
609                         }
610                 }
611                 pad();
612         }
613         printf( "\017" );               /* Lock in G0 (SI)      */
614         fflush( stdout );
615 }
616
617
618
619 /*
620  * highlight
621  *      Draw the cursor in the main display area.
622  */
623
624 void
625 highlight( row, col, on )
626 unsigned int row, col;
627 bool on;
628 {
629
630         printf( "\033)0" );             /* Special graphics in G1       */
631         printf( "\016" );               /* Lock in G1 (SO)              */
632         if ( on ) {
633                 printf( "\033[7m" );    /* Reverse video cursor         */
634         }
635
636         if ( display_table[row][col] ) {
637                 move( row * 2 + ROW_OFFSET,     col * 3 + COL_OFFSET );
638                 printf( "\141\141\141" );
639                 move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET );
640                 printf( "\141\141\141" );
641         } else {
642                 move( row * 2 + ROW_OFFSET,     col * 3 + COL_OFFSET );
643                 printf( "   " );        /* erase splat  */
644                 move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET );
645                 printf( "   " );        /* erase splat  */
646         }
647         pad();
648         printf( "\017" );               /* Lock in G0 (SI)      */
649         printf( "\033[0m" );            /* normal video         */
650         printf( "\b" );                 /* Back up one spot     */
651         fflush( stdout );
652 }
653
654
655
656 /*
657  * Clear_screen
658  */
659
660 void
661 clear_screen()
662 {
663         printf( "\033[H\033[J" );               /* Clear screen.        */
664         fflush( stdout );
665 }
666
667
668
669 /*
670  * move
671  */
672
673 move( y, x )
674 int y, x;
675 {
676         printf( "\033[%d;%df", y, x );
677 }
678
679
680
681 /*
682  * Build_entry
683  *      Convert the bit pattern used in the main display area into something
684  *      that the vt220 can digest - namely sixels...
685  */
686
687 void
688 build_entry( entry_no )
689 unsigned int entry_no;
690 {
691         register int row, col;
692         register unsigned int mask;
693
694         for ( col = 0; col < 8; ++col ) {
695
696                 /* Top set of sixels    */
697
698                 mask = 0;
699                 for ( row = 5; row >= 0; --row ) {
700                         mask = mask << 1;
701                         if ( display_table[row][col] )
702                                 mask |= 1;
703                 }
704                 font_table[entry_no][col] = mask + 077;
705
706                 /*  Bottom set of sixels        */
707
708                 mask = 0;
709                 for ( row = 9; row >= 6; --row ) {
710                         mask = mask << 1;
711                         if ( display_table[row][col] )
712                                 mask |= 1;
713                 }
714                 font_table[entry_no][col+8] = mask + 077;
715         }
716
717 }
718
719
720
721 /*
722  * Extract_engry
723  *      convert sixel representation into an array of bits.
724  */
725
726 void
727 extract_entry( entry_no )
728 unsigned int entry_no;
729 {
730         register int row, col;
731         register unsigned int mask;
732
733         for ( col = 0; col < 8; ++col ) {
734
735                 /* Top set of sixels    */
736
737                 mask = font_table[entry_no][col];
738                 if ( mask >= 077 )
739                         mask -= 077;
740                 else
741                         mask = 0;               /* Bogus entry  */
742
743                 for ( row = 0; row <= 5; ++row ) {
744                         display_table[row][col] = (bool)(mask & 0x0001);
745                         mask = mask >> 1;
746                 }
747
748                 /*  Bottom set of sixels        */
749
750                 mask = font_table[entry_no][col+8];
751                 if ( mask >= 077 )
752                         mask -= 077;
753                 else
754                         mask = 0;
755
756                 for ( row = 6; row <= 9; ++row ) {
757                         display_table[row][col] = (bool)(mask & 0x0001);
758                         mask = mask >> 1;
759                 }
760         }
761
762 }
763
764
765
766 /*
767  * Send_entry
768  *      Emit the stuff used by the VT220 to load a character into the
769  *      DRCS.  We could, of course, send more than one entry at a time...
770  */
771
772 void
773 send_entry( entry_no )
774 int entry_no;
775 {
776         register char *fp       = font_table[entry_no];
777
778         printf( "\033P1;%d;1;0;0;0{ @%c%c%c%c%c%c%c%c/%c%c%c%c%c%c%c%c\033\\",
779                 entry_no,
780                 fp[ 0], fp[ 1], fp[ 2], fp[ 3], fp[ 4], fp[ 5], fp[ 6], fp[ 7],
781                 fp[ 8], fp[ 9], fp[10], fp[11], fp[12], fp[13], fp[14], fp[15] );
782 }
783
784
785
786 /*
787  * Print_entry
788  *      The terminal normally has G0 in GL.  We don't want to change
789  *      this, nor do we want to use GR.  Sooooo send out the necessary
790  *      magic for shifting in G2 temporarily for the character that we
791  *      want to display.
792  */
793
794 void
795 print_entry( entry_no, highlight )
796 register unsigned int entry_no;
797 bool highlight;
798 {
799
800         register int y, x;
801
802         y = entry_no & 0x07;
803         x = entry_no >> 3 & 0x1f;
804         entry_no += 32;                 /* Map up to G set      */
805
806         move( y * 2 + TABLE_ROW, x * 2 + TABLE_COL );
807
808         if ( highlight )
809                 printf( "\033[7m" );
810
811         printf( "\033* @" );            /* select DRCS into G2  */
812         printf( "\033N" );              /* select single shift  */
813         printf( "%c", entry_no );       /* Draw the character   */
814
815         if ( highlight )
816                 printf( "\033[0m" );
817 }
818
819
820
821 /*
822  * Save_table
823  *      Save a font table
824  */
825
826 void
827 save_table( font_file )
828 FILE *font_file;
829 {
830         register char *fp;
831         register int i;
832
833         for ( i = 0; i < TOTAL_ENTRIES; ++i ) {
834                 fp = font_table[i];
835                 fprintf( font_file, "\033P1;%d;1;0;0;0{ @%c%c%c%c%c%c%c%c/%c%c%c%c%c%c%c%c\033\\\n",
836                         i,
837                         fp[ 0], fp[ 1], fp[ 2], fp[ 3], fp[ 4], fp[ 5], fp[ 6], fp[ 7],
838                         fp[ 8], fp[ 9], fp[10], fp[11], fp[12], fp[13], fp[14], fp[15] );
839         }
840 }
841
842
843
844 /*
845  * Get_table
846  *      Extract font table entries from a file
847  */
848
849 void
850 get_table( font_file )
851 FILE *font_file;
852 {
853         char    s[256];
854         register char   *p;
855         char    *fp;
856         int i;
857         register int j;
858
859         while( fgets( s, 255, font_file ) ) {
860                 if ( strncmp( s, "\033P1;", 4 ) !=  0 )
861                         continue;       /* Bogus line   */
862                 p = &s[4];
863                 if ( sscanf( p, "%d", &i ) != 1 )
864                         continue;       /* Illegal entry number */
865
866                 if ( i <= 0 || TOTAL_ENTRIES <= i )
867                         continue;       /* Bogues entry */
868
869                 fp = font_table[i];
870
871                 while ( *p && *p != '@' )
872                         ++p;            /* Skip to font definition */
873                 if ( ! *p++ )
874                         continue;       /* Skip @       */
875
876                 for ( j = 0; *p && *p != '\033' && j < 16; ++j, ++p ) {
877                         if ( *p == '/' ) {
878                                 j = 8;
879                                 ++p;
880                         }
881                         fp[j] = *p;
882                 }
883                 send_entry( i );
884         }
885 }
886
887
888
889 /*
890  * Help
891  *      Print out help information.
892  */
893
894 void
895 help()
896 {
897         printf( "Font editor\n\n" );
898         printf( "F6     - Pixel on\n" );
899         printf( "F7     - Pixel off\n" );
900         printf( "F13    - Clear display area\n" );
901         printf( "HELP   - This screen\n" );
902         printf( "FIND   - Update font table\n" );
903         printf( "INSERT - Insert a blank row\n" );
904         printf( "REMOVE - Remove a row\n" );
905         printf( "SELECT - Select current font table entry\n" );
906         printf( "PREV   - Move to previous font table entry\n" );
907         printf( "NEXT   - Move to next font table entry\n" );
908         printf( "^D     - Exit\n" );
909         printf( "\n\n\n\nPress any key to continue\n" );
910 }
911
912
913
914 /*
915  * Warning
916  *      Issue a warning to the regarding the current status.
917  */
918
919 void
920 warning( s )
921 char *s;
922 {
923         move( ERROR_ROW, ERROR_COL );
924         printf( "Warning: %s!\n", s );
925         move( ERROR_ROW+1, ERROR_COL );
926         printf( "         Reissue command to override\n" );
927 }