summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_out/Makefile.am7
-rw-r--r--src/video_out/video_out_pgx32.c824
-rw-r--r--src/video_out/video_out_pgx64.c82
3 files changed, 871 insertions, 42 deletions
diff --git a/src/video_out/Makefile.am b/src/video_out/Makefile.am
index f7288140d..a00573cba 100644
--- a/src/video_out/Makefile.am
+++ b/src/video_out/Makefile.am
@@ -32,6 +32,7 @@ syncfb_module = xineplug_vo_out_syncfb.la
endif
if HAVE_SUNFB
pgx64_module = xineplug_vo_out_pgx64.la
+pgx32_module = xineplug_vo_out_pgx32.la
endif
endif
@@ -71,7 +72,7 @@ endif
lib_LTLIBRARIES = $(xshm_module) $(xv_module) $(xvmc_module) \
$(opengl_module) \
$(syncfb_module) \
- $(pgx64_module)\
+ $(pgx64_module) $(pgx32_module)\
$(vidix_module) \
$(aa_module) \
$(fb_module) $(directfb_module) \
@@ -107,6 +108,10 @@ xineplug_vo_out_pgx64_la_SOURCES = alphablend.c video_out_pgx64.c
xineplug_vo_out_pgx64_la_LIBADD = $(X_LIBS)
xineplug_vo_out_pgx64_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
+xineplug_vo_out_pgx32_la_SOURCES = alphablend.c video_out_pgx32.c
+xineplug_vo_out_pgx32_la_LIBADD = $(X_LIBS)
+xineplug_vo_out_pgx32_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
+
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 \
diff --git a/src/video_out/video_out_pgx32.c b/src/video_out/video_out_pgx32.c
new file mode 100644
index 000000000..7ac66f41f
--- /dev/null
+++ b/src/video_out/video_out_pgx32.c
@@ -0,0 +1,824 @@
+/*
+ * Copyright (C) 2000-2004 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: video_out_pgx32.c,v 1.1 2004/02/17 19:44:02 komadori Exp $
+ *
+ * video_out_pgx32.c, Sun PGX32 output plugin for xine
+ *
+ * written and currently maintained by
+ * Robin Kay <komadori [at] gekkou [dot] co [dot] uk>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/fbio.h>
+#include <sys/visual_io.h>
+#include <sys/mman.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+
+#include "xine_internal.h"
+#include "alphablend.h"
+#include "bswap.h"
+#include "vo_scale.h"
+#include "xineutils.h"
+
+/* gfxp register defines */
+
+#define GFXP_VRAM_MMAPLEN 0x00800000
+#define GFXP_REGS_MMAPLEN 0x00020000
+#define GFXP_REGSBASE 0x00800000
+
+#define FIFO_SPACE 0x0003
+
+#define RASTERISER_MODE 0x1014
+#define SCISSOR_MODE 0x1030
+#define AREA_STIPPLE_MODE 0x1034
+#define WINDOW_ORIGIN 0x1039
+
+#define RECT_ORIGIN 0x101A
+#define RECT_SIZE 0x101B
+
+#define DY 0x1005
+
+#define TEXTURE_ADDR_MODE 0x1070
+#define SSTART 0x1071
+#define DSDX 0x1072
+#define DSDY_DOM 0x1073
+#define TSTART 0x1074
+#define DTDX 0x1075
+#define DTDY_DOM 0x1076
+
+#define TEXTURE_BASE_ADDR 0x10B0
+#define TEXTURE_MAP_FORMAT 0x10B1
+#define TEXTURE_DATA_FORMAT 0x10B2
+#define TEXTURE_READ_MODE 0x10CE
+#define TEXTURE_COLOUR_MODE 0x10D0
+
+#define SHADING_MODE 0x10FC
+#define ALPHA_BLENDING_MODE 0x1102
+#define DITHERING_MODE 0x1103
+#define LOGICAL_OP_MODE 0x1105
+#define STENCIL_MODE 0x1131
+
+#define READ_MODE 0x1150
+#define WRITE_MODE 0x1157
+#define WRITE_MASK 0x1158
+
+#define YUV_MODE 0x11E0
+
+#define RENDER 0x1007
+#define RENDER_BEGIN 0x00000000006020C0L
+
+static const int pitch_code_table[33][2] =
+{
+ {0, 0000},
+ {32, 0001},
+ {64, 0011},
+ {96, 0111},
+ {128, 0112},
+ {160, 0122},
+ {192, 0222},
+ {224, 0123},
+ {256, 0223},
+ {288, 0133},
+ {320, 0233},
+ {384, 0333},
+ {416, 0134},
+ {448, 0234},
+ {512, 0334},
+ {544, 0144},
+ {576, 0244},
+ {640, 0344},
+ {768, 0444},
+ {800, 0145},
+ {832, 0245},
+ {896, 0345},
+ {1024, 0445},
+ {1056, 0155},
+ {1088, 0255},
+ {1152, 0355},
+ {1280, 0455},
+ {1536, 0555},
+ {1568, 0156},
+ {1600, 0256},
+ {1664, 0356},
+ {1792, 0456},
+ {2048, 0556}
+};
+
+/* Structures */
+
+typedef struct {
+ video_driver_class_t vo_driver_class;
+
+ xine_t *xine;
+ config_values_t *config;
+
+ pthread_mutex_t mutex;
+ int instance_count;
+} pgx32_driver_class_t;
+
+typedef struct {
+ vo_frame_t vo_frame;
+
+ uint32_t *packedbuf, *stripe_dst;
+ int width, height, format, pitch, pitch_code, packedlen, lines_remaining;
+ double ratio;
+} pgx32_frame_t;
+
+typedef struct {
+ vo_driver_t vo_driver;
+ vo_scale_t vo_scale;
+
+ pgx32_driver_class_t *class;
+
+ pgx32_frame_t *current;
+
+ int fbfd, fb_width, fb_height, fb_depth, screen_pitch_code;
+ uint8_t *vbase;
+
+ Display *display;
+ int screen, depth;
+ Drawable drawable;
+ GC gc;
+ Visual *visual;
+
+ int delivered_format, deinterlace_en;
+} pgx32_driver_t;
+
+/*
+ * Dispose of any allocated image data within a pgx32_frame_t
+ */
+
+static void dispose_frame_internals(pgx32_frame_t *frame)
+{
+ if (frame->vo_frame.base[0]) {
+ free(frame->vo_frame.base[0]);
+ frame->vo_frame.base[0] = NULL;
+ }
+ if (frame->vo_frame.base[1]) {
+ free(frame->vo_frame.base[1]);
+ frame->vo_frame.base[1] = NULL;
+ }
+ if (frame->vo_frame.base[2]) {
+ free(frame->vo_frame.base[2]);
+ frame->vo_frame.base[2] = NULL;
+ }
+ if (frame->packedbuf) {
+ free(frame->packedbuf);
+ frame->packedbuf = NULL;
+ }
+}
+
+/*
+ * XINE VIDEO DRIVER FUNCTIONS
+ */
+
+static void pgx32_frame_proc_frame(vo_frame_t *frame_gen)
+{
+ pgx32_frame_t *frame = (pgx32_frame_t *)frame_gen;
+
+ frame->vo_frame.proc_called = 1;
+
+ switch (frame->format) {
+ case XINE_IMGFMT_YUY2: {
+ int i, x;
+ uint32_t *src, *dst, pixel;
+
+ src = (uint32_t *)(void *)frame->vo_frame.base[0];
+ dst = frame->stripe_dst;
+
+ for (i=0; i<frame->height; i++) {
+ for(x=0; x<frame->vo_frame.pitches[0]/4; x++) {
+ pixel = *(src++);
+ *(dst++) = (pixel >> 16) | ((pixel & 0xffff) << 16);
+ }
+ dst += (frame->pitch-frame->width)/2;
+ }
+ }
+ break;
+
+ case XINE_IMGFMT_YV12: {
+ int i, x;
+ uint16_t *yptr, y;
+ uint8_t *uptr, *vptr, u, v;
+ uint32_t *dst;
+
+ yptr = (uint16_t *)(void *)frame->vo_frame.base[0];
+ uptr = frame->vo_frame.base[1];
+ vptr = frame->vo_frame.base[2];
+ dst = frame->stripe_dst;
+
+ for (i=0; i<frame->height; i++) {
+ if (i & 1) {
+ uptr -= frame->vo_frame.pitches[1];
+ vptr -= frame->vo_frame.pitches[2];
+ }
+
+ for(x=0; x<frame->vo_frame.pitches[0]/2; x++) {
+ y = *(yptr++);
+ u = *(uptr++);
+ v = *(vptr++);
+ *(dst++) = u | (y & 0xff00) | (v << 16) | ((y & 0x00ff) << 24);
+ }
+ dst += (frame->pitch-frame->width)/2;
+ }
+ }
+ break;
+ }
+}
+
+static void pgx32_frame_proc_slice(vo_frame_t *frame_gen, uint8_t **src)
+{
+ pgx32_frame_t *frame = (pgx32_frame_t *)frame_gen;
+
+ frame->vo_frame.proc_called = 1;
+
+ switch (frame->format) {
+ case XINE_IMGFMT_YUY2: {
+ int i, x, len;
+ uint32_t *yptr, *dst, pixel;
+
+ yptr = (uint32_t *)(void *)src[0];
+ dst = frame->stripe_dst;
+
+ len = (frame->lines_remaining > 16) ? 16 : frame->lines_remaining;
+ frame->lines_remaining -= len;
+
+ for (i=0; i<len; i++) {
+ for(x=0; x<frame->vo_frame.pitches[0]/4; x++) {
+ pixel = *(yptr++);
+ *(dst++) = (pixel >> 16) | ((pixel & 0xffff) << 16);
+ }
+ dst += (frame->pitch-frame->width)/2;
+ }
+
+ frame->stripe_dst = dst;
+ }
+ break;
+
+ case XINE_IMGFMT_YV12: {
+ int i, x, len;
+ uint16_t *yptr, y;
+ uint8_t *uptr, *vptr, u, v;
+ uint32_t *dst;
+
+ yptr = (uint16_t *)(void *)src[0];
+ uptr = src[1];
+ vptr = src[2];
+ dst = frame->stripe_dst;
+
+ len = (frame->lines_remaining > 16) ? 16 : frame->lines_remaining;
+ frame->lines_remaining -= len;
+
+ for (i=0; i<len; i++) {
+ if (i & 1) {
+ uptr -= frame->vo_frame.pitches[1];
+ vptr -= frame->vo_frame.pitches[2];
+ }
+
+ for(x=0; x<frame->vo_frame.pitches[0]/2; x++) {
+ y = *(yptr++);
+ u = *(uptr++);
+ v = *(vptr++);
+ *(dst++) = u | (y & 0xff00) | (v << 16) | ((y & 0x00ff) << 24);
+ }
+ dst += (frame->pitch-frame->width)/2;
+ }
+
+ frame->stripe_dst = dst;
+ }
+ break;
+ }
+}
+
+static void pgx32_frame_field(vo_frame_t *frame_gen, int which_field)
+{
+ /*pgx32_frame_t *frame = (pgx32_frame_t *)frame_gen;*/
+}
+
+static void pgx32_frame_dispose(vo_frame_t *frame_gen)
+{
+ pgx32_frame_t *frame = (pgx32_frame_t *)frame_gen;
+
+ dispose_frame_internals(frame);
+ free(frame);
+}
+
+static uint32_t pgx32_get_capabilities(vo_driver_t *this_gen)
+{
+ /*pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen;*/
+
+ return VO_CAP_YV12 |
+ VO_CAP_YUY2;
+}
+
+static vo_frame_t *pgx32_alloc_frame(vo_driver_t *this_gen)
+{
+ /*pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen;*/
+ pgx32_frame_t *frame;
+
+ frame = (pgx32_frame_t *) xine_xmalloc(sizeof(pgx32_frame_t));
+ if (!frame) {
+ return NULL;
+ }
+
+ pthread_mutex_init(&frame->vo_frame.mutex, NULL);
+
+ frame->vo_frame.proc_frame = pgx32_frame_proc_frame;
+ frame->vo_frame.proc_slice = pgx32_frame_proc_slice;
+ frame->vo_frame.field = pgx32_frame_field;
+ frame->vo_frame.dispose = pgx32_frame_dispose;
+
+ return (vo_frame_t *)frame;
+}
+
+static void pgx32_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags)
+{
+ pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen;
+ pgx32_frame_t *frame = (pgx32_frame_t *)frame_gen;
+
+ if ((width != frame->width) ||
+ (height != frame->height) ||
+ (ratio != frame->ratio) ||
+ (format != frame->format)) {
+ int i, planes;
+
+ dispose_frame_internals(frame);
+
+ frame->width = width;
+ frame->height = height;
+ frame->ratio = ratio;
+ frame->format = format;
+
+ frame->pitch = 2048;
+ for (i=0; i<sizeof(pitch_code_table)/sizeof(pitch_code_table[0]); i++) {
+ if ((pitch_code_table[i][0] >= frame->width) && (pitch_code_table[i][0] <= frame->pitch)) {
+ frame->pitch = pitch_code_table[i][0];
+ frame->pitch_code = pitch_code_table[i][1];
+ }
+ }
+
+ frame->packedlen = frame->pitch * 2 * height;
+ if (!(frame->packedbuf = memalign(8, frame->packedlen))) {
+ xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_pgx32: frame packed buffer malloc failed\n");
+ abort();
+ }
+
+ planes = 0;
+
+ switch (format) {
+ case XINE_IMGFMT_YUY2:
+ planes = 1;
+ frame->vo_frame.pitches[0] = ((width + 1) / 2) * 4;
+ frame->vo_frame.base[0] = memalign(8, frame->vo_frame.pitches[0] * height);
+ break;
+
+ case XINE_IMGFMT_YV12:
+ planes = 3;
+ frame->vo_frame.pitches[0] = ((width + 1) / 2) * 2;
+ frame->vo_frame.pitches[1] = (width + 1) / 2;
+ frame->vo_frame.pitches[2] = (width + 1) / 2;
+ frame->vo_frame.base[0] = memalign(8, frame->vo_frame.pitches[0] * height);
+ frame->vo_frame.base[1] = memalign(8, frame->vo_frame.pitches[1] * ((height + 1) / 2));
+ frame->vo_frame.base[2] = memalign(8, frame->vo_frame.pitches[2] * ((height + 1) / 2));
+ break;
+ }
+
+ for (i=0;i<planes;i++) {
+ if (!frame->vo_frame.base[i]) {
+ xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_pgx32: frame plane malloc failed\n");
+ abort();
+ }
+ }
+ }
+
+ frame->stripe_dst = frame->packedbuf;
+ frame->lines_remaining = frame->height;
+}
+
+static void pgx32_display_frame(vo_driver_t *this_gen, vo_frame_t *frame_gen)
+{
+ pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen;
+ pgx32_frame_t *frame = (pgx32_frame_t *)frame_gen;
+ volatile uint64_t *vregs = (void *)(this->vbase+GFXP_REGSBASE);
+
+ if ((frame->width != this->vo_scale.delivered_width) ||
+ (frame->height != this->vo_scale.delivered_height) ||
+ (frame->ratio != this->vo_scale.delivered_ratio) ||
+ (frame->format != this->delivered_format)) {
+ this->vo_scale.delivered_width = frame->width;
+ this->vo_scale.delivered_height = frame->height;
+ this->vo_scale.delivered_ratio = frame->ratio;
+ this->delivered_format = frame->format;
+
+ this->vo_scale.force_redraw = 1;
+ _x_vo_scale_compute_ideal_size(&this->vo_scale);
+ }
+
+ if (_x_vo_scale_redraw_needed(&this->vo_scale)) {
+ int i;
+
+ _x_vo_scale_compute_output_size(&this->vo_scale);
+
+ XLockDisplay(this->display);
+ XSetForeground(this->display, this->gc, BlackPixel(this->display, this->screen));
+ for (i=0;i<4;i++) {
+ XFillRectangle(this->display, this->drawable, this->gc, this->vo_scale.border[i].x, this->vo_scale.border[i].y, this->vo_scale.border[i].w, this->vo_scale.border[i].h);
+ }
+ XUnlockDisplay(this->display);
+ }
+
+ memcpy((this->vbase+GFXP_VRAM_MMAPLEN)-frame->packedlen, frame->packedbuf, frame->packedlen);
+
+ XLockDisplay(this->display);
+ XGrabServer(this->display);
+ XSync(this->display, False);
+
+ while(le2me_64(vregs[FIFO_SPACE]) < 34) {}
+
+ vregs[RASTERISER_MODE] = 0;
+ vregs[SCISSOR_MODE] = 0;
+ vregs[AREA_STIPPLE_MODE] = 0;
+ vregs[WINDOW_ORIGIN] = 0;
+
+ vregs[RECT_ORIGIN] = le2me_64((this->vo_scale.gui_win_x + this->vo_scale.output_xoffset) | ((this->vo_scale.gui_win_y + this->vo_scale.output_yoffset) << 16));
+ vregs[RECT_SIZE] = le2me_64(this->vo_scale.output_width | (this->vo_scale.output_height << 16));
+
+ vregs[DY] = le2me_64(1 << 16);
+
+ vregs[TEXTURE_ADDR_MODE] = le2me_64(1);
+ vregs[SSTART] = 0;
+ vregs[DSDX] = le2me_64((frame->width << 20) / this->vo_scale.output_width);
+ vregs[DSDY_DOM] = 0;
+ vregs[TSTART] = 0;
+ vregs[DTDX] = 0;
+ vregs[DTDY_DOM] = le2me_64((frame->height << 20) / this->vo_scale.output_height);
+
+ vregs[TEXTURE_BASE_ADDR] = le2me_64((GFXP_VRAM_MMAPLEN-frame->packedlen) >> 1);
+ vregs[TEXTURE_MAP_FORMAT] = le2me_64((1 << 19) | frame->pitch_code);
+
+ vregs[TEXTURE_DATA_FORMAT] = le2me_64(0x63);
+ vregs[TEXTURE_READ_MODE] = le2me_64((1 << 17) | (11 << 13) | (11 << 9) | 1);
+ vregs[TEXTURE_COLOUR_MODE] = le2me_64((0 << 4) | (3 << 1) | 1);
+
+ vregs[SHADING_MODE] = 0;
+ vregs[ALPHA_BLENDING_MODE] = 0;
+ vregs[DITHERING_MODE] = le2me_64((1 << 10) | 1);
+ vregs[LOGICAL_OP_MODE] = 0;
+ vregs[STENCIL_MODE] = 0;
+
+ vregs[READ_MODE] = le2me_64(this->screen_pitch_code);
+ vregs[WRITE_MODE] = le2me_64(1);
+ vregs[WRITE_MASK] = le2me_64(0x00ffffff);
+
+ vregs[YUV_MODE] = le2me_64(1);
+
+ vregs[RENDER] = le2me_64(RENDER_BEGIN);
+
+ vregs[TEXTURE_READ_MODE] = 0;
+ vregs[TEXTURE_ADDR_MODE] = 0;
+ vregs[DITHERING_MODE] = 0;
+ vregs[TEXTURE_COLOUR_MODE] = 0;
+ vregs[YUV_MODE] = 0;
+
+ XUngrabServer(this->display);
+ XFlush(this->display);
+ XUnlockDisplay(this->display);
+
+ if (this->current != NULL) {
+ this->current->vo_frame.free(&this->current->vo_frame);
+ }
+ this->current = frame;
+}
+
+static void pgx32_overlay_blend(vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay)
+{
+ /*pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen;*/
+ pgx32_frame_t *frame = (pgx32_frame_t *)frame_gen;
+
+ if (overlay->rle) {
+ switch (frame->format) {
+ case XINE_IMGFMT_YV12: {
+ blend_yuv(frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches);
+ }
+ break;
+
+ case XINE_IMGFMT_YUY2: {
+ blend_yuy2(frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0]);
+ }
+ break;
+ }
+ }
+}
+
+static int pgx32_get_property(vo_driver_t *this_gen, int property)
+{
+ pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen;
+
+ switch (property) {
+ case VO_PROP_INTERLACED:
+ return this->deinterlace_en;
+ break;
+
+ case VO_PROP_ASPECT_RATIO:
+ return this->vo_scale.user_ratio;
+ break;
+
+ default:
+ return 0;
+ break;
+ }
+}
+
+static int pgx32_set_property(vo_driver_t *this_gen, int property, int value)
+{
+ pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen;
+
+ switch (property) {
+ case VO_PROP_INTERLACED: {
+ this->deinterlace_en = value;
+ this->vo_scale.force_redraw = 1;
+ }
+ break;
+
+ case VO_PROP_ASPECT_RATIO: {
+ if (value >= XINE_VO_ASPECT_NUM_RATIOS) {
+ value = XINE_VO_ASPECT_AUTO;
+ }
+ this->vo_scale.user_ratio = value;
+ this->vo_scale.force_redraw = 1;
+ _x_vo_scale_compute_ideal_size(&this->vo_scale);
+ }
+ break;
+ }
+ return value;
+}
+
+static void pgx32_get_property_min_max(vo_driver_t *this_gen, int property, int *min, int *max)
+{
+ /*pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen;*/
+
+ switch (property) {
+ default:
+ *min = 0;
+ *max = 0;
+ break;
+ }
+}
+
+static int pgx32_gui_data_exchange(vo_driver_t *this_gen, int data_type, void *data)
+{
+ pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen;
+
+ switch (data_type) {
+ case XINE_GUI_SEND_DRAWABLE_CHANGED: {
+ XWindowAttributes win_attrs;
+
+ XLockDisplay(this->display);
+ this->drawable = (Drawable)data;
+ XGetWindowAttributes(this->display, this->drawable, &win_attrs);
+ this->depth = win_attrs.depth;
+ this->visual = win_attrs.visual;
+ XFreeGC(this->display, this->gc);
+ this->gc = XCreateGC(this->display, this->drawable, 0, NULL);
+ XUnlockDisplay(this->display);
+ }
+ break;
+
+ case XINE_GUI_SEND_EXPOSE_EVENT: {
+ this->vo_scale.force_redraw = 1;
+ }
+ break;
+
+ case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: {
+ x11_rectangle_t *rect = data;
+ int x1, y1, x2, y2;
+
+ _x_vo_scale_translate_gui2video(&this->vo_scale, rect->x, rect->y, &x1, &y1);
+ _x_vo_scale_translate_gui2video(&this->vo_scale, rect->x + rect->w, rect->y + rect->h, &x2, &y2);
+
+ rect->x = x1;
+ rect->y = y1;
+ rect->w = x2 - x1;
+ rect->h = y2 - y1;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static int pgx32_redraw_needed(vo_driver_t *this_gen)
+{
+ pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen;
+
+ if (_x_vo_scale_redraw_needed(&this->vo_scale)) {
+ this->vo_scale.force_redraw = 1;
+ return 1;
+ }
+
+ return 0;
+}
+
+static void pgx32_dispose(vo_driver_t *this_gen)
+{
+ pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen;
+
+ XLockDisplay (this->display);
+ XFreeGC(this->display, this->gc);
+ XUnlockDisplay (this->display);
+
+ munmap(this->vbase, GFXP_VRAM_MMAPLEN);
+ munmap(this->vbase+GFXP_REGSBASE, GFXP_REGS_MMAPLEN);
+ close(this->fbfd);
+
+ pthread_mutex_lock(&this->class->mutex);
+ this->class->instance_count--;
+ pthread_mutex_unlock(&this->class->mutex);
+
+ free(this);
+}
+
+/*
+ * XINE VIDEO DRIVER CLASS FUNCTIONS
+ */
+
+static void pgx32_dispose_class(video_driver_class_t *class_gen)
+{
+ pgx32_driver_class_t *class = (pgx32_driver_class_t *)(void *)class_gen;
+
+ pthread_mutex_destroy(&class->mutex);
+ free(class);
+}
+
+static vo_info_t vo_info_pgx32 = {
+ 10,
+ XINE_VISUAL_TYPE_X11
+};
+
+static vo_driver_t *pgx32_init_driver(video_driver_class_t *class_gen, const void *visual_gen)
+{
+ pgx32_driver_class_t *class = (pgx32_driver_class_t *)(void *)class_gen;
+ char *devname;
+ int fbfd, i;
+ struct vis_identifier ident;
+ struct fbgattr attr;
+ uint8_t *vbase;
+ pgx32_driver_t *this;
+ XWindowAttributes win_attrs;
+
+ pthread_mutex_lock(&class->mutex);
+ if (class->instance_count > 0) {
+ pthread_mutex_unlock(&class->mutex);
+ return NULL;
+ }
+ class->instance_count++;
+ pthread_mutex_unlock(&class->mutex);
+
+ devname = class->config->register_string(class->config, "video.pgx32_device", "/dev/fb", "name of pgx32 device", NULL, 10, NULL, NULL);
+ if ((fbfd = open(devname, O_RDWR)) < 0) {
+ xprintf(class->xine, XINE_VERBOSITY_DEBUG, "video_out_pgx32: Error: can't open framebuffer device '%s'\n", devname);
+ return NULL;
+ }
+
+ if (ioctl(fbfd, VIS_GETIDENTIFIER, &ident) < 0) {
+ xprintf(class->xine, XINE_VERBOSITY_DEBUG, "video_out_sunfb: Error: ioctl failed, unable to determine framebuffer type\n");
+ close(fbfd);
+ return NULL;
+ }
+
+ if (strcmp("TSIgfxp", ident.name) != 0) {
+ xprintf(class->xine, XINE_VERBOSITY_DEBUG, "video_out_pgx64: Error: '%s' is not a gfxp framebuffer device\n", devname);
+ close(fbfd);
+ return NULL;
+ }
+
+ if (ioctl(fbfd, FBIOGATTR, &attr) < 0) {
+ xprintf(class->xine, XINE_VERBOSITY_DEBUG, "video_out_pgx32: Error: ioctl failed, unable to determine framebuffer characteristics\n");
+ close(fbfd);
+ return NULL;
+ }
+
+ if ((vbase = mmap(0, GFXP_VRAM_MMAPLEN, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0x04000000)) == MAP_FAILED) {
+ return 0;
+ }
+ if (mmap(vbase+GFXP_REGSBASE, GFXP_REGS_MMAPLEN, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fbfd, 0x02000000) == MAP_FAILED) {
+ munmap(vbase, GFXP_VRAM_MMAPLEN);
+ return 0;
+ }
+
+ this = (pgx32_driver_t *)xine_xmalloc(sizeof(pgx32_driver_t));
+ if (!this) {
+ return NULL;
+ }
+
+ this->vo_driver.get_capabilities = pgx32_get_capabilities;
+ this->vo_driver.alloc_frame = pgx32_alloc_frame;
+ this->vo_driver.update_frame_format = pgx32_update_frame_format;
+ this->vo_driver.overlay_begin = NULL;
+ this->vo_driver.overlay_blend = pgx32_overlay_blend;
+ this->vo_driver.overlay_end = NULL;
+ this->vo_driver.display_frame = pgx32_display_frame;
+ this->vo_driver.get_property = pgx32_get_property;
+ this->vo_driver.set_property = pgx32_set_property;
+ this->vo_driver.get_property_min_max = pgx32_get_property_min_max;
+ this->vo_driver.gui_data_exchange = pgx32_gui_data_exchange;
+ this->vo_driver.redraw_needed = pgx32_redraw_needed;
+ this->vo_driver.dispose = pgx32_dispose;
+
+ _x_vo_scale_init(&this->vo_scale, 0, 0, class->config);
+ this->vo_scale.user_ratio = XINE_VO_ASPECT_AUTO;
+ this->vo_scale.user_data = ((x11_visual_t *)visual_gen)->user_data;
+ this->vo_scale.frame_output_cb = ((x11_visual_t *)visual_gen)->frame_output_cb;
+ this->vo_scale.dest_size_cb = ((x11_visual_t *)visual_gen)->dest_size_cb;
+
+ this->class = class;
+
+ this->fbfd = fbfd;
+ this->fb_width = attr.fbtype.fb_width;
+ this->fb_height = attr.fbtype.fb_height;
+ this->fb_depth = attr.fbtype.fb_depth;
+ this->vbase = vbase;
+
+ for (i=0; i<sizeof(pitch_code_table)/sizeof(pitch_code_table[0]); i++) {
+ if (pitch_code_table[i][0] == this->fb_width) {
+ this->screen_pitch_code = pitch_code_table[i][1];
+ }
+ }
+
+ this->display = ((x11_visual_t *)visual_gen)->display;
+ this->screen = ((x11_visual_t *)visual_gen)->screen;
+ this->drawable = ((x11_visual_t *)visual_gen)->d;
+ this->gc = XCreateGC(this->display, this->drawable, 0, NULL);
+
+ XGetWindowAttributes(this->display, this->drawable, &win_attrs);
+ this->depth = win_attrs.depth;
+ this->visual = win_attrs.visual;
+
+ return (vo_driver_t *)this;
+}
+
+static char *pgx32_get_identifier(video_driver_class_t *class_gen)
+{
+ return "pgx32";
+}
+
+static char *pgx32_get_description(video_driver_class_t *class_gen)
+{
+ return "xine video output plugin for Sun PGX32 framebuffers";
+}
+
+static void *pgx32_init_class(xine_t *xine, void *visual_gen)
+{
+ pgx32_driver_class_t *class;
+
+ class = (pgx32_driver_class_t *)xine_xmalloc(sizeof(pgx32_driver_class_t));
+ if (!class) {
+ return NULL;
+ }
+
+ class->vo_driver_class.open_plugin = pgx32_init_driver;
+ class->vo_driver_class.get_identifier = pgx32_get_identifier;
+ class->vo_driver_class.get_description = pgx32_get_description;
+ class->vo_driver_class.dispose = pgx32_dispose_class;
+
+ class->xine = xine;
+ class->config = xine->config;
+
+ pthread_mutex_init(&class->mutex, NULL);
+
+ return class;
+}
+
+plugin_info_t xine_plugin_info[] = {
+ {PLUGIN_VIDEO_OUT, 19, "pgx32", XINE_VERSION_CODE, &vo_info_pgx32, pgx32_init_class},
+ {PLUGIN_NONE, 0, "", 0, NULL, NULL}
+};
diff --git a/src/video_out/video_out_pgx64.c b/src/video_out/video_out_pgx64.c
index fd31cc950..1d38ca062 100644
--- a/src/video_out/video_out_pgx64.c
+++ b/src/video_out/video_out_pgx64.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_pgx64.c,v 1.51 2004/02/16 23:17:07 komadori Exp $
+ * $Id: video_out_pgx64.c,v 1.52 2004/02/17 19:44:02 komadori Exp $
*
* video_out_pgx64.c, Sun PGX64/PGX24 output plugin for xine
*
@@ -144,7 +144,7 @@ typedef struct {
vo_frame_t vo_frame;
int lengths[3], stripe_lengths[3], stripe_offsets[3], buffers[3];
- int width, height, pitch, format, native_format, planes;
+ int width, height, format, pitch, native_format, planes;
double ratio;
uint8_t *buffer_ptrs[3];
} pgx64_frame_t;
@@ -183,7 +183,7 @@ typedef struct {
#define BUF_MODE_DOUBLE 3
/*
- * Dispose of any free_mark key data within a pgx64_frame_t
+ * Dispose of any allocated image data within a pgx64_frame_t
*/
static void dispose_frame_internals(pgx64_frame_t *frame)
@@ -227,7 +227,7 @@ static void repaint_output_area(pgx64_driver_t *this)
XLockDisplay(this->display);
XSetForeground(this->display, this->gc, BlackPixel(this->display, this->screen));
- for (i=0; i<4; i++) {
+ for (i=0;i<4;i++) {
XFillRectangle(this->display, this->drawable, this->gc, this->vo_scale.border[i].x, this->vo_scale.border[i].y, this->vo_scale.border[i].w, this->vo_scale.border[i].h);
}
@@ -247,13 +247,13 @@ static void repaint_output_area(pgx64_driver_t *this)
* Reset video memory allocator and release detained frames
*/
-static void vbase_reset(pgx64_driver_t* this)
+static void vbase_reset(pgx64_driver_t * this)
{
int i;
this->free_mark = this->free_top;
- for (i=0; i<this->detained_frames; i++) {
+ for (i=0;i<this->detained_frames;i++) {
this->detained[i]->vo_frame.free(&this->detained[i]->vo_frame);
}
this->detained_frames = 0;
@@ -263,7 +263,7 @@ static void vbase_reset(pgx64_driver_t* this)
* Allocate a portion of video memory
*/
-static int vbase_alloc(pgx64_driver_t* this, int size)
+static int vbase_alloc(pgx64_driver_t * this, int size)
{
if (this->free_mark - size < this->free_bottom) {
return -1;
@@ -285,7 +285,7 @@ static void pgx64_frame_proc_frame(vo_frame_t *frame_gen)
frame->vo_frame.proc_called = 1;
- for (i=0; i<frame->planes; i++) {
+ for (i=0;i<frame->planes;i++) {
memcpy(frame->buffer_ptrs[i], frame->vo_frame.base[i], frame->lengths[i]);
}
}
@@ -297,7 +297,7 @@ static void pgx64_frame_proc_slice(vo_frame_t *frame_gen, uint8_t **src)
frame->vo_frame.proc_called = 1;
- for (i=0; i<frame->planes; i++) {
+ for (i=0;i<frame->planes;i++) {
len = (frame->lengths[i] - frame->stripe_offsets[i] < frame->stripe_lengths[i]) ? frame->lengths[i] - frame->stripe_offsets[i] : frame->stripe_lengths[i];
memcpy(frame->buffer_ptrs[i]+frame->stripe_offsets[i], src[i], len);
frame->stripe_offsets[i] += len;
@@ -325,7 +325,7 @@ static uint32_t pgx64_get_capabilities(vo_driver_t *this_gen)
VO_CAP_YUY2;
}
-static vo_frame_t* pgx64_alloc_frame(vo_driver_t *this_gen)
+static vo_frame_t *pgx64_alloc_frame(vo_driver_t *this_gen)
{
/*pgx64_driver_t *this = (pgx64_driver_t *)(void *)this_gen;*/
pgx64_frame_t *frame;
@@ -364,8 +364,8 @@ static void pgx64_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_g
frame->format = format;
frame->pitch = ((width + 7) / 8) * 8;
- frame->vo_frame.proc_frame = NULL;
- frame->vo_frame.proc_slice = NULL;
+ frame->vo_frame.proc_frame = NULL;
+ frame->vo_frame.proc_slice = NULL;
switch (format) {
case XINE_IMGFMT_YUY2:
@@ -395,7 +395,7 @@ static void pgx64_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_g
break;
}
- for (i=0; i<frame->planes; i++) {
+ for (i=0;i<frame->planes;i++) {
if (!frame->vo_frame.base[i]) {
xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_pgx64: frame plane malloc failed\n");
abort();
@@ -455,7 +455,7 @@ static void pgx64_display_frame(vo_driver_t *this_gen, vo_frame_t *frame_gen)
vregs[OVERLAY_GRAPHICS_KEY_MSK] = le2me_32(0xffffffff >> (32 - this->fb_depth));
vregs[VIDEO_FORMAT] = le2me_32(frame->native_format);
- vregs[SCALER_BUF_PITCH] = le2me_32(this->deinterlace_en ? frame->pitch*2 : frame->pitch);
+ vregs[SCALER_BUF_PITCH] = le2me_32(this->deinterlace_en ? frame->pitch *2 : frame->pitch);
vregs[OVERLAY_X_Y_START] = le2me_32(((this->vo_scale.gui_win_x + this->vo_scale.output_xoffset) << 16) | (this->vo_scale.gui_win_y + this->vo_scale.output_yoffset) | OVERLAY_X_Y_LOCK);
vregs[OVERLAY_X_Y_END] = le2me_32(((this->vo_scale.gui_win_x + this->vo_scale.output_xoffset + this->vo_scale.output_width - 1) << 16) | (this->vo_scale.gui_win_y + this->vo_scale.output_yoffset + this->vo_scale.output_height - 1));
vregs[OVERLAY_SCALE_INC] = le2me_32((((frame->width << 12) / this->vo_scale.output_width) << 16) | (((this->deinterlace_en ? frame->height/2 : frame->height) << 12) / this->vo_scale.output_height));
@@ -479,7 +479,7 @@ static void pgx64_display_frame(vo_driver_t *this_gen, vo_frame_t *frame_gen)
int i;
if (frame->vo_frame.proc_slice != pgx64_frame_proc_slice) {
- for (i=0; i<frame->planes; i++) {
+ for (i=0;i<frame->planes;i++) {
if ((frame->buffers[i] = vbase_alloc(this, frame->lengths[i])) < 0) {
if (this->detained_frames < MAX_DETAINED_FRAMES) {
this->detained[this->detained_frames++] = frame;
@@ -502,7 +502,7 @@ static void pgx64_display_frame(vo_driver_t *this_gen, vo_frame_t *frame_gen)
frame->vo_frame.proc_slice = pgx64_frame_proc_slice;
}
- for (i=0; i<frame->planes; i++) {
+ for (i=0;i<frame->planes;i++) {
vregs[scaler_regs_table[this->dblbuf_select][i]] = le2me_32(frame->buffers[i]);
}
}
@@ -511,7 +511,7 @@ static void pgx64_display_frame(vo_driver_t *this_gen, vo_frame_t *frame_gen)
int i, j;
if (this->buf_mode == BUF_MODE_NOT_MULTI) {
- for (i=0; i<frame->planes; i++) {
+ for (i=0;i<frame->planes;i++) {
if ((this->buffers[0][i] = vbase_alloc(this, frame->lengths[i])) < 0) {
xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_pgx64: Error: insuffucient video memory\n"));
return;
@@ -522,7 +522,7 @@ static void pgx64_display_frame(vo_driver_t *this_gen, vo_frame_t *frame_gen)
}
this->buf_mode = BUF_MODE_DOUBLE;
- for (i=0; i<frame->planes; i++) {
+ for (i=0;i<frame->planes;i++) {
if ((this->buffers[1][i] = vbase_alloc(this, frame->lengths[i])) < 0) {
this->buf_mode = BUF_MODE_SINGLE;
}
@@ -533,20 +533,20 @@ static void pgx64_display_frame(vo_driver_t *this_gen, vo_frame_t *frame_gen)
if (this->buf_mode == BUF_MODE_SINGLE) {
xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_pgx64: Warning: low video memory, double-buffering disabled\n"));
- for (i=0; i<frame->planes; i++) {
+ for (i=0;i<frame->planes;i++) {
this->buffers[1][i] = this->buffers[0][i];
this->buffer_ptrs[1][i] = this->vbase + this->buffers[1][i];
}
}
- for (i=0; i<2; i++) {
- for (j=0; j<frame->planes; j++) {
+ for (i=0;i<2;i++) {
+ for (j=0;j<frame->planes;j++) {
vregs[scaler_regs_table[i][j]] = le2me_32(this->buffers[i][j]);
}
}
}
- for (i=0; i<frame->planes; i++) {
+ for (i=0;i<frame->planes;i++) {
memcpy(this->buffer_ptrs[this->dblbuf_select][i], frame->vo_frame.base[i], frame->lengths[i]);
}
@@ -625,7 +625,7 @@ static void pgx64_overlay_key_blend(vo_driver_t *this_gen, vo_frame_t *frame_gen
XLockDisplay(this->display);
ovl->p = XCreatePixmap(this->display, this->drawable, ovl->width, ovl->height, this->depth);
- for (i=0, x=0, y=0; i<overlay->num_rle; i++) {
+ for (i=0, x=0, y=0;i<overlay->num_rle;i++) {
len = overlay->rle[i].len;
while (len > 0) {
@@ -667,7 +667,7 @@ static void pgx64_overlay_key_blend(vo_driver_t *this_gen, vo_frame_t *frame_gen
src_trans = (uint8_t *)&overlay->trans;
}
- for (j=max_palette_colour[use_clip_palette]+1; j<=overlay->rle[i].color; j++) {
+ for (j=max_palette_colour[use_clip_palette]+1;j<=overlay->rle[i].color;j++) {
if (src_trans[j]) {
XColor col;
int y, u, v, r, g, b;
@@ -719,8 +719,8 @@ static void pgx64_overlay_key_blend(vo_driver_t *this_gen, vo_frame_t *frame_gen
XUnlockDisplay(this->display);
ovl_ptr = &this->first_overlay;
- while (*ovl_ptr != NULL) {
- ovl_ptr = &(*ovl_ptr)->next;
+ while ( *ovl_ptr != NULL) {
+ ovl_ptr = &( *ovl_ptr)->next;
}
*ovl_ptr = ovl;
}
@@ -826,7 +826,7 @@ static int pgx64_set_property(vo_driver_t *this_gen, int property, int value)
}
this->vo_scale.user_ratio = value;
this->vo_scale.force_redraw = 1;
- _x_vo_scale_compute_ideal_size(&this->vo_scale);
+ _x_vo_scale_compute_ideal_size(&this->vo_scale);
}
break;
@@ -1000,14 +1000,14 @@ static vo_info_t vo_info_pgx64 = {
XINE_VISUAL_TYPE_X11
};
-static vo_driver_t* pgx64_init_driver(video_driver_class_t *class_gen, const void *visual_gen)
+static vo_driver_t *pgx64_init_driver(video_driver_class_t *class_gen, const void *visual_gen)
{
pgx64_driver_class_t *class = (pgx64_driver_class_t *)(void *)class_gen;
char *devname;
int fbfd;
+ struct fbgattr attr;
uint8_t *vbase;
pgx64_driver_t *this;
- struct fbgattr attr;
XWindowAttributes win_attrs;
pthread_mutex_lock(&class->mutex);
@@ -1042,7 +1042,7 @@ static vo_driver_t* pgx64_init_driver(video_driver_class_t *class_gen, const voi
return NULL;
}
- this = (pgx64_driver_t*)xine_xmalloc(sizeof(pgx64_driver_t));
+ this = (pgx64_driver_t *)xine_xmalloc(sizeof(pgx64_driver_t));
if (!this) {
return NULL;
}
@@ -1063,9 +1063,9 @@ static vo_driver_t* pgx64_init_driver(video_driver_class_t *class_gen, const voi
_x_vo_scale_init(&this->vo_scale, 0, 0, class->config);
this->vo_scale.user_ratio = XINE_VO_ASPECT_AUTO;
- this->vo_scale.user_data = ((x11_visual_t*)visual_gen)->user_data;
- this->vo_scale.frame_output_cb = ((x11_visual_t*)visual_gen)->frame_output_cb;
- this->vo_scale.dest_size_cb = ((x11_visual_t*)visual_gen)->dest_size_cb;
+ this->vo_scale.user_data = ((x11_visual_t *)visual_gen)->user_data;
+ this->vo_scale.frame_output_cb = ((x11_visual_t *)visual_gen)->frame_output_cb;
+ this->vo_scale.dest_size_cb = ((x11_visual_t *)visual_gen)->dest_size_cb;
this->class = class;
@@ -1077,9 +1077,9 @@ static vo_driver_t* pgx64_init_driver(video_driver_class_t *class_gen, const voi
this->free_bottom = attr.sattr.dev_specific[5] + attr.fbtype.fb_size;
this->vbase = vbase;
- this->display = ((x11_visual_t*)visual_gen)->display;
- this->screen = ((x11_visual_t*)visual_gen)->screen;
- this->drawable = ((x11_visual_t*)visual_gen)->d;
+ this->display = ((x11_visual_t *)visual_gen)->display;
+ this->screen = ((x11_visual_t *)visual_gen)->screen;
+ this->drawable = ((x11_visual_t *)visual_gen)->d;
this->gc = XCreateGC(this->display, this->drawable, 0, NULL);
XGetWindowAttributes(this->display, this->drawable, &win_attrs);
@@ -1091,7 +1091,7 @@ static vo_driver_t* pgx64_init_driver(video_driver_class_t *class_gen, const voi
this->colour_key = class->config->register_num(this->class->config, "video.pgx64_colour_key", 1, "video overlay colour key", NULL, 10, pgx64_config_changed, this);
this->brightness = class->config->register_range(this->class->config, "video.pgx64_brightness", 0, -64, 63, "video overlay brightness", NULL, 10, pgx64_config_changed, this);
this->saturation = class->config->register_range(this->class->config, "video.pgx64_saturation", 16, 0, 31, "video overlay saturation", NULL, 10, pgx64_config_changed, this);
- this->ovl_mode = class->config->register_enum(this->class->config, "video.pgx64_overlay_mode", 0, (char**)overlay_modes, "video overlay mode", NULL, 10, pgx64_config_changed, this);
+ this->ovl_mode = class->config->register_enum(this->class->config, "video.pgx64_overlay_mode", 0, (char **)overlay_modes, "video overlay mode", NULL, 10, pgx64_config_changed, this);
this->multibuf_en = class->config->register_bool(this->class->config, "video.pgx64_multibuf_en", 1, "enable multi-buffering", NULL, 10, pgx64_config_changed, this);
pthread_mutex_init(&this->ovl_mutex, NULL);
@@ -1099,21 +1099,21 @@ static vo_driver_t* pgx64_init_driver(video_driver_class_t *class_gen, const voi
return (vo_driver_t *)this;
}
-static char* pgx64_get_identifier(video_driver_class_t *class_gen)
+static char *pgx64_get_identifier(video_driver_class_t *class_gen)
{
return "pgx64";
}
-static char* pgx64_get_description(video_driver_class_t *class_gen)
+static char *pgx64_get_description(video_driver_class_t *class_gen)
{
return "xine video output plugin for Sun PGX64/PGX24 framebuffers";
}
-static void* pgx64_init_class(xine_t *xine, void *visual_gen)
+static void *pgx64_init_class(xine_t *xine, void *visual_gen)
{
pgx64_driver_class_t *class;
- class = (pgx64_driver_class_t*)xine_xmalloc(sizeof(pgx64_driver_class_t));
+ class = (pgx64_driver_class_t *)xine_xmalloc(sizeof(pgx64_driver_class_t));
if (!class) {
return NULL;
}