⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 playeripc.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: playeripc.cpp,v 1.6.2.8 2004/11/23 00:24:25 rggammon Exp $ *  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved. *  * The contents of this file, and the files included with this file, * are subject to the current version of the RealNetworks Public * Source License (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (the "RCSL") available at * http://www.helixcommunity.org/content/rcsl, in which case the RCSL * will apply. You may also obtain the license terms directly from * RealNetworks.  You may not use this file except in compliance with * the RPSL or, if you have a valid RCSL with RealNetworks applicable * to this file, the RCSL.  Please see the applicable RPSL or RCSL for * the rights, obligations and limitations governing use of the * contents of the file. *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. *  * This file is part of the Helix DNA Technology. RealNetworks is the * developer of the Original Code and owns the copyrights in the * portions it created. *  * This file, and the files included with this file, is distributed * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET * ENJOYMENT OR NON-INFRINGEMENT. *  * Technology Compatibility Kit Test Suite(s) Location: *    http://www.helixcommunity.org/content/tck *  * Contributor(s): *  * ***** END LICENSE BLOCK ***** */#include "hlxclib/memory.h"#include "hlxclib/string.h"#include "hlxclib/stdio.h"#include "hlxclib/ctype.h"#include "hlxclib/errno.h"#include <unistd.h>#include <sys/time.h>#include "hlxclib/sys/types.h"#include "embeddedapp.h"#include <gtk/gtk.h>#include <glib.h>#include "embddef.h"#include "hxplayer.h"#define COMMAND_BUFFER_SIZE 16384// Avoid using helix-level constructs by defining these:#define HXR_OK   0x00000000     #define HXR_FAIL 0x80004005typedef guint HX_RESULT;#define PLAYER_IPC_VERSION 1struct {    GIOChannel* embedded_command_channel;    GIOChannel* embedded_callbacks_channel;        gint buf_pos;    gchar buf[COMMAND_BUFFER_SIZE];    guint sequence; // old RN code called this ProtocolNumber    GList* console_attributes_list;} g_playeripc;gboolean playeripc_handle_command(GIOChannel *channel, const char *command);gboolean playeripc_parse_commands(GIOChannel *channel, GIOCondition condition, gpointer data);static gbooleanhandle_ipc_error(GIOChannel*,                 GIOCondition,                 gpointer){    /* A broken pipe will not happen here -- see the EOF handler in       playeripc_parse_commands */    gtk_main_quit();        return FALSE; // remove event}gbooleanplayeripc_init(int command_fd, int callbacks_fd){    GError *error = NULL;    memset(&g_playeripc, 0, sizeof(g_playeripc));    if(command_fd >= 0)    {        g_playeripc.embedded_command_channel = g_io_channel_unix_new(command_fd);        g_return_val_if_fail(g_playeripc.embedded_command_channel != NULL, FALSE);        g_io_channel_set_encoding(g_playeripc.embedded_command_channel, NULL, &error);        if(error)        {            g_warning(error->message);                        g_free(error);                }        g_io_channel_set_buffered(g_playeripc.embedded_command_channel, FALSE);    }    if(callbacks_fd >= 0)    {        g_playeripc.embedded_callbacks_channel = g_io_channel_unix_new(callbacks_fd);        g_return_val_if_fail(g_playeripc.embedded_callbacks_channel != NULL, FALSE);        g_io_channel_set_encoding(g_playeripc.embedded_callbacks_channel, NULL, &error);        if(error)        {            g_warning(error->message);                        g_free(error);                }        g_io_channel_set_buffered(g_playeripc.embedded_callbacks_channel, FALSE);    }        g_io_add_watch(g_playeripc.embedded_command_channel,                   G_IO_IN,                   playeripc_parse_commands,                   NULL );    g_io_add_watch(g_playeripc.embedded_command_channel,                   (GIOCondition)(G_IO_ERR | G_IO_HUP),                   handle_ipc_error,                   NULL );    return TRUE;}/* Parser for plugin IPC protocol */gbooleanplayeripc_parse_commands(GIOChannel *channel,                           GIOCondition condition,                           gpointer){    GIOStatus status;    gsize bytes_read;    GError* error = NULL;    char c = 0;    int fd, result = 0;     fd_set fds_read, fds_exception;    struct timeval timeout;        if(condition != G_IO_IN)    {        g_warning("playeripc_parse_commands: condition is %d", condition);        return TRUE; // don't remove event source    }        fd = g_io_channel_unix_get_fd(channel);        /* Read from the command fd up to the first '\n' command */    /* We parse one character at a time because the SetStream command       does its own thing with reading, and we don't want to eat its data */    do    {        status = g_io_channel_read_chars(channel,                                         &c,                                         1,                                         &bytes_read,                                         &error);        if(error)        {            g_log(G_LOG_DOMAIN,                  G_LOG_LEVEL_WARNING,                  "g_io_channel_read_chars: %s",                  error->message);                        g_free(error);        }                switch(status)        {            case G_IO_STATUS_ERROR:                            case G_IO_STATUS_EOF:                gtk_main_quit();                return FALSE; // remove event                            case G_IO_STATUS_AGAIN:                continue;            case G_IO_STATUS_NORMAL:                g_assert(bytes_read == 1);                g_assert(c != '\0');                g_playeripc.buf[g_playeripc.buf_pos++] = c;                break;            default:                g_assert(FALSE); /* not reached */        }        FD_ZERO(&fds_read);        FD_ZERO(&fds_exception);        FD_SET(fd, &fds_read);                                                                                        FD_SET(fd, &fds_exception);        /* Return immediately */        timeout.tv_sec = 0;        timeout.tv_usec = 0;        result = select(fd + 1, &fds_read, NULL, &fds_exception, &timeout);        if(FD_ISSET(fd, &fds_exception) || result < 0)        {            /* This should never happen. A closed fd will not cause               this path to be called. */            g_warning("Exception in playeripc_parse_commands");            break;        }                /* Read until there's no more data, or we get a newline */    } while(c != '\n' && FD_ISSET(fd, &fds_read));        if(c == '\n')    {        g_assert(g_playeripc.buf[g_playeripc.buf_pos - 1] == '\n');        g_playeripc.buf[g_playeripc.buf_pos - 1] = '\0';        printf("playeripc: Got command %s\n", g_playeripc.buf);        playeripc_handle_command(channel, g_playeripc.buf);        g_playeripc.buf_pos = 0;    }    return TRUE; // don't remove the event source.}/* RGG: GLib needs one of these... Interval is in ms, in keeping   with glib standards */static gbooleanrecv_with_timeout(GIOChannel* channel, gchar* buf, gsize len, guint interval){    fd_set fds_read, fds_exception;    int fd;    int result;    struct timeval timeout;    int interval_sec, interval_usec;    guint pos = 0;    gboolean ret = TRUE;    interval_sec = interval / 1000;    interval_usec = (interval % 1000) * 1000;        fd = g_io_channel_unix_get_fd(channel);    do    {        FD_ZERO(&fds_read);        FD_ZERO(&fds_exception);        FD_SET(fd, &fds_read);                                                                                        FD_SET(fd, &fds_exception);        /* XXXRGG: FIXME: Right now, the timeout gets reset each time           data is received. Don't rely on select() to update timeout. */        timeout.tv_sec = interval_sec;        timeout.tv_usec = interval_usec;        result = select(fd + 1, &fds_read, NULL, &fds_exception, &timeout);        if(result == 0)        {            /* timeout */            g_warning("Timed out in recv_with_timeout with %d bytes", pos - 1);            ret = FALSE;        }        else if(FD_ISSET(fd, &fds_exception) || result < 0)        {            g_warning("Exception in recv_with_timeout");            ret = FALSE;        }        if(FD_ISSET(fd, &fds_read))        {            /* Receive data */            for(;;)            {                result = read(fd, buf + pos, len - pos);                if(result < 0)                {                    if(errno == EINTR || errno == EAGAIN)                    {                        continue;                    }                    else                    {                        perror("read");                        ret = FALSE;                    }                }                else if(result == 0)                {                        g_warning("Lost connection to plugin");                        /* Connection closed */                        ret = FALSE;                }                else                {                        pos += result;                }                break;            }                        }    } while(ret && pos < len);                                                                                   return ret;}static voidsend_ipc(GIOChannel *channel, const gchar* output, gsize size){    GIOStatus status;    GError *error = NULL;    gsize bytes_written;    gsize total_written = 0;        do    {        // XXXRGG: Need a timeout here.        status = g_io_channel_write_chars(channel,                                          output + total_written,                                          size - total_written,                                          &bytes_written,                                          &error);                if(error)        {            g_log(G_LOG_DOMAIN,                  G_LOG_LEVEL_WARNING,                  "g_io_channel_write_chars: %s",                  error->message);                        g_free(error);        }                switch(status)        {            case G_IO_STATUS_ERROR:                            case G_IO_STATUS_EOF:                gtk_main_quit();                return;                            case G_IO_STATUS_AGAIN:                break;            case G_IO_STATUS_NORMAL:                total_written += bytes_written;                break;            default:                g_assert(FALSE); /* not reached */        }            } while((total_written < size) || (status == G_IO_STATUS_AGAIN));}static voidsend_reply(GIOChannel *channel, const char *format, ...){        gchar *command;    gsize len;        va_list args;    va_start(args, format);    command = g_strdup_vprintf(format, args);        len = strlen(command) + 1;    /* We need to add a newline. We could reallocate the string with       an extra character. Instead, we replace the '\0' (send_ipc       doesn't need a null-terminated string). */    command[len - 1] = '\n';        send_ipc(channel, command, len);        g_free(command);            va_end(args);}/* This function will modify the string it is passed */static gchar*strunquote(gchar* str){    gchar* end;    gchar* pos;        if(str[0] == '"')    {        end = strrchr(str, '"');        if(end && end != str)        {            pos = end + 1;            while(*pos)            {                if(!isspace(*pos))                {                    /* There are trailing characters after the closing quote */                    return str;                }            }            str++;       // get rid of leading quote            *end = '\0'; // get rid of trailing quote        }    }    return str;}static voidwindow_attributes_set_defaults(HXEmbeddedWindowAttributes *attr){    /* See:       http://service.real.com/help/library/guides/realone/ScriptingGuide/HTML/realscript.htm    */    attr->autogotourl = FALSE;    attr->autostart = FALSE;    attr->backgroundcolor = g_strdup("black");    attr->center = FALSE;    attr->console = g_strdup("_unique");    attr->controls = HX_CONTROLS_ALL;    attr->controls_string = NULL;    attr->name_flags = HX_NAME_NONE;    attr->name = NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -