OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [mw/] [src/] [demos/] [nanox/] [nxterm.c] - Blame information for rev 1765

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 673 markom
/*
2
 * nxterm - terminal emulator for Nano-X
3
 *
4
 * (C) 1994,95,96 by Torsten Scherer (TeSche)
5
 * itschere@techfak.uni-bielefeld.de
6
 *
7
 * - quite some changes for W1R1
8
 * - yet more changes for W1R2
9
 *
10
 * TeSche 01/96:
11
 * - supports W_ICON & W_CLOSE
12
 * - supports /etc/utmp logging for SunOS4 and Linux
13
 * - supports catching of console output for SunOS4
14
 * Phx 02-06/96:
15
 * - supports NetBSD-Amiga
16
 * Eero 11/97:
17
 * - unsetenv(DISPLAY), setenv(LINES, COLUMNS).
18
 * - Add new text modes (you need to use terminfo...).
19
 * Eero 2/98:
20
 * - Implemented fg/bgcolor setting.  With monochrome server it changes
21
 *   bgmode variable, which tells in which mode to draw to screen
22
 *   (M_CLEAR/M_DRAW) and affects F_REVERSE settings.
23
 * - Added a couple of checks.
24
 *
25
 * TODO:
26
 * - Allocate and set sensible window palette for fg/bg color setting.
27
 * - add scroll-region ('cs') command. Fairly many programs
28
 *   can take advantage of that.
29
 * - Add xterm like mouse event to terminfo key event conversion... :)
30
 * - check if current NetBSD really needs ifdefs below with
31
 *   current W server/library.
32
 */
33
#include <stdio.h>
34
#include <signal.h>
35
#include <sys/time.h>
36
#include <utmp.h>
37
#include <unistd.h>
38
#include <errno.h>
39
#include <stdlib.h>
40
#include <pwd.h>
41
#include <string.h>
42
#include <sys/ioctl.h>
43
#include <termios.h>
44
#include <sys/types.h>
45
#include <sys/stat.h>
46
#include <fcntl.h>
47
#define MWINCLUDECOLORS
48
#include "nano-X.h"
49
#include "nxterm.h"
50
 
51
#define TITLE   "nxterm"
52
 
53
#define SMALLBUFFER 80
54
#define LARGEBUFFER 1024
55
 
56
/*
57
 * some pty helper functions
58
 */
59
#ifdef linux
60
#define NSIG _NSIG
61
#endif
62
 
63
#ifdef __FreeBSD__
64
#include <libutil.h>
65
#endif
66
 
67
 
68
/*
69
 * some global variables
70
 */
71
 
72
static GR_WINDOW_ID     w1;     /* id for window */
73
static GR_GC_ID         gc1;    /* graphics context */
74
static GR_FONT_ID       regFont;
75
/*static GR_FONT_ID       boldFont;*/
76
 
77
static GR_SCREEN_INFO   si;     /* screen info */
78
static GR_FONT_INFO     fi;     /* Font Info */
79
static GR_WINDOW_INFO   wi;
80
static GR_GC_INFO       gi;
81
static GR_BOOL          havefocus = GR_FALSE;
82
 
83
static short winw, winh, pid, console;
84
static int pipeh;
85
static short cblink = 0, visualbell = 0, debug = 0;
86
#ifdef __FreeBSD__
87
static char pty[SMALLBUFFER];
88
static struct winsize winsz;
89
#endif
90
 
91
#define fonh fi.height
92
#define fonw fi.maxwidth
93
 
94
int term_init();
95
 
96
/****************************************************************************/
97
 
98
/*
99
 *
100
 */
101
 
102
/* static int isIconified; */
103
static int isMaximized=0;
104
 
105
void maximize(void)
106
{
107
    static short x0, y0, w, h, w_max,h_max;
108
 
109
    if (!isMaximized)
110
    {
111
 
112
        w_max=si.cols-wi.bordersize;
113
        h_max=si.rows-wi.bordersize;
114
        GrMoveWindow(w1,0,0);
115
        GrResizeWindow(w1,w_max, h_max);
116
        isMaximized=1;
117
    }
118
    else
119
    {
120
        GrResizeWindow(w1, w, h);
121
        GrMoveWindow(w1, x0, y0);
122
        isMaximized=0;
123
    }
124
}
125
 
126
 
127
/****************************************************************************/
128
 
129
 
130
/*
131
 * some common tool functions
132
 */
133
 
134
void sigpipe(int sig)
135
{
136
  /* this one musn't close the window */
137
/*  _write_utmp(pty, "", "", 0);  */
138
  kill(-pid, SIGHUP);
139
  _exit(sig);
140
}
141
 
142
 
143
void sigchld(int sig)
144
{
145
/*  _write_utmp(pty, "", "", 0);  */
146
  _exit(sig);
147
}
148
 
149
 
150
void sigquit(int sig)
151
{
152
  signal(sig, SIG_IGN);
153
  kill(-pid, SIGHUP);
154
}
155
 
156
 
157
/*
158
 * this is the wterm terminal code, almost like VT52
159
 */
160
 
161
short   bgmode, escstate, curx, cury, curon, curvis;
162
short   savx, savy, wrap, style;
163
short   col, row, colmask = 0x7f, rowmask = 0x7f;
164
 
165
/*
166
 * something to buffer plain text output
167
 */
168
 
169
short   sbufcnt = 0;
170
short   sbufx, sbufy;
171
char    lineBuffer[SMALLBUFFER+1];
172
char    *sbuf=lineBuffer;
173
 
174
void sflush(void)
175
{
176
    if (sbufcnt)
177
    {
178
        GrText(w1,gc1, sbufx*fonw, sbufy*fonh, sbuf, sbufcnt, GR_TFTOP);
179
        sbufcnt = 0;
180
    }
181
}
182
 
183
 
184
void lineRedraw(void)
185
{
186
    GrSetGCForeground(gc1,gi.background);
187
    GrFillRect(w1, gc1, curx*fonw, cury*fonh, (col-curx)*fonw, fonh);
188
    GrSetGCForeground(gc1,gi.foreground);
189
 
190
    if (sbufcnt)
191
    {
192
        sbuf[sbufcnt] = 0;
193
        GrText(w1,gc1, sbufx*fonw, sbufy*fonh, sbuf, sbufcnt, GR_TFTOP);
194
    }
195
}
196
 
197
void sadd (char c)
198
{
199
    if (sbufcnt == SMALLBUFFER)
200
    {
201
        sflush ();
202
    }
203
 
204
    if (!sbufcnt)
205
    {
206
        sbufx = curx;
207
        sbufy = cury;
208
    }
209
 
210
    sbuf[sbufcnt++] = c;
211
}
212
 
213
void show_cursor (void)
214
{
215
        GrSetGCMode(gc1,GR_MODE_XOR);
216
        GrSetGCForeground(gc1, WHITE);
217
        GrFillRect(w1, gc1, curx*fonw, cury*fonh+1, fonw, fonh-1);
218
        GrSetGCForeground(gc1, gi.foreground);
219
        GrSetGCMode(gc1,GR_MODE_COPY);
220
}
221
 
222
 
223
void draw_cursor (void)
224
{
225
    if (!curvis)
226
    {
227
        curvis = 1;
228
        show_cursor();
229
    }
230
}
231
void hide_cursor (void)
232
{
233
    if (curvis)
234
    {
235
        curvis = 0;
236
        show_cursor();
237
    }
238
}
239
 
240
 
241
void vscroll(int lines)
242
{
243
    hide_cursor();
244
    GrCopyArea(w1,gc1,0, 0, winw, winh-(lines*fonh),
245
               w1, 0, (lines*fonh), MWROP_SRCCOPY);
246
 
247
    GrSetGCForeground(gc1,gi.background);
248
    GrFillRect(w1, gc1, 0, winh-(lines*fonh),
249
               winw, (lines*fonh));
250
    GrSetGCForeground(gc1,gi.foreground);
251
}
252
 
253
void esc5(unsigned char c)      /* setting background color */
254
{
255
 
256
    GrSetGCBackground(gc1, c);
257
    GrGetGCInfo(gc1,&gi);
258
    escstate = 0;
259
}
260
 
261
void esc4(unsigned char c)      /* setting foreground color */
262
{
263
    GrSetGCForeground(gc1,c);
264
    GrGetGCInfo(gc1,&gi);
265
    escstate = 0;
266
}
267
 
268
void esc3(unsigned char c)      /* cursor position x axis */
269
{
270
    curx = (c - 32) & colmask;
271
    if (curx >= col)
272
        curx = col - 1;
273
    else if (curx < 0)
274
        curx = 0;
275
    escstate = 0;
276
}
277
 
278
 
279
void esc2(unsigned char c)      /* cursor position y axis */
280
{
281
  cury = (c - 32) & rowmask;
282
  if (cury >= row)
283
    cury = row - 1;
284
  else if (cury < 0)
285
    cury = 0;
286
  escstate = 3;
287
}
288
 
289
 
290
void esc1(unsigned char c)      /* various control codes */
291
{
292
    static int ReverseMode=0;
293
    escstate = 0;
294
 
295
    switch(c)
296
    {
297
    case 'A':/* cursor up */
298
        hide_cursor();
299
        if ((cury -= 1) < 0)
300
            cury = 0;
301
        break;
302
 
303
    case 'B':/* cursor down */
304
        hide_cursor();
305
        if ((cury += 1) >= row)
306
            cury = row - 1;
307
        break;
308
 
309
    case 'C':/* cursor right */
310
        hide_cursor();
311
        if ((curx += 1) >= col)
312
            curx = col - 1;
313
        break;
314
 
315
    case 'D':/* cursor left */
316
        hide_cursor();
317
        if ((curx -= 1) < 0)
318
            curx = 0;
319
        break;
320
 
321
    case 'E':/* clear screen & home */
322
        GrClearWindow(w1, 0);
323
        curx = 0;
324
        cury = 0;
325
        break;
326
 
327
    case 'H':/* cursor home */
328
        curx = 0;
329
        cury = 0;
330
        break;
331
 
332
    case 'I':/* reverse index */
333
        if ((cury -= 1) < 0)
334
        {
335
            cury = 0;
336
            vscroll(1);
337
        }
338
        break;
339
 
340
    case 'J':/* erase to end of page */
341
 
342
        if (cury < row-1)
343
        {
344
            GrSetGCForeground(gc1,gi.background);
345
            GrFillRect(w1,gc1, 0,(cury+1)*fonh, winw, (row-1-cury)*fonh);
346
            GrSetGCForeground(gc1,gi.foreground);
347
        }
348
        GrSetGCForeground(gc1,gi.background);
349
        GrFillRect(w1, gc1, curx*fonw, cury*fonh, (col-curx)*fonw, fonh);
350
        GrSetGCForeground(gc1,gi.foreground);
351
        break;
352
 
353
    case 'K':/* erase to end of line */
354
        GrSetGCForeground(gc1,gi.background);
355
        GrFillRect(w1, gc1, curx*fonw, cury*fonh, (col-curx)*fonw, fonh);
356
        GrSetGCForeground(gc1,gi.foreground);
357
        break;
358
 
359
    case 'L':/* insert line */
360
        if (cury < row-1)
361
        {
362
            vscroll(1);
363
        }
364
        curx = 0;
365
        break;
366
 
367
    case 'M':/* delete line */
368
        if (cury < row-1)
369
        {
370
            vscroll(1);
371
        }
372
        curx = 0;
373
        break;
374
 
375
    case 'Y':/* position cursor */
376
        escstate = 2;
377
        break;
378
 
379
    case 'b':/* set foreground color */
380
        escstate = 4;
381
        break;
382
 
383
    case 'c':/* set background color */
384
        escstate = 5;
385
        break;
386
 
387
    case 'd':/* erase beginning of display */
388
/*      w_setmode(win, bgmode); */
389
        if (cury > 0)
390
        {
391
            GrSetGCForeground(gc1,gi.background);
392
            GrFillRect(w1,gc1, 0, 0, winw, cury*fonh);
393
            GrSetGCForeground(gc1,gi.foreground);
394
        }
395
        if (curx > 0)
396
        {
397
            GrSetGCForeground(gc1,gi.background);
398
            GrFillRect(w1,gc1, 0, cury*fonh, curx*fonw, fonh);
399
            GrSetGCForeground(gc1,gi.foreground);
400
        }
401
        break;
402
 
403
    case 'e':/* enable cursor */
404
        curon = 1;
405
        break;
406
 
407
    case 'f':/* disable cursor */
408
        curon = 0;
409
        break;
410
 
411
    case 'j':/* save cursor position */
412
        savx = curx;
413
        savy = cury;
414
        break;
415
 
416
    case 'k':/* restore cursor position */
417
        curx = savx;
418
        cury = savy;
419
        break;
420
 
421
    case 'l':/* erase entire line */
422
        GrSetGCForeground(gc1,gi.background);
423
        GrRect(w1,gc1, 0, cury*fonh, winw, fonh);
424
        GrSetGCForeground(gc1,gi.foreground);
425
        curx = 0;
426
        break;
427
 
428
    case 'o':/* erase beginning of line */
429
        if (curx > 0)
430
        {
431
            GrSetGCForeground(gc1,gi.background);
432
            GrRect(w1,gc1,0, cury*fonh, curx*fonw, fonh);
433
            GrSetGCForeground(gc1,gi.foreground);
434
        }
435
        break;
436
 
437
    case 'p':/* enter reverse video mode */
438
    {
439
        if(!ReverseMode)
440
        {
441
            GrSetGCForeground(gc1,gi.background);
442
            GrSetGCBackground(gc1,gi.foreground);
443
            ReverseMode=1;
444
        }
445
    }
446
        break;
447
 
448
    case 'q':/* exit reverse video mode */
449
    {
450
        if(ReverseMode)
451
        {
452
            GrSetGCForeground(gc1,gi.foreground);
453
            GrSetGCBackground(gc1,gi.background);
454
            ReverseMode=0;
455
        }
456
    }
457
        break;
458
 
459
    case 'v':/* enable wrap at end of line */
460
        wrap = 1;
461
        break;
462
 
463
    case 'w':/* disable wrap at end of line */
464
        wrap = 0;
465
        break;
466
 
467
/* and these are the extentions not in VT52 */
468
 
469
    case 'G': /* clear all attributes */
470
        break;
471
 
472
    case 'g': /* enter bold mode */
473
/*      GrSetGCFont(gc1, boldFont); */
474
        break;
475
 
476
    case 'h': /* exit bold mode */
477
/*      GrSetGCFont(gc1, regFont); */
478
        break;
479
 
480
    case 'i': /* enter underline mode */
481
        break;
482
 
483
        /* j, k and l are already used */
484
 
485
    case 'm': /* exit underline mode */
486
        break;
487
 
488
/* these ones aren't yet on the termcap entries */
489
 
490
    case 'n': /* enter italic mode */
491
        break;
492
        /* o, p and q are already used */
493
 
494
    case 'r': /* exit italic mode */
495
        break;
496
 
497
    case 's': /* enter light mode */
498
        break;
499
 
500
    case 't': /* exit ligth mode */
501
        break;
502
 
503
    default: /* unknown escape sequence */
504
        break;
505
    }
506
}
507
 
508
/*
509
 * un-escaped character print routine
510
 */
511
 
512
void esc0 (unsigned char c)
513
{
514
    switch (c)
515
    {
516
    case 0:
517
        /*
518
         * printing \000 on a terminal means "do nothing".
519
         * But since we use \000 as string terminator none
520
         * of the characters that follow were printed.
521
         *
522
         * perl -e 'printf("a%ca", 0);'
523
         *
524
         * said 'a' in a wterm, but should say 'aa'. This
525
         * bug screwed up most ncurses programs.
526
         *
527
         * kay.
528
         */
529
        break;
530
 
531
    case 7: /* bell */
532
        if (visualbell)
533
        {
534
/*          w_setmode(win, M_INVERS); */
535
/*          w_pbox(win, 0, 0, winw, winh); */
536
/*          w_test(win, 0, 0); */
537
/*          w_pbox(win, 0, 0, winw, winh); */
538
            ;
539
        }
540
        else
541
        {
542
            ;
543
            GrBell();
544
        }
545
        break;
546
 
547
    case 8: /* backspace */
548
        lineRedraw();
549
        if (--curx < 0)
550
        {
551
            curx = 0;
552
        }
553
        break;
554
 
555
    case 9: /* tab */
556
    {
557
        int borg,i;
558
 
559
        borg=(((curx >> 3) + 1) << 3);
560
        if(borg >= col)
561
        {
562
            borg=col-1;
563
        }
564
        borg=borg-curx;
565
        for(i=0; i < borg; ++i){sadd(' ');}
566
        if ((curx = ((curx >> 3) + 1) << 3) >= col)
567
        {
568
            curx = col - 1;
569
        }
570
    }
571
        break;
572
 
573
    case 10: /* line feed */
574
        sflush();
575
        if (++cury >= row)
576
        {
577
            vscroll(1);
578
            cury = row-1;
579
        }
580
        break;
581
 
582
    case 13: /* carriage return */
583
        sflush();
584
        curx = 0;
585
        break;
586
 
587
    case 27: /* escape */
588
        sflush();
589
        escstate = 1;
590
        break;
591
 
592
    case 127: /* delete */
593
        break;
594
 
595
    default: /* any printable char */
596
        sadd(c);
597
        if (++curx >= col)
598
        {
599
            sflush();
600
            if (!wrap)
601
            {
602
                curx = col-1;
603
            }
604
            else
605
            {
606
                curx = 0;
607
                if (++cury >= row)
608
                {
609
                    vscroll(1);
610
                }
611
            }
612
        }
613
        break;
614
    }
615
}
616
 
617
 
618
void printc(unsigned char c)
619
{
620
    switch(escstate)
621
    {
622
    case 0:
623
        esc0(c);
624
        break;
625
 
626
    case 1:
627
        sflush();
628
        esc1(c);
629
        break;
630
 
631
    case 2:
632
        sflush();
633
        esc2(c);
634
        break;
635
 
636
    case 3:
637
        sflush();
638
        esc3(c);
639
        break;
640
 
641
    case 4:
642
        sflush();
643
        esc4(c);
644
        break;
645
 
646
    case 5:
647
        sflush();
648
        esc5(c);
649
        break;
650
 
651
    default:
652
        escstate = 0;
653
        break;
654
    }
655
}
656
 
657
 
658
void init()
659
{
660
    curx = savx = 0;
661
    cury = savy = 0;
662
    wrap = 1;
663
    curon = 1;
664
    curvis = 0;
665
    escstate = 0;
666
}
667
 
668
 
669
/*
670
 * general code...
671
 */
672
 
673
void
674
term(void)
675
{
676
        long            in, l;
677
        GR_EVENT        wevent;
678
        GR_EVENT_KEYSTROKE *kp;
679
        unsigned char   buf[LARGEBUFFER];
680
 
681
        GrRegisterInput(pipeh);
682
        while (42) {
683
                if (havefocus)
684
                        draw_cursor();
685
                GrGetNextEvent(&wevent);
686
 
687
                switch(wevent.type) {
688
                case GR_EVENT_TYPE_CLOSE_REQ:
689
                        GrClose();
690
                        exit(0);
691
                        break;
692
 
693
                case GR_EVENT_TYPE_KEY_DOWN:
694
                        kp=(GR_EVENT_KEYSTROKE *)&wevent;
695
                        /* toss all special keys*/
696
                        if (kp->ch & MWKEY_NONASCII_MASK)
697
                                break;
698
                        *buf = kp->ch & 0xff;
699
                        write(pipeh, buf,1);
700
                        break;
701
 
702
                case GR_EVENT_TYPE_FOCUS_IN:
703
                        havefocus = GR_TRUE;
704
                        break;
705
 
706
                case GR_EVENT_TYPE_FOCUS_OUT:
707
                        havefocus = GR_FALSE;
708
                        hide_cursor();
709
                        break;
710
 
711
                case GR_EVENT_TYPE_UPDATE:
712
                        /*
713
                         * if we get temporarily unmapped (moved),
714
                         * set cursor state off.
715
                         */
716
                        if (wevent.update.utype == GR_UPDATE_UNMAPTEMP)
717
                                curvis = 0;
718
                        break;
719
 
720
                case GR_EVENT_TYPE_FDINPUT:
721
                        hide_cursor();
722
                        while ((in = read(pipeh, buf, sizeof(buf))) > 0) {
723
                                for (l=0; l<in; l++) {
724
                                        printc(buf[l]);
725
                                        if (buf[l] == '\n')
726
                                                printc('\r');
727
                                }
728
                                sflush();
729
                        }
730
                        break;
731
                }
732
        }
733
}
734
 
735
 
736
void usage(char *s)
737
{
738
    if (s)
739
        fprintf(stderr, "error: %s\n", s);
740
    printf("usage: nxterm [-b] [-d] [-f <font family>] [-s <font size>]\n");
741
    printf("       [-g <geometry>] [-v] [-c] [-h] [program {args}]\n");
742
    exit(0);
743
}
744
 
745
 
746
void *mysignal(int signum, void *handler)
747
{
748
  struct sigaction sa, so;
749
 
750
  sa.sa_handler = handler;
751
  sigemptyset(&sa.sa_mask);
752
  sa.sa_flags = SA_RESTART;
753
  sigaction(signum, &sa, &so);
754
 
755
  return so.sa_handler;
756
}
757
 
758
/*
759
 * guess what... :)
760
 */
761
 
762
int main(int argc, char **argv)
763
{
764
    GR_BITMAP   bitmap1fg[7];   /* mouse cursor */
765
    GR_BITMAP   bitmap1bg[7];
766
    GR_WM_PROPERTIES props;
767
 
768
    short xp, yp, fsize;
769
    char *family, *shell = NULL, *cptr, *geometry = NULL;
770
    struct passwd *pw;
771
    char buf[80];
772
    short uid;
773
    char thesh[128];
774
#ifdef __FreeBSD__
775
    char *ptr;
776
#endif
777
 
778
#ifdef SIGTTOU
779
    /* just in case we're started in the background */
780
    signal(SIGTTOU, SIG_IGN);
781
#endif
782
 
783
    /* who am I? */
784
    if (!(pw = getpwuid((uid = getuid()))))
785
    {
786
        fprintf(stderr, "error: wterm can't determine determine your login name\n");
787
        exit(-1);
788
    }
789
 
790
 
791
    if (GrOpen() < 0)
792
    {
793
        fprintf(stderr, "cannot open graphics\n");
794
        exit(1);
795
    }
796
 
797
    GrGetScreenInfo(&si);
798
    /*
799
     * scan arguments...
800
     */
801
 
802
    console = 0;
803
    argv++;
804
    while (*argv && **argv=='-')
805
        switch (*(*argv+1))
806
        {
807
        case 'b':
808
            cblink = 1;
809
            argv++;
810
            break;
811
 
812
        case 'c':
813
            console = 1;
814
            argv++;
815
            break;
816
 
817
        case 'd':
818
            debug = 1;
819
            argv++;
820
            break;
821
 
822
        case 'f':
823
            if (*++argv) {
824
                family = *argv++;
825
            } else {
826
                usage("-f option requires an argument");
827
            }
828
            break;
829
 
830
        case 's':
831
            if (*++argv) {
832
                fsize = atoi(*argv++);
833
            } else {
834
                usage("-s option requires an argument");
835
            }
836
            break;
837
 
838
        case 'g':
839
            if (*++argv) {
840
                geometry = *argv++;
841
            } else {
842
                usage("-g option requires an argument");
843
            }
844
            break;
845
 
846
        case 'h':
847
            /* this will never return */
848
            usage("");
849
 
850
        case 'v':
851
            visualbell = 1;
852
            argv++;
853
            break;
854
 
855
        default:
856
            usage("unknown option");
857
        }
858
 
859
    /*
860
     * now *argv either points to a program to start or is zero
861
     */
862
 
863
    if (*argv) {
864
        shell = *argv;
865
    }
866
    if (!shell) {
867
        shell = getenv("SHELL=");
868
    }
869
    if (!shell) {
870
        shell = pw->pw_shell;
871
    }
872
    if (!shell) {
873
        shell = "/bin/sh";
874
    }
875
 
876
    if (!*argv) {
877
        /*
878
         * the '-' makes the shell think it is a login shell,
879
         * we leave argv[0] alone if it isn`t a shell (ie.
880
         * the user specified the program to run as an argument
881
         * to wterm.
882
         */
883
        cptr = strrchr(shell, '/');
884
        sprintf (thesh, "-%s", cptr ? cptr + 1 : shell);
885
        *--argv = thesh;
886
    }
887
 
888
    col = 80;
889
    row = 25;
890
    xp = 0;
891
    yp = 0;
892
    if (geometry)
893
    {
894
        if (col < 1)
895
        {
896
            col = 80;
897
        }
898
        if (row < 1)
899
        {
900
            row = 25;
901
        }
902
        if (col > 0x7f)
903
            colmask = 0xffff;
904
        if (row > 0x7f)
905
            rowmask = 0xffff;
906
    }
907
 
908
    regFont=GrCreateFont(GR_FONT_SYSTEM_FIXED, 0, NULL);
909
    /*regFont=GrCreateFont(GR_FONT_OEM_FIXED, 0, NULL);*/
910
    /*boldFont=GrCreateFont(GR_FONT_SYSTEM_FIXED, 0, NULL);*/
911
    GrGetFontInfo(regFont, &fi);
912
 
913
    winw=col*fi.maxwidth;
914
    winh=row*fi.height;
915
    w1 = GrNewWindow(GR_ROOT_WINDOW_ID, 10,10,winw, winh,0,BLACK,LTBLUE);
916
    props.flags = GR_WM_FLAGS_TITLE;
917
    props.title = TITLE;
918
    GrSetWMProperties(w1, &props);
919
 
920
    GrSelectEvents(w1, GR_EVENT_MASK_BUTTON_DOWN |
921
                   GR_EVENT_MASK_KEY_DOWN |
922
                   GR_EVENT_MASK_FOCUS_IN | GR_EVENT_MASK_FOCUS_OUT |
923
                   GR_EVENT_MASK_UPDATE | GR_EVENT_MASK_CLOSE_REQ);
924
 
925
    GrMapWindow(w1);
926
 
927
    gc1 = GrNewGC();
928
    GrSetGCFont(gc1, regFont);
929
 
930
#define _       ((unsigned) 0)          /* off bits */
931
#define X       ((unsigned) 1)          /* on bits */
932
#define MASK(a,b,c,d,e,f,g) \
933
        (((((((((((((a * 2) + b) * 2) + c) * 2) + d) * 2) \
934
        + e) * 2) + f) * 2) + g) << 9)
935
        bitmap1fg[0] = MASK(_,_,X,_,X,_,_);
936
        bitmap1fg[1] = MASK(_,_,_,X,_,_,_);
937
        bitmap1fg[2] = MASK(_,_,_,X,_,_,_);
938
        bitmap1fg[3] = MASK(_,_,_,X,_,_,_);
939
        bitmap1fg[4] = MASK(_,_,_,X,_,_,_);
940
        bitmap1fg[5] = MASK(_,_,_,X,_,_,_);
941
        bitmap1fg[6] = MASK(_,_,X,_,X,_,_);
942
 
943
        bitmap1bg[0] = MASK(_,X,X,X,X,X,_);
944
        bitmap1bg[1] = MASK(_,_,X,X,X,_,_);
945
        bitmap1bg[2] = MASK(_,_,X,X,X,_,_);
946
        bitmap1bg[3] = MASK(_,_,X,X,X,_,_);
947
        bitmap1bg[4] = MASK(_,_,X,X,X,_,_);
948
        bitmap1bg[5] = MASK(_,_,X,X,X,_,_);
949
        bitmap1bg[6] = MASK(_,X,X,X,X,X,_);
950
    GrSetCursor(w1, 7, 7, 3, 3, GREEN, BLACK, bitmap1fg, bitmap1bg);
951
    GrSetGCForeground(gc1, GREEN);
952
    GrSetGCBackground(gc1, BLACK);
953
    GrGetWindowInfo(w1,&wi);
954
    GrGetGCInfo(gc1,&gi);
955
 
956
    sprintf(buf, "wterm: %s", shell);
957
 
958
    /*
959
     * what kind of terminal do we want to emulate?
960
     */
961
#ifdef __FreeBSD__
962
    putenv ("TERM=wterm");
963
#else
964
    putenv ("TERM=vt52");
965
#endif
966
 
967
    /*
968
     * this one should enable us to get rid of an /etc/termcap entry for
969
     * both curses and ncurses, hopefully...
970
     */
971
 
972
    if (termcap_string)
973
    {
974
        sprintf (termcap_string + strlen (termcap_string), "li#%d:co#%d:",
975
                 row, col);
976
        putenv (termcap_string);
977
    }
978
    /* in case program absolutely needs terminfo entry, these 'should'
979
     * transmit the screen size of correctly (at least xterm sets these
980
     * and everything seems to work correctly...). Unlike putenv(),
981
     * setenv() allocates also the given string not just a pointer.
982
     */
983
    sprintf (buf, "%d", col);
984
    setenv ("COLUMNS", buf, 1);
985
    sprintf (buf, "%d", row);
986
    setenv ("LINES", buf, 1);
987
 
988
    init();
989
 
990
    /*
991
     * create a pty
992
     */
993
#ifdef __FreeBSD__
994
    winsz.ws_col = col;
995
    winsz.ws_row = row;
996
    if ((pid = forkpty(&pipeh, pty, NULL, &winsz)) < 0)
997
    {
998
        fprintf(stderr,"wterm: can't create pty\r\n");
999
        perror("wterm");
1000
        sleep(2);
1001
        GrKillWindow(w1);
1002
        exit(-1);
1003
    }
1004
 
1005
    if ((ptr = rindex(pty, '/')))
1006
    {
1007
        strcpy(pty, ptr + 1);
1008
    }
1009
 
1010
    if (!pid)
1011
    {
1012
        int i;
1013
        for (i = getdtablesize(); --i >= 3; )
1014
            close (i);
1015
        /*
1016
         * SIG_IGN are not reset on exec()
1017
         */
1018
        for (i = NSIG; --i >= 0; )
1019
            signal (i, SIG_DFL);
1020
 
1021
        /* caution: start shell with correct user id! */
1022
        seteuid(getuid());
1023
        setegid(getgid());
1024
 
1025
        /* this shall not return */
1026
        execvp(shell, argv);
1027
 
1028
        /* oops? */
1029
        fprintf(stderr,"wterm: can't start shell\r\n");
1030
        sleep(3);
1031
        GrKillWindow(w1);
1032
        _exit(-1);
1033
    }
1034
#else
1035
    pipeh = term_init();
1036
#endif
1037
 
1038
/*    _write_utmp(pty, pw->pw_name, "", time(0)); */
1039
 
1040
#if 0
1041
    /* catch some signals */
1042
    mysignal(SIGTERM, sigquit);
1043
    mysignal(SIGHUP, sigquit);
1044
    mysignal(SIGINT, SIG_IGN);
1045
    mysignal(SIGQUIT, sigquit);
1046
    mysignal(SIGPIPE, sigpipe);
1047
    mysignal(SIGCHLD, sigchld);
1048
#endif
1049
 
1050
    /* prepare to catch console output */
1051
    if (console)
1052
    {
1053
        /* for any OS chr$(7) might cause endless loops if
1054
         * catched from console
1055
         */
1056
        visualbell = 1;
1057
        console = 0;       /* data will come to normal pipe handle */
1058
        ioctl(pipeh, TIOCCONS, 0);
1059
    }
1060
 
1061
    term();
1062
    return 0;
1063
}
1064
 
1065
#if ELKS
1066
char * nargv[2] = {"/bin/sash", NULL};
1067
#else
1068
#if DOS_DJGPP
1069
char * nargv[2] = {"bash", NULL};
1070
#else
1071
char * nargv[2] = {"/bin/sh", NULL};
1072
#endif
1073
#endif
1074
 
1075
void sigchild(int signo)
1076
{
1077
        GrClose();
1078
        exit(0);
1079
}
1080
 
1081
int term_init()
1082
{
1083
        int tfd;
1084
        int n = 0;
1085
        pid_t pid;
1086
        char pty_name[12];
1087
 
1088
again:
1089
        sprintf(pty_name, "/dev/ptyp%d", n);
1090
        if ((tfd = open(pty_name, O_RDWR | O_NONBLOCK)) < 0) {
1091
                if ((errno == EBUSY || errno == EIO) && n < 10) {
1092
                        n++;
1093
                        goto again;
1094
                }
1095
                fprintf(stderr, "Can't create pty %s\n", pty_name);
1096
                return -1;
1097
        }
1098
        signal(SIGCHLD, sigchild);
1099
        signal(SIGINT, sigchild);
1100
        if ((pid = fork()) == -1) {
1101
                fprintf(stderr, "No processes\n");
1102
                return -1;
1103
        }
1104
        if (!pid) {
1105
                close(STDIN_FILENO);
1106
                close(STDOUT_FILENO);
1107
                close(tfd);
1108
 
1109
                setsid();
1110
                pty_name[5] = 't';
1111
                if ((tfd = open(pty_name, O_RDWR)) < 0) {
1112
                        fprintf(stderr, "Child: Can't open pty %s\n", pty_name);
1113
                        exit(1);
1114
                }
1115
                close(STDERR_FILENO);
1116
                dup2(tfd, STDIN_FILENO);
1117
                dup2(tfd, STDOUT_FILENO);
1118
                dup2(tfd, STDERR_FILENO);
1119
                execv(nargv[0], nargv);
1120
                exit(1);
1121
        }
1122
        return tfd;
1123
}
1124
 
1125
#if 0
1126
void _write_utmp(char *line, char *user, char *host, int time)
1127
{
1128
    int fh, offset, isEmpty, isLine;
1129
    struct utmp ut;
1130
 
1131
    if ((fh = open("/etc/utmp", O_RDWR)) < 0) {
1132
        return;
1133
    }
1134
 
1135
    /* first of all try to find an entry with the same line */
1136
 
1137
    offset = 0;
1138
    isEmpty = -1;
1139
    isLine = -1;
1140
 
1141
    while ((isLine < 0) && (read(fh, &ut, sizeof(ut)) == sizeof(ut))) {
1142
        if (!ut.ut_line[0])
1143
        {
1144
            if (isEmpty < 0)
1145
            {
1146
                isEmpty = offset;
1147
            }
1148
        }
1149
        else
1150
        {
1151
            if (!strncmp(ut.ut_line, line, sizeof(ut.ut_line))) {
1152
                isLine = offset;
1153
            }
1154
        }
1155
        offset += sizeof(ut);
1156
    }
1157
 
1158
    if (isLine != -1) {
1159
        /* we've found a match */
1160
        lseek(fh, isLine, SEEK_SET);
1161
    } else if (isEmpty != -1) {
1162
        /* no match found, but at least an empty entry */
1163
        lseek(fh, isLine, SEEK_SET);
1164
    } else {
1165
        /* not even an empty entry found, assume we can append to the file */
1166
    }
1167
 
1168
    if (time)
1169
    {
1170
        strncpy(ut.ut_line, line, sizeof(ut.ut_line));
1171
        strncpy(ut.ut_name, user, sizeof(ut.ut_name));
1172
        strncpy(ut.ut_host, host, sizeof(ut.ut_host));
1173
        ut.ut_time = time;
1174
    }
1175
    else
1176
    {
1177
        memset(&ut, 0, sizeof(ut));
1178
    }
1179
    write(fh, &ut, sizeof(ut));
1180
    close(fh);
1181
}
1182
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.