1 | /*--------------------------------*-C-*---------------------------------* |
1 | /*--------------------------------*-C-*---------------------------------* |
2 | * File: command.c |
2 | * File: command.c |
3 | *----------------------------------------------------------------------* |
3 | *----------------------------------------------------------------------* |
4 | * $Id: command.C,v 1.6 2003/11/25 17:11:33 pcg Exp $ |
4 | * $Id: command.C,v 1.9 2003/11/27 10:12:10 pcg Exp $ |
5 | * |
5 | * |
6 | * All portions of code are copyright by their respective author/s. |
6 | * All portions of code are copyright by their respective author/s. |
7 | * Copyright (c) 1992 John Bovey, University of Kent at Canterbury <jdb@ukc.ac.uk> |
7 | * Copyright (c) 1992 John Bovey, University of Kent at Canterbury <jdb@ukc.ac.uk> |
8 | * - original version |
8 | * - original version |
9 | * Copyright (c) 1994 Robert Nation <nation@rocket.sanders.lockheed.com> |
9 | * Copyright (c) 1994 Robert Nation <nation@rocket.sanders.lockheed.com> |
… | |
… | |
704 | } |
704 | } |
705 | |
705 | |
706 | void |
706 | void |
707 | rxvt_term::blink_cb (time_watcher &w) |
707 | rxvt_term::blink_cb (time_watcher &w) |
708 | { |
708 | { |
|
|
709 | SET_R (this); |
|
|
710 | |
709 | w.at += BLINK_INTERVAL; |
711 | w.at += BLINK_INTERVAL; |
710 | hidden_cursor = !hidden_cursor; |
712 | hidden_cursor = !hidden_cursor; |
711 | want_refresh = 1; |
713 | want_refresh = 1; |
712 | flush(); |
714 | flush (); |
713 | } |
715 | } |
714 | |
716 | |
715 | void |
717 | void |
716 | rxvt_term::x_cb (io_watcher &w, short revents) |
718 | rxvt_term::x_cb (io_watcher &w, short revents) |
717 | { |
719 | { |
|
|
720 | SET_R (this); |
|
|
721 | |
718 | process_x_events (); |
722 | process_x_events (); |
719 | |
723 | |
720 | flush (); |
724 | flush (); |
721 | } |
725 | } |
722 | |
726 | |
… | |
… | |
774 | |
778 | |
775 | return NOCHAR; |
779 | return NOCHAR; |
776 | } |
780 | } |
777 | |
781 | |
778 | bool |
782 | bool |
779 | rxvt_term::pty_fill (size_t count) |
783 | rxvt_term::pty_fill () |
780 | { |
784 | { |
781 | ssize_t n = cmdbuf_endp - cmdbuf_ptr; |
785 | ssize_t n = cmdbuf_endp - cmdbuf_ptr; |
782 | |
786 | |
783 | memmove (cmdbuf_base, cmdbuf_ptr, n); |
787 | memmove (cmdbuf_base, cmdbuf_ptr, n); |
784 | cmdbuf_ptr = cmdbuf_base; |
788 | cmdbuf_ptr = cmdbuf_base; |
785 | cmdbuf_endp = cmdbuf_ptr + n; |
789 | cmdbuf_endp = cmdbuf_ptr + n; |
786 | |
790 | |
787 | n = read (cmd_fd, cmdbuf_endp, count); |
791 | n = read (cmd_fd, cmdbuf_endp, BUFSIZ - n); |
788 | |
792 | |
789 | if (n > 0) |
793 | if (n > 0) |
790 | { |
794 | { |
791 | cmdbuf_endp += n; |
795 | cmdbuf_endp += n; |
792 | return true; |
796 | return true; |
793 | } |
797 | } |
794 | else if (n < 0 && errno == EAGAIN) |
798 | else if (n < 0 && errno == EAGAIN) |
795 | return false; |
799 | return false; |
796 | |
800 | |
797 | rxvt_clean_exit(); |
801 | destroy (); |
798 | exit(EXIT_FAILURE); /* bad order of events? */ |
|
|
799 | } |
802 | } |
800 | |
803 | |
801 | void |
804 | void |
802 | rxvt_term::pty_cb (io_watcher &w, short revents) |
805 | rxvt_term::pty_cb (io_watcher &w, short revents) |
803 | { |
806 | { |
804 | while (pty_fill (BUFSIZ - (cmdbuf_endp - cmdbuf_ptr))) |
807 | SET_R (this); |
|
|
808 | |
|
|
809 | // loop, but don't allow a single term to monopolize us |
|
|
810 | // the number of loops is fully arbitrary, and thus wrong |
|
|
811 | for (int i = 7; i-- && pty_fill (); ) |
805 | { |
812 | { |
|
|
813 | //TODO: |
806 | /* once we know the shell is running, send the screen size. Again! */ |
814 | /* once we know the shell is running, send the screen size. Again! */ |
807 | //ch = rxvt_cmd_getc(aR); /* wait for something */ |
815 | //ch = rxvt_cmd_getc(aR); /* wait for something */ |
808 | //rxvt_tt_winsize(cmd_fd, TermWin.ncol, TermWin.nrow, cmd_pid); |
816 | //rxvt_tt_winsize(cmd_fd, TermWin.ncol, TermWin.nrow, cmd_pid); |
809 | |
817 | |
810 | uint32_t ch = NOCHAR; |
818 | uint32_t ch = NOCHAR; |
… | |
… | |
921 | #ifdef USE_XIM |
929 | #ifdef USE_XIM |
922 | rxvt_IMSendSpot (this); |
930 | rxvt_IMSendSpot (this); |
923 | #endif |
931 | #endif |
924 | } |
932 | } |
925 | |
933 | |
|
|
934 | if (XPending (Xdisplay)) process_x_events (); |
926 | XFlush (Xdisplay); |
935 | XFlush (Xdisplay); |
|
|
936 | if (XPending (Xdisplay)) process_x_events (); |
927 | } |
937 | } |
928 | |
938 | |
929 | /* rxvt_cmd_getc() - Return next input character */ |
939 | /* rxvt_cmd_getc() - Return next input character */ |
930 | /* |
940 | /* |
931 | * Return the next input character after first passing any keyboard input |
941 | * Return the next input character after first passing any keyboard input |
… | |
… | |
942 | return c; |
952 | return c; |
943 | |
953 | |
944 | // incomplete sequences should occur rarely, still, a better solution |
954 | // incomplete sequences should occur rarely, still, a better solution |
945 | // would be preferred. either setjmp/longjmp or better design. |
955 | // would be preferred. either setjmp/longjmp or better design. |
946 | fcntl (R->cmd_fd, F_SETFL, 0); |
956 | fcntl (R->cmd_fd, F_SETFL, 0); |
947 | R->pty_fill (1); |
957 | R->pty_fill (); |
948 | fcntl (R->cmd_fd, F_SETFL, O_NONBLOCK); |
958 | fcntl (R->cmd_fd, F_SETFL, O_NONBLOCK); |
949 | } |
959 | } |
950 | |
960 | |
951 | #if 0 |
961 | #if 0 |
952 | #define TIMEOUT_USEC 5000 |
962 | #define TIMEOUT_USEC 5000 |
… | |
… | |
1006 | quick_timeout |= R->want_full_refresh; |
1016 | quick_timeout |= R->want_full_refresh; |
1007 | #endif |
1017 | #endif |
1008 | #endif |
1018 | #endif |
1009 | } |
1019 | } |
1010 | |
1020 | |
|
|
1021 | void |
|
|
1022 | rxvt_term::pointer_unblank () |
|
|
1023 | { |
|
|
1024 | XDefineCursor (Xdisplay, TermWin.vt, TermWin_cursor); |
|
|
1025 | rxvt_recolour_cursor (this); |
|
|
1026 | |
|
|
1027 | #ifdef POINTER_BLANK |
|
|
1028 | hidden_pointer = 0; |
|
|
1029 | |
|
|
1030 | if (Options & Opt_pointerBlank) |
|
|
1031 | pointer_ev.start (NOW + pointerBlankDelay); |
|
|
1032 | #endif |
|
|
1033 | } |
|
|
1034 | |
1011 | #ifdef POINTER_BLANK |
1035 | #ifdef POINTER_BLANK |
1012 | void |
1036 | void |
1013 | rxvt_term::pointer_unblank () |
1037 | rxvt_term::pointer_blank () |
1014 | { |
1038 | { |
|
|
1039 | pointer_ev.stop (); |
|
|
1040 | |
1015 | if (!(Options & Opt_pointerBlank)) |
1041 | if (!(Options & Opt_pointerBlank)) |
1016 | return; |
1042 | return; |
1017 | |
1043 | |
1018 | XDefineCursor (Xdisplay, TermWin.vt, TermWin_cursor); |
|
|
1019 | rxvt_recolour_cursor (this); |
|
|
1020 | hidden_pointer = 0; |
|
|
1021 | |
|
|
1022 | pointer_ev.start (NOW + pointerBlankDelay); |
|
|
1023 | } |
|
|
1024 | |
|
|
1025 | void |
|
|
1026 | rxvt_term::pointer_blank () |
|
|
1027 | { |
|
|
1028 | pointer_ev.stop (); |
|
|
1029 | |
|
|
1030 | if (!(Options & Opt_pointerBlank)) |
|
|
1031 | return; |
|
|
1032 | |
|
|
1033 | XDefineCursor (Xdisplay, TermWin.vt, blank_cursor); |
1044 | XDefineCursor (Xdisplay, TermWin.vt, blank_cursor); |
1034 | XFlush (Xdisplay); |
1045 | XFlush (Xdisplay); |
1035 | |
1046 | |
1036 | hidden_pointer = 1; |
1047 | hidden_pointer = 1; |
1037 | } |
1048 | } |
1038 | |
1049 | |
1039 | void |
1050 | void |
1040 | rxvt_term::pointer_cb (time_watcher &w) |
1051 | rxvt_term::pointer_cb (time_watcher &w) |
1041 | { |
1052 | { |
|
|
1053 | SET_R (this); |
|
|
1054 | |
1042 | pointer_blank (); |
1055 | pointer_blank (); |
1043 | } |
1056 | } |
1044 | #endif |
1057 | #endif |
1045 | |
1058 | |
1046 | /* INTPROTO */ |
1059 | /* INTPROTO */ |
… | |
… | |
1243 | break; |
1256 | break; |
1244 | |
1257 | |
1245 | case ClientMessage: |
1258 | case ClientMessage: |
1246 | if (ev->xclient.format == 32 |
1259 | if (ev->xclient.format == 32 |
1247 | && (Atom)ev->xclient.data.l[0] == R->xa[XA_WMDELETEWINDOW]) |
1260 | && (Atom)ev->xclient.data.l[0] == R->xa[XA_WMDELETEWINDOW]) |
1248 | exit(EXIT_SUCCESS); |
1261 | R->destroy (); |
1249 | #ifdef OFFIX_DND |
1262 | #ifdef OFFIX_DND |
1250 | /* OffiX Dnd (drag 'n' drop) protocol */ |
1263 | /* OffiX Dnd (drag 'n' drop) protocol */ |
1251 | if (ev->xclient.message_type == R->xa[XA_DNDPROTOCOL] |
1264 | else if (ev->xclient.message_type == R->xa[XA_DNDPROTOCOL] |
1252 | && (ev->xclient.data.l[0] == DndFile |
1265 | && (ev->xclient.data.l[0] == DndFile |
1253 | || ev->xclient.data.l[0] == DndDir |
1266 | || ev->xclient.data.l[0] == DndDir |
1254 | || ev->xclient.data.l[0] == DndLink)) { |
1267 | || ev->xclient.data.l[0] == DndLink)) { |
1255 | /* Get Dnd data */ |
1268 | /* Get Dnd data */ |
1256 | Atom ActualType; |
1269 | Atom ActualType; |
… | |
… | |
1288 | * in the GraphicsExpose parts, which means that after each refresh, |
1301 | * in the GraphicsExpose parts, which means that after each refresh, |
1289 | * we need to wait for the graphics expose or Noexpose events, |
1302 | * we need to wait for the graphics expose or Noexpose events, |
1290 | * which ought to make things real slow! |
1303 | * which ought to make things real slow! |
1291 | */ |
1304 | */ |
1292 | case VisibilityNotify: |
1305 | case VisibilityNotify: |
1293 | switch (ev->xvisibility.state) { |
1306 | switch (ev->xvisibility.state) |
|
|
1307 | { |
1294 | case VisibilityUnobscured: |
1308 | case VisibilityUnobscured: |
1295 | R->refresh_type = FAST_REFRESH; |
1309 | R->refresh_type = FAST_REFRESH; |
1296 | break; |
1310 | break; |
1297 | case VisibilityPartiallyObscured: |
1311 | case VisibilityPartiallyObscured: |
1298 | R->refresh_type = SLOW_REFRESH; |
1312 | R->refresh_type = SLOW_REFRESH; |
1299 | break; |
1313 | break; |
1300 | default: |
1314 | default: |
1301 | R->refresh_type = NO_REFRESH; |
1315 | R->refresh_type = NO_REFRESH; |
1302 | break; |
1316 | break; |
1303 | } |
1317 | } |
1304 | break; |
1318 | break; |
1305 | |
1319 | |
1306 | case FocusIn: |
1320 | case FocusIn: |
1307 | if (!R->TermWin.focus) { |
1321 | if (!R->TermWin.focus) { |
1308 | R->TermWin.focus = 1; |
1322 | R->TermWin.focus = 1; |