Example #1
0
GLboolean glewCreateContext (struct createParams *params)
{
    int attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None };
    int erb, evb;
    XSetWindowAttributes swa;
    /* open display */
    dpy = XOpenDisplay(params->display);
    if (NULL == dpy) return GL_TRUE;
    /* query for glx */
    if (!glXQueryExtension(dpy, &erb, &evb)) return GL_TRUE;
    /* choose visual */
    if (params->visual == -1)
    {
        vi = glXChooseVisual(dpy, DefaultScreen(dpy), attrib);
        if (NULL == vi) return GL_TRUE;
        params->visual = (int)XVisualIDFromVisual(vi->visual);
    }
    else
    {
        int n_vis, i;
        vis = XGetVisualInfo(dpy, 0, NULL, &n_vis);
        for (i=0; i<n_vis; i++)
        {
            if ((int)XVisualIDFromVisual(vis[i].visual) == params->visual)
                vi = &vis[i];
        }
        if (vi == NULL) return GL_TRUE;
    }
    /* create context */
    ctx = glXCreateContext(dpy, vi, None, True);
    if (NULL == ctx) return GL_TRUE;
    /* create window */
    /*wnd = XCreateSimpleWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 1, 1, 1, 0, 0);*/
    cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
    swa.border_pixel = 0;
    swa.colormap = cmap;
    wnd = XCreateWindow(dpy, RootWindow(dpy, vi->screen),
                        0, 0, 1, 1, 0, vi->depth, InputOutput, vi->visual,
                        CWBorderPixel | CWColormap, &swa);
    /* make context current */
    if (!glXMakeCurrent(dpy, wnd, ctx)) return GL_TRUE;
    if (params->major || params->profile || params->flags)
    {
        GLXContext oldCtx = ctx;
        GLXFBConfig *FBConfigs;
        int FBConfigAttrs[] = { GLX_FBCONFIG_ID, 0, None };
        int contextAttrs[20];
        int nelems, i;

        glxewInit();

        if (!glxewGetExtension("GLX_ARB_create_context"))
            return GL_TRUE;

        if (glXQueryContext(dpy, oldCtx, GLX_FBCONFIG_ID, &FBConfigAttrs[1]))
            return GL_TRUE;
        FBConfigs = glXChooseFBConfig(dpy, vi->screen, FBConfigAttrs, &nelems);

        if (nelems < 1)
            return GL_TRUE;

        i = 0;
        if (params->major)
        {
            contextAttrs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB;
            contextAttrs[i++] = params->major;
            contextAttrs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB;
            contextAttrs[i++] = params->minor;
        }
        if (params->profile)
        {
            contextAttrs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB;
            contextAttrs[i++] = params->profile;
        }
        if (params->flags)
        {
            contextAttrs[i++] = GLX_CONTEXT_FLAGS_ARB;
            contextAttrs[i++] = params->flags;
        }
        contextAttrs[i++] = None;
        ctx = glXCreateContextAttribsARB(dpy, *FBConfigs, NULL, True, contextAttrs);

        if (NULL == ctx) return GL_TRUE;
        if (!glXMakeCurrent(dpy, wnd, ctx)) return GL_TRUE;

        glXDestroyContext(dpy, oldCtx);

        XFree(FBConfigs);
    }
    return GL_FALSE;
}
Example #2
0
void CGLContextGLX::Destroy()
{
  glXMakeCurrent(m_dpy, None, NULL);
  glXDestroyContext(m_dpy, m_glxContext);
  m_glxContext = 0;
}
Example #3
0
bool CGLContextGLX::Refresh(bool force, int screen, Window glWindow, bool &newContext)
{
  bool retVal = false;
  m_glxWindow = glWindow;
  m_nScreen = screen;

  // refresh context
  if (m_glxContext && !force)
  {
    CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context");
    glXMakeCurrent(m_dpy, None, NULL);
    glXMakeCurrent(m_dpy, glWindow, m_glxContext);
    return true;
  }

  // create context

  XVisualInfo vMask;
  XVisualInfo *visuals;
  XVisualInfo *vInfo = NULL;
  int availableVisuals = 0;
  vMask.screen = screen;
  XWindowAttributes winAttr;

  /* Assume a depth of 24 in case the below calls to XGetWindowAttributes()
     or XGetVisualInfo() fail. That shouldn't happen unless something is
     fatally wrong, but lets prepare for everything. */
  vMask.depth = 24;

  if (XGetWindowAttributes(m_dpy, glWindow, &winAttr))
  {
    vMask.visualid = XVisualIDFromVisual(winAttr.visual);
    vInfo = XGetVisualInfo(m_dpy, VisualScreenMask | VisualIDMask, &vMask, &availableVisuals);
    if (!vInfo)
      CLog::Log(LOGWARNING, "Failed to get VisualInfo of visual 0x%x", (unsigned) vMask.visualid);
    else if(!IsSuitableVisual(vInfo))
    {
      CLog::Log(LOGWARNING, "Visual 0x%x of the window is not suitable, looking for another one...",
                (unsigned) vInfo->visualid);
      vMask.depth = vInfo->depth;
      XFree(vInfo);
      vInfo = NULL;
    }
  }
  else
    CLog::Log(LOGWARNING, "Failed to get window attributes");

  /* As per glXMakeCurrent documentation, we have to use the same visual as
     m_glWindow. Since that was not suitable for use, we try to use another
     one with the same depth and hope that the used implementation is less
     strict than the documentation. */
  if (!vInfo)
  {
    visuals = XGetVisualInfo(m_dpy, VisualScreenMask | VisualDepthMask, &vMask, &availableVisuals);
    for (int i = 0; i < availableVisuals; i++)
    {
      if (IsSuitableVisual(&visuals[i]))
      {
        vMask.visualid = visuals[i].visualid;
        vInfo = XGetVisualInfo(m_dpy, VisualScreenMask | VisualIDMask, &vMask, &availableVisuals);
        break;
      }
    }
    XFree(visuals);
  }

  if (vInfo)
  {
    CLog::Log(LOGNOTICE, "Using visual 0x%x", (unsigned) vInfo->visualid);
    if (m_glxContext)
    {
      glXMakeCurrent(m_dpy, None, NULL);
      glXDestroyContext(m_dpy, m_glxContext);
      XSync(m_dpy, FALSE);
    }

    if ((m_glxContext = glXCreateContext(m_dpy, vInfo, NULL, True)))
    {
      // make this context current
      glXMakeCurrent(m_dpy, glWindow, m_glxContext);
      retVal = true;
    }
    else
      CLog::Log(LOGERROR, "GLX Error: Could not create context");

    XFree(vInfo);
  }
  else
  {
    CLog::Log(LOGERROR, "GLX Error: vInfo is NULL!");
  }

  return retVal;
}
Example #4
0
ENTRYPOINT void draw_providence(ModeInfo * mi) 
{
  providencestruct *mp;
  
  Display    *display = MI_DISPLAY(mi);
  Window      window = MI_WINDOW(mi);
  
  if(!providence)
    return;
  mp = &providence[MI_SCREEN(mi)];
  
  MI_IS_DRAWN(mi) = True;
  
  if(!mp->glx_context)
    return;
  
  glXMakeCurrent(display, window, *(mp->glx_context));
  
  /* setup twoside lighting */
  glLightfv(GL_LIGHT0, GL_AMBIENT, ambient2);
  glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  glLightfv(GL_LIGHT0, GL_POSITION, mp->position0);

  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);

  glEnable(GL_NORMALIZE);
  glFrontFace(GL_CCW);
/*   glDisable(GL_CULL_FACE); */
  glEnable(GL_CULL_FACE);
  glCullFace(GL_BACK);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  glShadeModel(GL_SMOOTH);
  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LEQUAL);

  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glPushMatrix();
  glRotatef(current_device_rotation(), 0, 0, 1);

  /* modify camera */
  if(fabs(mp->camera_velocity) > EPSILON) {
    mp->camera_z = max(min(mp->camera_z + 0.1*mp->camera_velocity, -4.0), -12.0);
    mp->camera_velocity = 0.95*mp->camera_velocity;
  }
  
  /* rotate providence */
  glTranslatef(0.0, 0.0, mp->camera_z + sin(mp->theta/4.0));
  glRotatef(10.0+20.0*sin(mp->theta/2.0), 1.0, 0.0, 0.0);
  gltrackball_rotate(mp->trackball);
  glRotatef(mp->theta * 180.0 / Pi, 0.0, -1.0, 0.0);

# ifdef HAVE_MOBILE	/* Keep it the same relative size when rotated. */
  {
    GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
    int o = (int) current_device_rotation();
    if (o != 0 && o != 180 && o != -180)
      glScalef (1/h, 1/h, 1/h);
  }
# endif

  /* draw providence */
  draw_providence_strip(mi);
  glPopMatrix();
  
  if(MI_IS_FPS(mi)) do_fps (mi);
  glFlush();
  
  glXSwapBuffers(display, window);

  /* update */
  mp->currenttime += 1.0 / FPS;
  mp->theta = mp->currenttime / 2.0 * mp->theta_scale;
  update_particles(mp);
}
Example #5
0
void SkNativeGLContext::makeCurrent() const {
    if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) {
        SkDebugf("Could not set the context.\n");
    }
}
//----------------------------------------------------------------------------//
void OpenGLGLXPBTextureTarget::disablePBuffer() const
{
    // switch back to rendering to previous set up
    if (!glXMakeCurrent(d_prevDisplay, d_prevDrawable, d_prevContext))
        std::cerr << "Failed to switch from pbuffer rendering" << std::endl;
}
void X11OpenGLWindow::disableOpenGL()
{
    glXMakeCurrent(m_data->m_dpy, None, NULL);
 	glXDestroyContext(m_data->m_dpy, m_data->m_glc);
}
VdpStatus
vdpDeviceDestroy(VdpDevice device)
{
    VdpStatus err_code;
    VdpDeviceData *data = handle_acquire(device, HANDLETYPE_DEVICE);
    if (NULL == data)
        return VDP_STATUS_INVALID_HANDLE;

    if (0 != data->refcount) {
        // Buggy client forgot to destroy dependend objects or decided that destroying
        // VdpDevice destroys all child object. Let's try to mitigate and prevent leakage.
        traceError("warning (%s): non-zero reference count (%d). Trying to free child objects.\n",
                   __func__, data->refcount);
        void *parent_object = data;
        handle_execute_for_all(destroy_child_objects, parent_object);
    }

    if (0 != data->refcount) {
        traceError("error (%s): still non-zero reference count (%d)\n", __func__, data->refcount);
        traceError("Here is the list of objects:\n");
        struct {
            int cnt;
            int total_cnt;
            VdpDeviceData *deviceData;
        } state = { .cnt = 0, .total_cnt = 0, .deviceData = data };

        handle_execute_for_all(print_handle_type, &state);
        traceError("Objects leaked: %d\n", state.cnt);
        traceError("Objects visited during scan: %d\n", state.total_cnt);
        err_code = VDP_STATUS_ERROR;
        goto quit;
    }

    // cleaup libva
    if (data->va_available)
        vaTerminate(data->va_dpy);

    glx_ctx_push_thread_local(data);
    glDeleteTextures(1, &data->watermark_tex_id);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    destroy_shaders(data);
    glx_ctx_pop();

    glx_ctx_lock();
    glXMakeCurrent(data->display, None, NULL);
    glx_ctx_unlock();

    glx_ctx_unref_glc_hash_table(data->display);

    handle_xdpy_unref(data->display_orig);
    handle_expunge(device);
    pthread_mutex_destroy(&data->refcount_mutex);
    free(data);

    GLenum gl_error = glGetError();
    if (GL_NO_ERROR != gl_error) {
        traceError("error (%s): gl error %d\n", __func__, gl_error);
        err_code = VDP_STATUS_ERROR;
        goto quit_skip_release;
    }

    return VDP_STATUS_OK;

quit:
    handle_release(device);
quit_skip_release:
    return err_code;
}
Example #9
0
ENTRYPOINT void
draw_stream (ModeInfo *mi)
{
  stream_configuration *es = &ess[MI_SCREEN(mi)];
  Display *dpy = MI_DISPLAY(mi);
  Window window = MI_WINDOW(mi);
  streamtime current_time;
  float cur_time;
  int i;
  float alpha = 1.0;
  Vector vx;
  Vector vy;
  GLfloat m[4*4];

  if (!es->glx_context)
    return;

  gettime (&current_time);

  cur_time = (float)(GETSECS(current_time) * 1000 + GETMSECS(current_time) - es->start_time) / 1000.0;
  cur_time *= global_speed;

  glXMakeCurrent (MI_DISPLAY(mi), MI_WINDOW(mi), *es->glx_context);

  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glMatrixMode (GL_PROJECTION);
  glLoadIdentity ();
  glFrustum (-.6f, .6f, -.45f, .45f, 1, 1000);

  glMatrixMode (GL_MODELVIEW);
  glLoadIdentity ();

  glEnable (GL_LIGHTING);
  glEnable (GL_TEXTURE_2D);
  glEnable (GL_BLEND);
  glBlendFunc (GL_SRC_ALPHA, GL_ONE);
  glDisable (GL_CULL_FACE);
  glDisable (GL_DEPTH_TEST);
  glDepthMask (0);

  glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);

  glTranslatef (0, 0, -300);
  glRotatef (cur_time * 30, 1, 0, 0);
  glRotatef (30 * sin(cur_time / 3) + 10, 0, 0, 1);

  {
    double x, y, z;
    get_position (es->rot, &x, &y, &z, !es->button_down_p);
    glTranslatef((x - 0.5) * 8,
                 (y - 0.5) * 8,
                 (z - 0.5) * 15);

    gltrackball_rotate (es->trackball);

    get_rotation (es->rot, &x, &y, &z, !es->button_down_p);
    glRotatef (x * 360, 1.0, 0.0, 0.0);
    glRotatef (y * 360, 0.0, 1.0, 0.0);
    glRotatef (z * 360, 0.0, 0.0, 1.0);
  }

  if (cur_time > change_time1)
  {
    if (cur_time > change_time2)
    {
      glRotatef (90, 0, 1, 0);

      if (cur_time > change_time3)
        es->start_time = GETSECS(current_time) * 1000 + GETMSECS(current_time) - 5000;
    }
    else
    {
      glRotatef (180, 0, 1, 0);
    }
  }

  glEnable ( GL_FOG);
  glFogf (GL_FOG_START, 200);
  glFogf (GL_FOG_END, 500);
  glFogf (GL_FOG_MODE, GL_LINEAR);

  glGetFloatv (GL_MODELVIEW_MATRIX, m);

  inverse_matrix (m);

  vx.x = m[0] * 10;
  vx.y = m[1] * 10;
  vx.z = m[2] * 10;

  vy.x = m[4] * 10;
  vy.y = m[5] * 10;
  vy.z = m[6] * 10;

  mi->polygon_count = 0;

  for (i = 0; i != es->num_streams; i++)
  {
    mi->polygon_count += es->streams[i].num_flares;
    render_flare_stream (&es->streams[i], cur_time, &vx, &vy, alpha);
  }

  glDisable (GL_TEXTURE_2D);
  glDisable (GL_LIGHTING);
  glDisable (GL_FOG);
  glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

  if (mi->fps_p) do_fps (mi);
  glFinish();

  glXSwapBuffers (dpy, window);
}
Example #10
0
int
main(int argc, char *argv[])
{
   unsigned int winWidth = 300, winHeight = 300;
   int x = 0, y = 0;
   Display *dpy;
   Window win;
   GLXContext ctx;
   char *dpyName = NULL;
   GLboolean printInfo = GL_FALSE;
   int i;

   for (i = 1; i < argc; i++) {
      if (strcmp(argv[i], "-display") == 0) {
         dpyName = argv[i+1];
         i++;
      }
      else if (strcmp(argv[i], "-info") == 0) {
         printInfo = GL_TRUE;
      }
      else if (strcmp(argv[i], "-stereo") == 0) {
         stereo = GL_TRUE;
      }
      else if (strcmp(argv[i], "-fullscreen") == 0) {
         fullscreen = GL_TRUE;
      }
      else if (i < argc-1 && strcmp(argv[i], "-geometry") == 0) {
         XParseGeometry(argv[i+1], &x, &y, &winWidth, &winHeight);
         i++;
      }
      else {
         usage();
         return -1;
      }
   }

   dpy = XOpenDisplay(dpyName);
   if (!dpy) {
      printf("Error: couldn't open display %s\n",
	     dpyName ? dpyName : getenv("DISPLAY"));
      return -1;
   }

   make_window(dpy, "glxgears", x, y, winWidth, winHeight, &win, &ctx);
   XMapWindow(dpy, win);
   glXMakeCurrent(dpy, win, ctx);
   query_vsync(dpy);

   if (printInfo) {
      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
   }

   init();

   /* Set initial projection/viewing transformation.
    * We can't be sure we'll get a ConfigureNotify event when the window
    * first appears.
    */
   reshape(winWidth, winHeight);

   event_loop(dpy, win);

   glDeleteLists(gear1, 1);
   glDeleteLists(gear2, 1);
   glDeleteLists(gear3, 1);
   glXMakeCurrent(dpy, None, NULL);
   glXDestroyContext(dpy, ctx);
   XDestroyWindow(dpy, win);
   XCloseDisplay(dpy);

   return 0;
}
Example #11
0
int main(int argc, char *argv[])
{
   static int glAttribs[] = {
      GLX_DOUBLEBUFFER,
      GLX_RGBA,
      GLX_DEPTH_SIZE, 1,
      None
   };
   Display *dpy;
   XVisualInfo *visInfo;
   int scrn;
   Window root;
   Colormap cmap;
   Window win;
   XSetWindowAttributes winAttribs;
   unsigned long winAttribsMask;
   GLXContext glCtx;
   int ignore;
   const char *name = "OpenGL in a Shaped Window";

   dpy = XOpenDisplay(NULL);
   if (!dpy) {
      fprintf(stderr, "Couldn't open default display\n");
      return 1;
   }

   /* check that we can use the shape extension */
   if (!XQueryExtension(dpy, "SHAPE", &ignore, &ignore, &ignore )) {
      fprintf(stderr, "Display doesn't support shape extension\n");
      return 1;
   }

   scrn = DefaultScreen(dpy);

   root = RootWindow(dpy, scrn);

   visInfo = glXChooseVisual(dpy, scrn, glAttribs);
   if (!visInfo) {
      fprintf(stderr, "Couldn't get RGB, DB, Z visual\n");
      return 1;
   }

   glCtx = glXCreateContext(dpy, visInfo, 0, True);
   if (!glCtx) {
      fprintf(stderr, "Couldn't create GL context\n");
      return 1;
   }

   cmap = alloc_colormap(dpy, root, visInfo->visual);
   if (!cmap) {
      fprintf(stderr, "Couln't create colormap\n");
      return 1;
   }

   winAttribs.border_pixel = 0;
   winAttribs.colormap = cmap;
   winAttribs.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
   winAttribsMask = CWBorderPixel | CWColormap | CWEventMask;
   win = XCreateWindow(dpy, root, 0, 0, Width, Height, 0,
                       visInfo->depth, InputOutput,
                       visInfo->visual,
                       winAttribsMask, &winAttribs);

   {
      XSizeHints sizehints;
      /*
      sizehints.x = xpos;
      sizehints.y = ypos;
      sizehints.width  = width;
      sizehints.height = height;
      */
      sizehints.flags = 0;
      XSetNormalHints(dpy, win, &sizehints);
      XSetStandardProperties(dpy, win, name, name,
                              None, (char **)NULL, 0, &sizehints);
   }


   XMapWindow(dpy, win);

   glXMakeCurrent(dpy, win, glCtx);

   printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
   printf("Press ESC to exit.\n");
   printf("Press up/down to change window shape.\n");

   event_loop(dpy, win);

   return 0;
}
Example #12
0
static void
print_screen_info(Display *dpy, int scrnum, Bool allowDirect, GLboolean limits)
{
   Window win;
   int attribSingle[] = {
      GLX_RGBA,
      GLX_RED_SIZE, 1,
      GLX_GREEN_SIZE, 1,
      GLX_BLUE_SIZE, 1,
      None };
   int attribDouble[] = {
      GLX_RGBA,
      GLX_RED_SIZE, 1,
      GLX_GREEN_SIZE, 1,
      GLX_BLUE_SIZE, 1,
      GLX_DOUBLEBUFFER,
      None };

   XSetWindowAttributes attr;
   unsigned long mask;
   Window root;
   GLXContext ctx = NULL;
   XVisualInfo *visinfo;
   int width = 100, height = 100;

   root = RootWindow(dpy, scrnum);

   /*
    * Find a basic GLX visual.  We'll then create a rendering context and
    * query various info strings.
    */
   visinfo = glXChooseVisual(dpy, scrnum, attribSingle);
   if (!visinfo)
      visinfo = glXChooseVisual(dpy, scrnum, attribDouble);

   if (visinfo)
      ctx = glXCreateContext( dpy, visinfo, NULL, allowDirect );

#ifdef GLX_VERSION_1_3
   /* Try glXChooseFBConfig() if glXChooseVisual didn't work.
    * XXX when would that happen?
    */
   if (!visinfo) {
      int fbAttribSingle[] = {
	 GLX_RENDER_TYPE,   GLX_RGBA_BIT,
	 GLX_RED_SIZE,      1,
	 GLX_GREEN_SIZE,    1,
	 GLX_BLUE_SIZE,     1,
	 GLX_DOUBLEBUFFER,  GL_FALSE,
	 None };
      int fbAttribDouble[] = {
	 GLX_RENDER_TYPE,   GLX_RGBA_BIT,
	 GLX_RED_SIZE,      1,
	 GLX_GREEN_SIZE,    1,
	 GLX_BLUE_SIZE,     1,
	 GLX_DOUBLEBUFFER,  GL_TRUE,
	 None };
      GLXFBConfig *configs = NULL;
      int nConfigs;

      configs = glXChooseFBConfig(dpy, scrnum, fbAttribSingle, &nConfigs);
      if (!configs)
	 configs = glXChooseFBConfig(dpy, scrnum, fbAttribDouble, &nConfigs);

      if (configs) {
	 visinfo = glXGetVisualFromFBConfig(dpy, configs[0]);
	 ctx = glXCreateNewContext(dpy, configs[0], GLX_RGBA_TYPE, NULL, allowDirect);
	 XFree(configs);
      }
   }
#endif

   if (!visinfo) {
      fprintf(stderr, "Error: couldn't find RGB GLX visual or fbconfig\n");
      return;
   }

   if (!ctx) {
      fprintf(stderr, "Error: glXCreateContext failed\n");
      XFree(visinfo);
      return;
   }

   attr.background_pixel = 0;
   attr.border_pixel = 0;
   attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
   attr.event_mask = StructureNotifyMask | ExposureMask;
   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
   win = XCreateWindow(dpy, root, 0, 0, width, height,
		       0, visinfo->depth, InputOutput,
		       visinfo->visual, mask, &attr);

   if (glXMakeCurrent(dpy, win, ctx)) {
      const char *serverVendor = glXQueryServerString(dpy, scrnum, GLX_VENDOR);
      const char *serverVersion = glXQueryServerString(dpy, scrnum, GLX_VERSION);
      const char *serverExtensions = glXQueryServerString(dpy, scrnum, GLX_EXTENSIONS);
      const char *clientVendor = glXGetClientString(dpy, GLX_VENDOR);
      const char *clientVersion = glXGetClientString(dpy, GLX_VERSION);
      const char *clientExtensions = glXGetClientString(dpy, GLX_EXTENSIONS);
      const char *glxExtensions = glXQueryExtensionsString(dpy, scrnum);
      const char *glVendor = (const char *) glGetString(GL_VENDOR);
      const char *glRenderer = (const char *) glGetString(GL_RENDERER);
      const char *glVersion = (const char *) glGetString(GL_VERSION);
      const char *glExtensions = (const char *) glGetString(GL_EXTENSIONS);
      int glxVersionMajor;
      int glxVersionMinor;
      char *displayName = NULL;
      char *colon = NULL, *period = NULL;
      
      if (! glXQueryVersion( dpy, & glxVersionMajor, & glxVersionMinor )) {
         fprintf(stderr, "Error: glXQueryVersion failed\n");
         exit(1);
      }

      /* Strip the screen number from the display name, if present. */
      if (!(displayName = (char *) malloc(strlen(DisplayString(dpy)) + 1))) {
         fprintf(stderr, "Error: malloc() failed\n");
         exit(1);
      }
      strcpy(displayName, DisplayString(dpy));
      colon = strrchr(displayName, ':');
      if (colon) {
         period = strchr(colon, '.');
         if (period)
            *period = '\0';
      }
      printf("display: %s  screen: %d\n", displayName, scrnum);
      free(displayName);
      printf("direct rendering: ");
      if (glXIsDirect(dpy, ctx)) {
         printf("Yes\n");
      } else {
         if (!allowDirect) {
            printf("No (-i specified)\n");
         } else if (getenv("LIBGL_ALWAYS_INDIRECT")) {
            printf("No (LIBGL_ALWAYS_INDIRECT set)\n");
         } else {
            printf("No (If you want to find out why, try setting "
                   "LIBGL_DEBUG=verbose)\n");
         }
      }
      printf("server glx vendor string: %s\n", serverVendor);
      printf("server glx version string: %s\n", serverVersion);
      printf("server glx extensions:\n");
      print_extension_list(serverExtensions);
      printf("client glx vendor string: %s\n", clientVendor);
      printf("client glx version string: %s\n", clientVersion);
      printf("client glx extensions:\n");
      print_extension_list(clientExtensions);
      printf("GLX version: %u.%u\n", glxVersionMajor, glxVersionMinor);
      printf("GLX extensions:\n");
      print_extension_list(glxExtensions);
      printf("OpenGL vendor string: %s\n", glVendor);
      printf("OpenGL renderer string: %s\n", glRenderer);
      printf("OpenGL version string: %s\n", glVersion);
#ifdef GL_VERSION_2_0
      if (glVersion[0] >= '2' && glVersion[1] == '.') {
         char *v = (char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
         printf("OpenGL shading language version string: %s\n", v);
      }
#endif

      printf("OpenGL extensions:\n");
      print_extension_list(glExtensions);
      if (limits)
         print_limits(glExtensions);
   }
   else {
      fprintf(stderr, "Error: glXMakeCurrent failed\n");
   }

   glXDestroyContext(dpy, ctx);
   XFree(visinfo);
   XDestroyWindow(dpy, win);
}
int main() {

	hvLogInit(HV_LOG_INFO, stdout);
	hvPrint("HyperVision design approach test programme: X + GLX + OpenGL");

	/* Open X Display */
	Display *x_dsp = XOpenDisplay(NULL);
	hvErrorCheck(!x_dsp, "Failed to open X display");

	/* Check and report GLX version*/ 
	int glx_maj = 0, glx_min = 0;
	glXQueryVersion(x_dsp, &glx_maj, &glx_min);
	hvErrorCheck(glx_maj * 10 + glx_min < 14, "Invalid GLX version (1.4 required)"); //*1
	hvInfo("GLX version: ", glXGetClientString(x_dsp, GLX_VERSION));

	/* Choose best GLX FB configuration and get the GLX visual */
	static int glx_fb_atr[] = {
		GLX_X_RENDERABLE    , True,
		GLX_DRAWABLE_TYPE   , GLX_WINDOW_BIT,
		GLX_RENDER_TYPE     , GLX_RGBA_BIT,
		GLX_X_VISUAL_TYPE   , GLX_TRUE_COLOR,
		GLX_CONFIG_CAVEAT   , GLX_NONE,
		GLX_RED_SIZE        , 8,
		GLX_GREEN_SIZE      , 8,
		GLX_BLUE_SIZE       , 8,
		GLX_ALPHA_SIZE      , 8,
		GLX_DEPTH_SIZE      , 24,
		GLX_STENCIL_SIZE    , 8,
		GLX_DOUBLEBUFFER    , True,
		None
    };
	int glx_fb_cnt;
	GLXFBConfig *glx_fb_cfg = glXChooseFBConfig(x_dsp, DefaultScreen(x_dsp), glx_fb_atr, &glx_fb_cnt);
	hvErrorCheck(!glx_fb_cfg, "Failed to retrieve a framebuffer config");
	// Pick the FB config with the most samples per pixel
	int top_fbc = 0, top_smp = 0, smp;
	for (int i = 0; i < glx_fb_cnt; i++) {
		glXGetFBConfigAttrib(x_dsp, glx_fb_cfg[i], GLX_SAMPLES, &smp);
		if (smp > top_smp) top_fbc = i, top_smp = smp;
	}
	GLXFBConfig glx_fbc = glx_fb_cfg[top_fbc];
	XFree(glx_fb_cfg);
	XVisualInfo *glx_vsl = glXGetVisualFromFBConfig(x_dsp, glx_fbc);
	hvInfo("Chosen visual ID = ", hvHex(glx_vsl->visualid));

	/* Create and map X window */
	Colormap x_cmap = XCreateColormap(x_dsp, RootWindow(x_dsp, glx_vsl->screen), glx_vsl->visual, AllocNone);
	XSetWindowAttributes x_swa;
	x_swa.colormap = x_cmap;
	x_swa.background_pixmap = None;
	x_swa.border_pixel = 0;
	x_swa.event_mask = StructureNotifyMask;
	Window x_wnd = XCreateWindow(x_dsp, RootWindow(x_dsp, glx_vsl->screen), 0, 0, 100, 100, 0, glx_vsl->depth,
	                             InputOutput, glx_vsl->visual, CWBorderPixel|CWColormap|CWEventMask, &x_swa);
	hvErrorCheck(!x_wnd, "Failed to create window");
	XFree(glx_vsl);
	XStoreName(x_dsp, x_wnd, "HyperVision GLX test");
	XMapWindow(x_dsp, x_wnd);

	/* Retreive GLX_ARB_create_context extension and create OpenGL 3.0 context */
	int context_attribs[] = {
		GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
		GLX_CONTEXT_MINOR_VERSION_ARB, 0,
		GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
		GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
		None
	};
	const char *glx_exts = glXQueryExtensionsString(x_dsp, DefaultScreen(x_dsp));
	glXCreateContextAttribsARBProc glXCreateContextAttribsARB = NULL;
	glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddress((const GLubyte*) "glXCreateContextAttribsARB");
	hvErrorCheck(!hvInSet(glx_exts, "GLX_ARB_create_context") || !glXCreateContextAttribsARB, "GLX_ARB_create_context extension missing");
	GLXContext glx_ctx = glXCreateContextAttribsARB(x_dsp, glx_fbc, 0, True, context_attribs );
 
	if (!glXIsDirect(x_dsp, glx_ctx)) {
		hvInfo("GLX rendering context: indirect");
	}
	else	{
		hvInfo("GLX rendering context: DRI");
	}

	/* Render OpenGL scene */
	glXMakeCurrent(x_dsp, x_wnd, glx_ctx);

	glClearColor(0, 0.5, 1, 1);
	glClear (GL_COLOR_BUFFER_BIT);
	glXSwapBuffers(x_dsp, x_wnd);
	sleep(1);

	glClearColor(1, 0.5, 0, 1);
	glClear(GL_COLOR_BUFFER_BIT);
	glXSwapBuffers(x_dsp, x_wnd);
	sleep(1);

	glXMakeCurrent(x_dsp, 0, 0);

	/* Release used resources */
	glXDestroyContext(x_dsp, glx_ctx);
	XDestroyWindow(x_dsp, x_wnd);
	XFreeColormap(x_dsp, x_cmap);
	XCloseDisplay(x_dsp);
}
Example #14
0
int
main (int argc, char **argv)
{

#ifdef WIN32
  HGLRC sdl_gl_context = 0;
  HDC sdl_dc = 0;
#else
  SDL_SysWMinfo info;
  Display *sdl_display = NULL;
  Window sdl_win = 0;
  GLXContext sdl_gl_context = NULL;
#endif

  GMainLoop *loop = NULL;
  GstPipeline *pipeline = NULL;
  GstBus *bus = NULL;
  GstElement *glfilter = NULL;
  GstElement *fakesink = NULL;
  GstState state;
  GAsyncQueue *queue_input_buf = NULL;
  GAsyncQueue *queue_output_buf = NULL;
  GstGLDisplay *display;
  GstGLContext *sdl_context;
  const gchar *platform;

  /* Initialize SDL for video output */
  if (SDL_Init (SDL_INIT_VIDEO) < 0) {
    fprintf (stderr, "Unable to initialize SDL: %s\n", SDL_GetError ());
    return -1;
  }

  /* Create a 640x480 OpenGL screen */
  if (SDL_SetVideoMode (640, 480, 0, SDL_OPENGL) == NULL) {
    fprintf (stderr, "Unable to create OpenGL screen: %s\n", SDL_GetError ());
    SDL_Quit ();
    return -1;
  }

  /* Set the title bar in environments that support it */
  SDL_WM_SetCaption ("SDL and gst-plugins-gl", NULL);


  /* Loop, drawing and checking events */
  InitGL (640, 480);

  gst_init (&argc, &argv);
  loop = g_main_loop_new (NULL, FALSE);

  /* retrieve and turn off sdl opengl context */
#ifdef WIN32
  sdl_gl_context = wglGetCurrentContext ();
  sdl_dc = wglGetCurrentDC ();
  wglMakeCurrent (0, 0);
  platform = "wgl";
  display = gst_gl_display_new ();
#else
  SDL_VERSION (&info.version);
  SDL_GetWMInfo (&info);
  /* FIXME: This display is different to the one that SDL uses to create the
   * GL context inside SDL_SetVideoMode() above which fails on Intel hardware
   */
  sdl_display = info.info.x11.display;
  sdl_win = info.info.x11.window;
  sdl_gl_context = glXGetCurrentContext ();
  glXMakeCurrent (sdl_display, None, 0);
  platform = "glx";
  display = (GstGLDisplay *) gst_gl_display_x11_new_with_display (sdl_display);
#endif

  sdl_context = gst_gl_context_new_wrapped (display, (guintptr) sdl_gl_context,
      gst_gl_platform_from_string (platform), GST_GL_API_OPENGL);

  pipeline =
      GST_PIPELINE (gst_parse_launch
      ("videotestsrc ! video/x-raw, width=320, height=240, framerate=(fraction)30/1 ! "
          "gleffects effect=5 ! fakesink sync=1", NULL));

  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_signal_watch (bus);
  g_signal_connect (bus, "message::error", G_CALLBACK (end_stream_cb), loop);
  g_signal_connect (bus, "message::warning", G_CALLBACK (end_stream_cb), loop);
  g_signal_connect (bus, "message::eos", G_CALLBACK (end_stream_cb), loop);
  gst_object_unref (bus);

  /* sdl_gl_context is an external OpenGL context with which gst-plugins-gl want to share textures */
  glfilter = gst_bin_get_by_name (GST_BIN (pipeline), "gleffects0");
  g_object_set (G_OBJECT (glfilter), "other-context", sdl_context, NULL);
  gst_object_unref (glfilter);

  /* NULL to PAUSED state pipeline to make sure the gst opengl context is created and
   * shared with the sdl one */
  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED);
  state = GST_STATE_PAUSED;
  if (gst_element_get_state (GST_ELEMENT (pipeline), &state, NULL,
          GST_CLOCK_TIME_NONE) != GST_STATE_CHANGE_SUCCESS) {
    g_debug ("failed to pause pipeline\n");
    return -1;
  }

  /* turn on back sdl opengl context */
#ifdef WIN32
  wglMakeCurrent (sdl_dc, sdl_gl_context);
#else
  glXMakeCurrent (sdl_display, sdl_win, sdl_gl_context);
#endif

  /* append a gst-gl texture to this queue when you do not need it no more */
  fakesink = gst_bin_get_by_name (GST_BIN (pipeline), "fakesink0");
  g_object_set (G_OBJECT (fakesink), "signal-handoffs", TRUE, NULL);
  g_signal_connect (fakesink, "handoff", G_CALLBACK (on_gst_buffer), NULL);
  queue_input_buf = g_async_queue_new ();
  queue_output_buf = g_async_queue_new ();
  g_object_set_data (G_OBJECT (fakesink), "queue_input_buf", queue_input_buf);
  g_object_set_data (G_OBJECT (fakesink), "queue_output_buf", queue_output_buf);
  g_object_set_data (G_OBJECT (fakesink), "loop", loop);
  gst_object_unref (fakesink);

  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);

  g_main_loop_run (loop);

  /* before to deinitialize the gst-gl-opengl context,
   * no shared context (here the sdl one) must be current
   */
#ifdef WIN32
  wglMakeCurrent (0, 0);
#else
  glXMakeCurrent (sdl_display, sdl_win, sdl_gl_context);
#endif

  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
  gst_object_unref (pipeline);

  /* turn on back sdl opengl context */
#ifdef WIN32
  wglMakeCurrent (sdl_dc, sdl_gl_context);
#else
  glXMakeCurrent (sdl_display, None, 0);
#endif

  SDL_Quit ();

  /* make sure there is no pending gst gl buffer in the communication queues 
   * between sdl and gst-gl
   */
  while (g_async_queue_length (queue_input_buf) > 0) {
    GstBuffer *buf = (GstBuffer *) g_async_queue_pop (queue_input_buf);
    gst_buffer_unref (buf);
  }

  while (g_async_queue_length (queue_output_buf) > 0) {
    GstBuffer *buf = (GstBuffer *) g_async_queue_pop (queue_output_buf);
    gst_buffer_unref (buf);
  }

  return 0;
}
Example #15
0
// Create window
// 
// Much of the Creation code was taken from the openGL wiki at:
// 
// http://www.opengl.org/wiki/Tutorial:_OpenGL_3.0_Context_Creation_(GLX) on 2/1/13
// 
//-----------------------------------------------------------------------------
CPUTResult CPUTWindowX::Create(CPUT* cput, const std::string WindowTitle, CPUTWindowCreationParams windowParams)
{
    CPUTResult result = CPUT_ERROR;
    
    pDisplay = XOpenDisplay(NULL);
    if (!pDisplay) {
        return result;
    }

    int glx_major, glx_minor;

    // FBConfigs were added in GLX version 1.3.
    if (!glXQueryVersion(pDisplay, &glx_major, &glx_minor)) {
        printf( "glXQueryVersion failed" );
        exit(1);
    }
    
    if (((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1)) {
        printf( "Invalid GLX version" );
        exit(1);
    }
    printf( "GLX version: %d.%d\n", glx_major, glx_minor );

    // Get a matching FB config
    int visual_attribs[] =
    {
        GLX_X_RENDERABLE    , True,
        GLX_DRAWABLE_TYPE   , GLX_WINDOW_BIT,
        GLX_RENDER_TYPE     , GLX_RGBA_BIT,
        GLX_X_VISUAL_TYPE   , GLX_TRUE_COLOR,
        GLX_RED_SIZE        , 8,
        GLX_GREEN_SIZE      , 8,
        GLX_BLUE_SIZE       , 8,
        GLX_ALPHA_SIZE      , 8,
        GLX_DEPTH_SIZE      , 24,
        GLX_STENCIL_SIZE    , 8,
        GLX_DOUBLEBUFFER    , True,
        //GLX_SAMPLE_BUFFERS  , 1,
        //GLX_SAMPLES         , 4,
        None
    };
    int fbcount;
    GLXFBConfig *fbc = glXChooseFBConfig(pDisplay, DefaultScreen( pDisplay ), visual_attribs, &fbcount );
    if ( !fbc )
    {
        printf( "Failed to retrieve a framebuffer config\n" );
        exit(1);
    }

    // Pick the FB config/visual with the most samples per pixel
    printf( "Getting XVisualInfos\n" );
    int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999;
    
    for ( int i = 0; i < fbcount; i++ )
    {
        XVisualInfo *vi = glXGetVisualFromFBConfig( pDisplay, fbc[i] );
        if (vi)
        {
            int samp_buf, samples;
            glXGetFBConfigAttrib( pDisplay, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf );
            glXGetFBConfigAttrib( pDisplay, fbc[i], GLX_SAMPLES       , &samples  );
 
            printf( "  Matching fbconfig %d, visual ID 0lx%2lx: SAMPLE_BUFFERS = %d,"
                    " SAMPLES = %d\n", 
                    i, vi -> visualid, samp_buf, samples );
 
            if ( best_fbc < 0 || samp_buf && samples > best_num_samp ) {
                best_fbc = i, best_num_samp = samples;
            }
            if ( worst_fbc < 0 || !samp_buf || samples < worst_num_samp ) {
                worst_fbc = i, worst_num_samp = samples;
            }
        }
        XFree( vi );
    }
    
    GLXFBConfig bestFbc = fbc[ best_fbc ];

    // Be sure to free the FBConfig list allocated by glXChooseFBConfig()
    XFree( fbc );
    
    // Get a visual
    XVisualInfo *vi = glXGetVisualFromFBConfig( pDisplay, bestFbc );
    printf( "Chosen visual ID = 0x%lx\n", vi->visualid );
 
    printf( "Creating colormap\n" );
    XSetWindowAttributes swa;
    swa.colormap = XCreateColormap(pDisplay,
                                          RootWindow(pDisplay, vi->screen), 
                                          vi->visual, AllocNone );
    swa.background_pixmap = None ;
    swa.border_pixel      = 0;
    swa.event_mask        = ExposureMask | Button1MotionMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask;
    
    printf( "Creating window\n" );
    win = XCreateWindow( pDisplay, RootWindow(pDisplay, vi->screen ), 
                        0, 0, windowParams.windowWidth, windowParams.windowHeight, 0, vi->depth, InputOutput, 
                        vi->visual, 
                        CWBorderPixel | CWColormap | CWEventMask, &swa );
    if ( !win )
    {
        printf( "Failed to create window.\n" );
        exit(1);
    }

    // Done with the visual info data
    XFree( vi );
 
    // register interest in the delete window message
    wmDeleteMessage = XInternAtom(pDisplay, "WM_DELETE_WINDOW", False);
    XSetWMProtocols(pDisplay, win, &wmDeleteMessage, 1);
   
    XStoreName( pDisplay, win, WindowTitle.c_str() );
    
    printf( "Mapping window\n" );
    XMapWindow( pDisplay, win );
 
    // Get the default screen's GLX extension list
    const char *glxExts = glXQueryExtensionsString(pDisplay,
                                                   DefaultScreen( pDisplay ) );

    // NOTE: It is not necessary to create or make current to a context before
    // calling glXGetProcAddressARB
    glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
    glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
                                  glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
 
    ctx = 0;
    
    // Install an X error handler so the application won't exit if GL 3.0
    // context allocation fails.
    //
    // Note this error handler is global.  All display connections in all threads
    // of a process use the same error handler, so be sure to guard against other
    // threads issuing X commands while this code is running.
    ctxErrorOccurred = false;
    int (*oldHandler)(Display*, XErrorEvent*) =
         XSetErrorHandler(&ctxErrorHandler);
 
    // Check for the GLX_ARB_create_context extension string and the function.
    // If either is not present, use GLX 1.3 context creation method.
    if (!isExtensionSupported( glxExts, "GLX_ARB_create_context" ) ||
        !glXCreateContextAttribsARB )
    {
        printf("glXCreateContextAttribsARB() not found"
               " ... using old-style GLX context\n" );
        ctx = glXCreateNewContext( pDisplay, bestFbc, GLX_RGBA_TYPE, 0, True );
    }
    else
    {
        int contextMajor = 3;
        int contextMinor = 3;
        printf( "Creating context %d.%d\n",  contextMajor, contextMinor);
        int context_attribs[] =
        {
            GLX_CONTEXT_MAJOR_VERSION_ARB, contextMajor,
            GLX_CONTEXT_MINOR_VERSION_ARB, contextMinor,
            GLX_CONTEXT_FLAGS_ARB        , GLX_CONTEXT_DEBUG_BIT_ARB,
            None
        };

        ctx = glXCreateContextAttribsARB(pDisplay, bestFbc, 0,
                                         True, context_attribs );

        // Sync to ensure any errors generated are processed.
        XSync( pDisplay, False );
        if ( !ctxErrorOccurred && ctx ) {
            printf( "Created GL 3.2 context\n" );
        } else {
            printf( "Failed to create requested context" );
        }
    }

    // Sync to ensure any errors generated are processed.
    XSync( pDisplay, False );
 
    // Restore the original error handler
    XSetErrorHandler( oldHandler );
    
    if ( ctxErrorOccurred || !ctx )
    {
        printf( "Failed to create an OpenGL context\n" );
        exit(1);
    }
 
    // Verifying that context is a direct context
    if ( ! glXIsDirect ( pDisplay, ctx ) )
    {
        printf( "Indirect GLX rendering context obtained\n" );
    }
    else
    {
        printf( "Direct GLX rendering context obtained\n" );
    }

    if (glXMakeCurrent( pDisplay, win, ctx ) == False) {
        printf( "glXMakeCurrent failed.");
    }

    glewExperimental=true;
    GLenum err = glewInit();
    if (GLEW_OK != err)
    {
        fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
    }
    
    // glewInit can generate an error which is apparently innocuous. Clear it out here.
    // http://www.opengl.org/wiki/OpenGL_Loading_Library on 2/20/13
    glGetError();
    
    printf("Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
    printf("GL Version: %s\n", glGetString(GL_VERSION));


    return CPUT_SUCCESS;
}
Example #16
0
/* Stereo thread - For GL_STEREO  */
static void * nvstusb_stereo_thread(void * in_pv_arg)
{
  struct nvstusb_context *ctx = (struct nvstusb_context *) in_pv_arg;
  Display *dpy;
  Window win;

  /* Openning X display */
  dpy = XOpenDisplay(0);

  /* Preparing new X window */
  Window s_window;
  static int attributeList[] =
  { GLX_RGBA,
    GLX_DOUBLEBUFFER,
    GLX_RED_SIZE,
    1,
    GLX_GREEN_SIZE,
    1,
    GLX_BLUE_SIZE,
    1,
    None };
  XVisualInfo *vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributeList);
  s_window = RootWindow(dpy, vi->screen);
  XSetWindowAttributes swa;
  swa.colormap = XCreateColormap(dpy, s_window, vi->visual, AllocNone);
  swa.override_redirect = true;

  /* Create X window 1x1 top left of screen */
  win = XCreateWindow(dpy,
      s_window ,
      0,
      0,
      1,
      1,
      0,
      vi->depth,
      InputOutput,
      vi->visual,
      CWColormap|CWOverrideRedirect,
      &swa);

  XMapWindow(dpy, win);

  /* Create glX context */
  GLXContext glx_ctx = glXCreateContext(dpy, vi, 0, true);
  glXMakeCurrent(dpy, win, glx_ctx);

  /* Loop until stop */
  while (ctx->b_thread_running) {
    /* Send swap to usb controler */
    nvstusb_swap(ctx, nvstusb_quad, NULL /*f_swap*/);

    /* Read status from usb controler */
    struct nvstusb_keys k;
    nvstusb_get_keys(ctx, &k);
    if (k.toggled3D) {
      nvstusb_invert_eyes(ctx);
    }
  }
  /* Destroy context */
  glx_ctx = glXGetCurrentContext();
  glXDestroyContext(dpy, glx_ctx);

  return NULL;
}
Example #17
0
void GLwDrawingAreaMakeCurrent (Widget w, GLXContext ctx)
{
    glXMakeCurrent (XtDisplay(w), XtWindow(w), ctx);
}
Example #18
0
bool GLWindow::CreateContextGL(int major, int minor)
{
	if (!NativeDisplay) return false;

	// Get visual information
	int attrListDbl[] =
	{
		// GLX_X_RENDERABLE: If True is specified, then only frame buffer configurations that have associated X
		// visuals (and can be used to render to Windows and/or GLX pixmaps) will be considered. The default value is GLX_DONT_CARE.
		GLX_X_RENDERABLE    , True,
		GLX_RED_SIZE        , 8,
		GLX_GREEN_SIZE      , 8,
		GLX_BLUE_SIZE       , 8,
		GLX_DEPTH_SIZE      , 24,
		GLX_DOUBLEBUFFER    , True,
		None
	};

	// Attribute are very sensible to the various implementation (intel, nvidia, amd)
	// Nvidia and Intel doesn't support previous attributes for opengl2.0
	int attrListDbl_2_0[] =
	{
		GLX_RGBA,
		GLX_DOUBLEBUFFER,
		GLX_RED_SIZE, 8,
		GLX_GREEN_SIZE, 8,
		GLX_BLUE_SIZE, 8,
		GLX_DEPTH_SIZE, 24,
		None
	};

	// Only keep for older card but NVIDIA and AMD both drop the support of those cards
	if (major <= 2) {
		XVisualInfo *vi = glXChooseVisual(NativeDisplay, DefaultScreen(NativeDisplay), attrListDbl_2_0);
		if (vi == NULL) return NULL;

		glxContext = glXCreateContext(NativeDisplay, vi, NULL, GL_TRUE);
        XFree(vi);

		if (!glxContext) return false;

		glXMakeCurrent(NativeDisplay, NativeWindow, glxContext);
		return true;
	}

	PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)GetProcAddress("glXChooseFBConfig");
	int fbcount = 0;
	GLXFBConfig *fbc = glXChooseFBConfig(NativeDisplay, DefaultScreen(NativeDisplay), attrListDbl, &fbcount);
	if (!fbc || fbcount < 1) {
		ZZLog::Error_Log("GLX: failed to find a framebuffer");
		return false;
	}

	PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)GetProcAddress("glXCreateContextAttribsARB");
	if (!glXCreateContextAttribsARB) return false;

	// Create a context
	int context_attribs[] =
	{
		GLX_CONTEXT_MAJOR_VERSION_ARB, major,
		GLX_CONTEXT_MINOR_VERSION_ARB, minor,
		// Keep compatibility for old cruft
		GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
		//GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
		// FIXME : Request a debug context to ease opengl development
#if (defined(ZEROGS_DEVBUILD) || defined(_DEBUG)) && defined(OGL4_LOG)
		GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
#endif
		None
	};

	glxContext = glXCreateContextAttribsARB(NativeDisplay, fbc[0], 0, true, context_attribs);
	if (!glxContext) {
		ZZLog::Error_Log("GLX: failed to create an opengl context");
		return false;
	}

	XSync( NativeDisplay, false);

	if (!glXMakeCurrent(NativeDisplay, NativeWindow, glxContext)) {
		ZZLog::Error_Log("GLX: failed to attach the opengl context");
		return false;
	}

	return true;
}
void X11OpenGLWindow::enableOpenGL()
{


    if (forceOpenGL3)
    {
 // Get the default screen's GLX extension list
  const char *glxExts = glXQueryExtensionsString( m_data->m_dpy,
                                                  DefaultScreen( m_data->m_dpy ) );

  // NOTE: It is not necessary to create or make current to a context before
  // calling glXGetProcAddressARB, unless we dynamically load OpenGL/GLX/X11

  glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
  glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
           glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );

  GLXContext ctx = 0;

  // Install an X error handler so the application won't exit if GL 3.0
  // context allocation fails.
  //
  // Note this error handler is global.  All display connections in all threads
  // of a process use the same error handler, so be sure to guard against other
  // threads issuing X commands while this code is running.
  ctxErrorOccurred = false;
  int (*oldHandler)(Display*, XErrorEvent*) =
         MyXSetErrorHandler(&ctxErrorHandler);

  // Check for the GLX_ARB_create_context extension string and the function.
  // If either is not present, use GLX 1.3 context creation method.
  if ( !isExtensionSupported( glxExts, "GLX_ARB_create_context" ) ||
       !glXCreateContextAttribsARB )
  {
    printf( "glXCreateContextAttribsARB() not found"
            " ... using old-style GLX context\n" );
    ctx = glXCreateNewContext( m_data->m_dpy, m_data->m_bestFbc, GLX_RGBA_TYPE, 0, True );
  }

  // If it does, try to get a GL 3.0 context!
  else
  {
	 int context_attribs[] = {
          GLX_CONTEXT_MAJOR_VERSION_ARB ,3,
          GLX_CONTEXT_MINOR_VERSION_ARB, 2,
          GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
          GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,None
     };
/*
    int context_attribs[] =
      {
        GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
        GLX_CONTEXT_MINOR_VERSION_ARB, 2,

        //GLX_CONTEXT_FLAGS_ARB        , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
        None
      };
*/
    printf( "Creating context\n" );
    ctx = glXCreateContextAttribsARB( m_data->m_dpy, m_data->m_bestFbc, 0,
                                      True, context_attribs );

    // Sync to ensure any errors generated are processed.
    MyXSync( m_data->m_dpy, False );
    if ( !ctxErrorOccurred && ctx )
      printf( "Created GL 3.0 context\n" );
    else
    {
      // Couldn't create GL 3.0 context.  Fall back to old-style 2.x context.
      // When a context version below 3.0 is requested, implementations will
      // return the newest context version compatible with OpenGL versions less
      // than version 3.0.
      // GLX_CONTEXT_MAJOR_VERSION_ARB = 1
      context_attribs[1] = 1;
      // GLX_CONTEXT_MINOR_VERSION_ARB = 0
      context_attribs[3] = 0;

      ctxErrorOccurred = false;

      printf( "Failed to create GL 3.0 context"
              " ... using old-style GLX context\n" );
      ctx = glXCreateContextAttribsARB( m_data->m_dpy, m_data->m_bestFbc, 0,
                                        True, context_attribs );
    }
  }

  // Sync to ensure any errors generated are processed.
  MyXSync( m_data->m_dpy, False );

  // Restore the original error handler
  MyXSetErrorHandler( oldHandler );

  if ( ctxErrorOccurred || !ctx )
  {
    printf( "Failed to create an OpenGL context\n" );
    exit(1);
  }

  // Verifying that context is a direct context
  if ( ! glXIsDirect ( m_data->m_dpy, ctx ) )
  {
    printf( "Indirect GLX rendering context obtained\n" );
  }
  else
  {
    printf( "Direct GLX rendering context obtained\n" );
  }

  printf( "Making context current\n" );
  glXMakeCurrent( m_data->m_dpy, m_data->m_win, ctx );
  m_data->m_glc = ctx;

    } else
    {
        m_data->m_glc = glXCreateContext(m_data->m_dpy, m_data->m_vi, NULL, GL_TRUE);
        glXMakeCurrent(m_data->m_dpy, m_data->m_win, m_data->m_glc);
    }

#ifdef GLEW_INIT_OPENGL11_FUNCTIONS
{
	GLboolean res = glewOpenGL11Init();
	if (res==0)
		{
			printf("glewOpenGL11Init OK!\n");
		} else
			{
				printf("ERROR: glewOpenGL11Init failed, exiting!\n");
				exit(0);
			}
}

#endif //GLEW_INIT_OPENGL11_FUNCTIONS

    const GLubyte* ven = glGetString(GL_VENDOR);
    printf("GL_VENDOR=%s\n", ven);

    const GLubyte* ren = glGetString(GL_RENDERER);
    printf("GL_RENDERER=%s\n",ren);
    const GLubyte* ver = glGetString(GL_VERSION);
    printf("GL_VERSION=%s\n", ver);
    const GLubyte* sl = glGetString(GL_SHADING_LANGUAGE_VERSION);
    printf("GL_SHADING_LANGUAGE_VERSION=%s\n", sl);

//Access pthreads as a workaround for a bug in Linux/Ubuntu
//See https://bugs.launchpad.net/ubuntu/+source/nvidia-graphics-drivers-319/+bug/1248642

	int i=pthread_getconcurrency();
        printf("pthread_getconcurrency()=%d\n",i);

//    const GLubyte* ext = glGetString(GL_EXTENSIONS);
//    printf("GL_EXTENSIONS=%s\n", ext);
}
void SkNativeSharedGLContext::makeCurrent() const {
    glXMakeCurrent(fDisplay, fGlxPixmap, fContext);
}
Example #21
0
static void
clutter_backend_glx_ensure_context (ClutterBackend *backend, 
                                    ClutterStage   *stage)
{
  ClutterStageWindow *impl;

  /* if there is no stage, the stage is being destroyed or it has no
   * implementation attached to it then we clear the GL context
   */
  if (stage == NULL ||
      (CLUTTER_PRIVATE_FLAGS (stage) & CLUTTER_ACTOR_IN_DESTRUCTION) ||
      ((impl = _clutter_stage_get_window (stage)) == NULL))
    {
      ClutterBackendX11 *backend_x11;

      backend_x11 = CLUTTER_BACKEND_X11 (backend);
      CLUTTER_NOTE (MULTISTAGE, "Clearing all context");

      glXMakeCurrent (backend_x11->xdpy, None, NULL);
    }
  else
    {
      ClutterBackendGLX *backend_glx;
      ClutterStageGLX   *stage_glx;
      ClutterStageX11   *stage_x11;

      g_assert (impl != NULL);

      CLUTTER_NOTE (MULTISTAGE, "Setting context for stage of type %s [%p]",
                    g_type_name (G_OBJECT_TYPE (impl)),
                    impl);

      stage_glx = CLUTTER_STAGE_GLX (impl);
      stage_x11 = CLUTTER_STAGE_X11 (impl);
      backend_glx = CLUTTER_BACKEND_GLX (backend);

      /* no GL context to set */
      if (backend_glx->gl_context == None)
        return;

      clutter_x11_trap_x_errors ();

      /* we might get here inside the final dispose cycle, so we
       * need to handle this gracefully
       */
      if (stage_x11->xwin == None)
        {
          ClutterBackendX11 *backend_x11;

          backend_x11 = CLUTTER_BACKEND_X11 (backend);
          CLUTTER_NOTE (MULTISTAGE,
                        "Received a stale stage, clearing all context");

          glXMakeCurrent (backend_x11->xdpy, None, NULL);
        }
      else
        {
          CLUTTER_NOTE (BACKEND,
                        "MakeCurrent dpy: %p, window: 0x%x (%s), context: %p",
                        stage_x11->xdpy,
                        (int) stage_x11->xwin,
                        stage_x11->is_foreign_xwin ? "foreign" : "native",
                        backend_glx->gl_context);

          glXMakeCurrent (stage_x11->xdpy,
                          stage_x11->xwin,
                          backend_glx->gl_context);
        }

      if (clutter_x11_untrap_x_errors ())
        g_critical ("Unable to make the stage window 0x%x the current "
                    "GLX drawable",
                    (int) stage_x11->xwin);
    }
}
Example #22
0
bool CWinSystemX11::RefreshGlxContext(bool force)
{
  bool retVal = false;

#if defined(HAS_GLX)
  if (m_glContext && !force)
  {
    CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context");
    glXMakeCurrent(m_dpy, None, NULL);
    glXMakeCurrent(m_dpy, m_glWindow, m_glContext);
    return true;
  }
#endif

#if defined(HAS_EGL)
  if (m_eglContext && !force)
  {
    CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context");
    eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
    return true;
  }
#endif


  XVisualInfo vMask;
  XVisualInfo *visuals;
  XVisualInfo *vInfo      = NULL;
  int availableVisuals    = 0;
  vMask.screen = m_nScreen;
  XWindowAttributes winAttr;

  /* Assume a depth of 24 in case the below calls to XGetWindowAttributes()
     or XGetVisualInfo() fail. That shouldn't happen unless something is
     fatally wrong, but lets prepare for everything. */
  vMask.depth = 24;

  if (XGetWindowAttributes(m_dpy, m_glWindow, &winAttr))
  {
    vMask.visualid = XVisualIDFromVisual(winAttr.visual);
    vInfo = XGetVisualInfo(m_dpy, VisualScreenMask | VisualIDMask, &vMask, &availableVisuals);
    if (!vInfo)
      CLog::Log(LOGWARNING, "Failed to get VisualInfo of SDL visual 0x%x", (unsigned) vMask.visualid);
    else if(!IsSuitableVisual(vInfo))
    {
      CLog::Log(LOGWARNING, "Visual 0x%x of the SDL window is not suitable, looking for another one...",
                (unsigned) vInfo->visualid);
      vMask.depth = vInfo->depth;
      XFree(vInfo);
      vInfo = NULL;
    }
  }
  else
    CLog::Log(LOGWARNING, "Failed to get SDL window attributes");

  /* As per glXMakeCurrent documentation, we have to use the same visual as
     m_glWindow. Since that was not suitable for use, we try to use another
     one with the same depth and hope that the used implementation is less
     strict than the documentation. */
  if (!vInfo)
  {
    visuals = XGetVisualInfo(m_dpy, VisualScreenMask | VisualDepthMask, &vMask, &availableVisuals);
    for (int i = 0; i < availableVisuals; i++)
    {
      if (IsSuitableVisual(&visuals[i]))
      {
        vMask.visualid = visuals[i].visualid;
        vInfo = XGetVisualInfo(m_dpy, VisualScreenMask | VisualIDMask, &vMask, &availableVisuals);
        break;
      }
    }
    XFree(visuals);
  }

  if (vInfo)
  {
    CLog::Log(LOGNOTICE, "Using visual 0x%x", (unsigned) vInfo->visualid);
#if defined(HAS_GLX)
    if (m_glContext)
    {
      glXMakeCurrent(m_dpy, None, NULL);
      glXDestroyContext(m_dpy, m_glContext);
      XSync(m_dpy, FALSE);
      m_newGlContext = true;
    }

    if ((m_glContext = glXCreateContext(m_dpy, vInfo, NULL, True)))
    {
      // make this context current
      glXMakeCurrent(m_dpy, m_glWindow, m_glContext);
      retVal = true;
    }
    else
      CLog::Log(LOGERROR, "GLX Error: Could not create context");
#endif
#if defined(HAS_EGL)
    if (m_eglContext)
    {
      eglMakeCurrent(m_eglContext, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
      eglDestroyContext(m_eglDisplay, m_eglContext);
      m_eglContext = EGL_NO_CONTEXT;
      eglDestroySurface(m_eglDisplay, m_eglSurface);
      m_eglSurface = EGL_NO_SURFACE;
      eglTerminate(m_eglDisplay);
      m_eglDisplay = EGL_NO_DISPLAY;
      XSync(m_dpy, FALSE);
      m_newGlContext = true;
    }

    m_eglDisplay = eglGetDisplay((EGLNativeDisplayType)m_dpy);
    if (m_eglDisplay == EGL_NO_DISPLAY)
    {
      CLog::Log(LOGERROR, "failed to get egl display\n");
      return false;
    }
    if (!eglInitialize(m_eglDisplay, NULL, NULL))
    {
      CLog::Log(LOGERROR, "failed to initialize egl\n");
      return false;
    }

    if(m_eglConfig == EGL_NO_CONFIG)
    {
      m_eglConfig = getEGLConfig(m_eglDisplay, vInfo);
    }

    if (m_eglConfig == EGL_NO_CONFIG)
    {
      CLog::Log(LOGERROR, "failed to get eglconfig for visual id\n");
      return false;
    }

    if (m_eglSurface == EGL_NO_SURFACE)
    {
      m_eglSurface = eglCreateWindowSurface(m_eglDisplay, m_eglConfig, m_glWindow, NULL);
      if (m_eglSurface == EGL_NO_SURFACE)
      {
        CLog::Log(LOGERROR, "failed to create EGL window surface %d\n", eglGetError());
        return false;
      }
    }

    EGLint contextAttributes[] =
    {
      EGL_CONTEXT_CLIENT_VERSION, 2,
      EGL_NONE
    };
    m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, contextAttributes);
    if (m_eglContext == EGL_NO_CONTEXT)
    {
      CLog::Log(LOGERROR, "failed to create EGL context\n");
      return false;
    }

    if (!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext))
    {
      CLog::Log(LOGERROR, "Failed to make context current %p %p %p\n", m_eglDisplay, m_eglSurface, m_eglContext);
      return false;
    }
#endif
    XFree(vInfo);
  }
  else
  {
    CLog::Log(LOGERROR, "EGL/GLX Error: vInfo is NULL!");
  }

  return retVal;
}
Example #23
0
SkNativeGLContext::AutoContextRestore::~AutoContextRestore() {
    if (NULL != fOldDisplay) {
        glXMakeCurrent(fOldDisplay, fOldDrawable, fOldGLXContext);
    }
}
Example #24
0
bool CVDPAU::MakePixmapGL()
{
  int num=0;
  int fbConfigIndex = 0;

  int doubleVisAttributes[] = {
    GLX_RENDER_TYPE, GLX_RGBA_BIT,
    GLX_RED_SIZE, 8,
    GLX_GREEN_SIZE, 8,
    GLX_BLUE_SIZE, 8,
    GLX_ALPHA_SIZE, 8,
    GLX_DEPTH_SIZE, 8,
    GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
    GLX_BIND_TO_TEXTURE_RGBA_EXT, True,
    GLX_DOUBLEBUFFER, True,
    GLX_Y_INVERTED_EXT, True,
    GLX_X_RENDERABLE, True,
    None
  };

  int pixmapAttribs[] = {
    GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
    GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT,
    None
  };

  GLXFBConfig *fbConfigs;
  fbConfigs = glXChooseFBConfig(m_Display, DefaultScreen(m_Display), doubleVisAttributes, &num);
  if (fbConfigs==NULL)
  {
    CLog::Log(LOGERROR, "GLX Error: MakePixmap: No compatible framebuffers found");
    return false;
  }
  CLog::Log(LOGDEBUG, "Found %d fbconfigs.", num);
  fbConfigIndex = 0;
  CLog::Log(LOGDEBUG, "Using fbconfig index %d.", fbConfigIndex);

  m_glPixmap = glXCreatePixmap(m_Display, fbConfigs[fbConfigIndex], m_Pixmap, pixmapAttribs);

  if (!m_glPixmap)
  {
    CLog::Log(LOGINFO, "GLX Error: Could not create Pixmap");
    XFree(fbConfigs);
    return false;
  }

  /* to make the pixmap usable, it needs to have any context associated with it */
  GLXContext  lastctx = glXGetCurrentContext();
  GLXDrawable lastdrw = glXGetCurrentDrawable();

  XVisualInfo *visInfo;
  visInfo = glXGetVisualFromFBConfig(m_Display, fbConfigs[fbConfigIndex]);
  if (!visInfo)
  {
    CLog::Log(LOGINFO, "GLX Error: Could not obtain X Visual Info for pixmap");
    XFree(fbConfigs);
    return false;
  }
  XFree(fbConfigs);

  CLog::Log(LOGINFO, "GLX: Creating Pixmap context");
  m_glContext = glXCreateContext(m_Display, visInfo, NULL, True);
  XFree(visInfo);

  if (!glXMakeCurrent(m_Display, m_glPixmap, m_glContext))
  {
    CLog::Log(LOGINFO, "GLX Error: Could not make Pixmap current");
    return false;
  }

  /* restore what thread had before */
  glXMakeCurrent(m_Display, lastdrw, lastctx);

  return true;

}
Example #25
0
const GrGLInterface* SkNativeGLContext::createGLContext(GrGLStandard forcedGpuAPI) {
    fDisplay = XOpenDisplay(0);

    if (!fDisplay) {
        SkDebugf("Failed to open X display.\n");
        this->destroyGLContext();
        return NULL;
    }

    // Get a matching FB config
    static int visual_attribs[] = {
        GLX_X_RENDERABLE    , True,
        GLX_DRAWABLE_TYPE   , GLX_PIXMAP_BIT,
        None
    };

    int glx_major, glx_minor;

    // FBConfigs were added in GLX version 1.3.
    if (!glXQueryVersion(fDisplay, &glx_major, &glx_minor) ||
            ((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1)) {
        SkDebugf("GLX version 1.3 or higher required.\n");
        this->destroyGLContext();
        return NULL;
    }

    //SkDebugf("Getting matching framebuffer configs.\n");
    int fbcount;
    GLXFBConfig *fbc = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay),
                                          visual_attribs, &fbcount);
    if (!fbc) {
        SkDebugf("Failed to retrieve a framebuffer config.\n");
        this->destroyGLContext();
        return NULL;
    }
    //SkDebugf("Found %d matching FB configs.\n", fbcount);

    // Pick the FB config/visual with the most samples per pixel
    //SkDebugf("Getting XVisualInfos.\n");
    int best_fbc = -1, best_num_samp = -1;

    int i;
    for (i = 0; i < fbcount; ++i) {
        XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, fbc[i]);
        if (vi) {
            int samp_buf, samples;
            glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf);
            glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLES, &samples);

            //SkDebugf("  Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d,"
            //       " SAMPLES = %d\n",
            //        i, (unsigned int)vi->visualid, samp_buf, samples);

            if (best_fbc < 0 || (samp_buf && samples > best_num_samp))
                best_fbc = i, best_num_samp = samples;
        }
        XFree(vi);
    }

    GLXFBConfig bestFbc = fbc[best_fbc];

    // Be sure to free the FBConfig list allocated by glXChooseFBConfig()
    XFree(fbc);

    // Get a visual
    XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, bestFbc);
    //SkDebugf("Chosen visual ID = 0x%x\n", (unsigned int)vi->visualid);

    fPixmap = XCreatePixmap(fDisplay, RootWindow(fDisplay, vi->screen), 10, 10, vi->depth);

    if (!fPixmap) {
        SkDebugf("Failed to create pixmap.\n");
        this->destroyGLContext();
        return NULL;
    }

    fGlxPixmap = glXCreateGLXPixmap(fDisplay, vi, fPixmap);

    // Done with the visual info data
    XFree(vi);

    // Create the context

    // Install an X error handler so the application won't exit if GL 3.0
    // context allocation fails.
    //
    // Note this error handler is global.
    // All display connections in all threads of a process use the same
    // error handler, so be sure to guard against other threads issuing
    // X commands while this code is running.
    ctxErrorOccurred = false;
    int (*oldHandler)(Display*, XErrorEvent*) =
        XSetErrorHandler(&ctxErrorHandler);

    // Get the default screen's GLX extension list
    const char *glxExts = glXQueryExtensionsString(
        fDisplay, DefaultScreen(fDisplay)
    );


    // Check for the GLX_ARB_create_context extension string and the function.
    // If either is not present, use GLX 1.3 context creation method.
    if (!gluCheckExtension(reinterpret_cast<const GLubyte*>("GLX_ARB_create_context"),
                           reinterpret_cast<const GLubyte*>(glxExts))) {
        if (kGLES_GrGLStandard != forcedGpuAPI) {
            fContext = glXCreateNewContext(fDisplay, bestFbc, GLX_RGBA_TYPE, 0, True);
        }
    } else {
        //SkDebugf("Creating context.\n");
        PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB =
            (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddressARB((GrGLubyte*)"glXCreateContextAttribsARB");

        if (kGLES_GrGLStandard == forcedGpuAPI) {
            if (gluCheckExtension(
                    reinterpret_cast<const GLubyte*>("GLX_EXT_create_context_es2_profile"),
                    reinterpret_cast<const GLubyte*>(glxExts))) {
                static const int context_attribs_gles[] = {
                    GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
                    GLX_CONTEXT_MINOR_VERSION_ARB, 0,
                    GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
                    None
                };
                fContext = glXCreateContextAttribsARB(fDisplay, bestFbc, 0, True,
                                                      context_attribs_gles);
            }
        } else {
            // Well, unfortunately GLX will not just give us the highest context so instead we have
            // to do this nastiness
            for (i = NUM_GL_VERSIONS - 2; i > 0 ; i--) {
                /* don't bother below GL 3.0 */
                if (gl_versions[i].major == 3 && gl_versions[i].minor == 0) {
                    break;
                }
                // On Nvidia GPUs, to use Nv Path rendering we need a compatibility profile for the
                // time being.
                // TODO when Nvidia implements NVPR on Core profiles, we should start requesting
                // core here
                static const int context_attribs_gl[] = {
                      GLX_CONTEXT_MAJOR_VERSION_ARB, gl_versions[i].major,
                      GLX_CONTEXT_MINOR_VERSION_ARB, gl_versions[i].minor,
                      GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
                      None
                };
                fContext =
                        glXCreateContextAttribsARB(fDisplay, bestFbc, 0, True, context_attribs_gl);

                // Sync to ensure any errors generated are processed.
                XSync(fDisplay, False);

                if (!ctxErrorOccurred && fContext) {
                    break;
                }
                // try again
                ctxErrorOccurred = false;
            }

            // Couldn't create GL 3.0 context.
            // Fall back to old-style 2.x context.
            // When a context version below 3.0 is requested,
            // implementations will return the newest context version
            // compatible with OpenGL versions less than version 3.0.
            if (ctxErrorOccurred || !fContext) {
                static const int context_attribs_gl_fallback[] = {
                    GLX_CONTEXT_MAJOR_VERSION_ARB, 1,
                    GLX_CONTEXT_MINOR_VERSION_ARB, 0,
                    None
                };

                ctxErrorOccurred = false;

                fContext = glXCreateContextAttribsARB(fDisplay, bestFbc, 0, True,
                                                      context_attribs_gl_fallback);
            }
        }
    }

    // Sync to ensure any errors generated are processed.
    XSync(fDisplay, False);

    // Restore the original error handler
    XSetErrorHandler(oldHandler);

    if (ctxErrorOccurred || !fContext) {
        SkDebugf("Failed to create an OpenGL context.\n");
        this->destroyGLContext();
        return NULL;
    }

    // Verify that context is a direct context
    if (!glXIsDirect(fDisplay, fContext)) {
        //SkDebugf("Indirect GLX rendering context obtained.\n");
    } else {
        //SkDebugf("Direct GLX rendering context obtained.\n");
    }

    //SkDebugf("Making context current.\n");
    if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) {
      SkDebugf("Could not set the context.\n");
        this->destroyGLContext();
        return NULL;
    }

    const GrGLInterface* interface = GrGLCreateNativeInterface();
    if (!interface) {
        SkDebugf("Failed to create gl interface");
        this->destroyGLContext();
        return NULL;
    }
    return interface;
}
Example #26
0
// activate the window: bind the OGL context    
void XWindow::doDeactivate(void)
{
    glXMakeCurrent(getDisplay(), None, NULL);
}
Example #27
0
void CGLContextGLX::Detach()
{
  glXMakeCurrent(m_dpy, None, NULL);
}
Example #28
0
ENTRYPOINT void
draw_morph3d(ModeInfo * mi)
{
	Display    *display = MI_DISPLAY(mi);
	Window      window = MI_WINDOW(mi);
	morph3dstruct *mp;

	if (morph3d == NULL)
		return;
	mp = &morph3d[MI_SCREEN(mi)];

	MI_IS_DRAWN(mi) = True;

	if (!mp->glx_context)
		return;

	glXMakeCurrent(display, window, *(mp->glx_context));

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glPushMatrix();

	glTranslatef(0.0, 0.0, -10.0);

	if (!MI_IS_ICONIC(mi)) {
		glScalef(Scale4Window * mp->WindH / mp->WindW, Scale4Window, Scale4Window);
		glTranslatef(2.5 * mp->WindW / mp->WindH * sin(mp->step * 1.11), 2.5 * cos(mp->step * 1.25 * 1.11), 0);
	} else {
		glScalef(Scale4Iconic * mp->WindH / mp->WindW, Scale4Iconic, Scale4Iconic);
	}

	glRotatef(mp->step * 100, 1, 0, 0);
	glRotatef(mp->step * 95, 0, 1, 0);
	glRotatef(mp->step * 90, 0, 0, 1);

	mp->seno = (sin(mp->step) + 1.0 / 3.0) * (4.0 / 5.0) * mp->Magnitude;

	if (mp->VisibleSpikes) {
#ifdef DEBUG_CULL_FACE
		int         loop;

		for (loop = 0; loop < 20; loop++)
			mp->MaterialColor[loop] = MaterialGray;
#endif
		glDisable(GL_CULL_FACE);
	} else {
#ifdef DEBUG_CULL_FACE
		int         loop;

		for (loop = 0; loop < 20; loop++)
			mp->MaterialColor[loop] = MaterialWhite;
#endif
		glEnable(GL_CULL_FACE);
	}

	mp->draw_object(mi);

	glPopMatrix();

	if (MI_IS_FPS(mi)) do_fps (mi);
	glXSwapBuffers(display, window);

	mp->step += 0.05;
}
Example #29
0
PP_Resource
ppb_graphics3d_create(PP_Instance instance, PP_Resource share_context, const int32_t attrib_list[])
{
    struct pp_instance_s *pp_i = tables_get_pp_instance(instance);
    if (!pp_i) {
        trace_error("%s, bad instance\n", __func__);
        return 0;
    }

    GLXContext share_glc = (share_context == 0) ? NULL
                                                : peek_gl_context(share_context);
    // check for required GLX extensions
#if HAVE_GLES2
    if (!display.glx_arb_create_context || !display.glx_arb_create_context_profile ||
        !display.glx_ext_create_context_es2_profile)
    {
        trace_warning("%s, some of GLX_ARB_create_context, GLX_ARB_create_context_profile, "
                      "GLX_EXT_create_context_es2_profile missing\n", __func__);
        return 0;
    }

    if (!display.glXCreateContextAttribsARB) {
        trace_warning("%s, no glXCreateContextAttribsARB found\n", __func__);
        return 0;
    }
#endif

    PP_Resource context = pp_resource_allocate(PP_RESOURCE_GRAPHICS3D, pp_i);
    struct pp_graphics3d_s *g3d = pp_resource_acquire(context, PP_RESOURCE_GRAPHICS3D);
    if (!g3d) {
        trace_error("%s, can't create context\n", __func__);
        return 0;
    }

    int attrib_len = 0;
    while (attrib_list[attrib_len] != PP_GRAPHICS3DATTRIB_NONE) {
        attrib_len += 2;
    }
    attrib_len ++;

    int *cfg_attrs = calloc(attrib_len + 3 * 2, sizeof(int));
    int k2 = 0;
    cfg_attrs[k2++] = GLX_X_RENDERABLE;
    cfg_attrs[k2++] = True;
    cfg_attrs[k2++] = GLX_DRAWABLE_TYPE;
    cfg_attrs[k2++] = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;

    int done = 0;
    int k1 = 0;
    while (!done) {
        switch (attrib_list[k1]) {
        case PP_GRAPHICS3DATTRIB_HEIGHT:
            g3d->height = attrib_list[k1 + 1];
            k1 += 2;
            break;
        case PP_GRAPHICS3DATTRIB_WIDTH:
            g3d->width = attrib_list[k1 + 1];
            k1 += 2;
            break;
        case PP_GRAPHICS3DATTRIB_GPU_PREFERENCE:
        case PP_GRAPHICS3DATTRIB_SWAP_BEHAVIOR:
            // TODO: save these values
            k1 += 2;
            break;
        case PP_GRAPHICS3DATTRIB_NONE:
            cfg_attrs[k2++] = None;
            done = 1;
            break;
        case PP_GRAPHICS3DATTRIB_ALPHA_SIZE:
            cfg_attrs[k2++] = GLX_ALPHA_SIZE;
            cfg_attrs[k2++] = attrib_list[k1 + 1];
            k1 += 2;
            break;
        case PP_GRAPHICS3DATTRIB_BLUE_SIZE:
            cfg_attrs[k2++] = GLX_BLUE_SIZE;
            cfg_attrs[k2++] = attrib_list[k1 + 1];
            k1 += 2;
            break;
        case PP_GRAPHICS3DATTRIB_GREEN_SIZE:
            cfg_attrs[k2++] = GLX_GREEN_SIZE;
            cfg_attrs[k2++] = attrib_list[k1 + 1];
            k1 += 2;
            break;
        case PP_GRAPHICS3DATTRIB_RED_SIZE:
            cfg_attrs[k2++] = GLX_RED_SIZE;
            cfg_attrs[k2++] = attrib_list[k1 + 1];
            k1 += 2;
            break;
        case PP_GRAPHICS3DATTRIB_DEPTH_SIZE:
            cfg_attrs[k2++] = GLX_DEPTH_SIZE;
            cfg_attrs[k2++] = attrib_list[k1 + 1];
            k1 += 2;
            break;
        case PP_GRAPHICS3DATTRIB_STENCIL_SIZE:
            cfg_attrs[k2++] = GLX_STENCIL_SIZE;
            cfg_attrs[k2++] = attrib_list[k1 + 1];
            k1 += 2;
            break;
        case PP_GRAPHICS3DATTRIB_SAMPLES:
            cfg_attrs[k2++] = GLX_SAMPLES;
            cfg_attrs[k2++] = attrib_list[k1 + 1];
            k1 += 2;
            break;
        case PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS:
            cfg_attrs[k2++] = GLX_SAMPLE_BUFFERS;
            cfg_attrs[k2++] = attrib_list[k1 + 1];
            k1 += 2;
            break;
        case GLX_Y_INVERTED_EXT:
            cfg_attrs[k2++] = GLX_Y_INVERTED_EXT;
            cfg_attrs[k2++] = attrib_list[k1 + 1];
            k1 += 2;
            break;
        case GLX_BIND_TO_TEXTURE_RGBA_EXT:
            cfg_attrs[k2++] = GLX_BIND_TO_TEXTURE_RGBA_EXT;
            cfg_attrs[k2++] = attrib_list[k1 + 1];
            k1 += 2;
            break;
        default:
            // skip unknown attribute
            trace_error("%s, unknown attribute 0x%x\n", __func__, attrib_list[k1]);
            k1 += 1;
            break;
        }
    }

    pthread_mutex_lock(&display.lock);
    int screen = DefaultScreen(display.x);
    int nconfigs = 0;
    GLXFBConfig *fb_cfgs = glXChooseFBConfig(display.x, screen, cfg_attrs, &nconfigs);
    free(cfg_attrs);

    if (!fb_cfgs) {
        trace_error("%s, glXChooseFBConfig returned NULL\n", __func__);
        goto err;
    }

    trace_info_f("%s, glXChooseFBConfig returned %d configs, choosing first one\n", __func__,
                 nconfigs);
    g3d->fb_config = fb_cfgs[0];
    XFree(fb_cfgs);

#if HAVE_GLES2
    // create context implementing OpenGL ES 2.0
    const int ctx_attrs[] = {
        GLX_RENDER_TYPE,                GLX_RGBA_TYPE,
        GLX_CONTEXT_MAJOR_VERSION_ARB,  2,
        GLX_CONTEXT_MINOR_VERSION_ARB,  0,
        GLX_CONTEXT_PROFILE_MASK_ARB,   GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
        None,
    };
#else
    // create context implementing OpenGL 2.0
    // OpenGL ES 2.0 will be emulated with help of shader translator
    const int ctx_attrs[] = {
        GLX_RENDER_TYPE,                GLX_RGBA_TYPE,
        GLX_CONTEXT_MAJOR_VERSION_ARB,  2,
        GLX_CONTEXT_MINOR_VERSION_ARB,  0,
        None,
    };
#endif

    if (display.glXCreateContextAttribsARB) {
        g3d->glc = display.glXCreateContextAttribsARB(display.x, g3d->fb_config, share_glc, True,
                                                      ctx_attrs);
        if (!g3d->glc)
            trace_warning("%s, glXCreateContextAttribsARB returned NULL\n", __func__);

    } else {
        g3d->glc = NULL;
    }

    if (!g3d->glc) {
        // if glXCreateContextAttribsARB is not present or returned NULL,
        // request any GL context
        g3d->glc = glXCreateNewContext(display.x, g3d->fb_config, GLX_RGBA_TYPE, share_glc, True);
        if (!g3d->glc) {
            trace_error("%s, glXCreateNewContext returned NULL\n", __func__);
            goto err;
        }
    }

    g3d->depth = pp_i->is_transparent ? 32 : DefaultDepth(display.x, screen);
    switch (g3d->depth) {
    case 24:
        g3d->xr_pictfmt = display.pictfmt_rgb24;
        break;
    case 32:
        g3d->xr_pictfmt = display.pictfmt_argb32;
        break;
    default:
        trace_error("%s, unsupported g3d->depth (%d)\n", __func__, g3d->depth);
        goto err;
    }

    g3d->pixmap = XCreatePixmap(display.x, DefaultRootWindow(display.x), g3d->width, g3d->height,
                                g3d->depth);
    g3d->glx_pixmap = glXCreatePixmap(display.x, g3d->fb_config, g3d->pixmap, NULL);
    if (g3d->glx_pixmap == None) {
        trace_error("%s, failed to create GLX pixmap\n", __func__);
        goto err;
    }

    XFlush(display.x);
    g3d->xr_pict = XRenderCreatePicture(display.x, g3d->pixmap, g3d->xr_pictfmt, 0, 0);

    int ret = glXMakeCurrent(display.x, g3d->glx_pixmap, g3d->glc);
    if (!ret) {
        trace_error("%s, glXMakeCurrent failed\n", __func__);
        goto err;
    }

    // clear surface
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glXMakeCurrent(display.x, None, NULL);

    g3d->sub_maps = g_hash_table_new(g_direct_hash, g_direct_equal);
    pthread_mutex_unlock(&display.lock);

    pp_resource_release(context);
    return context;
err:
    pthread_mutex_unlock(&display.lock);
    pp_resource_release(context);
    pp_resource_expunge(context);
    return 0;
}
Example #30
0
/*
 * Opens a window. Requires a SFG_Window object created and attached
 * to the freeglut structure. OpenGL context is created here.
 */
void fgOpenWindow( SFG_Window* window, const char* title,
                   int x, int y, int w, int h,
                   GLboolean gameMode, GLboolean isSubWindow )
{
#if TARGET_HOST_UNIX_X11
    XSetWindowAttributes winAttr;
    XTextProperty textProperty;
    XSizeHints sizeHints;
    XWMHints wmHints;
    unsigned long mask;

    freeglut_assert_ready;

    /*
     * XXX fgChooseVisual() is a common part of all three.
     * XXX With a little thought, we should be able to greatly
     * XXX simplify this.
     */
    if( !window->IsMenu )
        window->Window.VisualInfo = fgChooseVisual( );
    else if( fgStructure.MenuContext )
        window->Window.VisualInfo = fgChooseVisual( );
    else
    {
        /* XXX Why are menus double- and depth-buffered? */
        unsigned int current_DisplayMode = fgState.DisplayMode ;
        fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ;
        window->Window.VisualInfo = fgChooseVisual( );
        fgState.DisplayMode = current_DisplayMode ;
    }

    if( ! window->Window.VisualInfo )
    {
        /*
         * The "fgChooseVisual" returned a null meaning that the visual
         * context is not available.
         * Try a couple of variations to see if they will work.
         */
        if( !( fgState.DisplayMode & GLUT_DOUBLE ) )
        {
            fgState.DisplayMode |= GLUT_DOUBLE ;
            window->Window.VisualInfo = fgChooseVisual( );
            fgState.DisplayMode &= ~GLUT_DOUBLE;
        }

        /*
         * GLUT also checks for multi-sampling, but I don't see that
         * anywhere else in FREEGLUT so I won't bother with it for the moment.
         */
    }

    /*
     * XXX This seems to be abusing an assert() for error-checking.
     * XXX It is possible that the visual simply can't be found,
     * XXX in which case we should print an error and return a 0
     * XXX for the window id, I think.
     */
    assert( window->Window.VisualInfo != NULL );


    /*
     * XXX HINT: the masks should be updated when adding/removing callbacks.
     * XXX       This might speed up message processing. Is that true?
     * XXX
     * XXX A: Not appreciably, but it WILL make it easier to debug.
     * XXX    Try tracing old GLUT and try tracing freeglut.  Old GLUT
     * XXX    turns off events that it doesn't need and is a whole lot
     * XXX    more pleasant to trace.  (Think mouse-motion!  Tons of
     * XXX    ``bonus'' GUI events stream in.)
     */
    winAttr.event_mask        =
        StructureNotifyMask | SubstructureNotifyMask | ExposureMask |
        ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyRelease |
        VisibilityChangeMask | EnterWindowMask | LeaveWindowMask |
        PointerMotionMask | ButtonMotionMask;
    winAttr.background_pixmap = None;
    winAttr.background_pixel  = 0;
    winAttr.border_pixel      = 0;

    winAttr.colormap = XCreateColormap(
        fgDisplay.Display, fgDisplay.RootWindow,
        window->Window.VisualInfo->visual, AllocNone
    );

    mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;

    if( window->IsMenu )
    {
        winAttr.override_redirect = True;
        mask |= CWOverrideRedirect;
    }

    window->Window.Handle = XCreateWindow(
        fgDisplay.Display,
        window->Parent == NULL ? fgDisplay.RootWindow :
        window->Parent->Window.Handle,
        x, y, w, h, 0,
        window->Window.VisualInfo->depth, InputOutput,
        window->Window.VisualInfo->visual, mask,
        &winAttr
    );

    /*
     * The GLX context creation, possibly trying the direct context rendering
     *  or else use the current context if the user has so specified
     */
    if( window->IsMenu )
    {
        /*
         * If there isn't already an OpenGL rendering context for menu
         * windows, make one
         */
        if( !fgStructure.MenuContext )
        {
            fgStructure.MenuContext =
                (SFG_MenuContext *)malloc( sizeof(SFG_MenuContext) );
            fgStructure.MenuContext->VisualInfo = window->Window.VisualInfo;
            fgStructure.MenuContext->Context = glXCreateContext(
                fgDisplay.Display, fgStructure.MenuContext->VisualInfo,
                NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT )
            );
        }

        /* window->Window.Context = fgStructure.MenuContext->Context; */
        window->Window.Context = glXCreateContext(
            fgDisplay.Display, window->Window.VisualInfo,
            NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT )
        );
    }
    else if( fgState.UseCurrentContext )
    {
        window->Window.Context = glXGetCurrentContext( );

        if( ! window->Window.Context )
            window->Window.Context = glXCreateContext(
                fgDisplay.Display, window->Window.VisualInfo,
                NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT )
            );
    }
    else
        window->Window.Context = glXCreateContext(
            fgDisplay.Display, window->Window.VisualInfo,
            NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT )
        );

    if(  !glXIsDirect( fgDisplay.Display, window->Window.Context ) )
    {
      if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT )
        fgError( "Unable to force direct context rendering for window '%s'",
                 title );
      else if( fgState.DirectContext == GLUT_TRY_DIRECT_CONTEXT )
        fgWarning( "Unable to create direct context rendering for window '%s'\nThis may hurt performance.",
                 title );
    }

    glXMakeCurrent(
        fgDisplay.Display,
        window->Window.Handle,
        window->Window.Context
    );

    /*
     * XXX Assume the new window is visible by default
     * XXX Is this a  safe assumption?
     */
    window->State.Visible = GL_TRUE;

    sizeHints.flags = 0;
    if ( fgState.Position.Use )
        sizeHints.flags |= USPosition;
    if ( fgState.Size.Use )
        sizeHints.flags |= USSize;

    /*
     * Fill in the size hints values now (the x, y, width and height
     * settings are obsolote, are there any more WMs that support them?)
     * Unless the X servers actually stop supporting these, we should
     * continue to fill them in.  It is *not* our place to tell the user
     * that they should replace a window manager that they like, and which
     * works, just because *we* think that it's not "modern" enough.
     */
#if TARGET_HOST_WINCE
    sizeHints.x      = 0;
    sizeHints.y      = 0;
    sizeHints.width  = 320;
    sizeHints.height = 240;
#else
    sizeHints.x      = x;
    sizeHints.y      = y;
    sizeHints.width  = w;
    sizeHints.height = h;
#endif /* TARGET_HOST_WINCE */

    wmHints.flags = StateHint;
    wmHints.initial_state = fgState.ForceIconic ? IconicState : NormalState;
    /*
     * Prepare the window and iconified window names...
     */
    XStringListToTextProperty( (char **) &title, 1, &textProperty );

    XSetWMProperties(
        fgDisplay.Display,
        window->Window.Handle,
        &textProperty,
        &textProperty,
        0,
        0,
        &sizeHints,
        &wmHints,
        NULL
    );

    XSetWMProtocols( fgDisplay.Display, window->Window.Handle,
                     &fgDisplay.DeleteWindow, 1 );

    XMapWindow( fgDisplay.Display, window->Window.Handle );

#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE

    WNDCLASS wc;
    DWORD flags;
    DWORD exFlags = 0;
    ATOM atom;

    freeglut_assert_ready;

    /*
     * Grab the window class we have registered on glutInit():
     */
    atom = GetClassInfo( fgDisplay.Instance, _T("FREEGLUT"), &wc );
    assert( atom != 0 );

    if( gameMode )
    {
        assert( window->Parent == NULL );

        /*
         * Set the window creation flags appropriately to make the window
         * entirely visible:
         */
        flags = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE;
    }
    else
    {
#if !TARGET_HOST_WINCE
        if ( ( ! isSubWindow ) && ( ! window->IsMenu ) )
        {
            /*
             * Update the window dimensions, taking account of window
             * decorations.  "freeglut" is to create the window with the
             * outside of its border at (x,y) and with dimensions (w,h).
             */
            w += (GetSystemMetrics( SM_CXSIZEFRAME ) )*2;
            h += (GetSystemMetrics( SM_CYSIZEFRAME ) )*2 +
                GetSystemMetrics( SM_CYCAPTION );
        }
#endif /* TARGET_HOST_WINCE */

        if( ! fgState.Position.Use )
        {
            x = CW_USEDEFAULT;
            y = CW_USEDEFAULT;
        }
        if( ! fgState.Size.Use )
        {
            w = CW_USEDEFAULT;
            h = CW_USEDEFAULT;
        }

        /*
         * There's a small difference between creating the top, child and
         * game mode windows
         */
        flags = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE;

        if ( window->IsMenu )
        {
            flags |= WS_POPUP;
            exFlags |= WS_EX_TOOLWINDOW;
        }
#if !TARGET_HOST_WINCE
        else if( window->Parent == NULL )
            flags |= WS_OVERLAPPEDWINDOW;
#endif
        else
            flags |= WS_CHILD;
    }

#if TARGET_HOST_WINCE
    {
        wchar_t* wstr = wstr_from_str(title);

        window->Window.Handle = CreateWindow(
            _T("FREEGLUT"),
            wstr,
            WS_VISIBLE | WS_POPUP,
            0,0, 240,320,
            NULL,
            NULL,
            fgDisplay.Instance,
            (LPVOID) window
        );

        free(wstr);

        SHFullScreen(window->Window.Handle, SHFS_HIDESTARTICON);
        SHFullScreen(window->Window.Handle, SHFS_HIDESIPBUTTON);
        SHFullScreen(window->Window.Handle, SHFS_HIDETASKBAR);
        MoveWindow(window->Window.Handle, 0, 0, 240, 320, TRUE);
        ShowWindow(window->Window.Handle, SW_SHOW);
        UpdateWindow(window->Window.Handle);
    }
#else
    window->Window.Handle = CreateWindowEx(
        exFlags,
        "FREEGLUT",
        title,
        flags,
        x, y, w, h,
        (HWND) window->Parent == NULL ? NULL : window->Parent->Window.Handle,
        (HMENU) NULL,
        fgDisplay.Instance,
        (LPVOID) window
    );
#endif /* TARGET_HOST_WINCE */

    if( !( window->Window.Handle ) )
        fgError( "Failed to create a window (%s)!", title );

#if TARGET_HOST_WINCE
    ShowWindow( window->Window.Handle, SW_SHOW );
#else
    ShowWindow( window->Window.Handle,
                fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOW );
#endif /* TARGET_HOST_WINCE */

    UpdateWindow( window->Window.Handle );
    ShowCursor( TRUE );  /* XXX Old comments say "hide cusror"! */

#endif

    fgSetWindow( window );

    window->Window.DoubleBuffered =
        ( fgState.DisplayMode & GLUT_DOUBLE ) ? 1 : 0;

    if ( ! window->Window.DoubleBuffered )
    {
        glDrawBuffer ( GL_FRONT );
        glReadBuffer ( GL_FRONT );
    }
}