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

mmsfbwindowmanager.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 <cstring>
00034 #include "mmsgui/fb/mmsfbwindowmanager.h"
00035 #include "mmsinfo/mmsinfo.h"
00036 #include "mmsgui/fb/mmsfb.h"
00037 
00038 //#define DEBUG_LOCK_OUTPUT
00039 #ifdef DEBUG_LOCK_OUTPUT
00040 #include <sys/syscall.h>
00041 #define PRINT_LOCK(msg...) printf("%s %s - %d (%lu)\n", ((string)(msg)).c_str(),__FUNCTION__,__LINE__,(pid_t) syscall (SYS_gettid))
00042 #else
00043 #define PRINT_LOCK(msg...)
00044 #endif
00045 
00046 
00047 /* initialize the mmsfbwindowmanager object */
00048 MMSFBWindowManager *mmsfbwindowmanager = new MMSFBWindowManager();
00049 
00050 #define INITCHECK  if(!this->layer){MMSFB_SetError(0,"not initialized");return false;}
00051 
00052 MMSFBWindowManager::MMSFBWindowManager() {
00053     // init me
00054     this->layer = NULL;
00055     this->layer_surface = NULL;
00056     this->dst_surface = NULL;
00057     this->layer_pixelformat = MMSFB_PF_NONE;
00058     this->high_freq_surface = NULL;
00059     this->high_freq_saved_surface = NULL;
00060     this->high_freq_region.x1 = 0;
00061     this->high_freq_region.y1 = 0;
00062     this->high_freq_region.x2 = 0;
00063     this->high_freq_region.y2 = 0;
00064     this->high_freq_lastflip = 0;
00065     this->mmsfbwinmanthread = NULL;
00066 
00067     // init pointer values
00068     this->show_pointer = false;
00069     this->pointer_posx = -1;
00070     this->pointer_posy = -1;
00071     this->pointer_rect.x = 0;
00072     this->pointer_rect.y = 0;
00073     this->pointer_rect.w = 0;
00074     this->pointer_rect.h = 0;
00075     this->pointer_region.x1 = 0;
00076     this->pointer_region.y1 = 0;
00077     this->pointer_region.x2 = 0;
00078     this->pointer_region.y2 = 0;
00079     this->pointer_surface = NULL;
00080     this->pointer_opacity = 0;
00081     this->button_pressed = false;
00082     this->pointer_fadecnt = 0;
00083 }
00084 
00085 MMSFBWindowManager::~MMSFBWindowManager() {
00086     for (unsigned int i=0; i < this->windows.size(); i++) {
00087         delete this->windows.at(i).window;
00088     }
00089 }
00090 
00091 bool MMSFBWindowManager::init(MMSFBLayer *layer, bool show_pointer) {
00092 
00093     // check if already initialized
00094     if (this->layer) {
00095         MMSFB_SetError(0, "already initialized");
00096         return false;
00097     }
00098 
00099     // start my thread
00100     if (!this->mmsfbwinmanthread) {
00101         this->mmsfbwinmanthread = new MMSFBWindowManagerThread(&this->high_freq_surface,
00102                                                             &this->high_freq_saved_surface,
00103                                                             &this->high_freq_lastflip,
00104                                                             &this->lock);
00105         if (this->mmsfbwinmanthread)
00106             mmsfbwinmanthread->start();
00107     }
00108 
00109     // set values
00110     this->layer = layer;
00111     this->show_pointer = show_pointer;
00112 
00113     DEBUGMSG("MMSGUI", "MMSFBWindowManager: get layer surface");
00114 
00115     // get the surface of the layer
00116     if (!this->layer->getSurface(&this->layer_surface))
00117         return false;
00118     this->dst_surface = this->layer_surface;
00119 
00120     // get the pixelformat of the layer surface
00121     if (!this->layer_surface->getPixelFormat(&this->layer_pixelformat))
00122         return false;
00123 
00124     // get the pixelformat, create a little temp surface
00125     this->pixelformat = MMSFB_PF_NONE;
00126     this->ogl_mode = false;
00127     MMSFBSurface *ts;
00128     if (this->layer->createSurface(&ts, 8, 1)) {
00129         // okay, get the pixelformat from surface
00130         ts->getPixelFormat(&this->pixelformat);
00131         this->ogl_mode = (ts->allocated_by == MMSFBSurfaceAllocatedBy_ogl);
00132         delete ts;
00133     }
00134 
00135     // use taff?
00136     this->usetaff = false;
00137     switch (this->pixelformat) {
00138     case MMSFB_PF_ARGB:
00139         this->usetaff = true;
00140         this->taffpf = MMSTAFF_PF_ARGB;
00141         break;
00142     case MMSFB_PF_AiRGB:
00143         this->usetaff = true;
00144         this->taffpf = MMSTAFF_PF_AiRGB;
00145         break;
00146     case MMSFB_PF_AYUV:
00147         this->usetaff = true;
00148         this->taffpf = MMSTAFF_PF_AYUV;
00149         break;
00150     case MMSFB_PF_ARGB4444:
00151         this->usetaff = true;
00152         this->taffpf = MMSTAFF_PF_ARGB4444;
00153         break;
00154     case MMSFB_PF_RGB16:
00155         // if running in RGB16 mode, we use an ARGB surface for the mouse pointer
00156         this->usetaff = true;
00157         this->taffpf = MMSTAFF_PF_ARGB;
00158         break;
00159     case MMSFB_PF_ABGR:
00160         this->usetaff = true;
00161         this->taffpf = MMSTAFF_PF_ABGR;
00162         break;
00163     default:
00164         break;
00165     }
00166 
00167     return true;
00168 }
00169 
00170 bool MMSFBWindowManager::reset() {
00171 
00172     // check if initialized
00173     INITCHECK;
00174 
00175     // reset the high freq surface pointer
00176     this->high_freq_surface = NULL;
00177     this->high_freq_saved_surface = NULL;
00178     this->high_freq_lastflip = 0;
00179 
00180     return true;
00181 }
00182 
00183 bool MMSFBWindowManager::getLayer(MMSFBLayer **layer) {
00184 
00185     // check if initialized
00186     INITCHECK;
00187 
00188     // return the layer
00189     *layer = this->layer;
00190 
00191     return true;
00192 }
00193 
00194 void MMSFBWindowManager::lockWM() {
00195     // stop parallel processing
00196     lock.lock();
00197 }
00198 
00199 void MMSFBWindowManager::unlockWM() {
00200     // unlock
00201     lock.unlock();
00202 }
00203 
00204 bool MMSFBWindowManager::addWindow(MMSFBWindow *window) {
00205 
00206     /* check if initialized */
00207     INITCHECK;
00208 
00209     /* stop parallel processing */
00210     lock.lock();
00211 
00212     /* search for duplicate items */
00213     for (unsigned int i=0; i < this->windows.size(); i++)
00214         if (this->windows.at(i).window == window) {
00215             lock.unlock();
00216             return false;
00217         }
00218 
00219     /* add window */
00220     AVAILABLE_WINDOWS awin;
00221     awin.window = window;
00222     awin.vrect.x = 0;
00223     awin.vrect.y = 0;
00224     awin.vrect.w = 0;
00225     awin.vrect.h = 0;
00226     this->windows.push_back(awin);
00227 
00228     /* unlock */
00229     lock.unlock();
00230 
00231     return true;
00232 }
00233 
00234 bool MMSFBWindowManager::removeWindow(MMSFBWindow *window) {
00235 
00236     /* check if initialized */
00237     INITCHECK;
00238 
00239     /* stop parallel processing */
00240     lock.lock();
00241 
00242     /* search for item */
00243     for (unsigned int i=0; i < this->windows.size(); i++)
00244         if (this->windows.at(i).window == window) {
00245 
00246             /* hide the window before removing */
00247             hideWindow(window);
00248 
00249             /* remove it from list */
00250             this->windows.erase(this->windows.begin()+i);
00251 
00252             /* unlock */
00253             lock.unlock();
00254             return true;
00255         }
00256 
00257     /* not found */
00258     lock.unlock();
00259     return false;
00260 }
00261 
00262 bool MMSFBWindowManager::raiseToTop(MMSFBWindow *window, int zlevel) {
00263 
00264     // check if initialized
00265     INITCHECK;
00266 
00267     // stop parallel processing
00268     lock.lock();
00269 
00270     // get requested zorder index
00271     zlevel = this->vwins.size() - 1 - zlevel;
00272     if (zlevel < 0)
00273         zlevel = 0;
00274     else
00275     if (zlevel >= (int)this->vwins.size())
00276         zlevel = this->vwins.size() - 1;
00277 
00278     // search for item within visible list
00279     for (unsigned int i=0; i < this->vwins.size(); i++)
00280         if (this->vwins.at(i).window == window) {
00281             // window found
00282             if ((int)i < zlevel) {
00283                 // window is not at the top or the requested zlevel, raise it now
00284                 // if the requested zlevel is less than the current zlevel, nothing will be done
00285                 VISIBLE_WINDOWS vw = this->vwins.at(i);
00286                 this->vwins.erase(this->vwins.begin()+i);
00287                 this->vwins.insert(this->vwins.begin()+zlevel, vw);
00288 
00289                 // change the windows list
00290                 if ((int)this->vwins.size() <= zlevel+1) {
00291                     // at the top
00292                     for (unsigned int i=0; i < this->windows.size(); i++)
00293                         if (this->windows.at(i).window == window) {
00294                             // window found
00295                             if (i < this->windows.size()-1) {
00296                                 // put at the top
00297                                 AVAILABLE_WINDOWS aw = this->windows.at(i);
00298                                 this->windows.erase(this->windows.begin()+i);
00299                                 this->windows.push_back(aw);
00300                             }
00301                             break;
00302                         }
00303                 }
00304                 else {
00305                     for (unsigned int i=0; i < this->windows.size(); i++)
00306                         if (this->windows.at(i).window == window) {
00307                             // window found
00308                             if (i < this->windows.size()-1) {
00309                                 // put it behind the swin
00310                                 MMSFBWindow *swin = this->vwins.at(zlevel + 1).window;
00311                                 for (unsigned int j=0; j < this->windows.size(); j++)
00312                                     if (this->windows.at(j).window == swin) {
00313                                         // window found
00314                                         AVAILABLE_WINDOWS aw = this->windows.at(i);
00315                                         this->windows.insert(this->windows.begin()+j, aw);
00316                                         if (i>=j) i++;
00317                                         this->windows.erase(this->windows.begin()+i);
00318                                         break;
00319                                     }
00320                             }
00321                             break;
00322                         }
00323                 }
00324 
00325                 PRINT_LOCK("flipSurface");
00326                 // draw the window
00327                 vw.surface->lock();
00328                 flipSurface(vw.surface, NULL, true);
00329                 PRINT_LOCK("end flipSurface");
00330                 vw.surface->unlock();
00331             }
00332 
00333             // unlock
00334             lock.unlock();
00335             return true;
00336         }
00337 
00338 
00339     PRINT_LOCK("not found");
00340     // not found
00341     lock.unlock();
00342     return false;
00343 }
00344 
00345 bool MMSFBWindowManager::lowerToBottom(MMSFBWindow *window) {
00346 
00347     /* check if initialized */
00348     INITCHECK;
00349 
00350     /* stop parallel processing */
00351     lock.lock();
00352 
00353     /* search for item */
00354     for (unsigned int i=0; i < this->windows.size(); i++)
00355         if (this->windows.at(i).window == window) {
00356             /* window found */
00357             if (i > 0) {
00358                 /* window is not at the bottom, lower it now */
00359                 AVAILABLE_WINDOWS aw = this->windows.at(i);
00360                 this->windows.erase(this->windows.begin()+i);
00361                 this->windows.insert(this->windows.begin(), aw);
00362 
00363                 /* search for item within visible list */
00364                 for (unsigned int j=0; j < this->vwins.size(); j++)
00365                     if (this->vwins.at(j).window == window) {
00366                         /* window found */
00367                         if (j > 0) {
00368                             /* window is not at the bottom, lower it now */
00369                             VISIBLE_WINDOWS vw = this->vwins.at(j);
00370                             this->vwins.erase(this->vwins.begin()+j);
00371                             this->vwins.insert(this->vwins.begin(), vw);
00372 
00373                             PRINT_LOCK("flipSurface");
00374                             /* draw the window */
00375                             flipSurface(vw.surface, NULL, true);
00376                             PRINT_LOCK("end flipSurface");
00377                         }
00378                     }
00379             }
00380 
00381             /* unlock */
00382             lock.unlock();
00383             return true;
00384         }
00385 
00386     /* not found */
00387     lock.unlock();
00388     return false;
00389 }
00390 
00391 
00392 bool MMSFBWindowManager::loadWindowConfig(MMSFBWindow *window, VISIBLE_WINDOWS *vwin) {
00393     vwin->window = window;
00394     vwin->window->getSurface(&vwin->surface);
00395     MMSFBWindowConfig winconf;
00396     vwin->window->getConfiguration(&winconf);
00397     vwin->vrect.x = 0;
00398     vwin->vrect.y = 0;
00399     vwin->vrect.w = 0;
00400     vwin->vrect.h = 0;
00401     for (unsigned int i=0; i < this->windows.size(); i++)
00402         if (this->windows.at(i).window == window) {
00403             vwin->vrect = this->windows.at(i).vrect;
00404             break;
00405         }
00406     vwin->region.x1 = winconf.posx;
00407     vwin->region.y1 = winconf.posy;
00408     vwin->region.x2 = vwin->region.x1 + winconf.surface_config.w - 1;
00409     vwin->region.y2 = vwin->region.y1 + winconf.surface_config.h - 1;
00410     if ((vwin->vrect.w > 0)&&(vwin->vrect.h > 0)) {
00411         // visible rectangle set, so have to adjust region
00412         MMSFBRegion sr = vwin->region;
00413         sr.x1 += vwin->vrect.x;
00414         sr.y1 += vwin->vrect.y;
00415         sr.x2 = sr.x1 + vwin->vrect.w - 1;
00416         sr.y2 = sr.y1 + vwin->vrect.h - 1;
00417         if (sr.x1 < vwin->region.x1)
00418             sr.x1 = vwin->region.x1;
00419         if (sr.y1 < vwin->region.y1)
00420             sr.y1 = vwin->region.y1;
00421         if (sr.x2 > vwin->region.x2)
00422             sr.x2 = vwin->region.x2;
00423         if (sr.y2 > vwin->region.y2)
00424             sr.y2 = vwin->region.y2;
00425         if ((sr.x1 <= vwin->region.x2)&&(sr.y1 <= vwin->region.y2)&&(sr.x2 >= vwin->region.x1)&&(sr.y2 >= vwin->region.y1)) {
00426             // adjusted region okay, set it
00427             vwin->region = sr;
00428         }
00429         else {
00430             // window is outside it's visible region
00431             vwin->region.x1 = 0;
00432             vwin->region.y1 = 0;
00433             vwin->region.x2 = -1;
00434             vwin->region.y2 = -1;
00435         }
00436     }
00437     vwin->alphachannel = winconf.surface_config.surface_buffer->alphachannel;
00438     vwin->opacity = winconf.opacity;
00439     vwin->lastflip = 0;
00440     vwin->islayersurface = false;
00441     vwin->saved_surface = NULL;
00442     return true;
00443 }
00444 
00445 bool MMSFBWindowManager::showWindow(MMSFBWindow *window, bool locked, bool refresh) {
00446 
00447     /* check if initialized */
00448     INITCHECK;
00449 
00450     /* stop parallel processing */
00451     if (!locked)
00452         lock.lock();
00453 
00454     /* search for item */
00455     for (unsigned int i=0; i < this->windows.size(); i++)
00456         if (this->windows.at(i).window == window) {
00457             /* search for duplicate items */
00458             for (unsigned int j=0; j < this->vwins.size(); j++)
00459                 if (this->vwins.at(j).window == window) {
00460                     /* the window is already visible */
00461                     if (!locked)
00462                         lock.unlock();
00463                     return false;
00464                 }
00465 
00466             /* prepare new list item */
00467             VISIBLE_WINDOWS vwin;
00468             loadWindowConfig(window, &vwin);
00469 
00470             /* add window to visible list */
00471             bool inserted = false;
00472             if (i < this->windows.size()-1) {
00473                 /* first searching for the right position within the window stack */
00474                 for (unsigned int j=0; j < this->vwins.size() && !inserted; j++)
00475                     for (unsigned int k=0; k < this->windows.size() && !inserted; k++)
00476                         if (this->vwins.at(j).window == this->windows.at(k).window)
00477                             if (k > i) {
00478                                 /* insert the window */
00479                                 this->vwins.insert(this->vwins.begin()+j, vwin);
00480                                 inserted = true;
00481                                 break;
00482                             }
00483             }
00484             if (!inserted)
00485                 /* insert at the end (this is the top) */
00486                 this->vwins.push_back(vwin);
00487 
00488             PRINT_LOCK("flipSurface");
00489             /* draw the window */
00490             flipSurface(vwin.surface, NULL, true, refresh);
00491             PRINT_LOCK("end flipSurface");
00492 
00493             /* unlock */
00494             if (!locked)
00495                 lock.unlock();
00496 
00497             return true;
00498         }
00499 
00500     /* not found */
00501     lock.unlock();
00502     return false;
00503 }
00504 
00505 bool MMSFBWindowManager::hideWindow(MMSFBWindow *window, bool locked, bool refresh) {
00506 
00507     /* check if initialized */
00508     INITCHECK;
00509 
00510     /* stop parallel processing */
00511     if (!locked)
00512         lock.lock();
00513 
00514     /* search for item */
00515     for (unsigned int i=0; i < this->vwins.size(); i++)
00516         if (this->vwins.at(i).window == window) {
00517             /* redraw the window with no opacity because must redrawing other windows */
00518             this->vwins.at(i).opacity = 0;
00519 
00520             PRINT_LOCK("flipSurface");
00521             flipSurface(this->vwins.at(i).surface, NULL, true, refresh);
00522             PRINT_LOCK("end flipSurface");
00523 
00524             if (this->high_freq_surface==this->vwins.at(i).surface) {
00525                 /* i was the high_freq_surface */
00526                 this->high_freq_surface = NULL;
00527                 this->high_freq_saved_surface = NULL;
00528                 this->high_freq_lastflip = 0;
00529             }
00530 
00531             /* remove it from list */
00532             this->vwins.erase(this->vwins.begin()+i);
00533 
00534             /* unlock */
00535             if (!locked)
00536                 lock.unlock();
00537 
00538             return true;
00539         }
00540 
00541     /* not found */
00542     if (!locked)
00543         lock.unlock();
00544     return false;
00545 }
00546 
00547 bool MMSFBWindowManager::flipSurface(MMSFBSurface *surface, MMSFBRegion *region,
00548                                      bool locked, bool refresh) {
00549     VISIBLE_WINDOWS *vw = NULL;
00550     MMSFBRegion     ls_region;
00551     bool            high_freq = false;
00552     bool            cleared = false;
00553     bool            win_found = false;
00554 
00555     /* check if initialized */
00556     INITCHECK;
00557 
00558     PRINT_LOCK("enter flipSurface");
00559 
00560     /* stop parallel processing */
00561     if (!locked)
00562         lock.lock();
00563 
00564     if (this->ogl_mode) {
00565         // running in OpenGL mode
00566         // note: GLX can only flip the complete screen!!!
00567         //       EGL too, but currently we run EGL with FRONTONLY, so we do not need a layer flip
00568 #ifdef  __HAVE_GLX__
00569         surface = NULL;
00570         region = NULL;
00571 #endif
00572     }
00573 
00574 /*
00575 if (region)
00576 printf("#1winman: region = %d,%d,%d,%d\n", region->x1, region->y1, region->x2, region->y2);
00577 else
00578 printf("#1winman: region = NULL\n");
00579 */
00580 
00581     /* search for item */
00582     if (surface) {
00583         /* surface given */
00584         for (unsigned int i=0; i < this->vwins.size(); i++) {
00585             if (this->vwins.at(i).surface == surface) {
00586                 // surface found
00587                 vw = &(this->vwins.at(i));
00588                 ls_region = vw->region;
00589 
00590                 // calculate the affected region on the layer surface
00591                 if (region != NULL) {
00592                     // only a region
00593                     if (region->x1 > 0) {
00594                         ls_region.x2 = ls_region.x1 + region->x2;
00595                         ls_region.x1 = ls_region.x1 + region->x1;
00596                     }
00597                     else
00598                         ls_region.x2 = ls_region.x1 + region->x2;
00599                     if (region->y1 > 0) {
00600                         ls_region.y2 = ls_region.y1 + region->y2;
00601                         ls_region.y1 = ls_region.y1 + region->y1;
00602                     }
00603                     else
00604                         ls_region.y2 = ls_region.y1 + region->y2;
00605 
00606                     if ((vw->vrect.w > 0)&&(vw->vrect.h > 0)) {
00607                         // visible rectangle set, check calculated ls_region
00608                         ls_region.x1 -= vw->vrect.x;
00609                         ls_region.y1 -= vw->vrect.y;
00610                         ls_region.x2 -= vw->vrect.x;
00611                         ls_region.y2 -= vw->vrect.y;
00612 
00613                         if (ls_region.x1 < vw->region.x1)
00614                             ls_region.x1 = vw->region.x1;
00615                         if (ls_region.y1 < vw->region.y1)
00616                             ls_region.y1 = vw->region.y1;
00617                         if (ls_region.x2 > vw->region.x2)
00618                             ls_region.x2 = vw->region.x2;
00619                         if (ls_region.y2 > vw->region.y2)
00620                             ls_region.y2 = vw->region.y2;
00621 
00622                         if ((ls_region.x1 > ls_region.x2)||(ls_region.y1 > ls_region.y2)) {
00623                             // wrong region
00624                             vw = NULL;
00625                             break;
00626                         }
00627                     }
00628                 }
00629 
00630                 // check region
00631                 if (ls_region.x1 < 0) {
00632                     ls_region.x2+= ls_region.x1;
00633                     ls_region.x1 = 0;
00634                 }
00635                 if (ls_region.y1 < 0) {
00636                     ls_region.y2+= ls_region.y1;
00637                     ls_region.y1 = 0;
00638                 }
00639                 int ls_w, ls_h;
00640                 if (this->dst_surface->getSize(&ls_w, &ls_h)) {
00641                     if (ls_region.x2 >= ls_w)
00642                         ls_region.x2 = ls_w - 1;
00643                     if (ls_region.y2 >= ls_h)
00644                         ls_region.y2 = ls_h - 1;
00645                 }
00646 
00647                 break;
00648             }
00649         }
00650 
00651         if (!vw) {
00652             /* not found */
00653             if (!locked)
00654                 lock.unlock();
00655             PRINT_LOCK("leave flipSurface");
00656             return false;
00657         }
00658     }
00659     else {
00660         // no surface given, have to redraw a layer region?
00661         if (region == NULL) {
00662             // no
00663 /*            if (!locked)
00664                 lock.unlock();
00665             return false;*/
00666 
00667             if (!this->dst_surface->getSize(&ls_region.x2, &ls_region.y2)) {
00668                 if (!locked)
00669                     lock.unlock();
00670                 PRINT_LOCK("leave flipSurface");
00671                 return false;
00672             }
00673 
00674             ls_region.x1=0;
00675             ls_region.y1=0;
00676             ls_region.x2--;
00677             ls_region.y2--;
00678         }
00679         else {
00680             // take this region
00681             ls_region = *region;
00682         }
00683     }
00684 
00685     if ((region == NULL)&&(vw)) {
00686         /* this is only for whole (window) surfaces with an high flip frequency */
00687         struct  timeval tv;
00688         /* get the flip time */
00689         gettimeofday(&tv, NULL);
00690         int newfliptime = (((int)tv.tv_sec)%1000000)*1000+((int)tv.tv_usec)/1000;
00691         int diff = newfliptime - vw->lastflip;
00692 
00693         if ((diff > 0)&&(diff < 50)) {
00694             /* more than 20 pictures per second comes from this surface */
00695             high_freq = true;
00696         }
00697 
00698         if (vw->saved_surface) {
00699             /* save the frames if window works direct on the layer surface */
00700             if (vw->lastflip % 1000 < 40) {
00701             }
00702         }
00703 
00704         vw->lastflip = newfliptime;
00705     }
00706 
00707     if (high_freq) {
00708         /* this surface has an high flip frequency */
00709         if (!this->high_freq_surface) {
00710             /* this->high_freq_surface is not set, set it now */
00711             this->high_freq_region = ls_region;
00712             this->high_freq_lastflip = vw->lastflip;
00713             this->high_freq_surface = vw->surface;
00714             this->high_freq_saved_surface = vw->saved_surface;
00715         }
00716         else
00717             /* update the high_freq_lastflip */
00718             this->high_freq_lastflip = vw->lastflip;
00719     }
00720     else {
00721         bool check = (this->high_freq_surface!=NULL);
00722         if ((check)&&(vw))
00723             check = (this->high_freq_surface!=vw->surface);
00724         if (check) {
00725             /* high_freq_surface is set and i am not this surface */
00726             /* check if i am within high_freq_region */
00727             if ((this->high_freq_region.x1 <= ls_region.x1)
00728               &&(this->high_freq_region.y1 <= ls_region.y1)
00729               &&(this->high_freq_region.x2 >= ls_region.x2)
00730               &&(this->high_freq_region.y2 >= ls_region.y2)) {
00731                 /* yes, have to flip nothing */
00732                 if (!locked)
00733                     lock.unlock();
00734                 PRINT_LOCK("leave flipSurface");
00735                 return true;
00736             }
00737         }
00738         else {
00739             if ((this->high_freq_surface)&&(vw))
00740                 /* update the high_freq_lastflip */
00741                 this->high_freq_lastflip = vw->lastflip;
00742         }
00743     }
00744 
00745 
00746     this->dst_surface->lock();
00747     // set the region of the layer surface
00748     this->dst_surface->setClip(&ls_region);
00749 
00750     // check if i have to clear the background
00751     if (!vw)
00752         cleared = true;
00753     else
00754         cleared = (!((vw->alphachannel==false)&&(vw->opacity==255)));
00755 
00756 
00757 //printf("#2winman: flip windows\n");
00758 
00759     // two loops for optimized DEPTH TEST
00760     // FIRST:  find lowest window which is to blit
00761     // SECOND: blit the window stack beginning from lowest window
00762     int lowest_win = 0;
00763     MMSFBRegion tmpreg = MMSFBRegion(0,0,0,0);
00764     for (int depth_test = 1; depth_test >= 0; depth_test--) {
00765         // searching for affected windows and draw parts of it (in the second loop)
00766         for (unsigned int i = lowest_win; i < this->vwins.size(); i++) {
00767             VISIBLE_WINDOWS *aw = &(this->vwins.at(i));
00768             MMSFBRegion myreg = aw->region;
00769             MMSFBRegion *myregion = &myreg;
00770 
00771             // if the window has no opacity then continue
00772             if (!aw->opacity)
00773                 continue;
00774 
00775             // check if layer surface
00776             if (aw->islayersurface)
00777                 if (!cleared)
00778                     continue;
00779 
00780             if (!((myregion->x2 < ls_region.x1)||(myregion->y2 < ls_region.y1)
00781                 ||(myregion->x1 > ls_region.x2)||(myregion->y1 > ls_region.y2))) {
00782                 // the window is affected
00783                 if (depth_test) {
00784                     // FIRST loop: DEPTH TEST
00785                     if (myregion->x1 <= tmpreg.x1 && myregion->y1 <= tmpreg.y1
00786                             && myregion->x2 >= tmpreg.x2 && myregion->y2 >= tmpreg.y2) {
00787                         if ((!aw->alphachannel) || (MMSFBSURFACE_READ_BUFFER(aw->surface).opaque)) {
00788                             if (aw->opacity == 0xff) {
00789                                 tmpreg = *myregion;
00790                                 lowest_win = i;
00791                             }
00792                         }
00793                     }
00794                 }
00795                 else {
00796                     // SECOND loop: blit affected window
00797 
00798                     // check for locking on blit
00799                     if (aw->islayersurface) {
00800                         if (aw->saved_surface) {
00801                             if (!aw->saved_surface->tryToLock()) {
00802                                 printf("try lock failed - add to queue\n");
00803                                 if (mmsfbwinmanthread) {
00804                                     MMSFBWindowManagerThread::FLIP_STRUCT tmpFlipStruct = {NULL, NULL, refresh};
00805                                     mmsfbwinmanthread->flipQueue.push(tmpFlipStruct);
00806                                 }
00807                                 // reset the clip
00808                                 this->dst_surface->setClip(NULL);
00809                                 this->dst_surface->unlock();
00810                                 if (!locked)
00811                                     lock.unlock();
00812                                 return false;
00813                             }
00814                         }
00815                     }
00816                     else {
00817                         if (!aw->surface->tryToLock()) {
00818                             printf("try lock failed - add to queue\n");
00819                             if (mmsfbwinmanthread) {
00820                                 MMSFBWindowManagerThread::FLIP_STRUCT tmpFlipStruct = {NULL, NULL, refresh};
00821                                 mmsfbwinmanthread->flipQueue.push(tmpFlipStruct);
00822                             }
00823                             // reset the clip
00824                             this->dst_surface->setClip(NULL);
00825                             this->dst_surface->unlock();
00826                             if (!locked)
00827                                 lock.unlock();
00828                             return false;
00829                         }
00830                     }
00831 
00832                     // calc source and destination
00833                     MMSFBRectangle src_rect;
00834                     int dst_x = ls_region.x1;
00835                     int dst_y = ls_region.y1;
00836 
00837                     src_rect.x = ls_region.x1 - myregion->x1;
00838                     if (src_rect.x < 0) {
00839                         dst_x-= src_rect.x;
00840                         src_rect.x = 0;
00841                     }
00842 
00843                     src_rect.y = ls_region.y1 - myregion->y1;
00844                     if (src_rect.y < 0) {
00845                         dst_y-= src_rect.y;
00846                         src_rect.y = 0;
00847                     }
00848 
00849                     src_rect.w = myregion->x2 - myregion->x1 + 1 - src_rect.x;
00850                     if (myregion->x2 > ls_region.x2)
00851                         src_rect.w-= myregion->x2 - ls_region.x2;
00852 
00853                     src_rect.h = myregion->y2 - myregion->y1 + 1 - src_rect.y;
00854                     if (myregion->y2 > ls_region.y2)
00855                         src_rect.h-= myregion->y2 - ls_region.y2;
00856 
00857                     if ((aw->vrect.w > 0)&&(aw->vrect.h > 0)) {
00858                         // visible rectangle set, so have to adjust source offset
00859                         src_rect.x += aw->vrect.x;
00860                         src_rect.y += aw->vrect.y;
00861                     }
00862 /*
00863 printf("#3winman: flip window id = %d, opaque = %d, src_rect = %d,%d %dx%d, dst = %d,%d\n",
00864                         i, MMSFBSURFACE_READ_BUFFER(aw->surface).opaque,
00865                         src_rect.x, src_rect.y, src_rect.w, src_rect.h, dst_x, dst_y);
00866 */
00867 
00868                     // set the blitting flags and color
00869                     if ((aw->alphachannel)&&((win_found)||(!this->dst_surface->config.surface_buffer->alphachannel))) {
00870                         // the window has an alphachannel
00871                         if (!(MMSFBSURFACE_READ_BUFFER(aw->surface).opaque)) {
00872                             // (semi-)transparent surface buffer
00873                             if (aw->opacity < 255) {
00874                                 this->dst_surface->setBlittingFlags((MMSFBBlittingFlags) (MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA));
00875                                 this->dst_surface->setColor(0, 0, 0, aw->opacity);
00876                             }
00877                             else {
00878                                 this->dst_surface->setBlittingFlags((MMSFBBlittingFlags) MMSFB_BLIT_BLEND_ALPHACHANNEL);
00879                             }
00880                         }
00881                         else {
00882                             // opaque surface buffer, we do not need MMSFB_BLIT_BLEND_ALPHACHANNEL
00883                             if (aw->opacity < 255) {
00884                                 this->dst_surface->setBlittingFlags((MMSFBBlittingFlags) MMSFB_BLIT_BLEND_COLORALPHA);
00885                                 this->dst_surface->setColor(0, 0, 0, aw->opacity);
00886                             }
00887                             else {
00888                                 this->dst_surface->setBlittingFlags((MMSFBBlittingFlags) MMSFB_BLIT_NOFX);
00889                             }
00890                         }
00891 
00892                         // first window?
00893                         if (!win_found) {
00894                             // yes, clear the layer before blitting the first window surface
00895                             if (cleared)
00896                                 this->dst_surface->clear();
00897                             win_found = true;
00898                         }
00899                     }
00900                     else {
00901                         // the window has no alphachannel
00902                         if (aw->opacity < 255) {
00903                             this->dst_surface->setBlittingFlags((MMSFBBlittingFlags) MMSFB_BLIT_BLEND_COLORALPHA);
00904                             this->dst_surface->setColor(0, 0, 0, aw->opacity);
00905                         }
00906                         else {
00907                             this->dst_surface->setBlittingFlags((MMSFBBlittingFlags) MMSFB_BLIT_NOFX);
00908                         }
00909 
00910                         // first window?
00911                         if (!win_found) {
00912                             // yes, clear the layer before blitting the first window surface
00913                             // but only, if the first window does not use the whole layer region
00914                             // else we do not have to clear the layer region and can save CPU
00915                             if (cleared)
00916                                 if ((aw->opacity < 255)||((dst_x != ls_region.x1) || (dst_y != ls_region.y1)
00917                                  || (dst_x + src_rect.w <= ls_region.x2) || (dst_y + src_rect.h <= ls_region.y2))) {
00918                                     this->dst_surface->clear();
00919                                 }
00920 
00921                             win_found = true;
00922                         }
00923                     }
00924 
00925                     // check if layer surface and blit
00926                     if (aw->islayersurface) {
00927                         if (aw->saved_surface) {
00928                             this->dst_surface->blit(aw->saved_surface, &src_rect, dst_x, dst_y);
00929                             this->dst_surface->unlock();
00930                         }
00931                     }
00932                     else {
00933                         this->dst_surface->blit(aw->surface, &src_rect, dst_x, dst_y);
00934                         aw->surface->unlock();
00935                     }
00936                 }
00937             }
00938         }
00939     }
00940 
00941     if (!win_found) {
00942         // if no window is drawn, check if we have to clear the layer region
00943         if (cleared)
00944             this->dst_surface->clear();
00945     }
00946 
00947     // draw the pointer
00948     drawPointer(&ls_region);
00949 
00950     // reset the clip
00951     this->dst_surface->setClip(NULL);
00952 
00953     // make changes visible
00954     if (refresh) {
00955         PRINT_LOCK("enter flip");
00956         this->dst_surface->flip(&ls_region);
00957         PRINT_LOCK("leave flip");
00958     }
00959 
00960     this->dst_surface->unlock();
00961 
00962     // unlock
00963     if (!locked)
00964         lock.unlock();
00965 
00966     PRINT_LOCK("leave flipSurface");
00967 
00968     return true;
00969 }
00970 
00971 bool MMSFBWindowManager::setWindowOpacity(MMSFBWindow *window) {
00972 
00973     /* check if initialized */
00974     INITCHECK;
00975 
00976     /* stop parallel processing */
00977     lock.lock();
00978 
00979     /* search for item */
00980     for (unsigned int i=0; i < this->vwins.size(); i++)
00981         if (this->vwins.at(i).window == window) {
00982             /* reload windows config */
00983             loadWindowConfig(window, &(this->vwins.at(i)));
00984 
00985             PRINT_LOCK("flipSurface");
00986             /* redraw the window */
00987             flipSurface(this->vwins.at(i).surface, NULL, true);
00988             PRINT_LOCK("end flipSurface");
00989 
00990             /* unlock */
00991             lock.unlock();
00992 
00993             return true;
00994         }
00995 
00996     /* not found */
00997     lock.unlock();
00998     return false;
00999 }
01000 
01001 bool MMSFBWindowManager::setWindowPosition(MMSFBWindow *window, MMSFBRectangle *vrect) {
01002 
01003     /* check if initialized */
01004     INITCHECK;
01005 
01006     /* stop parallel processing */
01007     lock.lock();
01008 
01009     // change visible rectangle and position in one step?
01010     if (vrect) {
01011         // yes, change visible rectangle
01012         for (unsigned int i=0; i < this->windows.size(); i++) {
01013             if (this->windows.at(i).window == window) {
01014                 // set rect
01015                 this->windows.at(i).vrect = *vrect;
01016                 break;
01017             }
01018         }
01019     }
01020 
01021     /* search for item */
01022     for (unsigned int i=0; i < this->vwins.size(); i++)
01023         if (this->vwins.at(i).window == window) {
01024             /* get the old config */
01025             VISIBLE_WINDOWS old_vwin;
01026             old_vwin = this->vwins.at(i);
01027 
01028             /* reload windows config */
01029             loadWindowConfig(window, &(this->vwins.at(i)));
01030 
01031             /* moving high_freq_surface? */
01032             if (this->high_freq_surface == this->vwins.at(i).surface) {
01033                 /* yes, reset it */
01034                 PRINT_LOCK("flipSurface");
01035                 mmsfbwindowmanager->flipSurface(this->high_freq_surface, NULL, true);
01036                 PRINT_LOCK("end flipSurface");
01037                 this->high_freq_surface = NULL;
01038                 this->high_freq_saved_surface = NULL;
01039                 this->high_freq_lastflip = 0;
01040             }
01041 
01042             PRINT_LOCK("flipSurface");
01043             /* redraw the window */
01044             flipSurface(this->vwins.at(i).surface, NULL, true);
01045             PRINT_LOCK("end flipSurface");
01046 
01047             /* redraw the old rects */
01048             if (old_vwin.region.y1 < this->vwins.at(i).region.y1) {
01049                 /* redraw above */
01050                 MMSFBRegion region;
01051                 region = old_vwin.region;
01052                 if (region.y2 >= this->vwins.at(i).region.y1)
01053                     region.y2 = this->vwins.at(i).region.y1 - 1;
01054                 PRINT_LOCK("flipSurface");
01055                 flipSurface(NULL, &region, true);
01056                 PRINT_LOCK("end flipSurface");
01057             }
01058             else
01059             if (old_vwin.region.y1 > this->vwins.at(i).region.y1) {
01060                 /* redraw below */
01061                 MMSFBRegion region;
01062                 region = old_vwin.region;
01063                 if (region.y1 <= this->vwins.at(i).region.y2)
01064                     region.y1 = this->vwins.at(i).region.y2 + 1;
01065                 PRINT_LOCK("flipSurface");
01066                 flipSurface(NULL, &region, true);
01067                 PRINT_LOCK("end flipSurface");
01068             }
01069             if (old_vwin.region.x1 < this->vwins.at(i).region.x1) {
01070                 /* redraw left side */
01071                 MMSFBRegion region;
01072                 region = old_vwin.region;
01073                 if  ((region.y2 >= this->vwins.at(i).region.y1)
01074                    &&(region.y1 <= this->vwins.at(i).region.y2)) {
01075                     if (region.x2 >= this->vwins.at(i).region.x1)
01076                         region.x2 = this->vwins.at(i).region.x1 - 1;
01077                     region.y1 = this->vwins.at(i).region.y1;
01078                     region.y2 = this->vwins.at(i).region.y2;
01079                     PRINT_LOCK("flipSurface");
01080                     flipSurface(NULL, &region, true);
01081                     PRINT_LOCK("end flipSurface");
01082                 }
01083             }
01084             else
01085             if (old_vwin.region.x1 > this->vwins.at(i).region.x1) {
01086                 /* redraw right side */
01087                 MMSFBRegion region;
01088                 region = old_vwin.region;
01089                 if  ((region.y2 >= this->vwins.at(i).region.y1)
01090                    &&(region.y1 <= this->vwins.at(i).region.y2)) {
01091                     if (region.x1 <= this->vwins.at(i).region.x2)
01092                         region.x1 = this->vwins.at(i).region.x2 + 1;
01093                     region.y1 = this->vwins.at(i).region.y1;
01094                     region.y2 = this->vwins.at(i).region.y2;
01095                     PRINT_LOCK("flipSurface");
01096                     flipSurface(NULL, &region, true);
01097                     PRINT_LOCK("end flipSurface");
01098                 }
01099             }
01100 
01101             /* unlock */
01102             lock.unlock();
01103 
01104             return true;
01105         }
01106 
01107     /* not found */
01108     lock.unlock();
01109     return false;
01110 }
01111 
01112 bool MMSFBWindowManager::setWindowSize(MMSFBWindow *window, int w, int h) {
01113 
01114     /* check if initialized */
01115     INITCHECK;
01116 
01117     /* stop parallel processing */
01118     lock.lock();
01119 
01120     /* search for item which is visible */
01121     for (unsigned int i=0; i < this->vwins.size(); i++)
01122         if (this->vwins.at(i).window == window) {
01123             /* found as visible window */
01124             VISIBLE_WINDOWS old_vwin;
01125             old_vwin = this->vwins.at(i);
01126             int old_w = old_vwin.region.x2 - old_vwin.region.x1 + 1;
01127             int old_h = old_vwin.region.y2 - old_vwin.region.y1 + 1;
01128 
01129             if ((old_w != w)||(old_h != h)) {
01130                 /* hide the window without updating the screen */
01131                 hideWindow(window, true, false);
01132 
01133                 /* resizing surface */
01134                 MMSFBSurface *surface;
01135                 window->getSurface(&surface);
01136                 surface->lock();
01137                 surface->resize(w, h);
01138                 surface->unlock();
01139 
01140                 /* search for item in the window list */
01141                 for (unsigned int j=0; j < this->windows.size(); j++)
01142                     if (this->windows.at(j).window == window) {
01143                         // reset the visible region
01144                         this->windows.at(j).vrect.x = 0;
01145                         this->windows.at(j).vrect.y = 0;
01146                         this->windows.at(j).vrect.w = 0;
01147                         this->windows.at(j).vrect.h = 0;
01148                         break;
01149                     }
01150 
01151                 /* re-show it */
01152                 if ((old_w <= w)&&(old_h <= h))
01153                     /* larger or equal */
01154                     showWindow(window, true, true);
01155                 else {
01156                     /* new window is less than the old one */
01157                     showWindow(window, true, false);
01158 
01159                     PRINT_LOCK("flipSurface");
01160                     /* flip the old region */
01161                     flipSurface(NULL, &old_vwin.region, true, true);
01162                     PRINT_LOCK("end flipSurface");
01163                 }
01164             }
01165 
01166             /* unlock */
01167             lock.unlock();
01168 
01169             return true;
01170         }
01171 
01172     /* search for item in the window list */
01173     for (unsigned int i=0; i < this->windows.size(); i++)
01174         if (this->windows.at(i).window == window) {
01175             /* found as window which is currently not shown */
01176             /* resizing surface */
01177             MMSFBSurface *surface;
01178             window->getSurface(&surface);
01179             surface->lock();
01180             surface->resize(w, h);
01181             surface->unlock();
01182 
01183             // reset the visible region
01184             this->windows.at(i).vrect.x = 0;
01185             this->windows.at(i).vrect.y = 0;
01186             this->windows.at(i).vrect.w = 0;
01187             this->windows.at(i).vrect.h = 0;
01188 
01189             /* unlock */
01190             lock.unlock();
01191 
01192             return true;
01193         }
01194 
01195     /* not found */
01196     lock.unlock();
01197     return false;
01198 }
01199 
01200 bool MMSFBWindowManager::setWindowVisibleRectangle(MMSFBWindow *window, MMSFBRectangle *rect) {
01201     bool ret = false;
01202 
01203     // check if initialized
01204     INITCHECK;
01205 
01206     // stop parallel processing
01207     lock.lock();
01208 
01209     // search for item in available list
01210     for (unsigned int i=0; i < this->windows.size(); i++)
01211         if (this->windows.at(i).window == window) {
01212             // set rect
01213             if (rect) {
01214                 this->windows.at(i).vrect = *rect;
01215             }
01216             else {
01217                 this->windows.at(i).vrect.x = 0;
01218                 this->windows.at(i).vrect.y = 0;
01219                 this->windows.at(i).vrect.w = 0;
01220                 this->windows.at(i).vrect.h = 0;
01221             }
01222 
01223             ret = true;
01224             break;
01225         }
01226 
01227     // search for item in visible list
01228     for (unsigned int i=0; i < this->vwins.size(); i++)
01229         if (this->vwins.at(i).window == window) {
01230             // reload windows config
01231             loadWindowConfig(window, &(this->vwins.at(i)));
01232 
01233             PRINT_LOCK("flipSurface");
01234             // redraw the window
01235             flipSurface(this->vwins.at(i).surface, NULL, true);
01236             PRINT_LOCK("end flipSurface");
01237 
01238             ret = true;
01239             break;
01240         }
01241 
01242     lock.unlock();
01243     return ret;
01244 }
01245 
01246 bool MMSFBWindowManager::getWindowVisibleRectangle(MMSFBWindow *window, MMSFBRectangle *rect) {
01247     bool ret = false;
01248 
01249     // check if initialized
01250     INITCHECK;
01251 
01252     // stop parallel processing
01253     lock.lock();
01254 
01255     // search for item in available list
01256     for (unsigned int i=0; i < this->windows.size(); i++)
01257         if (this->windows.at(i).window == window) {
01258             // set rect
01259             if (rect) *rect = this->windows.at(i).vrect;
01260             if ((this->windows.at(i).vrect.w > 0)&&(this->windows.at(i).vrect.h > 0))
01261                 ret = true;
01262             break;
01263         }
01264 
01265     lock.unlock();
01266     return ret;
01267 }
01268 
01269 bool MMSFBWindowManager::getScreenshot(MMSFBWindow *window) {
01270     bool ret = false;
01271 
01272     // check if initialized
01273     INITCHECK;
01274 
01275     // stop parallel processing
01276     lock.lock();
01277 
01278     // search for item in available list
01279     for (unsigned int i=0; i < this->windows.size(); i++)
01280         if (this->windows.at(i).window == window) {
01281             // window found, hide the window if shown
01282             bool shown = window->isShown();
01283             window->hide();
01284 
01285             // switch the dst_surface
01286             MMSFBSurface *saved_suf = this->dst_surface;
01287             if (window->getSurface(&this->dst_surface)) {
01288                 // draw the complete screen to the surface of the window
01289                 MMSFBRegion region;
01290                 this->dst_surface->getSize(&region.x2, &region.y2);
01291                 region.x1 = 0;
01292                 region.y1 = 0;
01293                 region.x2-= 1;
01294                 region.y2-= 1;
01295                 PRINT_LOCK("flipSurface");
01296                 flipSurface(NULL, &region, true, false);
01297                 PRINT_LOCK("end flipSurface");
01298             }
01299 
01300             // restore the dst_surface
01301             this->dst_surface = saved_suf;
01302 
01303             // show the window again
01304             if (shown)
01305                 window->show();
01306 
01307             ret = true;
01308             break;
01309         }
01310 
01311     lock.unlock();
01312     return ret;
01313 }
01314 
01315 
01316 void MMSFBWindowManager::setPointerPosition(int pointer_posx, int pointer_posy, bool pressed) {
01317     // changed?
01318     if (this->button_pressed == pressed)
01319         if ((this->pointer_posx == pointer_posx)&&(this->pointer_posy == pointer_posy))
01320             return;
01321     this->button_pressed = pressed;
01322 
01323     switch (this->layer_pixelformat) {
01324     case MMSFB_PF_YV12:
01325     case MMSFB_PF_I420:
01326         // use even pointer position for this pixelformats
01327         this->pointer_posx = pointer_posx & ~0x01;
01328         this->pointer_posy = pointer_posy & ~0x01;
01329         break;
01330     default:
01331         // use normal odd/even positions
01332         this->pointer_posx = pointer_posx;
01333         this->pointer_posy = pointer_posy;
01334         break;
01335     }
01336 
01337     // do nothing more if pointer will not be shown
01338     if (!this->show_pointer)
01339         return;
01340 
01341     // surface of pointer initialized?
01342     if (!this->pointer_surface)
01343         if (!loadPointer()) {
01344             // not loaded, set a primitive pointer
01345             this->pointer_rect.w = 21;
01346             this->pointer_rect.h = 21;
01347             if (this->layer->createSurface(&this->pointer_surface, this->pointer_rect.w, this->pointer_rect.h)) {
01348                 pointer_surface->lock();
01349                 this->pointer_surface->clear();
01350                 this->pointer_surface->setColor(255,255,255,255);
01351                 this->pointer_surface->drawLine(0,this->pointer_rect.h/2,this->pointer_rect.w-1,this->pointer_rect.h/2);
01352                 this->pointer_surface->drawLine(this->pointer_rect.w/2,0,this->pointer_rect.w/2,this->pointer_rect.h-1);
01353                 pointer_surface->unlock();
01354             }
01355             else
01356                 this->pointer_surface = NULL;
01357         }
01358 
01359     // save the old region
01360     MMSFBRegion old_region = this->pointer_region;
01361 
01362     // set the rectangle/region position
01363     this->pointer_rect.x = this->pointer_posx - (this->pointer_rect.w >> 1);
01364     this->pointer_rect.y = this->pointer_posy - (this->pointer_rect.h >> 1);
01365     this->pointer_region.x1 = this->pointer_rect.x;
01366     this->pointer_region.y1 = this->pointer_rect.y;
01367     this->pointer_region.x2 = this->pointer_rect.x + this->pointer_rect.w - 1;
01368     this->pointer_region.y2 = this->pointer_rect.y + this->pointer_rect.h - 1;
01369 
01370     // set opacity
01371     this->pointer_opacity = 255;
01372     this->pointer_fadecnt = 0;
01373 
01374     // check if i have to flip one or two regions
01375     if   ((old_region.x1 > this->pointer_region.x2)
01376         ||(old_region.y1 > this->pointer_region.y2)
01377         ||(old_region.x2 < this->pointer_region.x1)
01378         ||(old_region.y2 < this->pointer_region.y1)) {
01379         // two regions to be updated
01380         PRINT_LOCK("flipSurface");
01381         flipSurface(NULL, &this->pointer_region, false);
01382         PRINT_LOCK("end flipSurface");
01383         if (old_region.x1 != old_region.x2) {
01384             PRINT_LOCK("flipSurface");
01385             flipSurface(NULL, &old_region, false);
01386             PRINT_LOCK("end flipSurface");
01387         }
01388     }
01389     else {
01390         // one region
01391         if (old_region.x1 > this->pointer_region.x1)
01392             old_region.x1 = this->pointer_region.x1;
01393         else
01394             old_region.x2 = this->pointer_region.x2;
01395         if (old_region.y1 > this->pointer_region.y1)
01396             old_region.y1 = this->pointer_region.y1;
01397         else
01398             old_region.y2 = this->pointer_region.y2;
01399         PRINT_LOCK("flipSurface");
01400         flipSurface(NULL, &old_region, false);
01401         PRINT_LOCK("end flipSurface");
01402     }
01403 }
01404 
01405 bool MMSFBWindowManager::getPointerPosition(int &pointer_posx, int &pointer_posy) {
01406     // set?
01407     if ((this->pointer_posx<0)||(this->pointer_posy<0))
01408         return false;
01409     pointer_posx = this->pointer_posx;
01410     pointer_posy = this->pointer_posy;
01411     return true;
01412 }
01413 
01414 bool MMSFBWindowManager::loadPointer() {
01415     string imagefile = (string)getPrefix() + "/share/disko/mmsgui/mmspointer.png";
01416 
01417     // try to read from taff?
01418     if (this->usetaff) {
01419         // yes, try with taff
01420         // assume: the taffpf (supported taff pixelformat) is correctly set
01421         // first : try to read taff image without special pixelformat
01422         // second: try with pixelformat from my surfaces
01423         bool retry = false;
01424         do {
01425             MMSTaffFile *tafff;
01426             if (retry) {
01427                 retry = false;
01428                 DEBUGOUT("MMSFBWindowManager, retry\n");
01429                 // have to convert taff with special destination pixelformat
01430                 tafff = new MMSTaffFile(imagefile + ".taff", NULL,
01431                                         "", MMSTAFF_EXTERNAL_TYPE_IMAGE);
01432                 if (tafff) {
01433                     // set external file and requested pixelformat
01434                     tafff->setExternal(imagefile, MMSTAFF_EXTERNAL_TYPE_IMAGE);
01435                     DEBUGOUT("MMSFBWindowManager, taffpf = %d\n", taffpf);
01436                     tafff->setDestinationPixelFormat(taffpf);
01437                     // convert it
01438                     if (!tafff->convertExternal2TAFF()) {
01439                         // conversion failed
01440                         delete tafff;
01441                         break;
01442                     }
01443                     delete tafff;
01444                 }
01445             }
01446 
01447             // load image
01448             tafff = new MMSTaffFile(imagefile + ".taff", NULL,
01449                                     imagefile, MMSTAFF_EXTERNAL_TYPE_IMAGE);
01450 
01451             if (tafff) {
01452                 if (tafff->isLoaded()) {
01453 
01454                     // load the attributes
01455                     int         attrid;
01456                     char        *value_str;
01457                     int         value_int;
01458                     void        *img_buf = NULL;
01459                     int         img_width = 0;
01460                     int         img_height= 0;
01461                     int         img_pitch = 0;
01462                     int         img_size  = 0;
01463                     MMSTAFF_PF  img_pixelformat = MMSTAFF_PF_ARGB;
01464                     bool        img_premultiplied = true;
01465                     int         img_mirror_size = 0;
01466 
01467                     while ((attrid=tafff->getNextAttribute(&value_str, &value_int, NULL))>=0) {
01468                         switch (attrid) {
01469                         case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_width:
01470                             img_width = value_int;
01471                             break;
01472                         case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_height:
01473                             img_height = value_int;
01474                             break;
01475                         case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_pitch:
01476                             img_pitch = value_int;
01477                             break;
01478                         case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_size:
01479                             img_size = value_int;
01480                             break;
01481                         case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_data:
01482                             img_buf = value_str;
01483                             break;
01484                         case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_pixelformat:
01485                             img_pixelformat = (MMSTAFF_PF)value_int;
01486                             break;
01487                         case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_premultiplied:
01488                             img_premultiplied = (value_int);
01489                             break;
01490                         case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_mirror_size:
01491                             img_mirror_size = value_int;
01492                             break;
01493                         }
01494                     }
01495 
01496                     if (img_pixelformat != taffpf) {
01497                         DEBUGOUT("MMSFBWindowManager, taffpf = %d\n", (int)taffpf);
01498                         // the image from the file has not the same pixelformat as the surface
01499                         if (!retry) {
01500                             // retry with surface pixelformat
01501                             DEBUGOUT("MMSFBWindowManager, request new pixf\n");
01502                             retry = true;
01503                             delete tafff;
01504                             continue;
01505                         }
01506                         else
01507                             retry = false;
01508                     }
01509                     else
01510                     if ((img_width)&&(img_height)&&(img_pitch)&&(img_size)&&(img_buf)) {
01511                         // successfully read, create a surface
01512                         if (!this->layer->createSurface(&this->pointer_surface, img_width, img_height, this->pixelformat)) {
01513                             DEBUGMSG("MMSFB", "cannot create surface for image file '%s'", imagefile.c_str());
01514                             return false;
01515                         }
01516 
01517                         this->pointer_surface->lock();
01518                         // blit from external buffer to surface
01519                         this->pointer_surface->blitBuffer(img_buf, img_pitch, this->pixelformat,
01520                                                             img_width, img_height, NULL, 0, 0);
01521                         this->pointer_surface->unlock();
01522 
01523                         // free
01524                         delete tafff;
01525 
01526                         DEBUGMSG("MMSFB", "MMSFBWindowManager has loaded: '%s'", imagefile.c_str());
01527 
01528                         // set pointer width & height
01529                         this->pointer_rect.w = img_width;
01530                         this->pointer_rect.h = img_height;
01531 
01532                         return true;
01533                     }
01534                 }
01535 
01536                 // free
01537                 delete tafff;
01538             }
01539         } while (retry);
01540     }
01541 
01542 
01543 #ifdef  __HAVE_DIRECTFB__
01544     IDirectFBImageProvider *imageprov = NULL;
01545     DFBSurfaceDescription   surface_desc;
01546 
01547     // create image provider
01548     if (!mmsfb->createImageProvider(&imageprov, imagefile)) {
01549         if (imageprov)
01550             imageprov->Release(imageprov);
01551         return false;
01552     }
01553 
01554     // get surface description
01555     if (imageprov->GetSurfaceDescription(imageprov, &surface_desc)!=DFB_OK) {
01556         imageprov->Release(imageprov);
01557         return false;
01558     }
01559 
01560     // create a surface
01561     if (!this->layer->createSurface(&this->pointer_surface, surface_desc.width, surface_desc.height)) {
01562         imageprov->Release(imageprov);
01563         return false;
01564     }
01565 
01566     // render to the surface
01567     if (imageprov->RenderTo(imageprov, (IDirectFBSurface *)this->pointer_surface->getDFBSurface(), NULL)!=DFB_OK) {
01568         imageprov->Release(imageprov);
01569         delete this->pointer_surface;
01570         return false;
01571     }
01572 
01573     // release imageprovider
01574     imageprov->Release(imageprov);
01575 
01576     // set pointer width & height
01577     this->pointer_rect.w = surface_desc.width;
01578     this->pointer_rect.h = surface_desc.height;
01579     return true;
01580 #endif
01581 
01582     return false;
01583 }
01584 
01585 void MMSFBWindowManager::drawPointer(MMSFBRegion *region) {
01586     // should draw the pointer?
01587     if (!this->show_pointer)
01588         return;
01589     if ((this->pointer_posx<0)||(this->pointer_posy<0))
01590         return;
01591     if (!this->pointer_surface)
01592         return;
01593     if (this->pointer_opacity == 0)
01594         return;
01595 
01596     this->layer_surface->lock();
01597     this->pointer_surface->lock();
01598 
01599     // blit the pointer surface with given opacity
01600     if (this->pointer_opacity < 255) {
01601         this->layer_surface->setBlittingFlags((MMSFBBlittingFlags) (MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA));
01602         this->layer_surface->setColor(0, 0, 0, this->pointer_opacity);
01603     }
01604     else
01605         this->layer_surface->setBlittingFlags((MMSFBBlittingFlags) MMSFB_BLIT_BLEND_ALPHACHANNEL);
01606     this->layer_surface->blit(this->pointer_surface, NULL, this->pointer_rect.x, this->pointer_rect.y);
01607     this->layer_surface->setBlittingFlags((MMSFBBlittingFlags) MMSFB_BLIT_NOFX);
01608     this->layer_surface->setColor(0, 0, 0, 0);
01609     this->pointer_surface->unlock();
01610     this->layer_surface->unlock();
01611 }
01612 
01613 unsigned char MMSFBWindowManager::getPointerOpacity() {
01614     return this->pointer_opacity;
01615 }
01616 
01617 void MMSFBWindowManager::setPointerOpacity(unsigned char opacity) {
01618     // set it
01619     this->pointer_opacity = opacity;
01620     this->pointer_fadecnt = 0;
01621     PRINT_LOCK("flipSurface");
01622     flipSurface(NULL, &this->pointer_region, false);
01623     PRINT_LOCK("end flipSurface");
01624 }
01625 
01626 void MMSFBWindowManager::fadePointer() {
01627     if (!this->button_pressed) {
01628         if (this->pointer_opacity > 0) {
01629             if (this->pointer_fadecnt == 0)
01630                 this->pointer_fadecnt = 1;
01631             else
01632                 this->pointer_fadecnt*= 3;
01633 
01634             if (this->pointer_fadecnt >= 3) {
01635                 // set it
01636                 if (this->pointer_opacity > this->pointer_fadecnt / 3)
01637                     this->pointer_opacity-= this->pointer_fadecnt / 3;
01638                 else
01639                     this->pointer_opacity = 0;
01640                 PRINT_LOCK("flipSurface");
01641                 flipSurface(NULL, &this->pointer_region, false);
01642                 PRINT_LOCK("end flipSurface");
01643             }
01644         }
01645     }
01646 }
01647 

Generated by doxygen