Merge /u/jrubio/cdesktopenv/ branch implicit-int into master
[oweals/cde.git] / cde / programs / dtudcfonted / ufont.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* ufont.c 1.45 - Fujitsu source for CDEnext    96/12/03 18:34:11      */
24 /* $XConsortium: ufont.c /main/14 1996/12/17 19:30:16 cde-fuj $ */
25 /*
26  *  (c) Copyright 1995 FUJITSU LIMITED
27  *  This is source code modified by FUJITSU LIMITED under the Joint
28  *  Development Agreement for the CDEnext PST.
29  *  This is unpublished proprietary source code of FUJITSU LIMITED
30  */
31
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <math.h>
36
37 #include <X11/Intrinsic.h>
38
39 #include "xoakufont.h"
40 #include "util.h"
41
42 #define _CLIENT_CAT_NAME "dtudcfonted"
43 extern char *_DtGetMessage(char *filename, int set, int n, char *s);
44 #define GETMESSAGE(set, number, string) GetMessage(set, number, string)
45 static char *
46 GetMessage(int set, int number, char *string)
47 {
48     char *tmp, *ret;
49     tmp = _DtGetMessage(_CLIENT_CAT_NAME, set, number, string);
50     ret = malloc(strlen(tmp) + 1);
51     strcpy(ret, tmp);
52     return (ret);
53 }
54
55 /****************************************************************
56  *    Widgets                                                   *
57  ***************************************************************/
58 Widget  toplevel;
59 static Widget   dnPopW;
60 Widget  wgeScro, editPopW;
61
62 static int      select_x, select_y, select_w, select_h;
63 static int      r1_x, r1_y, r2_x, r2_y, cut_w, cut_h;
64
65 extern  Widget          xlfdDialog, cpyDialog;
66
67 extern FalFontID font_id;
68
69 Pixmap          arrow_pix=0;
70
71
72 static XtAppContext app; /* application context */
73 static int edpane_size=0;
74
75 static void OtherFontSelect(void);
76 void drawDelCode(int i);
77 void drawDelPtn(int i);
78 static void xeg_init(void);
79
80
81 static void dstrypaneEditPtn(void);
82 void chgEdCode(int code, char mode);
83 void chgEdList(int statloc, int slctloc, char mode);
84 static void chgEdPtn(int code);
85 static void DrawRectEdPn(int x1, int y1, int x2, int y2);
86 static void DrawBorderEdPn(int x1, int y1, int x2, int y2);
87 static void DrawPointEdPn(int x, int y, int mode);
88 static void DrawDpPn(void);
89 static void DrawPointDpPn(int x, int y, int mode);
90 static void musPoint(int evtype, int px, int py);
91 static void musLine(int evtype, int px, int py);
92 static void musCircle(int evtype, int px, int py);
93 static void musRect(int proc, int evtype, int px, int py);
94 static void musRegionProc(int proc, int evtype, int px, int py);
95 static void musPasteProc(Widget w, XtPointer client_data, XEvent *event);
96 static void rubLine(int x1, int y1, int x2, int y2);
97 static void rubBand(int x1, int y1, int x2, int y2);
98 static void rubCircle(int ox, int oy, int rx, int ry);
99 static void resetEditMode(unsigned int flag);
100 static void copyPatterns(FalFontData *fdata,
101                          int s1_code,
102                          int s2_code,
103                          int d1_code,
104                          int proc);
105 extern String MngCodeTfValue(void);
106 extern String CpySrcCodeTfValue(void);
107 extern String CpyDestCodeTfValue(void);
108 char    *get_cmd_path(char *path, char *cmd);
109 extern  FalFontData     fullFontData;
110 extern  FalFontData     copyFontData;
111
112 extern void PopupSelectXLFD(Widget top);
113 extern void UpdateMessage(String str);
114 extern void DispMngErrorMessage(String msg);
115 extern void DispCpyErrorMessage(String msg);
116 static int setRealDelArea(int *s_ncode,
117                           int *e_ncode,
118                           int *sq_start,
119                           int *sq_end);
120
121 /****************************************************************
122  * parameters                                                   *
123  ***************************************************************/
124 static Arg      arg[30];
125 static int      n;
126
127 Resource resource;
128
129 /****************************************************************
130  * callback routines                                            *
131  ***************************************************************/
132
133 static void CancelCB(void);
134
135 static void
136 ExitCB(void)
137 {
138     exit(0);
139 }
140
141 int
142 efctPtnNum(void)
143 {
144     int no;
145     int sq;
146     int cnt;
147
148     for ( cnt = 0, sq = edlist.sqstart;
149              sq < (edlist.sqstart + edlist.nptn); sq++) {
150         no = ptnSqToNo(sq);
151         if (( no >= 0) && (codeCheck( noToCode( no)) == 0))
152             cnt++;
153     }
154     return( cnt);
155 }
156
157 void
158 Error_message(Widget widget, char *message)
159 {
160     static NoticeButton is_lock[] = {
161     NBTNARGS( ExitCB, NULL, 'E', True, False ),
162     NBTNARGS( CancelCB, NULL, 'C', True, True )
163     };
164     static NButton LockBTN = NBUTTONS( is_lock );
165
166     SetItemLabel(&LockBTN, 0, resource.l_exit);
167     SetItemLabel(&LockBTN, 1, resource.l_cancel);
168     PopupNotice( (widget), message,
169                 D_ERROR,
170                 &LockBTN,
171                 True,
172                 resource.l_question_title);
173 }
174
175 void
176 Error_message2(Widget widget, char *message)
177 {
178     static NoticeButton is_lock[] = {
179     NBTNARGS( CancelCB, NULL, 'C', True, True )
180     };
181     static NButton LockBTN = NBUTTONS( is_lock );
182
183     if (widget == NULL)
184         widget = toplevel;
185
186     SetItemLabel(&LockBTN, 0, resource.l_ok);
187     PopupNotice( (widget), message,
188                 D_ERROR,
189                 &LockBTN,
190                 True,
191                 resource.l_question_title);
192 }
193
194 /*
195  * contents : read a character pattern from SNF file
196  */
197 /*ARGSUSED*/
198 static void
199 CBmOblB_edit( Widget widget, caddr_t clientData, caddr_t callData )
200 {
201     int         ptn_n;
202     int         ptn_w;
203     int         ptn_h;
204     int         code;
205     int         i;
206     int         ret;
207     char        err[128];
208     extern int begin_code;
209
210     extern int ptnGetInfo();
211     extern void PopupEditPtn();
212
213     /* open font file and get informations of character to be edited  */
214
215     ret = readSNF( &(edg.fdata), &(edg.width), &(edg.height), err);
216
217     if( ret == -1 ) {
218         Error_message(widget, err);
219         return;
220     }
221     dn.ptn_w = (Dimension) edg.width;
222     dn.ptn_h = (Dimension) edg.height;
223
224
225     if( xlfdDialog != NULL )
226         PopdownDialog(xlfdDialog);
227
228     ptnGetInfo( &ptn_n, &ptn_w, &ptn_h );
229     for( i=0 ; i<ptn_n ; i++ ) {
230         code = noToCode( ptnSqToNo(i) );
231         if( begin_code > code){
232             edlist.sqstart = i+1;
233         } else {
234             edlist.nptn++;
235         }
236     }
237     if( efctPtnNum() > 0) {
238         for ( i=edlist.sqstart; i<(edlist.sqstart+edlist.nptn); i++){
239             if ( codeCheck( noToCode( ptnSqToNo(i))) == 0)
240                 break;
241         }
242         edg.ncode = ptnSqToNo( i );
243         edg.code = noToCode( edg.ncode );
244         ptnGet( edg.code, edg.ptn );
245     }
246     PopupEditPtn(toplevel);
247 }
248
249
250
251 void CBeOblB_aAdd(void);
252
253 static Boolean do_read = False;
254 static Boolean do_end = False;
255
256 static void CancelCB(void) { }
257
258 static void ContReadCB(Widget w)
259 {
260     FalCloseFont(font_id);
261     editPtnW = NULL;
262     OtherFontSelect();
263     PopupSelectXLFD(toplevel);
264 }
265
266 static void SaveReadCB(void)
267 {
268     CBeOblB_aAdd();
269     do_read = True;
270     PopupSelectXLFD(toplevel);
271 }
272
273
274 static void ContEndCB(void)
275 {
276     FalCloseFont(font_id);
277     exit(0);
278 }
279
280 static void SaveEndCB(void)
281 {
282     CBeOblB_aAdd();
283     do_end = True;
284 }
285
286
287 /*
288  * contents : quit editting
289  */
290
291
292 /*ARGSUSED*/
293 static int
294 QuitEditPtn( Widget widget, caddr_t clientData, caddr_t callData )
295 {
296     resetEditMode( RES_MSG | RES_PROC | RES_SLCT | RES_RSV );
297
298     if( edg.code != 0 ){
299         ptnAdd( edg.code, edg.ptn );
300     }
301     if( edg.flag == ON ){
302         return(0);
303     }
304     return(1);
305 }
306
307
308
309 void
310 OpenCB(Widget w, XtPointer client_data, XtPointer call_data)
311 {
312     static NoticeButton is_save_read_btn1[] = {
313     NBTNARGS( SaveReadCB, NULL, 'S', True, False ),
314     NBTNARGS( ContReadCB, NULL, 'O', True, False ),
315     NBTNARGS( CancelCB, NULL, 'C', True, True ),
316     };
317     static NoticeButton is_save_read_btn2[] = {
318     NBTNARGS( ContReadCB, NULL, 'O', True, False ),
319     NBTNARGS( CancelCB, NULL, 'C', True, True ),
320     };
321     static NButton SaveReadBTN1 = NBUTTONS( is_save_read_btn1 );
322     static NButton SaveReadBTN2 = NBUTTONS( is_save_read_btn2 );
323
324         if (QuitEditPtn((Widget)NULL, (caddr_t)NULL, (caddr_t)NULL)){
325             FalCloseFont(font_id);
326             editPtnW = NULL;
327             OtherFontSelect();
328             PopupSelectXLFD(toplevel);
329         }
330         else{
331             if (! fullFontData.prm) {
332                 SetItemLabel(&SaveReadBTN1, 0, resource.l_do_save_exit);
333                 SetItemLabel(&SaveReadBTN1, 1, resource.l_dont_save_exit);
334                 SetItemLabel(&SaveReadBTN1, 2, resource.l_cancel);
335                 PopupNotice( (w), resource.mn_saved_open ,
336                     D_QUESTION,
337                     &SaveReadBTN1,
338                     True,
339                     resource.l_question_title);
340             } else {
341                 SetItemLabel(&SaveReadBTN2, 0, resource.l_dont_save_exit);
342                 SetItemLabel(&SaveReadBTN2, 1, resource.l_cancel);
343                 PopupNotice( (w), resource.mn_saved_open ,
344                     D_QUESTION,
345                     &SaveReadBTN2,
346                     True,
347                     resource.l_question_title);
348             }
349         }
350 }
351
352
353 void
354 ReadCB(Widget w, XtPointer client_data, XtPointer call_data)
355 {
356     if (fullFontData.xlfdname == NULL) {
357         return;
358     }
359     if (fullFontData.xlfdname == (char *) -1) {
360         Error_message(w, resource.mn_prop_font);
361         return;
362     }
363     CBmOblB_edit( w, client_data, call_data );
364 }
365
366 /****************************************************************
367  * callback routines and event handler                          *
368  ***************************************************************/
369
370 /*
371  * contents : write character patterns to SNF file
372 */
373
374 static Boolean
375 WPwriteSNF( int restart )
376 {
377     int         rc, err;
378     char        str[MG_MAXSIZE];
379
380     switch( rc = writeSNF( restart, &err ) ) {
381     case -1:
382         if (dnPopW)
383             XtSetSensitive( dnPopW,  TRUE );
384         switch( err ) {
385         case 001:
386             sprintf(str, "%s(permission denied)", resource.me_write_snf);
387             break;
388         case 002:
389             sprintf(str, "%s(disk full)", resource.me_write_snf);
390             break;
391         case 101:
392             sprintf(str, "%s(pipe error)", resource.me_write_snf);
393             break;
394         case 102:
395             sprintf(str, "%s(fork error)", resource.me_write_snf);
396             break;
397         case 103:
398             sprintf(str, "%s(execv error)", resource.me_write_snf);
399             break;
400         case 104:
401             sprintf(str, "%s(data error)", resource.me_write_snf);
402             break;
403         default:
404             sprintf(str, "%s", resource.me_write_snf);
405         }
406         UpdateMessage( str );
407         return( TRUE );
408     case 0:
409         edg.flag = 0;
410         UpdateMessage( resource.mg_register );
411         sleep(1);
412         UpdateMessage("");
413
414         if (do_read){
415             do_read = False;
416             ContReadCB((Widget)NULL);
417         }
418         if (do_end){
419             do_read = False;
420             ContEndCB();
421         }
422         return(TRUE);
423     default:
424         if( rc == 1101 )
425             sprintf( str, "%s", resource.me_wait );
426         else
427             sprintf( str, "%s(%3d%%)", resource.mg_write_snf , rc-1000 );
428
429         UpdateMessage( str );
430         XtAppAddWorkProc( app, (XtWorkProc)WPwriteSNF, (XtPointer)ON );
431         if( rc == 1101 ){
432             XSync( xl.display,0 );
433         }
434         return( TRUE );
435     }
436 }
437
438
439
440 /*
441  * contents : write character patterns to SNF file
442  */
443
444 void
445 CBeOblB_aAdd(void)
446 {
447     char        str[MG_MAXSIZE];
448
449     resetEditMode( RES_MSG | RES_PROC | RES_SLCT | RES_RSV );
450     UpdateMessage( resource.mg_write_snf );
451
452     if( edg.code != 0 )
453         ptnAdd( edg.code, edg.ptn );
454
455     if( edg.flag == ON ) {
456         sprintf( str, "%s", resource.mg_write_snf );
457         if (dnPopW)
458             XtSetSensitive( dnPopW,  FALSE );
459
460         XtAppAddWorkProc( app, (XtWorkProc)WPwriteSNF, (XtPointer)OFF );
461         return;
462     }
463     else{
464         UpdateMessage( "" );
465     }
466 }
467
468
469
470 /*
471  * contents : destroy the editor window
472  */
473
474 static void
475 OtherFontSelect(void)
476 {
477     dstrypaneEditPtn();
478     xeg_init();
479 }
480
481
482
483 /*
484  * contents : close dtudcfonted
485  */
486
487 /*ARGSUSED*/
488 void
489 CBeOblB_aEnd( Widget widget, caddr_t clientData, caddr_t callData )
490 {
491     static NoticeButton is_save_exit_btn[] = {
492     NBTNARGS( SaveEndCB, NULL, 'S', True, False ),
493     NBTNARGS( ContEndCB, NULL, 'E', True, False ),
494     NBTNARGS( CancelCB,  NULL, 'C', True, True ),
495     };
496     static NButton SaveEndBTN = NBUTTONS( is_save_exit_btn );
497
498     resetEditMode( RES_MSG | RES_PROC | RES_SLCT | RES_RSV );
499
500     if( edg.code != 0 )
501         ptnAdd( edg.code, edg.ptn );
502     if( edg.flag == ON ) {
503
504         SetItemLabel(&SaveEndBTN, 0, resource.l_do_save);
505         SetItemLabel(&SaveEndBTN, 1, resource.l_dont_save);
506         SetItemLabel(&SaveEndBTN, 2, resource.l_cancel);
507         PopupNotice( widget, resource.mn_saved_exit, D_QUESTION,
508                             &SaveEndBTN, True, resource.l_question_title);
509         return;
510     } else {
511         FalCloseFont(font_id);
512     }
513
514     exit(0);
515 }
516
517
518
519 /*ARGSUSED*/
520 void
521 CBeOblB_rCmd( Widget widget, int proc, caddr_t callData )
522 {
523     extern void SelectUnset();
524     extern void UndoSet();
525     if (!select_x && !select_y && !select_w && !select_h)
526         return;
527     em.rsv_f = ON;
528     bitPtnCopy( em.rsv_ptn,  edg.ptn );
529     rubBand( r1_x,  r1_y,  r2_x,  r2_y );
530     switch( proc ) {
531     case PROC_CLS:
532         bitDrawCls (edg.ptn, select_x, select_y, select_w, select_h );
533         break;
534     case PROC_SET:
535         bitDrawSet (edg.ptn, select_x, select_y, select_w, select_h );
536         break;
537     case PROC_REV:
538         bitDrawRev (edg.ptn, select_x, select_y, select_w, select_h );
539         break;
540     case PROC_ROLL:
541         bitDrawRoll(edg.ptn, select_x, select_y, select_w, select_h);
542         break;
543     case PROC_SYMV:
544         bitDrawSymV(edg.ptn, select_x, select_y, select_w, select_h );
545         break;
546     case PROC_SYMH:
547         bitDrawSymH(edg.ptn, select_x, select_y, select_w, select_h );
548         break;
549     }
550     edg.flag = ON;
551     DrawRectEdPn( 0, 0,  edg.width - 1,  edg.height - 1 );
552     DrawDpPn();
553     select_x = select_y = select_w = select_h = 0;
554     SelectUnset();
555     UndoSet();
556 }
557
558 /*ARGSUSED*/
559 void
560 CBeOblB_rCmdp( Widget widget, int proc, caddr_t callData )
561 {
562     extern Widget wgeBulB_edit;
563     extern void CopySet();
564     extern void UndoSet();
565     extern void SelectUnset();
566
567     switch( proc ) {
568     case PROC_CPY:
569         if (!select_x && !select_y && !select_w && !select_h)
570             return;
571         rubBand( r1_x,  r1_y,  r2_x,  r2_y );
572         bitDrawCpy(edg.ptn, select_x, select_y, select_w, select_h, False);
573         cut_w = select_w;
574         cut_h = select_h;
575         select_x = select_y = select_w = select_h = 0;
576         CopySet();
577         SelectUnset();
578         break;
579     case PROC_CUT:
580         if (!select_x && !select_y && !select_w && !select_h)
581             return;
582         em.rsv_f = ON;
583         rubBand( r1_x,  r1_y,  r2_x,  r2_y );
584         bitPtnCopy( em.rsv_ptn,  edg.ptn );
585         bitDrawCpy(edg.ptn, select_x, select_y, select_w, select_h, True);
586         cut_w = select_w;
587         cut_h = select_h;
588         edg.flag = ON;
589         DrawRectEdPn( 0, 0,  edg.width - 1,  edg.height - 1 );
590         DrawDpPn();
591         select_x = select_y = select_w = select_h = 0;
592         CopySet();
593         UndoSet();
594         SelectUnset();
595         break;
596     case PROC_PASTE:
597         XtAddEventHandler(wgeBulB_edit,
598                             ButtonReleaseMask|PointerMotionMask,
599                                     False, musPasteProc, NULL );
600     }
601 }
602
603
604
605
606 /*
607  * contents : cancel all editting
608  */
609
610 /*ARGSUSED*/
611 void
612 CBeOblB_rCan( Widget widget, caddr_t clientData, caddr_t callData )
613 {
614     extern void UndoUnset();
615
616     resetEditMode( RES_MSG | RES_PROC | RES_SLCT );
617
618     if( em.rsv_f == ON ) {
619         bitPtnCopy( edg.ptn, em.rsv_ptn );
620         em.rsv_f = OFF;
621
622         DrawRectEdPn( 0, 0, edg.width - 1, edg.height - 1 );
623         DrawDpPn();
624         UndoUnset();
625     }
626 }
627
628
629
630
631 /*
632  *
633  *   contents : get a sequential number of the editor
634  */
635 int
636 RelToAbsSq( int from, int cnt)
637 {
638     int i;
639     int no;
640
641     if ( cnt >= 0) {
642         for ( i = -1; from < (edlist.sqstart + edlist.nptn) ; from++) {
643             no = ptnSqToNo(from);
644             if (( no >= 0) && ( noToCode( no) >= 0) ) {
645                 i++;
646                 if ( i >= cnt)
647                     return( from);
648             }
649         }
650     } else {
651         cnt *= -1;
652         for ( i = -1; from >= edlist.sqstart; from--) {
653             no = ptnSqToNo(from);
654             if (( no >= 0) && ( noToCode( no) >= 0) ) {
655                 i++;
656                 if ( i >= cnt)
657                     return(from);
658             }
659         }
660     }
661     return( -1);
662 }
663
664 /*
665  *   contents : get a relative number of the system area
666  */
667 int
668 AbsSqToRel( int from, int to)
669 {
670     int sq;
671     int cnt;
672     int sign = 1;
673     int no;
674
675     if ( from > to) {
676         sq = from;
677         from = to;
678         to = sq;
679         sign = -1;
680     }
681
682     for ( cnt = -1, sq = from; sq <= to; sq++) {
683         no = ptnSqToNo(sq);
684         if (( no >= 0) && (codeCheck( noToCode( no)) == 0))
685             cnt++;
686     }
687
688     if ( cnt < 0)
689         cnt = 0;
690
691     cnt *= sign;
692     return( cnt);
693 }
694
695
696 /*
697  * contents : be the character list selected
698  */
699
700 /*ARGSUSED*/
701 void
702 EHeStaT_list( Widget widget, int select, XEvent *e )
703 {
704     int         sq, no;
705     int         code;
706
707     resetEditMode( RES_MSG|RES_PROC|RES_SLCT|RES_RSV );
708
709     if( (e->xbutton.button != 1) || (e->type != ButtonRelease) ||
710         (e->xbutton.x < 0) || ((int)edlist.elem_w < e->xbutton.x) ||
711         (e->xbutton.y < 0) || ((int)edlist.elem_h < e->xbutton.y)
712        )
713         return;
714
715     if( edlist.slctloc == select )
716         return;
717
718     sq = RelToAbsSq( edlist.sqstart + edlist.statloc, select);
719
720     if( (no = ptnSqToNo(sq)) == -1 )
721         return;
722
723     code = noToCode( no );
724     if( codeCheck( code ) == -1 )
725         return;
726
727     if( ptnSense( code) == 0 )
728         return ;
729
730     chgEdList( edlist.statloc, select, OFF );
731     if( ptnSense(edg.code) == 1 )
732         ptnAdd(edg.code, edg.ptn );
733     chgEdPtn( code );
734 }
735
736
737
738
739 /*
740  * contents : update the character list
741  */
742
743 /*ARGSUSED*/
744 void
745 CBeScro( Widget widget, caddr_t clientData, caddr_t callData )
746 {
747     int         newl;
748     int         new_statloc;
749     int         new_slct;
750
751     n = 0;
752     XtSetArg( arg[n], XmNvalue,   (XtArgVal)&newl );    n++;
753     XtGetValues( wgeScro , arg, n );
754
755     if (( new_statloc = RelToAbsSq( edlist.sqstart, newl)) < 0) {
756         new_statloc = 0;
757     } else {
758         new_statloc -= edlist.sqstart;
759     }
760     /*
761      */
762     new_slct = edlist.slctloc
763         - AbsSqToRel( edlist.sqstart + edlist.statloc,
764                       edlist.sqstart + new_statloc);
765     chgEdList( new_statloc, new_slct, OFF);
766 }
767
768
769
770
771 /*
772  * contents : select the edit items by mouse
773  */
774
775 /*ARGSUSED*/
776 void
777 EHeBulB_eMEv( Widget widget, caddr_t clientData, XEvent *e )
778 {
779     int         px, py;
780     int         downbutton;
781
782     if (edpane.pix_w * edpane.pix_h == 0 ) {
783         return;
784     }
785
786     if( e->type == ButtonPress ){
787         em.drag_f = ON;
788     }
789     if( (edg.code == 0) || (em.drag_f == OFF) )
790         return;
791     if( e->type == ButtonRelease ){
792         em.drag_f = OFF;
793     }
794
795     px = e->xbutton.x / edpane.pix_w;
796     py = e->xbutton.y / edpane.pix_h;
797
798     if (( e->type == ButtonPress) || (e->type == ButtonRelease)){
799         downbutton = e->xbutton.button;
800     }else if ( e->type == MotionNotify ){
801         if ( e->xmotion.state & Button1Mask ){
802             downbutton = 1; /* select button */
803         }else if ( e->xmotion.state & Button2Mask ){
804             downbutton = 2; /* adjust button */
805         } else {
806             downbutton = 0;
807         }
808     }
809
810     switch( downbutton ) {
811     case 1:
812         switch( em.proc ) {
813         case PROC_POINT:
814             resetEditMode( RES_MSG | RES_PROC | RES_SLCT | RES_RSV );
815             musPoint( e->type, px, py );
816             break;
817         case PROC_LINE:
818             resetEditMode( RES_MSG | RES_PROC | RES_SLCT | RES_RSV );
819             musLine( e->type, px, py );
820             break;
821         case PROC_CIRCLE:
822             resetEditMode( RES_MSG | RES_PROC | RES_SLCT | RES_RSV );
823             musCircle( e->type, px, py );
824             break;
825         case PROC_RECT:
826             resetEditMode( RES_MSG | RES_PROC | RES_SLCT | RES_RSV );
827             musRect( em.proc, e->type, px, py );
828             break;
829         case PROC_ERASE:
830             resetEditMode( RES_MSG | RES_PROC | RES_SLCT | RES_RSV );
831             musPoint( e->type, px, py );
832             break;
833         case PROC_SELECT:
834             musRegionProc( em.proc, e->type, px, py );
835             break;
836         default:
837             break;
838         }
839         break;
840
841     case 2:
842         if( (0 <= px) && (px < edg.width) && (0 <= py) && (py < edg.height) ) {
843             resetEditMode( RES_MSG | RES_PROC | RES_SLCT | RES_RSV );
844
845             switch( e->type ) {
846             case MotionNotify:
847                 if( (em.adj_px == px) && (em.adj_py == py) )
848                     return;
849                 break;
850             case ButtonPress:
851                 em.adj_px = px;
852                 em.adj_py = py;
853                 if( bitRead(edg.ptn, px, py) == 0 ) {
854                     bitSet( edg.ptn, px, py );
855                     DrawPointEdPn( px,py, 1 );
856                     DrawPointDpPn( px,py, 1 );
857                 }
858                 else {
859                     bitReset( edg.ptn, px, py );
860                     DrawPointEdPn( px,py, 0 );
861                     DrawPointDpPn( px,py, 0 );
862                 }
863                 edg.flag = ON;
864                 break;
865             default:
866                 return;
867             }
868         }
869     default:
870         break;
871     }
872 }
873
874
875
876
877 /*
878  * contents : restore the editting pane
879  */
880
881 /*ARGSUSED*/
882 void
883 EHeBulB_eExp( Widget widget, caddr_t clientData, XEvent *e )
884 {
885     int         x1, y1;
886     int         x2, y2;
887
888     if (edpane.pix_w * edpane.pix_h == 0 ) {
889         return;
890     }
891
892     x1 = e->xexpose.x / edpane.pix_w;
893     y1 = e->xexpose.y / edpane.pix_h;
894     x2 = (e->xexpose.x + e->xexpose.width - 1) / edpane.pix_w;
895     y2 = (e->xexpose.y + e->xexpose.height - 1) / edpane.pix_h;
896
897     DrawRectEdPn( x1, y1, x2, y2 );
898     DrawBorderEdPn( x1, y1, x2, y2 );
899 }
900
901
902
903
904 /*
905  * contents : specifies the drawing operation (Pont/Line/Rectangle/Circle)
906  */
907
908 /*ARGSUSED*/
909 void
910 CBeRecB_obj( Widget widget, int obj, XmToggleButtonCallbackStruct *call)
911 {
912     extern void SelectUnset();
913
914     if (call->set == False)
915         return;
916
917     resetEditMode( RES_MSG | RES_RSV | RES_SLCT );
918
919     if (obj == PROC_ERASE)
920         edpane.color = OFF;
921     else
922         edpane.color = ON;
923     edpane.obj = obj;
924     em.proc = obj;
925     if (obj != PROC_SELECT) {
926         if (select_x || select_y || select_w || select_h) {
927             rubBand( r1_x,  r1_y,  r2_x,  r2_y );
928             select_x = select_y = select_w = select_h = 0;
929             SelectUnset();
930         }
931     }
932 }
933
934
935
936
937 /*
938  * contents : restore the displaying pane
939  */
940
941 /*ARGSUSED*/
942 void
943 EHeBulB_dExp( Widget widget, caddr_t clientData )
944 {
945     if (xl.display == NULL ){
946         return;
947     }
948
949     DrawDpPn();
950 }
951
952 /*
953  * contents : set the range to be add or deleted
954  */
955
956 static int
957 codeAreaSet(int *s_code, int *e_code)
958 {
959     char        *str;
960     char        delm;
961
962     str = MngCodeTfValue();
963     delm = '\0';
964     *s_code = 0;
965     *e_code = 0;
966     if (!str || !*str){
967         return(-1);
968     }
969     sscanf( str, "%x %c %x", s_code, &delm, e_code );
970     if (str) free( str );
971     switch( delm ) {
972     case '\0':
973         *e_code = *s_code;
974         break;
975     case '-':
976         break;
977     default:
978         return(-1);
979     }
980     if( codeCheck(*s_code) || codeCheck(*e_code) ||
981         (*s_code > *e_code) ) {
982         return(-1);
983     }
984     return(0);
985 }
986
987
988 /****************************************************************
989  * callback routines (character management window)              *
990  ***************************************************************/
991
992 Boolean
993 BeforeMngCheck(int *s_code, int *e_code)
994 {
995     if(codeAreaSet(s_code, e_code) == -1) {
996         DispMngErrorMessage( resource.me_illegal_code );
997         return(False);
998     }
999     return(True);
1000 }
1001
1002 void
1003 DoAddProc(int s_code, int e_code)
1004 {
1005     int         code;
1006
1007     int         s_ncode;
1008     int         e_ncode;
1009     char        ptn[MAXPTNBYTE];
1010     char        mode;
1011     int         i;
1012
1013     resetEditMode( RES_MSG | RES_PROC | RES_SLCT | RES_RSV );
1014
1015     s_ncode = codeToNo( s_code );
1016     e_ncode = codeToNo( e_code );
1017     mode = OFF;
1018     bitPtnClear( ptn );
1019     for( i=s_ncode ; i <= e_ncode ; i++ ) {
1020         code = noToCode(i);
1021         if ( codeCheck( code))
1022             continue;
1023         if (ptnSense(code) == 0) {
1024             if(ptnAdd(code, ptn) != 1) {
1025                 UpdateMessage( resource.me_non_memory );
1026                 return;
1027             }
1028             edg.flag = ON;
1029             mode = ON;
1030             edlist.nptn++;
1031         }
1032     }
1033
1034     if( ptnSense( edg.code ) == 1 ) {
1035         ptnAdd( edg.code, edg.ptn );
1036     }
1037
1038     if(mode == ON) {
1039         chgEdCode( s_code, mode );
1040     }
1041
1042     resetEditMode( RES_MSG | RES_PROC | RES_SLCT | RES_RSV );
1043 }
1044
1045
1046
1047 void PopupDelNotice();
1048 Widget CreateDelNotice();
1049
1050
1051 void
1052 DoDelProc( int s_code, int e_code )
1053 {
1054     resetEditMode( RES_MSG | RES_PROC | RES_SLCT | RES_RSV );
1055
1056     if( ptnSense( edg.code) == 1 )
1057         ptnAdd( edg.code, edg.ptn );
1058
1059     dn.s_ncode = codeToNo( s_code );
1060     dn.e_ncode = codeToNo( e_code );
1061
1062     if (setRealDelArea(&dn.s_ncode, &dn.e_ncode, &dn.sq_start, &dn.sq_end) == -1) {
1063         DispMngErrorMessage( resource.me_nodelete_code );
1064         return;
1065     }
1066     dn.sq_top  = dn.sq_start;
1067     dn.disp_num = AbsSqToRel( dn.sq_start, dn.sq_end) + 1;
1068     dn.disp_num = (dn.disp_num <= D_MAX) ? dn.disp_num : D_MAX;
1069
1070     PopupDelNotice( mngPtnW );
1071
1072 }
1073
1074
1075
1076
1077 /*
1078  * contents : get the real range to be add or delete
1079  */
1080
1081
1082 static int
1083 setRealDelArea(int *s_ncode, int *e_ncode, int *sq_start, int *sq_end )
1084 {
1085     int         ncode;
1086     int         flg;
1087     int         sq;
1088     int         i;
1089
1090     /* first code */
1091     flg = 0;
1092     ncode = *e_ncode;
1093     for( i=*s_ncode ; i <= ncode ; i++ ) {
1094         if (((sq = ptnNoToSq(i)) != -1) && (codeCheck( noToCode(i)) == 0)) {
1095             flg = 1;
1096             break;
1097         }
1098     }
1099     if (flg == 1) {
1100         *s_ncode = ptnSqToNo( sq );
1101         *sq_start = sq;
1102     } else {
1103         return(-1);
1104     }
1105
1106     /* last code */
1107     flg = 0;
1108     ncode = *s_ncode;
1109     for( i=*e_ncode ; i >= ncode ; i-- ) {
1110         if ((( sq = ptnNoToSq(i)) != -1) && (codeCheck( noToCode(i) ) == 0)) {
1111             flg = 1;
1112             break;
1113         }
1114     }
1115     *e_ncode = ptnSqToNo( sq );
1116     *sq_end = sq;
1117     return(0);
1118 }
1119
1120
1121
1122
1123
1124
1125 /****************************************************************
1126  * callback routines (Copy)                                     *
1127  ****************************************************************/
1128
1129 static int
1130 CpySrcCodeCheck(void)
1131 {
1132     char        *str;
1133     char        delm;
1134
1135     str = CpySrcCodeTfValue();
1136     if (!str)
1137         return(-1);
1138     if (!*str) {
1139         free(str);
1140         return(-1);
1141     }
1142     delm = '\0';
1143     cpm.s1_code = 0;
1144     cpm.s2_code = 0;
1145     sscanf( str, "%x %c %x", &cpm.s1_code,&delm, &cpm.s2_code );
1146     free( str );
1147     switch( delm ) {
1148     case '\0':
1149         cpm.s2_code = cpm.s1_code;
1150         break;
1151     case '-':
1152         break;
1153     default:
1154         return(-1);
1155     }
1156     if (cpm.s1_code > cpm.s2_code)
1157         return(-1);
1158     return(0);
1159 }
1160
1161 static int
1162 CpyDestCodeCheck(void)
1163 {
1164     char        *str;
1165
1166     str = CpyDestCodeTfValue();
1167     if (!str)
1168         return(-1);
1169     if (!*str){
1170         free(str);
1171         return(-1);
1172     }
1173     cpm.d1_code = 0;
1174     sscanf( str, "%x", &cpm.d1_code );
1175     free( str );
1176
1177     if( codeCheck(cpm.d1_code)  ) {
1178         return(-1);
1179     }
1180     return(0);
1181 }
1182
1183 Boolean
1184 BeforeCpyCheck( int proc )
1185 {
1186     int         s_ncode, e_ncode;
1187     int         r1_code, r2_code;
1188     int         no;
1189     int         i;
1190     char        rstr[30];
1191     extern void PopupCpyNotice();
1192
1193     if (copyFontData.xlfdname == NULL) {
1194         DispCpyErrorMessage(resource.me_non_srcfile);
1195         return(False);
1196     }
1197
1198     if (CpySrcCodeCheck() == -1){
1199         DispCpyErrorMessage( resource.me_illegal_srccode );
1200         return(False);
1201     }
1202
1203     if (CpyDestCodeCheck() == -1){
1204         DispCpyErrorMessage( resource.me_illegal_destcode );
1205         return(False);
1206     }
1207
1208     s_ncode = codeToNo( cpm.d1_code );
1209     e_ncode = codeToNo( cpm.d1_code + cpm.s2_code - cpm.s1_code);
1210     r1_code = r2_code = 0;
1211     for( i=s_ncode ; i <= e_ncode ; i++ ) {
1212         no = ptnSqToNo(i);
1213         if (( no >= 0) && (codeCheck( noToCode( no)) == 0)) {
1214             if(r1_code == 0)
1215                 r1_code = noToCode(i);
1216             r2_code = noToCode(i);
1217         }
1218     }
1219
1220     cpm.proc = proc;
1221
1222     if( r1_code != 0 ) {
1223         if( r1_code == r2_code ) {
1224             sprintf( rstr, "%s %x¡¡", resource.l_code, r1_code );
1225         } else if ( codeCheck(r1_code) && codeCheck(r2_code)){
1226             sprintf( rstr, "        %x - %x", r1_code, r2_code );
1227         } else {
1228             sprintf( rstr, "%s %x - %x ", resource.l_code_range, r1_code, r2_code );
1229         }
1230         PopupCpyNotice(rstr);
1231
1232         return(False);
1233     }
1234     return(True);
1235 }
1236
1237 void
1238 DoCpyProc(void)
1239 {
1240     extern void PopdownCpyPtn();
1241
1242     PopdownCpyPtn();
1243
1244     resetEditMode( RES_MSG | RES_PROC | RES_SLCT | RES_RSV );
1245
1246     copyPatterns( cpm.fdata, cpm.s1_code, cpm.s2_code, cpm.d1_code, cpm.proc );
1247 }
1248
1249 /****************************************************************
1250  * main routine                                                 *
1251  ****************************************************************/
1252 #define R(name, class, member,def)      { \
1253         name, \
1254         class, \
1255         XtRString, \
1256         sizeof(char *), \
1257         XtOffsetOf(Resource, member), \
1258         XtRString, \
1259         (XtPointer)def }
1260
1261 #define RBoolean(name, class, member,def) \
1262         { name, class, XtRBoolean, sizeof(XtRBoolean), \
1263         XtOffsetOf(Resource, member), XtRString, (XtPointer)def }
1264
1265 #define RDimension(name, class, member,def) \
1266         { name, class, XtRDimension, sizeof(XtRDimension), \
1267         XtOffsetOf(Resource, member), XtRString, (XtPointer)def }
1268
1269 #define Rint(name, class, member,def) \
1270         { name, class, XtRInt, sizeof(XtRInt), \
1271         XtOffsetOf(Resource, member), XtRString, (XtPointer)def }
1272
1273 #define RPixel(name, class, member,def) \
1274         { name, class, XtRPixel, sizeof(XtRPixel), \
1275         XtOffsetOf(Resource, member), XtRString, (XtPointer)def }
1276
1277 static XtResource app_resources[] = {
1278 RBoolean("Codepoint", "codepoint", codepoint, "False"),
1279
1280 R( "lptog", "Lptog", l_ptog, DFLTPATH ),
1281 R( "lptogCmd", "LptogCmd", l_ptog_cmd, DFLTCMD ),
1282
1283 /* CreateCaptionFrame() */
1284 RBoolean( "captResize",  "CaptResize",  capt_resize,  "True"  ) ,
1285 Rint( "captLftoff",  "CaptLftoff",  capt_lftoff,  "2"  ) ,
1286 Rint( "captTopoff",  "CaptTopoff",  capt_topoff,  "2"  ) ,
1287 Rint( "captRghoff", "CaptRghoff", capt_rghoff, "2" ) ,
1288
1289 RPixel( "paneBackground", "paneBackground", pane_background, "white" ),
1290 RPixel( "paneForeground", "PaneForeground", pane_foreground, "black" ),
1291 RPixel( "background", "Background", background, "white" ),
1292 RPixel( "foreground", "Foreground", foreground, "black" ),
1293
1294 /* CreateMenuButtons() */
1295 RDimension( "menuMargin", "MenuMargin", menu_margin, "0" ) ,
1296
1297 /* CreateDialogAndButtons() */
1298 RBoolean( "diaTmAutomng",  "DiaTmAutomng",  dia_tm_automng,  "False" ) ,
1299 RDimension( "diaTmWidth",  "DiaTmWidth",  dia_tm_width,  "4" ) ,
1300 RDimension( "diaTmHeight", "DiaTmHeight", dia_tm_height, "4" ) ,
1301 RBoolean( "diaTmResize",   "DiaTmResize",   dia_tm_resize,   "True" ) ,
1302 RBoolean( "diaTmMinimize", "DiaTmMinimize", dia_tm_minimize, "True" ) ,
1303
1304 RDimension( "diaRwWidth",   "DiaRwWidth",   dia_rw_width,   "6" ) ,
1305 RDimension( "diaRwHeight",  "DiaRwHeight",  dia_rw_height,  "6" ) ,
1306 RDimension( "diaRwSpacing", "DiaRwSpacing", dia_rw_spacing, "4" ) ,
1307
1308 /* CreateDrawingArea() */
1309 RDimension( "drawBorder", "DrawBorder", draw_border, "1" ) ,
1310 Rint( "drawTopoff", "DrawTopoff", draw_topoff, "2" ) ,
1311 Rint( "drawLftoff", "DrawLftoff", draw_lftoff, "2" ) ,
1312
1313 /* PopupNotice() */
1314 RBoolean( "popResize",   "PopResize",   pop_resize ,   "True" ) ,
1315 RBoolean( "popMinimize", "PopMinimize", pop_minimize , "True" ) ,
1316
1317 /* CreateTemplateDialog() */
1318 RBoolean( "tempResize",   "TempResize",   temp_resize,   "True" ) ,
1319 RBoolean( "tempMinimize", "TempMinimize", temp_minimize, "True" ) ,
1320
1321 RDimension( "tempWidth",  "TempWidth",  temp_width,  "1" ) ,
1322 RDimension( "tempHeight", "TempHeight", temp_height, "1" ) ,
1323
1324 /* CreateMenuBarAndFooterMessageForm() */
1325 Rint( "edBarTopoff", "EdBarTopoff", ed_bar_topoff, "1" ) ,
1326 Rint( "edBarLftoff", "EdBarLftoff", ed_bar_lftoff, "1" ) ,
1327 Rint( "edBarRghoff", "EdBarRghoff", ed_bar_rghoff, "1" ) ,
1328
1329 Rint( "edFrmBtmoff", "EdFrmBtmoff", ed_frm_btmoff, "3" ) ,
1330 Rint( "edFrmLftoff", "EdFrmLftoff", ed_frm_lftoff, "3" ) ,
1331 Rint( "edFrmRghoff", "EdFrmRghoff", ed_frm_rghoff, "3" ) ,
1332
1333 RDimension( "edMsgMargintop", "EdMsgMargintop", ed_msg_margintop, "3" ) ,
1334 RDimension( "edMsgMarginbtm", "EdMsgMarginbtm", ed_msg_marginbtm, "3" ) ,
1335
1336 RDimension( "edMesgMargintop", "EdMesgMargintop", ed_mesg_margintop, "3" ) ,
1337 RDimension( "edMesgMarginbtm", "EdMesgMarginbtm", ed_mesg_marginbtm, "3" ) ,
1338
1339 Rint( "edSepBtmoff", "EdSepBtmoff", ed_sep_btmoff, "3" ) ,
1340 Rint( "edSepLftoff", "EdSepLftoff", ed_sep_lftoff, "0" ) ,
1341 Rint( "edSepRghoff", "EdSepRghoff", ed_sep_rghoff, "0" ) ,
1342 RDimension( "edSepMargin", "EdSepMargin", ed_sep_margin, "0" ) ,
1343
1344 Rint( "edWgeTopoff", "EdWgeTopoff", ed_wge_topoff, "10" ) ,
1345 Rint( "edWgeLftoff", "EdWgeLftoff", ed_wge_lftoff, "10" ) ,
1346 Rint( "edWgeRghoff", "EdWgeRghoff", ed_wge_rghoff, "10" ) ,
1347 Rint( "edWgeBtmoff", "EdWgeBtmoff", ed_wge_btmoff, "10" ) ,
1348
1349 /* CreateFrame() */
1350 RBoolean( "frameResize", "FrameResize", frame_resize, "False" ) ,
1351
1352 /* CreateScrollBase() */
1353 RDimension( "scllFrWidth", "ScllFrWidth", scll_fr_width, "500" ) ,
1354
1355 RDimension( "scllFrThick", "ScllFrThick", scll_fr_thick, "2" ) ,
1356
1357 Rint( "scllBarLftoff", "ScllBarLftoff", scll_bar_lftoff, "4" ) ,
1358 };
1359 #undef R
1360 #undef RBoolean
1361 #undef RDimension
1362 #undef Rint
1363 #undef RPixel
1364
1365 int CodePoint = False;
1366
1367 /*ARGSUSED*/
1368 static void
1369 xerror(Display *d, XErrorEvent *ev)
1370 {
1371     fprintf (stderr, "dtudcfonted:  warning, error event receieved.\n");
1372     exit(-1);
1373 }
1374
1375 int
1376 main(int argc, char *argv[])
1377 {
1378     static char class_name[] = "Dtudcfonted";
1379     int i;
1380
1381     /* initialize GUI */
1382     toplevel = GuiInitialize(&app, class_name, &argc, argv);
1383
1384     /* get application's resources */
1385     XtGetApplicationResources( toplevel, &resource,
1386                 app_resources, XtNumber(app_resources), NULL, 0);
1387
1388     if (resource.codepoint)
1389         CodePoint = True;
1390     /* initialize the code range */
1391     for( i=1  ;  i < argc  ; i++  ) {
1392         if( !strcmp(argv[i],"-pane_size") ) {
1393             i++;
1394             edpane_size = atoi( argv[i] );
1395         } else if( !strcmp(argv[i],"-codepoint") ) {
1396             CodePoint = True;
1397         }
1398     }
1399
1400     resource.mg_write_snf = GETMESSAGE(2, 2, "Registration processing inside.");
1401     resource.me_write_snf = GETMESSAGE(2, 4, "Failed in the registration of the character.");
1402     resource.me_illegal_code = GETMESSAGE(2, 6, "Illegal code.");
1403     resource.me_non_memory = GETMESSAGE(2, 8, "Because the memory allocation cannot be done, it is not possible to add.");
1404     resource.mg_non_code = GETMESSAGE(2, 10, "There is no character of the specified code.");
1405     resource.me_illegal_srccode = GETMESSAGE(2, 12, "The mistake is found in the specified copy origin code.");
1406     resource.me_illegal_destcode = GETMESSAGE(2, 14, "The mistake is found in the specified copy target code.");
1407     resource.me_nodelete_code = GETMESSAGE(2, 16, "There is no character in the specified area.");
1408     resource.me_wait = GETMESSAGE(2, 18, "Please wait for a while.");
1409     resource.me_non_srcfile = GETMESSAGE(2, 20, "No copy origin code file is specified.");
1410     resource.mn_no_font = GETMESSAGE(2, 22, "Informations of user defined character cannot collect.\nThere is no font specified.");
1411     resource.mn_plural_font = GETMESSAGE(2, 24, "Informations of user defined character cannot collect.\nThere are plural fonts specified.");
1412     resource.mn_not_udc = GETMESSAGE(2, 26, "The specified font do not have any UDCs areas.");
1413     resource.mn_no_mem = GETMESSAGE(2, 28, "There are no memories any more.");
1414     resource.mn_illegal_area = GETMESSAGE(2, 30, "The information of UDCs area is illegal.");
1415     resource.mn_no_read = GETMESSAGE(2, 32, "The font file cannot read.\nPattern area was broken.");
1416     resource.mn_prop_font = GETMESSAGE(2, 34, "Dtudcfonted cannot edit proportional character font.");
1417     resource.mn_saved_open = GETMESSAGE(2, 36, "There are unsaved edits.\nDo you want to save them before opening?");
1418     resource.mn_saved_exit = GETMESSAGE(2, 38, "There are unsaved edits.\nDo you want to save them before exiting?");
1419     resource.mn_cpy_lost = GETMESSAGE(2, 40, "When the copy processing is done, the glyph\nimage within the following ranges is changed.\nDo you want to do the copy processing?\n\n");
1420     resource.mn_no_perm = GETMESSAGE(2, 42, "No write permission for this font. You should change the file access mode before saving.\n");
1421
1422     resource.l_selectitem = GETMESSAGE(2, 100, "Select Items"); /* font open */
1423     resource.l_codeset = GETMESSAGE(2, 102, "         CodeSet:");
1424     resource.l_style = GETMESSAGE(2, 104, "           Style:");
1425     resource.l_width = GETMESSAGE(2, 106, "           Width:");
1426     resource.l_height = GETMESSAGE(2, 108, "          Height:");
1427     resource.exec_label = GETMESSAGE(2, 110, "Open");
1428     resource.quit_label = GETMESSAGE(2, 112, "Quit");
1429
1430     resource.l_font = GETMESSAGE(2, 114, "Font");               /* menu bar */
1431     resource.l_edit = GETMESSAGE(2, 116, "Edit");
1432     resource.l_manage = GETMESSAGE(2, 118, "Character");
1433     resource.l_info = GETMESSAGE(2, 120, "Information");
1434
1435     resource.l_open_w = GETMESSAGE(2, 122, "Open");             /* font menu */
1436     resource.l_save = GETMESSAGE(2, 124, "Save");
1437     resource.l_exit = GETMESSAGE(2, 126, "Exit");
1438
1439     resource.l_clear = GETMESSAGE(2, 128, "Clear");             /* edit menu */
1440     resource.l_set = GETMESSAGE(2, 130, "Set");
1441     resource.l_reverse = GETMESSAGE(2, 132, "Reverse");
1442     resource.l_cut = GETMESSAGE(2, 134, "Cut");
1443     resource.l_Copy = GETMESSAGE(2, 135, "Copy");
1444     resource.l_paste = GETMESSAGE(2, 136, "Paste");
1445     resource.l_roll = GETMESSAGE(2, 138, "Rotate");
1446     resource.l_updown_roll = GETMESSAGE(2, 140, "Vertical Roll");
1447     resource.l_leftright_roll = GETMESSAGE(2, 142, "Horizontal Roll");
1448     resource.l_undo = GETMESSAGE(2, 144, "Undo");
1449
1450     resource.l_manage_w = GETMESSAGE(2, 146, "Add/Delete...");  /* character menu */
1451     resource.l_copy_w = GETMESSAGE(2, 148, "Copy...");
1452
1453     resource.l_xlfd = GETMESSAGE(2, 150, "XLFD name...");               /* information menu */
1454     resource.l_codearea = GETMESSAGE(2, 152, "Code Area...");
1455
1456     resource.l_add = GETMESSAGE(2, 154, "Add");         /* add/delete dialog */
1457     resource.l_delete = GETMESSAGE(2, 156, "Delete");
1458     resource.l_cancel = GETMESSAGE(2, 158, "Cancel");
1459
1460     resource.l_manage_code = GETMESSAGE(2, 160, "Code(hex):"); /* copy dialog */
1461     resource.l_copy_src_code = GETMESSAGE(2, 162, " Copy origin code(hex):");
1462     resource.l_copy_dest_code = GETMESSAGE(2, 164, "Copy target code(hex):");
1463     resource.l_copy = GETMESSAGE(2, 166, "Copy");
1464     resource.l_overlay = GETMESSAGE(2, 168, "Overlay");
1465     resource.l_ok = GETMESSAGE(2, 170, "OK");
1466
1467     resource.l_do_save = GETMESSAGE(2, 172, "Save");    /* unsaved edits */
1468     resource.l_dont_save = GETMESSAGE(2, 174, "Do not Save");
1469     resource.l_do_save_exit = GETMESSAGE(2, 176, "Save and Exit");
1470     resource.l_dont_save_exit = GETMESSAGE(2, 178, "Do not Save and Exit");
1471
1472     resource.mg_start_del_s = GETMESSAGE(2, 180, "The following character will be deleted.");   /* delete notice dialog */
1473     resource.mg_start_del_cs = GETMESSAGE(2, 182, "character");
1474     resource.mg_start_del_m = GETMESSAGE(2, 184, "The following characters will be deleted.");
1475     resource.mg_start_del_cm = GETMESSAGE(2, 186, "characters");
1476     resource.mg_register = GETMESSAGE(2, 188, "Register completed");
1477     resource.l_code = GETMESSAGE(2, 190, " Code : ");
1478     resource.l_code_range = GETMESSAGE(2, 192, " Code range : ");
1479
1480     resource.message = GETMESSAGE(2, 194, "Message : ");
1481
1482     resource.code = GETMESSAGE(2, 196, "code...");      /* code dialog */
1483     resource.previous = GETMESSAGE(2, 198, "Page up");
1484     resource.next = GETMESSAGE(2, 200, "Page down");
1485     resource.apply = GETMESSAGE(2, 202, "Apply");
1486
1487     resource.l_question_title = GETMESSAGE(2, 204, "dtudcfonted - Question");
1488     resource.l_warning_title = GETMESSAGE(2, 206, "dtudcfonted - Warning");
1489     resource.l_error_title = GETMESSAGE(2, 208, "dtudcfonted -  Error");
1490     resource.l_copy_title = GETMESSAGE(2, 210, "dtudcfonted - Copy");
1491     resource.l_open_title = GETMESSAGE(2, 212, "dtudcfonted - Open");
1492     resource.l_add_title = GETMESSAGE(2, 214, "dtudcfonted - Add/Delete");
1493     resource.l_xlfd_title = GETMESSAGE(2, 216, "dtudcfonted - XLFD");
1494     resource.l_codearea_title = GETMESSAGE(2, 218, "dtudcfonted - CodeArea");
1495
1496     resource.file_name = GETMESSAGE(2, 230, "File name");
1497     resource.xlfd_name = GETMESSAGE(2, 232, "XLFD name");
1498     resource.codearea = GETMESSAGE(2, 234, "Code area");
1499
1500     resource.falerrmsg[0] = GETMESSAGE(2, 300, "Fatal error occurred.");
1501     resource.falerrmsg[1] = GETMESSAGE(2, 301, "Cannot open the font file.");
1502     resource.falerrmsg[2] = GETMESSAGE(2, 302, "Cannot read the font file.");
1503     resource.falerrmsg[3] = GETMESSAGE(2, 303, "There is no more memory.");
1504     resource.falerrmsg[4] = GETMESSAGE(2, 304, "Fatal error occurred.");
1505     resource.falerrmsg[5] = GETMESSAGE(2, 305, "The specified font file does not exist.");
1506     resource.falerrmsg[6] = GETMESSAGE(2, 306, "This font is not a pcf or snf font.");
1507     resource.falerrmsg[7] = GETMESSAGE(2, 307, "Cannot open fonts.list file.");
1508     resource.falerrmsg[8] = GETMESSAGE(2, 308, "The format of fonts.list file is illegal.");
1509     resource.falerrmsg[9] = GETMESSAGE(2, 309, "The descriptions of the fonts.list file are incorrect.");
1510     resource.falerrmsg[10] = GETMESSAGE(2, 310, "The format of fonts.list file is illegal.");
1511     resource.falerrmsg[11] = GETMESSAGE(2, 311, "Cannot open fonts.dir file.");
1512     resource.falerrmsg[12] = GETMESSAGE(2, 312, "Cannot read fonts.dir file.");
1513     resource.falerrmsg[13] = GETMESSAGE(2, 313, "Cannot read font properties.");
1514     resource.falerrmsg[14] = GETMESSAGE(2, 314, "Cannot get FONT property.");
1515     resource.falerrmsg[15] = GETMESSAGE(2, 315, "Cannot get FAMILY_NAME property.");
1516     resource.falerrmsg[16] = GETMESSAGE(2, 316, "This font file is already opened by other application.");
1517     resource.falerrmsg[17] = GETMESSAGE(2, 317, "Cannot lock font file.");
1518     resource.falerrmsg[18] = GETMESSAGE(2, 318, "Cannot unlock font file.");
1519     resource.falerrmsg[19] = GETMESSAGE(2, 319, "Cannot get lock information from the font file.");
1520     resource.falerrmsg[20] = GETMESSAGE(2, 320, "Cannot find the specified font file.");
1521     resource.falerrmsg[21] = GETMESSAGE(2, 321, "Cannot read NLS database.");
1522     resource.falerrmsg[22] = GETMESSAGE(2, 322, "Cannot get charset names from NLS database.");
1523     resource.falerrmsg[23] = GETMESSAGE(2, 323, "Charset name not defined in NLS database.");
1524     resource.falerrmsg[24] = GETMESSAGE(2, 324, "The specified font has not been opened.");
1525     resource.falerrmsg[25] = GETMESSAGE(2, 325, "Fatal error occurred.");
1526
1527     xlfdDialog   = NULL ;
1528     cpyDialog    = NULL ;
1529
1530     /* initialize the global values and allocate the memories */
1531     xeg_init();
1532
1533
1534     /* displays the selection window */
1535     PopupSelectXLFD(toplevel);
1536
1537     XSetErrorHandler((XErrorHandler)xerror);
1538     XSetIOErrorHandler((XIOErrorHandler)xerror);
1539
1540     /* main loop */
1541     XtAppMainLoop(app);
1542
1543     return(-1);
1544 }
1545
1546
1547 /*
1548  * contents : initialize the global values
1549  */
1550
1551 static void
1552 xeg_init(void)
1553 {
1554     int i;
1555
1556     edg.code = edg.ncode = 0;
1557     bitPtnClear( edg.ptn );
1558     edg.flag = (char)0;
1559
1560     edlist.nlist = EDLIST_MAX;
1561     edlist.statloc = edlist.slctloc = 0;
1562     edlist.nptn = 0;
1563     edlist.sqstart = 0;
1564     edlist.list_h = edlist.elem_w = edlist.elem_h = (Dimension)0;
1565     edlist.back = resource.pane_background;
1566     edlist.border = resource.pane_foreground;
1567
1568     if ( edpane_size ){
1569         edpane.width = edpane_size;
1570         edpane.height = edpane_size;
1571     } else {
1572         edpane.width  = EDPANE_SIZE;
1573         edpane.height = EDPANE_SIZE;
1574     }
1575     edpane.pix_w  = edpane.pix_h = 0;
1576     edpane.color  = 0;
1577     edpane.obj    = 0;
1578     edpane.back   = resource.pane_background;
1579     edpane.border = resource.pane_foreground;
1580
1581     xl.display    = NULL;
1582     xl.root_winID = xl.edit_winID = xl.disp_winID = xl.list_winID =
1583                         (Window)NULL;
1584     xl.borderGC   = xl.backGC = xl.rubGC = xl.dashGC = (GC)NULL;
1585     xl.dispImage  = NULL;
1586
1587     dn.elem_w = dn.elem_h = (Dimension)0;
1588     dn.ptn_w  = dn.ptn_h  = (Dimension)0;
1589     dn.list_h = (Dimension)0;
1590     dn.s_ncode = dn.e_ncode = 0;
1591     dn.sq_top = dn.sq_start = dn.sq_end = 0;
1592     dn.disp_num = 0;
1593
1594     for ( i=0 ; i<D_MAX ; i++ ) {
1595         dl[i].disp_winID = (Window)NULL;
1596         dl[i].dispImage = NULL;
1597         bitPtnClear( dl[i].ptn );
1598     }
1599     for ( i=0 ; i<EDLIST_MAX ; i++ ) {
1600         dl_glyph[i].disp_winID = (Window)NULL;
1601         dl_glyph[i].dispImage = NULL;
1602         bitPtnClear( dl_glyph[i].ptn );
1603         sq_disp[i] = 0 ;
1604     }
1605     em.drag_f = OFF;
1606     em.adj_px = em.adj_py = 0;
1607     em.proc = em.slct_f = 0;
1608     em.src1_px = em.src1_py = 0;
1609     em.src2_px = em.src2_py = 0;
1610     em.dest_px = em.dest_py = 0;
1611     em.rsv_f = (char)0;
1612     bitPtnClear( em.rsv_ptn );
1613
1614     cpm.s1_code = cpm.s2_code = cpm.d1_code = 0;
1615     cpm.proc = 0;
1616
1617     return;
1618 }
1619
1620
1621
1622 /****************************************************************
1623  * distroy the "User defined character editor" window           *
1624  ****************************************************************/
1625
1626 /*
1627  * contents : destroy the editting window
1628  */
1629
1630 static void
1631 dstrypaneEditPtn(void)
1632 {
1633     int i ;
1634
1635     ptnClose();
1636
1637     XFree( (char *)xl.dispImage );
1638     XFreeGC( xl.display, xl.borderGC );
1639     XFreeGC( xl.display, xl.backGC );
1640     XFreeGC( xl.display, xl.rubGC );
1641     XFreeGC( xl.display, xl.dashGC );
1642
1643     for( i=0; i<EDLIST_MAX; i++ ){
1644         if( dl_glyph[i].dispImage ){
1645             XFree( (char *)dl_glyph[i].dispImage );
1646             dl_glyph[i].dispImage = NULL ;
1647         }
1648     }
1649
1650     XtPopdown( editPopW );
1651     XtDestroyWidget( editPopW );
1652
1653     return;
1654 }
1655
1656
1657 /****************************************************************
1658  * update character list                                        *
1659  ***************************************************************/
1660
1661 /*
1662  * contents :   add the specified code to the character list
1663  */
1664
1665 void
1666 chgEdCode( int code, char mode )
1667 {
1668     int ncode;
1669     int esq;
1670     int statloc;
1671     int slctloc;
1672     int slimax;
1673
1674     if( code == 0 ) {
1675         esq = -1;
1676     } else {
1677         ncode = codeToNo( code );
1678         esq = ptnNoToSq( ncode ) - edlist.sqstart;
1679     }
1680     if( esq < 0 ) {
1681         slctloc = -1;
1682         statloc = 0;
1683     } else if (efctPtnNum() <= edlist.nlist) {
1684         statloc = 0;
1685         slctloc = AbsSqToRel(edlist.sqstart, ptnNoToSq( ncode));
1686     } else {
1687         if ((esq >= edlist.statloc)
1688             && (esq <= (RelToAbsSq( edlist.sqstart + edlist.statloc,
1689                             edlist.nlist - 1) - edlist.sqstart))){
1690             statloc = edlist.statloc;
1691             slctloc = AbsSqToRel(edlist.sqstart+statloc,
1692                                         edlist.sqstart + esq);
1693         } else {
1694             statloc = esq;
1695             slctloc = 0;
1696         }
1697         while( RelToAbsSq(edlist.sqstart+statloc, edlist.nlist - 1) < 0)
1698             statloc = RelToAbsSq( edlist.sqstart + statloc, -1)
1699                        - edlist.sqstart;
1700         slctloc = AbsSqToRel( edlist.sqstart + statloc, edlist.sqstart + esq);
1701     }
1702
1703     n = 0;
1704     if (( slimax = efctPtnNum()) < edlist.nlist)
1705         slimax = edlist.nlist;
1706     XtSetArg( arg[n], XmNmaximum,   (XtArgVal)slimax ); n++;
1707     XtSetArg( arg[n], XmNvalue, (XtArgVal)AbsSqToRel( edlist.sqstart, edlist.sqstart + statloc) );      n++;
1708     XtSetValues( wgeScro , arg, n );
1709
1710     chgEdList( statloc, slctloc, mode );
1711     chgEdPtn( code );
1712 }
1713
1714
1715 /*
1716  * contents : rewrite the character list
1717  */
1718
1719 void
1720 chgEdList( int statloc, int slctloc, char mode  )
1721 {
1722     int         sq;
1723     int         i;
1724     char        str[6];
1725     int         no;
1726     int         code;
1727     extern void ListSetLabelStr();
1728     extern void ListSetGlyphImage();
1729     extern void ListUnselectItem();
1730     extern void ListSelectItem();
1731
1732     if((mode == ON) || (edlist.statloc != statloc)){
1733         for (i=0, sq=edlist.sqstart+statloc; i < edlist.nlist; sq++){
1734             no = ptnSqToNo(sq);
1735             sq_disp[i] = sq ;
1736
1737             if ((no >= 0) && (code = noToCode(no)) >= 0 ){
1738                 sprintf(str, "%4x", code);
1739                 ListSetLabelStr(i, str);
1740                 ListSetGlyphImage(i) ;
1741                 if (i == 0)
1742                     edlist.statloc = sq - edlist.sqstart;
1743                 i++;
1744             } else if (sq > ( edlist.sqstart + edlist.nptn - 1)){
1745                 strcpy(str, "    ");
1746                 ListSetLabelStr(i, str);
1747                 ListSetGlyphImage(i) ;
1748                 i++;
1749             }
1750         }
1751     }
1752
1753     if( (mode == ON) || (edlist.slctloc != slctloc) ) {
1754         if((0 <= edlist.slctloc) && (edlist.slctloc < edlist.nlist)){
1755             ListUnselectItem(edlist.slctloc);
1756         }
1757         if((0 <= slctloc) && (slctloc < edlist.nlist)){
1758             ListSelectItem(slctloc);
1759         }
1760         edlist.slctloc = slctloc;
1761     }
1762 }
1763
1764
1765 /*
1766  * contents : rewrite the editting pane
1767  */
1768
1769 static void
1770 chgEdPtn( int code )
1771 {
1772     extern void SetCodeString();
1773
1774         if (xl.display == NULL ){
1775                 return;
1776         }
1777
1778     if( code == 0 ) {
1779         XClearWindow( xl.display, xl.edit_winID );
1780         DrawBorderEdPn( 0, 0, edg.width - 1, edg.height - 1 );
1781         XClearWindow( xl.display, xl.disp_winID );
1782         XClearWindow( xl.display, xl.list_winID );
1783         bitPtnClear( edg.ptn );
1784         edg.code = 0;
1785         edg.ncode = 0;
1786         SetCodeString(0);
1787     }
1788
1789     if( ptnGet( code, edg.ptn) == 0 ) {
1790         edg.code = code;
1791         edg.ncode = codeToNo( code );
1792         DrawRectEdPn( 0, 0, edg.width - 1, edg.height - 1 );
1793
1794         SetCodeString(code);
1795         DrawDpPn();
1796     }
1797 }
1798
1799
1800
1801
1802
1803 /****************************************************************
1804  * draw patterns to the editting pane                           *
1805  ***************************************************************/
1806
1807 /*
1808  * contents : draw a rectangle
1809  *
1810  */
1811
1812 static void
1813 DrawRectEdPn( int x1, int y1, int x2, int y2 )
1814 {
1815     int i, j, wk;
1816     short    cx1, cy1, cx2, cy2;
1817     XRectangle    recOn[MAXPTNSIZE*MAXPTNSIZE];
1818     XRectangle    recOff[MAXPTNSIZE*MAXPTNSIZE];
1819     int nron, nroff;
1820
1821     if (xl.display == NULL ){
1822             return;
1823     }
1824
1825     if( x2 < x1 ) {
1826         wk = x2;
1827         x2 = x1;
1828         x1 = wk;
1829     }
1830     if( y2 < y1 ) {
1831         wk = y2;
1832         y2 = y1;
1833         y1 = wk;
1834     }
1835
1836     nron = nroff = 0;
1837     for( j=y1   ;   j <= y2   ;  j++ ) {
1838         for( i=x1   ;   i <= x2   ;   i++ ) {
1839             cx1 = (short)(edpane.pix_w * i);
1840             cy1 = (short)(edpane.pix_h * j);
1841             cx2 = (short)(cx1 + edpane.pix_w - 1);
1842             cy2 = (short)(cy1 + edpane.pix_h - 1);
1843
1844             if( bitRead( edg.ptn, i, j ) != 0 ) {
1845                 recOn[nron].x = cx1;
1846                 recOn[nron].y = cy1;
1847                 recOn[nron].width  = (unsigned short)(cx2 - cx1);
1848                 recOn[nron].height = (unsigned short)(cy2 - cy1);
1849                 nron++;
1850             }
1851             else {
1852                 recOff[nroff].x = cx1;
1853                 recOff[nroff].y = cy1;
1854                 recOff[nroff].width  = (unsigned short)(cx2 - cx1);
1855                 recOff[nroff].height = (unsigned short)(cy2 - cy1);
1856                 nroff++;
1857             }
1858         }
1859     }
1860     if( nron )
1861         XFillRectangles( xl.display, xl.edit_winID, xl.borderGC, recOn, nron );
1862     if( nroff )
1863         XFillRectangles( xl.display, xl.edit_winID, xl.backGC,   recOff, nroff );
1864 }
1865
1866
1867 /*
1868  * contents : draw a lattice inside of the editting pane
1869  */
1870
1871 static void
1872 DrawBorderEdPn( int x1, int y1, int x2, int y2 )
1873 {
1874     short       cx1, cy1;
1875     short       cx2, cy2;
1876     int         ndseg;
1877     int         wk, i;
1878     XSegment    dseg[MAXPTNSIZE*2];
1879
1880     if (xl.display == NULL ){
1881             return;
1882     }
1883
1884     if( x2 < x1 ) {
1885         wk = x2;
1886         x2 = x1;
1887         x1 = wk;
1888     }
1889     if( y2 < y1 ) {
1890         wk = y2;
1891         y2 = y1;
1892         y1 = wk;
1893     }
1894
1895     ndseg = 0;
1896
1897     cx1 = (short)(edpane.pix_w * x1);
1898     cx2 = (short)(edpane.pix_w * x2 + edpane.pix_w - 1);
1899     for( i=y1  ;  i <= y2  ;  i++ ) {
1900         cy1 = (short)(edpane.pix_h * i + edpane.pix_h - 1);
1901         dseg[ndseg].x1 = cx1;
1902         dseg[ndseg].y1 = cy1;
1903         dseg[ndseg].x2 = cx2;
1904         dseg[ndseg].y2 = cy1;
1905         ndseg++;
1906     }
1907     cy1 = (short)(edpane.pix_h * y1);
1908     cy2 = (short)(edpane.pix_h * y2 + edpane.pix_h - 1);
1909     for( i=x1  ;  i <= x2  ;   i++ ) {
1910         cx1 = (short)(edpane.pix_w * i + edpane.pix_w - 1);
1911         dseg[ndseg].x1 = cx1;
1912         dseg[ndseg].y1 = cy1;
1913         dseg[ndseg].x2 = cx1;
1914         dseg[ndseg].y2 = cy2;
1915         ndseg++;
1916     }
1917
1918     if( ndseg ) {
1919         XDrawSegments( xl.display,  xl.edit_winID,  xl.dashGC,  dseg, ndseg);
1920     }
1921 }
1922
1923
1924 /*
1925  * contents : draw a dot
1926  */
1927
1928 static void
1929 DrawPointEdPn( int x, int y, int mode )
1930 {
1931     int         x1, y1;
1932     int         x2, y2;
1933
1934     if (xl.display == NULL ){
1935             return;
1936     }
1937
1938     x1 = edpane.pix_w * x;
1939     y1 = edpane.pix_h * y;
1940     x2 = x1 + edpane.pix_w - 1;
1941     y2 = y1 + edpane.pix_h - 1;
1942
1943     if( mode != 0 ) {
1944         XFillRectangle( xl.display, xl.edit_winID, xl.borderGC,
1945                         x1, y1, x2-x1, y2-y1 );
1946     } else {
1947         XFillRectangle( xl.display, xl.edit_winID, xl.backGC,
1948                         x1, y1, x2-x1, y2-y1 );
1949     }
1950 }
1951
1952
1953
1954 /*
1955  * contents : draw a current character pattern to the display pane
1956  */
1957
1958 static void
1959 DrawDpPn(void)
1960 {
1961         if (xl.display == NULL ){
1962                 return;
1963         }
1964
1965         XPutImage( xl.display,  xl.disp_winID,  xl.borderGC,  xl.dispImage,
1966               0, 0, 0, 0, edg.width, edg.height );
1967         if( xl.list_winID ) {
1968                 XPutImage( xl.display,  xl.list_winID,  xl.borderGC,
1969                         xl.dispImage, 0, 0, 0, 0, edg.width, edg.height );
1970         }
1971 }
1972
1973
1974
1975 /*
1976  * contents : draw a dot
1977  */
1978
1979 static void
1980 DrawPointDpPn( int x, int y, int mode )
1981 {
1982
1983     if (xl.display == NULL ){
1984             return;
1985     }
1986     if( mode != 0 ){
1987         XDrawPoint( xl.display,  xl.disp_winID,  xl.borderGC, x,  y );
1988         if (xl.list_winID)
1989             XDrawPoint( xl.display,  xl.list_winID,  xl.borderGC, x,  y );
1990     } else {
1991         XDrawPoint( xl.display,  xl.disp_winID,  xl.backGC,   x,  y );
1992         if (xl.list_winID)
1993             XDrawPoint( xl.display,  xl.list_winID,  xl.backGC,   x,  y );
1994     }
1995 }
1996
1997
1998
1999 /****************************************************************
2000  * draw patterns by mouse                                       *
2001  ****************************************************************/
2002
2003
2004 /*
2005  * contents : draw a dot
2006  */
2007
2008 static void
2009 musPoint( int evtype, int px, int py )
2010 {
2011     switch( evtype ) {
2012     case MotionNotify:
2013         if( (em.src1_px == px) && (em.src1_py == py) )
2014             return;
2015         break;
2016     case ButtonPress:
2017         em.src1_px = px;
2018         em.src1_py = py;
2019         break;
2020     default:
2021         return;
2022     }
2023
2024     if( edpane.color == ON )
2025         bitSet( edg.ptn, px, py );
2026     else
2027         bitReset( edg.ptn, px, py );
2028     edg.flag = ON;
2029     DrawPointEdPn( px, py, edpane.color );
2030     DrawPointDpPn( px, py, edpane.color );
2031 }
2032
2033
2034 /*
2035  * contents : draw a line
2036  */
2037
2038 static void
2039 musLine( int evtype, int px, int py )
2040 {
2041     int         r1_x, r1_y;
2042     int         r2_x, r2_y;
2043     int         rx,   ry;
2044     int         harf_pix_w;
2045     int         harf_pix_h;
2046
2047     harf_pix_w = edpane.pix_w / 2;
2048     harf_pix_h = edpane.pix_h / 2;
2049     r1_x = em.src1_px * edpane.pix_w + harf_pix_w;
2050     r1_y = em.src1_py * edpane.pix_h + harf_pix_h;
2051     r2_x = em.src2_px * edpane.pix_w + harf_pix_w;
2052     r2_y = em.src2_py * edpane.pix_h + harf_pix_h;
2053     rx = px * edpane.pix_w + harf_pix_w;
2054     ry = py * edpane.pix_h + harf_pix_h;
2055
2056     switch( evtype ) {
2057     case MotionNotify:
2058         if( (em.src2_px == px) && (em.src2_py == py) )
2059             return;
2060         rubLine( r1_x, r1_y, r2_x, r2_y );
2061         rubLine( r1_x, r1_y, rx, ry );
2062         em.src2_px = px;
2063         em.src2_py = py;
2064         return;
2065     case ButtonPress:
2066         em.src1_px = em.src2_px = px;
2067         em.src1_py = em.src2_py = py;
2068         return;
2069     default:
2070         if( (r1_x == r2_x) && (r1_y == r2_y) )
2071             return;
2072         rubLine( r1_x, r1_y, r2_x, r2_y );
2073
2074         if ((em.src2_px < 0) || (em.src2_py < 0) ||
2075             (edg.width <= em.src2_px) || (edg.height <= em.src2_py))
2076             return;
2077
2078         bitDrawLine( edg.ptn, em.src1_px, em.src1_py,
2079                               em.src2_px, em.src2_py, edpane.color );
2080         edg.flag = ON;
2081         DrawRectEdPn( em.src1_px, em.src1_py, em.src2_px, em.src2_py );
2082         DrawDpPn();
2083     }
2084 }
2085
2086
2087
2088 /*
2089  * contents : draw a circle
2090  */
2091
2092 static void
2093 musCircle( int evtype, int px, int py )
2094 {
2095     int         r1_x, r1_y;
2096     int         r2_x, r2_y;
2097     int         rx,   ry;
2098     int         harf_pix_w;
2099     int         harf_pix_h;
2100     extern int  bitDrawCircle();
2101
2102     harf_pix_w = edpane.pix_w / 2;
2103     harf_pix_h = edpane.pix_h / 2;
2104
2105     r1_x = em.src1_px * edpane.pix_w + harf_pix_w;
2106     r1_y = em.src1_py * edpane.pix_h + harf_pix_h;
2107     r2_x = em.src2_px * edpane.pix_w + harf_pix_w;
2108     r2_y = em.src2_py * edpane.pix_h + harf_pix_h;
2109     rx = px * edpane.pix_w + harf_pix_w;
2110     ry = py * edpane.pix_h + harf_pix_h;
2111
2112     switch( evtype ) {
2113     case MotionNotify:
2114         if( (em.src2_px == px) && (em.src2_py == py) ) {
2115             return;
2116         }
2117         rubCircle( r1_x, r1_y, r2_x, r2_y );
2118         rubCircle( r1_x, r1_y, rx, ry );
2119         em.src2_px = px;
2120         em.src2_py = py;
2121         return;
2122     case ButtonPress:
2123         em.src1_px = em.src2_px = px;
2124         em.src1_py = em.src2_py = py;
2125         return;
2126     default:
2127         if( (em.src1_px == px) && (em.src1_py == py) ) {
2128             return;
2129         }
2130         rubCircle( r1_x, r1_y, r2_x, r2_y );
2131
2132         if( (px < 0) || (py < 0) || (edg.width <= px) || (edg.height <= py) ) {
2133             return;
2134         }
2135         bitDrawCircle( edg.ptn, em.src1_px, em.src1_py, px, py, edpane.color);
2136
2137         edg.flag = ON;
2138         DrawRectEdPn( 0, 0, edg.width -1, edg.height -1 );
2139         DrawDpPn();
2140     }
2141 }
2142
2143
2144 /*
2145  * contents : draw a rectangle
2146  */
2147
2148 static void
2149 musRect( int proc, int evtype, int px, int py )
2150 {
2151     int         r1_x, r1_y;
2152     int         r2_x, r2_y;
2153     int         rx,   ry;
2154     int         lux, luy;
2155     int         width, height;
2156     int         dpx, dpy, dp;
2157
2158     if( (proc == PROC_ROLL) && (evtype != ButtonPress) ) {
2159         dpx = px - em.src1_px;
2160         dpy = py - em.src1_py;
2161         dp = (abs(dpx) > abs(dpy) ) ? abs(dpx) : abs(dpy);
2162
2163         if( dpx != 0 )
2164             px = em.src1_px + dpx/abs(dpx) * dp;
2165         if( dpy != 0 )
2166             py = em.src1_py + dpy/abs(dpy) * dp;
2167     }
2168
2169     r1_x = em.src1_px * edpane.pix_w + edpane.pix_w / 2;
2170     r1_y = em.src1_py * edpane.pix_h + edpane.pix_h / 2;
2171     r2_x = em.src2_px * edpane.pix_w + edpane.pix_w / 2;
2172     r2_y = em.src2_py * edpane.pix_h + edpane.pix_h / 2;
2173     rx = px * edpane.pix_w + edpane.pix_w / 2;
2174     ry = py * edpane.pix_h + edpane.pix_h / 2;
2175
2176     switch( evtype ) {
2177     case MotionNotify:
2178         if( (em.src2_px == px) && (em.src2_py == py) )
2179             return;
2180         rubBand( r1_x, r1_y, r2_x, r2_y );
2181         rubBand( r1_x, r1_y, rx, ry );
2182         em.src2_px = px;
2183         em.src2_py = py;
2184         return;
2185     case ButtonPress:
2186         resetEditMode( RES_SLCT );
2187         em.src1_px = em.src2_px = px;
2188         em.src1_py = em.src2_py = py;
2189         return;
2190     default:
2191         resetEditMode( RES_MSG | RES_PROC );
2192         rubBand( r1_x,  r1_y,  r2_x,  r2_y );
2193         if( (r1_x == r2_x) || (r1_y == r2_y) )
2194             return;
2195         if( (em.src2_px < 0) || (em.src2_py < 0) ||
2196             (edg.width <= em.src2_px) || (edg.height <= em.src2_py)     )
2197             return;
2198
2199         lux = (em.src1_px < em.src2_px ) ?  em.src1_px   :   em.src2_px;
2200         luy = (em.src1_py < em.src2_py ) ?  em.src1_py   :   em.src2_py;
2201         width  = abs( em.src1_px - em.src2_px ) + 1;
2202         height = abs( em.src1_py - em.src2_py ) + 1;
2203
2204         bitDrawRect(edg.ptn, lux, luy, width, height, edpane.color);
2205
2206         edg.flag = ON;
2207         DrawRectEdPn( em.src1_px, em.src1_py, px, py );
2208         DrawDpPn();
2209     }
2210 }
2211
2212
2213 /*
2214  * contents : edit inside of the specified area (clear, reverse, rotate,etc.)
2215  */
2216
2217 static void
2218 musRegionProc( int proc, int evtype, int px, int py )
2219 {
2220     int         rx,   ry;
2221     int         dpx, dpy, dp;
2222     extern void SelectSet();
2223
2224     if( (proc == PROC_ROLL) && (evtype != ButtonPress) ) {
2225         dpx = px - em.src1_px;
2226         dpy = py - em.src1_py;
2227         dp = (abs(dpx) > abs(dpy) ) ? abs(dpx) : abs(dpy);
2228
2229         if( dpx != 0 )
2230             px = em.src1_px + dpx/abs(dpx) * dp;
2231         if( dpy != 0 )
2232             py = em.src1_py + dpy/abs(dpy) * dp;
2233     }
2234
2235     r1_x = em.src1_px * edpane.pix_w + edpane.pix_w / 2;
2236     r1_y = em.src1_py * edpane.pix_h + edpane.pix_h / 2;
2237     r2_x = em.src2_px * edpane.pix_w + edpane.pix_w / 2;
2238     r2_y = em.src2_py * edpane.pix_h + edpane.pix_h / 2;
2239     rx = px * edpane.pix_w + edpane.pix_w / 2;
2240     ry = py * edpane.pix_h + edpane.pix_h / 2;
2241
2242     switch( evtype ) {
2243     case MotionNotify:
2244         if( (em.src2_px == px) && (em.src2_py == py) )
2245             return;
2246         rubBand( r1_x, r1_y, r2_x, r2_y );
2247         rubBand( r1_x, r1_y, rx, ry );
2248         em.src2_px = px;
2249         em.src2_py = py;
2250         return;
2251     case ButtonPress:
2252         if (select_x || select_y || select_w || select_h) {
2253             rubBand( r1_x, r1_y, r2_x, r2_y );
2254         }
2255         resetEditMode( RES_SLCT );
2256         em.src1_px = em.src2_px = px;
2257         em.src1_py = em.src2_py = py;
2258         return;
2259     default:
2260         resetEditMode( RES_MSG | RES_PROC );
2261         select_x = select_y = select_w  = select_h = 0;
2262         if( (r1_x == r2_x) || (r1_y == r2_y) ) {
2263             rubBand( r1_x,  r1_y,  r2_x,  r2_y );
2264             return;
2265         }
2266         if( (em.src2_px < 0) || (em.src2_py < 0) ||
2267             (edg.width <= em.src2_px) || (edg.height <= em.src2_py)     ) {
2268             rubBand( r1_x,  r1_y,  r2_x,  r2_y );
2269             return;
2270         }
2271
2272         select_x = (em.src1_px < em.src2_px ) ?  em.src1_px   :   em.src2_px;
2273         select_y = (em.src1_py < em.src2_py ) ?  em.src1_py   :   em.src2_py;
2274         select_w  = abs( em.src1_px - em.src2_px ) + 1;
2275         select_h = abs( em.src1_py - em.src2_py ) + 1;
2276         SelectSet();
2277     }
2278 }
2279
2280
2281 /*ARGSUSED*/
2282 static void
2283 musPasteProc(Widget w, XtPointer client_data, XEvent *event)
2284 {
2285     static int ox=0, oy=0;
2286     int rc, tx, ty;
2287     extern void UndoSet();
2288     extern Widget wgeBulB_edit;
2289     extern int  bitDrawPaste();
2290
2291     switch(event->type) {
2292     case MotionNotify:
2293         tx = (event->xmotion.x / edpane.pix_w) * edpane.pix_w + edpane.pix_w / 2;
2294         ty = (event->xmotion.y / edpane.pix_h) * edpane.pix_h + edpane.pix_h / 2;
2295         if (tx == ox && ty == oy)
2296             return;
2297         if(ox) {
2298             rubBand(ox, oy, ox + cut_w * edpane.pix_w, oy + cut_h * edpane.pix_h);
2299         }
2300         ox = tx;
2301         oy = ty;
2302         rubBand(ox, oy, ox + cut_w * edpane.pix_w, oy + cut_h * edpane.pix_h);
2303         break;
2304     case ButtonRelease:
2305         XtRemoveEventHandler(wgeBulB_edit,
2306                                 ButtonReleaseMask|PointerMotionMask,
2307                                     False, (XtEventHandler)musPasteProc, NULL );
2308         rubBand(ox, oy, ox + cut_w * edpane.pix_w, oy + cut_h * edpane.pix_h);
2309         ox = 0;
2310         oy = 0;
2311         bitPtnCopy( em.rsv_ptn,  edg.ptn );
2312
2313         tx = event->xbutton.x / edpane.pix_w;
2314         ty = event->xbutton.y / edpane.pix_h;
2315         rc = bitDrawPaste(edg.ptn, tx, ty);
2316         if( rc == -1 )
2317              return;
2318         edg.flag = ON;
2319         em.rsv_f = ON;
2320         DrawRectEdPn( 0, 0,  edg.width - 1,  edg.height - 1 );
2321         DrawDpPn();
2322         UndoSet();
2323         break;
2324     }
2325 }
2326
2327
2328
2329 static void
2330 rubLine( int x1, int y1, int x2, int y2  )
2331 {
2332     if( x1==x2 && y1==y2 ) return;
2333
2334     XDrawLine( xl.display, xl.edit_winID, xl.rubGC,    x1,y1, x2,y2 );
2335 }
2336
2337
2338
2339 static void
2340 rubBand( int x1, int y1, int x2, int y2  )
2341 {
2342     if( x1==x2 && y1==y2 )
2343         return;
2344
2345     XDrawLine( xl.display, xl.edit_winID, xl.rubGC, x1, y1, x2, y1 );
2346     XDrawLine( xl.display, xl.edit_winID, xl.rubGC, x1, y1, x1, y2 );
2347     XDrawLine( xl.display, xl.edit_winID, xl.rubGC, x2, y1, x2, y2 );
2348     XDrawLine( xl.display, xl.edit_winID, xl.rubGC, x1, y2, x2, y2 );
2349 }
2350
2351
2352
2353 static void
2354 rubCircle( int ox, int oy, int rx, int ry )
2355 {
2356     unsigned int        r;
2357     int                 x, y;
2358
2359     if( ox==rx && oy==ry ) return;
2360
2361     x = rx - ox;
2362     y = ry - oy;
2363     r = (unsigned int)sqrt( (double)(x*x + y*y) );
2364     if ( r == 0 ) return;
2365
2366     x = ox - (int)r;
2367     y = oy - (int)r;
2368     XDrawArc( xl.display, xl.edit_winID, xl.rubGC,
2369              x, y, 2*r-1, 2*r-1,
2370              0, 360*64
2371              );
2372 }
2373
2374
2375
2376 static void
2377 resetEditMode( unsigned int flag )
2378 {
2379     int         r1_x, r1_y;
2380     int         r2_x, r2_y;
2381
2382     if( flag & RES_MSG )
2383         UpdateMessage( "" );
2384
2385     if( flag & RES_PROC )
2386         em.proc = edpane.obj;
2387
2388     if( (flag & RES_SLCT) && (em.slct_f) ) {
2389         r1_x = em.src1_px * edpane.pix_w + edpane.pix_w / 2;
2390         r1_y = em.src1_py * edpane.pix_h + edpane.pix_h / 2;
2391         r2_x = em.src2_px * edpane.pix_w + edpane.pix_w / 2;
2392         r2_y = em.src2_py * edpane.pix_h + edpane.pix_h / 2;
2393         rubBand( r1_x, r1_y, r2_x, r2_y );
2394         em.slct_f = OFF;
2395     }
2396
2397     if( flag & RES_RSV )
2398         em.rsv_f = OFF;
2399 }
2400
2401
2402 /****************************************************************
2403  * copy character pattern                                       *
2404  ***************************************************************/
2405
2406 /*
2407  * contents : copy or overlay the new character pattern to the current pattern
2408  */
2409
2410 /*ARGSUSED*/
2411 static void
2412 copyPatterns(
2413     FalFontData *fdata,
2414     int s1_code,
2415     int s2_code,
2416     int d1_code,
2417     int proc)
2418 {
2419     int         ret;
2420     int         d1_ncode, d2_ncode;
2421     int         code_d;
2422     int         code_disp;
2423     char        err[128];
2424     int         i_s, i_d;
2425     int         i;
2426     char        grc_d;
2427     char        **ptn;
2428     char        ptn2[MAXPTNBYTE];
2429     int         num;
2430     extern int  last_code;
2431
2432     ret = copySNF(s1_code, s2_code, &ptn, &num, err);
2433     if( ret == -1 ) {
2434         Error_message2((Widget)NULL, err);
2435         return;
2436     }
2437
2438     if (last_code < (d1_code + num))
2439         last_code = d1_code + num;
2440
2441     if( ptnSense(edg.code) == 1 )
2442         ptnAdd( edg.code, edg.ptn );
2443
2444     d1_ncode = codeToNo( d1_code );
2445
2446     for (i_d=d1_ncode, i_s=0; i_s < num; i_d++) {
2447         if ( codeCheck( noToCode( i_d)))
2448             continue;
2449         bitPtnClear( ptn2 );
2450         code_d = noToCode( i_d );
2451         grc_d = ptnGet( code_d,  ptn2 );
2452
2453         if (grc_d == 0) {
2454             if( proc == CPY_OVERLAY ) {
2455                 for( i=0  ;  i < edg.height*((edg.width+7)/8)  ;  i++ ) {
2456                     ptn[i_s][i] |= ptn2[i];
2457                 }
2458             }
2459             ptnAdd( code_d, ptn[i_s] );
2460             edg.flag = ON;
2461         } else {
2462             if( ptnAdd( code_d, ptn[i_s] ) != 1 ) {
2463                 UpdateMessage( resource.me_non_memory );
2464                 break;
2465             }
2466             edlist.nptn++;
2467             edg.flag = ON;
2468         }
2469         i_s ++;
2470     }
2471     d2_ncode = i_d - 1;
2472
2473     code_disp = 0;
2474     for( i=d1_ncode   ; i <= d2_ncode; i++ ) {
2475         if ( codeCheck( noToCode(i) ) )
2476             continue;
2477         if( ptnSense( noToCode( i ) ) == 1 ) {
2478             code_disp = noToCode( i );
2479             break;
2480         }
2481     }
2482     freeSNF(ptn, num);
2483
2484     if( (code_disp == 0) && (efctPtnNum() > 0))
2485         code_disp = noToCode( ptnSqToNo(edlist.sqstart) );
2486
2487     chgEdCode( code_disp, ON );
2488
2489     resetEditMode( (unsigned int) (RES_MSG | RES_PROC | RES_SLCT | RES_RSV) );
2490 }