站内邮件和催人的邮件和kanker
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中动了点手脚,使其在执行这个语句,自然就能打印出东西来了,不像现在
的全是问号了。 偶菜,这东东又要话偶一些时间来读了 :cry: 仰慕一下住顶楼的高人…… 感谢,牛人啊:P
我把这几天做的跟播放有关的补丁也贴出来:
用 kde 的 nspluginloader 装载插件时,如果窗口的高度或宽度为零,会引起 widget 创建错误而无法装载。
--- 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;
顺便把konqueror 右键菜单上的 netscape plugin viewer 的一个乱码错误给去掉:
--- 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;
konqueror 不能播放 www.qq163.com 里的歌曲,经过分析,是因为 www.qq163.com 在 object 标签内加了个错误的 embed 标签。因为embed 的 src 内容应与 object 的相同,故设定 khtml 兼容 IE 的情况下优先使用 object 以解决这个问题:
--- 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() ) );
高,实在是高呀
:mrgreen::mrgreen: 高,实在是高呀
:mrgreen::mrgreen:
学习中 大家辛苦呀!
页:
[1]