home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / sun / volume3 / sunview2open-look < prev    next >
Text File  |  1991-05-14  |  25KB  |  1,136 lines

  1. Path: uunet!wuarchive!zaphod.mps.ohio-state.edu!ub!rutgers!aramis.rutgers.edu!mcgrew
  2. From: mcgrew@aramis.rutgers.edu (Charles Mcgrew)
  3. Newsgroups: comp.sources.sun
  4. Subject: v03i002:  From SunView to OPEN LOOK via Developer's GUIDE
  5. Message-ID: <May.14.13.27.07.1991.28892@aramis.rutgers.edu>
  6. Date: 14 May 91 17:27:08 GMT
  7. Organization: Rutgers Univ., New Brunswick, N.J.
  8. Lines: 1125
  9. Approved: mcgrew@aramis.rutgers.edu
  10.  
  11. Submitted-by: leif@winsoft.se (Leif Samuelsson)
  12. Posting-number: Volume 3, Issue 1
  13. Archive-name: sunview2open-look
  14.  
  15. [ My apologies to one and all for the long quiet spell on this news-
  16. group.  Various work and non-work (like getting married) items got
  17. in the way of my doing moderation duties.  I do not plan for this
  18. "silence" to occur again. - CWM]
  19.  
  20.  
  21. Porting an application from SunView to XView is easy - if all you want
  22. is to make it compile and run.  Changing the user interface to comply
  23. with the OPEN LOOK style guide is harder and takes a lot more time.
  24.  
  25. Here is a utility I wrote for dumping a SunView window hierarchy to a
  26. file in Developer's GUIDE format.  This makes it easier to change the
  27. layout of subwindows and panel objects.  Uisng GUIDE, a new ui module
  28. can then be generated and used to replace the old SunView window code.
  29.  
  30.  
  31.  
  32. Leif Samuelsson
  33.  
  34. Winsoft Data AB            Phone: (011 468) 730-1240
  35. Lidgatan 18            Fax:   (011 468) 730-3102
  36. S-171 58 SOLNA            E-mail: leif@winsoft.se
  37. Sweden
  38.  
  39.  
  40. --------Cut here-----
  41. # This is a shell archive.  Remove anything before this line,
  42. # then unpack it by saving it in a file and typing "sh file".
  43. #
  44. # Wrapped by winsoft!leif on Sat Jan 19 17:12:03 MET 1991
  45. # Contents:  README svg.c
  46.  
  47. echo x - README
  48. sed 's/^@//' > "README" <<'@//E*O*F README//'
  49. README for svg.c
  50.  
  51. This module can be used with a SunView application to generate a
  52. user interface description file in Developer's GUIDE format.
  53.  
  54. To use it, compile svg.c and link it with the old SunView program.
  55. At least one function call needs to be added to the main module of
  56. the application.  See the instructions below.
  57.  
  58. This utility is meant as an aid only and will probably not work very
  59. well with applications that use anything other than standard
  60. (simple) SunView objects. In particular, the following limitations
  61. apply:
  62.  
  63.       -    All objects need to be created (instantiated) before the
  64.     call to window_main_loop().
  65.  
  66.       - Variable names are only preserved for global top-level
  67.     variables.
  68.  
  69.       - Button label strings can only be extracted (using an ugly
  70.     brute-force method) if the button font is the same as the
  71.     panel font.
  72.  
  73.       - Unparented objects have to be dumped with separate calls. The
  74.     only such calls provided are for frames and menus.
  75.  
  76.       - This software is provided as is. I do not guarantee any
  77.     support, but am grateful for any comments, bug fixes and
  78.     enhancements.
  79.  
  80.       - Core dumps are not unlikely to happen.
  81.  
  82.  
  83.  
  84. Instructions
  85. ------------
  86.  
  87. 1.    Add the call
  88.  
  89.         svg_dump(base_frame, argv);
  90.  
  91.     to your application just before (or instead of)
  92.     window_main_loop().  When run, it dumps the entire window
  93.     hierarchy below base_frame to a file called progname.G
  94.  
  95.     If you have floating menus that are created without parents,
  96.     use these calls instead of the one above:
  97.  
  98.         svg_start(argv);
  99.         svg_dump_baseframe(base_frame);
  100.         svg_dump_menu(menu_1);
  101.         ...
  102.         svg_dump_menu(menu_n);
  103.         svg_end();
  104.  
  105.  
  106. 2.    Compile svg.c:
  107.  
  108.         cc -c svg.c
  109.  
  110.  
  111. 3.    Link svg.o with application using the -Bstatic flag.
  112.  
  113.  
  114.  
  115. Copyright
  116. ---------
  117.  
  118.     Copyright (c) 1990, Winsoft Data AB
  119.  
  120.     This code may be freely copied, as long as this copyright
  121.     notice is left intact.
  122.  
  123.  
  124.  
  125. -------
  126. Leif Samuelsson
  127.  
  128. Winsoft Data AB            Phone: +46 8 7301240
  129. Lidgatan 18            Fax:   +46 8 7303102
  130. S-171 58 SOLNA            E-mail: leif@winsoft.se
  131. Sweden
  132. @//E*O*F README//
  133. chmod u=rw,g=rw,o=r README
  134.  
  135. echo x - svg.c
  136. sed 's/^@//' > "svg.c" <<'@//E*O*F svg.c//'
  137. /*    svg.c        - Dumps SunView windows in DevGuide format
  138.  *
  139.  *    Copyright (c) 1991, Winsoft Data AB
  140.  *
  141.  *    This code may be freely copied, as long as this copyright
  142.  *    notice is left intact.
  143.  *
  144.  *    Link with -Bstatic to application
  145.  */
  146.  
  147. #ifndef lint
  148. static    char sccsid[] = "@(#)svg.c 1.4 91-01-19 Copyright (c) 1991 Winsoft Data AB";
  149. #endif
  150.  
  151. #include <suntool/sunview.h>
  152. #include <suntool/frame.h>
  153. #include <suntool/canvas.h>
  154. #include <suntool/panel.h>
  155. #include <suntool/textsw.h>
  156. #include <suntool/tty.h>
  157. #include <suntool/menu.h>
  158. #include <stdio.h>
  159. #include <a.out.h>
  160. #include <stab.h>
  161. #include <sys/types.h>
  162. #include <sys/stat.h>
  163. #include <sys/mman.h>
  164.  
  165.  
  166. typedef void (*funcp)();
  167.  
  168. /*
  169.  *    External interface:
  170.  *
  171.  *    svg_dump(base_frame, argv);
  172.  *
  173.  *    This call should be placed just before (or instead of)
  174.  *    window_main_loop().  It dumps the entire hierarchy under
  175.  *    base_frame to the file progname.G
  176.  *
  177.  *
  178.  *    Alternative calls for applications with menus and other
  179.  *    objects which are not in the base_frame hierarchy:
  180.  *
  181.  *    svg_start(argv);
  182.  *    svg_dump_baseframe(base_frame);
  183.  *    svg_dump_menu(menu);
  184.  *    ...
  185.  *    svg_end();
  186.  *
  187.  */
  188.  
  189. void    svg_dump(),
  190.     svg_start(),
  191.     svg_dump_baseframe(),
  192.     svg_dump_subframe(),
  193.     svg_dump_menu(),
  194.     svg_end();
  195.  
  196. static void
  197.     dump_subwindow(),
  198.     dump_panel_items(),
  199.     dump_button(),
  200.     dump_icon(),
  201.     dump_messageitem(),
  202.     dump_textitem(),
  203.     dump_choice(),
  204.     dump_slider(),
  205.     putname(),
  206.     putstr(),
  207.     putint(),
  208.     putbool(),
  209.     really_dump_menus();
  210.  
  211. static char
  212.     *string_from_button_pr();
  213.  
  214. static Menu
  215.     dump_panel_menu();
  216.  
  217.  
  218. char  *newname(), *symbol(), *malloc();
  219.  
  220. static FILE        *svg_file = NULL;
  221. static struct nlist    *svg_symtab;
  222. static char        *svg_strtab;
  223. static int         svg_nsyms;
  224. static Menu          svg_menus[256];
  225. static int         svg_nmenus;
  226. static char        *progname;
  227.  
  228.  
  229.  
  230.  
  231.  
  232. void
  233. svg_dump(frame, argv)
  234.      Frame frame;
  235.      char **argv;
  236. {
  237.     svg_start(argv);
  238.     svg_dump_baseframe(frame);
  239.     svg_end();
  240. }
  241.  
  242.  
  243. void
  244. svg_dump_baseframe(frame)
  245.      Frame frame;
  246. {
  247.     Window win;
  248.     int n;
  249.     
  250.     fprintf(svg_file, "(\n");
  251.     putname("type",        ":base-window");
  252.  
  253.     putname("name", symbol(frame, TRUE, "frame"));
  254.  
  255.     putint("width",        window_get(frame, WIN_WIDTH) - 12);
  256.     putint("height",        window_get(frame, WIN_HEIGHT) - 22);
  257.  
  258.     putstr("label",        window_get(frame, FRAME_LABEL));
  259.  
  260.     putname("label-type",    ":string");
  261.  
  262.     putbool("mapped",        TRUE);
  263.  
  264.     putbool("show-footer",    TRUE);
  265.  
  266.     fprintf(svg_file, ")\n");
  267.  
  268.     n = 0;
  269.     while (win = window_get(frame, FRAME_NTH_SUBWINDOW, n++, 0))
  270.     dump_subwindow(win);
  271.  
  272.     n = 0;
  273.     while (win = window_get(frame, FRAME_NTH_SUBFRAME, n++, 0))
  274.     svg_dump_subframe(win);
  275. }
  276.  
  277.  
  278.  
  279.  
  280. void
  281. svg_dump_subframe(frame)
  282.      Frame frame;
  283. {
  284.     Window win;
  285.     int n;
  286.     
  287.     fprintf(svg_file, "(\n");
  288.     putname("type",        ":popup-window");
  289.     putname("name", symbol(frame, TRUE, "popup"));
  290.     putname("owner",        symbol(window_get(frame, WIN_OWNER), TRUE, "frame"));
  291.  
  292.     putint("width",        window_get(frame, WIN_WIDTH) - 12);
  293.     putint("height",        window_get(frame, WIN_HEIGHT) - 22);
  294.     putstr("label",        window_get(frame, FRAME_LABEL));
  295.     putname("label-type",    ":string");
  296.     putbool("mapped",        FALSE);
  297.     putbool("show-footer",    TRUE);
  298.  
  299.     fprintf(svg_file, ")\n");
  300.  
  301.     n = 0;
  302.     while (win = window_get(frame, FRAME_NTH_SUBWINDOW, n++, 0))
  303.     dump_subwindow(win);
  304. }
  305.  
  306.  
  307.  
  308.  
  309.  
  310. void
  311. svg_dump_menu(menu)
  312.      Menu    menu;
  313. {
  314.     int        i, nitems;
  315.     Menu    submenu;
  316.     Menu_item    item;
  317.  
  318.     nitems = (int)menu_get(menu, MENU_NITEMS);
  319.     if (nitems == 0)
  320.     return;
  321.  
  322.     for (i=1; i <= nitems; i++) {
  323.     item = (Menu_item)menu_get(menu, MENU_NTH_ITEM, i);
  324.     if (submenu = (Menu)menu_get(item, MENU_PULLRIGHT))
  325.         svg_dump_menu(submenu);
  326.     }
  327.     for (i=0; i<svg_nmenus; i++) {
  328.     if (svg_menus[i] == menu)
  329.         return;
  330.     }
  331.     svg_menus[svg_nmenus++] = menu;
  332. }
  333.  
  334.  
  335. void
  336. svg_start(argv)
  337.      char **argv;
  338. {
  339.     int        fd;
  340.     caddr_t    binfile;
  341.     struct stat    statbuf;
  342.     char    fname[128];
  343.     struct exec    *exec;
  344.  
  345.     if (svg_file)
  346.     return;
  347.  
  348.     progname = argv[0];
  349.  
  350.     fd = open(progname, 0);
  351.  
  352.     if (fd < 0) {
  353.     perror("sv_dump");
  354. /*    fprintf(stderr, "Can't find %s\n", progname); */
  355.     exit(1);
  356.     }
  357.  
  358.     fstat(fd, &statbuf);
  359.  
  360.     binfile = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
  361.  
  362.     close(fd);
  363.  
  364.     if ((int)binfile == -1) {
  365.     fprintf(stderr, "svg_dump: Can't mmap file\n");
  366.     exit(2);
  367.     }
  368.  
  369.     exec = (struct exec *)binfile;
  370.  
  371.     if (N_SYMOFF(*exec) > statbuf.st_size) {
  372.     fprintf(stderr, "svg_dump: Can't find symbol table\n");
  373.     exit(3);
  374.     }
  375.     svg_symtab = (struct nlist *) (binfile + N_SYMOFF(*exec));
  376.  
  377.     svg_nsyms = exec->a_syms / sizeof(struct nlist);
  378.  
  379.     svg_strtab = (char *)(binfile + N_STROFF(*exec));
  380.  
  381.  
  382.     sprintf(fname, "%s.G", progname);
  383.     svg_file = fopen(fname, "w");
  384.     if (!svg_file) {
  385.     perror(fname);
  386.     exit(4);
  387.     }
  388.     printf("svg_dump: Dumping to %s", fname);
  389.     fprintf(svg_file, ";GIL-1\n");
  390.     fprintf(svg_file, ";\n");
  391.     fprintf(svg_file, "; %s\n", fname);
  392.     fprintf(svg_file, ";\n");
  393.     fprintf(svg_file, "; This file was automatically generated by svg_dump()\n");
  394.     fprintf(svg_file, ";\n");
  395.     fprintf(svg_file, "(\n");
  396. }
  397.  
  398.  
  399. void
  400. svg_end()
  401. {
  402.     if (!svg_file)
  403.     return;
  404.  
  405.     really_dump_menus();
  406.  
  407.     fprintf(svg_file, ")\n");
  408.     fclose(svg_file);
  409.     printf("\n");
  410. }
  411.  
  412.  
  413.  
  414.  
  415.  
  416.  
  417. /* Private functions */
  418.  
  419. static void
  420. dump_subwindow(win)
  421.      Window win;
  422. {
  423.     Window_type    type;
  424.     funcp fp;
  425.     Menu    menu;
  426.  
  427.     extern void window_default_event_func();
  428.     extern void panel_default_event();
  429.  
  430.     type = (Window_type)window_get(win, WIN_TYPE);
  431.  
  432.     fprintf(svg_file, "(\n");
  433.  
  434.     switch(type) {
  435.       case ATTR_PKG_CANVAS:
  436.     putname("type",    ":canvas-pane");
  437.     putname("name",    symbol(win, TRUE, "canvas"));
  438.     break;
  439.  
  440.       case ATTR_PKG_PANEL:
  441.     putname("type",    ":control-area");
  442.     putname("name", symbol(win, TRUE, "panel"));
  443.     break;
  444.  
  445.       case ATTR_PKG_TEXTSW:
  446.     putname("type", ":text-pane");
  447.     putname("name",    symbol(win, TRUE, "textsw"));
  448.     break;
  449.  
  450.       case ATTR_PKG_TTY:
  451.     putname("type",    ":term-pane");
  452.     putname("name",    symbol(win, TRUE, "tty"));
  453.     break;
  454.     }
  455.  
  456.     putname("owner",    symbol(window_get(win, WIN_OWNER), TRUE, "frame"));
  457.     putint("x",        window_get(win, WIN_X));
  458.     putint("y",        window_get(win, WIN_Y));
  459.     putint("width",    window_get(win, WIN_WIDTH));
  460.     putint("height",    window_get(win, WIN_HEIGHT));
  461.  
  462.     switch(type) {
  463.       case ATTR_PKG_CANVAS:
  464.     menu = window_get(win, WIN_MENU);
  465.     putname("menu",    symbol(menu, TRUE, "menu"));
  466.     svg_dump_menu(menu);
  467.     putbool("horizontal-scrollbar",
  468.                 window_get(win, WIN_HORIZONTAL_SCROLLBAR));
  469.     putint("scrollable-width", window_get(win, CANVAS_WIDTH));
  470.     putbool("vertical-scrollbar",
  471.                 window_get(win, WIN_VERTICAL_SCROLLBAR));
  472.     putint("scrollable-height", window_get(win, CANVAS_HEIGHT));
  473.     putname("repaint-proc", window_get(win, CANVAS_REPAINT_PROC));
  474.     break;
  475.  
  476.       case ATTR_PKG_PANEL:
  477.     putbool("show-border",    FALSE);
  478.     putname("menu",    symbol(window_get(win, WIN_MENU), TRUE, "menu"));
  479.     break;
  480.  
  481.       case ATTR_PKG_TEXTSW:
  482.     putbool("show-border",    TRUE);
  483.     menu = window_get(win, WIN_MENU);
  484.     break;
  485.  
  486.       case ATTR_PKG_TTY:
  487.     putbool("show-border",    TRUE);
  488.     break;
  489.     }
  490.  
  491.  
  492.     /* Event handler and input mask */
  493.  
  494.     fp = (funcp)window_get(win, WIN_EVENT_PROC);
  495.     switch(type) {
  496.       case ATTR_PKG_PANEL:
  497.     if (fp && fp != panel_default_event)
  498.         putname("event-handler", symbol(fp, FALSE, "proc"));
  499.     break;
  500.  
  501.       default:
  502.     if (fp && fp != window_default_event_func)
  503.         putname("event-handler", symbol(fp, FALSE, "proc"));
  504.     }
  505.  
  506.     fprintf(svg_file, "\t:%-25s(", "events");
  507.     if (window_get(win, WIN_CONSUME_KBD_EVENT, WIN_ASCII_EVENTS))
  508.     fprintf(svg_file, ":keyboard ");
  509.     if (window_get(win, WIN_CONSUME_KBD_EVENT, WIN_LEFT_KEYS))
  510.     fprintf(svg_file, ":keyboard-left ");
  511.     if (window_get(win, WIN_CONSUME_KBD_EVENT, WIN_RIGHT_KEYS))
  512.     fprintf(svg_file, ":keyboard-right ");
  513.     if (window_get(win, WIN_CONSUME_KBD_EVENT, WIN_TOP_KEYS))
  514.     fprintf(svg_file, ":keyboard-top ");
  515.     if (window_get(win, WIN_CONSUME_PICK_EVENT, MS_LEFT)
  516.     || window_get(win, WIN_CONSUME_PICK_EVENT, MS_MIDDLE)
  517.     || window_get(win, WIN_CONSUME_PICK_EVENT, MS_RIGHT))
  518.     fprintf(svg_file, ":mouse ");
  519.     if (window_get(win, WIN_CONSUME_PICK_EVENT, LOC_MOVE))
  520.     fprintf(svg_file, ":mouse-move ");
  521.     if (window_get(win, WIN_CONSUME_PICK_EVENT, LOC_DRAG))
  522.     fprintf(svg_file, ":mouse-drag ");
  523.     if (window_get(win, WIN_CONSUME_PICK_EVENT, LOC_WINENTER))
  524.     fprintf(svg_file, ":mouse-enter ");
  525.     if (window_get(win, WIN_CONSUME_PICK_EVENT, LOC_WINEXIT))
  526.     fprintf(svg_file, ":mouse-exit");
  527.     fprintf(svg_file, ")\n");
  528.  
  529.     fprintf(svg_file, ")\n");
  530.  
  531.     if (type == ATTR_PKG_PANEL)
  532.     dump_panel_items(win);
  533. }
  534.  
  535.  
  536.  
  537.  
  538. /******** PANEL ITEMS *********/
  539.  
  540.  
  541. /* types of items */
  542. typedef enum { 
  543.    PANEL_MESSAGE_ITEM,
  544.    PANEL_BUTTON_ITEM, 
  545.    PANEL_CHOICE_ITEM, 
  546.    PANEL_TOGGLE_ITEM, 
  547.    PANEL_TEXT_ITEM,
  548.    PANEL_SLIDER_ITEM,
  549.    PANEL_LINE_ITEM
  550. } PANEL_ITEM_TYPE;
  551.     
  552. struct panel_item {
  553.    int    i1[2];
  554.    PANEL_ITEM_TYPE      item_type;      /* type of this item */
  555.    int    i2[6];
  556.    struct {
  557.       int i3, i4:1;
  558.       int i5[2];
  559.       short s1;
  560.    } st1;
  561.    int    i6[6];
  562.    struct menu          *menu;          /* menu of choices */
  563. };
  564.  
  565. static void
  566. dump_panel_items(panel)
  567.      Panel panel;
  568. {
  569.     Panel_item    pi;
  570.     char    *name, *str, prname[256];
  571.     int        type;
  572.     funcp    fun;
  573.     struct pixrect *pr;
  574.     struct menu    *menu;
  575.     extern int    panel_nullproc();
  576.  
  577.     panel_each_item(panel, pi) {
  578.     fprintf(svg_file, "(\n");
  579.  
  580.     switch (((struct panel_item *)pi)->item_type) {
  581.       case PANEL_BUTTON_ITEM:
  582.         dump_button(pi, panel);
  583.         break;
  584.  
  585.       case PANEL_MESSAGE_ITEM:
  586.         dump_messageitem(pi);
  587.         break;
  588.  
  589.       case PANEL_TEXT_ITEM:
  590.         dump_textitem(pi);
  591.         break;
  592.  
  593.       case PANEL_CHOICE_ITEM:
  594.       case PANEL_TOGGLE_ITEM:
  595.         dump_choice(pi);
  596.         break;
  597.  
  598.       case PANEL_SLIDER_ITEM:
  599.         dump_slider(pi);
  600.         break;
  601.  
  602.       case PANEL_LINE_ITEM:
  603.         break;
  604.     }
  605.  
  606.     name = symbol(pi, TRUE, "panel_item");
  607.     putname("name",     name);
  608.     putname("owner", symbol(panel_get(pi, PANEL_PARENT_PANEL), TRUE, "panel"));
  609.     putint("x",     panel_get(pi, PANEL_ITEM_X));
  610.     putint("y",     panel_get(pi, PANEL_ITEM_Y));
  611.  
  612.  
  613.     /* LABEL */
  614.     if (pr = (struct pixrect *)panel_get(pi, PANEL_LABEL_IMAGE)) {
  615.         str = string_from_button_pr(pr, panel);
  616.         if (str) {
  617.         putstr("label", str);
  618.         putname("label-type", ":string");
  619.         } else {
  620.         sprintf(prname, "%s_%s", progname, symbol(pr, TRUE, "glyph"));
  621.         dump_icon(pr, prname);
  622.         putstr("label", prname);
  623.         putname("label-type", ":glyph");
  624.         }
  625.     } else {
  626.         putstr("label", panel_get(pi, PANEL_LABEL_STRING));
  627.         putname("label-type", ":string");
  628.     }
  629.  
  630.     /* MENU */
  631.     switch (((struct panel_item *)pi)->item_type) {
  632.       case PANEL_CHOICE_ITEM:
  633.       case PANEL_TOGGLE_ITEM:
  634.         break;
  635.  
  636.       default:
  637.         putname("menu",
  638.             symbol(dump_panel_menu(((struct panel_item *)pi)->menu),
  639.                TRUE, "menu"));
  640.     }
  641.  
  642.     /* VALUE */
  643. #ifdef NOTDEF
  644.     /*
  645.      * GUIDE does not allow setting initial value yet
  646.      * so :initial-value is not used.
  647.      */
  648.     switch (((struct panel_item *)pi)->item_type) {
  649.       case PANEL_CHOICE_ITEM:
  650.       case PANEL_TOGGLE_ITEM:
  651.       case PANEL_SLIDER_ITEM:
  652.         putint("initial-value", panel_get(pi, PANEL_VALUE));
  653.         break;
  654.  
  655.       case PANEL_TEXT_ITEM:
  656.         putstr("initial-value", panel_get(pi, PANEL_VALUE));
  657.         break;
  658.     }
  659. #endif
  660.  
  661.  
  662.     /* NOTIFY */
  663.     fun = (funcp)panel_get(pi, PANEL_NOTIFY_PROC);
  664.     if (fun && fun != (funcp)panel_nullproc)
  665.         putname("notify-handler", symbol(fun, FALSE, "proc"));
  666.     fprintf(svg_file, ")\n");
  667.     } panel_end_each;
  668. }
  669.  
  670.  
  671. static Menu
  672. dump_panel_menu(menu)
  673.      struct menu    *menu;
  674. {
  675.     int        i, nitems;
  676.     Menu    walkmenu;
  677.  
  678.     if (!menu)
  679.     return((Menu)0);
  680.  
  681.     walkmenu = menu_create(0);
  682.  
  683.     nitems = menu->m_itemcount;
  684.     if (nitems == 0)
  685.     return((Menu)0);
  686.  
  687.     for (i=0; i < nitems; i++) {
  688.     menu_set(walkmenu, MENU_APPEND,
  689.          (menu->m_items[i].mi_imagetype == MENU_IMAGESTRING)
  690.             ? MENU_STRING_ITEM : MENU_IMAGE_ITEM,
  691.                    menu->m_items[i].mi_imagedata,
  692.                    menu->m_items[i].mi_data,
  693.          0);
  694.     }
  695.     svg_menus[svg_nmenus++] = walkmenu;
  696.     return(walkmenu);
  697. }
  698.  
  699.  
  700.  
  701.  
  702.  
  703. static char *
  704. string_from_button_pr(pr, panel)
  705.      struct pixrect *pr;
  706.      Panel panel;
  707. {
  708.     static char str[128];
  709.     char    tstr[128];
  710.     int        i, c, prx, tprx;
  711.     struct pixrect *tpr;
  712.  
  713.  
  714.     bzero(str, 128);
  715.  
  716.     /* First check if left edge looks like a button */
  717.     tpr = panel_button_image(panel, "xxx", 0, 0);
  718.     c = prcmp(pr, 0, tpr, 0, 6);
  719.     if (!c) {
  720.     pr_destroy(tpr);
  721.     return((char *)NULL);
  722.     }
  723.  
  724.     /* Find start of text */
  725.     tprx = 5;
  726.     for (i=6; i < tpr->pr_size.x - 6; i++) {
  727.     if (!prcmp(tpr, i, tpr, 5, 1)) {
  728.         tprx = i;
  729.         break;
  730.     }
  731.     }
  732.     prx = 5;
  733.     for (i=6; i < pr->pr_size.x - 6; i++) {
  734.     if (!prcmp(pr, i, tpr, 5, 1)) {
  735.         prx = i;
  736.         break;
  737.     }
  738.     }
  739.     pr_destroy(tpr);
  740.  
  741.     while (1) {
  742.     for (i = 32 ; i<= 126; i++) {
  743.         sprintf(tstr, "%s%c", str, i);
  744.         tpr = panel_button_image(panel, tstr, 0, 0);
  745.         c = prcmp(pr, prx, tpr, tprx, tpr->pr_size.x - tprx - 6);
  746.         pr_destroy(tpr);
  747.         if (c) {
  748.         strcpy(str, tstr);
  749.         break;
  750.         }
  751.     }
  752.     if (i > 126) {
  753.         if (str[0])
  754.         while (str[strlen(str)-1] == ' ')
  755.             str[strlen(str)-1] = '\0';
  756.         if (str[0])
  757.         return(str);
  758.         else
  759.         return((char *)NULL);
  760.     }
  761.     }
  762. }
  763.  
  764.  
  765. static int
  766. prcmp(pr1, x1, pr2, x2, w)
  767.      struct pixrect *pr1, *pr2;
  768.      int x1, x2, w;
  769. {
  770.     int h, x, y;
  771.  
  772.     h = pr1->pr_size.y;
  773.     if (h != pr2->pr_size.y)
  774.     return(FALSE);
  775.     for (y=0; y<h; y++) {
  776.     for (x=0; x<w; x++) {
  777.         if (pr_get(pr1, x1+x, y) != pr_get(pr2, x2+x, y))
  778.         return(FALSE);
  779.     }
  780.     }
  781.     return(TRUE);
  782. }
  783.  
  784.  
  785. static void
  786. dump_button(button, panel)
  787.      Panel_item button;
  788.      Panel    panel;
  789. {
  790.     struct rect *rect;
  791.  
  792.     putname("type",        ":button");
  793.     putbool("constant-width",    TRUE);
  794.     rect = (struct rect *)panel_get(button, PANEL_ITEM_RECT);
  795.     putint("width", rect->r_width - 10);
  796. }
  797.  
  798. static void
  799. dump_textitem(textitem)
  800.      Panel_item textitem;
  801. {
  802.     putname("type",        ":text-field");
  803. }
  804.  
  805.  
  806. static void
  807. dump_messageitem(pi)
  808.      Panel_item pi;
  809. {
  810.     putname("type", ":message");
  811.     putbool("label-bold", panel_get(pi, PANEL_LABEL_BOLD));
  812. }
  813.  
  814.  
  815. static void
  816. dump_choice(pi)
  817.      Panel_item pi;
  818. {
  819.     int      i, nchoices;
  820.     char prname[256], types[1024];
  821.     caddr_t choices[128];
  822.  
  823.     putname("type", ":setting");
  824.     putname("layout-type",
  825.       ((Panel_setting)panel_get(pi, PANEL_LAYOUT) == PANEL_HORIZONTAL)
  826.                                 ? ":horizontal"
  827.                                 : ":vertical");
  828.     putname("setting-type",
  829.         (panel_get(pi, PANEL_CHOOSE_ONE) ? (((Panel_setting)panel_get(pi, PANEL_DISPLAY_LEVEL) == PANEL_CURRENT) ? ":stack" : ":exclusive") : ":nonexclusive"));
  830.     putint("value-x",      panel_get(pi, PANEL_VALUE_X));
  831.     putint("value-y",      panel_get(pi, PANEL_VALUE_Y));
  832.  
  833.     fprintf(svg_file, "\t:%-25s(", "choices");
  834.     sprintf(types,    "\t:%-25s(", "choice-types");
  835.     nchoices = 0;
  836.     while (choices[nchoices] =
  837.             (caddr_t)panel_get(pi, PANEL_CHOICE_IMAGE, nchoices))
  838.     nchoices++;
  839.     if (nchoices) {
  840.     for (i=0; i<nchoices; i++) {
  841.         sprintf(prname, "%s_%s",
  842.             progname, symbol(choices[i], TRUE, "glyph"));
  843.         dump_icon(choices[i], prname);
  844.         fprintf(svg_file, "\"%s\" ", prname);
  845.         strcat(types, ":glyph ");
  846.     }
  847.     } else {
  848.     while (choices[nchoices] =
  849.             (caddr_t)panel_get(pi, PANEL_CHOICE_STRING, nchoices))
  850.         nchoices++;
  851.     if (nchoices) {
  852.         for (i=0; i<nchoices; i++) {
  853.         fprintf(svg_file, "\"%s\" ", choices[i]);
  854.         strcat(types, ":string ");
  855.         }
  856.     }
  857.     }
  858.     fprintf(svg_file, ")\n");
  859.     strcat(types,    ")\n");
  860.  
  861. #ifdef NOTDEF
  862.     /*
  863.      * GUIDE does not accept glyphs for choices yet,
  864.      * so :choice-types is not used.
  865.      */
  866.     fputs(types, svg_file); */
  867. #endif
  868.  
  869. }
  870.  
  871.  
  872.  
  873. static void
  874. dump_slider(slider)
  875.      Panel_item slider;
  876. {
  877.     putname("type",        ":slider");
  878.     putname("layout-type",
  879.       ((Panel_setting)panel_get(slider, PANEL_LAYOUT) == PANEL_HORIZONTAL)
  880.                                 ? ":horizontal"
  881.                                 : ":vertical");
  882.     putbool("show-range", panel_get(slider, PANEL_SHOW_RANGE));
  883.     putbool("show-value", panel_get(slider, PANEL_SHOW_VALUE));
  884.     putint("min-value",   panel_get(slider, PANEL_MIN_VALUE));
  885.     putint("max-value",   panel_get(slider, PANEL_MAX_VALUE));
  886.     putint("value-x",      panel_get(slider, PANEL_VALUE_X));
  887.     putint("value-y",      panel_get(slider, PANEL_VALUE_Y));
  888.     putint("slider-width",panel_get(slider, PANEL_SLIDER_WIDTH) - 8);
  889. }
  890.  
  891.  
  892.  
  893. static void
  894. really_dump_menus()
  895. {
  896.     Menu    menu, submenu;
  897.     Menu_item    item, defitem;
  898.     int     i, j, nitems, cols;
  899.     char    *str, prname[256], types[1024];
  900.     funcp    fun;
  901.     struct pixrect *pr;
  902.  
  903.     if (!svg_nmenus)
  904.     return;
  905.  
  906.     for (i = 0; i < svg_nmenus; i++) {
  907.     menu = svg_menus[i];
  908.     fprintf(svg_file, "(\n");
  909.     putname("type",    ":menu");
  910.     putname("name", symbol(menu, TRUE, "menu"));
  911.     cols = (int)menu_get(menu, MENU_NCOLS);
  912.     putint("columns", cols ? cols : 1);
  913.     putname("menu-type", ":command");
  914.  
  915.     fun = (funcp)menu_get(menu, MENU_NOTIFY_PROC);
  916.     if (fun && fun != (funcp)menu_return_value)
  917.         putname("menu-handler", symbol(fun, FALSE, "proc"));
  918.  
  919.     nitems = (int)menu_get(menu, MENU_NITEMS);
  920.     defitem = (Menu_item)menu_get(menu, MENU_DEFAULT_ITEM);
  921.  
  922.     fprintf(svg_file, "\t:%-25s(", "menu-item-labels");
  923.     sprintf(types,    "\t:%-25s(", "menu-item-label-types");
  924.     for (j=1; j <= nitems; j++) {
  925.         item = (Menu_item)menu_get(menu, MENU_NTH_ITEM, j);
  926.  
  927.         if (pr = (struct pixrect *)menu_get(item, MENU_IMAGE)) {
  928.         sprintf(prname, "%s_%s", progname, symbol(pr, TRUE, "glyph"));
  929.         dump_icon(pr, prname);
  930.         fprintf(svg_file, "\"%s\" ", prname);
  931.         strcat(types, ":glyph ");
  932.         } else {
  933.         if (str = (char *)menu_get(item, MENU_STRING))
  934.             fprintf(svg_file, "\"%s\" ", str);
  935.         else
  936.             fprintf(svg_file, "\"\" ", str);
  937.         strcat(types, ":string ");
  938.         }
  939.     }
  940.     fprintf(svg_file, ")\n");
  941.     strcat(types,    ")\n");
  942.     fputs(types, svg_file);
  943.  
  944.     fprintf(svg_file, "\t:%-25s(", "menu-item-defaults");
  945.     for (j=1; j <= nitems; j++) {
  946.         item = (Menu_item)menu_get(menu, MENU_NTH_ITEM, j);
  947.         fprintf(svg_file, (item == defitem) ? "t " : "nil ");
  948.     }
  949.     fprintf(svg_file, ")\n");
  950.  
  951.     fprintf(svg_file, "\t:%-25s(", "menu-item-handlers");
  952.     for (j=1; j <= nitems; j++) {
  953.         item = (Menu_item)menu_get(menu, MENU_NTH_ITEM, j);
  954.         fun = (funcp)menu_get(item, MENU_ACTION_PROC);
  955.         fprintf(svg_file, "%s ", symbol(fun, FALSE, "proc"));
  956.     }
  957.     fprintf(svg_file, ")\n");
  958.  
  959.     fprintf(svg_file, "\t:%-25s(", "menu-item-menus");
  960.     for (j=1; j <= nitems; j++) {
  961.         item = (Menu_item)menu_get(menu, MENU_NTH_ITEM, j);
  962.         submenu = (Menu)menu_get(item, MENU_PULLRIGHT);
  963.         fprintf(svg_file, "%s ", symbol(submenu, TRUE, "menu"));
  964.     }
  965.     fprintf(svg_file, ")\n");
  966.  
  967.     fprintf(svg_file, ")\n");
  968.     }
  969. }
  970.  
  971.  
  972.  
  973.  
  974.  
  975.  
  976.  
  977.  
  978. static void
  979. putname(name, value)
  980.      char *name, *value;
  981. {
  982.     fprintf(svg_file, "\t:%-25s%s\n", name, value ? value : "nil");
  983. }
  984.  
  985.  
  986. static void
  987. putstr(name, value)
  988.      char *name, *value;
  989. {
  990.     fprintf(svg_file, "\t:%-25s\"%s\"\n", name, value ? value : "");
  991. }
  992.  
  993.  
  994. static void
  995. putint(name, value)
  996.      char    *name;
  997.      int    value;
  998. {
  999.     fprintf(svg_file, "\t:%-25s%d\n", name, value);
  1000. }
  1001.  
  1002.  
  1003. static void
  1004. putbool(name, value)
  1005.      char    *name;
  1006.      int    value;
  1007. {
  1008.     fprintf(svg_file, "\t:%-25s%s\n", name, value ? "t" : "nil");
  1009. }
  1010.  
  1011.  
  1012. static char *
  1013. newname(str)
  1014.      char *str;
  1015. {
  1016.     static i = 0;
  1017.     char *p;
  1018.  
  1019.     p = malloc(10);
  1020.  
  1021.     sprintf(p, "%s_%d", str, i++);
  1022.  
  1023.     return (p);
  1024. }
  1025.  
  1026.  
  1027. static char *
  1028. symbol(addr, indirect, str)
  1029.      caddr_t     addr;
  1030.      int     indirect;
  1031.      char    *str;
  1032. {
  1033.     char    *p;
  1034.     int        i;
  1035.     caddr_t    v;
  1036.     static struct { caddr_t p; char *str; } lsyms[512];
  1037.     static int    nlsyms = 0;
  1038.  
  1039.     extern int    etext, edata, end;
  1040.  
  1041.     if (!addr)
  1042.     return("nil");
  1043.  
  1044.     for (i=0; i < nlsyms; i++) {
  1045.     if (addr == lsyms[i].p)
  1046.         return(lsyms[i].str);
  1047.     }
  1048.  
  1049.     for (i=0; i< svg_nsyms; i++) {
  1050.     v = (caddr_t)svg_symtab[i].n_value;
  1051.     if (indirect) {
  1052.         if (((int)v & 3) == 0
  1053.         && v >= (caddr_t)&edata
  1054.         && v < (caddr_t)&end
  1055.         && *(caddr_t *)v == addr) {
  1056.         p = &svg_strtab[svg_symtab[i].n_un.n_strx];
  1057.         if (*p++ == '_'
  1058.             && strcmp(p, "win_last_client")
  1059.             && strncmp(p, "svg_", 4)
  1060.             && strcmp(p, "edata"))
  1061.             return(p);
  1062.         }
  1063.     } else {
  1064.         if (v < (caddr_t)&etext && v == addr) {
  1065.         p = &svg_strtab[svg_symtab[i].n_un.n_strx];
  1066.         if (*p == '_') {
  1067.             return(p+1);
  1068.         }
  1069.         }
  1070.     }
  1071.     }
  1072.  
  1073.     lsyms[nlsyms].p = addr;
  1074.     lsyms[nlsyms].str = newname(str);
  1075.     return (lsyms[nlsyms++].str);
  1076. }
  1077.  
  1078.  
  1079. /*
  1080.  * dump_icon()
  1081.  *
  1082.  * code borrowed from /usr/src/sun/suntool/iconedit/iconedit_panel.c
  1083.  */
  1084. static void
  1085. dump_icon(pr, prname)
  1086.      struct pixrect *pr;
  1087.      char *prname;
  1088. {
  1089.     int                  i, limit;
  1090.     unsigned short    *data, *data_start;
  1091.     FILE        *fd;
  1092.     int             width, height;
  1093.     short         d0,d1,d2,d3,d4,d5,d6,d7;
  1094.  
  1095.  
  1096.     data_start = (unsigned short *)
  1097.          ((struct mpr_data *)(LINT_CAST(pr->pr_data)))->md_image;
  1098.     data = data_start;
  1099.  
  1100.     width = pr->pr_size.x;
  1101.     height = pr->pr_size.y;
  1102.  
  1103.     fd = fopen(prname, "w");
  1104.     if (!fd)  {
  1105.        perror(prname);
  1106.        exit(5);
  1107.     }
  1108.     fprintf(fd, "/* Format_version=1, Width=%d, Height=%d, %s=%d\n",
  1109.         width, height,
  1110.         "Depth=1, Valid_bits_per_item", 8*sizeof(*data));
  1111.     fprintf(fd, " */\n");
  1112.  
  1113.     limit = pr->pr_size.x * pr->pr_size.y /
  1114.          (8 * 8 * sizeof(*data));
  1115.     for (i=0;;) {
  1116.     d0 = data[0];d1 = data[1];d2 = data[2];d3 = data[3];
  1117.     d4 = data[4];d5 = data[5];d6 = data[6];d7 = data[7];
  1118.     fprintf(fd,
  1119.        "\t0x%-04X,0x%-04X,0x%-04X,0x%-04X,0x%-04X,0x%-04X,0x%-04X,0x%-04X",
  1120.        d0,d1,d2,d3,d4,d5,d6,d7);
  1121.  
  1122.        data += 8;
  1123.        if (++i < limit)
  1124.       fprintf(fd,",\n");
  1125.        else
  1126.       break;
  1127.     }      
  1128.     fputs("\n", fd);
  1129.     fclose(fd);
  1130. }
  1131.  
  1132. @//E*O*F svg.c//
  1133. chmod u=rw,g=r,o=r svg.c
  1134.  
  1135. exit 0
  1136.