home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume8 / chaos / part05 < prev    next >
Text File  |  1990-08-20  |  56KB  |  2,044 lines

  1. Path: uunet!wuarchive!usc!cs.utexas.edu!sun-barr!newstop!sun!uunet.UU.NET
  2. From: balr!panasun!ken@uunet.UU.NET (Ken Marks (x2425))
  3. Newsgroups: comp.sources.x
  4. Subject: v08i081: chaos, Part05/10
  5. Message-ID: <140959@sun.Eng.Sun.COM>
  6. Date: 20 Aug 90 18:04:04 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 2033
  9. Approved: argv@sun.com
  10.  
  11. Submitted-by: balr!panasun!ken@uunet.UU.NET (Ken Marks (x2425))
  12. Posting-number: Volume 8, Issue 81
  13. Archive-name: chaos/part05
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 5 (of 10)."
  22. # Contents:  headers/LocalDefs.h widgets/Menu.c widgets/Slider.c
  23. #   widgets/Text.c
  24. # Wrapped by ken@panasun on Mon Jul 30 14:59:49 1990
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f 'headers/LocalDefs.h' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'headers/LocalDefs.h'\"
  28. else
  29. echo shar: Extracting \"'headers/LocalDefs.h'\" \(1813 characters\)
  30. sed "s/^X//" >'headers/LocalDefs.h' <<'END_OF_FILE'
  31. X/*
  32. X * Copyright (c) Ken W. Marks 1989, 1990.
  33. X */
  34. X
  35. X#ifndef _LocalDefs_h
  36. X#define _LocalDefs_h
  37. X
  38. X/* Resource names */
  39. X
  40. X#define XtNbuffer        "buffer"
  41. X#define XtNbufferLen        "bufferLen"
  42. X#define XtNbuttonType        "buttonType"
  43. X#define XtNcellSize        "cellSize"
  44. X#define XtNcharsWide        "charsWide"
  45. X#define XtNcursor        "cursor"
  46. X#define XtNdefaultPos        "defaultPos"
  47. X#define XtNdialogbox        "dialogbox"
  48. X#define XtNdronePath        "dronePath"
  49. X#define XtNfontNormal        "fontNormal"
  50. X#define XtNfontReverse        "fontReverse"
  51. X#define XtNhorizPad        "horizPad"
  52. X#define XtNhosts        "hosts"
  53. X#define XtNimageDir        "imageDir"
  54. X#define XtNinitialText        "initialText"
  55. X#define XtNiterationLimit    "iterationLimit"
  56. X#define XtNkeepTasksSquare    "keepTasksSquare"
  57. X#define XtNlistDefault        "listDefault"
  58. X#define XtNlistItems        "listItems"
  59. X#define XtNmapDir        "mapDir"
  60. X#define XtNmaxValue        "maxValue"
  61. X#define XtNminValue        "minValue"
  62. X#define XtNmenuItems        "menuItems"
  63. X#define XtNnumberVisible    "numberVisible"
  64. X#define XtNradioDefault        "radioDefault"
  65. X#define XtNradioItems        "radioItems"
  66. X#define XtNretainAspectRatio    "retainAspectRatio"
  67. X#define XtNshowValue        "showValue"
  68. X#define XtNtaskHeight        "taskHeight"
  69. X#define XtNtaskWidth        "taskWidth"
  70. X#define XtNtoggleItems        "toggleItems"
  71. X#define XtNunfocusedBorder    "unfocusedBorder"
  72. X#define XtNvertPad        "vertPad"
  73. X#define XtNzoomDir        "zoomDir"
  74. X
  75. X/* Class types */
  76. X
  77. X#define XtCBuffer        "Buffer"
  78. X#define XtCButtonType        "ButtonType"
  79. X#define XtCCellSize        "CellSize"
  80. X#define XtCDefault        "Default"
  81. X#define XtCExtent        "Extent"
  82. X#define XtCHosts        "Hosts"
  83. X#define XtCLimit        "Limit"
  84. X#define XtCList            "List"
  85. X#define XtCPath            "Path"
  86. X#define XtCReserved        "Reserved"
  87. X#define XtCShowValue        "ShowValue"
  88. X#define XtCText            "Text"
  89. X#define XtCUnfocused        "Unfocused"
  90. X#define XtCWidget        "Widget"
  91. X
  92. X/* Resource types */
  93. X
  94. X#define XtRWidget        "Widget"
  95. X
  96. X#endif _LocalDefs_h
  97. END_OF_FILE
  98. if test 1813 -ne `wc -c <'headers/LocalDefs.h'`; then
  99.     echo shar: \"'headers/LocalDefs.h'\" unpacked with wrong size!
  100. fi
  101. # end of 'headers/LocalDefs.h'
  102. fi
  103. if test -f 'widgets/Menu.c' -a "${1}" != "-c" ; then 
  104.   echo shar: Will not clobber existing file \"'widgets/Menu.c'\"
  105. else
  106. echo shar: Extracting \"'widgets/Menu.c'\" \(16223 characters\)
  107. sed "s/^X//" >'widgets/Menu.c' <<'END_OF_FILE'
  108. X/*
  109. X * Copyright (c) Ken W. Marks 1989, 1990.
  110. X */
  111. X
  112. X#include <stdio.h>
  113. X#include <X11/IntrinsicP.h>
  114. X#include <X11/cursorfont.h>
  115. X#include <X11/StringDefs.h>
  116. X#include <Chaos.h>
  117. X#include <LocalDefs.h>
  118. X#include <MenuP.h>
  119. X#include <Colormap.h>
  120. X
  121. X/* For debugging purposes, set allow_grabs to False.  This disallows
  122. X * pointer and keyboard grabs so that menu code may be debugged
  123. X * (breakpointed) without the possibility of interrupting the client
  124. X * during a grab (rendering the workstation about as useful as a large
  125. X * paperweight or perhaps a small end table). */
  126. X
  127. Xstatic allow_grabs = True;
  128. X
  129. X#define GET_ITEM(w, x, y)    (((x) < 0 || \
  130. X                (x) >= w->core.width || \
  131. X                (y) < 0 || \
  132. X                (y) >= w->core.height) ? NO_ITEM : \
  133. X                (y) / w->menu.item_height)
  134. X
  135. X/* internal padding for items in menu */
  136. X#define VERTICAL_PAD        1
  137. X#define HORIZONTAL_PAD        2
  138. X
  139. X/* modes for drawing an item */
  140. X#define NORMAL            1
  141. X#define REVERSE            2
  142. X
  143. Xstatic void MenuInitialize();
  144. Xstatic void MenuRealize();
  145. Xstatic void MenuResize();
  146. Xstatic void MenuRedisplay();
  147. Xstatic void MenuDestroy();
  148. Xstatic void MenuBtnUp();
  149. Xstatic void MenuMotion();
  150. Xstatic void MenuLeave();
  151. Xstatic void MenuDrawItem();
  152. X
  153. X#define offset(field) XtOffset(MenuWidget, menu.field)
  154. X#define goffset(field) XtOffset(Widget,core.field)
  155. X
  156. Xstatic XtResource menu_resources[] = {
  157. X    {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
  158. X    offset(foreground), XtRString, "Black"},
  159. X    {XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel),
  160. X    goffset(background_pixel), XtRString, "White"},
  161. X    {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  162. X    offset(font), XtRString, "lucidasans-bold-18"},
  163. X    {XtNmenuItems, XtCList, XtRPointer, sizeof(char **),
  164. X    offset(items), XtRString, NULL},
  165. X    {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
  166. X    offset(cursor), XtRString, "arrow"},
  167. X    {XtNhorizPad, XtCMargin, XtRDimension, sizeof(Dimension),
  168. X    offset(h_pad), XtRImmediate, (caddr_t) HORIZONTAL_PAD},
  169. X    {XtNvertPad, XtCMargin, XtRDimension, sizeof(Dimension),
  170. X    offset(v_pad), XtRImmediate, (caddr_t) VERTICAL_PAD},
  171. X};
  172. X
  173. Xstatic XtActionsRec menu_actions[] =
  174. X{
  175. X    {"release", MenuBtnUp},
  176. X    {"move", MenuMotion},
  177. X    {"leave", MenuLeave},
  178. X};
  179. X
  180. Xstatic char menu_translations[] =
  181. X"<Btn3Up>:    release()\n\
  182. X <Motion>:    move()\n\
  183. X <Leave>:    leave()\n\
  184. X";
  185. X
  186. X#define superclass        (&simpleClassRec)
  187. X
  188. XMenuClassRec menuClassRec = {
  189. X    {
  190. X    /* core fields          */
  191. X     /* superclass         */ (WidgetClass) superclass,
  192. X     /* class_name         */ "Menu",
  193. X     /* widget_size         */ sizeof(MenuRec),
  194. X     /* class_initialize     */ NULL,
  195. X     /* class_part_initialize */ NULL,
  196. X     /* class_inited     */ FALSE,
  197. X     /* initialize         */ MenuInitialize,
  198. X     /* initialize_hook     */ NULL,
  199. X     /* realize         */ MenuRealize,
  200. X     /* actions         */ menu_actions,
  201. X     /* num_actions         */ XtNumber(menu_actions),
  202. X     /* resources         */ menu_resources,
  203. X     /* resource_count     */ XtNumber(menu_resources),
  204. X     /* xrm_class         */ NULLQUARK,
  205. X     /* compress_motion     */ TRUE,
  206. X     /* compress_exposure     */ TRUE,
  207. X     /* compress_enterleave     */ TRUE,
  208. X     /* visible_interest     */ FALSE,
  209. X     /* destroy         */ MenuDestroy,
  210. X     /* resize         */ MenuResize,
  211. X     /* expose         */ MenuRedisplay,
  212. X     /* set_values         */ NULL,
  213. X     /* set_values_hook     */ NULL,
  214. X     /* set_values_almost     */ XtInheritSetValuesAlmost,
  215. X     /* get_values_hook     */ NULL,
  216. X     /* accept_focus     */ NULL,
  217. X     /* version         */ XtVersion,
  218. X     /* callback_private     */ NULL,
  219. X     /* tm_table         */ menu_translations,
  220. X     /* query_geometry       */ NULL,
  221. X     /* display_accelerator     */ XtInheritDisplayAccelerator,
  222. X     /* extension         */ NULL
  223. X    },
  224. X    {
  225. X    /* Simple class fields initialization */
  226. X     /* change_sensitive     */ XtInheritChangeSensitive
  227. X    }
  228. X};
  229. X
  230. X
  231. XWidgetClass menuWidgetClass = (WidgetClass) & menuClassRec;
  232. X
  233. X
  234. X/************************************************************/
  235. X/******************** Private Procedures ********************/
  236. X/************************************************************/
  237. X
  238. X
  239. Xstatic void MenuGetGC(w)
  240. XMenuWidget w;
  241. X{
  242. X    Screen *screen = XtScreen(w);
  243. X    XGCValues values;
  244. X
  245. X    values.foreground = w->menu.foreground;
  246. X    values.background = w->core.background_pixel;
  247. X    values.font = w->menu.font->fid;
  248. X    values.fill_style = FillTiled;
  249. X    values.function = GXor;
  250. X    values.tile = XmuCreateStippledPixmap(screen, w->menu.foreground,
  251. X      w->core.background_pixel, (unsigned) DefaultDepthOfScreen(screen));
  252. X
  253. X
  254. X    w->menu.normal_gc = XtGetGC((Widget) w, (unsigned) GCForeground |
  255. X      GCBackground | GCFont, &values);
  256. X
  257. X    w->menu.gray_gc = XtGetGC((Widget) w, (unsigned) GCForeground |
  258. X      GCBackground | GCFunction | GCFont | GCTile | GCFillStyle, &values);
  259. X
  260. X    values.foreground = values.background;
  261. X
  262. X    w->menu.clear_gc = XtGetGC((Widget) w, (unsigned) GCForeground |
  263. X      GCBackground, &values);
  264. X
  265. X    values.background = w->menu.foreground;
  266. X
  267. X    w->menu.reverse_gc = XtGetGC((Widget) w, (unsigned) GCForeground |
  268. X      GCBackground | GCFont, &values);
  269. X}
  270. X
  271. X
  272. Xstatic void MenuSetSize(w)
  273. XMenuWidget w;
  274. X{
  275. X    XFontStruct *fs = w->menu.font;
  276. X    MenuItem *item;
  277. X    Cardinal height = fs->max_bounds.ascent + fs->max_bounds.descent;
  278. X    Cardinal width;
  279. X    Cardinal max_width = 0;
  280. X    int ii = 0;
  281. X
  282. X    while (1)
  283. X    {
  284. X    item = &(w->menu.items[ii]);
  285. X    if (item->label == NULL)
  286. X        break;
  287. X    width = XTextWidth(fs, item->label, STRLEN(item->label));
  288. X    max_width = MAX(max_width, width);
  289. X    ++ii;
  290. X    }
  291. X
  292. X    w->menu.num_items = ii;
  293. X    w->menu.item_width = max_width;
  294. X    w->menu.item_height = height + 2 * w->menu.v_pad;
  295. X    w->core.width = w->menu.item_width + 2 * w->menu.h_pad;
  296. X    w->core.height = w->menu.item_height * w->menu.num_items;
  297. X}
  298. X
  299. X
  300. X/*ARGSUSED*/
  301. Xstatic void MenuInitialize(request, new)
  302. XWidget request;            /* unused */
  303. XWidget new;
  304. X{
  305. X    MenuWidget w = (MenuWidget) new;
  306. X    int ii;
  307. X
  308. X    w->menu.pixmap = NULL;
  309. X    w->menu.current_item = NO_ITEM;
  310. X    w->menu.mode = ModeUndecided;
  311. X
  312. X    MenuGetGC(w);
  313. X    MenuSetSize(w);
  314. X
  315. X    /* After MenuSetSize is called, the number of menu items is stored in
  316. X     * num_items.  Using this value, we allocate a private copy of the menu
  317. X     * structure so that it doesn't change from under us. */
  318. X
  319. X    ii = w->menu.num_items;
  320. X    w->menu.items = (MenuItem *) COPY(w->menu.items, ii * sizeof(MenuItem));
  321. X
  322. X    /* And don't forget to make private copies of all the labels in the menu
  323. X     * structure. */
  324. X    while (--ii >= 0)
  325. X    w->menu.items[ii].label = STRCOPY(w->menu.items[ii].label);
  326. X}
  327. X
  328. X
  329. Xstatic void MenuRealize(widget, valueMask, attrs)
  330. XWidget widget;
  331. XXtValueMask *valueMask;
  332. XXSetWindowAttributes *attrs;
  333. X{
  334. X    XtCreateWindow(widget, InputOutput, (Visual *) CopyFromParent,
  335. X      *valueMask, attrs);
  336. X
  337. X    /* Call Resize() to initialize pixmap at creation time since the */
  338. X    /* Redisplay() will generally be called before Resize() would.   */
  339. X
  340. X    (*XtClass(widget)->core_class.resize) (widget);
  341. X}
  342. X
  343. X
  344. X/*ARGSUSED*/
  345. Xstatic void MenuRedisplay(widget, event, region)
  346. XWidget widget;
  347. XXEvent *event;
  348. XRegion region;            /* unused */
  349. X{
  350. X    MenuWidget w = (MenuWidget) widget;
  351. X    Window window = XtWindow(w);
  352. X    Display *dpy = XtDisplay(w);
  353. X    XExposeEvent *ev = (XExposeEvent *) event;
  354. X
  355. X    if (XtIsRealized(widget) == False)
  356. X    return;
  357. X
  358. X    XCopyArea(dpy, w->menu.pixmap, window, w->menu.normal_gc,
  359. X      ev->x, ev->y, (unsigned) ev->width, (unsigned) ev->height, ev->x, ev->y);
  360. X}
  361. X
  362. X
  363. Xstatic void MenuUpdatePixmap(widget, item)
  364. XWidget widget;
  365. Xint item;
  366. X{
  367. X    MenuWidget w = (MenuWidget) widget;
  368. X    Display *dpy = XtDisplay(w);
  369. X    Window window = XtWindow(w);
  370. X    MenuItem *menu_item;
  371. X    int ii;
  372. X    int x, y;
  373. X    int first_item = 0;
  374. X    int last_item = w->menu.num_items - 1;
  375. X
  376. X    if (!XtIsRealized(widget))
  377. X    return;
  378. X
  379. X    /* if the call was for a particular item */
  380. X    if (item != NO_ITEM)
  381. X    first_item = last_item = item;
  382. X
  383. X    for (ii = first_item; ii <= last_item; ++ii)
  384. X    {
  385. X    menu_item = &(w->menu.items[ii]);
  386. X    x = (Position) w->menu.h_pad;
  387. X    y = (Position) w->menu.item_height * ii + w->menu.v_pad +
  388. X      w->menu.font->max_bounds.ascent;
  389. X
  390. X    XFillRectangle(dpy, w->menu.pixmap,
  391. X      menu_item->sensitive ? w->menu.reverse_gc : w->menu.gray_gc,
  392. X      0, w->menu.item_height * ii, w->core.width, w->menu.item_height);
  393. X
  394. X    XDrawString(dpy, w->menu.pixmap, w->menu.normal_gc, x, y,
  395. X      menu_item->label, STRLEN(menu_item->label));
  396. X    }
  397. X
  398. X    XCopyArea(dpy, w->menu.pixmap, window, w->menu.normal_gc,
  399. X      0, w->menu.item_height * first_item, w->core.width,
  400. X      (last_item - first_item + 1) * w->menu.item_height,
  401. X      0, w->menu.item_height * first_item);
  402. X}
  403. X
  404. X
  405. Xstatic void MenuResize(widget)
  406. XWidget widget;
  407. X{
  408. X    MenuWidget w = (MenuWidget) widget;
  409. X    Display *dpy = XtDisplay(w);
  410. X    Window window = XtWindow(w);
  411. X    static unsigned int height = 0, width = 0;
  412. X
  413. X    if (XtIsRealized(widget) &&
  414. X      (height != w->core.height || width != w->core.width))
  415. X    {
  416. X    height = w->core.height;
  417. X    width = w->core.width;
  418. X
  419. X    if (w->menu.pixmap)
  420. X        XFreePixmap(dpy, w->menu.pixmap);
  421. X
  422. X    w->menu.pixmap = XCreatePixmap(dpy, window, width, height,
  423. X      w->core.depth);
  424. X
  425. X    if (!w->menu.pixmap)
  426. X    {
  427. X        eprintf("Insufficient space for pixmap\n");
  428. X        abort();
  429. X    }
  430. X
  431. X    /* clear the pixmap */
  432. X    XFillRectangle(dpy, w->menu.pixmap, w->menu.clear_gc,
  433. X      0, 0, w->core.width, w->core.height);
  434. X
  435. X    MenuUpdatePixmap(widget, NO_ITEM);
  436. X    }
  437. X}
  438. X
  439. X
  440. Xstatic void MenuDestroy(widget)
  441. XWidget widget;
  442. X{
  443. X    MenuWidget w = (MenuWidget) widget;
  444. X
  445. X    XtReleaseGC(widget, w->menu.normal_gc);
  446. X    XtReleaseGC(widget, w->menu.clear_gc);
  447. X    XtReleaseGC(widget, w->menu.reverse_gc);
  448. X    XtReleaseGC(widget, w->menu.gray_gc);
  449. X}
  450. X
  451. X
  452. Xstatic void MenuDrawItem(w, item, mode)
  453. XMenuWidget w;
  454. Xint item;
  455. Xint mode;
  456. X{
  457. X    MenuItem *menu_item = &(w->menu.items[item]);
  458. X    Display *dpy = XtDisplay(w);
  459. X    Window window = XtWindow(w);
  460. X    Position x, y;
  461. X    GC fill_gc;
  462. X    GC draw_gc;
  463. X
  464. X    x = (Position) w->menu.h_pad;
  465. X    y = (Position) w->menu.item_height * item + w->menu.v_pad +
  466. X      w->menu.font->max_bounds.ascent;
  467. X
  468. X    if (mode == REVERSE)
  469. X    {
  470. X    fill_gc = w->menu.normal_gc;
  471. X    draw_gc = w->menu.reverse_gc;
  472. X    }
  473. X    else
  474. X    {
  475. X    fill_gc = w->menu.reverse_gc;
  476. X    draw_gc = w->menu.normal_gc;
  477. X    }
  478. X
  479. X    XFillRectangle(dpy, window, fill_gc, 0, w->menu.item_height * item,
  480. X      w->core.width, w->menu.item_height);
  481. X
  482. X    XDrawString(dpy, window, draw_gc, x, y, menu_item->label,
  483. X      STRLEN(menu_item->label));
  484. X}
  485. X
  486. X
  487. X/***********************************************************/
  488. X/******************** Action Procedures ********************/
  489. X/***********************************************************/
  490. X
  491. X
  492. X/*ARGSUSED*/
  493. Xstatic void MenuLeave(widget, event, params, num_params)
  494. XWidget widget;
  495. XXEvent *event;            /* unused */
  496. XString *params;            /* unused */
  497. XCardinal *num_params;        /* unused */
  498. X{
  499. X    MenuWidget w = (MenuWidget) widget;
  500. X
  501. X    if (w->menu.current_item != NO_ITEM)
  502. X    {
  503. X    MenuDrawItem(w, w->menu.current_item, NORMAL);
  504. X    w->menu.current_item = NO_ITEM;
  505. X    }
  506. X}
  507. X
  508. X
  509. X/*ARGSUSED*/
  510. Xstatic void MenuBtnUp(widget, event, params, num_params)
  511. XWidget widget;
  512. XXEvent *event;
  513. XString *params;            /* unused */
  514. XCardinal *num_params;        /* unused */
  515. X{
  516. X    MenuWidget w = (MenuWidget) widget;
  517. X    Display *dpy = XtDisplay(w);
  518. X    XButtonEvent *ev = (XButtonEvent *) & event->xbutton;
  519. X    int selected;
  520. X
  521. X    if (w->menu.mode == ModeUndecided)
  522. X    {
  523. X    /* We ignore the event and implement a click style interface */
  524. X    w->menu.mode = ModeClick;
  525. X    return;
  526. X    }
  527. X
  528. X    MenuPopdown(widget);
  529. X    XSync(dpy, False);
  530. X    selected = GET_ITEM(w, ev->x, ev->y);
  531. X    if (selected == NO_ITEM)
  532. X    return;
  533. X
  534. X    /* Call function */
  535. X    if (w->menu.items[selected].sensitive &&
  536. X      w->menu.items[selected].func != NULL)
  537. X    (*w->menu.items[selected].func) (widget, w->menu.items[selected].data,
  538. X      selected);
  539. X}
  540. X
  541. X
  542. X/*ARGSUSED*/
  543. Xstatic void MenuMotion(widget, event, params, num_params)
  544. XWidget widget;
  545. XXEvent *event;
  546. XString *params;            /* unused */
  547. XCardinal *num_params;        /* unused */
  548. X{
  549. X    MenuWidget w = (MenuWidget) widget;
  550. X    XMotionEvent *ev = (XMotionEvent *) & event->xmotion;
  551. X    int new_item;
  552. X
  553. X    if (w->menu.mode == ModeUndecided)
  554. X    /* We implement a drag style interface */
  555. X    w->menu.mode = ModeDrag;
  556. X
  557. X    new_item = GET_ITEM(w, ev->x, ev->y);
  558. X
  559. X    if (w->menu.current_item == new_item)
  560. X    return;
  561. X
  562. X    if (w->menu.current_item != NO_ITEM)
  563. X    MenuDrawItem(w, w->menu.current_item, NORMAL);
  564. X
  565. X    if (new_item != NO_ITEM && w->menu.items[new_item].sensitive == False)
  566. X    {
  567. X    /* save the current item which is now insensitive in case it should
  568. X     * change to sensitive while we are over it. */
  569. X    w->menu.current_insensitive_item = new_item;
  570. X    new_item = NO_ITEM;
  571. X    }
  572. X
  573. X    w->menu.current_item = new_item;
  574. X
  575. X    if (new_item != NO_ITEM)
  576. X    {
  577. X    MenuDrawItem(w, w->menu.current_item, REVERSE);
  578. X    w->menu.current_insensitive_item = NO_ITEM;
  579. X    }
  580. X}
  581. X
  582. X
  583. X/***********************************************************/
  584. X/******************** Public Procedures ********************/
  585. X/***********************************************************/
  586. X
  587. X
  588. XBoolean MenuChangeLabel(widget, item, label)
  589. XWidget widget;
  590. XCardinal item;
  591. XString label;
  592. X{
  593. X    MenuWidget w = (MenuWidget) widget;
  594. X
  595. X    if (item >= w->menu.num_items || label == NULL)
  596. X    return (False);
  597. X
  598. X    if (strcmp(w->menu.items[item].label, label) != SAME)
  599. X    {
  600. X    free(w->menu.items[item].label);
  601. X    w->menu.items[item].label = STRCOPY(label);
  602. X    MenuUpdatePixmap(widget, (int) item);
  603. X    }
  604. X    return (True);
  605. X}
  606. X
  607. X
  608. XBoolean MenuChangeFunction(widget, item, func)
  609. XWidget widget;
  610. XCardinal item;
  611. Xvoid (*func) ();
  612. X{
  613. X    MenuWidget w = (MenuWidget) widget;
  614. X
  615. X    if (item >= w->menu.num_items)
  616. X    return (False);
  617. X
  618. X    w->menu.items[item].func = func;
  619. X    return (True);
  620. X}
  621. X
  622. X
  623. XBoolean MenuChangeClientData(widget, item, data)
  624. XWidget widget;
  625. XCardinal item;
  626. Xcaddr_t data;
  627. X{
  628. X    MenuWidget w = (MenuWidget) widget;
  629. X
  630. X    if (item >= w->menu.num_items)
  631. X    return (False);
  632. X
  633. X    w->menu.items[item].data = data;
  634. X    return (True);
  635. X}
  636. X
  637. X
  638. XBoolean MenuChangeSensitivity(widget, item, sensitive)
  639. XWidget widget;
  640. XCardinal item;
  641. XBoolean sensitive;
  642. X{
  643. X    MenuWidget w = (MenuWidget) widget;
  644. X
  645. X    if (item >= w->menu.num_items)
  646. X    return (False);
  647. X
  648. X    if (w->menu.items[item].sensitive != sensitive)
  649. X    {
  650. X    w->menu.items[item].sensitive = sensitive;
  651. X
  652. X    if (XtIsRealized(widget) == False)
  653. X        return (True);
  654. X
  655. X    if (sensitive == True && item == w->menu.current_insensitive_item)
  656. X    {
  657. X        /* we have re-sensitized the item that the pointer is parked on
  658. X         * therefore we should now highlight this item. */
  659. X        if (w->menu.current_item != NO_ITEM)
  660. X        {
  661. X        MenuDrawItem(w, w->menu.current_item, NORMAL);
  662. X        }
  663. X        w->menu.current_item = item;
  664. X        MenuDrawItem(w, w->menu.current_item, REVERSE);
  665. X    }
  666. X    else
  667. X        MenuUpdatePixmap(widget, (int) item);
  668. X    }
  669. X    return (True);
  670. X}
  671. X
  672. X
  673. Xvoid MenuPopup(widget, event, params, num_params)
  674. XWidget widget;
  675. XXEvent *event;
  676. XString *params;
  677. XCardinal *num_params;
  678. X{
  679. X    Display *dpy = XtDisplay(widget);
  680. X    Screen *screen = XtScreen(widget);
  681. X    Widget popup_shell;
  682. X    MenuWidget menu;
  683. X    XButtonEvent *ev = (XButtonEvent *) & event->xbutton;
  684. X    int popup_x, popup_y;
  685. X    int max_popup_x, max_popup_y;
  686. X    unsigned int mask;
  687. X
  688. X    if (*num_params != 1)
  689. X    {
  690. X    eprintf("MenuPopup must be called with the name of a menu\n");
  691. X    return;
  692. X    }
  693. X
  694. X    menu = (MenuWidget) XtNameToWidget(XtParent(widget), params[0]);
  695. X
  696. X    if (menu == NULL)
  697. X    {
  698. X    eprintf("Invalid menu name '%s'\n", params[0]);
  699. X    return;
  700. X    }
  701. X
  702. X    popup_shell = XtParent(menu);
  703. X
  704. X    popup_x = ev->x_root;
  705. X    popup_y = ev->y_root;
  706. X
  707. X    max_popup_x = WidthOfScreen(screen) - menu->core.width;
  708. X
  709. X    if (popup_x > max_popup_x)
  710. X    popup_x = max_popup_x;
  711. X
  712. X    max_popup_y = HeightOfScreen(screen) - menu->core.height;
  713. X
  714. X    if (popup_y > max_popup_y)
  715. X    popup_y = max_popup_y;
  716. X
  717. X    menu->menu.current_item = NO_ITEM;
  718. X    menu->menu.mode = ModeUndecided;
  719. X    XtMoveWidget(popup_shell, popup_x, popup_y);
  720. X    XtRealizeWidget(popup_shell);
  721. X    XMapRaised(dpy, XtWindow(popup_shell));
  722. X
  723. X    if (!allow_grabs)
  724. X    return;
  725. X
  726. X    mask = ButtonPressMask |
  727. X      ButtonReleaseMask |
  728. X      ButtonMotionMask |
  729. X      PointerMotionMask |
  730. X      EnterWindowMask |
  731. X      LeaveWindowMask;
  732. X
  733. X    XGrabPointer(dpy, XtWindow(menu), False, mask, GrabModeAsync,
  734. X      GrabModeAsync, None, menu->menu.cursor, ev->time);
  735. X}
  736. X
  737. X
  738. Xvoid MenuPopdown(widget)
  739. XWidget widget;
  740. X{
  741. X    MenuWidget w = (MenuWidget) widget;
  742. X    Display *dpy = XtDisplay(w);
  743. X
  744. X    XUngrabPointer(dpy, CurrentTime);
  745. X    XtUnmapWidget(XtParent(widget));
  746. X    XSync(dpy, False);
  747. X}
  748. END_OF_FILE
  749. if test 16223 -ne `wc -c <'widgets/Menu.c'`; then
  750.     echo shar: \"'widgets/Menu.c'\" unpacked with wrong size!
  751. fi
  752. # end of 'widgets/Menu.c'
  753. fi
  754. if test -f 'widgets/Slider.c' -a "${1}" != "-c" ; then 
  755.   echo shar: Will not clobber existing file \"'widgets/Slider.c'\"
  756. else
  757. echo shar: Extracting \"'widgets/Slider.c'\" \(16605 characters\)
  758. sed "s/^X//" >'widgets/Slider.c' <<'END_OF_FILE'
  759. X/*
  760. X * Copyright (c) Ken W. Marks 1989, 1990.
  761. X */
  762. X
  763. X#include <stdio.h>
  764. X#include <X11/IntrinsicP.h>
  765. X#include <X11/StringDefs.h>
  766. X#include <Chaos.h>
  767. X#include <LocalDefs.h>
  768. X#include <SliderP.h>
  769. X#include <Colormap.h>
  770. X#include <DlgShell.h>
  771. X
  772. X#define IN_LEFT_ARROW(w, x, y)    (((x) < (w)->slider.min_x && \
  773. X                (x) >= (w)->slider.char_width && \
  774. X                (y) >= 0 && \
  775. X                (y) < (w)->slider.char_height) ? True : False)
  776. X
  777. X#define IN_RIGHT_ARROW(w, x, y)    (((x) < (w)->slider.bar_width && \
  778. X                (x) >= (w)->slider.bar_width - \
  779. X                (w)->slider.arrow_width && \
  780. X                (y) >= 0 && \
  781. X                (y) < (w)->slider.char_height) ? True : False)
  782. X
  783. X#define IN_SCROLLBAR(w, x, y)    (((x) >= (w)->slider.min_x && \
  784. X                (x) < (w)->slider.bar_width - \
  785. X                (w)->slider.arrow_width \
  786. X                && (y) >= 0 && \
  787. X                (y) < (w)->slider.char_height) ? True : False)
  788. X
  789. X#define LEFT_ARROW_STRING    "\007\010"
  790. X#define RIGHT_ARROW_STRING    "\011\012"
  791. X#define SLOT_STRING        "\013\013"
  792. X#define KNOB_STRING        "\014\015"
  793. X
  794. X#define ARROW            '\037'
  795. X#define BLANK            '\036'
  796. X
  797. Xstatic void SliderInitialize();
  798. Xstatic void SliderRealize();
  799. Xstatic void SliderRedisplay();
  800. Xstatic void SliderDestroy();
  801. Xstatic void SliderDrawArrow();
  802. Xstatic void SliderMoveKnob();
  803. Xstatic void SliderMark();
  804. Xstatic void SliderGoto();
  805. Xstatic void SliderSlide();
  806. Xstatic void SliderFocusIn();
  807. Xstatic void SliderFocusOut();
  808. Xstatic void SliderBtnUp();
  809. Xstatic void SliderLeave();
  810. Xstatic void SliderMotion();
  811. X
  812. X#define offset(field) XtOffset(SliderWidget, slider.field)
  813. X#define goffset(field) XtOffset(Widget,core.field)
  814. X
  815. Xstatic XtResource slider_resources[] = {
  816. X    {XtNdefaultPos, XtCDefault, XtRInt, sizeof(int),
  817. X    offset(position), XtRImmediate, (caddr_t) 0},
  818. X    {XtNminValue, XtCExtent, XtRInt, sizeof(int),
  819. X    offset(min_value), XtRImmediate, (caddr_t) 0},
  820. X    {XtNmaxValue, XtCExtent, XtRInt, sizeof(int),
  821. X    offset(max_value), XtRImmediate, (caddr_t) 0},
  822. X    {XtNshowValue, XtCShowValue, XtRBool, sizeof(Boolean),
  823. X    offset(show_value), XtRImmediate, (caddr_t) True},
  824. X    {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
  825. X    offset(foreground), XtRString, "Black"},
  826. X    {XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel),
  827. X    goffset(background_pixel), XtRString, "White"},
  828. X    {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  829. X    offset(font), XtRString, "chaos-bold"},
  830. X    {XtNcallback, XtCCallback, XtRCallback, sizeof(caddr_t),
  831. X    offset(callbacks), XtRCallback, (caddr_t) NULL},
  832. X    {XtNdialogbox, XtCWidget, XtRWidget, sizeof(Widget),
  833. X    offset(dialogbox), XtRWidget, (caddr_t) NULL},
  834. X    {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
  835. X    offset(cursor), XtRString, "arrow"},
  836. X};
  837. X
  838. Xstatic XtActionsRec slider_actions[] =
  839. X{
  840. X    {"mark", SliderMark},
  841. X    {"goto", SliderGoto},
  842. X    {"slide", SliderSlide},
  843. X    {"focus_in", SliderFocusIn},
  844. X    {"focus_out", SliderFocusOut},
  845. X    {"release", SliderBtnUp},
  846. X    {"leave", SliderLeave},
  847. X    {"move", SliderMotion},
  848. X};
  849. X
  850. Xstatic char slider_translations[] =
  851. X"<BtnDown>:        mark()\n\
  852. X <BtnUp>:        release()\n\
  853. X <Motion>:        move()\n\
  854. X <Leave>:        leave()\n\
  855. X Shift<Key>Tab:        goto(PREV)\n\
  856. X <Key>Tab:        goto(NEXT)\n\
  857. X <Key>Right:        slide(RIGHT)\n\
  858. X <Key>Left:        slide(LEFT)\n\
  859. X <FocusIn>:        focus_in()\n\
  860. X <FocusOut>:        focus_out()\n\
  861. X";
  862. X
  863. X#define superclass        (&simpleClassRec)
  864. X
  865. XSliderClassRec sliderClassRec = {
  866. X    {
  867. X    /* core fields          */
  868. X     /* superclass         */ (WidgetClass) superclass,
  869. X     /* class_name         */ "Slider",
  870. X     /* widget_size         */ sizeof(SliderRec),
  871. X     /* class_initialize     */ NULL,
  872. X     /* class_part_initialize */ NULL,
  873. X     /* class_inited     */ FALSE,
  874. X     /* initialize         */ SliderInitialize,
  875. X     /* initialize_hook     */ NULL,
  876. X     /* realize         */ SliderRealize,
  877. X     /* actions         */ slider_actions,
  878. X     /* num_actions         */ XtNumber(slider_actions),
  879. X     /* resources         */ slider_resources,
  880. X     /* resource_count     */ XtNumber(slider_resources),
  881. X     /* xrm_class         */ NULLQUARK,
  882. X     /* compress_motion     */ TRUE,
  883. X     /* compress_exposure     */ TRUE,
  884. X     /* compress_enterleave     */ TRUE,
  885. X     /* visible_interest     */ FALSE,
  886. X     /* destroy         */ SliderDestroy,
  887. X     /* resize         */ NULL,
  888. X     /* expose         */ SliderRedisplay,
  889. X     /* set_values         */ NULL,
  890. X     /* set_values_hook     */ NULL,
  891. X     /* set_values_almost     */ XtInheritSetValuesAlmost,
  892. X     /* get_values_hook     */ NULL,
  893. X     /* accept_focus     */ NULL,
  894. X     /* version         */ XtVersion,
  895. X     /* callback_private     */ NULL,
  896. X     /* tm_table         */ slider_translations,
  897. X     /* query_geometry       */ NULL,
  898. X     /* display_accelerator     */ XtInheritDisplayAccelerator,
  899. X     /* extension         */ NULL
  900. X    },
  901. X    {
  902. X    /* Simple class fields initialization */
  903. X     /* change_sensitive     */ XtInheritChangeSensitive
  904. X    }
  905. X};
  906. X
  907. X
  908. XWidgetClass sliderWidgetClass = (WidgetClass) & sliderClassRec;
  909. X
  910. X
  911. X/************************************************************/
  912. X/******************** Private Procedures ********************/
  913. X/************************************************************/
  914. X
  915. X
  916. Xstatic void SliderGetGC(w)
  917. XSliderWidget w;
  918. X{
  919. X    XGCValues values;
  920. X
  921. X    values.foreground = w->slider.foreground;
  922. X    values.background = w->core.background_pixel;
  923. X    values.font = w->slider.font->fid;
  924. X
  925. X    w->slider.normal_gc = XtGetGC((Widget) w, (unsigned) GCForeground |
  926. X      GCBackground | GCFont, &values);
  927. X
  928. X    values.foreground = values.background;
  929. X
  930. X    w->slider.clear_gc = XtGetGC((Widget) w, (unsigned) GCForeground |
  931. X      GCBackground | GCFont, &values);
  932. X}
  933. X
  934. X
  935. Xstatic void SliderSetSize(w)
  936. XSliderWidget w;
  937. X{
  938. X    XtWidgetGeometry my_request;
  939. X    XFontStruct *fs = w->slider.font;
  940. X    Cardinal height = fs->max_bounds.ascent + fs->max_bounds.descent;
  941. X    Cardinal width = fs->max_bounds.width;
  942. X
  943. X    w->slider.baseline = fs->max_bounds.ascent + 1;
  944. X    w->slider.char_width = width;
  945. X    w->slider.char_height = height;
  946. X    w->slider.arrow_width = width * 2;
  947. X    w->slider.knob_width = width * 2;
  948. X    w->slider.center_to_left_edge = width;
  949. X
  950. X    w->slider.bar_width = w->slider.max_value - w->slider.min_value +
  951. X      w->slider.char_width + 2 * w->slider.arrow_width + w->slider.knob_width;
  952. X
  953. X    w->slider.value_width = (w->slider.show_value == False ? 0 :
  954. X      w->slider.value_len * width);
  955. X
  956. X    my_request.request_mode = CWWidth | CWHeight | CWBorderWidth;
  957. X    my_request.width = w->slider.bar_width + w->slider.value_width;
  958. X    my_request.height = w->slider.char_height + 2;
  959. X    my_request.border_width = 0;
  960. X
  961. X    XtMakeGeometryRequest((Widget) w, &my_request, NULL);
  962. X
  963. X    w->slider.min_x = w->slider.char_width + w->slider.arrow_width;
  964. X    w->slider.max_x = w->slider.bar_width - w->slider.arrow_width -
  965. X      w->slider.knob_width;
  966. X}
  967. X
  968. X
  969. X/*ARGSUSED*/
  970. Xstatic void SliderInitialize(request, new)
  971. XWidget request;            /* unused */
  972. XWidget new;
  973. X{
  974. X    SliderWidget w = (SliderWidget) new;
  975. X    int min_len, max_len;
  976. X
  977. X    if (w->slider.dialogbox == NULL)
  978. X    {
  979. X    eprintf("XtNdialogbox not set\n");
  980. X    abort();
  981. X    }
  982. X
  983. X    if (w->slider.show_value == True)
  984. X    {
  985. X    w->slider.show_sign = w->slider.min_value < 0;
  986. X    (void) sprintf(w->slider.value_in_ascii, "%+d", w->slider.min_value);
  987. X    min_len = strlen(w->slider.value_in_ascii);
  988. X
  989. X    (void) sprintf(w->slider.value_in_ascii, "%+d", w->slider.max_value);
  990. X    max_len = strlen(w->slider.value_in_ascii);
  991. X
  992. X    /* compute total length of string (e.g. " [-10]") */
  993. X    w->slider.value_len = MAX(min_len, max_len) +
  994. X      (w->slider.show_sign ? 3 : 2);
  995. X    }
  996. X
  997. X    SliderGetGC(w);
  998. X    SliderSetSize(w);
  999. X
  1000. X    w->slider.active = False;
  1001. X    w->slider.scrolling = False;
  1002. X    w->slider.knob_x = w->slider.min_x + w->slider.position -
  1003. X      w->slider.min_value;
  1004. X}
  1005. X
  1006. X
  1007. Xstatic void SliderRealize(widget, valueMask, attrs)
  1008. XWidget widget;
  1009. XXtValueMask *valueMask;
  1010. XXSetWindowAttributes *attrs;
  1011. X{
  1012. X    SliderWidget w = (SliderWidget) widget;
  1013. X    Display *dpy = XtDisplay(w);
  1014. X    Window window;
  1015. X    Position x;
  1016. X
  1017. X    XtCreateWindow(widget, InputOutput, (Visual *) CopyFromParent,
  1018. X      *valueMask, attrs);
  1019. X
  1020. X    window = XtWindow(w);
  1021. X
  1022. X    w->slider.pixmap = XCreatePixmap(dpy, window, w->core.width, w->core.height,
  1023. X      w->core.depth);
  1024. X
  1025. X    if (!w->slider.pixmap)
  1026. X    {
  1027. X    eprintf("Insufficient space for pixmap\n");
  1028. X    abort();
  1029. X    }
  1030. X
  1031. X    /* clear the pixmap */
  1032. X    XFillRectangle(dpy, w->slider.pixmap, w->slider.clear_gc, 0, 0,
  1033. X      w->core.width, w->core.height);
  1034. X
  1035. X    x = w->slider.char_width;
  1036. X    XDrawImageString(dpy, w->slider.pixmap, w->slider.normal_gc, x,
  1037. X      w->slider.baseline, LEFT_ARROW_STRING, 2);
  1038. X
  1039. X    for (x = w->slider.min_x; x < w->slider.bar_width - w->slider.arrow_width;
  1040. X      x += w->slider.knob_width)
  1041. X    XDrawImageString(dpy, w->slider.pixmap, w->slider.normal_gc, x,
  1042. X      w->slider.baseline, SLOT_STRING, 2);
  1043. X
  1044. X    x = w->slider.bar_width - w->slider.arrow_width;
  1045. X    XDrawImageString(dpy, w->slider.pixmap, w->slider.normal_gc, x,
  1046. X      w->slider.baseline, RIGHT_ARROW_STRING, 2);
  1047. X
  1048. X    x = w->slider.knob_x;
  1049. X    XDrawImageString(dpy, w->slider.pixmap, w->slider.normal_gc, x,
  1050. X      w->slider.baseline, KNOB_STRING, 2);
  1051. X
  1052. X    XDrawLine(dpy, w->slider.pixmap, w->slider.normal_gc, w->slider.char_width,
  1053. X      0, w->core.width - w->slider.value_width - 1, 0);
  1054. X
  1055. X    XDrawLine(dpy, w->slider.pixmap, w->slider.normal_gc, w->slider.char_width,
  1056. X      w->core.height - 1, w->core.width - w->slider.value_width - 1,
  1057. X      w->core.height - 1);
  1058. X}
  1059. X
  1060. X
  1061. X
  1062. X/*ARGSUSED*/
  1063. Xstatic void SliderRedisplay(widget, event, region)
  1064. XWidget widget;
  1065. XXEvent *event;
  1066. XRegion region;            /* unused */
  1067. X{
  1068. X    SliderWidget w = (SliderWidget) widget;
  1069. X    Window window = XtWindow(w);
  1070. X    Display *dpy = XtDisplay(w);
  1071. X    XExposeEvent *ev = (XExposeEvent *) event;
  1072. X
  1073. X    if (XtIsRealized(widget) == False)
  1074. X    return;
  1075. X
  1076. X    if (ev == NULL)
  1077. X    XCopyArea(dpy, w->slider.pixmap, window, w->slider.normal_gc,
  1078. X      0, 0, w->core.width, w->core.height, 0, 0);
  1079. X    else
  1080. X    XCopyArea(dpy, w->slider.pixmap, window, w->slider.normal_gc,
  1081. X      ev->x, ev->y, (unsigned) ev->width, (unsigned) ev->height,
  1082. X      ev->x, ev->y);
  1083. X
  1084. X    SliderDrawArrow(widget);
  1085. X
  1086. X    if (w->slider.show_value)
  1087. X    {
  1088. X    if (w->slider.show_sign)
  1089. X        (void) sprintf(w->slider.value_in_ascii, " [%+d]",
  1090. X          w->slider.position);
  1091. X    else
  1092. X        (void) sprintf(w->slider.value_in_ascii, " [%d]",
  1093. X          w->slider.position);
  1094. X
  1095. X    XDrawImageString(dpy, window, w->slider.normal_gc,
  1096. X      (int) (w->core.width - w->slider.value_width), w->slider.baseline,
  1097. X      w->slider.value_in_ascii, strlen(w->slider.value_in_ascii));
  1098. X    }
  1099. X}
  1100. X
  1101. X
  1102. Xstatic void SliderDestroy(widget)
  1103. XWidget widget;
  1104. X{
  1105. X    SliderWidget w = (SliderWidget) widget;
  1106. X
  1107. X    XtReleaseGC(widget, w->slider.normal_gc);
  1108. X    XtReleaseGC(widget, w->slider.clear_gc);
  1109. X}
  1110. X
  1111. X
  1112. Xstatic void SliderDrawArrow(widget)
  1113. XWidget widget;
  1114. X{
  1115. X    SliderWidget w = (SliderWidget) widget;
  1116. X    Display *dpy = XtDisplay(w);
  1117. X    Window window = XtWindow(w);
  1118. X    char active_string[1];
  1119. X
  1120. X    /* must convert the arrow/blank char into string for printing */
  1121. X    active_string[0] = w->slider.active ? ARROW : BLANK;
  1122. X
  1123. X    XDrawImageString(dpy, window, w->slider.normal_gc, 0,
  1124. X      w->slider.baseline, active_string, 1);
  1125. X}
  1126. X
  1127. X
  1128. Xstatic void SliderMoveKnob(widget, x)
  1129. XWidget widget;
  1130. XPosition x;
  1131. X{
  1132. X    SliderWidget w = (SliderWidget) widget;
  1133. X    Display *dpy = XtDisplay(w);
  1134. X
  1135. X    x -= w->slider.center_to_left_edge;
  1136. X
  1137. X    if (x < w->slider.min_x)
  1138. X    x = w->slider.min_x;
  1139. X    else if (x > w->slider.max_x)
  1140. X    x = w->slider.max_x;
  1141. X
  1142. X    if (x == w->slider.knob_x)
  1143. X    return;
  1144. X
  1145. X    w->slider.position = x - w->slider.min_x + w->slider.min_value;
  1146. X
  1147. X    /* Erase the old knob */
  1148. X    XDrawImageString(dpy, w->slider.pixmap, w->slider.normal_gc,
  1149. X      w->slider.knob_x, w->slider.baseline, SLOT_STRING, 2);
  1150. X
  1151. X    w->slider.knob_x = x;
  1152. X
  1153. X    /* Draw new knob */
  1154. X    XDrawImageString(dpy, w->slider.pixmap, w->slider.normal_gc,
  1155. X      w->slider.knob_x, w->slider.baseline, KNOB_STRING, 2);
  1156. X
  1157. X    SliderRedisplay(widget, (XEvent *) NULL, (Region) NULL);
  1158. X    XtCallCallbacks(widget, XtNcallback, (XtPointer) (w->slider.position));
  1159. X}
  1160. X
  1161. X
  1162. X/***********************************************************/
  1163. X/******************** Action Procedures ********************/
  1164. X/***********************************************************/
  1165. X
  1166. X
  1167. X/*ARGSUSED*/
  1168. Xstatic void SliderFocusIn(widget, event, params, num_params)
  1169. XWidget widget;
  1170. XXEvent *event;
  1171. XString *params;
  1172. XCardinal *num_params;        /* unused */
  1173. X{
  1174. X    SliderWidget w = (SliderWidget) widget;
  1175. X
  1176. X    if (w->slider.active == False)
  1177. X    {
  1178. X    w->slider.active = True;
  1179. X    SliderDrawArrow(widget);
  1180. X    }
  1181. X}
  1182. X
  1183. X
  1184. X/*ARGSUSED*/
  1185. Xstatic void SliderFocusOut(widget, event, params, num_params)
  1186. XWidget widget;
  1187. XXEvent *event;
  1188. XString *params;
  1189. XCardinal *num_params;        /* unused */
  1190. X{
  1191. X    SliderWidget w = (SliderWidget) widget;
  1192. X
  1193. X    if (w->slider.active == True)
  1194. X    {
  1195. X    w->slider.active = False;
  1196. X    SliderDrawArrow(widget);
  1197. X    }
  1198. X}
  1199. X
  1200. X
  1201. X/*ARGSUSED*/
  1202. Xstatic void SliderMark(widget, event, params, num_params)
  1203. XWidget widget;
  1204. XXEvent *event;
  1205. XString *params;            /* unused */
  1206. XCardinal *num_params;        /* unused */
  1207. X{
  1208. X    SliderWidget w = (SliderWidget) widget;
  1209. X    XButtonEvent *ev = (XButtonEvent *) & event->xbutton;
  1210. X
  1211. X    w->slider.active = True;
  1212. X    DialogSetNewFocus(w->slider.dialogbox, widget);
  1213. X
  1214. X    SliderDrawArrow(widget);
  1215. X
  1216. X    if (IN_SCROLLBAR(w, ev->x, ev->y))
  1217. X    {
  1218. X    w->slider.scrolling = True;
  1219. X    SliderMoveKnob(widget, ev->x);
  1220. X    }
  1221. X    else if (IN_LEFT_ARROW(w, ev->x, ev->y))
  1222. X    SliderMoveKnob(widget, w->slider.knob_x +
  1223. X      w->slider.center_to_left_edge - 1);
  1224. X    else if (IN_RIGHT_ARROW(w, ev->x, ev->y))
  1225. X    SliderMoveKnob(widget, w->slider.knob_x +
  1226. X      w->slider.center_to_left_edge + 1);
  1227. X}
  1228. X
  1229. X
  1230. X/* ARGSUSED */
  1231. Xstatic void SliderGoto(widget, event, params, num_params)
  1232. XWidget widget;
  1233. XXEvent *event;            /* unused */
  1234. XString *params;
  1235. XCardinal *num_params;        /* unused */
  1236. X{
  1237. X    SliderWidget w = (SliderWidget) widget;
  1238. X
  1239. X    switch (params[0][0])
  1240. X    {
  1241. X    case 'P':
  1242. X    DialogSetPrevFocus(w->slider.dialogbox);
  1243. X    break;
  1244. X
  1245. X    case 'N':
  1246. X    DialogSetNextFocus(w->slider.dialogbox);
  1247. X    break;
  1248. X    }
  1249. X
  1250. X    w->slider.active = False;
  1251. X
  1252. X    SliderDrawArrow(widget);
  1253. X}
  1254. X
  1255. X
  1256. X/* ARGSUSED */
  1257. Xstatic void SliderSlide(widget, event, params, num_params)
  1258. XWidget widget;
  1259. XXEvent *event;            /* unused */
  1260. XString *params;
  1261. XCardinal *num_params;        /* unused */
  1262. X{
  1263. X    SliderWidget w = (SliderWidget) widget;
  1264. X
  1265. X    switch (params[0][0])
  1266. X    {
  1267. X    case 'L':
  1268. X    SliderMoveKnob(widget, w->slider.knob_x +
  1269. X      w->slider.center_to_left_edge - 1);
  1270. X    break;
  1271. X
  1272. X    case 'R':
  1273. X    SliderMoveKnob(widget, w->slider.knob_x +
  1274. X      w->slider.center_to_left_edge + 1);
  1275. X    break;
  1276. X    }
  1277. X}
  1278. X
  1279. X
  1280. X/*ARGSUSED*/
  1281. Xstatic void SliderBtnUp(widget, event, params, num_params)
  1282. XWidget widget;
  1283. XXEvent *event;
  1284. XString *params;            /* unused */
  1285. XCardinal *num_params;        /* unused */
  1286. X{
  1287. X    SliderWidget w = (SliderWidget) widget;
  1288. X    XButtonEvent *ev = (XButtonEvent *) & event->xbutton;
  1289. X
  1290. X    if (w->slider.scrolling == False)
  1291. X    return;
  1292. X
  1293. X    w->slider.scrolling = False;
  1294. X    SliderMoveKnob(widget, ev->x);
  1295. X}
  1296. X
  1297. X
  1298. X/*ARGSUSED*/
  1299. Xstatic void SliderLeave(widget, event, params, num_params)
  1300. XWidget widget;
  1301. XXEvent *event;
  1302. XString *params;            /* unused */
  1303. XCardinal *num_params;        /* unused */
  1304. X{
  1305. X    SliderWidget w = (SliderWidget) widget;
  1306. X    XCrossingEvent *ev = (XCrossingEvent *) & event->xcrossing;
  1307. X
  1308. X    if (w->slider.scrolling == False)
  1309. X    return;
  1310. X
  1311. X    w->slider.scrolling = False;
  1312. X    SliderMoveKnob(widget, ev->x);
  1313. X}
  1314. X
  1315. X
  1316. X/*ARGSUSED*/
  1317. Xstatic void SliderMotion(widget, event, params, num_params)
  1318. XWidget widget;
  1319. XXEvent *event;
  1320. XString *params;            /* unused */
  1321. XCardinal *num_params;        /* unused */
  1322. X{
  1323. X    SliderWidget w = (SliderWidget) widget;
  1324. X    Display *dpy = XtDisplay(w);
  1325. X    Window window = XtWindow(w);
  1326. X    XMotionEvent *ev = (XMotionEvent *) & event->xmotion;
  1327. X
  1328. X    /* Always skip ahead to the latest ButtonMotionEvent in the queue */
  1329. X    /* SUPPRESS 530 */
  1330. X    while (XCheckWindowEvent(dpy, window, ButtonMotionMask, ev));
  1331. X
  1332. X    if (w->slider.scrolling == False)
  1333. X    return;
  1334. X
  1335. X    SliderMoveKnob(widget, ev->x);
  1336. X}
  1337. X
  1338. X
  1339. X/***********************************************************/
  1340. X/******************** Public Procedures ********************/
  1341. X/***********************************************************/
  1342. X
  1343. Xvoid SliderChangePosition(widget, value)
  1344. XWidget widget;
  1345. Xint value;
  1346. X{
  1347. X    SliderWidget w = (SliderWidget) widget;
  1348. X    Display *dpy = XtDisplay(w);
  1349. X    int x;
  1350. X
  1351. X    if (value > w->slider.max_value)
  1352. X    value = w->slider.max_value;
  1353. X
  1354. X    if (value < w->slider.min_value)
  1355. X    value = w->slider.min_value;
  1356. X
  1357. X    w->slider.position = value;
  1358. X
  1359. X    x = w->slider.position + w->slider.min_x - w->slider.min_value;
  1360. X
  1361. X    if (x == w->slider.knob_x)
  1362. X    return;
  1363. X
  1364. X    if (XtIsRealized(widget) == False)
  1365. X    {
  1366. X    w->slider.knob_x = x;
  1367. X    return;
  1368. X    }
  1369. X
  1370. X    /* Erase the old knob */
  1371. X    XDrawImageString(dpy, w->slider.pixmap, w->slider.normal_gc,
  1372. X      w->slider.knob_x, w->slider.baseline, SLOT_STRING, 2);
  1373. X
  1374. X    w->slider.knob_x = x;
  1375. X
  1376. X    /* Draw new knob */
  1377. X    XDrawImageString(dpy, w->slider.pixmap, w->slider.normal_gc,
  1378. X      w->slider.knob_x, w->slider.baseline, KNOB_STRING, 2);
  1379. X
  1380. X    SliderRedisplay(widget, (XEvent *) NULL, (Region) NULL);
  1381. X}
  1382. END_OF_FILE
  1383. if test 16605 -ne `wc -c <'widgets/Slider.c'`; then
  1384.     echo shar: \"'widgets/Slider.c'\" unpacked with wrong size!
  1385. fi
  1386. # end of 'widgets/Slider.c'
  1387. fi
  1388. if test -f 'widgets/Text.c' -a "${1}" != "-c" ; then 
  1389.   echo shar: Will not clobber existing file \"'widgets/Text.c'\"
  1390. else
  1391. echo shar: Extracting \"'widgets/Text.c'\" \(16216 characters\)
  1392. sed "s/^X//" >'widgets/Text.c' <<'END_OF_FILE'
  1393. X/*
  1394. X * Copyright (c) Ken W. Marks 1989, 1990.
  1395. X */
  1396. X
  1397. X#include <stdio.h>
  1398. X#include <ctype.h>
  1399. X#include <X11/Intrinsic.h>
  1400. X#include <X11/StringDefs.h>
  1401. X#include <Chaos.h>
  1402. X#include <LocalDefs.h>
  1403. X#include <TextP.h>
  1404. X#include <DlgShell.h>
  1405. X
  1406. X/* Default number of characters wide for widget */
  1407. X#define DEFAULT_WIDTH        20
  1408. X
  1409. X#define CARET_CURSOR        "\001"
  1410. X#define BAR_CURSOR        "\002"
  1411. X
  1412. X#define ARROW            '\037'
  1413. X#define BLANK            '\036'
  1414. X
  1415. Xstatic void TextInitialize();
  1416. Xstatic void TextResize();
  1417. Xstatic void TextRedisplay();
  1418. Xstatic void TextDestroy();
  1419. Xstatic void TextMark();
  1420. Xstatic void TextGoto();
  1421. Xstatic void TextFocusIn();
  1422. Xstatic void TextFocusOut();
  1423. X
  1424. Xstatic void TextDeleteNextChar();
  1425. Xstatic void TextDeletePreviousChar();
  1426. Xstatic void TextDeleteNextAll();
  1427. Xstatic void TextDeletePreviousAll();
  1428. Xstatic void TextMoveLeft();
  1429. Xstatic void TextMoveRight();
  1430. Xstatic void TextMoveStart();
  1431. Xstatic void TextMoveEnd();
  1432. Xstatic void TextInsertChar();
  1433. X
  1434. X#define offset(field) XtOffset(TextWidget, text.field)
  1435. Xstatic XtResource text_resources[] = {
  1436. X    {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
  1437. X    offset(foreground), XtRString, "XtDefaultForeground"},
  1438. X    {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  1439. X    offset(font), XtRString, "chaos-bold"},
  1440. X    {XtNbuffer, XtCBuffer, XtRString, sizeof(String),
  1441. X    offset(buffer), XtRString, NULL},
  1442. X    {XtNbufferLen, XtCLength, XtRInt, sizeof(int),
  1443. X    offset(buffer_len), XtRImmediate, (caddr_t) 0},
  1444. X    {XtNcharsWide, XtCLength, XtRInt, sizeof(int),
  1445. X    offset(width_in_chars), XtRImmediate, (caddr_t) DEFAULT_WIDTH},
  1446. X    {XtNinitialText, XtCText, XtRString, sizeof(String),
  1447. X    offset(initial_text), XtRString, NULL},
  1448. X    {XtNdialogbox, XtCWidget, XtRWidget, sizeof(Widget),
  1449. X    offset(dialogbox), XtRWidget, (caddr_t) NULL},
  1450. X};
  1451. X
  1452. Xstatic XtActionsRec text_actions[] =
  1453. X{
  1454. X    {"mark", TextMark},
  1455. X    {"goto", TextGoto},
  1456. X    {"focus_in", TextFocusIn},
  1457. X    {"focus_out", TextFocusOut},
  1458. X    {"delete-next-character", TextDeleteNextChar},
  1459. X    {"delete-previous-character", TextDeletePreviousChar},
  1460. X    {"delete-next-all", TextDeleteNextAll},
  1461. X    {"delete-previous-all", TextDeletePreviousAll},
  1462. X    {"move-left", TextMoveLeft},
  1463. X    {"move-right", TextMoveRight},
  1464. X    {"move-start", TextMoveStart},
  1465. X    {"move-end", TextMoveEnd},
  1466. X    {"insert-char", TextInsertChar},
  1467. X};
  1468. X
  1469. X#define superclass        (&simpleClassRec)
  1470. X
  1471. Xstatic char text_translations[] =
  1472. X"<BtnDown>:        mark()\n\
  1473. X Shift<Key>Tab:        goto(PREV)\n\
  1474. X <Key>Tab:        goto(NEXT)\n\
  1475. X <FocusIn>:        focus_in()\n\
  1476. X <FocusOut>:        focus_out()\n\
  1477. X Ctrl<Key>D:        delete-next-character()\n\
  1478. X <Key>BackSpace:    delete-previous-character()\n\
  1479. X <Key>Delete:        delete-previous-character()\n\
  1480. X Ctrl<Key>K:        delete-next-all()\n\
  1481. X Ctrl<Key>U:        delete-previous-all()\n\
  1482. X <Key>Left:        move-left()\n\
  1483. X Ctrl<Key>B:        move-left()\n\
  1484. X <Key>Right:        move-right()\n\
  1485. X Ctrl<Key>F:        move-right()\n\
  1486. X Shift<Key>Left:    move-start()\n\
  1487. X Ctrl<Key>A:        move-start()\n\
  1488. X Shift<Key>Right:    move-end()\n\
  1489. X Ctrl<Key>E:        move-end()\n\
  1490. X <Key>:            insert-char()\n\
  1491. X";
  1492. X
  1493. XTextClassRec textClassRec = {
  1494. X    {
  1495. X    /* core fields          */
  1496. X     /* superclass         */ (WidgetClass) superclass,
  1497. X     /* class_name         */ "Text",
  1498. X     /* widget_size         */ sizeof(TextRec),
  1499. X     /* class_initialize     */ NULL,
  1500. X     /* class_part_initialize */ NULL,
  1501. X     /* class_inited     */ FALSE,
  1502. X     /* initialize         */ TextInitialize,
  1503. X     /* initialize_hook     */ NULL,
  1504. X     /* realize         */ XtInheritRealize,
  1505. X     /* actions         */ text_actions,
  1506. X     /* num_actions         */ XtNumber(text_actions),
  1507. X     /* resources         */ text_resources,
  1508. X     /* resource_count     */ XtNumber(text_resources),
  1509. X     /* xrm_class         */ NULLQUARK,
  1510. X     /* compress_motion     */ TRUE,
  1511. X     /* compress_exposure     */ TRUE,
  1512. X     /* compress_enterleave     */ TRUE,
  1513. X     /* visible_interest     */ FALSE,
  1514. X     /* destroy         */ TextDestroy,
  1515. X     /* resize         */ TextResize,
  1516. X     /* expose         */ TextRedisplay,
  1517. X     /* set_values         */ NULL,
  1518. X     /* set_values_hook     */ NULL,
  1519. X     /* set_values_almost     */ XtInheritSetValuesAlmost,
  1520. X     /* get_values_hook     */ NULL,
  1521. X     /* accept_focus     */ NULL,
  1522. X     /* version         */ XtVersion,
  1523. X     /* callback_private     */ NULL,
  1524. X     /* tm_table         */ text_translations,
  1525. X     /* query_geometry       */ NULL,
  1526. X     /* display_accelerator     */ XtInheritDisplayAccelerator,
  1527. X     /* extension         */ NULL
  1528. X    },
  1529. X    {
  1530. X    /* Simple class fields initialization */
  1531. X     /* change_sensitive     */ XtInheritChangeSensitive
  1532. X    }
  1533. X};
  1534. X
  1535. XWidgetClass textWidgetClass = (WidgetClass) & textClassRec;
  1536. X
  1537. X
  1538. X/************************************************************/
  1539. X/******************** Private Procedures ********************/
  1540. X/************************************************************/
  1541. X
  1542. X
  1543. Xstatic void TextGetGC(w)
  1544. XTextWidget w;
  1545. X{
  1546. X    XGCValues values;
  1547. X
  1548. X    values.foreground = w->text.foreground;
  1549. X    values.background = w->core.background_pixel;
  1550. X    values.font = w->text.font->fid;
  1551. X
  1552. X    w->text.normal_gc = XtGetGC((Widget) w, (unsigned) GCForeground |
  1553. X      GCBackground | GCFont, &values);
  1554. X}
  1555. X
  1556. X
  1557. Xstatic void TextSetSize(w)
  1558. XTextWidget w;
  1559. X{
  1560. X    XtWidgetGeometry my_request;
  1561. X    XFontStruct *fs = w->text.font;
  1562. X    int width;
  1563. X
  1564. X    width = fs->max_bounds.width;
  1565. X    w->text.baseline = fs->max_bounds.ascent;
  1566. X    w->text.char_width = width;
  1567. X    w->text.text_offset = width / 2;
  1568. X
  1569. X    /* Width is based on (width_in_chars + 2) characters to account for the
  1570. X     * arrow character and a half character's width worth of spacing at either
  1571. X     * end. */
  1572. X
  1573. X    my_request.request_mode = CWWidth | CWHeight | CWBorderWidth;
  1574. X    my_request.width = (w->text.width_in_chars + 2) * w->text.char_width;
  1575. X    my_request.height = fs->max_bounds.ascent + fs->max_bounds.descent;
  1576. X    my_request.border_width = 1;
  1577. X
  1578. X    XtMakeGeometryRequest((Widget) w, &my_request, NULL);
  1579. X}
  1580. X
  1581. X
  1582. X/* ARGSUSED */
  1583. Xstatic void TextInitialize(request, new)
  1584. XWidget request;
  1585. XWidget new;
  1586. X{
  1587. X    TextWidget w = (TextWidget) new;
  1588. X
  1589. X    if (w->text.dialogbox == NULL)
  1590. X    {
  1591. X    eprintf("XtNdialogbox not set\n");
  1592. X    abort();
  1593. X    }
  1594. X
  1595. X    if (w->text.buffer == NULL)
  1596. X    {
  1597. X    eprintf("NULL buffer specified\n");
  1598. X    abort();
  1599. X    }
  1600. X
  1601. X    if (w->text.buffer_len == 0)
  1602. X    {
  1603. X    eprintf("Zero buffer length specified\n");
  1604. X    abort();
  1605. X    }
  1606. X
  1607. X    w->text.displayed_text = malloc((unsigned) (w->text.width_in_chars + 3));
  1608. X
  1609. X    /* The string displayed_text always has a space in the last character */
  1610. X    w->text.displayed_text[w->text.width_in_chars + 2] = BLANK;
  1611. X
  1612. X    w->text.text_len = STRLEN(w->text.initial_text);
  1613. X    w->text.text_len = MIN(w->text.text_len, w->text.buffer_len - 1);
  1614. X
  1615. X    if (w->text.text_len != 0)
  1616. X    {
  1617. X    (void) memcpy(w->text.buffer, w->text.initial_text,
  1618. X      w->text.text_len);
  1619. X    w->text.buffer[w->text.text_len] = 0;
  1620. X    }
  1621. X
  1622. X    w->text.cursor_position = w->text.text_len;
  1623. X    w->text.active = False;
  1624. X    w->text.first_char = MAX(0, w->text.text_len - w->text.width_in_chars);
  1625. X
  1626. X    TextGetGC(w);
  1627. X    (*XtClass(new)->core_class.resize) ((Widget) w);
  1628. X}
  1629. X
  1630. X
  1631. X/* ARGSUSED */
  1632. Xstatic void TextRedisplay(widget, event, region)
  1633. XWidget widget;
  1634. XXEvent *event;
  1635. XRegion region;
  1636. X{
  1637. X    TextWidget w = (TextWidget) widget;
  1638. X    int length;
  1639. X
  1640. X    if (XtIsRealized(widget) == False)
  1641. X    return;
  1642. X
  1643. X    length = MIN(w->text.text_len, w->text.width_in_chars);
  1644. X
  1645. X    if (w->text.active)
  1646. X    w->text.displayed_text[0] = ARROW;
  1647. X    else
  1648. X    w->text.displayed_text[0] = BLANK;
  1649. X
  1650. X    (void) memcpy(&(w->text.displayed_text[1]),
  1651. X      &(w->text.buffer[w->text.first_char]), length);
  1652. X
  1653. X    if (length < w->text.width_in_chars)
  1654. X    (void) memset(&(w->text.displayed_text[length + 1]), BLANK,
  1655. X      w->text.width_in_chars - length);
  1656. X
  1657. X    /* Draw text (with a trailing space to pick up EOL cursor droppings) */
  1658. X    XDrawImageString(XtDisplay(w), XtWindow(w), w->text.normal_gc,
  1659. X      w->text.text_offset, w->text.baseline, w->text.displayed_text,
  1660. X      w->text.width_in_chars + 2);
  1661. X
  1662. X    /* Draw cursor */
  1663. X    XDrawString(XtDisplay(w), XtWindow(w), w->text.normal_gc,
  1664. X      (int) (w->text.char_width * (w->text.cursor_position -
  1665. X      w->text.first_char + 1)), w->text.baseline, BAR_CURSOR, 1);
  1666. X}
  1667. X
  1668. X
  1669. Xstatic void TextResize(widget)
  1670. XWidget widget;
  1671. X{
  1672. X    TextSetSize((TextWidget) widget);
  1673. X}
  1674. X
  1675. X
  1676. Xstatic void TextDestroy(widget)
  1677. XWidget widget;
  1678. X{
  1679. X    TextWidget w = (TextWidget) widget;
  1680. X
  1681. X    XtReleaseGC(widget, w->text.normal_gc);
  1682. X}
  1683. X
  1684. X
  1685. X/***********************************************************/
  1686. X/******************** Action Procedures ********************/
  1687. X/***********************************************************/
  1688. X
  1689. X
  1690. X/* ARGSUSED */
  1691. Xstatic void TextMark(widget, event, params, num_params)
  1692. XWidget widget;
  1693. XXEvent *event;            /* unused */
  1694. XString *params;            /* unused */
  1695. XCardinal *num_params;        /* unused */
  1696. X{
  1697. X    TextWidget w = (TextWidget) widget;
  1698. X    XButtonEvent *ev = (XButtonEvent *) & event->xbutton;
  1699. X
  1700. X    int position;
  1701. X
  1702. X    w->text.active = True;
  1703. X
  1704. X    position = (ev->x) / w->text.char_width - 1;
  1705. X    position = MAX(position, 0);
  1706. X    position = MIN(position, w->text.text_len);
  1707. X
  1708. X    w->text.cursor_position = position + w->text.first_char;
  1709. X
  1710. X    TextRedisplay(widget, (XEvent *) NULL, (Region) NULL);
  1711. X    DialogSetNewFocus(w->text.dialogbox, widget);
  1712. X}
  1713. X
  1714. X
  1715. X/* ARGSUSED */
  1716. Xstatic void TextGoto(widget, event, params, num_params)
  1717. XWidget widget;
  1718. XXEvent *event;            /* unused */
  1719. XString *params;            /* unused */
  1720. XCardinal *num_params;        /* unused */
  1721. X{
  1722. X    TextWidget w = (TextWidget) widget;
  1723. X
  1724. X    switch (params[0][0])
  1725. X    {
  1726. X    case 'P':
  1727. X    DialogSetPrevFocus(w->text.dialogbox);
  1728. X    break;
  1729. X
  1730. X    case 'N':
  1731. X    DialogSetNextFocus(w->text.dialogbox);
  1732. X    break;
  1733. X    }
  1734. X
  1735. X    w->text.active = False;
  1736. X
  1737. X    TextRedisplay(widget, (XEvent *) NULL, (Region) NULL);
  1738. X}
  1739. X
  1740. X
  1741. X/*ARGSUSED*/
  1742. Xstatic void TextFocusIn(widget, event, params, num_params)
  1743. XWidget widget;
  1744. XXEvent *event;
  1745. XString *params;            /* unused */
  1746. XCardinal *num_params;        /* unused */
  1747. X{
  1748. X    TextWidget w = (TextWidget) widget;
  1749. X
  1750. X    if (w->text.active == False)
  1751. X    {
  1752. X    w->text.active = True;
  1753. X    TextRedisplay(widget, (XEvent *) NULL, (Region) NULL);
  1754. X    }
  1755. X}
  1756. X
  1757. X
  1758. X/*ARGSUSED*/
  1759. Xstatic void TextFocusOut(widget, event, params, num_params)
  1760. XWidget widget;
  1761. XXEvent *event;
  1762. XString *params;            /* unused */
  1763. XCardinal *num_params;        /* unused */
  1764. X{
  1765. X    TextWidget w = (TextWidget) widget;
  1766. X
  1767. X    if (w->text.active == True)
  1768. X    {
  1769. X    w->text.active = False;
  1770. X    TextRedisplay(widget, (XEvent *) NULL, (Region) NULL);
  1771. X    }
  1772. X}
  1773. X
  1774. X
  1775. X/* ARGSUSED */
  1776. Xstatic void TextDeleteNextChar(widget, event, params, num_params)
  1777. XWidget widget;
  1778. XXEvent *event;            /* unused */
  1779. XString *params;            /* unused */
  1780. XCardinal *num_params;        /* unused */
  1781. X{
  1782. X    TextWidget w = (TextWidget) widget;
  1783. X
  1784. X    if (w->text.cursor_position >= w->text.text_len)
  1785. X    return;
  1786. X
  1787. X    (void) memcpy(&(w->text.buffer[w->text.cursor_position]),
  1788. X      &(w->text.buffer[w->text.cursor_position + 1]),
  1789. X      w->text.text_len - w->text.cursor_position);
  1790. X
  1791. X    --w->text.text_len;
  1792. X
  1793. X    w->text.first_char = MIN(w->text.first_char, MAX(w->text.text_len -
  1794. X    w->text.width_in_chars, 0));
  1795. X
  1796. X    (*XtClass(widget)->core_class.expose) (widget, NULL, NULL);
  1797. X}
  1798. X
  1799. X
  1800. X/* ARGSUSED */
  1801. Xstatic void TextDeletePreviousChar(widget, event, params, num_params)
  1802. XWidget widget;
  1803. XXEvent *event;            /* unused */
  1804. XString *params;            /* unused */
  1805. XCardinal *num_params;        /* unused */
  1806. X{
  1807. X    TextWidget w = (TextWidget) widget;
  1808. X
  1809. X    if (w->text.cursor_position == 0)
  1810. X    return;
  1811. X
  1812. X    (void) memcpy(&(w->text.buffer[w->text.cursor_position - 1]),
  1813. X      &(w->text.buffer[w->text.cursor_position]),
  1814. X      w->text.text_len - w->text.cursor_position + 1);
  1815. X
  1816. X    --w->text.text_len;
  1817. X    --w->text.cursor_position;
  1818. X
  1819. X    w->text.first_char = MIN(w->text.first_char, MAX(w->text.text_len -
  1820. X    w->text.width_in_chars, 0));
  1821. X
  1822. X    (*XtClass(widget)->core_class.expose) (widget, NULL, NULL);
  1823. X}
  1824. X
  1825. X
  1826. X/* ARGSUSED */
  1827. Xstatic void TextDeleteNextAll(widget, event, params, num_params)
  1828. XWidget widget;
  1829. XXEvent *event;            /* unused */
  1830. XString *params;            /* unused */
  1831. XCardinal *num_params;        /* unused */
  1832. X{
  1833. X    TextWidget w = (TextWidget) widget;
  1834. X
  1835. X    w->text.text_len = w->text.cursor_position;
  1836. X    w->text.buffer[w->text.text_len] = 0;
  1837. X    w->text.first_char = MAX(0, w->text.text_len - w->text.width_in_chars);
  1838. X
  1839. X    (*XtClass(widget)->core_class.expose) (widget, NULL, NULL);
  1840. X}
  1841. X
  1842. X
  1843. X/* ARGSUSED */
  1844. Xstatic void TextDeletePreviousAll(widget, event, params, num_params)
  1845. XWidget widget;
  1846. XXEvent *event;            /* unused */
  1847. XString *params;            /* unused */
  1848. XCardinal *num_params;        /* unused */
  1849. X{
  1850. X    TextWidget w = (TextWidget) widget;
  1851. X
  1852. X    if (w->text.cursor_position == 0)
  1853. X    return;
  1854. X
  1855. X    (void) memcpy(w->text.buffer, &(w->text.buffer[w->text.cursor_position]),
  1856. X      w->text.text_len - w->text.cursor_position + 1);
  1857. X
  1858. X    w->text.text_len -= w->text.cursor_position;
  1859. X    w->text.cursor_position = 0;
  1860. X    w->text.first_char = 0;
  1861. X
  1862. X    (*XtClass(widget)->core_class.expose) (widget, NULL, NULL);
  1863. X}
  1864. X
  1865. X
  1866. X/* ARGSUSED */
  1867. Xstatic void TextMoveLeft(widget, event, params, num_params)
  1868. XWidget widget;
  1869. XXEvent *event;            /* unused */
  1870. XString *params;            /* unused */
  1871. XCardinal *num_params;        /* unused */
  1872. X{
  1873. X    TextWidget w = (TextWidget) widget;
  1874. X
  1875. X    if (w->text.cursor_position == 0)
  1876. X    return;
  1877. X
  1878. X    --w->text.cursor_position;
  1879. X
  1880. X    w->text.first_char = MIN(w->text.first_char, w->text.cursor_position);
  1881. X
  1882. X    (*XtClass(widget)->core_class.expose) (widget, NULL, NULL);
  1883. X}
  1884. X
  1885. X
  1886. X/* ARGSUSED */
  1887. Xstatic void TextMoveRight(widget, event, params, num_params)
  1888. XWidget widget;
  1889. XXEvent *event;            /* unused */
  1890. XString *params;            /* unused */
  1891. XCardinal *num_params;        /* unused */
  1892. X{
  1893. X    TextWidget w = (TextWidget) widget;
  1894. X
  1895. X    if (w->text.cursor_position >= w->text.text_len)
  1896. X    return;
  1897. X
  1898. X    ++w->text.cursor_position;
  1899. X
  1900. X    w->text.first_char = MAX(w->text.first_char, w->text.cursor_position -
  1901. X      w->text.width_in_chars);
  1902. X
  1903. X    (*XtClass(widget)->core_class.expose) (widget, NULL, NULL);
  1904. X}
  1905. X
  1906. X
  1907. X/* ARGSUSED */
  1908. Xstatic void TextMoveStart(widget, event, params, num_params)
  1909. XWidget widget;
  1910. XXEvent *event;            /* unused */
  1911. XString *params;            /* unused */
  1912. XCardinal *num_params;        /* unused */
  1913. X{
  1914. X    TextWidget w = (TextWidget) widget;
  1915. X
  1916. X    if (w->text.cursor_position == 0)
  1917. X    return;
  1918. X
  1919. X    w->text.cursor_position = 0;
  1920. X    w->text.first_char = 0;
  1921. X
  1922. X    (*XtClass(widget)->core_class.expose) (widget, NULL, NULL);
  1923. X}
  1924. X
  1925. X
  1926. X/* ARGSUSED */
  1927. Xstatic void TextMoveEnd(widget, event, params, num_params)
  1928. XWidget widget;
  1929. XXEvent *event;            /* unused */
  1930. XString *params;            /* unused */
  1931. XCardinal *num_params;        /* unused */
  1932. X{
  1933. X    TextWidget w = (TextWidget) widget;
  1934. X
  1935. X    if (w->text.cursor_position >= w->text.text_len)
  1936. X    return;
  1937. X
  1938. X    w->text.cursor_position = w->text.text_len;
  1939. X
  1940. X    w->text.first_char = MAX(0, w->text.text_len - w->text.width_in_chars);
  1941. X
  1942. X    (*XtClass(widget)->core_class.expose) (widget, NULL, NULL);
  1943. X}
  1944. X
  1945. X
  1946. X/* ARGSUSED */
  1947. Xstatic void TextInsertChar(widget, event, params, num_params)
  1948. XWidget widget;
  1949. XXEvent *event;
  1950. XString *params;            /* unused */
  1951. XCardinal *num_params;        /* unused */
  1952. X{
  1953. X    char buffer[64];
  1954. X    TextWidget w = (TextWidget) widget;
  1955. X    KeySym keysym;
  1956. X    int length;
  1957. X
  1958. X    length = XLookupString(&(event->xkey), buffer, 64, &keysym, NULL);
  1959. X    if (length == 0 || !isprint(buffer[0]))
  1960. X    return;
  1961. X
  1962. X    if (w->text.text_len + length < w->text.buffer_len)
  1963. X    {
  1964. X    {
  1965. X        /* move any following text to the right. we do this manually since
  1966. X         * memcpy() is too stupid to deal with overlapping regions. */
  1967. X
  1968. X        int ii = w->text.text_len - w->text.cursor_position + 1;
  1969. X        char *from = &(w->text.buffer[w->text.text_len]);
  1970. X        char *to = &(w->text.buffer[w->text.text_len + length]);
  1971. X
  1972. X        while (ii-- > 0)
  1973. X        *(to--) = *(from--);
  1974. X    }
  1975. X
  1976. X    if (length == 1)
  1977. X        w->text.buffer[w->text.cursor_position] = buffer[0];
  1978. X    else
  1979. X        (void) memcpy(&(w->text.buffer[w->text.cursor_position]), buffer,
  1980. X          length);
  1981. X
  1982. X    w->text.text_len += length;
  1983. X    w->text.cursor_position += length;
  1984. X    }
  1985. X    else
  1986. X    XBell(XtDisplay(w), 0);
  1987. X
  1988. X    w->text.first_char = MAX(w->text.first_char, w->text.cursor_position -
  1989. X      w->text.width_in_chars);
  1990. X
  1991. X    (*XtClass(widget)->core_class.expose) (widget, NULL, NULL);
  1992. X}
  1993. X
  1994. X
  1995. X/***********************************************************/
  1996. X/******************** Public Procedures ********************/
  1997. X/***********************************************************/
  1998. X
  1999. Xvoid TextChangeText(widget, text)
  2000. XWidget widget;
  2001. XString text;
  2002. X{
  2003. X    TextWidget w = (TextWidget) widget;
  2004. X
  2005. X    if (text == NULL)
  2006. X    w->text.buffer[0] = 0;
  2007. X    else
  2008. X    (void) strcpy(w->text.buffer, text);
  2009. X
  2010. X    w->text.text_len = STRLEN(w->text.buffer);
  2011. X    w->text.cursor_position = w->text.text_len;
  2012. X    w->text.first_char = MAX(0, w->text.text_len - w->text.width_in_chars);
  2013. X
  2014. X    (*XtClass(widget)->core_class.expose) (widget, NULL, NULL);
  2015. X}
  2016. END_OF_FILE
  2017. if test 16216 -ne `wc -c <'widgets/Text.c'`; then
  2018.     echo shar: \"'widgets/Text.c'\" unpacked with wrong size!
  2019. fi
  2020. # end of 'widgets/Text.c'
  2021. fi
  2022. echo shar: End of archive 5 \(of 10\).
  2023. cp /dev/null ark5isdone
  2024. MISSING=""
  2025. for I in 1 2 3 4 5 6 7 8 9 10 ; do
  2026.     if test ! -f ark${I}isdone ; then
  2027.     MISSING="${MISSING} ${I}"
  2028.     fi
  2029. done
  2030. if test "${MISSING}" = "" ; then
  2031.     echo You have unpacked all 10 archives.
  2032.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2033. else
  2034.     echo You still need to unpack the following archives:
  2035.     echo "        " ${MISSING}
  2036. fi
  2037. ##  End of shell archive.
  2038. exit 0
  2039.  
  2040. dan
  2041. ----------------------------------------------------
  2042. O'Reilly && Associates   argv@sun.com / argv@ora.com
  2043. Opinions expressed reflect those of the author only.
  2044.