📄 nanox.c
字号:
/* * Copyright (C) 1997, 1998 Olivetti & Oracle Research Laboratory * * 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. * * Microwindows interface by George Harvey * * 07/03/00 GH created nanox.c to replace x.c, development * being done using Microwindows 0.88pre3 * 16/03/00 GH try to match the VNC palette to the current * palette using a lookup table * 06/05/00 GH update for mwin 0.88pre7, use GrSetSystemPalette() * instead of lookup table * 27/05/00 GH update for mwin 0.88pre8 * 03/06/00 GH remove colour lookup code *//* * nanox.c - functions to deal with nano-X display. */#include <vncviewer.h>#include <unistd.h>#define VW_WIDTH 1024 /* VNC window width */#define VW_HEIGHT 768 /* VNC window height */#define VW_X 0 /* VNC window origin */#define VW_Y 0 /* VNC window origin */#define SCROLLBAR_SIZE 10#define SCROLLBAR_BG_SIZE (SCROLLBAR_SIZE + 2)#define INVALID_PIXEL 0xffffffff#define COLORMAP_SIZE 256/* * global data */Colormap cmap;Display *dpy;Window canvas;GR_GC_ID gc;GR_GC_ID srcGC;GR_GC_ID dstGC;/* BGR233ToPixel array */unsigned long BGR233ToPixel[COLORMAP_SIZE] = { \ 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, \ 0xf7, 0xc7, 0x87, 0x47, 0x07, 0xc6, 0x86, 0x46, \ 0xf7, 0xc7, 0x87, 0x47, 0x07, 0xc6, 0x86, 0x46, \ 0xf7, 0xc7, 0x87, 0x47, 0x07, 0xc6, 0x86, 0x46, \ 0xf7, 0xc7, 0x87, 0x47, 0x07, 0xc6, 0x86, 0x46, \ 0xf7, 0xc7, 0x87, 0x47, 0x07, 0xc6, 0x86, 0x46, \ 0xf7, 0xc7, 0x87, 0x47, 0x07, 0xc6, 0x86, 0x46, \ 0xf7, 0xc7, 0x87, 0x47, 0x07, 0xc6, 0x86, 0x46, \ 0xf7, 0xc7, 0x87, 0x47, 0x07, 0xc6, 0x86, 0x46, \ 0x0c, 0x4c, 0x8c, 0xcc, 0x0d, 0x4d, 0x8d, 0xcd, \ 0xcb, 0x80 \ };/* colour palette for 8-bit displays */static GR_PALETTE srv_pal; /* VNC server palette *//* temporary keyboard mapping array *//* ^T = up, ^F = left, ^G = right, ^V = down */CARD32 kmap[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0xff51, 0xff53, \ 0xff08, 0xff09, 0x0a, 0x0b, 0x0c, 0xff0d, 0x0e, 0x0f, \ 0x10, 0x11, 0x12, 0x13, 0xff52, 0x15, 0xff54, 0x17, \ 0x18, 0x19, 0x1a, 0xff1b, 0x1c, 0x1d, 0x1e, 0x1f, \ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, \ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, \ '0', '1', '2', '3', '4', '5', '6', '7', \ '8', '9', 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, \ 0x40, 'A', 'B', 'C', 'D', 'E', 'F', 'G', \ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', \ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', \ 'X', 'Y', 'Z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, \ 0x60, 'a', 'b', 'c', 'd', 'e', 'f', 'g', \ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', \ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', \ 'x', 'y', 'z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f };static Display nx_dpy;static GR_WINDOW_ID wid;static int pixtype; /* format of pixel value */static void CopyBGR233ToScreen(CARD8 *buf, int x, int y, int width, int height);extern MWPIXELVAL gr_foreground; /* for debugging only *//* * Initialize graphics and open a window for the viewer */BoolCreateXWindow(void){ int fd; GR_SIZE w, h; GR_SCREEN_INFO si; if ((fd = GrOpen()) < 0) return(False); nx_dpy.fd = fd; dpy = &nx_dpy; GrGetScreenInfo(&si); /* pass screen details to RFB handler */ myFormat.bitsPerPixel = si.bpp; myFormat.depth = si.bpp; /* is this right? */ myFormat.bigEndian = 0; /* how do I find this out? */ myFormat.trueColour = (myFormat.depth == 8 && !useBGR233) ? 0 : 1; if (myFormat.trueColour) { myFormat.redMax = myFormat.greenMax = 7; myFormat.blueMax = 3; myFormat.redShift = 0; myFormat.greenShift = 3; myFormat.blueShift = 6; } pixtype = si.pixtype; /* get the initial server palette */ GrGetSystemPalette(&srv_pal);#if 0 /* DEBUG */ for (i = 0; i < srv_pal.count; i++) { printf("0x%02x %03d %03d %03d\n", i, \ srv_pal.palette[i].r, srv_pal.palette[i].g, \ srv_pal.palette[i].b ); }#endif /* create the top-level window */ w = (VW_WIDTH > (si.cols - VW_X)) ? (si.cols - VW_X) : VW_WIDTH; h = (VW_HEIGHT > (si.rows - VW_Y)) ? (si.rows - VW_Y) : VW_HEIGHT; if ((wid = GrNewWindow(GR_ROOT_WINDOW_ID, VW_X, VW_Y, w, h, 2, LTGRAY, BLACK)) == 0) { fprintf(stderr, "Unable to create top-level window\n"); GrClose(); return False; } /* select events to receive */ GrSelectEvents(wid, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_BUTTON_UP | GR_EVENT_MASK_KEY_DOWN | GR_EVENT_MASK_KEY_UP | GR_EVENT_MASK_MOUSE_POSITION); /* make thw window visible */ GrMapWindow(wid); canvas = wid; /* create the graphics contexts */ gc = GrNewGC(); srcGC = GrNewGC(); dstGC = GrNewGC(); return True;}/* * set the server palette to the requested colour * NOTE: this has only been tested for 8-bit colour! */intXStoreColor(Display *dpy, Colormap cmap, XColor *xc){ unsigned char ind; ind = xc->pixel & 0xff; /* colour map index */ /* * the colours are passed as 16-bit values so divide by 256 to * get 8-bit RGB values */ srv_pal.palette[0].r = (xc->red / 256) & 0xff; srv_pal.palette[0].g = (xc->green / 256) & 0xff; srv_pal.palette[0].b = (xc->blue / 256) & 0xff; srv_pal.count = 1;#if 0 /* DEBUG */ printf("XStoreColor: ind=%d, r=%02x, g=%02x, b=%02x\n", ind, \ srv_pal.palette[0].r, srv_pal.palette[0].g, \ srv_pal.palette[0].b);#endif GrSetSystemPalette(ind, &srv_pal); return(0);}/* * Copy a rectangular block of pixels */intXCopyArea(Display *dpy, Window src, Window dst, GR_GC_ID gc, int x1, int y1, int w, int h, int x2, int y2){/* printf("XCopyArea: src=%d, dst=%d, w=%d, h=%d\n",src, dst, w, h); */ GrCopyArea(dst, gc, x2, y2, w, h, src, x1, y1, MWROP_SRCCOPY); return(0);}/* * Fill a rectangular block */intXFillRectangle(Display *dpy, Window canvas, GR_GC_ID gc, int x, int y, int w, int h){ GrFillRect(canvas, gc, x, y, w, h);/* printf("XFillRectangle: gr_foreground=%08x\n", (int)gr_foreground); */ return(0);}/* * get the X display name */char *XDisplayName(char *display){ return((char *)NULL);}/* * Change the graphics context. * VNC only uses this to set the foreground colour. */intXChangeGC(Display *dpy, GR_GC_ID gc, unsigned long vmask, GR_GC_INFO *gcv){ /* all we need is the foreground colour *//* printf("XChangeGC: foreground=%08x\n", gcv->foreground); */ if (pixtype == MWPF_PALETTE) { /* * The MWF_PALINDEX bit tells GdFindColor() to skip the palette * lookup. This is OK because we have already set the palette. */ GrSetGCForeground(gc, gcv->foreground | MWF_PALINDEX); } else { GrSetGCForeground(gc, gcv->foreground); } return(0);}/* * Ring the bell. */intXBell(Display *dpy, int pc){ return(0);}/* * */intXSync(Display *dpy, Bool disc){ return(0);}/* * */intXSelectInput(Display *dpy, Window win, long evmask){ return(0);}/* * */intXStoreBytes(Display *dpy, char *bytes, int nbytes){ return(0);}/* * */intXSetSelectionOwner(Display *dpy, Atom sel, Window own, Time t){ return(0);}/* * Copy raw pixel data to the screen */voidCopyDataToScreen(CARD8 *buf, int x, int y, int width, int height){#if 0 /* DEBUG */ printf("CDTS "); fflush(stdout);#endif if (rawDelay != 0) {#if 0 XFillRectangle(dpy, canvas, DefaultGC(dpy,DefaultScreen(dpy)), x, y, width, height);#endif XSync(dpy,False); usleep(rawDelay * 1000); } if (!useBGR233) { GrArea(canvas, gc, x, y, width, height, buf, MWPF_PALETTE); } else { CopyBGR233ToScreen(buf, x, y, width, height); }}/* * Copy BGR233 data to the screen. */static voidCopyBGR233ToScreen(CARD8 *buf, int x, int y, int width, int height){}/* * Handle all X events (keyboard and mouse). */BoolHandleXEvents(GR_EVENT *ev){ GR_BOOL ret = GR_TRUE; int buttons;#if 0 printf("H"); fflush(stdout);#endif switch (ev->type) { case GR_EVENT_TYPE_NONE: ret = GR_TRUE; break; case GR_EVENT_TYPE_MOUSE_POSITION: buttons = (ev->mouse.buttons & GR_BUTTON_R) << 2; buttons |= ev->mouse.buttons & GR_BUTTON_M; buttons |= (ev->mouse.buttons & GR_BUTTON_L) >> 2; ret = SendPointerEvent(ev->mouse.x, ev->mouse.y, buttons); break; case GR_EVENT_TYPE_BUTTON_DOWN: case GR_EVENT_TYPE_BUTTON_UP: buttons = (ev->button.buttons & GR_BUTTON_R) << 2; buttons |= ev->button.buttons & GR_BUTTON_M; buttons |= (ev->button.buttons & GR_BUTTON_L) >> 2; ret = SendPointerEvent(ev->button.x, ev->button.y, buttons); break; case GR_EVENT_TYPE_KEY_DOWN: case GR_EVENT_TYPE_KEY_UP: ret = SendKeyEvent(kmap[ev->keystroke.ch & 0x7f], (ev->type == GR_EVENT_TYPE_KEY_DOWN)); break; default: break; } return(ret);}/* * Close everything down before exiting. */voidShutdownX(void){ GrClose();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -