Warning: long.

I'm new to PKL, and while I decided to go with a different keyboard variant than Colemak, PKL is still the way to go for using your layout on others' [Windows] computers. However, I have found the documentation sparse, and since I'm pretty new to AHK and programming in general, I've had trouble getting to do what I want it to.

I have a lot of questions specific to creating a key layout from scratch, and creating my own extend bindings. I'll be remapping all of the 30 base keys plus some punctuation and LAlt to backspace, and then creating a custom extend layer for mapping symbols (@$%&[]{}<> and such) onto more ergonomic home-row positions. (I'm using TouchCursor for text editing shortcuts and such).

I will be assuming a layout with scancodes like so (ANSI layout, I believe):

---   ---------------   ---------------   ---------------   -----------
| 01| | 3B| 3C| 3D| 3E| | 3F| 40| 41| 42| | 43| 44| 57| 58| |+37|+46|+45|
---   ---------------   ---------------   ---------------   -----------

---------------------------------------------------------   -----------   ---------------
| 29| 02| 03| 04| 05| 06| 07| 08| 09| 0A| 0B| 0C| 0D|   0E| |*52|*47|*49| |+45|+35|+37| 4A|
|---------------------------------------------------------| |-----------| |---------------|
|   0F| 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 2B| 1A| 1B| |*53|*4F|*51| | 47| 48| 49|   |
|---------------------------------------------------------|  -----------  |-----------| 4E|
|    3A| 1E| 1F| 20| 21| 22| 23| 24| 25| 26| 27| 28|    1C|               | 4B| 4C| 4D|   |
|---------------------------------------------------------|      ---      |---------------|
| 56|  2A| 2C| 2D| 2E| 2F| 30| 31| 32| 33| 34| 35|      36|     |*4C|     | 4F| 50| 51|   |
|---------------------------------------------------------|  -----------  |-----------|-1C|
|   1D|-5B|   38|                       39|-38|-5C|-5D|-1D| |*4B|*50|*4D| |     52| 53|   |
---------------------------------------------------------   -----------   ---------------


1) What exactly are virtual key (VK) codes? What happens if the VK code does not match the normal symbols for the key it typically represents?

For example, this line from the layout.ini file

;scan = VK      CapStat    0Norm     1Sh    2Ctrl     6AGr        7AGrSh    Caps    CapsSh
...
SC02f = V       5             v           V     --      œ         Œ             ; QWERTY vV

corresponds to the "V" key in the normal Colemak layout. But on my layout, I have punctuation on this key, as shown below. (I don't need the deadkeys or AltGR).

;scan = VK       CapStat    0Norm     1Sh    2Ctrl
...
SC02f = ???   0             ,           )     --      ; QWERTY vV

Now, it would make sense to use the VK code for the comma, OEM_COMMA, but I don't have a < on the shifted version, I have a ) instead. Should I still use OEM_COMMA as the VK code?

What about characters that don't have a VK code? for instance, if I wanted the ( in the unshifted state and the , in the shifted state? There is no VK code for the “(, key”. Do I use one of the other nonspecific OEM codes?

If the VK codes are just a way for the system to know which key got pressed, could you just define all the VK codes as would be typical on QWERTY then just change which characters are on them? Would this work?


2) What does CapStat (CapState?) represent? The sample.ini has this bit here:

;     CapsState (like in MS KLC)
;         If CapsState == vk or VirtualKey
;             When you press this key, it sends only the virtual key.
;             It is very useful, if you install your special layout, and you 
;             would like to extend it. (See extend_* layouts)
;         Else If CapsState == modifier
;             You can use this key as a modifier, like Shift, RAlt (== AltGr)
;             See DDvorak or ENTI-key++ layouts
;         Else If CapsState & 1 == 1
;             Shift + Button == CapsLock + Button
;         Else If CapsState & 4 == 4
;             AltGr + Shift + Button == CapsLock + AltGr + Button

which doesn’t really explain anything. Plus, some keys apparently have a CapStat of 5, or 0, etc.


3) How do you set up a virtual layer to use with the extend key? I've looked at DreymaR's layouts, and to be quite honest, I got very confused. It looks like you define scancode mappings in the [extend] section of the pkl.ini file and virtual keys in your layout.ini file? Could someone walk me through it "as if I were 5"? Do the keys have to be virtual keys? What if you want nontraditional pairings like ,% or something like that?


4) I've seen references to a perl script that would take in a MSKLC file and make a layout.ini for you, but I can't seem to find it (and it doesn't come bundled with the PKL download). Does this exist, and does it work for current versions of MSKLC?


Just as a final note, I'm willing to write some more thorough documentation for this if someone can help me understand it all. It seems like there is a great need for such (at least in my opinion).

Thanks!


------------------------------- Edit-------------------------------------------------

I've come to understand most everything but the extend layer. I've pasted my layout.ini file below for those interested. I'd really appreciate it if someone could walk me through creating an extend layer though, as no matter what I try I can't get it it to work.

;
; Keyboard Layout definition for
; Portable Keyboard Layout 
; http://pkl.sourceforge.net
;


[informations]
;-----------------------------------------------------

layoutname           = HIEAM
layoutcode           = HIEAM
localeid             = 00000409
; Letter layout from Sasha Viminitz, found at the comments on the page
; https://mathematicalmulticore.wordpress.com/the-keyboard-layout-project/

copyright            = Public Domain
company              = Steven Tammen 
homepage             = 
version              = 1.0

generated_at         = Sun Dec 20 21:56:00 2015
generated_from       = HIEAM.klc
modified_after_generate = yes


[global]
;-----------------------------------------------------

shiftstates = 0:1:2    ; 0:1:2:6:7 if using 6AGr and 7AGrSh

; PKL is capable of defining images as below, but I chose to
; not have any. You may define the display size as you wish if
; you do create your own.

; img_width = *desired display width*
; img_height = *desired display height*


[fingers]
;-----------------------------------------------------

row1 = 1123445567888
row2 = 1123445567888
row3 = 1123445567888
row4 = 11234455678


[layout]
;-----------------------------------------------------

; 0Norm represents a key's normal, unshifted value.

; 1Sh represents a key's value when pressed concomitantly 
; with Shift

; 2Ctrl represents a key's value when pressed concomitantly 
; with Ctrl

; 6AGr represents a key's value when pressed concomitantly 
; with AltGr

; 7AGrSh represents a key's value when pressed concomitantly 
; with both AltGr AND Shift

; The 6AGr and 7AGrSh columns were omitted since this particular 
; layout is designed for a pure English corpus. Speakers of other
; languages (e.g., Norwegian, Dutch) will want to add AltGr
; values for additional characters like ß, æ, and so forth.

; The scancodes are the machine's representation physical keys on 
; a layout. This particular layout has scancodes corresponding to
; the ANSI arrangement of keys (as opposed to ISO).

; The VK (virtual key) code represents the semantic tag given 
; to a particular key. The 0Norm (unshifted) character is the 
; one that should be used to assign tags. If a VK code does not
; exist for a given key, use an OEM nonspecific code, such as
; OEM_8, or the VK code for the 0Norm of the key it was on for
; QWERTY (e.g., you would use OEM_1 for :, since OEM_1 corresponds
; to the ; key). This lackadaisical attitude is allowable ONLY FOR 
; punctuation keys, since they are seldom involved in shortcuts like 
; Ctrl+a, so "what key" is less important here than the characters on it. 

; Note that the exceptions I made to this regarding punctuation are with 
; the (! and )? keys. Since I actually use the Ctrl+[ and Ctrl+] commands
; on occasion to adjust block indentation I am "pretending" that these 
; keys are the [ and ] keys, respectively, so I can use the commands.

; The CS (=Capstate, shortened to line up with the tabbed data entries)
; represents whether a shifted version of a key is the capital version of 
; said key: if the shifted key is a capital version, add 1; if a shifted 
; AltGr key is a capital version, add 4. Thusly,
;
;  0 means 1Sh is NOT the capital of 0Norm AND
;          7AGrSh is NOT the capital of 6AGr
;
;  1 means 1Sh IS the capital of 0Norm AND
;          7AGrSh is NOT the capital of 6AGr
;
;  4 means 1Sh is NOT the capital of 0Norm AND
;          7AGrSh IS the capital of 6AGr
;
;  5 means 1Sh IS the capital of 0Norm AND
;          7AGrSh IS the capital of 6AGr


;scan = VK    CS    0Norm    1Sh    2Ctrl    6AGr    7AGrSh    QWERTY Key
;-----------------------------------------------------------------------------
SC002 = 1    0    7    --    --            ; QWERTY 1!
SC003 = 2    0    5    --    --            ; QWERTY 2@
SC004 = 3    0    3    --    --            ; QWERTY 3#
SC005 = 4    0    1    --    --            ; QWERTY 4$
SC006 = 5    0    9    --    --            ; QWERTY 5%
SC007 = 6    0    0    --    --            ; QWERTY 6^
SC008 = 7    0    2    --    --            ; QWERTY 7&
SC009 = 8    0    4    --    --            ; QWERTY 8*
SC00a = 9    0    6    --    --            ; QWERTY 9(
SC00b = 0    0    8    --    --            ; QWERTY 0)
SC00c = OEM_MINUS    0    --    --    --        ; QWERTY -_
SC00d = OEM_PLUS    0    --    --    --        ; QWERTY =+
SC010 = B    1    b    B    --            ; QWERTY qQ
SC011 = Y    1    y    Y    --            ; QWERTY wW
SC012 = O    1    o    O    --            ; QWERTY eE
SC013 = U    1    u    U    --            ; QWERTY rR
SC014 = OEM_4    0    (    !    --            ; QWERTY tT
SC015 = K    1    k    K    --            ; QWERTY yY
SC016 = D    1    d    D    --            ; QWERTY uU
SC017 = C    1    c    C    --            ; QWERTY iI
SC018 = L    1    l    L    --            ; QWERTY oO
SC019 = P    1    p    P    --            ; QWERTY pP
SC01a = Q    1    q    Q    --            ; QWERTY [{
SC01b = OEM_6    0    --    --    --            ; QWERTY ]}
CapsLock = OEM_CAPITAL    0    --    --    --        ; CapsLock
SC01e = H    1    h    H    --            ; QWERTY aA
SC01f = I    1    i    I    --            ; QWERTY sS
SC020 = E    1    e    E    --            ; QWERTY dD
SC021 = A    1    a    A    --            ; QWERTY fF
SC022 = OEM_PERIOD    0    .    '    --        ; QWERTY gG
SC023 = M    1    m    M    --            ; QWERTY hH
SC024 = T    1    t    T    --            ; QWERTY jJ
SC025 = S    1    s    S    --            ; QWERTY kK
SC026 = R    1    r    R    --            ; QWERTY lL
SC027 = N    1    n    N    --            ; QWERTY ;:
SC028 = V    1    v    V    --            ; QWERTY '"
SC029 = OEM_3    0    --    --    --            ; QWERTY `~
SC02b = OEM_5    0    --    --    --            ; QWERTY \|
SC02c = X    1    x    X    --            ; QWERTY zZ
SC02d = OEM_7    0    "    *    --            ; QWERTY xX
SC02e = OEM_1    0    :    ;    --            ; QWERTY cC
SC02f = OEM_COMMA    0    ,    -    --        ; QWERTY vV
SC030 = OEM_6    0    )    ?    --            ; QWERTY bB
SC031 = W    1    w    W    --            ; QWERTY nN
SC032 = G    1    g    G    --            ; QWERTY mM
SC033 = F    1    f    F    --            ; QWERTY ,<
SC034 = J    1    j    J    --            ; QWERTY .>
SC035 = Z    1    z    Z    --            ; QWERTY /?
SC039 = SPACE    0    ={space}    ={space}    --    ; QWERTY Space
SC056 = OEM_102    0    -    _    --            ; QWERTY OEM_102
SC053 = DECIMAL    0    .    .    --            ; QWERTY Decimal in Numpad

SC038 = OEM_1    0    ={backspace}    *{LAlt}        ={backspace}    ; Left Alt rebind to backspace
Last edited by Steven Tammen (21-Dec-2015 07:51:03)