G549P

            Подошедший трамвай (новый) удивил меня:
            Он был буквально забит людьми.
            Когда настало время выходить, я, наконец, понял:
            кнопка на двери со стороны салона не работала.

Пререквизиты (виртуальная машина Hamster-2)
-------------------------------------------

  apt install libx11-dev
  apt install python-xlib
  apt install python-visual
  apt install idle-python2.7
  apt install python-pip
  apt install imagemagick
  apt install python-imaging
  apt install libjpeg9 libjpeg9-dev libfreetype6 libfreetype6-dev zlib1g-dev
  pip install pillow

Определитель цвета пикселя под щелчком мышкой (X11)
---------------------------------------------------

ma.c

  // Compile with (^ order):
  // gcc -shared -O3 -fPIC -Wl,-soname,ma -o ma.so ma.c -lX11
  //                                                     ^

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

  int  X_mouse_pos( int*);
  int  X_color_at( int, int, int*);
  int  X_mouse_select( int*);
  void X_get_screen( int, int, int, int, unsigned char *);
  int  X_screen_size( int*);

  int  X_mouse_pos( int* axy) {
      Display *dsp = XOpenDisplay( NULL);
      if( !dsp) return 1;

      int screenNumber = DefaultScreen( dsp);

      XEvent event;

      /* get info about current pointer position */
      XQueryPointer(
          dsp, RootWindow( dsp, DefaultScreen( dsp)),
          &event.xbutton.root, &event.xbutton.window,
          &event.xbutton.x_root, &event.xbutton.y_root,
          &event.xbutton.x, &event.xbutton.y,
          &event.xbutton.state
      );
      
      axy[0] = event.xbutton.x;
      axy[1] = event.xbutton.y;
      XCloseDisplay( dsp);
      
      return 0;
  }
  
  int  X_color_at( int ax, int ay, int* argb)
  {
      Display *d = XOpenDisplay(NULL);
      XColor c;
      XImage *image;

      image = XGetImage(
                  d, RootWindow (d, DefaultScreen (d)),
                  ax, ay, 1, 1, AllPlanes, XYPixmap
      );
      c.pixel = XGetPixel( image, 0, 0);
      XFree( image);
      XQueryColor( d, DefaultColormap( d, DefaultScreen( d)), &c);
      argb[0] = c.red; argb[1] = c.green; argb[2] = c.blue;
      XCloseDisplay( d);
      return 0;
  }

  int X_mouse_select( int* aretdata) {
      int x=-1, y=-1;
      XEvent event;
      int button;
      Display *display = XOpenDisplay(NULL);
      if (display == NULL)
          // Error: Cannot connect to X server!
          return 1;
      Window root= XDefaultRootWindow(display);
      XGrabPointer( display, root, False, ButtonPressMask,
          GrabModeAsync, GrabModeAsync, None, None, CurrentTime);

      XSelectInput( display, root, ButtonPressMask) ;
      while( 1) {
          XNextEvent( display, &event);
          switch( event.type) {
              case ButtonPress:
                  switch( event.xbutton.button) {
                      case Button1:
                          x=event.xbutton.x;
                          y=event.xbutton.y;
                          button=Button1;
                          break;
                      case Button3:
                          x=event.xbutton.x;
                          y=event.xbutton.y;
                          button=Button3;
                          break;
                      default:
                          break;
                  }
                  break;
              default:
                  break;
          }
          if( x>=0 && y>=0) break;
      }
      aretdata[1] = x; aretdata[2] = y;
      X_color_at( x, y, aretdata+3);
      XCloseDisplay( display);
      if( button==Button1)
          aretdata[0] = 1;
      else
          aretdata[0] = 2;
      return 0;
  }

  int X_screen_size( int* axy)
  {
      Display* pdsp = NULL;
      Screen* pscr = NULL;

      pdsp = XOpenDisplay( NULL );
      if ( !pdsp )
          // Error: Failed to open default display
          return -1;

      pscr = DefaultScreenOfDisplay( pdsp );
      if ( !pscr )
          // Error: Failed to obtain the default screen of given display
          return -2;

      axy[0] = pscr->width;
      axy[1] = pscr->height;

      XCloseDisplay( pdsp );
      return 0;
  }

  void X_get_screen( int xx, int yy, int W, int H, unsigned char * data)
  {
     Display *display = XOpenDisplay(NULL);
     Window root = DefaultRootWindow(display);

     XImage *image =
        XGetImage(display,root, xx,yy, W,H, AllPlanes, ZPixmap);

     unsigned long red_mask   = image->red_mask;
     unsigned long green_mask = image->green_mask;
     unsigned long blue_mask  = image->blue_mask;
     int x, y;
     int ii = 0;
     for (y = 0; y < H; y++) {
         for (x = 0; x < W; x++) {
             unsigned long pixel = XGetPixel(image,x,y);
             unsigned char blue  = (pixel & blue_mask);
             unsigned char green = (pixel & green_mask) >> 8;
             unsigned char red   = (pixel & red_mask) >> 16;

             data[ii + 2] = blue;
             data[ii + 1] = green;
             data[ii + 0] = red;
             ii += 3;
        }
     }
     XCloseDisplay( display);
  }

  #include <stdio.h>
  /*
  int main() {
      int data[6] = {0};
      X_screen_size( data);
      printf(
          "screen size %d %d \n",
          data[0], data[1]
      );
      X_mouse_select( data);
      printf(
          "clicked %s at XY=(%d,%d) on RGB color=(%f,%f,%f)\n",
          data[0]==1 ? "(oO)" : "(Oo)",
          data[1], data[2], 
          data[3]/65536., data[4]/65536., data[5]/65536.
      );
      return 0;
  }
  */
  int main() {
      int data[2] = {0};
      while(1) {
          X_mouse_pos( data);
          printf("x=%d y=%d\n", data[0], data[1]);
      }
      return 0;
  }
  
печать

  screen size 1280 960 
  clicked (oO) at XY=(714,923) on RGB color=(0.999985,0.999985,0.423523)
  
ma_test.py

  import os
  import ctypes
  from visual import *

  name = 'ma.so'
  lib = os.path.dirname(os.path.abspath(__file__)) + os.path.sep + name
  dll = ctypes.cdll.LoadLibrary(lib)

  def getScreenSize():
      result = (ctypes.c_int*2)()
      dll.X_screen_size(result)
      return [result[0], result[1]]

  def pickColorOnClick():
      rs = (ctypes.c_int*6)()
      dll.X_mouse_select(rs)
      return rs[0], rs[1], rs[2], rs[3]/65536., rs[4]/65536., rs[5]/65536.

  if __name__ == '__main__':
      print "screen size", getScreenSize()
      rc = pickColorOnClick()
      print "pick color (btn, x, y, r, g, b)", rc
      
      ball = sphere(color=(rc[3], rc[4], rc[5]))
      
пример печати

  screen size [1280, 960]
  pick color (btn, x, y, r, g, b) (1, 1109, 468, 0.9999847412109375, 
                                                 0.9999847412109375, 
                                                 0.9999847412109375)
  Нарисует шарик выбранного цвета.

увязано c python-visual: ma_visu.py

  import os
  import ctypes
  import time
  from visual import *

  name = 'ma.so'
  lib = os.path.dirname(os.path.abspath(__file__)) + os.path.sep + name
  dll = ctypes.cdll.LoadLibrary(lib)

  def getScreenSize():
      result = (ctypes.c_int*2)()
      dll.X_screen_size(result)
      return [result[0], result[1]]

  def pickColorOnClick():
      rs = (ctypes.c_int*6)()
      dll.X_mouse_select(rs)
      return rs[0], rs[1], rs[2], rs[3]/65536., rs[4]/65536., rs[5]/65536.

  def pickColorAt( ax, ay):
      rs = (ctypes.c_int*3)()
      dll.X_color_at(ctypes.c_int(ax), ctypes.c_int(ay), rs)
      return rs[0]/65536., rs[1]/65536., rs[2]/65536.

  if __name__ == '__main__':
      print "screen size", getScreenSize()
      rc = pickColorOnClick()
      print "selected: x, y", rc[1], rc[2]

      x = rc[1]; y = rc[2]
      s = sphere(color=color.black)
      while(True):
          rc = pickColorAt( x, y)
          print 'pickColorAt({0},{1}) (r,g,b)'.format(x, y), rc
          s.color = (rc[0], rc[1], rc[2])
          time.sleep(.1)

Пример. Ускоритель
------------------

Требуется: Заставить ускорять
Дано:

  import time
  from visual import *

  co = curve( y=0, radius=0.3, color=color.yellow, f=arange(0,1.01,.01))
  co.x = 11. * sin( 2 * math.pi * co.f)
  co.z = 11. * cos( 2 * math.pi * co.f)

  ci = curve( y=0, radius=0.3, color=color.green, f=arange(0,1.01,.01))
  ci.x =  9. * sin( 2 * math.pi * ci.f)
  ci.z =  9. * cos( 2 * math.pi * ci.f)

  cs = curve( x=0, radius=0.3, color=color.blue, f=arange(0,1.01,.01))
  cs.y =  1.5 * sin( 2 * math.pi * cs.f)
  cs.z =  10 + 1.5 * cos( 2 * math.pi * cs.f)

  cn = curve( x=0, radius=0.3, color=color.blue, f=arange(0,1.01,.01))
  cn.y =  1.5 * sin( 2 * math.pi * cn.f)
  cn.z =  -10 + 1.5 * cos( 2 * math.pi * cn.f)

  ce = curve( z=0, radius=0.3, color=color.blue, f=arange(0,1.01,.01))
  ce.x =  10 + 1.5 * cos( 2 * math.pi * ce.f)
  ce.y =  1.5 * sin( 2 * math.pi * ce.f)

  cw = curve( z=0, radius=0.3, color=color.blue, f=arange(0,1.01,.01))
  cw.x =  -10 + 1.5 * cos( 2 * math.pi * cw.f)
  cw.y =  1.5 * sin( 2 * math.pi * cw.f)

  f = 0
  b = sphere(pos=(0,0,10),radius=1,color=color.red)
  while (True):
      x = 10. * sin( 2 * math.pi * f / 1000)
      y = 0
      z = 10. * cos( 2 * math.pi * f / 1000)
      if x > 0 and z > 0:
          ce.color = color.red
          cs.color = color.blue
      if x > 0 and z <= 0:
          cn.color = color.red
          ce.color = color.blue
      if x <= 0 and z <= 0:
          cw.color = color.red
          cn.color = color.blue
      if x <= 0 and z > 0:
          cs.color = color.red
          cw.color = color.blue
      b.pos=(x,y,z)
      f = f + 1 if f <= 1000 else 0
      time.sleep(.05)

Ссылки:
-------

[1] Getting mouseclick coordinates with Xlib

  http://stackoverflow.com/questions/16122196
       /getting-mouseclick-coordinates-with-xlib

[2] Take a screenshot via a python script. [Linux]

  http://stackoverflow.com/questions/69645
       /take-a-screenshot-via-a-python-script-linux
       
[3] Mouseposition on Linux via Xlib

  http://snipplr.com/view/19188/mouseposition-on-linux-via-xlib

[4] Calling a C-Library from within Python

  https://ka010.wordpress.com/2009/03/30
        /calling-a-c-library-from-within-python/

[5] How to get the screen resolution in Linux C

  http://surfingtroves.blogspot.com.ee/2011/01
       /how-to-get-screen-resolution-in-linux-c.html
       
[6] Get the Global Mouse Position

  http://ubuntuforums.org/showthread.php?t=562087

