英語配列と日本語配列を無視する（レイヤー切り替えで吸収）※検証途中

学生だった頃は、キーボード好きが高じて、頑張ってハッピーハッピーハッキングキーボードを購入して、ハッピーハッピーハッピーになっていたため、ずっと触り続けたいと思っていた。
もちろん英語キーボードだ。
そして、コンピュータ関係の仕事をすれば、夢が叶うと思えた。
社会人だった頃は、派遣社員だったため、派遣先が用意した ~~記号狂いの~~ 日本語キーボードを使うことになった。
しかも、テンキー付きのフルキーボードなので、でかい。
テンキー付きと言うことは、マウスを置く場所がテンキーに占拠されている。
ゆえに、マウスを左手で使うことを余儀なくされ、~~幸せな~~ 幸せな社会人生活を送っていた。
記号の狂いもエスケープキーやShift+数字キーなどは、すべて右手で操作するように気をつけて、まともな記号配列との違いを吸収して難を逃れていた。
東証のシステム開発時に、無断入退室させられたときは、それどころですらないぐらい忙しかった。
派遣社員は辛いよ。

そんななか、家に帰れば、まともなキーボードどころか、私を幸せにしてくれるキーボードが待っている。
今回、そのひとつにErgoDoxEZが加わった。

万が一、日本語キーボード設定のOSを使わなければならなくなったときに備えてのキー配列を考えた。
（個人のUSB機器を持ち込めないので、あり得ないことだが）

# ErgoDoxEZは4行+1行
上段に数字キー
その下3行は、アルファベットが存在する。
最終行の1行は、好きなキーを配置するだろう。

## 上段不要
上段不要は冗談ではない。
そもそも、誰も彼も思っている通り、ErgoDoxEZは外国製品だからか、キーキャップが大きいように思う。
1つの大きさはたかがしれているが、裾が広いようで、キーピッチの距離が遠いように感じる。
そして、キーの高さもそれなりにあるようで、日本人の手に合わないぐらいデカク感じる。
ただ、HHKBとの違いはないようにも思えるのだが・・・(材質や質は置いといて)。

上段とは、通常キーボードで言う数字キーに当たるところだ。
キーに手が届かないため、そんなキーを無理矢理使う必要は無い。

[左右分離キーボードのPやQに小指が届かない問題](http://make-keyboard.tk/blogs/1 "Site Updates")

### キーピッチとは
キーとキーの中央間の距離のこと。

[Weblio辞書：キーピッチ](https://www.weblio.jp/content/%E3%82%AD%E3%83%BC%E3%83%94%E3%83%83%E3%83%81)
[コトバンク：キーピッチ](https://kotobank.jp/word/%E3%82%AD%E3%83%BC%E3%83%94%E3%83%83%E3%83%81-2571)
[個人ページ：キーピッチ](http://www.pasonisan.com/pc-i-o/keyboard-keyword.html "納得パソコン購入術パソ兄さん")

# 言語設定に左右されない数字配置
上記通り、最上段まで ~~手が~~ 指が届かない。
そのため、レイヤーを切り替えて、ホームポジションで打てるようにしている。

以下、参考例(右手側は省略)

```ErgoDoxEZ:keymap.c
/* Keymap XXX: keys
 *
 * ,--------------------------------------------------.
 * |        |      |      |      |      |      |      |
 * |--------+------+------+------+------+-------------|
 * |        |      |      |      |      |      |      |
 * |--------+------+------+------+------+------|      |
 * |        |  1   |  2   |  3   |  4   |  5   |------|
 * |--------+------+------+------+------+------|      |
 * |        |      |      |      |      |      |      |
 * `--------+------+------+------+------+-------------'
 *   |  　  |      |      |      |      |              
 *   `----------------------------------'              
 *                                        ,-------------.
 *                                        |      |      |
 *                                 ,------|------|------|
 *                                 |      |      |      |
 *                                 |      |      |------|
 *                                 |      |      |      |
 *                                 `--------------------'
 */
[XXXkeys] = LAYOUT_ergodox(
       // left hand
		XXXXXXX,	XXXXXXX,	XXXXXXX,	XXXXXXX,	XXXXXXX,	XXXXXXX,	XXXXXXX,	
		XXXXXXX,	XXXXXXX,	XXXXXXX,	XXXXXXX,	XXXXXXX,	XXXXXXX,	XXXXXXX,	
		XXXXXXX,	KC_1,	KC_2,	KC_3,	KC_4,	KC_5,	
		XXXXXXX,	XXXXXXX,	XXXXXXX,	XXXXXXX,	XXXXXXX,	XXXXXXX,	XXXXXXX,	
		XXXXXXX,	XXXXXXX,	XXXXXXX,	XXXXXXX,	XXXXXXX,	
														XXXXXXX,	XXXXXXX,	
																		XXXXXXX,	
														XXXXXXX,	XXXXXXX,	
																		XXXXXXX,	

    // right hand
		・
		・
		・

),
```

# 記号入力（Shift+数字）
レイヤーを変えて、数字を打つため、記号が必要な場合、"レイヤー変更+Shift+数字"の3つもキーを押さなければならない。
そんな間抜けな話はない。
そのため、別枠で用意する。
そこで、言語設定に関係なく使えるようにすれば良いだけのこと。

英語配列だからとか日本語配列だとかの言い訳をして、過去の配列にこだわるなんてナンセンス。
ErgoDoxEZは、既製品ではなく、自分で配列を変えることが出来るのだから変えれば良い。
それだけで解決する。
既製品の配列に習うのであれば、既製品を使えば安く済む。

```ErgoDoxEZ:keymap.c
/* Keymap XXX: keys
 *
 * ,--------------------------------------------------.
 * |        |      |      |      |      |      |      |
 * |--------+------+------+------+------+-------------|
 * |        |  !   |  "   |  #   |  $   |  %   |      |
 * |--------+------+------+------+------+------|      |
 * |  Enter |  1   |  2   |  3   |  4   |  5   |------|
 * |--------+------+------+------+------+------|      |
 * |  Shift |  !   |  @   |  #   |  $   |  %   |      |
 * `--------+------+------+------+------+-------------'
 *   |  　  |      |      |      |      |
 *   `----------------------------------'
 *                                        ,-------------.
 *                                        |      |      |
 *                                 ,------|------|------|
 *                                 |      |      |      |
 *                                 |      |      |------|
 *                                 |      |      |      |
 *                                 `--------------------'
 */
[XXXkeys] = LAYOUT_ergodox(
       // left hand
		KC_NO,	KC_NO,	KC_NO,	KC_NO,	KC_NO,	KC_NO,	KC_NO,
		KC_NO,	JP_EXLM,	JP_DQT,	JP_HASH,	JP_DLR,	JP_PERC,	KC_NO,
		KC_ENTER,	KC_1,	KC_2,	KC_3,	KC_4,	KC_5,
		SFT_T(KC_NO),	KC_EXLM,	KC_AT,	KC_HASH,	KC_DLR,	KC_PERC,	KC_NO,
		KC_NO,	KC_NO,	KC_NO,	KC_NO,	KC_NO,
														KC_NO,	KC_NO,
																		KC_NO,
														KC_NO,	KC_NO,
																		KC_NO,

    // right hand
		・
		・
		・

),
```

数字の上にあるのが日本語配列用の記号で、その下段が英語配列の記号配列だ。
これで、ある程度は許容できるようになったはず。
しかし、その都度指の動きを上下で分けなければならないのは煩わしい。
さすがに、その動きを克服するのは辛いだろう。
仕事であれば、8時間以上日本語キーボードを使い、家ではちょろっとしかまともなキー配列に触れないのであれば、混乱してしまうだろう。
しかし、レイヤー0以外に数字や記号を含めている以上どうしようもない。

## 日本語配列
ちなみに、日本語配列用のキーコード

`クローン¥github_repository¥qmk_firmware¥quantum¥keymap_extras`
`keymap_jp.h`

これを使うこと。

```ErgoDoxEZ:keymap.c
# include "keymap_jp.h"
```

# キーマップの配列変更(検証途中)
上記では、英語配列の場合と日本語配列の場合で、同じ記号を使うにも関わらず、打つ場所を変えなければならない。
打つ前に鬱になる・・・これ如何に...

と言うことで、ハードウェア側で吸収するため、レイヤー切り替えをすることにした。
その対応で、英語配列と日本語配列の場合で、ワンタップにより切り替えるようにした。
（ワンタップ必要だが、ご愛敬）

ここの項目が本題になるはずだったのに、数日間の格闘の末、諦めて途中経過のまま投稿することにした。

[Levinson keymapカスタマイズ初日](http://make-keyboard.tk/blogs/3 "Site Updates")
[Add input cursor layer](http://make-keyboard.tk/blogs/4 "Site Updates")

色々サイトを見てあさるが、いまだに理解できないため、調査途中と言うことで・・・。
理解できないまでも自分がやりたいことは分かっている。

* ベースとなるレイヤーを切り替える。
* そのベースから英語配列用の記号レイヤーを使う。
* または、日本語配列用の記号レイヤーを使う。
* ※それ以外は、特に変更しない。

そのため、デフォルトレイヤーを変更しなければならない。
その関数が、`default_layer_set`だったいりする・・・未だに理解できていないが・・・。

取りあえず、中途半端に実装してみた。
[QMK⇒ErgoDoxEZ（英語・日本語レイヤー切り替え）keymap](https://github.com/chesscommands/clang/blob/master/Qiita投稿用keymap20180911.c "私のGithubにkeymap.cを配置した")

実際のレイヤー構造

* レイヤー0：英語配列を設定する。
* レイヤー1：日本語配列を設定する。
* レイヤー2：レイヤー0から呼ばれる英語配列用の記号を用意する。
* レイヤー3：レイヤー1から呼ばれる日本語配列用の記号を用意する。

注意すべき箇所は、ベースとなるレイヤーは、かならず若い番号に設定しなければならないと言うこと。
上記のサイトでそれを説明しているのだが、イマイチ理解できない。
確かに、大きいレイヤーに日本語配列用のベースレイヤーを設定した場合、その間に設定したレイヤーが有効化されてしまい、本来の日本語配列レイヤーが使えなくなってしまっていた。

ちなみに、レイヤーを設定するときは、エイリアスを使った方が見栄えが良くなると思う。

・キーに何も設定しない場合
`KC_NO`　⇒　`XXXXXXX`

・前のレイヤーキーを引き継ぐ場合
`KC_TRANSPARENT`　⇒　`KC_TRNS`もしくは`_______`

## 英語配列と日本語配列用のベースレイヤー
以下のように、押下時のみ記号レイヤーが切り替わるようにしている。
英語ベースレイヤーから`JAP`キー押下で、日本語ベースレイヤーに切り替わり、`ENG`キー押下で英語ベースレイヤーに切り替わる。

```ErgoDoxEZ:keymap.c
/* Keymap X: 英語配列用のベースレイヤ
 *
 * ,--------------------------------------------------.  
 * |        |      |      |      |      |      |      |  
 * |--------+------+------+------+------+-------------|  
 * |        |      |      |      |      |      | JAP  |  
 * |--------+------+------+------+------+------|      |  
 * |        |      |      |      |      |      |------|  
 * |--------+------+------+------+------+------|      |  
 * |        |      |      |      |      |      |      |  
 * `--------+------+------+------+------+-------------'  
 *   |      |      |      |      |      |                
 *   `----------------------------------'                
 *                                        ,-------------.
 *                                        |      | TO0  |
 *                                 ,------|------|------|
 *                                 |      |      |      |
 *                                 |LT(4) |      |------|
 *                                 |      |      |      |
 *                                 `--------------------'
 */


/* Keymap Y: 日本語配列用のベースレイヤ
 *
 * ,--------------------------------------------------.  
 * |        |      |      |      |      |      |      |  
 * |--------+------+------+------+------+-------------|  
 * |        |      |      |      |      |      | ENG  |  
 * |--------+------+------+------+------+------|      |  
 * |        |      |      |      |      |      |------|  
 * |--------+------+------+------+------+------|      |  
 * |        |      |      |      |      |      |      |  
 * `--------+------+------+------+------+-------------'  
 *   |      |      |      |      |      |                
 *   `----------------------------------'                
 *                                        ,-------------.
 *                                        |      | TO0  |
 *                                 ,------|------|------|
 *                                 |      |      |      |
 *                                 |LT(5) |      |------|
 *                                 |      |      |      |
 *                                 `--------------------'
 */
```

上記がベースレイヤーとなり、英語／日本語レイヤーとして基準になるレイヤーだ。
今回は、以下のレイヤーを記号レイヤーとして読み込む。
当然日本語用の記号レイヤーは、日本語用のヘッダを読み込み、記号を配置している。

```ErgoDoxEZ:keymap.c
/* Keymap：英語キーボードからの記号レイヤー読み込み
 *
 * ,--------------------------------------------------.           ,--------------------------------------------------.
 * |        |  F13 |  F14 |  F15 |  F16 |  F17 | F18  |           | LGUI |      |      |      |      |      |        |
 * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
 * |        |  F1  |  F2  |  F3  |  F4  |  F5  |      |           |      |  F6  |  F7  |  F8  |  F9  |  F10 |  F11   |
 * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
 * |  Enter |  1   |  2   |  3   |  4   |  5   |------|           |------|  6   |  7   |  8   |  9   |  0   |ZEROReturn|
 * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
 * |  Shift |  !   |  @   |  #   |  $   |  %   |      |           |      |  ^   |  &   |  *   |  (   |  )   | RShift |
 * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
 *   |      |      |      |      |      |                                       |      |      |      |      |      |
 *   `----------------------------------'                                       `----------------------------------'
 *                                        ,-------------.       ,-------------.
 *                                        |      |  JAP |       | RESET| TO(1)|
 *                                 ,------|------|------|       |------+------+------.
 *                                 |      |      |      |       |      |      |      |
 *                                 |      |      |------|       |------|      | M(2) |
 *                                 |      |      |      |       |      |      |      |
 *                                 `--------------------'       `--------------------'
 */
// ENGPlate
[ENGPlate] = LAYOUT_ergodox(
       // left hand
		_______,	KC_F13,	KC_F14,	KC_F15,	KC_F16,	KC_F17,	KC_F18,
		_______,	KC_F1,	KC_F2,	KC_F3,	KC_F4,	KC_F5,	_______,
		KC_ENTER,	KC_1,	KC_2,	KC_3,	KC_4,	KC_5,
		SFT_T(_______),	KC_EXLM,	KC_AT,	KC_HASH,	KC_DLR,	KC_PERC,	_______,
		_______,	_______,	_______,	_______,	_______,
														_______,	JAP,
																		_______,
														_______,	_______,
																		_______,



    // right hand
		QK_RGUI,	_______,	_______,	_______,	_______,	_______,	_______,
		_______,	KC_F6,	KC_F7,	KC_F8,	KC_F9,	KC_F10,	KC_F11,
			KC_6,	KC_7,	KC_8,	KC_9,	KC_0,	ZEROReturn,
		_______,	KC_CIRC,	KC_AMPR,	KC_ASTR,	KC_LPRN,	KC_RPRN,	RSFT_T(_______),
			_______,	_______,	_______,	_______,	_______,
		RESET,	TO(TEMP1Plate),
		_______,
		_______,
			_______,	M(2)

),

/* Keymap：日本語キーボードからの記号レイヤー読み込み
 *
 * ,--------------------------------------------------.           ,--------------------------------------------------.
 *|ZEROReturn|     |      |      |      |      | LGUI |           |  F19 |  F20 |  F21 |  F22 |  F23 |  F24 |  F12   |
 * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
 * |        |  F1  |  F2  |  F3  |  F4  |  F5  |      |           |      |  F6  |  F7  |  F8  |  F9  |  F10 |  F11   |
 * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
 * |  Enter |  1   |  2   |  3   |  4   |  5   |------|           |------|  6   |  7   |  8   |  9   |  0   |  TO(9) |
 * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
 * |  Shift |  !   |  "   |  #   |  $   |  %   |      |           |      |  &   |  '   |  (   |  )   |      | RESET  |
 * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
 *   | TO(1)|      |      |      |      |                                       |      |      |      |      |      |
 *   `----------------------------------'                                       `----------------------------------'
 *                                        ,-------------.       ,-------------.
 *                                        |      | Reset|       | RESET|      |
 *                                 ,------|------|------|       |------+------+------.
 *                                 |      |      |      |       |      |      |      |
 *                                 |      |      |------|       |------|      | M(2) |
 *                                 |      |      |      |       | ENG  |      |      |
 *                                 `--------------------'       `--------------------'
 */
// Jap keys
[JAPPlate] = LAYOUT_ergodox(
       // left hand
		ZEROReturn,	XXXXXXX,	XXXXXXX,	XXXXXXX,	XXXXXXX,	XXXXXXX,	QK_LGUI,
		XXXXXXX,	KC_F1,	KC_F2,	KC_F3,	KC_F4,	KC_F5,	XXXXXXX,
		KC_ENTER,	KC_1,	KC_2,	KC_3,	KC_4,	KC_5,
		SFT_T(XXXXXXX),	JP_EXLM,	JP_DQT,	JP_HASH,	JP_DLR,	JP_PERC,	XXXXXXX,
		TO(TEMP1Plate),	XXXXXXX,	XXXXXXX,	XXXXXXX,	XXXXXXX,
														TO(BASEPlate),	RESET,
																		XXXXXXX,
														XXXXXXX,	XXXXXXX,
																		XXXXXXX,



    // right hand
		KC_F19,	KC_F20,	KC_F21,	KC_F22,	KC_F23,	KC_F24,	KC_F12,
		XXXXXXX,	KC_F6,	KC_F7,	KC_F8,	KC_F9,	KC_F10,	KC_F11,
			KC_6,	KC_7,	KC_8,	KC_9,	KC_0,	XXXXXXX,
		XXXXXXX,	JP_AMPR,	JP_QUOT,	JP_LPRN,	JP_RPRN,	XXXXXXX,	RESET,
			XXXXXXX,	XXXXXXX,	XXXXXXX,	XXXXXXX,	TO(TEMP9Plate),
		RESET,	XXXXXXX,
		ENG,
		XXXXXXX,
			XXXXXXX,	M(2)


),
```

驚いたことに、英語設定のまま日本語レイヤーを使ったとき、なぜか英語設定の記号がそのまま出てくる(しかも、狂い無く)。
う〜ん...

`ENG`・`JAP`キーの設定は、`process_record_user`で行われる。

### process_record_user
ここの関数で、キー操作時の処理を記述する。
コメント通り、押下か押上で切り替えることも可能となっている。

一応仕込みが必要で、この関数を使うためには、case分で処理を振り分けているため、振り分けるための番号割り当てが必要になる。
それが`custom_keycodes`enumになる。

```ErgoDoxEZ:keymap.c
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  switch (keycode) {
    // dynamically generate these.
　　　・
　　　・
　　　・
	case JAP:
		if (record->event.pressed) {
			// キー押下時に動く
			default_layer_set(1UL<<JAPBASEPlate);
		}
		else {
			// キー押上時に動く
		}
		return false;
		break;

	case ENG:
		if (record->event.pressed) {
			// キー押下時に動く
			default_layer_set(1UL<<BASEPlate);
		}
		else {
			// キー押上時に動く
		}
		return false;
		break;

	case ZEROReturn:
		if (record->event.pressed) {
			// キー押下時に動く
			layer_clear();
			default_layer_set(0);
		}
		else {
			// キー押上時に動く
		}
		return false;
		break;


  }
  return true;
}
```

### custom_keycodes
ここは、先頭に既存のコードが割り振られているため、その末尾に追加していく形になる。

```ErgoDoxEZ:keymap.c
enum custom_keycodes {
　　　・
　　　・
　　　・,
  JAP,
  ENG,
  ZEROReturn
};
```

`ZEROReturn`は、保険のために追加した。
これをどこかのキーに割り当てておけば、かならずレイヤー0に戻れるからな。


* **注意**：
この設定をする場合は、かならずレイヤー0に戻せるキー設定をしておくこと。
そして、別途市販のキーボードを接続しておくこと。
レイヤー0以外で固定されてしまうかも知れない(今回とは異なる〜.hexファイルを読み込み直そうが、ケーブルを抜き差ししようが、レイヤー0に戻らない)。
かなり焦る。

* シフトビット
`default_layer_set`関数で、任意のレイヤーに移動できるが、引数には、レイヤー番号だけを与えるのではなく、Bit Shiftをさせるために、`1UL<<`を付けて、1ビット増やさせる必要がある。
初期の投稿では、これを追加し忘れていたため、レイヤー遷移してくれず、困っていたことを投稿した。
他の記事では、きちんと解説してあったのに、ソースコードをいじくることで、なぜか削除してしまったようだ。
見直しは大事だよ。

別のhexファイルを読み込むが、まったく0に戻らない。
そして、それまで使っていたhexを読み込み直し、別のキーボードを使って、何とかレイヤー0に戻した。
一安心して、本来のhexファイルを読み込み直して、愕然とした。
レイヤー0ではなく、先ほど読み込んだレイヤー位置のままになっていた。
どういうこと!?

インターネットに助けを求めたときに見つけたサイトは、それなりに分かりやすく説明していたのだが、私にはこれでも難しくて理解できなかった。
[QMK : キーマップのカスタマイズ](https://leico.github.io/TechnicalNote/QMK/key-customize "Technical Note")

## レイヤー0に戻す方法(`matrix_init_user`関数に追加)
ケーブルの抜き差しで0に戻せれば、かなり楽になるだろう。
常時、0レイヤーから他のレイヤーをデフォルトにする作業が発生してしまうが、検証のときだけだと考えれば、取るに足らない作業だろう。

```ErgoDoxEZ:keymap.c
void matrix_init_user(void) {
　　　・
　　　・
　　　・
	eeconfig_update_default_layer(0);
	default_layer_set(0);
};
```

初期の頃は、この設定がなければ、抜き差ししても戻らなかった・・・はず。
~~しかし、投稿直前に試したところ、何も設定がなくても抜き差しするだけで0に戻るようになった。
どういうこと!?~~

追記：[eeconfig_update_default_layer関数](#eeconfig_update_default_layer)について。
この関数がなければ、ケーブルの抜き差しで戻ってくれないことが分かった。
~~そして、この関数を使っても任意のレイヤーをデフォルトレイヤーにしてくれない。~~
まじで何をする関数なの!?


## 右手にマウスならば、左手にエンターキー必須
何かにつけてEnterキー押下は発生する。
ならば、左手側に、Enterキーを設定する必要がある。
既製品のキーボードで出来るのは数少ないが、ErgoDoxEZならば絶対に可能だ。
フルキーボードでの利点は、右手にマウスを持つ場合、マウスを持ったままエンターキーを押せる状態にあること。
その利点のために、フルキーボードに右手操作のマウスの組合せはおかしいけど(左手でマウスを使えば、必然的に右手はフォームポジションだろうからエンターキーに手が掛けやすい)。
何にせよ、体から手を離して作業するのは不自然だろうからHHKBが優れているのは言うまでも無い。

そして、ErgoDoxEZであれば、マウスを置く場所の左右どちらともキーボードで埋まっている。
問題ない。
中央において操作するため、何も問題ない。
マジックトラックパッドやトラックボールを使っているから成し得る技だが・・・。
ゲームするときは、ゲーミングとは言え、普通のマウスだろう。
そうした場合、右手側のキーボードを脇にどかし、マウスを置けば済む話。

もっといえば、右手側が不要なぐらい、左手側に集約したいと思っている。

[FrogPad - One-handed keyboard - Overview and demonstration](https://www.youtube.com/watch?v=TmzYovAMHE4 "FroggyTabletによる左手のみキーボード")

~~[Helix](6bf774ee30d410995879)が手に入ったら設定しようと思う。~~
~~待ち遠しい^^~~
能力の低さは直ぐに露呈するため、恥ずかしい(ニートになるわけだわ)。

## 備考(個人メモ)
[簡易的なレイヤー関数説明](https://www.reddit.com/r/olkb/comments/br0yq8/qmk_action_layerh_question/)


* [layer_clear](#layer_clear)：デフォルト/ベースレイヤ以外の全てのレイヤをクリアする。
* [layer_state_set](#layer_state_set)　←複数の関数から呼ばれる。

* [register_code](#register_code)　←C言語を使うときに、キー押下を実装するときに使うようだ。
* [unregister_code](#register_code)　←上記の押下を押し上げるときに使う。

* [layer_on](#layer_on)：特定のレイヤーをオンにし、すでにOnになっている場合は何もしない([MOキーコード](3e7e02d025f261bf6134#molayer)が使用する関数の最初の部分)。
* [layer_off](#layer_off)：特定のレイヤーをオフにし、すでにOffになっている場合は何もしない([MOキーコード](3e7e02d025f261bf6134#molayer)が使用する関数の第2の部分)。

* [default_layer_state_set](#default_layer_state_set)　←デフォルトレイヤー変更関数

* [eeconfig_update_default_layer](#eeconfig_update_default_layer)　←何もしない関数(しかし、重要なようだ)

* [layer_move](#layer_move)：移動先のレイヤ(及びベース/デフォルトレイヤ)以外の全てのレイヤをオフにする([TOキーコード](3e7e02d025f261bf6134#tolayer)が使用する関数)。

* [layer_invert](#layer_invert)：レイヤー切り替え([TGキーコード](3e7e02d025f261bf6134#tglayer)が使用する関数)。


### layer_clear
`layer_state_set`関数を呼び出し、0レイヤーをセットしている。
しかし、これだけではレイヤー0に移行できない。
`layer_move`関数との組合せでも移行できない。

### layer_state_set
現在の押下mods以外のすべてのキーをクリアする。
どういう意味!?
動作が関数名と合っていないし・・・。
※`clear_weak_mods`・`clear_macro_mods`・`clear_keys`などの関数が呼ばれるようだ。
`layer_on`関数から呼ばれるのだから理解しかねる。
※modsとは、KC_AやKC_RGUIなどの`MOD`のことを表しているとの解釈で合っているよね。
modeの複数形ではないよね。さすがにね...

`layer_state`変数は、標準で0が設定されている。
それをこの関数で上書きするようだが、デフォルトレイヤーが変わるわけではないようだ。

### register_code
`register_code`は、普通に、キー押下での機能が出来るようだ。これだけでは、押しっぱなしになってしまう。
`unregister_code`は、それの逆で、キーの押上をするのだろう。

※通常使用では使わない関数だと思う。

### layer_on
`layer_state_set`関数を呼び出しているだけなのだが、論理和にて、任意のレイヤーを追加しているようだ。

### layer_off
`layer_state_set`関数を呼び出し、指定のレイヤーを消しているようだ。

### layer_invert
`layer_state_set`関数を呼び出し、任意のレイヤーを反転させているのだが、何を言っているのか自分でも分からない。
そして、C言語のコメントにはドキュメントが必要だと言う記述が残っている。
何でだよ。

### layer_or
`layer_state_set`関数を呼び出し、任意のレイヤーと論理和を採っている・・・から何をする関数なのだろうか。。。

### layer_and
`layer_state_set`関数を呼び出し、任意のレイヤーと論理積を採っている。

### layer_xor
`layer_state_set`関数を呼び出し、任意のレイヤーと排他的論理和を採っているのが分かって頂けるだろう。
ならば、これ以上私を辱めないでくれ。
正解をくれ。私には理解できない。

### layer_move
`layer_state_set`関数を呼び出し、任意のレイヤーに移動する。
これだけでは移動できない。
`default_layer_set`関数呼び出し後に、レイヤー移動させる必要があるようだ。

### layer_state_cmp
現在のレイヤーと任意のレイヤーを比較している。
戻り値には、bool型が使われている。
これもソースコードのコメントに、ドキュメントが必要と残されている。
レイヤー0であれば、trueが返る。
現在のレイヤーと任意のレイヤーは、論理積をとり、0でなければfalseを返すはず。

### layer_state_is
`layer_state_cmp`関数を呼び出しているだけ。
もちろん戻り値は、bool型が使われている。

### default_layer_state_set
`default_layer_state`と言う変数があり、基本的には0が設定されている。
いわば、レイヤー0がデフォルトレイヤーだ。
そのデフォルトレイヤーを変更する関数として存在する。

何より、`layer_state_set`関数と同じで、現在の押下mods以外のすべてのキーをクリアする。
※`clear_weak_mods`・`clear_macro_mods`・`clear_keys`などの関数が呼ばれるようだ。


### default_layer_set
`default_layer_state_set`関数を呼ぶだけの関数。
何のために存在する関数か分からない。
よく見たらこの関数でなければ、レイヤー変更出来ない。
呼び出す関数は、static宣言されて、外部から安易に呼び出せないようになっている。

デフォルトレイヤーを変更後、`layer_move`関数を呼び、実際にレイヤーを明示的に変更する必要があるのかな。

### default_layer_or
`default_layer_state_set`関数を呼ぶ関数だが、現在のレイヤーと指定レイヤーを論理和で組み合わせている。
論理和か・・・ここでも出てくるのか。

### default_layer_and
`default_layer_state_set`関数を呼ぶ関数だが、現在のレイヤーと指定レイヤーを論理積で組み合わせている。

### default_layer_xor
`default_layer_state_set`関数を呼ぶ関数だが、現在のレイヤーと指定レイヤーを排他的論理和で組み合わせている。

### \_\_attribute\_\_⇒[解説](https://www.wdic.org/w/TECH/__attribute__ "通信用語の基礎知識")
プログラミングに関係するようだが、電算用語らしい。
[C++のattributeは難しい](https://cpplover.blogspot.com/2010/03/attribute.html "本の虫")
[データ型とAttribute](http://www.picfun.com/c30/c3004.html "電子工作の実験室")
[GCCによる関数の属性(__attribute__)について調べてみた](http://blueeyes.sakura.ne.jp/2018/01/10/761/ "なんとなく活動記録。")
[関数の属性](https://www.ibm.com/support/knowledgecenter/ja/ssw_ibm_i_73/rzarg/function_attributes.htm "IBM Knowledge Center")

今までの既存型に、付加価値を付けるのがアトリビュートなのだろうか。
だからなんだって話だが・・・。

この話題を出した理由は、`default_layer_state_set_kb`関数の直前に出現するからなんだよね。
関係あると思って調べたのだが、ちょっと挫折した。

`default_layer_state_set_kb`関数は、`default_layer_state_set`関数に呼ばれる。
しかし、特に何かの処理をしているわけではない。
現在のレイヤーを保存するためだけに存在する。
それなのに、わざわざ関数を設ける必要があるのか!?

### eeconfig_update_default_layer
この関数を使って、レイヤー変更している人が居たが、何をする関数なの!?
~~使う必要ないと思うのだが・・・~~ (以下,勝手に改行している)。
この関数がなければ、上手く動いてくれなかった。

```qmk:qmk_firmware/tmk_core/common/eeconfig.c
/** \brief eeconfig update default layer
 *
 * FIXME: needs doc
 */
void eeconfig_update_default_layer(uint8_t val)
{
	eeprom_update_byte(EECONFIG_DEFAULT_LAYER, val);
}
```

#### eeprom_update_byte
私の見る場所がおかしいのか!?
テストディレクトリにあるのだが・・・。

```qmk:qmk_firmware/tmk_core/common/test/eeprom.c
void eeprom_update_byte(uint8_t *addr, uint8_t value) {
	eeprom_write_byte(addr, value);
}
```

見る場所間違えた。

```qmk:qmk_firmware/tmk_core/common/arm_atsam/eeprom.c
void eeprom_update_byte(uint8_t *addr, uint8_t value) {
	eeprom_write_byte(addr, value);
}
```

大した違いなかった。
そして、`qmk_firmware/tmk_core/common/chibios/eeprom_teensy.c`にも同じ関数があり,処理内容も同じだ。
どちらが正しいのか。

#### eeprom_write_byte
結局、与えられた引数の値は、どこにも使っていないように思う。

```qmk:qmk_firmware/tmk_core/common/arm_atsam/eeprom.c
static uint8_t buffer[EEPROM_SIZE];
　　　・
　　　・
　　　・
void eeprom_write_byte(uint8_t *addr, uint8_t value) {
	uintptr_t offset = (uintptr_t)addr;
	buffer[offset] = value;
}
```

これにもテストディレクトリやchibiosディレクトリに同じ関数が存在する。
コンパイル時に、`chibios`の文言が出てくるのが分かった。
普段意識しなければ、見えているのに見えていないこととして過ごしてしまう。

#### EECONFIG_DEFAULT_LAYER
とりあえず、引数に定数を渡していたため調べたのだが、デフォルトレイヤーが3とか2とか、よく分からない値が固定値で宣言されている。

```ErgoDoxEZ:qmk_firmware/tmk_core/common/eeconfig.h
#if !defined(STM32F303xC)
　　　・
　　　・
　　　・
#define EECONFIG_DEFAULT_LAYER　(uint8_t *)3
　　　・
　　　・
　　　・
#else
　　　・
　　　・
　　　・
#define EECONFIG_DEFAULT_LAYER　(uint8_t *)2
　　　・
　　　・
　　　・
#endif

```

ポインタの使い方を忘れているのだが、3や2を直接使わないのかな・・・。

取りあえず、`default_layer_set`関数のみで動いた。
レイヤー変更出来た。


# 挑戦心あふれる人間が使うキーボードだ
学ぶことから逃げる人は、触るべきでないキーボードだ。
工夫を凝らさず、だらけた人は、触るべきでないキーボードだ。
過去のやり方に囚われることが好きな人は触るべきでないキーボードだ。
成長しないことにこだわる人は、触るべきでないキーボードだ。
経験を積みたくない人は、触るべきでないキーボードだ。
人間を捨てた人は、触るべきでないキーボードだ。
現実を直視できない人は、触るべきでないキーボードだ。
堕落し、成長せず、経験をせず、学ばず、生きずに死なない人は、触るべきではないキーボードだ。

## 逃げ出すのも作戦の一つだ
もうね、ドキュメントがアホのように抜けまくっている(英語のドキュメントですら言葉足らず)。
そのため、C言語のソースコードを読む必要が出てくる。
勘弁してくれ。
しかも、オーバーライドだか、オーバーロードなのかよく分からないことをしたいようなソースコードに見えてしまい、追いかけるのがかなりしんどい。
C言語でやるなよ・・・他の言語では、なおさら分からないけど...
[勉強](https://axia.co.jp/2018-09-07 "アクシアでの「プライベートでは一切勉強したくない」と言っていた社員のことの記事")しなくても生きていけるよ。きっとね。

# バーフバリ
映画『バーフバリ』を見て、勇気をもらおう。
自分が如何にちっぽけな人間なのかを理解できるだろう。
そして、いかにちっぽけなことで悩んでいるかも理解できるだろう。
少しぐらい躓いてもいいじゃないか。
何より、周りに助けを求めてもいいじゃないか。
普通の人間なのだから。
バーフバリ・バーフバリ・バーフバリ・バーフバリ

以上だ。