about-dialog.c 14.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/* The GIMP -- an image manipulation program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
Elliot Lee's avatar
Elliot Lee committed
18 19
#include <stdio.h>
#include <stdlib.h>
Tor Lillqvist's avatar
Tor Lillqvist committed
20
#include <string.h>
Elliot Lee's avatar
Elliot Lee committed
21
#include <time.h>
Manish Singh's avatar
Manish Singh committed
22

23
#include <gtk/gtk.h>
Manish Singh's avatar
Manish Singh committed
24 25 26

#include "libgimp/gimpfeatures.h"

27
#include "config.h"
Tor Lillqvist's avatar
Tor Lillqvist committed
28
#include "libgimp/gimpenv.h"
29 30
#include "libgimp/gimpintl.h"
#include "libgimp/gimpmath.h"
31

Elliot Lee's avatar
Elliot Lee committed
32
#include "about_dialog.h"
33

Elliot Lee's avatar
Elliot Lee committed
34
#define ANIMATION_STEPS 16
35
#define ANIMATION_SIZE   2
Elliot Lee's avatar
Elliot Lee committed
36

37 38 39 40 41 42
static gint  about_dialog_load_logo   (GtkWidget *window);
static void  about_dialog_destroy     (void);
static void  about_dialog_unmap       (void);
static gint  about_dialog_logo_expose (GtkWidget *widget, GdkEventExpose *event);
static gint  about_dialog_button      (GtkWidget *widget, GdkEventButton *event);
static gint  about_dialog_timer       (gpointer data);
Elliot Lee's avatar
Elliot Lee committed
43 44 45 46 47 48 49


static GtkWidget *about_dialog = NULL;
static GtkWidget *logo_area = NULL;
static GtkWidget *scroll_area = NULL;
static GdkPixmap *logo_pixmap = NULL;
static GdkPixmap *scroll_pixmap = NULL;
50 51 52 53 54 55 56 57 58 59 60 61
static guchar *dissolve_map = NULL;
static gint  dissolve_width;
static gint  dissolve_height;
static gint  logo_width = 0;
static gint  logo_height = 0;
static gint  do_animation = 0;
static gint  do_scrolling = 0;
static gint  scroll_state = 0;
static gint  frame = 0;
static gint  offset = 0;
static gint  timer = 0;

62
/* See the end of the list for how to add names with Non-ASCII characters */
63
static gchar *scroll_text[] =
Elliot Lee's avatar
Elliot Lee committed
64 65 66 67 68 69 70
{
  "Lauri Alanko",
  "Shawn Amundson",
  "John Beale",
  "Zach Beane",
  "Tom Bech",
  "Marc Bless",
71
  "Edward Blevins",
Elliot Lee's avatar
Elliot Lee committed
72
  "Roberto Boyd",
Adrian Likins's avatar
ooops  
Adrian Likins committed
73
  "Stanislav Brabec",
74
  "Simon Budig",
75
  "Seth Burgess",
Elliot Lee's avatar
Elliot Lee committed
76
  "Brent Burton",
77
  "Francisco Bustamante",
Elliot Lee's avatar
Elliot Lee committed
78
  "Ed Connel",
79
  "Jay Cox",
Adrian Likins's avatar
ooops  
Adrian Likins committed
80
  "Kenneth Christiansen",
Elliot Lee's avatar
Elliot Lee committed
81
  "Andreas Dilger",
82
  "Austin Donnelly",
Adrian Likins's avatar
ooops  
Adrian Likins committed
83
  "Scott Draves",
Manish Singh's avatar
Manish Singh committed
84
  "Misha Dynin",
Adrian Likins's avatar
ooops  
Adrian Likins committed
85
  "Daniel Egger",
Elliot Lee's avatar
Elliot Lee committed
86
  "Larry Ewing",
87
  "Nick Fetchak",
Adrian Likins's avatar
ooops  
Adrian Likins committed
88
  "Valek Filippov",
Elliot Lee's avatar
Elliot Lee committed
89 90 91 92 93
  "David Forsyth",
  "Jim Geuther",
  "Scott Goehring",
  "Heiko Goller",
  "Michael Hammel",
Adrian Likins's avatar
ooops  
Adrian Likins committed
94
  "James Henstridge",
Elliot Lee's avatar
Elliot Lee committed
95
  "Christoph Hoegl",
96
  "Wolfgang Hofer",
Elliot Lee's avatar
Elliot Lee committed
97 98 99 100
  "Jan Hubicka",
  "Simon Janes",
  "Tim Janik",
  "Tuomas Kuosmanen",
101 102
  "Peter Kirchgessner",
  "Karin Kylander",
103
  "Olof S Kylander",
104
  "Nick Lamb",
Elliot Lee's avatar
Elliot Lee committed
105
  "Karl LaRocca",
Adrian Likins's avatar
ooops  
Adrian Likins committed
106
  "Chris Lahey",
Elliot Lee's avatar
Elliot Lee committed
107
  "Jens Lautenbacher",
108
  "Laramie Leavitt",
109
  "Elliot Lee",
110
  "Marc Lehmann",
Elliot Lee's avatar
Elliot Lee committed
111
  "Raph Levien",
Adrian Likins's avatar
ooops  
Adrian Likins committed
112
  "Wing Tung Leung",
Elliot Lee's avatar
Elliot Lee committed
113
  "Adrian Likins",
114
  "Tor Lillqvist",
Elliot Lee's avatar
Elliot Lee committed
115 116 117
  "Ingo Luetkebohle",
  "Josh MacDonald",
  "Ed Mackey",
Adrian Likins's avatar
ooops  
Adrian Likins committed
118
  "Daniele Medri",
119
  "Vidar Madsen",
Elliot Lee's avatar
Elliot Lee committed
120 121
  "Marcelo Malheiros",
  "Ian Main",
Adrian Likins's avatar
ooops  
Adrian Likins committed
122 123
  "Kjartan Maraas",
  "Kelly Martin",
Elliot Lee's avatar
Elliot Lee committed
124 125
  "Torsten Martinsen",
  "Federico Mena",
Adrian Likins's avatar
ooops  
Adrian Likins committed
126
  "David Monniaux",
Elliot Lee's avatar
Elliot Lee committed
127
  "Adam D. Moss",
Adrian Likins's avatar
ooops  
Adrian Likins committed
128
  "Sung-Hyun Nam",
Elliot Lee's avatar
Elliot Lee committed
129
  "Shuji Narazaki",
130
  "Michael Natterer",
131
  "Sven Neumann",
Elliot Lee's avatar
Elliot Lee committed
132 133
  "Stephen Robert Norris",
  "Erik Nygren",
Adrian Likins's avatar
ooops  
Adrian Likins committed
134
  "Balazs Nagy",
Elliot Lee's avatar
Elliot Lee committed
135 136
  "Miles O'Neal",
  "Jay Painter",
137
  "Asbjorn Pettersen",
Elliot Lee's avatar
Elliot Lee committed
138 139
  "Mike Phillips",
  "Raphael Quinet",
Adrian Likins's avatar
ooops  
Adrian Likins committed
140
  "Vincent Renardias",
Elliot Lee's avatar
Elliot Lee committed
141 142 143
  "James Robinson",
  "Mike Schaeffer",
  "Tracy Scott",
144
  "Aaron Sherman",
145
  "Manish Singh",
146
  "Nathan Summers",
147
  "Mike Sweet",
Elliot Lee's avatar
Elliot Lee committed
148 149 150 151
  "Eiichi Takamori",
  "Tristan Tarrant",
  "Owen Taylor",
  "Ian Tester",
152
  "Andy Thomas",
Elliot Lee's avatar
Elliot Lee committed
153 154
  "James Wang",
  "Kris Wehner",
155
  "Matthew Wilson",
Adrian Likins's avatar
ooops  
Adrian Likins committed
156
  "Shirasaki Yasuhiro",
157 158 159 160 161 162 163
#ifndef GDK_USE_UTF8_MBS
  "Ville Hautamki",
  "Tomas gren",
#else  /* Win32 GDK uses UTF-8 */
  "Ville Hautamäki",
  "Tomas Ögren",
#endif
Elliot Lee's avatar
Elliot Lee committed
164
};
165 166 167
static gint nscroll_texts = sizeof (scroll_text) / sizeof (scroll_text[0]);
static gint scroll_text_widths[100] = { 0 };
static gint cur_scroll_text = 0;
168
static gint cur_scroll_index; 
Elliot Lee's avatar
Elliot Lee committed
169

170
static gint shuffle_array[ sizeof(scroll_text) / sizeof(scroll_text[0]) ];
Elliot Lee's avatar
Elliot Lee committed
171 172

void
173
about_dialog_create (gint timeout)
Elliot Lee's avatar
Elliot Lee committed
174 175 176
{
  GtkStyle *style;
  GtkWidget *vbox;
177
  GtkWidget *aboutframe;
Elliot Lee's avatar
Elliot Lee committed
178 179 180 181
  GtkWidget *label;
  GtkWidget *alignment;
  gint max_width;
  gint i;
182
  gchar *label_text;
Elliot Lee's avatar
Elliot Lee committed
183 184 185 186

  if (!about_dialog)
    {
      about_dialog = gtk_window_new (GTK_WINDOW_DIALOG);
187
      gtk_window_set_wmclass (GTK_WINDOW (about_dialog), "about_dialog", "Gimp");
188
      gtk_window_set_title (GTK_WINDOW (about_dialog), _("About the GIMP"));
Elliot Lee's avatar
Elliot Lee committed
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
      gtk_window_set_policy (GTK_WINDOW (about_dialog), FALSE, FALSE, FALSE);
      gtk_window_position (GTK_WINDOW (about_dialog), GTK_WIN_POS_CENTER);
      gtk_signal_connect (GTK_OBJECT (about_dialog), "destroy",
			  (GtkSignalFunc) about_dialog_destroy, NULL);
      gtk_signal_connect (GTK_OBJECT (about_dialog), "unmap_event",
			  (GtkSignalFunc) about_dialog_unmap, NULL);
      gtk_signal_connect (GTK_OBJECT (about_dialog), "button_press_event",
			  (GtkSignalFunc) about_dialog_button, NULL);
      gtk_widget_set_events (about_dialog, GDK_BUTTON_PRESS_MASK);

      if (!about_dialog_load_logo (about_dialog))
	{
	  gtk_widget_destroy (about_dialog);
	  about_dialog = NULL;
	  return;
	}

      vbox = gtk_vbox_new (FALSE, 1);
207
      gtk_container_set_border_width (GTK_CONTAINER (vbox), 1);
Elliot Lee's avatar
Elliot Lee committed
208 209 210
      gtk_container_add (GTK_CONTAINER (about_dialog), vbox);
      gtk_widget_show (vbox);

211 212
      aboutframe = gtk_frame_new (NULL);
      gtk_frame_set_shadow_type (GTK_FRAME (aboutframe), GTK_SHADOW_IN);
213
      gtk_container_set_border_width (GTK_CONTAINER (aboutframe), 0);
214 215
      gtk_box_pack_start (GTK_BOX (vbox), aboutframe, TRUE, TRUE, 0);
      gtk_widget_show (aboutframe);
Elliot Lee's avatar
Elliot Lee committed
216 217 218 219 220 221

      logo_area = gtk_drawing_area_new ();
      gtk_signal_connect (GTK_OBJECT (logo_area), "expose_event",
			  (GtkSignalFunc) about_dialog_logo_expose, NULL);
      gtk_drawing_area_size (GTK_DRAWING_AREA (logo_area), logo_width, logo_height);
      gtk_widget_set_events (logo_area, GDK_EXPOSURE_MASK);
222
      gtk_container_add (GTK_CONTAINER (aboutframe), logo_area);
Elliot Lee's avatar
Elliot Lee committed
223 224 225 226 227 228
      gtk_widget_show (logo_area);

      gtk_widget_realize (logo_area);
      gdk_window_set_background (logo_area->window, &logo_area->style->black);

      style = gtk_style_new ();
229
      gdk_font_unref (style->font);
Sven Neumann's avatar
Sven Neumann committed
230
      style->font = gdk_font_load ("-Adobe-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*");
Elliot Lee's avatar
Elliot Lee committed
231 232
      gtk_widget_push_style (style);

233 234
      label_text = g_strdup_printf("%s%s%s", _("Version "), GIMP_VERSION,
					     _(" brought to you by"));
235 236
      label = gtk_label_new (label_text);
      g_free(label_text); label_text=NULL;
Elliot Lee's avatar
Elliot Lee committed
237 238 239
      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
      gtk_widget_show (label);

Sven Neumann's avatar
Sven Neumann committed
240
      label = gtk_label_new ("Spencer Kimball & Peter Mattis");
Elliot Lee's avatar
Elliot Lee committed
241 242 243 244 245 246 247 248 249
      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
      gtk_widget_show (label);

      gtk_widget_pop_style ();

      alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
      gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, TRUE, 0);
      gtk_widget_show (alignment);

250 251
      aboutframe = gtk_frame_new (NULL);
      gtk_frame_set_shadow_type (GTK_FRAME (aboutframe), GTK_SHADOW_IN);
252
      gtk_container_set_border_width (GTK_CONTAINER (aboutframe), 0);
253 254
      gtk_container_add (GTK_CONTAINER (alignment), aboutframe);
      gtk_widget_show (aboutframe);
Elliot Lee's avatar
Elliot Lee committed
255 256 257 258

      max_width = 0;
      for (i = 0; i < nscroll_texts; i++)
	{
259
	  scroll_text_widths[i] = gdk_string_width (aboutframe->style->font, scroll_text[i]);
Elliot Lee's avatar
Elliot Lee committed
260 261 262 263 264 265
	  max_width = MAX (max_width, scroll_text_widths[i]);
	}

      scroll_area = gtk_drawing_area_new ();
      gtk_drawing_area_size (GTK_DRAWING_AREA (scroll_area),
			     max_width + 10,
266 267 268 269
			     aboutframe->style->font->ascent +
			     aboutframe->style->font->descent);
      gtk_widget_set_events (scroll_area, GDK_BUTTON_PRESS_MASK);
      gtk_container_add (GTK_CONTAINER (aboutframe), scroll_area);
Elliot Lee's avatar
Elliot Lee committed
270 271
      gtk_widget_show (scroll_area);

272
      label = gtk_label_new (_("Please visit http://www.gimp.org/ for more info"));
273 274 275
      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
      gtk_widget_show (label);

Elliot Lee's avatar
Elliot Lee committed
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
      gtk_widget_realize (scroll_area);
      gdk_window_set_background (scroll_area->window, &scroll_area->style->white);
    }

  if (!GTK_WIDGET_VISIBLE (about_dialog))
    {
      gtk_widget_show (about_dialog);

      do_animation = TRUE;
      do_scrolling = FALSE;
      scroll_state = 0;
      frame = 0;
      offset = 0;

      for (i = 0; i < nscroll_texts; i++) 
	{
	  shuffle_array[i] = i;
	}

      for (i = 0; i < nscroll_texts; i++) 
	{
297
	  int j;
Elliot Lee's avatar
Elliot Lee committed
298
	  j = rand() % nscroll_texts;
299
	  if (i != j) 
Elliot Lee's avatar
Elliot Lee committed
300 301 302
	    {
	      int t;
	      t = shuffle_array[j];
303 304
	      shuffle_array[j] = shuffle_array[i];
	      shuffle_array[i] = t;
Elliot Lee's avatar
Elliot Lee committed
305 306
	    }
	}
307
      cur_scroll_text = rand() % nscroll_texts;
Elliot Lee's avatar
Elliot Lee committed
308 309 310 311 312 313 314 315
    }
  else 
    {
      gdk_window_raise(about_dialog->window);
    }
}


316
static gint
Elliot Lee's avatar
Elliot Lee committed
317 318 319
about_dialog_load_logo (GtkWidget *window)
{
  GtkWidget *preview;
320
  GdkGC *gc;
321 322
  gchar buf[1024];
  guchar *pixelrow;
Elliot Lee's avatar
Elliot Lee committed
323
  FILE *fp;
324 325
  gint count;
  gint i, j, k;
Elliot Lee's avatar
Elliot Lee committed
326 327 328 329

  if (logo_pixmap)
    return TRUE;

Tor Lillqvist's avatar
Tor Lillqvist committed
330 331
  g_snprintf (buf, sizeof(buf), "%s" G_DIR_SEPARATOR_S "gimp_logo.ppm",
	      gimp_data_directory ());
Elliot Lee's avatar
Elliot Lee committed
332

Manish Singh's avatar
Manish Singh committed
333
  fp = fopen (buf, "rb");
Elliot Lee's avatar
Elliot Lee committed
334 335 336 337
  if (!fp)
    return 0;

  fgets (buf, 1024, fp);
338 339

  if (strncmp (buf, "P6", 2) != 0)
Elliot Lee's avatar
Elliot Lee committed
340 341 342 343 344 345 346 347 348 349
    {
      fclose (fp);
      return 0;
    }

  fgets (buf, 1024, fp);
  fgets (buf, 1024, fp);
  sscanf (buf, "%d %d", &logo_width, &logo_height);

  fgets (buf, 1024, fp);
350
  if (strncmp (buf, "255", 3) != 0)
Elliot Lee's avatar
Elliot Lee committed
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374
    {
      fclose (fp);
      return 0;
    }

  preview = gtk_preview_new (GTK_PREVIEW_COLOR);
  gtk_preview_size (GTK_PREVIEW (preview), logo_width, logo_height);
  pixelrow = g_new (guchar, logo_width * 3);

  for (i = 0; i < logo_height; i++)
    {
      count = fread (pixelrow, sizeof (unsigned char), logo_width * 3, fp);
      if (count != (logo_width * 3))
	{
	  gtk_widget_destroy (preview);
	  g_free (pixelrow);
	  fclose (fp);
	  return 0;
	}

      gtk_preview_draw_row (GTK_PREVIEW (preview), pixelrow, 0, i, logo_width);
    }

  gtk_widget_realize (window);
375 376 377
  logo_pixmap = gdk_pixmap_new (window->window, logo_width, logo_height, 
				gtk_preview_get_visual ()->depth);
  gc = gdk_gc_new (logo_pixmap);
Elliot Lee's avatar
Elliot Lee committed
378
  gtk_preview_put (GTK_PREVIEW (preview),
379
		   logo_pixmap, gc,
Elliot Lee's avatar
Elliot Lee committed
380
		   0, 0, 0, 0, logo_width, logo_height);
381
  gdk_gc_destroy (gc);
Elliot Lee's avatar
Elliot Lee committed
382

383
  gtk_widget_unref (preview);
Elliot Lee's avatar
Elliot Lee committed
384 385 386 387
  g_free (pixelrow);

  fclose (fp);

388 389
  dissolve_width = (logo_width / ANIMATION_SIZE)+(logo_width % ANIMATION_SIZE ==0 ?0 : 1);
  dissolve_height = (logo_height / ANIMATION_SIZE)+(logo_height % ANIMATION_SIZE ==0 ?0 : 1);
Elliot Lee's avatar
Elliot Lee committed
390 391 392 393 394 395 396 397 398 399 400 401 402

  dissolve_map = g_new (guchar, dissolve_width * dissolve_height);

  srand (time (NULL));

  for (i = 0, k = 0; i < dissolve_height; i++)
    for (j = 0; j < dissolve_width; j++, k++)
      dissolve_map[k] = rand () % ANIMATION_STEPS;

  return TRUE;
}

static void
Manish Singh's avatar
Manish Singh committed
403
about_dialog_destroy (void)
Elliot Lee's avatar
Elliot Lee committed
404 405 406 407 408 409
{
  about_dialog = NULL;
  about_dialog_unmap ();
}

static void
Manish Singh's avatar
Manish Singh committed
410
about_dialog_unmap (void)
Elliot Lee's avatar
Elliot Lee committed
411 412 413 414 415 416 417 418
{
  if (timer)
    {
      gtk_timeout_remove (timer);
      timer = 0;
    }
}

419
static gint
Elliot Lee's avatar
Elliot Lee committed
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450
about_dialog_logo_expose (GtkWidget      *widget,
			  GdkEventExpose *event)
{
  if (do_animation)
    {
      if (!timer)
	{
	  about_dialog_timer (widget);
	  timer = gtk_timeout_add (75, about_dialog_timer, NULL);
	}
    }
  else
    {
      /* If we draw beyond the boundaries of the pixmap, then X
	 will generate an expose area for those areas, starting
	 an infinite cycle. We now set allow_grow = FALSE, so
	 the drawing area can never be bigger than the preview.
         Otherwise, it would be necessary to intersect event->area
         with the pixmap boundary rectangle. */

      gdk_draw_pixmap (widget->window,
		       widget->style->black_gc,
		       logo_pixmap, 
		       event->area.x, event->area.y,
		       event->area.x, event->area.y,
		       event->area.width, event->area.height);
    }

  return FALSE;
}

451
static gint
Elliot Lee's avatar
Elliot Lee committed
452 453 454 455 456 457 458 459 460 461 462 463 464
about_dialog_button (GtkWidget      *widget,
		     GdkEventButton *event)
{
  if (timer)
    gtk_timeout_remove (timer);
  timer = 0;
  frame = 0;

  gtk_widget_hide (about_dialog);

  return FALSE;
}

465
static gint
Elliot Lee's avatar
Elliot Lee committed
466 467 468 469 470 471 472 473 474
about_dialog_timer (gpointer data)
{
  gint i, j, k;
  gint return_val;

  return_val = TRUE;

  if (do_animation)
    {
475
      if(logo_area->allocation.width != 1)
Elliot Lee's avatar
Elliot Lee committed
476
	{
477 478
	  for (i = 0, k = 0; i < dissolve_height; i++)
	    for (j = 0; j < dissolve_width; j++, k++)
Manish Singh's avatar
Manish Singh committed
479
	      if (frame == dissolve_map[k])
480 481 482 483 484 485 486 487 488 489 490 491 492 493 494
		{
		  gdk_draw_pixmap (logo_area->window,
				   logo_area->style->black_gc,
				   logo_pixmap,
				   j * ANIMATION_SIZE, i * ANIMATION_SIZE, j * ANIMATION_SIZE, i * ANIMATION_SIZE,
				   ANIMATION_SIZE, ANIMATION_SIZE);
		}

	  frame += 1;

	  if (frame == ANIMATION_STEPS)
	    {
	      do_animation = FALSE;
	      do_scrolling = TRUE;
	      frame = 0;
Elliot Lee's avatar
Elliot Lee committed
495

496
	      timer = gtk_timeout_add (75, about_dialog_timer, NULL);
Elliot Lee's avatar
Elliot Lee committed
497

498 499
	      return FALSE;
	    }
Elliot Lee's avatar
Elliot Lee committed
500 501 502 503 504
	}
    }

  if (do_scrolling)
    {
505 506 507 508 509 510 511
      if (!scroll_pixmap)
	scroll_pixmap = gdk_pixmap_new (scroll_area->window,
					scroll_area->allocation.width,
					scroll_area->allocation.height,
					-1);
  

Elliot Lee's avatar
Elliot Lee committed
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567
      switch (scroll_state)
	{
	case 1:
	  scroll_state = 2;
	  timer = gtk_timeout_add (700, about_dialog_timer, NULL);
	  return_val = FALSE;
	  break;
	case 2:
	  scroll_state = 3;
	  timer = gtk_timeout_add (75, about_dialog_timer, NULL);
	  return_val = FALSE;
	  break;
	}

      if (offset > (scroll_text_widths[cur_scroll_text] + scroll_area->allocation.width))
	{
	  scroll_state = 0;
	  cur_scroll_index += 1;
	  if (cur_scroll_index == nscroll_texts)
	    cur_scroll_index = 0;
	  
	  cur_scroll_text = shuffle_array[cur_scroll_index];

	  offset = 0;
	}

      gdk_draw_rectangle (scroll_pixmap,
			  scroll_area->style->white_gc,
			  TRUE, 0, 0,
			  scroll_area->allocation.width,
			  scroll_area->allocation.height);
      gdk_draw_string (scroll_pixmap,
		       scroll_area->style->font,
		       scroll_area->style->black_gc,
		       scroll_area->allocation.width - offset,
		       scroll_area->style->font->ascent,
		       scroll_text[cur_scroll_text]);
      gdk_draw_pixmap (scroll_area->window,
		       scroll_area->style->black_gc,
		       scroll_pixmap, 0, 0, 0, 0,
		       scroll_area->allocation.width,
		       scroll_area->allocation.height);

      offset += 15;
      if (scroll_state == 0)
	{
	  if (offset > ((scroll_area->allocation.width + scroll_text_widths[cur_scroll_text]) / 2))
	    {
	      scroll_state = 1;
	      offset = (scroll_area->allocation.width + scroll_text_widths[cur_scroll_text]) / 2;
	    }
	}
    }

  return return_val;
}