glwin.c
来自「有限元学习研究用源代码(老外的),供科研人员参考」· C语言 代码 · 共 2,180 行 · 第 1/4 页
C
2,180 行
max = (size > w->vInfoMain->colormap_size) ? w->vInfoMain->colormap_size
: size;
for (i = 0; i < max; i++) {
c.pixel = i;
c.red = (unsigned short)(rgb[i] * 65535.0 + 0.5);
c.green = (unsigned short)(rgb[size+i] * 65535.0 + 0.5);
c.blue = (unsigned short)(rgb[size*2+i] * 65535.0 + 0.5);
c.flags = DoRed | DoGreen | DoBlue;
XStoreColor(w->xDisplay, w->cMapMain, &c);
}
break;
}
XSync(w->xDisplay, 0);
}
/******************************************************************************/
GLenum glwSetWindowLevel(glWindow w,GLenum level)
{
switch (level) {
case GLW_OVERLAY:
if (GLW_HAS_OVERLAY(w->type)) {
if (!glXMakeCurrent(w->xDisplay, w->wOverlay, w->cOverlay)) {
return GL_FALSE;
}
} else {
return GL_FALSE;
}
break;
case GLW_RGB:
case GLW_INDEX:
if (!glXMakeCurrent(w->xDisplay, w->wMain, w->cMain)) {
return GL_FALSE;
}
break;
default:
break;
}
return GL_TRUE;
}
void glwQuit(glWindow w)
{
w->process=0;
}
/******************************************************************************/
static GLenum DoNextEvent(glWindow w)
{
XEvent current, ahead;
char buf[1000];
KeySym ks;
int key;
XNextEvent(w->xDisplay, ¤t);
switch (current.type) {
case MappingNotify:
XRefreshKeyboardMapping((XMappingEvent *)¤t);
w->lastEventType = MappingNotify;
return GL_FALSE;
case MapNotify:
w->lastEventType = MapNotify;
w->drawAllowFlag = GL_TRUE;
return GL_FALSE;
case UnmapNotify:
w->lastEventType = UnmapNotify;
w->drawAllowFlag = GL_FALSE;
return GL_FALSE;
case ClientMessage:
w->lastEventType = ClientMessage;
if (current.xclient.data.l[0] == w->deleteWindowAtom) {
exit(0);
}
return GL_FALSE;
case Expose:
while (XEventsQueued(current.xexpose.display, QueuedAfterReading) > 0) {
XPeekEvent(current.xexpose.display, &ahead);
if (ahead.xexpose.window != current.xexpose.window ||
ahead.type != Expose) {
break;
}
XNextEvent(w->xDisplay, ¤t);
}
if (current.xexpose.count == 0) {
if (w->ExposeFunc) {
#ifdef DEC /* bug fixes */
(*ExposeFunc)(w.w, w.h);
if (lastEventType == ConfigureNotify
&& drawAllowFlag == GL_TRUE) {
/* the last event must have generated a draw */
lastEventType = Expose;
return GL_FALSE;
} else {
drawAllowFlag = GL_TRUE;
lastEventType = Expose;
return GL_TRUE;
}
#else /* not DEC */
w->drawAllowFlag = GL_TRUE;
w->lastEventType = Expose;
(*w->ExposeFunc)(w,w->info,w->w, w->h);
if (w->lastEventType == ConfigureNotify) {
return GL_FALSE;
} else {
return GL_TRUE;
}
#endif /* not DEC */
}
}
return GL_FALSE;
case ConfigureNotify:
w->lastEventType = ConfigureNotify;
w->w = current.xconfigure.width;
w->h = current.xconfigure.height;
if (w->ReshapeFunc) {
(*w->ReshapeFunc)(w,w->info,w->w, w->h);
return GL_TRUE;
} else {
return GL_FALSE;
}
case MotionNotify:
w->lastEventType = MotionNotify;
if (w->MouseMoveFunc) {
GLenum mask;
mask = (GLenum)0;
if (current.xmotion.state & Button1Mask) mask |= GLW_LEFTBUTTON;
if (current.xmotion.state & Button2Mask) mask |= GLW_MIDDLEBUTTON;
if (current.xmotion.state & Button3Mask) mask |= GLW_RIGHTBUTTON;
if (current.xmotion.state & ShiftMask) mask |= GLW_SHIFT;
if (current.xmotion.state & ControlMask) mask |= GLW_CONTROL;
if (current.xmotion.state & Mod1Mask) mask |= GLW_MOD1;
if (current.xkey.state & LockMask) mask |= GLW_LOCK;
return (*w->MouseMoveFunc)(w,w->info,current.xmotion.x, current.xmotion.y, mask);
} else {
return GL_FALSE;
}
case ButtonPress:
w->lastEventType = ButtonPress;
if (w->MouseDownFunc) {
GLenum mask;
mask = (GLenum)0;
if (current.xbutton.button==1) mask |= GLW_LEFTBUTTON;
if (current.xbutton.button==2) mask |= GLW_MIDDLEBUTTON;
if (current.xbutton.button==3) mask |= GLW_RIGHTBUTTON;
if (current.xbutton.state & ShiftMask) mask |= GLW_SHIFT;
if (current.xbutton.state & ControlMask) mask |= GLW_CONTROL;
if (current.xmotion.state & Mod1Mask) mask |= GLW_MOD1;
return (*w->MouseDownFunc)(w,w->info,current.xbutton.x, current.xbutton.y, mask);
} else {
return GL_FALSE;
}
case ButtonRelease:
w->lastEventType = ButtonRelease;
if (w->MouseUpFunc) {
GLenum mask;
mask = (GLenum) 0;
if (current.xbutton.button==1) mask |= GLW_LEFTBUTTON;
if (current.xbutton.button==2) mask |= GLW_MIDDLEBUTTON;
if (current.xbutton.button==3) mask |= GLW_RIGHTBUTTON;
if (current.xbutton.state & ShiftMask) mask |= GLW_SHIFT;
if (current.xbutton.state & ControlMask) mask |= GLW_CONTROL;
if (current.xmotion.state & Mod1Mask) mask |= GLW_MOD1;
return (*w->MouseUpFunc)(w,w->info,current.xbutton.x, current.xbutton.y, mask);
} else {
return GL_FALSE;
}
case KeyPress:
w->lastEventType = KeyPress;
XLookupString(¤t.xkey, buf, sizeof(buf), &ks, 0);
switch (ks) {
#define CaseKS(sym) case XK_##sym: key=GLW_##sym; break
CaseKS(0);
CaseKS(1);
CaseKS(2);
CaseKS(3);
CaseKS(4);
CaseKS(5);
CaseKS(6);
CaseKS(7);
CaseKS(8);
CaseKS(9);
CaseKS(A);
CaseKS(B);
CaseKS(C);
CaseKS(D);
CaseKS(E);
CaseKS(F);
CaseKS(G);
CaseKS(H);
CaseKS(I);
CaseKS(J);
CaseKS(K);
CaseKS(L);
CaseKS(M);
CaseKS(N);
CaseKS(O);
CaseKS(P);
CaseKS(Q);
CaseKS(R);
CaseKS(S);
CaseKS(T);
CaseKS(U);
CaseKS(V);
CaseKS(W);
CaseKS(X);
CaseKS(Y);
CaseKS(Z);
CaseKS(a);
CaseKS(b);
CaseKS(c);
CaseKS(d);
CaseKS(e);
CaseKS(f);
CaseKS(g);
CaseKS(h);
CaseKS(i);
CaseKS(j);
CaseKS(k);
CaseKS(l);
CaseKS(m);
CaseKS(n);
CaseKS(o);
CaseKS(p);
CaseKS(q);
CaseKS(r);
CaseKS(s);
CaseKS(t);
CaseKS(u);
CaseKS(v);
CaseKS(w);
CaseKS(x);
CaseKS(y);
CaseKS(z);
CaseKS(space);
CaseKS(exclam);
CaseKS(quotedbl);
CaseKS(numbersign);
CaseKS(dollar);
CaseKS(percent);
CaseKS(ampersand);
CaseKS(apostrophe);
CaseKS(parenleft);
CaseKS(parenright);
CaseKS(asterisk);
CaseKS(plus);
CaseKS(comma);
CaseKS(minus);
CaseKS(period);
CaseKS(slash);
CaseKS(colon);
CaseKS(semicolon);
CaseKS(less);
CaseKS(equal);
CaseKS(greater);
CaseKS(question);
CaseKS(at);
CaseKS(bracketleft);
CaseKS(bracketright);
CaseKS(asciicircum);
CaseKS(underscore);
CaseKS(grave);
CaseKS(braceleft);
CaseKS(bar);
CaseKS(braceright);
CaseKS(asciitilde);
CaseKS(Return);
CaseKS(BackSpace);
CaseKS(Escape);
CaseKS(Left);
CaseKS(Up);
CaseKS(Right);
CaseKS(Down);
CaseKS(KP_Enter);
CaseKS(KP_Home);
CaseKS(KP_Left);
CaseKS(KP_Up);
CaseKS(KP_Right);
CaseKS(KP_Down);
CaseKS(KP_Page_Up);
CaseKS(KP_Page_Down);
CaseKS(KP_End);
CaseKS(KP_Begin);
CaseKS(KP_Insert);
CaseKS(KP_Delete);
CaseKS(KP_Divide);
CaseKS(KP_Multiply);
CaseKS(KP_Add);
CaseKS(KP_Subtract);
CaseKS(KP_Decimal);
CaseKS(KP_0);
CaseKS(KP_1);
CaseKS(KP_2);
CaseKS(KP_3);
CaseKS(KP_4);
CaseKS(KP_5);
CaseKS(KP_6);
CaseKS(KP_7);
CaseKS(KP_8);
CaseKS(KP_9);
CaseKS(F1);
CaseKS(F2);
CaseKS(F3);
CaseKS(F4);
CaseKS(F5);
CaseKS(F6);
CaseKS(F7);
CaseKS(F8);
CaseKS(F9);
CaseKS(F10);
CaseKS(F11);
CaseKS(F12);
CaseKS(Page_Up);
CaseKS(Page_Down);
CaseKS(Tab);
CaseKS(Home);
CaseKS(End);
CaseKS(Insert);
CaseKS(Delete);
CaseKS(Print);
CaseKS(Pause);
CaseKS(Scroll_Lock);
default: key = GL_FALSE; break;
}
if (key && w->KeyDownFunc) {
GLenum mask;
mask = (GLenum)0;
if (current.xkey.state & ShiftMask) mask |= GLW_SHIFT;
if (current.xkey.state & ControlMask) mask |= GLW_CONTROL;
if (current.xkey.state & Mod1Mask) mask |= GLW_MOD1;
return (*w->KeyDownFunc)(w,w->info,key, mask);
} else {
return GL_FALSE;
}
}
return GL_FALSE;
}
void glwSwapBuffers(glWindow w)
{
if (!w->offscreen)
glXSwapBuffers(w->xDisplay, w->wMain);
if (w->recording && (w->frame_num%w->skip==0))
{
glwGrab(w,w->moviepipe);
w->recorded_frame_num++;
}
w->frame_num++;
}
int glwAttach(glWindow w)
{
if (CurrentWindow==w) return 1;
glwTrace("attach");
if (w==NULL) { glwError("null window"); return GL_FALSE;}
if (w->offscreen)
{
if (!glXMakeCurrent(w->xDisplay, w->glx_pixmap, w->cMain))
{
glwError("Unable to attach window!");
return 0;
}
}
else
{
if (!glXMakeCurrent(w->xDisplay, w->wMain, w->cMain))
{
glwError("Unable to attach window!");
return 0;
}
}
glwTrace("attach");
CurrentWindow=w;
return 1;
}
void glwFlush(glWindow w)
{
glwTrace("flush");
glXWaitGL();
XFlush(w->xDisplay);
}
void glwProcess(glWindow w,void *info)
{
GLenum need_redraw;
int first=1;
glwTrace("process");
if (!glwAttach(w)) return;
w->info=info;
w->process=1;
if (w->control_mode==GLW_EVENT_DRIVEN )
w->drawAllowFlag=(GLenum)1;
do
{
if (w->control_mode==GLW_APPLICATION_DRIVEN )
{
glwTrace("redraw");
(*w->RedrawFunc)(w,w->info);
need_redraw = GL_FALSE;
if (!w->offscreen)
{
while (XPending(w->xDisplay))
{
need_redraw |= DoNextEvent(w);
}
}
}
else
{
if (first)
{
need_redraw=(GLenum)1;
first=0;
}
else
need_redraw = DoNextEvent(w);
}
if (
w->drawAllowFlag &&
(w->control_mode==GLW_EVENT_DRIVEN ) &&
need_redraw &&
w->process
)
{
XDefineCursor(w->xDisplay, w->wMain,w->wait_cursor);
glwTrace("redraw");
(*w->RedrawFunc)(w,w->info);
XDefineCursor(w->xDisplay, w->wMain,w->user_cursor);
}
}
while (w->process);
glXWaitGL();
XFlush(w->xDisplay);
w->drawAllowFlag = GL_FALSE;
w->lastEventType= -1;
glwTrace("process");
}
/******************************************************************************/
void glwSetRedrawFunc(glWindow w, void (*Func)(glWindow, void *))
{
if (w==NULL) { glwError("null window"); return;}
w->RedrawFunc = Func;
}
void glwSetControlMode(glWindow w, int mode)
{
if (w==NULL) { glwError("null window"); return;}
if (!w->offscreen)
{
w->control_mode=mode;
if (w->control_mode==GLW_APPLICATION_DRIVEN)
XDefineCursor(w->xDisplay,w->wMain, None);
else
XDefineCursor(w->xDisplay, w->wMain,w->user_cursor);
}
}
/******************************************************************************/
void glwSetExposeFunc(glWindow w, void (*Func)(glWindow, void *,int, int))
{
if (w==NULL) { glwError("null window"); return;}
w->ExposeFunc = Func;
}
/******************************************************************************/
void glwSetReshapeFunc(glWindow w,void (*Func)(glWindow, void *,int, int))
{
if (w==NULL) { glwError("null window"); return;}
w->ReshapeFunc = Func;
}
/******************************************************************************/
void glwSetDisplayFunc(glWindow w, void (*Func)(glWindow, void *))
{
if (w==NULL) { glwError("null window"); return;}
if (Func!=NULL)
{
w->RedrawFunc = Func;
w->control_mode=GLW_EVENT_DRIVEN;
}
else
w->control_mode=GLW_APPLICATION_DRIVEN;
}
/******************************************************************************/
void glwSetKeyDownFunc(glWindow w,GLenum (*Func)(glWindow, void *,int, GLenum))
{
if (w==NULL) { glwError("null window"); return;}
w->KeyDownFunc = Func;
}
/******************************************************************************/
void glwSetMouseDownFunc(glWindow w,GLenum (*Func)(glWindow, void *,int, int, GLenum))
{
if (w==NULL) { glwError("null window"); return;}
w->MouseDownFunc = Func;
}
/******************************************************************************/
void glwSetMouseUpFunc(glWindow w,GLenum (*Func)(glWindow, void *,int, int, GLenum))
{
if (w==NULL) { glwError("null window"); return;}
w->MouseUpFunc = Func;
}
/******************************************************************************/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?