glwin.c
来自「有限元学习研究用源代码(老外的),供科研人员参考」· C语言 代码 · 共 2,180 行 · 第 1/4 页
C
2,180 行
void glwSetMouseMoveFunc(glWindow w,GLenum (*Func)(glWindow, void *,int, int, GLenum))
{
if (w==NULL) { glwError("null window"); return;}
w->MouseMoveFunc = Func;
}
/******************************************************************************/
void glwSetIdleFunc(glWindow w,void (*Func)(glWindow, void *))
{
if (w==NULL) { glwError("null window"); return;}
if (Func!=NULL)
{
w->RedrawFunc = Func;
w->control_mode=GLW_APPLICATION_DRIVEN;
}
else
w->control_mode=GLW_EVENT_DRIVEN;
}
/******************************************************************************/
void glwDestroy(glWindow w)
{
glwTrace("destroy:");
if (glwAttach(w))
{
glFlush();
glFinish();
}
if (GLW_HAS_OVERLAY(w->type))
{
XDestroyWindow(w->xDisplay, w->wOverlay);
glXDestroyContext(w->xDisplay, w->cOverlay);
XFreeColormap(w->xDisplay, w->cMapOverlay);
XFree((char *)w->vInfoOverlay);
glwTrace("destroy overlay");
}
if (w->offscreen)
{
glXDestroyGLXPixmap(w->xDisplay, w->glx_pixmap);
XFreePixmap(w->xDisplay, w->pixmap);
glwTrace("destroy pixmap");
}
else
{
XDestroyWindow(w->xDisplay, w->wMain);
glwTrace("destroy xwindow");
}
XFreeColormap(w->xDisplay, w->cMapMain);
glXDestroyContext(w->xDisplay, w->cMain);
XFree((char *)w->vInfoMain);
XCloseDisplay(w->xDisplay);
free(w->title);
free(w->xtitle);
if (w->state!=NULL) free(w->state);
free(w);
w=NULL;
glwTrace("destroy window");
}
/******************************************************************************/
char *glwGetDefault(glWindow w,char *resource, char *dflt)
{
char *data;
data=XGetDefault(w->xDisplay,"gltools",resource);
if (data==NULL)
return dflt;
else
return data;
}
/******************************************************************************/
void glwGetWindowSize(glWindow w, int *width, int *height)
{
*width=w->w;
*height=w->h;
}
/******************************************************************************/
static glWindow wCreate=NULL;
static glWindow wEvent=NULL;
static void InitWindow(void)
{
glWindow w;
if (wCreate==NULL)
{
wCreate=(struct glWindowStruct *)calloc(sizeof(struct glWindowStruct),1);
if (wCreate==NULL)
{
glwError("No space for window struct!");
return;
}
}
else
return;
w=wCreate;
w->xDisplay = XOpenDisplay(NULL);
if (w->xDisplay==NULL)
{
glwError("Unable to connect to display!");
return;
}
w->x=atoi(glwGetDefault(w,"xOrigin","0"));
w->y=atoi(glwGetDefault(w,"yOrigin","0"));;
w->w=(atoi(glwGetDefault(w,"width","352"))/16)*16; /* GLW_MPEG1_PAL */
w->h=(atoi(glwGetDefault(w,"height","288"))/16)*16; /* GLW_MPEG1_PAL */
w->type=(GLenum)(GLW_RGB|GLW_DOUBLE|GLW_DIRECT|GLW_DEPTH);
w->dmPolicy=(GLenum)GLW_MINIMUM_CRITERIA;
w->title=(char*)malloc(GLW_NAMELEN);
w->xtitle=(char*)malloc(GLW_NAMELEN);
w->state=NULL;
strcpy(w->title,glwGetDefault(w,"title","gltools"));
w->control_mode=GLW_EVENT_DRIVEN;
w->font_base[0]=0;
w->keep_aspect=1;
w->offscreen=0;
}
void glwInitDisplayMode(GLenum type)
{
InitWindow();
wCreate->type = type;
}
void glwInitOffscreen(void)
{
InitWindow();
wCreate->offscreen=1;
wCreate->control_mode=GLW_APPLICATION_DRIVEN;
}
void glwInitDisplayModePolicy(GLenum type)
{
InitWindow();
wCreate->dmPolicy = type;
}
/******************************************************************************/
void glwInitPosition(int x, int y, int width, int height)
{
InitWindow();
wCreate->x = x;
wCreate->y = y;
wCreate->w = (width/16)*16;
wCreate->h = (height/16)*16;
}
void glwInitPos(int x, int y)
{
InitWindow();
wCreate->x = x;
wCreate->y = y;
}
void glwInitTitle(char *title)
{
InitWindow();
strcpy(wCreate->title,title);
}
void glwInitAspectKeeping(int yesno)
{
wCreate->keep_aspect=yesno;
}
static int ErrorHandler(Display *xDisplay, XErrorEvent *event)
{
char buf[80];
glwError("Received X error!");
printf(" Error code : %d\n", event->error_code);
printf(" Request code : %d\n", event->request_code);
printf(" Minor code : %d\n", event->minor_code);
XGetErrorText(xDisplay, event->error_code, buf, 80);
printf(" Error text : %s\n", buf);
return 0;
}
static XVisualInfo *FindBestMainVisual(glWindow w,GLenum type)
{
int list[32], i;
i = 0;
list[i++] = GLX_LEVEL;
list[i++] = 0;
if (GLW_IS_DOUBLE(type)) {
list[i++] = GLX_DOUBLEBUFFER;
}
if (GLW_IS_RGB(type)) {
list[i++] = GLX_RGBA;
list[i++] = GLX_RED_SIZE;
list[i++] = 1;
list[i++] = GLX_GREEN_SIZE;
list[i++] = 1;
list[i++] = GLX_BLUE_SIZE;
list[i++] = 1;
if (GLW_HAS_ALPHA(type)) {
list[i++] = GLX_ALPHA_SIZE;
list[i++] = 1;
}
if (GLW_HAS_ACCUM(type)) {
list[i++] = GLX_ACCUM_RED_SIZE;
list[i++] = 1;
list[i++] = GLX_ACCUM_GREEN_SIZE;
list[i++] = 1;
list[i++] = GLX_ACCUM_BLUE_SIZE;
list[i++] = 1;
if (GLW_HAS_ALPHA(type)) {
list[i++] = GLX_ACCUM_ALPHA_SIZE;
list[i++] = 1;
}
}
} else if (GLW_IS_INDEX(type)) {
list[i++] = GLX_BUFFER_SIZE;
list[i++] = 1;
}
if (GLW_HAS_DEPTH(type)) {
list[i++] = GLX_DEPTH_SIZE;
list[i++] = 1;
}
if (GLW_HAS_STENCIL(type)) {
list[i++] = GLX_STENCIL_SIZE;
list[i++] = 1;
}
list[i] = (int)None;
return glXChooseVisual(w->xDisplay, w->xScreen, list);
}
static XVisualInfo *FindExactMainVisual(glWindow w, GLenum type)
{
int i, nvis, val, rval, gval, bval, aval;
XVisualInfo *vis_list, *this_vis, *best_vis, sampleVis;
int this_score, best_score;
/* Get list of visuals for this screen */
sampleVis.screen = w->xScreen;
vis_list = XGetVisualInfo(w->xDisplay, VisualScreenMask, &sampleVis, &nvis);
/*
* Loop through the visuals; find first one that matches the attr
* specified in type
*/
best_score = -1; best_vis = NULL;
for ( i = 0; i < nvis; i++ )
{
this_vis = &vis_list[i];
if (debug)
fprintf(stderr,"glwin: testing visual id 0x%x: ", (unsigned)this_vis->visualid);
/* Visual must be supported by GLX */
if ( glXGetConfig(w->xDisplay, this_vis, GLX_USE_GL, &val) ) continue;
if ( !val )
{
if (debug) fprintf(stderr,"no GLX support.\n");
continue;
}
/* Visual must be in main planes which is level 0 */
glXGetConfig(w->xDisplay, this_vis, GLX_LEVEL, &val);
if ( val != 0 )
{
if (debug) fprintf(stderr,"no level 0 visual.\n");
continue;
}
/* Color Index or RGBA? It must match the requested value */
glXGetConfig(w->xDisplay, this_vis, GLX_RGBA, &val);
if ( GLW_IS_RGB(type) && !val )
{
if (debug) fprintf(stderr,"no RGB support.\n");
continue;
}
if ( GLW_IS_INDEX(type) && val )
{
if (debug) fprintf(stderr,"no color index support.\n");
continue;
}
/* Double buffered or Single buffered? */
glXGetConfig(w->xDisplay, this_vis, GLX_DOUBLEBUFFER, &val);
if ( GLW_IS_DOUBLE(type) && !val )
{
if (debug) fprintf(stderr,"no double buffer support.\n");
continue;
}
if ( GLW_IS_SINGLE(type) && val )
{
if (debug) fprintf(stderr,"no single buffer support.\n");
continue;
}
/* If accum requested then accum rgb size must be > 0 */
/* If alpha requested then alpha size must be > 0 */
/* if accum & alpha requested then accum alpha size must be > 0 */
if ( GLW_IS_RGB(type) )
{
glXGetConfig(w->xDisplay, this_vis, GLX_ACCUM_RED_SIZE, &rval);
glXGetConfig(w->xDisplay, this_vis, GLX_ACCUM_GREEN_SIZE, &gval);
glXGetConfig(w->xDisplay, this_vis, GLX_ACCUM_BLUE_SIZE, &bval);
glXGetConfig(w->xDisplay, this_vis, GLX_ACCUM_ALPHA_SIZE, &aval);
if ( GLW_HAS_ACCUM(type) )
{
if ( rval <= 0 || gval <= 0 || bval <= 0 )
{
if (debug) fprintf(stderr,"accum RGB size <0.\n");
continue;
}
}
else
{
if ( rval > 0 || gval > 0 || bval > 0 || aval > 0 )
{
if (debug) fprintf(stderr,"accum support not demanded.\n");
continue;
}
}
glXGetConfig(w->xDisplay, this_vis, GLX_ALPHA_SIZE, &val);
if ( GLW_HAS_ALPHA(type) )
{
if ( val <= 0 )
{
if (debug) fprintf(stderr,"alpha size < 0.\n");
continue;
}
if ( GLW_HAS_ACCUM(type) && aval <= 0 )
{
if (debug) fprintf(stderr,"alpha accum size < 0.\n");
continue;
}
}
else
{
if ( val > 0 )
{
if (debug) fprintf(stderr,"alpha support not demanded.\n");
continue;
}
}
}
/* Check depth buffer */
glXGetConfig(w->xDisplay, this_vis, GLX_DEPTH_SIZE, &val);
if ( GLW_HAS_DEPTH(type) )
{
if ( val <= 0 )
{
if (debug) fprintf(stderr,"no depth buffer support.\n");
continue;
}
}
else
{
if ( val > 0 )
{
if (debug) fprintf(stderr,"depth buffer support not demanded.\n");
continue;
}
}
/* Check stencil buffer */
glXGetConfig(w->xDisplay, this_vis, GLX_STENCIL_SIZE, &val);
if ( GLW_HAS_STENCIL(type) )
{
if ( val <= 0 )
{
if (debug) fprintf(stderr,"no stencil buffer support.\n");
continue;
}
}
else
{
if ( val > 0 )
{
if (debug) fprintf(stderr,"stencil buffer support not demanded.\n");
continue;
}
}
glXGetConfig(w->xDisplay, this_vis, GLX_BUFFER_SIZE, &this_score);
if (debug) fprintf(stderr,"ok, buffer size=%d.\n",this_score);
if (this_score > best_score )
{
best_score = this_score;
best_vis = this_vis;
}
}
if ( best_vis )
{
sampleVis.visualid = best_vis->visualid;
sampleVis.screen = w->xScreen;
if ( nvis > 0 ) XFree(vis_list);
return XGetVisualInfo(w->xDisplay, VisualIDMask|VisualScreenMask,
&sampleVis, &nvis);
}
else
{
if ( nvis > 0 ) XFree(vis_list);
return None;
}
}
/*
old code
static XVisualInfo *FindMainVisual(glWindow w,GLenum type)
{
int list[32], i;
i = 0;
list[i++] = GLX_LEVEL;
list[i++] = 0;
if (GLW_IS_DOUBLE(type))
{
list[i++] = GLX_DOUBLEBUFFER;
}
if (GLW_IS_RGB(type))
{
list[i++] = GLX_RGBA;
list[i++] = GLX_RED_SIZE;
list[i++] = 1;
list[i++] = GLX_GREEN_SIZE;
list[i++] = 1;
list[i++] = GLX_BLUE_SIZE;
list[i++] = 1;
if (GLW_HAS_ALPHA(type))
{
list[i++] = GLX_ALPHA_SIZE;
list[i++] = 1;
}
if (GLW_HAS_ACCUM(type))
{
list[i++] = GLX_ACCUM_RED_SIZE;
list[i++] = 1;
list[i++] = GLX_ACCUM_GREEN_SIZE;
list[i++] = 1;
list[i++] = GLX_ACCUM_BLUE_SIZE;
list[i++] = 1;
if (GLW_HAS_ALPHA(type)) {
list[i++] = GLX_ACCUM_ALPHA_SIZE;
list[i++] = 1;
}
}
}
else if (GLW_IS_INDEX(type))
{
list[i++] = GLX_BUFFER_SIZE;
list[i++] = 1;
}
if (GLW_HAS_DEPTH(type))
{
list[i++] = GLX_DEPTH_SIZE;
list[i++] = 1;
}
if (GLW_HAS_STENCIL(type))
{
list[i++] = GLX_STENCIL_SIZE;
list[i++] = 1;
}
list[i] = (int)None;
return glXChooseVisual(w->xDisplay, w->xScreen, list);
}
*/
static XVisualInfo *FindOverlayVisual(glWindow w)
{
int list[3];
list[0] = GLX_LEVEL;
list[1] = 1;
list[2] = (int)None;
return glXChooseVisual(w->xDisplay, w->xScreen, list);
}
static GLenum GetMainWindowType(glWindow w,XVisualInfo *vi)
{
GLenum mask;
int x, y, z;
mask = (GLenum)0;
glXGetConfig(w->xDisplay, vi, GLX_DOUBLEBUFFER, &x);
if (x) {
mask |= GLW_DOUBLE;
} else {
mask |= GLW_SINGLE;
}
glXGetConfig(w->xDisplay, vi, GLX_RGBA, &x);
if (x) {
mask |= GLW_RGB;
glXGetConfig(w->xDisplay, vi, GLX_ALPHA_SIZE, &x);
if (x > 0) {
mask |= GLW_ALPHA;
}
glXGetConfig(w->xDisplay, vi, GLX_ACCUM_RED_SIZE, &x);
glXGetConfig(w->xDisplay, vi, GLX_ACCUM_GREEN_SIZE, &y);
glXGetConfig(w->xDisplay, vi, GLX_ACCUM_BLUE_SIZE, &z);
if (x > 0 && y > 0 && z > 0) {
mask |= GLW_ACCUM;
}
} else {
mask |= GLW_INDEX;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?