home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / alt / sources / 2586 < prev    next >
Encoding:
Text File  |  1992-11-20  |  19.2 KB  |  699 lines

  1. Path: sparky!uunet!stanford.edu!morrow.stanford.edu!sep!steve
  2. From: steve@sep.Stanford.EDU (Steve Cole)
  3. Newsgroups: alt.sources
  4. Subject: xtpanel 2.0 - interactive program builder - part 10/10
  5. Followup-To: alt.sources.d
  6. Date: 21 Nov 1992 00:35:30 GMT
  7. Organization: Stanford Exploration Project
  8. Lines: 686
  9. Distribution: world
  10. Message-ID: <1ek08iINN194@morrow.stanford.edu>
  11. NNTP-Posting-Host: taal.stanford.edu
  12.  
  13.  
  14. Submitted-by: steve@sep.Stanford.EDU
  15. Archive-name: xtpanel/part10
  16.  
  17. #!/bin/sh
  18. # This is part 10 of a multipart archive
  19. # ============= xtpanel/object.c ==============
  20. if test ! -d 'xtpanel'; then
  21.     echo 'x - creating directory xtpanel'
  22.     mkdir 'xtpanel'
  23. fi
  24. if test -f 'xtpanel/object.c' -a X"$1" != X"-c"; then
  25.     echo 'x - skipping xtpanel/object.c (File already exists)'
  26. else
  27. echo 'x - extracting xtpanel/object.c (Text)'
  28. sed 's/^X//' << 'SHAR_EOF' > 'xtpanel/object.c' &&
  29. /*
  30. X * Copyright 1992 the Board of Trustees of the Leland Stanford Junior
  31. X * University. Official permission to use this software is included in
  32. X * the documentation. It authorizes you to use this file for any
  33. X * non-commercial purpose, provided that this copyright notice is not
  34. X * removed and that any modifications made to this file are commented
  35. X * and dated in the style of the example below.
  36. X */
  37. X
  38. /*
  39. X *
  40. X *  source file:   ./xtpanel/object.c
  41. X *
  42. X * Steve Cole, Dave Nichols (SEP), August 31 1992
  43. X *      Inserted this sample edit history entry.
  44. X *      Please log any further modifications made to this file:
  45. X * Steve Cole, Dave Nichols (SEP), November 20 1992 -  version 2.00
  46. X * 1) added new objects: toggle, scrollbar, graph.
  47. X * 2) added new actions: ASSIGN, SET.
  48. X * 3) objects can have multiple actions.
  49. X * 4) backquoted strings in actions get executed at action time.
  50. X */
  51. X
  52. #include <stdio.h>
  53. X
  54. #include <X11/Xatom.h>
  55. #include <X11/Intrinsic.h>
  56. X
  57. #include <X11/Xaw/Label.h>
  58. X
  59. #include "object.h"
  60. #include "tree.h"
  61. X
  62. static Objdef* topobj=0;
  63. X
  64. /*
  65. X * Function name: new_object
  66. X * Description: creates a structure for a new object
  67. X * Arguments: none
  68. X * Returns: pointer to new structure of type objdef
  69. X */
  70. Objdef* new_object()
  71. {
  72. X    Objdef *a, *b;
  73. X    
  74. X    if( topobj == (Objdef*)0 ){
  75. X    /* make the head of the list */
  76. X    topobj = (Objdef*) malloc( sizeof( Objdef ) );
  77. X    topobj->name = strdupl("top");
  78. X    topobj->action = (action *) 0;
  79. X    topobj->value = (char *) 0;
  80. X    topobj->widgetname = (Widget) 0;
  81. X    topobj->info = (void *) 0;
  82. X    topobj->updater = (void *) 0;
  83. X    topobj->next = (Objdef*)0;
  84. X    }
  85. X    
  86. X    a = (Objdef*) malloc( sizeof( Objdef ) );
  87. X    a->name= (char *)0;
  88. X    a->action= (action *)0;
  89. X    a->value= (char *)0;
  90. X    a->widgetname= (Widget)0;
  91. X    a->info= (void *)0;
  92. X    a->updater= (void *)0;
  93. X    a->next= (Objdef*)0;
  94. X    
  95. X    /* find the tail of the list */
  96. X    for( b=topobj; b->next != (Objdef*)0; b = b->next );
  97. X    
  98. X    b->next = a;
  99. X    
  100. X    return a;
  101. }
  102. X
  103. /*
  104. X * Function name: find_by_name
  105. X * Description: loop over all objects, find the one with
  106. X *        the right name.
  107. X * Arguments: name - name to match
  108. X * Returns: pointer to object structure for matching object
  109. X */
  110. Objdef* find_by_name(name)
  111. X    char* name;
  112. {
  113. X    int iobj;
  114. X    Objdef* obj;
  115. X    
  116. X    /* loop over objects */
  117. X    for ( obj=topobj; obj != (Objdef*) 0; obj=obj->next )
  118. X      {
  119. X      if (!strcmp(obj->name,name)) {
  120. X          return obj;
  121. X      }
  122. X      }
  123. X    
  124. X    fprintf(stderr,"find_by_name cannot find object %s\n",name);
  125. X    exit(-1);  
  126. }
  127. X
  128. /*
  129. X * Function name: find_widget
  130. X * Description: loop over all objects, find the one with
  131. X *        the right widget name.
  132. X * Arguments: w - widget id to match
  133. X * Returns: pointer to object structure for matching object
  134. X */
  135. Objdef*
  136. X  find_by_widget(w)
  137. Widget w;
  138. {
  139. X    Objdef* obj;
  140. X    
  141. X    /* loop over objects */
  142. X    for ( obj=topobj; obj != (Objdef*) 0; obj=obj->next )
  143. X      {
  144. X      if (obj->widgetname == w) {
  145. X          return obj;
  146. X      }
  147. X      }
  148. X    
  149. X    fprintf(stderr,"find_by_widget cannot find widget %d\n", (int)w );
  150. X    exit(-1);  
  151. }
  152. X
  153. /*
  154. X * Function name: get_string
  155. X * Description: find the value of an object, given its name
  156. X * Arguments: name - object name
  157. X * Returns: pointer to string containing objects value
  158. X */
  159. char*
  160. X  get_string(name)
  161. char* name;
  162. {
  163. char * val;
  164. X    if( (val = find_by_name(name)->value) == (char*) 0 ){
  165. X      return(strdupl(""));  
  166. X    }else{
  167. X      return(strdupl(val));  
  168. X    }
  169. }
  170. X
  171. /*
  172. X * Function name: set_string
  173. X * Description: set the value of an object
  174. X * Arguments: name - object name
  175. X *          string - pointer to string containing new object value
  176. X * Returns: none
  177. X */
  178. void set_string(name,string)
  179. X     char* name,*string;
  180. {
  181. X    Objdef *obj;
  182. X    obj = find_by_name(name);
  183. X    if( obj->value != (char*)0 ) free(obj->value);
  184. X    obj->value = strdupl(string);
  185. }
  186. X
  187. /*
  188. X * Function name: all_actions
  189. X * Description: do the actions of all objects whose action type
  190. X *        is STRING. This makes sure defaults are set.
  191. X * Arguments: none
  192. X * Returns: none
  193. X */
  194. void all_actions()
  195. {
  196. X    Objdef* obj;
  197. X    
  198. X    if( topobj == (Objdef*)0 ) return;
  199. X    
  200. X    /* loop over objects, skip the top one */
  201. X    for ( obj=topobj->next; obj != (Objdef*) 0; obj=obj->next )
  202. X      {
  203. X      if (obj->action != (action *) 0) {
  204. X         perform_actions(obj->name,obj->action,0);
  205. X      }
  206. X      }
  207. }
  208. X
  209. /*
  210. X * Function name: update_object
  211. X * Description: update the value of an object
  212. X * Arguments: name - object name
  213. X *          string - pointer to string containing new object value
  214. X * Returns: none
  215. X */
  216. void update_object(name,string)
  217. X     char* name,*string;
  218. {
  219. X    Objdef *object;
  220. X
  221. X    object = find_by_name(name);
  222. X
  223. X    if( object->value != (char*)0 ) free(object->value);
  224. X    object->value = strdupl(string);
  225. X
  226. X    if( object->updater != 0 ) object->updater(object,string);
  227. }
  228. X
  229. /*
  230. X * Function name: update_tag
  231. X * Description: update the value of an object's tag
  232. X * Arguments: name - object name
  233. X *          value - pointer to string containing new object value
  234. X * Returns: none
  235. X */
  236. void update_tag(name,tag,value)
  237. X     char* name,*tag,*value;
  238. {
  239. X    Objdef *object;
  240. X    Arg args[20];
  241. X    int narg;
  242. X
  243. X    object = find_by_name(name);
  244. X
  245. X    narg = 0;
  246. X    SetTag(object->widgetname,args,&narg,tag,value);
  247. X    XtSetValues(object->widgetname,args,narg);
  248. }
  249. SHAR_EOF
  250. chmod 0664 xtpanel/object.c ||
  251. echo 'restore of xtpanel/object.c failed'
  252. Wc_c="`wc -c < 'xtpanel/object.c'`"
  253. test 5219 -eq "$Wc_c" ||
  254.     echo 'xtpanel/object.c: original size 5219, current size' "$Wc_c"
  255. fi
  256. # ============= xtpanel/graph.c ==============
  257. if test -f 'xtpanel/graph.c' -a X"$1" != X"-c"; then
  258.     echo 'x - skipping xtpanel/graph.c (File already exists)'
  259. else
  260. echo 'x - extracting xtpanel/graph.c (Text)'
  261. sed 's/^X//' << 'SHAR_EOF' > 'xtpanel/graph.c' &&
  262. /*
  263. X * Copyright 1992 the Board of Trustees of the Leland Stanford Junior
  264. X * University. Official permission to use this software is included in
  265. X * the documentation. It authorizes you to use this file for any
  266. X * non-commercial purpose, provided that this copyright notice is not
  267. X * removed and that any modifications made to this file are commented
  268. X * and dated in the style of the example below.
  269. X */
  270. X
  271. /*
  272. X *
  273. X *  source file:   ./xtpanel/graph.c
  274. X *
  275. X * Steve Cole, Dave Nichols (SEP), August 28 1992
  276. X *      Inserted this sample edit history entry.
  277. X *      Please log any further modifications made to this file:
  278. X * Steve Cole, Dave Nichols (SEP), November 20 1992 -  version 2.00
  279. X * 1) added new objects: toggle, scrollbar, graph.
  280. X * 2) added new actions: ASSIGN, SET.
  281. X * 3) objects can have multiple actions.
  282. X * 4) backquoted strings in actions get executed at action time.
  283. X */
  284. X
  285. #include <X11/Intrinsic.h>
  286. #include <X11/StringDefs.h>
  287. X
  288. #include <X11/Xaw/Box.h>
  289. #include <X11/Xaw/Cardinals.h>
  290. #include <X11/Xaw/Command.h>
  291. #include <X11/Xaw/Label.h>
  292. #include <X11/Xaw/Scrollbar.h>
  293. X
  294. #include "object.h" 
  295. #include "tree.h"
  296. #include "builders.h"
  297. #include "string_buf.h"
  298. X
  299. #include <stdio.h>
  300. #include <string.h>
  301. X
  302. typedef struct graphinfo {
  303. X    float minval;
  304. X    float maxval;
  305. X    char* format;
  306. X    int nsamp;
  307. X    Widget *widgets;
  308. } _ginfo;
  309. X
  310. /* translation table used for graph widget */
  311. char graph_trans[] =
  312. X  "<Leave>:         update_graph()";
  313. X
  314. extern void graph_callback();
  315. extern void graph_scroll_callback();
  316. extern void graph_update();
  317. extern void parse_valuestring();
  318. X
  319. void build_graph(root,parent)
  320. X     entry *root;
  321. X     Widget parent;
  322. {
  323. X    Objdef *object;
  324. X    entry *curr;
  325. X    char* label;
  326. X    struct graphinfo *graph_info;
  327. X    Arg args[10];
  328. X    int narg;
  329. X    Widget box, scrollbar, box2, button, vlabel, labl;
  330. X    float valmin,valmax,val,top;
  331. X    float *values;
  332. X    char *valstring;
  333. X    int nsamp,isamp;
  334. X    char text[100];
  335. X    int width,height;
  336. X    XtOrientation orient;
  337. X    char defname[12];
  338. X    static int numgraph=1;
  339. X    
  340. X    /* graph gets its own box */
  341. X    narg = 0;
  342. X    common_tags(root,args,&narg,SET_BG|SET_BORDER|SET_ORIENT);
  343. X    box = XtCreateManagedWidget("graphbox",boxWidgetClass,parent,args,narg);
  344. X    /* find box orientation - used below to set scrollbar orientation */
  345. X    narg = 0;
  346. X    XtSetArg(args[narg], XtNorientation, &orient); narg++;
  347. X    XtGetValues( box, args, narg );
  348. X    
  349. X    /* create new object */
  350. X    object = new_object();
  351. X
  352. X    /* construct default graph name */
  353. X    sprintf(defname,"graph%d",numgraph++);
  354. X    
  355. X    /* find name, action, nsamp in tree */
  356. X    object->name = get_value(root,"name",defname);
  357. X    label = get_value(root,"label",object->name);
  358. X    object->action = parse_actions(object->name,root);
  359. X    graph_info = (struct graphinfo*) malloc( sizeof( struct graphinfo ) );
  360. X    object->info = graph_info;
  361. X    graph_info->minval = ((float) atof(get_value(root,"min","0")));
  362. X    graph_info->maxval = ((float) atof(get_value(root,"max","1")));
  363. X    graph_info->nsamp = ((int) atoi(get_value(root,"nsamp","1")));
  364. X
  365. X    /* label to indicate minimum value */
  366. X    narg = 0;
  367. X    XtSetArg(args[narg], XtNlabel, get_value(root,"min","0")); narg++;
  368. X    vlabel = XtCreateManagedWidget(object->name,labelWidgetClass,
  369. X                box,args,narg);
  370. X
  371. X    /* the graph label */
  372. X    narg = 0;
  373. X    XtSetArg(args[narg], XtNborderWidth, 0); narg++;
  374. X    XtSetArg(args[narg], XtNlabel, label); narg++;
  375. X
  376. X    labl = XtCreateManagedWidget(object->name,labelWidgetClass,box,
  377. X                                     args,narg);
  378. X
  379. X    /* inner box holds the scrollbars*/
  380. X    narg = 0;
  381. X    common_tags(root,args,&narg,SET_BG|SET_BORDER);
  382. X    /* orient must be the opposite of that of the box */
  383. X    if (orient == XtorientHorizontal) {
  384. X        XtSetArg(args[narg], XtNorientation, XtorientVertical); narg++;
  385. X    } else {
  386. X        XtSetArg(args[narg], XtNorientation, XtorientHorizontal); narg++;
  387. X    }
  388. X    box2 = XtCreateManagedWidget("samplebox",boxWidgetClass,box,args,narg);
  389. X    
  390. X    /* use translations to update value whenever mouse leaves the box */
  391. X    XtAugmentTranslations(box2,XtParseTranslationTable(graph_trans));
  392. X
  393. X    /* label to indicate maximum value */
  394. X    narg = 0;
  395. X    XtSetArg(args[narg], XtNlabel, get_value(root,"max","1")); narg++;
  396. X    vlabel = XtCreateManagedWidget(object->name,labelWidgetClass,
  397. X                 box,args,narg);
  398. X
  399. X    /* allocate space to hold slider values and widget names */
  400. X    values = (float*) malloc ( graph_info->nsamp * sizeof(float));
  401. X    graph_info->widgets = (Widget*) 
  402. X              malloc ( graph_info->nsamp * sizeof(Widget));
  403. X
  404. X    /* get the string containing default values */
  405. X    valstring = get_value(root,"value","");
  406. X
  407. X    /* decode */
  408. X    parse_valuestring(valstring,values,graph_info->nsamp," \n\t");
  409. X
  410. X    graph_info->format = get_value(root,"format","%f");
  411. X    height = (int) atoi(get_value(root,"height","5"));
  412. X    width = (int) atoi(get_value(root,"width","100"));
  413. X    
  414. X    /* loop over sliders */
  415. X    for (isamp=0; isamp<graph_info->nsamp; isamp++) {
  416. X  
  417. X    /* determine the correct starting point for the sliders */
  418. X    narg = 0;
  419. X    top = values[isamp]/graph_info->maxval;
  420. X    if (sizeof(float) > sizeof(XtArgVal))
  421. X      {
  422. X      XtSetArg(args[narg], XtNtopOfThumb, top); narg++;
  423. X      }
  424. X    else
  425. X      {
  426. X      XtArgVal * l_top = (XtArgVal *) ⊤
  427. X      XtSetArg(args[narg], XtNtopOfThumb, *l_top); narg++;
  428. X      }
  429. X
  430. X    /* common parameters */
  431. X    common_tags(root,args,&narg,SET_FG|SET_BG);
  432. X
  433. X    /* height, width */
  434. X    /* done here instead of common_tags so we could have defaults */
  435. X    XtSetArg(args[narg], XtNlength, width); narg++;
  436. X    XtSetArg(args[narg], XtNthickness, height); narg++;
  437. X    /* turn off border */
  438. X    XtSetArg(args[narg], XtNborderWidth, 0); narg++;
  439. X    /* same orientation as outer box */
  440. X    XtSetArg(args[narg], XtNorientation, orient); narg++;
  441. X
  442. X    /* slider is actually an athena scrollbar widget */
  443. X    scrollbar = XtCreateManagedWidget(object->name,scrollbarWidgetClass,
  444. X                   box2,args,narg);
  445. X    
  446. X    /* scroll callback is for incremental scrolling with left and 
  447. X       right buttons */
  448. X    XtAddCallback( scrollbar, XtNscrollProc, graph_scroll_callback, 
  449. X          (XtPointer) object );
  450. X    
  451. X    /* set to the correct starting point */
  452. X    (void) XawScrollbarSetThumb(scrollbar,
  453. X    (values[isamp]-graph_info->minval)/
  454. X            (graph_info->maxval-graph_info->minval),-1.);
  455. X    
  456. X    graph_info->widgets[isamp] = scrollbar;
  457. X    }
  458. X    
  459. X    object->value = strdupl(valstring);
  460. X    object->widgetname = box2;
  461. X    object->updater = graph_update;
  462. X    
  463. }
  464. X
  465. void
  466. X  graph_scroll_callback(widget, client_data, pos_ptr)
  467. Widget widget;
  468. XXtPointer client_data, pos_ptr;
  469. {
  470. X    Arg arg[1];
  471. X    float top;
  472. X    int pos;
  473. X    pos = (int) pos_ptr;
  474. X    /* get the current position of the graph */
  475. X    XtSetArg( arg[0], XtNtopOfThumb, &top );
  476. X    XtGetValues( widget, arg, ONE );
  477. X    /* now compute new position - 5% change */
  478. X    top -= pos/abs(pos) * 0.05;
  479. X    if (top > 1.) top = 1.;
  480. X    if (top < 0.) top = 0.;
  481. X    /* update the graph */
  482. X    if (sizeof(float) > sizeof(XtArgVal))
  483. X      {
  484. X      XtSetArg(arg[0], XtNtopOfThumb, top);
  485. X      }
  486. X    else
  487. X      {
  488. X      XtArgVal * l_top = (XtArgVal *) ⊤
  489. X      XtSetArg(arg[0], XtNtopOfThumb, *l_top);
  490. X      }
  491. X    XtSetValues( widget, arg, ONE );
  492. }
  493. X
  494. void
  495. X  graph_update(object, value)
  496. Objdef *object;
  497. char *value;
  498. {
  499. X    struct graphinfo *graph_info;
  500. X    Arg arg[1];
  501. X    char text[10];
  502. X    float top,val;
  503. X    Dimension len;
  504. X    int pos;
  505. X    float *values;
  506. X    int isamp;
  507. X
  508. X    graph_info = (struct graphinfo *) object->info;
  509. X    values = (float*) malloc ( graph_info->nsamp * sizeof(float));
  510. X
  511. X    /* update value string */
  512. X    object->value = strdupl(value);
  513. X
  514. X    /* decode */
  515. X    parse_valuestring(value,values,graph_info->nsamp," \n\t");
  516. X
  517. X    /* loop over sliders */
  518. X    for (isamp=0; isamp<graph_info->nsamp; isamp++) {
  519. X
  520. X    top = (values[isamp] - graph_info->minval)/
  521. X             (graph_info->maxval-graph_info->minval);
  522. X    if (top > 1.) top = 1.;
  523. X    if (top < 0.) top = 0.;
  524. X    /* compute new value */
  525. X    sprintf( text, graph_info->format, 
  526. X        (float) graph_info->minval +
  527. X        top*(graph_info->maxval - graph_info->minval));
  528. X    /* update the graph */
  529. X    if (sizeof(float) > sizeof(XtArgVal))
  530. X      {
  531. X      XtSetArg(arg[0], XtNtopOfThumb, top);
  532. X      }
  533. X    else
  534. X      {
  535. X      XtArgVal * l_top = (XtArgVal *) ⊤
  536. X      XtSetArg(arg[0], XtNtopOfThumb, *l_top);
  537. X      }
  538. X    XtSetValues( graph_info->widgets[isamp], arg, ONE );
  539. X    }
  540. X    perform_actions(object->name,object->action,0);
  541. }
  542. X
  543. void parse_valuestring(valstring,values,nsamp,separator) 
  544. X    char *valstring;
  545. X    float *values;
  546. X    int nsamp;
  547. X    char *separator;
  548. {
  549. X    char *item;
  550. X    int isamp,jsamp;
  551. X
  552. X    for( item=strtok(valstring,separator),isamp=0;
  553. X         item != (char*)0 && isamp <nsamp ;
  554. X         item =strtok( (char*)0, separator ),isamp++){
  555. X        sscanf(item,"%f",&values[isamp]);
  556. X    }
  557. X
  558. X    /* if valstring does not contain enough samples, reuse the last one */
  559. X    if (isamp < nsamp) {
  560. X    for (jsamp=isamp; jsamp<nsamp; jsamp++) {
  561. X        values[jsamp] = values[isamp-1];
  562. X    }
  563. X    }
  564. }
  565. X
  566. /* callback used when graph button is pressed or cursor leaves graph */
  567. void
  568. graph_callback(widget, client_data, callData)
  569. Widget widget;
  570. XXtPointer client_data, callData;
  571. {
  572. X    Objdef *object;
  573. X    struct graphinfo *graph_info;
  574. X    Arg arg[1];
  575. X    char text[64];
  576. X    float top;
  577. X    Dimension len;
  578. X    int isamp;
  579. X    char *valstring;
  580. X    string_buf *buffer;
  581. X
  582. X    object = (Objdef *) client_data;
  583. X    graph_info = (struct graphinfo *) object->info;
  584. X
  585. X    /* loop over widgets */
  586. X    strcpy(object->value,"");
  587. X    buffer = buf_start();
  588. X
  589. X    for (isamp=0; isamp<graph_info->nsamp; isamp++) {
  590. X
  591. X    /* get the current position of the graph */
  592. X    XtSetArg( arg[0], XtNtopOfThumb, &top );
  593. X    XtGetValues( graph_info->widgets[isamp], arg, ONE );
  594. X
  595. X    /* turn it into text, add to value string */
  596. X    sprintf( text, graph_info->format, 
  597. X        (float) graph_info->minval +
  598. X        top*(graph_info->maxval - graph_info->minval));
  599. X    buf_cat( buffer,text,strlen(text));
  600. X    buf_cat( buffer," ",1);
  601. X    }
  602. X    object->value = buf_fetch(buffer);
  603. /*    buf_free(buffer);*/
  604. X
  605. X    perform_actions(object->name,object->action,1);
  606. }
  607. X
  608. /*
  609. X * this routine gets called whenever we leave
  610. X * a graph box, to be sure the graph's value is up to date
  611. X */
  612. void graph_update_callback( w, event, params, num_params)
  613. X     Widget w;
  614. X     XEvent *event;
  615. X     String *params;
  616. X     Cardinal *num_params;
  617. {
  618. X    Objdef* object;
  619. X    struct graphinfo *graph_info;
  620. X    char *value;
  621. X    Arg arg[1];
  622. X    int narg;
  623. X    int isamp;
  624. X    float top;
  625. X    char text[64];
  626. X    Dimension len;
  627. X    char *valstring;
  628. X    string_buf *buffer;
  629. X
  630. X    object = find_by_widget(w);
  631. X    graph_info = (struct graphinfo *) object->info;
  632. X
  633. X    /* loop over widgets */
  634. X    strcpy(object->value,"");
  635. X    buffer = buf_start();
  636. X
  637. X    for (isamp=0; isamp<graph_info->nsamp; isamp++) {
  638. X
  639. X    /* get the current position of the graph */
  640. X    XtSetArg( arg[0], XtNtopOfThumb, &top );
  641. X    XtGetValues( graph_info->widgets[isamp], arg, ONE );
  642. X
  643. X    /* turn it into text, add to value string */
  644. X    sprintf( text, graph_info->format, 
  645. X        (float) graph_info->minval +
  646. X        top*(graph_info->maxval - graph_info->minval));
  647. X    buf_cat( buffer,text,strlen(text));
  648. X    buf_cat( buffer," ",1);
  649. X    }
  650. X    object->value = buf_fetch(buffer);
  651. X
  652. }
  653. SHAR_EOF
  654. chmod 0664 xtpanel/graph.c ||
  655. echo 'restore of xtpanel/graph.c failed'
  656. Wc_c="`wc -c < 'xtpanel/graph.c'`"
  657. test 11318 -eq "$Wc_c" ||
  658.     echo 'xtpanel/graph.c: original size 11318, current size' "$Wc_c"
  659. fi
  660. # ============= xtpanel/README.OW3 ==============
  661. if test -f 'xtpanel/README.OW3' -a X"$1" != X"-c"; then
  662.     echo 'x - skipping xtpanel/README.OW3 (File already exists)'
  663. else
  664. echo 'x - extracting xtpanel/README.OW3 (Text)'
  665. sed 's/^X//' << 'SHAR_EOF' > 'xtpanel/README.OW3' &&
  666. X
  667. X
  668. How to build xtpanel under Openwindows-3 (SUN OS-4.1.1) without changing
  669. SUN's #$!&*# imake configuration files.
  670. X
  671. X
  672. Then (all on one line):
  673. X
  674. X  /usr/openwin/bin/imake -DUseInstalled  -DLibDir=/usr/openwin/lib \
  675. X  -DIncRoot=/usr/openwin/include   -DOW3
  676. X
  677. Then:
  678. X
  679. X  make Makefiles
  680. X
  681. Then:
  682. X
  683. X   make
  684. X
  685. (cross your fingers!)
  686. X
  687. SHAR_EOF
  688. chmod 0664 xtpanel/README.OW3 ||
  689. echo 'restore of xtpanel/README.OW3 failed'
  690. Wc_c="`wc -c < 'xtpanel/README.OW3'`"
  691. test 317 -eq "$Wc_c" ||
  692.     echo 'xtpanel/README.OW3: original size 317, current size' "$Wc_c"
  693. fi
  694. exit 0
  695. -----------------------------------------------------------------
  696. Steve Cole  (steve@sep.stanford.edu, apple!sep!steve)
  697. Department of Geophysics, Stanford University, Stanford, CA 94305
  698.