1 /*****************************************************************************
2 * x264: x11 interface for visualization module
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>
30 static long event_mask = ConfigureNotify|ExposureMask|KeyPressMask|ButtonPressMask|StructureNotifyMask|ResizeRedirectMask;
32 static Display *disp_display = NULL;
33 static struct disp_window
39 static inline void disp_chkerror( int cond, char *e )
43 fprintf( stderr, "error: %s\n", e ? e : "?" );
47 static void disp_init_display()
56 memset( &disp_window, 0, sizeof(disp_window) );
57 disp_display = XOpenDisplay( "" );
58 disp_chkerror( !disp_display, "no display" );
59 screen = DefaultScreen( disp_display );
60 visual = DefaultVisual( disp_display, screen );
61 dpy_class = visual->class;
62 dpy_depth = DefaultDepth( disp_display, screen );
63 disp_chkerror( !((dpy_class == TrueColor && dpy_depth == 32)
64 || (dpy_class == TrueColor && dpy_depth == 24)
65 || (dpy_class == TrueColor && dpy_depth == 16)
66 || (dpy_class == PseudoColor && dpy_depth == 8)),
67 "requires 8 bit PseudoColor or 16/24/32 bit TrueColor display" );
70 static void disp_init_window( int num, int width, int height, const unsigned char *title )
72 XSetWindowAttributes xswa;
74 int screen = DefaultScreen(disp_display);
75 Visual *visual = DefaultVisual (disp_display, screen);
80 snprintf( buf, 200, "%s: %i/disp", title, num );
82 snprintf( buf, 200, "%i/disp", num );
84 XSizeHints *shint = XAllocSizeHints();
85 disp_chkerror( !shint, "memerror" );
86 shint->min_width = shint->max_width = shint->width = width;
87 shint->min_height = shint->max_height = shint->height = height;
88 shint->flags = PSize | PMinSize | PMaxSize;
89 disp_chkerror( num < 0 || num >= 10, "bad win num" );
90 if( !disp_window[num].init )
92 unsigned int mask = 0;
93 disp_window[num].init = 1;
94 unsigned int bg = WhitePixel( disp_display, screen );
95 unsigned int fg = BlackPixel( disp_display, screen );
96 int dpy_depth = DefaultDepth( disp_display, screen );
97 if( dpy_depth==32 || dpy_depth==24 || dpy_depth==16 )
100 xswa.colormap = XCreateColormap( disp_display, DefaultRootWindow( disp_display ), visual, AllocNone );
102 xswa.background_pixel = bg;
103 xswa.border_pixel = fg;
104 xswa.backing_store = Always;
105 xswa.backing_planes = -1;
106 xswa.bit_gravity = NorthWestGravity;
107 mask = CWBackPixel | CWBorderPixel | CWBackingStore | CWBackingPlanes | CWBitGravity;
108 window = XCreateWindow( disp_display, DefaultRootWindow( disp_display ),
109 shint->x, shint->y, shint->width, shint->height,
110 1, dpy_depth, InputOutput, visual, mask, &xswa );
111 disp_window[num].window = window;
113 XSelectInput( disp_display, window, event_mask );
114 XSetStandardProperties( disp_display, window, buf, buf, None, NULL, 0, shint );
115 XMapWindow( disp_display, window );
118 XNextEvent( disp_display, &xev );
119 } while( xev.type != MapNotify || xev.xmap.event != window );
121 window = disp_window[num].window;
122 XSetStandardProperties( disp_display, window, buf, buf, None, NULL, 0, shint );
123 XResizeWindow( disp_display, window, width, height );
124 XSync( disp_display, 1 );
130 XSync( disp_display, 1 );
133 void disp_setcolor( unsigned char *name )
135 XColor c_exact, c_nearest;
137 int screen = DefaultScreen( disp_display );
138 GC gc = DefaultGC( disp_display, screen );
139 Colormap cm = DefaultColormap( disp_display, screen );
140 Status st = XAllocNamedColor( disp_display, cm, name, &c_nearest, &c_exact );
141 disp_chkerror( st != 1, "XAllocNamedColor error" );
142 XSetForeground( disp_display, gc, c_nearest.pixel );
145 void disp_gray( int num, char *data, int width, int height, int stride, const unsigned char *title )
150 disp_init_window( num, width, height, title );
151 int screen = DefaultScreen( disp_display );
152 Visual *visual = DefaultVisual( disp_display, screen );
153 int dpy_depth = DefaultDepth( disp_display, screen );
154 XImage *ximage = XCreateImage( disp_display, visual, dpy_depth, ZPixmap, 0, &dummy, width, height, 8, 0 );
155 disp_chkerror( !ximage, "no ximage" );
156 #ifdef WORDS_BIGENDIAN
157 ximage->byte_order = MSBFirst;
158 ximage->bitmap_bit_order = MSBFirst;
160 ximage->byte_order = LSBFirst;
161 ximage->bitmap_bit_order = LSBFirst;
164 int pixelsize = dpy_depth>8 ? sizeof(int) : sizeof(unsigned char);
165 uint8_t *image = malloc( width * height * pixelsize );
166 disp_chkerror( !image, "malloc failed" );
167 for( int y = 0; y < height; y++ )
168 for( int x = 0; x < width; x++ )
169 memset( &image[(width*y + x)*pixelsize], data[y*stride+x], pixelsize );
170 ximage->data = image;
171 GC gc = DefaultGC( disp_display, screen );
173 XPutImage( disp_display, disp_window[num].window, gc, ximage, 0, 0, 0, 0, width, height );
174 XPutImage( disp_display, disp_window[num].window, gc, ximage, 0, 0, 0, 0, width, height );
176 XDestroyImage( ximage );
177 XSync( disp_display, 1 );
181 void disp_gray_zoom(int num, char *data, int width, int height, int stride, const unsigned char *title, int zoom)
183 unsigned char *dataz = malloc( width*zoom * height*zoom );
184 disp_chkerror( !dataz, "malloc" );
185 for( int y = 0; y < height; y++ )
186 for( int x = 0; x < width; x++ )
187 for( int y0 = 0; y0 < zoom; y0++ )
188 for( int x0 = 0; x0 < zoom; x0++ )
189 dataz[(y*zoom + y0)*width*zoom + x*zoom + x0] = data[y*stride+x];
190 disp_gray( num, dataz, width*zoom, height*zoom, width*zoom, title );
194 void disp_point( int num, int x1, int y1 )
196 int screen = DefaultScreen( disp_display );
197 GC gc = DefaultGC( disp_display, screen );
198 XDrawPoint( disp_display, disp_window[num].window, gc, x1, y1 );
201 void disp_line( int num, int x1, int y1, int x2, int y2 )
203 int screen = DefaultScreen( disp_display );
204 GC gc = DefaultGC( disp_display, screen );
205 XDrawLine( disp_display, disp_window[num].window, gc, x1, y1, x2, y2 );
208 void disp_rect( int num, int x1, int y1, int x2, int y2 )
210 int screen = DefaultScreen( disp_display );
211 GC gc = DefaultGC( disp_display, screen );
212 XDrawRectangle( disp_display, disp_window[num].window, gc, x1, y1, x2-x1, y2-y1 );