recording.o channel.o message.o playervideo.o playerradio.o messagequeue.o \
view.o vinfo.o vwallpaper.o vvolume.o vrecordinglist.o vlivebanner.o vmute.o \
vrecordingmenu.o vquestion.o vchannellist.o vwelcome.o vvideolive.o vvideorec.o vradiolive.o \
- vchannelselect.o vserverselect.o colour.o vconnect.o voptions.o \
+ vchannelselect.o vserverselect.o colour.o vconnect.o voptions.o region.o \
widget.o wselectlist.o wjpeg.o wsymbol.o wbutton.o woptionbox.o i18n.o \
fonts/helvB24.o fonts/helvB18.o
Box::Box()
{
- height = 0;
- width = 0;
+ area.x = 0;
+ area.y = 0;
+ area.w = 0;
+ area.h = 0;
- screenX = 0;
- screenY = 0;
offsetX = 0;
offsetY = 0;
void Box::setScreenPos(int x, int y)
{
- screenX = x;
- screenY = y;
+ area.x = x;
+ area.y = y;
}
void Box::setSurfaceOffset(UINT x, UINT y)
offsetY = y;
}
-void Box::show(int noBufferToScreen)
+void Box::show()
{
- Log::getInstance()->log("Box", Log::DEBUG, "Show data %p %u %u %u %u %u", surface, screenX, screenY, width, height, noBufferToScreen);
- surface->updateToBuffer(screenX, screenY, width, height);
- if (!noBufferToScreen) Surface::bufferToScreen(screenX, screenY, width, height);
+ show(area);
+}
+
+void Box::show(Region& r)
+{
+ Log::getInstance()->log("Box", Log::DEBUG, "Show region %p %u %u %u %u", surface, r.x, r.y, r.w, r.h);
+// surface->updateToScreen(area.x, area.y, area.w, area.h);
+
+ /* surface update to screen needs:
+ source x distance into this surface
+ source y distance into this surface
+ width of update
+ height of update
+ destination x on screen
+ destination y on screen
+ */
+
+ surface->updateToScreen(r.x - area.x, r.y - area.y, r.w, r.h, r.x, r.y);
}
int Box::getScreenX()
{
- return screenX;
+ return area.x;
}
int Box::getScreenY()
{
- return screenY;
+ return area.y;
}
int Box::getWidth()
{
- return width;
+ return area.w;
}
int Box::getHeight()
{
- return height;
+ return area.h;
}
// Level 1 drawing functions
void Box::fillColour(Colour& colour)
{
- rectangle(0, 0, width, height, colour);
+ rectangle(0, 0, area.w, area.h, colour);
}
void Box::drawPara(char* text, int x, int y, Colour& colour)
}
thisCharWidth = surface->getCharWidth(text[textPos]);
- if ((lineWidth + thisCharWidth) > (int)(width - (2 * paraMargin)))
+ if ((lineWidth + thisCharWidth) > (int)(area.w - (2 * paraMargin)))
{
// this character would break the right margin
if (text[textPos] == ' ')
{
drawText(line, x, ypos, colour);
ypos += lineHeight;
- if (ypos > (int)(height - lineHeight)) break;
+ if (ypos > (int)(area.h - lineHeight)) break;
}
else
{
#include "log.h"
#include "colour.h"
#include "surface.h"
+#include "region.h"
// Abstract ???????
class Box
void setScreenPos(int x, int y);
void setSurfaceOffset(UINT x, UINT y);
- void show(int noBufferToScreen = 0);
+ void show();
+ void show(Region& r);
virtual void draw();
int getWidth();
int getHeight();
+ // so viewman can read it:
+ Region area;
+ Surface* surface; // temp - is there a get function for this? FIXME
private:
protected:
- Surface* surface;
+
+
+/*
UINT width;
UINT height;
int screenX;
int screenY;
+*/
UINT offsetX;
UINT offsetY;
{
I18n::Initialize();
Video* video = Video::getInstance();
- viewman->removeView(vconnect, 0, 1);
+ viewman->removeView(vconnect, 0);
VInfo* vi = new VInfo();
vi->create(400, 200);
shutdown(1);
}
- success = osd->init("/dev/stbgfx", 1);
+ success = osd->init("/dev/stbgfx");
if (success)
{
logger->log("Core", Log::INFO, "OSD module initialised");
const static ULONG CLOSE_ME = 2;
const static ULONG PLAY_SELECTED_RECORDING = 3;
const static ULONG DELETE_SELECTED_RECORDING = 4;
- const static ULONG UPDATE_SCREEN = 5;
- const static ULONG SWAP_ME_FOR = 6;
- const static ULONG CHANNEL_CHANGE = 7;
- const static ULONG RESUME_SELECTED_RECORDING = 8;
- const static ULONG STANDBY = 9;
- const static ULONG STOP_PLAYBACK = 10;
- const static ULONG SERVER_SELECTED = 11;
- const static ULONG VDR_CONNECTED = 12;
- const static ULONG REDRAW_DATA = 13;
- const static ULONG ADD_VIEW = 14;
- const static ULONG CHANNEL_UP = 15;
- const static ULONG CHANNEL_DOWN = 16;
- const static ULONG STREAM_END = 17;
- const static ULONG CHILD_CLOSE = 18;
+ const static ULONG SWAP_ME_FOR = 5;
+ const static ULONG CHANNEL_CHANGE = 6;
+ const static ULONG RESUME_SELECTED_RECORDING = 7;
+ const static ULONG STANDBY = 8;
+ const static ULONG STOP_PLAYBACK = 9;
+ const static ULONG SERVER_SELECTED = 10;
+ const static ULONG VDR_CONNECTED = 11;
+ const static ULONG REDRAW_DATA = 12;
+ const static ULONG ADD_VIEW = 13;
+ const static ULONG CHANNEL_UP = 14;
+ const static ULONG CHANNEL_DOWN = 15;
+ const static ULONG STREAM_END = 16;
+ const static ULONG CHILD_CLOSE = 17;
};
#endif
fdOsd = 0;
screen = NULL;
- buffer = NULL;
}
Osd::~Osd()
return fdOsd;
}
-int Osd::init(char* device, int doubleBuffering)
+int Osd::init(char* device)
{
if (initted) return 0;
screen->create(video->getScreenWidth(), video->getScreenHeight());
screen->display();
- if (doubleBuffering)
- {
- buffer = new Surface(Surface::BUFFER);
- buffer->create(video->getScreenWidth(), video->getScreenHeight());
- }
- else
- {
- Surface::disableBuffer();
- }
-
return 1;
}
{
if (!initted) return 0;
initted = 0;
- if (buffer) delete buffer;
delete screen;
close(fdOsd);
return 1;
~Osd();
static Osd* getInstance();
- int init(char* device, int doubleBuffering);
+ int init(char* device);
int shutdown();
int getFD();
private:
static Osd* instance;
int initted;
-
Surface* screen;
- Surface* buffer;
-
int fdOsd;
};
--- /dev/null
+#include "region.h"
+
+Region::Region()
+{
+ x = 0;
+ y = 0;
+ w = 0;
+ h = 0;
+ z = 0;
+}
+
+bool Region::overlappedBy(Region& d)
+{
+ return
+ ( (d.x2() >= x) &&
+ (d.x <= x2()) &&
+ (d.y <= y2()) &&
+ (d.y2() >= y) );
+}
+
+UINT Region::x2()
+{
+ return x + w - 1;
+}
+
+UINT Region::y2()
+{
+ return y + h - 1;
+}
+/*
+Region Region::subtract(Region& other)
+{
+ printf("This: %i %i %i %i\n", x, y, w, h);
+ printf("Subtract this: %i %i %i %i\n", other.x, other.y, other.w, other.h);
+
+
+ Region s;
+
+ if (x < other.x)
+ {
+ printf("Case 1\n");
+ s.x = x;
+ s.y = y;
+ s.w = other.x - x;
+ s.h = h;
+ }
+ else if (x2() > other.x2())
+ {
+ printf("Case 2\n");
+ s.x = other.x2()+1;
+ s.y = y;
+ s.w = w - s.x;
+ s.h = h;
+ }
+ else if (y < other.y)
+ {
+ printf("Case 3\n");
+ s.x = x;
+ s.y = y;
+ s.w = w;
+ s.h = other.y - y;
+ }
+ else if (y2() > other.y2())
+ {
+ printf("Case 4\n");
+ s.x = x;
+ s.y = other.y2()+1;
+ s.w = w;
+ s.h = h - s.y;
+ }
+ else
+ {
+ s.x = 0;
+ s.y = 0;
+ s.w = 0;
+ s.h = 0;
+ }
+ printf("Result: %i %i %i %i\n", s.x, s.y, s.w, s.h);
+
+ return s;
+}
+*/
+
+ //i.x = (x >= other.x ? x : other.x);
+ //i.y = (y >= other.y ? y : other.y);
+ //i.w = (x2() <= other.x2() ? x2() : other.x2()) - i.x;
+ //i.h = (y2() <= other.y2() ? y2() : other.y2()) - i.y;
+ //return i;
--- /dev/null
+#ifndef REGION_H
+#define REGION_H
+
+#include <stdio.h>
+#include "defines.h"
+
+class Region
+{
+ public:
+ Region();
+ bool overlappedBy(Region& doesthisOverlap);
+// Region subtract(Region& other);
+ UINT x2();
+ UINT y2();
+
+ UINT x;
+ UINT y;
+ UINT w;
+ UINT h;
+ int z;
+};
+
+#endif
#include "osd.h"
Surface* Surface::screen = NULL;
-Surface* Surface::buffer = NULL;
-int Surface::disableDoubleBuffering = 0;
osd_font_t* Surface::font = &font_helvB18;
Surface::Surface(int id)
{
if (id == SCREEN) screen = this;
- if (id == BUFFER) buffer = this;
fdOsd = Osd::getInstance()->getFD();
memset(&surface, 0, sizeof(osd_surface_t));
}
-void Surface::disableBuffer()
+Surface* Surface::getScreen()
{
- disableDoubleBuffering = 1;
-}
-
-Surface* Surface::getObject(int id)
-{
- if (id == SCREEN) return screen;
- if (disableDoubleBuffering) return screen;
- if (id == BUFFER) return buffer;
- return NULL;
+ return screen;
}
int Surface::create(UINT width, UINT height)
fillblt(x, y1, 1, y2-y1, c);
}
-void Surface::bufferToScreen() // static, this is for Box::showAll
-{
- if (disableDoubleBuffering) return;
-
- Log::getInstance()->log("Surface", Log::DEBUG, "Full buffer to screen");
- bufferToScreen(0, 0, buffer->surface.sfc.width, buffer->surface.sfc.height);
-}
-//int Surface::updateToScreen(int x, int y, int width, int height) // main method for all normal windows
-//{
- /*
- With double buffering:
- A view has buffer for its surface. this is buffer, copy area specified to screen
- Without double buffering:
- A view has screen for its surface. this is screen, all painting work has already been done. ignore
+ /* surface update to screen needs:
+ source x distance into this surface
+ source y distance into this surface
+ width of update
+ height of update
+ destination x on screen
+ destination y on screen
*/
-
-// if (this == screen) return 0;
-//
-// return blt(fdOsd, surface.sfc.handle, x, y, width, height, screen->getSurfaceHandle(), x, y);
-//}
-
-int Surface::bufferToScreen(int x, int y, int width, int height) // static
-{
- return blt(Osd::getInstance()->getFD(), buffer->getSurfaceHandle(), x, y, width, height, screen->getSurfaceHandle(), x, y);
-}
-
-int Surface::updateToBuffer(int x, int y, int width, int height) // main method for all normal windows
+int Surface::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME
{
- return blt(fdOsd, surface.sfc.handle, 0, 0, width, height, buffer->getSurfaceHandle(), x, y);
+ return blt(fdOsd, surface.sfc.handle, sx, sy, w, h, screen->getSurfaceHandle(), dx, dy);
}
int Surface::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)
Surface(int id = 0);
~Surface();
- static Surface* getObject(int id);
- static int bufferToScreen(int x, int y, int width, int height);
+ static Surface* getScreen();
static int getFontHeight();
int create(UINT width, UINT height);
void drawPixel(int x, int y, unsigned int c);
void drawHorzLine(int x1, int x2, int y, unsigned int c);
void drawVertLine(int x, int y1, int y2, unsigned int c);
- int updateToBuffer(int x, int y, int width, int height);
+ int updateToScreen(int sx, int sy, int w, int h, int dx, int dy);
+
int drawText(char* text, int x, int y, int r, int g, int b);
int drawTextRJ(char* text, int x, int y, int r, int g, int b);
int getCharWidth(char c);
static void initConversionTables();
- static void disableBuffer();
- static void bufferToScreen();
static int blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy);
const static int SCREEN = 1;
private:
static Surface* screen;
- static Surface* buffer;
- static int disableDoubleBuffering;
static osd_font_t* font;
int fdOsd;
sl.setSurface(surface);
sl.setSurfaceOffset(10, 30 + 5);
- sl.setDimensions(width - 20, height - 30 - 15 - 30);
+ sl.setDimensions(area.w - 20, area.h - 30 - 15 - 30);
}
VChannelList::~VChannelList()
View::View()
{
- width = 0;
- height = 0;
- screenX = 0;
- screenY = 0;
-
delSec = 0;
delNSec = 0;
seconds = 0;
bool View::create(UINT w, UINT h)
{
- width = w;
- height = h;
+ area.w = w;
+ area.h = h;
surface = new Surface();
- return surface->create(width, height);
+ return surface->create(area.w, area.h);
}
void View::setTitleText(char* takeText)
if (borderOn)
{
- rectangle(0, 0, width, height, titleBarColour);
- rectangle(5, 5, width-10, height-10, backgroundColour);
+ rectangle(0, 0, area.w, area.h, titleBarColour);
+ rectangle(5, 5, area.w-10, area.h-10, backgroundColour);
}
else
{
if (titleBarOn)
{
- rectangle(0, 0, width, 30, titleBarColour);
+ rectangle(0, 0, area.w, 30, titleBarColour);
if (titleText) drawText(titleText, 5, 5, Colour::LIGHTTEXT);
}
}
if (instance) return;
instance = this;
initted = 0;
- topView = 0;
+ numViews = 0;
resetThreadFlag = 0;
autoDeleteThreadRun = 0;
callFromThread = 0;
int ViewMan::add(View* v)
{
if (!initted) return 0;
- if (topView == 10) return 0;
+ if (numViews == 20) return 0;
pthread_mutex_lock(&viewManLock);
- topView++;
- views[topView] = v;
+ views[numViews++] = v;
resetThread();
pthread_mutex_unlock(&viewManLock);
int ViewMan::addNoLock(View* v)
{
if (!initted) return 0;
- if (topView == 10) return 0;
+ if (numViews == 20) return 0;
- topView++;
- views[topView] = v;
+ views[numViews++] = v;
resetThread();
// ---------------------------------------------------- REMOVE CODE
-int ViewMan::removeView(View* toDelete, int noLock, int noShow)
+int ViewMan::removeView(View* toDelete, int noLock)
{
if (!initted) return 0;
- if (topView == 0) return 0;
+ if (numViews == 0) return 0;
if (!noLock) pthread_mutex_lock(&viewManLock);
- Log::getInstance()->log("ViewMan", Log::DEBUG, "entering remove, %u topview", topView);
+ Log::getInstance()->log("ViewMan", Log::DEBUG, "entering remove, numViews=%i", numViews);
int i;
- int wasTopView = 0;
- int slotTakenFrom = 0;
if (toDelete == NULL)
{
- toDelete = views[topView];
- i = topView;
- wasTopView = 1;
+ toDelete = views[numViews-1];
+ i = numViews - 1;
}
else
{
// to be deleted view is more likely to be at the top
-
-
- for (i = topView; i > 0; i--)
+ for (i = numViews-1; i >= 0; i--)
{
- if (views[i] == toDelete)
- {
- if (i == topView) wasTopView = 1;
- break;
- }
+ Log::getInstance()->log("ViewMan", Log::DEBUG, "todel: %p, i=%i, views[i]=%p", toDelete, i, views[i]);
+ if (views[i] == toDelete) break;
}
- if (i == 0)
+ if (i == -1)
{
// not a View we have!
if (!noLock) pthread_mutex_unlock(&viewManLock);
}
}
- // Save the position we are deleting the view from
- slotTakenFrom = i;
+ Log::getInstance()->log("ViewMan", Log::DEBUG, "Starting deleteView");
+ deleteView(i);
+ Log::getInstance()->log("ViewMan", Log::DEBUG, "Done deleteView");
// Shift the views on top down one
- for(; i < topView; i++)
- {
- views[i] = views[i + 1];
- }
- topView--;
+ --numViews;
+ for(int j = i; j < numViews; j++) views[j] = views[j+1];
- // Done. Now on to drawing.
+ // Delete the view
+ delete toDelete;
- View* newTopBox = views[topView]; // just to make second optimisation easier
+ resetThread();
+ if (!noLock) pthread_mutex_unlock(&viewManLock);
+
+ return 1;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// NEW STUFF
+/////////////////////////////////////////////////////////////////////////////
- // First optimisation. If there are no views left, don't do anything!
- if (topView == 0)
+void ViewMan::deleteView(int z)
+{
+ Log::getInstance()->log("ViewMan", Log::DEBUG, "Delete view %i of %i", z, numViews);
+ RegionList rl;
+ boxSplit(views[z]->area, z + 1, numViews, 1, rl);
+ while(!rl.empty())
{
- Log::getInstance()->log("ViewMan", Log::DEBUG, "re-draw using optimisation 1");
+ repaintRevealed(z, rl.front());
+ rl.pop_front();
}
+}
+
+/* For later...
+void ViewMan::update(int z)
+{
+ // get the region for the whole view, could be less than that
+ // for smaller updates
- // second optimisation. if view being deleted is entirely within the view underneath it,
- // and was the top most box,
- // only need to redraw the one underneath
- else if ( wasTopView
- && (toDelete->getScreenX() >= newTopBox->getScreenX())
- && (toDelete->getScreenY() >= newTopBox->getScreenY())
- && ((toDelete->getScreenX() + toDelete->getWidth()) <= (newTopBox->getScreenX() + newTopBox->getWidth()))
- && ((toDelete->getScreenY() + toDelete->getHeight()) <= (newTopBox->getScreenY() + newTopBox->getHeight()))
- )
+ Region r = views[z]->area;
+ RegionList rl;
+
+ r.y += 10;
+
+ Region r2;
+ boxSplit(r, z+1, numViews, 1, rl);
+ while(!rl.empty())
{
- newTopBox->show();
- Log::getInstance()->log("ViewMan", Log::DEBUG, "re-draw using optimisation 2");
+ r2 = rl.front();
+ r2.z = z;
+ views[z]->show(r2);
+ rl.pop_front();
}
+}
+*/
+
+void ViewMan::repaintRevealed(int x, Region r)
+{
+ RegionList rl;
+ boxSplit(r, x - 1, -1, -1, rl);
- // third optimisation. if the box being deleted is totally within one above it, don't do anything
- else if ((slotTakenFrom <= topView) && isTotallyCovered(toDelete, slotTakenFrom))
+ Region r2;
+ while(!rl.empty())
{
- Log::getInstance()->log("ViewMan", Log::DEBUG, "re-draw using optimisation 3");
+ r2 = rl.front();
+ views[r2.z]->show(r2);
+ rl.pop_front();
}
+}
- // no optimisations left, redo everything.
- else
+void ViewMan::boxSplit(Region r, int start, int end, int direction, RegionList& rl)
+{
+// printf("Y= S=%i E=%i D=%i: Boxsplit: %i %i %i %i\n", start, end, direction, r.x, r.y, r.w, r.h);
+
+ for(int z = start; z != end; z += direction)
{
- for (int j = 1; j <= topView; j++)
+ if (r.overlappedBy(views[z]->area))
{
- views[j]->show(1);
- }
- if (!noShow) Surface::bufferToScreen();
+// printf("Z=%i S=%i E=%i D=%i: %i overlaps\n", z, start, end, direction, z);
- Log::getInstance()->log("ViewMan", Log::DEBUG, "re-draw using no optimisation");
- }
+ int top = r.y;
+ int btm = r.y2();
- // Delete the view
- delete toDelete;
+ if (views[z]->area.y > r.y)
+ {
+// printf("Z=%i S=%i E=%i D=%i: Case 1 for %i %i %i %i split by %i: %i %i %i %i\n", z, start, end, direction, r.x, r.y, r.w, r.h, z, views[z]->area.x, views[z]->area.y, views[z]->area.w, views[z]->area.h);
+ top = views[z]->area.y;
+ Region newR;
+ newR.x = r.x;
+ newR.y = r.y;
+ newR.w = r.w;
+ newR.h = views[z]->area.y - r.y;
+ boxSplit(newR, z + direction, end, direction, rl);
+
+ if (direction == -1)
+ {
+ Region newR2;
+ newR2.x = r.x;
+ newR2.y = views[z]->area.y;
+ newR2.w = r.w;
+ newR2.h = r.h - newR.h;
+ boxSplit(newR2, z, end, -1, rl);
+ return;
+ }
+ }
- resetThread();
- if (!noLock) pthread_mutex_unlock(&viewManLock);
+ if (views[z]->area.y2() < r.y2())
+ {
+// printf("Z=%i S=%i E=%i D=%i: Case 2 for %i %i %i %i split by %i: %i %i %i %i\n", z, start, end, direction, r.x, r.y, r.w, r.h, z, views[z]->area.x, views[z]->area.y, views[z]->area.w, views[z]->area.h);
+ btm = views[z]->area.y2();
+ Region newR;
+ newR.x = r.x;
+ newR.y = views[z]->area.y2() + 1;
+ newR.w = r.w;
+ newR.h = r.y2() - newR.y + 1;
+ boxSplit(newR, z + direction, end, direction, rl);
+
+ if (direction == -1)
+ {
+ Region newR2;
+ newR2.x = r.x;
+ newR2.y = r.y;
+ newR2.w = r.w;
+ newR2.h = r.h - newR.h;
+ boxSplit(newR2, z, end, -1, rl);
+ return;
+ }
+ }
- return 1;
-}
+ if (views[z]->area.x > r.x)
+ {
+// printf("Z=%i S=%i E=%i D=%i: Case 3 for %i %i %i %i split by %i: %i %i %i %i\n", z, start, end, direction, r.x, r.y, r.w, r.h, z, views[z]->area.x, views[z]->area.y, views[z]->area.w, views[z]->area.h);
+ Region newR;
+ newR.x = r.x;
+ newR.y = top;
+ newR.w = views[z]->area.x - r.x;
+ newR.h = btm - top + 1;
+ boxSplit(newR, z + direction, end, direction, rl);
+
+ if (direction == -1)
+ {
+ Region newR2;
+ newR2.x = r.x + newR.w;
+ newR2.y = r.y;
+ newR2.w = r.w - newR.w;
+ newR2.h = r.h;
+ boxSplit(newR2, z, end, -1, rl);
+ return;
+ }
+ }
-int ViewMan::isTotallyCovered(View* toDelete, int slotTakenFrom)
-{
- int todelx1 = toDelete->getScreenX();
- int todelx2 = toDelete->getScreenX() + toDelete->getWidth();
- int todely1 = toDelete->getScreenY();
- int todely2 = toDelete->getScreenY() + toDelete->getHeight();
-
- int x1 = 999999;
- int x2 = 0;
- int y1 = 999999;
- int y2 = 0;
-
- int currentx1;
- int currentx2;
- int currenty1;
- int currenty2;
-
- for (int i = slotTakenFrom; i <= topView; i++)
- {
- currentx1 = views[i]->getScreenX();
- currentx2 = currentx1 + views[i]->getWidth();
- currenty1 = views[i]->getScreenY();
- currenty2 = currenty1 + views[i]->getHeight();
+ if (views[z]->area.x2() < r.x2())
+ {
+// printf("Z=%i S=%i E=%i D=%i: Case 4 for %i %i %i %i split by %i: %i %i %i %i\n", z, start, end, direction, r.x, r.y, r.w, r.h, z, views[z]->area.x, views[z]->area.y, views[z]->area.w, views[z]->area.h);
+ Region newR;
+ newR.x = views[z]->area.x2() + 1;
+ newR.y = top;
+ newR.w = r.x2() - newR.x + 1;
+ newR.h = btm - top + 1;
+ boxSplit(newR, z + direction, end, direction, rl);
+
+ if (direction == -1)
+ {
+ Region newR2;
+ newR2.x = r.x;
+ newR2.y = r.y;
+ newR2.w = r.w - newR.w;
+ newR2.h = r.h;
+ boxSplit(newR2, z, end, -1, rl);
+ return;
+ }
+ }
-// printf("Iteration in tc before. i=%i x1=%i x2=%i y1=%i y2=%i cx1=%i cx2=%i cy1=%i cy2=%i\n", i, x1, x2, y1, y2, currentx1, currentx2, currenty1, currenty2);
+ if (direction == -1)
+ {
+ // we are going down the stack
+ // r is underlapped by views[z]
+ // but we have not split
+ // Therefore this region under test is
+ // completely covering views[z]
- if (currentx1 < x1) x1 = currentx1;
- if (currentx2 > x2) x2 = currentx2;
- if (currenty1 < y1) y1 = currenty1;
- if (currenty2 > y2) y2 = currenty2;
+ // don't go any further down, generate a region and quit
-// printf("Iteration in tc after . i=%i x1=%i x2=%i y1=%i y2=%i\n", i, x1, x2, y1, y2);
+// printf("Repaint region: %i %i %i %i\n", r.x, r.y, r.w, r.h);
+ r.z = z;
+ rl.push_front(r);
+ }
+
+// printf("Returning from Z=%i\n", z);
+ return;
+ }
+ else
+ {
+// printf("Z=%i S=%i E=%i D=%i: %i does not overlap\n", z, start, end, direction, z);
+ }
}
- // k, now x1 x2 y1 y2 contain the dimensions of the biggest box over the deleted slot
+ // if direction = 1 then we have come to a region that is
+ // entirely clear of higher views and needs to be redrawn
- if ( (x1 <= todelx1)
- && (x2 >= todelx2)
- && (y1 <= todely1)
- && (y2 >= todely2)
- )
- {
- return 1;
- }
- else
+ // if direction = -1 then we have come to a region that is on
+ // the very bottom with nothing below it to repaint.
+ // do nothing. stale window data will be left on screen?
+
+ if (direction == 1)
{
- return 0;
+ rl.push_front(r);
}
}
+// TEMP
+void ViewMan::drawBlack(Region& r)
+{
+ Surface* surface = Surface::getScreen();
+ surface->fillblt(r.x, r.y, r.w, r.h, surface->rgba(0, 0, 0, 255));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// END NEW STUFF
+/////////////////////////////////////////////////////////////////////////////
+
// ---------------------------------------------------- END OF REMOVE CODE
{
pthread_mutex_lock(&viewManLock);
- // FIXME for don't delete wallpaper cos surface destroy doesn't work
-
- for (; topView > 1; topView--)
+ // 1.. Don't delete wallpaper. No point.
+ for (; numViews > 1; --numViews)
{
- delete views[topView];
+ delete views[numViews-1];
}
- Surface::bufferToScreen();
+// Surface::bufferToScreen();
resetThread();
pthread_mutex_unlock(&viewManLock);
if (command != Remote::NA_NONE)
{
-
// handle command return values
// 0 - drop through to next view
// 1 - dont drop to next view, but not handled
// 2 - handled - stop command here
// 4 - handled - delete this view
- for (i=topView; i>0; i--)
+ for (i=numViews-1; i>=0; i--)
{
+ Log::getInstance()->log("ViewMan", Log::DEBUG, "Giving command to i=%i", i);
retVal = views[i]->handleCommand(command);
if (retVal == 1)
{
// removeNoLock(views[i]);
// Box::showAll();
// resetThread();
+ Log::getInstance()->log("ViewMan", Log::DEBUG, "Return 4: i=%i, views[i]=%p", i, views[i]);
removeView(views[i], 1);
pthread_mutex_unlock(&viewManLock);
retVal2 = 1;
{
if (m->to != this)
{
- for (int i = topView; i > 0; i--)
+ for (int i = numViews-1; i >= 0; i--)
{
if (views[i] == m->to)
{
{
case Message::CLOSE_ME:
{
- removeView((View*)m->from, 1, 1);
- break;
- }
- case Message::UPDATE_SCREEN:
- {
- Surface::bufferToScreen();
+ removeView((View*)m->from, 1);
break;
}
case Message::SWAP_ME_FOR:
{
View* toReplace = (View*) m->parameter;
- removeView((View*)m->from, 1, 1);
+ removeView((View*)m->from, 1);
- topView++;
- views[topView] = toReplace;
+ views[numViews] = toReplace;
+ ++numViews;
if (toReplace->seconds)
{
struct timespec currentTime;
}
toReplace->draw();
toReplace->show();
- Surface::bufferToScreen();
resetThread();
break;
}
nextTime.tv_nsec = 0;
nextToDelete = NULL;
- for(int i = 1; i <= topView; i++)
+ for(int i = 0; i < numViews; i++)
{
if ((views[i]->delSec > 0) && (views[i]->delNSec > 0))
{
#include <time.h>
#include <signal.h>
#include <pthread.h>
+#include <slist>
#include "defines.h"
#include "view.h"
#include "messagequeue.h"
#include "remote.h"
#include "surface.h"
+#include "region.h"
+
+typedef slist<Region> RegionList;
class ViewMan : public MessageQueue
{
// All these reset the thread
int add(View* v);
int addNoLock(View* v);
- int removeView(View* toRemove = NULL, int noLock = 0, int noShow = 0);
+ int removeView(View* toRemove = NULL, int noLock = 0);
void removeAll();
int handleCommand(UCHAR command);
void startAutoDeleteThread3();
private:
- int isTotallyCovered(View* toDelete, int slotTakenFrom);
-
static ViewMan* instance;
int initted;
- View* views[11];
- UCHAR topView;
+ View* views[20];
+ int numViews;
// Threading stuff
void processMessage(Message* m);
+ // New windowing stuff
+ void deleteView(int z);
+ void repaintRevealed(int x, Region r);
+ void boxSplit(Region r, int start, int end, int direction, RegionList& rl);
+ void drawBlack(Region& r);
};
#endif
sl.setSurface(surface);
sl.setSurfaceOffset(0, 30);
- sl.setDimensions(width, height - 60);
+ sl.setDimensions(area.w, area.h - 60);
sl.setNoLoop();
setChannel(channel);
{
View::draw();
sl.draw();
- rectangle(0, height - 30, width, 30, titleBarColour);
+ rectangle(0, area.h - 30, area.w, 30, titleBarColour);
- rectangle(7, height - 24, 18, 16, Colour::RED);
- drawText(tr("info"), 32, height - 25, Colour::LIGHTTEXT);
+ rectangle(7, area.h - 24, 18, 16, Colour::RED);
+ drawText(tr("info"), 32, area.h - 25, Colour::LIGHTTEXT);
}
int VLiveBanner::handleCommand(int command)
sl.setSurface(surface);
sl.setSurfaceOffset(10, 30 + 5);
- sl.setDimensions(width - 20, height - 30 - 15 - 30);
+ sl.setDimensions(area.w - 20, area.h - 30 - 15 - 30);
}
VRecordingList::~VRecordingList()
}
show();
-
-/*
- Message* m2 = new Message();
- m2->from = this;
- m2->to = ViewMan::getInstance();
- m2->message = Message::UPDATE_SCREEN;
- ViewMan::getInstance()->postMessage(m2);
-*/
}
int VRecordingList::doPlay()
sl.setSurface(surface);
sl.setSurfaceOffset(10, 30 + 5);
- sl.setDimensions(width - 20, height - 30 - 15);
+ sl.setDimensions(area.w - 20, area.h - 30 - 15);
sl.addOption(tr("Play"), 1);
sl.addOption(tr("Resume"), 0);
sl.addOption(tr("Summary"), 0);
sl.setSurface(surface);
sl.setSurfaceOffset(10, 30 + 5);
- sl.setDimensions(width - 20, height - 30 - 15);
+ sl.setDimensions(area.w - 20, area.h - 30 - 15);
sl.addOption((*serverIPs)[0], 1);
for(UINT k = 1; k < serverIPs->size(); k++)
void VVideoLive::stop(int noRemoveVLB)
{
if (unavailable) return;
- if (!noRemoveVLB) viewman->removeView(vlb, 1, 1); // if live banner is present, remove it. won't cause damage if its not present
+ if (!noRemoveVLB) viewman->removeView(vlb, 1); // if live banner is present, remove it. won't cause damage if its not present
player->stop();
vdr->stopStreaming();
}
Log::getInstance()->log("VWelcome", Log::DEBUG, "possible delay start");
- viewman->removeView(viewWait, 1, 1);
+ viewman->removeView(viewWait, 1);
Log::getInstance()->log("VWelcome", Log::DEBUG, "possible delay end");
}
Widget::Widget()
{
- width = 0;
- height = 0;
}
Widget::~Widget()
void Widget::setDimensions(int twidth, int theight)
{
- width = twidth;
- height = theight;
+ area.w = twidth;
+ area.h = theight;
}
// MAKE THE 2D ARRAY
- unsigned char* buffer = (unsigned char*)malloc(width * height * 3);
- logger->log("BJpeg", Log::DEBUG, "Buffer allocated at %p, width = %i height = %i", buffer, width, height);
+ unsigned char* buffer = (unsigned char*)malloc(area.w * area.h * 3);
+ logger->log("BJpeg", Log::DEBUG, "Buffer allocated at %p, width = %i height = %i", buffer, area.w, area.h);
- unsigned char* bufferPointers[height];
- for(UINT ps = 0; ps < height; ps++) bufferPointers[ps] = buffer + (ps * width * 3);
+ unsigned char* bufferPointers[area.h];
+ for(UINT ps = 0; ps < area.h; ps++) bufferPointers[ps] = buffer + (ps * area.w * 3);
logger->log("BJpeg", Log::DEBUG, "done array check");
while (cinfo.output_scanline < cinfo.output_height)
{
// logger->log("BJpeg", Log::DEBUG, "%i", rowsread);
- rowsread += jpeg_read_scanlines(&cinfo, &bufferPointers[rowsread], height);
+ rowsread += jpeg_read_scanlines(&cinfo, &bufferPointers[rowsread], area.h);
}
logger->log("BJpeg", Log::DEBUG, "Done all jpeg_read");
fclose(infile);
- logger->log("BJpeg", Log::DEBUG, "jpeg shutdown done, x, y %u %u", width, height);
+ logger->log("BJpeg", Log::DEBUG, "jpeg shutdown done, x, y %u %u", area.w, area.h);
Colour c;
UINT x, y, xoff;
unsigned char* p;
- for (y = 0; y < height; y++)
+ for (y = 0; y < area.h; y++)
{
p = bufferPointers[y];
- for (x = 0; x < width; x++)
+ for (x = 0; x < area.w; x++)
{
xoff = x * 3;
int fontHeight = surface->getFontHeight();
int ySeperation = fontHeight + 1;
- numOptionsDisplayable = (height - 5) / ySeperation;
+ numOptionsDisplayable = (area.h - 5) / ySeperation;
if (selectedOption == (topOption + numOptionsDisplayable)) topOption++;
if (selectedOption == ((UINT)topOption - 1)) topOption--;
for (UINT i = topOption; i < (topOption + numOptionsDisplayable); i++)
{
if (i == options.size()) return;
- if ((ypos + ySeperation) > height) break;
+ if ((ypos + ySeperation) > area.h) break;
if (i == selectedOption)
{
- rectangle(0, ypos, width, fontHeight, Colour::SELECTHIGHLIGHT);
+ rectangle(0, ypos, area.w, fontHeight, Colour::SELECTHIGHLIGHT);
drawOptionLine(options[i], 5, ypos, Colour::DARKTEXT);
}
else