summaryrefslogtreecommitdiffstats
path: root/webkit/glue/webcursor_gtk.cc
blob: bb66be71fdcc8eefabf2d20827d0ceb225d8f85f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// Copyright (c) 2008 The Chromium Authors. All rights reserved.  Use of this
// source code is governed by a BSD-style license that can be found in the
// LICENSE file.

#include "webkit/glue/webcursor.h"

#include <gdk/gdk.h>

#include "config.h"
#include "PlatformCursor.h"

#undef LOG
#include "base/logging.h"

using WebCore::PlatformCursor;

namespace {

// webcursor_gtk_data.h is taken directly from WebKit's CursorGtk.h.
#include "webkit/glue/webcursor_gtk_data.h"

// This helper function is taken directly from WebKit's CursorGtk.cpp.
// It attempts to create a custom cursor from the data inlined in
// webcursor_gtk_data.h.
GdkCursor* GetInlineCustomCursor(CustomCursorType type) {
  const CustomCursor& custom = CustomCursors[type];
  GdkCursor* cursor = gdk_cursor_new_from_name(gdk_display_get_default(),
                                               custom.name);
  if (!cursor) {
    const GdkColor fg = { 0, 0, 0, 0 };
    const GdkColor bg = { 65535, 65535, 65535, 65535 };
    GdkPixmap* source = gdk_bitmap_create_from_data(NULL, custom.bits,
                                                    32, 32);
    GdkPixmap* mask = gdk_bitmap_create_from_data(NULL, custom.mask_bits,
                                                  32, 32);
    cursor = gdk_cursor_new_from_pixmap(source, mask, &fg, &bg,
                                        custom.hot_x, custom.hot_y);
    g_object_unref(source);
    g_object_unref(mask);
  }
  return cursor;
}

}  // end anonymous namespace

GdkCursorType WebCursor::GetCursorType() const {
  // http://library.gnome.org/devel/gdk/2.12/gdk-Cursors.html has images
  // of the default X theme, but beware that the user's cursor theme can
  // change everything.
  switch (type_) {
    case PlatformCursor::typePointer:
      return GDK_ARROW;
    case PlatformCursor::typeCross:
      return GDK_CROSS;
    case PlatformCursor::typeHand:
      return GDK_HAND2;
    case PlatformCursor::typeIBeam:
      return GDK_XTERM;
    case PlatformCursor::typeWait:
      return GDK_WATCH;
    case PlatformCursor::typeHelp:
      return GDK_QUESTION_ARROW;
    case PlatformCursor::typeEastResize:
      return GDK_RIGHT_SIDE;
    case PlatformCursor::typeNorthResize:
      return GDK_TOP_SIDE;
    case PlatformCursor::typeNorthEastResize:
      return GDK_TOP_RIGHT_CORNER;
    case PlatformCursor::typeNorthWestResize:
      return GDK_TOP_LEFT_CORNER;
    case PlatformCursor::typeSouthResize:
      return GDK_BOTTOM_SIDE;
    case PlatformCursor::typeSouthEastResize:
      return GDK_BOTTOM_LEFT_CORNER;
    case PlatformCursor::typeSouthWestResize:
      return GDK_BOTTOM_RIGHT_CORNER;
    case PlatformCursor::typeWestResize:
      return GDK_LEFT_SIDE;
    case PlatformCursor::typeNorthSouthResize:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeEastWestResize:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeNorthEastSouthWestResize:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeNorthWestSouthEastResize:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeColumnResize:
      return GDK_SB_H_DOUBLE_ARROW;  // TODO(evanm): is this correct?
    case PlatformCursor::typeRowResize:
      return GDK_SB_V_DOUBLE_ARROW;  // TODO(evanm): is this correct?
    case PlatformCursor::typeMiddlePanning:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeEastPanning:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeNorthPanning:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeNorthEastPanning:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeNorthWestPanning:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeSouthPanning:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeSouthEastPanning:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeSouthWestPanning:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeWestPanning:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeMove:
      return GDK_FLEUR;
    case PlatformCursor::typeVerticalText:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeCell:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeContextMenu:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeAlias:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeProgress:
      return GDK_WATCH;
    case PlatformCursor::typeNoDrop:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeCopy:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeNone:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeNotAllowed:
      NOTIMPLEMENTED(); return GDK_ARROW;
    case PlatformCursor::typeZoomIn:
    case PlatformCursor::typeZoomOut:
    case PlatformCursor::typeCustom:
      return GDK_CURSOR_IS_PIXMAP;
  }
  NOTREACHED();
  return GDK_ARROW;
}

GdkCursor* WebCursor::GetCustomCursor() const {
  switch (type_) {
    case PlatformCursor::typeZoomIn:
      return GetInlineCustomCursor(CustomCursorZoomIn);
    case PlatformCursor::typeZoomOut:
      return GetInlineCustomCursor(CustomCursorZoomOut);
  }

  if (type_ != PlatformCursor::typeCustom) {
    NOTREACHED();
    return NULL;
  }

  const guchar* data = reinterpret_cast<const guchar*>(&custom_data_[0]);
  GdkPixbuf* pixbuf =
      gdk_pixbuf_new_from_data(data,
                               GDK_COLORSPACE_RGB,
                               TRUE,  // has_alpha
                               8,     // bits_per_sample
                               custom_size_.width(),      // width
                               custom_size_.height(),     // height
                               custom_size_.width() * 4,  // row stride
                               NULL,   // data destroy function
                               NULL);  // data destroy function extra data

  GdkCursor* cursor = gdk_cursor_new_from_pixbuf(gdk_display_get_default(),
                                                 pixbuf,
                                                 hotspot_.x(),
                                                 hotspot_.y());

  gdk_pixbuf_unref(pixbuf);

  return cursor;
}