a1a4270fd3c76791f6c6622dc82b147d8a387e08
[alexxy/gromacs.git] / src / ngmx / g_showcol.c
1 /*
2  * 
3  *                This source code is part of
4  * 
5  *                 G   R   O   M   A   C   S
6  * 
7  *          GROningen MAchine for Chemical Simulations
8  * 
9  *                        VERSION 3.2.0
10  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12  * Copyright (c) 2001-2004, The GROMACS development team,
13  * check out http://www.gromacs.org for more information.
14
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  * 
20  * If you want to redistribute modifications, please consider that
21  * scientific software is very special. Version control is crucial -
22  * bugs must be traceable. We will be happy to consider code for
23  * inclusion in the official distribution, but derived work must not
24  * be called official GROMACS. Details are found in the README & COPYING
25  * files - if they are missing, get the official version at www.gromacs.org.
26  * 
27  * To help us fund GROMACS development, we humbly ask that you cite
28  * the papers on the package - you can find them in the top README file.
29  * 
30  * For more info, check our website at http://www.gromacs.org
31  * 
32  * And Hey:
33  * Gyas ROwers Mature At Cryogenic Speed
34  */
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include <math.h>
40 #include <smalloc.h>
41 #include <sysstuff.h>
42 #include <string2.h>
43 #include <Xstuff.h>
44 #include "xutil.h"
45 #include "futil.h"
46
47 typedef struct {
48   XColor    xc;
49   t_windata wd;
50 } t_col;
51
52 typedef struct {
53   t_windata wd;
54   t_windata but;
55   int       ncol;
56   t_col     *col;
57 } t_sc;
58
59 static bool ColCallBack(struct t_x11 *x11,XEvent *event, Window w, void *data)
60 {
61   t_col     *col;
62   XColor    *xc;
63   int       r,g,b;
64   t_windata *wd;
65
66   col=(t_col *)data;
67   xc=&(col->xc);
68   wd=&(col->wd);
69   switch (event->type) {
70   case ButtonPress:
71     r=xc->red >> 8;
72     g=xc->green >> 8;
73     b=xc->blue >> 8;
74     printf("%6d%6d%6d\t\t%-20s\n",r,g,b,wd->text);
75     break;
76   }
77   return FALSE;
78 }
79
80 static bool BCallBack(struct t_x11 *x11,XEvent *event, Window w, void *data)
81 {
82   t_sc  *sc;
83   
84   sc=(t_sc *)data;
85   switch (event->type) {
86   case Expose:
87     XSetForeground(x11->disp,x11->gc,sc->col[sc->ncol-1].xc.pixel);
88     TextInWin(x11,&sc->but,sc->but.text,eXCenter,eYCenter);
89     break;
90   case ConfigureNotify:
91     sc->but.width=event->xconfigure.width;
92     sc->but.height=event->xconfigure.height;
93     break;
94   case EnterNotify:
95     LightBorder(x11->disp,sc->but.self,sc->col[sc->ncol-1].xc.pixel);
96     break;
97   case LeaveNotify:
98     LightBorder(x11->disp,sc->but.self,sc->col[0].xc.pixel);
99     break;
100   case ButtonPress:
101     x11->UnRegisterCallback(x11,sc->wd.self);
102     x11->UnRegisterCallback(x11,sc->but.self);
103     return TRUE;
104   }
105   return FALSE;
106 }
107
108 static bool scCallBack(struct t_x11 *x11,XEvent *event, Window w, void *data)
109 {
110   t_sc  *sc;
111   int   i;
112   int   nx,ny,X,Y,Dx,Dy,th;
113   float x,y,dx,dy;
114   
115   th=XTextHeight(x11->font)+6;
116   sc=(t_sc *)data;
117   switch (event->type) {
118   case ConfigureNotify:
119     x=sc->wd.width=event->xconfigure.width;
120     y=sc->wd.height=event->xconfigure.height-th;
121     if ((x >= 100) && (y >= 100)) {
122 #ifdef DEBUG
123       printf("Disp: %x, But: %x, Font: %x x: %d, th: %d\n",
124              x11->disp,sc->but.self,x11->font,(int)x,th);
125 #endif
126       XResizeWindow(x11->disp,sc->but.self,(int)x-4,th-4);
127       nx=sqrt(sc->ncol);
128       ny=sc->ncol/nx;
129       while (nx*ny < sc->ncol)
130         ny++;
131       dx=((float)x) / nx;
132       dy=((float)y) / ny;
133       for(i=0; (i<sc->ncol); i++) {
134         X=x=(i%nx) * dx;
135         Y=y=(i/nx) * dy;
136         Dx=(int)(x+dx)-X;
137         Dy=(int)(y+dy)-Y;
138         XMoveWindow(x11->disp,sc->col[i].wd.self,X,th+Y);
139         XResizeWindow(x11->disp,sc->col[i].wd.self,Dx,Dy);
140       }
141     }
142     break;
143   }
144   return FALSE;
145 }
146
147 static int col_comp(const void *c1,const void *c2)
148 {
149   XColor *x1,*x2;
150   int    dr,dg;
151   int    diff;
152
153   x1=&(((t_col *)c1)->xc);
154   x2=&(((t_col *)c2)->xc);
155
156   /* sort on intensity */
157   diff=(x1->red+x1->green+x1->blue)-(x2->red+x2->green+x2->blue);
158
159   if (diff==0) {
160     if ((dr=(x1->red-x2->red)) != 0)
161       return dr;
162     if ((dg=(x1->green-x2->green)) != 0)
163       return dg;
164     return x1->blue-x2->blue;
165   }
166   else
167     return diff;
168 }
169
170 static void read_col(t_x11 *x11,t_sc *sc,char *rgb)
171 {
172   FILE   *fp;
173   char   buf[STRLEN],name[STRLEN],*dummy;
174   int    i,j;
175   int    r,g,b;
176   XColor xc,exact;
177   t_col  *cols;
178   
179   if ((fp=fopen(rgb,"r"))==NULL) {
180     perror(rgb);
181     exit(1);
182   }
183   do {
184     dummy=NULL;
185     if (fscanf(fp,"%d%d%d",&r,&g,&b)==3) {
186       dummy=fgets2(buf,STRLEN-1,fp);
187       if (dummy) {
188         trim(buf);
189         /* Filter out colours with names of two words */
190         sscanf(buf,"%s",name);
191         /* Filter out duplicate colours (grey and gray) */
192         if (strstr(name,"gray")==0) {
193           if (XAllocNamedColor(x11->disp,x11->cmap,name,&xc,&exact)) {
194             srenew(sc->col,++sc->ncol);
195             sc->col[sc->ncol-1].xc=xc;
196 #ifdef DEBUG
197             printf("color %3d: %s\n",sc->ncol,buf);
198 #endif
199             InitWin(&(sc->col[sc->ncol-1].wd),0,0,1,1,0,name);
200           }
201         }
202       }
203     }
204   } while (dummy);
205   fclose(fp);
206   if (sc->ncol)
207     qsort(sc->col,sc->ncol,sizeof(sc->col[0]),col_comp);
208   /* Now filter out doubles */
209   cols=&(sc->col[0]);
210   for(i=1,j=0; (i<sc->ncol); i++) {
211     if ((cols[i].xc.red   != cols[j].xc.red) ||
212         (cols[i].xc.green != cols[j].xc.green) ||
213         (cols[i].xc.blue  != cols[j].xc.blue)) {
214       j++;
215       cols[j]=cols[i];
216     }
217   }
218   sc->ncol=j;
219 }
220
221 static t_sc *init_sc(t_x11 *x11,Window Parent,char *rgb)
222 {
223   t_sc   *sc;
224   Window w;
225   int    i;
226
227   snew(sc,1);
228   InitWin(&sc->wd,0,0,400,300,1,"Show Colours");
229   sc->wd.self=XCreateSimpleWindow(x11->disp,Parent,sc->wd.x,sc->wd.y,
230                                   sc->wd.width,sc->wd.height,
231                                   sc->wd.bwidth,WHITE,BLACK);
232   x11->RegisterCallback(x11,sc->wd.self,Parent,scCallBack,sc);
233   x11->SetInputMask(x11,sc->wd.self,ButtonPressMask | ExposureMask |
234                     StructureNotifyMask);
235   InitWin(&sc->but,0,0,sc->wd.width-2,XTextHeight(x11->font)+2,1,"Quit");
236   sc->but.self=XCreateSimpleWindow(x11->disp,sc->wd.self,sc->but.x,sc->but.y,
237                                    sc->but.width,sc->but.height,
238                                    sc->but.bwidth,BLACK,BLACK);
239   x11->RegisterCallback(x11,sc->but.self,sc->but.self,BCallBack,sc);
240   x11->SetInputMask(x11,sc->but.self,ButtonPressMask | ExposureMask | 
241                     StructureNotifyMask | EnterWindowMask |
242                     LeaveWindowMask);
243
244   read_col(x11,sc,rgb);
245   fprintf(stderr,"%d colors found\n",sc->ncol);
246   fprintf(stderr,"%6s%6s%6s\t\t%-20s\n","Red","Green","Blue","name");
247   for(i=0; (i<sc->ncol); i++) {
248     sc->col[i].wd.self=w=XCreateSimpleWindow(x11->disp,sc->wd.self,0,0,1,1,0,
249                                              BLACK,sc->col[i].xc.pixel);
250     x11->RegisterCallback(x11,w,sc->wd.self,ColCallBack,&(sc->col[i]));
251     x11->SetInputMask(x11,w,ButtonPressMask);
252   }
253   
254   return sc;
255 }
256
257 int
258 main(int argc, char *argv[])
259 {
260   t_x11 *x11;
261   t_sc  *sc;
262   char  *fn;
263
264   x11=GetX11(&argc,argv);
265   if (argc > 1)
266     fn=argv[1];
267   else
268     fn="/usr/lib/X11/rgb.txt";
269   if (!gmx_fexist(fn)) {
270     fprintf(stderr,"Usage: %s rgb.txt\n",argv[0]);
271     fprintf(stderr,"rgb.txt is usually somewhere in your X windows directories.\n");
272     exit(1);
273   }
274   sc=init_sc(x11,x11->root,fn);
275   XMapWindow(x11->disp,sc->wd.self);
276   XMapSubwindows(x11->disp,sc->wd.self);
277   x11->MainLoop(x11);
278   x11->CleanUp(x11);
279
280   return 0;
281 }