Add GNU LGPL headers to all .c .C and .h files
[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 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 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 occurrance.
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     if (path != NULL)
232         SRV_FREE(path);
233     if (palettePath != NULL)
234         SRV_FREE(palettePath);
235
236     return (paletteDef);
237
238 }
239
240 /************************************************************************
241 **
242 **  FindPalette -
243 **  Open the directory and look for the palette file.
244 **  If found, read in data and return true.
245 **  If not found, return false
246 **
247 ************************************************************************/
248 static Boolean
249 FindPalette( 
250 char *palette,
251 char *directory)
252
253 {
254     DIR  *dirp;
255     struct dirent *file_descpt;
256
257     /* Open the directory */
258     if( (dirp = opendir(directory)) == NULL)
259     {
260        return(False);
261     }
262     else
263     {
264         file_descpt = readdir(dirp);
265     }
266
267     /* cycle through the files in the directory until found a match */
268     while( file_descpt != NULL)
269     {
270         /* check for a palette filename match */
271         if (strcmp(palette, file_descpt->d_name) == 0)
272         {
273             closedir(dirp);
274             return(True);
275         }
276         else 
277         {
278             /* read the next file */
279             file_descpt = readdir(dirp);
280         }
281     } /* while( file_descpt != NULL) */
282
283     closedir(dirp);
284     return (False);
285 }
286
287 /***************************************************************************
288  *
289  * ReadPaletteFile - this routines reads and parses the palette file.
290  *    It fills in the pCurrentPalette structure for the screen_number
291  *    that was passed in. 
292  *
293  *************************************************************************/
294 static struct _palette * 
295 ReadPaletteFile(
296         Display *dpy,
297         int     screen_number,
298         char *palettePath,
299         char *palette )
300 {
301    struct _palette *new_palette;
302    int             fd, nbytes;
303    char            buf[BUFSIZE];
304    char            tmpPalette[BUFSIZE];
305    char            *token1;
306    char            *tmpStr2;
307    char            *tmpStr;
308    char            *fullPath;
309
310    /* 
311     * create full path, don't forget to add 1 for the NULL byte
312     * and 1 for the slash in the format string for sprintf.
313     */
314    fullPath = (char *) SRV_MALLOC (strlen(palettePath) + strlen(palette) + 2);
315    sprintf(fullPath,"%s/%s", palettePath, palette); 
316
317    if( (fd = open( fullPath, O_RDONLY)) == -1)
318    { /* open failed */
319         printf("error opening %s\n",fullPath);
320         SRV_FREE(fullPath);
321         return((struct _palette *) NULL);
322    }
323       
324    /*
325    **  Read a buffer of data ... BUFSIZE == 1024, as long as 
326    **  screen < MAX_NUM_SCREENS (5) then we should never need more. 
327    */
328    nbytes = read(fd, buf, BUFSIZE);
329    if(nbytes == 0 || nbytes == BUFSIZE)  /* A bogus number of bytes */
330    { /* read failed */
331        /*
332         * Don't forget to add 1 for the NULL byte and 2 for the 
333         * period and the newline in the format string for sprintf
334         */
335        tmpStr = (char *)SRV_MALLOC(strlen(MSG2) + strlen(fullPath) + 3);
336        sprintf(tmpStr,"%s%s.\n", MSG2, palettePath); 
337        _DtSimpleError(XmSCOLOR_SRV_NAME, DtWarning, NULL, tmpStr, NULL); 
338        SRV_FREE(tmpStr);
339        SRV_FREE(fullPath);
340        close(fd);
341        return((struct _palette *) NULL);
342    }
343    else 
344    { /* read suceeded */
345       /* Allocate space for this new palette. */
346       new_palette = (palettes *)SRV_MALLOC( sizeof(struct _palette) + 1 );
347
348       /*  allocate enough space for the name */
349       strcpy(tmpPalette, palette); 
350       for (token1=tmpPalette; *token1; token1++);
351       while (token1!=tmpPalette && *token1!='.') token1--;
352       if (!strcmp(token1,PALETTE_SUFFIX)) *token1 = '\0';
353       new_palette->name = (char *)SRV_MALLOC(strlen(tmpPalette) + 1);
354       strcpy(new_palette->name, (char *) tmpPalette);
355
356       new_palette->converted = NULL;
357       new_palette->converted_len = 0L;
358
359       /* set the next pointer to NULL*/
360       new_palette->next = NULL;
361
362       if (ParsePaletteInfo(dpy, screen_number, buf, nbytes, new_palette) == -1)
363       {
364         /* palette file is bad */
365          tmpStr = (char *)SRV_MALLOC(strlen(MSG3) + strlen(MSG3a) + strlen(palettePath) +1);
366          tmpStr2 = (char *)SRV_MALLOC(strlen(MSG3)+1);
367          sprintf(tmpStr2,"%s", MSG3); 
368          sprintf(tmpStr,"%s%s%s", tmpStr2, palettePath, MSG3a); 
369          _DtSimpleError(XmSCOLOR_SRV_NAME, DtWarning, NULL, tmpStr, NULL); 
370          SRV_FREE(tmpStr);
371          SRV_FREE(tmpStr2);
372          error_value = 1;
373          unlink(palettePath);
374          SRV_FREE(fullPath);
375          return((struct _palette *) NULL);
376       }
377    }
378
379    /* close the file */
380    close(fd);
381    SRV_FREE(fullPath);
382
383    return(new_palette);
384 }
385
386 /***********************************************************************
387  *
388  * ParsePaletteInfo - This routine reads from the buffer(buf) the 
389  *      actual data into the new_palette.  It reads in the bg colors
390  *      then uses the XmCalculateColorRGB to generate the ts, bs, and sc 
391  *      colors.  This routine doesn't allocate any pixel numbers but
392  *      does generate the RGB values for each color in a palette.
393  *
394  ***********************************************************************/
395 static int 
396 ParsePaletteInfo(
397         Display *dpy,
398         int screen_num,
399         char *buf,
400         int nbytes,
401         struct _palette *new_palette )
402 {
403    char            tmpbuf[BUFSIZE];
404    int             count;
405    int             num_of_colors;
406    int             result;
407    XColor          tmp_color;
408    int             buf_count;
409    static XmColorProc   calcRGB = NULL;
410
411    num_of_colors = new_palette->num_of_colors = 0;
412
413    if(colorSrv.TypeOfMonitor[screen_num] != XmCO_BLACK_WHITE)
414       if((strcmp(new_palette->name, W_O_B)) == 0 || 
415                             (strcmp(new_palette->name, B_O_W)) == 0  ||
416                             (strcmp(new_palette->name, W_ONLY)) == 0 ||
417                             (strcmp(new_palette->name, B_ONLY)) == 0) 
418          return(-1);
419
420    buf_count = 0;
421   /* read in background colors until end of file */
422    while(buf_count < nbytes && buf[buf_count] != '!')
423    {
424       count = 0;
425
426      /* read in a BG color */
427       while(buf[buf_count] != '\012')
428          tmpbuf[count++] = buf[buf_count++];
429       tmpbuf[count++] = '\0';
430       buf_count++;
431
432       /* get the RGB value (XColor) of the background */
433       result = XParseColor(dpy, DefaultColormap(dpy, screen_num),
434                                                   tmpbuf, &tmp_color);
435       /* there was an error */
436       if(result == 0)
437           return(-1);
438
439       new_palette->color[num_of_colors].bg.red = tmp_color.red;
440       new_palette->color[num_of_colors].bg.blue = tmp_color.blue;
441       new_palette->color[num_of_colors].bg.green = tmp_color.green;
442    
443 /*
444 ** Now lets generate all the colors which go along with this bg i.e. ts,
445 ** fg, bs, and sc.
446 */
447       if (calcRGB == NULL) calcRGB = XmGetColorCalculation();
448       (*calcRGB)(&tmp_color,
449                                 &(new_palette->color[num_of_colors].fg),
450                                 &(new_palette->color[num_of_colors].sc),
451                                 &(new_palette->color[num_of_colors].ts),
452                                 &(new_palette->color[num_of_colors].bs));
453
454       if(colorSrv.TypeOfMonitor[screen_num] == XmCO_BLACK_WHITE)
455           InitializeBW(tmp_color.red, num_of_colors, new_palette);
456
457       else /* Not Black and White */
458       {
459          if(colorSrv.UsePixmaps[screen_num] == TRUE)
460          {
461            /* the values generated by XmCalculateColorRBG are invalid */
462             new_palette->color[num_of_colors].ts.red = 65535; 
463             new_palette->color[num_of_colors].ts.blue = 65535;
464             new_palette->color[num_of_colors].ts.green = 65535;
465
466             new_palette->color[num_of_colors].bs.red = 0;
467             new_palette->color[num_of_colors].bs.blue = 0;
468             new_palette->color[num_of_colors].bs.green = 0;
469          }
470
471          if(colorSrv.FgColor[screen_num] != DYNAMIC)
472          {
473              if(colorSrv.FgColor[screen_num] == BLACK)
474              {
475                 new_palette->color[num_of_colors].fg.red = 0;
476                 new_palette->color[num_of_colors].fg.blue = 0;
477                 new_palette->color[num_of_colors].fg.green = 0;
478              }
479              else /* colorSrv.FgColor[screen_num] == WHITE */
480              {
481                 new_palette->color[num_of_colors].fg.red = 65535;
482                 new_palette->color[num_of_colors].fg.blue = 65535;
483                 new_palette->color[num_of_colors].fg.green = 65535;
484              }
485          }
486       } /* else Not Black and White */
487
488       num_of_colors++;
489       new_palette->num_of_colors++;
490     
491       if(colorSrv.TypeOfMonitor[screen_num] == XmCO_BLACK_WHITE)
492          if( new_palette->num_of_colors == 2)
493            break;
494
495       if(colorSrv.TypeOfMonitor[screen_num] == XmCO_LOW_COLOR || 
496          colorSrv.TypeOfMonitor[screen_num] == XmCO_MEDIUM_COLOR)
497          if( new_palette->num_of_colors == 4)
498            break;
499
500    } /* while */
501    if(colorSrv.TypeOfMonitor[screen_num] == XmCO_LOW_COLOR) 
502    {
503       new_palette->num_of_colors = 2;
504       SwitchAItoPS(new_palette);
505    }
506    return(0);
507 }
508
509 /***********************************************************************
510  *
511  * InitializeBW - the type of monitor is a black and white, so
512  *      initialize the colors to black and white.  If the color passed
513  *      in is 0 (black) set everything to 65535 (white). Otherwise
514  *      set everything to 0 (black).
515  *
516  ***********************************************************************/
517 static void 
518 InitializeBW(
519         unsigned long color,
520         int num_of_colors,
521         struct _palette *new_palette )
522 {
523    if(color == 0L)
524    {
525       new_palette->color[num_of_colors].fg.red = 65535;
526       new_palette->color[num_of_colors].fg.blue = 65535;
527       new_palette->color[num_of_colors].fg.green = 65535;
528
529       new_palette->color[num_of_colors].ts.red = 65535;
530       new_palette->color[num_of_colors].ts.blue = 65535;
531       new_palette->color[num_of_colors].ts.green = 65535;
532
533       new_palette->color[num_of_colors].bs.red = 65535;
534       new_palette->color[num_of_colors].bs.blue = 65535;
535       new_palette->color[num_of_colors].bs.green = 65535;
536
537       new_palette->color[num_of_colors].sc.red = 0;
538       new_palette->color[num_of_colors].sc.blue = 0;
539       new_palette->color[num_of_colors].sc.green = 0;
540    }
541    else
542    {
543       new_palette->color[num_of_colors].fg.red = 0;
544       new_palette->color[num_of_colors].fg.blue = 0;
545       new_palette->color[num_of_colors].fg.green = 0;
546
547       new_palette->color[num_of_colors].ts.red = 0;
548       new_palette->color[num_of_colors].ts.blue = 0;
549       new_palette->color[num_of_colors].ts.green = 0;
550
551       new_palette->color[num_of_colors].bs.red = 0;
552       new_palette->color[num_of_colors].bs.blue = 0;
553       new_palette->color[num_of_colors].bs.green = 0;
554
555       new_palette->color[num_of_colors].sc.red = 65535;
556       new_palette->color[num_of_colors].sc.blue = 65535;
557       new_palette->color[num_of_colors].sc.green = 65535;
558    }
559 }
560
561 void 
562 SwitchAItoPS(
563         struct _palette *new_palette )
564 {
565    new_palette->color[0].bg.red = new_palette->color[3].bg.red;
566    new_palette->color[0].bg.green = new_palette->color[3].bg.green;
567    new_palette->color[0].bg.blue = new_palette->color[3].bg.blue;
568
569    new_palette->color[0].fg.red = new_palette->color[3].fg.red;
570    new_palette->color[0].fg.green = new_palette->color[3].fg.green;
571    new_palette->color[0].fg.blue = new_palette->color[3].fg.blue;
572
573    new_palette->color[0].ts.red = new_palette->color[3].ts.red;
574    new_palette->color[0].ts.green = new_palette->color[3].ts.green;
575    new_palette->color[0].ts.blue = new_palette->color[3].ts.blue;
576
577    new_palette->color[0].bs.red = new_palette->color[3].bs.red;
578    new_palette->color[0].bs.green = new_palette->color[3].bs.green;
579    new_palette->color[0].bs.blue = new_palette->color[3].bs.blue;
580
581    new_palette->color[0].sc.red = new_palette->color[3].sc.red;
582    new_palette->color[0].sc.green = new_palette->color[3].sc.green;
583    new_palette->color[0].sc.blue = new_palette->color[3].sc.blue;
584
585    new_palette->color[1].bg.red = new_palette->color[2].bg.red;
586    new_palette->color[1].bg.green = new_palette->color[2].bg.green;
587    new_palette->color[1].bg.blue = new_palette->color[2].bg.blue;
588
589    new_palette->color[1].fg.red = new_palette->color[2].fg.red;
590    new_palette->color[1].fg.green = new_palette->color[2].fg.green;
591    new_palette->color[1].fg.blue = new_palette->color[2].fg.blue;
592
593    new_palette->color[1].ts.red = new_palette->color[2].ts.red;
594    new_palette->color[1].ts.green = new_palette->color[2].ts.green;
595    new_palette->color[1].ts.blue = new_palette->color[2].ts.blue;
596
597    new_palette->color[1].bs.red = new_palette->color[2].bs.red;
598    new_palette->color[1].bs.green = new_palette->color[2].bs.green;
599    new_palette->color[1].bs.blue = new_palette->color[2].bs.blue;
600
601    new_palette->color[1].sc.red = new_palette->color[2].sc.red;
602    new_palette->color[1].sc.green = new_palette->color[2].sc.green;
603    new_palette->color[1].sc.blue = new_palette->color[2].sc.blue;
604
605 }
606
607 /***********************************************************************
608  *
609  * SaveDefaultPalette - used to save the palette.dt file to 
610  *         either $HOME/.dt/$DISPLAY/current or $HOME/.dt/$DISPLAY/home.
611  *         The parameter mode determines whether it is home or
612  *         current.  
613  *
614  ***********************************************************************/
615 void 
616 SaveDefaultPalette(
617         Display *dpy,
618         char *dtPath,
619         int mode )
620 {
621 }