« 2014年5月 | トップページ | 2014年7月 »

2014年6月

2014年6月30日 (月)

コマンドラインオプションを用意したい

UNIX向けにコマンドラインオプションを用意したいと突然思いました。

毎回GUIを開いて、サーバに接続するのが面倒かもしれないので。

Qt AssistantでQApplicationクラスを見るとコンストラクタに引数argc, argvを渡して、いくつかのオプションは解析するようです。

気になったのは以下の3つのオプションです。

1, -style オプション GUIの見た目を変えられるそうです。古いWindowsとかMotifとか…

2, -reverse オプション レイアウトが左右逆転します。文字列自体は逆転しませんが、不思議な感じです。右から左に文字を書く言語向けでしょうか。

3, -widgetcount デバッグメッセージにどのwidgetから出たものかが表示されるそうです。デバッグ時に使えるかも。

QApplicationで解釈してくれるオプション以外は必要な物は自前で解釈しなくてはなりません。

コマンドラインオプションを解析するのは面倒なので、getoptを使おうと思いましたが、いろいろ対応できたほうが便利そうなので、GNUのgengetoptを使おうと思います。このツールを使うとC言語向けの解析部分を生成してくれるそうです。

gengetoptの最新は2.22.6みたいです。cygwin/x64上でコンパイル、インストールしました。

cygwinの最新make (4.0)だと

"*** 複数のターゲットパターンです. 中止."

となるので、少し古いmakeか、さらに最新make(例えばMinGW-W64に付属の4.0.90)を使うと問題なくコンパイル/インストールできました。

/usr/local/binにgengetoptコマンドが入りますので、これを使って.cのソースファイルを生成します。

まず、使い方を調べなければいけませんね。man gengetoptを実行します。

パッケージのdocディレクトリを見るとC++での利用サンプルソースがあるようです。あと生成されるソースファイルのサンプルもあります。参考になりそうですね。
man以外にもtexinfoやhtmlのドキュメントも見られるようです。ちょっと眺めてみます。

doc/sample1.ggo

にあるような定義ファイルをまず書くみたいです。gengetoptの-i オプションで指定します。

ここまで来て、今更ですが、ヘルプメッセージは日本語化したいですね。その処理だけQtの多言語対応を使いたいです。

そのためには、gengetoptでソースファイルを生成する時に"-n"もしくは"--no-handle-help"を指定すれば、自動では処理関数が追加されず、その関数だけ自前で定義するようにできそうです。

さて、次はオプションの定義ファイルのフォーマットを調べます。

んー、このオプションの定義ファイルとヘルプメッセージの内容の整合性をとることを考慮すると、自前で簡単なオプションの管理クラスを作ったほうが管理が楽そうな気がしてきました。

(追記)

アプリケーションの設定情報を管理しているクラスにオプション解析その他もろもろを追加しました。gengetoptはこのアプリケーションには少しオーバースペックで、getoptはロースペックということで、作ったほうが早い、という結果に落ち着きました。GUIでの接続操作なしで起動後に接続します。

仕様は以下の様な感じです。パスワードが生なのが少し気にはなるのですが…

-server <server name|IP address>:<password>[:<port no>]

サーバ名(IPアドレス)とパスワードは必須。ポート番号は省略可能。省略時は55500を設定する。

各要素は":"で区切る。
パスワードに空文字は入れられない。(要検討)
ポート番号は1 - 65535の整数値とする。

exp)

-server 192.168.10.1:mcz-xoxo
-server 192.168.10.1:mcz-xoxo:55500
-server urd-PC:mcz-xoxo
-server urd-PC:mcz-xoxo:30000

-version (-v)

バージョン情報を表示する。

アプリケーション名、バージョン、プラットフォーム(OS, ホストタイプ)などを表示する。

-debug < on | off >

デバッグログ出力を制御する。

-help (-h)

コマンドラインオプションのヘルプを表示する。

今日リリースされたBrynhildr 1.0.3への接続は一応確認しました。サウンドの遅延、ノイズに関してはまだ確認していません。

Andoroid NDKをDownloadする、Apache Antもね…

Android NDKをダウンロードします。Qtのページからリンクを辿ります。

http://developer.android.com/tools/sdk/ndk/index.html

2014 Marchにリリースされた"r9d"というのが今の最新らしいです。Linux用なので、Linux 64bit (x86)というtar.bz2ファイルをダウンロードしました。

昔zipで固められたいたアーカイブは今はtar.bz2になっているようですね。Windowsは変わらずzipですね。

cd /opt
sudo tar xvfj android-ndk-r9d-linux-x86_64.tar.bz2

で/optに展開しました。

シンボリックリンクを張って、"/opt/android-nkd"でアクセスできるようにしました。mvしてもいいんですが,新しいバージョンがリリースされた時に前のバージョンもとっておきたいので、その時はシンボリックリンクを張り直します。

sudo ln -s android-ndk-r9d android-ndk

最後に環境変数PATHに"/opt/android-ndk"を追加します。

「Additional Download」としてC++の「STL debug info」がありますが、STLライブラリを使っていてデバッグしたい時に必要そうです。が、いまのところ必要なさそうなので、必要になったらDownloadしてunzipした後、上書きすればよいようです。

最後に"Apache Ant"をDownloadします。Qtのリンクを辿ります。

http://ant.apache.org/bindownload.cgi

「Apache Ant 1.9.4」が最新らしいです。

リンク「apache-ant-1.9.4-bin.tar.bz2」をクリックして最寄りのサイトからダウンロードしました。

cd /opt
sudo tar xvfj apache-ant-1.9.4-bin.tar.bz2
sudo ln -s apache-ant-1.9.4 apache-ant

で同じく/optに展開して、シンボリックリンクを張りました。/opt/apache-antでアクセスできます。

環境変数PATHに"/opt/apache-ant/bin"を追加すればよさそう。

とりあえず、Qtのページで必須とされていたパッケージが入ったと思いますが…これから確認します。
Eclipse ADT付きがあった方がいいのでしょうかね?

Windows版なら以下からAndroid SDK付きなADT付きEclipseがダウンロードできますね。
4.4 Lunaではなく4.3 Keplerだと思われます。

http://developer.android.com/sdk/index.html#win-bundle

以下が同梱されているようです。

 ・Eclipse + ADT plugin
 ・Android SDK Tools
 ・Android Platform-tools
 ・A version of the Android platform
 ・A version of the Android system image for the emulator

Android向けアプリケーション開発に必要なすべてが同梱されているそうです。

With a single download, the Eclipse ADT bundle includes everything you need to begin developing apps:

(追記)

「VIEW ALL DOWNLOADS AND SIZES」をクリックすると、Linux (32/64bit)版のADT bundleも提供されていました。

2014年6月28日 (土)

メッセージの管理について考える その後

メッセージダイアログ表示とログファイルの管理クラスを作りましたが、そのことについて書いてませんでした。

メッセージダイアログの出力種類は、Qtのメッセージを参考にして以下のようにしました。

(1) critical : 処理継続不可能な場合
(2) warning : 警告を表示して処理を継続する場合
(3) information : 一応お知らせをしておく場合
(4) question : 動作の選択を依頼する場合

ログファイルの管理については以下のようにしました。

openLogFile()/closeLogFile()で適当なタイミングで出力用のストリームをオープン/クローズする。
ログは出力用ストリームがオープンされていれば出力するが、オープンされていなければなにもしない。

出力する情報は以下。

(1) フェーズ名
(2) メッセージの種類 (critical/warning/information/question/normal)
(3) 時刻(ローカルタイム)
(4) メッセージ本体

ソースコードファイル名、位置(ライン数)、メッセージ番号の付加は今回は見送り。

メッセージは必要な部分は翻訳可能とする。(とりあえず、日本語と英語)
文字コードはUTF-8で固定、ログファイルは常に追記モードでオープンする。

こんな感じでログが出ます。

[brynhildr] : : 2014.06.28 10:19:24.997 : 起動しました。
[brynhildr] : : 2014.06.28 10:19:41.923 : 終了しました。

デバッグ用のログはこんな感じ。

[brynhildr] : : 2014.06.28 11:04:19.776 : 起動しました。
[debug] : : 2014.06.28 11:04:31.451 : Shutdown : 2014.06.28 11:04:31.451
[debug] : : 2014.06.28 11:04:31.451 : Total Frame Counter : 0
[debug] : : 2014.06.28 11:04:31.451 : FPS : - fps
[brynhildr] : : 2014.06.28 11:04:31.451 : 終了しました。
[brynhildr] : : 2014.06.28 11:06:10.664 : 起動しました。
[debug] : : 2014.06.28 11:06:10.664 : [Brynhildr()] CurrentPath: D:/home/masaaki/Src/qtbrynhildr/src
[debug] : : 2014.06.28 11:06:10.664 : [Brynhildr()] QLocale::system().name() : ja_JP
[debug] : : 2014.06.28 11:06:10.668 : Boot : 2014.06.28 11:06:10.664
[brynhildr] : : 2014.06.28 11:06:13.770 : デバッグログ出力モードです。
[debug] : : 2014.06.28 11:06:21.923 : [openConnectionToServer()] encryption_key:mokeke
---------------- Settings ----------------
Server Name : "urd-PC"
Server Type : "SERVER_TYPE_WINDOWS_XP"
Port No : 55500
Password : "1A4A946C5D1D8A54"
Control : false
Graphics : true
QUALITY : "QUALITY_MAXIMUM"
Sound : true
QUALITY : "QUALITY_24K"
CAPTURE : "CAPTURE_CORE_AUDIO"
------------------------------------------
Graphics Buffer Size (bytes) : 1048576
Sound Buffer Size (bytes) : 524288
------------------------------------------
DBG: output Graphics Data To File : false
DBG: output Sound Data To File : false
DBG: output Log : true
------------------------------------------
[debug] : : 2014.06.28 11:06:51.926 : [control] error().
[debug] : : 2014.06.28 11:07:12.941 : [control] error().
[control] : : 2014.06.28 11:07:19.938 : 通信エラーが発生しました。
[control] : : 2014.06.28 11:07:21.042 : 通信エラーが発生しました。
[debug] : : 2014.06.28 11:07:21.043 : [control] Time out.
[debug] : : 2014.06.28 11:07:38.801 : [control] close().
[debug] : : 2014.06.28 11:07:38.801 : Shutdown : 2014.06.28 11:07:38.801
[debug] : : 2014.06.28 11:07:38.801 : Total Frame Counter : 0
[debug] : : 2014.06.28 11:07:38.801 : FPS : - fps
[brynhildr] : : 2014.06.28 11:07:38.801 : 終了しました。

Andoroid SDKをDownloadする

とりあえず環境構築のための環境はVMware Workstation上のUbuntu 14.04 LTSにしました。実機PCが必要なら、同じ手順でやればいいということで。

Qtのページからリンクを辿ります。

http://developer.android.com/sdk/index.html

Linux用は「VIEW ALL DOWNLOADS AND SIZES」をクリックしてすればリストが表示されますね。

ADTというやつがついたものとSDKのみ(32bit/64bit同梱)があります。

とりあえずSDKのみでいいでしょうかね。ダメならやり直せばいいし。

SDK Tool Onlyの「android-sdk_r23-linux.tgz」をダウンロードしました。

ダウンロードを開始するとすぐに「インストールの仕方」のページに移動するので、これを読んで適当な場所にSDKを展開するみたいです。どこに置くのがいいんでしょうかね…

Qtが/optにあるので、とりあえず/optにでも展開します。

cd /opt
sudo tar xvfz android-sdk_r23-linux.tgz

(注) 自分のホームの下なら"sudo"なしで大丈夫ですね。/opt下は管理者権限がないとだめです。

android-sdk-linux

が現れました。SDKは日々改善されているので、最新にする必要があるそうです。

cd android-sdk-linux
sudo ./tools/andoird update sdk

途端に以下のメッセージが表示されました。

./tools/android: 1: ./tools/android: java: not found
./tools/android: 1: ./tools/android: java: not found
./tools/android: 110: exec: java: not found

javaがない…。ま、入れてませんからね(。・w・。 )

とりあえずjavaコマンドを実行してみます。

「javaコマンドはないよ。このパッケージなんじゃない?」

と表示されるので、とりあえずjavaの実行環境だけ入れてみます。

sudo apt-get install default-jre

終わったら、再度updateを実行します。

なんかウィンドウが出てきました。最新版のチェックが終わると、[install 15 package]というラベルのボタンが出てきます。15個のパッケージが更新されているようです。

[install xx package]をクリックして、アップデートを実行します。

「あれ、8つしかアップデートされていないな」 一回のアップデートで全部更新されないこともあるようです。

「もう一度アップデートしておけ」と押したら、ダウンロードのパッケージ名に「Preview」とか出ているので、本当は必要なかったのかもしれません。ま、余分に入る分にはいいかなと思って放置します。
# 「install package」ボタンが無効化になったら、もう最新ですので「バツ」ボタンを押してウィンドウを閉じます。

Qtのページにjava v6以降が必要と書いてあったので、ここでjava7を入れておきます。一応sunのjavaを入れましょうか。
# 先ほど入れたjavaの実行環境JREはopenJDKぽかったですが…
# java version "1.7.0_55"
# OpenJDK Runtime Environment (IcedTea 2.4.7) (7u55-2.4.7-1ubuntu1)
# OpenJDK 64-Bit Server VM (build 24.51-b03, mixed mode)

sudo aptitude install sun-java7-jdk

aptitudeがない場合は事前に入れなければいけませんね。

sudo apt-get install aptitude

で入ります。

javacを端末から使う場合はもう少し設定が必要ですが、また必要になったら設定します。

とりあえず、Android SDKとJDKが入りました…まだ半分も終わっていません。

(追記)
javacというコマンドを実行すると以下のように出ます。

プログラム 'javac' は以下のパッケージで見つかりました:
* default-jdk
* ecj
* gcj-4.8-jdk
* openjdk-7-jdk
* gcj-4.6-jdk
* openjdk-6-jdk
次の操作を試してください: sudo apt-get install <選択したパッケージ>

いずれかのパッケージを入れたらjavacコマンドが使えるようになりますが、OpenJDKが使えると書いてあったので、

openjdk-6-jdk, openjdk-7-jdk

あたりがいいかもしれませんね。sun-java7-jdkでなにか支障があったらopenjdk-7-jdkあたりも検討しましょうか。

(追記2)
と、思ったのですが、今後のことも考えて、jdkとしてOpenJDKを入れました。

sudo apt-get install openjdk-7-jdk

javacコマンドを実行するとオプションの説明が日本語で出ます。(*^-^)

2014年6月27日 (金)

Qt Brynhildr (仮称) for Linux (Ubuntu 14.04 LTS)

操作できない版( ̄ー ̄)ニヤリ
# 意図的に封印しています(嘘です)


[x64版 バイナリのみ]

「qtbrynhildr_ubuntu1404_jp_005_20140628.tar.xz」をダウンロード

[x86版 バイナリのみ]

「qtbrynhildr_ubuntu1404_x86_jp_005_20140628.tar.xz」をダウンロード

Brynhildrは"パブリックモード"である必要があります。brynhildr.iniの"publicmode=0"を"publicmode=1"に書き換えます。詳細はBrynhildrの開発ブログを御覧ください。
#やっぱり音が遅れますな。

しばらくAndroid版の作業にシフトします。

Android用にQt Brynhildr (仮称) をビルドする、ための準備をする

実機を持っていないので、動作確認はエミュレータに頼らざるを得ません。

QEMUベースのエミュレータがあるらしいのですが、最新の情報を集めないといけないでしょうね…
Andoroidそのものを修正したい時もあるかもしれないので、Linux上がよいようです。

Windowsを離れて、しばらくUbuntuで生活してみます…まずは、3.15.2にアップデートしてから。

2014年6月24日 (火)

Qt Brynhildr (仮称) for Android

なんか、新しいこともないので、Androidで作ってみます。(いつまで、”仮称”…)

WindowsかLinux上に開発環境と実行(シミュレータ)環境を作らないとなりません。

とりあえず、"Get Start with Qt for Android"を読みましょう。

http://qt-project.org/doc/qt-5/androidgs.html

なにやら、たくさん用意しないとダメみたいです(;ω;)

1, The Android SDK Tools

2, The Android NDK

3, Apache Ant v1.8 or later

4, Java SE Development Kit (JDK) v6 or later. You can also use OpenJDK on Linux.

5, On Windows, you need the following additional installations:

MinGW v4.8.0 revision 2

Android Debug Bridge (ADB) driver on the Windows platform to enable USB debugging. The default USB driver on Windows does not allow debugging. For details about how to get the USB driver, see
http://developer.android.com/sdk/win-usb.html.
After installing the driver, try running a few basic adb commands and check whether your device responds to it.

ん、まずは基本的なAndroidアプリケーション開発について勉強しないといけないですね…

買っておいた以下の本を眺めてみます。

「基礎から学ぶ組み込みAndroid」 C&R研究所
「組み込みAndroidエキスパートテクニックブック」 C&R研究所

せっかくなので以下もさらっと。

「Inside Android Androidのなかみ」 パーソナルメディア

明日は忙しいしなぁ…

再起動のたびにウィンドウがズレます

気にはなっていたのですが、再起動のたびにウィンドウがズレます。

メインウィンドウは、左上の位置(x, y)とサイズ(高さ、幅)という情報で保存しています。

settings->getSettings()->setValue(QTB_GEOMETRY, geometry());

この記述は「入門Qt4プログラミング」からコピーしたものをそのまま使ってました。
関数geometry()はQMainWindowsクラスのメソッドです。QRectというクラスを返してくれます。

で、この保存した情報を復帰する記述が以下です。

// restore geometry
QRect rect = settings->getSettings()->value(QTB_GEOMETRY,
QRect(200, 200, 800, 600)).toRect();
move(rect.topLeft());
resize(rect.size());

move()で位置を指定し、resize()でサイズを再設定します。ところが、この記述だと、起動のたびにどんどん下に移動していきます。かなり気持ち悪いです。

おかしいなぁと思い、Qt AssistantでQMainWindowを眺めていると、geometry()という関数以外に

frameGeometry()

というよく似た関数が存在することに気づきました。なんか怪しいので、frameGeometry()のところを見ると"Window Geometry"というリンクが張ってありました。これをクリック。

frameGeometry()はどうやら、Window Titleといったフレーム部分を含んだ形で位置、サイズ情報を返すようです。一方geometry()はフレーム部分を含まないウィンドウの位置、サイズ情報を返すようです。

再生時に使うmove(), resize()にはどの情報を使えばよいのでしょうか…これもQMainWindowのドキュメントで確認します。

結局move()で使う位置情報はフレーム込みの位置情報、サイズはフレームを含まないウィンドウのサイズということが分かりました。単純にgeometry()で帰ってくる位置、サイズ情報を保存してはタメだということのようです。

// save geometry
QRect geometryInfo(QPoint(frameGeometry().x(), frameGeometry().y()),
             QSize(geometry().width(), geometry().height()));
settings->getSettings()->setValue(QTB_GEOMETRY, geometryInfo);

とすればよいようです。何事もコピペではダメだということですね…

(追記)

Windowsだと上記で大丈夫そうですが、Ubuntuだとまだズレます。位置情報のx,yにそれぞれ10足した情報をUbuntuの場合だけ保存する必要がありそうです。うーん…

2014年6月23日 (月)

せっかくだからDoxgenを勉強するぜ その1

ソースコードへのコメントを今はワンラインコメント("//")で入れています。
あまりに貧弱な英語力のため、詳細な説明は全然入っていません。

コード自体がシンプル(なにもしていない)なので、たぶん最低限のコメントで問題ないかと思うのですが…

リファクタリングしながら、コメントを書こうかなと思いたち、Doxygenで勉強してみようかと思います。

コメント部分に必要なフォーマットで説明を入れると、自動で設計ドキュメントなどが生成されるそうです。

日本語のマニュアルが以下にありました。

http://www.doxygen.jp/manual.html

Cygwin64では、全パッケージを入れるとDoxygenパッケージがインストールされます。Ubuntuでは、

sudo apt-get install doxygen

とすれば関連パッケージがインストールされます。

ですので、最初の「セクション インストール」はスキップして「セクション はじめよう」から始めます。

ここでは大まかな流れが説明されています。

大昔に「javadoc」用コメントは書いたことがあったのですが、なんとなく似てます。少し違うのは、関数の先頭とかで大きなコメントとしていろいろ書く傾向ではなく、関数/変数の定義・宣言のところにそれぞれの説明を分けて書くと
いう傾向にあるということでしょうか。

「関数宣言の直前にあるコメントは、関数に関する説明だろう」
「変数宣言の直後にあるコメントは、変数に関する説明だろう」

というふうに、大雑把にソースコードを眺めて、関連付けてくれるみたいです。

2014年6月22日 (日)

パスワードが見えています

Qt Designerで作成した「接続ダイアログ」ですが…パスワードを打つとそのまま打った文字が表示されます。
時々打った文字列を見たいことはあるのですが、デフォルトで見えるのはまずそうです。

Qt Designerを起動して確認すると、lineEdit_password(QLineEdit)の"echoMode"というパラメータがその動作を決めているようです。GUIの部品をクリックし、"echoMode"を"Password"に変更しました。

ヘッダファイル内では、以下のようにセットされています。ここを動的に変えれば、パスワードの内容をそのまま表示するようにもできそうです。が、とりあえず初期設定では生のパスワードを表示しないようにしました。

ヘッダーファイル(ui_connect_to_server_dialog.h)には以下のような記述が追加されます。

lineEdit_password->setEchoMode(QLineEdit::Password);

20140622_164617


2014年6月19日 (木)

進捗記録 2014.6.19

記録のためUbuntu版だけアップロード。
1MBをはるかに超えるWindows版(17MB)はココログにアップロード不可でした(;ω;)

Qt Brynhildr (仮称) for Ubuntu 14.04 LTS (Linux 64bit)

<削除しました>

Qt Brynhildr (仮称) for Ubuntu 14.04 LTS (Linux 32bit)

<削除しました>

(追記1)

Qt Brynhildr (仮称) for Windows 8.1/8/7 (64bit版)は、ローカルホームサーバにひっそりと置きました。
機能的にはBrynhildrを超えるものではないので、興味のある方だけに…#いるのか(*^-^)

2014年6月18日 (水)

配布用に必要なファイルを探しました

現時点でWindows用バイナリに添付すべきQt5.3のダイナミックリンクライブラリです。

Qt5.3.0/5.3/mingw482_32/bin/icudt52.dll
Qt5.3.0/5.3/mingw482_32/bin/Qt5Core.dll
Qt5.3.0/5.3/mingw482_32/bin/Qt5Gui.dll
Qt5.3.0/5.3/mingw482_32/bin/Qt5Multimedia.dll
Qt5.3.0/5.3/mingw482_32/bin/Qt5Network.dll
Qt5.3.0/5.3/mingw482_32/bin/Qt5Widgets.dll
Qt5.3.0/5.3/mingw482_32/bin/libgcc_s_dw2-1.dll
Qt5.3.0/5.3/mingw482_32/bin/libstdc++-6.dll
Qt5.3.0/5.3/mingw482_32/bin/libwinpthread-1.dll
Qt5.3.0/5.3/mingw482_32/bin/icuin52.dll
Qt5.3.0/5.3/mingw482_32/bin/icuuc52.dll
Qt5.3.0/5.3/mingw482_32/bin/icudt52.dll
Qt5.3.0/5.3/mingw482_32/plugins/platforms/qwindows.dll
Qt5.3.0/5.3/mingw482_32/plugins/imageformats/qjpeg.dll

Qt Brynhildr (仮称) Windows 8.1 update 用パッケージの内容です。
右の数字はファイルのサイズです。

1334 dist_win81/doc/window81update.txt
48640 dist_win81/bin/libwinpthread-1.dll
117262 dist_win81/bin/libgcc_s_dw2-1.dll
242176 dist_win81/bin/imageformats/qjpeg.dll
760320 dist_win81/bin/Qt5Multimedia.dll
970766 dist_win81/bin/libstdc++-6.dll
1273856 dist_win81/bin/platforms/qwindows.dll
1411584 dist_win81/bin/Qt5Network.dll
1579008 dist_win81/bin/qtbrynhildr.exe
1992280 dist_win81/bin/icuuc52.dll
3347428 dist_win81/bin/icuin52.dll
4584448 dist_win81/bin/Qt5Gui.dll
4785664 dist_win81/bin/Qt5Core.dll
5881856 dist_win81/bin/Qt5Widgets.dll
23544786 dist_win81/bin/icudt52.dll

以下はVC++2010の再配布用のファイルです。Qt5.3.0/vcredist/vcredist_sp1_x86.exeにあります。

4995416 dist_win81/vcredist/vcredist_sp1_x86.exe

dllとフォルダplatforms、imageformatsは実行ファイルと同じ並びに置く必要があるので注意が必要でした。

(追記)

Windows 7 Home Premium (64bit) でも最低限の動作だけ確認できました。

2014年6月17日 (火)

テクノロジープレビューという名の人柱作戦

# テクノロジーってほどのものではないですが…

今のところキーボード操作もマウス操作もできませんが、Windowso8.1updateとUbuntu 14.04 LTS 日本語Remix (64bit/32bit)で試せるバイナリを作ってはみましたが…どこにアップロードしようかと迷っております。

インストーラではないし、Brynhildrの使い方について説明もしませんが、試そうとする人がどれだけいるのか、なぞです。紙芝居が見たい方ですかね。

とりあえず知り合いに頼みますかねぇ…

どんな感じかをお伝えするため、以下に簡易Readme.txtを付けます。

=============================================================================================

[Windows 8.1 update]

 実行ファイル、Qt5.3のダイナミックリンクライブラリ、VC++2010の再配布用パッケージを7zで固めたもの

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

!!!!!!!!!!お試し版のため完全無保証、再配布禁止です。!!!!!!!!!!

qtbrynhildr_win81_003_20140619.exe

----------------------------------------------------------------------
[install]
----------------------------------------------------------------------

1) 自己解凍アーカイブを展開する。

2) 必要なら以下のVC++2010の再配布ファイルをインストールする。

dist/vcredist/vcredist_sp1_x86.exe

3) dist/binにパスを通す。

4) dist/bin/qtbrynhildrを実行する。

----------------------------------------------------------------------
[unsinstall]
----------------------------------------------------------------------

1) レジストリエディタで"mcz-xoxo"を探して削除する。

恐らく以下です。

HKEY_CURRENT_USER\Software\mcz-xoxo

2) dist以下を削除する。

----------------------------------------------------------------------
[Note]
----------------------------------------------------------------------
いくつか不具合が見つかっていますが、まだ直してません。
サウンドが遅れて再生されるでしょう…
なにも操作できないのはバグではありません、現在の仕様です(^_^;

(*) この説明で、わからない人はもう少しお待ちください。
--------------------------------------------------------------------------------------

=============================================================================================

[Ubuntu 14.04 LTS 日本語Remix版]

 実行ファイルをbbzip2で圧縮したもの


!!!!!!!!!!お試し版のため完全無保証、再配布禁止です。!!!!!!!!!!

qtbrynhildr_ubuntu1404_jp_003_20140619.tar.bz2

----------------------------------------------------------------------
[install]
----------------------------------------------------------------------

1) Qt5.3をインストールします。

http://download.qt-project.org/official_releases/qt/5.3/5.3.0/qt-opensource-linux-x64-5.3.0.run

2) libglu1-mesa-dev パッケージをインストールします。

sudo apt-get install libglu1-mesa-dev

2) バイナリを解凍します。

tar xvfJ qtbrynhildr_ubuntu1404_jp_003_20140617.tar.bz2

3) 起動します。

./dist_ubuntu/bin/qtbrynhildr

4) 起動して、エラーが出たら、必要なパッケージをインストールして、3)へ戻ります。


----------------------------------------------------------------------
[unsinstall]
----------------------------------------------------------------------

1) 以下を削除してください。

~/.config/mcz-xoxoとdist_ubuntu以下

2) 気になる人は以下もアンインストールしてください。

Qt5.3, libglu1-mesa-dev

----------------------------------------------------------------------
[Note]
----------------------------------------------------------------------
いくつか不具合が見つかっていますが、まだ直してません。
サウンドが遅れて再生されるでしょう…
なにも操作できないのはバグではありません、現在の仕様です(^_^;

(*) この説明で、わからない人はもう少しお待ちください。

今朝ハマったこと

今朝ハマったこと。

クラスの定義に関数outputLogMessage()を追加しました。

classt LogMessage : public QMessageBox
{
// normal log message
void outputLogMessage(PHASE_ID id, const QString text);

private:
QTextStream *logFileStream;
};

クラスの実装ファイル(.cpp)に定義をコピーして、中身を書きました。


// normal log message
void outputLogMessage(PHASE_ID id, const QString text)
{
  (*logFileStream) << phaseName[id]  << text << endl << flush;
}

makeしましたが、errorになりました。

logmessage.cpp: In function 'void brynhildr::outputLogMessage(brynhildr::PHASE_ID, QString)':
logmessage.cpp:168:5: error: 'logFileStream' was not declared in this scope
   (*logFileStream) << phaseName[id] << text << endl << flush;
     ^
Makefile.Debug:2295: recipe for target 'debug/logmessage.o' failed
mingw32-make[1]: *** [debug/logmessage.o] Error 1
mingw32-make[1]: Leaving directory 'D:/home/masaaki/Src/qtbrynhildr/src'
Makefile:48: recipe for target 'debug' failed
mingw32-make: *** [debug] Error 2

「logFileStreamという変数が見つからないよ」と言われます。
何度見返しても、logFileStreamという変数は定義してあります。綴りも合っています。

答えは、エラーメッセージ内に書かれていました。

void brynhildr::outputLogMessage(brynhildr::PHASE_ID, QString)

です。関数outputLogMessage()がグローバルな関数になっています。

正しくはvoid brynhildr::LogMessage::outputLogMessage()になるはずです。

つまり、以下のように書く必要がありました。コピ&ペーストするとこんなこともありますね…
クラスに属さない関数なのですから、クラス内の変数にアクセスできるはずがありません。


// normal log message
void LogMessage::outputLogMessage(PHASE_ID id, const QString text)
{
  (*logFileStream) << phaseName[id] << text << endl << flush;
}

朝から疲れました…

QStringからconst char *を取得する

QStringで管理している文字列を古いインタフェースで渡したい時にconst char *に変換する必要がありました。

検索すると以下の様な方法が書かれているページを見つけました。

コンストラクタがCipher(const char *)なのです。QStringで渡して、中で処理しろよというツッコミはあると思いますが。

// bootTime
bootTime = QDateTime::currentDateTime(); // 現在の日時情報を得る

// create cipher 現在の日時情報の文字列を暗号化キーにして暗号化機能を準備する
QByteArray bootTimeStr = bootTime.toString().toUtf8();
cipher = new Cipher(bootTimeStr.constData());

で、あとで「入門Qt4プログラミング」を眺めていたら、qPrintable()というマクロがあると書かれていました。
QStringのインスタンスからconst char *を取得できると…

// bootTime
bootTime = QDateTime::currentDateTime();

cipher = new Cipher(qPrintable(bootTime.toString()));

とシンプルになりました。qPrintable()の中身を見たほうがよいと思うのですが、そこはいつかみてみたいと思います(*^-^)

今後の機能を妄想する

今後の機能の妄想です、スルーしてください。

Brynhildrの基本機能に追加したい項目。


1. デスクトップのスナップショット

もともと、Mortion JPEGでデスクトップ動画を実現しているので、実現は容易。今はデバッグ用に特定ファイル名でJPEGファイル残す機能がある。


2. サウンドのキャプチャ

PCMデータをそのまま残すだけならデバッグ機能で可能だが、MP3などのCompress Audioにも対応できるといいかも。プラグイン化できるといいなぁ。


2. デスクトップをそのまま動画としてファイルに出力

 たくさんのJPEG画像をMP4などに変換する処理が必要。JPEG画像ファイルをどこかに連番のファイル名で貯めて、録画停止した時点で変換する。(できたら別スレッドで)PCMデータはテンポラリファイルに残しておいて、利用する。変換処理を行うライブラリ or APIを探す必要がある。


3. デスクトップのコントロール(キーボード、マウス操作などの入力デバイス)を記録、再現する機能

コントロール用の通信データを保存すれば、再現は可能そう。単純に全通信データを残せばいいかは要検討。


4. デスクトップの任意の場所をズームアップする機能

QtのViewport指定で容易にできそう。具体的なインタフェースが要検討。


(関係ない話)

昨日リリースされたStable Linux-3.15.1でも問題なさそう。

2014年6月16日 (月)

MinGW-w64を試しましたが

Qt5.3に含まれるMinGW-w64はgcc-4.8.2ベースです。

MinGW-w64 project 日本語のページ(http://sourceforge.jp/projects/sfnet_mingw-w64/)を見ると4.8.3ベースのものがあるようです。

gcc-4.9.0ベースのものもありますが、今はi686(32bit)向けだけで、64bit(x64)向けには用意されていないようです。
というわけで、新しいものに興味があるので、gcc-4.8.3ベースのMinGW-w64をダウンロードしてみました。
# インストーラでインストールするバージョンを選択できます。

http://sourceforge.jp/projects/sfnet_mingw-w64/downloads/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/installer/mingw-w64-install.exe/

PATHを通して、makeしてみましたが、ダイナミックリンクライブラリのリンク処理で"incompatible"と言われてリンクできませんでした。というわけで…結局Qt5.3に付属のMinGW-64w(4.8.2ベース)を使い続けるという結果に終わりました。

普通に標準ライブラリレベルで使う分には4.8.3も使えると思われます。

2014年6月15日 (日)

間違えてました、Emacsさん

20年以上Emacsを使ってますが、間違えてました。

一行目に書くメジャーモードと文字コード指定のところです。
恥ずかしい。

(この指定を書くようにしたのは、今回からなんですよね…。これまでは文字コードとしてEUCを使っていたので、特にcodeing systemを指定する必要がなかったのです。記事に書いたソースファイルを修正しないと…)

// -*- mode: c++-mode; coding: utf-8-unix -*-

// -*- mode: c++; coding: utf-8-unix -*-

ファイルを開いた時に、「"c++mode-mode"という関数はないぞ」というメッセージが出ていたのですが、既読無視しておりました。

Ignoring unknown mode `c++-mode-mode'
File local-variables error: (void-function c++-mode-mode)

modeの所に書かれた文字列に"-mode"を後ろにくっつけた関数が自動的に呼ばれるようですが、"c++-mode"と書いちゃうと当然ですが"c++-mode-mode"というわけのわからない関数呼び出しになってしまうのですね…

数ヶ月の間頭の隅にひっかかっていた問題が、今日解けました…(*゚▽゚)ノ

2014年6月13日 (金)

ログファイルの機能を追加する オープンとクローズ

メッセージ・ダイアログの機能はQMessageBoxクラスを継承したので、おおよその目処はつきました。

あとはログファイルにメッセージを記録する仕組みの追加が必要です。

まず、ログファイルを書き込み用にオープンする/クローズする場所を決める必要がありますね。普通に考えるとコンストラクタでオープンして、デストラクタでクローズするのが良さそうですけど…。

LogMessageクラスインスタンスは、恐らくプログラム実行時に作成され、プログラム終了時に破棄されることになります。ですので、コンストラクタ/デストラクタに実装するとオープン/クローズするタイミングが限定されてしまいますね。

あと、設定ダイアログとかでログファイルを作る/作らないを切り替えた時に次回起動時以降にしかログ・ファイルが作成されないという仕様になってしまいます。それはあまりよろしくない気がします。

別にログファイルを作成開始(オープン)する関数とログファイルへのアクセス(書き込み)を終了する関数を設けたほうが良さそうです。

関数名はopenLogFile()/closeLogFile()でいいでしょうか。引数も検討しないと。

今はこんな感じでダイアログが出ます。内容は暫定ですが。

20140613_194005

呼び出し方はこんな感じです。


  // output message
  logMessage.criticalMessage(PHASE_BRYNHILDR,
                             tr("Password Error! Please check your password."),
                             LogMessage::Ok,
                             LogMessage::NoButton);

(*)お分かりだと思いますが、翻訳済みなので日本語で出てます。

openLogFile()/closeLogFile()の追加は後でやるとして、criticalなメッセージダイアログ出力の実装はもう可能になっています。

標準C++のfstreamを利用してほぼ書き上げたのですが、Qtの用意するQFileとQTextStreamを使ったほうがよいことに今更気づきました。今日はこれで終了します。

ログファイルとメッセージダイアログ出力

まだエラーメッセージダイアログは出せません。

アプリケーションの動作ログを出力する機能とエラーメッセージダイアログを出力する機能って似てますよね。 エラーを表示したら、そのログはログファイルに残っていて欲しいですが、ダイアログに出すほどのものでもないメッセージもログファイルには残したい時もあります。

こういう機能を持った部品があるとうれしいですね。

LogMessageクラスをこういうクラスにしたいです…、どうしたらいいんでしょうかね…

最初はこのLogMessageクラスにいろいろな変数や関数をどんどん書こうかと思いました。で、実際に書いたら、もう面倒になるほどいろいろ書かないといけないことに気づきました。

こんなこと、Qtで開発している人がみなやってるのかと疑問に思い、「入門Qt4プログラミング」を眺めます。

「おお」

なんだか詳細は分かりませんが、継承というテクニックを使えば良さそうです。

つまり、QtのQMessageBoxというクラス(部品)を取り込んで、これを拡張する形で、ログファイルにも出力する機能を追加すればよさそうです。

継承の恩恵がイマイチ、ピンとこなかったのですが、こういうことなんですねぇ。

大体こんな感じでしょうか?

[logmessage.h]
// -*- mode: c++; coding: utf-8-unix -*-
// Copyright (c) 2014 FunFun <fu.aba.dc5@gmail.com>

#ifndef LOGMESSAGE_H
#define LOGMESSAGE_H

// System Header

// Qt Header
#include <QMessageBox>
#include <QString>

// Local Header

namespace brynhildr {

// phase ID
typedef enum {
  PHASE_BRYNHILDR = 0,
  PHASE_CONTROL,
  PHASE_GRAPHICS,
  PHASE_SOUND,
  PHASE_NUM
} PHASE_ID;

class LogMessage : public QMessageBox {
 public:
  // constructor
  LogMessage(QWidget *parent);

  // critical message
  int criticalMessage(PHASE_ID id,
					  const QString text,
					  StandardButton buttons,
					  StandardButton defaultButton);
};

} // end of namespace brynhildr

#endif // LOGMESSAGE_H


[logmessage.cpp]
// -*- mode: c++; coding: utf-8-unix -*-
// Copyright (c) 2014 FunFun <fu.aba.dc5@gmail.com>

// System Header

// Qt Header
#include <QString>

// Local Header
#include "logmessage.h"
#include "settings.h"

namespace brynhildr {

// phase name
QString phaseName[PHASE_NUM] = {
  QObject::tr("[brynhildr] "),
  QObject::tr("[control] "),
  QObject::tr("[graphics] "),
  QObject::tr("[sound] "),
};

LogMessage::LogMessage(QWidget *parent)
{
}

// critical message
int LogMessage::criticalMessage(PHASE_ID id,
								const QString text,
								StandardButton buttons,
								StandardButton defaultButton)
{
  int ret;

  // output dialog
  ret = critical(this,
				 QTB_APPLICATION,
				 phaseName[id] + text,
				 buttons,
				 defaultButton);

  // TODO: output Log File

  return ret;
}

} // end of namespace brynhildr


今はcriticalなメッセージを扱うcriticalMessage()という関数しか追加していないのですがQMessageBoxの関数とか変数とかも同じように使えます。criticalMessage()にはまだダイアログを出す処理しか書いてません、別途受け取った引数を元にログファイルにログを出力する機能を追加しなくてはなりませんね。ま、ベースはできたので、少しづつ実装します。

2014年6月12日 (木)

進捗記録 2014.6.12

進捗記録

http://youtu.be/mQ2bXZmh7UQ

YouTubeだと画面が小さくてメニューを表示しても見えませんね…なにか対策があるのでしょうか。
oCamでキャプチャしたオリジナルのaviファイルは130MBもあるし。ローカルサーバに置くか…

メニューだけキャプチャ

1, PCMサウンドの再生が追いついていないので、再調査

2, エラーメッセージダイアログ出力およびログファイル出力機能の実装

3, その他もろもろの不適切な動作の確認と対策

2014年6月10日 (火)

サウンドの品質変更メニューを付けてみた

なんとなく思い立ったので、サウンドの品質を変えられるメニューを追加しました。
完全にコピペです。命名規則を決めているので、ほぼ記憶だけでコピペできました。
#記憶力が悪いので、命名規則は合わせておかないとプログラミングが進みません。

いつでも変更可能ですが、Brynhildrサーバさんが応じてくれるかは、分かりません。

20140610_112619

統一性がないので、「表示」メニューを「ビデオ」メニューに変更しました。

lupdateコマンドを実行すると以下のように出ます。

$ lupdate -verbose brynhildr.pro
Updating 'translations/brynhildr_ja_JP.ts'...
Found 30 source text(s) (1 new and 29 already existing)
Kept 1 obsolete entries

「Display」に関する記述が時代遅れだよと言われますが、気にならなければそのままでもよいようです。私は気になったので、エディタで.tsファイルを開いて該当の箇所を手動で削除しました。Linguist(もしくはlupdateコマンド)からもできるのかもしれませんが。("Display"で検索しました)

(追記)
lupdateコマンドに"-no-obsolete"オプションを与えればよいようです。

$ lupdate -verbose -no-obsolete brynhildr.pro
Updating 'translations/brynhildr_ja_JP.ts'...
Found 30 source text(s) (0 new and 30 already existing)


[修正後]

20140610_113923

今現在選択している画質、音質がどのレベルなのか、分かりませんね…メニューの左側がアイコン用に空いているので、ここに表示するようにすれば良さそうです。アイコンを書く芸術的センスがない…な、無料の素材をもらってくるしかないでしょうかね。調べてみないと。

(追記)
チェックマークを付ける機能はQtのQActionクラスに用意されていて、アイコンを書く必要はありませんでした。
setCheckable(true)で有効化し、setChekrd(true)/setChecked(false)で選択/非選択の設定をするようです。

// Sound Quality Action 8K
soundQuality_8K_Action = new QAction(tr("Sound Quality: 8000Hz"), this);
soundQuality_8K_Action->setCheckable(true);
soundQuality_8K_Action->setChecked(settings->getSoundQuality() == SOUND_QUALITY_8K);
soundQuality_8K_Action->setStatusTip(tr("Sound Quality: 8000Hz"));
connect(soundQuality_8K_Action, SIGNAL(triggered()), this, SLOT(setSoundQuality_8K()));

新規にログ・メッセージ用のソースファイルを追加する

必要そうなソースファイルを追加して、とりあえずビルドできるか試します。シンプルでコンパイルできるであろう形を作成して、早めにビルドしてみる方が近道だと思います。できるだけ小刻みに。

で.proファイルに.hファイル、.cppファイルを追加して

qmake brynhildr.pro

を実行して、"make debug"します。
ビルドできたので、これにいろいろ追加していきます。多分使うことが分かっているクラス(QMessageBox)のためのヘッダーファイルのインクルードとコンストラクタだけ書きました。

[logmessage.h]

// -*- mode: c++; coding: utf-8-unix -*-
// Copyright (c) 2014 FunFun <fu.aba.dc5@gmail.com>

#ifndef LOGMESSAGE_H
#define LOGMESSAGE_H

// System Header

// Qt Header
#include <QMessageBox>

// Local Header

namespace brynhildr {

class LogMessage {
 public:
  // constructor
  LogMessage();
};

} // end of namespace brynhildr

#endif // LOGMESSAGE_H


[logmessage.cpp]

// -*- mode: c++; coding: utf-8-unix -*-
// Copyright (c) 2014 FunFun <fu.aba.dc5@gmail.com>

// System Header

// Qt Header

// Local Header
#include "logmessage.h"

namespace brynhildr {

LogMessage::LogMessage()
{
}

} // end of namespace brynhildr

メッセージの管理について考える

メッセージの管理について考えました。

いろいろ考えるのには、やはり手を動かすほうが頭が回るので、手書きです。
画像データは検索対象にならないのがデメリットですが、それは仕方ないかと。

そのうち、画像認識して、検索対象にされる日が来る(すでに来ている)かもしれませんが…

Qtb_pic2

字が汚くて恥ずかしいですが、暫定仕様としてはこのくらいでもいいかと思います。
早速暫定実装をしようかな、と。

2014年6月 9日 (月)

エラー処理(メッセージ表示)が入っていない

#「Sunaba」が一段落付いたので…

サーバー接続先として、ホスト名もしくはIPアドレスを指定できますが、VMware上の仮想マシンで走るWindowsXPはDHCPによるIP取得のため、IPが変わってしまうことがあります。その際接続に失敗するのですが、おもむろにbash windowにエラー(error)が表示されますが、GUIとしては全くうんともすんともいいません。

とりあえず、これでは使ってもらうわけにはいきませんね。

サーバへの接続に失敗することは、かなり重要なエラーなので、適切にユーザに知らせる必要がありますね。

で、「入門Qt4プログラミング」を流し読みした記憶を辿り、「なんかメッセージを出すクラスがあったよなぁ」ということを思い出しました。

P.63あたりでしょうか。すでに使っていました。QMessageBoxというクラスです。

「このアプリケーションについて」ウィンドウを出したい時は、QMessageBox::about() を、

「ワーニング(Warning)メッセージ」を出したい時は、QMessageBox::warning() を、

「重要(critical)なメッセージ」を出したい時は、QMessageBox::critical() を、

実行すればいいらしいです。その他には、

QMessageBox::information() : 一般的な情報
QMessageBox::question() : 質問
QMessageBox::aboutQt() : Qtについて

などがありますね。

引数にはメッセージの内容、ウィンドウに出すボタンの種類などいろいろ渡せるのですが、これについてはQt AssistantでQMessageBoxを検索して、確認できます。渡せる引数は大体同じ内容なので、1パターン覚えれば大丈夫ではないでしょうか。

例えば、「このアプリケーション」ダイアログは以下のようにして出しています。

// display About Dialog
void Brynhildr::about()
{
  // display About Message Box
  QMessageBox::about(this,
					 "About " QTB_APPLICATION,
					 "<h2>"
					 QTB_APPLICATION
					 " Ver. "
					 QTB_VERSION
					 "</h2>"
					 "<p>Copyright ©"
					 " "
					 QTB_YEAR
					 " "
					 QTB_ORGANIZATION
					 " powered by MCZ.");
}

20140609_225334

エラー処理では重要なメッセージとして表示する必要があるので、QMessageBox::critical()を使うべきだと思われます。ちょっとこれから実装してみます( ^ω^ )

(追記)
場当たり的に実装するのは簡単なのですが、メッセージの管理がいずれ煩雑になります、そのあたりも含めての実装になるので、少し時間がかかるかも知れません…

ぜんぜん関係ありません

QtもBrynhildrも関係ないので、スルーしてください。

「プログラムは技術だけでは動かない」という本を読みました。

いちいち、「そうだよなぁ」と同意することばかりです。著者の方は私の少し上の世代の方のようですが、同じように

「なんでこんな非効率的な開発のススメ方を無理やりするのかな…」

と理解できないことがたくさんありました。

「デスマーチになるだろ、このプロジェクト」

と確信できましたね。大きなプロジェクトになればなるほど、フットワークは重くなって、無駄な会議で時間は浪費される…と。

プロジェクトは優秀な技術者数人で始めるのが、一番楽しいですね…多分。

あと、「プログラムはこうして作られる プログラマの頭の中をのぞいてみよう」という本も今読んでます。
著者はセガ(Sega)の社員の方で、「ゲームプログラマになる前に覚えておきたい技術」という本も書かれています。

入門書が好きで、時々新しく出た面白そうな入門書を読むのですが、この本で紹介されている「Sunaba(砂場)」というプログラミング言語の難解さにショックを受けて、立ち止まっております。ぴゅー太以来の日本語プログラミング言語で、動揺を隠せません(*^-^)

この言語を紐解くために、Qt Brynhildr(仮称)の開発はしばらく中断するかもしれません( ^ω^ )

2014年6月 8日 (日)

なんとなく体裁が整ったので

操作できそうですが、できません(;ω;)

Windows 8.1 update [MinGW + OpenGL + Qt5.3] です。

http://youtu.be/hhScpi8zwtI

(*) 音はサーバ側でミュートしています。

[サーバ接続前]

20140608_220353

[サーバ接続後]

20140608_220434

[接続ダイアログ]

20140608_222705

(追記)
「表示(Display)」メニューで画質を選択できますが、通信プロトコルを見ると接続中でも画質を変えられそうなので、メニューは常に選択可能状態になっています。あまり、途中で画質を下げたり、上げたりすることがあるのかわかりませんが、別に接続開始時に決めてしまう必要もないので、接続中も変更可能になってます。

音声の品質も同様だと思われますが、こちらはBrynhildrサーバさんが最適な品質にしてくれるようなので、メニューとして実装していません。どうしたほうがいいかは考え中です。接続時に決めるだけでいいのかもしれません。

やっぱり暗号化をします

crypto++によるパスワード暗号化保存ですが、やはりパスワードを記憶したいという人は居ますよね…

パスワードをメモリに記憶する際は常に暗号化、ヘキサコード化した文字列を置くようにします。
レジストリ保存時もですね。

crypto++の最適化レベルをO3にすれば、リンク後の実行ファイルはリリースバージョンで1.5MBに抑えられるのでスタティックリンクすることにしました。(少なくともMinGW版では、ですが)

外部ライブラリ(libcryptopp.a)をリンクするために.proファイルに以下のように記述を追加しました。

LIBS += -L../lib/cryptopp562 -lcryptopp
INCLUDEPATH += ../lib/cryptopp562

起動時にQDateTimeインスタンスを取得し、この時刻情報の文字列を種に暗号化クラスCipherを生成します。これで、起動するたびに暗号化の種データが変わるので、少し安全になるのではないでしょうかね。

…次回実行時レジストリからのパスワード情報復帰時に時刻が変わってしまうので、種が変わってしまいマズイですね…どうしよう。

(追記)
パスワードのレジストリ記憶を確認していたら、Linuxで.confファイルが更新されない不具合が見つかりました。

QSettings::setValue()で情報を書き込むのですが、Qt5.2.1で保存できていた情報がQt5.3になって保存されなくなりました。Windows(registryへの保存)では問題ありません。#本当にQt5.3への更新が原因かは不明ですが…

結局、必要な時にQSettings::sync()を呼び出して、任意のタイミングで明示的に書き込み処理を実行するのが礼儀ということみたいです。

<参考>
http://stackoverflow.com/questions/23027181/qsetting-doesnt-works-fine-for-me

.confファイルは以下のようになりました。

[General]
graphicsBufferSize=1048576
onControl=false
onGraphics=true
onSound=true
outputGraphicsDataToFile=false
outputLog=false
outputSoundDataToFile=false
password=E9C082A40E00B0D38441DE82597158F5
portNo=55500
serverName=urd-PC
serverType=0
soundBufferSize=524288
soundCapture=1
soundQuality=24000
videoQuality=9

2014年6月 7日 (土)

進捗記録 2014.6.7

ちょっと、進捗記録の間隔が短すぎる?

入力デバイスの制御以外の暫定実装を終わったかもしれないバージョンとして記録します。
#"0.03"って、刻みすぎ。

ソースコードは3,000行程度。Brynhildrサーバに接続して、デスクトップを眺めることが出来ます(◎´∀`)ノ

確認した環境は、Windows 8.1 update, Windows 7 Home (x64), Ubuntu 14.04 LTS 日本語Remix (64bit)です。

Windowsの確認環境はMinGW-4.8.2 + OpenGL 版ですが、VC2013+OpenGL、VC2013(native)でも作成できるはず…

潜在的にはWindows (32/64bit), Mac OS X, Linux (32/64bit), Android, iOS (iPhone, iPad, etc)、その他ですが…確認できてません。
FreeBSDでQt5.3を、と思う今日このごろですが。

20140607_190031

以下はWindows 8.1 update 版のキャプチャ動画です。

http://youtu.be/veQSUlH4Mu8

最後にbashにちらっと表示される"error()"は、バグでした。修正しました(´・ω・`)ショボーン

Qt Designerを使ってみる その4

設定ダイアログのデザインがいまいちしっくりこないなぁ、と思っていましたが、「入門Qt4プログラミング」を眺めていて、ふと気づきました。

「レイアウトマネージャーを全く無視しているんだけど」

「ダイアログのRADデザイン」という章を読んでいたのですが、斜め読み過ぎて、おざなりになりすぎたようです。
この章での表記はQt Designerが日本語化する前の表記らしく、ちょっとピンと来ていませんでした。

例えば、「Lay Out Horizontally」というメニューがあるのですが、Qt5.3のQt Designerでは「水平に並べる」です。水平方向の配置を管理する部品を配置し、その中にLabelやlineEditなどの部品を配置することで、水平方向の部品配置をうまく扱ってくれるようです。同様に「垂直に並べる」とかもあって、これらをきちんと使えば、ウィンドウをリサイズしたり、Linuxにもっていくとラベルが切れたりしなくなるようです。

あと、スペーサ(水平方向)とか言う部品も使いました。隙間をうまく調整してくれるようです。

20140607_105302

いろいろ部品をいじって、保存し、"mmake debug"とかすると、勝手にソースコードを生成しなおして、ビルドしてくれます、便利ですね。

20140607_105619

傍目には、クールになったとは言いがたいのですが、バランスとしては少しマシです(*^-^)

Linux (Ubuntu) 版は以下のような感じです。

20140607_123319

(追記)

今頃ですが、この設定情報って「設定」ではないですね…「ファイル」メニュー → 「サーバに接続」と選択して接続のために毎回出るって情報のような気がします。「ファイル」メニューに「サーバに接続」を追加して、そこから「接続ダイアログ」を表示するようにしたいと思います。
#今は関数main()の最後辺りにハードコーディングしてます。


  // for TEST
  SettingDialog *dialog = new SettingDialog;
  dialog->show();

とりあえず「サーバに接続」、「サーバから切断」を「ファイル」メニューに追加すれば、起動して、紙芝居を見られるツールとして使ってもらえるのかもしれません。リモートデスクトップソフトとしては、操作できないと意味ないですが(^-^;

上記が実装できたら、インストールパッケージを作ってみようかと。(Linux (Ubuntu)での音の遅延はちょっと対策したいです…)
しかし、Windows用インストールパッケージはともかく、Ubuntu用debパッケージの作り方が分からないな…

2014年6月 6日 (金)

Qt Designerを使ってみる その3

設定ダイアログを表示するだけだったので、キーの入力などに反応するように、環境を少しだけ整えました。

Qt Designerを使って、プロパティを書き換えました。

ダイアログのオブジェクト名を「SettingDialog」に変更。 それぞれのGUI部品の名前をわかりやすく変更。例えば、

lineEdit -> lineEdit_hostname
comboBox -> comboBox_hosttype
spinBox -> spinBox_portno
lineEdit_2 -> lineEdit_password


という感じです。

spinBoxの属性変更。

minimum 0 -> 1
maxmum 99 -> 65535

QAbstractSpinBoxの属性を以下のように変更。

alignment 横方向 左端揃え -> 右端揃え

今思いつく所はこんなもんでしょうか。なにかあったら、またQt Assistantで調べて変更しましょう。

lineEdit_passwordは、生のテキストでなく"******"というふうに表示されたほうがいいとかも要検討でしょうかね。

http://youtu.be/vj29ylEFglw

それにしても、デザインが素人丸出しですね…困った(^-^;

Qt Designerの出力した"ui_setting_dialog.h"というソースファイルを利用して、SettingDialogという新しいクラスを作ったのですが、これに関しては「入門Qt4プログラミング」のP.31あたりに書いてありますね。って、これで分かるのでしょうか…

[settingdialog.h]


#ifndef SETTINGDIALOG_H
#define SETTINGDIALOG_H

// Qt header
#include <QDialog>

// Local Header
#include "ui_setting_dialog.h"

namespace brynhildr {

class SettingDialog : public QDialog, private Ui::SettingDialog
{
  Q_OBJECT

 public:
  // Constructor
  SettingDialog(QWidget *parent = 0);

  private slots:
	void on_lineEdit_hostname_textChanged();
	void on_comboBox_hosttype_currentIndexChanged(int index);
	void on_spinBox_portno_valueChanged(int i);
	void on_lineEdit_password_textChanged();
};

} // end of namespace brynhildr

#endif // SETTINGDIALOG_H


[settingdialog.cpp]


// System Header
#include <iostream>

// Qt header
#include <QDialog>

// Local Header
#include "settings.h"
#include "settingdialog.h"

using namespace std;

namespace brynhildr {

SettingDialog::SettingDialog(QWidget *parent)
  : QDialog(parent)
{
  setupUi(this);

  // setting
  // for hosttype
  comboBox_hosttype->insertItem(SERVER_TYPE_WINDOWS_XP,		"Windows XP");
  comboBox_hosttype->insertItem(SERVER_TYPE_WINDOWS_VISTA,	"Windows Vista");
  comboBox_hosttype->insertItem(SERVER_TYPE_WINDOWS_7,		"Windows 7");
  comboBox_hosttype->insertItem(SERVER_TYPE_WINDOWS_8,		"Windows 8");
  comboBox_hosttype->insertItem(SERVER_TYPE_WINDOWS_8_1,	"Windows 8.1");
}

void SettingDialog::on_lineEdit_hostname_textChanged()
{
  cout << "text Changed : hostname" << endl;
}

void SettingDialog::on_comboBox_hosttype_currentIndexChanged(int index)
{
  cout << "index Changed : hosttype" << endl;
}

void SettingDialog::on_spinBox_portno_valueChanged(int i)
{
  cout << "value Changed : portno" << endl;
}

void SettingDialog::on_lineEdit_password_textChanged()
{
  cout << "text Changed : password" << endl;
}

} // end of namespace brynhildr

2014年6月 5日 (木)

進捗記録 2014.6.5

Linux (Ubuntu 14.04 LTS) で 「Setting」ダイアログを出してみました。

ラベルが全部出ていないです…、日本語対応はまだしていません。
カーネルは3.14.5です。

oCamをv23に上げたら、デフォルトの動画形式が変わってしまっているようです。YouTubeでアップロード時に警告が出ました。実際アクセスすると普通に再生されるのですが、ちょっと気持ち悪いですね。旧バージョンに戻すべきか…

あと、キャプチャー時にキャプチャ範囲のガイドラインが消えてしまうのが、あまり嬉しくないですね。オプションで戻せるのか調べてみたいと思います。

Ubuntu 14.04 LTS 動画キャプチャ
(http://youtu.be/ghWgiu1We_A)

20140605_094905


暗号化についても考えてみる その6

crypto++を利用して、パスワードを暗号化、復号化するためのクラスを作ってみました。名前は「Cipher」、まんまですね。といっても公開されていたサンプルを焼き直しただけです。

crypto++のフォルダにある"*.h"をすべて、ディレクトリ"./include"にコピーして、作ったライブラリ"libcryptopp.a"をディレクトリ"./lib"にコピーしました。

クラスの実装コードにテスト用のmain()を書きまして、生のパスワードと暗号化して16進数表示に直した文字列を表示するようにしてみました。

コンパイルしますと(実際は何度もコンパイルエラーを出して、直しました…)。

g++ -O2 -v -I./include cipher.cpp -L./lib -lcryptopp -o cipher
$ ./cipher
plain  text: mcz-xoxo
encode text: F48BF948DC9763F783A75275011D8C75
encode text: F48BF948DC9763F783A75275011D8C75
plain  text: mcz-xoxo


なんとなく暗号化、復号化できてるっぽいですね。実行ファイルのサイズは、どれくらいですかね…

$ ls -al cipher.exe
-rwxrwxr-x 1 masaaki masaaki 12865908 6月   5 08:14 cipher.exe


12MB…もある。たった数10行のコードでですか?crypto++のGNUmakefileを確認すると、

CXXFLAGS = -DNDEBUG -g -O2
となってますね。"-g"なのでデバッグコードが入ってます。リリース時は外していいのではないでしょうかね…

CXXFLAGS = -DNDEBUG -O2


変更して、"libcryptopp.a"を作りなおして、もう一度cipher.exeをコンパイルしますと、

$ ls -al ./cipher.exe
-rwxrwxr-x 1 masaaki masaaki 3400324 6月   5 08:17 ./cipher.exe
3MBちょっとですか。やはり、まだ大きいですね…。使っている".o"だけがリンクされるはずですが、それだけいろいろな処理をしているということらしいですね。

と、ここまでやって、思い直しました。

「パスワード保存しなくていいのでは?」と。「保存すると、危険なだけかも」

というわけで、大きなライブラリをリンクして、わざわざ危険なパスワードの保存をすることに意味があるのか、というところに落ち着いてしまいました。このようにしてregistryへのパスワード保存をやめました…(^-^;
#この記事必要なの?っていうツッコミは気にしない。
現在のリリースバージョンのファイルサイズは、200KB(MinGW-4.8.2)です。

$ ls -al release/qtbrynhildr.exe
-rwxrwxr-x 1 masaaki masaaki 203776 6月   4 22:16 release/qtbrynhildr.exe
以下のコードはご参考ということで。 [cipher.h]
#ifndef CIPHER_H
#define CIPHER_H

// CryptoPP Header
#include "cryptlib.h"
#include "modes.h"
#include "filters.h"
#include "hex.h"
#include "des.h"

using namespace CryptoPP;

namespace brynhildr {

class Cipher {
 public:
  // Contructor
  Cipher(const char *key);

  string encodeString(string plain);
  string decodeString(string decoded);

 private:
  ECB_Mode<DES>::Encryption encctx;
  ECB_Mode<DES>::Decryption decctx;
};

} // end of namespace brynhildr

#endif // CIPHER_H



[cipher.cpp]
// Common Header
#include "common.h"

// System Header
#include <cstring>
#include <iostream>

// Local Header
#include "cipher.h"

using namespace std;

namespace brynhildr {

// Constructor
Cipher::Cipher(const char* key)
{
  byte cryptkey[DES::DEFAULT_KEYLENGTH];

  memcpy(cryptkey, key, DES::DEFAULT_KEYLENGTH );
  encctx.SetKey(cryptkey, DES::DEFAULT_KEYLENGTH );
  decctx.SetKey(cryptkey, DES::DEFAULT_KEYLENGTH );
}

string Cipher::encodeString(string plain)
{
  string cipher, encoded;

  // cipher
  StringSource(plain, true, 
			   new StreamTransformationFilter(encctx,
											  new StringSink( cipher )
											  )      
			   );

  // hex encode
  StringSource(cipher, true,
			   new HexEncoder(new StringSink(encoded)
							  )
			   );
  cout << "plain  text: " << plain << endl;	
  cout << "encode text: " << encoded << endl;	

  return encoded;
}

string Cipher::decodeString(string encoded)
{
  string decoded, recovered;

  // hex decode
  StringSource(encoded, true,
			   new HexDecoder(new StringSink(decoded) 
							  )
			   );

  // cipher decode
  StringSource(decoded, true,
			   new StreamTransformationFilter(decctx,
											  new StringSink( recovered )
											  )
			   );

  return recovered;
}

} // end of namespace brynhildr

using namespace brynhildr;

int main(int argc, char* argv[])
{
  Cipher cipher("Soul Gem");

  string encoded = cipher.encodeString("mcz-xoxo");
  cout << "encode text: " << encoded << endl;	
  string plain = cipher.decodeString(encoded);
  cout << "plain  text: " << plain << endl;	
}

2014年6月 3日 (火)

Qt Designerを使ってみる その2

前回作った"setting_dialo.ui"をせっかくなので、GUIというディレクトリを作って、そこに入れました。
カレントにボコボコ置いてるのは、ちょっと気が引けますね。

で、この"setting_dialog.ui"から、この作ったダイアログを表示するためのソースコードを取り敢えず作ってみます。
えっと、「入門 Qt4 プログラミング」のP.30あたりを眺めてみますと、qmake -projectで.proを作って、qmake xxxx.proを実行しろと書いてありますね。

qmake -project [return]

永遠に終了しません…Ctrl-Cで強制終了。

qmake -project -norecursive [return]

終わりました。が、src.proとかいうファイルが出来てはいるものの、中身はさっぱり…です。".ui"ファイルも反映されていません。
# src.proというのは、カレントフォルダ名が反映されるみたいですね。カレントフォルダがtestならtest.proというファイル名になるらしいです。

早速、googleさんにお伺い。

http://doc.qt.digia.com/4.6/designer-using-a-ui-file.html

古いQt(4.6)のドキュメントが引っかかりました。なんか、このページの中程を見てゆくと、.proファイルの例が載っていますね。

TEMPLATE = app
FORMS = calculatorform.ui
SOURCES = main.cpp

このFORMSを.proに追加すれば、いいんじゃないですかね。

というわけで、手作業でbrynhildr.proをエディタで開いて以下を追加しました。

FORMS = GUI/setting_dialog.ui

さて、以下を実行します。

mmake brynhildr.pro [return]

お、Makefile.Debug/Makefile.Releaseが更新されています。

ui_setting_dialog.h というソースファイルもカレントに追加されてますね。これが自動生成されたダイアログ生成用のファイルのようです。

"setting_dialog.ui"というファイルからは"ui_setting_dialog.h"というファイルが生成されます。そういう規則みたいですね、ふーん。

中身は、こんな感じです。どこかで見たような文字列がありますね。翻訳のための準備も入ってそうです。
これを実際に使うには、もう少し手を加える必要があるらしいです。

続きを読む "Qt Designerを使ってみる その2" »

2014年6月 2日 (月)

Qt Designerを使ってみる

設定ダイアログ暫定版を作ってみることにしました。

Qt Designerを立ちあげて、以前保存したファイル"setting_dialog.ui"を「ファイル」メニューから読み込みました。

本格的な設定ダイアログはQt Designerの使用方法を理解した後にまた作りたいと思いますので、ショボイですが適当に作ってみます。

今回設定できる項目は、「ホスト名」、「ホストタイプ(Windows XP/Vista/7/8/8.1)」、「ポート番号」、「パスワード」の4つにしました。後はハードコーディングでもどうにかなりますので。

ホスト名(HostName)は、1行編集なので、「Line Edit」という部品で良さそうです。

ホストタイプ(HostType)は、XP/Vista/7/8/8.1から選択するので、「Combo Box」という部品でしょうか。

ポート番号(PoertNo)は、1~65535までの数値なので、「spin Box」にしました。

パスワード(Password)は、ホスト名と同様なので、これも「Line Edit」という部品で良さそうですね。

それぞれに対応するラベルを右側に設定して、以下のように配置しました。

20140602_174007

「label_1」とかだと分かりにくいので、「label_hostname」とかにわかりやすく変更しました。

後、「編集」メニューから「タブ順を編集」を選択して、部品のタブ順(Tab Order)を調整しました。
上から下に移動して、最後にボタンへ移動しするように編集します。

20140602_180802

実際のダイアログをプレビューしてみました。「フォーム」メニューから「プレビュー(P)」を選びます。
以下のように実際のダイアロ・グウィンドウが表示されます。少しショボイですね、やはり。

20140602_174021

「タブ順」を一応確認します。あれ、spinBoxで、直接数値は入力できませんね…spinBoxってそういう部品でしたっけ?

「QWidget」のプロパティ「windowTitle」を「Dialog」から「Setting」に変更しました。

20140602_181335

もう少し、各部品のプロパティの調整が必要そうです。

部品の位置、サイズ、プロパティの変更は簡単に行えるので、時々ファイルを保存しながら、いろいろやってみます。アクセラレータキーも付けたいし、もう少しカッコよくしたいですよねぇ(*^-^)

暗号化についても考えてみる その5

Doxgenドキュメントを読んでみることを早速断念し、googleさんのお世話になりました。

crypto++を使った暗号化/復号化について書かれた方がいらっしゃいました。

http://d.hatena.ne.jp/yutakikuchi/20131115/1384471222

掲載されていたTPをコピー&ペーストして、実行してみました。

$ g++ -I. tp.cpp -L. -lcryptopp

$ ./a.exe
encode text: B374EB12891FFF5C538281C88A612D522F2CE61360BA5B6776EB2A32E77E5C66B42978BA11B1C5E3
recovered text: 魔法少女まどか☆マギカ

encode textの後に出力された文字列が、暗号化された文字列ですね。これをレジストリに保存するようにしましょう。Brynhildrサーバさんにパスワードを送る時は、recovered text:の後にあるように復号化した文字列を取得して、これを送ればいいですね。

DES × ECBという方式の例が示されているのですが、これでよいかは再考の余地があると思います。まずは、使い方の勉強なので、公開されているこのTPを眺めてみます。

レジストリは以下のようになります。

20140602_111751


2014年6月 1日 (日)

進捗記録 2014.6.1

ソースコードの内容記録です。#はコメントです。Makefileの方がはるかに大きいです(*^-^)
(Note) '#' is comment.

$ ls -al *
-rw-rw-r--    26650 5月  27 15:37 brynhildr.cpp		# brynhildr class for main process
 drawing jpeg stream for Desktop and playing PCM sound stream and control with Input Devices.)
-rw-rw-r--     3588 5月  15 19:48 brynhildr.h
-rw-rw-r--      640 5月  22 20:09 brynhildr.pro		# made by qmake and written by hand.
-rw-rw-r--      148 5月  22 21:04 brynhildr.qrc		# resource file for Qt
-rw-rw-r--      517 5月  27 15:34 common.h
-rw-rw-r--     1437 5月  27 15:43 main.cpp		# main function only
-rw-rw-r--     2025 5月  14 08:25 mainwindow.cpp	# main window GUI
-rw-rw-r--      898 5月  13 18:27 mainwindow.h
-rw-rw-r--    22501 5月  28 18:45 Makefile
-rw-rw-r--   121216 5月  28 18:45 Makefile.Debug
-rw-rw-r--   121350 5月  28 18:45 Makefile.Release
-rw-rw-r--      916 5月  19 15:26 parameters.h		# parameters for brynhildr
-rw-rw-r--      630 5月  15 21:13 protocols.h		# protocol for brynhildr
 (include machine/protocols_x86.h or machine/protocols_x64.h)
-rw-rw-r--     9793 5月  28 20:05 settings.cpp		# for user setting infromations
-rw-rw-r--     4707 5月  27 15:53 settings.h
-rw-rw-r--     4343 5月  27 15:35 soundbuffer.cpp	# implementation of ring buffer for sound
-rw-rw-r--      512 5月  14 21:31 soundbuffer.h
-rw-rw-r--     1948 5月  28 22:30 TODO.txt		# to do memo
-rw-rw-r--      717 5月  13 23:00 util.h		# assertion macro and so on.
-rw-rw-r--      303 5月  23 08:31 version.h		# information for version displays

debug:		# debug version folder MinGW and Qt5.3
合計 5316
drwxrwxr-x+        0 5月  28 20:06 .
drwxrwxr-x+        0 5月  27 15:35 ..
-rwxrwxr-x    465490 5月  28 19:18 brynhildr.o
-rwxrwxr-x    364787 5月  28 19:18 main.o
-rwxrwxr-x    514261 5月  28 19:18 mainwindow.o
-rwxrwxr-x      7603 5月  28 19:18 moc_brynhildr.cpp
-rwxrwxr-x    420856 5月  28 19:18 moc_brynhildr.o
-rwxrwxr-x      2812 5月  28 19:18 moc_mainwindow.cpp
-rwxrwxr-x    191208 5月  28 19:18 moc_mainwindow.o
-rwxrwxr-x    494940 5月  28 19:18 qrc_brynhildr.cpp
-rwxrwxr-x    104016 5月  28 19:18 qrc_brynhildr.o
-rwxrwxr-x   2419142 5月  28 20:06 qtbrynhildr.exe
-rwxrwxr-x    410073 5月  28 20:06 settings.o
-rwxrwxr-x     18287 5月  28 19:18 soundbuffer.o

images:
合計 96
-rw-rw-r--   93968 5月  13 18:27 3Bjunior.jpg		# for screen splash

machine:
合計 12
-rw-rw-r--   4038 5月  13 18:27 protocols_x64.h		# for 64 bit compiler
-rw-rw-r--   4027 5月  13 18:27 protocols_x86.h		# for 32 bit compiler

release:	# release version folder MinGW and Qt5.3
合計 956
-rwxrwxr-x    63058 5月  28 20:06 brynhildr.o
-rwxrwxr-x     6588 5月  28 20:06 main.o
-rwxrwxr-x     5283 5月  28 20:06 mainwindow.o
-rwxrwxr-x     7603 5月  28 20:06 moc_brynhildr.cpp
-rwxrwxr-x    18135 5月  28 20:06 moc_brynhildr.o
-rwxrwxr-x     2812 5月  28 20:06 moc_mainwindow.cpp
-rwxrwxr-x    10764 5月  28 20:06 moc_mainwindow.o
-rwxrwxr-x   494939 5月  28 20:06 qrc_brynhildr.cpp
-rwxrwxr-x    96936 5月  28 20:06 qrc_brynhildr.o
-rwxrwxr-x   199680 5月  28 20:06 qtbrynhildr.exe
-rwxrwxr-x    39092 5月  28 20:06 settings.o
-rwxrwxr-x     5401 5月  28 20:06 soundbuffer.o

translations:
合計 12
-rwxrwxr-x    844 5月  26 17:29 brynhildr_ja_JP.qm	# binary file for translation
-rwxrwxr-x   3007 5月  26 17:27 brynhildr_ja_JP.ts	# text file for translation

« 2014年5月 | トップページ | 2014年7月 »