OSDN Git Service

change textbox interface.
[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         WEVENT savedwev;
404         wordlist_t wordlist;
405         TC strbuf[128];
406         TC *selector;
407 };
408
409 struct dathmi_t_ {
410         dathmievent_t evt;
411         datwindow_t *mainwindow;
412         cfrmwindow_t *cfrmwindow;
413         ngwordwindow_t *ngwordwindow;
414 };
415
416 EXPORT W datwindow_startredisp(datwindow_t *window, RECT *r)
417 {
418         return wsta_dsp(window->wid, r, NULL);
419 }
420
421 EXPORT W datwindow_endredisp(datwindow_t *window)
422 {
423         return wend_dsp(window->wid);
424 }
425
426 EXPORT W datwindow_eraseworkarea(datwindow_t *window, RECT *r)
427 {
428         return wera_wnd(window->wid, r);
429 }
430
431 EXPORT W datwindow_scrollworkarea(datwindow_t *window, W dh, W dv)
432 {
433         return wscr_wnd(window->wid, NULL, dh, dv, W_MOVE|W_RDSET);
434 }
435
436 EXPORT VOID datwindow_scrollbyvalue(datwindow_t *window, W dh, W dv)
437 {
438         windowscroll_scrollbyvalue(&window->wscr, dh, dv);
439 }
440
441 EXPORT W datwindow_requestredisp(datwindow_t *window)
442 {
443         return wreq_dsp(window->wid);
444 }
445
446 EXPORT GID datwindow_startdrag(datwindow_t *window)
447 {
448         return wsta_drg(window->wid, 0);
449 }
450
451 EXPORT W datwindow_getdrag(datwindow_t *window, PNT *pos, WID *wid, PNT *pos_butup)
452 {
453         W etype;
454
455         etype = wget_drg(pos, &window->savedwev);
456         *wid = window->savedwev.s.wid;
457         if (etype == EV_BUTUP) {
458                 *pos_butup = window->savedwev.s.pos;
459         }
460
461         return etype;
462 }
463
464 EXPORT VOID datwindow_enddrag(datwindow_t *window)
465 {
466         wend_drg();
467 }
468
469 EXPORT VOID datwindow_responsepasterequest(datwindow_t *window, W nak, PNT *pos)
470 {
471         if (pos != NULL) {
472                 window->savedwev.r.r.p.rightbot.x = pos->x;
473                 window->savedwev.r.r.p.rightbot.y = pos->y;
474         }
475         wrsp_evt(&window->savedwev, nak);
476 }
477
478 EXPORT W datwindow_getworkrect(datwindow_t *window, RECT *r)
479 {
480         return wget_wrk(window->wid, r);
481 }
482
483 EXPORT GID datwindow_getGID(datwindow_t *window)
484 {
485         return wget_gid(window->wid);
486 }
487
488 EXPORT WID datwindow_getWID(datwindow_t *window)
489 {
490         return window->wid;
491 }
492
493 EXPORT W datwindow_settitle(datwindow_t *window, TC *title)
494 {
495         return wset_tit(window->wid, -1, title, 0);
496 }
497
498 EXPORT W datwindow_setdrawrect(datwindow_t *window, W l, W t, W r, W b)
499 {
500         return windowscroll_setdrawrect(&window->wscr, l, t, r, b);
501 }
502
503 EXPORT W datwindow_setworkrect(datwindow_t *window, W l, W t, W r, W b)
504 {
505         return windowscroll_setworkrect(&window->wscr, l, t, r, b);
506 }
507
508 LOCAL WID dathmi_getmainWID(dathmi_t *hmi)
509 {
510         if (hmi->mainwindow == NULL) {
511                 return -1;
512         }
513         return hmi->mainwindow->wid;
514 }
515
516 LOCAL WID dathmi_getcfrmWID(dathmi_t *hmi)
517 {
518         if (hmi->cfrmwindow == NULL) {
519                 return -1;
520         }
521         return hmi->cfrmwindow->wid;
522 }
523
524 LOCAL WID dathmi_getngwordWID(dathmi_t *hmi)
525 {
526         if (hmi->ngwordwindow == NULL) {
527                 return -1;
528         }
529         return hmi->ngwordwindow->wid;
530 }
531
532 /* TODO: same as layoutstyle_resetgenvfont */
533 LOCAL VOID cfrmwindow_resetgenv(cfrmwindow_t *window)
534 {
535         FSSPEC spec;
536         GID gid;
537
538         gid = window->gid;
539
540         gget_fon(gid, &spec, NULL);
541         spec.attr |= FT_PROP;
542         spec.attr |= FT_GRAYSCALE;
543         spec.fclass = FTC_DEFAULT;
544         spec.size.h = 16;
545         spec.size.v = 16;
546         gset_fon(gid, &spec);
547         gset_chc(gid, 0x10000000, 0x10efefef);
548
549         return;
550 }
551
552 #define CFRMWINDOW_LAYOUT_WHOLE_MARGIN 5
553 #define CFRMWINDOW_LAYOUT_FROM_MARGIN 0
554 #define CFRMWINDOW_LAYOUT_MAIL_MARGIN 0
555 #define CFRMWINDOW_LAYOUT_MESSAGE_MARGIN 16
556 #define CFRMWINDOW_LAYOUT_BUTTON_MARGIN 5
557
558 LOCAL VOID cfrmwindow_calclayout(cfrmwindow_t *window, SIZE *sz)
559 {
560         SIZE sz_from = {0,0}, sz_mail = {0,0}, sz_msg = {0,0}, sz_button = {0,0};
561         TC label_from[] = {0x4C3E, 0x4130, TK_COLN, TK_KSP, TNULL};
562         TC label_mail[] = {TK_E, 0x213E, TK_m, TK_a, TK_i, TK_l, TK_COLN, TK_KSP, TNULL};
563         GID gid;
564         W width_from, width_mail;
565         actionlist_t *alist_from = NULL, *alist_mail = NULL, *alist_message = NULL;
566         TC *from, *mail, *message;
567         W from_len, mail_len, message_len;
568
569         sz->h = 0;
570         sz->v = 0;
571
572         if (window->post == NULL) {
573                 return;
574         }
575
576         gid = window->gid;
577
578         from = postresdata_getfromstring(window->post);
579         from_len = postresdata_getfromstringlen(window->post);
580         mail = postresdata_getmailstring(window->post);
581         mail_len = postresdata_getmailstringlen(window->post);
582         message = postresdata_getmessagestring(window->post);
583         message_len = postresdata_getmessagestringlen(window->post);
584
585         cfrmwindow_resetgenv(window);
586         width_from = gget_stw(gid, label_from, 4, NULL, NULL);
587         if (width_from < 0) {
588                 return;
589         }
590         tadlib_calcdrawsize(from, from_len, gid, &sz_from, &alist_from);
591         sz_from.h += width_from + CFRMWINDOW_LAYOUT_FROM_MARGIN * 2;
592         sz_from.v += CFRMWINDOW_LAYOUT_FROM_MARGIN * 2;
593
594         if (alist_from != NULL) {
595                 actionlist_delete(alist_from);
596         }
597         cfrmwindow_resetgenv(window);
598         width_mail = gget_stw(gid, label_mail, 4, NULL, NULL);
599         if (width_mail < 0) {
600                 return;
601         }
602         tadlib_calcdrawsize(mail, mail_len, gid, &sz_mail, &alist_mail);
603         sz_mail.h += width_mail + CFRMWINDOW_LAYOUT_MAIL_MARGIN * 2;
604         sz_mail.v += CFRMWINDOW_LAYOUT_MAIL_MARGIN * 2;
605
606         if (alist_mail != NULL) {
607                 actionlist_delete(alist_mail);
608         }
609         cfrmwindow_resetgenv(window);
610         tadlib_calcdrawsize(message, message_len, gid, &sz_msg, &alist_message);
611         if (alist_message != NULL) {
612                 actionlist_delete(alist_message);
613         }
614         sz_msg.h += CFRMWINDOW_LAYOUT_MESSAGE_MARGIN * 2;
615         sz_msg.v += CFRMWINDOW_LAYOUT_MESSAGE_MARGIN * 2;
616
617         sz_button.h = window->sz_ms_post.h + window->sz_ms_cancel.h + CFRMWINDOW_LAYOUT_BUTTON_MARGIN * 4;
618         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;
619
620         sz->v += sz_from.v;
621         if (sz->h < sz_from.h) {
622                 sz->h = sz_from.h;
623         }
624         sz->v += sz_mail.v;
625         if (sz->h < sz_mail.h) {
626                 sz->h = sz_mail.h;
627         }
628         sz->v += sz_msg.v;
629         if (sz->h < sz_msg.h) {
630                 sz->h = sz_msg.h;
631         }
632         sz->v += sz_button.v;
633         if (sz->h < sz_button.h) {
634                 sz->h = sz_button.h;
635         }
636         sz->h += CFRMWINDOW_LAYOUT_WHOLE_MARGIN * 2;
637         sz->v += CFRMWINDOW_LAYOUT_WHOLE_MARGIN * 2;
638
639         window->pos_from.x = CFRMWINDOW_LAYOUT_WHOLE_MARGIN + CFRMWINDOW_LAYOUT_FROM_MARGIN;
640         window->pos_from.y = CFRMWINDOW_LAYOUT_WHOLE_MARGIN + CFRMWINDOW_LAYOUT_FROM_MARGIN;
641         window->pos_mail.x = CFRMWINDOW_LAYOUT_WHOLE_MARGIN + CFRMWINDOW_LAYOUT_MAIL_MARGIN;
642         window->pos_mail.y = CFRMWINDOW_LAYOUT_WHOLE_MARGIN + sz_from.v + CFRMWINDOW_LAYOUT_MAIL_MARGIN;
643         window->pos_message.x = CFRMWINDOW_LAYOUT_WHOLE_MARGIN + CFRMWINDOW_LAYOUT_MESSAGE_MARGIN;
644         window->pos_message.y = CFRMWINDOW_LAYOUT_WHOLE_MARGIN + sz_from.v + sz_mail.v + CFRMWINDOW_LAYOUT_MESSAGE_MARGIN;
645         window->pos_cancel.x = CFRMWINDOW_LAYOUT_WHOLE_MARGIN + CFRMWINDOW_LAYOUT_BUTTON_MARGIN;
646         window->pos_cancel.y = CFRMWINDOW_LAYOUT_WHOLE_MARGIN + sz_from.v + sz_mail.v + sz_msg.v + CFRMWINDOW_LAYOUT_BUTTON_MARGIN;
647         window->pos_post.x = window->pos_cancel.x + window->sz_ms_cancel.h + CFRMWINDOW_LAYOUT_BUTTON_MARGIN;
648         window->pos_post.y = window->pos_cancel.y;
649 }
650
651 EXPORT W cfrmwindow_open(cfrmwindow_t* window)
652 {
653         static  PAT     pat0 = {{
654                 0,
655                 16, 16,
656                 0x10efefef,
657                 0x10efefef,
658                 FILL100
659         }};
660         WID wid;
661         SIZE sz;
662
663         if (window->wid > 0) {
664                 return 0;
665         }
666
667         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);
668         if (wid < 0) {
669                 DP_ER("wopn_wnd: confirm error", wid);
670                 return wid;
671         }
672         window->wid = wid;
673         window->gid = wget_gid(wid);
674         windowscroll_settarget(&window->wscr, wid);
675
676         cfrmwindow_calclayout(window, &sz);
677         windowscroll_setdrawrect(&window->wscr, 0, 0, sz.h, sz.v);
678         windowscroll_setworkrect(&window->wscr, 0, 0, window->r.c.right, window->r.c.bottom);
679
680         window->ms_cancel_id = copn_par(wid, window->dnum_cancel, &window->pos_cancel);
681         if (window->ms_cancel_id < 0) {
682                 DP_ER("copn_par error:", window->ms_cancel_id);
683         }
684
685         window->ms_post_id = copn_par(wid, window->dnum_post, &window->pos_post);
686         if (window->ms_post_id < 0) {
687                 DP_ER("copn_par error:", window->ms_post_id);
688         }
689
690         wreq_dsp(wid);
691
692         return 0;
693 }
694
695 LOCAL W ngwordwindow_writeswitchselecterstring(ngwordwindow_t *window, TC *str)
696 {
697         wordlist_iterator_t iter;
698         Bool cont;
699         TC *nodestr;
700         W size = 0, nodelen;
701
702         wordlist_iterator_initialize(&iter, &window->wordlist);
703         if (str == NULL) {
704                 for (;;) {
705                         cont = wordlist_iterator_next(&iter, &nodestr, &nodelen);
706                         if (cont == False) {
707                                 break;
708                         }
709                         size += 1; /* MC_STR */
710                         size += nodelen;
711                 }
712                 if (size == 0) {
713                         size = 1; /* MC_STR */
714                 }
715                 size++; /* TNULL */
716         } else {
717                 for (;;) {
718                         cont = wordlist_iterator_next(&iter, &nodestr, &nodelen);
719                         if (cont == False) {
720                                 break;
721                         }
722
723                         str[size++] = MC_STR;
724                         memcpy(str + size, nodestr, nodelen * sizeof(TC));
725                         size += nodelen;
726                 }
727                 if (size == 0) {
728                         str[size++] = MC_STR;
729                 }
730                 str[size++] = TNULL;
731         }
732
733         wordlist_iterator_finalize(&iter);
734         return size + 1;
735 }
736
737 LOCAL W ngwordwindow_updatescrollselector(ngwordwindow_t *window)
738 {
739         W len;
740
741         len = ngwordwindow_writeswitchselecterstring(window, NULL);
742         window->selector = realloc(window->selector, len*sizeof(TC));
743         if (window->selector == NULL) {
744                 return -1; /* TODO */
745         }
746         ngwordwindow_writeswitchselecterstring(window, window->selector);
747         cset_dat(window->ss_list_id, (W)window->selector);
748
749         return 0;
750 }
751
752 EXPORT W ngwordwindow_open(ngwordwindow_t *window)
753 {
754         TC test[] = {TK_N, TK_G, 0x256F, 0x213C, 0x2549, 0x306C, 0x4D77,TNULL};
755         WID wid;
756         PNT pos;
757
758         if (window->wid > 0) {
759                 return 0;
760         }
761
762         wid = wopn_wnd(WA_SUBW, window->parent, &(window->r), NULL, 2, test, &window->bgpat, NULL);
763         if (wid < 0) {
764                 DP_ER("wopn_wnd: ngword error", wid);
765                 return wid;
766         }
767         window->wid = wid;
768         window->gid = wget_gid(wid);
769
770         pos.x = 0;
771         pos.y = 0;
772         window->ss_list_id = copn_par(wid, window->dnum_list, &pos);
773         if (window->ss_list_id < 0) {
774                 DP_ER("copn_par list error:", window->ss_list_id);
775         }
776         pos.x = 0;
777         pos.y = 100;
778         window->ms_delete_id = copn_par(wid, window->dnum_delete, &pos);
779         if (window->ms_delete_id < 0) {
780                 DP_ER("copn_par delete error:", window->ms_delete_id);
781         }
782         pos.x = 0;
783         pos.y = 130;
784         window->tb_input_id = copn_par(wid, window->dnum_input, &pos);
785         if (window->tb_input_id < 0) {
786                 DP_ER("copn_par input error:", window->tb_input_id);
787         }
788         pos.x = 0;
789         pos.y = 160;
790         window->ms_append_id = copn_par(wid, window->dnum_append, &pos);
791         if (window->ms_append_id < 0) {
792                 DP_ER("copn_par append error:", window->ms_append_id);
793         }
794
795         ngwordwindow_updatescrollselector(window);
796
797         wreq_dsp(wid);
798
799         return 0;
800 }
801
802 LOCAL Bool ngwordwindow_searchwordbyindex(ngwordwindow_t *window, W index, TC **str, W *len)
803 {
804         return wordlist_searchwordbyindex(&window->wordlist, index, str, len);
805 }
806
807 EXPORT W ngwordwindow_appendword(ngwordwindow_t *window, TC *str, W len)
808 {
809         W err;
810
811         err = wordlist_appendword(&window->wordlist, str, len);
812         if (err < 0) {
813                 return err;
814         }
815         return ngwordwindow_updatescrollselector(window);
816 }
817
818 EXPORT W ngwordwindow_removeword(ngwordwindow_t *window, TC *str, W len)
819 {
820         Bool removed;
821
822         removed = wordlist_removeword(&window->wordlist, str, len);
823         if (removed == True) {
824                 return ngwordwindow_updatescrollselector(window);
825         }
826         return 0;
827 }
828
829 LOCAL Bool ngwordwindow_isopen(ngwordwindow_t *window)
830 {
831         if (window->wid < 0) {
832                 return False;
833         }
834         return True;
835 }
836
837 EXPORT VOID cfrmwindow_setpostresdata(cfrmwindow_t *window, postresdata_t *post)
838 {
839         SIZE sz;
840         RECT r;
841         RECT work;
842         W err;
843
844         window->post = post;
845         if (window->wid > 0) {
846                 cfrmwindow_calclayout(window, &sz);
847                 windowscroll_setdrawrect(&window->wscr, 0, 0, sz.h, sz.v);
848
849                 work.c.left = 0;
850                 work.c.top = 0;
851                 wset_wrk(window->wid, &work);
852                 windowscroll_setworkrect(&window->wscr, work.c.left, work.c.top, work.c.right, work.c.bottom);
853
854                 r.c.left = window->pos_cancel.x;
855                 r.c.top = window->pos_cancel.y;
856                 r.c.right = r.c.left + window->sz_ms_cancel.h;
857                 r.c.bottom = r.c.top + window->sz_ms_cancel.v;
858                 err = cset_pos(window->ms_cancel_id, &r);
859                 if (err < 0) {
860                         DP_ER("cset_pos error cancel button", err);
861                 }
862                 r.c.left = window->pos_post.x;
863                 r.c.top = window->pos_post.y;
864                 r.c.right = r.c.left + window->sz_ms_post.h;
865                 r.c.bottom = r.c.top + window->sz_ms_post.v;
866                 err = cset_pos(window->ms_post_id, &r);
867                 if (err < 0) {
868                         DP_ER("cset_pos error post button", err);
869                 }
870
871                 wreq_dsp(window->wid);
872         }
873 }
874
875 LOCAL VOID cfrmwindow_draw(cfrmwindow_t *window, RECT *r)
876 {
877         TC label_from[] = {0x4C3E, 0x4130, TK_COLN, TK_KSP, TNULL};
878         TC label_mail[] = {TK_E, 0x213E, TK_m, TK_a, TK_i, TK_l, TK_COLN, TK_KSP, TNULL};
879         GID gid;
880         TC *from, *mail, *message;
881         W from_len, mail_len, message_len;
882
883         if (window->post == NULL) {
884                 return;
885         }
886
887         gid = window->gid;
888
889         from = postresdata_getfromstring(window->post);
890         from_len = postresdata_getfromstringlen(window->post);
891         mail = postresdata_getmailstring(window->post);
892         mail_len = postresdata_getmailstringlen(window->post);
893         message = postresdata_getmessagestring(window->post);
894         message_len = postresdata_getmessagestringlen(window->post);
895
896         cfrmwindow_resetgenv(window);
897         gdra_stp(gid, window->pos_from.x, window->pos_from.y + 16, label_from, 4, G_STORE);
898         tadlib_drawtext(from, from_len, gid, 0, 0);
899         cfrmwindow_resetgenv(window);
900         gdra_stp(gid, window->pos_mail.x, window->pos_mail.y + 16, label_mail, 8, G_STORE);
901         tadlib_drawtext(mail, mail_len, gid, 0, 0);
902         cfrmwindow_resetgenv(window);
903         gset_chp(gid, window->pos_message.x, window->pos_message.y + 16, True);
904         tadlib_drawtext(message, message_len, gid, -window->pos_message.x, -window->pos_message.y);
905
906         cdsp_pwd(window->wid, r, P_RDISP);
907 }
908
909 LOCAL VOID cfrmwindow_redisp(cfrmwindow_t *window)
910 {
911         RECT r;
912         do {
913                 if (wsta_dsp(window->wid, &r, NULL) == 0) {
914                         break;
915                 }
916                 wera_wnd(window->wid, &r);
917                 cfrmwindow_draw(window, &r);
918         } while (wend_dsp(window->wid) > 0);
919 }
920
921 LOCAL VOID cfrmwindow_close2(cfrmwindow_t *window)
922 {
923         WDSTAT stat;
924         W err;
925
926         windowscroll_settarget(&window->wscr, -1);
927         stat.attr = WA_STD;
928         err = wget_sts(window->wid, &stat, NULL);
929         if (err >= 0) {
930                 window->r = stat.r;
931         }
932         wcls_wnd(window->wid, CLR);
933         window->wid = -1;
934         window->gid = -1;
935         window->ms_post_id = -1;
936         window->ms_cancel_id = -1;
937 }
938
939 LOCAL VOID cfrmwindow_close(cfrmwindow_t *window, dathmievent_t *evt)
940 {
941         cfrmwindow_close2(window);
942         evt->type = DATHMIEVENT_TYPE_CONFIRM_CLOSE;
943         evt->data.confirm_close.send = False;
944 }
945
946 LOCAL VOID ngwordwindow_close(ngwordwindow_t *window)
947 {
948         WDSTAT stat;
949         W err;
950
951         stat.attr = WA_STD;
952         err = wget_sts(window->wid, &stat, NULL);
953         if (err >= 0) {
954                 window->r = stat.r;
955         }
956         cdel_pwd(window->wid, NOCLR);
957         wcls_wnd(window->wid, CLR);
958         window->wid = -1;
959         window->gid = -1;
960 }
961
962 LOCAL VOID ngwordwindow_draw(ngwordwindow_t *window, RECT *r)
963 {
964         cdsp_pwd(window->wid, r, P_RDISP);
965 }
966
967 LOCAL VOID ngwordwindow_redisp(ngwordwindow_t *window)
968 {
969         RECT r;
970         do {
971                 if (wsta_dsp(window->wid, &r, NULL) == 0) {
972                         break;
973                 }
974                 wera_wnd(window->wid, &r);
975                 ngwordwindow_draw(window, &r);
976         } while (wend_dsp(window->wid) > 0);
977 }
978
979 LOCAL VOID dathmi_weventrequest(dathmi_t *hmi, WEVENT *wev, dathmievent_t *evt)
980 {
981         WID main_wid, cfrm_wid, ngword_wid;
982
983         main_wid = dathmi_getmainWID(hmi);
984         cfrm_wid = dathmi_getcfrmWID(hmi);
985         ngword_wid = dathmi_getngwordWID(hmi);
986
987         switch (wev->g.cmd) {
988         case    W_REDISP:       /*ºÆɽ¼¨Í×µá*/
989                 if (wev->g.wid == main_wid) {
990                         evt->type = DATHMIEVENT_TYPE_THREAD_DRAW;
991                 } else if (wev->g.wid == cfrm_wid) {
992                         cfrmwindow_redisp(hmi->cfrmwindow);
993                 } else if (wev->g.wid == ngword_wid) {
994                         ngwordwindow_redisp(hmi->ngwordwindow);
995                 }
996                 break;
997         case    W_PASTE:        /*Ž¹þ¤ßÍ×µá*/
998                 if (wev->g.wid == main_wid) {
999                         evt->type = DATHMIEVENT_TYPE_THREAD_PASTE;
1000                         memcpy(&hmi->mainwindow->savedwev, wev, sizeof(WEVENT));
1001                 } else if (wev->g.wid == cfrm_wid) {
1002                         wrsp_evt(wev, 1); /*NACK*/
1003                 } else if (wev->g.wid == ngword_wid) {
1004                         wrsp_evt(wev, 1); /*NACK*/
1005                 }
1006                 break;
1007         case    W_DELETE:       /*Êݸ½ªÎ»*/
1008                 wrsp_evt(wev, 0);       /*ACK*/
1009                 if (wev->g.wid == main_wid) {
1010                         evt->type = DATHMIEVENT_TYPE_THREAD_CLOSE;
1011                         evt->data.main_close.save = True;
1012                 } else if (wev->g.wid == cfrm_wid) {
1013                         cfrmwindow_close(hmi->cfrmwindow, evt);
1014                 } else if (wev->g.wid == ngword_wid) {
1015                         ngwordwindow_close(hmi->ngwordwindow);
1016                         evt->type = DATHMIEVENT_TYPE_NGWORD_CLOSE;
1017                 }
1018                 break;
1019         case    W_FINISH:       /*ÇÑ´þ½ªÎ»*/
1020                 wrsp_evt(wev, 0);       /*ACK*/
1021                 if (wev->g.wid == main_wid) {
1022                         evt->type = DATHMIEVENT_TYPE_THREAD_CLOSE;
1023                         evt->data.main_close.save = False;
1024                 } else if (wev->g.wid == cfrm_wid) {
1025                         cfrmwindow_close(hmi->cfrmwindow, evt);
1026                 } else if (wev->g.wid == ngword_wid) {
1027                         ngwordwindow_close(hmi->ngwordwindow);
1028                         evt->type = DATHMIEVENT_TYPE_NGWORD_CLOSE;
1029                 }
1030                 break;
1031         }
1032 }
1033
1034 LOCAL VOID cfrmwindow_resize(cfrmwindow_t *window)
1035 {
1036         RECT work;
1037         Bool workchange = False;
1038
1039         wget_wrk(window->wid, &work);
1040         if (work.c.left < 0) {
1041                 work.c.left = 0;
1042                 workchange = True;
1043         }
1044         if (work.c.top < 0) {
1045                 work.c.top = 0;
1046                 workchange = True;
1047         }
1048         wset_wrk(window->wid, &work);
1049         gset_vis(window->gid, work);
1050
1051         windowscroll_setworkrect(&window->wscr, work.c.left, work.c.top, work.c.right, work.c.bottom);
1052
1053         if (workchange == True) {
1054                 wera_wnd(window->wid, NULL);
1055                 wreq_dsp(window->wid);
1056         }
1057 }
1058
1059 LOCAL VOID datwindow_resize(datwindow_t *window, SIZE *sz)
1060 {
1061         RECT work;
1062         Bool workchange = False;
1063
1064         wget_wrk(window->wid, &work);
1065         if (work.c.left != 0) {
1066                 work.c.left = 0;
1067                 workchange = True;
1068         }
1069         if (work.c.top != 0) {
1070                 work.c.top = 0;
1071                 workchange = True;
1072         }
1073         wset_wrk(window->wid, &work);
1074         gset_vis(window->gid, work);
1075
1076         if (workchange == True) {
1077                 wera_wnd(window->wid, NULL);
1078                 wreq_dsp(window->wid);
1079         }
1080
1081         sz->v = work.c.bottom - work.c.top;
1082         sz->h = work.c.right - work.c.left;
1083 }
1084
1085 LOCAL VOID cfrmwindow_butdnwork(cfrmwindow_t *window, WEVENT *wev, dathmievent_t *evt)
1086 {
1087         PAID id;
1088         W ret;
1089
1090         ret = cfnd_par(window->wid, wev->s.pos, &id);
1091         if (ret <= 0) {
1092                 return;
1093         }
1094         if (id == window->ms_post_id) {
1095                 ret = cact_par(window->ms_post_id, wev);
1096                 if ((ret & 0x5000) != 0x5000) {
1097                         return;
1098                 }
1099                 cfrmwindow_close2(window);
1100                 evt->type = DATHMIEVENT_TYPE_CONFIRM_CLOSE;
1101                 evt->data.confirm_close.send = True;
1102                 return;
1103         }
1104         if (id == window->ms_cancel_id) {
1105                 ret = cact_par(window->ms_cancel_id, wev);
1106                 if ((ret & 0x5000) != 0x5000) {
1107                         return;
1108                 }
1109                 cfrmwindow_close2(window);
1110                 evt->type = DATHMIEVENT_TYPE_CONFIRM_CLOSE;
1111                 evt->data.confirm_close.send = False;
1112                 return;
1113         }
1114 }
1115
1116 EXPORT W ngwordwindow_starttextboxaction(ngwordwindow_t *window)
1117 {
1118         return 0;
1119 }
1120
1121 EXPORT W ngwordwindow_gettextboxaction(ngwordwindow_t *window, TC *key)
1122 {
1123         W ret;
1124         WEVENT *wev;
1125
1126         wev = &window->savedwev;
1127
1128         for (;;) {
1129                 ret = cact_par(window->tb_input_id, wev);
1130                 if (ret < 0) {
1131                         DP_ER("cact_par tb_input_id error:", ret);
1132                         return ret;
1133                 }
1134                 switch (ret & 0xefff) {
1135                 case P_EVENT:
1136                         switch (wev->s.type) {
1137                         case EV_INACT:
1138                         case EV_REQUEST:
1139                                 wugt_evt(wev);
1140                                 return NGWORDWINDOW_GETTEXTBOXACTION_FINISH;
1141                         case EV_DEVICE:
1142                                 oprc_dev(&wev->e, NULL, 0);
1143                                 break;
1144                         }
1145                         wev->s.type = EV_NULL;
1146                         continue;
1147                 case P_MENU:
1148                         wev->s.type = EV_NULL;
1149                         if ((wev->s.type == EV_KEYDWN)&&(wev->s.stat & ES_CMD)) {
1150                                 *key = wev->e.data.key.code;
1151                                 return NGWORDWINDOW_GETTEXTBOXACTION_KEYMENU;
1152                         }
1153                         return NGWORDWINDOW_GETTEXTBOXACTION_MENU;
1154                 case (0x4000|P_MOVE):
1155                         return NGWORDWINDOW_GETTEXTBOXACTION_MOVE;
1156                 case (0x4000|P_COPY):
1157                         return NGWORDWINDOW_GETTEXTBOXACTION_COPY;
1158                 case (0x4000|P_NL):
1159                 case (0x4000|P_TAB):
1160                         return NGWORDWINDOW_GETTEXTBOXACTION_FINISH;
1161                 case (0x4000|P_BUT):
1162                         wugt_evt(wev);
1163                         return NGWORDWINDOW_GETTEXTBOXACTION_FINISH;
1164                 default:
1165                         return NGWORDWINDOW_GETTEXTBOXACTION_FINISH;
1166                 }
1167         }
1168
1169         return NGWORDWINDOW_GETTEXTBOXACTION_FINISH;
1170 }
1171
1172 EXPORT W ngwordwindow_endtextboxaction(ngwordwindow_t *window)
1173 {
1174         return 0;
1175 }
1176
1177 LOCAL VOID ngwordwindow_butdnwork(ngwordwindow_t *window, WEVENT *wev, dathmievent_t *evt)
1178 {
1179         PAID id;
1180         W ret, len, val, err;
1181         Bool found;
1182         TC *str;
1183
1184         ret = cfnd_par(window->wid, wev->s.pos, &id);
1185         if (ret <= 0) {
1186                 return;
1187         }
1188         if (id == window->ss_list_id) {
1189                 cact_par(window->ss_list_id, wev);
1190         }
1191         if (id == window->ms_delete_id) {
1192                 ret = cact_par(window->ms_delete_id, wev);
1193                 if ((ret & 0x5000) != 0x5000) {
1194                         return;
1195                 }
1196                 err = cget_val(window->ss_list_id, 1, (W*)&val);
1197                 if (err < 0) {
1198                         DP_ER("cget_val ss_list_id error:", err);
1199                         return;
1200                 }
1201                 if (val < 0) {
1202                         return;
1203                 }
1204                 found = ngwordwindow_searchwordbyindex(window, val - 1, &str, &len);
1205                 if (found == False) {
1206                         DP(("not found in ngwordwindow parts\n"));
1207                         return;
1208                 }
1209                 memcpy(window->strbuf, str, len * sizeof(TC));
1210                 evt->type = DATHMIEVENT_TYPE_NGWORD_REMOVE;
1211                 evt->data.ngword_append.str = window->strbuf;
1212                 evt->data.ngword_append.len = len;
1213                 return;
1214         }
1215         if (id == window->tb_input_id) {
1216                 memcpy(&window->savedwev, wev, sizeof(WEVENT));
1217                 evt->type = DATHMIEVENT_TYPE_NGWORD_TEXTBOX;
1218                 return;
1219         }
1220         if (id == window->ms_append_id) {
1221                 ret = cact_par(window->ms_append_id, wev);
1222                 if ((ret & 0x5000) != 0x5000) {
1223                         return;
1224                 }
1225                 len = cget_val(window->tb_input_id, 128, (W*)window->strbuf);
1226                 if (len <= 0) {
1227                         return;
1228                 }
1229                 evt->type = DATHMIEVENT_TYPE_NGWORD_APPEND;
1230                 evt->data.ngword_append.str = window->strbuf;
1231                 evt->data.ngword_append.len = len;
1232                 len = cset_val(window->tb_input_id, 0, NULL);
1233                 if (len < 0) {
1234                         DP_ER("cset_val tb_input_id error", len);
1235                 }
1236                 return;
1237         }
1238 }
1239
1240 LOCAL VOID dathmi_weventbutdn(dathmi_t *hmi, WEVENT *wev, dathmievent_t *evt)
1241 {
1242         W i;
1243         WID main_wid, cfrm_wid, ngword_wid;
1244
1245         main_wid = dathmi_getmainWID(hmi);
1246         cfrm_wid = dathmi_getcfrmWID(hmi);
1247         ngword_wid = dathmi_getngwordWID(hmi);
1248
1249         switch  (wev->s.cmd) {
1250         case    W_PICT:
1251                 switch (wchk_dck(wev->s.time)) {
1252                 case    W_DCLICK:
1253                         if (wev->s.wid == main_wid) {
1254                                 evt->type = DATHMIEVENT_TYPE_THREAD_CLOSE;
1255                                 evt->data.main_close.save = True; /* TODO: tmp value. */
1256                         } else if (wev->s.wid == cfrm_wid) {
1257                                 cfrmwindow_close2(hmi->cfrmwindow);
1258                                 evt->type = DATHMIEVENT_TYPE_CONFIRM_CLOSE;
1259                                 evt->data.confirm_close.send = False;
1260                         } else if (wev->s.wid == ngword_wid) {
1261                                 ngwordwindow_close(hmi->ngwordwindow);
1262                                 evt->type = DATHMIEVENT_TYPE_NGWORD_CLOSE;
1263                         }
1264                         return;
1265                 case    W_PRESS:
1266                         break;
1267                 default:
1268                         return;
1269                 }
1270         case    W_FRAM:
1271         case    W_TITL:
1272                 if (wmov_drg(wev, NULL) > 0) {
1273                         if (wev->s.wid == main_wid) {
1274                                 evt->type = DATHMIEVENT_TYPE_THREAD_DRAW;
1275                         } else if (wev->s.wid == cfrm_wid) {
1276                                 cfrmwindow_redisp(hmi->cfrmwindow);
1277                         } else if (wev->s.wid == ngword_wid) {
1278                                 ngwordwindow_redisp(hmi->ngwordwindow);
1279                         }
1280                 }
1281                 return;
1282         case    W_LTHD:
1283         case    W_RTHD:
1284         case    W_LBHD:
1285         case    W_RBHD:
1286                 switch (wchk_dck(wev->s.time)) {
1287                 case    W_DCLICK:
1288                         i = wchg_wnd(wev->s.wid, NULL, W_MOVE);
1289                         break;
1290                 case    W_PRESS:
1291                         i = wrsz_drg(wev, NULL, NULL);
1292                         break;
1293                 default:
1294                         return;
1295                 }
1296
1297                 if (wev->s.wid == main_wid) {
1298                         evt->type = DATHMIEVENT_TYPE_THREAD_RESIZE;
1299                         datwindow_resize(hmi->mainwindow, &evt->data.main_resize.work_sz);
1300                         windowscroll_updatebar(&hmi->mainwindow->wscr);
1301                         if (i > 0) {
1302                                 //evt->type = DATHMIEVENT_TYPE_THREAD_DRAW;
1303                                 /* TODO: queueing */
1304                                 evt->data.main_resize.needdraw = True;
1305                         } else {
1306                                 evt->data.main_resize.needdraw = False;
1307                         }
1308                 } else if (wev->s.wid == cfrm_wid) {
1309                         cfrmwindow_resize(hmi->cfrmwindow);
1310                         windowscroll_updatebar(&hmi->cfrmwindow->wscr);
1311                         if (i > 0) {
1312                                 cfrmwindow_redisp(hmi->cfrmwindow);
1313                         }
1314                 }
1315                 /* ngword window need not do nothing. */
1316                 return;
1317         case    W_RBAR:
1318                 if (wev->s.wid == main_wid) {
1319                         windowscroll_weventrbar(&hmi->mainwindow->wscr, wev);
1320                 } else if (wev->s.wid == cfrm_wid) {
1321                         windowscroll_weventrbar(&hmi->cfrmwindow->wscr, wev);
1322                 }
1323                 /* ngword window need not do nothing. */
1324                 return;
1325         case    W_BBAR:
1326                 if (wev->s.wid == main_wid) {
1327                         windowscroll_weventbbar(&hmi->mainwindow->wscr, wev);
1328                 } else if (wev->s.wid == cfrm_wid) {
1329                         windowscroll_weventbbar(&hmi->cfrmwindow->wscr, wev);
1330                 }
1331                 /* ngword window need not do nothing. */
1332                 return;
1333         case    W_WORK:
1334                 if (wev->s.wid == main_wid) {
1335                         evt->type = DATHMIEVENT_TYPE_THREAD_BUTDN;
1336                         evt->data.main_butdn.type = wchk_dck(wev->s.time);
1337                         evt->data.main_butdn.pos = wev->s.pos;
1338                         memcpy(&hmi->mainwindow->savedwev, wev, sizeof(WEVENT));
1339                 } else if (wev->s.wid == cfrm_wid) {
1340                         cfrmwindow_butdnwork(hmi->cfrmwindow, wev, evt);
1341                 } else if (wev->s.wid == ngword_wid) {
1342                         ngwordwindow_butdnwork(hmi->ngwordwindow, wev, evt);
1343                 }
1344                 return;
1345         }
1346
1347         return;
1348 }
1349
1350 LOCAL VOID dathmi_weventswitch(dathmi_t *hmi, WEVENT *wev, dathmievent_t *evt)
1351 {
1352         evt->type = DATHMIEVENT_TYPE_THREAD_SWITCH;
1353         evt->data.main_switch.needdraw = False;
1354         //dathmi_weventbutdn(hmi, wev, evt);
1355 }
1356
1357 LOCAL VOID dathmi_weventreswitch(dathmi_t *hmi, WEVENT *wev, dathmievent_t *evt)
1358 {
1359         WID main_wid, cfrm_wid, ngword_wid;
1360
1361         main_wid = dathmi_getmainWID(hmi);
1362         cfrm_wid = dathmi_getcfrmWID(hmi);
1363         ngword_wid = dathmi_getngwordWID(hmi);
1364
1365         if (wev->s.wid == main_wid) {
1366                 evt->type = DATHMIEVENT_TYPE_THREAD_SWITCH;
1367                 evt->data.main_switch.needdraw = True;
1368         } else if (wev->s.wid == cfrm_wid) {
1369                 cfrmwindow_redisp(hmi->cfrmwindow);
1370         } else if (wev->s.wid == ngword_wid) {
1371                 ngwordwindow_redisp(hmi->ngwordwindow);
1372         }
1373         //dathmi_weventbutdn(hmi, wev, evt); TODO: event queueing
1374 }
1375
1376 LOCAL VOID dathmi_receivemessage(dathmi_t *hmi, dathmievent_t *evt)
1377 {
1378         MESSAGE msg;
1379         W err;
1380
1381     err = rcv_msg(MM_ALL, &msg, sizeof(MESSAGE), WAIT|NOCLR);
1382         if (err >= 0) {
1383                 if (msg.msg_type == MS_TMOUT) { /* should be use other type? */
1384                         evt->type = DATHMIEVENT_TYPE_COMMON_TIMEOUT;
1385                         evt->data.common_timeout.code = msg.msg_body.TMOUT.code;
1386                 }
1387         }
1388         clr_msg(MM_ALL, MM_ALL);
1389 }
1390
1391 EXPORT W dathmi_getevent(dathmi_t *hmi, dathmievent_t **evt)
1392 {
1393         WEVENT  wev0;
1394         WID main_wid, cfrm_wid, ngword_wid;
1395         Bool open;
1396
1397         main_wid = dathmi_getmainWID(hmi);
1398         cfrm_wid = dathmi_getcfrmWID(hmi);
1399         ngword_wid = dathmi_getngwordWID(hmi);
1400
1401         hmi->evt.type = DATHMIEVENT_TYPE_NONE;
1402
1403         wget_evt(&wev0, WAIT);
1404         switch (wev0.s.type) {
1405         case    EV_NULL:
1406                 cidl_par(wev0.s.wid, &wev0.s.pos);
1407                 if ((wev0.s.wid != main_wid)&&(wev0.s.wid != cfrm_wid)&&(wev0.s.wid != ngword_wid)) {
1408                         hmi->evt.type = DATHMIEVENT_TYPE_COMMON_MOUSEMOVE;
1409                         hmi->evt.data.common_mousemove.pos = wev0.s.pos;
1410                         break;          /*¥¦¥£¥ó¥É¥¦³°*/
1411                 }
1412                 if (wev0.s.cmd != W_WORK)
1413                         break;          /*ºî¶ÈÎΰ賰*/
1414                 if (wev0.s.stat & ES_CMD)
1415                         break;  /*Ì¿Îᥭ¡¼¤¬²¡¤µ¤ì¤Æ¤¤¤ë*/
1416                 if (wev0.s.wid == main_wid) {
1417                         hmi->evt.type = DATHMIEVENT_TYPE_THREAD_MOUSEMOVE;
1418                         hmi->evt.data.main_mousemove.pos = wev0.s.pos;
1419                         hmi->evt.data.main_mousemove.stat = wev0.s.stat;
1420                 }
1421                 break;
1422         case    EV_REQUEST:
1423                 dathmi_weventrequest(hmi, &wev0, &hmi->evt);
1424                 break;
1425         case    EV_RSWITCH:
1426                 dathmi_weventreswitch(hmi, &wev0, &hmi->evt);
1427                 break;
1428         case    EV_SWITCH:
1429                 dathmi_weventswitch(hmi, &wev0, &hmi->evt);
1430                 break;
1431         case    EV_BUTDWN:
1432                 dathmi_weventbutdn(hmi, &wev0, &hmi->evt);
1433                 break;
1434         case    EV_KEYDWN:
1435         case    EV_AUTKEY:
1436                 open = ngwordwindow_isopen(hmi->ngwordwindow);
1437                 if (open == True) {
1438                         memcpy(&hmi->ngwordwindow->savedwev, &wev0, sizeof(WEVENT));
1439                         hmi->evt.type = DATHMIEVENT_TYPE_NGWORD_TEXTBOX;
1440                         break;
1441                 }
1442                 hmi->evt.type = DATHMIEVENT_TYPE_COMMON_KEYDOWN;
1443                 hmi->evt.data.common_keydown.keycode = wev0.e.data.key.code;
1444                 hmi->evt.data.common_keydown.keytop = wev0.e.data.key.keytop;
1445                 hmi->evt.data.common_keydown.stat = wev0.e.stat;
1446                 break;
1447         case    EV_INACT:
1448                 pdsp_msg(NULL);
1449                 break;
1450         case    EV_DEVICE:
1451                 oprc_dev(&wev0.e, NULL, 0);
1452                 break;
1453         case    EV_MSG:
1454                 dathmi_receivemessage(hmi, &hmi->evt);
1455                 break;
1456         case    EV_MENU:
1457                 hmi->evt.type = DATHMIEVENT_TYPE_COMMON_MENU;
1458                 hmi->evt.data.common_menu.pos = wev0.s.pos;
1459                 break;
1460         }
1461
1462         *evt = &hmi->evt;
1463
1464         return 0;
1465 }
1466
1467 LOCAL VOID datwindow_scroll(VP arg, W dh, W dv)
1468 {
1469         datwindow_t *window = (datwindow_t*)arg;
1470         (*window->scroll_callback)(window->arg, dh, dv);
1471 }
1472
1473 LOCAL datwindow_t* datwindow_new(RECT *r, TC *title, PAT *bgpat, datwindow_scrollcalback scrollcallback, VP arg)
1474 {
1475         datwindow_t* window;
1476         W err;
1477
1478         window = malloc(sizeof(datwindow_t));
1479         if (window == NULL) {
1480                 return NULL;
1481         }
1482
1483         window->wid = wopn_wnd(WA_SIZE|WA_HHDL|WA_VHDL|WA_BBAR|WA_RBAR, 0, r, NULL, 1, title, bgpat, NULL);
1484         if (window->wid < 0) {
1485                 free(window);
1486                 return NULL;
1487         }
1488         err = windowscroll_initialize(&window->wscr, window->wid, datwindow_scroll, (VP)window);
1489         if (err < 0) {
1490                 wcls_wnd(window->wid, CLR);
1491                 free(window);
1492                 return NULL;
1493         }
1494         window->gid = wget_gid(window->wid);
1495         window->scroll_callback = scrollcallback;
1496         window->arg = arg;
1497
1498         return window;
1499 }
1500
1501 LOCAL VOID datwindow_delete(datwindow_t *window)
1502 {
1503         wcls_wnd(window->wid, CLR);
1504         windowscroll_finalize(&window->wscr);
1505         free(window);
1506 }
1507
1508 EXPORT datwindow_t* dathmi_newmainwindow(dathmi_t *hmi, RECT *r, TC *title, PAT *bgpat, datwindow_scrollcalback scrollcallback, VP arg)
1509 {
1510         hmi->mainwindow = datwindow_new(r, title, bgpat, scrollcallback, arg);
1511         return hmi->mainwindow;
1512 }
1513
1514 EXPORT VOID dathmi_deletemainwindow(dathmi_t *hmi, datwindow_t *window)
1515 {
1516         datwindow_delete(window);
1517         hmi->mainwindow = NULL;
1518 }
1519
1520 LOCAL VOID cfrmwindow_scroll(VP arg, W dh, W dv)
1521 {
1522         cfrmwindow_t *window = (cfrmwindow_t*)arg;
1523         wscr_wnd(window->wid, NULL, -dh, -dv, W_SCRL|W_RDSET);
1524         cfrmwindow_redisp(window);
1525 }
1526
1527 EXPORT cfrmwindow_t* cfrmwindow_new(RECT *r, WID parent, W dnum_title, W dnum_post, W dnum_cancel)
1528 {
1529         cfrmwindow_t *window;
1530         W err;
1531         SWSEL *sw;
1532
1533         window = (cfrmwindow_t*)malloc(sizeof(cfrmwindow_t));
1534         if (window == NULL) {
1535                 return NULL;
1536         }
1537         window->wid = -1;
1538         window->gid = -1;
1539         window->parent = parent;
1540         window->ms_post_id = -1;
1541         window->ms_cancel_id = -1;
1542         window->r = *r;
1543         window->post = NULL;
1544         err = windowscroll_initialize(&window->wscr, window->wid, cfrmwindow_scroll, (VP)window);
1545         if (err < 0) {
1546                 free(window);
1547                 return NULL;
1548         }
1549
1550         err = dget_dtp(TEXT_DATA, dnum_title, (void**)&window->windowtitle);
1551         if (err < 0) {
1552                 DP_ER("dget_dtp: message retrieving error", err);
1553                 windowscroll_finalize(&window->wscr);
1554                 free(window);
1555                 return NULL;
1556         }
1557
1558         err = dget_dtp(PARTS_DATA, dnum_post, (void**)&sw);
1559         if (err < 0) {
1560                 DP_ER("dget_dtp: message retrieving error", err);
1561                 windowscroll_finalize(&window->wscr);
1562                 free(window);
1563                 return NULL;
1564         }
1565         window->dnum_post = dnum_post;
1566         window->sz_ms_post.h = sw->r.c.right - sw->r.c.left;
1567         window->sz_ms_post.v = sw->r.c.bottom - sw->r.c.top;
1568
1569         err = dget_dtp(PARTS_DATA, dnum_cancel, (void**)&sw);
1570         if (err < 0) {
1571                 DP_ER("dget_dtp: message retrieving error", err);
1572                 windowscroll_finalize(&window->wscr);
1573                 free(window);
1574                 return NULL;
1575         }
1576         window->dnum_cancel = dnum_cancel;
1577         window->sz_ms_cancel.h = sw->r.c.right - sw->r.c.left;
1578         window->sz_ms_cancel.v = sw->r.c.bottom - sw->r.c.top;
1579
1580         return window;
1581 }
1582
1583 EXPORT cfrmwindow_t *dathmi_newconfirmwindow(dathmi_t *hmi, RECT *r, W dnum_title, W dnum_post, W dnum_cancel)
1584 {
1585         W main_wid;
1586         main_wid = dathmi_getmainWID(hmi);
1587         if (main_wid < 0) {
1588                 DP_ER("main window not exist", 0);
1589                 return NULL;
1590         }
1591         hmi->cfrmwindow = cfrmwindow_new(r, main_wid, dnum_title, dnum_post, dnum_cancel);
1592         return hmi->cfrmwindow;
1593 }
1594
1595 LOCAL VOID cfrmwindow_delete(cfrmwindow_t *window)
1596 {
1597         if (window->wid > 0) {
1598                 wcls_wnd(window->wid, CLR);
1599         }
1600         windowscroll_finalize(&window->wscr);
1601         free(window);
1602 }
1603
1604 EXPORT VOID dathmi_deleteconfirmwindow(dathmi_t *hmi, cfrmwindow_t *window)
1605 {
1606         cfrmwindow_delete(window);
1607         hmi->cfrmwindow = NULL;
1608 }
1609
1610 LOCAL ngwordwindow_t* ngwordwindow_new(PNT *p, WID parent, W dnum_list, W dnum_delete, W dnum_input, W dnum_append)
1611 {
1612         ngwordwindow_t *window;
1613         W err;
1614
1615         window = (ngwordwindow_t*)malloc(sizeof(ngwordwindow_t));
1616         if (window == NULL) {
1617                 DP_ER("malloc error:", 0);
1618                 return NULL;
1619         }
1620         window->wid = -1;
1621         window->gid = -1;
1622         window->parent = parent;
1623         window->r.p.lefttop = *p;
1624         window->r.p.rightbot.x = p->x + 300 + 7;
1625         window->r.p.rightbot.y = p->y + 200 + 30;
1626         err = wget_inf(WI_PANELBACK, &window->bgpat, sizeof(PAT));
1627         if (err != sizeof(PAT)) {
1628                 DP_ER("wget_inf error:", err);
1629                 window->bgpat.spat.kind = 0;
1630                 window->bgpat.spat.hsize = 16;
1631                 window->bgpat.spat.vsize = 16;
1632                 window->bgpat.spat.fgcol = 0x10ffffff;
1633                 window->bgpat.spat.bgcol = 0;
1634                 window->bgpat.spat.mask = FILL100;
1635         }
1636         window->dnum_list = dnum_list;
1637         window->dnum_delete = dnum_delete;
1638         window->dnum_input = dnum_input;
1639         window->dnum_append = dnum_append;
1640         window->ss_list_id = -1;
1641         window->ms_delete_id = -1;
1642         window->tb_input_id = -1;
1643         window->ms_append_id = -1;
1644         wordlist_initialize(&window->wordlist);
1645         window->selector = NULL;
1646
1647         return window;
1648 }
1649
1650 LOCAL VOID ngwordwindow_delete(ngwordwindow_t *window)
1651 {
1652         wordlist_finalize(&window->wordlist);
1653         if (window->wid > 0) {
1654                 cdel_pwd(window->wid, NOCLR);
1655                 wcls_wnd(window->wid, CLR);
1656         }
1657         free(window);
1658 }
1659
1660 EXPORT ngwordwindow_t *dathmi_newngwordwindow(dathmi_t *hmi, PNT *p, W dnum_list, W dnum_delete, W dnum_input, W dnum_append)
1661 {
1662         W main_wid;
1663         main_wid = dathmi_getmainWID(hmi);
1664         if (main_wid < 0) {
1665                 DP_ER("main window not exist", 0);
1666                 return NULL;
1667         }
1668         hmi->ngwordwindow = ngwordwindow_new(p, main_wid, dnum_list, dnum_delete, dnum_input, dnum_append);
1669         return hmi->ngwordwindow;
1670 }
1671
1672 EXPORT VOID dathmi_deletengwordwindow(dathmi_t *hmi, ngwordwindow_t *window)
1673 {
1674         ngwordwindow_delete(window);
1675         hmi->ngwordwindow = NULL;
1676 }
1677
1678 EXPORT dathmi_t* dathmi_new()
1679 {
1680         dathmi_t *hmi;
1681
1682         hmi = (dathmi_t *)malloc(sizeof(dathmi_t));
1683         if (hmi == NULL) {
1684                 return NULL;
1685         }
1686         hmi->mainwindow = NULL;
1687         hmi->cfrmwindow = NULL;
1688         hmi->ngwordwindow = NULL;
1689
1690         return hmi;
1691 }
1692
1693 EXPORT VOID dathmi_delete(dathmi_t *hmi)
1694 {
1695         if (hmi->ngwordwindow != NULL) {
1696                 ngwordwindow_delete(hmi->ngwordwindow);
1697         }
1698         if (hmi->cfrmwindow != NULL) {
1699                 cfrmwindow_delete(hmi->cfrmwindow);
1700         }
1701         if (hmi->mainwindow != NULL) {
1702                 datwindow_delete(hmi->mainwindow);
1703         }
1704         free(hmi);
1705 }