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 shmctl(this->x_shminfo1.shmid, IPC_RMID, 0);
00843 XFree(this->x_image1);
00844 this->x_image1 = NULL;
00845 XUnlockDisplay(mmsfb->x_display);
00846 MMSFB_SetError(0, "XShmAttach() failed");
00847 return false;
00848 }
00849 shmctl(this->x_shminfo1.shmid, IPC_RMID, 0);
00850
00851
00852 this->x_image2 = XShmCreateImage(mmsfb->x_display, this->x_visual, 32, ZPixmap,
00853 NULL, &this->x_shminfo2, this->config.w, this->config.h);
00854 if (!this->x_image2) {
00855 XUnlockDisplay(mmsfb->x_display);
00856 MMSFB_SetError(0, "XShmCreateImage() failed");
00857 return false;
00858 }
00859
00860
00861 this->x_shminfo2.shmid = shmget(IPC_PRIVATE, this->x_image2->bytes_per_line * this->x_image2->height, IPC_CREAT | 0777);
00862 this->x_shminfo2.shmaddr = this->x_image2->data = (char *)shmat(this->x_shminfo2.shmid, 0, 0);
00863 this->x_shminfo2.readOnly = False;
00864
00865
00866 if (!XShmAttach(mmsfb->x_display, &this->x_shminfo2)) {
00867 shmctl(this->x_shminfo2.shmid, IPC_RMID, 0);
00868 XFree(this->x_image2);
00869 this->x_image2 = NULL;
00870 XUnlockDisplay(mmsfb->x_display);
00871 MMSFB_SetError(0, "XShmAttach() failed");
00872 return false;
00873 }
00874 shmctl(this->x_shminfo2.shmid, IPC_RMID, 0);
00875
00876 if ((mmsfb->fullscreen == MMSFB_FSM_TRUE || mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO)&&(1==0)) {
00877
00878
00879 MMSFBRectangle dest;
00880 calcAspectRatio(this->config.w, this->config.h, mmsfb->display_w, mmsfb->display_h, dest,
00881 (mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO), false);
00882
00883
00884 this->x_image_scaler = XShmCreateImage(mmsfb->x_display, this->x_visual, 32, ZPixmap,
00885 NULL, &this->x_shminfo_scaler, dest.w, dest.h);
00886 if (!this->x_image_scaler) {
00887 XUnlockDisplay(mmsfb->x_display);
00888 MMSFB_SetError(0, "XShmCreateImage() failed");
00889 return false;
00890 }
00891
00892
00893 this->x_shminfo_scaler.shmid = shmget(IPC_PRIVATE, this->x_image_scaler->bytes_per_line * this->x_image_scaler->height, IPC_CREAT | 0777);
00894 this->x_shminfo_scaler.shmaddr = this->x_image_scaler->data = (char *)shmat(this->x_shminfo_scaler.shmid, 0, 0);
00895 this->x_shminfo_scaler.readOnly = False;
00896
00897
00898 if (!XShmAttach(mmsfb->x_display, &this->x_shminfo_scaler)) {
00899 shmctl(this->x_shminfo_scaler.shmid, IPC_RMID, 0);
00900 XFree(this->x_image_scaler);
00901 this->x_image_scaler = NULL;
00902 XUnlockDisplay(mmsfb->x_display);
00903 MMSFB_SetError(0, "XShmAttach() failed");
00904 return false;
00905 }
00906 shmctl(this->x_shminfo_scaler.shmid, IPC_RMID, 0);
00907
00908
00909 this->scaler = new MMSFBSurface(dest.w, dest.h, this->config.pixelformat,
00910 this->x_image_scaler, NULL, NULL);
00911 if (!this->scaler) {
00912 XUnlockDisplay(mmsfb->x_display);
00913 MMSFB_SetError(0, "cannot create scaler surface");
00914 return false;
00915 }
00916 this->scaler->layer=this;
00917
00918 this->scaler->setExtendedAcceleration(true);
00919 }
00920 }
00921
00922 XFlush(mmsfb->x_display);
00923 XSync(mmsfb->x_display, False);
00924
00925 this->impl.x_display = mmsfb->x_display;
00926 this->impl.x_gc = this->x_gc;
00927 this->impl.x_window = this->x_window;
00928 this->impl.w = this->x_window_w;
00929 this->impl.h = this->x_window_h;
00930 this->impl.x_screen = mmsfb->x_screen;
00931 #endif
00932 } else if(config.pixelformat == MMSFB_PF_RGB32 || config.pixelformat == MMSFB_PF_RGB24) {
00933
00934 this->x_visual = DefaultVisual(mmsfb->x_display, mmsfb->x_screen);
00935 mmsfb->x_depth=DefaultDepth(mmsfb->x_display, mmsfb->x_screen);
00936 XSetWindowAttributes x_window_attr;
00937 x_window_attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |PointerMotionMask|EnterWindowMask|ResizeRedirectMask;
00938 x_window_attr.background_pixel = 0;
00939 x_window_attr.border_pixel = 0;
00940 x_window_attr.colormap = colormap;
00941 unsigned long x_window_mask;
00942
00943 if(mmsfb->fullscreen == MMSFB_FSM_TRUE) {
00944 x_window_mask = CWBackPixel | CWBorderPixel | CWEventMask |CWColormap;
00945
00946
00947 this->x_window = XCreateWindow(mmsfb->x_display,DefaultRootWindow(mmsfb->x_display) , 0, 0, mmsfb->display_w, mmsfb->display_h, 0, mmsfb->x_depth,
00948 InputOutput, this->x_visual, x_window_mask, &x_window_attr);
00949
00950 this->x_window_w = mmsfb->display_w;
00951 this->x_window_h = mmsfb->display_h;
00952
00953 Atom the_atom = XInternAtom(mmsfb->x_display, "_NET_WM_WINDOW_TYPE_SPLASH", False);
00954 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);
00955
00956 XSetWMProtocols(mmsfb->x_display, this->x_window, &the_atom, 1);
00957
00958 } else {
00959 x_window_mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
00960
00961
00962 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,
00963 InputOutput, this->x_visual, x_window_mask, &x_window_attr);
00964 this->x_window_w = mmsfb->x11_win_rect.w;
00965 this->x_window_h = mmsfb->x11_win_rect.h;
00966 }
00967
00968
00969 XFlush(mmsfb->x_display);
00970 XSync(mmsfb->x_display, False);
00971
00972 this->x_gc = XCreateGC(mmsfb->x_display, this->x_window, 0, NULL);
00973
00974
00975 this->x_image1 = XShmCreateImage(mmsfb->x_display, this->x_visual, mmsfb->x_depth, ZPixmap,
00976 NULL, &this->x_shminfo1, this->config.w, this->config.h);
00977 if (!this->x_image1) {
00978 XUnlockDisplay(mmsfb->x_display);
00979 MMSFB_SetError(0, "XShmCreateImage() failed");
00980 return false;
00981 }
00982
00983
00984 this->x_shminfo1.shmid = shmget(IPC_PRIVATE, this->x_image1->bytes_per_line * this->x_image1->height, IPC_CREAT | 0777);
00985 this->x_shminfo1.shmaddr = this->x_image1->data = (char *)shmat(this->x_shminfo1.shmid, 0, 0);
00986 this->x_shminfo1.readOnly = False;
00987
00988
00989 if (!XShmAttach(mmsfb->x_display, &this->x_shminfo1)) {
00990 shmctl(this->x_shminfo1.shmid, IPC_RMID, 0);
00991 XFree(this->x_image1);
00992 this->x_image1 = NULL;
00993 XUnlockDisplay(mmsfb->x_display);
00994 MMSFB_SetError(0, "XShmAttach() failed");
00995 return false;
00996 }
00997 shmctl(this->x_shminfo1.shmid, IPC_RMID, 0);
00998
00999
01000 this->x_image2 = XShmCreateImage(mmsfb->x_display, this->x_visual, mmsfb->x_depth, ZPixmap,
01001 NULL, &this->x_shminfo2, this->config.w, this->config.h);
01002 if (!this->x_image2) {
01003 XUnlockDisplay(mmsfb->x_display);
01004 MMSFB_SetError(0, "XShmCreateImage() failed");
01005 return false;
01006 }
01007
01008
01009 this->x_shminfo2.shmid = shmget(IPC_PRIVATE, this->x_image2->bytes_per_line * this->x_image2->height, IPC_CREAT | 0777);
01010 this->x_shminfo2.shmaddr = this->x_image2->data = (char *)shmat(this->x_shminfo2.shmid, 0, 0);
01011 this->x_shminfo2.readOnly = False;
01012
01013
01014 if (!XShmAttach(mmsfb->x_display, &this->x_shminfo2)) {
01015 shmctl(this->x_shminfo2.shmid, IPC_RMID, 0);
01016 XFree(this->x_image2);
01017 this->x_image2 = NULL;
01018 XUnlockDisplay(mmsfb->x_display);
01019 MMSFB_SetError(0, "XShmAttach() failed");
01020 return false;
01021 }
01022 shmctl(this->x_shminfo2.shmid, IPC_RMID, 0);
01023
01024 if ((mmsfb->fullscreen == MMSFB_FSM_TRUE || mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO)&&(1==0)) {
01025
01026
01027 MMSFBRectangle dest;
01028 calcAspectRatio(this->config.w, this->config.h, mmsfb->display_w, mmsfb->display_h, dest,
01029 (mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO), false);
01030
01031
01032 this->x_image_scaler = XShmCreateImage(mmsfb->x_display, this->x_visual, mmsfb->x_depth, ZPixmap,
01033 NULL, &this->x_shminfo_scaler, dest.w, dest.h);
01034 if (!this->x_image_scaler) {
01035 XUnlockDisplay(mmsfb->x_display);
01036 MMSFB_SetError(0, "XShmCreateImage() failed");
01037 return false;
01038 }
01039
01040
01041 this->x_shminfo_scaler.shmid = shmget(IPC_PRIVATE, this->x_image_scaler->bytes_per_line * this->x_image_scaler->height, IPC_CREAT | 0777);
01042 this->x_shminfo_scaler.shmaddr = this->x_image_scaler->data = (char *)shmat(this->x_shminfo_scaler.shmid, 0, 0);
01043 this->x_shminfo_scaler.readOnly = False;
01044
01045
01046 if (!XShmAttach(mmsfb->x_display, &this->x_shminfo_scaler)) {
01047 shmctl(this->x_shminfo_scaler.shmid, IPC_RMID, 0);
01048 XFree(this->x_image_scaler);
01049 this->x_image_scaler = NULL;
01050 XUnlockDisplay(mmsfb->x_display);
01051 MMSFB_SetError(0, "XShmAttach() failed");
01052 return false;
01053 }
01054 shmctl(this->x_shminfo_scaler.shmid, IPC_RMID, 0);
01055
01056
01057 this->scaler = new MMSFBSurface(dest.w, dest.h, this->config.pixelformat,
01058 this->x_image_scaler, NULL, NULL);
01059 if (!this->scaler) {
01060 XUnlockDisplay(mmsfb->x_display);
01061 MMSFB_SetError(0, "cannot create scaler surface");
01062 return false;
01063 }
01064 this->scaler->layer=this;
01065
01066 this->scaler->setExtendedAcceleration(true);
01067 }
01068
01069 XFlush(mmsfb->x_display);
01070 XSync(mmsfb->x_display, False);
01071
01072 this->impl.x_display = mmsfb->x_display;
01073 this->impl.x_gc = this->x_gc;
01074 this->impl.x_window = this->x_window;
01075 this->impl.w = this->x_window_w;
01076 this->impl.h = this->x_window_h;
01077 this->impl.x_screen = mmsfb->x_screen;
01078 } else if(config.pixelformat == MMSFB_PF_YV12) {
01079 #ifdef __HAVE_XV__
01080
01081 unsigned int p_version,
01082 p_release,
01083 p_request_base,
01084 p_event_base,
01085 p_error_base;
01086
01087 if (XvQueryExtension(mmsfb->x_display, &p_version, &p_release, &p_request_base, &p_event_base, &p_error_base) != Success) {
01088 MMSFB_SetError(0, "XvQueryExtension() failed");
01089 fflush(stdout);
01090 return false;
01091 }
01092
01093 unsigned int num_adaptors;
01094 XvAdaptorInfo *ai;
01095 if (XvQueryAdaptors(mmsfb->x_display, DefaultRootWindow(mmsfb->x_display), &num_adaptors, &ai)) {
01096 MMSFB_SetError(0, "XvQueryAdaptors() failed");
01097 return false;
01098 }
01099 printf("DISKO: Available xv adaptors:\n");
01100 for(unsigned int cnt=0;cnt<num_adaptors;cnt++) {
01101
01102 if((mmsfb->xv_port == 0) &&
01103 (ai[cnt].type & XvImageMask) &&
01104 (XvGrabPort(mmsfb->x_display, ai[cnt].base_id, 0) == Success)) {
01105 mmsfb->xv_port = ai[cnt].base_id;
01106 printf(" %s (used)\n", ai[cnt].name);
01107 }
01108 else
01109 printf(" %s\n", ai[cnt].name);
01110 }
01111 XvFreeAdaptorInfo(ai);
01112
01113
01114
01115
01116 int image_width = this->config.w & ~0x7f;
01117 if (this->config.w & 0x7f)
01118 image_width += 0x80;
01119
01120
01121 int nFormats, xvPixFormat = (('2'<<24)|('1'<<16)|('V'<<8)|'Y');
01122 XvImageFormatValues *formats = XvListImageFormats(mmsfb->x_display, mmsfb->xv_port, &nFormats);
01123 if(formats) {
01124 for(int i = 0; i < nFormats; i++) {
01125 if(formats[i].type == XvYUV && formats[i].format == XvPlanar) {
01126 xvPixFormat = formats[i].id;
01127 break;
01128 }
01129 }
01130 XFree(formats);
01131 }
01132
01133
01134 this->xv_image1 = XvShmCreateImage(mmsfb->x_display, mmsfb->xv_port, xvPixFormat, 0, image_width, this->config.h, &this->xv_shminfo1);
01135 if(!this->xv_image1) {
01136 XUnlockDisplay(mmsfb->x_display);
01137 MMSFB_SetError(0, "XvShmCreateImage() failed");
01138 return false;
01139 }
01140 if(this->xv_image1->data_size == 0) {
01141 XFree(this->xv_image1);
01142 XUnlockDisplay(mmsfb->x_display);
01143 this->xv_image1 = NULL;
01144 MMSFB_SetError(0, "XvShmCreateImage() returned zero size");
01145 return false;
01146 }
01147
01148
01149 this->xv_shminfo1.shmid = shmget(IPC_PRIVATE, this->xv_image1->data_size, IPC_CREAT | 0777);
01150 if(this->xv_shminfo1.shmid < 0) {
01151 MMSFB_SetError(0, string("Error in shmget: ") + strerror(errno));
01152 XFree(this->xv_image1);
01153 XUnlockDisplay(mmsfb->x_display);
01154 this->xv_image1 = NULL;
01155 return false;
01156 }
01157
01158 this->xv_shminfo1.shmaddr = this->xv_image1->data = (char *)shmat(this->xv_shminfo1.shmid, 0, 0);
01159 if(!this->xv_shminfo1.shmaddr || (this->xv_shminfo1.shmaddr == (char*)-1)) {
01160 MMSFB_SetError(0, string("Error in shmat: ") + strerror(errno));
01161 XFree(this->xv_image1);
01162 XUnlockDisplay(mmsfb->x_display);
01163 this->xv_image1 = NULL;
01164 return false;
01165 }
01166
01167 this->xv_shminfo1.readOnly = False;
01168
01169
01170 if (!XShmAttach(mmsfb->x_display, &this->xv_shminfo1)) {
01171 XFree(this->xv_image1);
01172 XUnlockDisplay(mmsfb->x_display);
01173 this->xv_image1 = NULL;
01174 MMSFB_SetError(0, "XShmAttach() failed");
01175 return false;
01176 }
01177
01178
01179 XSync(mmsfb->x_display, False);
01180 shmctl(this->xv_shminfo1.shmid, IPC_RMID, 0);
01181
01182
01183 this->xv_image2 = XvShmCreateImage(mmsfb->x_display, mmsfb->xv_port, xvPixFormat, 0, image_width, this->config.h, &this->xv_shminfo2);
01184 if (!this->xv_image2) {
01185 XFree(this->xv_image1);
01186 XUnlockDisplay(mmsfb->x_display);
01187 this->xv_image1 = NULL;
01188 MMSFB_SetError(0, "XvShmCreateImage() failed");
01189 return false;
01190 }
01191 if(this->xv_image2->data_size == 0) {
01192 XFree(this->xv_image1);
01193 XFree(this->xv_image2);
01194 XUnlockDisplay(mmsfb->x_display);
01195 this->xv_image1 = NULL;
01196 this->xv_image2 = NULL;
01197 MMSFB_SetError(0, "XvShmCreateImage() returned zero size");
01198 return false;
01199 }
01200
01201
01202 this->xv_shminfo2.shmid = shmget(IPC_PRIVATE, this->xv_image2->data_size, IPC_CREAT | 0777);
01203 if(this->xv_shminfo2.shmid < 0) {
01204 MMSFB_SetError(0, string("Error in shmget: ") + strerror(errno));
01205 XFree(this->xv_image1);
01206 XFree(this->xv_image2);
01207 XUnlockDisplay(mmsfb->x_display);
01208 this->xv_image1 = NULL;
01209 this->xv_image2 = NULL;
01210 return false;
01211 }
01212
01213 this->xv_shminfo2.shmaddr = this->xv_image2->data = (char *)shmat(this->xv_shminfo2.shmid, 0, 0);
01214 if(!this->xv_shminfo2.shmaddr || (this->xv_shminfo2.shmaddr == (char*)-1)) {
01215 MMSFB_SetError(0, string("Error in shmat: ") + strerror(errno));
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 return false;
01222 }
01223
01224 this->xv_shminfo2.readOnly = False;
01225
01226
01227 if (!XShmAttach(mmsfb->x_display, &this->xv_shminfo2)) {
01228 XFree(this->xv_image1);
01229 XFree(this->xv_image2);
01230 XUnlockDisplay(mmsfb->x_display);
01231 this->xv_image1 = NULL;
01232 this->xv_image2 = NULL;
01233 MMSFB_SetError(0, "XShmAttach() failed");
01234 return false;
01235 }
01236
01237
01238 XSync(mmsfb->x_display, False);
01239 shmctl(this->xv_shminfo2.shmid, IPC_RMID, 0);
01240
01241 XSetWindowAttributes x_window_attr;
01242 unsigned long x_window_mask;
01243 this->x_visual = DefaultVisual(mmsfb->x_display,mmsfb->x_screen);
01244
01245
01246 x_window_attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |PointerMotionMask|EnterWindowMask|ResizeRedirectMask;
01247 x_window_attr.background_pixel = 0;
01248 x_window_attr.border_pixel = 0;
01249 if(mmsfb->fullscreen == MMSFB_FSM_TRUE) {
01250 x_window_mask = CWBackPixel | CWBorderPixel | CWEventMask ;
01251
01252 this->x_window = XCreateWindow(mmsfb->x_display, DefaultRootWindow(mmsfb->x_display), 0, 0, mmsfb->display_w, mmsfb->display_h, 0, CopyFromParent,
01253 InputOutput, this->x_visual, x_window_mask, &x_window_attr);
01254
01255 this->x_window_w = mmsfb->display_w;
01256 this->x_window_h = mmsfb->display_h;
01257 Atom the_atom = XInternAtom(mmsfb->x_display, "_NET_WM_WINDOW_TYPE_SPLASH", False);
01258 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);
01259
01260 XSetWMProtocols(mmsfb->x_display, this->x_window, &the_atom, 1);
01261 } else {
01262 x_window_mask = CWBackPixel | CWBorderPixel | CWEventMask ;
01263
01264 this->x_window_w = mmsfb->x11_win_rect.w;
01265 this->x_window_h = mmsfb->x11_win_rect.h;
01266 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,
01267 InputOutput, this->x_visual, x_window_mask, &x_window_attr);
01268
01269 }
01270
01271 this->x_gc = XCreateGC(mmsfb->x_display, this->x_window, 0, 0);
01272
01273 this->impl.x_display = mmsfb->x_display;
01274 this->impl.x_gc = this->x_gc;
01275 this->impl.x_window = this->x_window;
01276 this->impl.w = this->x_window_w;
01277 this->impl.h = this->x_window_h;
01278 this->impl.xv_image1 = this->xv_image1;
01279 this->impl.xv_image2 = this->xv_image2;
01280 this->impl.xv_port = mmsfb->xv_port;
01281 this->impl.x_screen = mmsfb->x_screen;
01282 #endif
01283 }
01284
01285
01286 if (this->config.outputtype == MMSFB_OT_OGL) {
01287 #ifdef __HAVE_OPENGL__
01288 #if defined(__HAVE_GLX__) || defined(__HAVE_EGL__)
01289 XUnlockDisplay(mmsfb->x_display);
01290 mmsfb->bei->init(mmsfb->x_display, mmsfb->x_screen, this->x_window, mmsfb->x11_win_rect);
01291 XLockDisplay(mmsfb->x_display);
01292 #endif
01293 #endif
01294 }
01295
01296 mmsfb->x_windows[this->config.id] = this->x_window;
01297
01298 if(this->config.id == 0) {
01299 mmsfb->input_window = this->x_window;
01300 XStoreName(mmsfb->x_display, this->x_window, mmsfb->applname.c_str());
01301 XSetIconName(mmsfb->x_display, this->x_window, mmsfb->appliconname.c_str());
01302 XClassHint clhi;
01303 clhi.res_name=(basename((char *)mmsfb->bin.c_str()));
01304
01305 clhi.res_class=(char*)"disko";
01306 XSetClassHint(mmsfb->x_display, this->x_window,&clhi);
01307 if(!mmsfb->hidden) {
01308 XMapWindow(mmsfb->x_display, this->x_window);
01309 XEvent x_event;
01310 do {
01311 XNextEvent(mmsfb->x_display, &x_event);
01312 }
01313 while (x_event.type != MapNotify || x_event.xmap.event != this->x_window);
01314
01315 XRaiseWindow(mmsfb->x_display, this->x_window);
01316 }
01317
01318 if (mmsfb->pointer != MMSFB_PM_EXTERNAL) {
01319 Pixmap bm_no;
01320 Colormap cmap;
01321 Cursor no_ptr;
01322 XColor black, dummy;
01323 static char bm_no_data[] = {0, 0, 0, 0, 0, 0, 0, 0};
01324
01325 cmap = DefaultColormap(mmsfb->x_display, DefaultScreen(mmsfb->x_display));
01326 XAllocNamedColor(mmsfb->x_display, cmap, "black", &black, &dummy);
01327 bm_no = XCreateBitmapFromData(mmsfb->x_display, this->x_window, bm_no_data, 8, 8);
01328 no_ptr = XCreatePixmapCursor(mmsfb->x_display, bm_no, bm_no, &black, &black, 0, 0);
01329
01330 XDefineCursor(mmsfb->x_display, this->x_window, no_ptr);
01331 XFreeCursor(mmsfb->x_display, no_ptr);
01332 if (bm_no != None)
01333 XFreePixmap(mmsfb->x_display, bm_no);
01334 XFreeColors(mmsfb->x_display, cmap, &black.pixel, 1, 0);
01335 }
01336 if(!mmsfb->hidden)
01337 XSetInputFocus(mmsfb->x_display, this->x_window,RevertToPointerRoot,CurrentTime);
01338 } else {
01339 if(!mmsfb->hidden) {
01340 XMapWindow(mmsfb->x_display, this->x_window);
01341 XEvent x_event;
01342 do {
01343 XNextEvent(mmsfb->x_display, &x_event);
01344 }
01345 while (x_event.type != MapNotify || x_event.xmap.event != this->x_window);
01346
01347 XRaiseWindow(mmsfb->x_display, this->x_window);
01348 }
01349 }
01350 XUnlockDisplay(mmsfb->x_display);
01351
01352 return true;
01353 #endif
01354 }
01355
01356 return false;
01357 }
01358
01359 bool MMSFBLayer::setOpacity(unsigned char opacity) {
01360
01361
01362 INITCHECK;
01363
01364 if (this->config.backend == MMSFB_BE_DFB) {
01365 #ifdef __HAVE_DIRECTFB__
01366 DFBResult dfbres;
01367
01368
01369 if (this->config.pixelformat == MMSFB_PF_AiRGB) {
01370 opacity = 255 - opacity;
01371 }
01372
01373
01374 if ((dfbres=this->dfblayer->SetOpacity(this->dfblayer, opacity)) != DFB_OK) {
01375 MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::SetOpacity(" + iToStr(opacity) + ") failed");
01376 return false;
01377 }
01378
01379 return true;
01380 #endif
01381 }
01382
01383 return false;
01384 }
01385
01386 bool MMSFBLayer::setLevel(int level) {
01387
01388
01389 INITCHECK;
01390
01391 if (this->config.backend == MMSFB_BE_DFB) {
01392 #ifdef __HAVE_DIRECTFB__
01393 DFBResult dfbres;
01394
01395
01396 if ((dfbres=this->dfblayer->SetLevel(this->dfblayer, level)) != DFB_OK) {
01397 MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::SetLevel(" + iToStr(level) + ") failed");
01398 return false;
01399 }
01400 return true;
01401 #endif
01402 } else if (this->config.backend == MMSFB_BE_X11) {
01403 #ifdef __HAVE_XLIB__
01404 XRaiseWindow(mmsfb->x_display, this->x_window);
01405
01406 #endif
01407 }
01408 return false;
01409 }
01410
01411 bool MMSFBLayer::getSurface(MMSFBSurface **surface, bool clear) {
01412
01413
01414 INITCHECK;
01415
01416 if (this->surface) {
01417
01418 *surface = this->surface;
01419 DEBUGMSG("MMSGUI", "have already a surface");
01420
01421 if (clear) {
01422
01423 this->surface->lock();
01424 this->surface->clear();
01425 this->surface->flip();
01426 this->surface->unlock();
01427 }
01428
01429 return true;
01430 }
01431
01432
01433 *surface = NULL;
01434
01435 if (this->config.backend == MMSFB_BE_DFB) {
01436 #ifdef __HAVE_DIRECTFB__
01437
01438 DFBResult dfbres;
01439 IDirectFBSurface *dfbsurface;
01440 DEBUGMSG("MMSGUI", "calling DFB->GetSurface()");
01441 if ((dfbres=this->dfblayer->GetSurface(this->dfblayer, &dfbsurface)) != DFB_OK) {
01442 MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::GetSurface() failed");
01443 return false;
01444 }
01445 DEBUGMSG("MMSGUI", "setting blitting flags");
01446 dfbsurface->SetBlittingFlags(dfbsurface, DSBLIT_NOFX);
01447
01448
01449 *surface = new MMSFBSurface(dfbsurface);
01450 if (!*surface) {
01451 dfbsurface->Release(dfbsurface);
01452 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface");
01453 return false;
01454 }
01455 #endif
01456 }
01457 else
01458 if (this->config.backend == MMSFB_BE_FBDEV) {
01459 #ifdef __HAVE_FBDEV__
01460 if (this->config.outputtype == MMSFB_OT_OGL) {
01461 #ifdef __HAVE_OPENGL__
01462
01463 *surface = new MMSFBSurface(this->config.w, this->config.h, MMSFBSurfaceAllocatedBy_ogl);
01464 if (!*surface) {
01465 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface for OPENGL");
01466 return false;
01467 }
01468 #endif
01469 }
01470 else
01471 if (this->config.buffermode == MMSFB_BM_FRONTONLY) {
01472
01473 *surface = this->mmsfbdev_surface;
01474 if (!*surface) {
01475 MMSFB_SetError(0, "layer surface is not initialized");
01476 return false;
01477 }
01478 }
01479 else
01480 if (this->config.buffermode == MMSFB_BM_BACKSYSTEM) {
01481
01482 *surface = new MMSFBSurface(this->config.w, this->config.h, this->config.pixelformat);
01483 if (!*surface) {
01484 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface");
01485 return false;
01486 }
01487
01488
01489 (*surface)->config.surface_buffer->mmsfbdev_surface = this->mmsfbdev_surface;
01490
01491
01492 (*surface)->setExtendedAcceleration(true);
01493 }
01494 else {
01495
01496 *surface = this->mmsfbdev_surface;
01497 if (!*surface) {
01498 MMSFB_SetError(0, "layer surface is not initialized");
01499 return false;
01500 }
01501
01502
01503
01504
01505 (*surface)->config.surface_buffer->mmsfbdev_surface = this->mmsfbdev_surface;
01506 }
01507 #endif
01508 }
01509 else
01510 if (this->config.backend == MMSFB_BE_KMS) {
01511 #ifdef __HAVE_KMS__
01512 if (this->config.outputtype == MMSFB_OT_OGL) {
01513 #ifdef __HAVE_OPENGL__
01514
01515 *surface = new MMSFBSurface(this->config.w, this->config.h, MMSFBSurfaceAllocatedBy_ogl);
01516 if (!*surface) {
01517 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface for OPENGL");
01518 return false;
01519 }
01520 #endif
01521 }
01522 else
01523 if (this->config.buffermode == MMSFB_BM_FRONTONLY) {
01524
01525 *surface = this->mmsfbdev_surface;
01526 if (!*surface) {
01527 MMSFB_SetError(0, "layer surface is not initialized");
01528 return false;
01529 }
01530 }
01531 else
01532 if (this->config.buffermode == MMSFB_BM_BACKSYSTEM) {
01533
01534 *surface = new MMSFBSurface(this->config.w, this->config.h, this->config.pixelformat);
01535 if (!*surface) {
01536 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface");
01537 return false;
01538 }
01539
01540
01541 (*surface)->config.surface_buffer->mmsfbdev_surface = this->mmsfbdev_surface;
01542
01543
01544 (*surface)->setExtendedAcceleration(true);
01545 }
01546 else {
01547
01548 *surface = this->mmsfbdev_surface;
01549 if (!*surface) {
01550 MMSFB_SetError(0, "layer surface is not initialized");
01551 return false;
01552 }
01553
01554
01555
01556
01557 (*surface)->config.surface_buffer->mmsfbdev_surface = this->mmsfbdev_surface;
01558 }
01559 #endif
01560 }
01561 else
01562 if (this->config.backend == MMSFB_BE_X11) {
01563 #ifdef __HAVE_XLIB__
01564 if (this->config.outputtype == MMSFB_OT_OGL) {
01565 #ifdef __HAVE_OPENGL__
01566
01567 *surface = new MMSFBSurface(this->config.w, this->config.h, MMSFBSurfaceAllocatedBy_ogl);
01568 if (!*surface) {
01569 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface for OPENGL");
01570 return false;
01571 }
01572 #endif
01573 }
01574 else
01575 if (isRGBPixelFormat(this->config.pixelformat)) {
01576
01577 if ((!this->x_image1)||(!this->x_image2)) {
01578 MMSFB_SetError(0, "x_image not available, cannot get surface");
01579 return false;
01580 }
01581
01582
01583 *surface = new MMSFBSurface(this->config.w, this->config.h, this->config.pixelformat,
01584 this->x_image1, this->x_image2, this->scaler);
01585 if (!*surface) {
01586 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface");
01587 return false;
01588 }
01589
01590
01591 (*surface)->setExtendedAcceleration(true);
01592 (*surface)->layer=this;
01593 }
01594 else {
01595 #ifdef __HAVE_XV__
01596
01597
01598 if ((!this->xv_image1)||(!this->xv_image2)) {
01599 MMSFB_SetError(0, "xv_image not available, cannot get surface");
01600 return false;
01601 }
01602
01603
01604 *surface = new MMSFBSurface(this->config.w, this->config.h, this->config.pixelformat,
01605 this->xv_image1, this->xv_image2);
01606 if (!*surface) {
01607 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface");
01608 return false;
01609 }
01610
01611
01612 (*surface)->setExtendedAcceleration(true);
01613 (*surface)->layer=this;
01614 #endif
01615 }
01616 #endif
01617 }
01618
01619
01620 this->surface = *surface;
01621
01622 if (this->surface) {
01623 this->surface->lock();
01624
01625 this->surface->setLayerSurface();
01626
01627 if (clear) {
01628
01629 this->surface->clear();
01630 this->surface->flip();
01631 }
01632
01633
01634 this->surface->setFlipFlags(this->flipflags);
01635
01636 this->surface->unlock();
01637
01638 return true;
01639 }
01640
01641 return false;
01642 }
01643
01644 bool MMSFBLayer::setFlipFlags(MMSFBFlipFlags flags) {
01645 this->flipflags = flags;
01646
01647
01648 if (this->surface) {
01649 this->surface->lock();
01650 this->surface->setFlipFlags(this->flipflags);
01651 this->surface->unlock();
01652 }
01653
01654 return true;
01655 }
01656
01657 bool MMSFBLayer::releaseLayer() {
01658
01659
01660 INITCHECK;
01661
01662 if (this->config.backend == MMSFB_BE_FBDEV) {
01663 #ifdef __HAVE_FBDEV__
01664 if (mmsfb->mmsfbdev) {
01665 return mmsfb->mmsfbdev->releaseLayer(this->config.id);
01666 }
01667 #endif
01668 } else if (this->config.backend == MMSFB_BE_KMS) {
01669 #ifdef __HAVE_KMS__
01670 if (mmsfb->mmskms) {
01671 return mmsfb->mmskms->releaseLayer(this->config.id);
01672 }
01673 #endif
01674 }
01675
01676 return false;
01677 }
01678
01679 bool MMSFBLayer::restoreLayer() {
01680
01681
01682 INITCHECK;
01683
01684 if (this->config.backend == MMSFB_BE_FBDEV) {
01685 #ifdef __HAVE_FBDEV__
01686 if (mmsfb->mmsfbdev) {
01687 return mmsfb->mmsfbdev->restoreLayer(this->config.id);
01688 }
01689 #endif
01690 } else if (this->config.backend == MMSFB_BE_KMS) {
01691 #ifdef __HAVE_KMS__
01692 if (mmsfb->mmskms) {
01693 return mmsfb->mmskms->restoreLayer(this->config.id);
01694 }
01695 #endif
01696 }
01697
01698 return false;
01699 }
01700
01701 bool MMSFBLayer::createSurface(MMSFBSurface **surface, int w, int h,
01702 MMSFBSurfacePixelFormat pixelformat, int backbuffer) {
01703
01704
01705 INITCHECK;
01706
01707 if (pixelformat == MMSFB_PF_NONE) {
01708 pixelformat = this->config.surface_pixelformat;
01709
01710 if (this->config.outputtype == MMSFB_OT_OGL) {
01711 pixelformat = MMSFB_PF_ABGR;
01712 }
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735 }
01736
01737 if (firsttime_createsurface) {
01738 printf("DISKO: Pixelformat %s is used for surfaces.\n", getMMSFBPixelFormatString(pixelformat).c_str());
01739 firsttime_createsurface = false;
01740 }
01741 if (mmsfb->createSurface(surface, w, h, pixelformat, backbuffer, (this->config.buffermode == MMSFB_BM_BACKSYSTEM))) {
01742 (*surface)->layer = this;
01743 return true;
01744 } else {
01745 return false;
01746 }
01747 }
01748
01749 bool MMSFBLayer::createWindow(MMSFBWindow **window, int x, int y, int w, int h,
01750 MMSFBSurfacePixelFormat pixelformat, bool usealpha, int backbuffer) {
01751
01752
01753 INITCHECK;
01754
01755
01756 MMSFBLayer *layer;
01757 mmsfbwindowmanager->getLayer(&layer);
01758 if (layer != this) {
01759 MMSFB_SetError(0, "not the right layer, cannot create MMSFBWindow");
01760 return false;
01761 }
01762
01763 if (pixelformat == MMSFB_PF_NONE) {
01764 if (usealpha) {
01765
01766 pixelformat = this->config.window_pixelformat;
01767 }
01768 else {
01769
01770 pixelformat = this->config.pixelformat;
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780 }
01781
01782 if (this->config.outputtype == MMSFB_OT_OGL) {
01783 pixelformat = MMSFB_PF_ABGR;
01784 }
01785
01786 }
01787
01788
01789 if (usealpha) {
01790 if (firsttime_createwindow_usealpha) {
01791 printf("DISKO: Pixelformat %s is used for windows with alphachannel.\n", getMMSFBPixelFormatString(pixelformat).c_str());
01792 firsttime_createwindow_usealpha = false;
01793 }
01794 }
01795 else
01796 if (firsttime_createwindow_noalpha) {
01797 printf("DISKO: Pixelformat %s is used for windows with no alphachannel.\n", getMMSFBPixelFormatString(pixelformat).c_str());
01798 firsttime_createwindow_noalpha = false;
01799 }
01800
01801
01802 #ifdef USE_DFB_WINMAN
01803
01804 DFBResult dfbres;
01805 IDirectFBWindow *dfbwindow;
01806 DFBWindowDescription window_desc;
01807
01808
01809 window_desc.flags = (DFBWindowDescriptionFlags)(DWDESC_POSX | DWDESC_POSY | DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_PIXELFORMAT | DWDESC_CAPS);
01810 window_desc.posx = x;
01811 window_desc.posy = y;
01812 window_desc.width = w;
01813 window_desc.height = h;
01814 window_desc.pixelformat = getDFBPixelFormatFromString(pixelformat);
01815
01816
01817 if (!isAlphaPixelFormat(pixelformat)) {
01818 if (backbuffer)
01819 window_desc.caps = (DFBWindowCapabilities)(DWCAPS_DOUBLEBUFFER);
01820 else
01821 window_desc.caps = (DFBWindowCapabilities)0;
01822 }
01823 else {
01824 if (backbuffer)
01825 window_desc.caps = (DFBWindowCapabilities)(DWCAPS_DOUBLEBUFFER | DWCAPS_ALPHACHANNEL);
01826 else
01827 window_desc.caps = (DFBWindowCapabilities)(DWCAPS_ALPHACHANNEL);
01828 }
01829
01830
01831 if ((dfbres=this->dfblayer->CreateWindow(this->dfblayer, &window_desc, &dfbwindow)) != DFB_OK) {
01832 MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::CreateWindow(" + iToStr(w) + "x" + iToStr(h) + "," + getDFBPixelFormatString(window_desc.pixelformat) + ") failed");
01833 return false;
01834 }
01835
01836
01837 *window = new MMSFBWindow(dfbwindow, window_desc.posx, window_desc.posy);
01838 if (!*window) {
01839 dfbwindow->Release(dfbwindow);
01840 MMSFB_SetError(0, "cannot create new instance of MMSFBWindow");
01841 return false;
01842 }
01843
01844 #endif
01845
01846 #ifdef USE_MMSFB_WINMAN
01847
01848
01849 MMSFBSurface *surface;
01850 if (!mmsfb->createSurface(&surface, w, h, pixelformat, backbuffer, (this->config.buffermode == MMSFB_BM_BACKSYSTEM)))
01851 return false;
01852 surface->layer=this;
01853
01854 *window = new MMSFBWindow(surface, x, y);
01855 if (!*window) {
01856 delete surface;
01857 MMSFB_SetError(0, "cannot create new instance of MMSFBWindow");
01858 return false;
01859 }
01860
01861
01862 surface->setWinSurface();
01863
01864
01865 mmsfbwindowmanager->addWindow(*window);
01866
01867 #endif
01868
01869 return true;
01870 }
01871
01872 void *MMSFBLayer::getImplementation() {
01873 #ifdef __HAVE_XLIB__
01874 return &(this->impl);
01875 #else
01876 return NULL;
01877 #endif
01878 }
01879
01880
01881