OSDN Git Service

fix datwindow's gid handling in hmi.c
[bbk/bchan.git] / src / hmi.c
1 /*
2  * hmi.c
3  *
4  * Copyright (c) 2011 project bchan
5  *
6  * This software is provided 'as-is', without any express or implied
7  * warranty. In no event will the authors be held liable for any damages
8  * arising from the use of this software.
9  *
10  * Permission is granted to anyone to use this software for any purpose,
11  * including commercial applications, and to alter it and redistribute it
12  * freely, subject to the following restrictions:
13  *
14  * 1. The origin of this software must not be misrepresented; you must not
15  *    claim that you wrote the original software. If you use this software
16  *    in a product, an acknowledgment in the product documentation would be
17  *    appreciated but is not required.
18  *
19  * 2. Altered source versions must be plainly marked as such, and must not be
20  *    misrepresented as being the original software.
21  *
22  * 3. This notice may not be removed or altered from any source
23  *    distribution.
24  *
25  */
26
27 #include    "hmi.h"
28 #include        "tadlib.h"
29 #include        "wordlist.h"
30
31 #include        <bstdio.h>
32 #include        <bstdlib.h>
33 #include        <tcode.h>
34 #include        <tstring.h>
35 #include        <btron/btron.h>
36 #include        <btron/hmi.h>
37 #include        <btron/vobj.h>
38
39 #ifdef BCHAN_CONFIG_DEBUG
40 # define DP(arg) printf arg
41 # define DP_ER(msg, err) printf("%s (%d/%x)\n", msg, err>>16, err)
42 #else
43 # define DP(arg) /**/
44 # define DP_ER(msg, err) /**/
45 #endif
46
47 typedef VOID (*windowscroll_scrollcalback)(VP arg, W dh, W dv);
48
49 struct windowscroll_t_ {
50         PAID rbar;
51         PAID bbar;
52         windowscroll_scrollcalback scroll_callback;
53         W draw_l,draw_t,draw_r,draw_b;
54         W work_l,work_t,work_r,work_b;
55         VP arg;
56 };
57 typedef struct windowscroll_t_ windowscroll_t;
58
59 LOCAL VOID windowscroll_callback_scroll(windowscroll_t *wscr, W dh, W dv)
60 {
61         if (wscr->scroll_callback != NULL) {
62                 (*wscr->scroll_callback)(wscr->arg, -dh, -dv);
63         }
64 }
65
66 LOCAL W windowscroll_updaterbar(windowscroll_t *wscr)
67 {
68         W sbarval[4],err;
69
70         sbarval[0] = wscr->work_t;
71         sbarval[1] = wscr->work_b;
72         sbarval[2] = 0;
73         sbarval[3] = wscr->draw_b - wscr->draw_t;
74         if (sbarval[1] > sbarval[3]) {
75                 sbarval[1] = sbarval[3];
76         }
77         if((err = cset_val(wscr->rbar, 4, sbarval)) < 0){
78                 DP(("windowscroll_updaterbar:cset_val rbar\n"));
79                 DP(("                       :%d %d %d %d\n", sbarval[0], sbarval[1], sbarval[2], sbarval[3]));
80                 return err;
81         }
82
83         return 0;
84 }
85
86 LOCAL W windowscroll_updatebbar(windowscroll_t *wscr)
87 {
88         W sbarval[4],err;
89
90         sbarval[0] = wscr->work_r;
91         sbarval[1] = wscr->work_l;
92         sbarval[2] = wscr->draw_r - wscr->draw_l;
93         sbarval[3] = 0;
94         if (sbarval[0] > sbarval[2]) {
95                 sbarval[0] = sbarval[2];
96         }
97         if((err = cset_val(wscr->bbar, 4, sbarval)) < 0){
98                 DP(("windowscroll_updatebbar:cset_val bbar\n"));
99                 DP(("                       :%d %d %d %d\n", sbarval[0], sbarval[1], sbarval[2], sbarval[3]));
100                 return err;
101     }
102
103         return 0;
104 }
105
106 EXPORT W windowscroll_updatebar(windowscroll_t *wscr)
107 {
108         W err;
109
110         err = windowscroll_updaterbar(wscr);
111         if (err < 0) {
112                 return err;
113         }
114
115         err = windowscroll_updatebbar(wscr);
116         if (err < 0) {
117                 return err;
118         }
119
120         return 0;
121 }
122
123 LOCAL W windowscroll_scrollbar(windowscroll_t *wscr, WEVENT *wev, PAID scrbarPAID)
124 {
125         W i,err,barval[4];
126         W *clo = barval,*chi = barval+1,*lo = barval+2,*hi = barval+3;
127         RECT sbarRECT;
128         W pressval,smoothscrolldiff;
129         W dh,dv;
130         WID wid;
131
132         wid = wev->g.wid;
133
134         for(;;) {
135                 if((i = cact_par(scrbarPAID, wev)) < 0) {
136                         DP_ER("cact_par error", i);
137                         return i;
138                 }
139                 cget_val(scrbarPAID, 4, barval);
140                 if((i & 0xc) == 0x8) { /*¥¸¥ã¥ó¥×*/
141                         if (scrbarPAID == wscr->rbar) { /*±¦¥Ð¡¼*/
142                                 dh = 0;
143                                 dv = -(*clo-wscr->work_t);
144                                 wscr->work_t -= dv;
145                                 wscr->work_b -= dv;
146                                 windowscroll_callback_scroll(wscr, dh, dv);
147                         } else if (scrbarPAID == wscr->bbar) { /*²¼¥Ð¡¼*/
148                                 dh = -(*chi-wscr->work_l);
149                                 dv = 0;
150                                 wscr->work_l -= dh;
151                                 wscr->work_r -= dh;
152                                 windowscroll_callback_scroll(wscr, dh, dv);
153                         }
154                         if ((i & 0x6000) == 0x6000) {
155                                 /*¥¸¥ã¥ó¥×°ÜÆ°Ãæ¤ÎÃͤÎÊѹ¹*/
156                                 continue;
157                         }
158                         break;
159                 }
160                 switch(i) {
161                         /*¥¹¥à¡¼¥¹¥¹¥¯¥í¡¼¥ë*/
162                         /*¥×¥ì¥¹°ÌÃ֤ȥΥ֤ΰÌÃÖ¤ËÈæÎ㤷¤¿Â®Å٤ǥ¹¥¯¥í¡¼¥ë*/
163                 case 0x6000:    /*¾å¤Ø¤Î¥¹¥à¡¼¥¹¥¹¥¯¥í¡¼¥ë¤ÇÃæÃÇ*/
164                 case 0x6001:    /*²¼¤Ø¤Î¥¹¥à¡¼¥¹¥¹¥¯¥í¡¼¥ë¤ÇÃæÃÇ*/
165                         if ((err = cget_pos(scrbarPAID, &sbarRECT)) < 0) {
166                                 continue;
167                         }
168                         pressval = (wev->s.pos.y - sbarRECT.c.top)*
169                                 (*hi - *lo)/(sbarRECT.c.bottom-sbarRECT.c.top) + *lo;
170                         smoothscrolldiff = (pressval - (*chi+*clo)/2)/5;
171                         if (smoothscrolldiff == 0) {
172                                 continue;
173                         }
174                         if ((*clo + smoothscrolldiff) < *lo) {
175                                 if (*lo >= *clo) {
176                                         continue;
177                                 }
178                                 dh = 0;
179                                 dv = -(*lo - *clo);
180                         } else if ((*chi + smoothscrolldiff) > *hi) {
181                                 if (*hi <= *chi) {
182                                         continue;
183                                 }
184                                 dh = 0;
185                                 dv = -(*hi - *chi);
186                         } else {
187                                 dh = 0;
188                                 dv = -smoothscrolldiff;
189                         }
190                         wscr->work_t -= dv;
191                         wscr->work_b -= dv;
192                         windowscroll_callback_scroll(wscr, dh, dv);
193                         windowscroll_updaterbar(wscr);
194                         continue;
195                 case 0x6002:    /*º¸¤Ø¤Î¥¹¥à¡¼¥¹¥¹¥¯¥í¡¼¥ë¤ÇÃæÃÇ*/
196                 case 0x6003:    /*±¦¤Ø¤Î¥¹¥à¡¼¥¹¥¹¥¯¥í¡¼¥ë¤ÇÃæÃÇ*/
197                         if ((err = cget_pos(scrbarPAID, &sbarRECT)) < 0) {
198                                 continue;
199                         }
200                         pressval = (wev->s.pos.x - sbarRECT.c.left)*
201                                 (*lo - *hi)/(sbarRECT.c.right-sbarRECT.c.left) + *hi;
202                         smoothscrolldiff = (pressval - (*clo+*chi)/2)/5;
203                         if (smoothscrolldiff == 0) {
204                                 continue;
205                         }
206                         if ((*clo + smoothscrolldiff) > *lo) {
207                                 if (*lo <= *clo) {
208                                         continue;
209                                 }
210                                 dh = -(*lo - *clo);
211                                 dv = 0;
212                         } else if ((*chi + smoothscrolldiff) < *hi) {
213                                 if (*hi >= *chi) {
214                                         continue;
215                                 }
216                                 dh = -(*hi - *chi);
217                                 dv = 0;
218                         } else {
219                                 dh = -smoothscrolldiff;
220                                 dv = 0;
221                         }
222                         wscr->work_l -= dh;
223                         wscr->work_r -= dh;
224                         windowscroll_callback_scroll(wscr, dh, dv);
225                         windowscroll_updatebbar(wscr);
226                         continue;
227                 case 0x5004:    /*¾å¤Ø¤Î¥¨¥ê¥¢¥¹¥¯¥í¡¼¥ë¤Ç½ªÎ»*/
228                         if ((wscr->work_t - (*chi-*clo)) < *lo) {
229                                 dh = 0;
230                                 dv = -(*lo - wscr->work_t);
231                         } else {
232                                 dh = 0;
233                                 dv = (*chi - *clo);
234                         }
235                         wscr->work_t -= dv;
236                         wscr->work_b -= dv;
237                         windowscroll_callback_scroll(wscr, dh, dv);
238                         windowscroll_updaterbar(wscr);
239                         break;
240                 case 0x5005:    /*²¼¤Ø¤Î¥¨¥ê¥¢¥¹¥¯¥í¡¼¥ë¤Ç½ªÎ»*/
241                         if((wscr->work_b + (*chi-*clo)) > *hi){
242                                 dh = 0;
243                                 dv = -(*hi - wscr->work_b);
244                         } else {
245                                 dh = 0;
246                                 dv = -(*chi - *clo);
247                         }
248                         wscr->work_t -= dv;
249                         wscr->work_b -= dv;
250                         windowscroll_callback_scroll(wscr, dh, dv);
251                         windowscroll_updaterbar(wscr);
252                         break;
253                 case 0x5006:    /*º¸¤Ø¤Î¥¨¥ê¥¢¥¹¥¯¥í¡¼¥ë¤Ç½ªÎ»*/
254                         if((wscr->work_l - (*clo-*chi)) < *hi){
255                                 dh = -(*hi - wscr->work_l);
256                                 dv = 0;
257                         } else {
258                                 dh = *clo - *chi;
259                                 dv = 0;
260                         }
261                         wscr->work_l -= dh;
262                         wscr->work_r -= dh;
263                         windowscroll_callback_scroll(wscr, dh, dv);
264                         windowscroll_updatebbar(wscr);
265                         break;
266                 case 0x5007:    /*±¦¤Ø¤Î¥¨¥ê¥¢¥¹¥¯¥í¡¼¥ë¤Ç½ªÎ»*/
267                         if((wscr->work_r + (*clo-*chi)) > *lo){
268                                 dh = -(*lo - wscr->work_r);
269                                 dv = 0;
270                         } else {
271                                 dh = -(*clo - *chi);
272                                 dv = 0;
273                         }
274                         wscr->work_l -= dh;
275                         wscr->work_r -= dh;
276                         windowscroll_callback_scroll(wscr, dh, dv);
277                         windowscroll_updatebbar(wscr);
278                         break;
279                 }
280                 break;
281         }
282
283         return 0;
284 }
285
286 EXPORT VOID windowscroll_scrollbyvalue(windowscroll_t *wscr, W dh, W dv)
287 {
288         wscr->work_l += dh;
289         wscr->work_t += dv;
290         wscr->work_r += dh;
291         wscr->work_b += dv;
292         windowscroll_callback_scroll(wscr, -dh, -dv);
293         windowscroll_updatebar(wscr);
294 }
295
296 LOCAL W windowscroll_weventrbar(windowscroll_t *wscr, WEVENT *wev)
297 {
298         return windowscroll_scrollbar(wscr, wev, wscr->rbar);
299 }
300
301 LOCAL W windowscroll_weventbbar(windowscroll_t *wscr, WEVENT *wev)
302 {
303         return windowscroll_scrollbar(wscr, wev, wscr->bbar);
304 }
305
306 LOCAL W windowscroll_setworkrect(windowscroll_t *wscr, W l, W t, W r, W b)
307 {
308         wscr->work_l = l;
309         wscr->work_t = t;
310         wscr->work_r = r;
311         wscr->work_b = b;
312         return windowscroll_updatebar(wscr);
313 }
314
315 LOCAL W windowscroll_setdrawrect(windowscroll_t *wscr, W l, W t, W r, W b)
316 {
317         wscr->draw_l = l;
318         wscr->draw_t = t;
319         wscr->draw_r = r;
320         wscr->draw_b = b;
321         return windowscroll_updatebar(wscr);
322 }
323
324 LOCAL VOID windowscroll_settarget(windowscroll_t *wscr, WID target)
325 {
326         if (target < 0) {
327                 wscr->rbar = -1;
328                 wscr->bbar = -1;
329         } else {
330                 wget_bar(target, &(wscr->rbar), &(wscr->bbar), NULL);
331                 cchg_par(wscr->rbar, P_NORMAL|P_NOFRAME|P_ENABLE|P_ACT|P_DRAGBREAK);
332                 cchg_par(wscr->bbar, P_NORMAL|P_NOFRAME|P_ENABLE|P_ACT|P_DRAGBREAK);
333         }
334 }
335
336 LOCAL W windowscroll_initialize(windowscroll_t *wscr, WID target, windowscroll_scrollcalback scrollcallback, VP arg)
337 {
338         windowscroll_settarget(wscr, target);
339         wscr->scroll_callback = scrollcallback;
340         wscr->arg = arg;
341         wscr->work_l = 0;
342         wscr->work_t = 0;
343         wscr->work_r = 0;
344         wscr->work_b = 0;
345         wscr->draw_l = 0;
346         wscr->draw_t = 0;
347         wscr->draw_r = 0;
348         wscr->draw_b = 0;
349
350         return 0;
351 }
352
353 LOCAL VOID windowscroll_finalize(windowscroll_t *wscr)
354 {
355 }
356
357 struct datwindow_t_ {
358         WID wid;
359         GID gid;
360         datwindow_scrollcalback scroll_callback;
361         windowscroll_t wscr;
362         VP arg;
363         WEVENT savedwev;
364 };
365
366 struct cfrmwindow_t_ {
367         WID wid;
368         GID gid;
369         WID parent;
370         PAID ms_post_id;
371         PAID ms_cancel_id;
372         RECT r;
373         windowscroll_t wscr;
374         postresdata_t *post;
375         TC *windowtitle;
376         W dnum_post;
377         W dnum_cancel;
378         SIZE sz_ms_post;
379         SIZE sz_ms_cancel;
380
381         /* left top of content rect */
382         PNT pos_from;
383         PNT pos_mail;
384         PNT pos_message;
385         PNT pos_cancel;
386         PNT pos_post;
387 };
388
389 struct ngwordwindow_t_ {
390         WID wid;
391         GID gid;
392         WID parent;
393         RECT r;
394         PAT bgpat;
395         W dnum_list;
396         W dnum_delete;
397         W dnum_input;
398         W dnum_append;
399         PAID ss_list_id;
400         PAID ms_delete_id;
401         PAID tb_input_id;
402         PAID ms_append_id;
403         wordlist_t wordlist;
404         TC strbuf[128];
405         TC *selector;
406 };
407
408 struct dathmi_t_ {
409         dathmievent_t evt;
410         datwindow_t *mainwindow;
411         cfrmwindow_t *cfrmwindow;
412         ngwordwindow_t *ngwordwindow;
413 };
414
415 EXPORT W datwindow_startredisp(datwindow_t *window, RECT *r)
416 {
417         return wsta_dsp(window->wid, r, NULL);
418 }
419
420 EXPORT W datwindow_endredisp(datwindow_t *window)
421 {
422         return wend_dsp(window->wid);
423 }
424
425 EXPORT W datwindow_eraseworkarea(datwindow_t *window, RECT *r)
426 {
427         return wera_wnd(window->wid, r);
428 }
429
430 EXPORT W datwindow_scrollworkarea(datwindow_t *window, W dh, W dv)
431 {
432         return wscr_wnd(window->wid, NULL, dh, dv, W_MOVE|W_RDSET);
433 }
434
435 EXPORT VOID datwindow_scrollbyvalue(datwindow_t *window, W dh, W dv)
436 {
437         windowscroll_scrollbyvalue(&window->wscr, dh, dv);
438 }
439
440 EXPORT W datwindow_requestredisp(datwindow_t *window)
441 {
442         return wreq_dsp(window->wid);
443 }
444
445 EXPORT GID datwindow_startdrag(datwindow_t *window)
446 {
447         return wsta_drg(window->wid, 0);
448 }
449
450 EXPORT W datwindow_getdrag(datwindow_t *window, PNT *pos, WID *wid, PNT *pos_butup)
451 {
452         W etype;
453
454         etype = wget_drg(pos, &window->savedwev);
455         *wid = window->savedwev.s.wid;
456         if (etype == EV_BUTUP) {
457                 *pos_butup = window->savedwev.s.pos;
458         }
459
460         return etype;
461 }
462
463 EXPORT VOID datwindow_enddrag(datwindow_t *window)
464 {
465         wend_drg();
466 }
467
468 EXPORT VOID datwindow_responsepasterequest(datwindow_t *window, W nak, PNT *pos)
469 {
470         if (pos != NULL) {
471                 window->savedwev.r.r.p.rightbot.x = pos->x;
472                 window->savedwev.r.r.p.rightbot.y = pos->y;
473         }
474         wrsp_evt(&window->savedwev, nak);
475 }
476
477 EXPORT W datwindow_getworkrect(datwindow_t *window, RECT *r)
478 {
479         return wget_wrk(window->wid, r);
480 }
481
482 EXPORT GID datwindow_getGID(datwindow_t *window)
483 {
484         return wget_gid(window->wid);
485 }
486
487 EXPORT WID datwindow_getWID(datwindow_t *window)
488 {
489         return window->wid;
490 }
491
492 EXPORT W datwindow_settitle(datwindow_t *window, TC *title)
493 {
494         return wset_tit(window->wid, -1, title, 0);
495 }
496
497 EXPORT W datwindow_setdrawrect(datwindow_t *window, W l, W t, W r, W b)
498 {
499         return windowscroll_setdrawrect(&window->wscr, l, t, r, b);
500 }
501
502 EXPORT W datwindow_setworkrect(datwindow_t *window, W l, W t, W r, W b)
503 {
504         return windowscroll_setworkrect(&window->wscr, l, t, r, b);
505 }
506
507 LOCAL WID dathmi_getmainWID(dathmi_t *hmi)
508 {
509         if (hmi->mainwindow == NULL) {
510                 return -1;
511         }
512         return hmi->mainwindow->wid;
513 }
514
515 LOCAL WID dathmi_getcfrmWID(dathmi_t *hmi)
516 {
517         if (hmi->cfrmwindow == NULL) {
518                 return -1;
519         }
520         return hmi->cfrmwindow->wid;
521 }
522
523 LOCAL WID dathmi_getngwordWID(dathmi_t *hmi)
524 {
525         if (hmi->ngwordwindow == NULL) {
526                 return -1;
527         }
528         return hmi->ngwordwindow->wid;
529 }
530
531 /* TODO: same as layoutstyle_resetgenvfont */
532 LOCAL VOID cfrmwindow_resetgenv(cfrmwindow_t *window)
533 {
534         FSSPEC spec;
535         GID gid;
536
537         gid = window->gid;
538
539         gget_fon(gid, &spec, NULL);
540         spec.attr |= FT_PROP;
541         spec.attr |= FT_GRAYSCALE;
542         spec.fclass = FTC_DEFAULT;
543         spec.size.h = 16;
544         spec.size.v = 16;
545         gset_fon(gid, &spec);
546         gset_chc(gid, 0x10000000, 0x10efefef);
547
548         return;
549 }
550
551 #define CFRMWINDOW_LAYOUT_WHOLE_MARGIN 5
552 #define CFRMWINDOW_LAYOUT_FROM_MARGIN 0
553 #define CFRMWINDOW_LAYOUT_MAIL_MARGIN 0
554 #define CFRMWINDOW_LAYOUT_MESSAGE_MARGIN 16
555 #define CFRMWINDOW_LAYOUT_BUTTON_MARGIN 5
556
557 LOCAL VOID cfrmwindow_calclayout(cfrmwindow_t *window, SIZE *sz)
558 {
559         SIZE sz_from = {0,0}, sz_mail = {0,0}, sz_msg = {0,0}, sz_button = {0,0};
560         TC label_from[] = {0x4C3E, 0x4130, TK_COLN, TK_KSP, TNULL};
561         TC label_mail[] = {TK_E, 0x213E, TK_m, TK_a, TK_i, TK_l, TK_COLN, TK_KSP, TNULL};
562         GID gid;
563         W width_from, width_mail;
564         actionlist_t *alist_from = NULL, *alist_mail = NULL, *alist_message = NULL;
565         TC *from, *mail, *message;
566         W from_len, mail_len, message_len;
567
568         sz->h = 0;
569         sz->v = 0;
570
571         if (window->post == NULL) {
572                 return;
573         }
574
575         gid = window->gid;
576
577         from = postresdata_getfromstring(window->post);
578         from_len = postresdata_getfromstringlen(window->post);
579         mail = postresdata_getmailstring(window->post);
580         mail_len = postresdata_getmailstringlen(window->post);
581         message = postresdata_getmessagestring(window->post);
582         message_len = postresdata_getmessagestringlen(window->post);
583
584         cfrmwindow_resetgenv(window);
585         width_from = gget_stw(gid, label_from, 4, NULL, NULL);
586         if (width_from < 0) {
587                 return;
588         }
589         tadlib_calcdrawsize(from, from_len, gid, &sz_from, &alist_from);
590         sz_from.h += width_from + CFRMWINDOW_LAYOUT_FROM_MARGIN * 2;
591         sz_from.v += CFRMWINDOW_LAYOUT_FROM_MARGIN * 2;
592
593         if (alist_from != NULL) {
594                 actionlist_delete(alist_from);
595         }
596         cfrmwindow_resetgenv(window);
597         width_mail = gget_stw(gid, label_mail, 4, NULL, NULL);
598         if (width_mail < 0) {
599                 return;
600         }
601         tadlib_calcdrawsize(mail, mail_len, gid, &sz_mail, &alist_mail);
602         sz_mail.h += width_mail + CFRMWINDOW_LAYOUT_MAIL_MARGIN * 2;
603         sz_mail.v += CFRMWINDOW_LAYOUT_MAIL_MARGIN * 2;
604
605         if (alist_mail != NULL) {
606                 actionlist_delete(alist_mail);
607         }
608         cfrmwindow_resetgenv(window);
609         tadlib_calcdrawsize(message, message_len, gid, &sz_msg, &alist_message);
610         if (alist_message != NULL) {
611                 actionlist_delete(alist_message);
612         }
613         sz_msg.h += CFRMWINDOW_LAYOUT_MESSAGE_MARGIN * 2;
614         sz_msg.v += CFRMWINDOW_LAYOUT_MESSAGE_MARGIN * 2;
615
616         sz_button.h = window->sz_ms_post.h + window->sz_ms_cancel.h + CFRMWINDOW_LAYOUT_BUTTON_MARGIN * 4;
617         sz_button.v = (window->sz_ms_post.v > window->sz_ms_cancel.v) ? window->sz_ms_post.v : window->sz_ms_cancel.v + CFRMWINDOW_LAYOUT_BUTTON_MARGIN * 2;
618
619         sz->v += sz_from.v;
620         if (sz->h < sz_from.h) {
621                 sz->h = sz_from.h;
622         }
623         sz->v += sz_mail.v;
624         if (sz->h < sz_mail.h) {
625                 sz->h = sz_mail.h;
626         }
627         sz->v += sz_msg.v;
628         if (sz->h < sz_msg.h) {
629                 sz->h = sz_msg.h;
630         }
631         sz->v += sz_button.v;
632         if (sz->h < sz_button.h) {
633                 sz->h = sz_button.h;
634         }
635         sz->h += CFRMWINDOW_LAYOUT_WHOLE_MARGIN * 2;
636         sz->v += CFRMWINDOW_LAYOUT_WHOLE_MARGIN * 2;
637
638         window->pos_from.x = CFRMWINDOW_LAYOUT_WHOLE_MARGIN + CFRMWINDOW_LAYOUT_FROM_MARGIN;
639         window->pos_from.y = CFRMWINDOW_LAYOUT_WHOLE_MARGIN + CFRMWINDOW_LAYOUT_FROM_MARGIN;
640         window->pos_mail.x = CFRMWINDOW_LAYOUT_WHOLE_MARGIN + CFRMWINDOW_LAYOUT_MAIL_MARGIN;
641         window->pos_mail.y = CFRMWINDOW_LAYOUT_WHOLE_MARGIN + sz_from.v + CFRMWINDOW_LAYOUT_MAIL_MARGIN;
642         window->pos_message.x = CFRMWINDOW_LAYOUT_WHOLE_MARGIN + CFRMWINDOW_LAYOUT_MESSAGE_MARGIN;
643         window->pos_message.y = CFRMWINDOW_LAYOUT_WHOLE_MARGIN + sz_from.v + sz_mail.v + CFRMWINDOW_LAYOUT_MESSAGE_MARGIN;
644         window->pos_cancel.x = CFRMWINDOW_LAYOUT_WHOLE_MARGIN + CFRMWINDOW_LAYOUT_BUTTON_MARGIN;
645         window->pos_cancel.y = CFRMWINDOW_LAYOUT_WHOLE_MARGIN + sz_from.v + sz_mail.v + sz_msg.v + CFRMWINDOW_LAYOUT_BUTTON_MARGIN;
646         window->pos_post.x = window->pos_cancel.x + window->sz_ms_cancel.h + CFRMWINDOW_LAYOUT_BUTTON_MARGIN;
647         window->pos_post.y = window->pos_cancel.y;
648 }
649
650 EXPORT W cfrmwindow_open(cfrmwindow_t* window)
651 {
652         static  PAT     pat0 = {{
653                 0,
654                 16, 16,
655                 0x10efefef,
656                 0x10efefef,
657                 FILL100
658         }};
659         WID wid;
660         SIZE sz;
661
662         if (window->wid > 0) {
663                 return 0;
664         }
665
666         wid = wopn_wnd(WA_SUBW|WA_SIZE|WA_HHDL|WA_VHDL|WA_BBAR|WA_RBAR, window->parent, &(window->r), NULL, 2, window->windowtitle, &pat0, NULL);
667         if (wid < 0) {
668                 DP_ER("wopn_wnd: confirm error", wid);
669                 return wid;
670         }
671         window->wid = wid;
672         window->gid = wget_gid(wid);
673         windowscroll_settarget(&window->wscr, wid);
674
675         cfrmwindow_calclayout(window, &sz);
676         windowscroll_setdrawrect(&window->wscr, 0, 0, sz.h, sz.v);
677         windowscroll_setworkrect(&window->wscr, 0, 0, window->r.c.right, window->r.c.bottom);
678
679         window->ms_cancel_id = copn_par(wid, window->dnum_cancel, &window->pos_cancel);
680         if (window->ms_cancel_id < 0) {
681                 DP_ER("copn_par error:", window->ms_cancel_id);
682         }
683
684         window->ms_post_id = copn_par(wid, window->dnum_post, &window->pos_post);
685         if (window->ms_post_id < 0) {
686                 DP_ER("copn_par error:", window->ms_post_id);
687         }
688
689         wreq_dsp(wid);
690
691         return 0;
692 }
693
694 LOCAL W ngwordwindow_writeswitchselecterstring(ngwordwindow_t *window, TC *str)
695 {
696         wordlist_iterator_t iter;
697         Bool cont;
698         TC *nodestr;
699         W size = 0, nodelen;
700
701         wordlist_iterator_initialize(&iter, &window->wordlist);
702         if (str == NULL) {
703                 for (;;) {
704                         cont = wordlist_iterator_next(&iter, &nodestr, &nodelen);
705                         if (cont == False) {
706                                 break;
707                         }
708                         size += 1; /* MC_STR */
709                         size += nodelen;
710                 }
711                 if (size == 0) {
712                         size = 1; /* MC_STR */
713                 }
714                 size++; /* TNULL */
715         } else {
716                 for (;;) {
717                         cont = wordlist_iterator_next(&iter, &nodestr, &nodelen);
718                         if (cont == False) {
719                                 break;
720                         }
721
722                         str[size++] = MC_STR;
723                         memcpy(str + size, nodestr, nodelen * sizeof(TC));
724                         size += nodelen;
725                 }
726                 if (size == 0) {
727                         str[size++] = MC_STR;
728                 }
729                 str[size++] = TNULL;
730         }
731
732         wordlist_iterator_finalize(&iter);
733         return size + 1;
734 }
735
736 LOCAL W ngwordwindow_updatescrollselector(ngwordwindow_t *window)
737 {
738         W len;
739
740         len = ngwordwindow_writeswitchselecterstring(window, NULL);
741         window->selector = realloc(window->selector, len*sizeof(TC));
742         if (window->selector == NULL) {
743                 return -1; /* TODO */
744         }
745         ngwordwindow_writeswitchselecterstring(window, window->selector);
746         cset_dat(window->ss_list_id, (W)window->selector);
747
748         return 0;
749 }
750
751 EXPORT W ngwordwindow_open(ngwordwindow_t *window)
752 {
753         TC test[] = {TK_N, TK_G, 0x256F, 0x213C, 0x2549, 0x306C, 0x4D77,TNULL};
754         WID wid;
755         PNT pos;
756
757         if (window->wid > 0) {
758                 return 0;
759         }
760
761         wid = wopn_wnd(WA_SUBW, window->parent, &(window->r), NULL, 2, test, &window->bgpat, NULL);
762         if (wid < 0) {
763                 DP_ER("wopn_wnd: ngword error", wid);
764                 return wid;
765         }
766         window->wid = wid;
767         window->gid = wget_gid(wid);
768
769         pos.x = 0;
770         pos.y = 0;
771         window->ss_list_id = copn_par(wid, window->dnum_list, &pos);
772         if (window->ss_list_id < 0) {
773                 DP_ER("copn_par list error:", window->ss_list_id);
774         }
775         pos.x = 0;
776         pos.y = 100;
777         window->ms_delete_id = copn_par(wid, window->dnum_delete, &pos);
778         if (window->ms_delete_id < 0) {
779                 DP_ER("copn_par delete error:", window->ms_delete_id);
780         }
781         pos.x = 0;
782         pos.y = 130;
783         window->tb_input_id = copn_par(wid, window->dnum_input, &pos);
784         if (window->tb_input_id < 0) {
785                 DP_ER("copn_par input error:", window->tb_input_id);
786         }
787         pos.x = 0;
788         pos.y = 160;
789         window->ms_append_id = copn_par(wid, window->dnum_append, &pos);
790         if (window->ms_append_id < 0) {
791                 DP_ER("copn_par append error:", window->ms_append_id);
792         }
793
794         ngwordwindow_updatescrollselector(window);
795
796         wreq_dsp(wid);
797
798         return 0;
799 }
800
801 LOCAL Bool ngwordwindow_searchwordbyindex(ngwordwindow_t *window, W index, TC **str, W *len)
802 {
803         return wordlist_searchwordbyindex(&window->wordlist, index, str, len);
804 }
805
806 EXPORT W ngwordwindow_appendword(ngwordwindow_t *window, TC *str, W len)
807 {
808         W err;
809
810         err = wordlist_appendword(&window->wordlist, str, len);
811         if (err < 0) {
812                 return err;
813         }
814         return ngwordwindow_updatescrollselector(window);
815 }
816
817 EXPORT W ngwordwindow_removeword(ngwordwindow_t *window, TC *str, W len)
818 {
819         Bool removed;
820
821         removed = wordlist_removeword(&window->wordlist, str, len);
822         if (removed == True) {
823                 return ngwordwindow_updatescrollselector(window);
824         }
825         return 0;
826 }
827
828 EXPORT VOID cfrmwindow_setpostresdata(cfrmwindow_t *window, postresdata_t *post)
829 {
830         SIZE sz;
831         RECT r;
832         RECT work;
833         W err;
834
835         window->post = post;
836         if (window->wid > 0) {
837                 cfrmwindow_calclayout(window, &sz);
838                 windowscroll_setdrawrect(&window->wscr, 0, 0, sz.h, sz.v);
839
840                 work.c.left = 0;
841                 work.c.top = 0;
842                 wset_wrk(window->wid, &work);
843                 windowscroll_setworkrect(&window->wscr, work.c.left, work.c.top, work.c.right, work.c.bottom);
844
845                 r.c.left = window->pos_cancel.x;
846                 r.c.top = window->pos_cancel.y;
847                 r.c.right = r.c.left + window->sz_ms_cancel.h;
848                 r.c.bottom = r.c.top + window->sz_ms_cancel.v;
849                 err = cset_pos(window->ms_cancel_id, &r);
850                 if (err < 0) {
851                         DP_ER("cset_pos error cancel button", err);
852                 }
853                 r.c.left = window->pos_post.x;
854                 r.c.top = window->pos_post.y;
855                 r.c.right = r.c.left + window->sz_ms_post.h;
856                 r.c.bottom = r.c.top + window->sz_ms_post.v;
857                 err = cset_pos(window->ms_post_id, &r);
858                 if (err < 0) {
859                         DP_ER("cset_pos error post button", err);
860                 }
861
862                 wreq_dsp(window->wid);
863         }
864 }
865
866 LOCAL VOID cfrmwindow_draw(cfrmwindow_t *window, RECT *r)
867 {
868         TC label_from[] = {0x4C3E, 0x4130, TK_COLN, TK_KSP, TNULL};
869         TC label_mail[] = {TK_E, 0x213E, TK_m, TK_a, TK_i, TK_l, TK_COLN, TK_KSP, TNULL};
870         GID gid;
871         TC *from, *mail, *message;
872         W from_len, mail_len, message_len;
873
874         if (window->post == NULL) {
875                 return;
876         }
877
878         gid = window->gid;
879
880         from = postresdata_getfromstring(window->post);
881         from_len = postresdata_getfromstringlen(window->post);
882         mail = postresdata_getmailstring(window->post);
883         mail_len = postresdata_getmailstringlen(window->post);
884         message = postresdata_getmessagestring(window->post);
885         message_len = postresdata_getmessagestringlen(window->post);
886
887         cfrmwindow_resetgenv(window);
888         gdra_stp(gid, window->pos_from.x, window->pos_from.y + 16, label_from, 4, G_STORE);
889         tadlib_drawtext(from, from_len, gid, 0, 0);
890         cfrmwindow_resetgenv(window);
891         gdra_stp(gid, window->pos_mail.x, window->pos_mail.y + 16, label_mail, 8, G_STORE);
892         tadlib_drawtext(mail, mail_len, gid, 0, 0);
893         cfrmwindow_resetgenv(window);
894         gset_chp(gid, window->pos_message.x, window->pos_message.y + 16, True);
895         tadlib_drawtext(message, message_len, gid, -window->pos_message.x, -window->pos_message.y);
896
897         cdsp_pwd(window->wid, r, P_RDISP);
898 }
899
900 LOCAL VOID cfrmwindow_redisp(cfrmwindow_t *window)
901 {
902         RECT r;
903         do {
904                 if (wsta_dsp(window->wid, &r, NULL) == 0) {
905                         break;
906                 }
907                 wera_wnd(window->wid, &r);
908                 cfrmwindow_draw(window, &r);
909         } while (wend_dsp(window->wid) > 0);
910 }
911
912 LOCAL VOID cfrmwindow_close2(cfrmwindow_t *window)
913 {
914         WDSTAT stat;
915         W err;
916
917         windowscroll_settarget(&window->wscr, -1);
918         stat.attr = WA_STD;
919         err = wget_sts(window->wid, &stat, NULL);
920         if (err >= 0) {
921                 window->r = stat.r;
922         }
923         wcls_wnd(window->wid, CLR);
924         window->wid = -1;
925         window->gid = -1;
926         window->ms_post_id = -1;
927         window->ms_cancel_id = -1;
928 }
929
930 LOCAL VOID cfrmwindow_close(cfrmwindow_t *window, dathmievent_t *evt)
931 {
932         cfrmwindow_close2(window);
933         evt->type = DATHMIEVENT_TYPE_CONFIRM_CLOSE;
934         evt->data.confirm_close.send = False;
935 }
936
937 LOCAL VOID ngwordwindow_close(ngwordwindow_t *window)
938 {
939         WDSTAT stat;
940         W err;
941
942         stat.attr = WA_STD;
943         err = wget_sts(window->wid, &stat, NULL);
944         if (err >= 0) {
945                 window->r = stat.r;
946         }
947         cdel_pwd(window->wid, NOCLR);
948         wcls_wnd(window->wid, CLR);
949         window->wid = -1;
950         window->gid = -1;
951 }
952
953 LOCAL VOID ngwordwindow_draw(ngwordwindow_t *window, RECT *r)
954 {
955         cdsp_pwd(window->wid, r, P_RDISP);
956 }
957
958 LOCAL VOID ngwordwindow_redisp(ngwordwindow_t *window)
959 {
960         RECT r;
961         do {
962                 if (wsta_dsp(window->wid, &r, NULL) == 0) {
963                         break;
964                 }
965                 wera_wnd(window->wid, &r);
966                 ngwordwindow_draw(window, &r);
967         } while (wend_dsp(window->wid) > 0);
968 }
969
970 LOCAL VOID dathmi_weventrequest(dathmi_t *hmi, WEVENT *wev, dathmievent_t *evt)
971 {
972         WID main_wid, cfrm_wid, ngword_wid;
973
974         main_wid = dathmi_getmainWID(hmi);
975         cfrm_wid = dathmi_getcfrmWID(hmi);
976         ngword_wid = dathmi_getngwordWID(hmi);
977
978         switch (wev->g.cmd) {
979         case    W_REDISP:       /*ºÆɽ¼¨Í×µá*/
980                 if (wev->g.wid == main_wid) {
981                         evt->type = DATHMIEVENT_TYPE_THREAD_DRAW;
982                 } else if (wev->g.wid == cfrm_wid) {
983                         cfrmwindow_redisp(hmi->cfrmwindow);
984                 } else if (wev->g.wid == ngword_wid) {
985                         ngwordwindow_redisp(hmi->ngwordwindow);
986                 }
987                 break;
988         case    W_PASTE:        /*Ž¹þ¤ßÍ×µá*/
989                 if (wev->g.wid == main_wid) {
990                         evt->type = DATHMIEVENT_TYPE_THREAD_PASTE;
991                         memcpy(&hmi->mainwindow->savedwev, wev, sizeof(WEVENT));
992                 } else if (wev->g.wid == cfrm_wid) {
993                         wrsp_evt(wev, 1); /*NACK*/
994                 } else if (wev->g.wid == ngword_wid) {
995                         wrsp_evt(wev, 1); /*NACK*/
996                 }
997                 break;
998         case    W_DELETE:       /*Êݸ½ªÎ»*/
999                 wrsp_evt(wev, 0);       /*ACK*/
1000                 if (wev->g.wid == main_wid) {
1001                         evt->type = DATHMIEVENT_TYPE_THREAD_CLOSE;
1002                         evt->data.main_close.save = True;
1003                 } else if (wev->g.wid == cfrm_wid) {
1004                         cfrmwindow_close(hmi->cfrmwindow, evt);
1005                 } else if (wev->g.wid == ngword_wid) {
1006                         ngwordwindow_close(hmi->ngwordwindow);
1007                         evt->type = DATHMIEVENT_TYPE_NGWORD_CLOSE;
1008                 }
1009                 break;
1010         case    W_FINISH:       /*ÇÑ´þ½ªÎ»*/
1011                 wrsp_evt(wev, 0);       /*ACK*/
1012                 if (wev->g.wid == main_wid) {
1013                         evt->type = DATHMIEVENT_TYPE_THREAD_CLOSE;
1014                         evt->data.main_close.save = False;
1015                 } else if (wev->g.wid == cfrm_wid) {
1016                         cfrmwindow_close(hmi->cfrmwindow, evt);
1017                 } else if (wev->g.wid == ngword_wid) {
1018                         ngwordwindow_close(hmi->ngwordwindow);
1019                         evt->type = DATHMIEVENT_TYPE_NGWORD_CLOSE;
1020                 }
1021                 break;
1022         }
1023 }
1024
1025 LOCAL VOID cfrmwindow_resize(cfrmwindow_t *window)
1026 {
1027         RECT work;
1028         Bool workchange = False;
1029
1030         wget_wrk(window->wid, &work);
1031         if (work.c.left < 0) {
1032                 work.c.left = 0;
1033                 workchange = True;
1034         }
1035         if (work.c.top < 0) {
1036                 work.c.top = 0;
1037                 workchange = True;
1038         }
1039         wset_wrk(window->wid, &work);
1040         gset_vis(window->gid, work);
1041
1042         windowscroll_setworkrect(&window->wscr, work.c.left, work.c.top, work.c.right, work.c.bottom);
1043
1044         if (workchange == True) {
1045                 wera_wnd(window->wid, NULL);
1046                 wreq_dsp(window->wid);
1047         }
1048 }
1049
1050 LOCAL VOID datwindow_resize(datwindow_t *window, SIZE *sz)
1051 {
1052         RECT work;
1053         Bool workchange = False;
1054
1055         wget_wrk(window->wid, &work);
1056         if (work.c.left != 0) {
1057                 work.c.left = 0;
1058                 workchange = True;
1059         }
1060         if (work.c.top != 0) {
1061                 work.c.top = 0;
1062                 workchange = True;
1063         }
1064         wset_wrk(window->wid, &work);
1065         gset_vis(window->gid, work);
1066
1067         if (workchange == True) {
1068                 wera_wnd(window->wid, NULL);
1069                 wreq_dsp(window->wid);
1070         }
1071
1072         sz->v = work.c.bottom - work.c.top;
1073         sz->h = work.c.right - work.c.left;
1074 }
1075
1076 LOCAL VOID cfrmwindow_butdnwork(cfrmwindow_t *window, WEVENT *wev, dathmievent_t *evt)
1077 {
1078         PAID id;
1079         W ret;
1080
1081         ret = cfnd_par(window->wid, wev->s.pos, &id);
1082         if (ret <= 0) {
1083                 return;
1084         }
1085         if (id == window->ms_post_id) {
1086                 ret = cact_par(window->ms_post_id, wev);
1087                 if ((ret & 0x5000) != 0x5000) {
1088                         return;
1089                 }
1090                 cfrmwindow_close2(window);
1091                 evt->type = DATHMIEVENT_TYPE_CONFIRM_CLOSE;
1092                 evt->data.confirm_close.send = True;
1093                 return;
1094         }
1095         if (id == window->ms_cancel_id) {
1096                 ret = cact_par(window->ms_cancel_id, wev);
1097                 if ((ret & 0x5000) != 0x5000) {
1098                         return;
1099                 }
1100                 cfrmwindow_close2(window);
1101                 evt->type = DATHMIEVENT_TYPE_CONFIRM_CLOSE;
1102                 evt->data.confirm_close.send = False;
1103                 return;
1104         }
1105 }
1106
1107 LOCAL VOID ngwordwindow_butdnwork(ngwordwindow_t *window, WEVENT *wev, dathmievent_t *evt)
1108 {
1109         PAID id;
1110         W ret, len, val, err;
1111         Bool found;
1112         TC *str;
1113
1114         ret = cfnd_par(window->wid, wev->s.pos, &id);
1115         if (ret <= 0) {
1116                 return;
1117         }
1118         if (id == window->ss_list_id) {
1119                 cact_par(window->ss_list_id, wev);
1120         }
1121         if (id == window->ms_delete_id) {
1122                 ret = cact_par(window->ms_delete_id, wev);
1123                 if ((ret & 0x5000) != 0x5000) {
1124                         return;
1125                 }
1126                 err = cget_val(window->ss_list_id, 1, (W*)&val);
1127                 if (err < 0) {
1128                         DP_ER("cget_val ss_list_id error:", err);
1129                         return;
1130                 }
1131                 if (val < 0) {
1132                         return;
1133                 }
1134                 found = ngwordwindow_searchwordbyindex(window, val - 1, &str, &len);
1135                 if (found == False) {
1136                         DP(("not found in ngwordwindow parts\n"));
1137                         return;
1138                 }
1139                 memcpy(window->strbuf, str, len * sizeof(TC));
1140                 evt->type = DATHMIEVENT_TYPE_NGWORD_REMOVE;
1141                 evt->data.ngword_append.str = window->strbuf;
1142                 evt->data.ngword_append.len = len;
1143                 return;
1144         }
1145         if (id == window->tb_input_id) {
1146                 for (;;) {
1147                         ret = cact_par(window->tb_input_id, wev);
1148                         if (ret < 0) {
1149                                 DP_ER("cact_par tb_input_id error:", ret);
1150                                 return;
1151                         }
1152                         switch (ret & 0xefff) {
1153                         case P_EVENT:
1154                                 switch (wev->s.type) {
1155                                 case EV_INACT:
1156                                 case EV_REQUEST:
1157                                         wugt_evt(wev);
1158                                         return;
1159                                 case EV_DEVICE:
1160                                         oprc_dev(&wev->e, NULL, 0);
1161                                         break;
1162                                 }
1163                                 wev->s.type = EV_NULL;
1164                                 continue;
1165                         case P_MENU:
1166                                 if ((wev->s.type == EV_KEYDWN)&&(wev->s.stat & ES_CMD)) {
1167                                 } else {
1168                                 }
1169                                 wev->s.type = EV_NULL;
1170                                 continue;
1171                         case (0x4000|P_NL):
1172                         case (0x4000|P_TAB):
1173                                 return;
1174                         case (0x4000|P_BUT):
1175                                 wugt_evt(wev);
1176                                 return;
1177                         default:
1178                                 return;
1179                         }
1180                 }
1181         }
1182         if (id == window->ms_append_id) {
1183                 ret = cact_par(window->ms_append_id, wev);
1184                 if ((ret & 0x5000) != 0x5000) {
1185                         return;
1186                 }
1187                 len = cget_val(window->tb_input_id, 128, (W*)window->strbuf);
1188                 if (len <= 0) {
1189                         return;
1190                 }
1191                 evt->type = DATHMIEVENT_TYPE_NGWORD_APPEND;
1192                 evt->data.ngword_append.str = window->strbuf;
1193                 evt->data.ngword_append.len = len;
1194                 len = cset_val(window->tb_input_id, 0, NULL);
1195                 if (len < 0) {
1196                         DP_ER("cset_val tb_input_id error", len);
1197                 }
1198                 return;
1199         }
1200 }
1201
1202 LOCAL VOID dathmi_weventbutdn(dathmi_t *hmi, WEVENT *wev, dathmievent_t *evt)
1203 {
1204         W i;
1205         WID main_wid, cfrm_wid, ngword_wid;
1206
1207         main_wid = dathmi_getmainWID(hmi);
1208         cfrm_wid = dathmi_getcfrmWID(hmi);
1209         ngword_wid = dathmi_getngwordWID(hmi);
1210
1211         switch  (wev->s.cmd) {
1212         case    W_PICT:
1213                 switch (wchk_dck(wev->s.time)) {
1214                 case    W_DCLICK:
1215                         if (wev->s.wid == main_wid) {
1216                                 evt->type = DATHMIEVENT_TYPE_THREAD_CLOSE;
1217                                 evt->data.main_close.save = True; /* TODO: tmp value. */
1218                         } else if (wev->s.wid == cfrm_wid) {
1219                                 cfrmwindow_close2(hmi->cfrmwindow);
1220                                 evt->type = DATHMIEVENT_TYPE_CONFIRM_CLOSE;
1221                                 evt->data.confirm_close.send = False;
1222                         } else if (wev->s.wid == ngword_wid) {
1223                                 ngwordwindow_close(hmi->ngwordwindow);
1224                                 evt->type = DATHMIEVENT_TYPE_NGWORD_CLOSE;
1225                         }
1226                         return;
1227                 case    W_PRESS:
1228                         break;
1229                 default:
1230                         return;
1231                 }
1232         case    W_FRAM:
1233         case    W_TITL:
1234                 if (wmov_drg(wev, NULL) > 0) {
1235                         if (wev->s.wid == main_wid) {
1236                                 evt->type = DATHMIEVENT_TYPE_THREAD_DRAW;
1237                         } else if (wev->s.wid == cfrm_wid) {
1238                                 cfrmwindow_redisp(hmi->cfrmwindow);
1239                         } else if (wev->s.wid == ngword_wid) {
1240                                 ngwordwindow_redisp(hmi->ngwordwindow);
1241                         }
1242                 }
1243                 return;
1244         case    W_LTHD:
1245         case    W_RTHD:
1246         case    W_LBHD:
1247         case    W_RBHD:
1248                 switch (wchk_dck(wev->s.time)) {
1249                 case    W_DCLICK:
1250                         i = wchg_wnd(wev->s.wid, NULL, W_MOVE);
1251                         break;
1252                 case    W_PRESS:
1253                         i = wrsz_drg(wev, NULL, NULL);
1254                         break;
1255                 default:
1256                         return;
1257                 }
1258
1259                 if (wev->s.wid == main_wid) {
1260                         evt->type = DATHMIEVENT_TYPE_THREAD_RESIZE;
1261                         datwindow_resize(hmi->mainwindow, &evt->data.main_resize.work_sz);
1262                         windowscroll_updatebar(&hmi->mainwindow->wscr);
1263                         if (i > 0) {
1264                                 //evt->type = DATHMIEVENT_TYPE_THREAD_DRAW;
1265                                 /* TODO: queueing */
1266                                 evt->data.main_resize.needdraw = True;
1267                         } else {
1268                                 evt->data.main_resize.needdraw = False;
1269                         }
1270                 } else if (wev->s.wid == cfrm_wid) {
1271                         cfrmwindow_resize(hmi->cfrmwindow);
1272                         windowscroll_updatebar(&hmi->cfrmwindow->wscr);
1273                         if (i > 0) {
1274                                 cfrmwindow_redisp(hmi->cfrmwindow);
1275                         }
1276                 }
1277                 /* ngword window need not do nothing. */
1278                 return;
1279         case    W_RBAR:
1280                 if (wev->s.wid == main_wid) {
1281                         windowscroll_weventrbar(&hmi->mainwindow->wscr, wev);
1282                 } else if (wev->s.wid == cfrm_wid) {
1283                         windowscroll_weventrbar(&hmi->cfrmwindow->wscr, wev);
1284                 }
1285                 /* ngword window need not do nothing. */
1286                 return;
1287         case    W_BBAR:
1288                 if (wev->s.wid == main_wid) {
1289                         windowscroll_weventbbar(&hmi->mainwindow->wscr, wev);
1290                 } else if (wev->s.wid == cfrm_wid) {
1291                         windowscroll_weventbbar(&hmi->cfrmwindow->wscr, wev);
1292                 }
1293                 /* ngword window need not do nothing. */
1294                 return;
1295         case    W_WORK:
1296                 if (wev->s.wid == main_wid) {
1297                         evt->type = DATHMIEVENT_TYPE_THREAD_BUTDN;
1298                         evt->data.main_butdn.type = wchk_dck(wev->s.time);
1299                         evt->data.main_butdn.pos = wev->s.pos;
1300                         memcpy(&hmi->mainwindow->savedwev, wev, sizeof(WEVENT));
1301                 } else if (wev->s.wid == cfrm_wid) {
1302                         cfrmwindow_butdnwork(hmi->cfrmwindow, wev, evt);
1303                 } else if (wev->s.wid == ngword_wid) {
1304                         ngwordwindow_butdnwork(hmi->ngwordwindow, wev, evt);
1305                 }
1306                 return;
1307         }
1308
1309         return;
1310 }
1311
1312 LOCAL VOID dathmi_weventswitch(dathmi_t *hmi, WEVENT *wev, dathmievent_t *evt)
1313 {
1314         evt->type = DATHMIEVENT_TYPE_THREAD_SWITCH;
1315         evt->data.main_switch.needdraw = False;
1316         //dathmi_weventbutdn(hmi, wev, evt);
1317 }
1318
1319 LOCAL VOID dathmi_weventreswitch(dathmi_t *hmi, WEVENT *wev, dathmievent_t *evt)
1320 {
1321         WID main_wid, cfrm_wid, ngword_wid;
1322
1323         main_wid = dathmi_getmainWID(hmi);
1324         cfrm_wid = dathmi_getcfrmWID(hmi);
1325         ngword_wid = dathmi_getngwordWID(hmi);
1326
1327         if (wev->s.wid == main_wid) {
1328                 evt->type = DATHMIEVENT_TYPE_THREAD_SWITCH;
1329                 evt->data.main_switch.needdraw = True;
1330         } else if (wev->s.wid == cfrm_wid) {
1331                 cfrmwindow_redisp(hmi->cfrmwindow);
1332         } else if (wev->s.wid == ngword_wid) {
1333                 ngwordwindow_redisp(hmi->ngwordwindow);
1334         }
1335         //dathmi_weventbutdn(hmi, wev, evt); TODO: event queueing
1336 }
1337
1338 LOCAL VOID dathmi_receivemessage(dathmi_t *hmi, dathmievent_t *evt)
1339 {
1340         MESSAGE msg;
1341         W err;
1342
1343     err = rcv_msg(MM_ALL, &msg, sizeof(MESSAGE), WAIT|NOCLR);
1344         if (err >= 0) {
1345                 if (msg.msg_type == MS_TMOUT) { /* should be use other type? */
1346                         evt->type = DATHMIEVENT_TYPE_COMMON_TIMEOUT;
1347                         evt->data.common_timeout.code = msg.msg_body.TMOUT.code;
1348                 }
1349         }
1350         clr_msg(MM_ALL, MM_ALL);
1351 }
1352
1353 EXPORT W dathmi_getevent(dathmi_t *hmi, dathmievent_t **evt)
1354 {
1355         WEVENT  wev0;
1356         WID main_wid, cfrm_wid, ngword_wid;
1357
1358         main_wid = dathmi_getmainWID(hmi);
1359         cfrm_wid = dathmi_getcfrmWID(hmi);
1360         ngword_wid = dathmi_getngwordWID(hmi);
1361
1362         hmi->evt.type = DATHMIEVENT_TYPE_NONE;
1363
1364         wget_evt(&wev0, WAIT);
1365         switch (wev0.s.type) {
1366         case    EV_NULL:
1367                 if ((wev0.s.wid != main_wid)&&(wev0.s.wid != cfrm_wid)&&(wev0.s.wid != ngword_wid)) {
1368                         hmi->evt.type = DATHMIEVENT_TYPE_COMMON_MOUSEMOVE;
1369                         hmi->evt.data.common_mousemove.pos = wev0.s.pos;
1370                         break;          /*¥¦¥£¥ó¥É¥¦³°*/
1371                 }
1372                 if (wev0.s.cmd != W_WORK)
1373                         break;          /*ºî¶ÈÎΰ賰*/
1374                 if (wev0.s.stat & ES_CMD)
1375                         break;  /*Ì¿Îᥭ¡¼¤¬²¡¤µ¤ì¤Æ¤¤¤ë*/
1376                 if (wev0.s.wid == main_wid) {
1377                         hmi->evt.type = DATHMIEVENT_TYPE_THREAD_MOUSEMOVE;
1378                         hmi->evt.data.main_mousemove.pos = wev0.s.pos;
1379                         hmi->evt.data.main_mousemove.stat = wev0.s.stat;
1380                 } else if (wev0.s.wid == cfrm_wid) {
1381                         cidl_par(wev0.s.wid, &wev0.s.pos);
1382                 } else if (wev0.s.wid == ngword_wid) {
1383                         cidl_par(wev0.s.wid, &wev0.s.pos);
1384                 }
1385                 break;
1386         case    EV_REQUEST:
1387                 dathmi_weventrequest(hmi, &wev0, &hmi->evt);
1388                 break;
1389         case    EV_RSWITCH:
1390                 dathmi_weventreswitch(hmi, &wev0, &hmi->evt);
1391                 break;
1392         case    EV_SWITCH:
1393                 dathmi_weventswitch(hmi, &wev0, &hmi->evt);
1394                 break;
1395         case    EV_BUTDWN:
1396                 dathmi_weventbutdn(hmi, &wev0, &hmi->evt);
1397                 break;
1398         case    EV_KEYDWN:
1399         case    EV_AUTKEY:
1400                 hmi->evt.type = DATHMIEVENT_TYPE_COMMON_KEYDOWN;
1401                 hmi->evt.data.common_keydown.keycode = wev0.e.data.key.code;
1402                 hmi->evt.data.common_keydown.keytop = wev0.e.data.key.keytop;
1403                 hmi->evt.data.common_keydown.stat = wev0.e.stat;
1404                 break;
1405         case    EV_INACT:
1406                 pdsp_msg(NULL);
1407                 break;
1408         case    EV_DEVICE:
1409                 oprc_dev(&wev0.e, NULL, 0);
1410                 break;
1411         case    EV_MSG:
1412                 dathmi_receivemessage(hmi, &hmi->evt);
1413                 break;
1414         case    EV_MENU:
1415                 hmi->evt.type = DATHMIEVENT_TYPE_COMMON_MENU;
1416                 hmi->evt.data.common_menu.pos = wev0.s.pos;
1417                 break;
1418         }
1419
1420         *evt = &hmi->evt;
1421
1422         return 0;
1423 }
1424
1425 LOCAL VOID datwindow_scroll(VP arg, W dh, W dv)
1426 {
1427         datwindow_t *window = (datwindow_t*)arg;
1428         (*window->scroll_callback)(window->arg, dh, dv);
1429 }
1430
1431 LOCAL datwindow_t* datwindow_new(RECT *r, TC *title, PAT *bgpat, datwindow_scrollcalback scrollcallback, VP arg)
1432 {
1433         datwindow_t* window;
1434         W err;
1435
1436         window = malloc(sizeof(datwindow_t));
1437         if (window == NULL) {
1438                 return NULL;
1439         }
1440
1441         window->wid = wopn_wnd(WA_SIZE|WA_HHDL|WA_VHDL|WA_BBAR|WA_RBAR, 0, r, NULL, 1, title, bgpat, NULL);
1442         if (window->wid < 0) {
1443                 free(window);
1444                 return NULL;
1445         }
1446         err = windowscroll_initialize(&window->wscr, window->wid, datwindow_scroll, (VP)window);
1447         if (err < 0) {
1448                 wcls_wnd(window->wid, CLR);
1449                 free(window);
1450                 return NULL;
1451         }
1452         window->gid = wget_gid(window->wid);
1453         window->scroll_callback = scrollcallback;
1454         window->arg = arg;
1455
1456         return window;
1457 }
1458
1459 LOCAL VOID datwindow_delete(datwindow_t *window)
1460 {
1461         wcls_wnd(window->wid, CLR);
1462         windowscroll_finalize(&window->wscr);
1463         free(window);
1464 }
1465
1466 EXPORT datwindow_t* dathmi_newmainwindow(dathmi_t *hmi, RECT *r, TC *title, PAT *bgpat, datwindow_scrollcalback scrollcallback, VP arg)
1467 {
1468         hmi->mainwindow = datwindow_new(r, title, bgpat, scrollcallback, arg);
1469         return hmi->mainwindow;
1470 }
1471
1472 EXPORT VOID dathmi_deletemainwindow(dathmi_t *hmi, datwindow_t *window)
1473 {
1474         datwindow_delete(window);
1475         hmi->mainwindow = NULL;
1476 }
1477
1478 LOCAL VOID cfrmwindow_scroll(VP arg, W dh, W dv)
1479 {
1480         cfrmwindow_t *window = (cfrmwindow_t*)arg;
1481         wscr_wnd(window->wid, NULL, -dh, -dv, W_SCRL|W_RDSET);
1482         cfrmwindow_redisp(window);
1483 }
1484
1485 EXPORT cfrmwindow_t* cfrmwindow_new(RECT *r, WID parent, W dnum_title, W dnum_post, W dnum_cancel)
1486 {
1487         cfrmwindow_t *window;
1488         W err;
1489         SWSEL *sw;
1490
1491         window = (cfrmwindow_t*)malloc(sizeof(cfrmwindow_t));
1492         if (window == NULL) {
1493                 return NULL;
1494         }
1495         window->wid = -1;
1496         window->gid = -1;
1497         window->parent = parent;
1498         window->ms_post_id = -1;
1499         window->ms_cancel_id = -1;
1500         window->r = *r;
1501         window->post = NULL;
1502         err = windowscroll_initialize(&window->wscr, window->wid, cfrmwindow_scroll, (VP)window);
1503         if (err < 0) {
1504                 free(window);
1505                 return NULL;
1506         }
1507
1508         err = dget_dtp(TEXT_DATA, dnum_title, (void**)&window->windowtitle);
1509         if (err < 0) {
1510                 DP_ER("dget_dtp: message retrieving error", err);
1511                 windowscroll_finalize(&window->wscr);
1512                 free(window);
1513                 return NULL;
1514         }
1515
1516         err = dget_dtp(PARTS_DATA, dnum_post, (void**)&sw);
1517         if (err < 0) {
1518                 DP_ER("dget_dtp: message retrieving error", err);
1519                 windowscroll_finalize(&window->wscr);
1520                 free(window);
1521                 return NULL;
1522         }
1523         window->dnum_post = dnum_post;
1524         window->sz_ms_post.h = sw->r.c.right - sw->r.c.left;
1525         window->sz_ms_post.v = sw->r.c.bottom - sw->r.c.top;
1526
1527         err = dget_dtp(PARTS_DATA, dnum_cancel, (void**)&sw);
1528         if (err < 0) {
1529                 DP_ER("dget_dtp: message retrieving error", err);
1530                 windowscroll_finalize(&window->wscr);
1531                 free(window);
1532                 return NULL;
1533         }
1534         window->dnum_cancel = dnum_cancel;
1535         window->sz_ms_cancel.h = sw->r.c.right - sw->r.c.left;
1536         window->sz_ms_cancel.v = sw->r.c.bottom - sw->r.c.top;
1537
1538         return window;
1539 }
1540
1541 EXPORT cfrmwindow_t *dathmi_newconfirmwindow(dathmi_t *hmi, RECT *r, W dnum_title, W dnum_post, W dnum_cancel)
1542 {
1543         W main_wid;
1544         main_wid = dathmi_getmainWID(hmi);
1545         if (main_wid < 0) {
1546                 DP_ER("main window not exist", 0);
1547                 return NULL;
1548         }
1549         hmi->cfrmwindow = cfrmwindow_new(r, main_wid, dnum_title, dnum_post, dnum_cancel);
1550         return hmi->cfrmwindow;
1551 }
1552
1553 LOCAL VOID cfrmwindow_delete(cfrmwindow_t *window)
1554 {
1555         if (window->wid > 0) {
1556                 wcls_wnd(window->wid, CLR);
1557         }
1558         windowscroll_finalize(&window->wscr);
1559         free(window);
1560 }
1561
1562 EXPORT VOID dathmi_deleteconfirmwindow(dathmi_t *hmi, cfrmwindow_t *window)
1563 {
1564         cfrmwindow_delete(window);
1565         hmi->cfrmwindow = NULL;
1566 }
1567
1568 LOCAL ngwordwindow_t* ngwordwindow_new(PNT *p, WID parent, W dnum_list, W dnum_delete, W dnum_input, W dnum_append)
1569 {
1570         ngwordwindow_t *window;
1571         W err;
1572
1573         window = (ngwordwindow_t*)malloc(sizeof(ngwordwindow_t));
1574         if (window == NULL) {
1575                 DP_ER("malloc error:", 0);
1576                 return NULL;
1577         }
1578         window->wid = -1;
1579         window->gid = -1;
1580         window->parent = parent;
1581         window->r.p.lefttop = *p;
1582         window->r.p.rightbot.x = p->x + 300 + 7;
1583         window->r.p.rightbot.y = p->y + 200 + 30;
1584         err = wget_inf(WI_PANELBACK, &window->bgpat, sizeof(PAT));
1585         if (err != sizeof(PAT)) {
1586                 DP_ER("wget_inf error:", err);
1587                 window->bgpat.spat.kind = 0;
1588                 window->bgpat.spat.hsize = 16;
1589                 window->bgpat.spat.vsize = 16;
1590                 window->bgpat.spat.fgcol = 0x10ffffff;
1591                 window->bgpat.spat.bgcol = 0;
1592                 window->bgpat.spat.mask = FILL100;
1593         }
1594         window->dnum_list = dnum_list;
1595         window->dnum_delete = dnum_delete;
1596         window->dnum_input = dnum_input;
1597         window->dnum_append = dnum_append;
1598         window->ss_list_id = -1;
1599         window->ms_delete_id = -1;
1600         window->tb_input_id = -1;
1601         window->ms_append_id = -1;
1602         wordlist_initialize(&window->wordlist);
1603         window->selector = NULL;
1604
1605         return window;
1606 }
1607
1608 LOCAL VOID ngwordwindow_delete(ngwordwindow_t *window)
1609 {
1610         wordlist_finalize(&window->wordlist);
1611         if (window->wid > 0) {
1612                 cdel_pwd(window->wid, NOCLR);
1613                 wcls_wnd(window->wid, CLR);
1614         }
1615         free(window);
1616 }
1617
1618 EXPORT ngwordwindow_t *dathmi_newngwordwindow(dathmi_t *hmi, PNT *p, W dnum_list, W dnum_delete, W dnum_input, W dnum_append)
1619 {
1620         W main_wid;
1621         main_wid = dathmi_getmainWID(hmi);
1622         if (main_wid < 0) {
1623                 DP_ER("main window not exist", 0);
1624                 return NULL;
1625         }
1626         hmi->ngwordwindow = ngwordwindow_new(p, main_wid, dnum_list, dnum_delete, dnum_input, dnum_append);
1627         return hmi->ngwordwindow;
1628 }
1629
1630 EXPORT VOID dathmi_deletengwordwindow(dathmi_t *hmi, ngwordwindow_t *window)
1631 {
1632         ngwordwindow_delete(window);
1633         hmi->ngwordwindow = NULL;
1634 }
1635
1636 EXPORT dathmi_t* dathmi_new()
1637 {
1638         dathmi_t *hmi;
1639
1640         hmi = (dathmi_t *)malloc(sizeof(dathmi_t));
1641         if (hmi == NULL) {
1642                 return NULL;
1643         }
1644         hmi->mainwindow = NULL;
1645         hmi->cfrmwindow = NULL;
1646         hmi->ngwordwindow = NULL;
1647
1648         return hmi;
1649 }
1650
1651 EXPORT VOID dathmi_delete(dathmi_t *hmi)
1652 {
1653         if (hmi->ngwordwindow != NULL) {
1654                 ngwordwindow_delete(hmi->ngwordwindow);
1655         }
1656         if (hmi->cfrmwindow != NULL) {
1657                 cfrmwindow_delete(hmi->cfrmwindow);
1658         }
1659         if (hmi->mainwindow != NULL) {
1660                 datwindow_delete(hmi->mainwindow);
1661         }
1662         free(hmi);
1663 }