LCOV - code coverage report
Current view: top level - fontforgeexe - macencui.c (source / functions) Hit Total Coverage
Test: FontForge coverage report 2017-08-04 01:21:11+02:00 (commit d35f7e4107a9e1db65cce47c468fcc914cecb8fd) Lines: 0 883 0.0 %
Date: 2017-08-04 Functions: 0 33 0.0 %

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

Generated by: LCOV version 1.10