/* * libmokoui -- OpenMoko Application Framework UI Library * * Authored by Michael 'Mickey' Lauer * Based on hildon-window.c (C) 2006 Nokia Corporation. * * Copyright (C) 2006-2007 OpenMoko Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser Public License as published by * the Free Software Foundation; version 2 of the license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser Public License for more details. * * Current Version: $Rev$ ($Date$) [$Author$] */ #include "moko-application.h" #include "moko-window.h" #include #include #include #include #include #include #include //#define DEBUG_THIS_FILE #undef DEBUG_THIS_FILE #ifdef DEBUG_THIS_FILE #define moko_debug(fmt,...) g_debug(fmt,##__VA_ARGS__) #define moko_debug_minder(predicate) moko_debug( __FUNCTION__ ); g_return_if_fail(predicate) #else #define moko_debug(...) #endif /* add your signals here */ enum { MOKO_WINDOW_SIGNAL, LAST_SIGNAL }; enum { PROP_0, PROP_IS_TOPMOST, }; static void moko_window_class_init(MokoWindowClass *klass); static void moko_window_init(MokoWindow *self); static void moko_window_set_property(GObject* object, guint property_id, const GValue* value, GParamSpec* pspec); static void moko_window_get_property(GObject* object, guint property_id, GValue* value, GParamSpec* pspec); static void moko_window_notify(GObject* gobject, GParamSpec* param); static void moko_window_is_topmost_notify(MokoWindow* self); static guint moko_window_signals[LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE (MokoWindow, moko_window, GTK_TYPE_WINDOW) #define MOKO_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MOKO_TYPE_WINDOW, MokoWindowPrivate)); typedef struct _MokoWindowPrivate { gboolean is_fullscreen; gboolean is_topmost; } MokoWindowPrivate; static void moko_window_class_init(MokoWindowClass *klass) /* Class Initialization */ { moko_debug( "moko_window_class_init" ); /* register private data */ g_type_class_add_private( klass, sizeof(MokoWindowPrivate) ); /* hook virtual methods */ GObjectClass *object_class = G_OBJECT_CLASS(klass); object_class->set_property = moko_window_set_property; object_class->get_property = moko_window_get_property; object_class->notify = moko_window_notify; /* install signals */ moko_window_signals[MOKO_WINDOW_SIGNAL] = g_signal_new ("moko_window", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (MokoWindowClass, moko_window), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); /* install properties */ g_object_class_install_property (object_class, PROP_IS_TOPMOST, g_param_spec_boolean ("is-topmost", "Is top-most", "Whether the window is currently activated by the window " "manager", FALSE, G_PARAM_READABLE)); } static void moko_window_init(MokoWindow *self) /* Instance Construction */ { moko_debug( "moko_window_init" ); gtk_widget_set_size_request( GTK_WIDGET(self), 480, 640 ); //FIXME get from style MokoApplication* app = moko_application_get_instance(); if ( !moko_application_get_main_window( app ) ) moko_application_set_main_window( app, self ); moko_application_add_window( app, self ); } GtkWidget* moko_window_new() /* Construction */ { return GTK_WIDGET(g_object_new(moko_window_get_type(), NULL)); } void moko_window_clear(MokoWindow *self) /* Destruction */ { /* destruct your widgets here */ } static void moko_window_set_property(GObject* object, guint property_id, const GValue* value, GParamSpec* pspec) { switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void moko_window_get_property(GObject* object, guint property_id, GValue* value, GParamSpec* pspec) { MokoWindowPrivate* priv = MOKO_WINDOW_GET_PRIVATE(object); switch (property_id) { case PROP_IS_TOPMOST: g_value_set_boolean( value, priv->is_topmost ); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, pspec ); break; } } static void moko_window_notify(GObject* gobject, GParamSpec* param) { moko_debug( "moko_window_notify '%s'", param->name ); MokoWindow* window = MOKO_WINDOW(gobject); if (strcmp(param->name, "title") == 0) { moko_debug( "update window title" ); //moko_window_update_title(window); } else if (strcmp(param->name, "is-topmost") == 0) { moko_window_is_topmost_notify(window); } if (G_OBJECT_CLASS(moko_window_parent_class)->notify) G_OBJECT_CLASS(moko_window_parent_class)->notify( gobject, param ); } static void moko_window_is_topmost_notify(MokoWindow* self) { moko_debug( "moko_window_is_topmost_notify" ); MokoWindowPrivate* priv = MOKO_WINDOW_GET_PRIVATE(self); if (priv->is_topmost) { moko_debug( "-- I am topmost now :D" ); } else { moko_debug( "-- I am no longer topmost :(" ); } } /* * Compare the window that was last topped, and act consequently */ void moko_window_update_topmost(MokoWindow* self, Window window_id) { moko_debug( "moko_window_update_topmost" ); MokoWindowPrivate* priv = MOKO_WINDOW_GET_PRIVATE(self); Window my_window; /* don't test the window unless it is realised */ if (!GTK_WIDGET (self)->window) return; my_window = GDK_WINDOW_XID (GTK_WIDGET (self)->window); if (window_id == my_window) { if (!priv->is_topmost) { priv->is_topmost = TRUE; g_object_notify( G_OBJECT(self), "is-topmost" ); } } else if (priv->is_topmost) { /* Should this go in the signal handler? */ GtkWidget *focus = gtk_window_get_focus(GTK_WINDOW(self)); if (GTK_IS_ENTRY(focus)) gtk_im_context_focus_out(GTK_ENTRY(focus)->im_context); if (GTK_IS_TEXT_VIEW (focus)) gtk_im_context_focus_out(GTK_TEXT_VIEW(focus)->im_context); priv->is_topmost = FALSE; g_object_notify( G_OBJECT(self), "is-topmost" ); } } void moko_window_set_status_message (MokoWindow *self, gchar *message) { GtkWidget *window = GTK_WIDGET (self); g_return_if_fail (MOKO_IS_WINDOW (self)); XChangeProperty(GDK_WINDOW_XDISPLAY (window->window), GDK_WINDOW_XID(window->window), gdk_x11_get_xatom_by_name ("_MOKO_STATUS_MESSAGE"), XA_STRING, 8, PropModeReplace, (guchar*)message, strlen (message) + 1); } void moko_window_set_status_progress (MokoWindow *self, gdouble progress) { GtkWidget *window = GTK_WIDGET (self); g_return_if_fail (MOKO_IS_WINDOW (self)); XChangeProperty(GDK_WINDOW_XDISPLAY (window->window), GDK_WINDOW_XID(window->window), gdk_x11_get_xatom_by_name ("_MOKO_STATUS_PROGRESS"), XA_STRING, 8, PropModeReplace, (unsigned char *)&progress, sizeof (progress)); }