This is MesaWorkstation.c in view mode; [Download] [Up]
/* MesaWorkstation.c -- Implementation file for the Mesa Workstation widget Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: MesaWorkstation.c,v 1.21 1996/09/30 00:21:07 ohl Exp $ */ #include <stdio.h> #include <stdlib.h> #include <math.h> #include <X11/IntrinsicP.h> #include <X11/StringDefs.h> #include <GL/glu.h> #include <GL/xmesa.h> #ifdef __GLX_MOTIF #include <GL/MesaMWorkstationP.h> #else #include <GL/MesaWorkstationP.h> #endif #if STDC_HEADERS # include <string.h> #else # ifndef HAVE_STRCHR # define strchr index # define strrchr rindex # endif char *strchr (), *strrchr (); # ifndef HAVE_MEMCPY # define memcpy(d, s, n) bcopy ((s), (d), (n)) # endif # ifndef HAVE_MEMMOVE # define memmove(d, s, n) bcopy ((s), (d), (n)) # endif #endif #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #ifdef __GLX_MOTIF #define GLwDrawingAreaWidget GLwMDrawingAreaWidget #define GLwDrawingAreaClassRec GLwMDrawingAreaClassRec #define GLwDrawingAreaRec GLwMDrawingAreaRec #define glwDrawingAreaClassRec glwMDrawingAreaClassRec #define glwDrawingAreaWidgetClass glwMDrawingAreaWidgetClass #define MesaDrawingAreaWidget MesaMDrawingAreaWidget #define MesaDrawingAreaClassRec MesaMDrawingAreaClassRec #define MesaDrawingAreaRec MesaMDrawingAreaRec #define mesaDrawingAreaClassRec mesaMDrawingAreaClassRec #define mesaDrawingAreaWidgetClass mesaMDrawingAreaWidgetClass #define MesaWorkstationWidget MesaMWorkstationWidget #define MesaWorkstationClassRec MesaMWorkstationClassRec #define MesaWorkstationRec MesaMWorkstationRec #define mesaWorkstationClassRec mesaMWorkstationClassRec #define mesaWorkstationWidgetClass mesaMWorkstationWidgetClass #define GLwPostObject GLwMPostObject #define GLwUnpostObject GLwMUnpostObject #define GLwUnpostAllObjects GLwMUnpostAllObjects #define GLwBeginView GLwMBeginView #define GLwEndView GLwMEndView #define GLwPostViewList GLwMPostViewList #define GLwPostViewMatrix GLwMPostViewMatrix #define GLwPostCurrentView GLwMPostCurrentView #define GLwUnpostView GLwMUnpostView #define GLwSetPolarView GLwMSetPolarView #define GLwGetViewList GLwMGetViewList #define GLwGetViewMatrix GLwMGetViewMatrix #define GLwBeginProjection GLwMBeginProjection #define GLwEndProjection GLwMEndProjection #define GLwPostProjectionList GLwMPostProjectionList #define GLwPostProjectionMatrix GLwMPostProjectionMatrix #define GLwPostCurrentProjection GLwMPostCurrentProjection #define GLwUnpostProjection GLwMUnpostProjection #define GLwSetFrustumProjection GLwMSetFrustumProjection #define GLwSetOrthoProjection GLwMSetOrthoProjection #define GLwGetProjectionList GLwMGetProjectionList #define GLwGetProjectionMatrix GLwMGetProjectionMatrix #define GLwRedrawObjects GLwMRedrawObjects #define GLwPostView GLwMPostView #define GLwGetView GLwMGetView #define GLwPostProjection GLwMPostProjection #define GLwGetProjection GLwMGetProjection #endif #define MesaProjection(_widget) \ (((MesaWorkstationWidget)_widget)->mesaWorkstation.projection) #define MesaView(_widget) \ (((MesaWorkstationWidget)_widget)->mesaWorkstation.view) #define MesaNextObject(_widget) \ (((MesaWorkstationWidget)_widget)->mesaWorkstation.next_object) #define MesaAllocatedObjects(_widget) \ (((MesaWorkstationWidget)_widget)->mesaWorkstation.allocated_objects) #define MesaObjects(_widget) \ (((MesaWorkstationWidget)_widget)->mesaWorkstation.objects) /* Private utility functions. */ /* Resources. */ /* Actions and their translations. */ static void Projection (Widget w, XEvent *event, String *argv, Cardinal *argc) { LOG (w); if (*argc == 0) return; if ((MesaProjection(w).type != FRUSTUM) && (MesaProjection(w).type != ORTHO)) return; switch (*argv[0]) { case 'p': MesaProjection(w).type = FRUSTUM; break; case 'o': MesaProjection(w).type = ORTHO; break; case 'l': MesaProjection(w).u.vol.left *= 1.1; break; case 'L': MesaProjection(w).u.vol.left /= 1.1; break; case 'r': MesaProjection(w).u.vol.right *= 1.1; break; case 'R': MesaProjection(w).u.vol.right /= 1.1; break; case 'b': MesaProjection(w).u.vol.bottom *= 1.1; break; case 'B': MesaProjection(w).u.vol.bottom /= 1.1; break; case 't': MesaProjection(w).u.vol.top *= 1.1; break; case 'T': MesaProjection(w).u.vol.top /= 1.1; break; case 'n': MesaProjection(w).u.vol.near *= 1.1; break; case 'N': MesaProjection(w).u.vol.near /= 1.1; break; case 'f': MesaProjection(w).u.vol.far *= 1.1; break; case 'F': MesaProjection(w).u.vol.far /= 1.1; break; case 'a': MesaProjection(w).u.vol.left *= 1.1; MesaProjection(w).u.vol.right *= 1.1; MesaProjection(w).u.vol.bottom *= 1.1; MesaProjection(w).u.vol.top *= 1.1; break; case 'A': MesaProjection(w).u.vol.left /= 1.1; MesaProjection(w).u.vol.right /= 1.1; MesaProjection(w).u.vol.bottom /= 1.1; MesaProjection(w).u.vol.top /= 1.1; break; } GLwRedrawObjects (w); } static void Move (Widget w, XEvent *event, String *argv, Cardinal *argc) { double scale = 0.01; LOG (w); if (*argc == 0) return; if (MesaView(w).type != POLAR) return; if (*argc >= 2) scale *= atof (argv[1]); switch (*argv[0]) { case '+': MesaView(w).u.polar.r /= 1.1; break; case '-': MesaView(w).u.polar.r *= 1.1; break; case 'l': MesaView(w).u.polar.phi += scale * M_PI; break; case 'r': MesaView(w).u.polar.phi -= scale * M_PI; break; case 'u': MesaView(w).u.polar.theta -= scale * M_PI; break; case 'd': MesaView(w).u.polar.theta += scale * M_PI; break; } GLwRedrawObjects (w); } static XtActionsRec actions[] = { /* {name, procedure} */ {"Move", Move }, {"Projection", Projection }, }; static char translations[] = #ifdef __GLX_MOTIF "~Shift<Key>osfLeft: Move(l)\n\ Shift<Key>osfLeft: Move(l,10)\n\ ~Shift<Key>osfRight: Move(r)\n\ Shift<Key>osfRight: Move(r,10)\n\ ~Shift<Key>osfUp: Move(u)\n\ Shift<Key>osfUp: Move(u,10)\n\ ~Shift<Key>osfDown: Move(d)\n\ Shift<Key>osfDown: Move(d,10)\n\ ~Shift<Key>Left: Move(l)\n\ Shift<Key>Left: Move(l,10)\n\ ~Shift<Key>Right: Move(r)\n\ Shift<Key>Right: Move(r,10)\n\ ~Shift<Key>Up: Move(u)\n\ Shift<Key>Up: Move(u,10)\n\ ~Shift<Key>Down: Move(d)\n\ Shift<Key>Down: Move(d,10)\n\ <Key>plus: Move(+)\n\ <Key>minus: Move(-)\n\ ~Shift<Key>l: Projection(l)\n\ Shift<Key>l: Projection(L)\n\ ~Shift<Key>r: Projection(r)\n\ Shift<Key>r: Projection(R)\n\ ~Shift<Key>b: Projection(b)\n\ Shift<Key>b: Projection(B)\n\ ~Shift<Key>t: Projection(t)\n\ Shift<Key>t: Projection(T)\n\ ~Shift<Key>n: Projection(n)\n\ Shift<Key>n: Projection(N)\n\ ~Shift<Key>f: Projection(f)\n\ Shift<Key>f: Projection(F)\n\ ~Shift<Key>a: Projection(a)\n\ Shift<Key>a: Projection(A)\n\ <Key>p: Projection(p)\n\ <Key>o: Projection(o)\n"; #else /* __GLX_MOTIF */ "~Shift<Key>Left: Move(l)\n\ Shift<Key>Left: Move(l,10)\n\ ~Shift<Key>Right: Move(r)\n\ Shift<Key>Right: Move(r,10)\n\ ~Shift<Key>Up: Move(u)\n\ Shift<Key>Up: Move(u,10)\n\ ~Shift<Key>Down: Move(d)\n\ Shift<Key>Down: Move(d,10)\n\ <Key>plus: Move(+)\n\ <Key>minus: Move(-)\n\ ~Shift<Key>l: Projection(l)\n\ Shift<Key>l: Projection(L)\n\ ~Shift<Key>r: Projection(r)\n\ Shift<Key>r: Projection(R)\n\ ~Shift<Key>b: Projection(b)\n\ Shift<Key>b: Projection(B)\n\ ~Shift<Key>t: Projection(t)\n\ Shift<Key>t: Projection(T)\n\ ~Shift<Key>n: Projection(n)\n\ Shift<Key>n: Projection(N)\n\ ~Shift<Key>f: Projection(f)\n\ Shift<Key>f: Projection(F)\n\ ~Shift<Key>a: Projection(a)\n\ Shift<Key>a: Projection(A)\n\ <Key>p: Projection(p)\n\ <Key>o: Projection(o)\n"; #endif /* __GLX_MOTIF */ /* Basic widget methods. */ #define OBJECT_CHUNK_SIZE 10 static void Initialize (Widget request, Widget new, ArgList args, Cardinal * num_args) { LOG (new); MesaAllocatedObjects (new) = OBJECT_CHUNK_SIZE; MesaObjects (new) = (GLuint *) XtCalloc (MesaAllocatedObjects (new), sizeof (GLuint)); MesaNextObject (new) = MesaObjects (new); MesaView(new).type = NOVIEW; MesaView(new).list = 0; MesaProjection(new).type = NOPROJ; MesaProjection(new).list = 0; } #if 0 static void Realize (Widget w, XtValueMask * mask, XSetWindowAttributes * attr) { LOG (w); (XtSuperclass (w)->core_class.realize) (w, mask, attr); } #endif static void Destroy (Widget w) { LOG (w); XtFree ((char *) MesaObjects (w)); } static void Redisplay (Widget w, XEvent *event, Region region) { LOG (w); if (event->xexpose.count == 0) /* last Expose event */ GLwRedrawObjects (w); } /* Now use all these methods in the widget class record. */ MesaWorkstationClassRec mesaWorkstationClassRec = { { /* superclass */ (WidgetClass) &mesaDrawingAreaClassRec, #ifdef __GLX_MOTIF /* class_name */ "MesaMWorkstation", #else /* class_name */ "MesaWorkstation", #endif /* widget_size */ sizeof (MesaWorkstationRec), /* class_initialize */ NULL, /* class_part_initialize */ NULL, /* class_inited */ FALSE, /* initialize */ Initialize, /* initialize_hook */ NULL, /* realize */ XtInheritRealize, /* actions */ actions, /* num_actions */ XtNumber (actions), /* resources */ NULL, /* num_resources */ 0, /* xrm_class */ NULLQUARK, /* compress_motion */ TRUE, /* compress_exposure */ TRUE, /* compress_enterleave */ TRUE, /* visible_interest */ FALSE, /* destroy */ Destroy, /* resize */ XtInheritResize, /* expose */ Redisplay, /* set_values */ NULL, /* set_values_hook */ NULL, /* set_values_almost */ XtInheritSetValuesAlmost, /* get_values_hook */ NULL, /* accept_focus */ NULL, /* version */ XtVersion, /* callback_private */ NULL, /* tm_table */ translations, /* query_geometry */ XtInheritQueryGeometry, /* display_accelerator */ XtInheritDisplayAccelerator, /* extension */ NULL }, #ifdef __GLX_MOTIF { /* XmPrimitive fields */ /* border_highlight */ (XtWidgetProc) _XtInherit, /* border_unhighlight */ (XtWidgetProc) _XtInherit, /* translations */ XtInheritTranslations, /* arm_and_activate */ NULL, /* get_resources */ NULL, /* num get_resources */ 0, /* extension */ NULL, }, #endif /* __GLX_MOTIF */ { /* MesaDrawingArea fields*/ /* RCS_id */ NULL }, { /* MesaWorkstation fields*/ /* RCS_id */ "@(#) $Id: MesaWorkstation.c,v 1.21 1996/09/30 00:21:07 ohl Exp $" } }; WidgetClass mesaWorkstationWidgetClass = (WidgetClass) & mesaWorkstationClassRec; /* More private utility functions. */ static int is_workstation (Widget w) { if (XtClass (w) != mesaWorkstationWidgetClass) { XtAppError (XtWidgetToApplicationContext (w), #ifndef __GLX_MOTIF "Not a Mesa Workstation!"); #else "Not a Mesa/Motif Workstation!"); #endif return 0; } else return 1; } static void mesa_frustum (volume v) { glFrustum (v.left, v.right, v.bottom, v.top, v.near, v.far); } static void mesa_ortho (volume v) { glOrtho (v.left, v.right, v.bottom, v.top, v.near, v.far); } static void mesa_look_at (look_at l) { gluLookAt (l.eyex, l.eyex, l.eyez, l.ctrx, l.ctrx, l.ctrz, l.upx, l.upx, l.upz); } static void mesa_polar (polar p) { GLdouble r, sin_th, cos_th, sin_phi, cos_phi, u_sin_th, u_cos_th; r = p.r; sin_th = sin (p.theta); cos_th = cos (p.theta); sin_phi = sin (p.phi); cos_phi = cos (p.phi); u_sin_th = cos_th; u_cos_th = -sin_th; gluLookAt (r*sin_th*cos_phi, r*cos_th, r*sin_th*sin_phi, 0.0, 0.0, 0.0, u_sin_th*cos_phi, u_cos_th, u_sin_th*sin_phi); } /* Exported utilility functions. */ void GLwPostObject (Widget w, GLuint object) { if (is_workstation (w)) { if (MesaNextObject (w) > MesaObjects (w) + MesaAllocatedObjects (w)) { MesaAllocatedObjects (w) += OBJECT_CHUNK_SIZE; MesaObjects (w) = (GLuint *) XtRealloc ((char *) MesaObjects (w), sizeof (GLuint) * MesaAllocatedObjects (w)); } *(MesaNextObject(w)++) = object; } } void GLwUnpostObject (Widget w, GLuint object) { if (is_workstation (w)) { GLuint *p; for (p = MesaObjects (w); p < MesaNextObject (w); p++) if (*p == object) { memmove (p, p + 1, sizeof (GLuint) * (MesaNextObject (w) - p - 1)); MesaNextObject(w)--; break; } } } void GLwUnpostAllObjects (Widget w) { if (is_workstation (w)) MesaNextObject (w) = MesaObjects (w); } void GLwBeginView (Widget w) { if (is_workstation (w)) { MesaView(w).type = VIEW_LIST; if (!glIsList (MesaView(w).list)) MesaView(w).list = glGenLists (1); glNewList (MesaView(w).list, GL_COMPILE); } } void GLwEndView (void) { glEndList (); } void GLwPostViewList (Widget w, GLuint view) { if (is_workstation (w)) { MesaView(w).type = VIEW_LIST; MesaView(w).list = view; } } void GLwPostViewMatrix (Widget w, GLdouble *m) { if (is_workstation (w)) { MesaView(w).type = VIEW_MATRIX; memcpy (MesaView(w).u.m, m, sizeof (MesaView(w).u.m)); } } void GLwPostCurrentView (Widget w) { if (is_workstation (w)) { MesaView(w).type = VIEW_MATRIX; glGetDoublev (GL_MODELVIEW_MATRIX, MesaView(w).u.m); } } void GLwUnpostView (Widget w) { if (is_workstation (w)) MesaView(w).type = NOVIEW; } void GLwSetPolarView (Widget w, GLdouble r, GLdouble theta, GLdouble phi) { if (is_workstation (w)) { MesaView(w).type = POLAR; MesaView(w).u.polar.r = r; MesaView(w).u.polar.theta = theta; MesaView(w).u.polar.phi = phi; } } GLuint GLwGetViewList (Widget w) { if (is_workstation (w)) { if (MesaView(w).type == VIEW_LIST) return MesaView(w).list; } return 0; } int GLwGetViewMatrix (Widget w, GLdouble *m) { if (is_workstation (w)) { if (MesaView(w).type == VIEW_MATRIX) memcpy (m, MesaView(w).u.m, sizeof (MesaView(w).u.m)); return 1; } return 0; } void GLwBeginProjection (Widget w) { if (is_workstation (w)) { MesaProjection(w).type = PROJ_LIST; if (!glIsList (MesaProjection(w).list)) MesaProjection(w).list = glGenLists (1); glNewList (MesaProjection(w).list, GL_COMPILE); } } void GLwEndProjection (void) { glEndList (); } void GLwPostProjectionList (Widget w, GLuint proj) { if (is_workstation (w)) { MesaProjection(w).type = PROJ_LIST; MesaProjection(w).list = proj; } } void GLwPostProjectionMatrix (Widget w, GLdouble *m) { if (is_workstation (w)) { MesaProjection(w).type = PROJ_MATRIX; memcpy (MesaProjection(w).u.m, m, sizeof (MesaProjection(w).u.m)); } } void GLwPostCurrentProjection (Widget w) { if (is_workstation (w)) { MesaProjection(w).type = PROJ_MATRIX; glGetDoublev (GL_PROJECTION_MATRIX, MesaProjection(w).u.m); } } void GLwUnpostProjection (Widget w) { if (is_workstation (w)) MesaProjection(w).type = NOPROJ; } void GLwSetFrustumProjection (Widget w, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far) { if (is_workstation (w)) { MesaProjection(w).type = FRUSTUM; MesaProjection(w).u.vol.left = left; MesaProjection(w).u.vol.right = right; MesaProjection(w).u.vol.bottom = bottom; MesaProjection(w).u.vol.top = top; MesaProjection(w).u.vol.near = near; MesaProjection(w).u.vol.far = far; } } void GLwSetOrthoProjection (Widget w, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far) { if (is_workstation (w)) { MesaProjection(w).type = ORTHO; MesaProjection(w).u.vol.left = left; MesaProjection(w).u.vol.right = right; MesaProjection(w).u.vol.bottom = bottom; MesaProjection(w).u.vol.top = top; MesaProjection(w).u.vol.near = near; MesaProjection(w).u.vol.far = far; } } GLuint GLwGetProjectionList (Widget w) { if (is_workstation (w)) { if (MesaProjection(w).type == PROJ_LIST) return MesaProjection(w).list; } return 0; } int GLwGetProjectionMatrix (Widget w, GLdouble *m) { if (is_workstation (w)) { if (MesaProjection(w).type == PROJ_MATRIX) memcpy (m, MesaProjection(w).u.m, sizeof (MesaProjection(w).u.m)); return 1; } return 0; } void GLwRedrawObjects (Widget w) { if (is_workstation (w)) { XMesaBuffer buffer = XMesaGetCurrentBuffer (); XMesaContext context = XMesaGetCurrentContext (); XMesaMakeCurrent (MesaContext (w), MesaBuffer (w)); if (MesaProjection(w).type != NOPROJ) { glMatrixMode (GL_PROJECTION); glPushMatrix (); glLoadIdentity (); } switch (MesaProjection(w).type) { case PROJ_MATRIX: glLoadMatrixd (MesaProjection(w).u.m); break; case PROJ_LIST: if (!glIsList (MesaProjection(w).list)) XtAppWarning (XtWidgetToApplicationContext (w), "Invalid projection list!"); else glCallList (MesaProjection(w).list); break; case FRUSTUM: mesa_frustum (MesaProjection(w).u.vol); break; case ORTHO: mesa_ortho (MesaProjection(w).u.vol); break; case NOPROJ: break; } glMatrixMode (GL_MODELVIEW); glPushMatrix (); { GLuint *obj; glLoadIdentity (); switch (MesaView(w).type) { case PROJ_MATRIX: glLoadMatrixd (MesaView(w).u.m); break; case PROJ_LIST: if (!glIsList (MesaView(w).list)) XtAppWarning (XtWidgetToApplicationContext (w), "Invalid view list!"); else glCallList (MesaView(w).list); break; case LOOK_AT: mesa_look_at (MesaView(w).u.look_at); break; case POLAR: mesa_polar (MesaView(w).u.polar); break; case NOVIEW: break; } for (obj = MesaObjects (w); obj < MesaNextObject (w); obj++) { if (!glIsList (*obj)) XtAppWarning (XtWidgetToApplicationContext (w), "Invalid object list!"); else { glPushMatrix (); glCallList (*obj); glPopMatrix (); } } } glPopMatrix (); if (MesaProjection(w).type != NOVIEW) { glMatrixMode (GL_PROJECTION); glPopMatrix (); glMatrixMode (GL_MODELVIEW); } glFinish (); XMesaSwapBuffers (buffer); XMesaMakeCurrent (context, buffer); } } /* obsolete aliases: */ void GLwPostView (Widget w, GLuint view) { GLwPostViewList (w, view); } GLuint GLwGetView (Widget w) { return GLwGetViewList (w); } void GLwPostProjection (Widget w, GLuint proj) { GLwPostProjectionList (w, proj); } GLuint GLwGetProjection (Widget w) { return GLwGetProjectionList (w); } /* The End. */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.