1 /**************************************************************************\
2  *
3  *  This file is part of the Coin 3D visualization library.
4  *  Copyright (C) by Kongsberg Oil & Gas Technologies.
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU General Public License
8  *  ("GPL") version 2 as published by the Free Software Foundation.
9  *  See the file LICENSE.GPL at the root directory of this source
10  *  distribution for additional information about the GNU GPL.
11  *
12  *  For using Coin with software that can not be combined with the GNU
13  *  GPL, and for taking advantage of the additional benefits of our
14  *  support services, please contact Kongsberg Oil & Gas Technologies
15  *  about acquiring a Coin Professional Edition License.
16  *
17  *  See http://www.coin3d.org/ for more information.
18  *
19  *  Kongsberg Oil & Gas Technologies, Bygdoy Alle 5, 0257 Oslo, NORWAY.
20  *  http://www.sim.no/  sales@sim.no  coin-support@coin3d.org
21  *
22 \**************************************************************************/
23 
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif // HAVE_CONFIG_H
27 
28 #include <assert.h>
29 
30 #include <X11/Xlib.h>
31 #include <X11/Xutil.h>
32 #include <X11/Intrinsic.h>
33 
34 #ifdef HAVE_LIBXPM
35 #include <X11/xpm.h>
36 #endif // HAVE_LIBXPM
37 
38 #ifdef HAVE_LIBXMU
39 #include <X11/Xmu/Xmu.h>
40 #include <X11/Xmu/StdCmap.h>
41 #endif // HAVE_LIBXMU
42 
43 #include <Xm/Xm.h>
44 #include <Xm/Form.h>
45 #include <Xm/Frame.h>
46 #include <Xm/Label.h>
47 #include <Xm/LabelG.h>
48 #include <Xm/PushB.h>
49 #include <Xm/ToggleB.h>
50 #include <Xm/DialogS.h>
51 #include <Xm/RowColumn.h>
52 #include <Xm/Text.h>
53 #include <Xm/TextF.h>
54 #include <Xm/Scale.h>
55 
56 #include <soxtdefs.h>
57 #include <Inventor/errors/SoDebugError.h>
58 
59 #include <Inventor/Xt/SoXtInternal.h>
60 #include <Inventor/Xt/SoAny.h>
61 
62 char * SoXtInternal::appname = NULL;
63 char * SoXtInternal::appclass = NULL;
64 
65 // *************************************************************************
66 
67 /*
68   \internal
69 */
70 const char *
xpmErrorString(int error)71 SoXtInternal::xpmErrorString(int error)
72 {
73 #ifdef HAVE_LIBXPM
74   switch (error) {
75   case XpmSuccess:      return "success";
76   case XpmColorError:   return "color error";
77   case XpmOpenFailed:   return "open failed";
78   case XpmFileInvalid:  return "file invalid";
79   case XpmNoMemory:     return "no memory";
80   case XpmColorFailed:  return "color failed";
81   default:              return "<unknown>";
82   }
83 #endif
84   return "no libxpm";
85 }
86 
87 
88 /*
89   \internal
90   Does nothing if libXpm use hasn't been enabled.
91 */
92 Pixmap
createPixmapFromXpm(Widget widget,const char ** xpm,SbBool ghost)93 SoXtInternal::createPixmapFromXpm(Widget widget, const char ** xpm, SbBool ghost)
94 {
95   Pixmap pixels = 0;
96 #if HAVE_LIBXPM
97   Widget shell = widget;
98   while (! XtIsShell(shell) && shell != (Widget) NULL) {
99     shell = XtParent(shell);
100   }
101   assert(shell != (Widget) NULL);
102   Display * dpy = XtDisplay(shell);
103 
104   XpmAttributes attrs;
105   attrs.visual = NULL;
106   attrs.colormap = 0;
107   attrs.depth = 0;
108 
109   XtVaGetValues(shell,
110                 XmNcolormap, &attrs.colormap,
111                 XmNdepth,    &attrs.depth,
112                 XmNvisual,   &attrs.visual,
113                 NULL);
114 
115   // CAT_MOD
116   if(!attrs.visual) {
117     int snum = XDefaultScreen(dpy);
118     attrs.visual = XDefaultVisual(dpy, snum);
119   }
120 
121   attrs.valuemask = XpmVisual | XpmColormap | XpmDepth;
122 
123   Drawable draw = RootWindow(dpy, DefaultScreen(dpy));
124   Pixmap stencil = 0;
125 
126   // FIXME: that cast is pretty nasty -- get rid of it. 20020319 mortene.
127   int error = XpmCreatePixmapFromData(dpy, draw, (char **)xpm,
128                                       &pixels, &stencil, &attrs);
129 
130   if (error != XpmSuccess) {
131 #if SOXT_DEBUG
132     SoDebugError::postInfo("SoXtInternal::createPixmapFromXpm",
133                            "XpmCreatePixmapFromData() failed: %s",
134                            SoXtInternal::xpmErrorString(error));
135 #endif // SOXT_DEBUG
136     return (Pixmap)0;
137   }
138 
139   if (stencil) {
140     Pixel bg;
141     XtVaGetValues(widget, XmNbackground, &bg, NULL);
142 
143     XImage * pixmap = XGetImage(dpy, pixels, 0, 0, attrs.width, attrs.height,
144                                 0xffffffff, ZPixmap);
145     XImage * mask = XGetImage(dpy, stencil, 0, 0, attrs.width, attrs.height,
146                               0xffffffff, ZPixmap);
147     assert(pixmap != NULL && mask != NULL);
148 
149     for (unsigned int x = 0; x < attrs.width; x++) {
150       for (unsigned int y = 0; y < attrs.height; y++) {
151         Pixel pixel = XGetPixel(mask, x, y);
152         Bool usebg = (pixel == 0);
153         if (ghost && !usebg) { usebg = ((x+y) % 2) == 1; }
154         if (usebg) { // background must be set in image
155           XPutPixel(pixmap, x, y, bg);
156         }
157       }
158     }
159 
160     GC temp = XCreateGC(dpy, pixels, 0, NULL);
161     XPutImage(dpy, pixels, temp, pixmap,
162               0, 0, 0, 0, attrs.width, attrs.height);
163     XFreeGC(dpy, temp);
164 
165     XDestroyImage(pixmap);
166     XDestroyImage(mask);
167   }
168 
169 #endif // HAVE_LIBXPM
170   return pixels;
171 }
172 
173 void
setAppName(const char * appname)174 SoXtInternal::setAppName(const char * appname)
175 {
176   if ( SoXtInternal::appname != NULL ) {
177     free(SoXtInternal::appname);
178     SoXtInternal::appname = NULL;
179   }
180   if ( appname )
181     SoXtInternal::appname = strcpy(new char [strlen(appname) + 1], appname);
182 }
183 
184 void
setAppClass(const char * appclass)185 SoXtInternal::setAppClass(const char * appclass)
186 {
187   if ( SoXtInternal::appclass != NULL ) {
188     free(SoXtInternal::appclass);
189     SoXtInternal::appclass = NULL;
190   }
191   if ( appclass )
192     SoXtInternal::appclass = strcpy(new char [strlen(appclass) + 1], appclass);
193 }
194 
195 const char *
getAppName(void)196 SoXtInternal::getAppName(void)
197 {
198   return SoXtInternal::appname;
199 }
200 
201 const char *
getAppClass(void)202 SoXtInternal::getAppClass(void)
203 {
204   return SoXtInternal::appclass;
205 }
206 
207 void
selectBestVisual(Display * dpy,Visual * & visual,Colormap & colormap,int & depth)208 SoXtInternal::selectBestVisual(Display * dpy, Visual * & visual,
209                        Colormap & colormap, int & depth)
210 {
211   assert(dpy != NULL);
212   const int screen = DefaultScreen(dpy);
213   visual = DefaultVisual(dpy, screen);
214   colormap = DefaultColormap(dpy, screen);
215   depth = DefaultDepth(dpy, screen);
216   return;
217 }
218 
219