glwin.c

来自「有限元学习研究用源代码(老外的),供科研人员参考」· C语言 代码 · 共 2,180 行 · 第 1/4 页

C
2,180
字号
    glXGetConfig(w->xDisplay, vi, GLX_DEPTH_SIZE, &x);
    if (x > 0) {
	mask |= GLW_DEPTH;
    }

    glXGetConfig(w->xDisplay, vi, GLX_STENCIL_SIZE, &x);
    if (x > 0) {
	mask |= GLW_STENCIL;
    }

    if (glXIsDirect(w->xDisplay, w->cMain)) {
	mask |= GLW_DIRECT;
    } else {
	mask |= GLW_INDIRECT;
    }

    return mask;
}

static int WaitForMainWindow(Display *d, XEvent *e, char *arg)
{

    if (e->type == MapNotify && e->xmap.window == wEvent->wMain) {
	return GL_TRUE;
    } else {
	return GL_FALSE;
    }
}

/*
static int WaitForOverlayWindow(Display *d, XEvent *e, char *arg)
{

    if (e->type == MapNotify && e->xmap.window == wEvent->wOverlay) {
	return GL_TRUE;
    } else {
	return GL_FALSE;
    }
}
*/
static void default_expose_func(glWindow w, 
			 void *user_data,
			 int width, 
			 int height)
{
  
  /* force redraw if no user drivers set */

}

static void create_window(glWindow w, int overlayFlag)
{
  XSetWindowAttributes wa;
  XTextProperty tp;
  XSizeHints sh;
  XEvent e;

  wa.colormap = w->cMapMain;
  wa.background_pixmap = None;
  wa.border_pixel = 0;
  wa.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask |
    ButtonPressMask | ButtonReleaseMask | PointerMotionMask;
  w->wMain = XCreateWindow(w->xDisplay, w->wRoot, w->x, w->y, w->w, w->h, 0,
			   w->vInfoMain->depth, InputOutput,
			   w->vInfoMain->visual,
			   CWBackPixmap|CWBorderPixel|CWEventMask|CWColormap,
			   &wa);
  
  XStringListToTextProperty(&w->title, 1, &tp);
  sh.flags = USPosition | USSize | PMaxSize |PResizeInc;
  sh.width_inc=16;
  sh.height_inc=16;
  if (w->keep_aspect)
    {
      
      sh.flags|=PAspect;
      sh.min_aspect.x=w->w;
      sh.min_aspect.y=w->h;
      
      sh.max_aspect.x=w->w;
      sh.max_aspect.y=w->h;
    }
  
  {
    Screen *scr = DefaultScreenOfDisplay(w->xDisplay);
    sh.max_width=WidthOfScreen(scr);
    sh.max_height=HeightOfScreen(scr);
  }
  
  XSetWMProperties(w->xDisplay, w->wMain, &tp, &tp, 0, 0, &sh, 0, 0);
  w->deleteWindowAtom = XInternAtom(w->xDisplay, "WM_DELETE_WINDOW", False);
  XSetWMProtocols(w->xDisplay, w->wMain, &w->deleteWindowAtom, 1);
  XMapWindow(w->xDisplay, w->wMain);
  w->drawAllowFlag = GL_FALSE;
  w->lastEventType= -1;
  wEvent=w;
  XIfEvent(w->xDisplay, &e, WaitForMainWindow, 0);
  
  if (overlayFlag == GL_TRUE) {
    w->vInfoOverlay = FindOverlayVisual(w);
    if (w->vInfoOverlay) {
      w->cOverlay = glXCreateContext(w->xDisplay, w->vInfoOverlay, None,
				     GL_TRUE);
      w->cMapOverlay = XCreateColormap(w->xDisplay, w->wRoot,
				       w->vInfoOverlay->visual, AllocNone);
      glwSetOverlayMap(w,256, colorMaps);
      wa.colormap = w->cMapOverlay;
      wa.background_pixmap = None;
      wa.border_pixel = 0;
      w->wOverlay = XCreateWindow(w->xDisplay, w->wMain, 0, 0, w->w, w->h, 0,
				  w->vInfoOverlay->depth, InputOutput,
				       w->vInfoOverlay->visual,
				  CWBackPixmap|CWBorderPixel|CWColormap,
				  &wa);
      XMapWindow(w->xDisplay, w->wOverlay);
      XSetWMColormapWindows(w->xDisplay, w->wMain, &w->wOverlay, 1);
      w->type |= GLW_OVERLAY;
    } else {
      glwError("Unable to create overlay plane!");
    }
  }

  w->wait_cursor=XCreateFontCursor(w->xDisplay,XC_watch);
  w->user_cursor=XCreateFontCursor(w->xDisplay,XC_cross);
  XDefineCursor(w->xDisplay,w->wMain, w->user_cursor);

}

static void create_pixmap(glWindow w, int overlayFlag)
{
  w->pixmap = XCreatePixmap(w->xDisplay, 
			    w->wRoot,
			    w->w, 
			    w->h, 
			    w->vInfoMain->depth);
  if (w->pixmap==0)
    glwError("Unable to create pixmap!");
  else
    glwTrace("pixmap ok");

  w->glx_pixmap =glXCreateGLXPixmap(w->xDisplay,
				   w->vInfoMain,
				   w->pixmap);
  if (w->glx_pixmap==0)
    glwError("Unable to create glx_pixmap!");
  else
    glwTrace("glxpixmap ok");
    
}

glWindow glwCreate(void)
{
  glWindow w;
  int erb, evb;
  GLenum overlayFlag;
    
  InitWindow();
  assert(wCreate);
  w=wCreate;
  wCreate=0;
  if (!glXQueryExtension(w->xDisplay, &erb, &evb))
    {
      glwError("No glx extension found!");
      return NULL;
    }
  w->xScreen = DefaultScreen(w->xDisplay);
  w->wRoot = RootWindow(w->xDisplay, w->xScreen);
  XSetErrorHandler(ErrorHandler);

  if (w->offscreen) w->type |= GLW_INDIRECT;
  
  if (GLW_HAS_OVERLAY(w->type))
      {
	overlayFlag = GL_TRUE;
      } 
  else 
    {
      overlayFlag = GL_FALSE;
    }
  w->type &= ~GLW_OVERLAY;
  
  
  if (w->dmPolicy == GLW_MINIMUM_CRITERIA)
    w->vInfoMain = FindBestMainVisual(w,w->type);
  else if (w->dmPolicy == GLW_EXACT_MATCH)
    w->vInfoMain = FindExactMainVisual(w,w->type);
  if (!w->vInfoMain)
    {
      glwError("Main visual not found!");
      return NULL;
    }
  
  if (debug) fprintf(stderr,"glwin: using  visual id 0x%x\n", (unsigned)w->vInfoMain->visualid);
  
#if defined(__cplusplus) || defined(c_plusplus)
  w->vInfoMainClass = w->vInfoMain->c_class;
#else
  w->vInfoMainClass = w->vInfoMain->class;
#endif  
  
  w->cMain = glXCreateContext(w->xDisplay, w->vInfoMain, None,
			      (GLW_IS_DIRECT(w->type))?GL_TRUE:GL_FALSE);
  if (!w->cMain) 
    {
      glwError("Unable to create glx context!");
      return NULL;
    }

  w->type = GetMainWindowType(w,w->vInfoMain);
  
  if (GLW_IS_INDEX(w->type)) {
    if (w->vInfoMainClass != StaticColor &&
	w->vInfoMainClass != StaticGray) {
      w->cMapMain = XCreateColormap(w->xDisplay, w->wRoot, w->vInfoMain->visual,
				    AllocAll);
    } else {
      w->cMapMain = XCreateColormap(w->xDisplay, w->wRoot, w->vInfoMain->visual,
				    AllocNone);
    }
  } else {
    
    /* alt ging schief fuer MESA auf Xterm 
       w->cMapMain = XCreateColormap(w->xDisplay, w->wRoot, w->vInfoMain->visual,
       AllocNone);
       */	
    /* RGB colormap is AllocNone, share the root colormap if possible */
    Screen *scr = DefaultScreenOfDisplay(w->xDisplay);
    if (MaxCmapsOfScreen(scr)==1
	&& w->vInfoMain->visual==DefaultVisual(w->xDisplay,w->xScreen)) {
      w->cMapMain = DefaultColormap(w->xDisplay,w->xScreen);
    }
    else {
      w->cMapMain = XCreateColormap(w->xDisplay, w->wRoot, w->vInfoMain->visual,
				    AllocNone);
    }
  }
/* PRE-MESA
   glwSetRGBMap(w,256, colorMaps);
   */   
  
  if (GLW_IS_INDEX(w->type) || w->vInfoMainClass==DirectColor) {
    glwSetRGBMap(w,256, colorMaps);
  }
  
  if (w->offscreen)
    create_pixmap(w,overlayFlag);
  else
    create_window(w,overlayFlag);

  

  if (!glwAttach(w))
    {
      glwDestroy(w);
      return NULL;	  
    }
  
  if (!glwLoadFont(w,0,"-*-helvetica-*-r-normal-*-16-*-*-*-*-*-iso8859-1"))
    glwLoadFont(w,0,"fixed");
  
  glwSetExposeFunc(w,default_expose_func);
  glwTrace("window ok");
  return w;
}

static void update_title(glWindow w)
{
  XTextProperty tp;
  if (w->state!=NULL) 
    {
      sprintf(w->xtitle,"%s [ %s ]",w->title,w->state);
      XStringListToTextProperty(&w->xtitle, 1, &tp);
    }
    else
      XStringListToTextProperty(&w->title, 1, &tp);
  
  XSetWMProperties(w->xDisplay, w->wMain, &tp, 0, 0, 0, 0, 0, 0);
  XFlush(w->xDisplay);
}

void glwShowState(glWindow w, char *state)
{
 if (state!=NULL)
   { 
     if (w->state==NULL)
       w->state=(char*)malloc(GLW_NAMELEN);
     strcpy(w->state,state);
   }
 else
  {
    free(w->state);
    w->state=NULL;
  }
 update_title(w);
}

void glwSetTitle(glWindow w, char *title)
{
  strcpy(w->title,title);
  update_title(w);
}

/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
void glwStartRecording(
		       glWindow win, 
		       char *fileNameStub,
		       int skip
		       )
{
  FILE *param_file=NULL;
  FILE *user_param_file=NULL;
  char *user_param_file_name;
  user_param_file_name=glwGetDefault(win,"mpegParams",NULL);
  if (user_param_file_name!=NULL) 
    {
      user_param_file=fopen(user_param_file_name,"r");
      if (user_param_file==NULL)
	glwError("user parameter file not found");
    }
  param_file=fopen(".glwin.mpeg.param","w");
  if (user_param_file==NULL) 
    /* set own default if user
       parameter file not given */
    {
      fprintf(param_file,"PATTERN  IBBPBBPBBPBBPBB\n");
      fprintf(param_file,"GOP_SIZE  30\n");
      fprintf(param_file,"SLICES_PER_FRAME 1\n");
      fprintf(param_file,"PIXEL	HALF\n");
      fprintf(param_file,"RANGE	10\n");
      fprintf(param_file,"PSEARCH_ALG	LOGARITHMIC\n");
      fprintf(param_file,"BSEARCH_ALG	CROSS2\n");
      fprintf(param_file,"IQSCALE 8\n");
      fprintf(param_file,"PQSCALE 10\n");
      fprintf(param_file,"BQSCALE  25\n");
      fprintf(param_file,"REFERENCE_FRAME	ORIGINAL\n");
    }
  else
    {
      while (!feof(user_param_file))
	{
	  fgets(glw_string_buffer,GLW_BUFSIZE,user_param_file);
	  fputs(glw_string_buffer,param_file);
	}
      fclose(user_param_file);
  }

  fprintf(param_file,"BASE_FILE_FORMAT	PNM\n");
  fprintf(param_file,"INPUT_DIR stdin\n");
  fprintf(param_file,"INPUT_CONVERT *\n");
  fprintf(param_file,"INPUT\n");
  fprintf(param_file,"END_INPUT\n");
  fprintf(param_file,"PNM_SIZE %dx%d\n",win->w,win->h);
  fprintf(param_file,"OUTPUT %s.mpg\n",fileNameStub);
  fclose(param_file);
  win->moviepipe=popen("mpeg_encode .glwin.mpeg.param","w");
  win->recorded_frame_num=0;
  win->frame_num=0;
  win->recording=1;
  if (skip<0) skip=0;
  win->skip=skip+1;
}

void glwStopRecording(glWindow win)
{
  win->recording=0;
  pclose(win->moviepipe);
  printf("%d frames recorded\n",win->recorded_frame_num);
}


#define GLW_SCREEN_WIDTH 2048
char pixelbuf[GLW_SCREEN_WIDTH*3];

void glwGrab(glWindow win, FILE *f)
{
  register int i;
  glPixelStorei(GL_PACK_ALIGNMENT, 1);
  glPixelStorei(GL_PACK_SWAP_BYTES, GL_TRUE);
  fprintf(f, "P6\n");
  fprintf(f, "%d %d\n", win->w, win->h);
  fprintf(f, "%d\n", 255);
  for(i=1;i<=win->h;i++)
    {
      glReadPixels(0, win->h-i, win->w,1, GL_RGB, GL_UNSIGNED_BYTE, pixelbuf);
      fwrite(pixelbuf, 3, win->w, f);
    }
}

void  glwGrabAndPrint(glWindow w)
{
  FILE *f;
  char *command;
  command=glwGetDefault(w,"printerCommand","pnmtops | lpr");
  f=popen(command,"w");
  glwGrab(w,f);
  pclose(f);
}

void  glwDump(
              glWindow win, 
              void * info, 
              char *fileName, 
              int w, 
              int h
              )
{
  FILE *f=fopen(fileName,"w");
  glwGrab(win,f);
  fclose(f);
}


/*
 * $Log: glwin.c,v $
 * Revision 2.28  1998/09/04  15:25:48  fuhrmann
 * skip frame option in StartRecording
 *
 * Revision 2.27  1998/07/09  14:39:52  fuhrmann
 * initialization bug in mpeg stuff removed
 *
 * Revision 2.26  1998/07/06  10:45:12  fuhrmann
 * Increased compiler warning level for all PDELIB-1.7 modules,
 * removed all bugs, some warnings remain (rcsids, ld_init, unused parameters)
 *
 * Revision 2.25  1998/05/18  17:19:27  fuhrmann
 * if file given in mpeg param ressource is not existent then invoke
 * default mechanism.
 *
 * Revision 2.24  1998/03/11  19:21:04  fuhrmann
 * Hey we can create batch videos! (still beta, but...)
 *
 * Revision 2.23  1998/03/06  16:45:31  fuhrmann
 * tiff->ppm
 * print command
 * video recording
 *
 * Revision 2.22  1998/03/05  20:01:24  fuhrmann
 * interim test version with SGI movie lib : it was a mess...
 *
 * Revision 2.21  1998/01/26  11:07:28  schmelze
 * tests from external working directory, box*test.html
 *
 * Revision 2.20  1998/01/14  18:27:34  fuhrmann
 * Merge mit Ilja
 *
 * Revision 2.19  1997/11/27  19:03:09  fuhrmann
 * glwRecord stuff, PAL-Format, tex-file for keys
 *
 * Revision 2.18  1997/11/04  15:53:30  fuhrmann
 * color scales ; crash with glrnd
 *
 * Revision 2.17  1997/10/17  16:54:58  fuhrmann
 * glwFlush
 *
 * Revision 2.16  1997/10/01  15:41:27  fuhrmann
 * GLW_MOD1
 *
 * Revision 2.15  1997/09/09  17:42:28  fuhrmann
 * cursor stuff
 *
 * Revision 2.14  1997/04/15  08:10:22  fuhrmann
 * still not clear which font to load...
 *
 * Revision 2.13  1997/03/20  18:19:18  fuhrmann
 * glwGrab in no-tiff case
 *
 * Revision 2.12  1997/02/28  17:41:13  fuhrmann
 * glwGrab code
 *
 * Revision 2.11  1997/01/27  14:30:45  fuhrmann
 * other default font
 *
 * Revision 2.10  1996/10/09  16:33:57  fuhrmann
 * keys next, prev, tab
 *
 * Revision 2.9  1996/10/02  11:12:05  fuhrmann
 * some debugging in visual stuff, no change of algorithm
 *
 * Revision 2.8  1996/09/23  17:47:27  fuhrmann
 * -DUSE_OS_MESA for mesa offscreen contexts
 *
 * Revision 2.7  1996/09/19  16:57:34  fuhrmann
 * typo in glwProcess removed
 *
 * Revision 2.6  1996/09/19  16:33:39  fuhrmann
 * GLW_DEPTH in default mode
 * redraw first when enterinh glw_process in event mode
 *
 * Revision 2.5  1996/09/03  09:22:41  fuhrmann
 * tiffio.h location changed
 *
 * Revision 2.4  1996/09/03  09:09:04  fuhrmann
 * - fonts & printing characters
 * - keep aspect ratio
 * - dump pixmap size can default to window size
 *
 * Revision 2.3  1996/08/30  10:47:34  fuhrmann
 * Default expose function set (glw should redraw in event driven
 * mode if user has no callbacks set)
 *
 * Revision 2.2  1996/04/17  16:47:56  fuhrmann
 * error in off-screen rendering: PixelAlignment in GL buf was wrong
 * error in off-screen rendering: wrong count of lines (black upper line in GL dump) fixed
 *
 * Revision 2.1  1996/03/12  09:49:27  fuhrmann
 * Off-screen rendering into memory with large pixmaps using osmesa
 *
 * Revision 2.0  1996/02/15  20:26:14  fuhrmann
 * First meta-stable distribution
 *
 * Revision 1.9  1996/02/15  20:25:00  fuhrmann
 * - Error in return value for glwDump removed
 *
 * Revision 1.8  1996/02/15  14:18:20  fuhrmann
 * - improved behaviour when tiff file not opened
 *
 * Revision 1.7  1996/02/09  16:45:02  fuhrmann
 * - shift keys now part of button mask
 * - more keysyms available
 *
 * Revision 1.6  1996/02/06  09:59:46  fuhrmann
 * - glwDump ( depends on libtiff.a !)
 * - glwSetIdleFunc and glwSetDisplayFunc obsolete,
 *   use glwSetRedrawFunc & glwSetControlMode (better to understand)
 *
 * Revision 1.5  1996/01/30  18:36:15  fuhrmann
 * Changed default title to gltools-1.0
 *
 * Revision 1.4  1995/11/08  12:05:39  fuhrmann
 * glwSetTitle introduced
 *
 * Revision 1.3  1995/10/24  18:34:15  fuhrmann
 * Namelen von 64 auf 128  ???
 * Merge mit libtk 1.1 (dmPolicy stuff) vielleicht unnoetig...
 *
 * Revision 1.2  1995/10/24  12:40:51  fuhrmann
 * Zeilennr in glwError
 *
 * Revision 1.1  1995/10/20  15:42:03  fuhrmann
 * Initial revision
 *
 */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?