window.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. /* Copyright 2001-2003 by Norbert Freudemann, David Frese */
  2. #include "xlib.h"
  3. s48_ref_t scx_set_window_attribute_binding = NULL;
  4. #define scx_extract_set_window_attribute(c, x) \
  5. S48_EXTRACT_ENUM(c, x, scx_set_window_attribute_binding)
  6. static unsigned long
  7. scx_extract_set_window_attribute_alist(s48_call_t call, s48_ref_t attribs,
  8. XSetWindowAttributes* Xattrs) {
  9. unsigned long mask = 0;
  10. s48_ref_t v = s48_false_2(call);
  11. while (!s48_null_p_2(call, attribs)) {
  12. int mv =
  13. scx_extract_set_window_attribute(call,
  14. s48_car_2(call, s48_car_2(call, attribs)));
  15. v = s48_cdr_2(call, s48_car_2(call, attribs));
  16. s48_ref_t temp = attribs;
  17. attribs = s48_cdr_2(call, attribs);
  18. s48_free_local_ref(call, temp);
  19. mask = mask | (1L << mv);
  20. switch (1L << mv) {
  21. case CWBackPixmap:
  22. Xattrs->background_pixmap = scx_extract_pixmap(call, v); break;
  23. case CWBackPixel:
  24. Xattrs->background_pixel = scx_extract_pixel(call, v); break;
  25. case CWBorderPixmap:
  26. Xattrs->border_pixmap = scx_extract_pixmap(call, v); break;
  27. case CWBorderPixel:
  28. Xattrs->border_pixel = scx_extract_pixel(call, v); break;
  29. case CWBitGravity:
  30. Xattrs->bit_gravity = scx_extract_bit_gravity(call, v); break;
  31. case CWWinGravity:
  32. Xattrs->win_gravity = scx_extract_win_gravity(call, v); break;
  33. case CWBackingStore:
  34. Xattrs->backing_store = scx_extract_backing_store(call, v); break;
  35. case CWBackingPlanes:
  36. Xattrs->backing_planes = s48_extract_long_2(call, v); break;
  37. case CWBackingPixel:
  38. Xattrs->backing_pixel = scx_extract_pixel(call, v); break;
  39. case CWOverrideRedirect:
  40. Xattrs->override_redirect = s48_extract_boolean_2(call, v); break;
  41. case CWSaveUnder:
  42. Xattrs->save_under = s48_extract_boolean_2(call, v); break;
  43. case CWEventMask:
  44. Xattrs->event_mask = scx_extract_event_mask(call, v); break;
  45. case CWDontPropagate:
  46. Xattrs->do_not_propagate_mask = scx_extract_event_mask(call, v); break;
  47. case CWColormap:
  48. Xattrs->colormap = scx_extract_colormap(call, v); break;
  49. case CWCursor:
  50. Xattrs->cursor = scx_extract_cursor(call, v); break;
  51. }
  52. }
  53. return mask;
  54. }
  55. s48_ref_t scx_Create_Window (s48_call_t call, s48_ref_t display,
  56. s48_ref_t parent,
  57. s48_ref_t x, s48_ref_t y,
  58. s48_ref_t width, s48_ref_t height,
  59. s48_ref_t border_width, s48_ref_t depth,
  60. s48_ref_t class, s48_ref_t visual,
  61. s48_ref_t attribs) {
  62. Window win;
  63. XSetWindowAttributes Xattrs;
  64. unsigned long mask;
  65. mask = scx_extract_set_window_attribute_alist(call, attribs, &Xattrs);
  66. win = XCreateWindow(scx_extract_display(call, display),
  67. scx_extract_window(call, parent),
  68. (int)s48_extract_long_2(call, x),
  69. (int)s48_extract_long_2(call, y),
  70. (int)s48_extract_long_2(call, width),
  71. (int)s48_extract_long_2(call, height),
  72. (int)s48_extract_long_2(call, border_width),
  73. s48_extract_long_2(call, depth),
  74. scx_extract_window(call, class),
  75. scx_extract_visual(call, visual), mask, &Xattrs);
  76. return scx_enter_window(call, win);
  77. }
  78. s48_ref_t scx_Create_Simple_Window(s48_call_t call, s48_ref_t display,
  79. s48_ref_t parent,
  80. s48_ref_t x, s48_ref_t y,
  81. s48_ref_t width, s48_ref_t height,
  82. s48_ref_t border_width, s48_ref_t border,
  83. s48_ref_t background) {
  84. Window win;
  85. win = XCreateSimpleWindow(scx_extract_display(call, display),
  86. scx_extract_window(call, parent),
  87. (int)s48_extract_long_2(call, x),
  88. (int)s48_extract_long_2(call, y),
  89. (int)s48_extract_long_2(call, width),
  90. (int)s48_extract_long_2(call, height),
  91. (int)s48_extract_long_2(call, border_width),
  92. s48_extract_long_2(call, border),
  93. s48_extract_long_2(call, background));
  94. return scx_enter_window(call, win);
  95. }
  96. s48_ref_t scx_Change_Window_Attributes(s48_call_t call, s48_ref_t display,
  97. s48_ref_t window, s48_ref_t attribs) {
  98. XSetWindowAttributes Xattrs;
  99. unsigned long mask;
  100. mask = scx_extract_set_window_attribute_alist(call, attribs, &Xattrs);
  101. XChangeWindowAttributes(scx_extract_display(call, display),
  102. scx_extract_window(call, window),
  103. mask, &Xattrs);
  104. return s48_unspecific_2(call);
  105. }
  106. s48_ref_t scx_enter_window_changes(s48_call_t call, XWindowChanges* WC,
  107. unsigned long mask) {
  108. s48_ref_t res = s48_null_2(call), t = s48_false_2(call);
  109. if (mask & CWX) {
  110. t = scx_enter_window_change(call, 0);
  111. t = s48_cons_2(call, t, s48_enter_long_2(call, WC->x));
  112. res = s48_cons_2(call, t, res);
  113. }
  114. if (mask & CWY) {
  115. t = scx_enter_window_change(call, 1);
  116. t = s48_cons_2(call, t, s48_enter_long_2(call, WC->y));
  117. res = s48_cons_2(call, t, res);
  118. }
  119. if (mask & CWWidth) {
  120. t = scx_enter_window_change(call, 2);
  121. t = s48_cons_2(call, t, s48_enter_long_2(call, WC->width));
  122. res = s48_cons_2(call, t, res);
  123. }
  124. if (mask & CWHeight) {
  125. t = scx_enter_window_change(call, 3);
  126. t = s48_cons_2(call, t, s48_enter_long_2(call, WC->height));
  127. res = s48_cons_2(call, t, res);
  128. }
  129. if (mask & CWBorderWidth) {
  130. t = scx_enter_window_change(call, 4);
  131. t = s48_cons_2(call, t, s48_enter_long_2(call, WC->border_width));
  132. res = s48_cons_2(call, t, res);
  133. }
  134. if (mask & CWSibling) {
  135. t = scx_enter_window_change(call, 5);
  136. t = s48_cons_2(call, t, scx_enter_window(call, WC->sibling));
  137. res = s48_cons_2(call, t, res);
  138. }
  139. if (mask & CWStackMode) {
  140. t = scx_enter_window_change(call, 6);
  141. t = s48_cons_2(call, t, scx_enter_stack_mode(call, WC->stack_mode));
  142. res = s48_cons_2(call, t, res);
  143. }
  144. return res;
  145. }
  146. unsigned long scx_extract_window_changes(s48_call_t call, s48_ref_t changes,
  147. XWindowChanges* WC) {
  148. unsigned long mask = 0;
  149. s48_ref_t v = s48_false_2(call);
  150. while (!s48_null_p_2(call, changes)) {
  151. int mv = scx_extract_window_change(call,
  152. s48_car_2(call, s48_car_2(call, changes)));
  153. v = s48_cdr_2(call, s48_car_2(call, changes));
  154. changes = s48_cdr_2(call, changes);
  155. mask = mask | (1L << mv);
  156. switch (1L << mv) {
  157. case CWX:
  158. WC->x = s48_extract_long_2(call, v); break;
  159. case CWY:
  160. WC->y = s48_extract_long_2(call, v); break;
  161. case CWWidth:
  162. WC->width = s48_extract_long_2(call, v); break;
  163. case CWHeight:
  164. WC->height = s48_extract_long_2(call, v); break;
  165. case CWBorderWidth:
  166. WC->border_width = s48_extract_long_2(call, v); break;
  167. case CWSibling:
  168. WC->sibling = scx_extract_window(call, v); break;
  169. case CWStackMode:
  170. WC->stack_mode = scx_extract_stack_mode(call, v); break;
  171. }
  172. }
  173. return mask;
  174. }
  175. s48_ref_t scx_Configure_Window(s48_call_t call, s48_ref_t display,
  176. s48_ref_t window, s48_ref_t changes) {
  177. XWindowChanges WC;
  178. unsigned long mask;
  179. mask = scx_extract_window_changes(call, changes, &WC);
  180. XConfigureWindow(scx_extract_display(call, display),
  181. scx_extract_window(call, window),
  182. mask, &WC);
  183. return s48_unspecific_2(call);
  184. }
  185. s48_ref_t scx_window_attibutes_binding = NULL;
  186. s48_ref_t scx_enter_window_attributes(s48_call_t call, XWindowAttributes* WA) {
  187. s48_ref_t v = s48_make_record_2(call, scx_window_attibutes_binding);
  188. s48_record_set_2(call, v, 0, s48_enter_long_2(call, WA->x));
  189. s48_record_set_2(call, v, 1, s48_enter_long_2(call, WA->y));
  190. s48_record_set_2(call, v, 2, s48_enter_long_2(call, WA->width));
  191. s48_record_set_2(call, v, 3, s48_enter_long_2(call, WA->height));
  192. s48_record_set_2(call, v, 4, s48_enter_long_2(call, WA->border_width));
  193. s48_record_set_2(call, v, 5, s48_enter_long_2(call, WA->depth));
  194. s48_record_set_2(call, v, 6, scx_enter_visual(call, WA->visual));
  195. s48_record_set_2(call, v, 7, scx_enter_window(call, WA->root));
  196. s48_record_set_2(call, v, 8, scx_enter_window_class(call, WA->class));
  197. s48_record_set_2(call, v, 9, scx_enter_bit_gravity(call, WA->bit_gravity));
  198. s48_record_set_2(call, v, 10, scx_enter_win_gravity(call, WA->win_gravity));
  199. s48_record_set_2(call, v, 11, scx_enter_backing_store(call, WA->backing_store));
  200. s48_record_set_2(call, v, 12, s48_enter_long_2(call, WA->backing_planes));
  201. s48_record_set_2(call, v, 13, scx_enter_pixel(call, WA->backing_pixel));
  202. s48_record_set_2(call, v, 14, s48_enter_boolean_2(call, WA->save_under));
  203. s48_record_set_2(call, v, 15, scx_enter_colormap(call, WA->colormap));
  204. s48_record_set_2(call, v, 16, s48_enter_boolean_2(call, WA->map_installed));
  205. s48_record_set_2(call, v, 17, scx_enter_map_state(call, WA->map_state));
  206. s48_record_set_2(call, v, 18, scx_enter_event_mask(call, WA->all_event_masks));
  207. s48_record_set_2(call, v, 19, scx_enter_event_mask(call, WA->your_event_mask));
  208. s48_record_set_2(call, v, 20, scx_enter_event_mask(call, WA->do_not_propagate_mask));
  209. s48_record_set_2(call, v, 21, s48_enter_boolean_2(call, WA->override_redirect));
  210. s48_record_set_2(call, v, 22, scx_enter_screen(call, WA->screen));
  211. return v;
  212. }
  213. s48_ref_t scx_Get_Window_Attributes(s48_call_t call, s48_ref_t display,
  214. s48_ref_t window) {
  215. XWindowAttributes WA;
  216. if (!XGetWindowAttributes(scx_extract_display(call, display),
  217. scx_extract_window(call, window),
  218. &WA))
  219. return s48_false_2(call);
  220. else
  221. return scx_enter_window_attributes(call, &WA);
  222. }
  223. s48_ref_t scx_Get_Geometry(s48_call_t call, s48_ref_t display,
  224. s48_ref_t drawable) {
  225. s48_ref_t v = s48_false_2(call);
  226. Window root;
  227. int x, y;
  228. unsigned int width, height, border_width, depth;
  229. if (!XGetGeometry(scx_extract_display(call, display),
  230. scx_extract_drawable(call, drawable),
  231. &root, &x, &y, &width, &height, &border_width, &depth))
  232. return s48_false_2(call);
  233. else {
  234. v = s48_make_vector_2(call, 7, s48_false_2(call));
  235. s48_vector_set_2(call, v, 0, scx_enter_window(call, root));
  236. s48_vector_set_2(call, v, 1, s48_enter_long_as_fixnum_2(call, x));
  237. s48_vector_set_2(call, v, 2, s48_enter_long_as_fixnum_2(call, y));
  238. s48_vector_set_2(call, v, 3, s48_enter_long_as_fixnum_2(call, width));
  239. s48_vector_set_2(call, v, 4, s48_enter_long_as_fixnum_2(call, height));
  240. s48_vector_set_2(call, v, 5, s48_enter_long_as_fixnum_2(call, border_width));
  241. s48_vector_set_2(call, v, 6, s48_enter_long_as_fixnum_2(call, depth));
  242. return v;
  243. }
  244. }
  245. s48_ref_t scx_Map_Window(s48_call_t call, s48_ref_t display, s48_ref_t window) {
  246. XMapWindow(scx_extract_display(call, display),
  247. scx_extract_window(call, window));
  248. return s48_unspecific_2(call);
  249. }
  250. s48_ref_t scx_Map_Raised(s48_call_t call, s48_ref_t display, s48_ref_t window) {
  251. XMapRaised(scx_extract_display(call, display),
  252. scx_extract_window(call, window));
  253. return s48_unspecific_2(call);
  254. }
  255. s48_ref_t scx_Map_Subwindows(s48_call_t call, s48_ref_t display,
  256. s48_ref_t window) {
  257. XMapSubwindows(scx_extract_display(call, display),
  258. scx_extract_window(call, window));
  259. return s48_unspecific_2(call);
  260. }
  261. s48_ref_t scx_Unmap_Window(s48_call_t call, s48_ref_t display, s48_ref_t window) {
  262. XUnmapWindow(scx_extract_display(call, display),
  263. scx_extract_window(call, window));
  264. return s48_unspecific_2(call);
  265. }
  266. s48_ref_t scx_Unmap_Subwindows(s48_call_t call, s48_ref_t display,
  267. s48_ref_t window) {
  268. XUnmapSubwindows(scx_extract_display(call, display),
  269. scx_extract_window(call, window));
  270. return s48_unspecific_2(call);
  271. }
  272. s48_ref_t scx_Destroy_Window(s48_call_t call, s48_ref_t display,
  273. s48_ref_t window) {
  274. XDestroyWindow(scx_extract_display(call, display),
  275. scx_extract_window(call, window));
  276. return s48_unspecific_2(call);
  277. }
  278. s48_ref_t scx_Destroy_Subwindows(s48_call_t call, s48_ref_t display,
  279. s48_ref_t window) {
  280. XDestroySubwindows(scx_extract_display(call, display),
  281. scx_extract_window(call, window));
  282. return s48_unspecific_2(call);
  283. }
  284. s48_ref_t scx_Raise_Window(s48_call_t call, s48_ref_t display,
  285. s48_ref_t window) {
  286. XRaiseWindow(scx_extract_display(call, display),
  287. scx_extract_window(call, window));
  288. return s48_unspecific_2(call);
  289. }
  290. s48_ref_t scx_Lower_Window(s48_call_t call, s48_ref_t display,
  291. s48_ref_t window) {
  292. XLowerWindow(scx_extract_display(call, display),
  293. scx_extract_window(call, window));
  294. return s48_unspecific_2(call);
  295. }
  296. s48_ref_t scx_circulate_direction_binding = NULL;
  297. #define scx_extract_direction(c, x) \
  298. S48_EXTRACT_ENUM(c, x, scx_circulate_direction_binding)
  299. s48_ref_t scx_Circulate_Subwindows(s48_call_t call, s48_ref_t display,
  300. s48_ref_t window, s48_ref_t dir) {
  301. XCirculateSubwindows(scx_extract_display(call, display),
  302. scx_extract_window(call, window),
  303. scx_extract_direction(call, dir));
  304. return s48_unspecific_2(call);
  305. }
  306. s48_ref_t scx_Restack_Windows(s48_call_t call, s48_ref_t display,
  307. s48_ref_t windows) {
  308. int i, n = s48_extract_long_2(call, s48_length_2(call, windows));
  309. Window wins[n];
  310. for (i = n-1; i >= 0; i--) {
  311. wins[i] = scx_extract_window(call, s48_car_2(call, windows));
  312. windows = s48_cdr_2(call, windows);
  313. }
  314. XRestackWindows(scx_extract_display(call, display),
  315. wins, n);
  316. return s48_unspecific_2(call);
  317. }
  318. s48_ref_t scx_Clear_Area(s48_call_t call, s48_ref_t display, s48_ref_t window,
  319. s48_ref_t x, s48_ref_t y,
  320. s48_ref_t width, s48_ref_t height,
  321. s48_ref_t exposures) {
  322. XClearArea(scx_extract_display(call, display),
  323. scx_extract_window(call, window),
  324. s48_extract_long_2(call, x), s48_extract_long_2(call, y),
  325. s48_extract_long_2(call, width), s48_extract_long_2(call, height),
  326. s48_extract_boolean_2(call, exposures));
  327. return s48_unspecific_2(call);
  328. }
  329. s48_ref_t scx_Clear_Window(s48_call_t call, s48_ref_t display, s48_ref_t window) {
  330. XClearWindow(scx_extract_display(call, display),
  331. scx_extract_window(call, window));
  332. return s48_unspecific_2(call);
  333. }
  334. s48_ref_t scx_Query_Tree(s48_call_t call, s48_ref_t display, s48_ref_t window) {
  335. Window root, parent, *children;
  336. int i;
  337. unsigned n;
  338. s48_ref_t c = s48_null_2(call), res = s48_null_2(call);
  339. if (! XQueryTree (scx_extract_display(call, display),
  340. scx_extract_window(call, window),
  341. &root, &parent, &children, &n))
  342. return s48_false_2(call);
  343. for (i = 0; i < n; i++)
  344. c = s48_cons_2(call, scx_enter_window(call, children[i]), c);
  345. if (children != NULL) XFree(children);
  346. res = s48_cons_2(call, c, res);
  347. res = s48_cons_2(call, scx_enter_window(call, parent), res);
  348. res = s48_cons_2(call, scx_enter_window(call, root), res);
  349. return res;
  350. }
  351. s48_ref_t scx_Translate_Coordinates(s48_call_t call, s48_ref_t display,
  352. s48_ref_t src,
  353. s48_ref_t dest,
  354. s48_ref_t x, s48_ref_t y) {
  355. int rx, ry;
  356. Window child;
  357. s48_ref_t res = s48_null_2(call);
  358. if (!XTranslateCoordinates(scx_extract_display(call, display),
  359. scx_extract_window(call, src),
  360. scx_extract_window(call, dest),
  361. (int)s48_extract_long_2(call, x),
  362. (int)s48_extract_long_2(call, y),
  363. &rx, &ry, &child))
  364. return s48_false_2(call);
  365. res = s48_cons_2(call, scx_enter_window(call, child), res);
  366. res = s48_cons_2(call, s48_enter_long_as_fixnum_2(call, ry), res);
  367. res = s48_cons_2(call, s48_enter_long_as_fixnum_2(call, rx), res);
  368. return res;
  369. }
  370. s48_ref_t scx_Query_Pointer(s48_call_t call, s48_ref_t display,
  371. s48_ref_t window) {
  372. s48_ref_t v = s48_false_2(call);
  373. Bool ret;
  374. Window root, child;
  375. int r_x, r_y, x, y;
  376. unsigned int mask;
  377. ret = XQueryPointer(scx_extract_display(call, display),
  378. scx_extract_window(call, window),
  379. &root, &child, &r_x, &r_y, &x, &y, &mask);
  380. v = s48_make_vector_2(call, 8, s48_false_2(call));
  381. s48_vector_set_2(call, v, 0, scx_enter_window(call, root));
  382. s48_vector_set_2(call, v, 1, scx_enter_window(call, child));
  383. s48_vector_set_2(call, v, 2, s48_enter_long_as_fixnum_2(call, r_x));
  384. s48_vector_set_2(call, v, 3, s48_enter_long_as_fixnum_2(call, r_y));
  385. s48_vector_set_2(call, v, 4, s48_enter_long_as_fixnum_2(call, x));
  386. s48_vector_set_2(call, v, 5, s48_enter_long_as_fixnum_2(call, y));
  387. s48_vector_set_2(call, v, 6, s48_enter_long_2(call, (unsigned long)mask));
  388. s48_vector_set_2(call, v, 7, ret ? s48_true_2(call) : s48_false_2(call));
  389. return v;
  390. }
  391. void scx_init_window(void) {
  392. scx_set_window_attribute_binding =
  393. s48_get_imported_binding_2("scx-set-window-attribute");
  394. scx_window_attibutes_binding =
  395. s48_get_imported_binding_2("scx-window-attributes");
  396. scx_circulate_direction_binding =
  397. s48_get_imported_binding_2("scx-circulate-direction");
  398. S48_EXPORT_FUNCTION(scx_Create_Window);
  399. S48_EXPORT_FUNCTION(scx_Create_Simple_Window);
  400. S48_EXPORT_FUNCTION(scx_Change_Window_Attributes);
  401. S48_EXPORT_FUNCTION(scx_Configure_Window);
  402. S48_EXPORT_FUNCTION(scx_Get_Window_Attributes);
  403. S48_EXPORT_FUNCTION(scx_Get_Geometry);
  404. S48_EXPORT_FUNCTION(scx_Map_Window);
  405. S48_EXPORT_FUNCTION(scx_Map_Raised);
  406. S48_EXPORT_FUNCTION(scx_Map_Subwindows);
  407. S48_EXPORT_FUNCTION(scx_Unmap_Window);
  408. S48_EXPORT_FUNCTION(scx_Unmap_Subwindows);
  409. S48_EXPORT_FUNCTION(scx_Destroy_Window);
  410. S48_EXPORT_FUNCTION(scx_Destroy_Subwindows);
  411. S48_EXPORT_FUNCTION(scx_Raise_Window);
  412. S48_EXPORT_FUNCTION(scx_Lower_Window);
  413. S48_EXPORT_FUNCTION(scx_Circulate_Subwindows);
  414. S48_EXPORT_FUNCTION(scx_Restack_Windows);
  415. S48_EXPORT_FUNCTION(scx_Clear_Area);
  416. S48_EXPORT_FUNCTION(scx_Clear_Window);
  417. S48_EXPORT_FUNCTION(scx_Query_Tree);
  418. S48_EXPORT_FUNCTION(scx_Translate_Coordinates);
  419. S48_EXPORT_FUNCTION(scx_Query_Pointer);
  420. }