Annotation of researchv9/X11/src/X.V11R1/clients/bitmap/dialog.c, revision 1.1.1.1

1.1       root        1: 
                      2: #include <X11/Xlib.h>
                      3: #include <X11/cursorfont.h>
                      4: 
                      5: #ifndef lint
                      6: static char *rcsid_dialog_c = "$Header: dialog.c,v 1.2 87/09/04 19:14:52 newman Exp $";
                      7: #endif
                      8: 
                      9: char *malloc();
                     10: 
                     11: extern Display *d;
                     12: extern int screen;
                     13: extern GC gc;
                     14: extern unsigned long foreground;
                     15: extern unsigned long background;
                     16: extern unsigned long border;
                     17: extern int borderwidth;
                     18: extern int invertplane;
                     19: 
                     20: #define NULL 0
                     21: #define MIN_BETWEEN_COMMANDS 10
                     22: #define BETWEEN_LINES 10
                     23: #define TOP_MARGIN 10
                     24: #define BOTTOM_MARGIN 10
                     25: #define MSG_RIGHT_MARGIN 7
                     26: #define MSG_LEFT_MARGIN 7
                     27: #define COMMAND_WIDTH_FUDGE 8
                     28: 
                     29: #define max(a,b) ((a > b) ? a : b)
                     30: 
                     31: static Cursor cross_cursor;
                     32: 
                     33: static struct dialog_data {
                     34:   Window w;
                     35:   XFontStruct *font;
                     36:   char *msg1, *msg2;
                     37:   int msg1_length, msg2_length;
                     38:   struct command_data *command_info;
                     39:   };
                     40: 
                     41: static struct command_data {
                     42:   Window window;
                     43:   char *name;
                     44:   int name_length;
                     45:   int name_width;  /* in pixels */
                     46:   int x_offset;
                     47:   };
                     48: 
                     49: int dialog (w, font,
                     50:     msg1, msg2, command_names, n_commands, input_handler)
                     51:   Window w;
                     52:   XFontStruct *font;
                     53:   char *msg1, *msg2;
                     54:   char **command_names;
                     55:   unsigned int n_commands;
                     56:   int (*input_handler) ();
                     57:   {
                     58:   struct dialog_data data;
                     59:   static int initialized = 0;  
                     60:   int msg1_width = XTextWidth (font, msg1, strlen(msg1));
                     61:   int msg2_width = XTextWidth (font, msg2, strlen(msg2));
                     62:   int command_width = 0;
                     63:   int font_height = font->ascent + font->descent;
                     64:   int result;
                     65:   register int i;
                     66:   
                     67:   if (!initialized) {
                     68:     Initialize ();
                     69:     initialized = 1;
                     70:     }
                     71: 
                     72:   data.font = font;
                     73:   data.msg1 = msg1;
                     74:   data.msg2 = msg2;
                     75:   data.msg1_length = strlen (msg1);
                     76:   data.msg2_length = strlen (msg2);
                     77:   data.command_info = (struct command_data *) malloc
                     78:     (n_commands*sizeof (struct command_data));
                     79: 
                     80:   for (i=0;i<n_commands;i++) {
                     81:     struct command_data *cmd = &data.command_info[i];
                     82:     cmd->name = command_names[i];
                     83:     cmd->name_length = strlen (cmd->name);
                     84:     cmd->name_width = XTextWidth (font, cmd->name, cmd->name_length);
                     85:     if (cmd->name_width > command_width)
                     86:       command_width = cmd->name_width;
                     87:     }
                     88:   command_width += COMMAND_WIDTH_FUDGE;
                     89: 
                     90:   {
                     91:   int between_commands;
                     92:   {
                     93:   int height = 3*font_height + 2*BETWEEN_LINES + TOP_MARGIN + BOTTOM_MARGIN;
                     94:   int width = max (msg1_width, msg2_width)
                     95:     + MSG_LEFT_MARGIN + MSG_RIGHT_MARGIN;
                     96:   int min_width =
                     97:     n_commands*command_width + (n_commands+1)*MIN_BETWEEN_COMMANDS;
                     98:   int x, y;
                     99:   XSetWindowAttributes attrs;
                    100:   attrs.border_pixel = border;
                    101:   attrs.background_pixel = background;
                    102:   attrs.cursor = cross_cursor;
                    103:   attrs.event_mask = ExposureMask;
                    104:   attrs.override_redirect = 1;
                    105: 
                    106:   DeterminePlace (w, &x, &y);
                    107:   width = max (width, min_width);
                    108:   between_commands = 
                    109:      (width - n_commands*command_width)/(n_commands+1);
                    110:   data.w = XCreateWindow (d, RootWindow(d, screen), x, y, width, height,
                    111:     borderwidth, CopyFromParent, CopyFromParent, CopyFromParent,
                    112:     CWBorderPixel | CWBackPixel | CWOverrideRedirect | CWCursor | CWEventMask, &attrs);
                    113:   }
                    114: 
                    115:   {
                    116:   int x = between_commands;
                    117:   int y = TOP_MARGIN + 2*(font_height + BETWEEN_LINES);
                    118:   for (i=0;i<n_commands;i++) {
                    119:     register struct command_data *command = &data.command_info[i];
                    120:     command->x_offset = (command_width - command->name_width)/2;
                    121:     command->window = XCreateSimpleWindow (d, data.w, x, y, command_width,
                    122:       font_height, 1, border, background);
                    123:     XSelectInput (d, command->window, 
                    124:        ButtonPressMask | ButtonReleaseMask | ExposureMask | LeaveWindowMask);
                    125:     x += (between_commands + command_width);
                    126:     }
                    127:   }}
                    128:   
                    129:   XMapWindow (d, data.w);
                    130:   XMapSubwindows (d, data.w);
                    131:   
                    132:   while (1) {
                    133:     struct command_data *command = NULL;
                    134:     XEvent event;
                    135:     XNextEvent (d, &event);
                    136:     if (event.xany.window == data.w) {
                    137:       ProcessDialogWindowEvent (&data, &event);
                    138:       continue;
                    139:       }
                    140:     for (i=0;i<n_commands;i++)
                    141:       if (event.xany.window == data.command_info[i].window) {
                    142:        command = &data.command_info[i];
                    143:        break;
                    144:        }
                    145:     if (command) {
                    146:        result = ProcessCommandEvent (&data, command, &event);
                    147:        if (result >= 0)
                    148:           break;
                    149:        }
                    150:     else 
                    151:        /* event doesn't belong to any of the dialog box's windows.
                    152:           Send it back to the calling application. */
                    153:       (*input_handler) (&event);
                    154:     }
                    155:   
                    156:   XDestroyWindow (d, data.w);
                    157: 
                    158:   free ((char *)data.command_info);
                    159:   return (result);
                    160:   }   /* end of dialog procedure */
                    161: 
                    162: 
                    163: Initialize ()
                    164:   {
                    165:   cross_cursor = XCreateFontCursor (d, XC_crosshair);
                    166:   }
                    167: 
                    168: 
                    169: /* ProcessCommandEvent returns -1 unless a command was actually invoked,
                    170: in which case it returns the command number. */
                    171: 
                    172: static int ProcessCommandEvent (data, command, event)
                    173:   struct dialog_data *data;
                    174:   struct command_data *command;
                    175:   XEvent *event;
                    176:   {
                    177:   static struct command_data *button_down_command = NULL;
                    178:   
                    179:   switch (event->type) {
                    180:     
                    181:     case Expose:
                    182:       if (event->xexpose.count == 0) {
                    183:        XSetState (d, gc, foreground, background, GXcopy, AllPlanes);
                    184:        XDrawString (d, command->window, gc, command->x_offset,
                    185:           data->font->ascent, command->name, command->name_length);
                    186:        }
                    187:       break;
                    188: 
                    189:     case ButtonPress:
                    190:       if (button_down_command != NULL)
                    191:         break;  /* must be second button press; ignore it */
                    192:       button_down_command = command;
                    193:       InvertCommand (command);
                    194:       break;
                    195: 
                    196:     case LeaveNotify:
                    197:       if (command == button_down_command) {
                    198:        InvertCommand (command);
                    199:        button_down_command = NULL;
                    200:        }
                    201:       break;
                    202: 
                    203:     case ButtonRelease:
                    204:       if (command == button_down_command) {
                    205:        button_down_command = NULL;
                    206:         return (command - data->command_info);
                    207:         }
                    208:       break;
                    209:    
                    210:     }
                    211: 
                    212:   return (-1);
                    213:   }
                    214: 
                    215: 
                    216: static ProcessDialogWindowEvent (data, event)
                    217:   struct dialog_data *data;
                    218:   XEvent *event;
                    219:   {
                    220:   if (event->type == Expose && event->xexpose.count == 0) {
                    221:     int y = TOP_MARGIN + data->font->ascent;
                    222:     XSetState (d, gc, foreground, background, GXcopy, AllPlanes);
                    223:     XDrawString (d, data->w, gc, MSG_LEFT_MARGIN, y,
                    224:        data->msg1, data->msg1_length);
                    225:     y += data->font->descent + BETWEEN_LINES + data->font->ascent;
                    226:     XDrawString (d, data->w, gc, MSG_LEFT_MARGIN, y,
                    227:        data->msg2, data->msg2_length);
                    228:     }
                    229:   }
                    230: 
                    231: 
                    232: static InvertCommand (command)
                    233:   struct command_data *command;
                    234:   {
                    235:   XSetState (d, gc, 1L, 0L, GXinvert, invertplane);
                    236:   XFillRectangle (d, command->window, gc, 0, 0, 400, 400);
                    237:   }
                    238: 
                    239: 
                    240: static DeterminePlace (w, px, py)
                    241:   Window w;
                    242:   int *px, *py;
                    243:   {
                    244:   int x, y;
                    245:   long trash;
                    246:   XGetGeometry (d, w, &trash, &x, &y, &trash, &trash, &trash, &trash);
                    247:   /* max (0,...) is to make sure dialog window is on screen, even
                    248:      if "parent" window is partially off screen (negative x or y) */
                    249:   *px = max (0, x + 10);
                    250:   *py = max (0, y + 10);
                    251:   }
                    252: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.