[onering-desktop] 12 new revisions pushed by hongqn on 2011-09-13 06:37 GMT

6 views
Skip to first unread message

onering...@googlecode.com

unread,
Sep 13, 2011, 2:38:23 AM9/13/11
to oneri...@googlegroups.com
12 new revisions:

Revision: c00ff64c9c94
Author: Qiangning Hong <hon...@gmail.com>
Date: Tue Aug 30 20:57:06 2011
Log: start plugin based branch. design doc:
http://code.google.com/p/oneri...
http://code.google.com/p/onering-desktop/source/detail?r=c00ff64c9c94

Revision: 529309cf5a72
Author: Qiangning Hong <hon...@gmail.com>
Date: Wed Aug 31 02:12:02 2011
Log: relative framework path
http://code.google.com/p/onering-desktop/source/detail?r=529309cf5a72

Revision: 2ad796cf312d
Author: Qiangning Hong <hon...@gmail.com>
Date: Wed Aug 31 02:54:24 2011
Log: renamed to qtcore
http://code.google.com/p/onering-desktop/source/detail?r=2ad796cf312d

Revision: 655739528403
Author: Qiangning Hong <hon...@gmail.com>
Date: Thu Sep 1 23:32:20 2011
Log: add new api
http://code.google.com/p/onering-desktop/source/detail?r=655739528403

Revision: 56f6d6f2b8d7
Author: Qiangning Hong <hon...@gmail.com>
Date: Thu Sep 1 23:37:57 2011
Log: move onering_load_plugins() implementation to pluginloader.cpp
http://code.google.com/p/onering-desktop/source/detail?r=56f6d6f2b8d7

Revision: 9fd7c8d72274
Author: Qiangning Hong <hon...@gmail.com>
Date: Fri Sep 2 00:09:10 2011
Log: add C version of test program
http://code.google.com/p/onering-desktop/source/detail?r=9fd7c8d72274

Revision: a94aabc2d153
Author: Qiangning Hong <hon...@gmail.com>
Date: Fri Sep 2 00:33:07 2011
Log: load dll
http://code.google.com/p/onering-desktop/source/detail?r=a94aabc2d153

Revision: 4f8ce306ad18
Author: Qiangning Hong <hon...@gmail.com>
Date: Fri Sep 2 00:56:09 2011
Log: c++'ifly
http://code.google.com/p/onering-desktop/source/detail?r=4f8ce306ad18

Revision: ececebfd9418
Author: Qiangning Hong <hon...@gmail.com>
Date: Fri Sep 2 02:08:58 2011
Log: scan and load plugins
http://code.google.com/p/onering-desktop/source/detail?r=ececebfd9418

Revision: 925d3d7c4c38
Author: Qiangning Hong <hon...@gmail.com>
Date: Sun Sep 11 02:07:25 2011
Log: refactor onering.h
http://code.google.com/p/onering-desktop/source/detail?r=925d3d7c4c38

Revision: 50085e4a3460
Author: Qiangning Hong <hon...@gmail.com>
Date: Sun Sep 11 02:13:42 2011
Log: rename from OneRing to OneRingQtCore
http://code.google.com/p/onering-desktop/source/detail?r=50085e4a3460

Revision: d2a182b904b1
Author: Qiangning Hong <hon...@gmail.com>
Date: Mon Sep 12 19:47:12 2011
Log: plugin ok
http://code.google.com/p/onering-desktop/source/detail?r=d2a182b904b1

==============================================================================
Revision: c00ff64c9c94
Author: Qiangning Hong <hon...@gmail.com>
Date: Tue Aug 30 20:57:06 2011
Log: start plugin based branch. design doc:
http://code.google.com/p/onering-desktop/wiki/PluginBasedArchitecture
http://code.google.com/p/onering-desktop/source/detail?r=c00ff64c9c94

==============================================================================
Revision: 529309cf5a72
Author: Qiangning Hong <hon...@gmail.com>
Date: Wed Aug 31 02:12:02 2011
Log: relative framework path
http://code.google.com/p/onering-desktop/source/detail?r=529309cf5a72

Modified:
/bindings/python/setup.py

=======================================
--- /bindings/python/setup.py Tue Apr 5 20:08:10 2011
+++ /bindings/python/setup.py Wed Aug 31 02:12:02 2011
@@ -2,10 +2,10 @@
from setuptools import setup, Extension

if sys.platform == 'darwin':
- include_dirs = ['/Library/Frameworks/OneRing.framework/Headers/']
+ include_dirs = ['../../OneRing.framework/Headers/']
library_dirs = []
libraries = []
- extra_link_args = ['-framework', 'OneRing']
+ extra_link_args = ['-F../..', '-framework', 'OneRing']
else:
include_dirs = [os.path.join('..', '..', 'include')]
library_dirs = [os.path.join('..', '..', 'release'),

==============================================================================
Revision: 2ad796cf312d
Author: Qiangning Hong <hon...@gmail.com>
Date: Wed Aug 31 02:54:24 2011
Log: renamed to qtcore
http://code.google.com/p/onering-desktop/source/detail?r=2ad796cf312d

Added:
/qtcore/js/onering.js
/qtcore/onering.pro
/qtcore/onering.qrc
/qtcore/src/app.cpp
/qtcore/src/app.h
/qtcore/src/application.cpp
/qtcore/src/application.h
/qtcore/src/appreply.cpp
/qtcore/src/appreply.h
/qtcore/src/cocoainit.h
/qtcore/src/cocoainit.mm
/qtcore/src/dataloader.cpp
/qtcore/src/dataloader.h
/qtcore/src/debugger.cpp
/qtcore/src/debugger.h
/qtcore/src/dockiconclick.h
/qtcore/src/dockiconclick.mm
/qtcore/src/hotkey.cpp
/qtcore/src/hotkey.h
/qtcore/src/jsapi.cpp
/qtcore/src/jsapi.h
/qtcore/src/json.cpp
/qtcore/src/json.h
/qtcore/src/menu.cpp
/qtcore/src/menu.h
/qtcore/src/networkaccessmanager.cpp
/qtcore/src/networkaccessmanager.h
/qtcore/src/onering.cpp
/qtcore/src/oneringapp.cpp
/qtcore/src/oneringapp.h
/qtcore/src/oneringview.cpp
/qtcore/src/oneringview.h
/qtcore/src/publishevent.cpp
/qtcore/src/publishevent.h
/qtcore/src/pubsubhub.cpp
/qtcore/src/pubsubhub.h
/qtcore/src/qxtglobal.h
/qtcore/src/qxtglobalshortcut.cpp
/qtcore/src/qxtglobalshortcut.h
/qtcore/src/qxtglobalshortcut_mac.cpp
/qtcore/src/qxtglobalshortcut_p.h
/qtcore/src/qxtglobalshortcut_win.cpp
/qtcore/src/qxtglobalshortcut_x11.cpp
/qtcore/src/systemtrayicon.cpp
/qtcore/src/systemtrayicon.h
Deleted:
/js/onering.js
/onering.pro
/onering.qrc
/src/app.cpp
/src/app.h
/src/application.cpp
/src/application.h
/src/appreply.cpp
/src/appreply.h
/src/cocoainit.h
/src/cocoainit.mm
/src/dataloader.cpp
/src/dataloader.h
/src/debugger.cpp
/src/debugger.h
/src/dockiconclick.h
/src/dockiconclick.mm
/src/hotkey.cpp
/src/hotkey.h
/src/jsapi.cpp
/src/jsapi.h
/src/json.cpp
/src/json.h
/src/menu.cpp
/src/menu.h
/src/networkaccessmanager.cpp
/src/networkaccessmanager.h
/src/onering.cpp
/src/oneringapp.cpp
/src/oneringapp.h
/src/oneringview.cpp
/src/oneringview.h
/src/publishevent.cpp
/src/publishevent.h
/src/pubsubhub.cpp
/src/pubsubhub.h
/src/qxtglobal.h
/src/qxtglobalshortcut.cpp
/src/qxtglobalshortcut.h
/src/qxtglobalshortcut_mac.cpp
/src/qxtglobalshortcut_p.h
/src/qxtglobalshortcut_win.cpp
/src/qxtglobalshortcut_x11.cpp
/src/systemtrayicon.cpp
/src/systemtrayicon.h
Modified:
/.hgignore

=======================================
--- /dev/null
+++ /qtcore/js/onering.js Wed Aug 31 02:54:24 2011
@@ -0,0 +1,446 @@
+ONERING = new Object();
+
+// Base {{{
+ONERING.Base = function() {};
+ONERING.Base.prototype = {
+ _call: function(command, param) {
+ if (!param) { param = {}; }
+ param.id = this.id;
+ return ONERING.call_app(this.appname, command, param);
+ },
+ _create: function(command, param) {
+ var obj = ONERING.call_app(this.appname, command, param);
+ if (!(this.validate_type(obj))) {
+ throw new Error(this.type + " not created");
+ }
+ return obj;
+ },
+ _destroy: function(command) {
+ if (!this.id) { return; }
+ var r = this._call(command);
+ this.id = null;
+ return r;
+ },
+ validate_type: function(obj) {
+ return (obj && obj.type == this.type);
+ },
+ bind: function(event, callback) {
+ ONERING.subscribe(this.appname+"."+this.type+"."+this.id+"."+event,
+ function(e) {
+ if (e instanceof Object && e.event_id) {
+ e = new ONERING.Event(e.event_id);
+ }
+ callback(e);
+ });
+ },
+ unbind: function(event) {
+ ONERING.unsubscribe(this.appname+"."+this.type+"."+this.id+"."+event);
+ },
+ extend: function(d) {
+ for (var k in d) {
+ this[k] = d[k];
+ }
+ return this;
+ },
+};
+//}}}
+
+// Event {{{
+ONERING.Event = function(id) {
+ this.id = id;
+};
+ONERING.Event.prototype = (new ONERING.Base()).extend({
+ appname: "onering",
+ type: "Event",
+ preventDefault: function() {
+ this._call("Event.preventDefault");
+ }
+ });
+// }}}
+
+// Application {{{
+
+ONERING.Application = function() {
+ this.id = 0;
+};
+ONERING.Application.prototype = (new ONERING.Base()).extend({
+ appname: "onering",
+ type: "Application",
+ setQuitOnLastWindowClosed: function(quit) {
+ return this._call("Application.setQuitOnLastWindowClosed", {quit:
quit}),
+ },
+ exit: function() {
+ this._call("Application.exit");
+ },
+ });
+
+ONERING.application = new ONERING.Application();
+ONERING.getApplication = function() {
+ return ONERING.application;
+};
+
+// }}}
+
+// Window {{{
+
+ONERING.Window = function(obj) {
+ if (!this.validate_type(obj)) {
+ throw new Error("invalid type");
+ }
+ this.id = obj.id;
+};
+ONERING.Window.prototype = (new ONERING.Base()).extend({
+ appname: "onering",
+ type: "Window",
+ createWindow: function(url, width, height, props) {
+ url = ONERING.resolve(url);
+ props.url = url;
+ props.width = width;
+ props.height = height;
+ var window = this._create("Window.create", props);
+ return new ONERING.Window(window);
+ },
+ isAlive: function() {
+ return this._call("Window.isAlive");
+ },
+ showInspector: function() {
+ return this._call("Window.showInspector");
+ },
+ hide: function() {
+ return this._call("Window.hide");
+ },
+ show: function() {
+ return this._call("Window.show");
+ },
+ maximize: function() {
+ return this._call("Window.maximize");
+ },
+ showNormal: function() {
+ return this._call("Window.showNormal");
+ },
+ isMinimized: function() {
+ return this._call("Window.isMinimized");
+ },
+ activateWindow: function() {
+ return this._call("Window.activateWindow");
+ }
+
+ });
+
+ONERING.window = new ONERING.Window({type: "Window",
+ id: _OneRing.getCurrentWindowId()});
+
+ONERING.getCurrentWindow = function() {
+ return ONERING.window;
+};
+
+// shortcuts
+ONERING.createWindow = function(url, width, height, props) {
+ return ONERING.getCurrentWindow().createWindow(url, width, height, props);
+};
+
+// }}}
+
+// System Tray Icon {{{
+
+ONERING.SystemTrayIcon = function(url) {
+ this.id = this._create("create").id;
+ if (url) {
+ this.load(url);
+ }
+};
+ONERING.SystemTrayIcon.prototype = (new ONERING.Base()).extend({
+ appname: "systray",
+ type: "SystemTrayIcon",
+ destroy: function() {
+ this._destroy("destroy");
+ },
+ load: function(url) {
+ return this._call("load", {url: ONERING.resolve(url)});
+ },
+ setContextMenu: function(menu) {
+ return this._call("setContextMenu", {menuId: menu.id});
+ }
+ });
+
+// }}}
+
+// Menu {{{
+
+ONERING.Menu = function(items) {
+ this.id = this._create("Menu.create").id;
+ for (var i=0; i<items.length; i++) {
+ var item = items[i];
+ if (item === ONERING.Menu.SEPARATOR) {
+ this.addSeparator();
+ } else {
+ this.addItem(item[0], item[1], item[2]);
+ }
+ };
+};
+ONERING.Menu.SEPARATOR = Object(); // a const
+ONERING.Menu.prototype = new ONERING.Base();
+ONERING.Menu.prototype.extend({
+ appname: "menu",
+ type: "Menu",
+ destroy: function() {
+ this._destroy("Menu.destroy");
+ },
+ addSeparator: function() {
+ return this._call("Menu.addSeparator");
+ },
+ addItem: function(title, callback, props) {
+ if (!(callback instanceof Function)) {
+ props = callback;
+ callback = null;
+ }
+ var item = new ONERING.MenuItem(this._call("Menu.addMenuItem", {text:
title}));
+ if (callback) {
+ item.bind('triggered', callback);
+ }
+ if (props) {
+ item.setProperties(props);
+ }
+ },
+ get: function(index) {
+ return new ONERING.MenuItem(this._call("Menu.getMenuItem", {index:
index}));
+ }
+ });
+
+ONERING.MenuItem = function(item) {
+ if (!item || item.type != this.type) {
+ throw new Error("invalid menu item");
+ }
+ this.id = item.id;
+};
+ONERING.MenuItem.prototype = (new ONERING.Base()).extend({
+ appname: "menu",
+ type: "MenuItem",
+ setProperties: function(props) {
+ return this._call("MenuItem.setProperties", props);
+ },
+ setText: function(text) {
+ return this._call("MenuItem.setText", {text: text});
+ },
+ setEnabled: function(enabled) {
+ return this.setProperties({enabled: enabled});
+ },
+ });
+
+// }}}
+
+// HotKey {{{
+
+ONERING.HotKey = function() {
+};
+ONERING.HotKey.prototype = (new ONERING.Base()).extend({
+ appname: "hotkey",
+ type: "HotKey",
+ destroy: function() {
+ return this._call("destroy");
+ },
+ });
+ONERING.HotKey.instances = {};
+ONERING.HotKey.create = function(shortcut) {
+ var hotkey = new ONERING.HotKey();
+ hotkey.id = (hotkey._create("create", {shortcut: shortcut})).id;
+ ONERING.HotKey.instances[shortcut] = hotkey;
+ return hotkey;
+};
+ONERING.HotKey.set = function(shortcut, callback) {
+ var hotkey = ONERING.HotKey.instances[shortcut] || new
ONERING.HotKey.create(shortcut);
+ hotkey.bind("activated", callback);
+};
+ONERING.HotKey.clear = function(shortcut) {
+ var hotkey = ONERING.HotKey.instances[shortcut];
+ if (hotkey !== undefined) {
+ hotkey.destroy();
+ delete ONERING.HotKey.instances[shortcut];
+ }
+};
+ONERING.setHotKey = ONERING.HotKey.set;
+ONERING.clearHotKey = ONERING.HotKey.clear;
+
+window.addEventListener('unload', function() {
+ for (var shortcut in ONERING.HotKey.instances) {
+ ONERING.HotKey.clear(shortcut);
+ }
+ });
+
+// }}}
+
+// subscribe/unsubscribe {{{
+
+ONERING.subscriptions = {};
+ONERING.hub = _OneRing.getPubSubHub().published;
+
+ONERING.subscribe = function(channel, callback) {
+ var ss = ONERING.subscriptions[channel] = ONERING.subscriptions[channel] |
| {};
+ var f = ss[callback] = ss[callback] || function(ch, msg) {
+ if (ch === channel) {
+ callback(JSON.parse(msg));
+ }
+ };
+ ONERING.hub.connect(f);
+};
+
+ONERING.unsubscribe = function(channel, callback) {
+ if (channel === undefined) {
+ for (channel in ONERING.subscriptions) {
+ ONERING.unsubscribe(channel);
+ }
+ } else {
+ var ss = ONERING.subscriptions[channel];
+ if (ss) {
+ if (callback === undefined) {
+ for (callback in ss) {
+ ONERING.hub.disconnect(ss[callback]);
+ }
+ delete ONERING.subscriptions[channel];
+ } else {
+ var f = ss[callback];
+ if (f) {
+ ONERING.hub.disconnect(f);
+ delete ss[callback];
+ }
+ }
+ }
+ }
+};
+
+window.addEventListener('unload', function() {
+ ONERING.unsubscribe();
+ });
+
+// }}}
+
+// functions {{{
+
+ONERING.log = function(o) {
+ return _OneRing.log(o);
+};
+
+ONERING.callback = function(name, para) {
+ var window_id = name.split('_')[1];
+ if (window_id != ONERING._window_id) {
+ return;
+ }
+ var f = _get_registered_function(name);
+ if (f) {
+ f(para);
+ }
+};
+
+ONERING.exit = function() {
+ ONERING.getApplication().exit();
+};
+
+ONERING.ajax = function(settings) {
+ var url = settings.url;
+ var data = settings.data || "";
+ if ( data instanceof Object ) {
+ data = ONERING.param(data);
+ }
+ var type = settings.type || "GET";
+ var dataType = settings.dataType;
+ var success = settings.success;
+ var async = settings.async || true;
+
+ if (data && type == "GET") {
+ url += ((url.indexOf('?') < 0) ? '?' : '&') + data;
+ data = "";
+ }
+
+ _OneRing.ajax(type, url, data, _register_function(function(s) {
+ if (dataType == "json") {
+ s = window.JSON.parse(s);
+ }
+ success && success(s);
+ }), async);
+};
+
+ONERING.get = function(url, data, callback, dataType) {
+ if (data instanceof Function) {
+ dataType = dataType || callback;
+ callback = data;
+ data = null;
+ }
+
+ return ONERING.ajax({
+ type: "GET",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: dataType
+ });
+};
+
+ONERING.getJSON = function(url, data, callback) {
+ return ONERING.get(url, data, callback, "json");
+};
+
+ONERING.post = function(url, data, callback, dataType) {
+ if (data instanceof Function) {
+ dataType = dataType || callback;
+ callback = data;
+ data = null;
+ }
+
+ return ONERING.ajax({
+ type: "POST",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: dataType
+ });
+};
+
+ONERING.call_app = function(appname, command, param) {
+ var url = appname ? ("onering://"+appname+"/"+command) : ("/"+command);
+ var data = JSON.stringify(param || {});
+ var r = _OneRing.call("POST", url, data);
+ r = JSON.parse(r);
+ if (r && r.err) {
+ throw new Error("ONERING.call_app("+appname+", "+command+") failed: " +
r.err);
+ }
+ return r;
+};
+
+ONERING.resolve = function(url) {
+ return _OneRing.resolve(url);
+};
+
+// }}}
+
+// internal utilities {{{
+
+var _guid = 0;
+var _get_guid = function() {
+ _guid += 1;
+ return '' + _guid;
+};
+
+ONERING._window_id = Math.floor(Math.random()*1000000);
+
+var _registered_functions = new Object();
+var _register_function = function(func) {
+ var name = 'f_' + ONERING._window_id + '_' + _get_guid();
+ _registered_functions[name] = func;
+ return name;
+};
+var _get_registered_function = function(name) {
+ return _registered_functions[name];
+};
+
+ONERING.param = function(a) {
+ var s = [];
+ for (var key in a) {
+ var value = a[key];
+ s.push( encodeURIComponent(key) + "=" + encodeURIComponent(value) );
+ }
+ return s.join("&").replace(/%20/g, "+");
+};
+
+// }}}
+
+// vim:set foldmethod=marker:
=======================================
--- /dev/null
+++ /qtcore/onering.pro Wed Aug 31 02:54:24 2011
@@ -0,0 +1,96 @@
+######################################################################
+# Automatically generated by qmake (2.01a) Thu Aug 19 21:40:02 2010
+######################################################################
+
+TEMPLATE = lib
+TARGET = OneRing
+DEPENDPATH += . ../include src
+INCLUDEPATH += . ../include
+QT += webkit network
+RESOURCES = onering.qrc
+CONFIG += shared
+DEFINES += ONERING_LIBRARY
+VERSION = 1
+macx {
+ CONFIG += lib_bundle
+ FRAMEWORK_HEADERS.version = Versions
+ FRAMEWORK_HEADERS.files = ../include/onering.h
+ FRAMEWORK_HEADERS.path = Headers
+ QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS
+ QMAKE_FRAMEWORK_BUNDLE_NAME = OneRing
+ QMAKE_FRAMEWORK_VERSION = $$VERSION
+}
+
+!release {
+ DEFINES += DEBUG
+}
+
+# Input
+HEADERS += \
+ ../include/onering.h \
+ src/app.h \
+ src/application.h \
+ src/appreply.h \
+ src/dataloader.h \
+ src/debugger.h \
+ src/jsapi.h \
+ src/json.h \
+ src/menu.h \
+ src/networkaccessmanager.h \
+ src/oneringapp.h \
+ src/oneringview.h \
+ src/publishevent.h \
+ src/pubsubhub.h \
+ src/systemtrayicon.h
+
+SOURCES += \
+ src/app.cpp \
+ src/application.cpp \
+ src/appreply.cpp \
+ src/dataloader.cpp \
+ src/debugger.cpp \
+ src/jsapi.cpp \
+ src/json.cpp \
+ src/menu.cpp \
+ src/networkaccessmanager.cpp \
+ src/onering.cpp \
+ src/oneringapp.cpp \
+ src/oneringview.cpp \
+ src/publishevent.cpp \
+ src/pubsubhub.cpp \
+ src/systemtrayicon.cpp
+
+# global shourtcut
+HEADERS += \
+ src/hotkey.h \
+ src/qxtglobalshortcut.h \
+ src/qxtglobal.h \
+ src/qxtglobalshortcut_p.h
+
+SOURCES += \
+ src/hotkey.cpp \
+ src/qxtglobalshortcut.cpp
+
+macx:SOURCES += src/qxtglobalshortcut_mac.cpp
+win32:SOURCES += src/qxtglobalshortcut_win.cpp
+unix:!macx:SOURCES += src/qxtglobalshortcut_x11.cpp
+macx:LIBS += -framework Carbon
+win32 {
+ win32-g++:LIBS += -l user32
+ !win32-g++:LIBS += user32.lib
+}
+# end of global shortcut
+
+# dock icon click
+macx {
+ HEADERS += \
+ src/cocoainit.h \
+ src/dockiconclick.h
+
+ OBJECTIVE_SOURCES += \
+ src/cocoainit.mm \
+ src/dockiconclick.mm
+
+ LIBS += -framework AppKit
+}
+# end dock icon click
=======================================
--- /dev/null
+++ /qtcore/onering.qrc Wed Aug 31 02:54:24 2011
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>js/onering.js</file>
+</qresource>
+</RCC>
=======================================
--- /dev/null
+++ /qtcore/src/app.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,158 @@
+#include <QDebug>
+#include <QString>
+#include <QHash>
+#include <QPair>
+#include <QUrl>
+#include <string.h>
+#include <assert.h>
+#include <onering.h>
+#include "app.h"
+#include "json.h"
+
+QHash<QString, QPair<onering_app_func_t, onering_free_response_func_t> >
g_apps;
+
+int onering_register_app(const char* appname, onering_app_func_t app_func,
onering_free_response_func_t free_response_func)
+{
+ if (strlen(appname) > ONERING_MAX_APPNAME_LEN) {
+ return -1;
+ }
+
+ qDebug() << "register app:" << appname;
+ QPair<onering_app_func_t, onering_free_response_func_t> funcs(app_func,
free_response_func);
+ g_apps[appname] = funcs;
+ return 0;
+}
+
+int is_appname_registered(const QString &appname)
+{
+ return g_apps.contains(appname);
+}
+
+QByteArray call_app(const QString &method, const QUrl &url, const QString
&body)
+{
+ QString appname = url.host();
+ const char * response;
+ int response_len;
+ onering_response_handle_t response_handle;
+ QByteArray retval;
+
+ if (is_appname_registered(appname)) {
+ QByteArray surl = url.toString().toUtf8();
+ QByteArray path_query = url.path().toUtf8();
+ if (url.hasQuery()) {
+ path_query += surl.mid(surl.indexOf('?'));
+ }
+
+ response_handle = g_apps[appname].first(qPrintable(appname),
qPrintable(method), path_query, body.toUtf8().constData(), &response,
&response_len);
+ retval.append(response, response_len);
+ // free response
+ g_apps[appname].second(qPrintable(appname), response_handle);
+ }
+
+ return retval;
+}
+
+QByteArray call_app_body(const QString &method, const QUrl &url, const
QString &body)
+{
+ QByteArray response = call_app(method, url, body);
+
+ int index;
+ if ((index = response.indexOf("\r\n")) < 0) {
+ // not header/body seperator found.
+ // consider the whole response is body
+ return response;
+ }
+ QByteArray line = response.left(index);
+ if (line.indexOf("200") < 0) {
+ qDebug() << "error status line:" << line;
+ return "";
+ }
+
+ if ((index = response.indexOf("\r\n\r\n")) < 0) {
+ qDebug() << "Body not found:" << response;
+ return "";
+ }
+ response.remove(0, index+4);
+ return response;
+}
+
+App::App(const QString& appname, QObject* parent)
+ : QObject(parent),
+ appname(appname)
+{
+}
+
+onering_response_handle_t App::processRequest(const char* appname,
+ const char* method, const QString& path, const QByteArray& body,
+ const char** response, int* response_len)
+{
+ Q_UNUSED(appname);
+ Q_UNUSED(method);
+
+ assert(path.startsWith("/"));
+
+ QByteArray* res = new QByteArray();
+
+ QVariantMap param = Json::parse(QString::fromUtf8(body)).toMap();
+ *res = processCall(path.mid(1), param);
+
+ *response = res->constData();
+ *response_len = res->size();
+ return reinterpret_cast<onering_response_handle_t>(res);
+}
+
+void App::freeResponse(const char* appname, onering_response_handle_t
handle)
+{
+ Q_UNUSED(appname);
+
+ delete reinterpret_cast<QByteArray *>(handle);
+}
+
+QString App::generateObjectId(void* obj)
+{
+ return QString::number(reinterpret_cast<unsigned long>(obj), 16);
+}
+
+
+QString App::getId(QObject* obj)
+{
+ connect(obj, SIGNAL(destroyed(QObject*)),
+ this, SLOT(instanceDestroyed(QObject*)),
+ Qt::UniqueConnection);
+ return generateObjectId(obj);
+}
+
+QString App::getId(void* obj)
+{
+ return generateObjectId(obj);
+}
+
+void* App::getInstance(const QString& id)
+{
+ bool ok;
+ return reinterpret_cast<void *>(id.toULong(&ok, 16));
+}
+
+void App::instanceDestroyed(QObject* obj)
+{
+ qDebug() << obj << "deleted";
+}
+
+void App::publishEvent(const QString& type, void* sender, const QString&
event)
+{
+ publishEvent(type, sender, event, "null");
+}
+
+void App::publishEvent(const QString& type, void* sender, const QString&
event, QEvent* e)
+{
+ QString data = QString("{\"event_id\":\"%1\"}").arg(getId(e));
+ publishEvent(type, sender, event, data);
+}
+
+
+void App::publishEvent(const QString& type, void* sender, const QString&
event, const QString& data)
+{
+ onering_publish(qPrintable(QString("%1.%2.%3.%4")
+ .arg(appname, type, getId(sender), event)),
+ qPrintable(data));
+}
=======================================
--- /dev/null
+++ /qtcore/src/app.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,46 @@
+#ifndef APP_H
+#define APP_H
+
+#include <onering.h>
+#include <QString>
+#include <QUrl>
+#include <QByteArray>
+#include <QVariantMap>
+#include <QEvent>
+#include <QSet>
+
+int is_appname_registered(const QString &appname);
+
+QByteArray call_app(const QString& method, const QUrl &url, const QString
&body);
+QByteArray call_app_body(const QString &method, const QUrl &url, const
QString &body);
+
+class App : public QObject
+{
+ Q_OBJECT
+
+public:
+ App(const QString& appname, QObject *parent=0);
+
+ onering_response_handle_t processRequest(const char* appname, const char*
method, const QString& path, const QByteArray& body, const char** response,
int* response_len);
+ void freeResponse(const char* appname, onering_response_handle_t
response_handle);
+
+ static QString generateObjectId(void* obj);
+
+private slots:
+ void instanceDestroyed(QObject* obj);
+
+protected:
+ QString getId(QObject* obj);
+ QString getId(void* obj);
+ void* getInstance(const QString& id);
+ void publishEvent(const QString& type, void* sender, const QString&
event);
+ void publishEvent(const QString& type, void* sender, const QString&
event, QEvent* e);
+ void publishEvent(const QString& type, void* sender, const QString&
event, const QString& data);
+
+private:
+ virtual QByteArray processCall(const QString& command, const QVariantMap&
param) = 0;
+
+ QString appname;
+};
+
+#endif
=======================================
--- /dev/null
+++ /qtcore/src/application.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,133 @@
+#include <QDir>
+#include <QDebug>
+#include <QWebSettings>
+#include <QWebSecurityOrigin>
+#include <QVariantMap>
+#include <QDesktopServices>
+#include <QApplication>
+#include <QUrl>
+#include <onering.h>
+#include "application.h"
+#include "oneringapp.h"
+#include "app.h"
+#include "oneringview.h"
+#include "dataloader.h"
+#include "debugger.h"
+#include "json.h"
+#include "dockiconclick.h"
+
+// plugins
+#include "menu.h"
+#include "systemtrayicon.h"
+#include "hotkey.h"
+
+static QUrl getAbsUrl(const QString &url, const QString &appname)
+{
+ QUrl u(url);
+
+ if (u.isRelative()) {
+ u.setScheme("onering");
+ u.setHost(appname);
+ }
+ return u;
+}
+
+Application::Application(int &argc, char **argv)
+ : QApplication(argc, argv),
+ quiting(false)
+{
+#ifdef Q_WS_MAC
+#ifdef QT_MAC_USE_COCOA
+ connect(&_dockIconClickMonitor, SIGNAL(dockIconClicked()),
+ this, SIGNAL(dockIconClicked()));
+#endif
+#endif
+}
+
+Application::~Application()
+{
+ quiting = true;
+}
+
+int Application::load(const char* appname)
+{
+#ifdef Q_OS_MAC
+ QDir plugins_dir = QCoreApplication::applicationDirPath();
+ if (!plugins_dir.path().startsWith("/System/")) {
+ plugins_dir.cd("../plugins");
+ QCoreApplication::setLibraryPaths(QStringList(plugins_dir.path()));
+ }
+#endif
+ qDebug() << "plugins dir:" << QCoreApplication::libraryPaths();
+
+ QWebSettings *settings = QWebSettings::globalSettings();
+ settings->setAttribute(QWebSettings::JavascriptCanOpenWindows, true);
+ settings->setAttribute(QWebSettings::JavascriptCanAccessClipboard, true);
+ settings->setAttribute(QWebSettings::LocalStorageEnabled, true);
+ settings->setAttribute(QWebSettings::LocalStorageDatabaseEnabled, true);
+ settings->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls,
true);
+ settings->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
+
+ QWebSecurityOrigin::addLocalScheme("onering");
+
+ register_onering_app("onering");
+
+ // register plugin apps
+ register_menu_app("menu");
+ register_systray_app("systray");
+ register_hotkey_app("hotkey");
+
+ QUrl initurl;
+ initurl.setScheme("onering");
+ initurl.setHost(appname);
+ initurl.setPath("/init");
+ QByteArray response = call_app_body("GET", initurl, "");
+
+ QVariantMap props = Json::parse(QString::fromLocal8Bit(response)).toMap();
+
+ QString s;
+ QUrl url;
+ QDir dir;
+
+ QString real_appname = props.value("appname", appname).toString();
+ qDebug() << "appname:" << real_appname;
+ QCoreApplication::setApplicationName(real_appname);
+
+ s = props.value("storageDir").toString();
+ dir = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
+ s = QDir::cleanPath(dir.filePath(s));
+ qDebug() << "data location:" << s;
+ settings->setLocalStoragePath(s);
+
+ s = props.value("icon").toString();
+ if (!s.isEmpty()) {
+ url = getAbsUrl(s, appname);
+ DataLoader *dataloader = new DataLoader();
+ Debugger::traceObj(dataloader);
+ connect(dataloader, SIGNAL(got(QByteArray&)),
+ this, SLOT(setWindowIconByData(QByteArray&)));
+ connect(dataloader, SIGNAL(got(QByteArray&)),
+ dataloader, SLOT(deleteLater()));
+ dataloader->load(url);
+ }
+
+ s = props["url"].toString();
+ if (s.isEmpty()) {
+ s = "/";
+ }
+ props["url"] = getAbsUrl(s, appname);
+
+ OneRingView* window = OneRingApp::createWindow(props);
+
+ window->show();
+ return 0;
+}
+
+void Application::setWindowIconByData(QByteArray &data)
+{
+ qDebug() << "setWindowIconByData";
+ QPixmap pixmap;
+ pixmap.loadFromData(data);
+ setWindowIcon(QIcon(pixmap));
+}
+
=======================================
--- /dev/null
+++ /qtcore/src/application.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,44 @@
+#ifndef APPLICATION_H
+#define APPLICATION_H
+
+#include <QApplication>
+#include <QObject>
+#include "pubsubhub.h"
+#ifdef Q_WS_MAC
+#ifdef QT_MAC_USE_COCOA
+#include "dockiconclick.h"
+#endif
+#endif
+
+class Application : public QApplication
+{
+ Q_OBJECT
+
+public:
+ Application(int &argc, char **argv);
+ ~Application();
+
+ int load(const char* appname);
+ PubSubHub pubsubhub;
+ bool quiting;
+
+public slots:
+ void setWindowIconByData(QByteArray &data);
+
+signals:
+#ifdef Q_WS_MAC
+#ifdef QT_MAC_USE_COCOA
+ void dockIconClicked();
+#endif
+#endif
+
+#ifdef Q_WS_MAC
+#ifdef QT_MAC_USE_COCOA
+private:
+ DockIconClickMonitor _dockIconClickMonitor;
+#endif
+#endif
+
+};
+
+#endif
=======================================
--- /dev/null
+++ /qtcore/src/appreply.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,121 @@
+#include <QDebug>
+#include <QtNetwork>
+#include <QIODevice>
+#include <QTimer>
+#include <string.h>
+#include <onering.h>
+#include "appreply.h"
+#include "app.h"
+
+
+AppReply::AppReply(const QUrl &url, QObject *parent)
+ : QNetworkReply(parent)
+{
+ AppReply("GET", url, 0, parent);
+}
+
+AppReply::AppReply(const char* method, const QUrl &url, QIODevice
*body_device, QObject *parent)
+ : QNetworkReply(parent)
+{
+ this->method = method;
+ this->url = url;
+ this->body_device = body_device;
+
+ if (body_device) {
+ qDebug() << "body_device connect";
+ connect(body_device, SIGNAL(readyRead()),
+ this, SLOT(readBody()));
+ } else {
+ QTimer::singleShot(0, this, SLOT(parseResponse()));
+ }
+}
+
+void AppReply::readBody()
+{
+ qDebug() << "body_device readyRead";
+ this->body += this->body_device->readAll();
+ if (this->body_device->atEnd()) {
+ parseResponse();
+ }
+}
+
+void AppReply::parseResponse()
+{
+ content = call_app(method, url, body);
+ offset = 0;
+
+ open(ReadOnly | Unbuffered);
+
+ // default attribute
+ setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 200);
+ setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/html;
charset=UTF-8"));
+
+ // TODO speed optimization needed
+ int index;
+ bool ok;
+ int code;
+ QByteArray line, key, value;
+ QList<QByteArray> words;
+ if ((index = content.indexOf("\r\n")) < 0) {
+ goto finish;
+ }
+ line = content.left(index);
+ words = line.split(' ');
+ if (words.size() < 3) {
+ goto finish;
+ }
+ code = words[1].toInt(&ok);
+ if (!ok) {
+ goto finish;
+ }
+ setAttribute(QNetworkRequest::HttpStatusCodeAttribute, code);
+ offset = index + 2;
+
+ // iterate over lines of header
+ for(; (index = content.indexOf("\r\n", offset)) > offset; offset=index+2)
{
+ line = content.mid(offset, index-offset);
+ int pos = line.indexOf(':');
+ if (pos <= 0) {
+ continue;
+ }
+ key = line.left(pos);
+ value = line.mid(pos+1).trimmed();
+ setRawHeader(key, value);
+ }
+
+ if (index == offset) {
+ // the CRLF seperate headers and body
+ offset += 2;
+ }
+
+finish:
+// qDebug() << "body:" << content.mid(offset);
+ emit readyRead();
+ emit finished();
+}
+
+void AppReply::abort()
+{
+}
+
+qint64 AppReply::bytesAvailable() const
+{
+ return content.size() - offset;
+}
+
+bool AppReply::isSequential() const
+{
+ return true;
+}
+
+qint64 AppReply::readData(char *data, qint64 maxSize)
+{
+ if (offset < content.size()) {
+ qint64 number = qMin(maxSize, content.size() - offset);
+ memcpy(data, content.constData() + offset, number);
+ offset += number;
+ return number;
+ } else
+ return -1;
+}
+
=======================================
--- /dev/null
+++ /qtcore/src/appreply.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,34 @@
+#ifndef APPREPLY_H
+#define APPREPLY_H
+
+#include <QNetworkReply>
+#include <QIODevice>
+
+class AppReply : public QNetworkReply
+{
+ Q_OBJECT
+
+public:
+ AppReply(const QUrl &url, QObject *parent=0);
+ AppReply(const char* method, const QUrl &url, QIODevice *body_device=0,
QObject *parent=0);
+ void abort();
+ qint64 bytesAvailable() const;
+ bool isSequential() const;
+
+protected:
+ qint64 readData(char *data, qint64 maxSize);
+
+private slots:
+ void readBody();
+ void parseResponse();
+
+private:
+ QIODevice *body_device;
+ QByteArray body;
+ QString method;
+ QUrl url;
+ QByteArray content;
+ qint64 offset;
+};
+
+#endif
=======================================
--- /dev/null
+++ /qtcore/src/cocoainit.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,15 @@
+#ifndef ONERING_COCOAINIT_H
+#define ONERING_COCOAINIT_H
+
+class CocoaInitializer
+{
+ public:
+ CocoaInitializer();
+ ~CocoaInitializer();
+
+ private:
+ class Private;
+ Private* d;
+};
+
+#endif
=======================================
--- /dev/null
+++ /qtcore/src/cocoainit.mm Wed Aug 31 02:54:24 2011
@@ -0,0 +1,21 @@
+#include <AppKit/AppKit.h>
+#include "cocoainit.h"
+
+class CocoaInitializer::Private
+{
+ public:
+ NSAutoreleasePool* autoReleasePool;
+};
+
+CocoaInitializer::CocoaInitializer()
+{
+ d = new CocoaInitializer::Private();
+ NSApplicationLoad();
+ d->autoReleasePool = [[NSAutoreleasePool alloc] init];
+}
+
+CocoaInitializer::~CocoaInitializer()
+{
+ [d->autoReleasePool release];
+ delete d;
+}
=======================================
--- /dev/null
+++ /qtcore/src/dataloader.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,27 @@
+#include <QDebug>
+#include <QNetworkRequest>
+#include "networkaccessmanager.h"
+#include "dataloader.h"
+#include "debugger.h"
+
+DataLoader::DataLoader(QObject *parent)
+ : QObject(parent)
+{
+}
+
+void DataLoader::load(const QUrl &url)
+{
+ NetworkAccessManager *manager = new NetworkAccessManager(this);
+ Debugger::traceObj(manager);
+ connect(manager, SIGNAL(finished(QNetworkReply*)),
+ this, SLOT(fetched(QNetworkReply*)));
+ manager->get(QNetworkRequest(url));
+}
+
+void DataLoader::fetched(QNetworkReply *reply)
+{
+ QByteArray data = reply->readAll();
+ emit got(data);
+
+ reply->manager()->deleteLater();
+}
=======================================
--- /dev/null
+++ /qtcore/src/dataloader.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,24 @@
+#ifndef DATALOADER_H
+#define DATALOADER_H
+
+#include <QObject>
+#include <QUrl>
+#include <QNetworkReply>
+
+class DataLoader : public QObject
+{
+ Q_OBJECT
+
+public:
+ DataLoader(QObject *parent=0);
+ void load(const QUrl &url);
+
+signals:
+ void got(QByteArray &data);
+
+private slots:
+ void fetched(QNetworkReply *reply);
+};
+
+
+#endif
=======================================
--- /dev/null
+++ /qtcore/src/debugger.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,23 @@
+#include <QDebug>
+#include "debugger.h"
+
+static Debugger *debugger = 0;
+
+void Debugger::traceObj(QObject *obj)
+{
+#ifdef DEBUG
+ qDebug() << "=== NEW" << obj;
+ if (!debugger) {
+ debugger = new Debugger();
+ }
+ connect(obj, SIGNAL(destroyed(QObject*)),
+ debugger, SLOT(printDestroyed(QObject*)));
+#endif
+}
+
+void Debugger::printDestroyed(QObject *obj)
+{
+#ifdef DEBUG
+ qDebug() << "=== DEL" << obj;
+#endif
+}
=======================================
--- /dev/null
+++ /qtcore/src/debugger.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,17 @@
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#include <QObject>
+
+class Debugger : public QObject
+{
+ Q_OBJECT
+
+public:
+ static void traceObj(QObject *obj);
+
+public slots:
+ void printDestroyed(QObject *obj);
+};
+
+#endif
=======================================
--- /dev/null
+++ /qtcore/src/dockiconclick.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,24 @@
+#ifndef ONERING_DOCKICONCLICK_H
+#define ONERING_DOCKICONCLICK_H
+
+#include <QObject>
+
+class DockIconClickMonitor : public QObject
+{
+ Q_OBJECT
+
+ public:
+ DockIconClickMonitor();
+ ~DockIconClickMonitor();
+
+ void emitEvent();
+
+ signals:
+ void dockIconClicked();
+
+ private:
+ class Private;
+ Private* d;
+};
+
+#endif
=======================================
--- /dev/null
+++ /qtcore/src/dockiconclick.mm Wed Aug 31 02:54:24 2011
@@ -0,0 +1,47 @@
+#include <Cocoa/Cocoa.h>
+#include <QDebug>
+#include "dockiconclick.h"
+
+@interface DockIconClickEventHandler : NSObject
+{
+@public
+ DockIconClickMonitor* monitor;
+}
+- (void)handle:(NSAppleEventDescriptor*)event
withReplyEvent:(NSAppleEventDescriptor*)replyEvent;
+@end
+
+@implementation DockIconClickEventHandler
+- (void)handle:(NSAppleEventDescriptor*)event
withReplyEvent:(NSAppleEventDescriptor*)replyEvent {
+ if (monitor)
+ monitor->emitEvent();
+}
+@end
+
+class DockIconClickMonitor::Private
+{
+ public:
+ DockIconClickEventHandler* handler;
+};
+
+DockIconClickMonitor::DockIconClickMonitor()
+{
+ d = new DockIconClickMonitor::Private();
+ d->handler = [[DockIconClickEventHandler alloc] init];
+ d->handler->monitor = this;
+
+ [[NSAppleEventManager sharedAppleEventManager]
+ setEventHandler:d->handler
+ andSelector:@selector(handle:withReplyEvent:)
+ forEventClass:kCoreEventClass
+ andEventID:kAEReopenApplication];
+}
+
+DockIconClickMonitor::~DockIconClickMonitor()
+{
+ delete d;
+}
+
+void DockIconClickMonitor::emitEvent()
+{
+ emit dockIconClicked();
+}
=======================================
--- /dev/null
+++ /qtcore/src/hotkey.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,59 @@
+#include <QDebug>
+#include "hotkey.h"
+
+static HotKeyApp* g_app = 0;
+
+HotKeyApp::HotKeyApp(const QString& appname, QObject *parent)
+ : App(appname, parent)
+{
+}
+
+QByteArray HotKeyApp::processCall(const QString& command, const
QVariantMap& param)
+{
+ QxtGlobalShortcut* shortcut;
+ if (command == "create") {
+ shortcut = new
QxtGlobalShortcut(QKeySequence(param["shortcut"].toString()));
+ connect(shortcut, SIGNAL(activated()),
+ this, SLOT(activated()));
+ return
QString("{\"type\":\"HotKey\",\"id\":\"%1\"}").arg(getId(shortcut)).toLatin1();
+ }
+
+ shortcut = static_cast<QxtGlobalShortcut
*>(getInstance(param["id"].toString()));
+ if (!shortcut) {
+ return "{\"err\":\"invalid id\"}";
+ }
+
+ if (command == "destroy") {
+ delete shortcut;
+ return "null";
+ }
+ return "{\"err\":\"invalid command\"}";
+}
+
+void HotKeyApp::activated()
+{
+ qDebug() << "activated";
+ publishEvent("HotKey", sender(), "activated");
+}
+
+static onering_response_handle_t app(const char* appname, const char*
method,
+ const char* path, const char* body,
+ const char** response, int* response_len)
+{
+ if (!g_app) {
+ g_app = new HotKeyApp(appname);
+ }
+
+ return g_app->processRequest(appname, method, path, body, response,
response_len);
+}
+
+
+static void app_free_response(const char* appname,
onering_response_handle_t response_handle)
+{
+ g_app->freeResponse(appname, response_handle);
+}
+
+void register_hotkey_app(const char* appname)
+{
+ onering_register_app(appname, &app, &app_free_response);
+}
=======================================
--- /dev/null
+++ /qtcore/src/hotkey.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,23 @@
+#ifndef HOTKEY_H
+#define HOTKEY_H
+
+#include "qxtglobalshortcut.h"
+#include "app.h"
+
+class HotKeyApp : public App
+{
+ Q_OBJECT
+
+public:
+ HotKeyApp(const QString& appname, QObject *parent=0);
+
+private slots:
+ void activated();
+
+private:
+ QByteArray processCall(const QString& command, const QVariantMap& param);
+};
+
+void register_hotkey_app(const char* appname);
+
+#endif
=======================================
--- /dev/null
+++ /qtcore/src/jsapi.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,127 @@
+// includes {{{
+#include <QDebug>
+#include <QApplication>
+#include <qwebview.h>
+#include <qwebframe.h>
+#include <QWebInspector>
+#include <QIcon>
+#include <QUrl>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#include <QSystemTrayIcon>
+#include <QApplication>
+#include "jsapi.h"
+#include "oneringview.h"
+#include "app.h"
+#include "networkaccessmanager.h"
+#include "systemtrayicon.h"
+#include "menu.h"
+#include "hotkey.h"
+#include "debugger.h"
+#include "application.h"
+// }}}
+
+// public methods {{{
+
+JsApi::JsApi(QObject *parent)
+ : QObject(parent)
+{
+}
+
+JsApi::~JsApi()
+{
+}
+
+void JsApi::setWebView(QWebView *view)
+{
+ QWebPage *page = view->page();
+ frame = page->mainFrame();
+
+ attachObject();
+ connect(frame, SIGNAL(javaScriptWindowObjectCleared()), this,
SLOT(attachObject()));
+}
+
+void JsApi::setWindow(QWidget *window)
+{
+ this->window = window;
+}
+
+void JsApi::attachObject()
+{
+ frame->addToJavaScriptWindowObject(QString("_OneRing"), this);
+}
+
+void JsApi::invokeCallback(const QString &funcname)
+{
+ qDebug() << "invokeCallback" << funcname;
+
+ frame->evaluateJavaScript(QString("ONERING.callback('%1');
null;").arg(funcname));
+}
+
+void JsApi::invokeCallback(const QString &funcname, const QString &param)
+{
+ qDebug() << "invokeCallback" << funcname << param;
+
+ QString jsparam = param;
+ // escape javascript string
+ jsparam.replace('\\', "\\\\").replace('\'', "\\'");
+ frame->evaluateJavaScript(
+ QString("ONERING.callback('%1', '%2'); null;")
+ .arg(funcname, jsparam));
+}
+
+// }}}
+
+// javascript api {{{
+
+QVariant JsApi::test(QVariant param)
+{
+ qDebug() << param;
+ return QVariant();
+}
+
+void JsApi::log(const QString &s)
+{
+ qDebug() << "JsApi::log" << s;
+}
+
+QString JsApi::call(const QString &method, const QString &url, const
QString &body) const
+{
+ qDebug() << "JsApi::call" << method << url << body;
+ QUrl absurl = frame->baseUrl().resolved(url);
+ QString response = call_app_body(method, absurl, body);
+ if (response.isEmpty()) {
+ response = "null";
+ }
+ qDebug() << "JsApi::call" << url << "returns" << response;
+ return response;
+}
+
+void JsApi::ajax(const QString &type, const QString &url, const QString
&body, const QString &callback, bool async)
+{
+ Q_UNUSED(async);
+
+ qDebug() << "JsApi::ajax" << type << url << body << callback;
+ QUrl absurl = frame->baseUrl().resolved(url);
+ QByteArray response = call_app_body(type, absurl, body);
+ invokeCallback(callback, response);
+}
+
+QString JsApi::getCurrentWindowId()
+{
+ return App::generateObjectId(window);
+}
+
+QObject* JsApi::getPubSubHub()
+{
+ return &(static_cast<Application *>(qApp)->pubsubhub);
+}
+
+QString JsApi::resolve(const QString &relative)
+{
+ return frame->baseUrl().resolved(relative).toString();
+}
+
+// }}}
+
+// vim:set foldmethod=marker:
=======================================
--- /dev/null
+++ /qtcore/src/jsapi.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,52 @@
+#ifndef JSAPI_H
+#define JSAPI_H
+
+#include <qobject.h>
+#include <QWebInspector>
+#include <QHash>
+#include <QList>
+#include <QVariantMap>
+
+class QWebView;
+class QWebFrame;
+class OneRingView;
+
+typedef QPair<QObject*, QString> EventSource;
+
+class JsApi : public QObject
+{
+ Q_OBJECT
+
+public:
+ JsApi(QObject *parent);
+ ~JsApi();
+
+ void setWebView(QWebView *view);
+ void setWindow(QWidget *window);
+ void invokeCallback(const QString &funcname);
+ void invokeCallback(const QString &funcname, const QString &param);
+
+ Q_INVOKABLE QObject* getPubSubHub(void);
+ Q_INVOKABLE QString resolve(const QString &relative);
+ Q_INVOKABLE QString call(const QString& method, const QString& url,
+ const QString& body) const;
+
+public slots:
+ QVariant test(QVariant param);
+
+ void log(const QString &s);
+ void ajax(const QString &type, const QString &url, const QString &body,
const QString &callback, bool async);
+ QString getCurrentWindowId();
+
+private slots:
+ void attachObject();
+
+private:
+ QWidget *window;
+ QWebFrame *frame;
+ QHash< EventSource, QList<QString> > callbacks;
+
+ void registerCallback(QObject *sender, const QString &event, const
QString &callback_funcname);
+};
+
+#endif
=======================================
--- /dev/null
+++ /qtcore/src/json.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,428 @@
+/**
+ * \file json.h
+ *
+ * \author Eeli Reilin <ee...@nilier.org>,
+ * Mikko Ahonen <mikko.j...@jyu.fi>
+ * \version 0.1
+ * \date 8/25/2010
+ */
+
+#include <QDebug>
+
+#include "json.h"
+
+/**
+ * parse
+ */
+QVariant Json::parse(const QString &json)
+{
+ bool success = true;
+ return Json::parse(json, success);
+}
+
+/**
+ * parse
+ */
+QVariant Json::parse(const QString &json, bool &success)
+{
+ success = true;
+
+ //Return an empty QVariant if the JSON data is either null or empty
+ if(!json.isNull() || !json.isEmpty())
+ {
+ QString data = json;
+ //We'll start from index 0
+ int index = 0;
+
+ //Parse the first value
+ QVariant value = Json::parseValue(data, index, success);
+
+ //Return the parsed value
+ return value;
+ }
+ else
+ {
+ //Return the empty QVariant
+ return QVariant();
+ }
+}
+
+/**
+ * parseValue
+ */
+QVariant Json::parseValue(const QString &json, int &index, bool &success)
+{
+ //Determine what kind of data we should parse by
+ //checking out the upcoming token
+ switch(Json::lookAhead(json, index))
+ {
+ case JsonTokenString:
+ return Json::parseString(json, index, success);
+ case JsonTokenNumber:
+ return Json::parseNumber(json, index);
+ case JsonTokenCurlyOpen:
+ return Json::parseObject(json, index, success);
+ case JsonTokenSquaredOpen:
+ return Json::parseArray(json, index, success);
+ case JsonTokenTrue:
+ Json::nextToken(json, index);
+ return QVariant(true);
+ case JsonTokenFalse:
+ Json::nextToken(json, index);
+ return QVariant(false);
+ case JsonTokenNull:
+ Json::nextToken(json, index);
+ return QVariant();
+ case JsonTokenNone:
+ break;
+ }
+
+ //If there were no tokens, flag the failure and return an empty QVariant
+ success = false;
+ return QVariant();
+}
+
+/**
+ * parseObject
+ */
+QVariant Json::parseObject(const QString &json, int &index, bool &success)
+{
+ QVariantMap map;
+ int token;
+
+ //Get rid of the whitespace and increment index
+ Json::nextToken(json, index);
+
+ //Loop through all of the key/value pairs of the object
+ bool done = false;
+ while(!done)
+ {
+ //Get the upcoming token
+ token = Json::lookAhead(json, index);
+
+ if(token == JsonTokenNone)
+ {
+ success = false;
+ return QVariantMap();
+ }
+ else if(token == JsonTokenComma)
+ {
+ Json::nextToken(json, index);
+ }
+ else if(token == JsonTokenCurlyClose)
+ {
+ Json::nextToken(json, index);
+ return map;
+ }
+ else
+ {
+ //Parse the key/value pair's name
+ QString name = Json::parseString(json, index, success).toString();
+
+ if(!success)
+ {
+ return QVariantMap();
+ }
+
+ //Get the next token
+ token = Json::nextToken(json, index);
+
+ //If the next token is not a colon, flag the failure
+ //return an empty QVariant
+ if(token != JsonTokenColon)
+ {
+ success = false;
+ return QVariant(QVariantMap());
+ }
+
+ //Parse the key/value pair's value
+ QVariant value = Json::parseValue(json, index, success);
+
+ if(!success)
+ {
+ return QVariantMap();
+ }
+
+ //Assign the value to the key in the map
+ map[name] = value;
+ }
+ }
+
+ //Return the map successfully
+ return QVariant(map);
+}
+
+/**
+ * parseArray
+ */
+QVariant Json::parseArray(const QString &json, int &index, bool &success)
+{
+ QVariantList list;
+
+ Json::nextToken(json, index);
+
+ bool done = false;
+ while(!done)
+ {
+ int token = Json::lookAhead(json, index);
+
+ if(token == JsonTokenNone)
+ {
+ success = false;
+ return QVariantList();
+ }
+ else if(token == JsonTokenComma)
+ {
+ Json::nextToken(json, index);
+ }
+ else if(token == JsonTokenSquaredClose)
+ {
+ Json::nextToken(json, index);
+ break;
+ }
+ else
+ {
+ QVariant value = Json::parseValue(json, index, success);
+
+ if(!success)
+ {
+ return QVariantList();
+ }
+
+ list.push_back(value);
+ }
+ }
+
+ return QVariant(list);
+}
+
+/**
+ * parseString
+ */
+QVariant Json::parseString(const QString &json, int &index, bool &success)
+{
+ QString s;
+ QChar c;
+
+ Json::eatWhitespace(json, index);
+
+ c = json[index++];
+
+ bool complete = false;
+ while(!complete)
+ {
+ if(index == json.size())
+ {
+ break;
+ }
+
+ c = json[index++];
+
+ if(c == '\"')
+ {
+ complete = true;
+ break;
+ }
+ else if(c == '\\')
+ {
+ if(index == json.size())
+ {
+ break;
+ }
+
+ c = json[index++];
+
+ if(c == '\"')
+ {
+ s.append('\"');
+ }
+ else if(c == '\\')
+ {
+ s.append('\\');
+ }
+ else if(c == '/')
+ {
+ s.append('/');
+ }
+ else if(c == 'b')
+ {
+ s.append('\b');
+ }
+ else if(c == 'f')
+ {
+ s.append('\f');
+ }
+ else if(c == 'n')
+ {
+ s.append('\n');
+ }
+ else if(c == 'r')
+ {
+ s.append('\r');
+ }
+ else if(c == 't')
+ {
+ s.append('\t');
+ }
+ else if(c == 'u')
+ {
+ int remainingLength = json.size() - index;
+
+ if(remainingLength >= 4)
+ {
+ QString unicodeStr = json.mid(index, 4);
+
+ int symbol = unicodeStr.toInt(0, 16);
+
+ s.append(QChar(symbol));
+
+ index += 4;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ s.append(c);
+ }
+ }
+
+ if(!complete)
+ {
+ success = false;
+ return QVariant();
+ }
+
+ return QVariant(s);
+}
+
+/**
+ * parseNumber
+ */
+QVariant Json::parseNumber(const QString &json, int &index)
+{
+ Json::eatWhitespace(json, index);
+
+ int lastIndex = Json::lastIndexOfNumber(json, index);
+ int charLength = (lastIndex - index) + 1;
+ QString numberStr;
+
+ numberStr = json.mid(index, charLength);
+
+ index = lastIndex + 1;
+
+ return QVariant(numberStr);
+}
+
+/**
+ * lastIndexOfNumber
+ */
+int Json::lastIndexOfNumber(const QString &json, int index)
+{
+ int lastIndex;
+
+ for(lastIndex = index; lastIndex < json.size(); lastIndex++)
+ {
+ if(QString("0123456789+-.eE").indexOf(json[lastIndex]) == -1)
+ {
+ break;
+ }
+ }
+
+ return lastIndex -1;
+}
+
+/**
+ * eatWhitespace
+ */
+void Json::eatWhitespace(const QString &json, int &index)
+{
+ for(; index < json.size(); index++)
+ {
+ if(QString(" \t\n\r").indexOf(json[index]) == -1)
+ {
+ break;
+ }
+ }
+}
+
+/**
+ * lookAhead
+ */
+int Json::lookAhead(const QString &json, int index)
+{
+ int saveIndex = index;
+ return Json::nextToken(json, saveIndex);
+}
+
+/**
+ * nextToken
+ */
+int Json::nextToken(const QString &json, int &index)
+{
+ Json::eatWhitespace(json, index);
+
+ if(index == json.size())
+ {
+ return JsonTokenNone;
+ }
+
+ QChar c = json[index];
+ index++;
+ switch(c.toAscii())
+ {
+ case '{': return JsonTokenCurlyOpen;
+ case '}': return JsonTokenCurlyClose;
+ case '[': return JsonTokenSquaredOpen;
+ case ']': return JsonTokenSquaredClose;
+ case ',': return JsonTokenComma;
+ case '"': return JsonTokenString;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case '-': return JsonTokenNumber;
+ case ':': return JsonTokenColon;
+ }
+
+ index--;
+
+ int remainingLength = json.size() - index;
+
+ //True
+ if(remainingLength >= 4)
+ {
+ if (json[index] == 't' && json[index + 1] == 'r' &&
+ json[index + 2] == 'u' && json[index + 3] == 'e')
+ {
+ index += 4;
+ return JsonTokenTrue;
+ }
+ }
+
+ //False
+ if (remainingLength >= 5)
+ {
+ if (json[index] == 'f' && json[index + 1] == 'a' &&
+ json[index + 2] == 'l' && json[index + 3] == 's' &&
+ json[index + 4] == 'e')
+ {
+ index += 5;
+ return JsonTokenFalse;
+ }
+ }
+
+ //Null
+ if (remainingLength >= 4)
+ {
+ if (json[index] == 'n' && json[index + 1] == 'u' &&
+ json[index + 2] == 'l' && json[index + 3] == 'l')
+ {
+ index += 4;
+ return JsonTokenNull;
+ }
+ }
+
+ return JsonTokenNone;
+}
=======================================
--- /dev/null
+++ /qtcore/src/json.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,157 @@
+/**
+ * \file json.h
+ *
+ * \author Eeli Reilin <ee...@nilier.org>,
+ * Mikko Ahonen <mikko.j...@jyu.fi>
+ * \version 0.1
+ * \date 8/25/2010
+ */
+
+#ifndef JSON_H
+#define JSON_H
+
+#include <QVariant>
+#include <QString>
+
+/**
+ * \enum JsonToken
+ */
+enum JsonToken
+{
+ JsonTokenNone = 0,
+ JsonTokenCurlyOpen = 1,
+ JsonTokenCurlyClose = 2,
+ JsonTokenSquaredOpen = 3,
+ JsonTokenSquaredClose = 4,
+ JsonTokenColon = 5,
+ JsonTokenComma = 6,
+ JsonTokenString = 7,
+ JsonTokenNumber = 8,
+ JsonTokenTrue = 9,
+ JsonTokenFalse = 10,
+ JsonTokenNull = 11
+};
+
+/**
+ * \class Json
+ * \brief A JSON data parser
+ *
+ * Json parses a JSON data into a QVariant hierarchy.
+ */
+class Json
+{
+ public:
+ /**
+ * Parse a JSON string
+ *
+ * \param json The JSON data
+ */
+ static QVariant parse(const QString &json);
+
+ /**
+ * Parse a JSON string
+ *
+ * \param json The JSON data
+ * \param success The success of the parsing
+ */
+ static QVariant parse(const QString &json, bool &success);
+
+ private:
+ /**
+ * Parses a value starting from index
+ *
+ * \param json The JSON data
+ * \param index The start index
+ * \param success The success of the parse process
+ *
+ * \return QVariant The parsed value
+ */
+ static QVariant parseValue(const QString &json, int &index,
+ bool &success);
+
+ /**
+ * Parses an object starting from index
+ *
+ * \param json The JSON data
+ * \param index The start index
+ * \param success The success of the object parse
+ *
+ * \return QVariant The parsed object map
+ */
+ static QVariant parseObject(const QString &json, int &index,
+ bool &success);
+
+ /**
+ * Parses an array starting from index
+ *
+ * \param json The JSON data
+ * \param index The starting index
+ * \param success The success of the array parse
+ *
+ * \return QVariant The parsed variant array
+ */
+ static QVariant parseArray(const QString &json, int &index,
+ bool &success);
+
+ /**
+ * Parses a string starting from index
+ *
+ * \param json The JSON data
+ * \param index The starting index
+ * \param success The success of the string parse
+ *
+ * \return QVariant The parsed string
+ */
+ static QVariant parseString(const QString &json, int &index,
+ bool &success);
+
+ /**
+ * Parses a number starting from index
+ *
+ * \param json The JSON data
+ * \param index The starting index
+ *
+ * \return QVariant The parsed number
+ */
+ static QVariant parseNumber(const QString &json, int &index);
+
+ /**
+ * Get the last index of a number starting from index
+ *
+ * \param json The JSON data
+ * \param index The starting index
+ *
+ * \return The last index of the number
+ */
+ static int lastIndexOfNumber(const QString &json, int index);
+
+ /**
+ * Skip unwanted whitespace symbols starting from index
+ *
+ * \param json The JSON data
+ * \param index The start index
+ */
+ static void eatWhitespace(const QString &json, int &index);
+
+ /**
+ * Check what token lies ahead
+ *
+ * \param json The JSON data
+ * \param index The starting index
+ *
+ * \return int The upcoming token
+ */
+ static int lookAhead(const QString &json, int index);
+
+ /**
+ * Get the next JSON token
+ *
+ * \param json The JSON data
+ * \param index The starting index
+ *
+ * \return int The next JSON token
+ */
+ static int nextToken(const QString &json, int &index);
+};
+
+#endif //JSON_H
=======================================
--- /dev/null
+++ /qtcore/src/menu.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,136 @@
+#include <QDebug>
+#include <QObject>
+#include <QString>
+#include <QMenu>
+#include <QUrl>
+#include <QKeySequence>
+#include <assert.h>
+#include "menu.h"
+
+static MenuApp* g_manager = 0;
+
+MenuApp::MenuApp(const QString& appname, QObject* parent)
+ : App(appname, parent)
+{
+}
+
+QByteArray MenuApp::processCall(const QString& command, const QVariantMap&
param)
+{
+ if (command == "Menu.create") {
+ return createMenu();
+ } else if (command.startsWith("Menu.")) {
+ QString id = param.value("id").toString();
+ QMenu* menu = static_cast<QMenu *>(getInstance(id));
+ if (!menu) {
+ return "{\"err\":\"invalid id\"}";
+ }
+ if (command == "Menu.destroy") {
+ return destroyMenu(menu);
+ } else if (command == "Menu.addSeparator") {
+ return addSeparator(menu);
+ } else if (command == "Menu.addMenuItem") {
+ return addMenuItem(menu, param.value("text").toString());
+ } else if (command == "Menu.getMenuItem") {
+ return getMenuItem(menu, param.value("index").toInt());
+ }
+ } else if (command.startsWith("MenuItem.")) {
+ QString id = param.value("id").toString();
+ QAction* item = static_cast<QAction *>(getInstance(id));
+ if (!item) {
+ return "{\"err\":\"invalid id\"}";
+ }
+ if (command == "MenuItem.setProperties") {
+ return setMenuItemProperties(item, param);
+ } else if (command == "MenuItem.setText") {
+ return setMenuItemText(item, param.value("text").toString());
+ }
+ }
+
+ return "{\"err\":\"invalid command\"}";
+}
+
+QByteArray MenuApp::createMenu()
+{
+ QMenu* menu = new QMenu();
+ return
QString("{\"type\":\"Menu\",\"id\":\"%1\"}").arg(getId(menu)).toLatin1();
+}
+
+QByteArray MenuApp::destroyMenu(QMenu* menu)
+{
+ delete menu;
+ return "null";
+}
+
+QByteArray MenuApp::addSeparator(QMenu* menu)
+{
+ menu->addSeparator();
+ return "null";
+}
+
+QByteArray MenuApp::addMenuItem(QMenu* menu, const QString& text)
+{
+ QAction* action = menu->addAction(text);
+ connect(action, SIGNAL(triggered(bool)),
+ this, SLOT(menuItemTriggered(bool)));
+ return
QString("{\"type\":\"MenuItem\",\"id\":\"%1\"}").arg(getId(action)).toLatin1();
+}
+
+QByteArray MenuApp::getMenuItem(QMenu* menu, int index)
+{
+ QList<QAction *> actions = menu->actions();
+ if (index < 0 || index >= actions.size()) {
+ return "null";
+ }
+ QAction* action = actions[index];
+ return
QString("{\"type\":\"MenuItem\",\"id\":\"%1\"}").arg(getId(action)).toLatin1();
+}
+
+QByteArray MenuApp::setMenuItemProperties(QAction* item, const
QVariantMap& props)
+{
+ if (props.contains("shortcut")) {
+ QString shortcut = props.value("shortcut").toString();
+ item->setShortcut(QKeySequence(shortcut));
+ item->setShortcutContext(Qt::ApplicationShortcut);
+ }
+ if (props.contains("enabled")) {
+ item->setEnabled(props.value("enabled").toBool());
+ }
+ if (props.contains("disabled")) {
+ item->setEnabled(!(props.value("disabled").toBool()));
+ }
+ return "null";
+}
+
+QByteArray MenuApp::setMenuItemText(QAction* item, const QString& text)
+{
+ item->setText(text);
+ return "null";
+}
+
+void MenuApp::menuItemTriggered(bool checked)
+{
+ publishEvent("MenuItem", sender(), "triggered",
+ QString("{\"checked\":%1}").arg(checked ? "true" : "false"));
+}
+
+static onering_response_handle_t menu_app(const char* appname, const char*
method,
+ const char* path, const char* body,
+ const char** response, int* response_len)
+{
+ if (!g_manager) {
+ g_manager = new MenuApp(appname);
+ }
+
+ return g_manager->processRequest(appname, method, path, body, response,
response_len);
+}
+
+
+static void menu_app_free_response(const char* appname,
onering_response_handle_t response_handle)
+{
+ g_manager->freeResponse(appname, response_handle);
+}
+
+void register_menu_app(const char* appname)
+{
+ onering_register_app(appname, &menu_app, &menu_app_free_response);
+}
=======================================
--- /dev/null
+++ /qtcore/src/menu.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,36 @@
+#ifndef MENU_H
+#define MENU_H
+
+#include <onering.h>
+#include <QSet>
+#include <QMenu>
+#include <QVariantMap>
+#include "app.h"
+
+class MenuApp : public App
+{
+Q_OBJECT
+
+public:
+ MenuApp(const QString& appname, QObject* parent=0);
+
+private:
+ QByteArray createMenu();
+ QByteArray destroyMenu(QMenu* menu);
+ QByteArray addSeparator(QMenu* menu);
+ QByteArray addMenuItem(QMenu* menu, const QString& text);
+ QByteArray getMenuItem(QMenu* menu, int index);
+
+ QByteArray setMenuItemProperties(QAction* action, const QVariantMap&
props);
+ QByteArray setMenuItemText(QAction* action, const QString& text);
+
+private slots:
+ void menuItemTriggered(bool checked=false);
+
+private:
+ QByteArray processCall(const QString& command, const QVariantMap& param);
+};
+
+void register_menu_app(const char* appname);
+
+#endif
=======================================
--- /dev/null
+++ /qtcore/src/networkaccessmanager.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,41 @@
+#include <QDebug>
+#include <QtNetwork>
+#include <QIODevice>
+#include <onering.h>
+#include "networkaccessmanager.h"
+#include "appreply.h"
+#include "app.h"
+#include "debugger.h"
+
+NetworkAccessManager::NetworkAccessManager(QObject *parent,
QNetworkAccessManager *manager)
+ : QNetworkAccessManager(parent)
+{
+ if (manager) {
+ setCache(manager->cache());
+ setCookieJar(manager->cookieJar());
+ setProxy(manager->proxy());
+ setProxyFactory(manager->proxyFactory());
+ }
+
+ methods[QNetworkAccessManager::HeadOperation] = "HEAD";
+ methods[QNetworkAccessManager::GetOperation] = "GET";
+ methods[QNetworkAccessManager::PutOperation] = "PUT";
+ methods[QNetworkAccessManager::PostOperation] = "POST";
+ methods[QNetworkAccessManager::DeleteOperation] = "DELETE";
+}
+
+QNetworkReply *NetworkAccessManager::createRequest(
+ QNetworkAccessManager::Operation operation,
+ const QNetworkRequest &request,
+ QIODevice *device)
+{
+ const QUrl& url = request.url();
+ if (is_appname_registered(url.host())) {
+// qDebug() << "delegate to app" << url.toString();
+ AppReply *reply = new AppReply(methods[operation], url, device, this);
+ Debugger::traceObj(reply);
+ return reply;
+ }
+
+ return QNetworkAccessManager::createRequest(operation, request, device);
+}
=======================================
--- /dev/null
+++ /qtcore/src/networkaccessmanager.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,20 @@
+#ifndef NETWORKACCESSMANAGER_H
+#define NETWORKACCESSMANAGER_H
+
+#include <QNetworkAccessManager>
+
+class NetworkAccessManager : public QNetworkAccessManager
+{
+ Q_OBJECT
+
+public:
+ NetworkAccessManager(QObject *parent = 0, QNetworkAccessManager
*oldManager=0);
+
+protected:
+ QNetworkReply *createRequest(Operation operation, const QNetworkRequest
&request, QIODevice *device);
+
+private:
+ const char* methods[10];
+};
+
+#endif
=======================================
--- /dev/null
+++ /qtcore/src/onering.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,45 @@
+#include <QDesktopServices>
+#include <QDir>
+#include <QDebug>
+#include <QApplication>
+#include <QCoreApplication>
+#include <QWebSettings>
+#include <QWebSecurityOrigin>
+#include <string.h>
+#include <onering.h>
+#include "oneringview.h"
+#include "app.h"
+#include "oneringapp.h"
+#include "dataloader.h"
+#include "application.h"
+#include "publishevent.h"
+#include "cocoainit.h"
+
+int onering_loop(const char* appname)
+{
+ int argc = 1;
+ char name[ONERING_MAX_APPNAME_LEN+1];
+ char *argv[] = {name};
+
+ strncpy(name, appname, ONERING_MAX_APPNAME_LEN);
+ name[ONERING_MAX_APPNAME_LEN] = '\0';
+
+#ifdef Q_WS_MAC
+#ifdef QT_MAC_USE_COCOA
+ CocoaInitializer cocoaInitializer;
+#endif
+#endif
+ Application app(argc, argv);
+ int retval = app.load(appname);
+ if (retval)
+ return retval;
+ return app.exec();
+}
+
+void onering_publish(const char* channel, const char* msg)
+{
+ Application *app = static_cast<Application *>(qApp);
+ if (app && !app->quiting) {
+ app->pubsubhub.publish(channel, msg);
+ }
+}
=======================================
--- /dev/null
+++ /qtcore/src/oneringapp.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,143 @@
+#include <QApplication>
+#include <QDebug>
+#include <QFile>
+#include <onering.h>
+#include "application.h"
+#include "oneringapp.h"
+#include "oneringview.h"
+#include "debugger.h"
+
+static OneRingApp* g_app = 0;
+
+OneRingApp::OneRingApp(const QString& appname, QObject *parent)
+ : App(appname, parent)
+{
+ QFile file(":/js/onering.js");
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ return;
+ }
+ _js = file.readAll();
+ file.close();
+ _js.prepend("HTTP/1.1 200 OK\r\nContent-Type:
application/javascript\r\n\r\n");
+
+#ifdef Q_WS_MAC
+#ifdef QT_MAC_USE_COCOA
+ connect(static_cast<Application *>(qApp), SIGNAL(dockIconClicked()),
+ this, SLOT(dockIconClicked()));
+#endif
+#endif
+}
+
+QByteArray OneRingApp::processCall(const QString& command, const
QVariantMap& param)
+{
+ if (command == "onering.js") {
+ return _js;
+ } else if (command == "Window.create") {
+ OneRingView* window = createWindow(param);
+ _windows.insert(window);
+ connect(window, SIGNAL(destroyed(QObject *)),
+ this, SLOT(windowDestroyed(QObject *)));
+ window->show();
+ return QString("{\"type\":\"Window\",\"id\":\"%1\"}")
+ .arg(getId(window)).toLatin1();
+ } else if (command.startsWith("Window.")) {
+ QString id = param.value("id").toString();
+ OneRingView* window = static_cast<OneRingView *>(getInstance(id));
+
+ if (command == "Window.isAlive") {
+ return _windows.contains(window) ? "true" : "false";
+ } else if (!window) {
+ return "{\"err\":\"invalid id\"}";
+ } else if (command == "Window.showInspector") {
+ window->showInspector();
+ return "null";
+ } else if (command == "Window.hide") {
+ window->hide();
+ return "null";
+ } else if (command == "Window.show") {
+ window->show();
+ return "null";
+ } else if (command == "Window.maximize") {
+ window->showMaximized();
+ return "null";
+ } else if (command == "Window.showNormal") {
+ window->showNormal();
+ return "null";
+ } else if (command == "Window.isMinimized") {
+ return window->isMinimized() ? "true" : "false";
+ } else if (command == "Window.activateWindow") {
+ window->activateWindow();
+ return "null";
+ }
+ } else if (command.startsWith("Application.")) {
+ if (command == "Application.setQuitOnLastWindowClosed") {
+ qApp->setQuitOnLastWindowClosed(param["quit"].toBool());
+ return "null";
+ } else if (command == "Application.exit") {
+ qApp->quit();
+ return "null";
+ }
+ } else if (command == "Event.preventDefault") {
+ QString id = param.value("id").toString();
+ QEvent* event = static_cast<QEvent *>(getInstance(id));
+ if (!event) {
+ return "{\"err\":\"invalid id\"}";
+ }
+ event->ignore();
+ return "null";
+ }
+
+ return "{\"err\":\"invalid command\"}";
+}
+
+OneRingView* OneRingApp::createWindow(const QVariantMap& props)
+{
+ if (!g_app) {
+ g_app = new OneRingApp("onering");
+ }
+
+ OneRingView* window = new OneRingView(props);
+ connect(window, SIGNAL(eventOccurred(QEvent*, const QString&)),
+ g_app, SLOT(windowEventOccurred(QEvent*, const QString&)));
+ return window;
+}
+
+void OneRingApp::windowEventOccurred(QEvent* e, const QString& type)
+{
+ publishEvent("Window", sender(), type, e);
+}
+
+void OneRingApp::windowDestroyed(QObject *obj)
+{
+ _windows.remove(static_cast<OneRingView *>(obj));
+}
+
+#ifdef Q_WS_MAC
+#ifdef QT_MAC_USE_COCOA
+void OneRingApp::dockIconClicked()
+{
+ publishEvent("Application", 0, "dockIconClicked");
+}
+#endif
+#endif
+
+static onering_response_handle_t app(const char *appname, const char*
method, const char* path, const char* body, const char **response, int
*response_len)
+{
+ if (!g_app) {
+ g_app = new OneRingApp(appname);
+ }
+
+ return g_app->processRequest(appname, method, path, body, response,
response_len);
+}
+
+static void free_response(const char *appname, onering_response_handle_t
response_handle)
+{
+ g_app->freeResponse(appname, response_handle);
+}
+
+void register_onering_app(const char* appname)
+{
+ onering_register_app(appname, &app, &free_response);
+}
+
+
=======================================
--- /dev/null
+++ /qtcore/src/oneringapp.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,38 @@
+#ifndef ONERINGAPP_H
+#define ONERINGAPP_H
+
+#include <onering.h>
+#include <QVariantMap>
+#include <QSet>
+#include <QByteArray>
+#include <QEvent>
+#include "oneringview.h"
+#include "app.h"
+
+class OneRingApp : public App
+{
+ Q_OBJECT
+
+public:
+ OneRingApp(const QString& appname, QObject* parent=0);
+
+ static OneRingView* createWindow(const QVariantMap& props);
+
+private slots:
+ void windowEventOccurred(QEvent* e, const QString& type);
+ void windowDestroyed(QObject *);
+#ifdef Q_WS_MAC
+#ifdef QT_MAC_USE_COCOA
+ void dockIconClicked();
+#endif
+#endif
+
+private:
+ QByteArray processCall(const QString& command, const QVariantMap&
param);
+ QByteArray _js;
+ QSet<OneRingView *> _windows;
+};
+
+void register_onering_app(const char* appname);
+
+#endif
=======================================
--- /dev/null
+++ /qtcore/src/oneringview.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,123 @@
+#include <QDebug>
+#include <QPair>
+#include <QEvent>
+#include <QCloseEvent>
+#include "oneringview.h"
+#include "networkaccessmanager.h"
+#include "jsapi.h"
+#include "debugger.h"
+
+OneRingView::OneRingView(const QVariantMap &props)
+ : QWebView(),
+#ifdef CONTEXTMENU
+ contextMenuEnabled(true),
+#else
+ contextMenuEnabled(false),
+#endif
+ inspector(0)
+{
+ QNetworkAccessManager *oldManager = page()->networkAccessManager();
+ NetworkAccessManager *newManager = new NetworkAccessManager(this,
oldManager);
+ Debugger::traceObj(newManager);
+ page()->setNetworkAccessManager(newManager);
+
+#ifdef DEBUG
+ connect(this, SIGNAL(urlChanged(const QUrl &)),
+ this, SLOT(printCurrentUrl(const QUrl &)));
+#endif
+
+ connect(this, SIGNAL(titleChanged(const QString &)),
+ this, SLOT(setWindowTitle(const QString &)));
+
+ jsapi = new JsApi(this);
+ Debugger::traceObj(jsapi);
+ jsapi->setWebView(this);
+ jsapi->setWindow(this);
+
+ setAttribute(Qt::WA_DeleteOnClose, true);
+
+ setProperties(props);
+}
+
+OneRingView::~OneRingView()
+{
+ if (inspector) {
+ delete inspector;
+ }
+}
+
+void OneRingView::printCurrentUrl(const QUrl &url)
+{
+ qDebug() << "nav to:" << url.toString();
+}
+
+void OneRingView::contextMenuEvent(QContextMenuEvent *ev)
+{
+ if (contextMenuEnabled) {
+ QWebView::contextMenuEvent(ev);
+ }
+}
+
+void OneRingView::changeEvent(QEvent * event)
+{
+ switch (event->type()) {
+ case QEvent::WindowStateChange:
+ emit eventOccurred(event, "windowStateChange");
+ break;
+ default:
+ ;
+ }
+ QWebView::changeEvent(event);
+}
+
+void OneRingView::closeEvent(QCloseEvent *event)
+{
+ emit eventOccurred(event, "close");
+}
+
+void OneRingView::activateWindow()
+{
+ QWebView::activateWindow();
+}
+
+void OneRingView::setProperties(const QVariantMap& props)
+{
+ load(props["url"].toString());
+ resize(props["width"].toInt(), props["height"].toInt());
+
+ if (props["fixedSize"].toBool()) {
+ setFixedSize(width(), height());
+ }
+ if (!props["title"].toString().isEmpty()) {
+ setWindowTitle(props["title"].toString());
+ }
+
+ if (props.contains("minimizeButton")
+ || props.contains("maximizeButton")) {
+ Qt::WindowFlags flags = Qt::Widget;
+ flags |= Qt::CustomizeWindowHint
+ | Qt::WindowTitleHint
+ | Qt::WindowSystemMenuHint
+ | Qt::WindowMinimizeButtonHint
+ | Qt::WindowMaximizeButtonHint
+ | Qt::WindowCloseButtonHint;
+ if (!(props.value("minimizeButton", QVariant(true)).toBool()))
+ flags ^= Qt::WindowMinimizeButtonHint;
+ if (!(props.value("maximizeButton", QVariant(true)).toBool()))
+ flags ^= Qt::WindowMaximizeButtonHint;
+ setWindowFlags(flags);
+ }
+}
+
+void OneRingView::showInspector()
+{
+ if (!inspector) {
+ inspector = new QWebInspector();
+ }
+ if (!inspector->page()) {
+ inspector->setPage(page());
+ }
+ inspector->resize(800, 600);
+ inspector->show();
+ inspector->activateWindow(); // put inspector at the top most
+}
=======================================
--- /dev/null
+++ /qtcore/src/oneringview.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,44 @@
+#ifndef ONERINGVIEW_H
+#define ONERINGVIEW_H
+
+#include <QWebView>
+#include <QHash>
+#include <QEvent>
+#include <QList>
+#include <QPair>
+#include <QWebInspector>
+#include "jsapi.h"
+
+class OneRingView : public QWebView
+{
+ Q_OBJECT
+
+public:
+ OneRingView(const QVariantMap &props);
+ ~OneRingView();
+
+ void setProperties(const QVariantMap &props);
+ void showInspector(void);
+
+signals:
+ void eventOccurred(QEvent *event, const QString& type);
+
+public slots:
+ void activateWindow(void);
+
+private slots:
+ void printCurrentUrl(const QUrl &url);
+
+protected:
+ void contextMenuEvent(QContextMenuEvent *ev);
+ void changeEvent(QEvent* event);
+ void closeEvent(QCloseEvent* event);
+ void initializEventMap(void);
+
+private:
+ bool contextMenuEnabled;
+ JsApi *jsapi;
+ QWebInspector *inspector;
+};
+
+#endif
=======================================
--- /dev/null
+++ /qtcore/src/publishevent.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,26 @@
+#include <QDebug>
+#include "publishevent.h"
+
+int PublishEvent::_type = QEvent::registerEventType();
+
+PublishEvent::PublishEvent(const char *channel, const char *msg)
+ : QEvent(static_cast<QEvent::Type>(_type)),
+ _channel(channel),
+ _msg(msg)
+{
+}
+
+const QString& PublishEvent::channel()
+{
+ return _channel;
+}
+
+const QString& PublishEvent::message()
+{
+ return _msg;
+}
+
+int PublishEvent::type()
+{
+ return _type;
+}
=======================================
--- /dev/null
+++ /qtcore/src/publishevent.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,22 @@
+#ifndef PUBLISHEVENT_H
+#define PUBLISHEVENT_H
+
+#include <QEvent>
+#include <QString>
+
+class PublishEvent : public QEvent
+{
+public:
+ PublishEvent(const char *channel, const char *msg);
+
+ const QString& channel(void);
+ const QString& message(void);
+ static int type(void);
+
+private:
+ QString _channel;
+ QString _msg;
+ static int _type;
+};
+
+#endif
=======================================
--- /dev/null
+++ /qtcore/src/pubsubhub.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,9 @@
+#include <QDebug>
+#include "publishevent.h"
+#include "pubsubhub.h"
+
+void PubSubHub::publish(const QString& channel, const QString& message)
+{
+ qDebug() << "publish" << channel << message;
+ emit published(channel, message);
+}
=======================================
--- /dev/null
+++ /qtcore/src/pubsubhub.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,17 @@
+#ifndef PUBSUBHUB_H
+#define PUBSUBHUB_H
+
+#include <QObject>
+
+class PubSubHub : public QObject
+{
+Q_OBJECT
+
+public:
+ void publish(const QString &channel, const QString &message);
+
+signals:
+ void published(const QString &channel, const QString &message);
+};
+
+#endif
=======================================
--- /dev/null
+++ /qtcore/src/qxtglobal.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,207 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtCore module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
+ **
+ ** <http://libqxt.org> <found...@libqxt.org>
+ **
+
****************************************************************************/
+
+#ifndef QXTGLOBAL_H
+#define QXTGLOBAL_H
+
+#include <QtGlobal>
+
+#define QXT_VERSION 0x000700
+#define QXT_VERSION_STR "0.7.0"
+
+//--------------------------global macros------------------------------
+
+#ifndef QXT_NO_MACROS
+
+#endif // QXT_NO_MACROS
+
+//--------------------------export macros------------------------------
+
+#define QXT_DLLEXPORT DO_NOT_USE_THIS_ANYMORE
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_CORE)
+# define QXT_CORE_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_CORE_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_CORE_EXPORT
+#endif // BUILD_QXT_CORE
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_GUI)
+# define QXT_GUI_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_GUI_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_GUI_EXPORT
+#endif // BUILD_QXT_GUI
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_NETWORK)
+# define QXT_NETWORK_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_NETWORK_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_NETWORK_EXPORT
+#endif // BUILD_QXT_NETWORK
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_SQL)
+# define QXT_SQL_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_SQL_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_SQL_EXPORT
+#endif // BUILD_QXT_SQL
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_WEB)
+# define QXT_WEB_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_WEB_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_WEB_EXPORT
+#endif // BUILD_QXT_WEB
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_BERKELEY)
+# define QXT_BERKELEY_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_BERKELEY_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_BERKELEY_EXPORT
+#endif // BUILD_QXT_BERKELEY
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_ZEROCONF)
+# define QXT_ZEROCONF_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_ZEROCONF_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_ZEROCONF_EXPORT
+#endif // QXT_ZEROCONF_EXPORT
+
+#if defined BUILD_QXT_CORE || defined BUILD_QXT_GUI || defined
BUILD_QXT_SQL || defined BUILD_QXT_NETWORK || defined BUILD_QXT_WEB ||
defined BUILD_QXT_BERKELEY || defined BUILD_QXT_ZEROCONF
+# define BUILD_QXT
+#endif
+
+QXT_CORE_EXPORT const char* qxtVersion();
+
+#ifndef QT_BEGIN_NAMESPACE
+#define QT_BEGIN_NAMESPACE
+#endif
+
+#ifndef QT_END_NAMESPACE
+#define QT_END_NAMESPACE
+#endif
+
+#ifndef QT_FORWARD_DECLARE_CLASS
+#define QT_FORWARD_DECLARE_CLASS(Class) class Class;
+#endif
+
+/****************************************************************************
+** This file is derived from code bearing the following notice:
+** The sole author of this file, Adam Higerd, has explicitly disclaimed all
+** copyright interest and protection for the content within. This file has
+** been placed in the public domain according to United States copyright
+** statute and case law. In jurisdictions where this public domain
dedication
+** is not legally recognized, anyone who receives a copy of this file is
+** permitted to use, modify, duplicate, and redistribute this file, in
whole
+** or in part, with no restrictions or conditions. In these jurisdictions,
+** this file shall be copyright (C) 2006-2008 by Adam Higerd.
+****************************************************************************/
+
+#define QXT_DECLARE_PRIVATE(PUB) friend class PUB##Private;
QxtPrivateInterface<PUB, PUB##Private> qxt_d;
+#define QXT_DECLARE_PUBLIC(PUB) friend class PUB;
+#define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this);
+#define QXT_D(PUB) PUB##Private& d = qxt_d()
+#define QXT_P(PUB) PUB& p = qxt_p()
+
+template <typename PUB>
+class QxtPrivate
+{
+public:
+ virtual ~QxtPrivate()
+ {}
+ inline void QXT_setPublic(PUB* pub)
+ {
+ qxt_p_ptr = pub;
+ }
+
+protected:
+ inline PUB& qxt_p()
+ {
+ return *qxt_p_ptr;
+ }
+ inline const PUB& qxt_p() const
+ {
+ return *qxt_p_ptr;
+ }
+
+private:
+ PUB* qxt_p_ptr;
+};
+
+template <typename PUB, typename PVT>
+class QxtPrivateInterface
+{
+ friend class QxtPrivate<PUB>;
+public:
+ QxtPrivateInterface()
+ {
+ pvt = new PVT;
+ }
+ ~QxtPrivateInterface()
+ {
+ delete pvt;
+ }
+
+ inline void setPublic(PUB* pub)
+ {
+ pvt->QXT_setPublic(pub);
+ }
+ inline PVT& operator()()
+ {
+ return *static_cast<PVT*>(pvt);
+ }
+ inline const PVT& operator()() const
+ {
+ return *static_cast<PVT*>(pvt);
+ }
+private:
+ QxtPrivateInterface(const QxtPrivateInterface&) { }
+ QxtPrivateInterface& operator=(const QxtPrivateInterface&) { }
+ QxtPrivate<PUB>* pvt;
+};
+
+#endif // QXT_GLOBAL
=======================================
--- /dev/null
+++ /qtcore/src/qxtglobalshortcut.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,197 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
+ **
+ ** <http://libqxt.org> <found...@libqxt.org>
+ **
+
****************************************************************************/
+#include "qxtglobalshortcut.h"
+#include "qxtglobalshortcut_p.h"
+#include <QAbstractEventDispatcher>
+#include <QtDebug>
+
+bool QxtGlobalShortcutPrivate::error = false;
+#ifndef Q_WS_MAC
+int QxtGlobalShortcutPrivate::ref = 0;
+QAbstractEventDispatcher::EventFilter
QxtGlobalShortcutPrivate::prevEventFilter = 0;
+#endif // Q_WS_MAC
+QHash<QPair<quint32, quint32>, QxtGlobalShortcut*>
QxtGlobalShortcutPrivate::shortcuts;
+
+QxtGlobalShortcutPrivate::QxtGlobalShortcutPrivate() : enabled(true),
key(Qt::Key(0)), mods(Qt::NoModifier)
+{
+#ifndef Q_WS_MAC
+ if (!ref++)
+ prevEventFilter =
QAbstractEventDispatcher::instance()->setEventFilter(eventFilter);
+#endif // Q_WS_MAC
+}
+
+QxtGlobalShortcutPrivate::~QxtGlobalShortcutPrivate()
+{
+#ifndef Q_WS_MAC
+ if (!--ref)
+
QAbstractEventDispatcher::instance()->setEventFilter(prevEventFilter);
+#endif // Q_WS_MAC
+}
+
+bool QxtGlobalShortcutPrivate::setShortcut(const QKeySequence& shortcut)
+{
+ Qt::KeyboardModifiers allMods = Qt::ShiftModifier |
Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier |
Qt::KeypadModifier | Qt::GroupSwitchModifier;
+ key = shortcut.isEmpty() ? Qt::Key(0) : Qt::Key((shortcut[0] ^
allMods) & shortcut[0]);
+ mods = shortcut.isEmpty() ? Qt::KeyboardModifiers(0) :
Qt::KeyboardModifiers(shortcut[0] & allMods);
+ const quint32 nativeKey = nativeKeycode(key, mods);
+ const quint32 nativeMods = nativeModifiers(mods);
+ const bool res = registerShortcut(nativeKey, nativeMods);
+ shortcuts.insert(qMakePair(nativeKey, nativeMods), &qxt_p());
+ if (!res)
+ qWarning() << "QxtGlobalShortcut failed to register:" <<
QKeySequence(key + mods).toString();
+ return res;
+}
+
+bool QxtGlobalShortcutPrivate::unsetShortcut()
+{
+ const quint32 nativeKey = nativeKeycode(key, mods);
+ const quint32 nativeMods = nativeModifiers(mods);
+ const bool res = unregisterShortcut(nativeKey, nativeMods);
+ shortcuts.remove(qMakePair(nativeKey, nativeMods));
+ if (!res)
+ qWarning() << "QxtGlobalShortcut failed to unregister:" <<
QKeySequence(key + mods).toString();
+ key = Qt::Key(0);
+ mods = Qt::KeyboardModifiers(0);
+ return res;
+}
+
+void QxtGlobalShortcutPrivate::activateShortcut(quint32 nativeKey, quint32
nativeMods)
+{
+ QxtGlobalShortcut* shortcut = shortcuts.value(qMakePair(nativeKey,
nativeMods));
+ if (shortcut && shortcut->isEnabled())
+ emit shortcut->activated();
+}
+
+/*!
+ \class QxtGlobalShortcut
+ \inmodule QxtGui
+ \brief The QxtGlobalShortcut class provides a global shortcut
aka "hotkey".
+
+ A global shortcut triggers even if the application is not active. This
+ makes it easy to implement applications that react to certain shortcuts
+ still if some other application is active or if the application is for
+ example minimized to the system tray.
+
+ Example usage:
+ \code
+ QxtGlobalShortcut* shortcut = new QxtGlobalShortcut(window);
+ connect(shortcut, SIGNAL(activated()), window,
SLOT(toggleVisibility()));
+ shortcut->setShortcut(QKeySequence("Ctrl+Shift+F12"));
+ \endcode
+
+ \bold {Note:} Since Qxt 0.6 QxtGlobalShortcut no more requires
QxtApplication.
+ */
+
+/*!
+ \fn QxtGlobalShortcut::activated()
+
+ This signal is emitted when the user types the shortcut's key sequence.
+
+ \sa shortcut
+ */
+
+/*!
+ Constructs a new QxtGlobalShortcut with \a parent.
+ */
+QxtGlobalShortcut::QxtGlobalShortcut(QObject* parent)
+ : QObject(parent)
+{
+ QXT_INIT_PRIVATE(QxtGlobalShortcut);
+}
+
+/*!
+ Constructs a new QxtGlobalShortcut with \a shortcut and \a parent.
+ */
+QxtGlobalShortcut::QxtGlobalShortcut(const QKeySequence& shortcut,
QObject* parent)
+ : QObject(parent)
+{
+ QXT_INIT_PRIVATE(QxtGlobalShortcut);
+ setShortcut(shortcut);
+}
+
+/*!
+ Destructs the QxtGlobalShortcut.
+ */
+QxtGlobalShortcut::~QxtGlobalShortcut()
+{
+ if (qxt_d().key != 0)
+ qxt_d().unsetShortcut();
+}
+
+/*!
+ \property QxtGlobalShortcut::shortcut
+ \brief the shortcut key sequence
+
+ \bold {Note:} Notice that corresponding key press and release events
are not
+ delivered for registered global shortcuts even if they are disabled.
+ Also, comma separated key sequences are not supported.
+ Only the first part is used:
+
+ \code
+ qxtShortcut->setShortcut(QKeySequence("Ctrl+Alt+A,Ctrl+Alt+B"));
+ Q_ASSERT(qxtShortcut->shortcut() == QKeySequence("Ctrl+Alt+A"));
+ \endcode
+ */
+QKeySequence QxtGlobalShortcut::shortcut() const
+{
+ return QKeySequence(qxt_d().key | qxt_d().mods);
+}
+
+bool QxtGlobalShortcut::setShortcut(const QKeySequence& shortcut)
+{
+ if (qxt_d().key != 0)
+ qxt_d().unsetShortcut();
+ return qxt_d().setShortcut(shortcut);
+}
+
+/*!
+ \property QxtGlobalShortcut::enabled
+ \brief whether the shortcut is enabled
+
+ A disabled shortcut does not get activated.
+
+ The default value is \c true.
+
+ \sa setDisabled()
+ */
+bool QxtGlobalShortcut::isEnabled() const
+{
+ return qxt_d().enabled;
+}
+
+void QxtGlobalShortcut::setEnabled(bool enabled)
+{
+ qxt_d().enabled = enabled;
+}
+
+/*!
+ Sets the shortcut \a disabled.
+
+ \sa enabled
+ */
+void QxtGlobalShortcut::setDisabled(bool disabled)
+{
+ qxt_d().enabled = !disabled;
+}
=======================================
--- /dev/null
+++ /qtcore/src/qxtglobalshortcut.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,58 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
+ **
+ ** <http://libqxt.org> <found...@libqxt.org>
+ **
+
****************************************************************************/
+#ifndef QXTGLOBALSHORTCUT_H
+#define QXTGLOBALSHORTCUT_H
+
+#include "qxtglobal.h"
+#include <QObject>
+#include <QKeySequence>
+class QxtGlobalShortcutPrivate;
+
+class QxtGlobalShortcut : public QObject
+{
+ Q_OBJECT
+ QXT_DECLARE_PRIVATE(QxtGlobalShortcut)
+ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
+ Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut)
+
+public:
+ explicit QxtGlobalShortcut(QObject* parent = 0);
+ explicit QxtGlobalShortcut(const QKeySequence& shortcut, QObject*
parent = 0);
+ virtual ~QxtGlobalShortcut();
+
+ QKeySequence shortcut() const;
+ bool setShortcut(const QKeySequence& shortcut);
+
+ bool isEnabled() const;
+
+public Q_SLOTS:
+ void setEnabled(bool enabled = true);
+ void setDisabled(bool disabled = true);
+
+Q_SIGNALS:
+ void activated();
+};
+
+#endif // QXTGLOBALSHORTCUT_H
=======================================
--- /dev/null
+++ /qtcore/src/qxtglobalshortcut_mac.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,297 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
+ **
+ ** <http://libqxt.org> <found...@libqxt.org>
+ **
+
****************************************************************************/
+#include <Carbon/Carbon.h>
+#include "qxtglobalshortcut_p.h"
+#include <QMap>
+#include <QHash>
+#include <QtDebug>
+#include <QApplication>
+
+typedef QPair<uint, uint> Identifier;
+static QMap<quint32, EventHotKeyRef> keyRefs;
+static QHash<Identifier, quint32> keyIDs;
+static quint32 hotKeySerial = 0;
+static bool qxt_mac_handler_installed = false;
+
+OSStatus qxt_mac_handle_hot_key(EventHandlerCallRef nextHandler, EventRef
event, void* data)
+{
+ Q_UNUSED(nextHandler);
+ Q_UNUSED(data);
+ if (GetEventClass(event) == kEventClassKeyboard && GetEventKind(event)
== kEventHotKeyPressed)
+ {
+ EventHotKeyID keyID;
+ GetEventParameter(event, kEventParamDirectObject,
typeEventHotKeyID, NULL, sizeof(keyID), NULL, &keyID);
+ Identifier id = keyIDs.key(keyID.id);
+ QxtGlobalShortcutPrivate::activateShortcut(id.second, id.first);
+ }
+ return noErr;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers
modifiers)
+{
+ quint32 native = 0;
+ if (modifiers & Qt::ShiftModifier)
+ native |= shiftKeyBit;
+ if (modifiers & Qt::ControlModifier)
+ native |= cmdKey;
+ if (modifiers & Qt::AltModifier)
+ native |= optionKey;
+ if (modifiers & Qt::MetaModifier)
+ native |= controlKey;
+ if (modifiers & Qt::KeypadModifier)
+ native |= kEventKeyModifierNumLockMask;
+ return native;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key,
Qt::KeyboardModifiers modifiers)
+{
+ quint32 INVALID_KEYCODE = 0xff;
+
+ switch (key)
+ {
+ case Qt::Key_A:
+ return kVK_ANSI_A;
+ case Qt::Key_S:
+ return kVK_ANSI_S;
+ case Qt::Key_D:
+ return kVK_ANSI_D;
+ case Qt::Key_F:
+ return kVK_ANSI_F;
+ case Qt::Key_H:
+ return kVK_ANSI_H;
+ case Qt::Key_G:
+ return kVK_ANSI_G;
+ case Qt::Key_Z:
+ return kVK_ANSI_Z;
+ case Qt::Key_X:
+ return kVK_ANSI_X;
+ case Qt::Key_C:
+ return kVK_ANSI_C;
+ case Qt::Key_V:
+ return kVK_ANSI_V;
+ case Qt::Key_B:
+ return kVK_ANSI_B;
+ case Qt::Key_Q:
+ return kVK_ANSI_Q;
+ case Qt::Key_W:
+ return kVK_ANSI_W;
+ case Qt::Key_E:
+ return kVK_ANSI_E;
+ case Qt::Key_R:
+ return kVK_ANSI_R;
+ case Qt::Key_Y:
+ return kVK_ANSI_Y;
+ case Qt::Key_T:
+ return kVK_ANSI_T;
+ case Qt::Key_1:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad1 : kVK_ANSI_1;
+ case Qt::Key_2:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad2 : kVK_ANSI_2;
+ case Qt::Key_3:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad3 : kVK_ANSI_3;
+ case Qt::Key_4:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad4 : kVK_ANSI_4;
+ case Qt::Key_6:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad6 : kVK_ANSI_6;
+ case Qt::Key_5:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad5 : kVK_ANSI_5;
+ case Qt::Key_Equal:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_KeypadEquals :
kVK_ANSI_Equal;
+ case Qt::Key_9:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad9 : kVK_ANSI_9;
+ case Qt::Key_7:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad7 : kVK_ANSI_7;
+ case Qt::Key_Minus:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_KeypadMinus :
kVK_ANSI_Minus;
+ case Qt::Key_8:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad8 : kVK_ANSI_8;
+ case Qt::Key_0:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad0 : kVK_ANSI_0;
+ case Qt::Key_BracketRight:
+ return kVK_ANSI_RightBracket;
+ case Qt::Key_O:
+ return kVK_ANSI_O;
+ case Qt::Key_U:
+ return kVK_ANSI_U;
+ case Qt::Key_BracketLeft:
+ return kVK_ANSI_LeftBracket;
+ case Qt::Key_I:
+ return kVK_ANSI_I;
+ case Qt::Key_P:
+ return kVK_ANSI_P;
+ case Qt::Key_L:
+ return kVK_ANSI_L;
+ case Qt::Key_J:
+ return kVK_ANSI_J;
+ case Qt::Key_QuoteDbl:
+ return kVK_ANSI_Quote;
+ case Qt::Key_K:
+ return kVK_ANSI_K;
+ case Qt::Key_Semicolon:
+ return kVK_ANSI_Semicolon;
+ case Qt::Key_Backslash:
+ return kVK_ANSI_Backslash;
+ case Qt::Key_Comma:
+ return kVK_ANSI_Comma;
+ case Qt::Key_Slash:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_KeypadDivide :
kVK_ANSI_Slash;
+ case Qt::Key_N:
+ return kVK_ANSI_N;
+ case Qt::Key_M:
+ return kVK_ANSI_M;
+ case Qt::Key_Period:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_KeypadDecimal :
kVK_ANSI_Period;
+ case Qt::Key_Dead_Grave:
+ return kVK_ANSI_Grave;
+ case Qt::Key_Asterisk:
+ return kVK_ANSI_KeypadMultiply;
+ case Qt::Key_Plus:
+ return kVK_ANSI_KeypadPlus;
+ case Qt::Key_Clear:
+ return kVK_ANSI_KeypadClear;
+ case Qt::Key_Return:
+ return kVK_Return;
+ case Qt::Key_Enter:
+ return kVK_ANSI_KeypadEnter;
+ case Qt::Key_Tab:
+ return kVK_Tab;
+ case Qt::Key_Space:
+ return kVK_Space;
+ case Qt::Key_Backspace:
+ return kVK_Delete;
+ case Qt::Key_Escape:
+ return kVK_Escape;
+ case Qt::Key_Control:
+ return kVK_Command;
+ case Qt::Key_Shift:
+ return kVK_Shift;
+ case Qt::Key_CapsLock:
+ return kVK_CapsLock;
+ case Qt::Key_Option:
+ return kVK_Option;
+ case Qt::Key_Meta:
+ return kVK_Control;
+ case Qt::Key_F17:
+ return kVK_F17;
+ case Qt::Key_VolumeUp:
+ return kVK_VolumeUp;
+ case Qt::Key_VolumeDown:
+ return kVK_VolumeDown;
+ case Qt::Key_F18:
+ return kVK_F18;
+ case Qt::Key_F19:
+ return kVK_F19;
+ case Qt::Key_F20:
+ return kVK_F20;
+ case Qt::Key_F5:
+ return kVK_F5;
+ case Qt::Key_F6:
+ return kVK_F6;
+ case Qt::Key_F7:
+ return kVK_F7;
+ case Qt::Key_F3:
+ return kVK_F3;
+ case Qt::Key_F8:
+ return kVK_F8;
+ case Qt::Key_F9:
+ return kVK_F9;
+ case Qt::Key_F11:
+ return kVK_F11;
+ case Qt::Key_F13:
+ return kVK_F13;
+ case Qt::Key_F16:
+ return kVK_F16;
+ case Qt::Key_F14:
+ return kVK_F14;
+ case Qt::Key_F10:
+ return kVK_F10;
+ case Qt::Key_F12:
+ return kVK_F12;
+ case Qt::Key_F15:
+ return kVK_F15;
+ case Qt::Key_Help:
+ return kVK_Help;
+ case Qt::Key_Home:
+ return kVK_Home;
+ case Qt::Key_PageUp:
+ return kVK_PageUp;
+ case Qt::Key_Delete:
+ return kVK_ForwardDelete;
+ case Qt::Key_F4:
+ return kVK_F4;
+ case Qt::Key_End:
+ return kVK_End;
+ case Qt::Key_F2:
+ return kVK_F2;
+ case Qt::Key_PageDown:
+ return kVK_PageDown;
+ case Qt::Key_F1:
+ return kVK_F1;
+ case Qt::Key_Left:
+ return kVK_LeftArrow;
+ case Qt::Key_Right:
+ return kVK_RightArrow;
+ case Qt::Key_Down:
+ return kVK_DownArrow;
+ case Qt::Key_Up:
+ return kVK_UpArrow;
+ default:
+ return INVALID_KEYCODE;
+ }
+}
+
+bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32
nativeMods)
+{
+ if (!qxt_mac_handler_installed)
+ {
+ EventTypeSpec t;
+ t.eventClass = kEventClassKeyboard;
+ t.eventKind = kEventHotKeyPressed;
+ InstallApplicationEventHandler(&qxt_mac_handle_hot_key, 1, &t,
NULL, NULL);
+ }
+
+ EventHotKeyID keyID;
+ keyID.signature = 'cute';
+ keyID.id = ++hotKeySerial;
+
+ EventHotKeyRef ref = 0;
+ bool rv = !RegisterEventHotKey(nativeKey, nativeMods, keyID,
GetApplicationEventTarget(), 0, &ref);
+ if (rv)
+ {
+ keyIDs.insert(Identifier(nativeMods, nativeKey), keyID.id);
+ keyRefs.insert(keyID.id, ref);
+ }
+ return rv;
+}
+
+bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey,
quint32 nativeMods)
+{
+ Identifier id(nativeMods, nativeKey);
+ if (!keyIDs.contains(id)) return false;
+
+ EventHotKeyRef ref = keyRefs.take(keyIDs[id]);
+ keyIDs.remove(id);
+ return !UnregisterEventHotKey(ref);
+}
=======================================
--- /dev/null
+++ /qtcore/src/qxtglobalshortcut_p.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,66 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
+ **
+ ** <http://libqxt.org> <found...@libqxt.org>
+ **
+
****************************************************************************/
+#ifndef QXTGLOBALSHORTCUT_P_H
+#define QXTGLOBALSHORTCUT_P_H
+
+#include "qxtglobalshortcut.h"
+#include <QAbstractEventDispatcher>
+#include <QKeySequence>
+#include <QHash>
+
+class QxtGlobalShortcutPrivate : public QxtPrivate<QxtGlobalShortcut>
+{
+public:
+ QXT_DECLARE_PUBLIC(QxtGlobalShortcut)
+ QxtGlobalShortcutPrivate();
+ ~QxtGlobalShortcutPrivate();
+
+ bool enabled;
+ Qt::Key key;
+ Qt::KeyboardModifiers mods;
+
+ bool setShortcut(const QKeySequence& shortcut);
+ bool unsetShortcut();
+
+ static bool error;
+#ifndef Q_WS_MAC
+ static int ref;
+ static QAbstractEventDispatcher::EventFilter prevEventFilter;
+ static bool eventFilter(void* message);
+#endif // Q_WS_MAC
+
+ static void activateShortcut(quint32 nativeKey, quint32 nativeMods);
+
+private:
+ static quint32 nativeKeycode(Qt::Key keycode, Qt::KeyboardModifiers
modifiers=Qt::NoModifier);
+ static quint32 nativeModifiers(Qt::KeyboardModifiers modifiers);
+
+ static bool registerShortcut(quint32 nativeKey, quint32 nativeMods);
+ static bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods);
+
+ static QHash<QPair<quint32, quint32>, QxtGlobalShortcut*> shortcuts;
+};
+
+#endif // QXTGLOBALSHORTCUT_P_H
=======================================
--- /dev/null
+++ /qtcore/src/qxtglobalshortcut_win.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,233 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
+ **
+ ** <http://libqxt.org> <found...@libqxt.org>
+ **
+
****************************************************************************/
+#include "qxtglobalshortcut_p.h"
+#include <qt_windows.h>
+
+bool QxtGlobalShortcutPrivate::eventFilter(void* message)
+{
+ MSG* msg = static_cast<MSG*>(message);
+ if (msg->message == WM_HOTKEY)
+ {
+ const quint32 keycode = HIWORD(msg->lParam);
+ const quint32 modifiers = LOWORD(msg->lParam);
+ activateShortcut(keycode, modifiers);
+ }
+ return false;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers
modifiers)
+{
+ // MOD_ALT, MOD_CONTROL, (MOD_KEYUP), MOD_SHIFT, MOD_WIN
+ quint32 native = 0;
+ if (modifiers & Qt::ShiftModifier)
+ native |= MOD_SHIFT;
+ if (modifiers & Qt::ControlModifier)
+ native |= MOD_CONTROL;
+ if (modifiers & Qt::AltModifier)
+ native |= MOD_ALT;
+ if (modifiers & Qt::MetaModifier)
+ native |= MOD_WIN;
+ // TODO: resolve these?
+ //if (modifiers & Qt::KeypadModifier)
+ //if (modifiers & Qt::GroupSwitchModifier)
+ return native;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key,
Qt::KeyboardModifiers modifiers)
+{
+ switch (key)
+ {
+ case Qt::Key_Escape:
+ return VK_ESCAPE;
+ case Qt::Key_Tab:
+ case Qt::Key_Backtab:
+ return VK_TAB;
+ case Qt::Key_Backspace:
+ return VK_BACK;
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ return VK_RETURN;
+ case Qt::Key_Insert:
+ return VK_INSERT;
+ case Qt::Key_Delete:
+ return VK_DELETE;
+ case Qt::Key_Pause:
+ return VK_PAUSE;
+ case Qt::Key_Print:
+ return VK_PRINT;
+ case Qt::Key_Clear:
+ return VK_CLEAR;
+ case Qt::Key_Home:
+ return VK_HOME;
+ case Qt::Key_End:
+ return VK_END;
+ case Qt::Key_Left:
+ return VK_LEFT;
+ case Qt::Key_Up:
+ return VK_UP;
+ case Qt::Key_Right:
+ return VK_RIGHT;
+ case Qt::Key_Down:
+ return VK_DOWN;
+ case Qt::Key_PageUp:
+ return VK_PRIOR;
+ case Qt::Key_PageDown:
+ return VK_NEXT;
+ case Qt::Key_F1:
+ return VK_F1;
+ case Qt::Key_F2:
+ return VK_F2;
+ case Qt::Key_F3:
+ return VK_F3;
+ case Qt::Key_F4:
+ return VK_F4;
+ case Qt::Key_F5:
+ return VK_F5;
+ case Qt::Key_F6:
+ return VK_F6;
+ case Qt::Key_F7:
+ return VK_F7;
+ case Qt::Key_F8:
+ return VK_F8;
+ case Qt::Key_F9:
+ return VK_F9;
+ case Qt::Key_F10:
+ return VK_F10;
+ case Qt::Key_F11:
+ return VK_F11;
+ case Qt::Key_F12:
+ return VK_F12;
+ case Qt::Key_F13:
+ return VK_F13;
+ case Qt::Key_F14:
+ return VK_F14;
+ case Qt::Key_F15:
+ return VK_F15;
+ case Qt::Key_F16:
+ return VK_F16;
+ case Qt::Key_F17:
+ return VK_F17;
+ case Qt::Key_F18:
+ return VK_F18;
+ case Qt::Key_F19:
+ return VK_F19;
+ case Qt::Key_F20:
+ return VK_F20;
+ case Qt::Key_F21:
+ return VK_F21;
+ case Qt::Key_F22:
+ return VK_F22;
+ case Qt::Key_F23:
+ return VK_F23;
+ case Qt::Key_F24:
+ return VK_F24;
+ case Qt::Key_Space:
+ return VK_SPACE;
+ case Qt::Key_Asterisk:
+ return VK_MULTIPLY;
+ case Qt::Key_Plus:
+ return VK_ADD;
+ case Qt::Key_Comma:
+ return VK_SEPARATOR;
+ case Qt::Key_Minus:
+ return VK_SUBTRACT;
+ case Qt::Key_Slash:
+ return VK_DIVIDE;
+
+#ifdef VK_MEDIA_NEXT_TRACK
+ case Qt::Key_MediaNext:
+ return VK_MEDIA_NEXT_TRACK;
+ case Qt::Key_MediaPrevious:
+ return VK_MEDIA_PREV_TRACK;
+ case Qt::Key_MediaPlay:
+ return VK_MEDIA_PLAY_PAUSE;
+ case Qt::Key_MediaStop:
+ return VK_MEDIA_STOP;
+ // couldn't find those in VK_*
+ //case Qt::Key_MediaLast:
+ //case Qt::Key_MediaRecord:
+ case Qt::Key_VolumeDown:
+ return VK_VOLUME_DOWN;
+ case Qt::Key_VolumeUp:
+ return VK_VOLUME_UP;
+ case Qt::Key_VolumeMute:
+ return VK_VOLUME_MUTE;
+#endif
+ // numbers
+ case Qt::Key_0:
+ case Qt::Key_1:
+ case Qt::Key_2:
+ case Qt::Key_3:
+ case Qt::Key_4:
+ case Qt::Key_5:
+ case Qt::Key_6:
+ case Qt::Key_7:
+ case Qt::Key_8:
+ case Qt::Key_9:
+ return key;
+
+ // letters
+ case Qt::Key_A:
+ case Qt::Key_B:
+ case Qt::Key_C:
+ case Qt::Key_D:
+ case Qt::Key_E:
+ case Qt::Key_F:
+ case Qt::Key_G:
+ case Qt::Key_H:
+ case Qt::Key_I:
+ case Qt::Key_J:
+ case Qt::Key_K:
+ case Qt::Key_L:
+ case Qt::Key_M:
+ case Qt::Key_N:
+ case Qt::Key_O:
+ case Qt::Key_P:
+ case Qt::Key_Q:
+ case Qt::Key_R:
+ case Qt::Key_S:
+ case Qt::Key_T:
+ case Qt::Key_U:
+ case Qt::Key_V:
+ case Qt::Key_W:
+ case Qt::Key_X:
+ case Qt::Key_Y:
+ case Qt::Key_Z:
+ return key;
+
+ default:
+ return 0;
+ }
+}
+
+bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32
nativeMods)
+{
+ return RegisterHotKey(0, nativeMods ^ nativeKey, nativeMods,
nativeKey);
+}
+
+bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey,
quint32 nativeMods)
+{
+ return UnregisterHotKey(0, nativeMods ^ nativeKey);
+}
=======================================
--- /dev/null
+++ /qtcore/src/qxtglobalshortcut_x11.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,118 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
+ **
+ ** <http://libqxt.org> <found...@libqxt.org>
+ **
+
****************************************************************************/
+#include "qxtglobalshortcut_p.h"
+#include <QX11Info>
+#include <X11/Xlib.h>
+
+static int (*original_x_errhandler)(Display* display, XErrorEvent* event);
+
+static int qxt_x_errhandler(Display* display, XErrorEvent *event)
+{
+ Q_UNUSED(display);
+ switch (event->error_code)
+ {
+ case BadAccess:
+ case BadValue:
+ case BadWindow:
+ if (event->request_code == 33 /* X_GrabKey */ ||
+ event->request_code == 34 /* X_UngrabKey */)
+ {
+ QxtGlobalShortcutPrivate::error = true;
+ //TODO:
+ //char errstr[256];
+ //XGetErrorText(dpy, err->error_code, errstr, 256);
+ }
+ default:
+ return 0;
+ }
+}
+
+bool QxtGlobalShortcutPrivate::eventFilter(void* message)
+{
+ XEvent* event = static_cast<XEvent*>(message);
+ if (event->type == KeyPress)
+ {
+ XKeyEvent* key = (XKeyEvent*) event;
+ activateShortcut(key->keycode,
+ // Mod1Mask == Alt, Mod4Mask == Meta
+ key->state & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask));
+ }
+ return false;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers
modifiers)
+{
+ // ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask,
Mod4Mask, and Mod5Mask
+ quint32 native = 0;
+ if (modifiers & Qt::ShiftModifier)
+ native |= ShiftMask;
+ if (modifiers & Qt::ControlModifier)
+ native |= ControlMask;
+ if (modifiers & Qt::AltModifier)
+ native |= Mod1Mask;
+ if (modifiers & Qt::MetaModifier)
+ native |= Mod4Mask;
+
+ // TODO: resolve these?
+ //if (modifiers & Qt::MetaModifier)
+ //if (modifiers & Qt::KeypadModifier)
+ //if (modifiers & Qt::GroupSwitchModifier)
+ return native;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key,
Qt::KeyboardModifiers modifiers)
+{
+ Display* display = QX11Info::display();
+ return XKeysymToKeycode(display,
XStringToKeysym(QKeySequence(key).toString().toLatin1().data()));
+}
+
+bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32
nativeMods)
+{
+ Display* display = QX11Info::display();
+ Window window = QX11Info::appRootWindow();
+ Bool owner = True;
+ int pointer = GrabModeAsync;
+ int keyboard = GrabModeAsync;
+ error = false;
+ original_x_errhandler = XSetErrorHandler(qxt_x_errhandler);
+ XGrabKey(display, nativeKey, nativeMods, window, owner, pointer,
keyboard);
+ XGrabKey(display, nativeKey, nativeMods | Mod2Mask, window, owner,
pointer, keyboard); // allow numlock
+ XSync(display, False);
+ XSetErrorHandler(original_x_errhandler);
+ return !error;
+}
+
+bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey,
quint32 nativeMods)
+{
+ Display* display = QX11Info::display();
+ Window window = QX11Info::appRootWindow();
+ error = false;
+ original_x_errhandler = XSetErrorHandler(qxt_x_errhandler);
+ XUngrabKey(display, nativeKey, nativeMods, window);
+ XUngrabKey(display, nativeKey, nativeMods | Mod2Mask, window); //
allow numlock
+ XSync(display, False);
+ XSetErrorHandler(original_x_errhandler);
+ return !error;
+}
=======================================
--- /dev/null
+++ /qtcore/src/systemtrayicon.cpp Wed Aug 31 02:54:24 2011
@@ -0,0 +1,110 @@
+#include <QDebug>
+#include <QApplication>
+#include <QMenu>
+#include "systemtrayicon.h"
+#include "jsapi.h"
+#include "dataloader.h"
+#include "debugger.h"
+
+static SystemTrayIconApp* g_app = 0;
+
+SystemTrayIconApp::SystemTrayIconApp(const QString& appname, QObject
*parent)
+ : App(appname, parent)
+{
+}
+
+QByteArray SystemTrayIconApp::processCall(const QString& command, const
QVariantMap& param)
+{
+ QSystemTrayIcon* icon;
+
+ if (command == "create") {
+ icon = new QSystemTrayIcon();
+ connect(icon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
+ this, SLOT(notifyClicked(QSystemTrayIcon::ActivationReason)));
+ return QString("{\"type\":\"SystemTrayIcon\",\"id\":\"%1\"}")
+ .arg(getId(icon)).toLatin1();
+ }
+
+
+ QString id = param.value("id").toString();
+ icon = static_cast<QSystemTrayIcon *>(getInstance(id));
+ if (!icon) {
+ return "{\"err\":\"invalid id\"}";
+ }
+
+ if (command == "destroy") {
+ delete icon;
+ return "null";
+ } else if (command == "load") {
+ DataLoader *loader = new DataLoader(icon);
+ connect(loader, SIGNAL(got(QByteArray&)),
+ this, SLOT(iconFetched(QByteArray&)));
+ connect(loader, SIGNAL(got(QByteArray&)),
+ loader, SLOT(deleteLater()));
+ loader->load(param["url"].toString());
+ return "null";
+ } else if (command == "setContextMenu") {
+ QString menu_id = param.value("menuId").toString();
+ QMenu* menu = static_cast<QMenu *>(getInstance(menu_id));
+ if (!menu) {
+ return "{\"err\":\"invalid menu id\"}";
+ }
+ icon->setContextMenu(menu);
+ return "null";
+ }
+
+ return "{\"err\":\"invalid command\"}";
+}
+
+void SystemTrayIconApp::iconFetched(QByteArray &data)
+{
+ QSystemTrayIcon *icon = static_cast<QSystemTrayIcon
*>(sender()->parent());
+
+ QPixmap pixmap;
+ pixmap.loadFromData(data);
+
+ icon->setIcon(QIcon(pixmap));
+ icon->show();
+}
+
+void SystemTrayIconApp::notifyClicked(QSystemTrayIcon::ActivationReason
reason)
+{
+ QSystemTrayIcon *icon = static_cast<QSystemTrayIcon *>(sender());
+ QString channel = QString("systray.SystemTrayIcon.%1.").arg(getId(icon));
+
+ switch (reason) {
+ case QSystemTrayIcon::Trigger:
+ publishEvent("SystemTrayIcon", icon, "click");
+ break;
+ case QSystemTrayIcon::Context:
+ publishEvent("SystemTrayIcon", icon, "rightclick");
+ break;
+ case QSystemTrayIcon::DoubleClick:
+ publishEvent("SystemTrayIcon", icon, "doubleclick");
+ break;
+ default:
+ ;
+ }
+}
+
+static onering_response_handle_t app(const char* appname, const char*
method,
+ const char* path, const char* body,
+ const char** response, int* response_len)
+{
+ if (!g_app) {
+ g_app = new SystemTrayIconApp(appname);
+ }
+
+ return g_app->processRequest(appname, method, path, body, response,
response_len);
+}
+
+
+static void app_free_response(const char* appname,
onering_response_handle_t response_handle)
+{
+ g_app->freeResponse(appname, response_handle);
+}
+
+void register_systray_app(const char* appname)
+{
+ onering_register_app(appname, &app, &app_free_response);
+}
=======================================
--- /dev/null
+++ /qtcore/src/systemtrayicon.h Wed Aug 31 02:54:24 2011
@@ -0,0 +1,25 @@
+#ifndef SYSTEMTRAYICON_H
+#define SYSTEMTRAYICON_H
+
+#include <QSystemTrayIcon>
+#include <QByteArray>
+#include "app.h"
+
+class SystemTrayIconApp : public App
+{
+Q_OBJECT
+
+public:
+ SystemTrayIconApp(const QString& appname, QObject* parent=0);
+
+private:
+ QByteArray processCall(const QString& command, const QVariantMap& param);
+
+private slots:
+ void iconFetched(QByteArray &data);
+ void notifyClicked(QSystemTrayIcon::ActivationReason reason);
+};
+
+void register_systray_app(const char* appname);
+
+#endif
=======================================
--- /js/onering.js Thu Feb 10 00:14:14 2011
+++ /dev/null
@@ -1,446 +0,0 @@
-ONERING = new Object();
-
-// Base {{{
-ONERING.Base = function() {};
-ONERING.Base.prototype = {
- _call: function(command, param) {
- if (!param) { param = {}; }
- param.id = this.id;
- return ONERING.call_app(this.appname, command, param);
- },
- _create: function(command, param) {
- var obj = ONERING.call_app(this.appname, command, param);
- if (!(this.validate_type(obj))) {
- throw new Error(this.type + " not created");
- }
- return obj;
- },
- _destroy: function(command) {
- if (!this.id) { return; }
- var r = this._call(command);
- this.id = null;
- return r;
- },
- validate_type: function(obj) {
- return (obj && obj.type == this.type);
- },
- bind: function(event, callback) {
- ONERING.subscribe(this.appname+"."+this.type+"."+this.id+"."+event,
- function(e) {
- if (e instanceof Object && e.event_id) {
- e = new ONERING.Event(e.event_id);
- }
- callback(e);
- });
- },
- unbind: function(event) {
- ONERING.unsubscribe(this.appname+"."+this.type+"."+this.id+"."+event);
- },
- extend: function(d) {
- for (var k in d) {
- this[k] = d[k];
- }
- return this;
- },
-};
-//}}}
-
-// Event {{{
-ONERING.Event = function(id) {
- this.id = id;
-};
-ONERING.Event.prototype = (new ONERING.Base()).extend({
- appname: "onering",
- type: "Event",
- preventDefault: function() {
- this._call("Event.preventDefault");
- }
- });
-// }}}
-
-// Application {{{
-
-ONERING.Application = function() {
- this.id = 0;
-};
-ONERING.Application.prototype = (new ONERING.Base()).extend({
- appname: "onering",
- type: "Application",
- setQuitOnLastWindowClosed: function(quit) {
- return this._call("Application.setQuitOnLastWindowClosed", {quit:
quit}),
- },
- exit: function() {
- this._call("Application.exit");
- },
- });
-
-ONERING.application = new ONERING.Application();
-ONERING.getApplication = function() {
- return ONERING.application;
-};
-
-// }}}
-
-// Window {{{
-
-ONERING.Window = function(obj) {
- if (!this.validate_type(obj)) {
- throw new Error("invalid type");
- }
- this.id = obj.id;
-};
-ONERING.Window.prototype = (new ONERING.Base()).extend({
- appname: "onering",
- type: "Window",
- createWindow: function(url, width, height, props) {
- url = ONERING.resolve(url);
- props.url = url;
- props.width = width;
- props.height = height;
- var window = this._create("Window.create", props);
- return new ONERING.Window(window);
- },
- isAlive: function() {
- return this._call("Window.isAlive");
- },
- showInspector: function() {
- return this._call("Window.showInspector");
- },
- hide: function() {
- return this._call("Window.hide");
- },
- show: function() {
- return this._call("Window.show");
- },
- maximize: function() {
- return this._call("Window.maximize");
- },
- showNormal: function() {
- return this._call("Window.showNormal");
- },
- isMinimized: function() {
- return this._call("Window.isMinimized");
- },
- activateWindow: function() {
- return this._call("Window.activateWindow");
- }
-
- });
-
-ONERING.window = new ONERING.Window({type: "Window",
- id: _OneRing.getCurrentWindowId()});
-
-ONERING.getCurrentWindow = function() {
- return ONERING.window;
-};
-
-// shortcuts
-ONERING.createWindow = function(url, width, height, props) {
- return ONERING.getCurrentWindow().createWindow(url, width, height, props);
-};
-
-// }}}
-
-// System Tray Icon {{{
-
-ONERING.SystemTrayIcon = function(url) {
- this.id = this._create("create").id;
- if (url) {
- this.load(url);
- }
-};
-ONERING.SystemTrayIcon.prototype = (new ONERING.Base()).extend({
- appname: "systray",
- type: "SystemTrayIcon",
- destroy: function() {
- this._destroy("destroy");
- },
- load: function(url) {
- return this._call("load", {url: ONERING.resolve(url)});
- },
- setContextMenu: function(menu) {
- return this._call("setContextMenu", {menuId: menu.id});
- }
- });
-
-// }}}
-
-// Menu {{{
-
-ONERING.Menu = function(items) {
- this.id = this._create("Menu.create").id;
- for (var i=0; i<items.length; i++) {
- var item = items[i];
- if (item === ONERING.Menu.SEPARATOR) {
- this.addSeparator();
- } else {
- this.addItem(item[0], item[1], item[2]);
- }
- };
-};
-ONERING.Menu.SEPARATOR = Object(); // a const
-ONERING.Menu.prototype = new ONERING.Base();
-ONERING.Menu.prototype.extend({
- appname: "menu",
- type: "Menu",
- destroy: function() {
- this._destroy("Menu.destroy");
- },
- addSeparator: function() {
- return this._call("Menu.addSeparator");
- },
- addItem: function(title, callback, props) {
- if (!(callback instanceof Function)) {
- props = callback;
- callback = null;
- }
- var item = new ONERING.MenuItem(this._call("Menu.addMenuItem", {text:
title}));
- if (callback) {
- item.bind('triggered', callback);
- }
- if (props) {
- item.setProperties(props);
- }
- },
- get: function(index) {
- return new ONERING.MenuItem(this._call("Menu.getMenuItem", {index:
index}));
- }
- });
-
-ONERING.MenuItem = function(item) {
- if (!item || item.type != this.type) {
- throw new Error("invalid menu item");
- }
- this.id = item.id;
-};
-ONERING.MenuItem.prototype = (new ONERING.Base()).extend({
- appname: "menu",
- type: "MenuItem",
- setProperties: function(props) {
- return this._call("MenuItem.setProperties", props);
- },
- setText: function(text) {
- return this._call("MenuItem.setText", {text: text});
- },
- setEnabled: function(enabled) {
- return this.setProperties({enabled: enabled});
- },
- });
-
-// }}}
-
-// HotKey {{{
-
-ONERING.HotKey = function() {
-};
-ONERING.HotKey.prototype = (new ONERING.Base()).extend({
- appname: "hotkey",
- type: "HotKey",
- destroy: function() {
- return this._call("destroy");
- },
- });
-ONERING.HotKey.instances = {};
-ONERING.HotKey.create = function(shortcut) {
- var hotkey = new ONERING.HotKey();
- hotkey.id = (hotkey._create("create", {shortcut: shortcut})).id;
- ONERING.HotKey.instances[shortcut] = hotkey;
- return hotkey;
-};
-ONERING.HotKey.set = function(shortcut, callback) {
- var hotkey = ONERING.HotKey.instances[shortcut] || new
ONERING.HotKey.create(shortcut);
- hotkey.bind("activated", callback);
-};
-ONERING.HotKey.clear = function(shortcut) {
- var hotkey = ONERING.HotKey.instances[shortcut];
- if (hotkey !== undefined) {
- hotkey.destroy();
- delete ONERING.HotKey.instances[shortcut];
- }
-};
-ONERING.setHotKey = ONERING.HotKey.set;
-ONERING.clearHotKey = ONERING.HotKey.clear;
-
-window.addEventListener('unload', function() {
- for (var shortcut in ONERING.HotKey.instances) {
- ONERING.HotKey.clear(shortcut);
- }
- });
-
-// }}}
-
-// subscribe/unsubscribe {{{
-
-ONERING.subscriptions = {};
-ONERING.hub = _OneRing.getPubSubHub().published;
-
-ONERING.subscribe = function(channel, callback) {
- var ss = ONERING.subscriptions[channel] = ONERING.subscriptions[channel] |
| {};
- var f = ss[callback] = ss[callback] || function(ch, msg) {
- if (ch === channel) {
- callback(JSON.parse(msg));
- }
- };
- ONERING.hub.connect(f);
-};
-
-ONERING.unsubscribe = function(channel, callback) {
- if (channel === undefined) {
- for (channel in ONERING.subscriptions) {
- ONERING.unsubscribe(channel);
- }
- } else {
- var ss = ONERING.subscriptions[channel];
- if (ss) {
- if (callback === undefined) {
- for (callback in ss) {
- ONERING.hub.disconnect(ss[callback]);
- }
- delete ONERING.subscriptions[channel];
- } else {
- var f = ss[callback];
- if (f) {
- ONERING.hub.disconnect(f);
- delete ss[callback];
- }
- }
- }
- }
-};
-
-window.addEventListener('unload', function() {
- ONERING.unsubscribe();
- });
-
-// }}}
-
-// functions {{{
-
-ONERING.log = function(o) {
- return _OneRing.log(o);
-};
-
-ONERING.callback = function(name, para) {
- var window_id = name.split('_')[1];
- if (window_id != ONERING._window_id) {
- return;
- }
- var f = _get_registered_function(name);
- if (f) {
- f(para);
- }
-};
-
-ONERING.exit = function() {
- ONERING.getApplication().exit();
-};
-
-ONERING.ajax = function(settings) {
- var url = settings.url;
- var data = settings.data || "";
- if ( data instanceof Object ) {
- data = ONERING.param(data);
- }
- var type = settings.type || "GET";
- var dataType = settings.dataType;
- var success = settings.success;
- var async = settings.async || true;
-
- if (data && type == "GET") {
- url += ((url.indexOf('?') < 0) ? '?' : '&') + data;
- data = "";
- }
-
- _OneRing.ajax(type, url, data, _register_function(function(s) {
- if (dataType == "json") {
- s = window.JSON.parse(s);
- }
- success && success(s);
- }), async);
-};
-
-ONERING.get = function(url, data, callback, dataType) {
- if (data instanceof Function) {
- dataType = dataType || callback;
- callback = data;
- data = null;
- }
-
- return ONERING.ajax({
- type: "GET",
- url: url,
- data: data,
- success: callback,
- dataType: dataType
- });
-};
-
-ONERING.getJSON = function(url, data, callback) {
- return ONERING.get(url, data, callback, "json");
-};
-
-ONERING.post = function(url, data, callback, dataType) {
- if (data instanceof Function) {
- dataType = dataType || callback;
- callback = data;
- data = null;
- }
-
- return ONERING.ajax({
- type: "POST",
- url: url,
- data: data,
- success: callback,
- dataType: dataType
- });
-};
-
-ONERING.call_app = function(appname, command, param) {
- var url = appname ? ("onering://"+appname+"/"+command) : ("/"+command);
- var data = JSON.stringify(param || {});
- var r = _OneRing.call("POST", url, data);
- r = JSON.parse(r);
- if (r && r.err) {
- throw new Error("ONERING.call_app("+appname+", "+command+") failed: " +
r.err);
- }
- return r;
-};
-
-ONERING.resolve = function(url) {
- return _OneRing.resolve(url);
-};
-
-// }}}
-
-// internal utilities {{{
-
-var _guid = 0;
-var _get_guid = function() {
- _guid += 1;
- return '' + _guid;
-};
-
-ONERING._window_id = Math.floor(Math.random()*1000000);
-
-var _registered_functions = new Object();
-var _register_function = function(func) {
- var name = 'f_' + ONERING._window_id + '_' + _get_guid();
- _registered_functions[name] = func;
- return name;
-};
-var _get_registered_function = function(name) {
- return _registered_functions[name];
-};
-
-ONERING.param = function(a) {
- var s = [];
- for (var key in a) {
- var value = a[key];
- s.push( encodeURIComponent(key) + "=" + encodeURIComponent(value) );
- }
- return s.join("&").replace(/%20/g, "+");
-};
-
-// }}}
-
-// vim:set foldmethod=marker:
=======================================
--- /onering.pro Sun Feb 6 08:24:12 2011
+++ /dev/null
@@ -1,96 +0,0 @@
-######################################################################
-# Automatically generated by qmake (2.01a) Thu Aug 19 21:40:02 2010
-######################################################################
-
-TEMPLATE = lib
-TARGET = OneRing
-DEPENDPATH += . include src
-INCLUDEPATH += . include
-QT += webkit network
-RESOURCES = onering.qrc
-CONFIG += shared
-DEFINES += ONERING_LIBRARY
-VERSION = 1
-macx {
- CONFIG += lib_bundle
- FRAMEWORK_HEADERS.version = Versions
- FRAMEWORK_HEADERS.files = include/onering.h
- FRAMEWORK_HEADERS.path = Headers
- QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS
- QMAKE_FRAMEWORK_BUNDLE_NAME = OneRing
- QMAKE_FRAMEWORK_VERSION = $$VERSION
-}
-
-!release {
- DEFINES += DEBUG
-}
-
-# Input
-HEADERS += \
- include/onering.h \
- src/app.h \
- src/application.h \
- src/appreply.h \
- src/dataloader.h \
- src/debugger.h \
- src/jsapi.h \
- src/json.h \
- src/menu.h \
- src/networkaccessmanager.h \
- src/oneringapp.h \
- src/oneringview.h \
- src/publishevent.h \
- src/pubsubhub.h \
- src/systemtrayicon.h
-
-SOURCES += \
- src/app.cpp \
- src/application.cpp \
- src/appreply.cpp \
- src/dataloader.cpp \
- src/debugger.cpp \
- src/jsapi.cpp \
- src/json.cpp \
- src/menu.cpp \
- src/networkaccessmanager.cpp \
- src/onering.cpp \
- src/oneringapp.cpp \
- src/oneringview.cpp \
- src/publishevent.cpp \
- src/pubsubhub.cpp \
- src/systemtrayicon.cpp
-
-# global shourtcut
-HEADERS += \
- src/hotkey.h \
- src/qxtglobalshortcut.h \
- src/qxtglobal.h \
- src/qxtglobalshortcut_p.h
-
-SOURCES += \
- src/hotkey.cpp \
- src/qxtglobalshortcut.cpp
-
-macx:SOURCES += src/qxtglobalshortcut_mac.cpp
-win32:SOURCES += src/qxtglobalshortcut_win.cpp
-unix:!macx:SOURCES += src/qxtglobalshortcut_x11.cpp
-macx:LIBS += -framework Carbon
-win32 {
- win32-g++:LIBS += -l user32
- !win32-g++:LIBS += user32.lib
-}
-# end of global shortcut
-
-# dock icon click
-macx {
- HEADERS += \
- src/cocoainit.h \
- src/dockiconclick.h
-
- OBJECTIVE_SOURCES += \
- src/cocoainit.mm \
- src/dockiconclick.mm
-
- LIBS += -framework AppKit
-}
-# end dock icon click
=======================================
--- /onering.qrc Sun Sep 19 21:37:09 2010
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource>
- <file>js/onering.js</file>
-</qresource>
-</RCC>
=======================================
--- /src/app.cpp Wed Feb 16 00:49:38 2011
+++ /dev/null
@@ -1,158 +0,0 @@
-#include <QDebug>
-#include <QString>
-#include <QHash>
-#include <QPair>
-#include <QUrl>
-#include <string.h>
-#include <assert.h>
-#include <onering.h>
-#include "app.h"
-#include "json.h"
-
-QHash<QString, QPair<onering_app_func_t, onering_free_response_func_t> >
g_apps;
-
-int onering_register_app(const char* appname, onering_app_func_t app_func,
onering_free_response_func_t free_response_func)
-{
- if (strlen(appname) > ONERING_MAX_APPNAME_LEN) {
- return -1;
- }
-
- qDebug() << "register app:" << appname;
- QPair<onering_app_func_t, onering_free_response_func_t> funcs(app_func,
free_response_func);
- g_apps[appname] = funcs;
- return 0;
-}
-
-int is_appname_registered(const QString &appname)
-{
- return g_apps.contains(appname);
-}
-
-QByteArray call_app(const QString &method, const QUrl &url, const QString
&body)
-{
- QString appname = url.host();
- const char * response;
- int response_len;
- onering_response_handle_t response_handle;
- QByteArray retval;
-
- if (is_appname_registered(appname)) {
- QByteArray surl = url.toString().toUtf8();
- QByteArray path_query = url.path().toUtf8();
- if (url.hasQuery()) {
- path_query += surl.mid(surl.indexOf('?'));
- }
-
- response_handle = g_apps[appname].first(qPrintable(appname),
qPrintable(method), path_query, body.toUtf8().constData(), &response,
&response_len);
- retval.append(response, response_len);
- // free response
- g_apps[appname].second(qPrintable(appname), response_handle);
- }
-
- return retval;
-}
-
-QByteArray call_app_body(const QString &method, const QUrl &url, const
QString &body)
-{
- QByteArray response = call_app(method, url, body);
-
- int index;
- if ((index = response.indexOf("\r\n")) < 0) {
- // not header/body seperator found.
- // consider the whole response is body
- return response;
- }
- QByteArray line = response.left(index);
- if (line.indexOf("200") < 0) {
- qDebug() << "error status line:" << line;
- return "";
- }
-
- if ((index = response.indexOf("\r\n\r\n")) < 0) {
- qDebug() << "Body not found:" << response;
- return "";
- }
- response.remove(0, index+4);
- return response;
-}
-
-App::App(const QString& appname, QObject* parent)
- : QObject(parent),
- appname(appname)
-{
-}
-
-onering_response_handle_t App::processRequest(const char* appname,
- const char* method, const QString& path, const QByteArray& body,
- const char** response, int* response_len)
-{
- Q_UNUSED(appname);
- Q_UNUSED(method);
-
- assert(path.startsWith("/"));
-
- QByteArray* res = new QByteArray();
-
- QVariantMap param = Json::parse(QString::fromUtf8(body)).toMap();
- *res = processCall(path.mid(1), param);
-
- *response = res->constData();
- *response_len = res->size();
- return reinterpret_cast<onering_response_handle_t>(res);
-}
-
-void App::freeResponse(const char* appname, onering_response_handle_t
handle)
-{
- Q_UNUSED(appname);
-
- delete reinterpret_cast<QByteArray *>(handle);
-}
-
-QString App::generateObjectId(void* obj)
-{
- return QString::number(reinterpret_cast<unsigned long>(obj), 16);
-}
-
-
-QString App::getId(QObject* obj)
-{
- connect(obj, SIGNAL(destroyed(QObject*)),
- this, SLOT(instanceDestroyed(QObject*)),
- Qt::UniqueConnection);
- return generateObjectId(obj);
-}
-
-QString App::getId(void* obj)
-{
- return generateObjectId(obj);
-}
-
-void* App::getInstance(const QString& id)
-{
- bool ok;
- return reinterpret_cast<void *>(id.toULong(&ok, 16));
-}
-
-void App::instanceDestroyed(QObject* obj)
-{
- qDebug() << obj << "deleted";
-}
-
-void App::publishEvent(const QString& type, void* sender, const QString&
event)
-{
- publishEvent(type, sender, event, "null");
-}
-
-void App::publishEvent(const QString& type, void* sender, const QString&
event, QEvent* e)
-{
- QString data = QString("{\"event_id\":\"%1\"}").arg(getId(e));
- publishEvent(type, sender, event, data);
-}
-
-
-void App::publishEvent(const QString& type, void* sender, const QString&
event, const QString& data)
-{
- onering_publish(qPrintable(QString("%1.%2.%3.%4")
- .arg(appname, type, getId(sender), event)),
- qPrintable(data));
-}
=======================================
--- /src/app.h Wed Feb 16 00:49:38 2011
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef APP_H
-#define APP_H
-
-#include <onering.h>
-#include <QString>
-#include <QUrl>
-#include <QByteArray>
-#include <QVariantMap>
-#include <QEvent>
-#include <QSet>
-
-int is_appname_registered(const QString &appname);
-
-QByteArray call_app(const QString& method, const QUrl &url, const QString
&body);
-QByteArray call_app_body(const QString &method, const QUrl &url, const
QString &body);
-
-class App : public QObject
-{
- Q_OBJECT
-
-public:
- App(const QString& appname, QObject *parent=0);
-
- onering_response_handle_t processRequest(const char* appname, const char*
method, const QString& path, const QByteArray& body, const char** response,
int* response_len);
- void freeResponse(const char* appname, onering_response_handle_t
response_handle);
-
- static QString generateObjectId(void* obj);
-
-private slots:
- void instanceDestroyed(QObject* obj);
-
-protected:
- QString getId(QObject* obj);
- QString getId(void* obj);
- void* getInstance(const QString& id);
- void publishEvent(const QString& type, void* sender, const QString&
event);
- void publishEvent(const QString& type, void* sender, const QString&
event, QEvent* e);
- void publishEvent(const QString& type, void* sender, const QString&
event, const QString& data);
-
-private:
- virtual QByteArray processCall(const QString& command, const QVariantMap&
param) = 0;
-
- QString appname;
-};
-
-#endif
=======================================
***Additional files exist in this changeset.***

==============================================================================
Revision: 655739528403
Author: Qiangning Hong <hon...@gmail.com>
Date: Thu Sep 1 23:32:20 2011
Log: add new api
http://code.google.com/p/onering-desktop/source/detail?r=655739528403

Modified:
/include/onering.h
/qtcore/src/onering.cpp

=======================================
--- /include/onering.h Fri Jan 14 02:21:10 2011
+++ /include/onering.h Thu Sep 1 23:32:20 2011
@@ -19,12 +19,57 @@
/*OUT*/ const char** response, int* response_len);
typedef void (*onering_free_response_func_t) (const char* appname,
onering_response_handle_t response_handle);

-/* Return -1 means strlen(appname) > MAX_APPNAME_LEN */
-ONERING_EXPORT int onering_register_app(const char* appname,
onering_app_func_t app_func, onering_free_response_func_t
free_response_func);
-
+/* Register a app with the name appname.
+ * Register Return -1 means strlen(appname) > MAX_APPNAME_LEN */
+ONERING_EXPORT int onering_register_app(
+ const char* appname,
+ onering_app_func_t app_func,
+ onering_free_response_func_t free_response_func);
+
+/* Start app */
ONERING_EXPORT int onering_loop(const char* appname);

-ONERING_EXPORT void onering_publish(const char* channel, const char* msg);
+/* Return the version number of the core.
+ * e.g. "OneRingQtCore 1.0.0" */
+ONERING_EXPORT const char* onering_version();
+
+/* Load all OneRingPlugins under dir.
+ * Returns number of loaded plugins. */
+ONERING_EXPORT int onering_load_plugins(const char* dir);
+
+/* Call a app */
+ONERING_EXPORT onering_response_handle_t onering_call_app(
+ const char* appname,
+ const char* method,
+ const char* body,
+ int body_len,
+ char** response,
+ int* response_len);
+
+/* Release a response */
+ONERING_EXPORT void onering_free_response(
+ const char* appname,
+ onering_response_handle_t response_handle);
+
+/* Subscribe a channel.
+ * When messages are published into this channel, the
+ * app's method will be called, with message as body. The response will be
+ * freed automatically after the calling. */
+ONERING_EXPORT void onering_subscribe(
+ const char* channel,
+ const char* callback_appname,
+ const char* callback_method);
+
+/* Unsubscribe the subscription to a channel */
+ONERING_EXPORT void onering_unsubscribe(
+ const char* channel,
+ const char* callback_appname,
+ const char* callback_method);
+
+/* Publish a message into a channel */
+ONERING_EXPORT void onering_publish(
+ const char* channel,
+ const char* msg);

#ifdef __cplusplus
}
=======================================
--- /qtcore/src/onering.cpp Wed Aug 31 02:54:24 2011
+++ /qtcore/src/onering.cpp Thu Sep 1 23:32:20 2011
@@ -15,6 +15,11 @@
#include "publishevent.h"
#include "cocoainit.h"

+// Implementations of APIs in oneirng.h:
+//
+// onering_register_app() implemented in app.cpp
+//
+
int onering_loop(const char* appname)
{
int argc = 1;
@@ -35,6 +40,33 @@
return retval;
return app.exec();
}
+
+const char* onering_version()
+{
+ return "OneRingQtCore 1.0.0";
+}
+
+int onering_load_plugins(const char* dir)
+{
+ return 0;
+}
+
+onering_response_handle_t onering_call_app(const char* appname, const
char* method, const char* body, int body_len, char** response, int*
response_len)
+{
+ return (onering_response_handle_t)0;
+}
+
+void onering_free_response(const char* appname, onering_response_handle_t
response_handle)
+{
+}
+
+void onering_subscribe(const char* channel, const char* callback_appname,
const char* callback_method)
+{
+}
+
+void onering_unsubscribe(const char* channel, const char*
callback_appname, const char* callback_method)
+{
+}

void onering_publish(const char* channel, const char* msg)
{

==============================================================================
Revision: 56f6d6f2b8d7
Author: Qiangning Hong <hon...@gmail.com>
Date: Thu Sep 1 23:37:57 2011
Log: move onering_load_plugins() implementation to pluginloader.cpp
http://code.google.com/p/onering-desktop/source/detail?r=56f6d6f2b8d7

Modified:
/qtcore/onering.pro
/qtcore/src/onering.cpp

=======================================
--- /qtcore/onering.pro Wed Aug 31 02:54:24 2011
+++ /qtcore/onering.pro Thu Sep 1 23:37:57 2011
@@ -41,7 +41,8 @@
src/oneringview.h \
src/publishevent.h \
src/pubsubhub.h \
- src/systemtrayicon.h
+ src/systemtrayicon.h \
+ src/pluginloader.h

SOURCES += \
src/app.cpp \
@@ -58,7 +59,8 @@
src/oneringview.cpp \
src/publishevent.cpp \
src/pubsubhub.cpp \
- src/systemtrayicon.cpp
+ src/systemtrayicon.cpp \
+ src/pluginloader.cpp

# global shourtcut
HEADERS += \
=======================================
--- /qtcore/src/onering.cpp Thu Sep 1 23:32:20 2011
+++ /qtcore/src/onering.cpp Thu Sep 1 23:37:57 2011
@@ -46,10 +46,7 @@
return "OneRingQtCore 1.0.0";
}

-int onering_load_plugins(const char* dir)
-{
- return 0;
-}
+// onering_load_plugins() implemented in pluginloader.cpp

onering_response_handle_t onering_call_app(const char* appname, const
char* method, const char* body, int body_len, char** response, int*
response_len)
{

==============================================================================
Revision: 9fd7c8d72274
Author: Qiangning Hong <hon...@gmail.com>
Date: Fri Sep 2 00:09:10 2011
Log: add C version of test program
http://code.google.com/p/onering-desktop/source/detail?r=9fd7c8d72274

Added:
/qtcore/test/Makefile
/qtcore/test/test.c
Modified:
/include/onering.h

=======================================
--- /dev/null
+++ /qtcore/test/Makefile Fri Sep 2 00:09:10 2011
@@ -0,0 +1,2 @@
+test: test.c
+ gcc -o test test.c -I ../../include -F.. -framework Onering
=======================================
--- /dev/null
+++ /qtcore/test/test.c Fri Sep 2 00:09:10 2011
@@ -0,0 +1,24 @@
+#include <string.h>
+#include <onering.h>
+
+onering_response_handle_t test_app(const char* appname, const char*
method, const char* path, const char* body, const char** response, int*
response_len)
+{
+ if (strcmp(path, "/init") == 0) {
+ *response = "{\"width\": 400, \"height\": 300, \"url\": \"/\"}";
+ } else {
+ *response = "<html><head><script
src='onering://onering/onering.js'></script></head><body><p>Hello,
World!</p></body></html>";
+ }
+ *response_len = strlen(*response);
+ return (onering_response_handle_t)0;
+}
+
+void free_response(const char* appname, onering_response_handle_t
response_handle)
+{
+}
+
+int main()
+{
+ onering_register_app("test", &test_app, &free_response);
+ onering_loop("test");
+ return 0;
+}
=======================================
--- /include/onering.h Thu Sep 1 23:32:20 2011
+++ /include/onering.h Fri Sep 2 00:09:10 2011
@@ -15,9 +15,18 @@

typedef long onering_response_handle_t;

-typedef onering_response_handle_t (*onering_app_func_t) (const char*
appname, const char* method, const char* path, const char* body,
- /*OUT*/ const char** response, int* response_len);
-typedef void (*onering_free_response_func_t) (const char* appname,
onering_response_handle_t response_handle);
+typedef onering_response_handle_t (*onering_app_func_t) (
+ const char* appname,
+ const char* method,
+ const char* path,
+ const char* body,
+ /*OUT*/
+ const char** response,
+ int* response_len);
+
+typedef void (*onering_free_response_func_t) (
+ const char* appname,
+ onering_response_handle_t response_handle);

/* Register a app with the name appname.
* Register Return -1 means strlen(appname) > MAX_APPNAME_LEN */

==============================================================================
Revision: a94aabc2d153
Author: Qiangning Hong <hon...@gmail.com>
Date: Fri Sep 2 00:33:07 2011
Log: load dll
http://code.google.com/p/onering-desktop/source/detail?r=a94aabc2d153

Added:
/qtcore/src/pluginloader.cpp
/qtcore/src/pluginloader.h
Modified:
/.hgignore
/qtcore/test/Makefile
/qtcore/test/test.c

=======================================
--- /dev/null
+++ /qtcore/src/pluginloader.cpp Fri Sep 2 00:33:07 2011
@@ -0,0 +1,25 @@
+#include <QDir>
+#include <QLibrary>
+#include <QDebug>
+#include <onering.h>
+#include "pluginloader.h"
+
+int onering_load_plugins(const char* dir)
+{
+ int n_loaded_plugins = 0;
+ QDir qdir(dir);
+ QStringList entries = qdir.entryList();
+
+ for (int i = 0; i < entries.size(); ++i) {
+ QString path = qdir.filePath(entries[i]);
+ QLibrary lib(path);
+ if (lib.load()) {
+ n_loaded_plugins += 1;
+ } else {
+ qDebug() << "load plugin" << path << "failed";
+ }
+ }
+
+ return n_loaded_plugins;
+}
+
=======================================
--- /dev/null
+++ /qtcore/src/pluginloader.h Fri Sep 2 00:33:07 2011
@@ -0,0 +1,4 @@
+#ifndef PLUGINLOADER_H
+#define PLUGINLOADER_H
+
+#endif
=======================================
--- /.hgignore Wed Aug 31 02:54:24 2011
+++ /.hgignore Fri Sep 2 00:33:07 2011
@@ -14,3 +14,4 @@
.*\.(so|a|dll|rc)$
object_script\.OneRing\.
.*\.bundle$
+qtcore/test/test$
=======================================
--- /qtcore/test/Makefile Fri Sep 2 00:09:10 2011
+++ /qtcore/test/Makefile Fri Sep 2 00:33:07 2011
@@ -1,2 +1,2 @@
test: test.c
- gcc -o test test.c -I ../../include -F.. -framework Onering
+ gcc -o test test.c -I ../../include -F. -framework Onering
=======================================
--- /qtcore/test/test.c Fri Sep 2 00:09:10 2011
+++ /qtcore/test/test.c Fri Sep 2 00:33:07 2011
@@ -1,4 +1,5 @@
#include <string.h>
+#include <stdio.h>
#include <onering.h>

onering_response_handle_t test_app(const char* appname, const char*
method, const char* path, const char* body, const char** response, int*
response_len)
@@ -18,7 +19,9 @@

int main()
{
+ printf("%s\n", onering_version());
onering_register_app("test", &test_app, &free_response);
- onering_loop("test");
+ printf("load %d plugins\n", onering_load_plugins("plugins"));
+/* onering_loop("test");*/
return 0;
}

==============================================================================
Revision: 4f8ce306ad18
Author: Qiangning Hong <hon...@gmail.com>
Date: Fri Sep 2 00:56:09 2011
Log: c++'ifly
http://code.google.com/p/onering-desktop/source/detail?r=4f8ce306ad18

Modified:
/qtcore/src/onering.cpp
/qtcore/src/pluginloader.cpp
/qtcore/src/pluginloader.h

=======================================
--- /qtcore/src/onering.cpp Thu Sep 1 23:37:57 2011
+++ /qtcore/src/onering.cpp Fri Sep 2 00:56:09 2011
@@ -14,6 +14,7 @@
#include "application.h"
#include "publishevent.h"
#include "cocoainit.h"
+#include "pluginloader.h"

// Implementations of APIs in oneirng.h:
//
@@ -46,7 +47,10 @@
return "OneRingQtCore 1.0.0";
}

-// onering_load_plugins() implemented in pluginloader.cpp
+int onering_load_plugins(const char* dir)
+{
+ return PluginLoader::loadDir(QDir(dir));
+}

onering_response_handle_t onering_call_app(const char* appname, const
char* method, const char* body, int body_len, char** response, int*
response_len)
{
=======================================
--- /qtcore/src/pluginloader.cpp Fri Sep 2 00:33:07 2011
+++ /qtcore/src/pluginloader.cpp Fri Sep 2 00:56:09 2011
@@ -4,16 +4,14 @@
#include <onering.h>
#include "pluginloader.h"

-int onering_load_plugins(const char* dir)
+int PluginLoader::loadDir(const QDir& dir)
{
int n_loaded_plugins = 0;
- QDir qdir(dir);
- QStringList entries = qdir.entryList();
+ QStringList entries = dir.entryList();

for (int i = 0; i < entries.size(); ++i) {
- QString path = qdir.filePath(entries[i]);
- QLibrary lib(path);
- if (lib.load()) {
+ QString path = dir.filePath(entries[i]);
+ if (loadPlugin(path)) {
n_loaded_plugins += 1;
} else {
qDebug() << "load plugin" << path << "failed";
@@ -23,3 +21,8 @@
return n_loaded_plugins;
}

+bool PluginLoader::loadPlugin(const QString& path)
+{
+ QLibrary lib(path);
+ return lib.load();
+}
=======================================
--- /qtcore/src/pluginloader.h Fri Sep 2 00:33:07 2011
+++ /qtcore/src/pluginloader.h Fri Sep 2 00:56:09 2011
@@ -1,4 +1,11 @@
#ifndef PLUGINLOADER_H
#define PLUGINLOADER_H

+class PluginLoader : public QObject
+{
+public:
+ static int loadDir(const QDir& dir);
+ static bool loadPlugin(const QString& path);
+};
+
#endif

==============================================================================
Revision: ececebfd9418
Author: Qiangning Hong <hon...@gmail.com>
Date: Fri Sep 2 02:08:58 2011
Log: scan and load plugins
http://code.google.com/p/onering-desktop/source/detail?r=ececebfd9418

Modified:
/include/onering.h
/qtcore/src/pluginloader.cpp
/qtcore/src/pluginloader.h
/qtcore/test/test.c

=======================================
--- /include/onering.h Fri Sep 2 00:09:10 2011
+++ /include/onering.h Fri Sep 2 02:08:58 2011
@@ -28,6 +28,11 @@
const char* appname,
onering_response_handle_t response_handle);

+/* Functions should be exported from plugins */
+typedef const char* (*require_onering_version_func_t) ();
+typedef const char* (*get_onering_appname_func_t) ();
+typedef int (*register_onering_plugin_func_t) (const char* appname);
+
/* Register a app with the name appname.
* Register Return -1 means strlen(appname) > MAX_APPNAME_LEN */
ONERING_EXPORT int onering_register_app(
=======================================
--- /qtcore/src/pluginloader.cpp Fri Sep 2 00:56:09 2011
+++ /qtcore/src/pluginloader.cpp Fri Sep 2 02:08:58 2011
@@ -10,11 +10,11 @@
QStringList entries = dir.entryList();

for (int i = 0; i < entries.size(); ++i) {
+ if (entries[i] == "." || entries[i] == "..")
+ continue;
QString path = dir.filePath(entries[i]);
if (loadPlugin(path)) {
n_loaded_plugins += 1;
- } else {
- qDebug() << "load plugin" << path << "failed";
}
}

@@ -24,5 +24,75 @@
bool PluginLoader::loadPlugin(const QString& path)
{
QLibrary lib(path);
- return lib.load();
-}
+ if (!lib.load()) {
+ qDebug() << "load plugin" << path << "failed";
+ return false;
+ }
+
+ require_onering_version_func_t require_onering_version =
(require_onering_version_func_t) lib.resolve("require_onering_version");
+ get_onering_appname_func_t get_onering_appname =
(get_onering_appname_func_t) lib.resolve("get_onering_appname");
+ register_onering_plugin_func_t register_onering_plugin =
(register_onering_plugin_func_t) lib.resolve("register_onering_plugin");
+
+ if (!require_onering_version || !get_onering_appname |
| !register_onering_plugin) {
+ qDebug() << path << "is not an onering plugin";
+ lib.unload();
+ return false;
+ }
+
+ const QString required_version = require_onering_version();
+ if (!versionMatch(required_version, onering_version())) {
+ qDebug() << path << "requires" << required_version << ", not me";
+ lib.unload();
+ return false;
+ }
+
+ if (!register_onering_plugin(get_onering_appname())) {
+ qDebug() << path << "register failed";
+ lib.unload();
+ return false;
+ }
+
+ return true;
+}
+
+bool PluginLoader::versionMatch(const QString& pluginRequiredVersion,
const QString& coreVersion)
+{
+ QStringList coreV = coreVersion.split(' ', QString::SkipEmptyParts);
+ if (coreV.size() != 2) {
+ qDebug() << "Core version" << coreVersion << "is invalid";
+ return false;
+ }
+
+ QStringList patterns = pluginRequiredVersion.split('|');
+ for (int i = 0; i < patterns.size(); ++i) {
+ QStringList require = patterns[i].split(' ', QString::SkipEmptyParts);
+ if (require.size() == 2 && require[0] == coreV[0] &&
versionCompare(require[1], coreV[1]) <= 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// compare between versions like "1.0.0" and "0.9".
+int PluginLoader::versionCompare(const QString& v1, const QString& v2)
+{
+ int i1, i2;
+ QStringList l1 = v1.split('.');
+ QStringList l2 = v2.split('.');
+
+ for (int i = 0; ; ++i) {
+ if (i >= l1.size()) {
+ return (i >= l2.size()) ? 0 : -1;
+ } else if (i >= l2.size()) {
+ return 1;
+ }
+
+ i1 = l1[i].toInt();
+ i2 = l2[i].toInt();
+ if (i1 > i2) {
+ return 1;
+ } else if (i1 < i2) {
+ return -1;
+ }
+ }
+}
=======================================
--- /qtcore/src/pluginloader.h Fri Sep 2 00:56:09 2011
+++ /qtcore/src/pluginloader.h Fri Sep 2 02:08:58 2011
@@ -1,11 +1,19 @@
#ifndef PLUGINLOADER_H
#define PLUGINLOADER_H

+#include <QObject>
+#include <QDir>
+#include <QString>
+
class PluginLoader : public QObject
{
public:
static int loadDir(const QDir& dir);
static bool loadPlugin(const QString& path);
+ static bool versionMatch(const QString& pluginRequiredVersion, const
QString& coreVersion);
+
+private:
+ static int versionCompare(const QString& v1, const QString& v2);
};

#endif
=======================================
--- /qtcore/test/test.c Fri Sep 2 00:33:07 2011
+++ /qtcore/test/test.c Fri Sep 2 02:08:58 2011
@@ -19,9 +19,8 @@

int main()
{
- printf("%s\n", onering_version());
- onering_register_app("test", &test_app, &free_response);
printf("load %d plugins\n", onering_load_plugins("plugins"));
+ onering_register_app("test", &test_app, &free_response);
/* onering_loop("test");*/
return 0;
}

==============================================================================
Revision: 925d3d7c4c38
Author: Qiangning Hong <hon...@gmail.com>
Date: Sun Sep 11 02:07:25 2011
Log: refactor onering.h
http://code.google.com/p/onering-desktop/source/detail?r=925d3d7c4c38

Added:
/plugins/hotkey/src/app.cpp
/plugins/hotkey/src/app.h
/plugins/hotkey/src/hotkey.cpp
/plugins/hotkey/src/hotkey.h
/plugins/hotkey/src/qxtglobal.h
/plugins/hotkey/src/qxtglobalshortcut.cpp
/plugins/hotkey/src/qxtglobalshortcut.h
/plugins/hotkey/src/qxtglobalshortcut_mac.cpp
/plugins/hotkey/src/qxtglobalshortcut_p.h
/plugins/hotkey/src/qxtglobalshortcut_win.cpp
/plugins/hotkey/src/qxtglobalshortcut_x11.cpp
Deleted:
/qtcore/src/hotkey.cpp
/qtcore/src/hotkey.h
/qtcore/src/qxtglobal.h
/qtcore/src/qxtglobalshortcut.cpp
/qtcore/src/qxtglobalshortcut.h
/qtcore/src/qxtglobalshortcut_mac.cpp
/qtcore/src/qxtglobalshortcut_p.h
/qtcore/src/qxtglobalshortcut_win.cpp
/qtcore/src/qxtglobalshortcut_x11.cpp
Modified:
/include/onering.h
/qtcore/onering.pro
/qtcore/src/app.cpp
/qtcore/src/app.h
/qtcore/src/application.cpp
/qtcore/src/jsapi.cpp
/qtcore/src/menu.cpp
/qtcore/src/onering.cpp
/qtcore/src/oneringapp.cpp
/qtcore/src/pluginloader.cpp
/qtcore/src/systemtrayicon.cpp
/qtcore/test/test.c

=======================================
--- /dev/null
+++ /plugins/hotkey/src/app.cpp Sun Sep 11 02:07:25 2011
@@ -0,0 +1,158 @@
+#include <QDebug>
+#include <QString>
+#include <QHash>
+#include <QPair>
+#include <QUrl>
+#include <string.h>
+#include <assert.h>
+#include <onering.h>
+#include "app.h"
+#include "json.h"
+
+QHash<QString, QPair<onering_app_func_t, onering_free_response_func_t> >
g_apps;
+
+int onering_register_app(const char* appname, onering_app_func_t app_func,
onering_free_response_func_t free_response_func)
+{
+ if (strlen(appname) > ONERING_MAX_APPNAME_LEN) {
+ return -1;
+ }
+
+ qDebug() << "register app:" << appname;
+ QPair<onering_app_func_t, onering_free_response_func_t> funcs(app_func,
free_response_func);
+ g_apps[appname] = funcs;
+ return 0;
+}
+
+int is_appname_registered(const QString &appname)
+{
+ return g_apps.contains(appname);
+}
+
+QByteArray call_app(const QString &method, const QUrl &url, const QString
&body)
+{
+ QString appname = url.host();
+ const char * response;
+ int response_len;
+ onering_response_handle_t response_handle;
+ QByteArray retval;
+
+ if (is_appname_registered(appname)) {
+ QByteArray surl = url.toString().toUtf8();
+ QByteArray path_query = url.path().toUtf8();
+ if (url.hasQuery()) {
+ path_query += surl.mid(surl.indexOf('?'));
+ }
+
+ response_handle = g_apps[appname].first(qPrintable(appname),
qPrintable(method), path_query, body.toUtf8().constData(), &response,
&response_len);
+ retval.append(response, response_len);
+ // free response
+ g_apps[appname].second(qPrintable(appname), response_handle);
+ }
+
+ return retval;
+}
+
+QByteArray call_app_body(const QString &method, const QUrl &url, const
QString &body)
+{
+ QByteArray response = call_app(method, url, body);
+
+ int index;
+ if ((index = response.indexOf("\r\n")) < 0) {
+ // not header/body seperator found.
+ // consider the whole response is body
+ return response;
+ }
+ QByteArray line = response.left(index);
+ if (line.indexOf("200") < 0) {
+ qDebug() << "error status line:" << line;
+ return "";
+ }
+
+ if ((index = response.indexOf("\r\n\r\n")) < 0) {
+ qDebug() << "Body not found:" << response;
+ return "";
+ }
+ response.remove(0, index+4);
+ return response;
+}
+
+App::App(const QString& appname, QObject* parent)
+ : QObject(parent),
+ appname(appname)
+{
+}
+
+onering_response_handle_t App::processRequest(const char* appname,
+ const char* method, const QString& path, const QByteArray& body,
+ const char** response, int* response_len)
+{
+ Q_UNUSED(appname);
+ Q_UNUSED(method);
+
+ assert(path.startsWith("/"));
+
+ QByteArray* res = new QByteArray();
+
+ QVariantMap param = Json::parse(QString::fromUtf8(body)).toMap();
+ *res = processCall(path.mid(1), param);
+
+ *response = res->constData();
+ *response_len = res->size();
+ return reinterpret_cast<onering_response_handle_t>(res);
+}
+
+void App::freeResponse(const char* appname, onering_response_handle_t
handle)
+{
+ Q_UNUSED(appname);
+
+ delete reinterpret_cast<QByteArray *>(handle);
+}
+
+QString App::generateObjectId(void* obj)
+{
+ return QString::number(reinterpret_cast<unsigned long>(obj), 16);
+}
+
+
+QString App::getId(QObject* obj)
+{
+ connect(obj, SIGNAL(destroyed(QObject*)),
+ this, SLOT(instanceDestroyed(QObject*)),
+ Qt::UniqueConnection);
+ return generateObjectId(obj);
+}
+
+QString App::getId(void* obj)
+{
+ return generateObjectId(obj);
+}
+
+void* App::getInstance(const QString& id)
+{
+ bool ok;
+ return reinterpret_cast<void *>(id.toULong(&ok, 16));
+}
+
+void App::instanceDestroyed(QObject* obj)
+{
+ qDebug() << obj << "deleted";
+}
+
+void App::publishEvent(const QString& type, void* sender, const QString&
event)
+{
+ publishEvent(type, sender, event, "null");
+}
+
+void App::publishEvent(const QString& type, void* sender, const QString&
event, QEvent* e)
+{
+ QString data = QString("{\"event_id\":\"%1\"}").arg(getId(e));
+ publishEvent(type, sender, event, data);
+}
+
+
+void App::publishEvent(const QString& type, void* sender, const QString&
event, const QString& data)
+{
+ onering_publish(qPrintable(QString("%1.%2.%3.%4")
+ .arg(appname, type, getId(sender), event)),
+ qPrintable(data));
+}
=======================================
--- /dev/null
+++ /plugins/hotkey/src/app.h Sun Sep 11 02:07:25 2011
@@ -0,0 +1,46 @@
+#ifndef APP_H
+#define APP_H
+
+#include <onering.h>
+#include <QString>
+#include <QUrl>
+#include <QByteArray>
+#include <QVariantMap>
+#include <QEvent>
+#include <QSet>
+
+int is_appname_registered(const QString &appname);
+
+QByteArray call_app(const QString& method, const QUrl &url, const QString
&body);
+QByteArray call_app_body(const QString &method, const QUrl &url, const
QString &body);
+
+class App : public QObject
+{
+ Q_OBJECT
+
+public:
+ App(const QString& appname, QObject *parent=0);
+
+ onering_response_handle_t processRequest(const char* appname, const char*
method, const QString& path, const QByteArray& body, const char** response,
int* response_len);
+ void freeResponse(const char* appname, onering_response_handle_t
response_handle);
+
+ static QString generateObjectId(void* obj);
+
+private slots:
+ void instanceDestroyed(QObject* obj);
+
+protected:
+ QString getId(QObject* obj);
+ QString getId(void* obj);
+ void* getInstance(const QString& id);
+ void publishEvent(const QString& type, void* sender, const QString&
event);
+ void publishEvent(const QString& type, void* sender, const QString&
event, QEvent* e);
+ void publishEvent(const QString& type, void* sender, const QString&
event, const QString& data);
+
+private:
+ virtual QByteArray processCall(const QString& command, const QVariantMap&
param) = 0;
+
+ QString appname;
+};
+
+#endif
=======================================
--- /dev/null
+++ /plugins/hotkey/src/hotkey.cpp Sun Sep 11 02:07:25 2011
@@ -0,0 +1,72 @@
+#include <QDebug>
+#include <QByteArray>
+#include <onering.h>
+#include "hotkey.h"
+#include "json.h"
+
+ONERING_EXPORT const char* require_onering_version()
+{
+ return "OneRingQtCore 1.0";
+}
+
+ONERING_EXPORT const char* get_onering_appname()
+{
+ return "hotkey";
+}
+
+ONERING_EXPORT int register_onering_plugin(const char* appname)
+{
+ return onering_register_app(appname, &app, &app_free_response);
+}
+
+onering_response_handle_t app(const char* appname, const char* method,
const char* path, const char* body, const char** response, int*
response_len)
+{
+ return HotKeyApp::getApp(appname).processRequest(appname, method, path,
body, response, response_len);
+}
+
+void app_free_response(const char* appname, onering_response_handle_t
response_handle)
+{
+ HotKeyApp::getApp(appname).freeResponse(appname, response_handle);
+}
+
+HotKeyApp::HotKeyApp(const QString& appname)
+ : App(appname)
+{
+}
+
+HotKeyApp& HotKeyApp::getApp(const QString& appname)
+{
+ static HotKeyApp app(appname);
+ return app;
+}
+
+QByteArray HotKeyApp::processCall(const QString& command, const
QVariantMap& param)
+{
+ QxtGlobalShortcut* shortcut;
+
+ if (command == "create") {
+ shortcut = new
QxtGlobalShortcut(QKeySequence(param["shortcut"].toString()));
+ connect(shortcut, SIGNAL(activated()),
+ this, SLOT(activated()));
+ return
QString("{\"type\":\"HotKey\",\"id\":\"%1\"}").arg(getId(shortcut)).toLatin1();
+ }
+
+ shortcut = static_cast<QxtGlobalShortcut
*>(getInstance(param["id"].toString()));
+ if (!shortcut) {
+ return "{\"err\":\"invalid id\"}";
+ }
+
+ if (command == "destroy") {
+ delete shortcut;
+ return "null";
+ }
+
+ return "{\"err\":\"invalid command\"}";
+}
+
+void HotKeyApp::activated()
+{
+ qDebug() << "activated";
+ publishEvent("HotKey", sender(), "activated");
+}
+
=======================================
--- /dev/null
+++ /plugins/hotkey/src/hotkey.h Sun Sep 11 02:07:25 2011
@@ -0,0 +1,25 @@
+#ifndef HOTKEY_H
+#define HOTKEY_H
+
+#include <QByteArray>
+#include <onering.h>
+#include "qxtglobalshortcut.h"
+#include "app.h"
+
+onering_response_handle_t app(const char* appname, const char* method,
const char* path, const char* body, const char** response, int*
response_len);
+void app_free_response(const char* appname, onering_response_handle_t
response);
+
+class HotKeyApp : public App
+{
+public:
+ static HotKeyApp& getApp(const QString& appname);
+ QByteArray processCall(const QString& path, const QVariantMap& param);
+
+private slots:
+ HotKeyApp(const QString& appname);
+ HotKeyApp(HotKeyApp const&);
+ void operator=(HotKeyApp const&);
+
+ void activated();
+};
+#endif
=======================================
--- /dev/null
+++ /plugins/hotkey/src/qxtglobal.h Sun Sep 11 02:07:25 2011
@@ -0,0 +1,207 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtCore module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
+ **
+ ** <http://libqxt.org> <found...@libqxt.org>
+ **
+
****************************************************************************/
+
+#ifndef QXTGLOBAL_H
+#define QXTGLOBAL_H
+
+#include <QtGlobal>
+
+#define QXT_VERSION 0x000700
+#define QXT_VERSION_STR "0.7.0"
+
+//--------------------------global macros------------------------------
+
+#ifndef QXT_NO_MACROS
+
+#endif // QXT_NO_MACROS
+
+//--------------------------export macros------------------------------
+
+#define QXT_DLLEXPORT DO_NOT_USE_THIS_ANYMORE
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_CORE)
+# define QXT_CORE_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_CORE_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_CORE_EXPORT
+#endif // BUILD_QXT_CORE
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_GUI)
+# define QXT_GUI_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_GUI_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_GUI_EXPORT
+#endif // BUILD_QXT_GUI
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_NETWORK)
+# define QXT_NETWORK_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_NETWORK_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_NETWORK_EXPORT
+#endif // BUILD_QXT_NETWORK
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_SQL)
+# define QXT_SQL_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_SQL_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_SQL_EXPORT
+#endif // BUILD_QXT_SQL
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_WEB)
+# define QXT_WEB_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_WEB_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_WEB_EXPORT
+#endif // BUILD_QXT_WEB
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_BERKELEY)
+# define QXT_BERKELEY_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_BERKELEY_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_BERKELEY_EXPORT
+#endif // BUILD_QXT_BERKELEY
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_ZEROCONF)
+# define QXT_ZEROCONF_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_ZEROCONF_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_ZEROCONF_EXPORT
+#endif // QXT_ZEROCONF_EXPORT
+
+#if defined BUILD_QXT_CORE || defined BUILD_QXT_GUI || defined
BUILD_QXT_SQL || defined BUILD_QXT_NETWORK || defined BUILD_QXT_WEB ||
defined BUILD_QXT_BERKELEY || defined BUILD_QXT_ZEROCONF
+# define BUILD_QXT
+#endif
+
+QXT_CORE_EXPORT const char* qxtVersion();
+
+#ifndef QT_BEGIN_NAMESPACE
+#define QT_BEGIN_NAMESPACE
+#endif
+
+#ifndef QT_END_NAMESPACE
+#define QT_END_NAMESPACE
+#endif
+
+#ifndef QT_FORWARD_DECLARE_CLASS
+#define QT_FORWARD_DECLARE_CLASS(Class) class Class;
+#endif
+
+/****************************************************************************
+** This file is derived from code bearing the following notice:
+** The sole author of this file, Adam Higerd, has explicitly disclaimed all
+** copyright interest and protection for the content within. This file has
+** been placed in the public domain according to United States copyright
+** statute and case law. In jurisdictions where this public domain
dedication
+** is not legally recognized, anyone who receives a copy of this file is
+** permitted to use, modify, duplicate, and redistribute this file, in
whole
+** or in part, with no restrictions or conditions. In these jurisdictions,
+** this file shall be copyright (C) 2006-2008 by Adam Higerd.
+****************************************************************************/
+
+#define QXT_DECLARE_PRIVATE(PUB) friend class PUB##Private;
QxtPrivateInterface<PUB, PUB##Private> qxt_d;
+#define QXT_DECLARE_PUBLIC(PUB) friend class PUB;
+#define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this);
+#define QXT_D(PUB) PUB##Private& d = qxt_d()
+#define QXT_P(PUB) PUB& p = qxt_p()
+
+template <typename PUB>
+class QxtPrivate
+{
+public:
+ virtual ~QxtPrivate()
+ {}
+ inline void QXT_setPublic(PUB* pub)
+ {
+ qxt_p_ptr = pub;
+ }
+
+protected:
+ inline PUB& qxt_p()
+ {
+ return *qxt_p_ptr;
+ }
+ inline const PUB& qxt_p() const
+ {
+ return *qxt_p_ptr;
+ }
+
+private:
+ PUB* qxt_p_ptr;
+};
+
+template <typename PUB, typename PVT>
+class QxtPrivateInterface
+{
+ friend class QxtPrivate<PUB>;
+public:
+ QxtPrivateInterface()
+ {
+ pvt = new PVT;
+ }
+ ~QxtPrivateInterface()
+ {
+ delete pvt;
+ }
+
+ inline void setPublic(PUB* pub)
+ {
+ pvt->QXT_setPublic(pub);
+ }
+ inline PVT& operator()()
+ {
+ return *static_cast<PVT*>(pvt);
+ }
+ inline const PVT& operator()() const
+ {
+ return *static_cast<PVT*>(pvt);
+ }
+private:
+ QxtPrivateInterface(const QxtPrivateInterface&) { }
+ QxtPrivateInterface& operator=(const QxtPrivateInterface&) { }
+ QxtPrivate<PUB>* pvt;
+};
+
+#endif // QXT_GLOBAL
=======================================
--- /dev/null
+++ /plugins/hotkey/src/qxtglobalshortcut.cpp Sun Sep 11 02:07:25 2011
@@ -0,0 +1,197 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
+ **
+ ** <http://libqxt.org> <found...@libqxt.org>
+ **
+
****************************************************************************/
+#include "qxtglobalshortcut.h"
+#include "qxtglobalshortcut_p.h"
+#include <QAbstractEventDispatcher>
+#include <QtDebug>
+
+bool QxtGlobalShortcutPrivate::error = false;
+#ifndef Q_WS_MAC
+int QxtGlobalShortcutPrivate::ref = 0;
+QAbstractEventDispatcher::EventFilter
QxtGlobalShortcutPrivate::prevEventFilter = 0;
+#endif // Q_WS_MAC
+QHash<QPair<quint32, quint32>, QxtGlobalShortcut*>
QxtGlobalShortcutPrivate::shortcuts;
+
+QxtGlobalShortcutPrivate::QxtGlobalShortcutPrivate() : enabled(true),
key(Qt::Key(0)), mods(Qt::NoModifier)
+{
+#ifndef Q_WS_MAC
+ if (!ref++)
+ prevEventFilter =
QAbstractEventDispatcher::instance()->setEventFilter(eventFilter);
+#endif // Q_WS_MAC
+}
+
+QxtGlobalShortcutPrivate::~QxtGlobalShortcutPrivate()
+{
+#ifndef Q_WS_MAC
+ if (!--ref)
+
QAbstractEventDispatcher::instance()->setEventFilter(prevEventFilter);
+#endif // Q_WS_MAC
+}
+
+bool QxtGlobalShortcutPrivate::setShortcut(const QKeySequence& shortcut)
+{
+ Qt::KeyboardModifiers allMods = Qt::ShiftModifier |
Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier |
Qt::KeypadModifier | Qt::GroupSwitchModifier;
+ key = shortcut.isEmpty() ? Qt::Key(0) : Qt::Key((shortcut[0] ^
allMods) & shortcut[0]);
+ mods = shortcut.isEmpty() ? Qt::KeyboardModifiers(0) :
Qt::KeyboardModifiers(shortcut[0] & allMods);
+ const quint32 nativeKey = nativeKeycode(key, mods);
+ const quint32 nativeMods = nativeModifiers(mods);
+ const bool res = registerShortcut(nativeKey, nativeMods);
+ shortcuts.insert(qMakePair(nativeKey, nativeMods), &qxt_p());
+ if (!res)
+ qWarning() << "QxtGlobalShortcut failed to register:" <<
QKeySequence(key + mods).toString();
+ return res;
+}
+
+bool QxtGlobalShortcutPrivate::unsetShortcut()
+{
+ const quint32 nativeKey = nativeKeycode(key, mods);
+ const quint32 nativeMods = nativeModifiers(mods);
+ const bool res = unregisterShortcut(nativeKey, nativeMods);
+ shortcuts.remove(qMakePair(nativeKey, nativeMods));
+ if (!res)
+ qWarning() << "QxtGlobalShortcut failed to unregister:" <<
QKeySequence(key + mods).toString();
+ key = Qt::Key(0);
+ mods = Qt::KeyboardModifiers(0);
+ return res;
+}
+
+void QxtGlobalShortcutPrivate::activateShortcut(quint32 nativeKey, quint32
nativeMods)
+{
+ QxtGlobalShortcut* shortcut = shortcuts.value(qMakePair(nativeKey,
nativeMods));
+ if (shortcut && shortcut->isEnabled())
+ emit shortcut->activated();
+}
+
+/*!
+ \class QxtGlobalShortcut
+ \inmodule QxtGui
+ \brief The QxtGlobalShortcut class provides a global shortcut
aka "hotkey".
+
+ A global shortcut triggers even if the application is not active. This
+ makes it easy to implement applications that react to certain shortcuts
+ still if some other application is active or if the application is for
+ example minimized to the system tray.
+
+ Example usage:
+ \code
+ QxtGlobalShortcut* shortcut = new QxtGlobalShortcut(window);
+ connect(shortcut, SIGNAL(activated()), window,
SLOT(toggleVisibility()));
+ shortcut->setShortcut(QKeySequence("Ctrl+Shift+F12"));
+ \endcode
+
+ \bold {Note:} Since Qxt 0.6 QxtGlobalShortcut no more requires
QxtApplication.
+ */
+
+/*!
+ \fn QxtGlobalShortcut::activated()
+
+ This signal is emitted when the user types the shortcut's key sequence.
+
+ \sa shortcut
+ */
+
+/*!
+ Constructs a new QxtGlobalShortcut with \a parent.
+ */
+QxtGlobalShortcut::QxtGlobalShortcut(QObject* parent)
+ : QObject(parent)
+{
+ QXT_INIT_PRIVATE(QxtGlobalShortcut);
+}
+
+/*!
+ Constructs a new QxtGlobalShortcut with \a shortcut and \a parent.
+ */
+QxtGlobalShortcut::QxtGlobalShortcut(const QKeySequence& shortcut,
QObject* parent)
+ : QObject(parent)
+{
+ QXT_INIT_PRIVATE(QxtGlobalShortcut);
+ setShortcut(shortcut);
+}
+
+/*!
+ Destructs the QxtGlobalShortcut.
+ */
+QxtGlobalShortcut::~QxtGlobalShortcut()
+{
+ if (qxt_d().key != 0)
+ qxt_d().unsetShortcut();
+}
+
+/*!
+ \property QxtGlobalShortcut::shortcut
+ \brief the shortcut key sequence
+
+ \bold {Note:} Notice that corresponding key press and release events
are not
+ delivered for registered global shortcuts even if they are disabled.
+ Also, comma separated key sequences are not supported.
+ Only the first part is used:
+
+ \code
+ qxtShortcut->setShortcut(QKeySequence("Ctrl+Alt+A,Ctrl+Alt+B"));
+ Q_ASSERT(qxtShortcut->shortcut() == QKeySequence("Ctrl+Alt+A"));
+ \endcode
+ */
+QKeySequence QxtGlobalShortcut::shortcut() const
+{
+ return QKeySequence(qxt_d().key | qxt_d().mods);
+}
+
+bool QxtGlobalShortcut::setShortcut(const QKeySequence& shortcut)
+{
+ if (qxt_d().key != 0)
+ qxt_d().unsetShortcut();
+ return qxt_d().setShortcut(shortcut);
+}
+
+/*!
+ \property QxtGlobalShortcut::enabled
+ \brief whether the shortcut is enabled
+
+ A disabled shortcut does not get activated.
+
+ The default value is \c true.
+
+ \sa setDisabled()
+ */
+bool QxtGlobalShortcut::isEnabled() const
+{
+ return qxt_d().enabled;
+}
+
+void QxtGlobalShortcut::setEnabled(bool enabled)
+{
+ qxt_d().enabled = enabled;
+}
+
+/*!
+ Sets the shortcut \a disabled.
+
+ \sa enabled
+ */
+void QxtGlobalShortcut::setDisabled(bool disabled)
+{
+ qxt_d().enabled = !disabled;
+}
=======================================
--- /dev/null
+++ /plugins/hotkey/src/qxtglobalshortcut.h Sun Sep 11 02:07:25 2011
@@ -0,0 +1,58 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
+ **
+ ** <http://libqxt.org> <found...@libqxt.org>
+ **
+
****************************************************************************/
+#ifndef QXTGLOBALSHORTCUT_H
+#define QXTGLOBALSHORTCUT_H
+
+#include "qxtglobal.h"
+#include <QObject>
+#include <QKeySequence>
+class QxtGlobalShortcutPrivate;
+
+class QxtGlobalShortcut : public QObject
+{
+ Q_OBJECT
+ QXT_DECLARE_PRIVATE(QxtGlobalShortcut)
+ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
+ Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut)
+
+public:
+ explicit QxtGlobalShortcut(QObject* parent = 0);
+ explicit QxtGlobalShortcut(const QKeySequence& shortcut, QObject*
parent = 0);
+ virtual ~QxtGlobalShortcut();
+
+ QKeySequence shortcut() const;
+ bool setShortcut(const QKeySequence& shortcut);
+
+ bool isEnabled() const;
+
+public Q_SLOTS:
+ void setEnabled(bool enabled = true);
+ void setDisabled(bool disabled = true);
+
+Q_SIGNALS:
+ void activated();
+};
+
+#endif // QXTGLOBALSHORTCUT_H
=======================================
--- /dev/null
+++ /plugins/hotkey/src/qxtglobalshortcut_mac.cpp Sun Sep 11 02:07:25 2011
@@ -0,0 +1,297 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
+ **
+ ** <http://libqxt.org> <found...@libqxt.org>
+ **
+
****************************************************************************/
+#include <Carbon/Carbon.h>
+#include "qxtglobalshortcut_p.h"
+#include <QMap>
+#include <QHash>
+#include <QtDebug>
+#include <QApplication>
+
+typedef QPair<uint, uint> Identifier;
+static QMap<quint32, EventHotKeyRef> keyRefs;
+static QHash<Identifier, quint32> keyIDs;
+static quint32 hotKeySerial = 0;
+static bool qxt_mac_handler_installed = false;
+
+OSStatus qxt_mac_handle_hot_key(EventHandlerCallRef nextHandler, EventRef
event, void* data)
+{
+ Q_UNUSED(nextHandler);
+ Q_UNUSED(data);
+ if (GetEventClass(event) == kEventClassKeyboard && GetEventKind(event)
== kEventHotKeyPressed)
+ {
+ EventHotKeyID keyID;
+ GetEventParameter(event, kEventParamDirectObject,
typeEventHotKeyID, NULL, sizeof(keyID), NULL, &keyID);
+ Identifier id = keyIDs.key(keyID.id);
+ QxtGlobalShortcutPrivate::activateShortcut(id.second, id.first);
+ }
+ return noErr;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers
modifiers)
+{
+ quint32 native = 0;
+ if (modifiers & Qt::ShiftModifier)
+ native |= shiftKeyBit;
+ if (modifiers & Qt::ControlModifier)
+ native |= cmdKey;
+ if (modifiers & Qt::AltModifier)
+ native |= optionKey;
+ if (modifiers & Qt::MetaModifier)
+ native |= controlKey;
+ if (modifiers & Qt::KeypadModifier)
+ native |= kEventKeyModifierNumLockMask;
+ return native;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key,
Qt::KeyboardModifiers modifiers)
+{
+ quint32 INVALID_KEYCODE = 0xff;
+
+ switch (key)
+ {
+ case Qt::Key_A:
+ return kVK_ANSI_A;
+ case Qt::Key_S:
+ return kVK_ANSI_S;
+ case Qt::Key_D:
+ return kVK_ANSI_D;
+ case Qt::Key_F:
+ return kVK_ANSI_F;
+ case Qt::Key_H:
+ return kVK_ANSI_H;
+ case Qt::Key_G:
+ return kVK_ANSI_G;
+ case Qt::Key_Z:
+ return kVK_ANSI_Z;
+ case Qt::Key_X:
+ return kVK_ANSI_X;
+ case Qt::Key_C:
+ return kVK_ANSI_C;
+ case Qt::Key_V:
+ return kVK_ANSI_V;
+ case Qt::Key_B:
+ return kVK_ANSI_B;
+ case Qt::Key_Q:
+ return kVK_ANSI_Q;
+ case Qt::Key_W:
+ return kVK_ANSI_W;
+ case Qt::Key_E:
+ return kVK_ANSI_E;
+ case Qt::Key_R:
+ return kVK_ANSI_R;
+ case Qt::Key_Y:
+ return kVK_ANSI_Y;
+ case Qt::Key_T:
+ return kVK_ANSI_T;
+ case Qt::Key_1:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad1 : kVK_ANSI_1;
+ case Qt::Key_2:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad2 : kVK_ANSI_2;
+ case Qt::Key_3:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad3 : kVK_ANSI_3;
+ case Qt::Key_4:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad4 : kVK_ANSI_4;
+ case Qt::Key_6:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad6 : kVK_ANSI_6;
+ case Qt::Key_5:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad5 : kVK_ANSI_5;
+ case Qt::Key_Equal:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_KeypadEquals :
kVK_ANSI_Equal;
+ case Qt::Key_9:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad9 : kVK_ANSI_9;
+ case Qt::Key_7:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad7 : kVK_ANSI_7;
+ case Qt::Key_Minus:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_KeypadMinus :
kVK_ANSI_Minus;
+ case Qt::Key_8:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad8 : kVK_ANSI_8;
+ case Qt::Key_0:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad0 : kVK_ANSI_0;
+ case Qt::Key_BracketRight:
+ return kVK_ANSI_RightBracket;
+ case Qt::Key_O:
+ return kVK_ANSI_O;
+ case Qt::Key_U:
+ return kVK_ANSI_U;
+ case Qt::Key_BracketLeft:
+ return kVK_ANSI_LeftBracket;
+ case Qt::Key_I:
+ return kVK_ANSI_I;
+ case Qt::Key_P:
+ return kVK_ANSI_P;
+ case Qt::Key_L:
+ return kVK_ANSI_L;
+ case Qt::Key_J:
+ return kVK_ANSI_J;
+ case Qt::Key_QuoteDbl:
+ return kVK_ANSI_Quote;
+ case Qt::Key_K:
+ return kVK_ANSI_K;
+ case Qt::Key_Semicolon:
+ return kVK_ANSI_Semicolon;
+ case Qt::Key_Backslash:
+ return kVK_ANSI_Backslash;
+ case Qt::Key_Comma:
+ return kVK_ANSI_Comma;
+ case Qt::Key_Slash:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_KeypadDivide :
kVK_ANSI_Slash;
+ case Qt::Key_N:
+ return kVK_ANSI_N;
+ case Qt::Key_M:
+ return kVK_ANSI_M;
+ case Qt::Key_Period:
+ return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_KeypadDecimal :
kVK_ANSI_Period;
+ case Qt::Key_Dead_Grave:
+ return kVK_ANSI_Grave;
+ case Qt::Key_Asterisk:
+ return kVK_ANSI_KeypadMultiply;
+ case Qt::Key_Plus:
+ return kVK_ANSI_KeypadPlus;
+ case Qt::Key_Clear:
+ return kVK_ANSI_KeypadClear;
+ case Qt::Key_Return:
+ return kVK_Return;
+ case Qt::Key_Enter:
+ return kVK_ANSI_KeypadEnter;
+ case Qt::Key_Tab:
+ return kVK_Tab;
+ case Qt::Key_Space:
+ return kVK_Space;
+ case Qt::Key_Backspace:
+ return kVK_Delete;
+ case Qt::Key_Escape:
+ return kVK_Escape;
+ case Qt::Key_Control:
+ return kVK_Command;
+ case Qt::Key_Shift:
+ return kVK_Shift;
+ case Qt::Key_CapsLock:
+ return kVK_CapsLock;
+ case Qt::Key_Option:
+ return kVK_Option;
+ case Qt::Key_Meta:
+ return kVK_Control;
+ case Qt::Key_F17:
+ return kVK_F17;
+ case Qt::Key_VolumeUp:
+ return kVK_VolumeUp;
+ case Qt::Key_VolumeDown:
+ return kVK_VolumeDown;
+ case Qt::Key_F18:
+ return kVK_F18;
+ case Qt::Key_F19:
+ return kVK_F19;
+ case Qt::Key_F20:
+ return kVK_F20;
+ case Qt::Key_F5:
+ return kVK_F5;
+ case Qt::Key_F6:
+ return kVK_F6;
+ case Qt::Key_F7:
+ return kVK_F7;
+ case Qt::Key_F3:
+ return kVK_F3;
+ case Qt::Key_F8:
+ return kVK_F8;
+ case Qt::Key_F9:
+ return kVK_F9;
+ case Qt::Key_F11:
+ return kVK_F11;
+ case Qt::Key_F13:
+ return kVK_F13;
+ case Qt::Key_F16:
+ return kVK_F16;
+ case Qt::Key_F14:
+ return kVK_F14;
+ case Qt::Key_F10:
+ return kVK_F10;
+ case Qt::Key_F12:
+ return kVK_F12;
+ case Qt::Key_F15:
+ return kVK_F15;
+ case Qt::Key_Help:
+ return kVK_Help;
+ case Qt::Key_Home:
+ return kVK_Home;
+ case Qt::Key_PageUp:
+ return kVK_PageUp;
+ case Qt::Key_Delete:
+ return kVK_ForwardDelete;
+ case Qt::Key_F4:
+ return kVK_F4;
+ case Qt::Key_End:
+ return kVK_End;
+ case Qt::Key_F2:
+ return kVK_F2;
+ case Qt::Key_PageDown:
+ return kVK_PageDown;
+ case Qt::Key_F1:
+ return kVK_F1;
+ case Qt::Key_Left:
+ return kVK_LeftArrow;
+ case Qt::Key_Right:
+ return kVK_RightArrow;
+ case Qt::Key_Down:
+ return kVK_DownArrow;
+ case Qt::Key_Up:
+ return kVK_UpArrow;
+ default:
+ return INVALID_KEYCODE;
+ }
+}
+
+bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32
nativeMods)
+{
+ if (!qxt_mac_handler_installed)
+ {
+ EventTypeSpec t;
+ t.eventClass = kEventClassKeyboard;
+ t.eventKind = kEventHotKeyPressed;
+ InstallApplicationEventHandler(&qxt_mac_handle_hot_key, 1, &t,
NULL, NULL);
+ }
+
+ EventHotKeyID keyID;
+ keyID.signature = 'cute';
+ keyID.id = ++hotKeySerial;
+
+ EventHotKeyRef ref = 0;
+ bool rv = !RegisterEventHotKey(nativeKey, nativeMods, keyID,
GetApplicationEventTarget(), 0, &ref);
+ if (rv)
+ {
+ keyIDs.insert(Identifier(nativeMods, nativeKey), keyID.id);
+ keyRefs.insert(keyID.id, ref);
+ }
+ return rv;
+}
+
+bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey,
quint32 nativeMods)
+{
+ Identifier id(nativeMods, nativeKey);
+ if (!keyIDs.contains(id)) return false;
+
+ EventHotKeyRef ref = keyRefs.take(keyIDs[id]);
+ keyIDs.remove(id);
+ return !UnregisterEventHotKey(ref);
+}
=======================================
--- /dev/null
+++ /plugins/hotkey/src/qxtglobalshortcut_p.h Sun Sep 11 02:07:25 2011
@@ -0,0 +1,66 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
+ **
+ ** <http://libqxt.org> <found...@libqxt.org>
+ **
+
****************************************************************************/
+#ifndef QXTGLOBALSHORTCUT_P_H
+#define QXTGLOBALSHORTCUT_P_H
+
+#include "qxtglobalshortcut.h"
+#include <QAbstractEventDispatcher>
+#include <QKeySequence>
+#include <QHash>
+
+class QxtGlobalShortcutPrivate : public QxtPrivate<QxtGlobalShortcut>
+{
+public:
+ QXT_DECLARE_PUBLIC(QxtGlobalShortcut)
+ QxtGlobalShortcutPrivate();
+ ~QxtGlobalShortcutPrivate();
+
+ bool enabled;
+ Qt::Key key;
+ Qt::KeyboardModifiers mods;
+
+ bool setShortcut(const QKeySequence& shortcut);
+ bool unsetShortcut();
+
+ static bool error;
+#ifndef Q_WS_MAC
+ static int ref;
+ static QAbstractEventDispatcher::EventFilter prevEventFilter;
+ static bool eventFilter(void* message);
+#endif // Q_WS_MAC
+
+ static void activateShortcut(quint32 nativeKey, quint32 nativeMods);
+
+private:
+ static quint32 nativeKeycode(Qt::Key keycode, Qt::KeyboardModifiers
modifiers=Qt::NoModifier);
+ static quint32 nativeModifiers(Qt::KeyboardModifiers modifiers);
+
+ static bool registerShortcut(quint32 nativeKey, quint32 nativeMods);
+ static bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods);
+
+ static QHash<QPair<quint32, quint32>, QxtGlobalShortcut*> shortcuts;
+};
+
+#endif // QXTGLOBALSHORTCUT_P_H
=======================================
--- /dev/null
+++ /plugins/hotkey/src/qxtglobalshortcut_win.cpp Sun Sep 11 02:07:25 2011
@@ -0,0 +1,233 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
+ **
+ ** <http://libqxt.org> <found...@libqxt.org>
+ **
+
****************************************************************************/
+#include "qxtglobalshortcut_p.h"
+#include <qt_windows.h>
+
+bool QxtGlobalShortcutPrivate::eventFilter(void* message)
+{
+ MSG* msg = static_cast<MSG*>(message);
+ if (msg->message == WM_HOTKEY)
+ {
+ const quint32 keycode = HIWORD(msg->lParam);
+ const quint32 modifiers = LOWORD(msg->lParam);
+ activateShortcut(keycode, modifiers);
+ }
+ return false;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers
modifiers)
+{
+ // MOD_ALT, MOD_CONTROL, (MOD_KEYUP), MOD_SHIFT, MOD_WIN
+ quint32 native = 0;
+ if (modifiers & Qt::ShiftModifier)
+ native |= MOD_SHIFT;
+ if (modifiers & Qt::ControlModifier)
+ native |= MOD_CONTROL;
+ if (modifiers & Qt::AltModifier)
+ native |= MOD_ALT;
+ if (modifiers & Qt::MetaModifier)
+ native |= MOD_WIN;
+ // TODO: resolve these?
+ //if (modifiers & Qt::KeypadModifier)
+ //if (modifiers & Qt::GroupSwitchModifier)
+ return native;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key,
Qt::KeyboardModifiers modifiers)
+{
+ switch (key)
+ {
+ case Qt::Key_Escape:
+ return VK_ESCAPE;
+ case Qt::Key_Tab:
+ case Qt::Key_Backtab:
+ return VK_TAB;
+ case Qt::Key_Backspace:
+ return VK_BACK;
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ return VK_RETURN;
+ case Qt::Key_Insert:
+ return VK_INSERT;
+ case Qt::Key_Delete:
+ return VK_DELETE;
+ case Qt::Key_Pause:
+ return VK_PAUSE;
+ case Qt::Key_Print:
+ return VK_PRINT;
+ case Qt::Key_Clear:
+ return VK_CLEAR;
+ case Qt::Key_Home:
+ return VK_HOME;
+ case Qt::Key_End:
+ return VK_END;
+ case Qt::Key_Left:
+ return VK_LEFT;
+ case Qt::Key_Up:
+ return VK_UP;
+ case Qt::Key_Right:
+ return VK_RIGHT;
+ case Qt::Key_Down:
+ return VK_DOWN;
+ case Qt::Key_PageUp:
+ return VK_PRIOR;
+ case Qt::Key_PageDown:
+ return VK_NEXT;
+ case Qt::Key_F1:
+ return VK_F1;
+ case Qt::Key_F2:
+ return VK_F2;
+ case Qt::Key_F3:
+ return VK_F3;
+ case Qt::Key_F4:
+ return VK_F4;
+ case Qt::Key_F5:
+ return VK_F5;
+ case Qt::Key_F6:
+ return VK_F6;
+ case Qt::Key_F7:
+ return VK_F7;
+ case Qt::Key_F8:
+ return VK_F8;
+ case Qt::Key_F9:
+ return VK_F9;
+ case Qt::Key_F10:
+ return VK_F10;
+ case Qt::Key_F11:
+ return VK_F11;
+ case Qt::Key_F12:
+ return VK_F12;
+ case Qt::Key_F13:
+ return VK_F13;
+ case Qt::Key_F14:
+ return VK_F14;
+ case Qt::Key_F15:
+ return VK_F15;
+ case Qt::Key_F16:
+ return VK_F16;
+ case Qt::Key_F17:
+ return VK_F17;
+ case Qt::Key_F18:
+ return VK_F18;
+ case Qt::Key_F19:
+ return VK_F19;
+ case Qt::Key_F20:
+ return VK_F20;
+ case Qt::Key_F21:
+ return VK_F21;
+ case Qt::Key_F22:
+ return VK_F22;
+ case Qt::Key_F23:
+ return VK_F23;
+ case Qt::Key_F24:
+ return VK_F24;
+ case Qt::Key_Space:
+ return VK_SPACE;
+ case Qt::Key_Asterisk:
+ return VK_MULTIPLY;
+ case Qt::Key_Plus:
+ return VK_ADD;
+ case Qt::Key_Comma:
+ return VK_SEPARATOR;
+ case Qt::Key_Minus:
+ return VK_SUBTRACT;
+ case Qt::Key_Slash:
+ return VK_DIVIDE;
+
+#ifdef VK_MEDIA_NEXT_TRACK
+ case Qt::Key_MediaNext:
+ return VK_MEDIA_NEXT_TRACK;
+ case Qt::Key_MediaPrevious:
+ return VK_MEDIA_PREV_TRACK;
+ case Qt::Key_MediaPlay:
+ return VK_MEDIA_PLAY_PAUSE;
+ case Qt::Key_MediaStop:
+ return VK_MEDIA_STOP;
+ // couldn't find those in VK_*
+ //case Qt::Key_MediaLast:
+ //case Qt::Key_MediaRecord:
+ case Qt::Key_VolumeDown:
+ return VK_VOLUME_DOWN;
+ case Qt::Key_VolumeUp:
+ return VK_VOLUME_UP;
+ case Qt::Key_VolumeMute:
+ return VK_VOLUME_MUTE;
+#endif
+ // numbers
+ case Qt::Key_0:
+ case Qt::Key_1:
+ case Qt::Key_2:
+ case Qt::Key_3:
+ case Qt::Key_4:
+ case Qt::Key_5:
+ case Qt::Key_6:
+ case Qt::Key_7:
+ case Qt::Key_8:
+ case Qt::Key_9:
+ return key;
+
+ // letters
+ case Qt::Key_A:
+ case Qt::Key_B:
+ case Qt::Key_C:
+ case Qt::Key_D:
+ case Qt::Key_E:
+ case Qt::Key_F:
+ case Qt::Key_G:
+ case Qt::Key_H:
+ case Qt::Key_I:
+ case Qt::Key_J:
+ case Qt::Key_K:
+ case Qt::Key_L:
+ case Qt::Key_M:
+ case Qt::Key_N:
+ case Qt::Key_O:
+ case Qt::Key_P:
+ case Qt::Key_Q:
+ case Qt::Key_R:
+ case Qt::Key_S:
+ case Qt::Key_T:
+ case Qt::Key_U:
+ case Qt::Key_V:
+ case Qt::Key_W:
+ case Qt::Key_X:
+ case Qt::Key_Y:
+ case Qt::Key_Z:
+ return key;
+
+ default:
+ return 0;
+ }
+}
+
+bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32
nativeMods)
+{
+ return RegisterHotKey(0, nativeMods ^ nativeKey, nativeMods,
nativeKey);
+}
+
+bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey,
quint32 nativeMods)
+{
+ return UnregisterHotKey(0, nativeMods ^ nativeKey);
+}
=======================================
--- /dev/null
+++ /plugins/hotkey/src/qxtglobalshortcut_x11.cpp Sun Sep 11 02:07:25 2011
@@ -0,0 +1,118 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
+ **
+ ** <http://libqxt.org> <found...@libqxt.org>
+ **
+
****************************************************************************/
+#include "qxtglobalshortcut_p.h"
+#include <QX11Info>
+#include <X11/Xlib.h>
+
+static int (*original_x_errhandler)(Display* display, XErrorEvent* event);
+
+static int qxt_x_errhandler(Display* display, XErrorEvent *event)
+{
+ Q_UNUSED(display);
+ switch (event->error_code)
+ {
+ case BadAccess:
+ case BadValue:
+ case BadWindow:
+ if (event->request_code == 33 /* X_GrabKey */ ||
+ event->request_code == 34 /* X_UngrabKey */)
+ {
+ QxtGlobalShortcutPrivate::error = true;
+ //TODO:
+ //char errstr[256];
+ //XGetErrorText(dpy, err->error_code, errstr, 256);
+ }
+ default:
+ return 0;
+ }
+}
+
+bool QxtGlobalShortcutPrivate::eventFilter(void* message)
+{
+ XEvent* event = static_cast<XEvent*>(message);
+ if (event->type == KeyPress)
+ {
+ XKeyEvent* key = (XKeyEvent*) event;
+ activateShortcut(key->keycode,
+ // Mod1Mask == Alt, Mod4Mask == Meta
+ key->state & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask));
+ }
+ return false;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers
modifiers)
+{
+ // ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask,
Mod4Mask, and Mod5Mask
+ quint32 native = 0;
+ if (modifiers & Qt::ShiftModifier)
+ native |= ShiftMask;
+ if (modifiers & Qt::ControlModifier)
+ native |= ControlMask;
+ if (modifiers & Qt::AltModifier)
+ native |= Mod1Mask;
+ if (modifiers & Qt::MetaModifier)
+ native |= Mod4Mask;
+
+ // TODO: resolve these?
+ //if (modifiers & Qt::MetaModifier)
+ //if (modifiers & Qt::KeypadModifier)
+ //if (modifiers & Qt::GroupSwitchModifier)
+ return native;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key,
Qt::KeyboardModifiers modifiers)
+{
+ Display* display = QX11Info::display();
+ return XKeysymToKeycode(display,
XStringToKeysym(QKeySequence(key).toString().toLatin1().data()));
+}
+
+bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32
nativeMods)
+{
+ Display* display = QX11Info::display();
+ Window window = QX11Info::appRootWindow();
+ Bool owner = True;
+ int pointer = GrabModeAsync;
+ int keyboard = GrabModeAsync;
+ error = false;
+ original_x_errhandler = XSetErrorHandler(qxt_x_errhandler);
+ XGrabKey(display, nativeKey, nativeMods, window, owner, pointer,
keyboard);
+ XGrabKey(display, nativeKey, nativeMods | Mod2Mask, window, owner,
pointer, keyboard); // allow numlock
+ XSync(display, False);
+ XSetErrorHandler(original_x_errhandler);
+ return !error;
+}
+
+bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey,
quint32 nativeMods)
+{
+ Display* display = QX11Info::display();
+ Window window = QX11Info::appRootWindow();
+ error = false;
+ original_x_errhandler = XSetErrorHandler(qxt_x_errhandler);
+ XUngrabKey(display, nativeKey, nativeMods, window);
+ XUngrabKey(display, nativeKey, nativeMods | Mod2Mask, window); //
allow numlock
+ XSync(display, False);
+ XSetErrorHandler(original_x_errhandler);
+ return !error;
+}
=======================================
--- /qtcore/src/hotkey.cpp Wed Aug 31 02:54:24 2011
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <QDebug>
-#include "hotkey.h"
-
-static HotKeyApp* g_app = 0;
-
-HotKeyApp::HotKeyApp(const QString& appname, QObject *parent)
- : App(appname, parent)
-{
-}
-
-QByteArray HotKeyApp::processCall(const QString& command, const
QVariantMap& param)
-{
- QxtGlobalShortcut* shortcut;
- if (command == "create") {
- shortcut = new
QxtGlobalShortcut(QKeySequence(param["shortcut"].toString()));
- connect(shortcut, SIGNAL(activated()),
- this, SLOT(activated()));
- return
QString("{\"type\":\"HotKey\",\"id\":\"%1\"}").arg(getId(shortcut)).toLatin1();
- }
-
- shortcut = static_cast<QxtGlobalShortcut
*>(getInstance(param["id"].toString()));
- if (!shortcut) {
- return "{\"err\":\"invalid id\"}";
- }
-
- if (command == "destroy") {
- delete shortcut;
- return "null";
- }
- return "{\"err\":\"invalid command\"}";
-}
-
-void HotKeyApp::activated()
-{
- qDebug() << "activated";
- publishEvent("HotKey", sender(), "activated");
-}
-
-static onering_response_handle_t app(const char* appname, const char*
method,
- const char* path, const char* body,
- const char** response, int* response_len)
-{
- if (!g_app) {
- g_app = new HotKeyApp(appname);
- }
-
- return g_app->processRequest(appname, method, path, body, response,
response_len);
-}
-
-
-static void app_free_response(const char* appname,
onering_response_handle_t response_handle)
-{
- g_app->freeResponse(appname, response_handle);
-}
-
-void register_hotkey_app(const char* appname)
-{
- onering_register_app(appname, &app, &app_free_response);
-}
=======================================
--- /qtcore/src/hotkey.h Wed Aug 31 02:54:24 2011
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef HOTKEY_H
-#define HOTKEY_H
-
-#include "qxtglobalshortcut.h"
-#include "app.h"
-
-class HotKeyApp : public App
-{
- Q_OBJECT
-
-public:
- HotKeyApp(const QString& appname, QObject *parent=0);
-
-private slots:
- void activated();
-
-private:
- QByteArray processCall(const QString& command, const QVariantMap& param);
-};
-
-void register_hotkey_app(const char* appname);
-
-#endif
=======================================
--- /qtcore/src/qxtglobal.h Wed Aug 31 02:54:24 2011
+++ /dev/null
@@ -1,207 +0,0 @@
-/****************************************************************************
- **
- ** Copyright (C) Qxt Foundation. Some rights reserved.
- **
- ** This file is part of the QxtCore module of the Qxt library.
- **
- ** This library is free software; you can redistribute it and/or modify it
- ** under the terms of the Common Public License, version 1.0, as published
- ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
- ** version 2.1, as published by the Free Software Foundation.
- **
- ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
- ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
- ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
- ** FITNESS FOR A PARTICULAR PURPOSE.
- **
- ** You should have received a copy of the CPL and the LGPL along with this
- ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
- ** included with the source distribution for more information.
- ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
- **
- ** <http://libqxt.org> <found...@libqxt.org>
- **
-
****************************************************************************/
-
-#ifndef QXTGLOBAL_H
-#define QXTGLOBAL_H
-
-#include <QtGlobal>
-
-#define QXT_VERSION 0x000700
-#define QXT_VERSION_STR "0.7.0"
-
-//--------------------------global macros------------------------------
-
-#ifndef QXT_NO_MACROS
-
-#endif // QXT_NO_MACROS
-
-//--------------------------export macros------------------------------
-
-#define QXT_DLLEXPORT DO_NOT_USE_THIS_ANYMORE
-
-#if !defined(QXT_STATIC)
-# if defined(BUILD_QXT_CORE)
-# define QXT_CORE_EXPORT Q_DECL_EXPORT
-# else
-# define QXT_CORE_EXPORT Q_DECL_IMPORT
-# endif
-#else
-# define QXT_CORE_EXPORT
-#endif // BUILD_QXT_CORE
-
-#if !defined(QXT_STATIC)
-# if defined(BUILD_QXT_GUI)
-# define QXT_GUI_EXPORT Q_DECL_EXPORT
-# else
-# define QXT_GUI_EXPORT Q_DECL_IMPORT
-# endif
-#else
-# define QXT_GUI_EXPORT
-#endif // BUILD_QXT_GUI
-
-#if !defined(QXT_STATIC)
-# if defined(BUILD_QXT_NETWORK)
-# define QXT_NETWORK_EXPORT Q_DECL_EXPORT
-# else
-# define QXT_NETWORK_EXPORT Q_DECL_IMPORT
-# endif
-#else
-# define QXT_NETWORK_EXPORT
-#endif // BUILD_QXT_NETWORK
-
-#if !defined(QXT_STATIC)
-# if defined(BUILD_QXT_SQL)
-# define QXT_SQL_EXPORT Q_DECL_EXPORT
-# else
-# define QXT_SQL_EXPORT Q_DECL_IMPORT
-# endif
-#else
-# define QXT_SQL_EXPORT
-#endif // BUILD_QXT_SQL
-
-#if !defined(QXT_STATIC)
-# if defined(BUILD_QXT_WEB)
-# define QXT_WEB_EXPORT Q_DECL_EXPORT
-# else
-# define QXT_WEB_EXPORT Q_DECL_IMPORT
-# endif
-#else
-# define QXT_WEB_EXPORT
-#endif // BUILD_QXT_WEB
-
-#if !defined(QXT_STATIC)
-# if defined(BUILD_QXT_BERKELEY)
-# define QXT_BERKELEY_EXPORT Q_DECL_EXPORT
-# else
-# define QXT_BERKELEY_EXPORT Q_DECL_IMPORT
-# endif
-#else
-# define QXT_BERKELEY_EXPORT
-#endif // BUILD_QXT_BERKELEY
-
-#if !defined(QXT_STATIC)
-# if defined(BUILD_QXT_ZEROCONF)
-# define QXT_ZEROCONF_EXPORT Q_DECL_EXPORT
-# else
-# define QXT_ZEROCONF_EXPORT Q_DECL_IMPORT
-# endif
-#else
-# define QXT_ZEROCONF_EXPORT
-#endif // QXT_ZEROCONF_EXPORT
-
-#if defined BUILD_QXT_CORE || defined BUILD_QXT_GUI || defined
BUILD_QXT_SQL || defined BUILD_QXT_NETWORK || defined BUILD_QXT_WEB ||
defined BUILD_QXT_BERKELEY || defined BUILD_QXT_ZEROCONF
-# define BUILD_QXT
-#endif
-
-QXT_CORE_EXPORT const char* qxtVersion();
-
-#ifndef QT_BEGIN_NAMESPACE
-#define QT_BEGIN_NAMESPACE
-#endif
-
-#ifndef QT_END_NAMESPACE
-#define QT_END_NAMESPACE
-#endif
-
-#ifndef QT_FORWARD_DECLARE_CLASS
-#define QT_FORWARD_DECLARE_CLASS(Class) class Class;
-#endif
-
-/****************************************************************************
-** This file is derived from code bearing the following notice:
-** The sole author of this file, Adam Higerd, has explicitly disclaimed all
-** copyright interest and protection for the content within. This file has
-** been placed in the public domain according to United States copyright
-** statute and case law. In jurisdictions where this public domain
dedication
-** is not legally recognized, anyone who receives a copy of this file is
-** permitted to use, modify, duplicate, and redistribute this file, in
whole
-** or in part, with no restrictions or conditions. In these jurisdictions,
-** this file shall be copyright (C) 2006-2008 by Adam Higerd.
-****************************************************************************/
-
-#define QXT_DECLARE_PRIVATE(PUB) friend class PUB##Private;
QxtPrivateInterface<PUB, PUB##Private> qxt_d;
-#define QXT_DECLARE_PUBLIC(PUB) friend class PUB;
-#define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this);
-#define QXT_D(PUB) PUB##Private& d = qxt_d()
-#define QXT_P(PUB) PUB& p = qxt_p()
-
-template <typename PUB>
-class QxtPrivate
-{
-public:
- virtual ~QxtPrivate()
- {}
- inline void QXT_setPublic(PUB* pub)
- {
- qxt_p_ptr = pub;
- }
-
-protected:
- inline PUB& qxt_p()
- {
- return *qxt_p_ptr;
- }
- inline const PUB& qxt_p() const
- {
- return *qxt_p_ptr;
- }
-
-private:
- PUB* qxt_p_ptr;
-};
-
-template <typename PUB, typename PVT>
-class QxtPrivateInterface
-{
- friend class QxtPrivate<PUB>;
-public:
- QxtPrivateInterface()
- {
- pvt = new PVT;
- }
- ~QxtPrivateInterface()
- {
- delete pvt;
- }
-
- inline void setPublic(PUB* pub)
- {
- pvt->QXT_setPublic(pub);
- }
- inline PVT& operator()()
- {
- return *static_cast<PVT*>(pvt);
- }
- inline const PVT& operator()() const
- {
- return *static_cast<PVT*>(pvt);
- }
-private:
- QxtPrivateInterface(const QxtPrivateInterface&) { }
- QxtPrivateInterface& operator=(const QxtPrivateInterface&) { }
- QxtPrivate<PUB>* pvt;
-};
-
-#endif // QXT_GLOBAL
=======================================
--- /qtcore/src/qxtglobalshortcut.cpp Wed Aug 31 02:54:24 2011
+++ /dev/null
@@ -1,197 +0,0 @@
-/****************************************************************************
- **
- ** Copyright (C) Qxt Foundation. Some rights reserved.
- **
- ** This file is part of the QxtGui module of the Qxt library.
- **
- ** This library is free software; you can redistribute it and/or modify it
- ** under the terms of the Common Public License, version 1.0, as published
- ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
- ** version 2.1, as published by the Free Software Foundation.
- **
- ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
- ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
- ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
- ** FITNESS FOR A PARTICULAR PURPOSE.
- **
- ** You should have received a copy of the CPL and the LGPL along with this
- ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
- ** included with the source distribution for more information.
- ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
- **
- ** <http://libqxt.org> <found...@libqxt.org>
- **
-
****************************************************************************/
-#include "qxtglobalshortcut.h"
-#include "qxtglobalshortcut_p.h"
-#include <QAbstractEventDispatcher>
-#include <QtDebug>
-
-bool QxtGlobalShortcutPrivate::error = false;
-#ifndef Q_WS_MAC
-int QxtGlobalShortcutPrivate::ref = 0;
-QAbstractEventDispatcher::EventFilter
QxtGlobalShortcutPrivate::prevEventFilter = 0;
-#endif // Q_WS_MAC
-QHash<QPair<quint32, quint32>, QxtGlobalShortcut*>
QxtGlobalShortcutPrivate::shortcuts;
-
-QxtGlobalShortcutPrivate::QxtGlobalShortcutPrivate() : enabled(true),
key(Qt::Key(0)), mods(Qt::NoModifier)
-{
-#ifndef Q_WS_MAC
- if (!ref++)
- prevEventFilter =
QAbstractEventDispatcher::instance()->setEventFilter(eventFilter);
-#endif // Q_WS_MAC
-}
-
-QxtGlobalShortcutPrivate::~QxtGlobalShortcutPrivate()
-{
-#ifndef Q_WS_MAC
- if (!--ref)
-
QAbstractEventDispatcher::instance()->setEventFilter(prevEventFilter);
-#endif // Q_WS_MAC
-}
-
-bool QxtGlobalShortcutPrivate::setShortcut(const QKeySequence& shortcut)
-{
- Qt::KeyboardModifiers allMods = Qt::ShiftModifier |
Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier |
Qt::KeypadModifier | Qt::GroupSwitchModifier;
- key = shortcut.isEmpty() ? Qt::Key(0) : Qt::Key((shortcut[0] ^
allMods) & shortcut[0]);
- mods = shortcut.isEmpty() ? Qt::KeyboardModifiers(0) :
Qt::KeyboardModifiers(shortcut[0] & allMods);
- const quint32 nativeKey = nativeKeycode(key, mods);
- const quint32 nativeMods = nativeModifiers(mods);
- const bool res = registerShortcut(nativeKey, nativeMods);
- shortcuts.insert(qMakePair(nativeKey, nativeMods), &qxt_p());
- if (!res)
- qWarning() << "QxtGlobalShortcut failed to register:" <<
QKeySequence(key + mods).toString();
- return res;
-}
-
-bool QxtGlobalShortcutPrivate::unsetShortcut()
-{
- const quint32 nativeKey = nativeKeycode(key, mods);
- const quint32 nativeMods = nativeModifiers(mods);
- const bool res = unregisterShortcut(nativeKey, nativeMods);
- shortcuts.remove(qMakePair(nativeKey, nativeMods));
- if (!res)
- qWarning() << "QxtGlobalShortcut failed to unregister:" <<
QKeySequence(key + mods).toString();
- key = Qt::Key(0);
- mods = Qt::KeyboardModifiers(0);
- return res;
-}
-
-void QxtGlobalShortcutPrivate::activateShortcut(quint32 nativeKey, quint32
nativeMods)
-{
- QxtGlobalShortcut* shortcut = shortcuts.value(qMakePair(nativeKey,
nativeMods));
- if (shortcut && shortcut->isEnabled())
- emit shortcut->activated();
-}
-
-/*!
- \class QxtGlobalShortcut
- \inmodule QxtGui
- \brief The QxtGlobalShortcut class provides a global shortcut
aka "hotkey".
-
- A global shortcut triggers even if the application is not active. This
- makes it easy to implement applications that react to certain shortcuts
- still if some other application is active or if the application is for
- example minimized to the system tray.
-
- Example usage:
- \code
- QxtGlobalShortcut* shortcut = new QxtGlobalShortcut(window);
- connect(shortcut, SIGNAL(activated()), window,
SLOT(toggleVisibility()));
- shortcut->setShortcut(QKeySequence("Ctrl+Shift+F12"));
- \endcode
-
- \bold {Note:} Since Qxt 0.6 QxtGlobalShortcut no more requires
QxtApplication.
- */
-
-/*!
- \fn QxtGlobalShortcut::activated()
-
- This signal is emitted when the user types the shortcut's key sequence.
-
- \sa shortcut
- */
-
-/*!
- Constructs a new QxtGlobalShortcut with \a parent.
- */
-QxtGlobalShortcut::QxtGlobalShortcut(QObject* parent)
- : QObject(parent)
-{
- QXT_INIT_PRIVATE(QxtGlobalShortcut);
-}
-
-/*!
- Constructs a new QxtGlobalShortcut with \a shortcut and \a parent.
- */
-QxtGlobalShortcut::QxtGlobalShortcut(const QKeySequence& shortcut,
QObject* parent)
- : QObject(parent)
-{
- QXT_INIT_PRIVATE(QxtGlobalShortcut);
- setShortcut(shortcut);
-}
-
-/*!
- Destructs the QxtGlobalShortcut.
- */
-QxtGlobalShortcut::~QxtGlobalShortcut()
-{
- if (qxt_d().key != 0)
- qxt_d().unsetShortcut();
-}
-
-/*!
- \property QxtGlobalShortcut::shortcut
- \brief the shortcut key sequence
-
- \bold {Note:} Notice that corresponding key press and release events
are not
- delivered for registered global shortcuts even if they are disabled.
- Also, comma separated key sequences are not supported.
- Only the first part is used:
-
- \code
- qxtShortcut->setShortcut(QKeySequence("Ctrl+Alt+A,Ctrl+Alt+B"));
- Q_ASSERT(qxtShortcut->shortcut() == QKeySequence("Ctrl+Alt+A"));
- \endcode
- */
-QKeySequence QxtGlobalShortcut::shortcut() const
-{
- return QKeySequence(qxt_d().key | qxt_d().mods);
-}
-
-bool QxtGlobalShortcut::setShortcut(const QKeySequence& shortcut)
-{
- if (qxt_d().key != 0)
- qxt_d().unsetShortcut();
- return qxt_d().setShortcut(shortcut);
-}
-
-/*!
- \property QxtGlobalShortcut::enabled
- \brief whether the shortcut is enabled
-
- A disabled shortcut does not get activated.
-
- The default value is \c true.
-
- \sa setDisabled()
- */
-bool QxtGlobalShortcut::isEnabled() const
-{
- return qxt_d().enabled;
-}
-
-void QxtGlobalShortcut::setEnabled(bool enabled)
-{
- qxt_d().enabled = enabled;
-}
-
-/*!
- Sets the shortcut \a disabled.
-
- \sa enabled
- */
-void QxtGlobalShortcut::setDisabled(bool disabled)
-{
- qxt_d().enabled = !disabled;
-}
=======================================
--- /qtcore/src/qxtglobalshortcut.h Wed Aug 31 02:54:24 2011
+++ /dev/null
@@ -1,58 +0,0 @@
-/****************************************************************************
- **
- ** Copyright (C) Qxt Foundation. Some rights reserved.
- **
- ** This file is part of the QxtGui module of the Qxt library.
- **
- ** This library is free software; you can redistribute it and/or modify it
- ** under the terms of the Common Public License, version 1.0, as published
- ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
- ** version 2.1, as published by the Free Software Foundation.
- **
- ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
- ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
- ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
- ** FITNESS FOR A PARTICULAR PURPOSE.
- **
- ** You should have received a copy of the CPL and the LGPL along with this
- ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
- ** included with the source distribution for more information.
- ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
- **
- ** <http://libqxt.org> <found...@libqxt.org>
- **
-
****************************************************************************/
-#ifndef QXTGLOBALSHORTCUT_H
-#define QXTGLOBALSHORTCUT_H
-
-#include "qxtglobal.h"
-#include <QObject>
-#include <QKeySequence>
-class QxtGlobalShortcutPrivate;
-
-class QxtGlobalShortcut : public QObject
-{
- Q_OBJECT
- QXT_DECLARE_PRIVATE(QxtGlobalShortcut)
- Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
- Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut)
-
-public:
- explicit QxtGlobalShortcut(QObject* parent = 0);
- explicit QxtGlobalShortcut(const QKeySequence& shortcut, QObject*
parent = 0);
- virtual ~QxtGlobalShortcut();
-
- QKeySequence shortcut() const;
- bool setShortcut(const QKeySequence& shortcut);
-
- bool isEnabled() const;
-
-public Q_SLOTS:
- void setEnabled(bool enabled = true);
- void setDisabled(bool disabled = true);
-
-Q_SIGNALS:
- void activated();
-};
-
-#endif // QXTGLOBALSHORTCUT_H
=======================================
--- /qtcore/src/qxtglobalshortcut_mac.cpp Wed Aug 31 02:54:24 2011
+++ /dev/null
@@ -1,297 +0,0 @@
-/****************************************************************************
- **
- ** Copyright (C) Qxt Foundation. Some rights reserved.
- **
- ** This file is part of the QxtGui module of the Qxt library.
- **
- ** This library is free software; you can redistribute it and/or modify it
- ** under the terms of the Common Public License, version 1.0, as published
- ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
- ** version 2.1, as published by the Free Software Foundation.
- **
- ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
- ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
- ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
- ** FITNESS FOR A PARTICULAR PURPOSE.
- **
- ** You should have received a copy of the CPL and the LGPL along with this
- ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
- ** included with the source distribution for more information.
- ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
- **
- ** <http://libqxt.org> <found...@libqxt.org>
- **
-
****************************************************************************/
-#include <Carbon/Carbon.h>
-#include "qxtglobalshortcut_p.h"
-#include <QMap>
-#include <QHash>
-#include <QtDebug>
-#include <QApplication>
-
-typedef QPair<uint, uint> Identifier;
-static QMap<quint32, EventHotKeyRef> keyRefs;
-static QHash<Identifier, quint32> keyIDs;
-static quint32 hotKeySerial = 0;
-static bool qxt_mac_handler_installed = false;
-
-OSStatus qxt_mac_handle_hot_key(EventHandlerCallRef nextHandler, EventRef
event, void* data)
-{
- Q_UNUSED(nextHandler);
- Q_UNUSED(data);
- if (GetEventClass(event) == kEventClassKeyboard && GetEventKind(event)
== kEventHotKeyPressed)
- {
- EventHotKeyID keyID;
- GetEventParameter(event, kEventParamDirectObject,
typeEventHotKeyID, NULL, sizeof(keyID), NULL, &keyID);
- Identifier id = keyIDs.key(keyID.id);
- QxtGlobalShortcutPrivate::activateShortcut(id.second, id.first);
- }
- return noErr;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers
modifiers)
-{
- quint32 native = 0;
- if (modifiers & Qt::ShiftModifier)
- native |= shiftKeyBit;
- if (modifiers & Qt::ControlModifier)
- native |= cmdKey;
- if (modifiers & Qt::AltModifier)
- native |= optionKey;
- if (modifiers & Qt::MetaModifier)
- native |= controlKey;
- if (modifiers & Qt::KeypadModifier)
- native |= kEventKeyModifierNumLockMask;
- return native;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key,
Qt::KeyboardModifiers modifiers)
-{
- quint32 INVALID_KEYCODE = 0xff;
-
- switch (key)
- {
- case Qt::Key_A:
- return kVK_ANSI_A;
- case Qt::Key_S:
- return kVK_ANSI_S;
- case Qt::Key_D:
- return kVK_ANSI_D;
- case Qt::Key_F:
- return kVK_ANSI_F;
- case Qt::Key_H:
- return kVK_ANSI_H;
- case Qt::Key_G:
- return kVK_ANSI_G;
- case Qt::Key_Z:
- return kVK_ANSI_Z;
- case Qt::Key_X:
- return kVK_ANSI_X;
- case Qt::Key_C:
- return kVK_ANSI_C;
- case Qt::Key_V:
- return kVK_ANSI_V;
- case Qt::Key_B:
- return kVK_ANSI_B;
- case Qt::Key_Q:
- return kVK_ANSI_Q;
- case Qt::Key_W:
- return kVK_ANSI_W;
- case Qt::Key_E:
- return kVK_ANSI_E;
- case Qt::Key_R:
- return kVK_ANSI_R;
- case Qt::Key_Y:
- return kVK_ANSI_Y;
- case Qt::Key_T:
- return kVK_ANSI_T;
- case Qt::Key_1:
- return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad1 : kVK_ANSI_1;
- case Qt::Key_2:
- return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad2 : kVK_ANSI_2;
- case Qt::Key_3:
- return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad3 : kVK_ANSI_3;
- case Qt::Key_4:
- return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad4 : kVK_ANSI_4;
- case Qt::Key_6:
- return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad6 : kVK_ANSI_6;
- case Qt::Key_5:
- return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad5 : kVK_ANSI_5;
- case Qt::Key_Equal:
- return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_KeypadEquals :
kVK_ANSI_Equal;
- case Qt::Key_9:
- return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad9 : kVK_ANSI_9;
- case Qt::Key_7:
- return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad7 : kVK_ANSI_7;
- case Qt::Key_Minus:
- return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_KeypadMinus :
kVK_ANSI_Minus;
- case Qt::Key_8:
- return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad8 : kVK_ANSI_8;
- case Qt::Key_0:
- return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_Keypad0 : kVK_ANSI_0;
- case Qt::Key_BracketRight:
- return kVK_ANSI_RightBracket;
- case Qt::Key_O:
- return kVK_ANSI_O;
- case Qt::Key_U:
- return kVK_ANSI_U;
- case Qt::Key_BracketLeft:
- return kVK_ANSI_LeftBracket;
- case Qt::Key_I:
- return kVK_ANSI_I;
- case Qt::Key_P:
- return kVK_ANSI_P;
- case Qt::Key_L:
- return kVK_ANSI_L;
- case Qt::Key_J:
- return kVK_ANSI_J;
- case Qt::Key_QuoteDbl:
- return kVK_ANSI_Quote;
- case Qt::Key_K:
- return kVK_ANSI_K;
- case Qt::Key_Semicolon:
- return kVK_ANSI_Semicolon;
- case Qt::Key_Backslash:
- return kVK_ANSI_Backslash;
- case Qt::Key_Comma:
- return kVK_ANSI_Comma;
- case Qt::Key_Slash:
- return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_KeypadDivide :
kVK_ANSI_Slash;
- case Qt::Key_N:
- return kVK_ANSI_N;
- case Qt::Key_M:
- return kVK_ANSI_M;
- case Qt::Key_Period:
- return (modifiers & Qt::KeypadModifier) ? kVK_ANSI_KeypadDecimal :
kVK_ANSI_Period;
- case Qt::Key_Dead_Grave:
- return kVK_ANSI_Grave;
- case Qt::Key_Asterisk:
- return kVK_ANSI_KeypadMultiply;
- case Qt::Key_Plus:
- return kVK_ANSI_KeypadPlus;
- case Qt::Key_Clear:
- return kVK_ANSI_KeypadClear;
- case Qt::Key_Return:
- return kVK_Return;
- case Qt::Key_Enter:
- return kVK_ANSI_KeypadEnter;
- case Qt::Key_Tab:
- return kVK_Tab;
- case Qt::Key_Space:
- return kVK_Space;
- case Qt::Key_Backspace:
- return kVK_Delete;
- case Qt::Key_Escape:
- return kVK_Escape;
- case Qt::Key_Control:
- return kVK_Command;
- case Qt::Key_Shift:
- return kVK_Shift;
- case Qt::Key_CapsLock:
- return kVK_CapsLock;
- case Qt::Key_Option:
- return kVK_Option;
- case Qt::Key_Meta:
- return kVK_Control;
- case Qt::Key_F17:
- return kVK_F17;
- case Qt::Key_VolumeUp:
- return kVK_VolumeUp;
- case Qt::Key_VolumeDown:
- return kVK_VolumeDown;
- case Qt::Key_F18:
- return kVK_F18;
- case Qt::Key_F19:
- return kVK_F19;
- case Qt::Key_F20:
- return kVK_F20;
- case Qt::Key_F5:
- return kVK_F5;
- case Qt::Key_F6:
- return kVK_F6;
- case Qt::Key_F7:
- return kVK_F7;
- case Qt::Key_F3:
- return kVK_F3;
- case Qt::Key_F8:
- return kVK_F8;
- case Qt::Key_F9:
- return kVK_F9;
- case Qt::Key_F11:
- return kVK_F11;
- case Qt::Key_F13:
- return kVK_F13;
- case Qt::Key_F16:
- return kVK_F16;
- case Qt::Key_F14:
- return kVK_F14;
- case Qt::Key_F10:
- return kVK_F10;
- case Qt::Key_F12:
- return kVK_F12;
- case Qt::Key_F15:
- return kVK_F15;
- case Qt::Key_Help:
- return kVK_Help;
- case Qt::Key_Home:
- return kVK_Home;
- case Qt::Key_PageUp:
- return kVK_PageUp;
- case Qt::Key_Delete:
- return kVK_ForwardDelete;
- case Qt::Key_F4:
- return kVK_F4;
- case Qt::Key_End:
- return kVK_End;
- case Qt::Key_F2:
- return kVK_F2;
- case Qt::Key_PageDown:
- return kVK_PageDown;
- case Qt::Key_F1:
- return kVK_F1;
- case Qt::Key_Left:
- return kVK_LeftArrow;
- case Qt::Key_Right:
- return kVK_RightArrow;
- case Qt::Key_Down:
- return kVK_DownArrow;
- case Qt::Key_Up:
- return kVK_UpArrow;
- default:
- return INVALID_KEYCODE;
- }
-}
-
-bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32
nativeMods)
-{
- if (!qxt_mac_handler_installed)
- {
- EventTypeSpec t;
- t.eventClass = kEventClassKeyboard;
- t.eventKind = kEventHotKeyPressed;
- InstallApplicationEventHandler(&qxt_mac_handle_hot_key, 1, &t,
NULL, NULL);
- }
-
- EventHotKeyID keyID;
- keyID.signature = 'cute';
- keyID.id = ++hotKeySerial;
-
- EventHotKeyRef ref = 0;
- bool rv = !RegisterEventHotKey(nativeKey, nativeMods, keyID,
GetApplicationEventTarget(), 0, &ref);
- if (rv)
- {
- keyIDs.insert(Identifier(nativeMods, nativeKey), keyID.id);
- keyRefs.insert(keyID.id, ref);
- }
- return rv;
-}
-
-bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey,
quint32 nativeMods)
-{
- Identifier id(nativeMods, nativeKey);
- if (!keyIDs.contains(id)) return false;
-
- EventHotKeyRef ref = keyRefs.take(keyIDs[id]);
- keyIDs.remove(id);
- return !UnregisterEventHotKey(ref);
-}
=======================================
--- /qtcore/src/qxtglobalshortcut_p.h Wed Aug 31 02:54:24 2011
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
- **
- ** Copyright (C) Qxt Foundation. Some rights reserved.
- **
- ** This file is part of the QxtGui module of the Qxt library.
- **
- ** This library is free software; you can redistribute it and/or modify it
- ** under the terms of the Common Public License, version 1.0, as published
- ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
- ** version 2.1, as published by the Free Software Foundation.
- **
- ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
- ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
- ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
- ** FITNESS FOR A PARTICULAR PURPOSE.
- **
- ** You should have received a copy of the CPL and the LGPL along with this
- ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
- ** included with the source distribution for more information.
- ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
- **
- ** <http://libqxt.org> <found...@libqxt.org>
- **
-
****************************************************************************/
-#ifndef QXTGLOBALSHORTCUT_P_H
-#define QXTGLOBALSHORTCUT_P_H
-
-#include "qxtglobalshortcut.h"
-#include <QAbstractEventDispatcher>
-#include <QKeySequence>
-#include <QHash>
-
-class QxtGlobalShortcutPrivate : public QxtPrivate<QxtGlobalShortcut>
-{
-public:
- QXT_DECLARE_PUBLIC(QxtGlobalShortcut)
- QxtGlobalShortcutPrivate();
- ~QxtGlobalShortcutPrivate();
-
- bool enabled;
- Qt::Key key;
- Qt::KeyboardModifiers mods;
-
- bool setShortcut(const QKeySequence& shortcut);
- bool unsetShortcut();
-
- static bool error;
-#ifndef Q_WS_MAC
- static int ref;
- static QAbstractEventDispatcher::EventFilter prevEventFilter;
- static bool eventFilter(void* message);
-#endif // Q_WS_MAC
-
- static void activateShortcut(quint32 nativeKey, quint32 nativeMods);
-
-private:
- static quint32 nativeKeycode(Qt::Key keycode, Qt::KeyboardModifiers
modifiers=Qt::NoModifier);
- static quint32 nativeModifiers(Qt::KeyboardModifiers modifiers);
-
- static bool registerShortcut(quint32 nativeKey, quint32 nativeMods);
- static bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods);
-
- static QHash<QPair<quint32, quint32>, QxtGlobalShortcut*> shortcuts;
-};
-
-#endif // QXTGLOBALSHORTCUT_P_H
=======================================
--- /qtcore/src/qxtglobalshortcut_win.cpp Wed Aug 31 02:54:24 2011
+++ /dev/null
@@ -1,233 +0,0 @@
-/****************************************************************************
- **
- ** Copyright (C) Qxt Foundation. Some rights reserved.
- **
- ** This file is part of the QxtGui module of the Qxt library.
- **
- ** This library is free software; you can redistribute it and/or modify it
- ** under the terms of the Common Public License, version 1.0, as published
- ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
- ** version 2.1, as published by the Free Software Foundation.
- **
- ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
- ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
- ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
- ** FITNESS FOR A PARTICULAR PURPOSE.
- **
- ** You should have received a copy of the CPL and the LGPL along with this
- ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
- ** included with the source distribution for more information.
- ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
- **
- ** <http://libqxt.org> <found...@libqxt.org>
- **
-
****************************************************************************/
-#include "qxtglobalshortcut_p.h"
-#include <qt_windows.h>
-
-bool QxtGlobalShortcutPrivate::eventFilter(void* message)
-{
- MSG* msg = static_cast<MSG*>(message);
- if (msg->message == WM_HOTKEY)
- {
- const quint32 keycode = HIWORD(msg->lParam);
- const quint32 modifiers = LOWORD(msg->lParam);
- activateShortcut(keycode, modifiers);
- }
- return false;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers
modifiers)
-{
- // MOD_ALT, MOD_CONTROL, (MOD_KEYUP), MOD_SHIFT, MOD_WIN
- quint32 native = 0;
- if (modifiers & Qt::ShiftModifier)
- native |= MOD_SHIFT;
- if (modifiers & Qt::ControlModifier)
- native |= MOD_CONTROL;
- if (modifiers & Qt::AltModifier)
- native |= MOD_ALT;
- if (modifiers & Qt::MetaModifier)
- native |= MOD_WIN;
- // TODO: resolve these?
- //if (modifiers & Qt::KeypadModifier)
- //if (modifiers & Qt::GroupSwitchModifier)
- return native;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key,
Qt::KeyboardModifiers modifiers)
-{
- switch (key)
- {
- case Qt::Key_Escape:
- return VK_ESCAPE;
- case Qt::Key_Tab:
- case Qt::Key_Backtab:
- return VK_TAB;
- case Qt::Key_Backspace:
- return VK_BACK;
- case Qt::Key_Return:
- case Qt::Key_Enter:
- return VK_RETURN;
- case Qt::Key_Insert:
- return VK_INSERT;
- case Qt::Key_Delete:
- return VK_DELETE;
- case Qt::Key_Pause:
- return VK_PAUSE;
- case Qt::Key_Print:
- return VK_PRINT;
- case Qt::Key_Clear:
- return VK_CLEAR;
- case Qt::Key_Home:
- return VK_HOME;
- case Qt::Key_End:
- return VK_END;
- case Qt::Key_Left:
- return VK_LEFT;
- case Qt::Key_Up:
- return VK_UP;
- case Qt::Key_Right:
- return VK_RIGHT;
- case Qt::Key_Down:
- return VK_DOWN;
- case Qt::Key_PageUp:
- return VK_PRIOR;
- case Qt::Key_PageDown:
- return VK_NEXT;
- case Qt::Key_F1:
- return VK_F1;
- case Qt::Key_F2:
- return VK_F2;
- case Qt::Key_F3:
- return VK_F3;
- case Qt::Key_F4:
- return VK_F4;
- case Qt::Key_F5:
- return VK_F5;
- case Qt::Key_F6:
- return VK_F6;
- case Qt::Key_F7:
- return VK_F7;
- case Qt::Key_F8:
- return VK_F8;
- case Qt::Key_F9:
- return VK_F9;
- case Qt::Key_F10:
- return VK_F10;
- case Qt::Key_F11:
- return VK_F11;
- case Qt::Key_F12:
- return VK_F12;
- case Qt::Key_F13:
- return VK_F13;
- case Qt::Key_F14:
- return VK_F14;
- case Qt::Key_F15:
- return VK_F15;
- case Qt::Key_F16:
- return VK_F16;
- case Qt::Key_F17:
- return VK_F17;
- case Qt::Key_F18:
- return VK_F18;
- case Qt::Key_F19:
- return VK_F19;
- case Qt::Key_F20:
- return VK_F20;
- case Qt::Key_F21:
- return VK_F21;
- case Qt::Key_F22:
- return VK_F22;
- case Qt::Key_F23:
- return VK_F23;
- case Qt::Key_F24:
- return VK_F24;
- case Qt::Key_Space:
- return VK_SPACE;
- case Qt::Key_Asterisk:
- return VK_MULTIPLY;
- case Qt::Key_Plus:
- return VK_ADD;
- case Qt::Key_Comma:
- return VK_SEPARATOR;
- case Qt::Key_Minus:
- return VK_SUBTRACT;
- case Qt::Key_Slash:
- return VK_DIVIDE;
-
-#ifdef VK_MEDIA_NEXT_TRACK
- case Qt::Key_MediaNext:
- return VK_MEDIA_NEXT_TRACK;
- case Qt::Key_MediaPrevious:
- return VK_MEDIA_PREV_TRACK;
- case Qt::Key_MediaPlay:
- return VK_MEDIA_PLAY_PAUSE;
- case Qt::Key_MediaStop:
- return VK_MEDIA_STOP;
- // couldn't find those in VK_*
- //case Qt::Key_MediaLast:
- //case Qt::Key_MediaRecord:
- case Qt::Key_VolumeDown:
- return VK_VOLUME_DOWN;
- case Qt::Key_VolumeUp:
- return VK_VOLUME_UP;
- case Qt::Key_VolumeMute:
- return VK_VOLUME_MUTE;
-#endif
- // numbers
- case Qt::Key_0:
- case Qt::Key_1:
- case Qt::Key_2:
- case Qt::Key_3:
- case Qt::Key_4:
- case Qt::Key_5:
- case Qt::Key_6:
- case Qt::Key_7:
- case Qt::Key_8:
- case Qt::Key_9:
- return key;
-
- // letters
- case Qt::Key_A:
- case Qt::Key_B:
- case Qt::Key_C:
- case Qt::Key_D:
- case Qt::Key_E:
- case Qt::Key_F:
- case Qt::Key_G:
- case Qt::Key_H:
- case Qt::Key_I:
- case Qt::Key_J:
- case Qt::Key_K:
- case Qt::Key_L:
- case Qt::Key_M:
- case Qt::Key_N:
- case Qt::Key_O:
- case Qt::Key_P:
- case Qt::Key_Q:
- case Qt::Key_R:
- case Qt::Key_S:
- case Qt::Key_T:
- case Qt::Key_U:
- case Qt::Key_V:
- case Qt::Key_W:
- case Qt::Key_X:
- case Qt::Key_Y:
- case Qt::Key_Z:
- return key;
-
- default:
- return 0;
- }
-}
-
-bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32
nativeMods)
-{
- return RegisterHotKey(0, nativeMods ^ nativeKey, nativeMods,
nativeKey);
-}
-
-bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey,
quint32 nativeMods)
-{
- return UnregisterHotKey(0, nativeMods ^ nativeKey);
-}
=======================================
--- /qtcore/src/qxtglobalshortcut_x11.cpp Wed Aug 31 02:54:24 2011
+++ /dev/null
@@ -1,118 +0,0 @@
-/****************************************************************************
- **
- ** Copyright (C) Qxt Foundation. Some rights reserved.
- **
- ** This file is part of the QxtGui module of the Qxt library.
- **
- ** This library is free software; you can redistribute it and/or modify it
- ** under the terms of the Common Public License, version 1.0, as published
- ** by IBM, and/or under the terms of the GNU Lesser General Public
License,
- ** version 2.1, as published by the Free Software Foundation.
- **
- ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
- ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
- ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
- ** FITNESS FOR A PARTICULAR PURPOSE.
- **
- ** You should have received a copy of the CPL and the LGPL along with this
- ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
- ** included with the source distribution for more information.
- ** If you did not receive a copy of the licenses, contact the Qxt
Foundation.
- **
- ** <http://libqxt.org> <found...@libqxt.org>
- **
-
****************************************************************************/
-#include "qxtglobalshortcut_p.h"
-#include <QX11Info>
-#include <X11/Xlib.h>
-
-static int (*original_x_errhandler)(Display* display, XErrorEvent* event);
-
-static int qxt_x_errhandler(Display* display, XErrorEvent *event)
-{
- Q_UNUSED(display);
- switch (event->error_code)
- {
- case BadAccess:
- case BadValue:
- case BadWindow:
- if (event->request_code == 33 /* X_GrabKey */ ||
- event->request_code == 34 /* X_UngrabKey */)
- {
- QxtGlobalShortcutPrivate::error = true;
- //TODO:
- //char errstr[256];
- //XGetErrorText(dpy, err->error_code, errstr, 256);
- }
- default:
- return 0;
- }
-}
-
-bool QxtGlobalShortcutPrivate::eventFilter(void* message)
-{
- XEvent* event = static_cast<XEvent*>(message);
- if (event->type == KeyPress)
- {
- XKeyEvent* key = (XKeyEvent*) event;
- activateShortcut(key->keycode,
- // Mod1Mask == Alt, Mod4Mask == Meta
- key->state & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask));
- }
- return false;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers
modifiers)
-{
- // ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask,
Mod4Mask, and Mod5Mask
- quint32 native = 0;
- if (modifiers & Qt::ShiftModifier)
- native |= ShiftMask;
- if (modifiers & Qt::ControlModifier)
- native |= ControlMask;
- if (modifiers & Qt::AltModifier)
- native |= Mod1Mask;
- if (modifiers & Qt::MetaModifier)
- native |= Mod4Mask;
-
- // TODO: resolve these?
- //if (modifiers & Qt::MetaModifier)
- //if (modifiers & Qt::KeypadModifier)
- //if (modifiers & Qt::GroupSwitchModifier)
- return native;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key,
Qt::KeyboardModifiers modifiers)
-{
- Display* display = QX11Info::display();
- return XKeysymToKeycode(display,
XStringToKeysym(QKeySequence(key).toString().toLatin1().data()));
-}
-
-bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32
nativeMods)
-{
- Display* display = QX11Info::display();
- Window window = QX11Info::appRootWindow();
- Bool owner = True;
- int pointer = GrabModeAsync;
- int keyboard = GrabModeAsync;
- error = false;
- original_x_errhandler = XSetErrorHandler(qxt_x_errhandler);
- XGrabKey(display, nativeKey, nativeMods, window, owner, pointer,
keyboard);
- XGrabKey(display, nativeKey, nativeMods | Mod2Mask, window, owner,
pointer, keyboard); // allow numlock
- XSync(display, False);
- XSetErrorHandler(original_x_errhandler);
- return !error;
-}
-
-bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey,
quint32 nativeMods)
-{
- Display* display = QX11Info::display();
- Window window = QX11Info::appRootWindow();
- error = false;
- original_x_errhandler = XSetErrorHandler(qxt_x_errhandler);
- XUngrabKey(display, nativeKey, nativeMods, window);
- XUngrabKey(display, nativeKey, nativeMods | Mod2Mask, window); //
allow numlock
- XSync(display, False);
- XSetErrorHandler(original_x_errhandler);
- return !error;
-}
=======================================
--- /include/onering.h Fri Sep 2 02:08:58 2011
+++ /include/onering.h Sun Sep 11 02:07:25 2011
@@ -13,36 +13,6 @@
# define ONERING_EXPORT
#endif

-typedef long onering_response_handle_t;
-
-typedef onering_response_handle_t (*onering_app_func_t) (
- const char* appname,
- const char* method,
- const char* path,
- const char* body,
- /*OUT*/
- const char** response,
- int* response_len);
-
-typedef void (*onering_free_response_func_t) (
- const char* appname,
- onering_response_handle_t response_handle);
-
-/* Functions should be exported from plugins */
-typedef const char* (*require_onering_version_func_t) ();
-typedef const char* (*get_onering_appname_func_t) ();
-typedef int (*register_onering_plugin_func_t) (const char* appname);
-
-/* Register a app with the name appname.
- * Register Return -1 means strlen(appname) > MAX_APPNAME_LEN */
-ONERING_EXPORT int onering_register_app(
- const char* appname,
- onering_app_func_t app_func,
- onering_free_response_func_t free_response_func);
-
-/* Start app */
-ONERING_EXPORT int onering_loop(const char* appname);
-
/* Return the version number of the core.
* e.g. "OneRingQtCore 1.0.0" */
ONERING_EXPORT const char* onering_version();
@@ -51,40 +21,101 @@
* Returns number of loaded plugins. */
ONERING_EXPORT int onering_load_plugins(const char* dir);

+/* Start app */
+ONERING_EXPORT int onering_loop(const char* appname);
+
/* Call a app */
-ONERING_EXPORT onering_response_handle_t onering_call_app(
+typedef void* (*onering_app_func_t) (
const char* appname,
const char* method,
+ const char* path,
const char* body,
int body_len,
- char** response,
+ /*OUT*/
+ const char** response,
int* response_len);
+ONERING_EXPORT void* onering_call_app(
+ const char* appname,
+ const char* method,
+ const char* path,
+ const char* body,
+ int body_len,
+ /*OUT*/
+ const char** response,
+ int* response_len);

/* Release a response */
+typedef void (*onering_free_response_func_t) (
+ const char* appname,
+ void* response_handle);
ONERING_EXPORT void onering_free_response(
const char* appname,
- onering_response_handle_t response_handle);
+ void* response_handle);
+
+/* Register a app with the name appname.
+ * Register Return -1 means strlen(appname) > MAX_APPNAME_LEN */
+typedef int (*onering_register_app_func_t) (
+ const char* appname,
+ onering_app_func_t app_func,
+ onering_free_response_func_t free_response_func);
+ONERING_EXPORT int onering_register_app(
+ const char* appname,
+ onering_app_func_t app_func,
+ onering_free_response_func_t free_response_func);

/* Subscribe a channel.
* When messages are published into this channel, the
* app's method will be called, with message as body. The response will be
* freed automatically after the calling. */
+typedef void (*onering_subscribe_func_t) (
+ const char* channel,
+ const char* callback_appname,
+ const char* callback_method);
ONERING_EXPORT void onering_subscribe(
const char* channel,
const char* callback_appname,
const char* callback_method);

/* Unsubscribe the subscription to a channel */
+typedef void (*onering_unsubscribe_func_t) (
+ const char* channel,
+ const char* callback_appname,
+ const char* callback_method);
ONERING_EXPORT void onering_unsubscribe(
const char* channel,
const char* callback_appname,
const char* callback_method);

/* Publish a message into a channel */
+typedef void (*onering_publish_func_t) (
+ const char* channel,
+ const char* msg);
ONERING_EXPORT void onering_publish(
const char* channel,
const char* msg);

+
+/* Functions should be exported from apps */
+
+typedef struct {
+ onering_app_func_t call_app;
+ onering_free_response_func_t free_response;
+ onering_register_app_func_t register_app;
+ onering_subscribe_func_t subscribe;
+ onering_unsubscribe_func_t unsubscribe;
+ onering_publish_func_t publish;
+} onering_helpers_t;
+
+/* const char* require_onering_version() */
+typedef const char* (*require_onering_version_func_t) ();
+/* const char* get_onering_appname() */
+typedef const char* (*get_onering_appname_func_t) ();
+/* const int register_onering_plugin(const char* appname) */
+typedef int (*register_onering_plugin_func_t) (const char* appname);
+/* void set_onering_helpers(onering_helpers_t* helpers) */
+typedef void (*set_onering_helpers_func_t) (onering_helpers_t* helpers);
+
+
#ifdef __cplusplus
}
#endif
=======================================
--- /qtcore/onering.pro Thu Sep 1 23:37:57 2011
+++ /qtcore/onering.pro Sun Sep 11 02:07:25 2011
@@ -62,27 +62,6 @@
src/systemtrayicon.cpp \
src/pluginloader.cpp

-# global shourtcut
-HEADERS += \
- src/hotkey.h \
- src/qxtglobalshortcut.h \
- src/qxtglobal.h \
- src/qxtglobalshortcut_p.h
-
-SOURCES += \
- src/hotkey.cpp \
- src/qxtglobalshortcut.cpp
-
-macx:SOURCES += src/qxtglobalshortcut_mac.cpp
-win32:SOURCES += src/qxtglobalshortcut_win.cpp
-unix:!macx:SOURCES += src/qxtglobalshortcut_x11.cpp
-macx:LIBS += -framework Carbon
-win32 {
- win32-g++:LIBS += -l user32
- !win32-g++:LIBS += user32.lib
-}
-# end of global shortcut
-
# dock icon click
macx {
HEADERS += \
=======================================
--- /qtcore/src/app.cpp Wed Aug 31 02:54:24 2011
+++ /qtcore/src/app.cpp Sun Sep 11 02:07:25 2011
@@ -33,7 +33,7 @@
QString appname = url.host();
const char * response;
int response_len;
- onering_response_handle_t response_handle;
+ void* response_handle;
QByteArray retval;

if (is_appname_registered(appname)) {
@@ -43,7 +43,8 @@
path_query += surl.mid(surl.indexOf('?'));
}

- response_handle = g_apps[appname].first(qPrintable(appname),
qPrintable(method), path_query, body.toUtf8().constData(), &response,
&response_len);
+ QByteArray qbody = body.toUtf8();
+ response_handle = g_apps[appname].first(qPrintable(appname),
qPrintable(method), path_query, qbody.constData(), qbody.size(), &response,
&response_len);
retval.append(response, response_len);
// free response
g_apps[appname].second(qPrintable(appname), response_handle);
@@ -82,7 +83,7 @@
{
}

-onering_response_handle_t App::processRequest(const char* appname,
+void* App::processRequest(const char* appname,
const char* method, const QString& path, const QByteArray& body,
const char** response, int* response_len)
{
@@ -98,14 +99,14 @@

*response = res->constData();
*response_len = res->size();
- return reinterpret_cast<onering_response_handle_t>(res);
+ return res;
}

-void App::freeResponse(const char* appname, onering_response_handle_t
handle)
+void App::freeResponse(const char* appname, void* handle)
{
Q_UNUSED(appname);

- delete reinterpret_cast<QByteArray *>(handle);
+ delete static_cast<QByteArray*>(handle);
}

QString App::generateObjectId(void* obj)
=======================================
--- /qtcore/src/app.h Wed Aug 31 02:54:24 2011
+++ /qtcore/src/app.h Sun Sep 11 02:07:25 2011
@@ -21,8 +21,8 @@
public:
App(const QString& appname, QObject *parent=0);

- onering_response_handle_t processRequest(const char* appname, const char*
method, const QString& path, const QByteArray& body, const char** response,
int* response_len);
- void freeResponse(const char* appname, onering_response_handle_t
response_handle);
+ void* processRequest(const char* appname, const char* method, const
QString& path, const QByteArray& body, const char** response, int*
response_len);
+ void freeResponse(const char* appname, void* response_handle);

static QString generateObjectId(void* obj);

=======================================
--- /qtcore/src/application.cpp Wed Aug 31 02:54:24 2011
+++ /qtcore/src/application.cpp Sun Sep 11 02:07:25 2011
@@ -19,7 +19,6 @@
// plugins
#include "menu.h"
#include "systemtrayicon.h"
-#include "hotkey.h"

static QUrl getAbsUrl(const QString &url, const QString &appname)
{
@@ -75,7 +74,6 @@
// register plugin apps
register_menu_app("menu");
register_systray_app("systray");
- register_hotkey_app("hotkey");

QUrl initurl;
initurl.setScheme("onering");
=======================================
--- /qtcore/src/jsapi.cpp Wed Aug 31 02:54:24 2011
+++ /qtcore/src/jsapi.cpp Sun Sep 11 02:07:25 2011
@@ -16,7 +16,6 @@
#include "networkaccessmanager.h"
#include "systemtrayicon.h"
#include "menu.h"
-#include "hotkey.h"
#include "debugger.h"
#include "application.h"
// }}}
=======================================
--- /qtcore/src/menu.cpp Wed Aug 31 02:54:24 2011
+++ /qtcore/src/menu.cpp Sun Sep 11 02:07:25 2011
@@ -113,19 +113,19 @@
QString("{\"checked\":%1}").arg(checked ? "true" : "false"));
}

-static onering_response_handle_t menu_app(const char* appname, const char*
method,
- const char* path, const char* body,
+static void* menu_app(const char* appname, const char* method,
+ const char* path, const char* body, int body_len,
const char** response, int* response_len)
{
if (!g_manager) {
g_manager = new MenuApp(appname);
}

- return g_manager->processRequest(appname, method, path, body, response,
response_len);
+ return g_manager->processRequest(appname, method, path, QByteArray(body,
body_len), response, response_len);
}


-static void menu_app_free_response(const char* appname,
onering_response_handle_t response_handle)
+static void menu_app_free_response(const char* appname, void*
response_handle)
{
g_manager->freeResponse(appname, response_handle);
}
=======================================
--- /qtcore/src/onering.cpp Fri Sep 2 00:56:09 2011
+++ /qtcore/src/onering.cpp Sun Sep 11 02:07:25 2011
@@ -52,12 +52,12 @@
return PluginLoader::loadDir(QDir(dir));
}

-onering_response_handle_t onering_call_app(const char* appname, const
char* method, const char* body, int body_len, char** response, int*
response_len)
-{
- return (onering_response_handle_t)0;
+void* onering_call_app(const char* appname, const char* method, const
char* body, int body_len, char** response, int* response_len)
+{
+ return 0;
}

-void onering_free_response(const char* appname, onering_response_handle_t
response_handle)
+void onering_free_response(const char* appname, void* response_handle)
{
}

=======================================
--- /qtcore/src/oneringapp.cpp Wed Aug 31 02:54:24 2011
+++ /qtcore/src/oneringapp.cpp Sun Sep 11 02:07:25 2011
@@ -121,16 +121,16 @@
#endif
#endif

-static onering_response_handle_t app(const char *appname, const char*
method, const char* path, const char* body, const char **response, int
*response_len)
+static void* app(const char *appname, const char* method, const char*
path, const char* body, int body_len, const char **response, int
*response_len)
{
if (!g_app) {
g_app = new OneRingApp(appname);
}

- return g_app->processRequest(appname, method, path, body, response,
response_len);
+ return g_app->processRequest(appname, method, path, QByteArray(body,
body_len), response, response_len);
}

-static void free_response(const char *appname, onering_response_handle_t
response_handle)
+static void free_response(const char *appname, void* response_handle)
{
g_app->freeResponse(appname, response_handle);
}
=======================================
--- /qtcore/src/pluginloader.cpp Fri Sep 2 02:08:58 2011
+++ /qtcore/src/pluginloader.cpp Sun Sep 11 02:07:25 2011
@@ -46,7 +46,7 @@
return false;
}

- if (!register_onering_plugin(get_onering_appname())) {
+ if (register_onering_plugin(get_onering_appname())) {
qDebug() << path << "register failed";
lib.unload();
return false;
=======================================
--- /qtcore/src/systemtrayicon.cpp Wed Aug 31 02:54:24 2011
+++ /qtcore/src/systemtrayicon.cpp Sun Sep 11 02:07:25 2011
@@ -87,19 +87,19 @@
}
}

-static onering_response_handle_t app(const char* appname, const char*
method,
- const char* path, const char* body,
+static void* app(const char* appname, const char* method,
+ const char* path, const char* body, int body_len,
const char** response, int* response_len)
{
if (!g_app) {
g_app = new SystemTrayIconApp(appname);
}

- return g_app->processRequest(appname, method, path, body, response,
response_len);
+ return g_app->processRequest(appname, method, path, QByteArray(body,
body_len), response, response_len);
}


-static void app_free_response(const char* appname,
onering_response_handle_t response_handle)
+static void app_free_response(const char* appname, void* response_handle)
{
g_app->freeResponse(appname, response_handle);
}
=======================================
--- /qtcore/test/test.c Fri Sep 2 02:08:58 2011
+++ /qtcore/test/test.c Sun Sep 11 02:07:25 2011
@@ -2,7 +2,7 @@
#include <stdio.h>
#include <onering.h>

-onering_response_handle_t test_app(const char* appname, const char*
method, const char* path, const char* body, const char** response, int*
response_len)
+void* test_app(const char* appname, const char* method, const char* path,
const char* body, int body_len, const char** response, int* response_len)
{
if (strcmp(path, "/init") == 0) {
*response = "{\"width\": 400, \"height\": 300, \"url\": \"/\"}";
@@ -10,10 +10,10 @@
*response = "<html><head><script
src='onering://onering/onering.js'></script></head><body><p>Hello,
World!</p></body></html>";
}
*response_len = strlen(*response);
- return (onering_response_handle_t)0;
+ return 0;
}

-void free_response(const char* appname, onering_response_handle_t
response_handle)
+void free_response(const char* appname, void* response_handle)
{
}

@@ -21,6 +21,6 @@
{
printf("load %d plugins\n", onering_load_plugins("plugins"));
onering_register_app("test", &test_app, &free_response);
-/* onering_loop("test");*/
+ onering_loop("test");
return 0;
}

==============================================================================
Revision: 50085e4a3460
Author: Qiangning Hong <hon...@gmail.com>
Date: Sun Sep 11 02:13:42 2011
Log: rename from OneRing to OneRingQtCore
http://code.google.com/p/onering-desktop/source/detail?r=50085e4a3460

Added:
/qtcore/qtcore.pro
/qtcore/qtcore.qrc
/qtcore/src/qtcore.cpp
Deleted:
/qtcore/onering.pro
/qtcore/onering.qrc
/qtcore/src/onering.cpp
Modified:
/.hgignore
/qtcore/test/Makefile
/qtcore/test/test.c

=======================================
--- /dev/null
+++ /qtcore/qtcore.pro Sun Sep 11 02:13:42 2011
@@ -0,0 +1,77 @@
+######################################################################
+# Automatically generated by qmake (2.01a) Thu Aug 19 21:40:02 2010
+######################################################################
+
+TEMPLATE = lib
+TARGET = OneRingQtCore
+DEPENDPATH += . ../include src
+INCLUDEPATH += . ../include
+QT += webkit network
+RESOURCES = qtcore.qrc
+CONFIG += shared
+DEFINES += ONERING_LIBRARY
+VERSION = 1
+macx {
+ CONFIG += lib_bundle
+ FRAMEWORK_HEADERS.version = Versions
+ FRAMEWORK_HEADERS.files = ../include/onering.h
+ FRAMEWORK_HEADERS.path = Headers
+ QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS
+ QMAKE_FRAMEWORK_BUNDLE_NAME = OneRingQtCore
+ QMAKE_FRAMEWORK_VERSION = $$VERSION
+}
+
+!release {
+ DEFINES += DEBUG
+}
+
+# Input
+HEADERS += \
+ ../include/onering.h \
+ src/app.h \
+ src/application.h \
+ src/appreply.h \
+ src/dataloader.h \
+ src/debugger.h \
+ src/jsapi.h \
+ src/json.h \
+ src/menu.h \
+ src/networkaccessmanager.h \
+ src/oneringapp.h \
+ src/oneringview.h \
+ src/publishevent.h \
+ src/pubsubhub.h \
+ src/systemtrayicon.h \
+ src/pluginloader.h
+
+SOURCES += \
+ src/app.cpp \
+ src/application.cpp \
+ src/appreply.cpp \
+ src/dataloader.cpp \
+ src/debugger.cpp \
+ src/jsapi.cpp \
+ src/json.cpp \
+ src/menu.cpp \
+ src/networkaccessmanager.cpp \
+ src/qtcore.cpp \
+ src/oneringapp.cpp \
+ src/oneringview.cpp \
+ src/publishevent.cpp \
+ src/pubsubhub.cpp \
+ src/systemtrayicon.cpp \
+ src/pluginloader.cpp
+
+# dock icon click
+macx {
+ HEADERS += \
+ src/cocoainit.h \
+ src/dockiconclick.h
+
+ OBJECTIVE_SOURCES += \
+ src/cocoainit.mm \
+ src/dockiconclick.mm
+
+ LIBS += -framework AppKit
+}
+# end dock icon click
=======================================
--- /dev/null
+++ /qtcore/qtcore.qrc Sun Sep 11 02:13:42 2011
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>js/onering.js</file>
+</qresource>
+</RCC>
=======================================
--- /dev/null
+++ /qtcore/src/qtcore.cpp Sun Sep 11 02:13:42 2011
@@ -0,0 +1,78 @@
+#include <QDesktopServices>
+#include <QDir>
+#include <QDebug>
+#include <QApplication>
+#include <QCoreApplication>
+#include <QWebSettings>
+#include <QWebSecurityOrigin>
+#include <string.h>
+#include <onering.h>
+#include "oneringview.h"
+#include "app.h"
+#include "oneringapp.h"
+#include "dataloader.h"
+#include "application.h"
+#include "publishevent.h"
+#include "cocoainit.h"
+#include "pluginloader.h"
+
+// Implementations of APIs in oneirng.h:
+//
+// onering_register_app() implemented in app.cpp
+//
+
+int onering_loop(const char* appname)
+{
+ int argc = 1;
+ char name[ONERING_MAX_APPNAME_LEN+1];
+ char *argv[] = {name};
+
+ strncpy(name, appname, ONERING_MAX_APPNAME_LEN);
+ name[ONERING_MAX_APPNAME_LEN] = '\0';
+
+#ifdef Q_WS_MAC
+#ifdef QT_MAC_USE_COCOA
+ CocoaInitializer cocoaInitializer;
+#endif
+#endif
+ Application app(argc, argv);
+ int retval = app.load(appname);
+ if (retval)
+ return retval;
+ return app.exec();
+}
+
+const char* onering_version()
+{
+ return "QtCore 1.0.0";
+}
+
+int onering_load_plugins(const char* dir)
+{
+ return PluginLoader::loadDir(QDir(dir));
+}
+
+void* onering_call_app(const char* appname, const char* method, const
char* body, int body_len, char** response, int* response_len)
+{
+ return 0;
+}
+
+void onering_free_response(const char* appname, void* response_handle)
+{
+}
+
+void onering_subscribe(const char* channel, const char* callback_appname,
const char* callback_method)
+{
+}
+
+void onering_unsubscribe(const char* channel, const char*
callback_appname, const char* callback_method)
+{
+}
+
+void onering_publish(const char* channel, const char* msg)
+{
+ Application *app = static_cast<Application *>(qApp);
+ if (app && !app->quiting) {
+ app->pubsubhub.publish(channel, msg);
+ }
+}
=======================================
--- /qtcore/onering.pro Sun Sep 11 02:07:25 2011
+++ /dev/null
@@ -1,77 +0,0 @@
-######################################################################
-# Automatically generated by qmake (2.01a) Thu Aug 19 21:40:02 2010
-######################################################################
-
-TEMPLATE = lib
-TARGET = OneRing
-DEPENDPATH += . ../include src
-INCLUDEPATH += . ../include
-QT += webkit network
-RESOURCES = onering.qrc
-CONFIG += shared
-DEFINES += ONERING_LIBRARY
-VERSION = 1
-macx {
- CONFIG += lib_bundle
- FRAMEWORK_HEADERS.version = Versions
- FRAMEWORK_HEADERS.files = ../include/onering.h
- FRAMEWORK_HEADERS.path = Headers
- QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS
- QMAKE_FRAMEWORK_BUNDLE_NAME = OneRing
- QMAKE_FRAMEWORK_VERSION = $$VERSION
-}
-
-!release {
- DEFINES += DEBUG
-}
-
-# Input
-HEADERS += \
- ../include/onering.h \
- src/app.h \
- src/application.h \
- src/appreply.h \
- src/dataloader.h \
- src/debugger.h \
- src/jsapi.h \
- src/json.h \
- src/menu.h \
- src/networkaccessmanager.h \
- src/oneringapp.h \
- src/oneringview.h \
- src/publishevent.h \
- src/pubsubhub.h \
- src/systemtrayicon.h \
- src/pluginloader.h
-
-SOURCES += \
- src/app.cpp \
- src/application.cpp \
- src/appreply.cpp \
- src/dataloader.cpp \
- src/debugger.cpp \
- src/jsapi.cpp \
- src/json.cpp \
- src/menu.cpp \
- src/networkaccessmanager.cpp \
- src/onering.cpp \
- src/oneringapp.cpp \
- src/oneringview.cpp \
- src/publishevent.cpp \
- src/pubsubhub.cpp \
- src/systemtrayicon.cpp \
- src/pluginloader.cpp
-
-# dock icon click
-macx {
- HEADERS += \
- src/cocoainit.h \
- src/dockiconclick.h
-
- OBJECTIVE_SOURCES += \
- src/cocoainit.mm \
- src/dockiconclick.mm
-
- LIBS += -framework AppKit
-}
-# end dock icon click
=======================================
--- /qtcore/onering.qrc Wed Aug 31 02:54:24 2011
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource>
- <file>js/onering.js</file>
-</qresource>
-</RCC>
=======================================
--- /qtcore/src/onering.cpp Sun Sep 11 02:07:25 2011
+++ /dev/null
@@ -1,78 +0,0 @@
-#include <QDesktopServices>
-#include <QDir>
-#include <QDebug>
-#include <QApplication>
-#include <QCoreApplication>
-#include <QWebSettings>
-#include <QWebSecurityOrigin>
-#include <string.h>
-#include <onering.h>
-#include "oneringview.h"
-#include "app.h"
-#include "oneringapp.h"
-#include "dataloader.h"
-#include "application.h"
-#include "publishevent.h"
-#include "cocoainit.h"
-#include "pluginloader.h"
-
-// Implementations of APIs in oneirng.h:
-//
-// onering_register_app() implemented in app.cpp
-//
-
-int onering_loop(const char* appname)
-{
- int argc = 1;
- char name[ONERING_MAX_APPNAME_LEN+1];
- char *argv[] = {name};
-
- strncpy(name, appname, ONERING_MAX_APPNAME_LEN);
- name[ONERING_MAX_APPNAME_LEN] = '\0';
-
-#ifdef Q_WS_MAC
-#ifdef QT_MAC_USE_COCOA
- CocoaInitializer cocoaInitializer;
-#endif
-#endif
- Application app(argc, argv);
- int retval = app.load(appname);
- if (retval)
- return retval;
- return app.exec();
-}
-
-const char* onering_version()
-{
- return "OneRingQtCore 1.0.0";
-}
-
-int onering_load_plugins(const char* dir)
-{
- return PluginLoader::loadDir(QDir(dir));
-}
-
-void* onering_call_app(const char* appname, const char* method, const
char* body, int body_len, char** response, int* response_len)
-{
- return 0;
-}
-
-void onering_free_response(const char* appname, void* response_handle)
-{
-}
-
-void onering_subscribe(const char* channel, const char* callback_appname,
const char* callback_method)
-{
-}
-
-void onering_unsubscribe(const char* channel, const char*
callback_appname, const char* callback_method)
-{
-}
-
-void onering_publish(const char* channel, const char* msg)
-{
- Application *app = static_cast<Application *>(qApp);
- if (app && !app->quiting) {
- app->pubsubhub.publish(channel, msg);
- }
-}
=======================================
--- /.hgignore Fri Sep 2 00:33:07 2011
+++ /.hgignore Sun Sep 11 02:13:42 2011
@@ -8,9 +8,9 @@
build
dist
Makefile(\.(Debug|Release))?$
-.*OneRing.framework
+.*\.framework
moc_.*.cpp$
-qrc_onering.cpp$
+qrc_.*.cpp$
.*\.(so|a|dll|rc)$
object_script\.OneRing\.
.*\.bundle$
=======================================
--- /qtcore/test/Makefile Fri Sep 2 00:33:07 2011
+++ /qtcore/test/Makefile Sun Sep 11 02:13:42 2011
@@ -1,2 +1,2 @@
test: test.c
- gcc -o test test.c -I ../../include -F. -framework Onering
+ gcc -o test test.c -I ../../include -F.. -framework OneringQtCore
=======================================
--- /qtcore/test/test.c Sun Sep 11 02:07:25 2011
+++ /qtcore/test/test.c Sun Sep 11 02:13:42 2011
@@ -21,6 +21,6 @@
{
printf("load %d plugins\n", onering_load_plugins("plugins"));
onering_register_app("test", &test_app, &free_response);
- onering_loop("test");
+ //onering_loop("test");
return 0;
}

==============================================================================
Revision: d2a182b904b1
Author: Qiangning Hong <hon...@gmail.com>
Date: Mon Sep 12 19:47:12 2011
Log: plugin ok
http://code.google.com/p/onering-desktop/source/detail?r=d2a182b904b1

Added:
/qtcore/test/testplugin.c
/qtcore/test/testplugin2.c
Modified:
/include/onering.h
/plugins/hotkey/src/app.h
/qtcore/src/app.cpp
/qtcore/src/app.h
/qtcore/src/pluginloader.cpp
/qtcore/src/qtcore.cpp
/qtcore/test/Makefile
/qtcore/test/test.c

=======================================
--- /dev/null
+++ /qtcore/test/testplugin.c Mon Sep 12 19:47:12 2011
@@ -0,0 +1,39 @@
+#include <string.h>
+#include <onering.h>
+
+onering_helpers_t* h = NULL;
+
+ONERING_EXPORT const char* require_onering_version()
+{
+ return "QtCore 1.0";
+}
+
+ONERING_EXPORT const char* get_onering_appname()
+{
+ return "testplugin";
+}
+
+void* app(const char* appname, const char* method, const char* path, const
char* body, int body_len, const char**response, int* response_len)
+{
+ *response = "Hello Test Plugin";
+ *response_len = strlen(*response);
+ return 0;
+}
+
+void free_response(const char* appname, void* handler)
+{
+}
+
+ONERING_EXPORT int register_onering_plugin(const char* appname)
+{
+ if (!h) {
+ return -2;
+ }
+
+ return h->register_app(appname, &app, &free_response);
+}
+
+ONERING_EXPORT void set_onering_helpers(onering_helpers_t* helpers)
+{
+ h = helpers;
+}
=======================================
--- /dev/null
+++ /qtcore/test/testplugin2.c Mon Sep 12 19:47:12 2011
@@ -0,0 +1,39 @@
+#include <string.h>
+#include <onering.h>
+
+onering_helpers_t* h = NULL;
+
+ONERING_EXPORT const char* require_onering_version()
+{
+ return "QtCore 1.0";
+}
+
+ONERING_EXPORT const char* get_onering_appname()
+{
+ return "testplugin2";
+}
+
+void* app(const char* appname, const char* method, const char* path, const
char* body, int body_len, const char**response, int* response_len)
+{
+ *response = "Hello Test Plugin 2";
+ *response_len = strlen(*response);
+ return 0;
+}
+
+void free_response(const char* appname, void* handler)
+{
+}
+
+ONERING_EXPORT int register_onering_plugin(const char* appname)
+{
+ if (!h) {
+ return -2;
+ }
+
+ return h->register_app(appname, &app, &free_response);
+}
+
+ONERING_EXPORT void set_onering_helpers(onering_helpers_t* helpers)
+{
+ h = helpers;
+}
=======================================
--- /include/onering.h Sun Sep 11 02:07:25 2011
+++ /include/onering.h Mon Sep 12 19:47:12 2011
@@ -53,7 +53,7 @@
void* response_handle);

/* Register a app with the name appname.
- * Register Return -1 means strlen(appname) > MAX_APPNAME_LEN */
+ * Returns non-zero if registration failed. */
typedef int (*onering_register_app_func_t) (
const char* appname,
onering_app_func_t app_func,
@@ -110,7 +110,7 @@
typedef const char* (*require_onering_version_func_t) ();
/* const char* get_onering_appname() */
typedef const char* (*get_onering_appname_func_t) ();
-/* const int register_onering_plugin(const char* appname) */
+/* int register_onering_plugin(const char* appname) */
typedef int (*register_onering_plugin_func_t) (const char* appname);
/* void set_onering_helpers(onering_helpers_t* helpers) */
typedef void (*set_onering_helpers_func_t) (onering_helpers_t* helpers);
=======================================
--- /plugins/hotkey/src/app.h Sun Sep 11 02:07:25 2011
+++ /plugins/hotkey/src/app.h Mon Sep 12 19:47:12 2011
@@ -21,8 +21,8 @@
public:
App(const QString& appname, QObject *parent=0);

- onering_response_handle_t processRequest(const char* appname, const char*
method, const QString& path, const QByteArray& body, const char** response,
int* response_len);
- void freeResponse(const char* appname, onering_response_handle_t
response_handle);
+ void* processRequest(const char* appname, const char* method, const
QString& path, const QByteArray& body, const char** response, int*
response_len);
+ void freeResponse(const char* appname, void* response_handle);

static QString generateObjectId(void* obj);

=======================================
--- /qtcore/src/app.cpp Sun Sep 11 02:07:25 2011
+++ /qtcore/src/app.cpp Mon Sep 12 19:47:12 2011
@@ -27,6 +27,17 @@
{
return g_apps.contains(appname);
}
+
+int get_app(const char* appname, onering_app_func_t* app,
onering_free_response_func_t* free_respnose)
+{
+ if (!is_appname_registered(appname)) {
+ return -1;
+ }
+
+ *app = g_apps[appname].first;
+ *free_respnose = g_apps[appname].second;
+ return 0;
+}

QByteArray call_app(const QString &method, const QUrl &url, const QString
&body)
{
=======================================
--- /qtcore/src/app.h Sun Sep 11 02:07:25 2011
+++ /qtcore/src/app.h Mon Sep 12 19:47:12 2011
@@ -10,6 +10,7 @@
#include <QSet>

int is_appname_registered(const QString &appname);
+int get_app(const char* appname, onering_app_func_t* app,
onering_free_response_func_t* free_respnose);

QByteArray call_app(const QString& method, const QUrl &url, const QString
&body);
QByteArray call_app_body(const QString &method, const QUrl &url, const
QString &body);
=======================================
--- /qtcore/src/pluginloader.cpp Sun Sep 11 02:07:25 2011
+++ /qtcore/src/pluginloader.cpp Mon Sep 12 19:47:12 2011
@@ -32,8 +32,9 @@
require_onering_version_func_t require_onering_version =
(require_onering_version_func_t) lib.resolve("require_onering_version");
get_onering_appname_func_t get_onering_appname =
(get_onering_appname_func_t) lib.resolve("get_onering_appname");
register_onering_plugin_func_t register_onering_plugin =
(register_onering_plugin_func_t) lib.resolve("register_onering_plugin");
-
- if (!require_onering_version || !get_onering_appname |
| !register_onering_plugin) {
+ set_onering_helpers_func_t set_onering_helpers =
(set_onering_helpers_func_t) lib.resolve("set_onering_helpers");
+
+ if (!require_onering_version || !get_onering_appname |
| !register_onering_plugin || !set_onering_helpers) {
qDebug() << path << "is not an onering plugin";
lib.unload();
return false;
@@ -46,8 +47,18 @@
return false;
}

- if (register_onering_plugin(get_onering_appname())) {
- qDebug() << path << "register failed";
+ static onering_helpers_t helpers = {
+ onering_call_app,
+ onering_free_response,
+ onering_register_app,
+ onering_subscribe,
+ onering_unsubscribe,
+ onering_publish,
+ };
+ set_onering_helpers(&helpers);
+
+ if (int ret = register_onering_plugin(get_onering_appname())) {
+ qDebug() << path << "register failed:" << ret;
lib.unload();
return false;
}
=======================================
--- /qtcore/src/qtcore.cpp Sun Sep 11 02:13:42 2011
+++ /qtcore/src/qtcore.cpp Mon Sep 12 19:47:12 2011
@@ -52,13 +52,30 @@
return PluginLoader::loadDir(QDir(dir));
}

-void* onering_call_app(const char* appname, const char* method, const
char* body, int body_len, char** response, int* response_len)
-{
- return 0;
+void* onering_call_app(const char* appname, const char* method, const
char* path, const char* body, int body_len, const char** response, int*
response_len)
+{
+ onering_app_func_t app;
+ onering_free_response_func_t free_response;
+
+ if (get_app(appname, &app, &free_response)) {
+ *response = "404 Not Found";
+ *response_len = strlen(*response);
+ return NULL;
+ }
+
+ return app(appname, method, path, body, body_len, response, response_len);
}

void onering_free_response(const char* appname, void* response_handle)
{
+ onering_app_func_t app;
+ onering_free_response_func_t free_response;
+
+ if (get_app(appname, &app, &free_response)) {
+ return;
+ }
+
+ free_response(appname, response_handle);
}

void onering_subscribe(const char* channel, const char* callback_appname,
const char* callback_method)
=======================================
--- /qtcore/test/Makefile Sun Sep 11 02:13:42 2011
+++ /qtcore/test/Makefile Mon Sep 12 19:47:12 2011
@@ -1,2 +1,17 @@
+all: test plugin
+
test: test.c
- gcc -o test test.c -I ../../include -F.. -framework OneringQtCore
+ gcc -o test $^ -I ../../include -F.. -framework OneringQtCore
+
+plugin: testplugin.so testplugin2.so
+
+testplugin.so: testplugin.c
+ gcc -o testplugin.so $^ -I ../../include -shared
+ cp testplugin.so plugins
+
+testplugin2.so: testplugin2.c
+ gcc -o testplugin2.so $^ -I ../../include -shared
+ cp testplugin2.so plugins
+
+clean:
+ rm test testplugin.so testplugin2.so
=======================================
--- /qtcore/test/test.c Sun Sep 11 02:13:42 2011
+++ /qtcore/test/test.c Mon Sep 12 19:47:12 2011
@@ -21,6 +21,20 @@
{
printf("load %d plugins\n", onering_load_plugins("plugins"));
onering_register_app("test", &test_app, &free_response);
- //onering_loop("test");
+
+ const char* response;
+ int response_len;
+ void* handler;
+
+ printf("GET onering://testplugin/ ->\n");
+ onering_call_app("testplugin", "GET", "/", NULL, 0, &response,
&response_len);
+ printf("%s\n", response);
+ onering_free_response("testplugin", handler);
+
+ printf("GET onering://testplugin2/ ->\n");
+ handler = onering_call_app("testplugin2", "GET", "/", NULL, 0, &response,
&response_len);
+ printf("%s\n", response);
+ onering_free_response("testplugin2", handler);
+
return 0;
}

Reply all
Reply to author
Forward
0 new messages