home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / software / unix / saoimage / sao1_07.tar / editctrl.c < prev    next >
C/C++ Source or Header  |  1990-06-03  |  9KB  |  283 lines

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    editctrl.c (Editor Control)
  6.  * Purpose:    Top level of text editing session for string input
  7.  * Subroutine:    init_edit_popup()        returns: EditStruct *
  8.  * Subroutine:    get_edit_input()        returns: int
  9.  * Subroutine:    unmap_popwin()            returns: void
  10.  * Xlib calls:    XCreateSimpleWindow(), XMapWindow(), XUnmapWindow()
  11.  * Xlib calls:    XSelectInput(), XNextEvent(), XDrawImageString()
  12.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  13.  *        You may do anything you like with this file except remove
  14.  *        this copyright.  The Smithsonian Astrophysical Observatory
  15.  *        makes no representations about the suitability of this
  16.  *        software for any purpose.  It is provided "as is" without
  17.  *        express or implied warranty.
  18.  * Modified:    {0} Michael VanHilst    initial version          7 July 1989
  19.  *        {1} Jay Travisano (STScI)  VMS,IMTOOL changes     10 Nov 1989
  20.  *              {2} MVH BSDonly strings.h compatability           19 Feb 1990
  21.  *        {n} <who> -- <does what> -- <when>
  22.  */
  23.  
  24. #include <stdio.h>        /* stderr, NULL, etc. */
  25.  
  26. #ifndef VMS
  27. #ifdef SYSV
  28. #include <string.h>        /* strlen, strcat, strcpy, strrchr */
  29. #else
  30. #include <strings.h>        /* strlen, etc. for unenlightened BSD's */
  31. #endif
  32. #else
  33. #include <string.h>        /* strlen, strcat, strcpy, strrchr */
  34. #endif
  35.  
  36. #include <X11/Xlib.h>        /* X window stuff */
  37. #include <X11/Xutil.h>        /* X window manager stuff */
  38. #include "hfiles/color.h"
  39. #include "hfiles/window.h"
  40. #include "hfiles/edit.h"
  41.  
  42. extern struct colorRec color;
  43. extern struct windowRec btnbox;
  44. extern struct windowRec desktop;
  45. extern Window root;
  46.  
  47. #define XOFF 2
  48. #define YOFF 1
  49. #define BDRWDTH 2
  50. #define WDTHLESS 12
  51.  
  52. struct popRec pop;
  53. static int init_window = 1;
  54.  
  55. #if VMS && IMTOOL
  56. extern void XZ_ast();
  57. extern int  XZ_efn;
  58. #endif
  59.  
  60. /*
  61.  * Subroutine:    init_edit_popup
  62.  * Purpose:    Get everything ready for running editor sessions
  63.  */
  64. EditStruct *init_edit_popup ( string, max_chars )
  65.      char *string;
  66.      int max_chars;
  67. {
  68.   EditStruct *edit;
  69.   int len;
  70.   EditStruct *get_edit_struct();
  71.   void init_edit_struct(), load_edit_struct();
  72.   static void init_popwin();
  73.  
  74.   if( init_window ) {
  75.     init_popwin(color.gcset.menu.foreground, color.gcset.menu.background);
  76.     init_window = 0;
  77.   }
  78.   edit = get_edit_struct (max_chars);
  79.   init_edit_struct(pop.display, pop.ID, edit,
  80.             pop.fontstruct, pop.foreground, pop.background);
  81.   if( (string != NULL) && ((len = strlen(string)) > 1) )
  82.     load_edit_struct(edit, string, len);
  83.   return( edit );
  84. }
  85.  
  86. /*
  87.  * Subroutine:    get_edit_input
  88.  * Purpose:    Run popup editor session for text input
  89.  * Xlib calls:    XNextEvent(), XDrawImageString(), XUnmapWindow()
  90.  * Note:    All non-editor events are thrown out during session
  91.  *        (but expose is fielded and configure is saved for end).
  92.  * Returns:    1 if user returns with a response, 0 if user cancels session
  93.  */
  94. int get_edit_input ( edit, one_row, map, unmap, prompt )
  95.      EditStruct *edit;
  96.      int one_row;    /* i: put-edit-after-prompt-on-same-line */
  97.      int map;        /* i: map-window-before-starting */
  98.      int unmap;        /* i: unmap-window-before-return */
  99.      char *prompt;    /* i: user prompt such as "enter file name:" */
  100. {
  101.   XEvent event, configure;
  102.   int init, got_configure, answer;
  103.   GC gc, set_edit_gc();
  104.   int emacs_response();
  105.   void draw_new_string(), redraw_edit_string();
  106.   void adjust_desktop(), redraw_window(), unmap_popwin();
  107.   static void map_popwin();
  108.  
  109.   map_popwin(edit, one_row, prompt, map);
  110.   if( !map ) {
  111.     /* window already up, don't wait for expose event */
  112.     XClearWindow(pop.display, pop.ID);
  113.     gc = set_edit_gc(pop.font, pop.foreground, pop.background);
  114.     XDrawImageString(pop.display, pop.ID, gc, pop.prompt_x,
  115.              pop.prompt_y, prompt, strlen(prompt));
  116.     draw_new_string(edit, 0);
  117.     init = 0;
  118.   } else
  119.     init = 1;
  120.   got_configure = 0;
  121.   while( 1 ) {
  122.     /* swallow all the events, except a few, from now until we are done */
  123.     XNextEvent(pop.display, &event);
  124.     switch( event.type ) {
  125.     case KeyPress:
  126.       /* grab key events from all application windows */
  127.       if( (answer = emacs_response(&event.xkey, edit)) != 0 ) {
  128.     if( got_configure )
  129.       adjust_desktop(&configure.xconfigure);
  130.     if( unmap )
  131.       unmap_popwin();
  132.     if( answer < 0 )
  133.       return( 0 );
  134.     else
  135.       return( 1 );
  136.       }
  137.       break;
  138.     case Expose:
  139.       if( event.xexpose.count > 0 )
  140.     break;
  141.       if( event.xexpose.window == pop.ID ) {
  142.     gc = set_edit_gc(pop.font, pop.foreground, pop.background);
  143.     XDrawImageString(pop.display, pop.ID, gc, pop.prompt_x,
  144.              pop.prompt_y, prompt, strlen(prompt));
  145.     if( init ) {
  146.       draw_new_string(edit, 0);
  147.       init = 0;
  148.     } else
  149.       redraw_edit_string(edit);
  150.       } else
  151.     /* redraw entire window once (not parts of windows) */
  152.     redraw_window(event.xexpose.window);
  153.       break;
  154.     case ConfigureNotify:
  155.       /* if the main window is reconfigured, save this info */
  156.       if( event.xconfigure.window == desktop.ID ) {
  157.     bcopy((char *)&event, (char *)&configure, sizeof(XEvent));
  158.     got_configure = 1;
  159.       }
  160.       break;
  161.     default:
  162.       break;
  163.     }
  164.   }
  165. }
  166.  
  167. /*
  168.  * Subroutine:    unmap_popwin
  169.  * Purpose:    Unmap the popwin: called by routines which control map and
  170.  *        unmap themselves because they use the window for multiple
  171.  *        queries (single query can have auto-unmap)
  172.  */
  173. void unmap_popwin ( )
  174. {
  175.   if( pop.pointer_x >= 0 )
  176.     /* if pointer position was noted, return pointer to continue from where
  177.        event processing was interrupted */
  178.     XWarpPointer(pop.display, None, root, 0, 0, 0, 0,
  179.          pop.pointer_x, pop.pointer_y);
  180.   XUnmapWindow(pop.display, pop.ID);
  181. }
  182.  
  183. /*
  184.  * Subroutine:    init_popwin
  185.  * Purpose:    Set the popup parameters and create the popup window
  186.  * Xlib calls:    XCreateSimpleWindow(), XSelectInput();
  187.  */
  188. static void init_popwin ( foreground, background )
  189.      unsigned long foreground, background;
  190. {
  191.   int text_yoff;
  192.   XWMHints wmhints;
  193.   XFontStruct *get_fontstruct();
  194.  
  195.   pop.foreground = foreground;
  196.   pop.background = background;
  197.   /* use the "large" font */
  198.   pop.fontstruct = get_fontstruct (2);
  199.   pop.font = pop.fontstruct->fid;
  200.   pop.font_height = pop.fontstruct->ascent + pop.fontstruct->descent;
  201.   pop.ref_width = btnbox.width;
  202.   pop.ref_height = btnbox.height;
  203.   pop.width = pop.ref_width - (XOFF + XOFF + BDRWDTH + BDRWDTH);
  204.   pop.height = pop.ref_height - (YOFF + YOFF + BDRWDTH + BDRWDTH);
  205.   text_yoff = (pop.height - (pop.font_height + pop.font_height)) / 3;
  206.   pop.two_y1 = pop.font_height + text_yoff - pop.fontstruct->descent;
  207.   pop.two_y2 = pop.two_y1 + pop.font_height + text_yoff;
  208.   pop.one_y = (pop.height + pop.fontstruct->ascent) / 2;
  209.   pop.prompt_x = pop.two_y1;
  210.   pop.display = btnbox.display;
  211.   pop.ID =
  212.     XCreateSimpleWindow(btnbox.display, btnbox.ID, XOFF, YOFF,
  213.             (unsigned int)pop.width, (unsigned int)pop.height,
  214.             BDRWDTH, pop.foreground, pop.background);
  215. #if VMS && IMTOOL
  216.   XSelectAsyncInput(pop.display, pop.ID, ExposureMask | KeyPressMask,
  217.           XZ_ast, XZ_efn);
  218. #endif
  219.   XSelectInput(pop.display, pop.ID, ExposureMask | KeyPressMask);
  220.   /* Tell window manager to handle focus for us */
  221.   wmhints.input = True;
  222.   wmhints.flags = InputHint;
  223.   XSetWMHints(btnbox.display, pop.ID, &wmhints);
  224. }
  225.  
  226. /*
  227.  * Subroutine:    map_popwin
  228.  * Purpose:    map the popwindow, noting its current size and setting params
  229.  * Xlib calls:    XMapWindow()
  230.  */
  231. static void map_popwin ( edit, one_row, prompt, map )
  232.      EditStruct *edit;
  233.      int one_row;    /* i: put-edit-after-prompt-on-same-line */
  234.      char *prompt;    /* i: prompt string such as "Enter file name:" */
  235.      int map;        /* i: map-the-window-when-ready */
  236. {
  237.   int text_yoff;
  238.   Window root_ret, child_ret;
  239.   int x_ret, y_ret;
  240.   unsigned int mask_ret;
  241.  
  242.   if( (pop.ref_width != btnbox.width) || (pop.ref_height != btnbox.height) ) {
  243.     pop.ref_width = btnbox.width;
  244.     pop.ref_height = btnbox.height;
  245.     pop.width = pop.ref_width - (XOFF + XOFF + BDRWDTH + BDRWDTH);
  246.     pop.height = pop.ref_height - (YOFF + YOFF + BDRWDTH + BDRWDTH);
  247.     XResizeWindow(btnbox.display, pop.ID,
  248.           (unsigned int)pop.width, (unsigned int)pop.height);
  249.     text_yoff = (pop.height - (pop.font_height + pop.font_height)) / 3;
  250.     pop.two_y1 = pop.font_height + text_yoff;
  251.     pop.two_y2 = pop.two_y1 + pop.font_height + text_yoff;
  252.     pop.one_y = (pop.height + pop.fontstruct->ascent) / 2;
  253.     pop.prompt_x = pop.two_y1;
  254.   }
  255.   /* we don't know how current this edit's coords are, always update them */
  256.   if( one_row ) {
  257.     pop.prompt_y = pop.one_y;
  258.     edit->y = pop.one_y;
  259.     edit->x =
  260.       pop.prompt_x + XTextWidth(pop.fontstruct, prompt, strlen(prompt)) + 10;
  261.   } else {
  262.     pop.prompt_y = pop.two_y1;
  263.     edit->y = pop.two_y2;
  264.     edit->x = pop.prompt_x;
  265.   }
  266.   edit->max_pixlen = pop.width - (edit->x + pop.prompt_x);
  267.   edit->area_y = edit->y - edit->fontstruct->max_bounds.ascent;
  268.   if( map ) {
  269.     if( XQueryPointer(pop.display, root, &root_ret, &child_ret, &x_ret, &y_ret,
  270.               &pop.pointer_x, &pop.pointer_y, &mask_ret) == False )
  271.       pop.pointer_x = -1;
  272.     XMapWindow (btnbox.display, pop.ID);
  273.   }
  274. }
  275.                                                           
  276.                                                                
  277.                                                                
  278.                                                               
  279.  
  280.                                                                
  281.                                                                
  282.  
  283.