1 /*
2 * SPDX-FileCopyrightText: 2014 Weng Xuetian <wengxt@gmail.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7 #include "common.h"
8 #include "parser.h"
9 #include "ximproto.h"
10 #include <stdlib.h>
11 #include <string.h>
12
_xcb_im_init_atoms(xcb_connection_t * conn,size_t n,const char ** atom_names,xcb_atom_t * atoms)13 bool _xcb_im_init_atoms(xcb_connection_t *conn, size_t n,
14 const char **atom_names, xcb_atom_t *atoms) {
15 // here we alloc some array on stack, but since we only use this function
16 // internally and all atom_names size are small (less than 10), so it
17 // doesn't matter.
18 xcb_intern_atom_cookie_t atom_cookies[n];
19 for (size_t i = 0; i < n; i++) {
20 atom_cookies[i] =
21 xcb_intern_atom(conn, false, strlen(atom_names[i]), atom_names[i]);
22 }
23 size_t i;
24 for (i = 0; i < n; i++) {
25 xcb_intern_atom_reply_t *atom_reply =
26 xcb_intern_atom_reply(conn, atom_cookies[i], NULL);
27 if (atom_reply) {
28 atoms[i] = atom_reply->atom;
29 free(atom_reply);
30 } else {
31 break;
32 }
33 }
34 return (i == n);
35 }
36
_xcb_get_event_mask(xcb_connection_t * conn,xcb_window_t window)37 uint32_t _xcb_get_event_mask(xcb_connection_t *conn, xcb_window_t window) {
38 if (window == XCB_NONE) {
39 return 0;
40 }
41 xcb_get_window_attributes_cookie_t cookie =
42 xcb_get_window_attributes(conn, window);
43 xcb_get_window_attributes_reply_t *reply =
44 xcb_get_window_attributes_reply(conn, cookie, NULL);
45 if (!reply) {
46 return 0;
47 }
48 uint32_t your_event_mask = reply->your_event_mask;
49 free(reply);
50 return your_event_mask;
51 }
52
_xcb_change_event_mask(xcb_connection_t * conn,xcb_window_t window,uint32_t mask,bool remove)53 bool _xcb_change_event_mask(xcb_connection_t *conn, xcb_window_t window,
54 uint32_t mask, bool remove) {
55 uint32_t your_event_mask = _xcb_get_event_mask(conn, window);
56
57 uint32_t masks[1];
58 if (remove) {
59 masks[0] = your_event_mask & (~mask);
60 } else {
61 masks[0] = your_event_mask | mask;
62 }
63
64 if (masks[0] == your_event_mask) {
65 return true;
66 }
67
68 xcb_void_cookie_t change_attr_cookie = xcb_change_window_attributes_checked(
69 conn, window, XCB_CW_EVENT_MASK, masks);
70
71 xcb_generic_error_t *error = NULL;
72 if ((error = xcb_request_check(conn, change_attr_cookie)) != NULL) {
73 free(error);
74 return false;
75 }
76 return true;
77 }
78
_xcb_im_ic_attr_size(uint32_t type)79 size_t _xcb_im_ic_attr_size(uint32_t type) {
80 switch (type) {
81 case XimType_CARD32:
82 case XimType_Window: {
83 return sizeof(uint32_t);
84 }
85 case XimType_XRectangle: {
86 xcb_im_xrectangle_fr_t fr;
87 return xcb_im_xrectangle_fr_size(&fr);
88 }
89 case XimType_XPoint: {
90 xcb_im_xpoint_fr_t fr;
91 return xcb_im_xpoint_fr_size(&fr);
92 }
93 }
94 return 0;
95 }
96
_xcb_im_get_ic_value(void * p,uint32_t type,uint8_t * data,bool swap)97 uint8_t *_xcb_im_get_ic_value(void *p, uint32_t type, uint8_t *data,
98 bool swap) {
99 switch (type) {
100 case XimType_CARD32:
101 case XimType_Window: {
102 uint32_t *result = p;
103 data = uint32_t_write(result, data, swap);
104 break;
105 }
106 case XimType_XRectangle: {
107 xcb_rectangle_t *result = p;
108 xcb_im_xrectangle_fr_t fr;
109 fr.x = result->x;
110 fr.y = result->y;
111 fr.width = result->width;
112 fr.height = result->height;
113 data = xcb_im_xrectangle_fr_write(&fr, data, swap);
114 break;
115 }
116 case XimType_XPoint: {
117 xcb_point_t *result = p;
118 xcb_im_xpoint_fr_t fr;
119 fr.x = result->x;
120 fr.y = result->y;
121 data = xcb_im_xpoint_fr_write(&fr, data, swap);
122 break;
123 }
124 case XimType_XFontSet: {
125 break;
126 }
127 }
128 return data;
129 }
130