dtpad: emit error on catopen() failure
[oweals/cde.git] / cde / programs / dtsession / SrvFile_io.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*
24 static char rcsid[] =
25   "$XConsortium: SrvFile_io.c /main/8 1996/09/25 09:41:53 barstow $";
26 */
27 /*                                                                      *
28  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
29  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
30  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
31  * (c) Copyright 1993, 1994 Novell, Inc.                                *
32  */
33
34 /*****************************************************************************
35  *****************************************************************************
36  **
37  **  File:        SrvFile_io.c
38  **
39  **  Project:     HP DT Style Manager (integrated into dtsession)
40  **
41  **  Description:
42  **  -----------
43  **       This file initializes the user specified ( or default) palette
44  **       for this session.
45  **
46  *******************************************************************
47  **  (c) Copyright Hewlett-Packard Company, 1990.  All rights are  
48  **  reserved.  Copying or other reproduction of this program      
49  **  except for archival purposes is prohibited without prior      
50  **  written consent of Hewlett-Packard Company.                     
51  ********************************************************************
52  **
53  **
54  **
55  *****************************************************************************
56  *************************************<+>*************************************/
57 /* #includes */
58
59 #include <fcntl.h>
60 #include "Srv.h"
61 #include "SrvFile_io.h"
62
63 /* #defines */
64
65 #define BUFSIZE              1024
66
67 #define MSG2  ((char *)GETMESSAGE(28, 3, "Color Server Warning, the size of file is invalid: ")) 
68 #define MSG3  ((char *)GETMESSAGE(28, 4, "Color Server Warning, invalid information in '"))
69 #define MSG3a ((char *)GETMESSAGE(28, 5, "' removing file and starting again.\n"))
70
71 /* Static Function Declarations */
72
73
74 static Boolean FindPalette( 
75                         char *palette,
76                         char *directory) ;
77 static struct _palette* ReadPaletteFile( 
78                         Display *dpy,
79                         int     screen_number,
80                         char *palettePath,
81                         char *palette) ;
82 static int ParsePaletteInfo( 
83                         Display *dpy,
84                         int numDisplay,
85                         char *buf,
86                         int nbytes,
87                         struct _palette *new_palette) ;
88 static void InitializeBW( 
89                         unsigned long color,
90                         int num_of_colors,
91                         struct _palette *new_palette) ;
92
93 /* static variables */
94
95 static int error_value;
96
97 #define HOME               "HOME"
98 #define USER_PALETTE_DIR   "/.dt/palettes"
99 #define SYSTEM_PALETTE_DIR CDE_INSTALLATION_TOP "/palettes"
100 #define CONFIG_PALETTE_DIR CDE_CONFIGURATION_TOP "/palettes"
101 #define DEFAULT_PALETTE    "Default.dp"
102
103
104 /************************************************************************
105 **
106 ** GetPaletteDefinition -
107 **  Query the database for the Dtstyle.paletteDirectories resource
108 **  Use Dtstyle default (Default) if not specified.
109 **  Search the directories for the palette in reverse order
110 **
111 ************************************************************************/
112 struct _palette * 
113 GetPaletteDefinition( 
114 Display *dpy,
115 int     screen_number,
116 char    *palette)
117
118 {
119     struct _palette *paletteDef;
120     char *str_type_return;
121     XrmValue value_return;
122     XrmDatabase db;
123     Boolean match = False;
124     char *palettePath;
125     char *path;
126     char *p, *d;
127     char *home;
128     char dir[256];
129                     
130
131     if (FindPalette (palette, SYSTEM_PALETTE_DIR))
132     {
133        /* 
134         * First look for palette in the system location
135         */
136         palettePath = (char *) SRV_MALLOC (strlen(SYSTEM_PALETTE_DIR) + 1 );
137         strcpy(palettePath, SYSTEM_PALETTE_DIR);
138         match = True;
139     }
140     else if (FindPalette (palette, CONFIG_PALETTE_DIR))
141     {
142        /* 
143         * Next check the local config location
144         */
145         palettePath = (char *) SRV_MALLOC (strlen(CONFIG_PALETTE_DIR) + 1 );
146         strcpy(palettePath, CONFIG_PALETTE_DIR);
147         match = True;
148     }
149     else 
150     {
151         palettePath = NULL;
152     }
153
154     /*  Get Dtstyle.paletteDirectories value */
155     db = XtDatabase(dpy);
156     if (XrmGetResource (db, "dtstyle.paletteDirectories",
157                             "Dtstyle.PaletteDirectories",
158                             &str_type_return, &value_return))
159     {
160         /* Make Local Copy of string */
161         path = (char *) SRV_MALLOC( value_return.size + 1 );
162         strcpy (path, value_return.addr);
163     }
164     else 
165     {
166         path = NULL;
167     }
168
169     /* Look for palette in paletteDirectories */
170     if (path != NULL)
171     {
172         /* Loop through paletteDirectories looking in each directory
173          * till we find the palette file. Take first occurrence.
174          * Copy directory name into dir.  Look for NULL or space 
175          */
176
177         p = path;
178         while (*p != '\0')
179         {
180             d = dir;
181             while (*p != ' ' && *p != '\0')
182                 *d++ = *p++;
183             *d = '\0';
184             if (FindPalette (palette, dir))
185             {
186                 palettePath = (char *)SRV_REALLOC(palettePath, 
187                                                 strlen(SYSTEM_PALETTE_DIR) + 1);
188                 strcpy(palettePath, dir);
189                 match = True;
190                 break;
191             }
192         }
193     }
194         
195     /* Look for palette in $HOME/.dt/palettes */
196     /* If there is a duplicate, take it */
197
198     if ((home=getenv(HOME)) == NULL)
199       home="";
200     path = (char *) SRV_REALLOC (path, 
201         strlen(home) + strlen(USER_PALETTE_DIR) + 1);
202     strcpy(path, home);
203     strcat(path, USER_PALETTE_DIR);
204
205     if (FindPalette (palette, path))
206     {
207         palettePath = (char *) SRV_REALLOC (palettePath, strlen(path) + 1 );
208         strcpy(palettePath, path);
209         match = True;
210     }
211     
212     if (match)
213     {
214         /* Parse the data from the palette file */
215         paletteDef = (struct _palette *) ReadPaletteFile(dpy, 
216                                                          screen_number, 
217                                                          palettePath,
218                                                          palette);
219     } 
220     else /* default to system Default */
221     {
222         palettePath = (char *) SRV_REALLOC (palettePath,
223                                             strlen(SYSTEM_PALETTE_DIR) + 1);
224         strcpy(palettePath, SYSTEM_PALETTE_DIR);
225         paletteDef = (struct _palette *)ReadPaletteFile(dpy, 
226                                                         screen_number, 
227                                                         palettePath,
228                                                         DEFAULT_PALETTE);
229     }
230
231     SRV_FREE(path);
232     SRV_FREE(palettePath);
233
234     return (paletteDef);
235
236 }
237
238 /************************************************************************
239 **
240 **  FindPalette -
241 **  Open the directory and look for the palette file.
242 **  If found, read in data and return true.
243 **  If not found, return false
244 **
245 ************************************************************************/
246 static Boolean
247 FindPalette( 
248 char *palette,
249 char *directory)
250
251 {
252     DIR  *dirp;
253     struct dirent *file_descpt;
254
255     /* Open the directory */
256     if( (dirp = opendir(directory)) == NULL)
257     {
258        return(False);
259     }
260     else
261     {
262         file_descpt = readdir(dirp);
263     }
264
265     /* cycle through the files in the directory until found a match */
266     while( file_descpt != NULL)
267     {
268         /* check for a palette filename match */
269         if (strcmp(palette, file_descpt->d_name) == 0)
270         {
271             closedir(dirp);
272             return(True);
273         }
274         else 
275         {
276             /* read the next file */
277             file_descpt = readdir(dirp);
278         }
279     } /* while( file_descpt != NULL) */
280
281     closedir(dirp);
282     return (False);
283 }
284
285 /***************************************************************************
286  *
287  * ReadPaletteFile - this routines reads and parses the palette file.
288  *    It fills in the pCurrentPalette structure for the screen_number
289  *    that was passed in. 
290  *
291  *************************************************************************/
292 static struct _palette * 
293 ReadPaletteFile(
294         Display *dpy,
295         int     screen_number,
296         char *palettePath,
297         char *palette )
298 {
299    struct _palette *new_palette;
300    int             fd, nbytes;
301    char            buf[BUFSIZE];
302    char            tmpPalette[BUFSIZE];
303    char            *token1;
304    char            *tmpStr2;
305    char            *tmpStr;
306    char            *fullPath;
307
308    /* 
309     * create full path, don't forget to add 1 for the NULL byte
310     * and 1 for the slash in the format string for sprintf.
311     */
312    fullPath = (char *) SRV_MALLOC (strlen(palettePath) + strlen(palette) + 2);
313    sprintf(fullPath,"%s/%s", palettePath, palette); 
314
315    if( (fd = open( fullPath, O_RDONLY)) == -1)
316    { /* open failed */
317         printf("error opening %s\n",fullPath);
318         SRV_FREE(fullPath);
319         return((struct _palette *) NULL);
320    }
321       
322    /*
323    **  Read a buffer of data ... BUFSIZE == 1024, as long as 
324    **  screen < MAX_NUM_SCREENS (5) then we should never need more. 
325    */
326    nbytes = read(fd, buf, BUFSIZE);
327    if(nbytes == 0 || nbytes == BUFSIZE)  /* A bogus number of bytes */
328    { /* read failed */
329        /*
330         * Don't forget to add 1 for the NULL byte and 2 for the 
331         * period and the newline in the format string for sprintf
332         */
333        tmpStr = (char *)SRV_MALLOC(strlen(MSG2) + strlen(fullPath) + 3);
334        sprintf(tmpStr,"%s%s.\n", MSG2, palettePath); 
335        _DtSimpleError(XmSCOLOR_SRV_NAME, DtWarning, NULL, tmpStr, NULL); 
336        SRV_FREE(tmpStr);
337        SRV_FREE(fullPath);
338        close(fd);
339        return((struct _palette *) NULL);
340    }
341    else 
342    { /* read suceeded */
343       /* Allocate space for this new palette. */
344       new_palette = (palettes *)SRV_MALLOC( sizeof(struct _palette) + 1 );
345
346       /*  allocate enough space for the name */
347       strcpy(tmpPalette, palette); 
348       for (token1=tmpPalette; *token1; token1++);
349       while (token1!=tmpPalette && *token1!='.') token1--;
350       if (!strcmp(token1,PALETTE_SUFFIX)) *token1 = '\0';
351       new_palette->name = (char *)SRV_MALLOC(strlen(tmpPalette) + 1);
352       strcpy(new_palette->name, (char *) tmpPalette);
353
354       new_palette->converted = NULL;
355       new_palette->converted_len = 0L;
356
357       /* set the next pointer to NULL*/
358       new_palette->next = NULL;
359
360       if (ParsePaletteInfo(dpy, screen_number, buf, nbytes, new_palette) == -1)
361       {
362         /* palette file is bad */
363          tmpStr = (char *)SRV_MALLOC(strlen(MSG3) + strlen(MSG3a) + strlen(palettePath) +1);
364          tmpStr2 = (char *)SRV_MALLOC(strlen(MSG3)+1);
365          sprintf(tmpStr2,"%s", MSG3); 
366          sprintf(tmpStr,"%s%s%s", tmpStr2, palettePath, MSG3a); 
367          _DtSimpleError(XmSCOLOR_SRV_NAME, DtWarning, NULL, tmpStr, NULL); 
368          SRV_FREE(tmpStr);
369          SRV_FREE(tmpStr2);
370          error_value = 1;
371          unlink(palettePath);
372          SRV_FREE(fullPath);
373          close(fd);
374          return((struct _palette *) NULL);
375       }
376    }
377
378    /* close the file */
379    close(fd);
380    SRV_FREE(fullPath);
381
382    return(new_palette);
383 }
384
385 /***********************************************************************
386  *
387  * ParsePaletteInfo - This routine reads from the buffer(buf) the 
388  *      actual data into the new_palette.  It reads in the bg colors
389  *      then uses the XmCalculateColorRGB to generate the ts, bs, and sc 
390  *      colors.  This routine doesn't allocate any pixel numbers but
391  *      does generate the RGB values for each color in a palette.
392  *
393  ***********************************************************************/
394 static int 
395 ParsePaletteInfo(
396         Display *dpy,
397         int screen_num,
398         char *buf,
399         int nbytes,
400         struct _palette *new_palette )
401 {
402    char            tmpbuf[BUFSIZE];
403    int             count;
404    int             num_of_colors;
405    int             result;
406    XColor          tmp_color;
407    int             buf_count;
408    static XmColorProc   calcRGB = NULL;
409
410    num_of_colors = new_palette->num_of_colors = 0;
411
412    if(colorSrv.TypeOfMonitor[screen_num] != XmCO_BLACK_WHITE)
413       if((strcmp(new_palette->name, W_O_B)) == 0 || 
414                             (strcmp(new_palette->name, B_O_W)) == 0  ||
415                             (strcmp(new_palette->name, W_ONLY)) == 0 ||
416                             (strcmp(new_palette->name, B_ONLY)) == 0) 
417          return(-1);
418
419    buf_count = 0;
420   /* read in background colors until end of file */
421    while(buf_count < nbytes && buf[buf_count] != '!')
422    {
423       count = 0;
424
425      /* read in a BG color */
426       while(buf[buf_count] != '\012')
427          tmpbuf[count++] = buf[buf_count++];
428       tmpbuf[count++] = '\0';
429       buf_count++;
430
431       /* get the RGB value (XColor) of the background */
432       result = XParseColor(dpy, DefaultColormap(dpy, screen_num),
433                                                   tmpbuf, &tmp_color);
434       /* there was an error */
435       if(result == 0)
436           return(-1);
437
438       new_palette->color[num_of_colors].bg.red = tmp_color.red;
439       new_palette->color[num_of_colors].bg.blue = tmp_color.blue;
440       new_palette->color[num_of_colors].bg.green = tmp_color.green;
441    
442 /*
443 ** Now lets generate all the colors which go along with this bg i.e. ts,
444 ** fg, bs, and sc.
445 */
446       if (calcRGB == NULL) calcRGB = XmGetColorCalculation();
447       (*calcRGB)(&tmp_color,
448                                 &(new_palette->color[num_of_colors].fg),
449                                 &(new_palette->color[num_of_colors].sc),
450                                 &(new_palette->color[num_of_colors].ts),
451                                 &(new_palette->color[num_of_colors].bs));
452
453       if(colorSrv.TypeOfMonitor[screen_num] == XmCO_BLACK_WHITE)
454           InitializeBW(tmp_color.red, num_of_colors, new_palette);
455
456       else /* Not Black and White */
457       {
458          if(colorSrv.UsePixmaps[screen_num] == TRUE)
459          {
460            /* the values generated by XmCalculateColorRBG are invalid */
461             new_palette->color[num_of_colors].ts.red = 65535; 
462             new_palette->color[num_of_colors].ts.blue = 65535;
463             new_palette->color[num_of_colors].ts.green = 65535;
464
465             new_palette->color[num_of_colors].bs.red = 0;
466             new_palette->color[num_of_colors].bs.blue = 0;
467             new_palette->color[num_of_colors].bs.green = 0;
468          }
469
470          if(colorSrv.FgColor[screen_num] != DYNAMIC)
471          {
472              if(colorSrv.FgColor[screen_num] == BLACK)
473              {
474                 new_palette->color[num_of_colors].fg.red = 0;
475                 new_palette->color[num_of_colors].fg.blue = 0;
476                 new_palette->color[num_of_colors].fg.green = 0;
477              }
478              else /* colorSrv.FgColor[screen_num] == WHITE */
479              {
480                 new_palette->color[num_of_colors].fg.red = 65535;
481                 new_palette->color[num_of_colors].fg.blue = 65535;
482                 new_palette->color[num_of_colors].fg.green = 65535;
483              }
484          }
485       } /* else Not Black and White */
486
487       num_of_colors++;
488       new_palette->num_of_colors++;
489     
490       if(colorSrv.TypeOfMonitor[screen_num] == XmCO_BLACK_WHITE)
491          if( new_palette->num_of_colors == 2)
492            break;
493
494       if(colorSrv.TypeOfMonitor[screen_num] == XmCO_LOW_COLOR || 
495          colorSrv.TypeOfMonitor[screen_num] == XmCO_MEDIUM_COLOR)
496          if( new_palette->num_of_colors == 4)
497            break;
498
499    } /* while */
500    if(colorSrv.TypeOfMonitor[screen_num] == XmCO_LOW_COLOR) 
501    {
502       new_palette->num_of_colors = 2;
503       SwitchAItoPS(new_palette);
504    }
505    return(0);
506 }
507
508 /***********************************************************************
509  *
510  * InitializeBW - the type of monitor is a black and white, so
511  *      initialize the colors to black and white.  If the color passed
512  *      in is 0 (black) set everything to 65535 (white). Otherwise
513  *      set everything to 0 (black).
514  *
515  ***********************************************************************/
516 static void 
517 InitializeBW(
518         unsigned long color,
519         int num_of_colors,
520         struct _palette *new_palette )
521 {
522    if(color == 0L)
523    {
524       new_palette->color[num_of_colors].fg.red = 65535;
525       new_palette->color[num_of_colors].fg.blue = 65535;
526       new_palette->color[num_of_colors].fg.green = 65535;
527
528       new_palette->color[num_of_colors].ts.red = 65535;
529       new_palette->color[num_of_colors].ts.blue = 65535;
530       new_palette->color[num_of_colors].ts.green = 65535;
531
532       new_palette->color[num_of_colors].bs.red = 65535;
533       new_palette->color[num_of_colors].bs.blue = 65535;
534       new_palette->color[num_of_colors].bs.green = 65535;
535
536       new_palette->color[num_of_colors].sc.red = 0;
537       new_palette->color[num_of_colors].sc.blue = 0;
538       new_palette->color[num_of_colors].sc.green = 0;
539    }
540    else
541    {
542       new_palette->color[num_of_colors].fg.red = 0;
543       new_palette->color[num_of_colors].fg.blue = 0;
544       new_palette->color[num_of_colors].fg.green = 0;
545
546       new_palette->color[num_of_colors].ts.red = 0;
547       new_palette->color[num_of_colors].ts.blue = 0;
548       new_palette->color[num_of_colors].ts.green = 0;
549
550       new_palette->color[num_of_colors].bs.red = 0;
551       new_palette->color[num_of_colors].bs.blue = 0;
552       new_palette->color[num_of_colors].bs.green = 0;
553
554       new_palette->color[num_of_colors].sc.red = 65535;
555       new_palette->color[num_of_colors].sc.blue = 65535;
556       new_palette->color[num_of_colors].sc.green = 65535;
557    }
558 }
559
560 void 
561 SwitchAItoPS(
562         struct _palette *new_palette )
563 {
564    new_palette->color[0].bg.red = new_palette->color[3].bg.red;
565    new_palette->color[0].bg.green = new_palette->color[3].bg.green;
566    new_palette->color[0].bg.blue = new_palette->color[3].bg.blue;
567
568    new_palette->color[0].fg.red = new_palette->color[3].fg.red;
569    new_palette->color[0].fg.green = new_palette->color[3].fg.green;
570    new_palette->color[0].fg.blue = new_palette->color[3].fg.blue;
571
572    new_palette->color[0].ts.red = new_palette->color[3].ts.red;
573    new_palette->color[0].ts.green = new_palette->color[3].ts.green;
574    new_palette->color[0].ts.blue = new_palette->color[3].ts.blue;
575
576    new_palette->color[0].bs.red = new_palette->color[3].bs.red;
577    new_palette->color[0].bs.green = new_palette->color[3].bs.green;
578    new_palette->color[0].bs.blue = new_palette->color[3].bs.blue;
579
580    new_palette->color[0].sc.red = new_palette->color[3].sc.red;
581    new_palette->color[0].sc.green = new_palette->color[3].sc.green;
582    new_palette->color[0].sc.blue = new_palette->color[3].sc.blue;
583
584    new_palette->color[1].bg.red = new_palette->color[2].bg.red;
585    new_palette->color[1].bg.green = new_palette->color[2].bg.green;
586    new_palette->color[1].bg.blue = new_palette->color[2].bg.blue;
587
588    new_palette->color[1].fg.red = new_palette->color[2].fg.red;
589    new_palette->color[1].fg.green = new_palette->color[2].fg.green;
590    new_palette->color[1].fg.blue = new_palette->color[2].fg.blue;
591
592    new_palette->color[1].ts.red = new_palette->color[2].ts.red;
593    new_palette->color[1].ts.green = new_palette->color[2].ts.green;
594    new_palette->color[1].ts.blue = new_palette->color[2].ts.blue;
595
596    new_palette->color[1].bs.red = new_palette->color[2].bs.red;
597    new_palette->color[1].bs.green = new_palette->color[2].bs.green;
598    new_palette->color[1].bs.blue = new_palette->color[2].bs.blue;
599
600    new_palette->color[1].sc.red = new_palette->color[2].sc.red;
601    new_palette->color[1].sc.green = new_palette->color[2].sc.green;
602    new_palette->color[1].sc.blue = new_palette->color[2].sc.blue;
603
604 }
605
606 /***********************************************************************
607  *
608  * SaveDefaultPalette - used to save the palette.dt file to 
609  *         either $HOME/.dt/$DISPLAY/current or $HOME/.dt/$DISPLAY/home.
610  *         The parameter mode determines whether it is home or
611  *         current.  
612  *
613  ***********************************************************************/
614 void 
615 SaveDefaultPalette(
616         Display *dpy,
617         char *dtPath,
618         int mode )
619 {
620 }