void ILGCDeinit() { _FinalizerStopFlag = 1; GC_TRACE("ILGCDeinit: Performing final GC [thread:%d]\n", (int)ILThreadSelf()); /* Do a final GC */ ILGCCollect(); /* Cleanup the finalizer thread */ if (_FinalizerThread && _FinalizerThreadStarted) { GC_TRACE("ILGCDeinit: Peforming last finalizer run [thread:%d]\n", (int)ILThreadSelf()); ILWaitEventSet(_FinalizerSignal); GC_TRACE("ILGCDeinit: Waiting for finalizer thread to end [thread:%d]\n", (int)ILThreadSelf()); /* Wait for the finalizer thread */ if (ILThreadJoin(_FinalizerThread, 15000)) { GC_TRACE("ILGCDeinit: Finalizer thread finished [thread:%d]\n", (int)ILThreadSelf()); } else { GC_TRACE("ILGCDeinit: Finalizer thread not responding [thread:%d]\n", (int)ILThreadSelf()); } /* Destroy the finalizer thread */ ILThreadDestroy(_FinalizerThread); } _ILMutexDestroy(&_FinalizerLock); }
int _fastcall TScanPort::ScanBRomComPort(int index) { string friendlyName; string label; int number; COMPortUtils comFinder; int comportType; //First scan GC_TRACE("<TScanPort> Execute(): First scan..."); comportType = BOOTROM_COMPORT; comFinder.ScanFriendlyNameByDDK(true, comportType); GC_TRACE("<TScanPort> Execute(): Scan Bootrom COM port for Channel[%d]...", index); while(!(*mpStopFlag)) { if(comFinder.GetNewPortFriendlyName(friendlyName, comportType)){ if(comFinder.ExtractCOMNumber(friendlyName, number)){ GC_TRACE("<TScanPort> Execute(): Find new Bootrom COM port for Channel[%d]! COM%d, comportType = %d", index, number, comportType); mIndex = index; m_BromComNum = number; SyncUpdateCOMPort(); break; } } Sleep(500); } return S_DONE; }
void __fastcall TScanPort::ScanPrealoderOnly() { bool * chnChecked = new bool[mArraySize]; COMPortUtils comFinder; int comportType; string friendlyName; int number; int iRet = S_STOP; memcpy(chnChecked, mpIndexArray, mArraySize * sizeof(bool)); //=====================Step1 Scan Brom Comport======================== for(unsigned int iCycle = 0; (iCycle < mArraySize) && (!(*mpStopFlag));iCycle++){ if(chnChecked[iCycle]){ m_BromComNum = 0; m_PreLoaderComNum = 0; mIndex = iCycle; //First scan and make comport list GC_TRACE("<TScanPort> ScanPrealoderOnly(): First scan..."); comportType = PRELOADER_COMPORT; comFinder.ScanFriendlyNameByDDK(true, comportType); //Now we find the new comport and compare with the comport list created by first scan GC_TRACE("<TScanPort> ScanPrealoderOnly(): Scan Prealoader COM port for Channel[%d]...", mIndex); iRet = S_STOP; while(!(*mpStopFlag)) { if(comFinder.GetNewPortFriendlyName(friendlyName, comportType)){ if(comFinder.ExtractCOMNumber(friendlyName, number)){ GC_TRACE("<TScanPort> ScanPrealoderOnly(): Find new Prealoader COM port for Channel[%d]! COM%d, comportType = %d", mIndex, number, comportType); mIndex = iCycle; m_PreLoaderComNum = number; SyncUpdateCOMPort(); iRet = S_DONE; break; } } Sleep(500); } if(S_DONE == iRet && m_PreLoaderComNum != 0){ SyncUpdateScanSuccess(); GC_TRACE("<TScanPort> ScanPrealoderOnly(): ScanPrealoderOnly success!"); } else{ SyncUpdateScanFail(); GC_TRACE("<TScanPort> ScanPrealoderOnly(): ScanPrealoderOnly fail!"); break; } } } delete [] chnChecked; SyncEnableUIForScan(); }
static uint16_t _find_selected_button_id(GRAPHICS_CONTROLLER *gc) { /* executed when playback condition changes (ex. new page, popup-on, ...) */ PG_DISPLAY_SET *s = gc->igs; BD_IG_PAGE *page = NULL; unsigned page_id = bd_psr_read(gc->regs, PSR_MENU_PAGE_ID); unsigned button_id = bd_psr_read(gc->regs, PSR_SELECTED_BUTTON_ID); unsigned ii; page = _find_page(&s->ics->interactive_composition, page_id); if (!page) { GC_TRACE("_find_selected_button_id(): unknown page #%d (have %d pages)\n", page_id, s->ics->interactive_composition.num_pages); return 0xffff; } /* run 5.9.8.3 */ /* 1) always use page->default_selected_button_id_ref if it is valid */ if (_find_button_page(page, page->default_selected_button_id_ref, NULL) && _is_button_enabled(gc, page, page->default_selected_button_id_ref)) { GC_TRACE("_find_selected_button_id() -> default #%d\n", page->default_selected_button_id_ref); return page->default_selected_button_id_ref; } /* 2) fallback to current PSR10 value if it is valid */ for (ii = 0; ii < page->num_bogs; ii++) { BD_IG_BOG *bog = &page->bog[ii]; uint16_t enabled_button = gc->bog_data[ii].enabled_button; if (button_id == enabled_button) { if (_find_button_bog(bog, enabled_button)) { GC_TRACE("_find_selected_button_id() -> PSR10 #%d\n", enabled_button); return enabled_button; } } } /* 3) fallback to find first valid_button_id_ref from page */ for (ii = 0; ii < page->num_bogs; ii++) { BD_IG_BOG *bog = &page->bog[ii]; uint16_t enabled_button = gc->bog_data[ii].enabled_button; if (_find_button_bog(bog, enabled_button)) { GC_TRACE("_find_selected_button_id() -> first valid #%d\n", enabled_button); return enabled_button; } } GC_TRACE("_find_selected_button_id(): not found -> 0xffff\n"); return 0xffff; }
void __fastcall TScanPort::Execute() { switch(m_eScanComportType) { case SCAN_BROM_AND_PRELOADER: GC_TRACE("<TScanPort> Execute(): Scan brom and prealoder begin..."); ScanBromAndPreloader(); break; case SCAN_PRELOADER_ONLY: GC_TRACE("<TScanPort> Execute(): Scan prealoder begin..."); ScanPrealoderOnly(); break; default: break; } }
//------------------------------------------------------------------------------ bool open_com_port( HANDLE &hCOM_HANDLE, int i_com_port, int i_baud_rate) { if ( hCOM_HANDLE != NULL && hCOM_HANDLE != INVALID_HANDLE_VALUE ) { PurgeComm( hCOM_HANDLE, PURGE_TXABORT); PurgeComm( hCOM_HANDLE, PURGE_RXABORT); PurgeComm( hCOM_HANDLE, PURGE_TXCLEAR); PurgeComm( hCOM_HANDLE, PURGE_RXCLEAR); CloseHandle( hCOM_HANDLE); hCOM_HANDLE = NULL; } char c_com[50]; ::sprintf(c_com, "\\\\.\\COM%d", i_com_port); hCOM_HANDLE = ::CreateFile( c_com, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if( hCOM_HANDLE == INVALID_HANDLE_VALUE ) { //ShowMessage(" COM" + IntToStr( i_com_port) + " is used by other program."); GC_TRACE("<EfuseWriter> open_com_port(): Com %d is used by other program", i_com_port); hCOM_HANDLE = NULL; return false; } if( ::SetupComm(hCOM_HANDLE, 8192, 8192)==FALSE ) return false; if( ::PurgeComm(hCOM_HANDLE, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR)==FALSE ) return false; COMMTIMEOUTS TimeOut; TimeOut.ReadIntervalTimeout = 0; TimeOut.ReadTotalTimeoutMultiplier = 1; TimeOut.ReadTotalTimeoutConstant = 700; TimeOut.WriteTotalTimeoutMultiplier = 1; TimeOut.WriteTotalTimeoutConstant = 700; SetCommTimeouts(hCOM_HANDLE, &TimeOut); char c_dcb[50]; ::sprintf( c_dcb, "%d,n,8,1", i_baud_rate); BuildCommDCB( c_dcb, &dcb ); SetCommState( hCOM_HANDLE, &dcb ); return true; }
static BD_PG_OBJECT *_find_object_for_button(PG_DISPLAY_SET *s, BD_IG_BUTTON *button, int state, BOG_DATA *bog_data) { BD_PG_OBJECT *object = NULL; unsigned object_id = 0xffff; unsigned object_id_end = 0xffff; unsigned repeat = 0; switch (state) { case BTN_NORMAL: object_id = button->normal_start_object_id_ref; object_id_end = button->normal_end_object_id_ref; repeat = button->normal_repeat_flag; break; case BTN_SELECTED: object_id = button->selected_start_object_id_ref; object_id_end = button->selected_end_object_id_ref; repeat = button->selected_repeat_flag; break; case BTN_ACTIVATED: object_id = button->activated_start_object_id_ref; object_id_end = button->activated_end_object_id_ref; break; } if (bog_data) { if (bog_data->animate_indx >= 0) { int range = object_id_end - object_id; if (range > 0 && object_id < 0xffff && object_id_end < 0xffff) { GC_TRACE("animate button #%d: animate_indx %d, range %d, repeat %d\n", button->id, bog_data->animate_indx, range, repeat); object_id += bog_data->animate_indx % (range + 1); bog_data->animate_indx++; if (!repeat && bog_data->animate_indx > range) { /* terminate animation to the last object */ bog_data->animate_indx = -1; } } else { /* no animation for this button */ bog_data->animate_indx = -1; } } } if (!repeat && object_id_end < 0xfffe) { object_id = object_id_end; } object = _find_object(s, object_id); return object; }
int _fastcall TScanPort::SwitchToHighSpeedComPort(string strVid, string strPid) { int iRet = S_DONE; unsigned short tempVidPid; USB_Setup_Info usb_setup_info; //FlashTool_CheckUSBStatus arguments FlashTool_USB_Status_Arg usb_status_arg; FlashTool_USB_Status_Result usb_statue_result; usb_status_arg.m_cb_usb_status_init = NULL; usb_status_arg.cb_usb_status_init_arg = NULL; usb_statue_result.usb_speed_status = USB_STATUS_UNKNOWN; GC_TRACE("[iComNum%d] SwitchToHighSpeedComPort():enter enum preloader comport.", m_BromComNum); iRet = FlashTool_CheckUSBStatus(m_ft_api_handle, &usb_status_arg, &usb_statue_result); if (usb_statue_result.usb_speed_status != USB_FULL_SPEED) // If usb is not full speed status, do not switch. { GC_TRACE("[COM%d] ScanPreLoaderComPort(): The com port is in high speed, do not switch it.",m_BromComNum); return -1; } GC_TRACE("[iComNum%d] SwitchToHighSpeedComPort():FlashTool_CheckUSBStatus, usb_speed_status is %d", m_BromComNum, usb_statue_result.usb_speed_status); //get new comport of Preloader comport usb_setup_info.enable_hs = 1; //translate pid&vid str to hex sscanf(strVid.c_str(), "%x", &tempVidPid); usb_setup_info.vid = tempVidPid; sscanf(strPid.c_str(), "%x", &tempVidPid); usb_setup_info.pid = tempVidPid; if(usb_setup_info.pid == 0 || usb_setup_info.vid == 0) { usb_setup_info.pid = 0x2000; usb_setup_info.vid = 0x0E8D; } GC_TRACE("[iComNum%d] SwitchToHighSpeedComPort():Preloader pid = 0x%4X, vid =0x%4X", m_BromComNum, usb_setup_info.pid, usb_setup_info.vid); iRet = FlashTool_SetupUSBDL_EX(&m_ft_api_handle, &usb_setup_info); if( S_DONE != iRet ) { GC_TRACE("[COM%d] SwitchComport(): [ERROR] Setup USB DL fail!,ret=%d",m_BromComNum,iRet); return iRet; } return iRet; }
static void _enable_button(GRAPHICS_CONTROLLER *gc, uint32_t button_id, unsigned enable) { PG_DISPLAY_SET *s = gc->igs; BD_IG_PAGE *page = NULL; BD_IG_BUTTON *button = NULL; unsigned page_id = bd_psr_read(gc->regs, PSR_MENU_PAGE_ID); unsigned cur_btn_id = bd_psr_read(gc->regs, PSR_SELECTED_BUTTON_ID); unsigned bog_idx = 0; GC_TRACE("_enable_button(#%d, %s)\n", button_id, enable ? "enable" : "disable"); page = _find_page(&s->ics->interactive_composition, page_id); if (!page) { GC_TRACE("_enable_button(): unknown page #%d (have %d pages)\n", page_id, s->ics->interactive_composition.num_pages); return; } /* find correct button overlap group */ button = _find_button_page(page, button_id, &bog_idx); if (!button) { GC_TRACE("_enable_button(): unknown button #%d (page #%d)\n", button_id, page_id); return; } if (enable) { if (gc->bog_data[bog_idx].enabled_button == cur_btn_id) { /* selected button goes to disabled state */ bd_psr_write(gc->regs, PSR_SELECTED_BUTTON_ID, 0x10000|button_id); } gc->bog_data[bog_idx].enabled_button = button_id; } else { if (gc->bog_data[bog_idx].enabled_button == button_id) { gc->bog_data[bog_idx].enabled_button = 0xffff; } if (cur_btn_id == button_id) { bd_psr_write(gc->regs, PSR_SELECTED_BUTTON_ID, 0xffff); } } }
static void _update_selected_button(GRAPHICS_CONTROLLER *gc) { /* executed after IG command sequence terminates */ unsigned button_id = bd_psr_read(gc->regs, PSR_SELECTED_BUTTON_ID); GC_TRACE("_update_selected_button(): currently enabled button is #%d\n", button_id); /* special case: triggered only after enable button disables selected button */ if (button_id & 0x10000) { button_id &= 0xffff; _select_button(gc, button_id); GC_TRACE("_update_selected_button() -> #%d [last enabled]\n", button_id); return; } if (button_id == 0xffff) { button_id = _find_selected_button_id(gc); _select_button(gc, button_id); } }
/* find_block -- find a free block of specified size */ static header *find_block(unsigned size, unsigned objsize) { header *h = NULL, *h2; int i = min(size/GC_PAGESIZE, BIG_BLOCK); ASSERT(size % GC_PAGESIZE == 0); do { for (headers(h2, free_list[i])) { /* This always succeeds for small blocks, and gives first-fit allocation for big blocks. */ if (size <= h2->h_size) { h = h2; break; } } i++; } while (h == NULL && i <= BIG_BLOCK); if (h == NULL) { /* No suitable block was found. Get a big chunk. */ unsigned chunk = max(size, CHUNK_SIZE); GC_TRACE("[ex]"); ASSERT(chunk % GC_PAGESIZE == 0); h = alloc_header(); h->h_memory = (uchar *) get_memory(chunk); h->h_size = chunk; /* Add to the free list for merging and page table setup */ h = free_block(h, FALSE); } ASSERT(h->h_memory != NULL && h->h_size >= size); unlink(h); if (size < h->h_size) { /* Split the block, and return the waste to the free list. It's best to use header h for the waste: that way, we don't have to reset lots of page table entries when we chip a small piece off a big block. */ h2 = alloc_header(); h2->h_memory = h->h_memory; h2->h_size = size; page_setup(h2->h_memory, size, h2); h->h_memory += size; h->h_size -= size; make_free(h); h = h2; } h->h_objsize = objsize; h->h_epoch = gencount; return h; }
int gc_decode_ts(GRAPHICS_CONTROLLER *gc, uint16_t pid, uint8_t *block, unsigned num_blocks, int64_t stc) { if (!gc) { GC_TRACE("gc_decode_ts(): no graphics controller\n"); return -1; } if (pid >= 0x1400 && pid < 0x1500) { /* IG stream */ if (!gc->igp) { gc->igp = graphics_processor_init(); } bd_mutex_lock(&gc->mutex); if (!graphics_processor_decode_ts(gc->igp, &gc->igs, pid, block, num_blocks, stc)) { /* no new complete display set */ bd_mutex_unlock(&gc->mutex); return 0; } if (!gc->igs || !gc->igs->complete) { bd_mutex_unlock(&gc->mutex); return 0; } bd_mutex_unlock(&gc->mutex); return 1; } else if (pid >= 0x1200 && pid < 0x1300) { /* PG stream */ if (!gc->pgp) { gc->pgp = graphics_processor_init(); } graphics_processor_decode_ts(gc->pgp, &gc->pgs, pid, block, num_blocks, stc); if (!gc->pgs || !gc->pgs->complete) { return 0; } return 1; } return -1; }
int _fastcall TScanPort::ScanPreLoaderComPort(unsigned int iComNum, int index) { int iRet = S_DONE; string friendlyName; string label; int number; COMPortUtils comFinder; int comportType; //============Step1 Download Da and connect dA=============================== GC_TRACE("[iComNum%d] ScanPreLoaderComPort():Da Connect begin.", iComNum); iRet = DAConnect(iComNum); if(S_DONE != iRet){ GC_TRACE("[iComNum%d] ScanPreLoaderComPort(): [ERROR] DAConnect fail!ret=%d", iComNum, iRet); return iRet; } //============Step2 change brom pid & vid to preloader pid & vid============= //Step2.1 First scan to get comport list before change preloader pid & vid GC_TRACE("<TScanPort> ScanPreLoaderComPort(): First scan..."); comportType = PRELOADER_COMPORT; comFinder.ScanFriendlyNameByDDK(true, comportType); //Step2.2 change Brom vid & pid to Preloader pid&vid iRet = SwitchToHighSpeedComPort(comFinder.GetAndroidVid(), comFinder.GetPreloaderPid()); if(S_DONE != iRet) { DADisConnect(); return iRet; } //=============Step3 Scan Preloader comport================================== GC_TRACE("<TScanPort> Execute(): Scan preloader COM port for Channel[%d]...", index); while(!(*mpStopFlag)) { if(comFinder.GetNewPortFriendlyName(friendlyName, comportType)){ if( comFinder.ExtractCOMNumber(friendlyName, number)){ GC_TRACE("<TScanPort> Execute(): Find new preloader COM port for Channel[%d]! COM%d, comportType = %d", index, number, comportType); mIndex = index; m_PreLoaderComNum = number; SyncUpdateCOMPort(); break; } } Sleep(500); } //=============Step4 change comport from full speed to high speed comport================= iRet = FlashTool_ChangeCOM(&m_ft_api_handle, m_PreLoaderComNum); if(iRet != S_DONE) { GC_TRACE("<TScanPort> Execute():: [ERROR] Change COM port fail!"); return iRet; } DADisConnect(); return iRet; }
void __fastcall TScanPort::ScanBromAndPreloader() { bool * chnChecked = new bool[mArraySize]; m_bIsDaConnecting = false; memcpy(chnChecked, mpIndexArray, mArraySize * sizeof(bool)); //=====================Step1 Scan Brom Comport======================== for(unsigned int iCycle = 0; (iCycle < mArraySize) && (!(*mpStopFlag));iCycle++){ if(chnChecked[iCycle]){ m_BromComNum = 0; m_PreLoaderComNum = 0; mIndex = iCycle; //Scan brom comport success if(S_DONE == ScanBRomComPort(iCycle) && m_BromComNum != 0){ GC_TRACE("<TScanPort> ScanBromAndPreloader(): ScanBRomComPort success!"); //Step2 Scan Preloader comport if(S_DONE == ScanPreLoaderComPort(m_BromComNum,iCycle)){ SyncUpdateScanSuccess(); GC_TRACE("<TScanPort> ScanBromAndPreloader(): ScanPreLoaderComPort Success!"); } else{ SyncUpdateScanFail(); GC_TRACE("<TScanPort> ScanBromAndPreloader(): ScanPreLoaderComPort fail!"); break; } } else{ SyncUpdateScanFail(); GC_TRACE("<TScanPort> ScanBromAndPreloader(): ScanBRomComPort fail!"); break; } } } delete [] chnChecked; SyncEnableUIForScan(); }
/* * Main entry point for the finalizer thread. */ static void _FinalizerThreadFunc(void *data) { GC_TRACE("GC:_FinalizerThread: Finalizer thread started [thread:%d]\n", (int)ILThreadSelf()); for (;;) { ILWaitOne(_FinalizerSignal, -1); GC_TRACE("GC:_FinalizerThread: Signal [thread:%d]\n", (int)ILThreadSelf()); /* This *must* to be set before checking for !_FinalizersDisabled to prevent a race with ILGCDisableFinalizers */ _FinalizersRunning = 1; ILThreadMemoryBarrier(); if (GC_should_invoke_finalizers() && !_FinalizersDisabled) { GC_TRACE("GC:_FinalizerThread: Finalizers running [thread:%d]\n", (int)ILThreadSelf()); GC_invoke_finalizers(); GC_TRACE("GC:_FinalizerThread: Finalizers finished [thread:%d]\n", (int)ILThreadSelf()); } _FinalizersRunning = 0; ILThreadMemoryBarrier(); if (_FinalizerStopFlag) { /* Exit finalizer thread after having invoked finalizers one last time */ GC_TRACE("GC:_FinalizerThread: Finalizer thread finished [thread:%d]\n", (int)ILThreadSelf()); ILWaitEventReset(_FinalizerSignal); /* Wake all waiting threads */ ILWaitEventPulse(_FinalizerResponse); return; } GC_TRACE("GC:_FinalizerThread: Response [thread:%d]\n", (int)ILThreadSelf()); ILWaitEventReset(_FinalizerSignal); /* Wake all waiting threads */ ILWaitEventPulse(_FinalizerResponse); } }
void EfuseSettings::ReadEfuseSettings(void) { AnsiString iniFileNameWithPath = NULL; AnsiString asPath = NULL; AnsiString as_str; if (getPathFromStr(Application->ExeName,asPath)) { GC_TRACE("<EfuseSettings> ReadEfuseSettings(): the tool path is %s", asPath); iniFileNameWithPath = asPath + "Efuse.ini"; if (!Check_FileExist(iniFileNameWithPath)) { GC_TRACE("<EfuseSettings> ReadEfuseSettings(): Can not find Efuse.ini file. "); return; } } TIniFile *ini; try { ini = new TIniFile(iniFileNameWithPath); if(ini != NULL) { as_str = ini->ReadString(EFUSE_SETTINGS, "Enable", "0"); mEfuseEnable = atoi(as_str.c_str()); as_str = ini->ReadString(EFUSE_SETTINGS, "SettingsEnable", "0"); mEfuseSettingsEnable = atoi(as_str.c_str()); as_str = ini->ReadString(EFUSE_SETTINGS, "LockEnable", "0"); mEfuseLockEnable = atoi(as_str.c_str()); as_str = ini->ReadString(EFUSE_SETTINGS, "ReadBackEnable", "0"); mEfuseReadBackEnable = atoi(as_str.c_str()); //dump GC_TRACE("<EfuseSettings> ReadEfuseSettings() the mEfuseEnable = %d .", mEfuseEnable); GC_TRACE("<EfuseSettings> ReadEfuseSettings() the mEfuseSettingsEnable = %d .", mEfuseSettingsEnable); GC_TRACE("<EfuseSettings> ReadEfuseSettings() the mEfuseLockEnable = %d .", mEfuseLockEnable); GC_TRACE("<EfuseSettings> ReadEfuseSettings() the mEfuseReadBackEnable = %d .", mEfuseReadBackEnable); delete ini; } } catch (...) { ShowMessage( "read setup file " + iniFileNameWithPath + " error"); delete ini; } /* TIniFile* efuseSettingsIni; TStringList* str_list = NULL; try { str_list = new TStringList; efuseSettingsIni = new TIniFile(iniFileNameWithPath.c_str()); efuseSettingsIni->ReadSection(EFUSE_SETTINGS, str_list); if ( 4 > str_list->Count ) { GC_TRACE("<EfuseSettings> ReadEfuseSettings() the config numbers is smaller than 4."); return; } this->mEfuseEnable = atoi(efuseSettingsIni->ReadString(EFUSE_SETTINGS, str_list->Strings[0], "0").c_str()); GC_TRACE("<EfuseSettings> ReadEfuseSettings() the mEfuseEnable is %d .", this->mEfuseEnable); this->mEfuseSettingsEnable = atoi(efuseSettingsIni->ReadString(EFUSE_SETTINGS, str_list->Strings[1], "0").c_str()); GC_TRACE("<EfuseSettings> ReadEfuseSettings() the mEfuseSettingsEnable is %d .", this->mEfuseSettingsEnable); this->mEfuseLockEnable = atoi(efuseSettingsIni->ReadString(EFUSE_SETTINGS, str_list->Strings[2], "0").c_str()); GC_TRACE("<EfuseSettings> ReadEfuseSettings() the mEfuseLockEnable is %d .", this->mEfuseLockEnable); this->mEfuseReadBackEnable = atoi(efuseSettingsIni->ReadString(EFUSE_SETTINGS, str_list->Strings[3], "0").c_str()); GC_TRACE("<EfuseSettings> ReadEfuseSettings() the mEfuseReadBackEnable is %d .", this->mEfuseReadBackEnable); } catch (const std::exception& ex) { if (NULL != str_list) { delete str_list; str_list = NULL; } if (NULL != efuseSettingsIni) { delete efuseSettingsIni; efuseSettingsIni = NULL; } GC_TRACE("<EfuseSettings> ReadEfuseSettings() failed, reason(%s).", ex.what()); } if (NULL != str_list) { delete str_list; str_list = NULL; } if (NULL != efuseSettingsIni) { delete efuseSettingsIni; efuseSettingsIni = NULL; }*/ }
// 发送数据 bool CCommunication::PendingSend(DWORD dwlen) { WSABUF wsabuf; WSAOVERLAPPED over; DWORD dwSend; DWORD dwTotalSend = 0; DWORD dwFlags; DWORD dwRet; BOOL fPending; ZeroMemory(&over, sizeof(WSAOVERLAPPED)); wsabuf.buf = m_pbBuffer; wsabuf.len = dwlen; over.hEvent = WSACreateEvent(); if (over.hEvent == WSA_INVALID_EVENT) { #ifdef _ZZYDEBUG GC_TRACE("Error5"); #endif CloseSocket(); return false; } while(1) { fPending = FALSE; // 发送数据 int nRet = WSASend(m_WorkSocket, &wsabuf, 1, &dwSend, 0, &over, NULL); if (nRet != 0) { if (WSAGetLastError() != WSA_IO_PENDING) { #ifdef _ZZYDEBUG GC_TRACE("Error4:%d",WSAGetLastError()); #endif WSACloseEvent(over.hEvent); CloseSocket(); return false; } else { fPending = TRUE; } } else { fPending = TRUE; } // 发送I/O操作未结束 if (fPending) { // 等待发送I/O操作接束 dwRet = WSAWaitForMultipleEvents(1, &(over.hEvent), FALSE, m_nTimeOut*1000, FALSE); if (dwRet==WSA_WAIT_FAILED || dwRet==WAIT_TIMEOUT) { #ifdef _ZZYDEBUG if (dwRet==WSA_WAIT_FAILED) GC_TRACE("Error1"); else GC_TRACE("Error6"); #endif WSACloseEvent(over.hEvent); CloseSocket(); return false; } WSAResetEvent(over.hEvent); // 判断重叠操作是否成功 if (!WSAGetOverlappedResult(m_WorkSocket, &over, &dwSend, FALSE, &dwFlags)) { #ifdef _ZZYDEBUG GC_TRACE("Error2"); #endif WSACloseEvent(over.hEvent); CloseSocket(); return false; } else { if (dwSend == 0) { #ifdef _ZZYDEBUG GC_TRACE("Error3"); #endif WSACloseEvent(over.hEvent); CloseSocket(); return false; } // 计算剩余发送字节数 wsabuf.len -= dwSend; dwTotalSend += dwSend; if(wsabuf.len <= 0) { break; } else { wsabuf.buf += dwSend; } } } }//while (1) 发送未结束 // 发送完成 if(over.hEvent) { WSACloseEvent(over.hEvent); } return true; }
static int _user_input(GRAPHICS_CONTROLLER *gc, uint32_t key, GC_NAV_CMDS *cmds) { PG_DISPLAY_SET *s = gc->igs; BD_IG_PAGE *page = NULL; unsigned page_id = bd_psr_read(gc->regs, PSR_MENU_PAGE_ID); unsigned cur_btn_id = bd_psr_read(gc->regs, PSR_SELECTED_BUTTON_ID); unsigned new_btn_id = cur_btn_id; unsigned ii; int activated_btn_id = -1; if (s->ics->interactive_composition.ui_model == IG_UI_MODEL_POPUP && !gc->popup_visible) { GC_TRACE("_user_input(): popup menu not visible\n"); return -1; } if (!gc->ig_drawn) { GC_ERROR("_user_input(): menu not visible\n"); return -1; } GC_TRACE("_user_input(%d)\n", key); page = _find_page(&s->ics->interactive_composition, page_id); if (!page) { GC_ERROR("_user_input(): unknown page id %d (have %d pages)\n", page_id, s->ics->interactive_composition.num_pages); return -1; } if (key == BD_VK_MOUSE_ACTIVATE) { if (!gc->valid_mouse_position) { GC_TRACE("_user_input(): BD_VK_MOUSE_ACTIVATE outside of valid buttons\n"); return -1; } key = BD_VK_ENTER; } for (ii = 0; ii < page->num_bogs; ii++) { BD_IG_BOG *bog = &page->bog[ii]; unsigned valid_id = gc->bog_data[ii].enabled_button; BD_IG_BUTTON *button = _find_button_bog(bog, valid_id); if (!button) { continue; } /* numeric select */ if (VK_IS_NUMERIC(key)) { if (button->numeric_select_value == VK_TO_NUMBER(key)) { new_btn_id = button->id; } } /* cursor keys */ else if (VK_IS_CURSOR(key) || key == BD_VK_ENTER) { if (button->id == cur_btn_id) { switch(key) { case BD_VK_UP: new_btn_id = button->upper_button_id_ref; break; case BD_VK_DOWN: new_btn_id = button->lower_button_id_ref; break; case BD_VK_LEFT: new_btn_id = button->left_button_id_ref; break; case BD_VK_RIGHT: new_btn_id = button->right_button_id_ref; break; case BD_VK_ENTER: activated_btn_id = cur_btn_id; cmds->num_nav_cmds = button->num_nav_cmds; cmds->nav_cmds = button->nav_cmds; cmds->sound_id_ref = button->activated_sound_id_ref; break; default:; } } if (new_btn_id != cur_btn_id) { BD_IG_BUTTON *new_button = _find_button_page(page, new_btn_id, NULL); if (new_button) { cmds->sound_id_ref = new_button->selected_sound_id_ref; } } } } /* render page ? */ if (new_btn_id != cur_btn_id || activated_btn_id >= 0) { _select_button(gc, new_btn_id); _render_page(gc, activated_btn_id, cmds); /* found one*/ return 1; } return 0; }
static void _set_button_page(GRAPHICS_CONTROLLER *gc, uint32_t param) { unsigned page_flag = param & 0x80000000; unsigned effect_flag = param & 0x40000000; unsigned button_flag = param & 0x20000000; unsigned page_id = (param >> 16) & 0xff; unsigned button_id = param & 0xffff; unsigned bog_idx = 0; PG_DISPLAY_SET *s = gc->igs; BD_IG_PAGE *page = NULL; BD_IG_BUTTON *button = NULL; GC_TRACE("_set_button_page(0x%08x): page flag %d, id %d, effects %d button flag %d, id %d\n", param, !!page_flag, page_id, !!effect_flag, !!button_flag, button_id); /* 10.4.3.4 (D) */ if (!page_flag && !button_flag) { return; } if (page_flag) { /* current page --> command is ignored */ if (page_id == bd_psr_read(gc->regs, PSR_MENU_PAGE_ID)) { GC_TRACE(" page is current\n"); return; } page = _find_page(&s->ics->interactive_composition, page_id); /* invalid page --> command is ignored */ if (!page) { GC_TRACE(" page is invalid\n"); return; } /* page changes */ _select_page(gc, page_id); } else { /* page does not change */ page_id = bd_psr_read(gc->regs, PSR_MENU_PAGE_ID); page = _find_page(&s->ics->interactive_composition, page_id); if (!page) { GC_ERROR("_set_button_page(): PSR_MENU_PAGE_ID refers to unknown page %d\n", page_id); return; } } if (button_flag) { /* find correct button and overlap group */ button = _find_button_page(page, button_id, &bog_idx); if (!page_flag) { if (!button) { /* page not given, invalid button --> ignore command */ GC_TRACE(" button is invalid\n"); return; } if (button_id == bd_psr_read(gc->regs, PSR_SELECTED_BUTTON_ID)) { /* page not given, current button --> ignore command */ GC_TRACE(" button is current\n"); return; } } } if (button) { gc->bog_data[bog_idx].enabled_button = button_id; _select_button(gc, button_id); } _render_page(gc, 0xffff, NULL); /* auto action not triggered yet */ }
static void _render_button(GRAPHICS_CONTROLLER *gc, BD_IG_BUTTON *button, BD_PG_PALETTE *palette, int state, BOG_DATA *bog_data) { BD_PG_OBJECT *object = _find_object_for_button(gc->igs, button, state, bog_data); if (!object) { GC_TRACE("_render_button(#%d): object (state %d) not found\n", button->id, state); _clear_bog_area(gc, bog_data); return; } /* object already rendered ? */ if (bog_data->visible_object_id == object->id && bog_data->x == button->x_pos && bog_data->y == button->y_pos && bog_data->w == object->width && bog_data->h == object->height) { GC_TRACE("skipping already rendered button #%d (object #%d at %d,%d %dx%d)\n", button->id, object->id, button->x_pos, button->y_pos, object->width, object->height); return; } /* new object is smaller than already drawn one ? -> need to render background */ if (bog_data->w > object->width || bog_data->h > object->height) { /* make sure we won't wipe other buttons */ unsigned ii, skip = 0; for (ii = 0; &gc->bog_data[ii] != bog_data; ii++) { if (_areas_overlap(bog_data, &gc->bog_data[ii])) skip = 1; /* FIXME: clean non-overlapping area */ } GC_TRACE("object size changed, %sclearing background at %d,%d %dx%d\n", skip ? " ** NOT ** " : "", bog_data->x, bog_data->y, bog_data->w, bog_data->h); if (!skip) { _clear_bog_area(gc, bog_data); } } GC_TRACE("render button #%d using object #%d at %d,%d %dx%d\n", button->id, object->id, button->x_pos, button->y_pos, object->width, object->height); _render_object(gc, -1, BD_OVERLAY_IG, button->x_pos, button->y_pos, object, palette); bog_data->x = button->x_pos; bog_data->y = button->y_pos; bog_data->w = object->width; bog_data->h = object->height; bog_data->visible_object_id = object->id; gc->ig_drawn = 1; gc->ig_dirty = 1; }
static int _render_page(GRAPHICS_CONTROLLER *gc, unsigned activated_button_id, GC_NAV_CMDS *cmds) { PG_DISPLAY_SET *s = gc->igs; BD_IG_PAGE *page = NULL; BD_PG_PALETTE *palette = NULL; unsigned page_id = bd_psr_read(gc->regs, PSR_MENU_PAGE_ID); unsigned ii; unsigned selected_button_id = bd_psr_read(gc->regs, PSR_SELECTED_BUTTON_ID); if (s->ics->interactive_composition.ui_model == IG_UI_MODEL_POPUP && !gc->popup_visible) { if (gc->ig_open) { GC_TRACE("_render_page(): popup menu not visible\n"); _close_osd(gc, BD_OVERLAY_IG); return 1; } return 0; } page = _find_page(&s->ics->interactive_composition, page_id); if (!page) { GC_ERROR("_render_page: unknown page id %d (have %d pages)\n", page_id, s->ics->interactive_composition.num_pages); return -1; } palette = _find_palette(s, page->palette_id_ref); if (!palette) { GC_ERROR("_render_page: unknown palette id %d (have %d palettes)\n", page->palette_id_ref, s->num_palette); return -1; } GC_TRACE("rendering page #%d using palette #%d. page has %d bogs\n", page->id, page->palette_id_ref, page->num_bogs); if (!gc->ig_open) { _open_osd(gc, BD_OVERLAY_IG, s->ics->video_descriptor.video_width, s->ics->video_descriptor.video_height); } for (ii = 0; ii < page->num_bogs; ii++) { BD_IG_BOG *bog = &page->bog[ii]; unsigned valid_id = gc->bog_data[ii].enabled_button; BD_IG_BUTTON *button; button = _find_button_bog(bog, valid_id); if (!button) { GC_TRACE("_render_page(): bog %d: button %d not found\n", ii, valid_id); // render background _clear_bog_area(gc, &gc->bog_data[ii]); } else if (button->id == activated_button_id) { GC_TRACE(" button #%d activated\n", button->id); _render_button(gc, button, palette, BTN_ACTIVATED, &gc->bog_data[ii]); } else if (button->id == selected_button_id) { if (button->auto_action_flag && !gc->auto_action_triggered) { if (cmds) { GC_TRACE(" auto-activate #%d\n", button->id); cmds->num_nav_cmds = button->num_nav_cmds; cmds->nav_cmds = button->nav_cmds; gc->auto_action_triggered = 1; } else { GC_ERROR(" auto-activate #%d not triggered (!cmds)\n", button->id); } _render_button(gc, button, palette, BTN_ACTIVATED, &gc->bog_data[ii]); } else { _render_button(gc, button, palette, BTN_SELECTED, &gc->bog_data[ii]); } } else { _render_button(gc, button, palette, BTN_NORMAL, &gc->bog_data[ii]); } } if (gc->ig_dirty) { _flush_osd(gc, BD_OVERLAY_IG, -1); gc->ig_dirty = 0; return 1; } return 0; }
/* * Notify the finalization thread that there is work to do. */ static int PrivateGCNotifyFinalize(int timeout, int ignoreDisabled) { int result; if (_FinalizersDisabled && !ignoreDisabled) { return 0; } /* Prevent recursive finalization */ if (_FinalizersRunningSynchronously || ILThreadSelf() == _FinalizerThread) { return 0; } #ifdef GC_TRY_INVOKE_SYNCHRONOUSLY /* Try to invoke synchronously (for performance & single threaded systems) */ if (_InvokeFinalizersSynchronously() == 0) { return 0; } #endif /* There is no finalizer thread! We've already attempted to invoke synchronously (above) so just exit. */ if (_FinalizerThread == 0) { return 0; } /* Finalizers need to be run on a seperate thread. Start the finalizer thread if it hasn't been started */ if (!_FinalizerThreadStarted) { _ILMutexLock(&_FinalizerLock); if (!_FinalizerThreadStarted) { if (ILThreadStart(_FinalizerThread) == 0) { /* Couldn't create the finalizer thread */ GC_TRACE("PrivateGCInvokeFinalizers: Couldn't " \ "start finalizer thread [thread: %d]\n", (int)ILThreadSelf()); _ILMutexUnlock(&_FinalizerLock); return 0; } _FinalizerThreadStarted = 1; } _ILMutexUnlock(&_FinalizerLock); } /* Signal the finalizer thread */ GC_TRACE("PrivateGCInvokeFinalizers: Invoking finalizers " \ "and waiting [thread: %d]\n", (int)ILThreadSelf()); result = ILSignalAndWait(_FinalizerSignal, _FinalizerResponse, timeout); GC_TRACE("PrivateGCInvokeFinalizers: Finalizers finished[thread: %d]\n", (int)ILThreadSelf()); return result; }
int __fastcall TScanPort::DAConnect(const int iComport) { int iRet = S_DONE; unsigned char iConnetComNum = iComport; int force_charge = FORCE_CHARGE_ON; if(MainForm->m_miDADLNoBattery->Checked) { force_charge = FORCE_CHARGE_ON; } else if(MainForm->m_miDADLBattery->Checked) { force_charge = FORCE_CHARGE_OFF; } else if(MainForm->m_miDADLAutoDetect->Checked) { force_charge = FORCE_CHARGE_AUTO; } /* set FlashTool_Connect_Arg */ m_sConnArg.m_com_ms_read_timeout = COM_DEFAULT_TIMEOUT; m_sConnArg.m_com_ms_write_timeout = COM_DEFAULT_TIMEOUT; BootArgSetting(m_sConnArg.m_boot_arg); m_sConnArg.m_cb_security_pre_process_notify = NULL; m_sConnArg.m_cb_security_pre_process_notify_arg = NULL; m_sConnArg.m_nor_chip_select[0] = CS_0; m_sConnArg.m_nor_chip_select[1] = CS_WITH_DECODER; m_sConnArg.m_nand_chip_select = m_sDnParam.s_bbchip_op.b_enable_nfi_cs1?CS_1:CS_0; m_sConnArg.m_p_nand_acccon = NULL ; m_sConnArg.m_boot_arg.m_bmt_block_count = frmMultiLoad->m_BMT_blocks; m_sConnArg.m_storage_type = frmMultiLoad->m_Storage_Type;// m_storage_type m_sConnArg.m_force_charge = force_charge; DL_HANDLE_T *p_dl_handle = MainForm->Get_DlHandle(0); m_sConnArg.m_p_dl_handle = *p_dl_handle; /* connect to target */ iRet = FlashTool_Connect( /*index + m_sDnParam.i_FirstComNo,*/ iConnetComNum, &m_sConnArg, &m_sConnResult, NULL, MainForm->_t_manager.Get_stop_flag_addr(mIndex), &m_ft_api_handle); if(S_DONE != iRet) { GC_TRACE("[COM%d] DAConnect(): [ERROR] DA connect fail!", iConnetComNum); return iRet; } m_bIsDaConnecting = true; FlashTool_ChangeBaudrate_Arg ft_cb_arg; ft_cb_arg.m_baudrate = MainForm->Get_Baudrate(); ft_cb_arg.m_baudrate_full_sync_count = 1; ft_cb_arg.m_cb_set_high_speed_baudrate = NULL; ft_cb_arg.m_cb_set_high_speed_baudrate_arg = NULL; iRet = FlashTool_ChangeBaudrate(m_ft_api_handle, &ft_cb_arg); if(S_DONE != iRet) { GC_TRACE("[iComNum%d] DAConnect(): [ERROR] FlashTool_ChangeBaudrate fail!", iConnetComNum); DADisConnect(); return iRet; } return iRet; }
ZEND_API int zend_gc_collect_cycles(void) { int count = 0; if (GC_G(num_roots)) { gc_root_buffer *current, *last; zend_refcounted *p; uint32_t gc_flags = 0; uint32_t idx, end; gc_stack stack; stack.prev = NULL; stack.next = NULL; if (GC_G(gc_active)) { return 0; } GC_TRACE("Collecting cycles"); GC_G(gc_runs)++; GC_G(gc_active) = 1; GC_TRACE("Marking roots"); gc_mark_roots(&stack); GC_TRACE("Scanning roots"); gc_scan_roots(&stack); GC_TRACE("Collecting roots"); count = gc_collect_roots(&gc_flags, &stack); gc_stack_free(&stack); if (!GC_G(num_roots)) { /* nothing to free */ GC_TRACE("Nothing to free"); GC_G(gc_active) = 0; return 0; } end = GC_G(first_unused); if (gc_flags & GC_HAS_DESTRUCTORS) { uint32_t *refcounts; GC_TRACE("Calling destructors"); // TODO: may be use emalloc() ??? refcounts = pemalloc(sizeof(uint32_t) * end, 1); /* Remember reference counters before calling destructors */ idx = GC_FIRST_ROOT; current = GC_IDX2PTR(GC_FIRST_ROOT); while (idx != end) { if (GC_IS_GARBAGE(current->ref)) { p = GC_GET_PTR(current->ref); refcounts[idx] = GC_REFCOUNT(p); } current++; idx++; } /* Call destructors * * The root buffer might be reallocated during destructors calls, * make sure to reload pointers as necessary. */ idx = GC_FIRST_ROOT; while (idx != end) { current = GC_IDX2PTR(idx); if (GC_IS_GARBAGE(current->ref)) { p = GC_GET_PTR(current->ref); if (GC_TYPE(p) == IS_OBJECT && !(OBJ_FLAGS(p) & IS_OBJ_DESTRUCTOR_CALLED)) { zend_object *obj = (zend_object*)p; GC_TRACE_REF(obj, "calling destructor"); GC_ADD_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED); if (obj->handlers->dtor_obj != zend_objects_destroy_object || obj->ce->destructor) { GC_ADDREF(obj); obj->handlers->dtor_obj(obj); GC_DELREF(obj); } } } idx++; } /* Remove values captured in destructors */ idx = GC_FIRST_ROOT; current = GC_IDX2PTR(GC_FIRST_ROOT); while (idx != end) { if (GC_IS_GARBAGE(current->ref)) { p = GC_GET_PTR(current->ref); if (GC_REFCOUNT(p) > refcounts[idx]) { gc_remove_nested_data_from_buffer(p, current); } } current++; idx++; } pefree(refcounts, 1); if (GC_G(gc_protected)) { /* something went wrong */ return 0; } } /* Destroy zvals */ GC_TRACE("Destroying zvals"); GC_G(gc_protected) = 1; current = GC_IDX2PTR(GC_FIRST_ROOT); last = GC_IDX2PTR(GC_G(first_unused)); while (current != last) { if (GC_IS_GARBAGE(current->ref)) { p = GC_GET_PTR(current->ref); GC_TRACE_REF(p, "destroying"); if (GC_TYPE(p) == IS_OBJECT) { zend_object *obj = (zend_object*)p; EG(objects_store).object_buckets[obj->handle] = SET_OBJ_INVALID(obj); GC_TYPE_INFO(obj) = IS_NULL | (GC_TYPE_INFO(obj) & ~GC_TYPE_MASK); if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) { GC_ADD_FLAGS(obj, IS_OBJ_FREE_CALLED); GC_ADDREF(obj); obj->handlers->free_obj(obj); GC_DELREF(obj); } ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(obj->handle); current->ref = GC_MAKE_GARBAGE(((char*)obj) - obj->handlers->offset); } else if (GC_TYPE(p) == IS_ARRAY) { zend_array *arr = (zend_array*)p; GC_TYPE_INFO(arr) = IS_NULL | (GC_TYPE_INFO(arr) & ~GC_TYPE_MASK); /* GC may destroy arrays with rc>1. This is valid and safe. */ HT_ALLOW_COW_VIOLATION(arr); zend_hash_destroy(arr); } } current++; } /* Free objects */ current = GC_IDX2PTR(GC_FIRST_ROOT); while (current != last) { if (GC_IS_GARBAGE(current->ref)) { p = GC_GET_PTR(current->ref); GC_LINK_UNUSED(current); GC_G(num_roots)--; efree(p); } current++; } GC_TRACE("Collection finished"); GC_G(collected) += count; GC_G(gc_protected) = 0; GC_G(gc_active) = 0; } gc_compact(); return count; }
int gc_run(GRAPHICS_CONTROLLER *gc, gc_ctrl_e ctrl, uint32_t param, GC_NAV_CMDS *cmds) { int result = -1; if (cmds) { cmds->num_nav_cmds = 0; cmds->nav_cmds = NULL; cmds->sound_id_ref = -1; cmds->status = GC_STATUS_NONE; } if (!gc) { GC_TRACE("gc_run(): no graphics controller\n"); return result; } bd_mutex_lock(&gc->mutex); /* always accept reset */ switch (ctrl) { case GC_CTRL_RESET: _gc_reset(gc); bd_mutex_unlock(&gc->mutex); return 0; default:; } /* other operations require complete display set */ if (!gc->igs || !gc->igs->ics || !gc->igs->complete) { GC_TRACE("gc_run(): no interactive composition\n"); bd_mutex_unlock(&gc->mutex); return result; } switch (ctrl) { case GC_CTRL_SET_BUTTON_PAGE: _set_button_page(gc, param); break; case GC_CTRL_VK_KEY: if (param != BD_VK_POPUP) { result = _user_input(gc, param, cmds); break; } param = !gc->popup_visible; /* fall thru (BD_VK_POPUP) */ case GC_CTRL_POPUP: if (gc->igs->ics->interactive_composition.ui_model != IG_UI_MODEL_POPUP) { /* not pop-up menu */ break; } gc->popup_visible = !!param; if (gc->popup_visible) { _select_page(gc, 0); } /* fall thru */ case GC_CTRL_NOP: result = _render_page(gc, 0xffff, cmds); break; case GC_CTRL_INIT_MENU: _select_page(gc, 0); _render_page(gc, 0xffff, cmds); break; case GC_CTRL_IG_END: _update_selected_button(gc); _render_page(gc, 0xffff, cmds); break; case GC_CTRL_ENABLE_BUTTON: _enable_button(gc, param, 1); break; case GC_CTRL_DISABLE_BUTTON: _enable_button(gc, param, 0); break; case GC_CTRL_MOUSE_MOVE: result = _mouse_move(gc, param >> 16, param & 0xffff, cmds); break; case GC_CTRL_RESET: /* already handled */ break; } if (cmds) { if (gc->igs->ics->interactive_composition.ui_model == IG_UI_MODEL_POPUP) { cmds->status |= GC_STATUS_POPUP; } if (gc->ig_drawn) { cmds->status |= GC_STATUS_MENU_OPEN; } } bd_mutex_unlock(&gc->mutex); return result; }
static int _mouse_move(GRAPHICS_CONTROLLER *gc, unsigned x, unsigned y, GC_NAV_CMDS *cmds) { PG_DISPLAY_SET *s = gc->igs; BD_IG_PAGE *page = NULL; unsigned page_id = bd_psr_read(gc->regs, PSR_MENU_PAGE_ID); unsigned cur_btn_id = bd_psr_read(gc->regs, PSR_SELECTED_BUTTON_ID); unsigned new_btn_id = 0xffff; unsigned ii; gc->valid_mouse_position = 0; if (!gc->ig_drawn) { GC_TRACE("_mouse_move(): menu not visible\n"); return -1; } page = _find_page(&s->ics->interactive_composition, page_id); if (!page) { GC_ERROR("_mouse_move(): unknown page #%d (have %d pages)\n", page_id, s->ics->interactive_composition.num_pages); return -1; } for (ii = 0; ii < page->num_bogs; ii++) { BD_IG_BOG *bog = &page->bog[ii]; unsigned valid_id = gc->bog_data[ii].enabled_button; BD_IG_BUTTON *button = _find_button_bog(bog, valid_id); if (!button) continue; if (x < button->x_pos || y < button->y_pos) continue; /* Check for SELECTED state object (button that can be selected) */ BD_PG_OBJECT *object = _find_object_for_button(s, button, BTN_SELECTED, NULL); if (!object) continue; if (x >= button->x_pos + object->width || y >= button->y_pos + object->height) continue; /* mouse is over button */ gc->valid_mouse_position = 1; /* is button already selected? */ if (button->id == cur_btn_id) { return 1; } new_btn_id = button->id; if (cmds) { cmds->sound_id_ref = button->selected_sound_id_ref; } break; } if (new_btn_id != 0xffff) { _select_button(gc, new_btn_id); _render_page(gc, -1, cmds); } return gc->valid_mouse_position; }