]> git.sesse.net Git - x264/blob - common/display-x11.c
1.5x faster center_filter_mmx (amd64)
[x264] / common / display-x11.c
1 /*****************************************************************************
2  * x264: h264 encoder
3  *****************************************************************************
4  * Copyright (C) 2005 x264 project
5  *
6  * Author: Tuukka Toivonen <tuukkat@ee.oulu.fi>
7  *
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.
12  *
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.
17  *
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  *****************************************************************************/
22
23 #include <X11/Xlib.h>
24 #include <X11/Xutil.h>
25 #include <stdio.h>
26 #include <string.h>
27
28 #include "display.h"
29
30 static long event_mask = ConfigureNotify|ExposureMask|KeyPressMask|ButtonPressMask|StructureNotifyMask|ResizeRedirectMask;
31
32 static Display *disp_display = NULL;
33 static struct disp_window {
34         int init;
35         Window window;
36 } disp_window[10];
37
38 static inline void disp_chkerror(int cond, char *e) {
39         if (!cond) return;
40         fprintf(stderr, "error: %s\n", e ? e : "?");
41         abort();
42 }
43
44 static void disp_init_display(void) {
45         Visual *visual;
46         int dpy_class;
47         int screen;
48         int dpy_depth;
49
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");
63 }
64
65 static void disp_init_window(int num, int width, int height, const unsigned char *tit) {
66         XSizeHints *shint;
67         XSetWindowAttributes xswa;
68         XEvent xev;
69         int screen = DefaultScreen(disp_display);
70         Visual *visual = DefaultVisual (disp_display, screen);
71         unsigned int fg, bg;
72         unsigned int mask;
73         char title[200];
74         Window window;
75         int dpy_depth;
76
77         if (tit) {
78                 snprintf(title, 200, "%s: %i/disp", tit, num);
79         } else {
80                 snprintf(title, 200, "%i/disp", num);
81         }
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) {
94                         mask |= CWColormap;
95                         xswa.colormap = XCreateColormap(disp_display, DefaultRootWindow(disp_display), visual, AllocNone);
96                 }
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;
107
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);*/
115         }
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);
120         XFree(shint);
121 }
122
123 void disp_sync(void) {
124         XSync(disp_display, 1);
125 }
126
127 void disp_setcolor(unsigned char *name) {
128         int screen;
129         GC gc;
130         XColor c_exact, c_nearest;
131         Colormap cm;
132         Status st;
133
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);
140 }
141
142 void disp_gray(int num, char *data, int width, int height, int stride, const unsigned char *tit) {
143         Visual *visual;
144         XImage *ximage;
145         unsigned char *image;
146         int y,x,pixelsize;
147         char dummy;
148         int t = 1;
149         int dpy_depth;
150         int screen;
151         GC gc;
152         //XEvent xev;
153
154         disp_init_display();
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;
164         } else {
165                 ximage->byte_order = MSBFirst;
166                 ximage->bitmap_bit_order = MSBFirst;
167         }
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);
173         }
174         ximage->data = image;
175         gc = DefaultGC(disp_display, screen);   /* allocate colors */
176
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);
184
185         XDestroyImage(ximage);
186         XSync(disp_display, 1);
187
188 }
189
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;
192         int y,x,y0,x0;
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];
198                 }
199         }
200         disp_gray(num, dataz, width*zoom, height*zoom, width*zoom, tit);
201         free(dataz);
202 }
203
204 void disp_point(int num, int x1, int y1) {
205         int screen;
206         GC gc;
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);
211 }
212
213 void disp_line(int num, int x1, int y1, int x2, int y2) {
214         int screen;
215         GC gc;
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);
220 }
221
222 void disp_rect(int num, int x1, int y1, int x2, int y2) {
223         int screen;
224         GC gc;
225         screen = DefaultScreen(disp_display);
226
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);
230 }