move around - flatter.
[profile/ivi/evas.git] / src / modules / engines / software_x11 / evas_x_buffer.c
1 #include "evas_common.h"
2 #include "evas_engine.h"
3
4 static int _x_err = 0;
5
6 void
7 evas_software_x11_x_write_mask_line(Outbuf *buf, X_Output_Buffer *xob, DATA32 *src, int w, int y)
8 {
9    int x;
10    DATA32 *src_ptr;
11    DATA8 *dst_ptr;
12    int bpl = 0;
13
14    src_ptr = src;
15    dst_ptr = evas_software_x11_x_output_buffer_data(xob, &bpl);
16    dst_ptr = dst_ptr + (bpl * y);
17    w -= 7;
18    if (buf->priv.x.bit_swap)
19      {
20         for (x = 0; x < w; x += 8)
21           {
22              *dst_ptr =
23                ((A_VAL(&(src_ptr[0])) >> 7) << 7) |
24                ((A_VAL(&(src_ptr[1])) >> 7) << 6) |
25                ((A_VAL(&(src_ptr[2])) >> 7) << 5) |
26                ((A_VAL(&(src_ptr[3])) >> 7) << 4) |
27                ((A_VAL(&(src_ptr[4])) >> 7) << 3) |
28                ((A_VAL(&(src_ptr[5])) >> 7) << 2) |
29                ((A_VAL(&(src_ptr[6])) >> 7) << 1) |
30                ((A_VAL(&(src_ptr[7])) >> 7) << 0);
31              src_ptr += 8;
32              dst_ptr++;
33           }
34      }
35    else
36      {
37         for (x = 0; x < w; x += 8)
38           {
39              *dst_ptr =
40                ((A_VAL(&(src_ptr[0])) >> 7) << 0) |
41                ((A_VAL(&(src_ptr[1])) >> 7) << 1) |
42                ((A_VAL(&(src_ptr[2])) >> 7) << 2) |
43                ((A_VAL(&(src_ptr[3])) >> 7) << 3) |
44                ((A_VAL(&(src_ptr[4])) >> 7) << 4) |
45                ((A_VAL(&(src_ptr[5])) >> 7) << 5) |
46                ((A_VAL(&(src_ptr[6])) >> 7) << 6) |
47                ((A_VAL(&(src_ptr[7])) >> 7) << 7);
48              src_ptr += 8;
49              dst_ptr++;
50           }
51      }
52    w += 7;
53    for (; x < w; x ++)
54      {
55         XPutPixel(xob->xim, x, y, A_VAL(src_ptr) >> 7);
56         src_ptr++;
57      }
58 }
59
60 int
61 evas_software_x11_x_can_do_shm(Display *d)
62 {
63    static Display *cached_d = NULL;
64    static int cached_result = 0;
65    
66    if (d == cached_d) return cached_result;
67    cached_d = d;
68    if (XShmQueryExtension(d))
69      {
70         X_Output_Buffer *xob;
71
72         xob = evas_software_x11_x_output_buffer_new
73           (d, DefaultVisual(d, DefaultScreen(d)),
74            DefaultDepth(d, DefaultScreen(d)), 16, 16, 2, NULL);
75         if (!xob)
76           {
77              cached_result = 0;
78              return 0;
79           }
80         evas_software_x11_x_output_buffer_free(xob, 1);
81         cached_result = 1;
82         return 1;
83      }
84    cached_result = 0;
85    return 0;
86 }
87
88 static void
89 x_output_tmp_x_err(Display * d, XErrorEvent * ev)
90 {
91    _x_err = 1;
92    return;
93 }
94
95 //static int creates = 0;
96
97 X_Output_Buffer *
98 evas_software_x11_x_output_buffer_new(Display *d, Visual *v, int depth, int w, int h, int try_shm, void *data)
99 {
100    X_Output_Buffer *xob;
101
102    xob = calloc(1, sizeof(X_Output_Buffer));
103    if (!xob) return NULL;
104
105    xob->display = d;
106    xob->visual = v;
107    xob->xim = NULL;
108    xob->shm_info = NULL;
109    xob->w = w;
110    xob->h = h;
111
112    if (try_shm > 0)
113      {
114         xob->shm_info = malloc(sizeof(XShmSegmentInfo));
115         if (xob->shm_info)
116           {
117              xob->xim = XShmCreateImage(d, v, depth, ZPixmap, NULL,
118                                         xob->shm_info, w, h);
119              if (xob->xim)
120                {
121                   xob->shm_info->shmid = shmget(IPC_PRIVATE,
122                                                 xob->xim->bytes_per_line *
123                                                 xob->xim->height,
124                                                 IPC_CREAT | 0777);
125                   if (xob->shm_info->shmid >= 0)
126                     {
127                        xob->shm_info->readOnly = False;
128                        xob->shm_info->shmaddr = xob->xim->data =
129                          shmat(xob->shm_info->shmid, 0, 0);
130                        if (xob->shm_info->shmaddr != NULL)
131                          {
132                             XErrorHandler ph;
133
134                             XSync(d, False);
135                             _x_err = 0;
136                             ph = XSetErrorHandler((XErrorHandler)
137                                                   x_output_tmp_x_err);
138                             XShmAttach(d, xob->shm_info);
139                             XSync(d, False);
140                             XSetErrorHandler((XErrorHandler)ph);
141                             if (!_x_err)
142                               {
143 //                               printf("SHM++ ID=%i -> %i bytes [%i creates]\n",
144 //                                      xob->shm_info->shmid,
145 //                                      xob->xim->bytes_per_line * xob->xim->height,
146 //                                      creates);
147 //                               creates++;
148                                  xob->bpl = xob->xim->bytes_per_line;
149                                  xob->psize = xob->bpl * xob->h;
150                                  return xob;
151                               }
152                          }
153                        shmdt(xob->shm_info->shmaddr);
154                        shmctl(xob->shm_info->shmid, IPC_RMID, 0);
155                     }
156                   if (xob->xim) XDestroyImage(xob->xim);
157                   xob->xim = NULL;
158                }
159              if (xob->shm_info) free(xob->shm_info);
160              xob->shm_info = NULL;
161           }
162      }
163
164    if (try_shm > 1) return NULL;
165
166    xob->xim = XCreateImage(d, v, depth, ZPixmap, 0, data, w, h, 32, 0);
167    if (!xob->xim)
168      {
169         free(xob);
170         return NULL;
171      }
172
173    xob->data = data;
174
175    if (!xob->xim->data)
176      {
177         xob->xim->data = malloc(xob->xim->bytes_per_line * xob->xim->height);
178         if (!xob->xim->data)
179           {
180              XDestroyImage(xob->xim);
181              free(xob);
182              return NULL;
183           }
184      }
185    xob->bpl = xob->xim->bytes_per_line;
186    xob->psize = xob->bpl * xob->h;
187    return xob;
188 }
189
190 void
191 evas_software_x11_x_output_buffer_free(X_Output_Buffer *xob, int sync)
192 {
193    if (xob->shm_info)
194      {
195 //      printf("SHM-- ID=%i -> %i bytes, [sync=%i]\n",
196 //             xob->shm_info->shmid,
197 //             xob->xim->bytes_per_line * xob->xim->height,
198 //             sync);
199         if (sync) XSync(xob->display, False);
200         XShmDetach(xob->display, xob->shm_info);
201         XDestroyImage(xob->xim);
202         shmdt(xob->shm_info->shmaddr);
203         shmctl(xob->shm_info->shmid, IPC_RMID, 0);
204         free(xob->shm_info);
205      }
206    else
207      {
208         if (xob->data) xob->xim->data = NULL;
209         XDestroyImage(xob->xim);
210      }
211    free(xob);
212 }
213
214 void
215 evas_software_x11_x_output_buffer_paste(X_Output_Buffer *xob, Drawable d, GC gc, int x, int y, int sync)
216 {
217    if (xob->shm_info)
218      {
219 //      printf("shm\n");
220         XShmPutImage(xob->display, d, gc, xob->xim, 0, 0, x, y,
221                      xob->w, xob->h, False);
222         if (sync) XSync(xob->display, False);
223      }
224    else
225      {
226 //      printf("NO! shm\n");
227         XPutImage(xob->display, d, gc, xob->xim, 0, 0, x, y,
228                   xob->w, xob->h);
229      }
230 }
231
232 DATA8 *
233 evas_software_x11_x_output_buffer_data(X_Output_Buffer *xob, int *bytes_per_line_ret)
234 {
235    if (bytes_per_line_ret) *bytes_per_line_ret = xob->xim->bytes_per_line;
236    return xob->xim->data;
237 }
238
239 int
240 evas_software_x11_x_output_buffer_depth(X_Output_Buffer *xob)
241 {
242    return xob->xim->bits_per_pixel;
243 }
244
245 int
246 evas_software_x11_x_output_buffer_byte_order(X_Output_Buffer *xob)
247 {
248    return xob->xim->byte_order;
249 }
250
251 int
252 evas_software_x11_x_output_buffer_bit_order(X_Output_Buffer *xob)
253 {
254    return xob->xim->bitmap_bit_order;
255 }