http://packetstormsecurity.org/UNIX/admin/xscreensaver-4.16.tar.gz
[xscreensaver] / hacks / analogtv.h
1 /* analogtv, Copyright (c) 2003, 2004 Trevor Blackwell <tlb@tlb.org>
2  *
3  * Permission to use, copy, modify, distribute, and sell this software and its
4  * documentation for any purpose is hereby granted without fee, provided that
5  * the above copyright notice appear in all copies and that both that
6  * copyright notice and this permission notice appear in supporting
7  * documentation.  No representations are made about the suitability of this
8  * software for any purpose.  It is provided "as is" without express or
9  * implied warranty.
10  */
11
12 #ifndef _XSCREENSAVER_ANALOGTV_H
13 #define _XSCREENSAVER_ANALOGTV_H
14
15 #include "xshm.h"
16
17 /*
18   You'll need these to generate standard NTSC TV signals
19  */
20 enum {
21   /* We don't handle interlace here */
22   ANALOGTV_V=262,
23   ANALOGTV_TOP=30,
24   ANALOGTV_VISLINES=200,
25   ANALOGTV_BOT=ANALOGTV_TOP + ANALOGTV_VISLINES,
26
27   /* This really defines our sampling rate, 4x the colorburst
28      frequency. Handily equal to the Apple II's dot clock.
29      You could also make a case for using 3x the colorburst freq,
30      but 4x isn't hard to deal with. */
31   ANALOGTV_H=912,
32
33   /* Each line is 63500 nS long. The sync pulse is 4700 nS long, etc.
34      Define sync, back porch, colorburst, picture, and front porch
35      positions */
36   ANALOGTV_SYNC_START=0,
37   ANALOGTV_BP_START=4700*ANALOGTV_H/63500,
38   ANALOGTV_CB_START=5800*ANALOGTV_H/63500,
39   /* signal[row][ANALOGTV_PIC_START] is the first displayed pixel */
40   ANALOGTV_PIC_START=9400*ANALOGTV_H/63500,
41   ANALOGTV_PIC_LEN=52600*ANALOGTV_H/63500,
42   ANALOGTV_FP_START=62000*ANALOGTV_H/63500,
43   ANALOGTV_PIC_END=ANALOGTV_FP_START,
44
45   /* TVs scan past the edges of the picture tube, so normally you only
46      want to use about the middle 3/4 of the nominal scan line.
47   */
48   ANALOGTV_VIS_START=ANALOGTV_PIC_START + (ANALOGTV_PIC_LEN*1/8),
49   ANALOGTV_VIS_END=ANALOGTV_PIC_START + (ANALOGTV_PIC_LEN*7/8),
50   ANALOGTV_VIS_LEN=ANALOGTV_VIS_END-ANALOGTV_VIS_START,
51
52   ANALOGTV_HASHNOISE_LEN=6,
53
54   ANALOGTV_GHOSTFIR_LEN=4,
55
56   /* analogtv.signal is in IRE units, as defined below: */
57   ANALOGTV_WHITE_LEVEL=100,
58   ANALOGTV_GRAY50_LEVEL=55,
59   ANALOGTV_GRAY30_LEVEL=35,
60   ANALOGTV_BLACK_LEVEL=10,
61   ANALOGTV_BLANK_LEVEL=0,
62   ANALOGTV_SYNC_LEVEL=-40,
63   ANALOGTV_CB_LEVEL=20,
64
65   ANALOGTV_SIGNAL_LEN=ANALOGTV_V*ANALOGTV_H,
66
67   /* The number of intensity levels we deal with for gamma correction &c */
68   ANALOGTV_CV_MAX=1024
69 };
70
71 typedef struct analogtv_input_s {
72   char signal[ANALOGTV_V+1][ANALOGTV_H];
73
74   int do_teletext;
75
76   /* for client use */
77   void (*updater)(struct analogtv_input_s *inp);
78   void *client_data;
79   double next_update_time;
80
81 } analogtv_input;
82
83 typedef struct analogtv_font_s {
84   XImage *text_im;
85   int char_w, char_h;
86   int x_mult, y_mult;
87 } analogtv_font;
88
89 typedef struct analogtv_reception_s {
90
91   analogtv_input *input;
92   double ofs;
93   double level;
94   double multipath;
95   double freqerr;
96
97   double ghostfir[ANALOGTV_GHOSTFIR_LEN];
98   double ghostfir2[ANALOGTV_GHOSTFIR_LEN];
99
100   double hfloss;
101   double hfloss2;
102
103 } analogtv_reception;
104
105 /*
106   The rest of this should be considered mostly opaque to the analogtv module.
107  */
108
109 typedef struct analogtv_s {
110
111   Display *dpy;
112   Window window;
113   Screen *screen;
114   XWindowAttributes xgwa;
115
116 #if 0
117   unsigned int onscreen_signature[ANALOGTV_V];
118 #endif
119
120   int n_colors;
121
122   int interlace;
123   int interlace_counter;
124
125   double agclevel;
126
127   /* If you change these, call analogtv_set_demod */
128   double tint_control,color_control,brightness_control,contrast_control;
129   double height_control, width_control, squish_control;
130   double horiz_desync;
131   double squeezebottom;
132   double powerup;
133
134   /* internal cache */
135   int blur_mult;
136
137   /* For fast display, set fakeit_top, fakeit_bot to
138      the scanlines (0..ANALOGTV_V) that can be preserved on screen.
139      fakeit_scroll is the number of scan lines to scroll it up,
140      or 0 to not scroll at all. It will DTRT if asked to scroll from
141      an offscreen region.
142   */
143   int fakeit_top;
144   int fakeit_bot;
145   int fakeit_scroll;
146   int redraw_all;
147
148   int use_shm,use_cmap,use_color;
149   int bilevel_signal;
150
151 #ifdef HAVE_XSHM_EXTENSION
152   XShmSegmentInfo shm_info;
153 #endif
154   int visdepth,visclass,visbits;
155   int red_invprec,red_shift,red_mask;
156   int green_invprec,green_shift,green_mask;
157   int blue_invprec,blue_shift,blue_mask;
158
159   Colormap colormap;
160   int usewidth,useheight,xrepl,subwidth;
161   XImage *image; /* usewidth * useheight */
162   GC gc;
163   int screen_xo,screen_yo; /* centers image in window */
164
165   void (*event_handler)(Display *dpy, XEvent *event);
166   int (*key_handler)(Display *dpy, XEvent *event,void *key_data);
167   void *key_data;
168
169   int flutter_horiz_desync;
170   int flutter_tint;
171
172   struct timeval last_display_time;
173   int need_clear;
174
175
176   /* Add hash (in the radio sense, not the programming sense.) These
177      are the small white streaks that appear in quasi-regular patterns
178      all over the screen when someone is running the vacuum cleaner or
179      the blender. We also set shrinkpulse for one period which
180      squishes the image horizontally to simulate the temporary line
181      voltate drop when someone turns on a big motor */
182   double hashnoise_rpm;
183   int hashnoise_counter;
184   int hashnoise_times[ANALOGTV_V];
185   int hashnoise_signal[ANALOGTV_V];
186   int hashnoise_on;
187   int hashnoise_enable;
188   int shrinkpulse;
189
190   double crtload[ANALOGTV_V];
191
192   unsigned int red_values[ANALOGTV_CV_MAX];
193   unsigned int green_values[ANALOGTV_CV_MAX];
194   unsigned int blue_values[ANALOGTV_CV_MAX];
195
196   struct analogtv_yiq_s {
197     float y,i,q;
198   } yiq[ANALOGTV_PIC_LEN+10];
199
200   unsigned long colors[256];
201   int cmap_y_levels;
202   int cmap_i_levels;
203   int cmap_q_levels;
204
205   int cur_hsync;
206   int line_hsync[ANALOGTV_V];
207   int cur_vsync;
208   double cb_phase[4];
209   double line_cb_phase[ANALOGTV_V][4];
210
211   int channel_change_cycles;
212   double rx_signal_level;
213   double rx_signal[ANALOGTV_SIGNAL_LEN + 2*ANALOGTV_H];
214
215 } analogtv;
216
217
218 analogtv *analogtv_allocate(Display *dpy, Window window);
219 analogtv_input *analogtv_input_allocate(void);
220
221 /* call if window size changes */
222 void analogtv_reconfigure(analogtv *it);
223
224 void analogtv_set_defaults(analogtv *it, char *prefix);
225 void analogtv_release(analogtv *it);
226 int analogtv_set_demod(analogtv *it);
227 void analogtv_setup_frame(analogtv *it);
228 void analogtv_setup_sync(analogtv_input *input, int do_cb, int do_ssavi);
229 void analogtv_draw(analogtv *it);
230
231 int analogtv_load_ximage(analogtv *it, analogtv_input *input, XImage *pic_im);
232
233 void analogtv_reception_update(analogtv_reception *inp);
234
235 void analogtv_init_signal(analogtv *it, double noiselevel);
236 void analogtv_add_signal(analogtv *it, analogtv_reception *rec);
237
238 void analogtv_setup_teletext(analogtv_input *input);
239
240
241 /* Functions for rendering content into an analogtv_input */
242
243 void analogtv_make_font(Display *dpy, Window window,
244                         analogtv_font *f, int w, int h, char *fontname);
245 int analogtv_font_pixel(analogtv_font *f, int c, int x, int y);
246 void analogtv_font_set_pixel(analogtv_font *f, int c, int x, int y, int value);
247 void analogtv_font_set_char(analogtv_font *f, int c, char *s);
248 void analogtv_lcp_to_ntsc(double luma, double chroma, double phase,
249                           int ntsc[4]);
250
251
252 void analogtv_draw_solid(analogtv_input *input,
253                          int left, int right, int top, int bot,
254                          int ntsc[4]);
255
256 void analogtv_draw_solid_rel_lcp(analogtv_input *input,
257                                  double left, double right,
258                                  double top, double bot,
259                                  double luma, double chroma, double phase);
260
261 void analogtv_draw_char(analogtv_input *input, analogtv_font *f,
262                         int c, int x, int y, int ntsc[4]);
263 void analogtv_draw_string(analogtv_input *input, analogtv_font *f,
264                           char *s, int x, int y, int ntsc[4]);
265 void analogtv_draw_string_centered(analogtv_input *input, analogtv_font *f,
266                                    char *s, int x, int y, int ntsc[4]);
267 void analogtv_draw_xpm(analogtv *tv, analogtv_input *input,
268                        const char * const *xpm, int left, int top);
269
270 int analogtv_handle_events (analogtv *it);
271
272 #ifdef HAVE_XSHM_EXTENSION
273 #define ANALOGTV_DEFAULTS_SHM "*useSHM:           True",
274 #else
275 #define ANALOGTV_DEFAULTS_SHM
276 #endif
277
278 #define ANALOGTV_DEFAULTS \
279   "*TVColor:         70", \
280   "*TVTint:          5",  \
281   "*TVBrightness:    2",  \
282   "*TVContrast:      150",\
283   "*Background:      Black", \
284   "*use_cmap:        0",  \
285   "*geometry:        800x600", \
286   ANALOGTV_DEFAULTS_SHM
287
288 #define ANALOGTV_OPTIONS \
289   { "-use-cmap",        ".use_cmap",  XrmoptionSepArg, 0 },
290
291
292 #endif /* _XSCREENSAVER_ANALOGTV_H */