Annotation of 43BSD/contrib/X/bitmap/dialog.c, revision 1.1.1.1

1.1       root        1: #include <X/mit-copyright.h>
                      2: 
                      3: /* Copyright 1985, Massachusetts Institute of Technology */
                      4: #include <X/Xlib.h>
                      5: 
                      6: #ifndef lint
                      7: static char *rcsid_dialog_c = "$Header: dialog.c,v 10.4 86/02/01 15:18:29 tony Rel $";
                      8: #endif
                      9: 
                     10: extern int foreground;
                     11: extern int background;
                     12: extern Pixmap backmap;
                     13: extern Pixmap border;
                     14: extern int borderwidth;
                     15: extern int invertplane;
                     16: extern int mousepix;
                     17: 
                     18: #define NULL 0
                     19: #define MIN_BETWEEN_COMMANDS 10
                     20: #define BETWEEN_LINES 10
                     21: #define TOP_MARGIN 10
                     22: #define BOTTOM_MARGIN 10
                     23: #define MSG_RIGHT_MARGIN 7
                     24: #define MSG_LEFT_MARGIN 7
                     25: #define COMMAND_WIDTH_FUDGE 8
                     26: 
                     27: #define max(a,b) ((a > b) ? a : b)
                     28: 
                     29: #include "../cursors/cross.cursor"
                     30: #include "../cursors/cross_mask.cursor"
                     31: static Cursor cross_cursor;
                     32: 
                     33: static struct dialog_data {
                     34:   Window w;
                     35:   Font font;
                     36:   int font_height;
                     37:   char *msg1, *msg2;
                     38:   int msg1_length, msg2_length;
                     39:   struct command_data *command_info;
                     40:   };
                     41: 
                     42: static struct command_data {
                     43:   Window window;
                     44:   char *name;
                     45:   int name_length;
                     46:   int name_width;  /* in pixels */
                     47:   int x_offset;
                     48:   };
                     49: 
                     50: int dialog (w, font, font_height,
                     51:     msg1, msg2, command_names, n_commands, input_handler)
                     52:   Window w;
                     53:   Font font;
                     54:   int font_height;
                     55:   char *msg1, *msg2;
                     56:   char **command_names;
                     57:   int n_commands;
                     58:   int (*input_handler) ();
                     59:   {
                     60:   struct dialog_data data;
                     61:   static int initialized = 0;  
                     62:   int msg1_width = XQueryWidth (msg1, font);
                     63:   int msg2_width = XQueryWidth (msg2, font);
                     64:   int command_width = 0;
                     65:   int result;
                     66:   register int i;
                     67:   
                     68:   if (!initialized) {
                     69:     Initialize ();
                     70:     initialized = 1;
                     71:     }
                     72: 
                     73:   data.font = font;
                     74:   data.font_height = font_height;
                     75:   data.msg1 = msg1;
                     76:   data.msg2 = msg2;
                     77:   data.msg1_length = strlen (msg1);
                     78:   data.msg2_length = strlen (msg2);
                     79:   data.command_info = (struct command_data *) malloc
                     80:     (n_commands*sizeof (struct command_data));
                     81: 
                     82:   for (i=0;i<n_commands;i++) {
                     83:     data.command_info[i].name = command_names[i];
                     84:     data.command_info[i].name_length = strlen (command_names[i]);
                     85:     data.command_info[i].name_width = XQueryWidth (command_names[i], font);
                     86:     if (data.command_info[i].name_width > command_width)
                     87:       command_width = data.command_info[i].name_width;
                     88:     }
                     89:   command_width += COMMAND_WIDTH_FUDGE;
                     90: 
                     91:   {
                     92:   int between_commands;
                     93:   {
                     94:   int height =
                     95:     3*font_height + 2*BETWEEN_LINES + TOP_MARGIN + BOTTOM_MARGIN;
                     96:   int width = max (msg1_width, msg2_width)
                     97:     + MSG_LEFT_MARGIN + MSG_RIGHT_MARGIN;
                     98:   int min_width =
                     99:     n_commands*command_width + (n_commands+1)*MIN_BETWEEN_COMMANDS;
                    100:   int x, y;
                    101:   DeterminePlace (w, &x, &y);
                    102:   width = max (width, min_width);
                    103:   between_commands = 
                    104:      (width - n_commands*command_width)/(n_commands+1);
                    105:   data.w = XCreateWindow (RootWindow, x, y, width, height,
                    106:     borderwidth, border, backmap);
                    107:   }
                    108: 
                    109:   {
                    110:   int xx = between_commands;
                    111:   OpaqueFrame *frames = (OpaqueFrame *)malloc(n_commands*sizeof(OpaqueFrame));
                    112:   for (i=0;i<n_commands;i++) {
                    113:     register OpaqueFrame *frame = &frames[i];
                    114:     register struct command_data *command = &data.command_info[i];
                    115:     command->x_offset = (command_width - command->name_width)/2;
                    116:     frame->x = xx;
                    117:     frame->y = TOP_MARGIN + 2*(font_height+BETWEEN_LINES);
                    118:     frame->width = command_width;
                    119:     frame->height = font_height;
                    120:     frame->bdrwidth = 1;
                    121:     frame->border = border;
                    122:     frame->background = backmap;
                    123:     xx += (between_commands + command_width);
                    124:     }
                    125:   XCreateWindows (data.w, frames, n_commands);
                    126:   for (i=0;i<n_commands;i++)
                    127:     data.command_info[i].window = frames[i].self;
                    128:   free (frames);
                    129:   }}
                    130:   
                    131:   XSelectInput (data.w,
                    132:     ButtonPressed | ButtonReleased | ExposeWindow | LeaveWindow);
                    133:   
                    134:   XDefineCursor (data.w, cross_cursor);
                    135:   XMapWindow (data.w);
                    136:   XMapSubwindows (data.w);
                    137:   
                    138:   while (1) {
                    139:     struct command_data *command = NULL;
                    140:     XEvent event;
                    141:     XNextEvent (&event);
                    142:     if (event.window != data.w) {
                    143:       (*input_handler) (&event);
                    144:       continue;  /* back around the loop */
                    145:       }
                    146:     if (event.subwindow == 0) {
                    147:       ProcessDialogWindowEvent (&data, &event);
                    148:       continue;
                    149:       }
                    150:     for (i=0;i<n_commands;i++)
                    151:       if (event.subwindow == data.command_info[i].window) {
                    152:        command = &data.command_info[i];
                    153:        break;
                    154:        }
                    155:     if (command == NULL)
                    156:       continue;  /* really shouldn't happen, but what can you do? */
                    157:     result = ProcessCommandEvent (&data, command, &event);
                    158:     if (result >= 0)
                    159:       break;
                    160:     }
                    161:   
                    162:   XDestroyWindow (data.w);
                    163: 
                    164:   free (data.command_info);
                    165:   return (result);
                    166:   }   /* end of dialog procedure */
                    167: 
                    168: 
                    169: Initialize ()
                    170:   {
                    171:   cross_cursor = XCreateCursor (cross_width, cross_height, cross_bits,
                    172:     cross_mask_bits, cross_x_hot, cross_y_hot,
                    173:     mousepix, background, GXcopy);
                    174:   }
                    175: 
                    176: 
                    177: /* ProcessCommandEvent returns -1 unless a command was actually invoked,
                    178: in which case it returns the command number. */
                    179: 
                    180: static int ProcessCommandEvent (data, command, event)
                    181:   struct dialog_data *data;
                    182:   struct command_data *command;
                    183:   XEvent *event;
                    184:   {
                    185:   static struct command_data *button_down_command = NULL;
                    186:   
                    187:   switch (event->type) {
                    188:     
                    189:     case ExposeWindow:
                    190:       XTextMask (command->window, command->x_offset,
                    191:         0, command->name, command->name_length, data->font, foreground);
                    192:       break;
                    193: 
                    194:     case ButtonPressed:
                    195:       if (button_down_command != NULL)
                    196:         break;  /* must be second button press; ignore it */
                    197:       button_down_command = command;
                    198:       InvertCommand (data, command);
                    199:       break;
                    200: 
                    201:     case LeaveWindow:
                    202:       if (command == button_down_command) {
                    203:        InvertCommand (data, command);
                    204:        button_down_command = NULL;
                    205:        }
                    206:       break;
                    207: 
                    208:     case ButtonReleased:
                    209:       if (command == button_down_command) {
                    210:        button_down_command = NULL;
                    211:         return (command - data->command_info);
                    212:         }
                    213:       break;
                    214:    
                    215:     }
                    216: 
                    217:   return (-1);
                    218:   }
                    219: 
                    220: 
                    221: static ProcessDialogWindowEvent (data, event)
                    222:   struct dialog_data *data;
                    223:   XEvent *event;
                    224:   {
                    225:   if (event->type == ExposeWindow) {
                    226:     XTextMask (
                    227:       data->w, MSG_LEFT_MARGIN,
                    228:       TOP_MARGIN, data->msg1, data->msg1_length, data->font, foreground);
                    229:     XTextMask (
                    230:       data->w, MSG_LEFT_MARGIN,
                    231:         TOP_MARGIN + data->font_height + BETWEEN_LINES,
                    232:        data->msg2, data->msg2_length, data->font, foreground);
                    233:     }
                    234:   }
                    235: 
                    236: 
                    237: static InvertCommand (data, command)
                    238:   struct dialog_data *data;
                    239:   struct command_data *command;
                    240:   {
                    241:   XPixFill (command->window, 0, 0, 400, data->font_height, 1, NULL,
                    242:           GXinvert, invertplane);
                    243:   }
                    244: 
                    245: 
                    246: static DeterminePlace (w, px, py)
                    247:   Window w;
                    248:   int *px, *py;
                    249:   {
                    250:   WindowInfo info;
                    251:   XQueryWindow (w, &info);
                    252:   /* max (0,...) is to make sure dialog window is on screen, even
                    253:      if "parent" window is partially off screen (negative x or y) */
                    254:   *px = max (0, info.x + 10);
                    255:   *py = max (0, info.y + 10);
                    256:   }
                    257: 

unix.superglobalmegacorp.com

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