home *** CD-ROM | disk | FTP | other *** search
/ ftp.freefriends.org / ftp.freefriends.org.tar / ftp.freefriends.org / arnold / Source / mush.rstevens.tar.gz / mush.tar / tool.c < prev    next >
C/C++ Source or Header  |  1991-05-22  |  17KB  |  626 lines

  1. /* @(#)tool.c    (c) copyright    10/15/86 (Dan Heller) */
  2.  
  3. /* tool.c --make the mailtool windows, panels, etc... */
  4. #include "mush.h"
  5.  
  6. #ifndef FONTDIR
  7. #define FONTDIR          "/usr/lib/fonts/fixedwidthfonts/"
  8. #endif /* FONTDIR */
  9.  
  10. extern void print_sigwinch(), make_hdr_sw();
  11. extern Notify_value fkey_interposer();
  12.  
  13. static void init_cursors(), geticon();
  14.  
  15. extern Panel /* panels.c */
  16.     make_hdr_panel(), make_main_panel();
  17.  
  18. Panel
  19.     main_panel,        /* the main panel dealing with generic items */
  20.     hdr_panel;        /* panel which contains message header specific items */
  21.  
  22. Textsw mfprint_sw;
  23. Frame compose_frame;
  24. int compose_destroy = 0;
  25.  
  26. static char **choice_args, **button_args;
  27.  
  28. short dat_mail_icon_1[] = {
  29. #include "mail.icon.1"
  30. };
  31.  
  32. short dat_mail_icon_2[] = {
  33. #include "mail.icon.2"
  34. };
  35.  
  36. short dat_compose_icon[] = {
  37. #include "compose.icon"
  38. };
  39.  
  40. short dat_coffee_cup[] = {
  41.     0x0200,0x0100,0x0600,0x0800,0x0600,0x0100,0xFFF8,0x800C,
  42.     0x800A,0x4012,0x401C,0x2020,0x9048,0x7FF0,0x3FE0,0x0000
  43. };
  44.  
  45. mpr_static(mail_icon_image1, 64, 64, 1, dat_mail_icon_1);
  46. mpr_static(mail_icon_image2, 64, 64, 1, dat_mail_icon_2);
  47. mpr_static(compose_icon_image, 64, 64, 1, dat_compose_icon);
  48.  
  49. mpr_static(coffee_cup,      16, 16, 1, dat_coffee_cup);
  50.  
  51. /* public for hdr_sw.c */
  52. Cursor l_cursor, m_cursor, r_cursor;
  53. static Cursor coffee;
  54.  
  55. /* text and font will be set in mail_status() */
  56. Icon mail_icon, compose_icon;
  57.  
  58. static Notify_value scroll_hdr();
  59.  
  60. make_tool()
  61. {
  62.     Rect    mrect;       /* Position and size of icon label. */
  63.     struct stat rootbuf, tmpbuf;
  64.     char    *p;
  65.     struct pixfont *pf_open();
  66.  
  67.     if (p = do_set(set_options, "font")) {
  68.     char buf[MAXPATHLEN];
  69.     (void) sprintf(buf, "%s%s", FONTDIR, p);
  70.     if (!(mush_font = pf_open(buf)))
  71.         print("couldn't open font \"%s\"\nUsing default font.\n", buf);
  72.     }
  73.     if (!mush_font)
  74.     mush_font = pf_default();
  75.  
  76.     geticon();
  77.     check_icons();
  78.  
  79.     if (p = do_set(set_options, "screen_win"))
  80.     screen = atoi(p);
  81.     else
  82.     screen = 6;
  83.  
  84.     /* where to place text on mail icon -- how many messages there are */
  85.     mrect.r_left = l_width();
  86.     mrect.r_top = 58-l_height();
  87.     mrect.r_width = 3*l_width();
  88.     mrect.r_height = l_height();
  89.     (void) icon_set(mail_icon, ICON_LABEL_RECT, &mrect, NULL);
  90.  
  91.     (void) window_set(tool,
  92.     FRAME_ICON,    mail_icon,
  93.     WIN_CONSUME_KBD_EVENTS,
  94.         WIN_LEFT_KEYS, WIN_TOP_KEYS, WIN_RIGHT_KEYS, NULL,
  95.     NULL);
  96.     (void) notify_interpose_destroy_func(tool, destroy_proc);
  97.  
  98.     choice_args = panel_make_list(
  99.     PANEL_MENU_TITLE_FONT, mush_font,
  100.     PANEL_DISPLAY_LEVEL,    PANEL_NONE,
  101.     PANEL_SHOW_MENU,    TRUE,
  102.     PANEL_SHOW_MENU_MARK,    FALSE,
  103.     NULL);
  104.  
  105.     button_args = panel_make_list(
  106.     PANEL_FEEDBACK,        PANEL_INVERTED,
  107.     PANEL_SHOW_MENU,    FALSE,
  108.     NULL);
  109.  
  110.     hdr_panel = make_hdr_panel(tool, choice_args, button_args);
  111.  
  112.     make_hdr_sw(tool);
  113.  
  114.     main_panel = make_main_panel(tool, choice_args, button_args);
  115.  
  116.     /* main mush frame text subwindow for wprint() */
  117.     mfprint_sw = window_create(tool, TEXTSW,
  118.     WIN_BELOW,                      main_panel,
  119.     WIN_HEIGHT,                     l_height() * 4,
  120.     TEXTSW_READ_ONLY,               TRUE,
  121.     TEXTSW_BLINK_CARET,             FALSE,
  122.     TEXTSW_LINE_BREAK_ACTION,       TEXTSW_WRAP_AT_CHAR,
  123.     NULL);
  124.     /* order is important -- scroll_textwin should be called first! */
  125.     (void) notify_interpose_event_func(mfprint_sw,
  126.     fkey_interposer, NOTIFY_SAFE);
  127.     (void) notify_interpose_event_func(mfprint_sw,
  128.     scroll_textwin, NOTIFY_SAFE);
  129.  
  130.     /* text subwindow for paging messages */
  131.     p = do_set(set_options, "crt_win");
  132.     pager_textsw = window_create(tool, TEXTSW,
  133.     WIN_HEIGHT,            l_height() * (p? atoi(p) : 12),
  134.     TEXTSW_READ_ONLY,        TRUE,
  135.     TEXTSW_BLINK_CARET,        FALSE,
  136. #ifdef SUN_4_0 /* SunOS 4.0+ */
  137.     TEXTSW_LINE_BREAK_ACTION,    TEXTSW_WRAP_AT_WORD,
  138. #else /* SUN_4_0 */
  139.     TEXTSW_LINE_BREAK_ACTION,    TEXTSW_WRAP_AT_CHAR,
  140. #endif /* SUN_4_0 */
  141.     NULL);
  142.     /* order is important -- scroll_textwin should be called first! */
  143.     (void) notify_interpose_event_func(pager_textsw,
  144.     fkey_interposer, NOTIFY_SAFE);
  145.     (void) notify_interpose_event_func(pager_textsw,
  146.     scroll_textwin, NOTIFY_SAFE);
  147.  
  148.     (void) sprintf(blank, "%*c", sizeof blank - 1, ' ');
  149.     mrect = *(Rect *)window_get(hdr_sw, WIN_RECT);
  150.     pw_writebackground(hdr_win, 0,0, mrect.r_width, mrect.r_height, PIX_CLR);
  151.     istool = 2;
  152.     (void) fclose(stdin);
  153.     (void) fclose(stdout);
  154. #ifndef SUN_3_5
  155.     /* SunOS 3.5 takes tty modes for ttysws from stderr. */
  156.     (void) fclose(stderr);
  157. #endif /* SUN_3_5 */
  158.     (void) do_version();
  159.     init_cursors();
  160.     timeout_cursors(TRUE);
  161.     window_fit_height(tool);
  162. }
  163.  
  164. void
  165. close_frame()
  166. {
  167.     if (do_set(set_options, "compose_icon")) {
  168.     icon_set(compose_icon, ICON_IMAGE, &compose_icon_image, NULL);
  169.     window_set(compose_frame, FRAME_CLOSED, TRUE, NULL);
  170.     } else
  171.     window_set(compose_frame, WIN_SHOW, FALSE, NULL);
  172. }
  173.  
  174. void
  175. make_compose_frame()
  176. {
  177.     char *p;
  178.     Textsw msg_sw;
  179.     Panel panel, make_compose_panel();
  180.     Notify_value compose_destroy_proc();
  181.  
  182. #ifdef SUN_3_5
  183.     if (nopenfiles(0) < 8) {
  184.     ok_box("Too many frames; close one, please.\n");
  185.     compose_frame = 0;
  186.     return;
  187.     }
  188. #endif /* SUN_3_5 */
  189.  
  190.     if (do_set(set_options, "compose_icon"))
  191.     compose_frame = window_create(NULL, FRAME,
  192.         FRAME_LABEL,        "Compose Letter",
  193.         FRAME_SHOW_LABEL,    TRUE,
  194.         FRAME_NO_CONFIRM,    TRUE,
  195.         FRAME_ICON,        compose_icon,
  196.         WIN_SHOW,        TRUE,
  197.         NULL);
  198.     else
  199.     compose_frame = window_create(tool, FRAME,
  200.         FRAME_LABEL,        "Compose Letter",
  201.         FRAME_SHOW_LABEL,    TRUE,
  202.         FRAME_NO_CONFIRM,    TRUE,
  203.         FRAME_DONE_PROC,    close_frame,
  204.         WIN_SHOW,        TRUE,
  205.         NULL);
  206.     (void) notify_interpose_destroy_func(compose_frame, compose_destroy_proc);
  207.  
  208.     panel = make_compose_panel(compose_frame, choice_args, button_args);
  209.  
  210.     /* text subwindow for composing messages */
  211.     p = do_set(set_options, "msg_win");
  212.     msg_sw = window_create(compose_frame, TEXTSW,
  213.     WIN_BELOW,            panel,
  214.     WIN_HEIGHT,            l_height() * (p? atoi(p) : 24),
  215.     TEXTSW_READ_ONLY,        TRUE, /* set to false later */
  216.     TEXTSW_BLINK_CARET,        FALSE,
  217.     TEXTSW_LINE_BREAK_ACTION,    TEXTSW_WRAP_AT_CHAR,
  218.     TEXTSW_IGNORE_LIMIT,        TEXTSW_INFINITY,
  219.     NULL);
  220.     notify_interpose_event_func(msg_sw, fkey_interposer, NOTIFY_SAFE);
  221.     notify_interpose_event_func(msg_sw, edit_msg_textwin, NOTIFY_SAFE);
  222.  
  223.     /* Assign textsw (msg_sw) to panel for panel items' callbacks */
  224.     panel_set(panel, PANEL_CLIENT_DATA, msg_sw, NULL);
  225.  
  226.     /* tty subwindow */
  227.     if (!(tty_sw = window_create(compose_frame, TTY,
  228.     TTY_QUIT_ON_CHILD_DEATH, FALSE,
  229.     TTY_ARGV,        TTY_ARGV_DO_NOT_FORK,
  230.     WIN_CLIENT_DATA,    msg_sw,
  231.     WIN_SHOW,        FALSE,
  232.     WIN_WIDTH,        WIN_EXTEND_TO_EDGE,
  233.     WIN_BELOW,        msg_sw,
  234.     NULL)))
  235.     perror("tty_sw"), cleanup(0);
  236.  
  237.     /* catch SIGTERM when tty_sw dies */
  238.     (void) signal(SIGTERM, catch);
  239.     window_fit_height(compose_frame);
  240. }
  241.  
  242. /*ARGSUSED*/
  243. void
  244. open_compose()
  245. {
  246.     if (compose_frame) {
  247.     if (do_set(set_options, "compose_icon"))
  248.         window_set(compose_frame, FRAME_CLOSED, FALSE, NULL);
  249.     else
  250.         window_set(compose_frame, WIN_SHOW, TRUE, NULL);
  251.     } else
  252.     make_compose_frame();
  253. }
  254.  
  255. void
  256. destroy_compose()
  257. {
  258.     if (!compose_destroy && compose_frame)
  259.     window_destroy(compose_frame);
  260. }
  261.  
  262. /*ARGSUSED*/
  263. Notify_value
  264. compose_destroy_proc(frame, status)
  265. Frame frame;
  266. Destroy_status status;
  267. {
  268.     if (!compose_destroy && compose_frame) {
  269.     compose_destroy++;
  270.     if (ison(glob_flags, IS_GETTING))
  271.         rm_edfile(-1);
  272.     }
  273.     return notify_next_destroy_func(frame, status);
  274. }
  275.  
  276. Panel
  277. get_compose_panel()
  278. {
  279.     Panel panel;
  280.  
  281. #ifdef SUN_4_0
  282.     if (do_set(set_options, "compose_icon"))
  283.     panel = (Panel)window_get(compose_frame, FRAME_NTH_WINDOW, 0);
  284.     else
  285.     panel = (Panel)window_get(compose_frame, FRAME_NTH_WINDOW, 1);
  286. #else
  287.     panel = (Panel)window_get(compose_frame, FRAME_NTH_WINDOW, 0);
  288. #endif /* SUN_4_0 */
  289.     return panel;
  290. }
  291.  
  292. void
  293. close_compose(item, value, event)
  294. Panel_item item;
  295. int value;
  296. Event *event;
  297. {
  298.     if (event_id(event) == MS_LEFT) {
  299.     close_frame();
  300.     return;
  301.     }
  302.     switch (value) {
  303.     case 0:
  304.         close_frame();
  305.     when 1:
  306.         destroy_compose();
  307.     when 2:
  308.         (void) help(0, "close", tool_help);
  309.     }
  310. }
  311.  
  312. parse_tool_opts(argcp, argv)
  313. int *argcp;
  314. char **argv;
  315. {
  316.     if (!(tool = window_create((Window) 0, FRAME,
  317.     FRAME_ARGC_PTR_ARGV, argcp, argv,
  318.     NULL)))
  319.     cleanup(0);
  320. }
  321.  
  322. /*
  323.  * used by both the hdr_sw (to scroll canvas) and by textsw's.
  324.  * Return values:
  325.  *  MUSH_SCROLL_TO (to scroll _to_ a particular location)
  326.  *  MUSH_SCROLL_RELATIVE (scroll relative our current location)
  327.  *  MUSH_SCROLL_IGNORE (not a scroll event and ignore it entirely (up events))
  328.  *  MUSH_SCROLL_PASS_EVENT (not a scroll event; pass it to next event handler)
  329.  * If absolute scrolling (scroll_to) then "amount" is set to 1 for beginning
  330.  * of textsw or 2 for end of textsw.
  331.  * User can precede a keyboard scrolling request by a "count" -- the
  332.  * count is typed by the user in digits: 5j = move 5 lines down.
  333.  * It is assumed that if the user moves the mouse after a digit is pressed,
  334.  * then he doesn't really want to adjust the scrolling amount and the 
  335.  * count is reset to the default (1).
  336.  */
  337. Scroll_action
  338. decode_scroll(client, event, len, amount)
  339. Notify_client client;
  340. Event    *event;
  341. int len, *amount;
  342. {
  343.     static int count;
  344.  
  345.     if (event_id(event) == LOC_MOVE) {
  346.     count = 0;
  347.     return MUSH_SCROLL_PASS_EVENT;
  348.     }
  349.  
  350.     *amount = 0;  /* Assume relative scroll */
  351.     if (ID == SCROLL_REQUEST)
  352.     return MUSH_SCROLL_PASS_EVENT;
  353.  
  354.     if (event_is_up(event))
  355.     return MUSH_SCROLL_PASS_EVENT;
  356.     if (event_is_ascii(event) && isdigit(event_id(event))) {
  357.     count = (count * 10) + event_id(event) - '0';
  358.     return MUSH_SCROLL_IGNORE;
  359.     }
  360. #ifdef SUN_4_0 /* SunOS 4.0+ */
  361.     /* returns sunview events for some ctl chars */
  362.     switch (event_action(event)) {
  363.     case ACTION_GO_LINE_FORWARD:
  364.     case ACTION_GO_COLUMN_FORWARD:
  365.         *amount = count ? count : 1;
  366.         count = 0;
  367.         return MUSH_SCROLL_RELATIVE;
  368.     case ACTION_GO_LINE_BACKWARD:
  369.     case ACTION_GO_COLUMN_BACKWARD:
  370.         *amount = count ? -count : -1;
  371.         count = 0;
  372.         return MUSH_SCROLL_RELATIVE;
  373.     case ACTION_GO_DOCUMENT_START:
  374.         *amount = 1;
  375.         count = 0;
  376.         return MUSH_SCROLL_TO;
  377.     case ACTION_GO_DOCUMENT_END:
  378.         *amount = 2;
  379.         count = 0;
  380.         return MUSH_SCROLL_TO;
  381.     }
  382. #endif /* SUN_4_0 */
  383.     /* for SunOS 3.5, assume default SunView key mapping */
  384.     /* a little redundancy for 4.0, but it's ok */
  385.     if (!event_is_ascii(event) && ID != KEY_RIGHT(14) && ID != KEY_RIGHT(8)
  386.     && ID != KEY_RIGHT(7) && ID != KEY_RIGHT(13))
  387.     /* may have to reset "count" here */
  388.     return MUSH_SCROLL_PASS_EVENT; /* Not a scroll event */
  389.     switch (event_id(event)) {
  390.     case KEY_RIGHT(7):    /* Home on new keyboards */
  391.         *amount = 1, count = 0;
  392.         return MUSH_SCROLL_TO;
  393.     case KEY_RIGHT(13):    /* End on new keyboards */
  394.         *amount = 2, count = 0;
  395.         return MUSH_SCROLL_TO;
  396.     case 'j': case KEY_RIGHT(14):    /* downarrow */
  397.         *amount = count ? count : 1;
  398.     when 'k': case KEY_RIGHT(8):    /* uparrow */
  399.         *amount = count ? -count : -1;
  400.     when 'F'-'@':    /* ^f */
  401.         *amount = count ? count * (len-1) : len - 1;
  402.     when 'D'-'@':    /* ^d */
  403.         *amount = len/2;
  404.     when 'B'-'@':    /* ^b */
  405.         *amount = -(count ? count * (1-len) : len - 1);
  406.     when 'U'-'@':    /* ^u */
  407.         *amount = -len/2;
  408.     when '\033':    /* Escape */
  409.         /* For SunOS 3.5 check to see if this is a cursor
  410.          * move key, i.e. ESC[A or ESC[B.
  411.          */
  412.         if (!(int)window_read_event(client, event) &&
  413.         event_id(event) == '[' &&
  414.         !(int)window_read_event(client, event))
  415.             if (event_id(event) == 'A') {
  416.             *amount = -1;
  417.             break;
  418.             } else if (event_id(event) == 'B') {
  419.             *amount = 1;
  420.             break;
  421.             }
  422.     default:
  423.         count = 0;
  424.         return event_is_ascii(event) ?
  425.         MUSH_SCROLL_IGNORE : MUSH_SCROLL_PASS_EVENT;
  426.     }
  427.     count = 0;
  428.     /* Scroll indicated amount if event is down, ignore up events */
  429.     return MUSH_SCROLL_RELATIVE;
  430. }
  431.  
  432. Notify_value
  433. scroll_textwin(textsw, event, arg, type)
  434. Textsw    textsw;
  435. Event    *event;
  436. Notify_arg    arg;
  437. Notify_event_type    type;
  438. {
  439.     int scroll_amount;
  440.  
  441.     switch (decode_scroll(textsw, event, textsw_screen_line_count(textsw),
  442.     &scroll_amount)) {
  443.     case MUSH_SCROLL_PASS_EVENT :
  444.         return notify_next_event_func(textsw, event, arg, type);
  445.     case MUSH_SCROLL_IGNORE:
  446.         return NOTIFY_IGNORED;
  447.     case MUSH_SCROLL_TO:
  448.         if (scroll_amount == 1)
  449.         window_set(textsw, TEXTSW_FIRST, 0, NULL);
  450.         else if (scroll_amount == 2)
  451.         window_set(textsw, TEXTSW_FIRST, TEXTSW_INFINITY, NULL);
  452.         textsw_scroll_lines(textsw, -textsw_screen_line_count(textsw));
  453.         break;
  454.     case MUSH_SCROLL_RELATIVE :
  455.         textsw_scroll_lines(textsw, scroll_amount);
  456.     }
  457.     window_set(textsw, TEXTSW_UPDATE_SCROLLBAR, NULL);
  458.     return NOTIFY_DONE;
  459. }
  460.  
  461. /*ARGSUSED*/
  462. Notify_value
  463. destroy_proc(frame, status)
  464. Frame frame;
  465. Destroy_status status;
  466. {
  467.     if (ison(glob_flags, IS_GETTING))
  468.     rm_edfile(-1);
  469.     /* status is ignored -- maybe post notice asking to confirm quit? */
  470.     if (status == DESTROY_CHECKING && ison(glob_flags, DO_UPDATE) &&
  471.     !ask("Your folder has been modified.  Quit anyway?"))
  472.     (void) notify_veto_destroy(frame);
  473.     else
  474.     cleanup(0); /* doesn't return */
  475.     return NOTIFY_DONE;
  476. }
  477.  
  478. /* Initialise the Mush mail icon. */
  479. static void
  480. geticon()
  481. {
  482.     static Rect lrect = { 5, 5, 26, 12 };
  483.  
  484.     mail_icon = icon_create(
  485.     ICON_WIDTH,        64,
  486.     ICON_HEIGHT,        64,
  487.     ICON_FONT,        mush_font,
  488.     ICON_IMAGE,        &mail_icon_image1,
  489.     ICON_LABEL,        "",
  490.     ICON_LABEL_RECT,    &lrect,
  491.     0);
  492.     compose_icon = icon_create(
  493.     ICON_WIDTH,        64,
  494.     ICON_HEIGHT,        64,
  495.     ICON_IMAGE,        &compose_icon_image,
  496.     ICON_LABEL,        "",
  497.     0);
  498. }
  499.  
  500. /* Initialise all the cursors used. */
  501. static void
  502. init_cursors()
  503. {
  504.     extern Pixrect mouse_left, mouse_middle, mouse_right, bent_arrow;
  505.     extern Cursor bentarrow;
  506.  
  507.     l_cursor = cursor_create(
  508.     CURSOR_XHOT,    3,
  509.     CURSOR_YHOT,    3,
  510.     CURSOR_OP,    PIX_SRC,
  511.     CURSOR_IMAGE,    &mouse_left,
  512.     NULL);
  513.     m_cursor = cursor_create(
  514.     CURSOR_XHOT,    3,
  515.     CURSOR_YHOT,    3,
  516.     CURSOR_OP,    PIX_SRC,
  517.     CURSOR_IMAGE,    &mouse_middle,
  518.     NULL);
  519.     r_cursor = cursor_create(
  520.     CURSOR_XHOT,    3,
  521.     CURSOR_YHOT,    3,
  522.     CURSOR_OP,    PIX_SRC,
  523.     CURSOR_IMAGE,    &mouse_right,
  524.     NULL);
  525.     bentarrow = cursor_create(
  526.     CURSOR_XHOT,    8,
  527.     CURSOR_YHOT,    8,
  528.     CURSOR_OP,    PIX_SRC|PIX_DST,
  529.     CURSOR_IMAGE,    &bent_arrow,
  530.     NULL);
  531.     coffee = cursor_create(
  532.     CURSOR_XHOT,    8,
  533.     CURSOR_YHOT,    8,
  534.     CURSOR_OP,    PIX_SRC,
  535.     CURSOR_IMAGE,    &coffee_cup,
  536.     NULL);
  537. }
  538.  
  539. /* show the timeout cursor (coffee cup) when "on" is TRUE.  This routine
  540.  * may be called many times in layers of locking mechanisms, so be careful
  541.  * not to unlock cursors until "on" has been FALSE as many times as it has
  542.  * been TRUE.
  543.  */
  544. void
  545. timeout_cursors(on)
  546. int on;
  547. {
  548.     Window win;
  549.     Frame subframe;
  550.     static int locked, numwins;
  551.     int i = 0, j;
  552.     static struct {
  553.     Cursor cursor;
  554.     Window win;
  555.     } win_curs[64];
  556.  
  557.     on? locked++ : locked--;
  558.     if (istool < 2 || locked > 1 || locked == 1 && on == 0)
  559.     return;
  560.     if (on) {
  561.     for (numwins = 0; win = window_get(tool, FRAME_NTH_SUBWINDOW, numwins);
  562.         numwins++) {
  563.         win_curs[numwins].cursor =
  564.                 cursor_copy((Cursor) window_get(win, WIN_CURSOR));
  565.         win_curs[numwins].win = win;
  566.         window_set(win, WIN_CURSOR, coffee, NULL);
  567.     }
  568.     while (subframe = window_get(tool, FRAME_NTH_SUBFRAME, i++))
  569.         for (j = 0; win = window_get(subframe, FRAME_NTH_SUBWINDOW, j);
  570.             j++,numwins++) {
  571.         win_curs[numwins].cursor =
  572.                 cursor_copy((Cursor) window_get(win, WIN_CURSOR));
  573.         win_curs[numwins].win = win;
  574.         window_set(win, WIN_CURSOR, coffee, NULL);
  575.         }
  576.     } else {
  577.     for (j = 0; j < numwins; j++) {
  578.         window_set(win_curs[j].win, WIN_CURSOR, win_curs[j].cursor, NULL);
  579.         cursor_destroy(win_curs[j].cursor);
  580.     }
  581.     }
  582. }
  583.  
  584. /*
  585.  * If the user has specified an alternate icon or set of icons in
  586.  * his .mushrc file, copy the image(s) over the defaults.
  587.  */
  588. void
  589. check_icons()
  590. {
  591.     Pixrect *icon_mpr;
  592.     char errbuf[256], *icon_file, *icon_path;
  593.     int isdir;
  594.  
  595.     if ((icon_file = do_set(set_options, "mail_icon")) && *icon_file) {
  596.     isdir = 0;
  597.     icon_path = getpath(icon_file, &isdir);
  598.     if (isdir == 0) {
  599.         if (!(icon_mpr = icon_load_mpr(icon_path, errbuf)))
  600.         error("Error loading mail icon file:\n%s",errbuf);
  601.         else
  602.         pr_rop(&mail_icon_image1, 0,0,64,64, PIX_SRC, icon_mpr, 0, 0);
  603.     }
  604.     }
  605.     if ((icon_file = do_set(set_options, "newmail_icon")) && *icon_file) {
  606.     isdir = 0;
  607.     icon_path = getpath(icon_file, &isdir);
  608.     if (isdir == 0) {
  609.         if (!(icon_mpr = icon_load_mpr(icon_path, errbuf)))
  610.         error("Error loading newmail icon file:\n%s",errbuf);
  611.         else
  612.         pr_rop(&mail_icon_image2, 0,0,64,64, PIX_SRC, icon_mpr, 0, 0);
  613.     }
  614.     }
  615.     if ((icon_file = do_set(set_options, "compose_icon")) && *icon_file) {
  616.     isdir = 0;
  617.     icon_path = getpath(icon_file, &isdir);
  618.     if (isdir == 0) {
  619.         if (!(icon_mpr = icon_load_mpr(icon_path, errbuf)))
  620.         error("Error loading newmail icon file:\n%s",errbuf);
  621.         else
  622.         pr_rop(&compose_icon_image, 0,0,64,64, PIX_SRC, icon_mpr, 0, 0);
  623.     }
  624.     }
  625. }
  626.