http://slackware.bholcomb.com/slackware/slackware-11.0/source/xap/xscreensaver/xscree...
[xscreensaver] / hacks / analogtv.c
index 3bd9d46085aebdaab049663aa24b5be075a33034..c7fb266de3214568dc2f52fe08370cf26392c4b1 100644 (file)
   Trevor Blackwell <tlb@tlb.org>
 */
 
   Trevor Blackwell <tlb@tlb.org>
 */
 
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Intrinsic.h>
+#ifdef HAVE_COCOA
+# include "jwxyz.h"
+#else /* !HAVE_COCOA */
+# include <X11/Xlib.h>
+# include <X11/Xutil.h>
+#endif
+
 #include <assert.h>
 #include "utils.h"
 #include "resources.h"
 #include <assert.h>
 #include "utils.h"
 #include "resources.h"
@@ -174,13 +178,13 @@ analogtv_set_defaults(analogtv *it, char *prefix)
   char buf[256];
 
   sprintf(buf,"%sTVTint",prefix);
   char buf[256];
 
   sprintf(buf,"%sTVTint",prefix);
-  it->tint_control = get_float_resource(buf,"TVTint");
+  it->tint_control = get_float_resource(it->dpy, buf,"TVTint");
   sprintf(buf,"%sTVColor",prefix);
   sprintf(buf,"%sTVColor",prefix);
-  it->color_control = get_float_resource(buf,"TVColor")/100.0;
+  it->color_control = get_float_resource(it->dpy, buf,"TVColor")/100.0;
   sprintf(buf,"%sTVBrightness",prefix);
   sprintf(buf,"%sTVBrightness",prefix);
-  it->brightness_control = get_float_resource(buf,"TVBrightness") / 100.0;
+  it->brightness_control = get_float_resource(it->dpy, buf,"TVBrightness") / 100.0;
   sprintf(buf,"%sTVContrast",prefix);
   sprintf(buf,"%sTVContrast",prefix);
-  it->contrast_control = get_float_resource(buf,"TVContrast") / 100.0;
+  it->contrast_control = get_float_resource(it->dpy, buf,"TVContrast") / 100.0;
   it->height_control = 1.0;
   it->width_control = 1.0;
   it->squish_control = 0.0;
   it->height_control = 1.0;
   it->width_control = 1.0;
   it->squish_control = 0.0;
@@ -236,7 +240,7 @@ analogtv_set_defaults(analogtv *it, char *prefix)
 
 extern Bool mono_p; /* shoot me */
 
 
 extern Bool mono_p; /* shoot me */
 
-void
+static void
 analogtv_free_image(analogtv *it)
 {
   if (it->image) {
 analogtv_free_image(analogtv *it)
 {
   if (it->image) {
@@ -251,7 +255,7 @@ analogtv_free_image(analogtv *it)
   }
 }
 
   }
 }
 
-void
+static void
 analogtv_alloc_image(analogtv *it)
 {
   if (it->use_shm) {
 analogtv_alloc_image(analogtv *it)
 {
   if (it->use_shm) {
@@ -270,7 +274,7 @@ analogtv_alloc_image(analogtv *it)
 }
 
 
 }
 
 
-void
+static void
 analogtv_configure(analogtv *it)
 {
   int oldwidth=it->usewidth;
 analogtv_configure(analogtv *it)
 {
   int oldwidth=it->usewidth;
@@ -280,7 +284,7 @@ analogtv_configure(analogtv *it)
   /* If the window is very small, don't let the image we draw get lower
      than the actual TV resolution (266x200.)
 
   /* If the window is very small, don't let the image we draw get lower
      than the actual TV resolution (266x200.)
 
-     If the aspect ratio of the window is within 20% of a 4:3 ratio,
+     If the aspect ratio of the window is within 15% of a 4:3 ratio,
      then scale the image to exactly fill the window.
 
      Otherwise, center the image either horizontally or vertically,
      then scale the image to exactly fill the window.
 
      Otherwise, center the image either horizontally or vertically,
@@ -289,7 +293,8 @@ analogtv_configure(analogtv *it)
      If it's very close (2.5%) to a multiple of VISLINES, make it exact
      For example, it maps 1024 => 1000.
    */
      If it's very close (2.5%) to a multiple of VISLINES, make it exact
      For example, it maps 1024 => 1000.
    */
-  float percent = 0.20;
+  float percent = 0.15;  /* jwz: 20% caused severe top/bottom clipping
+                                 in Pong on 1680x1050 iMac screen. */
   float min_ratio = 4.0 / 3.0 * (1 - percent);
   float max_ratio = 4.0 / 3.0 * (1 + percent);
   float ratio;
   float min_ratio = 4.0 / 3.0 * (1 - percent);
   float max_ratio = 4.0 / 3.0 * (1 + percent);
   float ratio;
@@ -404,7 +409,7 @@ analogtv_allocate(Display *dpy, Window window)
   it->visbits=it->xgwa.visual->bits_per_rgb;
   it->visdepth=it->xgwa.depth;
   if (it->visclass == TrueColor || it->visclass == DirectColor) {
   it->visbits=it->xgwa.visual->bits_per_rgb;
   it->visdepth=it->xgwa.depth;
   if (it->visclass == TrueColor || it->visclass == DirectColor) {
-    if (get_integer_resource ("use_cmap", "Integer")) {
+    if (get_integer_resource (it->dpy, "use_cmap", "Integer")) {
       it->use_cmap=1;
     } else {
       it->use_cmap=0;
       it->use_cmap=1;
     } else {
       it->use_cmap=0;
@@ -430,7 +435,7 @@ analogtv_allocate(Display *dpy, Window window)
     /* Is there a standard way to do this? Does this handle all cases? */
     int shift, prec;
     for (shift=0; shift<32; shift++) {
     /* Is there a standard way to do this? Does this handle all cases? */
     int shift, prec;
     for (shift=0; shift<32; shift++) {
-      for (prec=1; prec<16 && prec<32-shift; prec++) {
+      for (prec=1; prec<16 && prec<40-shift; prec++) {
         unsigned long mask=(0xffffUL>>(16-prec)) << shift;
         if (it->red_shift<0 && mask==it->red_mask)
           it->red_shift=shift, it->red_invprec=16-prec;
         unsigned long mask=(0xffffUL>>(16-prec)) << shift;
         if (it->red_shift<0 && mask==it->red_mask)
           it->red_shift=shift, it->red_invprec=16-prec;
@@ -455,8 +460,8 @@ analogtv_allocate(Display *dpy, Window window)
 
   }
 
 
   }
 
-  gcv.background=get_pixel_resource("background", "Background",
-                                    it->dpy, it->colormap);
+  gcv.background=get_pixel_resource(it->dpy, it->colormap,
+                                    "background", "Background");
 
   it->gc = XCreateGC(it->dpy, it->window, GCBackground, &gcv);
   XSetWindowBackground(it->dpy, it->window, gcv.background);
 
   it->gc = XCreateGC(it->dpy, it->window, GCBackground, &gcv);
   XSetWindowBackground(it->dpy, it->window, gcv.background);
@@ -882,7 +887,7 @@ analogtv_setup_sync(analogtv_input *input, int do_cb, int do_ssavi)
   }
 }
 
   }
 }
 
-void
+static void
 analogtv_sync(analogtv *it)
 {
   int cur_hsync=it->cur_hsync;
 analogtv_sync(analogtv *it)
 {
   int cur_hsync=it->cur_hsync;
@@ -972,7 +977,7 @@ analogtv_sync(analogtv *it)
 static double
 analogtv_levelmult(analogtv *it, int level)
 {
 static double
 analogtv_levelmult(analogtv *it, int level)
 {
-  static double levelfac[3]={-7.5, 5.5, 24.5};
+  static const double levelfac[3]={-7.5, 5.5, 24.5};
   return (40.0 + levelfac[level]*puramp(it, 3.0, 6.0, 1.0))/256.0;
 }
 
   return (40.0 + levelfac[level]*puramp(it, 3.0, 6.0, 1.0))/256.0;
 }
 
@@ -1000,46 +1005,40 @@ analogtv_level(analogtv *it, int y, int ytop, int ybot)
 }
 
 /*
 }
 
 /*
-
   The point of this stuff is to ensure that when useheight is not a
   multiple of VISLINES so that TV scan lines map to different numbers
   of vertical screen pixels, the total brightness of each scan line
   remains the same.
   The point of this stuff is to ensure that when useheight is not a
   multiple of VISLINES so that TV scan lines map to different numbers
   of vertical screen pixels, the total brightness of each scan line
   remains the same.
-  MAX_LINEHEIGHT corresponds to 2400 vertical pixels, beyond which
+  ANALOGTV_MAX_LINEHEIGHT corresponds to 2400 vertical pixels, beyond which
   it interpolates extra black lines.
  */
   it interpolates extra black lines.
  */
-enum {MAX_LINEHEIGHT=12};
-static struct {
-  int index;
-  double value;
-} leveltable[MAX_LINEHEIGHT+1][MAX_LINEHEIGHT+1];
 
 static void
 analogtv_setup_levels(analogtv *it, double avgheight)
 {
   int i,height;
 
 static void
 analogtv_setup_levels(analogtv *it, double avgheight)
 {
   int i,height;
-  static double levelfac[3]={-7.5, 5.5, 24.5};
+  static const double levelfac[3]={-7.5, 5.5, 24.5};
 
 
-  for (height=0; height<avgheight+2.0 && height<=MAX_LINEHEIGHT; height++) {
+  for (height=0; height<avgheight+2.0 && height<=ANALOGTV_MAX_LINEHEIGHT; height++) {
 
     for (i=0; i<height; i++) {
 
     for (i=0; i<height; i++) {
-      leveltable[height][i].index = 2;
+      it->leveltable[height][i].index = 2;
     }
     
     if (avgheight>=3) {
     }
     
     if (avgheight>=3) {
-      leveltable[height][0].index=0;
+      it->leveltable[height][0].index=0;
     }
     if (avgheight>=5) {
     }
     if (avgheight>=5) {
-      leveltable[height][height-1].index=0;
+      it->leveltable[height][height-1].index=0;
     }
     if (avgheight>=7) {
     }
     if (avgheight>=7) {
-      leveltable[height][1].index=1;
-      leveltable[height][height-2].index=1;
+      it->leveltable[height][1].index=1;
+      it->leveltable[height][height-2].index=1;
     }
 
     for (i=0; i<height; i++) {
     }
 
     for (i=0; i<height; i++) {
-      leveltable[height][i].value = 
-        (40.0 + levelfac[leveltable[height][i].index]*puramp(it, 3.0, 6.0, 1.0)) / 256.0;
+      it->leveltable[height][i].value = 
+        (40.0 + levelfac[it->leveltable[height][i].index]*puramp(it, 3.0, 6.0, 1.0)) / 256.0;
     }
 
   }
     }
 
   }
@@ -1057,8 +1056,8 @@ analogtv_blast_imagerow(analogtv *it,
   for (i=0; i<3; i++) level_copyfrom[i]=NULL;
 
   for (y=ytop; y<ybot; y++) {
   for (i=0; i<3; i++) level_copyfrom[i]=NULL;
 
   for (y=ytop; y<ybot; y++) {
-    int level=leveltable[ybot-ytop][y-ytop].index;
-    double levelmult=leveltable[ybot-ytop][y-ytop].value;
+    int level=it->leveltable[ybot-ytop][y-ytop].index;
+    double levelmult=it->leveltable[ybot-ytop][y-ytop].value;
     char *rowdata;
 
     rowdata=it->image->data + y*it->image->bytes_per_line;
     char *rowdata;
 
     rowdata=it->image->data + y*it->image->bytes_per_line;
@@ -1235,7 +1234,7 @@ analogtv_draw(analogtv *it)
     if (ytop<0) ytop=0;
     if (ybot>it->useheight) ybot=it->useheight;
 
     if (ytop<0) ytop=0;
     if (ybot>it->useheight) ybot=it->useheight;
 
-    if (ybot > ytop+MAX_LINEHEIGHT) ybot=ytop+MAX_LINEHEIGHT;
+    if (ybot > ytop+ANALOGTV_MAX_LINEHEIGHT) ybot=ytop+ANALOGTV_MAX_LINEHEIGHT;
 
     if (ytop < overall_top) overall_top=ytop;
     if (ybot > overall_bot) overall_bot=ybot;
 
     if (ytop < overall_top) overall_top=ytop;
     if (ybot > overall_bot) overall_bot=ybot;
@@ -1564,11 +1563,6 @@ analogtv_draw(analogtv *it)
     it->last_display_time=tv;
   }
 #endif
     it->last_display_time=tv;
   }
 #endif
-
-  XSync(it->dpy,0);
-
-  /* Small delay to avoid hogging the CPU. */
-  usleep (10000);
 }
 
 analogtv_input *
 }
 
 analogtv_input *
@@ -1601,7 +1595,7 @@ analogtv_load_ximage(analogtv *it, analogtv_input *input, XImage *pic_im)
 
   img_w=pic_im->width;
   img_h=pic_im->height;
 
   img_w=pic_im->width;
   img_h=pic_im->height;
-
+  
   for (i=0; i<ANALOGTV_PIC_LEN+4; i++) {
     double phase=90.0-90.0*i;
     double ampl=1.0;
   for (i=0; i<ANALOGTV_PIC_LEN+4; i++) {
     double phase=90.0-90.0*i;
     double ampl=1.0;
@@ -1888,6 +1882,11 @@ analogtv_reception_update(analogtv_reception *rec)
 }
 
 
 }
 
 
+/* jwz: since MacOS doesn't have "6x10", I dumped this font to an XBM...
+ */
+
+#include "images/6x10font.xbm"
+
 void
 analogtv_make_font(Display *dpy, Window window, analogtv_font *f,
                    int w, int h, char *fontname)
 void
 analogtv_make_font(Display *dpy, Window window, analogtv_font *f,
                    int w, int h, char *fontname)
@@ -1904,7 +1903,18 @@ analogtv_make_font(Display *dpy, Window window, analogtv_font *f,
 
   XGetWindowAttributes (dpy, window, &xgwa);
 
 
   XGetWindowAttributes (dpy, window, &xgwa);
 
-  if (fontname) {
+  if (fontname && !strcmp (fontname, "6x10")) {
+
+    text_pm = XCreatePixmapFromBitmapData (dpy, window,
+                                           (char *) font6x10_bits,
+                                           font6x10_width,
+                                           font6x10_height,
+                                           1, 0, 1);
+    f->text_im = XGetImage(dpy, text_pm, 0, 0, font6x10_width, font6x10_height,
+                           1, XYPixmap);
+    XFreePixmap(dpy, text_pm);
+
+  } else if (fontname) {
 
     font = XLoadQueryFont (dpy, fontname);
     if (!font) {
 
     font = XLoadQueryFont (dpy, fontname);
     if (!font) {
@@ -1912,7 +1922,7 @@ analogtv_make_font(Display *dpy, Window window, analogtv_font *f,
       abort();
     }
 
       abort();
     }
 
-    text_pm=XCreatePixmap(dpy, window, 128*f->char_w, f->char_h, xgwa.depth);
+    text_pm=XCreatePixmap(dpy, window, 256*f->char_w, f->char_h, 1);
 
     memset(&gcv, 0, sizeof(gcv));
     gcv.foreground=1;
 
     memset(&gcv, 0, sizeof(gcv));
     gcv.foreground=1;
@@ -1921,23 +1931,25 @@ analogtv_make_font(Display *dpy, Window window, analogtv_font *f,
     gc=XCreateGC(dpy, text_pm, GCFont|GCBackground|GCForeground, &gcv);
 
     XSetForeground(dpy, gc, 0);
     gc=XCreateGC(dpy, text_pm, GCFont|GCBackground|GCForeground, &gcv);
 
     XSetForeground(dpy, gc, 0);
-    XFillRectangle(dpy, text_pm, gc, 0, 0, 128*f->char_w, f->char_h);
+    XFillRectangle(dpy, text_pm, gc, 0, 0, 256*f->char_w, f->char_h);
     XSetForeground(dpy, gc, 1);
     XSetForeground(dpy, gc, 1);
-    /* Just ASCII */
-    for (i=0; i<128; i++) {
+    for (i=0; i<256; i++) {
       char c=i;
       int x=f->char_w*i+1;
       int y=f->char_h*8/10;
       XDrawString(dpy, text_pm, gc, x, y, &c, 1);
     }
       char c=i;
       int x=f->char_w*i+1;
       int y=f->char_h*8/10;
       XDrawString(dpy, text_pm, gc, x, y, &c, 1);
     }
-    f->text_im = XGetImage(dpy, text_pm, 0, 0, 128*f->char_w, f->char_h,
-                           ~0L, ZPixmap);
+    f->text_im = XGetImage(dpy, text_pm, 0, 0, 256*f->char_w, f->char_h,
+                           1, XYPixmap);
+# if 0
+    XWriteBitmapFile(dpy, "/tmp/tvfont.xbm", text_pm, 
+                     256*f->char_w, f->char_h, -1, -1);
+# endif
     XFreeGC(dpy, gc);
     XFreePixmap(dpy, text_pm);
   } else {
     XFreeGC(dpy, gc);
     XFreePixmap(dpy, text_pm);
   } else {
-    f->text_im = XCreateImage(dpy, xgwa.visual, xgwa.depth,
-                              ZPixmap, 0, 0,
-                              128*f->char_w, f->char_h, 8, 0);
+    f->text_im = XCreateImage(dpy, xgwa.visual, 1, XYPixmap, 0, 0,
+                              256*f->char_w, f->char_h, 8, 0);
     f->text_im->data = (char *)calloc(f->text_im->height,
                                       f->text_im->bytes_per_line);
 
     f->text_im->data = (char *)calloc(f->text_im->height,
                                       f->text_im->bytes_per_line);
 
@@ -1951,7 +1963,7 @@ analogtv_font_pixel(analogtv_font *f, int c, int x, int y)
 {
   if (x<0 || x>=f->char_w) return 0;
   if (y<0 || y>=f->char_h) return 0;
 {
   if (x<0 || x>=f->char_w) return 0;
   if (y<0 || y>=f->char_h) return 0;
-  if (c<0 || c>=128) return 0;
+  if (c<0 || c>=256) return 0;
   return XGetPixel(f->text_im, c*f->char_w + x, y) ? 1 : 0;
 }
 
   return XGetPixel(f->text_im, c*f->char_w + x, y) ? 1 : 0;
 }
 
@@ -1960,7 +1972,7 @@ analogtv_font_set_pixel(analogtv_font *f, int c, int x, int y, int value)
 {
   if (x<0 || x>=f->char_w) return;
   if (y<0 || y>=f->char_h) return;
 {
   if (x<0 || x>=f->char_w) return;
   if (y<0 || y>=f->char_h) return;
-  if (c<0 || c>=128) return;
+  if (c<0 || c>=256) return;
 
   XPutPixel(f->text_im, c*f->char_w + x, y, value);
 }
 
   XPutPixel(f->text_im, c*f->char_w + x, y, value);
 }
@@ -1970,7 +1982,7 @@ analogtv_font_set_char(analogtv_font *f, int c, char *s)
 {
   int value,x,y;
 
 {
   int value,x,y;
 
-  if (c<0 || c>=128) return;
+  if (c<0 || c>=256) return;
 
   for (y=0; y<f->char_h; y++) {
     for (x=0; x<f->char_w; x++) {
 
   for (y=0; y<f->char_h; y++) {
     for (x=0; x<f->char_w; x++) {
@@ -2186,64 +2198,3 @@ analogtv_draw_xpm(analogtv *tv, analogtv_input *input,
     }
   }
 }
     }
   }
 }
-
-extern XtAppContext app;
-
-int
-analogtv_handle_events (analogtv *it)
-{
-  XSync(it->dpy, False);
-  if (XtAppPending (app) & (XtIMTimer|XtIMAlternateInput))
-    XtAppProcessEvent (app, XtIMTimer|XtIMAlternateInput);
-
-  while (XPending (it->dpy))
-    {
-      XEvent event;
-      XNextEvent (it->dpy, &event);
-      switch (event.xany.type)
-        {
-        case ButtonPress:
-          return 1;
-
-        case KeyPress:
-          {
-            KeySym keysym;
-            char c = 0;
-
-            if (it->key_handler) {
-              if (it->key_handler (it->dpy, &event, it->key_data))
-                return 1;
-            } else {
-              XLookupString (&event.xkey, &c, 1, &keysym, 0);
-              if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
-                return 1;
-            }
-          }
-          break;
-
-          /* I don't seem to get an event when clicking the "full
-             screen" window manager icon, at least when using
-             metacity. Thus, it doesn't change the video size. Is this
-             some separate WM_* message I have to deal with?
-          */
-        case ConfigureNotify:
-          if (event.xconfigure.width  != it->xgwa.width ||
-              event.xconfigure.height != it->xgwa.height)
-            analogtv_reconfigure(it);
-          break;
-
-        case Expose:
-        case GraphicsExpose:
-          it->need_clear=1;
-          break;
-
-        default:
-          break;
-        }
-      if (it->event_handler) {
-        (*it->event_handler) (it->dpy, &event);
-      }
-    }
-  return 0;
-}
-