00001 /*************************************************************************** 00002 * Copyright (C) 2005-2007 Stefan Schwarzer, Jens Schneider, * 00003 * Matthias Hardt, Guido Madaus * 00004 * * 00005 * Copyright (C) 2007-2008 BerLinux Solutions GbR * 00006 * Stefan Schwarzer & Guido Madaus * 00007 * * 00008 * Copyright (C) 2009-2013 BerLinux Solutions GmbH * 00009 * * 00010 * Authors: * 00011 * Stefan Schwarzer <stefan.schwarzer@diskohq.org>, * 00012 * Matthias Hardt <matthias.hardt@diskohq.org>, * 00013 * Jens Schneider <jens.schneider@diskohq.org>, * 00014 * Guido Madaus <guido.madaus@diskohq.org>, * 00015 * Patrick Helterhoff <patrick.helterhoff@diskohq.org>, * 00016 * René Bählkow <rene.baehlkow@diskohq.org> * 00017 * * 00018 * This library is free software; you can redistribute it and/or * 00019 * modify it under the terms of the GNU Lesser General Public * 00020 * License version 2.1 as published by the Free Software Foundation. * 00021 * * 00022 * This library is distributed in the hope that it will be useful, * 00023 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00025 * Lesser General Public License for more details. * 00026 * * 00027 * You should have received a copy of the GNU Lesser General Public * 00028 * License along with this library; if not, write to the * 00029 * Free Software Foundation, Inc., * 00030 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * 00031 **************************************************************************/ 00032 00033 #include "mmsgui/mmslabelwidgetthread.h" 00034 00035 MMSLabelWidgetThread::MMSLabelWidgetThread(MMSLabelWidget *label) { 00036 this->label = label; 00037 this->inWait = false; 00038 this->stopThread = false; 00039 this->pauseThread = false; 00040 } 00041 00042 void MMSLabelWidgetThread::wait(unsigned int delaytime) { 00043 this->inWait = true; 00044 usleep(delaytime); 00045 while (this->pauseThread) 00046 usleep(1000); 00047 this->inWait = false; 00048 } 00049 00050 void MMSLabelWidgetThread::stop() { 00051 while (!this->inWait) 00052 usleep(1000); 00053 this->stopThread = true; 00054 while (isRunning()) 00055 usleep(1000); 00056 } 00057 00058 void MMSLabelWidgetThread::pause(bool pauseThread) { 00059 if (pauseThread) { 00060 while (!this->inWait) 00061 usleep(1000); 00062 this->pauseThread = true; 00063 } 00064 else { 00065 this->pauseThread = false; 00066 } 00067 } 00068 00069 void MMSLabelWidgetThread::doIt() { 00070 00071 // init 00072 this->inWait = false; 00073 this->stopThread = false; 00074 this->pauseThread = false; 00075 int refresh_frame_delay = 0; 00076 int pixel_shift = 1; 00077 int refresh_time = 0; 00078 00079 // maximum cpy usage in percent 00080 int max_cpu_usage = 33; 00081 00082 while (1) { 00083 /* first check if the window is shown */ 00084 MMSWindow *win = this->label->getRootWindow(); 00085 if (!win) { 00086 wait(1000000); 00087 if (this->stopThread) 00088 return; 00089 else 00090 continue; 00091 } 00092 if (!win->isShown(true)) { 00093 wait(1000000); 00094 if (this->stopThread) 00095 return; 00096 else 00097 continue; 00098 } 00099 00100 bool changed = false; 00101 if (label->getSlidable()) { 00102 if (label->slide_width > 0) { 00103 MMSFBRectangle surfaceGeom = label->getSurfaceGeometry(); 00104 if (label->slide_width > surfaceGeom.w) { 00105 // we should slide the label text 00106 if (label->slide_offset >= label->slide_width) 00107 // from the beginning 00108 label->slide_offset = -surfaceGeom.w; 00109 else 00110 // increase offset 00111 label->slide_offset+=pixel_shift; 00112 changed = true; 00113 } 00114 } 00115 } 00116 00117 // refresh the widget 00118 if (changed) { 00119 unsigned int start_ts; 00120 unsigned int end_ts; 00121 00122 // get start timestamp if needed 00123 if (!this->label->frame_delay_set) 00124 start_ts = getMTimeStamp(); 00125 00126 // refresh is required 00127 this->label->enableRefresh(); 00128 00129 // update screen 00130 this->label->refresh(); 00131 00132 // recalc speed parameters? 00133 if (!this->label->frame_delay_set) { 00134 // get refresh duration 00135 end_ts = getMTimeStamp(); 00136 if (!refresh_time) 00137 refresh_time = getMDiff(start_ts, end_ts); 00138 else 00139 refresh_time = (refresh_time * 2 + getMDiff(start_ts, end_ts)) / 3; 00140 00141 // calc shift and frame delay 00142 int slide_speed = label->getSlideSpeed(); 00143 if (slide_speed <= 0) slide_speed = 1; 00144 if (slide_speed > 255) slide_speed = 255; 00145 int max_sleep_time = 1000 / slide_speed; 00146 int total_time = (refresh_time * 100) / max_cpu_usage; 00147 pixel_shift = total_time / max_sleep_time; 00148 if (total_time % max_sleep_time) pixel_shift++; 00149 this->label->frame_delay = max_sleep_time * pixel_shift - refresh_time - pixel_shift; 00150 if (this->label->frame_delay <= 0) this->label->frame_delay = 1; 00151 00152 // mark as calculated 00153 this->label->frame_delay_set = true; 00154 } 00155 else { 00156 // recalc not needed 00157 refresh_frame_delay++; 00158 if (refresh_frame_delay >= 50) { 00159 // after 50 times, recalc requested 00160 refresh_frame_delay = 0; 00161 this->label->frame_delay_set = false; 00162 } 00163 } 00164 } 00165 00166 // sleep 00167 if (this->label->frame_delay > 0) 00168 wait(this->label->frame_delay*1000); 00169 else 00170 wait(1000000); 00171 if (this->stopThread) 00172 return; 00173 } 00174 } 00175 00176 void MMSLabelWidgetThread::threadMain() { 00177 doIt(); 00178 delete this; 00179 } 00180