dtstyle: resolve 30 compiler warnings.
[oweals/cde.git] / cde / programs / dtstyle / ColorFile.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /************************************<+>*************************************
24  ****************************************************************************
25  **
26  **   File:        ColorFile.c
27  **
28  **   Project:     DT 3.0
29  **
30  **   Description:
31  **
32  **
33  **  (c) Copyright Hewlett-Packard Company, 1990.  
34  **
35  **
36  **
37  ****************************************************************************
38  ************************************<+>*************************************/
39 /* $XConsortium: ColorFile.c /main/5 1995/10/30 13:08:20 rswiston $ */
40 /*+++++++++++++++++++++++++++++++++++++++*/
41 /* include files                         */
42 /*+++++++++++++++++++++++++++++++++++++++*/
43
44 #include <stdio.h>
45 #include <fcntl.h>
46 #include <errno.h>
47
48 #include <X11/Xlib.h>
49
50 #ifdef __hpux
51 #include <ndir.h>               /*   opendir(), directory(3C) */
52 #else
53 #if SVR4 || sco
54 #include <dirent.h>             /* opendir(), directory(3C) */
55 #else
56 #include <sys/dir.h>
57 #ifdef __apollo
58 #include <X11/apollosys.h>      /* needed for S_ISDIR macro */
59 #endif
60 #endif
61 #endif
62
63
64 #include <Xm/Xm.h>
65
66 #include <Dt/UserMsg.h>
67 #include <Dt/DtNlUtils.h>
68
69 #include "Main.h"
70 #include "ColorMain.h"
71 #include "ColorEdit.h"
72
73 /*+++++++++++++++++++++++++++++++++++++++*/
74 /* include extern functions              */
75 /*+++++++++++++++++++++++++++++++++++++++*/
76 #include "ColorFile.h"
77
78 /*+++++++++++++++++++++++++++++++++++++++*/
79 /* Local #defines                        */
80 /*+++++++++++++++++++++++++++++++++++++++*/
81 #define MAX_NUM_DIRECTORIES  12
82 #define BUFSIZE              1024
83 #define TMP_DEFAULT_NAME     "tmppalette"
84
85 /* these defines used to create error dialog */
86 #define  ERR1  ((char *)GETMESSAGE(16, 11, "Unable to delete '%s'.\n"))
87 #define  ERR2  ((char *)GETMESSAGE(16, 12, "Check $HOME/.dt/errorlog for hints."))
88 #define  ERR3  ((char *)GETMESSAGE(16, 19, "Could not open directory %s."))
89 #define  ERR4  ((char *)GETMESSAGE(16, 20, "Could not open %s."))
90 #define  ERR5  ((char *)GETMESSAGE(16, 21, "%s is an invalid palette file.\n"))
91 #define  ERR9  ((char *)GETMESSAGE(16, 18, "Warning, Too many directories listed in the resource paletteDirectories,\n Maximum number is %d."))
92
93 #ifndef CDE_INSTALLATION_TOP
94 #define CDE_INSTALLATION_TOP "/opt/dt"
95 #endif
96
97 /*+++++++++++++++++++++++++++++++++++++++*/
98 /* Local typedefs                        */
99 /*+++++++++++++++++++++++++++++++++++++++*/
100 /* Palette Directories structure */
101
102 typedef struct {
103    int NumOfDirectories;
104    char *directories[MAX_NUM_DIRECTORIES];
105 } Dir_data;
106
107 Dir_data palette_dirs;
108
109
110 /*+++++++++++++++++++++++++++++++++++++++*/
111 /* Internal Functions                    */
112 /*+++++++++++++++++++++++++++++++++++++++*/
113
114
115 static void SwitchAItoPS( palette *new_palette );
116 static palette *RemovePaletteFromList( palette *tmp_palette );
117 static void SetColors(
118                         int num_of_colors,
119                         palette *new_palette) ;
120 static void ReadInInfo(
121                         char *buf,
122                         int nbytes,
123                         palette *new_palette );
124 static void InitializeBW(
125                         unsigned long color,
126                         int num_of_colors,
127                         palette *new_palette ) ;
128
129
130
131 /*+++++++++++++++++++++++++++++++++++++++*/
132 /* Internal Variables                    */
133 /*+++++++++++++++++++++++++++++++++++++++*/
134 int NumOfPalettes = 0;
135
136 static char *PALETTE_DIR = CDE_INSTALLATION_TOP "/palettes/";
137 static char *PALETTE_DIR_ADM = "/etc/dt/palettes/";
138 static char *DEFAULT_FILENAME = "palette.dt";
139 static char *B_O_W = "BlackWhite.dp";
140 static char *W_O_B = "WhiteBlack.dp";
141 static char *W_ONLY = "White.dp";
142 static char *B_ONLY = "Black.dp";
143 static char *home_palette_dir;
144
145 static int loopcount = 0;
146 static DIR  *dirp;
147 #ifdef __hpux
148 static struct direct *file_descpt;
149 #else
150 static struct dirent *file_descpt;
151 #endif /* __hpux */
152 static Boolean open_dir = False;
153 extern XrmDatabase hm_pl_DB;
154
155 XColor saved_color[2];
156
157
158 /*
159 ** readinpalettes reads in the different palettes for the customizer.
160 **
161 ** The directories read from include:
162 **     1. the system palettes (PALETTE_DIR)
163 **     2. the user defined directories specified by the resource PaletteDir. 
164 **     3. the users $HOME/.dt/palettes
165 */
166
167 void 
168 ReadInPalettes(
169         char *text )
170 {
171 /*
172 **  if text is NULL then open only the global dir and user dir, 
173 **  otherwise open all the directories listed *text. 
174 */
175    AddSystemPath();
176
177    if (text != NULL)
178       AddDirectories(text);
179
180    AddHomePath();
181    
182    ReadPaletteLoop(False);
183
184 }
185
186 /*
187 **  ReadPalette reads the contents of the file in_filename, allocates space
188 **  for a new palette, and puts it in there.
189 **  The varible in_filename passed in should be just the filename 
190 **  of the file.  The absolute file name is constructed in this routine.
191 **  i.e.  directory/file.
192 **  Finally this routine ups the count for number of palettes in the
193 **  customizer.
194 **  The parameter length, which is passed in, is the length of the in_filename
195 **  string.
196 **  After the system palettes are read in, if there are duplicate copies 
197 **  of palette names, the first one encountered is the one that is used.  
198 **  Subsequent palettes with the same name are discarded.
199 **  Then when the users home palette directory is read, if there are
200 **  duplicates, the users home palettes is kept.
201 */
202 void 
203 ReadPalette(
204         char *directory,
205         char *in_filename,
206 #if NeedWidePrototypes
207         int length )
208 #else
209         short length )
210 #endif
211 {
212    char *filename;
213    int  i, fd, nbytes;
214    char buf[BUFSIZE];
215    palette *new_palette, *tmp_palette;
216    Boolean  modify, add, found;
217    char *tmpStr;
218    char *p;
219
220    modify = FALSE;
221    if (strcmp(directory, PALETTE_DIR) == 0)
222        add = TRUE;
223    else
224        add = FALSE;
225        
226 /* Allocate space for this new palette.*/
227    new_palette = (palette *)XtMalloc( sizeof(palette) + 1);
228
229 /* create the filename to be read by adding directory in front of it */
230    filename = (char *)XtMalloc( strlen(directory) + length + 2);
231    strcpy(filename, directory); 
232
233    if(DtCharCount(DtStrrchr(directory, '/')) != 1)
234         strcat(filename, "/"); 
235    strcat(filename, in_filename); 
236
237 /* open the file for reading */
238    if( (fd = open( filename, O_RDONLY)) == -1)
239    {
240       tmpStr = (char *)XtMalloc(strlen(ERR4) + strlen(filename) + 1);
241       sprintf(tmpStr, ERR4, filename);
242       _DtSimpleErrnoError (progName, DtWarning, NULL, tmpStr, NULL);
243       XtFree(tmpStr);
244       XtFree(filename);
245       return;
246    }
247    else 
248    {
249     /* determine number of bytes in the name of the palette */
250        i = strlen(in_filename) - strlen(PALETTE_SUFFIX);
251
252     /* allocate enough space for the name */
253       new_palette->name = (char *)XtMalloc(i + 1);
254
255     /* load the filename into the name element */
256       p = strstr (in_filename, PALETTE_SUFFIX);
257       *p = '\0';
258       strcpy(new_palette->name, in_filename);
259
260 /* 
261 ** Now we have a name lets check to see if it is already in the linked
262 ** list.  If it is and it is from the system palettes, replace it.
263 ** If it is already in the list but is not from the system palettes,
264 ** don't overwrite it - discard the one just read and go on to next palette.
265 */
266       if(pHeadPalette != NULL)
267       {
268          found = FALSE;
269          tmp_palette = pHeadPalette;
270          while(tmp_palette->next != NULL )
271          {
272             if(strcmp(tmp_palette->name, new_palette->name)) 
273                tmp_palette = tmp_palette->next;
274             else
275             {
276                found = TRUE;
277                if ((strcmp(tmp_palette->directory, PALETTE_DIR) == 0) ||
278                    (strcmp(directory, home_palette_dir) == 0))
279                {
280                    XtFree(new_palette->name);   
281                    XtFree((char *)new_palette);   
282                    XtFree(tmp_palette->directory);   
283                    new_palette = tmp_palette;
284                    modify = TRUE;
285                }
286                else
287                {
288                    XtFree(new_palette->name);   
289                    XtFree((char *)new_palette);   
290                }
291                break;
292             }
293          }
294         /* check the last palette */
295          if (!found)
296          {
297              if (strcmp(tmp_palette->name, new_palette->name) == 0) 
298
299                  if ((strcmp(tmp_palette->directory, PALETTE_DIR) == 0) ||
300                      (strcmp(directory, home_palette_dir) == 0))
301                  {
302                     XtFree(new_palette->name);
303                     XtFree((char *)new_palette);
304                     XtFree(tmp_palette->directory);
305                     new_palette = tmp_palette;
306                     modify = TRUE;
307                  }
308                  else 
309                  {
310                     if (!add) /* not system palettes */
311                     {
312                        XtFree(new_palette->name);   
313                        XtFree((char *)new_palette);   
314                     }
315                  }
316
317              else
318                 add = TRUE;
319          }
320       }
321
322       if ((modify == TRUE)||(add == TRUE))
323       {
324         /* allocate enough space for the directory */
325           new_palette->directory = (char *)XtMalloc(strlen(directory) + 1);
326
327         /* load the directory name into the directory element */
328           strcpy(new_palette->directory, directory);
329
330         /* set the num_of_colors  to 0 */
331           new_palette->num_of_colors = 0;
332
333           nbytes = read(fd, buf, BUFSIZE);
334           if( nbytes == BUFSIZE || nbytes == 0)
335           {
336              tmpStr = (char *)XtMalloc(strlen(ERR5) + strlen(filename) + 1);
337              sprintf(tmpStr, ERR5, filename);
338              _DtSimpleError (progName, DtWarning, NULL, tmpStr, NULL);
339              XtFree(filename);
340              XtFree(tmpStr);
341              close(fd);
342              return;
343           }
344           else
345           {
346            /* go parse the data from the palette file */
347              ReadInInfo(buf, nbytes, new_palette);
348           } 
349
350       } /* modify == TRUE */
351
352       /* close the file */
353       close(fd); 
354
355     } /* else */
356
357 /*
358 **  Find the next available location within the linked list of palettes to 
359 **  store the palette just created.  If it is the first one store it in
360 **  pHeadPalettes, else store it in the first place a NULL is encountered
361 **  for the next member of the palette structure.
362 */
363     if (add == TRUE)
364     {
365       /* set the next pointer to NULL*/
366        new_palette->next = NULL;
367
368       /* increment the total number of palettes in the customizer */
369        NumOfPalettes++;
370
371        if( pHeadPalette == NULL /* First entry */
372           || (pHeadPalette != NULL && strcmp(pHeadPalette->name, new_palette->name) > 0)) /* Earlier entry than current list head */
373        {
374            new_palette->item_position = 1;
375            if(pHeadPalette)
376            {
377                new_palette->next = pHeadPalette;
378                /* Increment position poineter of other items in the list */
379                tmp_palette = pHeadPalette;
380                while( tmp_palette != NULL)
381                {
382                    tmp_palette->item_position += 1;
383                    tmp_palette = tmp_palette->next;
384                }
385            }
386
387            pHeadPalette = new_palette;
388        }
389        else
390        {
391            tmp_palette = pHeadPalette;
392
393            /* Search through the linked list to find the first entry with a 
394               name > new entries name, new item will be inserted after it */
395            while(tmp_palette->next && strcmp(tmp_palette->next->name, new_palette->name) < 0) 
396            {
397                tmp_palette = tmp_palette->next;
398            }
399
400            /* Insert the new palette */
401            new_palette->next = tmp_palette->next;
402            tmp_palette->next = new_palette;
403            new_palette->item_position = tmp_palette->item_position + 1;
404
405            /* Now continue incrementing through the list increasing the position
406               count of all items following the new entry */
407            tmp_palette = new_palette->next;
408            while( tmp_palette != NULL)
409            {
410               tmp_palette->item_position += 1;
411               tmp_palette = tmp_palette->next;
412            }
413        }
414     }
415
416   /* done with filename so XtFree it */
417    XtFree(filename);
418
419 }
420 /***************************************************************************
421  *
422  * WriteOutPalette -
423  * This routine writes out a file (palette) to the users .dt/palettes
424  * directory. The palette name is passed into the routine. 
425  *
426  ***************************************************************************/
427 int 
428 WriteOutPalette(
429         char *paletteName )
430 {
431    char *temp, *tmpStr;
432    char *filename;
433    int  i, fd;
434
435   /* use the $HOME environment varible then constuct the full file name */
436    filename = (char *)XtMalloc(strlen(style.home) + 
437                                strlen(DT_PAL_DIR) +
438                                strlen(paletteName) + 
439                                strlen(PALETTE_SUFFIX) + 2);
440
441   /* create the full path name plus file name */
442    strcpy(filename, style.home);
443    strcat(filename, DT_PAL_DIR);
444    strcat(filename, paletteName);
445    strcat(filename, PALETTE_SUFFIX);
446
447    /* open the file for writing */
448 #if defined(linux)
449    if( (fd = open( filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) == -1)
450 #else
451    if( (fd = open( filename, O_RDWR | O_CREAT)) == -1)
452 #endif
453    {
454        tmpStr = (char *)XtMalloc(strlen(ERR4) + strlen(filename) + 1);
455        sprintf (tmpStr, ERR4, filename);
456        _DtSimpleErrnoError (progName, DtWarning, NULL, tmpStr, NULL);
457        XtFree(tmpStr);
458        XtFree(filename);
459        return(-1);
460    }
461    else
462    {
463        temp = (char *)XtMalloc(60);
464        for(i = 0; i < XmCO_MAX_NUM_COLORS; i++)
465        {
466         /* put the colors of the palette in the form #RRRRGGGGBBBB */   
467            if(TypeOfMonitor == XmCO_LOW_COLOR && (i == 0 || i == 1))
468                sprintf(temp,"#%04x%04x%04x\n", saved_color[i].red, 
469                                                saved_color[i].green, 
470                                                saved_color[i].blue);
471            else if(TypeOfMonitor == XmCO_LOW_COLOR && i == 2)
472                sprintf(temp,"#%04x%04x%04x\n",
473                                    pCurrentPalette->color[1].bg.red,
474                                    pCurrentPalette->color[1].bg.green,
475                                    pCurrentPalette->color[1].bg.blue);
476            else if(TypeOfMonitor == XmCO_LOW_COLOR && i == 3)
477                sprintf(temp,"#%04x%04x%04x\n",
478                                    pCurrentPalette->color[0].bg.red,
479                                    pCurrentPalette->color[0].bg.green,
480                                    pCurrentPalette->color[0].bg.blue);
481            else
482                sprintf(temp,"#%04x%04x%04x\n",
483                                    pCurrentPalette->color[i].bg.red,
484                                    pCurrentPalette->color[i].bg.green,
485                                    pCurrentPalette->color[i].bg.blue);
486            if(-1 == write(fd, temp, strlen(temp))) {
487                    perror(strerror(errno));
488                    return(-1);
489            }
490        }
491        XtFree(temp);
492    }
493    close(fd);
494    /* make sure the file is read/writable */
495    chmod(filename,438);
496    XtFree(filename);
497    return(0);
498 }
499
500 /***************************************************************************
501  *
502  * WriteOutDesc -
503  * This routine writes out the description file for the added palette in the 
504  * user's .dt/palettes directory.
505  ***************************************************************************/
506 int 
507 WriteOutDesc(
508         palette *tmp_palette )
509 {
510    char *desc_file;
511    char *desc_name;
512
513    /* write the description resource to the user's home data base and write out */
514    /* the database to the user's palatte directory */
515  
516    desc_name = (char *) XtMalloc(strlen("Palettes*") + 
517                                  strlen(tmp_palette->name) + 
518                                  strlen(".desc") + 1);
519    
520    sprintf(desc_name, "Palettes*%s.desc", tmp_palette->name);
521    
522    XrmPutStringResource(&hm_pl_DB, desc_name, tmp_palette->desc); 
523     
524    /* write out the description file */
525    desc_file = (char *) XtMalloc(strlen(style.home) +(strlen("/.dt/palettes/desc.palettes") + 1));
526    strcpy (desc_file, style.home);
527    strcat (desc_file, "/.dt/palettes/desc.palettes");
528    if (hm_pl_DB )
529      XrmPutFileDatabase(hm_pl_DB, desc_file);
530    /* make the file read, write */
531    chmod(desc_file,438);
532    XtFree(desc_file);
533    XtFree(desc_name);
534
535    return(0);
536 }
537
538 /*
539 ** This routine removes a palette.  
540 ** It actually creates a file in the users home palette directory with 
541 ** the current palette name preceeded by a '~'.
542 ** If the current palette is from the users home palette directory, that
543 ** file is removed.
544 */
545 Boolean 
546 RemovePalette( void )
547 {
548     int  result;
549     char *filename1, *filename2;
550     char *tmpStr;
551
552     /* prepend the palette name with '~' */
553
554     filename1 = (char *)XtMalloc(strlen(pCurrentPalette->name) +2); 
555     strcpy(filename1, "~");
556     strcat(filename1, pCurrentPalette->name);
557
558     if (WriteOutPalette(filename1) != 0)
559     {
560        tmpStr = (char *)XtMalloc(strlen(ERR1) + 
561                        strlen(pCurrentPalette->name) + strlen(ERR2) + 1);
562        sprintf(tmpStr, ERR1, pCurrentPalette->name);
563        strcat(tmpStr,ERR2);
564        ErrDialog (tmpStr, style.colorDialog);
565        XtFree (tmpStr);
566        XtFree (filename1);
567        return(False);
568     }
569
570     if (strcmp(pCurrentPalette->directory, home_palette_dir) == 0)
571     {
572         /* get the $HOME environment varible and constuct the full file name */
573         filename2 = (char *)XtMalloc(strlen(style.home) + strlen(DT_PAL_DIR) +
574                    strlen(pCurrentPalette->name) + strlen(PALETTE_SUFFIX) + 1);
575
576         /* create the full path name plus file name */
577         strcpy(filename2, style.home);
578         strcat(filename2, DT_PAL_DIR);
579         strcat(filename2, pCurrentPalette->name);
580         strcat(filename2, PALETTE_SUFFIX);
581
582         result = unlink(filename2);
583
584         if(result != 0)
585         {
586             tmpStr = (char *)XtMalloc(strlen(ERR1) + strlen(filename2) + 1); 
587             sprintf (tmpStr, ERR1, filename2);
588             _DtSimpleErrnoError (progName, DtWarning, NULL, tmpStr, NULL);
589             XtFree(tmpStr);
590
591             tmpStr = (char *)XtMalloc(strlen(ERR1) +
592                         strlen(pCurrentPalette->name) + strlen(ERR2) + 1);
593             sprintf(tmpStr, ERR1, pCurrentPalette->name);
594             strcat(tmpStr, ERR2);
595             ErrDialog (tmpStr, style.colorDialog);
596             XtFree (tmpStr);
597             XtFree(filename1);
598             XtFree(filename2);
599             return(False);
600         }
601
602         XtFree(filename2);
603     }
604
605     XtFree(filename1);
606     return(True);
607
608 }
609
610 /************************************************************************
611  *
612  * AddSystemPath - adds the system palettes to the directory structure.
613  *
614  ************************************************************************/
615 void 
616 AddSystemPath( void )
617 {
618   if(style.count > 4)
619     return;
620   
621   /*
622    ** Null out the head of the palette linked list
623    */
624   pHeadPalette = NULL;
625   
626   /* set the number of directories to search to 0, this is the first path
627      added  */
628   palette_dirs.NumOfDirectories = 0;
629   
630   /* store the system PALETTE_DIR in the palette_dirs structure */
631   palette_dirs.directories[palette_dirs.NumOfDirectories] = 
632     (char *) XtMalloc(strlen(PALETTE_DIR) + 1);
633   strcpy(palette_dirs.directories[palette_dirs.NumOfDirectories], 
634          PALETTE_DIR);
635   
636   /* increment the Number of directories to search */
637   palette_dirs.NumOfDirectories++;
638
639   style.count++;
640   
641   /* store the admin PALETTE_DIR_ADM in the palette_dirs structure */
642   palette_dirs.directories[palette_dirs.NumOfDirectories] = 
643     (char *) XtMalloc(strlen(PALETTE_DIR_ADM) + 1);
644   strcpy(palette_dirs.directories[palette_dirs.NumOfDirectories], 
645          PALETTE_DIR_ADM);
646   
647   /* increment the Number of directories to search */
648   palette_dirs.NumOfDirectories++;
649   
650 }
651
652 /************************************************************************
653  *
654  * AddHomePath - adds the users home directory to the directory structure.
655  *
656  ************************************************************************/
657 void 
658 AddHomePath( void )
659 {
660    int  result;
661    char *tmpStr;
662    
663    if(style.count > 6)
664       return;
665
666   /* get the $HOME environment varible and constuct the full path */
667    home_palette_dir = (char *)XtMalloc(strlen(style.home) 
668         + strlen(DT_PAL_DIR) + 1);
669
670   /* create the full path name plus file name */
671    strcpy(home_palette_dir, style.home);
672    strcat(home_palette_dir, DT_PAL_DIR);
673
674   /* open $HOME/.dt/palettes */
675    if( (dirp = opendir(home_palette_dir)) == NULL)
676    {
677        /*  create .dt/palettes if it does not exit */
678        result = mkdir(home_palette_dir, 511);
679        if(result == -1)
680        {
681            tmpStr = (char *)XtMalloc(strlen(ERR3) + 
682                 strlen(home_palette_dir) +1);
683            sprintf(tmpStr, ERR4, home_palette_dir);
684            _DtSimpleError (progName, DtWarning, NULL, tmpStr, NULL);
685            XtFree(tmpStr);
686        }
687    }
688                                          
689   /* store the directory in the palette_dirs structure */
690    palette_dirs.directories[palette_dirs.NumOfDirectories] = 
691                   (char *) XtMalloc(strlen(home_palette_dir) + 1);
692    strcpy(palette_dirs.directories[palette_dirs.NumOfDirectories], 
693                   home_palette_dir);
694   /* increment the Number of directories to search */
695    palette_dirs.NumOfDirectories++;
696
697    style.count++;
698 }
699
700 /************************************************************************
701  *
702  * AddDirectories - adds the directories listed in the string text
703  *     to the list of directories which must be checked for valid
704  *     palette files.
705  *
706  ************************************************************************/
707 void 
708 AddDirectories( char *text )
709 {
710    char *filename, *tmpStr;
711    int i, count;
712
713    if(style.count > 5)
714       return;
715
716   /* alloc enough space for temp length */
717    filename = (char *)XtMalloc(strlen(text) + 1);
718
719    count = 0;
720    while(1)
721    {
722      /* copy directory name into the  name .. look for NULL or space */
723       for(i=count; text[i] != ':' && text[i] != '\0'; i++)
724           filename[i - count] = text[i];
725       filename[i - count] = '\0';
726
727      /* store the directory in the palette_dirs structure */
728       palette_dirs.directories[palette_dirs.NumOfDirectories] = 
729                    (char *)XtMalloc(strlen(filename) + 1);
730       strcpy(palette_dirs.directories[palette_dirs.NumOfDirectories], 
731                    filename);
732
733      /* increment number of directories in the structure */
734       palette_dirs.NumOfDirectories++;
735
736      /* if the number of directories read is the maximum number of 
737          directories then break */
738       if (palette_dirs.NumOfDirectories == MAX_NUM_DIRECTORIES-1)
739       {
740           tmpStr = (char *)XtMalloc(strlen(ERR9) + 5);
741           sprintf(tmpStr, ERR9, MAX_NUM_DIRECTORIES-2);
742           _DtSimpleError (progName, DtWarning, NULL, tmpStr, NULL);
743           XtFree(tmpStr);
744           break;
745       }
746
747      /* if the last value was a NULL then all done,  Break out */
748       if (text[i] == '\0')
749          break;
750
751       count = i + 1;
752
753    } /* while(1) */
754
755    XtFree(filename);
756    style.count++;
757 }
758
759 /********************************************************************
760  * 
761  * CheckForDeletedFile - This routine looks through the linked list
762  *     of palettes for the file name passed in.  If it finds it, that
763  *     member of the linked list must be deleted. 
764  *
765  ********************************************************************/
766 void
767 CheckForDeletedFile(
768 #ifdef __hpux
769         struct direct *file_descpt )
770 #else
771         struct dirent *file_descpt )
772 #endif /* __hpux */
773 {
774    char *filename;
775    int i;
776    palette *tmp_palette;
777
778   /* alloc enough space for the name of the ~ file  */
779    filename = (char *)XtMalloc(strlen (file_descpt->d_name) + 1);
780
781   /* copy the name into filename taking out the ~ */
782    for(i=0; i < strlen (file_descpt->d_name) - (strlen(PALETTE_SUFFIX) + 1); i++)
783       filename[i] = file_descpt->d_name[i+1];
784    filename[i] = '\0';
785
786   /* now go see if the filename is in the palette link list */
787    tmp_palette = pHeadPalette;
788    while(tmp_palette->next != NULL )
789      if(strcmp(tmp_palette->name, filename)) 
790         tmp_palette = tmp_palette->next;
791      else
792         tmp_palette = RemovePaletteFromList(tmp_palette);
793
794    /* check the last palette */
795    if(tmp_palette->next == NULL && (strcmp(tmp_palette->name, filename) == 0))
796       (void) RemovePaletteFromList(tmp_palette);
797
798    XtFree(filename);
799 }
800
801 /****************************************************************************
802  *
803  * ReadInInfo - the routine used to actual parse the data from a palette
804  *       file.  It parses 8 different background colors.  
805  *
806  ****************************************************************************/
807 static void
808 ReadInInfo(
809         char *buf,
810         int nbytes,
811         palette *new_palette )
812 {
813    int buf_count, count, result;
814    char tmpbuf[50];
815    XColor tmp_color;
816    int  hue, sat, val;
817    int num_of_colors = 0;
818
819    for( buf_count = 0; buf_count < nbytes;)
820    {
821        count = 0;
822    
823      /* read in a background color */
824        while( buf[buf_count] != '\012' && buf[buf_count] != ':' )
825           tmpbuf[count++] = buf[buf_count++];
826        tmpbuf[count] = '\0';
827
828      /* temporary for now until all palettes are updated not to use : */
829        if(buf[buf_count] == ':')
830           while(buf[buf_count] != '\012')
831              buf_count++;
832        buf_count++;
833    
834       /* Parse the background color */
835        result = XParseColor(style.display, style.colormap, tmpbuf, &tmp_color);
836
837       /* if the result == 0 then the parse came back bad, uses the motif
838          default background (#729FFF) */
839        if(result == 0)
840        {
841           new_palette->color[num_of_colors].bg.red = 29184;
842           new_palette->color[num_of_colors].bg.green = 40704;
843           new_palette->color[num_of_colors].bg.blue = 65280;
844        }
845        else
846        {
847           new_palette->color[num_of_colors].bg.red = tmp_color.red;
848           new_palette->color[num_of_colors].bg.green = tmp_color.green;
849           new_palette->color[num_of_colors].bg.blue = tmp_color.blue;
850        }
851    
852       /* use the motif routine to generate fg, sc, ts, and bs */
853        if(TypeOfMonitor != XmCO_BLACK_WHITE) {
854           if (edit.calcRGB == NULL) edit.calcRGB = XmGetColorCalculation();
855           (*edit.calcRGB)(&tmp_color, 
856                                   &(new_palette->color[num_of_colors].fg),
857                                   &(new_palette->color[num_of_colors].sc),
858                                   &(new_palette->color[num_of_colors].ts),
859                                   &(new_palette->color[num_of_colors].bs));
860
861            RGBtoHSV(new_palette->color[num_of_colors].bg.red,
862                       new_palette->color[num_of_colors].bg.green,
863                       new_palette->color[num_of_colors].bg.blue,
864                       &hue, &sat, &val);
865    
866
867           SetColors(num_of_colors, new_palette);
868        }
869        else /* XmCO_BLACK_WHITE */
870           InitializeBW(tmp_color.red, num_of_colors, new_palette);
871
872        new_palette->num_of_colors++;
873        num_of_colors++;
874        if (num_of_colors == 8)
875             break;
876    
877    } /* for */
878
879   /* have now read in complete palette file .. set number of colors 
880      appropriatly because every palette has 8 entries */
881    if(TypeOfMonitor == XmCO_LOW_COLOR || TypeOfMonitor == XmCO_BLACK_WHITE)
882        new_palette->num_of_colors = 2;
883    
884    if(TypeOfMonitor == XmCO_MEDIUM_COLOR)
885        new_palette->num_of_colors = 4;
886
887    if(TypeOfMonitor == XmCO_LOW_COLOR)
888    {
889       SwitchAItoPS(new_palette);
890    }
891
892
893 /***************************************************************************
894  *
895  * SetColors - 
896  *       It sets bs and ts if Pixmaps are to be used for topshadow 
897  *       and bottomshadow.
898  *
899  ***************************************************************************/
900 static void 
901 SetColors(
902         int num_of_colors,
903         palette *new_palette )
904 {
905
906 /*
907 **  Set the foreground pixel to either black or white depending on brightness
908 */
909    if (FgColor != DYNAMIC) 
910    {
911       if (FgColor == BLACK)
912       {
913          new_palette->color[num_of_colors].fg.red = 0;
914          new_palette->color[num_of_colors].fg.blue = 0;
915          new_palette->color[num_of_colors].fg.green = 0;
916       }
917       else /* WHITE */
918       {
919          new_palette->color[num_of_colors].fg.red = 65535;
920          new_palette->color[num_of_colors].fg.blue = 65535;
921          new_palette->color[num_of_colors].fg.green = 65535;
922       }
923    }
924
925
926 /*
927 ** Now set ts and bs if the user is using pixmaps
928 */
929    if(UsePixmaps != FALSE)
930    {
931        new_palette->color[num_of_colors].ts.red = 65535; 
932        new_palette->color[num_of_colors].ts.blue = 65535;
933        new_palette->color[num_of_colors].ts.green = 65535;
934    
935        new_palette->color[num_of_colors].bs.red = 0;
936        new_palette->color[num_of_colors].bs.blue = 0;
937        new_palette->color[num_of_colors].bs.green = 0;
938    }
939
940 }
941
942 /***************************************************************************
943  *
944  * InitializeBW - initializes the RGB values for the WhiteOnBlack and
945  *        BlackOnWhite palettes.  The color passed in is used to determine
946  *        if its White on Black or Black on White.
947  *
948  ***************************************************************************/
949 static void
950 InitializeBW(
951         unsigned long color,
952         int num_of_colors,
953         palette *new_palette )
954 {
955   /* if color passed in is black(background) its white on black so
956      set everything to white */
957    if(color == 0)
958    {
959        new_palette->color[num_of_colors].fg.red = 65535; 
960        new_palette->color[num_of_colors].fg.blue = 65535;
961        new_palette->color[num_of_colors].fg.green = 65535;
962    
963        new_palette->color[num_of_colors].sc.red = 65535;
964        new_palette->color[num_of_colors].sc.blue = 65535;
965        new_palette->color[num_of_colors].sc.green = 65535;
966    
967        new_palette->color[num_of_colors].ts.red = 0; 
968        new_palette->color[num_of_colors].ts.blue = 0;
969        new_palette->color[num_of_colors].ts.green = 0;
970       
971        new_palette->color[num_of_colors].bs.red = 65535;
972        new_palette->color[num_of_colors].bs.blue = 65535;
973        new_palette->color[num_of_colors].bs.green = 65535;
974    }
975    else
976    {
977        new_palette->color[num_of_colors].fg.red = 0; 
978        new_palette->color[num_of_colors].fg.blue = 0;
979        new_palette->color[num_of_colors].fg.green = 0;
980    
981        new_palette->color[num_of_colors].sc.red = 65535;
982        new_palette->color[num_of_colors].sc.blue = 65535;
983        new_palette->color[num_of_colors].sc.green = 65535;
984    
985        new_palette->color[num_of_colors].ts.red = 0; 
986        new_palette->color[num_of_colors].ts.blue = 0;
987        new_palette->color[num_of_colors].ts.green = 0;
988    
989        new_palette->color[num_of_colors].bs.red = 0;
990        new_palette->color[num_of_colors].bs.blue = 0;
991        new_palette->color[num_of_colors].bs.green = 0;
992    }
993 }
994
995 /****************************************************************************
996  *
997  * SwitchAItoPS - used to in a XmCO_LOW_COLOR system to switch the Acitive and
998  *    Inactive colorsets to use the Primary and Secondary colorsets.  It
999  *    was determined that this would look much better to the user.
1000  *
1001  **************************************************************************/
1002 static void 
1003 SwitchAItoPS( palette *new_palette )
1004 {
1005    saved_color[0].red = new_palette->color[0].bg.red;
1006    saved_color[0].green = new_palette->color[0].bg.green;
1007    saved_color[0].blue = new_palette->color[0].bg.blue;
1008
1009    saved_color[1].red = new_palette->color[1].bg.red;
1010    saved_color[1].green = new_palette->color[1].bg.green;
1011    saved_color[1].blue = new_palette->color[1].bg.blue;
1012
1013    new_palette->color[0].bg.red = new_palette->color[3].bg.red;
1014    new_palette->color[0].bg.green = new_palette->color[3].bg.green;
1015    new_palette->color[0].bg.blue = new_palette->color[3].bg.blue;
1016
1017    new_palette->color[0].fg.red = new_palette->color[3].fg.red;
1018    new_palette->color[0].fg.green = new_palette->color[3].fg.green;
1019    new_palette->color[0].fg.blue = new_palette->color[3].fg.blue;
1020
1021    new_palette->color[0].ts.red = new_palette->color[3].ts.red;
1022    new_palette->color[0].ts.green = new_palette->color[3].ts.green;
1023    new_palette->color[0].ts.blue = new_palette->color[3].ts.blue;
1024
1025    new_palette->color[0].bs.red = new_palette->color[3].bs.red;
1026    new_palette->color[0].bs.green = new_palette->color[3].bs.green;
1027    new_palette->color[0].bs.blue = new_palette->color[3].bs.blue;
1028
1029    new_palette->color[0].sc.red = new_palette->color[3].sc.red;
1030    new_palette->color[0].sc.green = new_palette->color[3].sc.green;
1031    new_palette->color[0].sc.blue = new_palette->color[3].sc.blue;
1032
1033    new_palette->color[1].bg.red = new_palette->color[2].bg.red;
1034    new_palette->color[1].bg.green = new_palette->color[2].bg.green;
1035    new_palette->color[1].bg.blue = new_palette->color[2].bg.blue;
1036
1037    new_palette->color[1].fg.red = new_palette->color[2].fg.red;
1038    new_palette->color[1].fg.green = new_palette->color[2].fg.green;
1039    new_palette->color[1].fg.blue = new_palette->color[2].fg.blue;
1040
1041    new_palette->color[1].ts.red = new_palette->color[2].ts.red;
1042    new_palette->color[1].ts.green = new_palette->color[2].ts.green;
1043    new_palette->color[1].ts.blue = new_palette->color[2].ts.blue;
1044
1045    new_palette->color[1].bs.red = new_palette->color[2].bs.red;
1046    new_palette->color[1].bs.green = new_palette->color[2].bs.green;
1047    new_palette->color[1].bs.blue = new_palette->color[2].bs.blue;
1048
1049    new_palette->color[1].sc.red = new_palette->color[2].sc.red;
1050    new_palette->color[1].sc.green = new_palette->color[2].sc.green;
1051    new_palette->color[1].sc.blue = new_palette->color[2].sc.blue;
1052
1053 }
1054
1055 /****************************************************************************
1056  *
1057  * RemovePaletteFromList - used to remove the palette pointed to by 
1058  *    tmp_palette from the linked list of palettes.  The returned palette
1059  *    is the palette immediately before the deleted palette 
1060  *
1061  **************************************************************************/
1062 static palette * 
1063 RemovePaletteFromList( palette *tmp_palette )
1064
1065    palette *tmp2_palette; 
1066    int i, count;
1067
1068  /* it is in here ... get rid of this entry in the link list */
1069    if (tmp_palette->item_position == 1)
1070    {
1071        pHeadPalette = tmp_palette->next;
1072        tmp2_palette = pHeadPalette;
1073    }
1074    else
1075    {
1076      /* find palette just above the one being deleted */
1077        tmp2_palette = pHeadPalette;
1078        for (i=1; i < tmp_palette->item_position-1; i++)
1079            tmp2_palette = tmp2_palette->next;
1080
1081       /* set the palette before's next to the one being deleted next */
1082        tmp2_palette->next = tmp_palette->next;
1083    }
1084
1085     /* deallocate the palette structure */
1086    XtFree(tmp_palette->name);
1087    XtFree(tmp_palette->directory);
1088    XtFree((char *)tmp_palette);
1089
1090      /* make sure the item_positions are correct*/
1091    count = 1;
1092    tmp_palette = pHeadPalette;
1093    while(tmp_palette->next != NULL )
1094    {
1095       tmp_palette->item_position = count++;
1096       tmp_palette = tmp_palette->next;
1097    }
1098    tmp_palette->item_position = count;
1099
1100   /* decrease the number of palettes */
1101    NumOfPalettes--;
1102
1103   return(tmp2_palette);
1104 }
1105
1106 /*************************************************************************
1107  *
1108  * CheckFileType() - Determine if the system supports long file names
1109  *   or not .. set a flag accoringly.
1110  *
1111  ***********************************************************************/
1112 void
1113 CheckFileType( void )
1114 {
1115    char *filename1 = "abcdefghijklmno";
1116    char *filename2 = "abcdefghijklmn";
1117    int  fd, fd1;
1118    char *tmpfile1, *tmpfile2;
1119  
1120   /* get the $HOME environment varible and constuct the full file name */
1121    tmpfile1 = (char *)XtMalloc(strlen(style.home) + strlen(DT_PAL_DIR) +
1122                                                      strlen(filename1) + 2);
1123
1124   /* create the full path name plus file name */
1125    strcpy(tmpfile1, style.home);
1126    strcat(tmpfile1, DT_PAL_DIR);
1127    strcat(tmpfile1, filename1);
1128
1129 #if defined(linux)
1130    if( (fd = open( tmpfile1, O_CREAT, S_IRUSR | S_IWUSR)) == -1)
1131 #else
1132    if( (fd = open( tmpfile1, O_CREAT)) == -1)
1133 #endif
1134    {
1135         style. longfilename = False;
1136         XtFree(tmpfile1);
1137         style.count++;
1138         return;
1139    }
1140   /* get the $HOME environment varible and constuct the full file name */
1141    tmpfile2 = (char *)XtMalloc(strlen(style.home) + strlen(DT_PAL_DIR) +
1142                                                      strlen(filename2) + 2);
1143
1144   /* create the full path name plus file name */
1145    strcpy(tmpfile2, style.home);
1146    strcat(tmpfile2, DT_PAL_DIR);
1147    strcat(tmpfile2, filename2);
1148
1149 #if defined(linux)
1150    if( (fd1 = open(tmpfile2, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) == -1)
1151 #else
1152    if( (fd1 = open(tmpfile2, O_CREAT | O_EXCL)) == -1)
1153 #endif
1154    {
1155        style.longfilename = False; 
1156    }
1157    else
1158    {
1159        style.longfilename = True;
1160        unlink(tmpfile2);
1161    }
1162
1163    unlink(tmpfile1);
1164    XtFree(tmpfile1);
1165    XtFree(tmpfile2);
1166    close(fd);
1167    close(fd1);
1168    
1169 }
1170
1171 Boolean 
1172 ReadPaletteLoop( 
1173 #if NeedWidePrototypes
1174         int startup )
1175 #else
1176         Boolean startup )
1177 #endif
1178 {
1179    char *tmpStr;
1180
1181    if(style.count > 7)
1182       return(True);
1183
1184    /* read all files from all directories */
1185    while(loopcount<palette_dirs.NumOfDirectories && loopcount<MAX_NUM_DIRECTORIES)
1186    {
1187          
1188 /*
1189 ** Open the directory .
1190 **   dirp is a pointer to the directory stream
1191 */
1192       if( open_dir == False )
1193       {
1194          if( (dirp = opendir(palette_dirs.directories[loopcount])) == NULL)
1195          {
1196             /* note: if there is an error in opening a directory,
1197              * the directory is not deleted from the palette_dirs
1198              * structure.
1199              */
1200             loopcount++; 
1201             if(loopcount < palette_dirs.NumOfDirectories &&
1202                                           loopcount < MAX_NUM_DIRECTORIES)
1203                return(False);
1204             style.count++;
1205             return(True);
1206          }
1207          else {
1208             open_dir = True;
1209 /*
1210 ** get a pointer to the next file entry .. file_descpt
1211 **    the structure for direct looks like:
1212 **       struct direct {
1213 **              long    d_fileno;     #file number of entry
1214 **              short   d_reclen;     #length of this record
1215 **              short   d_namlen;     #length of string in d_name
1216 **              char    d_name[256];  #name 
1217 **            };
1218 */
1219              file_descpt = readdir(dirp);
1220           }
1221       }
1222
1223       while( file_descpt != NULL)
1224       {
1225        /* check for a valid palette file */
1226          if(!(strncmp(PALETTE_SUFFIX, DtStrrchr(file_descpt->d_name, '.'),
1227                                           strlen(PALETTE_SUFFIX)))) 
1228          {
1229 /*
1230 ** A file in the users home palette directory which begins with a ~
1231 ** is a palette that the user doesn't want.  Remove it from
1232 ** the palette link list.
1233 */
1234              if((strcmp(palette_dirs.directories[loopcount],
1235                                               home_palette_dir) == 0) && 
1236                           (strncmp(file_descpt->d_name, "~", 1) == 0) &&
1237                            pHeadPalette != NULL)
1238              {
1239                 CheckForDeletedFile(file_descpt);
1240              }
1241              else if (strncmp(file_descpt->d_name, "~", 1) != 0) 
1242              {
1243                /* make sure if Black and white monitor the file is one that
1244                   can be read for a XmCO_BLACK_WHITE monitor */
1245              if(TypeOfMonitor != XmCO_BLACK_WHITE ) 
1246              { 
1247                 if((fnmatch(file_descpt->d_name, B_O_W, 0) != 0) &&
1248                         (fnmatch(file_descpt->d_name, W_O_B, 0)  !=0 ) &&
1249                         (fnmatch(file_descpt->d_name, W_ONLY, 0) !=0 ) &&
1250                         (fnmatch(file_descpt->d_name, B_ONLY, 0) !=0 ))
1251                    ReadPalette(palette_dirs.directories[loopcount], 
1252                                          file_descpt->d_name,
1253                                          strlen (file_descpt->d_name));
1254               }
1255               else
1256               {
1257                  if((fnmatch(file_descpt->d_name, B_O_W, 0) == 0) ||
1258                         (fnmatch(file_descpt->d_name, W_O_B, 0)  == 0) ||
1259                         (fnmatch(file_descpt->d_name, W_ONLY, 0) == 0) ||
1260                         (fnmatch(file_descpt->d_name, B_ONLY, 0) == 0))
1261                     ReadPalette(palette_dirs.directories[loopcount], 
1262                                          file_descpt->d_name,
1263                                          strlen (file_descpt->d_name));
1264                }
1265            } 
1266
1267       }  /* if valid palette file */
1268
1269      /* read the next file */
1270       file_descpt = readdir(dirp);
1271
1272       if(startup == True)
1273          return(False);
1274
1275       } /* while( file_descpt != NULL) */
1276
1277       closedir(dirp);
1278       open_dir = False;
1279
1280       loopcount++;
1281
1282    } /* while */
1283
1284    style.count++;
1285    return(True);
1286
1287 }