OSDN Git Service

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