On Sun, June 14, 2020 11:54, Kirill Bychkov wrote:
> Hi!
> Recently I was looking for some zooming tool in our ports and found xzoom.
> It looks like it wasn't used by anyone for a long time. These days noone
> uses 8bpp in desktop I gusess. This patch adds support for 15, 16, 24 and
> 32 bpp displays.
> Taken from FreeBSD.
> OK?

Ping

> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/x11/xzoom/Makefile,v
> retrieving revision 1.20
> diff -u -p -u -p -r1.20 Makefile
> --- Makefile  14 Jul 2019 00:39:40 -0000      1.20
> +++ Makefile  30 May 2020 10:04:02 -0000
> @@ -3,7 +3,7 @@
>  COMMENT=     magnify, rotate, mirror the image on the X11 screen
>
>  DISTNAME=    xzoom-0.3
> -REVISION=    0
> +REVISION=    1
>  CATEGORIES=  x11
>
>  MASTER_SITES=        ${MASTER_SITE_SUNSITE:=libs/X/}
> Index: patches/patch-scale_h
> ===================================================================
> RCS file: patches/patch-scale_h
> diff -N patches/patch-scale_h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-scale_h     30 May 2020 10:04:02 -0000
> @@ -0,0 +1,108 @@
> +$OpenBSD$
> +
> +Index: scale.h
> +--- scale.h.orig
> ++++ scale.h
> +@@ -0,0 +1,102 @@
> ++/* scale image from SRC to DST - parameterized by type T */
> ++
> ++/* get pixel address of point (x,y) in image t */
> ++#define getP(t,x,y) \
> ++    (T *) (&ximage[t]->data[(ximage[t]->xoffset+(x))*sizeof(T) + \
> ++                            (y)*ximage[t]->bytes_per_line])
> ++
> ++{
> ++    int i, j, k;
> ++
> ++    /* copy scaled lines from SRC to DST */
> ++    j = flipxy ? width[SRC] - 1 : height[SRC] - 1;
> ++    do {
> ++            T *p1;
> ++            T *p2;
> ++            int p2step;
> ++            T *p1_save;
> ++
> ++            /* p1 point to begining of scanline j*magy in DST */
> ++            p1 = getP(DST,0,j*magy);
> ++            p1_save = p1;
> ++            /* p2 point to begining of scanline j in SRC */
> ++            /* if flipy then line height[SRC]-1-j */
> ++            p2 = getP(SRC,0,flipy ? (height[SRC]-1-j) : j);
> ++
> ++            if (flipxy)
> ++            {
> ++                    p2 = getP(SRC,flipy ? j : (width[SRC]-1-j),0);
> ++                    p2step = ximage[SRC]->bytes_per_line / sizeof(T);
> ++
> ++                    if (flipx)
> ++                    {
> ++                            p2 += p2step * (height[SRC]-1);
> ++                            p2step = -p2step;
> ++                    }
> ++
> ++                    i = height[SRC];
> ++                    do {
> ++                            T c = *p2; p2 += p2step;
> ++                            k = magx; do *p1++ = c; while (--k > 0);
> ++                    } while (--i > 0);
> ++            }
> ++            else if (flipx)
> ++            {
> ++                    p2 += width[SRC];
> ++                    i = width[SRC];
> ++                    do {
> ++                            T c = *--p2;
> ++                            k = magx; do *p1++ = c; while (--k > 0);
> ++                    } while (--i > 0);
> ++            }
> ++            else
> ++            {
> ++                    i = width[SRC];
> ++                    do {
> ++                            T c = *p2++;
> ++                            k = magx; do *p1++ = c; while (--k > 0);
> ++                    } while (--i > 0);
> ++            }
> ++
> ++            /* draw vertical grid */
> ++            if (gridy && magx >= 2)
> ++            {
> ++                    p1 = p1_save - 1;
> ++                    i = magx;
> ++                    k = flipxy ? height[SRC] : width[SRC];
> ++                    do {
> ++                            p1 += i;
> ++                            *p1 ^= ~((T)0);
> ++                    } while (--k > 0);
> ++            }
> ++
> ++            /* duplicate that line as needed */
> ++            if (magy > 1)
> ++            {
> ++                    /* p1 point to begining of scanline j*magy in DST */
> ++                    p1 = p1_save;
> ++                    /* p2 points to begining of next line */
> ++                    p2 = p1;
> ++                    p2step = ximage[DST]->bytes_per_line / sizeof(T);
> ++
> ++                    i = width[DST] * sizeof(T);
> ++                    k = magy - 1;
> ++                    do {
> ++                            p2 += p2step;
> ++                            memcpy(p2, p1, i);
> ++                    } while (--k > 0);
> ++
> ++                    /* draw horizontal grid */
> ++                    if (gridx && magy >= 2)
> ++                    {
> ++                            k = width[DST];
> ++                            do {
> ++                                    *p2++ ^= ~((T)0);
> ++                            } while (--k > 0);
> ++                    }
> ++            }
> ++    } while (--j >= 0);
> ++}
> ++
> ++#undef getP
> ++
> Index: patches/patch-xzoom_c
> ===================================================================
> RCS file: patches/patch-xzoom_c
> diff -N patches/patch-xzoom_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-xzoom_c     30 May 2020 10:04:02 -0000
> @@ -0,0 +1,432 @@
> +$OpenBSD$
> +
> +Index: xzoom.c
> +--- xzoom.c.orig
> ++++ xzoom.c
> +@@ -12,13 +12,20 @@
> +    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 <sys/types.h>
> +-            Use memmove() instead of memcopy()
> +-            Optional macro to replace call to usleep().
> ++Author                    Description
> ++------                    -----------
> ++Itai Nahshon              Version 0.1, Nov. 21 1995
> ++Itai Nahshon              Version 0.2, Apr. 17 1996
> ++                          include <sys/types.h>
> ++                          Use memmove() instead of memcopy()
> ++                          Optional macro to replace call to usleep().
> ++Markus F.X.J. Oberhumer   Version 0.4, Feb. 18 1998
> ++                          split into 2 files (scale.h)
> ++                          added support for 15, 16, 24 and 32 bpp displays
> ++                          added a grid (press key 'g')
> ++                          optimized scaling routines
> ++                          use memcpy() instead of memmove() ;-)
> ++                          some other minor changes/fixes
> + */
> +
> + #include <stdio.h>
> +@@ -87,8 +94,12 @@ 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 gridx = False;
> ++int gridy = False;
> ++
> + int width[2] = { 0, WIDTH };
> + int height[2] = { 0, HEIGHT };
> ++unsigned depth = 0;
> +
> + #ifdef XSHM
> + XShmSegmentInfo shminfo[2];                 /* Segment info.  */
> +@@ -106,6 +117,7 @@ int delay = 200000;                      /* 0.2 second 
> between updates */
> + void
> + timeout_func(int signum) {
> +     set_title = True;
> ++    signum = signum;          /* UNUSED */
> + }
> +
> + #ifdef FRAME
> +@@ -116,9 +128,6 @@ timeout_func(int signum) {
> + void
> + allocate_images(void) {
> +     int i;
> +-#ifndef XSHM
> +-    char *data;
> +-#endif
> +
> +     for(i = 0; i < 2; i++) {
> +
> +@@ -137,7 +146,7 @@ allocate_images(void) {
> +             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);
> +@@ -163,20 +172,21 @@ allocate_images(void) {
> +
> +             shmctl(shminfo[i].shmid, IPC_RMID, 0);
> + #else
> +-            data = malloc(width[i] * height[i]);
> ++            char *data;
> ++            data = malloc(BitmapUnit(dpy) / 8 * width[i] * height[i]);
> +
> +             ximage[i] = XCreateImage(dpy,
> +                     DefaultVisualOfScreen(scr),
> +                     DefaultDepthOfScreen(scr),
> +                     ZPixmap, 0, data,
> +-                    width[i], height[i], 8, width[i]);
> ++                    width[i], height[i], 32, 0);
> +
> +             if(ximage[i] == NULL) {
> +                     perror("XCreateImage");
> +                     exit(-1);
> +             }
> +
> +-#endif XSHM
> ++#endif /* XSHM */
> +     }
> +     created_images = True;
> + }
> +@@ -185,6 +195,9 @@ void
> + destroy_images(void) {
> +     int i;
> +
> ++    if (!created_images)
> ++            return;
> ++
> +     for(i = 0; i < 2; i++) {
> + #ifdef XSHM
> +             XShmDetach(dpy, &shminfo[i]);   /* ask X11 to detach shared 
> segment */
> +@@ -195,6 +208,8 @@ destroy_images(void) {
> +             ximage[i]->data = NULL;                 /* remove refrence to 
> that address */
> +             XDestroyImage(ximage[i]);               /* and destroy image */
> +     }
> ++
> ++    created_images = False;
> + }
> +
> + void
> +@@ -230,8 +245,7 @@ Usage(void) {
> + void
> + resize(int new_width, int new_height) {
> +
> +-    if(created_images)
> +-            destroy_images();               /* we can get rid of these */
> ++    destroy_images();               /* we can get rid of these */
> +
> +     /* find new dimensions for source */
> +
> +@@ -244,9 +258,13 @@ resize(int new_width, int new_height) {
> +             height[SRC] = (new_height+magy-1) / magy;
> +     }
> +
> ++    if(width[SRC] < 1)
> ++            width[SRC] = 1;
> +     if(width[SRC] > WidthOfScreen(scr))
> +             width[SRC] = WidthOfScreen(scr);
> +
> ++    if(height[SRC] < 1)
> ++            height[SRC] = 1;
> +     if(height[SRC] > HeightOfScreen(scr))
> +             height[SRC] = HeightOfScreen(scr);
> +
> +@@ -270,12 +288,34 @@ resize(int new_width, int new_height) {
> +             height[DST] = new_height;
> + }
> +
> ++
> ++void scale8(void)
> ++{
> ++#define T unsigned char
> ++#include "scale.h"
> ++#undef T
> ++}
> ++
> ++
> ++void scale16(void)
> ++{
> ++#define T unsigned short
> ++#include "scale.h"
> ++#undef T
> ++}
> ++
> ++
> ++void scale32(void)
> ++{
> ++#define T unsigned int
> ++#include "scale.h"
> ++#undef T
> ++}
> ++
> ++
> + 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;
> +@@ -286,8 +326,9 @@ main(int argc, char **argv) {
> +     int source_geom_mask = NoValue,
> +         dest_geom_mask = NoValue,
> +         copy_from_src_mask;
> +-    int xpos = 0, ypos = 0;
> ++    int xpos = 0, ypos = 0;
> +
> ++    atexit(destroy_images);
> +     progname = strrchr(argv[0], '/');
> +     if(progname)
> +             ++progname;
> +@@ -312,8 +353,8 @@ main(int argc, char **argv) {
> +
> +                     if(magx <= 0)
> +                             Usage();
> +-
> +
> ++
> +                     magy = argc > 1 ? atoi(argv[1]) : -1;
> +
> +                     if(magy <= 0)
> +@@ -340,7 +381,7 @@ main(int argc, char **argv) {
> +                     flipxy = True;
> +                     continue;
> +             }
> +-
> ++
> +             if(!strcmp(argv[0], "-source")) {
> +                     ++argv; --argc;
> +
> +@@ -438,23 +479,24 @@ main(int argc, char **argv) {
> +
> +     scr = DefaultScreenOfDisplay(dpy);
> +
> +-    if(DefaultDepthOfScreen(scr) != 8) {
> +-            fprintf(stderr, "%s: can work only with 8 bits/pixel\n", 
> progname);
> ++    depth = DefaultDepthOfScreen(scr);
> ++    if (depth < 8) {
> ++            fprintf(stderr, "%s: need at least 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;
> +@@ -463,17 +505,17 @@ main(int argc, char **argv) {
> +     xswa.background_pixel = BlackPixelOfScreen(scr);
> +
> +     win = XCreateWindow(dpy, RootWindowOfScreen(scr),
> +-        xpos, ypos, width[DST], height[DST], 0,
> ++        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,
> ++    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,
> ++    XChangeProperty(dpy, win, XA_WM_NAME, XA_STRING, 8,
> +                     PropModeReplace,
> +                     (unsigned char *)progname, strlen(progname));
> +     */
> +@@ -512,7 +554,7 @@ main(int argc, char **argv) {
> +     {
> +             static char bitmap_data[] = { 0 };
> +             static XColor col = { 0 };
> +-            Pixmap curs = XCreatePixmapFromBitmapData(dpy,
> ++            Pixmap curs = XCreatePixmapFromBitmapData(dpy,
> +                     RootWindowOfScreen(scr), bitmap_data, 1, 1, 0, 0, 1);
> +
> +             when_button = XCreatePixmapCursor(dpy, curs, curs, &col, &col, 
> 0, 0);
> +@@ -567,6 +609,7 @@ main(int argc, char **argv) {
> +
> +                             case '+':
> +                             case '=':
> ++                            case XK_KP_Add:
> +                                     if(!yzoom_flag) ++magx;
> +                                     if(!xzoom_flag) ++magy;
> +                                     xzoom_flag = yzoom_flag = False;
> +@@ -575,6 +618,7 @@ main(int argc, char **argv) {
> +                                     break;
> +
> +                             case '-':
> ++                            case XK_KP_Subtract:
> +                                     if(!yzoom_flag) --magx;
> +                                     if(!xzoom_flag) --magy;
> +                                     xzoom_flag = yzoom_flag = False;
> +@@ -585,6 +629,7 @@ main(int argc, char **argv) {
> +                                     break;
> +
> +                             case XK_Left:
> ++                            case XK_KP_Left:
> +                                     if(flipxy)
> +                                             if(flipx)
> +                                                     ygrab += scroll;
> +@@ -598,6 +643,7 @@ main(int argc, char **argv) {
> +                                     break;
> +
> +                             case XK_Right:
> ++                            case XK_KP_Right:
> +                                     if(flipxy)
> +                                             if(flipx)
> +                                                     ygrab -= scroll;
> +@@ -611,6 +657,7 @@ main(int argc, char **argv) {
> +                                     break;
> +
> +                             case XK_Up:
> ++                            case XK_KP_Up:
> +                                     if(flipxy)
> +                                             if(flipy)
> +                                                     xgrab -= scroll;
> +@@ -624,6 +671,7 @@ main(int argc, char **argv) {
> +                                     break;
> +
> +                             case XK_Down:
> ++                            case XK_KP_Down:
> +                                     if(flipxy)
> +                                             if(flipy)
> +                                                     xgrab += scroll;
> +@@ -666,12 +714,17 @@ main(int argc, char **argv) {
> +                                     xzoom_flag = False;
> +                                     break;
> +
> ++                            case 'g':
> ++                                    gridx = !gridx;
> ++                                    gridy = !gridy;
> ++                                    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,
> ++                                    XChangeProperty(dpy, win, XA_WM_NAME, 
> XA_STRING, 8,
> +                                             PropModeReplace,
> +                                             (unsigned char *)title, 
> strlen(title));
> +                                     signal(SIGALRM, timeout_func);
> +@@ -717,6 +770,7 @@ main(int argc, char **argv) {
> + #endif
> +                             }
> +                             break;
> ++
> +                     }
> +
> +                     /* trying XShmGetImage when part of the rect is
> +@@ -736,6 +790,7 @@ main(int argc, char **argv) {
> +
> +                     if(ygrab > HeightOfScreen(scr)-height[SRC])
> +                             ygrab = HeightOfScreen(scr)-height[SRC];
> ++
> +             }
> +
> + #ifdef XSHM
> +@@ -753,64 +808,13 @@ main(int argc, char **argv) {
> +             }
> + #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 (depth == 8)
> ++                    scale8();
> ++            else if (depth <= 8*sizeof(short))
> ++                    scale16();
> ++            else if (depth <= 8*sizeof(int))
> ++                    scale32();
> +
> +-                    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
> +@@ -825,7 +829,7 @@ main(int argc, char **argv) {
> +                                             flipx?"-":"", magx,
> +                                             flipxy?" <=>":";",
> +                                             flipy?"-":"", magy);
> +-                    XChangeProperty(dpy, win, XA_WM_NAME, XA_STRING, 8,
> ++                    XChangeProperty(dpy, win, XA_WM_NAME, XA_STRING, 8,
> +                             PropModeReplace,
> +                             (unsigned char *)title, strlen(title));
> +                     set_title = False;
>
>
>


Reply via email to