Можно ли уменьшить задержку отрисовки в этой программе X11? - PullRequest
0 голосов
/ 14 апреля 2020

Эта программа должна работать в любом Linux с X.org. Все, что он делает, это рисует круг вокруг мыши, когда она движется. Проблема в задержке, это плохо. Можно ли его уменьшить?

#include <X11/Xlib.h>
#include <stdlib.h>//this is for malloc
//#include <stdio.h>
#include <math.h>
#include <time.h>

int width, height;
char* data;
struct timespec t0, t1;

void set (int x, int y, char r, char g, char b)
{
  char* p = data + y*width*4 + x*4;
  *p = b;p++;
  *p = g;p++;
  *p = r;
}

void clear()
{
  for(int i = 0; i < width; i++)
  {
    for(int j = 0; j < height; j++)
    {
      set(i,j,0,0,0);
    }
  }
}

void draw_circle(int x, int y, int radius)
{
  int circum = 2*M_PI*radius;

  for (int i = 0; i < circum; i++)
  {
    int penx = x + radius*sin((double)i/radius);
    int peny = y + radius*cos((double)i/radius);

    if (penx >= 0 && penx < width &&
    peny >= 0 && peny < height)
    {
      set(penx, peny, 255,255,255);
    }
  }
}

void setq (int x, int y, char r, char g, char b)
{
  int hs, vs;
  if (x < width-1)
    hs = 1;
  else
    hs = -1;
  if (y < height-1)
    vs = 1;
  else
    vs = -1;

  set(x,y,r,g,b);
  set(x+hs,y,r,g,b);
  set(x,y+vs,r,g,b);
  set(x+hs,y+vs,r,g,b);
}

int main()
{
  Display *display = XOpenDisplay(NULL);
  int screen_num = DefaultScreen(display);
  Window root = RootWindow(display,screen_num);
  Visual *visual = DefaultVisual(display,screen_num);

  width = 512;
  height = 512;

  data = (char *)malloc(width*height*4);

  XImage *img = XCreateImage(display,visual,24,ZPixmap,0,data,width,height,8,0);

  Window win = XCreateSimpleWindow(display,root,50,50,width,height,1,0,0);
  XSelectInput(display,win,ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask |
      ButtonPressMask);

  XMapWindow(display,win);

  clock_gettime(CLOCK_REALTIME,&t0);

  XEvent ev;
  int running = 1;
  while(running)
  {
    //clear();
    while(XPending(display))
    {
      XNextEvent(display,&ev);
      switch(ev.type)
      {
    case KeyPress:
      running = 0;
      break;
    case KeyRelease:
      break;
    case MotionNotify:
      if (ev.xmotion.state & Button1Mask)
      {
        setq(ev.xmotion.x,ev.xmotion.y,255,0,0);
      }
      else if (ev.xmotion.state & Button2Mask)
      {
        setq(ev.xmotion.x,ev.xmotion.y,0,255,0);
      }
      else if (ev.xmotion.state & Button3Mask)
      {
        setq(ev.xmotion.x,ev.xmotion.y,0,0,255);
      }
      else
      {
        draw_circle(ev.xmotion.x,ev.xmotion.y,10);
        //setq(ev.xmotion.x,ev.xmotion.y,255,255,255);
      }
    case ButtonPress:
      switch (ev.xbutton.button)
      {
        case Button1:
          draw_circle(ev.xmotion.x,ev.xmotion.y,10);
          setq(ev.xbutton.x,ev.xbutton.y,255,127,127);
          break;
        case Button2:
          setq(ev.xbutton.x,ev.xbutton.y,127,255,127);
              break;
        case Button3: 
          setq(ev.xbutton.x,ev.xbutton.y,127,127,255);
          break;
        case Button5:
          setq(ev.xbutton.x,ev.xbutton.y,0,255,255);
          break;
      }
      break;
      }

    }
    clock_gettime(CLOCK_REALTIME,&t1);
    int delta = (t1.tv_sec-t0.tv_sec)*1000000000+(t1.tv_nsec-t0.tv_nsec);
    if(delta >= 16666667)
    //        1000000000
    {
    XPutImage(display,win,DefaultGC(display,screen_num),img,0,0,0,0,width,height);
    clear();
    t0 = t1;
    }
  }
  XDestroyWindow(display,win);
  XCloseDisplay(display);
}

Скомпилировать с:

gcc window.c -lX11 -lm

https://github.com/alexandrehmf/X11

...