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-2012 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_XLIB__
00070     this->x_display = NULL;
00071 #endif
00072 #ifdef __HAVE_XV__
00073     this->xv_port = 0;
00074 #endif
00075 #ifdef __HAVE_OPENGL__
00076     this->bei = NULL;
00077 #endif
00078 
00079     // set the atexit routine
00080     atexit(MMSFB_AtExit);
00081 }
00082 
00083 MMSFB::~MMSFB() {
00084 #ifdef __HAVE_XV__
00085     if(this->x_display && this->xv_port) {
00086         XvUngrabPort(this->x_display, this->xv_port, CurrentTime);
00087     }
00088 #endif
00089 }
00090 
00091 
00092 bool MMSFB::init(int argc, char **argv, MMSFBBackend backend, MMSFBRectangle x11_win_rect,
00093                  bool extendedaccel, MMSFBFullScreenMode fullscreen, MMSFBPointerMode pointer,
00094                  string appl_name, string appl_icon_name, bool hidden) {
00095 
00096     // check if already initialized
00097     if (this->initialized) {
00098         MMSFB_SetError(0, "already initialized");
00099         return false;
00100     }
00101 
00102     // save arguments
00103     this->argc = argc;
00104     this->argv = argv;
00105     this->bin = ((argc && argv) ? argv[0] : "");
00106     this->appliconname = appl_icon_name;
00107     this->applname = appl_name;
00108     this->fullscreen = fullscreen;
00109 
00110     // init layer pointers
00111     memset(this->layer, 0, sizeof(MMSFBLayer *) * MMSFBLAYER_MAXNUM);
00112 
00113 #ifdef __HAVE_XLIB__
00114     memset(this->x_windows, 0, sizeof(Window) * MMSFBLAYER_MAXNUM);
00115     // basic information mainly needed by X11 initialization
00116     this->x11_win_rect = x11_win_rect;
00117 #endif
00118 
00119     // which backend should i use?
00120     this->backend = backend;
00121     if (this->backend == MMSFB_BE_DFB) {
00122 #ifdef __HAVE_DIRECTFB__
00123 #else
00124         MMSFB_SetError(0, "compile DFB support!");
00125         return false;
00126 #endif
00127     }
00128     else
00129     if (this->backend == MMSFB_BE_X11) {
00130 #ifdef __HAVE_XLIB__
00131         XInitThreads();
00132         this->resized=false;
00133 #else
00134         MMSFB_SetError(0, "compile X11 support!");
00135         return false;
00136 #endif
00137     }
00138     else
00139     if (this->backend == MMSFB_BE_FBDEV) {
00140 #ifdef __HAVE_FBDEV__
00141 #else
00142         MMSFB_SetError(0, "compile FBDEV support!");
00143         return false;
00144 #endif
00145     }
00146     else {
00147         MMSFB_SetError(0, "wrong backend " + getMMSFBBackendString(backend));
00148         return false;
00149     }
00150 
00151 
00152     if (this->backend == MMSFB_BE_DFB) {
00153 #ifdef __HAVE_DIRECTFB__
00154         DFBResult dfbres;
00155 
00156         // init dfb
00157         DirectFBInit(&this->argc,&this->argv);
00158 
00159         // get interface to dfb
00160         if ((dfbres = DirectFBCreate(&this->dfb)) != DFB_OK) {
00161             MMSFB_SetError(dfbres, "DirectFBCreate() failed");
00162             return false;
00163         }
00164 #endif
00165     }
00166     else
00167     if (this->backend == MMSFB_BE_X11) {
00168 #ifdef __HAVE_XLIB__
00169         if (!(this->x_display = XOpenDisplay((char*)0))) {
00170             MMSFB_SetError(0, "XOpenDisplay() failed");
00171             return false;
00172         }
00173 
00174         this->x_screen = DefaultScreen(this->x_display);
00175 
00176         Window myroot=RootWindow(this->x_display, this->x_screen);
00177         Window root_ret;
00178         int myx,myy;
00179         unsigned int borderw, depthret;
00180         XGetGeometry(this->x_display, myroot, &root_ret, &myx, &myy, (unsigned int *)&(this->display_w), (unsigned int *)&(this->display_h), &borderw, &depthret);
00181 
00182         printf("w: %d, h: %d\n", this->display_w, this->display_h);
00183 
00184         x_depth=DefaultDepth(this->x_display, this->x_screen);
00185         rootimage =  XGetImage(mmsfb->x_display, myroot, 0, 0,
00186                       mmsfb->display_w,mmsfb->display_h, -1, ZPixmap);
00187         x_depth=DefaultDepth(this->x_display, this->x_screen);
00188 
00189         this->hidden = hidden;
00190         this->pointer = pointer;
00191 #endif
00192     }
00193 
00194     this->initialized = true;
00195     return true;
00196 }
00197 
00198 bool MMSFB::release() {
00199 #ifdef __HAVE_OPENGL__
00200     // stop backend interface server
00201     if (this->bei) {
00202         delete this->bei;
00203         this->bei = NULL;
00204     }
00205 #endif
00206 
00207     if (this->backend == MMSFB_BE_DFB) {
00208 #ifdef  __HAVE_DIRECTFB__
00209         if (this->dfb)
00210             this->dfb->Release(this->dfb);
00211 #endif
00212     }
00213     else
00214     if (this->backend == MMSFB_BE_FBDEV) {
00215 #ifdef __HAVE_FBDEV__
00216         if (this->mmsfbdev) {
00217             delete this->mmsfbdev;
00218             this->mmsfbdev = NULL;
00219         }
00220 #endif
00221     }
00222     else {
00223 #ifdef __HAVE_XLIB__
00224 #endif
00225     }
00226 
00227     this->initialized = false;
00228     return true;
00229 }
00230 
00231 bool MMSFB::isInitialized() {
00232     return this->initialized;
00233 }
00234 
00235 MMSFBBackend MMSFB::getBackend() {
00236     return this->backend;
00237 }
00238 
00239 bool MMSFB::lock() {
00240     PRINT_LOCK("mmsfb::lock");
00241     this->Lock.lock();
00242     return true;
00243 }
00244 
00245 bool MMSFB::unlock() {
00246     PRINT_LOCK("mmsfb::unlock");
00247 
00248     if(this->Lock.unlock() == 0)
00249         return true;
00250     else
00251         return false;
00252 }
00253 
00254 bool MMSFB::getLayer(int id, MMSFBLayer **layer, MMSFBOutputType outputtype, bool virtual_console) {
00255 
00256     // check if initialized
00257     INITCHECK;
00258 
00259     if (this->layer[id]) {
00260         // i have already the layer
00261         *layer = this->layer[id];
00262         return true;
00263     }
00264 
00265 
00266     // check the backend / outputtype combination
00267     if (this->backend == MMSFB_BE_X11) {
00268         if (outputtype == MMSFB_OT_XVSHM) {
00269 #ifdef __HAVE_XV__
00270 #else
00271             MMSFB_SetError(0, "compile X11/XV support!");
00272             return false;
00273 #endif
00274         }
00275         else
00276         if (outputtype == MMSFB_OT_OGL) {
00277 #ifdef __HAVE_OPENGL__
00278 #else
00279             MMSFB_SetError(0, "compile OPENGL support!");
00280             return false;
00281 #endif
00282 #ifdef __HAVE_GLX__
00283 #else
00284             MMSFB_SetError(0, "compile GLX support!");
00285             return false;
00286 #endif
00287         }
00288     }
00289     else
00290     if (this->backend == MMSFB_BE_FBDEV) {
00291         if (outputtype == MMSFB_OT_OGL) {
00292 #ifdef __HAVE_OPENGL__
00293 #else
00294             MMSFB_SetError(0, "compile OPENGL support!");
00295             return false;
00296 #endif
00297 #ifdef __HAVE_EGL__
00298 #else
00299             MMSFB_SetError(0, "compile EGL support!");
00300             return false;
00301 #endif
00302         }
00303     }
00304 
00305 
00306 
00307 
00308     if (this->backend == MMSFB_BE_FBDEV) {
00309 #ifdef __HAVE_FBDEV__
00310         if (!this->mmsfbdev) {
00311             if (outputtype == MMSFB_OT_MATROXFB) {
00312                 // matroxfb
00313                 this->mmsfbdev = new MMSFBDevMatrox();
00314             }
00315             else
00316             if (outputtype == MMSFB_OT_DAVINCIFB) {
00317                 // davincifb
00318                 this->mmsfbdev = new MMSFBDevDavinci();
00319             }
00320             else
00321             if (outputtype == MMSFB_OT_OMAPFB) {
00322                 // omapfb
00323                 DEBUGMSG("MMSGUI", "create new MMSFBDevOmap()");
00324                 this->mmsfbdev = new MMSFBDevOmap();
00325                 DEBUGMSG("MMSGUI", "created new MMSFBDevOmap()");
00326             }
00327             else {
00328                 // default fbdev
00329                 DEBUGMSG("MMSGUI", "create generic fbdev");
00330                 this->mmsfbdev = new MMSFBDev();
00331             }
00332 
00333             if (this->mmsfbdev) {
00334                 if (!this->mmsfbdev->openDevice(NULL, (virtual_console) ? MMSFBDEV_QUERY_CONSOLE : MMSFBDEV_NO_CONSOLE)) {
00335                     MMSFB_SetError(0, "MMSFBDEV device cannot be opened");
00336                     return false;
00337                 }
00338             }
00339         }
00340 #endif
00341     }
00342 
00343 
00344 
00345 
00346     if (outputtype == MMSFB_OT_OGL) {
00347 #ifdef __HAVE_OPENGL__
00348         if (!this->bei) {
00349             // start backend interface server
00350             this->bei = new MMSFBBackEndInterface();
00351         }
00352 #endif
00353     }
00354 
00355 
00356 
00357 
00358     // create a new layer instance
00359     *layer = new MMSFBLayer(id, this->backend, outputtype);
00360     if (!*layer) {
00361         MMSFB_SetError(0, "cannot create new instance of MMSFBLayer");
00362         return false;
00363     }
00364     if (!(*layer)->isInitialized()) {
00365         delete *layer;
00366         *layer = NULL;
00367         MMSFB_SetError(0, "cannot initialize MMSFBLayer");
00368         return false;
00369     }
00370 
00371     // save this for the next call
00372     this->layer[id] = *layer;
00373 
00374     return true;
00375 }
00376 
00377 
00378 bool MMSFB::getLayer(int id, MMSFBLayer **layer) {
00379 
00380     // check if initialized
00381     INITCHECK;
00382 
00383     if (this->layer[id]) {
00384         // i have already the layer
00385         *layer = this->layer[id];
00386         return true;
00387     }
00388 
00389     // layer is not initialized!!!
00390     return false;
00391 }
00392 
00393 
00394 void *MMSFB::getX11Window() {
00395     if (this->backend == MMSFB_BE_DFB) {
00396 #ifdef  __HAVE_DIRECTFB__
00397 #endif
00398     }
00399     else
00400     if (this->backend == MMSFB_BE_FBDEV) {
00401 #ifdef  __HAVE_FBDEV__
00402 #endif
00403     }
00404     else {
00405 #ifdef __HAVE_XLIB__
00406 
00407         return &this->input_window;
00408         //return &this->x_window;
00409 #endif
00410     }
00411     return NULL;
00412 }
00413 void *MMSFB::getX11Display() {
00414     if (this->backend == MMSFB_BE_DFB) {
00415 #ifdef  __HAVE_DIRECTFB__
00416 #endif
00417     }
00418     else
00419     if (this->backend == MMSFB_BE_FBDEV) {
00420 #ifdef  __HAVE_FBDEV__
00421 #endif
00422     }
00423     else {
00424 #ifdef __HAVE_XLIB__
00425         return this->x_display;
00426 #endif
00427     }
00428     return NULL;
00429 }
00430 
00431 bool MMSFB::refresh() {
00432     // check if initialized
00433     INITCHECK;
00434 
00435     if (this->backend == MMSFB_BE_DFB) {
00436 #ifdef  __HAVE_DIRECTFB__
00437 #endif
00438     }
00439     else
00440     if (this->backend == MMSFB_BE_FBDEV) {
00441 #ifdef  __HAVE_FBDEV__
00442 #endif
00443     }
00444     else {
00445 #ifdef __HAVE_XLIB__
00446         MMSFBSurface *suf;
00447         if (this->layer[0]->getSurface(&suf))
00448             suf->refresh();
00449 #endif
00450     }
00451 
00452     return true;
00453 }
00454 
00455 bool MMSFB::createSurface(MMSFBSurface **surface, int w, int h, MMSFBSurfacePixelFormat pixelformat, int backbuffer, bool systemonly) {
00456     /* check if initialized */
00457     INITCHECK;
00458 
00459     /* create or reuse a surface */
00460     *surface = mmsfbsurfacemanager->createSurface(w, h, pixelformat, backbuffer, systemonly);
00461 
00462     if (*surface)
00463         return true;
00464     else
00465         return false;
00466 }
00467 
00468 #ifdef  __HAVE_DIRECTFB__
00469 bool MMSFB::createImageProvider(IDirectFBImageProvider **provider, string filename) {
00470     *provider = NULL;
00471     if (this->backend == MMSFB_BE_DFB) {
00472 #ifdef  __HAVE_DIRECTFB__
00473         DFBResult   dfbres;
00474 
00475         /* check if initialized */
00476         INITCHECK;
00477 
00478         /* create the provider */
00479         if ((dfbres=this->dfb->CreateImageProvider(this->dfb, filename.c_str(), provider)) != DFB_OK) {
00480             MMSFB_SetError(dfbres, "IDirectFB::CreateImageProvider(" + filename + ") failed");
00481             return false;
00482         }
00483 
00484         return true;
00485 #endif
00486     }
00487     if (this->backend == MMSFB_BE_FBDEV) {
00488 #ifdef __HAVE_FBDEV__
00489 #endif
00490     }
00491     else {
00492 #ifdef __HAVE_XLIB__
00493 #endif
00494     }
00495     return false;
00496 }
00497 #endif
00498 
00499 bool MMSFB::createFont(MMSFBFont **font, string filename, int width, int height) {
00500     // check if initialized
00501     INITCHECK;
00502 
00503     // create new instance of MMSFBFont
00504     *font = new MMSFBFont(filename, width, height);
00505     if (!*font) {
00506         MMSFB_SetError(0, "cannot create new MMSFBFont instance for " + filename);
00507         return false;
00508     }
00509     if (!(*font)->isInitialized()) {
00510         delete *font;
00511         *font = NULL;
00512         MMSFB_SetError(0, "cannot initialize new MMSFBFont instance for " + filename);
00513         return false;
00514     }
00515     return true;
00516 }
00517 
00518 #ifdef __HAVE_XLIB__
00519 bool MMSFB::resizeWindow() {
00520     printf("resize w,h: %d,%d\n", this->target_window_w, this->target_window_h );
00521     XWindowChanges chg;
00522     chg.width=this->target_window_w;
00523     chg.height=this->target_window_h;
00524     printf("rc %d\n",XConfigureWindow(this->x_display, this->x_window,CWWidth|CWHeight, &chg));
00525     //XMoveResizeWindow(this->x_display, this->x_window, this->target_window_w, this->target_window_h);
00526     return true;
00527 }
00528 #endif
00529 
00530 void MMSFB::realignLayer() {
00531 #ifdef __HAVE_XLIB__
00532     static bool first = true;
00533 
00534     if(first==false)
00535         return;
00536 
00537     first=false;
00538     for(int i=0; ;i++) {
00539         if(mmsfb->x_windows[i]==0)
00540             break;
00541         else if(mmsfb->x_windows[i]!=mmsfb->input_window) {
00542             XLockDisplay(mmsfb->x_display);
00543             XLowerWindow(mmsfb->x_display, mmsfb->x_windows[i]);
00544             XFlush(mmsfb->x_display);
00545             XSync(mmsfb->x_display,False);
00546             X11_IMPL *impl = (X11_IMPL *)mmsfb->layer[i]->getImplementation();
00547 
00548             XPutImage(mmsfb->x_display, mmsfb->x_windows[i], impl->x_gc, mmsfb->rootimage, 0,0, 0, 0, mmsfb->display_w,
00549                       mmsfb->display_h);
00550 
00551             //XUnmapWindow(mmsfb->x_display, mmsfb->x_windows[i]);
00552             //printf("unmapping layer %d\n", i);
00553             XSync(mmsfb->x_display,False);
00554 
00555             XMapWindow(mmsfb->x_display, mmsfb->x_windows[i]);
00556             XRaiseWindow(mmsfb->x_display, mmsfb->input_window);
00557 
00558             //printf("mapping layer %d\n", i);
00559             XFlush(mmsfb->x_display);
00560             XSync(mmsfb->x_display,False);
00561             XUnlockDisplay(mmsfb->x_display);
00562         }
00563     }
00564 #endif
00565 }

Generated by doxygen