[Message Prev][Message Next][Thread Prev][Thread Next][Message Index][Thread Index]
Re: [MD:4204] Sound support
- X-ml-count: 4247
- Subject: Re: [MD:4204] Sound support
- From: MIYASHITA Hisashi(宮下 尚:HIMI) <himi@xxxxxxxxxxx>
- Date: Sun, 23 Feb 2003 10:56:12 +0900
- User-agent: Wanderlust/2.5.7 (Smooth) SEMI/1.14.3 (Ushinoya) FLIM/1.14.2 (Yagi-Nishiguchi) APEL/10.3 Emacs/21.1 (i386-msvc-nt5.1.2600) MULE/5.0 (SAKAKI) Meadow/1.99 Alpha4 (KUROGANE)
私は、日曜日、校正中...^^;;;
At Sun, 23 Feb 2003 10:38:56 +0900,
MIYOSHI Masanori wrote:
> >>>>> [meadow-develop : No.4207] にて
> >>>>> "himi" = MIYASHITA Hisashi(宮下 尚:HIMI) <himi@xxxxxxxxxxx> さんは書きました:
> himi> 理想的にはこっちですが、それは当分先のことなので、まず、MCIを入れるのは
> himi> それほど悪くない選択だと思います。大事なのは、まず、MCIに忠実な下位層を
> himi> 作成し、その後、Emacsの上位層のelisp APIをemulateするという構成が望ましいと
> himi> 思われます。MCIは、ほとんどcommand送るだけの単純構成だし、primitive APIも
> himi> 簡単に作れるでしょう。
>
> 実験的に、手元で、次の primitive function を実装してみました。
>
> (mw32-mci-send-string COMMAND NOTIFY-CALLBACK-FUNC NOTIFY-CALLBACK-ARG)
> (mw32-mci-get-error-string ERROR-CODE)
恐るべし。もう出来てしまうとは。^^;;;
> 次のようにして WAV データを再生できています。
>
> (mw32-mci-send-string "open c:/WINDOWS/Media/tada.wav alias x")
> (mw32-mci-send-string "play x")
> (mw32-mci-send-string "close x")
>
> で、質問があります。
>
> (1) 利用する MCI レイヤ
> MCI にもいろんなレイヤがあるようなのですが、himi さんが想定してい
> るのは、この文字列でコマンドを送るレイヤでいいのでしょうか?
はい。まさにそういうものを想定していました。^^;;;
> (2) コールバックの実装
> ループ再生のためなどに、再生完了時に発生する MM_MCINOTIFY イベン
> トをひろってコールバック関数を実行しようと思っているのですが、う
> まくいきません。
>
> NOTIFY-CALLBACK-FUNC を safe_call()で実行するときにエラーとなりま
> す。
それはいかんです。
> 多分、メッセージスレッドで safe_call() しているのが悪いと思われる
> ので、メインスレッドで実行させたいのですが、その方法が分かりませ
> ん。
>
> 分かる方教えてください。
>
> ;; 多分 Emacs イベントを介すればできそうだけど、よく分かりません。
もし本格的にやるなら、当然、Emacs eventを使うべきです。
## サボる手もあるけど、それは設計上良くないので、ここでは触れません。
emacs eventを拡張するには、まず、termhooks.hをいじります。ここに、
まず、新しいevent_kindを追加しましょう。候補としては、mw32_mci_eventが
良いかな。^^;;;
次に、lispy eventを定義します。これは、Lisp Objectとして、eventがどう
あらわされるかを決定するものです。Emacsは、XEmacsと違って、この辺が
例によっていい加減です。どうせ、MCIは、今までになかったeventの種類なので
自分で定義した方が良いでしょうね。
(mw32-mci <MCI-EVENT-TYPE> <DEVICE-ID> [EVENT-TYPE-SPECIFIC-PARAMETER])
こんな感じでよいかな。(対応を取る為に、mw32-mci-send-stringなどで
MCI命令を発行した後、device IDを返却するようにすれば良いでしょう。)
これは、make_lispy_event()で定義されます。
(もういい加減構造化してやりたい関数の筆頭:-P)
実際の定義はこんな感じになっています。
ここで、emacs_event構造体をLisp Objectに変換します。
case w32_mouse_wheel:
{
int part, row, column;
int delta = event->code;
FRAME_PTR f;
Lisp_Object window;
Lisp_Object posn;
Lisp_Object position, head;
f = XFRAME(event->frame_or_window);
if (! FRAME_LIVE_P (f))
return Qnil;
pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
&column, &row, NULL, 1);
window = window_from_coordinates (f, XINT(event->x),
XINT(event->y), &part, 0);
if (!WINDOWP (window))
{
window = event->frame_or_window;
posn = Qnil;
}
else
{
int pixcolumn, pixrow;
struct window *w = XWINDOW (window);
column -= XINT (w->left);
row -= XINT (w->top);
glyph_to_pixel_coords (w, column, row, &pixcolumn, &pixrow);
XSETINT (event->x, pixcolumn);
XSETINT (event->y, pixrow);
if (part == 1)
posn = Qmode_line;
else if (part == 2)
posn = Qvertical_line;
else
{
Lisp_Object object;
struct display_pos p;
buffer_posn_from_coords (w, &column, &row,
&object, &p);
posn = make_number (CHARPOS (p.pos));
}
}
position =
Fcons (window,
Fcons (posn,
Fcons (Fcons(event->x, event->y),
Fcons (make_number (event->timestamp),
Fcons (make_number(delta), Qnil)))));
/* Always treat mouse wheel events as clicks. */
event->modifiers |= click_modifier;
head = modify_event_symbol (0,
event->modifiers,
Qmouse_click, Qnil,
lispy_mouse_wheel_names,
&mouse_wheel_syms,
(sizeof (lispy_mouse_wheel_names)
/ sizeof (lispy_mouse_wheel_names[0])));
return Fcons (head,
Fcons (position,
Qnil));
}
--------------------------------------------------------------------------------
実際に、emacs eventを発行するのは、たとえば、mw32_drop_file_handlerとか、
mw32_mouse_wheel_handlerを見ればよいかな。今回必要なeventは、一回につき一つだろうから、
これで十分。
int
mw32_mouse_wheel_handler (FRAME_PTR frame,
MSG* msg,
struct input_event* emacs_event)
{
struct mw32_display_info *dpyinfo = FRAME_MW32_DISPLAY_INFO(frame);
POINT pt;
/* Sony VAIO Jog Dial Utility sends WM_MOUSEWHEEL with the posotion
guessed by active window. Here replace it by last mouse position
stored as last_mouse_motion_message. There is no side effect,
maybe.. 2001/03/16 K. Horiguchi */
pt.x = (signed short) LOWORD(last_mouse_motion_message.lParam);
pt.y = (signed short) HIWORD(last_mouse_motion_message.lParam);
/*
pt.x = (signed short) LOWORD(msg->lParam);
pt.y = (signed short) HIWORD(msg->lParam);
ScreenToClient(msg->hwnd, &pt);
*/
emacs_event->kind = w32_mouse_wheel;
emacs_event->code = (signed short) HIWORD(msg->wParam);
emacs_event->modifiers = MW32GETMODIFIER (dpyinfo);
XSETINT (emacs_event->x, pt.x);
XSETINT (emacs_event->y, pt.y);
XSETFRAME (emacs_event->frame_or_window, frame);
emacs_event->timestamp = msg->time;
return 1;
}
この関数を、mw32_message_loop()から呼び出せばよいというわけ。
やるべきことは以上。そんなに難しくないはず。
from himi