ここではそのウィンドウメッセージをどう処理しているのかコードを辿っていきたいと思う。
まず、SDLにおけるウィンドウプロシージャの実装はSDL_sysevents.cに定義されているWinMessage関数内で行われている。
ここから様々なサブシステムにメッセージを投げて処理をしていると思われるがウィンドウプロシージャ側から辿るのが難しそうなので逆方向からアプローチを行う。
ユーザーがイベントを取得するSDL_PollEvent側から辿ってみる。
SDL_PollEvent(正確にはSDL_PeepEvent)で使用するSDL_EventQ(イベントキュー)はグローバルメンバ変数で、SDL_events.cに次のように定義されている
[cpp]
/* SDL_events.c */
/* Private data -- event queue */
#define MAXEVENTS 128
static struct {
SDL_mutex *lock;
int active;
int head;
int tail;
SDL_Event event[MAXEVENTS];
int wmmsg_next;
struct SDL_SysWMmsg wmmsg[MAXEVENTS];
} SDL_EventQ;
[/cpp]
構造体の仕様から、SDLの内部処理でeventメンバに対して随時ウィンドウメッセージを処理したイベントを追加されることが予想される。では、実際にどこでイベントが追加されるかというとSDL_AddEvent内で処理される。
簡単に流れを整理するとWinMessage>(SDL入力処理?)>SDL_AddEvent>SDL_PollEventの順に処理されることでメッセージをやり取りするのではないかと推測できる。
次はSDL_AddEventをだれが呼び出しているかについて調べていきたい。
以降から多少複雑になるが、SDL_AddEventを呼び出している処理はSDL_PollEvent内でも呼び出しているSDL_PeepEventsによって追加処理も行われる。
これはSDL_PeepEventsと引数であるSDL_eventactionが次のような定義になっているためである。
定義を見るとSDL_ADDEVNETを渡せばイベントを登録するし、それ以外であればイベントを取得する処理になるのがわかる。
[cpp]
int SDL_PeepEvents(SDL_Event *events, int numevents, SDL_eventaction action,
Uint32 mask)
/* SDL_eventactionの定義 * /
typedef enum {
SDL_ADDEVENT,
SDL_PEEKEVENT,
SDL_GETEVENT
} SDL_eventaction;
[/cpp]
ではさらに辿ってSDL_PeepEventに対してSDL_ADDEVENTを渡している処理を追ってみる。
SDL_PeepEventをさらにラップしているSDL_PushEventを経由して多岐にわたるソースコードからイベントが登録されている。
SDL_PushEventを使用してイベントを登録しているサブシステムは以下の通り。
- sdl_mouse.c
- sdl_keyboard.c
- sdl_joystick.c
- sdl_events.c
- sdl_resize.c
- sdl_quit.c
- sdl_expose.c
- sdl_active.c
説明は省くがsdl_mouse、sdl_keyboardやsdl_joystick等入力処理からの登録がほとんどである。
これを集約してさらに元をたどるとWinMessageに行き当たる。
以上でSDLがウィンドウプロシージャからのメッセージをどの様にユーザーに提供しているのか大まかに把握できた。
0 件のコメント:
コメントを投稿