home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume5 / xview.demos / part02 < prev    next >
Text File  |  1989-12-07  |  57KB  |  1,758 lines

  1. Path: uunet!island!sun.com
  2. From: argv@sun.com (Dan Heller)
  3. Newsgroups: comp.sources.x
  4. Subject: v05i040: XView example programs, Part02/06
  5. Message-ID: <1240@island.uu.net>
  6. Date: 8 Dec 89 07:37:51 GMT
  7. Sender: argv@island.uu.net
  8. Lines: 1747
  9. Approved: island!argv@sun.com
  10.  
  11. Submitted-by: Dan Heller <argv@sun.com>
  12. Posting-number: Volume 5, Issue 40
  13. Archive-name: xview.demos/part02
  14.  
  15.  
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  22. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  23. # If this archive is complete, you will see the following message at the end:
  24. #        "End of archive 2 (of 6)."
  25. # Contents:  xview.demos/canvas/canvas_input.c
  26. #   xview.demos/canvas/scroll_view.c xview.demos/canvas/split_views.c
  27. #   xview.demos/color/x_draw.c xview.demos/menus/menu_dir2.c
  28. #   xview.demos/menus/pin_menu.c xview.demos/seln_svc/long_seln.c
  29. #   xview.demos/seln_svc/seln.c
  30. # Wrapped by argv@island on Thu Dec  7 23:18:16 1989
  31. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  32. if test -f 'xview.demos/canvas/canvas_input.c' -a "${1}" != "-c" ; then 
  33.   echo shar: Will not clobber existing file \"'xview.demos/canvas/canvas_input.c'\"
  34. else
  35. echo shar: Extracting \"'xview.demos/canvas/canvas_input.c'\" \(7680 characters\)
  36. sed "s/^X//" >'xview.demos/canvas/canvas_input.c' <<'END_OF_FILE'
  37. X/*
  38. X * canvas_input.c --
  39. X * Display a canvas whose views may be split repeatedly.  The event
  40. X * handler is installed for each view, so events are displayed in
  41. X * each paint window.
  42. X */
  43. X#include <xview/xview.h>
  44. X#include <xview/canvas.h>
  45. X#include <xview/scrollbar.h>
  46. X#include <xview/xv_xrect.h>
  47. X
  48. XCanvas  canvas;
  49. XFrame   frame;
  50. Xchar    msg[128];
  51. Xvoid    init_split(), my_event_proc(), my_repaint_proc();
  52. X
  53. Xmain(argc,argv)
  54. Xint     argc;
  55. Xchar    *argv[];
  56. X{
  57. X    /*
  58. X     * Initialize, create base frame (with footers) and create canvas.
  59. X     */
  60. X    xv_init(XV_INIT_ARGS, argc, argv, NULL);
  61. X    frame = (Frame)xv_create(NULL,FRAME,
  62. X        FRAME_LABEL,            "Split View Windows.",
  63. X        FRAME_SHOW_FOOTER,      TRUE,
  64. X        NULL);
  65. X    canvas = (Canvas)xv_create(frame,CANVAS,
  66. X        CANVAS_X_PAINT_WINDOW,  TRUE,
  67. X        OPENWIN_SPLIT,
  68. X            OPENWIN_SPLIT_INIT_PROC,    init_split,
  69. X            NULL,
  70. X        CANVAS_REPAINT_PROC,    my_repaint_proc,
  71. X        NULL);
  72. X
  73. X    (void) xv_create(canvas, SCROLLBAR,
  74. X        SCROLLBAR_SPLITTABLE,   TRUE,
  75. X        SCROLLBAR_DIRECTION,    SCROLLBAR_VERTICAL,
  76. X        NULL);
  77. X    (void) xv_create(canvas, SCROLLBAR,
  78. X        SCROLLBAR_SPLITTABLE,   TRUE,
  79. X        SCROLLBAR_DIRECTION,    SCROLLBAR_HORIZONTAL,
  80. X        NULL);
  81. X
  82. X    /*
  83. X     *  Set input mask
  84. X     */
  85. X    xv_set(canvas_paint_window(canvas),
  86. X        WIN_CONSUME_EVENTS,
  87. X            WIN_NO_EVENTS, WIN_ASCII_EVENTS, KBD_USE, KBD_DONE,
  88. X            LOC_DRAG, LOC_WINENTER, LOC_WINEXIT, WIN_MOUSE_BUTTONS,
  89. X            NULL,
  90. X        WIN_EVENT_PROC, my_event_proc,
  91. X        NULL);
  92. X
  93. X    xv_main_loop(frame);
  94. X}
  95. X
  96. X/*
  97. X * when a viewport is split, this routine is called.
  98. X */
  99. Xvoid
  100. Xinit_split(splitview, newview, pos)
  101. XXv_Window splitview, newview;
  102. Xint pos;
  103. X{
  104. X    Xv_Window   view;
  105. X    int         i = 0;
  106. X
  107. X    /*
  108. X     * Determine view # from the new view and set its scrollbar to 0,0
  109. X     */
  110. X    OPENWIN_EACH_VIEW(canvas, view)
  111. X        if (view == splitview) {
  112. X            /* identify the view # of the view the user just split. */
  113. X            sprintf(msg, "Split view #%d", i+1);
  114. X            xv_set(frame, FRAME_LEFT_FOOTER, msg, NULL);
  115. X        } else if (view == newview) {
  116. X            xv_set(xv_get(canvas, OPENWIN_VERTICAL_SCROLLBAR, view),
  117. X                SCROLLBAR_VIEW_START, 0,
  118. X                NULL);
  119. X            xv_set(xv_get(canvas, OPENWIN_HORIZONTAL_SCROLLBAR, view),
  120. X                SCROLLBAR_VIEW_START, 0,
  121. X                NULL);
  122. X        }
  123. X        i++;
  124. X    OPENWIN_END_EACH
  125. X    sprintf(msg, "Total views: %d", i);
  126. X    xv_set(frame, FRAME_RIGHT_FOOTER, msg, NULL);
  127. X}
  128. X
  129. X/*
  130. X * Called when an event is received in an arbitrary paint window.
  131. X */
  132. Xvoid
  133. Xmy_event_proc(window, event, arg)
  134. XXv_Window       window;
  135. XEvent           *event;
  136. XNotify_arg      arg;
  137. X{
  138. X    register char *p = msg;
  139. X
  140. X    *p = 0;
  141. X
  142. X    /* test to see if a function key has been hit */
  143. X    if (event_is_key_left(event))
  144. X        sprintf(p, "(L%d) ", event_id(event) - KEY_LEFTFIRST + 1);
  145. X    else if (event_is_key_top(event))
  146. X        sprintf(p, "(T%d) ", event_id(event) - KEY_TOPFIRST + 1);
  147. X    else if (event_is_key_right(event))
  148. X        sprintf(p, "(R%d) ", event_id(event) - KEY_RIGHTFIRST + 1);
  149. X    else if (event_id(event) == KEY_BOTTOMLEFT)
  150. X        strcpy(p, "bottom left ");
  151. X    else if (event_id(event) == KEY_BOTTOMRIGHT)
  152. X        strcpy(p, "bottom right ");
  153. X    p += strlen(p);
  154. X
  155. X
  156. X    if (event_is_ascii(event)) {
  157. X        /*
  158. X         * note that shift modifier is reflected in the event code by
  159. X         * virtue of the char printed is upper/lower case.
  160. X         */
  161. X        sprintf(p, "Keyboard: key '%c' (%d) %s at %d,%d",
  162. X            event_action(event), event_action(event),
  163. X            event_is_down(event)? "pressed" : "released",
  164. X            event_x(event), event_y(event));
  165. X    } else switch (event_action(event)) {
  166. X        case ACTION_CLOSE :
  167. X            xv_set(frame, FRAME_CLOSED, TRUE, NULL);
  168. X            break;
  169. X        case ACTION_OPEN :
  170. X            strcpy(p, "frame opened up");
  171. X            break;
  172. X        case ACTION_HELP :
  173. X            strcpy(p, "Help (action ignored)");
  174. X            break;
  175. X        case ACTION_SELECT :
  176. X            sprintf(p, "Button: Select (Left) %s at %d,%d",
  177. X                event_is_down(event)? "pressed" : "released",
  178. X                event_x(event), event_y(event));
  179. X            break;
  180. X        case ACTION_ADJUST :
  181. X            sprintf(p, "Button: Adjust (Middle) %s at %d,%d",
  182. X                event_is_down(event)? "pressed" : "released",
  183. X                event_x(event), event_y(event));
  184. X            break;
  185. X        case ACTION_MENU :
  186. X            sprintf(p, "Button: Menu (Right) %s at %d,%d",
  187. X                event_is_down(event)? "pressed" : "released",
  188. X                event_x(event), event_y(event));
  189. X            break;
  190. X        case SHIFT_RIGHT :
  191. X            sprintf(p, "Keyboard: right shift %s",
  192. X                event_is_down(event)? "pressed" : "released");
  193. X            break;
  194. X        case SHIFT_LEFT :
  195. X            sprintf(p, "Keyboard: left shift %s",
  196. X                event_is_down(event)? "pressed" : "released");
  197. X            break;
  198. X        case SHIFT_LEFTCTRL : case SHIFT_RIGHTCTRL :
  199. X            sprintf(p, "Keyboard: control key %s",
  200. X                event_is_down(event)? "pressed" : "released");
  201. X            break;
  202. X        case SHIFT_META :
  203. X            sprintf(p, "Keyboard: meta key %s",
  204. X                event_is_down(event)? "pressed" : "released");
  205. X            break;
  206. X        case SHIFT_ALT :
  207. X            sprintf(p, "Keyboard: alt key %s",
  208. X                event_is_down(event)? "pressed" : "released");
  209. X            break;
  210. X        case KBD_USE:
  211. X            sprintf(p, "Keyboard: got keyboard focus");
  212. X            break;
  213. X        case KBD_DONE:
  214. X            sprintf(p, "Keyboard: lost keyboard focus");
  215. X            break;
  216. X        case LOC_MOVE:
  217. X            sprintf(p, "Pointer: moved to %d,%d",
  218. X                    event_x(event),event_y(event));
  219. X            break;
  220. X        case LOC_DRAG:
  221. X            sprintf(p, "Pointer: dragged to %d,%d",
  222. X                    event_x(event), event_y(event));
  223. X            break;
  224. X        case LOC_WINENTER:
  225. X            win_set_kbd_focus(window, xv_get(window, XV_XID));
  226. X            sprintf(p, "Pointer: entered window at %d,%d",
  227. X                    event_x(event), event_y(event));
  228. X            break;
  229. X        case LOC_WINEXIT:
  230. X            sprintf(p, "Pointer: exited window at %d,%d",
  231. X                    event_x(event), event_y(event));
  232. X            break;
  233. X        case WIN_RESIZE :
  234. X        case WIN_REPAINT :
  235. X            return;
  236. X        default : ;
  237. X            /* There are too many ACTION events to trap -- ignore the
  238. X             * ones we're not interested in.
  239. X             */
  240. X    }
  241. X
  242. X    my_repaint_proc(canvas, window,
  243. X        xv_get(canvas, XV_DISPLAY), xv_get(window, XV_XID), NULL);
  244. X}
  245. X
  246. X/*
  247. X * my_repaint_proc()
  248. X *      Called to repaint the canvas in response to damage events
  249. X *      and the initial painting of the canvas window.
  250. X *      Displays the keyboard, pointer and button message strings
  251. X *      after erasing the previous messages.
  252. X */
  253. Xvoid
  254. Xmy_repaint_proc(canvas, pw, dpy, xwin, xrects)
  255. XCanvas          canvas;
  256. XXv_Window       pw;
  257. XDisplay         *dpy;
  258. XWindow          xwin;
  259. XXv_xrectlist    *xrects;
  260. X{
  261. X    char        win_num[16];
  262. X    Xv_Window   w;
  263. X    int         i = 0;
  264. X    GC          gc = DefaultGC(dpy, DefaultScreen(dpy));
  265. X
  266. X    /*
  267. X     * Determine which paint window we're writing in.
  268. X     */
  269. X    CANVAS_EACH_PAINT_WINDOW(canvas, w)
  270. X        if (w == pw)
  271. X            break;
  272. X        i++;
  273. X    CANVAS_END_EACH
  274. X    sprintf(win_num, "(Window #%d) ", i+1);
  275. X
  276. X    XClearWindow(dpy, xwin);
  277. X    XDrawString(dpy, xwin, gc, 25, 25, win_num, strlen(win_num));
  278. X    XDrawString(dpy, xwin, gc, 25, 45, msg, strlen(msg));
  279. X}
  280. END_OF_FILE
  281. if test 7680 -ne `wc -c <'xview.demos/canvas/canvas_input.c'`; then
  282.     echo shar: \"'xview.demos/canvas/canvas_input.c'\" unpacked with wrong size!
  283. fi
  284. # end of 'xview.demos/canvas/canvas_input.c'
  285. fi
  286. if test -f 'xview.demos/canvas/scroll_view.c' -a "${1}" != "-c" ; then 
  287.   echo shar: Will not clobber existing file \"'xview.demos/canvas/scroll_view.c'\"
  288. else
  289. echo shar: Extracting \"'xview.demos/canvas/scroll_view.c'\" \(6567 characters\)
  290. sed "s/^X//" >'xview.demos/canvas/scroll_view.c' <<'END_OF_FILE'
  291. X/*
  292. X * scroll_view.c
  293. X * Dan Heller <argv@sun.com> 1989
  294. X *
  295. X * Display a canvas in a frame.  The canvas displays a window that has
  296. X * lines drawn from the opposite corners and draws a black box in the
  297. X * top left corner.  This canvas may be split in many ways (vertically
  298. X * and/or horizontally), but the repaint routine makes sure that each
  299. X * paint window displays the same thing.
  300. X
  301. X * This program also demonstrates how to handle splitting views
  302. X * programmatically.  Using the left mouse button splits a view
  303. X * horizontally at the Y location of the mouse.  Using the middle
  304. X * mouse button splits the view vertically at the X location of
  305. X * the mouse.
  306. X */
  307. X#include <stdio.h>
  308. X#include <X11/X.h>
  309. X#include <X11/Xlib.h>   /* Using Xlib graphicsas well */
  310. X#include <xview/xview.h>
  311. X#include <xview/canvas.h>
  312. X#include <xview/scrollbar.h>
  313. X#include <xview/rectlist.h>
  314. X
  315. XCanvas  canvas;
  316. Xvoid    events(), repaint_proc(), init_split(), join_split();
  317. X
  318. Xmain(argc, argv)
  319. Xint argc;
  320. Xchar *argv[];
  321. X{
  322. X    Frame       frame;
  323. X    Xv_Window   view;
  324. X    Rect        *rect;
  325. X
  326. X    xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
  327. X
  328. X    /*
  329. X     * Create a frame that's 300 wide by 150 high -- give it a titlebar
  330. X     */
  331. X    frame = (Frame)xv_create(XV_NULL, FRAME,
  332. X        XV_WIDTH,               300,
  333. X        XV_HEIGHT,              150,
  334. X        FRAME_LABEL,            argv[0],
  335. X        NULL);
  336. X
  337. X    /*
  338. X     * Create a canvas that's 500 by 500.  This canvas should not adjust
  339. X     * its size if resized.  Install the repaint callback: repaint_proc()
  340. X     */
  341. X    canvas = (Canvas)xv_create(frame, CANVAS,
  342. X        CANVAS_WIDTH,           500,
  343. X        CANVAS_HEIGHT,          500,
  344. X        CANVAS_AUTO_SHRINK,     FALSE,
  345. X        CANVAS_AUTO_EXPAND,     FALSE,
  346. X        CANVAS_REPAINT_PROC,    repaint_proc,
  347. X        NULL);
  348. X
  349. X    /* Install the callback for events on the first (and only, so far)
  350. X     * paint window.  We'll use the default events provided by the canvas.
  351. X     */
  352. X    xv_set(canvas_paint_window(canvas),
  353. X        WIN_EVENT_PROC,         events,
  354. X        WIN_CONSUME_EVENTS,     ACTION_SELECT, ACTION_ADJUST, NULL,
  355. X        NULL);
  356. X
  357. X    /*
  358. X     * There's only one viewport since multi-views cannot be created
  359. X     * when creating a canvas.  Install "init" and "destroy" callbacks
  360. X     * in the canvas object.  See the corresponding routines for specifics.
  361. X     */
  362. X    xv_set(canvas,
  363. X        OPENWIN_SPLIT,
  364. X            OPENWIN_SPLIT_INIT_PROC,    init_split,
  365. X            OPENWIN_SPLIT_DESTROY_PROC, join_split,
  366. X            NULL,
  367. X        NULL);
  368. X
  369. X    /*
  370. X     * Attach scrollbars to the canvas.
  371. X     */
  372. X    xv_create(canvas, SCROLLBAR,
  373. X        SCROLLBAR_SPLITTABLE,   TRUE,
  374. X        SCROLLBAR_DIRECTION,    SCROLLBAR_VERTICAL,
  375. X        NULL);
  376. X    xv_create(canvas, SCROLLBAR,
  377. X        SCROLLBAR_SPLITTABLE,   TRUE,
  378. X        SCROLLBAR_DIRECTION,    SCROLLBAR_HORIZONTAL,
  379. X        NULL);
  380. X
  381. X    xv_main_loop(frame);
  382. X    exit(0);
  383. X}
  384. X
  385. X/*
  386. X * The repaint procedure is called whenever repainting is needed in a
  387. X * paint window.  If the canvas has been split into several views and
  388. X * repainting is necessary, then this repaint procedure is called for
  389. X * each paint window in the canvas.
  390. X */
  391. Xvoid
  392. Xrepaint_proc(canvas, paint_window, repaint_area)
  393. XCanvas          canvas;
  394. XXv_Window       paint_window;
  395. XRectlist        repaint_area;
  396. X{
  397. X    Display     *dpy;
  398. X    Window      win;
  399. X    Xv_Window   pw;
  400. X    Rect        *rect;
  401. X
  402. X    /* Get the size of the entire paint window */
  403. X    rect = (Rect *)xv_get(paint_window, XV_RECT);
  404. X
  405. X    /* Use Xview graphics to draw lines from opposite corners. */
  406. X    xv_vector(paint_window, 0, 0, rect->r_width, rect->r_height, PIX_SET, 1);
  407. X    xv_vector(paint_window, rect->r_width, 0, 0, rect->r_height, PIX_SET, 1);
  408. X
  409. X    /* Use Xlib calls to draw a black square in the top corner of the pw */
  410. X    dpy = (Display *)XV_DISPLAY_FROM_WINDOW(paint_window);
  411. X    win = (Window)xv_get(paint_window, XV_XID);
  412. X    XFillRectangle(dpy, win, DefaultGC(dpy, DefaultScreen(dpy)), 10,10, 50,50);
  413. X}
  414. X
  415. X/*
  416. X * This routine is installed as the callback for events for the paint
  417. X * window.  If more paint windows are created as a result of a view
  418. X * split, then this routine must be reinstalled in a new view.
  419. X */
  420. Xvoid
  421. Xevents(pw, event)
  422. XXv_Window pw;
  423. XEvent *event;
  424. X{
  425. X    int code = event_action(event);
  426. X    Xv_Window view;
  427. X    int i = (int)xv_get(canvas, OPENWIN_NVIEWS);
  428. X
  429. X    /* Not interested in button up events */
  430. X    if (win_inputnegevent(event))
  431. X        return;
  432. X
  433. X    /* Determine which paint window this event happened in. */
  434. X    while (pw != xv_get(canvas, CANVAS_NTH_PAINT_WINDOW, --i) && i > 0)
  435. X        ;
  436. X    /* The paint window number is "i" -- get the "i"th view window */
  437. X    view = xv_get(canvas, OPENWIN_NTH_VIEW, i);
  438. X
  439. X    /* determine which event was passed and deal with it. */
  440. X    switch (code) {
  441. X        case ACTION_SELECT : case ACTION_ADJUST :
  442. X            /*
  443. X             * split the view at the appropriate position -- this call
  444. X             * will generate a call to init_split below since a new view
  445. X             * will have been created.
  446. X             */
  447. X            printf("split at %d,%d\n", event_x(event), event_y(event));
  448. X            xv_set(canvas,
  449. X                OPENWIN_SPLIT, /* takes a null-terminated attr-value list */
  450. X                    OPENWIN_SPLIT_VIEW,         view,
  451. X                    OPENWIN_SPLIT_DIRECTION,    code == ACTION_ADJUST?
  452. X                                                    OPENWIN_SPLIT_VERTICAL :
  453. X                                                    OPENWIN_SPLIT_HORIZONTAL,
  454. X                    OPENWIN_SPLIT_POSITION,     code == ACTION_ADJUST?
  455. X                                                    event_x(event) :
  456. X                                                    event_y(event),
  457. X                    NULL,
  458. X                NULL);
  459. X            break;
  460. X        default:
  461. X            return;
  462. X    }
  463. X    /* indicate which paint window and view window ID's */
  464. X    printf("win %x, view: %x\n", pw, view);
  465. X}
  466. X
  467. X/*
  468. X * notify this routine whenever two views are joined.
  469. X */
  470. Xvoid
  471. Xjoin_split(view)
  472. XXv_Window view;
  473. X{
  474. X    puts("joined view");
  475. X}
  476. X
  477. X/*
  478. X * Notify this routine whenever a view is split.  The new view is
  479. X * created and its position is indicated.  This is the first time
  480. X * the new view can be accessed by the program.  Immediately install
  481. X * the callback for events for the new paint window.
  482. X */
  483. Xvoid
  484. Xinit_split(oldview, newview, pos)
  485. XXv_Window oldview, newview;
  486. Xint pos;
  487. X{
  488. X    xv_set(xv_get(newview, CANVAS_VIEW_PAINT_WINDOW),
  489. X        WIN_EVENT_PROC,         events,
  490. X        WIN_CONSUME_EVENT,      ACTION_SELECT, ACTION_ADJUST, NULL,
  491. X        NULL);
  492. X}
  493. END_OF_FILE
  494. if test 6567 -ne `wc -c <'xview.demos/canvas/scroll_view.c'`; then
  495.     echo shar: \"'xview.demos/canvas/scroll_view.c'\" unpacked with wrong size!
  496. fi
  497. # end of 'xview.demos/canvas/scroll_view.c'
  498. fi
  499. if test -f 'xview.demos/canvas/split_views.c' -a "${1}" != "-c" ; then 
  500.   echo shar: Will not clobber existing file \"'xview.demos/canvas/split_views.c'\"
  501. else
  502. echo shar: Extracting \"'xview.demos/canvas/split_views.c'\" \(7095 characters\)
  503. sed "s/^X//" >'xview.demos/canvas/split_views.c' <<'END_OF_FILE'
  504. X/*
  505. X * split_views.c -- run this program and then split the views using the
  506. X * scrollbars.  The new view should be scrolled to 0, 0 (click on the
  507. X * left and top elevator anchors to reset both scrollbars on the new view).
  508. X */
  509. X#include <stdio.h>
  510. X#include <xview/xview.h>
  511. X#include <xview/canvas.h>
  512. X#include <xview/scrollbar.h>
  513. X
  514. XCanvas    canvas;
  515. XFrame    frame;
  516. Xchar    msg[128];
  517. Xvoid    init_split(), my_event_proc(), my_repaint_proc();
  518. X
  519. Xmain(argc,argv)
  520. Xint    argc;
  521. Xchar    *argv[];
  522. X{
  523. X    /*
  524. X     * Initialize, create base frame (with footers) and * create canvas.
  525. X     */
  526. X    xv_init(XV_INIT_ARGS, argc,argv, 0);
  527. X    frame = xv_create(NULL,FRAME,
  528. X    FRAME_LABEL,        "Try Splitting views.",
  529. X    FRAME_SHOW_FOOTER,    TRUE,
  530. X    NULL);
  531. X    canvas = xv_create(frame,CANVAS,
  532. X    OPENWIN_SPLIT,
  533. X        OPENWIN_SPLIT_INIT_PROC,    init_split,
  534. X        NULL,
  535. X    CANVAS_REPAINT_PROC,    my_repaint_proc,
  536. X    NULL);
  537. X
  538. X    xv_create(canvas, SCROLLBAR,
  539. X    SCROLLBAR_SPLITTABLE,    TRUE,
  540. X    SCROLLBAR_DIRECTION,    SCROLLBAR_VERTICAL,
  541. X    NULL);
  542. X    xv_create(canvas, SCROLLBAR,
  543. X    SCROLLBAR_SPLITTABLE,    TRUE,
  544. X    SCROLLBAR_DIRECTION,    SCROLLBAR_HORIZONTAL,
  545. X    NULL);
  546. X
  547. X    /*
  548. X     *    Set input mask
  549. X     */
  550. X    xv_set(canvas_paint_window(canvas),
  551. X        WIN_CONSUME_EVENTS,
  552. X        WIN_NO_EVENTS, WIN_ASCII_EVENTS, KBD_USE, KBD_DONE,
  553. X        LOC_DRAG, LOC_WINENTER, LOC_WINEXIT, WIN_MOUSE_BUTTONS,
  554. X        NULL,
  555. X        WIN_EVENT_PROC,    my_event_proc,
  556. X        NULL);
  557. X
  558. X    xv_main_loop(frame);
  559. X    return 0;
  560. X}
  561. X
  562. X/*
  563. X * when a viewport is split, this routine is called.
  564. X */
  565. Xvoid
  566. Xinit_split(splitview, newview, pos)
  567. XXv_Window splitview, newview;
  568. Xint pos;
  569. X{
  570. X    Xv_Window    view, win;
  571. X    int        i = 0;
  572. X
  573. X    /*
  574. X     * Determine which view # is the new view and which is the original view
  575. X     */
  576. X    OPENWIN_EACH_VIEW(canvas, view)
  577. X    if (view == splitview) {
  578. X        /* identify the view # of the view the user just split. */
  579. X        sprintf(msg, "Split view #%d", i+1);
  580. X        xv_set(frame, FRAME_LEFT_FOOTER, msg, NULL);
  581. X    } else if (view == newview) {
  582. X        /*
  583. X         * install the same event handling mask and event callback
  584. X         * for the newview's paint window.
  585. X         */
  586. X        xv_set(win = xv_get(canvas, CANVAS_NTH_PAINT_WINDOW, i),
  587. X        WIN_CONSUME_EVENTS,
  588. X            WIN_NO_EVENTS, WIN_ASCII_EVENTS, KBD_USE, KBD_DONE,
  589. X            LOC_DRAG, LOC_WINENTER, LOC_WINEXIT, WIN_MOUSE_BUTTONS,
  590. X            NULL,
  591. X        WIN_EVENT_PROC,    my_event_proc,
  592. X        NULL);
  593. X    }
  594. X    i++;
  595. X    OPENWIN_END_EACH
  596. X    printf("win = %x, CANVAS_VIEW_PAINT_WINDOW = %x\n",
  597. X    win, xv_get(newview, CANVAS_VIEW_PAINT_WINDOW));
  598. X    sprintf(msg, "Total views: %d", i);
  599. X    xv_set(frame, FRAME_RIGHT_FOOTER, msg, NULL);
  600. X}
  601. X
  602. X/*
  603. X * Called when an event is received in an arbitrary paint window.
  604. X */
  605. Xvoid
  606. Xmy_event_proc(window, event, arg)
  607. XXv_Window    window;
  608. XEvent        *event;
  609. XNotify_arg    arg;
  610. X{
  611. X    register char *p = msg;
  612. X
  613. X    *p = 0;
  614. X
  615. X    /* test to see if a function key has been hit */
  616. X    if (event_is_key_left(event))
  617. X    sprintf(p, "(L%d) ", event_id(event) - KEY_LEFTFIRST + 1);
  618. X    else if (event_is_key_top(event))
  619. X    sprintf(p, "(T%d) ", event_id(event) - KEY_TOPFIRST + 1);
  620. X    else if (event_is_key_right(event))
  621. X    sprintf(p, "(R%d) ", event_id(event) - KEY_RIGHTFIRST + 1);
  622. X    else if (event_id(event) == KEY_BOTTOMLEFT)
  623. X    strcpy(p, "bottom left ");
  624. X    else if (event_id(event) == KEY_BOTTOMRIGHT)
  625. X    strcpy(p, "bottom left ");
  626. X    p += strlen(p);
  627. X
  628. X    /* Test to see if event is a special "mnemonic" action */
  629. X    if (event_action(event) != event_id(event)) {
  630. X    switch (event_action(event)) {
  631. X        case ACTION_CLOSE :
  632. X        strcpy(p, "close (action ignored)");
  633. X        break;
  634. X        case ACTION_OPEN :
  635. X        strcpy(p, "open (action ignored)");
  636. X        break;
  637. X        case ACTION_HELP :
  638. X        strcpy(p, "Help (action ignored)");
  639. X        break;
  640. X        case ACTION_SELECT : /* the action */
  641. X        case MS_LEFT :     /* the actual (literal) event */
  642. X        sprintf(p, "Button: Select (Left) %s at %d,%d",
  643. X            event_is_down(event)? "pressed" : "released",
  644. X            event_x(event), event_y(event));
  645. X        break;
  646. X        case ACTION_ADJUST :
  647. X        case MS_MIDDLE :
  648. X        sprintf(p, "Button: Adjust (Middle) %s at %d,%d",
  649. X            event_is_down(event)? "pressed" : "released",
  650. X            event_x(event), event_y(event));
  651. X        break;
  652. X        case ACTION_MENU :
  653. X        case MS_RIGHT :
  654. X        sprintf(p, "Button: Menu (Right) %s at %d,%d",
  655. X            event_is_down(event)? "pressed" : "released",
  656. X            event_x(event), event_y(event));
  657. X        break;
  658. X        default : ;
  659. X        /* There are too many ACTION events to trap -- ignore the
  660. X         * ones we're not interested in.
  661. X         */
  662. X    }
  663. X    } else if (event_is_ascii(event))
  664. X    /*
  665. X     * note that shift modifier is reflected in the event code by
  666. X     * virtue of the char printed is upper/lower case.
  667. X     */
  668. X    sprintf(p, "Keyboard: key '%c' (%d) %s at %d,%d",
  669. X        event_action(event), event_action(event),
  670. X        event_is_down(event)? "pressed" : "released",
  671. X        event_x(event), event_y(event));
  672. X    else switch (event_id(event)) {
  673. X    case SHIFT_RIGHT :
  674. X        sprintf(p, "Keyboard: right shift %s",
  675. X            event_is_down(event)? "pressed" : "released");
  676. X        break;
  677. X    case SHIFT_LEFT :
  678. X        sprintf(p, "Keyboard: left shift %s",
  679. X            event_is_down(event)? "pressed" : "released");
  680. X        break;
  681. X    case SHIFT_LEFTCTRL : case SHIFT_RIGHTCTRL :
  682. X        sprintf(p, "Keyboard: control key %s",
  683. X            event_is_down(event)? "pressed" : "released");
  684. X        break;
  685. X    case SHIFT_META :
  686. X        sprintf(p, "Keyboard: meta key %s",
  687. X            event_is_down(event)? "pressed" : "released");
  688. X        break;
  689. X    case SHIFT_ALT :
  690. X        sprintf(p, "Keyboard: alt key %s",
  691. X            event_is_down(event)? "pressed" : "released");
  692. X        break;
  693. X    case KBD_USE:
  694. X        sprintf(p, "Keyboard: got keyboard focus");
  695. X        break;
  696. X    case KBD_DONE:
  697. X        sprintf(p, "Keyboard: lost keyboard focus");
  698. X        break;
  699. X    case LOC_MOVE:
  700. X        sprintf(p, "Pointer: moved to %d,%d",
  701. X            event_x(event),event_y(event));
  702. X        break;
  703. X    case LOC_DRAG:
  704. X        sprintf(p, "Pointer: dragged to %d,%d",
  705. X            event_x(event), event_y(event));
  706. X        break;
  707. X    case LOC_WINENTER:
  708. X        win_set_kbd_focus(window, xv_get(window, XV_XID));
  709. X        sprintf(p, "Pointer: entered window at %d,%d",
  710. X            event_x(event), event_y(event));
  711. X        break;
  712. X    case LOC_WINEXIT:
  713. X        sprintf(p, "Pointer: exited window at %d,%d",
  714. X            event_x(event), event_y(event));
  715. X        break;
  716. X    case WIN_RESIZE :
  717. X        strcpy(msg, "resize");
  718. X        break;
  719. X    case WIN_REPAINT :
  720. X        strcpy(msg, "repaint");
  721. X        break;
  722. X    default:
  723. X        if (msg[0])
  724. X            printf("unknown event: %d\n", event_id(event));
  725. X    }
  726. X    my_repaint_proc(canvas, window, NULL);
  727. X}
  728. X
  729. X/*
  730. X * my_repaint_proc()
  731. X *    Called to repaint the canvas in response to damage events
  732. X *    and the initial painting of the canvas window.
  733. X *    Displays the keyboard, pointer and button message strings
  734. X *    after erasing the previous messages.
  735. X */
  736. Xvoid
  737. Xmy_repaint_proc(canvas, pw, repaint_area)
  738. XCanvas        canvas;
  739. XXv_Window    pw;
  740. XRectlist    *repaint_area;
  741. X{
  742. X    static char buf[] =
  743. X    "                                                                    ";
  744. X    char    win_num[16];
  745. X    Xv_Window    w;
  746. X    int        i = 0;
  747. X
  748. X    /*
  749. X     * Determine which # paint window we're writing in.
  750. X     */
  751. X    CANVAS_EACH_PAINT_WINDOW(canvas, w)
  752. X    if (w == pw)
  753. X        break;
  754. X    i++;
  755. X    CANVAS_END_EACH
  756. X    sprintf(win_num, "(Window #%d) ", i+1);
  757. X    xv_text(pw, 25, 25, PIX_SRC, NULL, win_num);
  758. X
  759. X    xv_text(pw, 25, 45, PIX_SRC, NULL, buf);
  760. X    xv_text(pw, 25, 45, PIX_SRC, NULL, msg);
  761. X}
  762. END_OF_FILE
  763. if test 7095 -ne `wc -c <'xview.demos/canvas/split_views.c'`; then
  764.     echo shar: \"'xview.demos/canvas/split_views.c'\" unpacked with wrong size!
  765. fi
  766. # end of 'xview.demos/canvas/split_views.c'
  767. fi
  768. if test -f 'xview.demos/color/x_draw.c' -a "${1}" != "-c" ; then 
  769.   echo shar: Will not clobber existing file \"'xview.demos/color/x_draw.c'\"
  770. else
  771. echo shar: Extracting \"'xview.demos/color/x_draw.c'\" \(5651 characters\)
  772. sed "s/^X//" >'xview.demos/color/x_draw.c' <<'END_OF_FILE'
  773. X/*
  774. X * x_draw.c --
  775. X *      Demonstrates the use of Xlib drawing functions inside an
  776. X *      XView canvas.  Color is also used, but not required.
  777. X */
  778. X#include <xview/xview.h>
  779. X#include <xview/canvas.h>
  780. X#include <xview/cms.h>
  781. X#include <xview/xv_xrect.h>
  782. X
  783. X/* indices into color table renders specified colors. */
  784. X#define WHITE   0
  785. X#define RED     1
  786. X#define GREEN   2
  787. X#define BLUE    3
  788. X#define ORANGE  4
  789. X#define AQUA    5
  790. X#define PINK    6
  791. X#define BLACK   7
  792. X
  793. XGC gc;   /* GC used for Xlib drawing */
  794. Xunsigned long *colors; /* the color table */
  795. X
  796. X/*
  797. X * initialize cms data to support colors specified above.  Assign
  798. X * data to new cms -- use either static or dynamic cms depending
  799. X * on -dynamic command line switch.
  800. X */
  801. Xmain(argc, argv)
  802. Xint     argc;
  803. Xchar    *argv[];
  804. X{
  805. X    unsigned char red[8], green[8], blue[8];
  806. X    static char stipple_bits[] = {0xAA, 0xAA, 0x55, 0x55};
  807. X    Frame       frame;
  808. X    Canvas      canvas;
  809. X    XFontStruct *font;
  810. X    Display     *display;
  811. X    XGCValues   gc_val;
  812. X    XID         xid;
  813. X    void        canvas_repaint();
  814. X    Xv_cmsdata  cms_data;
  815. X    int         use_dynamic = FALSE;
  816. X
  817. X    /* Create windows */
  818. X    xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
  819. X    if (*++argv && !strcmp(*argv, "-dynamic"))
  820. X        use_dynamic = TRUE;
  821. X
  822. X    frame = xv_create(NULL,FRAME,
  823. X        FRAME_LABEL,    "xv_canvas_x_draw",
  824. X        XV_WIDTH,       400,
  825. X        XV_HEIGHT,      300,
  826. X        NULL);
  827. X
  828. X    /* initialize RGB values for specified colors */
  829. X    red[WHITE] = 255;   green[WHITE] = 255;   blue[WHITE] = 255;
  830. X    red[RED] = 255;     green[RED] = 0;       blue[RED] = 0;
  831. X    red[GREEN] = 0;     green[GREEN] = 255;   blue[GREEN] = 0;
  832. X    red[BLUE] = 0;      green[BLUE] = 0;      blue[BLUE] = 255;
  833. X    red[ORANGE] = 250;  green[ORANGE] = 130;  blue[ORANGE] = 80;
  834. X    red[AQUA] = 30;     green[AQUA] = 230;    blue[AQUA] = 250;
  835. X    red[PINK] = 230;    green[PINK] = 30;     blue[PINK] = 250;
  836. X
  837. X    cms_data.type = use_dynamic? XV_DYNAMIC_CMS : XV_STATIC_CMS;
  838. X    cms_data.size = 8;
  839. X    cms_data.rgb_count = 8;
  840. X    cms_data.index = 0;
  841. X    cms_data.red = red;
  842. X    cms_data.green = green;
  843. X    cms_data.blue = blue;
  844. X
  845. X    canvas = xv_create(frame, CANVAS,
  846. X        CANVAS_REPAINT_PROC,    canvas_repaint,
  847. X        CANVAS_X_PAINT_WINDOW,  TRUE,
  848. X        WIN_DYNAMIC_VISUAL,     use_dynamic,
  849. X        WIN_CMS_NAME,           "palette",
  850. X        WIN_CMS_DATA,           &cms_data,
  851. X        NULL);
  852. X
  853. X    /* Get display and xid */
  854. X    display = (Display *)xv_get(frame, XV_DISPLAY);
  855. X    xid = (XID)xv_get(canvas_paint_window(canvas), XV_XID);
  856. X
  857. X    if (!(font = XLoadQueryFont(display, "fixed"))) {
  858. X        puts("cannot load fixed font");
  859. X        exit(1);
  860. X    }
  861. X
  862. X    /* Create and initialize GC */
  863. X    gc_val.font = font->fid;
  864. X    gc_val.stipple =
  865. X    XCreateBitmapFromData(display, xid, stipple_bits, 16, 2);
  866. X    gc = XCreateGC(display, xid, GCFont | GCStipple, &gc_val);
  867. X
  868. X    /* get the colormap from the canvas now that
  869. X     * the cms has been installed
  870. X     */
  871. X    colors = (unsigned long *)xv_get(canvas, WIN_X_COLOR_INDICES);
  872. X
  873. X    /* Start event loop */
  874. X    xv_main_loop(frame);
  875. X}
  876. X
  877. X/*
  878. X * Draws onto the canvas using Xlib drawing functions.
  879. X */
  880. Xvoid
  881. Xcanvas_repaint(canvas, pw, display, xid, xrects)
  882. XCanvas          canvas;
  883. XXv_Window       pw;
  884. XDisplay         *display;
  885. XWindow          xid;
  886. XXv_xrectlist    *xrects;
  887. X{
  888. X    static XPoint box[] = {
  889. X        {0,0}, {100,100}, {0,-100}, {-100,100}, {0,-100}
  890. X    };
  891. X    static XPoint points[] = {
  892. X        {0,0}, /* this point to be overwritten below */
  893. X        {25,0}, {25,0}, {25,0}, {25,0}, {-100,25},
  894. X        {25,0}, {25,0}, {25,0}, {25,0}, {-100,25},
  895. X        {25,0}, {25,0}, {25,0}, {25,0}, {-100,25},
  896. X        {25,0}, {25,0}, {25,0}, {25,0}, {-100,25},
  897. X        {25,0}, {25,0}, {25,0}, {25,0}, {-100,25},
  898. X    };
  899. X
  900. X    XSetForeground(display, gc, colors[RED]);
  901. X    XDrawString(display, xid, gc, 30, 20, "XFillRectangle", 14);
  902. X    XFillRectangle(display, xid, gc, 25, 25, 100, 100);
  903. X    XSetFunction(display, gc, GXinvert);
  904. X    XFillRectangle(display, xid, gc, 50, 50, 50, 50);
  905. X    XSetFunction(display, gc, GXcopy);
  906. X
  907. X    XSetForeground(display, gc, colors[BLACK]);
  908. X    XDrawString(display, xid, gc, 155, 20, "XFillRect - stipple", 19);
  909. X    XSetFillStyle(display, gc, FillStippled);
  910. X    XFillRectangle(display, xid, gc, 150, 25, 100, 100);
  911. X    XSetFillStyle(display, gc, FillSolid);
  912. X
  913. X    XSetForeground(display, gc, colors[BLUE]);
  914. X    XDrawString(display, xid, gc, 280, 20, "XDrawPoints", 11);
  915. X    points[0].x = 275; points[0].y = 25;
  916. X    XDrawPoints(display, xid, gc, points,
  917. X        sizeof(points)/sizeof(XPoint), CoordModePrevious);
  918. X
  919. X    XSetForeground(display, gc, colors[ORANGE]);
  920. X    XDrawString(display, xid, gc, 30, 145, "XDrawLine - solid", 17);
  921. X    XDrawLine(display, xid, gc, 25, 150, 125, 250);
  922. X    XDrawLine(display, xid, gc, 25, 250, 125, 150);
  923. X
  924. X    XSetForeground(display, gc, colors[AQUA]);
  925. X    XDrawString(display, xid, gc, 155, 145, "XDrawLine - dashed", 18);
  926. X    XSetLineAttributes(display, gc, 5,
  927. X        LineDoubleDash, CapButt, JoinMiter);
  928. X    XDrawLine(display, xid, gc, 150, 150, 250, 250);
  929. X    XDrawLine(display, xid, gc, 150, 250, 250, 150);
  930. X    XSetLineAttributes(display, gc, 0, LineSolid, CapButt, JoinMiter);
  931. X
  932. X    XSetForeground(display, gc, colors[PINK]);
  933. X    XDrawString(display, xid, gc, 280, 145, "XDrawLines", 10);
  934. X    box[0].x = 275; box[0].y = 150;
  935. X    XDrawLines(display, xid, gc, box, 5, CoordModePrevious);
  936. X
  937. X    XSetForeground(display, gc, colors[GREEN]);
  938. X    XDrawRectangle(display, xid, gc,
  939. X        5, 5, xv_get(pw, XV_WIDTH)-10, xv_get(pw, XV_HEIGHT)-10);
  940. X    XDrawRectangle(display, xid, gc,
  941. X        7, 7, xv_get(pw, XV_WIDTH)-14, xv_get(pw, XV_HEIGHT)-14);
  942. X}
  943. END_OF_FILE
  944. if test 5651 -ne `wc -c <'xview.demos/color/x_draw.c'`; then
  945.     echo shar: \"'xview.demos/color/x_draw.c'\" unpacked with wrong size!
  946. fi
  947. # end of 'xview.demos/color/x_draw.c'
  948. fi
  949. if test -f 'xview.demos/menus/menu_dir2.c' -a "${1}" != "-c" ; then 
  950.   echo shar: Will not clobber existing file \"'xview.demos/menus/menu_dir2.c'\"
  951. else
  952. echo shar: Extracting \"'xview.demos/menus/menu_dir2.c'\" \(6585 characters\)
  953. sed "s/^X//" >'xview.demos/menus/menu_dir2.c' <<'END_OF_FILE'
  954. X/*
  955. X * menu_dir2.c -
  956. X * Demonstrate the use of an XView menu in a canvas subwindow.
  957. X * A menu is brought up with the MENU mouse button and displays
  958. X * menu choices representing the files in the directory.  If a
  959. X * directory entry is found, a new pullright item is created with
  960. X * that subdir as the pullright menu's contents.  This implementation
  961. X * creates directories on an as-needed basis.  Thus, we provide a
  962. X * MENU_GEN_PULLRIGHT procedure.
  963. X *
  964. X * argv[1] indicates which directory to start from.
  965. X */
  966. X#include <xview/xview.h>
  967. X#include <xview/canvas.h>
  968. X#include <sys/stat.h>
  969. X#include <sys/dir.h>
  970. X#include <X11/Xos.h>
  971. X#ifndef MAXPATHLEN
  972. X#include <sys/param.h>
  973. X#endif /* MAXPATHLEN */
  974. X
  975. XFrame   frame;
  976. X
  977. Xmain(argc,argv)
  978. Xint     argc;
  979. Xchar    *argv[];
  980. X{
  981. X    Canvas      canvas;
  982. X    extern void exit();
  983. X    void        my_event_proc();
  984. X    Menu        menu;
  985. X    Menu_item   mi, add_path_to_menu();
  986. X
  987. X    xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
  988. X
  989. X    frame = (Frame)xv_create(NULL, FRAME,
  990. X        FRAME_LABEL,            argv[1]? argv[1] : "cwd",
  991. X        FRAME_SHOW_FOOTER,      TRUE,
  992. X        NULL);
  993. X    canvas = (Canvas)xv_create(frame, CANVAS,
  994. X        FRAME_LABEL,    argv[0],
  995. X        XV_WIDTH,       400,
  996. X        XV_HEIGHT,      100,
  997. X        NULL);
  998. X
  999. X    mi = add_path_to_menu(argc > 1? argv[1] : ".");
  1000. X    menu = (Menu)xv_get(mi, MENU_PULLRIGHT);
  1001. X    /* We no longer need the item since we have the menu from it */
  1002. X    xv_destroy(mi);
  1003. X
  1004. X    /* associate the menu to the canvas win for easy etreival */
  1005. X    xv_set(canvas_paint_window(canvas),
  1006. X        WIN_CONSUME_EVENTS,     WIN_MOUSE_BUTTONS, NULL,
  1007. X        WIN_EVENT_PROC,         my_event_proc,
  1008. X        WIN_CLIENT_DATA,        menu,
  1009. X        NULL);
  1010. X
  1011. X    window_fit(frame);
  1012. X    window_main_loop(frame);
  1013. X}
  1014. X
  1015. X/*
  1016. X * my_action_proc - display the selected item in the frame footer.
  1017. X */
  1018. Xvoid
  1019. Xmy_action_proc(menu, menu_item)
  1020. XMenu    menu;
  1021. XMenu_item       menu_item;
  1022. X{
  1023. X    xv_set(frame,
  1024. X        FRAME_LEFT_FOOTER,      xv_get(menu_item, MENU_STRING),
  1025. X        NULL);
  1026. X}
  1027. X
  1028. X/*
  1029. X * Call menu_show() to display menu on right mouse button push.
  1030. X */
  1031. Xvoid
  1032. Xmy_event_proc(canvas, event)
  1033. XCanvas  canvas;
  1034. XEvent *event;
  1035. X{
  1036. X    if ((event_id(event) == MS_RIGHT) && event_is_down(event)) {
  1037. X        Menu menu = (Menu)xv_get(canvas, WIN_CLIENT_DATA);
  1038. X        menu_show(menu, canvas, event, NULL);
  1039. X    }
  1040. X}
  1041. X
  1042. X/*
  1043. X * return an allocated char * that points to the last item in a path.
  1044. X */
  1045. Xchar *
  1046. Xgetfilename(path)
  1047. Xchar *path;
  1048. X{
  1049. X    char *p;
  1050. X
  1051. X    if (p = rindex(path, '/'))
  1052. X        p++;
  1053. X    else
  1054. X        p = path;
  1055. X    return strcpy(malloc(strlen(p)+1), p);
  1056. X}
  1057. X
  1058. XMenu
  1059. Xgen_pullright(mi, op)
  1060. XMenu_item mi;
  1061. XMenu_generate op;
  1062. X{
  1063. X    Menu menu;
  1064. X    Menu_item new, old = mi;
  1065. X    char buf[MAXPATHLEN];
  1066. X
  1067. X    if (op == MENU_DISPLAY) {
  1068. X        menu = (Menu)xv_get(mi, MENU_PARENT);
  1069. X        sprintf(buf, "%s/%s",
  1070. X            xv_get(menu, MENU_CLIENT_DATA), xv_get(mi, MENU_STRING));
  1071. X        new = add_path_to_menu(buf);
  1072. X        /* if item has a pullright menu, free it (its data first) */
  1073. X        if (menu = (Menu)xv_get(mi, MENU_PULLRIGHT)) {
  1074. X            free(xv_get(menu, MENU_CLIENT_DATA));
  1075. X            xv_destroy(menu);
  1076. X        }
  1077. X        if (new) {
  1078. X            menu = (Menu)xv_get(new, MENU_PULLRIGHT);
  1079. X            xv_destroy(new);
  1080. X            return menu;
  1081. X        }
  1082. X    }
  1083. X    if (!(menu = (Menu)xv_get(mi, MENU_PULLRIGHT)))
  1084. X            menu = (Menu)xv_create(NULL, MENU,
  1085. X                MENU_STRINGS, "Couldn't build a menu.", NULL,
  1086. X                NULL);
  1087. X    return menu;
  1088. X}
  1089. X
  1090. X/*
  1091. X * The path passed in is scanned via readdir().  For each file in the
  1092. X * path, a menu item is created and inserted into a new menu.  That
  1093. X * new menu is made the PULLRIGHT_MENU of a newly created panel item
  1094. X * for the path item originally passed it.  Since this routine is
  1095. X * recursive, a new menu is created for each subdirectory under the
  1096. X * original path.
  1097. X */
  1098. XMenu_item
  1099. Xadd_path_to_menu(path)
  1100. Xchar *path;
  1101. X{
  1102. X    DIR                 *dirp;
  1103. X    struct direct       *dp;
  1104. X    struct stat         s_buf;
  1105. X    Menu_item           mi;
  1106. X    Menu                next_menu;
  1107. X    char                buf[MAXPATHLEN];
  1108. X    static int          recursion;
  1109. X
  1110. X    /* don't add a folder to the list if user can't read it */
  1111. X    if (stat(path, &s_buf) == -1 || !(s_buf.st_mode & S_IREAD))
  1112. X        return NULL;
  1113. X    if (s_buf.st_mode & S_IFDIR) {
  1114. X        int cnt = 0;
  1115. X        if (!(dirp = opendir(path)))
  1116. X            /* don't bother adding to list if we can't scan it */
  1117. X            return NULL;
  1118. X        if (recursion)
  1119. X            return (Menu_item)-1;
  1120. X        recursion++;
  1121. X        next_menu = (Menu)xv_create(XV_NULL, MENU, NULL);
  1122. X        while (dp = readdir(dirp))
  1123. X            if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
  1124. X                (void) sprintf(buf, "%s/%s", path, dp->d_name);
  1125. X                mi = add_path_to_menu(buf);
  1126. X                if (!mi || mi == (Menu_item)-1) {
  1127. X                    int do_gen_pullright = (mi == (Menu_item)-1);
  1128. X                    /* unreadable file or dir - deactivate item */
  1129. X                    mi = (Menu_item)xv_create(XV_NULL, MENUITEM,
  1130. X                        MENU_STRING,  getfilename(dp->d_name),
  1131. X                        MENU_RELEASE,
  1132. X                        MENU_RELEASE_IMAGE,
  1133. X                        NULL);
  1134. X                    if (do_gen_pullright)
  1135. X                        xv_set(mi,
  1136. X                            MENU_GEN_PULLRIGHT, gen_pullright,
  1137. X                            NULL);
  1138. X                    else
  1139. X                        xv_set(mi, MENU_INACTIVE, TRUE, NULL);
  1140. X                }
  1141. X                xv_set(next_menu, MENU_APPEND_ITEM, mi, NULL);
  1142. X                cnt++;
  1143. X            }
  1144. X        closedir(dirp);
  1145. X        mi = (Menu_item)xv_create(XV_NULL, MENUITEM,
  1146. X            MENU_STRING,        getfilename(path),
  1147. X            MENU_RELEASE,
  1148. X            MENU_RELEASE_IMAGE,
  1149. X            MENU_NOTIFY_PROC,   my_action_proc,
  1150. X            NULL);
  1151. X        if (!cnt) {
  1152. X            xv_destroy(next_menu);
  1153. X            /* An empty or unsearchable directory - deactivate item */
  1154. X            xv_set(mi, MENU_INACTIVE, TRUE, NULL);
  1155. X        } else {
  1156. X            xv_set(next_menu,
  1157. X                MENU_TITLE_ITEM, strcpy(malloc(strlen(path)+1), path),
  1158. X                MENU_CLIENT_DATA, strcpy(malloc(strlen(path)+1), path),
  1159. X                NULL);
  1160. X            xv_set(mi, MENU_PULLRIGHT, next_menu, NULL);
  1161. X        }
  1162. X        recursion--;
  1163. X        return mi;
  1164. X    }
  1165. X    return (Menu_item)xv_create(NULL, MENUITEM,
  1166. X        MENU_STRING,            getfilename(path),
  1167. X        MENU_RELEASE,
  1168. X        MENU_RELEASE_IMAGE,
  1169. X        MENU_NOTIFY_PROC,       my_action_proc,
  1170. X        NULL);
  1171. X}
  1172. END_OF_FILE
  1173. if test 6585 -ne `wc -c <'xview.demos/menus/menu_dir2.c'`; then
  1174.     echo shar: \"'xview.demos/menus/menu_dir2.c'\" unpacked with wrong size!
  1175. fi
  1176. # end of 'xview.demos/menus/menu_dir2.c'
  1177. fi
  1178. if test -f 'xview.demos/menus/pin_menu.c' -a "${1}" != "-c" ; then 
  1179.   echo shar: Will not clobber existing file \"'xview.demos/menus/pin_menu.c'\"
  1180. else
  1181. echo shar: Extracting \"'xview.demos/menus/pin_menu.c'\" \(4815 characters\)
  1182. sed "s/^X//" >'xview.demos/menus/pin_menu.c' <<'END_OF_FILE'
  1183. X/*
  1184. X * pin_menu.c -
  1185. X *    Demonstrate how to generate your own pinup menu.
  1186. X *    Use of MENU_GEN_PIN_WINDOW is for static menus only.
  1187. X *    This demo uses menus whose items may change, so we
  1188. X *    need to reflect those changes in our own command frame.
  1189. X */
  1190. X#include <xview/xview.h>
  1191. X#include <xview/canvas.h>
  1192. X#include <xview/panel.h>
  1193. X
  1194. XFrame    frame;
  1195. X
  1196. X/*
  1197. X * main -
  1198. X *    Create a frame, canvas and menu.
  1199. X *    A canvas receives input in its canvas_paint_window().
  1200. X *    Specify creation of an Open Look Menu and transformation of
  1201. X *    the menu to a pinned command window.
  1202. X *    Each menu item specifies an action proc to be called when the
  1203. X *    item is chosen, regardless of whether or not menu is pinned.
  1204. X */
  1205. Xmain(argc,argv)
  1206. Xint    argc;
  1207. Xchar    *argv[];
  1208. X{
  1209. X    Canvas    canvas;
  1210. X    Menu    menu;
  1211. X    void    my_notify_proc(), my_event_proc(), menu_done();
  1212. X    extern void    exit();
  1213. X
  1214. X    xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
  1215. X
  1216. X    frame = (Frame)xv_create(NULL, FRAME,
  1217. X    FRAME_LABEL,    argv[0],
  1218. X    NULL);
  1219. X    canvas = (Canvas)xv_create(frame, CANVAS,
  1220. X    XV_WIDTH,    300,
  1221. X    XV_HEIGHT,    200,
  1222. X    NULL);
  1223. X    menu = (Menu)xv_create(NULL, MENU,
  1224. X    MENU_GEN_PIN_WINDOW,    frame, "Junk",
  1225. X    MENU_DONE_PROC,        menu_done,
  1226. X    /*
  1227. X    MENU_STRINGS,        "Yes", "No", "Maybe", NULL,
  1228. X    MENU_NOTIFY_PROC,    my_notify_proc,
  1229. X    */
  1230. X    MENU_ITEM, MENU_STRING,    "No", MENU_NOTIFY_PROC, my_notify_proc, NULL,
  1231. X    MENU_ITEM, MENU_STRING,    "Yes", MENU_NOTIFY_PROC, my_notify_proc, NULL,
  1232. X    MENU_ITEM, MENU_STRING,    "Maybe", MENU_NOTIFY_PROC, my_notify_proc, NULL,
  1233. X    MENU_ITEM,
  1234. X        MENU_STRING,    "Save",
  1235. X        MENU_NOTIFY_PROC,    my_notify_proc,
  1236. X        MENU_PULLRIGHT,
  1237. X        xv_create(canvas, MENU,
  1238. X            MENU_ITEM,
  1239. X            MENU_STRING,        "Update Changes",
  1240. X            MENU_NOTIFY_PROC,    my_notify_proc,
  1241. X            NULL,
  1242. X            NULL),
  1243. X        NULL,
  1244. X    MENU_ITEM,
  1245. X        MENU_STRING,    "Quit",
  1246. X        MENU_NOTIFY_PROC,    exit,
  1247. X        NULL,
  1248. X    NULL);
  1249. X
  1250. X    xv_set(canvas_paint_window(canvas),
  1251. X    WIN_CONSUME_EVENTS,    WIN_MOUSE_BUTTONS, NULL,
  1252. X    WIN_EVENT_PROC,        my_event_proc,
  1253. X    /* associate the menu to the canvas win so we can retreive it easily */
  1254. X    WIN_CLIENT_DATA,    menu,
  1255. X    NULL);
  1256. X
  1257. X    window_fit(frame);
  1258. X    window_main_loop(frame);
  1259. X}
  1260. X
  1261. X/*
  1262. X * menu_done - menu has been popped-down.  Make sure the command frame panel
  1263. X * matches the menu.
  1264. X */
  1265. Xvoid
  1266. Xmenu_done(menu, result)
  1267. XMenu menu;
  1268. XXv_opaque result;
  1269. X{
  1270. X    int default_item, i;
  1271. X    Frame pin_frame;
  1272. X    Panel panel;
  1273. X    Panel_item pi;
  1274. X
  1275. X    printf("result = %x\n", result);
  1276. X    if (!(pin_frame = (Frame)xv_get(menu, MENU_PIN_WINDOW))) {
  1277. X    puts("menu has no pin frame");
  1278. X    return;
  1279. X    }
  1280. X    panel = (Panel)xv_get(pin_frame, FRAME_CMD_PANEL);
  1281. X    /* get the ordinal number of the default menu item */
  1282. X    default_item = (int)xv_get(menu, MENU_DEFAULT);
  1283. X
  1284. X    /* search for the <default>-th item in the panel and... */
  1285. X    pi = (Panel_item)xv_get(panel, PANEL_FIRST_ITEM);
  1286. X    for (i = 1 /*menu items offset at 1*/; i < default_item && pi; i++)
  1287. X    pi = (Panel_item)xv_get(pi, PANEL_NEXT_ITEM);
  1288. X
  1289. X    /* set that paenl item to be the default item */
  1290. X    xv_set(panel, PANEL_DEFAULT_ITEM, pi, NULL);
  1291. X}
  1292. X
  1293. X/*
  1294. X * my_notify_proc - Display menu selection in frame header.
  1295. X */
  1296. Xvoid
  1297. Xmy_notify_proc(menu, menu_item)
  1298. XMenu menu;
  1299. XMenu_item menu_item;
  1300. X{
  1301. X    xv_set(frame,
  1302. X    FRAME_LABEL,    xv_get(menu_item, MENU_STRING),
  1303. X    NULL);
  1304. X}
  1305. X
  1306. X/*
  1307. X * my_event_proc - Call menu_show() to display menu on right mouse button push.
  1308. X */
  1309. Xvoid
  1310. Xmy_event_proc(window, event)
  1311. XXv_Window window;
  1312. XEvent *event;
  1313. X{
  1314. X    if (event_action(event) == ACTION_MENU && event_is_down(event)) {
  1315. X    Menu menu = (Menu)xv_get(window, WIN_CLIENT_DATA);
  1316. X    if (!xv_get(menu, MENU_PIN_WINDOW))
  1317. X        create_pin_win(menu);
  1318. X    menu_show(menu, window, event, NULL);
  1319. X    }
  1320. X}
  1321. X
  1322. X#define MENU_KEY    100
  1323. X#define MENU_ITEM_KEY    101
  1324. X#define ACTION_KEY    102
  1325. X
  1326. Xcreate_pin_win(menu)
  1327. XMenu menu;
  1328. X{
  1329. X    int i;
  1330. X    void pin_btn_notify();
  1331. X    Frame cmd_frame = (Frame)xv_create(frame, FRAME_CMD, XV_SHOW, FALSE, NULL);
  1332. X    Panel panel = (Panel)xv_get(cmd_frame, FRAME_CMD_PANEL);
  1333. X    Menu_item mi;
  1334. X
  1335. X    printf("frame = %x, panel = %x\n", cmd_frame, panel);
  1336. X    for (i = (int)xv_get(menu, MENU_NITEMS); i > 0; i--) {
  1337. X    mi = (Menu_item)xv_get(menu, MENU_NTH_ITEM, i);
  1338. X    printf("adding panel item: %s\n", xv_get(mi, MENU_STRING));
  1339. X    xv_create(panel, PANEL_BUTTON,
  1340. X        /* PANEL_MENU_ITEM,        TRUE, */
  1341. X        PANEL_LABEL_STRING,        xv_get(mi, MENU_STRING),
  1342. X        PANEL_NOTIFY_PROC,        pin_btn_notify,
  1343. X        XV_KEY_DATA, MENU_KEY,    menu,
  1344. X        XV_KEY_DATA, MENU_ITEM_KEY,    mi,
  1345. X        XV_KEY_DATA, ACTION_KEY,    xv_get(mi, MENU_NOTIFY_PROC),
  1346. X        NULL);
  1347. X    }
  1348. X    window_fit(panel);
  1349. X    window_fit(cmd_frame);
  1350. X    xv_set(menu, MENU_PIN_WINDOW, cmd_frame, NULL);
  1351. X}
  1352. X
  1353. Xvoid
  1354. Xpin_btn_notify(item, event)
  1355. XPanel_item item;
  1356. XEvent *event;
  1357. X{
  1358. X    Menu    menu = (Menu)xv_get(item, XV_KEY_DATA, MENU_KEY);
  1359. X    Menu_item    mi = (Menu)xv_get(item, XV_KEY_DATA, MENU_ITEM_KEY);
  1360. X    void    (*action)() = (void (*)())xv_get(item, XV_KEY_DATA, ACTION_KEY);
  1361. X
  1362. X    (*action)(menu, mi);
  1363. X}
  1364. END_OF_FILE
  1365. if test 4815 -ne `wc -c <'xview.demos/menus/pin_menu.c'`; then
  1366.     echo shar: \"'xview.demos/menus/pin_menu.c'\" unpacked with wrong size!
  1367. fi
  1368. # end of 'xview.demos/menus/pin_menu.c'
  1369. fi
  1370. if test -f 'xview.demos/seln_svc/long_seln.c' -a "${1}" != "-c" ; then 
  1371.   echo shar: Will not clobber existing file \"'xview.demos/seln_svc/long_seln.c'\"
  1372. else
  1373. echo shar: Extracting \"'xview.demos/seln_svc/long_seln.c'\" \(5727 characters\)
  1374. sed "s/^X//" >'xview.demos/seln_svc/long_seln.c' <<'END_OF_FILE'
  1375. X/*
  1376. X * long_seln.c shows how to get an arbitrarily large selection by
  1377. X * providing a reading procedure to selection_query().  The panel
  1378. X * items allow the user to choose between 3 selection ranks.
  1379. X */
  1380. X#include <xview/xview.h>
  1381. X#include <xview/textsw.h>
  1382. X#include <xview/panel.h>
  1383. X#include <xview/seln.h>
  1384. X
  1385. Xextern char *malloc();
  1386. X
  1387. XSeln_rank seln_type = SELN_PRIMARY;
  1388. X
  1389. X#define FIRST_BUFFER            0
  1390. X#define NOT_FIRST_BUFFER        !FIRST_BUFFER
  1391. X
  1392. Xchar *seln_bufs[3];     /* contents of each of the three selections */
  1393. X
  1394. XSeln_result read_proc(); /* supplied to selection_query() as reader */
  1395. X
  1396. XTextsw          textsw;  /* select from this textsw */
  1397. XXv_Server       server;
  1398. Xchar *get_selection();
  1399. X
  1400. Xvoid
  1401. Xchange_selection(item, value)
  1402. XPanel_item item;
  1403. Xint value;
  1404. X{
  1405. X    if (value == 0)
  1406. X        seln_type = SELN_PRIMARY;
  1407. X    else if (value == 1)
  1408. X        seln_type = SELN_SECONDARY;
  1409. X    else
  1410. X        seln_type = SELN_SHELF;
  1411. X}
  1412. X
  1413. Xmain(argc, argv)
  1414. Xchar *argv[];
  1415. X{
  1416. X    Frame       frame;
  1417. X    Panel       panel;
  1418. X    void        print_seln(), exit();
  1419. X
  1420. X    xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
  1421. X    frame = (Frame) xv_create(NULL, FRAME,
  1422. X        FRAME_LABEL, argv[0],
  1423. X        NULL);
  1424. X
  1425. X    panel = (Panel)xv_create(frame, PANEL,
  1426. X        WIN_WIDTH,              WIN_EXTEND_TO_EDGE,
  1427. X        NULL);
  1428. X
  1429. X    (void) xv_create(panel, PANEL_BUTTON,
  1430. X        PANEL_LABEL_STRING,     "Quit",
  1431. X        PANEL_NOTIFY_PROC,      exit,
  1432. X        NULL);
  1433. X    (void) xv_create(panel, PANEL_BUTTON,
  1434. X        PANEL_LABEL_STRING,     "Get Selection",
  1435. X        PANEL_NOTIFY_PROC,      print_seln,
  1436. X        NULL);
  1437. X    (void) xv_create(panel, PANEL_CHOICE,
  1438. X        PANEL_LABEL_STRING,     "Selection Type",
  1439. X        PANEL_CHOICE_STRINGS,   "Primary", "Secondary", "Shelf", NULL,
  1440. X        PANEL_NOTIFY_PROC,      change_selection,
  1441. X        NULL);
  1442. X    window_fit(panel);
  1443. X
  1444. X    textsw = (Textsw)xv_create(frame, TEXTSW,
  1445. X        WIN_X,                  0,
  1446. X        WIN_BELOW,              panel,
  1447. X        WIN_ROWS,               10,
  1448. X        WIN_COLUMNS,            80,
  1449. X        TEXTSW_FILE_CONTENTS,   "/etc/termcap",
  1450. X        NULL);
  1451. X    window_fit(frame);
  1452. X    server = (Xv_Server)xv_get(xv_get(frame, XV_SCREEN), SCREEN_SERVER);
  1453. X    xv_main_loop(frame);
  1454. X}
  1455. X
  1456. Xvoid
  1457. Xprint_seln()
  1458. X{
  1459. X    char *text = get_selection();
  1460. X
  1461. X    if (text)
  1462. X        printf("---seln---\n%.*s [...]\n---end seln---\n", 20, text);
  1463. X}
  1464. X
  1465. X/*
  1466. X * return the text selected in the current selection rank.  Use
  1467. X * selection_query() to guarantee that the entire selection is
  1468. X * retrieved.  selection_query() calls our installed routine,
  1469. X * read_proc() (see below).
  1470. X */
  1471. Xchar *
  1472. Xget_selection()
  1473. X{
  1474. X    Seln_holder   holder;
  1475. X    Seln_result   result;
  1476. X    Seln_request  *response;
  1477. X    char          context = FIRST_BUFFER;
  1478. X
  1479. X    holder = selection_inquire(server, seln_type);
  1480. X    printf("selection type = %s\n",
  1481. X        seln_type == SELN_PRIMARY? "primary" :
  1482. X        seln_type == SELN_SECONDARY? "secondary" : "shelf");
  1483. X
  1484. X    /* result is based on the return value of read_proc() */
  1485. X    result = selection_query(server, &holder, read_proc, &context,
  1486. X        SELN_REQ_BYTESIZE,              NULL,
  1487. X        SELN_REQ_CONTENTS_ASCII,        NULL,
  1488. X        NULL);
  1489. X    if (result == SELN_FAILED) {
  1490. X        puts("couldn't get selection");
  1491. X        return NULL;
  1492. X    }
  1493. X
  1494. X    return seln_bufs[seln_type];
  1495. X}
  1496. X
  1497. X/*
  1498. X * Called by selection_query for every buffer of information received.
  1499. X * Short messages (under about 2000 bytes) will fit into one buffer.
  1500. X * For larger messages, read_proc is called for each buffer in the
  1501. X * selection.  The context pointer passed to selection_query is
  1502. X * modified by read_proc so that we know if this is the first buffer
  1503. X * or not.
  1504. X */
  1505. XSeln_result
  1506. Xread_proc(response)
  1507. XSeln_request *response;
  1508. X{
  1509. X    char *reply;  /* pointer to the data in the response received */
  1510. X    long seln_len; /* total number of bytes in the selection */
  1511. X    static long seln_have_bytes;
  1512. X        /* number of bytes of the selection
  1513. X         * which have been read; cumulative over all calls for
  1514. X         * the same selection (it is reset when the first
  1515. X         * response of a selection is read)
  1516. X         */
  1517. X
  1518. X    printf("read_proc status: %s (%d)\n",
  1519. X        response->status == SELN_FAILED? "failed" :
  1520. X        response->status == SELN_SUCCESS? "succeeded" :
  1521. X        response->status == SELN_CONTINUED? "continued" : "???",
  1522. X        response->status);
  1523. X    if (*response->requester.context == FIRST_BUFFER) {
  1524. X        reply = response->data;
  1525. X
  1526. X        /* read in the length of the selection -- first attribute.
  1527. X         * advance "reply" passed attribute to point to actual data.
  1528. X         */
  1529. X        reply += sizeof(SELN_REQ_BYTESIZE);
  1530. X        /* set seln_len to actual data now. (bytes selected) */
  1531. X        seln_len = *(int *)reply;
  1532. X        printf("selection size is %ld bytes\n", seln_len);
  1533. X        /* advance "reply" to next attribute in list */
  1534. X        reply += sizeof(long);
  1535. X
  1536. X        /* create a buffer large enough to store entire selection */
  1537. X        if (seln_bufs[seln_type] != NULL)
  1538. X            free(seln_bufs[seln_type]);
  1539. X        if (!(seln_bufs[seln_type] = malloc(seln_len + 1))) {
  1540. X            puts("out of memory");
  1541. X            return(SELN_FAILED);
  1542. X        }
  1543. X        seln_have_bytes = 0;
  1544. X
  1545. X        /* move "reply" passed attribute so it points to contents */
  1546. X        reply += sizeof(SELN_REQ_CONTENTS_ASCII);
  1547. X        *response->requester.context = NOT_FIRST_BUFFER;
  1548. X    } else {
  1549. X        /* this is not the first buffer, so the contents of the
  1550. X     * response is just more of the selection
  1551. X         */
  1552. X        reply = response->data;
  1553. X    }
  1554. X
  1555. X    /* copy data from received to the seln buffer allocated above */
  1556. X    (void) strcpy(&seln_bufs[seln_type][seln_have_bytes], reply);
  1557. X    seln_have_bytes += strlen(reply);
  1558. X
  1559. X    return SELN_SUCCESS;
  1560. X}
  1561. END_OF_FILE
  1562. if test 5727 -ne `wc -c <'xview.demos/seln_svc/long_seln.c'`; then
  1563.     echo shar: \"'xview.demos/seln_svc/long_seln.c'\" unpacked with wrong size!
  1564. fi
  1565. # end of 'xview.demos/seln_svc/long_seln.c'
  1566. fi
  1567. if test -f 'xview.demos/seln_svc/seln.c' -a "${1}" != "-c" ; then 
  1568.   echo shar: Will not clobber existing file \"'xview.demos/seln_svc/seln.c'\"
  1569. else
  1570. echo shar: Extracting \"'xview.demos/seln_svc/seln.c'\" \(5659 characters\)
  1571. sed "s/^X//" >'xview.demos/seln_svc/seln.c' <<'END_OF_FILE'
  1572. X/*
  1573. X * seln.c -- print the primary selection from the server.  If the
  1574. X * selection is in a text subwindow, then print information about
  1575. X * the line number(s) the selection spans and the indexes of the
  1576. X * bytes within the textsw's text stream.  This simple program
  1577. X * may not be sufficient for general usage -- see comments in
  1578. X * get_selection() comments below.
  1579. X */
  1580. X#include <stdio.h>
  1581. X#include <xview/xview.h>
  1582. X#include <xview/textsw.h>
  1583. X#include <xview/panel.h>
  1584. X#include <xview/server.h>
  1585. X#include <xview/seln.h>
  1586. X
  1587. XXv_Server       server;
  1588. XTextsw          textsw;
  1589. X
  1590. Xchar *get_selection();
  1591. X
  1592. Xmain(argc, argv)
  1593. Xchar *argv[];
  1594. X{
  1595. X    Frame       frame;
  1596. X    Panel       panel;
  1597. X    void        print_seln(), exit();
  1598. X
  1599. X    xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
  1600. X
  1601. X    frame = (Frame) xv_create(NULL, FRAME,
  1602. X        FRAME_LABEL,            argv[0],
  1603. X        NULL);
  1604. X    panel = (Panel) xv_create(frame, PANEL,
  1605. X        WIN_WIDTH,              WIN_EXTEND_TO_EDGE,
  1606. X        NULL);
  1607. X    (void) xv_create(panel, PANEL_BUTTON,
  1608. X        PANEL_LABEL_STRING,     "Quit",
  1609. X        PANEL_NOTIFY_PROC,      exit,
  1610. X        NULL);
  1611. X    (void) xv_create(panel, PANEL_BUTTON,
  1612. X        PANEL_LABEL_STRING,     "Get Selection",
  1613. X        PANEL_NOTIFY_PROC,      print_seln,
  1614. X        NULL);
  1615. X    window_fit(panel);
  1616. X
  1617. X    textsw = (Textsw)xv_create(frame, TEXTSW,
  1618. X        WIN_X,                  0,
  1619. X        WIN_BELOW,              panel,
  1620. X        WIN_ROWS,               10,
  1621. X        WIN_COLUMNS,            80,
  1622. X        TEXTSW_FILE_CONTENTS,   "/etc/passwd",
  1623. X        NULL);
  1624. X    window_fit(frame);
  1625. X
  1626. X    server = (Xv_Server)xv_get(xv_get(frame, XV_SCREEN), SCREEN_SERVER);
  1627. X
  1628. X    xv_main_loop(frame);
  1629. X}
  1630. X
  1631. Xvoid
  1632. Xprint_seln()
  1633. X{
  1634. X    char *text = get_selection();
  1635. X
  1636. X    if (text)
  1637. X        printf("---selection---\n%s\n---end seln---\n", text);
  1638. X}
  1639. X
  1640. X/*
  1641. X * Get the selection using selection_ask().  Note that if the
  1642. X * selection is bigger than about 2K, the whole selection will
  1643. X * not be gotten with one call, thus this method of getting the
  1644. X * selection may not be sufficient.
  1645. X */
  1646. Xchar *
  1647. Xget_selection()
  1648. X{
  1649. X    long                sel_lin_num, lines_selected;
  1650. X    Textsw_index        first, last;
  1651. X    Seln_holder         holder;
  1652. X    Seln_result         result;
  1653. X    int                 len;
  1654. X    Seln_request       *request;
  1655. X    static char         selection_buf[BUFSIZ];
  1656. X    register char      *ptr;
  1657. X
  1658. X    /* get the holder of the primary selection */
  1659. X    holder = selection_inquire(server, SELN_PRIMARY);
  1660. X
  1661. X    /* If the selection occurs in the text subwindow, print lots
  1662. X     * of info about the selection.
  1663. X     */
  1664. X    if (seln_holder_same_client(&holder, textsw)) {
  1665. X        /* ask for information from the selection service */
  1666. X        request = selection_ask(server, &holder,
  1667. X            /* get the index of the first and last chars in seln */
  1668. X            SELN_REQ_FIRST,             NULL,
  1669. X            SELN_REQ_LAST,              NULL,
  1670. X            /* get the actual selection bytes */
  1671. X            SELN_REQ_CONTENTS_ASCII,    NULL,
  1672. X            /* fool the textsw to think entire lines are selected */
  1673. X            SELN_REQ_FAKE_LEVEL,        SELN_LEVEL_LINE,
  1674. X            /* line numbers of beginning and ending of the seln */
  1675. X            SELN_REQ_FIRST_UNIT,        NULL,
  1676. X            SELN_REQ_LAST_UNIT,         NULL,
  1677. X            NULL);
  1678. X        /* set the ptr to beginning of data -- SELN_REQ_FIRST */
  1679. X        ptr = request->data;
  1680. X        /* "first" is data succeeding SELN_REQ_FIRST -- skip attr */
  1681. X        first = *(Textsw_index *)(ptr += sizeof(SELN_REQ_FIRST));
  1682. X        ptr += sizeof(Textsw_index); /* skip over value of "first" */
  1683. X        /* "last" is data succeeding SELN_REQ_LAST -- skip attr */
  1684. X        last  = *(Textsw_index *)(ptr += sizeof(SELN_REQ_LAST));
  1685. X        ptr += sizeof(Textsw_index); /* skip over value of "last" */
  1686. X
  1687. X        /* advance pointer past SELN_REQ_CONTENTS_ASCII */
  1688. X        ptr += sizeof(SELN_REQ_CONTENTS_ASCII);
  1689. X        len = strlen(ptr); /* length of string in request */
  1690. X        (void) strcpy(selection_buf, ptr);
  1691. X        /*
  1692. X         * advance pointer past length of string.  If the string
  1693. X         * length isn't aligned to a 4-byte boundary, add the
  1694. X         * difference in bytes -- then advance pointer passed "value".
  1695. X         */
  1696. X        if (len % 4)
  1697. X            len = len + (4 - (len % 4));
  1698. X        ptr += len + sizeof(Seln_attribute); /* skip over "value" */
  1699. X
  1700. X        /* advance past SELN_REQ_FAKE_LEVEL, SELN_LEVEL_LINE */
  1701. X        ptr += sizeof(SELN_REQ_FAKE_LEVEL) + sizeof(SELN_LEVEL_LINE);
  1702. X
  1703. X        sel_lin_num = *(long *)(ptr += sizeof(SELN_REQ_FIRST_UNIT));
  1704. X        ptr += sizeof(long);
  1705. X        lines_selected = *(long *)(ptr += sizeof(SELN_REQ_LAST_UNIT));
  1706. X        ptr += sizeof(long);
  1707. X
  1708. X        /* hack to workaround bug with SELN_REQ_LAST_UNIT always
  1709. X         * returning -1.  We have to count the line numbers ourselves.
  1710. X         */
  1711. X        if (lines_selected < 0) {
  1712. X            register char *p;
  1713. X            lines_selected++;
  1714. X            for (p = selection_buf; *p; p++)
  1715. X                if (*p == '\n')
  1716. X                    lines_selected++;
  1717. X        }
  1718. X        printf("index in textsw: %d-%d, line number(s) = %d-%d\n",
  1719. X            first+1, last+1, sel_lin_num+1,
  1720. X            sel_lin_num+lines_selected+1);
  1721. X    } else {
  1722. X        /* the selection is not in the text subwindow */
  1723. X        request = selection_ask(server, &holder,
  1724. X            SELN_REQ_CONTENTS_ASCII, NULL,
  1725. X            NULL);
  1726. X        if (request->status != SELN_SUCCESS) {
  1727. X            printf("selection_ask() returns %d\n", request->status);
  1728. X            return "";
  1729. X        }
  1730. X        (void) strcpy(selection_buf,
  1731. X            request->data + sizeof(SELN_REQ_CONTENTS_ASCII));
  1732. X    }
  1733. X    return selection_buf;
  1734. X}
  1735. END_OF_FILE
  1736. if test 5659 -ne `wc -c <'xview.demos/seln_svc/seln.c'`; then
  1737.     echo shar: \"'xview.demos/seln_svc/seln.c'\" unpacked with wrong size!
  1738. fi
  1739. # end of 'xview.demos/seln_svc/seln.c'
  1740. fi
  1741. echo shar: End of archive 2 \(of 6\).
  1742. cp /dev/null ark2isdone
  1743. MISSING=""
  1744. for I in 1 2 3 4 5 6 ; do
  1745.     if test ! -f ark${I}isdone ; then
  1746.     MISSING="${MISSING} ${I}"
  1747.     fi
  1748. done
  1749. if test "${MISSING}" = "" ; then
  1750.     echo You have unpacked all 6 archives.
  1751.     rm -f ark[1-9]isdone
  1752. else
  1753.     echo You still need to unpack the following archives:
  1754.     echo "        " ${MISSING}
  1755. fi
  1756. ##  End of shell archive.
  1757. exit 0
  1758.