bool LH_LgLcdCallbackThread::render( int conn ) { // Close open contexts no longer in use if( !bw_bm.hdr.Format && bw_cxt.device != LGLCD_INVALID_DEVICE ) { lgLcdClose(bw_cxt.device); bw_cxt.device = LGLCD_INVALID_DEVICE; } if( !qvga_bm.hdr.Format && qvga_cxt.device != LGLCD_INVALID_DEVICE ) { lgLcdClose(qvga_cxt.device); qvga_cxt.device = LGLCD_INVALID_DEVICE; } // Open context that are available and needed if( bw_bm.hdr.Format && bw_cxt.device == LGLCD_INVALID_DEVICE ) { Q_ASSERT( bw_cxt.onSoftbuttonsChanged.softbuttonsChangedContext == this ); bw_cxt.connection = conn; if( LCD_ERR( lgLcdOpenByType(&bw_cxt) ) ) lgLcdSetAsLCDForegroundApp(bw_cxt.device,LGLCD_LCD_FOREGROUND_APP_YES); } if( qvga_bm.hdr.Format && qvga_cxt.device == LGLCD_INVALID_DEVICE ) { Q_ASSERT( qvga_cxt.onSoftbuttonsChanged.softbuttonsChangedContext == this ); qvga_cxt.connection = conn; if( LCD_ERR( lgLcdOpenByType(&qvga_cxt) ) ) lgLcdSetAsLCDForegroundApp(qvga_cxt.device,LGLCD_LCD_FOREGROUND_APP_YES); } // Push bits to open devices that has images if( bw_cxt.device != LGLCD_INVALID_DEVICE && bw_bm.hdr.Format ) { if( lgLcdUpdateBitmap( bw_cxt.device, &bw_bm.hdr, LGLCD_PRIORITY_NORMAL ) != ERROR_SUCCESS ) { lgLcdClose(bw_cxt.device); bw_cxt.device = LGLCD_INVALID_DEVICE; } } if( qvga_cxt.device != LGLCD_INVALID_DEVICE && qvga_bm.hdr.Format ) { if( lgLcdUpdateBitmap( qvga_cxt.device, &qvga_bm.hdr, LGLCD_PRIORITY_NORMAL ) != ERROR_SUCCESS ) { lgLcdClose(qvga_cxt.device); qvga_cxt.device = LGLCD_INVALID_DEVICE; } } return true; }
BOOL CLCDOutput::OnDraw(void) { DWORD dwPriorityToUse = LGLCD_ASYNC_UPDATE(m_nPriority); if ( (NULL == m_pActivePage) || (LGLCD_INVALID_DEVICE == m_hDevice) || (LGLCD_PRIORITY_IDLE_NO_SHOW == dwPriorityToUse) ) { // don't submit the bitmap return TRUE; } // Render the active screen m_pGfx->BeginDraw(); m_pGfx->ClearScreen(); m_pActivePage->OnDraw(*m_pGfx); m_pGfx->EndDraw(); // Get the active bitmap lgLcdBitmap* pBitmap = m_pGfx->GetLCDScreen(); // Only submit if the bitmap needs to be updated // (If the priority or bitmap have changed) DWORD res = ERROR_SUCCESS; if (DoesBitmapNeedUpdate(pBitmap)) { res = lgLcdUpdateBitmap(m_hDevice, &pBitmap->bmp_mono.hdr, dwPriorityToUse); HandleErrorFromAPI(res); } return (LGLCD_INVALID_DEVICE != m_hDevice); }
HRESULT CLCDOutput::Draw() { DWORD dwPriorityToUse = LGLCD_ASYNC_UPDATE(m_nPriority); if ( (NULL == m_pActiveScreen) || (LGLCD_INVALID_DEVICE == m_hDevice) || (LGLCD_PRIORITY_IDLE_NO_SHOW == dwPriorityToUse) ) { // don't submit the bitmap return S_OK; } // Render the active screen m_pActiveScreen->Draw(); // Get the active bitmap lgLcdBitmap160x43x1* pScreen = m_pActiveScreen->GetLCDScreen(); // Only submit if the bitmap needs to be updated // (If the priority or bitmap have changed) DWORD res = ERROR_SUCCESS; if (DoesBitmapNeedUpdate(pScreen)) { res = lgLcdUpdateBitmap(m_hDevice, &pScreen->hdr, dwPriorityToUse); HandleErrorFromAPI(res); } // read the soft buttons ReadButtons(); return S_OK; }
HRESULT CLCDOutput::Draw() { DWORD dwPriorityToUse; if (m_pActiveScreen) { m_pActiveScreen->Draw(); dwPriorityToUse = LGLCD_ASYNC_UPDATE(m_nPriority); } else { dwPriorityToUse = LGLCD_ASYNC_UPDATE(LGLCD_PRIORITY_IDLE_NO_SHOW); } lgLcdBitmap160x43x1* pScreen = GetLCDScreen(); if (pScreen && (LGLCD_INVALID_DEVICE != m_hDevice)) { DWORD res = ERROR_SUCCESS; res = lgLcdUpdateBitmap(m_hDevice, &pScreen->hdr, dwPriorityToUse); HandleErrorFromAPI(res); // read the soft buttons ReadButtons(); } return S_OK; }
void CLCDOutput::Update(DWORD dwTimestamp) { if (m_pActiveScreen) { m_pActiveScreen->Update(dwTimestamp); } // check for expiration if (m_pActiveScreen && m_pActiveScreen->HasExpired()) { m_pActiveScreen = NULL; //m_nPriority = LGLCD_PRIORITY_FYI; -> needs to go so that if a // program sets priority to LGLCD_PRIORITY_BACKGROUND, that // priority sticks. OnScreenExpired(m_pActiveScreen); // Clear the bitmap ClearBitmap(m_pLastBitmap); // find the next active screen LCD_MGR_LIST::iterator it = m_LCDMgrList.begin(); while(it != m_LCDMgrList.end()) { CLCDManager *pMgr = *it; LCDUIASSERT(NULL != pMgr); if (!pMgr->HasExpired()) { ActivateScreen(pMgr); //m_nPriority = LGLCD_PRIORITY_FYI; -> needs to go so that if a // program sets priority to LGLCD_PRIORITY_BACKGROUND, that // priority sticks. break; } ++it; } // if no screen found, empty the screen at idle priority if (NULL == m_pActiveScreen) { if (LGLCD_INVALID_DEVICE != m_hDevice) { lgLcdUpdateBitmap(m_hDevice, &CLCDManager::GetLCDScreen()->hdr, LGLCD_ASYNC_UPDATE(LGLCD_PRIORITY_IDLE_NO_SHOW)); } } } // check for lcd devices if (LGLCD_INVALID_DEVICE == m_hDevice) { EnumerateDevices(); } }
void CLCDConnectionLogitech::runDrawingThread() { m_hStopEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hDrawEvent = CreateEvent(NULL, FALSE, FALSE, NULL); DWORD dwRes = 0; while (1) { HANDLE hArray[2] = { m_hStopEvent, m_hDrawEvent }; dwRes = WaitForMultipleObjects(2, hArray, FALSE, INFINITE); if (dwRes == WAIT_OBJECT_0) { break; } else if (dwRes == WAIT_OBJECT_0 + 1) { DWORD rc; if (GetConnectionState() != CONNECTED) { continue; } // do a sync update if the applet is in the foreground, or every 500 ms // the delay is there because sync updates can take up to 33ms to fail if (m_dwForegroundCheck < GetTickCount()) { m_dwForegroundCheck = GetTickCount() + 500; rc = lgLcdUpdateBitmap(m_hDevice, &m_lcdBitmap.hdr, LGLCD_SYNC_COMPLETE_WITHIN_FRAME(m_iPriority)); if (rc == ERROR_ACCESS_DENIED) { rc = ERROR_SUCCESS; m_bIsForeground = false; } else if (rc == ERROR_SUCCESS) m_bIsForeground = true; } else rc = lgLcdUpdateBitmap(m_hDevice, &m_lcdBitmap.hdr, LGLCD_ASYNC_UPDATE(m_iPriority)); if (rc != ERROR_SUCCESS) { HandleErrorFromAPI(rc); } } } CloseHandle(m_hStopEvent); CloseHandle(m_hDrawEvent); }
void CLCDOutput::SetScreenPriority(DWORD priority) { // Priority has changed // If we're going into idle, send an idle frame if (LGLCD_PRIORITY_IDLE_NO_SHOW == priority) { lgLcdUpdateBitmap(m_hDevice, &m_pGfx->GetLCDScreen()->bmp_mono.hdr, LGLCD_ASYNC_UPDATE(LGLCD_PRIORITY_IDLE_NO_SHOW)); } m_nPriority = priority; }
void lcd_update (int led, int on) { int track, x, y; if (!inited) return; if (led < 0) { lgLcdUpdateBitmap (device, lbh, LGLCD_PRIORITY_IDLE_NO_SHOW); return; } if (on < 0) return; if (led >= 1 && led <= 4) { x = 23 + (led - 1) * 40; y = 17; track = gui_data.drive_track[led - 1]; if (gui_data.drive_disabled[led - 1]) { track = -1; on = 0; } putnumbers (x, y, track, on); } else if (led == 0) { dorect (&coords[4 * 2], on); } else if (led == 5) { dorect (&coords[4 * 1], on); } else if (led == 6) { dorect (&coords[4 * 0], on); } else if (led == 7) { y = 2; x = 125; putnumbers (x, y, gui_data.fps <= 999 ? (gui_data.fps + 5) / 10 : 99, 0); } else if (led == 8) { y = 2; x = 98; putnumbers (x, y, gui_data.idle <= 999 ? gui_data.idle / 10 : 99, 0); } lgLcdUpdateBitmap (device, lbh, LGLCD_ASYNC_UPDATE (LGLCD_PRIORITY_NORMAL + 1)); }
//************************************************************************ // Hides the applet //************************************************************************ bool CLCDConnectionLogitech::HideApplet() { if (!GetConnectionState() == CONNECTED) return false; DWORD rc; rc = lgLcdUpdateBitmap(m_hDevice, &m_lcdBitmap.hdr, LGLCD_ASYNC_UPDATE(LGLCD_PRIORITY_IDLE_NO_SHOW)); if (rc != ERROR_SUCCESS) return false; return true; }
void CLCDOutput::OnUpdate(DWORD dwTimestamp) { if (m_pActivePage) { m_pActivePage->OnUpdate(dwTimestamp); } // check for expiration if (m_pActivePage && m_pActivePage->HasExpired()) { m_pActivePage = NULL; //m_nPriority = LGLCD_PRIORITY_FYI; -> needs to go so that if a // program sets priority to LGLCD_PRIORITY_BACKGROUND, that // priority sticks. OnPageExpired(m_pActivePage); // find the next active screen for (size_t i = 0; i < m_Objects.size(); i++) { CLCDPage *pPage = dynamic_cast<CLCDPage*>(m_Objects[i]); LCDUIASSERT(NULL != pPage); if (!pPage->HasExpired()) { ShowPage(pPage); //m_nPriority = LGLCD_PRIORITY_FYI; -> needs to go so that if a // program sets priority to LGLCD_PRIORITY_BACKGROUND, that // priority sticks. break; } } // if no screen found, empty the screen at idle priority if (NULL == m_pActivePage) { OnEnteringIdle(); if (LGLCD_INVALID_DEVICE != m_hDevice) { m_pGfx->ClearScreen(); lgLcdUpdateBitmap(m_hDevice, &m_pGfx->GetLCDScreen()->bmp_mono.hdr, LGLCD_ASYNC_UPDATE(LGLCD_PRIORITY_IDLE_NO_SHOW)); } } } }
void G15LCDDeviceLGLCD::blitImage(QImage *img, bool alert) { Q_ASSERT(img); int len = G15_MAX_FBMEM_BITS; uchar *tmp = img->bits(); lgLcdBitmap160x43x1 bitmap; unsigned char *buf = bitmap.pixels; if (engine->llcContext.device == LGLCD_INVALID_DEVICE) return; if (! bEnabled) return; /* * The amount of copying/conversion we're doing is hideous. * * To draw to the LCD display using Logitech's SDK, we need to pass * it a byte array (in which each byte represents a single pixel on * the LCD.) * * Unfortunately, there's no way out, really. We *could* perhaps draw * directly to a monochrome "bytemap" (via Format_Indexed8, and a mono- * chrome colormap), but QPainter simply doesn't want to draw to a * QImage of Format_Indexed8. * * (What's even worse is that the byte array passed to the Logitech SDK * isn't even the native format of the LCD. It has to convert it once * more, when it receives a frame.) */ for (int i = 0; i < len; i++) { int idx = i*8; buf[idx+7] = tmp[i] & 0x80 ? 0xff : 0x00; buf[idx+6] = tmp[i] & 0x40 ? 0xff : 0x00; buf[idx+5] = tmp[i] & 0x20 ? 0xff : 0x00; buf[idx+4] = tmp[i] & 0x10 ? 0xff : 0x00; buf[idx+3] = tmp[i] & 0x08 ? 0xff : 0x00; buf[idx+2] = tmp[i] & 0x04 ? 0xff : 0x00; buf[idx+1] = tmp[i] & 0x02 ? 0xff : 0x00; buf[idx+0] = tmp[i] & 0x01 ? 0xff : 0x00; } bitmap.hdr.Format = LGLCD_BMP_FORMAT_160x43x1; DWORD dwErr = lgLcdUpdateBitmap(engine->llcContext.device, &bitmap.hdr, alert ? LGLCD_SYNC_UPDATE(LGLCD_PRIORITY_ALERT) : LGLCD_SYNC_UPDATE(LGLCD_PRIORITY_NORMAL)); }
//************************************************************************ // // CLCDOutput::SetScreenPriority // //************************************************************************ void CLCDOutput::SetScreenPriority(DWORD priority) { if (priority == m_nPriority) { // Nothing to do return; } // Clear the bitmap ClearBitmap(m_pLastBitmap); m_nPriority = priority; m_bPriorityHasChanged = TRUE; if (LGLCD_PRIORITY_IDLE_NO_SHOW == m_nPriority) { // send an empty bitmap at idle priority if (LGLCD_INVALID_DEVICE != m_hDevice) { lgLcdUpdateBitmap(m_hDevice, &m_pLastBitmap->hdr, LGLCD_ASYNC_UPDATE(LGLCD_PRIORITY_IDLE_NO_SHOW)); } } }
int main(int argc, char *argv[]) { int dwErr; BOOL bDetect = FALSE; int i; lgLcdConnectContextEx conn; lgLcdOpenByTypeContext ctx; lgLcdBitmap160x43x1 bitmap; if (argc > 1 && (strcmp(argv[1], "/detect") == 0)) { warn("Detect mode!"); bDetect = TRUE; } else if (!(argc > 1) || (strcmp(argv[1], "/mumble") != 0)) { CFUserNotificationDisplayAlert(0, 0, NULL, NULL, NULL, CFSTR("Nothing to see here"), CFSTR("This program is run by Mumble, and should not be started separately."), CFSTR("OK"), NULL, NULL, NULL); return 0; } /* * Clear and set up initial structures. */ memset(&conn, 0, sizeof(conn)); memset(&ctx, 0, sizeof(ctx)); memset(&bitmap, 0, sizeof(bitmap)); conn.appFriendlyName = G15_WIDGET_NAME; conn.isAutostartable = FALSE; conn.isPersistent = FALSE; conn.dwAppletCapabilitiesSupported =LGLCD_APPLET_CAP_BASIC | LGLCD_APPLET_CAP_BW; conn.connection = LGLCD_INVALID_CONNECTION; /* * Initialize and connect. */ dwErr = lgLcdInit(); if (dwErr != ERROR_SUCCESS) die(G15_ERR_INIT, "Unable to initialize Logitech LCD library. (Error: %i)", dwErr); dwErr = lgLcdConnectEx(&conn); if (dwErr != ERROR_SUCCESS) die(G15_ERR_CONNECT, "Unable to connect to Logitech LCD manager. (Error: %i)", dwErr); ctx.connection = conn.connection; ctx.device = LGLCD_INVALID_DEVICE; ctx.deviceType =LGLCD_DEVICE_BW; dwErr = lgLcdOpenByType(&ctx); warn("That returned %d %d", dwErr, ERROR_SUCCESS); if (bDetect) return (dwErr != ERROR_SUCCESS); else if (dwErr != ERROR_SUCCESS) die(G15_ERR_OPEN, "Unable to open device. (Error: %i)", dwErr); /* * Diplay buffer format. */ bitmap.hdr.Format = LGLCD_BMP_FORMAT_160x43x1; /* * Main drawing loop. */ while (1) { int ret; int remain = 0; BYTE bPriority; ret = read(0, &bPriority, 1); if (ret == -1 || ret != 1) die(G15_ERR_READFILE, "Error while reading priority."); do { ret = read(0, bitmap.pixels + remain, G15_MAX_FBMEM - remain); if (ret < 1) die(G15_ERR_READFILE, "Error while reading framebuffer. %d (%s)", ret, strerror(errno)); remain += ret; } while (remain < G15_MAX_FBMEM); dwErr = lgLcdUpdateBitmap(ctx.device, (const lgLcdBitmapHeader *) &bitmap, bPriority ? LGLCD_SYNC_UPDATE(LGLCD_PRIORITY_ALERT) : LGLCD_SYNC_UPDATE(LGLCD_PRIORITY_NORMAL)); if (dwErr != ERROR_SUCCESS) warn("Unable to update bitmap for device #%i successfully. (Error: %i)", i, dwErr); } /* * Close device connections. */ dwErr = lgLcdClose(ctx.device); if (dwErr != ERROR_SUCCESS) die(G15_ERR_CLOSE, "Unable to close LCD device. (Error: %i)", dwErr); /* * Disconnect from LCD monitor. */ dwErr = lgLcdDisconnect(conn.connection); if (dwErr != ERROR_SUCCESS) die(G15_ERR_DISCONNECT, "Unable to disconnect from LCD manager. (Error: %i)", dwErr); /* * Deinitialize G15 library. */ dwErr = lgLcdDeInit(); if (dwErr != ERROR_SUCCESS) die(G15_ERR_DEINIT, "Unable to deinitialize LCD library. (Error: %i)", dwErr); warn("Terminated successfully."); return 0; }