r1010: Save mask point coordinates using %g instead of %e to save space.
[cinelerra_cv/ct.git] / guicast / bcpixmap.C
blob3a4152bf930c6d2302edf663c53b2dff80062978
1 #include "bcbitmap.h"
2 #include "bcpixmap.h"
3 #include "bcresources.h"
4 #include "bcsignals.h"
5 #include "bcsynchronous.h"
6 #include "bcwindowbase.h"
7 #include "vframe.h"
10 #include <unistd.h>
12 BC_Pixmap::BC_Pixmap(BC_WindowBase *parent_window, 
13         VFrame *frame, 
14         int mode,
15         int icon_offset)
17         reset();
19         BC_Bitmap *opaque_bitmap, *alpha_bitmap, *mask_bitmap;
20         if(frame->get_color_model() != BC_RGBA8888 &&
21                 mode == PIXMAP_ALPHA)
22                 mode = PIXMAP_OPAQUE;
23         this->mode = mode;
25 // Temporary bitmaps
26         if(use_opaque())
27         {
28                 opaque_bitmap = new BC_Bitmap(parent_window, 
29                                         frame->get_w(), 
30                                         frame->get_h(), 
31                                         parent_window->get_color_model(), 
32                                         0);
33                 opaque_bitmap->set_bg_color(parent_window->get_bg_color());
34                 opaque_bitmap->read_frame(frame, 
35                         0, 
36                         0, 
37                         frame->get_w(), 
38                         frame->get_h());
39                 
40         }
42         if(use_alpha())
43         {
44                 alpha_bitmap = new BC_Bitmap(parent_window, 
45                                 frame->get_w(), 
46                                 frame->get_h(), 
47                                 BC_TRANSPARENCY, 
48                                 0);
50                 if(frame->get_color_model() != BC_RGBA8888)
51                         printf("BC_Pixmap::BC_Pixmap: PIXMAP_ALPHA but frame doesn't have alpha.\n");
52                 alpha_bitmap->read_frame(frame, 
53                         0, 
54                         0, 
55                         frame->get_w(), 
56                         frame->get_h());
57         }
59         initialize(parent_window, 
60                 frame->get_w(), 
61                 frame->get_h(), 
62                 mode);
64         if(use_opaque())
65         {
66                 opaque_bitmap->write_drawable(opaque_pixmap, 
67                                                                 top_level->gc,
68                                                                 0, 
69                                                                 0, 
70                                                                 0, 
71                                                                 0, 
72                                                                 w, 
73                                                                 h, 
74                                                                 1);
75                 delete opaque_bitmap;
76         }
78         if(use_alpha())
79         {
80                 alpha_bitmap->write_drawable(alpha_pixmap, 
81                         copy_gc, 
82                         0, 
83                         0, 
84                         icon_offset ? 2 : 0, 
85                         icon_offset ? 2 : 0, 
86                         w, 
87                         h, 
88                         1);
89                 delete alpha_bitmap;
90                 XFreeGC(top_level->display, copy_gc);
92                 XSetClipMask(top_level->display, alpha_gc, alpha_pixmap);
93         }
96 BC_Pixmap::BC_Pixmap(BC_WindowBase *parent_window, int w, int h)
98         reset();
99         initialize(parent_window, w, h, PIXMAP_OPAQUE);
103 BC_Pixmap::~BC_Pixmap()
105         if(use_opaque())
106         {
107 #ifdef HAVE_XFT
108                 if(opaque_xft_draw)
109                         XftDrawDestroy((XftDraw*)opaque_xft_draw);
110 #endif
111                 XFreePixmap(top_level->display, opaque_pixmap);
112         }
114         if(use_alpha())
115         {
116                 XFreeGC(top_level->display, alpha_gc);
117 #ifdef HAVE_XFT
118                 if(alpha_xft_draw)
119                         XftDrawDestroy((XftDraw*)alpha_xft_draw);
120 #endif
121                 XFreePixmap(top_level->display, alpha_pixmap);
122         }
125 // Have to delete GL objects because pixmaps are deleted during resizes.
126 #ifdef HAVE_GL
127         if(BC_WindowBase::get_synchronous() && gl_pixmap)
128         {
129                 BC_WindowBase::get_synchronous()->delete_pixmap(parent_window,
130                         gl_pixmap,
131                         gl_pixmap_context);
132         }
133 #endif
137 void BC_Pixmap::reset()
139         parent_window = 0;
140         top_level = 0;
141         opaque_pixmap = 0;
142         alpha_pixmap = 0;
143         opaque_xft_draw = 0;
144         alpha_xft_draw = 0;
145 #ifdef HAVE_GL
146         gl_pixmap_context = 0;
147         gl_pixmap = 0;
148 #endif
151 int BC_Pixmap::initialize(BC_WindowBase *parent_window, int w, int h, int mode)
153         this->w = w;
154         this->h = h;
155         this->parent_window = parent_window;
156         this->mode = mode;
157         top_level = parent_window->top_level;
159         if(use_opaque())
160         {
161                 opaque_pixmap = XCreatePixmap(top_level->display, 
162                         top_level->win, 
163                         w, 
164                         h, 
165                         top_level->default_depth);
166 #ifdef HAVE_XFT
167                 if(BC_WindowBase::get_resources()->use_xft)
168                 {
169                         opaque_xft_draw = XftDrawCreate(top_level->display,
170                            opaque_pixmap,
171                            top_level->vis,
172                            top_level->cmap);
173                 }
174 #endif
175         }
177         if(use_alpha())
178         {
179                 unsigned long gcmask = GCGraphicsExposures | 
180                         GCForeground | 
181                         GCBackground | 
182                         GCFunction;
183                 XGCValues gcvalues;
184                 gcvalues.graphics_exposures = 0;        // prevent expose events for every redraw
185                 gcvalues.foreground = 0;
186                 gcvalues.background = 1;
187                 gcvalues.function = GXcopy;
189                 alpha_pixmap = XCreatePixmap(top_level->display, 
190                         top_level->win, 
191                         w, 
192                         h, 
193                         1);
195                 alpha_gc = XCreateGC(top_level->display, 
196                         top_level->win, 
197                         gcmask, 
198                         &gcvalues);
200                 copy_gc = XCreateGC(top_level->display,
201                         alpha_pixmap,
202                         gcmask,
203                         &gcvalues);
205 #ifdef HAVE_XFT
206                 if(BC_WindowBase::get_resources()->use_xft)
207                 {
208                         alpha_xft_draw = XftDrawCreateBitmap(top_level->display,
209                                 alpha_pixmap);
210                 }
211 #endif
212         }
216 // // For some reason, this is required in 32 bit.
217 // #ifdef HAVE_XFT
218 //      if(BC_WindowBase::get_resources()->use_xft)
219 //              XSync(top_level->display, False);
220 // #endif
221         
222         return 0;
225 void BC_Pixmap::resize(int w, int h)
227         Pixmap new_pixmap = XCreatePixmap(top_level->display, 
228                         top_level->win, 
229                         w, 
230                         h, 
231                         top_level->default_depth);
232 #ifdef HAVE_XFT
233         XftDraw *new_xft_draw;
234         if(BC_WindowBase::get_resources()->use_xft)
235         {
236                 new_xft_draw = XftDrawCreate(top_level->display,
237                        new_pixmap,
238                        top_level->vis,
239                        top_level->cmap);
240         }
241 #endif
246         XCopyArea(top_level->display,
247                 opaque_pixmap,
248                 new_pixmap,
249                 top_level->gc,
250                 0,
251                 0,
252                 get_w(),
253                 get_h(),
254                 0,
255                 0);
256         this->w = w;
257         this->h = h;
258 #ifdef HAVE_XFT
259         if(BC_WindowBase::get_resources()->use_xft)
260                 XftDrawDestroy((XftDraw*)opaque_xft_draw);
261 #endif
262         XFreePixmap(top_level->display, opaque_pixmap);
264         opaque_pixmap = new_pixmap;
265 #ifdef HAVE_XFT
266         if(BC_WindowBase::get_resources()->use_xft)
267                 opaque_xft_draw = new_xft_draw;
268 #endif
272 void BC_Pixmap::copy_area(int x, int y, int w, int h, int x2, int y2)
274         XCopyArea(top_level->display,
275                 opaque_pixmap,
276                 opaque_pixmap,
277                 top_level->gc,
278                 x,
279                 y,
280                 w,
281                 h,
282                 x2,
283                 y2);
286 int BC_Pixmap::write_drawable(Drawable &pixmap, 
287                         int dest_x, 
288                         int dest_y,
289                         int dest_w,
290                         int dest_h,
291                         int src_x,
292                         int src_y)
294 //printf("BC_Pixmap::write_drawable 1\n");
295         if(dest_w < 0)
296         {
297                 dest_w = w;
298                 src_x = 0;
299         }
300         
301         if(dest_h < 0)
302         {
303                 dest_h = h;
304                 src_y = 0;
305         }
307         if(use_alpha())
308         {
309                 XSetClipOrigin(top_level->display, alpha_gc, dest_x - src_x, dest_y - src_y);
310                 XCopyArea(top_level->display, 
311                         this->opaque_pixmap, 
312                         pixmap, 
313                         alpha_gc, 
314                         src_x, 
315                         src_y, 
316                         dest_w, 
317                         dest_h, 
318                         dest_x, 
319                         dest_y);
320         }
321         else
322         if(use_opaque())
323         {
324                 XCopyArea(top_level->display, 
325                         this->opaque_pixmap, 
326                         pixmap, 
327                         top_level->gc, 
328                         src_x, 
329                         src_y, 
330                         dest_w, 
331                         dest_h, 
332                         dest_x, 
333                         dest_y);
334         }
335 //printf("BC_Pixmap::write_drawable 2\n");
337         return 0;
340 void BC_Pixmap::draw_vframe(VFrame *frame, 
341                 int dest_x, 
342                 int dest_y, 
343                 int dest_w, 
344                 int dest_h,
345                 int src_x,
346                 int src_y)
348         parent_window->draw_vframe(frame, 
349                 dest_x, 
350                 dest_y, 
351                 dest_w, 
352                 dest_h,
353                 src_x,
354                 src_y,
355                 0,
356                 0,
357                 this);
360 void BC_Pixmap::draw_pixmap(BC_Pixmap *pixmap, 
361         int dest_x, 
362         int dest_y,
363         int dest_w,
364         int dest_h,
365         int src_x,
366         int src_y)
368         pixmap->write_drawable(this->opaque_pixmap,
369                         dest_x, 
370                         dest_y,
371                         dest_w,
372                         dest_h,
373                         src_x,
374                         src_y);
387 int BC_Pixmap::get_w()
389         return w;
392 int BC_Pixmap::get_h()
394         return h;
397 int BC_Pixmap::get_w_fixed()
399         return w - 1;
402 int BC_Pixmap::get_h_fixed()
404         return h - 1;
407 Pixmap BC_Pixmap::get_pixmap()
409         return opaque_pixmap;
412 Pixmap BC_Pixmap::get_alpha()
414         return alpha_pixmap;
417 int BC_Pixmap::use_opaque()
419         return 1;
422 int BC_Pixmap::use_alpha()
424         return mode == PIXMAP_ALPHA;
428 void BC_Pixmap::enable_opengl()
430 printf("BC_Pixmap::enable_opengl called but it doesn't work.\n");
431 #ifdef HAVE_GL
432         BC_WindowBase *current_window = BC_WindowBase::get_synchronous()->current_window;
433         if(!gl_pixmap_context)
434         {
435                 
436 //              XVisualInfo viproto;
437 //              int nvi;
438 //              viproto.screen = current_window->get_screen();
439 //              static int framebuffer_attributes[] = 
440 //              {
441 //              GLX_RGBA,
442 //              GLX_RED_SIZE, 1,
443 //              GLX_GREEN_SIZE, 1,
444 //              GLX_BLUE_SIZE, 1,
445 //                      None
446 //              };
447 //              XVisualInfo *visinfo = glXChooseVisual(current_window->get_display(),
448 //                      current_window->get_screen(),
449 //                      framebuffer_attributes);
450 // printf("BC_Pixmap::enable_opengl 1 %p\n", visinfo->visual);
451 //              gl_pixmap = glXCreateGLXPixmap(current_window->get_display(),
452 //             visinfo,
453 //             opaque_pixmap);
454 // printf("BC_Pixmap::enable_opengl 2 %p\n", gl_pixmap);
455 // // This context must be indirect, but because it's indirect, it can't share
456 // // ID's with the window context.
457 //              gl_pixmap_context = glXCreateContext(current_window->get_display(),
458 //                      visinfo,
459 //                      0,
460 //                      0);
461 // printf("BC_Pixmap::enable_opengl 3 %p\n", gl_pixmap_context);
463                 static int framebuffer_attributes[] = 
464                 {
465                 GLX_RENDER_TYPE, GLX_RGBA_BIT,
466                         GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
467                         GLX_DOUBLEBUFFER, 0,
468                 GLX_RED_SIZE, 1,
469                 GLX_GREEN_SIZE, 1,
470                 GLX_BLUE_SIZE, 1,
471                         None
472                 };
473                 XVisualInfo *visinfo = 0;
474                 int config_result_count = 0;
475                 GLXFBConfig *config_result = glXChooseFBConfig(current_window->get_display(), 
476                         current_window->get_screen(), 
477                         framebuffer_attributes, 
478                         &config_result_count);
479                 if(config_result)
480                 {
481                         gl_pixmap = glXCreatePixmap(current_window->get_display(),
482                                 config_result[0],
483                                 opaque_pixmap,
484                                 0);
486                         visinfo = glXGetVisualFromFBConfig(current_window->get_display(), 
487                                 config_result[0]);
488                 }
490 // provide window context to share ID's.
491                 if(visinfo)
492                 {
493                         gl_pixmap_context = glXCreateContext(current_window->get_display(),
494                                         visinfo,
495                                         0,
496                                         0);
497                 }
499                 if(config_result) XFree(config_result);
500         if(visinfo) XFree(visinfo);
501         }
503         if(gl_pixmap_context)
504         {
505                 glXMakeCurrent(top_level->display,
506                         gl_pixmap,
507                         gl_pixmap_context);
508         }
509 #endif