クライアント情報
今度は、サーバーに接続されている、各クライアントの情報を取得してみます。
pa_context_get_client_info() は、インデックス番号を指定して、特定のクライアントの情報を取得します。
pa_context_get_client_info_list() は、すべてのクライアントの情報を取得します。
インデックス番号は、各オブジェクトを、サーバーが識別するための番号です。
オブジェクトの種類ごとに、0〜の番号が割り振られます。
プロパティリストは、キー文字列と値が関連付けられた、任意の値のリストです。
今回のコールバック関数には、eol 引数が追加されています。
複数の情報が取得される場合、コールバック関数は複数回実行されます。
i と eol の値によって、データを判断します。
データの数だけコールバック関数が来た後、最後に、i = NULL, eol > 0 の状態でコールバック関数が来ます。
なお、pa_context_get_client_info() のように、単一の情報を要求する関数を使ったとしても、上記の動作通り、コールバックは2回来ます。
クライアント情報の取得
pa_operation *pa_context_get_client_info(pa_context *c, uint32_t idx, pa_client_info_cb_t cb, void *userdata); pa_operation *pa_context_get_client_info_list(pa_context *c, pa_client_info_cb_t cb, void *userdata); //コールバック関数 typedef void (*pa_client_info_cb_t)(pa_context *c, const pa_client_info *i, int eol, void *userdata); //クライアント情報の構造体 typedef struct pa_client_info { uint32_t index; //インデックス番号 const char *name; //クライアント名 uint32_t owner_module; //所有モジュールのインデックス const char *driver; //ドライバ名 pa_proplist *proplist; //プロパティリスト } pa_client_info;
pa_context_get_client_info() は、インデックス番号を指定して、特定のクライアントの情報を取得します。
pa_context_get_client_info_list() は、すべてのクライアントの情報を取得します。
インデックス番号は、各オブジェクトを、サーバーが識別するための番号です。
オブジェクトの種類ごとに、0〜の番号が割り振られます。
プロパティリストは、キー文字列と値が関連付けられた、任意の値のリストです。
コールバック関数
typedef void (*pa_client_info_cb_t)(pa_context *c, const pa_client_info *i, int eol, void *userdata);
今回のコールバック関数には、eol 引数が追加されています。
複数の情報が取得される場合、コールバック関数は複数回実行されます。
i と eol の値によって、データを判断します。
データがある | i は NULL 以外。eol = 0。 |
---|---|
データの終了 | i = NULL、eol = 正の値 |
エラー | i = NULL、eol = 負の値 |
データの数だけコールバック関数が来た後、最後に、i = NULL, eol > 0 の状態でコールバック関数が来ます。
なお、pa_context_get_client_info() のように、単一の情報を要求する関数を使ったとしても、上記の動作通り、コールバックは2回来ます。
プログラム
現在、サーバーに接続されている、クライアントのリストを表示するプログラムです。
$ cc -o 05-client 05-client.c util.c -lpulse
#include <stdio.h> #include <pulse/pulseaudio.h> #include "util.h" PulseData *pulse; static void _client_callback(pa_context *c,const pa_client_info *i,int eol,void *userdata) { if(!i) { pa_threaded_mainloop_signal(pulse->mainloop, 0); return; } printf("[index:%u]\n", i->index); printf("name: %s\n", i->name); printf("owner_module: %u\n", i->owner_module); printf("driver: %s\n", i->driver); if(i->proplist) { char *str; str = pa_proplist_to_string(i->proplist); printf("<proplist>\n%s", str); pa_xfree(str); } printf("\n"); } static pa_operation *_get_info(PulseData *p,void *data) { return pa_context_get_client_info_list(pulse->ctx, _client_callback, NULL); } int main(void) { pulse = pulse_connect(0); if(!pulse) return 1; pulse_wait_operation(pulse, _get_info, NULL); pulse_free(pulse); return 0; }
pulse_wait_operation
util.c に、指定した関数 (func 引数) 内で PulseAudio の操作をして、戻り値の pa_operation * を元に、操作が終わるまで待つ関数を用意しています。
PulseAudio の操作をする前にロックが必要になるので、このような形になっています。
PulseAudio の操作をする前にロックが必要になるので、このような形になっています。
typedef pa_operation *(*pulse_func_wait_op)(PulseData *p,void *data); void pulse_wait_operation(PulseData *p,pulse_func_wait_op func,void *data) { pa_operation *op; pa_threaded_mainloop_lock(p->mainloop); op = (func)(p, data); if(!op) { pa_threaded_mainloop_unlock(p->mainloop); return; } while(pa_operation_get_state(op) == PA_OPERATION_RUNNING) pa_threaded_mainloop_wait(p->mainloop); pa_operation_unref(op); pa_threaded_mainloop_unlock(p->mainloop); }
実行結果
例えば、以下のように表示されます。
同じサーバーに接続されているクライアントのリストが表示されます。
プロパティリストには、アプリケーションの情報などが格納されています。
何度かこのプログラムを実行すると、test-pulse の index が増加していくのがわかります。
インデックス番号は、サーバーが起動している間は、常に新しい番号で割り当てられます。
オブジェクトが削除されても、古いインデックスは再利用されません。
同じサーバーに接続されているクライアントのリストが表示されます。
[index:0] name: Login Session 3 owner_module: 14 driver: module-systemd-login.c <proplist> application.name = "Login Session 3" systemd-login.session = "3" ... [index:3] name: Firefox owner_module: 8 driver: protocol-native.c <proplist> ... [index:21] name: test-pulse owner_module: 8 driver: protocol-native.c <proplist> application.name = "test-pulse" native-protocol.peer = "UNIX socket client" native-protocol.version = "35" application.process.id = "***" application.process.user = "***" application.process.host = "***" application.process.binary = "run" application.language = "C" window.x11.display = ":0" application.process.machine_id = "***" application.process.session_id = "2"
プロパティリストには、アプリケーションの情報などが格納されています。
何度かこのプログラムを実行すると、test-pulse の index が増加していくのがわかります。
インデックス番号は、サーバーが起動している間は、常に新しい番号で割り当てられます。
オブジェクトが削除されても、古いインデックスは再利用されません。