00001 #include "bcbitmap.h"
00002 #include "bcpixmap.h"
00003 #include "bcresources.h"
00004 #include "bcsignals.h"
00005 #include "bcsynchronous.h"
00006 #include "bcwindowbase.h"
00007 #include "vframe.h"
00008
00009
00010 #include <unistd.h>
00011
00012 BC_Pixmap::BC_Pixmap(BC_WindowBase *parent_window,
00013 VFrame *frame,
00014 int mode,
00015 int icon_offset)
00016 {
00017 reset();
00018
00019 BC_Bitmap *opaque_bitmap, *alpha_bitmap, *mask_bitmap;
00020 if(frame->get_color_model() != BC_RGBA8888 &&
00021 mode == PIXMAP_ALPHA)
00022 mode = PIXMAP_OPAQUE;
00023 this->mode = mode;
00024
00025
00026 if(use_opaque())
00027 {
00028 opaque_bitmap = new BC_Bitmap(parent_window,
00029 frame->get_w(),
00030 frame->get_h(),
00031 parent_window->get_color_model(),
00032 0);
00033 opaque_bitmap->set_bg_color(parent_window->get_bg_color());
00034 opaque_bitmap->read_frame(frame,
00035 0,
00036 0,
00037 frame->get_w(),
00038 frame->get_h());
00039
00040 }
00041
00042 if(use_alpha())
00043 {
00044 alpha_bitmap = new BC_Bitmap(parent_window,
00045 frame->get_w(),
00046 frame->get_h(),
00047 BC_TRANSPARENCY,
00048 0);
00049
00050 if(frame->get_color_model() != BC_RGBA8888)
00051 printf("BC_Pixmap::BC_Pixmap: PIXMAP_ALPHA but frame doesn't have alpha.\n");
00052 alpha_bitmap->read_frame(frame,
00053 0,
00054 0,
00055 frame->get_w(),
00056 frame->get_h());
00057 }
00058
00059 initialize(parent_window,
00060 frame->get_w(),
00061 frame->get_h(),
00062 mode);
00063
00064 if(use_opaque())
00065 {
00066 opaque_bitmap->write_drawable(opaque_pixmap,
00067 top_level->gc,
00068 0,
00069 0,
00070 0,
00071 0,
00072 w,
00073 h,
00074 1);
00075 delete opaque_bitmap;
00076 }
00077
00078 if(use_alpha())
00079 {
00080 alpha_bitmap->write_drawable(alpha_pixmap,
00081 copy_gc,
00082 0,
00083 0,
00084 icon_offset ? 2 : 0,
00085 icon_offset ? 2 : 0,
00086 w,
00087 h,
00088 1);
00089 delete alpha_bitmap;
00090 XFreeGC(top_level->display, copy_gc);
00091
00092 XSetClipMask(top_level->display, alpha_gc, alpha_pixmap);
00093 }
00094 }
00095
00096 BC_Pixmap::BC_Pixmap(BC_WindowBase *parent_window, int w, int h)
00097 {
00098 reset();
00099 initialize(parent_window, w, h, PIXMAP_OPAQUE);
00100 }
00101
00102
00103 BC_Pixmap::~BC_Pixmap()
00104 {
00105 if(use_opaque())
00106 {
00107 #ifdef HAVE_XFT
00108 if(opaque_xft_draw)
00109 XftDrawDestroy((XftDraw*)opaque_xft_draw);
00110 #endif
00111 XFreePixmap(top_level->display, opaque_pixmap);
00112 }
00113
00114 if(use_alpha())
00115 {
00116 XFreeGC(top_level->display, alpha_gc);
00117 #ifdef HAVE_XFT
00118 if(alpha_xft_draw)
00119 XftDrawDestroy((XftDraw*)alpha_xft_draw);
00120 #endif
00121 XFreePixmap(top_level->display, alpha_pixmap);
00122 }
00123
00124
00125
00126 #ifdef HAVE_GL
00127 if(BC_WindowBase::get_synchronous() && gl_pixmap)
00128 {
00129 BC_WindowBase::get_synchronous()->delete_pixmap(parent_window,
00130 gl_pixmap,
00131 gl_pixmap_context);
00132 }
00133 #endif
00134 }
00135
00136
00137 void BC_Pixmap::reset()
00138 {
00139 parent_window = 0;
00140 top_level = 0;
00141 opaque_pixmap = 0;
00142 alpha_pixmap = 0;
00143 opaque_xft_draw = 0;
00144 alpha_xft_draw = 0;
00145 #ifdef HAVE_GL
00146 gl_pixmap_context = 0;
00147 gl_pixmap = 0;
00148 #endif
00149 }
00150
00151 int BC_Pixmap::initialize(BC_WindowBase *parent_window, int w, int h, int mode)
00152 {
00153 this->w = w;
00154 this->h = h;
00155 this->parent_window = parent_window;
00156 this->mode = mode;
00157 top_level = parent_window->top_level;
00158
00159 if(use_opaque())
00160 {
00161 opaque_pixmap = XCreatePixmap(top_level->display,
00162 top_level->win,
00163 w,
00164 h,
00165 top_level->default_depth);
00166 #ifdef HAVE_XFT
00167 if(BC_WindowBase::get_resources()->use_xft)
00168 {
00169 opaque_xft_draw = XftDrawCreate(top_level->display,
00170 opaque_pixmap,
00171 top_level->vis,
00172 top_level->cmap);
00173 }
00174 #endif
00175 }
00176
00177 if(use_alpha())
00178 {
00179 unsigned long gcmask = GCGraphicsExposures |
00180 GCForeground |
00181 GCBackground |
00182 GCFunction;
00183 XGCValues gcvalues;
00184 gcvalues.graphics_exposures = 0;
00185 gcvalues.foreground = 0;
00186 gcvalues.background = 1;
00187 gcvalues.function = GXcopy;
00188
00189 alpha_pixmap = XCreatePixmap(top_level->display,
00190 top_level->win,
00191 w,
00192 h,
00193 1);
00194
00195 alpha_gc = XCreateGC(top_level->display,
00196 top_level->win,
00197 gcmask,
00198 &gcvalues);
00199
00200 copy_gc = XCreateGC(top_level->display,
00201 alpha_pixmap,
00202 gcmask,
00203 &gcvalues);
00204
00205 #ifdef HAVE_XFT
00206 if(BC_WindowBase::get_resources()->use_xft)
00207 {
00208 alpha_xft_draw = XftDrawCreateBitmap(top_level->display,
00209 alpha_pixmap);
00210 }
00211 #endif
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 return 0;
00223 }
00224
00225 void BC_Pixmap::resize(int w, int h)
00226 {
00227 Pixmap new_pixmap = XCreatePixmap(top_level->display,
00228 top_level->win,
00229 w,
00230 h,
00231 top_level->default_depth);
00232 #ifdef HAVE_XFT
00233 XftDraw *new_xft_draw;
00234 if(BC_WindowBase::get_resources()->use_xft)
00235 {
00236 new_xft_draw = XftDrawCreate(top_level->display,
00237 new_pixmap,
00238 top_level->vis,
00239 top_level->cmap);
00240 }
00241 #endif
00242
00243
00244
00245
00246 XCopyArea(top_level->display,
00247 opaque_pixmap,
00248 new_pixmap,
00249 top_level->gc,
00250 0,
00251 0,
00252 get_w(),
00253 get_h(),
00254 0,
00255 0);
00256 this->w = w;
00257 this->h = h;
00258 #ifdef HAVE_XFT
00259 if(BC_WindowBase::get_resources()->use_xft)
00260 XftDrawDestroy((XftDraw*)opaque_xft_draw);
00261 #endif
00262 XFreePixmap(top_level->display, opaque_pixmap);
00263
00264 opaque_pixmap = new_pixmap;
00265 #ifdef HAVE_XFT
00266 if(BC_WindowBase::get_resources()->use_xft)
00267 opaque_xft_draw = new_xft_draw;
00268 #endif
00269 }
00270
00271
00272 void BC_Pixmap::copy_area(int x, int y, int w, int h, int x2, int y2)
00273 {
00274 XCopyArea(top_level->display,
00275 opaque_pixmap,
00276 opaque_pixmap,
00277 top_level->gc,
00278 x,
00279 y,
00280 w,
00281 h,
00282 x2,
00283 y2);
00284 }
00285
00286 int BC_Pixmap::write_drawable(Drawable &pixmap,
00287 int dest_x,
00288 int dest_y,
00289 int dest_w,
00290 int dest_h,
00291 int src_x,
00292 int src_y)
00293 {
00294
00295 if(dest_w < 0)
00296 {
00297 dest_w = w;
00298 src_x = 0;
00299 }
00300
00301 if(dest_h < 0)
00302 {
00303 dest_h = h;
00304 src_y = 0;
00305 }
00306
00307 if(use_alpha())
00308 {
00309 XSetClipOrigin(top_level->display, alpha_gc, dest_x - src_x, dest_y - src_y);
00310 XCopyArea(top_level->display,
00311 this->opaque_pixmap,
00312 pixmap,
00313 alpha_gc,
00314 src_x,
00315 src_y,
00316 dest_w,
00317 dest_h,
00318 dest_x,
00319 dest_y);
00320 }
00321 else
00322 if(use_opaque())
00323 {
00324 XCopyArea(top_level->display,
00325 this->opaque_pixmap,
00326 pixmap,
00327 top_level->gc,
00328 src_x,
00329 src_y,
00330 dest_w,
00331 dest_h,
00332 dest_x,
00333 dest_y);
00334 }
00335
00336
00337 return 0;
00338 }
00339
00340 void BC_Pixmap::draw_vframe(VFrame *frame,
00341 int dest_x,
00342 int dest_y,
00343 int dest_w,
00344 int dest_h,
00345 int src_x,
00346 int src_y)
00347 {
00348 parent_window->draw_vframe(frame,
00349 dest_x,
00350 dest_y,
00351 dest_w,
00352 dest_h,
00353 src_x,
00354 src_y,
00355 0,
00356 0,
00357 this);
00358 }
00359
00360 void BC_Pixmap::draw_pixmap(BC_Pixmap *pixmap,
00361 int dest_x,
00362 int dest_y,
00363 int dest_w,
00364 int dest_h,
00365 int src_x,
00366 int src_y)
00367 {
00368 pixmap->write_drawable(this->opaque_pixmap,
00369 dest_x,
00370 dest_y,
00371 dest_w,
00372 dest_h,
00373 src_x,
00374 src_y);
00375 }
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 int BC_Pixmap::get_w()
00388 {
00389 return w;
00390 }
00391
00392 int BC_Pixmap::get_h()
00393 {
00394 return h;
00395 }
00396
00397 int BC_Pixmap::get_w_fixed()
00398 {
00399 return w - 1;
00400 }
00401
00402 int BC_Pixmap::get_h_fixed()
00403 {
00404 return h - 1;
00405 }
00406
00407 Pixmap BC_Pixmap::get_pixmap()
00408 {
00409 return opaque_pixmap;
00410 }
00411
00412 Pixmap BC_Pixmap::get_alpha()
00413 {
00414 return alpha_pixmap;
00415 }
00416
00417 int BC_Pixmap::use_opaque()
00418 {
00419 return 1;
00420 }
00421
00422 int BC_Pixmap::use_alpha()
00423 {
00424 return mode == PIXMAP_ALPHA;
00425 }
00426
00427
00428 void BC_Pixmap::enable_opengl()
00429 {
00430 printf("BC_Pixmap::enable_opengl called but it doesn't work.\n");
00431 #ifdef HAVE_GL
00432 BC_WindowBase *current_window = BC_WindowBase::get_synchronous()->current_window;
00433 if(!gl_pixmap_context)
00434 {
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463 static int framebuffer_attributes[] =
00464 {
00465 GLX_RENDER_TYPE, GLX_RGBA_BIT,
00466 GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
00467 GLX_DOUBLEBUFFER, 0,
00468 GLX_RED_SIZE, 1,
00469 GLX_GREEN_SIZE, 1,
00470 GLX_BLUE_SIZE, 1,
00471 None
00472 };
00473 XVisualInfo *visinfo = 0;
00474 int config_result_count = 0;
00475 GLXFBConfig *config_result = glXChooseFBConfig(current_window->get_display(),
00476 current_window->get_screen(),
00477 framebuffer_attributes,
00478 &config_result_count);
00479 if(config_result)
00480 {
00481 gl_pixmap = glXCreatePixmap(current_window->get_display(),
00482 config_result[0],
00483 opaque_pixmap,
00484 0);
00485
00486 visinfo = glXGetVisualFromFBConfig(current_window->get_display(),
00487 config_result[0]);
00488 }
00489
00490
00491 if(visinfo)
00492 {
00493 gl_pixmap_context = glXCreateContext(current_window->get_display(),
00494 visinfo,
00495 0,
00496 0);
00497 }
00498
00499 if(config_result) XFree(config_result);
00500 if(visinfo) XFree(visinfo);
00501 }
00502
00503 if(gl_pixmap_context)
00504 {
00505 glXMakeCurrent(top_level->display,
00506 gl_pixmap,
00507 gl_pixmap_context);
00508 }
00509 #endif
00510 }
00511