Guest User

Untitled

a guest
May 4th, 2017
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.32 KB | None | 0 0
  1. /* See LICENSE file for copyright and license details.
  2.  *
  3.  * To understand bgs , start reading main().
  4.  */
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <X11/Xlib.h>
  8. #include <Imlib2.h>
  9. #ifdef XINERAMA
  10. #include <X11/extensions/Xinerama.h>
  11. #endif
  12.  
  13. /* macros */
  14. #define MIN(a, b)       ((a) < (b) ? (a) : (b))
  15. #define MAX(a, b)       ((a) > (b) ? (a) : (b))
  16. #define LENGTH(x)       (sizeof x / sizeof x[0])
  17.  
  18. /* typedefs */
  19. typedef struct {
  20.     int x, y, w, h;
  21. } Monitor;
  22.  
  23. /* function declarations */
  24. static void cleanup(void);      /* frees images before exit. */
  25. static void die(const char *errstr);    /* prints errstr to strerr and exits. */
  26. static void drawbg(void);       /* draws background to root. */
  27. static void run(void);          /* main loop */
  28. static void setup(char *paths[], int c);/* sets up imlib and X */
  29. static void updategeom(void);       /* updates screen and/or Xinerama
  30.                        dimensions */
  31.  
  32. /* variables */
  33. static int sx, sy, sw, sh;  /* geometry of the screen */
  34. static Bool center  = False;    /* center image instead of rescale */
  35. static Bool running = False;
  36. static Display *dpy;
  37. static Window root;
  38. static Visual *vis;
  39. static Colormap cm;
  40. static int nmonitor, nimage;    /* Amount of monitors/available background
  41.                    images */
  42. static Monitor monitors[8];
  43. static Imlib_Image images[LENGTH(monitors)];
  44.  
  45. /* function implementations */
  46. void
  47. cleanup(void) {
  48.     int i;
  49.  
  50.     for(i = 0; i < nimage; i++) {
  51.         imlib_context_set_image(images[i]);
  52.         imlib_free_image_and_decache();
  53.     }
  54. }
  55.  
  56. void
  57. die(const char *errstr) {
  58.     fputs(errstr, stderr);
  59.     exit(EXIT_FAILURE);
  60. }
  61.  
  62. void
  63. drawbg(void) {
  64.     int i, w, h, nx, ny, nh, nw, tmp;
  65.     double factor;
  66.     Pixmap pm;
  67.     Imlib_Image tmpimg, buffer;
  68.  
  69.     pm = XCreatePixmap(dpy, root, sw, sh, DefaultDepth(dpy,
  70.                 DefaultScreen(dpy)));
  71.     if(!(buffer = imlib_create_image(sw, sh)))
  72.         die("Error: Cannot allocate buffer.\n");
  73.     imlib_context_set_blend(1);
  74.     //if ( nmonitor == 0 ) {
  75.     for(i = 0; i < nmonitor; i++) {
  76.     //  i = 0;
  77.         imlib_context_set_image(images[i % nimage]);
  78.         w = imlib_image_get_width();
  79.         h = imlib_image_get_height();
  80.         if(!(tmpimg = imlib_clone_image()))
  81.             die("Error: Cannot clone image.\n");
  82.         imlib_context_set_image(tmpimg);
  83.         if((monitors[i].w > monitors[i].h && w < h) ||
  84.                 (monitors[i].w < monitors[i].h && w > h)) {
  85.             imlib_image_orientate(1);
  86.             tmp = w;
  87.             w = h;
  88.             h = tmp;
  89.         }
  90.         imlib_context_set_image(buffer);
  91.         if(center) {
  92.             nw = (monitors[i].w - w) / 2;
  93.             nh = (monitors[i].h - h) / 2;
  94.         }
  95.         else {
  96.             factor = MAX((double)w / monitors[i].w,
  97.                     (double)h / monitors[i].h);
  98.             nw = w / factor;
  99.             nh = h / factor;
  100.         }
  101.         nx = monitors[i].x + (monitors[i].w - nw) / 2;
  102.         ny = monitors[i].y + (monitors[i].h - nh) / 2;
  103.         imlib_blend_image_onto_image(tmpimg, 0, 0, 0, w, h,
  104.                 nx, ny, nw, nh);
  105.         imlib_context_set_image(tmpimg);
  106.         imlib_free_image();
  107.     }
  108.     imlib_context_set_blend(0);
  109.     imlib_context_set_image(buffer);
  110.     imlib_context_set_drawable(root);
  111.     imlib_render_image_on_drawable(0, 0);
  112.     imlib_context_set_drawable(pm);
  113.     imlib_render_image_on_drawable(0, 0);
  114.     XSetWindowBackgroundPixmap(dpy, root, pm);
  115.     imlib_context_set_image(buffer);
  116.     imlib_free_image_and_decache();
  117.     XFreePixmap(dpy, pm);
  118. }
  119.  
  120. void
  121. run(void) {
  122.     XEvent ev;
  123.  
  124.     drawbg();
  125.     while(running) {
  126.         XNextEvent(dpy, &ev);
  127.         if(ev.type == ConfigureNotify) {
  128.             sw = ev.xconfigure.width;
  129.             sh = ev.xconfigure.height;
  130.             updategeom();
  131.             drawbg();
  132.         }
  133.     }
  134. }
  135.  
  136. void
  137. setup(char *paths[], int c) {
  138.     int i, screen;
  139.  
  140.     /* Loading images */
  141.     for(nimage = i = 0; i < c && i < LENGTH(images); i++) {
  142.         if((images[nimage] = imlib_load_image(paths[i])))
  143.             nimage++;
  144.         else {
  145.             fprintf(stderr, "Warning: Cannot load file `%s`."
  146.                     "Ignoring.\n", paths[nimage]);
  147.             continue;
  148.         }
  149.     }
  150.     if(nimage == 0)
  151.         die("Error: No image to draw.\n");
  152.  
  153.     /* set up X */
  154.     screen = DefaultScreen(dpy);
  155.     vis = DefaultVisual(dpy, screen);
  156.     cm = DefaultColormap(dpy, screen);
  157.     root = RootWindow(dpy, screen);
  158.     XSelectInput(dpy, root, StructureNotifyMask);
  159.     sx = sy = 0;
  160.     sw = DisplayWidth(dpy, screen);
  161.     sh = DisplayHeight(dpy, screen);
  162.     updategeom();
  163.  
  164.     /* set up Imlib */
  165.     imlib_context_set_display(dpy);
  166.     imlib_context_set_visual(vis);
  167.     imlib_context_set_colormap(cm);
  168. }
  169.  
  170. void
  171. updategeom(void) {
  172. #ifdef XINERAMA
  173.     int i;
  174.     XineramaScreenInfo *info = NULL;
  175.  
  176.     if(XineramaIsActive(dpy) &&
  177.             (info = XineramaQueryScreens(dpy, &nmonitor))) {
  178.         nmonitor = MIN(nmonitor, LENGTH(monitors));
  179.         for(i = 0; i < nmonitor; i++) {
  180.             monitors[i].x = info[i].x_org;
  181.             monitors[i].y = info[i].y_org;
  182.             monitors[i].w = info[i].width;
  183.             monitors[i].h = info[i].height;
  184.         }
  185.         XFree(info);
  186.     }
  187.     else
  188. #endif
  189.     {
  190.         nmonitor = 1;
  191.         monitors[0].x = sx;
  192.         monitors[0].y = sy;
  193.         monitors[0].w = sw;
  194.         monitors[0].h = sh;
  195.     }
  196. }
  197.  
  198. int
  199. main(int argc, char *argv[]) {
  200.     int i;
  201.  
  202.     for(i = 1; i < argc && argv[i][0] == '-' && argv[i][0] != '\0' &&
  203.             argv[i][2] == '\0'; i++)
  204.         switch(argv[i][1]) {
  205.         case 'c':
  206.             center = True; break;
  207.         case 'x':
  208.             running = True; break;
  209.         case 'v':
  210.             die("bgs-"VERSION", � 2008 bgs engineers, see"
  211.                     "LICENSE for details\n");
  212.         default:
  213.             die("usage: bgs [-v] [-c] [-x] [IMAGE]...\n");
  214.         }
  215.     if(!(dpy = XOpenDisplay(0)))
  216.         die("bgs: cannot open display\n");
  217.     setup(&argv[i], argc - i);
  218.     run();
  219.     cleanup();
  220.     XCloseDisplay(dpy);
  221.     return EXIT_SUCCESS;
  222. }
Advertisement
Add Comment
Please, Sign In to add comment