1
/* $Xorg: xmag.c,v 1.4 2001/02/09 02:05:55 xorgcvs Exp $ */
4
Copyright 1991, 1998 The Open Group
6
Permission to use, copy, modify, distribute, and sell this software and its
7
documentation for any purpose is hereby granted without fee, provided that
8
the above copyright notice appear in all copies and that both that
9
copyright notice and this permission notice appear in supporting
12
The above copyright notice and this permission notice shall be included
13
in all copies or substantial portions of the Software.
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
19
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21
OTHER DEALINGS IN THE SOFTWARE.
23
Except as contained in this notice, the name of The Open Group shall
24
not be used in advertising or otherwise to promote the sale, use or
25
other dealings in this Software without prior written authorization
29
/* $XFree86: xc/programs/xmag/xmag.c,v 1.11 2003/01/19 04:44:45 paulo Exp $ */
32
#include <stdlib.h> /* for exit() and abs() */
35
#include <X11/Intrinsic.h>
36
#include <X11/StringDefs.h>
37
#include <X11/Xaw/Paned.h>
38
#include <X11/Xaw/Command.h>
39
#include <X11/Xaw/Label.h>
40
#include <X11/Shell.h>
41
#include <X11/cursorfont.h>
42
#include <X11/Xmu/Error.h>
51
#define min(a, b) ((a) < (b) ? (a) : (b))
56
/* highlight interval */
60
typedef enum { drag, resize, done } hlMode;
62
/* highlight data structure */
67
XWindowAttributes win_info;
69
Position homeX, homeY, x, y;
70
Dimension width, height;
71
Widget scaleShell, scaleInstance, pixShell, pixLabel, cmapWinList [2];
74
static XtIntervalId hlId;
78
/* global variables */
79
static XtAppContext app;
80
static Cursor ulAngle, urAngle, lrAngle, llAngle;
84
static XGCValues selectGCV;
85
static Widget toplevel, root;
86
static Atom wm_delete_window;
87
static int numXmags = 0;
88
static int srcStat, srcX, srcY;
89
static unsigned int srcWidth, srcHeight;
91
/* forward declarations */
93
#if NeedFunctionPrototypes
95
static int Error(Display *, XErrorEvent *);
96
static void CloseAP(Widget, XEvent *, String *, Cardinal *);
97
static void SetCmapPropsAP(Widget, XEvent *, String *, Cardinal *);
98
static void UnsetCmapPropsAP(Widget, XEvent *, String *, Cardinal *);
99
static void NewAP(Widget, XEvent *, String *, Cardinal *);
100
static void ReplaceAP(Widget, XEvent *, String *, Cardinal *);
101
static void PopupPixelAP(Widget, XEvent *, String *, Cardinal *);
102
static void UpdatePixelAP(Widget, XEvent *, String *, Cardinal *);
103
static void PopdownPixelAP(Widget, XEvent *, String *, Cardinal *);
104
static void SelectRegionAP(Widget, XEvent *, String *, Cardinal *);
105
static void CheckPoints(Position *, Position *, Position *, Position *);
106
static void HighlightTO(XtPointer, XtIntervalId *);
107
static void CloseCB(Widget, XtPointer, XtPointer);
108
static void ReplaceCB(Widget, XtPointer, XtPointer);
109
static void NewCB(Widget, XtPointer, XtPointer);
110
static void SelectCB(Widget, XtPointer, XtPointer);
111
static void PasteCB(Widget, XtPointer, XtPointer);
112
static void SetupGC(void);
113
static Window FindWindow(int, int);
114
static void ResizeEH(Widget, XtPointer, XEvent *, Boolean *);
115
static void DragEH(Widget, XtPointer, XEvent *, Boolean *);
116
static void StartRootPtrGrab(int, hlPtr);
117
static void CreateRoot(void);
118
static void GetImageAndAttributes(Window, int, int, int, int, hlPtr);
119
static int Get_XColors(XWindowAttributes *, XColor **);
120
static Pixel GetMaxIntensity(hlPtr);
121
static Pixel GetMinIntensity(hlPtr);
122
static void PopupNewScale(hlPtr);
123
static void RedoOldScale(hlPtr);
124
static void InitCursors(void);
125
static void ParseSourceGeom(void);
148
GetImageAndAttributes(),
168
/* application resources */
170
typedef struct { String geometry, source, mag, title; } OptionsRec;
171
static OptionsRec options;
173
#define Offset(field) XtOffsetOf(OptionsRec, field)
174
static XtResource resources[] = {
175
{"geometry", "Geometry", XtRString, sizeof(String),
176
Offset(geometry), XtRString, (XtPointer)NULL},
177
{"mag", "Mag", XtRString, sizeof(String),
178
Offset(mag), XtRString, (XtPointer)"5.0"},
179
{"source", "Source", XtRString, sizeof(String),
180
Offset(source), XtRString, (XtPointer)"SRCWIDTHxSRCHEIGHT"},
181
{"title", XtCString, XtRString, sizeof(char *),
182
Offset(title), XtRString, "xmag"},
186
static XrmOptionDescRec optionDesc[] = {
187
{"-bd", "*borderColor", XrmoptionSepArg, (XtPointer)NULL},
188
{"-bg", "*background", XrmoptionSepArg, (XtPointer)NULL},
189
{"-bw", "*borderWidth", XrmoptionSepArg, (XtPointer)NULL},
191
{"-geometry", "*geometry", XrmoptionSepArg, (XtPointer)NULL},
192
{"-mag", "*mag", XrmoptionSepArg, (XtPointer)NULL},
193
{"-source", "*source", XrmoptionSepArg, (XtPointer)NULL},
194
{"-title", "*title", XrmoptionSepArg, (XtPointer)NULL},
201
static XtActionsRec actions_table[] = {
203
{"set-colors", SetCmapPropsAP},
204
{"unset-colors", UnsetCmapPropsAP},
206
{"replace", ReplaceAP},
207
{"popup-pixel", PopupPixelAP},
208
{"update-pixel", UpdatePixelAP},
209
{"popdown-pixel", PopdownPixelAP},
210
{"select-region", SelectRegionAP}
216
* Error() -- Error handler: Catch a bad match in magnifing an
217
* area that contains bits of different depths.
220
Error(Display *dpy, XErrorEvent *err)
222
(void) XmuPrintDefaultErrorMessage (dpy, err, stderr);
228
* CloseAP() -- Close this dialog. If its the last one exit the program.
231
static void /* ARGSUSED */
232
CloseAP(Widget w, XEvent *event, String *params, Cardinal *num_params)
234
Arg wargs[2]; int n; hlPtr data;
235
if (!--numXmags) exit(0);
236
if (event->type != ClientMessage) {
237
n = 0; /* get user data */
238
XtSetArg(wargs[0], XtNuserData, &data); n++;
239
XtGetValues(w, wargs, n);
240
w = data->scaleShell;
249
* SetCmapPropsAP() -- Put the scale widget first in WM_COLORMAP_WINDOWS
252
static void /* ARGSUSED */
253
SetCmapPropsAP(Widget w, XEvent *event, String *params, Cardinal *num_params)
255
Arg wargs[2]; int n; hlPtr data;
256
n = 0; /* get user data */
257
XtSetArg(wargs[0], XtNuserData, &data); n++;
258
XtGetValues(w, wargs, n);
259
if (data->win_info.colormap != DefaultColormap(dpy, scr)) {
260
data->cmapWinList[0] = data->scaleInstance;
261
data->cmapWinList[1] = data->scaleShell;
262
XtSetWMColormapWindows(data->scaleShell, data->cmapWinList, 2);
269
* UnsetCmapPropsAP() -- Put the shell first in WM_COLORMAP_WINDOWS
272
static void /* ARGSUSED */
273
UnsetCmapPropsAP(Widget w, XEvent *event, String *params, Cardinal *num_params)
275
Arg wargs[2]; int n; hlPtr data;
276
n = 0; /* get user data */
277
XtSetArg(wargs[0], XtNuserData, &data); n++;
278
XtGetValues(w, wargs, n);
279
if (data->win_info.colormap != DefaultColormap(dpy, scr)) {
280
data->cmapWinList[0] = data->scaleShell;
281
data->cmapWinList[1] = data->scaleInstance;
282
XtSetWMColormapWindows(data->scaleShell, data->cmapWinList, 2);
289
* NewAP() -- Create an additional xmag dialog. THIS IS A COPY OF NewEH
290
* FIND A BETTER WAY....
292
static void /* ARGSUSED */
293
NewAP(Widget w, XEvent *event, String *params, Cardinal *num_params)
295
StartRootPtrGrab(True, NULL);
301
* ReplaceAP() -- Replace this particular xmag dialog.
303
static void /* ARGSUSED */
304
ReplaceAP(Widget w, XEvent *event, String *params, Cardinal *num_params)
306
Arg wargs[2]; int n; hlPtr data;
307
n = 0; /* get user data */
308
XtSetArg(wargs[0], XtNuserData, &data); n++;
309
XtGetValues(w, wargs, n);
310
StartRootPtrGrab(False, data);
316
* PopupPixelAP() -- Show pixel information.
318
static void /* ARGSUSED */
319
PopupPixelAP(Widget w, XEvent *event, String *params, Cardinal *num_params)
321
Position scale_x, scale_y;
322
Dimension scale_height;
323
Position label_x, label_y;
324
Dimension label_height;
329
n = 0; /* get user data */
330
XtSetArg(wargs[0], XtNuserData, &data); n++;
331
XtGetValues(w, wargs, n);
334
XtSetArg(wargs[n], XtNheight, &scale_height); n++;
335
XtGetValues(w, wargs, n);
336
XtTranslateCoords(w, -1, -1, &scale_x, &scale_y);
338
XtRealizeWidget(data->pixShell); /* to get the right height */
341
XtSetArg(wargs[n], XtNheight, &label_height); n++;
342
XtGetValues(data->pixShell, wargs, n);
344
if ((double) event->xbutton.y / (double) scale_height > 0.5) {
350
label_y = scale_y + scale_height - label_height;
354
XtSetArg(wargs[n], XtNx, label_x); n++;
355
XtSetArg(wargs[n], XtNy, label_y); n++;
356
XtSetValues(data->pixShell, wargs, n);
358
UpdatePixelAP(w, event, 0, 0);
364
* UpdatePixelAP() -- Update pixel information.
366
static void /* ARGSUSED */
367
UpdatePixelAP(Widget w, XEvent *event, String *params, Cardinal *num_params)
378
XtSetArg(wargs[0], XtNuserData, &data); n++;
379
XtGetValues(w, wargs, n);
381
if (SWGetImagePixel(w, event->xbutton.x, event->xbutton.y, &x, &y, &pixel))
382
XtPopdown(data->pixShell);
385
XQueryColor(dpy, data->win_info.colormap, &color);
386
sprintf(string, "Pixel %ld at (%d,%d) colored (%x,%x,%x).",
387
pixel, x + data->x, y + data->y,
388
color.red, color.green, color.blue);
390
XtSetArg(wargs[n], XtNlabel, string); n++;
391
XtSetValues(data->pixLabel, wargs, n);
392
XtPopup(data->pixShell, XtGrabNone);
399
* PopdownPixelAP() -- Remove pixel info.
401
static void /* ARGSUSED */
402
PopdownPixelAP(Widget w, XEvent *event, String *params, Cardinal *num_params)
409
XtSetArg(wargs[0], XtNuserData, &data); n++;
410
XtGetValues(w, wargs, n);
413
XtPopdown(data->pixShell);
418
static void /* ARGSUSED */
419
SelectRegionAP(Widget w, XEvent *event, String *params, Cardinal *num_params)
421
/***** NOT SURE WHAT TO DO WITH THIS
422
if (app_resources.unmap)
423
XtUnmapWidget(toplevel);
424
Redisplay(XtDisplay(w), RootWindow(XtDisplay(w),
425
DefaultScreen(XtDisplay(w))),
426
source.width, source.height,
427
app_resources.freq, app_resources.puls,
431
if (app_resources.unmap)
432
XtMapWidget(toplevel);
439
* CheckPoints() -- Change the cursor for the correct quadrant.
440
* Make sure the first point is less than the second
441
* for drawing the selection rectangle.
445
CheckPoints(Position *x1, Position *x2, Position *y1, Position *y2)
450
above = (*y2 < *y1); left = (*x2 < *x1);
451
if (above&&left) newC = ulAngle;
452
else if (above&&!left) newC = urAngle;
453
else if (!above&&!left) newC = lrAngle;
455
XChangeActivePointerGrab
456
(dpy, PointerMotionMask|ButtonPressMask|ButtonReleaseMask,
458
if (*x2 < *x1) { tmp = *x1; *x1 = *x2; *x2 = tmp; }
459
if (*y2 < *y1) { tmp = *y1; *y1 = *y2; *y2 = tmp; }
465
* HighlightTO() -- Timer to highlight the selection box
468
HighlightTO(XtPointer closure, XtIntervalId *id) /* ARGSUSED */
470
hlPtr data = (hlPtr)closure;
472
if (data->selectMode == drag) {
473
XDrawRectangle(dpy, DefaultRootWindow(dpy), data->gc,
474
data->x, data->y, data->width, data->height);
475
XDrawRectangle(dpy, DefaultRootWindow(dpy), data->gc,
476
data->x, data->y, data->width, data->height);
478
else if (data->selectMode == resize) {
479
Position x1 = data->homeX,
483
CheckPoints(&x1, &x2, &y1, &y2);
484
XDrawRectangle(dpy, DefaultRootWindow(dpy), data->gc,
485
x1, y1, x2 - x1, y2 - y1);
486
XDrawRectangle(dpy, DefaultRootWindow(dpy), data->gc,
487
x1, y1, x2 - x1, y2 - y1);
490
if (data->selectMode != done)
491
XtAppAddTimeOut(app, HLINTERVAL, HighlightTO, (XtPointer)data);
497
* CloseCB() -- Delete this xmag dialog. If its the only one on the screen
500
static void /* ARGSUSED */
501
CloseCB(Widget w, XtPointer clientData, XtPointer callData)
503
Widget shell = (Widget)clientData;
504
if (!--numXmags) exit(0);
506
XtDestroyWidget(shell);
512
* ReplaceCB() -- Replace this particular xmag dialog.
514
static void /* ARGSUSED */
515
ReplaceCB(Widget w, XtPointer clientData, XtPointer callData)
517
hlPtr data = (hlPtr)clientData;
518
StartRootPtrGrab(False, data);
524
* NewCB() -- Create an additional xmag dialog.
526
static void /* ARGSUSED */
527
NewCB(Widget w, XtPointer clientData, XtPointer callData)
529
StartRootPtrGrab(True, NULL);
535
* SelectCB() -- Own the primary selection.
537
static void /* ARGSUSED */
538
SelectCB(Widget w, XtPointer clientData, XtPointer callData)
540
hlPtr data = (hlPtr)clientData;
541
SWGrabSelection(data->scaleInstance, XtLastTimestampProcessed(dpy));
547
* PasteCB() -- Paste from the primary selectin into xmag.
549
static void /* ARGSUSED */
550
PasteCB(Widget w, XtPointer clientData, XtPointer callData)
552
hlPtr data = (hlPtr)clientData;
553
SWRequestSelection(data->scaleInstance, XtLastTimestampProcessed(dpy));
559
* SetupGC() -- Graphics context for magnification selection.
564
selectGCV.function = GXxor;
565
selectGCV.foreground = 1L;
566
selectGCV.subwindow_mode = IncludeInferiors;
567
selectGC = XtGetGC(toplevel, GCFunction|GCForeground|GCSubwindowMode,
574
* FindWindow() -- Determin window the pointer is over.
578
FindWindow(int x, int y) /* Locatation of cursor */
580
XWindowAttributes wa;
581
Window findW = DefaultRootWindow(dpy), stopW, childW;
582
XTranslateCoordinates(dpy, findW, findW,
583
x, y, &x, &y, &stopW);
585
XTranslateCoordinates(dpy, findW, stopW,
586
x, y, &x, &y, &childW);
589
XGetWindowAttributes(dpy, childW, &wa) &&
590
wa.class != InputOutput)
600
* ResizeEH() -- Event Handler for resize of selection box.
603
ResizeEH(Widget w, XtPointer closure, XEvent *event,
604
Boolean *continue_to_dispatch) /* ARGSUSED */
606
hlPtr data = (hlPtr)closure;
607
switch (event->type) {
609
data->x = event->xmotion.x_root;
610
data->y = event->xmotion.y_root;
613
GetImageAndAttributes(FindWindow(event->xmotion.x_root,
614
event->xmotion.y_root),
615
min(data->homeX,event->xbutton.x_root),
616
min(data->homeY,event->xbutton.y_root),
617
abs(data->homeX - event->xbutton.x_root),
618
abs(data->homeY - event->xbutton.y_root),
623
SWSetImage(data->scaleInstance, data->image);
624
XtUngrabPointer(w, CurrentTime);
626
XtRemoveRawEventHandler(w, PointerMotionMask|ButtonReleaseMask,
627
True, ResizeEH, (XtPointer)data);
629
XtRemoveEventHandler(w, PointerMotionMask|ButtonReleaseMask,
630
True, ResizeEH, (XtPointer)data);
631
data->selectMode = done;
639
* DragEH() -- Event Handler for draging selection box.
642
DragEH(Widget w, XtPointer closure, XEvent *event,
643
Boolean *continue_to_dispatch) /* ARGSUSED */
645
hlPtr data = (hlPtr)closure;
646
switch (event->type) {
647
case MotionNotify: /* drag mode */
648
data->x = event->xmotion.x_root;
649
data->y = event->xmotion.y_root;
651
case ButtonRelease: /* end drag mode */
652
if (event->xbutton.button == Button1) { /* get image */
653
/* Problem: You can't get bits with XGetImage outside of its window.
654
* xmag will only do a GetImage on the actual window in the case
655
* where the depth of the window does not match the depth of
658
GetImageAndAttributes(FindWindow(event->xmotion.x_root,
659
event->xmotion.y_root),
660
event->xbutton.x_root,
661
event->xbutton.y_root,
662
srcWidth, srcHeight, data);
667
XtUngrabPointer(w, CurrentTime);
668
XtRemoveRawEventHandler(w, PointerMotionMask|ButtonPressMask|
669
ButtonReleaseMask, True, DragEH,
671
data->selectMode = done;
676
if (event->xbutton.button == Button2) { /* turn on resize mode */
677
data->homeX = event->xbutton.x_root;
678
data->homeY = event->xbutton.y_root;
679
data->x = event->xbutton.x_root + srcWidth;
680
data->y = event->xbutton.y_root + srcHeight;
681
data->selectMode = resize;
682
XtRemoveRawEventHandler(w, PointerMotionMask|ButtonPressMask|
683
ButtonReleaseMask, True, DragEH, (XtPointer)data);
684
XChangeActivePointerGrab
685
(dpy, PointerMotionMask|ButtonPressMask|ButtonReleaseMask,
686
lrAngle, CurrentTime);
687
XWarpPointer(dpy, None, None, 0, 0, 0, 0,
688
srcWidth, srcHeight);
689
XtAddEventHandler(w, PointerMotionMask|ButtonReleaseMask,
690
True, ResizeEH, (XtPointer)data);
700
* StartRootPtrGrab() -- Bring up the selection box.
704
StartRootPtrGrab(int new, /* do we cretate a new scale instance? */
705
hlPtr data) /* highligh data */
707
Window rootR, childR;
708
int rootX, rootY, winX, winY;
713
PointerMotionMask|ButtonPressMask|ButtonReleaseMask,
714
GrabModeAsync, GrabModeAsync, None, ulAngle, CurrentTime);
715
XQueryPointer(dpy, DefaultRootWindow(dpy), &rootR, &childR,
716
&rootX, &rootY, &winX, &winY, &mask);
719
hlData = (hlPtr)XtMalloc(sizeof(hlStruct));
722
hlData->newScale = new;
723
hlData->selectMode = drag;
726
hlData->gc = selectGC;
727
hlData->width = srcWidth;
728
hlData->height = srcHeight;
730
(root, PointerMotionMask|ButtonPressMask|ButtonReleaseMask,
731
True, DragEH, (XtPointer)hlData);
732
hlId = XtAppAddTimeOut(app, HLINTERVAL, HighlightTO, (XtPointer)hlData);
738
* CreateRoot() -- Create a root window widget. If the user specified x and y
739
* in his source geometry then use this to directly get the
746
root = XtCreateWidget("root", rootWindowWidgetClass, toplevel, NULL, 0);
747
XtRealizeWidget(root);
748
if (XValue & srcStat && YValue &srcStat) {
750
data = (hlPtr)XtMalloc(sizeof(hlStruct));
752
data->newScale = True;
753
data->selectMode = drag;
757
data->width = srcWidth;
758
data->height = srcHeight;
759
GetImageAndAttributes(RootWindow(dpy, scr), srcX, srcY, srcWidth,
768
* GetImageAndAttributes() -- Get the image bits from the screen.
769
* We will also determin here the colormap, depth, and
770
* visual to be used for the magnification image.
773
GetImageAndAttributes(Window w, int x, int y, int width, int height,
776
/* get parameters of window being magnified */
777
XGetWindowAttributes(dpy, w, &data->win_info);
779
if (data->win_info.depth == DefaultDepth(dpy, scr)) {
780
/* avoid off screen pixels */
781
if (x < 0) x = 0; if (y < 0) y = 0;
782
if (x + width > DisplayWidth(dpy,scr)) x = DisplayWidth(dpy,scr) - width;
783
if (y + height > DisplayHeight(dpy,scr))
784
y = DisplayHeight(dpy,scr) - height;
785
data->x = x; data->y = y;
786
/* get image pixels */
787
data->image = XGetImage (dpy,
788
RootWindow(dpy, scr),
794
int xInWin, yInWin; Window childWin;
795
XTranslateCoordinates(dpy, DefaultRootWindow(dpy), w, x, y,
796
&xInWin, &yInWin, &childWin);
797
/* avoid off screen pixels */
798
if (x + data->win_info.x < 0) x = abs(data->win_info.x);
799
if (y + data->win_info.y < 0) y = abs(data->win_info.y);
800
if (x + width > DisplayWidth(dpy,scr)) x = DisplayWidth(dpy,scr) - width;
801
if (y + height > DisplayHeight(dpy,scr))
802
y = DisplayHeight(dpy,scr) - height;
803
data->x = x; data->y = y;
804
data->image = XGetImage (dpy,
816
* Get_XColors() Get the XColors of all pixels in image - returns # of colors
817
* This function was taken from xwd (thanks Bob...)
819
#define lowbit(x) ((x) & (~(x) + 1))
821
Get_XColors(XWindowAttributes *win_info, XColor **colors)
825
if (!win_info->colormap)
828
ncolors = win_info->visual->map_entries;
829
if (!(*colors = (XColor *) XtMalloc (sizeof(XColor) * ncolors)))
830
XtError("Out of memory!");
832
if (win_info->visual->class == DirectColor ||
833
win_info->visual->class == TrueColor) {
834
Pixel red, green, blue, red1, green1, blue1;
836
red = green = blue = 0;
837
red1 = lowbit(win_info->visual->red_mask);
838
green1 = lowbit(win_info->visual->green_mask);
839
blue1 = lowbit(win_info->visual->blue_mask);
840
for (i=0; i<ncolors; i++) {
841
(*colors)[i].pixel = red|green|blue;
842
(*colors)[i].pad = 0;
844
if (red > win_info->visual->red_mask)
847
if (green > win_info->visual->green_mask)
850
if (blue > win_info->visual->blue_mask)
854
for (i=0; i<ncolors; i++) {
855
(*colors)[i].pixel = i;
856
(*colors)[i].pad = 0;
860
XQueryColors(dpy, win_info->colormap, *colors, ncolors);
867
#define Intensity(cptr) (3.0*cptr->red+0.59*cptr->green+0.11*cptr->blue)
870
* GetMaxIntensity() -- Find the maximum intensity pixel value for a colormap.
873
GetMaxIntensity(hlPtr data)
875
XColor *colors = NULL, *mptr, *tptr;
878
if (data->win_info.colormap == DefaultColormap(dpy, scr))
879
return WhitePixel(dpy, scr);
880
ncolors = Get_XColors(&data->win_info, &colors);
881
mptr = tptr = colors; tptr++;
882
for (i=1; i<ncolors; i++) {
883
if ((int)Intensity(mptr) < (int)Intensity(tptr))
891
* GetMinIntensity() -- Find the minimum intensity pixel value for a colormap.
894
GetMinIntensity(hlPtr data)
896
XColor *colors = NULL, *mptr, *tptr;
899
if (data->win_info.colormap == DefaultColormap(dpy, scr))
900
return BlackPixel(dpy, scr);
901
ncolors = Get_XColors(&data->win_info, &colors);
902
mptr = tptr = colors; tptr++;
903
for (i=1; i<ncolors; i++) {
904
if ((int)Intensity(mptr) > (int)Intensity(tptr))
914
static Widget pane1, pane2, pane3, cclose, replace, new, select_w, paste, label;
917
* PopupNewScale() -- Create and popup a new scale composite.
920
PopupNewScale(hlPtr data)
925
XtVaCreatePopupShell("xmag", topLevelShellWidgetClass, toplevel,
926
XtNgeometry, (XtArgVal)options.geometry,
927
XtNtitle, (XtArgVal)options.title,
929
pane1 = XtCreateManagedWidget("pane1", panedWidgetClass, data->scaleShell,
931
pane2 = XtCreateManagedWidget("pane2", panedWidgetClass, pane1,
933
cclose = XtCreateManagedWidget("close", commandWidgetClass, pane2,
935
XtAddCallback(cclose, XtNcallback, CloseCB, (XtPointer)data->scaleShell);
936
replace = XtCreateManagedWidget("replace", commandWidgetClass, pane2,
938
XtAddCallback(replace, XtNcallback, ReplaceCB, (XtPointer)data);
939
new = XtCreateManagedWidget("new", commandWidgetClass, pane2,
941
XtAddCallback(new, XtNcallback, NewCB, (XtPointer)NULL);
942
select_w = XtCreateManagedWidget("select", commandWidgetClass, pane2,
944
XtAddCallback(select_w, XtNcallback, SelectCB, (XtPointer)data);
945
paste = XtCreateManagedWidget("paste", commandWidgetClass, pane2,
947
XtAddCallback(paste, XtNcallback, PasteCB, (XtPointer)data);
948
label = XtCreateManagedWidget("helpLabel", labelWidgetClass, pane2,
950
pane3 = XtCreateManagedWidget("pane2", panedWidgetClass, pane1,
952
data->scaleInstance =
953
XtVaCreateManagedWidget("scale", scaleWidgetClass,
955
XtNvisual, (XtArgVal)data->win_info.visual,
956
XtNcolormap, (XtArgVal)data->win_info.colormap,
957
XtNdepth, (XtArgVal)data->win_info.depth,
958
XtNscaleX, (XtArgVal)options.mag,
959
XtNscaleY, (XtArgVal)options.mag,
961
SWSetImage(data->scaleInstance, data->image);
962
XtOverrideTranslations
964
XtParseTranslationTable ("<Message>WM_PROTOCOLS: close()"));
965
XtSetArg(warg, XtNuserData, data);
966
XtSetValues(data->scaleInstance, &warg, 1);
968
XtVaCreatePopupShell("pixShell", overrideShellWidgetClass,
970
XtNvisual, (XtArgVal)data->win_info.visual,
971
XtNcolormap, (XtArgVal)data->win_info.colormap,
972
XtNdepth, (XtArgVal)data->win_info.depth,
973
XtNborderWidth, (XtPointer)0,
976
XtVaCreateManagedWidget("pixLabel", labelWidgetClass,
978
XtNforeground, (XtPointer)GetMaxIntensity(data),
979
XtNbackground, (XtPointer)GetMinIntensity(data),
980
XtNborderWidth, (XtPointer)0,
982
XtInstallAllAccelerators(pane1, pane1); /* install accelerators */
983
if (data->newScale) {
984
XtPopup(data->scaleShell, XtGrabNone);
985
(void) XSetWMProtocols /* ICCCM delete window */
986
(dpy, XtWindow(data->scaleShell), &wm_delete_window, 1);
988
if (data->win_info.colormap != DefaultColormap(dpy, scr)) {
989
data->cmapWinList[0] = data->scaleShell;
990
data->cmapWinList[1] = data->scaleInstance;
991
XtSetWMColormapWindows(data->scaleShell, data->cmapWinList, 2);
998
* RedoOldScale() -- If the visual, depth, or colormap has changed, unrealize
999
* the scale widget and change its colormap/depth/visual.
1000
* Then re-realize it. Also do this for the pixel display
1004
RedoOldScale(hlPtr data)
1013
XtSetArg(wargs[n], XtNvisual, &oldVis); n++;
1014
XtSetArg(wargs[n], XtNdepth, &oldDepth); n++;
1015
XtSetArg(wargs[n], XtNcolormap, &oldCmap); n++;
1016
XtGetValues(data->scaleInstance, wargs, n);
1017
if (oldVis == data->win_info.visual && oldDepth == data->win_info.depth
1018
&& oldCmap == data->win_info.colormap) {
1019
SWSetImage(data->scaleInstance, data->image);
1022
/* get width and height, save and reuse them */
1023
XtUnmanageChild(data->scaleInstance);
1024
XtUnrealizeWidget(data->scaleInstance);
1026
XtSetArg(wargs[n], XtNcolormap, data->win_info.colormap); n++;
1027
XtSetArg(wargs[n], XtNdepth, data->win_info.depth); n++;
1028
XtSetArg(wargs[n], XtNvisual, data->win_info.visual); n++;
1029
XtSetValues(data->scaleInstance, wargs, n);
1031
XtSetArg(wargs[n], XtNforeground, GetMaxIntensity(data)); n++;
1032
XtSetArg(wargs[n], XtNbackground, GetMinIntensity(data)); n++;
1033
XtSetValues(data->pixLabel, wargs, n);
1034
SWSetImage(data->scaleInstance, data->image);
1035
XtRealizeWidget(data->scaleInstance);
1036
XtManageChild(data->scaleInstance);
1042
* InitCursors() -- Create our cursors for area selection.
1047
ulAngle = XCreateFontCursor(dpy, XC_ul_angle);
1048
urAngle = XCreateFontCursor(dpy, XC_ur_angle);
1049
lrAngle = XCreateFontCursor(dpy, XC_lr_angle);
1050
llAngle = XCreateFontCursor(dpy, XC_ll_angle);
1056
* ParseSourceGeom() -- Determin dimensions of area to magnify from resources.
1059
ParseSourceGeom(void)
1063
XParseGeometry(options.source, &srcX, &srcY, &srcWidth, &srcHeight);
1064
if (!srcWidth) srcWidth = SRCWIDTH;
1065
if (!srcHeight) srcHeight = SRCHEIGHT;
1066
if (XNegative & srcStat) srcX = DisplayWidth(dpy, scr) + srcX - srcWidth;
1067
if (YNegative & srcStat) srcY = DisplayHeight(dpy, scr) + srcY - srcHeight;
1077
main(int argc, char *argv[])
1079
XSetErrorHandler(Error);
1082
toplevel = XtAppInitialize(&app, "Xmag", optionDesc, XtNumber(optionDesc),
1086
dpy = XtDisplay(toplevel);
1087
scr = DefaultScreen(dpy);
1088
XtGetApplicationResources(toplevel, (XtPointer) &options, resources,
1089
XtNumber(resources), NULL, 0);
1092
"usage: xmag [-source geom] [-mag magfactor] [-toolkitoption]\n");
1098
XtAppAddActions(app, actions_table, XtNumber(actions_table));
1102
if (!(XValue & srcStat && YValue & srcStat))
1103
StartRootPtrGrab(True, (hlPtr)NULL);
1104
wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", False);