home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume4 / xpic / part15 < prev    next >
Encoding:
Internet Message Format  |  1989-07-21  |  32.2 KB

  1. Path: uunet!island!argv
  2. From: argv@island.uu.net (Dan Heller)
  3. Newsgroups: comp.sources.x
  4. Subject: v04i080: xpic -- pic previewer for X11, Part15/15
  5. Message-ID: <928@island.uu.net>
  6. Date: 22 Jul 89 07:42:39 GMT
  7. Organization: Island Graphics, Marin County, California
  8. Lines: 1204
  9. Approved: island!argv@sun.com
  10.  
  11. Submitted-by: Mark Moraes <moraes@ai.toronto.edu>
  12. Posting-number: Volume 4, Issue 80
  13. Archive-name: xpic/part15
  14.  
  15.  
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 15 (of 15)."
  24. # Contents:  xpic/Minibuf.c
  25. # Wrapped by moraes@neat.ai on Thu Jul 13 22:36:13 1989
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'xpic/Minibuf.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'xpic/Minibuf.c'\"
  29. else
  30. echo shar: Extracting \"'xpic/Minibuf.c'\" \(29988 characters\)
  31. sed "s/^X//" >'xpic/Minibuf.c' <<'END_OF_FILE'
  32. X/* $Header: Minibuf.c,v 1.5 89/06/30 03:38:22 moraes Exp $ */
  33. X/*
  34. X *  This file should be edited with 4-column tabs!  (:set ts=4 sw=4 in
  35. X *  vi, set internal-tabstop 4 in Jove, and use edit-tab-stops in Emacs
  36. X *  to get them
  37. X */
  38. X
  39. X/* 
  40. X *  This set of routines create and manipulate a simple one-line input
  41. X *  window. They offer a reasonable subset of EMACS like editing
  42. X *  capabilities, Like EMACS, the command-key to action bindings can be
  43. X *  altered. It does no data validation. The minibuffer can be created
  44. X *  using normal Xt calls, with args, and parsing the resources. Other
  45. X *  calls allow strings to be displayed or input or both. (prompted
  46. X *  input). There is no restriction on the length of the input line,
  47. X *  which will horizontally scroll in the window, EMACS-style, by half
  48. X *  the "screen" width.  It can be used in dialog boxes, or as in xpic,
  49. X *  for an interaction line.
  50. X */
  51. X/* 
  52. X *  Since this is the first (and only) widget I've written, there are
  53. X *  probably lots of things done wrong. Feel free to fix 'em. This was
  54. X *  written because the Text widgets available are more powerful than I
  55. X *  need, but aren't capable of performing the simple function that this
  56. X *  performs - display a prompt, a default chunk of text, and permit
  57. X *  editing of the default. MOST important, it must invoke some sort of
  58. X *  callback when the user hits RETURN or ^G/^C. As a minor point, I
  59. X *  hate the silly underline ^ cursor that the text widget allows. Give
  60. X *  me a solid blob anyday. It would be nice if someone could hack this
  61. X *  capability into the Text widget - after a bit of digging in its
  62. X *  code, I decided that preserving my sanity (or what's left of it) was
  63. X *  important, and chose to write this - it was much simpler.
  64. X */
  65. X/* Author: Mark Moraes (moraes@csri.toronto.edu)
  66. X   History: First written for X10 under the X10 tookit, for xpic in
  67. X               August 1987.
  68. X               This version was ported to X11, and then tuned and cleaned
  69. X            up - X11 is so much slower on Suns that the inefficient 
  70. X            redisplay strategy used in the X10 version was unfeasible
  71. X            June 1988.
  72. X */
  73. X/* To do:
  74. X    Get it to understand the subtleties of reverse video 
  75. X */
  76. X
  77. X#include <strings.h>
  78. X#include <ctype.h>
  79. X#ifdef DEBUG
  80. X#include <stdio.h>
  81. X#endif
  82. X#include <X11/Xlib.h>
  83. X#include <X11/StringDefs.h>
  84. X#include <X11/IntrinsicP.h>
  85. X#include <X11/Intrinsic.h>
  86. X#include <X11/keysymdef.h>
  87. X#include <X11/CoreP.h>
  88. X#include <X11/Core.h>
  89. X#include "MinibufP.h"
  90. X#include "Minibuf.h"
  91. X
  92. X#include "assert.h"
  93. X
  94. X/* To keep references to data less than six miles long */
  95. X#define mbuf(x)            buf->minibuf.x
  96. X#define mcore(x)        buf->core.x
  97. X#define fontwidth(x)    ((x)->max_bounds.rbearing - (x)->min_bounds.lbearing)
  98. X#define fontheight(x)    ((x)->max_bounds.ascent + (x)->max_bounds.descent)
  99. X#define fontbaseline(x)    ((x)->max_bounds.ascent)
  100. X#define CheckMode()        if (mbuf(inputMode) == FALSE) return; else ;
  101. X
  102. X
  103. X/*
  104. X *  This should be larger than the expected filesize - if a XtRealloc
  105. X *  occurs in insert_s(), add_mess(), bad things will happen because the
  106. X *  f_complete routines don't expect the string to change while they're
  107. X *  working - fixing this is work that I don't feel upto right now - one
  108. X *  day....
  109. X */
  110. X#define BUF_BLOCK         128
  111. X
  112. X#define MIN_COLS         5
  113. X#define DEFAULTFONT        "8x13"
  114. X#define ABORT_MSG        "[Aborted]"
  115. X#define DELAY            300000        /*
  116. X                                     *  Microseconds of delay for cursor
  117. X                                     *  flash in SetMark
  118. X                                     */
  119. X
  120. X/* The default bindings */
  121. Xstatic char defaultTranslations[] = 
  122. X    "Ctrl<Key>F:        forward-character()\n\
  123. X    <Key>0xff53:        forward-character()\n\
  124. X    Ctrl<Key>B:            backward-character()\n\
  125. X    <Key>0xff51:        backward-character()\n\
  126. X    Ctrl<Key>A:            beginning-of-line()\n\
  127. X    Ctrl<Key>E:            end-of-line()\n\
  128. X    Ctrl<Key>U:            universal-argument()\n\
  129. X    Ctrl<Key>D:            delete-next-character()\n\
  130. X    Ctrl<Key>H:            delete-previous-character()\n\
  131. X    <Key>0xff7f:        delete-previous-character()\n\
  132. X    <Key>0xffff:        delete-previous-character()\n\
  133. X    <Key>0xff08:        delete-previous-character()\n\
  134. X    Ctrl<Key>X:            exchange-point-and-mark()\n\
  135. X    Ctrl<Key>W:            kill-region()\n\
  136. X    Ctrl<Key>K:            kill-to-end-of-line()\n\
  137. X    Meta<Key>D:            kill-to-beginning-of-line()\n\
  138. X    Ctrl<Key>Y:            yank-killed-text()\n\
  139. X    Ctrl<Key>J:            newline()\n\
  140. X    <Key>0xff0a:        newline()\n\
  141. X    Ctrl<Key>M:            newline()\n\
  142. X    <Key>0xff0d:        newline()\n\
  143. X    Ctrl<Key>G:            abort()\n\
  144. X    Ctrl<Key>C:            abort()\n\
  145. X    <Btn1Down>:            set-cursor-to-mouse()\n\
  146. X    <Btn2Down>:            get-x-buffer()\n\
  147. X    <Btn3Down>:            set-mark-to-mouse()\n\
  148. X    Ctrl<Key>0x20:        make-this-the-mark()\n\
  149. X    <Key>0x20:            complete-filename()\n\
  150. X    Ctrl<Key>I:            complete-filename()\n\
  151. X    <Key>0xff09:        complete-filename()\n\
  152. X    Shift<Key>/:        list-files()\n\
  153. X    <Key>/:                insert-char()\n\
  154. X    <Key>?:                list-files()\n\
  155. X    <Key>:                insert-char()\n\
  156. X";
  157. X
  158. X
  159. Xstatic void CursorForward(), CursorBack(), BeginningOfBuf(), EndOfBuf(),
  160. X UnivArgument(), DeleteCharForward(), DeleteCharBack(), KillToEnd(),
  161. X KillToBeginning(), YankKilledStuff(), MakeMark(), ExchangeMarkAndPoint(),
  162. X CutMarkToPoint(), FinishedInput(), QuitInput(), SetCursor(), SetMark(),
  163. X GetXBuffer(), CharInsert(), CompleteFilename(), ListFiles();
  164. X
  165. X/* Actions Table */
  166. Xstatic XtActionsRec actionsList [] = {
  167. X/* motion bindings */
  168. X    {"forward-character",             CursorForward},
  169. X    {"backward-character",             CursorBack},
  170. X    {"beginning-of-line",             BeginningOfBuf},
  171. X    {"end-of-line",                 EndOfBuf},
  172. X    {"universal-argument",            UnivArgument},
  173. X/* delete bindings */
  174. X    {"delete-next-character",         DeleteCharForward},
  175. X    {"delete-previous-character",    DeleteCharBack},
  176. X/* kill bindings */
  177. X    {"kill-to-end-of-line",         KillToEnd},
  178. X    {"kill-to-beginning-of-line",     KillToBeginning},
  179. X/* yank bindings */
  180. X    {"yank-killed-text",             YankKilledStuff},
  181. X    {"make-this-the-mark",            MakeMark},
  182. X    {"exchange-point-and-mark",        ExchangeMarkAndPoint},
  183. X    {"kill-region",                    CutMarkToPoint},
  184. X/* new line stuff */
  185. X    {"newline",                     FinishedInput},
  186. X    {"abort",                        QuitInput},
  187. X/* Selection stuff */
  188. X    {"set-cursor-to-mouse",            SetCursor},
  189. X    {"set-mark-to-mouse",            SetMark},
  190. X    {"get-x-buffer",                GetXBuffer},
  191. X/* filename completion and listing of files */
  192. X    {"complete-filename",            CompleteFilename},
  193. X    {"list-files",                     ListFiles},
  194. X/* Insert character */
  195. X    {"insert-char",                    CharInsert},
  196. X};
  197. X
  198. Xstatic int zero = 0;
  199. X
  200. X#define offset(field) XtOffset(MinibufWidget, field)
  201. Xstatic XtResource resources[] = {
  202. X    {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
  203. X     offset(minibuf.foreground), XtRString, "Black"},
  204. X    {XtNfont,  XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  205. X     offset(minibuf.finfo),XtRString, DEFAULTFONT},
  206. X    {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
  207. X     offset(minibuf.cursor), XtRString, "xterm"},
  208. X    {XtNfinishedCallback, XtCCallback, XtRCallback, sizeof(XtProc),
  209. X     offset(minibuf.finishedCallback), XtRCallback, (caddr_t)NULL},
  210. X#ifdef TYPEOUT
  211. X    {XtNtypeoutColumns, XtCTypeoutColumns, XtRInt, sizeof(int),
  212. X     offset(minibuf.typeoutColumns), XtRInt, (caddr_t)&zero},
  213. X    {XtNtypeout, XtCtypeout, XtRPointer, sizeof(Widget),
  214. X     offset(minibuf.typeout), XtRPointer, (caddr_t)NULL},
  215. X#endif
  216. X};
  217. X
  218. Xstatic void Initialize(), Realize(), Destroy(), Redisplay(), Resize();
  219. X
  220. X/*
  221. X *  ...ClassData must be initialized at compile time.  Must initialize
  222. X *  all substructures.  (Actually, last two here need not be initialized
  223. X *  since not used.)
  224. X */
  225. XMinibufClassRec minibufClassRec = {
  226. X    {
  227. X        (WidgetClass) &widgetClassRec,    /* superclass            */    
  228. X        "Minibuf",                        /* class_name            */
  229. X        sizeof(MinibufRec),                /* size                    */
  230. X        NULL,                            /* class_initialize        */
  231. X        NULL,                            /* class_part_initialize*/
  232. X        FALSE,                            /* class_inited              */
  233. X        Initialize,                        /* initialize            */
  234. X        NULL,                            /* initialize_hook        */
  235. X        Realize,                        /* realize                 */
  236. X        actionsList,                    /* actions                  */
  237. X        XtNumber(actionsList),            /* num_actions              */
  238. X        resources,                        /* resources              */
  239. X        XtNumber(resources),            /* resource_count          */
  240. X        NULLQUARK,                        /* xrm_class              */
  241. X        TRUE,                            /* compress_motion          */
  242. X        TRUE,                            /* compress_exposure    */
  243. X        TRUE,                            /* compress_enterleave  */
  244. X        FALSE,                            /* visible_interest          */
  245. X        Destroy,                        /* destroy                  */
  246. X        Resize,                            /* resize                  */
  247. X        Redisplay,                        /* expose                  */
  248. X        NULL,                            /* set_values              */
  249. X        NULL,                            /* set_values_hook          */
  250. X        XtInheritSetValuesAlmost,        /* set_values_almost    */
  251. X        NULL,                            /* get_values_hook          */
  252. X        NULL,                            /* accept_focus              */
  253. X        XtVersion,                        /* version                  */
  254. X        NULL,                            /* callback_private          */
  255. X        defaultTranslations,            /* tm_table                  */
  256. X        NULL,                            /* query_geometry          */
  257. X#ifdef XtCAccelerators
  258. X        XtInheritDisplayAccelerator,    /* display_accelerator    */
  259. X        NULL                            /* extension        */
  260. X#endif /* XtCAccelerators */
  261. X    },  /* CoreClass fields initialization */
  262. X    {
  263. X        0,                                /* field not used        */
  264. X    },  /* MinibufClass fields initialization */
  265. X};
  266. X
  267. X/* for public consumption */
  268. XWidgetClass minibufWidgetClass = (WidgetClass)&minibufClassRec;
  269. X
  270. X/*ARGSUSED*/
  271. Xstatic void Initialize(request, new)
  272. XWidget request, new;
  273. X{
  274. X    register MinibufWidget buf = (MinibufWidget) new;
  275. X    XGCValues gcv;
  276. X
  277. X    mbuf(string) = mbuf(killBuffer) = NULL;
  278. X    mbuf(size) = mbuf(startPos) = mbuf(cursorPos) = mbuf(mark)
  279. X     = mbuf(killBufferLen) = mbuf(killBufferSize) = mbuf(len) 
  280. X     = mbuf(cols) = mbuf(promptLen) = 0;
  281. X    mbuf(arg) = 1;
  282. X    mbuf(cursorX) = 0;
  283. X    mbuf(inputMode) = FALSE;
  284. X    gcv.foreground = mbuf(foreground);
  285. X    gcv.background = mcore(background_pixel);
  286. X    gcv.font = mbuf(finfo)->fid;
  287. X    mbuf(normal_gc) = XtGetGC(new, GCForeground | GCBackground | GCFont,
  288. X     &gcv);
  289. X    gcv.foreground = mbuf(foreground) ^ mcore(background_pixel);
  290. X    gcv.function = GXxor;
  291. X    mbuf(invert_gc) = XtGetGC(new, GCForeground | GCBackground | GCFont |
  292. X     GCFunction, &gcv);
  293. X
  294. X    /* Compute these correctly */
  295. X    if (mcore(height) == 0)
  296. X        mcore(height) = fontheight(mbuf(finfo));
  297. X
  298. X    if ((mbuf(cols) = mcore(width) / fontwidth(mbuf(finfo))) < MIN_COLS) {
  299. X        /* Set it to MIN_COLS */
  300. X        mcore(width) = MIN_COLS * fontwidth(mbuf(finfo));
  301. X    }
  302. X}
  303. X
  304. X/* Wish the primitive widget had a cursor .. */
  305. Xstatic void Realize(w, valueMask, attributes)
  306. Xregister Widget w;
  307. XMask *valueMask;
  308. XXSetWindowAttributes *attributes;
  309. X{
  310. X    if ((attributes->cursor = ((MinibufWidget)w)->minibuf.cursor) != None)
  311. X     *valueMask |= CWCursor;
  312. X
  313. X    XtCreateWindow( w, (unsigned int)InputOutput, (Visual *)CopyFromParent,
  314. X     *valueMask, attributes );
  315. X}
  316. X
  317. Xstatic void Destroy(w)
  318. XWidget w;
  319. X{
  320. X    register MinibufWidget buf = (MinibufWidget) w;
  321. X
  322. X    if (mbuf(string) != NULL)
  323. X        free(mbuf(string));
  324. X    if (mbuf(killBuffer) != NULL)
  325. X        free(mbuf(killBuffer));
  326. X    XtDestroyGC(mbuf(normal_gc));
  327. X    XtDestroyGC(mbuf(invert_gc));
  328. X}
  329. X
  330. X
  331. X/*ARGSUSED*/
  332. Xstatic void Redisplay(w, event, region)
  333. XWidget w;
  334. XXEvent *event;
  335. XRegion region;
  336. X{
  337. X    register MinibufWidget buf = (MinibufWidget) w;
  338. X    static void DisplayBuf(), DisplayCursor();
  339. X
  340. X    if (!XtIsRealized(w))
  341. X        return;
  342. X    DisplayBuf(buf, TRUE);
  343. X    if (mbuf(cursorOn) == TRUE)
  344. X        DisplayCursor(buf);
  345. X}
  346. X
  347. X
  348. Xstatic void Resize(w)
  349. XWidget w;
  350. X{
  351. X    register MinibufWidget buf = (MinibufWidget) w;
  352. X    static void DisplayBuf(), DisplayCursor();
  353. X
  354. X    /*
  355. X     *  We should probably do some geometry management stuff here, if
  356. X     *  the number of cols is less than MIN_COLS
  357. X     */
  358. X    mbuf(cols) = mcore(width) / fontwidth(mbuf(finfo));
  359. X    if (!XtIsRealized(w))
  360. X        return;
  361. X    DisplayBuf(buf, TRUE);
  362. X    if (mbuf(cursorOn) == TRUE)
  363. X        DisplayCursor(buf);
  364. X}
  365. X
  366. X/* 
  367. X *  Displays the buffer. When called with redraw = TRUE, it clears the
  368. X *  entire buffer and redraws it. If redraw = FALSE, then it clears from
  369. X *  the cursor position to the end of the buffer, and then redraws just
  370. X *  that section. This allows for fast update when a single character is
  371. X *  typed, or deleted, usually at the end of the line. If redraw is
  372. X *  FALSE, teh cursor must be turned off before this is called -
  373. X *  otherwise it may or may not vanish, causing problems. Typically, we
  374. X *  hide the cursor, then update the buffer string and data, and then
  375. X *  call this procedure. Note that for delete-char-forward, char-insert,
  376. X *  and StrInsert, this gets called AFTER the mbuf(string) is updated
  377. X *  but before the mbuf(cursorPos) is updated, which in delete-char-back
  378. X *  and cut-point-to-mark, it is called afetr the cursorPos is updated
  379. X *  as well, so that the changed region is redrawn.
  380. X */
  381. Xstatic void DisplayBuf(buf, redraw)
  382. Xregister MinibufWidget buf;
  383. Xint redraw;
  384. X{
  385. X    register int nChars, isLonger;
  386. X    int start;
  387. X    register Widget w = (Widget) buf;
  388. X
  389. X    if (redraw) {
  390. X        start = mbuf(startPos);
  391. X        XClearWindow(XtDisplay(w), XtWindow(w));
  392. X    } else {
  393. X        start = mbuf(cursorPos);
  394. X        mbuf(cursorX) = (mbuf(cursorPos) - mbuf(startPos)) * 
  395. X         fontwidth(mbuf(finfo));
  396. X        XClearArea(XtDisplay(w), XtWindow(w), mbuf(cursorX), 0, 
  397. X         mcore(width) - mbuf(cursorX), (unsigned) fontheight(mbuf(finfo)), 
  398. X         False);
  399. X    }
  400. X    nChars = (mbuf(startPos) + mbuf(cols));
  401. X    isLonger = (nChars < mbuf(len));
  402. X    if (isLonger)
  403. X        nChars -= start + 1;
  404. X    else
  405. X        nChars = mbuf(len) - start;
  406. X
  407. X    XDrawImageString(XtDisplay(w), XtWindow(w), mbuf(normal_gc), 
  408. X     redraw? 0 : mbuf(cursorX), fontbaseline(mbuf(finfo)), 
  409. X     mbuf(string) + start, nChars);
  410. X
  411. X    if (isLonger) 
  412. X        XDrawImageString(XtDisplay(w), XtWindow(w), mbuf(normal_gc), 
  413. X         (mbuf(cols) - 1) * fontwidth(mbuf(finfo)), 
  414. X         fontbaseline(mbuf(finfo)), "!", 1); 
  415. X}
  416. X
  417. X
  418. X/* 
  419. X *  Display the buffer cursor. It does the devious computations for
  420. X *  Horiz scrolling of the minibuffer, back and forward, and does a
  421. X *  'hard' redisplay (i.e. with a clear) of the window if a horiz.
  422. X *  scroll is done. 
  423. X */
  424. Xstatic void DisplayCursor(buf)
  425. Xregister MinibufWidget buf;
  426. X{
  427. X    register int col;
  428. X    register Widget w = (Widget) buf;
  429. X
  430. X    if (mbuf(cursorPos) > mbuf(len))
  431. X        mbuf(cursorPos) = mbuf(len);
  432. X    if (mbuf(cursorPos) < mbuf(promptLen))
  433. X        mbuf(cursorPos) = mbuf(promptLen);
  434. X        
  435. X    col = (mbuf(cursorPos) - mbuf(startPos));
  436. X
  437. X    if ((col >= mbuf(cols)) || (col < 0)) {
  438. X        if (mbuf(cursorPos) < mbuf(cols) - 1) {
  439. X            /*
  440. X             *  The cursor will be seen if the start
  441. X             *  position is 0, which looks nicer than half
  442. X             *  the prompt showing
  443. X             */
  444. X            mbuf(startPos) = 0;
  445. X            col = mbuf(cursorPos);
  446. X        } else {
  447. X            /* 
  448. X             *  Horiz scroll the buffer to mbuf(cols)/2
  449. X             *  before cursorPos. this acounts for both
  450. X             *  forward and backward scrolling.
  451. X             */
  452. X            col = (mbuf(cols)) / 2 - 1;
  453. X            mbuf(startPos) = mbuf(cursorPos) - col;
  454. X            if (mbuf(startPos) < 0) {
  455. X                mbuf(startPos) = 0;
  456. X                col = (mbuf(cursorPos) - mbuf(startPos));
  457. X            }
  458. X        }
  459. X        DisplayBuf(buf, TRUE);
  460. X    }
  461. X    mbuf(cursorX) = col * fontwidth(mbuf(finfo));
  462. X    XFillRectangle(XtDisplay(w), XtWindow(w), mbuf(invert_gc), 
  463. X     mbuf(cursorX), 0, (unsigned) fontwidth(mbuf(finfo)),
  464. X     (unsigned) fontheight(mbuf(finfo)));
  465. X    mbuf(cursorOn) = TRUE;
  466. X}
  467. X
  468. X
  469. X
  470. X/*
  471. X *  Hide the cursor
  472. X */
  473. Xstatic void ConcealCursor(buf)
  474. Xregister MinibufWidget buf;
  475. X{
  476. X    register Widget w = (Widget) buf;
  477. X    if (mbuf(cursorOn) == TRUE) {
  478. X        XFillRectangle(XtDisplay(w), XtWindow(w), mbuf(invert_gc), 
  479. X         mbuf(cursorX), 0, (unsigned) fontwidth(mbuf(finfo)),
  480. X         (unsigned) fontheight(mbuf(finfo)));
  481. X        mbuf(cursorOn) = FALSE;
  482. X    }
  483. X}
  484. X
  485. X
  486. X
  487. X/* 
  488. X *  Inserts len characters of string s into the buffer at the current
  489. X *  cursor position. Note that it does not re-display the cursor, while
  490. X *  CharInsert does.
  491. X */
  492. X/* The universal argument has no effect on this one */
  493. Xstatic void StrInsert(s, len, buf)
  494. Xregister char *s;
  495. Xregister int len;
  496. Xregister MinibufWidget buf;
  497. X{
  498. X    register int newLen = mbuf(len) + len;
  499. X    static void QuitInput();
  500. X
  501. X    while (newLen > mbuf(size)) {
  502. X        mbuf(size) += BUF_BLOCK;
  503. X        if (mbuf(string) == NULL)
  504. X            mbuf(string) = XtMalloc((unsigned) mbuf(size));
  505. X        else 
  506. X            mbuf(string) = XtRealloc(mbuf(string), (unsigned) mbuf(size));
  507. X        if ( mbuf(string) == NULL) {
  508. X            mbuf(size) = 0;
  509. X            mbuf(len) = 0;
  510. X            mbuf(inputMode) = FALSE;
  511. X            QuitInput((Widget) buf, (XEvent *) NULL, (String *) NULL, 
  512. X             (Cardinal *) NULL);
  513. X            return;
  514. X        }
  515. X    }
  516. X    bcopy(mbuf(string) + mbuf(cursorPos), mbuf(string) + mbuf(cursorPos) + len, 
  517. X     mbuf(len) - mbuf(cursorPos));
  518. X    bcopy(s, mbuf(string) + mbuf(cursorPos), len);
  519. X    mbuf(len) += len;
  520. X    DisplayBuf(buf, FALSE);
  521. X    mbuf(cursorPos) += len;
  522. X    mbuf(arg) = 1;
  523. X}
  524. X
  525. X
  526. X
  527. X/*
  528. X *  Inserts c arg times into buffer string at current position and moves
  529. X *  cursor forward
  530. X */
  531. X/*ARGSUSED*/
  532. Xstatic void CharInsert(w, event, params, numparams)
  533. XWidget w;
  534. XXEvent *event;
  535. XString *params;
  536. XCardinal *numparams;
  537. X{
  538. X    register MinibufWidget buf = (MinibufWidget) w;
  539. X    register int i = mbuf(cursorPos);
  540. X    register int j = mbuf(arg);
  541. X    static void QuitInput();
  542. X    KeySym keysym;
  543. X    XComposeStatus compose;
  544. X    int status;
  545. X    char c;
  546. X    
  547. X    CheckMode();
  548. X    status = XLookupString(&event->xkey, &c, 1, &keysym, &compose);
  549. X    if (!status || !isascii(c) || !isprint(c))
  550. X        return;
  551. X    ConcealCursor(buf);
  552. X    while (mbuf(size) < mbuf(len) + mbuf(arg)) {     /* Need more space */
  553. X        mbuf(size) += BUF_BLOCK;
  554. X        if (mbuf(string) == NULL)
  555. X            mbuf(string) = XtMalloc((unsigned) mbuf(size));
  556. X        else 
  557. X            mbuf(string) = XtRealloc(mbuf(string), (unsigned) mbuf(size));
  558. X        if (mbuf(string) == NULL) {
  559. X            mbuf(size) = 0;
  560. X            mbuf(len) = 0;
  561. X            mbuf(inputMode) = FALSE;
  562. X            QuitInput(w, event, params, numparams);
  563. X            return;
  564. X        }
  565. X    }
  566. X
  567. X    bcopy(mbuf(string) + i, mbuf(string) + i + mbuf(arg),
  568. X     mbuf(len) - i);
  569. X    mbuf(len) += mbuf(arg);
  570. X    for (; j > 0; j--,i++) {
  571. X        mbuf(string)[i] = c;
  572. X    }
  573. X    DisplayBuf(buf, FALSE);
  574. X    mbuf(cursorPos) += mbuf(arg);
  575. X    mbuf(arg) = 1;
  576. X    DisplayCursor(buf);
  577. X}
  578. X
  579. X
  580. X/*ARGSUSED*/
  581. Xstatic void CursorBack(w, event, params, numparams)
  582. XWidget w;
  583. XXEvent *event;
  584. XString *params;
  585. XCardinal *numparams;
  586. X{
  587. X    register MinibufWidget buf = (MinibufWidget) w;
  588. X    register int i;
  589. X    
  590. X    CheckMode();
  591. X    if ((i = (mbuf(cursorPos) - mbuf(arg))) < mbuf(promptLen))
  592. X        i = mbuf(promptLen);
  593. X
  594. X    ConcealCursor(buf);
  595. X    mbuf(cursorPos) = i;
  596. X    mbuf(arg) = 1;
  597. X    DisplayCursor(buf);
  598. X}
  599. X
  600. X
  601. X/*ARGSUSED*/
  602. Xstatic void CursorForward(w, event, params, numparams)
  603. XWidget w;
  604. XXEvent *event;
  605. XString *params;
  606. XCardinal *numparams;
  607. X{
  608. X    register MinibufWidget buf = (MinibufWidget) w;
  609. X    register int i;
  610. X    
  611. X    CheckMode();
  612. X    if ((i = (mbuf(cursorPos) + mbuf(arg))) > mbuf(len))
  613. X        i = mbuf(len);
  614. X
  615. X    ConcealCursor(buf);
  616. X    mbuf(cursorPos) = i;
  617. X    mbuf(arg) = 1;
  618. X    DisplayCursor(buf);
  619. X}
  620. X
  621. X
  622. X/*ARGSUSED*/
  623. Xstatic void SetCursor(w, event, params, numparams)
  624. XWidget w;
  625. XXEvent *event;
  626. XString *params;
  627. XCardinal *numparams;
  628. X{
  629. X    register MinibufWidget buf = (MinibufWidget) w;
  630. X    Window foo1, foo2;
  631. X    int foo3, foo4;
  632. X    unsigned int foo5;
  633. X    int x, y;
  634. X    register int mCol;
  635. X
  636. X    CheckMode();
  637. X    (void) XQueryPointer(XtDisplay(w), XtWindow(w),
  638. X     &foo1, &foo2, &foo3, &foo4, &x, &y, &foo5);
  639. X    mCol = x / fontwidth(mbuf(finfo));
  640. X    ConcealCursor(buf);
  641. X    mbuf(cursorPos) = mbuf(startPos) + mCol;
  642. X    mbuf(arg) = 1;
  643. X    DisplayCursor(buf);
  644. X}
  645. X
  646. X/* 
  647. X *  Tries to flash the cursor to the mark, and then back to the cursor
  648. X *  position. This will only be useful when bound to the mouse buttons.
  649. X */
  650. X/*ARGSUSED*/
  651. Xstatic void SetMark(w, event, params, numparams)
  652. XWidget w;
  653. XXEvent *event;
  654. XString *params;
  655. XCardinal *numparams;
  656. X{
  657. X    register MinibufWidget buf = (MinibufWidget) w;
  658. X    register int tmp;
  659. X    Window foo1, foo2;
  660. X    int foo3, foo4;
  661. X    unsigned int foo5;
  662. X    int x, y;
  663. X    register int mCol;
  664. X
  665. X    CheckMode();
  666. X    tmp = mbuf(cursorPos);
  667. X    (void) XQueryPointer(XtDisplay(w), XtWindow(w),
  668. X     &foo1, &foo2, &foo3, &foo4, &x, &y, &foo5);
  669. X    mCol = x / fontwidth(mbuf(finfo));
  670. X    ConcealCursor(buf);
  671. X    mbuf(cursorPos) = mbuf(mark) = mbuf(startPos) + mCol;
  672. X    DisplayCursor(buf);
  673. X    XFlush(XtDisplay(w));
  674. X    usleep(DELAY);
  675. X    ConcealCursor(buf);
  676. X    mbuf(cursorPos) = tmp;
  677. X    DisplayCursor(buf);
  678. X    mbuf(arg) = 1;
  679. X}
  680. X
  681. X
  682. X
  683. X/* The universal argument has no effect on this one */
  684. X/*ARGSUSED*/
  685. Xstatic void BeginningOfBuf(w, event, params, numparams)
  686. XWidget w;
  687. XXEvent *event;
  688. XString *params;
  689. XCardinal *numparams;
  690. X{
  691. X    register MinibufWidget buf = (MinibufWidget) w;
  692. X    CheckMode();
  693. X    ConcealCursor(buf);
  694. X    mbuf(cursorPos) = mbuf(promptLen);
  695. X    DisplayCursor(buf);
  696. X}
  697. X
  698. X
  699. X
  700. X/* The universal argument has no effect on this one */
  701. X/*ARGSUSED*/
  702. Xstatic void EndOfBuf(w, event, params, numparams)
  703. XWidget w;
  704. XXEvent *event;
  705. XString *params;
  706. XCardinal *numparams;
  707. X{
  708. X    register MinibufWidget buf = (MinibufWidget) w;
  709. X
  710. X    CheckMode();
  711. X    ConcealCursor(buf);
  712. X    mbuf(cursorPos) = mbuf(len);
  713. X    DisplayCursor(buf);
  714. X}
  715. X
  716. X
  717. X
  718. X/*ARGSUSED*/
  719. Xstatic void DeleteCharForward(w, event, params, numparams)
  720. XWidget w;
  721. XXEvent *event;
  722. XString *params;
  723. XCardinal *numparams;
  724. X{
  725. X    register MinibufWidget buf = (MinibufWidget) w;
  726. X    register int i;
  727. X
  728. X    CheckMode();
  729. X    if ((i = (mbuf(cursorPos) + mbuf(arg))) > mbuf(len))
  730. X        i = mbuf(len);
  731. X
  732. X    ConcealCursor(buf);
  733. X    bcopy(mbuf(string) + i, mbuf(string) + mbuf(cursorPos), mbuf(len) - i);
  734. X    mbuf(len) -= i - mbuf(cursorPos);
  735. X    mbuf(arg) = 1;
  736. X    DisplayBuf(buf, FALSE);
  737. X    DisplayCursor(buf);
  738. X}
  739. X
  740. X
  741. X/*ARGSUSED*/
  742. Xstatic void DeleteCharBack(w, event, params, numparams)
  743. XWidget w;
  744. XXEvent *event;
  745. XString *params;
  746. XCardinal *numparams;
  747. X{
  748. X    register MinibufWidget buf = (MinibufWidget) w;
  749. X    register int i;
  750. X
  751. X    CheckMode();
  752. X    if ((i = (mbuf(cursorPos) - mbuf(arg))) < mbuf(promptLen))
  753. X        i = mbuf(promptLen);
  754. X
  755. X    ConcealCursor(buf);
  756. X    bcopy(mbuf(string) + mbuf(cursorPos), mbuf(string) + i, mbuf(len) - i);
  757. X    mbuf(len) += i - mbuf(cursorPos);
  758. X    mbuf(cursorPos) = i;
  759. X    mbuf(arg) = 1;
  760. X    DisplayBuf(buf, FALSE);
  761. X    DisplayCursor(buf);
  762. X}
  763. X
  764. X
  765. X
  766. X
  767. X/* The universal argument has no effect on this one */
  768. X/* Like Setmark, this flashes the cursor */
  769. X/*ARGSUSED*/
  770. Xstatic void MakeMark(w, event, params, numparams)
  771. XWidget w;
  772. XXEvent *event;
  773. XString *params;
  774. XCardinal *numparams;
  775. X{
  776. X    register MinibufWidget buf = (MinibufWidget) w;
  777. X
  778. X    CheckMode();
  779. X    mbuf(mark) = mbuf(cursorPos);
  780. X    mbuf(arg) = 1;
  781. X}
  782. X
  783. X
  784. X
  785. X/*ARGSUSED*/
  786. Xstatic void ExchangeMarkAndPoint(w, event, params, numparams)
  787. XWidget w;
  788. XXEvent *event;
  789. XString *params;
  790. XCardinal *numparams;
  791. X{
  792. X    register MinibufWidget buf = (MinibufWidget) w;
  793. X    register int tmp = mbuf(cursorPos);
  794. X
  795. X    CheckMode();
  796. X    if (mbuf(mark) < mbuf(promptLen))
  797. X        mbuf(mark) = mbuf(promptLen);
  798. X
  799. X    if (mbuf(mark) > mbuf(len))
  800. X        mbuf(mark) = mbuf(len);
  801. X        
  802. X    ConcealCursor(buf);
  803. X    mbuf(cursorPos) = mbuf(mark);
  804. X    mbuf(mark) = tmp;
  805. X    mbuf(arg) = 1;
  806. X    DisplayCursor(buf);
  807. X    
  808. X}
  809. X
  810. X
  811. X
  812. X/* The universal argument has no effect on this one */
  813. X/*ARGSUSED*/
  814. Xstatic void CutMarkToPoint(w, event, params, numparams)
  815. XWidget w;
  816. XXEvent *event;
  817. XString *params;
  818. XCardinal *numparams;
  819. X{
  820. X    register MinibufWidget buf = (MinibufWidget) w;
  821. X    register int lower, upper;
  822. X    static void QuitInput();
  823. X
  824. X    CheckMode();
  825. X
  826. X    if (mbuf(mark) < mbuf(promptLen))
  827. X        mbuf(mark) = mbuf(promptLen);
  828. X        
  829. X    if (mbuf(mark) > mbuf(len))
  830. X        mbuf(mark) = mbuf(len);
  831. X
  832. X    if (mbuf(mark) < mbuf(cursorPos)) {
  833. X         lower = mbuf(mark);
  834. X        upper = mbuf(cursorPos);
  835. X    } else {
  836. X        lower = mbuf(cursorPos);
  837. X        upper = mbuf(mark);
  838. X    }
  839. X
  840. X    mbuf(killBufferLen) = upper - lower;
  841. X    while (mbuf(killBufferLen) > mbuf(killBufferSize)) {
  842. X         mbuf(killBufferSize) += BUF_BLOCK;
  843. X        if (mbuf(killBuffer) == NULL)
  844. X            mbuf(killBuffer) = XtMalloc((unsigned) mbuf(size));
  845. X        else 
  846. X            mbuf(killBuffer) = XtRealloc(mbuf(killBuffer),
  847. X             (unsigned) mbuf(size));
  848. X         if (mbuf(killBuffer) == NULL) {
  849. X             mbuf(killBufferSize) = 0;
  850. X            mbuf(killBufferLen) = 0;
  851. X            mbuf(inputMode) = FALSE;
  852. X            QuitInput(w, event, params, numparams);
  853. X            return;
  854. X        }
  855. X    }
  856. X
  857. X    ConcealCursor(buf);
  858. X    bcopy(mbuf(string) + lower, mbuf(killBuffer), mbuf(killBufferLen));
  859. X    bcopy(mbuf(string) + upper, mbuf(string) + lower, mbuf(len) - upper);
  860. X    mbuf(cursorPos) = mbuf(mark) = lower;
  861. X    mbuf(len) -= mbuf(killBufferLen);
  862. X    mbuf(arg) = 1;
  863. X    DisplayBuf(buf, FALSE);
  864. X    DisplayCursor(buf);
  865. X}
  866. X
  867. X
  868. X
  869. X/* The universal argument has no effect on this one */
  870. X/*ARGSUSED*/
  871. Xstatic void KillToEnd(w, event, params, numparams)
  872. XWidget w;
  873. XXEvent *event;
  874. XString *params;
  875. XCardinal *numparams;
  876. X{
  877. X    register MinibufWidget buf = (MinibufWidget) w;
  878. X    register int tmp_mark;
  879. X
  880. X    CheckMode();
  881. X    tmp_mark = mbuf(mark);
  882. X    mbuf(mark) = mbuf(len);
  883. X    CutMarkToPoint(w, event, params, numparams);
  884. X    mbuf(mark) = tmp_mark;
  885. X}
  886. X
  887. X
  888. X
  889. X/* The universal argument has no effect on this one */
  890. X/*ARGSUSED*/
  891. Xstatic void KillToBeginning(w, event, params, numparams)
  892. XWidget w;
  893. XXEvent *event;
  894. XString *params;
  895. XCardinal *numparams;
  896. X{
  897. X    register MinibufWidget buf = (MinibufWidget) w;
  898. X    register int tmp_mark;
  899. X    
  900. X    CheckMode();
  901. X    tmp_mark = mbuf(mark);
  902. X    mbuf(mark) = mbuf(promptLen);
  903. X    CutMarkToPoint(w, event, params, numparams);
  904. X    mbuf(mark) = tmp_mark;
  905. X}
  906. X
  907. X
  908. X
  909. X/*ARGSUSED*/
  910. Xstatic void UnivArgument(w, event, params, numparams)
  911. XWidget w;
  912. XXEvent *event;
  913. XString *params;
  914. XCardinal *numparams;
  915. X{
  916. X    register MinibufWidget buf = (MinibufWidget) w;
  917. X
  918. X    CheckMode();
  919. X    mbuf(arg) *= 4;
  920. X}
  921. X
  922. X
  923. X/*
  924. X *  The universal argument has no effect on this one - maybe it should,
  925. X *  I'm not sure. So I'll take the easy way out
  926. X */
  927. X/*ARGSUSED*/
  928. Xstatic void YankKilledStuff(w, event, params, numparams)
  929. XWidget w;
  930. XXEvent *event;
  931. XString *params;
  932. XCardinal *numparams;
  933. X{
  934. X    register MinibufWidget buf = (MinibufWidget) w;
  935. X
  936. X    CheckMode();
  937. X    ConcealCursor(buf);
  938. X    mbuf(mark) = mbuf(cursorPos);
  939. X    StrInsert(mbuf(killBuffer), mbuf(killBufferLen), buf);
  940. X    DisplayCursor(buf);
  941. X}
  942. X
  943. X
  944. X/*ARGSUSED*/
  945. Xstatic void GetXBuffer(w, event, params, numparams)
  946. XWidget w;
  947. XXEvent *event;
  948. XString *params;
  949. XCardinal *numparams;
  950. X{
  951. X    register MinibufWidget buf = (MinibufWidget) w;
  952. X    register char *s;
  953. X    int nBytes;
  954. X    
  955. X    CheckMode();
  956. X    ConcealCursor(buf);
  957. X    s = XFetchBytes(XtDisplay(w), &nBytes);
  958. X    StrInsert(s, nBytes, buf);
  959. X    DisplayCursor(buf);
  960. X}
  961. X
  962. X
  963. X
  964. X/*ARGSUSED*/
  965. Xstatic void FinishedInput(w, event, params, numparams)
  966. XWidget w;
  967. XXEvent *event;
  968. XString *params;
  969. XCardinal *numparams;
  970. X{
  971. X    register MinibufWidget buf = (MinibufWidget) w;
  972. X    register char *s;
  973. X    register int len = mbuf(len) - mbuf(promptLen);
  974. X
  975. X    CheckMode();
  976. X    ConcealCursor(buf);
  977. X    XFlush(XtDisplay(w));
  978. X    mbuf(len) = 0;
  979. X    mbuf(cursorPos) = mbuf(startPos) = 0;
  980. X    mbuf(inputMode) = FALSE;
  981. X    if ((s = XtMalloc((unsigned) (len + 1))) != NULL) {
  982. X        bcopy(mbuf(string) + mbuf(promptLen), s, len);
  983. X        s[len] = '\0';
  984. X    }
  985. X    XtCallCallbacks(w, XtNfinishedCallback, s);
  986. X}
  987. X
  988. X
  989. X/*ARGSUSED*/
  990. Xstatic void QuitInput(w, event, params, numparams)
  991. XWidget w;
  992. XXEvent *event;
  993. XString *params;
  994. XCardinal *numparams;
  995. X{
  996. X    register MinibufWidget buf = (MinibufWidget) w;
  997. X    char *savestr;
  998. X    int savelen;
  999. X
  1000. X    CheckMode();
  1001. X    ConcealCursor(buf);
  1002. X    mbuf(len) = 0;
  1003. X    mbuf(cursorPos) = mbuf(startPos) = 0;
  1004. X    mbuf(inputMode) = FALSE;
  1005. X
  1006. X    savestr = mbuf(string);
  1007. X    savelen = mbuf(len);
  1008. X    mbuf(string) = ABORT_MSG;
  1009. X    mbuf(len) = strlen(ABORT_MSG);
  1010. X    DisplayBuf(buf, TRUE);
  1011. X    XFlush(XtDisplay(w));
  1012. X    mbuf(string) = savestr;
  1013. X    mbuf(len) = savelen;
  1014. X    
  1015. X    /*
  1016. X     *  We don't redisplay the cursor - we've gone out of input mode, but
  1017. X     *  we invoke the callback which tells the user about this
  1018. X     */
  1019. X    XtCallCallbacks(w, XtNfinishedCallback, (caddr_t) NULL);
  1020. X}
  1021. X
  1022. Xstatic MinibufWidget curbuf = NULL;
  1023. X
  1024. X/*ARGSUSED*/
  1025. Xstatic void CompleteFilename(w, event, params, numparams)
  1026. XWidget w;
  1027. XXEvent *event;
  1028. XString *params;
  1029. XCardinal *numparams;
  1030. X{
  1031. X    register MinibufWidget buf = (MinibufWidget) w;
  1032. X
  1033. X    CheckMode();
  1034. X    if (!mbuf(completion)) {
  1035. X        CharInsert(w, event, params, numparams);
  1036. X        return;
  1037. X    }
  1038. X    ConcealCursor(buf);
  1039. X    mbuf(string)[mbuf(len)] = '\0';
  1040. X    mbuf(cursorPos) = mbuf(len);
  1041. X    curbuf = buf;
  1042. X    (void) f_complete(mbuf(string) + mbuf(promptLen), 
  1043. X     mbuf(cursorPos) - mbuf(promptLen), 0, ' ');
  1044. X    DisplayCursor(buf);
  1045. X    
  1046. X}
  1047. X
  1048. Xvoid rbell()
  1049. X{
  1050. X    register MinibufWidget buf = curbuf;
  1051. X    
  1052. X    XBell(XtDisplay(mcore(self)), 0);
  1053. X}
  1054. X
  1055. X/*
  1056. X *  'at' is somewhere in mbuf(string), and we replace from 'at' to the
  1057. X *  end of the line with the first 'len' chars of string 's' - 'curpos'
  1058. X *  is updated.
  1059. X */
  1060. Xvoid insert_s(at, s, len, curpos)
  1061. Xchar *at;
  1062. Xchar *s;
  1063. Xint *curpos;
  1064. X{
  1065. X    register MinibufWidget buf = curbuf;
  1066. X    
  1067. X    mbuf(len) = mbuf(cursorPos) = at - mbuf(string);
  1068. X    *at = '\0';
  1069. X    StrInsert(s, len, buf);
  1070. X    *curpos = mbuf(cursorPos) - mbuf(promptLen);
  1071. X    mbuf(string)[mbuf(len)] = '\0';
  1072. X}
  1073. X
  1074. X/* add_mess(s) char *s;
  1075. X *    inserts 's' at the end of the buffer, then waits a respectable
  1076. X *    interval, deletes 's', and returns
  1077. X */
  1078. Xvoid add_mess(s)
  1079. Xchar *s;
  1080. X{
  1081. X    register MinibufWidget buf = curbuf;
  1082. X    int savecursor = mbuf(cursorPos);
  1083. X    
  1084. X    StrInsert(s, strlen(s), buf);
  1085. X    DisplayCursor(buf);
  1086. X    ConcealCursor(buf);
  1087. X    rbell();
  1088. X    usleep(DELAY);
  1089. X    mbuf(len) = mbuf(cursorPos) = savecursor;
  1090. X    mbuf(string)[savecursor] = '\0';
  1091. X    DisplayBuf(buf, FALSE);
  1092. X}
  1093. X
  1094. X/*ARGSUSED*/
  1095. Xstatic void ListFiles(w, event, params, numparams)
  1096. XWidget w;
  1097. XXEvent *event;
  1098. XString *params;
  1099. XCardinal *numparams;
  1100. X{
  1101. X    register MinibufWidget buf = (MinibufWidget) w;
  1102. X
  1103. X    CheckMode();
  1104. X    if (!mbuf(completion)) {
  1105. X        CharInsert(w, event, params, numparams);
  1106. X        return;
  1107. X    }
  1108. X    /* 
  1109. X     *  We haven't implemented a proper window typeout yet - if I
  1110. X     *  can manage it with the Text widget, but right now, it
  1111. X     *  redraws twice, and refuses to go away unless you take the
  1112. X     *  mouse into that window and click - yech!
  1113. X     */
  1114. X    curbuf = (MinibufWidget) w;
  1115. X#ifdef TYPEOUT
  1116. X    if (mbuf(typeout)) {
  1117. X        (void) f_complete(mbuf(string) + mbuf(promptLen), 
  1118. X         mbuf(cursorPos) - mbuf(promptLen), mbuf(typeoutColumns), '?');
  1119. X    } else
  1120. X#endif TYPEOUT
  1121. X        rbell();
  1122. X}
  1123. X
  1124. X/* 
  1125. X *  Public routines - these should probably be done with XtSetValues()
  1126. X *  but that means more work... Sigh!
  1127. X */
  1128. Xvoid MinibufGetInput(w, prompt, defaultInput, complete)
  1129. XWidget w;
  1130. Xregister char *prompt;
  1131. Xregister char *defaultInput;
  1132. X{
  1133. X    register MinibufWidget buf = (MinibufWidget) w;
  1134. X    if (buf == NULL) {
  1135. X        return;
  1136. X    }
  1137. X    
  1138. X    mbuf(cursorPos) = mbuf(len) = 0;
  1139. X    if (prompt != NULL) {
  1140. X        StrInsert(prompt, strlen(prompt), buf);
  1141. X    }
  1142. X    
  1143. X    mbuf(promptLen) = mbuf(cursorPos);
  1144. X
  1145. X    if (defaultInput != NULL) {
  1146. X        StrInsert(defaultInput, strlen(defaultInput), buf);
  1147. X        mbuf(cursorPos) = mbuf(promptLen);
  1148. X    }
  1149. X    mbuf(inputMode) = TRUE;
  1150. X    mbuf(completion) = complete;
  1151. X    DisplayCursor(buf);
  1152. X    /*
  1153. X     *  Focus events on the widget exclusively, not spring loaded - we
  1154. X     *  remove the grab in the callback
  1155. X     */
  1156. X}
  1157. X    
  1158. X
  1159. X/*
  1160. X *  This displays msg in the buffer - since it uses the string passed in
  1161. X *  directly, and does not affect the buffer string (which is saved and
  1162. X *  restored), it should result in no more mallocs.
  1163. X */
  1164. Xvoid MinibufDisplayMessage(w, msg, ringbell)
  1165. XWidget w;
  1166. Xregister char *msg;
  1167. Xint ringbell;    /* Do we want bell to sound */
  1168. X{
  1169. X    register MinibufWidget buf = (MinibufWidget) w;
  1170. X    char *savestr;
  1171. X    int savelen;
  1172. X
  1173. X    if (buf == NULL || msg == NULL) {
  1174. X        return;
  1175. X    }
  1176. X    
  1177. X    mbuf(inputMode) = FALSE;
  1178. X    mbuf(len) = mbuf(cursorPos) = mbuf(startPos) = 0;
  1179. X    savestr = mbuf(string);
  1180. X    savelen = mbuf(len);
  1181. X    mbuf(string) = msg;
  1182. X    mbuf(len) = strlen(msg);
  1183. X    
  1184. X    DisplayBuf(buf, TRUE);
  1185. X    XFlush(XtDisplay(w));
  1186. X    if (ringbell)        /* Maybe a visible bell for fun! One day...*/
  1187. X        XBell(XtDisplay(w), 0);
  1188. X    mbuf(string) = savestr;
  1189. X    mbuf(len) = savelen;
  1190. X}
  1191. X
  1192. END_OF_FILE
  1193. if test 29988 -ne `wc -c <'xpic/Minibuf.c'`; then
  1194.     echo shar: \"'xpic/Minibuf.c'\" unpacked with wrong size!
  1195. fi
  1196. # end of 'xpic/Minibuf.c'
  1197. fi
  1198. echo shar: End of archive 15 \(of 15\).
  1199. cp /dev/null ark15isdone
  1200. MISSING=""
  1201. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ; do
  1202.     if test ! -f ark${I}isdone ; then
  1203.     MISSING="${MISSING} ${I}"
  1204.     fi
  1205. done
  1206. if test "${MISSING}" = "" ; then
  1207.     echo You have unpacked all 15 archives.
  1208.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1209. else
  1210.     echo You still need to unpack the following archives:
  1211.     echo "        " ${MISSING}
  1212. fi
  1213. ##  End of shell archive.
  1214. exit 0
  1215.