aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/engines/software_16_x11/evas_x_buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/modules/engines/software_16_x11/evas_x_buffer.c')
-rw-r--r--libraries/evas/src/modules/engines/software_16_x11/evas_x_buffer.c186
1 files changed, 186 insertions, 0 deletions
diff --git a/libraries/evas/src/modules/engines/software_16_x11/evas_x_buffer.c b/libraries/evas/src/modules/engines/software_16_x11/evas_x_buffer.c
new file mode 100644
index 0000000..32784b0
--- /dev/null
+++ b/libraries/evas/src/modules/engines/software_16_x11/evas_x_buffer.c
@@ -0,0 +1,186 @@
1#include "evas_common.h"
2#include "evas_engine.h"
3
4static int _x_err = 0;
5
6int
7evas_software_16_x11_x_can_do_shm(Display *d)
8{
9 static Display *cached_d = NULL;
10 static int cached_result = 0;
11
12 if (d == cached_d) return cached_result;
13 cached_d = d;
14 if (XShmQueryExtension(d))
15 {
16 X_Output_Buffer *xob;
17
18 xob = evas_software_16_x11_x_output_buffer_new
19 (d, DefaultVisual(d, DefaultScreen(d)),
20 DefaultDepth(d, DefaultScreen(d)), 16, 16, 2, NULL);
21 if (!xob)
22 {
23 cached_result = 0;
24 return 0;
25 }
26 evas_software_16_x11_x_output_buffer_free(xob, 1);
27 cached_result = 1;
28 return 1;
29 }
30 cached_result = 0;
31 return 0;
32}
33
34static void
35x_output_tmp_x_err(Display * d __UNUSED__, XErrorEvent * ev __UNUSED__)
36{
37 _x_err = 1;
38 return;
39}
40
41X_Output_Buffer *
42evas_software_16_x11_x_output_buffer_new(Display *d, Visual *v, int depth, int w, int h, int try_shm, void *data)
43{
44 X_Output_Buffer *xob;
45
46 xob = calloc(1, sizeof(X_Output_Buffer));
47 if (!xob) return NULL;
48
49 xob->display = d;
50 xob->xim = NULL;
51 xob->shm_info = NULL;
52
53 if (try_shm > 0)
54 {
55 xob->shm_info = malloc(sizeof(XShmSegmentInfo));
56 if (xob->shm_info)
57 {
58 xob->xim = XShmCreateImage(d, v, depth, ZPixmap, NULL,
59 xob->shm_info, w, h);
60 if (xob->xim)
61 {
62 xob->shm_info->shmid = shmget(IPC_PRIVATE,
63 xob->xim->bytes_per_line *
64 xob->xim->height,
65 IPC_CREAT | 0777);
66 if (xob->shm_info->shmid >= 0)
67 {
68 xob->shm_info->readOnly = False;
69 xob->shm_info->shmaddr = xob->xim->data =
70 shmat(xob->shm_info->shmid, 0, 0);
71 if (xob->shm_info->shmaddr)
72 {
73 XErrorHandler ph;
74
75 XSync(d, False);
76 _x_err = 0;
77 ph = XSetErrorHandler((XErrorHandler)
78 x_output_tmp_x_err);
79 XShmAttach(d, xob->shm_info);
80 XSync(d, False);
81 XSetErrorHandler((XErrorHandler)ph);
82 if (!_x_err)
83 {
84 xob->im = (Soft16_Image *) evas_cache_image_data(evas_common_soft16_image_cache_get(), w, h, (DATA32 *) xob->xim->data, 0, EVAS_COLORSPACE_RGB565_A5P);
85 if (xob->im)
86 xob->im->stride = xob->xim->bytes_per_line / sizeof(DATA16);
87 return xob;
88 }
89 }
90 shmdt(xob->shm_info->shmaddr);
91 shmctl(xob->shm_info->shmid, IPC_RMID, 0);
92 }
93 if (xob->xim) XDestroyImage(xob->xim);
94 xob->xim = NULL;
95 }
96 if (xob->shm_info) free(xob->shm_info);
97 xob->shm_info = NULL;
98 }
99 }
100
101 if (try_shm > 1) return NULL;
102
103 xob->xim = XCreateImage(d, v, depth, ZPixmap, 0, data, w, h, 32, 0);
104 if (!xob->xim)
105 {
106 free(xob);
107 return NULL;
108 }
109
110 xob->data = data;
111
112 if (!xob->xim->data)
113 {
114 xob->xim->data = malloc(xob->xim->bytes_per_line * xob->xim->height);
115 if (!xob->xim->data)
116 {
117 XDestroyImage(xob->xim);
118 free(xob);
119 return NULL;
120 }
121 }
122 if (xob->im)
123 evas_cache_image_drop(&xob->im->cache_entry);
124
125 xob->im = (Soft16_Image *) evas_cache_image_data(evas_common_soft16_image_cache_get(), w, h, (DATA32 *) xob->xim->data, 0, EVAS_COLORSPACE_RGB565_A5P);
126 if (xob->im)
127 xob->im->stride = xob->xim->bytes_per_line / sizeof(DATA16);
128 return xob;
129}
130
131void
132evas_software_16_x11_x_output_buffer_free(X_Output_Buffer *xob, int sync)
133{
134 if (xob->shm_info)
135 {
136 if (sync) XSync(xob->display, False);
137 XShmDetach(xob->display, xob->shm_info);
138 XDestroyImage(xob->xim);
139 shmdt(xob->shm_info->shmaddr);
140 shmctl(xob->shm_info->shmid, IPC_RMID, 0);
141 free(xob->shm_info);
142 }
143 else
144 {
145 if (xob->data) xob->xim->data = NULL;
146 XDestroyImage(xob->xim);
147 }
148 free(xob);
149}
150
151void
152evas_software_16_x11_x_output_buffer_paste(X_Output_Buffer *xob, Drawable d, GC gc, int x, int y, int w, int h, int sync)
153{
154 if (xob->shm_info)
155 {
156 XShmPutImage(xob->display, d, gc, xob->xim, 0, 0, x, y, w, h, False);
157 if (sync) XSync(xob->display, False);
158 }
159 else
160 XPutImage(xob->display, d, gc, xob->xim, 0, 0, x, y, w, h);
161}
162
163DATA8 *
164evas_software_16_x11_x_output_buffer_data(X_Output_Buffer *xob, int *bytes_per_line_ret)
165{
166 if (bytes_per_line_ret) *bytes_per_line_ret = xob->xim->bytes_per_line;
167 return (DATA8*) xob->xim->data;
168}
169
170int
171evas_software_16_x11_x_output_buffer_depth(X_Output_Buffer *xob)
172{
173 return xob->xim->bits_per_pixel;
174}
175
176int
177evas_software_16_x11_x_output_buffer_byte_order(X_Output_Buffer *xob)
178{
179 return xob->xim->byte_order;
180}
181
182int
183evas_software_16_x11_x_output_buffer_bit_order(X_Output_Buffer *xob)
184{
185 return xob->xim->bitmap_bit_order;
186}