home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume14 / mush6.0 / part06 / select.c < prev   
Encoding:
C/C++ Source or Header  |  1988-04-12  |  12.7 KB  |  428 lines

  1. /* select.c    (c) copyright 1986 (Dan Heller) */
  2.  
  3. /* 
  4.  * Routine which handle io (selection on file descriptors) between user and
  5.  * the various windows.
  6.  *
  7.  * In toolmode, the user types characters and each character is interpreted
  8.  * here and, if applicable, is sent to rite.c where it is appended to a 
  9.  * string similar to a tty driver and fgets. When the user types a '\n' the
  10.  * rite() routine returns the string and we call add_to_letter to append the
  11.  * string to the letter.  Signals are caught here as well.  that is the signal
  12.  * characters setup by the user are checked and if one matches, call the signal
  13.  * handling routine as if there were a real signal.
  14.  *
  15.  * Mouse handling is done here. See code for more detail.
  16.  */
  17. #include "mush.h"
  18.  
  19. #define READ_MSG    (char *)'r'
  20. #define DEL_MSG        (char *)'d'
  21. #define UNDEL_MSG    (char *)'u'
  22. #define REPL_MSG    (char *)'R'
  23. #define SAVE_MSG    (char *)'s'
  24. #define PRNT_MSG    (char *)'p'
  25. #define PRE_MSG        (char *)'P'
  26. #define E_EDIT         (char *)'e'
  27. #define E_VIEW         (char *)'v'
  28. #define E_INCLUDE      (char *)'i'
  29. #define E_SEND        (char *)'S'
  30. #define E_ABORT       (char *)'a'
  31. #define MENU_HELP    (char *)'h'
  32. #define O_SAVE        (char *)'s'
  33. #define O_QUIT        (char *)'q'
  34. #define O_RSTR        (char *)'r'
  35.  
  36. #define N_MENU_ITEMS    8
  37. #define E_MENU_ITEMS    6
  38.  
  39. msg_io(gfxsw, ibits, obits, ebits, timer)
  40. register struct gfxsubwindow *gfxsw;
  41. register int *ibits,*obits,*ebits;
  42. struct timeval **timer;
  43. {
  44.     register char    *p;
  45.     struct inputevent     event;
  46.     static char     lastchar;
  47.     static int         line, count;
  48.  
  49.     if (*ibits & ~(1 << gfxsw->gfx_windowfd)) {
  50.     *ibits = *obits = *ebits = 0;
  51.     return;
  52.     }
  53.     if (input_readevent(msg_sw->ts_windowfd, &event) == -1) {
  54.     error("input event");
  55.     return;
  56.     }
  57.     /*
  58.     if (ID == LOC_WINENTER) {
  59.     int x;
  60.     struct inputmask im;
  61.     win_getinputmask(gfxsw->gfx_windowfd, &im, &x);
  62.     win_setinputmask(hdr_sw->ts_windowfd, &im, &im, x);
  63.     }
  64.     */
  65.     if (ID >= KEY_LEFTFIRST)
  66.     if (ison(glob_flags, IS_GETTING))
  67.         print("Finish editing letter first");
  68.     else
  69.         (void) func_key(ID);
  70.     else if (isascii(ID) && (msg_pix || ison(glob_flags, IS_GETTING) ||
  71.     getting_opts)) {
  72.     if (getting_opts) {
  73.         /*
  74.          * txt.x <= 5 indicates not to accept typed input for options
  75.          * and function key setting.
  76.          */
  77.         if (txt.x > 5) {
  78.         /* ^C, ^\ or ^U kills line */
  79.         type_cursor(PIX_XOR);
  80.         if (ID == tchars.t_intrc || ID == tchars.t_quitc ||
  81.                         ID == _tty.sg_kill) {
  82.             rite(_tty.sg_kill), txt.x = 5;
  83.             if (getting_opts == 1)
  84.             option_line(line), display_opts(0);
  85.             else
  86.             set_key(0, 0, 0);
  87.         } else if (p = rite((char)ID)) {
  88.             /* if no string entered, preserve old value */
  89.             if (*p && getting_opts == 1)
  90.             add_opt(p, line);
  91.             if (getting_opts == 2)
  92.             set_key(p, 0,0);
  93.         } else
  94.             type_cursor(PIX_XOR);
  95.         }
  96.     }
  97.     /*
  98.      * This section MUST BE BEFORE the following "is_getting" section.
  99.      * If user displays a message while editing a letter, he must hit 'q'
  100.      * to return to edit mode.  He may not edit a new letter while one is
  101.      * already being edited.
  102.      */
  103.     else if (msg_pix)
  104.         if (isdigit(ID)) {
  105.         if (!isdigit(lastchar))
  106.             count = 0;
  107.         count = count * 10 + ID - '0';
  108.         } else {
  109.         /* scroll <count> lines */
  110.         if (!count || count > msg_pix->pr_size.y / l_height(curfont))
  111.             count = 1;
  112.         if (ID == 'k' || ID == 'K' || ID == '-')
  113.             scroll_win(-count);
  114.         else if (ID == '\n' || ID == '\r' || ID == 'j')
  115.             scroll_win(count);
  116.         else if (ID == ' ')
  117.             scroll_win(crt);
  118.         else if ((ID == 'q' || ID == 'Q') &&
  119.             ison(glob_flags, IS_GETTING)) {
  120.             pr_destroy(msg_pix), msg_pix = (struct pixrect *)NULL;
  121.             win_setcursor(msg_sw->ts_windowfd, &write_cursor);
  122.             txt.x = 5, txt.y = msg_rect.r_height - l_height(curfont);
  123.             wprint("\n(continue editing letter)\n");
  124.             clr_bot_line();
  125.             type_cursor(PIX_SRC);
  126.         }
  127.         }
  128.     /*
  129.      * If msg_pix is NULL, then we are not reading a message. If we are
  130.      * editing a letter, then enter the keys typed.  If we are doing
  131.      * nothing, ignore this input.
  132.      */
  133.     else if (ison(glob_flags, IS_GETTING)) {
  134.         type_cursor(PIX_XOR);
  135.         if (lastchar != ltchars.t_lnextc &&
  136.         (ID == tchars.t_intrc || ID == tchars.t_quitc)) {
  137.             (void) rite(_tty.sg_kill);
  138.             (void) rm_edfile(SIGINT);
  139.         } else {
  140.         register int n = 1;
  141.         if (ID == tchars.t_eofc && txt.x == 5
  142.             || (p = rite((char)ID)) && !(n = add_to_letter(p)))
  143.             finish_up_letter();
  144.         else if (n > 0)
  145.             type_cursor(PIX_XOR);
  146.         }
  147.     }
  148.     lastchar = ID;
  149.     } else switch(ID) {
  150.     when MS_LEFT : case MS_MIDDLE:
  151.         if (getting_opts == 2)
  152.         if (ID == MS_LEFT)
  153.             set_key(NULL, event.ie_locx, event.ie_locy);
  154.         else {
  155.             register char *p = find_key(event.ie_locx, event.ie_locy);
  156.             if (p)
  157.             print("Function key %s:  %s", p, key_set_to(p));
  158.         }
  159.         else if (getting_opts) {
  160.         int y = event.ie_locy - 50;
  161.         if (y < -24)
  162.             break;
  163.         if (y < 0) {
  164.             register int x = event.ie_locx;
  165.             register int X = 60*l_width(LARGE);
  166.             if (x >= X && x <= X+16)
  167.             display_opts(-1); /* scroll options back one value */
  168.             else if (x >= X+20 && x <= X+36)
  169.             display_opts(1); /* scroll options forward one value */
  170.             break;
  171.         }
  172.         /* the user was typing something -- stopped by using mouse */
  173.         if (txt.x > 5) {
  174.             type_cursor(PIX_CLR);
  175.             (void) rite(_tty.sg_kill), txt.x = 5;
  176.             option_line(line), display_opts(0);
  177.         }
  178.             line = y/20;
  179.         if (ID == MS_LEFT)
  180.             toggle_opt(line);
  181.         help_opt(line);   /* display help (short info) in both cases */
  182.         } else if (msg_pix)
  183.         if (ID == MS_LEFT)
  184.             scroll_win(crt-3);
  185.         else
  186.             scroll_win(-(crt-3));
  187.     when MS_RIGHT:
  188.         if (getting_opts)
  189.         (void) view_opts_menu(&event, gfxsw->gfx_windowfd);
  190.         else if (isoff(glob_flags, IS_GETTING))
  191.         (void) do_menu(&event, gfxsw->gfx_windowfd, current_msg);
  192.         else
  193.         (void) edit_menu(&event, gfxsw->gfx_windowfd);
  194.     otherwise: ;
  195.     }
  196.     *ibits = *obits = *ebits = 0;
  197. }
  198.  
  199. struct cursor *mice[3] = { &l_cursor, &m_cursor, &r_cursor };
  200.  
  201. hdr_io(gfxsw, ibits, obits, ebits, sw_timer)
  202. register struct gfxsubwindow *gfxsw;
  203. int *ibits,*obits,*ebits;
  204. struct timeval **sw_timer;
  205. {
  206.     static int         which_cursor;
  207.     struct inputmask     im;
  208.     struct inputevent     event;
  209.     int         line;
  210.  
  211.     if (*ibits & ~(1 << gfxsw->gfx_windowfd)) {
  212.     *ibits = *obits = *ebits = 0;
  213.     return;
  214.     }
  215.     /* make curosr change which button is lit */
  216.     win_setcursor(gfxsw->gfx_windowfd, mice[which_cursor]);
  217.  
  218.     which_cursor = (which_cursor+1) % 3;
  219.     if (input_readevent(hdr_sw->ts_windowfd, &event) == -1) {
  220.     error("input event");
  221.     return;
  222.     }
  223.     /* I'm not sure why I have to do this.
  224.      * I'm doing it because sometimes the IO hangs completely and no input
  225.      * is accepted. What I do here is get the current mask, save it, then
  226.      * reset it. This action seems to flush the IO queue, and I don't have hung
  227.      * IO anymore.  This shouldn't be necessary, but it appears to work.
  228.      * (occurances have droped about 90%)
  229.      */
  230.     if (ID == LOC_WINENTER) {
  231.     int x;
  232.     win_getinputmask(gfxsw->gfx_windowfd, &im, &x);
  233.     win_setinputmask(hdr_sw->ts_windowfd, &im, &im, x);
  234.     }
  235.     /* just return -- we just wanted to make the cursor flicker */
  236.     if (ID == LOC_STILL || ID == LOC_MOVE || ID == LOC_WINENTER) {
  237.     *ibits = *obits = *ebits = 0;
  238.     return;
  239.     }
  240.     line = event.ie_locy / l_height(DEFAULT);
  241.     if (ID >= KEY_LEFTFIRST)
  242.     (void) func_key(ID);
  243.     else if (n_array[line] > msg_cnt)
  244.     if (!msg_cnt)
  245.         print("-- You have no messages -- ");
  246.     else
  247.         print("Message out of range.  Place mouse over a legal message.");
  248.     else switch(ID) {
  249.     when MS_LEFT: case MS_MIDDLE:
  250.         (void) do_menu((ID == MS_LEFT)? READ_MSG: DEL_MSG, 0,n_array[line]);
  251.     when MS_RIGHT:
  252.         (void) do_menu(&event, gfxsw->gfx_windowfd, n_array[line]);
  253.     otherwise : print("Unkown ID = %d", ID);
  254.     }
  255.     *ibits = *obits = *ebits = 0;
  256. }
  257.  
  258. /* if "fd" is 0, then event points to the action to be taken.
  259.  * otherwise, determine action to be taken by displaying a menu.
  260.  * message is the number current_msg should be changed to (may be the same).
  261.  */
  262. do_menu(event, fd, message)
  263. caddr_t event;
  264. {
  265.     static char buf[20];
  266.     struct menuitem *m_item;
  267.     char *action;
  268.     static struct menuitem msg_menu_items[] = {
  269.     { MENU_IMAGESTRING,  "Read",     READ_MSG   },
  270.     { MENU_IMAGESTRING,  "Delete",   DEL_MSG    },
  271.     { MENU_IMAGESTRING,  "Undelete", UNDEL_MSG  },
  272.     { MENU_IMAGESTRING,  "Reply",    REPL_MSG   },
  273.     { MENU_IMAGESTRING,  "Save",     SAVE_MSG   },
  274.     { MENU_IMAGESTRING,  "Preserve", PRE_MSG    },
  275.     { MENU_IMAGESTRING,  "Print",    PRNT_MSG   },
  276.     { MENU_IMAGESTRING,  "Help",     MENU_HELP  }
  277.     };
  278.     static struct menu help_menu = {
  279.         MENU_IMAGESTRING, "Item Help",
  280.     N_MENU_ITEMS, msg_menu_items,
  281.     (struct menu *)NULL, NULL
  282.     };
  283.     static struct menu msgs_menu = {
  284.         MENU_IMAGESTRING, buf, N_MENU_ITEMS,
  285.     msg_menu_items, &help_menu, NULL
  286.     };
  287.     /* to have the menu stack maintain order of menus upon each invokation,
  288.      * declare menu_ptr to be static and remove the following two lines
  289.      * after the declaration.
  290.      */
  291.     struct menu *menu_ptr = &msgs_menu;
  292.     msgs_menu.m_next = &help_menu;
  293.     help_menu.m_next = (struct menu *)NULL;
  294.  
  295.     if (!msg_cnt) {
  296.     print("No Messages.");
  297.     return;
  298.     }
  299.     if (fd) {
  300.     (void) sprintf(buf, "Message #%d", message+1);
  301.     if (m_item = menu_display(&menu_ptr, (struct inputevent *)event, fd))
  302.         action = m_item->mi_data;
  303.     else
  304.         return;
  305.     } else
  306.     action = event;
  307.  
  308.     if (menu_ptr == &help_menu || action == MENU_HELP) {
  309.     switch(action) {
  310.         when DEL_MSG: case UNDEL_MSG:
  311.         (void) help(fd, "menu_delete", tool_help);
  312.         when READ_MSG: (void) help(fd, "next", tool_help);
  313.         when REPL_MSG: (void) help(fd, "menu_respond", tool_help);
  314.         when SAVE_MSG: (void) help(fd, "save", tool_help);
  315.         when PRE_MSG: (void)  help(fd, "preserve", tool_help);
  316.         when PRNT_MSG: (void) help(fd, "printer", tool_help);
  317.         when MENU_HELP:
  318.         if (menu_ptr == &help_menu)
  319.             (void) help(fd, "help_menu_help_msg", tool_help);
  320.         else
  321.             (void) help(fd, "msg_menu", tool_help);
  322.     }
  323.     return;
  324.     }
  325.     set_isread(message);
  326.     if (action == SAVE_MSG) {
  327.     panel_set(msg_num_item, PANEL_VALUE, sprintf(buf, "%d", message+1), 0);
  328.     ((struct inputevent *)event)->ie_code = MS_LEFT;
  329.     do_file_dir(save_item, 0, event);
  330.     panel_set(msg_num_item, PANEL_VALUE, NO_STRING, 0);
  331.     return;
  332.     } else if (action == PRNT_MSG  || action == PRE_MSG ||
  333.            action == UNDEL_MSG || action == DEL_MSG) {
  334.     fkey_misc(action, message);
  335.     return;
  336.     }
  337.     if (isoff(glob_flags, IS_GETTING)) {
  338.     current_msg = message;
  339.     (void) do_hdrs(0, DUBL_NULL, NULL);
  340.     }
  341.     if (action == REPL_MSG) {
  342.     respond_mail(respond_item, 0, event);
  343.     return;
  344.     } else if (ison(glob_flags, IS_GETTING)) {
  345.     if (exec_pid)
  346.         /* User can read a message as long as he's not in an editor */
  347.         print("Finish editing message first");
  348.     else {
  349.         (void) do_hdrs(0, DUBL_NULL, NULL);
  350.         display_msg(message, (long)0);
  351.     }
  352.     return;
  353.     }
  354.     display_msg(current_msg, (long)0);
  355. }
  356.  
  357. /* miscellaneous function key actions there are here because the defines
  358.  * for DEL_MSG, etc are here in this file and the function is called from
  359.  * here more often.
  360.  */
  361. fkey_misc(action, message)
  362. char *action;
  363. {
  364.     int argc;
  365.     register char **argv;
  366.     char buf[30];
  367.  
  368.     print("Message #%d ", message+1);
  369.     if (action == UNDEL_MSG || action == DEL_MSG)
  370.     print_more("%sd. ", sprintf(buf, "%selete",
  371.                 (action == DEL_MSG)? "d": "und"));
  372.     else if (action == PRNT_MSG) {
  373.     print_more("sent to printer");
  374.     (void) strcpy(buf, "lpr");
  375.     } else if (action == PRE_MSG)
  376.     print_more("%sd", strcpy(buf, "preseve"));
  377.     (void) sprintf(&buf[strlen(buf)], " %d", message+1);
  378.     if (message == current_msg && action == DEL_MSG)
  379.     do_clear();
  380.  
  381.     if (argv = make_command(buf, DUBL_NULL, &argc))
  382.     (void) do_command(argc, argv, msg_list);
  383.     return;
  384. }
  385.  
  386. view_opts_menu(event, fd)
  387. struct inputevent *event;
  388. {
  389.     static char buf[5];
  390.     struct menuitem *m_item;
  391.     char *action;
  392.     static struct menuitem opts_items[] = {
  393.     { MENU_IMAGESTRING,  "Save Options",    O_SAVE  },
  394.     { MENU_IMAGESTRING,  "Restore Options",    O_RSTR  },
  395.     { MENU_IMAGESTRING,  "Quit Options",    O_QUIT  },
  396.     { MENU_IMAGESTRING,  "Help",        MENU_HELP  }
  397.     };
  398.     static struct menu msgs_menu = {
  399.         MENU_IMAGESTRING, "Options", 4, opts_items, (struct menu *)NULL, NULL
  400.     };
  401.     struct menu *menu_ptr = &msgs_menu;
  402.  
  403.     if (m_item = menu_display(&menu_ptr, event, fd))
  404.     action = m_item->mi_data;
  405.     else
  406.     return;
  407.     switch(action) {
  408.     case O_SAVE:
  409.         save_opts(0, DUBL_NULL);
  410.     when O_RSTR:
  411.         init();
  412.         if (getting_opts == 1)
  413.         view_options();
  414.         else
  415.         set_fkeys();
  416.     when O_QUIT:
  417.         do_clear();
  418.         unlock_cursors(); /* actually resets msg_win's cursor */
  419.         if (isoff(glob_flags, IS_GETTING) && msg_cnt)
  420.         if (isoff(msg[current_msg].m_flags, DELETE))
  421.             display_msg(current_msg, (long)0);
  422.         else
  423.             (void) read_mail(NO_ITEM, 0, NO_EVENT);
  424.     when MENU_HELP:
  425.         (void) help(fd, (getting_opts == 1)? "options": "fkeys", tool_help);
  426.     }
  427. }
  428.