Logo
  • Main Page
  • Related Pages
  • Modules
  • Classes
  • Files

mmsfb.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005-2007 Stefan Schwarzer, Jens Schneider,             *
00003  *                           Matthias Hardt, Guido Madaus                  *
00004  *                                                                         *
00005  *   Copyright (C) 2007-2008 BerLinux Solutions GbR                        *
00006  *                           Stefan Schwarzer & Guido Madaus               *
00007  *                                                                         *
00008  *   Copyright (C) 2009-2013 BerLinux Solutions GmbH                       *
00009  *                                                                         *
00010  *   Authors:                                                              *
00011  *      Stefan Schwarzer   <stefan.schwarzer@diskohq.org>,                 *
00012  *      Matthias Hardt     <matthias.hardt@diskohq.org>,                   *
00013  *      Jens Schneider     <jens.schneider@diskohq.org>,                   *
00014  *      Guido Madaus       <guido.madaus@diskohq.org>,                     *
00015  *      Patrick Helterhoff <patrick.helterhoff@diskohq.org>,               *
00016  *      René Bählkow       <rene.baehlkow@diskohq.org>                     *
00017  *                                                                         *
00018  *   This library is free software; you can redistribute it and/or         *
00019  *   modify it under the terms of the GNU Lesser General Public            *
00020  *   License version 2.1 as published by the Free Software Foundation.     *
00021  *                                                                         *
00022  *   This library is distributed in the hope that it will be useful,       *
00023  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00024  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00025  *   Lesser General Public License for more details.                       *
00026  *                                                                         *
00027  *   You should have received a copy of the GNU Lesser General Public      *
00028  *   License along with this library; if not, write to the                 *
00029  *   Free Software Foundation, Inc.,                                       *
00030  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
00031  **************************************************************************/
00032 
00033 #include <sys/types.h>
00034 #include <linux/fb.h>
00035 #include "mmsgui/fb/mmsfb.h"
00036 #include "mmsgui/fb/mmsfbsurfacemanager.h"
00037 #include <string.h>
00038 #include <stdlib.h>
00039 
00040 //#define DEBUG_LOCK_OUTPUT
00041 #ifdef DEBUG_LOCK_OUTPUT
00042 #include <sys/syscall.h>
00043 #define PRINT_LOCK(msg...) printf("%s (%lu)\n", ((string)(msg)).c_str(), (pid_t) syscall (SYS_gettid))
00044 #else
00045 #define PRINT_LOCK(msg...)
00046 #endif
00047 
00048 /* initialize the mmsfb object */
00049 MMSFB *mmsfb = new MMSFB();
00050 
00051 
00052 #define INITCHECK  if(!this->initialized){MMSFB_SetError(0,"not initialized");return false;}
00053 
00054 void MMSFB_AtExit() {
00055     if (mmsfb)
00056         mmsfb->release();
00057 }
00058 
00059 MMSFB::MMSFB() {
00060     this->argc = 0;
00061     this->argv = NULL;
00062     this->initialized = false;
00063 #ifdef  __HAVE_DIRECTFB__
00064     this->dfb = NULL;
00065 #endif
00066 #ifdef  __HAVE_FBDEV__
00067     this->mmsfbdev = NULL;
00068 #endif
00069 #ifdef  __HAVE_KMS__
00070     this->mmskms = NULL;
00071 #endif
00072 
00073 #ifdef __HAVE_XLIB__
00074     this->x_display = NULL;
00075 #endif
00076 #ifdef __HAVE_XV__
00077     this->xv_port = 0;
00078 #endif
00079 #ifdef __HAVE_OPENGL__
00080     this->bei = NULL;
00081 #endif
00082 
00083     // set the atexit routine
00084     atexit(MMSFB_AtExit);
00085 }
00086 
00087 MMSFB::~MMSFB() {
00088 #ifdef __HAVE_XV__
00089     if(this->x_display && this->xv_port) {
00090         XvUngrabPort(this->x_display, this->xv_port, CurrentTime);
00091     }
00092 #endif
00093 }
00094 
00095 
00096 bool MMSFB::init(int argc, char **argv, MMSFBBackend backend, MMSFBRectangle x11_win_rect,
00097                  bool extendedaccel, MMSFBFullScreenMode fullscreen, MMSFBPointerMode pointer,
00098                  string appl_name, string appl_icon_name, bool hidden) {
00099 
00100     // check if already initialized
00101     if (this->initialized) {
00102         MMSFB_SetError(0, "already initialized");
00103         return false;
00104     }
00105 
00106     // save arguments
00107     this->argc = argc;
00108     this->argv = argv;
00109     this->bin = ((argc && argv) ? argv[0] : "");
00110     this->appliconname = appl_icon_name;
00111     this->applname = appl_name;
00112     this->fullscreen = fullscreen;
00113 
00114     // init layer pointers
00115     memset(this->layer, 0, sizeof(MMSFBLayer *) * MMSFBLAYER_MAXNUM);
00116 
00117 #ifdef __HAVE_XLIB__
00118     memset(this->x_windows, 0, sizeof(Window) * MMSFBLAYER_MAXNUM);
00119     // basic information mainly needed by X11 initialization
00120     this->x11_win_rect = x11_win_rect;
00121 #endif
00122 
00123     // which backend should i use?
00124     this->backend = backend;
00125     if (this->backend == MMSFB_BE_DFB) {
00126 #ifdef __HAVE_DIRECTFB__
00127 #else
00128         MMSFB_SetError(0, "compile DFB support!");
00129         return false;
00130 #endif
00131     }
00132     else
00133     if (this->backend == MMSFB_BE_X11) {
00134 #ifdef __HAVE_XLIB__
00135         XInitThreads();
00136         this->resized=false;
00137 #else
00138         MMSFB_SetError(0, "compile X11 support!");
00139         return false;
00140 #endif
00141     }
00142     else
00143     if (this->backend == MMSFB_BE_FBDEV) {
00144 #ifdef __HAVE_FBDEV__
00145 #else
00146         MMSFB_SetError(0, "compile FBDEV support!");
00147         return false;
00148 #endif
00149     }
00150     else
00151     if (this->backend == MMSFB_BE_KMS) {
00152 #ifdef __HAVE_KMS__
00153 #else
00154         MMSFB_SetError(0, "compile KMS support!");
00155         return false;
00156 #endif
00157     }
00158     else {
00159         MMSFB_SetError(0, "wrong backend " + getMMSFBBackendString(backend));
00160         return false;
00161     }
00162 
00163 
00164     if (this->backend == MMSFB_BE_DFB) {
00165 #ifdef __HAVE_DIRECTFB__
00166         DFBResult dfbres;
00167 
00168         // init dfb
00169         DirectFBInit(&this->argc,&this->argv);
00170 
00171         // get interface to dfb
00172         if ((dfbres = DirectFBCreate(&this->dfb)) != DFB_OK) {
00173             MMSFB_SetError(dfbres, "DirectFBCreate() failed");
00174             return false;
00175         }
00176 #endif
00177     }
00178     else
00179     if (this->backend == MMSFB_BE_X11) {
00180 #ifdef __HAVE_XLIB__
00181         if (!(this->x_display = XOpenDisplay((char*)0))) {
00182             MMSFB_SetError(0, "XOpenDisplay() failed");
00183             return false;
00184         }
00185 
00186         this->x_screen = DefaultScreen(this->x_display);
00187 
00188         Window myroot=RootWindow(this->x_display, this->x_screen);
00189         Window root_ret;
00190         int myx,myy;
00191         unsigned int borderw, depthret;
00192         XGetGeometry(this->x_display, myroot, &root_ret, &myx, &myy, (unsigned int *)&(this->display_w), (unsigned int *)&(this->display_h), &borderw, &depthret);
00193 
00194         printf("w: %d, h: %d\n", this->display_w, this->display_h);
00195 
00196         x_depth=DefaultDepth(this->x_display, this->x_screen);
00197         rootimage =  XGetImage(mmsfb->x_display, myroot, 0, 0,
00198                       mmsfb->display_w,mmsfb->display_h, -1, ZPixmap);
00199         x_depth=DefaultDepth(this->x_display, this->x_screen);
00200 
00201         this->hidden = hidden;
00202         this->pointer = pointer;
00203 #endif
00204     }
00205 
00206     this->initialized = true;
00207     return true;
00208 }
00209 
00210 bool MMSFB::release() {
00211 #ifdef __HAVE_OPENGL__
00212     // stop backend interface server
00213     if (this->bei) {
00214         delete this->bei;
00215         this->bei = NULL;
00216     }
00217 #endif
00218 
00219     if (this->backend == MMSFB_BE_DFB) {
00220 #ifdef  __HAVE_DIRECTFB__
00221         if (this->dfb)
00222             this->dfb->Release(this->dfb);
00223 #endif
00224     }
00225     else
00226     if (this->backend == MMSFB_BE_FBDEV) {
00227 #ifdef __HAVE_FBDEV__
00228         if (this->mmsfbdev) {
00229             delete this->mmsfbdev;
00230             this->mmsfbdev = NULL;
00231         }
00232 #endif
00233     }
00234     else
00235     if (this->backend == MMSFB_BE_KMS) {
00236 #ifdef __HAVE_KMS__
00237         if (this->mmskms) {
00238             delete this->mmskms;
00239             this->mmskms = NULL;
00240         }
00241 #endif
00242     }
00243     else {
00244 #ifdef __HAVE_XLIB__
00245 #endif
00246     }
00247 
00248     this->initialized = false;
00249     return true;
00250 }
00251 
00252 bool MMSFB::isInitialized() {
00253     return this->initialized;
00254 }
00255 
00256 MMSFBBackend MMSFB::getBackend() {
00257     return this->backend;
00258 }
00259 
00260 bool MMSFB::lock() {
00261     PRINT_LOCK("mmsfb::lock");
00262     this->Lock.lock();
00263     return true;
00264 }
00265 
00266 bool MMSFB::unlock() {
00267     PRINT_LOCK("mmsfb::unlock");
00268 
00269     if(this->Lock.unlock() == 0)
00270         return true;
00271     else
00272         return false;
00273 }
00274 
00275 bool MMSFB::getLayer(int id, MMSFBLayer **layer, MMSFBOutputType outputtype, bool virtual_console) {
00276 
00277     // check if initialized
00278     INITCHECK;
00279 
00280     if (this->layer[id]) {
00281         // i have already the layer
00282         *layer = this->layer[id];
00283         return true;
00284     }
00285 
00286 
00287     // check the backend / outputtype combination
00288     if (this->backend == MMSFB_BE_X11) {
00289         if (outputtype == MMSFB_OT_XVSHM) {
00290 #ifdef __HAVE_XV__
00291 #else
00292             MMSFB_SetError(0, "compile X11/XV support!");
00293             return false;
00294 #endif
00295         }
00296         else
00297         if (outputtype == MMSFB_OT_OGL) {
00298 #ifdef __HAVE_OPENGL__
00299 #else
00300             MMSFB_SetError(0, "compile OPENGL support!");
00301             return false;
00302 #endif
00303 #ifdef __HAVE_GLX__
00304 #else
00305 #ifdef __HAVE_EGL__
00306 #else
00307             MMSFB_SetError(0, "compile GLX or EGL support!");
00308             return false;
00309 #endif
00310 #endif
00311         }
00312     }
00313     else
00314     if ((this->backend == MMSFB_BE_FBDEV) || (this->backend == MMSFB_BE_KMS)) {
00315         if (outputtype == MMSFB_OT_OGL) {
00316 #ifdef __HAVE_OPENGL__
00317 #else
00318             MMSFB_SetError(0, "compile OPENGL support!");
00319             return false;
00320 #endif
00321 #ifdef __HAVE_EGL__
00322 #else
00323             MMSFB_SetError(0, "compile EGL support!");
00324             return false;
00325 #endif
00326         }
00327     }
00328 
00329 
00330     if (this->backend == MMSFB_BE_FBDEV) {
00331 #ifdef __HAVE_FBDEV__
00332         if (!this->mmsfbdev) {
00333             if (outputtype == MMSFB_OT_MATROXFB) {
00334                 // matroxfb
00335                 this->mmsfbdev = new MMSFBDevMatrox();
00336             }
00337             else
00338             if (outputtype == MMSFB_OT_DAVINCIFB) {
00339                 // davincifb
00340                 this->mmsfbdev = new MMSFBDevDavinci();
00341             }
00342             else
00343             if (outputtype == MMSFB_OT_OMAPFB) {
00344                 // omapfb
00345                 DEBUGMSG("MMSGUI", "create new MMSFBDevOmap()");
00346                 this->mmsfbdev = new MMSFBDevOmap();
00347                 DEBUGMSG("MMSGUI", "created new MMSFBDevOmap()");
00348             }
00349             else {
00350                 // default fbdev
00351                 DEBUGMSG("MMSGUI", "create generic fbdev");
00352                 this->mmsfbdev = new MMSFBDev();
00353             }
00354 
00355             if (this->mmsfbdev) {
00356                 if (!this->mmsfbdev->openDevice(NULL, (virtual_console) ? MMSFBDEV_QUERY_CONSOLE : MMSFBDEV_NO_CONSOLE)) {
00357                     MMSFB_SetError(0, "MMSFBDEV device cannot be opened");
00358                     return false;
00359                 }
00360             }
00361         }
00362 #endif
00363     }
00364 
00365     if (this->backend == MMSFB_BE_KMS) {
00366     #ifdef __HAVE_KMS__
00367             if (!this->mmskms) {
00368                 // default kms
00369                 DEBUGMSG("MMSGUI", "create generic kms");
00370                 this->mmskms = new MMSKms();
00371 
00372                 if (this->mmskms) {
00373                     if (!this->mmskms->openDevice(outputtype)) {
00374                         MMSFB_SetError(0, "MMSKms device cannot be opened");
00375                         return false;
00376                     }
00377                 }
00378             }
00379     #endif
00380         }
00381 
00382 
00383 
00384     if (outputtype == MMSFB_OT_OGL) {
00385 #ifdef __HAVE_OPENGL__
00386         if (!this->bei) {
00387             // start backend interface server
00388             this->bei = new MMSFBBackEndInterface();
00389         }
00390 #endif
00391     }
00392 
00393 
00394 
00395 
00396     // create a new layer instance
00397     *layer = new MMSFBLayer(id, this->backend, outputtype);
00398     if (!*layer) {
00399         MMSFB_SetError(0, "cannot create new instance of MMSFBLayer");
00400         return false;
00401     }
00402     if (!(*layer)->isInitialized()) {
00403         delete *layer;
00404         *layer = NULL;
00405         MMSFB_SetError(0, "cannot initialize MMSFBLayer");
00406         return false;
00407     }
00408 
00409     // save this for the next call
00410     this->layer[id] = *layer;
00411 
00412     return true;
00413 }
00414 
00415 
00416 bool MMSFB::getLayer(int id, MMSFBLayer **layer) {
00417 
00418     // check if initialized
00419     INITCHECK;
00420 
00421     if (this->layer[id]) {
00422         // i have already the layer
00423         *layer = this->layer[id];
00424         return true;
00425     }
00426 
00427     // layer is not initialized!!!
00428     return false;
00429 }
00430 
00431 
00432 void *MMSFB::getX11Window() {
00433     if (this->backend == MMSFB_BE_DFB) {
00434 #ifdef  __HAVE_DIRECTFB__
00435 #endif
00436     }
00437     else
00438     if (this->backend == MMSFB_BE_FBDEV) {
00439 #ifdef  __HAVE_FBDEV__
00440 #endif
00441     }
00442     else
00443     if (this->backend == MMSFB_BE_KMS) {
00444 #ifdef  __HAVE_KMS__
00445 #endif
00446     }
00447     else {
00448 #ifdef __HAVE_XLIB__
00449 
00450         return &this->input_window;
00451         //return &this->x_window;
00452 #endif
00453     }
00454     return NULL;
00455 }
00456 void *MMSFB::getX11Display() {
00457     if (this->backend == MMSFB_BE_DFB) {
00458 #ifdef  __HAVE_DIRECTFB__
00459 #endif
00460     }
00461     else
00462     if (this->backend == MMSFB_BE_FBDEV) {
00463 #ifdef  __HAVE_FBDEV__
00464 #endif
00465     }
00466     else
00467     if (this->backend == MMSFB_BE_KMS) {
00468 #ifdef  __HAVE_KMS__
00469 #endif
00470     }
00471     else {
00472 #ifdef __HAVE_XLIB__
00473         return this->x_display;
00474 #endif
00475     }
00476     return NULL;
00477 }
00478 
00479 bool MMSFB::refresh() {
00480     // check if initialized
00481     INITCHECK;
00482 
00483     if (this->backend == MMSFB_BE_DFB) {
00484 #ifdef  __HAVE_DIRECTFB__
00485 #endif
00486     }
00487     else
00488     if (this->backend == MMSFB_BE_FBDEV) {
00489 #ifdef  __HAVE_FBDEV__
00490 #endif
00491     }
00492     else
00493     if (this->backend == MMSFB_BE_KMS) {
00494 #ifdef  __HAVE_KMS__
00495 #endif
00496     }
00497     else {
00498 #ifdef __HAVE_XLIB__
00499         MMSFBSurface *suf;
00500         if (this->layer[0]->getSurface(&suf))
00501             suf->refresh();
00502 #endif
00503     }
00504 
00505     return true;
00506 }
00507 
00508 bool MMSFB::createSurface(MMSFBSurface **surface, int w, int h, MMSFBSurfacePixelFormat pixelformat, int backbuffer, bool systemonly) {
00509     /* check if initialized */
00510     INITCHECK;
00511 
00512     /* create or reuse a surface */
00513     *surface = mmsfbsurfacemanager->createSurface(w, h, pixelformat, backbuffer, systemonly);
00514 
00515     if (*surface)
00516         return true;
00517     else
00518         return false;
00519 }
00520 
00521 #ifdef  __HAVE_DIRECTFB__
00522 bool MMSFB::createImageProvider(IDirectFBImageProvider **provider, string filename) {
00523     *provider = NULL;
00524     if (this->backend == MMSFB_BE_DFB) {
00525 #ifdef  __HAVE_DIRECTFB__
00526         DFBResult   dfbres;
00527 
00528         /* check if initialized */
00529         INITCHECK;
00530 
00531         /* create the provider */
00532         if ((dfbres=this->dfb->CreateImageProvider(this->dfb, filename.c_str(), provider)) != DFB_OK) {
00533             MMSFB_SetError(dfbres, "IDirectFB::CreateImageProvider(" + filename + ") failed");
00534             return false;
00535         }
00536 
00537         return true;
00538 #endif
00539     }
00540     if (this->backend == MMSFB_BE_FBDEV) {
00541 #ifdef __HAVE_FBDEV__
00542 #endif
00543     }
00544     else {
00545 #ifdef __HAVE_XLIB__
00546 #endif
00547     }
00548     return false;
00549 }
00550 #endif
00551 
00552 bool MMSFB::createFont(MMSFBFont **font, string filename, int width, int height) {
00553     // check if initialized
00554     INITCHECK;
00555 
00556     // create new instance of MMSFBFont
00557     *font = new MMSFBFont(filename, width, height);
00558     if (!*font) {
00559         MMSFB_SetError(0, "cannot create new MMSFBFont instance for " + filename);
00560         return false;
00561     }
00562     if (!(*font)->isInitialized()) {
00563         delete *font;
00564         *font = NULL;
00565         MMSFB_SetError(0, "cannot initialize new MMSFBFont instance for " + filename);
00566         return false;
00567     }
00568     return true;
00569 }
00570 
00571 #ifdef __HAVE_XLIB__
00572 bool MMSFB::resizeWindow() {
00573     printf("resize w,h: %d,%d\n", this->target_window_w, this->target_window_h );
00574     XWindowChanges chg;
00575     chg.width=this->target_window_w;
00576     chg.height=this->target_window_h;
00577     printf("rc %d\n",XConfigureWindow(this->x_display, this->x_window,CWWidth|CWHeight, &chg));
00578     //XMoveResizeWindow(this->x_display, this->x_window, this->target_window_w, this->target_window_h);
00579     return true;
00580 }
00581 #endif
00582 
00583 void MMSFB::realignLayer() {
00584 #ifdef __HAVE_XLIB__
00585     static bool first = true;
00586 
00587     if(first==false)
00588         return;
00589 
00590     first=false;
00591     for(int i=0; ;i++) {
00592         if(mmsfb->x_windows[i]==0)
00593             break;
00594         else if(mmsfb->x_windows[i]!=mmsfb->input_window) {
00595             XLockDisplay(mmsfb->x_display);
00596             XLowerWindow(mmsfb->x_display, mmsfb->x_windows[i]);
00597             XFlush(mmsfb->x_display);
00598             XSync(mmsfb->x_display,False);
00599             X11_IMPL *impl = (X11_IMPL *)mmsfb->layer[i]->getImplementation();
00600 
00601             XPutImage(mmsfb->x_display, mmsfb->x_windows[i], impl->x_gc, mmsfb->rootimage, 0,0, 0, 0, mmsfb->display_w,
00602                       mmsfb->display_h);
00603 
00604             //XUnmapWindow(mmsfb->x_display, mmsfb->x_windows[i]);
00605             //printf("unmapping layer %d\n", i);
00606             XSync(mmsfb->x_display,False);
00607 
00608             XMapWindow(mmsfb->x_display, mmsfb->x_windows[i]);
00609             XRaiseWindow(mmsfb->x_display, mmsfb->input_window);
00610 
00611             //printf("mapping layer %d\n", i);
00612             XFlush(mmsfb->x_display);
00613             XSync(mmsfb->x_display,False);
00614             XUnlockDisplay(mmsfb->x_display);
00615         }
00616     }
00617 #endif
00618 }
00619 
00620 #ifdef  __HAVE_KMS__
00621 MMSKms *MMSFB::getKmsInterface() {
00622     return this->mmskms;
00623 }
00624 #endif

Generated by doxygen