home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff386.lzh / XLispStat / src3.lzh / Mac / macdialogs2.c < prev    next >
C/C++ Source or Header  |  1990-07-30  |  22KB  |  787 lines

  1. /* macdialogs2 - Low Level Dialog Objects for Macintosh                */
  2. /* XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney                  */
  3. /* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz    */
  4. /* You may give out copies of this software; for conditions see the    */
  5. /* file COPYING included with this distribution.                       */
  6.  
  7. # include "dialogs.h"
  8. static int jump_to_top;
  9.  
  10. /* layout definitions */
  11. # define FONT_HEIGHT 16
  12. # define FONT_WIDTH_GUESS 9
  13. # define FONT_POINTS 12
  14.  
  15. # define BUTTON_HEIGHT 20
  16. # define BUTTON_WIDTH 90
  17. # define BUTTON_PAD 15
  18.  
  19. # define TOGGLE_PAD 20
  20. # define TOGGLE_HEIGHT FONT_HEIGHT - 2
  21.  
  22. # define EDIT_TEXT_PAD 20
  23. # define EDIT_TEXT_HEIGHT 20
  24. # define STATIC_TEXT_PAD 20
  25. # define STATIC_TEXT_HEIGHT FONT_HEIGHT
  26.  
  27. # define CHOICE_HEIGHT 20
  28. # define CHOICE_PAD 20
  29.  
  30. # define SCROLL_WIDTH 180
  31. # define SCROLL_HEIGHT 16
  32.  
  33. # define LIST_ITEM_HEIGHT 16
  34. # define MAX_LIST_ROWS 12
  35.  
  36. /***********************************************************************/
  37. /***********************************************************************/
  38. /**                                                                   **/
  39. /**                       Internal Dialog Functions                   **/
  40. /**                                                                   **/
  41. /***********************************************************************/
  42. /***********************************************************************/
  43.  
  44. /***********************************************************************/
  45. /**                                                                   **/
  46. /**                          Utility Functions                        **/
  47. /**                                                                   **/
  48. /***********************************************************************/
  49.  
  50. static GrafPort GP;
  51. static GrafPtr port = nil;
  52.  
  53. static Point StringSize(s)
  54.     char *s;
  55. {
  56.   Point pt;
  57.   GrafPtr savePort;
  58.   
  59.   if (port == nil) {
  60.     GetPort(&savePort);
  61.     port = &GP;
  62.     OpenPort(port);
  63.     port->txFont = systemFont;
  64.     port->txSize = FONT_POINTS;
  65.     SetPort(savePort);
  66.   }
  67.   
  68.   pt.v = FONT_HEIGHT;
  69.   if (port == nil) pt.h = FONT_WIDTH_GUESS * strlen(s);
  70.   else {
  71.     GetPort(&savePort);
  72.     SetPort(port);
  73.     CtoPstr(s);
  74.     pt.h = StringWidth(s);
  75.     PtoCstr(s);
  76.     SetPort(savePort);
  77.   }
  78.   return(pt);
  79. }
  80.  
  81. /***********************************************************************/
  82. /**                                                                   **/
  83. /**                         Callback Functions                        **/
  84. /**                                                                   **/
  85. /***********************************************************************/
  86.  
  87. static Boolean listClick(item, event, theDialog)
  88.     int item;
  89.     EventRecord *event;
  90.     DialogPtr theDialog;
  91. {
  92.   LVAL object;
  93.   int itemType;
  94.   ListHandle theItem;
  95.   Point pt;
  96.   Boolean list_click = false, double_click;
  97.   GrafPtr savePort;
  98.   DialogItemData *data;
  99.   
  100.   if (item > 1 && item <= DialogItemCount(theDialog) 
  101.       && event->what == mouseDown) {
  102.     data = GetDialogItemData(theDialog);
  103.     theItem = (ListHandle) data[item - 1].itemHandle;
  104.     itemType = data[item - 1].type;
  105.     object = data[item - 1].object;
  106.     
  107.     if (itemType == LIST_ITEM) {
  108.       list_click = true;
  109.       pt = event->where;
  110.       GetPort(&savePort);
  111.       SetPort(theDialog);
  112.       GlobalToLocal(&pt);
  113.       SetPort(savePort);
  114.       double_click = LClick(pt, event->modifiers, theItem);
  115.       if (double_click) {
  116.         send_message_1L(object, sk_do_action, s_true);
  117.       }
  118.     }
  119.   }  
  120.   return(list_click);
  121. }
  122.  
  123. static pascal char modalFilter(theDialog, theEvent, itemHit)
  124.     DialogPtr theDialog;
  125.     EventRecord *theEvent;
  126.     short *itemHit;
  127. {
  128.   char c;
  129.   char result;
  130.   
  131.   c = theEvent->message & charCodeMask;
  132.   if ((theEvent->modifiers & cmdKey) && (c == '.')) {
  133.     jump_to_top = true;
  134.     result = (char) true;
  135.     *itemHit = 0;
  136.   }
  137.   else if (theEvent->what == keyDown && c == RETURNCHAR) {
  138.       result = true;
  139.       *itemHit = ((DialogPeek) theDialog)->aDefItem;
  140.   }
  141.   else {
  142.     *itemHit = FindItemHit(theEvent->where, theDialog);
  143.     result = (char) listClick(*itemHit, theEvent, theDialog);
  144.   }
  145.   return(result);
  146. }
  147.  
  148. /* Action proc for scroll bars. */
  149. static pascal void scrollAction(theControl, partCode)
  150.     ControlHandle theControl;
  151.     short partCode;
  152. {
  153.   LVAL scroll = (LVAL) GetCRefCon(theControl);
  154.   int page, value;
  155.   GrafPtr savePort;
  156.   
  157.   if (! scroll_item_p(scroll)) return;
  158.   page = getfixnum(slot_value(scroll, s_page_increment));
  159.   
  160.   value = GetCtlValue(theControl);
  161.   switch (partCode) {
  162.   case inUpButton:   value--; break;
  163.   case inDownButton: value++; break;
  164.   case inPageUp:     value -= page; break;
  165.   case inPageDown:   value += page; break;
  166.   }
  167.   SetCtlValue(theControl, value);
  168.   set_slot_value(scroll, s_value, cvfixnum((FIXTYPE) value));
  169.   
  170.   GetPort(&savePort);
  171.   send_message(scroll, sk_scroll_action);
  172.   SetPort(savePort);
  173. }
  174.  
  175.  
  176. static TrackScroll(theDialog, item)
  177.     DialogPtr theDialog;
  178.     int item;
  179. {
  180.   DialogItemData *data;
  181.   ControlHandle theScroll;
  182.   LVAL scroll;
  183.   Point pt;
  184.   int part, value;
  185.   
  186.   data = GetDialogItemData(theDialog);
  187.   theScroll = (ControlHandle) data[item - 1].itemHandle;
  188.   
  189.   GetMouse(&pt);
  190.   part = TestControl(theScroll, pt);
  191.   if (part == inThumb) {
  192.       TrackControl(theScroll, pt, nil);
  193.     scroll = (LVAL) GetCRefCon(theScroll);
  194.     value = GetCtlValue(theScroll);
  195.     set_slot_value(scroll, s_value, cvfixnum((FIXTYPE) value));
  196.   }
  197.   else if (part != 0) TrackControl(theScroll, pt, (ProcPtr) scrollAction);
  198.   FlushEvents(mDownMask | mUpMask, 0);
  199.   
  200.   return (part != inThumb);
  201. }
  202.  
  203. doDialog(theItem, theEvent)
  204.     int theItem;
  205.     EventRecord *theEvent;
  206. {
  207.   GrafPtr port;
  208.   LVAL item;
  209.   DialogItemData *data;
  210.   int type;
  211.   ControlHandle itemHandle;
  212.   
  213.   GetPort(&port);
  214.   
  215.   data = GetDialogItemData(port);
  216.   item = data[theItem - 1].object;
  217.   type = data[theItem - 1].type;
  218.   itemHandle = (ControlHandle) data[theItem - 1].itemHandle;
  219.   
  220.   switch (type) {
  221.   case TOGGLE_ITEM: 
  222.     SetCtlValue(itemHandle, ! GetCtlValue(itemHandle));
  223.     set_slot_value(item, s_value, (GetCtlValue(itemHandle)) ? s_true : NIL);
  224.     break;
  225.   case CHOICE_ITEM:
  226.     SetClusterValue(port, theItem);
  227.     break;
  228.   case SCROLL_ITEM:
  229.     if (TrackScroll(port, theItem)) return; /* no message unless in thumb */
  230.     break;
  231.   }
  232.   
  233.   if (objectp(item) && theItem > 1 
  234.       && ! listClick(theItem, theEvent, port)) {
  235.     send_message(item, sk_do_action);
  236.   }
  237. }
  238.  
  239. closeDialog()
  240. {
  241.   GrafPtr port;
  242.   LVAL object;
  243.     
  244.   GetPort(&port);
  245.   object = GetDialogObject(port);
  246.   send_message(object, sk_close);
  247. }
  248.  
  249. activateDialog(active)
  250.     int active;
  251. {
  252.   GrafPtr port;
  253.   LVAL object;
  254.     
  255.   GetPort(&port);
  256.   object = GetDialogObject(port);
  257.   send_message_1L(object, sk_activate, (active) ? s_true : NIL);
  258. }
  259.  
  260. clobberDialog()
  261. {
  262.   GrafPtr port;
  263.   LVAL object;
  264.   Handle ref;
  265.   DialogItemData *data;
  266.   int i;
  267.     
  268.   GetPort(&port);
  269.   object = GetDialogObject(port);
  270.   ref = (Handle) GetWRefCon(port);
  271.   if (ref != nil) {
  272.     for (i = 0; i < DialogItemCount(port); i++)
  273.       data = GetDialogItemData(port);
  274.       switch(data[i].type) {
  275.       case SCROLL_ITEM: DisposeControl((ControlHandle) data[i].itemHandle); break;
  276.       case LIST_ITEM:   LDispose((ListHandle) data[i].itemHandle); break;
  277.       }
  278.     DisposHandle(ref);
  279.   }
  280.   DisposDialog(port);
  281.   if (objectp(object)) standard_hardware_clobber(object);
  282. }
  283.  
  284. static FindItemHit(pt, theDialog)
  285.     Point pt;
  286.     DialogPtr theDialog;
  287. {
  288.   GrafPtr savePort;
  289.   short itemType;
  290.   int i, itemHit;
  291.   Handle theItem;
  292.   Rect r;
  293.   
  294.   GetPort(&savePort);
  295.   SetPort(theDialog);
  296.   GlobalToLocal(&pt);
  297.   SetPort(savePort);
  298.   
  299.   itemHit = 0;
  300.   for (i = 1; i <= DialogItemCount(theDialog) && itemHit == 0; i++) {
  301.     GetDItem(theDialog, i, &itemType, &theItem, &r);
  302.     if (PtInRect(pt, &r))  itemHit = i;
  303.   }
  304.   return(itemHit);
  305. }
  306.  
  307. static SetClusterValue(theDialog, item)
  308.     DialogPtr theDialog;
  309.     int item;
  310. {
  311.   int i, n, leader;
  312.   DialogItemData *data;
  313.   ControlHandle itemHandle;
  314.   
  315.   data = GetDialogItemData(theDialog);
  316.   leader = data[item - 1].clusterLeader;
  317.   n = data[item - 1].clusterSize + leader;
  318.   itemHandle = (ControlHandle) data[item - 1].itemHandle;
  319.   
  320.   for (i = leader; i < n; i++) {
  321.     data = GetDialogItemData(theDialog);
  322.     SetCtlValue((ControlHandle) data[i - 1].itemHandle, 0);
  323.   }
  324.   SetCtlValue(itemHandle, 1);
  325. }
  326.  
  327.  
  328. /***********************************************************************/
  329. /***********************************************************************/
  330. /**                                                                   **/
  331. /**                        Public Dialog Functions                    **/
  332. /**                                                                   **/
  333. /***********************************************************************/
  334. /***********************************************************************/
  335.  
  336. /***********************************************************************/
  337. /**                                                                   **/
  338. /**                           Dialog Functions                        **/
  339. /**                                                                   **/
  340. /***********************************************************************/
  341.  
  342. LVAL DialogGetModalItem(dialog)
  343.     LVAL dialog;
  344. {
  345.   DialogPtr theDialog;
  346.   LVAL item;
  347.   short itemNumber;
  348.   int type;
  349.   DialogItemData *data;
  350.   ControlHandle itemHandle;
  351.   
  352.   theDialog = (DialogPtr) GETDIALOGADDRESS(dialog);
  353.   if (theDialog == nil) xlfail("the dialog is not visible");
  354.   
  355.   SetCursor(&arrow);
  356.   MyShowWindow(theDialog);
  357.   ModalDialog((ModalFilterProcPtr) modalFilter, &itemNumber);
  358.   if (jump_to_top) {
  359.     jump_to_top = false;
  360.     FlushEvents (everyEvent - diskMask, 0 );
  361.     xltoplevel();
  362.   }
  363.  
  364.   if (itemNumber < 1 || itemNumber > DialogItemCount(theDialog))
  365.     xlfail("invalid item number");
  366.  
  367.   data = GetDialogItemData(theDialog);
  368.   type = data[itemNumber - 1].type;
  369.   itemHandle = (ControlHandle) data[itemNumber - 1].itemHandle;
  370.   item = data[itemNumber - 1].object;
  371.   
  372.   switch (type) {
  373.   case TOGGLE_ITEM: 
  374.     SetCtlValue(itemHandle, ! GetCtlValue(itemHandle));
  375.     set_slot_value(item, s_value, (GetCtlValue(itemHandle)) ? s_true : NIL);
  376.     break;
  377.   case CHOICE_ITEM:
  378.     SetClusterValue(theDialog, itemNumber);
  379.     break;
  380.   case SCROLL_ITEM:
  381.     TrackScroll(theDialog, itemNumber);
  382.     break;
  383.   }
  384.   
  385.   return(item);
  386. }
  387.  
  388. /***********************************************************************/
  389. /**                                                                   **/
  390. /**                         Button Item Functions                     **/
  391. /**                                                                   **/
  392. /***********************************************************************/
  393.  
  394. DialogButtonGetDefaultSize(item, width, height)
  395.     LVAL item;
  396.     int *width, *height;
  397. {
  398.   LVAL text = slot_value(item, s_text);
  399.   Point sz;
  400.   
  401.   if (! stringp(text)) xlerror("not a string", text);
  402.   sz = StringSize(getstring(text));
  403.   
  404.   if (width != nil) *width = max(sz.h + BUTTON_PAD, BUTTON_WIDTH);
  405.   if (height != nil) *height = BUTTON_HEIGHT;
  406. }
  407.  
  408. /***********************************************************************/
  409. /**                                                                   **/
  410. /**                         Toggle Item Functions                     **/
  411. /**                                                                   **/
  412. /***********************************************************************/
  413.  
  414. DialogToggleGetDefaultSize(item, width, height)
  415.     LVAL item;
  416.     int *width, *height;
  417. {
  418.   Point sz;
  419.   sz = StringSize(getstring(slot_value(item, s_text)));
  420.   if (width != nil) *width = sz.h + TOGGLE_PAD;
  421.   if (height != nil) *height = TOGGLE_HEIGHT;
  422. }
  423.  
  424. LVAL DialogToggleItemValue(item, set, value)
  425.     LVAL item, value;
  426.     int set;
  427. {
  428.   LVAL dialog;
  429.   DialogItemData itemData;
  430.   DialogPtr theDialog;
  431.  
  432.   dialog = slot_value(item, s_dialog);
  433.   if (set) set_slot_value(item, s_value, (value != NIL) ?  s_true : NIL);
  434.  
  435.   theDialog = (DialogPtr) GETDIALOGADDRESS(dialog);
  436.   if (theDialog != nil) {
  437.     itemData = FindItemData(theDialog, item);
  438.     if (set) SetCtlValue((ControlHandle) itemData.itemHandle,
  439.                          (value != NIL) ? true : false);
  440.   }
  441.   return(slot_value(item, s_value));
  442. }
  443.  
  444. /***********************************************************************/
  445. /**                                                                   **/
  446. /**                         Text Item Functions                       **/
  447. /**                                                                   **/
  448. /***********************************************************************/
  449.  
  450. DialogTextGetDefaultSize(item, width, height)
  451.     LVAL item;
  452.     int *width, *height;
  453. {
  454.   Point sz;
  455.   LVAL text = slot_value(item, s_text);
  456.   LVAL text_length = slot_value(item, xlenter("TEXT-LENGTH"));
  457.   int w = 0;
  458.   char *s;
  459.   
  460.   if (stringp(text)) {
  461.     w = max_line_size(getstring(text));
  462.     s = (char *) getstring(text);
  463.     for (sz.v = STATIC_TEXT_HEIGHT; *s != '\0'; s++)
  464.       if (*s == '\n' || *s == '\r') sz.v += STATIC_TEXT_HEIGHT;
  465.   }
  466.   if (fixp(text_length)) {
  467.     sz = StringSize("M");
  468.     w = max((int) (getfixnum(text_length) * sz.h), w);
  469.   }
  470.   if (slot_value(item, s_editable) != NIL) {
  471.     if (width != nil) *width = w + EDIT_TEXT_PAD;
  472.     if (height != nil) *height = EDIT_TEXT_HEIGHT;
  473.   }
  474.   else {
  475.     if (width != nil) *width = w + STATIC_TEXT_PAD;
  476.     if (height != nil) *height = sz.v /* STATIC_TEXT_HEIGHT */;
  477.   }
  478. }
  479.  
  480. LVAL DialogTextItemText(item, set, text)
  481.     LVAL item;
  482.     int set;
  483.     char *text;
  484. {
  485.   LVAL dialog;
  486.   DialogItemData itemData;
  487.   DialogPtr theDialog;
  488.  
  489.   
  490.   if (set) set_slot_value(item, s_text, make_string(text));
  491.   dialog = slot_value(item, s_dialog);
  492.   theDialog = (DialogPtr) GETDIALOGADDRESS(dialog);
  493.  
  494.   if (theDialog != nil) {
  495.     itemData = FindItemData(theDialog, item);
  496.     if (set) {
  497.       strcpy(buf, text);
  498.       convert_newlines(buf);
  499.       CtoPstr(buf);
  500.       SetIText(itemData.itemHandle, buf);
  501.     }
  502.     GetIText(itemData.itemHandle, buf);
  503.     PtoCstr(buf);
  504.     set_slot_value(item, s_text, make_string(buf));
  505.   }
  506.   return(slot_value(item, s_text));
  507. }
  508.  
  509. /***********************************************************************/
  510. /**                                                                   **/
  511. /**                         Choice Item Functions                     **/
  512. /**                                                                   **/
  513. /***********************************************************************/
  514.  
  515. DialogChoiceGetDefaultSize(item, width, height)
  516.     LVAL item;
  517.     int *width, *height;
  518. {
  519.   Point sz, pt;
  520.   LVAL text = slot_value(item, s_text);
  521.   
  522.   for (sz.h = 0, sz.v = 0; consp(text); text = cdr(text)) {
  523.     pt = StringSize(getstring(car(text)));
  524.     sz.h = max(sz.h, pt.h);
  525.     sz.v += CHOICE_HEIGHT;
  526.   }
  527.   if (width != nil) *width = sz.h + CHOICE_PAD;
  528.   if (height != nil) *height = sz.v;
  529. }
  530.  
  531. LVAL DialogChoiceItemValue(item, set, value)
  532.     LVAL item;
  533.     int set, value;
  534. {
  535.   LVAL result, dialog;
  536.   DialogItemData itemData, *data;
  537.   DialogPtr theDialog;
  538.   int leader, i, n;
  539.   
  540.   if (set) set_slot_value(item, s_value, cvfixnum((FIXTYPE) value));
  541.   
  542.   dialog = slot_value(item, s_dialog);
  543.   theDialog = (DialogPtr) GETDIALOGADDRESS(dialog);
  544.   if (theDialog != nil) {
  545.     itemData = FindItemData(theDialog, item);
  546.     leader = itemData.clusterLeader;
  547.     n = itemData.clusterSize;
  548.   
  549.     if (set) {
  550.       if (value < 0 || value >= n) xlfail("value out of range");
  551.       for (i = 0; i < n; i++) {
  552.         data = GetDialogItemData(theDialog);
  553.         itemData = data[leader + i - 1];
  554.         SetCtlValue((ControlHandle) itemData.itemHandle, 0);
  555.       }
  556.       data = GetDialogItemData(theDialog);
  557.       itemData = data[leader + value - 1];
  558.       SetCtlValue((ControlHandle) itemData.itemHandle, 1);
  559.     }
  560.     result = NIL;
  561.     for (i = 0; i < n && result == NIL; i++) {
  562.       data = GetDialogItemData(theDialog);
  563.       itemData = data[leader + i - 1];  
  564.       result = (GetCtlValue((ControlHandle) itemData.itemHandle))
  565.              ? cvfixnum((FIXTYPE) i) : NIL;
  566.     }
  567.     set_slot_value(item, s_value, result);
  568.   }
  569.   
  570.   return(slot_value(item, s_value));
  571. }
  572.  
  573. /***********************************************************************/
  574. /**                                                                   **/
  575. /**                         Scroll Item Functions                     **/
  576. /**                                                                   **/
  577. /***********************************************************************/
  578.  
  579. DialogScrollGetDefaultSize(item, width, height)
  580.     LVAL item;
  581.     int *width, *height;
  582. {
  583.   if (width != nil) *width = SCROLL_WIDTH;
  584.   if (height != nil) *height = SCROLL_HEIGHT;
  585. }
  586.  
  587. static LVAL scroll_item_value(item, set, value, which)
  588.     LVAL item;
  589.     int set, value, which;
  590. {
  591.   LVAL dialog, result, slot;
  592.   DialogItemData itemData;
  593.   DialogPtr theDialog;
  594.   
  595.   dialog = slot_value(item, s_dialog);
  596.   theDialog = (DialogPtr) GETDIALOGADDRESS(dialog);
  597.  
  598.   if (theDialog != nil) {
  599.     itemData = FindItemData(theDialog, item);
  600.   
  601.     switch (which) {
  602.     case 'V':
  603.       if (set) SetCtlValue((ControlHandle) itemData.itemHandle, value);
  604.       value = GetCtlValue((ControlHandle) itemData.itemHandle);
  605.       break;
  606.     case 'H':
  607.       if (set) SetCtlMax((ControlHandle) itemData.itemHandle, value);
  608.       value = GetCtlMax((ControlHandle) itemData.itemHandle);
  609.       break;
  610.     case 'L':
  611.       if (set) SetCtlMin((ControlHandle) itemData.itemHandle, value);
  612.       value = GetCtlMin((ControlHandle) itemData.itemHandle);
  613.       break;
  614.     }
  615.   }
  616.   switch (which) {
  617.   case 'V': slot = s_value; break;
  618.   case 'H': slot = s_max_value; break;
  619.   case 'L': slot = s_min_value; break;
  620.   }
  621.   if (set || theDialog != nil) {
  622.     result = cvfixnum((FIXTYPE) value);
  623.     set_slot_value(item, slot, result);
  624.   }
  625.   else result = slot_value(item, slot);
  626.   
  627.   return (result);
  628. }
  629.  
  630. LVAL DialogScrollItemValue(item, set, value)
  631.     LVAL item;
  632.     int set, value;
  633. {
  634.   return(scroll_item_value(item, set, value, 'V'));
  635. }
  636.  
  637. LVAL DialogScrollItemMax(item, set, value)
  638.     LVAL item;
  639.     int set, value;
  640. {
  641.   return(scroll_item_value(item, set, value, 'H'));
  642. }
  643.  
  644. LVAL DialogScrollItemMin(item, set, value)
  645.     LVAL item;
  646.     int set, value;
  647. {
  648.   return(scroll_item_value(item, set, value, 'L'));
  649. }
  650.  
  651. /***********************************************************************/
  652. /**                                                                   **/
  653. /**                          List Item Functions                      **/
  654. /**                                                                   **/
  655. /***********************************************************************/
  656.  
  657. DialogListGetDefaultSize(item, width, height)
  658.     LVAL item;
  659.     int *width, *height;
  660. {
  661.   LVAL columns = slot_value(item, s_columns);
  662.   LVAL data = slot_value(item, s_list_data);
  663.   Point sz;
  664.  
  665.   if (listp(data)) sz.v = LIST_ITEM_HEIGHT * llength(data);
  666.   else if (simplevectorp(data)) sz.v = LIST_ITEM_HEIGHT * getsize(data);
  667.   else if (matrixp(data)) 
  668.     sz.v = 16 * getfixnum(getelement(displacedarraydim(data), 0));
  669.   sz.v = min(sz.v, MAX_LIST_ROWS * LIST_ITEM_HEIGHT);
  670.   if (matrixp(data) 
  671.       && getfixnum(getelement(displacedarraydim(data), 1)) 
  672.          > getfixnum(columns))
  673.     sz.v += 15;
  674.   sz.h = 150 * getfixnum(columns);
  675.   if (width != nil) *width = sz.h;
  676.   if (height != nil) *height = sz.v;
  677. }
  678.  
  679. DialogListItemSetText(item, index, text)
  680.     LVAL item, index;
  681.     char *text;
  682. {
  683.   LVAL dialog, listData;
  684.   DialogItemData itemData;
  685.   DialogPtr theDialog;
  686.   Point cell;
  687.   ListHandle theList;
  688.   int temp;
  689.     
  690.   listData = slot_value(item, s_list_data);
  691.   if (matrixp(listData)) {
  692.     cell = ListToPoint(index);
  693.       temp = cell.h; cell.h = cell.v; cell.v = temp;
  694.   }
  695.   else {
  696.       if (! fixp(index)) xlerror("not an integer", index);
  697.       cell.h = 0; cell.v = getfixnum(index);
  698.   }
  699.  
  700.   dialog = slot_value(item, s_dialog);
  701.   theDialog = (DialogPtr) GETDIALOGADDRESS(dialog);
  702.   if (theDialog != nil) {
  703.     itemData = FindItemData(theDialog, item);
  704.     theList = (ListHandle) itemData.itemHandle;
  705.  
  706.     strcpy(buf, text);
  707.     truncateListEntry(buf);
  708.     LSetCell(buf, strlen(buf), cell, theList);
  709.     check_alloc(theList, true);
  710.   }
  711. }
  712.  
  713. LVAL DialogListItemSelection(item, set, index)
  714.     LVAL item, index;
  715.     int set;
  716. {
  717.   LVAL dialog, result, listData;
  718.   DialogPtr theDialog;
  719.   DialogItemData itemData;
  720.   Point cell, new_cell;
  721.   int unselect = false;
  722.   ListHandle theList;
  723.   int temp;
  724.   
  725.   listData = slot_value(item, s_list_data);
  726.   if (set) {
  727.       if (index == NIL) unselect = true;
  728.       else {
  729.         unselect = false;
  730.         if (matrixp(listData)) {
  731.           cell = ListToPoint(index);
  732.           temp = cell.h; cell.h = cell.v; cell.v = temp;
  733.         }
  734.         else {
  735.           if (! fixp(index)) xlerror("not an integer", index);
  736.           cell.h = 0; cell.v = getfixnum(index);
  737.         }
  738.       }
  739.   }
  740.   new_cell = cell;
  741.   
  742.   dialog = slot_value(item, s_dialog);
  743.   theDialog = (DialogPtr) GETDIALOGADDRESS(dialog);
  744.   if (theDialog != nil) {
  745.     itemData = FindItemData(theDialog, item);
  746.     theList = (ListHandle) itemData.itemHandle;
  747.   
  748.     cell.h = 0; cell.v = 0;
  749.     if (set && LGetSelect(true, &cell, theList))
  750.       LSetSelect(false, cell, theList);
  751.     if (set && ! unselect) LSetSelect(true, new_cell, theList);
  752.  
  753.     cell.h = 0; cell.v = 0;
  754.     if (LGetSelect(true, &cell, theList)) {
  755.       if (unselect) {
  756.         LSetSelect(false, cell, theList);
  757.         result = NIL;
  758.       }
  759.       else {
  760.         if (matrixp(listData)) result = integer_list_2(cell.v, cell.h);
  761.         else result = cvfixnum((FIXTYPE) cell.v);
  762.       }
  763.     }
  764.     else result = NIL;
  765.   }
  766.   else result = NIL;
  767.   
  768.   return(result);
  769. }
  770.  
  771. static max_line_size(s)
  772.     char *s;
  773. {
  774.   char *bp;
  775.   int w;
  776.   Point sz;
  777.   
  778.   for (w = 0; *s != '\0'; *s++) {
  779.     for (bp = buf; *s != '\0' && *s != '\r' && *s != '\n'; s++, bp++)
  780.       *bp = *s;
  781.     *bp = '\0';
  782.     sz = StringSize(buf);
  783.     w = max(w, sz.h);
  784.   }
  785.   return(w);
  786. }
  787.