home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Source Code 1992 March
/
Source_Code_CD-ROM_Walnut_Creek_March_1992.iso
/
usenet
/
altsrcs
/
1
/
1391
/
XtoPS.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-12-28
|
40KB
|
1,368 lines
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% X X TTTTT OOO PPPP SSSSS %
% X X T O O P P S %
% X T O O PPPP SSS %
% X X T O O P S %
% X X T OOO P SSSSS %
% %
% %
% Import X11 image to a postscript format. %
% %
% %
% Software Design %
% John Cristy %
% January 1990 %
% %
% %
% Copyright 1990 E. I. Dupont de Nemours & Company %
% %
% Permission to use, copy, modify, distribute, and sell this software and %
% its documentation for any purpose is hereby granted without fee, %
% provided that the above copyright notice appear in all copies and that %
% both that copyright notice and this permission notice appear in %
% supporting documentation, and that the name of E. I. Dupont de Nemours %
% & Company not be used in advertising or publicity pertaining to %
% distribution of the software without specific, written prior %
% permission. E. I. Dupont de Nemours & Company makes no representations %
% about the suitability of this software for any purpose. It is provided %
% "as is" without express or implied warranty. %
% %
% E. I. Dupont de Nemours & Company disclaims all warranties with regard %
% to this software, including all implied warranties of merchantability %
% and fitness, in no event shall E. I. Dupont de Nemours & Company be %
% liable for any special, indirect or consequential damages or any %
% damages whatsoever resulting from loss of use, data or profits, whether %
% in an action of contract, negligence or other tortious action, arising %
% out of or in connection with the use or performance of this software. %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% The XtoPS program reads a X11 image from any visible window on a display
% and converts it to postscript format. The image can then be printed on a
% postscript compatible printer in either color or grayscale.
%
% The XtoPS program command syntax is:
%
% Usage: XToPS [options ...] file
%
% Where options include:
% +border include image borders in the output image
% -display name X server to contact
% +frame include window manager frame
% +grayscale print image as gray scale colors
% -id number select window with this id
% -name name select window with this name
% -root select root window
%
% Change '+' to '-' in any option above to reverse its effect.
% For example, -borders means do not include image borders).
%
% Specify 'file' as '-' for standard input or output.
%
%
*/
/*
Include declarations.
*/
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include "display.h"
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% C l i e n t W i n d o w %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function ClientWindow finds a window, at or below the specified window,
% which has a WM_STATE property. If such a window is found, it is returned,
% otherwise the argument window is returned.
%
% The format of the ClientWindow function is:
%
% child=ClientWindow(display,window)
%
% A description of each parameter follows:
%
% o child: ClientWindow returns a window, at or below the specified
% window, which has a WM_STATE property otherwise the argument window
% is returned.
%
% o display: Specifies a pointer to the Display structure; returned from
% XOpenDisplay.
%
% o window: Specifies the window to find a WM_STATE property.
%
%
*/
Window ClientWindow(display,window)
Display
*display;
Window
window;
{
Atom
state;
Atom
type;
int
format;
unsigned char
*data;
unsigned long
after,
number_items;
Window
child,
WindowByProperty();
state=XInternAtom(display,"WM_STATE",True);
if (!state)
return(window);
type=None;
XGetWindowProperty(display,window,state,0,0,False,AnyPropertyType,&type,
&format,&number_items,&after,&data);
if (type)
return(window);
child=WindowByProperty(display,window,state);
if (!child)
return(window);
return(child);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% I s T r u e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function IsTrue returns True if the boolean is "true", "on", "yes" or "1".
%
% The format of the IsTrue routine is:
%
% option=IsTrue(boolean)
%
% A description of each parameter follows:
%
% o option: either True or False depending on the boolean parameter.
%
% o boolean: Specifies a pointer to a character array.
%
%
*/
int IsTrue(boolean)
char
*boolean;
{
char
c,
*p;
if (!boolean)
return(False);
p=boolean;
for ( ; *p; p++)
{
/*
Convert to lower case.
*/
c=(*p);
if (isascii(c) && isupper(c))
*p=tolower(c);
}
if (strcmp(boolean,"true") == 0)
return(True);
if (strcmp(boolean,"on") == 0)
return(True);
if (strcmp(boolean,"yes") == 0)
return(True);
if (strcmp(boolean,"1") == 0)
return(True);
if (strcmp(boolean,"+") == 0)
return(True);
return(False);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% P r i n t I m a g e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function PrintImage translates a MIFF image to postscript for printing.
%
% The format of the PrintImage routine is:
%
% status=PrintImage(image,grayscale)
%
% A description of each parameter follows:
%
% o status: Function PrintImage return True if the image is printed.
% False is returned if the image file cannot be opened for printing.
%
% o image: The address of a structure of type Image; returned from
% ReadImage.
%
% o grayscale: An integer that specifies a grayscale image if non-zero.
%
%
*/
unsigned int PrintImage(image,grayscale)
Image
*image;
unsigned int
grayscale;
{
#define PointsPerInch 72.0
#define PageBorder 0.25
#define PageWidth 8.5
#define PageHeight 11.0
static char
*commands[]=
{
"%!",
"%",
"% Display a runlength-encoded grayscale or color image.",
"%",
"/buffer 512 string def",
"/byte 1 string def",
"/color_packet 3 string def",
"/gray_packet 1 string def",
"/expanded_packet 768 string def",
" ",
"/ReadColorPacket",
"{",
" %",
" % read a runlength-encoded color packet (length red green blue).",
" %",
" currentfile byte readhexstring pop 0 get",
" /count exch 1 add def",
" /count count 3 mul def",
" currentfile color_packet readhexstring pop",
" 0 3 count 1 sub",
" {",
" expanded_packet exch color_packet putinterval",
" } for pop",
" expanded_packet 0 count getinterval",
"} def",
" ",
"/DisplayColorImage",
"{",
" %",
" % display a runlength-encoded color image.",
" %",
" columns rows 8",
" [",
" columns 0 0",
" rows neg 0 rows",
" ]",
" { ReadColorPacket } false 3 colorimage",
"} def",
" ",
"/ReadGrayPacket",
"{",
" %",
" % read a runlength-encoded grayscale packet (length gray).",
" %",
" currentfile byte readhexstring pop 0 get",
" /count exch 1 add def",
" currentfile gray_packet readhexstring pop",
" 0 1 count 1 sub",
" {",
" expanded_packet exch gray_packet putinterval",
" } for pop",
" expanded_packet 0 count getinterval",
"} def",
" ",
"/DisplayGrayImage",
"{",
" %",
" % display a runlength-encoded grayscale image.",
" %",
" columns rows 8",
" [",
" columns 0 0",
" rows neg 0 rows",
" ]",
" { ReadGrayPacket } image",
"} def",
" ",
"/DisplayImage",
"{",
" %",
" % display a runlength-encoded grayscale or color image.",
" %",
" initgraphics",
" gsave",
" currentfile buffer readline pop",
" token { /degrees exch def } { } ifelse",
" degrees rotate",
" currentfile buffer readline pop",
" token { /x exch def } { } ifelse",
" token { /y exch def } { } ifelse",
" x y translate",
" currentfile buffer readline pop",
" token { /x exch def } { } ifelse",
" token { /y exch def } { } ifelse",
" x y scale",
" currentfile buffer readline pop",
" currentfile buffer readline pop",
" token { /columns exch def } { } ifelse",
" token { /rows exch def } { } ifelse",
" currentfile buffer readline pop",
" token { /grayscale exch def } { } ifelse",
" grayscale 0 gt { DisplayGrayImage } { DisplayColorImage } ifelse",
" grestore",
" showpage",
"} def",
" ",
"%",
"% DisplayImage parameters:",
"% degrees rotation.",
"% x & y translation.",
"% x & y scale.",
"% image name.",
"% image columns & rows.",
"% grayscale.",
"% hex grayscale or color runlength-encoded packets.",
"% ",
"DisplayImage",
NULL
};
char
**q;
double
delta_x,
delta_y,
image_height,
image_width,
max,
min,
rotate,
scale,
scale_x,
scale_y,
translate_x,
translate_y;
register RunlengthPacket
*p;
register int
i,
j;
register unsigned char
blue,
gray,
green,
red;
/*
Open output image file.
*/
if (*image->filename == '-')
image->file=stdout;
else
image->file=fopen(image->filename,"w");
if (image->file == (FILE *) NULL)
{
(void) fprintf(stderr,"Can't open %s for printing\n",image->filename);
return(False);
}
/*
Compute image rotation.
*/
if (((double) image->columns/(double) image->rows) > 1.0)
rotate=(-90.0);
else
rotate=0.0;
/*
Compute image scaling.
*/
image_width=(double) image->columns/PointsPerInch;
image_height=(double) image->rows/PointsPerInch;
/*
Check max page sizes
*/
max=image_width > image_height ? image_width : image_height;
if (max > (PageHeight-(2.0*PageBorder)))
{
scale=(PageHeight-(2.0*PageBorder))/max;
image_height*=scale;
image_width*=scale;
}
min=image_width > image_height ? image_height : image_width;
if (min > (PageWidth-(2.0*PageBorder)))
{
scale=(PageWidth-(2.0*PageBorder))/min;
image_width*=scale;
image_height*=scale;
}
scale_x=image_width*PointsPerInch;
scale_y=image_height*PointsPerInch;
translate_x=0.0;
translate_y=0.0;
if (rotate == 0.0)
{
delta_x=PageWidth-(image_width+(2.0*PageBorder));
delta_y=PageHeight-(image_height+(2.0*PageBorder));
if (delta_x >= 0.0)
translate_x=((delta_x/2.0+PageBorder)* PointsPerInch);
else
translate_x=PageBorder*PointsPerInch;
if (delta_y >= 0.0)
translate_y=((delta_y/2.0+PageBorder)* PointsPerInch);
else
translate_y=PageBorder*PointsPerInch;
}
else
{
delta_x=PageHeight-(image_width+(2.0*PageBorder));
delta_y=PageWidth-(image_height+(2.0*PageBorder));
if (delta_x >= 0.0)
translate_x=((delta_x/2.0+PageBorder-PageHeight)*PointsPerInch);
else
translate_x=(PageBorder-PageHeight)*PointsPerInch;
if (delta_y >= 0.0)
translate_y=((delta_y/2.0+PageBorder)*PointsPerInch);
else
translate_y=PageBorder*PointsPerInch;
}
/*
Output postscript commands.
*/
for (q=commands; *q; q++)
(void) fprintf(image->file,"%s\n",*q);
/*
Output image data.
*/
(void) fprintf(image->file,"%f\n%f %f\n%f %f\n%s\n%d %d\n%d\n",rotate,
translate_x,translate_y,scale_x,scale_y,image->filename,image->columns,
image->rows,grayscale);
p=image->pixels;
j=0;
for (i=0; i < image->packets; i++)
{
j++;
if (grayscale)
{
gray=Intensity(*p);
(void) fprintf(image->file,"%02x%02x ",p->length,gray);
if ((j % 6) == 0)
(void) fprintf(image->file,"\n");
}
else
{
red=p->red;
green=p->green;
blue=p->blue;
(void) fprintf(image->file,"%02x%02x%02x%02x ",p->length,red,green,
blue);
if ((j % 3) == 0)
(void) fprintf(image->file,"\n");
}
p++;
}
(void) fprintf(image->file,"\n\n");
if (image->file != stdin)
(void) fclose(image->file);
return(True);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% R e a d C o l o r m a p %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function ReadColormap returns the colormap of the image and the
% number of colors in the colormap.
%
% The format of the ReadColormap function is:
%
% number_colors=ReadColormap(display,window_attributes,colors)
%
% A description of each parameter follows:
%
% o number_colors: ReadColormap returns the number of colors in the
% colormap.
%
% o display: Specifies a pointer to the Display structure; returned from
% XOpenDisplay.
%
% o window_attributes: Specifies a pointer to the window attributes
% structure; returned from XGetWindowAttributes.
%
% o colors: Specifies a an array of XColor structures. The colormap
% red, green, and blue are returned.
%
%
*/
int ReadColormap(display,window_attributes,colors)
Display
*display;
XWindowAttributes
*window_attributes;
XColor
**colors;
{
int
number_colors;
register int
i;
if (!window_attributes->colormap)
return(0);
if (window_attributes->visual->class == TrueColor)
return(0);
number_colors=window_attributes->visual->map_entries;
*colors=(XColor *) malloc((unsigned) (number_colors*sizeof(XColor)));
if (*colors == (XColor *) NULL)
{
(void) fprintf(stderr,"Can't continue, not enough memory.\n");
exit(1);
}
for (i=0; i < number_colors; i++)
if (window_attributes->visual->class != DirectColor)
for (i=0; i < number_colors; i++)
{
(*colors)[i].pixel=i;
(*colors)[i].pad=0;
}
else
{
unsigned long
blue,
blue_bit,
green,
green_bit,
red,
red_bit;
red=0;
green=0;
blue=0;
red_bit=window_attributes->visual->red_mask &
(~(window_attributes->visual->red_mask)+1);
green_bit=window_attributes->visual->green_mask &
(~(window_attributes->visual->green_mask)+1);
blue_bit=window_attributes->visual->blue_mask &
(~(window_attributes->visual->blue_mask)+1);
for (i=0; i < number_colors; i++)
{
(*colors)[i].pixel=red | green | blue;
(*colors)[i].pad=0;
red+=red_bit;
if (red > window_attributes->visual->red_mask)
red=0;
green+=green_bit;
if (green > window_attributes->visual->green_mask)
green=0;
blue+=blue_bit;
if (blue > window_attributes->visual->blue_mask)
blue=0;
}
}
XQueryColors(display,window_attributes->colormap,*colors,number_colors);
return(number_colors);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% R e a d I m a g e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Procedure ReadImage reads an image from an X window.
%
% The format of the ReadImage routine is:
%
% ReadImage(display,screen,window,borders,image)
%
% A description of each parameter follows:
%
% o display: Specifies a pointer to the Display structure; returned from
% XOpenDisplay.
%
% o screen: Specifies the screen id of the root window.
%
% o window: Specifies the window id where the image resides.
%
% o borders: Specifies whether borders pixels are to be saved with
% the image.
%
% o image: specifies a pointer to the Image structure.
%
%
*/
static void ReadImage(display,screen,window,borders,image)
Display
*display;
int
screen;
Window
window;
unsigned int
borders;
Image
*image;
{
int
display_width,
display_height,
x,
y;
register int
i;
register RunlengthPacket
*p;
register unsigned int
pixel;
Window
child;
XColor
*colors;
XImage
*ximage;
XWindowAttributes
window_attributes;
/*
Inform the user not to alter the screen.
*/
XBell(display,0);
/*
Get the attributes of the window being dumped.
*/
if(!XGetWindowAttributes(display,window,&window_attributes))
{
(void) fprintf(stderr,
"Can't continue, unable to get target window attributes.\n");
exit(1);
}
XTranslateCoordinates(display,window,XRootWindow(display,screen),0,0,&x,&y,
&child);
window_attributes.x=x;
window_attributes.y=y;
image->columns=window_attributes.width;
image->rows=window_attributes.height;
if (borders)
{
x-=window_attributes.border_width;
y-=window_attributes.border_width;
image->columns+=2*window_attributes.border_width;
image->rows+=2*window_attributes.border_width;
}
/*
clip to window
*/
if (x < 0)
{
image->columns+=x;
x=0;
}
if (y < 0)
{
image->rows+=y;
y=0;
}
display_width=DisplayWidth(display,screen);
display_height=DisplayHeight(display,screen);
if ((x+image->columns) > display_width)
image->columns=display_width-x;
if ((y+image->rows) > display_height)
image->rows=display_height-y;
/*
Get image from window with XGetImage.
*/
x-=window_attributes.x;
y-=window_attributes.y;
ximage=XGetImage(display,window,x,y,image->columns,image->rows,AllPlanes,
ZPixmap);
if (!ximage)
{
(void) fprintf(stderr,
"Can't continue, unable to get image at %dx%d+%d+%d\n",image->columns,
image->rows,x,y);
exit(1);
}
image->colors=ReadColormap(display,&window_attributes,&colors);
XBell(display,0);
XBell(display,0);
XFlush(display);
/*
Convert image to MIFF format.
*/
image->comments=(char *) NULL;
image->class=(ximage->depth <= 16 ? PseudoClass : DirectClass);
image->compression=RunlengthEncodedCompression;
image->scene=0;
image->packets=image->columns*image->rows;
image->pixels=(RunlengthPacket *)
malloc((unsigned) (image->packets*sizeof(RunlengthPacket)));
if (image->pixels == (RunlengthPacket *) NULL)
{
(void) fprintf(stderr,"Can't image to postscript, not enough memory.\n");
exit(1);
}
p=image->pixels;
if (image->class == PseudoClass)
{
/*
Image is pseudo-color.
*/
image->colormap=(ColorPacket *)
malloc((unsigned) (image->colors*sizeof(ColorPacket)));
if (image->colormap == (ColorPacket *) NULL)
{
(void) fprintf(stderr,"Can't continue, not enough memory.\n");
exit(1);
}
for (i=0; i < image->colors; i++)
{
image->colormap[i].red=colors[i].red >> 8;
image->colormap[i].green=colors[i].green >> 8;
image->colormap[i].blue=colors[i].blue >> 8;
}
for (y=0; y < image->rows; y++)
{
for (x=0; x < image->columns; x++)
{
pixel=XGetPixel(ximage,x,y);
p->red=(unsigned char) (colors[pixel].red >> 8);
p->green=(unsigned char) (colors[pixel].green >> 8);
p->blue=(unsigned char) (colors[pixel].blue >> 8);
p->index=(short unsigned int) pixel;
p->length=0;
p++;
}
}
}
else
{
register unsigned long
color,
index;
unsigned long
blue_mask,
blue_shift,
green_mask,
green_shift,
red_mask,
red_shift;
/*
Determine shift and mask for red, green, and blue.
*/
red_mask=window_attributes.visual->red_mask;
red_shift=0;
while (!(red_mask & 0x01))
{
red_mask>>=1;
red_shift++;
}
green_mask=window_attributes.visual->green_mask;
green_shift=0;
while (!(green_mask & 0x01))
{
green_mask>>=1;
green_shift++;
}
blue_mask=window_attributes.visual->blue_mask;
blue_shift=0;
while (!(blue_mask & 0x01))
{
blue_mask>>=1;
blue_shift++;
}
/*
Convert DirectColor or TrueColor image to DirectClass.
*/
if ((image->colors > 0) &&
(window_attributes.visual->class == DirectColor))
for (y=0; y < image->rows; y++)
{
for (x=0; x < image->columns; x++)
{
pixel=XGetPixel(ximage,x,y);
index=(pixel >> red_shift) & red_mask;
p->red=(unsigned char) (colors[index].red >> 8);
index=(pixel >> green_shift) & green_mask;
p->green=(unsigned char) (colors[index].green >> 8);
index=(pixel >> blue_shift) & blue_mask;
p->blue=(unsigned char) (colors[index].blue >> 8);
p->index=0;
p->length=0;
p++;
}
}
else
for (y=0; y < image->rows; y++)
{
for (x=0; x < image->columns; x++)
{
pixel=XGetPixel(ximage,x,y);
color=(pixel >> red_shift) & red_mask;
p->red=(unsigned char)
((((unsigned long) color*65535)/red_mask) >> 8);
color=(pixel >> green_shift) & green_mask;
p->green=(unsigned char)
((((unsigned long) color*65535)/green_mask) >> 8);
color=(pixel >> blue_shift) & blue_mask;
p->blue=(unsigned char)
((((unsigned long) color*65535)/blue_mask) >> 8);
p->index=0;
p->length=0;
p++;
}
}
}
/*
Free image and colormap.
*/
if (image->colors > 0)
free((char *) colors);
XDestroyImage(ximage);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% S e l e c t W i n d o w %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function SelectWindow allows a user to select a window using the mouse.
%
% The format of the SelectWindow function is:
%
% window=SelectWindow(display,screen)
%
% A description of each parameter follows:
%
% o window: SelectWindow returns the window id.
%
% o display: Specifies a pointer to the Display structure; returned from
% XOpenDisplay.
%
% o screen: Specifies the screen id of the root window.
%
%
*/
Window SelectWindow(display,screen)
Display
*display;
int
screen;
{
Cursor
cursor;
int
status;
unsigned int
presses;
Window
target_window;
XEvent
event;
/*
Make the target cursor.
*/
cursor=XCreateFontCursor(display,XC_crosshair);
/*
Grab the pointer using target cursor.
*/
status=XGrabPointer(display,XRootWindow(display,screen),False,
ButtonPressMask | ButtonReleaseMask,GrabModeSync,GrabModeAsync,
XRootWindow(display,screen),cursor,CurrentTime);
if (status != GrabSuccess)
{
(void) fprintf(stderr,"Can't continue, cannot grab the mouse.\n");
exit(1);
}
/*
Select a window.
*/
target_window=None;
presses=0;
while ((target_window == None) || (presses != 0))
{
/*
Allow another event.
*/
XAllowEvents(display,SyncPointer,CurrentTime);
XWindowEvent(display,XRootWindow(display,screen),ButtonPressMask |
ButtonReleaseMask,&event);
switch (event.type)
{
case ButtonPress:
{
if (target_window == None)
{
target_window=event.xbutton.subwindow;
if (target_window == None)
target_window=XRootWindow(display,screen);
}
presses++;
break;
}
case ButtonRelease:
{
if (presses > 0)
presses--;
break;
}
default:
break;
}
}
XUngrabPointer(display,CurrentTime);
return(target_window);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% U s a g e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Procedure Usage displays the program usage;
%
% The format of the Usage routine is:
%
% Usage(program_name,message)
%
% A description of each parameter follows:
%
% program_name: Specifies the name of this program.
%
% message: Specifies a specific message to display to the user.
%
*/
void Usage(program_name,message)
char
*message,
*program_name;
{
char
**p;
static char
*options[]=
{
"+border include image borders in the output image",
"-display name X server to contact",
"+frame include window manager frame",
"+grayscale print image as gray scale colors",
"-id number select window with this id",
"-name name select window with this name",
"-root select root window",
NULL
};
if (message)
(void) fprintf(stderr,"Can't continue, %s\n\n",message);
(void) fprintf(stderr,"Usage: %s [options ...] file\n",program_name);
(void) fprintf(stderr,"\nWhere options include:\n");
for (p=options; *p; p++)
(void) fprintf(stderr," %s\n",*p);
(void) fprintf(stderr,
"\nChange '+' to '-' in any option above to reverse its effect.\n");
(void) fprintf(stderr,
"For example, -borders means do not include image borders.\n");
(void) fprintf(stderr,"\nSpecify 'file' as '-' for standard output.\n");
exit(1);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% W i n d o w B y N a m e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function WindowByName locates a window with a given name on a display.
% If no window with the given name is found, 0 is returned. If more than
% one window has the given name, the first one is returned. Only root and
% its children are searched.
%
% The format of the WindowByName function is:
%
% window=WindowByName(display,root,name)
%
%
% A description of each parameter follows:
%
% o window: WindowByName returns the window id.
%
% o display: Specifies a pointer to the Display structure; returned from
% XOpenDisplay.
%
% o root: Specifies a pointer to a window.
%
% o name: Specifies the name of the window to locate.
%
%
*/
Window WindowByName(display,root,name)
Display
*display;
Window
root;
char
*name;
{
char
*window_name;
register int
i;
unsigned int
number_children;
Window
*children,
child,
window;
if (XFetchName(display,root,&window_name) && !strcmp(window_name,name))
return(root);
if (!XQueryTree(display,root,&child,&child,&children,&number_children))
return(0);
window=0;
for (i=0; i < number_children; i++)
{
/*
Search each child and their children.
*/
window=WindowByName(display,children[i],name);
if (window)
break;
}
if (children)
XFree((char *) children);
return(window);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% W i n d o w B y P r o p e r y %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function WindowByProperty locates a child window with a given property.
% If no window with the given name is found, 0 is returned. If more than
% one window has the given property, the first one is returned. Only the
% window specified and its subwindows are searched.
%
% The format of the WindowByProperty function is:
%
% child=WindowByName(display,window,property)
%
%
% A description of each parameter follows:
%
% o child: WindowByProperty returns the window id with the specified
% property. If no windows are found, WindowByProperty returns 0.
%
% o display: Specifies a pointer to the Display structure; returned from
% XOpenDisplay.
%
% o property: Specifies the property of the window to locate.
%
%
*/
Window WindowByProperty(display,window,property)
Display
*display;
Window
window;
Atom
property;
{
Atom
type;
int
format;
unsigned char
*data;
unsigned int
i,
number_children;
unsigned long
after,
number_items;
Window
*children,
child,
parent,
root;
if (!XQueryTree(display,window,&root,&parent,&children,&number_children))
return((Window) NULL);
type=None;
child=(Window) NULL;
for (i=0; (i < number_children) && !child; i++)
{
XGetWindowProperty(display,children[i],property,0,0,False,AnyPropertyType,
&type,&format,&number_items,&after,&data);
if (type)
child=children[i];
}
for (i = 0; (i < number_children) && !child; i++)
child=WindowByProperty(display,children[i],property);
if (children)
XFree((char *) children);
return(child);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% M a i n %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
*/
main(argc,argv)
int
argc;
char
*argv[];
{
char
*option,
*program_name,
*server_name;
Display
*display;
Image
*image;
int
borders,
frame,
i,
screen;
unsigned int
grayscale,
PrintImage();
Window
target_window;
/*
Connect to X server.
*/
program_name=argv[0];
server_name=(char *) NULL;
for (i=1; i < argc; i++)
{
/*
Check command line for server name.
*/
option=argv[i];
if ((strlen(option) > 1) && ((*option == '-') || (*option == '+')))
if (strncmp("dis",option+1,3) == 0)
{
/*
User specified server name.
*/
i++;
if (i == argc)
Usage(program_name,"missing server name on -display");
server_name=argv[i];
break;
}
}
display=XOpenDisplay(server_name);
if (display == (Display *) NULL)
{
(void) fprintf(stderr,"Can't continue, unable to connect to %s.\n",
XDisplayName(server_name));
exit(1);
}
screen=XDefaultScreen(display);
/*
Get X defaults.
*/
option=XGetDefault(display,program_name,"borders");
borders=IsTrue(option);
option=XGetDefault(display,program_name,"frame");
frame=IsTrue(option);
option=XGetDefault(display,program_name,"grayscale");
grayscale=IsTrue(option);
/*
Check command syntax.
*/
target_window=(Window) NULL;
for (i=1; i < argc-1; i++)
{
option=argv[i];
if ((strlen(option) > 1) && ((*option == '-') || (*option == '+')))
switch(*(option+1))
{
case 'b':
{
borders=(*option == '+');
break;
}
case 'h':
{
Usage(program_name,(char *) NULL);
break;
}
case 'f':
{
frame=(*option == '+');
break;
}
case 'g':
{
grayscale=(*option == '+');
break;
}
case 'i':
{
i++;
if (i == argc)
Usage(program_name,"missing id on -id");
option=argv[i];
target_window=(Window) strtol(option,(char **) NULL,0);
break;
}
case 'n':
{
i++;
if (i == argc)
Usage(program_name,"missing name on -name");
option=argv[i];
target_window=
WindowByName(display,XRootWindow(display,screen),option);
if (target_window == (Window) NULL)
(void) fprintf(stderr,"No window with name %s exists!\n",option);
break;
}
case 'r':
{
target_window=XRootWindow(display,screen);
break;
}
default:
Usage(program_name,(char *) NULL);
}
}
if (argc == 1)
Usage(program_name,(char *) NULL);
if (!target_window)
target_window=SelectWindow(display,screen);
if (!frame)
if (target_window != XRootWindow(display,screen))
target_window=ClientWindow(display,target_window);
image=(Image *) malloc(sizeof(Image));
(void) strcpy(image->filename,argv[argc-1]);
ReadImage(display,screen,target_window,(unsigned int) borders,image);
(void) fprintf(stderr,"%s %dx%d\n",image->filename,image->columns,
image->rows);
(void) PrintImage(image,grayscale);
return(True);
}