|
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中动了点手脚,使其在执行这个语句,自然就能打印出东西来了,不像现在
的全是问号了。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
×
|