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:   }

Defined functions

DeterminePlace defined in line 246; used 1 times
Initialize defined in line 169; used 1 times
  • in line 69
InvertCommand defined in line 237; used 2 times
ProcessCommandEvent defined in line 180; used 1 times
ProcessDialogWindowEvent defined in line 221; used 1 times
dialog defined in line 50; used 2 times

Defined variables

cross_cursor defined in line 31; used 2 times
rcsid_dialog_c defined in line 7; never used

Defined struct's

command_data defined in line 42; used 15 times
dialog_data defined in line 33; used 8 times

Defined macros

BETWEEN_LINES defined in line 20; used 3 times
BOTTOM_MARGIN defined in line 22; used 1 times
  • in line 95
COMMAND_WIDTH_FUDGE defined in line 25; used 1 times
  • in line 89
MIN_BETWEEN_COMMANDS defined in line 19; used 1 times
  • in line 99
MSG_LEFT_MARGIN defined in line 24; used 3 times
MSG_RIGHT_MARGIN defined in line 23; used 1 times
  • in line 97
NULL defined in line 18; used 7 times
TOP_MARGIN defined in line 21; used 4 times
max defined in line 27; used 4 times
Last modified: 1986-02-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1674
Valid CSS Valid XHTML 1.0 Strict