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