Example #1
0
static int
string_width (sws_configuration *sc, const char *s)
{
  if (textures_p)
    return texture_string_width (sc->texfont, s, 0);
  else
    return glutStrokeLength (GLUT_FONT, (unsigned char *) s);
}
Example #2
0
static int
char_width (fliptext_configuration *sc, char c)
{
  char s[2];
  s[0] = c;
  s[1] = 0;
  return texture_string_width (sc->texfont, s, 0);
}
static void
loading_msg (ModeInfo *mi, int n)
{
  carousel_state *ss = &sss[MI_SCREEN(mi)];
  int wire = MI_IS_WIREFRAME(mi);
  char text[100];
  GLfloat scale;

  if (wire) return;

  if (n == 0)
    sprintf (text, "Loading images...");
  else
    sprintf (text, "Loading images...  (%d%%)",
             (int) (n * 100 / MI_COUNT(mi)));

  if (ss->loading_sw == 0)    /* only do this once, so that the string doesn't move. */
    ss->loading_sw = texture_string_width (ss->texfont, text, &ss->loading_sh);

  scale = ss->loading_sh / (GLfloat) MI_HEIGHT(mi);

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();

  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();
  gluOrtho2D(0, MI_WIDTH(mi), 0, MI_HEIGHT(mi));

  glTranslatef ((MI_WIDTH(mi)  - ss->loading_sw) / 2,
                (MI_HEIGHT(mi) - ss->loading_sh) / 2,
                0);
  glColor3f (1, 1, 0);
  glEnable (GL_TEXTURE_2D);
  glDisable (GL_DEPTH_TEST);
  print_texture_string (ss->texfont, text);
  glEnable (GL_DEPTH_TEST);
  glPopMatrix();

  glMatrixMode(GL_PROJECTION);
  glPopMatrix();

  glMatrixMode(GL_MODELVIEW);

  glFinish();
  glXSwapBuffers (MI_DISPLAY (mi), MI_WINDOW(mi));
}
Example #4
0
/* Reads some text from the subprocess, and creates and returns a `line'
   object.  Adds that object to the lines list.   Returns 0 if no text
   available yet.

   If skip_blanks_p, then keep trying for new lines of text until we
   get one that is not empty.
 */
static line *
make_line (fliptext_configuration *sc, Bool skip_blanks_p)
{
  line *ln;
  char *s;

 AGAIN:
  s = get_one_line (sc);
  if (s && skip_blanks_p && blank_p (s))
    {
      free (s);
      goto AGAIN;
    }

  if (!s) return 0;

  ln = (line *) calloc (1, sizeof(*ln));
  ln->text = s;
  ln->state = NEW;
  ln->width = sc->font_scale * texture_string_width (sc->texfont, s, 0);
  ln->height = sc->font_scale * sc->line_height;

  memcpy (ln->color, sc->color, sizeof(ln->color));

  sc->nlines++;
  if (sc->lines_size <= sc->nlines)
    {
      sc->lines_size = (sc->lines_size * 1.2) + sc->nlines;
      sc->lines = (line **)
        realloc (sc->lines, sc->lines_size * sizeof(*sc->lines));
      if (! sc->lines)
        {
          fprintf (stderr, "%s: out of memory (%d lines)\n",
                   progname, sc->lines_size);
          exit (1);
        }
    }

  sc->lines[sc->nlines-1] = ln;
  return ln;
}
static void
draw_frame (ModeInfo *mi, image_frame *frame, time_t now, Bool body_p)
{
  carousel_state *ss = &sss[MI_SCREEN(mi)];
  int wire = MI_IS_WIREFRAME(mi);

  GLfloat texw  = frame->current.geom.width  / (GLfloat) frame->current.tw;
  GLfloat texh  = frame->current.geom.height / (GLfloat) frame->current.th;
  GLfloat texx1 = frame->current.geom.x / (GLfloat) frame->current.tw;
  GLfloat texy1 = frame->current.geom.y / (GLfloat) frame->current.th;
  GLfloat texx2 = texx1 + texw;
  GLfloat texy2 = texy1 + texh;
  GLfloat aspect = ((GLfloat) frame->current.geom.height /
                    (GLfloat) frame->current.geom.width);

  glBindTexture (GL_TEXTURE_2D, frame->current.texid);

  glPushMatrix();

  /* Position this image on the wheel.
   */
  glRotatef (frame->theta, 0, 1, 0);
  glTranslatef (0, 0, frame->r);

  /* Scale down the image so that all N frames fit on the wheel
     without bumping in to each other.
  */
  {
    GLfloat t, s;
    switch (ss->nframes)
      {
      case 1:  t = -1.0; s = 1.7; break;
      case 2:  t = -0.8; s = 1.6; break;
      case 3:  t = -0.4; s = 1.5; break;
      case 4:  t = -0.2; s = 1.3; break;
      default: t =  0.0; s = 6.0 / ss->nframes; break;
      }
    glTranslatef (0, 0, t);
    glScalef (s, s, s);
  }

  /* Center this image on the wheel plane.
   */
  glTranslatef (-0.5, -(aspect/2), 0);

  /* Move as per the "zoom in and out" setting.
   */
  if (zoom_p)
    {
      double x, y, z;
      /* Only use the Z component of the rotator for in/out position. */
      get_position (frame->rot, &x, &y, &z, !ss->button_down_p);
      glTranslatef (0, 0, z/2);
    }

  /* Compute the "drop in and out" state.
   */
  switch (frame->mode)
    {
    case EARLY:
      abort();
      break;
    case NORMAL:
      if (!ss->button_down_p &&
          now >= frame->expires &&
          ss->loads_in_progress == 0)  /* only load one at a time */
        load_image (mi, frame);
      break;
    case LOADING:
      break;
    case OUT:
      if (--frame->mode_tick <= 0) {
        image swap = frame->current;
        frame->current = frame->loading;
        frame->loading = swap;

        frame->mode = IN;
        frame->mode_tick = fade_ticks / speed;
      }
      break;
    case IN:
      if (--frame->mode_tick <= 0)
        frame->mode = NORMAL;
      break;
    default:
      abort();
    }

  /* Now translate for current in/out state.
   */
  if (frame->mode == OUT || frame->mode == IN)
    {
      GLfloat t = (frame->mode == OUT
                   ? frame->mode_tick / (fade_ticks / speed)
                   : (((fade_ticks / speed) - frame->mode_tick + 1) /
                      (fade_ticks / speed)));
      t = 5 * (1 - t);
      if (frame->from_top_p) t = -t;
      glTranslatef (0, t, 0);
    }

  if (body_p)					/* Draw the image quad. */
    {
      if (! wire)
        {
          glColor3f (1, 1, 1);
          glNormal3f (0, 0, 1);
          glEnable (GL_TEXTURE_2D);
          glBegin (GL_QUADS);
          glNormal3f (0, 0, 1);
          glTexCoord2f (texx1, texy2); glVertex3f (0, 0, 0);
          glTexCoord2f (texx2, texy2); glVertex3f (1, 0, 0);
          glTexCoord2f (texx2, texy1); glVertex3f (1, aspect, 0);
          glTexCoord2f (texx1, texy1); glVertex3f (0, aspect, 0);
          glEnd();
        }

      /* Draw a box around it.
       */
      glLineWidth (2.0);
      glColor3f (0.5, 0.5, 0.5);
      glDisable (GL_TEXTURE_2D);
      glBegin (GL_LINE_LOOP);
      glVertex3f (0, 0, 0);
      glVertex3f (1, 0, 0);
      glVertex3f (1, aspect, 0);
      glVertex3f (0, aspect, 0);
      glEnd();

    }
  else					/* Draw a title under the image. */
    {
      int sw, sh;
      GLfloat scale = 0.05;
      char *title = frame->current.title ? frame->current.title : "(untitled)";
      sw = texture_string_width (ss->texfont, title, &sh);

      glTranslatef (0, -scale, 0);

      scale /= sh;
      glScalef (scale, scale, scale);

      glTranslatef (((1/scale) - sw) / 2, 0, 0);
      glColor3f (1, 1, 1);

      if (!wire)
        {
          glEnable (GL_TEXTURE_2D);
          print_texture_string (ss->texfont, title);
        }
      else
        {
          glBegin (GL_LINE_LOOP);
          glVertex3f (0,  0,  0);
          glVertex3f (sw, 0,  0);
          glVertex3f (sw, sh, 0);
          glVertex3f (0,  sh, 0);
          glEnd();
        }
    }

  glPopMatrix();
}
Example #6
0
ENTRYPOINT void 
init_sws (ModeInfo *mi)
{
  double font_height;

  sws_configuration *sc = 0;

  if (!scs) {
    scs = (sws_configuration *)
      calloc (MI_NUM_SCREENS(mi), sizeof (sws_configuration));
    if (!scs) {
      fprintf(stderr, "%s: out of memory\n", progname);
      exit(1);
    }
  }

  sc = &scs[MI_SCREEN(mi)];

  sc->dpy = MI_DISPLAY(mi);
  sc = &scs[MI_SCREEN(mi)];
  sc->lines = (char **) calloc (max_lines+1, sizeof(char *));

  if ((sc->glx_context = init_GL(mi)) != NULL) {
    gl_init(mi);
    reshape_sws (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
    clear_gl_error(); /* WTF? sometimes "invalid op" from glViewport! */

    init_stars (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
  }

  if (textures_p)
    {
      int cw, lh;
      sc->texfont = load_texture_font (MI_DISPLAY(mi), "font");
      cw = texture_string_width (sc->texfont, "n", &lh);
      sc->char_width = cw;
      font_height = lh;
      glEnable(GL_ALPHA_TEST);
      glEnable (GL_TEXTURE_2D);

      check_gl_error ("loading font");

      /* "Anistropic filtering helps for quadrilateral-angled textures.
         A sharper image is accomplished by interpolating and filtering
         multiple samples from one or more mipmaps to better approximate
         very distorted textures.  This is the next level of filtering
         after trilinear filtering." */
      if (smooth_p && 
          strstr ((char *) glGetString(GL_EXTENSIONS),
                  "GL_EXT_texture_filter_anisotropic"))
      {
        GLfloat anisotropic = 0.0;
        glGetFloatv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &anisotropic);
        if (anisotropic >= 1.0)
          glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 
                           anisotropic);
      }
    }
  else
    {
      font_height = GLUT_FONT->top - GLUT_FONT->bottom;
      sc->char_width = glutStrokeWidth (GLUT_FONT, 'z'); /* 'n' seems wide */
    }
  
  sc->font_scale = 1.0 / sc->char_width;


  /* We consider a font that consumes 80 columns to be "18 points".

     If neither -size nor -columns was specified, default to 60 columns
     (which is 24 points.)

     If both were specified, -columns has priority.
   */
  {
    int base_col  = 80;
    int base_size = 18;

    if (target_columns <= 0 && font_size <= 0)
      target_columns = 60;

    if (target_columns > 0)
      font_size = base_size * (base_col / (double) target_columns);
    else if (font_size > 0)
      target_columns = base_col * (base_size / (double) font_size);
  }

  sc->line_pixel_width = target_columns * sc->char_width;

  sc->font_scale /= target_columns;
  sc->line_height = font_height * sc->font_scale;


  /* Buffer only two lines of text.
     If the buffer is too big, there's a significant delay between
     when the program launches and when the text appears, which can be
     irritating for time-sensitive output (clock, current music, etc.)
   */
  sc->buf_size = target_columns * 2;
  if (sc->buf_size < 80) sc->buf_size = 80;
  sc->buf = (char *) calloc (1, sc->buf_size);

  sc->total_lines = max_lines-1;

  if (random() & 1)
    star_spin = -star_spin;

  if (!alignment_str || !*alignment_str ||
      !strcasecmp(alignment_str, "left"))
    alignment = -1;
  else if (!strcasecmp(alignment_str, "center") ||
           !strcasecmp(alignment_str, "middle"))
    alignment = 0;
  else if (!strcasecmp(alignment_str, "right"))
    alignment = 1;
  else
    {
      fprintf (stderr,
               "%s: alignment must be left, center, or right, not \"%s\"\n",
               progname, alignment_str);
      exit (1);
    }

  sc->tc = textclient_open (sc->dpy);

  /* one more reshape, after line_height has been computed */
  reshape_sws (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
}
Example #7
0
static int
draw_text (ModeInfo *mi, const char *string, GLfloat r, GLfloat th, 
           GLfloat ttl, GLfloat size)
{
  sonar_configuration *sp = &sps[MI_SCREEN(mi)];
  int wire = MI_IS_WIREFRAME(mi);
  int polys = 0;
  GLfloat font_scale = 0.001 * (size > 0 ? size : font_size) / 14.0;
  int lines = 0, max_w = 0, lh = 0;
  char *string2 = strdup (string);
  char *token = string2;
  char *line;
  GLfloat color[4];

  if (size <= 0)   /* if size not specified, draw in yellow with alpha */
    {
      color[0] = 1;
      color[1] = 1;
      color[2] = 0;
      color[3] = (ttl / (M_PI * 2)) * 1.2;
      if (color[3] > 1) color[3] = 1;

      glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
      if (wire)
        glColor3f (color[0]*color[3], color[1]*color[3], color[2]*color[3]);
    }

  while ((line = strtok (token, "\r\n")))
    {
      int w = texture_string_width (sp->texfont, line, &lh);
      if (w > max_w) max_w = w;
      lines++;
      token = 0;
    }

  glPushMatrix();
  glTranslatef (r * cos (th), r * sin(th), 0);
  glScalef (font_scale, font_scale, font_scale);

  if (size <= 0)		/* Draw the dot */
    {
      GLfloat s = font_size * 1.7;
      glDisable (GL_TEXTURE_2D);
      glFrontFace (GL_CW);
      glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
      glVertex3f (0, s, 0);
      glVertex3f (s, s, 0);
      glVertex3f (s, 0, 0);
      glVertex3f (0, 0, 0);
      glEnd();
      glTranslatef (-max_w/2, -lh, 0);
    }
  else
    glTranslatef (-max_w/2, -lh/2, 0);

  /* draw each line, centered */
  if (! wire) glEnable (GL_TEXTURE_2D);
  free (string2);
  string2 = strdup (string);
  token = string2;
  while ((line = strtok (token, "\r\n")))
    {
      int w = texture_string_width (sp->texfont, line, 0);
      glPushMatrix();
      glTranslatef ((max_w-w)/2, 0, 0);

      if (wire)
        {
          glBegin (GL_LINE_LOOP);
          glVertex3f (0, 0, 0);
          glVertex3f (w, 0, 0);
          glVertex3f (w, lh, 0);
          glVertex3f (0, lh, 0);
          glEnd();
        }
      else
        {
          glFrontFace (GL_CW);
          print_texture_string (sp->texfont, line);
        }
      glPopMatrix();
      glTranslatef (0, -lh, 0);
      polys++;
      token = 0;
    }
  glPopMatrix();

  free (string2);

  if (! wire) glEnable (GL_DEPTH_TEST);

  return polys;
}
Example #8
0
ENTRYPOINT void 
init_fliptext (ModeInfo *mi)
{
  int wire = MI_IS_WIREFRAME(mi);

  fliptext_configuration *sc;

  if (!scs) {
    scs = (fliptext_configuration *)
      calloc (MI_NUM_SCREENS(mi), sizeof (fliptext_configuration));
    if (!scs) {
      fprintf(stderr, "%s: out of memory\n", progname);
      exit(1);
    }

    sc = &scs[MI_SCREEN(mi)];
    sc->lines = (line **) calloc (max_lines+1, sizeof(char *));
  }

  sc = &scs[MI_SCREEN(mi)];
  sc->dpy = MI_DISPLAY(mi);

  if ((sc->glx_context = init_GL(mi)) != NULL) {
    reshape_fliptext (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
  }

  program = get_string_resource (mi->dpy, "program", "Program");

  {
    int cw, lh;
    sc->texfont = load_texture_font (MI_DISPLAY(mi), "font");
    check_gl_error ("loading font");
    cw = texture_string_width (sc->texfont, "n", &lh);
    sc->char_width = cw;
    sc->line_height = lh;
  }

  if (!wire)
    {
      glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
      glEnable (GL_BLEND);
      glEnable (GL_ALPHA_TEST);
      glEnable (GL_TEXTURE_2D);

      /* "Anistropic filtering helps for quadrilateral-angled textures.
         A sharper image is accomplished by interpolating and filtering
         multiple samples from one or more mipmaps to better approximate
         very distorted textures.  This is the next level of filtering
         after trilinear filtering." */
      if (strstr ((char *) glGetString(GL_EXTENSIONS),
                  "GL_EXT_texture_filter_anisotropic"))
      {
        GLfloat anisotropic = 0.0;
        glGetFloatv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &anisotropic);
        if (anisotropic >= 1.0)
          glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 
                           anisotropic);
      }
    }
  
  /* The default font is (by fiat) "18 points".
     Interpret the user's font size request relative to that.
   */
  sc->font_scale = 3 * (font_size / 18.0);

  if (target_columns <= 2) target_columns = 2;

  /* Figure out what the wrap column should be, in font-coordinate pixels.
     Compute it from the given -columns value, but don't let it be wider
     than the screen.
   */
  {
    GLfloat maxw = 110 * sc->line_height / sc->font_scale;  /* magic... */
    sc->font_wrap_pixels = target_columns * sc->char_width;
    if (sc->font_wrap_pixels > maxw ||
        sc->font_wrap_pixels <= 0)
      sc->font_wrap_pixels = maxw;
  }

  sc->buf_size = target_columns * max_lines;
  sc->buf = (char *) calloc (1, sc->buf_size);

  sc->subproc_relaunch_delay = 2 * 1000;   /* 2 seconds */

  alignment_random_p = False;
  if (!alignment_str || !*alignment_str ||
      !strcasecmp(alignment_str, "left"))
    alignment = -1;
  else if (!strcasecmp(alignment_str, "center") ||
           !strcasecmp(alignment_str, "middle"))
    alignment = 0;
  else if (!strcasecmp(alignment_str, "right"))
    alignment = 1;
  else if (!strcasecmp(alignment_str, "random"))
    alignment = -1, alignment_random_p = True;

  else
    {
      fprintf (stderr,
               "%s: alignment must be left/center/right/random, not \"%s\"\n",
               progname, alignment_str);
      exit (1);
    }

  launch_text_generator (sc);

  if (max_lines < 1) max_lines = 1;
  min_lines = max_lines * 0.66;
  if (min_lines > max_lines - 3) min_lines = max_lines - 4;
  if (min_lines < 1) min_lines = 1;

  parse_color (mi, "foreground",
               get_string_resource(mi->dpy, "foreground", "Foreground"),
               sc->color);

  sc->top_margin = (sc->char_width * 100);
  sc->bottom_margin = -sc->top_margin;
  reshape_fliptext (mi, MI_WIDTH(mi), MI_HEIGHT(mi));  /* compute left/right */
}
Example #9
0
static void
draw_line (ModeInfo *mi, line *line)
{
  int wire = MI_IS_WIREFRAME(mi);
  fliptext_configuration *sc = &scs[MI_SCREEN(mi)];

  if (! line->text || !*line->text ||
      line->state == NEW || line->state == HESITATE || line->state == DEAD)
    return;

  glPushMatrix();
  glTranslatef (line->current.x, line->current.y, line->current.z);

  glRotatef (line->cth, 0, 1, 0);

  if (alignment == 1)
    glTranslatef (-line->width, 0, 0);
  else if (alignment == 0)
    glTranslatef (-line->width/2, 0, 0);

  glScalef (sc->font_scale, sc->font_scale, sc->font_scale);

  glColor4f (line->color[0], line->color[1], line->color[2], line->color[3]);

  if (!wire)
    print_texture_string (sc->texfont, line->text);
  else
    {
      int w, h;
      char *s = line->text;
      char c[2];
      c[1]=0;
      glDisable (GL_TEXTURE_2D);
      glColor3f (0.4, 0.4, 0.4);
      while (*s)
        {
          *c = *s++;
          w = texture_string_width (sc->texfont, c, &h);
          glBegin (GL_LINE_LOOP);
          glVertex3f (0, 0, 0);
          glVertex3f (w, 0, 0);
          glVertex3f (w, h, 0);
          glVertex3f (0, h, 0);
          glEnd();
          glTranslatef (w, 0, 0);
        }
    }

#if 0
  glDisable (GL_TEXTURE_2D);
  glColor3f (0.4, 0.4, 0.4);
  glBegin (GL_LINE_LOOP);
  glVertex3f (0, 0, 0);
  glVertex3f (line->width/sc->font_scale, 0, 0);
  glVertex3f (line->width/sc->font_scale, line->height/sc->font_scale, 0);
  glVertex3f (0, line->height/sc->font_scale, 0);
  glEnd();
  if (!wire) glEnable (GL_TEXTURE_2D);
#endif

  glPopMatrix();

  mi->polygon_count += strlen (line->text);
}