⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dd_x11.c

📁 Very very small GUI. Usefull for small system, without OS or small OS. Event driven, support user m
💻 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 + -