r860: Merge 2.1:
[cinelerra_cv.git] / guicast / bcpixmap.C
blob3c8a7f5e2716e031e2e8f013dd3153fbd03c7caf
1 #include "bcbitmap.h"
2 #include "bcpixmap.h"
3 #include "bcsignals.h"
4 #include "bcwindowbase.h"
5 #include "vframe.h"
8 #include <unistd.h>
10 BC_Pixmap::BC_Pixmap(BC_WindowBase *parent_window, 
11         VFrame *frame, 
12         int mode,
13         int icon_offset)
15         reset();
17         BC_Bitmap *opaque_bitmap, *alpha_bitmap, *mask_bitmap;
18         if(frame->get_color_model() != BC_RGBA8888 &&
19                 mode == PIXMAP_ALPHA)
20                 mode = PIXMAP_OPAQUE;
21         this->mode = mode;
23 // Temporary bitmaps
24         if(use_opaque())
25         {
26                 opaque_bitmap = new BC_Bitmap(parent_window, 
27                                         frame->get_w(), 
28                                         frame->get_h(), 
29                                         parent_window->get_color_model(), 
30                                         0);
31                 opaque_bitmap->set_bg_color(parent_window->get_bg_color());
32                 opaque_bitmap->read_frame(frame, 
33                         0, 
34                         0, 
35                         frame->get_w(), 
36                         frame->get_h());
37                 
38         }
40         if(use_alpha())
41         {
42                 alpha_bitmap = new BC_Bitmap(parent_window, 
43                                 frame->get_w(), 
44                                 frame->get_h(), 
45                                 BC_TRANSPARENCY, 
46                                 0);
48                 if(frame->get_color_model() != BC_RGBA8888)
49                         printf("BC_Pixmap::BC_Pixmap: PIXMAP_ALPHA but frame doesn't have alpha.\n");
50                 alpha_bitmap->read_frame(frame, 
51                         0, 
52                         0, 
53                         frame->get_w(), 
54                         frame->get_h());
55         }
57         initialize(parent_window, 
58                 frame->get_w(), 
59                 frame->get_h(), 
60                 mode);
62         if(use_opaque())
63         {
64                 opaque_bitmap->write_drawable(opaque_pixmap, 
65                                                                 top_level->gc,
66                                                                 0, 
67                                                                 0, 
68                                                                 0, 
69                                                                 0, 
70                                                                 w, 
71                                                                 h, 
72                                                                 1);
73                 delete opaque_bitmap;
74         }
76         if(use_alpha())
77         {
78                 alpha_bitmap->write_drawable(alpha_pixmap, 
79                         copy_gc, 
80                         0, 
81                         0, 
82                         icon_offset ? 2 : 0, 
83                         icon_offset ? 2 : 0, 
84                         w, 
85                         h, 
86                         1);
87                 delete alpha_bitmap;
88                 XFreeGC(top_level->display, copy_gc);
90                 XSetClipMask(top_level->display, alpha_gc, alpha_pixmap);
91         }
94 BC_Pixmap::BC_Pixmap(BC_WindowBase *parent_window, int w, int h)
96         reset();
97         initialize(parent_window, w, h, PIXMAP_OPAQUE);
101 BC_Pixmap::~BC_Pixmap()
103         if(use_opaque())
104         {
105 #ifdef HAVE_XFT
106                 if(opaque_xft_draw)
107                         XftDrawDestroy((XftDraw*)opaque_xft_draw);
108 #endif
109                 XFreePixmap(top_level->display, opaque_pixmap);
110         }
112         if(use_alpha())
113         {
114                 XFreeGC(top_level->display, alpha_gc);
115 #ifdef HAVE_XFT
116                 if(alpha_xft_draw)
117                         XftDrawDestroy((XftDraw*)alpha_xft_draw);
118 #endif
119                 XFreePixmap(top_level->display, alpha_pixmap);
120         }
125 void BC_Pixmap::reset()
127         parent_window = 0;
128         top_level = 0;
129         opaque_pixmap = 0;
130         alpha_pixmap = 0;
131         opaque_xft_draw = 0;
132         alpha_xft_draw = 0;
135 int BC_Pixmap::initialize(BC_WindowBase *parent_window, int w, int h, int mode)
137         this->w = w;
138         this->h = h;
139         this->parent_window = parent_window;
140         this->mode = mode;
141         top_level = parent_window->top_level;
143         if(use_opaque())
144         {
145                 opaque_pixmap = XCreatePixmap(top_level->display, 
146                         top_level->win, 
147                         w, 
148                         h, 
149                         top_level->default_depth);
150 #ifdef HAVE_XFT
151                 if(BC_WindowBase::get_resources()->use_xft)
152                 {
153                         opaque_xft_draw = XftDrawCreate(top_level->display,
154                            opaque_pixmap,
155                            top_level->vis,
156                            top_level->cmap);
157                 }
158 #endif
159         }
161         if(use_alpha())
162         {
163                 unsigned long gcmask = GCGraphicsExposures | 
164                         GCForeground | 
165                         GCBackground | 
166                         GCFunction;
167                 XGCValues gcvalues;
168                 gcvalues.graphics_exposures = 0;        // prevent expose events for every redraw
169                 gcvalues.foreground = 0;
170                 gcvalues.background = 1;
171                 gcvalues.function = GXcopy;
173                 alpha_pixmap = XCreatePixmap(top_level->display, 
174                         top_level->win, 
175                         w, 
176                         h, 
177                         1);
179                 alpha_gc = XCreateGC(top_level->display, 
180                         top_level->win, 
181                         gcmask, 
182                         &gcvalues);
184                 copy_gc = XCreateGC(top_level->display,
185                         alpha_pixmap,
186                         gcmask,
187                         &gcvalues);
189 #ifdef HAVE_XFT
190                 if(BC_WindowBase::get_resources()->use_xft)
191                 {
192                         alpha_xft_draw = XftDrawCreateBitmap(top_level->display,
193                                 alpha_pixmap);
194                 }
195 #endif
196         }
200 // // For some reason, this is required in 32 bit.
201 // #ifdef HAVE_XFT
202 //      if(BC_WindowBase::get_resources()->use_xft)
203 //              XSync(top_level->display, False);
204 // #endif
205         
206         return 0;
209 void BC_Pixmap::resize(int w, int h)
211         Pixmap new_pixmap = XCreatePixmap(top_level->display, 
212                         top_level->win, 
213                         w, 
214                         h, 
215                         top_level->default_depth);
216 #ifdef HAVE_XFT
217         XftDraw *new_xft_draw;
218         if(BC_WindowBase::get_resources()->use_xft)
219         {
220                 new_xft_draw = XftDrawCreate(top_level->display,
221                        new_pixmap,
222                        top_level->vis,
223                        top_level->cmap);
224         }
225 #endif
230         XCopyArea(top_level->display,
231                 opaque_pixmap,
232                 new_pixmap,
233                 top_level->gc,
234                 0,
235                 0,
236                 get_w(),
237                 get_h(),
238                 0,
239                 0);
240         this->w = w;
241         this->h = h;
242 #ifdef HAVE_XFT
243         if(BC_WindowBase::get_resources()->use_xft)
244                 XftDrawDestroy((XftDraw*)opaque_xft_draw);
245 #endif
246         XFreePixmap(top_level->display, opaque_pixmap);
248         opaque_pixmap = new_pixmap;
249 #ifdef HAVE_XFT
250         if(BC_WindowBase::get_resources()->use_xft)
251                 opaque_xft_draw = new_xft_draw;
252 #endif
256 void BC_Pixmap::copy_area(int x, int y, int w, int h, int x2, int y2)
258         XCopyArea(top_level->display,
259                 opaque_pixmap,
260                 opaque_pixmap,
261                 top_level->gc,
262                 x,
263                 y,
264                 w,
265                 h,
266                 x2,
267                 y2);
270 int BC_Pixmap::write_drawable(Drawable &pixmap, 
271                         int dest_x, 
272                         int dest_y,
273                         int dest_w,
274                         int dest_h,
275                         int src_x,
276                         int src_y)
278 //printf("BC_Pixmap::write_drawable 1\n");
279         if(dest_w < 0)
280         {
281                 dest_w = w;
282                 src_x = 0;
283         }
284         
285         if(dest_h < 0)
286         {
287                 dest_h = h;
288                 src_y = 0;
289         }
291         if(use_alpha())
292         {
293                 XSetClipOrigin(top_level->display, alpha_gc, dest_x - src_x, dest_y - src_y);
294                 XCopyArea(top_level->display, 
295                         this->opaque_pixmap, 
296                         pixmap, 
297                         alpha_gc, 
298                         src_x, 
299                         src_y, 
300                         dest_w, 
301                         dest_h, 
302                         dest_x, 
303                         dest_y);
304         }
305         else
306         if(use_opaque())
307         {
308                 XCopyArea(top_level->display, 
309                         this->opaque_pixmap, 
310                         pixmap, 
311                         top_level->gc, 
312                         src_x, 
313                         src_y, 
314                         dest_w, 
315                         dest_h, 
316                         dest_x, 
317                         dest_y);
318         }
319 //printf("BC_Pixmap::write_drawable 2\n");
321         return 0;
324 void BC_Pixmap::draw_vframe(VFrame *frame, 
325                 int dest_x, 
326                 int dest_y, 
327                 int dest_w, 
328                 int dest_h,
329                 int src_x,
330                 int src_y)
332         parent_window->draw_vframe(frame, 
333                 dest_x, 
334                 dest_y, 
335                 dest_w, 
336                 dest_h,
337                 src_x,
338                 src_y,
339                 0,
340                 0,
341                 this);
344 void BC_Pixmap::draw_pixmap(BC_Pixmap *pixmap, 
345         int dest_x, 
346         int dest_y,
347         int dest_w,
348         int dest_h,
349         int src_x,
350         int src_y)
352         pixmap->write_drawable(this->opaque_pixmap,
353                         dest_x, 
354                         dest_y,
355                         dest_w,
356                         dest_h,
357                         src_x,
358                         src_y);
371 int BC_Pixmap::get_w()
373         return w;
376 int BC_Pixmap::get_h()
378         return h;
381 int BC_Pixmap::get_w_fixed()
383         return w - 1;
386 int BC_Pixmap::get_h_fixed()
388         return h - 1;
391 Pixmap BC_Pixmap::get_pixmap()
393         return opaque_pixmap;
396 Pixmap BC_Pixmap::get_alpha()
398         return alpha_pixmap;
401 int BC_Pixmap::use_opaque()
403         return 1;
406 int BC_Pixmap::use_alpha()
408         return mode == PIXMAP_ALPHA;