1 /*****************************************************************************
2 * display-x11.c: x11 interface
3 *****************************************************************************
4 * Copyright (C) 2005-2010 x264 project
6 * Authors: 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
22 * This program is also available under a commercial proprietary license.
23 * For more information, contact us at licensing@x264.com.
24 *****************************************************************************/
27 #include <X11/Xutil.h>
35 static long event_mask = ConfigureNotify|ExposureMask|KeyPressMask|ButtonPressMask|StructureNotifyMask|ResizeRedirectMask;
37 static Display *disp_display = NULL;
38 static struct disp_window
44 static inline void disp_chkerror( int cond, char *e )
48 fprintf( stderr, "error: %s\n", e ? e : "?" );
52 static void disp_init_display()
61 memset( &disp_window, 0, sizeof(disp_window) );
62 disp_display = XOpenDisplay( "" );
63 disp_chkerror( !disp_display, "no display" );
64 screen = DefaultScreen( disp_display );
65 visual = DefaultVisual( disp_display, screen );
66 dpy_class = visual->class;
67 dpy_depth = DefaultDepth( disp_display, screen );
68 disp_chkerror( !((dpy_class == TrueColor && dpy_depth == 32)
69 || (dpy_class == TrueColor && dpy_depth == 24)
70 || (dpy_class == TrueColor && dpy_depth == 16)
71 || (dpy_class == PseudoColor && dpy_depth == 8)),
72 "requires 8 bit PseudoColor or 16/24/32 bit TrueColor display" );
75 static void disp_init_window( int num, int width, int height, const unsigned char *title )
77 XSetWindowAttributes xswa;
79 int screen = DefaultScreen(disp_display);
80 Visual *visual = DefaultVisual (disp_display, screen);
85 snprintf( buf, 200, "%s: %i/disp", title, num );
87 snprintf( buf, 200, "%i/disp", num );
89 XSizeHints *shint = XAllocSizeHints();
90 disp_chkerror( !shint, "memerror" );
91 shint->min_width = shint->max_width = shint->width = width;
92 shint->min_height = shint->max_height = shint->height = height;
93 shint->flags = PSize | PMinSize | PMaxSize;
94 disp_chkerror( num < 0 || num >= 10, "bad win num" );
95 if( !disp_window[num].init )
97 unsigned int mask = 0;
98 disp_window[num].init = 1;
99 unsigned int bg = WhitePixel( disp_display, screen );
100 unsigned int fg = BlackPixel( disp_display, screen );
101 int dpy_depth = DefaultDepth( disp_display, screen );
102 if( dpy_depth==32 || dpy_depth==24 || dpy_depth==16 )
105 xswa.colormap = XCreateColormap( disp_display, DefaultRootWindow( disp_display ), visual, AllocNone );
107 xswa.background_pixel = bg;
108 xswa.border_pixel = fg;
109 xswa.backing_store = Always;
110 xswa.backing_planes = -1;
111 xswa.bit_gravity = NorthWestGravity;
112 mask = CWBackPixel | CWBorderPixel | CWBackingStore | CWBackingPlanes | CWBitGravity;
113 window = XCreateWindow( disp_display, DefaultRootWindow( disp_display ),
114 shint->x, shint->y, shint->width, shint->height,
115 1, dpy_depth, InputOutput, visual, mask, &xswa );
116 disp_window[num].window = window;
118 XSelectInput( disp_display, window, event_mask );
119 XSetStandardProperties( disp_display, window, buf, buf, None, NULL, 0, shint );
120 XMapWindow( disp_display, window );
123 XNextEvent( disp_display, &xev );
124 } while( xev.type != MapNotify || xev.xmap.event != window );
126 window = disp_window[num].window;
127 XSetStandardProperties( disp_display, window, buf, buf, None, NULL, 0, shint );
128 XResizeWindow( disp_display, window, width, height );
129 XSync( disp_display, 1 );
135 XSync( disp_display, 1 );
138 void disp_setcolor( unsigned char *name )
140 XColor c_exact, c_nearest;
142 int screen = DefaultScreen( disp_display );
143 GC gc = DefaultGC( disp_display, screen );
144 Colormap cm = DefaultColormap( disp_display, screen );
145 Status st = XAllocNamedColor( disp_display, cm, name, &c_nearest, &c_exact );
146 disp_chkerror( st != 1, "XAllocNamedColor error" );
147 XSetForeground( disp_display, gc, c_nearest.pixel );
150 void disp_gray( int num, char *data, int width, int height, int stride, const unsigned char *title )
155 disp_init_window( num, width, height, title );
156 int screen = DefaultScreen( disp_display );
157 Visual *visual = DefaultVisual( disp_display, screen );
158 int dpy_depth = DefaultDepth( disp_display, screen );
159 XImage *ximage = XCreateImage( disp_display, visual, dpy_depth, ZPixmap, 0, &dummy, width, height, 8, 0 );
160 disp_chkerror( !ximage, "no ximage" );
162 ximage->byte_order = MSBFirst;
163 ximage->bitmap_bit_order = MSBFirst;
165 ximage->byte_order = LSBFirst;
166 ximage->bitmap_bit_order = LSBFirst;
169 int pixelsize = dpy_depth>8 ? sizeof(int) : sizeof(unsigned char);
170 uint8_t *image = malloc( width * height * pixelsize );
171 disp_chkerror( !image, "malloc failed" );
172 for( int y = 0; y < height; y++ )
173 for( int x = 0; x < width; x++ )
174 memset( &image[(width*y + x)*pixelsize], data[y*stride+x], pixelsize );
175 ximage->data = image;
176 GC gc = DefaultGC( disp_display, screen );
178 XPutImage( disp_display, disp_window[num].window, gc, ximage, 0, 0, 0, 0, width, height );
179 XPutImage( disp_display, disp_window[num].window, gc, ximage, 0, 0, 0, 0, width, height );
181 XDestroyImage( ximage );
182 XSync( disp_display, 1 );
186 void disp_gray_zoom(int num, char *data, int width, int height, int stride, const unsigned char *title, int zoom)
188 unsigned char *dataz = malloc( width*zoom * height*zoom );
189 disp_chkerror( !dataz, "malloc" );
190 for( int y = 0; y < height; y++ )
191 for( int x = 0; x < width; x++ )
192 for( int y0 = 0; y0 < zoom; y0++ )
193 for( int x0 = 0; x0 < zoom; x0++ )
194 dataz[(y*zoom + y0)*width*zoom + x*zoom + x0] = data[y*stride+x];
195 disp_gray( num, dataz, width*zoom, height*zoom, width*zoom, title );
199 void disp_point( int num, int x1, int y1 )
201 int screen = DefaultScreen( disp_display );
202 GC gc = DefaultGC( disp_display, screen );
203 XDrawPoint( disp_display, disp_window[num].window, gc, x1, y1 );
206 void disp_line( int num, int x1, int y1, int x2, int y2 )
208 int screen = DefaultScreen( disp_display );
209 GC gc = DefaultGC( disp_display, screen );
210 XDrawLine( disp_display, disp_window[num].window, gc, x1, y1, x2, y2 );
213 void disp_rect( int num, int x1, int y1, int x2, int y2 )
215 int screen = DefaultScreen( disp_display );
216 GC gc = DefaultGC( disp_display, screen );
217 XDrawRectangle( disp_display, disp_window[num].window, gc, x1, y1, x2-x1, y2-y1 );