1 /*
2  * ***************************************************************************
3  * SG = < Socket Graphics >
4  * Copyright (C) 1994-- Michael Holst
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  * rcsid="$Id: main.c,v 1.5 2010/08/12 04:56:35 fetk Exp $"
21  * ***************************************************************************
22  */
23 
24 /*
25  * ***************************************************************************
26  * File:     main.c
27  *
28  * Purpose:  Driver program for testing the OpenGL Drawing Widget.
29  *
30  * Author:   Michael Holst (Hacked a test program found in Mesa)
31  * ***************************************************************************
32  */
33 
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <stdarg.h>
37 #include <math.h>
38 #include <X11/X.h>
39 #include <X11/Intrinsic.h>
40 #include <X11/StringDefs.h>
41 #include <X11/Shell.h>
42 #include <X11/Xaw/Command.h>
43 #include <X11/Xaw/Form.h>
44 #include <GL/gl.h>
45 #include <GL/GLwDrawA.h>
46 
47 static GLint Black, Red, Green, Blue;
48 
49 extern void quit_function (Widget, XtPointer, XtPointer);
50 
quit_function(Widget w,XtPointer closure,XtPointer call_data)51 void quit_function (Widget w, XtPointer closure, XtPointer call_data) {
52     exit (0);
53 }
54 
draw_cube(void)55 static void draw_cube (void) {
56     /* X faces */
57     glIndexi (Red);
58     glColor3d (1.0, 0.0, 0.0);
59     glBegin (GL_POLYGON); {
60         glVertex3d (1.0, 1.0, 1.0);
61         glVertex3d (1.0, -1.0, 1.0);
62         glVertex3d (1.0, -1.0, -1.0);
63         glVertex3d (1.0, 1.0, -1.0);
64     }
65     glEnd ();
66 
67     glBegin (GL_POLYGON);
68     {
69         glVertex3d (-1.0, 1.0, 1.0);
70         glVertex3d (-1.0, 1.0, -1.0);
71         glVertex3d (-1.0, -1.0, -1.0);
72         glVertex3d (-1.0, -1.0, 1.0);
73     }
74     glEnd ();
75 
76     /* Y faces */
77     glIndexi (Green);
78     glColor3d (0.0, 1.0, 0.0);
79     glBegin (GL_POLYGON); {
80         glVertex3d (1.0, 1.0, 1.0);
81         glVertex3d (1.0, 1.0, -1.0);
82         glVertex3d (-1.0, 1.0, -1.0);
83         glVertex3d (-1.0, 1.0, 1.0);
84     }
85     glEnd ();
86 
87     glBegin (GL_POLYGON); {
88         glVertex3d (1.0, -1.0, 1.0);
89         glVertex3d (-1.0, -1.0, 1.0);
90         glVertex3d (-1.0, -1.0, -1.0);
91         glVertex3d (1.0, -1.0, -1.0);
92     }
93     glEnd ();
94 
95     /* Z faces */
96     glIndexi (Blue);
97     glColor3d (0.0, 0.0, 1.0);
98     glBegin (GL_POLYGON); {
99         glVertex3d (1.0, 1.0, 1.0);
100         glVertex3d (-1.0, 1.0, 1.0);
101         glVertex3d (-1.0, -1.0, 1.0);
102         glVertex3d (1.0, -1.0, 1.0);
103     }
104     glEnd ();
105 
106     glBegin (GL_POLYGON); {
107         glVertex3d (1.0, 1.0, -1.0);
108         glVertex3d (1.0, -1.0, -1.0);
109         glVertex3d (-1.0, -1.0, -1.0);
110         glVertex3d (-1.0, 1.0, -1.0);
111     }
112     glEnd ();
113 }
114 
115 GLfloat xrot, yrot, zrot;
116 
init_display(Widget w)117 static void init_display (Widget w) {
118     xrot = yrot = zrot = 0.0;
119 
120     glClearColor (0.0, 0.0, 0.0, 0.0);
121     glClearIndex (Black);
122     glClearDepth (10.0);
123 
124     glMatrixMode (GL_PROJECTION);
125     glLoadIdentity ();
126     glFrustum (-1.0, 1.0, -1.0, 1.0, 1.0, 10.0);
127     glTranslated (0.0, 0.0, -3.0);
128 
129     glMatrixMode (GL_MODELVIEW);
130     glLoadIdentity ();
131 
132     glCullFace (GL_BACK);
133     glEnable (GL_CULL_FACE);
134 
135     glShadeModel (GL_FLAT);
136 }
137 
display(Widget w)138 static void display (Widget w)
139 {
140     glClear (GL_COLOR_BUFFER_BIT);
141     glPushMatrix (); {
142         glRotated (xrot, 1.0, 0.0, 0.0);
143         glRotated (yrot, 0.0, 1.0, 0.0);
144         glRotated (zrot, 0.0, 0.0, 1.0);
145         draw_cube ();
146     }
147     glPopMatrix ();
148     glFinish ();
149     GLwDrawingAreaSwapBuffers ( w );
150 
151     xrot += 1.0;
152     yrot += 0.7;
153     zrot -= 0.3;
154 }
155 
alloc_color(Widget w,Colormap cmap,int red,int green,int blue)156 static GLint alloc_color (Widget w, Colormap cmap, int red, int green, int blue)
157 {
158     XColor xcolor;
159     xcolor.red = red;
160     xcolor.green = green;
161     xcolor.blue = blue;
162     xcolor.flags = DoRed | DoGreen | DoBlue;
163     if (!XAllocColor (XtDisplay (w), cmap, &xcolor)) {
164         printf ("Couldn't allocate color!\n");
165         exit (1);
166     }
167     return xcolor.pixel;
168 }
169 
translate_pixels(Widget to,Widget from,...)170 static void translate_pixels (Widget to, Widget from, ...) {
171     va_list ap;
172     char *name;
173     Colormap from_cmap, to_cmap;
174     XColor xcolor;
175 
176     XtVaGetValues (from, XtNcolormap, &from_cmap, NULL);
177     XtVaGetValues (to, XtNcolormap, &to_cmap, NULL);
178 
179     va_start (ap, from);
180     for (name = va_arg (ap, char *); name != NULL; name = va_arg (ap, char *)) {
181         XtVaGetValues (from, name, &xcolor.pixel, NULL);
182         XQueryColor (XtDisplay (from), from_cmap, &xcolor);
183         if (!XAllocColor (XtDisplay (to), to_cmap, &xcolor))
184             XtAppWarning (XtWidgetToApplicationContext (to),
185                 "Couldn't allocate color!\n");
186         else
187             XtVaSetValues (from, name, xcolor.pixel, NULL);
188     }
189     va_end (ap);
190 }
191 
192 /* Just like the movies: do 24 frames per second. */
193 unsigned long delay = 1000/24;
194 
195 static void first_frame (Widget);
196 static void next_frame (XtPointer, XtIntervalId *);
197 
first_frame(Widget w)198 static void first_frame (Widget w) {
199     XtAppAddTimeOut (XtWidgetToApplicationContext (w),
200         delay, next_frame, (XtPointer) w);
201 }
202 
next_frame(XtPointer client_data,XtIntervalId * id)203 static void next_frame (XtPointer client_data, XtIntervalId *id) {
204     Widget w = (Widget) client_data;
205     first_frame (w);
206     display (w);
207 }
208 
209 static String fallback_resources[] = {
210     "*GLwDrawingArea.width: 300",
211     "*GLwDrawingArea.height: 300",
212     "*GLwDrawingArea.rgba: true",
213     "*GLwDrawingArea.installColormap: true",
214     "*GLwDrawingArea.doublebuffer: true",
215     NULL
216 };
217 
main(int argc,char * argv[])218 int main (int argc, char *argv[]) {
219     Widget top, frame, plot, quit;
220     XtAppContext app_context;
221     GLXContext glx_context;
222     XVisualInfo *vi;
223     Boolean rgba, doublebuffer, cmap_installed;
224 
225     top = XtVaAppInitialize (&app_context, "Cube", NULL, 0,
226         &argc, argv, fallback_resources, NULL);
227 
228     frame = XtVaCreateManagedWidget ("frame", formWidgetClass, top, NULL);
229     plot = XtVaCreateManagedWidget ("plot", glwDrawingAreaWidgetClass, frame,
230         NULL);
231     quit = XtVaCreateManagedWidget ("quit", commandWidgetClass, frame,
232         XtNfromHoriz, plot, XtNhorizDistance, 10, NULL);
233     XtAddCallback (quit, XtNcallback, quit_function, NULL);
234 
235     XtRealizeWidget (top);
236 
237     XtVaGetValues (plot, GLwNrgba, &rgba, GLwNinstallColormap, &cmap_installed,
238         GLwNdoublebuffer, &doublebuffer, GLwNvisualInfo, &vi, NULL);
239 
240     /* create a visual context */
241     glx_context = glXCreateContext (XtDisplay(plot), vi, 0, GL_FALSE);
242     GLwDrawingAreaMakeCurrent( plot, glx_context );
243 
244     if (rgba) {
245         Black = Red = Green = Blue = 0;
246 
247         if (cmap_installed) {
248             /* In RGBA mode, widgets will have their own color map.
249                Adjust the colors of the other widgets so that--even if the rest
250                of the screen has wrong colors--all application widgets have the
251                right colors.  */
252 
253             translate_pixels (plot, quit, XtNbackground, XtNforeground,
254                 XtNborder, NULL);
255             translate_pixels (plot, frame, XtNbackground, XtNborder, NULL);
256 
257             /* Finally warp the pointer into the widget, to make sure that
258             the user sees the right colors at the beginning.  */
259 
260             XWarpPointer (XtDisplay (plot), None, XtWindow (plot),
261             0, 0, 0, 0, 0, 0);
262         }
263     } else {
264         /* Allocate a few colors for use in color index mode.  */
265         Colormap cmap;
266         cmap = DefaultColormap(XtDisplay(top), DefaultScreen(XtDisplay (top)));
267         Black = alloc_color (top, cmap, 0x0000, 0x0000, 0x0000);
268         Red   = alloc_color (top, cmap, 0xffff, 0x0000, 0x0000);
269         Green = alloc_color (top, cmap, 0x0000, 0xffff, 0x0000);
270         Blue  = alloc_color (top, cmap, 0x0000, 0x0000, 0xffff);
271     }
272 
273     init_display (plot);
274     first_frame (plot);
275 
276     XtAppMainLoop (app_context);
277     return (0);
278 }
279