x11-ssh-askpass.c revision 8db30ca8
18db30ca8Sthorpej/* x11-ssh-askpass.c: A generic X11-based password dialog for OpenSSH. 28db30ca8Sthorpej * created 1999-Nov-17 03:40 Jim Knoble <jmknoble@pobox.com> 38db30ca8Sthorpej * autodate: 1999-Nov-23 02:52 48db30ca8Sthorpej * 58db30ca8Sthorpej * by Jim Knoble <jmknoble@pobox.com> 68db30ca8Sthorpej * Copyright � 1999 Jim Knoble 78db30ca8Sthorpej * 88db30ca8Sthorpej * Disclaimer: 98db30ca8Sthorpej * 108db30ca8Sthorpej * The software is provided "as is", without warranty of any kind, 118db30ca8Sthorpej * express or implied, including but not limited to the warranties of 128db30ca8Sthorpej * merchantability, fitness for a particular purpose and 138db30ca8Sthorpej * noninfringement. In no event shall the author(s) be liable for any 148db30ca8Sthorpej * claim, damages or other liability, whether in an action of 158db30ca8Sthorpej * contract, tort or otherwise, arising from, out of or in connection 168db30ca8Sthorpej * with the software or the use or other dealings in the software. 178db30ca8Sthorpej * 188db30ca8Sthorpej * Portions of this code are distantly derived from code in xscreensaver 198db30ca8Sthorpej * by Jamie Zawinski <jwz@jwz.org>. That code says: 208db30ca8Sthorpej * 218db30ca8Sthorpej * --------8<------------------------------------------------8<-------- 228db30ca8Sthorpej * xscreensaver, Copyright (c) 1991-1999 Jamie Zawinski <jwz@jwz.org> 238db30ca8Sthorpej * 248db30ca8Sthorpej * Permission to use, copy, modify, distribute, and sell this software and its 258db30ca8Sthorpej * documentation for any purpose is hereby granted without fee, provided that 268db30ca8Sthorpej * the above copyright notice appear in all copies and that both that 278db30ca8Sthorpej * copyright notice and this permission notice appear in supporting 288db30ca8Sthorpej * documentation. No representations are made about the suitability of this 298db30ca8Sthorpej * software for any purpose. It is provided "as is" without express or 308db30ca8Sthorpej * implied warranty. 318db30ca8Sthorpej * --------8<------------------------------------------------8<-------- 328db30ca8Sthorpej * 338db30ca8Sthorpej * The remainder of this code falls under the same permissions and 348db30ca8Sthorpej * provisions as those of the xscreensaver code. 358db30ca8Sthorpej */ 368db30ca8Sthorpej 378db30ca8Sthorpej#include <stdio.h> 388db30ca8Sthorpej#include <stdlib.h> 398db30ca8Sthorpej#include <string.h> 408db30ca8Sthorpej 418db30ca8Sthorpej/* For (get|set)rlimit() ... */ 428db30ca8Sthorpej#include <sys/time.h> 438db30ca8Sthorpej#include <sys/resource.h> 448db30ca8Sthorpej#include <unistd.h> 458db30ca8Sthorpej/* ... end */ 468db30ca8Sthorpej 478db30ca8Sthorpej/* For errno ... */ 488db30ca8Sthorpej#include <errno.h> 498db30ca8Sthorpej/* ... end */ 508db30ca8Sthorpej 518db30ca8Sthorpej#include <X11/Xlib.h> 528db30ca8Sthorpej#include <X11/Intrinsic.h> 538db30ca8Sthorpej#include <X11/Shell.h> 548db30ca8Sthorpej#include <X11/Xos.h> 558db30ca8Sthorpej#include "dynlist.h" 568db30ca8Sthorpej#include "drawing.h" 578db30ca8Sthorpej#include "resources.h" 588db30ca8Sthorpej#include "x11-ssh-askpass.h" 598db30ca8Sthorpej 608db30ca8Sthorpej#undef MAX 618db30ca8Sthorpej#define MAX(a,b) (((a) > (b)) ? (a) : (b)) 628db30ca8Sthorpej 638db30ca8Sthorpejchar *progname = NULL; 648db30ca8Sthorpejchar *progclass = NULL; 658db30ca8SthorpejXrmDatabase db = 0; 668db30ca8Sthorpej 678db30ca8Sthorpejstatic char *defaults[] = { 688db30ca8Sthorpej#include "SshAskpass_ad.h" 698db30ca8Sthorpej 0 708db30ca8Sthorpej}; 718db30ca8Sthorpej 728db30ca8Sthorpejvoid outOfMemory(AppInfo *app, int line) 738db30ca8Sthorpej{ 748db30ca8Sthorpej fprintf(stderr, "%s: Aaahhh! I ran out of memory at line %d.\n", 758db30ca8Sthorpej app->appName, line); 768db30ca8Sthorpej exit(EXIT_STATUS_NO_MEMORY); 778db30ca8Sthorpej} 788db30ca8Sthorpej 798db30ca8Sthorpejvoid freeIf(void *p) 808db30ca8Sthorpej{ 818db30ca8Sthorpej if (p) { 828db30ca8Sthorpej free(p); 838db30ca8Sthorpej } 848db30ca8Sthorpej} 858db30ca8Sthorpej 868db30ca8Sthorpejvoid freeFontIf(AppInfo *app, XFontStruct *f) 878db30ca8Sthorpej{ 888db30ca8Sthorpej if (f) { 898db30ca8Sthorpej XFreeFont(app->dpy, f); 908db30ca8Sthorpej } 918db30ca8Sthorpej} 928db30ca8Sthorpej 938db30ca8SthorpejXFontStruct *getFontResource(AppInfo *app, char *instanceName, char *className) 948db30ca8Sthorpej{ 958db30ca8Sthorpej char *fallbackFont = "fixed"; 968db30ca8Sthorpej 978db30ca8Sthorpej XFontStruct *f = NULL; 988db30ca8Sthorpej char *s = get_string_resource(instanceName, className); 998db30ca8Sthorpej f = XLoadQueryFont(app->dpy, (s ? s : fallbackFont)); 1008db30ca8Sthorpej if (!f) { 1018db30ca8Sthorpej f = XLoadQueryFont(app->dpy, fallbackFont); 1028db30ca8Sthorpej } 1038db30ca8Sthorpej if (s) { 1048db30ca8Sthorpej free(s); 1058db30ca8Sthorpej } 1068db30ca8Sthorpej return(f); 1078db30ca8Sthorpej} 1088db30ca8Sthorpej 1098db30ca8Sthorpejchar *getStringResourceWithDefault(char *instanceName, char *className, 1108db30ca8Sthorpej char *defaultText) 1118db30ca8Sthorpej{ 1128db30ca8Sthorpej char *s = get_string_resource(instanceName, className); 1138db30ca8Sthorpej if (!s) { 1148db30ca8Sthorpej if (!defaultText) { 1158db30ca8Sthorpej s = strdup(""); 1168db30ca8Sthorpej } else { 1178db30ca8Sthorpej s = strdup(defaultText); 1188db30ca8Sthorpej } 1198db30ca8Sthorpej } 1208db30ca8Sthorpej return(s); 1218db30ca8Sthorpej} 1228db30ca8Sthorpej 1238db30ca8Sthorpejvoid calcLabelTextExtents(LabelInfo *label) 1248db30ca8Sthorpej{ 1258db30ca8Sthorpej if ((!label) || (!(label->text)) || (!(label->font))) { 1268db30ca8Sthorpej return; 1278db30ca8Sthorpej } 1288db30ca8Sthorpej label->textLength = strlen(label->text); 1298db30ca8Sthorpej XTextExtents(label->font, label->text, label->textLength, 1308db30ca8Sthorpej &(label->direction), &(label->ascent), &(label->descent), 1318db30ca8Sthorpej &(label->overall)); 1328db30ca8Sthorpej label->w.height = label->descent + label->ascent; 1338db30ca8Sthorpej label->w.width = label->overall.width; 1348db30ca8Sthorpej} 1358db30ca8Sthorpej 1368db30ca8Sthorpejvoid calcTotalButtonExtents(ButtonInfo *button) 1378db30ca8Sthorpej{ 1388db30ca8Sthorpej if (!button) { 1398db30ca8Sthorpej return; 1408db30ca8Sthorpej } 1418db30ca8Sthorpej button->w3.w.width = (button->w3.interiorWidth + 1428db30ca8Sthorpej (2 * button->w3.shadowThickness)); 1438db30ca8Sthorpej button->w3.w.width += (2 * button->w3.borderWidth); 1448db30ca8Sthorpej button->w3.w.height = (button->w3.interiorHeight + 1458db30ca8Sthorpej (2 * button->w3.shadowThickness)); 1468db30ca8Sthorpej button->w3.w.height += (2 * button->w3.borderWidth); 1478db30ca8Sthorpej} 1488db30ca8Sthorpej 1498db30ca8Sthorpejvoid calcButtonExtents(ButtonInfo *button) 1508db30ca8Sthorpej{ 1518db30ca8Sthorpej if (!button) { 1528db30ca8Sthorpej return; 1538db30ca8Sthorpej } 1548db30ca8Sthorpej calcLabelTextExtents(&(button->label)); 1558db30ca8Sthorpej button->w3.interiorWidth = (button->label.w.width + 1568db30ca8Sthorpej (2 * button->w3.horizontalSpacing)); 1578db30ca8Sthorpej button->w3.interiorHeight = (button->label.w.height + 1588db30ca8Sthorpej (2 * button->w3.verticalSpacing)); 1598db30ca8Sthorpej calcTotalButtonExtents(button); 1608db30ca8Sthorpej} 1618db30ca8Sthorpej 1628db30ca8Sthorpejvoid balanceButtonExtents(ButtonInfo *button1, ButtonInfo *button2) 1638db30ca8Sthorpej{ 1648db30ca8Sthorpej if ((!button1) || (!button2)) { 1658db30ca8Sthorpej return; 1668db30ca8Sthorpej } 1678db30ca8Sthorpej button1->w3.interiorWidth = button2->w3.interiorWidth = 1688db30ca8Sthorpej MAX(button1->w3.interiorWidth, button2->w3.interiorWidth); 1698db30ca8Sthorpej button1->w3.interiorHeight = button2->w3.interiorHeight = 1708db30ca8Sthorpej MAX(button1->w3.interiorHeight, button2->w3.interiorHeight); 1718db30ca8Sthorpej calcTotalButtonExtents(button1); 1728db30ca8Sthorpej calcTotalButtonExtents(button2); 1738db30ca8Sthorpej} 1748db30ca8Sthorpej 1758db30ca8Sthorpejvoid calcButtonLabelPosition(ButtonInfo *button) 1768db30ca8Sthorpej{ 1778db30ca8Sthorpej if (!button) { 1788db30ca8Sthorpej return; 1798db30ca8Sthorpej } 1808db30ca8Sthorpej button->label.w.x = button->w3.w.x + 1818db30ca8Sthorpej ((button->w3.w.width - button->label.w.width) / 2); 1828db30ca8Sthorpej button->label.w.y = button->w3.w.y + 1838db30ca8Sthorpej ((button->w3.w.height - button->label.w.height) / 2) 1848db30ca8Sthorpej + button->label.ascent; 1858db30ca8Sthorpej} 1868db30ca8Sthorpej 1878db30ca8Sthorpejvoid createDialog(AppInfo *app) 1888db30ca8Sthorpej{ 1898db30ca8Sthorpej DialogInfo *d; 1908db30ca8Sthorpej 1918db30ca8Sthorpej if (app->dialog) { 1928db30ca8Sthorpej return; 1938db30ca8Sthorpej } 1948db30ca8Sthorpej d = malloc(sizeof(*d)); 1958db30ca8Sthorpej if (NULL == d) { 1968db30ca8Sthorpej outOfMemory(app, __LINE__); 1978db30ca8Sthorpej } 1988db30ca8Sthorpej memset(d, 0, sizeof(*d)); 1998db30ca8Sthorpej 2008db30ca8Sthorpej app->grabKeyboard = 2018db30ca8Sthorpej get_boolean_resource("grabKeyboard", "GrabKeyboard", True); 2028db30ca8Sthorpej app->grabPointer = 2038db30ca8Sthorpej get_boolean_resource("grabPointer", "GrabPointer", False); 2048db30ca8Sthorpej app->grabPointer = 2058db30ca8Sthorpej get_boolean_resource("grabServer", "GrabServer", False); 2068db30ca8Sthorpej 2078db30ca8Sthorpej d->title = 2088db30ca8Sthorpej getStringResourceWithDefault("dialog.title", "Dialog.Title", 2098db30ca8Sthorpej "OpenSSH Authentication Passphrase Request"); 2108db30ca8Sthorpej d->w3.w.foreground = 2118db30ca8Sthorpej get_pixel_resource("foreground", "Foreground", 2128db30ca8Sthorpej app->dpy, app->colormap, app->black); 2138db30ca8Sthorpej d->w3.w.background = 2148db30ca8Sthorpej get_pixel_resource("background", "Background", 2158db30ca8Sthorpej app->dpy, app->colormap, app->white); 2168db30ca8Sthorpej d->w3.topShadowColor = 2178db30ca8Sthorpej get_pixel_resource("topShadowColor", "TopShadowColor", 2188db30ca8Sthorpej app->dpy, app->colormap, app->white); 2198db30ca8Sthorpej d->w3.bottomShadowColor = 2208db30ca8Sthorpej get_pixel_resource("bottomShadowColor", "BottomShadowColor", 2218db30ca8Sthorpej app->dpy, app->colormap, app->black); 2228db30ca8Sthorpej d->w3.shadowThickness = 2238db30ca8Sthorpej get_integer_resource("shadowThickness", "ShadowThickness", 3); 2248db30ca8Sthorpej d->w3.borderColor = 2258db30ca8Sthorpej get_pixel_resource("borderColor", "BorderColor", 2268db30ca8Sthorpej app->dpy, app->colormap, app->black); 2278db30ca8Sthorpej d->w3.borderWidth = 2288db30ca8Sthorpej get_integer_resource("borderWidth", "BorderWidth", 1); 2298db30ca8Sthorpej 2308db30ca8Sthorpej d->w3.horizontalSpacing = 2318db30ca8Sthorpej get_integer_resource("horizontalSpacing", "Spacing", 5); 2328db30ca8Sthorpej d->w3.verticalSpacing = 2338db30ca8Sthorpej get_integer_resource("verticalSpacing", "Spacing", 6); 2348db30ca8Sthorpej 2358db30ca8Sthorpej if (2 == app->argc) { 2368db30ca8Sthorpej d->label.text = strdup(app->argv[1]); 2378db30ca8Sthorpej } else { 2388db30ca8Sthorpej d->label.text = 2398db30ca8Sthorpej getStringResourceWithDefault("dialog.label", "Dialog.Label", 2408db30ca8Sthorpej "Please enter your authentication passphrase:"); 2418db30ca8Sthorpej } 2428db30ca8Sthorpej d->label.font = getFontResource(app, "dialog.font", "Dialog.Font"); 2438db30ca8Sthorpej calcLabelTextExtents(&(d->label)); 2448db30ca8Sthorpej d->label.w.foreground = d->w3.w.foreground; 2458db30ca8Sthorpej d->label.w.background = d->w3.w.background; 2468db30ca8Sthorpej 2478db30ca8Sthorpej d->okButton.w3.w.foreground = 2488db30ca8Sthorpej get_pixel_resource("okButton.foreground", "Button.Foreground", 2498db30ca8Sthorpej app->dpy, app->colormap, app->black); 2508db30ca8Sthorpej d->okButton.w3.w.background = 2518db30ca8Sthorpej get_pixel_resource("okButton.background", "Button.Background", 2528db30ca8Sthorpej app->dpy, app->colormap, app->white); 2538db30ca8Sthorpej d->okButton.w3.topShadowColor = 2548db30ca8Sthorpej get_pixel_resource("okButton.topShadowColor", "Button.TopShadowColor", 2558db30ca8Sthorpej app->dpy, app->colormap, app->white); 2568db30ca8Sthorpej d->okButton.w3.bottomShadowColor = 2578db30ca8Sthorpej get_pixel_resource("okButton.bottomShadowColor", 2588db30ca8Sthorpej "Button.BottomShadowColor", 2598db30ca8Sthorpej app->dpy, app->colormap, app->black); 2608db30ca8Sthorpej d->okButton.w3.shadowThickness = 2618db30ca8Sthorpej get_integer_resource("okButton.shadowThickness", 2628db30ca8Sthorpej "Button.ShadowThickness", 2); 2638db30ca8Sthorpej d->okButton.w3.borderColor = 2648db30ca8Sthorpej get_pixel_resource("okButton.borderColor", "Button.BorderColor", 2658db30ca8Sthorpej app->dpy, app->colormap, app->black); 2668db30ca8Sthorpej d->okButton.w3.borderWidth = 2678db30ca8Sthorpej get_integer_resource("okButton.borderWidth", "Button.BorderWidth", 1); 2688db30ca8Sthorpej d->okButton.w3.horizontalSpacing = 2698db30ca8Sthorpej get_integer_resource("okButton.horizontalSpacing", "Button.Spacing", 4); 2708db30ca8Sthorpej d->okButton.w3.verticalSpacing = 2718db30ca8Sthorpej get_integer_resource("okButton.verticalSpacing", "Button.Spacing", 2); 2728db30ca8Sthorpej d->okButton.label.text = 2738db30ca8Sthorpej getStringResourceWithDefault("okButton.label", "Button.Label", "OK"); 2748db30ca8Sthorpej d->okButton.label.font = 2758db30ca8Sthorpej getFontResource(app, "okButton.font", "Button.Font"); 2768db30ca8Sthorpej calcButtonExtents(&(d->okButton)); 2778db30ca8Sthorpej d->okButton.label.w.foreground = d->okButton.w3.w.foreground; 2788db30ca8Sthorpej d->okButton.label.w.background = d->okButton.w3.w.background; 2798db30ca8Sthorpej 2808db30ca8Sthorpej d->cancelButton.w3.w.foreground = 2818db30ca8Sthorpej get_pixel_resource("cancelButton.foreground", "Button.Foreground", 2828db30ca8Sthorpej app->dpy, app->colormap, app->black); 2838db30ca8Sthorpej d->cancelButton.w3.w.background = 2848db30ca8Sthorpej get_pixel_resource("cancelButton.background", "Button.Background", 2858db30ca8Sthorpej app->dpy, app->colormap, app->white); 2868db30ca8Sthorpej d->cancelButton.w3.topShadowColor = 2878db30ca8Sthorpej get_pixel_resource("cancelButton.topShadowColor", 2888db30ca8Sthorpej "Button.TopShadowColor", 2898db30ca8Sthorpej app->dpy, app->colormap, app->white); 2908db30ca8Sthorpej d->cancelButton.w3.bottomShadowColor = 2918db30ca8Sthorpej get_pixel_resource("cancelButton.bottomShadowColor", 2928db30ca8Sthorpej "Button.BottomShadowColor", 2938db30ca8Sthorpej app->dpy, app->colormap, app->black); 2948db30ca8Sthorpej d->cancelButton.w3.shadowThickness = 2958db30ca8Sthorpej get_integer_resource("cancelButton.shadowThickness", 2968db30ca8Sthorpej "Button.ShadowThickness", 2); 2978db30ca8Sthorpej d->cancelButton.w3.borderColor = 2988db30ca8Sthorpej get_pixel_resource("cancelButton.borderColor", "Button.BorderColor", 2998db30ca8Sthorpej app->dpy, app->colormap, app->black); 3008db30ca8Sthorpej d->cancelButton.w3.borderWidth = 3018db30ca8Sthorpej get_integer_resource("cancelButton.borderWidth", "Button.BorderWidth", 3028db30ca8Sthorpej 1); 3038db30ca8Sthorpej d->cancelButton.w3.horizontalSpacing = 3048db30ca8Sthorpej get_integer_resource("cancelButton.horizontalSpacing", "Button.Spacing", 3058db30ca8Sthorpej 4); 3068db30ca8Sthorpej d->cancelButton.w3.verticalSpacing = 3078db30ca8Sthorpej get_integer_resource("cancelButton.verticalSpacing", "Button.Spacing", 3088db30ca8Sthorpej 2); 3098db30ca8Sthorpej d->cancelButton.label.text = 3108db30ca8Sthorpej getStringResourceWithDefault("cancelButton.label", "Button.Label", 3118db30ca8Sthorpej "Cancel"); 3128db30ca8Sthorpej d->cancelButton.label.font = 3138db30ca8Sthorpej getFontResource(app, "cancelButton.font", "Button.Font"); 3148db30ca8Sthorpej calcButtonExtents(&(d->cancelButton)); 3158db30ca8Sthorpej d->cancelButton.label.w.foreground = d->cancelButton.w3.w.foreground; 3168db30ca8Sthorpej d->cancelButton.label.w.background = d->cancelButton.w3.w.background; 3178db30ca8Sthorpej 3188db30ca8Sthorpej balanceButtonExtents(&(d->okButton), &(d->cancelButton)); 3198db30ca8Sthorpej 3208db30ca8Sthorpej d->indicator.w3.w.foreground = 3218db30ca8Sthorpej get_pixel_resource("indicator.foreground", "Indicator.Foreground", 3228db30ca8Sthorpej app->dpy, app->colormap, app->black); 3238db30ca8Sthorpej d->indicator.w3.w.background = 3248db30ca8Sthorpej get_pixel_resource("indicator.background", "Indicator.Background", 3258db30ca8Sthorpej app->dpy, app->colormap, app->white); 3268db30ca8Sthorpej d->indicator.w3.w.width = 3278db30ca8Sthorpej get_integer_resource("indicator.width", "Indicator.Width", 15); 3288db30ca8Sthorpej d->indicator.w3.w.height = 3298db30ca8Sthorpej get_integer_resource("indicator.height", "Indicator.Height", 7); 3308db30ca8Sthorpej d->indicator.w3.topShadowColor = 3318db30ca8Sthorpej get_pixel_resource("indicator.topShadowColor", 3328db30ca8Sthorpej "Indicator.TopShadowColor", 3338db30ca8Sthorpej app->dpy, app->colormap, app->white); 3348db30ca8Sthorpej d->indicator.w3.bottomShadowColor = 3358db30ca8Sthorpej get_pixel_resource("indicator.bottomShadowColor", 3368db30ca8Sthorpej "Indicator.BottomShadowColor", 3378db30ca8Sthorpej app->dpy, app->colormap, app->black); 3388db30ca8Sthorpej d->indicator.w3.shadowThickness = 3398db30ca8Sthorpej get_integer_resource("indicator.shadowThickness", 3408db30ca8Sthorpej "Indicator.ShadowThickness", 2); 3418db30ca8Sthorpej d->indicator.w3.borderColor = 3428db30ca8Sthorpej get_pixel_resource("indicator.borderColor", "Indicator.BorderColor", 3438db30ca8Sthorpej app->dpy, app->colormap, app->black); 3448db30ca8Sthorpej d->indicator.w3.borderWidth = 3458db30ca8Sthorpej get_integer_resource("indicator.borderWidth", "Indicator.BorderWidth", 3468db30ca8Sthorpej 0); 3478db30ca8Sthorpej d->indicator.w3.horizontalSpacing = 3488db30ca8Sthorpej get_integer_resource("indicator.horizontalSpacing", "Indicator.Spacing", 3498db30ca8Sthorpej 2); 3508db30ca8Sthorpej d->indicator.w3.verticalSpacing = 3518db30ca8Sthorpej get_integer_resource("indicator.verticalSpacing", "Indicator.Spacing", 3528db30ca8Sthorpej 4); 3538db30ca8Sthorpej d->indicator.minimumCount = 3548db30ca8Sthorpej get_integer_resource("indicator.minimumCount", "Indicator.MinimumCount", 3558db30ca8Sthorpej 8); 3568db30ca8Sthorpej d->indicator.maximumCount = 3578db30ca8Sthorpej get_integer_resource("indicator.maximumCount", "Indicator.MaximumCount", 3588db30ca8Sthorpej 24); 3598db30ca8Sthorpej d->indicator.w3.interiorWidth = d->indicator.w3.w.width; 3608db30ca8Sthorpej d->indicator.w3.interiorHeight = d->indicator.w3.w.height; 3618db30ca8Sthorpej d->indicator.w3.w.width += (2 * d->indicator.w3.shadowThickness); 3628db30ca8Sthorpej d->indicator.w3.w.width += (2 * d->indicator.w3.borderWidth); 3638db30ca8Sthorpej d->indicator.w3.w.height += (2 * d->indicator.w3.shadowThickness); 3648db30ca8Sthorpej d->indicator.w3.w.height += (2 * d->indicator.w3.borderWidth); 3658db30ca8Sthorpej { 3668db30ca8Sthorpej /* Make sure the indicators can all fit on the screen. 3678db30ca8Sthorpej * 80% of the screen width seems fine. 3688db30ca8Sthorpej */ 3698db30ca8Sthorpej Dimension maxWidth = (WidthOfScreen(app->screen) * 8 / 10); 3708db30ca8Sthorpej Dimension extraSpace = ((2 * d->w3.horizontalSpacing) + 3718db30ca8Sthorpej (2 * d->w3.shadowThickness)); 3728db30ca8Sthorpej 3738db30ca8Sthorpej if (d->indicator.maximumCount < 8) { 3748db30ca8Sthorpej d->indicator.maximumCount = 8; 3758db30ca8Sthorpej } 3768db30ca8Sthorpej if (((d->indicator.maximumCount * d->indicator.w3.w.width) + 3778db30ca8Sthorpej ((d->indicator.maximumCount - 1) * 3788db30ca8Sthorpej d->indicator.w3.horizontalSpacing) + extraSpace) > maxWidth) { 3798db30ca8Sthorpej d->indicator.maximumCount = 3808db30ca8Sthorpej ((maxWidth - extraSpace - d->indicator.w3.w.width) / 3818db30ca8Sthorpej (d->indicator.w3.w.width + d->indicator.w3.horizontalSpacing)) 3828db30ca8Sthorpej + 1; 3838db30ca8Sthorpej } 3848db30ca8Sthorpej if (d->indicator.minimumCount <= 6) { 3858db30ca8Sthorpej d->indicator.minimumCount = 6; 3868db30ca8Sthorpej } 3878db30ca8Sthorpej if (d->indicator.minimumCount > d->indicator.maximumCount) { 3888db30ca8Sthorpej d->indicator.minimumCount = d->indicator.maximumCount; 3898db30ca8Sthorpej } 3908db30ca8Sthorpej } 3918db30ca8Sthorpej 3928db30ca8Sthorpej { 3938db30ca8Sthorpej /* Calculate the width and horizontal position of things. */ 3948db30ca8Sthorpej Dimension labelAreaWidth; 3958db30ca8Sthorpej Dimension buttonAreaWidth; 3968db30ca8Sthorpej Dimension indicatorAreaWidth; 3978db30ca8Sthorpej Dimension extraIndicatorSpace; 3988db30ca8Sthorpej Dimension singleIndicatorSpace; 3998db30ca8Sthorpej Dimension interButtonSpace; 4008db30ca8Sthorpej Dimension w; 4018db30ca8Sthorpej Position leftX; 4028db30ca8Sthorpej int i; 4038db30ca8Sthorpej 4048db30ca8Sthorpej labelAreaWidth = d->label.w.width + (2 * d->w3.horizontalSpacing); 4058db30ca8Sthorpej buttonAreaWidth = ((3 * d->w3.horizontalSpacing) + 4068db30ca8Sthorpej d->okButton.w3.w.width + 4078db30ca8Sthorpej d->cancelButton.w3.w.width); 4088db30ca8Sthorpej w = MAX(labelAreaWidth, buttonAreaWidth); 4098db30ca8Sthorpej extraIndicatorSpace = ((2 * d->w3.horizontalSpacing) + 4108db30ca8Sthorpej d->indicator.w3.w.width); 4118db30ca8Sthorpej singleIndicatorSpace = (d->indicator.w3.w.width + 4128db30ca8Sthorpej d->indicator.w3.horizontalSpacing); 4138db30ca8Sthorpej d->indicator.count = ((w - extraIndicatorSpace) / singleIndicatorSpace); 4148db30ca8Sthorpej d->indicator.current = 0; 4158db30ca8Sthorpej d->indicator.count++; /* For gatepost indicator in extra space. */ 4168db30ca8Sthorpej if (((w - extraIndicatorSpace) % singleIndicatorSpace) > 4178db30ca8Sthorpej (singleIndicatorSpace / 2)) { 4188db30ca8Sthorpej d->indicator.count++; 4198db30ca8Sthorpej } 4208db30ca8Sthorpej if (d->indicator.count < d->indicator.minimumCount) { 4218db30ca8Sthorpej d->indicator.count = d->indicator.minimumCount; 4228db30ca8Sthorpej } 4238db30ca8Sthorpej if (d->indicator.count > d->indicator.maximumCount) { 4248db30ca8Sthorpej d->indicator.count = d->indicator.maximumCount; 4258db30ca8Sthorpej } 4268db30ca8Sthorpej indicatorAreaWidth = ((singleIndicatorSpace * (d->indicator.count - 1)) + 4278db30ca8Sthorpej extraIndicatorSpace); 4288db30ca8Sthorpej d->w3.interiorWidth = MAX(w, indicatorAreaWidth); 4298db30ca8Sthorpej d->w3.w.width = d->w3.interiorWidth + (2 * d->w3.shadowThickness); 4308db30ca8Sthorpej 4318db30ca8Sthorpej leftX = (d->w3.w.width - d->label.w.width) / 2; 4328db30ca8Sthorpej d->label.w.x = leftX; 4338db30ca8Sthorpej 4348db30ca8Sthorpej leftX = ((d->w3.w.width - 4358db30ca8Sthorpej (d->indicator.count * d->indicator.w3.w.width) - 4368db30ca8Sthorpej ((d->indicator.count - 1) * d->indicator.w3.horizontalSpacing)) 4378db30ca8Sthorpej / 2); 4388db30ca8Sthorpej { 4398db30ca8Sthorpej int n = d->indicator.count * sizeof(IndicatorElement); 4408db30ca8Sthorpej d->indicators = malloc(n); 4418db30ca8Sthorpej if (NULL == d->indicators) { 4428db30ca8Sthorpej destroyDialog(app); 4438db30ca8Sthorpej outOfMemory(app, __LINE__); 4448db30ca8Sthorpej } 4458db30ca8Sthorpej memset(d->indicators, 0, n); 4468db30ca8Sthorpej } 4478db30ca8Sthorpej d->indicators[0].parent = &(d->indicator); 4488db30ca8Sthorpej d->indicators[0].w.x = d->indicator.w3.w.x = leftX; 4498db30ca8Sthorpej d->indicators[0].w.width = d->indicator.w3.w.width; 4508db30ca8Sthorpej d->indicators[0].isLit = False; 4518db30ca8Sthorpej for (i = 1; i < d->indicator.count; i++) { 4528db30ca8Sthorpej d->indicators[i].parent = &(d->indicator); 4538db30ca8Sthorpej d->indicators[i].w.x = (d->indicators[i - 1].w.x + 4548db30ca8Sthorpej d->indicator.w3.w.width + 4558db30ca8Sthorpej d->indicator.w3.horizontalSpacing); 4568db30ca8Sthorpej d->indicators[i].w.width = d->indicator.w3.w.width; 4578db30ca8Sthorpej d->indicators[i].isLit = False; 4588db30ca8Sthorpej } 4598db30ca8Sthorpej interButtonSpace = ((d->w3.interiorWidth - d->okButton.w3.w.width - 4608db30ca8Sthorpej d->cancelButton.w3.w.width) / 3); 4618db30ca8Sthorpej d->okButton.w3.w.x = interButtonSpace + d->w3.shadowThickness; 4628db30ca8Sthorpej d->cancelButton.w3.w.x = (d->okButton.w3.w.x + d->okButton.w3.w.width + 4638db30ca8Sthorpej interButtonSpace); 4648db30ca8Sthorpej } 4658db30ca8Sthorpej { 4668db30ca8Sthorpej /* Calculate the height and vertical position of things. */ 4678db30ca8Sthorpej int i; 4688db30ca8Sthorpej 4698db30ca8Sthorpej d->w3.interiorHeight = ((4 * d->w3.verticalSpacing) + 4708db30ca8Sthorpej (2 * d->indicator.w3.verticalSpacing) + 4718db30ca8Sthorpej d->label.w.height + 4728db30ca8Sthorpej d->indicator.w3.w.height + 4738db30ca8Sthorpej d->okButton.w3.w.height); 4748db30ca8Sthorpej d->w3.w.height = d->w3.interiorHeight + (2 * d->w3.shadowThickness); 4758db30ca8Sthorpej d->label.w.y = (d->w3.shadowThickness + d->w3.verticalSpacing + 4768db30ca8Sthorpej d->label.ascent); 4778db30ca8Sthorpej d->indicator.w3.w.y = (d->label.w.y + d->label.descent + 4788db30ca8Sthorpej d->w3.verticalSpacing + 4798db30ca8Sthorpej d->indicator.w3.verticalSpacing); 4808db30ca8Sthorpej for (i = 0; i < d->indicator.count; i++) { 4818db30ca8Sthorpej d->indicators[i].w.y = d->indicator.w3.w.y; 4828db30ca8Sthorpej d->indicators[i].w.height = d->indicator.w3.w.height; 4838db30ca8Sthorpej } 4848db30ca8Sthorpej d->okButton.w3.w.y = d->cancelButton.w3.w.y = 4858db30ca8Sthorpej (d->indicator.w3.w.y + d->indicator.w3.w.height + 4868db30ca8Sthorpej d->w3.verticalSpacing + d->indicator.w3.verticalSpacing); 4878db30ca8Sthorpej } 4888db30ca8Sthorpej calcButtonLabelPosition(&(d->okButton)); 4898db30ca8Sthorpej calcButtonLabelPosition(&(d->cancelButton)); 4908db30ca8Sthorpej 4918db30ca8Sthorpej d->w3.w.x = (WidthOfScreen(app->screen) - d->w3.w.width) / 2; 4928db30ca8Sthorpej d->w3.w.y = (HeightOfScreen(app->screen) - d->w3.w.height) / 3; 4938db30ca8Sthorpej 4948db30ca8Sthorpej app->dialog = d; 4958db30ca8Sthorpej} 4968db30ca8Sthorpej 4978db30ca8Sthorpejvoid destroyDialog(AppInfo *app) 4988db30ca8Sthorpej{ 4998db30ca8Sthorpej DialogInfo *d = app->dialog; 5008db30ca8Sthorpej 5018db30ca8Sthorpej freeIf(d->title); 5028db30ca8Sthorpej freeIf(d->label.text); 5038db30ca8Sthorpej freeIf(d->okButton.label.text); 5048db30ca8Sthorpej freeIf(d->cancelButton.label.text); 5058db30ca8Sthorpej freeIf(d->indicators); 5068db30ca8Sthorpej 5078db30ca8Sthorpej freeFontIf(app, d->label.font); 5088db30ca8Sthorpej freeFontIf(app, d->okButton.label.font); 5098db30ca8Sthorpej freeFontIf(app, d->cancelButton.label.font); 5108db30ca8Sthorpej 5118db30ca8Sthorpej XFree(d->sizeHints); 5128db30ca8Sthorpej XFree(d->wmHints); 5138db30ca8Sthorpej XFree(d->classHints); 5148db30ca8Sthorpej XFree(d->windowName.value); 5158db30ca8Sthorpej 5168db30ca8Sthorpej freeIf(d); 5178db30ca8Sthorpej} 5188db30ca8Sthorpej 5198db30ca8Sthorpejvoid createDialogWindow(AppInfo *app) 5208db30ca8Sthorpej{ 5218db30ca8Sthorpej XSetWindowAttributes attr; 5228db30ca8Sthorpej unsigned long attrMask = 0; 5238db30ca8Sthorpej DialogInfo *d = app->dialog; 5248db30ca8Sthorpej 5258db30ca8Sthorpej attr.background_pixel = d->w3.w.background; 5268db30ca8Sthorpej attrMask |= CWBackPixel; 5278db30ca8Sthorpej attr.border_pixel = d->w3.borderColor; 5288db30ca8Sthorpej attrMask |= CWBorderPixel; 5298db30ca8Sthorpej attr.cursor = None; 5308db30ca8Sthorpej attrMask |= CWCursor; 5318db30ca8Sthorpej attr.event_mask = 0; 5328db30ca8Sthorpej attr.event_mask |= ExposureMask; 5338db30ca8Sthorpej attr.event_mask |= ButtonPressMask; 5348db30ca8Sthorpej attr.event_mask |= ButtonReleaseMask; 5358db30ca8Sthorpej attr.event_mask |= KeyPressMask; 5368db30ca8Sthorpej attrMask |= CWEventMask; 5378db30ca8Sthorpej 5388db30ca8Sthorpej d->dialogWindow = XCreateWindow(app->dpy, app->rootWindow, 5398db30ca8Sthorpej d->w3.w.x, d->w3.w.y, 5408db30ca8Sthorpej d->w3.w.width, d->w3.w.height, 5418db30ca8Sthorpej d->w3.borderWidth, 5428db30ca8Sthorpej DefaultDepthOfScreen(app->screen), 5438db30ca8Sthorpej InputOutput, 5448db30ca8Sthorpej DefaultVisualOfScreen(app->screen), 5458db30ca8Sthorpej attrMask, &attr); 5468db30ca8Sthorpej 5478db30ca8Sthorpej d->sizeHints = XAllocSizeHints(); 5488db30ca8Sthorpej if (!(d->sizeHints)) { 5498db30ca8Sthorpej destroyDialog(app); 5508db30ca8Sthorpej outOfMemory(app, __LINE__); 5518db30ca8Sthorpej } 5528db30ca8Sthorpej d->sizeHints->flags = 0; 5538db30ca8Sthorpej d->sizeHints->flags |= PPosition; 5548db30ca8Sthorpej d->sizeHints->flags |= PSize; 5558db30ca8Sthorpej d->sizeHints->min_width = d->w3.w.width; 5568db30ca8Sthorpej d->sizeHints->min_height = d->w3.w.height; 5578db30ca8Sthorpej d->sizeHints->flags |= PMinSize; 5588db30ca8Sthorpej d->sizeHints->max_width = d->w3.w.width; 5598db30ca8Sthorpej d->sizeHints->max_height = d->w3.w.height; 5608db30ca8Sthorpej d->sizeHints->flags |= PMaxSize; 5618db30ca8Sthorpej d->sizeHints->base_width = d->w3.w.width; 5628db30ca8Sthorpej d->sizeHints->base_height = d->w3.w.height; 5638db30ca8Sthorpej d->sizeHints->flags |= PBaseSize; 5648db30ca8Sthorpej 5658db30ca8Sthorpej d->wmHints = XAllocWMHints(); 5668db30ca8Sthorpej if (!(d->wmHints)) { 5678db30ca8Sthorpej destroyDialog(app); 5688db30ca8Sthorpej outOfMemory(app, __LINE__); 5698db30ca8Sthorpej } 5708db30ca8Sthorpej d->wmHints->flags = 0; 5718db30ca8Sthorpej d->wmHints->input = True; 5728db30ca8Sthorpej d->wmHints->flags |= InputHint; 5738db30ca8Sthorpej d->wmHints->initial_state = NormalState; 5748db30ca8Sthorpej d->wmHints->flags |= StateHint; 5758db30ca8Sthorpej 5768db30ca8Sthorpej d->classHints = XAllocClassHint(); 5778db30ca8Sthorpej if (!(d->classHints)) { 5788db30ca8Sthorpej destroyDialog(app); 5798db30ca8Sthorpej outOfMemory(app, __LINE__); 5808db30ca8Sthorpej } 5818db30ca8Sthorpej d->classHints->res_name = app->appName; 5828db30ca8Sthorpej d->classHints->res_class = app->appClass; 5838db30ca8Sthorpej 5848db30ca8Sthorpej if (!XStringListToTextProperty(&(d->title), 1, &(d->windowName))) { 5858db30ca8Sthorpej destroyDialog(app); 5868db30ca8Sthorpej outOfMemory(app, __LINE__); 5878db30ca8Sthorpej } 5888db30ca8Sthorpej XSetWMProperties(app->dpy, d->dialogWindow, &(d->windowName), NULL, 5898db30ca8Sthorpej app->argv, app->argc, d->sizeHints, 5908db30ca8Sthorpej d->wmHints, d->classHints); 5918db30ca8Sthorpej XSetTransientForHint(app->dpy, d->dialogWindow, d->dialogWindow); 5928db30ca8Sthorpej 5938db30ca8Sthorpej app->wmDeleteWindowAtom = XInternAtom(app->dpy, "WM_DELETE_WINDOW", False); 5948db30ca8Sthorpej XSetWMProtocols(app->dpy, d->dialogWindow, &(app->wmDeleteWindowAtom), 1); 5958db30ca8Sthorpej} 5968db30ca8Sthorpej 5978db30ca8Sthorpejvoid createGCs(AppInfo *app) 5988db30ca8Sthorpej{ 5998db30ca8Sthorpej DialogInfo *d = app->dialog; 6008db30ca8Sthorpej 6018db30ca8Sthorpej XGCValues gcv; 6028db30ca8Sthorpej unsigned long gcvMask; 6038db30ca8Sthorpej 6048db30ca8Sthorpej gcvMask = 0; 6058db30ca8Sthorpej gcv.foreground = d->w3.w.background; 6068db30ca8Sthorpej gcvMask |= GCForeground; 6078db30ca8Sthorpej gcv.fill_style = FillSolid; 6088db30ca8Sthorpej gcvMask |= GCFillStyle; 6098db30ca8Sthorpej app->fillGC = XCreateGC(app->dpy, app->rootWindow, gcvMask, &gcv); 6108db30ca8Sthorpej 6118db30ca8Sthorpej gcvMask = 0; 6128db30ca8Sthorpej gcv.foreground = d->w3.borderColor; 6138db30ca8Sthorpej gcvMask |= GCForeground; 6148db30ca8Sthorpej gcv.line_width = d->w3.borderWidth; 6158db30ca8Sthorpej gcvMask |= GCLineWidth; 6168db30ca8Sthorpej gcv.line_style = LineSolid; 6178db30ca8Sthorpej gcvMask |= GCLineStyle; 6188db30ca8Sthorpej gcv.cap_style = CapButt; 6198db30ca8Sthorpej gcvMask |= GCCapStyle; 6208db30ca8Sthorpej gcv.join_style = JoinMiter; 6218db30ca8Sthorpej gcvMask |= GCJoinStyle; 6228db30ca8Sthorpej app->borderGC = XCreateGC(app->dpy, app->rootWindow, gcvMask, &gcv); 6238db30ca8Sthorpej 6248db30ca8Sthorpej gcvMask = 0; 6258db30ca8Sthorpej gcv.foreground = d->label.w.foreground; 6268db30ca8Sthorpej gcvMask |= GCForeground; 6278db30ca8Sthorpej gcv.background = d->label.w.background; 6288db30ca8Sthorpej gcvMask |= GCBackground; 6298db30ca8Sthorpej gcv.font = d->label.font->fid; 6308db30ca8Sthorpej gcvMask |= GCFont; 6318db30ca8Sthorpej app->textGC = XCreateGC(app->dpy, app->rootWindow, gcvMask, &gcv); 6328db30ca8Sthorpej 6338db30ca8Sthorpej gcvMask = 0; 6348db30ca8Sthorpej gcv.foreground = d->indicator.w3.w.foreground; 6358db30ca8Sthorpej gcvMask |= GCForeground; 6368db30ca8Sthorpej gcv.fill_style = FillSolid; 6378db30ca8Sthorpej gcvMask |= GCFillStyle; 6388db30ca8Sthorpej app->brightGC = XCreateGC(app->dpy, app->rootWindow, gcvMask, &gcv); 6398db30ca8Sthorpej 6408db30ca8Sthorpej gcvMask = 0; 6418db30ca8Sthorpej gcv.foreground = d->indicator.w3.w.background; 6428db30ca8Sthorpej gcvMask |= GCForeground; 6438db30ca8Sthorpej gcv.fill_style = FillSolid; 6448db30ca8Sthorpej gcvMask |= GCFillStyle; 6458db30ca8Sthorpej app->dimGC = XCreateGC(app->dpy, app->rootWindow, gcvMask, &gcv); 6468db30ca8Sthorpej} 6478db30ca8Sthorpej 6488db30ca8Sthorpejvoid destroyGCs(AppInfo *app) 6498db30ca8Sthorpej{ 6508db30ca8Sthorpej XFreeGC(app->dpy, app->fillGC); 6518db30ca8Sthorpej XFreeGC(app->dpy, app->borderGC); 6528db30ca8Sthorpej XFreeGC(app->dpy, app->textGC); 6538db30ca8Sthorpej XFreeGC(app->dpy, app->brightGC); 6548db30ca8Sthorpej XFreeGC(app->dpy, app->dimGC); 6558db30ca8Sthorpej} 6568db30ca8Sthorpej 6578db30ca8Sthorpejvoid paintLabel(AppInfo *app, Drawable draw, LabelInfo label) 6588db30ca8Sthorpej{ 6598db30ca8Sthorpej if (!(label.text)) { 6608db30ca8Sthorpej return; 6618db30ca8Sthorpej } 6628db30ca8Sthorpej XSetForeground(app->dpy, app->textGC, label.w.foreground); 6638db30ca8Sthorpej XSetBackground(app->dpy, app->textGC, label.w.background); 6648db30ca8Sthorpej XSetFont(app->dpy, app->textGC, label.font->fid); 6658db30ca8Sthorpej XDrawString(app->dpy, draw, app->textGC, label.w.x, label.w.y, label.text, 6668db30ca8Sthorpej label.textLength); 6678db30ca8Sthorpej} 6688db30ca8Sthorpej 6698db30ca8Sthorpejvoid paintButton(AppInfo *app, Drawable draw, ButtonInfo button) 6708db30ca8Sthorpej{ 6718db30ca8Sthorpej Position x; 6728db30ca8Sthorpej Position y; 6738db30ca8Sthorpej Dimension width; 6748db30ca8Sthorpej Dimension height; 6758db30ca8Sthorpej 6768db30ca8Sthorpej if (button.w3.borderWidth > 0) { 6778db30ca8Sthorpej XSetForeground(app->dpy, app->borderGC, button.w3.borderColor); 6788db30ca8Sthorpej XFillRectangle(app->dpy, draw, app->borderGC, button.w3.w.x, 6798db30ca8Sthorpej button.w3.w.y, button.w3.w.width, button.w3.w.height); 6808db30ca8Sthorpej } 6818db30ca8Sthorpej if ((button.w3.shadowThickness <= 0) && (button.pressed)) { 6828db30ca8Sthorpej Pixel tmp = button.w3.w.background; 6838db30ca8Sthorpej button.w3.w.background = button.w3.w.foreground; 6848db30ca8Sthorpej button.w3.w.foreground = tmp; 6858db30ca8Sthorpej tmp = button.label.w.background; 6868db30ca8Sthorpej button.label.w.background = button.label.w.foreground; 6878db30ca8Sthorpej button.label.w.foreground = tmp; 6888db30ca8Sthorpej } 6898db30ca8Sthorpej x = (button.w3.w.x + button.w3.borderWidth); 6908db30ca8Sthorpej y = (button.w3.w.y + button.w3.borderWidth); 6918db30ca8Sthorpej width = (button.w3.w.width - (2 * button.w3.borderWidth)); 6928db30ca8Sthorpej height = (button.w3.w.height - (2 * button.w3.borderWidth)); 6938db30ca8Sthorpej if ((button.w3.shadowThickness > 0) && (button.pressed)) { 6948db30ca8Sthorpej XSetForeground(app->dpy, app->fillGC, button.w3.topShadowColor); 6958db30ca8Sthorpej } else { 6968db30ca8Sthorpej XSetForeground(app->dpy, app->fillGC, button.w3.w.background); 6978db30ca8Sthorpej } 6988db30ca8Sthorpej XFillRectangle(app->dpy, draw, app->fillGC, x, y, width, height); 6998db30ca8Sthorpej if (button.w3.shadowThickness > 0) { 7008db30ca8Sthorpej if (button.pressed) { 7018db30ca8Sthorpej draw_shaded_rectangle(app->dpy, draw, x, y, width, height, 7028db30ca8Sthorpej button.w3.shadowThickness, 7038db30ca8Sthorpej button.w3.bottomShadowColor, 7048db30ca8Sthorpej button.w3.topShadowColor); 7058db30ca8Sthorpej } else { 7068db30ca8Sthorpej draw_shaded_rectangle(app->dpy, draw, x, y, width, height, 7078db30ca8Sthorpej button.w3.shadowThickness, 7088db30ca8Sthorpej button.w3.topShadowColor, 7098db30ca8Sthorpej button.w3.bottomShadowColor); 7108db30ca8Sthorpej } 7118db30ca8Sthorpej } 7128db30ca8Sthorpej paintLabel(app, draw, button.label); 7138db30ca8Sthorpej if ((button.w3.shadowThickness <= 0) && (button.pressed)) { 7148db30ca8Sthorpej Pixel tmp = button.w3.w.background; 7158db30ca8Sthorpej button.w3.w.background = button.w3.w.foreground; 7168db30ca8Sthorpej button.w3.w.foreground = tmp; 7178db30ca8Sthorpej tmp = button.label.w.background; 7188db30ca8Sthorpej button.label.w.background = button.label.w.foreground; 7198db30ca8Sthorpej button.label.w.foreground = tmp; 7208db30ca8Sthorpej } 7218db30ca8Sthorpej} 7228db30ca8Sthorpej 7238db30ca8Sthorpejvoid paintIndicator(AppInfo *app, Drawable draw, IndicatorElement indicator) 7248db30ca8Sthorpej{ 7258db30ca8Sthorpej Position x; 7268db30ca8Sthorpej Position y; 7278db30ca8Sthorpej Dimension width; 7288db30ca8Sthorpej Dimension height; 7298db30ca8Sthorpej GC gc = app->dimGC; 7308db30ca8Sthorpej 7318db30ca8Sthorpej if (indicator.parent->w3.borderWidth > 0) { 7328db30ca8Sthorpej XSetForeground(app->dpy, app->borderGC, 7338db30ca8Sthorpej indicator.parent->w3.borderColor); 7348db30ca8Sthorpej XFillRectangle(app->dpy, draw, app->borderGC, indicator.w.x, 7358db30ca8Sthorpej indicator.w.y, indicator.w.width, indicator.w.height); 7368db30ca8Sthorpej } 7378db30ca8Sthorpej if (indicator.isLit) { 7388db30ca8Sthorpej gc = app->brightGC; 7398db30ca8Sthorpej } 7408db30ca8Sthorpej x = (indicator.w.x + indicator.parent->w3.borderWidth); 7418db30ca8Sthorpej y = (indicator.w.y + indicator.parent->w3.borderWidth); 7428db30ca8Sthorpej width = (indicator.w.width - (2 * indicator.parent->w3.borderWidth)); 7438db30ca8Sthorpej height = (indicator.w.height - (2 * indicator.parent->w3.borderWidth)); 7448db30ca8Sthorpej XFillRectangle(app->dpy, draw, gc, x, y, width, height); 7458db30ca8Sthorpej if (indicator.parent->w3.shadowThickness > 0) { 7468db30ca8Sthorpej draw_shaded_rectangle(app->dpy, draw, x, y, width, height, 7478db30ca8Sthorpej indicator.parent->w3.shadowThickness, 7488db30ca8Sthorpej indicator.parent->w3.bottomShadowColor, 7498db30ca8Sthorpej indicator.parent->w3.topShadowColor); 7508db30ca8Sthorpej } 7518db30ca8Sthorpej} 7528db30ca8Sthorpej 7538db30ca8Sthorpejvoid updateIndicatorElement(AppInfo *app, int i) 7548db30ca8Sthorpej{ 7558db30ca8Sthorpej DialogInfo *d = app->dialog; 7568db30ca8Sthorpej 7578db30ca8Sthorpej d->indicators[i].isLit = !(d->indicators[i].isLit); 7588db30ca8Sthorpej paintIndicator(app, d->dialogWindow, d->indicators[i]); 7598db30ca8Sthorpej} 7608db30ca8Sthorpej 7618db30ca8Sthorpejvoid updateIndicators(AppInfo *app, int condition) 7628db30ca8Sthorpej{ 7638db30ca8Sthorpej DialogInfo *d = app->dialog; 7648db30ca8Sthorpej 7658db30ca8Sthorpej if (condition > 0) { 7668db30ca8Sthorpej /* Move forward one. */ 7678db30ca8Sthorpej updateIndicatorElement(app, d->indicator.current); 7688db30ca8Sthorpej if (d->indicator.current < (d->indicator.count - 1)) { 7698db30ca8Sthorpej (d->indicator.current)++; 7708db30ca8Sthorpej } else { 7718db30ca8Sthorpej d->indicator.current = 0; 7728db30ca8Sthorpej } 7738db30ca8Sthorpej } else if (condition < 0) { 7748db30ca8Sthorpej /* Move backward one. */ 7758db30ca8Sthorpej if (d->indicator.current > 0) { 7768db30ca8Sthorpej (d->indicator.current)--; 7778db30ca8Sthorpej } else { 7788db30ca8Sthorpej d->indicator.current = d->indicator.count - 1; 7798db30ca8Sthorpej } 7808db30ca8Sthorpej updateIndicatorElement(app, d->indicator.current); 7818db30ca8Sthorpej } else { 7828db30ca8Sthorpej /* Erase them all. */ 7838db30ca8Sthorpej int i; 7848db30ca8Sthorpej 7858db30ca8Sthorpej for (i = 0; i < d->indicator.count; i++) { 7868db30ca8Sthorpej d->indicators[i].isLit = False; 7878db30ca8Sthorpej paintIndicator(app, d->dialogWindow, d->indicators[i]); 7888db30ca8Sthorpej } 7898db30ca8Sthorpej d->indicator.current = 0; 7908db30ca8Sthorpej } 7918db30ca8Sthorpej XSync(app->dpy, False); 7928db30ca8Sthorpej} 7938db30ca8Sthorpej 7948db30ca8Sthorpejvoid paintDialog(AppInfo *app) 7958db30ca8Sthorpej{ 7968db30ca8Sthorpej DialogInfo *d = app->dialog; 7978db30ca8Sthorpej Drawable draw = d->dialogWindow; 7988db30ca8Sthorpej int i; 7998db30ca8Sthorpej 8008db30ca8Sthorpej XSetForeground(app->dpy, app->fillGC, d->w3.w.background); 8018db30ca8Sthorpej XFillRectangle(app->dpy, draw, app->fillGC, 0, 0, 8028db30ca8Sthorpej d->w3.w.width, d->w3.w.height); 8038db30ca8Sthorpej if (d->w3.shadowThickness > 0) { 8048db30ca8Sthorpej draw_shaded_rectangle(app->dpy, draw, 0, 0, 8058db30ca8Sthorpej d->w3.w.width, d->w3.w.height, 8068db30ca8Sthorpej d->w3.shadowThickness, 8078db30ca8Sthorpej d->w3.topShadowColor, 8088db30ca8Sthorpej d->w3.bottomShadowColor); 8098db30ca8Sthorpej } 8108db30ca8Sthorpej paintLabel(app, draw, d->label); 8118db30ca8Sthorpej for (i = 0; i < d->indicator.count; i++) { 8128db30ca8Sthorpej paintIndicator(app, draw, d->indicators[i]); 8138db30ca8Sthorpej } 8148db30ca8Sthorpej paintButton(app, draw, d->okButton); 8158db30ca8Sthorpej paintButton(app, draw, d->cancelButton); 8168db30ca8Sthorpej XSync(app->dpy, False); 8178db30ca8Sthorpej} 8188db30ca8Sthorpej 8198db30ca8Sthorpejvoid grabKeyboard(AppInfo *app) 8208db30ca8Sthorpej{ 8218db30ca8Sthorpej if ((!(app->grabKeyboard)) || (app->isKeyboardGrabbed)) { 8228db30ca8Sthorpej return; 8238db30ca8Sthorpej } else { 8248db30ca8Sthorpej int status; 8258db30ca8Sthorpej Window grabWindow = app->dialog->dialogWindow; 8268db30ca8Sthorpej Bool ownerEvents = False; 8278db30ca8Sthorpej Bool pointerMode = GrabModeAsync; 8288db30ca8Sthorpej Bool keyboardMode = GrabModeAsync; 8298db30ca8Sthorpej 8308db30ca8Sthorpej app->isKeyboardGrabbed = True; 8318db30ca8Sthorpej XSync(app->dpy, False); 8328db30ca8Sthorpej status = XGrabKeyboard(app->dpy, grabWindow, ownerEvents, 8338db30ca8Sthorpej pointerMode, keyboardMode, CurrentTime); 8348db30ca8Sthorpej XSync(app->dpy, False); 8358db30ca8Sthorpej if (GrabSuccess != status) { 8368db30ca8Sthorpej char *reason = "reason unknown"; 8378db30ca8Sthorpej 8388db30ca8Sthorpej switch (status) { 8398db30ca8Sthorpej case AlreadyGrabbed: 8408db30ca8Sthorpej reason = "someone else already has the keyboard"; 8418db30ca8Sthorpej break; 8428db30ca8Sthorpej case GrabFrozen: 8438db30ca8Sthorpej reason = "someone else has frozen the keyboard"; 8448db30ca8Sthorpej break; 8458db30ca8Sthorpej case GrabInvalidTime: 8468db30ca8Sthorpej reason = "bad grab time [this shouldn't happen]"; 8478db30ca8Sthorpej break; 8488db30ca8Sthorpej case GrabNotViewable: 8498db30ca8Sthorpej reason = "grab not viewable [this shouldn't happen]"; 8508db30ca8Sthorpej break; 8518db30ca8Sthorpej } 8528db30ca8Sthorpej fprintf(stderr, "%s: Could not grab keyboard (%s)\n", app->appName); 8538db30ca8Sthorpej exitApp(app, EXIT_STATUS_ERROR); 8548db30ca8Sthorpej } 8558db30ca8Sthorpej } 8568db30ca8Sthorpej} 8578db30ca8Sthorpej 8588db30ca8Sthorpejvoid ungrabKeyboard(AppInfo *app) 8598db30ca8Sthorpej{ 8608db30ca8Sthorpej if (app->grabKeyboard) { 8618db30ca8Sthorpej XUngrabKeyboard(app->dpy, CurrentTime); 8628db30ca8Sthorpej } 8638db30ca8Sthorpej} 8648db30ca8Sthorpej 8658db30ca8Sthorpejvoid grabPointer(AppInfo *app) 8668db30ca8Sthorpej{ 8678db30ca8Sthorpej if ((!(app->grabPointer)) || (app->isPointerGrabbed)) { 8688db30ca8Sthorpej return; 8698db30ca8Sthorpej } else { 8708db30ca8Sthorpej int status; 8718db30ca8Sthorpej Window grabWindow = app->dialog->dialogWindow; 8728db30ca8Sthorpej Bool ownerEvents = False; 8738db30ca8Sthorpej unsigned int eventMask = ButtonPressMask | ButtonReleaseMask; 8748db30ca8Sthorpej Bool pointerMode = GrabModeAsync; 8758db30ca8Sthorpej Bool keyboardMode = GrabModeAsync; 8768db30ca8Sthorpej Window confineTo = None; 8778db30ca8Sthorpej Cursor cursor = None; 8788db30ca8Sthorpej 8798db30ca8Sthorpej app->isPointerGrabbed = True; 8808db30ca8Sthorpej XSync(app->dpy, False); 8818db30ca8Sthorpej status = XGrabPointer(app->dpy, grabWindow, ownerEvents, eventMask, 8828db30ca8Sthorpej pointerMode, keyboardMode, confineTo, cursor, 8838db30ca8Sthorpej CurrentTime); 8848db30ca8Sthorpej XSync(app->dpy, False); 8858db30ca8Sthorpej if (GrabSuccess != status) { 8868db30ca8Sthorpej char *reason = "reason unknown"; 8878db30ca8Sthorpej 8888db30ca8Sthorpej switch (status) { 8898db30ca8Sthorpej case AlreadyGrabbed: 8908db30ca8Sthorpej reason = "someone else already has the pointer"; 8918db30ca8Sthorpej break; 8928db30ca8Sthorpej case GrabFrozen: 8938db30ca8Sthorpej reason = "someone else has frozen the pointer"; 8948db30ca8Sthorpej break; 8958db30ca8Sthorpej case GrabInvalidTime: 8968db30ca8Sthorpej reason = "bad grab time [this shouldn't happen]"; 8978db30ca8Sthorpej break; 8988db30ca8Sthorpej case GrabNotViewable: 8998db30ca8Sthorpej reason = "grab not viewable [this shouldn't happen]"; 9008db30ca8Sthorpej break; 9018db30ca8Sthorpej } 9028db30ca8Sthorpej fprintf(stderr, "%s: Could not grab pointer (%s)\n", app->appName); 9038db30ca8Sthorpej exitApp(app, EXIT_STATUS_ERROR); 9048db30ca8Sthorpej } 9058db30ca8Sthorpej } 9068db30ca8Sthorpej} 9078db30ca8Sthorpej 9088db30ca8Sthorpejvoid ungrabPointer(AppInfo *app) 9098db30ca8Sthorpej{ 9108db30ca8Sthorpej if (app->grabPointer) { 9118db30ca8Sthorpej XUngrabPointer(app->dpy, CurrentTime); 9128db30ca8Sthorpej } 9138db30ca8Sthorpej} 9148db30ca8Sthorpej 9158db30ca8Sthorpejvoid grabServer(AppInfo *app) 9168db30ca8Sthorpej{ 9178db30ca8Sthorpej if ((!(app->grabServer)) || (app->isServerGrabbed)) { 9188db30ca8Sthorpej return; 9198db30ca8Sthorpej } else { 9208db30ca8Sthorpej app->isServerGrabbed = True; 9218db30ca8Sthorpej XSync(app->dpy, False); 9228db30ca8Sthorpej XGrabServer(app->dpy); 9238db30ca8Sthorpej XSync(app->dpy, False); 9248db30ca8Sthorpej } 9258db30ca8Sthorpej} 9268db30ca8Sthorpej 9278db30ca8Sthorpejvoid ungrabServer(AppInfo *app) 9288db30ca8Sthorpej{ 9298db30ca8Sthorpej if (app->grabServer) { 9308db30ca8Sthorpej XUngrabServer(app->dpy); 9318db30ca8Sthorpej } 9328db30ca8Sthorpej} 9338db30ca8Sthorpej 9348db30ca8Sthorpejvoid cleanUp(AppInfo *app) 9358db30ca8Sthorpej{ 9368db30ca8Sthorpej XDestroyWindow(app->dpy, app->dialog->dialogWindow); 9378db30ca8Sthorpej destroyGCs(app); 9388db30ca8Sthorpej destroyDialog(app); 9398db30ca8Sthorpej if (app->buf) { 9408db30ca8Sthorpej memset(app->buf, 0, app->bufSize); 9418db30ca8Sthorpej } 9428db30ca8Sthorpej freeIf(app->buf); 9438db30ca8Sthorpej ungrabPointer(app); 9448db30ca8Sthorpej ungrabKeyboard(app); 9458db30ca8Sthorpej ungrabServer(app); 9468db30ca8Sthorpej} 9478db30ca8Sthorpej 9488db30ca8Sthorpejvoid exitApp(AppInfo *app, int exitCode) 9498db30ca8Sthorpej{ 9508db30ca8Sthorpej cleanUp(app); 9518db30ca8Sthorpej exit(exitCode); 9528db30ca8Sthorpej} 9538db30ca8Sthorpej 9548db30ca8Sthorpejvoid acceptAction(AppInfo *app) 9558db30ca8Sthorpej{ 9568db30ca8Sthorpej int status = append_to_buf(&(app->buf), &(app->bufSize), 9578db30ca8Sthorpej &(app->bufIndex), '\0'); 9588db30ca8Sthorpej if (APPEND_FAILURE == status) { 9598db30ca8Sthorpej cleanUp(app); 9608db30ca8Sthorpej outOfMemory(app, __LINE__); 9618db30ca8Sthorpej } 9628db30ca8Sthorpej fputs(app->buf, stdout); 9638db30ca8Sthorpej fputc('\n', stdout); 9648db30ca8Sthorpej exitApp(app, EXIT_STATUS_ACCEPT); 9658db30ca8Sthorpej} 9668db30ca8Sthorpej 9678db30ca8Sthorpejvoid cancelAction(AppInfo *app) 9688db30ca8Sthorpej{ 9698db30ca8Sthorpej exitApp(app, EXIT_STATUS_CANCEL); 9708db30ca8Sthorpej} 9718db30ca8Sthorpej 9728db30ca8Sthorpejvoid backspacePassphrase(AppInfo *app) 9738db30ca8Sthorpej{ 9748db30ca8Sthorpej if (0 >= app->bufIndex) { 9758db30ca8Sthorpej XBell(app->dpy, 0); 9768db30ca8Sthorpej return; 9778db30ca8Sthorpej } 9788db30ca8Sthorpej (app->bufIndex)--; 9798db30ca8Sthorpej updateIndicators(app, -1); 9808db30ca8Sthorpej} 9818db30ca8Sthorpej 9828db30ca8Sthorpejvoid erasePassphrase(AppInfo *app) 9838db30ca8Sthorpej{ 9848db30ca8Sthorpej if (0 >= app->bufIndex) { 9858db30ca8Sthorpej XBell(app->dpy, 0); 9868db30ca8Sthorpej return; 9878db30ca8Sthorpej } 9888db30ca8Sthorpej updateIndicators(app, 0); 9898db30ca8Sthorpej app->bufIndex = 0; 9908db30ca8Sthorpej} 9918db30ca8Sthorpej 9928db30ca8Sthorpejvoid addToPassphrase(AppInfo *app, char c) 9938db30ca8Sthorpej{ 9948db30ca8Sthorpej int status = append_to_buf(&(app->buf), &(app->bufSize), 9958db30ca8Sthorpej &(app->bufIndex), c); 9968db30ca8Sthorpej if (APPEND_FAILURE == status) { 9978db30ca8Sthorpej cleanUp(app); 9988db30ca8Sthorpej outOfMemory(app, __LINE__); 9998db30ca8Sthorpej } 10008db30ca8Sthorpej updateIndicators(app, 1); 10018db30ca8Sthorpej} 10028db30ca8Sthorpej 10038db30ca8Sthorpejvoid handleKeyPress(AppInfo *app, XKeyEvent *event) 10048db30ca8Sthorpej{ 10058db30ca8Sthorpej char s[2]; 10068db30ca8Sthorpej int n; 10078db30ca8Sthorpej 10088db30ca8Sthorpej if (event->send_event) { 10098db30ca8Sthorpej /* Pay no attention to synthetic key events. */ 10108db30ca8Sthorpej return; 10118db30ca8Sthorpej } 10128db30ca8Sthorpej n = XLookupString(event, s, 1, NULL, NULL); 10138db30ca8Sthorpej 10148db30ca8Sthorpej if (1 != n) { 10158db30ca8Sthorpej return; 10168db30ca8Sthorpej } 10178db30ca8Sthorpej s[1] = '\0'; 10188db30ca8Sthorpej switch (s[0]) { 10198db30ca8Sthorpej case '\010': 10208db30ca8Sthorpej case '\177': 10218db30ca8Sthorpej backspacePassphrase(app); 10228db30ca8Sthorpej break; 10238db30ca8Sthorpej case '\025': 10248db30ca8Sthorpej case '\030': 10258db30ca8Sthorpej erasePassphrase(app); 10268db30ca8Sthorpej break; 10278db30ca8Sthorpej case '\012': 10288db30ca8Sthorpej case '\015': 10298db30ca8Sthorpej acceptAction(app); 10308db30ca8Sthorpej break; 10318db30ca8Sthorpej case '\033': 10328db30ca8Sthorpej cancelAction(app); 10338db30ca8Sthorpej break; 10348db30ca8Sthorpej default: 10358db30ca8Sthorpej addToPassphrase(app, s[0]); 10368db30ca8Sthorpej break; 10378db30ca8Sthorpej } 10388db30ca8Sthorpej} 10398db30ca8Sthorpej 10408db30ca8SthorpejBool eventIsInsideButton(AppInfo *app, XButtonEvent *event, ButtonInfo button) 10418db30ca8Sthorpej{ 10428db30ca8Sthorpej int status = False; 10438db30ca8Sthorpej 10448db30ca8Sthorpej if ((event->x >= (button.w3.w.x + button.w3.borderWidth)) && 10458db30ca8Sthorpej (event->x < (button.w3.w.x + button.w3.w.width - 10468db30ca8Sthorpej (2 * button.w3.borderWidth))) && 10478db30ca8Sthorpej (event->y >= (button.w3.w.y + button.w3.borderWidth)) && 10488db30ca8Sthorpej (event->y < (button.w3.w.y + button.w3.w.height - 10498db30ca8Sthorpej (2 * button.w3.borderWidth)))) { 10508db30ca8Sthorpej status = True; 10518db30ca8Sthorpej } 10528db30ca8Sthorpej return(status); 10538db30ca8Sthorpej} 10548db30ca8Sthorpej 10558db30ca8Sthorpejvoid handleButtonPress(AppInfo *app, XButtonEvent *event) 10568db30ca8Sthorpej{ 10578db30ca8Sthorpej DialogInfo *d = app->dialog; 10588db30ca8Sthorpej 10598db30ca8Sthorpej if (event->button != Button1) { 10608db30ca8Sthorpej return; 10618db30ca8Sthorpej } 10628db30ca8Sthorpej if (ButtonPress == event->type) { 10638db30ca8Sthorpej if (eventIsInsideButton(app, event, d->okButton)) { 10648db30ca8Sthorpej d->pressedButton = OK_BUTTON; 10658db30ca8Sthorpej d->okButton.pressed = True; 10668db30ca8Sthorpej paintButton(app, d->dialogWindow, d->okButton); 10678db30ca8Sthorpej } else if (eventIsInsideButton(app, event, d->cancelButton)) { 10688db30ca8Sthorpej d->pressedButton = CANCEL_BUTTON; 10698db30ca8Sthorpej d->cancelButton.pressed = True; 10708db30ca8Sthorpej paintButton(app, d->dialogWindow, d->cancelButton); 10718db30ca8Sthorpej } else { 10728db30ca8Sthorpej d->pressedButton = NO_BUTTON; 10738db30ca8Sthorpej } 10748db30ca8Sthorpej } else if (ButtonRelease == event->type) { 10758db30ca8Sthorpej if (OK_BUTTON == d->pressedButton) { 10768db30ca8Sthorpej if (eventIsInsideButton(app, event, d->okButton)) { 10778db30ca8Sthorpej acceptAction(app); 10788db30ca8Sthorpej } else { 10798db30ca8Sthorpej d->okButton.pressed = False; 10808db30ca8Sthorpej paintButton(app, d->dialogWindow, d->okButton); 10818db30ca8Sthorpej } 10828db30ca8Sthorpej } else if (CANCEL_BUTTON == d->pressedButton) { 10838db30ca8Sthorpej if (eventIsInsideButton(app, event, d->cancelButton)) { 10848db30ca8Sthorpej cancelAction(app); 10858db30ca8Sthorpej } else { 10868db30ca8Sthorpej d->cancelButton.pressed = False; 10878db30ca8Sthorpej paintButton(app, d->dialogWindow, d->cancelButton); 10888db30ca8Sthorpej } 10898db30ca8Sthorpej } 10908db30ca8Sthorpej d->pressedButton = NO_BUTTON; 10918db30ca8Sthorpej } 10928db30ca8Sthorpej} 10938db30ca8Sthorpej 10948db30ca8Sthorpejint main(int argc, char **argv) 10958db30ca8Sthorpej{ 10968db30ca8Sthorpej AppInfo app; 10978db30ca8Sthorpej XEvent event; 10988db30ca8Sthorpej 10998db30ca8Sthorpej memset(&app, 0, sizeof(app)); 11008db30ca8Sthorpej 11018db30ca8Sthorpej app.argc = argc; 11028db30ca8Sthorpej app.argv = argv; 11038db30ca8Sthorpej 11048db30ca8Sthorpej progclass = "SshAskpass"; 11058db30ca8Sthorpej app.toplevelShell = XtAppInitialize(&(app.appContext), progclass, 11068db30ca8Sthorpej NULL, 0, &argc, argv, 11078db30ca8Sthorpej defaults, NULL, 0); 11088db30ca8Sthorpej app.dpy = XtDisplay(app.toplevelShell); 11098db30ca8Sthorpej app.screen = DefaultScreenOfDisplay(app.dpy); 11108db30ca8Sthorpej app.rootWindow = RootWindowOfScreen(app.screen); 11118db30ca8Sthorpej app.black = BlackPixel(app.dpy, DefaultScreen(app.dpy)); 11128db30ca8Sthorpej app.white = WhitePixel(app.dpy, DefaultScreen(app.dpy)); 11138db30ca8Sthorpej app.colormap = DefaultColormapOfScreen(app.screen); 11148db30ca8Sthorpej app.resourceDb = XtDatabase(app.dpy); 11158db30ca8Sthorpej XtGetApplicationNameAndClass(app.dpy, &progname, &progclass); 11168db30ca8Sthorpej app.appName = progname; 11178db30ca8Sthorpej app.appClass = progclass; 11188db30ca8Sthorpej /* For resources.c. */ 11198db30ca8Sthorpej db = app.resourceDb; 11208db30ca8Sthorpej 11218db30ca8Sthorpej { 11228db30ca8Sthorpej struct rlimit resourceLimit; 11238db30ca8Sthorpej int status; 11248db30ca8Sthorpej 11258db30ca8Sthorpej status = getrlimit(RLIMIT_CORE, &resourceLimit); 11268db30ca8Sthorpej if (-1 == status) { 11278db30ca8Sthorpej fprintf(stderr, "%s: getrlimit failed (%s)\n", app.appName, 11288db30ca8Sthorpej strerror(errno)); 11298db30ca8Sthorpej exit(EXIT_STATUS_ERROR); 11308db30ca8Sthorpej } 11318db30ca8Sthorpej resourceLimit.rlim_cur = 0; 11328db30ca8Sthorpej status = setrlimit(RLIMIT_CORE, &resourceLimit); 11338db30ca8Sthorpej if (-1 == status) { 11348db30ca8Sthorpej fprintf(stderr, "%s: setrlimit failed (%s)\n", app.appName, 11358db30ca8Sthorpej strerror(errno)); 11368db30ca8Sthorpej exit(EXIT_STATUS_ERROR); 11378db30ca8Sthorpej } 11388db30ca8Sthorpej } 11398db30ca8Sthorpej 11408db30ca8Sthorpej createDialog(&app); 11418db30ca8Sthorpej createGCs(&app); 11428db30ca8Sthorpej createDialogWindow(&app); 11438db30ca8Sthorpej 11448db30ca8Sthorpej XMapWindow(app.dpy, app.dialog->dialogWindow); 11458db30ca8Sthorpej 11468db30ca8Sthorpej while(True) { 11478db30ca8Sthorpej XNextEvent(app.dpy, &event); 11488db30ca8Sthorpej switch (event.type) { 11498db30ca8Sthorpej case Expose: 11508db30ca8Sthorpej grabServer(&app); 11518db30ca8Sthorpej grabKeyboard(&app); 11528db30ca8Sthorpej grabPointer(&app); 11538db30ca8Sthorpej if (event.xexpose.count) { 11548db30ca8Sthorpej break; 11558db30ca8Sthorpej } 11568db30ca8Sthorpej paintDialog(&app); 11578db30ca8Sthorpej break; 11588db30ca8Sthorpej case ButtonPress: 11598db30ca8Sthorpej case ButtonRelease: 11608db30ca8Sthorpej handleButtonPress(&app, &(event.xbutton)); 11618db30ca8Sthorpej break; 11628db30ca8Sthorpej case KeyPress: 11638db30ca8Sthorpej handleKeyPress(&app, &(event.xkey)); 11648db30ca8Sthorpej break; 11658db30ca8Sthorpej case ClientMessage: 11668db30ca8Sthorpej if ((32 == event.xclient.format) && 11678db30ca8Sthorpej (event.xclient.data.l[0] == app.wmDeleteWindowAtom)) { 11688db30ca8Sthorpej cancelAction(&app); 11698db30ca8Sthorpej } 11708db30ca8Sthorpej break; 11718db30ca8Sthorpej default: 11728db30ca8Sthorpej break; 11738db30ca8Sthorpej } 11748db30ca8Sthorpej } 11758db30ca8Sthorpej 11768db30ca8Sthorpej fprintf(stderr, "%s: This should not happen.\n", app.appName); 11778db30ca8Sthorpej return(EXIT_STATUS_ANOMALY); 11788db30ca8Sthorpej} 11798db30ca8Sthorpej 1180