1 /* -*- coding: utf-8 -*- */
2 /* Copyright (C) 2003-2012 by George Williams */
3 /*
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6 
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9 
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13 
14  * The name of the author may not be used to endorse or promote products
15  * derived from this software without specific prior written permission.
16 
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <fontforge-config.h>
30 
31 #include "fontforgeui.h"
32 #include "gkeysym.h"
33 #include "macenc.h"
34 #include "splineutil.h"
35 #include "ttf.h"
36 #include "ustring.h"
37 
38 extern MacFeat *default_mac_feature_map,
39 	*builtin_mac_feature_map,
40 	*user_mac_feature_map;
41 
MacSettingCopy(struct macsetting * ms)42 static struct macsetting *MacSettingCopy(struct macsetting *ms) {
43     struct macsetting *head=NULL, *last, *cur;
44 
45     while ( ms!=NULL ) {
46 	cur = chunkalloc(sizeof(struct macsetting));
47 	cur->setting = ms->setting;
48 	cur->setname = MacNameCopy(ms->setname);
49 	cur->initially_enabled = ms->initially_enabled;
50 	if ( head==NULL )
51 	    head = cur;
52 	else
53 	    last->next = cur;
54 	last = cur;
55 	ms = ms->next;
56     }
57 return( head );
58 }
59 
MacFeatCopy(MacFeat * mf)60 static MacFeat *MacFeatCopy(MacFeat *mf) {
61     MacFeat *head=NULL, *last, *cur;
62 
63     while ( mf!=NULL ) {
64 	cur = chunkalloc(sizeof(MacFeat));
65 	cur->feature = mf->feature;
66 	cur->featname = MacNameCopy(mf->featname);
67 	cur->settings = MacSettingCopy(mf->settings);
68 	cur->ismutex = mf->ismutex;
69 	cur->default_setting = mf->default_setting;
70 	if ( head==NULL )
71 	    head = cur;
72 	else
73 	    last->next = cur;
74 	last = cur;
75 	mf = mf->next;
76     }
77 return( head );
78 }
79 
80 /* ************************************************************************** */
81 /* Sigh. This list is duplicated in macenc.c */
82 static GTextInfo maclanguages[] = {
83     { (unichar_t *) N_("English"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
84     { (unichar_t *) N_("French"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
85     { (unichar_t *) N_("German"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
86     { (unichar_t *) N_("Italian"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
87     { (unichar_t *) N_("Dutch"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
88     { (unichar_t *) N_("Swedish"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
89     { (unichar_t *) N_("Spanish"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
90     { (unichar_t *) N_("Danish"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
91     { (unichar_t *) N_("Portuguese"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
92     { (unichar_t *) N_("Norwegian"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
93     { (unichar_t *) N_("Lang|Hebrew"), NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
94     { (unichar_t *) N_("Japanese"), NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
95     { (unichar_t *) N_("Lang|Arabic"), NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
96     { (unichar_t *) N_("Finnish"), NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
97     { (unichar_t *) N_("Lang|Greek"), NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
98     { (unichar_t *) N_("Icelandic"), NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
99     { (unichar_t *) N_("Maltese"), NULL, 0, 0, (void *) 16, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
100     { (unichar_t *) N_("Turkish"), NULL, 0, 0, (void *) 17, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
101     { (unichar_t *) N_("Croatian"), NULL, 0, 0, (void *) 18, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
102     { (unichar_t *) N_("Traditional Chinese"), NULL, 0, 0, (void *) 19, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
103     { (unichar_t *) N_("Urdu"), NULL, 0, 0, (void *) 20, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
104     { (unichar_t *) N_("Hindi"), NULL, 0, 0, (void *) 21, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
105     { (unichar_t *) N_("Lang|Thai"), NULL, 0, 0, (void *) 22, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
106     { (unichar_t *) N_("Korean"), NULL, 0, 0, (void *) 23, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
107     { (unichar_t *) N_("Lithuanian"), NULL, 0, 0, (void *) 24, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
108     { (unichar_t *) N_("Polish"), NULL, 0, 0, (void *) 25, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
109     { (unichar_t *) N_("Hungarian"), NULL, 0, 0, (void *) 26, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
110     { (unichar_t *) N_("Estonian"), NULL, 0, 0, (void *) 27, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
111     { (unichar_t *) N_("Latvian"), NULL, 0, 0, (void *) 28, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
112     { (unichar_t *) N_("Sami (Lappish)"), NULL, 0, 0, (void *) 29, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
113     { (unichar_t *) N_("Faroese (Icelandic)"), NULL, 0, 0, (void *) 30, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
114 /* GT: See the long comment at "Property|New" */
115 /* GT: The msgstr should contain a translation of "Farsi/Persian", ignore "Lang|" */
116     { (unichar_t *) N_("Lang|Farsi/Persian"), NULL, 0, 0, (void *) 31, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
117     { (unichar_t *) N_("Russian"), NULL, 0, 0, (void *) 32, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
118     { (unichar_t *) N_("Simplified Chinese"), NULL, 0, 0, (void *) 33, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
119     { (unichar_t *) N_("Flemish"), NULL, 0, 0, (void *) 34, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
120     { (unichar_t *) N_("Irish Gaelic"), NULL, 0, 0, (void *) 35, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
121     { (unichar_t *) N_("Albanian"), NULL, 0, 0, (void *) 36, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
122     { (unichar_t *) N_("Romanian"), NULL, 0, 0, (void *) 37, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
123     { (unichar_t *) N_("Czech"), NULL, 0, 0, (void *) 38, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
124     { (unichar_t *) N_("Slovak"), NULL, 0, 0, (void *) 39, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
125     { (unichar_t *) N_("Slovenian"), NULL, 0, 0, (void *) 40, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
126     { (unichar_t *) N_("Yiddish"), NULL, 0, 0, (void *) 41, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
127     { (unichar_t *) N_("Serbian"), NULL, 0, 0, (void *) 42, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
128     { (unichar_t *) N_("Macedonian"), NULL, 0, 0, (void *) 43, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
129     { (unichar_t *) N_("Bulgarian"), NULL, 0, 0, (void *) 44, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
130     { (unichar_t *) N_("Ukrainian"), NULL, 0, 0, (void *) 45, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
131     { (unichar_t *) N_("Byelorussian"), NULL, 0, 0, (void *) 46, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
132     { (unichar_t *) N_("Uzbek"), NULL, 0, 0, (void *) 47, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
133     { (unichar_t *) N_("Kazakh"), NULL, 0, 0, (void *) 48, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
134     { (unichar_t *) N_("Axerbaijani (Cyrillic)"), NULL, 0, 0, (void *) 49, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
135     { (unichar_t *) N_("Axerbaijani (Arabic)"), NULL, 0, 0, (void *) 50, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
136     { (unichar_t *) N_("Lang|Armenian"), NULL, 0, 0, (void *) 51, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
137     { (unichar_t *) N_("Lang|Georgian"), NULL, 0, 0, (void *) 52, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
138     { (unichar_t *) N_("Moldavian"), NULL, 0, 0, (void *) 53, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
139     { (unichar_t *) N_("Kirghiz"), NULL, 0, 0, (void *) 54, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
140     { (unichar_t *) N_("Tajiki"), NULL, 0, 0, (void *) 55, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
141     { (unichar_t *) N_("Turkmen"), NULL, 0, 0, (void *) 56, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
142     { (unichar_t *) N_("Mongolian (Mongolian)"), NULL, 0, 0, (void *) 57, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
143     { (unichar_t *) N_("Mongolian (cyrillic)"), NULL, 0, 0, (void *) 58, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
144     { (unichar_t *) N_("Pashto"), NULL, 0, 0, (void *) 59, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
145     { (unichar_t *) N_("Kurdish"), NULL, 0, 0, (void *) 60, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
146     { (unichar_t *) N_("Kashmiri"), NULL, 0, 0, (void *) 61, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
147     { (unichar_t *) N_("Sindhi"), NULL, 0, 0, (void *) 62, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
148     { (unichar_t *) N_("Lang|Tibetan"), NULL, 0, 0, (void *) 63, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
149     { (unichar_t *) N_("Nepali"), NULL, 0, 0, (void *) 64, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
150     { (unichar_t *) N_("Sanskrit"), NULL, 0, 0, (void *) 65, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
151     { (unichar_t *) N_("Marathi"), NULL, 0, 0, (void *) 66, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
152     { (unichar_t *) N_("Lang|Bengali"), NULL, 0, 0, (void *) 67, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
153     { (unichar_t *) N_("Assamese"), NULL, 0, 0, (void *) 68, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
154     { (unichar_t *) N_("Lang|Gujarati"), NULL, 0, 0, (void *) 69, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
155     { (unichar_t *) N_("Punjabi"), NULL, 0, 0, (void *) 70, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
156     { (unichar_t *) N_("Lang|Oriya"), NULL, 0, 0, (void *) 71, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
157     { (unichar_t *) N_("Lang|Malayalam"), NULL, 0, 0, (void *) 72, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
158     { (unichar_t *) N_("Lang|Kannada"), NULL, 0, 0, (void *) 73, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
159     { (unichar_t *) N_("Lang|Tamil"), NULL, 0, 0, (void *) 74, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
160     { (unichar_t *) N_("Lang|Telugu"), NULL, 0, 0, (void *) 75, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
161     { (unichar_t *) N_("Lang|Sinhalese"), NULL, 0, 0, (void *) 76, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
162     { (unichar_t *) N_("Burmese"), NULL, 0, 0, (void *) 77, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
163     { (unichar_t *) N_("Lang|Khmer"), NULL, 0, 0, (void *) 78, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
164     { (unichar_t *) N_("Lang|Lao"), NULL, 0, 0, (void *) 79, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
165     { (unichar_t *) N_("Vietnamese"), NULL, 0, 0, (void *) 80, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
166     { (unichar_t *) N_("Indonesian"), NULL, 0, 0, (void *) 81, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
167     { (unichar_t *) N_("Lang|Tagalog"), NULL, 0, 0, (void *) 82, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
168     { (unichar_t *) N_("Malay (roman)"), NULL, 0, 0, (void *) 83, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
169     { (unichar_t *) N_("Malay (arabic)"), NULL, 0, 0, (void *) 84, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
170     { (unichar_t *) N_("Lang|Amharic"), NULL, 0, 0, (void *) 85, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
171     { (unichar_t *) N_("Tigrinya"), NULL, 0, 0, (void *) 86, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
172     { (unichar_t *) N_("Galla"), NULL, 0, 0, (void *) 87, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
173     { (unichar_t *) N_("Somali"), NULL, 0, 0, (void *) 88, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
174     { (unichar_t *) N_("Swahili"), NULL, 0, 0, (void *) 89, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
175     { (unichar_t *) N_("Kinyarwanda/Ruanda"), NULL, 0, 0, (void *) 90, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
176     { (unichar_t *) N_("Rundi"), NULL, 0, 0, (void *) 91, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
177     { (unichar_t *) N_("Nyanja/Chewa"), NULL, 0, 0, (void *) 92, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
178     { (unichar_t *) N_("Malagasy"), NULL, 0, 0, (void *) 93, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
179     { (unichar_t *) N_("Esperanto"), NULL, 0, 0, (void *) 94, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
180     { (unichar_t *) N_("Welsh"), NULL, 0, 0, (void *) 128, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
181     { (unichar_t *) N_("Basque"), NULL, 0, 0, (void *) 129, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
182     { (unichar_t *) N_("Catalan"), NULL, 0, 0, (void *) 130, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
183     { (unichar_t *) N_("Lang|Latin"), NULL, 0, 0, (void *) 131, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
184     { (unichar_t *) N_("Quechua"), NULL, 0, 0, (void *) 132, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
185     { (unichar_t *) N_("Guarani"), NULL, 0, 0, (void *) 133, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
186     { (unichar_t *) N_("Aymara"), NULL, 0, 0, (void *) 134, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
187     { (unichar_t *) N_("Tatar"), NULL, 0, 0, (void *) 135, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
188     { (unichar_t *) N_("Lang|Uighur"), NULL, 0, 0, (void *) 136, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
189     { (unichar_t *) N_("Dzongkha"), NULL, 0, 0, (void *) 137, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
190     { (unichar_t *) N_("Javanese (roman)"), NULL, 0, 0, (void *) 138, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
191     { (unichar_t *) N_("Sundanese (roman)"), NULL, 0, 0, (void *) 139, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
192     { (unichar_t *) N_("Galician"), NULL, 0, 0, (void *) 140, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
193     { (unichar_t *) N_("Afrikaans"), NULL, 0, 0, (void *) 141, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
194     { (unichar_t *) N_("Breton"), NULL, 0, 0, (void *) 142, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
195     { (unichar_t *) N_("Inuktitut"), NULL, 0, 0, (void *) 143, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
196     { (unichar_t *) N_("Scottish Gaelic"), NULL, 0, 0, (void *) 144, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
197     { (unichar_t *) N_("Manx Gaelic"), NULL, 0, 0, (void *) 145, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
198     { (unichar_t *) N_("Irish Gaelic (with dot)"), NULL, 0, 0, (void *) 146, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
199     { (unichar_t *) N_("Tongan"), NULL, 0, 0, (void *) 147, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
200     { (unichar_t *) N_("Greek (polytonic)"), NULL, 0, 0, (void *) 148, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
201     { (unichar_t *) N_("Greenlandic"), NULL, 0, 0, (void *) 149, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
202     { (unichar_t *) N_("Azebaijani (roman)"), NULL, 0, 0, (void *) 150, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
203     GTEXTINFO_EMPTY
204 };
205 
initmaclangs(void)206 static void initmaclangs(void) {
207     static int inited = false;
208     int i;
209 
210     if ( !inited ) {
211 	inited = true;
212 	for ( i=0; maclanguages[i].text!=NULL; ++i )
213 	    maclanguages[i].text = (unichar_t *) S_( (char *) maclanguages[i].text);
214     }
215 }
216 
217     /* These first three must match the values in prefs.c */
218 #define CID_Features	101
219 #define CID_FeatureDel	103
220 #define CID_FeatureEdit	105
221 
222 #define CID_Settings	101
223 #define CID_SettingDel	103
224 #define CID_SettingEdit	105
225 
226 #define CID_NameList	201
227 #define CID_NameNew	202
228 #define CID_NameDel	203
229 #define CID_NameEdit	205
230 
231 #define CID_Cancel	300
232 #define CID_OK		301
233 #define CID_Id		302
234 #define CID_Name	303
235 #define CID_Language	304
236 #define CID_On		305
237 #define CID_Mutex	306
238 
239 static char *spacer = " ⇒ ";	/* right double arrow */
240 
Pref_MacNamesList(struct macname * all)241 static GTextInfo *Pref_MacNamesList(struct macname *all) {
242     GTextInfo *ti;
243     int i, j;
244     struct macname *mn;
245     char *temp, *full;
246 
247     initmaclangs();
248 
249     for ( i=0, mn=all; mn!=NULL; mn=mn->next, ++i );
250     ti = calloc(i+1,sizeof( GTextInfo ));
251 
252     for ( i=0, mn=all; mn!=NULL; mn=mn->next, ++i ) {
253 	temp = MacStrToUtf8(mn->name,mn->enc,mn->lang);
254 	if ( temp==NULL )
255     continue;
256 	for ( j=0 ; maclanguages[j].text!=0; ++j )
257 	    if ( maclanguages[j].userdata == (void *) (intpt) (mn->lang ))
258 	break;
259 	if ( maclanguages[j].text!=0 ) {
260 	    char *lang = (char *) maclanguages[j].text;
261 	    full = malloc((strlen(lang)+strlen(temp)+strlen(spacer)+1));
262 	    strcpy(full,lang);
263 	} else {
264 	    char *hunh = "???";
265 	    full = malloc((strlen(hunh)+strlen(temp)+strlen(spacer)+1));
266 	    strcpy(full,hunh);
267 	}
268 	strcat(full,spacer);
269 	strcat(full,temp);
270 	free(temp);
271 	ti[i].text = (unichar_t *) full;
272 	ti[i].text_is_1byte = true;
273 	ti[i].userdata = (void *) mn;
274     }
275 return( ti );
276 }
277 
Pref_SettingsList(struct macsetting * all)278 static GTextInfo *Pref_SettingsList(struct macsetting *all) {
279     GTextInfo *ti;
280     int i;
281     struct macsetting *ms;
282     unichar_t *full; char *temp;
283     char buf[20];
284 
285     for ( i=0, ms=all; ms!=NULL; ms=ms->next, ++i );
286     ti = calloc(i+1,sizeof( GTextInfo ));
287 
288     for ( i=0, ms=all; ms!=NULL; ms=ms->next, ++i ) {
289 	temp = PickNameFromMacName(ms->setname);
290 	sprintf(buf,"%3d ", ms->setting);
291 	if ( temp==NULL )
292 	    full = uc_copy(buf);
293 	else {
294 	    full = malloc((strlen(buf)+strlen(temp)+1)*sizeof(unichar_t));
295 	    uc_strcpy(full,buf);
296 	    utf82u_strcpy(full+u_strlen(full),temp);
297 	    free(temp);
298 	}
299 	ti[i].text = full;
300 	ti[i].userdata = ms;
301     }
302 return( ti );
303 }
304 
Pref_FeaturesList(MacFeat * all)305 static GTextInfo *Pref_FeaturesList(MacFeat *all) {
306     GTextInfo *ti;
307     int i;
308     MacFeat *mf;
309     char *temp;
310     unichar_t *full;
311     char buf[20];
312 
313     for ( i=0, mf=all; mf!=NULL; mf=mf->next, ++i );
314     ti = calloc(i+1,sizeof( GTextInfo ));
315 
316     for ( i=0, mf=all; mf!=NULL; mf=mf->next, ++i ) {
317 	temp = PickNameFromMacName(mf->featname);
318 	sprintf(buf,"%3d ", mf->feature);
319 	if ( temp==NULL )
320 	    full = uc_copy(buf);
321 	else {
322 	    full = malloc((strlen(buf)+strlen(temp)+1)*sizeof(unichar_t));
323 	    uc_strcpy(full,buf);
324 	    utf82u_strcpy(full+u_strlen(full),temp);
325 	    free(temp);
326 	}
327 	ti[i].text = full;
328 	ti[i].userdata = mf;
329     }
330 return( ti );
331 }
332 
333 struct namedata {
334     GWindow gw;
335     int index;
336     int done;
337     struct macname *all, *changing;
338     GGadget *namelist;		/* Not in this dlg, in the dlg which created us */
339 };
340 
name_e_h(GWindow gw,GEvent * event)341 static int name_e_h(GWindow gw, GEvent *event) {
342     struct namedata *nd = GDrawGetUserData(gw);
343     int i;
344     int32 len;
345     GTextInfo **ti, *sel;
346     char *ret1, *temp; unichar_t *full;
347     int val1, val2;
348     struct macname *mn;
349     int language;
350 
351     if ( event->type==et_close ) {
352 	nd->done = true;
353 	if ( nd->index==-1 )
354 	    MacNameListFree(nd->changing);
355     } else if ( event->type==et_char ) {
356 	if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
357 	    help("ui/dialogs/prefs.html", "#prefs-features");
358 return( true );
359 	}
360 return( false );
361     } else if ( event->type==et_controlevent && event->u.control.subtype == et_buttonactivate ) {
362 	if ( GGadgetGetCid(event->u.control.g) == CID_Cancel ) {
363 	    nd->done = true;
364 	    if ( nd->index==-1 )
365 		MacNameListFree(nd->changing);
366 	} else if ( GGadgetGetCid(event->u.control.g) == CID_OK ) {
367 	    sel = GGadgetGetListItemSelected(GWidgetGetControl(nd->gw,CID_Language));
368 	    language = nd->changing->lang;
369 	    if ( sel!=NULL )
370 		language = (intpt) sel->userdata;
371 	    else if ( nd->index==-1 ) {
372 		ff_post_error(_("Bad Language"),_("Bad Language"));
373 return( true );
374 	    }	/* Otherwise use the original language, it might not be one we recognize */
375 	    if ( language != nd->changing->lang )
376 		nd->changing->enc = MacEncFromMacLang(language);
377 	    nd->changing->lang = language;
378 	    val1 = (nd->changing->enc<<16) | nd->changing->lang;
379 	    ret1 = GGadgetGetTitle8(GWidgetGetControl(nd->gw,CID_Name));
380 	    free(nd->changing->name);
381 	    nd->changing->name = Utf8ToMacStr(ret1,nd->changing->enc,nd->changing->lang);
382 	    free(ret1);
383 
384 	    ti = GGadgetGetList(nd->namelist,&len);
385 	    for ( i=0; i<len; ++i ) if ( i!=nd->index ) {
386 		val2 = (((struct macname *) (ti[i]->userdata))->enc<<16) |
387 			(((struct macname *) (ti[i]->userdata))->lang);
388 		if ( val2==val1 ) {
389 		    ff_post_error(_("This feature code is already used"),_("This feature code is already used"));
390 return( true );
391 		}
392 	    }
393 
394 	    temp = MacStrToUtf8(nd->changing->name,nd->changing->enc,nd->changing->lang);
395 	    if ( sel!=NULL ) {
396 		const unichar_t *lang = sel->text;
397 		full = malloc((u_strlen(lang)+strlen(temp)+6)*sizeof(unichar_t));
398 		u_strcpy(full,lang);
399 	    } else {
400 		char *hunh = "???";
401 		full = malloc((strlen(hunh)+strlen(temp)+6)*sizeof(unichar_t));
402 		uc_strcpy(full,hunh);
403 	    }
404 	    uc_strcat(full,spacer);
405 	    utf82u_strcpy(full+u_strlen(full),temp);
406 
407 	    if ( nd->index==-1 )
408 		GListAddStr(nd->namelist,full,nd->changing);
409 	    else {
410 		GListReplaceStr(nd->namelist,nd->index,full,nd->changing);
411 		if ( nd->all==nd->changing )
412 		    nd->all = nd->changing->next;
413 		else {
414 		    for ( mn=nd->all ; mn!=NULL && mn->next!=nd->changing; mn=mn->next );
415 		    if ( mn!=NULL ) mn->next = nd->changing->next;
416 		}
417 	    }
418 	    nd->changing->next = NULL;
419 	    if ( nd->all==NULL || val1< ((nd->all->enc<<16)|nd->all->lang) ) {
420 		nd->changing->next = nd->all;
421 		nd->all = nd->changing;
422 	    } else {
423 		for ( mn=nd->all; mn->next!=NULL && ((mn->next->enc<<16)|mn->next->lang)<val1; mn=mn->next );
424 		nd->changing->next = mn->next;
425 		mn->next = nd->changing;
426 	    }
427 	    GGadgetSetUserData(nd->namelist,nd->all);
428 	    nd->done = true;
429 	}
430     }
431 return( true );
432 }
433 
AskName(struct macname * changing,struct macname * all,GGadget * list,int index)434 static char *AskName(struct macname *changing,struct macname *all,GGadget *list, int index) {
435     GRect pos;
436     GWindow gw;
437     GWindowAttrs wattrs;
438     GGadgetCreateData gcd[8];
439     GTextInfo label[8];
440     struct namedata nd;
441     int i;
442 
443     initmaclangs();
444 
445     memset(&nd,0,sizeof(nd));
446     nd.namelist = list;
447     nd.index = index;
448     nd.changing = changing;
449     nd.all = all;
450 
451     memset(&wattrs,0,sizeof(wattrs));
452     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_restrict|wam_isdlg;
453     wattrs.event_masks = ~(1<<et_charup);
454     wattrs.restrict_input_to_me = 1;
455     wattrs.is_dlg = 1;
456     wattrs.undercursor = 1;
457     wattrs.cursor = ct_pointer;
458     wattrs.utf8_window_title = _("Setting");
459     pos.x = pos.y = 0;
460     pos.width = GGadgetScale(GDrawPointsToPixels(NULL,270));
461     pos.height = GDrawPointsToPixels(NULL,98);
462     gw = GDrawCreateTopWindow(NULL,&pos,name_e_h,&nd,&wattrs);
463     nd.gw = gw;
464 
465     memset(gcd,0,sizeof(gcd));
466     memset(label,0,sizeof(label));
467 
468     label[0].text = (unichar_t *) _("_Language:");
469     label[0].text_is_1byte = true;
470     label[0].text_in_resource = true;
471     gcd[0].gd.label = &label[0];
472     gcd[0].gd.pos.x = 5; gcd[0].gd.pos.y = 5+4;
473     gcd[0].gd.flags = gg_enabled|gg_visible;
474     gcd[0].creator = GLabelCreate;
475 
476     gcd[1].gd.pos.x = 60; gcd[1].gd.pos.y = 5;
477     gcd[1].gd.pos.width = 200;
478     gcd[1].gd.flags = gg_enabled|gg_visible | gg_list_alphabetic;
479     gcd[1].gd.u.list = maclanguages;
480     gcd[1].gd.cid = CID_Language;
481     gcd[1].creator = GListButtonCreate;
482 
483     for ( i=0; maclanguages[i].text!=NULL; ++i ) {
484 	if ( maclanguages[i].userdata == (void *) (intpt) (changing->lang) )
485 	    maclanguages[i].selected = true;
486 	else
487 	    maclanguages[i].selected = false;
488 	if ( changing->lang==65535 )
489 	    maclanguages[0].selected = true;
490     }
491 
492     label[2].text = (unichar_t *) _("_Name:");
493     label[2].text_is_1byte = true;
494     label[2].text_in_resource = true;
495     gcd[2].gd.label = &label[2];
496     gcd[2].gd.pos.x = 5; gcd[2].gd.pos.y = gcd[0].gd.pos.y+28;
497     gcd[2].gd.flags = gg_enabled|gg_visible;
498     gcd[2].creator = GLabelCreate;
499 
500     label[3].text = (unichar_t *) MacStrToUtf8(changing->name,changing->enc,changing->lang);
501     label[3].text_is_1byte = true;
502     gcd[3].gd.label = changing->name==NULL ? NULL : &label[3];
503     gcd[3].gd.pos.x = gcd[1].gd.pos.x; gcd[3].gd.pos.y = gcd[2].gd.pos.y-4;
504     gcd[3].gd.pos.width = 200;
505     gcd[3].gd.flags = gg_enabled|gg_visible;
506     gcd[3].gd.cid = CID_Name;
507     gcd[3].creator = GTextFieldCreate;
508 
509     i = 4;
510 
511     gcd[i].gd.pos.x = 13-3; gcd[i].gd.pos.y = gcd[i-1].gd.pos.y+30;
512     gcd[i].gd.pos.width = -1; gcd[i].gd.pos.height = 0;
513     gcd[i].gd.flags = gg_visible | gg_enabled | gg_but_default;
514     label[i].text = (unichar_t *) _("_OK");
515     label[i].text_is_1byte = true;
516     label[i].text_in_resource = true;
517     gcd[i].gd.label = &label[i];
518     gcd[i].gd.cid = CID_OK;
519     /*gcd[i].gd.handle_controlevent = Prefs_Ok;*/
520     gcd[i++].creator = GButtonCreate;
521 
522     gcd[i].gd.pos.x = -13; gcd[i].gd.pos.y = gcd[i-1].gd.pos.y+3;
523     gcd[i].gd.pos.width = -1; gcd[i].gd.pos.height = 0;
524     gcd[i].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
525     label[i].text = (unichar_t *) _("_Cancel");
526     label[i].text_is_1byte = true;
527     label[i].text_in_resource = true;
528     gcd[i].gd.label = &label[i];
529     gcd[i].gd.cid = CID_Cancel;
530     gcd[i].creator = GButtonCreate;
531 
532     GGadgetsCreate(gw,gcd);
533     GDrawSetVisible(gw,true);
534     GWidgetIndicateFocusGadget(gcd[1].ret);
535     while ( !nd.done )
536 	GDrawProcessOneEvent(NULL);
537     GDrawDestroyWindow(gw);
538 return( false );
539 }
540 
ChangeName(GGadget * list,int index)541 static void ChangeName(GGadget *list,int index) {
542     struct macname *mn = GGadgetGetListItemSelected(list)->userdata,
543 		    *all = GGadgetGetUserData(list);
544 
545     AskName(mn,all,list,index);
546 }
547 
Pref_NewName(GGadget * g,GEvent * e)548 static int Pref_NewName(GGadget *g, GEvent *e) {
549     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
550 	GWindow gw = GGadgetGetWindow(g);
551 	GGadget *list = GWidgetGetControl(gw,CID_NameList);
552 	struct macname *new, *all;
553 
554 	all = GGadgetGetUserData(list);
555 	new = chunkalloc(sizeof(struct macname));
556 	new->lang = -1;
557 	AskName(new,all,list,-1);
558     }
559 return( true );
560 }
561 
Pref_DelName(GGadget * g,GEvent * e)562 static int Pref_DelName(GGadget *g, GEvent *e) {
563     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
564 	struct macname *mn, *p, *all, *next;
565 	GWindow gw = GGadgetGetWindow(g);
566 	GGadget *list = GWidgetGetControl(gw,CID_NameList);
567 	int32 len;
568 	GTextInfo **ti = GGadgetGetList(list,&len);
569 	int i;
570 
571 	all = GGadgetGetUserData(list);
572 	for ( mn = all, p=NULL; mn!=NULL; mn = next ) {
573 	    next = mn->next;
574 	    for ( i=len-1; i>=0; --i ) {
575 		if ( ti[i]->selected && ti[i]->userdata==mn )
576 	    break;
577 	    }
578 	    if ( i>=0 ) {
579 		if ( p==NULL )
580 		    all = next;
581 		else
582 		    p->next = next;
583 		mn->next = NULL;
584 		MacNameListFree(mn);
585 	    } else
586 		p = mn;
587 	}
588 	GGadgetSetUserData(list,all);
589 	GListDelSelected(list);
590 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_NameDel),false);
591 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_NameEdit),false);
592     }
593 return( true );
594 }
595 
Pref_EditName(GGadget * g,GEvent * e)596 static int Pref_EditName(GGadget *g, GEvent *e) {
597     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
598 	GGadget *list = GWidgetGetControl(GGadgetGetWindow(g),CID_NameList);
599 	ChangeName(list,GGadgetGetFirstListSelectedItem(list));
600     }
601 return( true );
602 }
603 
Pref_NameSel(GGadget * g,GEvent * e)604 static int Pref_NameSel(GGadget *g, GEvent *e) {
605     if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
606 	int32 len;
607 	GTextInfo **ti = GGadgetGetList(g,&len);
608 	GWindow gw = GGadgetGetWindow(g);
609 	int i, sel_cnt=0;
610 	for ( i=0; i<len; ++i )
611 	    if ( ti[i]->selected ) ++sel_cnt;
612 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_NameDel),sel_cnt!=0);
613 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_NameEdit),sel_cnt==1);
614     } else if ( e->type==et_controlevent && e->u.control.subtype == et_listdoubleclick ) {
615 	ChangeName(g,e->u.control.u.list.changed_index!=-1?e->u.control.u.list.changed_index:
616 		GGadgetGetFirstListSelectedItem(g));
617     }
618 return( true );
619 }
620 
NameGadgetsGetNames(GWindow gw)621 struct macname *NameGadgetsGetNames( GWindow gw ) {
622 return( GGadgetGetUserData(GWidgetGetControl(gw,CID_NameList)) );
623 }
624 
NameGadgetsSetEnabled(GWindow gw,int enable)625 void NameGadgetsSetEnabled( GWindow gw, int enable ) {
626 
627     GGadgetSetEnabled(GWidgetGetControl(gw,CID_NameList),enable);
628     GGadgetSetEnabled(GWidgetGetControl(gw,CID_NameNew),enable);
629     if ( !enable ) {
630 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_NameDel),false);
631 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_NameEdit),false);
632     } else {
633 	int32 len;
634 	GGadget *list = GWidgetGetControl(gw,CID_NameList);
635 	GTextInfo **ti = GGadgetGetList(list,&len);
636 	int i, sel_cnt=0;
637 	for ( i=0; i<len; ++i )
638 	    if ( ti[i]->selected ) ++sel_cnt;
639 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_NameDel),sel_cnt>0);
640 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_NameEdit),sel_cnt=1);
641     }
642 }
643 
GCDBuildNames(GGadgetCreateData * gcd,GTextInfo * label,int pos,struct macname * names)644 int GCDBuildNames(GGadgetCreateData *gcd,GTextInfo *label,int pos,struct macname *names) {
645 
646     gcd[pos].gd.pos.x = 6; gcd[pos].gd.pos.y = pos==0 ? 6 :
647 	    gcd[pos-1].creator==GTextFieldCreate ? gcd[pos-1].gd.pos.y+30 :
648 						    gcd[pos-1].gd.pos.y+14;
649     gcd[pos].gd.pos.width = 250; gcd[pos].gd.pos.height = 5*12+10;
650     gcd[pos].gd.flags = gg_visible | gg_enabled | gg_list_alphabetic | gg_list_multiplesel;
651     gcd[pos].gd.cid = CID_NameList;
652     gcd[pos].data = names = MacNameCopy(names);
653     gcd[pos].gd.u.list = Pref_MacNamesList(names);
654     gcd[pos].gd.handle_controlevent = Pref_NameSel;
655     gcd[pos++].creator = GListCreate;
656 
657     gcd[pos].gd.pos.x = 6; gcd[pos].gd.pos.y = gcd[pos-1].gd.pos.y+gcd[pos-1].gd.pos.height+10;
658     gcd[pos].gd.flags = gg_visible | gg_enabled;
659     label[pos].text = (unichar_t *) S_("MacName|_New...");
660     label[pos].text_is_1byte = true;
661     label[pos].text_in_resource = true;
662     gcd[pos].gd.label = &label[pos];
663     gcd[pos].gd.handle_controlevent = Pref_NewName;
664     gcd[pos].gd.cid = CID_NameNew;
665     gcd[pos++].creator = GButtonCreate;
666 
667     gcd[pos].gd.pos.x = gcd[pos-1].gd.pos.x+20+GIntGetResource(_NUM_Buttonsize)*100/GIntGetResource(_NUM_ScaleFactor);
668     gcd[pos].gd.pos.y = gcd[pos-1].gd.pos.y;
669     gcd[pos].gd.flags = gg_visible ;
670     label[pos].text = (unichar_t *) _("_Delete");
671     label[pos].text_is_1byte = true;
672     label[pos].text_in_resource = true;
673     gcd[pos].gd.label = &label[pos];
674     gcd[pos].gd.cid = CID_NameDel;
675     gcd[pos].gd.handle_controlevent = Pref_DelName;
676     gcd[pos++].creator = GButtonCreate;
677 
678     gcd[pos].gd.pos.x = gcd[pos-1].gd.pos.x+20+GIntGetResource(_NUM_Buttonsize)*100/GIntGetResource(_NUM_ScaleFactor);
679     gcd[pos].gd.pos.y = gcd[pos-1].gd.pos.y;
680     gcd[pos].gd.flags = gg_visible ;
681     label[pos].text = (unichar_t *) _("_Edit...");
682     label[pos].text_is_1byte = true;
683     label[pos].text_in_resource = true;
684     gcd[pos].gd.label = &label[pos];
685     gcd[pos].gd.cid = CID_NameEdit;
686     gcd[pos].gd.handle_controlevent = Pref_EditName;
687     gcd[pos++].creator = GButtonCreate;
688 
689 return( pos );
690 }
691 
692 struct setdata {
693     GWindow gw;
694     int index;
695     int done;
696     struct macsetting *all, *changing;
697     GGadget *settinglist;		/* Not in this dlg, in the dlg which created us */
698 };
699 
set_e_h(GWindow gw,GEvent * event)700 static int set_e_h(GWindow gw, GEvent *event) {
701     struct setdata *sd = GDrawGetUserData(gw);
702     int i;
703     int32 len;
704     GTextInfo **ti;
705     const unichar_t *ret1; unichar_t *end, *res; char *temp;
706     int val1, val2;
707     char buf[20];
708     struct macsetting *ms;
709 
710     if ( event->type==et_close ) {
711 	sd->done = true;
712 	MacNameListFree(GGadgetGetUserData(GWidgetGetControl(sd->gw,CID_NameList)));
713 	if ( sd->index==-1 )
714 	    MacSettingListFree(sd->changing);
715     } else if ( event->type==et_char ) {
716 	if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
717 	    help("ui/dialogs/prefs.html", "#prefs-settings");
718 return( true );
719 	}
720 return( false );
721     } else if ( event->type==et_controlevent && event->u.control.subtype == et_buttonactivate ) {
722 	if ( GGadgetGetCid(event->u.control.g) == CID_Cancel ) {
723 	    sd->done = true;
724 	    MacNameListFree(GGadgetGetUserData(GWidgetGetControl(sd->gw,CID_NameList)));
725 	    if ( sd->index==-1 )
726 		MacSettingListFree(sd->changing);
727 	} else if ( GGadgetGetCid(event->u.control.g) == CID_OK ) {
728 	    ret1 = _GGadgetGetTitle(GWidgetGetControl(sd->gw,CID_Id));
729 	    val1 = u_strtol(ret1,&end,10);
730 	    if ( *end!='\0' ) {
731 		ff_post_error(_("Bad Number"),_("Bad Number"));
732 return( true );
733 	    }
734 	    ti = GGadgetGetList(sd->settinglist,&len);
735 	    for ( i=0; i<len; ++i ) if ( i!=sd->index ) {
736 		val2 = ((struct macsetting *) (ti[i]->userdata))->setting;
737 		if ( val2==val1 ) {
738 		    ff_post_error(_("This setting is already used"),_("This setting is already used"));
739 return( true );
740 		}
741 	    }
742 	    MacNameListFree(sd->changing->setname);
743 	    sd->changing->setname = GGadgetGetUserData(GWidgetGetControl(sd->gw,CID_NameList));
744 	    sd->changing->setting = val1;
745 	    sd->changing->initially_enabled = GGadgetIsChecked(GWidgetGetControl(sd->gw,CID_On));
746 	    if ( sd->changing->initially_enabled &&
747 		    GGadgetIsChecked(GWidgetGetControl(GGadgetGetWindow(sd->settinglist),CID_Mutex)) ) {
748 		/* If the mutually exclusive bit were set in the feature then */
749 		/*  turning this guy on, means we must turn others off */
750 		struct macsetting *test;
751 		for ( test = sd->all; test!=NULL; test = test->next )
752 		    if ( test!=sd->changing )
753 			test->initially_enabled = false;
754 	    }
755 
756 	    sprintf(buf,"%3d ", val1);
757 	    temp = PickNameFromMacName(sd->changing->setname);
758 	    len = strlen(temp);
759 	    res = malloc( (strlen(buf)+len+3)*sizeof(unichar_t) );
760 	    uc_strcpy(res,buf);
761 	    utf82u_strcpy(res+u_strlen(res),temp);
762 	    free(temp);
763 
764 	    if ( sd->index==-1 )
765 		GListAddStr(sd->settinglist,res,sd->changing);
766 	    else {
767 		GListReplaceStr(sd->settinglist,sd->index,res,sd->changing);
768 		if ( sd->all==sd->changing )
769 		    sd->all = sd->changing->next;
770 		else {
771 		    for ( ms=sd->all ; ms!=NULL && ms->next!=sd->changing; ms=ms->next );
772 		    if ( ms!=NULL ) ms->next = sd->changing->next;
773 		}
774 	    }
775 	    sd->changing->next = NULL;
776 	    if ( sd->all==NULL || sd->changing->setting<sd->all->setting ) {
777 		sd->changing->next = sd->all;
778 		sd->all = sd->changing;
779 	    } else {
780 		for ( ms=sd->all; ms->next!=NULL && ms->next->setting<sd->changing->setting; ms=ms->next );
781 		sd->changing->next = ms->next;
782 		ms->next = sd->changing;
783 	    }
784 	    GGadgetSetUserData(sd->settinglist,sd->all);
785 	    sd->done = true;
786 	}
787     }
788 return( true );
789 }
790 
AskSetting(struct macsetting * changing,struct macsetting * all,GGadget * list,int index)791 static char *AskSetting(struct macsetting *changing,struct macsetting *all,
792 	GGadget *list, int index) {
793     GRect pos;
794     GWindow gw;
795     GWindowAttrs wattrs;
796     GGadgetCreateData gcd[12];
797     GTextInfo label[12];
798     struct setdata sd;
799     char buf[20];
800     int i;
801 
802     memset(&sd,0,sizeof(sd));
803     sd.settinglist = list;
804     sd.index = index;
805     sd.changing = changing;
806     sd.all = all;
807 
808     memset(&wattrs,0,sizeof(wattrs));
809     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_restrict|wam_isdlg;
810     wattrs.event_masks = ~(1<<et_charup);
811     wattrs.restrict_input_to_me = 1;
812     wattrs.is_dlg = 1;
813     wattrs.undercursor = 1;
814     wattrs.cursor = ct_pointer;
815     wattrs.utf8_window_title = _("Setting");
816     pos.x = pos.y = 0;
817     pos.width = GGadgetScale(GDrawPointsToPixels(NULL,270));
818     pos.height = GDrawPointsToPixels(NULL,193);
819     gw = GDrawCreateTopWindow(NULL,&pos,set_e_h,&sd,&wattrs);
820     sd.gw = gw;
821 
822     memset(gcd,0,sizeof(gcd));
823     memset(label,0,sizeof(label));
824 
825     label[0].text = (unichar_t *) _("Setting Id:");
826     label[0].text_is_1byte = true;
827     gcd[0].gd.label = &label[0];
828     gcd[0].gd.pos.x = 5; gcd[0].gd.pos.y = 5+4;
829     gcd[0].gd.flags = gg_enabled|gg_visible;
830     gcd[0].creator = GLabelCreate;
831 
832     sprintf( buf, "%d", changing->setting );
833     label[1].text = (unichar_t *) buf;
834     label[1].text_is_1byte = true;
835     gcd[1].gd.label = &label[1];
836     gcd[1].gd.pos.x = 60; gcd[1].gd.pos.y = 5; gcd[1].gd.pos.width = 40;
837     gcd[1].gd.flags = gg_enabled|gg_visible;
838     gcd[1].gd.cid = CID_Id;
839     gcd[1].creator = GTextFieldCreate;
840 
841     label[2].text = (unichar_t *) _("_Enabled");
842     label[2].text_is_1byte = true;
843     label[2].text_in_resource = true;
844     gcd[2].gd.label = &label[2];
845     gcd[2].gd.pos.x = 110; gcd[2].gd.pos.y = 5;
846     gcd[2].gd.flags = gg_enabled|gg_visible | (changing->initially_enabled?gg_cb_on:0);
847     gcd[2].gd.cid = CID_On;
848     gcd[2].creator = GCheckBoxCreate;
849 
850     label[3].text = (unichar_t *) _("_Name:");
851     label[3].text_is_1byte = true;
852     label[3].text_in_resource = true;
853     gcd[3].gd.label = &label[3];
854     gcd[3].gd.pos.x = 5; gcd[3].gd.pos.y = 5+24;
855     gcd[3].gd.flags = gg_enabled|gg_visible;
856     gcd[3].creator = GLabelCreate;
857 
858 
859     i = GCDBuildNames(gcd,label,4,changing->setname);
860 
861     gcd[i].gd.pos.x = 13-3; gcd[i].gd.pos.y = gcd[i-1].gd.pos.y+35;
862     gcd[i].gd.pos.width = -1; gcd[i].gd.pos.height = 0;
863     gcd[i].gd.flags = gg_visible | gg_enabled | gg_but_default;
864     label[i].text = (unichar_t *) _("_OK");
865     label[i].text_is_1byte = true;
866     label[i].text_in_resource = true;
867     gcd[i].gd.label = &label[i];
868     gcd[i].gd.cid = CID_OK;
869     /*gcd[i].gd.handle_controlevent = Prefs_Ok;*/
870     gcd[i++].creator = GButtonCreate;
871 
872     gcd[i].gd.pos.x = -13; gcd[i].gd.pos.y = gcd[i-1].gd.pos.y+3;
873     gcd[i].gd.pos.width = -1; gcd[i].gd.pos.height = 0;
874     gcd[i].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
875     label[i].text = (unichar_t *) _("_Cancel");
876     label[i].text_is_1byte = true;
877     label[i].text_in_resource = true;
878     gcd[i].gd.label = &label[i];
879     gcd[i].gd.cid = CID_Cancel;
880     gcd[i].creator = GButtonCreate;
881 
882     GGadgetsCreate(gw,gcd);
883     GTextInfoListFree(gcd[4].gd.u.list);
884 
885     GDrawSetVisible(gw,true);
886     GWidgetIndicateFocusGadget(gcd[1].ret);
887     while ( !sd.done )
888 	GDrawProcessOneEvent(NULL);
889     GDrawDestroyWindow(gw);
890 
891 return( false );
892 }
893 
ChangeSetting(GGadget * list,int index)894 static void ChangeSetting(GGadget *list,int index) {
895     struct macsetting *ms = GGadgetGetListItemSelected(list)->userdata,
896 		    *all = GGadgetGetUserData(list);
897 
898     AskSetting(ms,all,list,index);
899 }
900 
Pref_NewSetting(GGadget * g,GEvent * e)901 static int Pref_NewSetting(GGadget *g, GEvent *e) {
902     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
903 	GWindow gw = GGadgetGetWindow(g);
904 	GGadget *list = GWidgetGetControl(gw,CID_Settings);
905 	struct macsetting *new, *ms, *all;
906 	int expected=0;
907 
908 	all = GGadgetGetUserData(list);
909 	if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_Mutex)) ) {
910 	    for ( ms=all; ms!=NULL; ms=ms->next ) {
911 		if ( ms->setting!=expected )
912 	    break;
913 		++expected;
914 	    }
915 	} else {
916 	    for ( ms=all; ms!=NULL; ms=ms->next ) {
917 		if ( ms->setting&1 )	/* Shouldn't be any odd settings for non-mutex */
918 	    continue;
919 		if ( ms->setting!=expected )
920 	    break;
921 		expected += 2;
922 	    }
923 	}
924 	new = chunkalloc(sizeof(struct macsetting));
925 	new->setting = expected;
926 	AskSetting(new,all,list,-1);
927     }
928 return( true );
929 }
930 
Pref_DelSetting(GGadget * g,GEvent * e)931 static int Pref_DelSetting(GGadget *g, GEvent *e) {
932     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
933 	struct macsetting *ms, *p, *all, *next;
934 	GWindow gw = GGadgetGetWindow(g);
935 	GGadget *list = GWidgetGetControl(gw,CID_Settings);
936 	int32 len;
937 	GTextInfo **ti = GGadgetGetList(list,&len);
938 	int i;
939 
940 	all = GGadgetGetUserData(list);
941 	for ( ms = all, p=NULL; ms!=NULL; ms = next ) {
942 	    next = ms->next;
943 	    for ( i=len-1; i>=0; --i ) {
944 		if ( ti[i]->selected && ti[i]->userdata==ms )
945 	    break;
946 	    }
947 	    if ( i>=0 ) {
948 		if ( p==NULL )
949 		    all = next;
950 		else
951 		    p->next = next;
952 		ms->next = NULL;
953 		MacSettingListFree(ms);
954 	    } else
955 		p = ms;
956 	}
957 	GGadgetSetUserData(list,all);
958 	GListDelSelected(list);
959 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_SettingDel),false);
960 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_SettingEdit),false);
961     }
962 return( true );
963 }
964 
Pref_EditSetting(GGadget * g,GEvent * e)965 static int Pref_EditSetting(GGadget *g, GEvent *e) {
966     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
967 	GGadget *list = GWidgetGetControl(GGadgetGetWindow(g),CID_Settings);
968 	ChangeSetting(list,GGadgetGetFirstListSelectedItem(list));
969     }
970 return( true );
971 }
972 
Pref_SettingSel(GGadget * g,GEvent * e)973 static int Pref_SettingSel(GGadget *g, GEvent *e) {
974     if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
975 	int32 len;
976 	GTextInfo **ti = GGadgetGetList(g,&len);
977 	GWindow gw = GGadgetGetWindow(g);
978 	int i, sel_cnt=0;
979 	for ( i=0; i<len; ++i )
980 	    if ( ti[i]->selected ) ++sel_cnt;
981 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_SettingDel),sel_cnt!=0);
982 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_SettingEdit),sel_cnt==1);
983     } else if ( e->type==et_controlevent && e->u.control.subtype == et_listdoubleclick ) {
984 	ChangeSetting(g,e->u.control.u.list.changed_index!=-1?e->u.control.u.list.changed_index:
985 		GGadgetGetFirstListSelectedItem(g));
986     }
987 return( true );
988 }
989 
990 struct featdata {
991     GWindow gw;
992     int index;
993     int done;
994     MacFeat *all, *changing;
995     GGadget *featurelist;		/* Not in this dlg, in the dlg which created us */
996 };
997 
feat_e_h(GWindow gw,GEvent * event)998 static int feat_e_h(GWindow gw, GEvent *event) {
999     struct featdata *fd = GDrawGetUserData(gw);
1000     int i;
1001     int32 len;
1002     GTextInfo **ti;
1003     const unichar_t *ret1; unichar_t *end, *res; char *temp;
1004     int val1, val2;
1005     char buf[20];
1006     MacFeat *mf;
1007 
1008     if ( event->type==et_close ) {
1009 	fd->done = true;
1010 	if ( fd->index==-1 )
1011 	    MacFeatListFree(fd->changing);
1012 	MacSettingListFree(GGadgetGetUserData(GWidgetGetControl(fd->gw,CID_Settings)));
1013 	MacNameListFree(GGadgetGetUserData(GWidgetGetControl(fd->gw,CID_NameList)));
1014     } else if ( event->type==et_char ) {
1015 	if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
1016 	    help("ui/dialogs/prefs.html", "#prefs-features");
1017 return( true );
1018 	}
1019 return( false );
1020     } else if ( event->type==et_controlevent && event->u.control.subtype == et_buttonactivate ) {
1021 	if ( GGadgetGetCid(event->u.control.g) == CID_Cancel ) {
1022 	    fd->done = true;
1023 	    if ( fd->index==-1 )
1024 		MacFeatListFree(fd->changing);
1025 	    MacSettingListFree(GGadgetGetUserData(GWidgetGetControl(fd->gw,CID_Settings)));
1026 	    MacNameListFree(GGadgetGetUserData(GWidgetGetControl(fd->gw,CID_NameList)));
1027 	} else if ( GGadgetGetCid(event->u.control.g) == CID_OK ) {
1028 	    ret1 = _GGadgetGetTitle(GWidgetGetControl(fd->gw,CID_Id));
1029 	    val1 = u_strtol(ret1,&end,10);
1030 	    if ( *end!='\0' ) {
1031 		ff_post_error(_("Bad Number"),_("Bad Number"));
1032 return( true );
1033 	    }
1034 	    ti = GGadgetGetList(fd->featurelist,&len);
1035 	    for ( i=0; i<len; ++i ) if ( i!=fd->index ) {
1036 		val2 = ((MacFeat *) (ti[i]->userdata))->feature;
1037 		if ( val2==val1 ) {
1038 		    ff_post_error(_("This feature code is already used"),_("This feature code is already used"));
1039 return( true );
1040 		}
1041 	    }
1042 	    MacSettingListFree(fd->changing->settings);
1043 	    MacNameListFree(fd->changing->featname);
1044 	    fd->changing->featname = GGadgetGetUserData(GWidgetGetControl(fd->gw,CID_NameList));
1045 	    fd->changing->settings = GGadgetGetUserData(GWidgetGetControl(fd->gw,CID_Settings));
1046 	    fd->changing->ismutex = GGadgetIsChecked(GWidgetGetControl(fd->gw,CID_Mutex));
1047 	    if ( fd->changing->ismutex ) {
1048 		struct macsetting *ms;
1049 		for ( i=0, ms = fd->changing->settings; ms!=NULL && !ms->initially_enabled; ms = ms->next, ++i );
1050 		if ( ms==NULL ) i = 0;
1051 		fd->changing->default_setting = i;
1052 		if ( ms!=NULL ) {
1053 		    for ( ms=ms->next ; ms!=NULL; ms = ms->next )
1054 			ms->initially_enabled = false;
1055 		}
1056 	    }
1057 
1058 	    sprintf(buf,"%3d ", val1);
1059 	    temp = PickNameFromMacName(fd->changing->featname);
1060 	    len = strlen(temp);
1061 	    res = malloc( (strlen(buf)+len+3)*sizeof(unichar_t) );
1062 	    uc_strcpy(res,buf);
1063 	    utf82u_strcpy(res+u_strlen(res),temp);
1064 	    free(temp);
1065 
1066 	    if ( fd->index==-1 )
1067 		GListAddStr(fd->featurelist,res,fd->changing);
1068 	    else {
1069 		GListReplaceStr(fd->featurelist,fd->index,res,fd->changing);
1070 		if ( fd->all==fd->changing )
1071 		    fd->all = fd->changing->next;
1072 		else {
1073 		    for ( mf=fd->all ; mf!=NULL && mf->next!=fd->changing; mf=mf->next );
1074 		    if ( mf!=NULL ) mf->next = fd->changing->next;
1075 		}
1076 	    }
1077 	    fd->changing->next = NULL;
1078 	    if ( fd->all==NULL || fd->changing->feature<fd->all->feature ) {
1079 		fd->changing->next = fd->all;
1080 		fd->all = fd->changing;
1081 	    } else {
1082 		for ( mf=fd->all; mf->next!=NULL && mf->next->feature<fd->changing->feature; mf=mf->next );
1083 		fd->changing->next = mf->next;
1084 		mf->next = fd->changing;
1085 	    }
1086 	    GGadgetSetUserData(fd->featurelist,fd->all);
1087 	    fd->done = true;
1088 	}
1089     }
1090 return( true );
1091 }
1092 
AskFeature(MacFeat * changing,MacFeat * all,GGadget * list,int index)1093 static char *AskFeature(MacFeat *changing,MacFeat *all,GGadget *list, int index) {
1094     GRect pos;
1095     GWindow gw;
1096     GWindowAttrs wattrs;
1097     GGadgetCreateData gcd[16];
1098     GTextInfo label[16], *freeme;
1099     struct featdata fd;
1100     char buf[20];
1101     int i;
1102 
1103     memset(&fd,0,sizeof(fd));
1104     fd.featurelist = list;
1105     fd.index = index;
1106     fd.changing = changing;
1107     fd.all = all;
1108 
1109     memset(&wattrs,0,sizeof(wattrs));
1110     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_restrict|wam_isdlg;
1111     wattrs.event_masks = ~(1<<et_charup);
1112     wattrs.restrict_input_to_me = 1;
1113     wattrs.is_dlg = 1;
1114     wattrs.undercursor = 1;
1115     wattrs.cursor = ct_pointer;
1116     wattrs.utf8_window_title = _("Feature");
1117     pos.x = pos.y = 0;
1118     pos.width = GGadgetScale(GDrawPointsToPixels(NULL,265));
1119     pos.height = GDrawPointsToPixels(NULL,353);
1120     gw = GDrawCreateTopWindow(NULL,&pos,feat_e_h,&fd,&wattrs);
1121     fd.gw = gw;
1122 
1123     memset(gcd,0,sizeof(gcd));
1124     memset(label,0,sizeof(label));
1125 
1126     label[0].text = (unichar_t *) _("Feature _Id:");
1127     label[0].text_is_1byte = true;
1128     gcd[0].gd.label = &label[0];
1129     gcd[0].gd.pos.x = 5; gcd[0].gd.pos.y = 5+4;
1130     gcd[0].gd.flags = gg_enabled|gg_visible;
1131     gcd[0].creator = GLabelCreate;
1132 
1133     sprintf( buf, "%d", changing->feature );
1134     label[1].text = (unichar_t *) buf;
1135     label[1].text_is_1byte = true;
1136     gcd[1].gd.label = &label[1];
1137     gcd[1].gd.pos.x = 60; gcd[1].gd.pos.y = 5; gcd[1].gd.pos.width = 40;
1138     gcd[1].gd.flags = gg_enabled|gg_visible;
1139     gcd[1].gd.cid = CID_Id;
1140     gcd[1].creator = GTextFieldCreate;
1141 
1142     label[2].text = (unichar_t *) _("Mutually Exclusive");
1143     label[2].text_is_1byte = true;
1144     gcd[2].gd.label = &label[2];
1145     gcd[2].gd.pos.x = 105; gcd[2].gd.pos.y = 5+4;
1146     gcd[2].gd.flags = gg_enabled|gg_visible | (changing->ismutex?gg_cb_on:0);
1147     gcd[2].gd.cid = CID_Mutex;
1148     gcd[2].creator = GCheckBoxCreate;
1149 
1150     label[3].text = (unichar_t *) _("_Name:");
1151     label[3].text_is_1byte = true;
1152     label[3].text_in_resource = true;
1153     gcd[3].gd.label = &label[3];
1154     gcd[3].gd.pos.x = 5; gcd[3].gd.pos.y = 5+24;
1155     gcd[3].gd.flags = gg_enabled|gg_visible;
1156     gcd[3].creator = GLabelCreate;
1157 
1158     i = GCDBuildNames(gcd,label,4,changing->featname);
1159 
1160     label[i].text = (unichar_t *) _("Settings");
1161     label[i].text_is_1byte = true;
1162     gcd[i].gd.label = &label[i];
1163     gcd[i].gd.pos.x = 5; gcd[i].gd.pos.y = gcd[i-1].gd.pos.y+35;
1164     gcd[i].gd.flags = gg_enabled|gg_visible;
1165     gcd[i++].creator = GLabelCreate;
1166 
1167     gcd[i].gd.pos.x = 6; gcd[i].gd.pos.y = gcd[i-1].gd.pos.y+14;
1168     gcd[i].gd.pos.width = 250; gcd[i].gd.pos.height = 8*12+10;
1169     gcd[i].gd.flags = gg_visible | gg_enabled | gg_list_alphabetic | gg_list_multiplesel;
1170     gcd[i].gd.cid = CID_Settings;
1171     gcd[i].data = MacSettingCopy(changing->settings);
1172     gcd[i].gd.u.list = freeme = Pref_SettingsList(gcd[i].data);
1173     gcd[i].gd.handle_controlevent = Pref_SettingSel;
1174     gcd[i++].creator = GListCreate;
1175 
1176     gcd[i].gd.pos.x = 6; gcd[i].gd.pos.y = gcd[i-1].gd.pos.y+gcd[i-1].gd.pos.height+10;
1177     gcd[i].gd.flags = gg_visible | gg_enabled;
1178     label[i].text = (unichar_t *) S_("MacSetting|_New...");
1179     label[i].text_is_1byte = true;
1180     label[i].text_in_resource = true;
1181     gcd[i].gd.label = &label[i];
1182     gcd[i].gd.handle_controlevent = Pref_NewSetting;
1183     gcd[i++].creator = GButtonCreate;
1184 
1185     gcd[i].gd.pos.x = gcd[i-1].gd.pos.x+20+GIntGetResource(_NUM_Buttonsize)*100/GIntGetResource(_NUM_ScaleFactor);
1186     gcd[i].gd.pos.y = gcd[i-1].gd.pos.y;
1187     gcd[i].gd.flags = gg_visible ;
1188     label[i].text = (unichar_t *) _("_Delete");
1189     label[i].text_is_1byte = true;
1190     label[i].text_in_resource = true;
1191     gcd[i].gd.label = &label[i];
1192     gcd[i].gd.cid = CID_SettingDel;
1193     gcd[i].gd.handle_controlevent = Pref_DelSetting;
1194     gcd[i++].creator = GButtonCreate;
1195 
1196     gcd[i].gd.pos.x = gcd[i-1].gd.pos.x+20+GIntGetResource(_NUM_Buttonsize)*100/GIntGetResource(_NUM_ScaleFactor);
1197     gcd[i].gd.pos.y = gcd[i-1].gd.pos.y;
1198     gcd[i].gd.flags = gg_visible ;
1199     label[i].text = (unichar_t *) _("_Edit...");
1200     label[i].text_is_1byte = true;
1201     label[i].text_in_resource = true;
1202     gcd[i].gd.label = &label[i];
1203     gcd[i].gd.cid = CID_SettingEdit;
1204     gcd[i].gd.handle_controlevent = Pref_EditSetting;
1205     gcd[i++].creator = GButtonCreate;
1206 
1207     gcd[i].gd.pos.x = 13-3; gcd[i].gd.pos.y = gcd[i-1].gd.pos.y+30;
1208     gcd[i].gd.pos.width = -1; gcd[i].gd.pos.height = 0;
1209     gcd[i].gd.flags = gg_visible | gg_enabled | gg_but_default;
1210     label[i].text = (unichar_t *) _("_OK");
1211     label[i].text_is_1byte = true;
1212     label[i].text_in_resource = true;
1213     gcd[i].gd.label = &label[i];
1214     gcd[i].gd.cid = CID_OK;
1215     /*gcd[i].gd.handle_controlevent = Prefs_Ok;*/
1216     gcd[i++].creator = GButtonCreate;
1217 
1218     gcd[i].gd.pos.x = -13; gcd[i].gd.pos.y = gcd[i-1].gd.pos.y+3;
1219     gcd[i].gd.pos.width = -1; gcd[i].gd.pos.height = 0;
1220     gcd[i].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
1221     label[i].text = (unichar_t *) _("_Cancel");
1222     label[i].text_is_1byte = true;
1223     label[i].text_in_resource = true;
1224     gcd[i].gd.label = &label[i];
1225     gcd[i].gd.cid = CID_Cancel;
1226     gcd[i].creator = GButtonCreate;
1227 
1228     GGadgetsCreate(gw,gcd);
1229     GTextInfoListFree(gcd[4].gd.u.list);
1230     GTextInfoListFree(freeme);
1231 
1232     GDrawSetVisible(gw,true);
1233     GWidgetIndicateFocusGadget(gcd[1].ret);
1234     while ( !fd.done )
1235 	GDrawProcessOneEvent(NULL);
1236     GDrawDestroyWindow(gw);
1237 
1238 return( false );
1239 }
1240 
ChangeFeature(GGadget * list,int index)1241 static void ChangeFeature(GGadget *list,int index) {
1242     MacFeat *mf = GGadgetGetListItemSelected(list)->userdata,
1243 	    *all = GGadgetGetUserData(list);
1244 
1245     AskFeature(mf,all,list,index);
1246 }
1247 
Pref_NewFeat(GGadget * g,GEvent * e)1248 static int Pref_NewFeat(GGadget *g, GEvent *e) {
1249     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
1250 	GWindow gw = GGadgetGetWindow(g);
1251 	GGadget *list = GWidgetGetControl(gw,CID_Features);
1252 	MacFeat *new, *mf, *all;
1253 	int expected=0;
1254 
1255 	all = GGadgetGetUserData(list);
1256 	for ( mf=all; mf!=NULL; mf=mf->next ) {
1257 	    if ( mf->feature!=expected )
1258 	break;
1259 	    ++expected;
1260 	}
1261 	new = chunkalloc(sizeof(MacFeat));
1262 	new->feature = expected;
1263 	AskFeature(new,all,list,-1);
1264     }
1265 return( true );
1266 }
1267 
Pref_DelFeat(GGadget * g,GEvent * e)1268 static int Pref_DelFeat(GGadget *g, GEvent *e) {
1269     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
1270 	MacFeat *mf, *p, *all, *next;
1271 	GWindow gw = GGadgetGetWindow(g);
1272 	GGadget *list = GWidgetGetControl(gw,CID_Features);
1273 	int32 len;
1274 	GTextInfo **ti = GGadgetGetList(list,&len);
1275 	int i;
1276 
1277 	all = GGadgetGetUserData(list);
1278 	for ( mf = all, p=NULL; mf!=NULL; mf = next ) {
1279 	    next = mf->next;
1280 	    for ( i=len-1; i>=0; --i ) {
1281 		if ( ti[i]->selected && ti[i]->userdata==mf )
1282 	    break;
1283 	    }
1284 	    if ( i>=0 ) {
1285 		if ( p==NULL )
1286 		    all = next;
1287 		else
1288 		    p->next = next;
1289 		mf->next = NULL;
1290 		MacFeatListFree(mf);
1291 	    } else
1292 		p = mf;
1293 	}
1294 	GGadgetSetUserData(list,all);
1295 	GListDelSelected(list);
1296 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_FeatureDel),false);
1297 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_FeatureEdit),false);
1298     }
1299 return( true );
1300 }
1301 
Pref_EditFeat(GGadget * g,GEvent * e)1302 static int Pref_EditFeat(GGadget *g, GEvent *e) {
1303     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
1304 	GGadget *list = GWidgetGetControl(GGadgetGetWindow(g),CID_Features);
1305 	ChangeFeature(list,GGadgetGetFirstListSelectedItem(list));
1306     }
1307 return( true );
1308 }
1309 
Pref_FeatureSel(GGadget * g,GEvent * e)1310 static int Pref_FeatureSel(GGadget *g, GEvent *e) {
1311     if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
1312 	int32 len;
1313 	GTextInfo **ti = GGadgetGetList(g,&len);
1314 	GWindow gw = GGadgetGetWindow(g);
1315 	int i, sel_cnt=0;
1316 	for ( i=0; i<len; ++i )
1317 	    if ( ti[i]->selected ) ++sel_cnt;
1318 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_FeatureDel),sel_cnt!=0);
1319 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_FeatureEdit),sel_cnt==1);
1320     } else if ( e->type==et_controlevent && e->u.control.subtype == et_listdoubleclick ) {
1321 	ChangeFeature(g,e->u.control.u.list.changed_index!=-1?e->u.control.u.list.changed_index:
1322 		GGadgetGetFirstListSelectedItem(g));
1323     }
1324 return( true );
1325 }
1326 
Pref_DefaultFeat(GGadget * g,GEvent * e)1327 static int Pref_DefaultFeat(GGadget *g, GEvent *e) {
1328     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
1329 	GGadget *list = GWidgetGetControl(GGadgetGetWindow(g),CID_Features);
1330 	int inprefs = (intpt) GGadgetGetUserData(g);
1331 	GTextInfo *ti, **arr;
1332 	uint16 cnt;
1333 	/* In preferences the default is the built in data. */
1334 	/* in a font the default is the preference data (which might be built in or might not) */
1335 	MacFeat *def = inprefs ? builtin_mac_feature_map : default_mac_feature_map;
1336 
1337 	def = MacFeatCopy(def);
1338 	MacFeatListFree(GGadgetGetUserData(list));
1339 	GGadgetSetUserData(list,def);
1340 	ti = Pref_FeaturesList(def);
1341 	arr = GTextInfoArrayFromList(ti,&cnt);
1342 	GGadgetSetList(list,arr,false);
1343 	GTextInfoListFree(ti);
1344     }
1345 return( true );
1346 }
1347 
GCDFillMacFeat(GGadgetCreateData * mfgcd,GTextInfo * mflabels,int width,MacFeat * all,int fromprefs,GGadgetCreateData * boxes,GGadgetCreateData ** array)1348 void GCDFillMacFeat(GGadgetCreateData *mfgcd,GTextInfo *mflabels, int width,
1349 	MacFeat *all, int fromprefs, GGadgetCreateData *boxes,
1350 	GGadgetCreateData **array) {
1351     int sgc;
1352     GGadgetCreateData **butarray = array+4;
1353 
1354     all = MacFeatCopy(all);
1355 
1356     sgc = 0;
1357 
1358     mfgcd[sgc].gd.pos.x = 6; mfgcd[sgc].gd.pos.y = 6;
1359     mfgcd[sgc].gd.pos.width = 250; mfgcd[sgc].gd.pos.height = 16*12+10;
1360     mfgcd[sgc].gd.flags = gg_visible | gg_enabled | gg_list_alphabetic | gg_list_multiplesel;
1361     mfgcd[sgc].gd.cid = CID_Features;
1362     mfgcd[sgc].gd.u.list = Pref_FeaturesList(all);
1363     mfgcd[sgc].gd.handle_controlevent = Pref_FeatureSel;
1364     mfgcd[sgc].data = all;
1365     mfgcd[sgc++].creator = GListCreate;
1366     array[0] = &mfgcd[sgc-1];
1367 
1368     mfgcd[sgc].gd.pos.x = 6; mfgcd[sgc].gd.pos.y = mfgcd[sgc-1].gd.pos.y+mfgcd[sgc-1].gd.pos.height+10;
1369     mfgcd[sgc].gd.flags = gg_visible | gg_enabled;
1370     mflabels[sgc].text = (unichar_t *) S_("MacFeature|_New...");
1371     mflabels[sgc].text_is_1byte = true;
1372     mflabels[sgc].text_in_resource = true;
1373     mfgcd[sgc].gd.label = &mflabels[sgc];
1374     /*mfgcd[sgc].gd.cid = CID_AnchorRename;*/
1375     mfgcd[sgc].gd.handle_controlevent = Pref_NewFeat;
1376     mfgcd[sgc++].creator = GButtonCreate;
1377     butarray[0] = GCD_Glue; butarray[1] = &mfgcd[sgc-1];
1378 
1379     mfgcd[sgc].gd.pos.x = mfgcd[sgc-1].gd.pos.x+10+GIntGetResource(_NUM_Buttonsize)*100/GIntGetResource(_NUM_ScaleFactor);
1380     mfgcd[sgc].gd.pos.y = mfgcd[sgc-1].gd.pos.y;
1381     mfgcd[sgc].gd.flags = gg_visible ;
1382     mflabels[sgc].text = (unichar_t *) _("_Delete");
1383     mflabels[sgc].text_is_1byte = true;
1384     mflabels[sgc].text_in_resource = true;
1385     mfgcd[sgc].gd.label = &mflabels[sgc];
1386     mfgcd[sgc].gd.cid = CID_FeatureDel;
1387     mfgcd[sgc].gd.handle_controlevent = Pref_DelFeat;
1388     mfgcd[sgc++].creator = GButtonCreate;
1389     butarray[2] = GCD_Glue; butarray[3] = &mfgcd[sgc-1];
1390 
1391     mfgcd[sgc].gd.pos.x = mfgcd[sgc-1].gd.pos.x+10+GIntGetResource(_NUM_Buttonsize)*100/GIntGetResource(_NUM_ScaleFactor);
1392     mfgcd[sgc].gd.pos.y = mfgcd[sgc-1].gd.pos.y;
1393     mfgcd[sgc].gd.flags = gg_visible ;
1394     mflabels[sgc].text = (unichar_t *) _("_Edit...");
1395     mflabels[sgc].text_is_1byte = true;
1396     mflabels[sgc].text_in_resource = true;
1397     mfgcd[sgc].gd.label = &mflabels[sgc];
1398     mfgcd[sgc].gd.cid = CID_FeatureEdit;
1399     mfgcd[sgc].gd.handle_controlevent = Pref_EditFeat;
1400     mfgcd[sgc++].creator = GButtonCreate;
1401     butarray[4] = GCD_Glue; butarray[5] = &mfgcd[sgc-1];
1402 
1403     mfgcd[sgc].gd.pos.x = mfgcd[sgc-1].gd.pos.x+10+GIntGetResource(_NUM_Buttonsize)*100/GIntGetResource(_NUM_ScaleFactor);
1404     mfgcd[sgc].gd.pos.y = mfgcd[sgc-1].gd.pos.y;
1405     mfgcd[sgc].gd.flags = gg_visible|gg_enabled ;
1406     mflabels[sgc].text = (unichar_t *) S_("MacFeature|Default");
1407     mflabels[sgc].text_is_1byte = true;
1408     mfgcd[sgc].gd.label = &mflabels[sgc];
1409     mfgcd[sgc].gd.handle_controlevent = Pref_DefaultFeat;
1410     mfgcd[sgc].data = (void *) (intpt) fromprefs;
1411     mfgcd[sgc++].creator = GButtonCreate;
1412     butarray[6] = GCD_Glue; butarray[7] = &mfgcd[sgc-1];
1413     butarray[8] = GCD_Glue; butarray[9] = NULL;
1414 
1415     boxes[2].gd.flags = gg_enabled|gg_visible;
1416     boxes[2].gd.u.boxelements = butarray;
1417     boxes[2].creator = GHBoxCreate;
1418     array[1] = GCD_Glue;
1419     array[2] = &boxes[2];
1420     array[3] = NULL;
1421 
1422     boxes[0].gd.flags = gg_enabled|gg_visible;
1423     boxes[0].gd.u.boxelements = array;
1424     boxes[0].creator = GVBoxCreate;
1425 }
1426 
Prefs_ReplaceMacFeatures(GGadget * list)1427 void Prefs_ReplaceMacFeatures(GGadget *list) {
1428     MacFeatListFree(user_mac_feature_map);
1429     user_mac_feature_map = GGadgetGetUserData(list);
1430     default_mac_feature_map = user_mac_feature_map;
1431 }
1432 
1433