Esempio n. 1
0
int visual_depth (Screen *screen, Visual *visual)
{
  Display *dpy = DisplayOfScreen (screen);
  XVisualInfo vi_in, *vi_out;
  int out_count, depth;
  vi_in.screen = screen_number (screen);
  vi_in.visualid = XVisualIDFromVisual (visual);
  vi_out = XGetVisualInfo (dpy, VisualScreenMask|VisualIDMask,
                           &vi_in, &out_count);
  if (! vi_out) abort ();
  depth = vi_out[0].depth;
  XFree ((char *) vi_out);
  return depth;
}
GLXContext *
init_GL(ModeInfo * mi)
{
    Display *dpy = mi->dpy;
    Window window = mi->window;
    Screen *screen = mi->xgwa.screen;
    Visual *visual = mi->xgwa.visual;
    GLXContext glx_context = 0;
    XVisualInfo vi_in, *vi_out;
    int out_count;

    vi_in.screen = screen_number (screen);
    vi_in.visualid = XVisualIDFromVisual (visual);
    vi_out = XGetVisualInfo (dpy, VisualScreenMask|VisualIDMask,
                             &vi_in, &out_count);
    if (! vi_out) abort ();

    {
        XSync (dpy, False);
        orig_ehandler = XSetErrorHandler (BadValue_ehandler);
        glx_context = glXCreateContext (dpy, vi_out, 0, GL_TRUE);
        XSync (dpy, False);
        XSetErrorHandler (orig_ehandler);
        if (got_error)
            glx_context = 0;
    }

    XFree((char *) vi_out);

    if (!glx_context)
    {
        fprintf(stderr, "%s: couldn't create GL context for visual 0x%x.\n",
                progname, (unsigned int) XVisualIDFromVisual (visual));
        exit(1);
    }

    glXMakeCurrent (dpy, window, glx_context);

    {
        GLboolean rgba_mode = 0;
        glGetBooleanv(GL_RGBA_MODE, &rgba_mode);
        if (!rgba_mode)
        {
            glIndexi (WhitePixelOfScreen (screen));
            glClearIndex (BlackPixelOfScreen (screen));
        }
    }


    /* jwz: the doc for glDrawBuffer says "The initial value is GL_FRONT
       for single-buffered contexts, and GL_BACK for double-buffered
       contexts."  However, I find that this is not always the case,
       at least with Mesa 3.4.2 -- sometimes the default seems to be
       GL_FRONT even when glGet(GL_DOUBLEBUFFER) is true.  So, let's
       make sure.

       Oh, hmm -- maybe this only happens when we are re-using the
       xscreensaver window, and the previous GL hack happened to die with
       the other buffer selected?  I'm not sure.  Anyway, this fixes it.
     */
    {
        GLboolean d = False;
        glGetBooleanv (GL_DOUBLEBUFFER, &d);
        if (d)
            glDrawBuffer (GL_BACK);
        else
            glDrawBuffer (GL_FRONT);
    }


    /* GLXContext is already a pointer type.
       Why this function returns a pointer to a pointer, I have no idea...
     */
    {
        GLXContext *ptr = (GLXContext *) malloc(sizeof(GLXContext));
        *ptr = glx_context;
        return ptr;
    }
}
Esempio n. 3
0
GLXContext *
init_GL(ModeInfo * mi)
{
  Display *dpy = mi->dpy;
  Window window = mi->window;
  Screen *screen = mi->xgwa.screen;
  Visual *visual = mi->xgwa.visual;
  XVisualInfo vi_in, *vi_out;
  int out_count;

  if (mi->glx_context) {
    glXMakeCurrent (dpy, window, mi->glx_context);
    return &mi->glx_context;
  }

# ifdef HAVE_JWZGLES
  jwzgles_make_current(jwzgles_make_state(state));
# endif

  vi_in.screen = screen_number (screen);
  vi_in.visualid = XVisualIDFromVisual (visual);
  vi_out = XGetVisualInfo (dpy, VisualScreenMask|VisualIDMask,
			   &vi_in, &out_count);
  if (! vi_out) abort ();

  {
    XSync (dpy, False);
    orig_ehandler = XSetErrorHandler (BadValue_ehandler);
    mi->glx_context = glXCreateContext (dpy, vi_out, 0, GL_TRUE);
    XSync (dpy, False);
    XSetErrorHandler (orig_ehandler);
    if (got_error)
      mi->glx_context = 0;
  }

  XFree((char *) vi_out);

  if (!mi->glx_context)
    {
      fprintf(stderr, "%s: couldn't create GL context for visual 0x%x.\n",
	      progname, (unsigned int) XVisualIDFromVisual (visual));
      exit(1);
    }

  glXMakeCurrent (dpy, window, mi->glx_context);

  {
    GLboolean rgba_mode = 0;
    glGetBooleanv(GL_RGBA_MODE, &rgba_mode);
    if (!rgba_mode)
      {
	glIndexi (WhitePixelOfScreen (screen));
	glClearIndex (BlackPixelOfScreen (screen));
      }
  }


  /* jwz: the doc for glDrawBuffer says "The initial value is GL_FRONT
     for single-buffered contexts, and GL_BACK for double-buffered
     contexts."  However, I find that this is not always the case,
     at least with Mesa 3.4.2 -- sometimes the default seems to be
     GL_FRONT even when glGet(GL_DOUBLEBUFFER) is true.  So, let's
     make sure.

     Oh, hmm -- maybe this only happens when we are re-using the
     xscreensaver window, and the previous GL hack happened to die with
     the other buffer selected?  I'm not sure.  Anyway, this fixes it.
   */
  {
    GLboolean d = False;
    glGetBooleanv (GL_DOUBLEBUFFER, &d);
    if (d)
      glDrawBuffer (GL_BACK);
    else
      glDrawBuffer (GL_FRONT);
  }

  /* Sometimes glDrawBuffer() throws "invalid op". Dunno why. Ignore. */
  clear_gl_error ();

  /* Process the -background argument. */
  {
    char *s = get_string_resource(mi->dpy, "background", "Background");
    XColor c = { 0, };
    if (! XParseColor (dpy, mi->xgwa.colormap, s, &c))
      fprintf (stderr, "%s: can't parse color %s; using black.\n", 
               progname, s);
    glClearColor (c.red   / 65535.0,
                  c.green / 65535.0,
                  c.blue  / 65535.0,
                  1.0);
  }

  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  /* GLXContext is already a pointer type.
     Why this function returns a pointer to a pointer, I have no idea...
   */
  return &mi->glx_context;
}
Esempio n. 4
0
/* Synchronize the contents of si->ssi to the current state of the monitors.
   Doesn't change anything if nothing has changed; otherwise, alters and
   reuses existing saver_screen_info structs as much as possible.
   Returns True if anything changed.
 */
Bool
update_screen_layout (saver_info *si)
{
  monitor **monitors = scan_monitors (si);
  int count = 0;
  int good_count = 0;
  int i, j;
  int seen_screens[100] = { 0, };

  if (! layouts_differ_p (monitors, si->monitor_layout))
    {
      free_monitors (monitors);
      return False;
    }

  free_monitors (si->monitor_layout);
  si->monitor_layout = monitors;
  check_monitor_sanity (si->monitor_layout);

  while (monitors[count])
    {
      if (monitors[count]->sanity == S_SANE)
        good_count++;
      count++;
    }

  if (si->ssi_count == 0)
    {
      si->ssi_count = 10;
      si->screens = (saver_screen_info *)
        calloc (sizeof(*si->screens), si->ssi_count);
    }

  if (si->ssi_count <= good_count)
    {
      si->ssi_count = good_count + 10;
      si->screens = (saver_screen_info *)
        realloc (si->screens, sizeof(*si->screens) * si->ssi_count);
      memset (si->screens + si->nscreens, 0, 
              sizeof(*si->screens) * (si->ssi_count - si->nscreens));
    }

  if (! si->screens) abort();

  si->nscreens = good_count;

  /* Regenerate the list of GL visuals as needed. */
  if (si->best_gl_visuals)
    free (si->best_gl_visuals);
  si->best_gl_visuals = 0;

  for (i = 0, j = 0; i < count; i++)
    {
      monitor *m = monitors[i];
      saver_screen_info *ssi = &si->screens[j];
      Screen *old_screen = ssi->screen;
      int sn;
      if (monitors[i]->sanity != S_SANE) continue;

      ssi->global = si;
      ssi->number = j;

      sn = screen_number (m->screen);
      ssi->screen = m->screen;
      ssi->real_screen_number = sn;
      ssi->real_screen_p = (seen_screens[sn] == 0);
      seen_screens[sn]++;

      ssi->default_visual =
	get_visual_resource (ssi->screen, "visualID", "VisualID", False);
      ssi->current_visual = ssi->default_visual;
      ssi->current_depth = visual_depth (ssi->screen, ssi->current_visual);

      /* If the screen changed (or if this is the first time) we need
         a new toplevel shell for this screen's depth.
       */
      if (ssi->screen != old_screen)
        initialize_screen_root_widget (ssi);

      ssi->poll_mouse_last_root_x = -1;
      ssi->poll_mouse_last_root_y = -1;

      ssi->x      = m->x;
      ssi->y      = m->y;
      ssi->width  = m->width;
      ssi->height = m->height;

# ifndef DEBUG_MULTISCREEN
      {
        saver_preferences *p = &si->prefs;
        if (p->debug_p
#  ifdef QUAD_MODE
            && !p->quad_p
#  endif
            )
          ssi->width /= 2;
      }
# endif

      j++;
    }

  si->default_screen = &si->screens[0];
  return True;
}
Esempio n. 5
0
void
describe_monitor_layout (saver_info *si)
{
  monitor **monitors = si->monitor_layout;
  int count = 0;
  int good_count = 0;
  int bad_count = 0;
  int implausible_p = !plausible_aspect_ratio_p (monitors);

  while (monitors[count])
    {
      if (monitors[count]->sanity == S_SANE)
        good_count++;
      else
        bad_count++;
      count++;
    }

  if (monitors[0]->err)		/* deferred error msg */
    {
      char *token = strtok (monitors[0]->err, "\n");
      while (token)
        {
          fprintf (stderr, "%s: %s\n", blurb(), token);
          token = strtok (0, "\n");
        }
      free (monitors[0]->err);
      monitors[0]->err = 0;
    }

  if (count == 0)
    fprintf (stderr, "%s: no screens!\n", blurb());
  else
    {
      int i;
      fprintf (stderr, "%s: screens in use: %d\n", blurb(), good_count);
      for (i = 0; i < count; i++)
        {
          monitor *m = monitors[i];
          if (m->sanity != S_SANE) continue;
          fprintf (stderr, "%s:  %3d/%d: %dx%d+%d+%d",
                   blurb(), m->id, screen_number (m->screen),
                   m->width, m->height, m->x, m->y);
          if (m->desc && *m->desc) fprintf (stderr, " (%s)", m->desc);
          fprintf (stderr, "\n");
        }
      if (bad_count > 0)
        {
          fprintf (stderr, "%s: rejected screens: %d\n", blurb(), bad_count);
          for (i = 0; i < count; i++)
            {
              monitor *m = monitors[i];
              monitor *e = monitors[m->enemy];
              if (m->sanity == S_SANE) continue;
              fprintf (stderr, "%s:  %3d/%d: %dx%d+%d+%d",
                       blurb(), m->id, screen_number (m->screen),
                       m->width, m->height, m->x, m->y);
              if (m->desc && *m->desc) fprintf (stderr, " (%s)", m->desc);
              fprintf (stderr, " -- ");
              switch (m->sanity)
                {
                case S_SANE: abort(); break;
                case S_ENCLOSED:
                  fprintf (stderr, "enclosed by %d (%dx%d+%d+%d)\n",
                           e->id, e->width, e->height, e->x, e->y);
                  break;
                case S_DUPLICATE:
                  fprintf (stderr, "duplicate of %d\n", e->id);
                  break;
                case S_OVERLAP:
                  fprintf (stderr, "overlaps %d (%dx%d+%d+%d)\n",
                           e->id, e->width, e->height, e->x, e->y);
                  break;
                case S_OFFSCREEN:
                  fprintf (stderr, "off screen (%dx%d)\n",
                           WidthOfScreen (e->screen), 
                           HeightOfScreen (e->screen));
                  break;
                case S_DISABLED:
                  fprintf (stderr, "output disabled\n");
                  break;
                }
            }
        }

      if (implausible_p)
        fprintf (stderr,
                 "%s: WARNING: single screen aspect ratio is %dx%d = %.2f\n"
                 "%s:          probable X server bug in Xinerama/RANDR!\n",
                 blurb(), monitors[0]->width, monitors[0]->height,
                 monitors[0]->width / (double) monitors[0]->height,
                 blurb());
    }
}
Esempio n. 6
0
static void *
noseguy_init (Display *d, Window w)
{
  struct state *st = (struct state *) calloc (1, sizeof(*st));
  unsigned long fg, bg, text_fg, text_bg;
  XWindowAttributes xgwa;
  Colormap cmap;
  char *fontname;
  XGCValues gcvalues;
  st->dpy = d;
  st->window = w;
  st->first_time = 1;

  fontname = get_string_resource (st->dpy, "font", "Font");
  XGetWindowAttributes (st->dpy, st->window, &xgwa);
  st->Width = xgwa.width + 2;
  st->Height = xgwa.height + 2;
  cmap = xgwa.colormap;

  st->tc = textclient_open (st->dpy);
  {
    int w = 40;
    int h = 15;
    textclient_reshape (st->tc, w, h, w, h,
                        /* Passing MAXLINES isn't actually necessary */
                        0);
  }

  init_images(st);

  st->xftfont = XftFontOpenXlfd (st->dpy, screen_number (xgwa.screen),
                                 fontname);
  XftColorAllocName (st->dpy, xgwa.visual, xgwa.colormap,
                     get_string_resource (st->dpy,
                                          "textForeground", "Foreground"),
                     &st->xftcolor);
  st->xftdraw = XftDrawCreate (st->dpy, st->window, xgwa.visual,
                               xgwa.colormap);


  fg = get_pixel_resource (st->dpy, cmap, "foreground", "Foreground");
  bg = get_pixel_resource (st->dpy, cmap, "background", "Background");
  text_fg = get_pixel_resource (st->dpy, cmap, "textForeground", "Foreground");
  text_bg = get_pixel_resource (st->dpy, cmap, "textBackground", "Background");
  /* notice when unspecified */
  if (! get_string_resource (st->dpy, "textForeground", "Foreground"))
    text_fg = bg;
  if (! get_string_resource (st->dpy, "textBackground", "Background"))
    text_bg = fg;

  gcvalues.foreground = fg;
  gcvalues.background = bg;
  st->fg_gc = XCreateGC (st->dpy, st->window,
                         GCForeground|GCBackground,
		     &gcvalues);
  gcvalues.foreground = bg;
  gcvalues.background = fg;
  st->bg_gc = XCreateGC (st->dpy, st->window,
                         GCForeground|GCBackground,
		     &gcvalues);
  gcvalues.foreground = text_fg;
  gcvalues.background = text_bg;
  st->text_fg_gc = XCreateGC (st->dpy, st->window,
                              GCForeground|GCBackground,
			  &gcvalues);
  gcvalues.foreground = text_bg;
  gcvalues.background = text_fg;
  st->text_bg_gc = XCreateGC (st->dpy, st->window, 
                              GCForeground|GCBackground,
			  &gcvalues);
  st->x = st->Width / 2;
  st->y = st->Height / 2;
  st->state = IS_MOVING;
  st->next_fn = move;
  st->walk_up = 1;
  return st;
}
Esempio n. 7
0
record_anim_state *
screenhack_record_anim_init (Screen *screen, Window window, int target_frames)
{
  Display *dpy = DisplayOfScreen (screen);
  record_anim_state *st;

# ifndef USE_GL
  XGCValues gcv;
# endif /* !USE_GL */

  if (target_frames <= 0) return 0;

  st = (record_anim_state *) calloc (1, sizeof(*st));

  st->fps = 30;
  st->screen = screen;
  st->window = window;
  st->target_frames = target_frames;
  st->start_time = double_time();
  st->frame_count = 0;
  st->fade_frames = st->fps * 1.5;

  if (st->fade_frames >= (st->target_frames / 2) - st->fps)
    st->fade_frames = 0;

# ifdef HAVE_GDK_PIXBUF
  {
    Window root;
    int x, y;
    unsigned int w, h, d, bw;
    XGetGeometry (dpy, window, &root, &x, &y, &w, &h, &bw, &d);
    gdk_pixbuf_xlib_init_with_depth (dpy, screen_number (screen), d);

#  ifdef HAVE_GTK2
#   if !GLIB_CHECK_VERSION(2, 36 ,0)
    g_type_init();
#   endif
#  else  /* !HAVE_GTK2 */
    xlib_rgb_init (dpy, screen);
#  endif /* !HAVE_GTK2 */
  }
# else  /* !HAVE_GDK_PIXBUF */
#  error GDK_PIXBUF is required
# endif /* !HAVE_GDK_PIXBUF */

  XGetWindowAttributes (dpy, st->window, &st->xgwa);

# ifdef USE_GL

  st->data  = (char *) calloc (st->xgwa.width, st->xgwa.height * 3);
  st->data2 = (char *) calloc (st->xgwa.width, st->xgwa.height * 3);

# else    /* !USE_GL */

  st->gc = XCreateGC (dpy, st->window, 0, &gcv);
  st->p = XCreatePixmap (dpy, st->window,
                         st->xgwa.width, st->xgwa.height, st->xgwa.depth);
  st->img = XCreateImage (dpy, st->xgwa.visual, st->xgwa.depth, ZPixmap,
                          0, 0, st->xgwa.width, st->xgwa.height, 8, 0);
  st->img->data = (char *) calloc (st->img->height, st->img->bytes_per_line);
# endif /* !USE_GL */


# ifndef HAVE_JWXYZ
  XFetchName (dpy, st->window, &st->title);
  {
    char *s = strchr(st->title, ':');
    if (s) *s = 0;
  }
# endif /* !HAVE_JWXYZ */

  return st;
}
Esempio n. 8
0
Bool
allocate_alpha_colors (Screen *screen, Visual *visual, Colormap cmap,
		       int *nplanesP, Bool additive_p,
		       unsigned long **plane_masks,
		       unsigned long *base_pixelP , ModeInfo* mi)
{
#ifdef WIN32
  return False;
#else
  Display *dpy = DisplayOfScreen (screen);
  XColor *colors;
  int nplanes = *nplanesP;
  int i;

  if (!has_writable_cells (mi))
    cmap = 0;

  if (!cmap)            /* A TrueColor visual, or similar. */
    {
      int depth = visual_depth (screen, visual);
      unsigned long masks;
      XVisualInfo vi_in, *vi_out;

      /* Find out which bits the R, G, and B components actually occupy
         on this visual. */
      vi_in.screen = screen_number (screen);
      vi_in.visualid = XVisualIDFromVisual (visual);
      vi_out = XGetVisualInfo (dpy, VisualScreenMask|VisualIDMask,
                               &vi_in, &i);
      if (! vi_out) return False;
      masks = vi_out[0].red_mask | vi_out[0].green_mask | vi_out[0].blue_mask;
      XFree ((char *) vi_out);

      if (nplanes > depth)
        nplanes = depth;
      *nplanesP = nplanes;
      *base_pixelP = 0;
      *plane_masks = (unsigned long *) calloc(sizeof(unsigned long), nplanes);

      /* Pick the planar values randomly, but constrain them to fall within
         the bit positions of the R, G, and B fields. */
      for (i = 0; i < nplanes; i++)
        (*plane_masks)[i] = LRAND() & masks;

    }
  else                  /* A PseudoColor visual, or similar. */
    {
      if (nplanes > 31) nplanes = 31;
      *plane_masks = (unsigned long *) malloc(sizeof(unsigned long) * nplanes);

      nplanes = allocate_color_planes (dpy, cmap, nplanes, *plane_masks,
				   base_pixelP);
      *nplanesP = nplanes;

      if (nplanes <= 1)
        {
          free(*plane_masks);
          *plane_masks = 0;
          return False;
        }

      colors = (XColor *) calloc (nplanes, sizeof (XColor));
      for (i = 0; i < nplanes; i++)
        {
          /* pick the base colors. If we are in subtractive mode, pick higher
             intensities. */
          hsv_to_rgb (NRAND( 360 ),
                      NRAND( 100000 ) / 100000.0 ,
                      NRAND( 100000 ) / 200000.0 + (additive_p ? 0.2 : 0.5),
                      &colors[i].red,
                      &colors[i].green,
                      &colors[i].blue);
        }
      initialize_transparency_colormap (dpy, cmap, nplanes,
                                        *base_pixelP, *plane_masks, colors,
                                        additive_p , mi );
      XFree ((XPointer) colors);
    }
  return True;
#endif
}