~ubuntu-branches/ubuntu/precise/fte/precise

« back to all changes in this revision

Viewing changes to src/con_linux.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Neil Williams
  • Date: 2011-08-14 10:28:46 UTC
  • mfrom: (1.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20110814102846-kate2jfkduwpnika
Tags: 0.50.2b6-1
* QA upload.
* Synchronise with current upstream sources.
  (Closes: #195945)
* Include NMUs by Nobuhiro Iwamatsu and Hideki Yamane,
  thanks to both.
* Move to 3.0 quilt

Show diffs side-by-side

added added

removed removed

Lines of Context:
52
52
#include <sys/vt.h>
53
53
#include <sys/wait.h>
54
54
#include <termios.h>
55
 
#include <unistd.h>
56
55
 
57
56
#include <linux/tty.h>
58
57
#include <linux/major.h>
64
63
#define MAX_PIPES 4
65
64
//#define PIPE_BUFLEN 4096
66
65
 
67
 
struct GPipe {
68
 
    int used;
69
 
    int id;
70
 
    int fd;
71
 
    int pid;
72
 
    int stopped;
73
 
    EModel *notify;
74
 
};
75
 
 
76
 
static GPipe Pipes[MAX_PIPES];
77
 
 
78
 
#define die(s) do { printf("%s\n", s); exit(1); } while(0)
 
66
#define die(s) do { printf("%s\n", s); exit(1); } while (0)
79
67
 
80
68
unsigned int VideoCols = 80;
81
69
unsigned int VideoRows = 25;
181
169
 
182
170
static void Die(int) {
183
171
    ConDone();
184
 
    exit(66);
 
172
    exit(1);
185
173
}
186
174
 
187
175
int ConInit(int /*XSize*/, int /*YSize*/) {
313
301
    GpmFd = Gpm_Open(&conn, 0);
314
302
    mouseShow();
315
303
#endif
316
 
    return 0;
 
304
 
 
305
    return 1;
317
306
}
318
307
 
319
308
int ConDone() {
328
317
        }
329
318
#endif
330
319
        ioctl(VtFd, KDSKBMODE, K_XLATE);
331
 
        tmp = tcsetattr(VtFd, 0, &Save_termios);
332
 
        if (tmp) fprintf(stderr, "tcsetattr = %d\n", tmp);
 
320
        if ((tmp = tcsetattr(VtFd, 0, &Save_termios)))
 
321
            fprintf(stderr, "tcsetattr = %d\n", tmp);
333
322
    }
334
 
    return 0;
 
323
    return 1;
335
324
}
336
325
 
337
326
int ConSuspend() {
344
333
    ioctl(VtFd, KDSKBMODE, K_XLATE);
345
334
    tmp = tcsetattr(VtFd, 0, &Save_termios);
346
335
    if (tmp) fprintf(stderr, "tcsetattr = %d\n", tmp);
347
 
    return 0;
 
336
    return 1;
348
337
}
349
338
 
350
339
int ConContinue() {
375
364
    GpmFd = Gpm_Open(&conn, 0);
376
365
    mouseShow();
377
366
#endif
378
 
    return 0;
 
367
 
 
368
    return 1;
379
369
}
380
370
 
381
371
int ConClear() {
384
374
    ConQuerySize(&X, &Y);
385
375
    ConSetBox(0, 0, X, Y, Cell);
386
376
    ConSetCursorPos(0, 0);
387
 
    return 0;
 
377
 
 
378
    return 1;
388
379
}
389
380
 
390
381
int ConSetTitle(const char */*Title*/, const char */*STitle*/) {
391
 
    return 0;
 
382
    return 1;
392
383
}
393
384
int ConGetTitle(char *Title, size_t MaxLen, char *STitle, size_t SMaxLen) {
394
385
    strlcpy(Title, "", MaxLen);
395
386
    strlcpy(STitle, "", SMaxLen);
396
 
    return 0;
 
387
 
 
388
    return 1;
397
389
}
398
390
 
399
391
int ConPutBox(int X, int Y, int W, int H, PCell Cell) {
402
394
        conwrite(VcsFd, Cell, W, 4 + ((Y + i) * VideoCols + X) * 2);
403
395
        if (LastMouseY == Y + i) mouseShow();
404
396
    }
405
 
    return 0;
 
397
 
 
398
    return 1;
406
399
}
407
400
 
408
401
int ConGetBox(int X, int Y, int W, int H, PCell Cell) {
411
404
        conread(VcsFd, Cell, W, 4 + ((Y + i) * VideoCols + X) * 2);
412
405
        if (LastMouseY == Y + i) mouseShow();
413
406
    }
414
 
    return 0;
 
407
 
 
408
    return 1;
415
409
}
416
410
 
417
411
int ConPutLine(int X, int Y, int W, int H, PCell Cell) {
419
413
    for (int i = 0; i < H; ++i)
420
414
        ConPutBox(X, Y + i, W, 1, Cell);
421
415
 
422
 
    return 0;
 
416
    return 1;
423
417
}
424
418
 
425
419
int ConSetBox(int X, int Y, int W, int H, TCell Cell) {
426
420
    TDrawBuffer B;
 
421
 
427
422
    MoveCh(B, Cell.GetChar(), Cell.GetAttr(), W);
428
423
    ConPutLine(X, Y, W, H, B);
429
 
    return 0;
 
424
 
 
425
    return 1;
430
426
}
431
427
 
432
428
int ConScroll(int Way, int X, int Y, int W, int H, TAttr Fill, int Count) {
433
429
 
434
430
    if (Count == 0 || Count > H)
435
 
        return 0;
 
431
        return 1;
436
432
 
437
433
    TDrawBuffer B;
438
434
    TCell C[W * H];
451
447
#ifdef USE_SCRNMAP
452
448
    noCharTrans = 0;
453
449
#endif
454
 
    return 0;
 
450
 
 
451
    return 1;
455
452
}
456
453
 
457
454
int ConSetSize(int /*X*/, int /*Y*/) {
458
 
    return -1;
 
455
    return 0;
459
456
}
460
457
 
461
458
int ConQuerySize(int *X, int *Y) {
462
459
    if (X) *X = VideoCols;
463
460
    if (Y) *Y = VideoRows;
464
 
    return 0;
 
461
 
 
462
    return 1;
465
463
}
466
464
 
467
465
int ConSetCursorPos(int X, int Y) {
473
471
    pos[1] = (char)CursorY;
474
472
    lseek(VcsFd, 2, SEEK_SET);
475
473
    write(VcsFd, pos, 2);
476
 
    return 0;
 
474
 
 
475
    return 1;
477
476
}
478
477
 
479
478
int ConQueryCursorPos(int *X, int *Y) {
480
479
    if (X) *X = CursorX;
481
480
    if (Y) *Y = CursorY;
482
 
    return 0;
 
481
 
 
482
    return 1;
483
483
}
484
484
 
485
485
int ConShowCursor() {
495
495
}
496
496
 
497
497
int ConSetMousePos(int /*X*/, int /*Y*/) {
498
 
    return -1;
 
498
    return 0;
499
499
}
500
500
 
501
501
int ConQueryMousePos(int *X, int *Y) {
502
502
    if (X) *X = LastMouseX;
503
503
    if (Y) *Y = LastMouseY;
504
 
    return -1;
 
504
    return 1;
505
505
}
506
506
 
507
507
int ConShowMouse() {
508
 
    return -1;
 
508
    return 0;
509
509
}
510
510
 
511
511
int ConHideMouse() {
512
 
    return -1;
 
512
    return 0;
513
513
}
514
514
 
515
515
int ConMouseVisible() {
516
 
    return 0;
 
516
    return 1;
517
517
}
518
518
 
519
519
int ConQueryMouseButtons(int *ButtonCount) {
520
 
    if (ButtonCount) *ButtonCount = 0;
521
 
    return 0;
 
520
    if (ButtonCount)
 
521
        *ButtonCount = 0;
 
522
 
 
523
    return 1;
522
524
}
523
525
 
524
526
static TEvent Prev = { evNone };
525
527
 
526
528
int ConGetEvent(TEventMask /*EventMask*/, TEvent *Event, int WaitTime, int Delete) {
527
 
    fd_set readfds;
528
 
    struct timeval timeout;
529
 
 
530
529
    if (Prev.What != evNone) {
531
530
        *Event = Prev;
532
531
        if (Delete) Prev.What = evNone;
533
532
        return 1;
534
533
    }
535
 
    Event->What = evNone;
536
534
 
537
 
    FD_ZERO(&readfds);
538
 
    FD_SET(VtFd, &readfds);
 
535
    switch (WaitFdPipeEvent(Event, VtFd,
539
536
#ifdef USE_GPM
540
 
    if (GpmFd != -1)
541
 
        FD_SET(GpmFd, &readfds);
 
537
                            GpmFd,
 
538
#else
 
539
                            -1,
542
540
#endif
543
 
    for (int p = 0; p < MAX_PIPES; p++)
544
 
        if (Pipes[p].used)
545
 
            if (Pipes[p].fd != -1)
546
 
                FD_SET(Pipes[p].fd, &readfds);
547
 
    if (WaitTime == -1) {
548
 
        if (select(sizeof(fd_set) * 8, &readfds, NULL, NULL, NULL) < 0) return -1;
549
 
    } else {
550
 
        timeout.tv_sec = WaitTime / 1000;
551
 
        timeout.tv_usec = (WaitTime % 1000) * 1000;
552
 
        if (select(sizeof(fd_set) * 8, &readfds, NULL, NULL, &timeout) < 0) return -1;
553
 
    }
554
 
    if (FD_ISSET(VtFd, &readfds)) {
 
541
                            WaitTime)) {
 
542
    default:
 
543
        return 1;
 
544
    case FD_PIPE_ERROR:
 
545
        return 0;
 
546
    case FD_PIPE_1:
555
547
        GetKeyEvent(Event);
556
548
        if (!Delete)
557
549
            Prev = *Event;
558
550
        return 1;
559
551
#ifdef USE_GPM
560
 
    } else if (GpmFd != -1 && FD_ISSET(GpmFd, &readfds)) {
 
552
    case FD_PIPE_2:
561
553
        GetMouseEvent(Event);
562
554
        if (!Delete)
563
555
            Prev = *Event;
564
556
        return 1;
565
557
#endif
566
 
    } else {
567
 
        for (int pp = 0; pp < MAX_PIPES; pp++) {
568
 
            if (Pipes[pp].used)
569
 
                if (Pipes[pp].fd != -1)
570
 
                    if (FD_ISSET(Pipes[pp].fd, &readfds)) {
571
 
                        if (Pipes[pp].notify) {
572
 
                            Event->What = evNotify;
573
 
                            Event->Msg.View = 0;
574
 
                            Event->Msg.Model = Pipes[pp].notify;
575
 
                            Event->Msg.Command = cmPipeRead;
576
 
                            Event->Msg.Param1 = pp;
577
 
                            Pipes[pp].stopped = 0;
578
 
                        }
579
 
                        //fprintf(stderr, "Pipe %d\n", Pipes[pp].fd);
580
 
                        return 0;
581
 
                    }
582
 
        }
583
 
        return -1;
584
558
    }
585
 
    return 0;
586
559
}
587
560
 
588
561
int ConPutEvent(const TEvent& Event) {
589
562
    Prev = Event;
590
 
    return 0;
 
563
    return 1;
591
564
}
592
565
 
593
566
int ConFlush() {return 0;  }
678
651
    Event->What = evNone;
679
652
 
680
653
    if (read(VtFd, &keycode, 1) != 1)
681
 
        return -1;
 
654
        return 0;
682
655
 
683
656
    int key = keycode & 0x7F;
684
657
    int press = (keycode & 0x80) ? 0 : 1;
835
808
                for (size_t i = 0; i < FTE_ARRAY_SIZE(DeadTrans); ++i)
836
809
                    if (DeadTrans[i].KeySym == keysym) {
837
810
                        dead_key = DeadTrans[i].Diacr;
838
 
                        return -1;
 
811
                        return 0;
839
812
                    }
840
813
 
841
814
                dead_key = 0;
842
 
                return -1;
 
815
                return 0;
843
816
            }
844
817
            if (! (ShiftFlags & (kfAlt | kfCtrl)) && dead_key) {
845
818
                for (unsigned i = 0; i < diacr_table.kb_cnt; ++i)
856
829
    }
857
830
 
858
831
    if (KeyCode == 0)
859
 
        return -1;
 
832
        return 0;
860
833
 
861
834
    if (ShiftFlags & kfCtrl)
862
835
        if (KeyCode < 32)
909
882
            Event->What = evNone;
910
883
            //                shift_state = lock_state = slock_state = 0; // bad
911
884
            shift_state = slock_state = 0; // bad
912
 
            return -1;
 
885
            return 0;
913
886
        }
914
887
 
915
 
        return 0;
 
888
        return 1;
916
889
    }
917
 
    return -1;
 
890
    return 0;
918
891
}
919
892
 
920
893
int GetMouseEvent(TEvent *Event) {
961
934
            ((e.modifiers & 4) ? kfCtrl : 0);
962
935
 
963
936
        if (LastMouseX != e.x ||
964
 
            LastMouseY != e.y)
965
 
        {
 
937
            LastMouseY != e.y) {
966
938
            mouseHide();
967
939
            LastMouseX = e.x;
968
940
            LastMouseY = e.y;
973
945
#else
974
946
    Event->What = evNone;
975
947
#endif
976
 
    return 0;
 
948
    return 1;
977
949
}
978
950
 
979
951
int ConSetCursorSize(int /*Start*/, int /*End*/) {
980
 
    return 0;
 
952
    return 1;
981
953
}
982
954
 
983
955
static PCell SavedScreen = 0;
992
964
    if (SavedScreen)
993
965
        ConGetBox(0, 0, SavedX, SavedY, SavedScreen);
994
966
    ConQueryCursorPos(&SaveCursorPosX, &SaveCursorPosY);
995
 
    return 0;
 
967
 
 
968
    return 1;
996
969
}
997
970
 
998
971
int RestoreScreen() {
1000
973
        ConPutBox(0, 0, SavedX, SavedY, SavedScreen);
1001
974
        ConSetCursorPos(SaveCursorPosX, SaveCursorPosY);
1002
975
    }
 
976
 
1003
977
    return 1;
1004
978
}
1005
979
 
1046
1020
    return 1;
1047
1021
}
1048
1022
 
1049
 
int GUI::OpenPipe(const char *Command, EModel *notify) {
1050
 
    int i;
1051
 
 
1052
 
    for (i = 0; i < MAX_PIPES; i++) {
1053
 
        if (Pipes[i].used == 0) {
1054
 
            int pfd[2];
1055
 
 
1056
 
            Pipes[i].id = i;
1057
 
            Pipes[i].notify = notify;
1058
 
            Pipes[i].stopped = 1;
1059
 
 
1060
 
            if (pipe((int *)pfd) == -1)
1061
 
                return -1;
1062
 
 
1063
 
            switch (Pipes[i].pid = fork()) {
1064
 
            case -1: /* fail */
1065
 
                return -1;
1066
 
            case 0: /* child */
1067
 
                signal(SIGPIPE, SIG_DFL);
1068
 
                VtFd = -1; // for atexit handler
1069
 
                close(VtFd);
1070
 
                close(pfd[0]);
1071
 
                close(0);
1072
 
                dup2(pfd[1], 1);
1073
 
                dup2(pfd[1], 2);
1074
 
                close(pfd[1]);
1075
 
                exit(system(Command));
1076
 
            default:
1077
 
                close(pfd[1]);
1078
 
                fcntl(pfd[0], F_SETFL, O_NONBLOCK);
1079
 
                Pipes[i].fd = pfd[0];
1080
 
            }
1081
 
            Pipes[i].used = 1;
1082
 
            //fprintf(stderr, "Pipe Open: %d\n", i);
1083
 
            return i;
1084
 
        }
1085
 
    }
1086
 
    return -1;
1087
 
}
1088
 
 
1089
 
int GUI::SetPipeView(int id, EModel *notify) {
1090
 
    if (id < 0 || id > MAX_PIPES)
1091
 
        return -1;
1092
 
    if (Pipes[id].used == 0)
1093
 
        return -1;
1094
 
    //fprintf(stderr, "Pipe View: %d %08X\n", id, notify);
1095
 
    Pipes[id].notify = notify;
1096
 
    return 0;
1097
 
}
1098
 
 
1099
 
ssize_t GUI::ReadPipe(int id, void *buffer, size_t len) {
1100
 
    ssize_t rc;
1101
 
 
1102
 
    if (id < 0 || id > MAX_PIPES)
1103
 
        return -1;
1104
 
    if (Pipes[id].used == 0)
1105
 
        return -1;
1106
 
    //fprintf(stderr, "Pipe Read: Get %d %d\n", id, len);
1107
 
 
1108
 
    rc = read(Pipes[id].fd, buffer, len);
1109
 
    //fprintf(stderr, "Pipe Read: Got %d %d\n", id, len);
1110
 
    if (rc == 0) {
1111
 
        close(Pipes[id].fd);
1112
 
        Pipes[id].fd = -1;
1113
 
        return -1;
1114
 
    }
1115
 
    if (rc == -1) {
1116
 
        Pipes[id].stopped = 1;
1117
 
        return 0;
1118
 
    }
1119
 
    return rc;
1120
 
}
1121
 
 
1122
 
int GUI::ClosePipe(int id) {
1123
 
    int status = -1;
1124
 
 
1125
 
    if (id < 0 || id > MAX_PIPES)
1126
 
        return -1;
1127
 
    if (Pipes[id].used == 0)
1128
 
        return -1;
1129
 
    if (Pipes[id].fd != -1)
1130
 
        close(Pipes[id].fd);
1131
 
    kill(Pipes[id].pid, SIGHUP);
1132
 
    alarm(1);
1133
 
    waitpid(Pipes[id].pid, &status, 0);
1134
 
    alarm(0);
1135
 
    //fprintf(stderr, "Pipe Close: %d\n", id);
1136
 
    Pipes[id].used = 0;
1137
 
    return WEXITSTATUS(status);
1138
 
}
1139
 
 
1140
1023
int GUI::RunProgram(int /*mode*/, char *Command) {
1141
1024
    int rc, W, H, W1, H1;
1142
1025
 
1147
1030
    if (*Command == 0)  // empty string = shell
1148
1031
        Command = getenv("SHELL");
1149
1032
 
1150
 
    rc = system(Command);
 
1033
    rc = (system(Command) == 0);
1151
1034
 
1152
1035
    ConContinue();
1153
1036
    ConShowMouse();
1154
1037
    ConQuerySize(&W1, &H1);
1155
1038
 
1156
 
    if (W != W1 || H != H1) {
 
1039
    if (W != W1 || H != H1)
1157
1040
        frames->Resize(W1, H1);
1158
 
    }
 
1041
 
1159
1042
    frames->Repaint();
 
1043
 
1160
1044
    return rc;
1161
1045
}
1162
1046
 
1165
1049
    static size_t tablen = 0;
1166
1050
 
1167
1051
    if (!tab) {
1168
 
        if (getenv("ISOCONSOLE")) {
 
1052
        if (getenv("ISOCONSOLE"))
1169
1053
            tab = GetGUICharacters("Linux", "++++-|+++++>.*-^v :[>");
1170
 
        } else {
 
1054
        else {
1171
1055
            /* it's hard to pick usable chars between way to many fonts */
1172
1056
            tab = GetGUICharacters("Linux", "\xDA\xBF\xC0\xD9\xC4\xB3\xC2\xC3\xB4\xC1\xC5\x1A.\x0A\xC4\x18\x19\xB1\xB0\x1B\x1A");
1173
1057
            //tab = GetGUICharacters("Linux", "\xDA\xBF\xC0\xD9\xC4\xB3\xC2\xC3\xB4\xC1\xC5\x1A\xFA\x04\xC4\x18\x19\xB1\xB0\x1B\x1A");