home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / sun / volume01 / lookingg.las < prev    next >
Encoding:
Text File  |  1991-08-27  |  21.5 KB  |  846 lines

  1. Path: wuarchive!brutus.cs.uiuc.edu!apple!rutgers!aramis.rutgers.edu!dartagnan.rutgers.edu!mcgrew
  2. From: mcgrew@dartagnan.rutgers.edu (Charles Mcgrew)
  3. Newsgroups: comp.sources.sun
  4. Subject: v01i059:  Zoom in on parts of a SunView screen
  5. Message-ID: <Aug.24.23.16.45.1989.12090@dartagnan.rutgers.edu>
  6. Date: 25 Aug 89 03:16:47 GMT
  7. Organization: Rutgers Univ., New Brunswick, N.J.
  8. Lines: 835
  9. Approved: mcgrew@aramis.rutgers.edu
  10.  
  11. Submitted-by: ecn!jack@nluug.nl (Jack van Wijk)
  12. Posting-number: Volume 1, Issue 59
  13. Archive-name: looking-glass
  14.  
  15.  
  16. I submit the following tool for the comp.sources.sun group. It is a
  17. looking-glass, which enables the user to look at the screen in detail.
  18. In my opinion, it is better (more features) and faster than the
  19. old glass (in the SUN User Group 87 tapes).
  20.  
  21. With compliments,
  22.  
  23. Jack van Wijk
  24.  
  25. ---------- Netherlands Energy Research Foundation, ECN --------------
  26. Jack (Jarke J.) van Wijk                  UUCP : jack@ecn.uucp
  27. P.O. Box 1, 1755 ZG  Petten(NH)           ARPA : ecn!jack@nluug.nl
  28. Holland    phone: +31 2246 4333                  ecn!jack@uunet.uu.net
  29. ---------------------------------------------------------------------------
  30. : To unbundle, sh this file
  31. echo README
  32. cat >README <<'@@@ End of README'
  33. Lglass is a SunView tool for looking at the screen.
  34. Options are: user-selectable scale, color/bw, dynamic update, and dragging.
  35. To make this tool, just type make.
  36. @@@ End of README
  37. echo Makefile
  38. cat >Makefile <<'@@@ End of Makefile'
  39. WINLIBS =  -lsuntool -lsunwindow -lpixrect 
  40.  
  41. lglass: lglass.o show.o
  42.     cc -o $@ $(CFLAGS) lglass.o show.o $(WINLIBS)
  43. @@@ End of Makefile
  44. echo lglass.c
  45. cat >lglass.c <<'@@@ End of lglass.c'
  46. /*************************************************************************
  47.  Lglass: screen viewer for the Sun Workstation running SunView
  48.    Copyright (c) 1989 by Jack van Wijk
  49.    7/24/89 @ Netherlands Energy Research Foundation, ECN
  50.  
  51.    This program may be redistributed without fee as long as this copyright
  52.    notice is intact.
  53.  
  54. ---------- Netherlands Energy Research Foundation, ECN ------------------
  55. Jack (Jarke J.) van Wijk                  UUCP : jack@ecn.uucp
  56. P.O. Box 1, 1755 ZG  Petten(NH)           ARPA : ecn!jack@nluug.nl
  57. Holland    phone: +31 2246 4333                  ecn!jack@uunet.uu.net
  58. *************************************************************************/
  59.  
  60. #include <stdio.h>
  61. #include <sys/time.h>
  62. #include <suntool/sunview.h>
  63. #include <suntool/window.h>
  64. #include <suntool/panel.h>
  65. #include <suntool/canvas.h>
  66.  
  67. #define MAXSCALE        32    
  68. #define SCALESTRINGS        "1", "2", "4", "8", "16", "32"
  69. #define SCALEMENUSTRINGS    "zoom in", "zoom out"
  70. #define UPDATEMENUSTRINGS    "off", "slow", "fast"
  71. #define COLORSTRINGS        "B/W", "color"
  72.  
  73. Pixrect     *scr_pr;
  74. Frame        my_frame;
  75. Canvas        my_canvas;
  76. Panel_item    scale_item;
  77. Cursor        std_cursor, select_cursor;
  78. struct {
  79.         int    depth;
  80.         int    scale;
  81.         int    curx;
  82.         int    cury;
  83.     } GV = { 1, 1, 500, 500 };
  84.  
  85. short select_data[] = {
  86. #include "select.cursor"
  87. };
  88. mpr_static (select_pr, 16, 16, 1, select_data);
  89.  
  90. short glas_data[] = {
  91. #include "lglass.icon"
  92. };
  93. mpr_static (glas_pr, 64, 64, 1, glas_data);
  94.  
  95. /*----------------------------------------------------------------------*/
  96. scale_to_nr(scale)
  97.  
  98.     /* Map scale to number: 2**nr = scale    */
  99.  
  100. int scale;
  101. {
  102.     int nr;
  103.  
  104.     for (nr= 0; scale > 1; scale /=2)
  105.         nr++;
  106.     return nr;
  107. }
  108.  
  109. /*----------------------------------------------------------------------*/
  110. nr_to_scale(nr)
  111.  
  112.     /* Map number to scale : 2**nr = scale    */
  113.  
  114. int nr;
  115. {
  116.     int scale;
  117.  
  118.     for (scale = 1; nr > 0; nr--)
  119.         scale *= 2;
  120.     return scale;
  121. }
  122.  
  123. /*----------------------------------------------------------------------*/
  124. do_repaint()
  125. {
  126.     if (!window_get(my_frame, FRAME_CLOSED))
  127.     {
  128.         show_pic(GV.curx, GV.cury, GV.scale);
  129.     }
  130. }
  131.  
  132. /*----------------------------------------------------------------------*/
  133. do_select(window, event, arg)
  134.  
  135. Window    window;
  136. Event    *event;
  137. caddr_t    arg;
  138. {
  139.     static int    lx, ly, dragging = 0;
  140.     int        dx, dy, value, i;
  141.     static Menu    scale_menu = NULL;
  142.  
  143.     dx = (event_x(event) - (int) window_get(window, WIN_WIDTH )/2)
  144.             /GV.scale;
  145.     dy = (event_y(event) - (int) window_get(window, WIN_HEIGHT)/2)
  146.             /GV.scale; 
  147.  
  148.     switch (event_id(event))
  149.     {
  150.         case MS_LEFT:
  151.             if (event_is_up(event))
  152.                    show_pic(GV.curx+dx, GV.cury+dy, GV.scale);
  153.             break;
  154.  
  155.         case MS_MIDDLE:
  156.             if (event_is_down(event))
  157.             {
  158.                 lx = dx;
  159.                 ly = dy;
  160.                 dragging = 1;
  161.             }
  162.             else
  163.                 dragging = 0;
  164.             break;
  165.  
  166.         case LOC_MOVE:
  167.         case LOC_DRAG:
  168.             if (!dragging) break;
  169.             show_pic(GV.curx+lx-dx, GV.cury+ly-dy, GV.scale);
  170.             lx = dx;
  171.             ly = dy;
  172.             break;
  173.             
  174.             
  175.         case MS_RIGHT:
  176.                 scale_menu = menu_create(MENU_STRINGS,
  177.                     SCALEMENUSTRINGS, 0,
  178.                     0);
  179.             value = (int) menu_show(scale_menu, window, event, 0);
  180.             if (value == 0)
  181.                 return;
  182.             if (value == 1 && GV.scale < MAXSCALE)
  183.                 GV.scale *= 2;
  184.             else if (value == 2 && GV.scale > 1)
  185.                 GV.scale /= 2;
  186.             else
  187.                 return;
  188.  
  189.             panel_set_value(scale_item, scale_to_nr(GV.scale));
  190.                show_pic(GV.curx+dx, GV.cury+dy, GV.scale);
  191.             break;
  192.     }
  193. }
  194.  
  195. /*----------------------------------------------------------------------*/
  196. do_set_scale(item, value, event)
  197.  
  198. Panel_item    item;
  199. int        value;
  200. Event        *event;
  201. {
  202.     show_pic(GV.curx, GV.cury, nr_to_scale(value));
  203. }
  204.  
  205. /*----------------------------------------------------------------------*/
  206. do_set_color(item, value, event)
  207.  
  208. Panel_item    item;
  209. int        value;
  210. Event        *event;
  211. {
  212.     if (value == 0)
  213.         GV.depth = 1;
  214.     else
  215.         GV.depth = 8;
  216.  
  217.     window_set(my_canvas,
  218.         CANVAS_FAST_MONO, (GV.depth == 1 ? TRUE : FALSE),
  219.         0);
  220.     reset_plane_groups();
  221.     reset_colortable();
  222.     do_repaint();
  223. }
  224.  
  225. #define ITIMER_NULL ((struct itimerval *) NULL)
  226. /*----------------------------------------------------------------------*/
  227. do_set_update(item, value, event)
  228.  
  229. Panel_item    item;
  230. int        value;
  231. Event        *event;
  232. {
  233.     static int my_client_object;
  234.     static int *my_client = &my_client_object;
  235.  
  236.     struct itimerval timerval;
  237.  
  238.     if (value == 0)
  239.         notify_set_itimer_func(my_client, do_repaint, ITIMER_REAL,
  240.             NULL, ITIMER_NULL);
  241.     else
  242.     {
  243.         timerval.it_value.tv_usec = 0;
  244.         timerval.it_value.tv_sec  = 1;
  245.         if (value == 1)
  246.         {
  247.             timerval.it_interval.tv_usec = 0;
  248.             timerval.it_interval.tv_sec  = 1;
  249.         }
  250.         else
  251.         {
  252.             timerval.it_interval.tv_usec = 200;
  253.             timerval.it_interval.tv_sec  = 0;
  254.         }
  255.  
  256.         do_repaint();
  257.         notify_set_itimer_func(my_client, do_repaint, ITIMER_REAL,
  258.             &timerval, ITIMER_NULL);
  259.     }
  260. }
  261.  
  262. /*----------------------------------------------------------------------*/
  263. do_done()
  264. {
  265.     window_set(my_frame, FRAME_CLOSED, TRUE, 0);
  266. }
  267.  
  268. /*----------------------------------------------------------------------*/
  269. do_quit()
  270. {
  271.     if (window_destroy(my_frame))
  272.         exit(0);
  273. }
  274.         
  275. /*----------------------------------------------------------------------*/
  276. reset_colortable()
  277. {
  278. #define CMS_NAME    "GLASS_COLOUR"
  279. #define CMS_SIZE    256
  280.  
  281.     u_char    red[CMS_SIZE], green[CMS_SIZE], blue[CMS_SIZE];
  282.     Pixwin    *pw;
  283.  
  284.     if (GV.depth > 1)
  285.     {
  286.         pw = canvas_pixwin(my_canvas);
  287.         pr_getcolormap(scr_pr, 0, 256, red, green, blue);
  288.         pw_setcmsname(pw, CMS_NAME);
  289.         pw_putcolormap(pw, 0, CMS_SIZE, red, green, blue);
  290.     }
  291. }
  292.  
  293. /*----------------------------------------------------------------------*/
  294. static void select_proc(window, event)
  295.  
  296. Window        window;
  297. Event        *event;
  298. {
  299.     static  int dragging = 0;
  300.     int    cx, cy;
  301.  
  302.     switch (event_id(event))
  303.     {
  304.     case MS_LEFT:
  305.         if (event_is_down(event) || 
  306.            (event_is_up(event) && dragging > 5))
  307.             exit_grab(window, event);
  308.         dragging = 0;
  309.         break;
  310.  
  311.     case LOC_DRAG:
  312.         dragging++;
  313.         get_abs_pos(window, event_x(event), event_y(event), 
  314.             &cx, &cy);
  315.         show_pic(cx, cy, GV.scale);
  316.         break;
  317.         
  318.     default:
  319.         panel_default_handle_event(window, event); 
  320.         break;
  321.     }
  322. }
  323.  
  324. /*----------------------------------------------------------------------*/
  325. static void init_grab_proc(item, event)
  326.  
  327. Panel_item    item;
  328. Event        *event;
  329. {
  330.     Panel    panel;
  331.  
  332.     if (event_action(event) == MS_LEFT && event_is_down(event))
  333.     {
  334.         panel  = (Window) panel_get(item, PANEL_PARENT_PANEL);
  335.  
  336.         window_set(panel,
  337.             WIN_GRAB_ALL_INPUT, TRUE, 
  338.             WIN_EVENT_PROC, select_proc, 
  339.             WIN_CURSOR, select_cursor, 
  340.             0);
  341.  
  342.     }
  343. }
  344.  
  345. /*----------------------------------------------------------------------*/
  346. exit_grab(window, event)
  347.  
  348. Window    window;
  349. Event    *event;
  350. {
  351.     int    cx, cy;
  352.  
  353.         /* Disable grab all input and get look-up table */
  354.  
  355.     window_set(window, WIN_GRAB_ALL_INPUT, FALSE, 0);
  356.     reset_colortable();
  357.  
  358.         /* Set std_cursor invisible, grab all input, and get image */
  359.  
  360.     cursor_set(std_cursor, CURSOR_SHOW_CURSOR, FALSE, 0);
  361.     window_set(window, 
  362.         WIN_GRAB_ALL_INPUT, TRUE,
  363.         WIN_CURSOR, std_cursor,
  364.         0);
  365.     get_abs_pos(window, event_x(event), event_y(event), &cx, &cy);
  366.     show_pic(cx, cy, GV.scale);
  367.  
  368.         /* Set std_cursor visible, and reset grab all input    */
  369.  
  370.     cursor_set(std_cursor, CURSOR_SHOW_CURSOR, TRUE, 0);
  371.     window_set(window, 
  372.         WIN_GRAB_ALL_INPUT, FALSE,
  373.         WIN_EVENT_PROC, NULL, 
  374.         WIN_CURSOR, std_cursor, 
  375.         0);
  376. }
  377.  
  378. /*----------------------------------------------------------------------*/
  379. show_pic(cx, cy, scale)
  380.  
  381. int    cx, cy;
  382. register int scale;
  383. {
  384.     int    dw, dh, dws, dhs;
  385.     Pixwin    *pw;
  386.  
  387.     pw = canvas_pixwin(my_canvas);
  388.  
  389.     dw = (int) window_get(my_canvas, WIN_WIDTH);
  390.     dh = (int) window_get(my_canvas, WIN_HEIGHT);
  391.     dws = dw/scale;
  392.     dhs = dh/scale;
  393.  
  394.     if (cx - dws/2 <= 0) cx = dws/2;
  395.     if (cy - dhs/2 <= 0) cy = dhs/2;
  396.  
  397.     if (cx + dws/2 >= scr_pr->pr_width)  cx = scr_pr->pr_width - dws/2;
  398.     if (cy + dhs/2 >= scr_pr->pr_height) cy = scr_pr->pr_height- dhs/2;
  399.  
  400.     GV.curx  = cx;
  401.     GV.cury  = cy;
  402.     GV.scale = scale;
  403.  
  404.     show_scaled(pw, 0, 0, dw, dh, scale, scr_pr, cx - dws/2, cy - dhs/2);
  405. }
  406.  
  407. /*----------------------------------------------------------------------*/
  408. get_abs_pos(win, rx, ry, cx, cy)
  409.  
  410. Window    win;
  411. int    rx, ry, *cx, *cy;
  412. {
  413.     *cx = rx;
  414.     *cy = ry;
  415.  
  416.     while (1)
  417.     {
  418.         *cx += (int) window_get(win, WIN_X) + 
  419.                (int) window_get(win, WIN_LEFT_MARGIN);
  420.         *cy += (int) window_get(win, WIN_Y) +
  421.                (int) window_get(win, WIN_TOP_MARGIN);
  422.         win = (Window) window_get(win, WIN_OWNER);
  423.         if (win == NULL)
  424.             break;
  425.     }
  426. }
  427.  
  428. /*----------------------------------------------------------------------*/
  429. reset_plane_groups()
  430. {
  431.     int groups[10];
  432.  
  433.     pr_available_plane_groups(scr_pr, 10, groups);
  434.  
  435.     if (GV.depth == 8 && groups[PIXPG_8BIT_COLOR])
  436.         pr_set_plane_group(scr_pr, PIXPG_8BIT_COLOR);
  437.     else if (GV.depth == 1 && groups[PIXPG_8BIT_COLOR])
  438.         pr_set_plane_group(scr_pr, PIXPG_OVERLAY);
  439.     else 
  440.     {
  441.         pr_set_plane_group(scr_pr, PIXPG_MONO);
  442.         GV.depth = 1;
  443.     }
  444. }
  445.  
  446. /*----------------------------------------------------------------------*/
  447. init_screen()
  448. {
  449.     scr_pr = pr_open("/dev/fb");
  450.     reset_plane_groups();
  451. }
  452.  
  453. /*----------------------------------------------------------------------*/
  454. main(argc, argv)
  455. int argc;
  456. char *argv[];
  457. {
  458.     Panel    panel;
  459.     Icon    icon;
  460.  
  461.     init_screen();
  462.     init_scaletable(MAXSCALE);
  463.  
  464.     icon      = icon_create(ICON_IMAGE, &glas_pr, 0);
  465.     my_frame  = window_create(NULL, FRAME, 
  466.             FRAME_LABEL, "lglass",
  467.             FRAME_ICON,  icon,
  468.             FRAME_ARGS,  argc, argv, 
  469.             0);
  470.  
  471.     panel  = window_create(my_frame, PANEL, 0); 
  472.  
  473.     panel_create_item(panel, PANEL_BUTTON,
  474.         PANEL_LABEL_IMAGE, panel_button_image(panel, "Select", 0, 0),
  475.         PANEL_EVENT_PROC, init_grab_proc, 0);
  476.  
  477.     panel_create_item(panel, PANEL_BUTTON,
  478.         PANEL_LABEL_IMAGE, panel_button_image(panel, "Redraw", 0, 
  479.                 0),
  480.         PANEL_NOTIFY_PROC, do_repaint, 0);
  481.  
  482.     panel_create_item(panel, PANEL_BUTTON,
  483.         PANEL_LABEL_IMAGE, panel_button_image(panel, "Done", 0, 
  484.                 0),
  485.         PANEL_NOTIFY_PROC, do_done, 0);
  486.  
  487.     panel_create_item(panel, PANEL_BUTTON,
  488.         PANEL_LABEL_IMAGE, panel_button_image(panel, "Quit", 0, 
  489.                 0),
  490.         PANEL_NOTIFY_PROC, do_quit, 0);
  491.  
  492.     window_fit_width(panel);
  493.     window_fit_width(my_frame);
  494.  
  495.     scale_item = panel_create_item(panel, PANEL_CHOICE,
  496.         PANEL_LABEL_STRING, "Scale :",
  497.         PANEL_CHOICE_STRINGS, SCALESTRINGS, 0,
  498.         PANEL_NOTIFY_PROC, do_set_scale, 
  499.         0);
  500.  
  501.     panel_create_item(panel, PANEL_CHOICE,
  502.         PANEL_LABEL_STRING, "Update:",
  503.         PANEL_CHOICE_STRINGS, UPDATEMENUSTRINGS, 0,
  504.         PANEL_NOTIFY_PROC, do_set_update, 
  505.         0);
  506.  
  507.     panel_create_item(panel, PANEL_CHOICE,
  508.         PANEL_LABEL_STRING, "Color :",
  509.         PANEL_CHOICE_STRINGS, COLORSTRINGS, 0,
  510.         PANEL_NOTIFY_PROC, do_set_color, 
  511.         0);
  512.  
  513.     window_fit(panel);
  514.  
  515.     std_cursor = cursor_copy((Cursor) window_get(panel, WIN_CURSOR));
  516.     select_cursor = cursor_create(CURSOR_IMAGE, &select_pr, 
  517.             CURSOR_XHOT, 2,
  518.             CURSOR_YHOT, 2,
  519.             0);
  520.  
  521.     my_canvas = window_create(my_frame, CANVAS,
  522.         CANVAS_RETAINED, FALSE,
  523.         CANVAS_REPAINT_PROC, do_repaint,
  524.         CANVAS_FAST_MONO, (GV.depth == 1 ? TRUE : FALSE),
  525.         WIN_X, 0,
  526.         WIN_BELOW, panel,
  527.         WIN_HEIGHT, (int) window_get(panel, WIN_WIDTH),
  528.         WIN_EVENT_PROC, do_select,
  529.         0);
  530.     window_fit(my_frame);
  531.     window_main_loop(my_frame);
  532. }
  533. @@@ End of lglass.c
  534. echo show.c
  535. cat >show.c <<'@@@ End of show.c'
  536. /*************************************************************************
  537.  Lglass: screen viewer for the Sun Workstation running SunView
  538.    Copyright (c) 1989 by Jack van Wijk
  539.    7/24/89 @ Netherlands Energy Research Foundation, ECN
  540.  
  541.    This program may be redistributed without fee as long as this copyright
  542.    notice is intact.
  543.  
  544. ---------- Netherlands Energy Research Foundation, ECN ------------------
  545. Jack (Jarke J.) van Wijk                  UUCP : jack@ecn.uucp
  546. P.O. Box 1, 1755 ZG  Petten(NH)           ARPA : ecn!jack@nluug.nl
  547. Holland    phone: +31 2246 4333                  ecn!jack@uunet.uu.net
  548. *************************************************************************/
  549.  
  550. #include <suntool/sunview.h>
  551. #include <suntool/window.h>
  552.  
  553. static u_char **scaletable;
  554.  
  555. /*----------------------------------------------------------------------*/
  556. init_scaletable(max_scale)
  557. int    max_scale;
  558. {
  559.     int i, j, k, bit, scale, srcbit;
  560.     u_char *tab;
  561.  
  562.     scaletable = (u_char **) 
  563.              malloc((scale_to_nr(max_scale)+1)*sizeof(u_char *));
  564.     scale = 2;
  565.     for (scale = 2, i=1; 
  566.          scale < 64; 
  567.          i++, scale *=2) /* For each scale a set */
  568.     {
  569.         scaletable[i] = (u_char *) malloc(16*scale/2);
  570.         tab = scaletable[i];
  571.         for (j = 0; j < 16; j++) /* For each nibble */
  572.         for (k = scale/2-1; k>=0; k--) /* For each scaled nibble */
  573.         {
  574.             *tab = 0;
  575.             for (bit = 7; bit >= 0; bit--) /* For each bit of dst */
  576.             {
  577.                srcbit = (8*k+bit)/scale; /* inverse mapping */
  578.                 if ((j >> srcbit) & 1)
  579.                     *tab |= 1 << bit;
  580.             }
  581.             tab++;
  582.         }
  583.     }
  584. }
  585.     
  586. /*----------------------------------------------------------------------*/
  587. static mem_scale8(mem_src, mem_dst, dh, scale)
  588.  
  589. Pixrect    *mem_src, *mem_dst;
  590. int    dh, scale;
  591. {
  592.     register u_char    *lxsrc, *lxdst, *lxmax;
  593.     u_char    *lysrc, *lydst, *lymax;
  594.     int        lbsrc, lbdst;
  595.     int    i;
  596.  
  597.         /* Calculate memory locations */
  598.  
  599.     lbsrc = mpr_d(mem_src)->md_linebytes;
  600.     lbdst = mpr_d(mem_dst)->md_linebytes;
  601.  
  602.     lysrc = (u_char *) mpr_d(mem_src)->md_image;
  603.     lydst = (u_char *) mpr_d(mem_dst)->md_image;
  604.     lymax = lysrc + (dh/scale+1)*lbsrc;
  605.  
  606.         /* Scale image in memory */
  607.  
  608.     for (;lysrc < lymax; lysrc += lbsrc, lydst += scale*lbdst)
  609.     {
  610.         lxsrc = lysrc;
  611.         lxdst = lydst;
  612.         lxmax = lxsrc + lbsrc;
  613.  
  614.         for (; lxsrc < lxmax; lxsrc++)
  615.         {
  616.             for (i=0; i < scale; i++) 
  617.                 *lxdst++ = *lxsrc;
  618.         }
  619.         for (i=1; i < scale; i++)
  620.             memcpy(lydst+i*lbdst, lydst, lbdst);
  621.     }
  622. }
  623.  
  624. /*----------------------------------------------------------------------*/
  625. static mem_scale1(mem_src, mem_dst, dh, scale)
  626.  
  627. Pixrect    *mem_src, *mem_dst;
  628. int    dh, scale;
  629. {
  630.     int        lbsrc, lbdst;
  631.     register u_char    *lxsrc, *lxdst, *lxmax;
  632.     u_char        *lysrc, *lydst, *lymax;
  633.     register u_char    *tab, *v1, *v2;
  634.     register int    i, nscale;
  635.  
  636.     tab = scaletable[scale_to_nr(scale)];
  637.  
  638.     lbsrc = mpr_d(mem_src)->md_linebytes;
  639.     lbdst = mpr_d(mem_dst)->md_linebytes;
  640.  
  641.     lysrc = (u_char *) mpr_d(mem_src)->md_image;
  642.     lydst = (u_char *) mpr_d(mem_dst)->md_image;
  643.     lymax = lysrc + (dh/scale+1)*lbsrc;
  644.  
  645.     nscale= scale / 2;
  646.  
  647.     for (;lysrc < lymax; lysrc += lbsrc, lydst += scale*lbdst)
  648.     {
  649.         lxsrc = lysrc;
  650.         lxdst = lydst;
  651.         lxmax = lxsrc + lbsrc;
  652.  
  653.         for (; lxsrc < lxmax; lxsrc++)
  654.         {
  655.             v1 = tab + (*lxsrc >> 4) * nscale;
  656.             v2 = tab + (*lxsrc & 15) * nscale;
  657.             if (nscale == 1)
  658.             {
  659.                 *lxdst++ = *v1;
  660.                 *lxdst++ = *v2;
  661.             }
  662.             else
  663.             {
  664.                 memcpy(lxdst, v1, nscale);
  665.                 lxdst += nscale;
  666.                 memcpy(lxdst, v2, nscale);
  667.                 lxdst += nscale;
  668.             }
  669.         }
  670.         for (i=1; i < scale; i++)
  671.             memcpy(lydst+i*lbdst, lydst, lbdst);
  672.     }
  673. }
  674.  
  675. /*----------------------------------------------------------------------*/
  676. show_scaled(pw, dx, dy, dw, dh, scale, pr, sx, sy)
  677.  
  678. Pixwin    *pw;
  679. int    dx, dy, dw, dh, scale;
  680. Pixrect    *pr;
  681. int    sx, sy;
  682. {
  683.     static Pixrect    *mem_src=NULL, *mem_dst=NULL;
  684.  
  685.     if (scale == 1)
  686.     {
  687.         pw_write(pw, dx, dy, dw, dh,
  688.             PIX_SRC, 
  689.             pr, sx, sy);
  690.         return;
  691.     }
  692.  
  693.         /* Allocate memory buffers */
  694.  
  695.     if (mem_src == NULL || 
  696.         mem_src->pr_width != dw/scale + 1 || 
  697.         mem_src->pr_height!= dh/scale + 1 ||
  698.         mem_src->pr_depth != pr->pr_depth)
  699.     {
  700.         if (mem_src != NULL)
  701.             pr_destroy(mem_src);
  702.         mem_src = mem_create(dw/scale+1, dh/scale+1, pr->pr_depth);
  703.     }
  704.  
  705.     if (mem_dst == NULL || 
  706.         mem_dst->pr_width != (dw/scale + 1)*scale || 
  707.         mem_dst->pr_height!= (dh/scale + 1)*scale ||
  708.         mem_dst->pr_depth != pr->pr_depth)
  709.     {
  710.         if (mem_dst != NULL)
  711.             pr_destroy(mem_dst);
  712.         mem_dst = mem_create((dw/scale + 1)*scale,
  713.                      (dh/scale + 1)*scale,
  714.                      pr->pr_depth);
  715.     }
  716.  
  717.         /* Read source image into memory    */
  718.  
  719.     pr_rop(mem_src, 0, 0, 
  720.         (dw/scale +1)*scale,
  721.         (dh/scale +1)*scale,
  722.         PIX_SRC,
  723.         pr,
  724.         sx, sy);
  725.  
  726.         /* Scale memory to memory    */
  727.  
  728.     if (pr->pr_depth == 8)
  729.         mem_scale8(mem_src, mem_dst, dh, scale);
  730.     else
  731.         mem_scale1(mem_src, mem_dst, dh, scale);
  732.  
  733.         /* Copy memory to destination pixwin    */
  734.  
  735.     pw_write(pw, dx, dy, dw, dh,
  736.         PIX_SRC, 
  737.         mem_dst,
  738.         0, 0);
  739. }
  740. @@@ End of show.c
  741. echo select.cursor
  742. cat >select.cursor <<'@@@ End of select.cursor'
  743. /* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16
  744.  */
  745.     0x1F00,0x2080,0x4040,0x8020,0x8020,0x8020,0x8020,0x8020,
  746.     0x4060,0x20D0,0x1FA8,0x0054,0x002A,0x0015,0x000A,0x0004
  747. @@@ End of select.cursor
  748. echo lglass.icon
  749. cat >lglass.icon <<'@@@ End of lglass.icon'
  750. /* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
  751.  */
  752.     0x8888,0x8888,0x8FF8,0x8888,0x8888,0x8888,0xFFFF,0x8888,
  753.     0x2222,0x2223,0xF007,0xE222,0x2222,0x222F,0x8FF8,0xFA22,
  754.     0x8888,0x889C,0x7C0F,0x1C88,0x8888,0x88B9,0x8C0C,0xCE88,
  755.     0x2222,0x22E6,0x0C0C,0x33A2,0x2222,0x23CC,0x0C0C,0x0962,
  756.     0x8888,0x8990,0xC0C0,0xC4C8,0x8888,0x8B20,0xC0C0,0xC268,
  757.     0x2222,0x2640,0xC0C0,0xC132,0x2222,0x2AC0,0xC0C0,0xC0AA,
  758.     0x8888,0x8D0C,0x0C0C,0x0C58,0x8888,0x990C,0x0C0C,0x0C4C,
  759.     0x2222,0x3A0C,0x0C0C,0x0C2E,0x2222,0x3A0C,0x0C0C,0x0C2E,
  760.     0x8888,0xB4C0,0xC0C0,0xC0D6,0x8888,0xB4C0,0xC0C0,0xC0D6,
  761.     0x2222,0x34C0,0xC0C0,0xC0D6,0x2222,0x68C0,0xC0C0,0xC0CB,
  762.     0x8888,0xEC0C,0x0C0C,0x0C0B,0x8888,0xEC0C,0x0C0C,0x0C0B,
  763.     0x2222,0x6C0C,0x0C0C,0x0C0B,0x2222,0x6C0C,0x0C0C,0x0C0B,
  764.     0x8888,0xE8C0,0xC0C0,0xC0CB,0x8888,0xE8C0,0xC0C0,0xC0CB,
  765.     0x2222,0x68C0,0xC0C0,0xC0CB,0x2222,0x68C0,0xC0C0,0xC0CB,
  766.     0x8888,0xB40C,0x0C0C,0x0C16,0x8888,0xB40C,0x0C0C,0x0C16,
  767.     0x2222,0x340C,0x0C0C,0x0C16,0x2222,0x3A0C,0x0C0C,0x0C2E,
  768.     0x8888,0x9AC0,0xC0C0,0xC0EC,0x8888,0x99C0,0xC0C0,0xC0CC,
  769.     0x2222,0x2DC0,0xC0C0,0xC0DA,0x2222,0x2AC0,0xC0C0,0xC0BA,
  770.     0x8888,0x9E4C,0x0C0C,0x0D38,0x8888,0xBB2C,0x0C0C,0x0E68,
  771.     0x2222,0x669C,0x0C0C,0x0CE2,0x2222,0x198C,0x0C0C,0x09E2,
  772.     0x8889,0x1766,0xC0C0,0xF388,0x888B,0x0EE9,0xC0C0,0xCE88,
  773.     0x2226,0xE5D4,0x70C7,0x1E22,0x222D,0xB3BF,0x8FF8,0xFA22,
  774.     0x889B,0x71BB,0xF007,0xE888,0x88B6,0xE878,0xFFFF,0x8888,
  775.     0x226D,0xDE62,0x2FFA,0x2222,0x22DB,0xBA22,0x2222,0x2222,
  776.     0x89B7,0x7688,0x8888,0x8888,0x8B6E,0xED88,0x8888,0x8888,
  777.     0x26DD,0xDBA2,0x2222,0x2222,0x2DBB,0xB622,0x2222,0x2222,
  778.     0x9B77,0x6C88,0x8888,0x8888,0xB6EE,0xD888,0x8888,0x8888,
  779.     0x6DDD,0xB222,0x2222,0x2222,0x3BBB,0x6222,0x2222,0x2222,
  780.     0x9776,0xC888,0x8888,0x8888,0x8EED,0x8888,0x8888,0x8888,
  781.     0x2DDB,0x2222,0x2222,0x2222,0x23B6,0x2222,0x2222,0x2222,
  782.     0x8B6C,0x8888,0x8888,0x8888,0x88D8,0x8888,0x8888,0x8888,
  783.     0x22B2,0x2222,0x2222,0x2222,0x2262,0x2222,0x2222,0x2222
  784. @@@ End of lglass.icon
  785. echo lglass.man
  786. cat >lglass.man <<'@@@ End of lglass.man'
  787. .TH LGLASS 1 "24 July 1989"
  788. .SH NAME
  789. lglass\- look at your screen through a looking-glass
  790. .SH SYNOPSIS
  791. .B lglass
  792. .SH DESCRIPTION
  793. .LP
  794. \fILglass\fP is SunView-based tool for examining the screen.
  795. At each moment an area around a selected spot is displayed at a
  796. user-definable scale.
  797. After start-up a window appears, divided in two sub-windows:
  798. a control-panel for setting options, and a canvas for showing the
  799. selected part of the screen.
  800. The buttons have the following meaning:
  801. .IP \fBSelect\fP 10
  802. Enables the user to change the currently selected spot on the screen.
  803. After pressing the button, the cursor changes to a looking-glass.
  804. When the left mouse-button is pressed, a new spot is selected, and
  805. the area around it is displayed in the canvas.
  806. With the middle-button down, the spot can be dragged, and the currently
  807. selected area is modified dynamically.
  808. When the middle-button is released, the selection is made.
  809. .IP \fBRedraw\fP 10
  810. Redraw the canvas according to the current setting.
  811. .IP \fBDone\fP 10
  812. Close the window.
  813. A looking-glass icon appears.
  814. .IP \fBQuit\fP 10
  815. Quit from lglass.
  816. .LP
  817. The choices below the buttons mean:
  818. .IP \fBScale\fP 10
  819. Select the scale for enlarging the screen.
  820. .IP \fBUpdate\fP 10
  821. Select the mode for updating the canvas: \fIoff\fP - no update;
  822. \fIslow\fP - update canvas each second; and \fIfast\fP - update canvas
  823. each 1/5th second.
  824. .IP \fBColor\fP 10
  825. Select whether black-and-white planes, or color-planes must be shown.
  826. .LP
  827. Further the scaled image can be modified when the cursor is inside
  828. the canvas. 
  829. With the \fIleft-button\fP a new spot can be selected: the canvas is redrawn,
  830. with the selected spot at the center of the canvas.
  831. With the \fImiddle-button\fP the image can be dragged.
  832. When the \fIright-button\fP is pressed, a menu appears showing \fBzoom in,
  833. zoom out\fP.
  834. After a choice is made, the canvas is redrawn at a modified scale,
  835. with the selected spot at the center of the canvas.
  836. .SH AUTHOR
  837. Jack van Wijk, ECN, PO box 1, 1755 ZG  Petten (NH), Holland.
  838. .SH BUGS
  839. Please contact me about bugs and wishes.
  840. .SH NOTES
  841. The development of \fIlglass\fP is part of a research project of the
  842. \fINetherlands Energy Research Foundation (ECN), Petten (NH),
  843. Holland\fP.
  844. @@@ End of lglass.man
  845. exit 0
  846.