--- /dev/null
+GTKCFLAGS := $(shell pkg-config gtk+-2.0 --cflags)
+GTKLIBS := $(shell pkg-config gtk+-2.0 --libs)
+
+DBUSCFLAGS := $(shell pkg-config dbus-1 --cflags)
+DBUSLIBS := $(shell pkg-config dbus-1 --libs)
+
+CXXFLAGS=-Wall -MMD $(GTKCFLAGS) $(DBUSCFLAGS)
+#LDFLAGS = -module -avoid-version
+LDFLAGS = -shared
+LIBS = -lstdc++
+
+TARGET=libsimple-launcher.so
+
+all: $(TARGET) test
+
+$(TARGET): simple-launcher.o launcher-item.o
+ $(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+test: test.o launcher-item.o
+ g++ -o $@ $^ $(LIBS) $(GTKLIBS) $(DBUSLIBS)
+
+clean:
+ rm -f *.d *.o $(TARGET) test
+
+install: $(TARGET)
+ install -d $(DESTDIR)/usr/share/applications/hildon-home
+ install -m 0644 simple-launcher.desktop $(DESTDIR)/usr/share/applications/hildon-home
+
+-include *.d
--- /dev/null
+#include <string>
+
+#include <glib/gmem.h>
+#include <glib/gkeyfile.h>
+
+#include <gtk/gtkicontheme.h>
+
+#include "launcher-item.h"
+
+static const char *DESKTOP_ENTRY_GROUP = "Desktop Entry",
+ *DESKTOP_ENTRY_TYPE_FIELD = "Type",
+ *DESKTOP_ENTRY_ICON_FIELD = "Icon",
+ *DESKTOP_ENTRY_NAME_FIELD = "Name",
+ *DESKTOP_ENTRY_COMMENT_FIELD = "Comment",
+ *DESKTOP_ENTRY_SERVICE_FIELD = "X-Osso-Service";
+
+inline std::string getStringWrapper(GKeyFile *keyFile, const gchar *group, const gchar *itemName) {
+ gchar *tempo = g_key_file_get_string(keyFile, group, itemName, 0);
+ std::string result;
+
+ if (tempo != 0) {
+ result = tempo;
+
+ g_free(tempo);
+ }
+
+ return result;
+}
+
+inline std::string getLocaleStringWrapper(GKeyFile *keyFile, const gchar *group, const gchar *itemName) {
+ gchar *tempo = g_key_file_get_locale_string(keyFile, group, itemName, 0, 0);
+ std::string result;
+
+ if (tempo != 0) {
+ result = tempo;
+
+ g_free(tempo);
+ }
+
+ return result;
+}
+
+LauncherItem::LauncherItem() {
+}
+
+LauncherItem::~LauncherItem() {
+}
+
+bool LauncherItem::load(const std::string& filename) {
+ GKeyFile *key_file = 0;
+ GError *error = 0;
+
+ for (;;) {
+ if ((key_file = g_key_file_new()) == 0) {
+ break;
+ }
+
+ if (!g_key_file_load_from_file(key_file, filename.c_str(), G_KEY_FILE_NONE, &error)) {
+ break;
+ }
+
+ if (getStringWrapper(key_file, DESKTOP_ENTRY_GROUP, DESKTOP_ENTRY_TYPE_FIELD) != "Application") {
+ break;
+ }
+
+ myName = getStringWrapper(key_file, DESKTOP_ENTRY_GROUP, DESKTOP_ENTRY_NAME_FIELD);
+ myComment = getLocaleStringWrapper(key_file, DESKTOP_ENTRY_GROUP, DESKTOP_ENTRY_COMMENT_FIELD);
+ myIcon = getStringWrapper(key_file, DESKTOP_ENTRY_GROUP, DESKTOP_ENTRY_ICON_FIELD);
+ myService = getStringWrapper(key_file, DESKTOP_ENTRY_GROUP, DESKTOP_ENTRY_SERVICE_FIELD);
+
+ break;
+ }
+
+ if (error != 0) {
+ g_error_free(error);
+ error = 0;
+ }
+
+ if (key_file != 0) {
+ g_key_file_free(key_file);
+ }
+
+ return !(myName.empty() || myIcon.empty() || myService.empty());
+}
+
+GdkPixbuf *LauncherItem::getIcon(int icon_size) const {
+ GdkPixbuf *pixbuf = 0;
+
+ if (!myIcon.empty()) {
+ GtkIconTheme *theme;
+ GError *error = 0;
+
+ theme = gtk_icon_theme_get_default();
+ pixbuf = gtk_icon_theme_load_icon(theme, myIcon.c_str(), icon_size, GTK_ICON_LOOKUP_NO_SVG, &error);
+
+ if (error != 0) {
+ g_error_free(error);
+ error = NULL;
+ }
+ }
+
+ return pixbuf;
+}
--- /dev/null
+#ifndef __LAUNCHER_ITEM_H__
+#define __LAUNCHER_ITEM_H__
+
+#include <string>
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+class LauncherItem {
+public:
+ LauncherItem();
+ ~LauncherItem();
+
+ bool load(const std::string&);
+
+ GdkPixbuf *getIcon(int icon_size) const;
+
+ const std::string& getName() const { return myName; }
+ const std::string& getComment() const { return myComment; }
+ const std::string& getService() const { return myService; }
+private:
+ std::string myName, myComment, myIcon, myService;
+};
+
+#endif
--- /dev/null
+static void
+set_hints (GtkWidget *widget)
+{
+ ZvtTerm *term;
+ GdkGeometry hints;
+ GtkWidget *app;
+
+ g_assert (widget != NULL);
+ term = ZVT_TERM (widget);
+
+ app = gtk_widget_get_toplevel(widget);
+ g_assert (app != NULL);
+
+#define PADDING 2
+ hints.base_width = (GTK_WIDGET (term)->style->klass->xthickness * 2) + PADDING;
+ hints.base_height = (GTK_WIDGET (term)->style->klass->ythickness * 2);
+
+ hints.width_inc = term->charwidth;
+ hints.height_inc = term->charheight;
+
+ hints.min_width = hints.base_width + hints.width_inc;
+ hints.min_height = hints.base_height + hints.height_inc;
+
+ gtk_window_set_geometry_hints(GTK_WINDOW(app),
+ GTK_WIDGET(term),
+ &hints,
+ GDK_HINT_RESIZE_INC|GDK_HINT_MIN_SIZE|GDK_HINT_BASE_SIZE);
+}
+
+
+The example above sets the window hints so that the window manager will force resizes to the nearest character, and report the character dimensions if it provides that functionality.
+
+It should be attached to the terminal instance using gtk_signal_connect_after() so that the hints are set after the window is realized.
+
+Example 3. Attaching the realize handler to the terminal
+
+ gtk_signal_connect_after (
+ GTK_OBJECT (term),
+ "realize",
+ GTK_SIGNAL_FUNC (set_hints),
+ term);
+
--- /dev/null
+
+#include <string>
+#include <vector>
+
+#include <gtk/gtk.h>
+
+#include <hildon-home-plugin/hildon-home-plugin-interface.h>
+#include <libosso.h>
+
+#include "launcher-item.h"
+
+extern "C" {
+ void *hildon_home_applet_lib_initialize (void *state_data, int *state_size, GtkWidget **widget);
+ void hildon_home_applet_lib_deinitialize (void *applet_data);
+ void hildon_home_applet_lib_background (void *applet_data);
+ void hildon_home_applet_lib_foreground(void *applet_data);
+ int hildon_home_applet_lib_save_state(void *applet_data, void **state_data, int *state_size);
+ GtkWidget *hildon_home_applet_lib_settings(void *applet_data, GtkWindow *parent);
+};
+
+#define SLA_APPLET_DBUS_NAME "simple-launcher"
+#define SLA_APPLET_VERSION "0.0"
+
+class SimpleLauncherApplet {
+public:
+ SimpleLauncherApplet();
+ ~SimpleLauncherApplet();
+
+ bool doInit(void *state_data, int *state_size);
+
+ void background() {}
+ void foreground() {}
+ int saveState(void **state_data, int *state_size);
+ GtkWidget *settings(GtkWindow *parent);
+
+ GtkWidget *getWidget() { return myWidget; }
+
+ bool startApplication(const std::string& application);
+
+private:
+ osso_context_t *myContext;
+ GtkWidget *myWidget;
+
+ std::vector<LauncherItem *> myItems;
+
+ static char *ourFiles[];
+};
+
+// Hildon home applet interface functions
+
+void *hildon_home_applet_lib_initialize (void *state_data, int *state_size, GtkWidget **widget) {
+ SimpleLauncherApplet *applet = new SimpleLauncherApplet();
+
+ if (applet != 0) {
+ if (applet->doInit(state_data, state_size)) {
+ *widget = applet->getWidget();
+ } else {
+ delete applet;
+ applet = 0;
+ }
+ }
+
+ return (void*)applet;
+}
+
+void hildon_home_applet_lib_deinitialize(void *applet_data) {
+ SimpleLauncherApplet *applet = (SimpleLauncherApplet *)applet_data;
+
+ delete applet;
+}
+
+void hildon_home_applet_lib_background(void *applet_data) {
+ ((SimpleLauncherApplet *)applet_data)->background();
+}
+
+void hildon_home_applet_lib_foreground (void *applet_data) {
+ ((SimpleLauncherApplet *)applet_data)->foreground();
+}
+
+GtkWidget *hildon_home_applet_lib_settings(void *applet_data, GtkWindow *parent) {
+ return ((SimpleLauncherApplet *)applet_data)->settings(parent);
+}
+
+int hildon_home_applet_lib_save_state (void *applet_data, void **state_data, int *state_size) {
+ return ((SimpleLauncherApplet *)applet_data)->saveState(state_data, state_size);
+}
+
+// SimpleLauncherApplet implementation
+
+char *SimpleLauncherApplet::ourFiles[] = {
+ 0
+};
+
+SimpleLauncherApplet::SimpleLauncherApplet(): myContext(0), myWidget(0) {
+}
+
+bool SimpleLauncherApplet::doInit(void *state_data, int *state_size) {
+ if ((myContext = osso_initialize(SLA_APPLET_DBUS_NAME, SLA_APPLET_VERSION, FALSE, NULL)) == 0) {
+ g_debug("sla-applet: failed to initialize the osso layer");
+ return false;
+ }
+
+ // myWidget = mis_widget_new_with_engines_and_history();
+ if (myWidget == 0) {
+ return false;
+ }
+
+ for (int i = 0 ; ourFiles[i] != 0 ; ++i) {
+ LauncherItem *item = new LauncherItem();
+
+ if (item->load(ourFiles[i])) {
+ myItems.push_back(item);
+ } else {
+ delete item;
+ }
+ }
+
+ // g_signal_connect (applet->myWidget, "do_search", G_CALLBACK (mis_applet_do_search), (gpointer)applet);
+
+ gtk_widget_show_all(myWidget);
+
+ return true;
+}
+
+SimpleLauncherApplet::~SimpleLauncherApplet() {
+ for (std::vector<LauncherItem *>::iterator it = myItems.begin(); it != myItems.end(); ++it) {
+ if (*it != 0) {
+ delete *it;
+ *it = 0;
+ }
+ }
+
+ myItems.resize(0);
+
+ if (myWidget != 0) {
+ gtk_widget_destroy(myWidget);
+ myWidget = 0;
+ }
+
+ if (myContext != 0) {
+ osso_deinitialize(myContext);
+ myContext = 0;
+ }
+}
+
+int SimpleLauncherApplet::saveState(void **state_data, int *state_size) {
+ if (state_data != 0) {
+ *state_data = 0;
+ }
+
+ if (state_size != 0) {
+ *state_size = 0;
+ }
+
+ return 1;
+}
+
+GtkWidget *SimpleLauncherApplet::settings(GtkWindow *parent) {
+ // TODO: in case we want SimpleLauncherApplet to be configurable, this method
+ // should return a gtk_menu_item that would be included in home settings
+ // menu. Method should make sure that when we activate that item, a
+ // corresponding dialog appears.
+ return 0;
+}
+
+bool SimpleLauncherApplet::startApplication(const std::string& application) {
+ return osso_application_top(myContext, application.c_str(), 0) == OSSO_OK;
+}
--- /dev/null
+[Desktop Entry]
+Name=Simple Launcher Applet
+Comment=A simple list of icons to click
+Type=HildonHomeApplet
+X-home-applet=libsimple-launcher.so
+X-home-applet-resizable=X
+X-home-applet-minwidth=270
+X-home-applet-minheight=45
+
--- /dev/null
+#include <iostream>
+
+#include "launcher-item.h"
+
+char *files[] = {
+ "/usr/share/applications/hildon/hildon-control-panel.desktop",
+ "/usr/share/applications/hildon/hwr-teacher.desktop",
+ "/usr/share/applications/hildon/osso-backup.desktop",
+ "/usr/share/applications/hildon/osso-global-search.desktop",
+ 0
+};
+
+int main() {
+ for (int i = 0 ; files[i] != 0 ; ++i) {
+ LauncherItem *item = new LauncherItem();
+
+ if (item->load(files[i])) {
+ std::cout << "Loaded " << files[i] << std::endl
+ << " name: " << item->getName() << std::endl
+ << " comment: " << item->getComment() << std::endl
+ << " service: " << item->getService() << std::endl;
+ } else {
+ std::cout << "Failed to load " << files[i] << std::endl;
+ }
+
+ delete item;
+ }
+
+ return 0;
+}