diff options
Diffstat (limited to 'krdc/vnc/desktop.c')
-rw-r--r-- | krdc/vnc/desktop.c | 1613 |
1 files changed, 0 insertions, 1613 deletions
diff --git a/krdc/vnc/desktop.c b/krdc/vnc/desktop.c deleted file mode 100644 index 73b2e423..00000000 --- a/krdc/vnc/desktop.c +++ /dev/null @@ -1,1613 +0,0 @@ -/* - * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. - * Copyright (C) 2002 Tim Jansen. All Rights Reserved. - * Copyright (C) 1999-2001 Anders Lindstr�m - * - * - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - * - * [email protected]: - removed stuff for krdc - * - merged with shm.c and misc.c - * - added FillRectangle and Sync methods to draw only on - * the image - * - added Zoom functionality, based on rotation funcs from - * SGE by Anders Lindstr�m) - * - added support for softcursor encoding - * - */ - -/* - * desktop.c - functions to deal with "desktop" window. - */ - -#include <X11/Xlib.h> -#include <sys/ipc.h> -#include <sys/shm.h> -#include <X11/extensions/XShm.h> -#include <math.h> -#include <limits.h> -#include "vncviewer.h" - -static XShmSegmentInfo shminfo; -static Bool caughtShmError = False; -static Bool needShmCleanup = False; - -static XShmSegmentInfo zoomshminfo; -static Bool caughtZoomShmError = False; -static Bool needZoomShmCleanup = False; - -static Bool gcInited = False; -GC gc; -GC srcGC, dstGC; /* used for debugging copyrect */ -Dimension dpyWidth, dpyHeight; - -static XImage *image = NULL; -Bool useShm = True; - -static Bool zoomActive = False; -static int zoomWidth, zoomHeight; -static XImage *zoomImage = NULL; -static Bool useZoomShm = True; - -/* for softcursor */ -static char *savedArea = NULL; - -typedef enum { - SOFTCURSOR_UNDER, - SOFTCURSOR_PART_UNDER, - SOFTCURSOR_UNAFFECTED -} SoftCursorState; - -typedef int Sint32; -typedef short Sint16; -typedef char Sint8; -typedef unsigned int Uint32; -typedef unsigned short Uint16; -typedef unsigned char Uint8; - -typedef struct { - int w, h; - unsigned int pitch; - void *pixels; - int BytesPerPixel; -} Surface; - -typedef struct { - Sint16 x, y; - Uint16 w, h; -} Rect; - -static void bgr233cpy(CARD8 *dst, CARD8 *src, int len); -static void CopyDataToScreenRaw(char *buf, int x, int y, int width, int height); -static void CopyBGR233ToScreen(CARD8 *buf, int x, int y, int width,int height); -static void FillRectangleBGR233(CARD8 buf, int x, int y, int width,int height); -static int CheckRectangle(int x, int y, int width, int height); -static SoftCursorState getSoftCursorState(int x, int y, int width, int height); -static void discardCursorSavedArea(void); -static void saveCursorSavedArea(void); - -static void ZoomInit(void); -static void transformZoomSrc(int six, int siy, int siw, int sih, - int *dix, int *diy, int *diw, int *dih, - int srcW, int dstW, int srcH, int dstH); -static void transformZoomDst(int *six, int *siy, int *siw, int *sih, - int dix, int diy, int diw, int dih, - int srcW, int dstW, int srcH, int dstH); -static void ZoomSurfaceSrcCoords(int x, int y, int w, int h, - int *dix, int *diy, int *diw, int *dih, - Surface * src, Surface * dst); -static void ZoomSurfaceCoords32(int sx, int sy, int sw, int sh, - int dx, int dy, Surface * src, Surface * dst); -static void sge_transform(Surface *src, Surface *dst, float xscale, float yscale, - Uint16 qx, Uint16 qy); - - -void -DesktopInit(Window win) -{ - XGCValues gcv; - - image = CreateShmImage(); - - if (!image) { - useShm = False; - image = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL, - si.framebufferWidth, si.framebufferHeight, - BitmapPad(dpy), 0); - - image->data = calloc(image->bytes_per_line * image->height, 1); - if (!image->data) { - fprintf(stderr,"malloc failed\n"); - exit(1); - } - } - - gc = XCreateGC(dpy,win,0,NULL); - - gcv.function = GXxor; - gcv.foreground = 0x0f0f0f0f; - srcGC = XCreateGC(dpy,win,GCFunction|GCForeground,&gcv); - gcv.foreground = 0xf0f0f0f0; - dstGC = XCreateGC(dpy,win,GCFunction|GCForeground,&gcv); - gcInited = True; -} - -/* - * DrawScreenRegionX11Thread - * Never call from any other desktop.c function, only for X11 thread - */ - -void -DrawScreenRegionX11Thread(Window win, int x, int y, int width, int height) { - zoomActive = False; - zoomWidth = 0; - zoomHeight = 0; - - if (!image) - return; - - if (useShm) - XShmPutImage(dpy, win, gc, image, x, y, x, y, width, height, False); - else - XPutImage(dpy, win, gc, image, x, y, x, y, width, height); -} - -/* - * CheckRectangle - */ - -static int CheckRectangle(int x, int y, int width, int height) { - if ((x < 0) || (y < 0)) - return 0; - - if (((x+width) > si.framebufferWidth) || ((y+height) > si.framebufferHeight)) - return 0; - - return 1; -} - -static -void bgr233cpy(CARD8 *dst, CARD8 *src, int len) { - int i; - CARD16 *d16; - CARD32 *d32; - - switch (visbpp) { - case 8: - for (i = 0; i < len; i++) - *(dst++) = (CARD8) BGR233ToPixel[*(src++)]; - break; - case 16: - d16 = (CARD16*) dst; - for (i = 0; i < len; i++) - *(d16++) = (CARD16) BGR233ToPixel[*(src++)]; - break; - case 32: - d32 = (CARD32*) dst; - for (i = 0; i < len; i++) - *(d32++) = (CARD32) BGR233ToPixel[*(src++)]; - break; - default: - fprintf(stderr, "Unsupported softcursor depth %d\n", visbpp); - } -} - - -/* - * CopyDataToScreen. - */ - -void -CopyDataToScreen(char *buf, int x, int y, int width, int height) -{ - SoftCursorState s; - - if (!CheckRectangle(x, y, width, height)) - return; - - LockFramebuffer(); - s = getSoftCursorState(x, y, width, height); - if (s == SOFTCURSOR_PART_UNDER) - undrawCursor(); - - if (!appData.useBGR233) - CopyDataToScreenRaw(buf, x, y, width, height); - else - CopyBGR233ToScreen((CARD8 *)buf, x, y, width, height); - - if (s != SOFTCURSOR_UNAFFECTED) - drawCursor(); - - UnlockFramebuffer(); - SyncScreenRegion(x, y, width, height); -} - -/* - * CopyDataToScreenRaw. - */ - -static void -CopyDataToScreenRaw(char *buf, int x, int y, int width, int height) -{ - int h; - int widthInBytes = width * visbpp / 8; - int scrWidthInBytes = image->bytes_per_line; - char *scr = (image->data + y * scrWidthInBytes - + x * visbpp / 8); - - for (h = 0; h < height; h++) { - memcpy(scr, buf, widthInBytes); - buf += widthInBytes; - scr += scrWidthInBytes; - } -} - -/* - * CopyBGR233ToScreen. - */ - -static void -CopyBGR233ToScreen(CARD8 *buf, int x, int y, int width, int height) -{ - int p, q; - int xoff = 7 - (x & 7); - int xcur; - int fbwb = si.framebufferWidth / 8; - CARD8 *scr1 = ((CARD8 *)image->data) + y * fbwb + x / 8; - CARD8 *scrt; - CARD8 *scr8 = ((CARD8 *)image->data) + y * si.framebufferWidth + x; - CARD16 *scr16 = ((CARD16 *)image->data) + y * si.framebufferWidth + x; - CARD32 *scr32 = ((CARD32 *)image->data) + y * si.framebufferWidth + x; - - switch (visbpp) { - - /* thanks to Chris Hooper for single bpp support */ - - case 1: - for (q = 0; q < height; q++) { - xcur = xoff; - scrt = scr1; - for (p = 0; p < width; p++) { - *scrt = ((*scrt & ~(1 << xcur)) - | (BGR233ToPixel[*(buf++)] << xcur)); - - if (xcur-- == 0) { - xcur = 7; - scrt++; - } - } - scr1 += fbwb; - } - break; - - case 8: - for (q = 0; q < height; q++) { - for (p = 0; p < width; p++) { - *(scr8++) = BGR233ToPixel[*(buf++)]; - } - scr8 += si.framebufferWidth - width; - } - break; - - case 16: - for (q = 0; q < height; q++) { - for (p = 0; p < width; p++) { - *(scr16++) = BGR233ToPixel[*(buf++)]; - } - scr16 += si.framebufferWidth - width; - } - break; - - case 32: - for (q = 0; q < height; q++) { - for (p = 0; p < width; p++) { - *(scr32++) = BGR233ToPixel[*(buf++)]; - } - scr32 += si.framebufferWidth - width; - } - break; - } -} - -/* - * FillRectangle8. - */ - -void -FillRectangle8(CARD8 fg, int x, int y, int width, int height) -{ - SoftCursorState s; - - if (!CheckRectangle(x, y, width, height)) - return; - - s = getSoftCursorState(x, y, width, height); - if (s == SOFTCURSOR_PART_UNDER) - undrawCursor(); - - if (!appData.useBGR233) { - int h; - int widthInBytes = width * visbpp / 8; - int scrWidthInBytes = image->bytes_per_line; - - char *scr = (image->data + y * scrWidthInBytes - + x * visbpp / 8); - - for (h = 0; h < height; h++) { - memset(scr, fg, widthInBytes); - scr += scrWidthInBytes; - } - } else { - FillRectangleBGR233(fg, x, y, width, height); - } - - if (s != SOFTCURSOR_UNAFFECTED) - drawCursor(); -} - -/* - * FillRectangleBGR233. - */ - -static void -FillRectangleBGR233(CARD8 fg, int x, int y, int width, int height) -{ - int p, q; - int xoff = 7 - (x & 7); - int xcur; - int fbwb = si.framebufferWidth / 8; - CARD8 *scr1 = ((CARD8 *)image->data) + y * fbwb + x / 8; - CARD8 *scrt; - CARD8 *scr8 = ((CARD8 *)image->data) + y * si.framebufferWidth + x; - CARD16 *scr16 = ((CARD16 *)image->data) + y * si.framebufferWidth + x; - CARD32 *scr32 = ((CARD32 *)image->data) + y * si.framebufferWidth + x; - - unsigned long fg233 = BGR233ToPixel[fg]; - - switch (visbpp) { - - /* thanks to Chris Hooper for single bpp support */ - - case 1: - for (q = 0; q < height; q++) { - xcur = xoff; - scrt = scr1; - for (p = 0; p < width; p++) { - *scrt = ((*scrt & ~(1 << xcur)) - | (fg233 << xcur)); - - if (xcur-- == 0) { - xcur = 7; - scrt++; - } - } - scr1 += fbwb; - } - break; - - case 8: - for (q = 0; q < height; q++) { - for (p = 0; p < width; p++) { - *(scr8++) = fg233; - } - scr8 += si.framebufferWidth - width; - } - break; - - case 16: - for (q = 0; q < height; q++) { - for (p = 0; p < width; p++) { - *(scr16++) = fg233; - } - scr16 += si.framebufferWidth - width; - } - break; - - case 32: - for (q = 0; q < height; q++) { - for (p = 0; p < width; p++) { - *(scr32++) = fg233; - } - scr32 += si.framebufferWidth - width; - } - break; - } -} - -/* - * FillRectangle16 - */ - -void -FillRectangle16(CARD16 fg, int x, int y, int width, int height) -{ - int i, h; - int scrWidthInBytes = image->bytes_per_line; - - char *scr = (image->data + y * scrWidthInBytes - + x * visbpp / 8); - CARD16 *scr16; - SoftCursorState s; - - if (!CheckRectangle(x, y, width, height)) - return; - - s = getSoftCursorState(x, y, width, height); - if (s == SOFTCURSOR_PART_UNDER) - undrawCursor(); - - for (h = 0; h < height; h++) { - scr16 = (CARD16*) scr; - for (i = 0; i < width; i++) - scr16[i] = fg; - scr += scrWidthInBytes; - } - - if (s != SOFTCURSOR_UNAFFECTED) - drawCursor(); -} - -/* - * FillRectangle32 - */ - -void -FillRectangle32(CARD32 fg, int x, int y, int width, int height) -{ - int i, h; - int scrWidthInBytes = image->bytes_per_line; - SoftCursorState s; - - char *scr = (image->data + y * scrWidthInBytes - + x * visbpp / 8); - CARD32 *scr32; - - if (!CheckRectangle(x, y, width, height)) - return; - - s = getSoftCursorState(x, y, width, height); - if (s == SOFTCURSOR_PART_UNDER) - undrawCursor(); - - for (h = 0; h < height; h++) { - scr32 = (CARD32*) scr; - for (i = 0; i < width; i++) - scr32[i] = fg; - scr += scrWidthInBytes; - } - - if (s != SOFTCURSOR_UNAFFECTED) - drawCursor(); -} - -/* - * CopyDataFromScreen. - */ - -void -CopyDataFromScreen(char *buf, int x, int y, int width, int height) -{ - int widthInBytes = width * visbpp / 8; - int scrWidthInBytes = image->bytes_per_line; - char *src = (image->data + y * scrWidthInBytes - + x * visbpp / 8); - int h; - - if (!CheckRectangle(x, y, width, height)) - return; - - for (h = 0; h < height; h++) { - memcpy(buf, src, widthInBytes); - src += scrWidthInBytes; - buf += widthInBytes; - } -} - -/* - * CopyArea - */ - -void -CopyArea(int srcX, int srcY, int width, int height, int x, int y) -{ - int widthInBytes = width * visbpp / 8; - SoftCursorState sSrc, sDst; - - LockFramebuffer(); - sSrc = getSoftCursorState(srcX, srcY, width, height); - sDst = getSoftCursorState(x, y, width, height); - if ((sSrc != SOFTCURSOR_UNAFFECTED) || - (sDst == SOFTCURSOR_PART_UNDER)) - undrawCursor(); - - if ((srcY+height < y) || (y+height < srcY) || - (srcX+width < x) || (x+width < srcX)) { - - int scrWidthInBytes = image->bytes_per_line; - char *src = (image->data + srcY * scrWidthInBytes - + srcX * visbpp / 8); - char *dst = (image->data + y * scrWidthInBytes - + x * visbpp / 8); - int h; - - if (!CheckRectangle(srcX, srcY, width, height)) { - UnlockFramebuffer(); - return; - } - if (!CheckRectangle(x, y, width, height)) { - UnlockFramebuffer(); - return; - } - - for (h = 0; h < height; h++) { - memcpy(dst, src, widthInBytes); - src += scrWidthInBytes; - dst += scrWidthInBytes; - } - } - else { - char *buf = malloc(widthInBytes*height); - if (!buf) { - UnlockFramebuffer(); - fprintf(stderr, "Out of memory, CopyArea impossible\n"); - return; - } - CopyDataFromScreen(buf, srcX, srcY, width, height); - CopyDataToScreenRaw(buf, x, y, width, height); - free(buf); - } - if ((sSrc != SOFTCURSOR_UNAFFECTED) || - (sDst != SOFTCURSOR_UNAFFECTED)) - drawCursor(); - UnlockFramebuffer(); - SyncScreenRegion(x, y, width, height); -} - -void SyncScreenRegion(int x, int y, int width, int height) { - int dx, dy, dw, dh; - - if (zoomActive) { - Surface src, dest; - src.w = si.framebufferWidth; - src.h = si.framebufferHeight; - src.pitch = image->bytes_per_line; - src.pixels = image->data; - src.BytesPerPixel = visbpp / 8; - dest.w = zoomWidth; - dest.h = zoomHeight; - dest.pitch = zoomImage->bytes_per_line; - dest.pixels = zoomImage->data; - dest.BytesPerPixel = visbpp / 8; - ZoomSurfaceSrcCoords(x, y, width, height, &dx, &dy, &dw, &dh, &src, &dest); - } - else { - dx = x; dy = y; - dw = width; dh = height; - } - DrawScreenRegion(dx, dy, dw, dh); -} - -void SyncScreenRegionX11Thread(int x, int y, int width, int height) { - int dx, dy, dw, dh; - - if (zoomActive) { - Surface src, dest; - src.w = si.framebufferWidth; - src.h = si.framebufferHeight; - src.pitch = image->bytes_per_line; - src.pixels = image->data; - src.BytesPerPixel = visbpp / 8; - dest.w = zoomWidth; - dest.h = zoomHeight; - dest.pitch = zoomImage->bytes_per_line; - dest.pixels = zoomImage->data; - dest.BytesPerPixel = visbpp / 8; - ZoomSurfaceSrcCoords(x, y, width, height, &dx, &dy, &dw, &dh, &src, &dest); - } - else { - dx = x; dy = y; - dw = width; dh = height; - } - DrawAnyScreenRegionX11Thread(dx, dy, dw, dh); -} - -/* - * ToplevelInitBeforeRealization sets the title, geometry and other resources - * on the toplevel window. - */ - -void -ToplevelInit() -{ - dpyWidth = WidthOfScreen(DefaultScreenOfDisplay(dpy)); - dpyHeight = HeightOfScreen(DefaultScreenOfDisplay(dpy)); -} - -/* - * Cleanup - perform shm cleanup operations prior to exiting. - */ - -void -Cleanup() -{ - if (useShm || useZoomShm) - ShmCleanup(); -} - -void -ShmCleanup() -{ - fprintf(stderr,"ShmCleanup called\n"); - if (needShmCleanup) { - shmdt(shminfo.shmaddr); - shmctl(shminfo.shmid, IPC_RMID, 0); - needShmCleanup = False; - } - if (needZoomShmCleanup) { - shmdt(zoomshminfo.shmaddr); - shmctl(zoomshminfo.shmid, IPC_RMID, 0); - needZoomShmCleanup = False; - } -} - -static int -ShmCreationXErrorHandler(Display *d, XErrorEvent *e) -{ - caughtShmError = True; - return 0; -} - -XImage * -CreateShmImage() -{ - XImage *_image; - XErrorHandler oldXErrorHandler; - - if (!XShmQueryExtension(dpy)) - return NULL; - - _image = XShmCreateImage(dpy, vis, visdepth, ZPixmap, NULL, &shminfo, - si.framebufferWidth, si.framebufferHeight); - if (!_image) return NULL; - - shminfo.shmid = shmget(IPC_PRIVATE, - _image->bytes_per_line * _image->height, - IPC_CREAT|0777); - - if (shminfo.shmid == -1) { - XDestroyImage(_image); - return NULL; - } - - shminfo.shmaddr = _image->data = shmat(shminfo.shmid, 0, 0); - - if (shminfo.shmaddr == (char *)-1) { - XDestroyImage(_image); - shmctl(shminfo.shmid, IPC_RMID, 0); - return NULL; - } - - shminfo.readOnly = True; - - oldXErrorHandler = XSetErrorHandler(ShmCreationXErrorHandler); - XShmAttach(dpy, &shminfo); - XSync(dpy, False); - XSetErrorHandler(oldXErrorHandler); - - if (caughtShmError) { - XDestroyImage(_image); - shmdt(shminfo.shmaddr); - shmctl(shminfo.shmid, IPC_RMID, 0); - return NULL; - } - - needShmCleanup = True; - - fprintf(stderr,"Using shared memory PutImage\n"); - - return _image; -} - -void undrawCursor() { - int x, y, w, h; - - if ((imageIndex < 0) || !savedArea) - return; - - getBoundingRectCursor(cursorX, cursorY, imageIndex, - &x, &y, &w, &h); - - if ((w < 1) || (h < 1)) - return; - - CopyDataToScreenRaw(savedArea, x, y, w, h); - discardCursorSavedArea(); -} - -static void drawCursorImage() { - int x, y, w, h, pw, pixelsLeft, processingMask; - int skipLeft, skipRight; - PointerImage *pi = &pointerImages[imageIndex]; - CARD8 *img = (CARD8*) pi->image; - CARD8 *imgEnd = &img[pi->len]; - CARD8 *fb; - - /* check whether the source image has ended (image broken) */ -#define CHECK_IMG(x) if (&img[x] > imgEnd) goto imgError - -/* check whether the end of the framebuffer has been reached (last line) */ -#define CHECK_END() if ((wl == 0) && (h == 1)) return - -/* skip x pixels in the source (x must be < pixelsLeft!) */ -#define SKIP_IMG(x) if ((x > 0) && !processingMask) { \ - CHECK_END(); \ - img += pw * x; \ - CHECK_IMG(0); \ - } - -/* skip x pixels in source and destination */ -#define SKIP_PIXELS(x) { int wl = x; \ - while (pixelsLeft <= wl) { \ - wl -= pixelsLeft; \ - SKIP_IMG(pixelsLeft); \ - CHECK_END(); \ - pixelsLeft = *(img++); \ - CHECK_IMG(0); \ - processingMask = processingMask ? 0 : 1; \ - } \ - pixelsLeft -= wl; \ - SKIP_IMG(wl); \ - } - - if (!img) - return; - - x = cursorX - pi->hotX; - y = cursorY - pi->hotY; - w = pi->w; - h = pi->h; - - if (!rectsIntersect(x, y, w, h, - 0, 0, si.framebufferWidth, si.framebufferHeight)) { - fprintf(stderr, "intersect abort\n"); - return; - } - - pw = myFormat.bitsPerPixel / 8; - processingMask = 1; - pixelsLeft = *(img++); - -/* at this point everything is initialized for the macros */ - - /* skip/clip bottom lines */ - if ((y+h) > si.framebufferHeight) - h = si.framebufferHeight - y; - - /* Skip invisible top lines */ - while (y < 0) { - SKIP_PIXELS(w); - y++; - h--; - } - - /* calculate left/right clipping */ - if (x < 0) { - skipLeft = -x; - w += x; - x = 0; - } - else - skipLeft = 0; - - if ((x+w) > si.framebufferWidth) { - skipRight = (x+w) - si.framebufferWidth; - w = si.framebufferWidth - x; - } - else - skipRight = 0; - - fb = (CARD8*) image->data + y * image->bytes_per_line + x * visbpp / 8; - - /* Paint the thing */ - while (h > 0) { - SKIP_PIXELS(skipLeft); - - { - CARD8 *fbx = fb; - int wl = w; - while (pixelsLeft <= wl) { - wl -= pixelsLeft; - if ((pixelsLeft > 0) && !processingMask) { - int pl = pw * pixelsLeft; - CHECK_IMG(pl); - if (!appData.useBGR233) - memcpy(fbx, img, pl); - else - bgr233cpy(fbx, img, pixelsLeft); - img += pl; - } - - CHECK_END(); - fbx += pixelsLeft * visbpp / 8; - pixelsLeft = *(img++); - - CHECK_IMG(0); - processingMask = processingMask ? 0 : 1; - } - pixelsLeft -= wl; - if ((wl > 0) && !processingMask) { - int pl = pw * wl; - CHECK_IMG(pl); - if (!appData.useBGR233) - memcpy(fbx, img, pl); - else - bgr233cpy(fbx, img, wl); - img += pl; - } - } - - SKIP_PIXELS(skipRight); - fb += image->bytes_per_line; - h--; - } - return; - -imgError: - fprintf(stderr, "Error in softcursor image %d\n", imageIndex); - pointerImages[imageIndex].set = 0; -} - -static void discardCursorSavedArea() { - if (savedArea) - free(savedArea); - savedArea = 0; -} - -static void saveCursorSavedArea() { - int x, y, w, h; - - if (imageIndex < 0) - return; - getBoundingRectCursor(cursorX, cursorY, imageIndex, - &x, &y, &w, &h); - if ((w < 1) || (h < 1)) - return; - discardCursorSavedArea(); - savedArea = malloc(h*image->bytes_per_line); - if (!savedArea) { - fprintf(stderr,"malloc failed, saving cursor not possible\n"); - exit(1); - } - CopyDataFromScreen(savedArea, x, y, w, h); -} - -void drawCursor() { - saveCursorSavedArea(); - drawCursorImage(); -} - -void getBoundingRectCursor(int cx, int cy, int _imageIndex, - int *x, int *y, int *w, int *h) { - int nx, ny, nw, nh; - - if ((_imageIndex < 0) || !pointerImages[_imageIndex].set) { - *x = 0; - *y = 0; - *w = 0; - *h = 0; - return; - } - - nx = cx - pointerImages[_imageIndex].hotX; - ny = cy - pointerImages[_imageIndex].hotY; - nw = pointerImages[_imageIndex].w; - nh = pointerImages[_imageIndex].h; - if (nx < 0) { - nw += nx; - nx = 0; - } - if (ny < 0) { - nh += ny; - ny = 0; - } - if ((nx+nw) > si.framebufferWidth) - nw = si.framebufferWidth - nx; - if ((ny+nh) > si.framebufferHeight) - nh = si.framebufferHeight - ny; - if ((nw <= 0) || (nh <= 0)) { - *x = 0; - *y = 0; - *w = 0; - *h = 0; - return; - } - - *x = nx; - *y = ny; - *w = nw; - *h = nh; -} - -static SoftCursorState getSoftCursorState(int x, int y, int w, int h) { - int cx, cy, cw, ch; - - if (imageIndex < 0) - return SOFTCURSOR_UNAFFECTED; - - getBoundingRectCursor(cursorX, cursorY, imageIndex, - &cx, &cy, &cw, &ch); - - if ((cw == 0) || (ch == 0)) - return SOFTCURSOR_UNAFFECTED; - - if (!rectsIntersect(x, y, w, h, cx, cy, cw, ch)) - return SOFTCURSOR_UNAFFECTED; - if (rectContains(x, y, w, h, cx, cy, cw, ch)) - return SOFTCURSOR_UNDER; - else - return SOFTCURSOR_PART_UNDER; -} - -int rectsIntersect(int x, int y, int w, int h, - int x2, int y2, int w2, int h2) { - if (x2 >= (x+w)) - return 0; - if (y2 >= (y+h)) - return 0; - if ((x2+w2) <= x) - return 0; - if ((y2+h2) <= y) - return 0; - return 1; -} - -int rectContains(int outX, int outY, int outW, int outH, - int inX, int inY, int inW, int inH) { - if (inX < outX) - return 0; - if (inY < outY) - return 0; - if ((inX+inW) > (outX+outW)) - return 0; - if ((inY+inH) > (outY+outH)) - return 0; - return 1; -} - -void rectsJoin(int *nx1, int *ny1, int *nw1, int *nh1, - int x2, int y2, int w2, int h2) { - int ox, oy, ow, oh; - ox = *nx1; - oy = *ny1; - ow = *nw1; - oh = *nh1; - - if (x2 < ox) { - ow += ox - x2; - ox = x2; - } - if (y2 < oy) { - oh += oy - y2; - oy = y2; - } - if ((x2+w2) > (ox+ow)) - ow = (x2+w2) - ox; - if ((y2+h2) > (oy+oh)) - oh = (y2+h2) - oy; - - *nx1 = ox; - *ny1 = oy; - *nw1 = ow; - *nh1 = oh; -} - -XImage * -CreateShmZoomImage() -{ - XImage *_image; - XErrorHandler oldXErrorHandler; - - if (!XShmQueryExtension(dpy)) - return NULL; - - _image = XShmCreateImage(dpy, vis, visdepth, ZPixmap, NULL, &zoomshminfo, - si.framebufferWidth, si.framebufferHeight); - if (!_image) return NULL; - - zoomshminfo.shmid = shmget(IPC_PRIVATE, - _image->bytes_per_line * _image->height, - IPC_CREAT|0777); - - if (zoomshminfo.shmid == -1) { - XDestroyImage(_image); - return NULL; - } - - zoomshminfo.shmaddr = _image->data = shmat(zoomshminfo.shmid, 0, 0); - - if (zoomshminfo.shmaddr == (char *)-1) { - XDestroyImage(_image); - shmctl(zoomshminfo.shmid, IPC_RMID, 0); - return NULL; - } - - zoomshminfo.readOnly = True; - - oldXErrorHandler = XSetErrorHandler(ShmCreationXErrorHandler); - XShmAttach(dpy, &zoomshminfo); - XSync(dpy, False); - XSetErrorHandler(oldXErrorHandler); - - if (caughtZoomShmError) { - XDestroyImage(_image); - shmdt(zoomshminfo.shmaddr); - shmctl(zoomshminfo.shmid, IPC_RMID, 0); - return NULL; - } - - needZoomShmCleanup = True; - - fprintf(stderr,"Using shared memory PutImage\n"); - - return _image; -} - - -/* - * DrawZoomedScreenRegionX11Thread - * Never call from any other desktop.c function, only for X11 thread - */ - -void -DrawZoomedScreenRegionX11Thread(Window win, int zwidth, int zheight, - int x, int y, int width, int height) { - if (!image) - return; - - if (zwidth > si.framebufferWidth) - zwidth = si.framebufferWidth; - if (zheight > si.framebufferHeight) - zheight = si.framebufferHeight; - - if (!zoomActive) { - ZoomInit(); - zoomActive = True; - } - - if ((zoomWidth != zwidth) || (zoomHeight != zheight)) { - Surface src, dest; - - zoomWidth = zwidth; - zoomHeight = zheight; - - src.w = si.framebufferWidth; - src.h = si.framebufferHeight; - src.pitch = image->bytes_per_line; - src.pixels = image->data; - src.BytesPerPixel = visbpp / 8; - dest.w = zwidth; - dest.h = zheight; - dest.pitch = zoomImage->bytes_per_line; - dest.pixels = zoomImage->data; - dest.BytesPerPixel = visbpp / 8; - sge_transform(&src, &dest, - (float)dest.w/(float)src.w, (float)dest.h/(float)src.h, - 0, 0); - - if (useZoomShm) - XShmPutImage(dpy, win, gc, zoomImage, 0, 0, 0, 0, zwidth, zheight, False); - else - XPutImage(dpy, win, gc, zoomImage, 0, 0, 0, 0, zwidth, zheight); - return; - } - - if (useZoomShm) - XShmPutImage(dpy, win, gc, zoomImage, x, y, x, y, width, height, False); - else - XPutImage(dpy, win, gc, zoomImage, x, y, x, y, width, height); -} - - -static void -ZoomInit() -{ - if (zoomImage) - return; - - zoomImage = CreateShmZoomImage(); - - if (!zoomImage) { - useZoomShm = False; - zoomImage = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL, - si.framebufferWidth, si.framebufferHeight, - BitmapPad(dpy), 0); - - zoomImage->data = calloc(zoomImage->bytes_per_line * zoomImage->height, 1); - if (!zoomImage->data) { - fprintf(stderr,"malloc failed\n"); - exit(1); - } - } -} - -static void transformZoomSrc(int six, int siy, int siw, int sih, - int *dix, int *diy, int *diw, int *dih, - int srcW, int dstW, int srcH, int dstH) { - double sx, sy, sw, sh; - double dx, dy, dw, dh; - double wq, hq; - - sx = six; sy = siy; - sw = siw; sh = sih; - - wq = ((double)dstW) / (double) srcW; - hq = ((double)dstH) / (double) srcH; - - dx = sx * wq; - dy = sy * hq; - dw = sw * wq; - dh = sh * hq; - - *dix = dx; - *diy = dy; - *diw = dw+(dx-(int)dx)+0.5; - *dih = dh+(dy-(int)dy)+0.5; -} - -static void transformZoomDst(int *six, int *siy, int *siw, int *sih, - int dix, int diy, int diw, int dih, - int srcW, int dstW, int srcH, int dstH) { - double sx, sy, sw, sh; - double dx, dy, dw, dh; - double wq, hq; - - dx = dix; dy = diy; - dw = diw; dh = dih; - - wq = ((double)dstW) / (double) srcW; - hq = ((double)dstH) / (double) srcH; - - sx = dx / wq; - sy = dy / hq; - sw = dw / wq; - sh = dh / hq; - - *six = sx; - *siy = sy; - *siw = sw+(sx-(int)sx)+0.5; - *sih = sh+(sy-(int)sy)+0.5; -} - - -static void ZoomSurfaceSrcCoords(int six, int siy, int siw, int sih, - int *dix, int *diy, int *diw, int *dih, - Surface * src, Surface * dst) -{ - int dx, dy, dw, dh; - int sx, sy, sw, sh; - - transformZoomSrc(six, siy, siw, sih, - &dx, &dy, &dw, &dh, - src->w, dst->w, src->h, dst->h); - dx-=2; - dy-=2; - dw+=4; - dh+=4; - - if (dx < 0) - dx = 0; - if (dy < 0) - dy = 0; - if (dx+dw > dst->w) - dw = dst->w - dx; - if (dy+dh > dst->h) - dh = dst->h - dy; - - transformZoomDst(&sx, &sy, &sw, &sh, - dx, dy, dw, dh, - src->w, dst->w, src->h, dst->h); - - if (sx+sw > src->w) - sw = src->w - sx; - if (sy+sh > src->h) - sh = src->h - sy; - - ZoomSurfaceCoords32(sx, sy, sw, sh, dx, dy, src, dst); - - *dix = dx; - *diy = dy; - *diw = dw; - *dih = dh; -} - -static void ZoomSurfaceCoords32(int sx, int sy, int sw, int sh, - int dx, int dy, - Surface * src, Surface * dst) -{ - Surface s2; - - s2 = *src; - s2.pixels = ((char*)s2.pixels) + (sx * s2.BytesPerPixel) + (sy * src->pitch); - s2.w = sw; - s2.h = sh; - sge_transform(&s2, dst, - (float)dst->w/(float)src->w, (float)dst->h/(float)src->h, - dx, dy); -} - - -#define sge_clip_xmin(pnt) 0 -#define sge_clip_xmax(pnt) pnt->w -#define sge_clip_ymin(pnt) 0 -#define sge_clip_ymax(pnt) pnt->h - -/*================================================================================== -// Helper function to sge_transform() -// Returns the bounding box -//================================================================================== -*/ -static void _calcRect(Surface *src, Surface *dst, float xscale, float yscale, - Uint16 qx, Uint16 qy, - Sint16 *xmin, Sint16 *ymin, Sint16 *xmax, Sint16 *ymax) -{ - Sint16 x, y, rx, ry; - int i; - - /* Clip to src surface */ - Sint16 sxmin = sge_clip_xmin(src); - Sint16 sxmax = sge_clip_xmax(src); - Sint16 symin = sge_clip_ymin(src); - Sint16 symax = sge_clip_ymax(src); - Sint16 sx[5]; - Sint16 sy[4]; - - /* We don't really need fixed-point here - * but why not? */ - Sint32 ictx = (Sint32) (xscale * 8192.0); - Sint32 icty = (Sint32) (yscale * 8192.0); - - sx[0] = sxmin; - sx[1] = sxmax; - sx[2] = sxmin; - sx[3] = sxmax; - sy[0] = symin; - sy[1] = symax; - sy[2] = symax; - sy[3] = symin; - - /* Calculate the four corner points */ - for(i=0; i<4; i++){ - rx = sx[i]; - ry = sy[i]; - - x = (Sint16)(((ictx*rx) >> 13) + qx); - y = (Sint16)(((icty*ry) >> 13) + qy); - - - if(i==0){ - *xmax = *xmin = x; - *ymax = *ymin = y; - }else{ - if(x>*xmax) - *xmax=x; - else if(x<*xmin) - *xmin=x; - - if(y>*ymax) - *ymax=y; - else if(y<*ymin) - *ymin=y; - } - } - - /* Better safe than sorry...*/ - *xmin -= 1; - *ymin -= 1; - *xmax += 1; - *ymax += 1; - - /* Clip to dst surface */ - if( !dst ) - return; - if( *xmin < sge_clip_xmin(dst) ) - *xmin = sge_clip_xmin(dst); - if( *xmax > sge_clip_xmax(dst) ) - *xmax = sge_clip_xmax(dst); - if( *ymin < sge_clip_ymin(dst) ) - *ymin = sge_clip_ymin(dst); - if( *ymax > sge_clip_ymax(dst) ) - *ymax = sge_clip_ymax(dst); -} - - -/*================================================================================== -** Scale by scale and place at position (qx,qy). -** -** -** Developed with the help from Terry Hancock ([email protected]) -** -**==================================================================================*/ -/* First we need some macros to handle different bpp - * I'm sorry about this... - */ -#define TRANSFORM(UintXX, DIV) \ - Sint32 src_pitch=src->pitch/DIV; \ - Sint32 dst_pitch=dst->pitch/DIV; \ - UintXX *src_row = (UintXX *)src->pixels; \ - UintXX *dst_row; \ -\ - for (y=ymin; y<ymax; y++){ \ - dy = y - qy; \ -\ - sx = (Sint32)ctdx; /* Compute source anchor points */ \ - sy = (Sint32)(cty*dy); \ -\ - /* Calculate pointer to dst surface */ \ - dst_row = (UintXX *)dst->pixels + y*dst_pitch; \ -\ - for (x=xmin; x<xmax; x++){ \ - rx=(Sint16)(sx >> 13); /* Convert from fixed-point */ \ - ry=(Sint16)(sy >> 13); \ -\ - /* Make sure the source pixel is actually in the source image. */ \ - if( (rx>=sxmin) && (rx<sxmax) && (ry>=symin) && (ry<symax) ) \ - *(dst_row + x) = *(src_row + ry*src_pitch + rx); \ -\ - sx += ctx; /* Incremental transformations */ \ - } \ - } - - -/* Interpolated transform */ -#define TRANSFORM_AA(UintXX, DIV) \ - Sint32 src_pitch=src->pitch/DIV; \ - Sint32 dst_pitch=dst->pitch/DIV; \ - UintXX *src_row = (UintXX *)src->pixels; \ - UintXX *dst_row; \ - UintXX c1, c2, c3, c4;\ - Uint32 R, G, B, A=0; \ - UintXX Rmask = image->red_mask;\ - UintXX Gmask = image->green_mask;\ - UintXX Bmask = image->blue_mask;\ - UintXX Amask = 0;\ - Uint32 wx, wy;\ - Uint32 p1, p2, p3, p4;\ -\ - /* - * Interpolation: - * We calculate the distances from our point to the four nearest pixels, d1..d4. - * d(a,b) = sqrt(a�+b�) ~= 0.707(a+b) (Pythagoras (Taylor) expanded around (0.5;0.5)) - * - * 1 wx 2 - * *-|-* (+ = our point at (x,y)) - * | | | (* = the four nearest pixels) - * wy --+ | wx = float(x) - int(x) - * | | wy = float(y) - int(y) - * *---* - * 3 4 - * d1 = d(wx,wy) d2 = d(1-wx,wy) d3 = d(wx,1-wy) d4 = d(1-wx,1-wy) - * We now want to weight each pixels importance - it's vicinity to our point: - * w1=d4 w2=d3 w3=d2 w4=d1 (Yes it works... just think a bit about it) - * - * If the pixels have the colors c1..c4 then our point should have the color - * c = (w1*c1 + w2*c2 + w3*c3 + w4*c4)/(w1+w2+w3+w4) (the weighted average) - * but w1+w2+w3+w4 = 4*0.707 so we might as well write it as - * c = p1*c1 + p2*c2 + p3*c3 + p4*c4 where p1..p4 = (w1..w4)/(4*0.707) - * - * But p1..p4 are fixed point so we can just divide the fixed point constant! - * 8192/(4*0.71) = 2897 and we can skip 0.71 too (the division will cancel it everywhere) - * 8192/4 = 2048 - * - * 020102: I changed the fixed-point representation for the variables in the weighted average - * to 24.7 to avoid problems with 32bit colors. Everything else is still 18.13. This - * does however not solve the problem with 32bit RGBA colors... - */\ -\ - Sint32 one = 2048>>6; /* 1 in Fixed-point */ \ - Sint32 two = 2*2048>>6; /* 2 in Fixed-point */ \ -\ - for (y=ymin; y<ymax; y++){ \ - dy = y - qy; \ -\ - sx = (Sint32)(ctdx); /* Compute source anchor points */ \ - sy = (Sint32)(cty*dy); \ -\ - /* Calculate pointer to dst surface */ \ - dst_row = (UintXX *)dst->pixels + y*dst_pitch; \ -\ - for (x=xmin; x<xmax; x++){ \ - rx=(Sint16)(sx >> 13); /* Convert from fixed-point */ \ - ry=(Sint16)(sy >> 13); \ -\ - /* Make sure the source pixel is actually in the source image. */ \ - if( (rx>=sxmin) && (rx+1<sxmax) && (ry>=symin) && (ry+1<symax) ){ \ - wx = (sx & 0x00001FFF) >>8; /* (float(x) - int(x)) / 4 */ \ - wy = (sy & 0x00001FFF) >>8;\ -\ - p4 = wx+wy;\ - p3 = one-wx+wy;\ - p2 = wx+one-wy;\ - p1 = two-wx-wy;\ -\ - c1 = *(src_row + ry*src_pitch + rx);\ - c2 = *(src_row + ry*src_pitch + rx+1);\ - c3 = *(src_row + (ry+1)*src_pitch + rx);\ - c4 = *(src_row + (ry+1)*src_pitch + rx+1);\ -\ - /* Calculate the average */\ - R = ((p1*(c1 & Rmask) + p2*(c2 & Rmask) + p3*(c3 & Rmask) + p4*(c4 & Rmask))>>7) & Rmask;\ - G = ((p1*(c1 & Gmask) + p2*(c2 & Gmask) + p3*(c3 & Gmask) + p4*(c4 & Gmask))>>7) & Gmask;\ - B = ((p1*(c1 & Bmask) + p2*(c2 & Bmask) + p3*(c3 & Bmask) + p4*(c4 & Bmask))>>7) & Bmask;\ - if(Amask)\ - A = ((p1*(c1 & Amask) + p2*(c2 & Amask) + p3*(c3 & Amask) + p4*(c4 & Amask))>>7) & Amask;\ - \ - *(dst_row + x) = R | G | B | A;\ - } \ - sx += ctx; /* Incremental transformations */ \ - } \ - } - -void sge_transform(Surface *src, Surface *dst, float xscale, float yscale, Uint16 qx, Uint16 qy) -{ - Sint32 dy, sx, sy; - Sint16 x, y, rx, ry; - Rect r; - - Sint32 ctx, cty; - Sint16 xmin, xmax, ymin, ymax; - Sint16 sxmin, sxmax, symin, symax; - Sint32 dx, ctdx; - - - /* Here we use 18.13 fixed point integer math - // Sint32 should have 31 usable bits and one for sign - // 2^13 = 8192 - */ - - /* Check scales */ - Sint32 maxint = (Sint32)(pow(2, sizeof(Sint32)*8 - 1 - 13)); /* 2^(31-13) */ - - r.x = r.y = r.w = r.h = 0; - - if( xscale == 0 || yscale == 0) - return; - - if( 8192.0/xscale > maxint ) - xscale = (float)(8192.0/maxint); - else if( 8192.0/xscale < -maxint ) - xscale = (float)(-8192.0/maxint); - - if( 8192.0/yscale > maxint ) - yscale = (float)(8192.0/maxint); - else if( 8192.0/yscale < -maxint ) - yscale = (float)(-8192.0/maxint); - - - /* Fixed-point equivalents */ - ctx = (Sint32)(8192.0/xscale); - cty = (Sint32)(8192.0/yscale); - - /* Compute a bounding rectangle */ - xmin=0; xmax=dst->w; ymin=0; ymax=dst->h; - _calcRect(src, dst, xscale, yscale, - qx, qy, &xmin, &ymin, &xmax, &ymax); - - /* Clip to src surface */ - sxmin = sge_clip_xmin(src); - sxmax = sge_clip_xmax(src); - symin = sge_clip_ymin(src); - symax = sge_clip_ymax(src); - - /* Some terms in the transform are constant */ - dx = xmin - qx; - ctdx = ctx*dx; - - /* Use the correct bpp */ - if( src->BytesPerPixel == dst->BytesPerPixel){ - switch( src->BytesPerPixel ){ - case 1: { /* Assuming 8-bpp */ - TRANSFORM(Uint8, 1) - } - break; - case 2: { /* Probably 15-bpp or 16-bpp */ - TRANSFORM_AA(Uint16, 2) - } - break; - case 4: { /* Probably 32-bpp */ - TRANSFORM_AA(Uint32, 4) - } - break; - } - } -} - -void freeDesktopResources() { - Cleanup(); - if (image) { - XDestroyImage(image); - } - if (zoomImage) { - XDestroyImage(zoomImage); - } - if (savedArea) - free(savedArea); - - if (gcInited) { - XFreeGC(dpy, gc); - XFreeGC(dpy, srcGC); - XFreeGC(dpy, dstGC); - } - - caughtShmError = False; - needShmCleanup = False; - caughtZoomShmError = False; - needZoomShmCleanup = False; - gcInited = False; - image = NULL; - useShm = True; - zoomActive = False; - zoomImage = NULL; - useZoomShm = True; - savedArea = NULL; -} - - -/* - * ColorRectangle32 - * Only used for debugging / visualizing output - */ -/* -static void -ColorRectangle32(XImage *img, CARD32 fg, int x, int y, int width, int height) -{ - int i, h; - int scrWidthInBytes = img->bytes_per_line; - char *scr; - CARD32 *scr32; - - if ((!img) || (!img->data)) - return; - - scr = (img->data + y * scrWidthInBytes + x * 4); - - if (!CheckRectangle(x, y, width, height)) - return; - - for (h = 0; h < height; h++) { - scr32 = (CARD32*) scr; - for (i = 0; i < width; i++) { - CARD32 n = 0; - CARD32 p = scr32[i]; - if (0xff & fg) - n |= ((( 0xff & p)+( 0xff & fg)) >> 2) & 0xff; - else - n |= (0xff & p); - if (0xff00 & fg) - n |= ((( 0xff00 & p)+( 0xff00 & fg)) >> 2) & 0xff00; - else - n |= (0xff00 & p); - if (0xff0000 & fg) - n |= (((0xff0000 & p)+(0xff0000 & fg)) >> 2) & 0xff0000; - else - n |= (0xff0000 & p); - scr32[i] = n; - } - scr += scrWidthInBytes; - } -} -*/ - |