aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/engines/software_8_x11/evas_x_buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/modules/engines/software_8_x11/evas_x_buffer.c')
-rw-r--r--libraries/evas/src/modules/engines/software_8_x11/evas_x_buffer.c243
1 files changed, 243 insertions, 0 deletions
diff --git a/libraries/evas/src/modules/engines/software_8_x11/evas_x_buffer.c b/libraries/evas/src/modules/engines/software_8_x11/evas_x_buffer.c
new file mode 100644
index 0000000..a2c40b1
--- /dev/null
+++ b/libraries/evas/src/modules/engines/software_8_x11/evas_x_buffer.c
@@ -0,0 +1,243 @@
1#include "evas_common.h"
2#include "evas_engine.h"
3
4static int _xcb_err = 0;
5
6int
7evas_software_8_x11_x_can_do_shm(xcb_connection_t * c, xcb_screen_t * screen)
8{
9 static xcb_connection_t *cached_c = NULL;
10 static int cached_result = 0;
11
12 if (c == cached_c)
13 return cached_result;
14 cached_c = c;
15
16 if (xcb_get_extension_data(c, &xcb_shm_id))
17 {
18 X_Output_Buffer *xob;
19
20 xob = evas_software_8_x11_x_output_buffer_new
21 (c, screen, screen->root_depth, (unsigned char *)NULL,
22 16, 16, 2, NULL);
23 if (!xob)
24 {
25 cached_result = 0;
26 return 0;
27 }
28 evas_software_8_x11_x_output_buffer_free(xob, 1);
29 cached_result = 1;
30 return 1;
31 }
32 cached_result = 0;
33 return 0;
34}
35
36X_Output_Buffer *
37evas_software_8_x11_x_output_buffer_new(xcb_connection_t * c,
38 xcb_screen_t * s,
39 int depth,
40 unsigned char *pal,
41 int w, int h, int try_shm, void *data)
42{
43 X_Output_Buffer *xob;
44
45 xob = calloc(1, sizeof(X_Output_Buffer));
46 if (!xob)
47 return NULL;
48
49 xob->connection = c;
50 xob->screen = s;
51 xob->xim = NULL;
52 xob->shm_info = NULL;
53 xob->pal = pal;
54
55 if (try_shm > 0)
56 {
57 xob->shm_info = malloc(sizeof(xcb_shm_segment_info_t));
58 if (xob->shm_info)
59 {
60 xob->shm_info->shmseg = xcb_generate_id(c);
61 xob->xim = xcb_image_create_native(c, w, h,
62 XCB_IMAGE_FORMAT_Z_PIXMAP,
63 depth, NULL, ~0, NULL);
64 if (xob->xim)
65 {
66 int shmid = shmget
67 (IPC_PRIVATE, xob->xim->size, IPC_CREAT | 0777);
68
69 if (shmid >= 0)
70 {
71 xob->shm_info->shmid = shmid;
72 xob->shm_info->shmaddr = xob->xim->data =
73 shmat(xob->shm_info->shmid, 0, 0);
74
75 if (xob->shm_info->shmaddr)
76 {
77 /*
78 * FIXME: no error mechanism
79 */
80
81 /* XErrorHandler ph; */
82 /* EventHandlers eh; */
83
84 free(xcb_get_input_focus_reply
85 (c, xcb_get_input_focus_unchecked(c), NULL));
86 _xcb_err = 0;
87 /* ph = XSetErrorHandler((XErrorHandler) */
88 /* x_output_tmp_x_err); */
89 xcb_shm_attach(c,
90 xob->shm_info->shmseg,
91 xob->shm_info->shmid, 0);
92 free(xcb_get_input_focus_reply
93 (c, xcb_get_input_focus_unchecked(c), NULL));
94 /* XSetErrorHandler((XErrorHandler)ph); */
95 if (!_xcb_err)
96 {
97 xob->im =
98 (Soft8_Image *)
99 evas_cache_image_data
100 (evas_common_soft8_image_cache_get(), w, h,
101 (DATA32 *) xob->xim->data, 0,
102 EVAS_COLORSPACE_GRY8);
103
104 if (xob->im)
105 xob->im->stride =
106 xob->xim->stride / sizeof(DATA8);
107 return xob;
108 }
109 }
110 shmdt(xob->shm_info->shmaddr);
111 shmctl(xob->shm_info->shmid, IPC_RMID, 0);
112 }
113 if (xob->xim)
114 xcb_image_destroy(xob->xim);
115 xob->xim = NULL;
116 }
117 if (xob->shm_info)
118 free(xob->shm_info);
119 xob->shm_info = NULL;
120 }
121 }
122
123 if (try_shm > 1)
124 return NULL;
125
126 xob->xim = xcb_image_create_native(c, w, h, XCB_IMAGE_FORMAT_Z_PIXMAP,
127 depth, NULL, ~0, NULL);
128 if (!xob->xim)
129 {
130 free(xob);
131 return NULL;
132 }
133
134 xob->data = data;
135
136 if (!xob->xim->data)
137 {
138 xob->xim->data = malloc(xob->xim->stride * xob->xim->height);
139 if (!xob->xim->data)
140 {
141 xcb_image_destroy(xob->xim);
142 free(xob);
143 return NULL;
144 }
145 }
146 if (xob->im)
147 evas_cache_image_drop(&xob->im->cache_entry);
148
149 xob->im =
150 (Soft8_Image *)
151 evas_cache_image_data(evas_common_soft8_image_cache_get(), w, h,
152 (DATA32 *) xob->xim->data, 0,
153 EVAS_COLORSPACE_GRY8);
154 if (xob->im)
155 xob->im->stride = xob->xim->stride / sizeof(DATA8);
156 return xob;
157}
158
159void
160evas_software_8_x11_x_output_buffer_free(X_Output_Buffer * xob, int sync)
161{
162 if (xob->shm_info)
163 {
164 if (sync)
165 free(xcb_get_input_focus_reply(xob->connection,
166 xcb_get_input_focus_unchecked(xob->
167 connection),
168 NULL));
169 xcb_shm_detach(xob->connection, xob->shm_info->shmseg);
170 xcb_image_destroy(xob->xim);
171 shmdt(xob->shm_info->shmaddr);
172 shmctl(xob->shm_info->shmid, IPC_RMID, 0);
173 free(xob->shm_info);
174 }
175 else
176 {
177 if (xob->data)
178 xob->xim->data = NULL;
179 free(xob->xim->data);
180 xcb_image_destroy(xob->xim);
181 }
182 free(xob);
183}
184
185void
186evas_software_8_x11_x_output_buffer_paste(X_Output_Buffer * xob,
187 xcb_drawable_t d,
188 xcb_gcontext_t gc,
189 int x, int y, int w, int h, int sync)
190{
191 unsigned char *data;
192 int i, j;
193
194 if (xob->shm_info)
195 {
196 for (i = y; i < y + h; i++)
197 {
198 data = xob->xim->data + i * xob->xim->width + x;
199 for (j = x; j < x + w; j++, data++)
200 *data = xob->pal[*data];
201 }
202
203 xcb_image_shm_put(xob->connection, d, gc,
204 xob->xim, *xob->shm_info, x, y, x, y, w, h, 0);
205
206 if (sync)
207 free(xcb_get_input_focus_reply(xob->connection,
208 xcb_get_input_focus_unchecked(xob->
209 connection),
210 NULL));
211 }
212 else
213 {
214 xcb_image_put(xob->connection, d, gc, xob->xim, x, y, 0);
215 }
216}
217
218DATA8 *
219evas_software_8_x11_x_output_buffer_data(X_Output_Buffer * xob,
220 int *bytes_per_line_ret)
221{
222 if (bytes_per_line_ret)
223 *bytes_per_line_ret = xob->xim->stride;
224 return (DATA8 *) xob->xim->data;
225}
226
227int
228evas_software_8_x11_x_output_buffer_depth(X_Output_Buffer * xob)
229{
230 return xob->xim->bpp;
231}
232
233int
234evas_software_8_x11_x_output_buffer_byte_order(X_Output_Buffer * xob)
235{
236 return xob->xim->byte_order;
237}
238
239int
240evas_software_8_x11_x_output_buffer_bit_order(X_Output_Buffer * xob)
241{
242 return xob->xim->bit_order;
243}