summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel Freitas <miguelfreitas@users.sourceforge.net>2003-11-26 01:03:31 +0000
committerMiguel Freitas <miguelfreitas@users.sourceforge.net>2003-11-26 01:03:31 +0000
commitf7c890258f736dc45ae81e2097df6c9658e93606 (patch)
treeeed0d30d99ebbdc649d7fb20329ec2911357b877
parent1daacd9d5b53cac2671d2bd9c93a3daa629254ea (diff)
downloadxine-lib-f7c890258f736dc45ae81e2097df6c9658e93606.tar.gz
xine-lib-f7c890258f736dc45ae81e2097df6c9658e93606.tar.bz2
* new unscaled overlay feature (using XShape extension)
text subtitles may now be rendered at full screen resolution * load xine fonts on demand - faster startup note: support added to xv, xshm and vidix CVS patchset: 5780 CVS date: 2003/11/26 01:03:31
-rw-r--r--misc/xine-fontconv.c4
-rw-r--r--src/libspudec/spu.c3
-rw-r--r--src/libspudec/xine_decoder.c4
-rw-r--r--src/libsputext/xine_decoder.c93
-rw-r--r--src/video_out/Makefile.am10
-rw-r--r--src/video_out/video_out_fb.c10
-rw-r--r--src/video_out/video_out_opengl.c6
-rw-r--r--src/video_out/video_out_sdl.c15
-rw-r--r--src/video_out/video_out_syncfb.c11
-rw-r--r--src/video_out/video_out_vidix.c97
-rw-r--r--src/video_out/video_out_xshm.c124
-rw-r--r--src/video_out/video_out_xv.c91
-rw-r--r--src/video_out/video_out_xvmc.c11
-rw-r--r--src/video_out/x11osd.c375
-rw-r--r--src/video_out/x11osd.h20
-rw-r--r--src/xine-engine/osd.c308
-rw-r--r--src/xine-engine/osd.h10
-rw-r--r--src/xine-engine/video_out.h13
18 files changed, 978 insertions, 227 deletions
diff --git a/misc/xine-fontconv.c b/misc/xine-fontconv.c
index 7a92417db..333e50e63 100644
--- a/misc/xine-fontconv.c
+++ b/misc/xine-fontconv.c
@@ -446,7 +446,7 @@ void render_font (FT_Face face, char *fontname, int size, int thickness,
error = FT_Get_Glyph( face->glyph, &glyph );
if( i == 0 ) {
- out_bitmap = create_bitmap( f266CeilToInt(MAX(face->glyph->metrics.horiAdvance, face->glyph->metrics.width + face->glyph->metrics.horiBearingX)),
+ out_bitmap = create_bitmap( f266CeilToInt(thickness + MAX(face->glyph->metrics.horiAdvance, face->glyph->metrics.width + face->glyph->metrics.horiBearingX)),
f266CeilToInt((max_bearing_y<<6) - face->glyph->metrics.horiBearingY +
face->glyph->metrics.height + thickness) );
}
@@ -581,6 +581,8 @@ int main(int argc, char *argv[]) {
render_font (face, argv[2], 20, thickness, unicodes);
render_font (face, argv[2], 24, thickness, unicodes);
render_font (face, argv[2], 32, thickness, unicodes);
+ render_font (face, argv[2], 48, thickness, unicodes);
+ render_font (face, argv[2], 64, thickness, unicodes);
list_free(unicodes);
diff --git a/src/libspudec/spu.c b/src/libspudec/spu.c
index 2270f6bb3..cd4219781 100644
--- a/src/libspudec/spu.c
+++ b/src/libspudec/spu.c
@@ -35,7 +35,7 @@
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: spu.c,v 1.71 2003/11/12 17:53:01 mroi Exp $
+ * $Id: spu.c,v 1.72 2003/11/26 01:03:31 miguelfreitas Exp $
*
*/
@@ -752,6 +752,7 @@ static void spudec_draw_picture (spudec_state_t *state, spudec_seq_t* seq, vo_ov
ovl->num_rle = rle - ovl->rle;
ovl->rgb_clut = 0;
+ ovl->unscaled = 0;
#ifdef LOG_DEBUG
printf ("spu: Num RLE=%d\n",ovl->num_rle);
printf ("spu: Date size=%d\n",ovl->data_size);
diff --git a/src/libspudec/xine_decoder.c b/src/libspudec/xine_decoder.c
index 1ef5bc841..3207f78dc 100644
--- a/src/libspudec/xine_decoder.c
+++ b/src/libspudec/xine_decoder.c
@@ -19,7 +19,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine_decoder.c,v 1.100 2003/10/23 20:12:33 mroi Exp $
+ * $Id: xine_decoder.c,v 1.101 2003/11/26 01:03:32 miguelfreitas Exp $
*
* stuff needed to turn libspu into a xine decoder plugin
*/
@@ -312,7 +312,7 @@ static spu_decoder_t *open_plugin (spu_decoder_class_t *class_gen, xine_stream_t
this->menu_handle = -1;
this->buttonN = 1;
- this->event.object.overlay = malloc(sizeof(vo_overlay_t));
+ this->event.object.overlay = xine_xmalloc(sizeof(vo_overlay_t));
pthread_mutex_init(&this->nav_pci_lock, NULL);
diff --git a/src/libsputext/xine_decoder.c b/src/libsputext/xine_decoder.c
index 2e0157b5c..c856dd827 100644
--- a/src/libsputext/xine_decoder.c
+++ b/src/libsputext/xine_decoder.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine_decoder.c,v 1.65 2003/11/11 18:44:54 f1rmb Exp $
+ * $Id: xine_decoder.c,v 1.66 2003/11/26 01:03:32 miguelfreitas Exp $
*
*/
@@ -49,6 +49,8 @@ typedef enum {
SUBTITLE_SIZE_SMALL,
SUBTITLE_SIZE_NORMAL,
SUBTITLE_SIZE_LARGE,
+ SUBTITLE_SIZE_VERY_LARGE,
+ SUBTITLE_SIZE_HUGE,
SUBTITLE_SIZE_NUM /* number of values in enum */
} subtitle_size;
@@ -62,6 +64,7 @@ typedef struct sputext_class_s {
int vertical_offset;
char font[FONTNAME_SIZE]; /* subtitle font */
char *src_encoding; /* encoding of subtitle file */
+ int use_unscaled; /* use unscaled OSD if possible */
xine_t *xine;
@@ -97,11 +100,12 @@ typedef struct sputext_decoder_s {
int64_t img_duration;
int64_t last_subtitle_end; /* no new subtitle before this vpts */
+ int unscaled; /* use unscaled OSD */
} sputext_decoder_t;
static void update_font_size (sputext_decoder_t *this) {
- static int sizes[SUBTITLE_SIZE_NUM] = { 16, 20, 24, 32 };
+ static int sizes[SUBTITLE_SIZE_NUM] = { 16, 20, 24, 32, 48, 64 };
int y;
@@ -125,8 +129,60 @@ static void update_font_size (sputext_decoder_t *this) {
this->renderer->set_font (this->osd, this->class->font, this->font_size);
this->renderer->set_position (this->osd, 0, y);
}
+
}
+static void update_output_size (sputext_decoder_t *this) {
+ int unscaled;
+
+ unscaled = this->class->use_unscaled &&
+ (this->stream->video_out->get_capabilities(this->stream->video_out) &
+ VO_CAP_UNSCALED_OVERLAY);
+ if( unscaled != this->unscaled ) {
+ this->unscaled = unscaled;
+ this->width = 0; /* force update */
+ }
+
+ /* initialize decoder if needed */
+ if( this->unscaled ) {
+ if( this->width != this->stream->video_out->get_property(this->stream->video_out,
+ VO_PROP_WINDOW_WIDTH) ||
+ this->height != this->stream->video_out->get_property(this->stream->video_out,
+ VO_PROP_WINDOW_HEIGHT) ||
+ !this->img_duration || !this->osd ) {
+
+ int width, height; /* dummy */
+
+ if( this->stream->video_out->status(this->stream->video_out, NULL,
+ &width, &height, &this->img_duration )) {
+
+ this->width = this->stream->video_out->get_property(this->stream->video_out,
+ VO_PROP_WINDOW_WIDTH);
+ this->height = this->stream->video_out->get_property(this->stream->video_out,
+ VO_PROP_WINDOW_HEIGHT);
+
+ if( this->width && this->height && this->img_duration ) {
+ this->renderer = this->stream->osd_renderer;
+
+ update_font_size (this);
+ }
+ }
+ }
+ } else {
+ if( !this->width || !this->height || !this->img_duration || !this->osd ) {
+
+ if( this->stream->video_out->status(this->stream->video_out, NULL,
+ &this->width, &this->height, &this->img_duration )) {
+
+ if( this->width && this->height && this->img_duration ) {
+ this->renderer = this->stream->osd_renderer;
+
+ update_font_size (this);
+ }
+ }
+ }
+ }
+}
static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t sub_end ) {
@@ -182,7 +238,10 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su
this->last_subtitle_end = sub_end;
this->renderer->set_text_palette (this->osd, -1, OSD_TEXT1);
- this->renderer->show (this->osd, sub_start);
+ if (this->unscaled)
+ this->renderer->show_unscaled (this->osd, sub_start);
+ else
+ this->renderer->show (this->osd, sub_start);
this->renderer->hide (this->osd, sub_end);
#ifdef LOG
@@ -246,19 +305,7 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
while(this->seek_count == extra_info.seek_count) {
- /* initialize decoder if needed */
- if( !this->width || !this->height || !this->img_duration || !this->osd ) {
-
- if( this->stream->video_out->status(this->stream->video_out, NULL,
- &this->width, &this->height, &this->img_duration )) {
-
- if( this->width && this->height && this->img_duration ) {
- this->renderer = this->stream->osd_renderer;
-
- update_font_size (this);
- }
- }
- }
+ update_output_size( this );
if( this->osd ) {
@@ -398,6 +445,13 @@ static void update_subtitle_size(void *class_gen, xine_cfg_entry_t *entry)
class->subtitle_size = entry->num_value;
}
+static void update_use_unscaled(void *class_gen, xine_cfg_entry_t *entry)
+{
+ sputext_class_t *class = (sputext_class_t *)class_gen;
+
+ class->use_unscaled = entry->num_value;
+}
+
static spu_decoder_t *sputext_class_open_plugin (spu_decoder_class_t *class_gen, xine_stream_t *stream) {
sputext_class_t *class = (sputext_class_t *)class_gen;
@@ -442,7 +496,7 @@ static void update_src_encoding(void *class_gen, xine_cfg_entry_t *entry)
static void *init_spu_decoder_plugin (xine_t *xine, void *data) {
static char *subtitle_size_strings[] = {
- "tiny", "small", "normal", "large", NULL
+ "tiny", "small", "normal", "large", "very large", "huge", NULL
};
sputext_class_t *this ;
@@ -480,6 +534,11 @@ static void *init_spu_decoder_plugin (xine_t *xine, void *data) {
"iso-8859-1",
_("Encoding of subtitles"),
NULL, 10, update_src_encoding, this);
+ this->use_unscaled = xine->config->register_bool(xine->config,
+ "misc.spu_use_unscaled_osd",
+ 1,
+ _("Use unscale OSD if possible"),
+ NULL, 0, update_use_unscaled, this);
return &this->class;
}
diff --git a/src/video_out/Makefile.am b/src/video_out/Makefile.am
index 0f5936412..43489bf9c 100644
--- a/src/video_out/Makefile.am
+++ b/src/video_out/Makefile.am
@@ -17,6 +17,7 @@ libdir = $(XINE_PLUGINDIR)
if HAVE_X11
xshm_module = xineplug_vo_out_xshm.la
syncfb_module = xineplug_vo_out_syncfb.la
+X11OSD = x11osd.c
if HAVE_XV
xv_module = xineplug_vo_out_xv.la
endif
@@ -66,7 +67,8 @@ lib_LTLIBRARIES = $(xshm_module) $(xv_module) $(xvmc_module) $(aa_module) $(pgx6
$(vidix_module) $(fb_module) $(sdl_module) $(syncfb_module) \
$(stk_module) $(directfb_module) xineplug_vo_out_none.la
-xineplug_vo_out_xv_la_SOURCES = deinterlace.c alphablend.c video_out_xv.c
+xineplug_vo_out_xv_la_SOURCES = deinterlace.c alphablend.c video_out_xv.c \
+ $(X11OSD)
xineplug_vo_out_xv_la_LIBADD = \
$(XV_LIB) \
$(X_LIBS) \
@@ -84,7 +86,7 @@ xineplug_vo_out_xvmc_la_LIBADD = \
xineplug_vo_out_xvmc_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
xineplug_vo_out_xshm_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c \
- alphablend.c video_out_xshm.c
+ alphablend.c video_out_xshm.c $(X11OSD)
xineplug_vo_out_xshm_la_LIBADD = $(MLIB_LIBS) $(X_LIBS) -lXext $(XINE_LIB)
xineplug_vo_out_xshm_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
@@ -115,7 +117,7 @@ xineplug_vo_out_sdl_la_SOURCES = alphablend.c video_out_sdl.c
xineplug_vo_out_sdl_la_LIBADD = $(SDL_LIBS) $(XINE_LIB)
xineplug_vo_out_sdl_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
-xineplug_vo_out_vidix_la_SOURCES = alphablend.c video_out_vidix.c
+xineplug_vo_out_vidix_la_SOURCES = alphablend.c video_out_vidix.c $(X11OSD)
xineplug_vo_out_vidix_la_LIBADD = $(X_LIBS) \
$(top_builddir)/src/video_out/vidix/libvidix.la \
$(top_builddir)/src/video_out/libdha/libdha.la
@@ -133,4 +135,4 @@ xineplug_vo_out_stk_la_LIBADD = $(LIBSTK_LIBS)
xineplug_vo_out_stk_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
noinst_HEADERS = alphablend.h deinterlace.h video_out_syncfb.h \
- yuv2rgb.h video_out_win32.h
+ yuv2rgb.h video_out_win32.h x11osd.h
diff --git a/src/video_out/video_out_fb.c b/src/video_out/video_out_fb.c
index 0d7c8ff73..5fa3df6e6 100644
--- a/src/video_out/video_out_fb.c
+++ b/src/video_out/video_out_fb.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_fb.c,v 1.31 2003/11/11 18:45:00 f1rmb Exp $
+ * $Id: video_out_fb.c,v 1.32 2003/11/26 01:03:32 miguelfreitas Exp $
*
* video_out_fb.c, frame buffer xine driver by Miguel Freitas
*
@@ -617,8 +617,14 @@ static int fb_get_property(vo_driver_t *this_gen, int property)
return this->sc.user_ratio;
case VO_PROP_BRIGHTNESS:
- return this->yuv2rgb_gamma;
+ return this->yuv2rgb_gamma;
+ case VO_PROP_WINDOW_WIDTH:
+ return this->sc.gui_width;
+
+ case VO_PROP_WINDOW_HEIGHT:
+ return this->sc.gui_height;
+
default:
printf("video_out_fb: tried to get unsupported "
"property %d\n", property);
diff --git a/src/video_out/video_out_opengl.c b/src/video_out/video_out_opengl.c
index 42f4cc9e0..ffe00340d 100644
--- a/src/video_out/video_out_opengl.c
+++ b/src/video_out/video_out_opengl.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_opengl.c,v 1.31 2003/11/11 18:45:00 f1rmb Exp $
+ * $Id: video_out_opengl.c,v 1.32 2003/11/26 01:03:32 miguelfreitas Exp $
*
* video_out_glut.c, glut based OpenGL rendering interface for xine
* Matthias Hopf <mat@mshopf.de>
@@ -749,6 +749,10 @@ static int opengl_get_property (vo_driver_t *this_gen, int property) {
return this->sc.user_ratio ;
case VO_PROP_BRIGHTNESS:
return this->yuv2rgb_gamma;
+ case VO_PROP_WINDOW_WIDTH:
+ return this->sc.gui_width;
+ case VO_PROP_WINDOW_HEIGHT:
+ return this->sc.gui_height;
default:
printf ("video_out_opengl: tried to get unsupported property %d\n",
property);
diff --git a/src/video_out/video_out_sdl.c b/src/video_out/video_out_sdl.c
index 3711855d4..18c9c962d 100644
--- a/src/video_out/video_out_sdl.c
+++ b/src/video_out/video_out_sdl.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_sdl.c,v 1.31 2003/11/11 18:45:00 f1rmb Exp $
+ * $Id: video_out_sdl.c,v 1.32 2003/11/26 01:03:32 miguelfreitas Exp $
*
* video_out_sdl.c, Simple DirectMedia Layer
*
@@ -355,10 +355,15 @@ static void sdl_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
static int sdl_get_property (vo_driver_t *this_gen, int property) {
sdl_driver_t *this = (sdl_driver_t *) this_gen;
-
- if ( property == VO_PROP_ASPECT_RATIO)
- return this->sc.user_ratio ;
-
+
+ switch (property) {
+ case VO_PROP_WINDOW_WIDTH:
+ return this->sc.gui_width;
+ case VO_PROP_WINDOW_HEIGHT:
+ return this->sc.gui_height;
+ case VO_PROP_ASPECT_RATIO:
+ return this->sc.user_ratio;
+ }
return 0;
}
diff --git a/src/video_out/video_out_syncfb.c b/src/video_out/video_out_syncfb.c
index ea301fd99..4aa89fa69 100644
--- a/src/video_out/video_out_syncfb.c
+++ b/src/video_out/video_out_syncfb.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_syncfb.c,v 1.92 2003/11/11 18:45:00 f1rmb Exp $
+ * $Id: video_out_syncfb.c,v 1.93 2003/11/26 01:03:32 miguelfreitas Exp $
*
* video_out_syncfb.c, SyncFB (for Matrox G200/G400 cards) interface for xine
*
@@ -644,6 +644,15 @@ static int syncfb_get_property(vo_driver_t* this_gen, int property)
{
syncfb_driver_t* this = (syncfb_driver_t *) this_gen;
+ switch (property) {
+ case VO_PROP_WINDOW_WIDTH:
+ this->props[property].value = this->sc.gui_width;
+ break;
+ case VO_PROP_WINDOW_HEIGHT:
+ this->props[property].value = this->sc.gui_height;
+ break;
+ }
+
return this->props[property].value;
}
diff --git a/src/video_out/video_out_vidix.c b/src/video_out/video_out_vidix.c
index c6d32fa45..66bd8cf6d 100644
--- a/src/video_out/video_out_vidix.c
+++ b/src/video_out/video_out_vidix.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_vidix.c,v 1.51 2003/11/11 18:45:00 f1rmb Exp $
+ * $Id: video_out_vidix.c,v 1.52 2003/11/26 01:03:32 miguelfreitas Exp $
*
* video_out_vidix.c
*
@@ -58,6 +58,10 @@
#include "alphablend.h"
#include "xineutils.h"
#include "vo_scale.h"
+
+#ifdef HAVE_X11
+#include "x11osd.h"
+#endif
/*
#define LOG
@@ -122,6 +126,8 @@ struct vidix_driver_s {
int screen;
Drawable drawable;
GC gc;
+ x11osd *xoverlay;
+ int ovl_changed;
#endif
/* fb related stuff */
@@ -574,6 +580,34 @@ static void vidix_update_frame_format (vo_driver_t *this_gen,
frame->ratio = ratio;
}
+static void vidix_overlay_begin (vo_driver_t *this_gen,
+ vo_frame_t *frame_gen, int changed) {
+#ifdef HAVE_X11
+ vidix_driver_t *this = (vidix_driver_t *) this_gen;
+
+ this->ovl_changed = changed;
+
+ if( this->ovl_changed && this->xoverlay ) {
+ XLockDisplay (this->display);
+ x11osd_clear(this->xoverlay);
+ XUnlockDisplay (this->display);
+ }
+#endif
+}
+
+static void vidix_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img) {
+#ifdef HAVE_X11
+ vidix_driver_t *this = (vidix_driver_t *) this_gen;
+
+ if( this->ovl_changed && this->xoverlay ) {
+ XLockDisplay (this->display);
+ x11osd_expose(this->xoverlay);
+ XUnlockDisplay (this->display);
+ }
+
+ this->ovl_changed = 0;
+#endif
+}
/*
*
@@ -581,12 +615,23 @@ static void vidix_update_frame_format (vo_driver_t *this_gen,
static void vidix_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) {
vidix_frame_t *frame = (vidix_frame_t *) frame_gen;
+ vidix_driver_t *this = (vidix_driver_t *) this_gen;
if (overlay->rle) {
- if( frame->format == XINE_IMGFMT_YV12 )
- blend_yuv( frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches);
- else
- blend_yuy2( frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0]);
+ if( overlay->unscaled ) {
+#ifdef HAVE_X11
+ if( this->ovl_changed && this->xoverlay ) {
+ XLockDisplay (this->display);
+ x11osd_blend(this->xoverlay, overlay);
+ XUnlockDisplay (this->display);
+ }
+#endif
+ } else {
+ if( frame->format == XINE_IMGFMT_YV12 )
+ blend_yuv( frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches);
+ else
+ blend_yuy2( frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0]);
+ }
}
}
@@ -658,6 +703,15 @@ static int vidix_get_property (vo_driver_t *this_gen, int property) {
vidix_driver_t *this = (vidix_driver_t *) this_gen;
+ switch (property) {
+ case VO_PROP_WINDOW_WIDTH:
+ this->props[property].value = this->sc.gui_width;
+ break;
+ case VO_PROP_WINDOW_HEIGHT:
+ this->props[property].value = this->sc.gui_height;
+ break;
+ }
+
#ifdef LOG
printf ("video_out_vidix: property #%d = %d\n", property,
this->props[property].value);
@@ -827,6 +881,8 @@ static int vidix_gui_data_exchange (vo_driver_t *this_gen,
XLockDisplay(this->display);
XFreeGC(this->display, this->gc);
this->gc = XCreateGC(this->display, this->drawable, 0, NULL);
+ if(this->xoverlay)
+ x11osd_drawable_changed(this->xoverlay, this->drawable);
XUnlockDisplay(this->display);
#endif
}
@@ -837,6 +893,14 @@ static int vidix_gui_data_exchange (vo_driver_t *this_gen,
printf ("video_out_vidix: GUI_DATA_EX_EXPOSE_EVENT\n");
#endif
vidix_clean_output_area(this);
+#ifdef HAVE_X11
+ XLockDisplay (this->display);
+ if(this->xoverlay)
+ x11osd_expose(this->xoverlay);
+
+ XSync(this->display, False);
+ XUnlockDisplay (this->display);
+#endif
break;
case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO:
@@ -871,6 +935,16 @@ static void vidix_exit (vo_driver_t *this_gen) {
vdlPlaybackOff(this->vidix_handler);
}
vdlClose(this->vidix_handler);
+
+#ifdef HAVE_X11
+ if( this->xoverlay ) {
+ XLockDisplay (this->display);
+ x11osd_destroy (this->xoverlay);
+ XUnlockDisplay (this->display);
+ }
+#endif
+
+ free (this);
}
static vidix_driver_t *open_plugin (video_driver_class_t *class_gen) {
@@ -975,9 +1049,9 @@ static vidix_driver_t *open_plugin (video_driver_class_t *class_gen) {
this->vo_driver.get_capabilities = vidix_get_capabilities;
this->vo_driver.alloc_frame = vidix_alloc_frame;
this->vo_driver.update_frame_format = vidix_update_frame_format;
- this->vo_driver.overlay_begin = NULL; /* not used */
+ this->vo_driver.overlay_begin = vidix_overlay_begin;
this->vo_driver.overlay_blend = vidix_overlay_blend;
- this->vo_driver.overlay_end = NULL; /* not used */
+ this->vo_driver.overlay_end = vidix_overlay_end;
this->vo_driver.display_frame = vidix_display_frame;
this->vo_driver.get_property = vidix_get_property;
this->vo_driver.set_property = vidix_set_property;
@@ -1079,6 +1153,8 @@ static vo_driver_t *vidix_open_plugin (video_driver_class_t *class_gen, const vo
this->screen = visual->screen;
this->drawable = visual->d;
this->gc = XCreateGC(this->display, this->drawable, 0, NULL);
+ this->xoverlay = NULL;
+ this->ovl_changed = 0;
XGetWindowAttributes(this->display, this->drawable, &window_attributes);
this->sc.gui_width = window_attributes.width;
@@ -1112,6 +1188,13 @@ static vo_driver_t *vidix_open_plugin (video_driver_class_t *class_gen, const vo
query_fourccs(this);
+ XLockDisplay (this->display);
+ this->xoverlay = x11osd_create (this->display, this->screen, this->drawable);
+ XUnlockDisplay (this->display);
+
+ if( this->xoverlay )
+ this->capabilities |= VO_CAP_UNSCALED_OVERLAY;
+
return &this->vo_driver;
}
diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c
index 51193a0ef..5ec9b31aa 100644
--- a/src/video_out/video_out_xshm.c
+++ b/src/video_out/video_out_xshm.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_xshm.c,v 1.119 2003/11/11 18:45:00 f1rmb Exp $
+ * $Id: video_out_xshm.c,v 1.120 2003/11/26 01:03:32 miguelfreitas Exp $
*
* video_out_xshm.c, X11 shared memory extension interface for xine
*
@@ -59,6 +59,7 @@
#include "yuv2rgb.h"
#include "xineutils.h"
#include "vo_scale.h"
+#include "x11osd.h"
/*
#define LOG
@@ -110,7 +111,8 @@ typedef struct {
vo_scale_t sc;
xshm_frame_t *cur_frame;
- vo_overlay_t *overlay;
+ x11osd *xoverlay;
+ int ovl_changed;
int (*x11_old_error_handler) (Display *, XErrorEvent *);
@@ -303,7 +305,13 @@ static void dispose_ximage (xshm_driver_t *this,
*/
static uint32_t xshm_get_capabilities (vo_driver_t *this_gen) {
- return VO_CAP_YV12 | VO_CAP_YUY2;
+ xshm_driver_t *this = (xshm_driver_t *) this_gen;
+ uint32_t capabilities = VO_CAP_YV12 | VO_CAP_YUY2;
+
+ if( this->xoverlay )
+ capabilities |= VO_CAP_UNSCALED_OVERLAY;
+
+ return capabilities;
}
static void xshm_frame_proc_slice (vo_frame_t *vo_img, uint8_t **src) {
@@ -597,38 +605,71 @@ static void xshm_overlay_clut_yuv2rgb(xshm_driver_t *this, vo_overlay_t *overla
}
}
+static void xshm_overlay_begin (vo_driver_t *this_gen,
+ vo_frame_t *frame_gen, int changed) {
+ xshm_driver_t *this = (xshm_driver_t *) this_gen;
+
+ this->ovl_changed = changed;
+
+ if( this->ovl_changed && this->xoverlay ) {
+ XLockDisplay (this->display);
+ x11osd_clear(this->xoverlay);
+ XUnlockDisplay (this->display);
+ }
+}
+
+static void xshm_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img) {
+ xshm_driver_t *this = (xshm_driver_t *) this_gen;
+
+ if( this->ovl_changed && this->xoverlay ) {
+ XLockDisplay (this->display);
+ x11osd_expose(this->xoverlay);
+ XUnlockDisplay (this->display);
+ }
+
+ this->ovl_changed = 0;
+}
+
static void xshm_overlay_blend (vo_driver_t *this_gen,
vo_frame_t *frame_gen, vo_overlay_t *overlay) {
xshm_driver_t *this = (xshm_driver_t *) this_gen;
xshm_frame_t *frame = (xshm_frame_t *) frame_gen;
/* Alpha Blend here */
- if (overlay->rle) {
- if (!overlay->rgb_clut || !overlay->clip_rgb_clut)
- xshm_overlay_clut_yuv2rgb (this, overlay, frame);
-
- switch (this->bpp) {
- case 16:
- blend_rgb16 ((uint8_t *)frame->image->data, overlay,
- frame->sc.output_width, frame->sc.output_height,
- frame->sc.delivered_width, frame->sc.delivered_height);
- break;
- case 24:
- blend_rgb24 ((uint8_t *)frame->image->data, overlay,
- frame->sc.output_width, frame->sc.output_height,
- frame->sc.delivered_width, frame->sc.delivered_height);
- break;
- case 32:
- blend_rgb32 ((uint8_t *)frame->image->data, overlay,
- frame->sc.output_width, frame->sc.output_height,
- frame->sc.delivered_width, frame->sc.delivered_height);
- break;
- default:
- printf("xine-lib:video_out_xshm:xshm_overlay_blend: Cannot blend bpp:%i\n", this->bpp);
+ if (overlay->rle) {
+ if( overlay->unscaled ) {
+ if( this->ovl_changed && this->xoverlay ) {
+ XLockDisplay (this->display);
+ x11osd_blend(this->xoverlay, overlay);
+ XUnlockDisplay (this->display);
+ }
+ } else {
+ if (!overlay->rgb_clut || !overlay->clip_rgb_clut)
+ xshm_overlay_clut_yuv2rgb (this, overlay, frame);
+
+ switch (this->bpp) {
+ case 16:
+ blend_rgb16 ((uint8_t *)frame->image->data, overlay,
+ frame->sc.output_width, frame->sc.output_height,
+ frame->sc.delivered_width, frame->sc.delivered_height);
+ break;
+ case 24:
+ blend_rgb24 ((uint8_t *)frame->image->data, overlay,
+ frame->sc.output_width, frame->sc.output_height,
+ frame->sc.delivered_width, frame->sc.delivered_height);
+ break;
+ case 32:
+ blend_rgb32 ((uint8_t *)frame->image->data, overlay,
+ frame->sc.output_width, frame->sc.output_height,
+ frame->sc.delivered_width, frame->sc.delivered_height);
+ break;
+ default:
+ printf("xine-lib:video_out_xshm:xshm_overlay_blend: Cannot blend bpp:%i\n", this->bpp);
/* it should never get here, unless a user tries to play in bpp:8 */
break;
- }
- }
+ }
+ }
+ }
}
static void clean_output_area (xshm_driver_t *this, xshm_frame_t *frame) {
@@ -742,6 +783,10 @@ static int xshm_get_property (vo_driver_t *this_gen, int property) {
return this->yuv2rgb_contrast;
case VO_PROP_SATURATION:
return this->yuv2rgb_saturation;
+ case VO_PROP_WINDOW_WIDTH:
+ return this->sc.gui_width;
+ case VO_PROP_WINDOW_HEIGHT:
+ return this->sc.gui_height;
default:
if (this->xine->verbosity >= XINE_VERBOSITY_LOG) {
printf ("video_out_xshm: tried to get unsupported property %d\n",
@@ -866,6 +911,9 @@ static int xshm_gui_data_exchange (vo_driver_t *this_gen,
this->sc.border[i].w, this->sc.border[i].h);
}
+ if(this->xoverlay)
+ x11osd_expose(this->xoverlay);
+
XSync(this->display, False);
XUnlockDisplay (this->display);
}
@@ -878,6 +926,8 @@ static int xshm_gui_data_exchange (vo_driver_t *this_gen,
XLockDisplay (this->display);
XFreeGC(this->display, this->gc);
this->gc = XCreateGC (this->display, this->drawable, 0, NULL);
+ if(this->xoverlay)
+ x11osd_drawable_changed(this->xoverlay, this->drawable);
XUnlockDisplay (this->display);
break;
@@ -915,6 +965,12 @@ static void xshm_dispose (vo_driver_t *this_gen) {
this->yuv2rgb_factory->dispose (this->yuv2rgb_factory);
+ if( this->xoverlay ) {
+ XLockDisplay (this->display);
+ x11osd_destroy (this->xoverlay);
+ XUnlockDisplay (this->display);
+ }
+
free (this);
}
@@ -1018,16 +1074,18 @@ static vo_driver_t *xshm_open_plugin (video_driver_class_t *class_gen, const voi
XLockDisplay(this->display);
this->gc = XCreateGC (this->display, this->drawable, 0, NULL);
XUnlockDisplay(this->display);
-
+ this->xoverlay = NULL;
+ this->ovl_changed = 0;
+
this->x11_old_error_handler = NULL;
this->xine = class->xine;
this->vo_driver.get_capabilities = xshm_get_capabilities;
this->vo_driver.alloc_frame = xshm_alloc_frame;
this->vo_driver.update_frame_format = xshm_update_frame_format;
- this->vo_driver.overlay_begin = NULL; /* not used */
+ this->vo_driver.overlay_begin = xshm_overlay_begin;
this->vo_driver.overlay_blend = xshm_overlay_blend;
- this->vo_driver.overlay_end = NULL; /* not used */
+ this->vo_driver.overlay_end = xshm_overlay_end;
this->vo_driver.display_frame = xshm_display_frame;
this->vo_driver.get_property = xshm_get_property;
this->vo_driver.set_property = xshm_set_property;
@@ -1177,7 +1235,11 @@ static vo_driver_t *xshm_open_plugin (video_driver_class_t *class_gen, const voi
this->yuv2rgb_brightness,
this->yuv2rgb_contrast,
this->yuv2rgb_saturation);
-
+
+ XLockDisplay (this->display);
+ this->xoverlay = x11osd_create (this->display, this->screen, this->drawable);
+ XUnlockDisplay (this->display);
+
return &this->vo_driver;
}
diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c
index 5c35d77be..cdb102b26 100644
--- a/src/video_out/video_out_xv.c
+++ b/src/video_out/video_out_xv.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_xv.c,v 1.181 2003/11/11 18:45:00 f1rmb Exp $
+ * $Id: video_out_xv.c,v 1.182 2003/11/26 01:03:32 miguelfreitas Exp $
*
* video_out_xv.c, X11 video extension interface for xine
*
@@ -29,6 +29,7 @@
* xine-specific code by Guenter Bartsch <bartscgr@studbox.uni-stuttgart.de>
*
* overlay support by James Courtier-Dutton <James@superbug.demon.co.uk> - July 2001
+ * X11 unscaled overlay support by Miguel Freitas - Nov 2003
*/
#ifdef HAVE_CONFIG_H
@@ -71,6 +72,7 @@
#include "deinterlace.h"
#include "xineutils.h"
#include "vo_scale.h"
+#include "x11osd.h"
/*
#define LOG
@@ -126,7 +128,8 @@ struct xv_driver_s {
xv_frame_t *recent_frames[VO_NUM_RECENT_FRAMES];
xv_frame_t *cur_frame;
- vo_overlay_t *overlay;
+ x11osd *xoverlay;
+ int ovl_changed;
/* all scaling information goes here */
vo_scale_t sc;
@@ -607,21 +610,51 @@ static void xv_compute_output_size (xv_driver_t *this) {
}
}
+static void xv_overlay_begin (vo_driver_t *this_gen,
+ vo_frame_t *frame_gen, int changed) {
+ xv_driver_t *this = (xv_driver_t *) this_gen;
+
+ this->ovl_changed = changed;
+
+ if( this->ovl_changed && this->xoverlay ) {
+ XLockDisplay (this->display);
+ x11osd_clear(this->xoverlay);
+ XUnlockDisplay (this->display);
+ }
+}
+
+static void xv_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img) {
+ xv_driver_t *this = (xv_driver_t *) this_gen;
+
+ if( this->ovl_changed && this->xoverlay ) {
+ XLockDisplay (this->display);
+ x11osd_expose(this->xoverlay);
+ XUnlockDisplay (this->display);
+ }
+
+ this->ovl_changed = 0;
+}
+
static void xv_overlay_blend (vo_driver_t *this_gen,
vo_frame_t *frame_gen, vo_overlay_t *overlay) {
+ xv_driver_t *this = (xv_driver_t *) this_gen;
xv_frame_t *frame = (xv_frame_t *) frame_gen;
- /* Alpha Blend here
- * As XV drivers improve to support Hardware overlay, we will change this function.
- */
-
if (overlay->rle) {
- if (frame->format == XINE_IMGFMT_YV12)
- blend_yuv(frame->vo_frame.base, overlay,
- frame->width, frame->height, frame->vo_frame.pitches);
- else
- blend_yuy2(frame->vo_frame.base[0], overlay,
- frame->width, frame->height, frame->vo_frame.pitches[0]);
+ if( overlay->unscaled ) {
+ if( this->ovl_changed && this->xoverlay ) {
+ XLockDisplay (this->display);
+ x11osd_blend(this->xoverlay, overlay);
+ XUnlockDisplay (this->display);
+ }
+ } else {
+ if (frame->format == XINE_IMGFMT_YV12)
+ blend_yuv(frame->vo_frame.base, overlay,
+ frame->width, frame->height, frame->vo_frame.pitches);
+ else
+ blend_yuy2(frame->vo_frame.base[0], overlay,
+ frame->width, frame->height, frame->vo_frame.pitches[0]);
+ }
}
}
@@ -756,6 +789,15 @@ static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
static int xv_get_property (vo_driver_t *this_gen, int property) {
xv_driver_t *this = (xv_driver_t *) this_gen;
+ switch (property) {
+ case VO_PROP_WINDOW_WIDTH:
+ this->props[property].value = this->sc.gui_width;
+ break;
+ case VO_PROP_WINDOW_HEIGHT:
+ this->props[property].value = this->sc.gui_height;
+ break;
+ }
+
if (this->xine->verbosity >= XINE_VERBOSITY_LOG)
printf ("video_out_xv: property #%d = %d\n", property,
this->props[property].value);
@@ -915,6 +957,9 @@ static int xv_gui_data_exchange (vo_driver_t *this_gen,
this->sc.border[i].w, this->sc.border[i].h);
}
+ if(this->xoverlay)
+ x11osd_expose(this->xoverlay);
+
XSync(this->display, False);
XUnlockDisplay (this->display);
}
@@ -927,6 +972,8 @@ static int xv_gui_data_exchange (vo_driver_t *this_gen,
XLockDisplay (this->display);
XFreeGC(this->display, this->gc);
this->gc = XCreateGC (this->display, this->drawable, 0, NULL);
+ if(this->xoverlay)
+ x11osd_drawable_changed(this->xoverlay, this->drawable);
XUnlockDisplay (this->display);
this->sc.force_redraw = 1;
break;
@@ -988,6 +1035,12 @@ static void xv_dispose (vo_driver_t *this_gen) {
this->recent_frames[i] = NULL;
}
+ if( this->xoverlay ) {
+ XLockDisplay (this->display);
+ x11osd_destroy (this->xoverlay);
+ XUnlockDisplay (this->display);
+ }
+
free (this);
}
@@ -1143,7 +1196,6 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
memset (this, 0, sizeof(xv_driver_t));
this->display = visual->display;
- this->overlay = NULL;
this->screen = visual->screen;
this->xv_port = class->xv_port;
this->config = config;
@@ -1162,6 +1214,8 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
this->deinterlace_frame.image = NULL;
this->use_colorkey = 0;
this->colorkey = 0;
+ this->xoverlay = NULL;
+ this->ovl_changed = 0;
this->x11_old_error_handler = NULL;
this->xine = class->xine;
@@ -1174,9 +1228,9 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
this->vo_driver.get_capabilities = xv_get_capabilities;
this->vo_driver.alloc_frame = xv_alloc_frame;
this->vo_driver.update_frame_format = xv_update_frame_format;
- this->vo_driver.overlay_begin = NULL; /* not used */
+ this->vo_driver.overlay_begin = xv_overlay_begin;
this->vo_driver.overlay_blend = xv_overlay_blend;
- this->vo_driver.overlay_end = NULL; /* not used */
+ this->vo_driver.overlay_end = xv_overlay_end;
this->vo_driver.display_frame = xv_display_frame;
this->vo_driver.get_property = xv_get_property;
this->vo_driver.set_property = xv_set_property;
@@ -1322,6 +1376,13 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
NULL, 10, xv_update_deinterlace, this);
this->deinterlace_enabled = 0;
+ XLockDisplay (this->display);
+ this->xoverlay = x11osd_create (this->display, this->screen, this->drawable);
+ XUnlockDisplay (this->display);
+
+ if( this->xoverlay )
+ this->capabilities |= VO_CAP_UNSCALED_OVERLAY;
+
return &this->vo_driver;
}
diff --git a/src/video_out/video_out_xvmc.c b/src/video_out/video_out_xvmc.c
index 91f90530d..547cf5804 100644
--- a/src/video_out/video_out_xvmc.c
+++ b/src/video_out/video_out_xvmc.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_xvmc.c,v 1.7 2003/11/11 18:45:00 f1rmb Exp $
+ * $Id: video_out_xvmc.c,v 1.8 2003/11/26 01:03:32 miguelfreitas Exp $
*
* video_out_xvmc.c, X11 video motion compensation extension interface for xine
*
@@ -1023,6 +1023,15 @@ static int xvmc_get_property (vo_driver_t *this_gen, int property) {
lprintf ("video_out_xvmc: xvmc_get_property\n");
+ switch (property) {
+ case VO_PROP_WINDOW_WIDTH:
+ this->props[property].value = this->sc.gui_width;
+ break;
+ case VO_PROP_WINDOW_HEIGHT:
+ this->props[property].value = this->sc.gui_height;
+ break;
+ }
+
return this->props[property].value;
}
diff --git a/src/video_out/x11osd.c b/src/video_out/x11osd.c
new file mode 100644
index 000000000..c94f2bd26
--- /dev/null
+++ b/src/video_out/x11osd.c
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2003 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: x11osd.c,v 1.1 2003/11/26 01:03:32 miguelfreitas Exp $
+ *
+ * x11osd.c, use X11 Nonrectangular Window Shape Extension to draw xine OSD
+ *
+ * Nov 2003 - Miguel Freitas
+ *
+ * based on ideas and code of
+ * xosd Copyright (c) 2000 Andre Renaud (andre@ignavus.net)
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <time.h>
+
+#include <assert.h>
+
+#include <netinet/in.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/shape.h>
+#include <X11/Xatom.h>
+
+#include "xine_internal.h"
+#include "alphablend.h"
+#include "x11osd.h"
+
+struct x11osd
+{
+ Display *display;
+ int screen;
+ Window window;
+ Window parent_window;
+ unsigned int depth;
+ Pixmap mask_bitmap;
+ Pixmap bitmap;
+ Visual *visual;
+ Colormap cmap;
+
+ GC gc;
+ GC mask_gc;
+ GC mask_gc_back;
+
+ int width;
+ int height;
+ int x;
+ int y;
+ int clean;
+ int mapped;
+};
+
+
+void
+x11osd_expose (x11osd * osd)
+{
+ assert (osd);
+
+ if( !osd->clean ) {
+
+ XShapeCombineMask (osd->display, osd->window, ShapeBounding, 0, 0,
+ osd->mask_bitmap, ShapeSet);
+
+ if( !osd->mapped )
+ XMapRaised (osd->display, osd->window);
+ osd->mapped = 1;
+
+ XCopyArea (osd->display, osd->bitmap, osd->window, osd->gc, 0, 0,
+ osd->width, osd->height, 0, 0);
+ } else {
+ if( osd->mapped )
+ XUnmapWindow (osd->display, osd->window);
+ osd->mapped = 0;
+ }
+}
+
+
+void
+x11osd_resize (x11osd * osd, int width, int height)
+{
+ assert (osd);
+ osd->width = width;
+ osd->height = height;
+
+ XResizeWindow (osd->display, osd->window, osd->width, osd->height);
+ XFreePixmap (osd->display, osd->mask_bitmap);
+ osd->mask_bitmap =
+ XCreatePixmap (osd->display, osd->window, osd->width, osd->height,
+ 1);
+ XFillRectangle (osd->display, osd->mask_bitmap, osd->mask_gc_back,
+ 0, 0, osd->width, osd->height);
+
+ XFreePixmap (osd->display, osd->bitmap);
+ osd->bitmap =
+ XCreatePixmap (osd->display, osd->window, osd->width,
+ osd->height, osd->depth);
+}
+
+void
+x11osd_drawable_changed (x11osd * osd, Window window)
+{
+ assert (osd);
+
+/*
+ Do I need to recreate the GC's??
+
+ XFreeGC (osd->display, osd->gc);
+ XFreeGC (osd->display, osd->mask_gc);
+ XFreeGC (osd->display, osd->mask_gc_back);
+*/
+ XFreePixmap (osd->display, osd->bitmap);
+ XFreePixmap (osd->display, osd->mask_bitmap);
+ XFreeColormap (osd->display, osd->cmap);
+ XDestroyWindow (osd->display, osd->window);
+
+
+ osd->parent_window = window;
+ osd->window = XCreateSimpleWindow (osd->display,
+ osd->parent_window,
+ 0, 0,
+ osd->width, osd->height, 1,
+ BlackPixel (osd->display, osd->screen),
+ BlackPixel (osd->display, osd->screen));
+
+ osd->mask_bitmap =
+ XCreatePixmap (osd->display, osd->window, osd->width, osd->height,
+ 1);
+ XFillRectangle (osd->display, osd->mask_bitmap, osd->mask_gc_back,
+ 0, 0, osd->width, osd->height);
+
+ osd->bitmap =
+ XCreatePixmap (osd->display, osd->window, osd->width,
+ osd->height, osd->depth);
+
+ osd->cmap = XCreateColormap(osd->display, osd->window,
+ osd->visual, AllocNone);
+
+ XSelectInput (osd->display, osd->window, ExposureMask);
+}
+
+
+x11osd *
+x11osd_create (Display *display, int screen, Window window)
+{
+ x11osd *osd;
+ int event_basep, error_basep;
+
+ osd = malloc (sizeof (x11osd));
+ memset (osd, 0, sizeof (x11osd));
+ if (osd == NULL)
+ return NULL;
+
+ osd->display = display;
+ osd->screen = screen;
+ osd->parent_window = window;
+
+ if (!XShapeQueryExtension (osd->display, &event_basep, &error_basep))
+ goto error2;
+
+ osd->visual = DefaultVisual (osd->display, osd->screen);
+ osd->depth = DefaultDepth (osd->display, osd->screen);
+ osd->width = XDisplayWidth (osd->display, osd->screen);
+ osd->height = XDisplayHeight (osd->display, osd->screen);
+
+ osd->window = XCreateSimpleWindow (osd->display,
+ osd->parent_window,
+ 0, 0,
+ osd->width, osd->height, 1,
+ BlackPixel (osd->display, osd->screen),
+ BlackPixel (osd->display, osd->screen));
+
+ osd->mask_bitmap =
+ XCreatePixmap (osd->display, osd->window, osd->width, osd->height,
+ 1);
+ osd->bitmap =
+ XCreatePixmap (osd->display, osd->window, osd->width,
+ osd->height, osd->depth);
+
+ osd->gc = XCreateGC (osd->display, osd->window, 0, NULL);
+ osd->mask_gc = XCreateGC (osd->display, osd->mask_bitmap, 0, NULL);
+ osd->mask_gc_back = XCreateGC (osd->display, osd->mask_bitmap, 0, NULL);
+
+ XSetForeground (osd->display, osd->mask_gc_back,
+ BlackPixel (osd->display, osd->screen));
+ XSetBackground (osd->display, osd->mask_gc_back,
+ WhitePixel (osd->display, osd->screen));
+
+ XSetForeground (osd->display, osd->mask_gc,
+ WhitePixel (osd->display, osd->screen));
+ XSetBackground (osd->display, osd->mask_gc,
+ BlackPixel (osd->display, osd->screen));
+
+ osd->cmap = XCreateColormap(osd->display, osd->window,
+ osd->visual, AllocNone);
+
+ XSelectInput (osd->display, osd->window, ExposureMask);
+
+ osd->clean = 0;
+ x11osd_clear(osd);
+ osd->mapped = 0;
+ x11osd_expose(osd);
+
+ return osd;
+
+/*
+error3:
+ XFreeGC (osd->display, osd->gc);
+ XFreeGC (osd->display, osd->mask_gc);
+ XFreeGC (osd->display, osd->mask_gc_back);
+ XFreePixmap (osd->display, osd->bitmap);
+ XFreePixmap (osd->display, osd->mask_bitmap);
+ XDestroyWindow (osd->display, osd->window);
+*/
+error2:
+ free (osd);
+ return NULL;
+}
+
+void
+x11osd_destroy (x11osd * osd)
+{
+
+ assert (osd);
+
+ XFreeGC (osd->display, osd->gc);
+ XFreeGC (osd->display, osd->mask_gc);
+ XFreeGC (osd->display, osd->mask_gc_back);
+ XFreePixmap (osd->display, osd->bitmap);
+ XFreePixmap (osd->display, osd->mask_bitmap);
+ XFreeColormap (osd->display, osd->cmap);
+ XDestroyWindow (osd->display, osd->window);
+
+ free (osd);
+}
+
+void x11osd_clear(x11osd *osd)
+{
+ if( !osd->clean )
+ XFillRectangle (osd->display, osd->mask_bitmap, osd->mask_gc_back,
+ 0, 0, osd->width, osd->height);
+ osd->clean = 1;
+}
+
+#define TRANSPARENT 0xffffffff
+
+#define saturate(n, l, u) ((n) < (l) ? (l) : ((n) > (u) ? (u) : (n)))
+
+void x11osd_blend(x11osd *osd, vo_overlay_t *overlay)
+{
+ if (overlay->rle) {
+ int i, x, y, len, width;
+ int use_clip_palette, max_palette_colour[2];
+ uint32_t palette[2][OVL_PALETTE_SIZE];
+
+ max_palette_colour[0] = -1;
+ max_palette_colour[1] = -1;
+
+ for (i=0, x=0, y=0; i<overlay->num_rle; i++) {
+ len = overlay->rle[i].len;
+
+ while (len > 0) {
+ use_clip_palette = 0;
+ if (len > overlay->width) {
+ width = overlay->width;
+ len -= overlay->width;
+ }
+ else {
+ width = len;
+ len = 0;
+ }
+ if ((y >= overlay->clip_top) && (y <= overlay->clip_bottom) && (x <= overlay->clip_right)) {
+ if ((x < overlay->clip_left) && (x + width - 1 >= overlay->clip_left)) {
+ width -= overlay->clip_left - x;
+ len += overlay->clip_left - x;
+ }
+ else if (x > overlay->clip_left) {
+ use_clip_palette = 1;
+ if (x + width - 1 > overlay->clip_right) {
+ width -= overlay->clip_right - x;
+ len += overlay->clip_right - x;
+ }
+ }
+ }
+
+ if (overlay->rle[i].color > max_palette_colour[use_clip_palette]) {
+ int j;
+ clut_t *src_clut;
+ uint8_t *src_trans;
+
+ if (use_clip_palette) {
+ src_clut = (clut_t *)&overlay->clip_color;
+ src_trans = (uint8_t *)&overlay->clip_trans;
+ }
+ else {
+ src_clut = (clut_t *)&overlay->color;
+ src_trans = (uint8_t *)&overlay->trans;
+ }
+ for (j=max_palette_colour[use_clip_palette]+1; j<=overlay->rle[i].color; j++) {
+ if (src_trans[j]) {
+ if (1) {
+ XColor xcolor;
+ int y, u, v, r, g, b;
+
+ y = saturate(src_clut[j].y, 16, 235);
+ u = saturate(src_clut[j].cb, 16, 240);
+ v = saturate(src_clut[j].cr, 16, 240);
+ y = (9 * y) / 8;
+ r = y + (25 * v) / 16 - 218;
+ xcolor.red = (65536 * saturate(r, 0, 255)) / 256;
+ g = y + (-13 * v) / 16 + (-25 * u) / 64 + 136;
+ xcolor.green = (65536 * saturate(g, 0, 255)) / 256;
+ b = y + 2 * u - 274;
+ xcolor.blue = (65536 * saturate(b, 0, 255)) / 256;
+
+ xcolor.flags = DoRed | DoBlue | DoGreen;
+
+ XAllocColor(osd->display, osd->cmap, &xcolor);
+
+ palette[use_clip_palette][j] = xcolor.pixel;
+ }
+ else {
+ if (src_clut[j].y > 127) {
+ palette[use_clip_palette][j] = WhitePixel(osd->display, osd->screen);
+ }
+ else {
+ palette[use_clip_palette][j] = BlackPixel(osd->display, osd->screen);
+ }
+ }
+ }
+ else {
+ palette[use_clip_palette][j] = TRANSPARENT;
+ }
+ }
+ max_palette_colour[use_clip_palette] = overlay->rle[i].color;
+ }
+
+ if(palette[use_clip_palette][overlay->rle[i].color] != TRANSPARENT) {
+ XSetForeground(osd->display, osd->gc, palette[use_clip_palette][overlay->rle[i].color]);
+ XFillRectangle(osd->display, osd->bitmap, osd->gc, overlay->x + x, overlay->y + y, width, 1);
+ XFillRectangle(osd->display, osd->mask_bitmap, osd->mask_gc, overlay->x + x, overlay->y + y, width, 1);
+ }
+
+ x += width;
+ if (x == overlay->width) {
+ x = 0;
+ y++;
+ }
+ }
+ }
+ }
+ osd->clean = 0;
+}
+
diff --git a/src/video_out/x11osd.h b/src/video_out/x11osd.h
new file mode 100644
index 000000000..3d74df780
--- /dev/null
+++ b/src/video_out/x11osd.h
@@ -0,0 +1,20 @@
+#ifndef X11OSD_H
+#define X11OSD_H
+
+ typedef struct x11osd x11osd;
+
+ x11osd *x11osd_create (Display *display, int screen, Window window);
+
+ void x11osd_destroy (x11osd * osd);
+
+ void x11osd_expose (x11osd * osd);
+
+ void x11osd_resize (x11osd * osd, int width, int height);
+
+ void x11osd_drawable_changed (x11osd * osd, Window window);
+
+ void x11osd_clear(x11osd *osd);
+
+ void x11osd_blend(x11osd *osd, vo_overlay_t *overlay);
+
+#endif
diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c
index 17c97d50b..2e8ff0637 100644
--- a/src/xine-engine/osd.c
+++ b/src/xine-engine/osd.c
@@ -21,7 +21,12 @@
*/
#define __OSD_C__
-
+
+/*
+#define LOG_VERBOSE 1
+#define LOG 1
+*/
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -54,9 +59,7 @@
#include FT_FREETYPE_H
#endif
-/*
-#define LOG_DEBUG 1
-*/
+#define FONT_VERSION 2
#define BINARY_SEARCH 1
@@ -89,11 +92,13 @@ typedef struct osd_fontchar_s {
struct osd_font_s {
char name[40];
+ char *filename;
uint16_t version;
uint16_t size;
uint16_t num_fontchars;
osd_fontchar_t *fontchar;
osd_font_t *next;
+ int loaded;
};
#ifdef HAVE_FT2
@@ -146,9 +151,7 @@ static osd_object_t *osd_new_object (osd_renderer_t *this, int width, int height
pthread_mutex_unlock (&this->osd_mutex);
-#ifdef LOG_DEBUG
- printf("osd_open %p [%dx%d]\n", osd, width, height);
-#endif
+ lprintf("osd=%p size: %dx%d\n", osd, width, height);
return osd;
}
@@ -159,16 +162,14 @@ static osd_object_t *osd_new_object (osd_renderer_t *this, int width, int height
* send the osd to be displayed at given pts (0=now)
* the object is not changed. there may be subsequent drawing on it.
*/
-static int osd_show (osd_object_t *osd, int64_t vpts ) {
+static int _osd_show (osd_object_t *osd, int64_t vpts, int unscaled ) {
osd_renderer_t *this = osd->renderer;
rle_elem_t rle, *rle_p=0;
int x, y, spare;
uint8_t *c;
-#ifdef LOG_DEBUG
- printf("osd_show %p vpts=%lld\n", osd, vpts);
-#endif
+ lprintf("osd=%p vpts=%lld\n", osd, vpts);
if( osd->handle < 0 ) {
if( (osd->handle = this->video_overlay->get_handle(this->video_overlay,0)) == -1 ) {
@@ -193,6 +194,7 @@ static int osd_show (osd_object_t *osd, int64_t vpts ) {
osd->y2 = osd->height;
memset( this->event.object.overlay, 0, sizeof(*this->event.object.overlay) );
+ this->event.object.overlay->unscaled = unscaled;
this->event.object.overlay->x = osd->display_x + osd->x1;
this->event.object.overlay->y = osd->display_y + osd->y1;
this->event.object.overlay->width = osd->x2 - osd->x1 + 1;
@@ -239,9 +241,7 @@ static int osd_show (osd_object_t *osd, int64_t vpts ) {
this->event.object.overlay->num_rle++;
}
-#ifdef LOG_DEBUG
- printf("osd_show num_rle = %d\n", this->event.object.overlay->num_rle);
-#endif
+ lprintf("num_rle = %d\n", this->event.object.overlay->num_rle);
memcpy(this->event.object.overlay->clip_color, osd->color, sizeof(osd->color));
memcpy(this->event.object.overlay->clip_trans, osd->trans, sizeof(osd->trans));
@@ -257,6 +257,20 @@ static int osd_show (osd_object_t *osd, int64_t vpts ) {
return 1;
}
+/* normal OSD show
+ * overlay is blended and scaled together with the stream.
+ */
+static int osd_show_scaled (osd_object_t *osd, int64_t vpts) {
+ return _osd_show(osd, vpts, 0);
+}
+
+/* unscaled OSD show
+ * overlay is blended at output (screen) resolution.
+ */
+static int osd_show_unscaled (osd_object_t *osd, int64_t vpts) {
+ return _osd_show(osd, vpts, 1);
+}
+
/*
* send event to hide osd at given pts (0=now)
* the object is not changed. there may be subsequent drawing on it.
@@ -265,9 +279,7 @@ static int osd_hide (osd_object_t *osd, int64_t vpts) {
osd_renderer_t *this = osd->renderer;
-#ifdef LOG_DEBUG
- printf("osd_hide %p vpts=%lld\n",osd, vpts);
-#endif
+ lprintf("osd=%p vpts=%lld\n",osd, vpts);
if( osd->handle < 0 )
return 0;
@@ -294,9 +306,7 @@ static int osd_hide (osd_object_t *osd, int64_t vpts) {
*/
static void osd_clear (osd_object_t *osd) {
-#ifdef LOG_DEBUG
- printf("osd_clear\n");
-#endif
+ lprintf("osd=%p\n",osd);
memset(osd->area, 0, osd->width * osd->height);
osd->x1 = osd->width;
@@ -312,9 +322,7 @@ static void osd_clear (osd_object_t *osd) {
static void osd_point (osd_object_t *osd, int x, int y, int color) {
uint8_t *c;
-#ifdef LOG_DEBUG
- printf("osd_point %p (%d x %d)\n", osd, x, y);
-#endif
+ lprintf("osd=%p (%d x %d)\n", osd, x, y);
/* update clipping area */
osd->x1 = MIN(osd->x1, x);
@@ -337,9 +345,7 @@ static void osd_line (osd_object_t *osd,
uint8_t *c;
int dx, dy, t, inc, d, inc1, inc2;
-#ifdef LOG_DEBUG
- printf("osd_line %p (%d,%d)-(%d,%d)\n",osd, x1,y1, x2,y2 );
-#endif
+ lprintf("osd=%p (%d,%d)-(%d,%d)\n",osd, x1,y1, x2,y2 );
/* update clipping area */
t = MIN( x1, x2 );
@@ -428,9 +434,7 @@ static void osd_filled_rect (osd_object_t *osd,
int x, y, dx, dy;
-#ifdef LOG_DEBUG
- printf("osd_filled_rect %p (%d,%d)-(%d,%d)\n",osd, x1,y1, x2,y2 );
-#endif
+ lprintf("osd=%p (%d,%d)-(%d,%d)\n",osd, x1,y1, x2,y2 );
/* update clipping area */
x = MIN( x1, x2 );
@@ -525,65 +529,101 @@ static int osd_renderer_load_font(osd_renderer_t *this, char *filename) {
osd_font_t *font = NULL;
int i, ret = 0;
-#ifdef LOG_DEBUG
- printf("osd: renderer_load_font %p name=%s\n", this, filename );
-#endif
-
- pthread_mutex_lock (&this->osd_mutex);
+ lprintf("name=%s\n", filename );
/* load quick & dirt font format */
- /* fixme: check read errors... */
+ /* fixme: check for all read errors... */
if( (fp = gzopen(filename,"rb")) != NULL ) {
font = xine_xmalloc( sizeof(osd_font_t) );
gzread(fp, font->name, sizeof(font->name) );
font->version = gzread_i16(fp);
- font->size = gzread_i16(fp);
- font->num_fontchars = gzread_i16(fp);
-
- font->fontchar = malloc( sizeof(osd_fontchar_t) * font->num_fontchars );
-
-#ifdef LOG_DEBUG
- printf("osd: font %s %d\n", font->name, font->num_fontchars);
-#endif
- for( i = 0; i < font->num_fontchars; i++ ) {
- font->fontchar[i].code = gzread_i16(fp);
- font->fontchar[i].width = gzread_i16(fp);
- font->fontchar[i].height = gzread_i16(fp);
- font->fontchar[i].bmp = malloc(font->fontchar[i].width*font->fontchar[i].height);
- if( gzread(fp, font->fontchar[i].bmp,
- font->fontchar[i].width*font->fontchar[i].height) <= 0 )
- break;
- }
- if( i == font->num_fontchars ) {
- ret = 1;
-
-#ifdef LOG_DEBUG
- printf("osd: font %s loading ok\n",font->name);
-#endif
-
- font->next = this->fonts;
- this->fonts = font;
- } else {
-
-#ifdef LOG_DEBUG
- printf("osd: font %s loading failed (%d < %d)\n",font->name,
- i, font->num_fontchars);
-#endif
-
- while( --i >= 0 ) {
- free(font->fontchar[i].bmp);
+ if( font->version == FONT_VERSION ) {
+
+ font->size = gzread_i16(fp);
+ font->num_fontchars = gzread_i16(fp);
+ font->loaded = 1;
+
+ font->fontchar = malloc( sizeof(osd_fontchar_t) * font->num_fontchars );
+
+ lprintf("font '%s' chars=%d\n", font->name, font->num_fontchars);
+
+ /* load all characters */
+ for( i = 0; i < font->num_fontchars; i++ ) {
+ font->fontchar[i].code = gzread_i16(fp);
+ font->fontchar[i].width = gzread_i16(fp);
+ font->fontchar[i].height = gzread_i16(fp);
+ font->fontchar[i].bmp = malloc(font->fontchar[i].width*font->fontchar[i].height);
+ if( gzread(fp, font->fontchar[i].bmp,
+ font->fontchar[i].width*font->fontchar[i].height) <= 0 )
+ break;
+ }
+
+ /* check if all expected characters were loaded */
+ if( i == font->num_fontchars ) {
+ osd_font_t *known_font;
+ ret = 1;
+
+ lprintf("font '%s' loaded\n",font->name);
+
+ /* check if font is already known to us */
+ known_font = this->fonts;
+ while( known_font ) {
+ if( !strcasecmp(known_font->name,font->name) &&
+ known_font->size == font->size )
+ break;
+ known_font = known_font->next;
+ }
+
+ if( !known_font ) {
+
+ /* new font, add it to list */
+ font->filename = strdup(filename);
+ font->next = this->fonts;
+ this->fonts = font;
+
+ } else {
+
+ if( !known_font->loaded ) {
+ /* the font was preloaded before.
+ * add loaded characters to the existing entry.
+ */
+ known_font->version = font->version;
+ known_font->num_fontchars = font->num_fontchars;
+ known_font->loaded = 1;
+ known_font->fontchar = font->fontchar;
+ } else {
+ printf("font '%s-%d' already loaded, weird.\n",
+ font->name, font->size);
+ while( --i >= 0 ) {
+ free(font->fontchar[i].bmp);
+ }
+ free(font->fontchar);
+ free(font);
+ }
+
+ }
+ } else {
+
+ printf("font '%s' loading failed (%d < %d)\n",font->name,
+ i, font->num_fontchars);
+
+ while( --i >= 0 ) {
+ free(font->fontchar[i].bmp);
+ }
+ free(font->fontchar);
+ free(font);
}
- free(font->fontchar);
+ } else {
+ printf("wrong version for font '%s'. expected %d found %d.\n",font->name,
+ font->version, FONT_VERSION);
free(font);
}
-
gzclose(fp);
}
- pthread_mutex_unlock (&this->osd_mutex);
return ret;
}
@@ -596,15 +636,13 @@ static int osd_renderer_unload_font(osd_renderer_t *this, char *fontname ) {
osd_object_t *osd;
int i, ret = 0;
-#ifdef LOG_DEBUG
- printf("osd_renderer_unload_font %p name=%s\n", this, fontname);
-#endif
+ lprintf("font '%s'\n", fontname);
pthread_mutex_lock (&this->osd_mutex);
osd = this->osds;
while( osd ) {
- if( !strcmp(osd->font->name, fontname) )
+ if( !strcasecmp(osd->font->name, fontname) )
osd->font = NULL;
osd = osd->next;
}
@@ -612,13 +650,17 @@ static int osd_renderer_unload_font(osd_renderer_t *this, char *fontname ) {
last = NULL;
font = this->fonts;
while( font ) {
- if ( !strcmp(font->name,fontname) ) {
+ if ( !strcasecmp(font->name,fontname) ) {
- for( i = 0; i < font->num_fontchars; i++ ) {
- free( font->fontchar[i].bmp );
+ free( font->filename );
+
+ if( font->loaded ) {
+ for( i = 0; i < font->num_fontchars; i++ ) {
+ free( font->fontchar[i].bmp );
+ }
+ free( font->fontchar );
}
- free( font->fontchar );
-
+
if( last )
last->next = font->next;
else
@@ -651,9 +693,7 @@ static int osd_set_font( osd_object_t *osd, const char *fontname, int size) {
int error_flag = 0;
#endif
-#ifdef LOG_DEBUG
- printf("osd_set_font %p name=%s\n", osd, fontname);
-#endif
+ lprintf("osd=%p font '%s'\n", osd, fontname);
pthread_mutex_lock (&this->osd_mutex);
@@ -662,19 +702,25 @@ static int osd_set_font( osd_object_t *osd, const char *fontname, int size) {
font = this->fonts;
while( font ) {
- if( !strcmp(font->name, fontname) && (size>=font->size)
+ if( !strcasecmp(font->name, fontname) && (size>=font->size)
&& (best<font->size)) {
ret = 1;
osd->font = font;
best = font->size;
-#ifdef LOG_DEBUG
- printf ("osd_set_font: font->name=%s, size=%d\n", font->name, font->size);
-#endif
+ lprintf ("best: font->name=%s, size=%d\n", font->name, font->size);
}
font = font->next;
}
-
+
+ if( ret ) {
+ /* load font if needed */
+ if( !osd->font->loaded )
+ ret = osd_renderer_load_font(this, osd->font->filename);
+ if(!ret)
+ osd->font = NULL;
+ }
+
#ifdef HAVE_FT2
if (osd->ft2) {
@@ -852,6 +898,8 @@ static int osd_set_encoding (osd_object_t *osd, const char *encoding) {
}
+#define FONT_OVERLAP 1/10 /* overlap between consecutive characters */
+
/*
* render text in current encoding on x,y position
* no \n yet
@@ -867,9 +915,7 @@ static int osd_render_text (osd_object_t *osd, int x1, int y1,
uint16_t unicode;
size_t inbytesleft;
-#ifdef LOG_DEBUG
- printf("osd_render_text %p (%d,%d) \"%s\"\n", osd, x1, y1, text);
-#endif
+ lprintf("osd=%p (%d,%d) \"%s\"\n", osd, x1, y1, text);
/* some sanity checks for the color indices */
if( color_base < 0 )
@@ -918,11 +964,9 @@ static int osd_render_text (osd_object_t *osd, int x1, int y1,
i = osd_search(font->fontchar, font->num_fontchars, unicode);
-#ifdef LOG_DEBUG
- printf("font %s [%d, U+%04X == U+%04X] %dx%d -> %d,%d\n", font->name, i,
+ lprintf("font '%s' [%d, U+%04X == U+%04X] %dx%d -> %d,%d\n", font->name, i,
unicode, font->fontchar[i].code, font->fontchar[i].width,
font->fontchar[i].height, x1, y1);
-#endif
#ifdef HAVE_FT2
} /* !(osd->ft2 && osd->ft2->useme) */
@@ -980,7 +1024,8 @@ static int osd_render_text (osd_object_t *osd, int x1, int y1,
uint8_t *s = src, *d = dst;
while (s < src + width) {
- if(d <= (osd->area + (osd->width * osd->height)))
+ if(d <= (osd->area + (osd->width * osd->height))
+ && *s > 1) /* skip drawing transparency */
*d = *s + (uint8_t) color_base;
d++;
@@ -989,7 +1034,7 @@ static int osd_render_text (osd_object_t *osd, int x1, int y1,
src += font->fontchar[i].width;
dst += osd->width;
}
- x1 += font->fontchar[i].width;
+ x1 += font->fontchar[i].width - (font->fontchar[i].width * FONT_OVERLAP);
if( x1 > osd->x2 ) osd->x2 = x1;
if( y1 + font->fontchar[i].height > osd->y2 )
@@ -1019,9 +1064,7 @@ static int osd_get_text_size(osd_object_t *osd, const char *text, int *width, in
uint16_t unicode;
size_t inbytesleft;
-#ifdef LOG_DEBUG
- printf("osd_get_text_size %p \"%s\"\n", osd, text);
-#endif
+ lprintf("osd=%p \"%s\"\n", osd, text);
pthread_mutex_lock (&this->osd_mutex);
@@ -1086,7 +1129,7 @@ static int osd_get_text_size(osd_object_t *osd, const char *text, int *width, in
if ( i != font->num_fontchars ) {
if( font->fontchar[i].height > *height )
*height = font->fontchar[i].height;
- *width += font->fontchar[i].width;
+ *width += font->fontchar[i].width - (font->fontchar[i].width * FONT_OVERLAP);
}
#ifdef HAVE_FT2
} /* !(osd->ft2 && osd->ft2->useme) */
@@ -1098,13 +1141,13 @@ static int osd_get_text_size(osd_object_t *osd, const char *text, int *width, in
return 1;
}
-static void osd_load_fonts (osd_renderer_t *this, char *path) {
+static void osd_preload_fonts (osd_renderer_t *this, char *path) {
DIR *dir;
- char pathname [1024];
+ osd_font_t *font;
+ char *pathname;
+ char *s, *p;
-#ifdef LOG_DEBUG
- printf ("osd: load_fonts, path=%s\n", path);
-#endif
+ lprintf ("path='%s'\n", path);
dir = opendir (path) ;
@@ -1112,31 +1155,37 @@ static void osd_load_fonts (osd_renderer_t *this, char *path) {
struct dirent *entry;
-#ifdef LOG_DEBUG
- printf ("osd: load_fonts, %s opened\n", path);
-#endif
-
while ((entry = readdir (dir)) != NULL) {
int len;
len = strlen (entry->d_name);
if ( (len>12) && !strncmp (&entry->d_name[len-12], ".xinefont.gz", 12)) {
-
-#ifdef LOG_DEBUG
- printf ("osd: trying to load font >%s< (ending >%s<)\n",
- entry->d_name,&entry->d_name[len-12]);
-#endif
-
- sprintf (pathname, "%s/%s", path, entry->d_name);
-
- osd_renderer_load_font (this, pathname);
+ s = strdup(entry->d_name);
+ p = strchr(s, '-');
+ if( p ) {
+ *p++ = '\0';
+ font = xine_xmalloc( sizeof(osd_font_t) );
+
+ strncpy(font->name, s, sizeof(font->name));
+ font->size = atoi(p);
+
+ lprintf("font '%s' size %d is preloaded\n",
+ font->name, font->size);
+
+ pathname = malloc(1024);
+ sprintf (pathname, "%s/%s", path, entry->d_name);
+ font->filename = pathname;
+
+ font->next = this->fonts;
+ this->fonts = font;
+ }
+ free(s);
}
}
closedir (dir);
-
}
}
@@ -1207,7 +1256,7 @@ static void update_text_palette(void *this_gen, xine_cfg_entry_t *entry)
osd_renderer_t *this = (osd_renderer_t *)this_gen;
this->textpalette = entry->num_value;
- printf("osd: text palette will be %s\n", textpalettes_str[this->textpalette] );
+ lprintf("palette will be '%s'\n", textpalettes_str[this->textpalette] );
}
static void osd_draw_bitmap(osd_object_t *osd, uint8_t *bitmap,
@@ -1216,9 +1265,7 @@ static void osd_draw_bitmap(osd_object_t *osd, uint8_t *bitmap,
{
int y, x;
-#ifdef LOG_DEBUG
- printf("osd_draw_bitmap %p at (%d,%d) %dx%d\n",osd, x1,y1, width,height );
-#endif
+ lprintf("osd=%p at (%d,%d) %dx%d\n",osd, x1,y1, width,height );
/* update clipping area */
osd->x1 = MIN( osd->x1, x1 );
@@ -1259,19 +1306,15 @@ osd_renderer_t *_x_osd_renderer_init( video_overlay_manager_t *video_overlay, co
pthread_mutex_init (&this->osd_mutex, NULL);
-#ifdef LOG_DEBUG
- printf("osd: _x_osd_renderer_init %p\n", this);
-#endif
-
/*
* load available fonts
*/
- osd_load_fonts (this, XINE_FONTDIR);
+ osd_preload_fonts (this, XINE_FONTDIR);
sprintf (str, "%s/.xine/fonts", xine_get_homedir ());
- osd_load_fonts (this, str);
+ osd_preload_fonts (this, str);
this->textpalette = config->register_enum (config, "misc.osd_text_palette", 0,
textpalettes_str,
@@ -1284,7 +1327,7 @@ osd_renderer_t *_x_osd_renderer_init( video_overlay_manager_t *video_overlay, co
this->new_object = osd_new_object;
this->free_object = osd_free_object;
- this->show = osd_show;
+ this->show = osd_show_scaled;
this->hide = osd_hide;
this->set_palette = osd_set_palette;
this->set_text_palette = osd_set_text_palette;
@@ -1300,6 +1343,7 @@ osd_renderer_t *_x_osd_renderer_init( video_overlay_manager_t *video_overlay, co
this->get_text_size = osd_get_text_size;
this->close = osd_renderer_close;
this->draw_bitmap = osd_draw_bitmap;
+ this->show_unscaled = osd_show_unscaled;
return this;
}
diff --git a/src/xine-engine/osd.h b/src/xine-engine/osd.h
index a0aa75b7f..9a58f1a7c 100644
--- a/src/xine-engine/osd.h
+++ b/src/xine-engine/osd.h
@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* OSD stuff (text and graphic primitives)
- * $Id: osd.h,v 1.20 2003/11/19 19:43:23 miguelfreitas Exp $
+ * $Id: osd.h,v 1.21 2003/11/26 01:03:32 miguelfreitas Exp $
*/
#ifndef HAVE_OSD_H
@@ -73,7 +73,6 @@ struct xine_osd_s {
osd_object_t osd;
};
-/* WARNING: this should be kept in sync with include/xine.h.in */
struct osd_renderer_s {
/*
@@ -201,6 +200,13 @@ struct osd_renderer_s {
int x1, int y1, int width, int height,
uint8_t *palette_map);
+ /*
+ * send the osd to be displayed (unscaled) at given pts (0=now)
+ * the object is not changed. there may be subsequent drawing on it.
+ * overlay is blended at output (screen) resolution.
+ */
+ int (*show_unscaled) (osd_object_t *osd, int64_t vpts );
+
/* private stuff */
pthread_mutex_t osd_mutex;
diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h
index 567f8ddfd..0f1e2db0e 100644
--- a/src/xine-engine/video_out.h
+++ b/src/xine-engine/video_out.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out.h,v 1.102 2003/11/15 14:54:31 miguelfreitas Exp $
+ * $Id: video_out.h,v 1.103 2003/11/26 01:03:32 miguelfreitas Exp $
*
*
* xine version of video_out.h
@@ -254,7 +254,9 @@ struct xine_video_port_s {
#define VO_PROP_MAX_NUM_FRAMES 11
#define VO_PROP_ZOOM_Y 13
#define VO_PROP_DISCARD_FRAMES 14 /* not used by drivers */
-#define VO_NUM_PROPERTIES 15
+#define VO_PROP_WINDOW_WIDTH 15 /* read-only */
+#define VO_PROP_WINDOW_HEIGHT 16 /* read-only */
+#define VO_NUM_PROPERTIES 17
/* number of colors in the overlay palette. Currently limited to 256
at most, because some alphablend functions use an 8-bit index into
@@ -280,6 +282,7 @@ struct xine_video_port_s {
#define VO_CAP_YUY2 0x00000002 /* driver can handle YUY2 pictures */
#define VO_CAP_XVMC_MOCOMP 0x00000004 /* driver can use XvMC motion compensation */
#define VO_CAP_XVMC_IDCT 0x00000008 /* driver can use XvMC idct acceleration */
+#define VO_CAP_UNSCALED_OVERLAY 0x00000010 /* driver can blend overlay at output resolution */
/* macroblock modes */
#define XINE_MACROBLOCK_INTRA 1
@@ -429,7 +432,7 @@ struct vo_overlay_s {
uint32_t color[OVL_PALETTE_SIZE]; /* color lookup table */
uint8_t trans[OVL_PALETTE_SIZE]; /* mixer key table */
- int rgb_clut; /* true if clut was converted to rgb*/
+ int rgb_clut; /* true if clut was converted to rgb */
int clip_top;
int clip_bottom;
@@ -437,8 +440,8 @@ struct vo_overlay_s {
int clip_right;
uint32_t clip_color[OVL_PALETTE_SIZE];
uint8_t clip_trans[OVL_PALETTE_SIZE];
- int clip_rgb_clut; /* true if clut was converted to rgb*/
-
+ int clip_rgb_clut; /* true if clut was converted to rgb */
+ int unscaled; /* true if it should be blended unscaled */
};