Subversion Repositories spk

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
79 cycrow 1
//************************************************************************
2
//
3
// LCDOutput.cpp
4
//
5
// The CLCDOutput class manages LCD hardware enumeration and screen 
6
// management.
7
// 
8
// Logitech LCD SDK
9
//
10
// Copyright 2005 Logitech Inc.
11
//************************************************************************
12
 
13
#include "LCDOutput.h"
14
 
15
//#pragma comment(lib, "lgLcd.lib")
16
 
17
// to keep track of clients that use multiple CLCDOutput instances
18
// within the same app
19
static LONG lInitCount = 0;
20
 
21
//************************************************************************
22
//
23
// CLCDOutput::CLCDOutput
24
//
25
//************************************************************************
26
 
27
CLCDOutput::CLCDOutput()
28
{
29
    m_pActiveScreen = NULL;
30
    m_bLocked = FALSE;
31
    m_hDevice = LGLCD_INVALID_DEVICE;
32
    m_hConnection = LGLCD_INVALID_CONNECTION;
33
    m_nPriority = LGLCD_PRIORITY_NORMAL;
34
    ZeroMemory(&m_lcdConnectCtx, sizeof(m_lcdConnectCtx));
35
    m_bDisplayLocked = FALSE;
36
    m_bSetAsForeground = FALSE;
37
}
38
 
39
//************************************************************************
40
//
41
// CLCDOutput::~CLCDOutput
42
//
43
//************************************************************************
44
 
45
CLCDOutput::~CLCDOutput()
46
{
47
 
48
}
49
 
50
 
51
//************************************************************************
52
//
53
// CLCDOutput::Initialize
54
//
55
//************************************************************************
56
 
57
HRESULT CLCDOutput::Initialize()
58
{
59
    return Initialize(NULL, FALSE);
60
}
61
 
62
 
63
//************************************************************************
64
//
65
// CLCDOutput::Initialize
66
//
67
// NOTE: Initialize should always return S_OK
68
//************************************************************************
69
 
70
HRESULT CLCDOutput::Initialize(lgLcdConnectContext* pContext, BOOL bUseWindow)
71
{    
72
 
73
    UNREFERENCED_PARAMETER(bUseWindow);
74
 
75
    DWORD res = ERROR_SUCCESS;
76
 
77
    CLCDManager::Initialize();
78
 
79
    // initialize our screens
80
    LCD_MGR_LIST::iterator it = m_LCDMgrList.begin();
81
    while(it != m_LCDMgrList.end())
82
    {
83
        CLCDManager *pMgr = *it;
84
        LCDUIASSERT(NULL != pMgr);
85
 
86
        pMgr->Initialize();
87
        ++it;
88
    }
89
 
90
    // LCD Stuff
91
    LCDUIASSERT(lInitCount >= 0);
92
    if(1 == InterlockedIncrement(&lInitCount))
93
    {
94
        // need to call lgLcdInit once
95
        res = lgLcdInit();
96
        if (ERROR_SUCCESS != res)
97
        {
98
//			LCDUIError(res,"lgLcdInit")
99
            InterlockedDecrement(&lInitCount);
100
            LCDUITRACE(_T("WARNING: lgLcdInit failed\n"));
101
            return E_FAIL;
102
        }
103
    }
104
 
105
 
106
    m_lcdConnectCtx.appFriendlyName = _T("My App");
107
    m_lcdConnectCtx.isPersistent = FALSE;
108
    m_lcdConnectCtx.isAutostartable = FALSE;
109
    m_lcdConnectCtx.connection = LGLCD_INVALID_CONNECTION;
110
 
111
    // if user passed in the context, fill it up
112
    if (NULL != pContext)
113
    {
114
        memcpy(&m_lcdConnectCtx, pContext, sizeof(lgLcdConnectContext));
115
    }
116
 
117
    return S_OK;
118
}
119
 
120
//************************************************************************
121
//
122
// CLCDOutput::Shutdown
123
//
124
//************************************************************************
125
 
126
void CLCDOutput::Shutdown(void)
127
{
128
    CloseAndDisconnect();
129
    if(0 == InterlockedDecrement(&lInitCount))
130
    {
131
        lgLcdDeInit();
132
    }
133
    LCDUIASSERT(lInitCount >= 0);
134
}
135
 
136
 
137
//************************************************************************
138
//
139
// CLCDOutput::Draw
140
//
141
//************************************************************************
142
 
143
HRESULT CLCDOutput::Draw()
144
{
145
    DWORD dwPriorityToUse;
146
 
147
    if (m_pActiveScreen)
148
    {
149
        m_pActiveScreen->Draw();
150
        dwPriorityToUse = LGLCD_ASYNC_UPDATE(m_nPriority);
151
    }
152
    else
153
    {
154
        dwPriorityToUse = LGLCD_ASYNC_UPDATE(LGLCD_PRIORITY_IDLE_NO_SHOW);
155
    }
156
 
157
    lgLcdBitmap160x43x1* pScreen = GetLCDScreen();
158
    if (pScreen && (LGLCD_INVALID_DEVICE != m_hDevice) && (LGLCD_PRIORITY_IDLE_NO_SHOW != dwPriorityToUse))
159
    {
160
        DWORD res = ERROR_SUCCESS;
161
        res = lgLcdUpdateBitmap(m_hDevice, &pScreen->hdr, dwPriorityToUse);
162
 
163
        HandleErrorFromAPI(res);
164
 
165
        // read the soft buttons
166
        ReadButtons();
167
    }
168
 
169
    return S_OK;
170
}
171
 
172
 
173
//************************************************************************
174
//
175
// CLCDOutput::Update
176
//
177
//************************************************************************
178
 
179
void CLCDOutput::Update(DWORD dwTimestamp)
180
{
181
    if (m_pActiveScreen)
182
    {
183
        m_pActiveScreen->Update(dwTimestamp);
184
    }
185
 
186
    // check for expiration
187
    if (m_pActiveScreen && m_pActiveScreen->HasExpired())
188
    {
189
        m_pActiveScreen = NULL;
190
        //m_nPriority = LGLCD_PRIORITY_FYI; -> needs to go so that if a 
191
		// program sets priority to LGLCD_PRIORITY_BACKGROUND, that 
192
		// priority sticks.
193
 
194
        OnScreenExpired(m_pActiveScreen);
195
 
196
        // find the next active screen
197
        LCD_MGR_LIST::iterator it = m_LCDMgrList.begin();
198
        while(it != m_LCDMgrList.end())
199
        {
200
            CLCDManager *pMgr = *it;
201
            LCDUIASSERT(NULL != pMgr);
202
 
203
            if (!pMgr->HasExpired())
204
            {
205
                ActivateScreen(pMgr);
206
                //m_nPriority = LGLCD_PRIORITY_FYI;  -> needs to go so that if a 
207
				// program sets priority to LGLCD_PRIORITY_BACKGROUND, that 
208
				// priority sticks.
209
                break;
210
            }
211
 
212
            ++it;
213
        }
214
 
215
        // if no screen found, empty the screen at idle priority
216
        if (NULL == m_pActiveScreen)
217
        {
218
            if (LGLCD_INVALID_DEVICE != m_hDevice)
219
            {
220
                lgLcdUpdateBitmap(m_hDevice, &CLCDManager::GetLCDScreen()->hdr,
221
                    LGLCD_ASYNC_UPDATE(LGLCD_PRIORITY_IDLE_NO_SHOW));
222
            }
223
        }
224
    }
225
 
226
    // check for lcd devices
227
    if (LGLCD_INVALID_DEVICE == m_hDevice)
228
    {
229
        EnumerateDevices();
230
    }
231
}
232
 
233
 
234
//************************************************************************
235
//
236
// CLCDOutput::HasHardwareChanged
237
//
238
//************************************************************************
239
 
240
BOOL CLCDOutput::HasHardwareChanged(void)
241
{
242
    if(LGLCD_INVALID_DEVICE != m_hDevice)
243
    {
244
        // ping to see whether we're still alive
245
        DWORD dwButtonState = 0;
246
 
247
        DWORD res = lgLcdReadSoftButtons(m_hDevice, &dwButtonState);
248
 
249
        HandleErrorFromAPI(res);
250
    }
251
 
252
    // check for lcd devices
253
    if (LGLCD_INVALID_DEVICE == m_hDevice)
254
    {
255
        EnumerateDevices();
256
    }
257
    else
258
    {
259
        // we still have our device;
260
        return FALSE;
261
    }
262
 
263
    // we got a new device
264
    return LGLCD_INVALID_DEVICE != m_hDevice;
265
}
266
 
267
 
268
//************************************************************************
269
//
270
// CLCDOutput::GetLCDScreen
271
//
272
//************************************************************************
273
 
274
lgLcdBitmap160x43x1 *CLCDOutput::GetLCDScreen(void)
275
{
276
    return m_pActiveScreen ? m_pActiveScreen->GetLCDScreen() : CLCDManager::GetLCDScreen();
277
}
278
 
279
 
280
//************************************************************************
281
//
282
// CLCDOutput::GetBitmapInfo
283
//
284
//************************************************************************
285
 
286
BITMAPINFO *CLCDOutput::GetBitmapInfo(void)
287
{
288
    return m_pActiveScreen ? m_pActiveScreen->GetBitmapInfo() : CLCDManager::GetBitmapInfo();
289
}
290
 
291
 
292
//************************************************************************
293
//
294
// CLCDOutput::ReadButtons
295
//
296
//************************************************************************
297
 
298
void CLCDOutput::ReadButtons()
299
{
300
    if(IsOpened())
301
    {
302
        DWORD dwButtonState = 0;
303
 
304
        DWORD res = lgLcdReadSoftButtons(m_hDevice, &dwButtonState);
305
        if (ERROR_SUCCESS != res)
306
        {
307
            LCDUITRACE(_T("lgLcdReadSoftButtons failed: unplug?\n"));
308
            HandleErrorFromAPI(res);
309
        }
310
 
311
        if (m_dwButtonState == dwButtonState)
312
            return;
313
 
314
        // handle the buttons
315
        HandleButtonState(dwButtonState, LGLCDBUTTON_BUTTON0);
316
        HandleButtonState(dwButtonState, LGLCDBUTTON_BUTTON1);
317
        HandleButtonState(dwButtonState, LGLCDBUTTON_BUTTON2);
318
        HandleButtonState(dwButtonState, LGLCDBUTTON_BUTTON3);
319
 
320
        m_dwButtonState = dwButtonState;
321
    }
322
}
323
 
324
 
325
//************************************************************************
326
//
327
// CLCDOutput::HandleButtonState
328
//
329
//************************************************************************
330
 
331
void CLCDOutput::HandleButtonState(DWORD dwButtonState, DWORD dwButton)
332
{
333
    if ( (m_dwButtonState & dwButton) && !(dwButtonState & dwButton) )
334
    {
335
        LCDUITRACE(_T("Button 0x%x released\n"), dwButton);
336
        OnLCDButtonUp(dwButton);
337
    }
338
    if ( !(m_dwButtonState & dwButton) && (dwButtonState & dwButton) )
339
    {
340
        LCDUITRACE(_T("Button 0x%x pressed\n"), dwButton);
341
        OnLCDButtonDown(dwButton);
342
    }
343
}
344
 
345
 
346
//************************************************************************
347
//
348
// CLCDOutput::OnLCDButtonDown
349
//
350
//************************************************************************
351
 
352
void CLCDOutput::OnLCDButtonDown(int nButton)
353
{
354
    if (m_pActiveScreen)
355
    {
356
        m_pActiveScreen->OnLCDButtonDown(nButton);
357
    }
358
}
359
 
360
 
361
//************************************************************************
362
//
363
// CLCDOutput::OnLCDButtonUp
364
//
365
//************************************************************************
366
 
367
void CLCDOutput::OnLCDButtonUp(int nButton)
368
{
369
    if (m_pActiveScreen)
370
    {
371
        m_pActiveScreen->OnLCDButtonUp(nButton);
372
    }
373
}
374
 
375
 
376
//************************************************************************
377
//
378
// CLCDOutput::ActivateScreen
379
//
380
//************************************************************************
381
 
382
void CLCDOutput::ActivateScreen(CLCDManager* pScreen)
383
{
384
    if (m_bLocked)
385
        return;
386
    m_pActiveScreen = pScreen;
387
}
388
 
389
 
390
//************************************************************************
391
//
392
// CLCDOutput::LockScreen
393
//
394
//************************************************************************
395
 
396
void CLCDOutput::LockScreen(CLCDManager* pScreen)
397
{
398
    if (m_bLocked)
399
        return;
400
 
401
    m_pActiveScreen = pScreen;
402
    m_bLocked = TRUE;
403
}
404
 
405
 
406
//************************************************************************
407
//
408
// CLCDOutput::UnlockScreen
409
//
410
//************************************************************************
411
 
412
void CLCDOutput::UnlockScreen()
413
{
414
    m_bLocked = FALSE;
415
    m_pActiveScreen = NULL;
416
}
417
 
418
 
419
//************************************************************************
420
//
421
// CLCDOutput::IsLocked
422
//
423
//************************************************************************
424
 
425
BOOL CLCDOutput::IsLocked()
426
{
427
    return m_bLocked;
428
}
429
 
430
 
431
//************************************************************************
432
//
433
// CLCDOutput::AddScreen
434
//
435
//************************************************************************
436
 
437
void CLCDOutput::AddScreen(CLCDManager* pScreen)
438
{
439
    m_LCDMgrList.push_back(pScreen);
440
}
441
 
442
 
443
//************************************************************************
444
//
445
// CLCDOutput::EnumerateDevices
446
//
447
//************************************************************************
448
 
449
void CLCDOutput::EnumerateDevices()
450
{
451
    lgLcdDeviceDesc desc;
452
 
453
    if (LGLCD_INVALID_CONNECTION == m_hConnection)
454
    {
455
        if (ERROR_SUCCESS == lgLcdConnect(&m_lcdConnectCtx))
456
        {
457
            // make sure we don't work with a stale device handle
458
            m_hConnection = m_lcdConnectCtx.connection;
459
            m_hDevice = LGLCD_INVALID_CONNECTION;
460
        }
461
        else
462
        {
463
            return;
464
        }
465
    }
466
 
467
    // close the lcd device before we open up another
468
    if (LGLCD_INVALID_DEVICE != m_hDevice)
469
    {
470
        lgLcdClose(m_hDevice);
471
        m_hDevice = LGLCD_INVALID_DEVICE;
472
    }
473
 
474
    ZeroMemory(&desc, sizeof(desc));
475
    DWORD res = ERROR_SUCCESS;
476
 
477
    res = lgLcdEnumerate(m_hConnection, 0, &desc);
478
    if (ERROR_SUCCESS != res)
479
    {
480
        if(ERROR_NO_MORE_ITEMS != res)
481
        {
482
            // something happened. Let's close this.
483
            CloseAndDisconnect();
484
        }
485
        return;
486
    }
487
 
488
    lgLcdOpenContext open_ctx;
489
    ZeroMemory(&open_ctx, sizeof(open_ctx));
490
 
491
    open_ctx.connection = m_hConnection;
492
    open_ctx.index = 0;
493
    res = lgLcdOpen(&open_ctx);
494
    if (ERROR_SUCCESS != res)
495
        return;
496
    m_hDevice = open_ctx.device;
497
    m_dwButtonState = 0;
498
 
499
    // restores
500
    SetAsForeground(m_bSetAsForeground);
501
}
502
 
503
 
504
//************************************************************************
505
//
506
// CLCDOutput::HandleErrorFromAPI
507
//
508
//************************************************************************
509
void CLCDOutput::HandleErrorFromAPI(DWORD dwRes)
510
{
511
    switch(dwRes)
512
    {
513
        // all is well
514
    case ERROR_SUCCESS:
515
        break;
516
        // we lost our device
517
    case ERROR_DEVICE_NOT_CONNECTED:
518
        LCDUITRACE(_T("lgLcdAPI returned with ERROR_DEVICE_NOT_CONNECTED, closing device\n"));
519
        OnClosingDevice(m_hDevice);
520
        break;
521
    default:
522
        LCDUITRACE(_T("lgLcdAPI returned with other error (0x%08x) closing device and connection\n"));
523
        OnClosingDevice(m_hDevice);
524
        OnDisconnecting(m_hConnection);
525
        // something else happened, such as LCDMon that was terminated
526
        break;
527
    }
528
}
529
 
530
//************************************************************************
531
//
532
// CLCDOutput::SetScreenPriority
533
//
534
//************************************************************************
535
void CLCDOutput::SetScreenPriority(DWORD priority)
536
{
537
    m_nPriority = priority;
538
    if (LGLCD_PRIORITY_IDLE_NO_SHOW == m_nPriority)
539
    {
540
        // send an empty bitmap at idle priority
541
        if (LGLCD_INVALID_DEVICE != m_hDevice)
542
        {
543
            lgLcdUpdateBitmap(m_hDevice, &CLCDManager::GetLCDScreen()->hdr,
544
                              LGLCD_ASYNC_UPDATE(LGLCD_PRIORITY_IDLE_NO_SHOW));
545
        }
546
    }
547
}
548
 
549
//************************************************************************
550
//
551
// CLCDOutput::GetScreenPriority
552
//
553
//************************************************************************
554
DWORD CLCDOutput::GetScreenPriority()
555
{
556
    return m_nPriority;
557
}
558
 
559
//************************************************************************
560
//
561
// CLCDOutput::CloseAndDisconnect
562
//
563
//************************************************************************
564
 
565
void CLCDOutput::CloseAndDisconnect()
566
{
567
    OnClosingDevice(m_hDevice);
568
    OnDisconnecting(m_hConnection);
569
}
570
 
571
 
572
//************************************************************************
573
//
574
// CLCDOutput::OnScreenExpired
575
//
576
//************************************************************************
577
 
578
void CLCDOutput::OnScreenExpired(CLCDManager* pScreen)
579
{
580
    UNREFERENCED_PARAMETER(pScreen);
581
    UnlockScreen();
582
}
583
 
584
 
585
//************************************************************************
586
//
587
// CLCDOutput::OnClosingDevice
588
//
589
//************************************************************************
590
 
591
void CLCDOutput::OnClosingDevice(int hDevice)
592
{
593
    UNREFERENCED_PARAMETER(hDevice);
594
    LCDUITRACE(_T("CLCDOutput::OnClosingDevice\n"));
595
    if (IsOpened())
596
    {
597
        lgLcdClose(m_hDevice);
598
        m_hDevice = LGLCD_INVALID_DEVICE;
599
    }
600
}
601
 
602
//************************************************************************
603
//
604
// CLCDOutput::OnDisconnecting
605
//
606
//************************************************************************
607
 
608
void CLCDOutput::OnDisconnecting(int hConnection)
609
{
610
    UNREFERENCED_PARAMETER(hConnection);
611
    LCDUITRACE(_T("CLCDOutput::OnDisconnecting\n"));
612
    // let's hope our device is already gone
613
    LCDUIASSERT(!IsOpened());
614
 
615
    if (LGLCD_INVALID_CONNECTION != m_hConnection)
616
    {
617
        lgLcdDisconnect(m_hConnection);
618
        m_hConnection = LGLCD_INVALID_CONNECTION;
619
    }
620
}
621
 
622
//************************************************************************
623
//
624
// CLCDOutput::IsOpened
625
//
626
//************************************************************************
627
 
628
BOOL CLCDOutput::IsOpened()
629
{
630
	return (LGLCD_INVALID_DEVICE != m_hDevice);
631
}
632
 
633
 
634
//************************************************************************
635
//
636
// CLCDOutput::SetAsForeground
637
//
638
//************************************************************************
639
 
640
void CLCDOutput::SetAsForeground(BOOL bSetAsForeground)
641
{
642
    DWORD dwSet = bSetAsForeground ? LGLCD_LCD_FOREGROUND_APP_YES : LGLCD_LCD_FOREGROUND_APP_NO;
643
    m_bSetAsForeground = bSetAsForeground;
644
    if (LGLCD_INVALID_DEVICE != m_hDevice)
645
    {
646
        lgLcdSetAsLCDForegroundApp(m_hDevice, bSetAsForeground);
647
    }
648
}
649
 
650
//** end of LCDOutput.cpp ************************************************