?? vnchooks.cc
字號:
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */#include <stdio.h>#include "XserverDesktop.h"#include "vncHooks.h"extern "C" {#define class c_class#define private c_private#include "scrnintstr.h"#include "windowstr.h"#include "gcstruct.h"#include "regionstr.h"#include "dixfontstr.h"#include "colormapst.h"#ifdef GC_HAS_COMPOSITE_CLIP#define COMPOSITE_CLIP(gc) ((gc)->pCompositeClip)#else#include "mfb.h"#define COMPOSITE_CLIP(gc) \ (((mfbPrivGCPtr)((gc)->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip)#endif#undef class#undef private}#include "RegionHelper.h"#define DBGPRINT(x) //(fprintf x)// MAX_RECTS_PER_OP is the maximum number of rectangles we generate from// operations like Polylines and PolySegment. If the operation is more complex// than this, we simply use the bounding box. Ideally it would be a// command-line option, but that would involve an extra malloc each time, so we// fix it here.#define MAX_RECTS_PER_OP 5static unsigned long vncHooksGeneration = 0;// vncHooksScreenRec and vncHooksGCRec contain pointers to the original// functions which we "wrap" in order to hook the screen changes. The screen// functions are each wrapped individually, while the GC "funcs" and "ops" are// wrapped as a unit.typedef struct { XserverDesktop* desktop; CloseScreenProcPtr CloseScreen; CreateGCProcPtr CreateGC; PaintWindowBackgroundProcPtr PaintWindowBackground; PaintWindowBorderProcPtr PaintWindowBorder; CopyWindowProcPtr CopyWindow; ClearToBackgroundProcPtr ClearToBackground; RestoreAreasProcPtr RestoreAreas; InstallColormapProcPtr InstallColormap; StoreColorsProcPtr StoreColors; DisplayCursorProcPtr DisplayCursor; ScreenBlockHandlerProcPtr BlockHandler;} vncHooksScreenRec, *vncHooksScreenPtr;typedef struct { GCFuncs *wrappedFuncs; GCOps *wrappedOps;} vncHooksGCRec, *vncHooksGCPtr;static int vncHooksScreenIndex;static int vncHooksGCIndex;// screen functionsstatic Bool vncHooksCloseScreen(int i, ScreenPtr pScreen);static Bool vncHooksCreateGC(GCPtr pGC);static void vncHooksPaintWindowBackground(WindowPtr pWin, RegionPtr pRegion, int what);static void vncHooksPaintWindowBorder(WindowPtr pWin, RegionPtr pRegion, int what);static void vncHooksCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion);static void vncHooksClearToBackground(WindowPtr pWin, int x, int y, int w, int h, Bool generateExposures);static RegionPtr vncHooksRestoreAreas(WindowPtr pWin, RegionPtr prgnExposed);static void vncHooksInstallColormap(ColormapPtr pColormap);static void vncHooksStoreColors(ColormapPtr pColormap, int ndef, xColorItem* pdef);static Bool vncHooksDisplayCursor(ScreenPtr pScreen, CursorPtr cursor);static void vncHooksBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask);// GC "funcs"static void vncHooksValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable);static void vncHooksChangeGC(GCPtr pGC, unsigned long mask);static void vncHooksCopyGC(GCPtr src, unsigned long mask, GCPtr dst);static void vncHooksDestroyGC(GCPtr pGC);static void vncHooksChangeClip(GCPtr pGC, int type, pointer pValue,int nrects);static void vncHooksDestroyClip(GCPtr pGC);static void vncHooksCopyClip(GCPtr dst, GCPtr src);static GCFuncs vncHooksGCFuncs = { vncHooksValidateGC, vncHooksChangeGC, vncHooksCopyGC, vncHooksDestroyGC, vncHooksChangeClip, vncHooksDestroyClip, vncHooksCopyClip,};// GC "ops"static void vncHooksFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit, DDXPointPtr pptInit, int *pwidthInit, int fSorted);static void vncHooksSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc, DDXPointPtr ppt, int *pwidth, int nspans, int fSorted);static void vncHooksPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *pBits);static RegionPtr vncHooksCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty);static RegionPtr vncHooksCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty, unsigned long plane);static void vncHooksPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, xPoint *pts);static void vncHooksPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppts);static void vncHooksPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *segs);static void vncHooksPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, xRectangle *rects);static void vncHooksPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *arcs);static void vncHooksFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape, int mode, int count, DDXPointPtr pts);static void vncHooksPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrects, xRectangle *rects);static void vncHooksPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *arcs);static int vncHooksPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars);static int vncHooksPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars);static void vncHooksImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars);static void vncHooksImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars);static void vncHooksImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase);static void vncHooksPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase);static void vncHooksPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable, int w, int h, int x, int y);static GCOps vncHooksGCOps = { vncHooksFillSpans, vncHooksSetSpans, vncHooksPutImage, vncHooksCopyArea, vncHooksCopyPlane, vncHooksPolyPoint, vncHooksPolylines, vncHooksPolySegment, vncHooksPolyRectangle, vncHooksPolyArc, vncHooksFillPolygon, vncHooksPolyFillRect, vncHooksPolyFillArc, vncHooksPolyText8, vncHooksPolyText16, vncHooksImageText8, vncHooksImageText16, vncHooksImageGlyphBlt, vncHooksPolyGlyphBlt, vncHooksPushPixels};/////////////////////////////////////////////////////////////////////////////// vncHooksInit() is called at initialisation time and every time the server// resets. It is called once for each screen, but the indexes are only// allocated once for each server generation.Bool vncHooksInit(ScreenPtr pScreen, XserverDesktop* desktop){ vncHooksScreenPtr vncHooksScreen; if (vncHooksGeneration != serverGeneration) { vncHooksGeneration = serverGeneration; vncHooksScreenIndex = AllocateScreenPrivateIndex(); if (vncHooksScreenIndex < 0) { ErrorF("vncHooksInit: AllocateScreenPrivateIndex failed\n"); return FALSE; } vncHooksGCIndex = AllocateGCPrivateIndex(); if (vncHooksGCIndex < 0) { ErrorF("vncHooksInit: AllocateGCPrivateIndex failed\n"); return FALSE; } } if (!AllocateGCPrivate(pScreen, vncHooksGCIndex, sizeof(vncHooksGCRec))) { ErrorF("vncHooksInit: AllocateGCPrivate failed\n"); return FALSE; } vncHooksScreen = (vncHooksScreenPtr)xnfalloc(sizeof(vncHooksScreenRec)); pScreen->devPrivates[vncHooksScreenIndex].ptr = (pointer)vncHooksScreen; vncHooksScreen->desktop = desktop; vncHooksScreen->CloseScreen = pScreen->CloseScreen; vncHooksScreen->CreateGC = pScreen->CreateGC; vncHooksScreen->PaintWindowBackground = pScreen->PaintWindowBackground; vncHooksScreen->PaintWindowBorder = pScreen->PaintWindowBorder; vncHooksScreen->CopyWindow = pScreen->CopyWindow; vncHooksScreen->ClearToBackground = pScreen->ClearToBackground; vncHooksScreen->RestoreAreas = pScreen->RestoreAreas; vncHooksScreen->InstallColormap = pScreen->InstallColormap; vncHooksScreen->StoreColors = pScreen->StoreColors; vncHooksScreen->DisplayCursor = pScreen->DisplayCursor; vncHooksScreen->BlockHandler = pScreen->BlockHandler; pScreen->CloseScreen = vncHooksCloseScreen; pScreen->CreateGC = vncHooksCreateGC; pScreen->PaintWindowBackground = vncHooksPaintWindowBackground; pScreen->PaintWindowBorder = vncHooksPaintWindowBorder; pScreen->CopyWindow = vncHooksCopyWindow; pScreen->ClearToBackground = vncHooksClearToBackground; pScreen->RestoreAreas = vncHooksRestoreAreas; pScreen->InstallColormap = vncHooksInstallColormap; pScreen->StoreColors = vncHooksStoreColors; pScreen->DisplayCursor = vncHooksDisplayCursor; pScreen->BlockHandler = vncHooksBlockHandler; return TRUE;}///////////////////////////////////////////////////////////////////////////////// screen functions//// SCREEN_UNWRAP and SCREEN_REWRAP unwrap and rewrap the given screen function.// It would be nice to do this with a C++ class, but each function is of a// distinct type, so it would have to use templates, and it's not worth that// much pain.#define SCREEN_UNWRAP(scrn,field) \ ScreenPtr pScreen = scrn; \ vncHooksScreenPtr vncHooksScreen \ = ((vncHooksScreenPtr)pScreen->devPrivates[vncHooksScreenIndex].ptr); \ pScreen->field = vncHooksScreen->field; \ DBGPRINT((stderr,"vncHooks" #field " called\n"));#define SCREEN_REWRAP(field) pScreen->field = vncHooks##field;// CloseScreen - unwrap the screen functions and call the original CloseScreen// functionstatic Bool vncHooksCloseScreen(int i, ScreenPtr pScreen_){ SCREEN_UNWRAP(pScreen_, CloseScreen); pScreen->CreateGC = vncHooksScreen->CreateGC; pScreen->PaintWindowBackground = vncHooksScreen->PaintWindowBackground; pScreen->PaintWindowBorder = vncHooksScreen->PaintWindowBorder; pScreen->CopyWindow = vncHooksScreen->CopyWindow; pScreen->ClearToBackground = vncHooksScreen->ClearToBackground; pScreen->RestoreAreas = vncHooksScreen->RestoreAreas; pScreen->InstallColormap = vncHooksScreen->InstallColormap; pScreen->StoreColors = vncHooksScreen->StoreColors; pScreen->DisplayCursor = vncHooksScreen->DisplayCursor; pScreen->BlockHandler = vncHooksScreen->BlockHandler; xfree((pointer)vncHooksScreen); DBGPRINT((stderr,"vncHooksCloseScreen: unwrapped screen functions\n")); return (*pScreen->CloseScreen)(i, pScreen);}// CreateGC - wrap the "GC funcs"static Bool vncHooksCreateGC(GCPtr pGC){ SCREEN_UNWRAP(pGC->pScreen, CreateGC); vncHooksGCPtr vncHooksGC = (vncHooksGCPtr)pGC->devPrivates[vncHooksGCIndex].ptr; Bool ret = (*pScreen->CreateGC) (pGC); vncHooksGC->wrappedOps = 0; vncHooksGC->wrappedFuncs = pGC->funcs; pGC->funcs = &vncHooksGCFuncs; SCREEN_REWRAP(CreateGC); return ret;}// PaintWindowBackground - changed region is the given regionstatic void vncHooksPaintWindowBackground(WindowPtr pWin, RegionPtr pRegion, int what){ SCREEN_UNWRAP(pWin->drawable.pScreen, PaintWindowBackground); RegionHelper changed(pScreen, pRegion); (*pScreen->PaintWindowBackground) (pWin, pRegion, what); vncHooksScreen->desktop->add_changed(changed.reg); SCREEN_REWRAP(PaintWindowBackground);}// PaintWindowBorder - changed region is the given regionstatic void vncHooksPaintWindowBorder(WindowPtr pWin, RegionPtr pRegion, int what){ SCREEN_UNWRAP(pWin->drawable.pScreen, PaintWindowBorder); RegionHelper changed(pScreen, pRegion); (*pScreen->PaintWindowBorder) (pWin, pRegion, what); vncHooksScreen->desktop->add_changed(changed.reg); SCREEN_REWRAP(PaintWindowBorder);}// CopyWindow - destination of the copy is the old region, clipped by// borderClip, translated by the delta. This call only does the copy - it// doesn't affect any other bits.static void vncHooksCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion){ SCREEN_UNWRAP(pWin->drawable.pScreen, CopyWindow); RegionHelper copied(pScreen, pOldRegion); int dx = pWin->drawable.x - ptOldOrg.x; int dy = pWin->drawable.y - ptOldOrg.y; REGION_TRANSLATE(pScreen, copied.reg, dx, dy); REGION_INTERSECT(pWin->drawable.pScreen, copied.reg, copied.reg, &pWin->borderClip); (*pScreen->CopyWindow) (pWin, ptOldOrg, pOldRegion); vncHooksScreen->desktop->add_copied(copied.reg, dx, dy); SCREEN_REWRAP(CopyWindow);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -