Annotation of 43BSD/contrib/X/bitmap/dialog.c, revision 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.