GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/windowmanager.cpp Lines: 74 162 45.7 %
Date: 2017-11-29 Branches: 77 238 32.4 %

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-2017  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
386
void WindowManager::init()
114
{
115
    // Initialize frame limiting
116
386
    fpsManager.framecount = 0;
117
386
    fpsManager.rateticks = 0;
118
386
    fpsManager.lastticks = 0;
119
386
    fpsManager.rate = 0;
120
386
}
121
122
2
void WindowManager::createWindows()
123
{
124
2
    userPalette = new UserPalette;
125
#ifndef DYECMD
126
2
    CREATEWIDGETV0(setupWindow, SetupWindow);
127
2
    CREATEWIDGETV0(helpWindow, HelpWindow);
128
2
    CREATEWIDGETV0(didYouKnowWindow, DidYouKnowWindow);
129
2
    CREATEWIDGETV0(popupMenu, PopupMenu);
130
2
    CREATEWIDGETV0(beingPopup, BeingPopup);
131
2
    CREATEWIDGETV0(textBoxPopup, TextBoxPopup);
132
2
    CREATEWIDGETV0(itemPopup, ItemPopup);
133
2
    CREATEWIDGETV0(spellPopup, SpellPopup);
134
2
    CREATEWIDGETV0(skillPopup, SkillPopup);
135
2
    delete2(debugChatTab);
136
2
    if (chatWindow != nullptr)
137
    {
138
        chatWindow->scheduleDelete();
139
        chatWindow = nullptr;
140
    }
141

8
    CREATEWIDGETV(chatWindow, ChatWindow,
142
        "DebugChat");
143
    // TRANSLATORS: chat tab header
144

22
    debugChatTab = new ChatTab(chatWindow, _("Debug"), "",
145

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

8
    CREATEWIDGETV(debugWindow, DebugWindow,
154
        "DebugDebug");
155
#endif  // DYECMD
156
157
2
    CREATEWIDGETV0(textPopup, TextPopup);
158
2
}
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
386
void WindowManager::deleteWindows()
181
{
182
#ifndef DYECMD
183
386
    delete2(textBoxPopup);
184
386
    delete2(beingPopup);
185
386
    delete2(itemPopup);
186
386
    delete2(spellPopup);
187
386
    delete2(skillPopup);
188
772
    delete2(popupMenu);
189
386
    delete2(didYouKnowWindow);
190
772
    delete2(helpWindow);
191
386
    delete2(setupWindow);
192
386
    delete2(userPalette);
193
386
    delete2(spellManager)
194
386
    delete2(spellShortcut)
195
196
386
    delete2(debugChatTab);
197
386
    delete2(chatWindow);
198
386
    delete2(debugWindow);
199
#endif  // DYECMD
200
201
386
    delete2(textPopup);
202
386
}
203
204
2
void WindowManager::initTitle()
205
{
206
2
    if (settings.options.test.empty())
207
    {
208
4
        settings.windowCaption = strprintf("%s %s",
209

10
            branding.getStringValue("appName").c_str(),
210
            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
2
    SDL::SetWindowTitle(mainGraphics->getWindow(),
221
        settings.windowCaption.c_str());
222
2
}
223
224
6
void WindowManager::updateTitle()
225
{
226
12
    std::string str;
227
6
    if (settings.login.empty())
228
        str = settings.serverName;
229
    else
230
2
        str.append(settings.login).append(" ").append(settings.serverName);
231
6
    if (str.empty())
232
    {
233
4
        settings.windowCaption = strprintf("%s %s",
234

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

20
            branding.getStringValue("appName").c_str(),
241
            SMALL_VERSION,
242
            str.c_str());
243
    }
244
6
    SDL::SetWindowTitle(mainGraphics->getWindow(),
245
        settings.windowCaption.c_str());
246
6
}
247
248
12
void WindowManager::setFramerate(const unsigned int fpsLimit)
249
{
250
12
    if (fpsLimit == 0u)
251
        return;
252
253
8
    if (!settings.limitFps)
254
        return;
255
256
4
    SDL_setFramerate(&fpsManager, fpsLimit);
257
}
258
259
12
int WindowManager::getFramerate()
260
{
261
12
    if (!settings.limitFps)
262
        return 0;
263
264
6
    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
384
void WindowManager::deleteIcon()
495
{
496
384
    MSDL_FreeSurface(mIcon);
497
384
    mIcon = nullptr;
498
384
}