1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-18 03:50:30 +01:00
Files
wmaker/util/wmagnify.c
Christophe CURIS c743c4b77b doc: updated man pages for many tools
This patch perform simple fixes to the man pages and tool help page:
 - minor style updates, to get cleaner pages
 - option re-ordering, to have them in alphabetic order (easier to search for)
 - consistency updates for descriptions and number of dash
 - spell-checking

The biggest changes are:
 - wmagnify: the option 'vdisplay' was not documented at all;

 - getstyle: the list of attributes that are taken for the Style are now
described in their own section to clarify the page;

 - setstyle: the help page left thinking that the file argument was
optional, which is not the case;

 - wdread: as the Exit Code may be useful, and it is not unusable, it is
now documented;

 - wmgenmenu: added information about how the content of the menu is
generated;

 - wmsetbg: added a section about dithering/best-match because as nowadays
most screens are in True Color, the reason for the option may not be clear.

Signed-off-by: Christophe CURIS <christophe.curis@free.fr>
2015-04-18 19:31:10 +01:00

489 lines
11 KiB
C

/*
* magnify - a X utility for magnifying screen image
*
* 2000/5/21 Alfredo K. Kojima
*
* This program is in the Public Domain.
*/
#include <config.h>
#include <X11/Xproto.h>
#include <WINGs/WINGs.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/*
* TODO:
* - lens that shows where it's magnifying
*
*
*/
int refreshrate = 200;
typedef struct {
Drawable d;
XRectangle *rects;
int rectP;
unsigned long lastpixel;
unsigned long *buffer;
int width, height;
int rwidth, rheight; /* size of window in real pixels */
int magfactor;
int refreshrate;
WMWindow *win;
WMLabel *label;
WMPixmap *pixmap;
WMWindow *dlg;
WMSlider *speed;
WMSlider *magnify;
WMButton *okB;
WMButton *cancelB;
WMButton *newB;
int x, y;
Bool frozen;
Bool firstDraw;
Bool markPointerHotspot;
WMHandlerID tid;
} BufferData;
static BufferData *newWindow(int magfactor);
int windowCount = 0;
int rectBufferSize = 32;
Display *dpy, *vdpy;
WMScreen *scr;
unsigned int black;
WMColor *cursorColor1;
WMColor *cursorColor2;
static BufferData *makeBufferData(WMWindow * win, WMLabel * label, int width, int height, int magfactor)
{
BufferData *data;
data = wmalloc(sizeof(BufferData));
data->rwidth = width;
data->rheight = height;
data->refreshrate = refreshrate;
data->firstDraw = True;
data->magfactor = magfactor;
data->rects = wmalloc(sizeof(XRectangle) * rectBufferSize);
data->rectP = 0;
data->win = win;
data->label = label;
data->pixmap = WMCreatePixmap(scr, width, height, WMScreenDepth(scr), False);
WMSetLabelImage(data->label, data->pixmap);
data->d = WMGetPixmapXID(data->pixmap);
data->frozen = False;
width /= magfactor;
height /= magfactor;
data->buffer = wmalloc(sizeof(unsigned long) * width * height);
data->width = width;
data->height = height;
return data;
}
static void resizeBufferData(BufferData * data, int width, int height, int magfactor)
{
int w = width / magfactor;
int h = height / magfactor;
data->rwidth = width;
data->rheight = height;
data->firstDraw = True;
data->magfactor = magfactor;
data->buffer = wrealloc(data->buffer, sizeof(unsigned long) * w * h);
data->width = w;
data->height = h;
memset(data->buffer, 0, w * h * sizeof(unsigned long));
WMResizeWidget(data->label, width, height);
WMReleasePixmap(data->pixmap);
data->pixmap = WMCreatePixmap(scr, width, height, WMScreenDepth(scr), False);
WMSetLabelImage(data->label, data->pixmap);
data->d = WMGetPixmapXID(data->pixmap);
}
static int drawpoint(BufferData * data, unsigned long pixel, int x, int y)
{
static GC gc = NULL;
Bool flush = (x < 0);
if (!flush) {
if (data->buffer[x + data->width * y] == pixel && !data->firstDraw)
return 0;
data->buffer[x + data->width * y] = pixel;
}
if (gc == NULL) {
gc = XCreateGC(dpy, DefaultRootWindow(dpy), 0, NULL);
}
if (!flush && data->lastpixel == pixel && data->rectP < rectBufferSize) {
data->rects[data->rectP].x = x * data->magfactor;
data->rects[data->rectP].y = y * data->magfactor;
data->rects[data->rectP].width = data->magfactor;
data->rects[data->rectP].height = data->magfactor;
data->rectP++;
return 0;
}
XSetForeground(dpy, gc, data->lastpixel);
XFillRectangles(dpy, data->d, gc, data->rects, data->rectP);
data->rectP = 0;
data->rects[data->rectP].x = x * data->magfactor;
data->rects[data->rectP].y = y * data->magfactor;
data->rects[data->rectP].width = data->magfactor;
data->rects[data->rectP].height = data->magfactor;
data->rectP++;
data->lastpixel = pixel;
return 1;
}
static inline unsigned long getpix(XImage * image, int x, int y, int xoffs, int yoffs)
{
if (x < xoffs || y < yoffs || x >= xoffs + image->width || y >= yoffs + image->height) {
return black;
}
return XGetPixel(image, x - xoffs, y - yoffs);
}
static void updateImage(BufferData * data, int rx, int ry)
{
int gx, gy, gw, gh;
int x, y;
int xoffs, yoffs;
int changedPixels = 0;
XImage *image;
gw = data->width;
gh = data->height;
gx = rx - gw / 2;
gy = ry - gh / 2;
xoffs = yoffs = 0;
if (gx < 0) {
xoffs = abs(gx);
gw += gx;
gx = 0;
}
if (gx + gw >= WidthOfScreen(DefaultScreenOfDisplay(vdpy))) {
gw = WidthOfScreen(DefaultScreenOfDisplay(vdpy)) - gx;
}
if (gy < 0) {
yoffs = abs(gy);
gh += gy;
gy = 0;
}
if (gy + gh >= HeightOfScreen(DefaultScreenOfDisplay(vdpy))) {
gh = HeightOfScreen(DefaultScreenOfDisplay(vdpy)) - gy;
}
image = XGetImage(vdpy, DefaultRootWindow(vdpy), gx, gy, gw, gh, AllPlanes, ZPixmap);
for (y = 0; y < data->height; y++) {
for (x = 0; x < data->width; x++) {
unsigned long pixel;
pixel = getpix(image, x, y, xoffs, yoffs);
if (drawpoint(data, pixel, x, y))
changedPixels++;
}
}
/* flush the point cache */
drawpoint(data, 0, -1, -1);
XDestroyImage(image);
if (data->markPointerHotspot && !data->frozen) {
XRectangle rects[4];
rects[0].x = (data->width / 2 - 3) * data->magfactor;
rects[0].y = (data->height / 2) * data->magfactor;
rects[0].width = 2 * data->magfactor;
rects[0].height = data->magfactor;
rects[1].x = (data->width / 2 + 2) * data->magfactor;
rects[1].y = (data->height / 2) * data->magfactor;
rects[1].width = 2 * data->magfactor;
rects[1].height = data->magfactor;
XFillRectangles(dpy, data->d, WMColorGC(cursorColor1), rects, 2);
rects[2].y = (data->height / 2 - 3) * data->magfactor;
rects[2].x = (data->width / 2) * data->magfactor;
rects[2].height = 2 * data->magfactor;
rects[2].width = data->magfactor;
rects[3].y = (data->height / 2 + 2) * data->magfactor;
rects[3].x = (data->width / 2) * data->magfactor;
rects[3].height = 2 * data->magfactor;
rects[3].width = data->magfactor;
XFillRectangles(dpy, data->d, WMColorGC(cursorColor2), rects + 2, 2);
}
if (changedPixels > 0) {
WMRedisplayWidget(data->label);
}
data->firstDraw = False;
}
static void update(void *d)
{
BufferData *data = (BufferData *) d;
Window win;
int rx, ry;
int bla;
unsigned ubla;
if (data->frozen) {
rx = data->x;
ry = data->y;
} else {
XQueryPointer(dpy, DefaultRootWindow(dpy), &win, &win, &rx, &ry, &bla, &bla, &ubla);
}
updateImage(data, rx, ry);
data->tid = WMAddTimerHandler(data->refreshrate, update, data);
}
static void resizedWindow(void *d, WMNotification * notif)
{
BufferData *data = (BufferData *) d;
WMView *view = (WMView *) WMGetNotificationObject(notif);
WMSize size;
size = WMGetViewSize(view);
resizeBufferData(data, size.width, size.height, data->magfactor);
}
static void closeWindow(WMWidget * w, void *d)
{
BufferData *data = (BufferData *) d;
windowCount--;
if (windowCount == 0) {
WMReleaseApplication();
exit(0);
} else {
WMDeleteTimerHandler(data->tid);
WMDestroyWidget(w);
wfree(data->buffer);
wfree(data->rects);
WMReleasePixmap(data->pixmap);
wfree(data);
}
}
static void keyHandler(XEvent * event, void *d)
{
BufferData *data = (BufferData *) d;
char buf[32];
KeySym ks;
WMView *view = WMWidgetView(data->win);
WMSize size;
size = WMGetViewSize(view);
if (XLookupString(&event->xkey, buf, 31, &ks, NULL) > 0) {
switch (buf[0]) {
case 'n':
newWindow(data->magfactor);
break;
case 'm':
data->markPointerHotspot = !data->markPointerHotspot;
break;
case 'f':
case ' ':
data->frozen = !data->frozen;
if (data->frozen) {
data->x = event->xkey.x_root;
data->y = event->xkey.y_root;
sprintf(buf, "[Magnify %ix]", data->magfactor);
} else {
sprintf(buf, "Magnify %ix", data->magfactor);
}
WMSetWindowTitle(data->win, buf);
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
resizeBufferData(data, size.width, size.height, buf[0] - '0');
if (data->frozen) {
sprintf(buf, "[Magnify %ix]", data->magfactor);
} else {
sprintf(buf, "Magnify %ix", data->magfactor);
}
WMSetWindowTitle(data->win, buf);
break;
}
}
}
static BufferData *newWindow(int magfactor)
{
WMWindow *win;
WMLabel *label;
BufferData *data;
char buf[32];
windowCount++;
win = WMCreateWindow(scr, "magnify");
WMResizeWidget(win, 300, 200);
sprintf(buf, "Magnify %ix", magfactor);
WMSetWindowTitle(win, buf);
WMSetViewNotifySizeChanges(WMWidgetView(win), True);
label = WMCreateLabel(win);
WMResizeWidget(label, 300, 200);
WMMoveWidget(label, 0, 0);
WMSetLabelRelief(label, WRSunken);
WMSetLabelImagePosition(label, WIPImageOnly);
data = makeBufferData(win, label, 300, 200, magfactor);
WMCreateEventHandler(WMWidgetView(win), KeyReleaseMask, keyHandler, data);
WMAddNotificationObserver(resizedWindow, data, WMViewSizeDidChangeNotification, WMWidgetView(win));
WMRealizeWidget(win);
WMMapSubwidgets(win);
WMMapWidget(win);
WMSetWindowCloseAction(win, closeWindow, data);
data->tid = WMAddTimerHandler(refreshrate, update, data);
return data;
}
int main(int argc, char **argv)
{
int i;
char *display = "";
char *vdisplay = NULL;
int magfactor = 2;
WMInitializeApplication("Magnify", &argc, argv);
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-display") == 0) {
i++;
if (i >= argc)
goto help;
display = argv[i];
} else if (strcmp(argv[i], "-vdisplay") == 0) {
i++;
if (i >= argc)
goto help;
vdisplay = argv[i];
} else if (strcmp(argv[i], "-m") == 0) {
i++;
if (i >= argc)
goto help;
magfactor = atoi(argv[i]);
if (magfactor < 1 || magfactor > 32) {
printf("%s:invalid magnification factor ``%s''\n", argv[0], argv[i]);
exit(1);
}
} else if (strcmp(argv[i], "-r") == 0) {
i++;
if (i >= argc)
goto help;
refreshrate = atoi(argv[i]);
if (refreshrate < 1) {
printf("%s:invalid refresh rate ``%s''\n", argv[0], argv[i]);
exit(1);
}
} else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
help:
printf("Usage: %s [options]\n", argv[0]);
puts("Options:");
puts(" -display <display>\tdisplay where to magnification is shown");
puts(" -m <number>\t\tchange magnification factor (default 2)");
puts(" -r <number>\t\tchange refresh delay, in milliseconds (default 200)");
puts(" -vdisplay <display>\tdisplay from which the magnification is taken");
puts(" -h, --help\t\tdisplay this help page");
puts("Keys:");
puts(" 1,2,3,4,5,6,7,8,9 change the magnification factor");
puts(" <space>, f freeze the 'camera', making it magnify only the current\n"
" position");
puts(" n create a new window");
puts(" m show/hide the pointer hotspot mark");
exit(0);
}
}
dpy = XOpenDisplay(display);
if (!dpy) {
puts("could not open display");
exit(1);
}
if (vdisplay) {
vdpy = XOpenDisplay(vdisplay);
if (!vdpy) {
puts("could not open display to be viewed");
exit(1);
}
} else {
vdpy = dpy;
}
/* calculate how many rectangles we can send in a trip to the server */
rectBufferSize = XMaxRequestSize(dpy) - 128;
rectBufferSize /= sizeof(XRectangle);
if (rectBufferSize < 1)
rectBufferSize = 1;
black = BlackPixel(dpy, DefaultScreen(dpy));
scr = WMCreateScreen(dpy, 0);
cursorColor1 = WMCreateNamedColor(scr, "#ff0000", False);
cursorColor2 = WMCreateNamedColor(scr, "#00ff00", False);
newWindow(magfactor);
WMScreenMainLoop(scr);
return 0;
}