home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / tcl / tclmotif.1 / tclmotif / tm.1.2 / src / tmExpand.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-03  |  15.7 KB  |  589 lines

  1. /*
  2.  * tmExpand.c --
  3.  *    This module handles % expansions of callback data
  4.  *
  5.  * Copyright 1993 Jan Newmarch, University of Canberra.
  6.  * Permission to use, copy, modify, and distribute this
  7.  * software and its documentation for any purpose and without
  8.  * fee is hereby granted, provided that the above copyright
  9.  * notice appear in all copies.  The author
  10.  * makes no representations about the suitability of this
  11.  * software for any purpose.  It is provided "as is" without
  12.  * express or implied warranty.
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <ctype.h>
  18. #include "tm.h"
  19.  
  20. #include <Xm/ArrowB.h>
  21. #include <Xm/Command.h>
  22. #include <Xm/DrawnB.h>
  23. #include <Xm/FileSB.h>
  24. #include <Xm/List.h>
  25. #include <Xm/PushB.h>
  26. #include <Xm/Scale.h>
  27. #include <Xm/ScrollBar.h>
  28. #include <Xm/SelectioB.h>
  29. #include <Xm/Text.h>
  30. #include <Xm/ToggleB.h>
  31. #ifndef MOTIF11
  32. #include <Xm/DragDrop.h>
  33. #endif
  34.  
  35. /*
  36.  *--------------------------------------------------------------
  37.  *
  38.  * getValue --
  39.  *
  40.  *    Get the value of a field from out of the callback data.
  41.  *
  42.  * Results:
  43.  *
  44.  *    places the string value in "value"
  45.  *
  46.  * Side effects:
  47.  *
  48.  *--------------------------------------------------------------
  49.  */
  50.  
  51. static char *
  52. getValue(pathName, w, event, call_data, value, length)
  53.     char *pathName;
  54.     Widget w;
  55.     XEvent *event;
  56.     XtPointer call_data;
  57.     char *value;
  58.     int length;
  59. {
  60.     char *result;
  61.     XrmValue from, to;
  62.     static char buf[32];
  63.     WidgetClass class;
  64.  
  65.     if (length == strlen("w") &&
  66.         strncmp(value, "w", length) == 0) {
  67.     return pathName;
  68.     }
  69.  
  70.     if (length == strlen("dragContext") &&
  71.         strncmp(value, "dragContext", length) == 0) {
  72.     return pathName;
  73.     }
  74.  
  75.     if (length == strlen("event") &&
  76.         strncmp(value, "event", length) == 0) {
  77.     sprintf(buf, "event-%lu", (long) event);
  78.     return buf;
  79.     }
  80.  
  81.     /* the reasons are widget specific, but get them over with at
  82.        the start all at once anyway since they overlap a lot
  83.      */
  84.     if (length == strlen("reason") &&
  85.         strncmp(value, "reason", length) == 0) {
  86.     XmAnyCallbackStruct *c_data = (XmAnyCallbackStruct *) call_data;
  87.  
  88.     switch (c_data->reason) {
  89.         case XmCR_NONE:            return "none";
  90.         case XmCR_HELP:            return "help";
  91.         case XmCR_VALUE_CHANGED:        return "value_changed";
  92.         case XmCR_INCREMENT:        return "increment";
  93.         case XmCR_DECREMENT:        return "decrement";
  94.         case XmCR_PAGE_INCREMENT:        return "page_increment";
  95.         case XmCR_PAGE_DECREMENT:        return "page_decrement";
  96.         case XmCR_TO_TOP:            return "to_top";
  97.         case XmCR_TO_BOTTOM:        return "to_bottom";
  98.         case XmCR_DRAG:            return "drag";
  99.         case XmCR_ACTIVATE:            return "activate";
  100.         case XmCR_ARM:            return "arm";
  101.         case XmCR_DISARM:            return "disarm";
  102.         case XmCR_MAP:            return "map";
  103.         case XmCR_UNMAP:            return "unmap";
  104.         case XmCR_FOCUS:            return "focus";
  105.         case XmCR_LOSING_FOCUS:        return "losing_focus";
  106.         case XmCR_MODIFYING_TEXT_VALUE:    return "modifying_text_value";
  107.         case XmCR_MOVING_INSERT_CURSOR:    return "moving_insert_cursor";
  108.         case XmCR_EXECUTE:            return "execute";
  109.         case XmCR_SINGLE_SELECT:        return "single_select";
  110.         case XmCR_MULTIPLE_SELECT:        return "multiple_select";
  111.         case XmCR_EXTENDED_SELECT:        return "extended_select";
  112.         case XmCR_BROWSE_SELECT:        return "browse_select";
  113.         case XmCR_DEFAULT_ACTION:        return "default_action";
  114.         case XmCR_CLIPBOARD_DATA_REQUEST:    return "clipboard_data_request";
  115.         case XmCR_CLIPBOARD_DATA_DELETE:    return "clipboard_data_delete";
  116.         case XmCR_CASCADING:        return "cascading";
  117.         case XmCR_OK:            return "ok";
  118.         case XmCR_CANCEL:            return "cancel";
  119.         case XmCR_APPLY:            return "apply";
  120.         case XmCR_NO_MATCH:            return "no_match";
  121.         case XmCR_COMMAND_ENTERED:        return "command_entered";
  122.         case XmCR_COMMAND_CHANGED:        return "command_changed";
  123.         case XmCR_EXPOSE:            return "expose";
  124.         case XmCR_RESIZE:            return "resize";
  125.         case XmCR_INPUT:            return "input";
  126.         case XmCR_GAIN_PRIMARY:        return "gain_primary";
  127.         case XmCR_LOSE_PRIMARY:        return "lose_primary";
  128.         case XmCR_CREATE:            return "create";
  129.         case XmCR_TEAR_OFF_ACTIVATE:    return "tear_off_activate";
  130.         case XmCR_TEAR_OFF_DEACTIVATE:    return "tear_off_deactivate";
  131.         case XmCR_OBSCURED_TRAVERSAL:    return "obscured_traversal";
  132.         default:                 return "none";
  133.     }
  134.     }
  135.  
  136.     class = XtClass(w);
  137.     if (XtIsSubclass(w, xmArrowButtonWidgetClass)) {
  138.     XmArrowButtonCallbackStruct *c_data = (XmArrowButtonCallbackStruct *) call_data;
  139.  
  140.     if (length == strlen("click_count") &&
  141.         strncmp(value, "click_count", length) == 0) {
  142.         sprintf(buf, "%d", c_data->click_count);
  143.         return buf;
  144.     } else {
  145.         return "ERROR in substitution";
  146.     }
  147.     } else
  148.  
  149.     if (XtIsSubclass(w, xmCommandWidgetClass)) {
  150.     XmCommandCallbackStruct *c_data = (XmCommandCallbackStruct *) call_data;
  151.  
  152.     if (length == strlen("value") &&
  153.         strncmp(value, "value", length) == 0) {
  154.         XmStringGetLtoR(c_data->value, 
  155.             XmFONTLIST_DEFAULT_TAG, &result);
  156.         return result;
  157. /*
  158.         from.addr = c_data->value;
  159.         from.size = sizeof(XmString);
  160.         to.addr = NULL;
  161.         Tm_CvtXmStringToString(NULL, NULL, 0, &from, &to, NULL);
  162.         return *(char **)to.addr;
  163. */
  164.     } else
  165.     if (length == strlen("length") &&
  166.         strncmp(value, "length", length) == 0) {
  167.         sprintf(buf, "%d", c_data->length);
  168.         return buf;
  169.     } else {
  170.         return "ERROR in substitution";
  171.     }
  172.     } else
  173.  
  174. #ifndef MOTIF11
  175.     if (XtIsSubclass(w, xmDragContextClass)) {
  176.     if (length == strlen("type") &&
  177.         strncmp(value, "type", length) == 0) {
  178.         return TM_CONVERT_TYPE;
  179.     } else
  180.     if (length == strlen("value") &&
  181.         strncmp(value, "value", length) == 0) {
  182.         return TM_CONVERT_VALUE;
  183.     } else {
  184.         return "ERROR in substitution";
  185.     }    
  186.     } else
  187. #endif
  188.  
  189.     if (XtIsSubclass(w, xmDrawnButtonWidgetClass)) {
  190.     XmDrawnButtonCallbackStruct *c_data = (XmDrawnButtonCallbackStruct *) call_data;
  191.  
  192.     if (length == strlen("click_count") &&
  193.         strncmp(value, "click_count", length) == 0) {
  194.         sprintf(buf, "%d", c_data->click_count);
  195.         return buf;
  196.     } else {
  197.         return "ERROR in substitution";
  198.     }
  199.     } else
  200.  
  201.     if (XtIsSubclass(w, xmFileSelectionBoxWidgetClass)) {
  202.     XmFileSelectionBoxCallbackStruct *c_data =
  203.             (XmFileSelectionBoxCallbackStruct *) call_data;
  204.  
  205.     if (length == strlen("value") &&
  206.         strncmp(value, "value", length) == 0) {
  207.         XmStringGetLtoR(c_data->value, 
  208.             XmFONTLIST_DEFAULT_TAG, &result);
  209.         return result;
  210.     } else
  211.     if (length == strlen("length") &&
  212.         strncmp(value, "length", length) == 0) {
  213.         sprintf(buf, "%d", c_data->length);
  214.         return buf;
  215.     } else
  216.     if (length == strlen("mask") &&
  217.         strncmp(value, "mask", length) == 0) {
  218.         XmStringGetLtoR(c_data->mask, 
  219.             XmFONTLIST_DEFAULT_TAG, &result);
  220.         return result;
  221.     } else
  222.     if (length == strlen("mask_length") &&
  223.         strncmp(value, "mask_length", length) == 0) {
  224.         sprintf(buf, "%d", c_data->mask_length);
  225.         return buf;
  226.     } else
  227.     if (length == strlen("dir") &&
  228.         strncmp(value, "dir", length) == 0) {
  229.         XmStringGetLtoR(c_data->dir, 
  230.             XmFONTLIST_DEFAULT_TAG, &result);
  231.         return result;
  232.     } else
  233.     if (length == strlen("dir_length") &&
  234.         strncmp(value, "dir_length", length) == 0) {
  235.         sprintf(buf, "%d", c_data->dir_length);
  236.         return buf;
  237.     } else
  238.     if (length == strlen("pattern") &&
  239.         strncmp(value, "pattern", length) == 0) {
  240.         XmStringGetLtoR(c_data->pattern, 
  241.             XmFONTLIST_DEFAULT_TAG, &result);
  242.         return result;
  243.     } else
  244.     if (length == strlen("pattern_length") &&
  245.         strncmp(value, "pattern_length", length) == 0) {
  246.         sprintf(buf, "%d", c_data->pattern_length);
  247.         return buf;
  248.     } else {
  249.         return "ERROR in substitution";
  250.     }
  251.     } else
  252.  
  253.     if (XtIsSubclass(w, xmListWidgetClass)) {
  254.     XmListCallbackStruct *c_data = (XmListCallbackStruct *) call_data;
  255.  
  256.     if (length == strlen("item") &&
  257.         strncmp(value, "item",length) == 0) {
  258.             XmStringGetLtoR(c_data->item, 
  259.             XmFONTLIST_DEFAULT_TAG, &result);
  260.         return result;
  261.     } else
  262.     if (length == strlen("item_length") &&
  263.         strncmp(value, "item_length", length) == 0) {
  264.         sprintf(buf, "%d", c_data->item_length);
  265.         return buf;
  266.     } else
  267.     if (length == strlen("item_position") &&
  268.         strncmp(value, "item_position", length) == 0) {
  269.         sprintf(buf, "%d", c_data->item_position);
  270.         return buf;
  271.     } else
  272.     if (length == strlen("selected_items") &&
  273.         strncmp(value, "selected_items", length) == 0) {
  274.         if (c_data->reason == XmCR_MULTIPLE_SELECT ||
  275.             c_data->reason == XmCR_EXTENDED_SELECT) {
  276.         String *items;
  277.         static String items_list = NULL;
  278.         static int items_list_len = 0;
  279.         int n, len;
  280.         char *p, *end;
  281.  
  282.         items = (char **) XtMalloc(sizeof(char *) *
  283.                     c_data->selected_item_count);
  284.         len= 0;
  285.         for (n = 0; n < c_data->selected_item_count; n++) {
  286.             XmStringGetLtoR(c_data->selected_items[n],
  287.                     XmFONTLIST_DEFAULT_TAG, items + n);
  288.             len += strlen(items[n]) + 2; /* for , */
  289.         }
  290.  
  291.         /* reuse the static space we malloc for this list */
  292.         if (items_list == NULL) {
  293.             items_list = XtMalloc(len + 1); /* we overshoot by 1 */
  294.             items_list_len = len + 1;
  295.         } else
  296.         if (items_list_len < len) {
  297.            items_list = XtRealloc(items_list, len + 1);
  298.            items_list_len = len + 1;
  299.         }
  300.  
  301.         if (len == 0) {
  302.             *items_list = '\0';
  303.             return items_list;
  304.         }
  305. #ifdef TM_MOTIF_XMSTRINGTABLE
  306.         end = items_list;
  307.         for (n = 0; n < c_data->selected_item_count; n++) {
  308.             p = items[n];
  309.             while (*end++ = *p++)
  310.             ;
  311.             *(end - 1) = ',';
  312.             *end++ = ' ';
  313.             XtFree(items[n]);
  314.         }
  315.         *(end - 2) = '\0';
  316. #else
  317.         items_list = Tcl_Merge(c_data->selected_item_count, items);
  318.                 for (n = 0; n < c_data->selected_item_count; n++) {
  319.                     XtFree(items[n]);
  320.                 }
  321. #endif
  322.         XtFree((char *) items);
  323.         return items_list;
  324.         }
  325.     } else
  326.     if (length == strlen("selection_type") &&
  327.         strncmp(value, "selection_type", length) == 0) {
  328.         switch (c_data->selection_type) {
  329.         case XmINITIAL:        return "initial";
  330.         case XmMODIFICATION:    return "modification";
  331.         case XmADDITION:    return "addition";
  332.         default:        return "ERROR!";
  333.         }
  334.     } else
  335.     if (length == strlen("selected_item_count") &&
  336.         strncmp(value, "selected_item_count", length) == 0) {
  337.         sprintf(buf, "%d", c_data->selected_item_count);
  338.         return buf;
  339.     } else {
  340.         return "ERROR in substitution";
  341.     }
  342.     } else
  343.  
  344.     if (XtIsSubclass(w, xmPushButtonWidgetClass)) {
  345.         XmPushButtonCallbackStruct *c_data = (XmPushButtonCallbackStruct *) call_data;
  346.  
  347.         if (length == strlen("click_count") &&
  348.                 strncmp(value, "click_count", length) == 0) {
  349.             sprintf(buf, "%d", c_data->click_count);
  350.             return buf;
  351.         } else {
  352.             return "ERROR in substitution";
  353.     }
  354.     } else
  355.  
  356.     if (XtIsSubclass(w, xmScaleWidgetClass)) {
  357.     XmScaleCallbackStruct *c_data = (XmScaleCallbackStruct *) call_data;
  358.  
  359.     if (length == strlen("value") &&
  360.         strncmp(value, "value", length) == 0) {
  361.         sprintf(buf, "%d", c_data->value);
  362.         return buf;
  363.     } else {
  364.         return "ERROR in substitution";
  365.     }
  366.     } else
  367.  
  368.     if (XtIsSubclass(w, xmScrollBarWidgetClass)) {
  369.     XmScrollBarCallbackStruct *c_data = (XmScrollBarCallbackStruct *) call_data;
  370.  
  371.     if (length == strlen("value") &&
  372.         strncmp(value, "value", length) == 0) {
  373.         sprintf(buf, "%d", c_data->value);
  374.         return buf;
  375.     } else {
  376.         return "ERROR in substitution";
  377.     }
  378.     } else
  379.  
  380.     if (XtIsSubclass(w, xmTextWidgetClass)) {
  381.     XmTextVerifyCallbackStruct *c_data =
  382.             (XmTextVerifyCallbackStruct *) call_data;
  383.  
  384.     if (length == strlen("doit") &&
  385.         strncmp(value, "doit", length) == 0) {
  386.         return TM_TEXT_DOIT;
  387.     } else
  388.     if (length == strlen("currInsert") &&
  389.         strncmp(value, "currInsert", length) == 0) {
  390.         sprintf(buf, "%d", c_data->currInsert);
  391.         return buf;
  392.     } else
  393.     if (length == strlen("newInsert") &&
  394.         strncmp(value, "newInsert", length) == 0) {
  395.         sprintf(buf, "%d", c_data->newInsert);
  396.         return buf;
  397.     } else
  398.     if (length == strlen("startPos") &&
  399.         strncmp(value, "startPos", length) == 0) {
  400.         return TM_TEXT_STARTPOS;
  401.     } else
  402.     if (length == strlen("endPos") &&
  403.         strncmp(value, "endPos", length) == 0) {
  404.         return TM_TEXT_ENDPOS;
  405.     } else
  406.     if (length == strlen("ptr") &&
  407.         strncmp(value, "ptr", length) == 0) {
  408.         return TM_TEXT_PTR;
  409.     } else
  410.     if (length == strlen("length") &&
  411.         strncmp(value, "length", length) == 0) {
  412.         return TM_TEXT_LENGTH;
  413.     } else {
  414.         return "ERROR in substitution";
  415.     }
  416.     } else
  417.  
  418.     if (XtIsSubclass(w, xmSelectionBoxWidgetClass)) {
  419.     XmSelectionBoxCallbackStruct *c_data =
  420.             (XmSelectionBoxCallbackStruct *) call_data;
  421.  
  422.     if (length == strlen("value") &&
  423.         strncmp(value, "value",length) == 0) {
  424.         XmStringGetLtoR(c_data->value, 
  425.             XmFONTLIST_DEFAULT_TAG, &result);
  426.         return result;
  427.     } else
  428.     if (length == strlen("length") &&
  429.         strncmp(value, "length", length) == 0) {
  430.         sprintf(buf, "%d", c_data->length);
  431.         return buf;
  432.     } else {
  433.         return "ERROR in substitution";
  434.     }
  435.     } else
  436.  
  437.     if (XtIsSubclass(w, xmToggleButtonWidgetClass)) {
  438.     XmToggleButtonCallbackStruct *c_data =
  439.             (XmToggleButtonCallbackStruct *) call_data;
  440.  
  441.     if (length == strlen("set") &&
  442.         strncmp(value, "set", length) == 0) {
  443.         if (c_data->set) {
  444.         return "true";
  445.         } else {
  446.         return "false";
  447.         }
  448.     } else {
  449.         return "ERROR in substitution";
  450.     }
  451.     } else
  452. #ifndef MOTIF11
  453.     if (XtIsSubclass(w, xmDropTransferObjectClass)) {
  454.     Tm_TransferStruct *c_data =
  455.             (Tm_TransferStruct *) call_data;
  456.  
  457.     if (length == strlen("value") &&
  458.         strncmp(value, "value", length) == 0) {
  459.         return c_data->value;
  460.     } else
  461.     if (length == strlen("closure") &&
  462.          strncmp(value, "closure", length) == 0) {
  463.         return c_data->closure;
  464.     } else {
  465.         return "ERROR in substitution";
  466.     }
  467.     }
  468. #endif
  469.     return "ERROR in substitution";
  470. }
  471.  
  472.  
  473. /*
  474.  *--------------------------------------------------------------
  475.  *
  476.  * addChars --
  477.  *
  478.  *    add a list of characters to a string.
  479.  *    grows space if neccessary
  480.  *
  481.  * Results:
  482.  *
  483.  *    "from" as appended to "after"
  484.  *
  485.  * Side effects:
  486.  *
  487.  *    may reallocate memory
  488.  *--------------------------------------------------------------
  489.  */
  490.  
  491. static char *
  492. addChars(after, afterSize, end, spaceLeft, fromSize, from)
  493.     char *after;
  494.     int *afterSize;
  495.     char **end;
  496.     int *spaceLeft;
  497.     int fromSize;
  498.     char *from;
  499. {
  500.     char *newSpace;
  501.     int extra;
  502.  
  503.     if (*spaceLeft < fromSize) {
  504.     if (fromSize > *afterSize) {
  505.         extra = fromSize + 50;
  506.     } else {
  507.         extra = *afterSize;
  508.     }
  509.     newSpace = XtRealloc(after, *afterSize + extra);
  510.     *spaceLeft += extra;
  511.     *afterSize += extra;
  512.     *end = newSpace + (*end - after);
  513.     after = newSpace;
  514.     }
  515.     *spaceLeft -= fromSize;
  516.  
  517.     while (fromSize) {
  518.     **end = *from;
  519.     from++;
  520.     (*end)++;
  521.     fromSize--;
  522.     }
  523.     return after;
  524. }
  525.  
  526. /*
  527.  *--------------------------------------------------------------
  528.  *
  529.  * Tm_ExpandPercents --
  530.  *
  531.  *    expand out the %field in patterns by their callback values
  532.  *
  533.  * Results:
  534.  *
  535.  *    A new string with the expansions is returned
  536.  * Side effects:
  537.  *
  538.  *    none.
  539.  *--------------------------------------------------------------
  540.  */
  541.  
  542. char *
  543. Tm_ExpandPercents(pathName, w, event, call_data, before)
  544.     char *pathName;
  545.     Widget w;
  546.     XEvent *event;
  547.     XtPointer call_data;
  548.     char *before;
  549. {
  550.     char *after, *end;
  551.     char *value;
  552. #   define TM_STR_SIZE 128
  553.     int afterSize = TM_STR_SIZE;
  554.     int spaceLeft = TM_STR_SIZE;
  555.     int wordSize;
  556.  
  557.     if (strchr(before, '%') == NULL) {
  558.     after = XtNewString(before);
  559.     return after;
  560.     }
  561.  
  562.     end = after = XtMalloc(TM_STR_SIZE);
  563.  
  564.     while (*before != 0) {
  565.     if (*before != '%') {
  566.         after = addChars(after, &afterSize, &end, &spaceLeft, 1, before);
  567.         before++;
  568.     } else {
  569.         before++;
  570.         wordSize = 0;
  571.         while (isalpha(before[wordSize]) || before[wordSize] == '_') {
  572.         wordSize++;
  573.         }
  574.         if (wordSize == 0) {
  575.             after = addChars(after, &afterSize, &end, &spaceLeft, 1, "%");
  576.         } else {
  577.         value = getValue(pathName, w,
  578.                 event, call_data, before, wordSize);
  579.         after = addChars(after, &afterSize, &end, &spaceLeft,
  580.                  strlen(value), value);
  581.         before += wordSize;
  582.         }
  583.     }
  584.     }
  585.     *end = '\0';
  586.  
  587.     return after;
  588. }
  589.