long getResolutionResource(AppInfo *app, char *instanceName, char *className,
			   char *defaultResolutionSpec)
{
   char units[3];
   char *s;
   int n;
   long resolution;
   unsigned int i;
   
   memset(units, 0, sizeof(units));
   s = getStringResourceWithDefault(instanceName, className,
				    defaultResolutionSpec);
   /* NOTE: The width of the %s format must be one less than
    * the length of the units[] array above!
    */
   n = sscanf(s, "%ld / %2s", &resolution, units);
   if (n != 2) {
      fprintf(stderr, "%s[%ld]: invalid value '%s' for %s.\n",
	      app->appName, (long) app->pid, s, instanceName);
      resolution = DefaultResolution;
   } else {
      if (resolution < 0) {
	 /* Resolution specifications should not be negative. */
	 resolution = -(resolution);
      }
      for (i = 0; i < (sizeof(units) - 1); i++) {
	 units[i] = tolower(units[i]);
      }
      if ((0 == strcmp(units, "in")) ||
	  (0 == strcmp(units, "i")) ||
	  (0 == strcmp(units, "\""))) {
	 /* dots/inch */
	 resolution = resolution * 10000 / 254;
      } else if ((0 == strcmp(units, "m")) ||
		 (0 == strcmp(units, "me"))) {
	 /* dots/meter; no conversion necessary */
	 ;
      } else {
	 /* some unit we don't recognize; cringe and stare at the floor */
	 resolution = DefaultResolution;
      }
   }
   free(s);
   return(resolution);
}
Esempio n. 2
0
void createDialog(AppInfo *app)
{
   DialogInfo *d;
   char *labelText;
   
   if (app->dialog) {
      return;
   }
   d = malloc(sizeof(*d));
   if (NULL == d) {
      outOfMemory(app, __LINE__);
   }
   memset(d, 0, sizeof(*d));

   app->grabKeyboard = 
      get_boolean_resource("grabKeyboard", "GrabKeyboard", True);
   app->grabPointer =
      get_boolean_resource("grabPointer", "GrabPointer", False);
   app->grabServer =
      get_boolean_resource("grabServer", "GrabServer", False);

   /* inputTimeout resource specified in seconds for easy human interface.
    * Convert to milliseconds here.
    */
   app->inputTimeout = (unsigned long) 1000 *
      getUnsignedIntegerResource(app, "inputTimeout", "InputTimeout", 0);
   
   app->defaultXResolution =
      getResolutionResource(app, "defaultXResolution", "DefaultXResolution",
			    "75/in");
   app->defaultYResolution =
      getResolutionResource(app, "defaultYResolution", "DefaultYResolution",
			    "75/in");
   app->xFuzz =
      getResolutionResource(app, "xResolutionFuzz", "XResolutionFuzz", "20/in");
   app->yFuzz =
      getResolutionResource(app, "yResolutionFuzz", "YResolutionFuzz", "20/in");
   
   d->title =
      getStringResourceWithDefault("dialog.title", "Dialog.Title",
				   "OpenSSH Authentication Passphrase Request");
   d->w3.w.foreground =
      get_pixel_resource("foreground", "Foreground",
			 app->dpy, app->colormap, app->black);
   d->w3.w.background =
      get_pixel_resource("background", "Background",
			 app->dpy, app->colormap, app->white);
   d->w3.topShadowColor =
      get_pixel_resource("topShadowColor", "TopShadowColor",
			 app->dpy, app->colormap, app->white);
   d->w3.bottomShadowColor =
      get_pixel_resource("bottomShadowColor", "BottomShadowColor",
			 app->dpy, app->colormap, app->black);
   d->w3.shadowThickness =
      get_integer_resource("shadowThickness", "ShadowThickness", 3);
   d->w3.borderColor =
      get_pixel_resource("borderColor", "BorderColor",
			 app->dpy, app->colormap, app->black);
   d->w3.borderWidth =
      get_integer_resource("borderWidth", "BorderWidth", 1);
   
   d->w3.horizontalSpacing = scaleXDimension(app,
      get_integer_resource("horizontalSpacing", "Spacing", 5));
   d->w3.verticalSpacing = scaleYDimension(app,
      get_integer_resource("verticalSpacing", "Spacing", 6));
   
   if (2 == app->argc) {
      labelText = strdup(app->argv[1]);
   } else {
      labelText =
	 getStringResourceWithDefault("dialog.label", "Dialog.Label",
				      "Please enter your authentication passphrase:");
   }
   createLabel(app, labelText, &(d->label));
   freeIf(labelText);
   d->label.font = getFontResource(app, "dialog.font", "Dialog.Font");
   calcLabelTextExtents(&(d->label));
   d->label.w.foreground = d->w3.w.foreground;
   d->label.w.background = d->w3.w.background;
   
   d->okButton.w3.w.foreground =
      get_pixel_resource("okButton.foreground", "Button.Foreground",
			 app->dpy, app->colormap, app->black);
   d->okButton.w3.w.background =
      get_pixel_resource("okButton.background", "Button.Background",
			 app->dpy, app->colormap, app->white);
   d->okButton.w3.topShadowColor =
      get_pixel_resource("okButton.topShadowColor", "Button.TopShadowColor",
			 app->dpy, app->colormap, app->white);
   d->okButton.w3.bottomShadowColor =
      get_pixel_resource("okButton.bottomShadowColor",
			 "Button.BottomShadowColor",
			 app->dpy, app->colormap, app->black);
   d->okButton.w3.shadowThickness =
      get_integer_resource("okButton.shadowThickness",
			   "Button.ShadowThickness", 2);
   d->okButton.w3.borderColor =
      get_pixel_resource("okButton.borderColor", "Button.BorderColor",
			 app->dpy, app->colormap, app->black);
   d->okButton.w3.borderWidth =
      get_integer_resource("okButton.borderWidth", "Button.BorderWidth", 1);
   d->okButton.w3.horizontalSpacing = scaleXDimension(app,
      get_integer_resource("okButton.horizontalSpacing", "Button.Spacing", 4));
   d->okButton.w3.verticalSpacing = scaleYDimension(app,
      get_integer_resource("okButton.verticalSpacing", "Button.Spacing", 2));
   labelText =
      getStringResourceWithDefault("okButton.label", "Button.Label", "OK");
   createLabel(app, labelText, &(d->okButton.label));
   freeIf(labelText);
   d->okButton.label.font =
      getFontResource(app, "okButton.font", "Button.Font");
   calcButtonExtents(&(d->okButton));
   d->okButton.label.w.foreground = d->okButton.w3.w.foreground;
   d->okButton.label.w.background = d->okButton.w3.w.background;
   
   d->cancelButton.w3.w.foreground =
      get_pixel_resource("cancelButton.foreground", "Button.Foreground",
			 app->dpy, app->colormap, app->black);
   d->cancelButton.w3.w.background =
      get_pixel_resource("cancelButton.background", "Button.Background",
			 app->dpy, app->colormap, app->white);
   d->cancelButton.w3.topShadowColor =
      get_pixel_resource("cancelButton.topShadowColor",
			 "Button.TopShadowColor",
			 app->dpy, app->colormap, app->white);
   d->cancelButton.w3.bottomShadowColor =
      get_pixel_resource("cancelButton.bottomShadowColor",
			 "Button.BottomShadowColor",
			 app->dpy, app->colormap, app->black);
   d->cancelButton.w3.shadowThickness =
      get_integer_resource("cancelButton.shadowThickness",
			   "Button.ShadowThickness", 2);
   d->cancelButton.w3.borderColor =
      get_pixel_resource("cancelButton.borderColor", "Button.BorderColor",
			 app->dpy, app->colormap, app->black);
   d->cancelButton.w3.borderWidth =
      get_integer_resource("cancelButton.borderWidth", "Button.BorderWidth",
			   1);
   d->cancelButton.w3.horizontalSpacing = scaleXDimension(app,
      get_integer_resource("cancelButton.horizontalSpacing", "Button.Spacing",
			   4));
   d->cancelButton.w3.verticalSpacing = scaleYDimension(app,
      get_integer_resource("cancelButton.verticalSpacing", "Button.Spacing",
			   2));
   labelText =
      getStringResourceWithDefault("cancelButton.label", "Button.Label",
				   "Cancel");
   createLabel(app, labelText, &(d->cancelButton.label));
   freeIf(labelText);
   d->cancelButton.label.font =
      getFontResource(app, "cancelButton.font", "Button.Font");
   calcButtonExtents(&(d->cancelButton));
   d->cancelButton.label.w.foreground = d->cancelButton.w3.w.foreground;
   d->cancelButton.label.w.background = d->cancelButton.w3.w.background;

   balanceButtonExtents(&(d->okButton), &(d->cancelButton));
   
   d->indicator.w3.w.foreground =
      get_pixel_resource("indicator.foreground", "Indicator.Foreground",
			 app->dpy, app->colormap, app->black);
   d->indicator.w3.w.background =
      get_pixel_resource("indicator.background", "Indicator.Background",
			 app->dpy, app->colormap, app->white);
   d->indicator.w3.w.width = scaleXDimension(app,
      get_integer_resource("indicator.width", "Indicator.Width", 15));
   d->indicator.w3.w.height = scaleYDimension(app,
      get_integer_resource("indicator.height", "Indicator.Height", 7));
   d->indicator.w3.topShadowColor =
      get_pixel_resource("indicator.topShadowColor",
			 "Indicator.TopShadowColor",
			 app->dpy, app->colormap, app->white);
   d->indicator.w3.bottomShadowColor =
      get_pixel_resource("indicator.bottomShadowColor",
			 "Indicator.BottomShadowColor",
			 app->dpy, app->colormap, app->black);
   d->indicator.w3.shadowThickness =
      get_integer_resource("indicator.shadowThickness",
			   "Indicator.ShadowThickness", 2);
   d->indicator.w3.borderColor =
      get_pixel_resource("indicator.borderColor", "Indicator.BorderColor",
			 app->dpy, app->colormap, app->black);
   d->indicator.w3.borderWidth =
      get_integer_resource("indicator.borderWidth", "Indicator.BorderWidth",
			   0);
   d->indicator.w3.horizontalSpacing = scaleXDimension(app,
      get_integer_resource("indicator.horizontalSpacing", "Indicator.Spacing",
			   2));
   d->indicator.w3.verticalSpacing =scaleYDimension(app,
      get_integer_resource("indicator.verticalSpacing", "Indicator.Spacing",
			   4));
   d->indicator.minimumCount =
      get_integer_resource("indicator.minimumCount", "Indicator.MinimumCount",
			   8);
   d->indicator.maximumCount =
      get_integer_resource("indicator.maximumCount", "Indicator.MaximumCount",
			   24);
   d->indicator.w3.interiorWidth = d->indicator.w3.w.width;
   d->indicator.w3.interiorHeight = d->indicator.w3.w.height;
   d->indicator.w3.w.width += (2 * d->indicator.w3.shadowThickness);
   d->indicator.w3.w.width += (2 * d->indicator.w3.borderWidth);
   d->indicator.w3.w.height += (2 * d->indicator.w3.shadowThickness);
   d->indicator.w3.w.height += (2 * d->indicator.w3.borderWidth);
   {
      /* Make sure the indicators can all fit on the screen.
       * 80% of the screen width seems fine.
       */
      Dimension maxWidth = (WidthOfScreen(app->screen) * 8 / 10);
      Dimension extraSpace = ((2 * d->w3.horizontalSpacing) +
			      (2 * d->w3.shadowThickness));
      
      if (d->indicator.maximumCount < 8) {
	 d->indicator.maximumCount = 8;
      }
      if (((d->indicator.maximumCount * d->indicator.w3.w.width) +
	   ((d->indicator.maximumCount - 1) *
	    d->indicator.w3.horizontalSpacing) + extraSpace) > maxWidth) {
	 d->indicator.maximumCount =
	    ((maxWidth - extraSpace - d->indicator.w3.w.width) /
	     (d->indicator.w3.w.width + d->indicator.w3.horizontalSpacing))
	    + 1;
      }
      if (d->indicator.minimumCount <= 6) {
	 d->indicator.minimumCount = 6;
      }
      if (d->indicator.minimumCount > d->indicator.maximumCount) {
	 d->indicator.minimumCount = d->indicator.maximumCount;
      }
   }
   
   {
      /* Calculate the width and horizontal position of things. */
      Dimension labelAreaWidth;
      Dimension buttonAreaWidth;
      Dimension indicatorAreaWidth;
      Dimension extraIndicatorSpace;
      Dimension singleIndicatorSpace;
      Dimension interButtonSpace;
      Dimension w;
      Position leftX;
      int i;
      
      labelAreaWidth = d->label.w.width + (2 * d->w3.horizontalSpacing);
      buttonAreaWidth = ((3 * d->w3.horizontalSpacing) +
			 d->okButton.w3.w.width +
			 d->cancelButton.w3.w.width);
      w = MAX(labelAreaWidth, buttonAreaWidth);
      extraIndicatorSpace = ((2 * d->w3.horizontalSpacing) +
			     d->indicator.w3.w.width);
      singleIndicatorSpace = (d->indicator.w3.w.width +
			      d->indicator.w3.horizontalSpacing);
      d->indicator.count = ((w - extraIndicatorSpace) / singleIndicatorSpace);
      d->indicator.current = 0;
      d->indicator.count++; /* For gatepost indicator in extra space. */
      if (((w - extraIndicatorSpace) % singleIndicatorSpace) >
	  (singleIndicatorSpace / 2)) {
	 d->indicator.count++;
      }
      if (d->indicator.count < d->indicator.minimumCount) {
	 d->indicator.count = d->indicator.minimumCount;
      }
      if (d->indicator.count > d->indicator.maximumCount) {
	 d->indicator.count = d->indicator.maximumCount;
      }
      indicatorAreaWidth = ((singleIndicatorSpace * (d->indicator.count - 1)) +
			    extraIndicatorSpace);
      d->w3.interiorWidth = MAX(w, indicatorAreaWidth);
      d->w3.w.width = d->w3.interiorWidth + (2 * d->w3.shadowThickness);

      leftX = (d->w3.w.width - d->label.w.width) / 2;
      d->label.w.x = leftX;
      
      leftX = ((d->w3.w.width -
	       (d->indicator.count * d->indicator.w3.w.width) -
	       ((d->indicator.count - 1) * d->indicator.w3.horizontalSpacing))
	       / 2);
      {
	 int n = d->indicator.count * sizeof(IndicatorElement);
	 d->indicators = malloc(n);
	 if (NULL == d->indicators) {
	    destroyDialog(app);
	    outOfMemory(app, __LINE__);
	 }
	 memset(d->indicators, 0, n);
      }
      d->indicators[0].parent = &(d->indicator);
      d->indicators[0].w.x = d->indicator.w3.w.x = leftX;
      d->indicators[0].w.width = d->indicator.w3.w.width;
      d->indicators[0].isLit = False;
      for (i = 1; i < d->indicator.count; i++) {
	 d->indicators[i].parent = &(d->indicator);
	 d->indicators[i].w.x = (d->indicators[i - 1].w.x +
				 d->indicator.w3.w.width +
				 d->indicator.w3.horizontalSpacing);
	 d->indicators[i].w.width = d->indicator.w3.w.width;
	 d->indicators[i].isLit = False;
      }
      interButtonSpace = ((d->w3.interiorWidth - d->okButton.w3.w.width -
			   d->cancelButton.w3.w.width) / 3);
      d->okButton.w3.w.x = interButtonSpace + d->w3.shadowThickness;
      d->cancelButton.w3.w.x = (d->okButton.w3.w.x + d->okButton.w3.w.width +
				interButtonSpace);
   }
   {
      /* Calculate the height and vertical position of things. */
      int i;
      
      d->w3.interiorHeight = ((4 * d->w3.verticalSpacing) +
			      (2 * d->indicator.w3.verticalSpacing) +
			      d->label.w.height +
			      d->indicator.w3.w.height +
			      d->okButton.w3.w.height);
      d->w3.w.height = d->w3.interiorHeight + (2 * d->w3.shadowThickness);
      d->label.w.y = d->w3.shadowThickness + d->w3.verticalSpacing;
      d->indicator.w3.w.y = (d->label.w.y + d->label.w.height +
			     d->w3.verticalSpacing +
			     d->indicator.w3.verticalSpacing);
      for (i = 0; i < d->indicator.count; i++) {
	 d->indicators[i].w.y = d->indicator.w3.w.y;
	 d->indicators[i].w.height = d->indicator.w3.w.height;
      }
      d->okButton.w3.w.y = d->cancelButton.w3.w.y =
	 (d->indicator.w3.w.y + d->indicator.w3.w.height +
	  d->w3.verticalSpacing + d->indicator.w3.verticalSpacing);
   }
   calcButtonLabelPosition(&(d->okButton));
   calcButtonLabelPosition(&(d->cancelButton));

   d->w3.w.x = (WidthOfScreen(app->screen) - d->w3.w.width) / 2;
   d->w3.w.y = (HeightOfScreen(app->screen) - d->w3.w.height) / 3;
   
   app->dialog = d;
}