Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
266 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"
271 andreas 25
#include "tresources.h"
266 andreas 26
 
27
#define MAX_BANK        3
28
 
29
#define DISPLAY_LINE    0
30
 
31
// Key definitions
308 andreas 32
#define KB_DISPLAY_INPUT_S  4
33
#define KB_DISPLAY_INPUT_M  5
266 andreas 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;
270 andreas 50
using std::bind;
266 andreas 51
using namespace Button;
52
 
53
TSystemButton::SYS_BUTTONS _sysButtons[] = {
269 andreas 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
266 andreas 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
 
267 andreas 164
    setBank(1);
266 andreas 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) &&
308 andreas 179
        !(bt->getChannelPort() == 0 && bt->getChannelNumber() > 0) &&
180
        bt->getButtonType() != TEXT_INPUT)
266 andreas 181
    {
271 andreas 182
        MSG_DEBUG("No system keyboard button: channel number=" << bt->getChannelNumber() << ", channel port=" << bt->getChannelPort());
266 andreas 183
        return;
184
    }
185
 
186
    // First we look if the button is already there
187
    if (!mButtons.empty())
188
    {
189
        vector<TButton *>::iterator iter;
271 andreas 190
        int channel = bt->getChannelNumber();
191
        int addrChannel = bt->getAddressChannel();
266 andreas 192
 
193
        for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
194
        {
195
            TButton *button = *iter;
196
 
271 andreas 197
            if (channel == button->getChannelNumber() &&
198
                addrChannel == button->getAddressChannel() &&
267 andreas 199
                bt->getName() == button->getName())
266 andreas 200
            {
271 andreas 201
                MSG_WARNING("Don't add the keyboard button " << button->getName() << " again!");
266 andreas 202
                return;
203
            }
204
        }
205
    }
206
 
308 andreas 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
 
266 andreas 214
    // Is the button a recognized system button
215
    int i = 0;
216
 
217
    while(_sysButtons[i].type != KEY_UNDEFINED)
218
    {
271 andreas 219
        if (_sysButtons[i].channel == bt->getChannelNumber() &&
266 andreas 220
            _sysButtons[i].port == bt->getAddressChannel())
221
        {
269 andreas 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
 
266 andreas 230
            bt->regCallButtonPress(bind(&TSystemButton::buttonPress, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
231
            mButtons.push_back(bt);
271 andreas 232
            MSG_DEBUG("Button " << bt->getName() << " was added to system keyboard buttons list.");
266 andreas 233
            return;
234
        }
235
 
236
        i++;
237
    }
238
 
271 andreas 239
    MSG_DEBUG("Button " << bt->getName() << " is not a supported system keyboard button!");
266 andreas 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
 
296 andreas 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
 
266 andreas 286
void TSystemButton::setBank(int bank)
287
{
288
    DECL_TRACER("TSystemButton::setBank(int bank)");
289
 
269 andreas 290
    if (bank < BANK_1 || bank > BANK_3)
266 andreas 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
 
310 andreas 335
    if (mButtons.empty())
336
        return nullptr;
337
 
338
    vector<TButton *> buffer;
266 andreas 339
    vector<TButton *>::iterator iter;
310 andreas 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.
266 andreas 343
    for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
344
    {
345
        TButton *button = *iter;
308 andreas 346
        int chan = button->getAddressChannel();
266 andreas 347
 
310 andreas 348
        if (button->getButtonType() == TEXT_INPUT)
268 andreas 349
        {
310 andreas 350
            if (chan == KB_DISPLAY_INPUT_S || chan == KB_DISPLAY_INPUT_M)
351
                return *iter;
352
 
353
            buffer.push_back(button);
268 andreas 354
        }
266 andreas 355
    }
310 andreas 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
    }
266 andreas 371
 
372
    return nullptr;
373
}
374
 
310 andreas 375
void TSystemButton::setDistinctFocus(ulong handle)
376
{
377
    DECL_TRACER("TSystemButton::setDistinctFocus(ulong handle)");
378
 
379
    if (mButtons.empty())
380
        return;
381
 
382
    vector<TButton *>::iterator iter;
383
 
384
    for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
385
    {
386
        TButton *button = *iter;
387
 
388
        if (button->getButtonType() == TEXT_INPUT)
389
        {
390
            if (button->getHandle() == handle && !button->isFocused())
391
                button->setTextFocus(true);
392
            else if (button->isFocused())
393
                button->setTextFocus(false);
394
        }
395
    }
396
}
397
 
309 andreas 398
void TSystemButton::setCursorPosition(ulong handle, int oldPos, int newPos)
399
{
400
    DECL_TRACER("TSystemButton::setCursorPosition(ulong handle, int pos)");
401
 
402
    vector<TButton *>::iterator iter;
403
 
404
    for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
405
    {
406
        TButton *button = *iter;
407
 
408
        if (button->getHandle() == handle)
409
        {
410
            button->setTextCursorPosition(oldPos, newPos);
411
 
412
            if (mLineHandle == handle || button->isFocused())
413
                mCursorPosition = newPos;
414
 
415
            return;
416
        }
417
    }
418
}
419
 
420
void TSystemButton::setInputFocus(ulong handle, bool in)
421
{
422
    DECL_TRACER("TSystemButton::setInputFocus(ulong handle, bool in)");
423
 
424
    if (mLineHandle == handle)
425
        return;
426
 
427
    vector<TButton *>::iterator iter;
428
 
429
    for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
430
    {
431
        TButton *button = *iter;
432
 
433
        if (button->getHandle() == handle && button->getButtonType() == TEXT_INPUT)
434
        {
435
            mLineHandle = handle;
436
            mCursorPosition = button->getTextCursorPosition();
437
            mInputText = button->getText();
438
            button->setTextFocus(in);
439
        }
440
        else if (button->getButtonType() == TEXT_INPUT)
441
            button->setTextFocus(false);
442
    }
443
}
444
 
268 andreas 445
TButton *TSystemButton::getSystemKey(int channel, uint handle)
266 andreas 446
{
447
    DECL_TRACER("TSystemButton::getSystemKey(int channel)");
448
 
268 andreas 449
    uint intHandle = handle;
266 andreas 450
 
451
    vector<TButton *>::iterator iter;
452
 
453
    for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
454
    {
455
        TButton *button = *iter;
456
 
268 andreas 457
        if (handle == 0)
458
            intHandle = button->getHandle();
459
 
460
        if (button->getChannelNumber() == channel && button->getHandle() == intHandle)
461
        {
462
            MSG_DEBUG("Found system key " << button->getName());
266 andreas 463
            return *iter;
268 andreas 464
        }
266 andreas 465
    }
466
 
467
    return nullptr;
468
}
469
 
268 andreas 470
void TSystemButton::buttonPress(int channel, uint handle, bool pressed)
266 andreas 471
{
472
    DECL_TRACER("TSystemButton::buttonPress(int channel, const std::string& text, bool pressed);");
473
 
474
    if (mButtons.empty())
475
        return;
476
 
477
    SYS_BUTTON_TYPE type = getSystemButtonType(channel, 0);
478
 
479
    if (type == KEY_UNDEFINED)
480
        return;
481
 
268 andreas 482
    MSG_DEBUG("Found button of type " << typeToString(type));
269 andreas 483
 
484
    if (channel > 500)
485
    {
486
        handleDedicatedKeys(channel, pressed);
487
        return;
488
    }
489
 
268 andreas 490
    TButton *btShift = nullptr;
491
    TButton *btBank3 = nullptr;
492
    TButton *btCaps = nullptr;
266 andreas 493
 
494
    // Handle the switch keys
268 andreas 495
    if (pressed)
266 andreas 496
    {
268 andreas 497
        if (type == KEY_BUTTON)
266 andreas 498
        {
268 andreas 499
            if (channel == KB_SHIFT)
500
            {
501
                mShift = !mShift;
502
 
503
                if (mShift)
504
                {
269 andreas 505
                    mCapsLock = mBank3 = false;
506
                    mBank = BANK_2;
268 andreas 507
                }
269 andreas 508
                else
509
                    mBank = BANK_1;
268 andreas 510
            }
511
            else if (channel == KB_CAPS_LOCK)
512
            {
513
                mCapsLock = !mCapsLock;
514
 
515
                if (mCapsLock)
516
                {
269 andreas 517
                    mShift = mBank3 = false;
518
                    mBank = BANK_2;
268 andreas 519
                }
269 andreas 520
                else
521
                    mBank = BANK_1;
268 andreas 522
            }
269 andreas 523
            else if (channel == KB_BANK3)
268 andreas 524
            {
525
                mBank3 = !mBank3;
526
 
527
                if (mBank3)
269 andreas 528
                {
529
                    mBank = BANK_3;
268 andreas 530
                    mShift = mCapsLock = false;
269 andreas 531
                }
532
                else
533
                    mBank = BANK_1;
268 andreas 534
            }
535
 
536
            mStateKeyActive = (mBank - 1) * 2 + 1;
266 andreas 537
        }
268 andreas 538
        else if (type == KEY_KEY)
539
        {
269 andreas 540
            mBank = (mBank3 ? BANK_3 : (mShift || mCapsLock ? BANK_2 : BANK_1));
268 andreas 541
            mStateKeyActive = (mBank - 1) * 2 + 1;
542
        }
543
 
544
        btShift = getSystemKey(KB_SHIFT);
545
        btBank3 = getSystemKey(KB_BANK3);
546
        btCaps = getSystemKey(KB_CAPS_LOCK);
266 andreas 547
    }
268 andreas 548
    else
549
        mStateKeyActive = (mBank - 1) * 2;
266 andreas 550
 
271 andreas 551
    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);
266 andreas 552
    // Handle all keys who must be switched as a group
553
    TButton *input = getSystemInputLine();
268 andreas 554
    MSG_DEBUG("Input line was " << (input ? "found" : "not found"));
266 andreas 555
 
310 andreas 556
    if (input && !input->isFocused())
557
        setDistinctFocus(input->getHandle());
558
 
269 andreas 559
    if (pressed)
560
    {
561
        if (btShift)
562
            btShift->setActive(mShift ? STATE_ON : STATE_OFF);
266 andreas 563
 
269 andreas 564
        if (btCaps)
565
            btCaps->setActive(mCapsLock ? STATE_ON : STATE_OFF);
266 andreas 566
 
269 andreas 567
        if (btBank3)
568
            btBank3->setActive(mBank3 ? STATE_ON : STATE_OFF);
569
    }
266 andreas 570
 
269 andreas 571
    uint hd = handle;
266 andreas 572
 
269 andreas 573
    if ((type == KEY_BUTTON && channel != KB_SHIFT && channel != KB_CAPS_LOCK && channel != KB_BANK3) ||
574
        (type == KEY_KEY && !pressed))
575
        hd = HANDLE_UNDEF;
576
 
577
    if (type == KEY_BUTTON && hd != HANDLE_UNDEF && !mShift && !mCapsLock && !mBank3)
578
        hd = HANDLE_UNDEF;
579
 
580
    if (pressed && (channel == KB_BACKSPACE || channel == KB_CANCEL ||
581
        channel == KB_CLEAR || channel == KB_ENTER || channel == KB_SPACE ||
582
        channel == KB_SUBMIT) && hd == HANDLE_UNDEF)
583
        hd = handle;
584
 
585
    setKeysToBank(mBank, hd);
586
 
268 andreas 587
    if (channel == KB_SHIFT || channel == KB_CAPS_LOCK || channel == KB_BANK3)
588
        return;
266 andreas 589
 
268 andreas 590
    TButton *button = nullptr;
591
 
592
    if (channel == KB_SHIFT)
593
        button = btShift;
594
    else if (channel == KB_CAPS_LOCK)
595
        button = btCaps;
596
    else if (channel == KB_BANK3)
269 andreas 597
        button = btBank3;
268 andreas 598
    else
599
        button = getSystemKey(channel, (type == KEY_KEY ? handle : 0));
600
 
601
    if (!button)
266 andreas 602
        return;
268 andreas 603
 
604
    if (pressed && type == KEY_KEY)
605
    {
269 andreas 606
        string letter = button->getText(mStateKeyActive);
268 andreas 607
 
309 andreas 608
        if ((size_t)mCursorPosition < mInputText.length())
609
        {
610
            string left, right;
611
 
612
            if (mCursorPosition > 0)
613
                left = mInputText.substr(0, mCursorPosition);
614
 
615
            right = mInputText.substr(mCursorPosition);
616
            mInputText = left + letter + right;
617
            mCursorPosition++;
618
        }
619
        else
620
        {
621
            mInputText.append(letter);
622
            mCursorPosition++;
623
        }
624
 
268 andreas 625
        if (input)
309 andreas 626
        {
268 andreas 627
            input->setText(mInputText, 0);
309 andreas 628
            input->setTextCursorPosition(0, mCursorPosition);
629
        }
268 andreas 630
 
269 andreas 631
        if (gPageManager)
632
            gPageManager->sendKeyStroke(letter[0]);
633
 
268 andreas 634
        MSG_DEBUG("Actual text: " << mInputText);
635
        mShift = mBank3 = false;
269 andreas 636
        mBank = (mCapsLock ? BANK_2 : BANK_1);
268 andreas 637
        return;
266 andreas 638
    }
639
 
640
    // Handle control keys
268 andreas 641
    if (pressed)
266 andreas 642
    {
269 andreas 643
        string kbtype = (isKeyboard ? "KEYB-" : "KEYP-");
644
 
268 andreas 645
        switch(channel)
646
        {
647
            case KB_BACKSPACE:
269 andreas 648
                if (gPageManager)
308 andreas 649
                    gPageManager->sendKeyboard(kbtype + "BACKSPACE");
269 andreas 650
 
309 andreas 651
                if (mCursorPosition > 0)
652
                {
653
                    if ((size_t)mCursorPosition < mInputText.length())
654
                    {
655
                        string old = mInputText;
656
                        mInputText = mInputText.substr(0, mCursorPosition - 1);
266 andreas 657
 
309 andreas 658
                        if (old.length() > (size_t)mCursorPosition)
659
                            mInputText = old.substr(mCursorPosition);
660
                    }
661
                    else
662
                        mInputText = mInputText.substr(0, mInputText.length() - 1);
266 andreas 663
 
309 andreas 664
                    mCursorPosition--;
665
 
666
                    if (input)
667
                    {
668
                        input->setText(mInputText, 0);
669
                        input->setTextCursorPosition(0, mCursorPosition);
670
                    }
671
                }
672
 
268 andreas 673
                mShift = mBank3 = false;
269 andreas 674
                mBank = (mCapsLock ? BANK_2 : BANK_1);
268 andreas 675
            break;
266 andreas 676
 
268 andreas 677
            case KB_CANCEL:
678
                if (gPageManager)
269 andreas 679
                    gPageManager->sendKeyboard(kbtype + "ABORT");
266 andreas 680
 
268 andreas 681
                mInputText.clear();
309 andreas 682
                mCursorPosition = 0;
266 andreas 683
 
268 andreas 684
                if (input)
309 andreas 685
                {
268 andreas 686
                    input->setText("", 0);
309 andreas 687
                    input->setTextCursorPosition(0, mCursorPosition);
688
                }
266 andreas 689
 
268 andreas 690
                mShift = mBank3 = mCapsLock = false;
269 andreas 691
                mBank = BANK_1;
268 andreas 692
            break;
266 andreas 693
 
268 andreas 694
            case KB_CLEAR:
269 andreas 695
                if (gPageManager)
696
                    gPageManager->sendKeyboard(kbtype + "CLEAR");
697
 
268 andreas 698
                mInputText.clear();
309 andreas 699
                mCursorPosition = 0;
266 andreas 700
 
268 andreas 701
                if (input)
309 andreas 702
                {
268 andreas 703
                    input->setText(mInputText, 0);
309 andreas 704
                    input->setTextCursorPosition(0, mCursorPosition);
705
                }
266 andreas 706
 
268 andreas 707
                mShift = mBank3 = false;
269 andreas 708
                mBank = (mCapsLock ? BANK_2 : BANK_1);
268 andreas 709
            break;
266 andreas 710
 
268 andreas 711
            case KB_ENTER:
269 andreas 712
                if (gPageManager)
713
                    gPageManager->sendKeyboard(kbtype + "ENTER");
714
 
309 andreas 715
                if ((size_t)mCursorPosition < mInputText.length())
716
                {
717
                    string left, right;
266 andreas 718
 
309 andreas 719
                    if (mCursorPosition > 0)
720
                        left = mInputText.substr(0, mCursorPosition);
721
 
722
                    right = mInputText.substr(mCursorPosition);
723
                    mInputText = left + "\n" + right;
724
                    mCursorPosition++;
725
                }
726
                else
727
                {
728
                    mInputText.append("\n");
729
                    mCursorPosition++;
730
                }
731
 
268 andreas 732
                if (input)
309 andreas 733
                {
268 andreas 734
                    input->setText(mInputText, 0);
309 andreas 735
                    input->setTextCursorPosition(0, mCursorPosition);
736
                }
268 andreas 737
            break;
266 andreas 738
 
268 andreas 739
            case KB_SPACE:
269 andreas 740
                if (gPageManager)
741
                    gPageManager->sendKeyboard(kbtype + "SPACE");
742
 
309 andreas 743
                if ((size_t)mCursorPosition < mInputText.length())
744
                {
745
                    string left, right;
266 andreas 746
 
309 andreas 747
                    if (mCursorPosition > 0)
748
                        left = mInputText.substr(0, mCursorPosition);
749
 
750
                    right = mInputText.substr(mCursorPosition);
751
                    mInputText = left + " " + right;
752
                    mCursorPosition++;
753
                }
754
                else
755
                {
756
                    mInputText.append(" ");
757
                    mCursorPosition++;
758
                }
759
 
268 andreas 760
                if (input)
309 andreas 761
                {
268 andreas 762
                    input->setText(mInputText, 0);
309 andreas 763
                    input->setTextCursorPosition(0, mCursorPosition);
764
                }
268 andreas 765
 
766
                mShift = mBank3 = false;
269 andreas 767
                mBank = (mCapsLock ? BANK_2 : BANK_1);
268 andreas 768
            break;
769
 
770
            case KB_SUBMIT:
771
                if (gPageManager)
269 andreas 772
                    gPageManager->sendKeyboard(kbtype + mInputText);
268 andreas 773
 
774
                mInputText.clear();
775
 
776
                if (input)
777
                    input->setText(mInputText, 0);
778
 
779
                mShift = mBank3 = mCapsLock = false;
780
                mBank = 1;
781
            break;
782
        }
783
 
784
        MSG_DEBUG("Current string: " << mInputText);
266 andreas 785
    }
268 andreas 786
}
266 andreas 787
 
269 andreas 788
/**
789
 * Set the keys of a keyboard or keypad to the given \b bank. With the \b handle
790
 * one key can be set to pressed state.
791
 * This works for multi bargraph keys with 6 states as well as normal keys
792
 * with only 2 states.
793
 *
794
 * @param bank      The number of the bank the multi bargraph keys should be set.
795
 *                  This is a number between 1 and 3.
796
 * @param handle    If this is >0 and a button with the given handle is found,
797
 *                  The state is increased by 1, so that the button appears
798
 *                  highlighted.
799
 */
268 andreas 800
void TSystemButton::setKeysToBank(int bank, uint handle)
801
{
802
    DECL_TRACER("TSystemButton::setKeysToBank(int bank, int handle)");
803
 
269 andreas 804
    if (mButtons.empty() || bank < BANK_1 || bank > BANK_3)
268 andreas 805
        return;
806
 
807
    vector<TButton *>::iterator iter;
808
    int inst = (bank - 1) * 2;
809
 
810
    for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
266 andreas 811
    {
268 andreas 812
        TButton *button = *iter;
813
        SYS_BUTTON_TYPE tp = getSystemButtonType(button->getChannelNumber(), 0);
266 andreas 814
 
268 andreas 815
        if (tp == KEY_KEY)
816
        {
817
            if (handle == button->getHandle())
818
                button->setBargraphLevel(inst + 1);
819
            else
820
                button->setBargraphLevel(inst);
821
        }
822
        else if (tp == KEY_BUTTON)
823
        {
269 andreas 824
            if (handle == button->getHandle() || (button->getChannelNumber() == KB_CAPS_LOCK && mCapsLock))
825
                button->setActive(STATE_ON);
268 andreas 826
            else
269 andreas 827
                button->setActive(STATE_OFF);
268 andreas 828
        }
266 andreas 829
    }
268 andreas 830
}
266 andreas 831
 
269 andreas 832
void TSystemButton::handleDedicatedKeys(int channel, bool pressed)
833
{
834
    DECL_TRACER("TSystemButton::handleDedicatedKeys(int channel, bool pressed)");
835
 
836
    if (!gPageManager)
837
        return;
838
 
839
    string kbtype = "KEYB-";
840
 
841
    if (mCapsLock)
842
        mShift = true;
843
 
844
    switch (channel)
845
    {
846
        case 501: sendDedicatedKey(channel, kbtype + "ESC", pressed); break;
847
        case 502: sendDedicatedKey(channel, kbtype + (mShift ? "!" : "1"), pressed); break;
848
        case 503: sendDedicatedKey(channel, kbtype + (mShift ? "@" : "2"), pressed); break;
849
        case 504: sendDedicatedKey(channel, kbtype + (mShift ? "#" : "3"), pressed); break;
850
        case 505: sendDedicatedKey(channel, kbtype + (mShift ? "$" : "4"), pressed); break;
851
        case 506: sendDedicatedKey(channel, kbtype + (mShift ? "%" : "5"), pressed); break;
852
        case 507: sendDedicatedKey(channel, kbtype + (mShift ? "^" : "6"), pressed); break;
853
        case 508: sendDedicatedKey(channel, kbtype + (mShift ? "&" : "7"), pressed); break;
854
        case 509: sendDedicatedKey(channel, kbtype + (mShift ? "*" : "8"), pressed); break;
855
        case 510: sendDedicatedKey(channel, kbtype + (mShift ? "(" : "9"), pressed); break;
856
        case 511: sendDedicatedKey(channel, kbtype + (mShift ? ")" : "0"), pressed); break;
857
        case 512: sendDedicatedKey(channel, kbtype + (mShift ? "_" : "-"), pressed); break;
858
        case 513: sendDedicatedKey(channel, kbtype + (mShift ? "+" : "="), pressed); break;
859
        case 514: sendDedicatedKey(channel, kbtype + "BACKSPACE", pressed); break;
860
        case 515: sendDedicatedKey(channel, kbtype + "TAB", pressed); break;
861
        case 516: sendDedicatedKey(channel, kbtype + (mShift ? "Q" : "q"), pressed); break;
862
        case 517: sendDedicatedKey(channel, kbtype + (mShift ? "W" : "w"), pressed); break;
863
        case 518: sendDedicatedKey(channel, kbtype + (mShift ? "E" : "e"), pressed); break;
864
        case 519: sendDedicatedKey(channel, kbtype + (mShift ? "R" : "r"), pressed); break;
865
        case 520: sendDedicatedKey(channel, kbtype + (mShift ? "T" : "t"), pressed); break;
866
        case 521: sendDedicatedKey(channel, kbtype + (mShift ? "Y" : "y"), pressed); break;
867
        case 522: sendDedicatedKey(channel, kbtype + (mShift ? "U" : "u"), pressed); break;
868
        case 523: sendDedicatedKey(channel, kbtype + (mShift ? "I" : "i"), pressed); break;
869
        case 524: sendDedicatedKey(channel, kbtype + (mShift ? "O" : "o"), pressed); break;
870
        case 525: sendDedicatedKey(channel, kbtype + (mShift ? "P" : "p"), pressed); break;
871
        case 526: sendDedicatedKey(channel, kbtype + (mShift ? "{" : "["), pressed); break;
872
        case 527: sendDedicatedKey(channel, kbtype + (mShift ? "}" : "]"), pressed); break;
873
        case 528: sendDedicatedKey(channel, kbtype + "ENTER", pressed); break;
874
        case 529: sendDedicatedKey(channel, kbtype + "CTRLL", pressed); break;
875
        case 530: sendDedicatedKey(channel, kbtype + (mShift ? "A" : "a"), pressed); break;
876
        case 531: sendDedicatedKey(channel, kbtype + (mShift ? "S" : "s"), pressed); break;
877
        case 532: sendDedicatedKey(channel, kbtype + (mShift ? "D" : "d"), pressed); break;
878
        case 533: sendDedicatedKey(channel, kbtype + (mShift ? "F" : "f"), pressed); break;
879
        case 534: sendDedicatedKey(channel, kbtype + (mShift ? "G" : "g"), pressed); break;
880
        case 535: sendDedicatedKey(channel, kbtype + (mShift ? "H" : "h"), pressed); break;
881
        case 536: sendDedicatedKey(channel, kbtype + (mShift ? "J" : "j"), pressed); break;
882
        case 537: sendDedicatedKey(channel, kbtype + (mShift ? "K" : "k"), pressed); break;
883
        case 538: sendDedicatedKey(channel, kbtype + (mShift ? "L" : "l"), pressed); break;
884
        case 539: sendDedicatedKey(channel, kbtype + (mShift ? ":" : ";"), pressed); break;
885
        case 540: sendDedicatedKey(channel, kbtype + (mShift ? "\"" : "'"), pressed); break;
886
        case 541: sendDedicatedKey(channel, kbtype + (mShift ? "~" : "`"), pressed); break;
887
        case 542: sendDedicatedKey(channel, kbtype + "SHIFTL", pressed); mShift = !mShift; break;
888
        case 543: sendDedicatedKey(channel, kbtype + (mShift ? "|" : "\\"), pressed); break;
889
        case 544: sendDedicatedKey(channel, kbtype + (mShift ? "Z" : "z"), pressed); break;
890
        case 545: sendDedicatedKey(channel, kbtype + (mShift ? "X" : "x"), pressed); break;
891
        case 546: sendDedicatedKey(channel, kbtype + (mShift ? "C" : "c"), pressed); break;
892
        case 547: sendDedicatedKey(channel, kbtype + (mShift ? "V" : "v"), pressed); break;
893
        case 548: sendDedicatedKey(channel, kbtype + (mShift ? "B" : "b"), pressed); break;
894
        case 549: sendDedicatedKey(channel, kbtype + (mShift ? "N" : "n"), pressed); break;
895
        case 550: sendDedicatedKey(channel, kbtype + (mShift ? "M" : "m"), pressed); break;
896
        case 551: sendDedicatedKey(channel, kbtype + (mShift ? "<" : ","), pressed); break;
897
        case 552: sendDedicatedKey(channel, kbtype + (mShift ? ">" : "."), pressed); break;
898
        case 553: sendDedicatedKey(channel, kbtype + (mShift ? "?" : "/"), pressed); break;
899
        case 554: sendDedicatedKey(channel, kbtype + "SHIFTR", pressed); mShift = !mShift; break;
900
        case 556: sendDedicatedKey(channel, kbtype + "ALT", pressed); break;
901
        case 557: sendDedicatedKey(channel, kbtype + "SPACE", pressed); break;
902
        case 558: sendDedicatedKey(channel, kbtype + "CAPS", pressed); mCapsLock = !mCapsLock; break;
903
        case 559: sendDedicatedKey(channel, kbtype + "F1", pressed); break;
904
        case 560: sendDedicatedKey(channel, kbtype + "F2", pressed); break;
905
        case 561: sendDedicatedKey(channel, kbtype + "F3", pressed); break;
906
        case 562: sendDedicatedKey(channel, kbtype + "F4", pressed); break;
907
        case 563: sendDedicatedKey(channel, kbtype + "F5", pressed); break;
908
        case 564: sendDedicatedKey(channel, kbtype + "F6", pressed); break;
909
        case 565: sendDedicatedKey(channel, kbtype + "F7", pressed); break;
910
        case 566: sendDedicatedKey(channel, kbtype + "F8", pressed); break;
911
        case 567: sendDedicatedKey(channel, kbtype + "F9", pressed); break;
912
        case 568: sendDedicatedKey(channel, kbtype + "F10", pressed); break;
913
        case 587: sendDedicatedKey(channel, kbtype + "F11", pressed); break;
914
        case 588: sendDedicatedKey(channel, kbtype + "F12", pressed); break;
915
        case 597: sendDedicatedKey(channel, kbtype + "CTRLR", pressed); break;
916
        case 600: sendDedicatedKey(channel, kbtype + "ALTGR", pressed); break;
917
        case 602: sendDedicatedKey(channel, kbtype + "HOME", pressed); break;
918
        case 603: sendDedicatedKey(channel, kbtype + "UP", pressed); break;
919
        case 604: sendDedicatedKey(channel, kbtype + "PGDN", pressed); break;
920
        case 605: sendDedicatedKey(channel, kbtype + "LEFT", pressed); break;
921
        case 606: sendDedicatedKey(channel, kbtype + "RIGHT", pressed); break;
922
        case 607: sendDedicatedKey(channel, kbtype + "END", pressed); break;
923
        case 608: sendDedicatedKey(channel, kbtype + "DOWN", pressed); break;
924
        case 609: sendDedicatedKey(channel, kbtype + "PGDN", pressed); break;
925
        case 610: sendDedicatedKey(channel, kbtype + "INS", pressed); break;
926
        case 611: sendDedicatedKey(channel, kbtype + "DEL", pressed); break;
927
    }
928
 
929
    if ((mShift && channel != 554 && channel != 542) || mCapsLock)
930
        mShift = false;
931
}
932
 
933
void TSystemButton::sendDedicatedKey(int channel, const string str, bool pressed)
934
{
935
    DECL_TRACER("TSystemButton::sendDedicatedKey(int channel, const string str)");
936
 
937
    TButton *button = getSysButton(channel, 0);
938
 
939
    if (button)
940
        button->setActive(pressed ? STATE_ON : STATE_OFF);
941
 
942
    gPageManager->sendKeyboard(str);
943
}
944
 
945
/**
946
 * @brief Translates the button types into a string.
947
 * This method is for debugging purposes only!
948
 *
949
 * @param type  The enum number of the button type.
950
 *
951
 * @return Returns the string representation of the button type.
952
 */
268 andreas 953
string TSystemButton::typeToString(TSystemButton::SYS_BUUTON_TYPE type)
954
{
955
    switch (type)
266 andreas 956
    {
268 andreas 957
        case KEY_BUTTON:            return "KEY_BUTTON";
958
        case KEY_INPUT_MULTI:       return "KEY_INPUT_MULTI";
959
        case KEY_INPUT_SINGLE:      return "KEY_INPUT_SINGLE";
960
        case KEY_KEY:               return "KEY_KEY";
961
        case KEY_UNDEFINED:         return "KEY_UNDEFINED";
962
    }
266 andreas 963
 
268 andreas 964
    return string();
266 andreas 965
}