QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1280|回复: 6

站内邮件和催人的邮件和kanker

[复制链接]
发表于 2005-10-22 12:43:21 | 显示全部楼层 |阅读模式
KanKer:
    你好!因为最近忙于生计,一直没时间好好完善kaffeine的播放问题,
实在不好意思,下面说一下最近的研究成果。(另外最近在研究freebsd,
该系统不能在论坛上发言,发送时告诉我请求不能识别,怪怪的。后来用
“瘟到死”才看到你留的站内邮件不好意思!)
   
1.如何让kaffeine_part支持javasript
在KDE中KParts::LiveConnectExtension这个类能使一个kpart的东西支持
javascript。

在下面的补丁中一个该类的实作
头文件部分
#include <kparts/browserextension.h>
class KaffeinePartLiveConnectExtension : public KParts::LiveConnectExtension {
    Q_OBJECT
public:
    KaffeinePartLiveConnectExtension(KaffeinePart * parent);

    bool get (const unsigned long objid, const QString & field, KParts::LiveConnectExtension::Type & type, unsigned long & retobjid, QString & value);
    bool put(const unsigned long, const QString & field, const QString & value);
    bool call (const unsigned long , const QString & func, const QStringList & args, KParts::LiveConnectExtension::Type & type, unsigned long & retobjid, QString & value);
    void unregister (const unsigned long objid);

private:
    KaffeinePart * m_parent;
};

实作代码部分
KaffeinePartLiveConnectExtension::KaffeinePartLiveConnectExtension(KaffeinePart * parent)
: KParts::LiveConnectExtension (parent, "KaffeinePart LiveConnect Extension"), m_parent (parent)
{}
//kde的javascrip执行引擎,遇到比如kaffeine_object.play()函数时会先解析该play函数名,
//于是根据kaffeine_object这个kpart,发现它有绑定了LiveConnectExtension这个类时,就会
//调用该类的虚拟方法bool get (...)从而获得这个play的具体定义。
//前面提到的kaffeine_object由html中object 用classid指定(名称是随便定义的)。具体id是
//多少我忘记了,反正就是windows中播放媒体工具com对象的几个id,好像这个:
// kdelibs_src/khtml/rendering/render_frames.cpp 文件中有做判断
bool KaffeinePartLiveConnectExtension::get (
        const unsigned long objid, const QString & name,
        KParts::LiveConnectExtension::Type & type,
        unsigned long & rid, QString & value)
{
    kdDebug(6074) << "KaffeinePartLiveConnectExtension::get"
        << " objid:" << objid
        << " name :" << name
        << " type :" << type
        << " rid  :" << rid
        << " value:" << value
        << endl;
    QString data = name.lower();
    if (data == "play" || data == "stop" || data == "pause") {
        type = LiveConnectExtension::TypeFunction; //告诉javascript引擎play()、stop()、pause()是三个函数
        rid = LiveConnectExtension::TypeVoid;
        value = "";
        return true;
    } else if (data == "mute") {                  //告诉javascript引擎mute是个属性值,这样调用的var mut=kaffeine_object.mute;
        type = LiveConnectExtension::TypeBool;
        value = QString::number(m_parent->slotMuteState());
        return true;
    } else if (data == "duration") {              //大意同上
        type = LiveConnectExtension::TypeNumber;
        value = QString::number(m_parent->slotDuration());
        return true;
    } else if (data == "currentposition") {       //大意同上
        type = LiveConnectExtension::TypeNumber;
        value = QString::number(m_parent->slotCurPosition());
        return true;
    } else if (data == "playstate") {             //大意同上
        type = LiveConnectExtension::TypeNumber;
        if (m_parent->isPlaying()) {
            value = QString::number(2);
        } else if (m_parent->isPaused()) {
            value = QString::number(1);
        } else {
            value = QString::number(0);
        }
        return true;
    }
    return false;
}
//put方法在javascript中对某一对象的属性赋值时被调用
bool KaffeinePartLiveConnectExtension::put(
    const unsigned long objid,
    const QString & name, const QString & value)
{

    kdDebug(6074) << "KaffeinePartLiveConnectExtension::put"
        << " objid:" << objid
        << " name :" << name
        << " value:" << value
        << endl;
    QString data = name.lower();
    if (data == "mute") {                       //当这样时kaffeine_object.mute=mut时被调用
        bool val = (value.lower() == "true");
        if (val != m_parent->slotMuteState()) {
            m_parent->slotMute();
        }
    } else if (data == "currentposition") {
        bool ok;
        double pos = value.toDouble(&ok);
        int len = m_parent->slotDuration();
        if (len <= 0) {
            return false;
        }
        pos = pos * 65535 / len;
        if (!ok || pos < 0) {
            return false;
        }
        m_parent->slotCurPosition((int)pos);
    } else if (data == "filename") {
        m_parent->slotStop();
        if (!m_parent->openURL(MRL(value)))
            return false;
    }
    return true;
}
//call方法在javasript中调用某一函数时被调用
bool KaffeinePartLiveConnectExtension::call(
    const unsigned long objid, const QString & func,
    const QStringList & fargs, KParts::LiveConnectExtension::Type & type,
    unsigned long & rid, QString & value )
{

    kdDebug(6074) << "KaffeinePartLiveConnectExtension::call"
        << " objid:" << objid
        << " func :" << func
        << " type :" << type
        << " rid  :" << rid
        << " value:" << value
        << endl;
    kdDebug(6074) << "args:" << endl;
    for (unsigned int i = 0; i < fargs.count() ; ++i) {
        kdDebug(6074) << fargs << endl;
    }
    kdDebug(6074) << endl;

    QString action = func.lower();
    if (action == "play") {                      //当这样时kaffeine_object.play()时被调用
        if (m_parent->isPaused()) {
            m_parent->slotTogglePause();
        } else
            m_parent->slotPlay();
    } else if (action == "stop") {
        m_parent->slotStop();
    } else if (action == "pause") {
        if (!m_parent->isPaused()) {
            m_parent->slotTogglePause();
        }
    } else
        return false;
        
    return true;
}

void KaffeinePartLiveConnectExtension::unregister(const unsigned long objid)
{
    kdDebug(6074) << "KaffeinePartLiveConnectExtension::unregister"
        << " objid:" << objid
        << endl;
}

kaffeinepart必须绑定上面这个类才能支持javascript的调用
具体内容见补丁中,这个补丁只能支持一些比较低级的javasript的调用,很多网站还不行:<,
主要是对一些javascript播放语句比如duration之类的不甚了了,希望有智者能帮忙解决。


2.如何让drkonqi在程序出错时打印堆栈出来,而不是问号
drkonqi在程序出现比如段错误时,会捕获这个signal(信号),这个是linux的处理机制,
一段程序出错就只能退出,不像windows下面比如delphi,try... except,在try段中的程序
部分即算出错也能回到except或finally部分继续执行像java,不过java的异常处理都是虚拟
机自己实现的,所以在linux照样能用。
drkonqi俘获一个signal后就会调用gdb的bt功能(backtrace)去打印错误线程的堆栈,然后
显示出来。不过可能是因为linux内核中断门使用vsyscall的原因,gdb没有把符号表装载进
内存中必须在调用gdb时手工加一点指令:
add-symbol-file-from-memory 0xffffe000 就ok,具体内容到gdb官方的bug列表中去找吧,
所以我在drkonqi中动了点手脚,使其在执行这个语句,自然就能打印出东西来了,不像现在
的全是问号了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
发表于 2005-10-22 14:24:40 | 显示全部楼层
偶菜,这东东又要话偶一些时间来读了
回复

使用道具 举报

发表于 2005-10-22 14:38:34 | 显示全部楼层
仰慕一下住顶楼的高人……
回复

使用道具 举报

发表于 2005-10-22 14:47:34 | 显示全部楼层
感谢,牛人啊  
我把这几天做的跟播放有关的补丁也贴出来:
用 kde 的 nspluginloader 装载插件时,如果窗口的高度或宽度为零,会引起 widget 创建错误而无法装载。
[code:1]
--- kdebase-3.4.3.bak/nsplugins/viewer/nsplugin.cpp        2005-10-05 21:38:27.000000000 +0800
+++ kdebase-3.4.3/nsplugins/viewer/nsplugin.cpp        2005-10-21 19:40:23.000000000 +0800
@@ -912,6 +912,10 @@

    _win.x = 0;
    _win.y = 0;
+   //_height and _width can't equal to zero.
+   if (_height==0 || _width==0)
+        return NPERR_NO_ERROR;
+
    _win.height = _height;
    _win.width = _width;
    _win.type = NPWindowTypeWindow;
[/code:1]
顺便把konqueror 右键菜单上的 netscape plugin viewer 的一个乱码错误给去掉:
[code:1]
--- kdebase-3.4.3.bak/nsplugins/pluginscan.cpp.orig        2005-10-05 21:38:27.000000000 +0800
+++ kdebase-3.4.3.bak/nsplugins/pluginscan.cpp        2005-10-20 18:26:44.000000000 +0800
@@ -184,7 +184,7 @@
         if (!description.isEmpty())
             ts << "Name=" << description << endl;
         else
-            ts << "Name=" << i18n("Netscape plugin mimeinfo") << endl;
+            ts << "Name=" << "Netscape plugin mimeinfo" << endl;

         f.close();
     }
@@ -489,10 +489,10 @@
         QTextStream ts(&f);

         ts << "[Desktop Entry]" << endl;
-        ts << "Name=" << i18n("Netscape plugin viewer") << endl;
+        ts << "Name=" << "Netscape plugin viewer" << endl;
         ts << "Type=Service" << endl;
         ts << "Icon=netscape" << endl;
-        ts << "Comment=" << i18n("Netscape plugin viewer") << endl;
+        ts << "Comment=" << "Netscape plugin viewer" << endl;
         ts << "X-KDE-Library=libnsplugin" << endl;
         ts << "InitialPreference=0" << endl;
         ts << "ServiceTypes=KParts/ReadOnlyPart,Browser/View" << endl;
[/code:1]
konqueror 不能播放 www.qq163.com 里的歌曲,经过分析,是因为 www.qq163.com 在 object 标签内加了个错误的 embed 标签。因为embed 的 src 内容应与 object 的相同,故设定 khtml 兼容 IE 的情况下优先使用 object 以解决这个问题:
[code:1]
--- kdelibs-3.4.3/khtml/rendering/render_frames.cpp.orig        2005-10-05 21:40:35.000000000 +0800
+++ kdelibs-3.4.3/khtml/rendering/render_frames.cpp        2005-10-22 21:05:06.000000000 +0800
@@ -652,11 +653,12 @@
       else { // if(element()->id() == ID_OBJECT || element()->id() == ID_APPLET)

           // check for embed child object
-          for (NodeImpl *child = objbase->firstChild(); child; child = child->nextSibling())
-              if ( child->id() == ID_EMBED ) {
-                  embed = static_cast<HTMLEmbedElementImpl *>( child );
-                  break;
-              }
+          if (! document()->inCompatMode() || objbase->classId.isEmpty())
+            for (NodeImpl *child = objbase->firstChild(); child; child = child->nextSibling())
+               if ( child->id() == ID_EMBED ) {
+                   embed = static_cast<HTMLEmbedElementImpl *>( child );
+                   break;
+               }

           params.append( QString::fromLatin1("__KHTML__CLASSID=\"%1\"").arg( objbase->classId ) );
           params.append( QString::fromLatin1("__KHTML__CODEBASE=\"%1\"").arg( objbase->getAttribute(ATTR_CODEBASE).string() ) );
[/code:1]
回复

使用道具 举报

发表于 2005-10-22 14:51:25 | 显示全部楼层
高,实在是高呀

  
回复

使用道具 举报

发表于 2005-10-22 15:32:58 | 显示全部楼层
[quote:839e63e729="tingxx"]高,实在是高呀

  [/quote]
学习中
回复

使用道具 举报

发表于 2005-10-22 22:15:10 | 显示全部楼层
大家辛苦呀!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-29 11:06 , Processed in 0.084810 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表