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