screen.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. * wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
  3. * For license, see COPYING.
  4. */
  5. #ifdef HAVE_XINERAMA
  6. #include <X11/extensions/Xinerama.h>
  7. #endif /* HAVE_XINERAMA */
  8. #include "screen.h"
  9. #include "util.h"
  10. #include "tag.h"
  11. #include "infobar.h"
  12. #include "client.h"
  13. static struct screen*
  14. screen_new(struct geo *g, int id)
  15. {
  16. struct screen *s = (struct screen*)xcalloc(1, sizeof(struct screen));
  17. s->geo = s->ugeo = *g;
  18. s->seltag = NULL;
  19. s->id = id;
  20. s->flags = 0;
  21. TAILQ_INIT(&s->tags);
  22. SLIST_INIT(&s->infobars);
  23. SLIST_INSERT_HEAD(&W->h.screen, s, next);
  24. /* Set as selected screen */
  25. W->screen = s;
  26. return s;
  27. }
  28. void
  29. screen_init(void)
  30. {
  31. struct geo g;
  32. SLIST_INIT(&W->h.screen);
  33. #ifdef HAVE_XINERAMA
  34. XineramaScreenInfo *xsi;
  35. int i, n = 0;
  36. if(XineramaIsActive(W->dpy))
  37. {
  38. xsi = XineramaQueryScreens(W->dpy, &n);
  39. for(i = 0; i < n; ++i)
  40. {
  41. g.x = xsi[i].x_org;
  42. g.y = xsi[i].y_org;
  43. g.w = xsi[i].width;
  44. g.h = xsi[i].height;
  45. screen_new(&g, i);
  46. }
  47. W->nscreen = n;
  48. XFree(xsi);
  49. }
  50. else
  51. #endif /* HAVE_XINERAMA */
  52. {
  53. g.x = g.y = 0;
  54. g.w = DisplayWidth(W->dpy, W->xscreen);
  55. g.h = DisplayHeight(W->dpy, W->xscreen);
  56. screen_new(&g, 0);
  57. W->nscreen = 1;
  58. }
  59. }
  60. /*
  61. * Update selected screen with mouse location
  62. */
  63. struct screen*
  64. screen_update_sel(void)
  65. {
  66. #ifdef HAVE_XINERAMA
  67. if(XineramaIsActive(W->dpy))
  68. return (W->screen = screen_gb_mouse());
  69. #endif /* HAVE_XINERAMA */
  70. return W->screen;
  71. }
  72. static void
  73. screen_select(struct screen *s)
  74. {
  75. XWarpPointer(W->dpy, None, W->root, 0, 0, 0, 0,
  76. s->ugeo.x + (s->ugeo.w >> 1),
  77. s->ugeo.y + (s->ugeo.h >> 1));
  78. W->screen = s;
  79. }
  80. void
  81. uicb_screen_next(Uicb cmd)
  82. {
  83. struct screen *s = SLIST_NEXT(W->screen, next);
  84. (void)cmd;
  85. if(!s)
  86. s = SLIST_FIRST(&W->h.screen);
  87. screen_select(s);
  88. }
  89. void
  90. uicb_screen_prev(Uicb cmd)
  91. {
  92. struct screen *s = SLIST_FIRST(&W->h.screen);
  93. (void)cmd;
  94. while(SLIST_NEXT(s, next) && SLIST_NEXT(s, next) != s)
  95. s = SLIST_NEXT(s, next);
  96. screen_select(s);
  97. }
  98. void
  99. uicb_screen_move_client_next(Uicb cmd)
  100. {
  101. struct screen *s = SLIST_NEXT(W->screen, next);
  102. (void)cmd;
  103. if(!s)
  104. s = SLIST_FIRST(&W->h.screen);
  105. if(W->client)
  106. tag_client(s->seltag, W->client);
  107. }
  108. void
  109. uicb_screen_move_client_prev(Uicb cmd)
  110. {
  111. struct screen *s = SLIST_FIRST(&W->h.screen);
  112. (void)cmd;
  113. while(SLIST_NEXT(s, next) && SLIST_NEXT(s, next) != s)
  114. s = SLIST_NEXT(s, next);
  115. if(W->client)
  116. tag_client(s->seltag, W->client);
  117. }
  118. void
  119. screen_free(void)
  120. {
  121. struct screen *s;
  122. while(!SLIST_EMPTY(&W->h.screen))
  123. {
  124. s = SLIST_FIRST(&W->h.screen);
  125. SLIST_REMOVE_HEAD(&W->h.screen, next);
  126. infobar_free(s);
  127. tag_free(s);
  128. free(s);
  129. }
  130. }