summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/efl/WidgetEfl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/efl/WidgetEfl.cpp')
-rw-r--r--Source/WebCore/platform/efl/WidgetEfl.cpp368
1 files changed, 368 insertions, 0 deletions
diff --git a/Source/WebCore/platform/efl/WidgetEfl.cpp b/Source/WebCore/platform/efl/WidgetEfl.cpp
new file mode 100644
index 0000000..640e6e3
--- /dev/null
+++ b/Source/WebCore/platform/efl/WidgetEfl.cpp
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
+ * Copyright (C) 2007 Holger Hans Peter Freyther
+ * Copyright (C) 2008 Kenneth Rohde Christiansen
+ * Copyright (C) 2009-2010 ProFUSION embedded systems
+ * Copyright (C) 2009-2010 Samsung Electronics
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Widget.h"
+
+#include "ChromeClient.h"
+#include "Cursor.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "GraphicsContext.h"
+#include "IntRect.h"
+#include "NotImplemented.h"
+#include "Page.h"
+
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Edje.h>
+#include <Evas.h>
+
+#ifdef HAVE_ECORE_X
+#include <Ecore_X.h>
+#include <Ecore_X_Cursor.h>
+#endif
+
+#include <wtf/HashMap.h>
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+#ifdef HAVE_ECORE_X
+class CursorMap {
+private:
+ HashMap<String, unsigned short> m_cursorStringMap;
+
+public:
+ CursorMap();
+ unsigned int cursor(String);
+};
+
+unsigned int CursorMap::cursor(String cursorGroup)
+{
+ int ret = m_cursorStringMap.get(cursorGroup);
+
+ if (ret < ECORE_X_CURSOR_X || ret > ECORE_X_CURSOR_XTERM)
+ ret = ECORE_X_CURSOR_LEFT_PTR;
+
+ return ret;
+}
+
+CursorMap::CursorMap()
+{
+ m_cursorStringMap.set("cursor/pointer", ECORE_X_CURSOR_LEFT_PTR);
+ m_cursorStringMap.set("cursor/move", ECORE_X_CURSOR_FLEUR);
+ m_cursorStringMap.set("cursor/cross", ECORE_X_CURSOR_CROSS);
+ m_cursorStringMap.set("cursor/hand", ECORE_X_CURSOR_HAND2);
+ m_cursorStringMap.set("cursor/i_beam", ECORE_X_CURSOR_XTERM);
+ m_cursorStringMap.set("cursor/wait", ECORE_X_CURSOR_WATCH);
+ m_cursorStringMap.set("cursor/help", ECORE_X_CURSOR_QUESTION_ARROW);
+ m_cursorStringMap.set("cursor/east_resize", ECORE_X_CURSOR_RIGHT_SIDE);
+ m_cursorStringMap.set("cursor/north_resize", ECORE_X_CURSOR_TOP_SIDE);
+ m_cursorStringMap.set("cursor/north_east_resize", ECORE_X_CURSOR_TOP_RIGHT_CORNER);
+ m_cursorStringMap.set("cursor/north_west_resize", ECORE_X_CURSOR_TOP_LEFT_CORNER);
+ m_cursorStringMap.set("cursor/south_resize", ECORE_X_CURSOR_BOTTOM_SIDE);
+ m_cursorStringMap.set("cursor/south_east_resize", ECORE_X_CURSOR_BOTTOM_RIGHT_CORNER);
+ m_cursorStringMap.set("cursor/south_west_resize", ECORE_X_CURSOR_BOTTOM_LEFT_CORNER);
+ m_cursorStringMap.set("cursor/west_resize", ECORE_X_CURSOR_LEFT_SIDE);
+ m_cursorStringMap.set("cursor/north_south_resize", ECORE_X_CURSOR_SB_H_DOUBLE_ARROW);
+ m_cursorStringMap.set("cursor/east_west_resize", ECORE_X_CURSOR_SB_V_DOUBLE_ARROW);
+ m_cursorStringMap.set("cursor/north_east_south_west_resize", ECORE_X_CURSOR_SIZING);
+ m_cursorStringMap.set("cursor/north_west_south_east_resize", ECORE_X_CURSOR_SIZING);
+ m_cursorStringMap.set("cursor/column_resize", ECORE_X_CURSOR_SB_V_DOUBLE_ARROW);
+ m_cursorStringMap.set("cursor/row_resize", ECORE_X_CURSOR_SB_H_DOUBLE_ARROW);
+ m_cursorStringMap.set("cursor/middle_panning", ECORE_X_CURSOR_CROSS_REVERSE);
+ m_cursorStringMap.set("cursor/east_panning", ECORE_X_CURSOR_CROSS_REVERSE);
+ m_cursorStringMap.set("cursor/north_panning", ECORE_X_CURSOR_CROSS_REVERSE);
+ m_cursorStringMap.set("cursor/north_east_panning", ECORE_X_CURSOR_CROSS_REVERSE);
+ m_cursorStringMap.set("cursor/north_west_panning", ECORE_X_CURSOR_CROSS_REVERSE);
+ m_cursorStringMap.set("cursor/south_panning", ECORE_X_CURSOR_CROSS_REVERSE);
+ m_cursorStringMap.set("cursor/south_east_panning", ECORE_X_CURSOR_CROSS_REVERSE);
+ m_cursorStringMap.set("cursor/south_west_panning", ECORE_X_CURSOR_CROSS_REVERSE);
+ m_cursorStringMap.set("cursor/west_panning", ECORE_X_CURSOR_CROSS_REVERSE);
+ m_cursorStringMap.set("cursor/vertical_text", ECORE_X_CURSOR_SB_DOWN_ARROW);
+ m_cursorStringMap.set("cursor/cell", ECORE_X_CURSOR_ICON);
+ m_cursorStringMap.set("cursor/context_menu", ECORE_X_CURSOR_HAND2);
+ m_cursorStringMap.set("cursor/no_drop", ECORE_X_CURSOR_DOT_BOX_MASK);
+ m_cursorStringMap.set("cursor/copy", ECORE_X_CURSOR_ICON);
+ m_cursorStringMap.set("cursor/progress", ECORE_X_CURSOR_WATCH);
+ m_cursorStringMap.set("cursor/alias", ECORE_X_CURSOR_MAN);
+ m_cursorStringMap.set("cursor/none", ECORE_X_CURSOR_X);
+ m_cursorStringMap.set("cursor/not_allowed", ECORE_X_CURSOR_X);
+ m_cursorStringMap.set("cursor/zoom_in", ECORE_X_CURSOR_DIAMOND_CROSS);
+ m_cursorStringMap.set("cursor/zoom_out", ECORE_X_CURSOR_DIAMOND_CROSS);
+ m_cursorStringMap.set("cursor/grab", ECORE_X_CURSOR_HAND2);
+ m_cursorStringMap.set("cursor/grabbing", ECORE_X_CURSOR_HAND2);
+}
+
+static CursorMap cursorStringMap = CursorMap();
+#endif
+
+class WidgetPrivate {
+public:
+ Evas* m_evas;
+ Evas_Object* m_evasObject;
+ String m_theme;
+
+ WidgetPrivate()
+ : m_evas(0)
+ , m_evasObject(0)
+ , m_cursorObject(0)
+#ifdef HAVE_ECORE_X
+ , m_isUsingEcoreX(false)
+#endif
+ {}
+
+ /* cursor */
+ String m_cursorGroup;
+ Evas_Object* m_cursorObject;
+
+#ifdef HAVE_ECORE_X
+ bool m_isUsingEcoreX;
+#endif
+};
+
+Widget::Widget(PlatformWidget widget)
+ : m_parent(0)
+ , m_widget(0)
+ , m_selfVisible(false)
+ , m_parentVisible(false)
+ , m_frame(0, 0, 0, 0)
+ , m_data(new WidgetPrivate)
+{
+ init(widget);
+}
+
+Widget::~Widget()
+{
+ ASSERT(!parent());
+
+ if (m_data->m_cursorObject)
+ evas_object_del(m_data->m_cursorObject);
+
+ delete m_data;
+}
+
+IntRect Widget::frameRect() const
+{
+ return m_frame;
+}
+
+void Widget::setFrameRect(const IntRect& rect)
+{
+ m_frame = rect;
+ Widget::frameRectsChanged();
+}
+
+void Widget::frameRectsChanged()
+{
+ Evas_Object* o = evasObject();
+ Evas_Coord x, y;
+
+ if (!parent() || !o)
+ return;
+
+ IntRect rect = frameRect();
+ if (parent()->isScrollViewScrollbar(this))
+ rect.setLocation(parent()->convertToContainingWindow(rect.location()));
+ else
+ rect.setLocation(parent()->contentsToWindow(rect.location()));
+
+ evas_object_geometry_get(root()->evasObject(), &x, &y, 0, 0);
+ evas_object_move(o, x + rect.x(), y + rect.y());
+ evas_object_resize(o, rect.width(), rect.height());
+}
+
+void Widget::setFocus(bool focused)
+{
+}
+
+void Widget::applyFallbackCursor()
+{
+#ifdef HAVE_ECORE_X
+ if (m_data->m_isUsingEcoreX && !m_data->m_cursorGroup.isNull()) {
+ int shape = cursorStringMap.cursor(m_data->m_cursorGroup.utf8().data());
+
+ if (shape < ECORE_X_CURSOR_X || shape > ECORE_X_CURSOR_XTERM) {
+ LOG_ERROR("cannot map an equivalent X cursor for"
+ " c ursor group %s", m_data->m_cursorGroup.utf8().data());
+ shape = ECORE_X_CURSOR_LEFT_PTR;
+ }
+
+ Ecore_X_Window win = ecore_evas_software_x11_window_get(ecoreEvas());
+ Ecore_X_Cursor cur = ecore_x_cursor_shape_get(shape);
+ ecore_x_window_cursor_set(win, cur);
+ return;
+ }
+#endif
+ LOG_ERROR("Ooops, no fallback to set cursor %s!\n",
+ m_data->m_cursorGroup.utf8().data());
+}
+
+void Widget::applyCursor()
+{
+ CString file = edjeThemeRecursive().utf8();
+
+ m_data->m_cursorObject = edje_object_add(evas());
+ if (!file.isNull() && !edje_object_file_set(m_data->m_cursorObject, file.data(), m_data->m_cursorGroup.utf8().data())) {
+ evas_object_del(m_data->m_cursorObject);
+ m_data->m_cursorObject = 0;
+ ecore_evas_object_cursor_set(ecoreEvas(), 0, 0, 0, 0);
+ applyFallbackCursor();
+ } else {
+ Evas_Coord x, y, w, h;
+ const char *d;
+
+ edje_object_size_min_get(m_data->m_cursorObject, &w, &h);
+ if ((w <= 0) || (h <= 0))
+ edje_object_size_min_calc(m_data->m_cursorObject, &w, &h);
+ if ((w <= 0) || (h <= 0))
+ w = h = 16;
+ evas_object_resize(m_data->m_cursorObject, w, h);
+
+ d = edje_object_data_get(m_data->m_cursorObject, "hot.x");
+ x = d ? atoi(d) : 0;
+
+ d = edje_object_data_get(m_data->m_cursorObject, "hot.y");
+ y = d ? atoi(d) : 0;
+
+ ecore_evas_object_cursor_set(ecoreEvas(), m_data->m_cursorObject,
+ EVAS_LAYER_MAX, x, y);
+ }
+}
+
+void Widget::setCursor(const Cursor& cursor)
+{
+ if (!evas())
+ return;
+
+ const char *group = cursor.impl();
+ if (!group || String(group) == m_data->m_cursorGroup)
+ return;
+
+ m_data->m_cursorGroup = group;
+
+ applyCursor();
+}
+
+void Widget::show()
+{
+ if (!platformWidget())
+ return;
+
+ evas_object_show(platformWidget());
+}
+
+void Widget::hide()
+{
+ if (!platformWidget())
+ return;
+
+ evas_object_hide(platformWidget());
+}
+
+void Widget::paint(GraphicsContext* context, const IntRect&)
+{
+ notImplemented();
+}
+
+void Widget::setIsSelected(bool)
+{
+ notImplemented();
+}
+
+const String Widget::edjeTheme() const
+{
+ return m_data->m_theme;
+}
+
+void Widget::setEdjeTheme(const String& themePath)
+{
+ if (m_data->m_theme == themePath)
+ return;
+
+ m_data->m_theme = themePath;
+}
+
+const String Widget::edjeThemeRecursive() const
+{
+ if (!m_data->m_theme.isNull())
+ return m_data->m_theme;
+ if (m_parent)
+ return m_parent->edjeThemeRecursive();
+
+ return String();
+}
+
+Evas* Widget::evas() const
+{
+ return m_data->m_evas;
+}
+
+Ecore_Evas* Widget::ecoreEvas() const
+{
+ // FIXME EFL: XXX assume evas was created by ecore_evas
+ return static_cast<Ecore_Evas*>(evas_data_attach_get(evas()));
+}
+
+void Widget::setEvasObject(Evas_Object *o)
+{
+ // FIXME: study platformWidget() and use it
+ // FIXME: right now platformWidget() requires implementing too much
+ if (m_data->m_evasObject == o)
+ return;
+ m_data->m_evasObject = o;
+ if (!o) {
+ m_data->m_evas = 0;
+#ifdef HAVE_ECORE_X
+ m_data->m_isUsingEcoreX = false;
+#endif
+ return;
+ }
+
+ m_data->m_evas = evas_object_evas_get(o);
+
+#ifdef HAVE_ECORE_X
+ const char *engine = ecore_evas_engine_name_get(ecoreEvas());
+ m_data->m_isUsingEcoreX = (!strcmp(engine, "software_x11")
+ || !strcmp(engine, "software_xcb")
+ || !strcmp(engine, "software_16_x11")
+ || !strncmp(engine, "xrender", sizeof("xrender") - 1));
+#endif
+
+ Widget::frameRectsChanged();
+}
+
+Evas_Object* Widget::evasObject() const
+{
+ return m_data->m_evasObject;
+}
+
+}