ARROWS NXが気になる

電車広告で見かけたdocomoからリリースされるFUjitsu ARROWS NX F-02Gが気になる。

ARROWSシリーズといえばねとらぼで展開している突飛すぎるPRが思い浮かぶが、内容は確かに圧倒的だ。

WQHD

最大の注目はWQHDディスプレイ&WQHD動画カメラ採用だろう。WQHDは1440×2560で、HDx4というピクセル数になる。FullHDの1.8倍だ。

5.2inchという大きめのディスプレイにWQHDというまだディスプレイでも普及は途上の多ピクセルディスプレイを採用する。当然ながらディスプレイサイズが上がれば解像度は落ちるが、それでも5.2というのはディスプレイとしてはかなり小さい。それに、単体ディスプレイなら27inchからというようなWQHDであり、ppiは564だという。かなり高精細で美しく、見やすい画面だと期待できる。

主に動画で強調されるが、WQHDの映像ソースというのはあまりない。それよりも文字の可読性が向上することのほうがメリットは大きいだろう。ただ、「世界最高峰」という記述からすると、5inchクラスのWQHDは初めてではないのだろう。

それ以上に注目すべきは、そんなWQHD映像ソースをつくることができるWQHD動画対応のカメラのほうだ。1/2.3 CMOSということで「大型」というには随分小さいが、それでもWQHD映像が撮れるカメラはかなり少ないので、非常に魅力的だ。ただし、FPSについて言及がない。キャノンのスティルカメラは4kに対応するが、FPSはかなり低い。

マイレージ性能

前モデルではWhiteMagicディスプレイを採用し、IGZOをヒューマンセントリックエンジンとの組み合わせでIGZOケータイを凌ぐマイレージを実現していたが、今回はジャパンディスプレイの最新IPS液晶を使っている。現状では、省エネスペシャルなディスプレイと、高解像度ディスプレイはORであり、高解像度をとれば省エネディスプレイは採用できなかった、ということのようだ。

それでも「前モデル以上のマイレージ性能」を謳うだけのものをヒューマンセントリックエンジンで稼ぎ出しているようだ。とはいえ、SHARPのエコ技の使いにくさに困っている私としてはあまり嬉しさを感じないが。

しかしタブレット並の3500mHaは、もちろん充電が大変になるとか、モバイルバッテリーによる駆動延長が難しくなる、といったところはあるが、それでもマイレージ性能には大きく影響するだろう。ただ、思った程電池が進化してこないのは、根本的な泣き所だ。採用している電池についての情報はない。

急速充電にも対応とのことである。

VoLTE

ヴォルテ、とよむらしい。私は知らなかったので調べたのだが、まぁ字面から予測できるように、音声通信をLTEデータ回線に乗せる技術だ。

私はこれがSkypeなどの音質向上のために通常とは別回線に乗せるものかと思ったのだが、そうではないらしい。通常の音声通話をLTE上に乗せるというもので、従来の音声通話が3G回線を使っていたのに対して、音声もLTEに切り替える中で、音声もデータ通信に乗せるというもののようだ。オプショナルなものではなく、音声通話のバックボーンをデータ通信(LTE)に切り替えるということで、音声通話分の帯域は特別に保証されるため、「スマホによるパケット通信のトラフィックに逼迫されて音声通話ができなくなる」という事態は起きない、ということのようだ。

もっとも、個人的には音声回線の安定感からしてデータ通信ベースにするということは色々と不安があるし、従来型のeメールはできなくなる可能性がある(対応されなければ)とも考えているので、あまり嬉しくない。

少なくともVoLTE対応を高らかにうたわれても、ユーザーメリットは現時点でないように思う。

ATOK

ATOKに関しては後入れが可能なものではあるが、それでもそれなりの出費にはなるわけで、デフォルトの入力エンジンがATOKであるということは非常に大きい。

しかもARROWSのものは、ULTIUSというさらなる改良を加えたスペシャル版だ。

POBox*ジョグダイアルの圧倒的な変換能力を体験した身としては、Simeji+Mozcだろうと、Wnnだろうと、入力効率の悪さにはイライライライライライライライライライライライライラする。少しでも有能な日本語入力環境が欲しい、と考えるのは当然だろう。

現在はスマホで文字入力することがあまりないため、それほど気にしていない(というよりも、ガラケーのほうの入力効率の悪さに絶望している)が、これはもう最大の魅力と言っていいだろう。

ちなみに、WnnはMozcよりも劣るように感じられる。

192kHz/24bit音源対応

ハイレゾ対応プレーヤーはまだまだ高級で、Xperiaのウリにもなっているが、これに対応してきた。

ただし、これは一部マニア向けの話だろう。一般ユーザーはMP3やAAC(M4A)で満足してしまっているのだし、CDなど一般的な音源ではなく入手が難しい上に、音源自体があまり多くない。環境の有無よりも、そもそもハイレゾ音源を楽しんでいる、楽しもうとしているユーザーが少ない。

だいたい、ハイレゾ音源は結構ファイルサイズが大きいので、スマホのようにフラッシュメモリカードだけで対応するような場合、大した曲数はいれられないため、実際はlossyにして全部入れたほうが楽しめる。実際、私はPDAPがFLAC対応だが、Ogg vorbisにしている。そのため、意外とメリットがない。現状では「体験できる」といった意味合い、もしくは「興味をもったら試せる」。

使い勝手

形状はかなり良好なようで、加えて防塵・防水仕様となっている。しかも、傷がつきにくいよう配慮された設計で、メイド・イン・ジャパンらしさを感じる。

UIも人気が高いが、これにもさらに磨きがかけられたということで、非常に使いやすいだろう。指紋センサーも扱いやすいよう配慮がなされ、さらに手袋モード(低静電容量感応モード)も搭載。「非常に速い」と評判のダウンロード機能や、前述のATOKなど、徹底して「使いやすいスマホ」に仕上げている印象を受ける。

私には魅力ではないが、おサイフケータイ及びワンセグにも対応と日本のニーズに応える。32GB内蔵+128GB microSDとストレージ性能は、ある程度大きいものが使えるようになっている。

ディスプレイは表示の美しさに加え、日光の中でも見やすいよう調整されるという。

地味な機能だが、FMトランスミッタ内蔵、ANT+対応というのはかなり応用が効く。

日本のスマホは非常に制限が厳しく不自由で魅力がないのだが、カスタマイズできなくとも、このように日本メーカーらしく徹底した使いやすさにこだわったもの、というのはやはり非常に高い価値と魅力があるように思うし、それであるならば日本のスマホを選んでもいい、とも思う。この場合、Rootedを捨ててもの話だ。

非常に魅力的で気になる存在だ。

mount namespace, VineSeed, nc chat&ZeroMQ

mount namespace

試してみたのだが、うまくいかなかった。

通常は共有されるマウントツリーの空間だが、これをプロセス固有のものにすることができるのがmount namespaceだ。

mount namespace適用の方法はunshare –mount commandとなる。これでcommandが新たにマウントしたファイルシステムは、そのプロセスと子孫プロセスに固有のものになり、上流には反映されないという。

というわけで試してみた。

$ sudo unshare zsh
$ sudo mount -o subvol=testvol /dev/sdd2 /mnt/3
}

p {[
"しかし、異なるmount namespaceをもっているプロセスからもそれが見えてしまう。違うファイルシステムツリーをもっている環境を作りたかったのだが、それ以前の問題だ。",
"btrfs
]}

h3 "VineSeed"
p {[
"Vine Projectのお手伝いをすることにして、Seed環境を構築しようとしたのだが、マニュアルに従ってVirtualBox上で構築するも、うまくいかなかった。",
"ベースシステムで手順どおりにするとPlymouthのあとブラックアウト、フルインストールからではXDMが起動し、ログインしてもただちにXDMに戻る。",
"問題はVineSeed MLにレポート済み"
]}

h3 "ncでchat & ZeroMQで拡張を目論見る"
p {[
"LAN内のコンピュータととりあえずメッセージをやりとりするのに良い手段…と考えたのだが、なかなか良い方法がなかった。",
"最も手間がないのは、ssh+ncを使う方法だろう。",
"2つのコンピュータは、まず片方でつぎのようにして、コネクションを対話的に待ち受ける。",
]}

sb(c:"shell") { "$ nc -l 55555" }

p {[
"そしてもう片方のクライアントはSSHでログインし、ncで接続する。"
]}

sb(c:"shell) { <<-END
$ ssh -x user@host
$ nc localhost 55555

ふたりなら十分に実用になるが、頻繁に書いていると画面がごちゃごちゃになり、また消すことができない(日本語の場合)のも難点。

こういうのを処理するのがlibChat ZMQ Framework(私の作品)なのだが、そのベースになるようなシンプルなサーバーを書いてみた。

のはいいのだが、MageiaでRuby ZeroMQバインディングがインストールできない。Pythonのほうは用意されているのだが、

Building native extensions. This could take a while…
ERROR: Error installing zmq:
ERROR: Failed to build gem native extension.

/usr/bin/ruby extconf.rb
checking for zmq.h… yes
checking for zmq_init() in -lzmq… yes
Cool, I found your zmq install…
creating Makefile

make “DESTDIR=”
gcc -I. -I/usr/include/x86_64-linux -I/usr/include/ruby/backward -I/usr/include -I. -DHAVE_ZMQ_H -fPIC -O2 -g -pipe -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector –param=ssp-buffer-size=4 -fPIC -fPIC -o rbzmq.o -c rbzmq.c
rbzmq.c: 関数 ‘internal_select’ 内:
rbzmq.c:324:9: 警告: ‘rb_thread_blocking_region’ は廃止されました (宣言位置 /usr/include/ruby/intern.h:839) [-Wdeprecated-declarations]
rb_thread_blocking_region (zmq_poll_blocking, (void*)&poll_args, NULL, NULL);
^
rbzmq.c: 関数 ‘socket_getsockopt’ 内:
rbzmq.c:968:7: エラー: ‘ZMQ_RECOVERY_IVL_MSEC’ が宣言されていません (この関数内での最初の使用)
case ZMQ_RECOVERY_IVL_MSEC:
^
rbzmq.c:968:7: 備考: 未宣言の識別子は出現した各関数内で一回のみ報告されます
rbzmq.c:990:10: エラー: ‘ZMQ_HWM’ が宣言されていません (この関数内での最初の使用)
case ZMQ_HWM:
^
rbzmq.c:991:10: エラー: ‘ZMQ_SWAP’ が宣言されていません (この関数内での最初の使用)
case ZMQ_SWAP:
^
rbzmq.c:995:10: エラー: ‘ZMQ_MCAST_LOOP’ が宣言されていません (この関数内での最初の使用)
case ZMQ_MCAST_LOOP:
^
rbzmq.c: 関数 ‘socket_setsockopt’ 内:
rbzmq.c:1292:10: エラー: ‘ZMQ_HWM’ が宣言されていません (この関数内での最初の使用)
case ZMQ_HWM:
^
rbzmq.c:1293:10: エラー: ‘ZMQ_SWAP’ が宣言されていません (この関数内での最初の使用)
case ZMQ_SWAP:
^
rbzmq.c:1297:10: エラー: ‘ZMQ_MCAST_LOOP’ が宣言されていません (この関数内での最初の使用)
case ZMQ_MCAST_LOOP:
^
rbzmq.c:1315:10: エラー: ‘ZMQ_RECOVERY_IVL_MSEC’ が宣言されていません (この関数内での最初の使用)
case ZMQ_RECOVERY_IVL_MSEC:
^
rbzmq.c: 関数 ‘zmq_send_blocking’ 内:
rbzmq.c:1443:5: エラー: 関数 ‘zmq_send’ へ渡す引数が少なすぎます
send_args->rc = zmq_send(send_args->socket, send_args->msg, send_args->flags);
^
In file included from rbzmq.c:28:0:
/usr/include/zmq.h:349:16: 備考: ここで宣言されています
ZMQ_EXPORT int zmq_send (void *s, const void *buf, size_t len, int flags);
^
rbzmq.c: 関数 ‘socket_send’ 内:
rbzmq.c:1512:9: 警告: ‘rb_thread_blocking_region’ は廃止されました (宣言位置 /usr/include/ruby/intern.h:839) [-Wdeprecated-declarations]
rb_thread_blocking_region (zmq_send_blocking, (void*) &send_args, NULL, NULL);
^
rbzmq.c:1517:9: エラー: 関数 ‘zmq_send’ へ渡す引数が少なすぎます
rc = zmq_send (s, &msg, flags);
^
In file included from rbzmq.c:28:0:
/usr/include/zmq.h:349:16: 備考: ここで宣言されています
ZMQ_EXPORT int zmq_send (void *s, const void *buf, size_t len, int flags);
^
rbzmq.c: 関数 ‘zmq_recv_blocking’ 内:
rbzmq.c:1541:5: エラー: 関数 ‘zmq_recv’ へ渡す引数が少なすぎます
recv_args->rc = zmq_recv(recv_args->socket, recv_args->msg, recv_args->flags);
^
In file included from rbzmq.c:28:0:
/usr/include/zmq.h:350:16: 備考: ここで宣言されています
ZMQ_EXPORT int zmq_recv (void *s, void *buf, size_t len, int flags);
^
rbzmq.c: 関数 ‘socket_recv’ 内:
rbzmq.c:1596:9: 警告: ‘rb_thread_blocking_region’ は廃止されました (宣言位置 /usr/include/ruby/intern.h:839) [-Wdeprecated-declarations]
rb_thread_blocking_region (zmq_recv_blocking, (void*) &recv_args,
^
rbzmq.c:1602:9: エラー: 関数 ‘zmq_recv’ へ渡す引数が少なすぎます
rc = zmq_recv (s, &msg, flags);
^
In file included from rbzmq.c:28:0:
/usr/include/zmq.h:350:16: 備考: ここで宣言されています
ZMQ_EXPORT int zmq_recv (void *s, void *buf, size_t len, int flags);
^
In file included from /usr/include/ruby.h:33:0,
from rbzmq.c:22:
rbzmq.c: 関数 ‘Init_zmq’ 内:
rbzmq.c:1675:50: エラー: ‘ZMQ_HWM’ が宣言されていません (この関数内での最初の使用)
rb_define_const (zmq_module, “HWM”, INT2NUM (ZMQ_HWM));
^
rbzmq.c:1676:51: エラー: ‘ZMQ_SWAP’ が宣言されていません (この関数内での最初の使用)
rb_define_const (zmq_module, “SWAP”, INT2NUM (ZMQ_SWAP));
^
rbzmq.c:1683:57: エラー: ‘ZMQ_MCAST_LOOP’ が宣言されていません (この関数内での最初の使用)
rb_define_const (zmq_module, “MCAST_LOOP”, INT2NUM (ZMQ_MCAST_LOOP));
^
rbzmq.c:1698:64: エラー: ‘ZMQ_RECOVERY_IVL_MSEC’ が宣言されていません (この関数内での最初の使用)
rb_define_const (zmq_module, “RECOVERY_IVL_MSEC”, INT2NUM (ZMQ_RECOVERY_IVL_MSEC));
^
Makefile:224: recipe for target ‘rbzmq.o’ failed
make: *** [rbzmq.o] Error 1

Gem files will remain installed in /home/aki/.gem/ruby/gems/zmq-2.1.4 for inspection.
Results logged to /home/aki/.gem/ruby/gems/zmq-2.1.4/./gem_make.out

libChat::ZMQにしてもZeroMQを使っているので試せない。サーバー用にVMを用意するなどすればいいのだが、なかなか厄介な事態だ。

PureDocのエスケープ機能

ずっと機能しない、と言ってきたPureDoc組み込みHTMLエスケープ機能だが、修正されて動くようになった。

問題のコードはこんな感じ。

STANDARD_ESCAPE_EX = /<(?![a-z/])|(?<![/"a-z])>|&(?![a-z0-9]+;|#[x0-9]+;)/
FORCE_ESCAPE_EX = /[<>"&]/
ESCAPE_INVOKE = ->(m, ptn) {
return "" if m.nil?
m.gsubz(ptn) do
case m
when "<"
"&lt;"
when ">"
"&gt;"
when '"'
"&quot;"
when "&"
"&amp;"
end
end
}

修正版はこうなった

STANDARD_ESCAPE_EX = /<(?:(?:/[a-z]+|[a-z]+(?: +[a-z]+="[^"]*"+)*)>)?|(?:<(?:/[a-z]+|[a-z]+(?: +[a-z]+="[^"]*"+)*))?>|&(?![a-z0-9]+;|#[x0-9]+;)/
FORCE_ESCAPE_EX = /[<>"&]/
ESCAPE_INVOKE = ->(m, ptn) {
return "" if m.nil?
m.gsub(ptn) do
case $&
when "<"
"&lt;"
when ">"
"&gt;"
when '"'
"&quot;"
when "&"
"&amp;"
else
$&
end
end
}

動かない原因は、caseでマッチする文字列が、正規表現のマッチ文字列ではなく元文字列になっていた、という単純なもので、気付くまでにデバッグに時間がかかったが、気付いてしまえばあっという間だった。

ところが、よく見るとSTANDARD_ESCAPE_EXがまるごと変わっている。これは、「<及び>がタグを構成する一部か」を判定する部分が甘かったからなのだが、ちょっとハマったのが、るりまには書かれていない「後読みアサーションに量指定子は使えない」という仕様だった。どうしても量指定子を使いたかったので、選択(?)でタグを構成する場合はタグ全体がマッチするようにした。このようにすると、case文で判定しているのは文字が含まれているかではなく、文字が===でマッチするかであるため(標準では文字列の同一性を見る)、タグ全体がマッチした場合はcase文でのマッチに失敗する。マッチに失敗した場合はelseでマッチ文字列全体を返すためString#grubの内容が唯一のcase文である時それにマッチしない文字列は変更されない。結果的に「タグを構成しているとみられる文字列は変更しない」となる。

なお、#escメソッドはこのように「タグ、もしくは文字参照と見られる文字列はエスケープしない」が、これは全ての要素メソッドが自動的に呼ぶためで、ユーザーが明示的にエスケープしたい場合は#esc!メソッドを呼ぶことで対応できる。これは、このような判定は一切行わず、全ての当該シンボルをエスケープする。

なお、PureDocは特殊文字入力にHTML/XMLの文字参照を使うことになっている。そのため文字参照のエスケープを回避しているのだが、HTML以外への編訳においては当然文字参照のアンエスケープまたは変換が必要となる。

ReasonSet サイト構築システム PureBuilder

PureBuilderは以前から何度か登場し、完全にやり直し、と繰り返している。今回は、「本体スクリプト」というものがない状態で登場し、ついに実用となった。

まず下地となるPureBuilderだが、かなり更新され、GitHubにも既に反映されている。まずこれがベースになる。

そして、「PureDocを使った翻訳を自動化する」というのがPureBuilderの基本的なところだ。PureBuilderのGitHubにあるpurebuild-puredoc.zshがその根幹となるスクリプトである。

はっきり言ってGitHubにある設定ファイルのサンプルとREADMEを読むのが一番早いと思うのだが、つまりこのスクリプトは.purebuild-puredoc.rc, .up_*, .rebuild-rulesファイルに従って実行するための補助ユーティリティでしかない。だが、設定ファイルを適切に書くことでほぼ全面的な自動化を実現している。サンプルをみれば分かるように、メニューを動的生成していたりする(eRubyを使っている)ため、サイトでユーザーからのアクションが自動的に反映されるような仕組みを持たないドキュメントに関してはこの方法で動的に静的ドキュメントを生成することができる。これは、著しいオーバーヘッド削減につながる。

参考までに、ReasonSetのサイトのメニューの構築を行うテンプレートは次のようなものだ。

<% menu = [
[ ["ReasonSet / Help", "//reasonset.net/", "ReasonSet全体の情報"], (ENV["SITETYPE"] == "REASONSET"), [["Profile", "//reasonset.net/profile.html", "正木はるか(柊美亜紀)のプロフィール"]] ],
[ ["HARUKA Sound", nil, "音楽プロダクション/プロジェクト HARUKA Soundの公式ページ(お仕事)"], nil, [] ],
[ ["Aki's palace", nil, "正木はるか(柊美亜紀)に関するウェブサイト。本人について、意見など"], (ENV["SITETYPE"] == "AKI"), [ ["Talkin' about", nil, "様々なテーマに対しそのフィルタを通して語る" ] ] ],
[ ["ちぇのみ-Chienomi-", nil, "コンピュータ"] , (ENV["SITETYPE"] == "CHIENOMI"), ["COLUMN", nil, "コラム" ], ["+Play programming with JavaScript", nil, "JavaScriptでプログラミングを遊ぶ"] ["+Easy step programming with Perl", nil, "Perlではじめるプログラミング入門"], ["+Easy step object oriented programming with Ruby", nil, "Rubyではじめるオブジェクト指向入門"] , ["Live with Linux", "http://reasonset.net/journal/archives/category/livewithlinux", "Linux日記" ] ],
[ ["Feel the Earth", nil, "バイク"], (ENV["SITETYPE"] == "MOTO"), [["Impression",nil,"所有車両のインプレッション"], ["Impression:HONDA VT250J SPADA", nil], ["Impression: SUZUKI SV400S", nil], ["Impression:YAMAHA MT-09", nil], ["Column", nil, "コラム"] ] ],
[ ["Blogs", "//reasonset.net/blog.html", "ブログ"], (ENV["SITETYPE"] == "BLOG") , [["journal de Aki", "http://reasonset.net/journal/", "本来のブログ"], ["Ameblo", "http://ameblo.jp/reasonset", "くだらないブログ"]] ],
[ ["SI Service", "http://reasonset.net/si/", "コンピュータの技術を供与するサービスについて(お仕事)"], nil, [] ]
]
%>

<div id="ReasonsetMenu">
% menu.each do | name, cond, items |
% if name[1]
<div class="menu_title"><a href="<%= name[1] %>" title="<%= name[2] %>"><%= name[0] %></a></div>
% else
<div class="menu_title"><span title="<%= name[2] %>"><%= name[0] %></span></div>
% end
% items.each do |i|
% if i[1]
<div class="menu_item"><a href="<%= i[1] %>" title="<%= i[2] %>"><%= i[0] %></a></div>
% else
<div class="menu_item"><span title="<%= i[2] %>"><%= i[0] %></span></div>
% end
% end if cond
% end
</div>

さらに、よりプロフィールに関してはプロフィール自体がRuby scriptとなっており、それを実行することでPureDocを拡張した形式で書かれたプロフィールを展開する。

もっとも、プロフィールを含むスクリプトはあくまで出力するだけであり、実際にアップロードする処理は.up_profileというスクリプトを書いて実行している。

全体には伝播する環境変数をうまくつかった仕組みになっていると思う。

PureBuilderでzsh functionを導入

Zshのautoloading functionは「functionを書いたファイルを大量に.する代わりにロードする手段を与える」ものだと思えばいい。基本的には1 file 1 functionであるようだ。

$fpathに含まれるディレクトリにあるファイル名がautoloadで指定する値であり、またfunction名にもなる。

これまでrcファイルに直接書いていたUpdate機能だが、Zsh functionとして提供することにした。ファンクションインストーラが勝手に専用ディレクトリ~/.yek/lib/purebuild_functionsにインストールするので($funcdirで直接指定することもできる)、それを$fpathに追加することでロードできるようになる。あとはautoload -Uzして使って欲しい。

このfunctionはかなり丁寧に情報を出力する。「Last Updateよりも新しい」の判定は、素直にfind(1)touch(1)を使っている。また、最終更新についてはstat(1)を使って表示している。

今回はfunctionを使うようになったのがメインだが、つられてpure builder及びpuredocの更新もあった。

また、purebuilderはGitHubで公開したので参考にしてほしい。

Canon MP630 マルチプリンターを openSUSE 13.1 x86_64 (64bit) で使う

Canon MP630はCanonのサイトに純正のドライバ及びソフトウェアが配布されている。各共通ファイルと機種別ファイルがあり、RPM, debとソースファイル(共通ファイルのみ)で提供されている。動作はFedora/openSUSE/Ubuntuでの動作が保証されているが、Fedora 9/openSUSE 11.0/Ubuntu 8.04とかなり古い。しかも、i386なのでかなり難しい。

openSUSEであればそのインストールは比較的容易、おそらくはRPM系およびdeb系なら比較的楽だろう。しかしx86_64のopenSUSEでインストールすると、大量の32bitライブラリの欠如を指摘される。基本的には指摘されたライブラリ名をYaSTで検索すればインストールできるのだが、libtiffに関してはlibtiff3を要求されるため、YaSTからインストール可能なlibtiff5では依存性欠如が回復されない。libtiff3はopenSUSE公式に不安定版で入手できるほか、RPM searchにも存在する。また、RPM resourceでも入手可能。

それだけで安定して動作する。1回目のプリントでは「準備しています」が異常に長かったが、その後は特に問題なく動作している。比較的安定し、また使用環境も整えやすいようだ。少なくとも、もはやレガシーハードウェアであるBJ S600よりははるかに楽だろう。

USBメモリーとF2fs

USBメモリーが600MB以上かけない、という症状が生じていた。結局はWindowsで書いてみたところ不安定ながら動作したが、その後Ext3でフォーマット、F2fsでフォーマットとした。

F2fsは実装はLinux kernel内にあるため、操作するためのツールがあれば利用できる。ツールが用意されているものはあまり多くないようだ。ツールが用意されていないディストリビューションの場合、

$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs-tools.git

あとは

$ autoreconf --install
$ ./configure
$ make
$ sudo make install

これで利用可能。ファイルシステムの作成は単純にmkfs.f2fsで行える。また、パーティションIDの設定も兼ねてGpartedで操作すればf2fsの作成も可能になる。

F2fsの性能についてはまだ不明だ。だが、先日のLinuxConでは「フラッシュストレージ用ファイルシステム」が話題になっていた。フラッシュメモリは一種のデータベースで管理する必要があり、それは既存のHDD向けファイルシステムとは全く異なる要件である、という話だったと思う。そのため、既存のファイルシステムの拡張ではなく、新しいファイルシステムが必要なのだと。

フラッシュストレージ用ファイルシステムというのは既にいくつかある。Btrfsがフラッシュストレージ向けだというような話だったが、実際はもっと汎用設計になっている。ある意味、中途半端になってしまったともいえる。それに対して、続々出てきている新しいフラッ社ストレージ用ファイルシステムは完全にフラッシュメモリ専用で、フラッシュメモリの特性に合わせてI/Oを行う。これらはカーネルのI/O機構を利用したくないという話だし、実際に利用していないのかもしれない。フラッシュストレージ用ファイルシステムの動作は複雑で、従来のファイルシステムほど簡単には説明できない。ただし、基本的な部分ではウェアレベリングと配置をバラバラのままにするというのがフラッシュストレージ用ファイルシステムというのだろう。

そのようなフラッシュストレージ用ファイルシステムは今後さらに増え、また成熟してくるだろう。現在のところWindowsで一般的なフラッシュストレージ用ファイルシステムというのはなく、FAT32, exFAT, NTFSでこなしているが、将来的にはやはりWindowsもなんらかフラッシュストレージ用ファイルシステムを採用せざるをえないだろう。その時、現在はF2fsをWindowsで使うことは非常に難しいが、今後AndroidがF2fsを採用する可能性が高く、F2fsはかなり普及しそうなのでWindowsとしてもOSでF2fsをサポートせざるをえないのではないかという気がする。

本当は個人的にはF2fsよりもLogFSが気になっていたのだが、情報が少なく、なかなか茨の道と感じた。実装はカーネルにあるが、logfs-toolsが見つからない。ドキュメントも大体が2007年のものであまり現状がわからないので、やはり普及せずに終わったのだろうか、という感じがする。明らかに成功しているのはF2fsであるようにも思える。

HTML * CSS 美しいフレームをもつカラムスタイルレイアウトの難しさ

私のサイトをみるとわかるのだが、ボーダーが画像になっている。これをどうやって作るのか、というとごくごく単純で、背景画像を持つdiv要素に入れ子で白背景のdiv要素をおいているだけだ。ちなみに、外側のdiv要素にpaddingを設定するのが正しいやり方だ。

ところが、これで左右カラムを置き、しかもその中にブロック要素をおこうとするとかなり難しい。floatを使って配置すると、内側のブロック要素は親要素のブロックを突き抜けてくっついてしまうのだ。普通なら左右カラムはくっついて配置されて構わないものだから、このような挙動は気にしないのだが、今回の場合、左右カラムの間に空間を作ってボーダーを表示したいため、工夫がいる。

とりあえず、まずは縦に並ぶブロックを分けろ、だ。左右カラムはブロックの中に入れて左右分割すべきだ。でないととても苦労する。

さて、問題の比較的単純な解決策はfloatを使い、左右それぞれにfloatし、かつ重ならないようにwidthを設定する方法だ。だが、私はfloatを使う方法があまり好きでない。なんらかの理由で重なってしまうと後に書いたブロックは後ろにいってしまうという、表示への影響が大きいからだ。

そのため、私がとった方法は

  1. static配置では中のブロックに対してabsoluteが使えないので外のコンテナはrelativeで配置
  2. 右に配置されるサイドバーコンテナを先に書く
  3. サイドバーコンテナはabosluteで配置。widthz-indexを設定
  4. メイン部分コンテナはrelativeで配置。同様にwidthz-indexを設定
  5. サイドバーコンテナ、メイン部分コンテナ共に内側に入れ子のコンテナを配置(白背景)
  6. 外のコンテナのwidthpaddingでボーダーを適切にする。つまりギリギリにしないほうが良い
  7. サイドバーコンテナにmax-height、メイン部分コンテナにmin-heightを設定。サイドバーコンテナはoverflow: auto

簡単な話なのに複雑、と感じただろうか。実はそう簡単ではない。確実に正確な位置に配置しようとすると、floatしないならabsoluteで置くしかない。ところが、そうしようとするとstaticのまま親コンテナが配置されていてはいけない。

サイドバーコンテナを先にするのも理由はあるが、別に好みだとは言える。

widthの設定はもちろんかさならないように、またボーダーのサイズを調整するためで、z-indexは万一重なった時のためだ。

入れ子にするのは白背景とボーダー調整のためだが、この方法ではなくてもできる。

さて、なぜ両方absoluteにしないかというと、そうするとこのブロックは高さ0であるとみなされ、下側のボーダーが出ない(下にフッターを配置した場合、それも出ない)。そのため無限に長くなるメインのほうをrelativeにしているのだが、そうすると本文よりもサイドバーが長くなるときに支障が出る。そこで、サイドバーの最大長を制限すると共に、本文の最低長を要求することで、サイドバーのほうが長くならないようにしている。

別に「すごく難しい」という話ではないのだが、これはなかなか出てこない話だ。というのは、かなり技術的なことをしているが、それは構造的、意味的なものではなく、完全にデザインのための記述だ。デザインのための技法というのは技術者にはなかなか身につかない。そして、デザイナーがデザインを実現するための技術もそうそう思いつかない。ボーダーに画像を使いたいと言われた時、エンジニアがそのような機能はないのでできない、と言ってしまう可能性もある。今回やっていることはどちらかというとデザイナー主体のことで、デザイナーがそれを実現するための技術的知識があるか?というところが問われる。

このようなデザインは非常に個人サイト的で、商業サイトではトレンドもあるためこのようなデザインを採用することはない。というよりも今は非常にDHTML流行りなので、そもそもアクセシビリティ自体がナンセンスのように言われることも少なくないし、こうした指向がないために見かけないのかもしれないが、アクセシビリティとデザインを両立し、独自性があり、かつ習慣に基づくなじみやすさを満たす、というこうした技法は、そうしたサイトをみないだけに抜け落ちるポイントになっているのではないか?と思う。

今回は他の方法もあるにはあるのだが、これが最もアクセシビリティが高い方法だと思う。個人的には、最新のウェブブラウザでなければ見られないようなサイトは好きでない。

なお、現状公開しているサイトはこの仕様になっていない。現在テンプレートを修正したところだからだ。恐らく、本体ウェブサイトではなく、商業ページのほうが先にこのレイアウトを採用するだろう。現在の本体ウェブサイトは類似のデザインを採用しているが、バグがある。


/* Skin CSS for general essay.
* This is used by essays independent from the site.
*/

/* Top definition */
body {
background: #fff url("//reasonset.net/img/wp/heartline.gif") repeat-y 15% 0% scroll;
font-size: 10pt;
color: #39f;

}


/* Main Container. Over all container. */
#MainContainer {
width : 950;
margin : 0 auto;
background: #e0f0ff url("//reasonset.net/img/wp/check_bp.png") repeat scroll;
font-family: "Rounded-X M+ 2c","Migu 1C","M+IPA+2VM circle","Gen Jyuu Gothic Normal","VL P Gothic", "Hiragino Maru Gothic", "Meiryo",sans-serif; /* define Japanese Font */
position: relative;
padding: 45px;
}

/* For overwrite font-family for English document. */
#MainContainer {

font-family: serif;

}

/* Top banner */
#TopBan {
margin : 0px 0px 18px 0px;
font-size: 300%;
padding: 1.3em;
position: relative;
}

#UnderContainer {
position: relative;
}

/* Main content container */
#LeftPage {
position: relative;
top: 0px;
left: 0px;
z-index: 1000;
/*   margin: 30px; */
padding: 0;
background-color: transparent;
/*   border: blue 1px solid; */
width: 650px;
}

#SideBar {
padding: 0;
/*   border: blue 1px solid; */
position: absolute;
right: 0px;
top: 0px;
width: 250px;
z-index: 200;
}

/* Any container. */
.container {
background-color: #fff;
padding : 4em;
/*   border: red 1px solid; */
margin: 0;

}

/* paragraph */
p:first-letter {
text-indent: 1em;
}

p {
line-height: 1.2;
letter-spacing: 0.25em;
}

/* headline to left */
h1,h2,h3,h4,h5,h6 { text-indent: -1.3em; }



<html>
<head>
<link rel="stylesheet" type="text/css" href="./puredoc.css" />
<link rel="stylesheet" type="text/css" href="./puredoc_skin.css" />
<link rel="stylesheet" type="text/css" href="./gen-essay-skin.css" />

</head>
<body>
<div id="MainContainer">

<div id="TopBan" class="container">
Site title.
</div>
<div id="UnderContainer">

<div id="SideBar">
<div class="container">Sometext</div>
</div>
<div id="LeftPage">
<div class="container">
<h1>H1 title</h1>
<h2>h2 title</h2>
<p> p1</p>
<p>p2</p>
</div>

</div>
</div>
</div>



</body>
</html>

AMD APU Kaveri (A7700-K) * Linux

openSUSEのメーリングリストでご教示いただき、解決したので詳細を示そうと思う。

答はここに集約されている。今井さんによると

Kaveri等のプロプラなドライバを必要とする奴は

/etc/default/grubだったかのGRUB_CMDLINE_LINUX_DEFAULT=”nomodeset”ってしておくのが良いようです。

これをやっとけばブートパラメータで必ずnomodesetされますし。

ほぼnomodesetで通る、ようだ。実際にやってみたところ、

  • PCLinuxOS 2013.12 64bit KDE Fullmonty
  • Sabayon 14.01 KDE amd64
  • Linux Mint 16 x86_64
  • Korora20 x64_64
  • Chakra 2014.02 64bit

のいずれも、通常起動ではGrubのあとはディスプレイ信号が消え、ディスクも停止し、反応もなくなるのだが、nomodesetならば正常に起動した。

ただし、PCLOSについてはXが起動せず、Chakraはsnmpd起動時にものすごく待たされるが、これは別の問題だ。PCLOSに関しては、ビデオドライバまたはカーネルによって解決することだろう。2013.12とやや古いことが、古いカーネルを使っているという問題になるのかもしれない。

さて、nomodesetとは何か?調べてみると、そのものズバリな答がArch Wikiにあった。

Catalystドライバを使っているときなど、ブランクスクリーンになったりディスプレイに”no signal” エラーがでたりするなどの理由で KMSを無効にしたい時があるかもしれません。KMSを無効にするには、カーネルパラメータに nomodeset を追加します。詳しくは Kernel parameters (日本語) を見て下さい。

どうも、openSUSEで「NoKMS」オプションを選択することで起動できる、というのはこのあたりからきているようだ。

そしてMageiaの/boot/grub/menu.lstを見てみると、nokmsbootという値がある。しかし、nomodesetとの違いは何かと思いそれを調べてみると大半はMageia関連の記事で、FedoraやArch, Gentooでもひっかかることはひっかかるもののはっきりしたことが分からない。カーネルのドキュメントを検索してもこれについてはヒットしない。結局それについてはよくわからないままとなった。

おそらくは起動時のみKMSを無効にするのだろうと想像はつくが、推測の域を出ない。

さて、nomodesetのブート時の指定方法だが、最近流行りのグラフィカルなものは大体legacy Grubのようだ。Fキーによってメニューを出すタイプだ。これは、F3を押して「起動オプション」を選択したあとESCで戻ると起動オプションが編集できるようになっている。値はスペース区切りなので、スペースで区切ってnomodesetを追記してEnterキーで起動できる。eで起動オプション編集に行けないので戸惑う。もしかしたらもっとスマートな方法があるのかもしれない。

Grub2はeで編集に行くと複数行になっているので戸惑うが、linuxという行の最後に追加する。

DeleGateでHTTPSリバースプロキシ

私のサイトはずっとhttpsで接続できなかったのだけれど、ようやく手を入れることにした。

HTTPSによる接続自体はできるのでサーバーは動いているし、ファイアウォールも阻害していない。証明書関連の問題だと判断できる。

DeleGate + SSLについての情報は大概が古く、SSLwayについてしか言及されていない。DeleGateの最新マニュアルを見ると、STLSというビルトインTLSフィルタを持ち、またビルトイン匿名証明書を持つため証明書も不要であるように思える。ではどう使うのか??

jfuruyaのブログに答があった。DelegateのパラメータとしてSTLS=”fcl,fsv:https”を渡す必要があるのだ。しかしこれだとHTTPでアクセスするとはじかれる。ちなみに、SERVER=httpではhttpsで接続しろと言われる。マニュアルを確認、どうもSTLS=”-fcl,-fsv:https”であるべきであるということが分かった。

しかしそのままでいくとスタイルシートが表示されない。どうやら、httpsでページを表示しているのにhttpでスタイルシートをロードしているのが問題らしい。つまり、リンクはhref=”http://…”ではなく、一般には説明されない書式でスキームを維持するhref=”//…”形式にしなくてはいけないようだ。

とりあえずこのような特殊な接続をする人はいないと思うので、全体は修正していないが、ビルド時にテンプレートを変更するので、サイト全体をビルドする時には直る、はずである。