screen.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. * screen.c
  3. * Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are
  8. * met:
  9. *
  10. * * Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * * Redistributions in binary form must reproduce the above
  13. * copyright notice, this list of conditions and the following disclaimer
  14. * in the documentation and/or other materials provided with the
  15. * distribution.
  16. * * Neither the name of the nor the names of its
  17. * contributors may be used to endorse or promote products derived from
  18. * this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. */
  32. #include "wmfs.h"
  33. /** Count the screens
  34. *\return the number of screen
  35. */
  36. int
  37. screen_count(void)
  38. {
  39. int n = 0;
  40. n = ScreenCount(dpy);
  41. #ifdef HAVE_XINERAMA
  42. if(XineramaIsActive(dpy))
  43. XineramaQueryScreens(dpy, &n);
  44. #endif /* HAVE_XINERAMA */
  45. /* Set _WMFS_SCREEN_COUNT */
  46. if(net_atom)
  47. XChangeProperty(dpy, ROOT, net_atom[wmfs_screen_count], XA_CARDINAL, 32,
  48. PropModeReplace, (uchar*)&n, 1);
  49. return n;
  50. }
  51. /** Get screen geometry by number
  52. *\param s Screen number
  53. *\return XRectangle struct
  54. */
  55. XRectangle
  56. screen_get_geo(int s)
  57. {
  58. int barpos = tags[selscreen][seltag[selscreen]].barpos;
  59. XRectangle geo;
  60. geo.x = BORDH;
  61. if(barpos == IB_Hide || barpos == IB_Bottom)
  62. geo.y = TBARH;
  63. else
  64. geo.y = INFOBARH + TBARH;
  65. geo.height = MAXH - INFOBARH - TBARH;
  66. geo.width = MAXW;
  67. #ifdef HAVE_XINERAMA
  68. if(XineramaIsActive(dpy))
  69. {
  70. XineramaScreenInfo *xsi;
  71. int n = 0;
  72. xsi = XineramaQueryScreens(dpy, &n);
  73. geo.x = xsi[s].x_org + BORDH;
  74. if(barpos == IB_Hide || barpos == IB_Bottom)
  75. geo.y = TBARH;
  76. else
  77. geo.y = xsi[s].y_org + INFOBARH + TBARH;
  78. geo.height = xsi[s].height - INFOBARH - TBARH;
  79. geo.width = xsi[s].width;
  80. XFree(xsi);
  81. }
  82. #endif /* HAVE_XINERAMA */
  83. return geo;
  84. }
  85. /** Get the current screen number with
  86. * coordinated
  87. *\param geo Geometry for get the screen number
  88. *\return The screen number
  89. */
  90. int
  91. screen_get_with_geo(int x, int y)
  92. {
  93. int i, r = 0;
  94. for(i = 0; i < screen_count(); ++i)
  95. if((x >= spgeo[i].x && x < spgeo[i].x + spgeo[i].width)
  96. && y >= spgeo[i].y && y < spgeo[i].y + spgeo[i].height)
  97. r = i;
  98. return r;
  99. }
  100. /** Set the selected screen
  101. *\param screen Number of the wanted selected screen
  102. */
  103. void
  104. screen_set_sel(int screen)
  105. {
  106. if(screen < 0 || screen > screen_count() - 1)
  107. screen = 0;
  108. prevselscreen = selscreen;
  109. client_focus(NULL);
  110. XWarpPointer(dpy, None, ROOT, 0, 0, 0, 0,
  111. sgeo[screen].x + sgeo[screen].width / 2,
  112. sgeo[screen].y + sgeo[screen].height / 2);
  113. selscreen = screen;
  114. return;
  115. }
  116. /** Get and set the selected screen
  117. *\return The number of the selected screen
  118. */
  119. int
  120. screen_get_sel(void)
  121. {
  122. int os = selscreen;
  123. selscreen = 0;
  124. #ifdef HAVE_XINERAMA
  125. if(XineramaIsActive(dpy))
  126. {
  127. /* Unused variables (except x/y) */
  128. Window w;
  129. int d, x, y;
  130. XQueryPointer(dpy, ROOT, &w, &w, &x, &y, &d, &d, (uint *)&d);
  131. selscreen = screen_get_with_geo(x, y);
  132. }
  133. #endif /* HAVE_XINERAMA */
  134. /* Set _WMFS_CURRENT_SCREEN */
  135. XChangeProperty(dpy, ROOT, net_atom[wmfs_current_screen], XA_CARDINAL, 32,
  136. PropModeReplace, (uchar*)&selscreen, 1);
  137. if(os != selscreen)
  138. prevselscreen = os;
  139. return selscreen;
  140. }
  141. /** Init screen geo
  142. */
  143. void
  144. screen_init_geo(void)
  145. {
  146. int i;
  147. int s = screen_count();
  148. sgeo = emalloc(s, sizeof(XRectangle));
  149. spgeo = emalloc(s, sizeof(XRectangle));
  150. for(i = 0; i < s; ++i)
  151. sgeo[i] = screen_get_geo(i);
  152. spgeo[0].x = 0;
  153. spgeo[0].y = 0;
  154. spgeo[0].width = MAXW;
  155. spgeo[0].height = MAXH;
  156. #ifdef HAVE_XINERAMA
  157. XineramaScreenInfo *xsi;
  158. int n;
  159. if(XineramaIsActive(dpy))
  160. {
  161. xsi = XineramaQueryScreens(dpy, &n);
  162. for(i = 0; i < n; ++i)
  163. {
  164. spgeo[i].x = xsi[i].x_org;
  165. spgeo[i].y = xsi[i].y_org;
  166. spgeo[i].width = xsi[i].width;
  167. spgeo[i].height = xsi[i].height;
  168. }
  169. XFree(xsi);
  170. }
  171. #endif /* HAVE_XINERAMA */
  172. #ifdef HAVE_XRANDR
  173. /* Init xrandr stuff */
  174. int d;
  175. XRRSelectInput(dpy, ROOT, 1);
  176. XRRQueryExtension(dpy, &xrandr_event, &d);
  177. #endif /* HAVE_XRANDR */
  178. ewmh_set_desktop_geometry();
  179. ewmh_set_workarea();
  180. return;
  181. }
  182. /** Uicb: screen select
  183. * \param cmd Screen uicb_t type
  184. */
  185. void
  186. uicb_screen_select(uicb_t cmd)
  187. {
  188. screen_set_sel(atoi(cmd));
  189. return;
  190. }
  191. /** Uicb: screen next
  192. * \param cmd Screen uicb_t type
  193. */
  194. void
  195. uicb_screen_next(uicb_t cmd)
  196. {
  197. screen_get_sel();
  198. selscreen = (selscreen + 1 > screen_count() - 1) ? 0 : selscreen + 1;
  199. screen_set_sel(selscreen);
  200. return;
  201. }
  202. /** Uicb: screen prev
  203. * \param cmd Screen uicb_t type
  204. */
  205. void
  206. uicb_screen_prev(uicb_t cmd)
  207. {
  208. screen_get_sel();
  209. selscreen = (selscreen - 1 < 0) ? screen_count() - 1 : selscreen - 1;
  210. screen_set_sel(selscreen);
  211. return;
  212. }
  213. /** Uicb: screen prev sel
  214. * \param cmd uicb_t type unused
  215. */
  216. void
  217. uicb_screen_prev_sel(uicb_t cmd)
  218. {
  219. screen_get_sel();
  220. screen_set_sel(prevselscreen);
  221. return;
  222. }