Date:2014-08-10 13:25:54 (9 years 7 months ago)
Author:Maarten ter Huurne
Commit:4bd1c799bdf421394331540486425d09501a597c
Message:Created separate subclasses for output and off-screen surfaces

There are a few exclusive operations for each type. Also we no longer
need the freeWhenDone flag since the class now determines whether the
surface should be freed or not.
Files: src/battery.cpp (1 diff)
src/battery.h (2 diffs)
src/browsedialog.cpp (1 diff)
src/gmenu2x.cpp (5 diffs)
src/gmenu2x.h (2 diffs)
src/inputdialog.cpp (2 diffs)
src/linkapp.cpp (2 diffs)
src/messagebox.cpp (1 diff)
src/selector.cpp (2 diffs)
src/settingsdialog.cpp (2 diffs)
src/surface.cpp (4 diffs)
src/surface.h (5 diffs)
src/surfacecollection.cpp (5 diffs)
src/surfacecollection.h (2 diffs)
src/textdialog.cpp (2 diffs)
src/textmanualdialog.cpp (2 diffs)
src/wallpaperdialog.cpp (1 diff)

Change Details

src/battery.cpp
4646    return 0;
4747}
4848
49Battery::Battery(SurfaceCollection &sc_)
49Battery::Battery(SurfaceCollection& sc_)
5050    : sc(sc_)
5151{
5252    lastUpdate = SDL_GetTicks();
5353    update();
5454}
5555
56const Surface &Battery::getIcon()
56OffscreenSurface const& Battery::getIcon()
5757{
5858    // Check battery status every 60 seconds.
5959    unsigned int now = SDL_GetTicks();
src/battery.h
33
44#include <string>
55
6class Surface;
6class OffscreenSurface;
77class SurfaceCollection;
88
99
...... 
1212 */
1313class Battery {
1414public:
15    Battery(SurfaceCollection &sc);
15    Battery(SurfaceCollection& sc);
1616
1717    /**
1818     * Gets the icon that reflects the current battery status.
1919     */
20    const Surface &getIcon();
20    OffscreenSurface const& getIcon();
2121
2222private:
2323    void update();
2424
25    SurfaceCollection &sc;
25    SurfaceCollection& sc;
2626    std::string iconPath;
2727    unsigned int lastUpdate;
2828};
src/browsedialog.cpp
224224
225225void BrowseDialog::paint()
226226{
227    Surface& s = *gmenu2x->s;
227    OutputSurface& s = *gmenu2x->s;
228228
229229    unsigned int i, iY;
230230    unsigned int firstElement, lastElement;
231231    unsigned int offsetY;
232232
233    Surface bg(gmenu2x->bg);
233    OffscreenSurface bg(gmenu2x->bg);
234234    drawTitleIcon(bg, "icons/explorer.png", true);
235235    writeTitle(bg, title);
236236    writeSubTitle(bg, subtitle);
src/gmenu2x.cpp
259259        exit(EXIT_FAILURE);
260260    }
261261
262    s = Surface::openOutputSurface(resX, resY, confInt["videoBpp"]);
262    s = OutputSurface::open(resX, resY, confInt["videoBpp"]);
263263
264264    if (!fileExists(confStr["wallpaper"])) {
265265        DEBUG("No wallpaper defined; we will take the default one.\n");
...... 
305305
306306    fflush(NULL);
307307    sc.clear();
308    delete s;
309308
310309#ifdef ENABLE_INOTIFY
311310    delete monitor;
...... 
317316
318317    // Load wallpaper.
319318    delete bg;
320    bg = Surface::loadImage(confStr["wallpaper"]);
319    bg = OffscreenSurface::loadImage(confStr["wallpaper"]);
321320    if (!bg) {
322        bg = Surface::emptySurface(resX, resY);
321        bg = OffscreenSurface::emptySurface(resX, resY);
323322    }
324323
325324    drawTopBar(*bg);
326325    drawBottomBar(*bg);
327326
328    Surface *bgmain = sc.add(bg, "bgmain");
327    OffscreenSurface *bgmain = sc.add(*bg, "bgmain");
329328
330    Surface *sd = Surface::loadImage("imgs/sd.png", confStr["skin"]);
329    Surface *sd = OffscreenSurface::loadImage("imgs/sd.png", confStr["skin"]);
331330    if (sd) sd->blit(*bgmain, 3, bottomBarIconY);
332331
333332    string df = getDiskFree(getHome().c_str());
...... 
336335
337336    cpuX = font->getTextWidth(df)+32;
338337#ifdef ENABLE_CPUFREQ
339    Surface *cpu = Surface::loadImage("imgs/cpu.png", confStr["skin"]);
338    Surface *cpu = OffscreenSurface::loadImage("imgs/cpu.png", confStr["skin"]);
340339    if (cpu) cpu->blit(bgmain, cpuX, bottomBarIconY);
341340    cpuX += 19;
342341    manualX = cpuX+font->getTextWidth("300MHz")+5;
...... 
348347    int serviceX = resX-38;
349348    if (usbnet) {
350349        if (web) {
351            Surface *webserver = Surface::loadImage(
350            Surface *webserver = OffscreenSurface::loadImage(
352351                "imgs/webserver.png", confStr["skin"]);
353352            if (webserver) webserver->blit(*bgmain, serviceX, bottomBarIconY);
354353            serviceX -= 19;
355354            delete webserver;
356355        }
357356        if (samba) {
358            Surface *sambaS = Surface::loadImage(
357            Surface *sambaS = OffscreenSurface::loadImage(
359358                "imgs/samba.png", confStr["skin"]);
360359            if (sambaS) sambaS->blit(*bgmain, serviceX, bottomBarIconY);
361360            serviceX -= 19;
362361            delete sambaS;
363362        }
364363        if (inet) {
365            Surface *inetS = Surface::loadImage("imgs/inet.png", confStr["skin"]);
364            Surface *inetS = OffscreenSurface::loadImage("imgs/inet.png", confStr["skin"]);
366365            if (inetS) inetS->blit(*bgmain, serviceX, bottomBarIconY);
367366            serviceX -= 19;
368367            delete inetS;
src/gmenu2x.h
4242class Layer;
4343class MediaMonitor;
4444class Menu;
45class OutputSurface;
4546class Surface;
4647
4748#ifndef GMENU2X_SYSTEM_DIR
...... 
158159
159160    SurfaceCollection sc;
160161    Translator tr;
161    Surface *s, *bg;
162    std::unique_ptr<OutputSurface> s;
163    Surface *bg;
162164    std::unique_ptr<Font> font;
163165
164166    //Status functions
src/inputdialog.cpp
149149    Uint32 caretTick = 0, curTick;
150150    bool caretOn = true;
151151
152    Surface bg(gmenu2x->bg);
152    OffscreenSurface bg(gmenu2x->bg);
153153    drawTitleIcon(bg, icon, false);
154154    writeTitle(bg, title);
155155    writeSubTitle(bg, text);
...... 
159159    close = false;
160160    ok = true;
161161    while (!close) {
162        Surface& s = *gmenu2x->s;
162        OutputSurface& s = *gmenu2x->s;
163163
164164        bg.blit(s, 0, 0);
165165
src/linkapp.cpp
433433        gmenu2x->setSafeMaxClock();
434434#endif
435435
436        Surface *pngman = Surface::loadImage(manual);
436        OffscreenSurface *pngman = OffscreenSurface::loadImage(manual);
437437        if (!pngman) {
438438            return;
439439        }
440        Surface *bg = Surface::loadImage(gmenu2x->confStr["wallpaper"]);
440        OffscreenSurface *bg = OffscreenSurface::loadImage(gmenu2x->confStr["wallpaper"]);
441441        if (!bg) {
442            bg = Surface::emptySurface(gmenu2x->s->width(), gmenu2x->s->height());
442            bg = OffscreenSurface::emptySurface(gmenu2x->s->width(), gmenu2x->s->height());
443443        }
444444        bg->convertToDisplayFormat();
445445
...... 
459459#endif
460460
461461        while (!close) {
462            Surface& s = *gmenu2x->s;
462            OutputSurface& s = *gmenu2x->s;
463463
464464            if (repaint) {
465465                bg->blit(s, 0, 0);
src/messagebox.cpp
6262}
6363
6464int MessageBox::exec() {
65    Surface& s = *gmenu2x->s;
66    Surface bg(s);
65    OutputSurface& s = *gmenu2x->s;
66    OffscreenSurface bg(s);
6767    //Darken background
6868    bg.box(0, 0, gmenu2x->resX, gmenu2x->resY, 0,0,0,200);
6969
src/selector.cpp
5959    fl.setFilter(link->getSelectorFilter());
6060    fl.browse();
6161
62    Surface bg(gmenu2x->bg);
62    OffscreenSurface bg(gmenu2x->bg);
6363    drawTitleIcon(bg, link->getIconPath(), true);
6464    writeTitle(bg, link->getTitle());
6565    writeSubTitle(bg, link->getDescription());
...... 
9595        gmenu2x->sc.addSkinRes("imgs/folder.png");
9696    gmenu2x->sc.defaultAlpha = false;
9797    while (!close) {
98        Surface& s = *gmenu2x->s;
98        OutputSurface& s = *gmenu2x->s;
9999
100100        bg.blit(s, 0, 0);
101101
src/settingsdialog.cpp
5050}
5151
5252bool SettingsDialog::exec() {
53    Surface bg(gmenu2x->bg);
53    OffscreenSurface bg(gmenu2x->bg);
5454    bg.convertToDisplayFormat();
5555
5656    bool close = false, ts_pressed = false;
...... 
7878    }
7979
8080    while (!close) {
81        Surface& s = *gmenu2x->s;
81        OutputSurface& s = *gmenu2x->s;
8282
8383        if (ts.available()) ts.poll();
8484
src/surface.cpp
3232
3333using namespace std;
3434
35
36// RGBAColor:
37
3538RGBAColor RGBAColor::fromString(const string &strColor) {
3639    return {
3740        uint8_t(constrain(strtol(strColor.substr(0, 2).c_str(), nullptr, 16),
...... 
5861    return os;
5962}
6063
61Surface *Surface::openOutputSurface(int width, int height, int bitsperpixel) {
62    SDL_ShowCursor(SDL_DISABLE);
63    SDL_Surface *raw = SDL_SetVideoMode(
64        width, height, bitsperpixel, SDL_HWSURFACE | SDL_DOUBLEBUF);
65    return raw ? new Surface(raw, false) : NULL;
66}
67
68Surface *Surface::emptySurface(int width, int height) {
69    SDL_Surface *raw = SDL_CreateRGBSurface(
70        SDL_SWSURFACE, width, height, 32, 0, 0, 0, 0);
71    if (!raw) return NULL;
72    SDL_FillRect(raw, NULL, SDL_MapRGB(raw->format, 0, 0, 0));
73    return new Surface(raw, true);
74}
75
76Surface *Surface::loadImage(const string &img, const string &skin, bool loadAlpha) {
77    string skinpath;
78    if (!skin.empty() && !img.empty() && img[0]!='/')
79      skinpath = SurfaceCollection::getSkinFilePath(skin, img);
80    else
81      skinpath = img;
82
83    SDL_Surface *raw = loadPNG(skinpath, loadAlpha);
84    if (!raw) {
85        ERROR("Couldn't load surface '%s'\n", img.c_str());
86        return NULL;
87    }
8864
89    return new Surface(raw, true);
90}
91
92Surface::Surface(SDL_Surface *raw_, bool freeWhenDone_)
93    : raw(raw_)
94    , freeWhenDone(freeWhenDone_)
95{
96}
65// Surface:
9766
9867Surface::Surface(Surface const& other)
99    : Surface(SDL_ConvertSurface(
100            other.raw, other.raw->format, SDL_SWSURFACE), true)
68    : Surface(SDL_ConvertSurface(other.raw, other.raw->format, SDL_SWSURFACE))
10169{
10270    // Note: A bug in SDL_ConvertSurface() leaves the per-surface alpha
10371    // undefined when converting from RGBA to RGBA. This can cause
...... 
10674    raw->format->alpha = other.raw->format->alpha;
10775}
10876
109Surface::Surface(Surface&& other)
110    : raw(other.raw)
111    , freeWhenDone(other.freeWhenDone)
112{
113    other.raw = nullptr;
114    other.freeWhenDone = false;
115}
116
117Surface::~Surface()
118{
119    if (freeWhenDone) {
120        SDL_FreeSurface(raw);
121    }
122}
123
124Surface& Surface::operator=(Surface other)
125{
126    swap(other);
127    return *this;
128}
129
130void Surface::swap(Surface& other)
131{
132    std::swap(raw, other.raw);
133    std::swap(freeWhenDone, other.freeWhenDone);
134}
135
136void Surface::convertToDisplayFormat() {
137    SDL_Surface *newSurface = SDL_DisplayFormat(raw);
138    if (newSurface) {
139        if (freeWhenDone) {
140            SDL_FreeSurface(raw);
141        }
142        raw = newSurface;
143        freeWhenDone = true;
144    }
145}
146
147void Surface::flip() {
148    SDL_Flip(raw);
149}
150
15177void Surface::blit(SDL_Surface *destination, int x, int y, int w, int h, int a) const {
15278    if (destination == NULL || a==0) return;
15379
...... 
351277        SDL_UnlockSurface(raw);
352278    }
353279}
280
281
282// OffscreenSurface:
283
284OffscreenSurface *OffscreenSurface::emptySurface(int width, int height)
285{
286    SDL_Surface *raw = SDL_CreateRGBSurface(
287            SDL_SWSURFACE, width, height, 32, 0, 0, 0, 0);
288    if (!raw) return nullptr;
289    SDL_FillRect(raw, nullptr, SDL_MapRGB(raw->format, 0, 0, 0));
290    return new OffscreenSurface(raw);
291}
292
293OffscreenSurface *OffscreenSurface::loadImage(
294        const string &img, const string &skin, bool loadAlpha)
295{
296    string skinpath;
297    if (!skin.empty() && !img.empty() && img[0]!='/')
298      skinpath = SurfaceCollection::getSkinFilePath(skin, img);
299    else
300      skinpath = img;
301
302    SDL_Surface *raw = loadPNG(skinpath, loadAlpha);
303    if (!raw) {
304        ERROR("Couldn't load surface '%s'\n", img.c_str());
305        return nullptr;
306    }
307
308    return new OffscreenSurface(raw);
309}
310
311OffscreenSurface::OffscreenSurface(OffscreenSurface&& other)
312    : Surface(other.raw)
313{
314    other.raw = nullptr;
315}
316
317OffscreenSurface::~OffscreenSurface()
318{
319    SDL_FreeSurface(raw);
320}
321
322OffscreenSurface& OffscreenSurface::operator=(OffscreenSurface other)
323{
324    swap(other);
325    return *this;
326}
327
328void OffscreenSurface::swap(OffscreenSurface& other)
329{
330    std::swap(raw, other.raw);
331}
332
333void OffscreenSurface::convertToDisplayFormat() {
334    SDL_Surface *newSurface = SDL_DisplayFormat(raw);
335    if (newSurface) {
336        SDL_FreeSurface(raw);
337        raw = newSurface;
338    }
339}
340
341
342// OutputSurface:
343
344unique_ptr<OutputSurface> OutputSurface::open(
345        int width, int height, int bitsPerPixel)
346{
347    SDL_ShowCursor(SDL_DISABLE);
348    SDL_Surface *raw = SDL_SetVideoMode(
349        width, height, bitsPerPixel, SDL_HWSURFACE | SDL_DOUBLEBUF);
350    return unique_ptr<OutputSurface>(raw ? new OutputSurface(raw) : nullptr);
351}
352
353void OutputSurface::flip() {
354    SDL_Flip(raw);
355}
src/surface.h
11/***************************************************************************
22 * Copyright (C) 2006 by Massimiliano Torromeo *
3 * massimiliano.torromeo@gmail.com *
3 * massimiliano.torromeo@gmail.com *
4 * Copyright (C) 2010-2014 by various authors; see Git log *
45 * *
56 * This program is free software; you can redistribute it and/or modify *
67 * it under the terms of the GNU General Public License as published by *
...... 
2627#include <SDL.h>
2728
2829#include <cstdint>
30#include <memory>
2931#include <ostream>
3032#include <string>
3133
...... 
4244std::ostream& operator<<(std::ostream& os, RGBAColor const& color);
4345
4446/**
45    Wrapper around SDL_Surface
46    @author Massimiliano Torromeo <massimiliano.torromeo@gmail.com>
47*/
47 * Abstract base class for surfaces; wraps SDL_Surface.
48 */
4849class Surface {
4950public:
50    static Surface *openOutputSurface(int width, int height, int bitsperpixel);
51    static Surface *emptySurface(int width, int height);
52    static Surface *loadImage(const std::string &img,
53            const std::string &skin="", bool loadAlpha=true);
54
55    // TODO: Remove this once naked Surface pointers are no longer in use.
56    Surface(Surface *other) : Surface(*other) {}
57
58    Surface(Surface const& other);
59    Surface(Surface&& other);
60    ~Surface();
61    Surface& operator=(Surface other);
62    void swap(Surface& other);
63
64    /** Converts the underlying surface to the same pixel format as the frame
65      * buffer, for faster blitting. This removes the alpha channel if the
66      * image has done.
67      */
68    void convertToDisplayFormat();
51    Surface& operator=(Surface const& other) = delete;
6952
7053    int width() const { return raw->w; }
7154    int height() const { return raw->h; }
7255
73    void flip();
74
7556    void clearClipRect();
7657    void setClipRect(int x, int y, int w, int h);
7758    void setClipRect(SDL_Rect rect);
...... 
9677        rectangle((SDL_Rect){ x, y, w, h }, RGBAColor(r, g, b, a));
9778    }
9879
80protected:
81    Surface(SDL_Surface *raw) : raw(raw) {}
82    Surface(Surface const& other);
83
84    SDL_Surface *raw;
85
86    // For direct access to "raw".
87    friend class Font;
88
9989private:
100    Surface(SDL_Surface *raw, bool freeWhenDone);
10190    void blit(SDL_Surface *destination, int x, int y, int w=0, int h=0, int a=-1) const;
10291    void blitCenter(SDL_Surface *destination, int x, int y, int w=0, int h=0, int a=-1) const;
10392    void blitRight(SDL_Surface *destination, int x, int y, int w=0, int h=0, int a=-1) const;
...... 
111100      * rectangle.
112101      */
113102    void applyClipRect(SDL_Rect& rect);
103};
114104
115    SDL_Surface *raw;
116    bool freeWhenDone;
105/**
106 * A surface that is off-screen: not visible.
107 */
108class OffscreenSurface: public Surface {
109public:
110    static OffscreenSurface *emptySurface(int width, int height);
111    static OffscreenSurface *loadImage(const std::string &img,
112            const std::string &skin="", bool loadAlpha=true);
117113
118    // For direct access to "raw".
119    friend class Font;
114    // TODO: Remove this once naked Surface pointers are no longer in use.
115    OffscreenSurface(Surface *other) : Surface(*other) {}
116
117    OffscreenSurface(Surface const& other) : Surface(other) {}
118    OffscreenSurface(OffscreenSurface&& other);
119    ~OffscreenSurface();
120    OffscreenSurface& operator=(OffscreenSurface other);
121    void swap(OffscreenSurface& other);
122
123    /**
124     * Converts the underlying surface to the same pixel format as the frame
125     * buffer, for faster blitting. This removes the alpha channel if the
126     * image has one.
127     */
128    void convertToDisplayFormat();
129
130private:
131    OffscreenSurface(SDL_Surface *raw) : Surface(raw) {}
132};
133
134/**
135 * A surface that is used for writing to a video output device.
136 */
137class OutputSurface: public Surface {
138public:
139    static std::unique_ptr<OutputSurface> open(
140            int width, int height, int bitsPerPixel);
141
142    /**
143     * Offers the current buffer to the video system to be presented and
144     * acquires a new buffer to draw into.
145     */
146    void flip();
147
148private:
149    OutputSurface(SDL_Surface *raw) : Surface(raw) {}
120150};
121151
122152#endif
src/surfacecollection.cpp
9898    return surfaces.find(path) != surfaces.end();
9999}
100100
101Surface *SurfaceCollection::add(Surface const& s, std::string const& path) {
101OffscreenSurface *SurfaceCollection::add(Surface const& s, std::string const& path) {
102102    if (exists(path)) del(path);
103    Surface *copy = new Surface(s);
103    auto copy = new OffscreenSurface(s);
104104    surfaces[path] = copy;
105105    return copy;
106106}
107107
108Surface *SurfaceCollection::add(const string &path) {
108OffscreenSurface *SurfaceCollection::add(const string &path) {
109109    if (path.empty()) return NULL;
110110    if (exists(path)) del(path);
111111    string filePath = path;
...... 
120120    }
121121
122122    DEBUG("Adding surface: '%s'\n", path.c_str());
123    Surface *s = Surface::loadImage(filePath, "", defaultAlpha);
124    if (s != NULL) {
123    auto s = OffscreenSurface::loadImage(filePath, "", defaultAlpha);
124    if (s) {
125125        surfaces[path] = s;
126126    }
127127    return s;
128128}
129129
130Surface *SurfaceCollection::addSkinRes(const string &path, bool useDefault) {
130OffscreenSurface *SurfaceCollection::addSkinRes(const string &path, bool useDefault) {
131131    if (path.empty()) return NULL;
132132    if (exists(path)) del(path);
133133
...... 
136136        return NULL;
137137
138138    DEBUG("Adding skin surface: '%s'\n", path.c_str());
139    Surface *s = Surface::loadImage(skinpath);
140    if (s != NULL) {
139    auto s = OffscreenSurface::loadImage(skinpath);
140    if (s) {
141141        surfaces[path] = s;
142142    }
143143    return s;
...... 
163163    surfaces.erase(from);
164164}
165165
166Surface *SurfaceCollection::operator[](const string &key) {
166OffscreenSurface *SurfaceCollection::operator[](const string &key) {
167167    SurfaceHash::iterator i = surfaces.find(key);
168168    if (i == surfaces.end())
169169        return add(key);
...... 
171171        return i->second;
172172}
173173
174Surface *SurfaceCollection::skinRes(const string &key, bool useDefault) {
174OffscreenSurface *SurfaceCollection::skinRes(const string &key, bool useDefault) {
175175    if (key.empty()) return NULL;
176176
177177    SurfaceHash::iterator i = surfaces.find(key);
src/surfacecollection.h
2323#include <string>
2424#include <unordered_map>
2525
26class OffscreenSurface;
2627class Surface;
2728
28typedef std::unordered_map<std::string, Surface *> SurfaceHash;
29typedef std::unordered_map<std::string, OffscreenSurface *> SurfaceHash;
2930
3031/**
3132Hash Map of surfaces that loads surfaces not already loaded and reuses already loaded ones.
...... 
4950     * Adds a copy of the given surface to this collection under the given
5051     * path. Returns the copy.
5152     */
52    Surface *add(Surface const& s, std::string const& path);
53    OffscreenSurface *add(Surface const& s, std::string const& path);
5354
54    Surface *add(const std::string &path);
55    Surface *addSkinRes(const std::string &path, bool useDefault = true);
55    OffscreenSurface *add(const std::string &path);
56    OffscreenSurface *addSkinRes(const std::string &path, bool useDefault = true);
5657    void del(const std::string &path);
5758    void clear();
5859    void move(const std::string &from, const std::string &to);
5960    bool exists(const std::string &path);
6061
61    Surface *operator[](const std::string &);
62    Surface *skinRes(const std::string &key, bool useDefault = true);
62    OffscreenSurface *operator[](const std::string &);
63    OffscreenSurface *skinRes(const std::string &key, bool useDefault = true);
6364
6465private:
6566    SurfaceHash surfaces;
src/textdialog.cpp
6060void TextDialog::exec() {
6161    bool close = false;
6262
63    Surface bg(gmenu2x->bg);
63    OffscreenSurface bg(gmenu2x->bg);
6464
6565    //link icon
6666    if (!fileExists(icon))
...... 
8787
8888    unsigned firstRow = 0;
8989    while (!close) {
90        Surface& s = *gmenu2x->s;
90        OutputSurface& s = *gmenu2x->s;
9191
9292        bg.blit(s, 0, 0);
9393        drawText(text, contentY, firstRow, rowsPerPage);
src/textmanualdialog.cpp
6868}
6969
7070void TextManualDialog::exec() {
71    Surface bg(gmenu2x->bg);
71    OffscreenSurface bg(gmenu2x->bg);
7272
7373    //link icon
7474    if (!fileExists(icon))
...... 
102102    bool close = false;
103103
104104    while (!close) {
105        Surface& s = *gmenu2x->s;
105        OutputSurface& s = *gmenu2x->s;
106106
107107        bg.blit(s,0,0);
108108        writeSubTitle(s, pages[page].title);
src/wallpaperdialog.cpp
8888    unsigned int nb_elements = height / fontheight;
8989
9090    while (!close) {
91        Surface& s = *gmenu2x->s;
91        OutputSurface& s = *gmenu2x->s;
9292
9393        if (selected > firstElement + nb_elements - 1)
9494            firstElement = selected - nb_elements + 1;

Archive Download the corresponding diff file



interactive