00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "mmsgui/fb/mmsfblayer.h"
00034 #include "mmsgui/fb/mmsfb.h"
00035 #include <string.h>
00036 #include <cerrno>
00037
00038 #ifdef __HAVE_XLIB__
00039 #include <sys/shm.h>
00040 #endif
00041
00042
00043 #ifdef __HAVE_DIRECTFB__
00044 D_DEBUG_DOMAIN( MMS_Layer, "MMS/Layer", "MMS Layer" );
00045 #endif
00046
00047 #ifdef __HAVE_XLIB__
00048 #define GUID_YUV12_PLANAR ('2'<<24)|('1'<<16)|('V'<<8)|'Y')
00049 #include <X11/Xatom.h>
00050 #endif
00051
00052 #include <unistd.h>
00053 #include <stdlib.h>
00054
00055
00056 bool MMSFBLayer::firsttime_createsurface = true;
00057 bool MMSFBLayer::firsttime_createwindow_usealpha= true;
00058 bool MMSFBLayer::firsttime_createwindow_noalpha = true;
00059
00060
00061 #define INITCHECK if(!this->initialized){MMSFB_SetError(0,"not initialized");return false;}
00062
00063
00064 MMSFBLayer::MMSFBLayer(int id, MMSFBBackend backend, MMSFBOutputType outputtype) {
00065
00066 this->initialized = false;
00067 this->surface = NULL;
00068 this->flipflags = MMSFB_FLIP_NONE;
00069 this->config.avail = false;
00070 this->config.id = id;
00071 this->config.backend = backend;
00072 this->config.outputtype = outputtype;
00073 this->config.window_pixelformat = MMSFB_PF_ARGB;
00074 this->config.surface_pixelformat = MMSFB_PF_ARGB;
00075
00076 #ifdef __HAVE_FBDEV__
00077 this->mmsfbdev_surface = NULL;
00078 #endif
00079
00080 #ifdef __HAVE_XLIB__
00081 this->x_image1 = NULL;
00082 this->x_image2 = NULL;
00083 this->x_image_scaler = NULL;
00084 this->scaler = NULL;
00085 #endif
00086 #ifdef __HAVE_XV__
00087 this->xv_image1 = NULL;
00088 this->xv_image2 = NULL;
00089 #endif
00090
00091 if (this->config.backend == MMSFB_BE_DFB) {
00092 #ifdef __HAVE_DIRECTFB__
00093
00094 DFBResult dfbres;
00095 this->dfblayer = NULL;
00096 if ((dfbres = mmsfb->dfb->GetDisplayLayer(mmsfb->dfb, this->config.id, &this->dfblayer)) != DFB_OK) {
00097 this->dfblayer = NULL;
00098 MMSFB_SetError(dfbres, "IDirectFB::GetDisplayLayer(" + iToStr(id) + ") failed");
00099 return;
00100 }
00101 this->initialized = true;
00102 #endif
00103 }
00104 else
00105 if (this->config.backend == MMSFB_BE_FBDEV) {
00106 #ifdef __HAVE_FBDEV__
00107 if (mmsfb->mmsfbdev) {
00108
00109 if (!mmsfb->mmsfbdev->testLayer(this->config.id)) {
00110 MMSFB_SetError(0, "init test of layer " + iToStr(this->config.id) + " failed!");
00111 return;
00112 }
00113
00114 if (this->config.outputtype == MMSFB_OT_OGL) {
00115
00116 if (this->config.id != 0) {
00117 MMSFB_SetError(0, "OPENGL support needs layer 0!");
00118 return;
00119 }
00120 }
00121
00122 this->initialized = true;
00123 }
00124 #endif
00125 }
00126 else
00127 if (this->config.backend == MMSFB_BE_X11) {
00128 #ifdef __HAVE_XLIB__
00129
00130
00131 this->config.w = mmsfb->x11_win_rect.w;
00132 this->config.h = mmsfb->x11_win_rect.h;
00133 this->config.pixelformat = MMSFB_PF_NONE;
00134 this->config.buffermode = MMSFB_BM_BACKSYSTEM;
00135 this->config.options = MMSFB_LO_NONE;
00136 if (this->config.outputtype == MMSFB_OT_XSHM) {
00137
00138 switch (mmsfb->x_depth) {
00139 case 16:
00140 this->config.pixelformat = MMSFB_PF_RGB16;
00141 break;
00142 case 24:
00143 this->config.pixelformat = MMSFB_PF_RGB24;
00144 break;
00145 case 32:
00146 this->config.pixelformat = MMSFB_PF_RGB32;
00147 break;
00148 }
00149
00150 this->initialized = true;
00151 }
00152 else
00153 if (this->config.outputtype == MMSFB_OT_XVSHM) {
00154
00155 this->config.pixelformat = MMSFB_PF_YV12;
00156
00157 this->initialized = true;
00158 }
00159 else
00160 if (this->config.outputtype == MMSFB_OT_OGL) {
00161
00162 if (this->config.id != 0) {
00163 MMSFB_SetError(0, "OPENGL support needs layer 0!");
00164 return;
00165 }
00166
00167
00168 this->config.w = mmsfb->x11_win_rect.w;
00169 this->config.h = mmsfb->x11_win_rect.h;
00170 this->config.pixelformat = MMSFB_PF_ARGB;
00171 this->config.buffermode = MMSFB_BM_BACKSYSTEM;
00172 this->config.options = MMSFB_LO_NONE;
00173
00174 this->initialized = true;
00175 }
00176 #endif
00177 }
00178
00179
00180 if (this->initialized) {
00181 MMSFBLayerConfig config;
00182 getConfiguration(&config);
00183 }
00184 }
00185
00186
00187 MMSFBLayer::~MMSFBLayer() {
00188 if (this->config.backend == MMSFB_BE_DFB) {
00189 #ifdef __HAVE_DIRECTFB__
00190 if (this->dfblayer)
00191 this->dfblayer->Release(this->dfblayer);
00192 #endif
00193 }
00194 else
00195 if (this->config.backend == MMSFB_BE_FBDEV) {
00196 #ifdef __HAVE_FBDEV__
00197 if (this->mmsfbdev_surface)
00198 delete this->mmsfbdev_surface;
00199 #endif
00200 }
00201 else {
00202 #ifdef __HAVE_XLIB__
00203 if (this->config.outputtype == MMSFB_OT_XSHM) {
00204
00205 if (this->x_image1)
00206 XFree(this->x_image1);
00207 if (this->x_image2)
00208 XFree(this->x_image2);
00209 }
00210 else {
00211 #ifdef __HAVE_XV__
00212
00213 if (this->xv_image1)
00214 XFree(this->xv_image1);
00215 if (this->xv_image2)
00216 XFree(this->xv_image2);
00217 #endif
00218 }
00219 #endif
00220 }
00221 }
00222
00223 bool MMSFBLayer::isInitialized() {
00224 if (this->config.backend == MMSFB_BE_DFB) {
00225 #ifdef __HAVE_DIRECTFB__
00226 return (this->dfblayer != NULL);
00227 #endif
00228 }
00229 else {
00230 return this->initialized;
00231 }
00232
00233 return false;
00234 }
00235
00236 bool MMSFBLayer::getID(int *id) {
00237
00238
00239 INITCHECK;
00240
00241
00242 MMSFBLayerConfig config;
00243 if (!getConfiguration(&config))
00244 return false;
00245
00246
00247 *id = this->config.id;
00248
00249 return true;
00250 }
00251
00252 bool MMSFBLayer::setExclusiveAccess() {
00253
00254
00255 INITCHECK;
00256
00257 if (this->config.backend == MMSFB_BE_DFB) {
00258 #ifdef __HAVE_DIRECTFB__
00259 DFBResult dfbres;
00260
00261
00262 if ((dfbres=this->dfblayer->SetCooperativeLevel(this->dfblayer, DLSCL_EXCLUSIVE)) != DFB_OK) {
00263 MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::SetCooperativeLevel(DLSCL_EXCLUSIVE) failed");
00264 return false;
00265 }
00266
00267 return true;
00268 #endif
00269 }
00270 else {
00271 return true;
00272 }
00273
00274 return false;
00275 }
00276
00277 bool MMSFBLayer::getConfiguration(MMSFBLayerConfig *config) {
00278
00279
00280 INITCHECK;
00281
00282 if (this->config.avail) {
00283
00284 if (config)
00285 *config = this->config;
00286 return true;
00287 }
00288
00289 if (this->config.backend == MMSFB_BE_DFB) {
00290 #ifdef __HAVE_DIRECTFB__
00291 DFBResult dfbres;
00292 DFBDisplayLayerConfig dlc;
00293
00294
00295 if ((dfbres=this->dfblayer->GetConfiguration(this->dfblayer, &dlc)) != DFB_OK) {
00296 MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::GetConfiguration() failed");
00297 return false;
00298 }
00299
00300
00301 this->config.avail = true;
00302 this->config.w = dlc.width;
00303 this->config.h = dlc.height;
00304 this->config.pixelformat = getMMSFBPixelFormatFromDFBPixelFormat(dlc.pixelformat);
00305 this->config.buffermode = getDFBLayerBufferModeString(dlc.buffermode);
00306 this->config.options = getDFBLayerOptionsString(dlc.options);
00307
00308 #endif
00309 }
00310 else {
00311 this->config.avail = true;
00312 }
00313
00314 if (!config) {
00315 DEBUGMSG("MMSGUI", "Layer properties:");
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 DEBUGMSG("MMSGUI", " backend: " + getMMSFBBackendString(this->config.backend));
00345 DEBUGMSG("MMSGUI", " outputtype: " + getMMSFBOutputTypeString(this->config.outputtype));
00346
00347 DEBUGMSG("MMSGUI", " size: " + iToStr(this->config.w) + "x" + iToStr(this->config.h));
00348
00349 DEBUGMSG("MMSGUI", " pixelformat: " + getMMSFBPixelFormatString(this->config.pixelformat));
00350
00351 if (this->config.buffermode!="")
00352 DEBUGMSG("MMSGUI", " buffermode: " + this->config.buffermode);
00353 else
00354 DEBUGMSG("MMSGUI", " buffermode: NONE");
00355
00356 if (this->config.options!="")
00357 DEBUGMSG("MMSGUI", " options: " + this->config.options);
00358 else
00359 DEBUGMSG("MMSGUI", " options: NONE");
00360 }
00361
00362
00363 if (config)
00364 *config = this->config;
00365
00366 return true;
00367 }
00368
00369 bool MMSFBLayer::getResolution(int *w, int *h) {
00370
00371
00372 INITCHECK;
00373
00374
00375 MMSFBLayerConfig config;
00376 if (!getConfiguration(&config))
00377 return false;
00378
00379
00380 *w = this->config.w;
00381 *h = this->config.h;
00382
00383 return true;
00384 }
00385
00386 bool MMSFBLayer::getPixelFormat(MMSFBSurfacePixelFormat *pixelformat) {
00387
00388
00389 INITCHECK;
00390
00391
00392 MMSFBLayerConfig config;
00393 if (!getConfiguration(&config))
00394 return false;
00395
00396
00397 *pixelformat = this->config.pixelformat;
00398
00399 return true;
00400 }
00401
00402 bool MMSFBLayer::setConfiguration(int w, int h, MMSFBSurfacePixelFormat pixelformat, string buffermode, string options,
00403 MMSFBSurfacePixelFormat window_pixelformat, MMSFBSurfacePixelFormat surface_pixelformat) {
00404
00405
00406 INITCHECK;
00407 if (this->config.backend == MMSFB_BE_DFB) {
00408 #ifdef __HAVE_DIRECTFB__
00409
00410 MMSFBLayerConfig config;
00411 if (!getConfiguration(&config))
00412 return false;
00413
00414
00415 if (config.w != w || config.h != h || config.pixelformat != pixelformat || config.buffermode != buffermode) {
00416
00417 DFBResult dfbres;
00418 DFBDisplayLayerConfig dlc;
00419 dlc.flags = DLCONF_NONE;
00420 dlc.width = w;
00421 dlc.height = h;
00422 dlc.pixelformat = getDFBPixelFormatFromMMSFBPixelFormat(pixelformat);
00423 dlc.buffermode = getDFBLayerBufferModeFromString(buffermode);
00424 dlc.options = getDFBLayerOptionsFromString(options);
00425
00426 if (dlc.width > 0)
00427 dlc.flags = (DFBDisplayLayerConfigFlags)(dlc.flags | DLCONF_WIDTH);
00428 if (dlc.height > 0)
00429 dlc.flags = (DFBDisplayLayerConfigFlags)(dlc.flags | DLCONF_HEIGHT);
00430 if (dlc.pixelformat != DSPF_UNKNOWN)
00431 dlc.flags = (DFBDisplayLayerConfigFlags)(dlc.flags | DLCONF_PIXELFORMAT);
00432 if (dlc.buffermode != DLBM_UNKNOWN)
00433 dlc.flags = (DFBDisplayLayerConfigFlags)(dlc.flags | DLCONF_BUFFERMODE);
00434
00435 DEBUGOUT("\nSET OPTIONS 0x%08x!!!!\n", dlc.options);
00436 dlc.flags = (DFBDisplayLayerConfigFlags)(dlc.flags | DLCONF_OPTIONS);
00437
00438
00439
00440 DFBDisplayLayerConfigFlags failedFlags;
00441 if ((dfbres=this->dfblayer->TestConfiguration(this->dfblayer, &dlc, &failedFlags)) != DFB_OK) {
00442 if(failedFlags & DLCONF_PIXELFORMAT) {
00443 MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::TestConfiguration(" + iToStr(w) + "x" + iToStr(h) + "," + getMMSFBPixelFormatString(pixelformat) + "," + buffermode + "," + options + ") failed");
00444 DEBUGMSG("MMSGUI", "Your configuration contains a pixelformat that is not supported.");
00445 return false;
00446 }
00447 if(failedFlags & DLCONF_BUFFERMODE) {
00448 MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::TestConfiguration(" + iToStr(w) + "x" + iToStr(h) + "," + getMMSFBPixelFormatString(pixelformat) + "," + buffermode + "," + options + ") failed");
00449 DEBUGMSG("MMSGUI", "Your configuration contains a buffermode that is not supported.");
00450 return false;
00451 }
00452 if(failedFlags & DLCONF_OPTIONS) {
00453 MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::TestConfiguration(" + iToStr(w) + "x" + iToStr(h) + "," + getMMSFBPixelFormatString(pixelformat) + "," + buffermode + "," + options + ") failed");
00454 DEBUGMSG("MMSGUI", "Your configuration contains options that are not supported.");
00455 return false;
00456 }
00457
00458
00459 if(failedFlags & DLCONF_WIDTH)
00460 dlc.flags = (DFBDisplayLayerConfigFlags)(dlc.flags & ~DLCONF_WIDTH);
00461 if(failedFlags & DLCONF_HEIGHT)
00462 dlc.flags = (DFBDisplayLayerConfigFlags)(dlc.flags & ~DLCONF_HEIGHT);
00463 if ((dfbres=this->dfblayer->TestConfiguration(this->dfblayer, &dlc, &failedFlags)) != DFB_OK) {
00464 MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::TestConfiguration(" + iToStr(w) + "x" + iToStr(h) + "," + getMMSFBPixelFormatString(pixelformat) + "," + buffermode + "," + options + ") failed");
00465 return false;
00466 }
00467 DEBUGMSG("MMSGUI", "Your configuration contains a resolution that is not supported.");
00468 }
00469
00470
00471 if((dfbres = this->dfblayer->SetConfiguration(this->dfblayer, &dlc)) != DFB_OK) {
00472 MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::SetConfiguration(" + iToStr(w) + "x" + iToStr(h) + "," + getMMSFBPixelFormatString(pixelformat) + "," + buffermode + "," + options + ") failed");
00473 return false;
00474 }
00475 }
00476
00477
00478 this->config.avail = false;
00479 if (!getConfiguration())
00480 return false;
00481
00482
00483 this->dfblayer->SetBackgroundMode(this->dfblayer, DLBM_COLOR);
00484 this->dfblayer->SetBackgroundColor(this->dfblayer, 0, 0, 0, 0);
00485
00486
00487 this->config.window_pixelformat = window_pixelformat;
00488 this->config.surface_pixelformat = surface_pixelformat;
00489
00490 return true;
00491 #endif
00492 }
00493 else
00494 if (this->config.backend == MMSFB_BE_FBDEV) {
00495 #ifdef __HAVE_FBDEV__
00496 if (!mmsfb->mmsfbdev)
00497 return false;
00498
00499
00500 if (!mmsfb->mmsfbdev->initLayer(this->config.id, w, h, pixelformat,
00501 (buffermode == MMSFB_BM_BACKVIDEO)?1:(buffermode == MMSFB_BM_TRIPLE)?2:0)) {
00502 MMSFB_SetError(0, "init layer " + iToStr(this->config.id) + " failed!");
00503 return false;
00504 }
00505
00506
00507 MMSFBSurfacePlanesBuffer buffers;
00508 memset(&buffers, 0, sizeof(buffers));
00509 if (!mmsfb->mmsfbdev->getFrameBufferPtr(this->config.id, buffers, &this->config.w, &this->config.h)) {
00510 MMSFB_SetError(0, "getFrameBufferPtr() failed");
00511 return false;
00512 }
00513 mmsfb->mmsfbdev->getPixelFormat(this->config.id, &this->config.pixelformat);
00514 this->config.buffermode = buffermode;
00515 this->config.options = MMSFB_LO_NONE;
00516
00517
00518 this->mmsfbdev_surface = new MMSFBSurface(this->config.w, this->config.h, this->config.pixelformat,
00519 MMSFB_MAX_SURFACE_PLANES_BUFFERS - 1, buffers);
00520 if (!this->mmsfbdev_surface) {
00521 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface");
00522 return false;
00523 }
00524
00525 if (this->config.outputtype == MMSFB_OT_OGL) {
00526
00527 this->mmsfbdev_surface->setExtendedAcceleration(false);
00528 }
00529 else {
00530
00531 this->mmsfbdev_surface->setExtendedAcceleration(true);
00532 }
00533
00534
00535 this->mmsfbdev_surface->setLayerSurface();
00536
00537 if (this->config.outputtype == MMSFB_OT_OGL) {
00538 #ifdef __HAVE_OPENGL__
00539 #ifdef __HAVE_EGL__
00540
00541 mmsfb->bei->init();
00542 #endif
00543 #endif
00544 }
00545
00546
00547 this->config.avail = false;
00548 if (!getConfiguration()) {
00549 printf("getconfiguration failed!");
00550 return false;
00551 }
00552
00553
00554
00555 this->config.window_pixelformat = window_pixelformat;
00556 this->config.surface_pixelformat = surface_pixelformat;
00557
00558
00559 return true;
00560 #endif
00561 }
00562 else {
00563 #ifdef __HAVE_XLIB__
00564
00565 this->config.avail = false;
00566 if (!getConfiguration())
00567 return false;
00568 printf("setConfiguration called for id: %d\n", this->config.id);
00569
00570
00571 this->config.window_pixelformat = window_pixelformat;
00572 this->config.surface_pixelformat = surface_pixelformat;
00573 this->config.pixelformat = pixelformat;
00574
00575 XLockDisplay(mmsfb->x_display);
00576
00577 Colormap colormap;
00578 Window root = RootWindow(mmsfb->x_display, mmsfb->x_screen);
00579
00580
00581
00582
00583
00584 if(config.pixelformat == MMSFB_PF_ARGB) {
00585
00586 #ifdef __HAVE_XV__
00587
00588 int major, minor;
00589 if (!XCompositeQueryVersion(mmsfb->x_display,&major, &minor)) {
00590 printf("No Composite extension available, and ARGB is requested for Window Pixelformat\n");
00591 return false;
00592 } else {
00593 printf("Composite: %d.%d\n", major, minor);
00594 }
00595
00596
00597 if (!XRenderQueryVersion(mmsfb->x_display, &major, &minor)) {
00598 printf("no render extension available, just go for rgba visual \n");
00599 return false;
00600 } else {
00601 printf("render extension: %d.%d\n", major, minor);
00602
00603
00604
00605 pict_format = NULL;
00606 XRenderPictFormat *pict_visualformat = NULL;
00607 XRenderPictFormat pf;
00608 XVisualInfo xvinfo_template;
00609 XVisualInfo *xvinfos;
00610
00611 pict_format = XRenderFindStandardFormat(mmsfb->x_display, PictStandardARGB32);
00612 if (pict_format == NULL) {
00613 fprintf(stderr, "Can't find standard format for ARGB32\n");
00614
00615
00616 pf.type = PictTypeDirect;
00617 pf.depth = 32;
00618
00619 pf.direct.alphaMask = 0xff;
00620 pf.direct.redMask = 0xff;
00621 pf.direct.greenMask = 0xff;
00622 pf.direct.blueMask = 0xff;
00623
00624 pf.direct.alpha = 24;
00625 pf.direct.red = 16;
00626 pf.direct.green = 8;
00627 pf.direct.blue = 0;
00628
00629 pict_format = XRenderFindFormat(mmsfb->x_display,(PictFormatType | PictFormatDepth |PictFormatRedMask | PictFormatRed |
00630 PictFormatGreenMask | PictFormatGreen |PictFormatBlueMask | PictFormatBlue |PictFormatAlphaMask | PictFormatAlpha),
00631 &pf, 0);
00632
00633 if (pict_format == NULL) {
00634 fprintf(stderr, "Can't find format for ARGB32\n");
00635 this->initialized = false;
00636 return false;
00637 }
00638 }
00639
00640
00641 int count = 0;
00642 xvinfo_template.screen = mmsfb->x_screen;
00643 xvinfo_template.depth = 32;
00644 xvinfo_template.bits_per_rgb = 8;
00645
00646 xvinfos = XGetVisualInfo(mmsfb->x_display, (VisualScreenMask | VisualDepthMask | VisualBitsPerRGBMask), &xvinfo_template, &count);
00647 if (xvinfos == NULL) {
00648 fprintf(stderr, "No visual matching criteria\n");
00649 } else {
00650 for(int i = 0; i < count; i++) {
00651 pict_visualformat = XRenderFindVisualFormat(mmsfb->x_display, xvinfos[i].visual);
00652 if (pict_visualformat != NULL && pict_visualformat->id == pict_format->id) {
00653
00654 this->x_visual=xvinfos[i].visual;
00655 break;
00656 }
00657 }
00658 }
00659
00660
00661 colormap = XCreateColormap(mmsfb->x_display,
00662 root,
00663 this->x_visual,
00664 AllocNone);
00665
00666 XInstallColormap(mmsfb->x_display, colormap);
00667
00668 XSetWindowAttributes x_window_attr;
00669 x_window_attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |PointerMotionMask|EnterWindowMask|ResizeRedirectMask;
00670 x_window_attr.background_pixel = 0;
00671 x_window_attr.border_pixel = 0;
00672 x_window_attr.colormap = colormap;
00673 unsigned long x_window_mask;
00674
00675 if(mmsfb->fullscreen == MMSFB_FSM_TRUE) {
00676 x_window_mask = CWBackPixel | CWBorderPixel | CWEventMask |CWColormap;
00677
00678
00679 this->x_window = XCreateWindow(mmsfb->x_display,DefaultRootWindow(mmsfb->x_display) , 0, 0, mmsfb->display_w, mmsfb->display_h, 0, 32,
00680 InputOutput, this->x_visual, x_window_mask, &x_window_attr);
00681 this->x_window_w = mmsfb->display_w;
00682 this->x_window_h = mmsfb->display_h;
00683
00684 Atom the_atom = XInternAtom(mmsfb->x_display, "_NET_WM_WINDOW_TYPE_SPLASH", False);
00685 XChangeProperty(mmsfb->x_display, this->x_window,XInternAtom(mmsfb->x_display, "_NET_WM_WINDOW_TYPE", False), XInternAtom(mmsfb->x_display, "ATOM[]/32", False), 32, PropModePrepend, (unsigned char*) &the_atom,1);
00686
00687 XSetWMProtocols(mmsfb->x_display, this->x_window, &the_atom, 1);
00688
00689 } else {
00690 x_window_mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
00691
00692
00693 this->x_window = XCreateWindow(mmsfb->x_display, DefaultRootWindow(mmsfb->x_display), mmsfb->x11_win_rect.x, mmsfb->x11_win_rect.y, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, 0, 32,
00694 InputOutput, this->x_visual, x_window_mask, &x_window_attr);
00695 this->x_window_w = mmsfb->x11_win_rect.w;
00696 this->x_window_h = mmsfb->x11_win_rect.h;
00697 }
00698
00699 Atom the_atom = XInternAtom(mmsfb->x_display, "_NET_WM_WINDOW_TYPE_SPLASH", False);
00700 XChangeProperty(mmsfb->x_display, this->x_window,XInternAtom(mmsfb->x_display, "_NET_WM_WINDOW_TYPE", False), XInternAtom(mmsfb->x_display, "ATOM[]/32", False), 32, PropModePrepend, (unsigned char*) &the_atom,1);
00701
00702 XSetWMProtocols(mmsfb->x_display, this->x_window, &the_atom, 1);
00703
00704 XFlush(mmsfb->x_display);
00705 XSync(mmsfb->x_display, False);
00706
00707 XGCValues gcvalues;
00708
00709 gcvalues.foreground = None;
00710 gcvalues.background = None;
00711 gcvalues.function = GXcopy;
00712 gcvalues.plane_mask = XAllPlanes();
00713 gcvalues.clip_mask = None;
00714
00715 this->x_gc = XCreateGC(mmsfb->x_display, this->x_window, 0, NULL);
00716
00717 XRenderPictureAttributes pict_attr;
00718 pict_attr.component_alpha = False;
00719
00720
00721 pixmap = XCreatePixmap(mmsfb->x_display, this->x_window,mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, 32);
00722
00723
00724 this->x_pixmap_pict = XRenderCreatePicture(mmsfb->x_display,
00725 pixmap,
00726 pict_format,
00727 CPComponentAlpha,
00728 &pict_attr);
00729
00730 this->x_window_pict = XRenderCreatePicture(mmsfb->x_display,
00731 this->x_window,
00732 pict_format,
00733 CPComponentAlpha,
00734 &pict_attr);
00735
00736
00737 this->x_image1 = XShmCreateImage(mmsfb->x_display, this->x_visual, 32, ZPixmap,
00738 NULL, &this->x_shminfo1, this->config.w, this->config.h);
00739 if (!this->x_image1) {
00740 XUnlockDisplay(mmsfb->x_display);
00741 MMSFB_SetError(0, "XShmCreateImage() failed");
00742 return false;
00743 }
00744
00745
00746 this->x_shminfo1.shmid = shmget(IPC_PRIVATE, this->x_image1->bytes_per_line * this->x_image1->height, IPC_CREAT | 0777);
00747 this->x_shminfo1.shmaddr = this->x_image1->data = (char *)shmat(this->x_shminfo1.shmid, 0, 0);
00748 this->x_shminfo1.readOnly = False;
00749
00750
00751 if (!XShmAttach(mmsfb->x_display, &this->x_shminfo1)) {
00752 XFree(this->x_image1);
00753 this->x_image1 = NULL;
00754 XUnlockDisplay(mmsfb->x_display);
00755 MMSFB_SetError(0, "XShmAttach() failed");
00756 return false;
00757 }
00758
00759
00760 this->x_image2 = XShmCreateImage(mmsfb->x_display, this->x_visual, 32, ZPixmap,
00761 NULL, &this->x_shminfo2, this->config.w, this->config.h);
00762 if (!this->x_image2) {
00763 XUnlockDisplay(mmsfb->x_display);
00764 MMSFB_SetError(0, "XShmCreateImage() failed");
00765 return false;
00766 }
00767
00768
00769 this->x_shminfo2.shmid = shmget(IPC_PRIVATE, this->x_image2->bytes_per_line * this->x_image2->height, IPC_CREAT | 0777);
00770 this->x_shminfo2.shmaddr = this->x_image2->data = (char *)shmat(this->x_shminfo2.shmid, 0, 0);
00771 this->x_shminfo2.readOnly = False;
00772
00773
00774 if (!XShmAttach(mmsfb->x_display, &this->x_shminfo2)) {
00775 XFree(this->x_image2);
00776 this->x_image2 = NULL;
00777 XUnlockDisplay(mmsfb->x_display);
00778 MMSFB_SetError(0, "XShmAttach() failed");
00779 return false;
00780 }
00781
00782 if ((mmsfb->fullscreen == MMSFB_FSM_TRUE || mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO)&&(1==0)) {
00783
00784
00785 MMSFBRectangle dest;
00786 calcAspectRatio(this->config.w, this->config.h, mmsfb->display_w, mmsfb->display_h, dest,
00787 (mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO), false);
00788
00789
00790 this->x_image_scaler = XShmCreateImage(mmsfb->x_display, this->x_visual, 32, ZPixmap,
00791 NULL, &this->x_shminfo_scaler, dest.w, dest.h);
00792 if (!this->x_image_scaler) {
00793 XUnlockDisplay(mmsfb->x_display);
00794 MMSFB_SetError(0, "XShmCreateImage() failed");
00795 return false;
00796 }
00797
00798
00799 this->x_shminfo_scaler.shmid = shmget(IPC_PRIVATE, this->x_image_scaler->bytes_per_line * this->x_image_scaler->height, IPC_CREAT | 0777);
00800 this->x_shminfo_scaler.shmaddr = this->x_image_scaler->data = (char *)shmat(this->x_shminfo_scaler.shmid, 0, 0);
00801 this->x_shminfo_scaler.readOnly = False;
00802
00803
00804 if (!XShmAttach(mmsfb->x_display, &this->x_shminfo_scaler)) {
00805 XFree(this->x_image_scaler);
00806 this->x_image_scaler = NULL;
00807 XUnlockDisplay(mmsfb->x_display);
00808 MMSFB_SetError(0, "XShmAttach() failed");
00809 return false;
00810 }
00811
00812
00813 this->scaler = new MMSFBSurface(dest.w, dest.h, this->config.pixelformat,
00814 this->x_image_scaler, NULL, NULL);
00815 if (!this->scaler) {
00816 XUnlockDisplay(mmsfb->x_display);
00817 MMSFB_SetError(0, "cannot create scaler surface");
00818 return false;
00819 }
00820 this->scaler->layer=this;
00821
00822 this->scaler->setExtendedAcceleration(true);
00823 }
00824 }
00825
00826 XFlush(mmsfb->x_display);
00827 XSync(mmsfb->x_display, False);
00828
00829 this->impl.x_display = mmsfb->x_display;
00830 this->impl.x_gc = this->x_gc;
00831 this->impl.x_window = this->x_window;
00832 this->impl.w = this->x_window_w;
00833 this->impl.h = this->x_window_h;
00834 this->impl.x_screen = mmsfb->x_screen;
00835 #endif
00836 } else if(config.pixelformat == MMSFB_PF_RGB32 || config.pixelformat == MMSFB_PF_RGB24) {
00837
00838 this->x_visual = DefaultVisual(mmsfb->x_display, mmsfb->x_screen);
00839 mmsfb->x_depth=DefaultDepth(mmsfb->x_display, mmsfb->x_screen);
00840 XSetWindowAttributes x_window_attr;
00841 x_window_attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |PointerMotionMask|EnterWindowMask|ResizeRedirectMask;
00842 x_window_attr.background_pixel = 0;
00843 x_window_attr.border_pixel = 0;
00844 x_window_attr.colormap = colormap;
00845 unsigned long x_window_mask;
00846
00847 if(mmsfb->fullscreen == MMSFB_FSM_TRUE) {
00848 x_window_mask = CWBackPixel | CWBorderPixel | CWEventMask |CWColormap;
00849
00850
00851 this->x_window = XCreateWindow(mmsfb->x_display,DefaultRootWindow(mmsfb->x_display) , 0, 0, mmsfb->display_w, mmsfb->display_h, 0, mmsfb->x_depth,
00852 InputOutput, this->x_visual, x_window_mask, &x_window_attr);
00853
00854 this->x_window_w = mmsfb->display_w;
00855 this->x_window_h = mmsfb->display_h;
00856
00857 Atom the_atom = XInternAtom(mmsfb->x_display, "_NET_WM_WINDOW_TYPE_SPLASH", False);
00858 XChangeProperty(mmsfb->x_display, this->x_window,XInternAtom(mmsfb->x_display, "_NET_WM_WINDOW_TYPE", False), XInternAtom(mmsfb->x_display, "ATOM[]/32", False), 32, PropModePrepend, (unsigned char*) &the_atom,1);
00859
00860 XSetWMProtocols(mmsfb->x_display, this->x_window, &the_atom, 1);
00861
00862 } else {
00863 x_window_mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
00864
00865
00866 this->x_window = XCreateWindow(mmsfb->x_display, DefaultRootWindow(mmsfb->x_display), mmsfb->x11_win_rect.x, mmsfb->x11_win_rect.y, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, 0, mmsfb->x_depth,
00867 InputOutput, this->x_visual, x_window_mask, &x_window_attr);
00868 this->x_window_w = mmsfb->x11_win_rect.w;
00869 this->x_window_h = mmsfb->x11_win_rect.h;
00870 }
00871
00872
00873 XFlush(mmsfb->x_display);
00874 XSync(mmsfb->x_display, False);
00875
00876 this->x_gc = XCreateGC(mmsfb->x_display, this->x_window, 0, NULL);
00877
00878
00879 this->x_image1 = XShmCreateImage(mmsfb->x_display, this->x_visual, mmsfb->x_depth, ZPixmap,
00880 NULL, &this->x_shminfo1, this->config.w, this->config.h);
00881 if (!this->x_image1) {
00882 XUnlockDisplay(mmsfb->x_display);
00883 MMSFB_SetError(0, "XShmCreateImage() failed");
00884 return false;
00885 }
00886
00887
00888 this->x_shminfo1.shmid = shmget(IPC_PRIVATE, this->x_image1->bytes_per_line * this->x_image1->height, IPC_CREAT | 0777);
00889 this->x_shminfo1.shmaddr = this->x_image1->data = (char *)shmat(this->x_shminfo1.shmid, 0, 0);
00890 this->x_shminfo1.readOnly = False;
00891
00892
00893 if (!XShmAttach(mmsfb->x_display, &this->x_shminfo1)) {
00894 XFree(this->x_image1);
00895 this->x_image1 = NULL;
00896 XUnlockDisplay(mmsfb->x_display);
00897 MMSFB_SetError(0, "XShmAttach() failed");
00898 return false;
00899 }
00900
00901
00902 this->x_image2 = XShmCreateImage(mmsfb->x_display, this->x_visual, mmsfb->x_depth, ZPixmap,
00903 NULL, &this->x_shminfo2, this->config.w, this->config.h);
00904 if (!this->x_image2) {
00905 XUnlockDisplay(mmsfb->x_display);
00906 MMSFB_SetError(0, "XShmCreateImage() failed");
00907 return false;
00908 }
00909
00910
00911 this->x_shminfo2.shmid = shmget(IPC_PRIVATE, this->x_image2->bytes_per_line * this->x_image2->height, IPC_CREAT | 0777);
00912 this->x_shminfo2.shmaddr = this->x_image2->data = (char *)shmat(this->x_shminfo2.shmid, 0, 0);
00913 this->x_shminfo2.readOnly = False;
00914
00915
00916 if (!XShmAttach(mmsfb->x_display, &this->x_shminfo2)) {
00917 XFree(this->x_image2);
00918 this->x_image2 = NULL;
00919 XUnlockDisplay(mmsfb->x_display);
00920 MMSFB_SetError(0, "XShmAttach() failed");
00921 return false;
00922 }
00923
00924 if ((mmsfb->fullscreen == MMSFB_FSM_TRUE || mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO)&&(1==0)) {
00925
00926
00927 MMSFBRectangle dest;
00928 calcAspectRatio(this->config.w, this->config.h, mmsfb->display_w, mmsfb->display_h, dest,
00929 (mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO), false);
00930
00931
00932 this->x_image_scaler = XShmCreateImage(mmsfb->x_display, this->x_visual, mmsfb->x_depth, ZPixmap,
00933 NULL, &this->x_shminfo_scaler, dest.w, dest.h);
00934 if (!this->x_image_scaler) {
00935 XUnlockDisplay(mmsfb->x_display);
00936 MMSFB_SetError(0, "XShmCreateImage() failed");
00937 return false;
00938 }
00939
00940
00941 this->x_shminfo_scaler.shmid = shmget(IPC_PRIVATE, this->x_image_scaler->bytes_per_line * this->x_image_scaler->height, IPC_CREAT | 0777);
00942 this->x_shminfo_scaler.shmaddr = this->x_image_scaler->data = (char *)shmat(this->x_shminfo_scaler.shmid, 0, 0);
00943 this->x_shminfo_scaler.readOnly = False;
00944
00945
00946 if (!XShmAttach(mmsfb->x_display, &this->x_shminfo_scaler)) {
00947 XFree(this->x_image_scaler);
00948 this->x_image_scaler = NULL;
00949 XUnlockDisplay(mmsfb->x_display);
00950 MMSFB_SetError(0, "XShmAttach() failed");
00951 return false;
00952 }
00953
00954
00955 this->scaler = new MMSFBSurface(dest.w, dest.h, this->config.pixelformat,
00956 this->x_image_scaler, NULL, NULL);
00957 if (!this->scaler) {
00958 XUnlockDisplay(mmsfb->x_display);
00959 MMSFB_SetError(0, "cannot create scaler surface");
00960 return false;
00961 }
00962 this->scaler->layer=this;
00963
00964 this->scaler->setExtendedAcceleration(true);
00965 }
00966
00967 XFlush(mmsfb->x_display);
00968 XSync(mmsfb->x_display, False);
00969
00970 this->impl.x_display = mmsfb->x_display;
00971 this->impl.x_gc = this->x_gc;
00972 this->impl.x_window = this->x_window;
00973 this->impl.w = this->x_window_w;
00974 this->impl.h = this->x_window_h;
00975 this->impl.x_screen = mmsfb->x_screen;
00976 } else if(config.pixelformat == MMSFB_PF_YV12) {
00977 #ifdef __HAVE_XV__
00978
00979 unsigned int p_version,
00980 p_release,
00981 p_request_base,
00982 p_event_base,
00983 p_error_base;
00984
00985 if (XvQueryExtension(mmsfb->x_display, &p_version, &p_release, &p_request_base, &p_event_base, &p_error_base) != Success) {
00986 MMSFB_SetError(0, "XvQueryExtension() failed");
00987 fflush(stdout);
00988 return false;
00989 }
00990
00991 unsigned int num_adaptors;
00992 XvAdaptorInfo *ai;
00993 if (XvQueryAdaptors(mmsfb->x_display, DefaultRootWindow(mmsfb->x_display), &num_adaptors, &ai)) {
00994 MMSFB_SetError(0, "XvQueryAdaptors() failed");
00995 return false;
00996 }
00997 printf("DISKO: Available xv adaptors:\n");
00998 for(unsigned int cnt=0;cnt<num_adaptors;cnt++) {
00999
01000 if((mmsfb->xv_port == 0) &&
01001 (ai[cnt].type & XvImageMask) &&
01002 (XvGrabPort(mmsfb->x_display, ai[cnt].base_id, 0) == Success)) {
01003 mmsfb->xv_port = ai[cnt].base_id;
01004 printf(" %s (used)\n", ai[cnt].name);
01005 }
01006 else
01007 printf(" %s\n", ai[cnt].name);
01008 }
01009 XvFreeAdaptorInfo(ai);
01010
01011
01012
01013
01014 int image_width = this->config.w & ~0x7f;
01015 if (this->config.w & 0x7f)
01016 image_width += 0x80;
01017
01018
01019 int nFormats, xvPixFormat = (('2'<<24)|('1'<<16)|('V'<<8)|'Y');
01020 XvImageFormatValues *formats = XvListImageFormats(mmsfb->x_display, mmsfb->xv_port, &nFormats);
01021 if(formats) {
01022 for(int i = 0; i < nFormats; i++) {
01023 if(formats[i].type == XvYUV && formats[i].format == XvPlanar) {
01024 xvPixFormat = formats[i].id;
01025 break;
01026 }
01027 }
01028 XFree(formats);
01029 }
01030
01031
01032 this->xv_image1 = XvShmCreateImage(mmsfb->x_display, mmsfb->xv_port, xvPixFormat, 0, image_width, this->config.h, &this->xv_shminfo1);
01033 if(!this->xv_image1) {
01034 XUnlockDisplay(mmsfb->x_display);
01035 MMSFB_SetError(0, "XvShmCreateImage() failed");
01036 return false;
01037 }
01038 if(this->xv_image1->data_size == 0) {
01039 XFree(this->xv_image1);
01040 XUnlockDisplay(mmsfb->x_display);
01041 this->xv_image1 = NULL;
01042 MMSFB_SetError(0, "XvShmCreateImage() returned zero size");
01043 return false;
01044 }
01045
01046
01047 this->xv_shminfo1.shmid = shmget(IPC_PRIVATE, this->xv_image1->data_size, IPC_CREAT | 0777);
01048 if(this->xv_shminfo1.shmid < 0) {
01049 MMSFB_SetError(0, string("Error in shmget: ") + strerror(errno));
01050 XFree(this->xv_image1);
01051 XUnlockDisplay(mmsfb->x_display);
01052 this->xv_image1 = NULL;
01053 return false;
01054 }
01055
01056 this->xv_shminfo1.shmaddr = this->xv_image1->data = (char *)shmat(this->xv_shminfo1.shmid, 0, 0);
01057 if(!this->xv_shminfo1.shmaddr || (this->xv_shminfo1.shmaddr == (char*)-1)) {
01058 MMSFB_SetError(0, string("Error in shmat: ") + strerror(errno));
01059 XFree(this->xv_image1);
01060 XUnlockDisplay(mmsfb->x_display);
01061 this->xv_image1 = NULL;
01062 return false;
01063 }
01064
01065 this->xv_shminfo1.readOnly = False;
01066
01067
01068 if (!XShmAttach(mmsfb->x_display, &this->xv_shminfo1)) {
01069 XFree(this->xv_image1);
01070 XUnlockDisplay(mmsfb->x_display);
01071 this->xv_image1 = NULL;
01072 MMSFB_SetError(0, "XShmAttach() failed");
01073 return false;
01074 }
01075
01076
01077 XSync(mmsfb->x_display, False);
01078 shmctl(this->xv_shminfo1.shmid, IPC_RMID, 0);
01079
01080
01081 this->xv_image2 = XvShmCreateImage(mmsfb->x_display, mmsfb->xv_port, xvPixFormat, 0, image_width, this->config.h, &this->xv_shminfo2);
01082 if (!this->xv_image2) {
01083 XFree(this->xv_image1);
01084 XUnlockDisplay(mmsfb->x_display);
01085 this->xv_image1 = NULL;
01086 MMSFB_SetError(0, "XvShmCreateImage() failed");
01087 return false;
01088 }
01089 if(this->xv_image2->data_size == 0) {
01090 XFree(this->xv_image1);
01091 XFree(this->xv_image2);
01092 XUnlockDisplay(mmsfb->x_display);
01093 this->xv_image1 = NULL;
01094 this->xv_image2 = NULL;
01095 MMSFB_SetError(0, "XvShmCreateImage() returned zero size");
01096 return false;
01097 }
01098
01099
01100 this->xv_shminfo2.shmid = shmget(IPC_PRIVATE, this->xv_image2->data_size, IPC_CREAT | 0777);
01101 if(this->xv_shminfo2.shmid < 0) {
01102 MMSFB_SetError(0, string("Error in shmget: ") + strerror(errno));
01103 XFree(this->xv_image1);
01104 XFree(this->xv_image2);
01105 XUnlockDisplay(mmsfb->x_display);
01106 this->xv_image1 = NULL;
01107 this->xv_image2 = NULL;
01108 return false;
01109 }
01110
01111 this->xv_shminfo2.shmaddr = this->xv_image2->data = (char *)shmat(this->xv_shminfo2.shmid, 0, 0);
01112 if(!this->xv_shminfo2.shmaddr || (this->xv_shminfo2.shmaddr == (char*)-1)) {
01113 MMSFB_SetError(0, string("Error in shmat: ") + strerror(errno));
01114 XFree(this->xv_image1);
01115 XFree(this->xv_image2);
01116 XUnlockDisplay(mmsfb->x_display);
01117 this->xv_image1 = NULL;
01118 this->xv_image2 = NULL;
01119 return false;
01120 }
01121
01122 this->xv_shminfo2.readOnly = False;
01123
01124
01125 if (!XShmAttach(mmsfb->x_display, &this->xv_shminfo2)) {
01126 XFree(this->xv_image1);
01127 XFree(this->xv_image2);
01128 XUnlockDisplay(mmsfb->x_display);
01129 this->xv_image1 = NULL;
01130 this->xv_image2 = NULL;
01131 MMSFB_SetError(0, "XShmAttach() failed");
01132 return false;
01133 }
01134
01135
01136 XSync(mmsfb->x_display, False);
01137 shmctl(this->xv_shminfo2.shmid, IPC_RMID, 0);
01138
01139 XSetWindowAttributes x_window_attr;
01140 unsigned long x_window_mask;
01141 this->x_visual = DefaultVisual(mmsfb->x_display,mmsfb->x_screen);
01142
01143
01144 x_window_attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |PointerMotionMask|EnterWindowMask|ResizeRedirectMask;
01145 x_window_attr.background_pixel = 0;
01146 x_window_attr.border_pixel = 0;
01147 if(mmsfb->fullscreen == MMSFB_FSM_TRUE) {
01148 x_window_mask = CWBackPixel | CWBorderPixel | CWEventMask ;
01149
01150 this->x_window = XCreateWindow(mmsfb->x_display, DefaultRootWindow(mmsfb->x_display), 0, 0, mmsfb->display_w, mmsfb->display_h, 0, CopyFromParent,
01151 InputOutput, this->x_visual, x_window_mask, &x_window_attr);
01152
01153 this->x_window_w = mmsfb->display_w;
01154 this->x_window_h = mmsfb->display_h;
01155 Atom the_atom = XInternAtom(mmsfb->x_display, "_NET_WM_WINDOW_TYPE_SPLASH", False);
01156 XChangeProperty(mmsfb->x_display, this->x_window,XInternAtom(mmsfb->x_display, "_NET_WM_WINDOW_TYPE", False), XInternAtom(mmsfb->x_display, "ATOM[]/32", False), 32, PropModePrepend, (unsigned char*) &the_atom,1);
01157
01158 XSetWMProtocols(mmsfb->x_display, this->x_window, &the_atom, 1);
01159 } else {
01160 x_window_mask = CWBackPixel | CWBorderPixel | CWEventMask ;
01161
01162 this->x_window_w = mmsfb->x11_win_rect.w;
01163 this->x_window_h = mmsfb->x11_win_rect.h;
01164 this->x_window = XCreateWindow(mmsfb->x_display, DefaultRootWindow(mmsfb->x_display), mmsfb->x11_win_rect.x, mmsfb->x11_win_rect.y, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, 0, CopyFromParent,
01165 InputOutput, this->x_visual, x_window_mask, &x_window_attr);
01166
01167 }
01168
01169 this->x_gc = XCreateGC(mmsfb->x_display, this->x_window, 0, 0);
01170
01171 this->impl.x_display = mmsfb->x_display;
01172 this->impl.x_gc = this->x_gc;
01173 this->impl.x_window = this->x_window;
01174 this->impl.w = this->x_window_w;
01175 this->impl.h = this->x_window_h;
01176 this->impl.xv_image1 = this->xv_image1;
01177 this->impl.xv_image2 = this->xv_image2;
01178 this->impl.xv_port = mmsfb->xv_port;
01179 this->impl.x_screen = mmsfb->x_screen;
01180 #endif
01181 }
01182
01183
01184 if (this->config.outputtype == MMSFB_OT_OGL) {
01185 #ifdef __HAVE_OPENGL__
01186 #ifdef __HAVE_GLX__
01187 XUnlockDisplay(mmsfb->x_display);
01188 mmsfb->bei->init(mmsfb->x_display, mmsfb->x_screen, this->x_window, mmsfb->x11_win_rect);
01189 XLockDisplay(mmsfb->x_display);
01190 #endif
01191 #endif
01192 }
01193
01194 mmsfb->x_windows[this->config.id] = this->x_window;
01195
01196 if(this->config.id == 0) {
01197 mmsfb->input_window = this->x_window;
01198 XStoreName(mmsfb->x_display, this->x_window, mmsfb->applname.c_str());
01199 XSetIconName(mmsfb->x_display, this->x_window, mmsfb->appliconname.c_str());
01200 XClassHint clhi;
01201 clhi.res_name=(basename((char *)mmsfb->bin.c_str()));
01202
01203 clhi.res_class=(char*)"disko";
01204 XSetClassHint(mmsfb->x_display, this->x_window,&clhi);
01205 if(!mmsfb->hidden) {
01206 XMapWindow(mmsfb->x_display, this->x_window);
01207 XEvent x_event;
01208 do {
01209 XNextEvent(mmsfb->x_display, &x_event);
01210 }
01211 while (x_event.type != MapNotify || x_event.xmap.event != this->x_window);
01212
01213 XRaiseWindow(mmsfb->x_display, this->x_window);
01214 }
01215
01216 if (mmsfb->pointer != MMSFB_PM_EXTERNAL) {
01217 Pixmap bm_no;
01218 Colormap cmap;
01219 Cursor no_ptr;
01220 XColor black, dummy;
01221 static char bm_no_data[] = {0, 0, 0, 0, 0, 0, 0, 0};
01222
01223 cmap = DefaultColormap(mmsfb->x_display, DefaultScreen(mmsfb->x_display));
01224 XAllocNamedColor(mmsfb->x_display, cmap, "black", &black, &dummy);
01225 bm_no = XCreateBitmapFromData(mmsfb->x_display, this->x_window, bm_no_data, 8, 8);
01226 no_ptr = XCreatePixmapCursor(mmsfb->x_display, bm_no, bm_no, &black, &black, 0, 0);
01227
01228 XDefineCursor(mmsfb->x_display, this->x_window, no_ptr);
01229 XFreeCursor(mmsfb->x_display, no_ptr);
01230 if (bm_no != None)
01231 XFreePixmap(mmsfb->x_display, bm_no);
01232 XFreeColors(mmsfb->x_display, cmap, &black.pixel, 1, 0);
01233 }
01234 if(!mmsfb->hidden)
01235 XSetInputFocus(mmsfb->x_display, this->x_window,RevertToPointerRoot,CurrentTime);
01236 } else {
01237 if(!mmsfb->hidden) {
01238 XMapWindow(mmsfb->x_display, this->x_window);
01239 XEvent x_event;
01240 do {
01241 XNextEvent(mmsfb->x_display, &x_event);
01242 }
01243 while (x_event.type != MapNotify || x_event.xmap.event != this->x_window);
01244
01245 XRaiseWindow(mmsfb->x_display, this->x_window);
01246 }
01247 }
01248 XUnlockDisplay(mmsfb->x_display);
01249
01250 return true;
01251 #endif
01252 }
01253
01254 return false;
01255 }
01256
01257 bool MMSFBLayer::setOpacity(unsigned char opacity) {
01258
01259
01260 INITCHECK;
01261
01262 if (this->config.backend == MMSFB_BE_DFB) {
01263 #ifdef __HAVE_DIRECTFB__
01264 DFBResult dfbres;
01265
01266
01267 if (this->config.pixelformat == MMSFB_PF_AiRGB) {
01268 opacity = 255 - opacity;
01269 }
01270
01271
01272 if ((dfbres=this->dfblayer->SetOpacity(this->dfblayer, opacity)) != DFB_OK) {
01273 MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::SetOpacity(" + iToStr(opacity) + ") failed");
01274 return false;
01275 }
01276
01277 return true;
01278 #endif
01279 }
01280
01281 return false;
01282 }
01283
01284 bool MMSFBLayer::setLevel(int level) {
01285
01286
01287 INITCHECK;
01288
01289 if (this->config.backend == MMSFB_BE_DFB) {
01290 #ifdef __HAVE_DIRECTFB__
01291 DFBResult dfbres;
01292
01293
01294 if ((dfbres=this->dfblayer->SetLevel(this->dfblayer, level)) != DFB_OK) {
01295 MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::SetLevel(" + iToStr(level) + ") failed");
01296 return false;
01297 }
01298 return true;
01299 #endif
01300 } else if (this->config.backend == MMSFB_BE_X11) {
01301 #ifdef __HAVE_XLIB__
01302 XRaiseWindow(mmsfb->x_display, this->x_window);
01303
01304 #endif
01305 }
01306 return false;
01307 }
01308
01309 bool MMSFBLayer::getSurface(MMSFBSurface **surface, bool clear) {
01310
01311
01312 INITCHECK;
01313
01314 if (this->surface) {
01315
01316 *surface = this->surface;
01317 DEBUGMSG("MMSGUI", "have already a surface");
01318
01319 if (clear) {
01320
01321 this->surface->lock();
01322 this->surface->clear();
01323 this->surface->flip();
01324 this->surface->unlock();
01325 }
01326
01327 return true;
01328 }
01329
01330
01331 *surface = NULL;
01332
01333 if (this->config.backend == MMSFB_BE_DFB) {
01334 #ifdef __HAVE_DIRECTFB__
01335
01336 DFBResult dfbres;
01337 IDirectFBSurface *dfbsurface;
01338 DEBUGMSG("MMSGUI", "calling DFB->GetSurface()");
01339 if ((dfbres=this->dfblayer->GetSurface(this->dfblayer, &dfbsurface)) != DFB_OK) {
01340 MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::GetSurface() failed");
01341 return false;
01342 }
01343 DEBUGMSG("MMSGUI", "setting blitting flags");
01344 dfbsurface->SetBlittingFlags(dfbsurface, DSBLIT_NOFX);
01345
01346
01347 *surface = new MMSFBSurface(dfbsurface);
01348 if (!*surface) {
01349 dfbsurface->Release(dfbsurface);
01350 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface");
01351 return false;
01352 }
01353 #endif
01354 }
01355 else
01356 if (this->config.backend == MMSFB_BE_FBDEV) {
01357 #ifdef __HAVE_FBDEV__
01358 if (this->config.outputtype == MMSFB_OT_OGL) {
01359 #ifdef __HAVE_OPENGL__
01360
01361 *surface = new MMSFBSurface(this->config.w, this->config.h, MMSFBSurfaceAllocatedBy_ogl);
01362 if (!*surface) {
01363 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface for OPENGL");
01364 return false;
01365 }
01366 #endif
01367 }
01368 else
01369 if (this->config.buffermode == MMSFB_BM_FRONTONLY) {
01370
01371 *surface = this->mmsfbdev_surface;
01372 if (!*surface) {
01373 MMSFB_SetError(0, "layer surface is not initialized");
01374 return false;
01375 }
01376 }
01377 else
01378 if (this->config.buffermode == MMSFB_BM_BACKSYSTEM) {
01379
01380 *surface = new MMSFBSurface(this->config.w, this->config.h, this->config.pixelformat);
01381 if (!*surface) {
01382 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface");
01383 return false;
01384 }
01385
01386
01387 (*surface)->config.surface_buffer->mmsfbdev_surface = this->mmsfbdev_surface;
01388
01389
01390 (*surface)->setExtendedAcceleration(true);
01391 }
01392 else {
01393
01394 *surface = this->mmsfbdev_surface;
01395 if (!*surface) {
01396 MMSFB_SetError(0, "layer surface is not initialized");
01397 return false;
01398 }
01399
01400
01401
01402
01403 (*surface)->config.surface_buffer->mmsfbdev_surface = this->mmsfbdev_surface;
01404 }
01405 #endif
01406 }
01407 else
01408 if (this->config.backend == MMSFB_BE_X11) {
01409 #ifdef __HAVE_XLIB__
01410 if (this->config.outputtype == MMSFB_OT_OGL) {
01411 #ifdef __HAVE_OPENGL__
01412
01413 *surface = new MMSFBSurface(this->config.w, this->config.h, MMSFBSurfaceAllocatedBy_ogl);
01414 if (!*surface) {
01415 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface for OPENGL");
01416 return false;
01417 }
01418 #endif
01419 }
01420 else
01421 if (isRGBPixelFormat(this->config.pixelformat)) {
01422
01423 if ((!this->x_image1)||(!this->x_image2)) {
01424 MMSFB_SetError(0, "x_image not available, cannot get surface");
01425 return false;
01426 }
01427
01428
01429 *surface = new MMSFBSurface(this->config.w, this->config.h, this->config.pixelformat,
01430 this->x_image1, this->x_image2, this->scaler);
01431 if (!*surface) {
01432 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface");
01433 return false;
01434 }
01435
01436
01437 (*surface)->setExtendedAcceleration(true);
01438 (*surface)->layer=this;
01439 }
01440 else {
01441 #ifdef __HAVE_XV__
01442
01443
01444 if ((!this->xv_image1)||(!this->xv_image2)) {
01445 MMSFB_SetError(0, "xv_image not available, cannot get surface");
01446 return false;
01447 }
01448
01449
01450 *surface = new MMSFBSurface(this->config.w, this->config.h, this->config.pixelformat,
01451 this->xv_image1, this->xv_image2);
01452 if (!*surface) {
01453 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface");
01454 return false;
01455 }
01456
01457
01458 (*surface)->setExtendedAcceleration(true);
01459 (*surface)->layer=this;
01460 #endif
01461 }
01462 #endif
01463 }
01464
01465
01466 this->surface = *surface;
01467
01468 if (this->surface) {
01469 this->surface->lock();
01470
01471 this->surface->setLayerSurface();
01472
01473 if (clear) {
01474
01475 this->surface->clear();
01476 this->surface->flip();
01477 }
01478
01479
01480 this->surface->setFlipFlags(this->flipflags);
01481
01482 this->surface->unlock();
01483
01484 return true;
01485 }
01486
01487 return false;
01488 }
01489
01490 bool MMSFBLayer::setFlipFlags(MMSFBFlipFlags flags) {
01491 this->flipflags = flags;
01492
01493
01494 if (this->surface) {
01495 this->surface->lock();
01496 this->surface->setFlipFlags(this->flipflags);
01497 this->surface->unlock();
01498 }
01499
01500 return true;
01501 }
01502
01503 bool MMSFBLayer::releaseLayer() {
01504
01505
01506 INITCHECK;
01507
01508 if (this->config.backend == MMSFB_BE_FBDEV) {
01509 #ifdef __HAVE_FBDEV__
01510 if (mmsfb->mmsfbdev) {
01511 return mmsfb->mmsfbdev->releaseLayer(this->config.id);
01512 }
01513 #endif
01514 }
01515
01516 return false;
01517 }
01518
01519 bool MMSFBLayer::restoreLayer() {
01520
01521
01522 INITCHECK;
01523
01524 if (this->config.backend == MMSFB_BE_FBDEV) {
01525 #ifdef __HAVE_FBDEV__
01526 if (mmsfb->mmsfbdev) {
01527 return mmsfb->mmsfbdev->restoreLayer(this->config.id);
01528 }
01529 #endif
01530 }
01531
01532 return false;
01533 }
01534
01535 bool MMSFBLayer::createSurface(MMSFBSurface **surface, int w, int h,
01536 MMSFBSurfacePixelFormat pixelformat, int backbuffer) {
01537
01538
01539 INITCHECK;
01540
01541 if (pixelformat == MMSFB_PF_NONE) {
01542 pixelformat = this->config.surface_pixelformat;
01543
01544 if (this->config.outputtype == MMSFB_OT_OGL) {
01545 pixelformat = MMSFB_PF_ABGR;
01546 }
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569 }
01570
01571 if (firsttime_createsurface) {
01572 printf("DISKO: Pixelformat %s is used for surfaces.\n", getMMSFBPixelFormatString(pixelformat).c_str());
01573 firsttime_createsurface = false;
01574 }
01575 if (mmsfb->createSurface(surface, w, h, pixelformat, backbuffer, (this->config.buffermode == MMSFB_BM_BACKSYSTEM))) {
01576 (*surface)->layer = this;
01577 return true;
01578 } else {
01579 return false;
01580 }
01581 }
01582
01583 bool MMSFBLayer::createWindow(MMSFBWindow **window, int x, int y, int w, int h,
01584 MMSFBSurfacePixelFormat pixelformat, bool usealpha, int backbuffer) {
01585
01586
01587 INITCHECK;
01588
01589
01590 MMSFBLayer *layer;
01591 mmsfbwindowmanager->getLayer(&layer);
01592 if (layer != this) {
01593 MMSFB_SetError(0, "not the right layer, cannot create MMSFBWindow");
01594 return false;
01595 }
01596
01597 if (pixelformat == MMSFB_PF_NONE) {
01598 if (usealpha) {
01599
01600 pixelformat = this->config.window_pixelformat;
01601 }
01602 else {
01603
01604 pixelformat = this->config.pixelformat;
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614 }
01615
01616 if (this->config.outputtype == MMSFB_OT_OGL) {
01617 pixelformat = MMSFB_PF_ABGR;
01618 }
01619
01620 }
01621
01622
01623 if (usealpha) {
01624 if (firsttime_createwindow_usealpha) {
01625 printf("DISKO: Pixelformat %s is used for windows with alphachannel.\n", getMMSFBPixelFormatString(pixelformat).c_str());
01626 firsttime_createwindow_usealpha = false;
01627 }
01628 }
01629 else
01630 if (firsttime_createwindow_noalpha) {
01631 printf("DISKO: Pixelformat %s is used for windows with no alphachannel.\n", getMMSFBPixelFormatString(pixelformat).c_str());
01632 firsttime_createwindow_noalpha = false;
01633 }
01634
01635
01636 #ifdef USE_DFB_WINMAN
01637
01638 DFBResult dfbres;
01639 IDirectFBWindow *dfbwindow;
01640 DFBWindowDescription window_desc;
01641
01642
01643 window_desc.flags = (DFBWindowDescriptionFlags)(DWDESC_POSX | DWDESC_POSY | DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_PIXELFORMAT | DWDESC_CAPS);
01644 window_desc.posx = x;
01645 window_desc.posy = y;
01646 window_desc.width = w;
01647 window_desc.height = h;
01648 window_desc.pixelformat = getDFBPixelFormatFromString(pixelformat);
01649
01650
01651 if (!isAlphaPixelFormat(pixelformat)) {
01652 if (backbuffer)
01653 window_desc.caps = (DFBWindowCapabilities)(DWCAPS_DOUBLEBUFFER);
01654 else
01655 window_desc.caps = (DFBWindowCapabilities)0;
01656 }
01657 else {
01658 if (backbuffer)
01659 window_desc.caps = (DFBWindowCapabilities)(DWCAPS_DOUBLEBUFFER | DWCAPS_ALPHACHANNEL);
01660 else
01661 window_desc.caps = (DFBWindowCapabilities)(DWCAPS_ALPHACHANNEL);
01662 }
01663
01664
01665 if ((dfbres=this->dfblayer->CreateWindow(this->dfblayer, &window_desc, &dfbwindow)) != DFB_OK) {
01666 MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::CreateWindow(" + iToStr(w) + "x" + iToStr(h) + "," + getDFBPixelFormatString(window_desc.pixelformat) + ") failed");
01667 return false;
01668 }
01669
01670
01671 *window = new MMSFBWindow(dfbwindow, window_desc.posx, window_desc.posy);
01672 if (!*window) {
01673 dfbwindow->Release(dfbwindow);
01674 MMSFB_SetError(0, "cannot create new instance of MMSFBWindow");
01675 return false;
01676 }
01677
01678 #endif
01679
01680 #ifdef USE_MMSFB_WINMAN
01681
01682
01683 MMSFBSurface *surface;
01684 if (!mmsfb->createSurface(&surface, w, h, pixelformat, backbuffer, (this->config.buffermode == MMSFB_BM_BACKSYSTEM)))
01685 return false;
01686 surface->layer=this;
01687
01688 *window = new MMSFBWindow(surface, x, y);
01689 if (!*window) {
01690 delete surface;
01691 MMSFB_SetError(0, "cannot create new instance of MMSFBWindow");
01692 return false;
01693 }
01694
01695
01696 surface->setWinSurface();
01697
01698
01699 mmsfbwindowmanager->addWindow(*window);
01700
01701 #endif
01702
01703 return true;
01704 }
01705
01706 void *MMSFBLayer::getImplementation() {
01707 #ifdef __HAVE_XLIB__
01708 return &(this->impl);
01709 #else
01710 return NULL;
01711 #endif
01712 }
01713
01714
01715