« 2014年9月 | トップページ | 2014年11月 »

2014年10月

2014年10月28日 (火)

キーボードコントロールを実装しました その3

シフトキーが効かない原因がよく分からないので、キーボードコントロールの情報を見直しました。

キーボードの情報の主なところは操作したキーの仮想キーコードとキーのUP/DOWNの情報の2つです。

が、もうひとつありました…keydownという情報です。この情報、キーが押された or 離された時にのみ1になると思い込んでいましたが、もしかして違うのか…

zerosikikai.cppにkeydownの値を表示するprintf()を追加して再度ログを取りながら実行しました。

以下が出力です。

keydown = 1
keycode = 10     // SHIFT キーがPressされた
keycode_flg = ffffff80
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 41    // 'A'キーがPressされた
keycode_flg = ffffff80
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 41   // 'A'キーがReleaseされた
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 1
keycode = 00
keycode_flg = 00
keydown = 0
keycode = 10   // SHIFTキーがReleaseされた
keycode_flg = 00

どうやら、SHIFTキーが離されるまでkeydownが1にセットされているようです。サンプルソースの理解が足らなかったことが原因ですね…(;ω;)

keydownの値設定部分が少しだけ複雑なのですが、「こんな感じかなぁ」くらいの理解で実装を進めたのがマズかったですね。実際に通信させてみなければわからないことは多いのですが…

というわけで、SHIFT/ALT/CONTROLに関しては、この情報の適切な設定が必要ということのようです。

(追記)

SHIFT/ALT/CONTROLの各キーの状態を保存するようにして、キーが押されている時はkeydownを1にセットするように変更しました。SHIFT/ALT/CONTROLが正しく効くことは確認できました。

マウスとキーボード操作はなんとなくできるようになったのでクライアントとしては使えますが、まだ、やや不安定なのは否めません…調整が必要です。

2014年10月27日 (月)

キーボードコントロールを実装しました その2

キーボード情報が送れるようにはなったのですが、大きな不具合が見つかりました。

エディターで大文字の"A"が出せませんヽ(´▽`)/

シフトキーの情報がうまく送れていないようです。

[MainWindow] "JP" : Press : VK_Code = "VK_SHIFT" : 10
[MainWindow] "JP" : Press : VK_Code = "VK_A" : 41
[MainWindow] "JP" : Release : VK_Code = "VK_A" : 41
[MainWindow] "JP" : Release : VK_Code = "VK_SHIFT" : 10

Brynhildrサーバさんに送っているキーの押下情報を表示させてみましたが、送っている情報の値、順序としては問題なさそうです。

仕方ないのでサンプルソース(zeroshikikai.cpp)ではどのように情報が送られているか確認してみましょう。

制御用のスレッドのキーボード用情報の設定部分(450行目あたり)にprintf文を挿入しました。
(stdio.hのインクルードも必要です)

com_data.keycode = g_keyboard1[0];
com_data.keycode_flg = g_keyboard2[0];

printf("keycode = %02x\n", com_data.keycode); // これ
printf("keycode_flg = %02x\n", com_data.keycode_flg); // これ

確認用なのでお手軽なものを使えばいいですよね。Visual Studioからデバッグ実行しても標準出力は得られないのでコマンドプロンプトを使います。リダイレクトもしくはパイプを使えば端末 or ファイルに出力できるそうなので以下のようにしました。

d:\src\zerosikikai\zerosikikai\Debug>zerosikikai.exe > run.log

結果は以下のようになりました。ffffff80となってますがintに拡張されてしまったためなのでとりあえず放っておきます。

keycode = 10
keycode_flg = ffffff80
keycode = 41
keycode_flg = ffffff80
keycode = 41
keycode_flg = 00
keycode = 10
keycode_flg = 00

動作としては、

SHIFT KEY DOWN
A KEY DOWN
A KEY UP
SHIFT KEY DOWN

なので、値、順序も問題はなさそうです。

キーの押下時の情報だけでなく実際に送られるキーボード情報をすべて確認してみた方がよさそうです。

まず、zeroshikikai.cppの場合シフトキーを押した直後からの情報を出力させてみました。

keycode = 10
keycode_flg = 80
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 41
keycode_flg = 80
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 41
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 00
keycode_flg = 00
keycode = 10
keycode_flg = 00

キー操作の情報送信の間に結構空の情報(keycode = 00 and keycode_flg = 00)が送られていますね。

Qt Brynhildr (仮称)も同様に出力させて確認してみました。押すタイミングなどの差はありますが、やはりデータの値、順序としては問題なさそうです。

なにが違うのでしょうか…謎です。

マウスコントロールを実装しました その2

マウスカーソルの動きがダメな件ですが、そもそもマウスイベントをすべてバッファリングすること自体が問題でした。後から考えるとすでにサンプルソースにその解はあったのでした…

つまり、マウスのボタンとホイール操作はバッファリングしますが、マウスの位置情報は最新のみを保持しているということです。サーバに送る情報としてボタンを押したとかホイールを回転させたという情報は落とすことはできないのですが、マウスの位置情報はその軌跡が必要なのではなく、現在の位置情報だけが重要ということですね。

これまでマウスイベントをすべてバッファリングしていたため、細かいマウスカーソルの移動軌跡を逃さず保存して、それを順番に送っていたのです。マウスの移動イベントはかなり細かく発生するため、不必要に細かい移動軌跡を辿らせていたようです。

マウスの移動イベントのみを特別扱いし、最新の位置情報のみを保持するように変更しました。

やっとマウスが普通に使えるようになりました。

ローカルのマウスカーソルが同時に表示されてしまうのは、とりあえずQtのQApplicationクラスのメソッドで
クロスカーソルに変更して様子を見ます。

QApplication app(argc, argv);

// set cursor
app.setOverrideCursor(Qt::CrossCursor);

2014年10月25日 (土)

Qt5.3に付属のMinGW-4.8.2は32bitコンパイラでした…

すみません、元記事にも訂正を追記したのですが、Qt5.3.xに付属しているMinGW-4.8.2は64bit対応したprojectの成果物ではありますが、中身は64bitコンパイラではなくMinGW-W64 projectがリリースした32bitコンパイラでした。

Thread model: posix
gcc version 4.8.2 (i686-posix-dwarf-rev3, Built by MinGW-W64 project)

"by MinGW-W64 project"というところだけみて勘違いしていました(;ω;)

よくみると"i686"とちゃんと書いてありますよね…orz

2014年10月19日 (日)

キーボードコントロールを実装しました

QtのキーボードイベントをBrynhildrサーバさん向けの情報に変換して通信データにセットする処理を実装しました。
基本的なキー入力はできるようになりました。(特別なキーの情報は別途送る仕組みを実装する必要があります)

1,マウス・キーボードの動作チェック (特別なキーの情報の送信機能実装を含む)
2,通信エラー処理の正式対応実装
3,メッセージロギングの正式対応実装

Windows版リリースに向けて必要なこと。

・ドキュメントの整備
・インストーラ作成環境整備
・Windows 7 Home (64ビット)/8.1Professional update (64ビット)以外のWindowsでの動作確認
(持ってないので、できないだろうな…)

2014年10月18日 (土)

マウスコントロールを実装しました

QtのマウスイベントをBrynhildrサーバさん向けの情報に変換して通信データにセットする処理を実装しました。
これでようやくマウスカーソルの移動、ボタンのクリック/ダブルクリック、ホイールの回転は可能になりました。

ですが調整すべき点が2つ見つかりました。

1、Qtのマウスイベントのすべてを無条件で送るようにしたら、位置情報(x,y)が細かすぎて通信のスピードに追いつかない

マウス制御用の通信は1秒間に20回とかそんなレベルなんですがQtのマウスイベントはもっと細かいレベルで発生するのでマウスの動きがスローモーションのようになります。これは適度にデータを間引くことで対応可能かもしれません。一番いいのはQtのマウス情報のサンプリング間隔を調整できればいいのかな…

2、ローカルのマウスカーソルが同時に表示される

 Qtの設定で表示をdisabledにすることが可能かもしれません。調べないと分かりませんが。

キャプチャ動画は以下です。

マウスコントロール実装直後のテスト動画


時々画面が乱れるのはモーションJPEGとして送られてくるデスクトップ画像のデータが壊れていることがあるからみたいです、これも要確認ですね。

2014年10月17日 (金)

windows版インストーラを作成してみる

ちょっと道をそれまして、Inno Setupで暫定windows版インストーラを作成してみました。

まず、Inno Setupの最新版をインストールします。

http://www.jrsoftware.org/isinfo.php

インストールするとInno Setup用のスクリプトファイル(.iss)が関連付けされるので、インストーラ作成の設定を.issという拡張子で作成すればよいようです。

.issファイルがあるフォルダからの相対位置でファイルなどを指定するので、適切な位置におくようにした方がよいようです。

アタッシェケースの設定ファイルを参考に書いてみました。アイコンとかreadme.txtとかはまだないので設定していません。今はデスクトップにショートカットのみが作成されます。

qtbrynhildr.issというファイル名で作成し、同じ並びにbinフォルダを作成後本体の実行ファイルとQt5用のdllファイルを配置しました。


;----------------------------------------------------------------------
; QtBrynhildr installer script for Inno Setup
;----------------------------------------------------------------------
#define AppVer "0.08"
#define AppVerNum StringChange(AppVer, ".", "")

[Setup]
AppName=Qt Brynhildr
AppVersion={#AppVer}
AppVerName=Qt Brynhildr Ver.{#AppVer}
DefaultGroupName=Qt Brynhildr
OutputBaseFilename=qtbrynhildr-windows-{#AppVerNum}
DefaultDirName={pf}\QtBrynhildr
UsePreviousAppDir=yes
AppendDefaultDirName=yes
OutputDir=.\
TouchTime=03:15

;----------------------------------------------------------------------
; インストーラプログラム
;----------------------------------------------------------------------
VersionInfoVersion={#AppVer}
VersionInfoDescription=Qt Brynhildrをセットアップするプログラム
AppCopyright=Copyright(C) 2014 FunFun, All rights reserved.
;SetupIconFile=icon\main_icon.ico
;ウィザードページに表示されるグラフィック(*.bmp: 164 x 314)
;WizardImageFile=bmp\installer_pic.bmp
;ウィザードページに表示されるグラフィックが拡大されない
;WizardImageStretch=no
;その隙間色
;WizardImageBackColor=$ffffff
;ウィザードページの右上部分のグラフィック(*.bmp: 55 x 58)
;WizardSmallImageFile=bmp\installer_pic.bmp
;進捗表示
ShowTasksTreeLines=yes

;----------------------------------------------------------------------
;「プログラムの追加と削除」ダイアログ情報
;----------------------------------------------------------------------
;配布元
AppPublisher=FunFun @ mcz-xoxo
;アプリケーション配布元 Webサイトの URL
AppPublisherURL=http://xxxx.com/
;連絡先
AppContact=fu.aba.dc5@gmail.com
;サポートサイトURL
AppSupportURL=http://xxxx.com/support
;ReadMeファイルパス
;AppReadmeFile="{app}\readme.txt"
;製品更新先のURL
AppUpdatesURL=http://xxxx.com/software/qtbrynhildr/
;アプリケーションの説明
AppComments=A client for Brynhildr (public mode)

[Languages]
Name: japanese; MessagesFile: compiler:Languages\Japanese.isl

[Files]
Source: "bin\qtbrynhildr.exe"; DestDir: "{app}"; Flags: ignoreversion touch
Source: "bin\icudt52.dll"; DestDir: "{app}"; Flags: ignoreversion touch
Source: "bin\icuin52.dll"; DestDir: "{app}"; Flags: ignoreversion touch
Source: "bin\icuuc52.dll"; DestDir: "{app}"; Flags: ignoreversion touch
Source: "bin\libgcc_s_dw2-1.dll"; DestDir: "{app}"; Flags: ignoreversion touch
Source: "bin\libstdc++-6.dll"; DestDir: "{app}"; Flags: ignoreversion touch
Source: "bin\libwinpthread-1.dll"; DestDir: "{app}"; Flags: ignoreversion touch
Source: "bin\Qt5Core.dll"; DestDir: "{app}"; Flags: ignoreversion touch
Source: "bin\Qt5Gui.dll"; DestDir: "{app}"; Flags: ignoreversion touch
Source: "bin\Qt5Multimedia.dll"; DestDir: "{app}"; Flags: ignoreversion touch
Source: "bin\Qt5Network.dll"; DestDir: "{app}"; Flags: ignoreversion touch
Source: "bin\Qt5Widgets.dll"; DestDir: "{app}"; Flags: ignoreversion touch
Source: "bin\imageformats\qjpeg.dll"; DestDir: "{app}\imageformats"; Flags: ignoreversion touch
Source: "bin\platforms\qwindows.dll"; DestDir: "{app}\platforms"; Flags: ignoreversion touch

[Registry]
;(アンインストール時に)動作設定を削除
Root: HKCU; Subkey: "Software\mcz-xoxo\Qt Brynhildr"; Flags: uninsdeletekey

[Icons]
Name: "{commondesktop}\Qt Brynhildr"; Filename: "{app}\qtbrynhildr.exe"; WorkingDir: "{app}"; Tasks: desktopicon

[Tasks]
Name: desktopicon; Description: "デスクトップにショートカットアイコンを作成する"

この.issのファイルを作成し、エクスプローラからダブルクリックするとInno Setupが起動します。

20141017_163814

「Build」メニューから「Compile」を選ぶとインストーラの作成が開始されます。正常終了すると、.issファイルと同じフォルダにqtbrynhildr-windows-008.exeが出来上がりました。13MB程のサイズです。

Brynhildr(1.0.5)はexe+dllで400KBほどですが、インストール後サイズ48.3MBは昔なら受け入れられないですね…46.7MBはQt5のランタイムではあるのですが。

実行させるとこんな感じです。

20141017_161556


20141017_161559


20141017_161602


20141017_161605


20141017_161607


20141017_161612


アンインストールも出来ます。削除するとすべてのファイルとレジストリが削除されることを確認しました。

20141017_161624

ライセンスなどの表示のためにreadmeは追加しないといけませんねぇ。

2014年10月16日 (木)

音がやっとまともに聞けました

なんだかんだで半年かかって、やっと曲がまともに聴けるようになりました。

画像との同期はまだ全然取っていませんが、Windows版では遅延は感じませんね。Brynhildrサーバさん側である程度やってくれてるようです。(バージョンは先日公開された1.0.5です)

Windows版 0.08 テスト動画

ちょっとウィンドウサイズが正しくないですけど、そこはまだ完全な実装ではないので調整の範囲だと思います。

ノイズがのっていないのはやっぱりいいですね。プチノイズは精神衛生上よくないです。多分シングルスレッドでコントロール/画像/音の3つの通信をやっているうちは多分だめだったでしょう…恐らく。

現在は3つの通信をマルチスレッドで処理しています。PCMデータの再生用バッファはbuffer underrunの発生もなく満たされ続けているようです。

音がちゃんと出るとなんかやる気が出てきますねぇ…Linuxでも試してみますかね。

2014年10月15日 (水)

windows版インストーラ作成ツールを変更する

結構前にwindows版インストーラ作成ツールを検討して暫定版としてEXEPress 6 Liteでインストーラを作成したのですが、やはりかゆい所に手が届かないもどかしさを感じていました。

インストーラ作成ツールの検討時に「Inno Setup」というオープンソースのインストーラ作成ツールをインストールしたことを忘れていて、今日あまり使わないツールの棚卸しをしていた所、「Inno Setup」ってなんだったっけ?ということになりました。

「Inno Setup」で検索してみると、アタッシェケースを開発されている方のページが目に止まりました。

Inno Setup の様々な機能を使ってみる

MarkDown#Editorのインストーラとしても使われているそうです。

使い方がよく分からず、食わず嫌いな感じで候補から外していたのですが、こちらの方が良さそうです。
アタッシェケースもMarkDown#Editorもオープンソース(GitHub)で公開されているのでいろいろ参考にできそうです。

2014年10月 9日 (木)

なんとなく思ったことですが…

なんとなく思ったことですが…

某社のFullHD TVを使っているのですが、最近のTVはUSB/Bluetoothが搭載されているのでキーボード/マウスはどうにかすれば接続できるなぁと思うのです。マウスはタッチパネルや他のリモートデバイスでもいいんですけど。

さらに無線/有線LANも繋がるなら、クライアントアプリが標準で入ってればリモートデスクトップとしてFullHD TVが使えるのでは?と。

ま、どれだけ使えるのかは未知ですが(◎´∀`)ノ

どうですかね? > P社さん( ^ω^ )

Raspberry PiやBeagle Bone Blackを繋ぐのもありだとは思うのですが…

ひとりごとでした。

2014年10月 8日 (水)

「ブリュンヒルデ零式改」をVS2013 Expressで作ってみます その3

えーっと、作者の方からご連絡を頂きまして、サンプルソースコードが修正されているとのことでしたので、ダウンロードし直してビルドしました。

VS2013 Express IDEからRelease/Debugの両ビルドで実行できました。
少しデスクトップの下が切れているのは、まぁ細かい調整が少し必要ということでしょう。

20141008_100449

このサンプルソースコードに確認用のデバッグコードを追加して、送信している内容の確認をしたいと思います。たぶん通信内容を保存して内容を比較できたらテスト項目として追加できますね。

操作手順の記録/再生もできるように少し、ちゃんと作りこんで置いたほうがよいですね。機能的には最初は見せないと思いますが。

(追記)

サンプルソース(zeroshikikai.cpp)の478行目あたりにsound_captureの指定があるのですが、これがCoreAudio(1)になっていることが原因の1つでした。XPの場合DirectSound(0)に指定しなくてはならないようでした。

//音声系

com_data.sound_type = 1;
com_data.sound_capture = 1; <= ここ
com_data.sound_quality = 3;

Windows 7のようなCoreAudioな新しめのOSなら問題ないとのことです。

やはりもうXPは使わないほうがいいのでしょうね…ブルースクリーン久しぶりに見ました。

2014年10月 7日 (火)

すべてのイベントを取得するには

最後の問題として挙げていた件ですが…

通常のアプリケーションとしては、特殊なキー(例えば「全角/半角キー」とか「Windowsキー」)はあまり扱う必要はないのですが、リモートでPCを操作しようとする今回の場合すべてのキーを扱う必要があります。

先人たちの知恵を頼りに早速googleさんで検索してみました。

Qt eventFilterでイベントを振り分ける

どうやら仮想関数eventFilter()を実装してQApplicationのインスタンスにイベントフィルタとして登録(install)すればいいみたいですね。

virtual bool eventFilter(QObject *obj, QEvent *event);

イベントフィルターということなので、すべてのイベント(キー、マウスなど)が起こる度にこの関数が呼ばれるみたいです。ということは、今までデバイスの種類(キーボード/マウス)とイベントの種類(キーが押された/離された、マウスのボタンが押された、など)で別々な関数を書いていたのを1つにまとめる必要がありそうです。

これで取り敢えず見えている問題は解決できそうです。

あとはドキュメント作りもあるか…USキーボードも…インストーラ環境の確認(EXEpress6)も…

(追記)
QApplicationのインスタンスにイベントフィルタを登録しても、「全角/半角」、「ひらがな/カタカナ」、「変換」、「左右のWindows」の各キーイベントは取得できないようです…無変換キーだけは取得できますが…

これ以上だとQApplicationのサブクラスを作って、notify()関数をオーバライドする手段しかなさそうです。

« 2014年9月 | トップページ | 2014年11月 »