xzoom-0.3.orig/ 40755 764 764 0 6153252213 11560 5ustar joeyjoeyxzoom-0.3.orig/Imakefile100644 764 764 1202 6135132063 13461 0ustar joeyjoey#ifndef XCOMM #define XCOMM # #endif XCOMM Imakefile for xzoom XCOMM Copyright Itai Nahshon 1995, 1996 XCOMM XCOMM Valid compile time options: XCOMM -DFRAME: source area is marked with a rectangular frame. XCOMM -DXSHM: use X11 shared memory extension. XCOMM -DTIMER: count time between window updates (just for testing). XCOMM -DNO_USLEEP: for system that do not have the usleep function XCOMM -DBCOPY: use bcopy() instead of memmove() XCOMM DEFINES = -DFRAME -DXSHM -DTIMER -DNO_USLEEP DEFINES = -DFRAME -DXSHM LOCAL_LIBRARIES = -lXext -lX11 NAME = xzoom BINDIR = /usr/local/bin MANPATH = /usr/local/man SimpleProgramTarget($(NAME)) xzoom-0.3.orig/xzoom.c100644 764 764 44361 6153015643 13231 0ustar joeyjoey/* Copyright Itai Nahshon 1995, 1996. This program is distributed with no warranty. Source files for this program may be distributed freely. Modifications to this file are okay as long as: a. This copyright notice and comment are preserved and left at the top of the file. b. The man page is fixed to reflect the change. c. The author of this change adds his name and change description to the list of changes below. Executable files may be distributed with sources, or with exact location where the source code can be obtained. Changelist: Author Description ------ ----------- Itai Nahshon Version 0.1, Nov. 21 1995 Itai Nahshon Version 0.2, Apr. 17 1996 include Use memmove() instead of memcopy() Optional macro to replace call to usleep(). */ #include #include #include #include #include #include #include #include #ifdef XSHM #include #include #include #endif #include #include #ifdef TIMER #include #include #endif Display *dpy; Screen *scr; Window win; GC gc; #ifdef FRAME GC framegc; #endif #ifdef TIMER Font font; struct timeval old_time; #endif Cursor when_button; Cursor crosshair; char *progname; int set_title; #define SRC 0 /* index for source image */ #define DST 1 /* index for dest image */ #define WIDTH 256 /* default width */ #define HEIGHT 256 /* default height */ #define MAG 2 /* default magnification */ #define MAGX MAG /* horizontal magnification */ #define MAGY MAG /* vertical magnification */ int xgrab, ygrab; /* where do we take the picture from */ int magx = MAGX; int magy = MAGY; int flipxy = False; /* flip x and y */ int flipx = False; /* flip display about y axis */ int flipy = False; /* flip display about x axiz */ int xzoom_flag = False; /* next mag change only to magx */ int yzoom_flag = False; /* next mag change only to magy */ int width[2] = { 0, WIDTH }; int height[2] = { 0, HEIGHT }; #ifdef XSHM XShmSegmentInfo shminfo[2]; /* Segment info. */ #endif XImage *ximage[2]; /* Ximage struct. */ int created_images = False; #define NDELAYS 5 int delays[NDELAYS] = { 200000, 100000, 50000, 10000, 0 }; int delay_index = 0; int delay = 200000; /* 0.2 second between updates */ void timeout_func(int signum) { set_title = True; } #ifdef FRAME #define DRAW_FRAME() \ XDrawRectangle(dpy, RootWindowOfScreen(scr), framegc, xgrab, ygrab, width[SRC]-1, height[SRC]-1) #endif void allocate_images(void) { int i; #ifndef XSHM char *data; #endif for(i = 0; i < 2; i++) { #ifdef XSHM ximage[i] = XShmCreateImage(dpy, DefaultVisualOfScreen(scr), DefaultDepthOfScreen(scr), ZPixmap, NULL, &shminfo[i], width[i], height[i]); if(ximage[i] == NULL) { perror("XShmCreateImage"); exit(-1); } shminfo[i].shmid = shmget(IPC_PRIVATE, (unsigned int)(ximage[i]->bytes_per_line * ximage[i]->height), IPC_CREAT | 0777); if(shminfo[i].shmid < 0) { perror("shmget"); exit(-1); } shminfo[i].shmaddr = (char *)shmat(shminfo[i].shmid, 0, 0); if (shminfo[i].shmaddr == ((char *) -1)) { perror("shmat"); exit(-1); } #ifdef DEBUG fprintf(stderr, "new shared memory segment at 0x%08x size %d\n", shminfo[i].shmaddr, ximage[i]->bytes_per_line * ximage[i]->height); #endif ximage[i]->data = shminfo[i].shmaddr; shminfo[i].readOnly = False; XShmAttach(dpy, &shminfo[i]); XSync(dpy, False); shmctl(shminfo[i].shmid, IPC_RMID, 0); #else data = malloc(width[i] * height[i]); ximage[i] = XCreateImage(dpy, DefaultVisualOfScreen(scr), DefaultDepthOfScreen(scr), ZPixmap, 0, data, width[i], height[i], 8, width[i]); if(ximage[i] == NULL) { perror("XCreateImage"); exit(-1); } #endif XSHM } created_images = True; } void destroy_images(void) { int i; for(i = 0; i < 2; i++) { #ifdef XSHM XShmDetach(dpy, &shminfo[i]); /* ask X11 to detach shared segment */ shmdt(shminfo[i].shmaddr); /* detach it ourselves */ #else free(ximage[i]->data); #endif ximage[i]->data = NULL; /* remove refrence to that address */ XDestroyImage(ximage[i]); /* and destroy image */ } } void Usage(void) { fprintf(stderr, "Usage: %s [ args ]\n" "Command line args:\n" "-display displayname\n" "-mag magnification [ magnification ]\n" "-geometry geometry\n" "-source geometry\n" "-x\n" "-y\n" "-xy\n\n" "Window commands:\n" "+: Zoom in\n" "-: Zoom out\n" "x: Flip right and left\n" "y: Flip top and bottom\n" "z: Rotate 90 degrees counter-clockwize\n" "w: Next '+' or '-' only change width scaling\n" "h: Next '+' or '-' only change height scaling\n" "d: Change delay between frames\n" "q: Quit\n" "Arrow keys: Scroll in direction of arrow\n" "Mouse button drag: Set top-left corner of viewed area\n", progname); exit(1); } /* resize is called with the dest size. we call it then manification changes or when actual window size is changed */ void resize(int new_width, int new_height) { if(created_images) destroy_images(); /* we can get rid of these */ /* find new dimensions for source */ if(flipxy) { height[SRC] = (new_width+magx-1) / magx; width[SRC] = (new_height+magy-1) / magy; } else { width[SRC] = (new_width+magx-1) / magx; height[SRC] = (new_height+magy-1) / magy; } if(width[SRC] > WidthOfScreen(scr)) width[SRC] = WidthOfScreen(scr); if(height[SRC] > HeightOfScreen(scr)) height[SRC] = HeightOfScreen(scr); /* temporary, the dest image may be larger than the actual window */ if(flipxy) { width[DST] = magx * height[SRC]; height[DST] = magy * width[SRC]; } else { width[DST] = magx * width[SRC]; height[DST] = magy * height[SRC]; } allocate_images(); /* allocate new images */ /* remember actual window size */ if(width[DST] > new_width) width[DST] = new_width; if(height[DST] > new_height) height[DST] = new_height; } int main(int argc, char **argv) { XSetWindowAttributes xswa; int i, j, k; char c; char *p1, *p2; XEvent event; int buttonpressed = False; int unmapped = True; int scroll = 1; char title[80]; XGCValues gcv; char *dpyname = NULL; int source_geom_mask = NoValue, dest_geom_mask = NoValue, copy_from_src_mask; int xpos = 0, ypos = 0; progname = strrchr(argv[0], '/'); if(progname) ++progname; else progname = argv[0]; /* parse command line options */ while(--argc > 0) { ++argv; if(argv[0][0] == '=') { dest_geom_mask = XParseGeometry(argv[0], &xpos, &ypos, &width[DST], &height[DST]); continue; } if(!strcmp(argv[0], "-mag")) { ++argv; --argc; magx = argc > 0 ? atoi(argv[0]) : -1; if(magx <= 0) Usage(); magy = argc > 1 ? atoi(argv[1]) : -1; if(magy <= 0) magy = magx; else { ++argv; --argc; } continue; } if(!strcmp(argv[0], "-x")) { flipx = True; continue; } if(!strcmp(argv[0], "-y")) { flipy = True; continue; } if(!strcmp(argv[0], "-z") || !strcmp(argv[0], "-xy")) { flipxy = True; continue; } if(!strcmp(argv[0], "-source")) { ++argv; --argc; if(argc < 1) Usage(); source_geom_mask = XParseGeometry(argv[0], &xgrab, &ygrab, &width[SRC], &height[SRC]); continue; } if(!strcmp(argv[0], "-dest") || !strcmp(argv[0], "-geometry")) { ++argv; --argc; if(argc < 1) Usage(); dest_geom_mask = XParseGeometry(argv[0], &xpos, &ypos, &width[DST], &height[DST]); continue; } if(!strcmp(argv[0], "-d") || !strcmp(argv[0], "-display")) { ++argv; --argc; if(argc < 1) Usage(); dpyname = argv[0]; continue; } if(!strcmp(argv[0], "-delay")) { ++argv; --argc; if(argc < 1) Usage(); if(sscanf(argv[0], "%u", &delay) != 1) Usage(); delay *= 1000; continue; } Usage(); } if (!(dpy = XOpenDisplay(dpyname))) { perror("Cannot open display"); exit(-1); } /* Now, see if we have to calculate width[DST] and height[DST] from the SRC parameters */ copy_from_src_mask = NoValue; if(source_geom_mask & WidthValue) { if(flipxy) { height[DST] = magy * width[SRC]; copy_from_src_mask |= HeightValue; } else { width[DST] = magx * width[SRC]; copy_from_src_mask |= WidthValue; } } if(source_geom_mask & HeightValue) { if(flipxy) { width[DST] = magx * height[SRC]; copy_from_src_mask |= WidthValue; } else { height[DST] = magy * height[SRC]; copy_from_src_mask |= HeightValue; } } if(copy_from_src_mask & dest_geom_mask) { fprintf(stderr, "Conflicting dimensions between source and dest geometry\n"); Usage(); } scr = DefaultScreenOfDisplay(dpy); if(DefaultDepthOfScreen(scr) != 8) { fprintf(stderr, "%s: can work only with 8 bits/pixel\n", progname); exit(1); } if(source_geom_mask & XNegative) xgrab += WidthOfScreen(scr); if(source_geom_mask & YNegative) ygrab += HeightOfScreen(scr); if(dest_geom_mask & XNegative) xpos += WidthOfScreen(scr); if(source_geom_mask & YNegative) ypos += HeightOfScreen(scr); /* printf("=%dx%d+%d+%d\n", width[DST], height[DST], xpos, ypos); */ xswa.event_mask = ButtonPressMask|ButtonReleaseMask|ButtonMotionMask; xswa.event_mask |= StructureNotifyMask; /* resize etc.. */ xswa.event_mask |= KeyPressMask|KeyReleaseMask; /* commands */ xswa.background_pixel = BlackPixelOfScreen(scr); win = XCreateWindow(dpy, RootWindowOfScreen(scr), xpos, ypos, width[DST], height[DST], 0, DefaultDepthOfScreen(scr), InputOutput, DefaultVisualOfScreen(scr), CWEventMask | CWBackPixel, &xswa); XChangeProperty(dpy, win, XA_WM_ICON_NAME, XA_STRING, 8, PropModeReplace, (unsigned char *)progname, strlen(progname)); /* XChangeProperty(dpy, win, XA_WM_NAME, XA_STRING, 8, PropModeReplace, (unsigned char *)progname, strlen(progname)); */ set_title = True; XMapWindow(dpy, win); gcv.plane_mask = AllPlanes; gcv.subwindow_mode = IncludeInferiors; gcv.function = GXcopy; gcv.foreground = WhitePixelOfScreen(scr); gcv.background = BlackPixelOfScreen(scr); gc = XCreateGC(dpy, RootWindowOfScreen(scr), GCFunction|GCPlaneMask|GCSubwindowMode|GCForeground|GCBackground, &gcv); #ifdef FRAME gcv.foreground = AllPlanes; gcv.plane_mask = WhitePixelOfScreen(scr)^BlackPixelOfScreen(scr); gcv.subwindow_mode = IncludeInferiors; gcv.function = GXxor; framegc = XCreateGC(dpy, RootWindowOfScreen(scr), GCFunction|GCPlaneMask|GCSubwindowMode|GCForeground, &gcv); #endif #ifdef TIMER font = XLoadFont(dpy, "fixed"); #endif resize(width[DST], height[DST]); #ifdef FRAME { static char bitmap_data[] = { 0 }; static XColor col = { 0 }; Pixmap curs = XCreatePixmapFromBitmapData(dpy, RootWindowOfScreen(scr), bitmap_data, 1, 1, 0, 0, 1); when_button = XCreatePixmapCursor(dpy, curs, curs, &col, &col, 0, 0); } #else when_button = XCreateFontCursor(dpy, XC_ul_angle); #endif crosshair = XCreateFontCursor(dpy, XC_crosshair); XDefineCursor(dpy, win, crosshair); for(;;) { while(unmapped? (XWindowEvent(dpy, win, (long)-1, &event), 1): XCheckWindowEvent(dpy, win, (long)-1, &event)) { switch(event.type) { case ConfigureNotify: if(event.xconfigure.width != width[DST] || event.xconfigure.height != height[DST]) { resize(event.xconfigure.width, event.xconfigure.height); } break; case ReparentNotify: break; /* what do we do with it? */ case MapNotify: unmapped = False; break; case UnmapNotify: unmapped = True; break; case KeyRelease: switch(XKeycodeToKeysym(dpy, event.xkey.keycode, 0)) { case XK_Control_L: case XK_Control_R: scroll = 1; break; } break; case KeyPress: switch(XKeycodeToKeysym(dpy, event.xkey.keycode, 0)) { case XK_Control_L: case XK_Control_R: scroll = 10; break; case '+': case '=': if(!yzoom_flag) ++magx; if(!xzoom_flag) ++magy; xzoom_flag = yzoom_flag = False; resize(width[DST], height[DST]); set_title = True; break; case '-': if(!yzoom_flag) --magx; if(!xzoom_flag) --magy; xzoom_flag = yzoom_flag = False; if(magx < 1) magx = 1; if(magy < 1) magy = 1; resize(width[DST], height[DST]); set_title = True; break; case XK_Left: if(flipxy) if(flipx) ygrab += scroll; else ygrab -= scroll; else if(flipx) xgrab += scroll; else xgrab -= scroll; break; case XK_Right: if(flipxy) if(flipx) ygrab -= scroll; else ygrab += scroll; else if(flipx) xgrab -= scroll; else xgrab += scroll; break; case XK_Up: if(flipxy) if(flipy) xgrab -= scroll; else xgrab += scroll; else if(flipy) ygrab += scroll; else ygrab -= scroll; break; case XK_Down: if(flipxy) if(flipy) xgrab += scroll; else xgrab -= scroll; else if(flipy) ygrab -= scroll; else ygrab += scroll; break; case 'x': flipx = !flipx; set_title = True; break; case 'y': flipy = !flipy; set_title = True; break; case 'z': if(flipx^flipy^flipxy) { flipx = !flipx; flipy = !flipy; } flipxy = !flipxy; resize(width[DST], height[DST]); set_title = True; break; case 'w': xzoom_flag = True; yzoom_flag = False; break; case 'h': yzoom_flag = True; xzoom_flag = False; break; case 'd': if(++delay_index >= NDELAYS) delay_index = 0; delay = delays[delay_index]; sprintf(title, "delay = %d ms", delay/1000); XChangeProperty(dpy, win, XA_WM_NAME, XA_STRING, 8, PropModeReplace, (unsigned char *)title, strlen(title)); signal(SIGALRM, timeout_func); alarm(2); break; case 'q': exit(0); break; } break; case ButtonPress: #ifdef FRAME xgrab = event.xbutton.x_root - width[SRC]/2; ygrab = event.xbutton.y_root - height[SRC]/2; #else xgrab = event.xbutton.x_root; ygrab = event.xbutton.y_root; #endif XDefineCursor(dpy, win, when_button); buttonpressed = True; break; case ButtonRelease: /* xgrab = event.xbutton.x_root - width[SRC]/2; ygrab = event.xbutton.y_root - height[SRC]/2; */ XDefineCursor(dpy, win, crosshair); buttonpressed = False; break; case MotionNotify: if(buttonpressed) { #ifdef FRAME xgrab = event.xmotion.x_root - width[SRC]/2; ygrab = event.xmotion.y_root - height[SRC]/2; #else xgrab = event.xmotion.x_root; ygrab = event.xmotion.y_root; #endif } break; } /* trying XShmGetImage when part of the rect is not on the screen will fail LOUDLY.. we have to veryfy this after anything that may may modified xgrab or ygrab or the size of the source ximage */ if(xgrab < 0) xgrab = 0; if(xgrab > WidthOfScreen(scr)-width[SRC]) xgrab = WidthOfScreen(scr)-width[SRC]; if(ygrab < 0) ygrab = 0; if(ygrab > HeightOfScreen(scr)-height[SRC]) ygrab = HeightOfScreen(scr)-height[SRC]; } #ifdef XSHM XShmGetImage(dpy, RootWindowOfScreen(scr), ximage[SRC], xgrab, ygrab, AllPlanes); #else XGetSubImage(dpy, RootWindowOfScreen(scr), xgrab, ygrab, width[SRC], height[SRC], AllPlanes, ZPixmap, ximage[SRC], 0, 0); #endif #ifdef FRAME if(buttonpressed) { /* show the frame */ DRAW_FRAME(); XSync(dpy, False); } #endif /* copy scaled lines from src to dst */ for(j = flipxy?width[SRC]:height[SRC]; --j >= 0; ) { /* p1 point to begining of scanline j*magy in DST */ p1 = &ximage[DST]->data[ximage[DST]->xoffset + j*magy*ximage[DST]->bytes_per_line ]; /* p2 point to begining of scanline j in SRC */ /* if flipy then line height[SRC]-1-j */ p2 = &ximage[SRC]->data[ximage[SRC]->xoffset + (flipy?(height[SRC]-1-j):j)*ximage[SRC]->bytes_per_line ]; if(flipxy) { int p2step = ximage[SRC]->bytes_per_line; p2 = &ximage[SRC]->data[ximage[SRC]->xoffset + (flipy?j:(width[SRC]-1-j))]; if(flipx) { p2 += p2step * (height[SRC]-1); p2step = -p2step; } for(i = height[SRC]; --i >= 0;) { c = *p1++ = *p2; p2 += p2step; for(k = magx; --k > 0; ) *p1++ = c; } } else if(flipx) { p2 += width[SRC]; for(i = width[SRC]; --i >= 0;) { c = *p1++ = *--p2; for(k = magx; --k > 0; ) *p1++ = c; } } else { for(i = width[SRC]; --i >= 0;) { c = *p1++ = *p2++; for(k = magx; --k > 0; ) *p1++ = c; } } /* p1 point to begining of scanline j*magy in DST */ p1 = &ximage[DST]->data[ximage[DST]->xoffset + j*magy*ximage[DST]->bytes_per_line ]; /* p2 points to begining of next line */ p2 = p1 + ximage[DST]->bytes_per_line; /* duplicate that line as needed */ for(k = magy; --k > 0; ) { #ifdef BCOPY bcopy(p1, p2, width[DST]); #else memmove(p2, p1, width[DST]); #endif p2 += ximage[DST]->bytes_per_line; } } #ifdef XSHM XShmPutImage(dpy, win, gc, ximage[DST], 0, 0, 0, 0, width[DST], height[DST], False); #else XPutImage(dpy, win, gc, ximage[DST], 0, 0, 0, 0, width[DST], height[DST]); #endif if(set_title) { if(magx == magy && !flipx && !flipy && !flipxy) sprintf(title, "%s x%d", progname, magx); else sprintf(title, "%s X %s%d%s Y %s%d", progname, flipx?"-":"", magx, flipxy?" <=>":";", flipy?"-":"", magy); XChangeProperty(dpy, win, XA_WM_NAME, XA_STRING, 8, PropModeReplace, (unsigned char *)title, strlen(title)); set_title = False; } #ifdef TIMER { struct timeval current_time; double DT; gettimeofday(¤t_time, NULL); DT = current_time.tv_sec - old_time.tv_sec; DT += 1e-6*(current_time.tv_usec - old_time.tv_usec); sprintf(title, "DT=%6.3f", DT); XDrawString(dpy, win, gc, 20, 20, title, strlen(title)); old_time = current_time; } #endif XSync(dpy, 0); #ifdef NO_USLEEP #define usleep(_t) \ { \ struct timeval timeout; \ timeout.tv_sec = 0; \ timeout.tv_usec = _t; \ select(0, NULL, NULL, NULL, &timeout); \ } #endif if(!buttonpressed && delay > 0) usleep(delay); #ifdef FRAME if(buttonpressed) /* erase the frame */ DRAW_FRAME(); #endif } } xzoom-0.3.orig/xzoom.lsm100644 764 764 1266 6153247311 13556 0ustar joeyjoeyBegin3 Title: xzoom Version: 0.3 Entered-date: May 30 1996 Description: xzoom can magnify (by integer value) rotate (by a multiple if 90 degrees) and mirror about the X or Y axes areas on X11 screen and display them in it's window. Keywords: X11 zoom magnify xmag Author: Itai Nahshon Maintained-by: Itai Nahshon Primary-site: sunsite.unc.edu probably in /pub/Linux/X11/xutils/xzoom-0.3.tgz Platforms: Linux+11. Support only for 8-bit depth. Tested only in Linux pre-2.0.* with the XSVGA 3.1.2 driver. Needs the XSHM extension. Copying-policy: Free End xzoom-0.3.orig/xzoom.man100644 764 764 12240 6135217134 13550 0ustar joeyjoey.\" xzoom.man .\" Copyright Itai Nahshon .\" .TH XZOOM 1X .SH NAME xzoom \- .SH SYNOPSIS .B xzoom [ \-display \fIdisplayname\fP ] [ \-mag \fImag\fP [ \fImag\fP ] ] [ \-x ] [ \-y ] [ \-xy ] [ \-geometry \fIgeometry\fP ] [ \-source \fIgeometry\fP ] .SH OPTIONS .LP .TP 5 .B \-display \fIdisplayname\fP \fR|\fP \-d \fIdisplayname\fP The name of the display to use (not very useful). .TP 5 .B \-mag \fImag\fP [ \fImag\fP ] What magnification to use. If two number arguments are supplied the first is used for X magniications and the second is used for Y magnification. Magnification should be greater than 0. .TP 5 .B \-x Mirror horizontally. .TP 5 .B \-y Mirror vertically. .TP 5 .B \-xy \fR|\fP \-z Exchange X and Y axes before any magnification is performed. .TP 5 .B \-geometry \fIgeometry\fP \fR|\fP =\fIgeometry\fP Size and position \fBxzoom\fR's window. .TP 5 .B \-source \fIgeometry\fP Size and position the initial source area which is magnified. The dimensions of this area are multiplied by the magnification to get the size of \fBxzoom\fR's window. If these dimensions are given separately (by use of \-geometry ) then an error is reported. .br .SH DESCRIPTION .IR Xzoom displays in its window a magnified area of the X11 display. The user can interactively change the zoomed area, the window size, magnification (optionally different magnification for X and Y axes) or rotate or mirror the image. .SH COMMANDS .LP Once xzoom has started the user can enter simple commands using the keyboard. .LP .TP 5 .B q quit. .TP 5 .B \+ increase magnification value by 1. .TP 5 .B \- decrease magnification value by 1. .TP 5 .B w next \+ or \- command only affect X magnification. .TP 5 .B h next \+ or \- command only affect Y magnification. .TP 5 .B x mirror the display image horizontally. .TP 5 .B y mirror the display image vertically. .TP 5 .B z rotate the displayed image 90 degrees counter-clockwise. .TP 5 .B arrow keys scroll the zoomed area 1 pixel in the direction of the arrow. if the .B control key is pressed the zoomed area will scroll 10 pixels. .TP 5 .B d sets the delay between frame updates. Built-in delays are 200, 100, 50, 10 and 0 ms. .TP 5 .B Mouse buttons To set the location of the magnified are click the left mouse button inside xzoom's window and then move it (keep the button pressed) to the place which you want to see magnified. .sp 1 Xzoom allow you to resize it's window at any time. .sp 1 When xzoom is iconified it simply waits to get deiconified. .SH DISPLAYS Xzoom uses the window's title bar to inform the user about it's status. Normally the title says something like .B "xzoom x2" which means the magnification is 2 both in X and Y axes. If the image is stretched differently on the X and Y axes the title will say .B "xzoom X 2; Y 4." Negative numbers mean reflection. If the image is rotated by 90 or 270 degrees the title will show .B "<=>" between the X and Y values. .sp 1 When .B d is depressed the title will display the new delay value for approximately 2 seconds and then revert to the default display of magnification values. .SH PERFORMANCE Xzoom is fast enough to display enlarged or mirrored animations in small windows. On my 486 DX2-66 and Cirrus Logic CL-GD5428 display card (attached to Vesa local bus) update of a 256x256 window magnified by 2 (ie, source rect is 128x128) takes approximately 30 ms. This time varies, off course when a different size window or different magnification is used. If we chose 50 ms between updates we can get about 12.5 frames per second and still let an animation program do it's work. It is possible to compile xzoom without X shared memory support. In that case window update may be about 3 times slower (if we are using a local display, using LAN is a different story). .SH SEE ALSO xmag.1x. .br I got the motivation for writing xzoom after I saw a similar WindowsNT program, zoomin working. It started just as a test for X11 performance. I don't have the fancy menus and scrollbar like zoomin but I do have all their features (and more) accessible from the keyboard. .SH BUGS .LP 5 \(dg The maximum internal built in delay (see command .B d above) was set to 200 ms. Xzoom completes the delay before polling the X event queue for the next command. Larger delays would feel like poor response to user commands. .LP 5 \(dg For best performance the shared memory extension for X11 is used. Xzoom will fail if it is compiled to use XSHM and its display is not on the local host. .LP 5 \(dg The Ximage data is accessed directly, in a way which may not be portable. Xzoom will not run with display depth other than 8 bits per pixel. .LP 5 \(dg Xzoom is given with no warranty. It was tested only under Linux with Xfree86 release 3.1.2 (X11R6). .LP 5 \(dg Some strange behavior may occur if the requested magnified area falls beyond the borders of the screen. Example is when you have magnification of 1 and a window whose width is greater than the height of the screen and you want 90 degrees rotation. In that case part of the window will not get updated. .LP 5 \(dg The frame used to mark the zoomed area may corrupt the contents of other windows if they are modified when the frame is visible. If you don't like it disable the \-DFRAME option when compiling xzoom. .SH AUTHOR Itai Nahshon xzoom-0.3.orig/README100644 764 764 1734 6153252113 12541 0ustar joeyjoeyThis is xzoom 0.3. I got a few letters from people who tried xzoom-0.1. I want to thank all these people for the responses. Some people have requested to add features. Some also suggested their own contribution. I am sory that I could not satisfy all. I will try to do so in the next releases. What's changed since release 0.1: Mainly I added command line options. With these you can start xzoom and focus at any point in the screen and at any magnification which you want. Look at the man page for details. A second thing that you might have noticed is a memory leak in 0.1 (funny, I did not get any mail about it). As I finally found, the leak was due to some X events queing up and not discarded. Finally I found the documentation for XSHM in the X11R6 CDROM (disk 2, file distrib/xc/doc/specs/Xext/mit-shm.ms). The MS macros came from the BSD cdrom and with that help I could find the bug and fix it. Plese send comments, requests, suggestions to nahshon@best.com. Itai Nahshon