1 /* analogtv, Copyright (c) 2003 Trevor Blackwell <tlb@tlb.org>
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
12 #ifndef _XSCREENSAVER_ANALOGTV_H
13 #define _XSCREENSAVER_ANALOGTV_H
18 You'll need these to generate standard NTSC TV signals
21 /* We don't handle interlace here */
24 ANALOGTV_VISLINES=200,
25 ANALOGTV_BOT=ANALOGTV_TOP + ANALOGTV_VISLINES,
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. */
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
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,
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.
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,
52 ANALOGTV_HASHNOISE_LEN=6,
54 ANALOGTV_GHOSTFIR_LEN=4,
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,
65 ANALOGTV_SIGNAL_LEN=ANALOGTV_V*ANALOGTV_H,
67 /* The number of intensity levels we deal with for gamma correction &c */
71 typedef struct analogtv_input_s {
72 char signal[ANALOGTV_V+1][ANALOGTV_H];
77 void (*updater)(struct analogtv_input_s *inp);
79 double next_update_time;
83 typedef struct analogtv_font_s {
89 typedef struct analogtv_reception_s {
91 analogtv_input *input;
97 double ghostfir[ANALOGTV_GHOSTFIR_LEN];
98 double ghostfir2[ANALOGTV_GHOSTFIR_LEN];
103 } analogtv_reception;
106 The rest of this should be considered mostly opaque to the analogtv module.
109 typedef struct analogtv_s {
114 XWindowAttributes xgwa;
117 unsigned int onscreen_signature[ANALOGTV_V];
123 int interlace_counter;
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;
131 double squeezebottom;
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
148 int use_shm,use_cmap,use_color;
151 #ifdef HAVE_XSHM_EXTENSION
152 XShmSegmentInfo shm_info;
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;
160 int usewidth,useheight,xrepl,subwidth;
161 XImage *image; /* usewidth * useheight */
163 int screen_xo,screen_yo; /* centers image in window */
165 void (*event_handler)(Display *dpy, XEvent *event);
166 int (*key_handler)(Display *dpy, XEvent *event,void *key_data);
169 int flutter_horiz_desync;
172 struct timeval last_display_time;
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];
187 int hashnoise_enable;
190 double crtload[ANALOGTV_V];
192 unsigned int red_values[ANALOGTV_CV_MAX];
193 unsigned int green_values[ANALOGTV_CV_MAX];
194 unsigned int blue_values[ANALOGTV_CV_MAX];
196 struct analogtv_yiq_s {
198 } yiq[ANALOGTV_PIC_LEN+10];
200 unsigned long colors[256];
206 int line_hsync[ANALOGTV_V];
209 double line_cb_phase[ANALOGTV_V][4];
211 int channel_change_cycles;
212 double rx_signal_level;
213 double rx_signal[ANALOGTV_SIGNAL_LEN + 2*ANALOGTV_H];
218 analogtv *analogtv_allocate(Display *dpy, Window window);
219 analogtv_input *analogtv_input_allocate(void);
221 /* call if window size changes */
222 void analogtv_reconfigure(analogtv *it);
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);
231 int analogtv_load_ximage(analogtv *it, analogtv_input *input, XImage *pic_im);
233 void analogtv_reception_update(analogtv_reception *inp);
235 void analogtv_init_signal(analogtv *it, double noiselevel);
236 void analogtv_add_signal(analogtv *it, analogtv_reception *rec);
238 void analogtv_setup_teletext(analogtv_input *input);
241 /* Functions for rendering content into an analogtv_input */
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,
252 void analogtv_draw_solid(analogtv_input *input,
253 int left, int right, int top, int bot,
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);
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);
270 int analogtv_handle_events (analogtv *it);
272 #ifdef HAVE_XSHM_EXTENSION
273 #define ANALOGTV_DEFAULTS_SHM "*useSHM: True",
275 #define ANALOGTV_DEFAULTS_SHM
278 #define ANALOGTV_DEFAULTS \
281 "*TVBrightness: 2", \
283 "*Background: Black", \
285 "*geometry: 800x600", \
286 ANALOGTV_DEFAULTS_SHM
288 #define ANALOGTV_OPTIONS \
289 { "-use-cmap", ".use_cmap", XrmoptionSepArg, 0 },
292 #endif /* _XSCREENSAVER_ANALOGTV_H */