x11用xlib库创建个framebuffer可写的窗口

写了个测试小程序,用X11的Xlib库创建个可写的framebuffer窗口,逐像素刷新。供参考。
编译

gcc  testfb.c -lX11

d键测试,esc和小叉退出。

d键测试图片

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdlib.h>
#include <stdio.h>

enum KEY {K_Escape=9, K_1,K_2,K_3,K_4,K_5,K_6,K_7,K_8,K_9,K_0,
 K_minus,K_equal,K_BackSpace,K_Tab,K_q,K_w,K_e,K_r,K_t,K_y,
 K_u,K_i,K_o,K_p,K_bracketleft,K_bracketright,K_Return,K_Control_L,K_a,K_s,
 K_d,K_f,K_g,K_h,K_j,K_k,K_l,K_semicolon,K_apostrophe,K_grave,
 K_Shift_L,K_backslash,K_z,K_x,K_c,K_v,K_b,K_n,K_m,K_comma,
 K_period,K_slash,K_Shift_R,Kp_Multiply,K_Alt_L,K_space,K_Caps_Lock,K_F1,K_F2,K_F3,
 K_F4,K_F5,K_F6,K_F7,K_F8,K_F9,K_F10,K_Num_Lock,K_Scroll_Lock,Kp_Home,
 Kp_Up,Kp_Prior,Kp_Subtract,Kp_Left,Kp_Begin,Kp_Right,Kp_Add,Kp_End,Kp_Down ,Kp_Next,
 Kp_Insert,Kp_Delete,K_ISO_Level3_Shift,K_less=94,K_F11,K_F12,
    Kp_Enter=104,K_Control_R,Kp_Divide,K_Print,K_Alt_R,K_Linefeed,
 K_Home,K_Up,K_Prior,K_Left,K_Right,K_End,K_Down,K_Next,K_Insert,K_Delete,
 Kp_Equal=125,K_plusminus,K_Pause,Kp_Decimal=129,
 K_Super_L=133,K_Super_R,K_Menu,K_Cancel,K_Redo}; 
enum BUTTON { B_Right = 1, B_Middle, B_Left,B_Wheel_up, B_Wheel_down};

Window win;
short fb_width;
short fb_height;
Display *display;
GC *gcptr;
XImage *img;
int* dataptr;

int put_pixel(int x, int y, int pix)
{
    if(x>=0 && x < fb_width && y >= 0 && y < fb_height){
        XPutPixel(img, x, y, (unsigned long) pix);
        XPutImage(display,win,*gcptr,img,x,y,x,y,1,1);  // refresh single pixel
      //  XPutImage(display,win,*gcptr,img,0,0,0,0,fb_width,fb_height); //refresh all
        return 0;
    } else 
            return -1; //not valid
}

void flush()
{
     XPutImage(display,win,*gcptr,img,0,0,0,0,fb_width,fb_height); //refresh all
}

int process_event_loop()
{
    XEvent event;
    Atom wm_delete_window;
    wm_delete_window	= XInternAtom(display,"WM_DELETE_WINDOW",False);
    XSetWMProtocols(display,win,&wm_delete_window,1);

    while(1) {
        XNextEvent(display,&event);

        if (event.type == KeyPress ){

            switch(event.xkey.keycode) {
                case K_d:   //d键 测试
                    for(int i = 0; i<fb_width; i++) {
                        int pix = (i*256)/fb_width <<8;
                        for(int j = 0; j <fb_height; j++)
                            put_pixel(i,j,pix);
                            }
                    break;

                case K_Escape:
                    return 0;

                default:
                    break;
            }

        } else if (event.type == Expose){
            img->data = (char*)dataptr;
            XPutImage(display,win,*gcptr,img,0,0,0,0,fb_width,fb_height);
        } else if ( event.type == ClientMessage 
                && ((Atom) event.xclient.data.l[0]) == wm_delete_window)
        {	// 处理右上角叉退出
            return 0;
        } 
      //  else XPutImage(display,win,*gcptr,img,0,0,0,0,fb_width,fb_height);
    }
}
void open_window(short width,short height)
{
    fb_width = width;
    fb_height  = height;

    display = XOpenDisplay(NULL);
    int screen_num = DefaultScreen(display);

    Window root = RootWindow(display,screen_num);
    Visual *visual = DefaultVisual(display, screen_num);

    dataptr = (int*) malloc(fb_width*fb_height*4*sizeof(char)); 
    img = XCreateImage(display, visual, DefaultDepth(display,screen_num),
            ZPixmap,0,(char*)dataptr,fb_width,fb_height,32,0);

    win = XCreateSimpleWindow(display, root, 50, 50, fb_width, fb_height, 1, 0, 0);
    gcptr = &(DefaultGC(display,screen_num));
    XSelectInput(display,win,ExposureMask | KeyPressMask |StructureNotifyMask |ButtonPressMask|ButtonReleaseMask|SubstructureNotifyMask);
    XMapWindow(display,win);
}

void close_window()
{
    free(dataptr);
    XCloseDisplay(display);
}

int main() {
    open_window(640,480);
    process_event_loop();
    printf("exited\n");
    close_window();
}


  • 27
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yvee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值