/* * Copyright (C) 2000-2003 the xine project * * This file is part of xine, a unix 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: main.c,v 1.13 2003/01/05 00:24:33 f1rmb Exp $ * * xine main for DirectFB * Rich Wareham * */ #ifndef __sun #define _XOPEN_SOURCE 500 #endif #define _BSD_SOURCE 1 #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include "dfb.h" dfbxine_t dfbxine; static void config_update(xine_cfg_entry_t *entry, int type, int min, int max, int value, char *string) { switch(type) { case XINE_CONFIG_TYPE_UNKNOWN: fprintf(stderr, "Config key '%s' isn't registered yet.\n", entry->key); return; break; case XINE_CONFIG_TYPE_RANGE: entry->range_min = min; entry->range_max = max; break; case XINE_CONFIG_TYPE_STRING: entry->str_value = string; break; case XINE_CONFIG_TYPE_ENUM: case XINE_CONFIG_TYPE_NUM: case XINE_CONFIG_TYPE_BOOL: entry->num_value = value; break; default: fprintf(stderr, "Unknown config type %d\n", type); return; break; } xine_config_update_entry(dfbxine.xine, entry); } void config_update_range(char *key, int min, int max) { xine_cfg_entry_t entry; if(xine_config_lookup_entry(dfbxine.xine, key, &entry)) config_update(&entry, XINE_CONFIG_TYPE_RANGE, min, max, 0, NULL); else fprintf(stderr, "WOW, key %s isn't registered\n", key); } void config_update_string(char *key, char *string) { xine_cfg_entry_t entry; if((xine_config_lookup_entry(dfbxine.xine, key, &entry)) && string) config_update(&entry, XINE_CONFIG_TYPE_STRING, 0, 0, 0, string); else { if(string == NULL) fprintf(stderr, "string is NULL\n"); else fprintf(stderr, "WOW, key %s isn't registered\n", key); } } void config_update_enum(char *key, int value) { xine_cfg_entry_t entry; if(xine_config_lookup_entry(dfbxine.xine, key, &entry)) config_update(&entry, XINE_CONFIG_TYPE_ENUM, 0, 0, value, NULL); else fprintf(stderr, "WOW, key %s isn't registered\n", key); } void config_update_bool(char *key, int value) { xine_cfg_entry_t entry; if(xine_config_lookup_entry(dfbxine.xine, key, &entry)) config_update(&entry, XINE_CONFIG_TYPE_BOOL, 0, 0, ((value > 0) ? 1 : 0), NULL); else fprintf(stderr, "WOW, key %s isn't registered\n", key); } void config_update_num(char *key, int value) { xine_cfg_entry_t entry; if(xine_config_lookup_entry(dfbxine.xine, key, &entry)) config_update(&entry, XINE_CONFIG_TYPE_NUM, 0, 0, value, NULL); else fprintf(stderr, "WOW, key %s isn't registered\n", key); } /* * Handling xine engine status changes. */ static void gui_status_callback (int nStatus) { if (dfbxine.ignore_status) return; if(nStatus == XINE_STATUS_STOP) { dfbxine.current_mrl++; if (dfbxine.current_mrl < dfbxine.num_mrls) { if(xine_open(dfbxine.xine, dfbxine.mrl[dfbxine.current_mrl])) xine_play (dfbxine.xine, 0, 0 ); } else { if (dfbxine.auto_quit == 1) { dfbxine.running = 0; } dfbxine.current_mrl--; } } } /* * Return next available mrl to xine engine. */ static char *gui_next_mrl_callback (void ) { if(dfbxine.current_mrl >= (dfbxine.num_mrls - 1)) return NULL; return dfbxine.mrl[dfbxine.current_mrl + 1]; } /* * Xine engine branch success. */ static void gui_branched_callback (void ) { if(dfbxine.current_mrl < (dfbxine.num_mrls - 1)) { dfbxine.current_mrl++; } } /* * Seek in current stream. */ static void set_position (int pos) { dfbxine.ignore_status = 1; xine_play(dfbxine.xine, pos, 0); dfbxine.ignore_status = 0; } /* * Extract mrls from argv[] and store them to playlist. */ void extract_mrls(int num_mrls, char **mrls) { int i; for(i = 0; i < num_mrls; i++) dfbxine.mrl[i] = mrls[i]; dfbxine.num_mrls = num_mrls; dfbxine.current_mrl = 0; } void vm_cb(int w, int h, int bpp, void* cb_data) { printf("Mode %ix%i @ %i bpp supported\n", w,h,bpp); } int main(int argc, char *argv[]) { char *configfile; char *driver_name; dfb_visual_info_t visual_info; IDirectFBEventBuffer *input_buf; IDirectFBInputDevice *keyboard = NULL; int window_grabbed = 0; int window_size = 0; int startx = 0; int starty = 0; int endx = 0; int endy = 0; /* * Check xine library version */ if(!xine_check_version(0, 9, 14)) { int major, minor, sub; xine_get_version (&major, &minor, &sub); fprintf(stderr, "require xine library version 0.9.14, found %d.%d.%d.\n", major, minor, sub); goto failure; } dfbxine.num_mrls = 0; dfbxine.current_mrl = 0; dfbxine.auto_quit = 0; /* default: loop forever */ dfbxine.debug_messages = 0; dfbxine.dfb = NULL; dfbxine.primary = NULL; dfbxine.audio_driver_id = dfbxine.video_driver_id = NULL; dfbxine.audio_channel = 0; if(!do_command_line(argc,argv)) { goto failure; } /* * generate and init a config "object" */ { char *cfgfile = ".xine/config"; if (!(configfile = getenv("XINERC"))) { configfile = (char *) xine_xmalloc((strlen((xine_get_homedir())) + strlen(cfgfile))+2); sprintf(configfile, "%s/%s", (xine_get_homedir()), cfgfile); } } if(!init_dfb()) { fprintf(stderr, "Error initialising DirectFB\n"); goto failure; } dfbxine.xine = (xine_t *) xine_new(); xine_config_load (dfb.xine, configfile); xine_init (dfbxine.xine, dfbxine.ao_driver, dfbxine.vo_driver); if(!dfbxine.xine) { fprintf(stderr, "xine_init() failed.\n"); goto failure; } /* * init video output driver */ if(!dfbxine.video_driver_id) dfbxine.video_driver_id = "directfb"; visual_info.dfb = dfbxine.dfb; visual_info.layer = dfbxine.video_layer; dfbxine.vo_driver = xine_open_video_driver(dfbxine.xine, dfbxine.video_driver_id, XINE_VISUAL_TYPE_DFB, (void *)(&visual_info)); if (!dfbxine.vo_driver) { printf ("main: video driver failed\n"); goto failure; } /* * init audio output driver */ driver_name = (char *) xine_config_register_string(dfbxine.xine, "audio.driver", "oss", "audio driver to use", NULL, 20, NULL, NULL); if(!dfbxine.audio_driver_id) dfbxine.audio_driver_id = driver_name; else config_update_string (dfbxine.xine, "audio.driver", dfbxine.audio_driver_id); dfbxine.ao_driver = xine_open_audio_driver(dfbxine.xine, dfbxine.audio_driver_id, NULL); if (!dfbxine.ao_driver) { printf ("main: audio driver %s failed\n", dfbxine.audio_driver_id); } /* * xine init */ /* Init mixer control */ dfbxine.mixer.enable = 0; dfbxine.mixer.caps = 0; if(xine_get_param(dfbxine.xine, XINE_PARAM_AO_MIXER_VOL)) dfbxine.mixer.caps |= XINE_PARAM_AO_MIXER_VOL; if(xine_get_param(dfbxine.xine, XINE_PARAM_AO_PCM_VOL)) dfbxine.mixer.caps |= XINE_PARAM_AO_PCM_VOL; if(xine_get_param(dfbxine.xine, XINE_PARAM_AO_MUTE)) dfbxine.mixer.caps |= XINE_PARAM_AO_MUTE; if(dfbxine.mixer.caps & (XINE_PARAM_AO_MIXER_VOL | XINE_PARAM_AO_PCM_VOL)) { dfbxine.mixer.enable = 1; dfbxine.mixer.volume_level = xine_get_param(dfbxine.xine, XINE_PARAM_AUDIO_VOLUME); } if(dfbxine.mixer.caps & XINE_PARAM_AO_MUTE) dfbxine.mixer.mute = xine_get_param(dfbxine.xine, XINE_PARAM_AUDIO_MUTE); /* Select audio channel */ xine_set_param(dfbxine.xine, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, dfbxine.audio_channel); /* * ui loop */ if(xine_open(dfbxine.xine, dfbxine.mrl[dfbxine.current_mrl])) xine_play (dfbxine.xine, 0, 0); dfbxine.running = 1; DFBCHECK(dfbxine.dfb->GetInputDevice (dfbxine.dfb, DIDID_KEYBOARD, &keyboard)); DFBCHECK(keyboard->CreateEventBuffer (keyboard, &input_buf)); DFBCHECK(dfbxine.main_window->AttachEventBuffer(dfbxine.main_window, input_buf)); while (dfbxine.running) { DFBWindowEvent win_event; DFBInputEvent input_event; DFBEvent event; input_buf->WaitForEventWithTimeout(input_buf, 0, 10000000); while (input_buf->GetEvent(input_buf, &event) == DFB_OK) { if(event.clazz == DFEC_WINDOW) { win_event = event.window; switch (win_event.type) { case DWET_BUTTONDOWN: if(!window_grabbed && win_event.button == DIBI_LEFT) { window_grabbed = 1; dfbxine.layer->GetCursorPosition(dfbxine.layer, &startx, &starty); dfbxine.main_window->GrabPointer(dfbxine.main_window); } if(!window_size && win_event.button == DIBI_MIDDLE) { int w,h; window_size = 1; dfbxine.layer->GetCursorPosition(dfbxine.layer, &startx, &starty); dfbxine.main_window->GrabPointer(dfbxine.main_window); dfbxine.main_window->GetSize(dfbxine.main_window, &w, &h); startx -= w; starty -= h; } break; case DWET_BUTTONUP: if(win_event.button == DIBI_LEFT) { dfbxine.main_window->UngrabPointer(dfbxine.main_window); window_grabbed = 0; } if(win_event.button == DIBI_MIDDLE) { dfbxine.main_window->UngrabPointer(dfbxine.main_window); window_size = 0; } break; case DWET_MOTION: endx = win_event.cx; endy = win_event.cy; break; default: break; } } if(window_grabbed) { dfbxine.main_window->Move(dfbxine.main_window, endx-startx, endy-starty); startx = endx; starty = endy; } if(window_size) { dfbxine.main_window->Resize(dfbxine.main_window, endx-startx, endy-starty); } if(event.clazz == DFEC_INPUT) { input_event = event.input; if(input_event.type == DIET_KEYPRESS) { printf("USER QUITTED\n"); dfbxine.running = 0; } } } } failure: if(dfbxine.xine) xine_config_save(dfbxine.xine, configfile); if(dfbxine.xine) xine_exit(dfbxine.xine); if(dfbxine.video_layer) DFBCHECK(dfbxine.video_layer->Release(dfbxine.video_layer)); if(dfbxine.main_surface) DFBCHECK(dfbxine.main_surface->Release(dfbxine.main_surface)); if(dfbxine.main_window) DFBCHECK(dfbxine.main_window->Release(dfbxine.main_window)); if(dfbxine.primary) DFBCHECK(dfbxine.primary->Release(dfbxine.primary)); if(dfbxine.pointer) DFBCHECK(dfbxine.pointer->Release(dfbxine.pointer)); if(dfbxine.layer) DFBCHECK(dfbxine.layer->Release(dfbxine.layer)); if(dfbxine.dfb) DFBCHECK(dfbxine.dfb->Release(dfbxine.dfb)); return 0; }