-
Notifications
You must be signed in to change notification settings - Fork 0
/
blit.c
297 lines (243 loc) · 9.28 KB
/
blit.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/Xutil.h>
void blit_pixels_to_new_window
(argc, argv, my_pix_data,
my_pix_width,
my_pix_height)
int argc; /* passed from main */
char **argv; /* passed from main */
char my_pix_data []; /* array contianing pixel data */
unsigned int my_pix_width, my_pix_height; /* pixmap size */
/*
* This routine is very simple in conception. It accepts eight-bit
* pixels as input, opens a new window, puts the raw pixels into the
* window (using the default colormap ???), and then enters an infinite
* loop to handle the redraw events. The inifinite loop then runs as a
* detached process, so nothing new can be added to the window after it has
* been opened.
*/
{
Display *display; /* Connection to X server */
int screen; /* cathode ray tube id */
Window root_win; /* root attributes */
Window child_win;
XSizeHints my_size_hints; /* hints for the window manager */
XEvent event_buffer; /* buffer for holding events */
GC context; /* graphics context */
XImage *image; /* this is my pixmap */
Pixmap pixmap_id; /* pixmap */
unsigned long border_color, ground_color;
int display_width, display_height, display_depth;
int my_pix_padding; /* pixmap junk */
int bytes_per_line; /* number of bytes in a scanline */
display = XOpenDisplay (NULL);
screen = DefaultScreen (display); /* get CRT id number */
root_win = RootWindow (display, screen); /* get default attributes */
context = XCreateGC (display, root_win, 0, NULL);
my_pix_padding = 32; /* scanlines must start on word boundaries */
bytes_per_line = 0; /* let X figure out the length of a scanline */
/* put my pixmap data into the client side X image data structure */
image = XCreateImage (display, NULL, 8, ZPixmap, 0,
my_pix_data,
my_pix_width, my_pix_height, my_pix_padding,
bytes_per_line);
/* tell server that start managing my pixmap */
pixmap_id = XCreatePixmap (display, root_win, my_pix_width,
my_pix_height, 8);
/* copy from client to server */
(void) XPutImage (display, pixmap_id, context, image, 0,0, 0, 0,
my_pix_width, my_pix_height);
/* free up the client side pixmap data area */
XDestroyImage (image);
/* set up window size hints for the window manager */
my_size_hints.flags = PSize;
my_size_hints.height = my_pix_width;
my_size_hints.width = my_pix_height;
child_win = XCreateSimpleWindow (display, root_win,
10, 10, my_pix_width, my_pix_height,
0, BlackPixel(display, screen), WhitePixel (display, screen));
/* pass my size hints to the window manager, along with window
and icon names */
(void) XSetStandardProperties (display, child_win, "Color Pixmap",
"Pixmap", None, argv, argc, &my_size_hints);
/* copy the server copy of the pixmap into the window */
(void) XCopyArea (display, pixmap_id, child_win, context, 0,0,
my_pix_width, my_pix_height, 0, 0);
/* set masks for event reporting */
(void) XSelectInput (display, child_win, ExposureMask);
/* get the window up onto the screen */
(void) XMapWindow (display, child_win);
(void) XSync (display, 0); /* make it a squeaky clean map */
/* detach a new process */
if (fork()) return;
while (1) { /* begin event loop */
XNextEvent (display, &event_buffer);
if (event_buffer.type == Expose) {
(void) XCopyArea (display, pixmap_id, child_win, context, 0,0,
my_pix_width, my_pix_height, 0, 0);
}
}
}
/*-------------------------------------------------------------------*/
void blit_pixmap_to_root
(argc, argv, my_pix_data,
my_pix_width,
my_pix_height,
bytes_per_scanline)
int argc; /* passed from main */
char **argv; /* passed from main */
char my_pix_data []; /* array contianing pixel data */
unsigned int my_pix_width, my_pix_height; /* pixmap size */
unsigned int bytes_per_scanline;
/* This is the version to use with the Megapel -- it blits a one byte
* deep pixmap to the root window */
{
Display *display; /* Connection to X server */
int screen; /* cathode ray tube id */
Window root_win; /* root attributes */
XImage *image;
Visual visual;
GC gc;
Pixmap pixmap; /* pixmap */
display = XOpenDisplay (NULL);
screen = DefaultScreen (display); /* get CRT id number */
root_win = RootWindow (display, screen); /* get default attributes */
gc = XCreateGC (display, root_win, 0, NULL);
/* create client side data structure */
image = XCreateImage (display, NULL, 8, ZPixmap, 0, my_pix_data,
my_pix_width, my_pix_height, 8, bytes_per_scanline);
/* image = XCreateImage (display, &visual, 8, ZPixmap, 0, my_pix_data,
my_pix_width, my_pix_height, 8, bytes_per_scanline); */
/* create server side data structure */
pixmap = XCreatePixmap (display, root_win, my_pix_width,
my_pix_height, 8);
/* copy from client to server */
XPutImage (display, pixmap, gc, image, 0, 0, 0, 0,
my_pix_width, my_pix_height);
/* free client side data structures */
XDestroyImage (image);
(void) XSetWindowBackgroundPixmap (display, root_win, pixmap);
/* Use clear area to fake out window manager with an exposure event */
XClearArea (display, root_win, 0, 0, 1, 1, TRUE);
/* flush out the protocol buffer */
(void) XSync (display, 0);
XFreePixmap (display, pixmap);
XFreeGC (display, gc);
XCloseDisplay (display);
printf ("Done Blitting\n");
}
/*-------------------------------------------------------------------*/
void blit_bitmap_to_root
(argc, argv, my_pix_data,
my_pix_width,
my_pix_height,
bytes_per_scanline)
int argc; /* passed from main */
char **argv; /* passed from main */
char my_pix_data []; /* array contianing pixel data */
unsigned int my_pix_width, my_pix_height; /* pixmap size */
unsigned int bytes_per_scanline;
/* This is the version to use with the APA -- it blits a one bit
* deep bitmap to the root window */
{
Display *display; /* Connection to X server */
int screen; /* cathode ray tube id */
Window root_win; /* root attributes */
Pixmap pixmap; /* pixmap */
display = XOpenDisplay (NULL);
screen = DefaultScreen (display); /* get CRT id number */
root_win = RootWindow (display, screen); /* get default attributes */
/* allocate space for the pixmap */
pixmap = XCreatePixmapFromBitmapData
(display, root_win,
my_pix_data, 8*bytes_per_scanline, my_pix_height, 0, 1, 1);
(void) XSetWindowBackgroundPixmap (display, root_win, pixmap);
/* Use clear area to fake out window manager with an exposure event */
XClearArea (display, root_win, 0, 0, 1, 1, TRUE);
/* flush out the protocol buffer */
(void) XSync (display, 0);
XCloseDisplay (display);
printf ("Done Blitting\n");
}
#define DUTY_CYCLE 0.5
/*-------------------------------------------------------------------*/
void add_float_data_to_pixmap
(data_array, data_len,
data_x_offset, data_y_offset,
pix_array, pix_width, pix_height)
float data_array [];
unsigned int data_len; /* length of data_array */
unsigned int data_x_offset, data_y_offset; /* where to start writing */
char pix_array []; /* bitmap to be written into */
unsigned int pix_width, pix_height; /* size of bitmap */
/*
add_float_data_to_pixmap --- Linas Vepstas --- 3 May 1989
This routine takes the array of floating point numbers in data_array
(which should all be normalized -- i.e. run between zero and one)
and stuffs them into a 8 bit deep pixmap. Each float represents one byte.
The location written to is given by the two offsets.
Writing is performed in the x (horizontal) direction.
The code has been optimized for human readability, not for fast
execution.
*/
{
int i;
unsigned int byte;
char off;
unsigned int byte_off, bytes_per_line;
byte_off = pix_width * data_y_offset + data_x_offset;
/* loop over x directions */
for (i=0; i<data_len; i++) {
pix_array [i+byte_off] = (int) (255.0 * data_array [i]);
}
}
/*-------------------------------------------------------------------*/
void add_float_data_to_bitmap
(data_array, data_len,
data_x_offset, data_y_offset,
pix_array, pix_width, pix_height,
bytes_per_line_return)
float data_array [];
unsigned int data_len; /* length of data_array */
unsigned int data_x_offset, data_y_offset; /* where to start writing */
char pix_array []; /* bitmap to be written into */
unsigned int pix_width, pix_height; /* size of bitmap */
unsigned int *bytes_per_line_return;
/*
add_float_data_to_bitmap --- Linas Vepstas --- 8 April 1989
This routine takes the array of floating point numbers in data_array
(which should all be normalized -- i.e. run between zero and one)
and stuffs them into a bitmap. Each float represents one bit.
Each bit is turned on if its floating value is greater than #define
DUTY_CYCLE. The location written to is given by the two offsets.
Writing is performed in the x (horizontal) direction.
The code has been optimized for human readability, not for fast
execution.
*/
{
int i,j;
unsigned int byte;
char off;
unsigned int bit_off, bytes_per_line;
/* scan lines must start on word boundaries */
bytes_per_line = pix_width/32;
if (pix_width%32 != 0) bytes_per_line = bytes_per_line +1;
bytes_per_line = 4 * bytes_per_line;
*bytes_per_line_return = bytes_per_line;
/* loop over x directions */
bit_off = bytes_per_line * data_y_offset;
for (i=0; i<data_len; i++) {
if (data_array [i] > DUTY_CYCLE) {
j = i+data_x_offset;
byte = bit_off + j/8;
#ifdef BYTE_SWAP
off = 0x80 >> (j%8);
#else
off = 0x1 << (j%8);
#endif
/* set that bit ! */
pix_array [byte] = pix_array [byte] | off;
}
}
}