home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume4 / xconf / part02 < prev    next >
Encoding:
Internet Message Format  |  1993-05-04  |  55.4 KB

  1. From: argv@island.uu.net (Dan Heller)
  2. Newsgroups: comp.sources.x
  3. Subject: v04i083: xconf -- X-based conferencing tool, Part02/05
  4. Message-ID: <934@island.uu.net>
  5. Date: 25 Jul 89 08:10:51 GMT
  6. Approved: island!argv@sun.com
  7.  
  8. Submitted-by: Jon Crowcroft <J.Crowcroft@Cs.Ucl.AC.UK>
  9. Posting-number: Volume 4, Issue 83
  10. Archive-name: xconf/part02
  11.  
  12.  
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then feed it
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  19. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  20. # If this archive is complete, you will see the following message at the end:
  21. #        "End of archive 2 (of 5)."
  22. # Contents:  xconf/AsciiSink.c xconf/GCManager.c xconf/Makefile
  23. #   xconf/Text.c.ab
  24. # Wrapped by argv@sumatra on Tue Jul 25 01:01:05 1989
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f 'xconf/AsciiSink.c' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'xconf/AsciiSink.c'\"
  28. else
  29. echo shar: Extracting \"'xconf/AsciiSink.c'\" \(15302 characters\)
  30. sed "s/^X//" >'xconf/AsciiSink.c' <<'END_OF_FILE'
  31. X#ifndef lint
  32. Xstatic char Xrcsid[] = "$XConsortium: AsciiSink.c,v 1.26 88/10/19 20:08:51 swick Exp $";
  33. X#endif lint
  34. X
  35. X
  36. X/***********************************************************
  37. XCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
  38. Xand the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  39. X
  40. X                        All Rights Reserved
  41. X
  42. XPermission to use, copy, modify, and distribute this software and its 
  43. Xdocumentation for any purpose and without fee is hereby granted, 
  44. Xprovided that the above copyright notice appear in all copies and that
  45. Xboth that copyright notice and this permission notice appear in 
  46. Xsupporting documentation, and that the names of Digital or MIT not be
  47. Xused in advertising or publicity pertaining to distribution of the
  48. Xsoftware without specific, written prior permission.  
  49. X
  50. XDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  51. XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  52. XDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  53. XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  54. XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  55. XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  56. XSOFTWARE.
  57. X
  58. X******************************************************************/
  59. X
  60. X#include <X11/Xlib.h>
  61. X#include <X11/Xutil.h>
  62. X#include <X11/Xatom.h>
  63. X#include <X11/IntrinsicP.h>
  64. X#include <X11/StringDefs.h>
  65. X#ifdef JON
  66. X#include "TextP.h"
  67. X#else JON
  68. X#include <X11/TextP.h>
  69. X#endif JON
  70. X
  71. X
  72. X#define GETLASTPOS (*source->Scan)(source, 0, XtstAll, XtsdRight, 1, TRUE)
  73. X/* Private Ascii TextSink Definitions */
  74. X
  75. Xstatic unsigned bufferSize = 200;
  76. X
  77. Xtypedef struct _AsciiSinkData {
  78. X    Pixel foreground;
  79. X    GC normgc, invgc, xorgc;
  80. X    XFontStruct *font;
  81. X    int em;
  82. X    Pixmap insertCursorOn;
  83. X    XtTextInsertState laststate;
  84. X    int tab_count;
  85. X    Position *tabs;
  86. X} AsciiSinkData, *AsciiSinkPtr;
  87. X
  88. Xstatic char *buf = NULL;
  89. X
  90. X/* XXX foreground default should be XtDefaultFGPixel. How do i do that?? */
  91. X
  92. Xstatic XtResource SinkResources[] = {
  93. X    {XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
  94. X        XtOffset(AsciiSinkPtr, font), XtRString, "Fixed"},
  95. X    {XtNforeground, XtCForeground, XtRPixel, sizeof (int),
  96. X        XtOffset(AsciiSinkPtr, foreground), XtRString, "Black"},    
  97. X};
  98. X
  99. X/* Utilities */
  100. X
  101. Xstatic int CharWidth (w, x, c)
  102. X  Widget w;
  103. X  int x;
  104. X  char c;
  105. X{
  106. X    AsciiSinkData *data = (AsciiSinkData*) ((TextWidget)w)->text.sink->data;
  107. X    int     width, nonPrinting;
  108. X    XFontStruct *font = data->font;
  109. X
  110. X    if (c == '\t') {
  111. X    int i;
  112. X    Position *tab;
  113. X    if (x >= w->core.width) return 0;
  114. X    for (i=0, tab=data->tabs; i<data->tab_count; i++, tab++) {
  115. X        if (x < *tab) {
  116. X        if (*tab < w->core.width)
  117. X            return *tab - x;
  118. X        else
  119. X            return 0;
  120. X        }
  121. X    }
  122. X    return 0;
  123. X    }
  124. X    if (c == LF)
  125. X    c = SP;
  126. X    nonPrinting = (c < SP);
  127. X    if (nonPrinting) c += '@';
  128. X
  129. X    if (font->per_char &&
  130. X        (c >= font->min_char_or_byte2 && c <= font->max_char_or_byte2))
  131. X    width = font->per_char[c - font->min_char_or_byte2].width;
  132. X    else
  133. X    width = font->min_bounds.width;
  134. X
  135. X    if (nonPrinting)
  136. X    width += CharWidth(w, x, '^');
  137. X
  138. X    return width;
  139. X}
  140. X
  141. X/* Sink Object Functions */
  142. X
  143. Xstatic int AsciiDisplayText (w, x, y, pos1, pos2, highlight)
  144. X  Widget w;
  145. X  Position x, y;
  146. X  int highlight;
  147. X  XtTextPosition pos1, pos2;
  148. X{
  149. X    XtTextSink sink = ((TextWidget)w)->text.sink;
  150. X    XtTextSource source = ((TextWidget)w)->text.source;
  151. X    AsciiSinkData *data = (AsciiSinkData *) sink->data ;
  152. X
  153. X    XFontStruct *font = data->font;
  154. X    int     j, k;
  155. X    Dimension width;
  156. X    XtTextBlock blk;
  157. X    GC gc = highlight ? data->invgc : data->normgc;
  158. X    GC invgc = highlight ? data->normgc : data->invgc;
  159. X
  160. X    y += font->ascent;
  161. X    j = 0;
  162. X    while (pos1 < pos2) {
  163. X    pos1 = (*source->Read)(source, pos1, &blk, pos2 - pos1);
  164. X    for (k = 0; k < blk.length; k++) {
  165. X        if (j >= bufferSize - 5) {
  166. X        bufferSize *= 2;
  167. X        buf = XtRealloc(buf, bufferSize);
  168. X        }
  169. X        buf[j] = blk.ptr[k];
  170. X        if (buf[j] == LF)
  171. X        buf[j] = ' ';
  172. X        else if (buf[j] == '\t') {
  173. X            XDrawImageString(XtDisplay(w), XtWindow(w),
  174. X            gc, x, y, buf, j);
  175. X        buf[j] = 0;
  176. X        x += XTextWidth(data->font, buf, j);
  177. X        width = CharWidth(w, x, '\t');
  178. X        XFillRectangle(XtDisplay(w), XtWindow(w), invgc, x,
  179. X                   y - font->ascent, width,
  180. X                   (Dimension) (data->font->ascent +
  181. X                        data->font->descent));
  182. X        x += width;
  183. X        j = -1;
  184. X        }
  185. X        else
  186. X        if (buf[j] < ' ') {
  187. X            buf[j + 1] = buf[j] + '@';
  188. X            buf[j] = '^';
  189. X            j++;
  190. X        }
  191. X        j++;
  192. X    }
  193. X    }
  194. X    XDrawImageString(XtDisplay(w), XtWindow(w), gc, x, y, buf, j);
  195. X}
  196. X
  197. X
  198. X#define insertCursor_width 6
  199. X#define insertCursor_height 3
  200. Xstatic char insertCursor_bits[] = {0x0c, 0x1e, 0x33};
  201. X
  202. X#ifdef SERVERNOTBROKEN
  203. Xstatic Pixmap CreateInsertCursor(s)
  204. XScreen *s;
  205. X{
  206. X    return (XCreateBitmapFromData (DisplayOfScreen(s), RootWindowOfScreen(s),
  207. X        insertCursor_bits, insertCursor_width, insertCursor_height));
  208. X}
  209. X#endif
  210. X
  211. X/*
  212. X * The following procedure manages the "insert" cursor.
  213. X */
  214. X
  215. Xstatic AsciiInsertCursor (w, x, y, state)
  216. X  Widget w;
  217. X  Position x, y;
  218. X  XtTextInsertState state;
  219. X{
  220. X    XtTextSink sink = ((TextWidget)w)->text.sink;
  221. X    AsciiSinkData *data = (AsciiSinkData *) sink->data;
  222. X
  223. X/*
  224. X    XCopyArea(sink->dpy,
  225. X          (state == XtisOn) ? data->insertCursorOn : data->insertCursorOff,
  226. X          w, data->normgc, 0, 0, insertCursor_width, insertCursor_height,
  227. X          x - (insertCursor_width >> 1), y - (insertCursor_height));
  228. X*/
  229. X
  230. X    if (state != data->laststate && XtIsRealized(w)) {
  231. X#ifdef SERVERNOTBROKEN
  232. X    XCopyPlane(XtDisplay(w),
  233. X          data->insertCursorOn, XtWindow(w),
  234. X          data->xorgc, 0, 0, insertCursor_width, insertCursor_height,
  235. X          x - (insertCursor_width >> 1), y - (insertCursor_height), 1);
  236. X#else /* SERVER is BROKEN */
  237. X    /*
  238. X     * See the comment down at the bottom where the pixmap gets built
  239. X     * for why we are doing this this way.
  240. X     */
  241. X    XCopyArea (XtDisplay(w), data->insertCursorOn, XtWindow (w),
  242. X           data->xorgc, 0, 0, insertCursor_width, insertCursor_height,
  243. X           x - (insertCursor_width >> 1), y - (insertCursor_height));
  244. X#endif /* SERVERNOTBROKEN */
  245. X    }
  246. X    data->laststate = state;
  247. X}
  248. X
  249. X/*
  250. X * Clear the passed region to the background color.
  251. X */
  252. X
  253. Xstatic AsciiClearToBackground (w, x, y, width, height)
  254. X  Widget w;
  255. X  Position x, y;
  256. X  Dimension width, height;
  257. X{
  258. X#ifndef USE_CLEAR_AREA
  259. X    XFillRectangle(XtDisplay(w), XtWindow(w),
  260. X           ((AsciiSinkData*)((TextWidget)w)->text.sink->data)->invgc,
  261. X           x, y, width, height);
  262. X#else
  263. X    XClearArea(XtDisplay(w), XtWindow(w), x, y, width, height, False);
  264. X#endif /*USE_CLEAR_AREA*/
  265. X}
  266. X
  267. X/*
  268. X * Given two positions, find the distance between them.
  269. X */
  270. X
  271. Xstatic AsciiFindDistance (w, fromPos, fromx, toPos,
  272. X              resWidth, resPos, resHeight)
  273. X  Widget w;
  274. X  XtTextPosition fromPos;    /* First position. */
  275. X  int fromx;            /* Horizontal location of first position. */
  276. X  XtTextPosition toPos;        /* Second position. */
  277. X  int *resWidth;        /* Distance between fromPos and resPos. */
  278. X  XtTextPosition *resPos;    /* Actual second position used. */
  279. X  int *resHeight;        /* Height required. */
  280. X{
  281. X    XtTextSink sink = ((TextWidget)w)->text.sink;
  282. X    XtTextSource source = ((TextWidget)w)->text.source;
  283. X
  284. X    AsciiSinkData *data;
  285. X    register    XtTextPosition index, lastPos;
  286. X    register char   c;
  287. X    XtTextBlock blk;
  288. X
  289. X    data = (AsciiSinkData *) sink->data;
  290. X    /* we may not need this */
  291. X    lastPos = GETLASTPOS;
  292. X    (*source->Read)(source, fromPos, &blk, toPos - fromPos);
  293. X    *resWidth = 0;
  294. X    for (index = fromPos; index != toPos && index < lastPos; index++) {
  295. X    if (index - blk.firstPos >= blk.length)
  296. X        (*source->Read)(source, index, &blk, toPos - fromPos);
  297. X    c = blk.ptr[index - blk.firstPos];
  298. X    if (c == LF) {
  299. X        *resWidth += CharWidth(w, fromx + *resWidth, SP);
  300. X        index++;
  301. X        break;
  302. X    }
  303. X    *resWidth += CharWidth(w, fromx + *resWidth, c);
  304. X    }
  305. X    *resPos = index;
  306. X    *resHeight = data->font->ascent + data->font->descent;
  307. X}
  308. X
  309. X
  310. Xstatic AsciiFindPosition(w, fromPos, fromx, width, stopAtWordBreak, 
  311. X             resPos, resWidth, resHeight)
  312. X  Widget w;
  313. X  XtTextPosition fromPos;     /* Starting position. */
  314. X  int fromx;            /* Horizontal location of starting position. */
  315. X  int width;            /* Desired width. */
  316. X  int stopAtWordBreak;        /* Whether the resulting position should be at
  317. X                   a word break. */
  318. X  XtTextPosition *resPos;    /* Resulting position. */
  319. X  int *resWidth;        /* Actual width used. */
  320. X  int *resHeight;        /* Height required. */
  321. X{
  322. X    XtTextSink sink = ((TextWidget)w)->text.sink;
  323. X    XtTextSource source = ((TextWidget)w)->text.source;
  324. X    AsciiSinkData *data;
  325. X    XtTextPosition lastPos, index, whiteSpacePosition;
  326. X    int     lastWidth, whiteSpaceWidth;
  327. X    Boolean whiteSpaceSeen;
  328. X    char    c;
  329. X    XtTextBlock blk;
  330. X    data = (AsciiSinkData *) sink->data;
  331. X    lastPos = GETLASTPOS;
  332. X
  333. X    (*source->Read)(source, fromPos, &blk, bufferSize);
  334. X    *resWidth = 0;
  335. X    whiteSpaceSeen = FALSE;
  336. X    c = 0;
  337. X    for (index = fromPos; *resWidth <= width && index < lastPos; index++) {
  338. X    lastWidth = *resWidth;
  339. X    if (index - blk.firstPos >= blk.length)
  340. X        (*source->Read)(source, index, &blk, bufferSize);
  341. X    c = blk.ptr[index - blk.firstPos];
  342. X    if (c == LF) {
  343. X        *resWidth += CharWidth(w, fromx + *resWidth, SP);
  344. X        index++;
  345. X        break;
  346. X    }
  347. X    *resWidth += CharWidth(w, fromx + *resWidth, c);
  348. X    if ((c == SP || c == TAB) && *resWidth <= width) {
  349. X        whiteSpaceSeen = TRUE;
  350. X        whiteSpacePosition = index;
  351. X        whiteSpaceWidth = *resWidth;
  352. X    }
  353. X    }
  354. X    if (*resWidth > width && index > fromPos) {
  355. X    *resWidth = lastWidth;
  356. X    index--;
  357. X    if (stopAtWordBreak && whiteSpaceSeen) {
  358. X        index = whiteSpacePosition + 1;
  359. X        *resWidth = whiteSpaceWidth;
  360. X    }
  361. X    }
  362. X    if (index == lastPos && c != LF) index = lastPos + 1;
  363. X    *resPos = index;
  364. X    *resHeight = data->font->ascent + data->font->descent;
  365. X}
  366. X
  367. X
  368. Xstatic int AsciiResolveToPosition (w, pos, fromx, width,
  369. X                   leftPos, rightPos)
  370. X  Widget w;
  371. X  XtTextPosition pos;
  372. X  int fromx,width;
  373. X  XtTextPosition *leftPos, *rightPos;
  374. X{
  375. X    int     resWidth, resHeight;
  376. X    XtTextSource source = ((TextWidget)w)->text.source;
  377. X
  378. X    AsciiFindPosition(w, pos, fromx, width, FALSE,
  379. X        leftPos, &resWidth, &resHeight);
  380. X    if (*leftPos > GETLASTPOS)
  381. X    *leftPos = GETLASTPOS;
  382. X    *rightPos = *leftPos;
  383. X}
  384. X
  385. X
  386. Xstatic int AsciiMaxLinesForHeight (w, height)
  387. X  Widget w;
  388. X  Dimension height;
  389. X{
  390. X    AsciiSinkData *data;
  391. X    XtTextSink sink = ((TextWidget)w)->text.sink;
  392. X
  393. X    data = (AsciiSinkData *) sink->data;
  394. X    return(height / (data->font->ascent + data->font->descent));
  395. X}
  396. X
  397. X
  398. Xstatic int AsciiMaxHeightForLines (w, lines)
  399. X  Widget w;
  400. X  int lines;
  401. X{
  402. X    AsciiSinkData *data;
  403. X    XtTextSink sink = ((TextWidget)w)->text.sink;
  404. X
  405. X    data = (AsciiSinkData *) sink->data;
  406. X    return(lines * (data->font->ascent + data->font->descent));
  407. X}
  408. X
  409. X
  410. Xstatic void AsciiSetTabs (w, offset, tab_count, tabs)
  411. X  Widget w;            /* for context */
  412. X  Position offset;        /* from left, for margin */
  413. X  int tab_count;        /* count of entries in tabs */
  414. X  Position *tabs;        /* list of character positions */
  415. X{
  416. X    AsciiSinkData *data = (AsciiSinkData*)((TextWidget)w)->text.sink->data;
  417. X    int i;
  418. X
  419. X    if (tab_count > data->tab_count) {
  420. X    data->tabs = (Position*)XtRealloc(data->tabs,
  421. X                    (unsigned)tab_count * sizeof(Position*));
  422. X    }
  423. X    
  424. X    for (i=0; i < tab_count; i++) {
  425. X    data->tabs[i] = offset + tabs[i] * data->em;
  426. X    }
  427. X    data->tab_count = tab_count;
  428. X}
  429. X
  430. X/***** Public routines *****/
  431. X
  432. XXtTextSink XtAsciiSinkCreate (parent, args, num_args)
  433. X    Widget    parent;
  434. X    ArgList     args;
  435. X    Cardinal     num_args;
  436. X{
  437. X    XtTextSink sink;
  438. X    AsciiSinkData *data;
  439. X    unsigned long valuemask = (GCFont | GCGraphicsExposures |
  440. X                   GCForeground | GCBackground | GCFunction);
  441. X    XGCValues values;
  442. X    long wid;
  443. X    XFontStruct *font;
  444. X
  445. X    if (!buf) buf = XtMalloc(bufferSize);
  446. X
  447. X    sink = XtNew(XtTextSinkRec);
  448. X    sink->Display = AsciiDisplayText;
  449. X    sink->InsertCursor = AsciiInsertCursor;
  450. X    sink->ClearToBackground = AsciiClearToBackground;
  451. X    sink->FindPosition = AsciiFindPosition;
  452. X    sink->FindDistance = AsciiFindDistance;
  453. X    sink->Resolve = AsciiResolveToPosition;
  454. X    sink->MaxLines = AsciiMaxLinesForHeight;
  455. X    sink->MaxHeight = AsciiMaxHeightForLines;
  456. X    sink->SetTabs = AsciiSetTabs;
  457. X    data = XtNew(AsciiSinkData);
  458. X    sink->data = (caddr_t)data;
  459. X
  460. X    XtGetSubresources (parent, (caddr_t)data, XtNtextSink, XtCTextSink, 
  461. X               SinkResources, XtNumber(SinkResources),
  462. X               args, num_args);
  463. X
  464. X    font = data->font;
  465. X    values.function = GXcopy;
  466. X    values.font = font->fid;
  467. X    values.graphics_exposures = (Bool) FALSE;
  468. X    values.foreground = data->foreground;
  469. X    values.background = parent->core.background_pixel;
  470. X    data->normgc = XtGetGC(parent, valuemask, &values);
  471. X    values.foreground = parent->core.background_pixel;
  472. X    values.background = data->foreground;
  473. X    data->invgc = XtGetGC(parent, valuemask, &values);
  474. X    values.function = GXxor;
  475. X    values.foreground = data->foreground ^ parent->core.background_pixel;
  476. X    values.background = 0;
  477. X    data->xorgc = XtGetGC(parent, valuemask, &values);
  478. X
  479. X
  480. X    wid = -1;
  481. X    if ((!XGetFontProperty(font, XA_QUAD_WIDTH, &wid)) || wid <= 0) {
  482. X    if (font->per_char && font->min_char_or_byte2 <= '0' &&
  483. X                      font->max_char_or_byte2 >= '0')
  484. X        wid = font->per_char['0' - font->min_char_or_byte2].width;
  485. X    else
  486. X        wid = font->max_bounds.width;
  487. X    }
  488. X    if (wid <= 0)
  489. X    data->em = 1;
  490. X    else
  491. X    data->em = wid;
  492. X
  493. X    data->font = font;
  494. X#ifdef SERVERNOTBROKEN
  495. X    data->insertCursorOn = CreateInsertCursor(XtScreen(parent));
  496. X#else
  497. X    /*
  498. X     * This is the work around for not being able to do CopyPlane with XOR.
  499. X     * However, there is another bug which doesn't let us use the new
  500. X     * CreatePixmapFromBitmapData routine to build the pixmap that we will
  501. X     * use CopyArea with.
  502. X     */
  503. X#ifdef SERVERNOTBROKEN2
  504. X    data->insertCursorOn =
  505. X      XCreatePixmapFromBitmapData (XtDisplay (parent), 
  506. X                   RootWindowOfScreen(XtScreen(parent)),
  507. X                   insertCursor_bits, insertCursor_width,
  508. X                   insertCursor_height, data->foreground,
  509. X                   parent->core.background_pixel,
  510. X                   parent->core.depth);
  511. X#else /* SERVER is BROKEN the second way */
  512. X    {
  513. X    Screen *screen = XtScreen (parent);
  514. X    Display *dpy = XtDisplay (parent);
  515. X    Window root = RootWindowOfScreen(screen);
  516. X    Pixmap bitmap = XCreateBitmapFromData (dpy, root, insertCursor_bits,
  517. X                           insertCursor_width,
  518. X                           insertCursor_height);
  519. X    Pixmap pixmap = XCreatePixmap (dpy, root, insertCursor_width,
  520. X                       insertCursor_height,
  521. X                       DefaultDepthOfScreen (screen));
  522. X    XGCValues gcv;
  523. X    GC gc;
  524. X
  525. X    gcv.function = GXcopy;
  526. X    gcv.foreground = data->foreground ^ parent->core.background_pixel;
  527. X    gcv.background = 0;
  528. X    gcv.graphics_exposures = False;
  529. X    gc = XtGetGC (parent, (GCFunction | GCForeground | GCBackground |
  530. X                   GCGraphicsExposures), &gcv);
  531. X    XCopyPlane (dpy, bitmap, pixmap, gc, 0, 0, insertCursor_width,
  532. X            insertCursor_height, 0, 0, 1);
  533. X    XtDestroyGC (gc);
  534. X    data->insertCursorOn = pixmap;
  535. X    }
  536. X#endif /* SERVERNOTBROKEN2 */
  537. X#endif /* SERVERNOTBROKEN */
  538. X    data->laststate = XtisOff;
  539. X    data->tab_count = 0;
  540. X    data->tabs = NULL;
  541. X    return sink;
  542. X}
  543. X
  544. Xvoid XtAsciiSinkDestroy (sink)
  545. X    XtTextSink sink;
  546. X{
  547. X    AsciiSinkData *data;
  548. X
  549. X    data = (AsciiSinkData *) sink->data;
  550. X    XtFree((char *) data->tabs);
  551. X    XtFree((char *) data);
  552. X    XtFree((char *) sink);
  553. X}
  554. END_OF_FILE
  555. if test 15302 -ne `wc -c <'xconf/AsciiSink.c'`; then
  556.     echo shar: \"'xconf/AsciiSink.c'\" unpacked with wrong size!
  557. fi
  558. # end of 'xconf/AsciiSink.c'
  559. fi
  560. if test -f 'xconf/GCManager.c' -a "${1}" != "-c" ; then 
  561.   echo shar: Will not clobber existing file \"'xconf/GCManager.c'\"
  562. else
  563. echo shar: Extracting \"'xconf/GCManager.c'\" \(6869 characters\)
  564. sed "s/^X//" >'xconf/GCManager.c' <<'END_OF_FILE'
  565. X#ifndef lint
  566. Xstatic char Xrcsid[] = "$XConsortium: GCManager.c,v 1.31 88/09/06 16:27:54 jim Exp $";
  567. X/* $oHeader: GCManager.c,v 1.4 88/08/19 14:19:51 asente Exp $ */
  568. X#endif lint
  569. X
  570. X/***********************************************************
  571. XCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
  572. Xand the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  573. X
  574. X                        All Rights Reserved
  575. X
  576. XPermission to use, copy, modify, and distribute this software and its 
  577. Xdocumentation for any purpose and without fee is hereby granted, 
  578. Xprovided that the above copyright notice appear in all copies and that
  579. Xboth that copyright notice and this permission notice appear in 
  580. Xsupporting documentation, and that the names of Digital or MIT not be
  581. Xused in advertising or publicity pertaining to distribution of the
  582. Xsoftware without specific, written prior permission.  
  583. X
  584. XDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  585. XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  586. XDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  587. XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  588. XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  589. XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  590. XSOFTWARE.
  591. X
  592. X******************************************************************/
  593. X
  594. X#include <stdio.h>
  595. X#include "IntrinsicI.h"
  596. X
  597. X
  598. Xtypedef struct _GCrec {
  599. X    Display    *dpy;        /* Display for GC */
  600. X    Screen    *screen;    /* Screen for GC */
  601. X    Cardinal    depth;        /* Depth for GC */
  602. X    Cardinal    ref_count;      /* # of shareholders */
  603. X    GC         gc;        /* The GC itself. */
  604. X    XtValueMask    valueMask;    /* What fields are being used right now. */
  605. X    XGCValues     values;        /* What values those fields have. */
  606. X    struct _GCrec *next;    /* Next GC for this widgetkind. */
  607. X} GCrec, *GCptr;
  608. X
  609. Xstatic Drawable GCparents[256]; /* static initialized to zero, K&R ss 4.9 */
  610. Xstatic GCrec    *GClist = NULL;
  611. X
  612. Xstatic Bool Matches(ptr, valueMask, v)
  613. X         GCptr        ptr;
  614. X    register XtValueMask    valueMask;
  615. X    register XGCValues      *v;
  616. X{
  617. X    register XGCValues      *p = &(ptr->values);
  618. X
  619. X#define CheckGCField(MaskBit,fieldName) \
  620. X    if ((valueMask & MaskBit) && (p->fieldName != v->fieldName)) return False
  621. X
  622. X    /* Check most common fields specified for GCs first */
  623. X    CheckGCField( GCForeground,        foreground);
  624. X    CheckGCField( GCBackground,        background);
  625. X    CheckGCField( GCFont,        font);
  626. X    CheckGCField( GCFillStyle,        fill_style);
  627. X    CheckGCField( GCLineWidth,        line_width);
  628. X    /* Are we done yet ? */
  629. X    if (! (valueMask
  630. X        & ~(GCForeground | GCBackground | GCFont | GCFillStyle | GCLineWidth)))
  631. X    return True;
  632. X
  633. X    /* Check next most common */
  634. X    CheckGCField( GCFunction,        function);
  635. X    CheckGCField( GCGraphicsExposures,    graphics_exposures);
  636. X    CheckGCField( GCTile,        tile);
  637. X    CheckGCField( GCSubwindowMode,    subwindow_mode);
  638. X    CheckGCField( GCPlaneMask,        plane_mask);
  639. X    /* Now are we done ? */
  640. X    if (! (valueMask
  641. X         & ~(GCForeground | GCBackground | GCFont | GCFillStyle | GCLineWidth
  642. X        | GCFunction | GCGraphicsExposures | GCTile | GCSubwindowMode
  643. X        | GCPlaneMask))) return True;
  644. X
  645. X    CheckGCField( GCLineStyle,        line_style);
  646. X    CheckGCField( GCCapStyle,        cap_style);
  647. X    CheckGCField( GCJoinStyle,        join_style);
  648. X    CheckGCField( GCFillRule,        fill_rule);
  649. X    CheckGCField( GCArcMode,        arc_mode);
  650. X    CheckGCField( GCStipple,        stipple);
  651. X    CheckGCField( GCTileStipXOrigin,    ts_x_origin);
  652. X    CheckGCField( GCTileStipYOrigin,    ts_y_origin);
  653. X    CheckGCField( GCClipXOrigin,    clip_x_origin);
  654. X    CheckGCField( GCClipYOrigin,    clip_y_origin);
  655. X    CheckGCField( GCClipMask,        clip_mask);
  656. X    CheckGCField( GCDashOffset,        dash_offset);
  657. X    CheckGCField( GCDashList,        dashes);
  658. X#undef CheckGCField
  659. X    return True;
  660. X} /* Matches */
  661. X
  662. X
  663. X/* 
  664. X * Return a read-only GC with the given values.  
  665. X */
  666. X
  667. XGC XtGetGC(widget, valueMask, values)
  668. X         Widget    widget;
  669. X    register XtGCMask    valueMask;
  670. X         XGCValues    *values;
  671. X{
  672. X         GCptr      prev;
  673. X    register GCptr      cur;
  674. X    register Cardinal   depth   = widget->core.depth;
  675. X    register Screen     *screen = XtScreen(widget);
  676. X         Drawable   drawable;
  677. X    register Display     *dpy = XtDisplay(widget);
  678. X
  679. X    /* Search for existing GC that matches exactly */
  680. X    for (cur = GClist, prev = NULL; cur != NULL; prev = cur, cur = cur->next) {
  681. X    if (cur->valueMask == valueMask && cur->depth == depth
  682. X        && cur->screen == screen && cur->dpy == dpy
  683. X        && Matches(cur, valueMask, values)) {
  684. X            cur->ref_count++;
  685. X        /* Move this GC to front of list if not already there */
  686. X        if (prev != NULL) {
  687. X        prev->next = cur->next;
  688. X        cur->next = GClist;
  689. X        GClist = cur;
  690. X        }
  691. X        return cur->gc;
  692. X    }
  693. X    }
  694. X
  695. X    /* No matches, have to create a new one */
  696. X    cur        = XtNew(GCrec);
  697. X    cur->next   = GClist;
  698. X    GClist      = cur;
  699. X
  700. X    cur->dpy        = XtDisplay(widget);
  701. X    cur->screen     = screen;
  702. X    cur->depth      = depth;
  703. X    cur->ref_count  = 1;
  704. X    cur->valueMask  = valueMask;
  705. X    cur->values     = *values;
  706. X    if (XtWindow(widget) == NULL) {
  707. X    /* Have to create a bogus pixmap for the GC.  Stupid X protocol. */
  708. X#ifdef JON
  709. X    if (depth == DefaultDepthOfScreen(screen))
  710. X                drawable = RootWindowOfScreen(screen);
  711. X            else
  712. X                drawable = XCreatePixmap(cur->dpy, screen->root, 1, 1,
  713. Xdepth);
  714. X#else
  715. X    if (GCparents[depth] != 0) {
  716. X        drawable = GCparents[depth];
  717. X        } else {
  718. X        if (depth == DefaultDepthOfScreen(screen))
  719. X        drawable = RootWindowOfScreen(screen);
  720. X        else 
  721. X        drawable = XCreatePixmap(cur->dpy, screen->root, 1, 1, depth);
  722. X           GCparents[depth] = drawable;
  723. X        }
  724. X#endif
  725. X    } else {
  726. X    drawable = XtWindow(widget);
  727. X    }
  728. X    cur->gc = XCreateGC(cur->dpy, drawable, valueMask, values);
  729. X    return cur->gc;
  730. X} /* XtGetGC */
  731. X
  732. Xvoid  XtReleaseGC(widget, gc)
  733. X    Widget   widget;
  734. X    GC      gc;
  735. X{
  736. X    register GCptr cur, prev;
  737. X    
  738. X    for (cur = GClist, prev = NULL; cur != NULL; prev = cur, cur = cur->next) {
  739. X    if (cur->gc == gc && cur->dpy == XtDisplay(widget)) {
  740. X        if (--(cur->ref_count) == 0) {
  741. X        if (prev != NULL) prev->next = cur->next;
  742. X        else GClist = cur->next;
  743. X        XFreeGC(cur->dpy, gc);
  744. X        XtFree((char *) cur);
  745. X        break;
  746. X        }
  747. X    }
  748. X    }
  749. X} /* XtReleaseGC */
  750. X
  751. X/*  The following interface is broken and supplied only for backwards
  752. X *  compatibility.  It will work properly in all cases only if there
  753. X *  is exactly 1 Display created by the application.
  754. X */
  755. X
  756. Xvoid XtDestroyGC(gc)
  757. X    GC      gc;
  758. X{
  759. X    register GCptr cur, prev;
  760. X    
  761. X    for (cur = GClist, prev = NULL; cur != NULL; prev = cur, cur = cur->next) {
  762. X    if (cur->gc == gc) {
  763. X        if (--(cur->ref_count) == 0) {
  764. X        if (prev != NULL) prev->next = cur->next;
  765. X        else GClist = cur->next;
  766. X        XFreeGC(cur->dpy, gc);
  767. X        XtFree((char *) cur);
  768. X        break;
  769. X        }
  770. X    }
  771. X    }
  772. X} /* XtDestroyGC */
  773. END_OF_FILE
  774. if test 6869 -ne `wc -c <'xconf/GCManager.c'`; then
  775.     echo shar: \"'xconf/GCManager.c'\" unpacked with wrong size!
  776. fi
  777. # end of 'xconf/GCManager.c'
  778. fi
  779. if test -f 'xconf/Makefile' -a "${1}" != "-c" ; then 
  780.   echo shar: Will not clobber existing file \"'xconf/Makefile'\"
  781. else
  782. echo shar: Extracting \"'xconf/Makefile'\" \(437 characters\)
  783. sed "s/^X//" >'xconf/Makefile' <<'END_OF_FILE'
  784. XH = AsciiText.h Text.h TextSrcP.h AsciiTextP.h TextP.h xconf.h
  785. XS = xconf.c ru.c Text.c AsciiText.c
  786. XO = xconf.o ru.o Text.o AsciiText.o AsciiSink.o  \
  787. X    StringSrc.o DiskSrc.o \
  788. X    Dialog.o  \
  789. X    GCManager.o Converters.o 
  790. XL = -lXaw -lXt -lXmu -lX11 -lrpcsvc
  791. XCFLAGS = -I/usr/src/X11R3/lib/Xt -DJON -DDEBUG -DJOKE -DEXPTL -DSUNRPC -g
  792. X
  793. Xall:    xconf
  794. X
  795. Xxconf:    $O $H
  796. X    cc $(CFLAGS) -o xconf $O $L
  797. X
  798. Xlint:    $S
  799. X    lint -I/usr/ucl/include -DJON -DDEBUG xconf.c
  800. END_OF_FILE
  801. if test 437 -ne `wc -c <'xconf/Makefile'`; then
  802.     echo shar: \"'xconf/Makefile'\" unpacked with wrong size!
  803. fi
  804. # end of 'xconf/Makefile'
  805. fi
  806. if test -f 'xconf/Text.c.ab' -a "${1}" != "-c" ; then 
  807.   echo shar: Will not clobber existing file \"'xconf/Text.c.ab'\"
  808. else
  809. echo shar: Extracting \"'xconf/Text.c.ab'\" \(29444 characters\)
  810. sed "s/^X//" >'xconf/Text.c.ab' <<'END_OF_FILE'
  811. X    if (visible) {
  812. X    XtTextLineTableEntry *thisLine, *nextLine = ctx->text.lt.info + line1;
  813. X    Boolean resizeable = ctx->text.options & resizeWidth;
  814. X    Boolean wordwrap = ctx->text.options & wordBreak;
  815. X    int (*FindPosition)() = ctx->text.sink->FindPosition;
  816. X    int (*ClearToBackground)() = ctx->text.sink->ClearToBackground;
  817. X    register XtTextPosition lastPos = ctx->text.lastPos;
  818. X    for (i = line1; i < ctx->text.lt.lines; i++) {/* fixup line table */
  819. X        thisLine = nextLine++;
  820. X        width = resizeable ? BIGNUM : ctx->core.width - x;
  821. X        if (startPos <= lastPos) {
  822. X        (*FindPosition)(ctx, startPos, x, width, wordwrap,
  823. X                &endPos, &realW, &realH);
  824. X        if (!wordwrap && endPos < lastPos) {
  825. X            /* if not wordBreak, skip remainder of this line */
  826. X            endPos = (*Scan)(ctx->text.source, startPos,
  827. X                     XtstEOL, XtsdRight, 1, TRUE);
  828. X            if (endPos == startPos)
  829. X            endPos = lastPos + 1;
  830. X        }
  831. X        thisLine->endX = x + realW;
  832. X        nextLine->y = thisLine->y + realH;
  833. X        if ((endPos > pos1) && (endPos == nextLine->position))
  834. X            break;    /* %%% why not update remaining y's? */
  835. X        startPos = endPos;
  836. X        }
  837. X        if (startPos > lastPos) {
  838. X        if (nextLine->position <= lastPos) {
  839. X            (*ClearToBackground) (ctx, nextLine->x, nextLine->y,
  840. X                      nextLine->endX,
  841. X                      (nextLine+1)->y - nextLine->y);
  842. X        }
  843. X        nextLine->endX = ctx->text.leftmargin;
  844. X        }
  845. X        nextLine->position = startPos;
  846. X        x = nextLine->x;
  847. X    }
  848. X    if (delta >= lastPos)
  849. X        endPos = lastPos;
  850. X    if (endPos < pos2)    /* might scroll if word wrapped off bottom */
  851. X        endPos = pos2;
  852. X    if (endPos > lastPos && delta > 0)
  853. X        endPos = lastPos;    /* optimize insert at end; don't clear below */
  854. X    if (pos2 >= ctx->text.lt.top || delta >= lastPos)
  855. X        _XtTextNeedsUpdating(ctx, updateFrom, endPos);
  856. X    }
  857. X    SetScrollBar(ctx);
  858. X    return error;
  859. X}
  860. X
  861. X
  862. X/*
  863. X * This routine will display text between two arbitrary source positions.
  864. X * In the event that this span contains highlighted text for the selection, 
  865. X * only that portion will be displayed highlighted.
  866. X */
  867. Xstatic void DisplayText(w, pos1, pos2)
  868. X  Widget w;
  869. X  XtTextPosition pos1, pos2;
  870. X  /* it is illegal to call this routine unless there is a valid line table! */
  871. X{
  872. X    TextWidget ctx = (TextWidget)w;
  873. X    Position x, y;
  874. X    int height;
  875. X    int line, i, visible;
  876. X    XtTextPosition startPos, endPos;
  877. X    int lastPos = ctx->text.lastPos;
  878. X    Boolean clear_eol;
  879. X    Boolean clear_eos = True;
  880. X
  881. X    if (pos1 < ctx->text.lt.top)
  882. X    pos1 = ctx->text.lt.top;
  883. X    if (pos2 > ctx->text.lastPos)
  884. X    pos2 = ctx->text.lastPos;
  885. X    else if (pos2 == ctx->text.lastPos)
  886. X    clear_eos = False;
  887. X    if (pos1 >= pos2) return;
  888. X    visible = LineAndXYForPosition(ctx, pos1, &line, &x, &y);
  889. X    if (!visible)
  890. X    return;
  891. X    startPos = pos1;
  892. X    for (i = line; i < ctx->text.lt.lines; i++) {
  893. X    endPos = ctx->text.lt.info[i + 1].position;
  894. X    if (endPos > pos2) {
  895. X        if (endPos >= lastPos)
  896. X        clear_eol = True;
  897. X        else
  898. X        clear_eol = False;
  899. X        endPos = pos2;
  900. X    }
  901. X    else clear_eol = True;
  902. X    height = ctx->text.lt.info[i + 1].y - ctx->text.lt.info[i].y;
  903. X    if (endPos > startPos) {
  904. X        if (x == ctx->text.leftmargin)
  905. X                (*ctx->text.sink->ClearToBackground)
  906. X            (w, 0, y, ctx->text.leftmargin, height);
  907. X        if (startPos >= ctx->text.s.right || endPos <= ctx->text.s.left) {
  908. X        (*ctx->text.sink->Display) (w, x, y, startPos, endPos, FALSE);
  909. X        } else if (startPos >= ctx->text.s.left && endPos <= ctx->text.s.right) {
  910. X        (*ctx->text.sink->Display) (w, x, y, startPos, endPos, TRUE);
  911. X        } else {
  912. X        DisplayText(w, startPos, ctx->text.s.left);
  913. X        DisplayText(w, max(startPos, ctx->text.s.left), 
  914. X                min(endPos, ctx->text.s.right));
  915. X        DisplayText(w, ctx->text.s.right, endPos);
  916. X        }
  917. X    }
  918. X    startPos = endPos;
  919. X    if (clear_eol)
  920. X        (*ctx->text.sink->ClearToBackground)(ctx,
  921. X        ctx->text.lt.info[i].endX, y, (int)ctx->core.width, height);
  922. X    x = ctx->text.leftmargin;
  923. X    y = ctx->text.lt.info[i + 1].y;
  924. X    if ((endPos == pos2) && !clear_eos)
  925. X        break;
  926. X    }
  927. X}
  928. X
  929. X/*
  930. X * This routine implements multi-click selection in a hardwired manner.
  931. X * It supports multi-click entity cycling (char, word, line, file) and mouse
  932. X * motion adjustment of the selected entitie (i.e. select a word then, with
  933. X * button still down, adjust wich word you really meant by moving the mouse).
  934. X * [NOTE: This routine is to be replaced by a set of procedures that
  935. X * will allows clients to implements a wide class of draw through and
  936. X * multi-click selection user interfaces.]
  937. X*/
  938. Xstatic void DoSelection (ctx, position, time, motion)
  939. X  TextWidget ctx;
  940. X  XtTextPosition position;
  941. X  Time time;
  942. X  Boolean motion;
  943. X{
  944. X    int     delta;
  945. X    XtTextPosition newLeft, newRight;
  946. X    XtTextSelectType newType;
  947. X    XtTextSelectType *sarray;
  948. X
  949. X    delta = (time < ctx->text.lasttime) ?
  950. X    ctx->text.lasttime - time : time - ctx->text.lasttime;
  951. X    if (motion)
  952. X    newType = ctx->text.s.type;
  953. X    else {
  954. X    if ((delta < 500) && ((position >= ctx->text.s.left)
  955. X            && (position <= ctx->text.s.right))) { /* multi-click event */
  956. X        for (sarray = ctx->text.sarray;
  957. X        *sarray != XtselectNull && *sarray != ctx->text.s.type;
  958. X        sarray++) ;
  959. X        if (*sarray != XtselectNull) sarray++;
  960. X        if (*sarray == XtselectNull) sarray = ctx->text.sarray;
  961. X        newType = *sarray;
  962. X    } else {            /* single-click event */
  963. X        newType = *(ctx->text.sarray);
  964. X    }
  965. X        ctx->text.lasttime = time;
  966. X    }
  967. X    switch (newType) {
  968. X    case XtselectPosition: 
  969. X            newLeft = newRight = position;
  970. X        break;
  971. X    case XtselectChar: 
  972. X            newLeft = position;
  973. X            newRight = (*ctx->text.source->Scan)(
  974. X                    ctx->text.source, position, position, XtsdRight, 1, FALSE);
  975. X        break;
  976. X    case XtselectWord: 
  977. X        newLeft = (*ctx->text.source->Scan)(
  978. X            ctx->text.source, position, XtstWhiteSpace, XtsdLeft, 1, FALSE);
  979. X        newRight = (*ctx->text.source->Scan)(
  980. X            ctx->text.source, position, XtstWhiteSpace, XtsdRight, 1, FALSE);
  981. X        break;
  982. X    case XtselectLine: 
  983. X    case XtselectParagraph:  /* need "para" scan mode to implement pargraph */
  984. X         newLeft = (*ctx->text.source->Scan)(
  985. X            ctx->text.source, position, XtstEOL, XtsdLeft, 1, FALSE);
  986. X        newRight = (*ctx->text.source->Scan)(
  987. X            ctx->text.source, position, XtstEOL, XtsdRight, 1, FALSE);
  988. X        break;
  989. X    case XtselectAll: 
  990. X        newLeft = (*ctx->text.source->Scan)(
  991. X            ctx->text.source, position, XtstAll, XtsdLeft, 1, FALSE);
  992. X        newRight = (*ctx->text.source->Scan)(
  993. X            ctx->text.source, position, XtstAll, XtsdRight, 1, FALSE);
  994. X        break;
  995. X    }
  996. X    if ((newLeft != ctx->text.s.left) || (newRight != ctx->text.s.right)
  997. X        || (newType != ctx->text.s.type)) {
  998. X    _XtTextSetNewSelection(ctx, newLeft, newRight, NULL, ZERO);
  999. X    ctx->text.s.type = newType;
  1000. X    if (position - ctx->text.s.left < ctx->text.s.right - position)
  1001. X        ctx->text.insertPos = newLeft;
  1002. X    else 
  1003. X        ctx->text.insertPos = newRight;
  1004. X    }
  1005. X    if (!motion) { /* setup so we can freely mix select extend calls*/
  1006. X    ctx->text.origSel.type = ctx->text.s.type;
  1007. X    ctx->text.origSel.left = ctx->text.s.left;
  1008. X    ctx->text.origSel.right = ctx->text.s.right;
  1009. X    if (position >= ctx->text.s.left + ((ctx->text.s.right - ctx->text.s.left) / 2))
  1010. X        ctx->text.extendDir = XtsdRight;
  1011. X    else
  1012. X        ctx->text.extendDir = XtsdLeft;
  1013. X    }
  1014. X}
  1015. X
  1016. X/*
  1017. X * This routine implements extension of the currently selected text in
  1018. X * the "current" mode (i.e. char word, line, etc.). It worries about
  1019. X * extending from either end of the selection and handles the case when you
  1020. X * cross through the "center" of the current selection (e.g. switch which
  1021. X * end you are extending!).
  1022. X * [NOTE: This routine will be replaced by a set of procedures that
  1023. X * will allows clients to implements a wide class of draw through and
  1024. X * multi-click selection user interfaces.]
  1025. X*/
  1026. Xstatic void ExtendSelection (ctx, position, motion)
  1027. X  TextWidget ctx;
  1028. X  XtTextPosition position;
  1029. X  Boolean motion;
  1030. X{
  1031. X    XtTextPosition newLeft, newRight;
  1032. X    
  1033. X
  1034. X    if (!motion) {        /* setup for extending selection */
  1035. X    ctx->text.origSel.type = ctx->text.s.type;
  1036. X    ctx->text.origSel.left = ctx->text.s.left;
  1037. X    ctx->text.origSel.right = ctx->text.s.right;
  1038. X    if (position >= ctx->text.s.left + ((ctx->text.s.right - ctx->text.s.left) / 2))
  1039. X        ctx->text.extendDir = XtsdRight;
  1040. X    else
  1041. X        ctx->text.extendDir = XtsdLeft;
  1042. X    }
  1043. X    else /* check for change in extend direction */
  1044. X    if ((ctx->text.extendDir == XtsdRight && position < ctx->text.origSel.left) ||
  1045. X        (ctx->text.extendDir == XtsdLeft && position > ctx->text.origSel.right)) {
  1046. X        ctx->text.extendDir = (ctx->text.extendDir == XtsdRight)? XtsdLeft : XtsdRight;
  1047. X        _XtTextSetNewSelection(ctx, ctx->text.origSel.left, ctx->text.origSel.right, NULL, ZERO);
  1048. X    }
  1049. X    newLeft = ctx->text.s.left;
  1050. X    newRight = ctx->text.s.right;
  1051. X    switch (ctx->text.s.type) {
  1052. X    case XtselectPosition: 
  1053. X        if (ctx->text.extendDir == XtsdRight)
  1054. X        newRight = position;
  1055. X        else
  1056. X        newLeft = position;
  1057. X        break;
  1058. X    case XtselectWord: 
  1059. X        if (ctx->text.extendDir == XtsdRight)
  1060. X        newRight = position = (*ctx->text.source->Scan)(
  1061. X            ctx->text.source, position, XtstWhiteSpace, XtsdRight, 1, FALSE);
  1062. X        else
  1063. X        newLeft = position = (*ctx->text.source->Scan)(
  1064. X            ctx->text.source, position, XtstWhiteSpace, XtsdLeft, 1, FALSE);
  1065. X        break;
  1066. X        case XtselectLine:
  1067. X    case XtselectParagraph: /* need "para" scan mode to implement pargraph */
  1068. X        if (ctx->text.extendDir == XtsdRight)
  1069. X        newRight = position = (*ctx->text.source->Scan)(
  1070. X            ctx->text.source, position, XtstEOL, XtsdRight, 1, TRUE);
  1071. X        else
  1072. X        newLeft = position = (*ctx->text.source->Scan)(
  1073. X            ctx->text.source, position, XtstEOL, XtsdLeft, 1, FALSE);
  1074. X        break;
  1075. X    case XtselectAll: 
  1076. X        position = ctx->text.insertPos;
  1077. X        break;
  1078. X    }
  1079. X    _XtTextSetNewSelection(ctx, newLeft, newRight, NULL, ZERO);
  1080. X    ctx->text.insertPos = position;
  1081. X}
  1082. X
  1083. X
  1084. X/*
  1085. X * Clear the window to background color.
  1086. X */
  1087. Xstatic ClearWindow (w)
  1088. X  Widget w;
  1089. X{
  1090. X    if (XtIsRealized(w))
  1091. X    (*((TextWidget)w)->text.sink->
  1092. X     ClearToBackground) (w, 0, 0, (int)w->core.width, (int)w->core.height);
  1093. X}
  1094. X
  1095. X
  1096. X/*
  1097. X * Internal redisplay entire window.
  1098. X * Legal to call only if widget is realized.
  1099. X */
  1100. XDisplayTextWindow (w)
  1101. X  Widget w;
  1102. X{
  1103. X    TextWidget ctx = (TextWidget) w;
  1104. X    ClearWindow(w);
  1105. X    BuildLineTable(ctx, ctx->text.lt.top);
  1106. X    _XtTextNeedsUpdating(ctx, zeroPosition, ctx->text.lastPos);
  1107. X    SetScrollBar(ctx);
  1108. X}
  1109. X
  1110. X/*
  1111. X * This routine checks to see if the window should be resized (grown or
  1112. X * shrunk) or scrolled when text to be painted overflows to the right or
  1113. X * the bottom of the window. It is used by the keyboard input routine.
  1114. X*/
  1115. Xstatic CheckResizeOrOverflow(ctx)
  1116. X  TextWidget ctx;
  1117. X{
  1118. X    XtTextPosition posToCheck;
  1119. X    int     visible, line, width;
  1120. X    XtWidgetGeometry rbox;
  1121. X    XtGeometryResult reply;
  1122. X    register int options = ctx->text.options;
  1123. X
  1124. X    if (options & resizeWidth) {
  1125. X    XtTextLineTableEntry *lt;
  1126. X    width = 0;
  1127. X    for (line=0, lt=ctx->text.lt.info; line<ctx->text.lt.lines; line++) {
  1128. X        if (width < lt->endX)
  1129. X        width = lt->endX;
  1130. X        lt++;
  1131. X    }
  1132. X    if (width > ctx->core.width) {
  1133. X        rbox.request_mode = CWWidth;
  1134. X        rbox.width = width;
  1135. X        reply = XtMakeGeometryRequest((Widget)ctx, &rbox, &rbox);
  1136. X        if (reply == XtGeometryAlmost)
  1137. X            reply = XtMakeGeometryRequest((Widget)ctx, &rbox, NULL);
  1138. X    }
  1139. X    }
  1140. X    if ((options & resizeHeight) || (options & scrollOnOverflow)) {
  1141. X    if (options & scrollOnOverflow)
  1142. X        posToCheck = ctx->text.insertPos;
  1143. X    else
  1144. X        posToCheck = ctx->text.lastPos;
  1145. X    visible = IsPositionVisible(ctx, posToCheck);
  1146. X    if (visible)
  1147. X        line = LineForPosition(ctx, posToCheck);
  1148. X    else
  1149. X        line = ctx->text.lt.lines;
  1150. X    if ((options & scrollOnOverflow) && (line + 1 > ctx->text.lt.lines)) {
  1151. X        BuildLineTable(ctx, ctx->text.lt.info[1].position);
  1152. X        XCopyArea(XtDisplay(ctx), XtWindow(ctx), XtWindow(ctx),
  1153. X              ctx->text.gc, (int)ctx->text.leftmargin, 
  1154. X              (int)ctx->text.lt.info[1].y,
  1155. X              (int)ctx->core.width, (int)ctx->core.height,
  1156. X              (int)ctx->text.leftmargin, ctx->text.lt.info[0].y);
  1157. X    }
  1158. X    else
  1159. X        if ((options & resizeHeight) && (line + 1 != ctx->text.lt.lines)) {
  1160. X        int oldHeight = ctx->core.height;
  1161. X        rbox.request_mode = CWHeight;
  1162. X        rbox.height = (*ctx->text.sink->MaxHeight)
  1163. X                (ctx, line + 1) + (2*yMargin)+2;
  1164. X        reply = XtMakeGeometryRequest(ctx, &rbox, &rbox);
  1165. X        if (reply == XtGeometryAlmost)
  1166. X            reply = XtMakeGeometryRequest((Widget)ctx, &rbox, NULL);
  1167. X        if (reply == XtGeometryYes) {
  1168. X            BuildLineTable(ctx, ctx->text.lt.top);
  1169. X            if (!(options & wordBreak) /* if NorthEastGravity */
  1170. X            && rbox.height < oldHeight) {
  1171. X            /* clear cruft from bottom margin */
  1172. X            (*ctx->text.sink->ClearToBackground)
  1173. X                (ctx, ctx->text.leftmargin,
  1174. X                 ctx->text.lt.info[ctx->text.lt.lines].y,
  1175. X                 (int)ctx->core.width, oldHeight - rbox.height);
  1176. X            }
  1177. X        }
  1178. X        }
  1179. X    }
  1180. X}
  1181. X
  1182. Xstatic Atom* _SelectionList(ctx, params, num_params)
  1183. X  TextWidget ctx;
  1184. X  String *params;
  1185. X  Cardinal num_params;
  1186. X{
  1187. X    /* converts (params, num_params) to a list of atoms & caches the
  1188. X     * list in the TextWidget instance.
  1189. X     */
  1190. X
  1191. X    if (num_params > ctx->text.s.array_size) {
  1192. X    ctx->text.s.selections =
  1193. X        (Atom*)XtRealloc(ctx->text.s.selections, num_params*sizeof(Atom));
  1194. X    ctx->text.s.array_size = num_params;
  1195. X    }
  1196. X    XmuInternStrings( XtDisplay((Widget)ctx), params, num_params,
  1197. X              ctx->text.s.selections );
  1198. X    ctx->text.s.atom_count = num_params;
  1199. X    return ctx->text.s.selections;
  1200. X}
  1201. X
  1202. X
  1203. X/*
  1204. X * This routine is used to perform various selection functions. The goal is
  1205. X * to be able to specify all the more popular forms of draw-through and
  1206. X * multi-click selection user interfaces from the outside.
  1207. X */
  1208. Xvoid AlterSelection (ctx, mode, action, params, num_params)
  1209. X    TextWidget     ctx;
  1210. X    XtTextSelectionMode   mode;    /* {XtsmTextSelect, XtsmTextExtend} */
  1211. X    XtTextSelectionAction action; /* {XtactionStart, XtactionAdjust, XtactionEnd} */
  1212. X    String    *params;
  1213. X    Cardinal    *num_params;
  1214. X{
  1215. X    XtTextPosition position;
  1216. X
  1217. X    position = PositionForXY (ctx, (int) ctx->text.ev_x, (int) ctx->text.ev_y);
  1218. X    if (action == XtactionStart) {
  1219. X    switch (mode) {
  1220. X    case XtsmTextSelect: 
  1221. X        DoSelection (ctx, position, ctx->text.time, FALSE);
  1222. X        break;
  1223. X    case XtsmTextExtend: 
  1224. X        ExtendSelection (ctx, position, FALSE);
  1225. X        break;
  1226. X    }
  1227. X    }
  1228. X    else {
  1229. X    switch (mode) {
  1230. X    case XtsmTextSelect: 
  1231. X        DoSelection (ctx, position, ctx->text.time, TRUE);
  1232. X        break;
  1233. X    case XtsmTextExtend: 
  1234. X        ExtendSelection (ctx, position, TRUE);
  1235. X        break;
  1236. X    }
  1237. X    }
  1238. X    if (action == XtactionEnd) {
  1239. X    if (ctx->text.s.left < ctx->text.s.right) {
  1240. X        Cardinal count = *num_params;
  1241. X        if (count == 0) {
  1242. X        static String defaultSelection = "CUT_BUFFER0";
  1243. X        params = &defaultSelection;
  1244. X        count = 1;
  1245. X        }
  1246. X        _XtTextSetNewSelection(
  1247. X           ctx, ctx->text.s.left, ctx->text.s.right,
  1248. X           _SelectionList(ctx, params, count),
  1249. X           count );
  1250. X    }
  1251. X    else XtTextUnsetSelection((Widget)ctx);
  1252. X    }
  1253. X}
  1254. X
  1255. X/*
  1256. X * This routine processes all "expose region" XEvents. In general, its job
  1257. X * is to the best job at minimal re-paint of the text, displayed in the
  1258. X * window, that it can.
  1259. X*/
  1260. Xstatic void ProcessExposeRegion(w, event)
  1261. X  Widget w;
  1262. X  XEvent *event;
  1263. X{
  1264. X    TextWidget ctx = (TextWidget) w;
  1265. X    XtTextPosition pos1, pos2, resultend;
  1266. X    int line;
  1267. X    int x = event->xexpose.x;
  1268. X    int y = event->xexpose.y;
  1269. X    int width = event->xexpose.width;
  1270. X    int height = event->xexpose.height;
  1271. X    XtTextLineTableEntry *info;
  1272. X
  1273. X   _XtTextPrepareToUpdate(ctx);
  1274. X    if (x < ctx->text.leftmargin) /* stomp on caret tracks */
  1275. X        (*ctx->text.sink->ClearToBackground)(ctx, x, y, width, height);
  1276. X   /* figure out starting line that was exposed */
  1277. X    line = LineForPosition(ctx, PositionForXY(ctx, x, y));
  1278. X    while (line < ctx->text.lt.lines && ctx->text.lt.info[line + 1].y < y)
  1279. X    line++;
  1280. X    while (line < ctx->text.lt.lines) {
  1281. X    info = &(ctx->text.lt.info[line]);
  1282. X    if (info->y >= y + height)
  1283. X        break;
  1284. X    (*ctx->text.sink->Resolve)(ctx, 
  1285. X                                info->position, info->x,
  1286. X                    x - info->x, &pos1, &resultend);
  1287. X    (*ctx->text.sink->Resolve)(ctx, 
  1288. X                                info->position, info->x,
  1289. X                    x + width - info->x, &pos2, 
  1290. X                                &resultend);
  1291. X    pos2 = (*ctx->text.source->Scan)(ctx->text.source, pos2, XtstPositions, 
  1292. X                                      XtsdRight, 1, TRUE);
  1293. X    _XtTextNeedsUpdating(ctx, pos1, pos2);
  1294. X    line++;
  1295. X    }
  1296. X    _XtTextExecuteUpdate(ctx);
  1297. X}
  1298. X
  1299. X/*
  1300. X * This routine does all setup required to syncronize batched screen updates
  1301. X*/
  1302. Xint _XtTextPrepareToUpdate(ctx)
  1303. X  TextWidget ctx;
  1304. X{
  1305. X    if (ctx->text.old_insert < 0) {
  1306. X    InsertCursor((Widget)ctx, XtisOff);
  1307. X    ctx->text.numranges = 0;
  1308. X    ctx->text.showposition = FALSE;
  1309. X    ctx->text.old_insert = ctx->text.insertPos;
  1310. X    }
  1311. X}
  1312. X
  1313. X
  1314. X/*
  1315. X * This is a private utility routine used by _XtTextExecuteUpdate. It
  1316. X * processes all the outstanding update requests and merges update
  1317. X * ranges where possible.
  1318. X*/
  1319. Xstatic void FlushUpdate(ctx)
  1320. X  TextWidget ctx;
  1321. X{
  1322. X    int     i, w;
  1323. X    XtTextPosition updateFrom, updateTo;
  1324. X    if (!XtIsRealized((Widget)ctx)) {
  1325. X    ctx->text.numranges = 0;
  1326. X    return;
  1327. X    }
  1328. X    while (ctx->text.numranges > 0) {
  1329. X    updateFrom = ctx->text.updateFrom[0];
  1330. X    w = 0;
  1331. X    for (i=1 ; i<ctx->text.numranges ; i++) {
  1332. X        if (ctx->text.updateFrom[i] < updateFrom) {
  1333. X        updateFrom = ctx->text.updateFrom[i];
  1334. X        w = i;
  1335. X        }
  1336. X    }
  1337. X    updateTo = ctx->text.updateTo[w];
  1338. X    ctx->text.numranges--;
  1339. X    ctx->text.updateFrom[w] = ctx->text.updateFrom[ctx->text.numranges];
  1340. X    ctx->text.updateTo[w] = ctx->text.updateTo[ctx->text.numranges];
  1341. X    for (i=ctx->text.numranges-1 ; i>=0 ; i--) {
  1342. X        while (ctx->text.updateFrom[i] <= updateTo && i < ctx->text.numranges) {
  1343. X        updateTo = ctx->text.updateTo[i];
  1344. X        ctx->text.numranges--;
  1345. X        ctx->text.updateFrom[i] = ctx->text.updateFrom[ctx->text.numranges];
  1346. X        ctx->text.updateTo[i] = ctx->text.updateTo[ctx->text.numranges];
  1347. X        }
  1348. X    }
  1349. X    DisplayText((Widget)ctx, updateFrom, updateTo);
  1350. X    }
  1351. X}
  1352. X
  1353. X
  1354. X/*
  1355. X * This is a private utility routine used by _XtTextExecuteUpdate. This routine
  1356. X * worries about edits causing new data or the insertion point becoming
  1357. X * invisible (off the screen). Currently it always makes it visible by
  1358. X * scrolling. It probably needs generalization to allow more options.
  1359. X*/
  1360. X_XtTextShowPosition(ctx)
  1361. X  TextWidget ctx;
  1362. X{
  1363. X    XtTextPosition top, first, second;
  1364. X    if (!XtIsRealized((Widget)ctx)) return;
  1365. X    if (ctx->text.insertPos < ctx->text.lt.top ||
  1366. X    ctx->text.insertPos >= ctx->text.lt.info[ctx->text.lt.lines].position) {
  1367. X    if (ctx->text.lt.lines > 0 && (ctx->text.insertPos < ctx->text.lt.top 
  1368. X        || ctx->text.lt.info[ctx->text.lt.lines].position <= ctx->text.lastPos)) {
  1369. X        first = ctx->text.lt.top;
  1370. X        second = ctx->text.lt.info[1].position;
  1371. X        if (ctx->text.insertPos < first)
  1372. X        top = (*ctx->text.source->Scan)(
  1373. X            ctx->text.source, ctx->text.insertPos, XtstEOL,
  1374. X            XtsdLeft, 1, FALSE);
  1375. X        else
  1376. X        top = (*ctx->text.source->Scan)(
  1377. X            ctx->text.source, ctx->text.insertPos, XtstEOL,
  1378. X            XtsdLeft, ctx->text.lt.lines, FALSE);
  1379. X        BuildLineTable(ctx, top);
  1380. X        while (ctx->text.insertPos >= ctx->text.lt.info[ctx->text.lt.lines].position) {
  1381. X        if (ctx->text.lt.info[ctx->text.lt.lines].position > ctx->text.lastPos)
  1382. X            break;
  1383. X        BuildLineTable(ctx, ctx->text.lt.info[1].position);
  1384. X        }
  1385. X        if (ctx->text.lt.top == second) {
  1386. X            BuildLineTable(ctx, first);
  1387. X        _XtTextScroll(ctx, 1);
  1388. X        } else if (ctx->text.lt.info[1].position == first) {
  1389. X        BuildLineTable(ctx, first);
  1390. X        _XtTextScroll(ctx, -1);
  1391. X        } else {
  1392. X        ctx->text.numranges = 0;
  1393. X        if (ctx->text.lt.top != first)
  1394. X            DisplayTextWindow((Widget)ctx);
  1395. X        }
  1396. X    }
  1397. X    }
  1398. X}
  1399. X
  1400. X
  1401. X
  1402. X/*
  1403. X * This routine causes all batched screen updates to be performed
  1404. X*/
  1405. X_XtTextExecuteUpdate(ctx)
  1406. X  TextWidget ctx;
  1407. X{
  1408. X    if (ctx->text.update_disabled) return;
  1409. X
  1410. X    if (ctx->text.old_insert >= 0) {
  1411. X    if (ctx->text.old_insert != ctx->text.insertPos
  1412. X        || ctx->text.showposition)
  1413. X        _XtTextShowPosition(ctx);
  1414. X    FlushUpdate(ctx);
  1415. X    InsertCursor((Widget)ctx, XtisOn);
  1416. X    ctx->text.old_insert = -1;
  1417. X    }
  1418. X}
  1419. X
  1420. X
  1421. Xstatic void TextDestroy(w)
  1422. X    Widget w;
  1423. X{
  1424. X    TextWidget ctx = (TextWidget)w;
  1425. X    register struct _dialog *dialog, *next;
  1426. X
  1427. X    for (dialog = ctx->text.dialog; dialog; dialog = next) {
  1428. X    /* no need to destroy the widgets here; they should go automatically */
  1429. X    next = dialog->next;
  1430. X    XtFree( dialog );
  1431. X    }
  1432. X    if (ctx->text.outer)
  1433. X    (void) XtDestroyWidget(ctx->text.outer);
  1434. X    if (ctx->text.sbar)
  1435. X    (void) XtDestroyWidget(ctx->text.sbar);
  1436. X    XtFree((char *)ctx->text.updateFrom);
  1437. X    XtFree((char *)ctx->text.updateTo);
  1438. X}
  1439. X
  1440. X
  1441. X/* by the time we are managed (and get this far),
  1442. X * we had better have both a source and a sink */
  1443. Xstatic void Resize(w)
  1444. X    Widget          w;
  1445. X{
  1446. X    TextWidget ctx = (TextWidget) w;
  1447. X
  1448. X    if (ctx->text.sbar) {
  1449. X    Widget sbar = ctx->text.sbar;
  1450. X    XtResizeWidget( sbar, sbar->core.width, ctx->core.height,
  1451. X                sbar->core.border_width );
  1452. X    }
  1453. X    _XtTextPrepareToUpdate(ctx);
  1454. X    ForceBuildLineTable(ctx);
  1455. X    _XtTextExecuteUpdate(ctx);
  1456. X}
  1457. X
  1458. X
  1459. X/*
  1460. X * This routine allow the application program to Set attributes.
  1461. X */
  1462. X
  1463. X/*ARGSUSED*/
  1464. Xstatic Boolean SetValues(current, request, new)
  1465. XWidget current, request, new;
  1466. X{
  1467. X    TextWidget oldtw = (TextWidget) current;
  1468. X    TextWidget newtw = (TextWidget) new;
  1469. X    Boolean    redisplay = FALSE;
  1470. X
  1471. X    _XtTextPrepareToUpdate(newtw);
  1472. X    
  1473. X    if ((oldtw->text.options & scrollVertical)
  1474. X        != (newtw->text.options & scrollVertical)) {
  1475. X    newtw->text.leftmargin = newtw->text.client_leftmargin;
  1476. X    if (newtw->text.options & scrollVertical)
  1477. X        CreateScrollbar(newtw);
  1478. X    else {
  1479. X        XtDestroyWidget(oldtw->text.sbar);
  1480. X        newtw->text.sbar = NULL;
  1481. X    }
  1482. X    }
  1483. X    else if (oldtw->text.client_leftmargin != newtw->text.client_leftmargin) {
  1484. X    newtw->text.leftmargin = newtw->text.client_leftmargin;
  1485. X    if (newtw->text.options & scrollVertical) {
  1486. X        newtw->text.leftmargin +=
  1487. X            newtw->text.sbar->core.width +
  1488. X            newtw->text.sbar->core.border_width;
  1489. X    }
  1490. X    }
  1491. X
  1492. X    if (oldtw->text.source != newtw->text.source ||
  1493. X    oldtw->text.sink != newtw->text.sink ||
  1494. X    oldtw->text.lt.top != newtw->text.lt.top ||
  1495. X    oldtw->text.leftmargin != newtw->text.leftmargin ||
  1496. X    ((oldtw->text.options & wordBreak)
  1497. X            != (newtw->text.options & wordBreak)))
  1498. X    {
  1499. X    ForceBuildLineTable(newtw);
  1500. X    SetScrollBar(newtw);
  1501. X    redisplay = TRUE;
  1502. X    }
  1503. X
  1504. X    if (oldtw->text.insertPos != newtw->text.insertPos)
  1505. X    newtw->text.showposition = TRUE;
  1506. X
  1507. X    if (XtIsRealized(newtw)
  1508. X    && ((oldtw->text.options & wordBreak)
  1509. X        != (newtw->text.options & wordBreak))) {
  1510. X    XSetWindowAttributes attributes;
  1511. X    Mask valueMask;
  1512. X    valueMask = CWBitGravity;
  1513. X    attributes.bit_gravity =
  1514. X      (newtw->text.options & wordBreak) ? ForgetGravity : NorthWestGravity;
  1515. X    XChangeWindowAttributes(XtDisplay(newtw), XtWindow(newtw),
  1516. X                valueMask, &attributes);
  1517. X    redisplay = TRUE;
  1518. X    }
  1519. X
  1520. X
  1521. X    if (!redisplay)
  1522. X    _XtTextExecuteUpdate(newtw);
  1523. X
  1524. X    return redisplay;
  1525. X}
  1526. X
  1527. X
  1528. X
  1529. Xvoid XtTextDisplay (w)
  1530. X    Widget w;
  1531. X{
  1532. X    TextWidget ctx = (TextWidget) w;
  1533. X
  1534. X    if (!XtIsRealized(w)) return;
  1535. X
  1536. X    _XtTextPrepareToUpdate(ctx);
  1537. X    DisplayTextWindow(w);
  1538. X    _XtTextExecuteUpdate(ctx);
  1539. X}
  1540. X
  1541. X/*******************************************************************
  1542. XThe following routines provide procedural interfaces to Text window state
  1543. Xsetting and getting. They need to be redone so than the args code can use
  1544. Xthem. I suggest we create a complete set that takes the context as an
  1545. Xargument and then have the public version lookup the context and call the
  1546. Xinternal one. The major value of this set is that they have actual application
  1547. Xclients and therefore the functionality provided is required for any future
  1548. Xversion of Text.
  1549. X********************************************************************/
  1550. X
  1551. Xvoid XtTextSetSelectionArray(w, sarray)
  1552. X    Widget w;
  1553. X    XtTextSelectType *sarray;
  1554. X{
  1555. X    ((TextWidget)w)->text.sarray = sarray;
  1556. X}
  1557. X
  1558. X#ifdef JON
  1559. XXtTextPosition XtTextGetLastPos(w)
  1560. X   Widget w;
  1561. X{
  1562. X   TextWidget ctx = (TextWidget) w;;
  1563. X    return GETLASTPOS;
  1564. X}
  1565. X#endif JON
  1566. X
  1567. Xvoid XtTextSetLastPos (w, lastPos)
  1568. X    Widget w;
  1569. X    XtTextPosition lastPos;
  1570. X{
  1571. X    TextWidget  ctx = (TextWidget) w;
  1572. X
  1573. X    _XtTextPrepareToUpdate(ctx);
  1574. X    (*ctx->text.source->SetLastPos)(ctx->text.source, lastPos);
  1575. X    ctx->text.lastPos = GETLASTPOS;
  1576. X    ForceBuildLineTable(ctx);
  1577. X        if (XtIsRealized(w))
  1578. X        DisplayTextWindow(w);
  1579. X    _XtTextExecuteUpdate(ctx);
  1580. X}
  1581. X
  1582. X
  1583. Xvoid XtTextGetSelectionPos(w, left, right)
  1584. X  Widget w;
  1585. X  XtTextPosition *left, *right;
  1586. X{
  1587. X    TextWidget ctx = (TextWidget) w;
  1588. X    *left = ctx->text.s.left;
  1589. X    *right = ctx->text.s.right;
  1590. X}
  1591. X
  1592. X
  1593. Xvoid XtTextSetSource(w, source, startPos)
  1594. X    Widget w;
  1595. X    XtTextSource   source;
  1596. X    XtTextPosition startPos;
  1597. X{
  1598. X    TextWidget ctx = (TextWidget) w;
  1599. X
  1600. X    ctx->text.source = source;
  1601. X    ctx->text.lt.top = startPos;
  1602. X    ctx->text.s.left = ctx->text.s.right = 0;
  1603. X    ctx->text.insertPos = startPos;
  1604. X    ctx->text.lastPos = GETLASTPOS;
  1605. X
  1606. X    ForceBuildLineTable(ctx);
  1607. X        if (XtIsRealized(w)) {
  1608. X        _XtTextPrepareToUpdate(ctx);
  1609. X        DisplayTextWindow(w);
  1610. X        _XtTextExecuteUpdate(ctx);
  1611. X    }
  1612. X}
  1613. X
  1614. X/*
  1615. X * This public routine deletes the text from startPos to endPos in a source and
  1616. X * then inserts, at startPos, the text that was passed. As a side effect it
  1617. X * "invalidates" that portion of the displayed text (if any), so that things
  1618. X * will be repainted properly.
  1619. X */
  1620. Xint XtTextReplace(w, startPos, endPos, text)
  1621. X    Widget        w;
  1622. X    XtTextPosition  startPos, endPos;
  1623. X    XtTextBlock     *text;
  1624. X{
  1625. X    TextWidget ctx = (TextWidget) w;
  1626. X    int result;
  1627. X
  1628. X    _XtTextPrepareToUpdate(ctx);
  1629. X    if (endPos > ctx->text.lastPos) endPos = ctx->text.lastPos;
  1630. X    if (startPos > ctx->text.lastPos) startPos = ctx->text.lastPos;
  1631. X    if ((result = ReplaceText(ctx, startPos, endPos, text)) == EditDone) {
  1632. X    if (ctx->text.insertPos >= endPos) {
  1633. X        int delta = text->length - (endPos - startPos);
  1634. X        XtTextScanDirection sd;
  1635. X        if (delta < 0) {
  1636. X        sd = XtsdLeft;
  1637. X        delta = -delta;
  1638. X        }
  1639. X        else
  1640. X        sd = XtsdRight;
  1641. X
  1642. X        ctx->text.insertPos =
  1643. X        (*ctx->text.source->Scan)(ctx->text.source,
  1644. X                      ctx->text.insertPos,
  1645. X                      XtstPositions, sd,
  1646. X                      delta, TRUE);
  1647. X    }
  1648. X    else if (ctx->text.insertPos > startPos)
  1649. X        ctx->text.insertPos =
  1650. X        (*ctx->text.source->Scan)(ctx->text.source, startPos,
  1651. X                      XtstPositions, XtsdRight,
  1652. X                      text->length, TRUE);
  1653. X    }
  1654. X    CheckResizeOrOverflow(ctx);
  1655. X    _XtTextExecuteUpdate(ctx);
  1656. X
  1657. X    return result;
  1658. X}
  1659. X
  1660. X
  1661. XXtTextPosition XtTextTopPosition(w)
  1662. X    Widget        w;
  1663. X{
  1664. X    TextWidget ctx = (TextWidget) w;
  1665. X
  1666. X     return ctx->text.lt.top;
  1667. X}
  1668. X
  1669. X
  1670. Xvoid XtTextSetInsertionPoint(w, position)
  1671. X    Widget        w;
  1672. X    XtTextPosition position;
  1673. X{
  1674. X    TextWidget ctx = (TextWidget) w;
  1675. X
  1676. X    _XtTextPrepareToUpdate(ctx);
  1677. X    ctx->text.insertPos = (position > ctx->text.lastPos)
  1678. X                   ? ctx->text.lastPos : position;
  1679. X    ctx->text.showposition = TRUE;
  1680. X    _XtTextExecuteUpdate(ctx);
  1681. X}
  1682. X
  1683. X
  1684. XXtTextPosition XtTextGetInsertionPoint(w)
  1685. X    Widget        w;
  1686. X{
  1687. X    TextWidget ctx = (TextWidget) w;
  1688. X
  1689. X    return(ctx->text.insertPos);
  1690. X}
  1691. X
  1692. X
  1693. Xvoid XtTextUnsetSelection(w)
  1694. X    Widget        w;
  1695. X{
  1696. X    register TextWidget ctx = (TextWidget)w;
  1697. X    int i;
  1698. X    void (*nullProc)() = NULL;
  1699. X
  1700. X    ctx->text.s.left = ctx->text.s.right = ctx->text.insertPos;
  1701. X    if (ctx->text.source->SetSelection != nullProc) {
  1702. X    (*ctx->text.source->SetSelection) (ctx->text.source, ctx->text.s.left,
  1703. X                       ctx->text.s.right,
  1704. X                       ctx->text.s.atom_count ? 
  1705. X                       ctx->text.s.selections[0] : NULL);
  1706. X    }
  1707. X
  1708. X    for (i = ctx->text.s.atom_count; i;) {
  1709. X    Atom selection = ctx->text.s.selections[--i];
  1710. X    switch (selection) {
  1711. X      case XA_CUT_BUFFER0:
  1712. X      case XA_CUT_BUFFER1:
  1713. X      case XA_CUT_BUFFER2:
  1714. X      case XA_CUT_BUFFER3:
  1715. X      case XA_CUT_BUFFER4:
  1716. X      case XA_CUT_BUFFER5:
  1717. X      case XA_CUT_BUFFER6:
  1718. X      case XA_CUT_BUFFER7: continue;
  1719. X    }
  1720. X    XtDisownSelection(w, selection);
  1721. X    LoseSelection(w, &selection); /* in case it wasn't just called */
  1722. X    }
  1723. X}
  1724. X
  1725. X
  1726. Xvoid XtTextChangeOptions(w, options)
  1727. X    Widget        w;
  1728. X    int    options;
  1729. X{
  1730. X    TextWidget ctx = (TextWidget) w;
  1731. X
  1732. X    ctx->text.options = options;
  1733. X}
  1734. X
  1735. X
  1736. Xint XtTextGetOptions(w)
  1737. X    Widget        w;
  1738. X{
  1739. X    TextWidget ctx = (TextWidget) w;
  1740. X
  1741. X     return ctx->text.options;
  1742. X}
  1743. X
  1744. Xvoid XtTextSetSelection (w, left, right)
  1745. X    Widget        w;
  1746. X    XtTextPosition left, right;
  1747. X{
  1748. X    TextWidget ctx = (TextWidget) w;
  1749. X    Atom selection = XA_PRIMARY;
  1750. X
  1751. X    _XtTextPrepareToUpdate(ctx);
  1752. X        if (left == right)
  1753. X        XtTextUnsetSelection(w);
  1754. X    else
  1755. X        _XtTextSetNewSelection(ctx, left, right, &selection, ONE);
  1756. X    _XtTextExecuteUpdate(ctx);
  1757. X}
  1758. X
  1759. Xvoid XtTextInvalidate(w, from, to)
  1760. X    Widget        w;
  1761. X    XtTextPosition from,to;
  1762. X{
  1763. X    TextWidget ctx = (TextWidget) w;
  1764. X
  1765. X        ctx->text.lastPos = (*ctx->text.source->GetLastPos)(ctx->text.source);
  1766. X        _XtTextPrepareToUpdate(ctx);
  1767. X        _XtTextNeedsUpdating(ctx, from, to);
  1768. X        ForceBuildLineTable(ctx);
  1769. X        _XtTextExecuteUpdate(ctx);
  1770. X}
  1771. X
  1772. X/*ARGSUSED*/
  1773. Xvoid XtTextDisableRedisplay(w, d)
  1774. X    Widget w;
  1775. X    int d;
  1776. X{
  1777. X    register TextWidget ctx = (TextWidget)w;
  1778. X
  1779. X    ctx->text.update_disabled = True;
  1780. X    _XtTextPrepareToUpdate(ctx);
  1781. X}
  1782. X
  1783. Xvoid XtTextEnableRedisplay(w)
  1784. X    Widget w;
  1785. X{
  1786. X    register TextWidget ctx = (TextWidget)w;
  1787. X    register XtTextPosition lastPos;
  1788. X
  1789. X    if (!ctx->text.update_disabled) return;
  1790. X
  1791. X    ctx->text.update_disabled = False;
  1792. X    lastPos = ctx->text.lastPos = GETLASTPOS;
  1793. X    if (ctx->text.lt.top > lastPos)    ctx->text.lt.top = ctx->text.lastPos;
  1794. X    if (ctx->text.insertPos > lastPos) ctx->text.insertPos = ctx->text.lastPos;
  1795. X    if (ctx->text.s.left > lastPos ||
  1796. X    ctx->text.s.right > lastPos)  ctx->text.s.left = ctx->text.s.right = 0;
  1797. X
  1798. X    ForceBuildLineTable(ctx);
  1799. X    if (XtIsRealized(w))
  1800. X    DisplayTextWindow(w);
  1801. X    _XtTextExecuteUpdate(ctx);
  1802. X}
  1803. X
  1804. XXtTextSource XtTextGetSource(w)
  1805. X    Widget w;
  1806. X{
  1807. X    return ((TextWidget)w)->text.source;
  1808. X}
  1809. X
  1810. X
  1811. END_OF_FILE
  1812. if test 29444 -ne `wc -c <'xconf/Text.c.ab'`; then
  1813.     echo shar: \"'xconf/Text.c.ab'\" unpacked with wrong size!
  1814. fi
  1815. # end of 'xconf/Text.c.ab'
  1816. fi
  1817. echo shar: End of archive 2 \(of 5\).
  1818. cp /dev/null ark2isdone
  1819. MISSING=""
  1820. for I in 1 2 3 4 5 ; do
  1821.     if test ! -f ark${I}isdone ; then
  1822.     MISSING="${MISSING} ${I}"
  1823.     fi
  1824. done
  1825. if test "${MISSING}" = "" ; then
  1826.     echo You have unpacked all 5 archives.
  1827.     rm -f ark[1-9]isdone
  1828. else
  1829.     echo You still need to unpack the following archives:
  1830.     echo "        " ${MISSING}
  1831. fi
  1832. ##  End of shell archive.
  1833. exit 0
  1834.