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 <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
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
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
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
00097 if (this->initialized) {
00098 MMSFB_SetError(0, "already initialized");
00099 return false;
00100 }
00101
00102
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
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
00116 this->x11_win_rect = x11_win_rect;
00117 #endif
00118
00119
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
00157 DirectFBInit(&this->argc,&this->argv);
00158
00159
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
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
00257 INITCHECK;
00258
00259 if (this->layer[id]) {
00260
00261 *layer = this->layer[id];
00262 return true;
00263 }
00264
00265
00266
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
00313 this->mmsfbdev = new MMSFBDevMatrox();
00314 }
00315 else
00316 if (outputtype == MMSFB_OT_DAVINCIFB) {
00317
00318 this->mmsfbdev = new MMSFBDevDavinci();
00319 }
00320 else
00321 if (outputtype == MMSFB_OT_OMAPFB) {
00322
00323 DEBUGMSG("MMSGUI", "create new MMSFBDevOmap()");
00324 this->mmsfbdev = new MMSFBDevOmap();
00325 DEBUGMSG("MMSGUI", "created new MMSFBDevOmap()");
00326 }
00327 else {
00328
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
00350 this->bei = new MMSFBBackEndInterface();
00351 }
00352 #endif
00353 }
00354
00355
00356
00357
00358
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
00372 this->layer[id] = *layer;
00373
00374 return true;
00375 }
00376
00377
00378 bool MMSFB::getLayer(int id, MMSFBLayer **layer) {
00379
00380
00381 INITCHECK;
00382
00383 if (this->layer[id]) {
00384
00385 *layer = this->layer[id];
00386 return true;
00387 }
00388
00389
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
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
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
00457 INITCHECK;
00458
00459
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
00476 INITCHECK;
00477
00478
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
00501 INITCHECK;
00502
00503
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
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
00552
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
00559 XFlush(mmsfb->x_display);
00560 XSync(mmsfb->x_display,False);
00561 XUnlockDisplay(mmsfb->x_display);
00562 }
00563 }
00564 #endif
00565 }