1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2005 Tuukka Toivonen <tuukkat@ee.oulu.fi>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
19 *****************************************************************************/
22 #include <X11/Xutil.h>
28 static long event_mask
= ConfigureNotify
|ExposureMask
|KeyPressMask
|ButtonPressMask
|StructureNotifyMask
|ResizeRedirectMask
;
30 static Display
*disp_display
= NULL
;
31 static struct disp_window
{
36 static inline void disp_chkerror(int cond
, char *e
) {
38 fprintf(stderr
, "error: %s\n", e
? e
: "?");
42 static void disp_init_display(void) {
48 if (disp_display
!= NULL
) return;
49 memset(&disp_window
, 0, sizeof(disp_window
));
50 disp_display
= XOpenDisplay("");
51 disp_chkerror(!disp_display
, "no display");
52 screen
= DefaultScreen(disp_display
);
53 visual
= DefaultVisual(disp_display
, screen
);
54 dpy_class
= visual
->class;
55 dpy_depth
= DefaultDepth(disp_display
, screen
);
56 disp_chkerror(!((dpy_class
== TrueColor
&& dpy_depth
== 32)
57 || (dpy_class
== TrueColor
&& dpy_depth
== 24)
58 || (dpy_class
== TrueColor
&& dpy_depth
== 16)
59 || (dpy_class
== PseudoColor
&& dpy_depth
== 8)),
60 "requires 8 bit PseudoColor or 16/24/32 bit TrueColor display");
63 static void disp_init_window(int num
, int width
, int height
, const unsigned char *tit
) {
65 XSetWindowAttributes xswa
;
67 int screen
= DefaultScreen(disp_display
);
68 Visual
*visual
= DefaultVisual (disp_display
, screen
);
76 snprintf(title
, 200, "%s: %i/disp", tit
, num
);
78 snprintf(title
, 200, "%i/disp", num
);
80 shint
= XAllocSizeHints();
81 disp_chkerror(!shint
, "memerror");
82 shint
->min_width
= shint
->max_width
= shint
->width
= width
;
83 shint
->min_height
= shint
->max_height
= shint
->height
= height
;
84 shint
->flags
= PSize
| PMinSize
| PMaxSize
;
85 disp_chkerror(num
<0 || num
>=10, "bad win num");
86 if (!disp_window
[num
].init
) {
87 disp_window
[num
].init
= 1;
88 bg
= WhitePixel(disp_display
, screen
);
89 fg
= BlackPixel(disp_display
, screen
);
90 dpy_depth
= DefaultDepth(disp_display
, screen
);
91 if (dpy_depth
==32 || dpy_depth
==24 || dpy_depth
==16) {
93 xswa
.colormap
= XCreateColormap(disp_display
, DefaultRootWindow(disp_display
), visual
, AllocNone
);
95 xswa
.background_pixel
= bg
;
96 xswa
.border_pixel
= fg
;
97 xswa
.backing_store
= Always
;
98 xswa
.backing_planes
= -1;
99 xswa
.bit_gravity
= NorthWestGravity
;
100 mask
= CWBackPixel
| CWBorderPixel
| CWBackingStore
| CWBackingPlanes
| CWBitGravity
;
101 window
= XCreateWindow(disp_display
, DefaultRootWindow(disp_display
),
102 shint
->x
, shint
->y
, shint
->width
, shint
->height
,
103 1, dpy_depth
, InputOutput
, visual
, mask
, &xswa
);
104 disp_window
[num
].window
= window
;
106 XSelectInput(disp_display
, window
, event_mask
);
107 XSetStandardProperties(disp_display
, window
, title
, title
, None
, NULL
, 0, shint
); /* Tell other applications about this window */
108 XMapWindow(disp_display
, window
); /* Map window. */
109 do { /* Wait for map. */
110 XNextEvent(disp_display
, &xev
);
111 } while (xev
.type
!=MapNotify
|| xev
.xmap
.event
!=window
);
112 //XSelectInput(disp_display, window, KeyPressMask); /* XSelectInput(display, window, NoEventMask);*/
114 window
= disp_window
[num
].window
;
115 XSetStandardProperties(disp_display
, window
, title
, title
, None
, NULL
, 0, shint
); /* Tell other applications about this window */
116 XResizeWindow(disp_display
, window
, width
, height
);
117 XSync(disp_display
, 1);
121 void disp_sync(void) {
122 XSync(disp_display
, 1);
125 void disp_setcolor(unsigned char *name
) {
128 XColor c_exact
, c_nearest
;
132 screen
= DefaultScreen(disp_display
);
133 gc
= DefaultGC(disp_display
, screen
); /* allocate colors */
134 cm
= DefaultColormap(disp_display
, screen
);
135 st
= XAllocNamedColor(disp_display
, cm
, name
, &c_nearest
, &c_exact
);
136 disp_chkerror(st
!=1, "XAllocNamedColor error");
137 XSetForeground(disp_display
, gc
, c_nearest
.pixel
);
140 void disp_gray(int num
, char *data
, int width
, int height
, int stride
, const unsigned char *tit
) {
143 unsigned char *image
;
153 disp_init_window(num
, width
, height
, tit
);
154 screen
= DefaultScreen(disp_display
);
155 visual
= DefaultVisual(disp_display
, screen
);
156 dpy_depth
= DefaultDepth(disp_display
, screen
);
157 ximage
= XCreateImage(disp_display
, visual
, dpy_depth
, ZPixmap
, 0, &dummy
, width
, height
, 8, 0);
158 disp_chkerror(!ximage
, "no ximage");
159 if (*(char *)&t
== 1) {
160 ximage
->byte_order
= LSBFirst
;
161 ximage
->bitmap_bit_order
= LSBFirst
;
163 ximage
->byte_order
= MSBFirst
;
164 ximage
->bitmap_bit_order
= MSBFirst
;
166 pixelsize
= dpy_depth
>8 ? sizeof(int) : sizeof(unsigned char);
167 image
= malloc(width
* height
* pixelsize
);
168 disp_chkerror(!image
, "malloc failed");
169 for (y
=0; y
<height
; y
++) for (x
=0; x
<width
; x
++) {
170 memset(&image
[(width
*y
+ x
)*pixelsize
], data
[y
*stride
+x
], pixelsize
);
172 ximage
->data
= image
;
173 gc
= DefaultGC(disp_display
, screen
); /* allocate colors */
175 // XUnmapWindow(disp_display, disp_window[num].window); /* Map window. */
176 // XMapWindow(disp_display, disp_window[num].window); /* Map window. */
177 XPutImage(disp_display
, disp_window
[num
].window
, gc
, ximage
, 0, 0, 0, 0, width
, height
);
178 // do { /* Wait for map. */
179 // XNextEvent(disp_display, &xev);
180 // } while (xev.type!=MapNotify || xev.xmap.event!=disp_window[num].window);
181 XPutImage(disp_display
, disp_window
[num
].window
, gc
, ximage
, 0, 0, 0, 0, width
, height
);
183 XDestroyImage(ximage
);
184 XSync(disp_display
, 1);
188 void disp_gray_zoom(int num
, char *data
, int width
, int height
, int stride
, const unsigned char *tit
, int zoom
) {
189 unsigned char *dataz
;
191 dataz
= malloc(width
*zoom
* height
*zoom
);
192 disp_chkerror(!dataz
, "malloc");
193 for (y
=0; y
<height
; y
++) for (x
=0; x
<width
; x
++) {
194 for (y0
=0; y0
<zoom
; y0
++) for (x0
=0; x0
<zoom
; x0
++) {
195 dataz
[(y
*zoom
+ y0
)*width
*zoom
+ x
*zoom
+ x0
] = data
[y
*stride
+x
];
198 disp_gray(num
, dataz
, width
*zoom
, height
*zoom
, width
*zoom
, tit
);
202 void disp_point(int num
, int x1
, int y1
) {
205 screen
= DefaultScreen(disp_display
);
206 gc
= DefaultGC(disp_display
, screen
); /* allocate colors */
207 XDrawPoint(disp_display
, disp_window
[num
].window
, gc
, x1
, y1
);
208 // XSync(disp_display, 1);
211 void disp_line(int num
, int x1
, int y1
, int x2
, int y2
) {
214 screen
= DefaultScreen(disp_display
);
215 gc
= DefaultGC(disp_display
, screen
); /* allocate colors */
216 XDrawLine(disp_display
, disp_window
[num
].window
, gc
, x1
, y1
, x2
, y2
);
217 // XSync(disp_display, 1);
220 void disp_rect(int num
, int x1
, int y1
, int x2
, int y2
) {
223 screen
= DefaultScreen(disp_display
);
225 gc
= DefaultGC(disp_display
, screen
); /* allocate colors */
226 XDrawRectangle(disp_display
, disp_window
[num
].window
, gc
, x1
, y1
, x2
-x1
, y2
-y1
);
227 // XSync(disp_display, 1);