static void putChangedKey(uint8_t xKeyidx, bool xIsDown, uint8_t xCol, uint8_t xRow){ applyKeyDownForFullLED(xKeyidx, xCol, xRow, xIsDown); // 빈 키코드는 LED 반응 이외의 기능 없음; if(xKeyidx == KEY_NONE ) return; // fn 키가 눌렸을 경우 해당 위치의 키는 무시한다. uint8_t gLayer, gKeyIndex, gFnIndex; if(getBeyondFN()) { gLayer = getBeyondFN(); }else{ gLayer = LAYER_NORMAL; } if(isFnPosition(xCol, xRow)) { // 현재 레이어에서 눌린 FN키가 듀얼 액션 키이면, 변경된 레이어의 키를 듀얼 액션 키로 강제 치환시켜서 진행 gKeyIndex = getCurrentKeyindex(gLayer, xRow, xCol); // fn key는 하나만 눌릴 수 있도록 처리; if(xIsDown) { // dual action key라면 FN을 추출; gFnIndex = getDualActionDownKeyIndexWhenIsCompounded(gKeyIndex, true); // DBG1(0x32, (uchar *)&gFnIndex, 1); setFnPressed(gFnIndex); } else { setFnPressed(KEY_NONE); clearFnPosition(); } IF_IS_DUAL_ACTION_KEY(gKeyIndex) { xKeyidx = gKeyIndex; } else { return; } }
static void putChangedKey(uint8_t xKeyidx, bool xIsDown, uint8_t xCol, uint8_t xRow){ applyKeyDownForFullLED(xKeyidx, xCol, xRow, xIsDown); // 빈 키코드는 LED 반응 이외의 기능 없음; if(xKeyidx == KEY_NONE ) return; // fn 키가 눌렸을 경우 해당 위치의 키는 무시한다. uint8_t gLayer, gKeyIndex, gFnIndex; gLayer = getCurrentFnLayer(); DBG1(0xC2, (uchar *)&gLayer, 1); if(isFnPosition(xCol, xRow) /* -> */ && (xIsDown || (!xIsDown && isFnPressed())) /* <- */) // 키 입력 동안 레이어 토글이 변경될 경우 FN 키와 같은 위치의 키들은 up 신호가 무시 되어 계속 눌려진 상태가 된다. 이를 패치. // 이 경우 fnPressed가 false 상태로 진행되므로 이를 확인 { // 현재 레이어에서 눌린 FN키가 듀얼 액션 키이면, 변경된 레이어의 키를 듀얼 액션 키로 강제 치환시켜서 진행 gKeyIndex = getCurrentKeyindex(gLayer, xRow, xCol); // fn key는 하나만 눌릴 수 있도록 처리; if(xIsDown) { // dual action key라면 FN을 추출; gFnIndex = getDualActionDownKeyIndexWhenIsCompounded(gKeyIndex, true); // DBG1(0x32, (uchar *)&gFnIndex, 1); setFnPressed(gFnIndex); } else { setFnPressed(KEY_NONE); clearFnPosition(); } IF_IS_DUAL_ACTION_KEY(gKeyIndex) { xKeyidx = gKeyIndex; } else { return;
// function that determine keymap // 0 = normal, 1 = fn, 2 = beyond_fn uint8_t getLayer(void) { uint8_t col, row, keyidx, cur, gLayer; /* 게으른 FN이 작동되는 상황 정리; - 첫키로 FN이 눌려야 한다. 이미 다른 키가 눌려있다면 작동 안 함; <- 불편할 수 있으므로 기본 레이어일 경우에는 다른 키들이 눌려져 있어도 FN이 작동하도록 한다. : - 작동이 된 후에는 모든 키가 release 되는 순간까지 layer를 유지 시킨다. (즉, 모든 키가 release 되고 1프레임 후에 작동 해제 되어야한다. ps2의 경우 제일 마지막 키의 release값을 처리해야하기 때문에.) */ if(_currentLazyLayer > 0) return _currentLazyLayer; gLayer= 0; // fn이 가장 우선, 다음 fn2 uint8_t *gMatrix = getCurrentMatrix(); for(row=0;row<ROWS;row++){ if(gMatrix[row] == 0) continue; for(col=0;col<COLUMNS;col++){ cur = gMatrix[row] & BV(col); if(cur){ keyidx = getCurrentKeyindex(_fnScanLayer, row, col); keyidx = getDualActionKeyWhenCompound(keyidx); // fn 키는 무조건 다운 액션을 적용; #ifdef DEBUG_QUICK_BOOTLOADER // for test if(col == 0 && row == 0){ wdt_enable(WDTO_15MS); while(1); } #endif // DEBUG_PRINT(("col= %d, row= %d keymap\n", col, row)); if(keyidx == KEY_FN){ gLayer = LAYER_FN; }else if(keyidx == KEY_FN2){ gLayer = LAYER_FN2; }else if(keyidx == KEY_FN3){ gLayer = LAYER_FN3; }else if(keyidx == KEY_NOR){ if(_fnScanLayer == LAYER_FN2){ // _fnScanLayer은 2를 유지하면서 스캔할 레이어는 0으로 반환; _isFnPressed = true; return LAYER_NORMAL; } } if(gLayer > 0){ // _fnScanLayer은 0을 유지하면서 스캔할 레이어는 1로 반환; if(isLazyFn()){ if(isReleaseAllPrev() || _isFnPressed == false){ _currentLazyLayer = gLayer; }else{ return _fnScanLayer; } } _isFnPressed = true; return gLayer; } } } } if(isBeyondFN()) { _fnScanLayer = isBeyondFN(); }else{ _fnScanLayer = LAYER_NORMAL; } _isFnPressed = false; return _fnScanLayer; }