GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/windowmanager.cpp Lines: 81 174 46.6 %
Date: 2018-12-09 Branches: 73 210 34.8 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2004-2009  The Mana World Development Team
4
 *  Copyright (C) 2009-2010  The Mana Developers
5
 *  Copyright (C) 2011-2018  The ManaPlus Developers
6
 *
7
 *  This file is part of The ManaPlus Client.
8
 *
9
 *  This program is free software; you can redistribute it and/or modify
10
 *  it under the terms of the GNU General Public License as published by
11
 *  the Free Software Foundation; either version 2 of the License, or
12
 *  any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  GNU General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU General Public License
20
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 */
22
23
#include "gui/windowmanager.h"
24
25
#include "client.h"
26
#include "configuration.h"
27
#include "game.h"
28
#include "main.h"
29
#include "settings.h"
30
#include "spellmanager.h"
31
32
#include "fs/virtfs/tools.h"
33
34
#include "gui/gui.h"
35
#include "gui/userpalette.h"
36
37
#include "gui/shortcut/spellshortcut.h"
38
39
#include "gui/popups/textpopup.h"
40
41
#ifdef DYECMD
42
#include "render/graphics.h"
43
#else  // DYECMD
44
#include "gui/popups/beingpopup.h"
45
#include "gui/popups/itempopup.h"
46
#include "gui/popups/popupmenu.h"
47
#include "gui/popups/skillpopup.h"
48
#include "gui/popups/spellpopup.h"
49
#include "gui/popups/textboxpopup.h"
50
51
#include "gui/windows/chatwindow.h"
52
#include "gui/windows/debugwindow.h"
53
#include "gui/windows/didyouknowwindow.h"
54
#include "gui/windows/equipmentwindow.h"
55
#include "gui/windows/helpwindow.h"
56
#include "gui/windows/setupwindow.h"
57
#include "gui/windows/skilldialog.h"
58
#include "gui/windows/questswindow.h"
59
60
#include "gui/widgets/tabs/chat/chattab.h"
61
62
#include "utils/gettext.h"
63
#endif  // DYECMD
64
65
#include "gui/widgets/createwidget.h"
66
#include "gui/widgets/desktop.h"
67
68
#include "input/touch/touchmanager.h"
69
70
#include "utils/delete2.h"
71
#include "utils/sdlcheckutils.h"
72
#include "utils/sdlhelper.h"
73
#ifdef __native_client__
74
#include "utils/naclmessages.h"
75
#endif  // __native_client__
76
77
PRAGMA48(GCC diagnostic push)
78
PRAGMA48(GCC diagnostic ignored "-Wshadow")
79
#ifdef ANDROID
80
#ifndef USE_SDL2
81
#include <SDL_screenkeyboard.h>
82
#endif  // USE_SDL2
83
#endif  // ANDROID
84
85
#ifdef USE_SDL2
86
#include <SDL2_framerate.h>
87
#else  // USE_SDL2
88
#include <SDL_framerate.h>
89
#endif  // USE_SDL2
90
91
#include <SDL_image.h>
92
93
#ifdef WIN32
94
#include <SDL_syswm.h>
95
#endif  // WIN32
96
PRAGMA48(GCC diagnostic pop)
97
98
#include "debug.h"
99
100
FPSmanager fpsManager;
101
102
namespace
103
{
104
    SDL_Surface *mIcon(nullptr);
105
#ifndef USE_SDL2
106
    int mKeyboardHeight(0);
107
#endif  // USE_SDL2
108
109
    bool mIsMinimized(false);
110
    bool mNewMessageFlag(false);
111
}  // namespace
112
113
216
void WindowManager::init()
114
{
115
    // Initialize frame limiting
116
216
    fpsManager.framecount = 0;
117
216
    fpsManager.rateticks = 0;
118
216
    fpsManager.lastticks = 0;
119
216
    fpsManager.rate = 0;
120
216
}
121
122
1
void WindowManager::createWindows()
123
{
124
1
    userPalette = new UserPalette;
125
#ifndef DYECMD
126
1
    CREATEWIDGETV0(setupWindow, SetupWindow);
127
1
    CREATEWIDGETV0(helpWindow, HelpWindow);
128
1
    CREATEWIDGETV0(didYouKnowWindow, DidYouKnowWindow);
129
1
    CREATEWIDGETV0(popupMenu, PopupMenu);
130
1
    CREATEWIDGETV0(beingPopup, BeingPopup);
131
1
    CREATEWIDGETV0(textBoxPopup, TextBoxPopup);
132
1
    CREATEWIDGETV0(itemPopup, ItemPopup);
133
1
    CREATEWIDGETV0(spellPopup, SpellPopup);
134
1
    CREATEWIDGETV0(skillPopup, SkillPopup);
135
1
    delete2(debugChatTab)
136
1
    if (chatWindow != nullptr)
137
    {
138
        chatWindow->scheduleDelete();
139
        chatWindow = nullptr;
140
    }
141

4
    CREATEWIDGETV(chatWindow, ChatWindow,
142
1
        "DebugChat");
143
    // TRANSLATORS: chat tab header
144
2
    debugChatTab = new ChatTab(chatWindow, _("Debug"), "",
145


10
        "#Debug", ChatTabType::DEBUG);
146
2
    debugChatTab->setAllowHighlight(false);
147
1
    chatWindow->setVisible(Visible_false);
148
1
    if (debugWindow != nullptr)
149
    {
150
        debugWindow->scheduleDelete();
151
        debugWindow = nullptr;
152
    }
153

4
    CREATEWIDGETV(debugWindow, DebugWindow,
154
1
        "DebugDebug");
155
#endif  // DYECMD
156
157
1
    CREATEWIDGETV0(textPopup, TextPopup);
158
1
}
159
160
void WindowManager::createValidateWindows()
161
{
162
#ifndef DYECMD
163
    CREATEWIDGETV0(skillDialog, SkillDialog);
164
    skillDialog->loadSkills();
165
    CREATEWIDGETV(beingEquipmentWindow, EquipmentWindow,
166
        nullptr, nullptr, true);
167
    CREATEWIDGETV0(questsWindow, QuestsWindow);
168
#endif  // DYECMD
169
}
170
171
void WindowManager::deleteValidateWindows()
172
{
173
#ifndef DYECMD
174
    delete2(skillDialog)
175
    delete2(beingEquipmentWindow)
176
    delete2(questsWindow)
177
#endif  // DYECMD
178
}
179
180
216
void WindowManager::deleteWindows()
181
{
182
#ifndef DYECMD
183
216
    delete2(textBoxPopup)
184
216
    delete2(beingPopup)
185
216
    delete2(itemPopup)
186
216
    delete2(spellPopup)
187
216
    delete2(skillPopup)
188
432
    delete2(popupMenu)
189
216
    delete2(didYouKnowWindow)
190
432
    delete2(helpWindow)
191
216
    delete2(setupWindow)
192
216
    delete2(userPalette)
193
216
    delete2(spellManager)
194
216
    delete2(spellShortcut)
195
196
216
    delete2(debugChatTab)
197
216
    delete2(chatWindow)
198
216
    delete2(debugWindow)
199
#endif  // DYECMD
200
201
216
    delete2(textPopup)
202
216
}
203
204
1
void WindowManager::initTitle()
205
{
206
1
    if (settings.options.test.empty())
207
    {
208
2
        settings.windowCaption = strprintf("%s %s",
209
4
            branding.getStringValue("appName").c_str(),
210
1
            SMALL_VERSION);
211
    }
212
    else
213
    {
214
        settings.windowCaption = strprintf(
215
            "Please wait - VIDEO MODE TEST - %s %s - Please wait",
216
            branding.getStringValue("appName").c_str(),
217
            SMALL_VERSION);
218
    }
219
220
1
    SDL::SetWindowTitle(mainGraphics->getWindow(),
221
1
        settings.windowCaption.c_str());
222
1
}
223
224
3
void WindowManager::updateTitle()
225
{
226
6
    std::string str;
227
3
    if (settings.login.empty())
228
        str = settings.serverName;
229
    else
230
1
        str.append(settings.login).append(" ").append(settings.serverName);
231
3
    if (str.empty())
232
    {
233
2
        settings.windowCaption = strprintf("%s %s",
234

4
            branding.getStringValue("appName").c_str(),
235
1
            SMALL_VERSION);
236
    }
237
    else
238
    {
239
6
        settings.windowCaption = strprintf("%s %s - %s",
240

8
            branding.getStringValue("appName").c_str(),
241
            SMALL_VERSION,
242
2
            str.c_str());
243
    }
244
3
    SDL::SetWindowTitle(mainGraphics->getWindow(),
245
3
        settings.windowCaption.c_str());
246
3
}
247
248
6
void WindowManager::setFramerate(const unsigned int fpsLimit)
249
{
250
6
    if (fpsLimit == 0U)
251
        return;
252
253
4
    if (!settings.limitFps)
254
        return;
255
256
2
    SDL_setFramerate(&fpsManager, fpsLimit);
257
}
258
259
6
int WindowManager::getFramerate()
260
{
261
6
    if (!settings.limitFps)
262
        return 0;
263
264
3
    return SDL_getFramerate(&fpsManager);
265
}
266
267
void WindowManager::doResizeVideo(const int actualWidth,
268
                                  const int actualHeight,
269
                                  const bool always)
270
{
271
    if (!always
272
        && mainGraphics->mActualWidth == actualWidth
273
        && mainGraphics->mActualHeight == actualHeight)
274
    {
275
        return;
276
    }
277
278
#ifdef __native_client__
279
    naclPostMessage("resize-window",
280
        strprintf("%d,%d", actualWidth, actualHeight));
281
#else  // __native_client__
282
283
    resizeVideo(actualWidth, actualHeight, always);
284
#endif  // __native_client__
285
}
286
287
void WindowManager::resizeVideo(int actualWidth,
288
                                int actualHeight,
289
                                const bool always)
290
{
291
    // Keep a minimum size. This isn't adhered to by the actual window, but
292
    // it keeps some window positions from getting messed up.
293
    actualWidth = std::max(470, actualWidth);
294
    actualHeight = std::max(320, actualHeight);
295
296
    if (mainGraphics == nullptr)
297
        return;
298
    if (!always
299
        && mainGraphics->mActualWidth == actualWidth
300
        && mainGraphics->mActualHeight == actualHeight)
301
    {
302
        return;
303
    }
304
305
    if (mainGraphics->resizeScreen(actualWidth, actualHeight))
306
    {
307
        const int width = mainGraphics->mWidth;
308
        const int height = mainGraphics->mHeight;
309
        touchManager.resize(width, height);
310
311
        if (gui != nullptr)
312
            gui->videoResized();
313
314
        if (desktop != nullptr)
315
            desktop->setSize(width, height);
316
317
        client->moveButtons(width);
318
319
#ifndef DYECMD
320
        Game *const game = Game::instance();
321
        if (game != nullptr)
322
            Game::videoResized(width, height);
323
#endif  // DYECMD
324
325
        if (gui != nullptr)
326
            gui->draw();
327
328
        config.setValue("screenwidth", actualWidth);
329
        config.setValue("screenheight", actualHeight);
330
    }
331
}
332
333
bool WindowManager::setFullScreen(const bool fs)
334
{
335
#ifdef __native_client__
336
    naclPostMessage("set-fullscreen",
337
        fs ? "on" : "off");
338
    return true;
339
#else  // __native_client__
340
341
    if (mainGraphics == nullptr)
342
        return false;
343
    return mainGraphics->setFullscreen(fs);
344
#endif  // __native_client__
345
}
346
347
void WindowManager::applyGrabMode()
348
{
349
    SDL::grabInput(mainGraphics->getWindow(),
350
        config.getBoolValue("grabinput"));
351
}
352
353
void WindowManager::applyGamma()
354
{
355
    if (config.getBoolValue("enableGamma"))
356
    {
357
        SDL::setGamma(mainGraphics->getWindow(),
358
            config.getFloatValue("gamma"));
359
    }
360
}
361
362
void WindowManager::applyVSync()
363
{
364
    const int val = config.getIntValue("vsync");
365
    if (val > 0 && val < 2)
366
        SDL::setVsync(val);
367
}
368
369
void WindowManager::applyKeyRepeat()
370
{
371
#ifndef USE_SDL2
372
    SDL_EnableKeyRepeat(config.getIntValue("repeateDelay"),
373
        config.getIntValue("repeateInterval"));
374
#endif  // USE_SDL2
375
}
376
377
void WindowManager::applyScale()
378
{
379
    const int scale = config.getIntValue("scale");
380
    if (mainGraphics->getScale() == scale)
381
        return;
382
    mainGraphics->setScale(scale);
383
    doResizeVideo(mainGraphics->mActualWidth,
384
        mainGraphics->mActualHeight,
385
        true);
386
}
387
388
void WindowManager::setIsMinimized(const bool n)
389
{
390
    mIsMinimized = n;
391
    if (!n && mNewMessageFlag)
392
    {
393
        mNewMessageFlag = false;
394
        SDL::SetWindowTitle(mainGraphics->getWindow(),
395
            settings.windowCaption.c_str());
396
    }
397
}
398
399
void WindowManager::newChatMessage()
400
{
401
    if (!mNewMessageFlag && mIsMinimized)
402
    {
403
        // show * on window caption
404
        SDL::SetWindowTitle(mainGraphics->getWindow(),
405
            ("*" + settings.windowCaption).c_str());
406
        mNewMessageFlag = true;
407
    }
408
}
409
410
void WindowManager::setIcon()
411
{
412
#ifndef ANDROID
413
    std::string iconFile = branding.getValue("appIcon", "icons/manaplus");
414
#ifdef WIN32
415
    iconFile.append(".ico");
416
#else  // WIN32
417
418
    iconFile.append(".png");
419
#endif  // WIN32
420
421
    iconFile = VirtFs::getPath(iconFile);
422
    logger->log("Loading icon from file: %s", iconFile.c_str());
423
424
#ifdef WIN32
425
    static SDL_SysWMinfo pInfo;
426
    if (mainGraphics)
427
        SDL::getWindowWMInfo(mainGraphics->getWindow(), &pInfo);
428
    else
429
        SDL::getWindowWMInfo(nullptr, &pInfo);
430
    // Attempt to load icon from .ico file
431
    HICON icon = static_cast<HICON>(LoadImage(nullptr,
432
        iconFile.c_str(),
433
        IMAGE_ICON,
434
        64, 64,
435
        LR_LOADFROMFILE));
436
    // If it's failing, we load the default resource file.
437
    if (!icon)
438
    {
439
        logger->log("icon load error");
440
        icon = LoadIcon(GetModuleHandle(nullptr), "A");
441
    }
442
    if (icon)
443
    {
444
#ifdef WIN64
445
        SetClassLongPtr(pInfo.window,
446
            GCLP_HICON,
447
            reinterpret_cast<LONG_PTR>(icon));
448
#else  // WIN64
449
        SetClassLong(pInfo.window,
450
            GCL_HICON,
451
            reinterpret_cast<LONG>(icon));
452
#endif  // WIN64
453
    }
454
#else  // WIN32
455
456
    mIcon = MIMG_Load(iconFile.c_str());
457
    if (mIcon != nullptr)
458
    {
459
#ifdef USE_SDL2
460
        SDL_SetSurfaceAlphaMod(mIcon, SDL_ALPHA_OPAQUE);
461
#else  // USE_SDL2
462
463
        SDL_SetAlpha(mIcon, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
464
#endif  // USE_SDL2
465
466
        SDL::SetWindowIcon(mainGraphics->getWindow(), mIcon);
467
    }
468
#endif  // WIN32
469
#endif  // ANDROID
470
}
471
472
bool WindowManager::isKeyboardVisible()
473
{
474
#ifdef USE_SDL2
475
    return SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE;
476
#else  // USE_SDL2
477
478
    return mKeyboardHeight > 1;
479
#endif  // USE_SDL2
480
}
481
482
bool WindowManager::getIsMinimized()
483
{
484
    return mIsMinimized;
485
}
486
487
#ifndef USE_SDL2
488
void WindowManager::updateScreenKeyboard(const int height)
489
{
490
    mKeyboardHeight = height;
491
}
492
#endif  // USE_SDL2
493
494
215
void WindowManager::deleteIcon()
495
{
496
215
    MSDL_FreeSurface(mIcon);
497
215
    mIcon = nullptr;
498
215
}