Annotation of researchv9/X11/src/X.V11R1/clients/bitmap/dialog.c, revision 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.