v13i033: ImageMagick - Graphics display programs, Part17/21
cristy at dupont.com
cristy at dupont.com
Fri May 24 13:20:24 AEST 1991
Submitted-by: cristy at dupont.com
Posting-number: Volume 13, Issue 33
Archive-name: imagemagic/part17
#!/bin/sh
# this is img.17 (part 17 of ImageMagick)
# do not concatenate these parts, unpack them in order with /bin/sh
# file ImageMagick/display.c continued
#
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 17; then
echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping ImageMagick/display.c'
else
echo 'x - continuing file ImageMagick/display.c'
sed 's/^X//' << 'SHAR_EOF' >> 'ImageMagick/display.c' &&
% 3 press and drag to define a region of the image to magnify
%
% Keys
% 1-9 press to change the level of magnification
% < press to half the image size
% > press to double the image size
% / press to rotate the image 90 degrees clockwise
% \ press to rotate the image 90 degrees counter-clockwise
% r press to reflect the image scanlines
% o press to restore the image to its original size
% w press to restore the image window to its original size
% m press to map or unmap the magnify window
% i press to display information about the image
% n press to display the next image
% q press to discard all images and exit program
%
%
*/
X
/*
X Include declarations.
*/
#include "display.h"
#include "image.h"
#include "X.h"
X
/*
X Define declarations.
*/
#define ConstrainMagnifyFactor(image_window,magnify_window,magnify) \
{ \
X while ((magnify*image_window->ximage->width) < magnify_window->width) \
X magnify<<=1; \
X while ((magnify*image_window->ximage->height) < magnify_window->height) \
X magnify<<=1; \
X if (magnify > magnify_window->width) \
X magnify=magnify_window->width; \
X if (magnify > magnify_window->height) \
X magnify=magnify_window->height; \
}
#define ConfigureWindowState 0x0001
#define ControlState 0x0002
#define DefaultState 0x0004
#define ExitState 0x0008
#define ImageMappedState 0x0010
#define HighlightState 0x0020
#define InfoMappedState 0x0040
#define MagnifyState 0x0080
#define MagnifyMappedState 0x0100
X
/*
X Forward declarations.
*/
static Cursor
X XMakeCursor();
X
static unsigned int
X XReflectImageWindow(),
X XResizeImageWindow(),
X XRotateImageWindow();
X
static void
X XDisplayImageWindow(),
X XMagnifyImageWindow(),
X XMakeMagnifyImage(),
X XMenuWindow(),
X XPanImageWindow();
X
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% E r r o r %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function Error displays an error message and then terminates the program.
%
% The format of the Error routine is:
%
% Error(message,qualifier)
%
% A description of each parameter follows:
%
% o message: Specifies the message to display before terminating the
% program.
%
% o qualifier: Specifies any qualifier to the message.
%
%
*/
void Error(message,qualifier)
char
X *message,
X *qualifier;
{
X (void) fprintf(stderr,"%s: %s",application_name,message);
X if (qualifier != (char *) NULL)
X (void) fprintf(stderr," (%s)",qualifier);
X (void) fprintf(stderr,".\n");
X exit(1);
}
X
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% U s a g e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function Usage displays the program command syntax.
%
% The format of the Usage routine is:
%
% Usage(message,terminate)
%
% A description of each parameter follows:
%
% o message: Specifies a specific message to display to the user.
%
% o terminate: A value other than zero is returned if the program is to
% terminate immediately.
%
*/
static void Usage(message,terminate)
char
X *message;
X
unsigned int
X terminate;
{
X char
X **p;
X
X static char
X *buttons[]=
X {
X "Control-1",
X " press and drag to pan the image",
X "1 press and drag to select a command from a pop-up menu",
X "2 press and drag to define a region of the image to clip",
X "3 press and drag to define a region of the image to magnify",
X (char *) NULL
X },
X *keys[]=
X {
X "1-9 press to change the level of magnification",
X "< press to half the image size",
X "> press to double the image size",
X "/ press to rotate the image 90 degrees clockwise",
X "\\ press to rotate the image 90 degrees counter-clockwise",
X "r press to reflect the image scanlines",
X "o press to restore the image to its original size",
X "w press to restore the image window to its original size",
X "m press to map or unmap the magnify window",
X "i press to display information about the image",
X "n press to display the next image",
X "q press to discard all images and exit program",
X (char *) NULL
X },
X *options[]=
X {
X "-backdrop display image centered on a backdrop",
X "-clip geometry preferred size and location of the clipped image",
X "-colors value preferred number of colors in the image",
X "-compress type compress image: RunlengthEncoded or QEncoded",
X "-delay seconds display the next image after pausing",
X "-display server display image to this X server",
X "-dither apply Floyd/Steinberg error diffusion to image",
X "-enhance apply a digital filter to enhance a noisy image",
X "-gamma value level of gamma correction",
X "-geometry geometry preferred size and location of the image window",
X "-gray transform image to gray scale colors",
X "-inverse apply color inversion to image",
X "-magnify value level of image magnification",
X "-map type display image using this Standard Colormap",
X "-monochrome transform image to black and white",
X "-noise reduce noise with a noise peak elimination filter",
X "-normalize tranform image to span the full range of colors",
X "-print file write image as Postscript to a file",
X "-reflect reflect the image scanlines",
X "-root display image on the root window",
X "-rotate degrees apply Paeth rotation to the image",
X "-scale geometry preferred size factors of the image",
X "-scene number image scene number",
X "-treedepth value depth of the color classification tree",
X "-verbose print detailed information about the image",
X "-visual type display image using this visual type",
X "-write file write image to a file",
X (char *) NULL
X };
X if (message != (char *) NULL)
X (void) fprintf(stderr,"Can't continue, %s\n\n",message);
X (void) fprintf(stderr,
X "Usage: %s [-options ...] file [ [-options ...] file ...]\n",
X application_name);
X (void) fprintf(stderr,"\nWhere options include: \n");
X for (p=options; *p != (char *) NULL; p++)
X (void) fprintf(stderr," %s\n",*p);
X (void) fprintf(stderr,
X "\nIn addition to those listed above, you can specify these standard X\n");
X (void) fprintf(stderr,
X "resources as command line options: -background, -bordercolor,\n");
X (void) fprintf(stderr,
X "-borderwidth, -font, -foreground, -iconGeometry, -iconic, -name, or\n");
X (void) fprintf(stderr,"-title.\n");
X (void) fprintf(stderr,
X "\nChange '-' to '+' in any option above to reverse its effect. For\n");
X (void) fprintf(stderr,
X "example, specify +compress to store the image as uncompressed.\n");
X (void) fprintf(stderr,
X "\nSpecify 'file' as '-' for standard input or output.\n");
X (void) fprintf(stderr,"\nButtons: \n");
X for (p=buttons; *p != (char *) NULL; p++)
X (void) fprintf(stderr," %s\n",*p);
X (void) fprintf(stderr,"\nKeys: \n");
X for (p=keys; *p != (char *) NULL; p++)
X (void) fprintf(stderr," %s\n",*p);
X if (terminate)
X exit(1);
}
X
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% U s e r C o m m a n d %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function UserCommand makes a transform to the image or image window as
% specified by a user menu button or keyboard command.
%
% The format of the UserCommand routine is:
%
% UserCommand(display,resource_info,info_window,image_window,magnify_window,
% image,command,timeout,state);
%
% A description of each parameter follows:
%
% o display: Specifies a connection to an X server; returned from
% XOpenDisplay.
%
% o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
% o info_window: Specifies a pointer to a XWindowInfo structure.
%
% o image_window: Specifies a pointer to a XWindowInfo structure.
%
% o magnify_window: Specifies a pointer to a XWindowInfo structure.
%
% o image: Specifies a pointer to a Image structure; UserCommand
% may transform the image and return a new image pointer.
%
% o timeout: Specifies an unsigned long; UserCommand may modify this
% value.
%
% o state: Specifies an unsigned int; UserCommand may return a
% modified state.
%
%
*/
static void UserCommand(display,resource_info,info_window,image_window,
X magnify_window,command,image,timeout,state)
Display
X *display;
X
XXResourceInfo
X *resource_info;
X
XXWindowInfo
X *info_window,
X *image_window,
X *magnify_window;
X
char
X *command;
X
Image
X **image;
X
unsigned long
X *timeout;
X
unsigned int
X *state;
{
X XWindowInfo
X window;
X
X XWindowChanges
X window_changes;
X
X if (*state & InfoMappedState)
X XWithdrawWindow(display,info_window->id,info_window->screen);
X /*
X Process user command.
X */
X switch (*command)
X {
X case 'i':
X {
X char
X text[256];
X
X /*
X Display information about the image in the info window.
X */
X (void) sprintf(text,"[%d] %s %dx%d %s \0",(*image)->scene,
X (*image)->filename,image_window->ximage->width,
X image_window->ximage->height,
X XVisualClassName(info_window->visual_info));
X if ((*image)->colors > 0)
X (void) sprintf(text,"%s%dc \0",text,(*image)->colors);
X info_window->width=XTextWidth(info_window->font_info,text,strlen(text));
X info_window->height=
X info_window->font_info->ascent+info_window->font_info->descent+4;
X XResizeWindow(display,info_window->id,info_window->width,
X info_window->height);
X XMapWindow(display,info_window->id);
X XClearWindow(display,info_window->id);
X XDrawString(display,info_window->id,info_window->graphic_context,2,
X info_window->font_info->ascent+2,text,strlen(text));
X break;
X }
X case '<':
X case '>':
X {
X /*
X Half or double the image size.
X */
X window=(*image_window);
X if (*command == '>')
X {
X window.width=image_window->ximage->width << 1;
X window.height=image_window->ximage->height << 1;
X }
X else
X {
X window.width=image_window->ximage->width >> 1;
X window.height=image_window->ximage->height >> 1;
X if ((window.width == 0) || (window.height == 0))
X break;
X }
X (void) XResizeImageWindow(display,resource_info,info_window,&window,
X *image);
X image_window->ximage=window.ximage;
X window_changes.width=image_window->ximage->width;
X if (window_changes.width > XDisplayWidth(display,image_window->screen))
X window_changes.width=XDisplayWidth(display,image_window->screen);
X window_changes.height=image_window->ximage->height;
X if (window_changes.height > XDisplayHeight(display,image_window->screen))
X window_changes.height=XDisplayHeight(display,image_window->screen);
X if ((image_window->width == window_changes.width) &&
X (image_window->height == window_changes.height))
X XDisplayImageWindow(display,image_window,0,0,image_window->width,
X image_window->height);
X else
X {
X /*
X Resize image window.
X */
X XReconfigureWMWindow(display,image_window->id,image_window->screen,
X CWWidth | CWHeight,&window_changes);
X *state|=ConfigureWindowState;
X }
X break;
X }
X case '/':
X case '\\':
X {
X unsigned int
X status;
X
X /*
X Rotate image 90 degrees to the right or left.
X */
X status=XRotateImageWindow(display,info_window,image_window,
X (unsigned int) (*command == '/' ? 90 : 270),image);
X if (!status)
X break;
X window=(*image_window);
X window.width=image_window->ximage->height;
X window.height=image_window->ximage->width;
X (void) XResizeImageWindow(display,resource_info,info_window,&window,
X *image);
X image_window->ximage=window.ximage;
X window_changes.width=image_window->ximage->width;
X if (window_changes.width > XDisplayWidth(display,image_window->screen))
X window_changes.width=XDisplayWidth(display,image_window->screen);
X window_changes.height=image_window->ximage->height;
X if (window_changes.height > XDisplayHeight(display,image_window->screen))
X window_changes.height=XDisplayHeight(display,image_window->screen);
X if ((image_window->width == window_changes.width) &&
X (image_window->height == window_changes.height))
X XDisplayImageWindow(display,image_window,0,0,image_window->width,
X image_window->height);
X else
X {
X /*
X Resize image window.
X */
X XReconfigureWMWindow(display,image_window->id,image_window->screen,
X CWWidth | CWHeight,&window_changes);
X *state|=ConfigureWindowState;
X }
X break;
X }
X case 'r':
X {
X /*
X Reflect image scanlines.
X */
X (void) XReflectImageWindow(display,info_window,image_window,image);
X (void) XResizeImageWindow(display,resource_info,info_window,image_window,
X *image);
X XDisplayImageWindow(display,image_window,0,0,image_window->width,
X image_window->height);
X break;
X }
X case 'o':
X case 'w':
X {
X /*
X Restore image or image window to its original size.
X */
X if (image_window->clip_geometry != (char *) NULL)
X {
X unsigned int
X clip_height,
X clip_width;
X
X /*
X Retain the image clipping offsets; discard geometry.
X */
X (void) XParseGeometry(image_window->clip_geometry,&image_window->x,
X &image_window->y,&clip_width,&clip_height);
X image_window->x=(-image_window->x);
X image_window->y=(-image_window->y);
X (void) free((char *) image_window->clip_geometry);
X image_window->clip_geometry=(char *) NULL;
X }
X window=(*image_window);
X window.width=(*image)->columns;
X window.height=(*image)->rows;
X (void) XResizeImageWindow(display,resource_info,info_window,&window,
X *image);
X image_window->ximage=window.ximage;
X window_changes.width=image_window->ximage->width;
X if (window_changes.width > XDisplayWidth(display,image_window->screen))
X window_changes.width=XDisplayWidth(display,image_window->screen);
X window_changes.height=image_window->ximage->height;
X if (window_changes.height > XDisplayHeight(display,image_window->screen))
X window_changes.height=XDisplayHeight(display,image_window->screen);
X if ((*command == 'o') ||
X ((image_window->width == window_changes.width) &&
X (image_window->height == window_changes.height)))
X XDisplayImageWindow(display,image_window,0,0,image_window->width,
X image_window->height);
X else
X {
X /*
X Resize image window.
X */
X XReconfigureWMWindow(display,image_window->id,image_window->screen,
X CWWidth | CWHeight,&window_changes);
X *state|=ConfigureWindowState;
X }
X break;
X }
X case 'm':
X {
X /*
X Unmap or unmap magnify image.
X */
X if (*state & MagnifyMappedState)
X XWithdrawWindow(display,magnify_window->id,magnify_window->screen);
X else
X {
X ConstrainMagnifyFactor(image_window,magnify_window,
X resource_info->magnify);
X XMakeMagnifyImage(magnify_window,image_window->ximage,
X resource_info->magnify);
X XMapRaised(display,magnify_window->id);
X }
X break;
X }
X case 'n':
X {
X /*
X Display next image.
X */
X *timeout=0;
X break;
X }
X case 'q':
X {
X /*
X Exit program
X */
X *state|=ExitState; /* exit program */
X break;
X }
X case ' ':
X case '\0':
X break;
X default:
X {
X XBell(display,0);
X break;
X }
X }
}
X
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% X C l i p I m a g e W i n d o w %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function XClipImageWindow displays a rectangle whose sizes changes as
% the pointer moves. When the mouse button is released, the geometry of
% the image region defined within the rectangle is returned.
%
% The format of the XClipImageWindow routine is:
%
% XClipImageWindow(display,info_window,image_window,image,x_offset,y_offset)
%
% A description of each parameter follows:
%
% o display: Specifies a connection to an X server; returned from
% XOpenDisplay.
%
% o info_window: Specifies a pointer to a XWindowInfo structure.
%
% o image_window: Specifies a pointer to a XWindowInfo structure.
%
% o image: Specifies a pointer to a Image structure; returned from
% ReadImage.
%
% o x_offset: Specifies the initial offset in the x-direction of the
% rectangle.
%
% o y_offset: Specifies the initial offset in the y-direction of the
% rectangle.
%
%
*/
static void XClipImageWindow(display,info_window,image_window,image,x_offset,
X y_offset)
Display
X *display;
X
XXWindowInfo
X *info_window,
X *image_window;
X
Image
X *image;
X
int
X x_offset,
X y_offset;
{
#define ClipRectangle(x,y,width,height) \
{ \
X if ((width >= MinRectangle) && (height >= MinRectangle)) \
X { \
X XSetFunction(display,image_window->graphic_context,GXinvert); \
X XDrawRectangle(display,image_window->id,image_window->graphic_context, \
X x,y,width-1,height-1); \
X XDrawRectangle(display,image_window->id,image_window->graphic_context, \
X x+1,y+1,width-3,height-3); \
X XSetFunction(display,image_window->graphic_context,GXcopy); \
X } \
}
#define MinRectangle 3
X
X char
X text[256];
X
X register int
X x,
X y;
X
X register unsigned int
X height,
X width;
X
X unsigned int
X state;
X
X XEvent
X event;
X
X /*
X Set the width of info window.
X */
X state=DefaultState;
X (void) sprintf(text," %dx%d%+d%+d \0",image_window->width,
X image_window->height,image_window->width,image_window->height);
X info_window->width=XTextWidth(info_window->font_info,text,strlen(text));
X info_window->height=
X info_window->font_info->ascent+info_window->font_info->descent+4;
X XResizeWindow(display,info_window->id,info_window->width,
X info_window->height);
X /*
X Size rectangle as pointer moves until the mouse button is released.
X */
X x=x_offset;
X y=y_offset;
X width=0;
X height=0;
X do
X {
X if ((width >= MinRectangle) && (height >= MinRectangle))
X {
X /*
X Display info and draw clipping rectangle.
X */
X if (!(state & InfoMappedState))
X {
X XMapWindow(display,info_window->id);
X state|=InfoMappedState;
X }
X (void) sprintf(text," %dx%d%+d%+d\0",width,height,x,y);
X XClearWindow(display,info_window->id);
X XDrawString(display,info_window->id,info_window->graphic_context,2,
X info_window->font_info->ascent+2,text,strlen(text));
X ClipRectangle(x,y,width,height);
X }
X else
X if (state & InfoMappedState)
X {
X /*
X Clipping rectangle is too small; withdraw info window.
X */
X XWithdrawWindow(display,info_window->id,info_window->screen);
X state&=(~InfoMappedState);
X }
X /*
X Wait for next event.
X */
X XMaskEvent(display,ButtonPressMask | Button2MotionMask | ButtonReleaseMask,
X &event);
X ClipRectangle(x,y,width,height);
X switch (event.type)
X {
X case ButtonPress:
X break;
X case ButtonRelease:
X {
X /*
X User has committed to clipping rectangle.
X */
X if (event.xbutton.button != Button2)
X break;
X state|=ExitState;
X break;
X }
X case MotionNotify:
X {
X /*
X Discard pending button motion events.
X */
X while (XCheckMaskEvent(display,Button2MotionMask,&event));
X x=event.xmotion.x;
X y=event.xmotion.y;
X /*
X Check boundary conditions.
X */
X if (x < 0)
X x=0;
X else
X if (x > image_window->width)
X x=image_window->width-1;
X if (x < x_offset)
X width=(unsigned int) (x_offset-x);
X else
X {
X width=(unsigned int) (x-x_offset);
X x=x_offset;
X }
X if (y < 0)
X y=0;
X else
X if (y > image_window->height)
X y=image_window->height-1;
X if (y < y_offset)
X height=(unsigned int) (y_offset-y);
X else
X {
X height=(unsigned int) (y-y_offset);
X y=y_offset;
X }
X }
X default:
X break;
X }
X } while (!(state & ExitState));
X if (state & InfoMappedState)
X XWithdrawWindow(display,info_window->id,info_window->screen);
X if ((width >= MinRectangle) && (height >= MinRectangle))
X {
X int
X clip_x,
X clip_y;
X
X unsigned int
X clip_height,
X clip_width;
X
X unsigned long
X scale_factor;
X
X XWindowChanges
X window_changes;
X
X /*
X Check boundary conditions.
X */
X if (((x+(int) width) < image_window->x) ||
X ((y+(int) height) < image_window->y) ||
X (x > (image_window->x+image_window->ximage->width)) ||
X (y > (image_window->y+image_window->ximage->height)))
X return;
X if (x < image_window->x)
X {
X width-=(unsigned int) (image_window->x-x);
X x=image_window->x;
X }
X if (y < image_window->y)
X {
X height-=(unsigned int) (image_window->y-y);
X y=image_window->y;
X }
X if ((x+(int) width) > (image_window->x+image_window->ximage->width))
X width=(unsigned int) (image_window->x+image_window->ximage->width);
X if ((y+(int) height) > (image_window->y+image_window->ximage->height))
X height=(unsigned int) (image_window->y+image_window->ximage->height);
X x-=image_window->x;
X y-=image_window->y;
X /*
X Clipping geometry is relative to any previous clip geometry.
X */
X clip_x=0;
X clip_y=0;
X clip_width=image->columns;
X clip_height=image->rows;
X if (image_window->clip_geometry != (char *) NULL)
X (void) XParseGeometry(image_window->clip_geometry,&clip_x,&clip_y,
X &clip_width,&clip_height);
X else
X {
X /*
X Allocate clip geometry string.
X */
X image_window->clip_geometry=(char *) malloc(256);
X if (image_window->clip_geometry == (char *) NULL)
X Error("unable to clip X image",image_window->name);
X }
X /*
X Define the clip geometry string from the clipping rectangle.
X */
X scale_factor=(clip_width << 14)/image_window->ximage->width;
X if (x > 0)
X clip_x+=(x*scale_factor+8191) >> 14;
X clip_width=(width*scale_factor+8191) >> 14;
X if (clip_width == 0)
X clip_width=1;
X scale_factor=(clip_height << 14)/image_window->ximage->height;
X if (y > 0)
X clip_y+=(y*scale_factor+8191) >> 14;
X clip_height=(height*scale_factor+8191) >> 14;
X if (clip_height == 0)
X clip_height=1;
X (void) sprintf(image_window->clip_geometry,"%dx%d%+d%+d\0",clip_width,
X clip_height,clip_x,clip_y);
X /*
X Reconfigure image window as defined by clipping rectangle.
X */
X window_changes.width=width;
X window_changes.height=height;
X XReconfigureWMWindow(display,image_window->id,image_window->screen,
X CWWidth | CWHeight,&window_changes);
X }
}
X
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% X D i s p l a y I m a g e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function XDisplayImage displays an image via X11.
%
% The format of the XDisplayImage routine is:
%
% displayed_image=XDisplayImage(display,resource_info,argv,argc,image,
% clip_geometry,image_geometry,terminate)
%
% A description of each parameter follows:
%
% o display: Specifies a connection to an X server; returned from
% XOpenDisplay.
%
% o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
% o argv: Specifies the application's argument list.
%
% o argc: Specifies the number of arguments.
%
% o image: Specifies a pointer to a Image structure; returned from
% ReadImage.
%
% o clip_geometry: Returns a pointer to a clip geometry string.
% This geometry defines a subregion of the image.
%
% o image_geometry: Returns a pointer to a image geometry string.
% The specified width and height of this geometry string are absolute.
%
% o terminate: A value other than zero is returned if the user requests
% the program to terminate immediately.
%
%
*/
static Image *XDisplayImage(display,resource_info,argv,argc,image,
X clip_geometry,image_geometry,terminate)
Display
X *display;
X
XXResourceInfo
X *resource_info;
X
char
X **argv;
X
int
X argc;
X
Image
X *image;
X
char
X **clip_geometry,
X **image_geometry;
X
unsigned int
X *terminate;
{
#define MagnifySize 256 /* must be a power of 2 */
X
X Atom
X delete_property,
X protocols_property;
X
X Colormap
X colormap;
X
X char
X text[256];
X
X Cursor
X arrow_cursor,
X watch_cursor;
X
X GC
X graphic_context;
X
X unsigned int
X state;
X
X unsigned long
X timeout;
X
X Window
X root_window;
X
X XClassHint
X *class_hint;
X
X XColor
X color;
X
X XEvent
X event;
X
X XFontStruct
X *font_info;
X
X XGCValues
X graphic_context_value;
X
X XPixelInfo
X pixel_info;
X
X XStandardColormap
X *map_info;
X
X XVisualInfo
X *visual_info;
X
X XWindowInfo
X backdrop_window,
X icon_window,
X image_window,
X info_window,
X magnify_window,
X menu_window,
X superclass_window;
X
X XWMHints
X *manager_hints;
X
X /*
X Discard outstanding X events.
X */
X while (XEventsQueued(display,QueuedAfterFlush) > 0)
X XNextEvent(display,&event);
X /*
X Get the best visual this server supports.
X */
X visual_info=XBestVisualInfo(display,resource_info->visual_type,
X resource_info->map_type,&map_info);
X if (visual_info == (XVisualInfo *) NULL)
X Error("unable to get visual",resource_info->visual_type);
X /*
X Initialize colormap.
X */
X pixel_info.pixels=(unsigned long *) NULL;
X if (resource_info->map_type == (char *) NULL)
X {
X /*
X Create Standard Colormap.
X */
X map_info=XMakeStandardColormap(display,visual_info,resource_info,
X &pixel_info,image);
X colormap=map_info->colormap;
X }
X else
X {
X if (image->class == PseudoClass)
X {
X register int
X i;
X
X /*
X Initialize pixel array for images of type PseudoClass.
X */
X pixel_info.pixels=(unsigned long *)
X malloc((unsigned int) image->colors*sizeof(unsigned long));
X if (pixel_info.pixels == (unsigned long *) NULL)
X Error("unable to create colormap","memory allocation failed");
X for (i=0; i < image->colors; i++)
X pixel_info.pixels[i]=XStandardPixel(map_info,image->colormap[i],8);
X }
X /*
X Define background/border/foreground pixels.
X */
X colormap=map_info->colormap;
X XParseColor(display,colormap,resource_info->background_color,&color);
X pixel_info.background_pixel=XStandardPixel(map_info,color,16);
X XParseColor(display,colormap,resource_info->border_color,&color);
X pixel_info.border_pixel=XStandardPixel(map_info,color,16);
X XParseColor(display,colormap,resource_info->foreground_color,&color);
X pixel_info.foreground_pixel=XStandardPixel(map_info,color,16);
X }
X /*
X Initialize font info.
X */
X (void) sprintf(text," %+d%+d #%02x%02x%02x \0",image->columns,image->rows,
X MaxRgb,MaxRgb,MaxRgb);
X font_info=XBestFont(display,resource_info,text,image->columns >> 1);
X if (font_info == (XFontStruct *) NULL)
X Error("unable to load font",resource_info->font_name);
X /*
X Initialize cursor.
X */
X arrow_cursor=XCreateFontCursor(display,XC_arrow);
X watch_cursor=XCreateFontCursor(display,XC_watch);
X if ((arrow_cursor == (Cursor) NULL) || (watch_cursor == (Cursor) NULL))
X Error("unable to create cursor",(char *) NULL);
X /*
X Initialize atoms.
X */
X protocols_property=XInternAtom(display,"WM_PROTOCOLS",False);
X delete_property=XInternAtom(display,"WM_DELETE_WINDOW",False);
X if ((protocols_property == (Atom) NULL) || (delete_property == (Atom) NULL))
X Error("unable to create property",(char *) NULL);
X /*
X Initialize class and manager hints.
X */
X class_hint=XAllocClassHint();
X manager_hints=XAllocWMHints();
X if ((class_hint == (XClassHint *) NULL) ||
X (manager_hints == (XWMHints *) NULL))
X Error("unable to allocate X hints",(char *) NULL);
X if (resource_info->name == (char *) NULL)
X class_hint->res_name=application_name;
X else
X class_hint->res_name=resource_info->name;
X class_hint->res_class=(char *) "ImageMagick";
X manager_hints->flags=InputHint | StateHint;
X manager_hints->input=False;
X manager_hints->initial_state=NormalState;
X /*
X Window superclass.
X */
X superclass_window.screen=visual_info->screen;
X superclass_window.depth=visual_info->depth;
X superclass_window.visual_info=visual_info;
X superclass_window.map_info=map_info;
X superclass_window.pixel_info=(&pixel_info);
X superclass_window.font_info=font_info;
X superclass_window.cursor=arrow_cursor;
X superclass_window.busy_cursor=watch_cursor;
X superclass_window.name="ImageMagick SuperClass";
X superclass_window.geometry=(char *) NULL;
X superclass_window.icon_geometry=resource_info->icon_geometry;
X superclass_window.clip_geometry=(char *) NULL;
X superclass_window.flags=PSize;
X superclass_window.x=0;
X superclass_window.y=0;
X superclass_window.width=1;
X superclass_window.height=1;
X superclass_window.min_width=0;
X superclass_window.min_height=0;
X superclass_window.width_inc=1;
X superclass_window.height_inc=1;
X superclass_window.border_width=2;
X superclass_window.immutable=True;
X superclass_window.attributes.background_pixel=pixel_info.background_pixel;
X superclass_window.attributes.background_pixmap=(Pixmap) NULL;
X superclass_window.attributes.backing_store=WhenMapped;
X superclass_window.attributes.bit_gravity=ForgetGravity;
X superclass_window.attributes.border_pixel=pixel_info.border_pixel;
X superclass_window.attributes.colormap=colormap;
X superclass_window.attributes.cursor=arrow_cursor;
X superclass_window.attributes.do_not_propagate_mask=NoEventMask;
X superclass_window.attributes.event_mask=NoEventMask;
X superclass_window.attributes.override_redirect=False;
X superclass_window.attributes.save_under=False;
X superclass_window.attributes.win_gravity=NorthWestGravity;
X superclass_window.graphic_context=(GC) NULL;
X superclass_window.ximage=(XImage *) NULL;
X /*
X Initialize graphic context.
X */
X root_window=XRootWindow(display,visual_info->screen);
X XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
X delete_property,&superclass_window);
X graphic_context_value.background=pixel_info.background_pixel;
X graphic_context_value.foreground=pixel_info.foreground_pixel;
X graphic_context_value.font=font_info->fid;
X graphic_context_value.function=GXcopy;
X graphic_context_value.plane_mask=AllPlanes;
X graphic_context=XCreateGC(display,superclass_window.id,GCBackground |
X GCFont | GCForeground | GCFunction | GCPlaneMask,&graphic_context_value);
X if (graphic_context == (GC) NULL)
X Error("unable to create graphic context",(char *) NULL);
X superclass_window.graphic_context=graphic_context;
X /*
X Initialize icon window.
X */
X icon_window=superclass_window;
X icon_window.name="ImageMagick Icon";
X XBestIconSize(display,&icon_window,image);
X icon_window.attributes.event_mask=ExposureMask | StructureNotifyMask;
X manager_hints->flags=InputHint | StateHint | WindowGroupHint;
X manager_hints->input=False;
X manager_hints->initial_state=IconicState;
X manager_hints->window_group=superclass_window.id;
X XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
X delete_property,&icon_window);
X /*
X Initialize image window.
X */
X image_window=superclass_window;
X image_window.name=(char *) malloc(256);
X if (image_window.name == NULL)
X Error("unable to create image window","memory allocation failed");
X if (resource_info->title == (char *) NULL)
X (void) sprintf(image_window.name,"ImageMagick: %s\0",image->filename);
X else
X (void) strcpy(image_window.name,resource_info->title);
X image_window.geometry=resource_info->image_geometry;
X image_window.width=image->columns;
X if (image_window.width > XDisplayWidth(display,visual_info->screen))
X image_window.width=XDisplayWidth(display,visual_info->screen);
X image_window.height=image->rows;
X if (image_window.height > XDisplayHeight(display,visual_info->screen))
X image_window.height=XDisplayHeight(display,visual_info->screen);
X image_window.border_width=resource_info->border_width;
X backdrop_window=superclass_window;
X if (resource_info->backdrop)
X {
X /*
X Initialize backdrop window.
X */
X backdrop_window.name="ImageMagick Background";
X backdrop_window.flags=USSize | USPosition;
X backdrop_window.width=XDisplayWidth(display,visual_info->screen);
X backdrop_window.height=XDisplayHeight(display,visual_info->screen);
X backdrop_window.border_width=0;
X backdrop_window.attributes.do_not_propagate_mask=
X ButtonPressMask | ButtonReleaseMask;
X manager_hints->flags=IconWindowHint | InputHint | StateHint |
X WindowGroupHint;
X manager_hints->icon_window=icon_window.id;
X manager_hints->input=True;
X manager_hints->initial_state=
X resource_info->iconic ? IconicState : NormalState;
X manager_hints->window_group=superclass_window.id;
X XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
X delete_property,&backdrop_window);
X XSetTransientForHint(display,backdrop_window.id,backdrop_window.id);
X XMapWindow(display,backdrop_window.id);
X /*
X Position image in the center the backdrop.
X */
X image_window.flags|=USPosition;
X image_window.x=XDisplayWidth(display,visual_info->screen)/2-
X (image_window.width+image_window.border_width)/2;
X image_window.y=XDisplayHeight(display,visual_info->screen)/2-
X (image_window.height+image_window.border_width)/2;
X }
X image_window.immutable=False;
X image_window.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
X ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
X KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
X StructureNotifyMask;
X manager_hints->flags=
X IconWindowHint | InputHint | StateHint | WindowGroupHint;
X manager_hints->icon_window=icon_window.id;
X manager_hints->input=True;
X manager_hints->initial_state=
X resource_info->iconic ? IconicState : NormalState;
X manager_hints->window_group=superclass_window.id;
X XMakeWindow(display,(resource_info->backdrop ? backdrop_window.id :
X root_window),argv,argc,class_hint,manager_hints,delete_property,
X &image_window);
X XMapWindow(display,image_window.id);
X /*
X Initialize image X image structure.
X */
X image_window.x=0;
X image_window.y=0;
X image_window.ximage=XMakeImage(display,resource_info,&image_window,image,
X image->columns,image->rows);
X if (image_window.ximage == (XImage *) NULL)
X Error("unable to create X image",(char *) NULL);
X /*
X Initialize magnify window and cursor.
X */
X magnify_window=superclass_window;
X magnify_window.cursor=XMakeCursor(display,image_window.id,colormap,
X resource_info->background_color,resource_info->foreground_color);
X if (magnify_window.cursor == (Cursor) NULL)
X Error("unable to create cursor",(char *) NULL);
X magnify_window.name="ImageMagick Magnifier";
X magnify_window.width=MagnifySize;
X magnify_window.height=MagnifySize;
X magnify_window.min_width=MagnifySize;
X magnify_window.min_height=MagnifySize;
X magnify_window.width_inc=MagnifySize;
X magnify_window.height_inc=MagnifySize;
X magnify_window.immutable=False;
X magnify_window.attributes.cursor=magnify_window.cursor;
X magnify_window.attributes.event_mask=
X ExposureMask | KeyPressMask | StructureNotifyMask;
X manager_hints->flags=InputHint | StateHint | WindowGroupHint;
X manager_hints->input=False;
X manager_hints->initial_state=NormalState;
X manager_hints->window_group=superclass_window.id;
X XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
X delete_property,&magnify_window);
X /*
X Initialize magnify window X image structure.
X */
X magnify_window.x=image->columns >> 1;
X magnify_window.y=image->rows >> 1;
X magnify_window.ximage=XMakeImage(display,resource_info,&magnify_window,
X (Image *) NULL,magnify_window.width,magnify_window.height);
X if (magnify_window.ximage == (XImage *) NULL)
X Error("unable to create magnify image",(char *) NULL);
X /*
X Initialize menu window.
X */
X menu_window=superclass_window;
X menu_window.name="ImageMagick Menu";
X menu_window.flags=PSize | PPosition;
X menu_window.attributes.override_redirect=True;
X menu_window.attributes.save_under=True;
X menu_window.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
X ButtonReleaseMask | EnterWindowMask | ExposureMask | LeaveWindowMask |
X OwnerGrabButtonMask;
X manager_hints->flags=InputHint | StateHint | WindowGroupHint;
X manager_hints->input=False;
X manager_hints->initial_state=NormalState;
X manager_hints->window_group=superclass_window.id;
X XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
X delete_property,&menu_window);
X XSetTransientForHint(display,menu_window.id,image_window.id);
X /*
X Initialize info window.
X */
X info_window=superclass_window;
X info_window.name="ImageMagick Info";
X info_window.flags=PSize | PPosition;
X info_window.x=2;
X info_window.y=2;
X info_window.attributes.event_mask=StructureNotifyMask;
X manager_hints->flags=InputHint | StateHint | WindowGroupHint;
X manager_hints->input=False;
X manager_hints->initial_state=NormalState;
X manager_hints->window_group=superclass_window.id;
X XMakeWindow(display,image_window.id,argv,argc,class_hint,manager_hints,
X delete_property,&info_window);
X /*
X Respond to events.
X */
X state=DefaultState;
X timeout=(~0);
X do
X {
X /*
X Handle a window event.
X */
X if (resource_info->delay > 0)
X if (XEventsQueued(display,QueuedAfterFlush) == 0)
X {
X /*
X Block if delay > 0.
X */
X (void) sleep(1);
X continue;
X }
X XNextEvent(display,&event);
X switch (event.type)
X {
X case ButtonPress:
X {
X if (event.xbutton.window == image_window.id)
X switch (event.xbutton.button)
X {
X case Button1:
X {
X static char
X command[256];
X
X if (state & ControlState)
X {
X /*
X User pressed the image pan button.
X */
X XPanImageWindow(display,&info_window,&image_window,
X event.xbutton.x,event.xbutton.y);
X break;
X }
X /*
X Select a command from the pop-up menu.
X */
X XMenuWindow(display,&menu_window,event.xbutton.x_root,
X event.xbutton.y_root,command);
X UserCommand(display,resource_info,&info_window,&image_window,
X &magnify_window,command,&image,&timeout,&state);
X break;
X }
X case Button2:
X {
X /*
X User pressed the image clip button.
X */
X XClipImageWindow(display,&info_window,&image_window,image,
X event.xbutton.x,event.xbutton.y);
X break;
X }
X case Button3:
X {
X /*
X User pressed the image magnify button.
X */
X magnify_window.x=event.xbutton.x-image_window.x;
X magnify_window.y=event.xbutton.y-image_window.y;
X if (state & MagnifyMappedState)
X XRaiseWindow(display,magnify_window.id);
X else
X {
X XMapRaised(display,magnify_window.id);
X state|=MagnifyMappedState;
X XWindowEvent(display,magnify_window.id,ExposureMask,&event);
X }
X XMagnifyImageWindow(display,resource_info,&info_window,
X &image_window,&magnify_window);
X break;
X }
X default:
X break;
X }
X break;
X }
X case ClientMessage:
X {
X /*
X If client window delete message, exit.
X */
X if (event.xclient.message_type == protocols_property)
X if (*event.xclient.data.l == delete_property)
X if (event.xclient.window == image_window.id)
X state|=ExitState;
X else
X XWithdrawWindow(display,event.xclient.window,
X visual_info->screen);
X break;
X }
X case ConfigureNotify:
X {
X if (event.xconfigure.window == image_window.id)
X {
X static unsigned long
X scale_factor;
X
X /*
X Image window has a new configuration.
X */
X image_window.x=0;
X image_window.y=0;
X if ((event.xconfigure.width == image_window.width) &&
X (event.xconfigure.height == image_window.height))
X break;
X /*
X Make magnify offset proportional to the window size.
X */
X scale_factor=(event.xconfigure.width << 14)/image_window.width;
X magnify_window.x=(magnify_window.x*scale_factor+8191) >> 14;
X scale_factor=(event.xconfigure.height << 14)/image_window.height;
X magnify_window.y=(magnify_window.y*scale_factor+8191) >> 14;
X image_window.width=event.xconfigure.width;
X image_window.height=event.xconfigure.height;
X if (!(state & ImageMappedState))
X break;
X /*
X Make font proportional to the window size.
X */
X (void) sprintf(text," %+d%+d #%02x%02x%02x \0",image_window.width,
X image_window.height,MaxRgb,MaxRgb,MaxRgb);
X XFreeFont(display,font_info);
X font_info=
X XBestFont(display,resource_info,text,image_window.width >> 1);
X if (font_info == (XFontStruct *) NULL)
X Error("unable to load font",resource_info->font_name);
X XSetFont(display,superclass_window.graphic_context,font_info->fid);
X superclass_window.font_info=font_info;
X icon_window.font_info=font_info;
X backdrop_window.font_info=font_info;
X image_window.font_info=font_info;
X magnify_window.font_info=font_info;
X menu_window.font_info=font_info;
X info_window.font_info=font_info;
X /*
X If ConfigureState, image is already resized.
X */
X if (state & ConfigureWindowState)
X state&=(~ConfigureWindowState);
X else
X (void) XResizeImageWindow(display,resource_info,&info_window,
X &image_window,image);
X while
X (XCheckWindowEvent(display,image_window.id,ExposureMask,&event));
X XDisplayImageWindow(display,&image_window,0,0,image_window.width,
X image_window.height);
X break;
X }
X if (event.xconfigure.window == magnify_window.id)
X {
X /*
X Magnify window has a new configuration.
X */
X magnify_window.width=event.xconfigure.width;
X magnify_window.height=event.xconfigure.height;
X if (((magnify_window.width % magnify_window.width_inc) != 0) ||
X ((magnify_window.height % magnify_window.height_inc) != 0))
X break;
X XDestroyImage(magnify_window.ximage);
X magnify_window.ximage=XMakeImage(display,resource_info,
X &magnify_window,(Image *) NULL,magnify_window.width,
X magnify_window.height);
X if (magnify_window.ximage == (XImage *) NULL)
X Error("unable to create magnify image",(char *) NULL);
X ConstrainMagnifyFactor((&image_window),(&magnify_window),
X resource_info->magnify);
X XMakeMagnifyImage(&magnify_window,image_window.ximage,
X resource_info->magnify);
X XPutImage(display,magnify_window.id,magnify_window.graphic_context,
X magnify_window.ximage,0,0,0,0,magnify_window.width,
X magnify_window.height);
X break;
X }
X if (event.xconfigure.window == icon_window.id)
X {
X /*
X Icon window has a new configuration.
X */
X icon_window.width=event.xconfigure.width;
X icon_window.height=event.xconfigure.height;
X break;
X }
X }
X case EnterNotify:
X {
X /*
X Selectively install colormap.
X */
X if (colormap != XDefaultColormap(display,visual_info->screen))
X if (event.xcrossing.mode != NotifyUngrab)
X XInductColormap(display,colormap);
X break;
X }
X case Expose:
X {
X /*
X Repaint windows that are now exposed.
X */
X if (event.xexpose.window == image_window.id)
X {
X XDisplayImageWindow(display,&image_window,event.xexpose.x,
X event.xexpose.y,(unsigned int) event.xexpose.width,
X (unsigned int) event.xexpose.height);
X /*
X Reset timeout after expose.
X */
X if (resource_info->delay == 0)
X timeout=(~0);
X else
X timeout=time((long *) 0)+resource_info->delay;
X break;
X }
X if (event.xexpose.window == magnify_window.id)
X {
X XPutImage(display,magnify_window.id,magnify_window.graphic_context,
X magnify_window.ximage,event.xexpose.x,event.xexpose.y,
X event.xexpose.x,event.xexpose.y,
X (unsigned int) event.xexpose.width,
X (unsigned int) event.xexpose.height);
X break;
X }
X if (event.xexpose.window == icon_window.id)
X {
X XPutImage(display,icon_window.id,icon_window.graphic_context,
X icon_window.ximage,event.xexpose.x,event.xexpose.y,
X event.xexpose.x,event.xexpose.y,
X (unsigned int) event.xexpose.width,
X (unsigned int) event.xexpose.height);
X break;
X }
X break;
X }
X case KeyPress:
X {
X static char
X command[256];
X
X static KeySym
X key_symbol;
X
X /*
X Respond to a user key press.
X */
X if (state & ConfigureWindowState)
X {
X XBell(display,0);
X break;
X }
X *command=(char) NULL;
X XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
X &key_symbol,(XComposeStatus *) NULL);
X if (key_symbol == XK_Control_L)
X state|=ControlState;
X else
X if (key_symbol == XK_Help)
X Usage((char *) NULL,False);
X else
X if (!IsCursorKey(key_symbol) && !isdigit(*command))
X UserCommand(display,resource_info,&info_window,&image_window,
X &magnify_window,command,&image,&timeout,&state);
X else
X {
X /*
X User specified a magnify factor or position.
X */
X if (!(state & MagnifyMappedState))
X break;
X if (key_symbol == XK_Home)
X {
X magnify_window.x=0;
X magnify_window.y=0;
X }
X if (key_symbol == XK_Left)
X magnify_window.x--;
X if (key_symbol == XK_Up)
X magnify_window.y--;
X if (key_symbol == XK_Right)
X magnify_window.x++;
X if (key_symbol == XK_Down)
X magnify_window.y++;
X if (isdigit(*command))
X resource_info->magnify=1 << atoi(command);
X /*
X Magnify image.
X */
X ConstrainMagnifyFactor((&image_window),(&magnify_window),
X resource_info->magnify);
X XMakeMagnifyImage(&magnify_window,image_window.ximage,
X resource_info->magnify);
X XPutImage(display,magnify_window.id,
X magnify_window.graphic_context,magnify_window.ximage,0,0,0,0,
X magnify_window.width,magnify_window.height);
X }
X break;
X }
X case KeyRelease:
X {
X static char
X command[256];
X
X static KeySym
X key_symbol;
X
X /*
X Respond to a user key release.
X */
X *command=(char) NULL;
X XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
X &key_symbol,(XComposeStatus *) NULL);
X if (key_symbol == XK_Control_L)
X state&=(~ControlState);
X break;
X }
X case LeaveNotify:
X {
X /*
X Selectively uninstall colormap.
X */
X if (colormap != XDefaultColormap(display,visual_info->screen))
X if (event.xcrossing.mode != NotifyUngrab)
X XUninductColormap(display,colormap);
X break;
X }
X case MapNotify:
X {
X if (event.xmap.window == image_window.id)
X {
X state|=ImageMappedState;
X break;
X }
X if (event.xmap.window == magnify_window.id)
X {
X state|=MagnifyMappedState;
X break;
X }
X if (event.xmap.window == info_window.id)
X {
X state|=InfoMappedState;
X break;
X }
X if (event.xmap.window == icon_window.id)
X {
X /*
X Create icon image.
X */
X icon_window.ximage=XMakeImage(display,resource_info,&icon_window,
X image,icon_window.width,icon_window.height);
X if (icon_window.ximage == (XImage *) NULL)
X Error("unable to create icon image",(char *) NULL);
X break;
X }
X break;
X }
X case MappingNotify:
X {
X XRefreshKeyboardMapping(&event.xmapping);
X break;
X }
X case UnmapNotify:
X {
X if (event.xunmap.window == image_window.id)
X {
X state&=(~ImageMappedState);
X /*
X Unmap magnify window.
X */
X if (state & MagnifyMappedState)
X XWithdrawWindow(display,magnify_window.id,magnify_window.screen);
X break;
X }
X if (event.xunmap.window == magnify_window.id)
X {
X /*
X Destroy magnify image.
X */
X state&=(~MagnifyMappedState);
X break;
X }
X if (event.xunmap.window == info_window.id)
X {
X state&=(~InfoMappedState);
X break;
X }
X if (event.xunmap.window == icon_window.id)
X {
X /*
X Destroy icon image.
X */
X XDestroyImage(icon_window.ximage);
X icon_window.ximage=(XImage *) NULL;
X break;
X }
X break;
X }
X default:
X break;
X }
X }
X while ((timeout > time((long *) 0)) && !(state & ExitState));
X /*
X Initialize function return values.
X */
X *terminate=state & ExitState;
X *clip_geometry=image_window.clip_geometry;
X if ((image->columns == image_window.ximage->width) &&
X (image->rows == image_window.ximage->height))
X *image_geometry=(char *) NULL;
X else
X {
X *image_geometry=(char *) malloc(256);
X if (*image_geometry == (char *) NULL)
X Error("unable to transform X image",(char *) NULL);
X (void) sprintf(*image_geometry,"%dx%d\0",image_window.ximage->width,
X image_window.ximage->height);
X }
X /*
X Free up memory.
X */
X XDestroyWindow(display,info_window.id);
X XDestroyWindow(display,menu_window.id);
X XDestroyWindow(display,magnify_window.id);
X XDestroyImage(magnify_window.ximage);
X XDestroyWindow(display,image_window.id);
X XDestroyImage(image_window.ximage);
X (void) free((char *) image_window.name);
X if (resource_info->backdrop)
X XDestroyWindow(display,backdrop_window.id);
X XDestroyWindow(display,icon_window.id);
X if (icon_window.ximage != (XImage *) NULL)
X XDestroyImage(icon_window.ximage);
X XDestroyWindow(display,superclass_window.id);
X XFreeGC(display,graphic_context);
X XFree((char *) class_hint);
X XFree((char *) manager_hints);
X XFreeCursor(display,arrow_cursor);
X XFreeCursor(display,watch_cursor);
X XFreeCursor(display,magnify_window.cursor);
X XFreeFont(display,font_info);
X /*
X Discard pending events before freeing colormap.
X */
X while (XEventsQueued(display,QueuedAfterFlush) > 0)
X XNextEvent(display,&event);
X if (resource_info->map_type == (char *) NULL)
X if (colormap != XDefaultColormap(display,visual_info->screen))
X XFreeColormap(display,colormap);
X else
X if ((visual_info->class == GrayScale) ||
X (visual_info->class == PseudoColor))
X XFreeColors(display,colormap,pixel_info.pixels,(int) image->colors,0);
X if (pixel_info.pixels != (unsigned long *) NULL)
X (void) free((char *) pixel_info.pixels);
X XFree((char *) map_info);
X XFree((char *) visual_info);
X return(image);
}
X
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% X D i s p l a y I m a g e W i n d o w %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function XDisplayImageWindow displays an image in a X window.
%
% The format of the XDisplayImageWindow routine is:
%
% XDisplayImageWindow(display,image_window,x,y,width,height)
%
% A description of each parameter follows:
%
% o display: Specifies a connection to an X server; returned from
% XOpenDisplay.
%
% o image_window: Specifies a pointer to a XWindowInfo structure.
%
% o x: Specifies the x coordinate relative to the image window.
%
% o y: Specifies the y coordinate relative to the image window.
%
% o width: Specifies the width in pixels of the rectangular area to
% display.
%
% o height: Specifies the height in pixels of the rectangular area to
% display.
%
%
*/
static void XDisplayImageWindow(display,image_window,x,y,width,height)
Display
X *display;
X
XXWindowInfo
X *image_window;
X
register int
X x,
X y;
X
register unsigned int
X height,
X width;
{
X /*
X Check boundary conditions.
X */
X if ((x+(int) width) > (int) image_window->width)
X width=(unsigned int) ((int) image_window->width-x);
X if ((y+(int) height) > (int) image_window->height)
X height=(unsigned int) ((int) image_window->height-y);
X if (x < image_window->x)
X {
X XClearArea(display,image_window->id,x,y,
X (unsigned int) (image_window->x-x),(unsigned int) (y+(int) height),
X False);
X width-=(unsigned int) (image_window->x-x);
X x=image_window->x;
X }
X if (y < image_window->y)
X {
X XClearArea(display,image_window->id,x,y,width,
X (unsigned int) (image_window->y-y),False);
X height-=(unsigned int) (image_window->y-y);
X y=image_window->y;
X }
X if ((x+(int) width) > (image_window->x+image_window->ximage->width))
X {
X width=(unsigned int) (image_window->x+image_window->ximage->width);
X XClearArea(display,image_window->id,width,y,image_window->width-width,
X image_window->height,False);
X }
X if ((y+(int) height) > (image_window->y+image_window->ximage->height))
X {
X height=(unsigned int) (image_window->y+image_window->ximage->height);
X XClearArea(display,image_window->id,x,height,width,image_window->height-
X height,False);
X }
X /*
X Display image.
X */
X XPutImage(display,image_window->id,image_window->graphic_context,
X image_window->ximage,x-image_window->x,y-image_window->y,x,y,width,height);
}
X
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% X D i s p l a y R o o t I m a g e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function XDisplayRootImage displays an image in the root window.
%
% The format of the XDisplayRootImage routine is:
%
% XDisplayRootImage(display,resource_info,image)
%
% A description of each parameter follows:
%
% o display: Specifies a connection to an X server; returned from
% XOpenDisplay.
%
% o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
% o image: Specifies a pointer to a Image structure; returned from
% ReadImage.
%
%
*/
static void XDisplayRootImage(display,resource_info,image)
Display
X *display;
X
XXResourceInfo
X *resource_info;
X
Image
X *image;
{
X Atom
X property,
X type;
X
X Colormap
X colormap;
X
X int
X format,
X i;
X
X Pixmap
X pixmap;
X
X unsigned char
X *data;
X
X unsigned int
X height,
X number_children,
X width;
X
X unsigned long
X after,
X length;
X
X Window
X *children,
X parent,
X root,
X root_window;
X
X XColor
X color;
X
X XGCValues
X graphic_context_value;
X
X XPixelInfo
X pixel_info;
X
X XStandardColormap
X *map_info;
X
X XWindowInfo
X image_window;
X
X XVisualInfo
X *visual_info;
X
X /*
X Initialize visual info.
X */
X if ((resource_info->visual_type != (char *) NULL) ||
X (resource_info->map_type != (char *) NULL))
X visual_info=XBestVisualInfo(display,resource_info->visual_type,
X resource_info->map_type,&map_info);
X else
X {
X int
X number_visuals;
X
X XVisualInfo
X visual_template;
X
X /*
X Get the default visual.
X */
X visual_template.visualid=
X XVisualIDFromVisual(XDefaultVisual(display,XDefaultScreen(display)));
X visual_info=XGetVisualInfo(display,VisualIDMask,&visual_template,
X &number_visuals);
X }
X if (visual_info == (XVisualInfo *) NULL)
X Error("unable to get visual",resource_info->visual_type);
X if (visual_info->visual != XDefaultVisual(display,visual_info->screen))
X Error("visual must be server default",resource_info->visual_type);
X /*
X Determine if root window is virtual.
X */
X root_window=XRootWindow(display,visual_info->screen);
X property=XInternAtom(display,"__SWM_VROOT",False);
X XQueryTree(display,root_window,&root,&parent,&children,&number_children);
X for (i=0; i < number_children; i++)
X {
X (void) XGetWindowProperty(display,children[i],property,0L,1L,False,
X XA_WINDOW,&type,&format,&length,&after,&data);
X if ((format == 32) && (length == 1) && (after == 0))
X {
X /*
X Root window is a virtual root.
X */
X root_window=(*((Window *) data));
X break;
X }
X }
X if (children != (Window *) NULL)
X XFree((char *) children);
X /*
X If there are previous resources on the root window, destroy them.
X */
X property=XInternAtom(display,"_XSETROOT_ID",False);
X if (property == (Atom) NULL)
X Error("unable to create X property","_XSETROOT_ID");
X (void) XGetWindowProperty(display,root_window,property,0L,1L,True,
X AnyPropertyType,&type,&format,&length,&after,&data);
X if ((type == XA_PIXMAP) && (format == 32) && (length == 1) && (after == 0))
X {
X /*
X Free previous resources on the root window.
X */
X XKillClient(display,*((Pixmap *) data));
X XFree((char *) data);
X }
X /*
X Initialize colormap.
X */
X pixel_info.pixels=(unsigned long *) NULL;
X if (resource_info->map_type == (char *) NULL)
X {
X /*
X Create Standard Colormap.
X */
X map_info=XMakeStandardColormap(display,visual_info,resource_info,
X &pixel_info,image);
X colormap=map_info->colormap;
X }
X else
X {
X if (image->class == PseudoClass)
X {
X register int
X i;
X
X /*
X Initialize pixel array for images of type PseudoClass.
X */
X pixel_info.pixels=(unsigned long *)
X malloc((unsigned int) image->colors*sizeof(unsigned long));
X if (pixel_info.pixels == (unsigned long *) NULL)
X Error("unable to create colormap","memory allocation failed");
X for (i=0; i < image->colors; i++)
X pixel_info.pixels[i]=XStandardPixel(map_info,image->colormap[i],8);
X }
X /*
X Define background/border/foreground pixels.
X */
X colormap=map_info->colormap;
X XParseColor(display,colormap,resource_info->background_color,&color);
X pixel_info.background_pixel=XStandardPixel(map_info,color,16);
X XParseColor(display,colormap,resource_info->border_color,&color);
X pixel_info.border_pixel=XStandardPixel(map_info,color,16);
X XParseColor(display,colormap,resource_info->foreground_color,&color);
X pixel_info.foreground_pixel=XStandardPixel(map_info,color,16);
X }
X /*
X The colormap must be the default colormap.
X */
X if (colormap != XDefaultColormap(display,visual_info->screen))
X Error("unable to display X image on the root window","too many colors");
X /*
X Initialize image window attributes.
X */
X image_window.id=root_window;
X image_window.visual_info=visual_info;
X image_window.screen=visual_info->screen;
X image_window.depth=visual_info->depth;
X image_window.clip_geometry=(char *) NULL;
X image_window.map_info=map_info;
X image_window.pixel_info=(&pixel_info);
X image_window.x=0;
X image_window.y=0;
X image_window.width=image->columns;
X if (image_window.width > XDisplayWidth(display,visual_info->screen))
X image_window.width=XDisplayWidth(display,visual_info->screen);
X image_window.height=image->rows;
X if (image_window.height > XDisplayHeight(display,visual_info->screen))
X image_window.height=XDisplayHeight(display,visual_info->screen);
X image_window.border_width=resource_info->border_width;
X /*
X Graphic context superclass.
X */
X graphic_context_value.background=pixel_info.background_pixel;
X graphic_context_value.foreground=pixel_info.foreground_pixel;
X graphic_context_value.fill_style=FillSolid;
X graphic_context_value.function=GXcopy;
X graphic_context_value.plane_mask=AllPlanes;
X image_window.graphic_context=XCreateGC(display,image_window.id,
X GCBackground | GCFillStyle | GCForeground | GCFunction | GCPlaneMask,
X &graphic_context_value);
X if (image_window.graphic_context == (GC) NULL)
X Error("unable to create graphic context",(char *) NULL);
X /*
X Create the X image.
X */
X image_window.ximage=XMakeImage(display,resource_info,&image_window,image,
X image->columns,image->rows);
X if (image_window.ximage == (XImage *) NULL)
X Error("unable to create X image",(char *) NULL);
X /*
X Adjust image dimensions as specified by backdrop or geometry options.
X */
X width=image_window.width;
X height=image_window.height;
X if (resource_info->backdrop)
X {
X /*
X Center image on root window.
X */
X image_window.x=
X XDisplayWidth(display,visual_info->screen)/2-image->columns/2;
X image_window.y=
X XDisplayHeight(display,visual_info->screen)/2-image->rows/2;
X width=XDisplayWidth(display,visual_info->screen);
X height=XDisplayHeight(display,visual_info->screen);
X }
X if (resource_info->image_geometry != (char *) NULL)
X {
X char
X default_geometry[256];
X
X int
X flags,
X gravity;
X
X XSizeHints
X *size_hints;
X
X /*
X User specified geometry.
X */
X size_hints=XAllocSizeHints();
X if (size_hints == (XSizeHints *) NULL)
X Error("unable to display on root","memory allocation failed");
X size_hints->flags=(long int) NULL;
X (void) sprintf(default_geometry,"%dx%d\0",width,height);
X flags=XWMGeometry(display,visual_info->screen,
X resource_info->image_geometry,default_geometry,
X image_window.border_width,size_hints,&image_window.x,&image_window.y,
X (int *) &width,(int *) &height,&gravity);
X if (flags & (XValue | YValue))
X {
X width=XDisplayWidth(display,visual_info->screen);
X height=XDisplayHeight(display,visual_info->screen);
X }
X XFree((char *) size_hints);
X }
X /*
X Create the root pixmap.
X */
X pixmap=
X XCreatePixmap(display,image_window.id,width,height,image_window.depth);
X if (pixmap == (Pixmap) NULL)
X Error("unable to create X pixmap",(char *) NULL);
X /*
X Display pixmap on the root window.
X */
X if ((width > image_window.width) || (height > image_window.height))
X {
X /*
X Surround the image by pixels of the background color.
X */
X XSetForeground(display,image_window.graphic_context,
X pixel_info.background_pixel);
X XFillRectangle(display,pixmap,image_window.graphic_context,0,0,width,
X height);
X XSetForeground(display,image_window.graphic_context,
X pixel_info.foreground_pixel);
X }
X XPutImage(display,pixmap,image_window.graphic_context,image_window.ximage,
X 0,0,image_window.x,image_window.y,image_window.width,image_window.height);
X XSetWindowBackgroundPixmap(display,image_window.id,pixmap);
X XClearWindow(display,image_window.id);
X /*
X Free resources.
X */
X if (pixel_info.pixels != (unsigned long *) NULL)
X (void) free((char *) pixel_info.pixels);
X XFreePixmap(display,pixmap);
X XDestroyImage(image_window.ximage);
X XFreeGC(display,image_window.graphic_context);
X XFree((char *) visual_info);
X XFree((char *) map_info);
X /*
X Put property on root window and set close-down mode to RetainPermanent.
X */
X pixmap=XCreatePixmap(display,image_window.id,1,1,1);
X if (pixmap == (Pixmap) NULL)
X Error("unable to create X pixmap",(char *) NULL);
X XChangeProperty(display,image_window.id,property,XA_PIXMAP,32,PropModeReplace,
X (unsigned char *) &pixmap,1);
X XSetCloseDownMode(display,RetainPermanent);
}
X
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% X M a g n i f y I m a g e W i n d o w %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function XMagnifyImageWindow magnifies portions of the image as indicated
% by the pointer. The magnified portion is displayed in a separate window.
%
% The format of the XMagnifyImageWindow routine is:
%
% XMagnifyImageWindow(display,resource_info,info_window,image_window,
% magnify_window)
%
% A description of each parameter follows:
%
% o display: Specifies a connection to an X server; returned from
% XOpenDisplay.
%
% o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
% o info_window: Specifies a pointer to a XWindowInfo structure.
%
% o image_window: Specifies a pointer to a XWindowInfo structure.
%
% o magnify_window: Specifies a pointer to a XWindowInfo structure.
%
%
*/
static void XMagnifyImageWindow(display,resource_info,info_window,image_window,
SHAR_EOF
true || echo 'restore of ImageMagick/display.c failed'
fi
echo 'End of ImageMagick part 17'
echo 'File ImageMagick/display.c is continued in part 18'
echo 18 > _shar_seq_.tmp
exit 0
--
Dan Heller
O'Reilly && Associates Z-Code Software Comp-sources-x:
Senior Writer President comp-sources-x at uunet.uu.net
argv at ora.com argv at zipcode.com
More information about the Comp.sources.x
mailing list