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, &current);
    switch (current.type) {
      case MappingNotify:
	XRefreshKeyboardMapping((XMappingEvent *)&current);
	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, &current);
	}
	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(&current.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 + -
显示快捷键?