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