home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume18 / mush6.4 / part06 / select.c < prev    next >
C/C++ Source or Header  |  1989-03-12  |  13KB  |  429 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)
  111.             count = 1;
  112.         if (ID == 'k' || ID == 'K' || ID == '-')
  113.             scroll_win(-count);
  114.         else if (ID == '\n' || ID == '\r' || ID == 'j' ||
  115.              ID == 'J' || ID == '+')
  116.             scroll_win(count);
  117.         else if (ID == ' ')
  118.             scroll_win(crt-3);
  119.         else if ((ID == 'q' || ID == 'Q') &&
  120.             ison(glob_flags, IS_GETTING)) {
  121.             pr_destroy(msg_pix), msg_pix = (struct pixrect *)NULL;
  122.             win_setcursor(msg_sw->ts_windowfd, &write_cursor);
  123.             txt.x = 5, txt.y = msg_rect.r_height - l_height(curfont);
  124.             wprint("\n(continue editing letter)\n");
  125.             clr_bot_line();
  126.             type_cursor(PIX_SRC);
  127.         }
  128.         }
  129.     /*
  130.      * If msg_pix is NULL, then we are not reading a message. If we are
  131.      * editing a letter, then enter the keys typed.  If we are doing
  132.      * nothing, ignore this input.
  133.      */
  134.     else if (ison(glob_flags, IS_GETTING)) {
  135.         type_cursor(PIX_XOR);
  136.         if (lastchar != ltchars.t_lnextc &&
  137.         (ID == tchars.t_intrc || ID == tchars.t_quitc)) {
  138.             (void) rite(_tty.sg_kill);
  139.             (void) rm_edfile(SIGINT);
  140.         } else {
  141.         register int n = 1;
  142.         if (ID == tchars.t_eofc && txt.x == 5
  143.             || (p = rite((char)ID)) && !(n = add_to_letter(p)))
  144.             finish_up_letter();
  145.         else if (n > 0)
  146.             type_cursor(PIX_XOR);
  147.         }
  148.     }
  149.     lastchar = ID;
  150.     } else switch(ID) {
  151.     when MS_LEFT : case MS_MIDDLE:
  152.         if (getting_opts == 2)
  153.         if (ID == MS_LEFT)
  154.             set_key(NULL, event.ie_locx, event.ie_locy);
  155.         else {
  156.             register char *p = find_key(event.ie_locx, event.ie_locy);
  157.             if (p)
  158.             print("Function key %s:  %s", p, key_set_to(p));
  159.         }
  160.         else if (getting_opts) {
  161.         int y = event.ie_locy - 50;
  162.         if (y < -24)
  163.             break;
  164.         if (y < 0) {
  165.             register int x = event.ie_locx;
  166.             register int X = 60*l_width(LARGE);
  167.             if (x >= X && x <= X+16)
  168.             display_opts(-1); /* scroll options back one value */
  169.             else if (x >= X+20 && x <= X+36)
  170.             display_opts(1); /* scroll options forward one value */
  171.             break;
  172.         }
  173.         /* the user was typing something -- stopped by using mouse */
  174.         if (txt.x > 5) {
  175.             type_cursor(PIX_CLR);
  176.             (void) rite(_tty.sg_kill), txt.x = 5;
  177.             option_line(line), display_opts(0);
  178.         }
  179.             line = y/20;
  180.         if (ID == MS_LEFT)
  181.             toggle_opt(line);
  182.         help_opt(line);   /* display help (short info) in both cases */
  183.         } else if (msg_pix)
  184.         if (ID == MS_LEFT)
  185.             scroll_win(crt-3);
  186.         else
  187.             scroll_win(-(crt-3));
  188.     when MS_RIGHT:
  189.         if (getting_opts)
  190.         (void) view_opts_menu(&event, gfxsw->gfx_windowfd);
  191.         else if (isoff(glob_flags, IS_GETTING))
  192.         (void) do_menu(&event, gfxsw->gfx_windowfd, current_msg);
  193.         else
  194.         (void) edit_menu(&event, gfxsw->gfx_windowfd);
  195.     otherwise: ;
  196.     }
  197.     *ibits = *obits = *ebits = 0;
  198. }
  199.  
  200. struct cursor *mice[3] = { &l_cursor, &m_cursor, &r_cursor };
  201.  
  202. hdr_io(gfxsw, ibits, obits, ebits, sw_timer)
  203. register struct gfxsubwindow *gfxsw;
  204. int *ibits,*obits,*ebits;
  205. struct timeval **sw_timer;
  206. {
  207.     static int         which_cursor;
  208.     struct inputmask     im;
  209.     struct inputevent     event;
  210.     int         line;
  211.  
  212.     if (*ibits & ~(1 << gfxsw->gfx_windowfd)) {
  213.     *ibits = *obits = *ebits = 0;
  214.     return;
  215.     }
  216.     /* make curosr change which button is lit */
  217.     win_setcursor(gfxsw->gfx_windowfd, mice[which_cursor]);
  218.  
  219.     which_cursor = (which_cursor+1) % 3;
  220.     if (input_readevent(hdr_sw->ts_windowfd, &event) == -1) {
  221.     error("input event");
  222.     return;
  223.     }
  224.     /* I'm not sure why I have to do this.
  225.      * I'm doing it because sometimes the IO hangs completely and no input
  226.      * is accepted. What I do here is get the current mask, save it, then
  227.      * reset it. This action seems to flush the IO queue, and I don't have hung
  228.      * IO anymore.  This shouldn't be necessary, but it appears to work.
  229.      * (occurances have droped about 90%)
  230.      */
  231.     if (ID == LOC_WINENTER) {
  232.     int x;
  233.     win_getinputmask(gfxsw->gfx_windowfd, &im, &x);
  234.     win_setinputmask(hdr_sw->ts_windowfd, &im, &im, x);
  235.     }
  236.     /* just return -- we just wanted to make the cursor flicker */
  237.     if (ID == LOC_STILL || ID == LOC_MOVE || ID == LOC_WINENTER) {
  238.     *ibits = *obits = *ebits = 0;
  239.     return;
  240.     }
  241.     line = event.ie_locy / l_height(DEFAULT);
  242.     if (ID >= KEY_LEFTFIRST)
  243.     (void) func_key(ID);
  244.     else if (n_array[line] > msg_cnt)
  245.     if (!msg_cnt)
  246.         print("-- You have no messages -- ");
  247.     else
  248.         print("Message out of range.  Place mouse over a legal message.");
  249.     else switch(ID) {
  250.     when MS_LEFT: case MS_MIDDLE:
  251.         (void) do_menu((ID == MS_LEFT)? READ_MSG: DEL_MSG, 0,n_array[line]);
  252.     when MS_RIGHT:
  253.         (void) do_menu(&event, gfxsw->gfx_windowfd, n_array[line]);
  254.     otherwise : print("Unkown ID = %d", ID);
  255.     }
  256.     *ibits = *obits = *ebits = 0;
  257. }
  258.  
  259. /* if "fd" is 0, then event points to the action to be taken.
  260.  * otherwise, determine action to be taken by displaying a menu.
  261.  * message is the number current_msg should be changed to (may be the same).
  262.  */
  263. do_menu(event, fd, message)
  264. caddr_t event;
  265. {
  266.     static char buf[20];
  267.     struct menuitem *m_item;
  268.     char *action;
  269.     static struct menuitem msg_menu_items[] = {
  270.     { MENU_IMAGESTRING,  "Read",     READ_MSG   },
  271.     { MENU_IMAGESTRING,  "Delete",   DEL_MSG    },
  272.     { MENU_IMAGESTRING,  "Undelete", UNDEL_MSG  },
  273.     { MENU_IMAGESTRING,  "Reply",    REPL_MSG   },
  274.     { MENU_IMAGESTRING,  "Save",     SAVE_MSG   },
  275.     { MENU_IMAGESTRING,  "Preserve", PRE_MSG    },
  276.     { MENU_IMAGESTRING,  "Print",    PRNT_MSG   },
  277.     { MENU_IMAGESTRING,  "Help",     MENU_HELP  }
  278.     };
  279.     static struct menu help_menu = {
  280.         MENU_IMAGESTRING, "Item Help",
  281.     N_MENU_ITEMS, msg_menu_items,
  282.     (struct menu *)NULL, NULL
  283.     };
  284.     static struct menu msgs_menu = {
  285.         MENU_IMAGESTRING, buf, N_MENU_ITEMS,
  286.     msg_menu_items, &help_menu, NULL
  287.     };
  288.     /* to have the menu stack maintain order of menus upon each invokation,
  289.      * declare menu_ptr to be static and remove the following two lines
  290.      * after the declaration.
  291.      */
  292.     struct menu *menu_ptr = &msgs_menu;
  293.     msgs_menu.m_next = &help_menu;
  294.     help_menu.m_next = (struct menu *)NULL;
  295.  
  296.     if (!msg_cnt) {
  297.     print("No Messages.");
  298.     return;
  299.     }
  300.     if (fd) {
  301.     (void) sprintf(buf, "Message #%d", message+1);
  302.     if (m_item = menu_display(&menu_ptr, (struct inputevent *)event, fd))
  303.         action = m_item->mi_data;
  304.     else
  305.         return;
  306.     } else
  307.     action = event;
  308.  
  309.     if (menu_ptr == &help_menu || action == MENU_HELP) {
  310.     switch(action) {
  311.         when DEL_MSG: case UNDEL_MSG:
  312.         (void) help(fd, "menu_delete", tool_help);
  313.         when READ_MSG: (void) help(fd, "next", tool_help);
  314.         when REPL_MSG: (void) help(fd, "menu_respond", tool_help);
  315.         when SAVE_MSG: (void) help(fd, "save", tool_help);
  316.         when PRE_MSG: (void)  help(fd, "preserve", tool_help);
  317.         when PRNT_MSG: (void) help(fd, "printer", tool_help);
  318.         when MENU_HELP:
  319.         if (menu_ptr == &help_menu)
  320.             (void) help(fd, "help_menu_help_msg", tool_help);
  321.         else
  322.             (void) help(fd, "msg_menu", tool_help);
  323.     }
  324.     return;
  325.     }
  326.     set_isread(message);
  327.     if (action == SAVE_MSG) {
  328.     panel_set(msg_num_item, PANEL_VALUE, sprintf(buf, "%d", message+1), 0);
  329.     ((struct inputevent *)event)->ie_code = MS_LEFT;
  330.     do_file_dir(save_item, 0, event);
  331.     panel_set(msg_num_item, PANEL_VALUE, NO_STRING, 0);
  332.     return;
  333.     } else if (action == PRNT_MSG  || action == PRE_MSG ||
  334.            action == UNDEL_MSG || action == DEL_MSG) {
  335.     fkey_misc(action, message);
  336.     return;
  337.     }
  338.     if (isoff(glob_flags, IS_GETTING)) {
  339.     current_msg = message;
  340.     (void) do_hdrs(0, DUBL_NULL, NULL);
  341.     }
  342.     if (action == REPL_MSG) {
  343.     respond_mail(respond_item, 0, event);
  344.     return;
  345.     } else if (ison(glob_flags, IS_GETTING)) {
  346.     if (exec_pid)
  347.         /* User can read a message as long as he's not in an editor */
  348.         print("Finish editing message first");
  349.     else {
  350.         (void) do_hdrs(0, DUBL_NULL, NULL);
  351.         display_msg(message, (long)0);
  352.     }
  353.     return;
  354.     }
  355.     display_msg(current_msg, (long)0);
  356. }
  357.  
  358. /* miscellaneous function key actions there are here because the defines
  359.  * for DEL_MSG, etc are here in this file and the function is called from
  360.  * here more often.
  361.  */
  362. fkey_misc(action, message)
  363. char *action;
  364. {
  365.     int argc;
  366.     register char **argv;
  367.     char buf[30];
  368.  
  369.     print("Message #%d ", message+1);
  370.     if (action == UNDEL_MSG || action == DEL_MSG)
  371.     print_more("%sd. ", sprintf(buf, "%selete",
  372.                 (action == DEL_MSG)? "d": "und"));
  373.     else if (action == PRNT_MSG) {
  374.     print_more("sent to printer");
  375.     (void) strcpy(buf, "lpr");
  376.     } else if (action == PRE_MSG)
  377.     print_more("%sd", strcpy(buf, "preserve"));
  378.     (void) sprintf(&buf[strlen(buf)], " %d", message+1);
  379.     if (message == current_msg && action == DEL_MSG)
  380.     do_clear();
  381.  
  382.     if (argv = make_command(buf, DUBL_NULL, &argc))
  383.     (void) do_command(argc, argv, msg_list);
  384.     return;
  385. }
  386.  
  387. view_opts_menu(event, fd)
  388. struct inputevent *event;
  389. {
  390.     static char buf[5];
  391.     struct menuitem *m_item;
  392.     char *action;
  393.     static struct menuitem opts_items[] = {
  394.     { MENU_IMAGESTRING,  "Save Options",    O_SAVE  },
  395.     { MENU_IMAGESTRING,  "Restore Options",    O_RSTR  },
  396.     { MENU_IMAGESTRING,  "Quit Options",    O_QUIT  },
  397.     { MENU_IMAGESTRING,  "Help",        MENU_HELP  }
  398.     };
  399.     static struct menu msgs_menu = {
  400.         MENU_IMAGESTRING, "Options", 4, opts_items, (struct menu *)NULL, NULL
  401.     };
  402.     struct menu *menu_ptr = &msgs_menu;
  403.  
  404.     if (m_item = menu_display(&menu_ptr, event, fd))
  405.     action = m_item->mi_data;
  406.     else
  407.     return;
  408.     switch(action) {
  409.     case O_SAVE:
  410.         save_opts(0, DUBL_NULL);
  411.     when O_RSTR:
  412.         init();
  413.         if (getting_opts == 1)
  414.         view_options();
  415.         else
  416.         set_fkeys();
  417.     when O_QUIT:
  418.         do_clear();
  419.         unlock_cursors(); /* actually resets msg_win's cursor */
  420.         if (isoff(glob_flags, IS_GETTING) && msg_cnt)
  421.         if (isoff(msg[current_msg].m_flags, DELETE))
  422.             display_msg(current_msg, (long)0);
  423.         else
  424.             (void) read_mail(NO_ITEM, 0, NO_EVENT);
  425.     when MENU_HELP:
  426.         (void) help(fd, (getting_opts == 1)? "options": "fkeys", tool_help);
  427.     }
  428. }
  429.