diff --git a/src/battery.cpp b/src/battery.cpp index 6ad9e20..404f90f 100644 --- a/src/battery.cpp +++ b/src/battery.cpp @@ -46,14 +46,14 @@ static unsigned short getBatteryLevel() return 0; } -Battery::Battery(SurfaceCollection &sc_) +Battery::Battery(SurfaceCollection& sc_) : sc(sc_) { lastUpdate = SDL_GetTicks(); update(); } -const Surface &Battery::getIcon() +OffscreenSurface const& Battery::getIcon() { // Check battery status every 60 seconds. unsigned int now = SDL_GetTicks(); diff --git a/src/battery.h b/src/battery.h index 964e5fd..90d7ea0 100644 --- a/src/battery.h +++ b/src/battery.h @@ -3,7 +3,7 @@ #include -class Surface; +class OffscreenSurface; class SurfaceCollection; @@ -12,17 +12,17 @@ class SurfaceCollection; */ class Battery { public: - Battery(SurfaceCollection &sc); + Battery(SurfaceCollection& sc); /** * Gets the icon that reflects the current battery status. */ - const Surface &getIcon(); + OffscreenSurface const& getIcon(); private: void update(); - SurfaceCollection ≻ + SurfaceCollection& sc; std::string iconPath; unsigned int lastUpdate; }; diff --git a/src/browsedialog.cpp b/src/browsedialog.cpp index 5f5e039..9cce30a 100644 --- a/src/browsedialog.cpp +++ b/src/browsedialog.cpp @@ -224,13 +224,13 @@ void BrowseDialog::quit() void BrowseDialog::paint() { - Surface& s = *gmenu2x->s; + OutputSurface& s = *gmenu2x->s; unsigned int i, iY; unsigned int firstElement, lastElement; unsigned int offsetY; - Surface bg(gmenu2x->bg); + OffscreenSurface bg(gmenu2x->bg); drawTitleIcon(bg, "icons/explorer.png", true); writeTitle(bg, title); writeSubTitle(bg, subtitle); diff --git a/src/gmenu2x.cpp b/src/gmenu2x.cpp index 2bc8a6d..412331e 100644 --- a/src/gmenu2x.cpp +++ b/src/gmenu2x.cpp @@ -259,7 +259,7 @@ GMenu2X::GMenu2X() exit(EXIT_FAILURE); } - s = Surface::openOutputSurface(resX, resY, confInt["videoBpp"]); + s = OutputSurface::open(resX, resY, confInt["videoBpp"]); if (!fileExists(confStr["wallpaper"])) { DEBUG("No wallpaper defined; we will take the default one.\n"); @@ -305,7 +305,6 @@ GMenu2X::~GMenu2X() { fflush(NULL); sc.clear(); - delete s; #ifdef ENABLE_INOTIFY delete monitor; @@ -317,17 +316,17 @@ void GMenu2X::initBG() { // Load wallpaper. delete bg; - bg = Surface::loadImage(confStr["wallpaper"]); + bg = OffscreenSurface::loadImage(confStr["wallpaper"]); if (!bg) { - bg = Surface::emptySurface(resX, resY); + bg = OffscreenSurface::emptySurface(resX, resY); } drawTopBar(*bg); drawBottomBar(*bg); - Surface *bgmain = sc.add(bg, "bgmain"); + OffscreenSurface *bgmain = sc.add(*bg, "bgmain"); - Surface *sd = Surface::loadImage("imgs/sd.png", confStr["skin"]); + Surface *sd = OffscreenSurface::loadImage("imgs/sd.png", confStr["skin"]); if (sd) sd->blit(*bgmain, 3, bottomBarIconY); string df = getDiskFree(getHome().c_str()); @@ -336,7 +335,7 @@ void GMenu2X::initBG() { cpuX = font->getTextWidth(df)+32; #ifdef ENABLE_CPUFREQ - Surface *cpu = Surface::loadImage("imgs/cpu.png", confStr["skin"]); + Surface *cpu = OffscreenSurface::loadImage("imgs/cpu.png", confStr["skin"]); if (cpu) cpu->blit(bgmain, cpuX, bottomBarIconY); cpuX += 19; manualX = cpuX+font->getTextWidth("300MHz")+5; @@ -348,21 +347,21 @@ void GMenu2X::initBG() { int serviceX = resX-38; if (usbnet) { if (web) { - Surface *webserver = Surface::loadImage( + Surface *webserver = OffscreenSurface::loadImage( "imgs/webserver.png", confStr["skin"]); if (webserver) webserver->blit(*bgmain, serviceX, bottomBarIconY); serviceX -= 19; delete webserver; } if (samba) { - Surface *sambaS = Surface::loadImage( + Surface *sambaS = OffscreenSurface::loadImage( "imgs/samba.png", confStr["skin"]); if (sambaS) sambaS->blit(*bgmain, serviceX, bottomBarIconY); serviceX -= 19; delete sambaS; } if (inet) { - Surface *inetS = Surface::loadImage("imgs/inet.png", confStr["skin"]); + Surface *inetS = OffscreenSurface::loadImage("imgs/inet.png", confStr["skin"]); if (inetS) inetS->blit(*bgmain, serviceX, bottomBarIconY); serviceX -= 19; delete inetS; diff --git a/src/gmenu2x.h b/src/gmenu2x.h index 3b6cbc3..dcb6194 100644 --- a/src/gmenu2x.h +++ b/src/gmenu2x.h @@ -42,6 +42,7 @@ class Launcher; class Layer; class MediaMonitor; class Menu; +class OutputSurface; class Surface; #ifndef GMENU2X_SYSTEM_DIR @@ -158,7 +159,8 @@ public: SurfaceCollection sc; Translator tr; - Surface *s, *bg; + std::unique_ptr s; + Surface *bg; std::unique_ptr font; //Status functions diff --git a/src/inputdialog.cpp b/src/inputdialog.cpp index 21f16ce..2f0071b 100644 --- a/src/inputdialog.cpp +++ b/src/inputdialog.cpp @@ -149,7 +149,7 @@ bool InputDialog::exec() { Uint32 caretTick = 0, curTick; bool caretOn = true; - Surface bg(gmenu2x->bg); + OffscreenSurface bg(gmenu2x->bg); drawTitleIcon(bg, icon, false); writeTitle(bg, title); writeSubTitle(bg, text); @@ -159,7 +159,7 @@ bool InputDialog::exec() { close = false; ok = true; while (!close) { - Surface& s = *gmenu2x->s; + OutputSurface& s = *gmenu2x->s; bg.blit(s, 0, 0); diff --git a/src/linkapp.cpp b/src/linkapp.cpp index bd7fb01..0c562bd 100644 --- a/src/linkapp.cpp +++ b/src/linkapp.cpp @@ -433,13 +433,13 @@ void LinkApp::showManual() { gmenu2x->setSafeMaxClock(); #endif - Surface *pngman = Surface::loadImage(manual); + OffscreenSurface *pngman = OffscreenSurface::loadImage(manual); if (!pngman) { return; } - Surface *bg = Surface::loadImage(gmenu2x->confStr["wallpaper"]); + OffscreenSurface *bg = OffscreenSurface::loadImage(gmenu2x->confStr["wallpaper"]); if (!bg) { - bg = Surface::emptySurface(gmenu2x->s->width(), gmenu2x->s->height()); + bg = OffscreenSurface::emptySurface(gmenu2x->s->width(), gmenu2x->s->height()); } bg->convertToDisplayFormat(); @@ -459,7 +459,7 @@ void LinkApp::showManual() { #endif while (!close) { - Surface& s = *gmenu2x->s; + OutputSurface& s = *gmenu2x->s; if (repaint) { bg->blit(s, 0, 0); diff --git a/src/messagebox.cpp b/src/messagebox.cpp index 889a0d0..18c2a75 100644 --- a/src/messagebox.cpp +++ b/src/messagebox.cpp @@ -62,8 +62,8 @@ void MessageBox::setButton(InputManager::Button button, const string &label) { } int MessageBox::exec() { - Surface& s = *gmenu2x->s; - Surface bg(s); + OutputSurface& s = *gmenu2x->s; + OffscreenSurface bg(s); //Darken background bg.box(0, 0, gmenu2x->resX, gmenu2x->resY, 0,0,0,200); diff --git a/src/selector.cpp b/src/selector.cpp index e5b901b..61d61f9 100644 --- a/src/selector.cpp +++ b/src/selector.cpp @@ -59,7 +59,7 @@ int Selector::exec(int startSelection) { fl.setFilter(link->getSelectorFilter()); fl.browse(); - Surface bg(gmenu2x->bg); + OffscreenSurface bg(gmenu2x->bg); drawTitleIcon(bg, link->getIconPath(), true); writeTitle(bg, link->getTitle()); writeSubTitle(bg, link->getDescription()); @@ -95,7 +95,7 @@ int Selector::exec(int startSelection) { gmenu2x->sc.addSkinRes("imgs/folder.png"); gmenu2x->sc.defaultAlpha = false; while (!close) { - Surface& s = *gmenu2x->s; + OutputSurface& s = *gmenu2x->s; bg.blit(s, 0, 0); diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 8bb860c..1a2e700 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -50,7 +50,7 @@ SettingsDialog::~SettingsDialog() { } bool SettingsDialog::exec() { - Surface bg(gmenu2x->bg); + OffscreenSurface bg(gmenu2x->bg); bg.convertToDisplayFormat(); bool close = false, ts_pressed = false; @@ -78,7 +78,7 @@ bool SettingsDialog::exec() { } while (!close) { - Surface& s = *gmenu2x->s; + OutputSurface& s = *gmenu2x->s; if (ts.available()) ts.poll(); diff --git a/src/surface.cpp b/src/surface.cpp index cd79b6a..1f99a6e 100644 --- a/src/surface.cpp +++ b/src/surface.cpp @@ -32,6 +32,9 @@ using namespace std; + +// RGBAColor: + RGBAColor RGBAColor::fromString(const string &strColor) { return { uint8_t(constrain(strtol(strColor.substr(0, 2).c_str(), nullptr, 16), @@ -58,46 +61,11 @@ ostream& operator<<(ostream& os, RGBAColor const& color) { return os; } -Surface *Surface::openOutputSurface(int width, int height, int bitsperpixel) { - SDL_ShowCursor(SDL_DISABLE); - SDL_Surface *raw = SDL_SetVideoMode( - width, height, bitsperpixel, SDL_HWSURFACE | SDL_DOUBLEBUF); - return raw ? new Surface(raw, false) : NULL; -} -Surface *Surface::emptySurface(int width, int height) { - SDL_Surface *raw = SDL_CreateRGBSurface( - SDL_SWSURFACE, width, height, 32, 0, 0, 0, 0); - if (!raw) return NULL; - SDL_FillRect(raw, NULL, SDL_MapRGB(raw->format, 0, 0, 0)); - return new Surface(raw, true); -} - -Surface *Surface::loadImage(const string &img, const string &skin, bool loadAlpha) { - string skinpath; - if (!skin.empty() && !img.empty() && img[0]!='/') - skinpath = SurfaceCollection::getSkinFilePath(skin, img); - else - skinpath = img; - - SDL_Surface *raw = loadPNG(skinpath, loadAlpha); - if (!raw) { - ERROR("Couldn't load surface '%s'\n", img.c_str()); - return NULL; - } - - return new Surface(raw, true); -} - -Surface::Surface(SDL_Surface *raw_, bool freeWhenDone_) - : raw(raw_) - , freeWhenDone(freeWhenDone_) -{ -} +// Surface: Surface::Surface(Surface const& other) - : Surface(SDL_ConvertSurface( - other.raw, other.raw->format, SDL_SWSURFACE), true) + : Surface(SDL_ConvertSurface(other.raw, other.raw->format, SDL_SWSURFACE)) { // Note: A bug in SDL_ConvertSurface() leaves the per-surface alpha // undefined when converting from RGBA to RGBA. This can cause @@ -106,48 +74,6 @@ Surface::Surface(Surface const& other) raw->format->alpha = other.raw->format->alpha; } -Surface::Surface(Surface&& other) - : raw(other.raw) - , freeWhenDone(other.freeWhenDone) -{ - other.raw = nullptr; - other.freeWhenDone = false; -} - -Surface::~Surface() -{ - if (freeWhenDone) { - SDL_FreeSurface(raw); - } -} - -Surface& Surface::operator=(Surface other) -{ - swap(other); - return *this; -} - -void Surface::swap(Surface& other) -{ - std::swap(raw, other.raw); - std::swap(freeWhenDone, other.freeWhenDone); -} - -void Surface::convertToDisplayFormat() { - SDL_Surface *newSurface = SDL_DisplayFormat(raw); - if (newSurface) { - if (freeWhenDone) { - SDL_FreeSurface(raw); - } - raw = newSurface; - freeWhenDone = true; - } -} - -void Surface::flip() { - SDL_Flip(raw); -} - void Surface::blit(SDL_Surface *destination, int x, int y, int w, int h, int a) const { if (destination == NULL || a==0) return; @@ -351,3 +277,79 @@ void Surface::fillRectAlpha(SDL_Rect rect, RGBAColor c) { SDL_UnlockSurface(raw); } } + + +// OffscreenSurface: + +OffscreenSurface *OffscreenSurface::emptySurface(int width, int height) +{ + SDL_Surface *raw = SDL_CreateRGBSurface( + SDL_SWSURFACE, width, height, 32, 0, 0, 0, 0); + if (!raw) return nullptr; + SDL_FillRect(raw, nullptr, SDL_MapRGB(raw->format, 0, 0, 0)); + return new OffscreenSurface(raw); +} + +OffscreenSurface *OffscreenSurface::loadImage( + const string &img, const string &skin, bool loadAlpha) +{ + string skinpath; + if (!skin.empty() && !img.empty() && img[0]!='/') + skinpath = SurfaceCollection::getSkinFilePath(skin, img); + else + skinpath = img; + + SDL_Surface *raw = loadPNG(skinpath, loadAlpha); + if (!raw) { + ERROR("Couldn't load surface '%s'\n", img.c_str()); + return nullptr; + } + + return new OffscreenSurface(raw); +} + +OffscreenSurface::OffscreenSurface(OffscreenSurface&& other) + : Surface(other.raw) +{ + other.raw = nullptr; +} + +OffscreenSurface::~OffscreenSurface() +{ + SDL_FreeSurface(raw); +} + +OffscreenSurface& OffscreenSurface::operator=(OffscreenSurface other) +{ + swap(other); + return *this; +} + +void OffscreenSurface::swap(OffscreenSurface& other) +{ + std::swap(raw, other.raw); +} + +void OffscreenSurface::convertToDisplayFormat() { + SDL_Surface *newSurface = SDL_DisplayFormat(raw); + if (newSurface) { + SDL_FreeSurface(raw); + raw = newSurface; + } +} + + +// OutputSurface: + +unique_ptr OutputSurface::open( + int width, int height, int bitsPerPixel) +{ + SDL_ShowCursor(SDL_DISABLE); + SDL_Surface *raw = SDL_SetVideoMode( + width, height, bitsPerPixel, SDL_HWSURFACE | SDL_DOUBLEBUF); + return unique_ptr(raw ? new OutputSurface(raw) : nullptr); +} + +void OutputSurface::flip() { + SDL_Flip(raw); +} diff --git a/src/surface.h b/src/surface.h index b643934..b5d90df 100644 --- a/src/surface.h +++ b/src/surface.h @@ -1,6 +1,7 @@ /*************************************************************************** * Copyright (C) 2006 by Massimiliano Torromeo * - * massimiliano.torromeo@gmail.com * + * massimiliano.torromeo@gmail.com * + * Copyright (C) 2010-2014 by various authors; see Git log * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -26,6 +27,7 @@ #include #include +#include #include #include @@ -42,36 +44,15 @@ struct RGBAColor { std::ostream& operator<<(std::ostream& os, RGBAColor const& color); /** - Wrapper around SDL_Surface - @author Massimiliano Torromeo -*/ + * Abstract base class for surfaces; wraps SDL_Surface. + */ class Surface { public: - static Surface *openOutputSurface(int width, int height, int bitsperpixel); - static Surface *emptySurface(int width, int height); - static Surface *loadImage(const std::string &img, - const std::string &skin="", bool loadAlpha=true); - - // TODO: Remove this once naked Surface pointers are no longer in use. - Surface(Surface *other) : Surface(*other) {} - - Surface(Surface const& other); - Surface(Surface&& other); - ~Surface(); - Surface& operator=(Surface other); - void swap(Surface& other); - - /** Converts the underlying surface to the same pixel format as the frame - * buffer, for faster blitting. This removes the alpha channel if the - * image has done. - */ - void convertToDisplayFormat(); + Surface& operator=(Surface const& other) = delete; int width() const { return raw->w; } int height() const { return raw->h; } - void flip(); - void clearClipRect(); void setClipRect(int x, int y, int w, int h); void setClipRect(SDL_Rect rect); @@ -96,8 +77,16 @@ public: rectangle((SDL_Rect){ x, y, w, h }, RGBAColor(r, g, b, a)); } +protected: + Surface(SDL_Surface *raw) : raw(raw) {} + Surface(Surface const& other); + + SDL_Surface *raw; + + // For direct access to "raw". + friend class Font; + private: - Surface(SDL_Surface *raw, bool freeWhenDone); void blit(SDL_Surface *destination, int x, int y, int w=0, int h=0, int a=-1) const; void blitCenter(SDL_Surface *destination, int x, int y, int w=0, int h=0, int a=-1) const; void blitRight(SDL_Surface *destination, int x, int y, int w=0, int h=0, int a=-1) const; @@ -111,12 +100,53 @@ private: * rectangle. */ void applyClipRect(SDL_Rect& rect); +}; - SDL_Surface *raw; - bool freeWhenDone; +/** + * A surface that is off-screen: not visible. + */ +class OffscreenSurface: public Surface { +public: + static OffscreenSurface *emptySurface(int width, int height); + static OffscreenSurface *loadImage(const std::string &img, + const std::string &skin="", bool loadAlpha=true); - // For direct access to "raw". - friend class Font; + // TODO: Remove this once naked Surface pointers are no longer in use. + OffscreenSurface(Surface *other) : Surface(*other) {} + + OffscreenSurface(Surface const& other) : Surface(other) {} + OffscreenSurface(OffscreenSurface&& other); + ~OffscreenSurface(); + OffscreenSurface& operator=(OffscreenSurface other); + void swap(OffscreenSurface& other); + + /** + * Converts the underlying surface to the same pixel format as the frame + * buffer, for faster blitting. This removes the alpha channel if the + * image has one. + */ + void convertToDisplayFormat(); + +private: + OffscreenSurface(SDL_Surface *raw) : Surface(raw) {} +}; + +/** + * A surface that is used for writing to a video output device. + */ +class OutputSurface: public Surface { +public: + static std::unique_ptr open( + int width, int height, int bitsPerPixel); + + /** + * Offers the current buffer to the video system to be presented and + * acquires a new buffer to draw into. + */ + void flip(); + +private: + OutputSurface(SDL_Surface *raw) : Surface(raw) {} }; #endif diff --git a/src/surfacecollection.cpp b/src/surfacecollection.cpp index 9c51626..25a762e 100644 --- a/src/surfacecollection.cpp +++ b/src/surfacecollection.cpp @@ -98,14 +98,14 @@ bool SurfaceCollection::exists(const string &path) { return surfaces.find(path) != surfaces.end(); } -Surface *SurfaceCollection::add(Surface const& s, std::string const& path) { +OffscreenSurface *SurfaceCollection::add(Surface const& s, std::string const& path) { if (exists(path)) del(path); - Surface *copy = new Surface(s); + auto copy = new OffscreenSurface(s); surfaces[path] = copy; return copy; } -Surface *SurfaceCollection::add(const string &path) { +OffscreenSurface *SurfaceCollection::add(const string &path) { if (path.empty()) return NULL; if (exists(path)) del(path); string filePath = path; @@ -120,14 +120,14 @@ Surface *SurfaceCollection::add(const string &path) { } DEBUG("Adding surface: '%s'\n", path.c_str()); - Surface *s = Surface::loadImage(filePath, "", defaultAlpha); - if (s != NULL) { + auto s = OffscreenSurface::loadImage(filePath, "", defaultAlpha); + if (s) { surfaces[path] = s; } return s; } -Surface *SurfaceCollection::addSkinRes(const string &path, bool useDefault) { +OffscreenSurface *SurfaceCollection::addSkinRes(const string &path, bool useDefault) { if (path.empty()) return NULL; if (exists(path)) del(path); @@ -136,8 +136,8 @@ Surface *SurfaceCollection::addSkinRes(const string &path, bool useDefault) { return NULL; DEBUG("Adding skin surface: '%s'\n", path.c_str()); - Surface *s = Surface::loadImage(skinpath); - if (s != NULL) { + auto s = OffscreenSurface::loadImage(skinpath); + if (s) { surfaces[path] = s; } return s; @@ -163,7 +163,7 @@ void SurfaceCollection::move(const string &from, const string &to) { surfaces.erase(from); } -Surface *SurfaceCollection::operator[](const string &key) { +OffscreenSurface *SurfaceCollection::operator[](const string &key) { SurfaceHash::iterator i = surfaces.find(key); if (i == surfaces.end()) return add(key); @@ -171,7 +171,7 @@ Surface *SurfaceCollection::operator[](const string &key) { return i->second; } -Surface *SurfaceCollection::skinRes(const string &key, bool useDefault) { +OffscreenSurface *SurfaceCollection::skinRes(const string &key, bool useDefault) { if (key.empty()) return NULL; SurfaceHash::iterator i = surfaces.find(key); diff --git a/src/surfacecollection.h b/src/surfacecollection.h index 10165e1..0f97bab 100644 --- a/src/surfacecollection.h +++ b/src/surfacecollection.h @@ -23,9 +23,10 @@ #include #include +class OffscreenSurface; class Surface; -typedef std::unordered_map SurfaceHash; +typedef std::unordered_map SurfaceHash; /** Hash Map of surfaces that loads surfaces not already loaded and reuses already loaded ones. @@ -49,17 +50,17 @@ public: * Adds a copy of the given surface to this collection under the given * path. Returns the copy. */ - Surface *add(Surface const& s, std::string const& path); + OffscreenSurface *add(Surface const& s, std::string const& path); - Surface *add(const std::string &path); - Surface *addSkinRes(const std::string &path, bool useDefault = true); + OffscreenSurface *add(const std::string &path); + OffscreenSurface *addSkinRes(const std::string &path, bool useDefault = true); void del(const std::string &path); void clear(); void move(const std::string &from, const std::string &to); bool exists(const std::string &path); - Surface *operator[](const std::string &); - Surface *skinRes(const std::string &key, bool useDefault = true); + OffscreenSurface *operator[](const std::string &); + OffscreenSurface *skinRes(const std::string &key, bool useDefault = true); private: SurfaceHash surfaces; diff --git a/src/textdialog.cpp b/src/textdialog.cpp index 5c317af..b524003 100644 --- a/src/textdialog.cpp +++ b/src/textdialog.cpp @@ -60,7 +60,7 @@ void TextDialog::drawText(const vector &text, unsigned int y, void TextDialog::exec() { bool close = false; - Surface bg(gmenu2x->bg); + OffscreenSurface bg(gmenu2x->bg); //link icon if (!fileExists(icon)) @@ -87,7 +87,7 @@ void TextDialog::exec() { unsigned firstRow = 0; while (!close) { - Surface& s = *gmenu2x->s; + OutputSurface& s = *gmenu2x->s; bg.blit(s, 0, 0); drawText(text, contentY, firstRow, rowsPerPage); diff --git a/src/textmanualdialog.cpp b/src/textmanualdialog.cpp index 5171981..6a18c0d 100644 --- a/src/textmanualdialog.cpp +++ b/src/textmanualdialog.cpp @@ -68,7 +68,7 @@ TextManualDialog::TextManualDialog(GMenu2X *gmenu2x, const string &title, const } void TextManualDialog::exec() { - Surface bg(gmenu2x->bg); + OffscreenSurface bg(gmenu2x->bg); //link icon if (!fileExists(icon)) @@ -102,7 +102,7 @@ void TextManualDialog::exec() { bool close = false; while (!close) { - Surface& s = *gmenu2x->s; + OutputSurface& s = *gmenu2x->s; bg.blit(s,0,0); writeSubTitle(s, pages[page].title); diff --git a/src/wallpaperdialog.cpp b/src/wallpaperdialog.cpp index d7ed451..2234c0a 100644 --- a/src/wallpaperdialog.cpp +++ b/src/wallpaperdialog.cpp @@ -88,7 +88,7 @@ bool WallpaperDialog::exec() unsigned int nb_elements = height / fontheight; while (!close) { - Surface& s = *gmenu2x->s; + OutputSurface& s = *gmenu2x->s; if (selected > firstElement + nb_elements - 1) firstElement = selected - nb_elements + 1;