~ubuntu-branches/ubuntu/quantal/xdaliclock/quantal

« back to all changes in this revision

Viewing changes to gtk/digital.c

  • Committer: Bazaar Package Importer
  • Author(s): Kartik Mistry
  • Date: 2010-04-20 08:42:20 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20100420084220-j7ykvh34b2jx7hyv
Tags: 2.31-1
* New maintainer (Closes: #561233)
* New upstream release (Closes: #578379)
* debian/control:
  + Updated to Standards-Version 3.8.4
  + Added ${misc:Depends} to Depends
  + Updated debhelper dependency to 7
* debian/rules:
  + Do not do append to copyright file trick
  + Used dh_prep instead of dh_clean -k
* Converted package to new source format 3.0 (quilt)
* debian/copyright:
  + Added missing vroot.h copyright
  + Better copyright assignment, year for Author
* debian/patches/spelling-error-in-manpage_xdaliclock:
  + Added patch to fix manpage spelling mistake by Florian Ernst
    <florian@debian.org>

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* xdaliclock - a melting digital clock
2
 
 * Copyright (c) 1991-2006 Jamie Zawinski <jwz@jwz.org>
 
2
 * Copyright (c) 1991-2010 Jamie Zawinski <jwz@jwz.org>
3
3
 *
4
4
 * Permission to use, copy, modify, distribute, and sell this software and its
5
5
 * documentation for any purpose is hereby granted without fee, provided that
185
185
 
186
186
#endif /* BUILTIN_FONTS */
187
187
 
188
 
#define SECONDS_ONLY_MODE
189
 
 
190
188
#undef countof
191
189
#define countof(x) (sizeof((x))/sizeof(*(x)))
192
190
 
212
210
/* The runtime settings (some initialized from system prefs, but changable.)
213
211
 */
214
212
struct render_state {
215
 
 
216
 
  enum date_state { DTime, DDateIn, DDate, DDateOut, DDateOut2, DDash, DDash2 }
217
 
    display_date;
218
 
 
219
 
  unsigned int last_time;
220
 
 
 
213
  unsigned int last_secs;
221
214
  int char_width, char_height, colon_width;
222
 
 
223
 
  struct frame *base_frames [12];
224
 
  struct frame *orig_frames [6];
225
 
  struct frame *current_frames [6];
226
 
  struct frame *target_frames [6];
227
 
  struct frame *clear_frame;
228
 
 
229
 
  signed char current_digits [6];
230
 
  signed char target_digits [6];
231
 
  BOOL digits_clean_p [6];     /* "clean" means "not stuck between digits" */
 
215
  struct frame *base_frames [12];       /* all digits */
 
216
  struct frame *orig_frames [8];        /* what was there */
 
217
  struct frame *current_frames [8];     /* current intermediate animation */
 
218
  struct frame *target_frames [8];      /* where we are going */
 
219
  int           target_digits [8];      /* where we are going */
 
220
  struct frame *empty_frame;
 
221
  struct frame *empty_colon;
232
222
};
233
223
 
234
224
 
235
225
static struct frame *
236
 
make_blank_frame (int width, int height)
 
226
make_empty_frame (int width, int height)
237
227
{
238
 
  int size = sizeof (struct frame) + (sizeof (struct scanline) * (height - 1));
 
228
  int size = sizeof (struct frame) + (sizeof (struct scanline) * height);
239
229
  struct frame *frame;
240
230
  int x, y;
241
231
 
248
238
 
249
239
 
250
240
static struct frame *
 
241
copy_frame (dali_config *c, struct frame *from)
 
242
{
 
243
  struct render_state *state = c->render_state;
 
244
  int height = state->char_height;
 
245
  int size = sizeof (struct frame) + (sizeof (struct scanline) * height);
 
246
  struct frame *to = (struct frame *) calloc (size, 1);
 
247
  int y;
 
248
  for (y = 0; y < height; y++)
 
249
    to->scanlines[y] = from->scanlines[y];  /* copies the whole struct */
 
250
  return to;
 
251
}
 
252
 
 
253
 
 
254
static struct frame *
251
255
number_to_frame (const unsigned char *bits, int width, int height)
252
256
{
253
257
  int x, y;
254
258
  struct frame *frame;
255
259
  POS *left, *right;
256
260
 
257
 
  frame = make_blank_frame (width, height);
 
261
  frame = make_empty_frame (width, height);
258
262
 
259
263
  for (y = 0; y < height; y++)
260
264
    {
284
288
      for (; x < width; x++)
285
289
        if (GETBIT (bits, x, y))
286
290
          {
287
 
            /* This means the font is too curvy.  Increase MAX_SEGS_PER_LINE
288
 
               and recompile. */
289
291
            fprintf (stderr, "%s: font is too curvy\n", progname);
 
292
            /* Increase MAX_SEGS_PER_LINE and recompile. */
290
293
            exit (-1);
291
294
          }
292
295
 
309
312
}
310
313
 
311
314
 
312
 
static void
313
 
copy_frame (dali_config *c, struct frame *from, struct frame *to)
314
 
{
315
 
  struct render_state *state = c->render_state;
316
 
  int y;
317
 
  for (y = 0; y < state->char_height; y++)
318
 
    to->scanlines[y] = from->scanlines[y];  /* copies the whole struct */
319
 
}
320
 
 
321
 
 
322
 
static BOOL
323
 
frame_equal (dali_config *c, struct frame *a, struct frame *b)
324
 
{
325
 
  struct render_state *state = c->render_state;
326
 
  int y;
327
 
  for (y = 0; y < state->char_height; y++)
328
 
    /* compare the whole scanline struct at once */
329
 
    if (memcmp (a->scanlines, b->scanlines, sizeof(b->scanlines)))
330
 
      return 0;
331
 
  return 1;
332
 
}
333
 
 
334
 
 
335
315
static int
336
316
pick_font_size (dali_config *c, unsigned int *w_ret, unsigned int *h_ret)
337
317
{
374
354
      f = 0;
375
355
    }
376
356
 
 
357
  w += 2;  /* Leave a single pixel margin in the overall bitmap */
 
358
  h += 2;
 
359
 
377
360
  w = ((w + 7) / 8) * 8;  /* round up to byte */
378
361
 
379
362
#else  /* !BUILTIN_FONTS */
409
392
  state->char_height = raw[0].height;
410
393
  state->colon_width = raw[10].width;
411
394
 
 
395
  state->empty_frame = make_empty_frame (raw[0].width,  raw[0].height);
 
396
  state->empty_colon = make_empty_frame (raw[10].width, raw[10].height);
 
397
 
412
398
  for (i = 0; i < countof(state->base_frames); i++)
413
399
    state->base_frames [i] =
414
400
      number_to_frame (raw[i].bits, raw[i].width, raw[i].height);
415
401
#endif /* BUILTIN_FONTS */
416
402
 
417
 
  for (i = 0; i < countof(state->orig_frames); i++)
418
 
    state->orig_frames [i] =
419
 
      make_blank_frame (state->char_width, state->char_height);
420
 
 
421
 
  for (i = 0; i < countof(state->current_frames); i++)
422
 
    state->current_frames [i] =
423
 
      make_blank_frame (state->char_width, state->char_height);
424
 
 
425
 
  for (i = 0; i < countof(state->target_frames); i++)
426
 
    state->target_frames [i] =
427
 
      make_blank_frame (state->char_width, state->char_height);
428
 
 
429
 
  state->clear_frame = make_blank_frame (state->char_width,
430
 
                                         state->char_height);
 
403
  memset (state->orig_frames,    0, sizeof(state->orig_frames));
 
404
  memset (state->current_frames, 0, sizeof(state->current_frames));
 
405
  memset (state->target_frames,  0, sizeof(state->target_frames));
 
406
 
 
407
  for (i = 0; i < countof(state->current_frames); i++) {
 
408
    int colonic_p = (i == 2 || i == 5);
 
409
    int cw = raw[colonic_p ? 10 : 0].width;
 
410
    int ch = raw[0].height;
 
411
    state->orig_frames[i]    = make_empty_frame (cw, ch);
 
412
    state->current_frames[i] = make_empty_frame (cw, ch);
 
413
    state->target_frames[i]  = make_empty_frame (cw, ch);
 
414
  }
431
415
 
432
416
  for (i = 0; i < countof(state->target_digits); i++)
433
 
    state->target_digits[i] = state->current_digits[i] = -1;
434
 
 
435
 
  memset (state->digits_clean_p, 0, sizeof(state->digits_clean_p));
 
417
    state->target_digits[i] = -1;
436
418
 
437
419
  memset (c->bitmap, 0, c->height * (c->width >> 3));
438
420
}
451
433
  FREELOOP (state->orig_frames);
452
434
  FREELOOP (state->current_frames);
453
435
  FREELOOP (state->target_frames);
454
 
  FREEIF (state->clear_frame);
 
436
  FREEIF (state->empty_frame);
 
437
  FREEIF (state->empty_colon);
455
438
 
456
439
# undef FREELOOP
457
440
# undef FREEIF
464
447
  struct render_state *state = c->render_state;
465
448
  struct tm *tm = localtime ((time_t *) &time);
466
449
 
 
450
  int i;
 
451
  int h = tm->tm_hour;
 
452
  int m = tm->tm_min;
 
453
  int s = tm->tm_sec;
 
454
  int D = tm->tm_mday;
 
455
  int M = tm->tm_mon;
 
456
  int Y = tm->tm_year % 100;
 
457
 
 
458
  int twelve_p = c->twelve_hour_p;
 
459
 
 
460
  if (c->countdown)
 
461
    {
 
462
      long delta = ((unsigned long) c->countdown) - time;
 
463
      if (delta < 0) delta = -delta;
 
464
      s = delta % 60;
 
465
      m = (delta / 60) % 60;
 
466
      h = (delta / (60 * 60)) % 100;
 
467
      twelve_p = 0;
 
468
    }
 
469
 
 
470
  if (twelve_p) 
 
471
    {
 
472
      if (h > 12) { h -= 12; }
 
473
      else if (h == 0) { h = 12; }
 
474
    }
 
475
 
 
476
  for (i = 0; i < countof(state->target_digits); i++)
 
477
    state->target_digits[i] = -1;
 
478
 
467
479
  if (c->test_hack)
468
480
    {
469
481
      state->target_digits [0] =
475
487
                                    : c->test_hack - '0');
476
488
      c->test_hack = 0;
477
489
    }
478
 
  else if (state->display_date == DTime ||
479
 
           state->display_date == DDash ||
480
 
           state->display_date == DDash2)
 
490
  else if (!c->display_date_p)
481
491
    {
482
 
      BOOL twelve_hour_time_p = c->twelve_hour_p;
483
 
 
484
 
      if (state->display_date == DDash)
485
 
        state->display_date = DDash2;
486
 
      else if (state->display_date == DDash2)
487
 
        state->display_date = DTime;
488
 
 
489
 
      if (c->countdown)
 
492
      switch (c->time_mode)
490
493
        {
491
 
          long delta = ((unsigned long) c->countdown) - time;
492
 
          if (delta < 0) delta = -delta;
493
 
          tm->tm_sec = delta % 60;
494
 
          tm->tm_min = (delta / 60) % 60;
495
 
          tm->tm_hour = (delta / (60 * 60)) % 100;
496
 
          twelve_hour_time_p = 0;
 
494
        case SS:
 
495
          state->target_digits[0] = (s / 10);
 
496
          state->target_digits[1] = (s % 10);
 
497
          break;
 
498
        case HHMM:
 
499
          state->target_digits[0] = (h / 10);
 
500
          state->target_digits[1] = (h % 10);
 
501
          state->target_digits[2] = 10;         /* colon */
 
502
          state->target_digits[3] = (m / 10);
 
503
          state->target_digits[4] = (m % 10);
 
504
          if (twelve_p && state->target_digits[0] == 0)
 
505
            state->target_digits[0] = -1;
 
506
          break;
 
507
        case HHMMSS:
 
508
          state->target_digits[0] = (h / 10);
 
509
          state->target_digits[1] = (h % 10);
 
510
          state->target_digits[2] = 10;         /* colon */
 
511
          state->target_digits[3] = (m / 10);
 
512
          state->target_digits[4] = (m % 10);
 
513
          state->target_digits[5] = 10;         /* colon */
 
514
          state->target_digits[6] = (s / 10);
 
515
          state->target_digits[7] = (s % 10);
 
516
          if (twelve_p && state->target_digits[0] == 0)
 
517
            state->target_digits[0] = -1;
 
518
          break;
 
519
        default: 
 
520
          abort();
497
521
        }
498
 
      if (twelve_hour_time_p && tm->tm_hour > 12) tm->tm_hour -= 12;
499
 
      if (twelve_hour_time_p && tm->tm_hour == 0) tm->tm_hour = 12;
500
 
      state->target_digits [0] = (tm->tm_hour - (tm->tm_hour % 10)) / 10;
501
 
      state->target_digits [1] = tm->tm_hour % 10;
502
 
      state->target_digits [2] = (tm->tm_min - (tm->tm_min % 10)) / 10;
503
 
      state->target_digits [3] = tm->tm_min % 10;
504
 
      state->target_digits [4] = (tm->tm_sec - (tm->tm_sec % 10)) / 10;
505
 
      state->target_digits [5] = tm->tm_sec % 10;
506
 
 
507
 
      if (twelve_hour_time_p && state->target_digits [0] == 0)
508
 
        state->target_digits [0] = -1;
509
522
    }
510
 
  else
 
523
  else  /* date mode */
511
524
    {
512
 
      int m0,m1,d0,d1,y0,y1;
513
 
      tm->tm_mon++; /* 0 based */
514
 
      m0 = (tm->tm_mon - (tm->tm_mon % 10)) / 10;
515
 
      m1 = tm->tm_mon % 10;
516
 
      d0 = (tm->tm_mday - (tm->tm_mday % 10)) / 10;
517
 
      d1 = tm->tm_mday % 10;
518
 
      y0 = tm->tm_year % 100;
519
 
      y0 = (y0 - (y0 % 10)) / 10;
520
 
      y1 = tm->tm_year % 10;
521
 
 
522
 
      if (state->display_date == DDateIn)
523
 
        state->display_date = DDate;
524
 
      if (state->display_date == DDateOut)
525
 
        state->display_date = DDateOut2;
526
 
      else if (state->display_date == DDateOut2)
527
 
        state->display_date = DDash;
528
 
      else if (state->display_date == DDash)
529
 
        state->display_date = DDash2;
530
 
 
531
 
      switch (c->date_mode)
 
525
      switch (c->date_mode) 
532
526
        {
533
527
        case MMDDYY:
534
 
          switch (c->time_mode)
535
 
            {
536
 
            case HHMMSS:
537
 
            case HHMM:
538
 
              state->target_digits [0] = m0; state->target_digits [1] = m1;
539
 
              state->target_digits [2] = d0; state->target_digits [3] = d1;
540
 
              state->target_digits [4] = y0; state->target_digits [5] = y1;
541
 
              break;
542
 
            case SS:
543
 
              state->target_digits [4] = d0; state->target_digits [5] = d1;
544
 
              break;
545
 
            default:
546
 
              abort();
547
 
            }
 
528
          switch (c->time_mode) {
 
529
          case SS:
 
530
            state->target_digits[0] = (D / 10);
 
531
            state->target_digits[1] = (D % 10);
 
532
            break;
 
533
          case HHMM:
 
534
            state->target_digits[0] = (M / 10);
 
535
            state->target_digits[1] = (M % 10);
 
536
            state->target_digits[2] = 11;               /* dash */
 
537
            state->target_digits[3] = (D / 10);
 
538
            state->target_digits[4] = (D % 10);
 
539
            break;
 
540
          case HHMMSS:
 
541
            state->target_digits[0] = (M / 10);
 
542
            state->target_digits[1] = (M % 10);
 
543
            state->target_digits[2] = 11;               /* dash */
 
544
            state->target_digits[3] = (D / 10);
 
545
            state->target_digits[4] = (D % 10);
 
546
            state->target_digits[5] = 11;               /* dash */
 
547
            state->target_digits[6] = (Y / 10);
 
548
            state->target_digits[7] = (Y % 10);
 
549
            break;
 
550
          default:
 
551
            abort();
 
552
          }
548
553
          break;
549
554
        case DDMMYY:
550
 
          switch (c->time_mode)
551
 
            {
552
 
            case HHMMSS:
553
 
            case HHMM:
554
 
              state->target_digits [0] = d0; state->target_digits [1] = d1;
555
 
              state->target_digits [2] = m0; state->target_digits [3] = m1;
556
 
              state->target_digits [4] = y0; state->target_digits [5] = y1;
557
 
              break;
558
 
            case SS:
559
 
              state->target_digits [4] = d0; state->target_digits [5] = d1;
560
 
              break;
561
 
            default:
562
 
              abort();
563
 
            }
 
555
          switch (c->time_mode) {
 
556
          case SS:
 
557
            state->target_digits[0] = (D / 10);
 
558
            state->target_digits[1] = (D % 10);
 
559
            break;
 
560
          case HHMM:
 
561
            state->target_digits[0] = (D / 10);
 
562
            state->target_digits[1] = (D % 10);
 
563
            state->target_digits[2] = 11;               /* dash */
 
564
            state->target_digits[3] = (M / 10);
 
565
            state->target_digits[4] = (M % 10);
 
566
            break;
 
567
          case HHMMSS:
 
568
            state->target_digits[0] = (D / 10);
 
569
            state->target_digits[1] = (D % 10);
 
570
            state->target_digits[2] = 11;               /* dash */
 
571
            state->target_digits[3] = (M / 10);
 
572
            state->target_digits[4] = (M % 10);
 
573
            state->target_digits[5] = 11;               /* dash */
 
574
            state->target_digits[6] = (Y / 10);
 
575
            state->target_digits[7] = (Y % 10);
 
576
            break;
 
577
          default:
 
578
            abort();
 
579
          }
564
580
          break;
565
581
        case YYMMDD:
566
 
          switch (c->time_mode)
567
 
            {
568
 
            case HHMMSS:
569
 
            case SS:
570
 
              state->target_digits [0] = y0; state->target_digits [1] = y1;
571
 
              state->target_digits [2] = m0; state->target_digits [3] = m1;
572
 
              state->target_digits [4] = d0; state->target_digits [5] = d1;
573
 
              break;
574
 
            case HHMM:
575
 
              state->target_digits [0] = m0; state->target_digits [1] = m1;
576
 
              state->target_digits [2] = d0; state->target_digits [3] = d1;
577
 
              break;
578
 
            default:
579
 
              abort();
580
 
            }
581
 
          break;              
 
582
          switch (c->time_mode) {
 
583
          case SS:
 
584
            state->target_digits[0] = (D / 10);
 
585
            state->target_digits[1] = (D % 10);
 
586
            break;
 
587
          case HHMM:
 
588
            state->target_digits[0] = (M / 10);
 
589
            state->target_digits[1] = (M % 10);
 
590
            state->target_digits[2] = 11;               /* dash */
 
591
            state->target_digits[3] = (D / 10);
 
592
            state->target_digits[4] = (D % 10);
 
593
            break;
 
594
          case HHMMSS:
 
595
            state->target_digits[0] = (Y / 10);
 
596
            state->target_digits[1] = (Y % 10);
 
597
            state->target_digits[2] = 11;               /* dash */
 
598
            state->target_digits[3] = (M / 10);
 
599
            state->target_digits[4] = (M % 10);
 
600
            state->target_digits[5] = 11;               /* dash */
 
601
            state->target_digits[6] = (D / 10);
 
602
            state->target_digits[7] = (D % 10);
 
603
            break;
 
604
          default:
 
605
            abort();
 
606
          }
 
607
          break;
582
608
        default:
583
609
          abort();
584
 
          break;
585
610
        }
586
611
    }
587
612
}
624
649
}
625
650
 
626
651
 
627
 
static void
 
652
static int
628
653
draw_frame (dali_config *c, struct frame *frame, int x, int y, int colonic_p)
629
654
{
630
655
  struct render_state *state = c->render_state;
671
696
                            y + py,
672
697
                            0);
673
698
    }
 
699
  return cw;
674
700
}
675
701
 
676
702
 
682
708
  struct render_state *state = c->render_state;
683
709
  int i;
684
710
 
685
 
  /* Copy the (old) current_frames into the (new) orig_frames,
686
 
     since that's what's on the screen now. */
 
711
  /* Move the (old) current_frames into the (new) orig_frames,
 
712
     since that's what's on the screen now. 
 
713
     Frames are freed as they expire out of orig_frames.
 
714
   */
687
715
  for (i = 0; i < countof (state->current_frames); i++)
688
 
    copy_frame (c, state->current_frames[i], state->orig_frames[i]);
689
 
 
690
 
  /* likewise with the (old) current_digits */
691
 
  memcpy (state->current_digits, state->target_digits,
692
 
          sizeof (state->target_digits));
 
716
    {
 
717
      if (state->orig_frames[i]) 
 
718
        free (state->orig_frames[i]);
 
719
      state->orig_frames[i]    = state->current_frames[i];
 
720
      state->current_frames[i] = state->target_frames[i];
 
721
      state->target_frames[i]  = 0;
 
722
    }
693
723
 
694
724
  /* generate new target_digits */
695
725
  fill_target_digits (c, time);
697
727
  /* Fill the (new) target_frames from the (new) target_digits. */
698
728
  for (i = 0; i < countof (state->target_frames); i++)
699
729
    {
700
 
      int j = state->target_digits[i];
701
 
      struct frame *to = state->target_frames[i];
702
 
      struct frame *from = (j < 0 
703
 
                            ? state->clear_frame
704
 
                            : state->base_frames [j]);
705
 
      copy_frame (c, from, to);
706
 
      
707
 
      /* This digit is "clean" if what is currently on screen is exactly
708
 
         equal to the rest-state digit (not in some half-animated inbetween
709
 
         state, as it might be if the wall clock moved from 4.8 seconds
710
 
         directly to 5.2 seconds without stopping closer to 5.0.) */
711
 
      state->digits_clean_p[i] = frame_equal (c, to, state->current_frames[i]);
 
730
      int colonic_p = (i == 2 || i == 5);
 
731
      state->target_frames[i] =
 
732
        copy_frame (c,
 
733
                    (state->target_digits[i] == -1
 
734
                     ? (colonic_p ? state->empty_colon : state->empty_frame)
 
735
                     : state->base_frames[state->target_digits[i]]));
712
736
    }
713
737
 
714
738
  /* Render the current frame. */
750
774
 
751
775
 
752
776
static void
753
 
tick_sequence (dali_config *c, unsigned long time, unsigned long msecs)
 
777
tick_sequence (dali_config *c)
754
778
{
755
779
  struct render_state *state = c->render_state;
756
780
  int i;
757
781
 
758
 
  if (time != state->last_time)
 
782
  struct timeval now;
 
783
  struct timezone tzp;
 
784
  gettimeofday (&now, &tzp);
 
785
  unsigned long secs = now.tv_sec;
 
786
  unsigned long msecs = now.tv_usec / 1000;
 
787
 
 
788
  if (!state->last_secs)
 
789
    state->last_secs = secs;   /* fading in! */
 
790
  else if (secs != state->last_secs) 
759
791
    {
760
792
      /* End of the animation sequence; fill target_frames with the
761
793
         digits of the current time. */
762
 
      start_sequence (c, time);
763
 
      state->last_time = time;
764
 
/*      return; #### */
 
794
      start_sequence (c, secs);
 
795
      state->last_secs = secs;
765
796
    }
766
797
 
767
798
  /* Linger for about 1/10th second at the end of each cycle. */
771
802
  /* Construct current_frames by interpolating between
772
803
     orig_frames and target_frames. */
773
804
  for (i = 0; i < countof (state->current_frames); i++)
774
 
    /* We can skip animating this frame if:
775
 
       - the old and new digit are the same (no motion desired); and
776
 
       - what is on the screen is a rest-state of that digit (not an
777
 
         intermediate frame of the last animation that didn't fully
778
 
         complete). */
779
 
    if (state->target_digits[i] != state->current_digits[i] ||
780
 
        !state->digits_clean_p[i])
781
 
      {
782
 
        one_step (c,
783
 
                  state->orig_frames[i],
784
 
                  state->current_frames[i],
785
 
                  state->target_frames[i],
786
 
                  msecs);
787
 
        state->digits_clean_p[i] = 0; /* we just animated; no longer clean */
788
 
      }
789
 
 
 
805
    one_step (c,
 
806
              state->orig_frames[i],
 
807
              state->current_frames[i],
 
808
              state->target_frames[i],
 
809
              msecs);
790
810
}
791
811
 
792
812
 
794
814
draw_clock (dali_config *c, BOOL colonic_p)
795
815
{
796
816
  struct render_state *state = c->render_state;
797
 
  int x, y;
798
 
  int width = c->width;
799
 
  int height = c->height;
800
 
  int nn, cc;
801
 
 
802
 
  switch (c->time_mode)
803
 
    {
804
 
    case SS:     nn = 2, cc = 0; break;
805
 
    case HHMM:   nn = 4, cc = 1; break;
806
 
    case HHMMSS: nn = 6, cc = 2; break;
807
 
    default:   abort(); break;
808
 
    }
809
 
 
810
 
  x = (width - ((state->char_width * nn) +
811
 
                (state->colon_width * cc))) / 2;
812
 
  y = (height - state->char_height) / 2;
813
 
 
814
 
/* As above: 
815
 
    We can skip rendering this frame if:
816
 
    - the old and new digit are the same (no motion desired); and
817
 
    - what is on the screen is a rest-state of that digit (not an
818
 
      intermediate frame of the last animation that didn't fully
819
 
      complete). */
820
 
# define DIGIT(n) \
821
 
   if (state->target_digits[n] != state->current_digits[n] || \
822
 
      !state->digits_clean_p[n]) \
823
 
     draw_frame (c, state->current_frames [n], x, y, 0); \
824
 
  x += state->char_width
825
 
 
826
 
# define COLON() \
827
 
  if (colonic_p) \
828
 
    draw_frame (c, state->base_frames \
829
 
                         [state->display_date == DTime ? 10 : 11], \
830
 
                x, y, 1); \
831
 
  x += state->colon_width
832
 
 
833
 
  switch (c->time_mode)
834
 
    {
835
 
    case SS:
836
 
      DIGIT(4);
837
 
      DIGIT(5);
838
 
      break;
839
 
    case HHMM:
840
 
      DIGIT(0);
841
 
      DIGIT(1);
842
 
      COLON();
843
 
      DIGIT(2);
844
 
      DIGIT(3);
845
 
      break;
846
 
    case HHMMSS:
847
 
      DIGIT(0);
848
 
      DIGIT(1);
849
 
      COLON();
850
 
      DIGIT(2);
851
 
      DIGIT(3);
852
 
      COLON();
853
 
      DIGIT(4);
854
 
      DIGIT(5);
855
 
      break;
856
 
    default:
857
 
      abort();
858
 
      break;
859
 
    }
860
 
# undef COLON
861
 
# undef DIGIT
 
817
  int i;
 
818
  int x = 0, y = 0;
 
819
  int displayed_digits;
 
820
 
 
821
  switch (c->time_mode)
 
822
    {
 
823
    case SS:     displayed_digits = 2; break;
 
824
    case HHMM:   displayed_digits = 6; break;
 
825
    case HHMMSS: displayed_digits = 8; break;
 
826
    default:     abort(); break;
 
827
    }
 
828
 
 
829
  for (i = 0; i < displayed_digits; i++) 
 
830
    {
 
831
      int colonic_p = (i == 2 || i == 5);
 
832
      x += draw_frame (c, state->current_frames[i], x, y, colonic_p);
 
833
    }
862
834
}
863
835
 
864
836
 
868
840
  if (c->render_state) abort();
869
841
  c->render_state = (struct render_state *)
870
842
    calloc (1, sizeof (struct render_state));
871
 
  c->render_state->display_date = DTime;
872
843
  init_numbers (c);
873
844
}
874
845
 
882
853
}
883
854
 
884
855
void
885
 
render_once (dali_config *c, unsigned long time, unsigned long usecs)
 
856
render_once (dali_config *c)
886
857
{
887
 
  struct render_state *state = c->render_state;
888
 
 
889
 
  if (c->display_date_p && state->display_date == DTime)
890
 
    state->display_date = DDateIn;
891
 
  else if (!c->display_date_p && state->display_date == DDate)
892
 
    state->display_date = DDateOut;
893
 
 
894
858
  if (! c->render_state) abort();
895
859
  if (! c->bitmap) abort();
896
 
  tick_sequence (c, time, (usecs / 1000));
 
860
  tick_sequence (c);
897
861
  draw_clock (c, 0);
898
862
}
899
863