summaryrefslogtreecommitdiff
path: root/doc/hackersguide/library.sgml
diff options
context:
space:
mode:
Diffstat (limited to 'doc/hackersguide/library.sgml')
-rw-r--r--doc/hackersguide/library.sgml410
1 files changed, 0 insertions, 410 deletions
diff --git a/doc/hackersguide/library.sgml b/doc/hackersguide/library.sgml
deleted file mode 100644
index 8f53d1556..000000000
--- a/doc/hackersguide/library.sgml
+++ /dev/null
@@ -1,410 +0,0 @@
-<chapter id="xine-library">
- <title>Using the xine library</title>
-
- <sect1>
- <title>xine architecture as visible to libxine clients</title>
- <para>
- The following drawing shows the components of xine as outside applications
- see them. For every component, the functions for creating and destroying it
- are given. Every other function works in the context it is enclosed in.
- Functions that facilitate the connection of the individual components are
- also given.
- </para>
- <mediaobject>
- <imageobject>
- <imagedata fileref="library.png" format="PNG">
- </imageobject>
- <imageobject>
- <imagedata fileref="library.eps" format="EPS">
- </imageobject>
- <caption>
- <para>outside view on xine components</para>
- </caption>
- </mediaobject>
- <para>
- The function are named just to give you an overview of what is actually
- there. It is all thoroughly documented in the plublic header
- <filename>xine.h</filename>, which is the main and preferably the only xine
- header, clients should include. (xine/xineutils.h and the XML parser might
- make an exception.)
- </para>
- <para>
- Details on the OSD feature can be found in the <link linkend="osd">OSD section</link>.
- </para>
- </sect1>
-
- <sect1>
- <title>Writing a new frontend to xine</title>
- <para>
- The best way to explain this seems to be actual code. Below you
- will find a very easy and hopefully self-explaining xine frontend
- to give you a start.
- </para>
- <para>
- One important thing to note is that any X11 based xine-lib frontend
- must call <function>XInitThreads()</function> before calling the
- first Xlib function, because xine will access the display from
- within a different thread than the frontend.
- </para>
- <sect2>
- <title>Source code of a simple X11 frontend</title>
- <programlisting>
-/*
-** Copyright (C) 2003 Daniel Caujolle-Bert &lt;segfault@club-internet.fr&gt;
-**
-** This program 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.
-**
-** This program 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.
-**
-*/
-
-/*
- * compile-command: "gcc -Wall -O2 `pkg-config --cflags --libs libxine x11` -lm -o xinimin xinimin.c"
- */
-
-#include &lt;stdio.h&gt;
-#include &lt;string.h&gt;
-#include &lt;math.h&gt;
-
-#include &lt;X11/X.h&gt;
-#include &lt;X11/Xlib.h&gt;
-#include &lt;X11/Xutil.h&gt;
-#include &lt;X11/keysym.h&gt;
-#include &lt;X11/Xatom.h&gt;
-#include &lt;X11/Xutil.h&gt;
-#include &lt;X11/extensions/XShm.h&gt;
-
-#include &lt;xine.h&gt;
-#include &lt;xine/xineutils.h&gt;
-
-
-#define MWM_HINTS_DECORATIONS (1L &lt;&lt; 1)
-#define PROP_MWM_HINTS_ELEMENTS 5
-typedef struct {
- uint32_t flags;
- uint32_t functions;
- uint32_t decorations;
- int32_t input_mode;
- uint32_t status;
-} MWMHints;
-
-static xine_t *xine;
-static xine_stream_t *stream;
-static xine_video_port_t *vo_port;
-static xine_audio_port_t *ao_port;
-static xine_event_queue_t *event_queue;
-
-static Display *display;
-static int screen;
-static Window window[2];
-static int xpos, ypos, width, height, fullscreen;
-static double pixel_aspect;
-
-static int running = 1;
-
-#define INPUT_MOTION (ExposureMask | ButtonPressMask | KeyPressMask | \
- ButtonMotionMask | StructureNotifyMask | \
- PropertyChangeMask | PointerMotionMask)
-
-/* this will be called by xine, if it wants to know the target size of a frame */
-static void dest_size_cb(void *data, int video_width, int video_height, double video_pixel_aspect,
- int *dest_width, int *dest_height, double *dest_pixel_aspect) {
- *dest_width = width;
- *dest_height = height;
- *dest_pixel_aspect = pixel_aspect;
-}
-
-/* this will be called by xine when it's about to draw the frame */
-static void frame_output_cb(void *data, int video_width, int video_height,
- double video_pixel_aspect, int *dest_x, int *dest_y,
- int *dest_width, int *dest_height,
- double *dest_pixel_aspect, int *win_x, int *win_y) {
- *dest_x = 0;
- *dest_y = 0;
- *win_x = xpos;
- *win_y = ypos;
- *dest_width = width;
- *dest_height = height;
- *dest_pixel_aspect = pixel_aspect;
-}
-
-static void event_listener(void *user_data, const xine_event_t *event) {
- switch(event-&gt;type) {
- case XINE_EVENT_UI_PLAYBACK_FINISHED:
- running = 0;
- break;
-
- case XINE_EVENT_PROGRESS:
- {
- xine_progress_data_t *pevent = (xine_progress_data_t *) event-&gt;data;
-
- printf("%s [%d%%]\n", pevent-&gt;description, pevent-&gt;percent);
- }
- break;
-
- /* you can handle a lot of other interesting events here */
- }
-}
-
-int main(int argc, char **argv) {
- char configfile[2048];
- x11_visual_t vis;
- double res_h, res_v;
- char *vo_driver = "auto";
- char *ao_driver = "auto";
- char *mrl = NULL;
- int i;
- Atom XA_NO_BORDER;
- MWMHints mwmhints;
-
- /* parsing command line */
- for (i = 1; i &lt; argc; i++) {
- if (strcmp(argv[i], "-vo") == 0) {
- vo_driver = argv[++i];
- }
- else if (strcmp(argv[i], "-ao") == 0) {
- ao_driver = argv[++i];
- }
- else
- mrl = argv[i];
- }
-
- if (!mrl) {
- printf("specify an mrl\n");
- return 1;
- }
- printf("mrl: '%s'\n", mrl);
-
- if (!XInitThreads()) {
- printf("XInitThreads() failed\n");
- return 1;
- }
-
- /* load xine config file and init xine */
- xine = xine_new();
- snprintf(configfile, sizeof(configfile), "%s%s", xine_get_homedir(), "/.xine/config");
- xine_config_load(xine, configfile);
- xine_init(xine);
-
- display = XOpenDisplay(NULL);
- screen = XDefaultScreen(display);
- xpos = 0;
- ypos = 0;
- width = 320;
- height = 200;
-
- /* some initalization for the X11 Window we will be showing video in */
- XLockDisplay(display);
- fullscreen = 0;
- window[0] = XCreateSimpleWindow(display, XDefaultRootWindow(display),
- xpos, ypos, width, height, 1, 0, 0);
-
- window[1] = XCreateSimpleWindow(display, XDefaultRootWindow(display),
- 0, 0, (DisplayWidth(display, screen)),
- (DisplayHeight(display, screen)), 0, 0, 0);
-
- XSelectInput(display, window[0], INPUT_MOTION);
-
- XSelectInput(display, window[1], INPUT_MOTION);
-
- XA_NO_BORDER = XInternAtom(display, "_MOTIF_WM_HINTS", False);
- mwmhints.flags = MWM_HINTS_DECORATIONS;
- mwmhints.decorations = 0;
- XChangeProperty(display, window[1],
- XA_NO_BORDER, XA_NO_BORDER, 32, PropModeReplace, (unsigned char *) &amp;mwmhints,
- PROP_MWM_HINTS_ELEMENTS);
-
- XMapRaised(display, window[fullscreen]);
-
- res_h = (DisplayWidth(display, screen) * 1000 / DisplayWidthMM(display, screen));
- res_v = (DisplayHeight(display, screen) * 1000 / DisplayHeightMM(display, screen));
- XSync(display, False);
- XUnlockDisplay(display);
-
- /* filling in the xine visual struct */
- vis.display = display;
- vis.screen = screen;
- vis.d = window[fullscreen];
- vis.dest_size_cb = dest_size_cb;
- vis.frame_output_cb = frame_output_cb;
- vis.user_data = NULL;
- pixel_aspect = res_v / res_h;
-
- /* opening xine output ports */
- vo_port = xine_open_video_driver(xine, vo_driver, XINE_VISUAL_TYPE_X11, (void *)&amp;vis);
- ao_port = xine_open_audio_driver(xine , ao_driver, NULL);
-
- /* open a xine stream connected to these ports */
- stream = xine_stream_new(xine, ao_port, vo_port);
- /* hook our event handler into the streams events */
- event_queue = xine_event_new_queue(stream);
- xine_event_create_listener_thread(event_queue, event_listener, NULL);
-
- /* make the video window visible to xine */
- xine_port_send_gui_data(vo_port, XINE_GUI_SEND_DRAWABLE_CHANGED, (void *) window[fullscreen]);
- xine_port_send_gui_data(vo_port, XINE_GUI_SEND_VIDEOWIN_VISIBLE, (void *) 1);
-
- /* start playback */
- if (!xine_open(stream, mrl) || !xine_play(stream, 0, 0)) {
- printf("Unable to open mrl '%s'\n", mrl);
- return 1;
- }
-
- while (running) {
- XEvent xevent;
- int got_event;
-
- XLockDisplay(display);
- got_event = XPending(display);
- if( got_event )
- XNextEvent(display, &amp;xevent);
- XUnlockDisplay(display);
-
- if( !got_event ) {
- xine_usec_sleep(20000);
- continue;
- }
-
- switch(xevent.type) {
-
- case KeyPress:
- {
- XKeyEvent kevent;
- KeySym ksym;
- char kbuf[256];
- int len;
-
- kevent = xevent.xkey;
-
- XLockDisplay(display);
- len = XLookupString(&amp;kevent, kbuf, sizeof(kbuf), &amp;ksym, NULL);
- XUnlockDisplay(display);
-
- switch (ksym) {
-
- case XK_q:
- case XK_Q:
- /* user pressed q => quit */
- running = 0;
- break;
-
- case XK_f:
- case XK_F:
- {
- /* user pressed f => toggle fullscreen */
- Window tmp_win;
-
- XLockDisplay(display);
- XUnmapWindow(display, window[fullscreen]);
- fullscreen = !fullscreen;
- XMapRaised(display, window[fullscreen]);
- XSync(display, False);
- XTranslateCoordinates(display, window[fullscreen],
- DefaultRootWindow(display),
- 0, 0, &amp;xpos, &amp;ypos, &amp;tmp_win);
- XUnlockDisplay(display);
-
- xine_port_send_gui_data(vo_port, XINE_GUI_SEND_DRAWABLE_CHANGED,
- (void*) window[fullscreen]);
- }
- break;
-
- case XK_Up:
- /* cursor up => increase volume */
- xine_set_param(stream, XINE_PARAM_AUDIO_VOLUME,
- (xine_get_param(stream, XINE_PARAM_AUDIO_VOLUME) + 1));
- break;
-
- case XK_Down:
- /* cursor down => decrease volume */
- xine_set_param(stream, XINE_PARAM_AUDIO_VOLUME,
- (xine_get_param(stream, XINE_PARAM_AUDIO_VOLUME) - 1));
- break;
-
- case XK_plus:
- /* plus => next audio channel */
- xine_set_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL,
- (xine_get_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL) + 1));
- break;
-
- case XK_minus:
- /* minus => previous audio channel */
- xine_set_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL,
- (xine_get_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL) - 1));
- break;
-
- case XK_space:
- /* space => toggle pause mode */
- if (xine_get_param(stream, XINE_PARAM_SPEED) != XINE_SPEED_PAUSE)
- xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
- else
- xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL);
- break;
-
- }
- }
- break;
-
- case Expose:
- /* this handles (partial) occlusion of our video window */
- if (xevent.xexpose.count != 0)
- break;
- xine_port_send_gui_data(vo_port, XINE_GUI_SEND_EXPOSE_EVENT, &amp;xevent);
- break;
-
- case ConfigureNotify:
- {
- XConfigureEvent *cev = (XConfigureEvent *) &amp;xevent;
- Window tmp_win;
-
- width = cev-&gt;width;
- height = cev-&gt;height;
-
- if ((cev-&gt;x == 0) &amp;&amp; (cev-&gt;y == 0)) {
- XLockDisplay(display);
- XTranslateCoordinates(display, cev-&gt;window,
- DefaultRootWindow(cev-&gt;display),
- 0, 0, &amp;xpos, &amp;ypos, &amp;tmp_win);
- XUnlockDisplay(display);
- } else {
- xpos = cev-&gt;x;
- ypos = cev-&gt;y;
- }
- }
- break;
-
- }
- }
-
- /* cleanup */
- xine_close(stream);
- xine_event_dispose_queue(event_queue);
- xine_dispose(stream);
- xine_close_audio_driver(xine, ao_port);
- xine_close_video_driver(xine, vo_port);
- xine_exit(xine);
-
- XLockDisplay(display);
- XUnmapWindow(display, window[fullscreen]);
- XDestroyWindow(display, window[0]);
- XDestroyWindow(display, window[1]);
- XUnlockDisplay(display);
-
- XCloseDisplay (display);
-
- return 0;
-}</programlisting>
- </sect2>
- </sect1>
-
-</chapter>