📄 dd_x11.c
字号:
#include <i_pwin.h>/* -------------------------------------------------------------------------- */#include <X11/X.h>#include <X11/Xlib.h>#include <X11/keysym.h>#include <sys/time.h>/* -------------------------------------------------------------------------- */#define DPY_WIDTH 128 /* Display width */#define DPY_HEIGHT 64 /* Display height */#define DPY_SCALE 2 /* Display pixel scale */#define DPY_BIT_BUFF 1 /* Define to support bit buffers *//* -------------------------------------------------------------------------- */static Display* x_dpy; /* X11 Display */static Window x_win; /* X11 Window */static GC x_gc; /* X11 graphics context */static Pw_Display pw_dpy;static Pw_Int xinput_values[4] = {24, 60, 0, 99};#ifdef DPY_BIT_BUFFstatic Pw_Bitmap bit_buff1;static Pw_Bitmap bit_buff2;static Pw_Byte bit_buff1_bits[((DPY_WIDTH*DPY_HEIGHT + 0x07) >> 3)];static Pw_Byte bit_buff2_bits[((DPY_WIDTH*DPY_HEIGHT + 0x07) >> 3)];static XColor black_xcolor;static XColor white_xcolor;#endif /* DPY_BIT_BUFF *//* -------------------------------------------------------------------------- */#ifdef DPY_BIT_BUFFstatic void _InitBitBuff(void){ Pw_BitmapCreate(DPY_WIDTH, DPY_HEIGHT, bit_buff1_bits, &bit_buff1); Pw_BitmapCreate(DPY_WIDTH, DPY_HEIGHT, bit_buff2_bits, &bit_buff2); black_xcolor.red = pw_black_pixel->red * 257; black_xcolor.green = pw_black_pixel->green * 257; black_xcolor.blue = pw_black_pixel->blue * 257; white_xcolor.red = pw_white_pixel->red * 257; white_xcolor.green = pw_white_pixel->green * 257; white_xcolor.blue = pw_white_pixel->blue * 257; XAllocColor(x_dpy, DefaultColormap(x_dpy, 0), &black_xcolor); XAllocColor(x_dpy, DefaultColormap(x_dpy, 0), &white_xcolor); IPw_BitmapFillRect(&bit_buff1, 0, 0, DPY_WIDTH, DPY_HEIGHT, 0); IPw_BitmapFillRect(&bit_buff2, 0, 0, DPY_WIDTH, DPY_HEIGHT, 0);}static void _FreeBitBuff(void){ Pw_BitmapDestroy(&bit_buff1); Pw_BitmapDestroy(&bit_buff2);}/* * Its a lot of work to draw a bitmap byte on X11 screen, * but its very fast to do it on a B/W LCD display :-). */ static void _DrawBitmapByte(Pw_uInt baddr, Pw_Byte dbyte){ Pw_uInt w = bit_buff1.width8; Pw_uInt x = 8 * (baddr % w); Pw_uInt y = baddr / w; Pw_Byte mask = 0x80; IPW_ASSERT(baddr < (bit_buff1.width8 * bit_buff1.height), ("baddr = %d size = %d !!!", baddr, bit_buff1.width8 * bit_buff1.height)); for (w = 0; w < 8; w++) { if (0 == (dbyte & mask)) XSetForeground(x_dpy, x_gc, black_xcolor.pixel); else XSetForeground(x_dpy, x_gc, white_xcolor.pixel); XFillRectangle(x_dpy, x_win, x_gc, x * DPY_SCALE, y * DPY_SCALE, DPY_SCALE, DPY_SCALE); x++; mask >>= 1; }}#else /* DPY_BIT_BUFF */static void _SetColor(Pw_Color* color){ static Pw_uInt or = 256, og = 256, ob = 256; XColor xcolor; if (or == color->red && og == color->green && ob == color->blue) return; or = color->red; og = color->green; ob = color->blue; xcolor.red = or * 257; xcolor.green = og * 257; xcolor.blue = ob * 257; XAllocColor(x_dpy, DefaultColormap(x_dpy, 0), &xcolor); XSetForeground(x_dpy, x_gc, xcolor.pixel);}#endif /* not DPY_BIT_BUFF */static Pw_Bool _OpenDisplay(void){ x_dpy = XOpenDisplay(NULL); if (x_dpy == PW_NULL) return(FALSE);#ifdef DPY_BIT_BUFF _InitBitBuff();#endif /* DPY_BIT_BUFF */ x_win = XCreateSimpleWindow(x_dpy, XRootWindow(x_dpy, DefaultScreen(x_dpy)), 0, 0, DPY_WIDTH * DPY_SCALE, DPY_HEIGHT * DPY_SCALE, 0, 0, BlackPixel(x_dpy, DefaultScreen(x_dpy))); XMapWindow(x_dpy, x_win); x_gc = XCreateGC(x_dpy, x_win, 0, NULL); XSetForeground(x_dpy, x_gc, WhitePixel(x_dpy, DefaultScreen(x_dpy))); XSetBackground(x_dpy, x_gc, BlackPixel(x_dpy, DefaultScreen(x_dpy))); XSelectInput(x_dpy, x_win, ExposureMask | KeyPressMask | KeyReleaseMask); XSync(x_dpy, False); return(TRUE);}static void _CloseDisplay(void){#ifdef DPY_BIT_BUFF _FreeBitBuff();#endif /* DPY_BIT_BUFF */ XFreeGC(x_dpy, x_gc); XDestroyWindow(x_dpy, x_win); XCloseDisplay(x_dpy);}static Pw_Bool _TranslateKeyCode(XKeyEvent* event, Pw_uInt* keycode){ KeySym keysym = XLookupKeysym(event, 0); switch (keysym) { case XK_Up: *keycode = PW_UP_KEY_CODE; return(TRUE); case XK_Down: *keycode = PW_DOWN_KEY_CODE; return(TRUE); case XK_Left: *keycode = PW_LEFT_KEY_CODE; return(TRUE); case XK_Right: *keycode = PW_RIGHT_KEY_CODE; return(TRUE); case XK_Page_Down: *keycode = PW_NEXT_KEY_CODE; return(TRUE); case XK_Page_Up: *keycode = PW_PREV_KEY_CODE; return(TRUE); case XK_Return: *keycode = PW_YES_KEY_CODE; return(TRUE); default: return(FALSE); }} static void _HandleXInputsSim(Pw_Display* dpy, XEvent* xe){ Pw_uInt keycode, changed, step; if (xe->type != KeyPress) return; keycode = XLookupKeysym((XKeyEvent*)xe, 0); step = 20; switch (keycode) { case XK_1: xinput_values[0] -= step; changed = 0; break; case XK_2: xinput_values[0] += step; changed = 0; break; case XK_3: xinput_values[1] -= step; changed = 1; break; case XK_4: xinput_values[1] += step; changed = 1; break; case XK_5: xinput_values[2] -= step; changed = 2; break; case XK_6: xinput_values[2] += step; changed = 2; break; case XK_7: xinput_values[3] -= step; changed = 3; break; case XK_8: xinput_values[3] += step; changed = 3; break; default: return; } if (xinput_values[changed] < 0) xinput_values[changed] = 0; else if (xinput_values[changed] > 511) xinput_values[changed] = 511; IPw_EventXInputChanged(dpy, changed, xinput_values[changed]);}static Pw_uLong _GetCurrentMS(void){ struct timeval now; gettimeofday(&now, 0); return(1000 * now.tv_sec + (now.tv_usec / 1000.0));} static void _MainLoop(Pw_Display* dpy){ static Pw_uLong otime; otime = _GetCurrentMS(); while (TRUE) { if (XPending(x_dpy) > 0) { XEvent xe; XNextEvent(x_dpy, &xe); if (xe.type == KeyPress && XLookupKeysym((XKeyEvent*)&xe, 0) == XK_Escape) return; _HandleXInputsSim(dpy, &xe); switch (xe.type) { case KeyPress: { XKeyEvent* xkey = (XKeyEvent*)&xe; Pw_uInt keycode; if (_TranslateKeyCode(xkey, &keycode)) IPw_EventKeyPressed(dpy, keycode); break; } case KeyRelease: { XKeyEvent* xkey = (XKeyEvent*)&xe; Pw_uInt keycode; if (_TranslateKeyCode(xkey, &keycode)) IPw_EventKeyReleased(dpy, keycode); break; } case Expose: {#ifdef DPY_BIT_BUFF IPw_BitmapFillRect(&bit_buff2, 0, 0, DPY_WIDTH, DPY_HEIGHT, 0); XSetForeground(x_dpy, x_gc, black_xcolor.pixel); XFillRectangle(x_dpy, x_win, x_gc, 0, 0, DPY_WIDTH * DPY_SCALE, DPY_HEIGHT * DPY_SCALE);#endif IPw_DisplayRefresh(dpy); break; } } } if (dpy->close) return; if ((_GetCurrentMS() - otime) > 0) { IPw_TimeoutProcess(dpy, _GetCurrentMS() - otime); otime = _GetCurrentMS(); } } } /* -------------------------------------------------------------------------- */#ifdef DPY_BIT_BUFFstatic void _DrawPoint(Pw_GC* gc, Pw_Coord x, Pw_Coord y){ IPw_BitmapDrawPoint(&bit_buff1, x, y, ((Pw_GCGetColor(gc) == pw_black_pixel) ? 0 : 1));} static void_DrawPoints(Pw_GC* gc, Pw_Coord x, Pw_Coord y, Pw_Byte bits){ IPw_BitmapDrawPoints(&bit_buff1, x, y, bits, ((Pw_GCGetColor(gc) == pw_black_pixel) ? 0 : 1));} static void _DrawHorLine(Pw_GC* gc, Pw_Coord x1, Pw_Coord y1, Pw_Coord x2){ IPw_BitmapDrawHorLine(&bit_buff1, x1, y1, x2, ((Pw_GCGetColor(gc) == pw_black_pixel) ? 0 : 1));} static void _DrawVerLine(Pw_GC* gc, Pw_Coord x1, Pw_Coord y1, Pw_Coord y2){ IPw_BitmapDrawVerLine(&bit_buff1, x1, y1, y2, ((Pw_GCGetColor(gc) == pw_black_pixel) ? 0 : 1));} static void _FillRect(Pw_GC* gc, Pw_Coord x, Pw_Coord y, Pw_Coord w, Pw_Coord h){ IPw_BitmapFillRect(&bit_buff1, x, y, w, h, ((Pw_GCGetColor(gc) == pw_black_pixel) ? 0 : 1));} static void _DisplayRefresh(Pw_Display* dpy, Pw_Rectangle* area){ IPw_BitmapDiff(&bit_buff1, &bit_buff2, area, _DrawBitmapByte); XFlush(x_dpy);}#else /* DPY_BIT_BUFF */static void _DrawPoint(Pw_GC* gc, Pw_Coord x, Pw_Coord y){ _SetColor(Pw_GCGetColor(gc)); XFillRectangle(x_dpy, x_win, x_gc, x * DPY_SCALE, y * DPY_SCALE, DPY_SCALE, DPY_SCALE);}static void _DrawPoints(Pw_GC* gc, Pw_Coord x, Pw_Coord y, Pw_Byte bits){ Pw_uInt w; Pw_Byte mask = 0x80; _SetColor(Pw_GCGetColor(gc)); for (w = 0; w < 8; w++) { if ((bits & mask) != 0) { XFillRectangle(x_dpy, x_win, x_gc, x * DPY_SCALE, y * DPY_SCALE, DPY_SCALE, DPY_SCALE); } x++; mask >>= 1; }} static void _DrawHorLine(Pw_GC* gc, Pw_Coord x1, Pw_Coord y1, Pw_Coord x2){ Pw_Int rx = x1 * DPY_SCALE; Pw_Int ry = y1 * DPY_SCALE; Pw_Int rw = x2 * DPY_SCALE - rx + DPY_SCALE; Pw_Int rh = DPY_SCALE; _SetColor(Pw_GCGetColor(gc)); XFillRectangle(x_dpy, x_win, x_gc, rx, ry, rw, rh); } static void _DrawVerLine(Pw_GC* gc, Pw_Coord x1, Pw_Coord y1, Pw_Coord y2){ Pw_Int rx = x1 * DPY_SCALE; Pw_Int ry = y1 * DPY_SCALE; Pw_Int rw = DPY_SCALE; Pw_Int rh = y2 * DPY_SCALE - ry + DPY_SCALE; _SetColor(Pw_GCGetColor(gc)); XFillRectangle(x_dpy, x_win, x_gc, rx, ry, rw, rh); } static void _FillRect(Pw_GC* gc, Pw_Coord x, Pw_Coord y, Pw_Coord w, Pw_Coord h){ _SetColor(Pw_GCGetColor(gc)); XFillRectangle(x_dpy, x_win, x_gc, x * DPY_SCALE, y * DPY_SCALE, w * DPY_SCALE, h * DPY_SCALE);}static void _DisplayRefresh(Pw_Display* dpy, Pw_Rectangle* area){ XFlush(x_dpy);}#endif /* not DPY_BIT_BUFF */static Pw_Int _DisplayGetXInputValue(Pw_Display* dpy, Pw_uInt num){ return(xinput_values[num]); } extern Pw_Bool Pw_Init(Pw_Display* dpy);Pw_Int main(Pw_Int argc, Pw_Char** argv){ Pw_Int fcnt, fcnt2; Pw_DD dd; Pw_LLD lld; lld.draw_point = _DrawPoint; lld.draw_points = _DrawPoints; lld.draw_hor_line = _DrawHorLine; lld.draw_ver_line = _DrawVerLine; lld.fill_rect = _FillRect; dd.lld = &lld; dd.display_refresh = _DisplayRefresh; dd.get_xinput_value = _DisplayGetXInputValue; dd.init_components = Pw_Init; if(!_OpenDisplay()) return(-1); IPw_InitInternals(); fcnt = IPw_RegionGetFreeCnt(); IPw_DisplayOpen(DPY_WIDTH, DPY_HEIGHT, &dd, &pw_dpy); if (!IPw_InitComponents(&pw_dpy)) { IPw_DisplayClose(&pw_dpy); _CloseDisplay(); return(0); } _MainLoop(&pw_dpy); IPw_DisplayClose(&pw_dpy); _CloseDisplay(); fcnt2 = IPw_RegionGetFreeCnt(); IPW_FAIL(fcnt2 == fcnt, ("Some regions not freed! (%d != %d)", fcnt2, fcnt)); return(0);}/*---------------------------------------------------------------------------// end of dd_x11.c //--------------------------------------------------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -