home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / X / XtAppInitwIcon / testicon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  13.0 KB  |  486 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*------------------------------------------------------------------------
  18.  * Test the ability to create color icons.
  19.  *
  20.  * New functions used:
  21.  *    XGetIconSizes
  22.  *    XAllocIconSize
  23.  *    XAllocWMHints
  24.  *    XSetWMHints
  25.  *
  26.  * Events that I've figured out can be handled:
  27.  *    When created:
  28.  *     1  ConfigureNotify
  29.  *     2  ReparentNotify
  30.  *    While main window is up:
  31.  *     <none>
  32.  *    Turned into an icon:
  33.  *     1  MapNotify
  34.  *     2  VisibilityNotify
  35.  *     3  Expose            Only if icon visible
  36.  *    Cursor movement:
  37.  *     1  EnterNotify
  38.  *     2  MotionNotify        Only 1 ever received
  39.  *     3  LeaveNotify
  40.  *    Returned to main window:
  41.  *     1  UnmapNotify
  42.  *     2  LeaveNotify
  43.  *    Make icon visible:
  44.  *     1  VisibilityNotify
  45.  *     2  Expose
  46.  *    Button pushes within icon:
  47.  *     1  LeaveNotify
  48.  *     2  EnterNotify
  49.  *    Keys within icon:
  50.  *     1  KeyPress
  51.  *     2  KeyRelease
  52.  *------------------------------------------------------------------------*/
  53.  
  54. #include <stdio.h>
  55. #include <unistd.h>
  56. #include <signal.h>
  57.  
  58. #include "Initialize.h"
  59.  
  60. #include <Xm/Xm.h>
  61. #include <Xm/Label.h>
  62.  
  63. /*------------------------------------------------------------------------
  64.  * DEBUG uses
  65.  *    0x0001        Print Window IDs.
  66.  *    0x0002        Print Events processed by Icon.
  67.  *    0x0004        Print colors used.
  68.  *    0x0008        Print information on sizes of icons allowed.
  69.  *------------------------------------------------------------------------*/
  70.  
  71. #define DEBUG    0x0000
  72.  
  73. #define WINDOW_BACKGROUND    "Blue"
  74. #define GC_BACKGROUND        "Red"
  75. #define GC_FOREGROUND        "Yellow"
  76. #define BLOCK_X            4
  77. #define BLOCK_Y            4
  78. #define BLOCK_HEIGHT        50
  79. #define BLOCK_WIDTH        50
  80.  
  81. /*----
  82.  * This structure is used to print out what event was received.
  83.  *----*/
  84.  
  85. #define TABLE_ENTRY(x)        { (x), #x }
  86.  
  87. struct { int value; char* string; } event_names[] = {
  88.     TABLE_ENTRY (KeyPress),
  89.     TABLE_ENTRY (KeyRelease),
  90.     TABLE_ENTRY (ButtonPress),
  91.     TABLE_ENTRY (ButtonRelease),
  92.     TABLE_ENTRY (MotionNotify),
  93.     TABLE_ENTRY (EnterNotify),
  94.     TABLE_ENTRY (LeaveNotify),
  95.     TABLE_ENTRY (FocusIn),
  96.     TABLE_ENTRY (FocusOut),
  97.     TABLE_ENTRY (KeymapNotify),
  98.     TABLE_ENTRY (Expose),
  99.     TABLE_ENTRY (GraphicsExpose),
  100.     TABLE_ENTRY (NoExpose),
  101.     TABLE_ENTRY (VisibilityNotify),
  102.     TABLE_ENTRY (CreateNotify),
  103.     TABLE_ENTRY (DestroyNotify),
  104.     TABLE_ENTRY (UnmapNotify),
  105.     TABLE_ENTRY (MapNotify),
  106.     TABLE_ENTRY (MapRequest),
  107.     TABLE_ENTRY (ReparentNotify),
  108.     TABLE_ENTRY (ConfigureNotify),
  109.     TABLE_ENTRY (ConfigureRequest),
  110.     TABLE_ENTRY (GravityNotify),
  111.     TABLE_ENTRY (ResizeRequest),
  112.     TABLE_ENTRY (CirculateNotify),
  113.     TABLE_ENTRY (CirculateRequest),
  114.     TABLE_ENTRY (PropertyNotify),
  115.     TABLE_ENTRY (SelectionClear),
  116.     TABLE_ENTRY (SelectionRequest),
  117.     TABLE_ENTRY (SelectionNotify),
  118.     TABLE_ENTRY (ColormapNotify),
  119.     TABLE_ENTRY (ClientMessage),
  120.     TABLE_ENTRY (MappingNotify),
  121. };
  122.  
  123. Window            icon_window;
  124. GC            graphics_context;
  125. Display            *display;
  126. int            block_width = BLOCK_WIDTH, block_height = BLOCK_HEIGHT;
  127. int            block_x = BLOCK_X, block_y = BLOCK_Y;
  128. int            icon_mapped = 0;
  129.  
  130. /*------------------------------------------------------------------------
  131.  * Set up Icon function
  132.  *    This function is called by XtAppInitializeWithIcon to perform
  133.  *    whatever is necessary to create the icon window.
  134.  *------------------------------------------------------------------------*/
  135.  
  136. Window createIconWindow (Display *dpy,
  137. #if XtSpecificationRelease > 4
  138.              int *argc,
  139. #else
  140.              Cardinal *argc,
  141. #endif
  142.              String *argv)
  143. {
  144.     int            i, status;
  145.     XIconSize        *icon_sizes, *icon_size;
  146.     int            number_of_sizes;
  147.     unsigned int    border_width;
  148.     int            depth;
  149.     Visual        *visual;
  150.     unsigned long    background, border;
  151.     XSetWindowAttributes    window_attributes;
  152.     unsigned long    valuemask;
  153.     unsigned int    class;
  154.     XColor           backColor, tmpColor;
  155.     XGCValues        gc_values;
  156.  
  157.     /*----
  158.      * Find out what icon sizes are allowed.
  159.      *----*/
  160.  
  161.     status = XGetIconSizes (dpy, DefaultRootWindow (dpy),
  162.                 &icon_sizes, &number_of_sizes);
  163.     if (status == 0)
  164.     {
  165.     fprintf (stderr, "Unable to get icon sizes from window manager.\n");
  166.     return NULL;
  167.     }
  168.  
  169. #if DEBUG & 8
  170.     printf ("Number of icon sizes given is %d\n", number_of_sizes);
  171.     for (i = 0; i < number_of_sizes; i++)
  172.     {
  173.     icon_size = &icon_sizes[i];
  174.     printf ("Size %d\n", i);
  175.     printf ("  Minimum width     %d, height     %d\n",
  176.         icon_size->min_width, icon_size->min_height);
  177.     printf ("  Maximum width     %d, height     %d\n",
  178.         icon_size->max_width, icon_size->max_height);
  179.     printf ("  Increment width   %d, height     %d\n",
  180.         icon_size->width_inc, icon_size->height_inc);
  181.     }
  182. #endif
  183.  
  184.     /*----
  185.      * Set up the variables needed to create the icon window.
  186.      *       class    As specified in the manual.
  187.      *       visual    Same as root window (because it will be reparented
  188.      *              to the root window).
  189.      *       depth    Same as root window.
  190.      *       border_width    Whatever.
  191.      *       valuemask    Attributes that I want to set.  I want to get
  192.      *               some events and if I don't set the background
  193.      *            pixel value, the window comes up with garbage.
  194.      *       window_attributes.event_mask
  195.      *            This is all the possible events because I want
  196.      *            to see what events are passed on to the icon.
  197.      *----*/
  198.  
  199.     class = InputOutput;
  200.     visual = DefaultVisual (dpy, DefaultScreen (dpy));
  201.     depth = DefaultDepth (dpy, DefaultScreen (dpy));
  202.  
  203.     border_width = 10;            /* I made this number up */
  204.     valuemask = CWEventMask | CWBackPixel;
  205.     window_attributes.event_mask = (
  206.                     KeyPressMask |
  207.                     KeyReleaseMask |
  208.                     ButtonPressMask |
  209.                     ButtonReleaseMask |
  210.                     EnterWindowMask |
  211.                     LeaveWindowMask |
  212.                     PointerMotionMask |
  213.                     PointerMotionHintMask |
  214.                     Button1MotionMask |
  215.                     Button2MotionMask |
  216.                     Button3MotionMask |
  217.                     Button4MotionMask |
  218.                     Button5MotionMask |
  219.                     ButtonMotionMask |
  220.                     KeymapStateMask |
  221.                     ExposureMask |
  222.                     VisibilityChangeMask |
  223.                     StructureNotifyMask |
  224.                     ResizeRedirectMask |
  225.                     SubstructureNotifyMask |
  226.                     SubstructureRedirectMask |
  227.                     FocusChangeMask |
  228.                     PropertyChangeMask |
  229.                     ColormapChangeMask |
  230.                     OwnerGrabButtonMask);
  231.  
  232.     /*----
  233.      * In order to set the background pixel value, I have to get it.
  234.      *----*/
  235.  
  236.     if (!XAllocNamedColor (dpy, DefaultColormap (dpy, 0), WINDOW_BACKGROUND,
  237.                &backColor, &tmpColor))
  238.     fprintf (stderr, "Unable to find '%s' in database\n",
  239.          WINDOW_BACKGROUND);
  240. #if DEBUG & 0x0004
  241.     else
  242.     {
  243.     fprintf (stderr, "%s color is 0x%08x = %02x %02x %02x\n",
  244.          WINDOW_BACKGROUND, backColor.pixel,
  245.          backColor.red, backColor.green, backColor.blue);
  246.     fprintf (stderr, "Color found is 0x%08x = %02x %02x %02x\n",
  247.          tmpColor.pixel,
  248.          tmpColor.red, tmpColor.green, tmpColor.blue);
  249.     }
  250. #endif
  251.  
  252.     window_attributes.background_pixel = backColor.pixel;
  253.  
  254.     /*----
  255.      * OK, now we actually create the icon window.
  256.      *----*/
  257.  
  258.     icon_window = XCreateWindow (dpy, DefaultRootWindow (dpy),
  259.                  0, 0,
  260.                  icon_sizes->max_width, icon_sizes->max_height,
  261.                  border_width, depth, class, visual,
  262.                  valuemask, &window_attributes);
  263.  
  264.     /*----
  265.      * Now, for the fun of it, let's create a graphics context
  266.      * so that other routines can draw.  This could be done anywhere.
  267.      *        1) Set up a different background color in the
  268.      *           graphics context (to find out what it does).
  269.      *        2) Set up a foreground color.
  270.      *        3) Define the line width.
  271.      *        4) Define the line style.
  272.      *----*/
  273.  
  274.     if (!XAllocNamedColor (dpy, DefaultColormap (dpy, 0), GC_BACKGROUND,
  275.                &backColor, &tmpColor))
  276.     fprintf (stderr, "Unable to find '%s' in database\n",
  277.          GC_BACKGROUND);
  278. #if DEBUG & 0x0004
  279.     else
  280.     {
  281.     fprintf (stderr, "%s color is 0x%08x = %02x %02x %02x\n",
  282.          GC_BACKGROUND, backColor.pixel,
  283.          backColor.red, backColor.green, backColor.blue);
  284.     fprintf (stderr, "Color found is 0x%08x = %02x %02x %02x\n",
  285.          tmpColor.pixel,
  286.          tmpColor.red, tmpColor.green, tmpColor.blue);
  287.     }
  288. #endif
  289.  
  290.     gc_values.background = backColor.pixel;
  291.  
  292.     if (!XAllocNamedColor (dpy, DefaultColormap (dpy, 0), GC_FOREGROUND,
  293.                &backColor, &tmpColor))
  294.     fprintf (stderr, "Unable to find '%s' in database\n",
  295.          GC_FOREGROUND);
  296. #if DEBUG & 0x0004
  297.     else
  298.     {
  299.     fprintf (stderr, "%s color is 0x%08x = %02x %02x %02x\n",
  300.          GC_FOREGROUND, backColor.pixel,
  301.          backColor.red, backColor.green, backColor.blue);
  302.     fprintf (stderr, "Color found is 0x%08x = %02x %02x %02x\n",
  303.          tmpColor.pixel,
  304.          tmpColor.red, tmpColor.green, tmpColor.blue);
  305.     }
  306. #endif
  307.  
  308.     gc_values.foreground = backColor.pixel;
  309.     gc_values.line_width = 1;
  310.     gc_values.line_style = LineSolid;
  311.     graphics_context = XCreateGC (dpy, icon_window,
  312.                   (GCForeground | GCBackground | GCLineWidth |
  313.                    GCLineStyle),
  314.                   &gc_values);
  315.  
  316.     return icon_window;
  317. }
  318.  
  319. /*------------------------------------------------------------------------
  320.  * find_table_entry
  321.  *    Just a little function for determining the index into the
  322.  *    event_names table that a particular event is described in.
  323.  *    This allows us to print the name of the event when it is
  324.  *    processed.
  325.  *------------------------------------------------------------------------*/
  326.  
  327. int find_table_entry (int val)
  328. {
  329.     int        i;
  330.  
  331.     for (i = 0; i < XtNumber (event_names); i++)
  332.     {
  333.     if (event_names[i].value == val)
  334.         return i;
  335.     }
  336.  
  337.     return -1;
  338. }
  339.  
  340. /*------------------------------------------------------------------------
  341.  * draw_icon
  342.  *    Just a simple routine which is called whenever we need to
  343.  *    redraw the contents of the icon.
  344.  *------------------------------------------------------------------------*/
  345.  
  346. void draw_icon (int motion, XEvent event)
  347. {
  348.     static int        direction = 1;
  349.  
  350.     if (motion == 2)
  351.     {
  352.     if (direction)
  353.     {
  354.         block_x++;
  355.         block_width -= 2;
  356.         if (block_width <= 1)
  357.         direction--;
  358.     }
  359.     else
  360.     {
  361.         block_x--;
  362.         block_width += 2;
  363.         if (block_width == BLOCK_WIDTH)
  364.         direction++;
  365.     }
  366.     }
  367.  
  368.     XClearWindow (display, icon_window);
  369.     XFillRectangle (display, icon_window, graphics_context, block_x, block_y,
  370.             block_width, block_height);
  371.  
  372.     XSync (display, FALSE);
  373. }
  374.  
  375. /*------------------------------------------------------------------------
  376.  * update    Update the icon when alarm occurs.
  377.  *------------------------------------------------------------------------*/
  378.  
  379. void update ()
  380. {
  381.     XEvent    event;
  382.  
  383.     if (icon_mapped)
  384.     {
  385.     draw_icon (2, event);
  386.     alarm (1);
  387.     }
  388. }
  389.  
  390. /*------------------------------------------------------------------------
  391.  * MAIN
  392.  *------------------------------------------------------------------------*/
  393.  
  394. main (int argc, char *argv[])
  395. {
  396.     XtAppContext    app_context;
  397.     Widget        toplevel, hello;
  398.     XmString        xmstr;
  399.     Arg            wargs[10];
  400.     Window        window;
  401.     XEvent           event;
  402.  
  403.     toplevel = XtAppInitializeWithIcon (&app_context, "TextIcon", NULL, 0,
  404. #if XtSpecificationRelease > 4
  405.                     &argc,
  406. #else
  407.                     (Cardinal *)&argc,
  408. #endif
  409.                     argv, NULL, NULL, 0,
  410.                     (makeIcon)createIconWindow);
  411.  
  412.     display = XtDisplay (toplevel);
  413.  
  414.     hello = XmCreateLabel (toplevel, "hello", NULL, 0);
  415.     XtManageChild (hello);
  416.  
  417.     XtRealizeWidget (toplevel);
  418.     window = XtWindow (toplevel);
  419.  
  420. #if DEBUG & 0x0001
  421.     fprintf (stderr, "toplevel window = 0x%08x\n", window);
  422.     fprintf (stderr, "icon window     = 0x%08x\n", icon_window);
  423. #endif
  424.  
  425.     /*----
  426.      * Do the realizing and other standard X stuff.
  427.      *----*/
  428.  
  429.     xmstr = XmStringCreateSimple ("hello");
  430.     XtVaSetValues (hello, XmNlabelString, xmstr, NULL);
  431.     XmStringFree (xmstr);
  432.  
  433.     /*----
  434.      * Set up signal handler.
  435.      *----*/
  436.  
  437.     sigset (SIGALRM, update);
  438.  
  439.     /*----
  440.      * This is the MAIN LOOP.
  441.      *
  442.      * I have it expanded out so that I can process the events that are
  443.      * given to the icon window.  This is just for fun so I can find
  444.      * out what events are processed.
  445.      *----*/
  446.  
  447.     while (1)
  448.     {
  449.     XtAppNextEvent (app_context, &event);
  450.     if (event.xany.window == icon_window)
  451.     {
  452. #if DEBUG & 0x0002
  453.         fprintf (stderr, "Icon received event #%d - %s\n", event.type,
  454.              event_names[find_table_entry (event.type)].string);
  455. #endif
  456.  
  457.         if (event.type == MapNotify)
  458.         {
  459.         icon_mapped = 1;
  460.         alarm (1);
  461.         }
  462.         else if (event.type == UnmapNotify)
  463.         {
  464.         icon_mapped = 0;
  465.         alarm (0);
  466.         }
  467.         else if (event.type == Expose)
  468.         {
  469.         draw_icon (0, event);
  470.         }
  471.         else if (event.type == MotionNotify)
  472.         {
  473.         draw_icon (0, event);
  474.         }
  475.         else if (event.type == KeyRelease)
  476.         {
  477.         draw_icon (1, event);
  478.         }
  479.     }
  480.     else
  481.     {
  482.         XtDispatchEvent (&event);
  483.     }
  484.     }
  485. }
  486.