cristy@dupont.com (05/24/91)
Submitted-by: cristy@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@uunet.uu.net argv@ora.com argv@zipcode.com