Mercurial > mplayer.hg
annotate libvo/vo_xvidix.c @ 4185:85c90bb8729a
initial stuff. comments welcomed...
author | arpi |
---|---|
date | Wed, 16 Jan 2002 00:14:59 +0000 |
parents | 7134f727e3c6 |
children | 37c35f4ef9e2 |
rev | line source |
---|---|
4123 | 1 /* |
2 VIDIX accelerated overlay in a X window | |
3 | |
4132
84ecfd03c86a
test for preinit errors and correct handling subdevice
nick
parents:
4131
diff
changeset
|
4 (C) Alex Beregszaszi & Nick Kurshev |
4123 | 5 |
6 WS window manager by Pontscho/Fresh! | |
7 | |
8 Based on vo_gl.c and vo_vesa.c | |
9 */ | |
10 | |
11 #include <stdio.h> | |
12 #include <stdlib.h> | |
13 #include <string.h> | |
14 #include <math.h> | |
15 #include <errno.h> | |
16 | |
17 #include "config.h" | |
18 #include "video_out.h" | |
19 #include "video_out_internal.h" | |
20 | |
21 #include <X11/Xlib.h> | |
22 #include <X11/Xutil.h> | |
23 //#include <X11/keysym.h> | |
24 | |
25 #include "x11_common.h" | |
26 #include "aspect.h" | |
27 #include "mp_msg.h" | |
28 | |
29 #include "vosub_vidix.h" | |
30 | |
31 LIBVO_EXTERN(xvidix) | |
32 | |
33 static vo_info_t vo_info = | |
34 { | |
35 "X11 (VIDIX)", | |
36 "xvidix", | |
37 "Alex Beregszaszi", | |
38 "" | |
39 }; | |
40 | |
41 /* X11 related variables */ | |
42 static Window mywindow; | |
43 static int X_already_started = 0; | |
44 | |
45 /* VIDIX related stuff */ | |
4125 | 46 static const char *vidix_name = (char *)(-1); |
4132
84ecfd03c86a
test for preinit errors and correct handling subdevice
nick
parents:
4131
diff
changeset
|
47 static int pre_init_err = 0; |
4123 | 48 |
49 /* Image parameters */ | |
50 static uint32_t image_width; | |
51 static uint32_t image_height; | |
52 static uint32_t image_format; | |
53 static uint32_t image_depth; | |
54 | |
55 /* Window parameters */ | |
56 static uint32_t window_x, window_y; | |
57 static uint32_t window_width, window_height; | |
58 | |
59 /* used by XGetGeometry & XTranslateCoordinates */ | |
60 static Window mRoot; | |
61 static uint32_t drwX, drwY, drwWidth, drwHeight, drwBorderWidth, | |
62 drwDepth, drwcX, drwcY, dwidth, dheight, mFullscreen; | |
63 | |
64 static void resize(int x, int y) | |
65 { | |
66 XGetGeometry(mDisplay, mywindow, &mRoot, &drwX, &drwY, &drwWidth, | |
67 &drwHeight, &drwBorderWidth, &drwDepth); | |
68 drwX = drwY = 0; | |
69 XTranslateCoordinates(mDisplay, mywindow, mRoot, 0, 0, &drwcX, &drwcY, &mRoot); | |
70 | |
71 mp_msg(MSGT_VO, MSGL_DBG2, "[xvidix] dcx: %d dcy: %d dx: %d dy: %d dw: %d dh: %d\n", | |
72 drwcX, drwcY, drwX, drwY, drwWidth, drwHeight); | |
73 | |
74 if ((window_x != drwcX) || (window_y != drwcY) || | |
75 (window_width != drwWidth) || (window_height != drwHeight)) | |
76 { | |
77 /* FIXME: implement runtime resize/move if possible, this way is very ugly! */ | |
78 vidix_term(); | |
79 vidix_preinit(vidix_name, &video_out_xvidix); | |
80 if (vidix_init(image_width, image_height, window_x, window_y, | |
4133 | 81 window_width, window_height, image_format, vo_depthonscreen, vo_screenwidth, vo_screenheight) != 0) |
4123 | 82 { |
83 mp_msg(MSGT_VO, MSGL_FATAL, "Can't initialize VIDIX driver: %s: %s\n", | |
84 vidix_name, strerror(errno)); | |
85 vidix_term(); | |
86 uninit(); | |
87 exit(1); /* !!! */ | |
4125 | 88 x = window_width; |
89 y = window_height; | |
4123 | 90 } |
91 } | |
92 | |
93 window_x = drwcX; | |
94 window_y = drwcY; | |
95 window_width = drwWidth; | |
96 window_height = drwHeight; | |
97 | |
98 mp_msg(MSGT_VO, MSGL_INFO, "[xvidix] window properties: pos: %dx%d, size: %dx%d\n", | |
99 window_x, window_y, window_width, window_height); | |
100 | |
101 return; | |
102 } | |
103 | |
104 /* connect to server, create and map window, | |
105 * allocate colors and (shared) memory | |
106 */ | |
107 static uint32_t init(uint32_t width, uint32_t height, uint32_t d_width, | |
108 uint32_t d_height, uint32_t flags, char *title, uint32_t format) | |
109 { | |
110 unsigned int fg, bg; | |
111 XVisualInfo vinfo; | |
112 XEvent xev; | |
113 XSizeHints hint; | |
114 XSetWindowAttributes xswa; | |
115 unsigned long xswamask; | |
116 XWindowAttributes attribs; | |
117 int window_depth; | |
4125 | 118 |
4132
84ecfd03c86a
test for preinit errors and correct handling subdevice
nick
parents:
4131
diff
changeset
|
119 if(pre_init_err) |
84ecfd03c86a
test for preinit errors and correct handling subdevice
nick
parents:
4131
diff
changeset
|
120 { |
84ecfd03c86a
test for preinit errors and correct handling subdevice
nick
parents:
4131
diff
changeset
|
121 mp_msg(MSGT_VO, MSGL_INFO, "[xvidix] Quiting due preinit error\n"); |
84ecfd03c86a
test for preinit errors and correct handling subdevice
nick
parents:
4131
diff
changeset
|
122 return -1; |
84ecfd03c86a
test for preinit errors and correct handling subdevice
nick
parents:
4131
diff
changeset
|
123 } |
4125 | 124 // if (title) |
125 // free(title); | |
126 title = strdup("MPlayer VIDIX X11 Overlay"); | |
4123 | 127 |
128 image_height = height; | |
129 image_width = width; | |
130 image_format = format; | |
131 | |
132 if (IMGFMT_IS_RGB(format)) | |
133 { | |
134 image_depth = IMGFMT_RGB_DEPTH(format); | |
135 } | |
136 else | |
137 if (IMGFMT_IS_BGR(format)) | |
138 { | |
139 image_depth = IMGFMT_BGR_DEPTH(format); | |
140 } | |
141 else | |
142 switch(format) | |
143 { | |
144 case IMGFMT_IYUV: | |
145 case IMGFMT_I420: | |
146 case IMGFMT_YV12: | |
147 image_depth = 12; | |
148 break; | |
149 case IMGFMT_YUY2: | |
150 image_depth = 16; | |
151 break; | |
152 default: | |
153 mp_msg(MSGT_VO, MSGL_FATAL, "Unknown image format: %s", | |
154 vo_format_name(format)); | |
155 return(-1); | |
156 } | |
157 | |
158 if (X_already_started) | |
159 return(-1); | |
160 if (!vo_init()) | |
161 return(-1); | |
162 | |
163 aspect_save_orig(width,height); | |
164 aspect_save_prescale(d_width,d_height); | |
165 aspect_save_screenres(vo_screenwidth,vo_screenheight); | |
166 | |
167 X_already_started++; | |
168 | |
169 aspect(&d_width, &d_height, A_NOZOOM); | |
170 #ifdef X11_FULLSCREEN | |
171 if (flags & 0x01) /* fullscreen */ | |
4131 | 172 if(flags & 0x04) aspect(&d_width, &d_height, A_ZOOM); |
173 else | |
174 { | |
175 d_width = vo_screenwidth; | |
176 d_height = vo_screenheight; | |
177 } | |
4123 | 178 #endif |
179 | |
180 hint.x = 0; | |
181 hint.y = 0; | |
182 hint.width = d_width; | |
183 hint.height = d_height; | |
184 hint.flags = PPosition | PSize; | |
185 | |
186 /* Get some colors */ | |
187 bg = WhitePixel(mDisplay, mScreen); | |
188 fg = BlackPixel(mDisplay, mScreen); | |
189 | |
190 /* Make the window */ | |
191 XGetWindowAttributes(mDisplay, DefaultRootWindow(mDisplay), &attribs); | |
192 | |
193 /* from vo_x11 */ | |
194 window_depth = attribs.depth; | |
195 if ((window_depth != 15) && (window_depth != 16) && (window_depth != 24) | |
196 && (window_depth != 32)) | |
197 window_depth = 24; | |
198 XMatchVisualInfo(mDisplay, mScreen, window_depth, TrueColor, &vinfo); | |
199 | |
200 xswa.background_pixel = 0; | |
201 xswa.border_pixel = 1; | |
202 xswa.colormap = XCreateColormap(mDisplay, RootWindow(mDisplay, mScreen), | |
203 vinfo.visual, AllocNone); | |
204 xswamask = CWBackPixel | CWBorderPixel | CWColormap; | |
205 // xswamask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWCursor | CWOverrideRedirect | CWSaveUnder | CWX | CWY | CWWidth | CWHeight; | |
206 | |
207 if (WinID >= 0) | |
208 { | |
209 mywindow = WinID ? ((Window)WinID) : RootWindow(mDisplay, mScreen); | |
210 XUnmapWindow(mDisplay, mywindow); | |
211 XChangeWindowAttributes(mDisplay, mywindow, xswamask, &xswa); | |
212 } | |
213 else | |
214 mywindow = XCreateWindow(mDisplay, RootWindow(mDisplay, mScreen), | |
215 hint.x, hint.y, hint.width, hint.height, xswa.border_pixel, | |
216 vinfo.depth, CopyFromParent, vinfo.visual, xswamask, &xswa); | |
217 | |
218 vo_x11_classhint(mDisplay, mywindow, "xvidix"); | |
219 vo_hidecursor(mDisplay, mywindow); | |
220 | |
221 if (flags & 0x01) /* fullscreen */ | |
222 vo_x11_decoration(mDisplay, mywindow, 0); | |
223 | |
224 XSelectInput(mDisplay, mywindow, StructureNotifyMask); | |
225 | |
226 /* Tell other applications about this window */ | |
227 XSetStandardProperties(mDisplay, mywindow, title, title, None, NULL, 0, &hint); | |
228 | |
229 /* Map window. */ | |
230 XMapWindow(mDisplay, mywindow); | |
4125 | 231 #if 0 |
4123 | 232 #ifdef HAVE_XINERAMA |
233 vo_x11_xinerama_move(mDisplay, mywindow); | |
234 #endif | |
4125 | 235 #endif |
4123 | 236 |
237 /* Wait for map. */ | |
238 do | |
239 { | |
240 XNextEvent(mDisplay, &xev); | |
241 } | |
242 while ((xev.type != MapNotify) || (xev.xmap.event != mywindow)); | |
243 | |
244 XSelectInput(mDisplay, mywindow, NoEventMask); | |
245 | |
246 XGetGeometry(mDisplay, mywindow, &mRoot, &drwX, &drwY, &drwWidth, | |
247 &drwHeight, &drwBorderWidth, &drwDepth); | |
248 drwX = drwY = 0; | |
249 XTranslateCoordinates(mDisplay, mywindow, mRoot, 0, 0, &drwcX, &drwcY, &mRoot); | |
250 | |
251 window_x = drwcX; | |
252 window_y = drwcY; | |
253 window_width = drwWidth; | |
254 window_height = drwHeight; | |
255 | |
256 mp_msg(MSGT_VO, MSGL_INFO, "[xvidix] image properties: %dx%d depth: %d\n", | |
257 image_width, image_height, image_depth); | |
258 mp_msg(MSGT_VO, MSGL_INFO, "[xvidix] window properties: pos: %dx%d, size: %dx%d\n", | |
259 window_x, window_y, window_width, window_height); | |
260 | |
261 if (vidix_init(image_width, image_height, window_x, window_y, window_width, | |
4133 | 262 window_height, format, vo_depthonscreen, vo_screenwidth, vo_screenheight) != 0) |
4123 | 263 { |
264 mp_msg(MSGT_VO, MSGL_FATAL, "Can't initialize VIDIX driver: %s: %s\n", | |
265 vidix_name, strerror(errno)); | |
266 vidix_term(); | |
267 return(-1); | |
268 } | |
269 | |
270 XFlush(mDisplay); | |
271 XSync(mDisplay, False); | |
272 | |
273 XSelectInput(mDisplay, mywindow, StructureNotifyMask | KeyPressMask ); | |
274 | |
275 saver_off(mDisplay); /* turning off screen saver */ | |
276 | |
277 return(0); | |
278 } | |
279 | |
280 static const vo_info_t *get_info(void) | |
281 { | |
282 return(&vo_info); | |
283 } | |
284 | |
285 static void Terminate_Display_Process(void) | |
286 { | |
287 getchar(); /* wait for enter to remove window */ | |
288 vidix_term(); | |
289 XDestroyWindow(mDisplay, mywindow); | |
290 XCloseDisplay(mDisplay); | |
291 X_already_started = 0; | |
4125 | 292 |
293 return; | |
4123 | 294 } |
295 | |
296 static void check_events(void) | |
297 { | |
298 const int event = vo_x11_check_events(mDisplay); | |
4125 | 299 |
4123 | 300 if (event & VO_EVENT_RESIZE) |
301 resize(vo_dwidth, vo_dheight); | |
4125 | 302 return; |
4123 | 303 } |
304 | |
305 /* draw_osd, flip_page, draw_slice, draw_frame should be | |
306 overwritten with vidix functions (vosub_vidix.c) */ | |
307 static void draw_osd(void) | |
308 { | |
309 mp_msg(MSGT_VO, MSGL_FATAL, "[xvidix] error: didn't used vidix draw_osd!\n"); | |
310 return; | |
311 } | |
312 | |
313 static void flip_page(void) | |
314 { | |
315 mp_msg(MSGT_VO, MSGL_FATAL, "[xvidix] error: didn't used vidix flip_page!\n"); | |
316 return; | |
317 } | |
318 | |
319 static uint32_t draw_slice(uint8_t *src[], int stride[], | |
320 int w, int h, int x, int y) | |
321 { | |
322 mp_msg(MSGT_VO, MSGL_FATAL, "[xvidix] error: didn't used vidix draw_slice!\n"); | |
323 return(0); | |
324 } | |
325 | |
326 static uint32_t draw_frame(uint8_t *src[]) | |
327 { | |
328 mp_msg(MSGT_VO, MSGL_FATAL, "[xvidix] error: didn't used vidix draw_frame!\n"); | |
329 return(0); | |
330 } | |
331 | |
332 static uint32_t query_format(uint32_t format) | |
333 { | |
4132
84ecfd03c86a
test for preinit errors and correct handling subdevice
nick
parents:
4131
diff
changeset
|
334 static int first = 1; |
84ecfd03c86a
test for preinit errors and correct handling subdevice
nick
parents:
4131
diff
changeset
|
335 if(first) |
84ecfd03c86a
test for preinit errors and correct handling subdevice
nick
parents:
4131
diff
changeset
|
336 { |
84ecfd03c86a
test for preinit errors and correct handling subdevice
nick
parents:
4131
diff
changeset
|
337 first = 0; |
4125 | 338 if (vidix_name == (char *)(-1)) |
339 { | |
340 if (vo_subdevice) | |
341 vidix_name = strdup(vo_subdevice); | |
342 else | |
343 { | |
344 mp_msg(MSGT_VO, MSGL_INFO, "No vidix driver name provided, probing available drivers!\n"); | |
345 vidix_name = NULL; | |
346 } | |
347 } | |
348 | |
349 if (vidix_preinit(vidix_name, &video_out_xvidix) != 0) | |
4132
84ecfd03c86a
test for preinit errors and correct handling subdevice
nick
parents:
4131
diff
changeset
|
350 { |
84ecfd03c86a
test for preinit errors and correct handling subdevice
nick
parents:
4131
diff
changeset
|
351 pre_init_err = 1; |
4125 | 352 return(0); |
4132
84ecfd03c86a
test for preinit errors and correct handling subdevice
nick
parents:
4131
diff
changeset
|
353 } |
84ecfd03c86a
test for preinit errors and correct handling subdevice
nick
parents:
4131
diff
changeset
|
354 } |
84ecfd03c86a
test for preinit errors and correct handling subdevice
nick
parents:
4131
diff
changeset
|
355 return pre_init_err ? 0 : vidix_query_fourcc(format); |
4123 | 356 } |
357 | |
358 | |
359 static void uninit(void) | |
360 { | |
361 #ifdef HAVE_NEW_GUI | |
362 if (vo_window == None) | |
363 #endif | |
364 { | |
365 vidix_term(); | |
366 saver_on(mDisplay); /* screen saver back on */ | |
367 XDestroyWindow(mDisplay, mywindow); | |
368 // XCloseDisplay(mDisplay); | |
369 } | |
370 } |