4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "bcresources.h"
25 #include "bcsignals.h"
26 #include "bcsynchronous.h"
27 #include "bcwindowbase.h"
29 #include "workarounds.h"
33 BC_Pixmap::BC_Pixmap(BC_WindowBase *parent_window,
40 BC_Bitmap *opaque_bitmap = 0, *alpha_bitmap = 0;
41 if(frame->get_color_model() != BC_RGBA8888 && mode == PIXMAP_ALPHA)
48 opaque_bitmap = new BC_Bitmap(parent_window,
49 frame->get_w(), frame->get_h(),
50 parent_window->get_color_model(), 0);
51 opaque_bitmap->read_frame(frame,
52 0, 0, frame->get_w(), frame->get_h());
58 alpha_bitmap = new BC_Bitmap(parent_window,
64 if(frame->get_color_model() != BC_RGBA8888)
65 printf("BC_Pixmap::BC_Pixmap: PIXMAP_ALPHA but frame doesn't have alpha.\n");
66 alpha_bitmap->read_frame(frame,
73 initialize(parent_window,
80 opaque_bitmap->write_drawable(opaque_pixmap,
81 top_level->gc, 0, 0, 0, 0, w, h, 1);
87 alpha_bitmap->write_drawable(alpha_pixmap,
88 copy_gc, 0, 0, icon_offset ? 2 : 0, icon_offset ? 2 : 0, w, h, 1);
90 XFreeGC(top_level->display, copy_gc);
92 XSetClipMask(top_level->display, alpha_gc, alpha_pixmap);
96 BC_Pixmap::BC_Pixmap(BC_WindowBase *parent_window, int w, int h)
99 initialize(parent_window, w, h, PIXMAP_OPAQUE);
103 BC_Pixmap::~BC_Pixmap()
109 xftDrawDestroy((XftDraw*)opaque_xft_draw);
111 XFreePixmap(top_level->display, opaque_pixmap);
116 XFreeGC(top_level->display, alpha_gc);
119 xftDrawDestroy((XftDraw*)alpha_xft_draw);
121 XFreePixmap(top_level->display, alpha_pixmap);
125 // Have to delete GL objects because pixmaps are deleted during resizes.
127 if(BC_WindowBase::get_synchronous() && glx_pixmap)
129 BC_WindowBase::get_synchronous()->delete_pixmap(parent_window,
130 glx_pixmap, glx_pixmap_context);
136 void BC_Pixmap::reset()
145 glx_pixmap_context = 0;
150 int BC_Pixmap::initialize(BC_WindowBase *parent_window, int w, int h, int mode)
156 this->parent_window = parent_window;
158 top_level = parent_window->top_level;
162 opaque_pixmap = XCreatePixmap(top_level->display,
166 top_level->default_depth);
168 if(BC_WindowBase::get_resources()->use_xft)
170 opaque_xft_draw = xftDrawCreate(top_level->display,
180 unsigned long gcmask = GCGraphicsExposures |
185 gcvalues.graphics_exposures = 0; // prevent expose events for every redraw
186 gcvalues.foreground = 0;
187 gcvalues.background = 1;
188 gcvalues.function = GXcopy;
190 alpha_pixmap = XCreatePixmap(top_level->display,
191 top_level->win, w, h, 1);
192 alpha_gc = XCreateGC(top_level->display,
193 top_level->win, gcmask, &gcvalues);
194 copy_gc = XCreateGC(top_level->display,
195 alpha_pixmap, gcmask, &gcvalues);
198 if(BC_WindowBase::get_resources()->use_xft)
200 alpha_xft_draw = xftDrawCreateBitmap(top_level->display,
208 // // For some reason, this is required in 32 bit.
210 // if(BC_WindowBase::get_resources()->use_xft)
211 // XSync(top_level->display, False);
217 void BC_Pixmap::resize(int w, int h)
219 Pixmap new_pixmap = XCreatePixmap(top_level->display,
223 top_level->default_depth);
225 XftDraw *new_xft_draw = 0;
226 if(BC_WindowBase::get_resources()->use_xft) {
227 new_xft_draw = xftDrawCreate(top_level->display,
237 XCopyArea(top_level->display,
250 if(BC_WindowBase::get_resources()->use_xft)
251 xftDrawDestroy((XftDraw*)opaque_xft_draw);
253 XFreePixmap(top_level->display, opaque_pixmap);
255 opaque_pixmap = new_pixmap;
257 if(BC_WindowBase::get_resources()->use_xft)
258 opaque_xft_draw = new_xft_draw;
263 void BC_Pixmap::copy_area(int x, int y, int w, int h, int x2, int y2)
265 XCopyArea(top_level->display,
266 opaque_pixmap, opaque_pixmap, top_level->gc,
270 int BC_Pixmap::write_drawable(Drawable &pixmap,
271 int dest_x, int dest_y, int dest_w, int dest_h,
272 int src_x, int src_y)
274 //printf("BC_Pixmap::write_drawable 1\n");
289 XSetClipOrigin(top_level->display, alpha_gc, dest_x - src_x, dest_y - src_y);
290 XCopyArea(top_level->display,
291 this->opaque_pixmap, pixmap, alpha_gc,
292 src_x, src_y, dest_w, dest_h, dest_x, dest_y);
297 XCopyArea(top_level->display,
298 this->opaque_pixmap, pixmap, top_level->gc,
299 src_x, src_y, dest_w, dest_h, dest_x, dest_y);
301 //printf("BC_Pixmap::write_drawable 2\n");
306 void BC_Pixmap::draw_vframe(VFrame *frame,
307 int dest_x, int dest_y, int dest_w, int dest_h,
308 int src_x, int src_y)
310 parent_window->draw_vframe(frame,
311 dest_x, dest_y, dest_w, dest_h, src_x,
315 void BC_Pixmap::draw_pixmap(BC_Pixmap *pixmap,
316 int dest_x, int dest_y, int dest_w, int dest_h,
317 int src_x, int src_y)
319 pixmap->write_drawable(this->opaque_pixmap,
320 dest_x, dest_y, dest_w, dest_h,
325 int BC_Pixmap::get_w() { return w; }
326 int BC_Pixmap::get_h() { return h; }
327 int BC_Pixmap::get_w_fixed() { return w - 1; }
328 int BC_Pixmap::get_h_fixed() { return h - 1; }
329 Pixmap BC_Pixmap::get_pixmap() { return opaque_pixmap; }
330 Pixmap BC_Pixmap::get_alpha() { return alpha_pixmap; }
331 int BC_Pixmap::use_opaque() { return 1; }
332 int BC_Pixmap::use_alpha() { return mode == PIXMAP_ALPHA; }
335 void BC_Pixmap::enable_opengl()
337 //printf("BC_Pixmap::enable_opengl called but it doesn't work.\n");
339 BC_WindowBase *current_window = BC_WindowBase::get_synchronous()->current_window;
340 if(!glx_pixmap_context) {
341 GLXFBConfig *glx_fb_configs = current_window->glx_pixmap_fb_configs();
342 if( glx_fb_configs ) {
343 Display *dpy = current_window->get_display();
345 glXCreatePixmap(dpy, *glx_fb_configs, opaque_pixmap, 0);
347 glXCreateNewContext(dpy, *glx_fb_configs, GLX_RGBA_TYPE, 0, True);
351 printf("BC_Pixmap::enable_opengl(): no glx_pixmap\n");
352 else if( !glx_pixmap_context )
353 printf("BC_Pixmap::enable_opengl(): no glx_pixmap_context\n");
355 current_window->glx_make_current(glx_pixmap, glx_pixmap_context);