469N/A/*
469N/A * xmag - simple magnifying glass application
469N/A *
469N/A * $XConsortium: xmag.c,v 1.29 89/12/10 17:23:58 rws Exp $
469N/A *
469N/A * Copyright 1988 Massachusetts Institute of Technology
469N/A *
469N/A * Permission to use, copy, modify, and distribute this software and its
469N/A * documentation for any purpose and without fee is hereby granted, provided
469N/A * that the above copyright notice appear in all copies and that both that
469N/A * copyright notice and this permission notice appear in supporting
469N/A * documentation, and that the name of M.I.T. not be used in advertising or
469N/A * publicity pertaining to distribution of the software without specific,
469N/A * written prior permission. M.I.T. makes no representations about the
469N/A * suitability of this software for any purpose. It is provided "as is"
469N/A * without express or implied warranty.
469N/A *
469N/A * Author: Jim Fulton, MIT X Consortium
469N/A *
469N/A * Revision History:
469N/A * 11-15-90 MultiVis changes made by: Milind M. Pansare
469N/A * milind@Eng.Sun.COM
469N/A *
469N/A */
469N/A
1068N/A/*
1068N/A * Copyright (c) 1990, 2011, Oracle and/or its affiliates. All rights reserved.
1068N/A *
1068N/A * Permission is hereby granted, free of charge, to any person obtaining a
1068N/A * copy of this software and associated documentation files (the "Software"),
1068N/A * to deal in the Software without restriction, including without limitation
1068N/A * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1068N/A * and/or sell copies of the Software, and to permit persons to whom the
1068N/A * Software is furnished to do so, subject to the following conditions:
1068N/A *
1068N/A * The above copyright notice and this permission notice (including the next
1068N/A * paragraph) shall be included in all copies or substantial portions of the
1068N/A * Software.
1068N/A *
1068N/A * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1068N/A * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1068N/A * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1068N/A * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1068N/A * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1068N/A * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
1068N/A * DEALINGS IN THE SOFTWARE.
1068N/A */
1068N/A
1068N/A
469N/A#include <X11/Xos.h>
469N/A#include <X11/Xlib.h>
469N/A#include <X11/Xutil.h>
469N/A#include <X11/cursorfont.h>
469N/A#include <X11/Xatom.h>
469N/A#include <stdio.h>
1068N/A#include <stdlib.h>
1068N/A#ifdef ALLPLANES
1068N/A# include <X11/extensions/allplanes.h>
1068N/A#endif
469N/A#include "multivis.h"
469N/A
1233N/A#ifdef __SUNPRO_C
1233N/A/* prevent "Function has no return statement" error for shhh() */
1233N/A#pragma does_not_return(exit)
469N/A#endif
469N/A
469N/A#define DEFAULT_BORDER_SIZE 2
469N/A#define DEFAULT_CURSOR_SIZE 64
469N/A#define DEFAULT_MAGNIFICATION 5
469N/A#define DEFAULT_PIX_FONT "fixed"
469N/A
469N/Aint Argc; /* copy of argc */
469N/Achar **Argv; /* copy of argv */
469N/A
469N/Achar *ProgramName; /* name of program being executed */
469N/ADisplay *dpy = NULL; /* X server being used */
469N/Aint screen; /* screen being used */
469N/Aint pixmap_format; /* XYPixmap or ZPixmap */
469N/AColormap cmap; /* colormap to use for drawing */
469N/AVisual *visual; /* This is to fix the bug for TrueColor */
469N/Aint npixelvalues; /* number of pixel values */
469N/AWindow w, w1, mw; /* enlargement window */
469N/A /* w1 is TrueColor 24 bit */
469N/A /* mw is the window that is finally
469N/A mapped , w or w1 */
469N/AWindow root; /* root window of screen */
469N/AGC fillGC = (GC) NULL; /* for drawing enlargement */
469N/AGC fillGC1 = (GC) NULL; /* for drawing enlargement */
469N/AGC fGC = (GC) NULL; /* either fillGC or fillGC1 */
469N/ABool do_grab = False; /* grab server */
469N/Achar *pix_font = NULL; /* for displaying pixel value */
469N/A
469N/A/* start MultiVisual Fix */
469N/Aint num_vis;
469N/AXVisualInfo vinfo_template, *vlist, *def_vis;
469N/Aint def_vis_is_ok = 0; /* is def visual 24bit TrueColor */
469N/A
469N/Aint wd, ht; /* request width & height */
469N/AXVisualInfo vis; /* The TrueColor 24 bit one..
469N/A We'll use this for output */
469N/A
469N/AXImage *FinalImage; /* XImage corresponding to Img */
469N/A
469N/Aint multiVis=0; /* if (multiVis), MultiVisual kludge */
469N/Aint red_shift, blue_shift, green_shift, rgb_shift;
1233N/Astatic XImage *CreateImageFromImg(void);
469N/A#ifdef ALLPLANES
469N/Aint allplanes; /* Is the SUN_ASLLPLANES extension present ? */
469N/A#endif /* ALLPLANES */
469N/AAtom wm_delete_window;
469N/A
469N/A/* end MultiVisual Fix */
469N/A
1233N/Astatic void magnify (char *window_geometry, char *source_geometry,
1233N/A int magnification, char *border_color, int border_width,
1233N/A char *back_color);
1233N/Astatic void get_source (XSizeHints *shp);
1233N/Astatic void repaint_image (XImage *image, XEvent *eventp, int magnification,
1233N/A unsigned long back_pixel);
469N/A
1233N/Astatic Bool do_magnify (XSizeHints *shp, XSizeHints *whp, int magnification,
1233N/A unsigned long back_pixel);
469N/A
1233N/Astatic int IsMultiVis (int multivisFromMvLib);
1233N/Astatic void MapPixWindow (Window wind, int bot);
1233N/Astatic void DrawPixWindow (char *str);
1233N/Astatic void UnmapPixWindow (void);
1233N/Astatic int shhh(Display *dsp, XErrorEvent *err); /* quiet IO error handler */
1233N/A
1233N/Astatic void
1233N/AExit (int status)
469N/A{
469N/A if (dpy) {
469N/A XCloseDisplay (dpy);
469N/A dpy = NULL;
469N/A }
469N/A (void) exit (status);
469N/A}
469N/A
1233N/Astatic void
1233N/AUsage (void)
469N/A{
1233N/A static const char *help_message[] = {
469N/A"where options include:",
469N/A" -display displaystring X server to contact",
469N/A" -geometry geomstring size and location of enlargement",
469N/A" -source geomstring size and location of area to be enlarged",
469N/A" -mag magfactor integral amount by which area is enlarged",
469N/A" -bw pixels border width in pixels",
469N/A" -bd color border color",
469N/A" -bg colororpixelvalue background color or %pixel number",
469N/A" -fn fontname name of font for examining enlarged pixels",
469N/A" -z grab server during dynamics and XGetImage",
469N/A"",
469N/A"Options may be abbreviated to the shortest unambiguous prefix.",
469N/A"",
469N/ANULL
469N/A }, **cpp;
469N/A
469N/A fprintf (stderr, "usage:\n %s [-options ...]\n\n", ProgramName);
469N/A for (cpp = help_message; *cpp; cpp++) {
469N/A fprintf (stderr, "%s\n", *cpp);
469N/A }
469N/A Exit (1);
469N/A}
469N/A
469N/A
1233N/Aint
1233N/Amain (int argc, char **argv)
469N/A{
469N/A int i; /* iterator variable */
469N/A char *displayname = NULL; /* name of X server to contact */
469N/A char *source_geometry = NULL; /* size of square tracking pointer */
469N/A char *geometry = NULL; /* size and location of enlarged */
469N/A int magnification = 0; /* enlarged image will be m by m */
469N/A char *border_color = NULL; /* border color name */
469N/A char *back_color = NULL; /* background of enlargement */
469N/A int border_width = -1; /* border width in pixels */
469N/A
469N/A ProgramName = argv[0];
469N/A Argc = argc;
469N/A Argv = argv;
469N/A
469N/A for (i = 1; i < argc; i++) {
469N/A char *arg = argv[i];
469N/A
469N/A if (arg[0] == '-') { /* process command line switches */
469N/A switch (arg[1]) {
469N/A case 'd': /* -display displaystring */
469N/A if (++i >= argc) Usage ();
469N/A displayname = argv[i];
469N/A continue;
469N/A case 'g': /* -geometry geomstring */
469N/A if (++i >= argc) Usage ();
469N/A geometry = argv[i];
469N/A continue;
469N/A case 's': /* -source geomstring */
469N/A if (++i >= argc) Usage ();
469N/A source_geometry = argv[i];
469N/A continue;
469N/A case 'm': /* -mag magnification */
469N/A if (++i >= argc) Usage ();
469N/A magnification = atoi (argv[i]);
469N/A continue;
469N/A case 'b':
469N/A switch (arg[2]) {
469N/A case 'w': /* -bw pixels */
469N/A if (++i >= argc) Usage ();
469N/A border_width = atoi (argv[i]);
469N/A continue;
469N/A case 'd': /* -bd color */
469N/A if (++i >= argc) Usage ();
469N/A border_color = argv[i];
469N/A continue;
469N/A case 'g': /* -bg colororpixel*/
469N/A if (++i >= argc) Usage ();
469N/A back_color = argv[i];
469N/A continue;
469N/A } /* end switch */
469N/A Usage ();
469N/A /* NOTREACHED */
469N/A case 'z': /* -z */
469N/A do_grab = True;
469N/A continue;
469N/A case 'f': /* -font fontname */
469N/A if (++i >= argc) Usage ();
469N/A pix_font = argv[i];
469N/A continue;
469N/A default:
469N/A Usage ();
469N/A /* NOTREACHED */
469N/A } /* end switch */
469N/A } else { /* any command line parameters */
469N/A Usage ();
469N/A /* NOTREACHED */
469N/A } /* end if else */
469N/A } /* end for */
469N/A
469N/A dpy = XOpenDisplay (displayname);
469N/A if (!dpy) {
469N/A fprintf (stderr, "%s: unable to open display \"%s\".\n",
469N/A ProgramName, XDisplayName (displayname));
469N/A Exit (1);
469N/A }
469N/A /*
469N/A * set the fatal error handler to be an innocuous wimp that
469N/A * exits quietly
469N/A */
469N/A /*
469N/A XSetIOErrorHandler(shhh);
469N/A */
469N/A#ifdef ALLPLANES
469N/A {
469N/A int tmp;
469N/A allplanes = XAllPlanesQueryExtension(dpy, &tmp, &tmp);
469N/A }
469N/A#endif /* ALLPLANES */
469N/A
469N/A wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
469N/A
469N/A
469N/A /*
469N/A * get defaults (would be nice to use the resource manager instead)
469N/A */
469N/A
469N/A if (!pix_font) pix_font = XGetDefault (dpy, ProgramName, "font");
469N/A if (!pix_font) pix_font = XGetDefault (dpy, ProgramName, "Font");
469N/A
469N/A if (!geometry) geometry = XGetDefault (dpy, ProgramName, "geometry");
469N/A if (!geometry) geometry = XGetDefault (dpy, ProgramName, "Geometry");
469N/A
469N/A if (!source_geometry)
469N/A source_geometry = XGetDefault (dpy, ProgramName, "source");
469N/A if (!source_geometry)
469N/A source_geometry = XGetDefault (dpy, ProgramName, "Source");
469N/A
469N/A if (magnification < 1) {
469N/A char *tmp = XGetDefault (dpy, ProgramName, "magnification");
469N/A if (!tmp) tmp = XGetDefault (dpy, ProgramName, "Magnification");
469N/A
469N/A if (tmp) magnification = atoi (tmp);
469N/A }
469N/A
469N/A if (border_width < 0) {
469N/A char *tmp = XGetDefault (dpy, ProgramName, "borderWidth");
469N/A if (!tmp) tmp = XGetDefault (dpy, ProgramName, "BorderWidth");
469N/A
469N/A border_width = tmp ? atoi (tmp) : DEFAULT_BORDER_SIZE;
469N/A }
469N/A
469N/A if (!border_color)
469N/A border_color = XGetDefault (dpy, ProgramName, "borderColor");
469N/A if (!border_color)
469N/A border_color = XGetDefault (dpy, ProgramName, "BorderColor");
469N/A
469N/A if (!back_color)
469N/A back_color = XGetDefault (dpy, ProgramName, "background");
469N/A if (!back_color)
469N/A back_color = XGetDefault (dpy, ProgramName, "Background");
469N/A
469N/A /*
469N/A * set up globals
469N/A */
469N/A
469N/A screen = DefaultScreen (dpy);
469N/A cmap = DefaultColormap (dpy, screen);
469N/A visual = DefaultVisual(dpy,screen) ;
469N/A vinfo_template.visualid = XVisualIDFromVisual(visual) ;
469N/A vinfo_template.screen = screen;
469N/A if (((def_vis = XGetVisualInfo(dpy,VisualIDMask|VisualScreenMask,
469N/A &vinfo_template,&num_vis))
469N/A == NULL) || num_vis > 1)
469N/A Exit(1);
469N/A if ((def_vis->class == DirectColor) || (def_vis->class == TrueColor)) {
469N/A npixelvalues = (def_vis->red_mask | def_vis->green_mask |
469N/A def_vis->blue_mask) + 1 ;
469N/A/* start MultiVisual fix */
469N/A if (def_vis->class == TrueColor && def_vis->depth == 24) {
469N/A /* The default visual is TrueColor, 24 bit... */
469N/A def_vis_is_ok = 1;
469N/A }
469N/A/* end MultiVisual fix */
469N/A }
469N/A else
469N/A npixelvalues = DisplayCells (dpy, screen);
469N/A
469N/A/* start MultiVisual Fix */
469N/A vinfo_template.screen = screen; /* Who cares about the other screens ? */
469N/A if ((vlist=XGetVisualInfo(dpy,VisualScreenMask,&vinfo_template,&num_vis))
469N/A == NULL)
469N/A Exit(1); /* Duh ? */
469N/A
469N/A/* end MultiVisual Fix */
469N/A
469N/A root = RootWindow (dpy, screen);
469N/A pixmap_format = (DisplayPlanes (dpy, screen) > 1 ? ZPixmap : XYPixmap);
469N/A
469N/A /*
469N/A * do the work
469N/A */
469N/A
469N/A magnify (geometry, source_geometry, magnification,
469N/A border_color, border_width, back_color);
469N/A
469N/A Exit (0);
469N/A}
469N/A
469N/A
469N/A/*
469N/A * Do the setup for the magnification. Use the geometry, source_geometry,
469N/A * and magnification to figure out how big of an area to magnify, and by
469N/A * how much it should be enlarged according to the following relations:
469N/A *
469N/A * magnification = window.geometry.width / source_geometry.width
469N/A * magnification = window.geometry.height / source_geometry.height
469N/A *
469N/A * Thus, only two of the three values may be specified by the user. The
469N/A * following values are used to indicate that the default should be taken:
469N/A *
469N/A * Variable blank value default value
469N/A *
469N/A * magnification 0 5
469N/A * window NULL "320x320-0-0"
469N/A * source NULL "64x64"
469N/A *
469N/A * If a location is not specified for the source, a square centered on the
469N/A * pointer will be displayed that can be dragged around the screen.
469N/A */
469N/A
469N/Avoid
1233N/Amagnify(
1233N/A char *window_geometry, /* size and location of enlargement */
1233N/A char *source_geometry, /* size and location of area */
1233N/A int magnification, /* enlargement ratio */
1233N/A char *border_color, /* name of color to use for border */
1233N/A int border_width, /* width of border */
1233N/A char *back_color) /* color name or pixel value */
469N/A{
469N/A XTextProperty windowName, iconName;
469N/A XWMHints wmHints;
469N/A XClassHint classHints;
469N/A XSizeHints source_hints, window_hints; /* for sizes and locations */
469N/A int source_geom_mask, window_geom_mask; /* for XParseGeometry results */
469N/A int params; /* for which arguments present */
469N/A unsigned long border_pixel; /* pixel value for border */
469N/A int tmp; /* work variable */
469N/A XColor cdef; /* for parsing border color name */
469N/A unsigned long valuemask; /* for window attributes */
469N/A XSetWindowAttributes attr; /* for creating window */
469N/A XGCValues gcv; /* for creating GC */
469N/A unsigned long back_pixel; /* background of enlargement */
469N/A
469N/A bzero ((char *) &source_hints, sizeof source_hints);
469N/A bzero ((char *) &window_hints, sizeof window_hints);
469N/A source_geom_mask = window_geom_mask = 0;
469N/A
469N/A#define SizeValues (WidthValue | HeightValue)
469N/A#define valNothing 0
469N/A#define valMagnification 1
469N/A#define valWindow 2
469N/A#define valSource 4
469N/A#define valAll 7
469N/A
469N/A params = valNothing;
469N/A
469N/A if (magnification > 0) params |= valMagnification;
469N/A
469N/A if (window_geometry) {
469N/A window_geom_mask = XParseGeometry (window_geometry,
469N/A &window_hints.x, &window_hints.y,
469N/A (unsigned int *)&window_hints.width,
469N/A (unsigned int *)&window_hints.height);
469N/A tmp = (window_geom_mask & SizeValues);
469N/A if (tmp) {
469N/A if (tmp == SizeValues)
469N/A params |= valWindow;
469N/A else
469N/A window_geom_mask &= ~SizeValues;
469N/A }
469N/A }
469N/A
469N/A if (source_geometry) {
469N/A source_geom_mask = XParseGeometry (source_geometry,
469N/A &source_hints.x, &source_hints.y,
469N/A (unsigned int *)&source_hints.width,
469N/A (unsigned int *)&source_hints.height);
469N/A tmp = (source_geom_mask & SizeValues);
469N/A if (tmp) {
469N/A if (tmp == SizeValues)
469N/A params |= valSource;
469N/A else
469N/A source_geom_mask &= ~SizeValues;
469N/A }
469N/A }
469N/A
469N/A /*
469N/A * Check to make sure that user didn't give -geometry, -source, and -mag
469N/A */
469N/A
469N/A if (params == valAll) {
469N/A fprintf (stderr, "%s: magnifier size over specified, ignoring -mag\n",
469N/A ProgramName);
469N/A magnification = 0;
469N/A params &= ~valMagnification;
469N/A }
469N/A
469N/A /*
469N/A * Verify the input and compute the appropriate sizes
469N/A */
469N/A
469N/A if ((params & valMagnification) && magnification <= 0) {
469N/A fprintf (stderr, "%s: bad magnification %d.\n",
469N/A ProgramName, magnification);
469N/A Exit (1);
469N/A }
469N/A if ((params & valWindow) && (window_hints.width <= 0 ||
469N/A window_hints.height <= 0)) {
469N/A fprintf (stderr, "%s: bad window size %dx%d.\n",
469N/A ProgramName, window_hints.width, window_hints.height);
469N/A Exit (1);
469N/A }
469N/A if ((params & valSource) && (source_hints.width <= 0 ||
469N/A source_hints.height <= 0)) {
469N/A fprintf (stderr, "%s: bad source size %dx%d.\n",
469N/A ProgramName, source_hints.width, source_hints.height);
469N/A Exit (1);
469N/A }
469N/A
469N/A switch (params) {
469N/A case valMagnification:
469N/A source_hints.width = source_hints.height = DEFAULT_CURSOR_SIZE;
469N/A goto mag_and_cur;
469N/A
469N/A case valWindow:
469N/A magnification = DEFAULT_MAGNIFICATION;
469N/A /* fall through */
469N/A case valMagnification|valWindow:
469N/A source_hints.width = window_hints.width / magnification;
469N/A source_hints.height = window_hints.height / magnification;
469N/A break;
469N/A
469N/A case valNothing:
469N/A source_hints.width = source_hints.height = DEFAULT_CURSOR_SIZE;
469N/A /* fall through */
469N/A case valSource:
469N/A magnification = DEFAULT_MAGNIFICATION;
469N/A /* fall through */
469N/A case valMagnification|valSource:
469N/A mag_and_cur:
469N/A window_hints.width = source_hints.width * magnification;
469N/A window_hints.height = source_hints.height * magnification;
469N/A break;
469N/A
469N/A case valWindow|valSource:
469N/A magnification = window_hints.width / source_hints.width;
469N/A tmp = window_hints.height / source_hints.height;
469N/A if (tmp < magnification) magnification = tmp;
469N/A break;
469N/A }
469N/A
469N/A /*
469N/A * At this point, both hints structures contain the appropriate width
469N/A * and height fields. Now we need to do the placement calculations.
469N/A */
469N/A
469N/A if ((window_geom_mask & XValue) && (window_geom_mask & XNegative))
469N/A window_hints.x = DisplayWidth (dpy, screen) + window_hints.x -
469N/A window_hints.width - border_width * 2;
469N/A
469N/A if ((window_geom_mask & YValue) && (window_geom_mask & YNegative))
469N/A window_hints.y = DisplayHeight (dpy, screen) + window_hints.y -
469N/A window_hints.height - border_width * 2;
469N/A
469N/A if ((source_geom_mask & XValue) && (source_geom_mask & XNegative))
469N/A source_hints.x = DisplayWidth (dpy, screen) + source_hints.x -
469N/A source_hints.width;
469N/A
469N/A if ((source_geom_mask & YValue) && (source_geom_mask & YNegative))
469N/A source_hints.y = DisplayHeight (dpy, screen) + source_hints.y -
469N/A source_hints.height;
469N/A
469N/A /*
469N/A * Set the flags entries so that we know what we have
469N/A */
469N/A
469N/A source_hints.flags = 0;
469N/A source_hints.flags |= USSize;
469N/A if ((source_geom_mask & XValue) && (source_geom_mask & YValue))
469N/A source_hints.flags |= USPosition;
469N/A
469N/A window_hints.flags = 0;
469N/A window_hints.flags |= USSize;
469N/A if ((window_geom_mask & XValue) && (window_geom_mask & YValue))
469N/A window_hints.flags |= USPosition;
469N/A
469N/A if (border_color && XParseColor (dpy, cmap, border_color, &cdef) &&
469N/A XAllocColor (dpy, cmap, &cdef)) {
469N/A border_pixel = cdef.pixel;
469N/A } else {
469N/A border_pixel = BlackPixel (dpy, screen);
469N/A }
469N/A
469N/A window_hints.flags |= (PResizeInc | PBaseSize | PWinGravity);
469N/A window_hints.width_inc = window_hints.height_inc = magnification;
469N/A window_hints.base_width = window_hints.base_height = 0;
469N/A switch (window_geom_mask & (XNegative | YNegative)) {
469N/A case 0:
469N/A window_hints.win_gravity = NorthWestGravity;
469N/A break;
469N/A case XNegative:
469N/A window_hints.win_gravity = NorthEastGravity;
469N/A break;
469N/A case YNegative:
469N/A window_hints.win_gravity = SouthWestGravity;
469N/A break;
469N/A default:
469N/A window_hints.win_gravity = SouthEastGravity;
469N/A break;
469N/A }
469N/A
469N/A back_pixel = BlackPixel (dpy, screen);
469N/A if (back_color) {
469N/A XColor cdef;
469N/A
469N/A if (back_color[0] == '%') { /* pixel specifier */
1233N/A const char *fmt = "%lu";
469N/A register char *s = back_color + 1;
469N/A
469N/A if (!*s) Usage ();
469N/A if (*s == '0') {
469N/A s++;
469N/A fmt = "%lo";
469N/A }
469N/A if (*s == 'x' || *s == 'X') {
469N/A s++;
469N/A fmt = "%lx";
469N/A }
469N/A if (sscanf (s, fmt, &back_pixel) != 1) Usage ();
469N/A } else if (XParseColor (dpy, cmap, back_color, &cdef) &&
469N/A XAllocColor (dpy, cmap, &cdef)) {
469N/A back_pixel = cdef.pixel;
469N/A }
469N/A }
469N/A
469N/A /*
469N/A * Make the enlargment window, but don't map it
469N/A */
469N/A
469N/A attr.background_pixel = back_pixel;
469N/A attr.border_pixel = border_pixel;
469N/A attr.event_mask = (ExposureMask|ButtonPressMask|ButtonReleaseMask|KeyPressMask);
469N/A attr.cursor = XCreateFontCursor (dpy, XC_top_left_arrow);
469N/A valuemask = (CWBackPixel | CWBorderPixel | CWEventMask | CWCursor);
469N/A
469N/A/* start MultiVisual Fix */
469N/A/*
469N/A * If the worst has happened, and we have a mix of Visuals to
469N/A * work from, then we insist on a TrueColor 24 bit Visual.
469N/A *This makes life (a bit) simpler.
469N/A*/
469N/A
469N/A if ((num_vis) > 1 && (XMatchVisualInfo(dpy, screen, 24, TrueColor, &vis))) {
469N/A wd = source_hints.width;
469N/A ht = source_hints.height;
469N/A FinalImage = XCreateImage(dpy, vis.visual, vis.depth, ZPixmap, 0,
469N/A (char *)malloc(wd*ht*sizeof(unsigned long)),
469N/A wd, ht, 32, 0);
469N/A if (def_vis_is_ok) {
469N/A w1 = XCreateWindow(dpy, root,
469N/A window_hints.x, window_hints.y,
469N/A window_hints.width, window_hints.height,
469N/A border_width, 24,
469N/A InputOutput, def_vis->visual, valuemask, &attr);
469N/A }
469N/A else {
469N/A /* The default visual is not 24 bit True Color,
469N/A Create a colormap for this visual */
469N/A Colormap c = XCreateColormap(dpy, root, vis.visual, AllocNone);
469N/A attr.colormap = c;
469N/A valuemask |= CWColormap;
469N/A w1 = XCreateWindow(dpy, root,
469N/A window_hints.x, window_hints.y,
469N/A window_hints.width, window_hints.height,
469N/A border_width, 24,
469N/A InputOutput, vis.visual, valuemask, &attr);
469N/A }
469N/A
469N/A /* We assume that there's going to be a 24 bit TrueColor Visual
469N/A to display the Image we create. Also, that each of R,G,B
469N/A masks will be 8 bits. We now need to calculate the
469N/A R, G, B offsets & order in the pixel.
469N/A CAUTION: We also assume that the upper 8 bits of each of RGB in the
469N/A XColor are the significant 8 bits, and discard the lower
469N/A 8 bits */
469N/A if (mvOnes(vis.red_mask) != 8 ||
469N/A mvOnes(vis.blue_mask) != 8 ||
469N/A mvOnes(vis.green_mask) != 8) {
469N/A /* This visual is no good for us */
469N/A if (w1) {
469N/A XDestroyWindow(dpy, w1);
469N/A w1 = NULL;
469N/A }
469N/A }
469N/A else {
469N/A red_shift = mvShifts(vis.red_mask);
469N/A blue_shift = mvShifts(vis.blue_mask);
469N/A green_shift = mvShifts(vis.green_mask);
469N/A rgb_shift = 16-vis.bits_per_rgb;
469N/A }
469N/A }
469N/A
469N/A/* At this moment, create both windows.. later decide which one to map */
469N/A
469N/A/* end MultiVisual Fix */
469N/A valuemask = (CWBackPixel | CWBorderPixel | CWEventMask | CWCursor);
469N/A w = XCreateWindow (dpy, root,
469N/A window_hints.x, window_hints.y,
469N/A window_hints.width, window_hints.height,
469N/A border_width, DefaultDepth (dpy, screen),
469N/A CopyFromParent, CopyFromParent, valuemask, &attr);
469N/A
469N/A windowName.encoding = XA_STRING;
469N/A windowName.format = 8;
469N/A windowName.value = (unsigned char *) "Magnifying Glass";
469N/A windowName.nitems = strlen ((char *)(windowName.value));
469N/A iconName.encoding = XA_STRING;
469N/A iconName.format = 8;
469N/A iconName.value = (unsigned char *) "xmag";
469N/A iconName.nitems = strlen ((char *)(iconName.value));
469N/A wmHints.input = True;
469N/A wmHints.flags = InputHint;
469N/A classHints.res_name = NULL;
469N/A classHints.res_class = "Magnifier";
469N/A XSetWMProperties (dpy, w, &windowName, &iconName, Argv, Argc,
469N/A &window_hints, &wmHints, &classHints);
469N/A/* start MultiVisual Fix */
469N/A if (w1) {
469N/A XSetWMProperties (dpy, w1, &windowName, &iconName, Argv, Argc,
469N/A &window_hints, &wmHints, &classHints);
469N/A }
469N/A/* end MultiVisual Fix */
469N/A
469N/A /*
469N/A * Make up a dummy GC
469N/A */
469N/A gcv.function = GXcopy;
469N/A gcv.plane_mask = AllPlanes;
469N/A gcv.fill_style = FillSolid;
469N/A /* repaint_image fills in foreground */
469N/A
469N/A fillGC = XCreateGC (dpy, w, (GCFunction | GCPlaneMask | GCFillStyle),
469N/A &gcv);
469N/A/* start MultiVisual Fix */
469N/A if (w1)
469N/A fillGC1 = XCreateGC (dpy, w1, (GCFunction | GCPlaneMask | GCFillStyle),
469N/A &gcv);
469N/A/* end MultiVisual Fix */
469N/A
469N/A /*
469N/A * Do the work. If the user specified the location of the source,
469N/A * then just that one spot, otherwise do some dynamics.
469N/A */
469N/A
469N/A if (source_hints.flags & USPosition) {
469N/A if (do_grab) {
469N/A XGrabServer (dpy); /* ungrab is in do_magnify */
469N/A XSync (dpy, 0);
469N/A }
469N/A (void) do_magnify (&source_hints, &window_hints, magnification,
469N/A back_pixel);
469N/A } else {
469N/A do {
469N/A if (do_grab) {
469N/A XGrabServer (dpy); /* ungrab is in do_magnify */
469N/A }
469N/A XSync (dpy, 1);
469N/A get_source (&source_hints);
469N/A } while (do_magnify (&source_hints, &window_hints, magnification,
469N/A back_pixel));
469N/A }
469N/A
469N/A return;
469N/A}
469N/A
469N/A#define NITERATIONS 6
469N/A#define NPOINTS (1 + (NITERATIONS * 2 * 4)) /* 1 move, 2 inverts, 4 sides */
469N/A
1233N/Astatic void
1233N/Aget_source (XSizeHints *shp)
469N/A{
469N/A register int x, y;
469N/A int width = shp->width, height = shp->height;
469N/A int dw = DisplayWidth (dpy, screen), dh = DisplayHeight (dpy, screen);
469N/A Window root_window, child_window;
469N/A int root_x, root_y, win_x, win_y;
469N/A int xoff = width / 2, yoff = height / 2;
469N/A XPoint box[NPOINTS];
469N/A int lastx, lasty;
469N/A unsigned int mask;
469N/A Bool done;
469N/A static GC invGC = (GC) NULL; /* for drawing source region outline */
469N/A static Cursor invCursor;
469N/A
469N/A if (!invGC) { /* make it the first time */
469N/A XGCValues gcv;
469N/A
469N/A gcv.function = GXxor;
469N/A gcv.subwindow_mode = IncludeInferiors;
469N/A gcv.foreground = BlackPixel (dpy, screen);
469N/A
469N/A invGC = XCreateGC (dpy, root, (GCFunction | GCSubwindowMode |
469N/A GCForeground), &gcv);
469N/A if (!invGC) {
469N/A fprintf (stderr, "%s: unable to create invert GC.\n",
469N/A ProgramName);
469N/A Exit (1);
469N/A }
469N/A invCursor = XCreateFontCursor (dpy, XC_crosshair);
469N/A }
469N/A
469N/A
469N/A if (XGrabPointer (dpy, root, False, ButtonReleaseMask,
469N/A GrabModeAsync, GrabModeAsync, root,
469N/A invCursor, CurrentTime) != GrabSuccess) {
469N/A fprintf (stderr, "%s: unable to grab pointer\n", ProgramName);
469N/A Exit (1);
469N/A }
469N/A
469N/A /*
469N/A * Do the loop looking for a button press, drawing the image each time;
469N/A * since other clients may be running, make sure that the xor segments all
469N/A * get drawn at the same time.
469N/A */
469N/A
469N/A#define FAROFFSCREEN -9999
469N/A
469N/A for (done = False, lastx = lasty = FAROFFSCREEN; !done; ) {
469N/A if (XPending (dpy) != 0) {
469N/A XEvent event;
469N/A
469N/A XNextEvent (dpy, &event);
469N/A
469N/A switch (event.type) {
469N/A case ButtonRelease:
469N/A root_x = event.xbutton.x_root;
469N/A root_y = event.xbutton.y_root;
469N/A done = True;
469N/A break;
469N/A default:
1233N/A fprintf (stderr, "%s: warning unhandled event %u = 0x%x\n",
469N/A ProgramName, event.type, event.type);
469N/A continue;
469N/A } /* end switch */
469N/A } else if (!XQueryPointer (dpy, root, &root_window, &child_window,
469N/A &root_x, &root_y, &win_x, &win_y, &mask)) {
469N/A fprintf (stderr, "%s: unable to QueryPointer on root window.\n",
469N/A ProgramName);
469N/A Exit (1);
469N/A }
469N/A if (root_x != lastx || root_y != lasty) {
469N/A register int i;
469N/A
469N/A /* clip to screen */
469N/A
469N/A x = root_x - xoff;
469N/A y = root_y - yoff;
469N/A if (x < 0) x = 0;
469N/A if (y < 0) y = 0;
469N/A if (x + width > dw) x = dw - width;
469N/A if (y + height > dh) y = dh - height;
469N/A
469N/A /* fill in the outline box */
469N/A
469N/A for (i = 0; i < NPOINTS; i += 4) {
469N/A box[i].x = x; box[i].y = y; /* u.l. */
469N/A if (i == (NPOINTS - 1)) break;
469N/A box[i+1].x = x + width; box[i+1].y = y; /* u.r. */
469N/A box[i+2].x = box[i+1].x; box[i+2].y = y + height; /* l.r. */
469N/A box[i+3].x = x; box[i+3].y = box[i+2].y; /* l.l. */
469N/A }
469N/A lastx = root_x;
469N/A lasty = root_y;
469N/A }
469N/A
469N/A#ifdef ALLPLANES
469N/A if (allplanes) {
469N/A XAllPlanesDrawLines (dpy, root, box, NPOINTS, CoordModeOrigin);
469N/A }
469N/A else {
469N/A#endif /* ALLPLANES */
469N/A XDrawLines (dpy, root, invGC, box, NPOINTS, CoordModeOrigin);
469N/A#ifdef ALLPLANES
469N/A }
469N/A#endif /* ALLPLANES */
469N/A }
469N/A XUngrabPointer (dpy, CurrentTime);
469N/A XFlush (dpy);
469N/A
469N/A shp->x = x;
469N/A shp->y = y;
469N/A
469N/A return;
469N/A}
469N/A
1233N/Astatic Bool
1233N/Ado_magnify (
1233N/A XSizeHints *shp,
1233N/A XSizeHints *whp,
1233N/A int magnification,
1233N/A unsigned long back_pixel)
469N/A{
469N/A int x = shp->x, y = shp->y, width = shp->width, height = shp->height;
469N/A int dw = DisplayWidth (dpy, screen), dh = DisplayHeight (dpy, screen);
469N/A XImage *image;
469N/A Bool done, domore;
469N/A int i;
469N/A
469N/A /*
469N/A * Don't get bits that are off the edges of the screen
469N/A */
469N/A
469N/A if (x < 0) x = 0;
469N/A if (y < 0) y = 0;
469N/A if (x + width > dw) x = dw - width;
469N/A if (y + height > dh) y = dh - height;
469N/A
469N/A/* start MultiVisual Fix */
469N/A
469N/A if (num_vis > 1) { /* Fire, Walk with me */
469N/A /* Initialise the MultiVisual Routines */
469N/A mvInit(dpy, screen, vlist, num_vis);
469N/A /* Get a list of intersecting windows, with their visual details */
469N/A#ifdef SHAPE
469N/A mvWalkTree(root, 0, 0, x, y, width, height, False, NULL);
469N/A#else /* ! SHAPE */
469N/A mvWalkTree(root, 0, 0, x, y, width, height);
469N/A#endif /* SHAPE */
469N/A /* Check if we have a multiVis on our hands */
469N/A multiVis = IsMultiVis(mvIsMultiVis());
469N/A if (multiVis) {
469N/A /* Creat an Image where mvDoWindows.. will operate */
469N/A if (!mvCreatImg(wd,ht,x,y)) {
469N/A printf("mvCreatImg failed\n");
469N/A Exit(1);
469N/A }
469N/A mvDoWindowsFrontToBack();
469N/A /* Convert the map into an XImage */
469N/A image = CreateImageFromImg();
469N/A }
469N/A else {
469N/A image = XGetImage (dpy, root, x, y, width, height,
469N/A AllPlanes, pixmap_format);
469N/A if (multiVis == 2) /* Warn the user .... */
469N/A fprintf(stderr,
469N/A "%s: Warning -- source windows differ in VisualClass or ColorMap\n",
469N/A ProgramName);
469N/A }
469N/A
469N/A }
469N/A else if (num_vis == 1) {
469N/A image = XGetImage (dpy, root, x, y, width, height,
469N/A AllPlanes, pixmap_format);
469N/A }
469N/A else { /* Duh ? */
469N/A printf("Where are all the visuals ? \n");
469N/A Exit(1);
469N/A }
469N/A/* end MultiVisual Fix */
469N/A
469N/A if (do_grab) {
469N/A XUngrabServer (dpy);
469N/A XSync (dpy, 0);
469N/A }
469N/A
469N/Aif (!image) { /* clean up */
469N/A/* start MultiVisual fix */
469N/A/* Nothing to do, as we assume that the program will exit when we return */
469N/A/* end MultiVisual fix */
469N/A return (False);
469N/A}
469N/A
469N/A /*
469N/A * Map the window and do the work. Space means do another;
469N/A * Button1 press displays pixel value.
469N/A * q, Q, or ^C mean quit.
469N/A */
469N/A
469N/A domore = False; /* ButtonRelease will override */
469N/A
469N/A/* start MultiVisual Fix */
469N/A if (multiVis) {
469N/A if (!w1) { /* But we *insisted* on a TrueColor Window ! */
469N/A printf("Couldn't get a TrueColor 24 bit window...\n");
469N/A Exit(1);
469N/A }
469N/A mw = w1;
469N/A fGC=fillGC1;
469N/A }
469N/A else {
469N/A mw = w;
469N/A fGC=fillGC;
469N/A }
469N/A XMapWindow (dpy, mw);
469N/A (void)XSetWMProtocols(dpy, mw, &wm_delete_window, 1);
469N/A/* end MultiVisual Fix */
469N/A for (done = False; !done; ) {
469N/A XEvent event;
469N/A XButtonEvent *buttonevent;
469N/A XColor def;
469N/A int len,first;
469N/A char keybuffer[10];
469N/A
469N/A XNextEvent (dpy, &event);
469N/A switch (event.type) {
469N/A case ClientMessage:
469N/A if (event.xclient.data.l[0] == wm_delete_window) {
469N/A XCloseDisplay(dpy);
469N/A exit(0);
469N/A }
469N/A break;
469N/A case Expose:
469N/A repaint_image (image, &event, magnification, back_pixel);
469N/A break;
469N/A
469N/A case ButtonRelease:
469N/A buttonevent = (XButtonEvent *) &event;
469N/A if (buttonevent->button != Button1)
469N/A domore = done = True;
469N/A break;
469N/A
469N/A case ButtonPress:
469N/A buttonevent = (XButtonEvent *) &event;
469N/A if (buttonevent->button != Button1)
469N/A continue;
469N/A first = 1;
469N/A MapPixWindow (mw, (buttonevent->y/magnification < height/2));
469N/A while (1) { /* loop until button released */
469N/A Window rootW,childW;
469N/A int rx,ry,x,y,lx,ly;
469N/A unsigned int mask;
469N/A char str[64];
469N/A
469N/A if (XQueryPointer(dpy,mw,&rootW,&childW,&rx,&ry,&x,&y,&mask)) {
469N/A if (!(mask & Button1Mask)) break; /* button released */
469N/A
469N/A x /= magnification; y /= magnification;
469N/A
469N/A /* look for new pixel */
469N/A if ((first || x != lx || y != ly) &&
469N/A (x >= 0 && x < width && y >= 0 && y < height)) {
469N/A/* start MultiVisual Fix */
469N/A if (multiVis) {
469N/A XColor *col = mvFindColorInColormap(x, y);
469N/A sprintf (str,
469N/A "Pixel at (%d,%d): %3lx (%04x, %04x, %04x)",
469N/A x, y, col->pixel, col->red, col->green, col->blue);
469N/A }
469N/A/* end MultiVisual Fix */
469N/A else {
469N/A def.pixel = XGetPixel (image, x, y);
469N/A if (def.pixel >= 0 && def.pixel < npixelvalues) {
469N/A XQueryColor (dpy, cmap, &def);
469N/A sprintf (str,
469N/A "Pixel at (%d,%d): %3lx (%04x, %04x, %04x)",
469N/A x, y, def.pixel, def.red, def.green, def.blue);
469N/A } else {
469N/A def.red = def.green = def.blue = 0;
469N/A sprintf (str, "Pixel at (%d,%d): %3ld",
469N/A x, y, def.pixel);
469N/A }
469N/A }
469N/A DrawPixWindow (str);
469N/A first = 0; lx = x; ly = y;
469N/A }
469N/A } else
469N/A break;
469N/A }
469N/A UnmapPixWindow ();
469N/A break;
469N/A
469N/A case KeyPress:
469N/A len = XLookupString (&event.xkey, keybuffer, sizeof keybuffer,
469N/A NULL, NULL);
469N/A if (len == 1 && (keybuffer[0] == 'q' || keybuffer[0] == 'Q' ||
469N/A keybuffer[0] == '\003')) {
469N/A domore = False; /* q, Q, or ^C to quit */
469N/A done = True;
469N/A } else if (len == 1 && keybuffer[0] == ' ') {
469N/A domore = True; /* space to continue */
469N/A done = True;
469N/A } /* else ignore */
469N/A break;
469N/A }
469N/A }
469N/A XUnmapWindow (dpy, mw);
469N/A whp->flags |= (USPosition | USSize);
469N/A XSetWMNormalHints (dpy, mw, whp);
469N/A
469N/A /*
469N/A * free the image and return
469N/A */
469N/A
469N/A/* start MultiVisual Fix */
469N/A if (num_vis > 1) {
469N/A /* Reset the mvLib */
469N/A mvReset();
469N/A }
469N/A if (!multiVis) {
469N/A XDestroyImage (image);
469N/A }
469N/A/* end MultiVisual Fix */
469N/A return (domore);
469N/A}
469N/A
1233N/Astatic void
1233N/Arepaint_image (
1233N/A XImage *image,
1233N/A XEvent *eventp,
1233N/A int magnification,
1233N/A unsigned long back_pixel)
469N/A{
469N/A XExposeEvent *ev = &eventp->xexpose; /* to get repaint section */
469N/A int e_row, e_column; /* expose dimensions */
469N/A int r_x, r_y, r_width, r_height; /* filled rectangle dimensions */
469N/A XGCValues gcv; /* for doing filled rectangles */
469N/A int row, column; /* iterators */
469N/A int initialx, maxrow, maxcolumn; /* avoid recomputation */
469N/A unsigned long pixel; /* image pixel values */
469N/A unsigned long prev_pixel; /* last pixel set with XChangeGC */
469N/A
469N/A gcv.foreground = prev_pixel = back_pixel;
469N/A XChangeGC (dpy, fGC, GCForeground, &gcv);
469N/A
469N/A /*
469N/A * figure out where in the image we have to start and end
469N/A */
469N/A
469N/A e_row = ev->y / magnification;
469N/A e_column = ev->x / magnification;
469N/A initialx = e_column * magnification;
469N/A maxrow = e_row +
469N/A ((ev->y + ev->height + magnification - 1) / magnification) - 1;
469N/A maxcolumn = e_column +
469N/A ((ev->x + ev->width + magnification - 1) / magnification) - 1;
469N/A
469N/A /*
469N/A * clip to image size
469N/A */
469N/A
469N/A if (maxcolumn >= image->width) maxcolumn = image->width - 1;
469N/A if (maxrow >= image->height) maxrow = image->height - 1;
469N/A
469N/A /*
469N/A * Repaint the image; be somewhat clever by only drawing when the pixel
469N/A * changes or when we run out of lines.
469N/A */
469N/A
469N/A r_y = e_row * magnification; /* to start */
469N/A r_height = magnification; /* always doing just 1 line */
469N/A
469N/A /*
469N/A * iterate over scanlines (rows)
469N/A */
469N/A
469N/A for (row = e_row; row <= maxrow; row++) {
469N/A r_x = initialx; /* start at beginning */
469N/A r_width = 0; /* have done nothing so far */
469N/A
469N/A /*
469N/A * iterate over pixels in scanline (columns)
469N/A */
469N/A
469N/A for (column = e_column; column <= maxcolumn; column++) {
469N/A pixel = XGetPixel (image, column, row);
469N/A
469N/A /*
469N/A * If the current pixel is different from the previous pixel,
469N/A * then we need to set the drawing color and do the previous
469N/A * rectangle. We can also avoid extra calls to XChangeGC by
469N/A * keeping track of the last value we set (note that this may
469N/A * be different from gcv.foreground if the latter is the same
469N/A * as back_pixel). This is most useful when magnifying the
469N/A * background stipple pattern on monochrome displays.
469N/A */
469N/A if (pixel != gcv.foreground) {
469N/A /*
469N/A * We only need to draw the rectangle if it isn't background.
469N/A */
469N/A if (gcv.foreground != back_pixel && r_width > 0) {
469N/A if (gcv.foreground != prev_pixel) {
469N/A XChangeGC (dpy, fGC, GCForeground, &gcv);
469N/A prev_pixel = gcv.foreground;
469N/A }
469N/A XFillRectangle (dpy, mw, fGC,
469N/A r_x, r_y, r_width, r_height);
469N/A } /* end if */
469N/A r_x += r_width;
469N/A gcv.foreground = pixel;
469N/A r_width = 0;
469N/A } /* end if */
469N/A r_width += magnification;
469N/A } /* end for */
469N/A /*
469N/A * draw final rectangle on line
469N/A */
469N/A if (gcv.foreground != back_pixel && r_width > 0) {
469N/A if (gcv.foreground != prev_pixel) {
469N/A XChangeGC (dpy, fGC, GCForeground, &gcv);
469N/A prev_pixel = gcv.foreground;
469N/A }
469N/A XFillRectangle (dpy, mw, fGC, r_x, r_y, r_width, r_height);
469N/A } /* end if */
469N/A
469N/A r_y += magnification; /* advance to next scanline */
469N/A } /* end for */
469N/A
469N/A XFlush (dpy);
469N/A return;
469N/A}
469N/A
469N/A
469N/Astatic Window pixwind = None;
469N/Astatic XFontStruct *pixfinfo = NULL;
469N/AGC pixGC = (GC) NULL;
469N/A
1233N/Astatic void
1233N/AMapPixWindow (
1233N/A Window wind,
1233N/A int bot)
469N/A{
469N/A
469N/A /* creates a small window inside of 'wind', at the top or bottom,
469N/A suitable for displaying one line of text. Also loads in a font
469N/A if necessary; John Bradley, University of Pennsylvania */
469N/A
469N/A Window rootW;
469N/A int x,y;
469N/A unsigned int w,h,bwide,depth,thigh;
469N/A
469N/A XGetGeometry (dpy, wind, &rootW, &x, &y, &w, &h, &bwide, &depth);
469N/A
469N/A if (!pixfinfo) {
469N/A if (!pix_font) pix_font = DEFAULT_PIX_FONT;
469N/A pixfinfo = XLoadQueryFont (dpy, pix_font);
469N/A if (!pixfinfo) {
469N/A fprintf (stderr, "%s: unable to load font '%s'\n",
469N/A ProgramName, pix_font);
469N/A Exit (1);
469N/A }
469N/A }
469N/A
469N/A thigh = pixfinfo->ascent + pixfinfo->descent + 4;
469N/A y = (bot ? (h - thigh) : 0);
469N/A
469N/A if (pixwind == None) {
469N/A XGCValues gcv; /* for creating GC */
469N/A XSetWindowAttributes xsw;
469N/A XSetFont (dpy, fGC, pixfinfo->fid);
469N/A/* start MultiVisual fix */
469N/A /**** don't use CreateSimpleWindow when there is the possibility
469N/A of Multiple visuals ......
469N/A pixwind = XCreateSimpleWindow (dpy, wind, 0, y, w, thigh,
469N/A 0, None, BlackPixel (dpy, screen));
469N/A ******/
469N/A /*
469N/A * Note that all these fileds need to be set, as the
469N/A * default CopyFromParent values may cause BadMatch
469N/A * errors, if the depth of the parent is different.
469N/A */
469N/A xsw.background_pixel = BlackPixel(dpy, screen);
469N/A /* We don't care for the border pixel, but must set it
469N/A * anyways, to any value at all, for the above reasons.
469N/A */
469N/A xsw.border_pixel = BlackPixel(dpy, screen);
469N/A xsw.colormap = DefaultColormap(dpy, screen);
469N/A pixwind = XCreateWindow(dpy, wind, 0, y, w, thigh, 0,
469N/A DefaultDepth(dpy, screen), InputOutput,
469N/A DefaultVisual(dpy, screen),
469N/A CWBackPixel|CWColormap|CWBorderPixel, &xsw);
469N/A /* Make a GC ... */
469N/A gcv.function = GXcopy;
469N/A gcv.plane_mask = AllPlanes;
469N/A gcv.fill_style = FillSolid;
469N/A
469N/A pixGC = XCreateGC (dpy,pixwind,(GCFunction | GCPlaneMask | GCFillStyle),
469N/A &gcv);
469N/A/* End MultiVisual Fix */
469N/A } else {
469N/A XMoveWindow (dpy, pixwind, 0, y);
469N/A }
469N/A
469N/A XMapWindow (dpy, pixwind);
469N/A}
469N/A
469N/A
1233N/Astatic void
1233N/ADrawPixWindow (char *str)
469N/A{
469N/A XClearWindow (dpy, pixwind);
469N/A XSetForeground (dpy, pixGC, WhitePixel(dpy, screen));
469N/A XDrawString (dpy, pixwind, pixGC, 4, 2 + pixfinfo->ascent,
469N/A str, strlen (str));
469N/A}
469N/A
469N/A
1233N/Astatic void
1233N/AUnmapPixWindow(void)
469N/A{
469N/A XUnmapWindow (dpy, pixwind);
469N/A/* start MultiVisual Fix */
469N/A XDestroyWindow(dpy, pixwind);
469N/A pixwind = None;
469N/A XFreeGC(dpy, pixGC);
469N/A/* end MultiVisual Fix */
469N/A}
469N/A
469N/A/* start MultiVisual Fix */
469N/A
469N/A/*
469N/A * Create an XImage from the Img we have.
469N/A * Note that this routine has nothing to
469N/A * do with the MultiVisual Mechanism.
469N/A * It is a matter of policy that XMag chooses to
469N/A * do all output to a 24 bit true color visual.
469N/A * Selecting the best visual to display Img
469N/A * is a totally distinct problem. XMag
469N/A * solves it simplistically, by insisting on 24bit TrueColor.
469N/A * The TrueColor visual is assumed to provide a
469N/A * linear ramp in each primary.
469N/A*/
1233N/Astatic XImage *
1233N/ACreateImageFromImg(void)
469N/A{
469N/A XImage *image = FinalImage;
469N/A int x, y;
469N/A
469N/A for (y = 0; y < ht; y++) {
469N/A for (x=0; x < wd; x++) {
469N/A unsigned long pixel;
469N/A XColor *col = mvFindColorInColormap(x, y);
469N/A pixel = ((unsigned long)((unsigned short)(col->red) >> rgb_shift)
469N/A <<red_shift)
469N/A |((unsigned long)((unsigned short)(col->blue) >> rgb_shift)
469N/A <<blue_shift)
469N/A |((unsigned long)((unsigned short)(col->green) >> rgb_shift)
469N/A <<green_shift);
469N/A XPutPixel(image, x, y, pixel);
469N/A }
469N/A }
469N/A return image;
469N/A}
469N/A
1233N/Astatic int
1233N/Ashhh(
1233N/A Display *dsp,
1233N/A XErrorEvent *err)
469N/A{
469N/A /* be quiet */
469N/A exit(1);
469N/A}
469N/A
469N/A
469N/A/*
469N/A * Based on what mvLib returns, determine the best thing to do ...
469N/A*/
469N/Aint
1233N/AIsMultiVis(int multivisFromMvLib)
469N/A{
469N/A switch (multivisFromMvLib) {
469N/A case 0: /* No multiVis problems, do it the simple way */
469N/A return 0;
469N/A case 1: /* Definitely a multidepth problem */
469N/A return 1;
469N/A case 2: /* no depth problem , but colormap or visual class mismatch */
469N/A /* do a best effort... if 24bit window exists, use the mvLib
469N/A else do a simple GetImage, and warn user that displayed image
469N/A may not show true colors. */
469N/A if (w1) /* have TrueColor capability */
469N/A return 1;
469N/A /* else , best effort */
469N/A fprintf(stderr,
469N/A "%s: Warning - source window has different colormap or visual than root\n Image displayed using colormap and visual of root\n",
469N/A ProgramName);
469N/A return 0;
469N/A }
1233N/A return 0;
469N/A}
469N/A/* end MultiVisual Fix */