22 1 6 : 오토마타 수정

드디어 회사를 나왔다. 이제 충분히 연구할 시간이 주어졌지만 좀 쉬기도 해야 하고 급하게 처리할 다른 일도 있어 키보드 작업은 시작하지 않았다. 이번 쉬는 동안 최소한 특허는 내 놓고 다른 일을 해야겠다.

오늘 MS 스컬프트 키보드를 중고로 하나 구입해서 좀 써 봤는데 인체공학이라는 키보드가 기대만큼 편리하지 않고 인체 공학적이지도 않다. 이렇게 크고 둔탁해서는 효율이 나오지 않을 거 같다. ㅠ자가 왼쪽에 있다는 것과 스페이스가 엄지 끝에 걸린다는 점이 특히 문제이다. 이 키보드를 써 보고는 최소한 이보다는 더 좋게 만들 수 있을 거 같아 빨리 내 키보드를 만들어야겠다는 생각이 들었다.

SBS에서 한 프로중 우연히 달인을 봤는데 왼손이 없는 장애인이 오른손의 새끼, 검지 두 개의 손가락만으로 연습을 해서 분당 760타를 친다는거다. 연습에 의한 효율 향상이 어디까지인지 참 놀랍고 이런 사람을 위해서라도 빨리 키보드를 만들어야겠다. 양손으로 제자리에서 빨리 칠 수 있음은 물론이고 한손으로 불편없이 쓸 수 있는 키보드였으면 좋겠다.

오늘은 문득 키 개수를 더 줄이는 방법을 생각해 봤다. 손가락 두 개로도 칠 정도이면 키 개수가 그렇게까지 많을 필요는 없을 거 같다. 그리고 영문에 대해 통계를 뽑아 봤듯이 한글에 대해서도 그럴 필요가 있다. 이를 위해 문자 목록을 다음과 같이 선정했다.

 

자음 : ㄱㄴㄷㄹㅁㅂㅅㅇㅈㅎ + 된소리, 쎈소리 = 10

모음 : ㅏㅓㅗㅜㅡㅣㅐㅔ = 8

 

ㄱㄷㅂㅈㅅ에 대해서는 누른 후 된소리키를 누르면 ㄲㄸㅃㅆㅉ으로 바꾸고 ㄱㄷㅂㅈ에 대 쎈소리키를 누르면 ㅋㅌㅍㅊ으로 바꾸는 것이다. 자음을 분해하여 키를 아끼는 작전인데 이대로 하면 딱 18개로 기호를 빼고 정확하게 현재 키 숫자와 맞아 떨어진다. Shift를 누를 필요도 없고 집안열로 손가락을 이동시킬 필요도 없다. 초안 배치를 대충 잡아 보면 다음과 같은 모양이 된다. 오른쪽은 똑같고 왼쪽만 달라진다.

, 쎈 키는 연타 방지를 위해 조합 자음과는 손가락이 겹치지 않도록 배치했다. 그런데 이렇게 보면 된소리는 Shift를 엄지로 누르고 자음을 누르는 것과 편의성이 비슷해 별 차이가 없지 않나 싶다. 다만 Shift는 누른 채로이지만 된소리키는 연속으로 누르면 되니 감이 좀 다르기는 하다. 자판안에 문자 입력을 위한 모든 키가 포함되어 있다는 면에서도 합당하다.

또 자음을 연속으로 두 번 입력할 때의 문제점만 해결하면 이 키도 굳이 필요치 않다. 동백꽃, 햇쌀, 앗싸 처럼 같은 자음 셋이 이어질 때 어느쪽이 쌍자음인지 결정해야 다른 자음이라도 여러 가지 형태로 해석할 위험이 있다.

 

앗사 : 앗사, 아싸

말씀 : 말씀, 맔슴

첫번째 : 첫번째, 첫벉재

 

07 8 27일자에 이 부분에 대해 연구해 둔게 있는데 결론적으로는 별도키없이 연타만으로 쌍자음을 입력할 수는 없다. 현재로서는 된소리키가 따로 있거나 아니면 Shift키로 된소리임을 입력자가 분명히 밝히는 수밖에 없다.

쎈소리는 앞에 ㅎ을 써서 표기하기도 한다. 그러나 "이렇게"를 칠 때 이러케일지와 구분할 수 없어 ㅎ키를 쎈소리 선두 문자로 쓰기는 어려울 것 같다. 이 문자 구성에서 랭킹을 매기면 18! = 6400조개의 조합이 나온다. 이 중 두 개의 키만 고정해도 20조개로 줄어들어 금방 랭킹을 매겨볼 수 있다. 좌우가 자음, 모음으로 분명히 나누어져 있으니 각각 따로 랭킹을 매겨도 될 거 같다. 영문과는 달리 좌자우모의 원칙이 있어 채점 대상이 다르다.

 

채점 대상 : 부담도, 손가락연타율, 손가락 비율, 행비율

제외 대상 : 좌우비율, 손연타율, 연철

 

이 방안에 대해 좀 더 생각해 보고 영문과 마찬가지로 랭킹을 한번 돌려 봐야겠다. 영문 랭킹은 앞서 조사해 둔 dist5 정도면 충분하니 한글만 배치하면 대충 특허 제출 정도는 가능할 거 같다.

아이디어는 연구해볼만한 대상이기는 한데 명칭이 좀 문제다. 된소리는 경음, 거센소리는 격음이라고 하는데 키에다 이렇게 새길 수는 없다. 쌍자음과 쎈소리의 정식명칭이 뭔지 조사해 봤다. 키의 이름을 결정하고 그 위에 캡션을 붙여야 하는데 직관적인 이름을 붙이기 참 어렵다.

같은 글자를 두 번쓰는 것을 병서라고 하며 같은 걸 두 번 쓰면 각자병서라고하는데 ㄲ, , , , ㅃ 등이다. 다른걸 두번쓰면 합용병서라고 하는데 ㅄ, , ㄺ 이런 것이다. 아래한글이나 애플 입력기는 단어 처음에는 연타로 쌍자음을 만들 수 있다고 하는데 해 보니 진짜 된다.

,,,ㅍ은 거센소리라고 한다. 한자로는 격음이라고 부르며 파열음에 h가 따라 붙는 발음이며 유기음이라고도 한다. 예사소리 ㅅ에 대응하는 거센소리는 없는데 옛글인 세모라는 주장도 있는 모양이다. 이 두 키의 이름에 대해 여러 가지 고민을 해 봤는데 후보는 다음과 같다.

 

, : 대표글자로 표기. 가장 직관적이며 기존 글자와 비슷해 이질적이지 않다.

, : 설명적이나 키캡에 인쇄하면 번잡해 보인다.

ㅁㅁ, - : 사각 기호로 반복 및 획추가 표시. 표시는 무난한데 부르기 애매함

: : 가로 두 점으로 반복 표시, 세로 두 점으로 획추가. 콜론이랑 헷갈림

: 쌍자음은 직관적이지만 쎈소리는 이게 뭥미?

W, F : 반복이나 획추가를 표현하는 알파벳. 진짜 알파벳키랑 헷갈려 안됨

∬∮ 또는 ∞∝: 수학기호로도 그럭 저럭 표현은 가능

 

새로운 개념에 대해 정확한 명칭을 붙이는 것은 참 어려운 일이다. 앞으로도 더 생각해 봐야겠지만 일단은 가장 무난해 보이는 ㄲ, ㅋ으로 표기하고 부를 때는 쌍음, 쎈음키 등으로 부르기로 한다.

----------------

1 10 - 영문배치 평가 및 한글 빈도 측증

영문 랭킹을 다 산출해 놓고도 아직 평가도 못해 봤다. 과연 제대로 된 건지 검증해 보자. 작년에 매긴 dist5의 영문 랭킹은 다음과 같다. dist4의 랭킹 결과도 빨간색으로 같이 표시해 두었는데 보다시피 변화가 그리 많지는 않다. 쿼티와 비교해 보면 w p만 빼고 모두 자리가 바뀌었다.

h, l, d 세 글자가 각각 자리를 바꾸었고 p g가 교체된 정도 뿐이다. 서로 교환한 글자끼리는 빈도가 비슷해서 변화는 미세하다. 2행은 하나도 바뀌지 않았고 모음이 모두 오른쪽에 있는 점도 같다. 점수상의 차이점은 다음과 같다.

 

dist4 : 감점 23.83,좌우 51:49, 18:21:27:33-44:26:21:6 29:57:15 지연 6.97% 손연 35%

dist5 : 감점 22.86,좌우 50:50, 18:21:25:35-43:28:21:6 29:57:15 지연 7.98% 손연 34%

 

좌우 분담율이 절반에 가깝고 왼중지 부담이 집게로 약간 전가되었고 지연타는 약간 늘어도 손연타가 조금 줄었다. 이 정도면 거의 차이가 없는 거나 마찬가지이며 dist6를 더 돌려 봐야 별 진전도 없을 거 같다.

이 배치가 과연 영문 타이핑이 적합한지 일단 그림만 보고 연습을 좀 해 봤는데 대충 괜찮은 거 같다. 아무래도 진짜 치는게 아니다 보니 느낌이 좀 없는 편인데 실제 쳐 보기 위해 AnerimExercise 프로그램의 문자표를 수정했다. 일전에 구조를 조금 정리해 놓아 배치를 수정하는 것은 어렵지 않았다.

Yesterday 가사를 쳐 봤는데 그럭 저럭 칠만하다. 자리만 대충 연습한 후 처음 쳐 본 결과 총 116타에 2 40초 정도, 분당 41타가 나왔다. 조금 더 연습한 후 다시 해 보니 1 58, 분당 58타가 나왔다. 대충만 연습해도 분당 100타는 금방 넘을 거 같기는 하다. Esc 누르고 치기 시작하면 시간과 타수까지 계산해 주는데 이런 기능은 참 잘 만들어 놓은 거 같다.

아직 배치에 익숙하지 않아서이긴 한데 의외로 쿼티랑 좀 헷갈린다. 특히 S가 한자리 옆이라 자꾸 실수를 한다. 또한 화면의 키보드를 보고 해도 집안열 때문에 검지와 중지 자리가 헷갈리는 면이 있고 키가 기울어진 정도가 달라 이 점도 헷갈린다. 실제 키보드가 있어야 좀 연습해 볼만할 거 같다. 그나마 대타로 터치 노트북을 사용해 봤다. 원래 이럴려고 산 노트북인데 이제서야 활용해 본다.

이렇게 연습해 보려고 키보드의 확대 배율까지 조정할 수 있도록 해 두었는데 FHD 해상도에 180% 비율이면 대략 키피치 18미리 정도 나오니 적당하다. 이걸로 연습하면 기울기나 공백, 엔터 등이 제자리에 있어 좀 실감은 난다. 그러나 이건 또 다른 단점이 있는데 키보드위에 손가락을 올려 놓을 수 없고 공중에 붕 떠 있어야 한다.

멀티 터치를 고려하지 않아 두 키를 한꺼번에 누를 수 없으며 실제 키를 만지는게 아니기 때문에 치다 보면 자리를 자꾸 벗어난다. 또한 손톱으로는 터치가 안되어 3행을 구부려 칠 수 없다. 이 화면을 쓰려면 손톱을 짧게 잘라야 하며 아랫열을 터치할 때 손가락 바닥이 닿도록 신경써야 한다. 보조적인 테스트 용도로는 쓸 수 있지만 이 배열이 과연 효율적인지 점검하기에는 적합하지 않다.

터치로 연습을 좀 해 본 결과 분당 54타까지는 나온다. 배열까지 제대로 갖춰서 연습해 보려면 결국 원하는 배열의 실물 키보드가 있어야 한다. 키피치도 맞추고 손의 각도까지 다 기울인 상태로 시제품을 만들어 봐야 진짜 입력할만한지 알 수 있을 거 같다.

대충 쳐 본 결과 배치는 그럭 저럭 괜찮아 보인다. in, to, as, is 같은 글자의 연타가 별로 없고 좌우 골고루 나누어지며 모음이 오른쪽에 몰려 있는 것도 좀 쉬운 것 같다. 그리고 확실히 2행 빈도가 높다 보니 위나 아래로 이동할 일이 별로 없고 v, k만 가끔 나올 뿐 jxqz가 나오지 않아 손이 편안하다.

--------------------

영문 랭킹은 그럭저럭 된 거 같고 이제 한글 랭킹을 매겨야 한다. 한글 빈도수는 조사되어 있지만 오토마타가 바뀌면 키의 빈도가 바뀐다. 문자의 빈도가 아닌 키의 빈도를 조사해야 한다. , 쎈키를 도입했을 때의 키 빈도 초안은 다음과 같다. 12 3월에 조사한 빈도로부터 12개키의 빈도를 대충 조사했다.

 

9.77

7.24

6.23

5.76

4.64

4.22

3.41

2.85

2.29

쌍자음

2.26

2.16

거친

1.81

 

이 빈도는 모음까지 같이 고려한 것이고 ㅄ, , ㄺ 등의 복자음받침까지는 고려하지 않은 것이다. 결국 통계를 다시 작성해야 한다는 얘기인데 자음과 모음의 통계를 따로 내는게 좋을지 아니면 통합해서 백분율로 내야 할지가 고민이다. 어차피 상대적 빈도가 중요하니 그냥 통째로 같이 내도록 하자.

오토마타까지 수정해서 통계를 내려면 프로그램을 새로 짜야 한다. 이 코드를 어디다 짜야 할지가 문제인데 현재 키보드 관련 프로젝트는 두 개가 있는데 다음과 같이 정리하기로 한다.

 

AnerimExercise : 이름 바꿔서 다시 짤 예정이다. 통계는 빼고 순수하고 연습 기능만 넣는다. 키보드 이름도 바꿀 예정이고 워낙 오래전 프로젝트라 릴리즈에서 뭔가 꼬여 있어 관리도 잘 안된다.

RankingKeyboard : , 영 통계는 모두 여기에서 산출한다. 현재 영문 통계를 내는 용으로만 되어 있는데 멀티 스레드나 배치 크기, 허용 거리 등의 옵션은 한글에는 다 필요 없다. 딱 한글 통계만 더 낼 수 있도록 기능만 추가한다.

 

통계를 내기 전에 먼저 샘플부터 정리해야 한다. 한글 샘플은 대략 36K 16000자 분량으로 커스텀 리소스로 준비했다. 더 늘릴 수 있지만 영문 경험상 이 정도 샘플이면 비교적 충분하다. 텍스트 파일 정리해서 영문과 함께 커스텀 리소스로 프로그램에 내장시켜 버렸다. 다른 샘플은 에디트에 붙여 넣어서 사용할 수 있다.

UI도 수정했다. 영문/한글 샘플을 각각 읽어오는 버튼을 배치하고 최초에는 영문을 읽어 오되 한글 버튼을 누르면 한글 샘플을 읽어 에디트에 채운다. 통계 대상은 항상 이 에디트의 텍스트이다.

한글빈도 버튼을 클릭하면 조합형을 경유하여 한글을 자모로 분리한다. 이 기능은 AnerimExercise의 통계 기능에 이미 작성되어 있어 가져만 오면 된다. 통계 결과는 sHanResult 구조체 배열에 저장하되 조합키를 누르는 문자의 조합키도 구조체 안에 같이 지정하도록 했다.

여기서 좀 골치 아픈 문제 하나를 발견했는데 ㄿ과 ㄾ의 경우 키 세 개를 눌러야 한다. 그나마 ㄿ은 ㄼ 다음에 쎈소리를 누르면 ㄿ으로 바꾸면 되는데 ㄾ은 ㄹㄷ이 따로 없어 일단 단 모음으로 입력받은 후 쎈소리를 누르면 ㄹㅌ이 되었다가 다음 자음이 들어오지 않으면 이전 글자의 받침으로 ㄾ을 내려야 한다. 통계에는 일단 반영해 놨는데 오타마타에도 특별한 예외 처리가 필요하다.

통계는 문자와 키에 대해 각각 내도록 했다. 예를 들어 ㅘ 음소에 대해서는 ㅘ 문자가 한번 입력되고 ㅗ와 ㅏ의 키를 각각 누른 것으로 통계를 낸다. 이 통계는 문자에 대한 통계가 아니라 키보드에 존재하는 자모키에 대한 통계여서 결국 어떤 키를 얼마나 많이 눌렀는가가 중요하다.

UI 바꾸고 한글 자모 분리한 후 문자와 키에 대해 통계를 내고 정렬까지 해서 출력하는 기능까지 완성했다. 조금 복잡하다 보니 한나절이 꼬박 걸렸는데 역시 논리적 체력도 좀 떨어진 것 같다. 통계 결과는 다음과 같다. 왼쪽열이 키보드에 있는 문자 20개키에 대한 빈도이며 나머지는 키보드에는 없지만 문자에 대한 통계이다.

 

 

:4501,=4501(18.9%)

:3119,=3494(20.5%)

:1814,=3290(19.3%)

:3014,=3090(13.0%)

:2286,=2766(16.2%)

:2385,=2681(11.2%)

:2607,=2680(11.2%)

:2266,=2484(14.5%)

:1565,=2146(12.6%)

:1612,=2045(8.6%)

:1361,=1859(7.8%)

:1298,=1675(7.0%)

:1009,=1349(7.9%)

:909,=1310(5.5%)

:1140,=1145(4.8%)

:1018,=1089(4.6%)

:0,=975(4.1%)

:682,=873(5.1%)

:0,=799(3.4%)

:658,=683(4.0%)

:703,=0

:419,=0

:320,=0

:282,=0

:281,=0

:218,=0

:173,=0

:152,=0

:138,=0

:133,=0

:130,=0

:129,=0

:101,=0

:92,=0

:79,=0

:76,=0

:70,=0

:69,=0

:63,=0

:52,=0

:50,=0

:40,=0

:33,=0

:19,=0

:7,=0

:5,=0

:3,=0

:3,=0

:3,=0

:2,=0

:0,=0

:0,=0

:0,=0

 

비율은 자음, 모음 각각에 대해 냈는데 섞어서 놓으니 한눈에 얼른 들어오지 않는다. 좌우를 분리하면 다음과 같다.

 

:4501,=4501(18.9%)

:3014,=3090(13.0%)

:2385,=2681(11.2%)

:2607,=2680(11.2%)

:1612,=2045(8.6%)

:1361,=1859(7.8%)

:1298,=1675(7.0%)

:909,=1310(5.5%)

:1140,=1145(4.8%)

:1018,=1089(4.6%)

:0,=975(4.1%)

:0,=799(3.4%)

:3119,=3494(20.5%)

:1814,=3290(19.3%)

:2286,=2766(16.2%)

:2266,=2484(14.5%)

:1565,=2146(12.6%)

:1009,=1349(7.9%)

:682,=873(5.1%)

:658,=683(4.0%)

 

오토마타 적용 전의 음소 순위와 유사하지만 ㄷ과 ㅅ의 차이가 벌어졌고 ㅂ이 ㅁ,ㅎ보다 더 빈도가 높은 것으로 바뀌었다. 쎈소리, 쌍소리키의 빈도가 음소보다 더 떨어지는건 좀 의외의 결과이다. 모음은 순위는 변화가 없는데 비슷하다고 평가했던 ㅡㅗ의 차와 ㅐㅔ의 차가 조금 벌어졌다.

4 7일 작성한 키별 부담도 순위에 따라 빈도가 높은 문자를 차례대로 맵핑해 보면 다음과 같은 초안 배치가 나온다. 키에 없는 문자중에 ㅕ와 ㅆ의 빈도가 다른 것에 비해 높은 편이다. 제자리 원칙에는 어긋나지만 집게 집안열 위치에 이 두개 정도는 놓아도 되지 않을까 싶기도 하다. 이 배치대로 2행을 좌우 교대로 치면 "아너길"이 된다.

이렇게 배치해 놓고 보니 기존에 대충 배치했던 것보다 별로 좋아 보이지 않는다. , 쌍키가 둘 다 새끼에 맵핑되어 있는데다 빈도도 12번에 한번꼴이니 결코 낮지 않다. 그렇다고 어제 초안대로 집게 1, 3행에 쎈, 쌍키를 주기에는 빈도가 너무 떨어진다.

모음의 경우도 기존 배치에 비해 ㅓㅏ가 바뀌고 ㅡㅗ가 바뀌었을 뿐인데 2벌식과 멀어져 익숙해지기 더 어려울 것 같다. 모음은 바꿔봐야 득보다 실이 더 많을 거 같고 자음만 좀 재배치하면 될 거 같다.

그런데 이건 굳이 통계를 돌려가며 점수를 뽑아야 할 필요성까지는 없을 거 같다. 영문과는 달리 채점 기준이 주관적이니 통계 점수가 좋다고 좋은 배치라고 하기는 어렵다. 효율이나 피로도 이런 것보다 2벌식과의 유사성이 더 중요해 빈도 참고해서 직접 배치하는게 더 빠르고 합리적이지 않을까 생각된다.

두 가지 정도 방안을 생각해 봤는데 둘 다 별로이다. , 쎈의 빈도가 너무 떨어져 좋은 자리를 주기도 아깝고 구석에 두자니 치기가 어렵다. 제자리 원칙을 지키기 위해 시도해 봤는데 결국 그다지 좋은 아이디어는 아닌 거 같다. 시도해 본 걸로 만족하고 통계 루틴을 재정비한 성과만 남기고 일단 관두기로 한다.

기존의 배치를 다시 보니 그리 나쁜 거 같지 않다. 제자리 원칙에서 두 개의 키가 벗어났지만 집안열의 ㅋ, ㅍ 출현은 400건 정도이며 ㅇ의 1/10밖에 안된다. 전체 타자에서는 겨우 50번에 한번꼴로 제자리를 벗어나는 정도라 크게 부담되지 않는다. 2벌식과 유사하고 ㅕ와 ㅆ까지 키를 할당하는 방법도 쓸 수 있다.

----------------

1 15 - 기호키 재배치

영문과 한글에 대한 배치는 이제 초안 이상 거의 다 완료된 것 같다. 이제 기호와 기타 문자에 대한 배치도 다시 점검해 보자. 특허 문서를 작성하기 전에 문자와 키의 배치는 거의 완료해야 한다.

가장 시급히 개선해야 할 점은 $ ^의 위치인데 현재 1, 3행 새밖열 바깥에 있다. 게다가 Shift자리라 누르기 쉽지 않다. 다행히 언어나 모드에 상관없는 기호키 전영이라 모드를 바꿀 필요는 없다. 최초 $ Num 모드의 Shift인지 오해해서 3터치인줄 알았는데 그건 아니었다.

$ PHP에서 변수명 앞에 붙이는 기호인데 접근성이 너무 떨어진다. 이에 비해 쿼티 키보드에도 없는 가 한자리를 차지하고 있고 잘 쓰지도 않는 `가 또 한자리를 차지한다. 이 두 문자가 $에 비해 빈도가 더 높다고 할 수 없다. 언제 왜 이런 배치를 결정했는지 기록을 좀 검토해 보니 21 3 15일인데 기록을 그렇게 꼼꼼하게 해 놔도 근거는 따로 없다. $와 바꿀만한 문자는 다음과 같다.

 

1.Num 모드의 2행 우집안열(쿼티 G 자리) : Num 키와 함께 눌러야 하지만 접근성은 더 좋아 보임. 위에 있는 와 같은 화폐 문자라는 것도 괜찮아 보이고.

2.Num 모드의 1행 새끼(쿼티 Q 자리) : 일단 제자리라 자세가 딱 나오기는 한다. 집게를 안쪽으로 구부리는 것보다는 더 나아 보인다.

3.Num 모드의 1행 검지(쿼티 W 자리) : 집게보다는 더 힘이 좋으니 접근성이 좋다.

4.% $ Shift 상태를 바꾸기. 이건 %도 많이 쓰이기 때문에 좋은 선택은 아닌 거 같다.

5.$ @의 위치 바꾸기. @도 많이 쓰긴 하는데 $보다는 빈도가 떨어지니 Shift 자리로 옮기는게 어떨까 싶다.

 

이 결정을 내리기가 참 어려운게 $, %, #, @의 빈도를 정확히 측정할 수 없고 사용하는 언어에 따라 달라진다는 점이다. 고민끝에 $ @의 자리를 바꾸는 것으로 잠정 결정했다가 다른 기호까지도 전반적으로 조정했다. 조정 대상 기호는 다음과 같다.

 

$ : 기호 전용키에 Shift없는 자리 할당. 새밖열이지만 항상 누를 수 있다.

: 거의 사용하지 않으므로 새밖열 Shift에 할당

% : 원래 자리에 배치. #, &와 같은 열이며 숫자와 자주 씀

` ^ : `의 빈도가 떨어지므로 $ Shift 자리에 넣고 ^ Num 모드에 배치

, 중복키 : 숫자 입력시 자리 구분을 위해 직접 넣는 경우가 흔치 않고 원래 Num 패드에도 이 키는 따로 없다. =_는 모드에 상관없이 기호 전용키가 된다. 기호 전용키중에 :; Num 모드에서 +가 된다.

. 중복키 : 소수점 입력이 잦으므로 Num 모드에 중복시켜 둔다.

 

쿼티 키보드의 기호 42개를 다음과 같이 배치했다.

 

기호전용키 7 * 2 = 14 : ,?.!=_$`;:"'@

Num 모드 : 27. 숫자 9개 및 괄호 8. 가감승제 4, ^~|\%#& 7

남은 하나인 숫자 0 Num 모드의 공백키에 할당

Num 모드에서 우3집안열은 . 중복 배치

 

쿼티키의 모든 기호는 다 포함했으며 0이 공백으로 들어간 대신 .을 중복 배치했다. Num 모드와 언어모드는 세 개의 키를 공유하는데 이 중 .은 중복되어 있어 Num 모드에서 직접 입력할 수 없는 기호는 :;,!? 등 다섯 개이다.

Num Shift일 때 왼쪽 15개 키에 뷸릿, 화살표, 수학기호 등을 배치했놨는데 번잡스러우므로 차후 키캡에는 그리지 않고 숨겨진 기능으로 취급하기로 한다.

---------

22 1 17

다음은 엄지키의 동작 방식을 정리한다. 이 부분은 연습 프로그램은 물론이고 전반적인 오토마타에 큰 영향을 끼치므로 코드까지 일체 정비가 필요하다. 더블푸시 등의 논리가 기획만 되어 있을 뿐 아직 정확히 구현되어 있지도 않다. 엄지키는 쿼티 키보드와 다음과 같이 맵핑하고 기능도 다음과 같이 정의한다.

 

엄지키

맵핑

푸시

홀드

더블 푸시

Lang

Menu(VK_APPS)

언어 순환

다음 언어 임시

기능 없음

Edit

Ctrl

1회 편집

편집 임시

편집 고정

Num

Alt

숫자 하나 입력

숫자 계속 입력

숫자 고정

Shift

Shift

윗 글자 입력

윗 글자 계속 입력

윗 글자 고정

 

이전에는 Lang, Num, Edit F1, F2, F3키에 맵핑했었는데 위쪽에 있다 보니 제대로 누르기가 어렵다. 그래서 아래쪽에 있는 Ctrl, Alt, Menu 키를 활용하고자 하는데 특히 Alt키는 WM_SYSKEYDOWN으로 검출해야 해서 좀 번거롭다. 예제 만들어서 테스트해 보니 검출 자체는 가능한 것 같다.

왼쪽의 Alt, Ctrl Edit, Num에 맵핑했는데 쿼티 키보드에 원래 없는 키이다 보니 나중에 실물 키보드를 만들 때 어떤 키를 맵핑할지는 그때 생각해 봐야겠다. 지금은 시제품을 쿼티 기반으로 만들어야 하니 최대한 엄지에 가까운 걸 쓸 수밖에 없다. 오른쪽 Alt, Ctrl은 원래 기능대로 쓰고자 한다. Win, BS, Enter, Space는 원래대로 맵핑하면 된다. 이렇게 되면 문자키중에 남는 건 \ `, + 세 개가 있고 나머지는 다 쓴다.

키맵을 재배치하기 전에 기존 코드부터 좀 정비했다. Mode라고 되어 있던 한영 전환키는 이름을 Lang으로 바꾸었는데 차후 여러 개의 언어를 등록해 놓고 순환하는 키로 쓸 예정이다. 모드 변환을 기획하다 보니 예전 구현의 모드는 레이어를 고려하지 않는 문제가 발견되었다.

 

enum eMode { MODE_HAN,MODE_ENG,MODE_NUM,MODE_EDIT};

 

기록을 살펴 보니 이 모드는 07 8 29일에 초안을 만들었으며 네 모드는 평등하게 구분하였다. 그러나 한글, 영문은 언어의 목록이고 숫자, 편집은 레이어의 목록이어서 이 두 그룹이 하나의 모드를 구성할 수 없다. 그러다 보니 이전 언어가 뭐였는지 큐를 유지하고 찾는 논리가 복잡하다. 레이어는 현재 딱 3개밖에 없다.

 

enum eLayer { LAY_LANG, LAY_NUM, LAY_EDIT };

 

언어 레이어는 다수 개의 언어 목록을 순환하는데 임의의 언어를 지원하기 위해 열거형이 아닌 문자열로 언어명을 지정한다. 사용자 설정에 따라 최대 10개의 언어를 지원하며 Lang 키로 순환하며 사용할 수 있다. 예를 들어 동아시아 무역 회사라면 한,,, 4개의 언어를 세팅해 놓고 쓸 수 있다. 현재는 영문, 한글 딱 2개밖에 없다.

 

TCHAR langs[10][3] = { "EN", "KR", "" };

int lang = 0;

 

언어의 현재값을 0으로 전역 초기화하되 편의상 OnCreate에서 한글인 1로 바꾸어 두었다. 기존의 Mode 변수와 ModeQueue 등은 불필요하다. layer를 먼저 보고 LAY_LANG이면 어떤 언어인지 보면 된다. Mode 하나로 1차원으로 구분하던 것을 layer lang 두 개의 변수로 구분하는 방식으로 바꾸었다. 이 방식이 맞는 거 같다.

엄지키의 기능 정의와 함께 전반적인 코드 수정이 불가피하다. 이전 소스를 보니 이것 저것 고려하는게 많고 중간 중간에 들어간 테스트 기능까지 있었는데 이 기능은 일단 삭제한다. 다음에 필요하면 다시 만들더라도 지금은 일단 빼는게 좋을 거 같다.

 

- 키맵에 한행씩 위로 올리는 기능이 있었는데 이 기능은 제거했다. 초기에 시제품 제작을 위해 만들었었는데 지금은 어차피 시제품도 새로 만들어야 하기 때문에 불필요하다. 키맵 자체에 vkup 필드를 없애 버렸다.

- 훅킹 기능을 제거한다. 만약 이 기능이 필요하면 훅 DLL과 함께 오토마타를 처리하는 별도의 프로그램을 따로 만드는게 좋을 거 같다. 한 프로그램에 구겨 넣으니 흐름도 복잡하고 헷갈린다. 물론 공유할 수 있는 부분이 많은 건 사실인데 그냥 코드 두 벌을 유지하는게 좋을 거 같다.

- 게임 기능도 일단 제거한다. 괜히 페이지를 만들어 어지럽다. 차후 다시 살리더라도 일단 무시한다. 훅킹을 완벽하게 구현한다면 게임은 별도의 프로그램으로 분리해서 다시 만드는게 나을 거 같다.

- 키보드 메시지를 (SYS)KEY_DOWN(UP) 네 개의 메시지에서 받아 각각 처리하려니 엄청 복잡하고 코드 관리도 쉽지 않다. Alt키 때문에 SYS 메시지도 받아야 하고 또 훅킹시는 업, 다운이 따로 구분되지 않아 더 복잡하다. 그래서 모든 키 입력은 다음 함수로 몰아서 받도록 했다.

 

void OnKey(bool bDown, bool bSys, WPARAM wParam, LPARAM lParam)

 

, 다운 여부와 Alt키 여부 등을 인수로 받고 파라미터도 다 전달받는데 lParam의 비트를 판별하면 확장키인지, 자동반복인지를 알 수 있고 스캔코드와 반복카운트까지 조사할 수 있다. 이 함수에서 Ctrl, Alt의 확장키를 구분하고 키맵상의 첨자를 조사하며 자동반복 무시 속성의 키도 처리한다. 맵에 없거나 현재 구성상 보이지 않는 키를 무시하는 필터링까지 처리한 후 다음 함수로 처리를 넘긴다.

 

void ProcessKey(int kidx, bool bDown, bool bSys, bool bPrevdown, bool bExtend, WPARAM wParam, LPARAM lParam)

 

이 함수는 키입력에 대한 모든 것을 집중적으로 처리한다. 키입력은 키보드 메시지로부터 올 수도 있지만 마우스 클릭이나 훅킹을 통해 올 수도 있다. 어떤 경로를 통해 전달된 메시지이든 키 입력에 대한 모든 것을 이 함수가 처리한다. OnKey가 물리적인 입력 시점이면 ProcessKey는 논리적인 처리 함수이다. wParam, lParam은 사실상 불필요한데 예전 함수를 사용하기 위한 통과 인수로 필요하다.

구조를 단순화 해 놓고 엄지키의 기능을 하나씩 재작성했다. Lang키 홀드시 다음 언어를 임시로 입력하고 놓으면 바로 원래 언어로 돌아오도록 한다. 아주 예전에는 이 기능이 되었던 거 같은데 최종 버전 실행해 보니 안된다. 아마 기획만 해 놓고 안 만들었던 거 같다.

예전 기록과 소스를 뒤져 보느니 그냥 새로 만드는게 더 빠를 거 같다. 편집 고정, 숫자 고정 기능을 위해 다음 4개의 전역 변수를 추가했다.

 

bool useNumLock = true;

bool numLock = false;

bool useEditLock = true;

bool editLock = false;

 

use는 일종의 옵션인데 일단은 true로 설정하되 더블푸시가 마음에 들지 않으면 끌 수도 있다. layer, lang 등과 함께 현재 입력 모드를 정의하는 주요 상태 변수이다. Lang 키의 현재 구현 코드는 다음과 같다. 예전 소스와는 구조가 완전히 달라 새로 만들었으며 흐름은 주석에 잘 설명해 두었다.

 

if (kidx == GetIdxFromName("Lang")) {

     if (bDown) {

          // 다른 레이어이면 언어 레이어로 바꾸고 언어는 최후 언어로 유지한다.

          if (layer != LAY_LANG) {

              layer = LAY_LANG;

              // 고정 상태는 해제한다.

              numLock = false;

              editLock = false;

          } else {

              // 이미 언어 레이어이면 다음 언어로 바꾼다.

              lang = FindNextLang();

          }

     } else {

          // 키를 놓을 때 다른 키를 입력했으면 이전 언어로 돌리고 Lang키를 놓았다 바로 뗐으면 변경한 언어를 유지한다.

          if (KeyQueue[0].idx != GetIdxFromName("Lang")) {

              lang = FindPrevLang();

          }

     }

 

     // 숫자가 입력될 수도 있으므로 한글 조립은 일단 푼다.

     bComp = FALSE;

}

 

홀드 기능은 큐를 점검하여 직전에 누른 키가 자신이 아니면 누른 채로 뭔가 다른 키를 입력했다는 것으로 인식하여 이전 언어로 돌아가도록 처리했다. 큐는 이럴 때 아주 유용하다. 다음은 Num 모드의 처리 코드이며 Edit의 처리 코드도 거의 비슷하다.

 

// Num 키 처리 - 숫자 모드를 전환한다.

if (kidx == GetIdxFromName("Num")) {

     if (bDown) {

          // 누를 때 Num 레이어로 바꾼다.

          if (layer != LAY_NUM) {

              layer = LAY_NUM;

              // 편집 고정 상태에서 숫자로 넘어갈 때 편집 고정 해제

              editLock = false;

          } else {

              // 더블푸시하면 숫자 고정.

              if (useNumLock && KeyQueue[1].idx == kidx && TestEllapse(1, Opt.dpTime)) {

                   numLock = true;

                   wl("숫자고정");

              } else {

                   // Num 레이어 이전의 레이어로 돌아간다. 일단 언어 모드로. 편집모드는 차후 고려

                   layer = LAY_LANG;

                   wl("언어복귀");

                   numLock = false;

              }

          }

     } else {

          // Num 키 누른 후 숫자 입력하고 놓았으면 언어 모드로 즉시 복귀한다.

          if (KeyQueue[0].idx != GetIdxFromName("Num")) {

              layer = LAY_LANG;

          }

     }

}

 

Num 자체의 코드 뿐만 아니라 Num 모드에서 숫자를 입력할 때의 처리까지 같이 작성해야 한다.

 

case LAY_NUM:

     ProcessNumber(kidx, wParam, lParam);

     // 홀드 또는 숫자고정 상태. useNumLock 조건은 numLock 조건에 포함되므로 굳이 볼 필요 없음.

     if (IsKeyDown("Num") || numLock) {

          // 현상태 유지.

     } else {

          layer = LAY_LANG;

          wl("한글자 입력 후 언어복귀");

     }

     break;

 

숫자 모드 진입과 해제, 숫자 고정 등의 흐름도는 다음과 같다. 현재는 이 흐름대로 잘 되는데 문제가 생기면 흐름을 수정한 후 코드도 다시 작성해야 한다.

이런 흐름이 단순한 거 같애도 조건이 은근히 복잡하다. 한군데만 까딱 실수해도 전체적인 상태가 꼬여 버린다. numLock이나 editLock 상태에서 Lang키를 누르면 두 고정 상태를 모두 해제하는 코드도 필요하다.

Shift와 영문의 Caps Lock을 처리하는 논리도 비슷하다. Shift는 더블푸시로 고정할 수 없는 대신 CapsLock 키를 눌러 대문자로 고정한다. 다른 레이어와 다른게 영문자는 CapsLock 상태에서 Shift이면 오히려 소문자를 입력해야 한다. 다음 두 개의 변수를 추가했다.

 

bool bShift = false;

bool capLock = false;

 

Shift키를 누르면 토글하고 한 글자 입력 후 즉시 bShift는 해제한다. 이렇게 해도 Shift 상태는 GetKeyState로 눌러져 있는지 점검하므로 홀드 기능에는 이상이 없다. Caps 키는 눌렀다 바로 놓을 때 capLock을 토글한다. Caps 홀드는 FN키로 동작하므로 중간에 다른 키를 눌렀다면 capLock은 건드리지 않는다.

영문 입력 루틴은 소문자를 먼저 읽고 Shift 상태를 조사하여 대문자로 변환하도록 한다. 만약 capLock 상태면 Shift 상태를 반대로 뒤집어 소문자를 그대로 입력한다. 영문자가 아닌 기호는 capLock에 상관없이 Shift 상태에 따라 문자를 읽어 적용하면 된다.

여기까지 작업하니 웬만한 입력 루틴은 다 정비되었다. 언어 변환 잘 되고 숫자, 편집 홀드나 고정도 잘되며 Shift도 잘 입력된다. 한 글자만 입력할 때는 홀드를 꼭 할 필요 없어 엄지쪽의 키를 누른 후 문자키를 누르면 되니 그다지 불편하지 않을 거 같다. 예를 들어 다음 문장을 보자.

 

if (a == 3)

 

(를 입력할 때 Num, (를 차례대로 눌러야 하지만 바로 다시 영문자로 복귀하며 3을 입력할 때도 Num, 3을 누르고 다시 Num )를 누르면 된다. 아니면 Num 홀드 상태에서 3)를 같이 입력해도 된다.

막상 입력해 보면 조금 버벅거리기는 한데 타수가 쿼티보다 과다하게 많지는 않다. ()는 어차피 원래도 투터치였던데다 손가락이 0행까지 가야 하고 3은 바로 입력할 수 있지만 역시 거리가 멀다. 이 정도면 작은 키 개수로 그럭 저럭 괜찮지 않나 싶다.

이 외에도 이런 저런 버그나 아직 미구현한게 많아 코드를 한참이나 뜯어 고쳤다. 다음은 주요 수정 사항이며 이 과정에서 추가적인 문제점을 파악했다.

 

- 조합키 표시 : 상태란에 입력했음만 표시한다. OnKey 선두에서 일괄 처리하려고 했는데 알파벳과 숫자, 기호 등의 레이어가 달라 그렇게 안된다. 조합키에 한영 구분은 없어 Ctrl+C는 언제나 가능하지만 Ctrl+1이나 Ctrl+Del 등은 레이어를 바꿔야 입력할 수 있다. 이 점은 키 개수가 작다보니 좀 불편한 점이며 특히 게임에서 그룹 지정을 바로 할 수 없다는 약점이 있다. 0행의 숫자키가 필요하다.

- Shift + Space = BS : 양쪽키를 다닥 누르면 뒤로 한칸 가니 BS를 대신하기에도 괜찮은 거 같다. , Shift를 홀드한 상태로 Space를 누르면 연속 삭제가 안된다. 이는 윈도우의 키보드 종류3 Shift+Space를 한영 전환키로 정의하기 때문이다. 기반 운영체제의 키보드 드라이버를 바꾸지 않는한 현재로는 해결하기 어렵고 굳이 해결할 필요도 없다. BS 키 자체를 없애 버려도 되지 않을까 싶다.

- 마우스 클릭 지원 : 원래 되던건데 bShift 등의 새로운 변수를 인식하지 못해서 잘 안되었었다. 마우스 루틴도 OnKey를 통하도록 구조를 정비하여 터치 입력도 잘 된다. , 멀티 터치까지 구현하지는 않아 홀드는 마우스로 입력할 수 없다.

- 초성 쌍자음 입력 : 아래한글이 이걸 지원하길레 나도 지원했다. 초성만 입력된 상태에서 단어의 시작일 때 쌍자음이 연속으로 들어오면 교체한다. 예를 들어 ㄱㄱ이 두번 들어오면 ㄲ이다. 이 기능은 원래 bSsangDP 옵션으로 구현되어 있던 것인데 단어 처음에서 쌍자음은 옵션과 상관없이 항상 입력받도록 했다. 단어 중간에서의 쌍자음 입력은 시간차로 구분하는데 이건 완벽하지 않다. 이 작업을 하며 HanCode의 ㅈ에 대해 ㅉ이 지정되어 있지 않은 버그를 발견했다. 아주 옛날부터 있었던 버그인 모양이다.

- 펑션키 입력, 오른쪽 편집기 처리, Esc, Tab 입력 : 원래 있던 기능인데 코드의 구조를 바꾸면서 잠시 정지되었던걸 복구시켜 두었다. , 현재 구성상 보이지 않는 키는 눌러도 입력받지 않는다.

 

여기까지 코드 수정을 완료하니 입력기가 웬만큼 쓸만해졌다. 그 전에도 안되던 기능이 꽤 많았었고 테스트하느라 이것 저것 뒤집어 엎다 보니 숱하게 많은 버그가 있었다. 내가 짜 놓고도 잘 이해되지 않는 코드도 많은데 특히 한글 조합형 조립 코드는 주석이 부실해 관리가 잘 안된다. 이 부분은 공부를 좀 해 두어야겠다.

이제 기능이 거의 다 정의된 거 같으니 코드를 확정하되 모든 코드를 이해하고 관리 가능해야 하며 1년이 지난 후에 다시 봐도 알 수 있도록 직관적인 코드를 만들어야 한다. 그렇지 않으면 기능 개선이나 변경이 무척 어렵다.

22 1 20 - 소젯, 시제품

현재 관리하는 프로젝트는 2개가 있다. 랭킹은 그냥 통계 산출용이고 AnerimExercise가 메인인에 이 안에 기능이 너무 많이 들어 있다. 통계, 타이핑은 물론이고 훅킹, 게임까지 한 프로그램에 몰아 넣다 보니 구조가 복잡하고 관리도 안된다. 과거 기록이 있긴 하지만 기억도 잘 나지 않고 구조도 많이 바뀌어서 새로 짤 계획이다.

그런데 문제는 이름이다. 언제부터 이름을 새로 지어야겠다고 생각만 했지 실천에 옮기지 못했는데 이런 작업은 틈틈이 할려고 미루다 보면 한정없이 늦어진다. 그래서 하루 날 잡고 작명만 하기로 했는데 하루종일 생각했음에도 그다지 쌈박한 이름이 떠오르지 않았다. 쌈박한거 포기하고 그냥 무난한거 고르자. 작명을 위해 내가 만드는 키보드의 특징을 잘 고려해야 한다.

 

- 손가락 제자리 고정. 인체공학적이고 편안함

- 고속 입력이 가능하다.

- 최소 레이아웃으로 작으며 공간을 많이 차지하지 않는다.

- 손가락 개수에 키 개수를 맞추고 손가락당 3개씩만 담당.

- 모든 손가락이 균등하게 작업한다.

- 영문 알파벳 재배치하고 한글은 2벌식 최대 호환

- 홀드, 더블푸시 등 소프트웨어가 좀 더 정교해서 입력을 보조한다.

 

이중 레이아웃을 결정하는 핵심은 "손가락당 3개 제자리"이다. 고속, 소형, 편안함 등은 부차적인 장점이고 키보드의 특성을 잘 설명하는 단어는 아니다. 제자리 특성은 손가락이 웬만해서는 자리를 벗어나지 않고 자기 자리를 지킨다는 뜻이다. 이 특성을 고려하여 다음과 같은 이름을 만들었다.

 

S1B3 : 손가락 하나당 버튼 3개라는 뜻이다. 발음이 어렵다.

Sojett : 손가락이 제자리에서 또각거린다. 는 뜻이다.

Sojetty : ~또각거리는 키보드 라는 뜻이며 좀 귀여운 맛이 있다.

soty : 소엔이 만든 작은 것.

soky : 소엔이 만든 작은 키보드라는 뜻. SoEnKy도 가능

 

이중 Sojett(y)가 제일 무난한 것 같은데 둘 다 상표권이나 도메인은 등록되어 있지 않아 명칭으로 쓰기에 문제는 없어 보인다. 이외에 영문으로 된 이름도 고려해 봤는데 다 손가락을 제자리에 둔다는 뜻이다.

 

finfix, finplace, finkeep, finclick, fintab

 

finkeep 정도면 발음은 괜찮아 보이는데 굳이 영어로 이름을 붙이고 싶지는 않다. 여기까지 생각해본 결과는 소젯이나 소젯티 중 하나가 나을 거 같은데 이 둘로 여러 사람에게 의견을 구해 봤다.

 

Sojett : 2음절. 무난함. 잠이, 종민, 한결, 꽁치, 대희가 각각 한표씩 투표

Sojetty : 3음절. 약간 길지만 귀여움. , 승우, 한슬이 한표씩 투표

 

더 고민해 봐야 새로운 이름이 나올 거 같지는 않고 이 중 하나를 골라 프로젝트를 새로 만들 예정이다. 더 고민해 봐야겠지만 시간을 더 쓴다고 해서 더 좋은 이름이 나올 것도 같지 않고 어차피 나중에라도 다시 바꿀 수 있으니 일단 Sojett를 코드명으로 해서 프로젝트를 새로 만든다. 새 프로젝트 제작을 위해 비주얼 스튜디오 2022도 새로 설치하고 다음 절차를 거쳐 프로젝트를 만들었다.

 

- Win32 데스크톱 빈프로젝트 옵션으로 Sojett 생성. 솔루션과 프로젝트 같은 폴더에 배치 옵션 선택.

- Sojett.cpp 소스 파일 만들고 ApiStart.txt가져와 붙여 넣고 클래스명만 Sojett로 변경. WinMain의 원형 변경하여 경고 제거

- 구성 관리자/편집 선택해서 x64 구성 제거하고 32비트로만 만들 계획. 프로젝트 옵션 조정. 고급/문자집합=설정 안함. C/C++/코드생성/런타임 라이브러리=DLL없는걸로 설정해서 단독 실행 파일 생성, C/C++/일반/SDL 체크=아니오

- Sojett.rc 파일 추가. AnerimExercise.ico res/Sojett.ico로 복사한 후 임포트. resource.h 인클루드하고 메인 아이콘으로 지정

- Util.h, cpp 추가하고 DrawBitmap 함수만 정의해 놓고 차후 필요한 함수로 채울 예정임. JohabUtil 모듈의 함수 가져옴. global.h 추가하고 외부 변수 선언

- ApiEdit 관련 모듈 복사해서 프로젝트에 추가. 당근에서 쓰던 원본을 약간 수정한 것이어서 AnerimExercise에서 가져와야 함. 수정한 코드가 꽤 많은 모양임.

- stdafx.h, cpp 추가하고 헤더 파일 stdafx.h에 모음. 미리컴파일된 헤더 옵션 설정. 임포트 라이브러리 연결하고 경고 무시 지시자 작성

- TCHAR * 타입에 문자열 상수 직접 대입 안된다고 에러 발생. C/C++/언어/준수모드를 Default나 아니오로 변경하면 됨.

- Sojett Insert, Delete 함수를 ApiEdit에서 직접 호출하고 있음. Sojett.h 헤더 파일에 원형 선언하고 구현부 코드 복사. 필요한 전역 변수 모두 선언해 줌

- WndProc을 메시지 핸들러로 쪼갬. Create, Destroy, Paint, Key 메시지만 일단 처리하고 코드는 비워 둠.

 

여기까지 하니 일단 컴파일은 되나 아직 동작은 하지 않음. 기본적인 초기화 및 메시지 입력 받아 처리하는 코드 작성해야 함. 아예 처음부터 다시 작성하는 것과 유사하되 수정을 거쳐야 하기 때문에 오히려 새로 만드는 것보다 더 시간이 오래 걸릴 수도 있다. 다음 절차대로 이틀간 작업을 진행했다.

 

- 키보드 그리기 : OnPaint와 관련 함수, 키맵 등을 모두 가져와 그렸다. 가져올게 많아서 그렇지 기존 코드가 잘 동작했다. 시작 직후 그려지지 않는 문제가 있었는데 LoadPosition에서 위치를 초기화해야 그려진다.

- 키 입력 받기 : OnKey와 그 일당들을 모두 가져 왔다. Process~ 함수가 엄청 많은데 일부는 통폐합하고 불필요한 건 삭제했다. wParam, lParam 통과 인수를 제거하여 ProcessKey 이하의 함수는 키를 논리적으로만 다루면 된다.

 

이 두 가지를 다 처리하는데 하루 정도가 걸렸다. 기본 동작까지 일단 완료한 후 다음 추가 작업을 순서대로 진행하며 코드 정리했다.

 

- Setting 클래스 가져와 INI 파일에 옵션 저장. 소엔티는 유니코드로 동작하는데 비해 이건 ANSI여서 문자열 타입을 중간타입으로 바꾸었다. 한글 조합형을 써야 하고 ApiEdit ANSI 기반이어서 어쩔 수 없다. 위치와 옵션을 저장 및 복구한다.

- 함수 순서를 정비했다. 불필요한 함수는 제거하고 기능별로 함수의 목록을 작성했다. 함수가 너무 많아 좀 난잡했는데 조금 정리된 거 같다. 함수명도 적절히 바꿨다. 예를 들어 GetPrev GetPrevChar로 바꾸고 초성 쌍자음 판별에 이 함수를 호출하도록 했다. 이 함수가 있는지 몰라 새로 만들었었다.

- Util의 함수 목록 정리. 기존 Util에 있던 함수는 대부분 다 가져온 것 같다. 한글 조합형 관련 함수도 여기다 갔다 넣었다.

- 키큐 멤버 정리. 키맵의 그룹 제거. 그룹과 행수가 사실 중복된 정보여서 제거했다. 카테고리와 행으로 키의 그룹을 충분히 판별할 수 있다. 키맵의 순서도 좀 조정했다.

- 보이기 레벨은 없애고 카테고리별로 개별적으로 토글하도록 했다. 메뉴와 툴바도 같이 수정했는데 5레벨과 윗행수 등 불필요한 버튼 없애고 한영키보드 종류를 더 넣었다.

 

하루 쉬었다가 다음 작업 계속 진행했다. 보기보다 꽤 작업양이 많다.

 

- 한글로 시작하기 옵션 추가. 나중에 옵션 구조체에도 넣었으며 대화상자에서 옵션 변경 가능하도록 한다.

- 첫 자에 이응 넣기 옵션 제거, 복모음 옵션은 무조건으로 고정. 이 두 옵션은 별로 조정할 일이 없다. 첫글자 쌍자음 지원 옵션 추가하고 대화상자 안에 체크 박스 배치

- 숫자 고정, 편집 고정 옵션화. 이 옵션을 끄면 고정은 안되고 홀드 또는 한번 입력만 된다. 디폴트는 true이며 웬만하면 true이겠지만 불편하면 끌 수 있다.

- 툴바 전면 재디자인. 14개의 버튼이 있고 예비도 3개나 만들어 두었다. 아주 고급 옵션이 아닌 한 바로 변경할 수 있도록 한다.

- useEmpty 옵션 추가. 한글 자판의 빈칸 4개에 ㅆ, , , ㅛ 음소를 배치한다. 디폴트는 당연히 off이지만 남는키를 최대한 활용할 수 있도록 했다. 입력 방법이 일관되지 않다는 면에서 바람직하지는 않은 것 같다.

- useNumberRow 옵션 추가. 0행을 일단 비워 두되 원하면 쿼티와 같은 숫자를 입력할 수 있도록 했다. 권장하지는 않지만 남는 키를 어떻게든 활용할 방법이 있어야 하며 Ctrl+1 같은 단축키가 꼭 필요하면 이 옵션을 켜고 쓰면 된다. 이 옵션과 2벌식, 쿼티 자판 옵션과는 별개이다. , 2벌식이라고 해서 숫자행을 꼭 쓰는 건 아니며 단지 문자의 배치만 2벌식과 같을 뿐이다.

- 툴바에 한영 자판 선택키 배치하고 실시간으로 한영 키보드 바꿔가며 쓸 수 있도록 했다. 대화상자 안에 있었는데 변경 번거로워 툴바로 뺐다. 툴바에 있는 건 옵션 대화상자에는 굳이 중복할 필요 없어 제거했다.

- 2벌식과 쿼티는 한글 음소, 영문 알파벳 배치만 바꿀 뿐이며 기호 전용키의 문자는 소젯과 같다. 어차피 나머지 기호는 숫자 모드에서 입력해야 한다. 만약 이 키보드를 쿼티, 2벌식으로 쓰고 싶다면 디바이스 드라이버를 깔지 않으면 된다. 그렇더라도 +, \ 키가 아예 없어 진짜 기존 키보드처럼 쓸 수는 없다.

- 컴파일러의 모든 경고 제거했다. 합당한 지적도 있긴 하지만 대부분 쓸데없는 잔소리여서 굳이 참고하지 않아도 된다.

- 옵션 대화상자 작성. 기존 프로젝트의 RC 파일에서 스크립트 복사하고 ID도 직접 정의했는데 예상보다 잘 옮겨진다. 고급 옵션 몇 개만 남겨 두고 다 툴바로 옮겼으며 새로 옵션 몇 개를 더 배치하기도 했다. Option.cpp에 키맵 등 자주 편집하는 소스를 옮겨 메인 소스와 같이 보며 편집할 수 있도록 했다. 편집기 옵션은 잘 동작하되 레이아웃 옵션은 일부 버그가 있는 모양이다.

- 매크로 로드 및 편집, 저장 기능 추가. 이건 기존 프로그램에 있던 기능이라 일단 가져오기만 했다. 잘 동작하는지는 정확히 모르겠는데 매크로 키를 이걸로 구현하고 있어 차후에도 필요할 거 같아 일단 복사만 해 두었다. 지금 당장 쓰지도 않을건데 이걸 지금 손데기는 체력이 딸려 못하겠다. 차후 좀 더 조정이 필요하다.

 

여기까지 작업을 완료하니 웬만큼 쓸만해졌다. 기존 프로젝트에서 가져오지 않은 기능은 다음 몇 가지 뿐이다.

 

- DirectCode : Lang 홀드 상태에서 가상키의 숫자를 직접 입력받는 방식인데 필요는 하더라도 필수적이지는 않다.

- 액셀러레이터 : 원래도 엑셀러레이터가 없긴 했지만 메시지 루프에는 고려하고 있었다. 이 프로그램이 키보드 전체를 독점해야 하니 엑셀러레이터가 먹히기는 어렵다. Alt + F4로 종료도 안되는데 이건 다음에 손 좀 봐야겠다.

- 게임 및 단어, 문장 연습 : 입력 루틴의 복잡도를 증가시키는 것 같아 일단 뺐다. 다음에 필요하면 별도의 창으로 넣어야겠다.

- 훅킹 : 별도 모듈로 분리할지 아니면 예전처럼 다시 끼워 넣을지는 좀 더 연구해 봐야겠다. 예전 버전의 훅킹도 뭔가 완전하지 않았다.

 

이상으로 Sojett 첫버전 제작은 여기까지이다. 하루 쉬고 내일부터 몇 가지 개선 사항을 좀 더 구현해 봐야겠다.

-------------------------------

1 24

하루 쉬기는 개뿔. 빨리 마무리하자 싶어 몇시간 놀다가 다시 자리에 앉았다. 다음 작업은 한글 ㅗ 의 위치이다. 현재 우집1행인데 집안2행도 괜찮아 보인다. 두 자리를 엄밀하게 비교해 보자.

 

우집1 : 일단 제자리 범위. 8순위 피로도 20. 위로 약간 뻗기만 하면 되므로 자세 유지되며 차후 키간격을 좁히면 더 유리해짐.

집안2 : 제자리는 약간 벗어나지만 2벌식과 호환. 18순위 피로도 28. 자세는 약간 틀어지나 아주 많이는 아님.

 

둘 다 부담은 오른손 집게가 지는 자리인데 옆이냐 위냐를 선택해야 한다. 효율상으로는 분명히 위가 좋은데 2벌식을 고려하면 옆도 나쁘지는 않다. 이럴 때는 일단 둘 다 만들어 봐야 한다. swapOyu 옵션을 만들고 이 옵션에 따라 ㅗ의 자리를 결정하되 ㅗ가 갈 자리에는 빈칸 활용시 ㅕ가 있으므로 이 둘을 교환하는 것으로 구현한다.

이 둘을 교체하면 둘 다 2벌식과 자리가 같다. 옵션을 만들고 옵션에 따라 H 자리와 U자리에 음소를 배치했다. 이래 놓고 쳐 보니 2벌식이랑 비슷해져 훨씬 더 적응하기가 편하긴 하다. 그런데 이래 놓고 보니 왼쪽도 마찬가지로 ㅍ과 ㅎ의 자리를 바꿀 수 있고 이왕 바꾸는 김에 ㅊ까지도 같이 교체하면 ㅎ, ㅊ이 둘 다 2벌식과 같아진다.

 

: 빈도 2.89%. 소젯 위치인 C 자리는 13위 부담도 22

: 빈도 1.14%. 소젯 위치인 X 자리는 16위 부담도 23

: 빈도 0.61%. 소젯 위치인 G 자리는 17위 부담도 28

 

진짜 도찐 개찐이다. ㅎ을 2벌식 자리인 G로 옮기고 ㅍ은 C로 옮긴다. 이래 놓고 보면 X 자리의 ㅊ을 C 자리로 옮기면 이것도 2벌식과 같아지고 ㅍ보다는 ㅊ이 빈도가 높아 더 바람직하다. 옵션을 따로 또 만들지 말고 swapOyu 옵션과 함께 적용해 보니 다음 배치가 만들어진다.

2벌식에 비해 자음은 빨간 동그라미한 4개가 다르되 격음 셋은 어차피 빈도가 떨어져 ㅅ위치만 잘 적응하면 되고 모음은 ㅜ만 적응하면 된다. swapOyu 옵션을 적용하지 않으면 파란색 네모친 부분도 2벌식과 달라진다.

두 방식을 비교해 보니 약간 더 쉬운감은 있지만 그렇다고 해서 엄청 자연스럽지는 않다. 어차피 ㅅ과 ㅜ의 위치가 달라 연습은 여전히 필요하고 집안열이 자세가 틀어지는 것도 사실이다. 옵션으로 남겨는 두되 디폴트로 채택은 하지 않기로 한다.

어차피 똑같지 않다면 변화를 적당히 주고 이상적인 배치를 시도해 보는 것이 더 바람직하다. 그렇지 않다면 이 키보드를 굳이 만들 필요가 없지 않겠는가? 처음 생각한대로 밀어부치자.

위 두 문장을 소젯 키보드에서 입력해서 붙여 넣었는데 확실히 2벌식보다는 좀 오래 걸리기는 한다. 내가 더 꾸준히 연습해 봐야겠다.

-----------------

22 1 26

어제는 소젯 소개 ppt 문서 작업을 했다. 쿼티의 문제점 먼저 점검하고 소젯이 이런 문제를 해결한다는 식으로 작성했는데 활용예까지 상세하게 작성하다 보니 시간이 꽤 오래 걸린다. 원래 하루만에 다 할려고 했는데 안되고 이틀은 해야 할 거 같다. 작업중에 몇 가지 문제가 발견되어 버그 먼저 수정했다.

펑션키가 F5~F8까지만 보이고 나머지는 안 보이는 문제가 발생했다. 조사해 보니 코드상의 문제는 없고 k_funmargin 옵션 변수가 엉뚱한 값을 가지고 있었다. 이 값은 펑션키 4개씩의 간격이며 디폴트가 8일뿐 저장은 하지 않는데 테스트중에 뭔가 잘못 들어간 모양이다. INI 파일 삭제 후 다시 실행하니 잘 나온다. 이 과정에서 bHideKey의 디폴트가 TRUE로 되어 있어 처음에 키가 안 보이는 문제가 추가로 발견되어 FALSE로 바꿔 두었다.

다음은 왼쪽 매크로키에 가상키가 연결되어 있지 않은데 시범적인 기능이다 보니 그냥 아무거나 맵핑해 놓았다. arVk 배열상으로는 3000번대의 가상키를 할당할 계획이었던 거 같은데 이렇게 되면 아예 없던 키를 새로 만들어야 한다. 당분간은 쿼티 키보드에서 테스트해야 하므로 어디든 연결해 두어야 한다.

현재 텐키레스 87키에서 남은건 =, \ 딱 두개의 문자밖에 없고 PrtSc, ScrLock, Pause, Ins 기능키 넷도 남아 있다. 나머지는 모두 어딘가에 맵핑되어 있어 텐키레스 키보드로는 매크로에 연결할 키가 없다. M5, M6에 대해서 =, \ 가상키를 맵핑하고 M1 ~ M4 까지는 어쩔 수 없이 넘패드의 1~4까지 맵핑해 두었다.

프로그램 간단히 수정한 후 수정 내용까지 반영해서 ppt를 일단 완성했다. 27페이지 분량이며 쿼티의 불합리성을 먼저 설명한 후 이를 해소하는 소젯의 설계 방향을 기술하는 식이다. 대략 하루 반 정도 걸린 거 같은데 이걸로 지인들에게 자문을 좀 구해야겠다. 앞으로도 꾸준히 관리할 문서이다.

-------------------------

22 1 27

이제 프로그램이 웬만큼 되었으니 시제품을 만들어 볼 때가 되었다. 전부터 생각은 하고 있었지만 실제 만들려고 시도하는 건 처음이다. 그 전에 기존 키보드가 어떻게 구성되어 있는지, 어디를 어떻게 고치면 될지 알아야 하니 일단 뜯어 봤다.

K611 광축 스위치 교체형 텐키레스를 먼저 뜯어 봤는데 이건 광축이라 스위치만 교체할 수 있을 뿐 위치를 바꿀 수는 없다. 다음은 언제 사 둔지 기억도 안나는 콕스 CK420 청축 풀배열이다. 스위치 교체형이라 납땜을 해체할 필요가 없고 풀배열이라 넘패드 영역까지 스위치를 활용할 수 있다. 그냥 막 벌리는건가 싶어 힘 써 봤는데 그래서는 안 열리고 키캡을 제거하면 군데 군데 나사가 있다. 나사를 푸니 뚜껑은 잘 열린다. 기판까지 분리하려면 스위치도 다 분리해야 한다.

전면에서 스위치를 뽑는건 힘이 무척 많이 드는데 나중에 알고 보니 그건 내가 몰라서 그런 것이고 상하의 레버를 오므린 후 뽑으면 잘 뽑인다. 이 경우는 뚜껑을 열었기 때문에 굳이 풀러를 쓸 필요 없고 기판 뒤에서 돌기를 드라이버로 쿡 눌러 주면 쏙 빠진다. 덕분에 100개가 넘는 스위치를 쉽게 해체했다.

스위치를 해체하니 기판만 달랑 떨어져 나오며 요걸 PC에 연결하면 LED 불까지 들어오고 스위치의 두 접점을 붙이면 키 입력도 된다. 키보드의 구조는 무척 간단한 편이다. 그나마 LED가 있어 회로가 좀 복잡하지 입력만 받는다면 훨씬 더 간단할 거 같다.

아크릴판에 구멍 뚫어 키 원하는대로 배치하고 점프선으로 원하는 위치의 선과 연결하면 동작하는 키보드를 만들어볼 수 있을 거 같다. 일단 동작은 둘째치고 배치부터 만들어 보자. 더 쉬운 건 없나 싶어 저번에 당근에서 중고로 산 보스위즈 무선 키보드를 뜯어 봤다.

이건 러버돔에 멤브레인이라 구조가 극단적으로 단순하다. 기판이라고는 저 빨간색 영역이 다이고 필름 세장 겹쳐서 압력으로 입력을 인식한다. 가볍고 무선이라 좋은데 필름을 납땜할 수는 없어 위치를 바꾸지 못한다. 첫 시제품으로 풀배열은 너무 큰 거 같아 2만원짜리 텐키레스 갈축을 뜯어 봤다.

어린 학생한테 해커 K640T 모델 적축, 갈축 각 2만원씩 사 둔건데 키감도 그리 썩 훌륭하지 않고 중복된 키보드도 있어 괜히 샀다 싶었다. 그런데 안 버리고 남겨 두니 이럴 때 유용하게 써 먹는다. 사 둔건 어떤 식으로든 용도가 생기는 모양이다. 콕스 모기업 제품이라 해체 방법이 똑같다.

요런식으로 스위치 사이에 나사가 숨어 있다. 보강판과 기판을 단단하게 고정시키는 역할을 하는데 총 11개이다. 나사 풀고 스위치 다 해체하면 기판이 나타난다.

작아서 귀엽고 일단 46키 정도만 배열해 볼 것이므로 이 정도만 해도 시제품을 만들기에는 충분한 것 같다. 일일이 점프선을 연결하는게 노가다겠지만 케이스도 나름 잘 구비되어 있고 설사 모양새가 좀 안나더라도 동작을 확인하는데는 별 무리 없다. 배열을 마음대로 수정하려면 요런 보강판을 만들어야 한다.

1미리 두께인데 스위치가 모두 이 두께에 맞춘 거 같다. 아크릴은 3미리로 주문했는데 그래도 꽃힐지 모르겠다. 저 철판을 어디 가서 만들어 올 수 있다면 좋겠는데 어디서 만들어야 할지 당췌 아는 바가 없으니 시장 조사를 해 봐야겠다. 일단은 배치만 볼거니까 아크릴에 구멍 뚫어 보고 연결은 다음에 생각해 보자.

기존 키보드의 기판과 보강판을 원하는 위치로 바꾸어 만들기만 하면 되는데 이게 그리 만만하지 않고 돈도 꽤 많이 들어갈 거 같다. 아크릴판에 시제품 만들어 보기 전에 필요한 치수부터 정확히 결정해야 한다. 대충 생각은 하고 있었지만 한번도 실물을 만들어 본 적이 없어 구체적인 값은 처음 결정하는 것 같다. 좌우 대칭형이라 오른쪽만 생각하면 되고 왼쪽은 뒤집어서 쓰면 된다.

 

- 피치 : 표준은 19.1미리이고 휴대용은 18미리 정도로 나오는데 소젯은 19미리나 띄울 필요 없이 17이나 18 정도면 충분하다. 그러나 지금은 기존의 스위치와 키캡을 활용해야 하니 좁게 만들기 어렵다. 스위치를 꽂는 홈은 14미리 정사각형이지만 키캡이 18미리여서 결국 당장은 19미리로 만들 수밖에 없다. 홈 사이에도 최소 2미리는 띄워야 하니 16미리까지는 만들어도 될 거 같다.

- 인덴트 : 좌우 분리형으로 양쪽 자판을 벌릴 수 있어 행사이의 들여쓰는 정도는 그리 클 필요가 없다. 자판을 기울인다면 직교도 가능하다. 그러나 시제품은 옆으로 나란히 놓아야 하고 기울일 수도 없으니 적당히 들여써야 한다. 쿼티는 1, 2행이 25%니까 4.7미리 정도 어긋나는데 조금 많아 보인다. 4미리로 하는 것도 괜찮을 거 같은데 거리를 적당히 띄울거니까 일단 3미리로 정했다.

인덴트는 좌우 거리와도 상관이 있는데 많이 벌릴수록 들여쓸 필요가 없다. 터치패드를 중앙에 놓을 정도로 충분히 벌린다면 직교도 가능할 거 같다. 좌우 자판 전체를 기울인다면 인덴트는 더 줄어 든다. 10도 정도만 기울이고 좌우 2행을 80미리 정도로 충분히 띄운다면 이때도 직교 가능할 거 같다.

- 3행과 엄지행의 거리 : Space가 중앙이지만 기울일 거라 이걸로는 위치를 잡기 어렵고 Enter의 위치를 잡아야 한다. 수직으로는 3미리 더 띄우고 수평으로는 J K의 중간 위치로 잡는다. Space H J의 중간이므로 그 한칸 오른쪽인 Enter J의 절반 위치에 맞추면 된다. 엄지행이 이보다 왼쪽으로 약간 이동하는게 공백키를 누르기 자연스러운데 그러면 Lang키가 멀어지는 부작용이 있다.

- Space, Lang 기울이기 : 엄지의 나머지 두 버튼은 Enter 왼쪽에 나란히 놓되 Space 15도 기울이고 Lang 30도 기울였다. 위치는 Enter 외곽선과 Space 스위치 사각형의 우하단이 일치하는 곳에 배치한다. Lang도 마찬가지로 스위치 우하단이 Space의 외곽선과 일치하게 맞춘다.

- BS, Alt의 위치 : 문자 배열의 연속이라고 보고 BS는 약지 4, Alt는 새끼 4행에 맞춘다. 2칸 아래라 사실 안 보고 치기 쉬운 위치는 아니다.

 

여기까지 치수를 결정한 후 ppt에 실제 배치할 구멍을 디자인했다. ppt는 밀리미터 단위로 정확히 디자인할 수 있어 이런 초안을 그릴 때 좋다. 초안 배치 완성한 후 인쇄했다. 파워포인트의 그림 확장 옵션을 꺼야 정확한 크기로 인쇄된다.

다음은 실제 배치를 해 봐야 하는데 아크릴에 구멍을 정확하게 뚫으려면 공구가 있어야 하고 시간도 오래 걸린다. 대충 배치부터 해 보자 싶어 좀 더 간단한 재료를 찾아 봤다. 마분지나 골판지도 생각해 봤는데 너무 강도가 떨어져 오래 유지할 수 없다. 집안을 둘러 보던 중 기막힌 걸 찾았다. ClearFile의 표지 정도면 강도도 적당하고 자르기도 쉬워 보인다.

오랫동안 개발 문서를 정리하던 파일의 뒷면을 요렇게 싹뚝 잘랐다. 두께가 조금 얇지만 대략 0.8미리 정도 되어 보강판과 비슷하며 스위치를 끼울만 하다. 인쇄한 배치도를 스카치 테이프로 붙인 후 하나만 구멍을 뚫어 키를 꽂아 봤는데 제법 그럴 듯 하다. 크기만 잘 맞추면 스위치가 딸깍하고 걸리기도 한다.

아무리 플라스틱이라고는 하나 그래도 두께가 있어 손으로 직접 구멍을 뚫기 쉽지 않다. 구멍 하나 뚫는데 대략 3분 정도 걸리며 예상보다 손가락에 힘이 많이 들어간다. 음악 들으면 대략 1시간 이상 작업한 후 오른쪽만 다 뚫어 봤다. 한쪽을 다 하고 나니 손에 힘이 빠져서 더 못해 먹겠다.

아까 빼놓은 청축 스위치를 활용하여 끼우고 키캡은 무접점 35그램 중고로 살 때 같이 셋트로 온 덱 키캡을 사용했다. 이게 무려 4만원짜리인데 첫 시제품인만큼 돈 아끼지 말고 팍팍 쓰기로 했다. 바탕이 검정색이니 키캡은 흰색으로 해야 보기 좋다.

키캡까지 다 끼우고 보니 키배열이 평평하지 않다. 중앙 부분이 쑥 꺼진 형태로 끼워지는데 구멍을 너무 작게 뚫은 상태에서 스위치를 끼우니 보강판의 부피가 증가해 평평하지 않고 울퉁불퉁 운다. 엄지행은 적당한 키캡이 없어 방향키를 꺼꾸로 뒤집어 끼웠다. 엄지 각도에 맞출려면 이게 그나마 비슷하다.

스페이스와 양쪽의 키를 곡선으로 배치하다 보니 모서리 부분이 겹친다. 스위치끼리는 침범하지 않지만 키캡이 부딪혀 서로 방해가 된다. 그래서 스페이스 키의 아래쪽을 칼로 잘라 내어 부딪치지 않도록 했다. PBT 키캡인데 딱딱할줄 알았더니 예상외로 잘 잘린다. 실물 키보드의 키캡은 둥근 형태로 만들 계획이다.

여기까지 작업한 후 오른손 팔목과 손가락에 힘이 쭉 빠져 욱신거린다. 도저히 한번에 다는 못할 거 같아 좀 쉬다가 그냥 잠이 들어 버렸다. 푹 자고 팔을 쉬게 한 후 계속 하는게 좋을 거 같다. 오후에 일어나 보니 팔목 상태는 약간 나아졌는데 그렇다고 다 나을 때까지 미룰 수가 없어 바로 작업을 시작했다.

왼쪽도 똑같은 방법으로 뚫되 같은 일을 반복하다 보니 좀 요령이 생긴다. 하나씩 뚫는게 아니라 수평쪽으로 먼저 뚫어 놓고 수직은 나중에 뚫으면 빠르다. 어제 너무 타이트하게 뚫어 이번에는 조금 더 여유있게 뚫었다. 손목이 계속 욱신거리지만 완성을 빨리 보고 싶은 조급한 마음에 서둘러 작업했다.

구멍 뿐만 아니라 어제 뚫었던 것도 가장자리와 모서리 다시 가다듬고 키캡 골라 끼우는 작업까지 서너 시간 정도 걸렸다. 이 작업을 하면서 소프트웨어 개발자인 내가 이런 것까지 해야 하나 회의감이 살짝 들었다. 빨리 이런 건 하인들 시키는 사장님이 되어야 할텐데. 아무튼 고생 끝에 첫 번째 소젯 키보드를 완성했다.

딱 생각했던 배치가 완성되니 나름 감동적이다. 구멍은 대충 다 맞는데 R키 구멍이 너무 헐렁해져 버렸다. 작은 건 깍아서 키울 수 있는데 큰 건 어떻게 방법이 없다. 왼쪽 엄지는 키캡이 없어 안쓰는 흰색 키캡의 방향키 2개를 차출했다. 차후 이 키캡들은 다른 시제품을 만들 때 활용할 수도 있을 거 같다. 뒷면의 모양은 이렇다.

스위치마다 2개의 핀이 있는데 이 핀에 점프선을 납땜해서 기판의 맵핑된 위치에 연결하면 실제 동작하는 키보드가 된다. 나중에 납땜 작업을 하려면 핀이 똑바로 서 있는 것보다 누운게 더 낫다. 핀이 뾰족해서 손을 많이 찔렸고 가운데 둥근 기둥보다 핀이 약간 더 높아 바닥에 놓으면 책상을 긁는다. 그래서 핀을 다 눕혀 버렸다.

핀의 강도가 예상보다 약해서 몇 번 더 구부리면 금방 부러져 버릴 거 같다. 이걸로 시제품을 만들지는 모르겠지만 원한다면 가능은 하다. 키보드 보강판의 스테빌은 모두 제거했다. 보강판 위에 소젯 키보드 올리고 점프선으로 스위치만 연결하면 실제 동작하는 키보드가 된다.

이번 제작은 배열을 일단 만들어 보자는건데 이 배치를 그대로 쓸 수도 있고 수치를 좀 조정할 필요도 있다. 실사용이라고 하기에는 편집키도 없고 펑션키도 없어 좀 불편할 거 같다. 아무래도 이건 배치 확인용으로만 쓰는게 좋다. 혹시 시제품 제작에 더 좋은 키보드가 없을까 싶어 콕스 황축을 뜯어 보았다.

상당히 아끼는 키보드이고 키감도 꽤 마음에 든다. 이 키보드가 시제품으로 적합한 이유는 블루투스 무선으로 연결 가능하기 때문이다. 물론 유선도 된다. 시연할 때 굳이 본체 연결 안해도 되니 좋을 거 같다. 마침 키를 빼 보니 이것도 축 분리형이라 점프선으로 배치를 바꿀 수 있다. 분리하는데는 상당히 애를 먹었다.

상판이 따로 나사로 체결되어 있지 않고 그냥 이빨이 꽉 맞는 플라스틱이라 힘으로 빼는 수밖에 없다. 라벨 부분에 혹시 나사가 있나 싶어 뜯어 봤는데 없다. 그냥 측면에 일자 드라이버를 넣고 무지비하게 재껴서 걸린 부분을 분리해야 한다. 상판을 분리하면 요렇게 숨어 있는 나사가 보인다.

이 나사를 불면 보강판과 기판이 분리된다. 스위치는 뒤에서 밀 것도 없이 풀러로 상하만 집어서 빼면 쉽게 빠진다. 배터리와 기판 연결선까지 분리하면 완전히 해체된다.

 

다 해체하고 나면 결국 기판과 보강판이다. 해체해 본 후 다시 조립해 놨는데 구조를 알고 보니 굳이 상판까지 해체할 필요도 없었다. 스위치의 접점이 노출되어 있으니 여기다 점프선만 연결하는 되는 구조이다. 스테빌까지 다 해체해 놔서 이대로는 쓸 수 없고 결국 공작용이 되고 말았다.

대략 6만원 정도 준 키보드이고 꽤 만족하게 사용했었는데 시제품 제작을 위한 후보로 아낌없이 투자하기로 한다. 블루투스의 이점을 살리면 시연하기도 좋고 테스트하기도 좋으며 실사용에도 큰 문제는 없을 거 같다. 실제 키보드는 아크릴판에 만들 것이며 이미 재료는 사 두었다.

200 * 400 크기이고 3미리 두께이다. 파랑, 반투명 흰색, 투명 등 3개를 샀는데 배송비까지 대략 2만원 들었다. 이 아크릴 판에 소젯 배열 만들어 올리고 점프선으로 텐키레스 키보드랑 연결하면 실제 동작하는 시제품이 된다. 진짜 동작하는 시제품은 85키 풀배열로 만들 것이라 크기가 좀 넉넉해야 한다.

3미리나 되는 아크릴 판을 어떻게 가공할지, 점프선은 어떻게 연결할지 이건 좀 더 고민해 봐야겠다. 당장 손목이 아파서 오늘은 뭘 못하겠고 공구나 재료가 더 필요하니 설 연휴에 숙고를 해 봐야겠다. 만들어 놓은 시제품 배열도 비록 입력은 안되지만 테스트해 보고 실제 배열에 대한 문제점도 더 점검해 보자. 숙고하는동안 몇 가지 생각해 두었던 소프트웨어 개선점이나 작업해야겠다.

22 1 29 - 0.99 릴리즈

시제품을 만든 후 테스트해 보니 글자의 배열이 다른 것보다 더 심각한 문제는 기울기 각도이다. 쿼티에서 왼손 집게 F의 바로 아래쪽은 V로 되어 있기 때문에 손가락을 오른쪽 아래로 기울이며 모두가 여기에 익숙해져 있다. 그러나 소젯 자판에는 왼쪽 아래로 기울이도록 되어 있어 이 방향이 맞지 않다. 손가락은 F 아래쪽이 소젯의 B위치라고 착각하고 있다.

분명히 쿼티가 잘못된 것이 소젯이 맞는데 습관이 이렇게 들어 있다 보니 이상하게 느껴질 수밖에 없다. 오른쪽은 방향이 같애 좀 나은 거 같지만 이쪽도 어색하기는 마찬가지이다. J의 아래쪽인 M이 오른쪽으로 약간 기울어져 있는 것은 같지만 쿼티는 10미리 인덴트인데 비해 소젯은 3미리여서 차이가 많다. 쿼티에 익숙한 상태에서 M을 누르다 보면 그 옆칸인 ,와의 절반 부분을 두드리고 있다.

문자의 배치가 과연 효율적인 판단하려면 나 스스로부터 소젯의 기울기에 익숙해져야 한다. 그러나 당분간 쿼티 키보드를 사용해야 하니 이 습관을 제대로 들일 수가 없고 소젯에 익숙해지기도 어렵다. 결국 검증을 위해서는 나부터 소젯에 익숙해져야 하고 쿼티는 쓰지 말아야 하며 이를 위해 동작하는 소젯 시제품이 절실하다.

시제품을 만들어 쓸려면 차후 변경하기 힘든 부분을 최대한 먼저 찾아내서 어느 정도는 완벽한 형태를 갖추어야 한다. 기울기 외에 엄지행과 3행의 간격 3미리도 살짝 많은 거 같다. 약간만 띄웠는데도 엄지가 키의 중앙이 아닌 윗부분을 누르고 있다. 1미리로 살짝 띄우는 시늉만 내는게 딱 좋을 거 같다는 느낌인데 이건 좀 더 쳐 봐야 알 수 있을 거 같다.

근데 이건 현재 기준으로 그렇다는거지 키피치가 18이나 16미리로 줄어 들고 3행의 키캡 높이를 더 줄이면 달라질 수도 있다. 엄지행이 약간 기울어진 입체이다 보니 숫자행, 펑션까지 다 넣은 풀배열은 쿼티보다 높이도 살짝 높아진다. 피치와 키캡을 줄이면 궁극적으로는 해결되겠지만 시제품은 1미리가 적당한 것 같다. 그러나 양산품이 아닌한 당분간은 기존 스위치와 키캡을 활용해야 하니 상당히 오랫동안 그럴 거 같다. 엄지행 키캡의 크기나 기울기는 현재 상태가 적합한 것 같다.

그 외 다음 몇 가지 개선 사항을 더 적용했다. 시제품을 만들기 전에 조금이라도 더 완벽한 형태를 만들기 위한 시도이다. 발견되는 문제점을 최대한 해결한 후 시제품을 만들어 이것만 쓰면서 테스트해 봐야 한다.

 

- 어차피 당분간 쿼티로 시연을 하고 사용자도 쿼티로 소젯의 배열을 살펴 봐야 한다면 Lang키의 맵핑을 스페이스 바로 옆에 있는 Alt키로 바꾸는게 좋을 거 같다. 쿼티의 자판 종류1에서 이 키가 한영키여서 습관에도 맞고 말이다. 남은 Menu키를 Alt키로 바꾸면 된다. 키맵부터 수정해 봤다.

 

{0,4,4, "Num",VK_MENU,0x0103,       {-1,0},        0,                {{"Num"}}},

{0,4,7, "Lang",VK_MENU,0x0103,      {0,0},     0,                {{"한영"}}},

{0,4,11,"Alt",VK_APPS,0x0303,          {4,0},     VK_LMENU,      {{"Alt"}}},

 

이렇게 되면 Num Lang이 모두 Alt키와 연결되고 좌우만 다를 뿐이다. 소젯의 Alt키는 메뉴키인 VK_APPS에 맵핑한다. 웃긴게 Alt의 가상 키코드가 VK_MENU로 되어 있어 차칮하면 이게 메뉴키인지 헷갈릴 수 있다는 점이다. 맵만 바꾼다고 해서 키 기능이 즉시 바뀌는 건 당연히 아니다. 다른 키는 몰라도 Alt는 시스템키로 취급해서 OnKey에서 조작해 줘야 한다.

 

// Alt키는 오른쪽 확장키일 때 Lang이고 왼쪽 기본키는 Num이다.

if (vk == VK_MENU) {

     if (bExtend) {

          kidx = GetIdxFromName("Lang");

     } else {

          kidx = GetIdxFromName("Num");

     }

}

 

원래는 확장키일 때 "Alt" 입력으로 간주했는데 이걸 Lang으로 바꿔 주면 좌우 Alt키를 각각 다르게 인식한다. 여기까지 하면 Alt키로 언어는 잘 변환된다. 그러나 Hold 상태에서 입력하면 다음 언어로 입력이 안되며 Menu키와 다른 키를 누를 때 조합키로 인식하지 않는다. 이는 우Alt를 현재 조합키로 인식하기 때문인데 다음을 수정해야 한다.

 

// 조합키가 눌러져 있는지 조사한다.

bool IsModifierPress()

{

     // 오른쪽 Ctrl만 조합키이다. Alt Menu키가 대신한다. Shift 단독으로는 조합키가 아니어서 당장은 볼 필요 없다.

     if ((GetKeyState(VK_RCONTROL) & 0x8000) == 0x8000) return true;

     if ((GetKeyState(VK_APPS) & 0x8000) == 0x8000) return true;

     if ((GetKeyState(VK_LWIN) & 0x8000) == 0x8000 || (GetKeyState(VK_RWIN) & 0x8000) == 0x8000) return true;

 

     return false;

}

 

두번째 조건이 원래는 VK_RMENU를 보는 것인데 이제는 VK_APPS를 봐야 한다. GetModifierString 함수도 같은 방식으로 수정한다. 여기까지 수정하면 맵핑이 변경되며 모든 기능이 잘 동작한다. 엄지 안쪽이 약간 멀고 소젯과 방향이 반대지만 Menu키보다는 안보고 누르기 편해졌다.

 

- Shift + SP를 한번 누르면 BS로 동작하는데 같이 누르거나 연속으로 누르는건 안된다. 이는 윈도우의 종류3 Shift+Sp를 언어 변환키로 활용하기 때문이다. Shift + Sp를 누를 때 전달되는 키 입력은 다음과 같다.

 

KeyDown : 10(VK_SHIFT)

KeyDown : E5(VK_PROCESSKEY)

KeyUp : 15(VK_HANGUL)

KeyUp : 10(VK_SHIFT)

 

공백이 눌러졌다는 키는 전혀 전달되지 않으며 한글 전환키로 인식한다. 그렇다면 종류1로 바꾸면 되는지 테스트해 볼 필요가 있다. 윈도우10의 키보드 종류를 바꾸는 절차가 엄청 복잡하다. 제어판이 일관되지 못해 맨날 바뀐다. 설정/시간 및 언어로 들어가 언어탭을 보면 한국어로 되어 있다. 이걸 클릭하면 아래쪽에 옵션 버튼이 나타난다.

 

한국어를 클릭하지 않으면 옵션 버튼을 볼 수 없고 팝업 메뉴도 지원하지 않아 이따구로 숨겨 놓으면 도대체 어떻게 찾으라는건지. 옵션을 클릭하면 새로운 팝업이 열리며 여기서 레이아웃 변경 버튼을 클릭한다.

종류3으로 되어 있는데 종류1로 변경하고 재부팅하면 Alt키로 한영을 전환한다. 내가 Shift+Sp에 너무 익숙해져 있다 보니 엄청 불편하다. 이 상태에서 Shift+Sp입력은 평이하게 두 키의 연속 입력으로 인식되며 연속으로 눌러도 BS로 잘 인식된다. 반면 오른쪽 Alt키가 한영전환키가 되어 이 키 입력이 따로 전달되지 않는다.

대신 E5 15가 연속적으로 온 것으로 인식한다. 키보드 종류에 상관없이 동작하려면 결국 이 두 키도 처리해야 한다는 얘기다. 종류 1일 때 우Alt 입력을 Lang에 맵핑하는 코드가 필요하다. VK_HANGUL은 키맵에 없기 때문에 GetIdxFromName 이전에 점검해야 한다. 그런데 또 다른 문제가 있다. 한글 모드로 바뀌면 가상키가 전달되지 않고 대신 IME 메시지가 전달된다. 이런 문제로 한글 모드에서 단축키가 안 먹는 경우가 종종 있다.

한글 모드에서도 단축키를 알아 내려면 스캔코드를 읽으면 되는데 그것도 TranslateMessage 이전에 미리 읽어 봐야 한다. 한글 모드로 바꾸는 건 메시지를 전달하기 이전에 시스템이 알아서 해 버리기 때문에 끼어들기 쉽지 않다. 메시지 루프를 건드리는거라 쉽지 않고 다른 부작용도 많다. 결국 한글 모드로 바꾸도록 해서는 안된다. 다음과 같이 코드를 작성했다.

 

if (vk == VK_HANGUL) {

     kidx = GetIdxFromName("Lang");

     if (MyGetImeMode(hWndMain)) {

          MySetImeMode(hWndMain, FALSE);

     }

} else {

     // 눌러진 키 조사.

     kidx = GetIdxFromVk(vk);

 

Alt 키를 누를 때 한글 모드이면 강제로 꺼 버리는 것이다. 여기까지 하면 일단 언어 전환은 잘 된다. 그러나 Lang키를 홀드한 상태를 구분해 내지 못하는 문제가 있다. Alt키를 누르고 있는 동안은 계속 e5 가상 코드가 전달되기 때문이다. 이 문제는 IME와도 연관이 있어 좀 더 연구해 봐야 한다. 일단은 내가 쓰는 키보드인 종류3에서의 문제부터 해결해 보자. 키보드 바꾸고 재부팅을 다시 해야 하니 시간이 좀 걸린다.

재부팅 후 종류3으로 다시 바꾸었다. 종류 1은 오히려 Alt키가 오토 리피트가 되지 않아 더 불편한 면이 있다. 종류 3에서 Shift+Sp를 누를 때 VK_PROCESSKEY가 전달되고 연이어 VK_HANGUL이 오는데 VK_HANGUL은 오토 리피트가 안된다. 그래서 E5 가상키코드와 스캔코드 57이 입력될 때를 잡아서 Space로 바꿔 주었다.

 

// 키보드 종류 3에서 Shift+Space를 누를 때 한영 전환하지 않고 Space 입력으로 간주한다.

if (vk == VK_PROCESSKEY && scan == 57) {

     kidx = GetIdxFromName("Space");

     Trace("한글키 입력 - Space로 강제 변환");

     if (MyGetImeMode(hWndMain)) {

          MySetImeMode(hWndMain, FALSE);

     }

} else {

     // 눌러진 키 조사.

     kidx = GetIdxFromVk(vk);

 

이렇게 하니 언어 전환도 잘 되고 Shift+Sp 연속 입력도 잘 된다. 일단은 모든 문제가 다 해결된 거 같은데 어디까지나 연습 프로그램 수준에서 그럴 뿐이다. 실제 디바이스 드라이버를 만들려면 IME 메시지까지 생성해 줘야 하며 한, 영 모드를 시스템 차원에서 관리할 수 있도록 해야 한다. 이건 한참이나 더 연구가 필요한 부분이다.

 

- Shift+Sp BS를 완전히 대신할 수 있도록 수정했다. 한글 조립중에 음소 단위로 지우는 것도 잘 된다. 윈도우의 IME가 아닌 직접 만든 오토마타를 사용하니 입력된 키만 정확히 구분하면 된다. 그렇다면 이 시점에서 이제 BS 키가 과연 필요한지 잘 생각해 봐야 한다. 4행에는 조합키를 주로 두는데 이 위치의 BS가 좀 쌩뚱맞다. 예전에 기획했던 다음 4행이 어떨까 싶다.

Ctrl 키의 사용 빈도가 높으니 이 키를 양쪽에 배치하면 실용성이 있다. 쿼티 키보드에서도 Alt는 빈도가 낮고 하나를 언어 전환으로 쓰고 있어 하나만 있으면 충분하다. 반면 Ctrl은 여러 키와 조합하기 때문에 양쪽에 있으면 실용성이 증가한다.

어차피 BS Shift+Space로도 입력할 수 있고 초보가 아닌한 오타를 낼 확률이 많지 않아 BS가 아예 필요 없는 키 정도로 광고하면 그것도 나름 괜찮지 않을까 싶다. 시제품 키보드로 테스트해 보면 오른손 약지를 아래로 뻗어 BS를 누르는 것보다 양손 엄지로 Shift+Sp를 누르는게 더 쉽다.

또한 BS Ctrl, Alt, Shift 등과 조합하는 경우가 거의 없어 단독키가 없어도 크게 불편하지 않다. BS가 단독으로 있어야 하는 경우는 초보자가 이 키보드를 배울 때인데 아예 처음부터 Shift+Sp에 익숙해도록 하는게 낫지 않을까 싶다. 같은 키를 양쪽에 두는게 뭣하다면 FN 같은 키보드 고유의 조합키를 배치하는 것도 괜찮아 보인다. BS를 제거하고 Alt, Ctrl을 배치하는 것은 키 맵만 수정하면 그만이다.

 

{0,4,10,"Alt",VK_APPS,0x0103,          {3,0},     0,                {{"Alt"}}},

{0,4,11,"RCtrl",VK_CONTROL,0x0303,    {4,0},     VK_LMENU,      {{"Ctrl"}}},

 

간단하게 수정은 되지만 왼쪽 Ctrl키를 편집키로 맵핑하여 키보드로 실제 오른쪽 Ctrl을 누를 방법은 없다. 그냥 배치가 그렇다는 것만 표시할 뿐이며 나중에 실물 키보드에서 Edit키를 다른 키로 맵핑할 필요가 있다. 별도의 스캔 코드를 가지는 키를 도입하든가 아니면 PrtSc Pause처럼 남은 키 하나를 할당하는 수밖에 없다.

 

- 다음은 Num Shift의 위치에 대해 다시 한번 검증해 보자. 기호가 대부분 왼쪽에 있기 때문에 코딩을 할 때 Num의 빈도가 굉장히 높다. 이에 비해 Shift는 한글 쌍자음 입력 외에는 별로 쓸 일이 없고 영문도 첫 글자만 대문자로 쓰는 경향이 많아 Num 보다는 빈도가 낮다. 그래서 이 둘을 바꿔봄직하다.

그러나 Shift의 빈도도 무시할 수 없는게 문장만 입력할 때는 기호가 많지 않고 기호영역에 있는 ' : ! ? 등도 꽤 높은 편이다. 게다가 Shift+Sp BS의 기능을 부여하면 수정의 빈도도 굉장히 높아진다. 또 쿼티의 양쪽에 있던 Shift가 너무 안 좋은 자리로 밀려나는 것도 그다지 바람직해 보이지 않는다.

둘 중 어떤 키의 빈도가 더 높은지는 실제 사용예의 통계를 뽑아 봐야 한다. 그럴려면 이 둘을 바꿔가며 써 봐야 한다는 얘기인데 결국 swapShiftNum 옵션이 필요하다. 디폴트는 현재대로 두 되 옵션에 따라 두 키를 교환하도록 하자. 실제 바꾸겠다는 뜻이 아니라 바꿔 보고 테스트해 보기 위한 시범적인 기능이다.

Option 구조체에 swapShiftNum 변수를 추가하고 두 키의 정보가 기록되어 있는 51, 52번 맵 요소의 값만 변경하면 된다. 키의 기능을 바꾸기 때문에 이름이나 가상키로 찾아서는 일정한 위치를 정확히 찾을 수 없어 상수 51 52를 바로 사용했다. 맵의 요소 순서가 바뀌면 이 두 위치값도 같이 조정해야 하는 번거로움이 있다.

 

     int numIdx, shiftIdx;

     if (Opt.swapShiftNum) {

          shiftIdx = 52;

          numIdx = 51;

     } else {

          shiftIdx = 51;

          numIdx = 52;

     }

     lstrcpy(kbd.Map[shiftIdx].Name, "Shift");

     kbd.Map[shiftIdx].vk = VK_SHIFT;

     lstrcpy(kbd.Map[shiftIdx].Han[0][0], "Shift");

     lstrcpy(kbd.Map[numIdx].Name, "Num");

     kbd.Map[numIdx].vk = VK_MENU;

     lstrcpy(kbd.Map[numIdx].Han[0][0], "Num");

 

대화상자에 체크 박스 하나 배치해 두고 이 옵션을 상태를 보여 주고 체크 상태 변경시 옵션도 변경한다. 옵션이 바뀌면 키보드 정보를 새로 조사한다. 이 옵션에 따라 왼손 엄지행은 다음과 같이 바뀐다.

 

주의할 것은 화면상의 위치가 바뀌는 것이지 키의 맵핑이 바뀌는 것은 아니라는 점이다. Shift는 여전히 Shift에 맵핑하고 Num은 항상 Alt에 맵핑하므로 코드상의 변화는 없다. 실물 키보드라면 맵핑은 그대로 유지한 채 물리적인 키의 순서를 직접 바꿔야 한다. 다만, 이 옵션은 터치 스크린으로 입력할 때는 효과가 있다.

 

- Caps 키를 누른 채로 다른 키를 누르면 이때는 FN키로 동작한다. 이 기능이 동작하지 않는데 조사해 보니 IsModifierPress에서 Caps를 조합키로 지정하지 않았다. 마찬가지로 GetModifierString 함수도 FN 조합을 인식하지 않도 다른 키와는 조합 방버이 좀 다르다.

 

 

// FN 조합키는 다른 조합키와는 결합하지 않는다. 이게 눌러지면 무조건 알파벳 키와만 결합한다.

if ((GetKeyState(VK_CAPITAL) & 0x8000) == 0x8000) {

     lstrcat(Control, "FN+");

     return;

}

 

FN을 누르고 있으면 이때는 어떤 키를 눌렀는가만 중요하지 레이어나 쉬프트 상태 따위는 중요하지 않다. FN+A는 항상 FN+A이지 FN+Shift+A FN+Ctrl+A 따위는 없다는 뜻이다. FN이 키보드 자체의 옵션 변경 등을 지정하는 역할을 하므로 수가 그렇게 많을 필요가 없고 레이어를 구분하는 것도 웃긴 일이다.

 

- 프로젝트 이름이 바뀌었으니 아이콘도 교체했다. 그 전에는 아너림이라는 의미라 ""자를 새겨 놨는지 지금은 손가락이 제자리에 있다는 의미로 손가락 하나를 키 위에 그려 넣었다. 물론 예쁜 거와는 거리가 멀지는 언제는 내가 예쁘게 만들었나. 그냥 대충 알아볼 수 있고 구분 가능하게만 그리자.

여기까지 소젯 0.99 버전으로 릴리즈한다. 실행 파일 크기는 323KB이다. 완성도가 많이 높아지기도 했고 실물 키보드까지 만들어 봤으니 좀 있으면 1.0을 릴리즈할 때도 되었다. 오늘 릴리즈한 건 1.0 베타 정도의 의미이고 이후 잔버그를 조금만 더 수정해서 1.0으로 확정한다. 이후에는 1.1, 1.2 식으로 버전을 계속 높여 나갈 것이다.

-----------------------

1 30

이틀에 걸쳐 소젯 소개 ppt 문서를 30페이지 가량 만들어 두었다. 다른 개발자에게 조언을 구하거나 개념을 설명하기 위해 잘 정리된 문서가 필요하다. 이걸로 오늘 리허설을 해 보니 아직 빠진 것도 좀 있고 말이 너무 장황해 간략하지 못하다.

지금까지의 작업 기록을 참고했는데 오래 되다 보니 불명확한게 좀 있다. 특히 문자 통계는 그동안 여러번 바뀌어 어떤게 최종인지 구분하기 어렵다. 따로 최종 통계를 문서 처음에 정리해 두고 문장도 전반적으로 다듬어 두었다.

다음은 클리앙 키보드당에서 본 커스텀 키보드에 대한 분석이다. 내것도 중요하지만 남의 것도 자꾸 참고해서 장점을 따올 필요가 있다. 키보드매니아 등 동호회도 자주 들락거리며 정보를 좀 더 모아야겠다. -> 이하 내용은 개요로 옮겨 정리해 놓음

....

여러 가지 시도가 많다는 것은 바람직한데 커스텀이다 보니 배열을 프로그래밍하기 나름이고 자잘한 변형이 많아 모든 사람이 동일한 방식으로 입력할 수 없는 문제가 있다. 진정한 대통일을 이루려면 최선의 방법 딱 하나를 찾아 모두에게 강제할 필요가 있다. 그 방법이 일상적인 모든 입력은 물론이고 다국어까지 훌륭히 지원해야 한다.

-----------------------------

1 31

문서를 실컷 썼다가 윈도우가 다운되는 바람에 다시 작성함. 운영체제가 다운되는 일이 흔한게 아닌데 개짜증남.

소젯은 원래 한손 키보드로 기획되었다. 지금은 양손으로 만들고 있지만 좌우 대칭을 잘 활용하면 한손도 가능하다. 또한 알파벳보다 문자가 많은 유럽언어를 위해 더 많은 문자키를 확보할 필요가 있다. 이게 가능하려면 우새밖열의 ETC가 기능키가 아닌 문자키가 되어야 한다. 이 점에 대해서는 210313에 연구해 본바가 있는데 ETC를 오른쪽 매크로 영역으로 이동시키면 된다.

이렇게 하면 새밖열은 비는데 한글 ㅋ 정도를 가져다 놓을 수 있다. 물론 그럴 수 있다는거지 1행집안열보다 더 좋지는 않다. ETC는 왼쪽으로 밀려나고 남은 3개의 키는 클립보드 동작으로 초기화해 둔다. Edit 영역에 조합키로 있는 것은 Ctrl+C와 다를바 없어 단독키여야 한다. 이 셋만 단독키이면 영문 배열의 차이로 인한 단축키 불편도 어느 정도 해소된다.

초기값만 클립보드 동작일 뿐 매크로키이므로 다른 용도로 바꿔쓸 수 있다. 매크로키가 사실 그렇게 많이 있을 필요가 없고 필요할 때 바꿔 쓸 수 있는 키 한두개만 있으면 되니 3개 정도면 딱히 부족하지는 않을 거 같다. 한글, 영문 모드에서 새밖열 3개가 비는 것이 좀 안타까워 보이기도 하는데 이게 싫으면 ETC를 안으로 다시 가져 오고 옵션에 따라 매크로로 옮기도록 하면 될 거 같다. 사실 ETC가 안에 있다고 해서 한손 모드로 문자 입력을 못하라는 법은 없고 키 형태가 문자와 같아 기능만 바꾸면 가능도 하다.

한손 키보드에 대한 이전 구현을 살펴 보니 070815 20키가 좀 그럴싸해 보이고 070819 16키로도 모든 입력이 가능했던 모양이다. 이 배치를 참조할 수는 있겠지만 지금은 키 배열이 완전히 달라졌고 엄지에 키가 3개나 있어 만들기 더 쉬워졌다. 소젯 배열의 한쪽 키 개수는 다음 둘 중 하나이다.

 

1, 2, 3 18 + 엄지 5 = 23. 이중 Alt, Ctrl은 조합키이며 문자용은 아님.

23 + 숫자행 6 = 29. 이중 6, - 자리는 너무 멀어 빼면 27

 

기준 위치에서 2행 위까지 올라가고 키 4 개를 더 확보하는게 좋을지 아니면 한손이라도 3행만으로 입력하는게 좋을지는 좀 더 생각해 봐야겠지만 당장은 바로 위의 4키 정도는 사용해도 될 것 같다. 그러면 총 27키가 되는데 초안은 다음과 같다.

엄지는 주로 조합키를 배치한다. Sp, Enter, Lang은 조합하지는 않으므로 2행에 두었으며 키가 부족하니 Shift외에 Upper가 하나 더 필요하다. 27개중 엄지 5개와 2행의 4개를 빼면 18개가 남는다.

 

한글 : ㄱㄴㄷㄹㅁㅂㅅㅇㅈㅎ 자음 10, ㅏㅓㅗㅜㅡㅣㅐㅔ 자음 8개 딱 맞음

영문 : 상위 18개 배치후 하위 pbvkjxqz upper에 배치. 대략 5% 빈도로 Upper.

기호 : 숫자 10개와 .,+=/(){} 9개 배치. Sp 자리도 Num 모드에서는 숫자임. 23개 남는데 Shift 12 Upper 11개 배치하면 되고 오히려 자리가 남음

편집 : 이동은 Shift에 펑션은 Upper에 넣으면 됨.

 

대충 이 정도면 한손 자판이 될 거 같은데 더 자세한 것은 통계도 돌려 보고 실사용 테스트도 거쳐야 한다. 영문도 행비율, 손가락 연타, 연철 정도는 고려해야 하며 한글도 비슷한 통계를 뽑아볼 필요가 있다. 사실 이건 잘 만들어 놓으면 장애인에게 실용적이지만 일반인이 애써 배울 가능성은 거의 없다.

이 시점에 중요한 것은 배치가 아니라 한손 자판을 위해 과연 어떤 키를 남겨야 하는가이다. 이것만 결정해 놓고 대비만 해 놓으면 키맵핑은 차후에라도 얼마든지 바꿀 수 있다. 초안 구현상으로 볼 때 0행 숫자행이 꼭 필요하며 ETC는 굳이 왼쪽 매크로로 빼지 않아도 될 거 같다. 이 정도 점검만 해 두고 한손은 다음에 구현하자.

결론적으로 ETC를 매크로 자리로 빼는건 일단 보류하고 숫자행은 옵션으로 계속 남겨둔다. 3행을 완성하기 위해 일본어나 프랑스어 등은 숫자행까지도 있어야 한다. 0행을 완전히 없앨려면 엄지행에 Upper키를 하나 더 늘리고 Alt, Ctrl까지도 문자키로 전용해서 쓰면 될 거 같기는 하다.

22 2 1-숫자행제거, 다국어지원

유럽 언어와 한손 키보드를 연구하다가 잠자리에 들어 가만 생각해 보니 숫자행을 굳이 남길 필요가 없다는 생각이 문득 들었다. 유럽 알파벳이 좀 많지만 어차피 쿼티에서도 AltGr을 쓰고 있는데 이 기능은 Lang이 대신할 수 있고 ETC를 비워 주면 문자 3개분을 더 확보할 수 있다. 왼손 새밖열로 문자를 입력할 필요가 없는 나라는 이 자리에 ETC를 두도록 옵션을 지정하여 둘 중 하나를 선택적으로 쓸 수 있도록 해 주면 된다.

한손 키보드를 위해 숫자행을 남겨 두려고 했는데 일렬로 늘어선 숫자행이 사각모양보다 편할리 없고 진짜 자주 입력한다면 넘패드를 따로 두면 된다. 숫자행은 제거하되 그 자리에 펑션키를 놓으면 한손에서 펑션키를 문자 입력용으로 사용할 수 있다. 어차피 한손은 문자를 빠르게 입력하는 게 주 목적이므로 펑션키까지 동시 접근이 가능해야 할 이유는 없다.

이런 이유로 숫자행을 아예 제거하고 좌측 매크로행으로 ETC를 옮기는 옵션을 만들어 보기로 했다. 매크로 키는 여섯 개를 제공하되 기본 기능을 일단 할당해 놓고 옵션에 따라 ETC를 놓고 남은 세 개는 매크로를 할당하기로 한다. 이 경우라도 Edit 모드에서는 왼새밖열로 ETC를 누를 수 있다. 숫자행을 없애버릴 예정이므로 매크로키에 쿼티의 1~6까지 키를 할당하면 딱 좋을 거 같다. 여기까지 초안 배치해 본 모습은 다음과 같다. 키를 조금 더 작게 그리고 가운데는 도표로 처리해서 편집하기 쉽도록 했다.

기본 46키에 펑션 12, 편집 9, 매크로 6개까지 다 더하면 풀배열이 73키이며 85키에서 12개나 줄어들었다. 텐키레스 87키보다 작고 65% 배열이 대략 68키이니 그보다 약간 더 많은 셈이다. 오른쪽 편집키 9개를 드러내면 64키가 되는데 그럼 60개인 해피해킹이랑 비슷하다.

오른쪽 편집키는 3열인데 비해 왼쪽 매크로키는 2열이어서 좌우 대칭이 아니다. 매크로도 3열로 9개 배치해 볼까 했는데 딱 2열이 좋다. Copy, Paste에 두 손가락 올려 놓고 교대로 누르기 좋다. 가운데 키는 왠지 누르기 어려워 보이며 매크로키가 9개나 있을 필요가 없다. 카테고리중 사실 편집키가 마우스와의 거리가 멀어 제일 쓸모가 없고 매크로키는 오히려 오른손이 마우스를 잡는 역할을 보조해 준다는 점에서 더 실용적이다.

숫자행이 필요 없다는 것은 여러 가지 실험을 통해 이제 거의 결론이 난 거 같다. 지금까지의 소소한 변화에 비해 좀 파격적이어서 코드를 여기 저기 수정할 곳이 많다. 키맵은 물론 옵션, 화면 배치까지 다 뜯어 고쳐야 하고 다시 돌아오기 쉽지 않다. 이게 과연 맞는지 장단점을 잘 따져 보자. 본격적으로 수정하기 전에 숙고를 해 볼 필요가 있다.

 

장점 : 키보드가 더 작아진다. 안그래도 엄지행 땜에 높이가 높아지는데 위에 따로 떨어진 펑션열이 없어지니 텐키레스와 높이가 비슷하다. 숫자키를 매크로에 맵핑할 수 있고 여유가 많아 텐키레스 수준의 키로도 시제품을 만들 수 있다.

단점 : 쿼티 호환은 거의 물건너 간다. 어차피 기호 때문에 호환이 어렵지만 숫자행이 없어지면 불가능해진다. 유럽은 펑션열에 문자를 할당하고 싶은 유혹이 들 거 같은데 그런 일은 가급적 없도록 방지할 예정이며 그래서 ETC 이동 옵션을 제공한다. 옵션으로 없앨 수 있지만 펑션행 때문에 트리플 키로 만들어도 위에 한 행이 남는다. 숫자행이 없다는 사실에 거부감을 느낄 사람이 많을 거 같은데 어차피 새로 만든거라 충격은 어쩔 수 없다.

 

먼저 숫자행이 있는 마지막 구현을 0.99로 백업해 둔다. 그리고 다음 작업을 순서대로 했다.이 작업에 대해 굳이 상세한 기록을 작성하는 이유는 차후 어떤 이유로 롤백하거나 부분 변경이 필요할 때 어디를 바꿨는지, 또 왜 바꿨는지 알아야 하기 때문이다.

 

- 키맵에서 앞쪽 0 ~ 11번 숫자행을 삭제한다. 대신 펑션행을 키맵의 제일 앞에 배치하여 수직 순서대로 배열했다. 키 맵을 수정하면 Shift, Num의 번호가 자꾸 바뀌는데 관리하기 귀찮아 ApplyMapOption 함수에서 첨자를 찾을 때 Edit를 찾은 후 뒤쪽 두 키의 상태를 변경하도록 했다.

- Category C_NUMBER를 없애고 툴바의 TB_NUMBER 관련 코드 제거. viewCat 배열도 5에서 4로 크기 줄이고 [4]번에 대한 옵션 저장 및 로드 코드 제거. 키맵에도 2번 이후의 카테고리는 1씩 뺀다.

- useNumberRow 옵션 및 TB_USENUMBER 툴바 제거. ApplyMapOption의 관련 코드도 제거. ini 삭제 후 새로 시작하면 일단 제대로 보이고 입력은 됨.

- 펑션키가 한줄 위에 나타난다. 숫자키 자리인 0행으로 각 키의 행, 열 조정하고 CalcKeyRect에서 표준과 똑같은 수식으로 0행에 배치하면 된다. 키의 배치가 딱 맞아 떨어지지 않는데 배치에 관련된 k_* 변수가 너무 많아 헷갈린다. k_vpitchfun, k_vpitch13, k_vpitch4 등 안쓰는 변수를 모조리 제거해 버렸다.

원래 의도는 2행만 크게 배치하고 1, 3행은 좀 낮게 배치하고 엄지행 높이도 각각 지정하려고 했는데 너무 복잡하고 뭐가 뭔지 내가 구분이 안된다. 과거 기록을 보면 어느 정도 유추는 할 수 있지만 수식이 말도 못하게 복잡하다. 죄다 없애 버리고 펑션키와 문자키의 간격인 k_fungap도 없애 버렸다. 이랬더니 수식 좀 손델만 하다.

연습 프로그램이 실제 키보드와 똑같은 필요는 전혀 없다. 키피치는 실물 키보드를 만들 때 적용하면 될 뿐 화면상에서는 그냥 사각으로 보이기만 하면 된다. 옵션창의 펑션 간격 슬라이더는 키마진으로 용도를 변경했다. 차후 더 필요한 옵션이 있으면 그때 만들되 지금은 정비가 필요한 시점이다.

- 매크로키에 1~6까지 맵핑했다. 숫자행을 안 쓰니 맵핑할 키가 많아서 좋다. 캡션도 디폴트 기능으로 적어 뒀다. 그러나 눌렀다는 사실만 알려줄 뿐 기능은 아직 구현하지 않았다. 매크로 편집 기능도 있지만 이건 아직도 한참 더 연구하고 정비해야 할 대상이다. 지금은 키 구조가 중요하니 이건 다음에 하기로 하자.

- ETC의 키 맵핑도 789로 변경한다. 어차피 키가 남고 쿼티 키보드로 이 키를 누르지 않을 것이므로 일관되게 맵핑하는게 좋다. 쿼티의 ETC키는 그냥 미사용으로 남겨 두고 Esc는 연습 프로그램이 단독으로 사용하기로 한다. 키맵에서 인덱스를 찾기 전에 Esc는 리셋용으로 따로 처리한다. Caps의 캡션이 Cpas로 오타가 나 있는데 이제서야 수정했다.

 

여기까지 수정 사항을 반영한 결과는 다음과 같다.좌우 대칭이 아니라 쪼매 안타깝지만 나름 예쁘게 잘 배치된 거 같다. 각 카테고리는 토글 가능하다.

다국어를 넣기 위해 먼저 독일어와 프랑스 자판을 좀 더 연구해 봤는데 프랑스어는 액센트를 조합해서 넣는 식이라 오토마타가 필요하다. 자세한 입력 방법까지는 모르겠고 문자가 좀 더 많으니 더 많은 키가 필요한 것은 분명하다. ETC 세칸으로도 부족하면 펑션키 12개까지 총 15개를 더 쓸 수 있도록 할 예정이다.

다국어를 지원하려면 먼저 키맵부터 뜯어 고쳐야 한다. 현재 한글 2, 영문 2벌에 대해 고정맵으로 작성해 놨는데 이렇게 하면 안되고 임의의 언어를 임의의 개수만큼 정의할 수 있어야 하므로 언어에 대한 정의는 키맵 외부에 있어야 한다. 이를 위해 레이아웃(나중에 차맷으로 바꿈)의 개념을 도입했다. 자판 하나가 곧 레이아웃이며 언어별로 여러 개 존재할 수 있다. 한글의 소젯, 2벌식이 그 예이다.

 

struct sLayout

{

     char Caption[64];     // 레이아웃 이름

     int Lang;               // 언어.

     bool useEtc;             // ETC를 문자로 사용하는가?

     bool useFn;              // FN키를 문자로 사용하는가?

 

     char glyph[MAXGLYPH][2][8];   // 문자 배열. 첨자0=키맵상의 순서, 첨자1=Shift. 첨자3=문자열 버퍼

};

 

ETC 키를 쓸 것인가, 펑션행을 쓸 것인가는 레이아웃별로 다르다. 이건 전역 옵션이 아니라 레이아웃마다 달라지되 ETC를 쓰지 않는 레이아웃도 강제로 매크로 카테고리에 표시하는 옵션은 가능하다.

이 구조체 하나가 레이아웃이며 이런 레이아웃의 배열 arLayout을 정의한다. 각 레이아웃별로 이름과 언어 속성을 가지고 48개의 키에 대해 보통 상태와 Shift 상태를 구분한다. Shift 이외의 문자 상태는 별도로 가지지 않되 언어별로 더 필요하다면 코드에서 처리해야 한다.

 

sLayout arLayout[] = {

     {

          "영문 소젯",

          N_EN,

          false,

          false,

          {

     ....

              {"Esc", ""},

              {"y",""},

              {"w",""},

              {"l",""},

....

     {

          "한글 소젯",

          N_KO,

          false,

          false,

          {

....

              {"Esc", ""},

              {"",""},

              {"",""},

              {"",""},

 

키맵은 언어의 문자 맵핑에 대한 정보는 가지지 않으며 어떤 언어를 사용할 것인지 useLayout 배열에 사용할 언어의 첨자와 순서만 가진다. 최대 5개의 언어를 가질 수 있으며 9999는 끝 표식이다.

 

struct sKeyboard

{

     char Name[64];                  // 키보드의 이름

     int useLayout[MAXLANG + 1];     // 지원 언어 첨자. 최대 5. 9999는 끝

     sKey Map[128];                  // 키맵 배열

};

 

Map은 펑션, 숫자, 엄지행 등에 대한 키맵만 정의하며 앞쪽 48개의 키맵은 각 레이아웃이 정의한다. 최초 sKeyboard 구조체에 사용할 언어의 키맵을 일일이 복사해서 가져오도록 했는데 이미 있는 정보에 대한 사본을 뜨는 삽질이었다. 그냥 어떤 언어를 쓴다는 것만 밝히고 arLayout을 찾아가면 그만이다.

이제 2벌식, 쿼티 변경 옵션은 의미가 없다. 어떤 레이아웃이든 배열에 넣어 놓고 Lang 키로 순회해 가며 사용할 수 있다. 한글 소젯 배열과 한글 2벌식을 같이 쓸수도 있고 영문 소젯과 쿼티를 같이 쓸 수도 있다. 물론 그럴 이유는 없지만 레이아웃끼리는 평등하도록 했다. 과연 다국어가 가능한지 일본어와 독일어 자판을 대충 만들어 넣어 봤다.

히라가나를 배치할 수 있고 입력도 가능하다. 다만 아직 ETC와 펑션행을 쓰지는 못하는데 레이아웃 속성을 참조하여 이 두 영역에도 문자를 배치하고 입력받을 수 있도록 할 계획이다. 언어별로 오토마타도 달라 ProcessJapan, ProcessGerman 등의 함수도 같이 만들고 관리해야 한다.

임의 개수의 언어를 지원할 수 있는 구조를 만들었다. 이제 옵션에서 원하는 레이아웃을 선택해서 순서를 조정해 두면 이대로 동작할 것이다. useLayout 배열을 Option 구조체로 옮기고 디폴트로 L_ENG, L_HAN 두 개만 넣어 둔 후 대화상자에서 지원 가능한 언어 목록을 보여 주고 사용할 언어를 선택하도록 했다.

임의의 목록을 순서대로 조정할 수 있지만 편집이 쉽지 않아 프리셋도 4개 제공한다. 이 배열에 저장해 놓은 언어 목록을 INI 파일에 저장해 두고 다음번 시작할 때 읽어오도록 했다. 한꺼번에 대량의 코드를 작성하다 보니 좀 불안정한데 일단은 잘 동작하는 거 같다. 잔 버그는 있을지언정 흐름은 대충 맞다는 얘기다.

동작에 변경을 가하는 옵션이 많아지다 보니 툴바에 원래 있던 버튼이 필요 없어지고 새로운 옵션이 생긴다. 대화상자에 숨겨 놓은 것도 편의상 꺼내 놓는게 좋을 거 같다. 숫자행 관련 버튼 없애고 레이아웃 프리셋 버튼과 키 교체 옵션 등을 모두 툴바로 빼내고 디자인도 좀 다듬었다.

이런 작업은 자주 하기 어려워 예비 버튼도 2개 남겨 두었다. 이래 놨더니 옵션 바꿔가며 테스트하기 편하고 데모할 때도 기능을 보여 주기 편리하다.

다음은 Lang키의 동작을 조정한다. 이 키는 언어간을 순환하는 역할을 하는데 언어가 하나뿐이라면 순환할 것도 없다. 이런 경우가 별로 없을 거 같지만 미국이나 영국에서는 영어 모드 하나만 쓰고 프랑스나 독일도 자국어에 영어가 포함되어 있으니 굳이 언어를 바꿀 필요가 없다.

우리나라는 영어가 없으면 말이 안되지만 꼭 원한다면 한글 자판 하나만 놓고 쓸 수도 있다. 이 경우는 Lang키가 역할이 없으므로 BS를 대신하는게 좋다. Num 락이나 Edit 락 상태에서 언어 모드로 돌아오는 기능을 줄 수도 있지만 어차피 Num이나 Edit를 다시 눌러 돌아올 수 있으므로 그냥 BS로 두는게 좋을 거 같다. Shift+Space도 같은 기능을 계속 제공하지만 원터치만큼 편하지는 않다. 이 동작은 옵션이 아니라 그냥 무조건이다.

----------------------------------

2 3

윈도우 강제 업데이트로 문서 날릴뻔함. 서비스 중지시켜도 말 안듣고 지맘대로 재부팅해 버리고 진짜 맘에 안듬. 모든 소프트웨어는 버그까지도 하나의 완성품이며 개발자 맘대로 업데이트해서는 안됨. 사용자가 잘 쓰고 있으면 그 상태를 유지할 수 있어야 함. 재부팅후 다음 작업 수행

 

- 공백키는 Shift와 레이어에 따라 Sp, BS, 0 등으로 캡션이 달라지는데 이건 키맵에 적어서는 구현할 수 없고 코드로 구현해야 한다. OnPaint에서 조건에 따라 공백키의 캡션을 변경하였다. 또한 Lang 키도 언어가 하나 뿐이면 캡션은 무조건 BS이다.

이 외에 매크로의 Next/Prev Undo/Redo Shift 상태에 영향을 받으므로 고정 캡션도 두 벌이 있어야 한다. 그러나 이 기능은 연습 프로그램의 캡션 표시 기능일 뿐 동작과는 상관이 없으므로 일단 제외했다. 키캡에 쓰인대로 표시만 하면 된다. 사용자는 Shift+Undo Redo라고 생각할 것이다.

 

- 어떤 대상이나 용어를 정확하게 정립하는게 중요하다. 키보드 제작에도 여러 가지 전문용어를 쓰는데 이 용어가 정확하게 정의되어 있지 않다. 그러다 보니 소스도 난잡하고 이름을 붙이기도 헷갈린다. 주요 세 용어는 다음과 같다.

 

레이어(Layer) : 자판의 입력 모드이며 언어, 숫자, 편집 세 가지가 있다. 앞으로 더 늘어날 가능성은 거의 없다.

레이아웃(Layout) : 어떤 키에 어떤 문자를 맵핑해 놨고 어떻게 입력할지 오토마타를 정의한다. 쿼티, 소젯, 2벌식 등이 있고 나라마다 조금씩 다르다.

언어(Lang) : 입력하는 문자이다. 한글, 영문, 일어 등이 있고 한 언어에도 2벌식, 3벌식 등으로 레이아웃이 각각 다를 수 있다.

 

이 용어들이 우연히 모두 L로 시작하고 레이어와 레이아웃은 앞 세 글자까지 같아 명칭을 붙이기 여럽고 혼란스럽다. 그래서 레이아웃 용어를 적합한 다른 용어로 변경하고자 한다. 사실 레이아웃도 윤곽이라는 뜻일 뿐 키보드와는 직접적인 상관이 없다.

 

키맵(KeyMap) : 키의 배열이라는 뜻이다. KeyArray도 가능하나 너무 길다.

문자맵(CharMap) : 의미는 적합한데 윈도우의 문자표 프로그램과 헷갈린다.

키매트릭스(KeyMatrix) : 키의 배열이라는 뜻이며 2차원 행렬이라 딱 맞긴 하다.

문자 매트릭스(CharMatrix) : 문자의 배열이라는 뜻이다.

 

이 중 의미상으로는 CharMatrix가 가장 명확하다. 사실 Key는 원래 뜻이 열쇠이지 키보드의 버튼 하나를 의미하는게 아니며 키마다 문자를 배열한 표이므로 Char가 더 맞다. 그런데 너무 길다. 그래서 ChaMat로 줄여 부르기로 하고 접두는 CM을 사용하면 적합하다. 어차피 Char Character의 줄인말이라 Char Cha나 별 차이도 없다. 발음할 때 차맷이라고 하면 짧고 좋다.

소스상의 모든 Layout을 찾아 ChaMat으로 바꿨다. 타입, 변수, 리소스는 물론이고 지역 변수 lidx cm으로 수정했다. 비주얼 스튜디오의 바꾸기 기능이 Win32 프로젝트에서는 완벽하지 않아 수작업이 좀 필요하다. 레이어랑 헷갈리지 않아 좋다. 다 바꾸고 난 다음에 생각해 보니 ChrMat도 괜찮지 않았나 싶다.

 

- 독일어 키보드를 만들었다. 유럽 키보드 샘플인 셈인데 ETC가 필요한 키보드라고 가정한 것이다. 움라우트 세 개는 ETC에 할당할 수 있되 ß를 넣을 마땅한 자리가 없다. 독일어는 숫자행에 넣어놨지만 숫자행까지는 쓰지 않으니 [ 자리에 넣었다. 그럼 소젯의 [ 자리에 있던 $ `는 어디론가 가야 하는데 다행히 Num 레이어의 $"@= 네자리가 비어 있다.

$는 기호키에 그대로 있되 Num 레이어로 옮기고 `는 바로 아래 " Num 레이어로 옮겼다. 이렇게 하면 ETC를 쓰지 않아도 2개의 문자를 더 구겨 넣을 수 있고 ETC까지 합하면 세 키에 Num 레이어 세 문자까지 더해 최대 여섯 개까지 추가 가능하다. Num 모드 4개는 모드에 상관없이 일정한 기호를 입력하기 위해 비워둔 것인데 이렇게 유용하게 쓰일줄이야.

그런데 문제가 생겼다. Num 레이어를 차맷에 따라 변경하려면 각 차맷에 Num 레이어 문자 배열이 있어야 한다. 현재 언어 레이어만 정의하고 Num, Edit는 차맷과 상관없이 일정하다고 가정하는데 이게 틀려진 것이다. 그래서 차맷 구조체를 다음과 같이 바꿨다.

 

// 키 하나에 할당되는 문자 정보

struct sCha

{

     char glyph[2][8];     // 문자 레이어. 첨자0=Shift. 첨자1=문자열 버퍼

     char Number[2][8];      // 숫자 레이어. 첨자0=Shift, 첨자1=문자열 버퍼

};

 

// 언어별 차맷 정보

struct sChaMat

{

     char Caption[64];     // 차맷 이름

     int Lang;               // 언어.

     bool useEtc;             // ETC를 문자로 사용하는가?

     bool useFn;              // FN키를 문자로 사용하는가?

     bool diffNum;             // NUM 모드가 기본과 다른가?

 

     sCha Map[MAXGLYPH];              // 문자와 숫자 정보. 첨자0=키맵상의 순서

};

 

문자 외에 숫자도 Shift 상태 두 가지를 가질 수 있도록 했으며 차맷 전부를 일괄 편집하여 Num 레이어의 문자를 정의했다. diffNum 속성은 Num 레이어가 표준과 다르다는 뜻이며 이 경우 키맵이 아닌 차맷에서 기호를 읽는다. Edit 레이어는 아직 그럴 일이 없어 키맵에만 있는데 이건 절대 바뀌면 안된다.

그외 Z Y의 위치도 바꾸었다. 알파벳 언어끼리는 다 같은게 좋지만 독일어가 두 알파벳만 바꾸어 놓은 이유가 있을 것이므로 같이 바꾸었다. 가급적인 영문 배열과 같은게 좋겠지만 필요하다면 알파벳 순서도 바꿀 수 있다.

ß까지는 넣었는데 움라우트는 넣을 수는 있어도 ApiEdit가 표현을 못한다. 유니코드 기반의 편집기가 아니다 보니 움라우트가 깨져 보이는데 이건 어쩔 수 없다. 대신 점 두개짜리 문자를 옆에 적어 움라우트임을 표시했다. 출력은 잘 되는데 이동이나 삭제시 알파벳과 움라우트가 제각각이다.

차맷을 바꿀 때 ApplyChaMat 함수를 호출하고 여기서 차맷의 속성에 따라 ETC와 펑션키의 속성을 변경한다. 플래그가 301로 고정 캡션에 회색이지만 ETC를 쓰는 차맷은 0으로 바꾸어 흰색에 차맷 배열대로 캡션을 출력한다. 매크로 m1, m2, m4 ETC가 되며 캡션과 실행할 가상키가 다 바뀐다. 플래그만 바꿔 놓으면 OnPaint에서 이대로 그린다.

Num 레이어의 캡션이나 입력할 문자는 diffNum 속성에 따라 다른데 이 속성이 선택되어 있으면 차맷에서 읽고 아니면 키맵에서 읽는다. Number 문자표를 어디서 읽는가만 다를 뿐이며 이 코드는 다음과 같이 구현했다.

 

// 크기 8 2차 배열을 가리키는 배열 포인터. 키맵 또는 차맷의 Number 배열을 가리킨다.

char(*Num)[8];

// Num 문자가 따로 있는 차맷이면 차맷에서 읽고 아니면 키맵에서 읽는다.

if (arChaMat[cm].diffNum) {

     Num = arChaMat[cm].Map[kidx].Number;

} else {

     Num = kbd.Map[kidx].Number;

}

lstrcpy(Caption, Num[tShift]);

// Shift에 문자가 없으면 Normal의 문자 표시

if (lstrlen(Caption) == 0) {

     lstrcpy(Caption, Num[0]);

}

 

diffNum 속성에 따라 배열 포인터 변수 Num Number 배열을 선택해 놓고 Num의 문자를 읽는다. Shift에 문자가 없으면 노멀 문자를 읽는다. 이 코드에서 사용한 Num이 배열 포인터인데 이건 C 좀 한다는 사람도 잘 모르는 문법이다. 나도 기억이 나지 않아 내 책보고 복습한 후 사용했다. 진짜 C 문법은 안 쓰는게 없는 거 같다.

독일어는 diffNum 때문에 시간이 좀 걸렸지만 기술적으로 크게 어렵지는 않았다. 고등학교 때 독일어를 해서 최소한 문자 구조는 알고 있으니 이런 개발이 가능하다. 배워서 남주는 건 없다. 알파벳보다 문자수 5개 내외의 언어는 이런 식으로 차맷을 만들면 된다.

 

- 다음은 일본어 자판을 만들어 보자. 독일어보다 언어가 더 많이 FN 행까지 다 사용해야 하는 예이다. 사실 일본어는 ETC까지는 쓰지 않지만 최대한 글자수가 많은 문자를 가정하고 배치해 봤다. 대학교 1학년때 일본어를 배우기는 했지만 F학점 맞아서 글자만 겨우 아는 수준이라 배치는 이미지 보고 대충 했다.

펑션키를 사용하는 차맷은 useFn 속성을 사용하며 여기에 문자를 출력하는 방법은 앞에서 독일어의 ETC의 속성을 편집하는 방법과 같다. 차맷에 문자 배치해 놓고 ApplyChaMat에서 펑션키의 속성만 바꿔 주면 된다. 이래서 배치는 대충 완성했고 0행도 문자키이므로 입력도 잘 된다. Shift도 물론 사용할 수 있다. Num 레이어는 건드리지 않았다.

입력도 잘 되는데 두 가지 사소한 문제가 있다. 매크로의 ETC도 문자가 입력되는데 이건 키맵에 이 키가 0행으로 되어 있어서 그렇다. 매크로는 5, 편집키는 6행으로 정의하여 문제를 해결했다. 펑션키는 문자를 할당했지만 펑션키 눌렀음으로 나오는데 useFn true이면 펑션키는 누르지 못하는 것으로 처리했다. 이 방식대로 하면 기호키 7개만 빼고 41개에 문자를 자유롭게 할당할 수 있다. 최대 82개인 셈이다.

 

- 일본어 자판까지 만들어 봤는데 여기서 문제가 하나 있다. 펑션을 문자로 쓰는 차맷에서는 진짜 펑션키를 누를 방법이 없다. 펑션 카테고리가 있지만 이걸 문자키로 써 버렸기 때문이다. 한영 차맷에서는 문제되지 않지만 펑션행을 문자로 쓰는 차맷은 뭔가 대안적인 방법을 제공해야 한다. 결국 FN키가 따로 필요하다는 얘기인데 오른쪽 Ctrl키를 FN으로 쓰는게 좋을 거 같다.

현재 Caps키에 FN 기능이 있지만 푸시와 홀드를 구분하는 복잡함이 있고 펑션키 외에도 키보드 자체의 고유한 기능을 넣으려면 FN키가 별도로 필요하다. 맵핑할 키가 오른쪽 아래에 더 남아 있지 않은데 ` 또는 \가 비어 있다. 오른쪽에 있는 \가 좀 위에 있지만 오른쪽에 있어서 괜찮을 거 같다.

키맵 수정하고 useFn true인 경우는 Fn이 눌러졌는지까지 확인하고 펑션키 입력을 받는다. Fn을 누른 상태에서는 펑션키 외에는 모두 하드웨어가 직접 처리하므로 프로그램에게 입력으로 보낼 필요 없다. 코드에서는 b를 누를 때 블루투스 연결을 하는 시늉만 한다. 소젯에서는 b가 쿼티의 Z 자리에 있다.

Caps FN키 겸용 기능은 없애 버렸다. 홀드시에 FN으로 쓸려고 했는데 이제 별도의 FN키가 생겼으니 그럴 필요가 없다. 누르는 즉시 대문자 고정 모드를 토글한다. 또 이 키의 플래그에 오토 리피트가 켜져 있는데 무시하도록 속성을 바꿨다.

----------------------------------

2 4 : 하루밤 지남

 

- 상태란에 한글, 영문 언어와 숫자, 편집 등의 레이어만 나타나고 독일어, 일본어는 나타나지 않는데 한영 둘만 지원할 때의 코드가 그대로 있어이다. 언어 레이어일 때는 차맷의 Caption을 읽어 출력하도록 수정했다.

- 독일어의 대문자가 입력되지 않는 버그가 있다. 일본어 루틴을 복사하다 보니 대소문자 처리가 빠졌다. 대소문자는 Shift, capLock을 참조해서 결정하는데 알파벳 언어는 이 논리가 다 똑같다. GetAlphabet 함수에서 이 처리를 하도록 하고 영어와 독일어에서 호출하도록 했다. OnPaint에서 캡션을 출력할 때도 이 함수가 필요하다.

두 번 이상 반복되면 함수로 빼는게 당연하다. 각 언어의 문자를 조사하는 버퍼가 t[3]으로 되어 있었는데 움라우트처럼 2바이트를 넘는 경우가 발견되었다. 또 아무리 지역 변수지만 t는 이름을 너무 무성의하게 붙인 것 같아 chr[8]로 변경했다.

- 펑션행이 문자행 바로 위에 있으니 1~=까지의 숫자키에 맵핑하면 쿼티 키보드에서 구조가 비슷하다. 매크로와 ETC F1~F9까지 맵핑하면 된다. 이렇게 생각한 이유는 쿼티 키보드의 숫자행까지 4행을 그대로 쓰기 위해서이며 쿼티 키보드로 연습 가능하기 때문이다. 그런데 생각해 보니 기울기가 완전히 달라 어차피 연습 효과가 없다. 또 디바이스 드라이버없이 소젯 키보드를 연결했을 때 펑션은 펑션키로 동작하는게 더 맞지 않을까 싶다. 이 기능은 생각만 해보고 적용하지는 않았다.

- ETC위치가 차맷에 따라 가변적인데 만약 독일어와 한국어 차맷 둘을 선택해 놓으면 ETC가 왔다 갔다 한다. ETC의 위치를 매크로 키로 고정시키는 옵션을 두면 어떨까 싶었는데 이것도 안하기로 했다. 한글, 영문 키보드는 ETC가 바깥에 있는것보다 안쪽에 있는게 더 편하고 독일어를 쓴다면 영문 차맷을 같이 쓸 이유가 없기 때문이다. ETC는 차맷에 따라 왔다리 갔다리 해도 별 문제는 없을 거 같고 차맷 목록은 실행중에 자주 바뀌는게 아니라 처음 설치시 한번만 선택하는 설정이다. 만약 한/독 키보드를 꼭 만든다면 이때 한국어의 ETC를 아예 바깥으로 빼서 만들어 버리면 된다.

- 키마다 문자열로된 고유한 이름이 있고 GetIdxFromName("Lang") 식으로 첨자를 찾아 사용했다. vk는 맵핑이 바뀔 수 있으니 고유 명칭으로 쓸 수 없어 이름을 준건데 문제는 검색 함수가 항상 순차검색을 한다는 점이다. 정렬되어 있지 않으니 어쩔 수 없지만 80개 정도 크기라 큰 부담이 되는 것은 아니었다.

그러나 일일이 첨자를 먼저 찾아야 하니 코드가 쓸데없이 길어지는 불편함이 있고 첨자를 기억할 변수가 필요하다. 또 디바이스 드라이버가 이렇게 비효율적으로 동작해서는 안된다. 그래서 각 키의 이름을 열거형으로 일일이 정의했다.

 

enum {

     K_F1, K_F2, K_F3, K_F4, K_F5, K_F6, K_F7, K_F8, K_F9, K_F10, K_F11, K_F12,

     K_ESC, K_Q, K_W, K_E, K_R, K_T, K_Y, K_U, K_I, K_O, K_P, K_OPEN,

     ....

 

K_ 접두를 붙이고 키 이름을 붙이되 [ ] 키는 기호를 쓸 수 없어 K_OPEN, K_CLOSE로 붙였다. 키맵에서 Name은 없애 버리고 키를 찾을 때 그냥 열거형을 바로 쓰면 되니 속도도 빠르다. 그러나 문제가 있는데 Shift Num을 교체할 때 이전에는 키의 이름을 바꿔 버리면 그 키를 찾지만 이제는 절대 첨자를 열거상수로 참조하니 그렇게 안된다. 그게 가능하려면 코드에서 옵션에 따라 점검하는 키의 첨자도 같이 바꿔야 하는데 이는 너무 번거롭다. 실제 키보드에서는 납땜 배선을 바꿔야 하는데 화면상의 캡션만 바꾸도록 했고 맵핑된 가상키는 같다. 그냥 옵션의 의도만 설명할 수 있을 뿐이다.

- 편집키에 대한 새로운 배열을 하나 더 만들어 봤다. 편집키는 지금까지 여러 번 바뀌었는데 제일 왼쪽이 최초 버전이며 쿼티의 편집키와 유사하다. 이랬던걸 210711에 중간 형태로 바꾸었다. Home, End가 직관적이어서 좋고 Del의 위치가 쿼티와 같아 익숙하다. PgUp, PgDn이 붙어 있고 손가락이 달라 상하 이동이 용이하다.

문제는 커서 이동키가 홈포지션이 아니라 아래로 한칸 내려야 한다는게 불편하다는 점이다. JKLI에 커서 이동키를 맵핑해 두면 입력중에 바로 왼쪽, 오른쪽으로 이동할 수 있어 편리하다. Del키도 중지만 구부리면 되니 나쁘지 않다. 다만 Home, End PgUp, PgDn 자리가 서로 떨어져 이 점은 좀 불편할 거 같다. 그리고 Home, End가 홈 포지션이 아니라는 점도 아쉽다.

두 배치중 어떤게 더 나은지는 실사용을 해 보지 않는한 정확히 알 수 없다. 실제 키보드에서 두 배치를 테스트해 보려면 옵션을 만들어 자유롭게 바꿔볼 수 있어야 한다. 그래서 editType 옵션 변수를 만들고 두 가지 타입을 바꿔가며 쓸 수 있도록 했다. 편집 모드에서 이 옵션을 적용하면 다음과 같아지며 잘 동작한다.

문자영역의 편집키는 옵션에 따라 바꾸되 편집영역은 바꾸지 않았다. Name을 없애 버려 맵핑을 바꿀 방법이 현재는 없기 때문이다. 실제 키보드에서도 이 옵션은 납땜을 바꿔야 적용할 수 있다. 두 가지 타입을 비교해 보고 테스트하기에는 현재 상태로도 그리 나쁘지 않다.

- 개발 문서의 2021년분을 과거 문서로 이동했다. 현재 작성하고 있는 2022년 문서가 너무 커져 저장 속도가 느리고 랭킹 관련 코드는 이미 다 테스트해서 더 참조할 일이 없기 때문이다. 그런데 2022년 문서가 56메가에서 45메가 정도로만 줄어 사진을 좀 더 줄여야 할 거 같다. 디지털 카메라로 찍어 그냥 삽입한 이미지를 50~20%로 축소했더니 15M로 줄어 들었다. 문서가 크면 다운도 잘 되고 편집 속도가 느리니 사진 너무 크게 넣지 말아야겠다.

- 설정을 리셋하려면 INI 파일을 일일이 지워야 하는 불편함이 있다. 그래서 디폴트 옵션으로 실행하는 방법을 따로 만들어 두려고 했다. 시작할 때 특정키를 누르고 있으면 설정을 읽지 않고 그냥 초기화만 하는 것이다.

 

if ((GetKeyState(VK_SHIFT) & 0x8000) != 0x8000) {

     LoadOption();

} else {

     InitOption(Opt);

}

 

원래는 Ctrl 키로 할려고 했는데 비주얼 스튜디오에서 실행할 때 Ctrl+F5를 누르니 Ctrl키가 항상 눌러져 있는 셈이다. 그래서 Shift로 바꿨는데 이것도 문제가 있다. 토탈커맨더에서 Shift+더블클릭은 실행과는 의미가 좀 달라 콘솔로 열린다.

프로그램이 너무 빨리 뜨니까 키보드로 초기화 의사를 전달할 방법이 마땅치 않다. 그렇다고 시작할 때 메시지 박스 열어서 물어볼 수도 없고 말이다. 초기화 패스는 구현이 좀 어려워 보류하고 대신 종료시 옵션을 저장하지 않는 코드는 만들어 두었다.

 

if ((GetKeyState(VK_SHIFT) & 0x8000) != 0x8000) {

     SaveOption();

}

 

옵션을 이리 저리 바꿔 보고 굳이 저장하고 싶지 않다면 Shift 키를 누른채로 종료하면 된다. 현재 옵션을 그냥 유지하고 싶다는 뜻인데 이것도 쓸 일이 그리 많을 거 같지는 않다.

- 소개 문서에 새로 들어간 다국어 지원과 편집기 배치 옵션 등을 새로 기록하고 숫자행 카테고리와 숫자행 사용 옵션 등은 제거했다. 또 쿼티와 2벌식이 옵션이 아니라 하나의 차맷으로 지위가 격상된 점도 반영했다. 겨우 며칠간 작업했는데도 소개 문서가 달라질 정도로 변화가 많았던 모양이다.

- 소엔에 소젯 홈페이지를 만들었다. 아직까지도 아너림으로 되어 있는데 기존 문서를 이름만 바꾸고 작업 일지를 작년 연말치까지 추가해서 공개했다. 누가 보지도 않겠지만 그래도 연구 성과는 공유해야지. 연습 프로그램의 도움말과 소개도 새로 만든 경로로 연결해 두었다.

- 소프트웨어는 아직도 버그가 많겠지만 기본틀은 어느 정도 잡았지 않나 싶다. 이 구현이 과연 실용적인지는 시제품을 만들어 봐야 정확히 알 수 있으며 문제점을 더 파악할 수 있다. 시제품 1호 키보드를 만들 준비를 슬슬 해 보자. 먼저 스위치를 모두 황축으로 교체했다.

원래 청축 스위치를 썼는데 좀 시끄러워서 오른쪽만 황축으로 바꿔 봤다. 이른바 가변축인데 이랬더니 좌우손의 감각이 달라 오른손을 쳤다는 느낌이 들지 않았다. 첫 시제품이니만큼 조용한 걸로 하는게 좋을 거 같은데 어떤 걸 쓰든 좌우 스위치가 달라서는 안된다.

이 키보드는 펄렁거려서 이대로는 쓸 수 없다. 뭔가 딱딱한 보강판이 필요한데 아크랄판이 적당할 거 같아 키보드 넓이 똑같이 잘랐다. 배선이 잘 보여야 하므로 투명 아크릴을 사용했다.

아크릴이 미끌거려 키보드가 고정이 안되고 스위치 바닥과 플라스틱판 사이에 6미리의 공간이 있다. 이 공간은 배선 연결을 위해 필요해 막을 수는 없고 가장자리 부분만 아크릴판과 단단히 고정해야 한다. 마땅한 아이디어가 떠오르지 않는데 일단 두 가지 후보가 있다.

 

컵라면 나무젓가락 두개를 겹치니 딱 6미리가 된다. 아니면 3미리 아크릴 두 장을 겹쳐도 된다. 구멍을 뚫어 고정할 볼트가 필요한데 둘 다 좀 별로일 거 같다. 배선도 쉽게 하고 고정도 단단히 되고 이후 배선도 수정할 수 있어야 하는데 마땅한 재료가 생각이 안나 일단 원목을 좀 주문해 놨다.

배선이랑 인두 오면 납땜부터 하고 원목으로 케이스를 짤 생각이다. 연장도 몇 개 새로 장만해 놨다. 소프트웨어 개발자가 공돌이 작업까지 같이 배워가며 할려니 만만치 않지만 어쩔 도리가 없다. 시제품을 만들어 봐야 남을 설득을 하든지 도와줄 사람을 찾든지 할거 아닌가. 오늘 작업은 여기까지

----------------------------

2 5 - 소젯1, 쎈소리 입력 변경

배선을 위해 주문한 점프선이 도착했다. 하나는 0.6미리이고 하나는 0.3미리인데 각 10미터씩 9천원이다. 연선은 구멍에 끼우기 어려울 거 같아 단선으로 준비했는데 이건 또 잘 끊어질까봐 걱정이다. 한번 잘 세팅해 놓고 최대한 움직이지 말아야지.

스위치까지의 거리와 중간에 끼울 목재 보강판의 구멍까지 고려해서 대략 한뼘 정도 길이로 자르고 두 가닥을 스위치에 연결한다. 핫스왑 기판이라 어뎁터가 장착되어 있는데 원래는 구멍에 살짝 끼워 넣을 생각이었으나 그러면 빠질 거 같아 아예 반대쪽으로 빼서 꼬아 버렸다.

왼쪽이 0.3미리이고 오른쪽이 0.6미리인데 하나는 너무 가늘어 문제고 하나는 너무 두꺼워 문제다. 0.3은 얇아서 잘 들어 가는데 약하고 0.6은 두꺼워 구멍에 밀어 넣기 어려운데다 유연성이 떨어진다. 0.4미리 정도가 딱 좋을 거 같다. 전면부 구멍에 끼우고 반대쪽에서 다른 구멍으로 다시 넣어 꼬았다. 기판 반대쪽에서 보면 이런 모양이다.

어뎁터가 선을 꽉 물고 있는 형태라 꼬아서 고정만 잘 하면 기판쪽은 굳이 납땜을 안해도 될 거 같고 필요할 경우 배선을 바꾸기도 쉽다. 이거 두 개 연결하는데 대략 30분 정도 걸렸다. 숙달되더라도 납땜까지 고려하면 시간당 4, 46키 다 연결하려면 11.5시간 작업해야 한다는 얘기다.

문제는 스위치쪽이다. 핀이 노출만 되어 있지 일자로 쭉 뻗어 있어 꼬아서 걸 수가 없다. 핀도 약해서 몇 번 구부리다 보면 부러질 거 같아 함부로 다루지도 못하겠다. 대충 선을 동그랗게 말아 걸쳐만 놨는데 이 상태로 납땜을 해야 한다. 한번 땜을 하면 다시 빼지 못하니 이때부터 기판과 스위치는 일체형이 되어 버린다.

F X 두 개의 스위치를 배선한 후 키보드 연결하고 스위치 눌러 보니 문자 입력은 잘 된다. 이 방식대로 어쨌든 배선만 연결하면 원하는 배열을 만들 수는 있다는 얘기이다. 작전은 일단 됐고 하우징과 보강판을 만들어야 하는데 이게 또 쉽지 않다. 원목 목재를 주문해 놨는데 나무가 다루기 제일 쉬우니 어떻게 뚝딱거려 봐야 한다.

하우징은 기판만 감싸 주면 그만이라 납작한 통 형태로 만들면 되지만 중간 보강판은 스위치도 얹어야 하고 배선도 통과해야 한다. 배선을 이미 납땜한 상태에서 보강판을 중간에 끼워야 하니 보강판의 모든 구멍은 바깥쪽으로 뚫려 있어야 한다. 스위치가 얹히지 않는 쪽으로 홈을 여기 저기 많이 파 놓아야겠다. 그리고 보강판과 스위치가 있는 플라스틱판을 고정하는 것도 문제인데 일단은 볼트를 쓸 생각이다.

---------------------------

2 7

주말동안 공구도 좀 구하고 배선 작업도 좀 했다. 여러 가지 고민을 해 본 결과 새로운 아이디어도 생기고 숙달되기도 했다. 기판에 점프선 연결하는 건 선택의 여지가 없는 거 같고 기판과 플라스틱판 사이에 보강판을 어떻게 만들지 결정해야 한다. 나무든 아크릴이든 보강판이 있어야 타이핑을 해도 울렁거리지 않는다. 일단 이런 형태가 될 거 같다.

보강판 사이로 점프선이 통과해야 하는데 납땜이 먼저이니 구멍을 뚫어 선을 통과시키는 방식은 안된다. 남땜 후 선이 보강판 가장자리를 돌아와야 하니 보강판이 기판과 플라스틱판 사이에 끼어들어야 한다. 점프선도 부피가 상당할텐데 그 공간도 생각해야 한다. 보강판과 기판 사이의 뒤쪽을 들어 공간도 만들고 각도도 기울일 계획이다.

기판을 만들다 실패하거나 두 번째 풀배열 키보드를 또 만들 수도 있는데 후보가 하나 더 필요하다. 지금 쓰고 있는건 CK87 블루투스 모델이고 K641T도 하나 뜯어 놨는데 이건 컨넥터가 없고 그냥 구멍만 있어 반대쪽으로 선을 통과시킬 수가 없다. , 그냥 납땜을 해야 하는 식이라 좀 부담스럽다.

CK87에 첫 버전 만들어 보고 이 기판은 좀 더 숙달되면 납땜해서 사용하는걸로 해야겠다. 이제 전반적인 설계도가 나와야 하며 치수나 모양이 정확해야 한다. 초안은 대략 이 정도가 된다.

하우징을 넣는 박스를 목재로 제작하고 그 위에 목재 또는 아크릴 보강판을 집어 넣고 그 위에 플라스틱판을 얹는다. 문제는 배선 통과 구멍인데 두 가지 문제가 있다.

 

- 납땜 후에 기판과 키보드가 일체가 된 후에 연결하고 이후 분해도 가능해야 하므로 구멍은 안되고 열린 형태여야 한다.

- 플라스틱판과 보강판 사이에도 6미리의 갭이 있어 채워야 하는데 배선이 통과할 수 있으면서 지지까지 가능하게 만들어야 하니 결국 조립 순서를 잘 설계해야 한다.

 

보류한 결정이 있다는게 참 문제다. 배선통과홀의 모양이 결정되지 않으니 선의 길이도 결정할 수 없다. 목재 12T는 너무 두꺼워 둔해 보이고 아크릴은 타이핑시 울렁거림이 있을 거 같다. 목재는 아직 배송이 안됐고 아크릴은 갖고 있는게 3T라 주문부터 다시 해야 한다. 이 둘이 와 봐야 보강판 설계를 할 수 있다. 그러니 지금 할 수 있는건 고작 기판에다 선 연결하는 지루한 작업 뿐이다.

그런데 이 짓도 하다 보니 경험이 쌓이고 정확하고 빨리 할 수 있는 통빡이 생기기 시작했다. 처음에는 선을 통과시킨 후 선 자체를 꼬았는데 그렇게 했더니 선이 약해지고 뭔가 허술해 보였다. 그래서 다음부터는 피복을 완전히 기판에 밀착시킨 후 선을 피복에다 꼬우는 방식으로 바꿨다.

오른쪽은 초기 작업분이고 왼쪽이 좀 진화한 방식이다. 왼쪽 방식이 더 튼튼해 보이고 합선의 위험도 덜하다. 이후부터는 이 방식으로 하고 있다. 점프선은 0.6, 0.3 이후에 0.2도 하나 더 구입해 봤는데 0.6은 억세서 안되겠고 0.2는 너무 약해서 안된다. 0.4 정도가 딱 맞을 거 같은데 지금은 0.3밖에 없으니 이걸로 하기로 했다.

점프선도 하나 탈피해서 하나 끼우고 하는 식이었는데 이제는 한꺼번에 탈피해 놓고 하나씩 꺼내가며 쓰고 있다. 이 작업을 위해 탈피하는 스트립퍼를 하나 구입해 왔다. 비싸지도 않고 고작 2000원짜리이다. 역시 공구가 좋으니 정확하고 안전하다.

익숙해지니 대략 하나당 5분 정도면 점프선 연결이 가능하다. 시간당 12개 할 수 있으니 전체 4시간이면 된다는 얘기인데 전부 연결할 수 있다는 얘기다. 대략 3시간 쪼그리고 앉아 했더니 3, 엄지행은 다 했다.

편집키는 굳이 할 필요 없는데 해 놔서 선만 일단 묶어 놨다. 다음에 풀배열로 만들때나 써야겠다. 0.3미리가 얇아도 컨넥터 구멍에 잘 안들어가는데 이 경우 핀셋으로 구멍을 약간 늘려서 끼우고 있다. 구멍이 넓어지면 접촉 불량이 발생할 수도 있는데 만약 그러면 그냥 납땜해 버려야겠다. 작업을 마친 후 손가락은 공돌이 습진이 발생했다.

점프선에 찔리기도 하고 공구니 기판이니 기름기 있는걸 만지다 보니 이렇게 된다. 그렇다고 이 정밀한 작업을 장갑끼고 할 수도 없는 노릇이다. 쉬엄 쉬엄 그냥 하는 수밖에 없다. 오늘중으로 점프선 연결은 일단 마무리해 놓을 생각이다. 목재 배송 오면 하우징이랑 보강판 만들고 다음 작전 생각해 봐야겠다.

주말에는 작업을 위해 여러 가지 공구를 마련해 두었다. 목재나 아크릴 재단을 위해 컷소를 장호원장에서 2만원 주고 구입했는데 이건 꽤나 쓸만한 거 같다. 유선 드릴에 연결하는게 귀찮아 무선 드릴을 각각 6만원, 2만원에 당근에서 중고 구입했다. 이중 6만원짜리가 괜찮은 거 같다.

 

주말에는 다이소, 다있소 등등 여기 저기 돌아다니며 공구와 재료를 대판 구입했다. 옥션에서 주문해서 배송 받은 것도 있다. 뭐가 필요할지 모르니 미리 필요할 거 같은거 다 사 놓는 수밖에 다른 도리가 없다. 엄청 비쌀 거 같지만 개당 2000원 정도고 비싸 봐야 5000원이라 다 해서 10만원도 안된다. 만원 넘는건 인두기가 고작이다.

스트립퍼 하나 샀더니 탈피하기 좋고 송곳이나 버어니어 캘리퍼스도 활용도가 높다. 원형컷쏘나 원형톱날도 나중에는 쓸 일이 있을 거 같다. 이중 특히 보강판과 플라스틱 고정에 쓸 볼트는 온라인에서 그렇게 찾아도 딱 맞는 걸 찾지 못했는데 운 좋게 정확한 크기를 구했다. 이런거 하나 구하는게 막상 닥치면 만만치가 않다.

또 뭐 쓸만한 거 없나 신소재에도 관심을 가지고 이것 저것 사 모아 봤다. 2000원짜리 도마는 플라스틱판으로 쓸려고 샀는데 일단 두께가 좀 얇고 풀배열을 앉히기에는 폭이 좀 좁다. 최소 배열로 만들 때는 클리어파일 희생 안하고 쓸 수 있을 거 같다.

 

다른 뭐 좋은거 없나 싶어 폭풍 검색해 본 결과 이런 걸 찾아 냈다. 있을 거 같던데 혹시 파나 싶어 검색했는데 명칭을 몰라 검색이 어려웠다. 정식 명칭은 Kailh switch connector이다. 또는 socket이라고 하는데 처음에 adapter로 검색해서 찾지 못했다.

이 부품을 살 수 있다는 걸 진작 알았으면 스위치 핀을 구부릴 필요가 없었는데 말이다. 이래서 아직도 공부를 좀 더 해야한다. 최대한 일찍 구해 보고 구할 수 있으면 이걸로 하고 아니면 그냥 스위치에 납땜해야겠다.

100 3만원인데 200 4만원이다. 옥션에서 주문했는데 해외 배송이라 2주 걸린다는데 통관 부호 넣으라는 문자는 평택시 비전동에서 왔다. 이것 때문에 개인통관부호라는 것도 받았다. 문자로 문의해 보니 중국 명절이라 3주 정도 걸린다고 한다.

네이버에서 좀 더 검색해 보니 국내에서 파는 곳도 있다. http://vctec.co.kr/ 이며 가치창조기술이라는 곳인데 부품/프로토타이핑-커넥터/마운팅/케이스 메뉴로 들어가 8번째 페이지를 보면 있다. 가격이 개당 거의 500원꼴이라 해외 구입보다는 훨씬 비싸다. 이 부품 외에도 여러 가지 전자 부품을 파는데 필요한게 더 있을 거 같아 sm/cr로 일단 회원 가입해 두었다.

재고가 있는데 고객 센터로 문의했는데 20개 한 묶음밖에 없고 미국에서 들어오는데 2주 이상 걸린다고 한다. 값도 비싸고 시간도 오래 걸려 일단 포기했다. 국내에서 파는 곳은 더 검색되지 않아 일단 주문할 걸 기다려 보기로 했다.

다음은 플라스틱판과 보강판을 겸할 수 있는 철판 보강판을 찾아 봤다. 공구만 갖추면 철판에 드릴로 구멍을 직접 뚫어 진짜 보강판처름 만들 수 있다. 이것도 검색이 좀 어렵긴 하지만 파는 곳이 있다. 스텐레스판과 알루미늄판 두 개를 구해 놨다. 기본 카테고리 270에 좌우 여백 5미리, 편집폭 60, 매크로폭 40에 좌우 가장자리 각 10씩하면 딱 폭 400이며 높이는 150이면 충분하다.

 

옥션에서 스텐레스판으로 검색해서 큐브메탈 판매자를 찾은 후 304, 1D, 두께 1.5, 가로 400mm, 세로 150mm으로 주문함. 가격 13000원이되 택배착불비가 6000원임.  강철판 1.2T 주문하면 11000원임.  착불 땜에 일단 보류했다가 일단 받아 놓고 보자 싶어 주문 넣음

네이버쇼핑에서 알루미늄판으로 검색해서 상페톡 판매자를 찾은 후 1.5T 생판 400 * 150으로 견적 메일 보냄. 두번 보내고 문자까지 보냈는데 답이 없음. 한참 후에 문자로 장당 6000원이라고 해서 두장 + 배송비 3000 = 15000에 주문 넣음

 

비싸 봐야 개당 2만원 수준이니 실패하더라도 큰 부담은 없다. 일단 주문해 놓고 올 때까지 기다려 보자. 소재가 바뀌면 작업이 좀 쉬어지고 여러 가지 시도를 더 해볼 수 있으니 투자할만 하다. 요즘 택배 파업이라 잘 안오는데 그래서 작업이 더 느려진다.

주문한 거 올 때까지는 딱히 할 일이 없어 선끼우기 놀이나 하고 있다. 1시간 했는데 15개 끼웠으니 속도가 나쁘지는 않다. 배선 고려하여 맵핑을 좀 변경해 볼까 했는데 그냥 두기로 했다. ETC에 연결되는 789만 선을 조금 길게 빼면 될 뿐 나머지는 특별히 멀리 이동하는 선이 없어 그냥 둬도 될 거 같다.

 

점심 때부터 점프선 연결을 시작해서 완료했다. 이제 숙달되니 시간당 15개씩 해 치울 수 있다. 음악 들으며 두시간 딱 일하니 연결이 완료되었다.

46개니 총 96가닥이다. 저렇게 많을줄이야. 저 엉킨 타래를 잘 정리해서 보강판을 통과행야 하는데 그게 참 난제다. 일단 상하좌우 4방향으로 묶어 봤다.

이렇게 하니 정리가 좀 된 거 같기는 한데 플라스틱판의 키 기둥에 걸리지 않게 정리하려면 이 작업도 만만치 않을 거 같다.

택배로 주문한 부품이 오기전까지는 할 일이 없으니 오늘은 납땜을 하기로 했다. 원래대로라면 하우징과 보강판을 먼저 만들고 보강판 구조에 맞게 선을 빼야 하는데 일단 납땜부터 해 놓고 나중에 조정하기로 한다.

납땜은 중학생 때 한두번 해 본게 다인데 인두를 관리하는게 만만치 않다. 납땜풀을 먹이고 인두팁에 납을 발라 보관해야 하며 예열과 부품 예열도 잘 관리해야 한다. 검색을 통해 납땜의 기본을 익힌 후 일단 연습부터 해 보았다.

2분 정도 예열한 후에 땜을 해야 하며 납을 너무 많이 묻혀서도 안된다. 선 두 가닥 꼬아 놓고 붙여 봤다.

 

이 정도면 그럭저럭 제법이다. 다음은 스위치에 선 꼬아서 납땜해 봤다. 황축 스위치는 써야 하니 청축 스위치 남는걸 실습용으로 썼다. 선을 꼬아서 걸면 쑥 빠지지면 납을 먹이면 잘 고정되어 있는데 선의 방향을 좌우로 벌리면 나중에 선끼리 꼬일 거 같아 수직으로 나란히 배열했다.

 

클램프 사다 놓은 걸로 고정해 놓고 선 꼬아서 걸고 땜하면 된다. 제법 그럴듯하게 되는 거 같아 자신감이 붙었다. 혹시 땜열에 의해 스위치의 기능에 문제가 생기지 않았을까 싶어 통전 시험을 해 봤는데 마땅히 시험해 볼 대상이 없어 텔레비전 리모컨 밧데리로 테스트해 봤다. 다행히 기능상 문제는 없는 거 같다.

스위치쪽을 탈피하고 동그랗게 고리를 말아야 하는데 이 작업도 꽤 시간이 걸린다. 적당한 두께의 기둥에 먼저 돌리면 될 거 같은데 면봉이나 드라이버는 너무 두꺼워 압정을 사용했다. 압정에 일단 말아서 모양 만들고 스위치에 거는 방식이다.

 

연습만 해 볼 수는 없으니 일단 QW 두 개의 스위치에 걸어 봤다. 이대로면 그냥 바로 땜해 버려도 될 거 같다. 위치가 헷갈릴 거 같으니 위쪽에 마스킹 테이프로 표시해 놓고 제 스위치를 찾아 건 후 공구로 선 살짝 눌러 놓고 납을 먹인다.

그런데 막상 땜질을 해 보니 오른손에 인두기, 왼손에 납, 그리고 선도 잡아야 하니 원래 손이 3개 있어야 가능한 작업인 거 같다. 두 개밖에 없으니 펜치같은 공구로 고정해 놓고 작업하는 수밖에 없다. 처음 해 보는거라 납이 좀 덜 먹어 제일 오른쪽 선이 고정되지 않고 덜렁거린다. 고리가 너무 크게 만들어졌고 납도 위쪽으로만 붙어서 그렇다. 납을 충분히 발라주는 수밖에 없다.

연습이나 함 해 보자 했었는데 그냥 진행해도 될 거 같아 쭉 작업했다. 이것도 하다 보면 요령이 생긴다. 고리 만들기는 옷핀이 두께가 딱 맞다. 여기다 걸고 두 바퀴 돌린 후 걸면 적당하다. 선 고정은 마스킹 테이프로 했다. 서너개 걸어 놓고 인두로 딱딱딱 쏴 주면 된다.

 

고리 부분으로 납이 스며들어 강도도 확보하고 플라스틱이 조금 가열되긴 하지만 녹을 정도는 아니다. 사람의 적응력은 참 대단한 거 같다. 내가 똑똑한거일 수도 있고. 이런식으로 작업해서 그냥 다 해 버렸다. 납 연기 때문에 창문 열어 놓고 환기하면서 했는데 다음부터는 마스크를 쓰고 해야겠다.

맵핑표 보면서 짝을 찾아 줬는데 다행히 땜을 잘못한 건 없었다. 이 상태로 키보드 조립해서 테스트해 보니 모두 제대로 위치를 잡았다. , 몇 가지 문제가 있는데 ㄹ이랑 ;이 가끔 접촉 불량이 발생하고 삐져 나온선 정리하느라 s의 묶음 고리를 실수로 잘라 버렸다. 키보드 다시 분리한 후 뒷판에도 납땜을 했다. 어차피 이 용도로 쓰기로 한 기판이라 아까워할 필요는 없고 이제 다른 용도로 쓰기도 어렵다.

뒷판은 평평해서 오히려 쉬울 줄 알았는데 납이 자꾸 이슬처럼 맺히는 현상이 일어났다. 부품도 적당히 예열한 후 납을 먹어야 잘 스며든다. 키보드 재조립하고 테스트해 보니 모든 키가 잘 입력된다.

이제 보강판 사이로 선이 잘 통과할 수 있도록 상하좌우 그룹을 잘 묶어야 하는데 막상 해 보니 선끼리 꼬여 있는 경우가 있다. 왼쪽으로 가야 할 선이 아래쪽으로 가야할 선 밑으로 지나가고 있다. 양쪽이 다 납땜되어 있으니 해결할 수가 없다.

납땜할 때 이런것까지 고려했어야 하는데 그건 미처 생각할 겨를이 없었다. 어쩔 수 없이 선을 자른 후 다시 이어 붙이는 수밖에 없다. 어떤 경우는 선이 짧아 길이를 늘려 줘야 하는 경우도 있는 Ctrl 키가 그렇다. 맵핑은 오른쪽 끝에 있고 키는 왼쪽 끝에 있으니 짧아서 늘려 줬다. 상하좌우 네 그룹으로 선을 나누고 중간에 아크릴 보강판을 끼웠다.

선이 통과하는 홀을 잘 파야 하는데 보강판으로 쓸 5T 아크릴판이 오지 않아 당장 작업하기는 어렵다. 두 가지 문제를 더 해결해야 한다. 우선 플라스틱판쪽 선이 지나가는 경로를 정리해서 스위치 기둥에 걸리지 않도록 해야 한다. 그렇지 않으면 기둥이 보강판에 딱 붙지 않아 울렁거릴 것이고 선 때문에 불룩해져 타이핑감이 나빠진다.

두번째는 앞판 높이인데 최초 가급적 낮게 하려고 15미리로 생각했으나 아래선이 지나갈 공간을 확보해야 할 거 같아 최소 20미리는 되어야 하지 않을까 싶다. 원본 키보드의 하우징 높이도 있어서 이 정도 띄우면 팜레스트가 필요할 거 같은데 어쩔 수 없다. 오늘 목재랑 아크릴 배송이 와 봐야 작업 계획을 짤 수 있을 거 같다.

최초 납땜 연습을 시작한게 오후 3 30분이고 4시부터 납땜을 시작해 오후 8시에 완료했으며 뒷판 납땜과 선 정리까지 10시에 끝냈으니 대략 6시간 정도 걸렸다. 작업 내도록 최신 가요 실컷 들었다. 다음번에 다시 한다면 이보다는 더 빠르게 더 정확하게 할 수 있을 거 같다. 스위치 컨넥터를 주문해 놨으니 더 깔끔하게 할 수 있지 않을까 싶다.

-----------------------

2 8

(여기부터는 소젯1호 키보드로 입력한 것이다)

밤새 푹 자고 일어나 오늘은 뭐 할까 생각하다 풀배열 배치도부터 그려봤다. 2호 키보드는 철판이나 알루미늄판에 실사용 가능한 걸로 만들되 풀배열 또는 직교 배열로 만들 계획이다. A4 한장에 다 그릴 수 없어 오려 붙였다. 편집 영역과 매크로 영역은 기본 배열과 5미리만 띄웠다.

길이는 400미리 정도 되어 텐키레스보다 약간 길고 높이는 비슷하다. 이 정도면 기존 기판 활용해서 얼마든지 만들 수 있을 거 같다. 이거 다 그려 놓고 혹시 택배 온 거 없나 싶어 문을 열어보니 목재가 와 있다. 마침 프레임을 만들 차례인데 정확하게 도착했다.

12T 4, 15t 2, 6.5t 자작나무 2, 6t mdf 4장 정도 주문했다. 넓이는 모두 380*150으로 같으며 미리 계산해 놓은 크기이다. 상하판은 그대로 쓸수 있으니 좌우 기둥부터 만든다. 점프선 공간 확보를 위해 아랫변을 20미리로 약간 늘리고 윗변은 최초 설계대로 45미리로 했다. 목공 작업을 위해 거실을 싹 비우고 목재 포장재로 바닥을 깔고 재단했다. 3 1000원짜리 클램프가 여러모로 큰 도움이 되었다. 반면 무선 전동 드릴은 막상 사용해 보니 힘이 많이 딸린다. 역시 유선 공구가 힘이 좋고 시원스럽게 잘 잘린다.

요래 놓고 기계톱으로 썰었는데 선 맞추는 건 어렵지 않으나 수직을 맞추는게 정말 어렵다. 오른손잡이가 톱을 중앙에 놓고 톱질을 하니 오려놓고 보면 절단면이 항상 비스듬하다. 톱질에도 정확한 자세가 중요함을 알 수 있으며 이것도 따로 배우고 연습해야 하는 모양이다.

 

 

할 수 없이 원래 재단되어 온 면을 최대한 활용해서 수직이 요구되는 부분에 쓰기로 했다. 아랫판은 6.5t 자작나무로 하고 기둥과 붙인 후 2미리 길이로 구멍을 뚫는다. 이런 얇은 길이를 엇다 쓸까 싶었는데 쓸데가 있네. 구멍 뚫고 가장 얇은 나사로 박으니 딱 맞다. 3미리 길이로도 뚫어 봤는데 헐렁해서 큰 나사를 써야 한다.

 

앞뒷판은 따로 만들지 않고 본체가 흔들리지 않게 막는 나무조각만 붙였다. 어차피 시제품이라 배선이 드러나는 것도 나쁘지 않고 USB홀이나 블루투스키가 노출되는 것도 좋다. 사이즈 맞춰 본체를 넣어 보니 딱 맞게 들어간다.

아랫면에 블루투스 스위치가 있는데 여기는 그냥 10미리 드릴로 구멍 하나만 뚫어 놨다. 오프셋이 좀 안 맞지만 전원을 켜고 끌 수는 있다.

상판은 구멍 네 개를 3미리로 뚫어 일단 고정부터 해 봤는데 잘 맞긴 하다. 이 보강판 위에 플라스틱 키보드를 얹고 그 사이로 배선이 통과해야 한다.

여기까지 작업중에 혹시나 싶어 문을 열어보니 또 택배가 와 있다. 요즘 택배는 소리소문없이 온다. 아크릴 5t를 상판으로 써볼까 하고 주문해 놓은 것이다.

당장 어디다 쓴다기보다는 나중에 어디에 필요할지 모르니 그냥 넉넉하게 주문했다. 풀배열 고려해서 폭 400미리로 주문했는데 조금 남긴 한다. 얇은 건 좋은데 목재에 비해 확실히 울렁거림이 있다. 이건 이번에는 사용하지 않고 그냥 목재를 쓰기로 했다.

다음은 상판에 배선 통과 홀을 뚫을 차례인데 가장 난이도가 높고 잘 해야 하는 작업이다. 플라스틱 키보드 크기에 맞춰 구멍과 지지대 자리를 그렸다. CK87이 넓다 보니 상판도 넓고 어쩔 수 없이 구멍까지 틈을 파야 한다.

뚫을 게 많아 저번에 사둔 컷쏘를 사용해 봤는데 훨씬 더 빠르고 정확하다. 잘 안 쓸거 같아 팔아 버리려고 했는데 놔두기 잘 한거 같다. 구멍은 둥근 드릴날을 사 두긴 했지만 선이 굵지 않으니 10미리 드릴로 2개씩 뚫어 해결했다. 이런걸 보면 아버지가 엄마한테 그 잔소리 들어가며 왜 공구 수집에 열광했는지 이해가 간다. 모양이 예쁘진 않아도 대충 완성했다.

다음은 이 구멍으로 배선을 통과시키고 키보드를 상판에 앉혀야 한다. 차칫하면 선을 끊어 먹을 수 있어 극도로 조심하고 주의해야 하는 작업이다. 오른쪽에서 왼쪽으로 상판을 밀어 넣었다. 아래 위 선 길이가 넉넉해 큰 문제없이 잘 들어간다.

일단 왼쪽부터 밀어 넣었는데 의도한대로 잘 자리 잡았다. 구멍이 좁아도 들어가 있기만 하면 되니 딱 좋다. 아래 위는 어차피 자동으로 맞게 되어 있다.

문제는 오른쪽인데 일부는 구멍으로 잘 들어 갔지만 일부는 선이 짧아 들어가지 않는다. 신축성이 없어 힘으로는 안되고 최대한 오른쪽으로 당겨서 밀어 넣었다.

그래도 안들어 가는 일부는 어쩔 수 없이 위로 이적시켰다.

대충 끼우는데는 성공했는데 키보드가 제자리에 오지 않고 오른쪽 위가 들린 모양새다. 왜 그런가 봤더니 위쪽 선 하나가 짧다. < 자리의 선인데 아래쪽에 있는 선을 위로 빼서 그런거 같다. 어쩔 수 없이 선을 잘라 길이를 늘리고 오른쪽으로 뺐다. 자르고 네 군데를 다시 잇고 테이핑까지 해야 하니 번거로운 작업이다.

다음은 키보드와 상판을 볼트로 고정한다. 6미리 MDF로 지지대를 만들고 키보드와 보강판 사이에 끼운 후 볼트로 조이면 된다. 구멍은 5미리 길이가 딱 맞았다. 그런데 이미 조립된 상태에서 드릴질을 하다보니 길이가 안까지 후비고 들어가 M자리의 선 하나가 말려 들어 끊어졌다.

긴급 보수했는데 상판이 끼워진 상태라 어렵다. 이거 연결했더니 이번에는 N자리가 안된다. 여긴 납땜이 떨어진 거 같은데 흔들어 주니 된다. 차후 이 두 키는 주의깊게 봐야겠다. 줄로 모서리 라운딩 처리하고 본체는 뒤쪽 양쪽으로 피스를 박아 고정했다.

이것저것 가공하느라 거실은 공방이 되었다. 몇개 되지도 않는 공구로 이 정도 공작을 할려니 시간이 많이 걸릴 수밖에 없다.

완성된 소젯 1호 키보드는 이런 모양이다. USB 연결해서 테스트해보니 모든 키가 잘 입력되고 맵핑도 제대로 되었다. 상판과 키보드를 고정하는 볼트가 위로 솟아 있는데 이건 아래쪽으로 두면 기판과 맞닿고 조으고 풀기가 어렵기 때문이다.

전면부 높이가 너무 높아 팜레스트가 필수이고 그래도 실사용은 쉽지 않을 거 같다. 바닥에 나사 때문에 책상이 긁히는 문제가 있어 신발을 신겨 주었다.

아침 9시에 작업 시작해서 저녁 6시에 끝냈으니 이 정도면 예상보다는 덜 걸린거 같다. 다음번 작업때는 다른 소재로 더 빨리 마칠 수 있을 거 같다.

----------------------------------

22 2 9

어제 공작을 마치니 대략 오후 6시였다. 제대로 연결되었는지 테스트만 좀 해 보고 바로 잠이 들었는데 일어나 보니 또 6시다. 몸 많이 쓰는 작업이 과히 쉽지 않았던 모양이다. 작업할 때는 몰랐는데 오른쪽 새끼 손가락에 생치기가 나 있고 톱밥을 많이 마셔서인지 호흡기가 조금 따끔거린다.

아침에 일어나 어제 공작 작업 내용을 일지에 정리했는데 처음부터 끝까지 소젯 1호 키보드로 타이핑을 해 봤다. 만들었으니 당연히 이걸로 사용성을 테스트해 보고 문제점을 발견해야 하기 때문이다. 물론 워드에서 직접 칠 수는 없고 연습 프로그램에서 친 후 붙여 넣었다. 최종적으로 후킹이나 디바이스 드라이버를 제작해야 직접 사용 가능하다.

 

- 상판 울렁거림은 거의 느낄 수 없었다. YUI 쪽이 좀 들뜨지만 저속으로 치느라 문제가 안된다. 상판 볼트 고정이 나름 효과가 있고 필요하면 더 삽입할 수도 있다. 1호 키보드가 이 정도면 양호한거다.

- 높이가 너무 높아 팜 레스트도 높은게 필요하다. 놀이방 패드 두장을 겹쳐 전용 팜레스트를 만들었다. 좀 둔해 보이지만 어쩔 도리가 없다.

- 이래 놓고 쳐도 각도가 너무 평평해 뒤에 팜레스트 하나 두께로 각도를 올렸다. 애초에 20미리, 45미리로 옆판을 제단한게 부족했다. 앞판 15, 뒷판 50 정도가 적당하다. 이거 옆판만 다시 만들어 갈아 끼우면 되기는 한데 일단은 이대로 쓰기로 한다. 각도가 생기니 좀 더 치기 편해졌다.

- 예상외로 배열 적응이 어렵지 않았다. 왼손 기울어진 각도가 아직 어색하지만 자리만 익히면 꽤 속도도 나오는 편이고 숫자 모드, 한영 전환, 편집 모드 등에 불편함이 느껴지지 않았다. 숙달하면 꽤 쓸만할 거 같다. 다만 1.5T 처럼 영문 한 글자가 대문자이면 Shift가 중간에 끼어야 하므로 이건 좀 불편하다.

- 엄지쪽을 약간 더 올리는게 좋을 거 같다. 3 2미리 아래쪽인데 엄지가 편안하게 닿는 곳은 여기보다 5미리 정도 위다. 일단 다음판에는 2미리 더 위로 바짝 올리고 장기적으로 2행은 16미리, 3행은 14미리 높이로 제작하면 엄지를 더 가까이 둬도 된다. 각도는 현재도 나쁘지 않은데 공백을 현재 15도에서 20도 정도로 약간 더 틀면 좋을 거 같다.

- Shift를 눌러 놓고 ㄹ을 누르면 다운되는 버그가 있다. 디버깅해 보니 Shift 자리에 글자가 없으면 tShift 0으로 바꿔 노말 문자를 읽도록 되어 있다. 그런데 자소 구분을 할 때는 bShift를 참고하도록 되어 있어 HanCode에 글자가 없으며 한글이 아닌 것으로 인식하는 문제가 있다. 일단 수정은 했는데 HanCode의 구조를 좀 더 정리해야할 거 같다.

- 한글 자음의 ㅍ, ㅋ이 제자리가 아니라는 점이 은근히 불편하다. 또 ㅌ, ㅊ도 원래 자리가 아니어서 쎈소리를 입력할 때마다 은근히 헷갈리고 속도가 떨어진다. 이럴 바에야 아예 쎈소리를 조합해서 제자리에서 입력하는게 어떨까 싶다. 물론 이것도 부작용이 만만치 않을 거 같은데 일단 옵션으로 만들어 놓고 테스트해 보기로 한다. 일단 두 가지 후보안을 만들어 봤는데 둘 다 마음에 쏙 들지는 않는다.

 

 

장점

단점

쎈소리 연타가 2, 1행이어서 쉬움

ㅁ이 2벌식 호환이 아님

빈도가 더 높은 ㅊ이 조합키임

ㅁ이 2벌식과 같음

빈도가 높은 ㅊ이 단독키임.

3, 1행 연타가 멀어서 자세 틀어짐

 

이 안은 1 6일에도 고민했었던건데 쌍, 쎈의 빈도가 예상보다 낮아 관뒀었다. 쌍은 어차피 Shift로 입력하니 관두고 쎈만 도입하자는건데 딱히 좋아 보이지는 않는다. 기존 배치도 비율 0.4%의 ㅋ만 빼고는 거의 제자리여서 그리 나쁘지 않았다. 채택하지는 않더라도 일단 옵션이라도 만들어 두자.

별 효용은 없을 거 같지만 제자리 원칙을 지킨다는 원칙에는 부합하고 각 언어의 오토마타는 문자 영역에서 해결하는 한 예로도 만들어 둘만 하다. 둘 중에는 그나마 ㅁ이 2벌식이랑 호환되는 게 나은 거 같다.

옵션 자체는 만들기 별로 어렵지 않다. Opt.modiStrong으로 쎈소리 조합 옵션을 만들고 차맷의 키맵핑을 4개만 변경하면 된다. 쎈소리 조합키는 캡션을 일단 ""으로 했다. 쎈키 누른 상태에서 ㅂㅈㄷㄱ을 입력하면 ㅍㅊㅌㅋ으로 바꾸기만 하면 된다. 문제는 ProcessHan에서 조립할 음소를 HanCode에서 찾는데 이 구조를 모르겠다는 것이다.

과거 기록을 살펴 봐도 이 부분에 대한 기록은 없고 코드 내의 주석이 다다. 내가 만든 코드인데 내가 이해를 못하고 있어 일단 분석부터 했다. JohabCode 룩업 테이블은 상용 조합형 한글 코드를 가지되 조합으로 만드는 음소에 대한 코드는 생략한 표이다. 상용 조합형 한글 코드는 다음과 같다.

이걸 차맷에 맞게 HanCode에 옮겨 kidx와 각 초중종 조합형 코드를 찾아 내도록 되어 있다. 그러다 보니 차맷에서 ㅊㅋㅌㅍ이 사라지면 이 코드에 대한 조합형 코드도 사라져 버린다. 어쩔 수 없이 modiString일 때는 초성, 종성의 조합형 코드를 변수로 직접 지정하고 조합 루틴에서 찾아 쓰도록 했다.

쎈 키를 두 번 누르면 취소하는 처리까지 했고 다른 키는 영향을 받지 않도록 했다. 툴바 제일 끝의 남은 여분 한칸에 이 기능을 할당하고 이미지도 적당히 그려 넣었다. OnOdle에서 상태 체크하는 코드도 작성했는데 editType에 대한 상태 체크 코드가 빠져 있어 같이 채워 넣었다.

기능적으로는 일단 대충 완성했고 동작한다. 집안열이 비어 있어 시원스럽고 손가락이 제자리에서 노는 것까지는 좋은데 조합키 연타가 영 매끄럽지 못하다. 약지 3행을 치고 1행을 다시 치는 것도 제자리를 벗어나는 것만큼이나 자세가 흐트러진다. 차라리 ㅁ자리에 쎈키를 두는게 어떨까 싶어 이것도 구현해 봤다. 이 옵션은 세 가지 상태를 순환한다.

 

새끼 끝자리를 치고 ㅂㅈㄷㄱ을 누르는 것은 굉장히 부드럽고 편안하다. 쎈ㅂ 연타도 그리 어색하지 않아 남은 한 키는 가장 빈도가 높은 ㅊ으로 뒀다. 이려면 ㅊ은 입력 방법이 두 가지가 되는데 차라리 이 자리에 ㅆ을 둘까 싶기도 하다. ㅊ이 320회인데 비해 ㅆ은 419회로 빈도가 더 높다. 아니면 아예 깔끔하게 비워 두든가.

이 안이 마음에 든다는 건 아니고 계속 테스트해 봐야 한다. 당장은 A 자리가 더 좋은 거 같은데 밀려난 ㅁ이 얼마나 불편할지도 점검해 봐야 한다. 옵션으로 만들어 놨으니 실습해 보며 검증을 거친 후 다시 생각해 볼 예정이다.

만들어 놓고 보니 이 옵션과 ㅗㅕ 교체 옵션이 충돌난다. CG 자리를 둘 다 건드리기 때문인데 여분 사용 옵션도 마찬가지이다. ㅗㅕ교체 옵션에 우선 순위를 주고 한번에 하나의 옵션만 선택하도록 했다. 어차피 테스트용이라 옵션끼는 상호 배타적이며 두 가지 이상을 같이 테스트할 경우는 별로 없고 정 필요하다면 확정 후 코드에 반영하는 식이어야 한다.

 - 인덴트를 얼마로 줘도 그다지 편안하지는 않다. 손가락 뻗는 각도를 정확히 계산한 것도 아니고 그냥 대충 기울인건데 이러다 보니 아래 위 키를 촉감으로 찾기 어렵다. 이럴 바에야 아예 인덴트는 빼고 직교로 배열한 후 좌우를 기울이는 방안에 대해 생각해 봐야겠다. 다음 키보드를 만들 때는 직교 전체 기울임으로 기획해 보기로 한다.

- 한참동안 소젯으로 타이핑하다 쿼티로 갑자기 돌아오니 원래 배열이 어색해 순간적으로 헷갈리는 현상이 있다. ''를 칠 때 자꾸 ''를 치고 있는데 ㅗ 자리가 헷갈린다. 두 키보드 사이를 왔다 갔다 하면서 쓰기가 쉽지 않아 일단 전환했으면 계속 하나만 사용해야 한다. 실사용 가능한 수준으로 만든 후 나부터 완전히 소젯으로 전환해야겠다.

------------------------------------

22 2 10

아침에 일어나 어제 만든 키보드를 보니 너무 높아 보이고 둔탁하다. 특히 전면부가 무려 6센치나 되어 일반 키보드의 두 배가 넘는다. 이러니 타이프치는 자세가 안나오고 불편하다.

 

전면부를 살펴 보니 본체 자체에 돌기가 있고 미끄럼 방지 패드도 2미리는 되어 보인다. 이걸 깍아내고 상판을 아래로 내리면 전면부 높이를 상당히 줄일 수 있을 거 같다. 또 뒤쪽을 높이면 각도도 자동으로 조절되니 고무판을 뒤에 대지 않아도 된다. 옆판을 10미리, 60미리로 다시 만들어 붙이기로 하고 공구를 다시 꺼내 톱질을 했다.

 

한쪽을 16미리로 잘못 재단해 하나를 새로 잘랐다. 이거 자르면서 톱질의 스킬이 늘었는데 톱날 끝부분보다는 앞부분으로 잘라야 떨림이 없고 수직으로 잘 잘린다. 역시 뭐든지 자꾸 하면 늘기 마련이다. 이전의 옆판에 비해 각도가 더 급해졌다. 새로 만든 옆판을 앞으로 약간 돌출시켜 고정하고 본체 뒤는 와셔로, 앞은 피스로 대충 고정했다. 

 

본체가 더 뒤로 이동함에 따라 블루투스 구멍 오프셋이 달라져 아래쪽에 구멍을 새로 뚫었다.

 

다 조립한 후 보니 앞쪽에 그래도 공간이 많이 남는다. 옆판 앞쪽 높이를 10보다 작게 했어도 될 뻔했다. 완성된 모습을 보자.

앞으로 쭉 빼는 바람에 폭이 3센티 정도 길어졌지만 각도는 더 편안해졌다. 이 작업을 하는동안 선이 하나도 안 끊어지고 잘 버텨준게 대견하다. 당분간은 이 형태로 계속 쓰기로 하고 소프트웨어나 잘 만들자.

 

여기까지 소젯 키보드로 타이핑을 했는데 느리면 분당 50, 좀 빨리 치면 70타 정도 나온다. 조금만 연습하면 100타는 무난히 넘을 거고 숙달되면 200~300타까지는 금방이다. 쎈소리 조합 기능은 대충 쓸만하다. ㅁ 자리가 바뀌어 헷갈리지만 불편한 정도는 아니고 익숙해지면 충분히 괜찮을 거 같다.

ㅁ이 그다지 불편하지 않으니 쎈 키를 3행에 두는 것보다는 2행에 두는게 확실히 더 감이 좋고 빠르다. ㅍ이 새끼 손가락 연타라 불편해 Z 자리에 ㅊ보다는 ㅍ을 두는게 더 나은 거 같다. ㅊ이 빈도는 약간 높지만 쎈ㅈ은 연타가 쉬워 ㅍ한테 자리를 내 주는게 좋겠다.

그런데 쎈소리 조합키의 캡션을 뭐라고 붙여야 할까? 키캡에도 표시해야 하는데 '' 이라고 하기는 유치하다. 예사소리에 비해 획이 한두개 더 있으니 +도 의미상으로 괜찮지만 기호랑 헷갈릴 것이고 ±는 수학 기호처럼 보인다. 실제 예전 LG폰에서는 획추가 버튼이 있었다.

학술적 정식 명칭이 뭔가 찾아 보았다. ㅆㄲ이 쌍자음으로 불리는 것에 비해 ㅊㅋㅌㅍ은 그냥 자음 홑낱자로 취급되며 별도의 이름이 없다. 나름 분류를 조사해 보니 ㅍㅌㅋ은 파열 거센음이고 ㅊ은 파찰 거센음이다. 어쨌든 쎈소리이다. 대표 쎈소리로 ㅋ을 갖다 놓으면 직관적이지 않고 ㅋㅌ을 나란히 또는 아래 위로 높으면 어떨까 싶기는 하다. 유니코드표에 ᅒ이 실제로 존재하지만 연습 프로그램이 안시로 되어 있어 출력이 안된다. ㈊㉪ 은 가능한데 일단 동그라미 ㅋ으로 선택했다. 쎈소리 조합 옵션은 다음 하나만 남긴다.

제자리 원칙을 강조하기 위해 특허도 이 옵션을 적용한 걸로 내야겠다. '옆판' 처럼 쎈소리가 다음 글자의 자음으로 올 때는 조합이 안되는 버그를 발견했다. ProcessHan에서 글자가 완성된 상태에서 자음 입력시 복자음이 아니면 새 글자로 독립하는데 이때 조합쎈소리의 코드를 적용하지 않아서이다. 디버그를 통해 쉽게 수정은 했는데 아주 시간이 지난 후에 이 코드를 보면 기억이 날려나 모르겠다.

쎈소리 옵션 켜 놓고 연습을 해 봤는데 ㅁ자리가 바뀌어서 그렇지 쎈소리 조합 때문에 불편한 건 별로 없는 거 같다. 아무리 새끼 손가락이라고 해도 기준 위치여서 연타를 눌러도 어색하지 않고 속도도 잘 나오는 편이다. 연습 프로그램에 리셋 기능이 없어 Esc는 다른 키보드에 눌러야 하는 불편함이 있어 Esc입력에도 리셋 기능을 넣었다. 타수 측정할 때 꽤 유용하다. BS가 없어도 예상 외로 수정이 편리하고 단어 처음 쌍자음 연타도 꽤 쓸만하다. 시제품을 만들어 놓으니 이런 검증이 가능해 좋다.

쎈소리 옵션이 무난해 보이고 또 한글이라도 제자리 원칙을 잘 지킨다는 것을 강조하기 위해 집안열에는 디폴트로 문자를 배치하지 않는 것이 좋을 거 같아. 기존의 modiStrong 옵션을 디폴트로 선택하기 위해 반대 옵션인 strongKey 옵션을 만들고 이 옵션 선택시 쎈소리키를 독립적으로 배치하기로 한다. 즉 쎈소리 조합이 디폴트이고 옵션 선택시 조합없이 독립키를 배치할 수도 있다.

옵션이 왠만큼 정비가 된 거 같아 툴바를 다시 한번 정비했다. 통짜 이미지라 순서를 조정하는게 좀 번거롭다. 키배치에 영향을 주는 옵션을 한 곳에 같이 모아 두었다.

소젯 한글 자판의 세 옵션이 배타적이라 같이 선택하기는 어렵고 이 옵션을 조합하는 방식에 대해서는 세심하게 테스트해 보지 않았다.

------------------------------

22 2 11

쎈소리 옵션을 켜 놓고 타이핑을 장시간 해 보니 오른손에 비해 왼손, 특히 새끼 손가락이 은근히 아프다. 조합키를 누르는데 익숙치 않아 그럴 수도 있고 왼손에 부담이 좀 많이 가서 그럴 수도 있는데 오토마타가 바뀌었으니 통계도 다시 내 볼 필요가 있다. 랭킹의 한글 통계를 다음과 같이 수정했다.

 

- 자음, 모음은 굳이 구분할 필요 없고 전체 음소에 대한 비율을 계산한다.

- 음소 빈도와 키입력 빈도는 구분해서 따로 통계를 낸다.

- 손가락 빈도와 행 빈도를 계산한다.

- 쎈소리 조합 옵션의 변경에 따른 차이를 뽑아 본다.

- 공백과 마침표도 주요 구두점이므로 통계에 포함시켰다.

 

이 통계를 수정하는데 대략 2~3시간 정도 걸렸다. 통계 대상 키맵부터 수정하고 쌍소리는 Shift로 대체하고 통계 출력 방식도 수정했다. 결과는 다음과 같다. 키 누른 횟수의 내림차순 정렬이라 ㄴ보다 ㅓ가 더 앞에 있다.

  

ㅇ은 문자와 키 횟수가 같지만 ㅏ는 ㅑ와 ㅘ 등에도 들어 있어 문자에 비해 키가 101 * 2 + 173 = 375번 더 많게 나타난다. , , ㅌ은 음소는 있지만 조합하는 식이라 쎈키와 ㅈ, , ㄷ에 키 횟수가 더해지는 식이다. 좌우 비율은 딱 절반씩이라 균형이 맞게 행 비율도 26:44:15:13이면 나름 괜찮은 편이다.

왼새끼가 오른새끼에 비해 2배 이상 과다한 부담을 지고 있는 것으로 나오지만 이는 오른새끼에 할당된 ;"=$@ 등에 대한 부담이 통계에 잡히지 않아서이다. 오른약지가 마침표까지 고려해도 부담이 덜한 편인데 이건 2벌식 특성상 어쩔 수 없다.

왼손 엄지도 부담이 덜한 거 같지만 숫자가 많이 나오는 문장이나 편집을 자주 한다면 이 비율도 올라간다. 결론적으로 현재 분담율은 비교적 합리적인 셈이다. 쎈소리 조합을 하지 않을 때의 통계는 다음과 같다.

  

쎈 키를 누르지 않으니 총 타수가 693타 줄어들고 왼손 부담율이 50.8에서 50.1로 약간 내려간다. 왼새끼 부담이 4.3%에서 2.9%로 감소하는 반면 왼집게 부담이 15.6에서 16.4로 증가한다. 그 외 나머지 손가락이나 행에는 부담율 변화가 별로 없다. 이 정도 통계 결과면 타수가 1.6% 증가하고 왼새끼에 부담에 좀 증가한다는 것 외에는 치명적이지 않아 제자리 원칙을 고수할만하다.

한글 음소 통계는 개요에 따로 정리해 두었다. 음소 빈도와 키누름 빈도가 다르고 오토마타의 영향을 받기 때문에 현재 오토마트 기준으로 뽑은 통계가 유효하다. 그러나 2벌식과의 호환성을 유지해야 하과 좌자우모의 원칙을 지켜야 하는 한계가 있어 통계대로 음소를 배치할 수는 없다. 쎈소리 조합에 의한 부담도 변화를 검증하기 위한 통계일 뿐이며 결과적으로 채택해도 될만한 오토마타임을 확인했다.

 

점심 먹고 잠시 낮잠을 잤는데 깨다가 얼풋 이런 생각이 들었다. 쎈소리 조합키를 눌렀다가 한번 더 누르면 취소하는 걸로 했는데 그러지 말고 ㅊ을 입력하면 어떨까? 쎈ㅈ을 누르는 것보다는 쎈을 두 번 누르는게 더 쉽고 ㅊ의 빈도가 높으니 실용성 있다. 일어나서 오토마타 수정해 보니 괜찮은거 같아 채택하기로 했다.

이렇게 되면 쎈소리의 캡션은 ㉪이 아니라 ㉩이어야 적당하다. 두 번 누르는 것도 일종의 조합이지만 연속 두 번이라 좀 쉽다. 남은 ㅌ은 0.65%, ㅋ은 0.21%이나 둘 다 합쳐 빈도는 0.86% 100번에 1번 미만의 확률이다. ㅊㅍ도 조합으로 입력할 수 있어 이 둘은 입력 방법이 두 가지인 셈이다.

 

그런데 이렇게 바꿔 놓고 또 생각해 보니 쎈ㅂ이 연타가 아닐 방법이 있으니 차라리 단독키 하나 남은거에 ㅊ을 주고 쎈키 두 번은 ㅍ으로 만들면 되지 않을까? 이렇게 되면 센소리키의 캡션은 ㉬이 되어야 한다. 이건 테스트해 보나 마나 편의성은 마찬가지이고 빈도가 약간 개선되는 정도이다.

그렇다면 여기서 한단계 더 나아가 쎈소리 조합 비율이 1%미만이라면 굳이 ㅁ을 저 외진 곳으로 쫒아내지 않아도 되지 않을까? 2벌식 호환성을 더 확보할 수 있어 거부감이 덜하고 익숙해지기도 쉽다. 이때는 3 1, 2열의 배치에 따라 다음 두 가지 안이 또 나온다. 하나의 아이디어로부터 파생되는 변화가 상당하다.

 

ㅊ은 320회인데 비해 ㉬은 ㅍ 282 * 2 + 281 + 90 = 935로 빈도가 월등히 높으니 새끼보다 약지에 주는게 합리적이다. 이 경우 가장 푸대접을 받는게 ㅌ인데 0.65%의 확률이라도 3, 1행 연타가 그다지 쉽지 않다. ㅋ은 0.21%인데다 두 손가락이 좀 멀어 연타하기는 더 쉬워 큰 문제가 되지 않는다. 

ㅊ㉬안을 선택하고 시험해 보니 역시 ㅌ 입력이 불편하고 약지로 3행 두 번 누르는 것도 그다지 쉽지 않다. 하지만 연타가 센ㅂ처럼 역방향은 없고 센ㅈ처럼 같은 손가락이 아니라는게 다행이다. 쎈소리보다는 ㅁ이 제자리를 찾아와 이게 더 좋은 거 같다. ㅁ의 빈도는 무려 2.7%로 쎈소리를 다 더한 것보다 높다.

배치를 수정했으니 오토마타가 바뀌었고 따라서 통계도 또 수정해야 한다. ㅁ은 원래 자리인 1 2행에 복귀하고 조합시 ㅊ을 1 3행에 두고 ㅍ은 쎈키 두 번으로 조합하도록 했다. 쎈키는 2 3행으로 이동한다. 그리고 ㅊㅌㅍ이 셋다 비율 0.7로 나오는데 소수점 두자리로 출력하여 0.75, 0.66, 0.66으로 차이를 분명히 표시했다.

총 타수가 46360에서 46322 38타 줄었는데 단독키가 된 ㅊ의 횟수 320이 줄고 조합키 ㅍ의 282회가 늘어났기 때문이다. 계산은 딱 맞고 전체 순위에는 심한 변화가 없어 통계 결과만 업데이트해 두고 순위 정리해 놓은 것은 따로 수정 안해도 될 거 같다. 일단 이 배치대로 확정해 놓고 좀 더 테스트해 보자.

----------------------

22 2 12

오토마타가 바뀌었으니 소개 ppt 문서도 갱신했다. 쎈소리 조합 입력 방법 내용 추가하고 쎈키 독립 배치 옵션에 대한 설명도 작성했다. 그외 예전 캡처로 들어가 있던 부분 교체하고 ㅎㅗ 교체시 ㅊ이 남아 있는 버그도 찾아 수정했다. 줄간을 1.5배로 늘려 읽기 시원하도록 했으며 현재 분량은 35페이지이다. 앞으로도 점점 더 늘어나겠지만 읽고 개념을 파악하는데만도 시간이 엄청 많이 걸릴 거 같다.

쎈소리 입력 방법이 아무래도 좀 어색하고 이대로 릴리즈하면 두고 두고 까일 거 같아 생각이 많다. 누워서도, 밥먹다가도 계속 이 생각만 하고 있다. 심지어 두 키를 한꺼번에 누르는 방식까지도 생각해 봤다. 예를 들어 ㅂㅈ을 같이 누르면 ㅍ이고 ㅈㄷ을 같이 누르면 ㅊ이다. ㅋ은 옆칸이 비었고 제자리를 벗어나니 ㅇㄱ정도가 적당하다. 그러나 이건 더 어색한 방법임이 분명하고 누르는 동작만 쓴다는 원칙에도 부합하지 않다.

㉬㉬을 두번 누르는 방식을 ㅍ으로 인식하는 방법이 꽤 괜찮았다는 생각이 들었다. 그러다가 ㉬키를 좀 더 활용해 보자 싶어 Shift+㉬을 ㅌ으로 인식하는 아이디어가 떠올랐다. 좀 쌩뚱맞지만 ㉬ㄷ보다는 더 치기 쉽고 접근성도 높다. 이 기능까지 추가하면 ㅊ은 단독키 ㅍ, ㅌ은 ㉬으로 입력 가능하고 조합은 제일 빈도가 낮은 ㅋ밖에 없어 입력 부담이 확 떨어진다. 꽤 괜찮을 거 같다는 생각까지만 하고 자바 원고 교정 보느라 구현은 하지 않았다.

그러다 시장을 갔는데 장보다가 또 새로운 아이디어가 떠올랐다. Shift+㉬이 가능하다면 Shift+다른키도 가능하다. ㅂㅈㄷㄱ 아래키를 Shift와 누르면 ㅍㅊㅌㅋ으로 인식하면 된다. 멀리 떨어진 ㅍㅊ은 단독키를 주고 ㅌㅋ만 이 방법을 적용하면 빈도상으로 보나 위치상의 직관성으로 보나 괜찮은 방법인 거 같다.

Shift는 어차피 엄지로 누르니 연속 입력해도 부담이 없고 ㅌㅋ의 자리가 기준행이어서 입력도 쉽다. 또 예사소리와 쎈소리의 수직 위치가 일치해 외우기 쉽고 직관적이다. 이거 연구하면서 2벌식 자판은 1행 예사소리 ㅂㅈㄷㄱ의 역순으로 3행의 쎈소리 ㅋㅌㅊㅍ이 배치되어 있음을 발견했는데 대충 빈도와는 일치한다. 여기까지 일단 생각해 두고 혹시 더 좋은 아이디어가 떠오를 수도 있으니 시간차를 두고 구현해 보기로 한다.

오늘이 가기 전에 일단 만들어는 보자 싶어 코드로 구현해 봤다. 차맷만 고치면 되는게 아니라 코드에 이미 작성해 놓은 strongKey 옵션 처리문까지 다 주석 처리하느라 시간이 좀 걸렸다. 이 코드는 별도의 백업이 없어 여기에 주석으로 남겨둔다. 다음에 또 필요할지도 모르니까.

 

// 쎈소리 독립키 옵션이 꺼져 있으면 조합에 의한 쎈소리를 만든다.

//bool bstrongKey = true;

//WORD modiCho;

//WORD modiJong;

//if (Opt.strongKey == false) {

//  int modiKey = K_X;

//  if (kidx == modiKey) {

//       // 이미 들어가 있는 상태에서 또 눌렀으면 둘 다 지워 취소하고 ㅊ을 입력한다.

//       if (KeyQueue[0].kidx == modiKey && KeyQueue[1].kidx == modiKey) {

//           KeyQueue[0] = KeyQueue[2];

//           KeyQueue[1] = KeyQueue[3];

//           KeyQueue[2] = KeyQueue[4];

//

//           bstrongKey = false;

//           modiCho = 19;

//           modiJong = 28;

//       } else {

//           // 처음 큐에 들어가는 것이면 이미 기록했으므로 더 기록할 필요 없다.

//           return;

//       }

//  }

//

//  // 쎈 키 입력 후 ㅂ, , , ㄱ을 눌렀을 때. 두 번 눌러 이미 ㅍ을 결정했으면 더 볼 필요 없다.

//  if (KeyQueue[1].kidx == modiKey && bstrongKey == true) {

//       // ㅂ을 ㅍ으로 바꾼다. 조합형 코드표에서 19는 초성 ㅍ코드이고 28은 종성 ㅍ코드이다.

//       // 아래 조합 루틴에서 쎈소리 조합키 상태이면 HanCode가 아닌 미리 대입해 놓은 변수에서 초성, 종성 코드를 구한다.

//       if (kidx == K_Q) {

//           bstrongKey = false;

//           modiCho = 19;

//           modiJong = 28;

//       }

//       // ->

//       if (kidx == K_W) {

//           bstrongKey = false;

//           modiCho = 16;

//           modiJong = 25;

//       }

//       // ->

//       if (kidx == K_E) {

//           bstrongKey = false;

//           modiCho = 18;

//           modiJong = 27;

//       }

//       // ->

//       if (kidx == K_R) {

//           bstrongKey = false;

//           modiCho = 17;

//           modiJong = 26;

//       }

//  }

//}

....

          //if (bstrongKey) {

              Code = kbd.Map[kidx].HanCode[b][CHO][tShift];

          //} else {

          //  Code = modiCho;

          //}

 

2벌식과는 자리가 하나도 안 맞지만 예사소리 바로 아래에 쎈소리가 있어 외우기 좋고 덜 헷갈린다. 엄지로 shift를 누른 후 2행의 키를 누르는게 어렵지도 않고 익숙해지면 속도도 꽤 나올거 같아 일단 마음에 드는데 좀 더 오래 실사용해 봐야겠다.

통계도 수정해 놨는데 Shift 799에서 1172로 늘어났고 대신 쎈키는 사라졌다. 타수는 약간 늘고 왼 엄지 비율이 1.7에서 1.5, 왼손 비율이 50.1에서 50.5로 약간씩 증가한다. 배치에 영향을 미칠만큼 큰 변화는 없는 셈이다. 가이드의 쎈소리 입력 부분도 수정해 두었다.

-----------------------------------

22 2 16 - 소젯 2, 후킹

사흘간 자바 2판 원고가 넘어와 교정을 보느라 키보드 작업은 잠시 손 놓았다. 소스 정리 좀 하고 툴바에 툴팁을 달아 주는 정도로 잔손질만 했다. 툴바의 캡션이 너무 핵심적이고 짧다 보니 의미를 파악하기 힘들고 시간이 오래 지나면 내가 봐도 모를 거 같아 상세한 설명을 달았다.

어제는 출판사 가는 길에 의자 하나 사오고 창모형 사무실 방문해서 키보드도 보여 주고 왔다. 여러 사람 의견을 수렴할 필요가 있어 키보드 시제품을 보여 주고 있다.

윤팀장님은 그냥 저냥 괜찮아 보인다는 의견이고 기존 키보드가 좀 불편한 면이 있다는데 동의하는 정도일 뿐 특별한 코멘트는 없었다. 시제품 보고 저걸 다 만들었냐고 약간 놀랬다. 상장하기 전에 투자하자고 꼬셔 봤는데 웃기만 할 뿐 넘어오지 않았다. 그래도 pt하는 시간이 길었는데도 지겨워하지 않고 잘 들어 주었다. 흥미는 있는 모양이다.

창모형은 좌우 분리나 인덴트, 엄지키 배열 등에는 별다른 이견을 제시하지 않고 괜찮아 보인다고 했다. 여러 가지 의견을 제시했는데 PrtSc, Break 등까지 다 생략해 버리고 너무 컴팩트하면 이런 이유로 쓰지 않은 사람이 많을 것이다, 키보드 면적이 중요치 않으니 있는건 다 넣어야 한다는 의견이다. 자신은 Win, Break, 넘패드까지 아주 잘 활용하고 있는데 이런게 갑자기 없어져 버리면 불편해 쓰지 못할 것이라고 했다.

나는 모두를 만족시키자면 아무도 만족시키지 못하니 여러 사람 의견을 참고하되 내가 먼저 이상형을 제시하겠다고 했다. 창모형은 이런걸 완성하려면 한사람의 헌신과 여러 사람의 조언이 필요하다고 했는데 이에는 동의한다. 결국 헌신해야 할 한사람이 나인 셈이고 여러 사람에게 보여 주고 의견을 구하라는 것이다. 그러나 이사람 저사람 얘기 다 듣다 보면 죽도 밥도 안된다는 생각이 들었다. 많이 듣고 많이 참조하되 일단은 내 고집대로 진행할 필요가 있고 채택하지 않은 의견에 대해서는 분명한 이유를 댈 수 있으면 된다. 편집 영역에 Pause, ScrL, Break 정도는 넣어서 79키로 해도 될 거 같고 얘들을 매크로키에 기본 할당해 둬도 될 거 같다. 이전을 위해 키 개수를 임시적으로 늘려 두었다가 필요 없다고 느껴질 때 빼는 것도 괜찮은 작전이다.

타겟을 명확히 하라는 조언도 했는데 일반인이 키보드를 그리 많이 쓰지 않아 굳이 익숙한 걸 바꿀 이유는 없다는 것이다. 키보드를 많이 쓰는 편집자나 속기사 등을 타겟으로 해야 한다는 건데 맞는 얘기이다. 이미 익숙한 사람이 좀 더 빠르다고 해서 이걸 바꿀 이유가 없고 웬만해서는 바꿀려고 하지 않는다. 소수의 일부 영역이라도 특화된 부분이 있어야 알릴 수 있고 새로 배우는 세대가 관심을 보일 것이다. 나는 0.01%의 점유율만 가져도 성공으로 볼 수 있고 내가 완성을 못해도 다음 작업자에게 참고만 되어도 좋겠다고 했다.

사업을 할려면 크라우드 펀딩을 해 보라고 조언해 줬다. 킥스타터, 인디고고 등에 아이디어를 제시해서 투자받아 진행하라는건데 사실 나도 생각해 본 적은 있지만 아직 시제품조차 완성되지 않아 특허부터 내고 고려해 볼 생각이다. 펀딩은 못 받더라도 적어도 제품을 알리는 효과는 있어 시도해 볼만 하다. 후킹으로는 한계가 있으니 결국 디바이스 드라이버를 만들어야 하는데 형이 속기 키보드 드라이버를 만들어 본 적이 있다고 하며 WDM(=DDK) 안에 샘플도 있다고 한다.

아직 많은 사람의 조언을 들어본 것은 아닌데 대부분의 반응이 비슷할 거 같다. 어차피 익숙해진거 안 바꿀 거고 조금이라도 다르면 적응하기 어렵다는 거다. 결국 잘 만들어 놔도 알리는 것조차도 쉽지 않고 대중화는 더 어렵다. 기존 키보드를 압도할 만한 요인이 있어야 하고 더 변형이 필요 없을 정도로 완성도가 높아야 한다. 단기간에 성과를 바래서는 안되며 최선을 다 해 만들어 두고 점점 퍼져 나가도록 하는게 최선이다.

 

두 사람에게 시연을 해 본 결과 한글 차맷은 어차피 2벌식 호환에 대한 제한이 있어 별다른 이견이 없지만 영문 배열에 대해서는 여러 가지 이견이 나올 수 있다. 확실한 근거를 제시하기 위해 좀 더 많은 배열을 점검해 보는게 좋겠다는 생각이 들었다.

dist5만 해도 충분하지만 이왕 시간이 남으니 dist6도 돌려 보기로 했다. 작년 9 12일 완료하고 5개월간 관뒀었는데 그 기간 동안 돌렸으면 꽤 많이 돌렸을 것을 하는 아쉬움이 있다. 오늘 16일 점심 12 30분부터 시작해서 새로 돌렸는데 800조개 정도로 추산되니 대략 1년 가까이 걸리지 않을까 예상된다.

지금은 랭킹 프로그램을 더 최적화하기 어렵고 이미 충분히 최적화되었으니 이 상태로 그냥 돌려만 보자. 다 못 돌리더라도 dist5보다 감점이 낮은 배열이 나올 수도 있고 그렇지 않더라도 최소한 dist5 배열을 채택한 이유라도 만들 수 있지 않을까 예상된다. 어차피 특허 내고 시제품 만들고 테스트하는데 1년은 더 소요될 예정이다.

 

다음은 옵션을 좀 조정했다. 한글 차맷의 여분키를 쓰는건 좋은데 ㅆ의 접근성이 떨어지고 ㅑ, ㅛ는 빈도상 굳이 여분까지 할당할 필요는 없다. ㅕ는 1.64%로 단모음 ㅔ의 1.47%보다 높고 ㅛ, ㅑ는 각각 0.3, 024%로 굳이 여분키까지 할당할 필요가 없다.

ㅆ의 빈도는 0.98%로 꽤 높아 ㅊ 0.69, , 0.66보다 높으며 심지어 마침표의 0.91%보다 더 높아 여분키를 쓸만 하다. 그래서 여분은 ㅕ, ㅆ 두개만 배치하되 집게 안쪽열 기준 위치에 배치하는 걸로 했다.

이 옵션은 장기간에 걸친 테스트와 점검이 필요하다. 기준 위치에서 두 번 누르는게 좋은지, 아니면 자리를 약간 벗어나더라도 한 번 누르는게 효율적인지 실사용하면서 점검해볼 필요가 있어 옵션으로 둘만하다. 지금 생각으로는 그래도 제자리가 낫다는 느낌이다.

, ㅗ를 2벌식 위치에 놓는 옵션은 일단 만들어는 놨지만 채택 가능성은 거의 없다. 만약 이 옵션을 쓴다면 ㅎ의 원래 자리에 ㅌ을 놓고 ㅗ의 원래 자리에 ㅕ를 넣을 수는 있지만 제자리를 심각하게 벗어난다는 면에서 바람직하지 않다. 쎈소리 독립키 옵션도 제자리에서 Shift 조합이 더 나은 거 같아 채택 가능성이 낮다. 각 옵션은 서로 배타적으로 선택하고 우선 순위를 부여해 방해하지 않도록 했다.

 

시제품 1호를 만들어 테스트해 보니 키배치에 대해서는 그럭 저럭 만족할만한 테스트가 된다. 그러나 풀배열이 아니다 보니 여전히 실사용하기는 어렵고 기존 키보드를 완전히 대체할 수 없다. 왼쪽의 기울어진 각도도 여전히 문제다. 후킹이든 디바이스 드라이버든 만들려면 풀배열 시제품이 있어야 한다.

1호는 비록 최소 배열로 나무로 둔탁하게 만들었지만 2호는 더 쎄련되게 발전할 필요가 있다. 그래서 알루미늄판과 스텐레스판을 주문해 놨다. 풀 배열 고려하여 400 * 150 크기인데 텐키레스보다는 35미리 길고 풀배열보다는 35미리 짧아 중간 크기이다. 알루미늄은 6000 2장과 배송비 3000원까지 15000원이고 스텐은 13000원에 배송비 6000원 착불로 냈다.

 

똑같이 1.5T인데 막상 두께를 재 보면 알루미늄보다는 스텐판이 더 두꺼워 보인다. 표준 스위치의 걸쇠가 1.5여서 둘 다 스위치를 끼우는데는 별 문제가 없다. 휨 강도는 스텐판이 더 강직해 보이며 웬만해서는 휘지 않을 거 같지만 중간에 보강 기둥 하나 정도는 더 세워야 할 거 같다.

2호 시제품을 만들기 위해 3가지 조건을 만족해야 한다. 우선 스위치에 직접 납땜을 하는건 번거롭고 재배열에도 좋지 않으니 컨넥터가 필요한데 이건 배송 오는데 2주 걸린다고 했으니 조금만 기다리면 된다. 최장 3주 걸린다고 했는데 조회해 보니 아직도 한국으로 배송중이다. 컨넥터가 있으면 스위치를 핫스왑할 수도 있고 배선을 과다하게 길게 만들 필요도 없어 두께를 절약할 수 있다.

점프선은 두개 한묶음인 걸로 구할 예정이다. 0.3미리 단선으로 묶여 있는거면 배선하기도 편리하고 선끼리도 덜 꼬일 거 같다. 요게 20센치인데 10 1400원이다. 둘둘 말려 있는건 90센치 10선이 4100, 4.5미터가 6000원 정도인데 이거 몇 묶음만 있어도 될 거 같다. 내부 단선의 두께에 대한 설명이 없는데 대충 맞을 거 같다.

 

 

4.5미터 짜리 하나, 유연납 2, 카일 스위치 커넥터 1개 같이 주문했다. 커넥트는 다음주에 재고가 들어온다는데 일단 하나 있다고 하니 그거부터 받아 보고 다시 주문해야겠다. 3주 걸린다는건 언제 올지 모르니 하나 더 따로 주문했는데 이러다 보니 돈이 엄청 들어간다. 새로 가입한 가치 장조 기술 사이트는 예치금도 없고 신용 카드 결제도 어려워 결국 무통장 입금했다. 점점 노인이 되어가는 느낌이다.

 

두 번째로 컷팅을 하기 전에 컷팅 도면을 새로 만들어야 한다. 2호는 기울어진 형태가 아닌 직교 형태로 만들 계획이다. 직교 형태를 ortholinear(똑바른 직선이라는 신조어)라고 하며 기울어진 형태는 Staggered라고 한다. https://gigglehd.com/gg/review/4460917 여기에 직교 키보드 관련 내용이 좀 있는데 타입 메트릭스는 나도 가지고 있는 키보드이다. 이 후에 47키의 플랑크(Planck) 12개의 숫자행을 한행 더 얹은 프리오닉을 만들었다고 한다.

 

플랑크의 키 개수가 소젯 최소 배열과 거의 비슷하지만 엄지 활용도가 떨어진다는 면에서 조금 다르다. 각 키의 맵핑을 조정할 수 있도록 되어 있는데 이러면 변형이 많고 바로 사서 쓸 수 없어 좀 골치가 아프고 초보자가 하기는 쉽지 않다. 맵핑을 직접 변경하는 방식은 번거롭고 어려워 미리 세팅한 옵션 정도만 제공하는 것이 바람직하다.

사실 전에도 직교 배열을 생각했었고 예전 특허에도 직교 형식의 배열이 있었다. 이 시점에서 직교 배열을 고려하는 이유는 여러 가지가 있다.

 

1. 시제품 1호가 인덴트 방식이니 2호는 다르게 만들어 봐야겠다. 어차피 만들 시제품이면 각각 달라야 이것 저것 테스트를 다양하게 해 볼 수 있다.

2. 인덴트를 어떻게 조정하더라도 모두에게 맞을 수 없고 최적값을 찾는게 거의 불가능하다. 현재 19미리 피치에 3미리 인덴트를 줬으니 행간 15.7% 들여쓴건데 테스트해 보면 적응하기 쉽지 않고 쿼티로 돌아오면 또 헷갈린다.

3. 어차피 좌우 분리형이면 손목을 꺽을 필요 없이 좌우 전체의 각도를 기울인 직교 형태가 이상적이다. 인덴트 생각할 필요 없이 좌우 키그룹의 거리와 각도로 조정하면 된다. 거리와 각도까지 조정할 수 있어 변화를 줄 여지가 더 많다.

4. 트리플키로 만들거면 이동 거리가 최대한 짧아야 하니 이때는 인덴트를 적용해서는 안되며 수직으로 아래 위에 붙어 있어야 한다. 최종적으로 원하는 형태는 인덴트가 아니라 직교 형태이다.

 

직교 배열이 과연 덜 헷갈리는지 타입 메트릭스 키보드를 꺼내 테스트해 봤다. 왼쪽에는 이 키보드를 약간 기울여 놓고 오른쪽은 소젯으로 쳐 봤다. 좌우를 다른 키보드로 입력해도 잘 된다. 수직 위치가 약간 다르지만 각도 테스트에는 적합하다. ㅎ과 ㅅ을 찾는데 별 에러가 없고 바로 아래이니 항상 정확하며 익숙해지기도 쉽다.

왼쪽이 직교 배열이면 확실히 아래 위 구분이 잘되고 항상 일관된 이점이 있다. 각도가 조금 맘에 안들면 자판 전체를 기울여 버리면 되고 좌우손이 너무 붙었으면 거리를 띄워 버리면 된다. 직교는 한쪽 자판 내에서는 형태가 고정된다는 면에서 바람직하다. 트리플 배열로 가는 중간 단계로도 딱 적당하다.

타입 매트릭스 키보드는 전에 잠시 사용해 봤는데 다시 보니 편집키의 Home, End 키 구조가 소젯이랑 같다. 그리고 Copy, Paste를 어떻게 조합하나 키메시지 프로그램으로 살펴 봤더니 Ctrl+C, Ctrl+V가 아니라 Ctrl+Ins, Shift+Ins 조합키로 되어 있다. 왜 이렇게 해 놨는지 이유는 정확히 알 수 없지만 아무튼 클립보드용 키의 스캔코드가 별도로 정의되어 있는 것은 아니다.

일단 좌우를 직교로 배치하고 10도 정도 기울여 보면 이런 모양이 된다. 지면에 인쇄하기 위해 일단 붙였는데 대충봐도 각도가 좀 작다. 어차피 오려서 쓸거라 도면상의 기울기는 중요하지 않다.

각도는 거리에 비례한다. 멀수록 수평에 가깝고 가까울수록 많이 기울여야 한다. 만약 두 손의 거리가 어깨만큼이라면 완전 수평이면 되고 가까워지면 팔이 기울어지니 각도를 줘야 한다. 거리와 각도의 함수 관계를 찾기 위해 초안을 오려 놓고 직접 손을 얹어 볼 필요가 있다. 양 자판의 거리는 집게 기준열(쿼티의 F, J)의 안쪽 위 사이로 재고 완전 수평으로 놓으면 거리가 360미리 정도된다.

0행 모서리를 완전히 밀착시켜 거리를 최대한 좁힌 상태에서 양손가락이 수직 뻗는 방향이 되도록 하면 양 자판의 각도는 56도이며 수평선에서 한 자판이 28도이다. 이때 FJ 기준키 위쪽 모서리간의 간격은 70미리이다.

(370, 0) (70, 28) 두 점을 지나는 선분의 방정식을 구하면 angle = 35 -0.1dist가 된다. 기울기를 -0.1로 맞추기 위해 수평일 때 자판 거리를 350으로 대충 잡았다. 350미리 거리가 수평이고 10미리 가까워질 때마다 한쪽 자판을 1도씩 기울이면 된다. 두 자판의 거리를 100미리로 하면 25도 기울여야 한다. 이 상태로 진짜 배치를 만들어 보니 말도 안된다. 좌우 손가락을 놓아 보면 새끼쪽이 너무 아래로 내려간다.

처음에 두 자판 밀착시 28도가 너무 과다하게 계산된 거 같다. 다시 배열해 보고 손가락을 편안해게 올렸을 때의 각도를 재 보니 12도 정도밖에 안되며 이때 양자판의 거리는 55미리이다.

(370,0) (55, 12)의 방정식은 angle = 14.145 - 0.039dist가 되는데 거리 10에 대해서 각도 10.245가 나온다. 그냥 거리 10일 때 각도 10으로 맞추자. 어차피 대충 계산한거고 체격에 따라서도 달라질 수 있어 이 정도 근거면 크게 부족하지는 않을 거 같다.

요렇게 100미리에 10도로 맞췄더니 양쪽에 편집, 매크로를 둘 공간이 부족하다. 나중에는 이만큼 띄워도 상관없겠지만 시제품은 폭이 400으로 제한되어 있어 공간을 아껴야 한다. 그래서 80미리로 간격을 줄이고 각도는 11도로 했다. 좌우는 키 구멍끼리 10미리 띄웠다. 초안으로 그려본 것과 거의 비슷하되 좌우 거리가 약간 더 멀다.

이렇게 만드니 기준점이 애매하다. 그래서 아예 좌우 각각 합쳐서 하나씩 도안을 따로 그렸다. 좌우 가장자리와 위쪽을 각각 10미리씩 띄우는걸로 하면 명쾌하고 편집, 매크로와 기본도 10미리를 띄웠다. 아래쪽은 약간 여유가 있다. 한 묶음으로 인쇄해서 스텐판에 붙이니 틀어질 위험도 덜하고 차후 도면으로 만들 때도 좀 쉬울거다.

F,J 키의 좌우 거리는 77미리이다. 좌우를 띄우다 보니 폭이 400으로 텐키레스보다 더 길고 높이도 비슷하다. 애초의 컴팩트에서 좀 멀어졌는데 시제품이라 어쩔 수 없고 나중에 키피치를 줄이고 간격도 조정하면 텐키레스랑 비슷해질 거 같다.

매크로와 편집키도 같이 기울어야 하나 잠시 고민했다가 이 위치는 어차피 팔을 벌려 누르기 때문에 그냥 평행하면 될 거 같다. 오히려 기울이면 더 이상하다. 키를 더 많이 배치하려면 편집키 한칸 아래로 내리고 그 위에 약간 띄운 후 PrtSc, Break 정도는 더 넣어도 될 거 같다. ScrL이나 Menu도 넣을만 하다.

이것도 물론 초안이지만 이대로 구멍만 뚫을 수 있다면 나쁘진 않을 거 같다. 대충 테이핑해서 붙였는데 스틸판에 좀 더 정밀하게 배치해 봐야겠다. 각도가 들어가니 무척 피곤하고 눈대중으로 맞추기도 어렵고 도안에 정확히 표시하기도 쉽지 않다.

 

세 번째는 스텐판에 구멍을 어떻게 뚫을것인가인데 아우한테 물어 보니 레이저 커팅을 해야 하는 모양이다. 목재, 플라스틱, 가죽 등 재료에 상관없이 쓸 수 있고 정밀하다. 높은 열을 0.5미리 이하의 영역에 집중해 태워 증발시키며 공구 마모나 재료 변형이 없다. 가공 표면은 거칠며 광택이 죽는 문제가 있지만 모양의 자유도가 높다. 유튜브 동영상 보니 금속판도 자유자재로 잘라내기는 한다.

 

스텐, 알루미늄 같은 전도성 재료는 최대 0.5미리까지만 가능해 플라즈마 절단을 사용해야 한다는 얘기가 있으며 일반적으로 금속 가공은 어렵다고 한다. 레이저보다는 에너지 소모율이 낮고 품질은 떨어지며 먼지와 소음도 많이 발생한다. 그런데 다른 자료를 보면 금속도 30미리까지 뚫을 수 있다고 하는데 뭐가 맞는지 모르겠다.

위 오른쪽 사진은 창원의 가공월드(https://gagongworld.tistory.com) 블로그의 작업 샘플인데 2T 스텐에 패턴 작업을 한 것이라고 한다. 이런 가공을 CNC(Computer Numerical Control)이라고 하는데 캐드로 DWG STP 도면을 2D로 그린 후 도면의 수치에 따라 재료를 가공한다.

이런 업체가 있다는 것은 일단 다행스럽다. 루리웹 게시물을 통해 레이저 1번가(http://laser1st.co.kr)라는 업체를 일단 검색해 놨는데 인천에 있고 최소 견적이 3만원, 1개라도 가공해 준다고 되어 있다. 이런 업체 좀 알아 보고 상담 요청해 봐야겠다. 레이저 커팅 말고 펀칭이나 절단 등을 해 주는 업체도 있다는데 이쪽도 좀 알아 보야겠다. 정 안되면 드릴로 여러방 뚫는 방법도 생각중이다.

------------------------------

22 2 17

구멍을 어떻게 뚫을 것인가 이것 저것 검색을 해 보니 유튜브에도 몇 개 있기는 하지만 딱히 뾰족한 방법이 없다. 그라인더로 톱길 대충 내 놓고 컷쏘로 오린후 줄로 마무리하는 원론적인 방법뿐이다. 적당한 공구가 없나 싶어 찾아 보니 니블러라는게 있다.

가격도 2만원 정도밖에 안하고 작은 컷쏘 형식으로 제법 절단이 잘 되는 거 같기는 한데 왠지 좀 힘이 약해 보인다. 해외 배송도 아니고 바로 받을 수 있을 거 같은데 일단 주문할까 하다가 다른 방법 먼저 좀 알아 보자 싶어 보류했다.

잘 모르는 전공 분야에 대해 혼자 고민하지 말고 일단 나가서 좀 알아 보자 싶어 이천 시내로 나가 봤다. 철공소를 들러 물어 봤더니 여기서는 이런 거 안 한다고 레이저 컷팅이나 판금 업체를 알아 보라고 한다. 이천에도 그런거 하난 업체가 있긴 있다고 한다.

이천 공구상에 들어가 사각 구멍을 뚫을 때는 어떤 공구를 써야 하냐고 물어 봤더니 이건 방법이 없다고 한다. 드릴로 뚫은 후 컷쏘질을 해야 하는데 수작업으로는 거의 불가능하니 업체를 알아 보란다. 그래서 업체 좀 소개해 달랬더니 자기는 거래하는데가 없다고 한다. 혹시나 싶어 이런 저런 공구 몇 개를 사 왔다.

아크릴 칼, 쇠톱 2 8000원이고 원형 컷쏘날은 13미리, 14미리 2개 각 3000원씩이다. 강철 컷쏘날이 3000원밖에 안한다니 참 싸다고 느껴진다. 일단 14미리로 구멍을 먼저 뚫고 쇠톱으로 모서를 따 볼까 생각해 봤다. 정 안되면 그렇게라도 해야지.

공구상을 나와 밀리, 선반 업체가 있길레 혹시나 싶어 들어가 봤다. 나이 약간 드신 아저씨가 내가 들고간 스텐판을 보더니 이런건 업체 가야 한다고 말해 줬다. 그러면서 이렇게 만들어 오면 안되고 도면을 따로 준비해야 한다고 잔소리했다. 나도 알긴 아는데 일단 가능한지부터 확인하러 왔다고 해도 자꾸 그 사람들 도면 안주면 일 못한다고 반복이다. 어디 사냐길레 호법 산다고 했더니 그럼 저짜 새로 난 길로 가면 현대 스텐이라고 있는데 가 보란다. 새로 난 길이 어딘가 했더니 아 왜 로컬푸드에서 모가면으로 가는 길 있잖여~~ 하길레 은계보로인가 싶었다. 그쪽 끝에 주유소가 있는데 그 옆에 있다고 한다. 아무튼 소중한 정보를 듣고 차 빼서 가 봤다. 과연 딱 원하는 업체가 있다.

 

마당에 작업해 놓은 철기둥이 있는데 두꺼운 스텐판에 꽃무늬를 새겨 놓았다. 이 정도면 충분할 거 같아 사무실로 들어가 상담을 받았다. 젊은 남자분이라 키보드 보강판이라고 하니 척 알아 들었다. 뭘 원하는지 알겠다고 하고 충분히 가능하다고 한다. 1.5T 철판에 구멍 다 뚫어 주고 비용으로 대략 25000원 정도 들며 작업은 하루면 충분한다고 한다. 대량으로 생산하면 물론 가격은 더 떨어지고.

문제는 도면을 반드시 DWG로 준비를 하라는데 이건 또 안해 본 거라 배워서 해야 한다. 캐드를 내가 다뤄본 적이 있어야 말이지. 자유롭게 제작해 보려면 결국 캐드도 배워야 하는데 당장 소프트웨어부터 구해야 한다. 이거부터 찬찬히 그려 보고 다음주에 스텐판에 구멍 뚫어 2호를 만들어 봐야겠다. 이왕 만드는거 각도 약간씩 다르게 해서 2개를 만들어 볼까 싶다.

드릴로 직접 구멍을 뚫었으면 아마 며칠은 걸릴거고 또 몸살을 앓을텐데 이래서 모르는게 있으면 밖에 나가 물어 보고 정보를 구해야 한다. 공구는 왠지 괜히 산거 같은데 그래도 다음에 쓸 일이 있을지 모르니 일단 가지고 있자.

 

DWG drawing의 약자로 도면 파일이다. 오토데스크의 2D, 3D 파일을 저장한다. 오토캐드는 유료 프로그램이고 뷰어는 오토데스크 홈페이지에 공개되어 있는데 뷰어만 866메가에 달한다. 건방지거로 C 드라이브 루트에 폴더를 만들고 압축을 해제한다. 깔아 보고 샘플 파일 구해서 읽어 봤는데 어떻게 보는지도 잘 모르겠다.

ppt dwg로 변환하는 reaConveter라는 프로그램도 있다. 280메가짜리 7 Standard 버전을 받아 설치했는데 2주 평가 기간동안 한번에 5개까지만 변환할 수 있다. 설치한 후 도면을 400 * 150 크기로 새로 만든 후 간단한 ppt 파일로 복사해 놓고 변환해 봤는데 원본 파일을 읽지 못한다. 더 간단하게 네모하나, 동그라미 하나만 그려 놔도 못 읽는다.

파일 추가하고 출력 포맷에서 DWG 선택하고 Start 누르면 된다고 되어 있지만 원본을 읽지 못한다. 커스텀 크기라 그런가 싶어 표준 크기로 줄여도 안되고 pptx라 안되나 싶어 ppt로 저장해 봐도 안된다. 좀 쉽게 해 볼려고 했는데 안되네 그랴. 아우한테 물어 보니 ppt로 만들어 주면 dwg로 만들어 준단다. 도면 잘 만들어서 일단 메일로 보냈는데 결국은 내가 오토캐드도 공부해야 하지 않을까 싶다.

메일로 구조와 치수를 설명하는 ppt 상세하게 작성해서 보내 놓으니 다음날 아침에 도면을 그려 보냈다. 1차로 보낸건 좌우 자판과 문자 자판의 거리가 너무 띄워져 한번 수정했다. 두 자판의 거리가 10미리인데 키캡간의 거리가 아니라 키홀간의 거리인데 잘못 배치했다. 5미리씩 더 멀어져 가운데 문자키가 안으로 몰려 문자키를 밖으로 5미리씩 다시 뺏다.

이걸 어제 명함 받아온 석동호 팀장께 보냈더니 한참 있다가 오후 늦게 전화가 왔다. 다행히 도면은 별 이상없이 잘 그렸다고 한다. 주말이 끼어 내일은 작업하지 않으니 화요일 아무때나 찾으러 오라고 한다. 알루미늄으로 하면 재료는 더 싸지만 가공비가 더 드는데 쌤쌤이해서 똑같이 25000원이라고 한다. 그냥 스텐으로 해 달라고 요청했다. 화요일 어떤 철판이 나올지 기대된다.

커넥터 주문해 놓은 건 택배 파업으로 인해 이천으로는 못 온다고 해서 평택 주소를 가르쳐 줬다. 도착은 했는데 오늘은 가져오지 않아 다음주말이나 되어야 받을 수 있을 거 같다. 그나마도 20개밖에 안되어 부품을 좀 더 주문해야 하니 2호 키보드는 다다음주나 되어야 만들어볼 거 같다. 그동안 후킹이나 해 놔야겠다.

오늘은 그동안 수집해 놓은 경쟁 키보드에 대한 개요를 정리해 놓았다. 그 중에 corne가 소젯이랑 제일 비슷한데 다들 독특하다. 또한 다들 커스텀으로 비싸게 팔고 맵핑이 필요해 초보자용은 아니다. 소젯은 일반 입력용이며 완제품으로 발표할 계획이며 연습만 하면 쓸 수 있는 키보드를 지향한다.

-----------------------

22 2 19

스텐 구멍 뚫고 납땜 준비하고 나무판 잘라 붙이면서 나름 재미는 있었지만 내가 지금 과연 소프트웨어를 만들고 있는건지 하드웨어를 만들고 있는건지 헷갈린다. 소젯은 하드웨어 실물이 있지만 오토마타가 핵심이라 소프트웨어에 더 가깝다. 나는 공작이 전문이 아니고 개발자이니 개발에 치중해야 하되 시제품을 만들어줄 사람이 없으니 어쩔 수 없이 모든 걸 내가 다 하는 중이다.

소젯2호는 다다음중에나 만들어 볼건데 이게 완성되면 쿼티 키보드를 완전히 대체할 수 있어야 하고 첫번째 사용자인 내가 실사용을 계속 하면서 점검 및 개선해 나가야 한다. 그러나 현재 소젯은 연습 프로그램상에서만 동작하며 다른 프로그램에서는 사용할 수 없다. 후킹이든 디바이스 드라이버든 소프트웨어를 만들어야 하는데 공돌이짓하다가 막상 프로그램 짜려니 무척 귀찮기도 하다. 둘 다 난이도가 높아 시작하기가 조금 두렵다.

후킹은 전에도 해 본 적이 있는데 기록을 살펴 보면 여러 가지 문제를 해결하기가 쉽지 않을 뿐만 아니라 해결 불가한 한계가 있어 근본적인 해결책이 아니다. 하지만 디바이스 드라이버에 비해 쿼티와 공존할 수 있고 필요할 때만 기동할 수 있다는 면에서 효용성은 있다. 시제폼 배포시도 사용자에게 큰 부담을 주지 않고 개선도 용이하다. 완벽하지 않더라도 최소한 영문, 기호만이라도 입력할 수 있도록 과거 기록 참고해서 어느 정도까지 복원은 해 놔야겠다.

과거 기록은 많이 있는데 표기를 훅킹, 후킹으로 통일하지 않아 검색이 다 안된다. 예전 문서를 일괄 치환하여 훅킹을 후킹으로 바꿨다. 07 8 26일 후킹 초안을 작성했으나 메모장에 영문만 가능한 수준이었다. 한동안 방치하다가 12 6 20일부터 후킹을 다시 시작했는데 재귀 문제, 한영 전환 문제, 프로그램마다 증상이 다른 문제 등을 차례대로 해결했고 저수준 후킹까지도 도입해 봤다. 마지막 버전은 저수준을 사용한다. 기록은 있지만 그렇다고 그게 현재의 경험은 아니어서 새로 공부해야 하는 문제가 있다.

이전 버전은 어디까지 개발해 놨는지 일단 현재 상황부터 파악해야 하는데 0.97 버전에서 훅 버튼을 눌러도 전혀 동작하지 않는다. 소스를 까 봐야 알 것 같다. 소스를 까 보니 모든 코드가 다 잘 작성되어 있기는 한데 실행 파일의 DLL이 아주 예전에 컴파일했던건지 같이 동작하지 않는다. 컴파일러 버전은 물론이고 32/64비트, Debug/Release까지 짝을 맞춰야 제대로 동작한다.

0.97 버전에 대해 후킹되는 릴리즈 버전 VS 2019로 컴파일해서 따로 폴더를 만들고 데모용으로 준비해 뒀다. 일단 메모장이나 비주얼 스튜디오에서는 잘 동작하는데 레지스트리에 옵션을 공유하다 보니 윗줄 올림 같은 옵션이 켜져 있어 조금 조정해 줘야 하는 불편함이 있다. 이래서 INI 파일을 사용해야 하는 모양이다. 이 소스 참조해서 이 수준까지만이라도 소스 작성해 둬야겠다. 이전 버전 코드가 잘 동작해서 예상외로 금방 될 거 같다.

예전 프로젝트중에 HookTestForAnerim이 있는데 후킹 관련 문제를 연구하기 위해 12 6 20일 만든걸로 되어 있다. VS2022로 열면 프로젝트를 변환하는데 냅다 변환해 버리면 리소스에서 에러가 발생한다. SDK와 플랫폼 도구 집합을 업그레이드하지 말아야 제대로 열리며 컴파일도 가능하다. 애초에 뭘로 컴파일했었는지도 생각나지 않는다.

 

실행해 보니 뭔가 후킹을 시도하는 거 같은데 제대로 동작하지 않는다. 기록을 보면 이런 저런 코드를 테스트 하느라 소스는 걸레가 되어 가고 있다고 하는데 그냥 걸레인채로 방치했던 모양이다. 혹시라도 다음에 참고할 일이 또 있을 수도 있어 VS2022로 변환해서 소스만 백업해 두었다.

AnerimHook 프로젝트는 SojettHook으로 이름을 바꿔 프로젝트를 새로 생성한다. 자주 업데이트하지 않으니 굳이 솔루션으로 묶을 필요는 없고 컴파일 결과를 Debug, Release 폴더에 수동으로 복사하기로 한다. Win32 DLL 프로젝트 생성하고 x64 구성 없앤 후 pch 설정 제거하고 런타임 라이브러리 포함으로 옵션 조정했다.

소스는 AnerimHook을 그대로 가져오되 #pragma comment(lib, "imm32.lib") 추가하고 hWndAnerim 변수명을 hWndSojett으로 변경했다. Debug 838, 릴리즈는 71K DLL 파일이 만들어진다. 이 파일을 Sojett 프로젝트의 Debug, Release 폴더에 각각 복사해 둔다. 코드 내용은 별거 없고 설치시 소젯 윈도우 핸들 받아 두고 키보드 훅시 WM_USER+1 메시지를 보내고 리턴값이 0이면 메시지는 먹어 버린다.

언어 모드가 바뀌면 CBT 훅에서 WM_USER+2를 보내는데 이 부분은 잘 모르겠다. 모든 키입력을 소젯이 다 받는데 이게 굳이 왜 필요한가 싶기도 한데 일단은 가져왔다. 좀 더 연구해 볼 필요가 있다. 여기까지 해 놓고 윈도우 업데이트가 강제 재부팅을 시켜 버리는 바람에 시간 좀 낭비했다. 진짜 이놈의 업데이트 왜 그러는지 모르겠네....

Sojett도 수정했다. 훅은 툴바에 버튼만 남겨 놨는데 누를 경우 StartHook을 호출하여 DLL 로드하고 훅 루틴을 설치한다. 종료시는 EndHook을 호출한다. 최초 시작시 후킹 옵션이 켜져 있으면 타이머 호출하여 훅 초기화하고 OnPaint에서는 훅 안내 메시지를 출력한다. 훅 메시지를 보여 주기 위해 리스트박스 하나 배치하고 정보를 덤프했다. 사용자에게는 별 필요 없지만 개발을 위해 필요하다.

이후 사나흘간 훅 작업만 했다. 이전 소스를 다 꿰고 있는게 아니고 훅도 이론을 까먹어 공부해 가며 하나씩 복원해야 하니 시간이 오래 걸린다. 또한 여기 저기 말썽 있는 부분도 아직 남아 있어 순차적으로 해결했는데 하나같이 시간이 오래 걸리는 작업이다. 다행히 예전 기록과 소스의 주석이 많아 과하게 헷갈리지는 않았다.

훅은 WM_KEYDOWN WM_KEYUP을 분명히 구분하지 않고 파라미터로 알려주는데 예전 소스는 이 두 상태를 구분하기 위해 일일이 if 문을 사용했고 모든 함수로 wParam, lParam을 전달했다. 이번에 Sojett 프로젝트를 새로 만들면서 파라미터는 OnKey에서 해석하고 모든 키 처리를 ProcessKey 함수로 집중하고 인수로 kidx bDown 딱 두 개만 전달받았는데 이게 신의 한수였다.

논리적 구조가 잘 잡혀 있으니 후킹 루틴이 끼어들 부분이 명확하고 ProcessKey 이하는 코드가 거의 비슷해 비슷한 부분을 가급적 공유할 수 있다. 후킹에서 가장 중요한 것은 메시지의 흐름인데 다음과 같은 구조로 되어 있다.

키보드 메시지로부터 전달되는 정보와 후킹으로 전달되는 정보의 구조가 많이 다르다. 이 정보에서 원하는 값을 추출 및 변형하고 ProcessKey 함수로 전달한다. 이 함수는 가상키니 확장키니 이런건 전혀 신경쓰지 않고 오로지 키와 Down/Up 정보만 받아 처리한다. 키 입력 정보가 앞 단계에서 추상화되어 꼭 필요한 정보만 전달하니 이후에는 kidx와 누름/놓음 여부에 따른 처리만 하면 된다.

키입력과 후킹에 따른 처리를 수행하는 핵심 함수는 InsertChar이다. 연습 프로그램은 ApiEdit에 문자열을 직접 삽입하고 후킹중이면 kidx에 대한 대응 가상키를 찾아 타겟으로 kbd_event를 호출한다. 예를 들어 소젯의 S(쿼티의 A)를 누르면 쿼티의 S키 가상키를 타겟으로 보내는 식이다. 한글은 ProcessHan에서 직접 변환하는데 쿼티의 C키를 누르면 ㅎ을 입력하기 위해 타겟으로 G를 보낸다. 소젯의 C 자리에 ㅎ이 있고 쿼티는 G 자리에 ㅎ이 있어 가상키만 잘 찾아 보내면 IME는 타겟이 직접 처리한다.

이 구조를 잘 만들어 놓으니 웬만한 루틴은 공유 가능하고 꼭 구분이 필요한 부분에 대해서만 if (Opt.bHooking) 조건문으로 처리하면 된다. 메시지 구조차는 ProcessKey 이전에 통일되고 입력은 대응키를 찾아 디바이스 드라이버에게 넘기는 식이다. 결국 후킹으로 키를 중개하는 셈인데 예상외로 이 방법이 큰 말썽이 없다. 구조적 차이나 버그로 인해 여러 가지 문제가 추가로 발생했는데 하나씩 해결했다.

 

- 소젯과 타겟의 IME 모드가 불일치하는 문제가 있다. 소젯은 무조건 영문 모드로 후킹을 하고 chrMat 변수로 언어를 기억하는데 비해 타겟은 고유의 IME 모드가 있어 가끔 불일치한다. Lang 버튼을 누를 때 소젯의 현재 언어에 맞게 타겟의 IME 모드를 강제로 바꾸도록 했다. 그래도 포커스 이동시에는 모드가 불일치하는 경우가 아직 있다.

- 키입력은 좌우키에 대해 대표 가상키를 보내는데 비해 후킹은 좌우를 명확히 구분한다. 대표 가상키로 통일해서 쓰는데 키맵에 VK_CONTROL, VK_ALT가 좌우 양쪽으로 있어 명확히 구분되지 않는다. 진짜 가상키에 대해서만 누름 상태를 관리해 오토리피트를 정확히 구현하기 어렵다. 모드키에 대해 VK_EDIT, VK_NUM, VK_LANG 가상키코드를 정의하여 좌우 구분을 명확히 하는 방식으로 해결했다.

- 펑션, Esc, Tab 등도 타겟으로 대응키를 보내 처리했다. 편집키나 조합키도 실행할 가상키 코드만 구하면 타겟으로 보내기만 하면 된다.

- 한글 모드에서 Ctrl+A, Ctrl+F 등의 조합키가 안 먹힌다. 조합시 무조건 영문으로 넘기도록 했는데 이러면 차맷이 달라 한글 문자를 보내게 된다. 한글 모드에서는 강제로 영문 모드의 문자를 읽어 조합키를 실행하도록 했다.

- Shift+BS 연속 입력 안됨. 후킹시 VK_HANGUL 가상키가 오는데 이 경우 공백으로 바꿔 버리면 된다. OnKey에서는 VK_PROCESSKEY로 와 판별하는 방법이 다르다.

- 쌍자음 입력 기능 구현. 후킹에서는 좀 어려울 거라 예상했는데 이전 키와 큐를 잘 점검해 보니 되긴 한다. 버퍼를 읽을 수 없어 키 입력 순서를 잘 봐야 하는데 공백++ㄱ일 때 단어 처음으로 보고 ㄲ으로 바꿔 입력하면 된다.

 

이 외에도 숱하게 많은 잔버그들이 있었는데 보이는 족족 해결했다. 막상 달려들면 논리가 어렵지는 않은데 일단 디버깅이 안되는게 치명적이다. 키입력을 독점하는 녀석을 디버깅하면 비주얼 스튜디오도 키입력을 못 받아 마우스로 디버깅을 해야 한다. 다행히 이렇게 해도 운영체제 안정성에는 별 문제가 없다.

그 외에 단순한 실수나 오타에 의한 자잘한 문제도 많았다. 적어도 이전 아너림의 후킹보다는 훨씬 더 완벽해졌으며 메모장, 워드, 웹 브라우저에서 모두 잘 동작한다. 게시판에 소젯1호 키보드 연결해 놓고 직접 글을 쓰고 편집할 수 있다. 몇 가지 골치 아픈 문제만 더 해결하면 후킹으로 실사용해도 될 정도이다.

 

- 저수준 후킹을 위해 DLL을 만들었는데 그럴 필요 없다. 기록에 의하면 12 6 21일 고수준 후킹에서 저수준 후킹으로 바꿨는데 여기를 보면 저수준은 DLL을 안만들어도 전역으로 동작한다고 되어 있다. 예제를 만들어 보니 과연 잘 동작한다. 어차피 큐만 들여다 보는거니 굳이 남의 주소 영역까지 잠입할 필요없이 메시지를 잘 읽어낸다.

그렇다면 아예 연습 프로그램에 후킹 논리를 포함시켜 버리는게 더 깔끔하다. DLL 하나 딸려 있는 것보다 단독 실행 파일이면 사용하기도 쉽고 소스 관리나 배포도 유리하다. OnKeyHookLL 함수로 후킹을 설치했는데 원형에 nCode가 들어가는 것 외에 외형적인 변화는 별로 없다. 다만 리턴값이 1일 때 먹고 0일 때 전달하는건데 이게 반대로 되어 있어서 잠시 엉뚱한 동작을 했다.

왜 그런가 한참 뜯어 봤는데 디버깅이 안되다 보니 증세를 보고 추론을 잘 해야 한다. DLL에서 리턴값을 반대로 바꾸어 리턴하다 보니 헷갈렸는데 인젝트 메시지만 빼고 전부 1을 리턴하면 해결된다. 리턴값 0, 1의 의미는 참 헷갈리기 쉽다. 이제 DLL이 없어도 잘 후킹되며 이전과 다를 바 없이 훌륭하게 동작한다.

이걸 미리 알았더라면 DLL이 없어도 되는데 삽질을 했다. 이래서 아는게 힘이고 공부부터 해야 하는거다. 사실 저수준 후킹을 아직 다 아는 것도 아니라 좀 더 연구해 볼 필요가 있다. 도움말을 보니 후킹은 성능이 그다지 좋지 않으니 Raw Input이라는 방법이 더 낫다고 되어 있는데 이것도 다음에 한가할 때 연구해 봐야겠다. 한가할 때가 없어서 문제지만

- SojettHook은 키보드 훅 뿐만 아니라 CBT 훅도 처리하는데 이 훅은 포커스 이동시 해당 윈도우의 IME 상태를 알려 주고 소젯이 동기화하도록 하는 역할을 한다. Lang를 누를 때 소젯의 모드를 활성창에 전달하는 것과 반대 동작이다. 포커스를 이동하면 활성창의 모드를 소젯으로 전달해야 한다. 한글 상태의 윈도우에서 입력하다 영문 상태의 윈도우로 옮기면 소젯의 차맷도 영문으로 바꿔야 한다.

CBT HCBT_SETFOCUS 코드가 원래 이 역할을 하는데 테스트해 보면 훅 메시지가 거의 오지 않는다. , 포커스 변화를 제대로 감지하지 못해 영문 윈도우에 한글 키보드 메시지를 입력하는 현상이 발생한다. 이 문제는 CBT 훅을 수정하기 보다는 내부에서 타이머 돌리며 폴링하는 방식으로 다시 작성했다. 0.5초 타이머이면 평균 0.25초만에 포커스 이동을 감지해 낼 수 있으며 이 정도면 빠른 편이다. 활성창이 실제 바뀌지 않으면 아무 일도 하지 않으니 큰 부담도 없다.

논리는 간단하다 활성창은 한글인데 소젯이 영문이라면 차맷을 한글로 바꾼다. 반대의 경우도 마찬가지이다. 그러면 포커스를 옮기는 족족 소젯이 활성창의 IME 모드를 인식하게 된다. 문제는 옵션에 대상 차맷이 없는 경우와 한영 차멧이 소젯이 아닐 때이다. 영문만 등록해 놓고 쓰고 있다면 활성창이 한글모드이더라도 차맷이 없어 한글을 입력받을 수 없다. 이 경우는 어쩔 수 없이 활성창의 모드를 한글로 강제로 바꿔 버린다. 반대도 마찬가지이다. 미국인이 한글 차맷을 쓸 이유가 없으니 이 기능도 꼭 필요하다.

- 현재 차맷을 관리하는 변수가 좀 복잡하다. 차맷 목록은 arChaMat 배열에 정적으로 정의되어 있고 사용 차맷은 Opt.useChaMat 배열에 기록해 둔다. chaMat 변수에 옵션 배열의 첨자를 기억해 두고 현재 차맷을 찾을 때 useChaMat[chaMat]로 번호를 찾고 실제 차맷은 arChaMat[번호]로 다시 읽어야 하니 느리고 각 변수의 관계를 파악하기가 어렵다. 그래서 번호와 실제 차맷을 다음 세 변수로 다시 정의했다.

 

int cmIdx;                           // 현재 차맷 번호. Opt.useChaMat배열의 첨자.

int chaMat;                         // 현재 차맷. Opt.useChaMat[cmIdx]

sChaMat* pCm;                       // 현재 차맷 구조체. &arChaMat[chaMat]

 

cmIdx가 결정되면 나머지 둘 도 결정된다. 옵션이 바뀌면 모두 리셋된다. 이 변수들의 관계를 ApplyChaMat에서 일괄 동기화하고 입력 루틴은 그때 그때 필요한 변수를 통해 원하는 값을 알아 내면 된다. 현재 차맷의 문자는 다음 코드로 읽으면 된다.

 

pCm->Map[kidx].glyph[tShift]

 

이 수식이 원래는 arChaMat[Opt.useChaMat[cmIdx]].Map[kidx].glyph[tShift] 였으니 얼마나 복잡한가. 차맷 번호와 차맥 구조체를 미리 찾아 놓으니 쓰기도 편하고 덜 헷갈린다. 포커스 변경에 의한 IME 동기화 코드를 작성할 때 엄청 복잡했는데 변수를 좀 정리했더니 그나마 좀 간단해졌다.

이제 SojettHook 프로젝트는 아예 필요가 없어졌다. 사실 AnerimHook과 코드도 거의 비슷해서 굳이 프로젝트를 유지할 필요도 없다. 적당한 때에 프로젝트 자체를 날려 버려야겠다. Sojett은 완전한 단독 실행 파일이며 혼자서도 모든 것을 다 처리할 수 있다. 나는 요런 단순한게 좋다.

- 왼쪽 Shift키로 블록을 선택하면 홀드시만 블록이 늘어나고 놓으면 이동으로 바뀌어 잘 동작한다. 반면 오른쪽 Shift키는 한번 누르면 놓아도 계속 블록이 늘어나며 풀리지 않는다. 문자 영역의 편집키를 누르나 편집 카테고리의 키를 누르나 차이는 없이 똑같은 증상이 발생한다. 영문 대문자를 입력할 때는 좌우 Shift 모두 잘 동작하며 푸시나 홀드 다 이상 없다. 오른 Shift로 블록을 선택할 때만 문제가 된다.

후킹할 때만 이렇고 연습 모드에서 직접 입력할 때는 그렇지 않다. 후킹에서 오는 파라미터와 인젝트 메시지간의 관계 때문에 그런 듯 하다. 심지어 후킹을 완전히 종료해도 똑같은 현상이 지속되며 오른쪽 Shift키를 한번 눌렀다 놓아 줘야 해소된다. 타겟뿐만 아니라 모든 프로그램에 전역적으로 같은 현상이 발생하는데 GetKeyState가 참조하는 Shift 키의 상태가 고정되어 버리는 것 같다. 왜 이런 현상이 일어나는지 오른Shift+왼쪽이동을 한번 누를 때의 로그를 찍어 보았다.

 

KHLL : Down, vk = 161, scan = 36, flag = 1   // 오른쪽 Shift 누름

KHLL : Down, vk = 37, scan = 4b, flag = 1     // 왼쪽 커서키 누름

ProcessEdit. kidx=64

ProcessVk. vk = 37, Contro = Shift+                // 여기서 Shift + 왼쪽 키이벤트 발생

KHLL : Down, vk = 160, scan = 0, flag = 10   // 왼쪽 Shift 누름. 대표 Shift로 이벤트 생성

인젝트 메시지 체인 전달                      

KHLL : Up, vk = 161, scan = 236, flag = 81    // 오른쪽 Shift 놓음. 아직 안 놓았는데 이게 왜 오지?

KHLL : Down, vk = 37, scan = ff, flag = 10     // 왼쪽 커서키 누름

인젝트 메시지 체인 전달                                     // 여기서 블록 한칸 왼쪽으로 확장

KHLL : Up, vk = 37, scan = ff, flag = 80         // 왼쪽 커서키 놓음. 스캔코드 ff는 뭐야?

KHLL : Down, vk = 161, scan = 36, flag = 11 // 오른쪽 Shift 누름. 이게 왜 또 오지?

인젝트 메시지 체인 전달                                     // 여기서 오른쪽 Shift 상태 고정되는 듯

KHLL : Up, vk = 160, scan = 0, flag = 90        // 왼쪽 Shift키 놓음

인젝트 메시지 체인 전달

KHLL : Up, vk = 37, scan = 4b, flag = 81       // 왼쪽 커서키 놓음

KHLL : Up, vk = 161, scan = 36, flag = 81      // 오른쪽 Shift 놓음. 여기서 풀려야 하는데

 

순서도 이상하고 스캔코드 ff 236도 뭔가 특별한 의미가 있어 보인다. 236에 대해서는 블록 유지가 안되어 먹어 버리는 코드를 작성해 뒀는데 이 코드를 없애도 증상은 똑같다.  Shift가 양쪽에 두 개라서 이를 구분 또는 통합하고자 하는 시도로 인해 뭔가 히스토리가 있을 거 같고 모든 환경에서 말썽이 없도록 만들다 보니 예외적인 코드가 들어간 거 같다.

이 문제를 풀지 못하면 한번 증상 발생시 소젯을 종료했다 재시작하는 수밖에 없다. 이 상태를 방치할 수는 없고 그렇다고 풀기에는 너무 복잡해 보인다. 어쩔 수 없이 가장 비겁한 방법을 선택했다. 그냥 오른쪽 Shift는 완전히 무시해 버리는 작전이다. 오른쪽 Shift를 왼쪽 Shift로 바꾸는 방법은 통하지 않았다.

 

if (kb->vkCode == VK_RSHIFT) return 1; //  kb->vkCode = VK_LSHIFT;

 

이게 정확한 해결책이 아니라는 것은 나도 안다. 그러나 쿼티 키보드에서만 그렇고 소젯 시제품은 어차피 맵핑을 왼쪽 Shift와만 하니 당장은 문제가 없다. 쿼티에서 후킹중일 때 오른쪽 Shift는 아예 지원하지 않는 걸로 하자. 영문 대문자도 왼쪽 Shift만 된다. , 연습 프로그램에서는 오른쪽 Shift도 이상없이 지원한다.

- 윈도우 키를 전혀 처리하고 있지 않음을 발견했다. 후킹중이 아닐 때는 어차피 운영체제가 처리하므로 상태란에 누름, 놓음만 처리했다. 후킹중일 때는 누를 때 아무 것도 하지 않고 단독으로 눌렀다 놓을 때 VK_LWIN 이벤트를 발생한다. Ctrl, Alt와는 달리 누를 때가 아니라 놓을 때 시작 메뉴를 열도록 되어 있으며 조합하면 시작 메뉴를 열지 않는다. 조합키는 이미 처리되어 있어 Win + D Win + R이 이미 잘 동작한다.

마찬가지로 Alt도 단독으로 누를 때 메뉴를 여는 기능이 아직 구현되어 있지 않다. Win 키와 유사하게 처리했는데 Alt+Tab이 제대로 먹히지 않는데 Alt 홀드 상태로 Tab키를 계속 누를 수 있는데 KeyEventModi 함수가 홀드 상태까지는 처리하지 않아서이다. 이 문제는 다음에 해결하기로 하자. 체력이 달리니 문제가 있어도 즉시 해결하기가 싫어진다. 어차피 이거 아니라도 다른 문제도 많을텐데 모아 놨다 한꺼번에 해결하자.

- 여기까지 후킹 관련 코드를 그럭 저럭 일단락 짓기로 한다. 아직 완벽한 것은 아니고 더 해결해야 할 문제가 있지만 과거의 후킹 코드 작성 성과는 다 가져왔다는데 의의가 있다. 고수준은 재귀나 IME 동기화가 어려운데 저수준으로 바꾼 후 많이 해결했고 예전 버전보다는 개선했다. 과거의 경험까지 다 가져올 수는 없지만 지금 정도 수준이면 앞으로 발생하는 문제에 대해서도 어느 정도 대응 가능할 거 같다.

이후의 문제는 연구해 가며 하나씩 풀어야 하되 디바이스 드라이버 제작 전의 대용품이므로 완벽할 필요까지는 없다. 대충 시제품을 테스트해 보고 큰 불편없이 입력만 가능한 수준이면 되고 지금 딱 그 수준까지 온 거 같다. 이 이상은 더 정교한 연구와 학습이 필요하다.

- 시제품 2호를 제작하기 전에 맵핑을 좀 조정하기로 한다. ETC를 연습 프로그램의 테스트키로 쓰기 위해 789에 맵핑해 놓았는데 잘못 내린 결정이었다. 막상 쿼티에서는 완전히 달라 혼란스럽고 배포할 때 설명하기도 괜히 복잡하다. 그냥 평이하게 원래키로 맵핑하자. 자판의 맵핑만 바꿔 주니 너무 잘 동작한다. 차후 매크로키를 9개까지 늘릴 수도 있어 7~9까지의 키는 미할당한 채로 남겨 두기로 한다.

Alt키가 공백키의 양쪽에 있어 Num, Lang으로 맵핑되어 있고 정작 Alt키는 Menu키에 맵핑해 놨는데 이게 좀 아쉽기는 하다. 그러나 모드키가 엄지에 최대한 가까워야 하니 어쩔 수 없는 일인 거 같다. 쿼티로 연습하는 사람에게 잘 숙지시키는 방법밖에 없다. Ctrl키가 Edit인 것도 어차피 무척 헷갈릴 것이다.

그 외 쿼티와 좀 다르게 맵핑된 게 ] 키가 새밖열 3행에, \키가 FN에 맵핑된 것인데 위치상으로는 맞지 않아도 최대한 가까이 남은 키를 쓰다 보니 어쩔 수 없는 거 같다. 시제품 제작할 때 배선 거리도 고려해야 하니 너무 멀어서는 안된다. 이렇게 되면 87키 중에 남는 키는 다음 14개이다.

 

PrtSc, ScrL, Pause, Ins

`, 7, 8, 9, 0, -, +, BS

사용 불가 : FN, Shift

 

아직 좀 여유가 있다. 맵핑을 이렇게 바꿔 버리면 기존에 만들어 두었던 소젯 1호 키보드는 ETC가 먹지 않을 것이다. 어차피 1호는 문자 입력만 테스트할 목적으로 만든거니 소프트웨어의 맵핑을 바꾸지 않는 한 어쩔 수 없다. 지금이라도 맵핑을 합리적으로 조정해 놔야 2호부터는 큰 충격없이 일관되게 만들 수 있다.

19일부터 23일까지 5일중 어제는 오산에 부동산 문제로 좀 다녀 왔고 4일간 후킹 작업을 했다. 예전 작업 성과나 가져 오자 싶어 시작했는데 기대 이상으로 많이 진척되어 실사용이 가능한 수준까지 이르렀다고 자평한다. 체력이 고갈되어 잔문제는 앞으로 하나씩 해결할 예정이고 이 정도면 만족스럽다.

22 2 24 - 소젯 3

월요일 저녁 늦게 혹시나 싶어 스텐 주문한 곳에 무작정 가 보니 완성되어 있었다. 25000원이라고 하더니 부가세 10%까지 27500원이었다. 소량이니 뭐 할 수 없지. 가져온 그냥 바로 조립부터 해 봤다.

도면대로 진짜 똑같이 구멍을 뚫어 놨다. 손으로 이걸 뚫으려면 얼마나 개고생을 해야 할지 아찔하다. 사선 부분이 조금 삐뚤하지만 키는 꼭 맞게 잘 들어 갔다. 스위치는 체리축 예전에 사 놓은걸로 끼우되 축이 다 달라 이것 저것 섞어서 끼웠다. 문자 부분은 적축, 잘 안쓰는건 갈축, 좌우는 청축이다.

다 끼우고 나니 딸랑 여섯 개 남는다. 분해해 놓은 다른 스위치도 좀 활용해야겠다. 키캡은 검정은 좀 그렇고 레인보우 사 놓은걸 끼웠는데 원래 키보드의 수평 위치에 따라 높이가 좀 제각각이다. 스텐판도 딱딱한데다 스위치의 핀이 뾰족해 책상에 얹으면 긁힌다. 그래서 임시적으로 다리를 달아 각도를 줬다.

앞쪽은 낮게 했는데 제일 아래쪽 엄지키의 핀이 걸리적거려 구부렸다. 이 판은 굳이 연결하지 않더라도 이대로 테스트 목적으로 사용해도 될 거 같다. 막상 다 조립하고 보니 텐키레스보다 더 거대하다. 높이는 비슷한데 폭이 훨씬 더 넓다. 똑같은 피치에 좌우 공간 띄우고 벌려 놓은데다 매크로까지 있으니 더 넓을수밖에 없다.

며칠동안 이 키보드를 좀 테스트해 봤는데 굳이 납땜까지 안해도 쳐 보면 뭐가 문제인지 개선점을 찾을 수 있다. 결국 이건 그냥 중간본인 셈인데 원하면 연결할 수는 있지만 굳이 그럴 필요까지도 없을 거 같다. 이 자판으로 테스트해 본 결과 다음과 같은 개선점을 찾았다. 다음판은 이 문제점을 다 해결한 후 제작할 계획이다.

 

- 우선 너무 넓다. 아무리 풀배열이라도 텐키레스보다 더 넓어서는 곤란하다. 기성품 스위치와 키캡을 활용해야 해서 표준 19미리로 했는데 벙벙하다. 제자리 배열이니 굳이 그럴 필요가 없고 그래서도 안된다. 스위치가 14 16까지는 줄일 수 있다.

- 편집, 매크로를 5미리 정도 띄웠는데 바짝 붙여도 될 거 같다. 어차피 기울어진 각도가 달라 하단만 붙을 뿐이며 서로 방해하지 않는다. 피치에서 2미리 줄이고 간격 3미리 줄이면 양쪽으로 10미리나 줄어든다. 가장자리와의 간격도 좀 더 줄일 수 있다.

- 좌우 자판 각도가 11도인 이 상태에서 손을 자판에 얹으면 손목이 살짝 꺽여 불편하다. 11도가 맞으려면 좌우 좌판이 현재 기울기보다는 더 멀어져야 하는데 이러면 크기가 커진다. 거리를 유지하려면 문자판을 더 기울여야 하는데 대충 14도까지는 기울여야 할 거 같다.

- 막상 타이핑을 해 보니 평면상으로는 기울어져 있어도 손가락을 바닥에 밀착하려면 손목을 튼 상태여야 한다. 양손 바닥을 약간 마주 보도록 중앙 부분을 볼록하게 만들면 어떨까 싶은데 인체 공학 키보드가 이런 식이다. 대략 5도 정도만 들면 될 거 같다.

 

먼저 키피치를 줄여 보자. 19는 너무 넓은게 확실하고 18이나 17로 줄일 예정인데 17 이하면 키캡도 깍아서 사용해야 한다. 일단 기성품의 키피치부터 확인해 보자. 보유한 소형 키보드를 다 꺼내 키피치를 확인해 봤다. 이럴 때 쓸라고 열심히 모아 놨지.

일반 키보드는 19미리이다. 제일 아래쪽 키보드는 17미리인데 2미리 더 줄어도 전혀 답답하지 않고 손가락이 부딪치지도 않는다. 수직 피치도 같을 줄 알았는데 16미리로 직사각형이다. 키캡 영역이 좁아 손가락이 벗어나는 느낌이고 키압이 높아 타건감이 좋지는 않다. 17미리로만 줄여도 괜찮을 거 같다.

중간의 흰건 16.5미리로 약간 더 좁되 수직, 수평 피치가 같다. 키압이 적당해 타건감도 괜찮은 편이다. 제일 위의 검정색은 15미리인데 이 정도 되니 확실히 좁다는 느낌이 들고 손가락끼리 스친다. 제일 소형 키보드는 9미리인데 양손으로 치는 개념은 아니라 그렇다. 손가락으로 칠 때는 이 정도 피치까지도 적응할만하다.

기계식 스위치 기준으로 과연 어느 정도까지 줄여도 되는지 플라스틱판에 구멍을 뚫어 실제 감을 체크해 보기로 했다. 만드는데 시간이 좀 걸리지만 이후에도 키피치는 정밀하게 점검해야 하니 애써 만들어둘 가치가 있다. 피치별로 도면을 그린 후 인쇄하고 붙인 후 키홀만 자르면 된다.

 

다이소에서 2000원에 3개짜리 플라스틱 도마를 사 뒀는데 두께가 얇지만 가공이 편하다. 큰칼이 더 편할줄 알았는데 잘 들지도 않고 손에 잡기도 불편하다. 작은칼이 훨씬 잘 든다. 나무판은 미끌거려 힘들고 커팅 패드가 딱 좋다. 3000원짜리인데 아끼지 말고 팍팍 쓰자. 이미 한본 해 본 작업이어서 구멍 12개 뚫는 정도는 금방이다.

위에서부터 순서대로 18미리, 17미리, 16미리이다. 구멍만 뚫는다고 다 된건 아니고 플라스틱판이 울지 않도록 가장자리를 다듬어 줘야 한다. 키홀은 14미리로 딱 정해져 있으니 스위치를 끼우기만 하면 되지만 키캡은 그렇지 않다.

 

18미리만 봐도 키캡끼리 딱 붙어서 서로 방해되며 17미리는 들어가지도 않는다. 16미리는 키캡 넓이가 스위치 간격보다 월등히 넓어 이대로는 끼울 수 없다. 결국 키캡도 가공해야 하는데 18미리는 옆을 살짝 긁어주면 되고 17미리는 조금 잘라내야 한다. 16미리는 자르는 정도로는 어림도 없고 아예 상하좌우변을 제거해야 꽂힌다. 다행히 키캡 윗면이 스위치 간격보다는 좁다.

키캡도 좀 작은게 있으면 좋으련만 기성품 중에는 그런게 없으니 어쩔 도리가 없다. 검색 좀 해 봤는데 높이별로는 나와도 넓이가 다른건 없다. 스위치 크기가 고정되어 있으니 키캡도 다 같을 수밖에 없다. 로우 프로파일도 높이만 낮을 뿐 크기는 같다. 키캡 때문에라도 피치를 너무 좁힐 수 없다. 최종적으로는 키캡도 따로 만들어야 한다.

이거 만드는데 3시간 정도 걸렸다. 칼질은 어렵지 않았지만 키캡은 두꺼워 잘라내기 쉽지 않았다. 위쪽에 칼로 흠집 내 놓고 뺀찌와 니퍼로 잡아서 겨우 부러뜨렸다. 이 작업 후 힘들어서 2시간동안 기절해 있었다. 이제 체력도 달리고 참 큰일이다. 머리는 돌아가는 거 같은데 몸이 안 따라주니...

샘플 만들어서 테스트해 보니 17미리가 딱 적당하다. 18미리는 좀 벙벙해 보이고 1미리 줄여 봐야 별 차이도 못 느낄 거 같다. 16미리는 손가락이 너무 밀착하는데다 손이 큰 사람은 불편해 보인다. 키홀을 빼면 철판이 2미리밖에 안남아 힘도 없을 거 같고 키캡도 적당한게 없으니 당장은 적용하고 싶어도 적용할 수가 없다. 내 맘대로 만들 수 있다면 가로 17, 세로 15가 딱 좋을 거 같은데 일단은 무난하게 17로 만드는게 좋겠다.

손가락 4개를 모아 놓고 중앙폭을 재 보면 75미리이며 손가락당 18.5미리인 셈이다. 그러나 손가락 끝 4개를 모아 재 보면 48미리 정도밖에 안되며 손가락당 12미리이다. 이건 딱 붙인거니 손가락당 2미리씩 띄운다 치면 최소 14미리폭은 확보해야 한다. 16이나 17이면 부족하지 않고 수직 피치는 14 12까지 줄여도 될 거 같다.

피치를 17로 하면 키간의 철판은 3미리인데 이 정도면 울렁대지는 않을 것이다. 키당 2미리씩 줄고 좌우 자판과 거리를 좁히면 대략 40~50미리 폭이 줄어든다. , 엄지쪽은 여전히 간격이 필요해 19미리와 비슷하게 띄웠다. 전에는 키홀과 외곽선을 맞췄는데 이제는 외곽선끼리 맞추면 된다.

17미리로 잠정 결정하고 이 피치로 다시 배치해 봤다. 문자판의 각도를 14도로 더 틀고 편집과 매크로는 외곽선이 밀착할 정도로 바짝 붙였다. 이 배치대로 하면 330 * 130이며 가운데 좀 벌려도 340이면 충분해 텐키레스보다 작다.

다음은 수직 기울기를 결정해야 한다. 수평만 기울이면 손목이 긴장된 상태를 유지해 자세가 불안정하고 건강에도 좋지 않다. 집게쪽을 살짝 들어 보면 좀 편안하다. 이 테스트를 위해 17미리 자판을 인쇄하고 아크릴판에 분리하여 배치해 봤다.

3T 아크릴판을 자르는데 톱질은 필요없고 아크릴칼로 죽죽 그은 후 뚝 부러뜨리기만 하면 된다. 이거 생각보다 잘 들고 효율적이다. 양쪽에 인쇄한 자판 오려 붙여 두고 거리와 각도를 다양하게 테스트해 봤다.

 

높이 10미리짜리 고무판 두 개를 오린 후 중앙에 놓아 약간 들어 올렸다. 이때 각도를 측정해 보면 대략 5도 정도 된다. 카메라 시점이 높아 사진이 좀 잘못 찍혔는데 5도 맞으며 고무판을 가운데 하나만 놓으면 4.5도 정도다. 높이 6미리 고무를 중앙에 받치면 3도인데 이것도 기울이지 않은 것보다는 편하다. 고무판을 더 안쪽으로 밀거나 세로로 세우면 8도이다. 이 각도도 편하기는 한데 중앙이 좀 불룩해 보인다.

 

앞으로 더 테스트해 보고 여러 사람들에게 느낌도 물어 봐야겠지만 느낌상 5도 정도면 부족하지는 않은 거 같다. 이 각도를지금 결정할 필요는 없다. 수직 각도를 주기로 했으면 좌우 철판을 각각 따로 만들어야 한다는게 중요하다. 좌우만 분리하면 밑바닥에 하우징을 어떻게 만드는가에 따라 수평, 수직 각도와 거리를 자유 자재로 변형할 수 있다.

나중에는 한꺼번에 만들더라도 지금은 테스트를 위해 분리해서 철판을 자르는게 좋을 거 같다. 어차피 와이어링 할거라 보강판이 어떤 모양이더라도 상관 없다는 자유가 있다. 좌우 분리할거면 아예 동형으로 2개를 만들어 한쪽을 뒤집어서 쓰면 된다. 매크로키는 당장 6개만 쓰되 차후 9개로 늘어날 수도 있다.

좌우 동형이라면 아예 글자판을 똑바로 배치하고 편집, 매크로를 바깥으로 기울여서 만들어도 된다. 좌우 동형이 아니라면 길이가 달라 중앙 부분을 똑같이 올려도 수직 기울기가 미세하게 달라지는 문제가 있다. 키 하나 넓이만큼의 길이라 거의 느끼기 어렵고 문제될 정도는 아니지만 하우징의 높이로 극복해야 할 수는 있다.

여기까지 테스트한 결과를 종합하면 키피치는 17로 하고 문자판은 14도 기울이며 좌우 철판을 따로 잘라 수직 각도와 기울기를 차후 결정한다. 수평 각도도 조정할 수는 있되 14도 정도면 무난할 거 같다. 다음주에 도면 그려서 철판 컷팅하고 소젯 2호 키보드를 완성하는 걸 목표로 하자. 다음은 납땜 준비를 해야 한다. 마침 시간 맞춰 재료가 도착했다.

커넥터는 두 종류이다. 국내 배송 카일 20개는 개당 500원이고 해외배송 게이트론은 개당 200원이다. 언제 어디서 사는가에 따라 가격이 천차 만별이다. 구조도 조금 다른데 카일은 일자인 반면 게이트론은 중앙에 둥근 홈이 있어 납땜하기 더 쉬울 거 같고 더 견고하게 납땜될 거 같다. 400개면 키보드 4개는 만들 수 있는 물량이니 당분간은 충분하다.

점프선은 10가닥이 붙어 있는 형태인데 2개씩 찢어서 사용하면 된다. 한 스위치로 가는 선을 그룹으로 묶어둘 수 있어 더 깔끔할 거 같다. 탈피해 보니 단선이 아닌 연선인데 너무 얇지는 않아 별 문제는 없어 보인다.

이제 납땜을 해 보자. 기판은 저번에 남겨둔 K640T를 쓰기로 했다. 시내 중학생한테 적축, 갈축 2개 사 뒀는데 이럴 때 잘 써 먹는다. 일단 갈축을 해채해 뒀다. 기판 구멍이 뚫려 있지 않아도 납땜하면 튼튼하게 붙어 있을 거 같다. Z자리에 시험 삼아 남땜해 봤다.

3행 알파벳은 기판과 가까우므로 100리로 잘라 연결하면 충분할 거 같다. 물론 더 멀리 이동하는 키는 더 길게 줘야 한다. 키보드에 전원 넣어 보고 스위치 연결해서 테스트해 봤다. 별 이상없이 잘 입력된다.

 

2호 키보드에도 이상없이 연결되는지 키 하나만 붙여 봤다. 이것도 물론 잘 된다. 나중에 컨넥터 제자리에 끼우는데 고생 좀 할 거 같다. 붙였다 뗐다 할 수는 있지만 선 길이가 무한히 길지 않아 최대한 붙여서 맵핑해야 하는데 핀셋으로 잘 끼워야 하며 컨넥터 방향을 맞춘다고 신경을 썼는데 방향이 반대로 된게 좀 있다. 되는걸 확인했으니 이제 부지런히 납땜질을 하면 된다.

선을 적당한 길이로 잘라 양쪽을 벌리고 탈피하여 꼬아 놓는다. 연선이라 꼬아 놓지 않으면 선이 흩어져서 연결하기 무척 불편하다. 두 가닥씩 컨넥터에 연결한다. 이 작업이 굉장히 오래 걸리는데 구멍이 너무 작아 끼우기 어렵고 고정할려면 한바퀴 돌려서 꼬아야 하는데 손가락으로 일일이 해야 하니 손이 쓰라린다.

도열해 놓은 상태 그대로 납땜한다. 홀을 막으면 안되고 옆에 선이랑 연결한 부분만 납을 먹여야 하는데 새로 산 납이 잘 흐르는 성질이 있어 열을 가하면 스르륵 스며 들어 어렵지 않았다. 다만 컨텍터 무게가 너무 가볍다 보니 인두로 조금만 밀어도 옆으로 밀려가며 수평이 유지되지 않아 그것도 불편하다. 암만 생각해 봐도 납땜할 때는 팔이 세 개 있어야 한다. 컨텍터에 끼운 후 기판에 선 끼워 고정하고 여기도 납땜한다.

이 작업도 딱히 어렵지는 않다. 1호 기판 CK87에 비해 구멍이 뚫려 있지 않지만 깊이가 적당해서 선 꼬아 밀어 넣고 납만 먹이면 잘 붙어 있는데 홀이 원형으로 아래로 공간이 있어 납도 잘 스며드는 편이다. 스위치당 두 가닥씩 묶여 있어 선끼리 꼬이지 않는 점도 좋다. 그러나 컨넥터 홀에 끼우는게 너무 힘들고 선이 자꾸 흩어져 이번에는 단선으로 해 봤다.

선이 흩어지는 건 사실 큰 상관은 없다. 그러나 두 선이 각각 놀다 보니 컨넥터 홀에 끼워 놔도 자꾸 빠진다. 단선이라 홀에 끼우는 것만 쉬울 뿐 고정이 잘 안되는 단점이 있고 기판에 끼울 때도 탄력 때문에 자꾸 삐져 나온다. 단선보다는 연선이 더 쉬워 나머지는 전부 연선으로 했다. 하다 보면 조금 요령이 생기는데 집게를 잘 쓰면 납땜이 좀 편하다.

두 세개씩 집게에 물려 두면 움직이지 않고 땜을 하는동안 잘 고정되어 있는다. 이런 식으로 10개 정도씩 계속 작업하는데 단계별로 걸리는 시간은 다음과 같다.

 

선 자르고 탈피 : 13

커넥터에 썬 끼움 : 12

컨텍터 납땜 : 15

기판에 끼움 : 8

기판 납땜 : 2

 

10개 연결하는데 딱 50분 걸렸으니 개당 5분씩 걸리는 셈이다. 시간당 12개씩 73개를 다 납땜하려면 쉬지 않고 6시간 걸린다. 중간 중간 쉬는 시간, 기절해 있는 시간 등을 다 더하면 하루가 더 걸리는 셈인데 실제로 1.5일이 걸렸다. 정말 지루한 작업이지만 음악 들으며 일하는 재미는 있다. 작업 완료 모습이다.

1호에 비해 좀 덜 산만하다. 그러나 솔직히 작업 시간은 거의 비슷하게 걸렸고 컨넥터 연결하는 게 만만치 않다. 이렇게 만들어 두면 기판을 여러 배열에 재사용할 수 있는 이점이 있겠지만 만약 딱 하나만 만든다면 그냥 스위치에다 바로 직결해서 납땜해 버리는게 더 빠르고 저렴할 거 같다.

커넥터에 더 편하게 연결하는 방법을 찾지 않는 한 시간이 걸리는건 더 단축하기 어렵다. 두 가닥씩 묶여 있는 단선 점프선을 찾아 봐야겠다. 굳이 꼬으지 말고 커넥터에 붙인 후 바로 납땜해 버리면 좀 더 빠르지 않을까 싶다. 세번째 기판 만들 때는 시간을 단축하는 방법에 대해 더 연구해 봐야겠다.

납땜 작업을 하는동안 좀 쉴겸 해서 3차 도면을 그려 보고 아우한테 부탁해서 DWG 파일까지 제작했다. 시제품 2호로부터 테스트한 모든 것을 다 적용했다. 키피치 17미리에 문자판 14도 기울이고 좌우 자판 밀착하고 엄지는 간격 유지했다. 내가 작업 설명서를 잘 작성해 주기도 했지만 원식이가 바로 작업해 줘서 도면도 정확하게 나왔다.

가장자리는 5미리씩 띄웠다. 높이는 130이고 왼쪽 158, 오른쪽 175이다. 딱 붙이면 폭이 333인데 좌우를 20밀리 정도 띄울 거라 350 정도 될 거 같다. 이 정도면 텐키레스보다는 폭이 더 좁아 좀 작아 보일 것이다. 수직 기울기는 철판 받은 후 결정할 예정이되 대략 5 ~ 8도 정도면 되지 않을까 예상한다.

도면을 현대 스틸로 보냈는데 금요일 오후 5시라 이번주는 그냥 넘겨야 한다. 석팀장께 전화했더니 그냥 월요일 오후에 찾으러 오라고 한다. 주말에 수직 각도 고려해서 하우징이나 좀 고민해 봐야겠다. 그리고 좀 쉬기도 해야 하는데 3 16일부터 출근할지도 모른다는 정보가 있어 시간이 넉넉치 않다.

보강판 제작까지는 일단 됐고 다음은 스위치와 키캡을 결정해야 한다. 키피치를 17미리로 하니 키캡이 들어가지 않아 일일이 깍아야 하는데 이건 어쩔 수 없다 하더라도 이왕 깍을거면 1호와는 다른 스위치를 써 보고 싶다. 키피치를 줄인 목적이 운지거리를 좁혀 속도를 높이자는 것이므로 스트로크도 가급적 줄여야 하고 키보드도 더 작게 만들어야 한다. 이때 필요한건 LP 스위치이다. 그러나 검색해 보면 LP 스위치를 파는 곳이 별로 없다.

그나마 파는 것도 다 옵티컬이라 납땜이 안되고 비싸다. 비싼건 개당 1700원이고 싸도 1000원은 넘는데다 다 해외 배송이고 기껏해야 20개 한 묶음이다. 알리에서 찾아 보면 좀 싼 것도 있기는 하다. 90, 70개에 대략 6만원 넘으니 이것도 개당 가격은 800원꼴이다. 게다가 알리에서 뭘 사 본적이 없어서 거래 뚫기도 귀찮다.

더 큰 문제는 스위치는 비싸도 일단 구한다 치더라도 키캡은 더 구하기 어렵다는 점이다. LP끼리도 키캡이 호환되지 않아 묶음으로 파는걸 찾아야 하는데 그런게 없고 판매 사이트도 어떤 키캡을 쓴다는 정보가 없어 괜히 사 봐야 쓰지도 못할 확률이 높다.

이렇게 어렵게 일일이 수집하기는 어려우니 아예 완제품을 사 해체해서 쓰는게 어떨까 하는 생각이 들었다. 전에 산 S200 LP 적축을 분해해 봤는데 이건 축 교체형이 아니라 납땜으로 해체해야 하는 어려움이 있고 국내에 안 파는 키보드라 구하기도 어렵다. 이러던 차에 기가 막힌 걸 발견했다.

완제품이고 축교환형인데다 가격까지 착하다. 국내에서 쉽게 구할 수 있고 중고 매물도 꽤 많다. GTMX라는 저가형 스위치인데 키감은 영 별로라고 하지만 지금 그런게 중요한게 아니다. 뽑아 쓸 수 있다는게 어딘가? 키캡은 모두 플랫이라 아무거나 뽑아서 쓰면 된다. 이중 사출이지만 그냥 플라스틱일 듯하다.

텐키레스 모델만 있고 청축, 적축 두 가지 종류로 나오며 쓸데는 없지만 RGB까지 달렸다. 유선 전용인데 C타입이라는 것도 마음에 든다. 청축 블랙, 적축 화이트로 일단 2개 주문했다. 다음주 화요일에나 올텐데 월요일 하우징 만들어 두고 이 스위치를 적극 활용해 봐야겠다.

밤새 소젯 1호로 타이핑을 해 봤다. 게시판에 글도 쓰고 장편 사용기도 하나 써 놓고 이것저것 프로그램도 사용해 봤다. 문장을 입력하는데는 큰 불편이 없고 편집도 원활하다. 지금도 소젯으로 치고 있는데 워드에서도 아주 잘 동작한다. 다만 아직 조합키 홀드에는 좀 문제가 있다. 이 정도만 해도 실용성은 그럭저럭 확보한 거 같아 만족스럽다.

-----------------------------

22 2 27

소젯 1호로 장시간 타이핑을 해 보니 충분히 쓸만하다. 그러나 여러 가지 버그와 아쉬운 점이 발견되어 대대적인 수정 작업을 해야 한다. 처음 후킹을 도입할 때는 일단 문자열만 제대로 입력되도록 하자는 생각이었는데 그게 다 되고 나니 이왕이면 실사용에 아무런 불편이 없도록 목표치를 상향 조정하게 되었다.

 

- 당근에서 Ctrl+휠로 확대가 안된다. 또 다음팟에서 Shift+오른쪽 이동으로 재생 위치 빨리 건너 뛰기도 안된다. 둘 다 조합키를 무시한다는 면에서 원인이 같다. 이게 제일 심각한 문제이며 쿼티와 똑같은 활용성을 확보하려면 반드시 해결해야 한다. 현재 소젯이 조합키를 다루는 방식에 문제가 있다. 키보드 드라이버는 각 키의 누름 상태를 따로 추적하고 응용 프로그램은 GetKeyState 함수로 특정키의 눌림 여부를 조사하도록 되어 있다. 그러나 소젯은 조합키 자체의 누름, 놓음을 관리하지 않고 조합되는 키가 입력될 때 조합키를 먼저 누른 후 조합되는 키를 누르고 조합키를 떼는 식이다. 예를 들어 Ctrl + C를 누른다면

 

키보드 드라이버 : Ctrl 누름 -> C 누름 -> C -> Ctrl

소젯 : Ctrl 누름-기록만 함 -> C 누름:Ctrl 누르고 C 누름 -> C : 무시 -> Ctrl -떨어짐을 기록만 함

 

누르고 놓을 때를 일일이 보고하는 식이 아니라 누를 때만 어떤 동작을 하도록 되어 있다 보니 Ctrl을 홀드한 상태로 어떤 동작을 할 때를 인식하지 못한다. 문제의 핵심은 다음 함수이다.

 

void KeyEventModi(BYTE vk, BYTE scan, bool ctrl, bool shift, bool alt, bool win)

{

     ....

     // 조합키 누르고

     if (ctrl) KeyEvent(VK_LCONTROL, 0, AC_DOWN);

     if (shift) KeyEvent(VK_SHIFT, 0, AC_DOWN);

     if (alt) KeyEvent(VK_LMENU, 0, AC_DOWN);

     if (win) KeyEvent(VK_LWIN, 0, AC_DOWN);

 

     // 키 눌렀다 떼고

     KeyEvent(vk, scan, AC_DOWNUP);

 

     // 조합키를 놓는다.

     if (ctrl) KeyEvent(VK_LCONTROL, 0, AC_UP);

     if (shift) KeyEvent(VK_SHIFT, 0, AC_UP);

     if (alt) KeyEvent(VK_LMENU, 0, AC_UP);

     if (win) KeyEvent(VK_LWIN, 0, AC_UP);

}

 

내부적으로 조합키 누름을 인식은 하지만 조합키를 실행한 후 조합키를 강제로 떼 버린다는 것이다. Ctrl + C를 누르면 아예 눌렀다 뗀 걸로 처리해 버리니 Ctrl을 홀드하고 있는 상황을 반영하지 못한다. 진짜 사용자가 키보드를 조작하는 것과 똑같은 순서대로 keybd_event를 발생시켜야 한다. 그래야 GetKeyState 함수가 키의 상태를 제대로 보고하고 응용 프로그램이 이에 반응할 수 있다.

그렇다면 훅 프로시저가 메시지를 받는 족족 키만 원하는대로 바꿔서 보내 주면 되지 않느냐 싶겠지만 그것도 아니다. 소젯은 Shift키에 대해 Once 기능이 있으며 순서대로 누르지 않아도 조합되는 특성이 있어 이 부분에 대해서는 따로 관리해야 한다. Ctrl 조합키도 마찬가지이다.

shiftOnce, ctrlOnce 두 개의 변수로 두 키의 직전 누름 상태를 기억해야 한다. 반면 altOnce, winOnce는 필요 없다. 이 두 키는 단독으로 눌러도 어떤 동작을 하도록 되어 있어 반드시 조합으로 누를 때만 동작해야 한다. 사실 꼭 그래야 할 필연성은 없지만 윈도우가 그렇게 동작하니 일단을 따라야 한다.

KeyHookLL 예제로 테스트해 보니 메시지를 특별히 변형하지 않고 CallNextHookEx로 보내 주기만 하면 모든 조합키가 정상적으로 잘 동작한다. 그리고 오토 리피트 기능도 굳이 애써 막을 필요가 없다. 그냥 발생하는 족족 보내 줘도 응용 프로그램이 알아서 무시한다.-> 그런줄 알았는데 lang, edit, num 은 모드가 계속 바뀌어 막아야 함. 문자 입력은 KeyDown에서 발생하지만 KeyUp을 같이 보내도 이상 없으며 그게 더 자연스럽다. 소젯에 일단 다음 코드를 추가했다.

 

LRESULT CALLBACK OnKeyHookLL(int nCode, WPARAM wParam, LPARAM lParam)

{

     .....

     // 논리적으로 키를 처리하는 함수로 넘긴다.

     ProcessKey(kidx, bDown);

 

     // 키 처리 후 Shift, Ctrl, Win에 대한 누름/놓음은 체인으로 그대로 보내 줘야 한다.

     // 그래야 GetKeyState가 제대로 조합키의 상태를 읽어 타겟에서 조합키가 먹는다.

     if (kidx == K_SHIFT || kidx == K_CTRL || kidx == K_WIN) {

          return 0;

     }

 

     // Alt Menu키에 맵핑되어 있어 그대로 보내면 안되고 진짜 Alt키로 바꿔서 다시 보내야 한다.

     // Alt의 가상키가 VK_MENU이고 이게 Menu(VK_APP)에 맵핑되어 있는 건 순전히 우연이다.

     if (kidx == K_ALT) {

          KeyEvent(VK_MENU, 56, bDown ? AC_DOWN : AC_UP);

          return 1;

     }

 

     // 체인으로 보내지 않고 먹는다.

     return 1;

}

 

다른 키는 ProcessKey에서 알아서 처리하고 없애 버려도 되지만 Shift, Ctrl, Win, Alt에 대해서는 누름, 놓음 모두 체인으로 보내 GetKeyState의 내부 배열을 관리하도록 해야 한다. return 0만 하면 체인으로도 간다. , Alt Menu에 맵핑되어 있어 이 키는 먹어 버리고 Alt키로 바꿔서 보내야 한다.

이 코드만 추가해도 Ctrl + , Shift + 오른쪽이 잘 실행된다. GetKeyState가 제대로 판단하고 있다는 얘기다. 문제는 KeyEventModi 함수에서 조합키를 또 눌렀다 뗀다는 점이다. 조합키 상태는 디바이스 드라이버가 관리하고 있으므로 이제 조합된 키만 보내주면 된다. , Shift Ctrl에는 Once 기능이 있어 이 플래그가 켜져 있으면 Shift, Ctrl도 보내야 한다.

bShiftOnce는 원래 있었으니 bCtrlOnce 변수를 추가한다. 두 키를 눌렀다 바로 떼면 상태를 토글한다. 원래는 bDown에서 토글했었는데 누른 후 아무 것도 하지 않고 그냥 뗄 때 토글하는게 정확하다. 누른 상태에서 다른 키와 조합으로 눌렀으면 이때는 GetKeyState가 누른 걸 인식하므로 Once 상태가 필요 없다.

 

     // Shift 상태 변경

     if (kidx == K_SHIFT) {

          if (bDown) {

               // 누를 때는 아무 것도 안한다.

          } else {

              // 눌렀다가 그냥 놓았으면 Shift 상태를 토글한다. 조합으로 다른키와 함께 눌렀으면 ShiftOnce가 아니다.

              if (KeyQueue[0].kidx == K_SHIFT) {

                   bShiftOnce = !bShiftOnce;

              }

          }

     }

 

Once는 다음 입력 한번에만 적용하므로 이동, 문자 입력, 조합키 입력 등 모든 경우에 즉시 해제한다. 이게 안 풀리면 계속 누르고 있는 것으로 판별할 위험이 있다. 키 이벤트를 보낼 때는 Once 상태만 고려한다.

 

void KeyEventModi(BYTE vk, BYTE scan, bool ctrlOnce, bool shiftOnce)

{

     ....

     // Once 상태의 조합키 누르고

     if (ctrlOnce) KeyEvent(VK_LCONTROL, 0, AC_DOWN);

     if (shiftOnce) KeyEvent(VK_SHIFT, 0, AC_DOWN);

 

     // 키 눌렀다 떼고

     KeyEvent(vk, scan, AC_DOWNUP);

 

     // Once 상태의 조합키를 놓는다.

     if (ctrlOnce) KeyEvent(VK_LCONTROL, 0, AC_UP);

     if (shiftOnce) KeyEvent(VK_SHIFT, 0, AC_UP);

}

 

Alt Win의 상태는 볼 필요 없고 홀드 상태인 Shift, Ctrl도 볼 필요 없다. Once일 때만 Ctrl, Shift를 잠시 켜 주면 된다. ProcessModifier에서는 처리 후 즉시 Once를 해제한다.

 

void ProcessModifier(char ch)

{

     ....

     // 처리 후 Once 상태 즉시 해제

     bShiftOnce = false;

     bCtrlOnce = false;

}

 

조합키를 판별할 때도 Once 조건을 점검한다. Ctrl키를 홀드하고 있을 때뿐만 아니라 한번 누르고 있을 때도 Ctrl을 조합해야 한다.

 

bool IsModifierPress()

{

     return (IsKeyDown(K_CTRL) || bCtrlOnce || IsKeyDown(K_ALT) || IsKeyDown(K_WIN) || IsKeyDown(K_FN));

}

 

조합키 문자열을 구하는 GetModifierString 함수도 마찬가지로 Once 상태를 고려한다. 여기까지 작업하니 조합키 대부분 잘 먹는다. 다만 Win+Tab후 커서 이동키로 포커스 이동이 잘 안되는데 이건 좀 더 연구해 봐야겠다. 조합키를 처리하는 논리는 오늘 작성한 코드가 맞다. 잔 버그는 더 있겠지만 큰 흐름은 잘 정비한 거 같다.

 

- 앞쪽에 오타가 발생했을 때 편집 모드로 바꾼 후 앞으로 이동하여 오타난 글자를 지워야 하는데 BS가 없기 때문에 오타난 글자 앞으로 이동해서 Del키를 눌러야 한다. 한칸 더 앞으로 간다는게 굉장히 불편한데 편집 모드야 말로 BS가 필요하다. 처음에는 N 위치에 멀티미디어 Prev 따위 집어 치워 버리고 BS를 넣을려고 했다. 그러나 이 자리는 집안열이라 자세가 흐트러진다.

그러고 보니 편집 모드에서 Space가 놀고 있다. 이동하다가 공백을 입력할 일이 없으니 여기다 BS를 넣으면 좋을 거 같다. Shift+Space와 같아지는 것이다. 지금은 어떻게 되어 있나 봤더니 연습용은 공백이 입력되고 후킹은 아무 입력도 되지 않아 서로 다른데 이것도 수정해야 한다. 틀릴 수는 있어도 두 모드가 각각 달라서는 안된다.

이 문제를 점검하다 또 골때리는 상황에 부닥쳤다. 키보드 종류3에서 Ctrl+Space가 한자로 정의되어 있어 다음 글자의 한자 후보창을 보여 준다. 지금에서야 이걸 발견했다는 것은 한번도 눌러보지 않았다는 뜻이다. ApiEdit Ctrl+Space를 눌러도 한자창이 나타나지 않는데 IME를 완벽하게 처리하지 않아서이다. 원래대로라면 다음과 같이 동작한다.

if (kb->vkCode == VK_HANJA) 조건일 때 VK_SPACE로 바꿔 버려도 한자 후보창이 여전히 열린다. return 1로 먹어 버리면 일단 안 뜨기는 하지만 이후 Ctrl키가 고정 상태가 되어 버리고 풀리지 않는다. Edit에 맵핑해 놓은 왼쪽 Ctrl뿐만 아니라 진짜 Ctrl키에 맵핑해 놓은 오른쪽 Ctrl에 대해서도 Space와 함께 누르면 한자창이 열린다. 이건 어찌보면 당연한거고 이렇게 되어야 한다.

디바이스 드라이버라면 내맘대로 키의 기능을 정의할 수 있어 이런 문제가 없는게 당연하지만 남의 드라이버 위에서 굴러가는 후킹 프로그램이다 보니 골치 아픈 문제가 발생했다. 소프트웨어적으로 해결해 보되 만약 이 문제가 잘 풀리지 않으면 맵핑을 바꿔야 한다. 이런 문제를 만나면 급피곤해지고 체력이 바닥나 그냥 드러 눕게 된다. 포기하고 가만히 누워서 생각해 보니 누를 때 바꾼 후 먹어 치우고 놓을 때는 그냥 보내주면 될 거 같다. 일어나서 다음과 같이 코딩했다.

 

     if (kb->vkCode == VK_HANJA) {

          if (bDown) {

              KeyEvent(VK_CONTROL, 29, AC_UP);

              KeyEvent(VK_SPACE, 57, AC_DOWN);

              return 1;

          } else {

              return 0;

          }

     }

 

Ctrl+Space를 누를 때 Ctrl 놓고 Space를 누른 걸로 하고 진짜 놓을 때는 그냥 체인으로 보내 Ctrl 고정되지 않도록 했는데 이 작전이 잘 통했다. 로그를 찍어 보니 Ctrl을 놓을 때 VK_PROCESS가 와서 한자 모드를 해제하며 VK_HANJA에 대한 Up은 오지 않는다. 다음으로 평이하게 Space를 누른걸로 메시지가 온다. 일단 한자창은 열리지 않고 공백도 잘 입력된다. LAY_EDIT에서의 공백을 BS로 바꾸도록 했다.

 

     if (bDown && kidx == K_SPACE) {

          // Shift + Space BS와 같음. 한글자만 지운 후 Shift는 즉시 해제한다.

          if (IsShift() || layer == LAY_EDIT) {

              ProcessBs();

 

될거 같은데 안된다. 공백만 입력한 것이기 때문에 아직 EDIT 레이어로 전환하지 않았다. Ctrl을 계속 누르고 있으면 EDIT 모드가 되어 두 번째부터는 BS가 된다. Edit 푸시에 대해서는 공백으로 잘 동작하지만 편집 모드가 풀리지 않는다. BS 처리 후 EDIT 레이어를 푸는 처리도 필요하다. 총체적으로 문제가 많은데 더 연구해 보니 몇 가지 실수가 있었다. 시행착오도 분명히 기록할 필요가 있어 앞의 코드도 기록은 남겨 두었다.

 

     if (kb->vkCode == VK_HANJA) {

          if (bDown) {

              KeyEvent(VK_SPACE, 29, AC_UP);

              Trace("1");

              KeyEvent(VK_CONTROL, 29, AC_UP);

              Trace("2");

              KeyEvent(VK_BACK, 14, AC_DOWNUP);

              return 1;

          } else {

              Trace("3");

              return 0;

          }

     }

 

Ctrl+Space를 놓을 때 VK_HANJA가 먼저 풀리며 로그 3을 찍는다. 그리고 VK_HANJA가 다시 온다. 여기서 Space를 먼저 놓고 Ctrl을 놓아 이 둘을 풀어 준다. 그리고 SPACE를 보내는게 아니라 BS를 보내야 한다. 처음에는 Space를 보내면 EDIT 레이어를 인식해서 BS가 될거라 생각했는데 KeyEvent는 후킹으로 가는게 아니라 타겟으로 가는거니 이대로 보내면 Space일 수밖에 없다. 다른 조건 볼 필요 없고 그냥 VK_BACK을 눌렀다 놓으면 한글자 깔끔하게 지워진다.

 

     // Space 처리. 숫자 모드이면 0 대신 입력

     if (bDown && kidx == K_SPACE) {

          if (IsKeyDown(K_EDIT)) {

              ProcessBs();

              goto end;

          }

          if (layer == LAY_EDIT) {

              ProcessBs();

              if (editLock == false) {

                   layer = LAY_LANG;

              }

              goto end;

          }

          // Shift + Space BS와 같음. 한글자만 지운 후 Shift는 즉시 해제한다.

          if (IsShift()) {

 

K_SPACE에 대해서는 앞서 두 조건을 먼저 처리한다. K_EDIT를 누르고 있는 상황이면 BS로 처리하고 바로 리턴한다. 누르고 있지 않더라도 EDIT 레이어이면, 즉 한번만 편집하는 상황이면 BS를 한번 입력하고 언어 모드로 즉시 복귀하면 된다. 여기까지 작성하니 Edit 푸시, 홀드 상태의 Space BS로 잘 바뀐다.

...... 더 테스트해 보니 이것도 끝이 아니다. 왼쪽 Ctrl Edit에 맵핑해 놓았으니 이게 맞지만 오른쪽 Ctrl은 진짜 Ctrl이니 이건 한자가 열려야 맞다. 양쪽 Ctrl 모두에 대해 디바이스 드라이버는 VK_HANJA를 생성해 내는데 이걸 구분해서 걸러야 한다. 바로 연이어 오므로 이전 VK를 보면 될거 같아 prevVk 변수를 만들고 직전에 누른 키가 오른쪽 Ctrl이 아닐 때만 VK_HANJA를 없애 버리도록 했다.

이랬더니 더 이상한 현상이 일어난다. 오른쪽 Ctrl + Space에 대해 한자창이 열리지 않고 앞쪽 몇 글자가 한꺼번에 지워져 버리고 왼쪽 Ctrl도 처음 입력은 다시 공백이 되어 버린다. Ctrl키를 운영체제가 특별하게 취급하고 있어 후킹으로 조작하기는 한계가 있다. 어찌 잘 하면 될 거 같기도 하지만 키보드 종류마다 이 고생을 해야 한다니 도저히 못할 짓이다. 해가 중천에 떴지만 한잠 더 자고난 다음에 맵핑을 바꾸는 방법에 대해 진지하게 생각해 보자.

한잠 자고 일어난 후 결국 맵핑을 바꿔 보기로 했다. Ctrl이나 Alt는 디바이스 드라이버가 특별히 취급하고 있어 예외 상황이 많고 각 예외가 디바이스 드라이버마다 다르다는 점도 문제다. 왼쪽 끝의 `키가 남아 있으니 여기다 Edit키를 맵핑해 봤다. 별거 없고 Edit 키의 맵핑을 VK_OEM_3으로 바꾸면 된다.

 

{C_BASIC,   4,2,    VK_OEM_3,  0x0303, {-3,0},         0,                "Edit", },

 

물론 이게 다는 아니고 IsKeyDown에서 GetKeyState로 조사할 키도 VK_OEM_3으로 바꿔 주어야 한다. 이 부분이 아직 하드 코딩인데 차후 키맵 뒤져서 VK를 조사하는 걸로 리팩토링해야겠다. OnKey에는 VK_CONTROL일 때 확장키에 따라 Edit 또는 Ctrl로 가상키 할당하는 코드 제거하고 OnKeyHookLL에도 좌우 컨트롤키로부터 가상키를 결정하는 코드를 제거한다. 그리고 VK_HANJA는 체인으로 그냥 보내 주면 된다.

 

if (kb->vkCode == VK_HANJA) return 0;

 

ProcessKey의 논리는 딱히 수정할 게 없다. 나름 추상화가 되어 있어 가상키만 잘 조작해 주면 하부 흐름이 영향을 받는다. 여기까지 작업하면 모든게 정상적이다. 그러나 연습용에서 Ctrl+Space가 그냥 공백으로 인식되는 문제가 있는데 이는 ApiEdit가 한자를 지원하지 않아서이며 큰 문제는 아니다.

Edit의 맵핑이 `로 바뀌었으니 화면에도 자동으로 수정된다. OnPaint에서 Edit 레이어일 때 스페이스키의 캡션을 BS로 표기했다. Edit+Sp BS로 바꾸는 간단한 문제로 시작해서 맵핑까지 대대적으로 조정해서 작업이 컸다. 앞쪽 조합키 처리에 비해 무척 간단할 줄 알았는데 오히려 더 복잡하다. 이 문제로 꼬박 밤을 새고 오후까지 작업했으니 12시간 정도 걸린 셈이다.

, 그렇다면 Edit Ctrl에 맵핑하는게 부적절했다면 좌우 Alt에 맵핑된 Num, Lang은 어떨까? 현재는 별 문제가 없어 보이지만 키보드 종류를 바꾸면 또 어떤 말썽을 일으킬지 알 수 없다. 그래서 아예 운영체제와 무관한 1, \ 키로 바꿔 보기로 했다. 이 작업도 시간이 좀 걸리겠지만 해 볼만 하다.

 

{C_BASIC,   4,4,    '1',          0x0103, {-1,0},         0,                "Num",},

{C_BASIC,   4,7,    VK_OEM_5,  0x0103, {0,0},      0,                "Lang", },

....

{C_BASIC,   4,10,  VK_MENU,   0x0103, {3,0},      0,                "Alt", },

{C_BASIC,   4,11,  VK_APPS,    0x0303, {4,0},      0,                "Fn", },

 

Num, Lang의 맵핑이 바뀌니 Alt가 원래 자기키를 가져가고 Lang \를 뺏긴 Fn Menu키로 맵핑한다. 맵을 바꿔 주고 OnKey OnKeyHookLL에서 좌우에 따라 가상키 강제 맵핑하는 코드만 제거해도 잘 돌아간다. 그러나 후킹할 때 Alt Ctrl 조합이 안 먹는데 이는 후킹시 전달되는 가상키가 좌우 구분이 있어 GetIdxFromVk kidx를 찾지 못해서이다. 대표 가상키로 바꿔 키맵을 검색하는 코드가 필요하다.

 

     if (vk == VK_LCONTROL || vk == VK_RCONTROL) vk = VK_CONTROL;

     if (vk == VK_LMENU || vk == VK_RMENU) vk = VK_MENU;

 

OnKeyHookLL에도 누름 상태를 저장할 때 대표 가상키를 찾아 저장한다. 이제 VK_SJ_EDIT, VK_SJ_NUM, VK_SJ_LANG 세 개의 가상의 가상키코드는 이제 필요 없다. 맵핑이 명확해 arKeyDown 배열에 자기 자리가 있고 kidx만 찾으면 어떤 키인지 알 수 있기 때문이다.

중간에 다른 버그도 하나 더 발견해서 잡았는데 차맷 변경시 타겟의 IME 모드를 변경하는 기능이 Lang 홀드후 놓을 때는 적용되지 않았다. 다음 차맷으로 바꿀 때 뿐만 아니라 이전 차맷으로 돌아갈 때도 타겟을 동기화해야 하므로 이 코드는 ApplyChaMat에 있어야 한다. 코드 흐름상의 버그였던 셈이다.

맵핑을 바꾸면 코드의 여기 저기도 같이 바꿔야 하는데 이게 무척 불편하고 위험하다. 키맵만 바꾸면 맵핑을 조사해서 적용하도록 해야 차후 관리하기가 편하다. 맵핑된 가상키 정보는 가급적 키맵에서 찾아 쓰도록 했다. 여기까지 엄지쪽키의 맵핑을 왕창 수정했으며 FN키도 맵핑이 바뀌었다.

왼쪽의 ` 1이 왼쪽 엄지에 맵핑되고 2는 혹시 모드키가 하나 더 늘어날 때를 대비하여 예비로 남겨 둔다. 오른쪽의 \ Menu Lang FN에 맵핑하고 =키는 여유분으로 남겨둔다. 숫자열에 남은 3에서 -까지 9개는 매크로 영역에 맵핑하면 된다.

 

- 다음은 오타마타 버그가 하나 발견되었다. '' 에서 BS를 누르면 ''가 되는데 이 상태에서 Shift + ㅅ을 누르면 ''이 되지 않고 'ㅇㅆ'이 되어 버린다. 같은 방식으로 '' 에서 BS 후 ㅃ을 입력하면 'ㅇㅃ'이 된다. 둘 다 연습용에서는 나타나지 않으며 후킹에서만 문제가 발생하며 메모장과 ApiEdit에서 공통으로 재현되었다. Trace 넣어 조사해 보니 다음 조건문이 문제다.

 

if (Opt.bSsangWord && (KeyQueue[2].kidx == K_SPACE || KeyQueue[2].kidx == K_ENTER)) {

 

단어 처음 쌍자음 옵션이 켜져 있고 앞문자가 공백이나 개행인 상태에서 이전에 입력한 가상키(PrevHookVk)와 방금 들어온 vk가 같으면 BS로 지우고 Shift+Vk를 보내 쌍자음으로 바꿔치는 코드이다. 단어 처음에서 ㄱㄱ을 누르면 앞쪽 ㄱ을 BS로 지우고 Shift+ㄱ을 보내는 식이다.

그런데 잇BSㅆ 열이 우연히 이 조건과 일치한다. BS Shift+Space로 입력하니 큐의 앞문자는 BS가 아닌 Space로 기록되어 있고 이 양쪽의 ㅅ과 ㅆ이 둘 다 가상키 T여서 똑같다. 그러니 BS를 한번 보내 ㅣ를 지워 버리고 ㅆ으로 바꿔치며 그래서 ㅇㅆ이 된다. 단어 쌍자음 옵션을 끄면 현상이 나타나지 않는다.

우연히 조건이 같아 나타난 버그인데 해결하려면 단어 처음이 아닌 상태에서는 쌍자음 대체를 하지 말아야 한다. 앞문자를 Space가 아닌 BS로 큐에 기록하면 되지만 BS키가 따로 없으니 어쨌거나 Space를 누른건 맞고 이때 Shift 상태까지 큐에 기록하지 않으니 그게 공백으로 들어간건지 BS로 들어간건지 판단할 수 없다. 그래서 BS를 누를 때 PrevHookVk를 리셋하여 앞에 누른 문자가 없는 것으로 하여 문제를 해결했다.

 

     // 후킹중일 때는 BS키를 보내면 된다.

     if (Opt.bHooking) {

          KeyEventModi(VK_BACK);

          // BS Shift+Space로 입력하므로 단어 처음 조건과 일치해 복자음으로 잘못 판단하지 않도록 이전 vk를 리셋한다.

          // ' BS ' 입력시 앞의 ㅅ과 뒤의 ㅅ이 vk가 같고 중간이 space여서 이대로 두면 단어 처음 조건이 되어 버린다.

          PrevHookVk = 0xff;

          return;

     }

오토마타가 그다지 정교하지 않고 조건도 대충이다 보니 이런 우연에 의해 이상한 현상이 발생했다. 이런건 미리 예측하기는 거의 불가능하고 증세가 나타날 때 Trace 끼워가며 잡는 수밖에 없다.

 

- 연습 프로그램에 후킹 메시지를 보여 주는 것은 디버깅에 상당한 도움이 되지만 최종 사용자가 이걸 보고 싶어하지는 않을 거 같다. 로그 만드느라 시간을 소모하기도 하고 스크롤되는 모습이 정신 사납기도 하다. 디버그 모드에서는 켜 두되 릴리즈 모드에서는 꺼 두는게 좋을 거 같고 설사 릴리즈라도 필요하면 켜서 확인할 수 있어야 한다.

로그를 보여줄 것인가 아닌가 변수가 필요하며 이 변수를 토글할 수 있는 UI가 필요하다. viewHookLog 변수를 선언하고 디버그에서만 TRUE로 초기화한다. StartHook에서 이 변수값에 따라 리스트 뷰의 보이기를 결정하고 훅 프로시저는 로그 리스트가 보이지 않으면 아예 로그를 작성하지 않는다. 화면 왼쪽 변을 클릭하면 보이기 상태를 토글하도록 했다.

 

만 하루동안 대대적으로 소프트웨어를 수정했는데 양이 많다 보니 코드는 걸레가 되어 있을 것으로 예상된다. 지금은 원하는대로 대충 동작하는데 조금 더 점검해 본 후 리팩토링도 한번 해야겠다. 다행인 것은 후킹에 좀 버그가 있어도 시스템 안정성에는 별 문제가 없다는 것이다. 잘못된 입력을 자꾸 주면 워드가 가끔 스트레스를 받아 다운되는 경우가 있는데 아마도 UP 메시지를 제대로 보내 주지 않아서인 거 같다. 차후 안정성에 문제가 있다면 이런 부분도 점진적으로 개선해 나가야 한다.

맵핑을 바꿨으니 이제 소젯1호를 수술하자. 실사용은 하지 않더라도 기념비적인 녀석이고 2, 3호와 소프트웨어를 공유하려면 납땜질이 필요하다. 그리고 당장 오늘 새벽에 테스트할 장비가 없으니 이 녀석을 뜯어 고쳐서 점검할 수밖에 없다. 다음번에는 시제품과 소프트웨어 버전끼리 짝을 맞추더라도 이번에는 수리를 좀 해야겠다.

ETC는 이미 바뀌었고 Ctrl은 왼쪽으로 연결하고 Edit, Num `1, Lang \, Alt는 오른쪽으로, FN Menu로 바꾼다. 뜯어서 납땜을 여러번 해야 하고 선도 바꿔 연결해야 하는데 그나마 지금이라도 수정한게 다행이다. 차후에도 바뀔 수는 있겠지만 맵핑을 바꾸는게 쉽지 않다.

멀쩡히 잘 조립되어 있는 녀석 배를 가르고 밑판도 딴 후 ETC `1에 새로운 선을 연결했다. 중간에 보강판이 끼워져 있는 상태에서 선을 끼우고 납땜을 해야 하니 작업 자세가 참 안나온다. 다행이 몇 가닥 안되어 금방 작업했다. 789의 선을 잘라 ETC에 연결하고 Lang, Num `1에 각각 연결했다. 원래 연결되어 있던 키는 사용하지 않는다.

오른쪽의 키는 이놈 떼다 저놈에다 붙이고 하는 식으로 연결을 교체한다. 선을 끊어 다른 곳에 붙이면 되는데 길이가 짧을 경우 연장한 후 붙여야 하니 작업이 많다. 맵핑 수정한 후 테스트해 보니 모두 제자리에 붙었고 안되는 녀석이 없다. 깔끔하게 다시 조립했는데 다시 뜯을 일은 없었으면 좋겠다.

소젯 2호는 아직 연결 안했지만 ` 78에 선을 더 연결해 두었다. 1은 이미 연결되어 있지만 선이 짧을 거 같아 나중에 좀 늘려야 할 거 같다. 이왕 선 연결하는 김에 ins, bs, prtsc, scrlock, pause도 커넥터는 달아 놓을려고 했는데 이건 다음 버전에서 하기로 하자. 지금은 소프트웨어가 더 급하다.

업데이트한 프로그램과 맵핑 수정한 1호 키보드로 이것 저것 타이핑을 해 봤다. 한동안 쿼티를 써서 그런지 자리가 또 마구마구 헷갈린다. 번갈아가며 쓰기는 참 어렵다. 안되는 건 없고 기능적으로 이상한 것도 없지만 여러모로 불편한 점이 많다. 우선 1호가 풀배열이 아니다 보니 Edit 레이어로 전환이 잦은데 Num이랑 은근히 헷갈린다. 손을 이동하더라도 편집키가 일단은 있어야 한다.

46배열이 작고 귀엽고 손 이동이 덜해 편리한 면도 있지만 미니 배열은 아무래도 매니악하다. 이 배열에 이미 익숙해진 사람들이 더 간편하게 쓸 수 있는 배열이지 처음부터 메인이 되기는 어렵다. 키 개수에 너무 연연하지 말고 일단 늘린 후 나중에 줄이는 방법이 합리적일 거 같다. 4호는 펹집키 위에 3개 정도의 키를 더 넣어 볼까 생각중인데 3호부터 면밀히 테스트한 후 결정하기로 하자.

키피치랑 각도도 어색하고 키캡도 왠지 미끌거리는 느낌이다. 인덴트도 적응이 어려워 아직도 아래위 키 위치를 정확히 찾는데 애로가 있다. 이래서 직교로 가야 하나 보다. 소젯 3호가 완성되면 적어도 지금보다는 좀 많이 나아지지 않을까 기대되며 실사용도 가능할거 같다. 후킹이 별 문제는 없는 거 같은데 CPU 점유율이 은근 높다. 순차 검색하는 부분을 색출하여 최적화도 좀 신경써야겠다.

------------------------------

22 3 1

3차 시제품 스텐판이 완성되었다. 금요일 저녁에 맡겼더니 월요일 오후 3시쯤 그냥 오면된다 해 놓고 막상 가 보니 아직 멀었다고 한다. 계산 먼저 하고 내일 아침에 찾기로 했는데 이번에는 현금으로 25000원에 주었다. 마침 삼일절 휴무라 당장 찾지 못하면 모레까지 기다려야 하니 아침에 사무실 앞에 내 놓기로 했다.

아침에 내 놓는다는건 야간에 작업하겠다는건데 그러면 밤 늦게 오면 내 놓고 퇴근하지 않을까 싶었다. 9시에 와 봤는데 아직 없고 사무실에 불도 켜져 있었다. 일하는데 달라하기 뭣해 집에 갔다가 12시쯤 왔더니 사무실 앞에 놓고 퇴근했다. 반가운 마음에 얼른 가져 왔다.

좌우로 딱 예쁘게 잘렸으며 폭도 좀 좁아졌다. 좌우로 분리해서 만든건 참 잘 결정한 거 같다. 각도나 거리를 마음대로 조정할 수 있어서 자유롭다. 2호 위에 올려 보니 확실히 작아졌다.

양쪽으로 키 하나 폭만큼 줄어 든 셈인데 가운데를 좁히면 더 줄어든다. 엄지행은 간격이 이전과 동일하고 각도도 11도에서 14도로 약간 더 기울였다. 이걸 기판 위에 올리면 된다. 올라가기는 당연히 올라가는데 기판이 예상외로 커서 하우질을 만들 여유가 없다. 기판의 하우징을 벗겨 내고 앉혀도 꽤나 큰 편이다.

기판이 343 * 115여서 폭은 철판보다 좁고 높이는 겨우 16미리 여유가 남는다. 옆판은 대지 못할거 같고 아래 윗판만 대되 그나마도 양쪽에 8미리밖에 안남아 나사만 겨우 박을 수 있는 수준이다. 기판을 활용하려면 철판 크기가 너무 과도하게 작아져도 안되고 작아져 봤자 기판 크기 이하로 키보드를 만들 수는 없다.

, 이제 기울일 각도를 계산해 보자. 하우징 하판폭이 380이니 절반의 폭은 190이다. 거리에 따라 철판을 놓을 위치가 달라지면 되니 철판폭은 고려할 필요가 없다. 190의 중앙쪽을 5도 위로 올리려면 중앙의 높이는 다음과 같이 계산한다. 이럴 때 삼각함수가 필요할 줄이야.

6(0.1045) 19.85, 7(0.1219) 23.161, 8(0.1392) 26.448로 높아지며 10(0.1737) 33.003이 된다. 어떤 각도가 가장 편할지를 결정해야 높이도 결정할 수 있다. 하우징을 만들어 봐야 실제 느낌을 알 수 있으니 지금은 각도를 만들어서 비교 체험해 보는 수밖에 없다. 높이 17.5미리 고무판을 가운데 두고 양쪽에 철판을 둔다.

왼쪽이 조금 짧기 때문에 컷팅패드로 끝을 올려 줘야 양쪽 각도가 어느 정도 맞다. 지금은 오른쪽만으로 점검하고 있으니 굳이 그럴 필요까지도 없지만 말이다. 오른쪽 철판이 175이니 17.5/175 = 0.1이며 sin(x) 0.1이 되는 각도는 대략 5.8도이다. 이 계산이 과연 맞는지 각도기로 측정해 봤다.

얼추 비슷하게 나오는데 0.1도 단위는 고사하고 1도 단위로도 각도를 측정하는게 만만치 않다. 가운데 고무를 12미리 낮은걸로 바꾸면 12/175 = 0.0685이며 대략 4도 정도 된다. 그렇다면 8도로 기울이려면 중앙의 높이는 얼마여야 할까 sin(8) 0.1396에 빗변 175를 곱하면 24.43이 된다. 12미리 고무 두 개를 겹치면 딱 이 높이이다. 과연 이 높이가 쓸만한지 MS 스컬프트랑 비교해 봤다.

눈으로 보기에는 비슷한 거 같은데 스컬프트는 유선형이라 정확한 비교가 어렵다. 인체공학 키보드의 기울기가 얼마인지 공식 자료를 좀 검색해 봤는데 못 찾겠고 눈대중으로 봤을 때 5~10도 정도인 거 같다. 결국 각도는 그냥 내가 임의로 결정할 수 밖에 없다. 어차피 4, 5호 몇 번은 더 만들어 볼테니 지금 최종 결정할 필요도 없다. 또 이건 시제품이 아니라 하우징의 문제라 중간에 원하면 바꿀 수도 있다.

이걸 검색하다가 또 다른 논쟁거리를 발견했는데 앞뒤 기울기가 평평한게 건강에는 더 좋다고 한다. 뒤쪽 다리가 타자기의 유물이라 안 쓰는 사람도 많고 인체 공학 키보드는 오히려 앞쪽을 들며 평평하게 해 놓거나 오히려 앞쪽을 들기도 한다. 나는 항상 뒤를 높여서 썼는데 좀 의외이다. 동의하지 않는 사람도 많고 팜레스트가 더 중요하다는 얘기도 있다.

이건 좀 더 검토해 봐야겠지만 당장 배선 공간이 필요해 뒤를 드는게 좋다. 그런데 이게 또 다른 문제가 있다. 한방향으로만 기울이면 별 문제 없지만 수평, 수직 다 기울이면 철판의 꼭지점 4개를 한 평면에 놓기 위해 복잡한 계산이 필요하다. 게다가 이렇게 하면 철판의 거리는 더 이상 조정할 수 없다. 이런 이유로 수직 각도는 일단 두지 말고 위, 아래 받침대를 동형으로 만들고 전체 키보드의 뒤쪽 다리를 붙여 조정해야 한다.

각도를 6도로 결정했을 때 중앙의 높이는 길이로부터 역산할 수 있되 190에 대해 가운데를 대략 2센티 정도 높이면 된다. 여기에 기판의 높이만큼은 위로 띄워야 한다. 오른쪽의 USB 포트와 콘덴서 때문에 9미리 정도 되는데 여유 조금 줘서 10미리라고 정했다. 그랬더니 가장자리가 너무 낮아 다시 15미리로 높였다. 상하 받침대는 다음과 같다.

이 치수면 과연 타당한지 골판지로 똑같이 오려 보고 철판을 위에 올려 봤다. 다음 사진은 가장자리를 10미리로 만든 것이며 뒤쪽에 다리를 붙여 키보드 전체를 20미리 수직으로 기울였다.

스위치가 아래쪽으로 내려오는 높이까지 고려하면 가장자리쪽은 확실히 낮고 가운데도 별로 여유가 없다. 그래서 15미리로 늘렸다. 이래 놓고 보니 앞쪽이 너무 높아 팜레스트가 있어야 한다. 기판의 높이를 가급적 낮추기 위해 USB 포트와 콘덴서가 있는 부분은 구멍을 뚫어 쏙 집어 넣었다.

원형쏘로 대충 뚫었더니 제일 아래쪽 콘덴서가 계속 걸려 모서리 부분을 좀 더 땄다. 이랬더니 기판이 하판에 딱 붙어 안정적이고 높이도 더 확보되었다. USB 연결선이 지나갈 홈도 파 두었다. 위 치수대로 이제 나무만 잘라 붙이면 된다. 공동 주택에서 새벽에 톱질을 할 수는 없어 전기톱 충전만 시켜 두고 6시 땡 하자마다 2층에 올라가 나무를 썰었다.

다이소에서 3000, 1000원에 사 둔 클램프가 이렇게 유용하게 쓰인다. 나무를 꽉 잡아 주니 떨리지도 않고 자세도 잘 나오고 아주 좋다. 톱날을 작은걸로 바꾸고 완충한 상태로 톱질을 하니 나무가 두부 썰리듯 쭈욱 잘 썰린다. 그러나 수직을 맞추는 것은 여전히 어렵다. 얼마전에 보쉬 직소가 중고로 올라온걸 놓쳤는데 그런거 하나 장만해 놔야겠다. 나무 한판 희생해서 앞뒤 지지대를 완성했다.

분명히 치수 딱 맞춰서 잘랐는데 왜 이렇게 높이가 안 맞고 수직도 들쭉날쭉인지 모르겠다. 어쩔 수 없이 튀어 나온 부분은 칼로 대패질을 해서 맞췄다. 물론 이것도 눈대중으로 대충 맞춘거다.

수평을 맞춘 후 철판을 올려 보니 끄덕거리는 부분 없고 대충 잘 맞다. 하판과 기판을 가운데 넣어 보니 배선하는데도 별 문제가 없을 정도로 공간이 충분히 확보된 거 같다.

배선하기 전에 철판을 지지대에 고정해야 한다. 나사못 각 4개씩 박아 놓으면 될 거 같은데 문제는 철판에 구멍이 안 뚫린다는거다. 가지고 있는 모든 기리를 다 동원해 봐도 철판에 겨우 흠집만 날 뿐 파고 들어가지 못한다. 쇠를 깍아 먹는 쇠가 필요한데 이건 아직 구비하지 못했다.

게다가 기판이 들어가면 철판이 지지대에 겨우 걸치는 수준이라 나사로 고정하기는 쉽지 않을 거 같다. 다른 보강 철물로 고정하는 방법을 생각해 봐야겠다. 이제 배선을 하나씩 연결한다. 제일 오른쪽의 편집키 9개부터 연결해 봤다. 컨넥터가 반대로 되어 있는게 있어 위에서 아래로 꽂아야 하는 것도 있다. 처음부터 고려했었는데 잠시 착각을 했는지 반대로 된게 꽤 많다.

9개만 연결한 후 잘 되는지 중간 점검해 봤다. USB 선은 이미 뽑아 놔서 꽂기만 하면 바로 동작한다. 쓸데없이 LED가 들어와 눈이 부시다.

연결 후 테스트해 보니 다 잘 되는데 End키가 인식되지 않는다. 기판부터 커넥터까지 꼼꼼하게 살펴 봤는데 외관상으로는 이상이 없다. 기판을 쇼트시켜 보니 인식되는 걸로 봐서 기판이 고장난 건 아니고 컨넥터를 쇼트시켜도 입력된다. 결국 스위치가 불량인데 그나마 이게 가장 나은 케이스이다. 스위치 빼서 청축으로 바꾼 후 입력해 보니 잘 된다.

고장난 스위치도 몇 번 눌러 주니 되기는 하지만 뭔가 불안해서 다른 스위치로 바꿨다. 게이트론 스위치인데 내구성이 썩 좋은 거 같지는 않다. 철판에 끼우면서 꽉 눌렀더니 충격이 가해진 모양이다. 되는거 확인했으니 이제 배선을 끼운다. 오른쪽부터 차례대로 하나씩 찾아 컨넥터에 연결했다.

대부분 순조롭게 잘 되었지만 일부 위치를 잘못 끼우거나 커넥터 다리 하나를 빼고 잘못 끼운게 있었다. 분리형으로 만들었더니 이런거 수정하기 편하다. 배선 길이는 넉넉하지는 않아도 연결 작업하기 딱 적당한 길이였다. 물론 좀 타이트하고 공간이 좁아 조심 조심 끼워야 하며 배선중에 선끼리도 꼬이지 않도록 잘 관리해야 한다. 배선을 거의 다 완료한 모습니다.

모든 선을 다 끼웠는데 딱 하나 1번 키만 선이 짧아 끼우지 못했다. 원래 1번이 M1이었다가 맵핑을 바꾸는 바람에 Lang이 되었는데 그러다 보니 아래쪽으로 내려갈만큼 길이가 충분치 않다. 이 선만 끊어서 연장한 후 Lang에 붙였다. 이래서 맵핑을 한번 결정하면 바꾸기 쉽지 않다.

배선하다가 선이 끊어지는 경우는 없었던걸로 봐서 납땜은 튼튼하게 잘 된 모양이다. 다 연결한 후 테스트해 보니 몇 가지 말썽이 있었다. 우선 Enter키를 누르면 BS가 같이 입력되는 이해할 수 없는 현상이 일어나는데 어딘가 합선이 있는 모양이다. 미사용으로 남겨 둔 오른쪽 Ctrl, 2, 왼쪽 Alt는 컨넥터가 방치되어 있는데 이 녀석들이 기판을 건드리는 모양이다. 그래서 안 쓰는건 종이 테이프로 봉해 놓았다.

그리고 또 하나, 막판에 FN키도 스위치를 달아 주었다. 입력에는 쓰지 않지만 LED를 끄려면 이 키를 밖으로 빼 놔야 한다. 오른쪽 Ctrl의 컨넥터를 잘라 FN에 붙이고 남는 청축 스위치 하나 붙여서 중앙에 던져 놓기로 한다. 웬만하면 그냥 둬도 되지만 LED가 정 눈에 거슬리면 끌 방법이 있어야 한다.

LED 밝기 조절은 FN+아래, 위 키인데 FN+아래를 몇 번 눌러주면 꺼진다. 그러나 이 상태를 기억하는건 아니어서 연결할 때마다 리셋되는 불편함이 있다. LED 타입이 몇 가지 있는데 이건 FN+Ins로 조정한다. Ins 키가 맵핑되어 있지 않으니 조정할 방법이 없고 굳이 조정할 필요도 없다.

스위치 체결은 무사히 다 된 거 같고 다음은 키캡을 끼운다. 이미 테스트해 본 바대로 17미리면 키캡을 깍아야 한다. CK 87 황축에 끼워 쓰다가 주인이 시제품 1호가 되는 바람에 놀고 있는 분필 키캡을 쓰기로 했다. 일단 간격이 이전과 동일한 엄지쪽부터 끼워 봤는데 중간키의 모서리만 깍으면 잘 들어간다. 그러나 양쪽의 조합키는 딱 붙어 있어 두 키의 가운데 부분을 잘라내야 한다.

좀 편하게 작업할 방법이 없을까 싶어 사포로 밀어 봤는데 가루만 떨어질 뿐 두께는 거의 줄지 않아 택도 없다. 그라인더를 사더라도 손으로 일일이 대 줘야 하니 그 또한 비슷할거 같다. 결국 손으로 일일이 잘라내는 수밖에 현재로서는 다른 방법이 없다. 과연 끼워는지는지 문자키 몇 개를 잘라 보았다.

 

윗면은 수직이라 깍으나 마나고 좌우와 아래쪽을 많이 깍아야 한다. 특히 아래쪽은 키캡 일부가 떨어져 나갈 정도까지 깊이 파야 서로 걸리적거리지 않는다. 깍은 후의 모습을 보면 모든 키가 다닥다닥 붙어 있으며 누를 때 살짝 스치기도 한다. 그러나 일단 깍아 놓기만 하면 타이프치는데는 큰 불편함이 없다.

키 몇 개 잘랐을 뿐인데 손가락이 아파 더 할 수가 없다. 새벽부터 지지대 만들고 배선 연결하고 스위치 끼우고 너무 고된 노동에 시달린지라 체력이 바닥 나 버렸다. 이럴 때는 한잠 푹 자고 일어나야 한다. 빨리 완성을 보고 싶은 마음이 간절하지만 그렇다고 꼴딱 밤샜는데 낮까지 샐 수는 없다. 12시 즈음 잠 들어 오후 5시쯤 깼는데 잠이 충분치 않아 개운하지는 않지만 키캡 정도는 깍을 수 있다.

이후 책상에 앉아 음악 틀어 놓고 칼로 키캡 오리기 놀이만 했다. 시간이 얼마나 걸리나 재 보니 다섯개 깍는데 26분 걸린다. 개당 5분 살짝 넘는데 좀 숙련된다 하더라도 이 정도 시간은 어쩔 수 없다. 칼날을 자주 갈아 주고 장갑을 끼고 컷팅 패드를 활용해서 미끌림을 방지하니 조금 편해지기는 했지만 그렇다고 속도가 월등히 개선되지는 않았다.

몇 개 깍다가 좀 쉬었다가 또 깍다가 밥 먹고 이런 식으로 쉬엄 쉬엄 하는 수밖에. 그런데 키캡 깍는건 진짜 힘든 일이다. 별 도구도 없이 컷트칼로 일일이 잘라 내야 하니 효율도 좋지 않고 자르는 오른손이나 그 작은 키캡을 꽉 잡고 있는 왼손이나 힘들어가기는 매 한가지이다. 어떡하던 3호를 완성하겠다는 일념으로 매달리기는 했는데 이거 하면서 문득 수핑 방망이 깍는 노인이 생각났다. 하루 종일 앉아서 키캡만 깍고 있는 내 처지가 꼭 그 노인 같다는 생각이 들었다.

그래도 대충 깍을 수는 없어 입력 가능한 수준으로 걸리적거리지 않게 충분히 깍아 냈다. 아직도 조금 스치는게 있지만 서로 방해하지는 않는 정도다. 키캡 깍는 작업은 제발 이번이 마지막이었으면 좋겠고 다음번에는 3D 프린터로 키캡을 꼭 만들어야겠다. 저녁 6시부터 시작해서 자정 약간 넘어서까지 깍았는데 기본 카테고리와 편집 카테고리까지만 완성했다.

18개 남은 상황이라 조금만 더 하면 될 거 같지만 여기서 중지했다. 손가락에 힘이 없어 강행하다가는 손을 베일 수도 있고 품질도 별로 좋지 않을 거 같다. 온몬이 땀에 젖었고 손이 덜덜 떨리는데 굳이 지금 할 필요는 없고 하루, 이틀 지난 후 손이 좀 회복 되었을 때 시간 떼우기용으로 하면 된다. 당장 테스트에 필요한만큼은 해 놨고 키캡이 없다고 해서 키를 누르지 못하는 것도 아니니 오늘은 여기까지만 하자. 키캡 깍으면서 나온 잔해를 보면 이게 얼마나 개고생이었는지 알 수 있다.

저 부스러기 조각만큼이나 양 팔을 부지런히 놀린 셈이니 참 대단하다. 다음에 이 작업을 또 하게 된다면 더 효율적인 방법을 꼭 찾아 봐야겠다. 그나마 다행인 것은 칼날이 기대 이상으로 잘 들어 플라스틱 정도는 잘 파고 든다는 점이다. 키캡 재질도 물렁해서 칼질이 먹혀 들어 큰 부상을 입지는 않았다.

---------------------

하룻밤 지나고 원기를 회복한 후 일어나자 마자 칼질을 또 시작했다. 손가락 힘이 조금이라도 회복되었을 때 몇 개라도 좀 해 놓자는 생각에서 시작했는데 막상 시작하니 아파도 그냥 끝장을 보자 싶어 다 해 버렸다. 무척 힘든 일이지만 아이러니하게도 은근히 중독성이 있어 계속 하게 된다.

다 깍은 후에도 다시 한번 점검해 보고 아래 위가 스치는 키캡을 빼 재조정했다. 아랫면만 깍아서는 완전히 분리되지 않아 일부는 윗면도 깍았다. 윗면은 거의 수직이라 깍으나 마나일거라고 생각했는데 막상 끼워 보니 그렇지도 않았다. 윗면의 모서리만 깍아줘도 꽤 간격이 벌어져 서로 부딪치지 않게 만들 수 있었다.

2호와 3호를 나란히 놓고 찍었다. 폭이 꽤 많이 줄었지만 그렇다고 엄청나게 작아졌다는 느낌은 들지 않는다. 19 17이 되었으니 비율상 10% 약간 더 작아진 것이다. 기울어진 각도도 사실 큰 차이는 없어 보인다. 같은 스위치를 쓰니 변형을 줄 수 있는 여지가 많지 않다. 그러나 수직 각도로 인해 타이핑 감은 좀 달라졌다. 작업을 마친 후 찌끄레기를 모으고 방 청소도 새로 했다.

다 하고 나니 뿌듯하기는 한데 너무 힘들어 힘이 하나도 없다. 이걸 1.5일에 걸쳐 한방에 다 해 내는걸 보면 나도 어지간히 끈기는 있는 셈이다. 그렇다고 다 만든 것도 아니다. 아직 하우징을 다 만들지 않아 대충 걸쳐만 놨는데 이것도 마무리해야 한다.

아직 보강판을 고정하지는 않았지만 여기까지 작업한 걸로도 테스트는 가능하다. 좀 쳐 보며 여러 모로 테스트해 봤다. 여기서의 테스트 결과는 곧 시제품 4호의 설계방향이기도 하다. 한번에 다 점검한게 아니라 몇일을 두고 지속적으로 점검 및 수정사항을 정리했다.

 

피치 : 간격이 좁아지니 이동거리는 약간 줄었다. 그러나 사람 습관이 무서운게 이전 간격에 익숙해 손가락이 너무 멀리 이동하는 경향이 있으며 가끔 엉뚱한 곳을 누른다. 좌우로는 이동할 일이 없고 수직으로 이동할 때만 그런데 어차피 조금 어긋나도 그 자리에 키가 있으니 별 문제는 아니다. 수평으로는 살짝 좁다는 느낌이 든다.

집게와 중지, 약지까지는 괜찮은데 새끼 손가락이 약지에 밀착하는 느낌이다. 17까지는 적응하면 괜찮을 거 같은데 16미리까지 내리면 답답할 거 같다. 수평쪽은 어차피 손가락이 이동하는 거리가 아닌 벌리는 간격이므로 애써 꼭 줄일 필요는 없고 18로 해도 괜찮다. 그러나 17로 치다가 쿼티 19로 돌아 오면 벙벙하다는 느낌이 든다. 키캡을 깍는 한이 있더라도 당분간 17 또는 18로 만들 예정이다.

그러나 수직 피치는 이동 거리여서 한참 더 줄여야 한다. 아래 위로 멀리 떨어져 있으면 손가락이 그만큼 피곤해지고 속도도 떨어진다. LP 스위치로 바꾸고 2행은 12로 하고 1, 3행은 높이 10 정도로 만드는게 적당하다. 12면 좁은 거 같지만 쿼티도 키캡 위쪽 면적, 즉 실제 손가락이 닿는 곳은 12~13에 불과하다.

엄지가 대략 4미리 위로 올라 왔는데 이 정도 위치면 괜찮다. 약간 더 올려도 될 거 같고 3행 피치를 줄이면 적당한 위치가 된다. 피치를 이 정도로 줄이면 처음엔 어색하겠지만 한번 결정한 피치에 익숙해지기만 하면 된다.

3 5일 추가 : 4호는 수평 18, 수직 17로 하기로 했다. 18로는 안 만들어 봤으니 시도해 볼만하고 수직은 가급적 줄여 놓는게 차후 최종판에 조금이라도 거부감이 덜 들거 같아 칼질을 또 하는 한이 있어도 가급적 줄이기로 한다. 다행히 LP 키캡이 얇아 자르기 어렵지 않고 밑부분만 자르면 된다.

 

직교 배열 자체는 굉장히 긍정적이며 인덴트를 주는 것보다 훨씬 낫다. 당장은 적응의 문제가 있지만 일관되다는 이점이 있고 키보드를 만들기도 쉽다. 직교 배열은 당연히 채택해야 할 정책이며 얼마나 쉽게 적응할 수 있는가는 수평, 수직 기울기를 잘 결정하는 문제이다. 앞으로도 시제품은 직교로 만들 예정이다.

 

수평 기울기 14. 2호의 11호에 비해 더 많이 준답시고 14도로 늘렸는데 막상 쳐 보니 각도가 많이 부족하다. 양팔 팔꿈치를 자연스럽게 벌린 상태에서 손을 쭉 뻗으면 손가락을 뻗는 각도와 직각을 이루어야 한다. 그러나 실제로 손을 얹어 보면 새끼쪽이 위로 올라간다.

이 상태에서 집게를 쭉 뻗어 보면 J에 있다가 U의 약간 왼쪽으로 뻗어지며 아래로 굽으면 M의 약간 오른쪽이 된다. 손가락이 뻗는 각도보다 수평 기울기가 작다는 얘기이다.

 

팔꿈치를 벌린 상태에서 꼭 키보드와 직각을 이루려면 손목을 살짝 꺽으면 된다. 쿼티 키보드에서 실제로 이렇게 치고 있으며 익숙해서인지 아니면 손목이 유연해서인지 모르겠지만 예상외로 큰 무리가 가지는 않았던 거 같다. 그러나 분명한건 일자로 쭉 뻗는게 더 편하다는 것이다.

그럼 바람직한 각도는 얼마일까 재 봤다. 양팔을 벌리고 앞으로 쭉 뻗은 상태에서 손을 안쪽으로 오므렸을 때의 각도만큼 자판을 기울이면 된다. 내 몸을 기준으로 실측해 보니 대략 22도 정도 나온다. 측정을 위해 팔을 벌렸다가 안으로 과하게 오므린 것이라 거의 최대값이라고 할 수 있다.

그럼 14도는 엄청 부족한가 하면 그렇지도 않고 양팔을 몸통에 밀착한 상태로 뻗어 보면 14도가 딱 맞다. 그러나 사람들이 일할 때 허리를 꼿꼿이 세우고 팔을 붙인 상태가 아니라 등받이쪽으로 기대거나 팔걸이에 팔꿈치를 걸치고 일한다. 그래서 22도가 나오는데 팔을 오므렸을 때는 오히려 이 각도가 클 것이다.

또 수평 각도는 두 자판의 거리와도 연관이 있다. 양쪽 자판이 가운데에 딱 붙어 있다면 각도를 더 많이 줘야 하지만 최대한 찢어 놓으면 많이 줄 필요 없다. 테스트 자판을 약간 벌려 놓았는데 좀 더 벌리면 14도로도 충분하다. 그러나 이러면 또 공간을 너무 많이 차지하니 거리를 조금 좁히고 각도를 더 기울이는게 좋겠다.

3 4일 추가 : 오랫동안 쳐보니 14도는 과하다. 의식적으로 편안한 자세를 취하면 팔을 벌리지만 장시간동안 그 자세를 유지할 수 없고 키보드 각도에 맞춰 팔을 벌리고 있으면 오히려 더 피곤하다. 양 팔이 저릿저릿할 정도로 부자연스럽다. 장시간 작업하면 팔이 자연스럽게 몸통에 붙게 되고 이때는 손가락 각도는 오히려 반대가 된다.

이 상태면 새끼 손가락이 윗행으로 이동하기 너무 힘들고 각도를 맞추려면 억지로 팔을 벌리거나 아니면 손목을 바깥쪽으로 꺽어야 한다. 이 자세는 안으로 구부리는 것보다 월등히 피곤하다.

2호는 11도인데 이것도 팔을 몸통에 붙이고 손을 얹어 보면 약간 더 기울었다. 어그노믹은 몇도인가 각도기로 재 볼려다 정확하게 잴수 없어 포기하고 사진으로 재 봤다. 파워포인트에 각도를 기울이는 기능을 활용한건데 이런 좋은 방법이 있을 줄이야. 각도기로 눈대중으로 재는 건 힘들기도 하고 정확하지도 않다.

9도 정도 기울어 있으며 14도로 하니 확실히 과하다. 저 정도 거리에 9도라면 소젯은 좀 더 띄우므로 8도만 해도 될 거 같다. 확 더 줄여서 만들어 봐야겠다. 이번 실험에서 '편안함'의 기준을 정적, 단시간으로 측정하지 말고 동적, 장시간으로 측정해야 함을 깨달았다. 이래서 시제품을 만들어 봐야 하고 일일이 쳐 봐야 한다.

그럼 이왕 만들어 버린 3호는 어떻게 할까? 이럴줄 알고 분리형으로 만든거다. 하우징 고정 나사를 풀고 약간 기울인 후 다시 조이면 된다. 14도를 8도로 조정해야 하니 하우징과 철판의 각도를 6도로 맞추면 딱 맞다. 조정하는 김에 거리도 약간 좁혔다.

이 상태로 타이프 쳐 보니 이전보다 확실히 편하다. 팔을 벌리지 않아도 되고 혹시 벌리더라도 손목을 안쪽으로 약간 꺽으면 된다. 안쪽으로 구부리는건 불편하지 않고 건강에 무리가 가지도 않는다. 쿼티를 쓰면서 이미 익숙해져 있기 때문일거다. 당분간 이 각도로 쓰되 시도했던 모든 기록을 보존하기 위해 4호 완성 후 애초의 각도인 14도로 다시 돌려 놓을 것이다.

 

수평 기울기 6도는 일단은 부족한게 맞다. 손을 자연스럽게 오므리면 10도 정도 되어야 편안해 보이며 8도까지는 높여야 한다. 그러나 각도를 높이면 키보드 중앙이 과하게 불룩해지는 반대급부가 있으며 그래서 팜레스트가 반드시 필요하다. 오히려 4도로 낮춰 키보드 전체 높이를 낮추는게 더 편할지도 모른다.

비록 4도라도 평평한 것에 비해서는 감이 좋고 손이 편안하다. 스위치를 LP로 바꾸면 그 높이차가 5미리 이상 낮아지니 이때는 6도까지 줘도 될 거 같다. 키보드 전체의 기울기에도 영향을 받아 앞쪽이 낮으면 덜 기울여도 된다. 일단은 6도 유지하고 그 이상 높이는 건 스위치를 바꾼 후에 다시 생각해 봐야겠다.

3 5일 추가 : 지지대를 만들 때 적용한 각도는 6도가 맞지만 재단상의 오차도 있고 아래쪽 기울기를 주다가 바뀐 것도 있고 철판이 짧아 달라진 부분도 있다. 현재 상태로 실측해 보니 7도다.

입력에 문제가 있거나 불편한건 분명히 아니지만 조금 더 낮춰도 될 거 같은 느낌이다. 변화를 주려면 차이가 많이 나야 하며 그래야 다양한 테스트를 해 볼 수 있으니 4호는 4도로 만들어 보기로 한다. 근데 이건 하우징의 문제라 차후 얼마든지 조정할 수 있다.

 

수직 기울기 : 현재 지지대 높이를 결정하지 못해 평평한 상태인데 앞쪽을 더 낮춰야 한다. 이게 수학적으로 참 어려운데 중앙과 뒤쪽을 들었을 때 앞쪽의 좌우 높이가 각각 얼마여야 하는지 모르겠다. 다음 사진을 보자.

중앙과 위쪽을 높이기 위해 좌상단(1)을 제일 높게 잡았다. 반면 우하단(3)은 최대한 낮추기 위해 바닥에 붙였다. 이때 우상단(2)과 좌하단(4)의 높이가 같지 않다는 것이다. 윗변이 기울어졌으니 아랫변도 기울어지는데 각도가 다르다. 우하단이 바닥이면 좌하단은 공중에 붕 뜬다. 그렇다고 좌하단을 우상단 높이만큼 높이면 우하단이 붕 뜬다.

기하학적으로 네 점을 지나는 평면을 정의할 수 없다. 삼각형은 세 꼭지점을 모두 지나는 평면이 반드시 있지만 사각형은 일부러 맞춰야 한다. 그렇다면 1점과 2점의 높이차만큼 4점의 높이를 정의하면 이게 맞을까? 수학적으로는 정확히 모르겠지만 직관적으로 생각해 보면 맞는 거 같다.

위 사진에서 1점은 높게 두고 3점은 바닥에 두면 대각선으로 기울어지며 2, 4점으로 끄덕거린다. 2점을 최대로 올리면 4점이 바닥이 되고 반대로 4점을 최대로 올리면 2점이 바닥이 된다. 1점의 높이를 절반으로 나누어 2, 4점에 주면 두 점의 높이가 같다. 2점과 4점 높이의 총합이 1점이며 두 점의 높이는 서로 반비례이다. 정량적으로 반비례인지 확실치 않은데 대충 맞는 거 같다.

그런데 또 여기에 한가지 더 고려할게 있다. 3점의 바닥도 0은 아니라는 점이다. 이 점도 어느 정도 위로 올라와야 하므로 전체 높이에 더해야 한다. 이건 일단 높이 0을 기준으로 계산해 놓고 전체를 수직으로 평행 이동하면 된다. 다음 문제는 이런 식으로 2, 4점의 높이를 정했을 때 오프셋이 바뀌어도 비율이 유지되는가이다. , 자판의 간격을 벌리기 위해 아래, 위로 이동해도 네 변이 모두 한 평면에 속하는가인데 정확히 모르겠다.

또 자판의 길이를 미리 고려해야 한다. 현재 지지대는 기판 길이에 맞춰 중앙과 끝쪽의 높이를 결정했는데 자판 길이에 따라 2점의 높이가 달라진다. 여기서부터는 솔직히 계산이 어려운데 일단 된다고 하자. 오프셋이 바뀌어도 비율이 유지된다면 기판 길이에 맞춰 계산하면 된다. 혹시 아니면 꼭지점의 맞는 자리에 갖다 놓는 수밖에 없다. 뒷판은 이미 만들어 두었으니 앞판의 높이를 줄여서 다시 만들기로 했다.

측면에서 안쪽을 들여다 보면 공간상의 여유는 있다. 위쪽을 들 것이므로 배선을 가급적 위로 몰아 놓으면 아래쪽은 거의 빈다. 기판 자체의 높이는 4미리이며 최하단 납땜의 높이까지 고려해도 7미리만 확보하면 된다. 3점이 7미리이면 4점은 35 - 7 = 28이다.

이 계산이 정확하게 맞는지 검증하는 것도 피곤하니 그냥 일단 잘라 보자. 2층에 올라가 전에 잘랐던 나무의 자른 면을 활용하여 나무 두 조각을 만들어 왔다. 나무를 아낄려고 그런건데 막상 잘라와 보니 좌우를 각각 조정할 수 있어서 이게 더 좋다. 밑에 피스만 하나 더 박으면 될 뿐 굳이 좌우 지지대가 한 덩어리일 필요가 없다.

대략 조금 더 낮아진 모습인데 많이는 아니고 7~8미리 정도다. 이 나무를 끼워 보니 철판이 같은 평면에 들어오지 않는다. 수학적 계산의 문제보다는 재단의 오차 문제가 더 크다. 톱질도 서툴고 나무가 톱 두께만큼 줄어들기도 해 정확하지 않다.

여기서부터는 측정이나 계산을 포기하고 그냥 눈대중으로 맞추었다. 하단 지지대가 높아 안쪽 일부를 잘라냈다. 그러고도 안쪽이 높아 칼로 대패질을 해서 대충 맞추었다. 역시 실제 잘라 보고 눈으로 확인해 가며 맞추는게 제일 확실하다. 수평을 얼추 맞춘 후에 와셔로 철판을 고정했다. 나사못으로 했더니 나사못 안쪽이 삼각형으로 기울어져 있어 철판을 밀어낸다. 철물점에 가서 평평한 나사를 좀 구해와야겠다.

1점 꼭지점이 42미리, 4점 꼭지점이 33미리이니 9미리 정도 차이난다. 9/130 0.069이므로 딱 4도 정도 된다. 2점이 22미리, 3점이 13미리이다. 하판 두께 6미리를 걷어내 버리고 싶지만 이거 없으면 지지가 안되니 어찌 방법이 없다. 앞쪽으로 약간 기울어져 팜레스트는 하나만 대면 그럭 저럭 칠만하다. 뒤쪽을 조금 더 들어도 쓸만한데 이게 건강에 안 좋다니 4도 각도만 주기로 한다.

좌우 거리는 어떻게 재야 할지 기준이 애매한데 철판끼리 29미리이고 자판끼리는 40미리 떨어졌다. 와셔를 너무 꽉 조여서 그런지 아니면 지지대 조립을 잘못한건지 하판이 높이가 평평하지 않아 끄덕거린다. 좌상단에 양면 테이프로 높이를 살짝 줘 평평하게 만들었다. 이상으로 소젯 3호 제작을 완료했다. 하드웨어는 웬만하면 더 손대지 않을 생각이다.

22 3 2- 소젯 4

새로운 키보드 재료가 도착했다. K640T Slim을 두 개 주문해 놨는데 어제 배송왔다. 둘 다 LP 스위치이고 청축 검정, 적축 흰색이다. 받자 마자 반가워서 바로 뜯어 봤다.

타이프쳐 보니 짤각거리는 청축이 더 감이 좋고 적축은 고급 멤브레인 느낌이되 암만 그래도 멤브레인보다는 감이 좋다. USB C로 연결하고 케이블이 분리형이라는 점도 마음에 든다. 적축을 연결해 봤다.

지금 이걸로 타이프치고 있는데 이 정도면 아주 고급 느낌은 아니라도 정갈한 편이다. 팜레스트가 없어도 된다는 점이 마음에 든다. 검정 청축은 스위치를 뽑아 봤다.

확실히 낮다. 높이는 물론이고 스트록도 짧으며 기판 아래쪽도 짧아 배선하는데 여유가 있다. 사실 이게 정상 높이이고 원래 스위치가 지나치게 큰거 아닌가 싶다.

 

면적이 살짝 작은거 같아 철판 구멍이 안 맞으면 어쩌나 했는데 끼워 보니 철판에 들어가는 면적은 같고 테두리가 얇다. 이게 안 맞으면 스텐판 설계를 다시 해야 하는데 똑같아서 다행이다.

뒷면을 보면 핀 구조가 다르다. 이 구조가 똑같다면 소젯3호에 바로 이 스위치를 쓸 수 있는데 그렇지 못해 시제품을 하나 더 만들어야 한다. 컨넥터를 이미 끼워 놔서 직결 납땜을 할 수도 없다. 소젯 3호는 어쩔 수 없이 기본 스위치로 만들 수밖에 없었다.

 

스텐판에 끼워 보면 확실히 낮고 키캡까지 끼워 보면 확 차이가 벌어진다. 처음부터 이렇게 낮게 만들었으면 좋을걸 체리는 왜 그렇게 높게 만든걸까? 십자 스템이 똑같아 키캡은 공유할 수 있다. 들어는 가는데 일반 키캡을 LP에 끼우면 옆면이 보강판 아래까지 걸쳐 스트록을 다 누를 수 없다.

반대의 경우는 윗부분만 살짝 얹혀 비키 스타일이 된다. 소젯3호의 키캡만 이걸로 바꿔도 되지만 지금까지 칼질한게 헛수고가 되어 버리는 셈이라 억울해서 그렇게 못하겠다. 어차피 이걸로 다음 키보드를 만들거라 바로 해체했다.

같은 회사 제품이라 해체 방법도 거의 비슷하다. 그러나 스위치 체결이 너무 강해 뒷면을 눌러서는 빠지지 않고 풀러로 빼야 한다. 이게 또 힘을 많이 요구하는지라 손가락이 무척 아팠다. 힘껏 잡아 빼다 부상병이 발생하기도 했다.

너무 힘이 들어서 이것도 쉬엄 쉬엄 해야 하나, 전용 풀러를 새로 장만해야 하나 싶었는데 자꾸 하다 보니 빼는 방법을 터득했다. 보강판과 스위치가 강력하게 체결되어 있는게 아니라 기판과 핀이 꼭 맞물려 있다. 그래서 풀러를 너무 꼭 쥘 필요 없이 좌우만 살짝 눌러주고 앞뒤로 비틀어 핀을 뽑아 주면 된다. 요령을 터득하니 금방 다 뽑았다.

이왕 다 뜯어 봤으니 부상당한 스위치도 한번 분해해 보자. 사실 이미 분해되어 있어 잔해만 수거하면 된다.

 

위에 있는 두 개가 접점이며 아래쪽으로 핀이 노출되어 있다. 파란 스템이 이 두 접점을 떨어지도록 살짝 밀고 있고 누르면 접점이 붙어 입력으로 인식한다. , 접점은 붙은 채로 제작되어 스템이 떨어뜨려 놨다가 누르면 탄력으로 붙는 방식이다. 떨어진 채로 만들어 놓고 스템이 밀어서 붙이는게 아니다. 아마 수명 때문에 이렇게 만든 거 같다.

접점 반대쪽에는 걸쇠가 있는데 스템의 반대쪽 돌기가 이 걸쇠의 중앙 부분을 통과하면서 딸깍하는 소리를 낸다. 이 걸쇠는 구분감을 주고 소리를 내는 역할을 한다. 스템 아래쪽에 용수철이 있는데 얘가 키압을 결정한다. 아랫판에 모든 부품이 들어가고 윗판으로 덮는 구조이다.

걸쇠 때문에 소리가 나는거라면 적축은 이 걸쇠가 없겠네? 그럴거 같아 적축 스위치도 하나 분해해 봤다. 이럴줄 알고 두 축 모두 한꺼번에 산거다. 뚜껑이 4군데나 고정되어 있어 해체하려면 이것도 쉽지 않다. 확인 결과 진짜 걸쇠가 없다. 아니, 이럴거 같으면 적축이 청축보다는 좀 싸야 되는거 아닌가? 소리를 내는건 필수 기능은 아니고 적축에는 어차피 없으니 이 부분은 제거해도 된다.

윗부분을 제거하고 높이를 재 보니 11미리가 약간 넘는다. 원래 14미리에서 이 정도까지는 잘라낼 수 있다는 얘기인데 그러면 수직 피치를 더 줄일 수 있다. 사실 LP 스위치를 살 때부터 이게 가능하지 않을까 기대했었다. 과연 가능한지 또 잘라 보기로 했다. 어제 키캡 작업으로 손가락 부상중이지만 궁금하니 어쩔 수 없다.

플라스틱이 두꺼워 이건 칼로는 어림도 없다. 바깥에서부터 한땀 한땀 잘라내지 않는한 중간을 뚝 자를 수는 없어 결국 톱으로 잘랐다. 톱의 정밀도가 떨어져 대충 자른 후 칼로 다시 다듬어 줘야 하니 이 작업도 꽤 시간이 오래 걸린다. 다 자른 후 원래 스위치와 높이를 비교해 보면 최대 3미리 정도 줄어들어 11미리가 된다. 대충 줄이면 12미리이되 뚜껑 고정 장치 한쪽을 반만 남기는 무리수를 동원해야 11미리이다.

 

이게 가능은 해도 실용성이 떨어진다. 11미리까지 줄인다고 해도 철판의 일부를 남겨야 하므로 키피치는 13미리까지 줄일 수 있고 그것도 솔직히 무리다. 스위치 12미리에 철판 2미리 남기면 14미리 피치가 된다. 이 고생해서 고작 3미리 줄일 수 있다는 얘긴데 어차피 원하는 최종값도 아니어서 굳이 이렇게까지 할 필요는 없다.

이런 목적이라면 차라리 게이트론 스위치가 더 낫다. 게이트론은 LED를 위해 위쪽에 공간을 남겨 두는데 이게 무려 4미리이다. 게다가 LED 영역은 노출되어 있어 잘라내기도 쉽다. 이 영역만 싹둑 잘라내면 키피치를 12미리로 줄일 수 있다. 이것도 물론 가공에 꽤 난관이 있을거 같다.

정말 딱 원하는 최종 피치는 가로 17 ~18, 세로는 2 12미리 1, 3 10미리이다. 이걸 구현하려면 스위치는 12 * 8 미리로 나와야 한다. 스위치 뜯어 보고 구조까지 파악했으니 차후 3D 프린터로 출력해서 제작하는 방법도 고려할 만하다. 어차피 키캡도 만들어야 한다. 기존 스위치를 잘라서 쓰는건 좀 아닌 거 같다. 손가락이 죽어난다. 로지텍 K470의 펑션열이 딱 10미리이다.

 

위 사진의 숫자행을 12미리로 하고 여백을 더 줄이면 이상적이다. 이 정도면 딱 좋은데 이건 펜터그래프라 부품을 빼 쓸 수가 없다. 뜯어 보면 그냥 러버돔에 X자로 걸쳐 놓았을 뿐이다. 대량 생산할 때는 이것도 좋겠지만 위치를 마음대로 바꿀 수 없으니 시제품 제작에는 부적합하다.

한잠 푹 자고 일어났다. 공돌이짓을 하다 보니 도저히 체력이 달려서 못해 먹겠는데 자고 일어나면 그나마 컨디션이 좀 좋다. 새벽에 3호를 테스트해 봤는데 또 여러 가지 개선 사항이 많다. 그 전에 소프트웨어 버그와 개선사항부터 좀 적용하자. 시제품까지 만들어 놓고 보니 여러 가지 수정할게 많이 보인다.

 

▶매크로행 맵핑이 1~6으로 잘못되어 있다. 조정하다가 누락한 거 같다. 특히 1 Num에 맵핑되어 있어 이중 맵핑인 셈이다. 3~8까지로 맵핑을 바꾼다. 2는 예비로 남겨둔건데 좌상단 ESC로 갈 수도 있을거 같다. 키맵만 수정하면 되는거라 바로 완료했다.

▶영문 자판을 쿼티로 선택해 놔도 단축키는 소젯 배열에서 읽는 문제가 발견되었다. 단축키가 불편해 쿼티로 바꾸었다면 이때는 쿼티 배열에서 키를 읽어야 한다. 특히 게임 모드에서는 쿼티로 바꿔쓸 수밖에 없어 단축키 지원이 정확해야 한다. 다음 코드가 문제다.

 

GetAlphabet(CM_ENG, kidx, chr)

 

무조건 CM_ENG라고 할 수 없으며 세팅에 설정된 영문 자판중에 하나를 골라야 한다. 이게 간단한거 같아도 차맷 순서까지 고려하면 소젯과 쿼티 차맷의 존재 여부에 따라 무려 다섯 가지 케이스로 나누어진다.

 

S, Q - S

Q, S - Q

Q - Q

S - S

없음 - S

 

영문 차맷을 찾아 보고 먼저 발견되는걸 적용하되 없으면 CM_ENG로 단축키를 읽으면 되겠다. 굳이 소젯에 우선권을 준다거나 하지는 않았다.

 

// 먼저 발견되는 영문 자판에서 단축키를 읽되 영문 자판이 없으면 소젯 차맷을 적용한다.

int engCmIdx = FindLangChaMat(N_EN);

int engCm;

if (engCmIdx == -1) {

     engCm = CM_ENG;

} else {

     engCm = Opt.useChaMat[engCmIdx];

}

if (GetAlphabet(engCm, kidx, chr)) {

 

FindLangChaMat이 차맷을 직접 찾아 주는게 아니라 Opt.useChaMat내의 번호를 찾아줌을 유의해야 한다. 이 구조를 한번 정비했는데도 헷갈린다. 쿼티로 바꾸면 쿼티 단축키로 잘 적용되며 실행중에도 자판을 바꾸면 바로 적용된다.

▶ 현재 워드, 웹브라우저, 비주얼스튜디오 등등 웬만한 프로그램은 후킹으로도 잘 동작하며 큰 문제가 없다. 그런데 유독 아래한글은 후킹이 전혀 먹혀들지 않는다. IME 모드도 동기화되지 않으며 Shift+Space로 한영 전환도 안된다. VK_HANGUL 가상키 입력을 무시하는 듯하다. 도구/글자판 메뉴를 선택하면 자판을 선택할 수 있다.

두벌식, 세벌식은 물론이고 북한 자판까지 지원한다. 이런식이다 보니 운영체제의 표준 입력 IME를 따르지 않고 고유의 키입력 처리 방식이 있는 모양이다. 자판 전환 단축키까지 원하는대로 바꿀 수 있되 실제로는 좌우 Shift, Ctrl 스페이스 정도만 되고 Ctrl+Space로 바꿔 놓으면 한자 변환과 충돌이 발생하기도 한다.

운영체제의 입력기를 쓰도록 설정할 수 있을거 같기도 한데 그런 옵션은 딱히 보이지 않는다. 한글로 치다 오타나면 지가 영문 모드로 강제로 바꾸기도 하고 제 3 자판까지 지원하다 보니 운영체제와는 다른 입력 체계를 적용하는 것 같다. 혹시나 해서 소젯의 한글 차맷을 2벌식으로 바꾸니 이건 된다. 그리고 소젯이더라도 영문은 또 잘된다.

그러나 소젯으로 바꾸면 이해할 수 없을 정도로 왕창 깨져 버린다. 다른 방법이 더 있는지 모르겠지만 이건 디바이스 드라이버를 만들어도 제대로 지원하기 어려울 거 같다. 안된다는 것만 알아 두고 잠정 포기한다.

▶ 매크로 키를 4개 더 늘리기로 했다. 그러면 73키에서 77키가 되는데 일단 숫자는 마음에 든다. 이건 창모형의 조언을 받아 들인건데 PrtSc Break 등이 따로 없으면 불편해서 대중화하기 어려운데다 키보드 면적이 중요하지 않다는 것이다. 있던게 없어지면 불편을 느낄 수 있고 까이는 껀수가 되니 굳이 뺄 필요 없다. 나중에 빼더라도 또는 최소 배열에는 포함하지 않더라도 시제품 상태에서는 일단 포함하는게 유리하다.

키를 더 늘리려고 하는 다른 이유는 일단 편집키 위쪽에 공간이 남아 있어 어차피 면적에는 영향을 미치지 않는다는 점이다. 텐키레스 키보드에 맵핑할 키도 아직 남아 있다. 또 매크로가 왼쪽에만 있는 것보다 오른쪽에도 3개 정도 있으면 활용도가 있다. 추가하는 키는 M7, M8, M9로 명명하되 디폴트로 PrtSc, ScrL, Break로 맵핑만 해 놓을 뿐 사용자 정의 가능하다. Menu, Ins, BS, NumLock 등을 더 맵핑해 쓸 수 있다.

좌상단에도 Esc를 따로 놓을건데 Esc도 자주 쓰는 키인데다 이 위치가 워낙 익숙해 없으면 아쉬워 하는 사람이 많다. 그런데 이건 좀 골치가 아픈게 최소 배열에도 Esc가 있어야 하는데 그러면 이중 배치라는 점이다. 풀배열에서 같은 키 2개를 둘 수 없으니 뭔가 활용 방안을 마련해야 한다.

풀배열일 때 안쪽 Esc의 기능을 정지시켜 버릴 수 있는데 굳이 그럴 필요는 없다. 그럼 기호를 하나 할당해서 입력 편의를 도모할 수 있는데 마땅한 기호도 없고 위치가 그리 썩 좋은 편도 아니고 일관성도 훼손된다. 여러 모로 생각해 본 결과 풀배열의 Esc를 매크로로 정의하고 초기값을 Esc로만 할당해 두기로 했다. , 지금은 중복이지만 원하면 다른 키로 바꿔 쓸 수도 있도록 함으로써 중복을 회피할 수단만 제공하는 것이다. -> 나중에 다시 생각해 봤는데 Esc의 기능을 바꿀 사람은 거의 없을 거 같다. Esc는 그냥 고정하자.

그렇다면 Esc 자리의 매크로 번호는 뭘로 줄까? 끝번호인 M10으로 주는건 너무 홀대하는 거 같고 M7로 주면 아래 위가 안 맞다. 결국 Esc 자리가 M1이 되고 이후의 매크로키는 번호가 하나씩 밀려나야 한다. 물리키 맵핑은 2로 할 것이며 이럴 때를 대비해서 하나 남겨 두었었다.

키맵에 4개 더 늘리고 좌표 조정한 후 Esc는 수평으로 키피치 절반반큼 이동시켜 중앙에 두었다. 매크로키 캡션은 전부 Mx로 변경하고 useEtc 옵션 선택시 Esc키는 항상 단독으로 존재하므로 매크로로 맵핑하지 않는다. 화면상의 키 배치를 대폭 수정했다. 이는 화면상의 배치일 뿐 시제품에서는 각도가 들어가 모양이 상당히 달라진다.

거의 텐키레스에 필적하는 면적이 되었으며 왼쪽에 없던 키까지 늘어났지만 그래도 숫자키가 없어서 좀 적은 편이긴 하다. 좌우 균형도 비교적 잘 맞다.

모든 매크로는 재정의 가능하며 ProcessMacro 함수에서 정의값을 읽어 실행한다. 그런데 이 함수가 아주 예전 버전으로 되어 있다. 매크로 키는 고유의 번호를 가지고 매크로 목록은 따로 유지하며 키를 할당해서 사용하는 형식이다. , 매크로는 100개든 1000개든 미리 등록해 놓고 키할당을 편집하여 바꿔 가며 쓰는 식이라 범용적이다.

단순한 키 대체 뿐만 아니라 당근의 매크로 기능을 활용하여 연속적인 동작도 가능하다. 그러나 너무 범용적이다 보니 복잡하고 사용하기도 번거롭다. 그냥 단순하게 10개의 매크로에 대해 대체할 키나 조합키 정도만 기억하는 형식으로 바꾸는게 좋겠다. Opt arMacro 배열을 정의하고 각 매크로키에 1:1로 대응한다. 여기에 대체할 키 이름을 적되 앞에 접두 기호 ^@#!를 붙여 조합키 정도만 지정하도록 했다.

초기 셋팅은 클립보드 동작, UnDo, 데스크탑 보기 정도로 잡아 놨으며 오른쪽은 원래 쿼티의 키를 대체하도록 해 놓았다. 물론 디폴트가 그럴 뿐 차후에 편집 가능하다. 매크로 편집 대화상자는 간단하게 수정했다. 단순히 10개의 문자열을 보여 주고 편집 후 저장하기만 하면 된다.

간단한 작업이지만 오랜만에 UI 작업할려니 무척 피곤해서 다음에 할까 하다가 웬지 찝찝해서 대충 만들어 뒀다. 가상키 테이블 arVk에도 불필요하게 매크로 이름 따위가 들어가 있어 모두 제거했는데 차후 가상키 이름은 좀 더 정성껏 붙여 줘야겠다.

넘패드에 있는 키나 멀티미디어 키, 브라우저 키 등을 등록해서 쓸 수 있다. 후킹중에 이 대화상자를 열면 소젯 방식으로 키 이름을 입력해야 한다. 메인 윈도우는 후킹을 받지 않지만 대화상자는 후킹 대상이다.

▶ 오른쪽의 편집키는 모두 미니배열의 Edit 모드에도 있고 상단의 펑션키도 마찬가지이다. 그러나 왼쪽의 매크로키는 미니배열에서는 아예 접근할 방법이 없다. 미니 배열로도 모든 것이 가능하려면 이들도 미니배열안의 어딘가에 들어와야 한다.

집안열에 멀티미디어키가 있는데 이 자리에 M2 ~ M7까지 맵핑해 놓자. 아쉽게도 양쪽으로 갈라져 EditLock 상태에서도 Copy, Paste를 교대로 누르기 어렵지만 매크로를 재정의하면 가능은 하다. 그래도 수평으로 나란히 있는 매크로 키가 없어 불편하기는 여전한데 미니 배열 구조상 어쩔 수 없는 부분이다.

BS만 단독으로 누를 방법이 없는데 Edit 모드의 Tab 자리에 BS도 넣어 두기로한다. 수정을 위해 굳이 이 키를 실사용할 일은 없겠지만 만약 Ctrl+BS를 굳이 입력해야 한다면 어떡하든 방법은 있어야 한다. 이게 안되면 이것도 까이는 요소가 될 수 있으니 방어 차원에서 BS 키도 두기로 한다.

구현은 다 했는데 문제는 이게 다 하드코딩이라는 점이다. OnPaint에서 TYGHBN 자리의 캡션을 M2~M7로 일일이 바꾸고 ProcessMacro에서 왼쪽 매크로 인덱스로 일일이 맵핑해 주었다. Tab은 더 골때려서 편집 레이어일 때 캡션도 바꾸고 ProcessKey에서 직접 BS 처리했다. ProcessEdit 호출 이전에 Tab을 처리하기 때문에 직접 처리하는 수밖에 없고 BS ProcessBs를 호출해야 하기 때문에 가상키만 맵핑해서는 안된다. 구현은 했지만 코드가 좀 지저분해졌다.

매크로 때문에 밀려난 멀티미디어키는 FN 키에 넣었다. 그런데 이렇게 되면 FN도 하나의 레이어 비스무리하게 되어 버리는 효과가 있는데 굳이 레이어로 정의하지는 않기로 한다. 어차피 단독키만 가능하고 다른키와 조합하지 않으니 레이어라고 하기는 애매하다. 오른쪽의 편집키 영역에 맵핑해 뒀는데 FN키가 오른쪽에 있다 보니 누르기 쉽지는 않다. FN키를 눌러도 화면에 키를 보여 주는 기능은 아직 작성하지 않았다. FN의 다른 키는 차후 키보드 옵션 조정용으로 쓸 예정이다.

 

여기까지 소프트웨어 수정도 당장 급한만큼은 했다. 이제 소젯 4호를 만들어 보자. 3호 만든지 얼마되지도 않았지만 테스트도 좀 진행했고 개선 사항도 있어 슬슬 설계에 들어가야할 때이다. 주말 사흘간 설계해서 철판 주문 넣고 하우징 미리 만들어 두고 다음주에 4호 만들어야 한다. 그 다음 주부터 출근할지 몰라 시간도 얼마 없다. 4호 기반으로 특허 내 놓고 회사 다니면서 오랫동안 실사용해 보자. 지금 이 정도만 해도 처음 예상했던 것보다 많이 진척되어 실사용 가능하다.

4호는 일단 LP 스위치로 만들거고 커넥터를 쓸 수 없으니 직결하거나 다른 소켓을 찾아 봐야 한다. 각도나 피치도 의도적으로 약간씩 변형해 보고 이번에는 새끼 손가락도 살짝 내려 볼려고 한다. 매번 다르게 이것 저것 만들어 보면 그 중에 제일 괜찮은걸 선택할 수 있을거다. 직결 케이블은 일단 요걸로 골라 놨다.

6핀이라 고작 키 3개만 연결할 수 있지만 그래도 분리형이라 납땜이나 조립은 편할거 같다. 20핀짜리도 있는데 암수를 다 팔지 않아 쓸 수가 없다. 딱 필요한건 이건데 비싸고 내가 거래하는 사이트에서는 취급하지 않는다. 옥션, 쿠팡도 팔긴 하는데 다 해외배송이고 가격은 비슷하다. 이거 두 개면 양쪽 20키를 한방에 연결할 수 있지만 3만원은 좀 쎄다.

 

FF는 불과 2000원 정도밖에 안하는데 FM은 무쟈게 비싸고 국내에는 파는 곳도 없다. 이걸 구하기는 어려운거 같으니 직결할 수 있는 2가닥 단선이라도 구해야겠는데 그것도 구할 수가 없다. 찾다 찾다 쿠팡에서 겨우 하나 찾았다. 이거 검색하느라 거의 밤을 샌거 같은데 진짜 입맛에 맞는거 찾기 어렵다.

3호는 철판을 너무 작게 만들어 하우징에 걸치지도 않고 기판보다 폭이 짧아 옆에 지지대를 세울 수가 없다. 이번에는 하판을 가득 채울만큼 여유있게 만들어 튼튼하게 고정할거다. 지금은 작은게 중요하지 않다. 편안한 자세와 실용성을 먼저 확보해야 한다.

▶갑자기 alt+f4가 안 먹히는 현상이 발생했다. alt만 누르고 있으면 공백만 잔뜩 입력된다. 이게 웬일인가 싶어 테스트 프로그램으로 점검해 보니 좌우 alt키의 입력이 다르게 나타난다. sys 입력이 아니고 down만 올 뿐 up이 오지 않는다.

이 정도면 하드웨어 이상이라고 봐야 할 상황이라 뜯어서 점검해 봤다. 납땜은 분명히 잘 되어 있고 스위치도 이상이 없는데 쇼트시키면 keydown만 온다. 어딘가 합선이 발생했거나 키보드 설정에 문제가 생긴거 같다. 왼쪽 alt는 이상없이 잘 동작하는데 이 녀석은 미사용으로 묶여 있다.

 

원래 왼쪽을 맵핑했다가 오른쪽이 남아 바꾼건데 오른쪽 alt가 한영키라 좀 다르게 동작하는 모양이다. 둘 다 커넥터는 연결되어 있으니 잘라서 붙여 맵핑을 바꾸면 된다. 왼쪽 alt로 바꿨더니 정상 동작한다. 문제는 해결했는데 정확한 원인은 알 수 없다. 아마 합선 때문이 아닌가 추측되는데 따로 빼 놓은 FN키가 말썽일 수도 있다.

이 키를 아무데나 던져 놨더니 기판 사이를 돌아 다니며 말썽을 일으킨 거 같다. 바닥에 굴러 다니지 않도록 벽면에 양면 테이프로 고정해 주고 키캡도 달아 줬다. 중앙 부분을 막아서 LED불빛을 차단해 버려야겠다.

LP 청축을 놀고 있는 2호 철판에도 붙여 봤다. 확실이 낮아서 이동거리가 짧고 키감도 나쁘지 않다. 소음이 심하지 않아 이걸로 시제품을 만들어 사무실에서 써도 될 거 같다. 키캡도 표준보다 약간 더 작아 18미리 정도면 많이 안 깍아도 된다.

엄지쪽 키는 긴걸로 썼는데 위쪽이 빈거 같지 않아 예쁘고 손가락이 닿는 면적이 넓어져 더 편리하다. 남는 키캡도 알뜰하게 활용할 수 있고 말이다. 어차피 깍아 써야 하니 이게 더 좋은데 왜 진작 이 생각을 못했는지 모르겠다. 이왕 일 벌린 김에 3호도 키캡을 바꿨다. 이 정도 칼질은 이제 껌이다.

그러나 이건 높이가 맞지 않아 별로다. 가운데를 역방향으로 끼우니 이 자리는 편한데 좌우가 높아 약간 걸리적거린다. 스텝스컬쳐 키보드의 특성상 어쩔 수 없는 부분이다.

▶ 오늘부터 소젯으로 타이핑 연습을 하고 성적을 기록하기로 했다. 2벌식으로는 대략 600타 정도 나오지만 소젯으로는 아직 어림도 없다. 연습할 때마다 조금씩 늘기는 하지만 매번 배열이 조금씩 바뀌는데다 쿼티랑 왔다 갔다 하다 보니 기록도 꾸준히 갱신되는 것은 아니다. 주기적으로 연습해 보고 계속 기록하기로 한다. 너무 열심히 하지 말고 하루에 한시간 정도만 연습해도 금방 늘거 같다. 연습 기록은 문서 상단으로 옮겼다.

 

다음은 시제품 4호를 위한 여러가지 조정 사항이다. 가급적 다른 형태로 만들어 다양한 테스트를 해 보려고 한다. 비슷비슷하면 굳이 만들 필요가 없다.

 

▶ 엄지행의 세 키가 약간 안쪽이라 이번에는 밖으로 좀 빼 본다. 손을 자연스럽게 얹었을 때 엄지가 벌어진 형태가 되며 현재 위치와는 맞지 않다.

miryoku, corne가 딱 현재의 소젯 위치인데 나는 반쯤 더 중앙쪽으로 이동하기로 한다. 이렇게 결정한 근거는 안쪽의 edit enter쪽으로 구부리는게 바깥쪽의 num, lang으로 뻗는 것보다 더 힘들기 때문이다. 엄지를 바깥으로는 뻗는 것에 비해 안으로 구부릴 때 자세가 더 틀어진다. 원래 enter JK의 가운데 있었는데 직교 배열에서는 M키와 17미리는 8.5미리, 19미리는 9.5미리 떨어져 있었다.

M에 일치시키는 건 너무 많이 가는 거 같으니 이번에는 4미리만 띄어 보자. 그리고 안쪽키의 각도는 각각 15, 30도였는데 이게 좀 작다. 이번에는 20, 40도로 약간 늘려 보기로 한다. 엄지행 키끼리는 2호와 같이 키홀과 키캡 모서리를 일치시킨다. 여기까지 그림으로 그려 보면 이렇게 된다.

중앙쪽으로 대략 5미리 이동했고 간격 줄이고 각도는 더 둥글게 만들었다. 여러모로 변화를 주고 손가락을 실테스트를 해 보기로 한다.

▶ 자판을 기울여 놔도 새끼 손가락은 짧아서 자세가 안 나온다. 인체공학 키보드는 손가락 길이에 따라 키의 높이를 다르게 하는데 중지까지는 일자로 두더라도 새끼는 아무래도 좀 내리는게 좋겠다. 내가 가진 것중에 xbow가 그런데 얼마나 내렸는지 측정해 봤다.

대략 8미리 정도 내린 거 같다. 새끼만 이렇고 나머지 손가락은 모두 일자이다. 내 손가락으로 실측해 보니 새끼가 다른 손가락보다 7미리 정도 짧다.

손 크기에 따라 차이가 있겠지만 대략 이 정도 차이가 난다. 그러나 오랫동안 일자에 익숙해 있는 사람에게는 갑자기 이만큼 차이를 두면 이것도 적응이 아려울 거 같아 딱 5미리만 내리기로 한다. 5, 6열을 살짝 내리면 4행의 조합키도 내려가고 엄지행이 전체적으로 둥그러진다.

▶ 방금 예전 영화를 좀 보다가 앞으로 빨리 이동하려니 Ctrl+오른쪽키를 눌러야 하는데 이걸 한손으로 누를 수 없다는 걸 발견했다. Shift도 물론 마찬가지다. 또 로그인할 때 ctrl+alt+del을 한손으로 누를 수 없고 심지어 두 손으로도 불편하다. 미니배열일 때는 난감하기까지 해 활용성에 심각한 문제가 있다.

엄지행에 Ctrl만큼은 양쪽에 배치해야 할지, 아니면 예전처럼 FN Caps랑 합치고 그 자리에 Ctrl을 놓아야 할지 고민중이다. 키를 중복 배치하는 것에는 부정적인 입장인데 Ctrl만큼은 예외를 둬야겠다. 동영상 빠른 이동의 경우 오른쪽 상단의 매크로를 #right, ^right로 등록해서 쓰는 방법도 있긴 하다. 이런걸 보면 재정의 가능한 키를 좌우에 모두 두는건 바람직한거 같다.

이 작전은 다음에 더 생각해 보고 결정하되 4호를 만들 때 양 끝에 구멍은 미리 뚫어 놓기로 한다. 필요 없으면 안 쓰면 그만이다. ctrl, alt를 양쪽에 각각 2개씩 두는 걸로 만들어 보자. 키맵핑 조정해 놔서 어차피 남는다.

 

기획한 사항을 모두 적용하여 설계안을 그렸다. 키 개수도 늘었고 구조도 복잡해져 점점 정신이 없어지고 있다. 이제 거의 텐키레스 수준으로 넓직해졌다.

여기까지 문서와 설계 등을 모두 소젯 3호로 편집했다. 워드나 파워포인트나 다 후킹이 잘 되어 큰 말썽은 없었다. 다만 자잘하게 버그가 있고 불편한 점도 있다. 우선 왼쪽 매크로의 copy, paste는 무척 편리하다. 원터치로 복사가 된다는 것은 엄청난 장점이며 매크로의 제대로된 활용예이다. 키조합만 정의해도 편의성이 월등하다.

수치를 많이 입력하다 보니 숫자키가 따로 없는 것은 좀 힘들다. num모드로 일일이 왔다 갔다 할려니 번잡스럽고 실수도 많아 엉뚱하게 입력하는 예가 많다. 레이어가 많으면 헷갈릴 수밖에 없다. 숫자행을 아예 추가해 버릴까 싶기도 한데 12개를 얹으면 num모드의 숫자, 괄호 등이 대부분 다 들어가고 키 2개만 부족하다. 쿼티의 기호키가 21개인데 소젯은 기호 전용 7개에 12개 추가해도 19개이다. \ `키 자리가 없어서 그런데 빈도가 떨어지는 4개를 골라 제외하는 수밖에 없다.

숫자행 12개를 더 넣으려면 91키로 대폭 늘어날 뿐만 아니라 텐키레스로는 안되고 풀배열 기판을 사용해야 하는데 폭이 너무 넓어져 부담이다. 이건 원하는 바가 아니고 바람직하지도 않다. 대신 펑션키를 숫자 입력용으로 잠시 용도를 변경하는 옵션을 제공하기로 했다. 어차피 게임을 위해 숫자를 바로 입력할 수 있어야 한다. 이 옵션은 대화상자가 아니라 FN조합키로 실시간 토글할 수 있도록 할 예정이다.

레이어를 자주 바꾸다 보니 edit num을 눌러 놓고 한참 있다가 문자를 입력하면 엉뚱한 동작을 하는 예가 있었다. 한번 입력 후 복귀하는 ctrl, shift도 마찬가지이다. 문자를 눌렀는데 갑자기 단축키가 실행된다거나 펑션키가 동작하면 당황스럽다. 그래서 이런 키는 타임아웃을 정해 두고 일정시간 후속 입력이 없으면 언어 레이어의 보통 모드로 돌아오는 기능이 필요하다. 짧게는 1초에서 길게는 10초 정도면 사고를 좀 방지할 수 있지 않을까 생각된다.

Shift 클릭, Ctrl 휠 등 마우스와 조합키를 같이 쓸 때는 조합키의 Once 상태가 리셋되지 않는 문제를 발견했다. 진짜 예상 외의 버그인데 이 문제를 어떻게 해결할지는 장시간 숙고해 봐야겠다. Once를 쓰지 말든가 마우스를 후킹하든가 뭔가 조치를 취해야 한다. 윈도우의 고정키가 어떻게 동작하는지 먼저 연구해 봐야겠다.

------------------------

3 6

4호는 하우징을 먼저 만들고 여기에 맞추어 철판을 자르기로 했다. 3호는 순서를 반대로 했더니 하우징 고정이 잘 맞지 않고 모양새도 영 좋지 못했다. 이번에는 밑판을 아크릴로 만든다. 사 놓은 나무도 다 썼고 높이를 낮춰 볼려고 3미리 아크릴로 선택했다. 기판과 15미리 나무 지지대 두께까지 378 * 148 크기로 잘랐다.

아크릴 칼을 사용하면 톱질을 안해도 쉽게 자를 수 있다. 공구상에서 이거 쓸일이 있을까 망설이다 그냥 사 두지 싶어 업어온건데 유용하게 잘 써 먹고 있다. 덕분에 아크릴은 원하는대로 자유롭게 가공할 수 있게 되었다. 공구를 많이 알아두는 것도 큰 힘이 된다. 기판 영역을 마킹해 놓고 위쪽에 양면 테이프로 푹신한 솜을 깔았다.

이건 USB포트를 보호하기 위해서이다. 너무 바닥에 닿으면 파손될 수도 있고 접촉도 안 좋아 위로 좀 띄워 두기 위함이다. 아래쪽의 구멍 두 개는 기판을 고정하기 위한 홀이다. 철사끈으로 대충이라도 묶어두려고 뚫었는데 나름 튼튼하다. 3호는 이런 고정도 안 했는데 그래도 잘 버티고 있다.

 

다음은 아크릴 위에 지지대를 박아야 한다. 과연 나무를 잘 잡고 있을지 구멍을 뚫고 나사를 박아 봤다. 드릴로 구멍이 깔끔하게 잘 뚫리며 피스도 튼튼하게 잘 박힌다. 다만 목재와는 달리 나사 머리 부분이 툭 튀어나와 평평하지 않다는 점이 아쉽다.

나사머리 부분을 위해 5미리짜리 기리로 입구를 팠더니 조금 더 깊게 들어가지만 그래도 어느 정도 돌출된다. 더 깊이 파다가는 아크릴에 구멍이 뚫릴거 같아 안되겠다. 머리가 작은 나사를 구해야겠다.

 

다음은 자판을 만들어 얹는다. 철판을 대신할 도면을 인쇄하고 1.5미리 아크릴에 붙였다. 이런 모양인데 3호랑 거의 비슷하다. 이번에는 목표 기울기에 맞게 지지대를 정확하게 계산해서 붙일 예정이다.

이게 간단해 보이지만 처음 해 보는 입장에서는 엄청 복잡한 수학 계산이다. 수평, 수직 기울기를 다 고려해야 하고 배선 공간도 확보해야 한다. 게다가 좌우 자판의 길이가 달라 중앙이 왼쪽으로 치우치고 좌우 기울기 계산 방식이 약간 다르다. 절단면의 기울기까지 고려해야 하는데 이건 그냥 대패질로 대신하자.

수식을 만들기 전에 현재의 소젯 3호로부터 각 꼭지점의 높이와 길이, 각도가 맞는지 점검해 보고 이를 구하는 수식도 산출해 봤다. 오른쪽 자판만 보자. 높이는 버니어 캘리퍼스로 실측한 것이고 각도는 계산으로 구했다.

asin sin의 역함수인데 머리털 나고 처음 사용해 봤다. sin은 각도로부터 빗변과 높이의 비를 구하는데 비해 asin은 반대로 비율로부터 각도를 구한다. 두 지점의 높이차와 빗변 길이를 알고 있으니 이들로부터 각도를 구해내는 것이다. 엑셀식으로 =DEGREES(ASIN(19/180)), =DEGREES(ASIN(8/130)) 이다. 엑셀은 기본적으로 라디안을 사용해서 각도로 바꿔야 한다.

실제 이 각도가 맞는지 각도기 들고 재 봤는데 정확하다. 오히려 침침한 눈으로 재는 것보다 수학식으로 계산하는게 더 빠른거 같다. 이 수식을 활용하여 원하는 각도를 만들기 위한 지지대 높이를 계산하면 된다. 우하단은 5미리로 충분히 낮게 잡았고 수평, 수직 각도는 모두 4도로 정했다.

오른쪽 위 꼭지점을 구하는 엑셀식은 =140*SIN(RADIANS(4))+5이고, 왼쪽 위는 =190*SIN(RADIANS(4))+14.76로 구한다. 여기서 5, 14.76 3, 2점의 높이이다. 좌하단점은 세 점이 결정되면 자동으로 결정된다. 이렇게 계산해서 각 꼭지점의 지지대를 만들면 된다.

그런데 왼쪽 자판은 조금 다르다. 중앙의 높이는 같아야 하니 여기는 결정된거고 빗변의 길이가 다르니 왼쪽변의 높이가 다르다. 가운데 높이에서 4도 기울기로 170만큼 이동했을 때의 높이를 빼면 된다.

 

=28-170*SIN(RADIANS(4)) = 16.14

 

왼쪽변의 지지대가 오른쪽보다 1.38미리 더 높아야 똑같은 4도가 된다는 얘기다. 그럼 이제 높이가 다 나왔으니 지지대를 설계할 수 있다. 아래 위 지지대는 모양은 같고 높이만 다르다. 좌우 지지대도 마찬가지이다.

양 철판과 밑판 길이에 18미리의 간격이 있다. 그러나 자판을 4도 들었을 때 위쪽이 약간 벌어지는데 대략 19~20정도 될 것이다. 이 바깥쪽은 기울어지기 시작하므로 4도의 경사를 줘야 한다. 수평 뿐만 아니라 수직쪽도 마찬가지인데 이걸 미리 고려해 톱질하기는 불가능하다. 결국 78*28 크기의 사각형을 자른 후 나머지는 칼로 다듬어야 한다.

옆 지지대는 높이만 1.38만큼 차이나고 모양은 같다. 아래쪽 30미리는 나사도 안 박힐 높이라 버린다. 계산한 높이는 제일 바깥쪽이며 안으로 들어오면 4도 기울기로 인해 미세하게 높아져야 한다. 굳이 계산해 보자면 tan(4)*15=1.04이다. 15미리 나무를 지나는 동안에도 1미리 더 높아진다. 이를 고려하여 1미리 더 높게 자른 후 바깥쪽을 1미리 칼로 비스듬히 깍아야 계산이 맞다.

치수 다 뽑았으니 만들어 보자. 사용하던 나무의 바깥쪽 면이 남은 쪽으로 연필로 치수를 그리고 톱질했다. 양도 얼마 안되고 크기도 작아 전기톱 쓰지 않고 그냥 손으로 직접 잘랐다. 이 정도는 뭐 껌이다.

그런데 다 잘라서 하판에 얹어 보니 공간이 남는다. 왜 그런가 봤더니 설계는 15T로 해 놓고 나무는 12T를 잘랐다. 반대의 경우보다는 낫지만 나사박을 공간이 부족하게 됐다. 다시 자르자니 귀찮고 그냥 쓰기로 한다.

기울기 맞추느라 칼로 대패질을 열심히 했는데 이거 솔직히 이럴 필요까지나 있나 싶기도 하다. 대충 철판만 얹히고 고정만 하면 되는데 말이다. 아크릴판에 나무 고정하는 과정에서 미끌거려 고생 좀 했는데 이런 점은 나무보다 못한 거 같다. 다 완성한 후 자판을 올려 봤다.

원하던 모양이긴 한데 마음에 걸리는 부분이 좀 있다. 각도가 너무 없는 거 같고 그러다 보니 배선 공간도 충분치 않다. 철판을 조금 짧게 만들었는데 꽉 채우고 나사 구멍도 정확히 맞춰야겠다. 하우징은 다음에라도 조정 가능하지만 이거 만드느라 밤을 꼴딱 새고 몸도 피곤하다. 하우징에 자판까지 얹어 보고 애초의 설계를 보완했다.

 

- 철판 높이는 148까지 가득 채운다. 하판 크기 때문에 키보드가 작아지지도 않는다. 늘어난 여백은 아래쪽에 둔다.

- 편집, 매크로와 문자 카테고리군 3미리에서 2미리만 띄움

- 왼쪽 172 2미리 늘림. 피치 18키 하나가 없으므로 190보다 18만큼 작아야 딱 맞음,

- 나사 구멍 가장자리에서 5미리 띄우고 지름은 3미리. 단 측면은 키캡과 겹쳐 3미리만 띄움.

 

소젯 키보드로 4호 설계 작업을 하면서 일종의 좌절을 느꼈다. 안되는 거 없이 다 되긴 하는 것만 해도 참 다행스럽기는한데 불편한게 너무 많다. 수치 계산을 위해 엑셀을 사용했는데 영문, 숫자, 기호가 한꺼번에 나오니 레이어 바꿔가며 입력하기가 너무 어렵고 비효율적이다. 이건 펑션과 숫자를 토글하는 기능으로 해결을 시도해 볼 예정이다. 또 이건 언젠가는 해결될 거지만 키캡에 문자 인쇄가 되어 있지 않아 떠듬거린다는 것도 예상외로 불편하다. 연재는 외워야 하되 그나마 후킹 화면의 캡션 표시가 좀 도움이 된다.

또한 BS가 따로 없어 수식을 편집하기 곤란하다. 숫자 모드에는 직접 BS를 입력할 방법이 없어 언어로 바꾼 후 지우고 다시 숫자 모드로 가야 한다. 새로 추가한 우측 매크로의 prtsc 자리에 BS를 넣거나 아니면 아예 BS를 배치해야겠다. 편집의 tab 자리에 BS를 두는 어줍짢은 방법으로는 근본적인 해결이 어렵다. 조합키 2개 늘어난 걸 다음 방식으로 배치하기로 한다.

 

ctrl win alt   bs fn ctrl

 

ctrl도 양쪽에 있고 bs도 따로 있어서 일단은 좋다. bs는 문장 입력중에는 Shift+Space보다 불편해 잘 안 쓸거 같지만 엑셀 작업 등 수치를 입력할 때는 유용할 거 같다. 근데 이렇게 되면 미니 배열도 46키가 아니라 48키가 된다. 이건 좀 큰 변화이며 되돌리기도 어렵지만 받아들여야 할 거 같다.

소젯은 제자리에서 문장을 대량으로 입력할 때는 쓸만한데 아직 범용적으로 모든 용도로 쓰기에는 한계가 많다. 하드웨어 키는 더 늘리기 어렵고 4호의 79키 정도면 충분하다. 아니, 이 이상 더 키의 개수를 늘리는 경우는 가급적 자재해야 한다. 고로, 하드웨어는 더 변화를 줄 부분이 많지 않다. 이제부터는 소프트웨어를 얼마나 정교하게 만드는가의 문제이다.

샘플을 만들어 놓고 보니 수직 기울기가 너무 작아 배선 공간이 협소하고 타이핑 자세도 나오지 않는다. 어차피 뒤에 다리를 또 세울거라면 아예 뒤를 높여 공간을 미리 확보하는게 더 쉽다. 또 철판 크기를 바꿔서 이전 계산이 맞지도 않다. 수직 각도를 8도로 올려 다시 계산했다. 엑셀식을 잘 만들어 놨더니 대입만 하면 된다.

3점을 5로 미리 정해 놓고 나머지는 계산으로 구한다. 아랫변의 높이는 같고 윗변이 10.8미리 높아진다. 오른쪽 변의 좌상단 높이는 다음 공식으로 계산한다. 철판이 짧으니 오른쪽보다 1.1미리 더 높다.

 

=38.84-173*SIN(RADIANS(4)) = 26.77

 

이 높이대로 오른쪽 자판만 얹어 보면 배선공간은 충분하고 타이핑 각도도 적당하다. 사실 이것도 살짝 낮아 뒤를 조금은 더 들어야 할 거 같다. 조금만 더 높이고 싶다면 윗면에 볼트를 하나 끼우는 방법도 있는데 대략 3미리 더 높아진다.

-------------------

3 7

어제 백암장에 잠시 나간 김에 공구를 좀 사 왔다. 이것 저것 만들다 보니 공구나 소모품이 많이 필요하다. 나사못 120개에 3000, 길이 2, 2.5, 3미리 각각 1000원씩, 2000원이다.

 

다시 계산한 높이대로 나무를 다시 재단하기로 했다. 이왕 새로 만드는김에 이번에는 15T로 두께 맞췄다. 아래쪽은 그대로 쓰고 윗변만 10미리 정도 높이면 되는데 그 정도 높이의 고무판을 대 보니 딱 적당한 거 같다. 수직 각도 적당하고 배선 공간도 충분하다.

위쪽 지지대는 새로 잘라야 하되 옆면은 3호 밑면으로 만들었다 교체당한 녀석을 재활용했다. 종이에 원하는 기울기로 그려 놓고 대충 맞는 부분을 잘라서 쓰면 된다. 이런거 보면 머리가 나쁜건 아닌 거 같은데.... 기울기가 살짝 안 맞지만 칼로 대패질을 할거라 문제되지 않는다. 이거 재단하는데 샤프를 오랜만에 꺼내 써 봤다. 언제부터 있던 녀석인지 모르겠는데 연필보다 정밀하고 지우기도 쉽다.

나무 자르고 칼로 경사면을 다듬고 구멍 다시 뚫어 아크릴판에 고정시켰다. 한번 해 본 작업이라 능숙하게 처리했고 시간도 얼마 걸리지 않는다. 이제 철판만 만들어 올리고 납땜만 하면 된다. 갈수록 제작 속도가 빨라지고 있다.

내일 아침 철판을 주문하기 위해 작업 요청서를 작성한다. 오토캐드를 직접 배워 해 볼려고 했는데 설치도 잘 안될 뿐더러 최소한 한달은 배워야 뭐라도 그릴 수 있을 정도로 복잡하다고 한다. 어쩔 수 없이 이번에도 원식이한테 부탁해야 하며 그러기 위해 요청서를 아주 상세하게 잘 적어야 한다.

새벽에 작업 요청서를 작성해서 메일로 보냈다. 꼼꼼하게 적다 보니 2~3시간 정도 걸린 거 같은데 점심 전에 오면 내일쯤 철판을 찾을 수 있지 않을까 기대된다. 택배로 점프선까지 오면 바로 작업해서 목요일쯤에는 4호를 완성할 수 있다. 작업 요청서에 수치가 많이 들어가 이번에는 쿼티로 작업했는데 확실히 소젯보다는 편하고 속도가 빠르다. 그러고 보면 쿼티도 일반적인 용도로 쓰기에 큰 부족함은 없다.

또 놀라운게 지금 쿼티로 치고 있는데 소젯을 쓰다가 처음 바꿀 때만 약간 헷갈릴 뿐 치다 보면 금방 또 원래 습관으로 돌아온다. 몸에 베인 습관이 금방 없어지지는 않는 모양이다. 손가락 이동이 좀 있는게 오히려 고정된 것보다 리듬감이 있어 보이기도 한다. 어떻게 만들어도 이것보다는 더 좋을 거 같은데 소젯은 키를 79개나 달고도 아직 왜 저 모양인지 모르겠네. 모든 면에서 쿼티를 압도하는건 요원한 일이다.

4호를 제작하기 전에 sojett부터 1.0을 릴리즈한다. 3호에 비해 조합키 개수가 늘어나고 맵핑이 바뀔 수도 있어 3호 이전의 시제품과 짝을 이루는 버전을 기록으로 남길 필요가 있다. 또 첫 버전인만큼 기술 공유 차원에서 소스도 한번은 공개해야 한다. 특허 때문에 이후는 당분간 소스 공개가 어렵지만 나같이 키보드 연구하는 사람이 참조할만한 소스를 공개하는 것도 의미 있는 일이다.

다만 소스를 너무 보기 좋게 정리하지는 않으려고 한다. 시간이 없기도 하지만 과거의 시행착오도 기록으로 남길 필요가 있고 되는 것 뿐만 아니라 문제점도 적시해 놓아야 다음 버전의 개선 사항을 더 잘 이해할 수 있기 때문이다. 일반적으로 1.0은 완성의 의미지만 이번 버전은 그 정도까지는 아니고 단순히 일단락의 의미이다. 개발하던 소스에서 다음 사항 정도만 정리했다.

 

- 타이틀 바의 날짜를 숫자로 표기했다. 전처리기로 자동화했더니 영문으로 나와 보기 좋지 않고 굳이 자동일 필요까지는 없다.

- 최초 실행시 모든 카테고리를 다 보이도록 했다. 미니 배열이 기본이 아니라 당분간은 풀배열이 기본이다.

- 초기 윈도우 크기가 FHD로 되어 있는데 너무 커 1400*800으로 적당한 크기로 줄였다.

 

이 정도까지만 해서 홈페이지에 공개하되 실행 파일명은 Sojett100으로 버전을 명시한다. 같은 디렉토리에 있을 때 버전별로 ini 파일을 각각 사용하기 위함이다. 실행 파일과 소스만 일단 공개했는데 실사용 가능한 수준까지 만든 후 사용법, 연혁, 일지 등도 업데이트해야겠다.

새벽에 작업해서 아침 일찍 도면 요청서 보냈는데 아우가 바쁜 일이 있는지 낮에는 작업하지 못하고 저녁에 작업을 한 모양이다. 2시까지 기다리다 잠이 들었는데 8시에 완료했다고 전화가 왔다. 복잡한 도면임에도 정확하게 잘 그렸다. 이걸로 완성이면 좋겠지만 한두번은 더 부탁해야 할 거 같으니 다음에 원식이한테 맛있는거라도 좀 사 줘야겠다. 

이거 사실 외부에 의뢰하려면 비용이 꽤 많이 드는 작업인데 공짜로 서비스 받고 있는 셈이다. 도면 받자 마자 현대스틸에 제작 의뢰 메일과 문자를 보냈는데 아직 답은 없다. 빠르면 내일, 늦으면 대선 건너 뛰고 목요일쯤에 완료될 거 같다. 이번주내로 4호 완성해야 할텐데 일정이 될래나 모르겠다.

보강판 나오기 전에 소프트웨어부터 대판 업데이트를 해야 한다. 1.0은 릴리즈했으니 이제 다음 버전 부지런히 만들자. 기능을 늘리기 전에 앞으로의 효율적인 작업과 소스 관리를 위해 리팩토링부터 좀 단행한다.

 

▶ 가상키 테이블부터 정리했다. 순서없이 막 정리했더니 속도도 느리고 관리도 잘 안된다. arHookRecord, arHookRecordHan 등 문자로부터 가상키와 Shift 여부를 조사하는 테이블도 중복이다. 이들을 모두 합쳐 tblVk 하나로 통합하고 가상키 순서대로 256개의 가상키 테이블을 정리했다.

 

struct sVirtualKey

{

     UINT vk;           // 가상키 코드. 이 값으로 정렬하므로 첨자와 일치한다.

     char Name[32];        // 가상키 이름. 캡션 표시 및 매크로 작성용. 대소문자는 구분하지 않음

     int scan;          // 스캔 코드

     char han[8];        // 한글 음소. 가상키 R에 대해 ㄱ

     char hanShift[8];  // Shift 입력시 한글 음소. 가상키 R에 대해 ㄲ

     char eng[8];        // 영문, 기호. 가상키 R에 대해 r

     char engShift[8];  // Shift 입력시 영문, 기호. 가상키 R에 대해 R

};

 

이 구조체 하나면 가상키, 매크로에서 쓸 일음, 스캔코드, 한영 문자와 대응되는 가상키 등을 모두 표현할 수 있다. , 스캔코드는 아직 덜 조사된 것이 있는데 다음에 조사해서 채울 것이다. 이 테이블 정리하는데 생각보다 할게 많아 3~4시간 정도 걸렸다.

이 테이블에서 정보를 구하는 함수도 일체 정비했다. 어떤건 Find, 어떤것 Get이라 일관성이 없는데 모두 Get으로 통일했다. 문자로부터 가상키를 찾는 함수도 영문, 한글에 대해 각각 작성해 중복을 방지했다.

Option 모듈을 Sojett에 통합했다. 괜히 둘로 나눠 놨더니 작업만 번거롭다. 외부 변수를 일일이 등록해야 하고 배열의 크기를 sizeof로 조사할 수 없는 불편함이 있었다. 대신 키맵 관련 정보는 KeyMap.h 파일로 분리해서 두 파일을 동시에 편집할 수 있도록 했다.

공통 함수만 Util 모듈로 분리했을 뿐 실질적으로 단일 소스 프로젝트이다. 다만, ApiEdit 때문에 진짜 단일 소스로 만들기는 어렵다. 한 소스의 아래 위로 오르락 내리락 거리며 편집하는게 제일 편하다.

▶ 매크로 4개 추가한 것은 코드에 이미 반영해 두었는데 조합키 2개가 늘어난 것은 아직 반영하지 않았다. Ctrl키가 2개가 된 것은 별 문제는 아니지만 BS가 단독키로도 분리되었으므로 이 부분을 미리 처리해 놓아야 한다. 키맵의 엄지행에 두 개의 키를 추가했다.

 

     {C_BASIC,  4,-1, VK_CONTROL, 0x0303, {-6,0},     0,         0,              "Ctrl", },

     ....

     {C_BASIC,  4,10, VK_BACK, 0x0103, {3,0},   0,         0,   "BS", },

 

키맵이 늘어났으면 K_BS, K_RCTRL도 같이 정의해 줘야 갯수가 맞다. 왼쪽은 K_LCTRL로 명명하고 Ctrl 입력을 점검하는 코드는 두 키를 OR로 검사하도록 했다. K_BS 다운에 대해 ProcessBs 함수를 호출하면 바로 동작한다. 새로 추가한 키는 좌표만 잘 조정해 주면 된다. 그런데 캡션이 좀 이상하게 나온다.

arVk 테이블이 좀 잘못된게 있는데 VK_HANGUL VK_KANJI 등 같은 값을 가지는 동의어를 잘못 처리하여 한칸씩 밀린 경우가 있고 예약된 가상키가 과다 삽입되기도 했다. vk와 배열 첨자가 일치하지 않아서 엉뚱한 캡션을 찾은 경우이다.

또 캡션은 대문자로 쓰고 Alt, Caps 등으로 표기하는게 좋은데 name만으로는 캡션을 정확히 정의하기 어렵다. sVirtualKey 구조체에 cap 멤버를 하나 더 추가하고 캡션으로 딱 보기 좋은 값을 대입했다. name과 달리 cap은 출력용이라 중복되어도 상관 없다. 캡션을 구하는 GetNameFromVk은 이름을 GetCapFromVk으로 바꾸고 cap을 읽도록 했다.

▶ 엑셀에 숫자를 많이 입력해 보니 Num 레이어로 일일이 이동해서 입력하는게 쉽지 않았다. 또 게임에서 Ctrl+1, Ctrl+2 등으로 그룹 지정을 많이 하는데 이를 위해 숫자키를 쿼티와 같이 가로로 나열할 필요가 있다. 방금 tblVk를 편집할 때도 숫자키가 따로 나와 있어야 빠르게 작업할 수 있다.

옵션에 row0Num 멤버를 추가하고 이 값이 true일 때 0행을 펑션키 대신 숫자키로 쓰도록 한다. 디폴트는 물론 false이며 필요할 때만 숫자로 잠시 바꿔서 쓰도록 한다. 펑션키 12개에 어떤 문자를 할당할지를 결정해야 하는데 이것도 생각할게 좀 많다.

 

F1

F2

F3

F4

F5

F6

F7

F8

F9

F10

F11

F12

1

2

3

4

5

6

7

8

9

0

+

-

|

\

^

(

)

< 

#

%

&

~

*

/

 

- 먼저 F1부터 1을 대응할지, F2부터 대응할지가 애매하다. 쿼티는 제일 오른쪽에 `가 있어 새끼 손가락부터 1인데 소젯의 F1은 새끼바깥열이라 위치가 맞지 않다. 그렇다고 F2 1에 맵핑하면 캡션이랑 맞지 않아 헷갈릴 거 같아 F1 1을 맵핑한다.

- 아라비아 숫자를 다 맵핑하고 남는 두 키는 숫자와 함께 가장 많이 사용하는 +, -가 가장 합리적이다. 이건 의심의 여지가 없는데 - *의 빈도가 좀 애매하다.

- Shift 자리도 정의할 필요가 있는가? 숫자 외에는 다 Num 모드와 문자 영역에 있으며 Shift를 누르나 Num을 누르나 투터치이기는 마찬가지이다. 애초의 의도와는 부합하지 않지만 숫자와 함께 많이 쓰는 기호를 일단 배치해 놓기로 하되 사실 조금 지저분해 보이는 감이 있다.

- 문자 영역에 있는 .,= 등은 굳이 Shift 영역에 둘 필요 없다. 쿼티랑 일치시킬 필요도 없고 많이 쓸거 같은 순서대로 치기 쉬운 자리에 맵핑했다. 괄호까지는 필요하다 쳐도 < 하나만 있는게 좀 어색한데 for (int i=0;i<10; 식으로 많이 쓰기 때문에 <로 했다.

 

Shift 사용 여부와 맵핑은 차후에라도 조정할 수 있으니 일단 옵션부터 구현해 보자. 펑션의 숫자맵은 키맵에 이미 자리가 마련되어 있어 K_F1 ~ K_F12 Number 배열에 값을 써 넣기만 하면 된다. 숫자를 어디서 읽을 것인지는 옵션과 차맷 구성에 따라 달라지며 ProcessNumber 함수에 row0Num 인수를 추가하고 다음 코드로 숫자를 읽는다.

 

     if (row0Num) {

          Num = kbd.Map[kidx].Number;

     } else {

          if (pCm->diffNum) {

              Num = pCm->Map[kidx].Number;

          } else {

              Num = kbd.Map[kidx].Number;

          }

     }

 

row0Num 옵션이 켜져 있더라도 FN키와 함께 누르면 이때는 펑션키로 입력받는다. 대충 되는 거 같은데 ProcessKey의 조건판단이 좀 복잡해졌다. 이 옵션이 과연 엑셀 작업에 효율적인지는 실사용을 해 봐야 알 거 같다.

2벌식 옵션중에 여분과 쎈소리 옵션을 통합한다. 여분은 많이 쓰는 ㅆ과 ㅕ를 집안열에 배치하고 쎈소리는 ㅋ, ㅌ을 배치하는데 G 자리에 ㅆ과 ㅋ이 같아 같이 적용할 수 없었다. 여분은 키를 최대한 활용하는 옵션이므로 중복되지 않도록 모든 여분 키를 다 사용하는게 합리적이다.

여분을 배치하더라도 Shift 조합으로 ㅋ, ㅌ을 입력하는 것과 ㅓㅓ로 ㅕ를 입력하는 기능은 그대로 유지한다. 여분은 어디까지나 남는 키를 활용한다는 것이지 기존 오토마타에 영향을 끼치는 것은 아니다.

이렇게 남는키를 다 배치하면 2벌식에 비해 ㅠ가 빠지고 ㅆ이 대신 들어간 형태이다. ㅆ 빈도가 ㅠ보다 8배 더 높아 무리가 아니다. 이럴바에야 모음을 2벌식과 같이 배치하는게 어떨까 싶기도 하지만 그럴려면 그냥 2벌식 자판을 쓰면 된다. 빈도상으로 봐도 2벌식보다는 소젯의 배치가 더 좋다. 여분키를 쓰는 취지는 어디까지나 테스트용일 뿐이며 최종 채택 여부는 아직 결정하지 않았다.

이 옵션을 적용해 놓고 소젯 3호로 "쳐들면서", "양념", "숱한" 등의 단어를 쳐봤는데 복모음은 두번 누르는게 더 편하고 쎈소리나 ㅆ은 여분도 괜찮은 거 같다. 키를 최대한 활용한다는 면에서 나쁘지는 않은 거 같지만 디폴트로 선택해 놓고 싶지는 않다. 더 장기간에 걸친 테스트가 필요하다.

▶ 상당한 기간동안 키보드의 설정을 바꿔 가며 사용할 필요가 있고 사용자도 옵션을 골고루 써 볼 수 있어야 한다. 툴바로도 가능하고 대화상자도 있지만 신속하게 옵션을 바꿀 수 있는 단축키가 필요하다. 키보드 자체의 하드웨어 키로 바로 바꿀 수 있도록 FN 조합키를 사용한다. 오른쪽은 멀티미디어용으로 사용하고 있어 주로 왼쪽에 기능을 할당했다.

 

조합키

설명

QW

영문 쿼티, 소젯 선택. 영문 차맷이 없으면 아무 것도 하지 않는다.

AS

한글 2벌식, 소젯 선택

E

윈도우키 잠금 토글

R

전체키 잠금 토글

DF

0행 숫자, 펑션키 선택

V

사운드 옵션 토글

C

후킹토글 -> 안됨. 포기

X

Once 기능 사용 여부 토글

 

윈도우 키 잠금, 전체 키 잠금을 위해 다음 두 변수를 선언한다. 이 옵션은 동작중에 잠시 쓰는 것이므로 Option에 포함될 필요 없고 저장하지도 않으며 시작할 때 항상 리셋 상태이다.

 

bool winLock = false;                                 // 윈도우 키 잠금

bool keyLock = false;                                 // 전체 키 잠금

 

둘 다 후킹중에만 동작하며 소젯이 포커스를 가지고 있을 때는 굳이 막을 필요 없다. 전체키를 잠그면 FN+R 외에는 락을 풀 방법이 없어 조심해야 한다.

후킹을 단축키로 토글하도록 시도해 봤는데 여러 가지 문제가 있다. 토글 자체는 가장하지만 누른 후 놓을 때의 키입력이 타겟으로 전달되어 부작용이 많다. 풀 때도 타겟에 팝업 메뉴가 열리는 문제가 있다. 일회용 타이머를 쓸 수 있을 거 같은데 그러면 타이머 동작 전에 키를 반드시 놓아야 하는 어려움이 있다. 이 기능은 포기하고 툴바로만 토글하도록 한다.

FN키에 어떤 기능이 들어가 있는지 캡션이 없으니 외워서 쓰기 어렵다. 개발자인 나도 헷갈리는데 사용자가 이걸 어떻게 찾아서 쓰겠는가? 그래서 캡션을 표시했다. 키맵에 펑션 모드일 때의 캡션 멤버를 정의하고 작은 폰트로 출력했다.

소젯으로 입력하다가 갑자기 게임 한판 하고 싶으면 FN+Q로 쿼티로 바꾸고 FN+D 0행을 숫자로 바꾸면 되는 식이다.

그런데, 이 특수키의 이름을 FN으로 붙이는게 맞는지 헷갈린다. 기존 키보드의 FN은 하드웨어 동작을 하는 키인데 이건 멀티미디어와 키보드 옵션을 조정하니 뭔가 다른 이름을 붙여야 하지 않을까 싶기도 하다. 사용자도 기존 키보드의 FN과 좀 헷갈려 하지 않을까 예상된다. 더 생각해 보자.

-----------------------

3 10 - 4호 조립

그제 오후 늦게 석팀장한테 작업 언제 완료되냐고 문자를 보냈더니 오후 5시까지는 해 주겠다고 답이 왔다. 일단 철판 좀 보고 자자 싶어 낮에 자지도 않고 기다렸다고 5시에 갔더니 완성해 놓았다. 현금가로 25000원이다.

스위치 몇 개 들고가 잘 들어가는지 끼워 보니 어떤 건 헐렁하고 어떤 건 빡빡하지만 어쨌든 다 들어는 간다. 집에 와서 만들어 놓은 하우징에다 대 보니 아뿔사 미처 고려하지 못한 문제점이 발견되었다.

측면 지지대의 나사 구멍까지 밖으로 빼 놨는데 스위치가 내려올 부분까지는 고려하지 못했다. 중앙의 간격을 더 밀착했으면 딱 맞을 뻔 했는데 좌우를 너무 벌리다 보니 가장자리 키가 지지대에 걸린다. 지지대를 없애버릴 수는 없으니 깍는 수밖에 다른 도리가 없다. 다음은 이번에 새로 장만한 드릴 셋트이다.

비트를 2미리, 3미리 바꿔 가며 쓰기 귀찮아 그냥 하나 더 샀다. 85000원짜리인데 거의 미사용이라 아무래도 중국제 수입해서 싸게 파는 거 모양이다. 마감이 조악하고 설명서가 부실하지만 드릴 자체는 쓸만하다. 여기도 원형 톱을 끼웠다.

이걸로 스텐 구멍 뚫어 볼려고 장만해 놓은건데 택도 없다. 대신 이럴 때는 유용하게 써 먹는다. 수직으로 자르고 측면에서 자르고 하면 나무를 각지게 잘라낼 수 있다. 톱날은 잘 드는 편인데 회전하면서 자르다 보니 톱이 자꾸 전진하려는 경향이 있어 꼭 잡아야 한다. 아니면 옆으로 톱이 굴러가 엉뚱한 부분을 자르거나 다칠 수도 있다. 아래 사진 보면 위쪽으로 톱이 한번 지나갔음을 알 수 있다.

좀 위험한 공구지만 아무튼 무사히 잘라냈고 칼로 마무리했다. 스위치 아랫부분이 들어갈만한 공간을 만들어 구겨 넣었다. 다행히 스위치가 높지 않아 조금만 잘라내면 된다. 다음에는 철판을 약간 더 넓게 만들거나 중앙의 여백을 비워 지지대 자리를 미리 고려해야겠다.

2호에 시럼삼아 끼워 두었던 스위치를 빼 4호로 옮긴다. 스위치 빼는 것도 힘이 많이 드는데 좀 쉽게 해 볼려고 풀러를 미리 사 두었다. 역시 돈주고 산게 기본 구성품보다는 품질이 좋고 힘이 덜 든다. 다음에도 스위치 뺄 일이 많으니 미리 장만해 두는 것도 좋은 거 같다. 근데 왜 2개냐면 한개 3900원인데 배송비가 3500원이라 억울해서 그냥 2개 샀다. 색상은 랜덤이라고 하더니 이왕이면 다른 색으로 2개 줄 것이지....

스위치를 다 끼운 후 다음은 키캡을 끼운다. 사실 철판을 찾아 오기 전에 미리 작업을 좀 해 둬서 일찍 끝냈다. 수평 피치가 18미리이다 보니 아래쪽만 조금 깍아 주면 된다. LP 키캡이 더 얇아 칼질이 쉽고 좌우는 거의 건드리지 않아도 되니 2시간 정도만에 모두 깍았다. 대략 2분당 1개꼴이어서 놀며 놀며 깍으면 된다.

기준 자리는 흰색 키캡을 빼다 박았는데 나름 예쁘고 시인성이 좋다. 키 개수가 늘어나니 키캡이 부족하다. 엄지쪽 2개를 넓은걸로 써도 3개나 부족한데 이건 다음에 키보드를 하나 더 주문해서 끼워야겠다. 일반 키캡은 LP랑 스템만 일치하지 깊이가 맞지 않아 쓸 수 없다. 그냥 얹히기만 하고 안으로 쑥 들어가지 않는다.

다음은 납땜을 할 차례인데 2가닥 한선짜리 납땜선이 아직 도착하지 않았다. 하필 대통령 선거날이라 이틀을 기다려야 하는데 그럴 수 없어 그냥 전에 사둔 얇은 단선을 쓰기로 했다. 선 가닥수가 많아 정신이 좀 없지만 얇아서 구부리기 쉽고 강도도 충분하며 무엇보다 배선 부피가 작아 아래쪽에 여유 공간이 많다.

옷핀에 돌려 동그란 고리를 만들고 스위치에 건다. 집게나 테이프로 눌러 놔야 빠지지 않는데 이런 작업이 시간을 잡아 먹는다. 단선이지만 탄력이 있어 잡아 주지 않으면 지 맘대로 빠져서 도망가 버린다. 스위치쪽 납땜을 한 후 기판쪽에 고정시킨다.

한번에 4 ~ 6개 정도 꽂아 놓고 납으로 고정한다. 탈피하고 꽂아서 고정하는게 힘들지 납땜 자체는 어렵지 않다. 오른쪽 편집키를 다 한 후 중앙 문자 부분을 납땜할 때는 기판과 철판을 같이 들어 V자 형태로 만들어야 한다. 그렇지 않으면 거리가 너무 멀어 선이 쓸데없이 길어진다.

안쪽으로 이동할수록 각도가 급해져 배선이나 납땜할 공간이 부족하며 선이 많아지면 기존 선을 건드리지 않게 신경이 많이 쓰여 더 느려진다. 3호의 컨넥터를 쓰는 방식에 비해 번거로운 건 사실이지만 시간은 덜 걸린다. 컨넥터 써 봐야 스위치 바꿔끼울 일도 없을 거 같고 값만 비싸다. 차라리 그냥 직결하는게 더 간단하고 싸다. 어차피 시제품은 다 1회용이라 직결해 버리는게 훨 간편하다.

편집키만 납땜해서 잘 동작하나 테스트해 본 후 피곤해서 잠이 들었다. 사실 잘 시간이 훨씬 지났는데 철판을 찾아 왔으니 뭔가 동작하는 걸 봐야 잘 거 아닌가? 성질이 급해서 잠을 줄여 가며 일하고 있다. 일 끝내고 푹 자는 것도 아니고 그냥 잠시 쓰러지는 식인데 6시쯤 자서 9시쯤 일어나는 식이다. 일어나자 마자 커피 한잔 독하게 타 먹고 부지런히 납땜해서 오른쪽을 완성했다.

순서를 생각하지 않고 엄지쪽 키를 먼저 연결했다가 중앙의 문자 부분 땜할 때 걸리적거려 힘들었다. 이미 연결해 놓은 걸 빼기도 그렇고 그냥 참아가며 꿋꿋하게 해 치웠다. 다 해 놓고 테스트해 보니 FN Space를 반대로 연결하는 실수를 했다. 다행히 육안으로 찾아 자르고 다시 이어 붙였는데 안그래도 짧은 선 2개를 그 좁은 공간에서 이어 붙일려니 무척 어려웠다. 다음은 왼쪽을 연결한다.

처음에 가장자리 부분을 연결할 때는 평평하게 펴 놓고 하니 아주 쉽다. 테이프 붙일 공간도 많고 선 길이도 짧다. 그러나 중앙 부분으로 갈수록 선이 너무 길어지고 복잡해 점점 힘들어진다. 시간 측정해 보니 딱 1시간에 11개 정도 연결하니 개당 5분이 더 걸린다.

그래도 점점 숙련되어 왼쪽은 3시간 정도밖에 걸리지 않았다. 스위치 핀을 수직으로 두고 걸면 자꾸 빠지는데 약간 휘어 놓고 걸면 잘 안 빠진다. 순서도 잘 고려해서 기판의 위에서 아래로 차례대로 땜하면 선이 걸리적거리지 않는다. 공간이 아주 협소해 테이핑을 할 수 없을 때는 왼손으로 선을 잡고 인두에 납을 묻힌 후 땜하는 내공까지 생겼다.

왼쪽까지 작업 완료한 모습이다. 뚜껑 덮기 전에 대충 테스트해 보니 다 제대로 연결한 거 같다. 맵핑 바꿀 계획이 있어 Esc는 직접 연결하고 미니 배열의 Esc 2에 연결했다. 맵핑이 바뀌었으니 소젯 3호와는 달라졌다. 이럴려고 1.0을 미리 릴리즈해 놓은 것이다. 4호가 완성되면 3호는 안 쓸거 같으니 맵핑이 달라져도 어쩔 수 없다.

큰 작업을 완료했으니 책상을 좀 치웠다. 이제 당분간 시제품 만들 일은 없을 거 같아 공구들 정리하고 작업하다 남은 찌꺼기도 다 치웠다. 선 탈피한게 이 정도다. 저걸 일일이 다 탈피해서 연결했으니 시간이 많이 들 수밖에 없다. 중간에 납땜선이 너무 길어 대충 쓸만큼만 잘랐는데 다 하고 보니 핀셋으로 집을 만큼만 딱 남았다. 이렇게 딱 떨어지면 뭔가 기분이 좋다. 남은 것도 인두기 팁에 다 발라 줬다.

주변 정리 후 기본 테스트해 보고 마무리했다. 바닥의 나사가 책상이 질질 끌려 뒤쪽에 신발하나 신겨 주고 앞쪽은 5미리 드릴로 입구를 넓혀 최대한 안쪽으로 밀어 넣었다. 지지대 바깥으로 튀어 나온 부분은 칼로 다듬어 잘랐다. 중앙의 LED 불빛이 너무 번쩍거리고 속이 훤히 들여다 보이는게 꼴사나워 흰색 도마 플라스틱으로 가렸다.

기본 테스트해 보니 일단 입력에는 이상이 없다. 그런데 FN키로 LED를 끄는 기능이 동작하지 않는다. 뭔가 납땜이 잘못된 부분이 있는건지 약간 불안하다. 그 외에 아래쪽 높이를 좀 더 낮출 수 있을 거 같은데 이 부분은 다음에 한가할 때 튜닝하기로 한다. 키캡 빠진건 어디서 구해서 끼워 놓아야 하는데 당장은 흰거라도 뽑아 넣으면 된다.

이제 당분간은 4호로 소프트웨어 개발에만 전념할 생각이다. 시제품 만드는데 너무 많은 돈과 시간이 들어가고 몸도 피곤하다. 조그만 개선 사항이 있다고 해서 너무 성급하게 시제품 다시 만들지 말고 충분히 모아 놨다가 만들어야겠다. 4호를 만드는데 드는 시간과 비용을 대충이라도 계산해 보자.

 

철판 : 2.5만원

기판, 스위치, 키캡 : 4만원

아크릴, 목재 : 1만원

배선, , 나사, 기타 : 0.5만원

키캡 가공 : 4시간. 12만원(시간당 3만원 계산)

납땜 : 8시간. 24만원

하우징 제작 : 2시간. 6만원

 

재료비가 8만원, 인건비가 42만원 정도 들어간 셈이니 원가는 50만원이다. 원식이 디자인값, 왔다갔다 교통비, 각종 공구나 전기세, 소프트웨어 개발비 등은 계산하지 않았다. 대량 생산을 하더라도 하루에 하나씩 뚝딱 만들지 않는 한 최소 30만원은 드는 셈이다.

하드웨어를 새로 만들었으니 소프트웨어도 그에 맞게 수정해야 한다. 오늘부터 당분간은 소프트웨어 개발에 치중할 예정이다.

 

ESC를 매크로키에 할당해 놓은 이유는 미니 배열에 ESC가 이미 있어 중복을 회피하기 위해서였다. 그런데 이 자리를 ESC 이외의 다른 기능으로 바꿀 사람은 거의 없을 거 같고 굳이 그럴 필요도 없다. Esc는 아예 자리를 고정하고 매크로에서 뺀다. 사실 매크로라기보다는 재정의 가능한 키라고 하는게 맞다. 매크로키는 왼쪽에 M1~M6까지, 오른쪽에 M7~M9까지 총 9개이다.

이 수정사항의 영향을 받는 코드가 은근히 많다. 일단 키맵 수정하고 매크로 실행 코드에서 번호를 조사하는 논리가 바뀌며 arMacro 배열의 크기와 초기값이 다 하나씩 이동해야 한다. useEtc 옵션의 조정 대상도 바뀌고 매크로 대화상자의 에디트도 하나씩 앞으로 당겼다.

▶ 조정은 마쳤는데 골치 아픈 문제가 하나 더 생겼다. 미니 배열의 Esc가 중복이라 풀배열에서는 자리만 차지한다는 점이다. 미니 배열에서 Esc에서 자리를 따로 내 주는게 좀 과하다 싶고 Caps도 마찬가지이다. 이 둘을 아예 Edit 레이어로 옮겨 버리면 키 2개를 문자로 활용할 수 있어 다국어와 기호 입력에 유용하게 쓸 수 있다.

, Tab은 도표 입력이나 엑셀 셀이동 등의 용도가 분명히 있고 또 그 자체로도 문자이므로 단독키를 유지한다. 이럴거 같으면 Tab을 쿼티와 똑같이 1행 제일 왼쪽에 두고 문자를 2행에 두는게 더 좋다. Esc Caps 자리가 문자가 되고 펑션행을 숫자로 사용하면 12 + 9 = 21개의 키가 할당되어 Num 레이어로 전환하지 않고도 모든 숫자와 기호를 다 입력할 수 있다. 여러 문자의 재배치가 필요한데 초안은 다음과 같다.

기호 전용키 9개에 빈도가 높은 18개의 문자를 배치해 놓고 Num 레이어의 문자와 0행에는 숫자 10, 괄호 8, 가감승제, `|까지 24개이다. 이 배치의 세부 사항이 복잡하다.

 

- 유로는 빈도가 높진 않으므로 Num 레이어에만 있다.

- 남는 자리를 활용하여 Num 레이어에 ,도 중복 배치해 콤마 삽입 가능. -> 삽입은 했는데 빈도가 더 높은 = 자리여서 건너편 Q 자리로 옮김.

- 0행의 괄호는 (), {}를 최우선 자리에 배정하고 []는 어쩔 수 없이 찢어 놨다.

- Caps Edit 레이어에만 있다. 이거 없다고 좀 까일 거 같은데 매크로키 쓰라 그래

- Esc Edit에 넣긴 하되 아예 ESC 키를 기본 배열에 포함하여 49키로 하는건 어떨까 생각중이다. 이런 식이면 Caps도 키를 배정하는게 좋다. 기본 배열 왼쪽에 Esc Cap만 나란히 수직으로 놓으면 된다. 이 경우 둘 다 기본 배열에 속하며 50키가 된다.

- Edit 레이어의 F1 이후를 왼쪽으로 한칸 옮겨 위의 펑션행과 맞추고 매크로를 왼쪽 5, 6열에 두고 싶은데 Caps, Esc가 한자리 차지하고 있어서 지금은 안된다. 매크로가 양쪽으로 찢어져 있어 실용성이 떨어진다.

- Num 레이어와 펑션행의 중복이 굉장히 지저분해 보인다. 기호는 Num에 두고 숫자와 +, -만 두는 것이 오히려 더 깔끔할 거 같은데 Num 레이어로 가지 않고도 모든 입력이 가능하도록 하기 위해 Shift에도 문자를 넣었다. Shift+F8보다 Num+T가 더 가깝고 제자리여서 효율적이다.

- 숫자를 0행에서 입력하는게 편하다면 아예 펑션 카테고리를 위에 더 배치하자는 요구도 나올 거 같다. 행을 토글해 가며 쓰면 결국 불편하다는 말이 나온다. 그러면 풀배열이 91키가 되며 텐키레스 기판으로는 시제품을 만들 수 없다.

- 숫자를 0행에서 주로 입력하면 Num 레이어는 결국 넘패드를 대신하는 역할과 미니배열에서의 숫자, 기호를 담당한다. 숫자, 기호를 입력하는 두 방법이 대체 관계이다.

- Tab이 한칸 위로 올라갔으니 Tab 2의 맵핑을 바꿔야 한다. Caps 9 정도의 다른 키로 바꾸고 싶은데 배선이 너무 길어질 거 같고 인두기 다시 꺼내기 싫어 망설이는 중이다. 5호는 2, 3을 새밖열에 맵핑하는게 좋겠다.

- Tab 아래의 추가된 두 키는 K_AL, K_ZL로 이름을 붙였다. A 키의 왼쪽, Z 키의 왼쪽에 있는 키라는 뜻이다. 쿼티에 원래 없던 키여서 이름을 만들어야 한다.

 

시제품 4호까지나 만들어 놓은 시점에서 문자를 재배치하고 있는게 믿기지 않을 정도로 황당하다. 키 개수가 바뀌고 여유키가 생기니 활용할 방안을 찾게 되고 그럴 때마다 차맷에 지진이 발생한다. 지금 이 배치가 적당한지 잘 모르겠는데 어쨌거나 테스트는 필요하니 조금 더 생각해 본 후 일단 적용해 보자. 후보가 될만한 거 다 때려박고 실사용해 본 후 필요 없다 싶은걸 걷어내는 작전이다.

▶ 문자 배치가 점점 복잡해져 나도 화면을 보지 않고는 어디에 어떤 문자가 있는지 바로 알기 어렵다. 또 펑션행은 지금 펑션 입력 상태인지 숫자 입력 상태인지 쳐 보기 전에는 알 수 없다. 더 이상 고정 캡션이 아니므로 누를 때 입력할 문자를 정확히 표시하는 것이 바람직하다.

매크로도 M1, M2 따위의 의미없는 키이름을 보여주는 것보다 등록된 내용을 보여주는 것이 쉽다. 물리적인 키보드의 캡션에는 어쩔 수 없지만 화면상의 프로그램에서는 연습을 위해 최대한 직관적으로 키 내용을 알 수 있도록 했다.

▶ 차맷의 useEtc 옵션은 더 이상 필요 없다. 문자키가 2개나 더 생겼고 필요하면 기호 영역키 일부까지 땡겨서 쓸 수 있으니 Tab 하나 정도는 기능을 고정해도 무방하다. 한글, 영문 모드에서는 기호키로만 쓰지만 다른 언어에서는 아닐 수도 있다.

Edit 모드에서 Tab BS 기능을 넣었는데 이제 BS 키가 따로 생겼으니 그럴 필요 없다. 항상 Tab으로 처리하면 된다.

▶ 쎈키 옵션이 없으졌으므로 툴바의 이 자리는 펑션행을 숫자로 입력하는 기능을 토글하는 것으로 사용한다. 툴바의 비트맵까지 수정했다.

Esc는 밖으로 빠지고 Tab은 위로 올라가고 Caps는 사라졌다. 이를 반영하기 위해 맵핑을 수정한다. 소프트웨어부터 진작 만들었으면 새벽에 납땜할 때부터 수정된 맵핑으로 했을텐데 키보드부터 조립하다 보니 괜히 일을 두 번 하게 된다. 이왕 옮기는 김에 왼쪽에 전부 숫자를 주고 Num 9로 조정했다.

다 조립한 거 뜯어서 저 좁은 공간에서 선 이어 붙일려니 힘들다. Num에 붙어 있던 1 K_AL, K_AL에 붙어 있던 Tab K_Tab으로, Caps에 붙어 있던 선은 K_ZL, 9는 새로 선 연결해서 Num에 붙였다. 4개를 바꾸는데도 무쟈게 헷갈린다. 다행히 다 한 후 테스트해 보니 정상적으로 잘 붙었으며 소프트웨어 수정한 것도 잘 적용되었다.

다음은 하우징을 좀 더 조정했다. 왼쪽 아래는 7미리로 그나마 좀 나은데 오른쪽 아래는 9미리로 붕 떠 있다. 원래 설계가 5미리였는데 왜 이렇게 높아졌는지 모르겠다. 계산은 똑바로 했는데 나무를 자를 때 오차가 있었던 모양이다. 배선을 다 하고 나서도 아래쪽에 공간이 많이 남아 있어 바짝 더 내려도 되는데 너무 떠 있다.

옆 지지대 2개 분리해서 대패질했다. 큰 칼로 하니 대패질도 할만한데 나무가 작아 꽉 잡고 있느라 팔이 아프다. 원목이라 슥슥 잘리는 느낌이 참 좋고 향기도 좋으며 대패질하고난 면이 반질반질하다. 요렇게 해서 붙였는데 왼쪽은 5미리에 근접하지만 오른쪽은 7미리로 소폭 낮아졌다. 또 뜯기 귀찮아 그냥 조립해 버렸다.

높이를 대폭 낮추며 팜레스트없이 써볼려고 했는데 억지로 쓸 수는 있을 거 같다. 그러나 다른 문제가 또 있는데 철판면이 각져 자꾸 비비면 손바닥이 아프다. 이걸 줄로 갈 수는 없으니 팜레스트를 써야 한다.

여기까지 작업했는데 택배가 도착했다. 사실 이 점프선을 받고 난 다음에 조립할려고 했는데 이틀이나 기다릴 수 없어 그냥 단선을 썼다. 막상 택배 받아 보니 안 기다리길 잘 했다는 생각이 든다.

선이 너무 굵어 이걸로 땜하다가는 배선 공간이 안나올 거 같다. 이게 무려 16000 + 2500원인데 길이만 나와 있을 뿐 선두께에 대한 설명이 없다. 대략 0.5미리는 더 되어 보이는데 그보다 피복이 더 두꺼워 둔해 보인다. 피복까지 재 보니 1.2미리 정도이다.

아주 쓸데가 없을 거 같지는 않고 다음번에는 철판 먼저 조립해 놓고 구멍 사이로 선을 넣은 후 스위치를 납땜할까 생각중이다. 그때 함 써 먹어 봐야겠다. 스위치 구멍에 꽂아 보니 쑥 들어가기는 하고 스위치에는 감지 말고 바로 납땜해 버려야겠다.

▶ 키캡 3개가 부족해 빠져 있는 상태인데 이대로 둘 수는 없어 흰색 키보드에서 세개 압수해서 대충 꽂아 줬다. 물론 칼질은 새로 해야 한다.

이렇게 하니 좌우 대칭도 안맞고 예쁘지도 않다. 이왕 압수할거면 여러개 가져와 대칭을 이루는게 좋겠고 문자 영역과 조합키를 명백히 분리하여 시인성을 높이자. 그래서 세 개 더 압수해서 조합키에 꽂았다.

이로써 4호 키보드가 일단 완성되었다. 다음판은 검정 키보드 하나 더 주문해서 이 모양과 반대로 끼워야겠다. 스위치는 몇개 남는데 키캡이 3개 부족해 키보드 3개를 사야 시제품 2개를 만들 수 있다. 두달 반동안 만든 1~4호까지 한자리에 모아 봤다.

뭔가 매번 바뀌기는 하는데 과연 발전하고 있는지는 모르겠다. 1,2호는 앞으로 쓸일이 없을 거 같고 당분간 3,4호로 테스트나 많이 해 봐야겠다. 4호가 그늘지게 나와서 독사진 한장 더 찍었다.

--------------------

3 11

하루가 또 지났다. 16일 출근이 확정되었고 주말에는 할아버지 제사 가야해서 이제 시간이 얼마 남지 않았다. 오늘은 소프트웨어 업데이트나 집중하자.

▶ 연습 프로그램의 자판에 마지막 누른 키를 노란색으로 강조하여 보여 주는 기능이 있으며 처음 연습할 때는 꽤 도움이 된다. 그러나 익숙해진 상태에서 후킹 프로그램을 띄워 놓으면 화면 모퉁이에서 번쩍번쩍거려 요란하기만 하고 정신 사납다.

Option showLastKey 멤버 추가하고 이 값이 true일 때만 표시하도록 했다. 디폴트는 일단 true이며 옵션 대화상자에서 끈다. 굳이 툴바에 빼 놓지는 않았는데 다음에 필요하면 빼 놓기로 한다.

▶ 소젯은 Shift, Ctrl, Num, Edit 등의 키에 대해 1회 입력 기능을 제공하여 굳이 같이 누르지 않아도 된다. 윈도우에서는 고정키라고 불리는 기능인데 일단 Once라고 하자. Num, Edit의 경우는 소젯이 정의한 키이고 이 방식이 편리하지만 Ctrl, Shift의 경우는 부작용이 발견되었다. 눌러 놓고 다음 키를 누를 때 딱 한번만 적용하고 바로 리셋하며 Ctrl, Shift를 다시 눌러 취소할 수 있어 키보드 입력시는 별 문제가 되지 않는다.

그러나 마우스와 결합하면 문제가 달라진다. Shift+클릭 후 어떤 키를 누르면 Shift가 눌러진 상태로 인식된다. 토탈 커맨더에서 Shift+클릭으로 파일 여러 개 선택할 때 Shift 누름, 놓음 사이에 마우스 클릭이 있을 뿐 다른 키는 입력한 바 없어 bShiftOnce true로 설정한다. 이 상태에서 F5를 누르면 복사하는 게 아니라 Shift+F5로 인식하여 폴더내 복사 명령이 된다. 문제의 핵심은 Shift 사이에 키입력이 끼어 들면 Once가 아니지만 마우스 입력은 Once라는 점이다. 이때는 Shift만 단독으로 누른 것이 아니다.

Once 상태가 너무 오래 지속되는 문제도 있다. 입력중에 Ctrl만 눌러 놓고 갑자기 자리를 비웠다가 다시 돌아왔을 때 처음 누르는 키는 여전히 Ctrl 조합으로 인식되어 엉뚱한 오동작을 할 수 있다. Shift, Ctrl 1회 입력은 타임아웃을 두어 짧은 시간에 누를 때만 인정하고 일정 시간을 넘기면 리셋해 버리는 기능이 필요하다. 윈도우의 고정키 기능은 어떤지 분석해 보자.

 

옵션을 켜야만 적용되며 디폴트는 꺼져 있다. Shift를 다섯번 누르면 켜지되 대화상자가 나타나 귀찮게 한다.  작업 표시줄에 4칸으로 된 아이콘으로 어떤 키가 고정되어 있는지 보여 준다. Ctrl Shift를 동시에 누르면 해제되며 Shift를 누른 채로 블록을 선택해도 해제된다. 더블 푸시로 Shift를 잠근 후 이동해야 블록 선택이 된다. 켜지고 꺼질 때 소리로 알려 주기도 하는데 현재 상태를 사용자가 알아야 하니 필요하지만 좀 시끄럽다.

막상 사용해 보니 별로 편리하지 않다. 쌍자음 입력할 때 따로 눌러도 잘 동작하지만 어찌 잘못 누르면 영문이 rkqwkrl dlfjs answkrk 이딴 자가 나오기도 한다. 밑줄은 그어지는지 모르겠네. 마우스 입력도 고정키를 리셋하여 Shift 클릭 후에 Shift가 잘 풀린다. 나는 이 기능을 제대로 써 본적이 없고 검색해 봐도 해제법이 주로 많아 별 인기는 없는 모양이다. 손이 불편한 사람들이 가끔 쓰는 정도이다.

소젯은 입력 편의를 위해 처음부터 기능을 염두에 두고 포함했는데 부작용 사례가 있어 해결해야 한다. 먼저 기능을 것인가 아닌가를 사용자가 선택할 옵션이 필요하다. Alt, Win, Fn까지는 필요 없고 Ctrl, Shift 두 개의 키 각각에 대해 사용 여부를 선택한다. 다음 4개의 변수를 선언하고 INI 입출력 및 대화상자에 표시한다.

 

     BOOL shiftOnce;            // Shift 1회 입력 사용 여부

     int shiftTimeout;         // Shift 1회 입력 타임아웃

     BOOL ctrlOnce;             // Ctrl 1회 입력 사용여부

     int ctrlTimeout;     // Ctrl 1회 입력 타임아웃

 

옵션을 적용하는건 예상외로 간단한데 켜져 있지 않으면 bShiftOnce 변수를 건드리지 않으면 된다. 이 값이 항상 false이면 키가 눌러졌을 때만 Shift를 조합한다.

 

     // Shift 상태 변경

     if (kidx == K_SHIFT) {

          if (bDown) {

              // 누를 때는 아무 것도 안한다.

          } else {

              // Shift 1회 입력 옵션이 켜져 있을 때만 bShiftOnce를 변경한다. 그렇지 않으면 이 값은 항상 false이며 누르고 있을 때만 Shift 조합한다.

              if (Opt.shiftOnce) {

                   // 눌렀다가 그냥 놓았으면 Shift 상태를 토글한다. 조합으로 다른키와 함께 눌렀으면 ShiftOnce가 아니다.

                   if (KeyQueue[0].kidx == K_SHIFT) {

                        bShiftOnce = !bShiftOnce;

                   }

              }

          }

     }

 

Ctrl도 마찬가지 방식이다. Once 기능을 사용한다면 마우스 입력 감지와 타임아웃 기능이 필요하다. 타임아웃은 bShiftOnce 변수가 켜져 있는데 직전에 입력한 Shift키 시간이 일정 시간이 넘었으면 리셋해 버리는 것이다. 이것도 논리는 간단하다. ProcessKey 선두에서 두 Once 변수의 유효성을 점검해 보면 된다.

 

     if (bShiftOnce) {

          if (GetTickCount() - KeyQueue[0].Tick > (DWORD)Opt.shiftTimeout) {

              bShiftOnce = false;

          }

     }

 

마지막 입력한 시간이 타임아웃보다 더 이전이면 무시해 버리는 것이다. Shift Ctrl 눌러 놓고 밥 먹고 와서 누르는건 인정하지 않는다. 입력 시점에서 점검하기 때문에 화면의 캡션을 바꾸지 않는건 좀 아쉬운데 그렇다고 타이머 돌려가며 관리할 필요까지는 없어 보인다.

다음은 마우스 클릭 조합을 처리한다. 윈도우의 고정키 기능을 분석해 보니 고정키 상태에서 클릭하면 고정키가 해제되는데 휠을 굴렸을 때는 해제되지 않는다. Ctrl 눌러 놓고 휠 돌리다 Z를 누르면 이때는 Ctrl+Z가 된다. , 클릭에 대해서는 그럭 저럭 동작하지만 휠에 대해서는 제대로 동작하지 않는다. 운영체제의 고정키도 완벽하지 않다.

이 문제를 해결하려면 Shift 상태에서 클릭할 때는 Once가 설정되지 않도록 해야 하며 결국 마우스도 후킹해야 한다. 저수준 마우스 후킹 예제를 만들어 보니 키보드와 마찬가지로 DLL 없이 로컬 함수로 모든 마우스 입력을 받을 수 있다. 좌우 버튼 DOWN에 대해서만 키큐에 kidx 100 등을 집어 넣어 Shift 누름과 놓음이 연속되지 않도록 하면 된다. Once 설정을 다음 조건으로 하기 때문이다.

 

if (KeyQueue[0].kidx == K_SHIFT)

 

Shift를 놓을 때 직전에 누른게 Shift이면 중간에 다른 입력이 없었다는 뜻이며 이때 Once를 토글한다. 그러나 마우스 클릭이 중간에 끼어들면 키큐에 100을 기록하여 직전에 누른게 Shift가 아니도록 만들어 버림으로써 Once가 되지 않도록 한다.

이 작전이 좀 대충인 거 같아도 일단 잘 통한다. 토탈 커맨더의 Shift 클릭 문제는 일단 해결했다. 그러나 더 사용해 보면 추가적인 문제가 더 발생할 거 같은데 마우스와 키보드를 다 후킹하고 있으니 어떻게든 대처는 가능할 거 같다. 마우스 메시지는 보기만 할 뿐 조작하지는 않는다.

bShiftOnce는 클릭에는 적용되지 않는다. 소젯이 이 플래그를 설정했더라도 응용 프로그램은 GetKeyState Shift키의 상태를 판별하므로 이 플래그를 바꿀 방법이 없다. 그래서 Shift+클릭은 홀드 상태로만 동작하며 Once로는 동작하지 않는다. 이게 더 자연스러운 거 같다.

4호의 실정에 맞게 소프트웨어도 적당히 업그레이드했다. 이제 4호 시제품을 제대로 사용해 보고 점검해 보자. 여기서 점검한 사항은 3호때와 마찬가지로 5호를 만들 때 참조할 것이다.

 

- 키감 : LP의 키감이 무척 마음에 든다. 스트록이 짧아 속도도 빠른 느낌이고 손에도 별 부담을 주지 않는다. LP 쓰다가 일반 기계식은 다시 못 쓸거 같다. 싸구려 스위치임에도 로지텍 g913 수준의 키감을 선사한다. 다음부터 시제품은 계속 이 모델로 만들어야겠다. 내구성이 조금 걱정되지만 고장난 스위치만 바꾸면 된다.

- 키피치 : 18*17이나 17*17이나 차이를 느끼기 어렵다. 하긴 1미리 차이가 느껴지면 그게 더 이상한거겠지. 이거 치다가 쿼티 19*19를 치면 벙벙해 가급적 좁히는게 바람직하다. 스위치만 나온다면 17*12 정도로 만들고 싶은데 그건 당분간 어려울 거 같다. 그런데 수직 2미리 차이로 인해 손가락 위치가 좀 달라지기도 한다. 2행에 있던 손가락이 1행으로 이동하면 나도 모르게 키의 윗부분을 치고 있다. 

손가락이 기억하는 키간 거리를 바꾸는데는 시간이 걸리고 한번 적응하면 다시 돌아오기 쉽지 않다. 그래서 처음부터 피치를 원하는대로 만들고 싶은데 그게 안되니 안타깝다. 키캡 깍는게 고달파도 낮은 스위치를 구하기 전까지 당분간은 피치를 18*17로 만들기로 한다. 

- 수평각도 : 8도 정도면 과하지 않고 딱 좋다. 양팔을 몸에 붙이고 쳐도 손목에 무리없고 벌렸을 때는 손목을 약간 꺽어서 치면 된다. 자판 거리에 따라 변화가 있는데 좁히면 9도로 조정하고 넓히면 7도가 적당하다. 기껏해야 1,2도만 증감할 거 같은데 당분간은 8도를 유지하기로 한다.

- 수직각도 : 4도로 약간만 기울였는데 이것도 괜찮다. 평평한 것보다는 자연스럽고 과하지도 않다. 좌우 분리형으로 계속 만들거라면 적당히 각도를 줘 볼 생각이다. 이 각도는 하우징만 다시 만들면 되기 때문에 여러 각도를 시험해 볼 수 있다. 6도는 만들어 봤으니 다음에는 8도로도 만들어 봐야겠다. 볼록해져서 그렇지 8도까지는 괜찮을 거 같다.

- 키보드 기울기 : 지금 대략 8~10도 정도 되는데 적당하다. 배선 공간 때문에 하단을 과하게 낮출 수 없어 팜레스트는 필수이다. 혹시나 해서 앞쪽을 높여 평평하게 해 놓고 쳐 봤는데 팜레스트가 두개 필요하다. 이론적으로는 이게 손목에 좋다고 하는데 암만 쳐 봐도 동의하기 어렵다. 아예 앞을 높여 앞쪽으로 기울여 놓고 써 보니 이건 정말 아닌거 같다.

내 팔꿈치가 한참 아래쪽이라 손목이 볼록하게 꺽인다. 각도는 더 연구해 봐야겠지만 방향은 뒤를 드는게 맞고 5~12도 범위가 적당하다. 근데 이건 키보드 자체의 기울기라 만들 때는 심각하게 고려하지 않아도 된다.

- 좌우거리 : 엄지 안쪽키간 거리는 26미리인데 충분하다. 철판이 키와 5미리 차이니 철판끼리는 16미리 거리이다. 이보다 더 좁은 것도 괜찮을 거 같은데 더 넓은건 공간을 많이 차지해 별로다. 자판만 있으면 20 정도, 만약 중간에 터치패드를 놓는다면 40미리까지는 벌려도 될거 같다. 5호는 철판끼리 딱 붙여서 10미리만 띄워 보는 것도 시도해 볼만하다.

- 새끼 내림 : 대충 5미리 내렸는데 적당하다. 7미리 내리면 많을 거 같고 3미리 내릴 바에야 안 내리는 거랑 거의 비슷해 더 조정할 필요는 없어 보인다. 새끼 손가락이 아래위로 이동하기 편하고 새밖열도 접근성이 좋아져 오타도 덜하고 자세도 편안하다. 우연의 일치겠지만 8도 기울이고 2열을 5미리 내리면 상단이 일치해 보기 좋고 편집키와도 상단 정렬되어 안정감이 있다.

만약 꼭 조정해 보고 싶다면 6미리로 조금 더 내려 보는게 좋겠다. 중지를 약간 올리는 방안도 있고 실제 그렇게 나오는 인체공학 키보드도 많은데 지금 당장은 굳이 그렇게까지 할 필요가 있나 싶다. 나중에 시범삼아 한번 해 보되 당장은 일자로 가기로 한다.

- Once : 옵션을 꺼 놓고 치고 있는데 한글은 딱히 불편하지 않고 오히려 일관성이 있어 좋다. 그런데 :이나 ?를 칠 때는 좀 손이 간다는 느낌이다. 이건 습관의 문제다. 별 문제 없도록 수정은 해 놨는데 이 옵션이 유용한지, 부작용은 없는지 장기간 테스트가 필요하다.

- 재질 : 스텐판이 단단해서 좋다. 모서리는 라운드를 줬는데 가장자리는 여전히 뾰족해 손바닥이 닿으면 조금 아프다. 줄질을 하기는 어렵고 테이핑이나 앞쪽 마개 등을 강구해 봐야겠다. 다음판은 알루미늄도 시도해볼 예정이다.

- 나사구멍 : 측면 지지대가 키에 걸려 깍아내는 수고를 했다. 이걸 안 깍으려면 하판폭이 더 넓어져야 하는데 그건 좀 부담스럽다. 하단 모서리에 지지대를 세우는 방법이 있지만 나사구멍을 뚫어 놓지 않았다. 확실히 하우징을 먼저 만들고 철판을 만들어야 순서가 맞다. 다음 판은 나사 구멍을 여기저기 뚫어 놔야겠다.

- 엄지키의 오프셋 및 각도 : 느낌상 약간 안쪽으로 들어간 거 같다. 3호는 바깥쪽으로 들어가 있어 4호는 안쪽으로 약간 이동했는데 많이 간 거 같다. 자연스러운 자세로 엄지를 얹어 보면 공백키의 약간 오른쪽이다.

 

엄지키의 들여쓰기 정도를 enter키의 위치로 정의한다. 공백은 기울어져 있어 정확한 위치를 지정하기 어렵다. 두 키의 거리는 피치의 영향을 받기 때문에 단순히 몇미리 띄운다는 정의로는 일관되지 않다. J enter의 중심 거리를 정의해야 일관된 거리를 유지할 수 있다. 3, 4호의 현재 거리는 다음과 같다.

8.5는 너무 많고 4는 너무 작으니 6 정도가 적당해 보인다. 수직 거리는 키캡 크기를 더 줄일 수 없어 강제로 34이지만 차후 작은 키캡을 쓴다면 30 정도가 적당하다. 더 낮은 키캡을 쓰면 오히려 수직 간격을 띄워야 한다. , 이상적인 위치는 J중심에서 수평으로 +6, 수직으로 +30이되 현재는 키캡 높이 제한이 있어 (+6, +34)에 배치해야 한다. 5호는 이렇게 만들어 보기로 한다. 공백, lang의 각도는 20 ,40이 적당하다.

 

전반적으로 완성도가 많이 높아졌고 시급히 개선할만한 부분은 보이지 않는다. 이 정도면 장기간 사용해 보고 문제점을 하나씩 발견할 수 있을 거 같다. 한달 이상 사용해 보고 5호는 모든 개선 사항을 다 수집한 후에 만들어 보기로 한다. 키보드 배열의 문제보다는 내 손가락이 아직 자리를 정확히 찾지 못하는 문제가 더 크다.

 

▶ 테스트하는 중에 오토마타 버그를 2개 발견했다. Shift+ㅔ를 누르면 ㅖ가 입력되는데 소젯은 ㅔ를 두 번 누르도록 되어 있어 맞지 않다. 연습에서는 정상 동작하나 후킹중에만 문제가 발생한다. 키맵에는 Shift 자리에 ㅖ가 기록되어 있지 않고 후킹 코드도 withShift 0으로 정상 계산한다. 그러나 kbd_event p만 보내도 타겟에서 GetKeyState로 조사하면 Shift를 누른 것으로 나타나니 ㅖ가 입력된다.

Shift를 이미 누르고 있는 상태에서 타겟이 이를 무시하도록 할 방법이 마땅치 않다. 억지로 up을 먼저 보내 놓고 p만 보낸 후 다시 Shift down을 보낼 수는 있지만 굳이 그럴 필요까지야 있나 싶다. once옵션을 켜 두고 순서대로 Shift와 ㅔ를 누르면 이때는 ㅔ가 정상 입력된다. 당장 해결은 어려울거 같으니 문제만 파악해 두자.

다음은 =을 누를 때 +를 잘못 입력하는 문제가 있다. 디버깅해 보니 arVk 테이블에 맵을 잘못 작성했다. 가상키 187번의 문자표에 노멀 위치의 문자와 Shift 위치의 문자가 반대로 되어 있다. =가 노멀이고 + Shift이다. 맵만 수정하니 정상 동작한다. 맵이 은근히 복잡하고 양이 많아 정확하게 적기 참 어렵다.

▶이제 실사용하기 부족하지 않을만큼 만들었다. 그런데 소젯으로 못하는게 있다. 후킹중인 소젯을 디버깅하는건 안될 뿐만 아니라 위험하기까지 하다. 키보드를 둘이 동시에 후킹하면 꼬일게 뻔하다. 디버깅 대상인 디버기가 디버깅을 수행하는 디버거에게 키를 입력받아 전달해 줘야 하니 말이 안된다.

그냥 실행은 가능하고 심지어 이중 후킹도 다음 체인으로 입력을 보내지 않기 때문에 예상외로 별 문제가 없다. 그냥 뒤쪽 체인이 무시당할 뿐이다. 그러나 중단점에서 멈춰 단계 실행하는건 안된다. 디버기가 멈추면 디버거도 같이 멈춰 버리며 마우스 디버깅만 가능하다. 후킹 디버깅은 Trace로 하는 수밖에 없다. 소젯 개발중에는 어쩔 수 없이 쿼티 키보드를 써야 한다.

그럼 연습은 어떨까? 막상 해 보니 앞에서 후킹한 키를 받아서는 아무것도 할 수 없고 그야말로 개판이 되어 버린다. 소젯은 2벌식 키보드에 기생하는 구현체인데 먼저 입력을 받는 녀석이 소젯이면 안되는거다. 소젯이 떠 있는 상태에서 소젯을 다시 띄우면 이걸로는 할 수 있는게 없다. 소젯은 디바이스 드라이버에 준하는 프로그램이며 두번 실행을 금지하는게 답이다.

뮤텍스를 사용하여 두번 실행을 금지했다. 어떡하든 소젯으로 디버깅을 일부라도 가능하게 해 볼려고 했는데 불가능하다. 이때는 어쩔 수 없이 쿼티 키보드를 잠시 쓰기로 한다. 아니면 소젯으로 쿼티를 대체할 수 있도록 맵핑을 최대한 유사하게 만드는 것도 한 방법이다.

---------------------

3 14

제사 다녀 오느라 이틀이 지났다. 아우한테 키보드 보여줬는데 별 관심이 없음. 그냥 만들고 있나 보다 생각하는 거 같음. 일반적으로 사람들은 남이 하는 일에 큰 관심이 없다. pt할려고 노트북 다 챙겨 갔는데 그럴 필요가 없는 거 같다. 좀 더 완성된 후에 보여줘야겠다. 장거리 운전하고 12시간이나 잤더니 개운하기는 하다.

 

▶레이어 타임아웃을 적용했다. 이 기능이 필요한 이유는 키보드는 문자 입력이 주 기능이고 편집이나 숫자 입력이 보조 기능이기 때문이다. 타이프 치다가 Edit 모드까지 눌러 놓고 잠시 자리를 비운 후 다시 돌아와 다시 타이프를 칠 때 10분전에 눌러 놓은 Edit키는 무효가 되어야 맞다. 숫자도 마찬가지이고.

그래서 10분 타임아웃을 설정하고 이 시간 경과 후에는 자동으로 언어 레이어로 복귀하는 옵션을 만들었다. 락 상태일 때도 타임아웃을 적용할 수 있되 이것도 옵션이다. 디폴트는 60초이고 잠금도 풀도록 했다.

▶매크로에 연속 누름 기능을 작성했다. 한번에 하나의 키만 입력하는게 아니라 :으로 구분된 여러명령을 일괄실행하는 것이다. 이 기능을 사용하면 다음 매크로로 좌우글자를 교환하는게 가능하다. 옆글자 선택해서 자르고 오른쪽으로 이동해서 붙이고 원래 자리로 다시 돌아가는 식이다.

 

#left:^X:right:^V:left

 

사실 전에도 있던 기능인데 잠시 없앴다가 정비해서 다시 적용했다. 목적어, 횟수 등의 문법은 간소화하고 키누름만 기록한다. 어떻게 조합하는가에 따라 응용의 묘미가 있다. 조합키만 해도 상당히 편리하다. 지금은 이 정도까지만 해 두고 다음에 스크립트 수준까지 업그레이드할 예정이다. 물론 AutoHotKey같은 훌륭한 프로그램이 있지만 키보다 자체가 지원하면 더 간편하다.

▶매크로를 작성하려면 키의 이름과 간단한 규칙 정도는 숙지해야 한다. 그래서 대화상자에 도움말을 작성했다. 시간 관계상 텍스트 포맷으로 만들었지만 필요한 내용은 다 포함되어 있다. 차후 그래픽으로 예쁘게 만들어 보기로 한다. 시간이 아주 널널해지면

▶위의 그림 붙여 넣다가 m5 m6이랑 키캡이 부딪혀 m5를 빼는데 선이 하나 쏙 빠져 버렸다. 대부분 튼튼하게 땜이 되어 있는데 납이 좀 덜 묻은게 있는 모양이다. 얼른 빼서 수술해 줬는데 회사 가지고 갔다가 이러면 정말 낭패다. 납땜 더 튼튼하게 해야겠다.

showLastKey 옵션이 꺼져 있을 때는 매번 화면의 키보드를 그릴 필요가 없다. 물론 매번 그리는게 제일 확실하지만 디바이스 드라이버가 CPU 시간을 너무 많이 쳐먹으면 전반적인 시스템의 속도에 좋지 않으니 가급적 시간을 아껴야 한다. 레이어나 Shift, FN 모드 등이 바뀔 때만 그리도록 했다. 릴리즈에서는 로그도 안 찍으며 조용히 후킹만 한다.

Num Shift 모드에 이모티콘을 더 넣으려고 했는데 실패했을 뿐만 아니라 기존의 이모티콘이나 유로 문자도 넣을 수 없을 발견했다. 키보드 후킹은 타겟으로 문자열을 보내는 게 아니라 누를 키를 보내는건데 어떤 키를 보내도 한번에 입력할 수는 없다. 혹시 WM_CHAR를 보내면 될지 모르겠지만 이것도 응용 프로그램이 처리해야 가능하다.

그러고 보면 쿼티 키보드로 2바이트 문자를 입력하는 예가 없다. 디바이스 드라이버라도 이건 안될 수도 있다. 일단 안되는 걸로 정리해 놓자. 그리고 왼새밖열 3행에 아직 유로 문자가 남아 있어 ^문자로 대체해 두었다.

Num 모드에서 Shift를 누른 상태에서 123을 누르면 !@#이 입력된다. 원래 이 자리는 숫자만 있어 Shift를 눌러도 123이 나와야 하며 후킹시 Shift없이 숫자만 보내지만 이미 Shift가 홀드되어 있는 상태여서 타겟이 인식해 버린다. 어제 ㅒ, ㅖ도 똑같은 증상이 있어 잠시 접어 뒀는데 이제 그럴 수가 없다.

$자리의 위에 `가 있는데 이 문자를 타겟으로 그냥 보내면 ~가 입력되어 완전히 틀린 결과가 된다. 소젯에 Shift 자리에 있지만 쿼티에서는 Normal자리에 있다면 Shift 홀드를 풀고 보내야 한다. 이 동작을 처리하는 KeyEventShift 함수를 만들고 Shift 없이 보낼 입력이 이미 Shift홀드 상태이면 풀고 보내도록 했다. 다행히 이 처리가 잘 먹혀 들어가 ㅐ, ㅔ도 정상 처리했다.

다음은 Alt+Tab이 먹지 않는 문제가 발견되었다. 전 버전에서 분명히 되었던 기능인데 지금은 안되어 조사해 보니 맵핑이 바뀌면서 주석 처리한 코드가 문제였다. 전에는 Alt VK_MENU에 맵핑되어 있어 이 키 입력시 체인으로 보내줬는데 이제는 K_ALT를 그냥 보내면 된다. 주석 처리할 때 부주의해서 발생했던 문제였다.

▶기호의 위치를 대판 조정했다. 코드를 잠시 입력해 보니 / 자리가 너무 외진 곳에 있고 *도 집안열이라 자리가 좋지 않은데다 펑션행에도 두 기호가 Shift자리라 어떻게 입력해도 불편하다. /는 나눗셈 뿐만 아니라 주석으로 많이 쓰고 경로 구분자이기도 한데다 쿼티에서 원래 노말 자리였는데 밀려나 불만이 많을 거 같다. 이 둘을 새밖열이나마 노말 자리로 옮기고 밀려난 다른 기호도 연쇄적으로 이동했다.

$ %는 스크립트에서 많이 쓰니 노말 자리로 옮기고 숫자와 함께 주로 사용하는 ~를 숫자 옆으로 옮겼다. 펑션행에 */가 빠진 자리에 ^~를 배치하고 괄호도 둘씩 짝을 지어 찢어지지 않도록 조정했다. ()는 쿼티와 같은 90 위에 두었다. 그리고 이전 배치에서 `가 두 개이고 역슬레시가 빠진 버그도 수정했다.

 Num 모드의 집안열에 .,와 공백을 중복 배치하여 숫자 입력이 쉽도록 하고 ~는 건너편에 두었다. 이게 최적인지는 물론 모르겠지만 이전보다는 나아진 느낌이다. 더 테스트해 보고 하나씩 조정하도록 하자.

---------------------------

3 15 - 1.1릴리즈

어제 하루동안에도 꽤 많이 진척되었다. 하루 종일, 거의 20시간 가량 일만 했더니 버그도 잡고 추가하려고 계획했던 기능은 거의 다 포함했다. 여기까지가 시제품 4호를 위한 버전 1.1이다. 이걸로 내일 회사에 들고가 실무에 사용할 것이며 집에서는 시제품 5호를 차근차근 준비하기로 한다.

4호를 많이 사용해 본 것은 아니지만 그래도 다음 버전을 위한 개선 사항은 왠만큼 다 생각해 두었다. 만들다 보면 뭐가 부족하다는 것과 개선할 점이 뭔지 슬슬 보이기 시작한다. 물론 실사용해 보면 더 많이 보이는데 대략 2주 후에 5호를 만들기로 하고 준비 작업을 해 보자. 주 작업 내용은 다음과 같다.

 

- 숫자 카테고리를 다시 도입한다. 기록을 보니 2 1일 없앤 걸로 되어 있으며 펑션행만 해도 한손 자판을 충분히 만들 수 있고 일렬로 늘어서 효용성이 없다고 판단했다. 사실 지금도 그렇게 생각하며 정 필요하면 펑션행을 숫자로 쓰는 옵션도 제공한다. 그러나 잘 안 쓰더라도 이전을 위해 또 테스트를 위해 일시적으로는 필요하다고 생각이 바뀌었다.

일단 만들어 놓고 정말 없어도 되는지는 사용자가 결정해야 하며 그러기 위해서는 사용 빈도가 낮아도 일단은 있어야 한다. 없다고 까이는 것보다 일단 만들어 놓고 안쓰면 그때 없애도 된다. 펑션행이 없어도 숫자행을 대신 쓰거나 FN키로 임시적으로 쓰는 방법도 있고 Edit 레이어에도 있다.

숫자행이 있었던 마지막 버전인 0.99의 소스를 참고하여 C_NUMBER 카테고리와 k_fungap 옵션, 숫자키맵 등을 살려 놓기로 한다. 그때랑은 상황이 다르지만 참고할 소스가 있어 시간은 얼마 걸리지 않을 것이다. 키보드 높이가 높아지는건 수직 피치의 디폴트를 12미리로 낮추어 표시한다. 최종적으로 만들 모양대로 보여주는게 좋을 거 같다.

 

- 숫자행의 부활을 결정한 또 다른 중요한 이유는 드라이버없이 연결해도 기본 기능을 수행할 수 있도록 하기 위해서이다. 지금은 드라이버를 띄우지 않으면 숫자를 입력할 방법이 없다. 기호 배치가 좀 달라도 쿼티로도 그냥 쓸 수 있어야 한다. 이게 되면 소젯 개발시 쿼티를 굳이 연결하지 않아도 된다. 후킹을 안해도 쿼티로 실행하면 웬만큼 쓸만하다. 또 쿼티를 후킹해도 웬만큼 쓸만할 것이다.

이게 가능하려면 맵핑을 최대한 쿼티와 유사하게 해야 한다. 지금은 0행에 펑션을 맵핑해 놓고 숫자키를 매크로에 맵핑해 두었는데 결정적인 실수였다. 반대로 했어야 숫자는 일단 입력할 수 있고 펑션을 Edit 레이어에서 쓸 수 있다. 모든 키를 가급적 쿼티와 호환되도록 재연결해야 한다. 초기 맵핑을 다음과 같이 잡았다.

매크로는 넘패드에 연결하고 나머지는 텐키레스의 키를 가급적 활용했다. 87개의 키중 우Shift FN 2개 빼고 다 쓰는 셈이다. Alt는 이미 맵핑해 본 적이 있지만 caps는 특수키여서 별 말썽이 없을래나 모르겠다.

숫자행을 추가하고 맵핑을 조정하기 전에 오늘자 현재 버전을 1.1로 릴리즈한다. 4호를 위한 전용 드라이버가 되는 셈이다. 버전을 너무 막 올리는 거 같은데 변화가 많아 중간 백업이 필요해서이다.

1.1릴리즈한 실행 파일과 소스까지 홈 페이지에 공개했다. 아직 완성도가 낮고 정리도 덜 되었지만 내일 당장 회사에 가면 받아서 써야 하기 때문에 올렸다. 이후 실행 파일만 주기적으로 올리고 소스는 다 정리될 때 올려야겠다.

장시간 작업 끝에 숫자행 살려 넣고 추가 작업까지 완료했다. row0num 옵션은 numRawFn으로 이름을 바꾸고 숫자행을 펑션으로도 쓸 수 있도록 했다. 펑션행은 항상 펑션키로만 사용한다. numRawFn false여도 Fn키와는 조합하지 않는다. 그럴바에야 그냥 Edit조합을 쓰면 된다. 차맷의 useFn옵션은 이름을 useNum으로 바꾸고 숫자 영역에 문자를 사용하도록 했다.

엄지의 맵핑 변경은 좀 난관이 있었다. Num레이어의 ins키는 테스트 코드가 쓰고 있어 풀어주니 바로 되었다. 그러나 Edit레이어의 caps는 키 자체는 사용 가능하지만 누를 때마다 삑삑 소리가 난다. 대소문자 설정이 바뀌지는 않지만 시끄럽다. 찾아 보니 윈두의 설정을 꺼 줘야 소리가 나지 않는다.

후킹을 해서 막아 버려도 소리가 나는걸로 봐서 후킹보다 운영체제가 먼저 이 키를 인식하는 모양이다. 옵션만 끄면 큰 문제는 없는 거 같으니 당분간 이 키를 쓰기로 한다. Lang에 맵핑할 우 Alt는 전에 썼던 기능인데 소스를 찾기 어려웠다. 주기적으로 백업을 해 둬도 중간본이 없는 경우가 있어 휴지통까지 뒤져가며 이전 소스를 겨우 찾아냈다.

적용은 했고 동작도 잘 하지만 OnKeyHookLL, OnKey 함수가 워낙 복잡해 불안불안하다. 맵핑이 하도 자주 바뀌다 보니 땜방해 놓은 코드가 많은데 일체 정비를 해야겠다. 이제 87키중 남은건 우Shift FN밖에 없어 써 먹을건 다 써 먹은 셈이다. 여기까지 작업한 결과이다.

소젯 4호는 이 배열로는 동작하지 않는다. 왼쪽의 매크로 키를 누를려면 풀배열 키보드가 필요차며 따라서 5호는 풀배열 기판을 사용할 수밖에 없다. 그렇다고 무조건 풀배열일 필요는 없고 펑션행을 빼면 펑션에 연결할 수 있다. 5호 이후는 아마 그렇게 만들지 않을까 싶은데 그러면 맵핑만 바뀔 뿐 4호랑 사실 비슷하다.

▶ 매크로의 맵핑이 텐키레스에 자리가 없어 어쩔 수 없이 넘패드로 연결되었는데 펑션열이 없을 때는 굳이 그럴 필요가 없다. 펑션이 숨겨지면 이때는 f1~f6을 사용해도 된다. 소스에서 매번 맵핑을 수정하기는 귀찮으니 상황에 따라 동적으로 조정하는 옵션을 만들어 두기로 한다.

macroMapFn 옵션을 생성하고 디폴트를 true로 지정했다. 펑션을 숨길 때 이 옵션이 켜져 있으면 맵핑을 F1~F6으로 변경한다. 물론 옵션이 꺼져 있으면 그럴 필요없다. 펑션을 다시 보일 때는 이 옵션과 상관 없이 매크로의 맵핑은 무조건 넘패드로 옮겨야 한다. 안그러면 맵핑 충돌이 발생한다.

사용자가 이 옵션을 직접 변경할 경우는 그리 많지 않을 것이다. 이 옵션은 다만 텐키레스 기판으로 시제품을 만들었을 때 펑션을 당연히 숨길 것이므로 F1~F6에 맵핑하는 것을 자동으로 수행하기 위한 조치이다. 아마 이 형태의 시제품을 제일 많이 만들지 않을까 예상된다. 전체 배열은 91키이지만 펑션을 빼면 79키이다. 펑션키는 이전을 위한 중간 단계 정도로만 생각하고 있다.

----------------------------------

3 16

4호는 이미 완성되었고 5호 설계를 슬슬 시작했다. 이제 뭘 입력할 때 쿼티보다는 소젯이 더 편하다고 느끼고 있고 가급적 소젯을 사용한다. 아직 덜 익숙해서 속도는 느리지만 쿼티를 대체했다는 면에서 바람직한 현상이다. 더 좋다고는 아직 말하지 못하겠지만 최소한 대체 가능하다는 것을 확인했고 익숙해지면 더 좋긴 하다.

그런데 가끔 쿼티를 쳐 보면 도저히 못쓸만큼 엉망인 키보드는 아니라는 생각도 든다. 87개면 키 개수도 적당하고 손의 이동이 잦지만 그것도 나름 운동이다 생각하고 자세를 가끔 바꿔 주는 것도 피로도 개선에는 나름 도움이 되기도 한다. 영문 배열이 개판이지만 대량을 많이 입력하지 않는 한 익숙한게 더 편리한 것도 사실이고 기호 배치도 수십년간 손에 익어 착착 감긴다. 그 익숙함을 압도하기는 참 어렵다.

속도나 편의성으로 대중화를 바라기는 어려다 보니 소젯을 어필할 다른 뭔가가 필요하다. 아마 장애인용 한손 키보드가 그 역할을 해 주지 않을까 싶은데 장애인이 아니라도 한손만으로 입력이 가능하다는 건 큰 장점이기는 하다. 그래서 5호부터 한손 자판 설계를 시작하며 이를 위해 좌우동형으로 만들기로 한다.

철판을 재단하기 전에 하우징부터 만들어 봤다. 풀배열 기판이 필요해 콕스 CK420을 사용했는데 1년전에 쿠팡에서 33250원에 미리 사 둔 것이다. 콕스사가 핫스왑 제품을 많이 출시해서 제작에 큰 도움이 된다. 하판은 전에 사둔 알루미늄을 쓰기로 했다. 원래는 보강판용으로 사둔건데 레이저 컷팅을 하고나서부터 그럴 필요가 없어졌다.

길이 400이어서 풀배열 기판 일부가 노숙중인데 그냥 이대로 만들기로 한다. 하판에 구멍 몇개 뚫고 초록색 철끈으로 기판과 케이블을 단단히 고정했다. 드릴로 구멍뚫기 편해 가공하기 좋다. 다 고정한 후에 연결 테스트를 해 보려다 문득 알루미늄은 도체라 절연이 필요하다는 걸 깨달았다. 이대로 연결하면 모든 스위치가 합선이라 난리가 날 것이다. 다시 풀어서 전에 사둔 플라스틱 도마를 잘라 절연해 주었다.

길이가 확실이 좀 길기는 한데 어쩔 수 없다. 이 상태로 연결해 보니 키입력은 잘 된다. 이제 여기에 지지대 설치하고 스위치를 하나씩 납땜해 붙이면 되는데 이번에는 보강판 먼저 올려 놓고 구멍 사이로 선을 빼 바로 납땜해 버릴 것이다. 맵핑 거리만큼 선만 잘 빼 놓으면 된다.

지금은 쿼티 기준으로 맵핑이 되어 있어 드라이버없이 꽂으면 쿼티로 동작할텐데 아예 소젯으로 맵핑을 해 버리면 어떨까 하는 생각이 들었다. 그러면 드라이버가 없어도 영문은 qwerty로 나오지 않고 ywldj로 나올 것이고 한글은 아예 입력이 불가능할 것이다. 소젯이 기본이라는 면에서 의미는 있지만 대중화에는 지극히 불리할 거 같아 아주 다음에나 해 볼 수 있을 거 같다.

오늘부터 출근이라 4호는 당분간 회사로 출장을 보내야 한다. 그래서 3호를 다시 꺼내 치고 있는데 한글 배열이 같아도 스위치가 달라 어색하다. ETC가 있는 배열이고 기호 배치가 달라 입력용으로 쓰기 쉽지 않다. 배열이나 구조가 조금만 바뀌어도 이렇게 적응이 어렵다니, 한방에 제대로 만들어야겠다는 생각이 든다.

회사에 다녀왔는데 출근은 4 1일부터라고 해서 갑자기 시간 여유가 생겼다. 인재 부장님께 4호를 잠시 보여 줬는데 자세히 설명하지 못해 별 감흥은 없다. 영문 한번 쳐 보더니 알파벳 배열이 달라 적응하기 어렵겠으며 매니아가 아니면 적응할려고 하지 않을 거 같다는 의견을 밝혔다. 공감은 고사하고 설명하는 것도 참 어려운 일이다.

시간이 확보되었으니 5호까지는 일단 만들어 보자. , 회사 각각 있어야 하니 축별로 만들어 볼까 하고 CK420 미개봉 중고를 2만원에 하나 더 주문해 놨다. 용산 업자인 거 같은데 사자 마자 또 올리는 걸로 봐서 물량이 많은가 보다. 이걸 2만원에 팔 정도면 원가는 도대체 얼마인지 궁금하다.

스위치와 키캡도 더 필요해 640T슬림 청축 화이트도 하나 더 주문해 놨다. 시간 여유가 있을 때 재료는 일단 확보해 놔야 한다. 5호는 사실 4호에 펑션키만 얹는거라 거의 비슷하지만 이왕 처음부터 다시 만들어야 하니 몇가지 변화를 줘 봤다.

 

- 키피치 18*18로 수직 1미리 더 늘림 : 안 만들어본 크기라 시도해 보되 키캡 깍기 싫어서 조금 늘리기로 했다. 시제품일 뿐이고 어차피 최종적으로 원하는 피치가 아니니 그냥 시간 덜 드는 크기로 만드는 것다.

- 엄지행 2미리 더 바깥쪽으로 이동 : 4호를 실사용해 보니 조금 안쪽인 거 같아 2미리 더 이동했다. 수직 위치는 더 올려야 하지만 수평은 거의 확정이다.

- 새끼열 5미리에서 6미리로 약간 더 내림. 이것도 어디까지나 시도의 의미가 있을 뿐 5미리가 나빠서 그런 것은 아니다. 둘을 비교해 보고 결정할거다.

- 왼쪽 매크로 영역에도 편집 영역의 구멍만큼 뚫어 예비 구멍을 만들어 두었다. 장애인용을 위한 포석이기도 하고 각도 계산을 간편하게 하기 위해서이기도 하다. esc는 중간에 두면 되고 남은 구멍에 키보드의 Fn키도 맵핑해 놓을 수 있다.

 

키가 늘어난만큼 철판도 소폭 늘어난다. 모든 키가 다 들어오지만 지지대까지 고려하면 좁다. 펑션행을 굳이 가운데 놓지 않고 지지대 넓이만큼 벌려 놨는데 일단 보기가 싫고 자판 거리 조정이 자유롭지 못한 단점이 있다. Fn키를 안 끼우면 위쪽이 넓어질 뿐 별 상관은 없다. 텐키레스 기판을 쓰더라도 이 철판을 계속 쓸 수 있다.

피치를 18로 늘려서 수직 공간이 좁아졌는데 그렇다고 17로 줄여 봐야 겨우 6미리 정도 확보될 뿐이라 문제가 덜할 뿐 해결되는게 아니다. 이상적인 배치는 키캡 높이가 12미리 정도라 수직 공간 문제는 없다. 당장은 칼질 하기 싫으니 이번에는 그냥 18미리로 하자.

하판 높이를 아예 160이나 170으로 늘릴까도 생각해 봤는데 이러면 기판을 위로 붙이고 하단을 더 아래쪽으로 쭉 내려 키보드 높이를 더 낮출 수 있다. 팜레스트를 쓰지 않아도 된다. 그러나 160 높이에 Fn키를 배치하지 않으면 쓸데없이 공간만 차지하는 단점이 있다. 당장 보기는 싫지만 일단 이대로 만들어 보자.

4호와 5호는 큰 차이가 없는 거 같지만 다시 만들어야 할 정도로 중요한 차이가 있다. 맵핑을 쿼티 호환으로 만들거라서 5호는 드라이버가 없어도 웬만큼 쓸 수 있으며 Num, Edit 모드를 쓰지 못할 뿐이다. 그러면 소젯 개발도 가능하고 옆에 쿼티 키보드가 따로 없어도 이거 하나만 있으면 되니 간편하다. 처음 적응하는 사람에게도 무리가 없다. 왜 진작 이 생각을 못했는지 모르겠다.

도면 작업 요청서 상세하게 작성해서 아우한테 보냈다. 매번 원식이한테 신세 지는게 미안해 맛있는 거 사 먹으라고 10만원 보내 줬다. 이런 고급 인력을 이 가격에 활용할 수 있는게 어디냐. 원식이 없었으면 맨날 나무 자르고 있을 뻔 했는데 덕분에 일이 많이 단순해졌다. 물론 돈은 좀 들어가지만 말이다.오전 10시에 요청서를 보냈는데 원식이가 학교에 다녀 오는 바람에 오후 3시에 도면이 도착했다.

 펑션행이 2미리 덜 이동되어 있지만 큰 차이가 아니라 그냥 컷팅 주문을 넣었다. 메일과 문자를 보냈는데 별도의 답변이 없어 진행 상태를 알 수가 없다. 친절도가 좀 떨어지는 편인데 빠르면 내일, 늦으면 다음주에나 철판이 나올 거 같다.

철판이 오기 전에는 딱히 할 일이 없어 4호 하우징을 조정했다. 암만 봐도 앞쪽이 설계한 것보다 높고 특히 왼쪽이 더 심하다. 팜레스트없이 쓸려면 앞이 최대한 낮아야 해서 바짝 낮춰 보기로 했다.

지지대가 아직도 여전히 높아 줄그어 놓고 대패질로 바짝 낮추었다. 높이를 조정했더니 스위치 들어갈 자리가 좁아져 키가 눌리지 않는 문제가 발생해 한번 더 뜯어서 홈을 더 팠다. 전면 지지대도 풀어 깍아 주고 재조립했다.

그동안 좀 쉬어 손가락이 회복되었을 줄 알았는데 칼질을 해 보니 힘이 별로 없다. 게다가 언제 다쳤는지도 모르게 집게 손가락에 생채기가 생겼다. 키캡 칼질 안하게 18미리 피치로 한건 참 잘한 일이다. 이거 하는동안 어제 주문한 CK420이 도착했다.

쓰지도 않은 미개봉품이 2만원이라니 참 싸다. 얘는 기판만 빼 쓸거고 스위치나 키캡은 남는다. 풀배열은 요 두개만 만들어볼 것이다. 꽂아보니 정상 동작하며 쓸데없이 LED 불빛이 화려하다.

풀배열로 넘키가 어떻게 입력되는지 테스트해 봤는데 NumLock 상태에 따라 전달되는 가상키가 다르다. 4를 눌러 봤는데 넘락 상태에서는 가상키 64(VK_NUMPAD4)가 오고 넘락을 풀면 25(VK_LEFT)가 온다. 다행히 두 경우 모드 스캔코드는 75로 같아 넘패드의 키는 스캔코드로 읽어야 할거 같다.

오후에는 알리에서 이것 저것 주문 좀 했다. 회원 가입만 해 두고 뭘 산 적이 없는데 국내에서는 못구하는 재료가 있어 개통을 하긴 해야한다. 인증 다시 하고 주소랑 통관 번호 넣고 첫 주문을 넣어 봤다. 결제를 어찌 하나 좀 걱정했는데 네이버페이랑 카카오페이가 되어 어렵지 않게 주문했다.

카일 LP 청축 스위치 100개랑 그에 맞을 거 같은 키캡 110개 주문했는데 월말이나 되어야 올 예정이다. 주소를 한글로 넣어 놨는데 오기는 과연 올런지 모르겠다. 이게 오면 재료를 다양하게 구할 수 있을 거 같다. 쿠팡에서도 거치대랑 키캡 예쁜거 주문해 놨다. 돈도 못 벌면서 쓰기는 잘도 쓴다.

시간 있을 때 지지대를 미리 만들어 놓기로 하자. 수평 각도는 4도에서 2도로 낮추어 앞쪽 중앙을 낮게 해서 팜레스트없이 쓸 수 있도록 한다. 수직 각도는 8도에서 10도로 높여 배선 공간을 더 많이 확보한다. 다른 키보드를 재보니 8도는 넘고 내가 셋팅해서 쓰는 각도는 10도도 넘는다.

재보니 다 10도인데 4후는 뒤에 신발도 신고 놨으니 10도가 넘어도 될거 같다. 이러니 뒷면을 미리 들어 두고 앞면을 낮추는게 유리하다. 철판 크기가 바뀌었으니 계산을 다시 해야 한다. 엑셀식을 만들어 놨더니 무척 빠르고 정확하다.

중앙 부분은 낮아지고 양쪽 모서리가 높아진다. 이 높이대로 지지대를 만들되 기울어진 아래쪽 방향으로 더 깍아야 한다. 15미리 이동시 다음 높이를 더한다. 지지대가 15T이니 반대쪽이 이만큼 더 높거나 낮아야 한다.

 

수직 : =15*TAN(RADIANS(10)) = 2.64

수평 : =15*TAN(RADIANS(2)) = 0.52

 

하단 지지대의 바깥은 11.6이되 15미리 안쪽은 2.64미리 더 높은 14.2미리여야 한다. 수평쪽은 변화가 미미해서 칼로 조금만 다듬으면 된다. 전에 쓰던 나무 토막을 잘라 기둥 3개를 만들었다.

경사면을 다듬는 작업이 어렵고 시간이 많이 걸린다. 위쪽 중앙 지지대는 새 나무를 잘라 만들었는데 결방향으로 하면 자꾸 쪼개져 반대 방향으로 했더니 칼질이 더럽게 힘들었다. 나무가공도 만만한게 아니다. 4개의 기둥을 만든 후 아크릴판을 올려 봤더니 딱 맞다. 역시 수학은 위대하다.

조립하고 보니 하판이 알루미늄이라 이대로면 합선이 날게 뻔하다. 다시 해체하여 플라스틱 도마를 오려 중간에 끼웠다. 도체는 하판으로는 부적합하니 다음부터는 아크릴을 써야겠다.

하단은 뒤쪽 나사가 툭 튀어 나와 있는데 좀 더 넣어 보고 안되면 양면 테이프를 쓸까도 생각중이다. 지지대는 얼마든지 만들어 교체할 수 있어 좋다. 철판 나오면 납땜부터 천천히 할건데 또 한 이틀은 홀라당 날라갈거다. 주말에는 자바 교정도 봐야 해서 다음주 초에 해야겠다.

3 22 - 5호 조립

주말에 자바 원고 교정도 했고 3D 프린터 구입해서 갖고 노느라 키보드 조립을 못했다. 혹시 키캡을 프린터로 뽑는게 잘 되면 키피치를 17*17로 다시 만들까 했는데 아직 출력 품질을 확보하지 못해 어려운 거 같다. 좀 더 학습 및 연구해 보기로 하고 5호는 그냥 전통적인 방법으로 만들자. 어차피 계속 만들어야 한다. 앞으로도 납땜은 피할 수 없을 거 같아 공구를 더 장만했다.

 

3000원짜리 탈피기는 일일이 팔로 땡겨 줘야 하는 불편함이 있어 집게 모양의 편리한 탈피기를 만원 정도 주고 하나 더 구매했다. 이건 찝은 후에 손잡이를 오므리면 탈피되고 선 빼면 껍데기도 자동으로 날라가 편리하다. 다만 이걸로는 0.3미리까지만 가능하고 그보다 얇은 0.2미리선은 안된다. 저번건 손으로 하나 비틀어 탈피 가능했지만 이건 자동으로 그것도 안된다. 당분간 두 개를 다 써야겠다.

막상 써 보니 다른 문제도 있는데 손잡이를 완전히 조였다 완전히 놓아야 동작한다. 중간에 놓아 버리면 선이 빠지지도 않고 뭉게져 버린다. 또 적당한 공간이 확보되어야 쓸 수 있다는 문제도 있다. 모든게 다 좋을 수는 없다. 다음은 납땜 선을 잡아 주는 집게다.

 

최대 4가닥까지 잡을 수 있는데 고정할 곳이 마땅치 않다. 과연 쓸모가 있을지, 실용적일지는 써 봐야 알 거 같은데 어떻게든 활용할 데는 있을 거 같다. 철판은 저번주 금요일 찾아 왔다. 석팀장님이 직원들 코로나 걸린 상황에서도 빨리 만들어 줬는데 딴데 정신 팔려서 이제서야 조립을 한다.

좌우 대칭이라 똑같다. 하우징을 다 만들어 놨기 때문에 바로 얹으면 된다. 나사를 너무 꽉 조였더니 조금 휜다. 이건 나무를 더 깍아야 한다는 얘기인데 일단은 나사를 살짝 풀어 평평하게 해 두었다. 우하단, 좌하단은 높이가 낮아 나사를 채울 수 없다. 다음에 나무 동가리라도 하나 끼워야겠다.

 

이번에는 기판 먼저 납땜하고 구멍사이로 선 빼서 스위치에 바로 직결하기로 했다. 옷핀으로 선을 동그랗게 말지 않고 스위치에 바로 붙여도 괜찮을지 직결 테스트를 해 봤다. 집게로 하나는 스위치, 하나는 선을 잡도록 하되 자바라가 탄성이 조금 있어 원하는 위치에 정확하게 갖다 놓기 쉽지 않았다. 위치만 맞추면 우인두 좌실납 자세로 납땜은 가능하다.

직결 테스트를 해 보니 일단 힘껏 당겨도 뜯어지지 않을만큼의 강도는 확보된다. 돌돌 말은 것보다는 약하겠지만 이 정도 강도면 그냥 연결해도 될 거 같다. 실전 테스트까지 해 봤지만 나중에 다른 이유로 결국 안되는 걸로 밝혀졌다.

이번에는 케이블을 다양하게 써 보기로 했다. 먼저 오른쪽에서 멀리 왼쪽까지 갈 선을 한다발로 묶었다. 외우기 쉽게 빨주노초파남 6가닥으로 매크로 선을 빼 두었다. 방향키는 리본 케이블을 사용했다. 기판에 납땝할 때는 집게보다 테이핑이 역시 편리하다.

 

위쪽은 거리가 짧아 연접선을 썼는데 이건 너무 두꺼워 불편했다. 탈피 및 납땜이 되어 있지만 길이가 짧아 다시 탈피해야 한다. 기판 납땜시는 테이핑을 안해도 잘 버티고 있지만 스위치에 납땜할 때는 연선이 너무 많이 합선 위험이 있다. 예상외로 연선인 것 자체는 별 문제가 되지 않아 쓸만했다. 얇은 연선 정도는 괜찮다.

오른쪽 선을 다 연결해 놓고 철판 얹은 후 구멍 사이로 선 밀어 넣고 스위치를 직결로 땜했다. 겨우 하나 연결하기는 했는데 이건 불가능한 작전이었다. 강도가 문제가 하니라 납이 스며들 곳이 없어 굴러 떨어진다. 핀은 막대 모양이고 선도 막대이니 이 둘을 붙여 놔도 납이 묻을 곳이 없다. 납을 왕창 먹이면 붙어 있지만 그 전에 고정하는게  보통 어려운게 아니다.

집게로 어떻게 해 봤는데 스위치와 선이 만나도록 집어둘 수가 없고 탄력 조정해 가며 겨우 맞춘다 하더라도 한번에 하나만 가능하며 둘을 동시에 맞출 수는 없다. 결국 옷핀으로 돌돌 말아 거는 방식을 다시 도입했다. 이 방법이 좀 원시적인거 같애도 납이 고리 사이로 쏙 들어가 편하기도 하고 강도도 충분하다. 이때 집게가 도움이 되는데 스위치를 공중부양시켜 놓고 선 두 개를 걸면 된다. 이때는 탄력이 오히려 도움이 되었다.

 

이 방법으로 오른쪽부터 연결 작업을 완료했다. 기판의 선 위치를 보고 구멍 찾아 끼워 넣는게 어렵고 철판 위로 나온 선을 길게 할 수 없어 탈피 및 고리 만드는 시간이 걸린다. 그러나 별 말썽이 없는 방법이라 이게 제일 나은 거 같다.

풀배열 기판을 사용하다 보니 선이 전반적으로 오른쪽으로 많이 이동한다. 원래 계획은 바로 위에 구멍으로 선 빼면 될줄 알았는데 구멍 위치가 원하는 것과는 다르다. 반만 해 놓고 테스트해 보니 모든 스위치가 제 위치에 제대로 연결되었다. 그러나 Ctrl키만 누르면 열 댓개의 글자가 와장창 입력되는 이상 증상을 보였다.

왜 그런가 한참 찾아 보니 기판 아래쪽에 있는 용수철과 보강판이 붙으면 합선이 일어나는 것이었다. 이렇게 붙으면 같은 라인의 모든 키가 다 붙은걸로 인식하도록 되어 있는 모양이다. 용수철을 잘라 주니 일단은 해결이 되었다. 이 용수철은 엄청 쎈 녀석이라 니퍼로 잘 잘리지 않는데 억지로 잘랐더니 니퍼 이빨이 나가 버렸다. 역시 2000원짜리 공구의 내구성은 믿을게 못된다.

문제는 해결했지만 다른 의문이 또 생겼다. 상판이랑 용수철이 붙었다고 입력이 된다는 것은 스위치랑 상판이 붙어 있다는 얘기이므로 이것도 잠재적인 문제가 될 것이다. 그래서 모든 스위치를 샅샅이 뒤져 문제를 찾아냈다. 스위치 하나의 점프선이 삐져 놔와 상판에 닿아 있다. 발견 못했으면 계속 다른 문제가 생길 뻔했다. 상판은 스위치와 완전히 절연되야 한다.

 

오른쪽 완성한 후 왼쪽 작업을 시작했다. 이번에는 0.3미리 선만 사용했다. 제일 먼저 사용했던 선이 무난하다. 다만 연접선이 아니라 선 정리가 번거롭다.

기판에 선 다 붙이고 철판 올린 후 구멍마다 선을 빼는데 이 작업도 시간이 좀 걸린다. 선 뺄 때는 철판 분리하고 땜할 때는 다시 고정하기를 계속 반복해야 한다. 한번에 두 줄 정도씩 할 수 있어 4번 정도는 해야 한다.

왼쪽 완성 후 테스트를 해 보니 또 문제가 있었다. 키 하나가 입력되지 않아 살펴 보니 기판쪽의 선이 끊어져 있다. 이건 납땜을 잘못했거나 무리하게 당기다가 끊어졌다기 보다는 탈피할 때 선이 손상된 경우로 추측된다. 대충 다시 땜해 주었다.

다른 한키는 입력이 되다가 말다가 하는데 뜯어 보니 납땜 에러이다. 이건 이후에도 발생할 수 있는 경우인데 납은 핀 위쪽에 동그랗게 붙어 있고 선은 그 아래쪽에 덜렁 덜렁 달려 있다. 이래도 왠만하면 접촉은 되지만 선이 핀 딱 가운데에 떠 있으면 접촉되지 않는다. 아래쪽에도 납을 먹여 다시 납땜해 주었다.

 

여기까지 완성된 모습이다. 모든 스위치가 정상적으로 연결되었음을 확인했다. 이 상태에서는 철판을 다시 위로 들지 못한다. 철판, 기판, 스위치가 통째로 한 묶음이다. 어차피 기록으로 남길거니까 굳이 재사용까지는 고려하지 않기로 한다.

직결로 바로 연결했음에도 선 길이가 길며 배선 덩어리가 꽤 묵직해 기판 사이의 공간이 충분히 확보되어 있어야 한다.

다음은 키캡을 끼운다. 피치가 18미리라 거의 안깍아도 되지만 아슬아슬하게 붙는 부분이 있어 아래쪽과 위쪽은 조금 긁어 줘야 한다.

많이 파는게 아니다 보니 시간과 노력은 그리 많이 들지 않는다. 키캡 전체를 다 칼질해서 붙이는데 한시간 정도밖에 걸리지 않았다. 이 정도면 굳이 3D 프린터 동원하지 않고도 할만하다. 키보드 하나 해체하면 스위치는 4개 부족하고 키캡은 17개 부족하다.

풀배열로 만들려면 키보드 2개를 갈아 넣어야 한다. 흰색 적축 사둔걸 해체해서 부족한 키캡을 채워 넣었다. 다음은 몇가지 마무리를 한다.

 

하판 전면의 나사가 너무 튀어 나와 있어 5미리 길이로 입구를 넓혀 주었다. 쏙 들어가는 정도는 아니지만 조금 낮아지는 효과가 있다. 하단 모서리는 붕 떠 있는데 나무 조각 하나씩 깍아 받쳐 주었다. 나사를 긴걸 쓸 수 없어 짧은걸로 대충 자리만 잡아 주었다.

높이가 낮아 팜레스트 없이도 쓸 수는 있는데 철판 전면이 날카로워 손바닥이 아프다. 강철이라 갈리지 않을 줄 알았는데 줄로 갈아 보니 갈리기는 한다. 그래 봤자 둥글게 만들기는 어렵고 줄로 갈린 표면도 거칠다. 다음에 테이프나 고무 소재로 막아 봐야겠다.

대충 마무리까지 해서 5호를 완성했다. 좌우로 기판 튀어 나와 있는게 꼴불견이고 크기도 넓어졌지만 쿼티로도 쓸 수 있어 다른 키보드가 없어도 된다는 장점이 있다. 소젯으로 쓰다가 급하면 후킹 끄고 쿼티로도 쓸 수 있다.

어젝 저녁 6시에 시작해서 새벽 2시까지 하고 7시간 자고 일어나 9시부터 다시 작업하여 뒷정리까지 대략 25시간이 걸렸다. 잘 때 외에는 계속 작업했으니 순수 작업 시간만 치면 17시간 정도 걸린 셈이나 일일 8시간 근무로 따지만 이틀 걸렸다고 볼 수 있으며 인건비는 작게 잡아도 40만원 정도 든 셈이다.

하우징 준비한 시간도 쳐야 한다. 이번에 작업해 보니 속도의 관건은 점프선이다. 납땜하기 딱 좋은 점프선만 찾아도 시간을 상당히 아낄 수 있다. 0.3미리 연접선에 앞부분 탈피만 되어 있어도 12시간 내로 하나 뚝딱 만들 수 있을 거 같다. 국내에서는 이런 선 구하기 어렵고 알리 좀 뒤져 봐야겠다. => 두시간동안 뒤졌는데 못찾겠음. 28awg(0.3) 연접선조차도 구하기 어렵다.

------------------------------

3 25-영문, 기호 재배치

5호를 완성한 후 연습도 조금 해 보고 기본 테스트는 해 봤다. 앞으로도 계속 사용하면서 정리하겠지만 일단 평가를 해 보자. 기울기는 수평, 수직 대신에 직관적인 용어로 바꾸어 어디 부분인지 알아 보기 쉽게 했다. 내가 정의하는 거지만 용어를 정하기도 참 어렵다.

 

피치 : 18*18이 원하던 크기는 아니지만 적응하기는 쉽고 칼질을 덜 해도 되니 만들기 쉽다. 4호와 수직 거리 1미리 차이나는건 실감하기 어렵다. 키캡을 더 줄일 수 있으면 다음 버전은 17*17로 만들 것이다. 펑션행을 빼면 19*19로 부품 조립식으로 만들어 배포해도 될 거 같다.

▶ 문자 기울기 8 : 4호와 같다. 팔을 벌리면 부족하지만 몸에 딱 붙이면 편안하다. 장시간 타이핑시는 이 각도가 무난하다.

▶ 좌우 기울기 2 : 거의 각도를 주지 않았지만 그래도 평평한 것보다는 낫다는 느낌이다. 하단 가운데가 낮아지는 효과는 있다. 차후 지지대를 3D 프린터로 인쇄하면 10도까지 올려도 봐야겠다.

▶ 전체 기울기 10 : 8도보다는 더 편하고 뒤쪽에 신발을 안 신겨도 되니 좋다. 배선 공간도 충분히 확보할 수 있어 제작이 용이하다.

▶ 엄지 6미리 : 딱 적당하다. 수평은 더 조정할 필요 없고 피치를 줄이면 수직은 약간 더 올리는 게 좋겠다. Enter J기준 (+6, +30)이 이상적이되 지금은 키캡 높이로 인해 수직이 +36이다.

▶ 새끼 6미리 : 많이 내렸다. 4호의 5미리보다 조금 더 내려 본 건데 팔을 몸에 딱 붗이면 자연스럽지만 팔을 벌리면 새끼쪽이 올라가 과하다. 한글 타이핑중에 ㅁ을 쳤는데 ㅂ이 입력되는 경우가 종종 있다. 너무 내리지 말고 4미리나 3미리로 약간만 내리는게 좋다.

▶ 좌우동형 : 미사용 구멍이 있어 미관상 좋지 않지만 딱히 사용에 걸리지는 않는다. esc가 중앙이 아닌건 조금 아쉽다. 예비 구멍을 쓸 데는 없지만 좌우폭이 같아서 좋다. 장애인용 제작은 아직 먼 얘기인데 너무 성급히 뚫어 놓은 거 같다. 일단 막아 놓고 폭만 같게 만들까 싶다.

▶ 스위치 직결 : 제작 시간을 조금 줄였고 작업도 그리 어렵지 않았다. 다만 점프선을 쓸만한 걸로 잘 구해야 한다.

▶ 풀배열 : 펑션키를 따로 둬도 아직은 딱히 큰 실용성을 못 느끼겠다. 기판이 좌우로 튀어 나와 보기 좋지 않고 배선도 어렵다. 하나 만들어 봤으니 앞으로 펑션행은 가급적 없이 만드는 걸로 해야겠다. 4호가 딱 모양이 예쁘고 실용적이다. 4호를 뜯어 배선을 수술할까 고민중이다.

LP 스위치와 키캡 : 키감도 좋고 스트록도 적당하다. 다만 키캡이 조금만 더 작았으면 좋겠는데 이건 3D 프린터로 출력해서 써 보기로 한다.

▶ 제작 방식 : 아직도 기판 납땜인데 다음 버전은 아두이노 공부해서 만들 계획이다. 작업 시간을 줄일 수 있고 모양도 더 예쁘게 나올거 같은데 일단 시도해 볼 필요가 있다.

 

조립이나 제작은 무난히 잘 되어 실용적으로 쓸만하다. 다음 버전은 새끼만 살짝 내리는 정도만 변형을 주면 될 듯 하다. 제작보다도 이제 사용성을 점검해 보고 단점을 찾아 개선해야 한다. 사용하면서 느낀점 및 개선 방식을 하나씩 정리및 적용했다.

 

▶ 쿼티 호환 키맵핑 : 펑션, 숫자를 가급적 쿼티와 일치시켜 다른 키보드없이 소젯으로 모든 걸 할 수 있도록 했고 그게 5호의 가장 큰 목적이다. 그러나 막상 후킹 꺼 놓고 쳐 보면 쿼티 배열임에도 소젯으로는 어색해 오타작렬이다. , ㅜ의 위치가 무쟈게 헷갈리며 BS도 자꾸 Shift+Space를 누르고 있다. 숫자키는 물론 보고치니 문제없이 입력할 수 있고 펑션키도 그럴 것이다. 기호는 어차피 화면의 자판을 보고 쳐야 한다.

억지로 쓸 수는 있지만 속도가 안나오고 헷갈리기만 한다. 가장 큰 이유는 배열보다는 키의 위치와 인덴트다. 손이 아직 쿼티 배열을 기억하고 있지만 그건 위치까지 다 맞을 때의 얘기이고 조금만 달라져도 버벅거린다. 똑같은 배열이라도 오쏘와 스태그를 왔다 갔다 하며 둘 다 익숙해지긴 어렵고 자주 바꿔 치는 건 거의 불가능하다.

웃긴게 쿼티 키보드로 바꿔 치면 약간의 시간이 걸리지만 금방 익숙하게 쳐진다. 그러나 이러다가 다시 소젯으로 돌아온다고 해서 소젯에서 쿼티 배열을 쓸 수 있는건 아니다. 소젯에서 쿼티 배열을 치려면 이것도 연습이 따로 필요하다. 또한 소젯 키보드로 소젯 배열로 바꿔도 한동안은 쿼티 배열이랑 헷갈린다. 결론적으로 두 방식의 키보드에 모두 익숙해도 바꿔 치면 헷갈릴 수밖에 없다. 디버깅할 때는 어쩔 수 없이 쿼티 키보드를 쓰거나 소젯에서의 쿼티에 익숙해져야 한다. 

그렇다고 해서 맵핑을 쿼티 호환으로 바꾼게 의미가 없지는 않다. 일단 아래한글을 쓸 수 있고 느리더라도 소젯 디버깅도 가능은 하다. 두 키보드를 번갈아 쓰면 몸이 혼란스러워 하므로 가급적 소젯만 써야 한다. 불가피하게 쿼티를 써야 한다면 독수리 타법으로 치는 수밖에 없다. 배열을 바꾸는 것도 어렵지만 다시 돌아가는 것도 어렵고 둘을 번갈아 가며 쓰는 건 거의 불가능하다. 앞으로는 불가피한 경우만 빼고 무조건 소젯만 쓰기로 한다.

▶ 숫자행의 펑션키 여부를 토글하는 단축키를 fn+d, fn+f로 해 놨는데 굳이 문자 영역에 있을 필요가 없다. 숫자행이 없으면 쓸일이 없고 숫자행의 용도를 결정하는 옵션이니 숫자행에 두는 것이 바람직하다. , 알파벳은 쿼티 기준이어서 소젯에서는 혼란스러우니 숫자로 옮기는게 합리적이다. fn+1은 숫자, fn+2는 펑션으로 정의했다.

K_1 ~ K_12 IsKeyDown(K_FN)보다 먼저 점검하기 때문에 두 단축키는 더 앞쪽에서 미리 점검해야 한다. 후킹중에도 잘 바뀐다. 이 코드 수정을 소젯으로 했는데 쿼티 배열을 떠올리며 하느라 쉽지 않았다.

▶ 숫자행에서 Shift와 함께 기호를 입력한 후 shift once가 풀리지 않는 버그가 발견되었다. 문자를 하나라도 입력했으면 즉시 풀어야 한다. 이 부분의 흐름을 정비할 필요가 있다.

▶ 카테고리라는 용어가 영 별로라 설명하기도 어렵고 직관적이지도 않다. 키그룹으로 이름을 바꾸고 관련 상수도 KG_로 수정했다. C_BASIC은 기본이라는 의미인데 그보다는 문자라는 의미로 KG_CHAR로 변경했다. 그외 주석과 멤버명, 툴팁의 설명까지 모두 찾아 수정했다. 이름을 중간에 바꾸는 것은 참 번거로운 일이다. 명칭만 바꾼거라 실행과는 상관이 없다.

Once 옵션이 둘 다 선택되어 있지 않다면 마우스는 굳이 해킹할 필요 없다. 후킹을 시작할 때 마우스 후킹 여부를 선택한다.

 

if (Opt.shiftOnce || Opt.ctrlOnce) {

     hMouseHookLL = SetWindowsHookEx(WH_MOUSE_LL, OnMouseHookLL, g_hInst, NULL);

     MessageBeep(0);

} else {

     hMouseHookLL = NULL;

}

 

이러면 잘 동작하지만 후킹중에 옵션을 변경할 때 굳이 마우스 후킹을 추가하는 조치까지는 하지 않았다. 옵션 변경 후 후킹을 재시작하는 것은 수동으로 직접 해야 한다. 마우스 훅 프로시저도 일단은 설치되었더라도 once옵션이 꺼져 있으면 큐에 기록하지 않도록 했다.

▶ 툴바에 쿼티 버튼이 나타나지 않는다. 아마 숫자행 그룹을 추가하면서 갯수를 늘리지 않은 모양이다. 마지막키 보이기 옵션과 Shift 1회 옵션도 추가했다. 둘 다 실사용과 테스트에 아직 필요하다.

▶ 영문 타이핑을 계속 연습해도 잘 늘지 않고 무척이나 헷갈린다. 더 연습하면 되긴 하겠지만 쿼티와 번갈아 칠 때 좀체 익숙해지기 어렵다. 아예 배치가 완전히 다른 키는 상관없는데 원래 쿼티에서 한칸만 다른 키가 문제다. c, s, i가 그런데 둘 다 손가락이 기억하는 예전 위치를 자꾸 치고 있다. 후킹 끄고 소젯으로 칠 때 Ctrl+C, Ctrl+S도 바로 치기 어렵다.

이 점은 나만 그런게 아니라 새로 배우는 모든 사람이 다 그럴 것이다. 그렇다면 적당히 타협을 해 보는 건 어떨까?  s자리보다는 그 옆의 r자리가 더 좋고 c자리나 그 옆의 m자리나 별반 다를게 없다. i h도 인접이라 피로도 차이가 거의 없다. 다만 이 셋을 바꾸면 손가락 비율이나 연타율 등이 영향을 받는다. 과연 얼마나 점수차가 발생하는지 오랜만에 랭킹을 돌려 봤다.

 

현재 배열 : tenorasdiculhmwfgvkypbjxqz 감점 22

csi 교체 : tenosardhmulicwfgvkypbjxqz 감점 44

 

수평으로만 바꾼 것이어서 행비율, 좌우 비율, 손연타는 변화가 없다. 다른 부분은 얼마나 변화가 있는지 점검해 보자.

 

항목

현재 배열

csi 교체

차이

비고

부담도

15.4124

15.4296

8점 더 감점

점수차만큼 부담도가 늘어나는건 아님

손가락 분담율

18:21:25:35

43:28:21:6

18:21:26:33

41:30:21:6

1.5점 더 감점

오른손 집게, 중지 비율만 약간 달라짐. 이것도 크게 불편한 건 아니다.

손가락연타

268

370

10점 더 감점

he, sw 등에서 연타가 발생한 듯 하다.

10대연철

없음

 

2점 감점

eh연철에 걸린다. the를 입력할 때 좀 걸리적거린다.

 

부담도는 체감할만큼 중요한 기준은 아니다. 그보다는 쿼티와의 호환성이 더 중요하다. 그러나 연철은 확실히 문제가 되는데 eh연철은 반드시 피해야 한다. 연철 순위가 er, th 다음의 3위이다. 이를 회피하기 위해 ih를 그대로 두는 배열과 fih로 셋을 회전하는 배열을 점검해 봤다.

 

cs 교체 : tenosardimulhcwfgvkypbjxqz 감점 27

cs 교체 fih : tenosardfmulicwhgvkypbjxqz 감점 77

 

항목

cs 교체

cs 교체 fih

비고

부담도

15.4214(-20)

15.4796(-50)

점수차만큼 부담도가 늘어나는건 아님

손가락 분담율

18:21:26:33

43:28:21:6

18:21:26:33

35:30:28:6

fih가 오른손 약지 비율이 너무 높아 21점 감점

손가락연타

259

285

연타율은 둘 다 준수하다.

10대연철

없음

없음

 

 

cs만 교체는 감점이 낮지만 i가 여전히 헷갈리게 생겼다. fih는 일단 i위치는 좋지만 부담도에서 받은 감점은 무시하더라도 오른손 손가락 비율이 좋지 않다. 더구나 3행의 마침표까지 고려하면 약지의 분담율이 더 높아진다.

쿼티와 한자리 차이나는 i를 원래 자리에 갖다 놓으면서도 분담율이 적당하고 연철이 없는 배열이어야 한다. 이번에는 f를 그 자리에 두고 왼쪽의 l을 포함하여 돌려 보자. h l자리로 가고 li가 왼손에 온다.

 

hli : tenosardlmuhicwfgvkypbjxqz 감점 49

 

감점이 높지만 부담도에서 31점이고 손연타율이 37%로 조금 높아졌다. 손가락 연타에 비해서는 치명적이지 않다. 손가락 비율은 18:20:28:32 -39:31:22:6으로 괜찮다. 같은 손이지만 wh가 붙어 있다는 것도 괜찮고 th가 인접한 것도 오히려 리듬감이 있어 나쁘지 않다. 

 

부담도 평균 = 15.4421 감점 => 31.0326

좌우 분담률 : 51.70%:48.30% 감점 => 0.00

행분담률 : 28.5 : 56.5 : 15.0

손가락 연타 : 293 8.72% 감점 => 5.17

손 연타 : 1268 37.75% 감점 => 7.50

10대 연철 : 0.00점 감점

총 감점 = 49.5452

 

통계 데이터보다 직관에 의존해 보면 이 배열이 썩 괜찮아 보인다. 이 배열을 만든 근거와 과정은 다음과 같다. 통계가 비록 정밀하지만 쿼티와의 호환성이 채점에 포함되어 있지 않은데 이 부분을 수동으로 맞춘 것이다.

 

dist 5 최고득점 배열 기반

s, c, i 등 쿼티와 딱 한칸만 다른 거 주변 교체하여 일치시킴

연철 방지, 손가락 분담율 감점 최소화

 

sr교체, cm교체, lih hli로 교환하였다. 쿼티랑 같은 자리에 있는 문자는 기존의 wp csi를 추가하여 다섯 글자이다. 수평으로 한칸만 바뀌어 헷갈리는 글자가 없고 대각선으로 이동한 글자는 dotv 네글자이다. 대각선 이동은 별로 헷갈리지 않는다. 나머지는 다 멀찍이 떨어져 있어 다시 익혀야 한다.

이렇게 수정해 놓고 영문 타이핑을 해 보니 이전보다 더 편해졌다. th가 인접해 있어 the, that 등을 입력하기 좋고 wh가 붙어 있는 것도 좋다. yes, as, so 등을 입력할 때 s자리가 헷갈리지 않고 my, me 등도 편하다. 다 좋아졌는데 o a가 자꾸 헷갈린다. 특히 a가 빈도에 비해 o보다 높은데 가장자리로 밀려난 느낌이다. a 6.09, o 5.64니 차이가 좀 있다.

이 둘을 바꿔 보자. 오른손 분담률은 39.5 : 32.0 : 21.7 : 6.7로 중지의 부담이 약간 더 높아졌다. 빈도에 따라 조정한 것이어서 부담도는 조금 내려갔고 좌우, 행은 변화없다. 손가락 연타율이 조금 더 올라 갔는데 10대 연철은 없지만 전치사 of가 연타여서 그런 듯 하다. of가 단어 빈도로 무려 5위이고 전치사 for도 영향을 받는 부분이 아쉽지만 관사 a 4위여서 교환할만 하다.

 

부담도 평균 = 15.4399 감점 => 29.9696

좌우 분담률 : 51.70%:48.30% 감점 => 0.00

행분담률 : 28.5 : 56.5 : 15.0

손가락 연타 : 311 9.26% 감점 => 6.78

손 연타 : 1268 37.75% 감점 => 7.50

10대 연철 : 0.00점 감점

총 감점 = 52.0842

 

이렇게 교환해 놓고 쳐 보니 a자리가 편하다는 느낌은 확실히 있다. 그러나 of가 연타여서 불편하고 for도 마찬가지이다. a가 원래 왼쪽 끝에 있었으니 아예 반대쪽인 오른쪽 끝에 두는 것도 오히려 의미가 있다. 이 변화는 얻는만큼 잃는 것도 확실하니 채택하지 않기로 한다. csi만 쿼티에 일치시킨 배열을 채택하고 키캡도 바꿔 두었다.

약간만 조정했어도 영타가 많이 빨라진 느낌이 든다. yesterday top of the world로 연습을 하고 있는데 전에는 50~60타가 고작이었지만 지금은 84타까지 나온다. 조금 더 연습하면 100타까지는 무난히 나올 거 같다.

 ▶전에 게시판에 글을 쓰다 대문자 고정이 필요해 caps를 누르느라 edit키와 함께 $를 눌렀는데 그 옆에 키를 잘못 누른 적이 있다. edit모드에서 2 2열은 F5인데 새로고침을 하다 보니 쓰던 게시물이 다 날라가 버리는 사고가 발생했다. 딴 링크를 타고 갔으면 뒤로 돌아올 수 있지만 새로고침을 해 버리면 복구할 방법이 없다.

이 사고는 중복키가 너무 많아 발생한 것이다. 펑션키의 경우 별도키가 있고 숫자행을 쓸 수도 있고 edit모드에도 있으니 세벌이나 있는 셈이다. 이렇게 되어 있는 이유는 레이아웃 구성이 여러 벌이고 보이는 키그룹에 따라 입력할 키가 달라지기 때문이다. 아직 개발중이다 보니 정비를 제대로 하지 못한 사정도 있다.

그런데 이런 중복이 여러가지 문제를 일으킨다. 일단 보기 싫고 복잡해 보이며 실수로 인한 오동작을 유발한다. 숫자나 기호, 커서 이동 정도는 별 문제 없지만 펑션이나 매크로 등은 때로는 심각한 문제를 일으킬 수도 있다. 그렅다고 무조건 숨겨 버리는 것도 좋은 방법은 아니다. 그래서 중복인 경우 해당 키를 아예 없애 버리되 이걸 원치 않는 경우도 있을 거 같아 옵션을 도입하기로 한다.

 

useEditFn : edit모드의 펑션키 항상 사용. true이면 항상 보이고 false이면 필요할 때만 보인다. 펑션행이 있거나 숫자행을 펑션으로 쓰고 있으면 보일 필요 없다.

useEditMacro : edit 모드의 매크로키 항상 사용. false이면 매크로 키그룹이 없을 때만 보인다.

useNumSymbol : num 모드의 기호 항상 사용. false이고 숫자행이 없을 때 숫자와 소수점, 공백만 빼고 모두 숨긴다.

 

풀배열에서 이 옵션을 모두 꺼 두면 중복이 많이 제거된다. 디폴트는 false이며 가급적 숨긴다. num 모드의 숫자와 edit 모드의 커서 이동키는 최소한 위험하지는 않으므로 이 옵션과 상관없이 항상 보이도록 한다.

옵션이 자꾸 늘어나니 대화상자의 페이지를 하나 더 만들었다. 차맷을 별도 페이지로 분리하는 작업을 했는데 그랬더니 차맷 목록이 초기화되지 않아 사용 차맷이 깨지는 문제가 발생했다. 프로퍼티 시트는 페이지를 열지 않으면 WM_INITDIALOG 메시지가 오지 않는다. 차후 일반 대화상자로 바꿔야겠다.

이 옵션과 키그룹의 보이기 상태에 따라 OnPaint에서 캡션 표시와 ProcessKey에서 입력을 선택한다. 보이지 않는 키는 캡션을 출력하지 않고 입력도 하지 않도록 했다. 중복이 제거되고 실수를 방지하는 효과가 확실히 있다. 물론 항상 보기 옵션을 선택하면 언제나 보인다. 레이아웃 구성에 따라 적당한 옵션을 사용하면 된다.

이 코드를 적용하는 과정이 나름 험난했다. 소젯 키보드로 소젯을 수정할려니 애로가 좀 있는데 그렇다고 쿼티 키보드로 돌아가기는 손이 혼란스러워해서 싫다. 소젯에 점점 더 익숙해져 간다는 증거이니 어찌보면 바람직한 현상이다. 소젯으로 코딩을 하는 속도는 굉장히 느리지만 다행히 눈에 띄게 속도가 빨라지고 있어 실사용이 충분히 가능함을 확인하였다는데 의의가 있다.

▶ 위 작업을 하면서 num 모드의 +가 세미콜론 기호 영역을 침범하는 통에 골치 아픈 문제가 생겼다. - p를 침범하지만 알파벳은 레이어가 다르니 문제가 되지 안으며 그냥 숨기면 된다. 그러나 +는 숨기는게 아니라 원래 자리에 있는 ;을 살려 줘야 하는 번거로움이 있다. , num모드에서는 ; :을 입력할 방법이 없다. 다른 기호는 다 가능한데 이것만 안되어 불편하다. +를 숨길 때 이것만 하드코딩해야 한다.

 

if (IsShowNumSymbol(kidx) == false) {

     // 세미콜론 자리는 숨길 때 비우는게 아니라 문자 영역의 기호를 표시한다.

     if (kidx == K_SEMI) {

          lstrcpy(Caption, tShift ? ":":";");

     } else {

          lstrcpy(Caption, "");

     }

 

뿐만 아니라 ProcessNumber에서도 이 조건에 따라 입력할 문자를 결정해야 한다. 한 키에 레이어에 따른 문자를 겹치다 보니 코드가 골 때리고 이후 관리하기도 번거롭다. 그래서 Num모드의 배치를 바꾸어 기호영역을 침범하지 않도록 했다. 1차로 다음과 같이 배치했다.

B자리가 보이진 않지만 sp이다. sp., 023에 의해 가려졌으니 중복시켜둔 것이고 +-~는 숫자와 함께 많이 쓰이니 근처에 두고 숨기지도 않는다. 숫자 입력만으로 본다면 이것도 괜찮은데 +-가 집게 안쪽열이라 최소 배열일 때 자리가 안좋다. + 2행이라 그래도 괜찮은데 -는 최악이다. + -가 찢어지더라도 ~ -의 자리를 바꾸기로 한다.

이 배치도 그리 썩 마음에 드는건 아니지만 숫자행이 있으면 보조적인 입력 방법이므로 딱히 나쁘지는 않은 거 같다. 일단 이 배열을 채용해 보기로 하자.

Edit 키를 Caps에 맵핑해 두었더니 후킹전에 이 키를 눌러 놓아 기판이 대문자 모드가 켜진 채로 시작하기도 한다. 이 경우 영문 대소문자가 반대가 되며 후킹을 풀고 기판의 Caps를 끄고 재기동해야 하는 불편이 있다. 이를 방지하려면 시작할 때 기판의 Caps와 소젯의 capLock 변수를 동기화해야한다.

연습용은 고유의 대소문자 모드를 변수로 관리하며 기판의 상태에 영향을 받지 않는다. Caps키를 누르면 기판의 대소문자 상태가 실제로 바뀌기도 하지만 연습 프로그램의 동작에는 영향을 미치지 않는다. 그러나 후킹시에는 Shift키를 먼저 보내는가 아닌가로만 대소문자를 결정하므로 기판의 영향을 받는다. 후킹 시작시 다음 중 하나의 처리가 필요하다.

 

1. 기판의 현재 상태에 맞춤. 기판의 Caps가 켜져 있으면 capLock true로 초기화한다. 이 경우 소젯은 Shift와 함께 대문자를 입력하므로 기판 자체는 소문자 상태로 바꿔 두어야 한다.

2. 소젯에 맞춤. capLock의 상태를 그대로 사용하므로 기판만 강제로 소문자로 바꿔 두면 된다. 소젯은 항상 기판이 소문자라고 생각하므로 capLock에 따라 기판의 Caps 상태를 맞추는 것이 아님을 주의한다.

3. 무조건 소문자 모드로 시작한다. capLock false로 바꾸고 기판을 소문자로 설정해 둔다. 일관되지만 너무 단순하다.

 

이걸 옵션으로 만들어 두기는 번잡스럽고 하나를 선택해야 한다. 후킹 해제시에 사용자가 쓰던 상태를 반영하기 위해 1번을 채택하되 이것도 재시작하면 항상 소문자로 시작하는 건 마찬가지이다. 대소문자 입력 모드를 유지하려면 세션간 capLock을 저장해야 하는데 굳이 이럴 필요까지나 있나 싶다.

CapsLock이 소젯의 동작에 영향을 주는 것과 마찬가지로 NumLock도 마찬가지이다. 매크로에 연결된 넘패드의 키는 NumLock이 켜져 있으면 VK_NUMPAD이지만 꺼져 있으면 VK_LEFT 등이다. 현재 키맵에 넘패드의 가상키로 연결되어 있는데 NumLock이 꺼지면 인식하지 않는다.

그러나 후킹시작