1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2005 x264 project
6 * Author: Tuukka Toivonen <tuukkat@ee.oulu.fi>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
21 *****************************************************************************/
24 #include <X11/Xutil.h>
30 static long event_mask = ConfigureNotify|ExposureMask|KeyPressMask|ButtonPressMask|StructureNotifyMask|ResizeRedirectMask;
32 static Display *disp_display = NULL;
33 static struct disp_window {
38 static inline void disp_chkerror(int cond, char *e) {
40 fprintf(stderr, "error: %s\n", e ? e : "?");
44 static void disp_init_display(void) {
50 if (disp_display != NULL) return;
51 memset(&disp_window, 0, sizeof(disp_window));
52 disp_display = XOpenDisplay("");
53 disp_chkerror(!disp_display, "no display");
54 screen = DefaultScreen(disp_display);
55 visual = DefaultVisual(disp_display, screen);
56 dpy_class = visual->class;
57 dpy_depth = DefaultDepth(disp_display, screen);
58 disp_chkerror(!((dpy_class == TrueColor && dpy_depth == 32)
59 || (dpy_class == TrueColor && dpy_depth == 24)
60 || (dpy_class == TrueColor && dpy_depth == 16)
61 || (dpy_class == PseudoColor && dpy_depth == 8)),
62 "requires 8 bit PseudoColor or 16/24/32 bit TrueColor display");
65 static void disp_init_window(int num, int width, int height, const unsigned char *tit) {
67 XSetWindowAttributes xswa;
69 int screen = DefaultScreen(disp_display);
70 Visual *visual = DefaultVisual (disp_display, screen);
78 snprintf(title, 200, "%s: %i/disp", tit, num);
80 snprintf(title, 200, "%i/disp", num);
82 shint = XAllocSizeHints();
83 disp_chkerror(!shint, "memerror");
84 shint->min_width = shint->max_width = shint->width = width;
85 shint->min_height = shint->max_height = shint->height = height;
86 shint->flags = PSize | PMinSize | PMaxSize;
87 disp_chkerror(num<0 || num>=10, "bad win num");
88 if (!disp_window[num].init) {
89 disp_window[num].init = 1;
90 bg = WhitePixel(disp_display, screen);
91 fg = BlackPixel(disp_display, screen);
92 dpy_depth = DefaultDepth(disp_display, screen);
93 if (dpy_depth==32 || dpy_depth==24 || dpy_depth==16) {
95 xswa.colormap = XCreateColormap(disp_display, DefaultRootWindow(disp_display), visual, AllocNone);
97 xswa.background_pixel = bg;
98 xswa.border_pixel = fg;
99 xswa.backing_store = Always;
100 xswa.backing_planes = -1;
101 xswa.bit_gravity = NorthWestGravity;
102 mask = CWBackPixel | CWBorderPixel | CWBackingStore | CWBackingPlanes | CWBitGravity;
103 window = XCreateWindow(disp_display, DefaultRootWindow(disp_display),
104 shint->x, shint->y, shint->width, shint->height,
105 1, dpy_depth, InputOutput, visual, mask, &xswa);
106 disp_window[num].window = window;
108 XSelectInput(disp_display, window, event_mask);
109 XSetStandardProperties(disp_display, window, title, title, None, NULL, 0, shint); /* Tell other applications about this window */
110 XMapWindow(disp_display, window); /* Map window. */
111 do { /* Wait for map. */
112 XNextEvent(disp_display, &xev);
113 } while (xev.type!=MapNotify || xev.xmap.event!=window);
114 //XSelectInput(disp_display, window, KeyPressMask); /* XSelectInput(display, window, NoEventMask);*/
116 window = disp_window[num].window;
117 XSetStandardProperties(disp_display, window, title, title, None, NULL, 0, shint); /* Tell other applications about this window */
118 XResizeWindow(disp_display, window, width, height);
119 XSync(disp_display, 1);
123 void disp_sync(void) {
124 XSync(disp_display, 1);
127 void disp_setcolor(unsigned char *name) {
130 XColor c_exact, c_nearest;
134 screen = DefaultScreen(disp_display);
135 gc = DefaultGC(disp_display, screen); /* allocate colors */
136 cm = DefaultColormap(disp_display, screen);
137 st = XAllocNamedColor(disp_display, cm, name, &c_nearest, &c_exact);
138 disp_chkerror(st!=1, "XAllocNamedColor error");
139 XSetForeground(disp_display, gc, c_nearest.pixel);
142 void disp_gray(int num, char *data, int width, int height, int stride, const unsigned char *tit) {
145 unsigned char *image;
155 disp_init_window(num, width, height, tit);
156 screen = DefaultScreen(disp_display);
157 visual = DefaultVisual(disp_display, screen);
158 dpy_depth = DefaultDepth(disp_display, screen);
159 ximage = XCreateImage(disp_display, visual, dpy_depth, ZPixmap, 0, &dummy, width, height, 8, 0);
160 disp_chkerror(!ximage, "no ximage");
161 if (*(char *)&t == 1) {
162 ximage->byte_order = LSBFirst;
163 ximage->bitmap_bit_order = LSBFirst;
165 ximage->byte_order = MSBFirst;
166 ximage->bitmap_bit_order = MSBFirst;
168 pixelsize = dpy_depth>8 ? sizeof(int) : sizeof(unsigned char);
169 image = malloc(width * height * pixelsize);
170 disp_chkerror(!image, "malloc failed");
171 for (y=0; y<height; y++) for (x=0; x<width; x++) {
172 memset(&image[(width*y + x)*pixelsize], data[y*stride+x], pixelsize);
174 ximage->data = image;
175 gc = DefaultGC(disp_display, screen); /* allocate colors */
177 // XUnmapWindow(disp_display, disp_window[num].window); /* Map window. */
178 // XMapWindow(disp_display, disp_window[num].window); /* Map window. */
179 XPutImage(disp_display, disp_window[num].window, gc, ximage, 0, 0, 0, 0, width, height);
180 // do { /* Wait for map. */
181 // XNextEvent(disp_display, &xev);
182 // } while (xev.type!=MapNotify || xev.xmap.event!=disp_window[num].window);
183 XPutImage(disp_display, disp_window[num].window, gc, ximage, 0, 0, 0, 0, width, height);
185 XDestroyImage(ximage);
186 XSync(disp_display, 1);
190 void disp_gray_zoom(int num, char *data, int width, int height, int stride, const unsigned char *tit, int zoom) {
191 unsigned char *dataz;
193 dataz = malloc(width*zoom * height*zoom);
194 disp_chkerror(!dataz, "malloc");
195 for (y=0; y<height; y++) for (x=0; x<width; x++) {
196 for (y0=0; y0<zoom; y0++) for (x0=0; x0<zoom; x0++) {
197 dataz[(y*zoom + y0)*width*zoom + x*zoom + x0] = data[y*stride+x];
200 disp_gray(num, dataz, width*zoom, height*zoom, width*zoom, tit);
204 void disp_point(int num, int x1, int y1) {
207 screen = DefaultScreen(disp_display);
208 gc = DefaultGC(disp_display, screen); /* allocate colors */
209 XDrawPoint(disp_display, disp_window[num].window, gc, x1, y1);
210 // XSync(disp_display, 1);
213 void disp_line(int num, int x1, int y1, int x2, int y2) {
216 screen = DefaultScreen(disp_display);
217 gc = DefaultGC(disp_display, screen); /* allocate colors */
218 XDrawLine(disp_display, disp_window[num].window, gc, x1, y1, x2, y2);
219 // XSync(disp_display, 1);
222 void disp_rect(int num, int x1, int y1, int x2, int y2) {
225 screen = DefaultScreen(disp_display);
227 gc = DefaultGC(disp_display, screen); /* allocate colors */
228 XDrawRectangle(disp_display, disp_window[num].window, gc, x1, y1, x2-x1, y2-y1);
229 // XSync(disp_display, 1);