HTREEITEM InsertNode(HWND hwndTV, HTREEITEM hItem, LPWSTR name) { WCHAR buf[MAX_NEW_KEY_LEN]; HTREEITEM hNewItem = 0; TVITEMEXW item; if (!hItem) hItem = (HTREEITEM)SendMessageW(hwndTV, TVM_GETNEXTITEM, TVGN_CARET, 0); if (!hItem) return FALSE; if (SendMessageW(hwndTV, TVM_GETITEMSTATE, (WPARAM)hItem, TVIS_EXPANDEDONCE) & TVIS_EXPANDEDONCE) { hNewItem = AddEntryToTree(hwndTV, hItem, name, 0, 0); } else { item.mask = TVIF_CHILDREN | TVIF_HANDLE; item.hItem = hItem; if (!TreeView_GetItemW(hwndTV, &item)) return FALSE; item.cChildren = 1; if (!TreeView_SetItemW(hwndTV, &item)) return FALSE; } SendMessageW(hwndTV, TVM_EXPAND, TVE_EXPAND, (LPARAM)hItem ); if (!hNewItem) { for(hNewItem = (HTREEITEM)SendMessageW(hwndTV, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem); hNewItem; hNewItem = (HTREEITEM)SendMessageW(hwndTV, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hNewItem)) { item.mask = TVIF_HANDLE | TVIF_TEXT; item.hItem = hNewItem; item.pszText = buf; item.cchTextMax = COUNT_OF(buf); if (!TreeView_GetItemW(hwndTV, &item)) continue; if (lstrcmpW(name, item.pszText) == 0) break; } } if (hNewItem) SendMessageW(hwndTV, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hNewItem); return hNewItem; }
/*********************************************************************** * UPDOWN_GetBuddyInt * Tries to read the pos from the buddy window and if it succeeds, * it stores it in the control's CurVal * returns: * TRUE - if it read the integer from the buddy successfully * FALSE - if an error occurred */ static BOOL UPDOWN_GetBuddyInt (UPDOWN_INFO *infoPtr) { WCHAR txt[20], sep, *src, *dst; int newVal; if (!((infoPtr->Flags & FLAG_BUDDYINT) && IsWindow(infoPtr->Buddy))) return FALSE; /*if the buddy is a list window, we must set curr index */ if (UPDOWN_IsBuddyListbox(infoPtr)) { newVal = SendMessageW(infoPtr->Buddy, LB_GETCARETINDEX, 0, 0); if(newVal < 0) return FALSE; } else { /* we have a regular window, so will get the text */ /* note that a zero-length string is a legitimate value for 'txt', * and ought to result in a successful conversion to '0'. */ if (GetWindowTextW(infoPtr->Buddy, txt, COUNT_OF(txt)) < 0) return FALSE; sep = UPDOWN_GetThousandSep(); /* now get rid of the separators */ for(src = dst = txt; *src; src++) if(*src != sep) *dst++ = *src; *dst = 0; /* try to convert the number and validate it */ newVal = strtolW(txt, &src, infoPtr->Base); if(*src || !UPDOWN_InBounds (infoPtr, newVal)) return FALSE; } TRACE("new value(%d) from buddy (old=%d)\n", newVal, infoPtr->CurVal); infoPtr->CurVal = newVal; return TRUE; }
/* * Main Loop */ int main() { LOG("--------------------------------\r\n"); /* Unmask interrupt for output compare match A on TC0 */ timers_setup_timer(TIMER_COUNTER0, TIMER_MODE_CTC, 1000UL); TIMSK0 |= (1 << OCIE0A); lcd_load_custom_character(degree_symbol, CUSTOM_SYMBOL_DEGREE); cli_init(); motor_init(&g_timers_state); log_init(); scheduler_init(&g_timers_state, g_tasks, COUNT_OF(g_tasks)); interpolator_init(&g_timers_state); sei(); log_start(); /* Main Loop: Run Tasks scheduled by scheduler */ while (1) { int i; for (i = 0; i < 50; i++) { serial_check(); /* needs to be called frequently */ } scheduler_service(); } }
static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME* pofn) { FILTERPAIR FilterPairs[4]; static WCHAR Filter[1024]; memset(pofn, 0, sizeof(OPENFILENAME)); pofn->lStructSize = sizeof(OPENFILENAME); pofn->hwndOwner = hWnd; pofn->hInstance = hInst; /* create filter string */ FilterPairs[0].DisplayID = IDS_FLT_REGFILES; FilterPairs[0].FilterID = IDS_FLT_REGFILES_FLT; FilterPairs[1].DisplayID = IDS_FLT_HIVFILES; FilterPairs[1].FilterID = IDS_FLT_HIVFILES_FLT; FilterPairs[2].DisplayID = IDS_FLT_REGEDIT4; FilterPairs[2].FilterID = IDS_FLT_REGEDIT4_FLT; FilterPairs[3].DisplayID = IDS_FLT_ALLFILES; FilterPairs[3].FilterID = IDS_FLT_ALLFILES_FLT; BuildFilterStrings(Filter, FilterPairs, COUNT_OF(FilterPairs)); pofn->lpstrFilter = Filter; pofn->lpstrFile = FileNameBuffer; pofn->nMaxFile = _MAX_PATH; pofn->lpstrFileTitle = FileTitleBuffer; pofn->nMaxFileTitle = _MAX_PATH; pofn->Flags = OFN_HIDEREADONLY; pofn->lpstrDefExt = L"reg"; return TRUE; }
BOOL CopyKeyName(HWND hWnd, HKEY hRootKey, LPCWSTR keyName) { BOOL bClipboardOpened = FALSE; BOOL bSuccess = FALSE; WCHAR szBuffer[512]; HGLOBAL hGlobal; LPWSTR s; if (!OpenClipboard(hWnd)) goto done; bClipboardOpened = TRUE; if (!EmptyClipboard()) goto done; if (!GetKeyName(szBuffer, COUNT_OF(szBuffer), hRootKey, keyName)) goto done; hGlobal = GlobalAlloc(GMEM_MOVEABLE, (wcslen(szBuffer) + 1) * sizeof(WCHAR)); if (!hGlobal) goto done; s = GlobalLock(hGlobal); wcscpy(s, szBuffer); GlobalUnlock(hGlobal); SetClipboardData(CF_UNICODETEXT, hGlobal); bSuccess = TRUE; done: if (bClipboardOpened) CloseClipboard(); return bSuccess; }
void showstatus(FILE *f, struct guest_thread *vm_thread) { struct vm_trapframe *vm_tf = &(vm_thread->uthread.u_ctx.tf.vm_tf); int shutdown = vm_tf->tf_exit_reason; char *when = shutdown & VMX_EXIT_REASONS_FAILED_VMENTRY ? "entry" : "exit"; shutdown &= ~VMX_EXIT_REASONS_FAILED_VMENTRY; char *reason = "UNKNOWN"; if (shutdown < COUNT_OF(vmxexit) && vmxexit[shutdown]) reason = vmxexit[shutdown]; fprintf(f, "Shutdown: core %d, %s due to %s(0x%x); ret code 0x%x\n", vm_tf->tf_guest_pcoreid, when, reason, shutdown, vm_tf->tf_exit_reason); fprintf(f, " gva %p gpa %p cr3 %p\n", (void *)vm_tf->tf_guest_va, (void *)vm_tf->tf_guest_pa, (void *)vm_tf->tf_cr3); fprintf(f, " rax 0x%016lx\n", vm_tf->tf_rax); fprintf(f, " rbx 0x%016lx\n", vm_tf->tf_rbx); fprintf(f, " rcx 0x%016lx\n", vm_tf->tf_rcx); fprintf(f, " rdx 0x%016lx\n", vm_tf->tf_rdx); fprintf(f, " rbp 0x%016lx\n", vm_tf->tf_rbp); fprintf(f, " rsi 0x%016lx\n", vm_tf->tf_rsi); fprintf(f, " rdi 0x%016lx\n", vm_tf->tf_rdi); fprintf(f, " r8 0x%016lx\n", vm_tf->tf_r8); fprintf(f, " r9 0x%016lx\n", vm_tf->tf_r9); fprintf(f, " r10 0x%016lx\n", vm_tf->tf_r10); fprintf(f, " r11 0x%016lx\n", vm_tf->tf_r11); fprintf(f, " r12 0x%016lx\n", vm_tf->tf_r12); fprintf(f, " r13 0x%016lx\n", vm_tf->tf_r13); fprintf(f, " r14 0x%016lx\n", vm_tf->tf_r14); fprintf(f, " r15 0x%016lx\n", vm_tf->tf_r15); }
static BOOL UnloadHive(HWND hWnd) { WCHAR Caption[128]; LPCWSTR pszKeyPath; HKEY hRootKey; LONG regUnloadResult; /* get the item key to unload */ pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey); /* load and set the caption and flags for dialog */ LoadStringW(hInst, IDS_UNLOAD_HIVE, Caption, COUNT_OF(Caption)); /* Enable the 'restore' privilege, unload the hive, disable the privilege */ EnablePrivilege(SE_RESTORE_NAME, NULL, TRUE); regUnloadResult = RegUnLoadKeyW(hRootKey, pszKeyPath); EnablePrivilege(SE_RESTORE_NAME, NULL, FALSE); if(regUnloadResult == ERROR_SUCCESS) { /* refresh tree and list views */ RefreshTreeView(g_pChildWnd->hTreeWnd); pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey); RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath); } else { ErrorMessageBox(hWnd, Caption, regUnloadResult); return FALSE; } return TRUE; }
void toencounter(DW o) { if (encounterList.n >= COUNT_OF(encounterList.x)) { DLOG("encounter list overflow: %i",encounterList.n); crash(); } else { encounterList.x[encounterList.n++] = o; } }
/* Format Timestamp from EventLog */ WCHAR * WinEventTimeToString(ULONGLONG ulongTime) { SYSTEMTIME sysTime; FILETIME fTime, lfTime; ULARGE_INTEGER ulargeTime; struct tm tm_struct; WCHAR result[17] = L""; static WCHAR formatted_result[] = L"Mmm dd hh:mm:ss"; memset(&tm_struct, 0, sizeof(tm_struct)); /* Convert from ULONGLONG to usable FILETIME value */ ulargeTime.QuadPart = ulongTime; fTime.dwLowDateTime = ulargeTime.LowPart; fTime.dwHighDateTime = ulargeTime.HighPart; /* Adjust time value to reflect current timezone */ /* then convert to a SYSTEMTIME */ if (FileTimeToLocalFileTime(&fTime, &lfTime) == 0) { Log(LOG_ERROR|LOG_SYS,"Error formatting event time to local time"); return NULL; } if (FileTimeToSystemTime(&lfTime, &sysTime) == 0) { Log(LOG_ERROR|LOG_SYS,"Error formatting event time to system time"); return NULL; } /* Convert SYSTEMTIME to tm */ tm_struct.tm_year = sysTime.wYear - 1900; tm_struct.tm_mon = sysTime.wMonth - 1; tm_struct.tm_mday = sysTime.wDay; tm_struct.tm_hour = sysTime.wHour; tm_struct.tm_wday = sysTime.wDayOfWeek; tm_struct.tm_min = sysTime.wMinute; tm_struct.tm_sec = sysTime.wSecond; /* Format timestamp string */ wcsftime(result, COUNT_OF(result), L"%b %d %H:%M:%S", &tm_struct); if (result[4] == L'0') /* Replace leading zero with a space for */ result[4] = L' '; /* single digit days so we comply with the RFC */ wcsncpy_s(formatted_result, COUNT_OF(L"Mmm dd hh:mm:ss"), result, _TRUNCATE); return formatted_result; }
/* Creates a child process for exe, and shares the parent's standard FDs (stdin, * stdout, stderr) with the child. Returns the child's PID on success, -1 o/w. */ pid_t create_child_with_stdfds(const char *exe, int argc, char *const argv[], char *const envp[]) { struct childfdmap fd_dups[3] = { {0, 0}, {1, 1}, {2, 2} }; pid_t kid; int ret; kid = create_child(exe, argc, argv, envp); if (kid < 0) return -1; ret = syscall(SYS_dup_fds_to, kid, fd_dups, COUNT_OF(fd_dups)); if (ret != COUNT_OF(fd_dups)) { sys_proc_destroy(kid, -1); return -1; } return kid; }
DeviceId toDeviceId(DeviceIndex device) { if (device < 0 || (unsigned)device > COUNT_OF(deviceTable)) { errno = EINVAL; return -1; } return deviceTable[device]->id; }
static HRESULT InitializeRemoteRegistryPicker(OUT IDsObjectPicker **pDsObjectPicker) { HRESULT hRet; *pDsObjectPicker = NULL; hRet = CoCreateInstance(&CLSID_DsObjectPicker, NULL, CLSCTX_INPROC_SERVER, &IID_IDsObjectPicker, (LPVOID*)pDsObjectPicker); if (SUCCEEDED(hRet)) { DSOP_INIT_INFO InitInfo; static DSOP_SCOPE_INIT_INFO Scopes[] = { { sizeof(DSOP_SCOPE_INIT_INFO), DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE | DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE | DSOP_SCOPE_TYPE_GLOBAL_CATALOG | DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN | DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN | DSOP_SCOPE_TYPE_WORKGROUP | DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN, 0, { { DSOP_FILTER_COMPUTERS, 0, 0 }, DSOP_DOWNLEVEL_FILTER_COMPUTERS }, NULL, NULL, S_OK }, }; InitInfo.cbSize = sizeof(InitInfo); InitInfo.pwzTargetComputer = NULL; InitInfo.cDsScopeInfos = COUNT_OF(Scopes); InitInfo.aDsScopeInfos = Scopes; InitInfo.flOptions = 0; InitInfo.cAttributesToFetch = 0; InitInfo.apwzAttributeNames = NULL; hRet = (*pDsObjectPicker)->lpVtbl->Initialize(*pDsObjectPicker, &InitInfo); if (FAILED(hRet)) { /* delete the object picker in case initialization failed! */ (*pDsObjectPicker)->lpVtbl->Release(*pDsObjectPicker); } } return hRet; }
DemuxTable::DemuxTable() { int i = 0; int count = COUNT_OF(table_); while (i++ < count) { table_[i].handler_ = NULL; } }
bool CreateShaders() { // Load the shaders and get a linked program object const char * srcs_color_vertex[] = { ZLGLSL_LIST_LOW_PRECISION_HEADER baseattribs_vertex_shader_src, color_vertex_shader_src }; const char * srcs_color_fragment[] = { ZLGLSL_LIST_LOW_PRECISION_HEADER baseattribs_fragment_shader_src, color_fragment_shader_src }; const char * const attr_color[] = { "a_position", "a_color" }; if (!(_COLOR_PROGRAM = CreateProgramFromVertexAndFragmentShaders(COUNT_OF(srcs_color_vertex), srcs_color_vertex, COUNT_OF(srcs_color_fragment), srcs_color_fragment, COUNT_OF(attr_color), attr_color))) return false; COLOR_UNI_MVP = (GLuint)glGetUniformLocation(_COLOR_PROGRAM, "u_mvpMatrix"); // Load the shaders and get a linked program object const char * const attr_texture[] = { "a_position", "a_color", "a_texcoord" }; if (!(_TEXTURE_PROGRAM = CreateProgramFromVertexAndFragmentShaders(COUNT_OF(srcs_texture_vertex), srcs_texture_vertex, COUNT_OF(srcs_texture_fragment), srcs_texture_fragment, COUNT_OF(attr_texture), attr_texture))) return false; TEXTURE_UNI_MVP = (GLuint)glGetUniformLocation(_TEXTURE_PROGRAM, "u_mvpMatrix"); glEnableVertexAttribArrayUnbuffered(0); //0 = POSITION = always required return true; }
static int decode_codon(char codon) { for (int i = 0; i < COUNT_OF(kCodonMatrix); i++) { if (kCodonMatrix[i].code == codon) return i; } return -1; }
static int decode_amino(char amino) { for (int i = 0; i < COUNT_OF(kAminoMatrix); i++) { if (kAminoMatrix[i].code == amino) return i; } return -1; }
static s8 modem_signal_strength_to_dbm(u32 signal_raw) { s8 signal_dbm = 0; // unknown will remain 0 if (signal_raw < (s8)COUNT_OF(signal_to_dbm_lookup)) { signal_dbm = signal_to_dbm_lookup[signal_raw]; } return signal_dbm; }
/* assumes presence of the global device table */ DeviceIndex fromDeviceId(DeviceId id) { for (unsigned i = 0; i < COUNT_OF(deviceTable); i++) { if (deviceTable[i]->id == id) return i; } errno = ENODEV; return -1; }
/* * Initialize the button clocks. And configure the buttons. */ static void initButtons(void) { static const Button buttons[] = { Button1, Button2 }; SIM_SCGC5 |= (SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK); /* clock port D & E */ for (unsigned i = 0; i < COUNT_OF(buttons); i++) { makeGPIOIn(buttons[i]); } }
static const NsEntry* lookup_ns_entry(const char *prefix, int len) { int i; for (i = 0; i < COUNT_OF(ns_entries); i++) { if (xmlStrncmp(BAD_CAST prefix, ns_entries[i].prefix, len) == 0) return &ns_entries[i]; } return NULL; }
static float modem_error_rate_to_percent(u32 error_raw) { float error_percent = 0.0; // unknown will remain 0 if (error_raw < (u32)COUNT_OF(error_to_percent_lookup)) { error_percent = error_to_percent_lookup[error_raw]; } return error_percent; }
/* * generic query lookup. The query is of one of the following * forms: * * attr1=val1 attr2=val2 attr3=val3 ... * * returns the matching tuple * * ipinfo attr=val attr1 attr2 attr3 ... * * is like ipinfo and returns the attr{1-n} * associated with the ip address. */ static char *genquery(struct mfile *mf, char *query) { int i, n; char *p; char *attr[Maxattr]; char *val[Maxattr]; struct ndbtuple *t; struct ndbs s; n = getfields(query, attr, COUNT_OF(attr), 1, " "); if (n == 0) return "bad query"; if (strcmp(attr[0], "ipinfo") == 0) return ipinfoquery(mf, attr, n); /* parse pairs */ for (i = 0; i < n; i++) { p = strchr(attr[i], '='); if (p == 0) return "bad query"; *p++ = 0; val[i] = p; } /* give dns a chance */ if ((strcmp(attr[0], "dom") == 0 || strcmp(attr[0], "ip") == 0) && val[0]) { t = dnsiplookup(val[0], &s); if (t) { if (qmatch(t, attr, val, n)) { qreply(mf, t); ndbfree(t); return 0; } ndbfree(t); } } /* first pair is always the key. It can't be a '*' */ t = ndbsearch(db, &s, attr[0], val[0]); /* search is the and of all the pairs */ while (t) { if (qmatch(t, attr, val, n)) { qreply(mf, t); ndbfree(t); return 0; } ndbfree(t); t = ndbsnext(&s, attr[0], val[0]); } return "no match"; }
static BOOL LoadHive(HWND hWnd) { OPENFILENAME ofn; WCHAR Caption[128]; LPCWSTR pszKeyPath; WCHAR xPath[LOADHIVE_KEYNAMELENGTH]; HKEY hRootKey; WCHAR Filter[1024]; FILTERPAIR filter; /* get the item key to load the hive in */ pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey); /* initialize the "open file" dialog */ InitOpenFileName(hWnd, &ofn); /* build the "All Files" filter up */ filter.DisplayID = IDS_FLT_ALLFILES; filter.FilterID = IDS_FLT_ALLFILES_FLT; BuildFilterStrings(Filter, &filter, 1); ofn.lpstrFilter = Filter; /* load and set the caption and flags for dialog */ LoadStringW(hInst, IDS_LOAD_HIVE, Caption, COUNT_OF(Caption)); ofn.lpstrTitle = Caption; ofn.Flags |= OFN_ENABLESIZING; /* ofn.lCustData = ;*/ /* now load the hive */ if (GetOpenFileName(&ofn)) { if (DialogBoxParamW(hInst, MAKEINTRESOURCEW(IDD_LOADHIVE), hWnd, &LoadHive_KeyNameInHookProc, (LPARAM)xPath)) { LONG regLoadResult; /* Enable the 'restore' privilege, load the hive, disable the privilege */ EnablePrivilege(SE_RESTORE_NAME, NULL, TRUE); regLoadResult = RegLoadKeyW(hRootKey, xPath, ofn.lpstrFile); EnablePrivilege(SE_RESTORE_NAME, NULL, FALSE); if(regLoadResult == ERROR_SUCCESS) { /* refresh tree and list views */ RefreshTreeView(g_pChildWnd->hTreeWnd); pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey); RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath); } else { ErrorMessageBox(hWnd, Caption, regLoadResult); return FALSE; } } } else { CheckCommDlgError(hWnd); } return TRUE; }
OutputHandlerFunction GetOutputHandler(uint8_t channel) { if (channel >= COUNT_OF(OutputHandlerVector)) return NULL; #ifdef CAYENNE_USING_PROGMEM return (OutputHandlerFunction)pgm_read_word(&OutputHandlerVector[channel]); #else return OutputHandlerVector[channel]; #endif }
bool arcan_event_blacklisted(const char* idstr) { /* idstr comes from a trusted context, won't exceed stack size */ char buf[strlen(idstr) + sizeof("bl_")]; snprintf(buf, COUNT_OF(buf), "bl_%s", idstr); char* res = arcan_db_appl_val(dbhandle, ARCAN_TBL, "bl_"); bool rv = res && strcmp(res, "block") == 0; arcan_mem_free(res); return rv; }
WidgetWriteHandler GetWriteHandler(uint8_t pin) { if (pin >= COUNT_OF(BlynkWriteHandlerVector)) return NULL; #ifdef BLYNK_HAS_PROGMEM return (WidgetWriteHandler)pgm_read_word(&BlynkWriteHandlerVector[pin]); #else return BlynkWriteHandlerVector[pin]; #endif }
void Button_Init(void (*pButton_StateChanged) (uint8_t buttonNumber, ButtonState buttonState)) { Button_StateChanged = pButton_StateChanged; for (uint8_t index = 0x00; index < COUNT_OF(Buttons); index++) { #ifdef __AVR__ Button_SingleInit(Buttons[index]->pinPort); #endif } }
void CDispatch::execute (const xl::tstring &command, CPoint ptCur) { const xl::tchar *cmd = command.c_str(); // 1. try CMainWindow command for (int i = 0; i < COUNT_OF(sMainWindowCmdMap); ++ i) { if (_tcsicmp(cmd, sMainWindowCmdMap[i].command.c_str()) == 0) { (m_pMainWindow->*(sMainWindowCmdMap[i].func))(); return; } } // 2. try CImageView command for (int i = 0; i < COUNT_OF(sImageViewCmdMap); ++ i) { if (_tcsicmp(cmd, sImageViewCmdMap[i].command.c_str()) == 0) { (m_pView->*(sImageViewCmdMap[i].func))(ptCur); return; } } }
void Win32_Raytrace_Work_Queue::add_entry(Raytrace_Work_Entry entry) { u32 new_next_entry_to_add = (this->next_entry_to_add + 1) % COUNT_OF(this->entries); assert(new_next_entry_to_add != this->next_entry_to_do); Raytrace_Work_Entry *entry_to_add = this->entries + this->next_entry_to_add; *entry_to_add = entry; _WriteBarrier(); this->next_entry_to_add = new_next_entry_to_add; ReleaseSemaphore(this->semaphore, 1, 0); }
WidgetReadHandler GetReadHandler(unsigned pin) { if (pin >= COUNT_OF(BlynkReadHandlerVector)) return NULL; #ifdef BLYNK_HAS_PROGMEM return (WidgetReadHandler)pgm_read_word(&BlynkReadHandlerVector[pin]); #else return BlynkReadHandlerVector[pin]; #endif }