Subversion Repositories tpanel

Rev

Rev 446 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
446 andreas 1
/*
2
 * Copyright (C) 2023 by Andreas Theofilu <andreas@theosys.at>
3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software Foundation,
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
17
 */
18
 
19
#include <functional>
20
 
21
#include "tsystembutton.h"
22
#include "tpagemanager.h"
23
#include "tbutton.h"
24
#include "terror.h"
25
#include "tresources.h"
26
 
27
#define MAX_BANK        3
28
 
29
#define DISPLAY_LINE    0
30
 
31
// Key definitions
32
#define KB_DISPLAY_INPUT_S  4
33
#define KB_DISPLAY_INPUT_M  5
34
#define KB_DISPLAY_INFO     6
35
 
36
#define KB_KEYBOARD_KEY     201
37
 
38
#define KB_SPACE            202
39
#define KB_ENTER            203
40
#define KB_BACKSPACE        208
41
#define KB_CLEAR            210
42
#define KB_CANCEL           211
43
#define KB_SUBMIT           212
44
#define KB_CAPS_LOCK        221
45
#define KB_BANK3            222
46
#define KB_SHIFT            226
47
 
48
using std::string;
49
using std::vector;
50
using std::bind;
51
using namespace Button;
52
 
53
TSystemButton::SYS_BUTTONS _sysButtons[] = {
54
    {   0, 4, TSystemButton::KEY_INPUT_SINGLE },   // A single line textarea getting typed keys for keypad
55
    {   0, 5, TSystemButton::KEY_INPUT_MULTI },    // A multiline textarea getting typed keys for keyboard
56
    {   0, 6, TSystemButton::KEY_BUTTON },         // A button showing the prompt text comming from the call to the keyboard
57
    { 201, 0, TSystemButton::KEY_KEY },            // A keyboard key
58
    { 202, 0, TSystemButton::KEY_BUTTON },         // Space button
59
    { 203, 0, TSystemButton::KEY_BUTTON },         // Enter/Return button
60
    { 208, 0, TSystemButton::KEY_BUTTON },         // Backspace button
61
    { 210, 0, TSystemButton::KEY_BUTTON },         // Clear button
62
    { 211, 0, TSystemButton::KEY_BUTTON },         // The keyboard cancel button
63
    { 212, 0, TSystemButton::KEY_BUTTON },         // The keyboard submit button
64
    { 221, 0, TSystemButton::KEY_BUTTON },         // bank 2; Caps lock button
65
    { 222, 0, TSystemButton::KEY_BUTTON },         // Bank 3; lock button
66
    { 226, 0, TSystemButton::KEY_BUTTON },         // Bank 2; shift button
67
    // Virtual keyboard keys
68
    { 501, 0, TSystemButton::KEY_BUTTON },         // ESC
69
    { 502, 0, TSystemButton::KEY_BUTTON },         // !\n1
70
    { 503, 0, TSystemButton::KEY_BUTTON },         // @\n2
71
    { 504, 0, TSystemButton::KEY_BUTTON },         // #\n3
72
    { 505, 0, TSystemButton::KEY_BUTTON },         // $\n4
73
    { 506, 0, TSystemButton::KEY_BUTTON },         // %\n5
74
    { 507, 0, TSystemButton::KEY_BUTTON },         // ^\n6
75
    { 508, 0, TSystemButton::KEY_BUTTON },         // &\n7
76
    { 509, 0, TSystemButton::KEY_BUTTON },         // *\n8
77
    { 510, 0, TSystemButton::KEY_BUTTON },         // (\n9
78
    { 511, 0, TSystemButton::KEY_BUTTON },         // )\n0
79
    { 512, 0, TSystemButton::KEY_BUTTON },         // _\n-
80
    { 513, 0, TSystemButton::KEY_BUTTON },         // +\n=
81
    { 514, 0, TSystemButton::KEY_BUTTON },         // Backspace
82
    { 515, 0, TSystemButton::KEY_BUTTON },         // TAB
83
    { 516, 0, TSystemButton::KEY_BUTTON },         // Q
84
    { 517, 0, TSystemButton::KEY_BUTTON },         // W
85
    { 518, 0, TSystemButton::KEY_BUTTON },         // E
86
    { 519, 0, TSystemButton::KEY_BUTTON },         // R
87
    { 520, 0, TSystemButton::KEY_BUTTON },         // T
88
    { 521, 0, TSystemButton::KEY_BUTTON },         // Y
89
    { 522, 0, TSystemButton::KEY_BUTTON },         // U
90
    { 523, 0, TSystemButton::KEY_BUTTON },         // I
91
    { 524, 0, TSystemButton::KEY_BUTTON },         // O
92
    { 525, 0, TSystemButton::KEY_BUTTON },         // P
93
    { 526, 0, TSystemButton::KEY_BUTTON },         // {\n[
94
    { 527, 0, TSystemButton::KEY_BUTTON },         // }\n]
95
    { 528, 0, TSystemButton::KEY_BUTTON },         // Enter
96
    { 529, 0, TSystemButton::KEY_BUTTON },         // Ctrl left
97
    { 530, 0, TSystemButton::KEY_BUTTON },         // A
98
    { 531, 0, TSystemButton::KEY_BUTTON },         // S
99
    { 532, 0, TSystemButton::KEY_BUTTON },         // D
100
    { 533, 0, TSystemButton::KEY_BUTTON },         // F
101
    { 534, 0, TSystemButton::KEY_BUTTON },         // G
102
    { 535, 0, TSystemButton::KEY_BUTTON },         // H
103
    { 536, 0, TSystemButton::KEY_BUTTON },         // J
104
    { 537, 0, TSystemButton::KEY_BUTTON },         // K
105
    { 538, 0, TSystemButton::KEY_BUTTON },         // L
106
    { 539, 0, TSystemButton::KEY_BUTTON },         // :\n;
107
    { 540, 0, TSystemButton::KEY_BUTTON },         // "\n'
108
    { 541, 0, TSystemButton::KEY_BUTTON },         // ~\n`
109
    { 542, 0, TSystemButton::KEY_BUTTON },         // Shift left
110
    { 543, 0, TSystemButton::KEY_BUTTON },         // |
111
    { 544, 0, TSystemButton::KEY_BUTTON },         // Z
112
    { 545, 0, TSystemButton::KEY_BUTTON },         // X
113
    { 546, 0, TSystemButton::KEY_BUTTON },         // C
114
    { 547, 0, TSystemButton::KEY_BUTTON },         // V
115
    { 548, 0, TSystemButton::KEY_BUTTON },         // B
116
    { 549, 0, TSystemButton::KEY_BUTTON },         // N
117
    { 550, 0, TSystemButton::KEY_BUTTON },         // M
118
    { 551, 0, TSystemButton::KEY_BUTTON },         // <\n,
119
    { 552, 0, TSystemButton::KEY_BUTTON },         // >\n.
120
    { 553, 0, TSystemButton::KEY_BUTTON },         // ?\n/
121
    { 554, 0, TSystemButton::KEY_BUTTON },         // Shift right
122
    { 556, 0, TSystemButton::KEY_BUTTON },         // Alt left
123
    { 557, 0, TSystemButton::KEY_BUTTON },         // Space
124
    { 558, 0, TSystemButton::KEY_BUTTON },         // Caps lock
125
    { 559, 0, TSystemButton::KEY_BUTTON },         // F1
126
    { 560, 0, TSystemButton::KEY_BUTTON },         // F2
127
    { 561, 0, TSystemButton::KEY_BUTTON },         // F3
128
    { 562, 0, TSystemButton::KEY_BUTTON },         // F4
129
    { 563, 0, TSystemButton::KEY_BUTTON },         // F5
130
    { 564, 0, TSystemButton::KEY_BUTTON },         // F6
131
    { 565, 0, TSystemButton::KEY_BUTTON },         // F7
132
    { 566, 0, TSystemButton::KEY_BUTTON },         // F8
133
    { 567, 0, TSystemButton::KEY_BUTTON },         // F9
134
    { 568, 0, TSystemButton::KEY_BUTTON },         // F10
135
    { 587, 0, TSystemButton::KEY_BUTTON },         // F11
136
    { 588, 0, TSystemButton::KEY_BUTTON },         // F12
137
 
138
    { 597, 0, TSystemButton::KEY_BUTTON },         // Ctrl right
139
 
140
    { 600, 0, TSystemButton::KEY_BUTTON },         // Alt right (AltGr)
141
 
142
    { 602, 0, TSystemButton::KEY_BUTTON },         // Home
143
    { 603, 0, TSystemButton::KEY_BUTTON },         // Arrow up
144
    { 604, 0, TSystemButton::KEY_BUTTON },         // PgUp
145
    { 605, 0, TSystemButton::KEY_BUTTON },         // Arrow left
146
    { 606, 0, TSystemButton::KEY_BUTTON },         // Arrow right
147
    { 607, 0, TSystemButton::KEY_BUTTON },         // End
148
    { 608, 0, TSystemButton::KEY_BUTTON },         // Arrow down
149
    { 609, 0, TSystemButton::KEY_BUTTON },         // PgDn
150
    { 610, 0, TSystemButton::KEY_BUTTON },         // Insert
151
    { 611, 0, TSystemButton::KEY_BUTTON },         // Delete
152
    {   0, 0, TSystemButton::KEY_UNDEFINED}        // End of table marker
153
};
154
 
155
TSystemButton::TSystemButton()
156
{
157
    DECL_TRACER("TSystemButton::TSystemButton()");
158
}
159
 
160
TSystemButton::~TSystemButton()
161
{
162
    DECL_TRACER("TSystemButton::~TSystemButton()");
163
 
164
    setBank(1);
165
    mButtons.clear();
166
}
167
 
168
void TSystemButton::addSysButton(TButton *bt)
169
{
170
    DECL_TRACER("TSystemButton::addButton(TButton *bt)");
171
 
172
    if (!bt)
173
    {
174
        MSG_WARNING("No valid button pointer!");
175
        return;
176
    }
177
 
178
    if (!(bt->getAddressPort() == 0 && bt->getAddressChannel() > 0) &&
179
        !(bt->getChannelPort() == 0 && bt->getChannelNumber() > 0) &&
180
        bt->getButtonType() != TEXT_INPUT)
181
    {
182
        MSG_DEBUG("No system keyboard button: channel number=" << bt->getChannelNumber() << ", channel port=" << bt->getChannelPort());
183
        return;
184
    }
185
 
186
    // First we look if the button is already there
187
    if (!mButtons.empty())
188
    {
189
        vector<TButton *>::iterator iter;
190
        int channel = bt->getChannelNumber();
191
        int addrChannel = bt->getAddressChannel();
192
 
193
        for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
194
        {
195
            TButton *button = *iter;
196
 
197
            if (channel == button->getChannelNumber() &&
198
                addrChannel == button->getAddressChannel() &&
199
                bt->getName() == button->getName())
200
            {
201
                MSG_WARNING("Don't add the keyboard button " << button->getName() << " again!");
202
                return;
203
            }
204
        }
205
    }
206
 
207
    // If the button is an input text field then we add it in any case.
208
    if (bt->getButtonType() == TEXT_INPUT)
209
    {
210
        mButtons.push_back(bt);
211
        return;
212
    }
213
 
214
    // Is the button a recognized system button
215
    int i = 0;
216
 
217
    while(_sysButtons[i].type != KEY_UNDEFINED)
218
    {
219
        if (_sysButtons[i].channel == bt->getChannelNumber() &&
220
            _sysButtons[i].port == bt->getAddressChannel())
221
        {
222
            if (!isKeyboard && bt->getChannelNumber() == KB_KEYBOARD_KEY)
223
            {
224
                char ch = bt->getText(STATE_1)[0];
225
 
226
                if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
227
                    isKeyboard = true;
228
            }
229
 
230
            bt->regCallButtonPress(bind(&TSystemButton::buttonPress, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
231
            mButtons.push_back(bt);
232
            MSG_DEBUG("Button " << bt->getName() << " was added to system keyboard buttons list.");
233
            return;
234
        }
235
 
236
        i++;
237
    }
238
 
239
    MSG_DEBUG("Button " << bt->getName() << " is not a supported system keyboard button!");
240
}
241
 
242
TButton *TSystemButton::getSysButton(int channel, int port)
243
{
244
    DECL_TRACER("TSystemButton::getButton(int channel, int port)");
245
 
246
    if (channel == 0 && port == 0)
247
        return nullptr;
248
 
249
    if (mButtons.empty())
250
        return nullptr;
251
 
252
    vector<TButton *>::iterator iter;
253
 
254
    for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
255
    {
256
        TButton *button = *iter;
257
 
258
        if (button->getChannelNumber() == channel && button->getAddressChannel() == port)
259
            return *iter;
260
    }
261
 
262
    return nullptr;
263
}
264
 
265
void TSystemButton::dropButton(Button::TButton* bt)
266
{
267
    DECL_TRACER("TSystemButton::dropButton(Button::TButton* bt)");
268
 
269
    if (mButtons.empty())
270
        return;
271
 
272
    vector<TButton *>::iterator iter;
273
 
274
    for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
275
    {
276
        TButton *button = *iter;
277
 
278
        if (button == bt)
279
        {
280
            mButtons.erase(iter);
281
            return;
282
        }
283
    }
284
}
285
 
286
void TSystemButton::setBank(int bank)
287
{
288
    DECL_TRACER("TSystemButton::setBank(int bank)");
289
 
290
    if (bank < BANK_1 || bank > BANK_3)
291
    {
292
        MSG_WARNING("Illegal bank " << bank << "! Ignoring it.");
293
        return;
294
    }
295
 
296
    if (mButtons.empty())
297
        return;
298
 
299
    mStateKeyActive = (bank - 1) * 2;
300
    vector<TButton *>::iterator iter;
301
 
302
    for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
303
    {
304
        TButton *button = *iter;
305
 
306
        if (button->getActiveInstance() == mStateKeyActive)
307
            continue;
308
 
309
        if (getSystemButtonType(button->getChannelNumber(), button->getAddressChannel()) == KEY_KEY && button->getNumberInstances() <= (MAX_BANK * 2))
310
            button->setActive(mStateKeyActive);
311
    }
312
}
313
 
314
TSystemButton::SYS_BUTTON_TYPE TSystemButton::getSystemButtonType(int channel, int port)
315
{
316
    DECL_TRACER("TSystemButton::getSystemButtonType(int channel, int port)");
317
 
318
    int i = 0;
319
 
320
    while(_sysButtons[i].type != KEY_UNDEFINED)
321
    {
322
        if (_sysButtons[i].channel == channel && _sysButtons[i].port == port)
323
            return _sysButtons[i].type;
324
 
325
        i++;
326
    }
327
 
328
    return KEY_UNDEFINED;
329
}
330
 
331
TButton *TSystemButton::getSystemInputLine()
332
{
333
    DECL_TRACER("TSystemButton::getSystemInputLine()");
334
 
335
    if (mButtons.empty())
336
        return nullptr;
337
 
338
    vector<TButton *> buffer;
339
    vector<TButton *>::iterator iter;
340
    // The first loop looks for a system input line. If there is one (or more)
341
    // The first one is taken. All other input lines are stored into a temporary
342
    // buffer.
343
    for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
344
    {
345
        TButton *button = *iter;
346
        int chan = button->getAddressChannel();
347
 
348
        if (button->getButtonType() == TEXT_INPUT)
349
        {
350
            if (chan == KB_DISPLAY_INPUT_S || chan == KB_DISPLAY_INPUT_M)
351
                return *iter;
352
 
353
            buffer.push_back(button);
354
        }
355
    }
356
    // The second loop is executed only if there was one or more normal input
357
    // lines.
358
    if (!buffer.empty())
359
    {
360
        for (iter = buffer.begin(); iter != buffer.end(); ++iter)
361
        {
362
            TButton *button = *iter;
363
            // If there is a line which has the focus, it is selected.
364
            if (button->isFocused())
365
                return *iter;
366
        }
367
        // We're here because there were no system input line nor one with
368
        // the focus. Because of this we take the first line in the buffer.
369
        return buffer[0];
370
    }
371
 
372
    return nullptr;
373
}
374
 
375
void TSystemButton::setDistinctFocus(ulong handle)
376
{
377
    DECL_TRACER("TSystemButton::setDistinctFocus(ulong handle)");
378
 
379
    if (mButtons.empty())
380
        return;
381
 
382
    std::thread thr = std::thread([=] {
383
        vector<TButton *>::iterator iter;
384
 
385
        for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
386
        {
387
            TButton *button = *iter;
388
 
389
            if (button->getButtonType() == TEXT_INPUT)
390
            {
391
                if (button->getHandle() == handle && !button->isFocused())
392
                    button->setTextFocus(true);
393
                else if (button->isFocused())
394
                    button->setTextFocus(false);
395
            }
396
        }
397
    });
398
 
399
    thr.detach();
400
}
401
 
402
void TSystemButton::setCursorPosition(ulong handle, int oldPos, int newPos)
403
{
404
    DECL_TRACER("TSystemButton::setCursorPosition(ulong handle, int pos)");
405
 
406
    vector<TButton *>::iterator iter;
407
 
408
    for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
409
    {
410
        TButton *button = *iter;
411
 
412
        if (button->getHandle() == handle)
413
        {
414
            button->setTextCursorPosition(oldPos, newPos);
415
 
416
            if (mLineHandle == handle || button->isFocused())
417
                mCursorPosition = newPos;
418
 
419
            return;
420
        }
421
    }
422
}
423
 
424
void TSystemButton::setInputFocus(ulong handle, bool in)
425
{
426
    DECL_TRACER("TSystemButton::setInputFocus(ulong handle, bool in)");
427
 
428
    if (mLineHandle == handle)
429
        return;
430
 
431
    vector<TButton *>::iterator iter;
432
 
433
    for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
434
    {
435
        TButton *button = *iter;
436
 
437
        if (button->getHandle() == handle && button->getButtonType() == TEXT_INPUT)
438
        {
439
            mLineHandle = handle;
440
            mCursorPosition = button->getTextCursorPosition();
441
            mInputText = button->getText();
442
            button->setTextFocus(in);
443
            MSG_DEBUG("Input text: " << mInputText << ", cursor position: " << mCursorPosition << ", handle: " << handleToString(handle));
444
        }
445
        else if (button->getButtonType() == TEXT_INPUT)
446
            button->setTextFocus(false);
447
    }
448
}
449
 
450
TButton *TSystemButton::getSystemKey(int channel, uint handle)
451
{
452
    DECL_TRACER("TSystemButton::getSystemKey(int channel)");
453
 
454
    uint intHandle = handle;
455
 
456
    vector<TButton *>::iterator iter;
457
 
458
    for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
459
    {
460
        TButton *button = *iter;
461
 
462
        if (handle == 0)
482 andreas 463
            intHandle = static_cast<uint>(button->getHandle());
446 andreas 464
 
465
        if (button->getChannelNumber() == channel && button->getHandle() == intHandle)
466
        {
467
            MSG_DEBUG("Found system key " << button->getName());
468
            return *iter;
469
        }
470
    }
471
 
472
    return nullptr;
473
}
474
 
475
void TSystemButton::buttonPress(int channel, uint handle, bool pressed)
476
{
477
    DECL_TRACER("TSystemButton::buttonPress(int channel, const std::string& text, bool pressed);");
478
 
479
    if (mButtons.empty())
480
        return;
481
 
482
    SYS_BUTTON_TYPE type = getSystemButtonType(channel, 0);
483
 
484
    if (type == KEY_UNDEFINED)
485
        return;
486
 
487
    MSG_DEBUG("Found button of type " << typeToString(type));
488
 
489
    if (channel > 500)
490
    {
491
        handleDedicatedKeys(channel, pressed);
492
        return;
493
    }
494
 
495
    TButton *btShift = nullptr;
496
    TButton *btBank3 = nullptr;
497
    TButton *btCaps = nullptr;
498
 
499
    // Handle the switch keys
500
    if (pressed)
501
    {
502
        if (type == KEY_BUTTON)
503
        {
504
            if (channel == KB_SHIFT)
505
            {
506
                mShift = !mShift;
507
 
508
                if (mShift)
509
                {
510
                    mCapsLock = mBank3 = false;
511
                    mBank = BANK_2;
512
                }
513
                else
514
                    mBank = BANK_1;
515
            }
516
            else if (channel == KB_CAPS_LOCK)
517
            {
518
                mCapsLock = !mCapsLock;
519
 
520
                if (mCapsLock)
521
                {
522
                    mShift = mBank3 = false;
523
                    mBank = BANK_2;
524
                }
525
                else
526
                    mBank = BANK_1;
527
            }
528
            else if (channel == KB_BANK3)
529
            {
530
                mBank3 = !mBank3;
531
 
532
                if (mBank3)
533
                {
534
                    mBank = BANK_3;
535
                    mShift = mCapsLock = false;
536
                }
537
                else
538
                    mBank = BANK_1;
539
            }
540
 
541
            mStateKeyActive = (mBank - 1) * 2 + 1;
542
        }
543
        else if (type == KEY_KEY)
544
        {
545
            mBank = (mBank3 ? BANK_3 : (mShift || mCapsLock ? BANK_2 : BANK_1));
546
            mStateKeyActive = (mBank - 1) * 2 + 1;
547
        }
548
 
549
        btShift = getSystemKey(KB_SHIFT);
550
        btBank3 = getSystemKey(KB_BANK3);
551
        btCaps = getSystemKey(KB_CAPS_LOCK);
552
    }
553
    else
554
        mStateKeyActive = (mBank - 1) * 2;
555
 
556
    MSG_DEBUG("Button " << handleToString(handle) << ": shift is " << (mShift ? "TRUE" : "FALSE") << ", caps lock is " << (mCapsLock ? "TRUE" : "FALSE") << ", current bank: " << mBank << " (" << (mBank3 ? "TRUE" : "FALSE") << "), pressed is " << (pressed ? "TRUE" : "FALSE") << ", instance is " << mStateKeyActive);
557
    // Handle all keys who must be switched as a group
558
    TButton *input = getSystemInputLine();
559
    MSG_DEBUG("Input line was " << (input ? "found" : "not found"));
560
 
561
    if (input && !input->isFocused())
562
        setDistinctFocus(input->getHandle());
563
 
564
    if (pressed)
565
    {
566
        if (btShift)
567
            btShift->setActive(mShift ? STATE_ON : STATE_OFF);
568
 
569
        if (btCaps)
570
            btCaps->setActive(mCapsLock ? STATE_ON : STATE_OFF);
571
 
572
        if (btBank3)
573
            btBank3->setActive(mBank3 ? STATE_ON : STATE_OFF);
574
    }
575
 
576
    uint hd = handle;
577
 
578
    if ((type == KEY_BUTTON && channel != KB_SHIFT && channel != KB_CAPS_LOCK && channel != KB_BANK3) ||
579
        (type == KEY_KEY && !pressed))
580
        hd = HANDLE_UNDEF;
581
 
582
    if (type == KEY_BUTTON && hd != HANDLE_UNDEF && !mShift && !mCapsLock && !mBank3)
583
        hd = HANDLE_UNDEF;
584
 
585
    if (pressed && (channel == KB_BACKSPACE || channel == KB_CANCEL ||
586
        channel == KB_CLEAR || channel == KB_ENTER || channel == KB_SPACE ||
587
        channel == KB_SUBMIT) && hd == HANDLE_UNDEF)
588
        hd = handle;
589
 
590
    setKeysToBank(mBank, hd);
591
 
592
    if (channel == KB_SHIFT || channel == KB_CAPS_LOCK || channel == KB_BANK3)
593
        return;
594
 
595
    TButton *button = nullptr;
596
 
597
    if (channel == KB_SHIFT)
598
        button = btShift;
599
    else if (channel == KB_CAPS_LOCK)
600
        button = btCaps;
601
    else if (channel == KB_BANK3)
602
        button = btBank3;
603
    else
604
        button = getSystemKey(channel, (type == KEY_KEY ? handle : 0));
605
 
606
    if (!button)
607
        return;
608
 
609
    if (pressed && type == KEY_KEY)
610
    {
611
        string letter = button->getText(mStateKeyActive);
612
 
613
        if ((size_t)mCursorPosition < mInputText.length())
614
        {
615
            string left, right;
616
 
617
            if (mCursorPosition > 0)
618
                left = mInputText.substr(0, mCursorPosition);
619
 
620
            right = mInputText.substr(mCursorPosition);
621
            mInputText = left + letter + right;
622
            mCursorPosition++;
623
        }
624
        else
625
        {
626
            mInputText.append(letter);
627
            mCursorPosition++;
628
        }
629
 
630
        if (input)
631
        {
632
            input->setText(mInputText, 0);
633
            input->setTextCursorPosition(0, mCursorPosition);
634
        }
635
 
636
        if (gPageManager)
637
            gPageManager->sendKeyStroke(letter[0]);
638
 
639
        MSG_DEBUG("Actual text: " << mInputText);
640
        mShift = mBank3 = false;
641
        mBank = (mCapsLock ? BANK_2 : BANK_1);
642
        return;
643
    }
644
 
645
    // Handle control keys
646
    if (pressed)
647
    {
648
        string kbtype = (isKeyboard ? "KEYB-" : "KEYP-");
649
 
650
        switch(channel)
651
        {
652
            case KB_BACKSPACE:
653
                if (gPageManager)
654
                    gPageManager->sendKeyboard(kbtype + "BACKSPACE");
655
 
656
                if (mCursorPosition > 0)
657
                {
658
                    if ((size_t)mCursorPosition < mInputText.length())
659
                    {
660
                        string old = mInputText;
661
                        mInputText = mInputText.substr(0, mCursorPosition - 1);
662
 
663
                        if (old.length() > (size_t)mCursorPosition)
664
                            mInputText = old.substr(mCursorPosition);
665
                    }
666
                    else
667
                        mInputText = mInputText.substr(0, mInputText.length() - 1);
668
 
669
                    mCursorPosition--;
670
 
671
                    if (input)
672
                    {
673
                        input->setText(mInputText, 0);
674
                        input->setTextCursorPosition(0, mCursorPosition);
675
                    }
676
                }
677
 
678
                mShift = mBank3 = false;
679
                mBank = (mCapsLock ? BANK_2 : BANK_1);
680
            break;
681
 
682
            case KB_CANCEL:
683
                if (gPageManager)
684
                    gPageManager->sendKeyboard(kbtype + "ABORT");
685
 
686
                mInputText.clear();
687
                mCursorPosition = 0;
688
 
689
                if (input)
690
                {
691
                    input->setText("", 0);
692
                    input->setTextCursorPosition(0, mCursorPosition);
693
                }
694
 
695
                mShift = mBank3 = mCapsLock = false;
696
                mBank = BANK_1;
697
            break;
698
 
699
            case KB_CLEAR:
700
                if (gPageManager)
701
                    gPageManager->sendKeyboard(kbtype + "CLEAR");
702
 
703
                mInputText.clear();
704
                mCursorPosition = 0;
705
 
706
                if (input)
707
                {
708
                    input->setText(mInputText, 0);
709
                    input->setTextCursorPosition(0, mCursorPosition);
710
                }
711
 
712
                mShift = mBank3 = false;
713
                mBank = (mCapsLock ? BANK_2 : BANK_1);
714
            break;
715
 
716
            case KB_ENTER:
717
                if (gPageManager)
718
                    gPageManager->sendKeyboard(kbtype + "ENTER");
719
 
720
                if ((size_t)mCursorPosition < mInputText.length())
721
                {
722
                    string left, right;
723
 
724
                    if (mCursorPosition > 0)
725
                        left = mInputText.substr(0, mCursorPosition);
726
 
727
                    right = mInputText.substr(mCursorPosition);
728
                    mInputText = left + "\n" + right;
729
                    mCursorPosition++;
730
                }
731
                else
732
                {
733
                    mInputText.append("\n");
734
                    mCursorPosition++;
735
                }
736
 
737
                if (input)
738
                {
739
                    input->setText(mInputText, 0);
740
                    input->setTextCursorPosition(0, mCursorPosition);
741
                }
742
            break;
743
 
744
            case KB_SPACE:
745
                if (gPageManager)
746
                    gPageManager->sendKeyboard(kbtype + "SPACE");
747
 
748
                if ((size_t)mCursorPosition < mInputText.length())
749
                {
750
                    string left, right;
751
 
752
                    if (mCursorPosition > 0)
753
                        left = mInputText.substr(0, mCursorPosition);
754
 
755
                    right = mInputText.substr(mCursorPosition);
756
                    mInputText = left + " " + right;
757
                    mCursorPosition++;
758
                }
759
                else
760
                {
761
                    mInputText.append(" ");
762
                    mCursorPosition++;
763
                }
764
 
765
                if (input)
766
                {
767
                    input->setText(mInputText, 0);
768
                    input->setTextCursorPosition(0, mCursorPosition);
769
                }
770
 
771
                mShift = mBank3 = false;
772
                mBank = (mCapsLock ? BANK_2 : BANK_1);
773
            break;
774
 
775
            case KB_SUBMIT:
776
                if (gPageManager)
777
                    gPageManager->sendKeyboard(kbtype + mInputText);
778
 
779
                mInputText.clear();
780
 
781
                if (input)
782
                    input->setText(mInputText, 0);
783
 
784
                mShift = mBank3 = mCapsLock = false;
785
                mBank = 1;
786
            break;
787
        }
788
 
789
        MSG_DEBUG("Current string: " << mInputText);
790
    }
791
}
792
 
793
/**
794
 * Set the keys of a keyboard or keypad to the given \b bank. With the \b handle
795
 * one key can be set to pressed state.
796
 * This works for multi bargraph keys with 6 states as well as normal keys
797
 * with only 2 states.
798
 *
799
 * @param bank      The number of the bank the multi bargraph keys should be set.
800
 *                  This is a number between 1 and 3.
801
 * @param handle    If this is >0 and a button with the given handle is found,
802
 *                  The state is increased by 1, so that the button appears
803
 *                  highlighted.
804
 */
805
void TSystemButton::setKeysToBank(int bank, uint handle)
806
{
807
    DECL_TRACER("TSystemButton::setKeysToBank(int bank, int handle)");
808
 
809
    if (mButtons.empty() || bank < BANK_1 || bank > BANK_3)
810
        return;
811
 
812
    std::thread thr = std::thread([=] {
813
        vector<TButton *>::iterator iter;
814
        int inst = (bank - 1) * 2;
815
 
816
        for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
817
        {
818
            TButton *button = *iter;
819
            int channelNumber = button->getChannelNumber();
482 andreas 820
            uint hdl = static_cast<uint>(button->getHandle());
446 andreas 821
            SYS_BUTTON_TYPE tp = getSystemButtonType(channelNumber, 0);
822
 
823
            if (tp == KEY_KEY)
824
            {
825
                if (handle == hdl)
826
                    button->setBargraphLevel(inst + 1);
827
                else
828
                    button->setBargraphLevel(inst);
829
            }
830
            else if (tp == KEY_BUTTON)
831
            {
832
                if (handle == hdl || (channelNumber == KB_CAPS_LOCK && mCapsLock))
833
                    button->setActive(STATE_ON);
834
                else
835
                    button->setActive(STATE_OFF);
836
            }
837
        }
838
    });
839
 
840
    thr.detach();
841
}
842
 
843
void TSystemButton::handleDedicatedKeys(int channel, bool pressed)
844
{
845
    DECL_TRACER("TSystemButton::handleDedicatedKeys(int channel, bool pressed)");
846
 
847
    if (!gPageManager)
848
        return;
849
 
850
    string kbtype = "KEYB-";
851
 
852
    if (mCapsLock)
853
        mShift = true;
854
 
855
    switch (channel)
856
    {
857
        case 501: sendDedicatedKey(channel, kbtype + "ESC", pressed); break;
858
        case 502: sendDedicatedKey(channel, kbtype + (mShift ? "!" : "1"), pressed); break;
859
        case 503: sendDedicatedKey(channel, kbtype + (mShift ? "@" : "2"), pressed); break;
860
        case 504: sendDedicatedKey(channel, kbtype + (mShift ? "#" : "3"), pressed); break;
861
        case 505: sendDedicatedKey(channel, kbtype + (mShift ? "$" : "4"), pressed); break;
862
        case 506: sendDedicatedKey(channel, kbtype + (mShift ? "%" : "5"), pressed); break;
863
        case 507: sendDedicatedKey(channel, kbtype + (mShift ? "^" : "6"), pressed); break;
864
        case 508: sendDedicatedKey(channel, kbtype + (mShift ? "&" : "7"), pressed); break;
865
        case 509: sendDedicatedKey(channel, kbtype + (mShift ? "*" : "8"), pressed); break;
866
        case 510: sendDedicatedKey(channel, kbtype + (mShift ? "(" : "9"), pressed); break;
867
        case 511: sendDedicatedKey(channel, kbtype + (mShift ? ")" : "0"), pressed); break;
868
        case 512: sendDedicatedKey(channel, kbtype + (mShift ? "_" : "-"), pressed); break;
869
        case 513: sendDedicatedKey(channel, kbtype + (mShift ? "+" : "="), pressed); break;
870
        case 514: sendDedicatedKey(channel, kbtype + "BACKSPACE", pressed); break;
871
        case 515: sendDedicatedKey(channel, kbtype + "TAB", pressed); break;
872
        case 516: sendDedicatedKey(channel, kbtype + (mShift ? "Q" : "q"), pressed); break;
873
        case 517: sendDedicatedKey(channel, kbtype + (mShift ? "W" : "w"), pressed); break;
874
        case 518: sendDedicatedKey(channel, kbtype + (mShift ? "E" : "e"), pressed); break;
875
        case 519: sendDedicatedKey(channel, kbtype + (mShift ? "R" : "r"), pressed); break;
876
        case 520: sendDedicatedKey(channel, kbtype + (mShift ? "T" : "t"), pressed); break;
877
        case 521: sendDedicatedKey(channel, kbtype + (mShift ? "Y" : "y"), pressed); break;
878
        case 522: sendDedicatedKey(channel, kbtype + (mShift ? "U" : "u"), pressed); break;
879
        case 523: sendDedicatedKey(channel, kbtype + (mShift ? "I" : "i"), pressed); break;
880
        case 524: sendDedicatedKey(channel, kbtype + (mShift ? "O" : "o"), pressed); break;
881
        case 525: sendDedicatedKey(channel, kbtype + (mShift ? "P" : "p"), pressed); break;
882
        case 526: sendDedicatedKey(channel, kbtype + (mShift ? "{" : "["), pressed); break;
883
        case 527: sendDedicatedKey(channel, kbtype + (mShift ? "}" : "]"), pressed); break;
884
        case 528: sendDedicatedKey(channel, kbtype + "ENTER", pressed); break;
885
        case 529: sendDedicatedKey(channel, kbtype + "CTRLL", pressed); break;
886
        case 530: sendDedicatedKey(channel, kbtype + (mShift ? "A" : "a"), pressed); break;
887
        case 531: sendDedicatedKey(channel, kbtype + (mShift ? "S" : "s"), pressed); break;
888
        case 532: sendDedicatedKey(channel, kbtype + (mShift ? "D" : "d"), pressed); break;
889
        case 533: sendDedicatedKey(channel, kbtype + (mShift ? "F" : "f"), pressed); break;
890
        case 534: sendDedicatedKey(channel, kbtype + (mShift ? "G" : "g"), pressed); break;
891
        case 535: sendDedicatedKey(channel, kbtype + (mShift ? "H" : "h"), pressed); break;
892
        case 536: sendDedicatedKey(channel, kbtype + (mShift ? "J" : "j"), pressed); break;
893
        case 537: sendDedicatedKey(channel, kbtype + (mShift ? "K" : "k"), pressed); break;
894
        case 538: sendDedicatedKey(channel, kbtype + (mShift ? "L" : "l"), pressed); break;
895
        case 539: sendDedicatedKey(channel, kbtype + (mShift ? ":" : ";"), pressed); break;
896
        case 540: sendDedicatedKey(channel, kbtype + (mShift ? "\"" : "'"), pressed); break;
897
        case 541: sendDedicatedKey(channel, kbtype + (mShift ? "~" : "`"), pressed); break;
898
        case 542: sendDedicatedKey(channel, kbtype + "SHIFTL", pressed); mShift = !mShift; break;
899
        case 543: sendDedicatedKey(channel, kbtype + (mShift ? "|" : "\\"), pressed); break;
900
        case 544: sendDedicatedKey(channel, kbtype + (mShift ? "Z" : "z"), pressed); break;
901
        case 545: sendDedicatedKey(channel, kbtype + (mShift ? "X" : "x"), pressed); break;
902
        case 546: sendDedicatedKey(channel, kbtype + (mShift ? "C" : "c"), pressed); break;
903
        case 547: sendDedicatedKey(channel, kbtype + (mShift ? "V" : "v"), pressed); break;
904
        case 548: sendDedicatedKey(channel, kbtype + (mShift ? "B" : "b"), pressed); break;
905
        case 549: sendDedicatedKey(channel, kbtype + (mShift ? "N" : "n"), pressed); break;
906
        case 550: sendDedicatedKey(channel, kbtype + (mShift ? "M" : "m"), pressed); break;
907
        case 551: sendDedicatedKey(channel, kbtype + (mShift ? "<" : ","), pressed); break;
908
        case 552: sendDedicatedKey(channel, kbtype + (mShift ? ">" : "."), pressed); break;
909
        case 553: sendDedicatedKey(channel, kbtype + (mShift ? "?" : "/"), pressed); break;
910
        case 554: sendDedicatedKey(channel, kbtype + "SHIFTR", pressed); mShift = !mShift; break;
911
        case 556: sendDedicatedKey(channel, kbtype + "ALT", pressed); break;
912
        case 557: sendDedicatedKey(channel, kbtype + "SPACE", pressed); break;
913
        case 558: sendDedicatedKey(channel, kbtype + "CAPS", pressed); mCapsLock = !mCapsLock; break;
914
        case 559: sendDedicatedKey(channel, kbtype + "F1", pressed); break;
915
        case 560: sendDedicatedKey(channel, kbtype + "F2", pressed); break;
916
        case 561: sendDedicatedKey(channel, kbtype + "F3", pressed); break;
917
        case 562: sendDedicatedKey(channel, kbtype + "F4", pressed); break;
918
        case 563: sendDedicatedKey(channel, kbtype + "F5", pressed); break;
919
        case 564: sendDedicatedKey(channel, kbtype + "F6", pressed); break;
920
        case 565: sendDedicatedKey(channel, kbtype + "F7", pressed); break;
921
        case 566: sendDedicatedKey(channel, kbtype + "F8", pressed); break;
922
        case 567: sendDedicatedKey(channel, kbtype + "F9", pressed); break;
923
        case 568: sendDedicatedKey(channel, kbtype + "F10", pressed); break;
924
        case 587: sendDedicatedKey(channel, kbtype + "F11", pressed); break;
925
        case 588: sendDedicatedKey(channel, kbtype + "F12", pressed); break;
926
        case 597: sendDedicatedKey(channel, kbtype + "CTRLR", pressed); break;
927
        case 600: sendDedicatedKey(channel, kbtype + "ALTGR", pressed); break;
928
        case 602: sendDedicatedKey(channel, kbtype + "HOME", pressed); break;
929
        case 603: sendDedicatedKey(channel, kbtype + "UP", pressed); break;
930
        case 604: sendDedicatedKey(channel, kbtype + "PGDN", pressed); break;
931
        case 605: sendDedicatedKey(channel, kbtype + "LEFT", pressed); break;
932
        case 606: sendDedicatedKey(channel, kbtype + "RIGHT", pressed); break;
933
        case 607: sendDedicatedKey(channel, kbtype + "END", pressed); break;
934
        case 608: sendDedicatedKey(channel, kbtype + "DOWN", pressed); break;
935
        case 609: sendDedicatedKey(channel, kbtype + "PGDN", pressed); break;
936
        case 610: sendDedicatedKey(channel, kbtype + "INS", pressed); break;
937
        case 611: sendDedicatedKey(channel, kbtype + "DEL", pressed); break;
938
    }
939
 
940
    if ((mShift && channel != 554 && channel != 542) || mCapsLock)
941
        mShift = false;
942
}
943
 
944
void TSystemButton::sendDedicatedKey(int channel, const string str, bool pressed)
945
{
946
    DECL_TRACER("TSystemButton::sendDedicatedKey(int channel, const string str)");
947
 
948
    TButton *button = getSysButton(channel, 0);
949
 
950
    if (button)
951
        button->setActive(pressed ? STATE_ON : STATE_OFF);
952
 
953
    gPageManager->sendKeyboard(str);
954
}
955
 
956
/**
957
 * @brief Translates the button types into a string.
958
 * This method is for debugging purposes only!
959
 *
960
 * @param type  The enum number of the button type.
961
 *
962
 * @return Returns the string representation of the button type.
963
 */
964
string TSystemButton::typeToString(TSystemButton::SYS_BUUTON_TYPE type)
965
{
966
    switch (type)
967
    {
968
        case KEY_BUTTON:            return "KEY_BUTTON";
969
        case KEY_INPUT_MULTI:       return "KEY_INPUT_MULTI";
970
        case KEY_INPUT_SINGLE:      return "KEY_INPUT_SINGLE";
971
        case KEY_KEY:               return "KEY_KEY";
972
        case KEY_UNDEFINED:         return "KEY_UNDEFINED";
973
    }
974
 
975
    return string();
976
}