home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / g / gs / !GS / ps / Source / WimpPlus / c / wimpio < prev    next >
Encoding:
Text File  |  1991-12-05  |  22.9 KB  |  798 lines

  1. /* wimpio.c */
  2.  
  3. /* Copyright (C) David Elworthy 1991. No warranty is given on this code. */
  4.  
  5. /*
  6.    1.0  --  April 1991  --  First working version
  7.    2.0  --  July  1991  --  Added extra handle to w_event
  8.                         --  Allow file drop on read window
  9.                         --  Use control block
  10.    2.1  --  Oct   1991  --  Change drop handler
  11.                             Reading from input icon changed
  12.    2.2   -- Dec   1991   -- Fix menu bug: menus can now only be put up
  13.                             when we are waiting for input.
  14.  
  15.  * This file contains code for implementing printf and read via the WIMP.
  16.  * The external functions, create, show, hide and delete the printf
  17.  * window.
  18.  * It would be nice to implement scanf as well, but the lack of a vsscanf function
  19.  * in the ANSI library makes this next to impossible.
  20.  *
  21.  * PRINTF
  22.  * We keep a buffer of text in memory. On a redraw event, we plot it into the
  23.  * window.
  24.  * The text is held as an array of characters, with newlines as character
  25.  * separators. Control characters are kept in the text but not displayed.
  26.  * This allows us to use a buffer supplied by the user.
  27.  *
  28.  * In plotting, we have line breaks on newlines and on filling the width of the
  29.  * work area. To allow for mode changes, the physical line length is
  30.  * recalculated every time. We assume the window work area will not change --
  31.  * reasonable in most cases.
  32.  *
  33.  * READ
  34.  * Input is read through a writeable icon in a window, returning on return or OK.
  35.  * The text is read into a local buffer initially. Close or CANCEL causes the function
  36.  * to return as if there had been no input.
  37.  * If there are any extra icons, then a click on them has the same effect as entering their
  38.  * text into the writeable icon. This applies for icons number > the input icon.
  39.  */
  40.  
  41.  
  42. #include "wimp.h"
  43. #include "wimpt.h"
  44. #include "win.h"
  45. #include "template.h"
  46. #include "werr.h"
  47. #include "bbc.h"
  48. #include "coords.h"
  49. #include "event.h"
  50. #include "heap.h"
  51. #include "xferrecv.h"
  52. #include "baricon.h"
  53. #include "menu.h"
  54.  
  55. #include <stdio.h>
  56. #include <stdlib.h>
  57. #include <string.h>
  58. #include <stdarg.h>
  59. #include "wimpio.h"
  60.  
  61. /*---------------------------------------- CONTROL BLOCK---------------------------------*/
  62.  
  63. wimpio_cb wimpio_control =
  64. {
  65.     -1,    /* Printf window handle */
  66.     -1     /* Read window handle */
  67. };
  68.  
  69. /* Close icon string */
  70. static char *close_string = NULL;
  71.  
  72. /*---------------------------------------- COMMON ----------------------------------------*/
  73.  
  74. /* Show the window */
  75. static void w_show(BOOL exists, wimp_w handle)
  76. {
  77.     wimp_wstate  state;
  78.  
  79.     if (exists)
  80.     {
  81.         /* Get the state of the window */
  82.         if (wimpt_complain(wimp_get_wind_state(handle, &state)) == 0)
  83.         {
  84.             state.o.behind = -1;          /* Make sure window is opened in front */
  85.             wimpt_noerr(wimp_open_wind(&state.o));
  86.         }
  87.     }
  88. }
  89.  
  90. /* Hide the window */
  91. static void w_hide(BOOL exists, wimp_w handle)
  92. {
  93.     if (exists)
  94.         wimpt_noerr(wimp_close_wind(handle));
  95. }
  96.  
  97. /* Delete the window */
  98. static void w_delete(BOOL *exists, wimp_w *handle)
  99. {
  100.     if (*exists)
  101.     {
  102.         wimpt_noerr(wimp_delete_wind(*handle));
  103.         *handle = -1;
  104.         *exists = FALSE;
  105.         win_activedec();
  106.     }
  107. }
  108.  
  109. void w_event(wimp_eventstr *e, w_redraw_fn redraw, BOOL *closed, void *handle)
  110. {
  111.     if (closed) *closed = FALSE;
  112.  
  113.     /* Deal with event */
  114.     switch (e->e)
  115.     {
  116.         case wimp_EREDRAW:
  117.         {
  118.             int            more;
  119.             wimp_redrawstr r;
  120.  
  121.             wimpt_checkmode(); /* This means wimpt_mode will work */
  122.  
  123.             r.w = e->data.o.w;
  124.             wimpt_noerr(wimp_redraw_wind(&r, &more));
  125.             while (more)
  126.             {
  127.                 if (redraw != NULL) redraw(&r, handle);
  128.                 wimp_get_rectangle(&r, &more);
  129.             }
  130.             break;
  131.         }
  132.  
  133.         case wimp_EOPEN: /* Pass on open request */
  134.             wimpt_noerr(wimp_open_wind(&e->data.o));
  135.             break;
  136.  
  137.         case wimp_ECLOSE:
  138.             wimpt_noerr(wimp_close_wind(e->data.o.w));
  139.             if (closed) *closed = TRUE;
  140.             break;
  141.  
  142.         default:   /* Ignore any other event */
  143.             break;
  144.     }
  145. }
  146.  
  147. /* Standard window creator */
  148. wimp_w w_create(char *title, char *templatename, int *nicons)
  149. {
  150.     wimp_wind *window;    /* Pointer to window definition */
  151.     wimp_w    handle;
  152.  
  153.     /* Find template for the window */
  154.     window = template_syshandle(templatename);
  155.     if (window == 0)
  156.     {
  157.         werr(0, "Template not found");
  158.         return -1;
  159.     }
  160.  
  161.     /* Set title string (must be indirect and long enough) */
  162.     strcpy(window->title.indirecttext.buffer, title);
  163.  
  164.     /* Create the window, dealing with errors */
  165.     if (wimpt_complain(wimp_create_wind(window, &handle)))
  166.         return -1;
  167.  
  168.     win_activeinc();
  169.     if (nicons) *nicons = window->nicons;
  170.     return handle;
  171. }
  172.  
  173. /*---------------------------------------- PRINTF ----------------------------------------*/
  174.  
  175. /* Flag - does window exist */
  176. static BOOL printf_window_exists = FALSE;
  177.  
  178. /* Bottom left of window work area, and width */
  179. static int wa_base, wa_left, wa_width;
  180.  
  181. /* Buffer for text - may be supplied by user */
  182. static char *main_buffer = NULL;
  183. static int  main_end; /* Index of terminating null */
  184. static int  main_buf_len = 0;
  185. static BOOL locally_allocated = FALSE;
  186.  
  187. #define BUF_LEN_DEFAULT 10000
  188.  
  189. /* Size of the local buffer for wimpio */
  190. #define MAX_LOCAL_BUFFER 4096
  191.  
  192. /* Main part of the display routine */
  193. /* Must be a null at buffer[len], i.e. length including null = len+1 */
  194. static void low_w_write(char *buffer, int len)
  195. {
  196.     len += 1; /* Output length including null */
  197.  
  198.     /* Transfer to main buffer. First check it will all fit */
  199.     if (len > main_buf_len)
  200.     {
  201.         /* Replace entire main buffer */
  202.         strcpy(main_buffer, buffer + len - main_buf_len);
  203.         main_end = main_buf_len-1;
  204.     }
  205.     else
  206.     {
  207.         if (main_end + len > main_buf_len)
  208.         {   /* Move existing text up */
  209.             char *to   = main_buffer;
  210.             char *from = main_buffer + len + main_end - main_buf_len;
  211.             while (*from) *to++ = *from++;
  212.             strcpy(to, buffer);
  213.             main_end = main_buf_len - 1;
  214.         }
  215.         else
  216.         {
  217.             /* Text will fit */
  218.             strcpy(main_buffer+main_end, buffer);
  219.             main_end += len - 1;
  220.         }
  221.     }
  222.  
  223.     /* Force redraw */
  224.     {   wimp_redrawstr r;
  225.         r.w = wimpio_control.printf_win_handle;
  226.         r.box.x0 = r.box.y0 = -1000000;
  227.         r.box.x1 = r.box.y1 =  1000000;
  228.         wimpt_noerr(wimp_force_redraw(&r));
  229.     }
  230.  
  231. /* printf interface */
  232. int wprintf(const char *format, va_list arg)
  233. {
  234.     char    local_buffer[MAX_LOCAL_BUFFER];
  235.     int     chars_out;
  236.  
  237.     chars_out = vsprintf(local_buffer, format, arg);
  238.  
  239.     if (chars_out >= MAX_LOCAL_BUFFER)
  240.     {   /* Dangerous error, but untrappable! */
  241.         werr(0, "Warning: local buffer overflowed. Who know what might happen now!");
  242.     }
  243.     else
  244.         low_w_write(local_buffer, chars_out);
  245.     return chars_out;
  246. }
  247.  
  248. /* write interface */
  249. void w_write(char *buffer, int bufflen)
  250. {
  251.     if (buffer[bufflen - 1] == 0)
  252.         low_w_write(buffer, bufflen-1);
  253.     else
  254.     {
  255.         char local_buffer[MAX_LOCAL_BUFFER];
  256.  
  257.         memcpy(local_buffer, buffer, bufflen);
  258.         local_buffer[bufflen] = 0;
  259.         low_w_write(local_buffer, bufflen);
  260.     }
  261. }
  262.  
  263. /* Given an address of the last character in some text (e.g. just before \n),
  264.    this returns the start of the line (at \n, or start of buffer - 1),
  265.    and the number of physical lines it represents, excluding newline effect.
  266.    The number of lines is 1 for an empty line, or for 1...line_length
  267.    characters.
  268. */
  269. static char *find_lines(char *end, int line_length, int *lines)
  270. {
  271.     char *c;
  272.     int  chars = 0;
  273.  
  274.     /* Scan back for start, counting non-control characters */
  275.     for (c = end ; c - main_buffer >= 0 && *c != '\n' ; c--)
  276.         if (*c >= ' ') chars += 1;
  277.  
  278.     /* Lines is chars / line_length, rounded up. Special case for zero characters */
  279.     if (chars == 0) *lines = 1;
  280.     else *lines = (chars + line_length - 1) / line_length;
  281.  
  282.     return c;
  283. }
  284.  
  285. /* Given the address of the start of a line, returns the the end of it
  286.    as an index: either the line length or where the \n is.
  287. */
  288. static int find_line_end(char *c, int line_length)
  289. {
  290.     int index;
  291.  
  292.     for (index = 0 ; *c != 0 && *c != '\n' && index < line_length ; c++)
  293.         if (*c >= ' ') index += 1;
  294.     return index;
  295. }
  296.  
  297. /* Draw the text window */
  298. static void wprintf_draw(wimp_redrawstr *r, void *handle)
  299. {
  300.     int        xgap, ygap; /* Character spacings */
  301.     coords_pointstr base;  /* BL of clip region (widened) */
  302.     coords_cvtstr *cvt = (coords_cvtstr *)&(r->box);
  303.     div_t      d;
  304.     int        xpos, ypos, maxx, line_length, lines;
  305.     int        yline = 0;
  306.     int        endy;
  307.     char       *c;
  308.  
  309.     handle = handle;
  310.  
  311.     /* Calculate character gaps in OS units */
  312.     xgap  = bbc_vduvar(bbc_GCharSpaceX) << bbc_vduvar(bbc_XEigFactor);
  313.     ygap  = bbc_vduvar(bbc_GCharSpaceY) << bbc_vduvar(bbc_YEigFactor);
  314.  
  315.     /* Find line length */
  316.     line_length = wa_width / xgap;
  317.  
  318.     /* Convert clip window (screen coords) to work area coords */
  319.     base.x = r->g.x0;
  320.     base.y = r->g.y0;
  321.     coords_point_toworkarea(&base, cvt);
  322.  
  323.     /* Widen to character boundary relative to BL of work area */
  324.     d       = div(base.x - wa_left , xgap);
  325.     base.x -= d.rem;
  326.     d       = div(base.y - wa_base , ygap);
  327.     base.y -= d.rem;
  328.  
  329.     /* Change BL of widended box to a character position in the buffer */
  330.     xpos = base.x / xgap;
  331.     ypos = base.y / ygap;
  332.  
  333.     /* Set base coordinate - x from clip region, y from work area */
  334.     base.y = wa_base;
  335.     coords_point_toscreen(&base, cvt);
  336.  
  337.     c = main_buffer + main_end;
  338.     if (*(c-1) == '\n') c -= 1;
  339.  
  340.     endy = r->g.y1 + ygap;                         /* y coord at which to stop */
  341.     maxx = xpos + (r->g.x1 - base.x + xgap) / xgap; /* Max index to display */
  342.  
  343.     /* Display lines until out of clip window */
  344.     while (base.y < endy)
  345.     {
  346.         int   len;
  347.         char  *end = c - 1;
  348.  
  349.         c       = find_lines(end, line_length, &lines);
  350.         yline  += lines;
  351.         base.y += ygap * lines;
  352.  
  353.         /* Display if line is not empty ... */
  354.         if (c < end)
  355.         {
  356.             /* ... and if in clip region */
  357.             if (yline >= ypos)
  358.             {
  359.                 char *from = c + 1;
  360.                 int   y1 = base.y;
  361.  
  362.                 do
  363.                 {
  364.                     /* Get a physical line to display, unless empty */
  365.                     if (*from != '\n')
  366.                     {
  367.                         len = find_line_end(from, line_length);
  368.  
  369.                         /* Check there is enough text on the line */
  370.                         if (len >= xpos)
  371.                         {
  372.                             int limit = (len < maxx) ? len : maxx;
  373.                             int index = xpos - 1;
  374.  
  375.                             /* Display text */
  376.                             bbc_move(base.x, y1);
  377.                             while (++index < limit)
  378.                                 if (from[index] >= ' ') bbc_vdu(from[index]);
  379.                         }
  380.  
  381.                         y1   -= ygap;
  382.                         from += len;
  383.                     }
  384.                 } while (--lines > 0);
  385.             }
  386.         }
  387.     }
  388. }
  389.  
  390. /***************************** WINDOW FUNCTIONS *****************************/
  391.  
  392. static void wprintf_event_handler(wimp_eventstr *e, void *handle)
  393. {
  394.     /* Deal with close event */
  395.     if (e->e == wimp_ECLOSE && close_string != NULL)
  396.         wread_fake_input(close_string);
  397.     else
  398.         w_event(e, wprintf_draw, NULL, handle);
  399. }
  400.  
  401. int wprintf_create(char *title, char *buffer, int bufflen)
  402. {
  403.     wimp_wind *window;    /* Pointer to window definition */
  404.  
  405.     /* Do nothing if already initialised */
  406.     if (printf_window_exists) return TRUE;
  407.  
  408.     /* Allocate buffer if asked to */
  409.     if (buffer == NULL)
  410.     {
  411.         if (bufflen == 0) bufflen = BUF_LEN_DEFAULT;
  412.         if ((buffer = heap_alloc(bufflen)) == NULL)
  413.         {
  414.             werr(0, "Unable to allocate memory for buffer");
  415.             return FALSE;
  416.         }
  417.         locally_allocated = TRUE;
  418.     }
  419.     main_buffer  = buffer;
  420.     main_buf_len = bufflen;
  421.     main_buffer[0] = 0;
  422.     main_end       = 0;
  423.  
  424.     /* Find template for the window */
  425.     window = template_syshandle("wprintf");
  426.     if (window == 0)
  427.     {
  428.         werr(0, "Template wprintf not found");
  429.         return FALSE;
  430.     }
  431.  
  432.     /* Set title string (must be indirect and long enough) */
  433.     strcpy(window->title.indirecttext.buffer, title);
  434.  
  435.     /* Note work area sizes */
  436.     wa_left  = window->ex.x0;
  437.     wa_base  = window->ex.y0;
  438.     wa_width = window->ex.x1 - window->ex.x0;
  439.  
  440.     /* Create the window, dealing with errors */
  441.     if (wimpt_complain(wimp_create_wind(window, &wimpio_control.printf_win_handle)))
  442.         return FALSE;
  443.  
  444.     win_register_event_handler(wimpio_control.printf_win_handle, wprintf_event_handler, NULL);
  445.     win_activeinc();
  446.     printf_window_exists = TRUE;
  447.  
  448.     /* Let the print window have idle events, so it can update */
  449.     win_claim_idle_events(wimpio_control.printf_win_handle);
  450.     event_setmask(event_getmask() & ~wimp_EMNULL);
  451.     return TRUE;
  452. }
  453.  
  454. /* Show the window */
  455. void wprintf_show(void)
  456. {
  457.     w_show(printf_window_exists, wimpio_control.printf_win_handle);
  458. }
  459.  
  460. /* Hide the window */
  461. void wprintf_hide(void)
  462. {
  463.     w_hide(printf_window_exists, wimpio_control.printf_win_handle);
  464. }
  465.  
  466. /* Delete the window */
  467. void wprintf_delete(void)
  468. {
  469.     if (printf_window_exists && locally_allocated)
  470.         heap_free(main_buffer);
  471.     win_claim_idle_events((wimp_w)-1);
  472.     event_setmask(event_getmask() | wimp_EMNULL);
  473.     w_delete(&printf_window_exists, &wimpio_control.printf_win_handle);
  474. }
  475.  
  476. /*---------------------------------------- READ ----------------------------------------*/
  477.  
  478. /* Number of icons in the read window */
  479. static int n_read_icons;
  480.  
  481. /* Flag - does window exist */
  482. static BOOL read_window_exists = FALSE;
  483.  
  484. static BOOL read_printf_flag;
  485.  
  486. #define icon_OK      (0)
  487. #define icon_Input   (1)
  488.  
  489. /* Type ahead buffer - characters are moved here on return */
  490. #define MaxReadBuffer (1000)
  491. static char read_buffer[MaxReadBuffer+1];
  492. static int  read_index = 0; /* Where to put next character */
  493.  
  494. /* Drop handler globals */
  495. static char read_drop_format[WRead_MaxFormat];
  496. static w_drop_handler read_drop_handler = NULL;
  497. static void *read_drop_handle = NULL;
  498. static w_drop_handler icon_drop_handler = NULL;
  499. static void *icon_drop_handle = NULL;
  500.  
  501. /* Place the caret in the read window. */
  502. static void place_caret()
  503. {
  504.     wimp_caretstr caretstr;
  505.  
  506.     /* Set the caret into the icon */
  507.     caretstr.w = wimpio_control.read_win_handle;
  508.     caretstr.i = icon_Input;
  509.     caretstr.height = -1;
  510.     caretstr.index  = 0;
  511.     wimpt_noerr(wimp_set_caret_pos(&caretstr));
  512. }
  513.  
  514. /* Transfer as much data as we can to the local buffer, and add a newline.
  515.    Data from this buffer gets picked up in wread */
  516. static void buffer_input(char *source)
  517. {
  518.     int i;
  519.  
  520.     for (i = 0 ; source[i] >= ' ' && read_index < MaxReadBuffer-1 ; i++)
  521.         read_buffer[read_index++] = source[i];
  522.     read_buffer[read_index++] = '\n';
  523.     read_buffer[read_index] = 0;
  524. }
  525.  
  526. /* Are menus enabled? */
  527. static BOOL menu_enable;
  528.  
  529. /* Menu maker and processor */
  530. static event_menu_maker read_menu_maker = NULL;
  531. static event_menu_proc  read_menu_proc  = NULL;
  532. static void *read_menu_h = NULL;
  533.  
  534. /* Local menu routines */
  535. static menu menu_maker(void *handle)
  536. {
  537.     return (menu_enable) ? (*read_menu_maker)(read_menu_h) : (menu)-1;
  538. }
  539.  
  540. static void menu_proc(void *handle, char *hit)
  541. {
  542.     if (menu_enable) (*read_menu_proc)(read_menu_h, hit);
  543. }
  544.  
  545. /* Enable/disable menus */
  546. static void enable_menus(BOOL enable)
  547. {
  548.     menu_enable = enable;
  549.  
  550.     event_attachmenumaker(wimpio_control.printf_win_handle,
  551.                           (enable) ? menu_maker : 0,
  552.                           (enable) ? menu_proc : 0, read_menu_h);
  553.     event_attachmenumaker(wimpio_control.read_win_handle,
  554.                           (enable) ? menu_maker : 0,
  555.                           (enable) ? menu_proc : 0, read_menu_h);
  556.     event_attachmenumaker(win_ICONBAR,
  557.                           (enable) ? menu_maker : 0,
  558.                           (enable) ? menu_proc : 0, read_menu_h);
  559. }
  560.  
  561.  
  562. /* The read routine itself. Bytes read if successful, -1 if not. */
  563. int wread(char *buffer, int bufflen)
  564. {
  565.     int i, j, to_move;
  566.  
  567.     if (read_index <= 0) enable_menus(TRUE);
  568.     while (read_index <= 0) event_process();
  569.  
  570.     to_move = (bufflen < read_index) ? bufflen : read_index;
  571.     memcpy(buffer, read_buffer, to_move);
  572.  
  573.     for (i = 0, j = bufflen ; j <= read_index ; i++, j++)
  574.         read_buffer[i] = read_buffer[j];
  575.     read_index = i;
  576.  
  577.     /* Echo what we read into the print buffer */
  578.     if (read_printf_flag && to_move > 0)
  579.     {
  580.         w_write(buffer, to_move);
  581.         if (event_anywindows()) event_process();
  582.     }
  583.  
  584.     enable_menus(FALSE);
  585.     return to_move;
  586. }
  587.  
  588. /* Return processor - move characters to buffer and clear icon */
  589. static void process_return()
  590. {
  591.     char *icontext;
  592.     wimp_icon result;
  593.     int  i;
  594.  
  595.     wimpt_noerr(wimp_get_icon_info(wimpio_control.read_win_handle, icon_Input, &result));
  596.     icontext = result.data.indirecttext.buffer;
  597.     buffer_input(icontext);
  598.  
  599.     for (i = 0 ; i < result.data.indirecttext.bufflen ; i++) icontext[i] = 0;
  600.     wimpt_noerr(wimp_set_icon_state(wimpio_control.read_win_handle, icon_Input, 0, 0));
  601.     place_caret();   
  602. }
  603.  
  604. /* Register a file drop handler for the read window.
  605.    If you drop a file onto the read window, and you have given a non-null
  606.    string to this routine, and the icons are not grayed, then it treats
  607.    the string as a format string, and simulates the effect of typing that
  608.    in to the window. For example, to get "(<filname>) run", you would give
  609.    a string of "(%s) run". The format must be less than 80 characters -
  610.    it is ignored if not. Passing NULL removes the drop handling.
  611.    The second parameter allows a function to be called before this string is
  612.    issued, for example to display menus. At the moment it passes no parameters on:
  613.    future versions might pass the string in, or allow the process to be halted.
  614. */
  615. void w_register_drop(char *format, w_drop_handler handler, void *handle)
  616. {
  617.     if (format == NULL)
  618.         read_drop_format[0] = 0;
  619.     else if (strlen(format) < WRead_MaxFormat)
  620.         strcpy(read_drop_format, format);
  621.     read_drop_handler = handler;
  622.     read_drop_handle  = handle;
  623. }
  624.  
  625. /* Fake input */
  626. void wread_fake_input(char *text)
  627. {
  628.     buffer_input(text);
  629. }
  630.  
  631. /***************************** WINDOW FUNCTIONS *****************************/
  632.  
  633. static void wread_event_handler(wimp_eventstr *e, void *handle)
  634. {
  635.     switch (e->e)
  636.     {
  637.         case wimp_ECLOSE:
  638.             if (close_string != NULL)
  639.             {
  640.                 wread_fake_input(close_string);
  641.                 return;
  642.             }
  643.             else
  644.                 break;
  645.                 
  646.         case wimp_EBUT:
  647.             if (e->data.but.m.i >= icon_Input)
  648.             {
  649.                 wimp_icon result;
  650.                 char *icontext;
  651.  
  652.                 wimpt_noerr(wimp_get_icon_info(wimpio_control.read_win_handle,
  653.                                                e->data.but.m.i, &result));
  654.                 icontext = result.data.indirecttext.buffer;
  655.                 buffer_input(icontext);
  656.                 return;
  657.             }
  658.             else break;
  659.  
  660.         case wimp_EKEY:
  661.             if (e->data.key.chcode == 13)
  662.                 process_return();
  663.             /* Otherwise pass the key on */
  664.             else wimp_processkey(e->data.key.chcode);
  665.             return;
  666.  
  667.         case wimp_ESEND:
  668.         case wimp_ESENDWANTACK:
  669.             if (e->data.msg.hdr.action == wimp_MDATALOAD)
  670.             {    /* File load - only respond to DATALOAD because it is the only one
  671.                     which guarantees a persistent file name */
  672.                 char *filename;
  673.  
  674.                 if (xferrecv_checkinsert(&filename) != -1)
  675.                 {
  676.                     if (read_drop_handler) (*read_drop_handler)(read_drop_handle);
  677.  
  678.                     if (read_drop_format[0] != 0)
  679.                     {
  680.                         /* Fill the icon buffer, so it gets picked up on the next read */
  681.                         /* No buffer overflow check */
  682.                         char temp_buffer[1000];
  683.  
  684.                         sprintf(temp_buffer, read_drop_format, filename);
  685.                         wread_fake_input(temp_buffer);
  686.                     }
  687.                 }
  688.                 return;
  689.         }
  690.     }
  691.  
  692.     /* Default and fall through case */
  693.     w_event(e, NULL, NULL, handle);
  694. }
  695.  
  696. BOOL wread_create(char *title, BOOL printf_flag)
  697. {
  698.     /* Do nothing if already initialised */
  699.     if (read_window_exists) return TRUE;
  700.  
  701.     if ((wimpio_control.read_win_handle = w_create(title, "wread", &n_read_icons)) == -1)
  702.         return FALSE;
  703.  
  704.     win_register_event_handler(wimpio_control.read_win_handle, wread_event_handler, NULL);
  705.  
  706.     read_window_exists = TRUE;
  707.     read_printf_flag   = printf_flag;
  708.     enable_menus(FALSE);
  709.     return TRUE;
  710. }
  711.  
  712. /* Show the window */
  713. void wread_show(void)
  714. {
  715.     w_show(read_window_exists, wimpio_control.read_win_handle);
  716. }
  717.  
  718. /* Hide the window */
  719. void wread_hide(void)
  720. {
  721.     w_hide(read_window_exists, wimpio_control.read_win_handle);
  722. }
  723.  
  724. /* Delete the window */
  725. void wread_delete(void)
  726. {
  727.     w_delete(&read_window_exists, &wimpio_control.read_win_handle);
  728. }
  729.  
  730. char *w_close_string(char *text)
  731. {
  732.     char *old = close_string;
  733.     close_string = text;
  734.     return old;
  735. }
  736.  
  737. /***************************** ICON BAR *************************************/
  738.  
  739. static void clickproc(wimp_i i)
  740. {
  741.     /* Open the print and scan windows */
  742.     wprintf_show();
  743.     wread_show();
  744.     place_caret();
  745. }
  746.  
  747. /* Call on file drop onto icon bar */
  748. static void icon_drop(wimp_eventstr *e, void *handle)
  749. {
  750.     char *command = (char *)handle;
  751.     
  752.     switch (e->e)
  753.     {
  754.         case wimp_ESEND:
  755.         case wimp_ESENDWANTACK:
  756.         {
  757.             if (e->data.msg.hdr.action == wimp_MDATALOAD)
  758.             {    /* File load - only respond to DATALOAD because it is the only one
  759.                     which guarantees a persistent file name */
  760.                 char *filename;
  761.  
  762.                 if (xferrecv_checkinsert(&filename) != -1)
  763.                 {
  764.                     if (icon_drop_handler) (*icon_drop_handler)(icon_drop_handle);
  765.  
  766.                     if (command)
  767.                     {
  768.                         /* Fill the icon buffer, so it gets picked up on the next read */
  769.                         /* No buffer overflow check */
  770.                         char temp_buffer[1000];
  771.  
  772.                         sprintf(temp_buffer, command, filename);
  773.                         wread_fake_input(temp_buffer);
  774.                     }
  775.                 }
  776.                 return;
  777.             }
  778.         }
  779.     }
  780. }
  781.  
  782. void w_baricon(char *command, w_drop_handler handler, void *handle)
  783. {
  784.     /* Register icon on icon bar */
  785.     baricon(wimpt_programname(), 1, clickproc);
  786.     win_register_event_handler(win_ICONBARLOAD, icon_drop, command);
  787.     icon_drop_handler = handler;
  788.     icon_drop_handle  = handle;
  789. }
  790.  
  791. void w_register_menu(event_menu_maker maker, event_menu_proc proc, void *handle)
  792. {
  793.     read_menu_maker = maker;
  794.     read_menu_proc  = proc;
  795.     read_menu_h     = handle;
  796. }
  797.