Compare commits

...

562 Commits

Author SHA1 Message Date
Carlos Garnacho
564b813093 gdk: Make gdk_display_peek_event() Return a reference to the event
And gdk_peek_event() indirectly, but that one should probably be removed.
2017-12-13 17:27:26 +01:00
Carlos Garnacho
435bf05325 gtk: Make gtk_get_current_event() return a reference
All callers in gtk seem to be ok with it, and it makes sense if
we are dealing with events as "static after delivered".
2017-12-13 17:27:26 +01:00
Carlos Garnacho
17c65ffbf2 gtk: Avoid some event copies
Those places can do with an extra reference.
2017-12-13 17:27:26 +01:00
Carlos Garnacho
c3412ef61b gtk: s/gdk_event_free/g_object_unref/ 2017-12-13 17:27:26 +01:00
Carlos Garnacho
14421aa6be gdk/wayland: s/gdk_event_free/g_object_unref/ 2017-12-13 17:27:25 +01:00
Carlos Garnacho
a54df76a58 gdk/x11: s/gdk_event_free/g_object_unref/ 2017-12-13 17:27:24 +01:00
Carlos Garnacho
0d67cd2b88 gdk: Remove gdk_window_[gs]et_event_compression()
Motion compression is now the unmodifiable default, callers may
call gdk_event_get_motion_history() to check the uncoalesced
motion history.
2017-12-13 17:27:04 +01:00
Carlos Garnacho
9b5ccb0d0f gtk: Remove CONSTRUCT_ONLY flag from GtkEventControllerScroll::flags
There is a gtk_event_controller_scroll_set_flags() call that's meant
to be called after construction (eg. due to scrolledwindow relayouts
hiding/showing scrollbars). The property shouldn't be construct-only
for consistence.
2017-12-13 17:27:04 +01:00
Carlos Garnacho
c153f44108 gdk: Implement motion history as motion event data
In the motion compression phase the coalesced events will be saved
as a GdkTimeCoord on the motion event that shall be delivered.

For simplicity (and because history doesn't make much sense otherwise)
event history is only recorded while there are buttons pressed, this
also tidily ensures that those coalesced events would have the same
target widget on the gtk side than the delivered one, because of
implicit grabs.
2017-12-13 17:27:04 +01:00
Carlos Garnacho
940c9812f1 gdk: Keep reference on tools from motion/button events. 2017-12-13 17:27:04 +01:00
Carlos Garnacho
2e07652c25 gdk: Move additional code in gdk_event_new() to GdkEvent::constructed
Now that the type is a construct only property, we can initialize the
event fields properly here.
2017-12-13 17:27:04 +01:00
Carlos Garnacho
488a8f1fff gdk: Make GdkEvent type a construct only property
So it must be set at the time of doing g_object_new().
2017-12-13 17:27:04 +01:00
Carlos Garnacho
81b547f14b gdk: Remove gdk_event_is_allocated()
All events are allocated now.
2017-12-13 17:27:04 +01:00
Carlos Garnacho
0d13813a93 gtk: Adapt marshallers to GdkEvent as GObject 2017-12-13 17:27:04 +01:00
Carlos Garnacho
1c8c3a5378 gdk: Turn GdkEvent into a GObject
Two warts remain. gdk_event_copy() should be unnecessary as
events should be considered static after delivery, so g_object_ref()
should be just as good. There's a few exceptional cases that the event
is copied and then modifier for later processing, those cases should be
reconsidered individually.

And gdk_event_free() could be likewise turned into g_object_unref(),
many callers remain though.
2017-12-13 17:27:04 +01:00
Carlos Garnacho
b5203fae0e gdk: Remove GdkScreen from GdkEventPrivate
Figure out the screen from the event window, there's presumably
just one GdkScreen anyway.
2017-12-13 17:27:04 +01:00
Carlos Garnacho
347a3ff916 gdk: Figure out the GdkSeat of an event from the GdkDevice
Removes the need for gdk_event_set_seat() and the GdkSeat field from
GdkEventPrivate.
2017-12-13 17:27:04 +01:00
Carlos Garnacho
bd9569d8c1 gdk: Use allocated events
Stack allocated GdkEvent structs will not be ok when events become
objects.
2017-12-13 17:27:04 +01:00
Carlos Garnacho
f1096a1146 gtk/a11y: Use allocated events
Using stack allocated GdkEvent will not be ok when they become
objects.
2017-12-13 17:27:04 +01:00
Carlos Garnacho
fdae7179df gdk: Fold GdkEventPrivate fields into event structs
Now all events structs are private, it doesn't make as much sense
having GdkEventPrivate wrapping allocating events. This is a first
step towards removing it.
2017-12-13 17:27:04 +01:00
Carlos Garnacho
3a7a3c2df4 gdk: Remove GdkEventType argument from GdkEvent union
It won't stand true anymore that the GdkEventType argument is the
first field of the GdkEvent* structs. All callers have been updated
to use event->any.type instead.
2017-12-13 17:27:03 +01:00
Carlos Garnacho
84e4ec78e9 gdk: Refurbish GdkEvent struct hierarchy
Make all specific event structs contain a GdkEventAny, so the base
struct can be extended without modifying structs all over the place.
2017-12-13 17:27:02 +01:00
Matthias Clasen
c30cd885dd A forgotten file
These changes belong to the scale button autoscrollling
commit.
2017-12-12 23:23:17 -05:00
Matthias Clasen
9b29369222 Make sure events have displays
This seems to be necessary if you want to call
gdk_display_put_event on them.
2017-12-12 23:21:26 -05:00
Matthias Clasen
7e02ad648c toolbar: Stop using legacy event signals
We can reuse the button gesture here.
2017-12-12 22:55:48 -05:00
Matthias Clasen
fa7ef93bc5 scalebutton: Add autoscrolling
Use the smooth autoscrolling that the scale can do,
and at the same time stop using legacy event signals.
2017-12-12 22:21:43 -05:00
Matthias Clasen
05fbd32c4d button: Add private api to get at the gesture
Attaching another gesture from the outside does not
work currently, so let widgets share their button's
gesture for now.
2017-12-12 22:18:19 -05:00
Matthias Clasen
b891d205dd range: Add private api to autoscroll
This will be used to scroll the scale in scale buttons.
2017-12-12 22:17:49 -05:00
Matthias Clasen
2f6f8a7e6f path bar: Drop non-functional hold-to-scroll code
Scrolling a path bar is of marginal usefulness - you need to
find a really deep place in your filesystem hierarchy in order
to scroll one or two places at best. And the code we had for
this was not working. And it was using legacy event handlers.
Instead of fixing it, remove it.
2017-12-12 20:49:31 -05:00
Benjamin Otte
fb0fdddd76 x11: Refactor xevent filtering some more
We now have a GdkX11Display::xevent signal that gets emitted for every
XEvent and allows you to interrupt processing via TRUE/FALSE return
values.
These return values to correspond to GDK_FILTER_REMOVE and
GDK_FILTER_CONTINUE respectively.

The GDK_FILTER_TRANSLATE case from gdk_window_add_filter() is now meant
to be handled via gdk_display_put_event().
2017-12-13 01:55:56 +01:00
Matthias Clasen
76b93f5598 widget-factory: Avoid a legacy event handler
We can use a gesture instead, here.
2017-12-12 19:46:10 -05:00
Benjamin Otte
4b33a34ce3 x11: Use GdkX11Display::translate-event more 2017-12-13 01:09:32 +01:00
Benjamin Otte
2d86c1a869 x11: Make clipboard use translate-event signal 2017-12-13 00:56:52 +01:00
Benjamin Otte
c93ddf62c3 gdk: Clean up marshalers
Don't generate marshallers that are not needed.

Use the default ones if they exist.
2017-12-13 00:56:52 +01:00
Benjamin Otte
0d1ea05658 x11: Add GdkX11Display:translate-event signal
This is supposed to replace gdk_window_add_filter() in the long run.
2017-12-13 00:56:52 +01:00
Benjamin Otte
f34297cfba x11: Constify XEvent usage 2017-12-13 00:56:52 +01:00
Benjamin Otte
8a453924a0 gdk: Remove gdk_event_put(), peek() etc
We don't want to treat events like they don't belong to displays. So
instead, people should use gdk_display_put/peek/get_event().
2017-12-13 00:56:52 +01:00
Benjamin Otte
5df527edaf x11: Refactor code
This is in preparation for DND.

It moves a lot of code from gdkclipboard-x11.c to
gdkselectionoutputstream-x11.c to untangle it from GdkX11Clipboard
usage.
2017-12-13 00:56:52 +01:00
Benjamin Otte
80dcdd3df6 gdk: Remove unused function
Fun fact: This function was never used.
2017-12-13 00:56:52 +01:00
Matthias Clasen
1b9aa1b708 a11y: drop the focus tracker
This code was doing horrible things, and the atk documentation
for the focus tracking feature says that this is deprecated and
not used anymore. So lets not do it.
2017-12-12 14:49:44 -05:00
Matthias Clasen
33fdcca2cf placesview: Make middle click work
This does not cost us much, and improves consistency.
2017-12-12 13:56:15 -05:00
Matthias Clasen
6896e9402e Deprecate many legacy event signals
Mark the following signals as deprecated:
event, event-after, button-press-event, button-release-event,
touch-event, scroll-event, motion-notify-event, enter-notify-event,
leave-notify-event, property-notify-event, selection-clear-event,
selection-request-event, selection-notify-event, selection-received,
selection-get, proximity-in-event, proximity-out-event. Most
of these have suitable replacements in event controllers and
gestures already. The selection-related signals will soon be
irrelevant when selection handling moves to GDK.

Set G_ENABLE_DIAGNOSTIC=1 to see deprecation
warnings for uses of these signals.
2017-12-12 11:04:49 -05:00
Matthias Clasen
20bdb347cd Install gtkeventcontrollermotion.h
Public headers need to be listed in gtk/meson.build.
This was overlooked when I added the controller.
2017-12-12 10:39:16 -05:00
Piotr Drąg
cb8888a985 Update POTFILES.in 2017-12-12 16:33:22 +01:00
Matthias Clasen
a20a828b57 Add GtkEventControllMotion to the docs 2017-12-12 10:26:03 -05:00
Matthias Clasen
c3851c5469 paned: Stop using motion notify
We can use the new motion event controller that
was introduced for this purpose.
2017-12-12 09:42:05 -05:00
Matthias Clasen
3aa6890e3e about dialog: Stop using event-after as well
We can just use a multipress gesture for this purpose.
2017-12-12 09:42:05 -05:00
Matthias Clasen
56a41f174e about dialog: Stop using motion notify
We can use the new motion event controller for this.
2017-12-12 09:42:05 -05:00
Matthias Clasen
ecdf8c64fe label: Use GtkEventControllerMotion
This lets us avoid legacy event signals here.
2017-12-12 09:42:05 -05:00
Matthias Clasen
911f9fb0ee Add a simple motion eventcontroller
This can serve as a replacement for the legacy
event signals for enter/leave/motion notify.
2017-12-12 09:42:05 -05:00
Matthias Clasen
d871fd12cc Try to make a composite entry
This is an attempt to see how much work is needed to
reproduce entry icons by just putting an entry and images
in a box, with some css glue.
2017-12-12 09:42:05 -05:00
Benjamin Otte
b80d14ba19 placessidebar: Don't use root coordinates 2017-12-12 00:31:49 +01:00
Benjamin Otte
04ac4c66ae dnd: Pass device, not event
You don't start a dnd operation with a device, you start it with an
event.
2017-12-12 00:31:49 +01:00
Benjamin Otte
23c798b41d dnd: No longer allow passing -1
Nobody ever does that and special cases are evil.
2017-12-12 00:29:51 +01:00
Benjamin Otte
756b276070 dnd: Remove button argument from drag_begin()
It was unused.
2017-12-12 00:29:51 +01:00
Matthias Clasen
1e4aeb2efb calendar: Stop using a legacy event handler
Replace the motion_notify handler by a drag gesture.
2017-12-10 22:15:12 -05:00
Matthias Clasen
474d36499a Adwaita: Set an icon size for drag icons
This makes drag icons set from icon names come out
at a size that it large enough to not disappear under
the drag cursor.
2017-12-10 21:17:13 -05:00
Matthias Clasen
c2bdae23a1 Set a style class for drag icons
This lets us use the new icon-size machinery to
ensure we don't have tiny drag icons when using
named icons.
2017-12-10 21:16:31 -05:00
Benjamin Otte
643a6c2311 gdk: Remove gdk_drag_manage_dnd()
Instead, pass the actions as part of gdk_drag_begin() and insist DND is
always managed.

A new side effect is that gdk_drag_begin() can now return %NULL.
2017-12-11 01:46:33 +01:00
Benjamin Otte
7e0844d92f dnd: No point in determining the keyboard
We only use the pointer.
2017-12-11 01:02:31 +01:00
Benjamin Otte
218efa62ef dnd: Pass dx/dy instead of x_root/y_root
This way, we don't need root coordinates when computing the dnd start
position.
2017-12-11 01:02:31 +01:00
Benjamin Otte
a7c3c794df dnd: Make gdk_drag_context_set_device() private
There's no need to call it from GTK anymore, because we pass the device
to gdk_drag_begin().
2017-12-11 01:02:31 +01:00
Benjamin Otte
33a634be33 calendar: Don't request drag data on every motion event
At least wait until we've received the previous one.
2017-12-11 01:02:31 +01:00
Benjamin Otte
565d8325c4 gdk: Remove outdated gdk_drag_begin() alternatives
There's only one that's ever used, so delete the others and rename this
one to gdk_drag_begin().
2017-12-11 01:02:31 +01:00
Matthias Clasen
6af4947e70 link button: Set a drag icon
It is a bit odd to drag nothing around, so set an icon.
2017-12-10 14:05:01 -05:00
Matthias Clasen
642588b9cd docs: Don't mention css for setting cursors
We don't have a plan to make this work, so lets not
talk about it in the docs.
2017-12-09 23:59:31 -05:00
Matthias Clasen
c35cb0eb1b entry: Allocate the progress bar only what it needs
We were allocating the progress bar to the full size
of the entry. This made entry icons loose their cursors,
since they were 'covered' by the progress bar, even though
it doesn't draw anything there.
2017-12-09 23:48:35 -05:00
Colomban Wendling
69344322d1 Fix updating the widget accessible description when using its tooltip
We need to notify ATK the description changed when the tooltip text associated
with the widget changes and gtk_widget_accessible_get_description() would use
it as the description.

https://bugzilla.gnome.org/show_bug.cgi?id=779009
2017-12-09 21:24:44 -05:00
Daniel van Vugt
3b2f939590 Fix irregular gdk_frame_clock_get_frame_time
This fixes stuttering in animations that rely on the regularity of
gdk_frame_clock_get_frame_time.

https://bugzilla.gnome.org/show_bug.cgi?id=787665

BEFORE
gdkgears:
58 FPS and visibly stuttering
gnome-maps on a 59.95Hz monitor:
"paint" g_get_monotonic_time +17278μs, gdk_frame_clock_get_frame_time +17278μs
"paint" g_get_monotonic_time +17449μs, gdk_frame_clock_get_frame_time +17426μs
"paint" g_get_monotonic_time +17620μs, gdk_frame_clock_get_frame_time +17600μs

AFTER
gdkgears:
60 FPS and smoother
gnome-maps on a 59.95Hz monitor:
"paint" g_get_monotonic_time +18228μs, gdk_frame_clock_get_frame_time +16680μs
"paint" g_get_monotonic_time +15010μs, gdk_frame_clock_get_frame_time +16680μs
"paint" g_get_monotonic_time +17134μs, gdk_frame_clock_get_frame_time +16680μs
2017-12-09 20:52:36 -05:00
Benjamin Otte
7a17865b22 dnd: Remove "delete" argument from gtk_drag_finish()
The argument is ignored by anything but X11.
It's treated like suggested_action == MOVE.

So do that in gtk_drag_finish(), too.
2017-12-10 01:33:38 +01:00
Benjamin Otte
803cbd576f dnd: Introduce gdk_drop_read_async() and use it
This is the replacement for selection usage.

Backend implementations for X11 (missing support for backwards compat
formats like COMPOUND_TEXT) and Wayland are included.

GTK code should be adapted to use gdk_drop_read_*() functions instead
of gtk_drag_get_data().
2017-12-10 01:09:14 +01:00
Benjamin Otte
963264a73a gdk: Fix wrong usage of g_task_propagate_pointer()
The return value is transfer full, not transfer none.
2017-12-10 01:09:14 +01:00
Benjamin Otte
234d34366a clipboard: Add the useful stuff from reverted commit
This is the parts of dc50e0637f that
should have been committed but were reverted in
b5c62cf86f to unbreak the build.
2017-12-10 01:09:14 +01:00
Benjamin Otte
0d31eb8670 dnd: Add gdk_drag_context_get_display()
Also turn it into a readable, construct-only property.

Every GDK object should have this. (Apart from GdkDisplay, obviously.)
2017-12-10 01:09:14 +01:00
Benjamin Otte
815cd0ed68 gdk: Include gio.h in gdktypes.h
It's where we include all our external dependencies.

This way, we don't have to include it in all headers again and again.
2017-12-10 01:09:14 +01:00
Carlos Garnacho
8233cf3688 gtkwindow: Allow edge resizing from corners if constraints forbid either side
The fix is twofold. First, when checking that a corner is resizable, we must
check the constraints on both edges. Second, when checking either edge we
must include both perpendicular sides in order to allow those to be
resizable when the constraint does not allow resizing the edge being
checked.
2017-12-09 22:19:57 +01:00
Carlos Garnacho
6b4dd4be6c gtkwindow: Use shadow border when calculating resize areas positions
This way resize areas are correctly positioned right outside the visible
window edge on all sides.
2017-12-09 17:33:44 +01:00
Carlos Garnacho
f6ef18ac74 gtkwindow: Do not account handle size when checking content area
This is necessary to bring back the L-shaped resize corners. On all edges
(not corners) the handle width is determined by the border size.
2017-12-09 17:32:02 +01:00
Rico Tzschichholz
d872640927 Fix some parameter name mismatches to make g-ir-scanner happier 2017-12-09 15:36:35 +01:00
Matthias Clasen
b3ebffa07d Switch the order for cursor lookup
When looking for the cursor to apply, start from the innermost
widget and go up. This is the right behavior for cases like
entry icons. The top-down order we were using so far is the
right behavior for cases like global wait cursors. Since we
have entry icons in gtk, but not global wait cursors, lets
pick the other order for now.
2017-12-09 08:35:23 -05:00
Timm Bäder
da0582075a treeview: Don't draw background twice
This is done unconditionally for all widgets these days.
2017-12-09 13:15:07 +01:00
Timm Bäder
f7f0461471 recorder: Show rounded clip node corner size info 2017-12-09 13:14:59 +01:00
Timm Bäder
329683f746 snapshot: Don't create blur nodes with radius 0 2017-12-09 13:14:51 +01:00
Timm Bäder
f6f1dfb55d snapshot: Collapse color matrix nodes
Color matrix nodes as the child of other color matrix nodes can happen
quite frequently as a result of CSS. To ease the renderer
implementations, collapse chains of color matrix nodes into one.
2017-12-09 13:14:44 +01:00
Timm Bäder
484e453780 Fix a few overlooked casts
glib warns about these now.
2017-12-09 13:14:00 +01:00
Matthias Clasen
e7ed7c1913 paned: Grab during the drag
This is necessary to ensure we get the right cursor.
2017-12-08 21:09:24 -05:00
Marco Trevisan (Treviño)
29f36fed08 cssshadowvalue: don't apply the y_scale offset twice to the shadow
As per commit 942e904 this changed causing a regression that
seems to be visible only when scale > 2.

https://bugzilla.gnome.org/show_bug.cgi?id=791363
2017-12-08 18:23:10 -05:00
Matthias Clasen
072f06abf7 Fix fallout from g_object_ref change
g_object_ref now returns the type of the object that was
passed. Introduce cast as necessary to avoid warnings due
to this.
2017-12-08 17:48:47 -05:00
Timm Bäder
1c9e3af482 css node tests: Update expected output 2017-12-08 21:09:03 +01:00
Matthias Clasen
029a84aa74 Fix fallout from the show-close-button rename
I had overlooked ui files. We should really
validate those during build.
2017-12-08 11:29:14 -05:00
Philip Withnall
276c462553 mir: Fix potential use of NULL GDBusConnection
If we fail to connect to the session bus, it would be a bit silly to
immediately try and use that NULL connection.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

https://bugzilla.gnome.org/show_bug.cgi?id=668590
2017-12-08 09:55:27 +00:00
Matthias Clasen
fec0dc2b13 Rename GtkHeaderBar::show-close-button
It is about all window buttons, so rename it to ::show-title-buttons.

https://bugzilla.gnome.org/show_bug.cgi?id=779862
2017-12-07 22:37:06 -05:00
Jonas Ådahl
6412d25602 wayland: Destroy the xdg_imported after the wl_surface
This way the window manager can handle destruction while having the
transient-for relationship still valid.

https://bugzilla.gnome.org/show_bug.cgi?id=791062
2017-12-07 22:13:30 -05:00
Jonas Ådahl
7c743e6f41 wayland: Maybe postpone xdg-foreign state setup until mapping
In order to map a window with the correct initial parent-child
relationship when a modal dialog is set up to be a child of an imported
foreign window, the relationship must be set up before the window is
mapped.

In order to do this, if a window is not yet mapped, postpone the
relationship setup until when the window is eventually mapped.

https://bugzilla.gnome.org/show_bug.cgi?id=791062
2017-12-07 22:13:30 -05:00
Colin Leroy
0156c52a2c placesview: Present FUSE-reachable network shares in Other Locations
The documentation about gtk_file_chooser_set_local_only() states
that "non-native files may still be available using the native
filesystem via a userspace filesystem (FUSE)."
The code that made this possible in GTK+2 was missing from GTK+3 and
that represented a regression for Linux users in numerous applications
(Firefox, Thunderbird, Chromium, ...)

https://bugzilla.gnome.org/show_bug.cgi?id=787128
2017-12-07 21:31:46 -05:00
Carlos Garnacho
7531be3510 gdk: Add GDK_SEAT_CAPABILITY_TABLET_PAD
Tablet pads don't adapt really well to any other capability, so add a
distinct one to be able to query those properly.

https://bugzilla.gnome.org/show_bug.cgi?id=790920
2017-12-07 21:27:33 -05:00
Carlos Garnacho
4c45022ed0 gdk: Add gdk_seat_get_master_pointers()
Traditionally (and on most backends) there's a single master pointer driven
by all pointing devices. The notable exception is Wayland though, where
master pointing devices are created per capability in the case of
pointer/touch, and one for each drawing tablet.

This function call makes it easy to access all these.

https://bugzilla.gnome.org/show_bug.cgi?id=790920
2017-12-07 21:27:14 -05:00
Matthias Clasen
62f1695cb3 Move editing to button release
This will free up primary button press for drags.
2017-12-07 21:25:44 -05:00
Matthias Clasen
b6f33919b7 Make sure stopped spinner stay visible
This demo needs stopped spinners to be visible,
so the user can interact with them.
2017-12-06 23:49:48 -05:00
Matthias Clasen
2d85e8df8b Fix a typo in the docs 2017-12-06 23:39:27 -05:00
Matthias Clasen
79ddb14404 Add a Cut menuitem to the dnd demo 2017-12-06 23:36:35 -05:00
Matthias Clasen
e104cf012d More work on the dnd demo
Still no dnd in the drag-and-drop demo...
2017-12-06 23:10:56 -05:00
Timm Bäder
49e624bbe9 paned: Restrict picking to allocation
Same reason as GtkViewport does it: We might allocate child widgets
outside of the paned's content allocation. For drawing, we add a clip
node.

This was causing the "Record" button in the inspector recorder to ignore
pointer events since the treeview column header label in the GtkPaned
was swallowing it.
2017-12-06 08:23:03 +01:00
Timm Bäder
1aa811ce12 Remove all gtk_widget_get_content_size usages
And remove the function itself. Make everything use gtk_widget_get_width
and gtk_widget_get_height instead.
2017-12-06 07:56:12 +01:00
Matthias Clasen
2dae71c619 Add some copy-paste for widgets demo
Not sure this is quite right yet.
2017-12-05 17:45:39 -08:00
Matthias Clasen
2a49371e07 Start a dnd demo
Nothing to see yet.
2017-12-05 16:22:06 -08:00
Matthias Clasen
20cbb3f745 Update gtk docs for recent changes
Clipboards are gone, textures appear...
2017-12-05 08:56:09 -08:00
Matthias Clasen
48f1e53e1e Drop get/set_scale_factor from gsk docs
They no longer exist.
2017-12-05 08:39:04 -08:00
Alexander Larsson
df2716a109 broadway: Add broadway_server_lookup_surface helper 2017-12-05 16:10:06 +01:00
Alexander Larsson
2cad2c21e6 broadway: Make the use of next_texture_id clearer
It used to actually be pre-incremented, so meant like "one before
next id".
2017-12-05 15:54:36 +01:00
Alexander Larsson
d141bd4121 broadway: Use "surface" instead of window/toplevel for browser object
Als fixes indentation/tabs and removes some unused code.
2017-12-05 15:50:34 +01:00
Alexander Larsson
e80ad0e0f9 broadway: Remove references to unused BROADWAY_EVENT_DELETE_NOTIFY 2017-12-05 15:50:34 +01:00
Alexander Larsson
4694885015 broadway: Remove now unused toplevel surface 2017-12-05 15:50:34 +01:00
Christian Hergert
dc8320c129 autocleanups: allow g_autoptr() usage with GtkTreePath
As the summary says, this allows using g_autoptr(GtkTreePath). This is
useful for API that uses out parameters for GtkTreePath that need to be
freed.

https://bugzilla.gnome.org/show_bug.cgi?id=791234
2017-12-05 12:33:50 +00:00
Emmanuele Bassi
51db8f8f53 Ensure that the path is always set
We are using `path` unconditionally, but it can be conditionally filled.
To avoid inconsistent internal state, and a compiler warning, let's
assert that the variable is always set.
2017-12-05 11:07:46 +00:00
Emmanuele Bassi
66f7f1768f Fix the build
Use the right argument name in the preconditions check.
2017-12-05 11:02:20 +00:00
Matthias Clasen
4a11baa372 gdk: Documentation improvements 2017-12-04 23:52:48 -08:00
Matthias Clasen
4ab15a8292 docs: Drop some no longer existing functions 2017-12-04 23:15:06 -08:00
Matthias Clasen
b5c62cf86f Revert "clipboard: Add gdk_clipboard_set()"
This reverts commit dc50e0637f.

This broke the build.
2017-12-04 23:09:54 -08:00
Benjamin Otte
dc50e0637f clipboard: Add gdk_clipboard_set()
This API allows specifying a GType and va_args of a value of that type
to set the clipboard contents. This massively simplifies setting weird
object types into the clipboard.
2 example patches included in this patch are the GtkTextBuffer and the
file list in the file chooser.

Using gobject-introspection, this should work without specifying the
type, so that you can literlally say
  clipboard.set ("Hello World")
or
  clipboard.set (pixbuf)
which is why I've also marked all other setters as (skip). They just
exist in C as wrappers for type safety reasons.
2017-12-05 05:29:03 +01:00
Benjamin Otte
4658d7ea54 dnd: Remove x/y coordinates from drag-data-received
This is in preparation of using input streams to show that these
coordinates aren't needed most of the time and can otherwise be saved
during GtkWidget::drag-drop.
2017-12-05 05:29:00 +01:00
Matthias Clasen
6f00c1b626 Expand the docs
Cross-reference the serializers.
2017-12-04 16:28:33 -08:00
Matthias Clasen
ddcd687617 Document gdk_content_provider_contents_changed 2017-12-04 16:08:32 -08:00
Matthias Clasen
91499d4b0e gdk: Expand the clipboard documentation 2017-12-04 16:06:02 -08:00
Matthias Clasen
77f0e678ec gdk: Fill in some blanks in the docs
This is just an initial cut; more work is needed.
2017-12-04 15:58:30 -08:00
Matthias Clasen
d5afb9e805 Add a long description for GdkTexture 2017-12-04 11:04:02 -08:00
Matthias Clasen
384a999032 Move GdkGrabStatus docs
This enum was the odd man out in the initialization docs.
Move it to GdkSeat where grabbing happens nowadays.
2017-12-04 10:36:19 -08:00
Matthias Clasen
edfb86fe10 Add new stuff to the gdk docs
Document all the things.
2017-12-04 10:32:17 -08:00
Matthias Clasen
5cc7bf5dbd Fix the gdk doc build
Some types don't exist anymore.
2017-12-04 10:03:23 -08:00
Timm Bäder
8619ff0744 switch: Remove unused variable 2017-12-04 18:35:48 +01:00
Benjamin Otte
2f12eb616a wayland: Initialize variable
Otherwise we get NULL-warnings when we try to use (read: unref) it.
2017-12-04 18:28:53 +01:00
Matthias Clasen
841eb45b66 actionbar: Add more docs for gtk_action_bar_get_revealed
This stops gtk-doc complaints.
2017-12-04 07:42:01 -08:00
Matthias Clasen
b912416be5 about dialog: Add some missing docs
gtk_about_dialog_set/get_system_information are new,
and were missing docs.
2017-12-04 07:42:01 -08:00
Matthias Clasen
5c1a46c149 docs: Remove gtk_application_is_inhibited
It doesn't exist anymore.
2017-12-04 07:42:01 -08:00
Timm Bäder
93df23d962 Remove some more gtk_widget_get_content_size uses 2017-12-04 12:42:52 +01:00
Timm Bäder
1ed364a000 widgetbowl: Add some more widget types 2017-12-04 12:24:33 +01:00
Timm Bäder
78832732c4 testswitch: Remove unnecessary gtk_widget_show calls 2017-12-04 12:24:27 +01:00
Timm Bäder
3a3783dfcd image: Stop using gtk_widget_get_content_size 2017-12-04 12:24:18 +01:00
Timm Bäder
dbc4796d6a popover: Stop using gtk_widget_get_content_size 2017-12-03 22:05:15 +01:00
Timm Bäder
7cc9bee7a2 spinner: Stop using gtk_widget_get_content_size 2017-12-03 22:04:59 +01:00
Benjamin Otte
52b1cd40d1 gsk: Remove gsk_render_node_set_scaling_filters()
This is a leftover from the very early rendernode that we forgot to delete.

This can be seen by the fact that it is settable on an immutable object.
2017-12-03 21:57:21 +01:00
Piotr Drąg
794a2bfd00 Use Unicode quotation marks in new strings
See https://developer.gnome.org/hig/stable/typography.html

https://bugzilla.gnome.org/show_bug.cgi?id=772371
2017-12-03 18:38:39 +01:00
Piotr Drąg
a5815ad5c6 Update POTFILES.in 2017-12-03 18:24:36 +01:00
Руслан Ижбулатов
bcc77e169c GDK W32: Remove stray debug code
I have no idea how this slipped into master (these two lines are not present
in the same commit that went into gtk-3-22).
2017-12-03 06:10:03 +00:00
Benjamin Otte
acee3809b3 dnd: Remove unused variables 2017-12-03 06:50:51 +01:00
Matthias Clasen
6ab72b2653 Remove GdkDragProtocol from the api
...together with apis that return it. We were not using this
information in GTK+ at all, so no need to provide it.
2017-12-03 06:41:08 +01:00
Matthias Clasen
8b1b9f8c55 Drop api that is only for unmanaged dnd
These functions are not needed as public api anymore.
2017-12-03 06:24:24 +01:00
Matthias Clasen
e74c46fc4e dnd: Handle rootwin drop in gdk
This lets us drop the only use of the drag protocol in gtk.
2017-12-03 06:22:25 +01:00
Matthias Clasen
6cfb55a396 dnd: Remove much of the unmanaged dnd 2017-12-03 06:17:42 +01:00
Benjamin Otte
ff577e6c2c wayland: Add primary clipboard subclass
I decided to put this in a custom subclass, because then I could keep
the whole gtk primary protocol self-contained.

The other option would have been reusing GdkWaylandClipboard, but that
didn't seem worth it, especially because that code needs to interact
with the DND machinery, while the primary doesn't.
2017-12-03 05:46:49 +01:00
Benjamin Otte
ef69daacdf wayland: Implement taking over the clipboard
The clipboard is now complete.
That was fast.
2017-12-03 05:46:49 +01:00
Benjamin Otte
82002eabfe wayland: Implement reading the clipboard
We now keep track of what's in the clipboard and allow people to read
its contents.
2017-12-03 05:46:49 +01:00
Benjamin Otte
00192266a1 wayland: Add skeleton for a GdkClipboardWayland
Creates the source file and a custom subclass and makes sure it's used
by GDK.
2017-12-03 05:46:49 +01:00
Benjamin Otte
437d70f569 gdk: Get rid of owner change events
They're unused now.
2017-12-03 05:46:49 +01:00
Benjamin Otte
2d5c82b4ec gtk: Remove GtkClipboard 2017-12-03 05:46:49 +01:00
Benjamin Otte
c8edc6ed58 icon-browser: Port to new clipboard 2017-12-03 05:46:49 +01:00
Benjamin Otte
c833b47b21 gtk-demo: Port to GdkClipboard 2017-12-03 05:46:49 +01:00
Benjamin Otte
18bf0eb61a clipboard: Change image convenience APIs
Don't use pixbufs anymore, use textures.
2017-12-03 05:46:49 +01:00
Benjamin Otte
a34836f35b gdk: Add (de)serializers for GDK_TYPE_TEXTURE
We want to use textures more, so we should be able to use them for
copy/paste and dnd.
2017-12-03 05:46:49 +01:00
Benjamin Otte
ead67a7c17 x11: Handle case where clipboard was reclaimed quickly
When the reply to a TARGETS request comes in, the clipboard may already
be reclaimed by the local app. Deal with that case (in an ugly way,
strictly speaking we should use a cancellable here).

This happens for example at startup when the initial TARGETS requests
have not been answered until after the main widow popped up. And if such
a window immediately claims the primary clipboard (like when the initial
focus is inside an entry), this race will happen.
2017-12-03 05:46:49 +01:00
Benjamin Otte
24c934f8c0 entry: Port to GdkClipboard 2017-12-03 05:46:49 +01:00
Benjamin Otte
5abd7a39a2 x11: Implement storing the clipboard 2017-12-03 05:46:49 +01:00
Benjamin Otte
b75546d0fb x11: Implement MULTIPLE requests 2017-12-03 05:46:48 +01:00
Benjamin Otte
3ea258de26 tests: Don't crash if widgets go away before clipboard
Don't g_signal_connect() to the clipboard without protection - the
clipboard might outlast you and still emit signals.
2017-12-03 05:46:48 +01:00
Benjamin Otte
ea18793965 x11: Introduce GdkX11PendingSelectionNotify
This object tracks the SelectionNotifyEvent that has to be sent in
response to a SelectionRequest.

Currently it just looks like code reshuffling, but it's a prerequisite
for handling MULTIPLE, which requires to only send the notify after
every stream has writtten at least once.

But anyway, code is cleaner now, so it's a win!
2017-12-03 05:46:48 +01:00
Benjamin Otte
bcc0d4b5f0 x11: Split out a function
This will be necessary for MULTIPLE handling.
2017-12-03 05:46:48 +01:00
Benjamin Otte
0ff3340da7 main: Implement storing all clipboards 2017-12-03 05:46:48 +01:00
Benjamin Otte
4cce109e16 application: Put shared code into a common function 2017-12-03 05:46:48 +01:00
Benjamin Otte
fe7c283aea clipboard: Add infrastructure to store clipboards
Clipboard managers will be so happy once the backends actually implement
it!
2017-12-03 05:46:48 +01:00
Benjamin Otte
51e46cc898 contentprovider: Add ref_storable_formats()
This is to be used for advocating to clipboard managers.
2017-12-03 05:46:48 +01:00
Benjamin Otte
ca96fac488 filechooserwidget: Port to new clipboard
We use the new GDK_TYPE_FILE_LIST here.
2017-12-03 05:46:48 +01:00
Benjamin Otte
6b326b14c0 gdk: Add GDK_TYPE_FILE_LIST with serializers
This is a GSList of GFile and we want it so we can operate with lists of
files and text/uri-list.

I chose GSList over GList because that's what the GtkFileChooser API
uses, too.
2017-12-03 05:46:48 +01:00
Benjamin Otte
928c98a84e gdk: Add serializers and deserializers for GFile
in particular, support:
GFile <=> text/uri-list
GFile  => text/plain
2017-12-03 05:46:48 +01:00
Benjamin Otte
39d4622563 tests: Improve formats list for testclipboard2 2017-12-03 05:46:48 +01:00
Benjamin Otte
5632d0eabb label: Port to new clipboard 2017-12-03 05:46:48 +01:00
Benjamin Otte
f53848c360 textview: Redo clipboard handling
Instead of using GtkClipboard and handling everything ourselves, we now
put GtkTextBuffer into the GdkClipboard and register (de)serializers for
text/plain.
2017-12-03 05:46:48 +01:00
Benjamin Otte
4e06aaeaa8 gdk: Add gdk_content_formats_new_for_gtype()
Many places create formats for a single tpye, so make it easy for them
to get this without having to create a builder first.
2017-12-03 05:46:48 +01:00
Benjamin Otte
cc07800570 gdk: Allow setting task data on (de)serializers
This mirrors GTask.
2017-12-03 05:46:48 +01:00
Benjamin Otte
c146132a4a gtk-demo: Port clipboards example to new clipboard 2017-12-03 05:46:48 +01:00
Benjamin Otte
8cd5e0af1a recentchooser: Port to GdkClipboard 2017-12-03 05:46:48 +01:00
Benjamin Otte
909b6877bd linkbutton: Port to GdkClipboard 2017-12-03 05:46:48 +01:00
Benjamin Otte
825612b419 a11y: Port to GdkClipboard 2017-12-03 05:46:47 +01:00
Benjamin Otte
54c8a4b3b7 widget: Add gtk_widget_get_clipboard()
... and gtk_widget_get_primary_clipboard().

They both give out the new GdkClipboard.
2017-12-03 05:46:47 +01:00
Benjamin Otte
a59572f96d widget: gtk_widget_get_clipboard => gtk_widget_get_old_clipboard
Just rename the function, so the previous one can be used for the
new clipboard.
2017-12-03 05:46:47 +01:00
Benjamin Otte
6fffa5b171 tests: Open a 2nd display in testclipboard2
This allows testing local transfer of data as well as remote transfer
(by transferring data between clipboards of both Displays).
2017-12-03 05:46:47 +01:00
Benjamin Otte
134076e738 x11: Implement claiming the X Selection with the clipboard
... and of course support writing to other apps.
2017-12-03 05:46:47 +01:00
Benjamin Otte
e2014850b9 tests: Add possibility to set invalid UTF-8 and clear clipboard 2017-12-03 05:46:47 +01:00
Benjamin Otte
c66a61d896 x11: Add gdk_x11_display_get_max_request_size()
There's multiple places in the clipboard code where I need it, so make
it a custom function.
2017-12-03 05:46:47 +01:00
Benjamin Otte
8e132ef0c4 clipboard: Allow claiming the clipboard to fail
Also make clipboard_claim() a vfunc so backends can override it.

Because the whole operation a vfunc, backends have the option of adding
code before the actual claim is done and potentially even fail or do
something after the successful claim.
2017-12-03 05:46:47 +01:00
Benjamin Otte
7426f1a16b gdkcontentformats: Change the matching API
Instead of having just one function that has the gtype and mime type as
out arguments, have 3 functions: 1 that finds any match, 1 that finds a
GType match and one for a mime type match.

This makes the API way more convenient to use.
2017-12-03 05:46:47 +01:00
Benjamin Otte
25c3895836 clipboard: Add serialization
This completes the local clipboard code.
2017-12-03 05:46:47 +01:00
Benjamin Otte
12ca641ff5 clipboard: Implement local fallback clipboard transfers
This requires implementing a "pipe" so we can have 2 streams running:
  contentprovider => serializer => outputstream
  inputstream => deserializer => reader
And the pipe shoves the data from the outputstream into the inputstream.
2017-12-03 05:46:47 +01:00
Benjamin Otte
888e5257e0 clipboard: Introduce GdkContentProvider
GdkContentProvider is the object that represents local data in the
clipboard.

This patch only introduces the object and adds the clipboard properties,
it does not yet provide a way for the actual implementations to access
it.

The only access that is implemented is the local shortcut GValue access.
2017-12-03 05:46:47 +01:00
Benjamin Otte
3023d254dd clipboard: Make value getters set the passed in value
Don't return a const GValue, that's ugly API. Instead require people to
pass in a preinitialized GValue and set that one.
2017-12-03 05:46:47 +01:00
Benjamin Otte
9b78d76873 x11: Improve fallbacks for text
(1) Try all passed in formats in order if one of them fails.
(2) Don't blindly accept all formats, make sure they are mime types
(3) Add a bunch of special non-mime types that plug converters to
    get to mime types
2017-12-03 05:46:46 +01:00
Benjamin Otte
88684baecf clipboard: Add gdk_clipboard_read_text_async()
Also add deserializers for G_TYPE_STRING.
2017-12-03 05:46:28 +01:00
Benjamin Otte
02d1f90d13 clipboard: Add gdk_clipboard_read_pixbuf_async() 2017-12-03 05:46:28 +01:00
Benjamin Otte
91910ba013 gdk: Im[plement content deserializing
Add infrastructure to do GInputStream => GType conversions. Use that to
implement gdk_clipboard_read_value() which reads into GValues.
2017-12-03 05:46:27 +01:00
Benjamin Otte
970cb100af x11: Improve debugging output for selection input stream 2017-12-03 05:46:27 +01:00
Benjamin Otte
41f70e18af clipboard: Refactor gdk_clipboard_read() to be async
This allows us not just to pass any mime type to the read function, but
it also makes it possible to pass multiple mime types and the clipboard
can then try them in order until it finds a supported one.

This is so far not implemented though.
2017-12-03 05:46:26 +01:00
Benjamin Otte
516f35b865 x11: Use async queue and implement sync reads on selections stream
Turns out, way too many async operations are implemented by running the
sync operation in a thread. The easiest solution is to support that is
to use a GAsyncQueue for the buffers and deadlock if called from the
main thread.
2017-12-03 05:43:24 +01:00
Benjamin Otte
3506ae6085 tests: Add a new test app for GdkClipboard 2017-12-03 05:43:24 +01:00
Benjamin Otte
c91a38b013 clipboard: Implement gdk_clipboard_read() 2017-12-03 05:43:24 +01:00
Benjamin Otte
13fb3fd4a0 x11: Implement INCR reads 2017-12-03 05:43:24 +01:00
Benjamin Otte
fe9045d82e x11: Various clipboard cleanups
(1) Turn X11 clipboard event handling into a regular filter function
(2) Maintain a timestamp in the clipboard, so we can pass it when
    querying selections.
2017-12-03 05:43:24 +01:00
Benjamin Otte
a5ab9a9671 clipboard: Add gdk_clipboard_claim_remote()
This allows the remote clipboard to take over. The X11 clipboard already
does that.
2017-12-03 05:43:24 +01:00
Benjamin Otte
4728dd0a9e x11: Add an initial clipboard implementation
This does nothing but download the targets and debug-print them.
2017-12-03 05:43:24 +01:00
Matthias Clasen
e94b9b9a62 gdk: A GdkClipboard API draft
This commit adds a GdkClipboard object which is intended to
replace GtkClipboard, eventually.
2017-12-03 05:43:24 +01:00
Руслан Ижбулатов
174a36257f GDK W32: Plug a resource leak
Ensure that surfaces allocated in the impl are destroyed in finalize()

https://bugzilla.gnome.org/show_bug.cgi?id=787089
2017-12-03 03:19:02 +00:00
Piotr Drąg
4198434261 Update Polish translation 2017-12-02 18:45:33 +01:00
Benjamin Otte
481c6ad99a dnd: Add gtk_drag_set_icon_texture() 2017-12-02 16:21:58 +01:00
Benjamin Otte
20de4c86ad selection: Add texture getter/setter 2017-12-02 16:21:58 +01:00
Benjamin Otte
85b3f6d372 image: Add gtk_image_new_from_texture()
Docs and header knew about this function.
There just was no implementation.
2017-12-02 16:21:58 +01:00
Benjamin Otte
373848f561 image: Store pixbufs as textures, not surfaces 2017-12-02 16:21:58 +01:00
Benjamin Otte
9048d40bc2 vulkan: Fix mask shader to premultiply color
The inColor wasn't premultiplied, so the resulting colors were wrong
with translucent borders.
2017-12-02 16:21:58 +01:00
Benjamin Otte
abc8d61730 vulkan: Fix border shader to premultiply color
The inColor wasn't premultiplied, so the resulting colors were wrong
with translucent borders.
2017-12-02 16:21:58 +01:00
Руслан Ижбулатов
ae76d19663 GDK W32: Remove an unnecessary type check
No idea why it's here, the hash table can store any kind of data,
there's no reason why it wouldn't be able to store an old X string type.
Might be a holdout from the old days, when strings were handled in
a special way (stored directly in the clipboard?).

https://bugzilla.gnome.org/show_bug.cgi?id=786509
2017-12-02 10:38:42 +00:00
Руслан Ижбулатов
c89c19d2f9 GDK W32: Make sure drag source window is not NULL
This prevents GTK from throwing a bunch of warnings when it tries
to get drag source window -> screen of that window -> ipc widget for that screen,
and then tries to attach a signal handler to that widget.

Specifically, this happens when we get a DnD move from another
application.

https://bugzilla.gnome.org/show_bug.cgi?id=786509
2017-12-02 10:38:41 +00:00
Руслан Ижбулатов
f0d04f82f8 GDK W32: Special handling for DELETE requests
1) Ensure that any DELETE requests from the target are sent to GDK, even if
   both the source and the target are in the same process and it
   is therefore possible to use a shortcut and call the handler directly
   in GTK layer
2) Ensure that target GDK doesn't do anything when GTK asks it to send
   a DELETE request, just report back immediately (the code up the stack
   does not check for successfullness when request is DELETE, so not giving
   it any data is OK).

The source code already synthesizes a DELETE request, so that side is
also taken care of.

https://bugzilla.gnome.org/show_bug.cgi?id=786509
2017-12-02 10:38:40 +00:00
Руслан Ижбулатов
5e2e0af8b4 GDK W32: Preserve the target value for change_property()
We need to know the target atom value to know when we need to
do something with side-effects (since side-effects are expressed via
special target values). Previously, the code side-stepped that by looking
at the data type (which was rather unique for the one side-effect
target that we supported, signalled by the TARGETS target),
but for the DELETE target that seems to be no longer an option, hence the new
field to carry this information past the convert_selection() routine.

This prevents GDK from throwing a warning when trying to convert
a DELETE target, which has no format or data objects set.

The side-effects for the DELETE target happen earlier, in GTK layer.
By the point it gets to change_property(), it's a no-op.

https://bugzilla.gnome.org/show_bug.cgi?id=786509
2017-12-02 10:38:39 +00:00
Руслан Ижбулатов
44bc05df80 Fix a nefarious typo 2017-12-02 10:38:38 +00:00
Руслан Ижбулатов
5d0bfdd840 GDK W32: Ensure that selection request is processed
To do that, run the message loop for one second or until the side-effect
of running the selection request handler is achieved (as opposed to
running it until the event is no longer queued).

The disavantage of this method is that if the event handling is
somehow missed (due to a variety of reasons - after all, it's not
a straight path from an event being queued to property_change()
being called), this will loop for one second. Since we do process
events during that time, this will not hang the application, but
might still restrict some of the functionality.

https://bugzilla.gnome.org/show_bug.cgi?id=786509
2017-12-02 10:38:37 +00:00
Руслан Ижбулатов
a66017a6a0 GDK W32: Refuse to release mouse grab while in DnD mode
Handle WM_CANCELMODE and do nothing in response to it when DnD is
active. Otherwise pass it to DefWindowProc, which will call ReleaseCapture()
on our behalf.
This prevents us from losing mouse capture when alt-tabbing during DnD
(this includes the feature of Windows Explorer where dragging stuff over
a window button in the taskbar causes that window to receive focus, i.e.
keyboardless alt-tabbing).

https://bugzilla.gnome.org/show_bug.cgi?id=786509
2017-12-02 10:38:36 +00:00
Руслан Ижбулатов
6d37ed6256 GDK W32: Update layered windows on opacity changes
Without this patch layered windows are only updated when they are moved
by the user or then their contents changes. This patch adds opacity
changes to the list of things that make GDK update a window. Without this
windows that don't redraw and are not moved by the used (DnD drag indicator
windows, for example) don't change their opacity.

(This commit is cherry-picked from the gtk-3-22 branch)

https://bugzilla.gnome.org/show_bug.cgi?id=786509
2017-12-02 10:38:35 +00:00
Руслан Ижбулатов
6c29e81051 W32: Massive W32 DnD fix
Massive changes to OLE2 DnD protocol, which was completely broken before:
* Keep GdkDragContext and OLE2 objects separate (don't ref/unref them
  together, don't necessarily create them together).
* Keep IDataObject formats in the object itself, not in a global variable.
* Fix getdata() to look up the request target in its format list, not in the
  global hash table
* Create target GdkDragContext on each drag_enter, destroy it on drag_leave,
  whereas IDropTarget is created when a window becomes a drag destination
  and is re-used indefinitely.
* Query the source IDataObject for its supported types, cache them in the
  target (!) context. This is how GTK+ works, honestly.
* Remember current_src_object when we initiate a drag, to be able
  to detect later on that the data object is ours and use a
  shortcut when querying targets
* Make sure GDK_DRAG_MOTION is only sent when something changes
* Support GTK drag cursors
* Ensure that exotic GTK clipboard formats are registered
  (but try to avoid registering formats that can't be used between applications).
* Don't enumerate internal formats
* Ensure that DnD indicator window can't accept drags or receive any kind of input
  (use WS_EX_TRANSPARENT).
* Remove unneeded indentation in _gdk_win32_dnd_do_dragdrop()
* Fix indentation in gdk_win32_drag_context_drop_finish()
* Remove obsolete comments in _gdk_win32_window_register_dnd()
* Check for DnD in progress when processing WM_KILLFOCUS, don't emit a grab
  break event in such cases (this allows alt-tabbing while DnD is in progress,
  though there may be lingering issues with focus after dropping...)
* Support Shell ID List -> text/uri-list conversion, now it's possible
  to drop files (dragged from Explorer) on GTK+ applications
* Explicitly use RegisterClipboardFormatA() when we know that the string
  is not in unicode. Otherwise explicitly use RegisterClipboardFormatW()
  with a UTF8->UTF16 converted string
* Fix _gdk_win32_display_get_selection_owner() to correctly bail
  when selection owner HWND is NULL (looking up GdkWindow for NULL
  HWND always succeeds and returns the root window - not the intended
  effect)
* More logging
* Send DROP_FINISHED event after DnD loop ends
* Send STATUS event on feedback
* Move GetKeyboardState() and related code into _gdk_win32_window_drag_begin(),
  so that it's closer to the point where last_pt and start_pt are set
* Use & 0x80 to check for the key being pressed. Windows will set low-order bit
  to 1 for all mouse buttons to indicate that they are toggled, so simply
  checking for the value not being 0 is not enough anymore.
  This is probably a new thing in modern W32 that didn't exist before
  (OLE2 DnD code is old).
* Fixed (hopefully) and simplified HiDPI parts of the code.

Also adds managed DnD implementation for W32 GDK backend (for both
OLE2 and LOCAL protocols). Mostly a copy of the X11 backend code, but
there are some minor differences:
* doesn't use drag_window field in GdkDragContext,
  uses the one in GdkWin32DragContext exclusively
* subtracts hotspot offset from the window coordinates when showing
  the dragback animation
* tries to consistently support scaling and caches the scale
  in the context
* Some keynav code is removed (places where grabbing/ungrabbing should
  happen is marked with TODOs), and the rest is probably inert.

Also significantly changes the way selection (and clipboard) is handled
(as MSDN rightly notes, the handling for DnD and Clipboard
 formats is virtually the same, so it makes sense to handle
 both with the same code):
* Don't spam GDK_OWNER_CHANGE, send them only when owner
  actually changes
* Open clipboard when our process becomes the clipboard owner
  (we are doing it anyway, to empty the clipboard and *become* the owner),
  and then don't close it until a scheduled selection request event
  (with TARGETS target) is received. Process that event by announcing
  all of our supported formats (by that time add_targets() should have
  been called up the stack, thus the formats are known; just in case,
  add_targets() will also schedule a selection request, if one isn't
  scheduled already, so that late-coming formats can still be announced).
* Allow clipboard opening for selection_convert() to be delayed if it
  fails initially.
* The last two points above should fix all the bugs about GTK+ rising
  too much ruckus over OpenClipboard() failures, as owner change
  *is allowed* to fail (though not all callers currently handle
  that case), and selection_convert() is asynchronous to begin with.
  Still, this is somewhat risky, as there's a possibility that the
  code will work in unexpected ways and the clipboard will remain open.
  There's now logging to track the clipboard being opened and closed,
  and a number of failsafes that try to ensure that it isn't kept open
  for no reason.
* Added copious notes on the way clipboard works on X11, Windows and GDK-W32,
  also removed old comments in DnD implementation, replaced some of them
  with the new ones
* A lot of crufty module-global variables are stuffed into a singleton
  object, GdkWin32Selection. It's technically possible to make it a
  sub-object of the Display object (the way Wayland backend does),
  but since Display object on W32 is a singleton anyway... why bother?
* Fixed the send_change_events() a bit (was slightly broken in one of the
  previous iterations)
* Ensure that there's no confusion between selection conversion (an artifact
  term from X11) and selection transmutation (changing the data to be W32-compatible)
* Put all the transmutation code and format-target-matching code into gdkselection-win32.c,
  now this code isn't spread across multiple files.
* Consequently, moved some code away from gdkproperty-win32.c and gdkdnd-win32.c
* Extensive format transmutation checks for OLE2 DnD and clipboard.
  We now keep track of which format mappings are for transmutations,
  and which aren't (for example, when formats are passed as-is, or when
  a registered name is just an alias)
* Put transmutation code into separate functions

* Ensure that drop target keeps a format->target map for supported formats,
  this is useful when selection_convert() is called, as it only receives a
  single target and no hints on the format from which the data should
  be transmuted into this target.
* Add clear_targets() on W32, to de called by GTK
* Use g_set_object() instead of g_ref_object() where it is allowed.
* Fix indentation (and convert tabs to spaces), remove unused variables

(This commit is cherry-picked from the gtk-3-22 branch)

https://bugzilla.gnome.org/show_bug.cgi?id=786509
2017-12-02 10:38:34 +00:00
Руслан Ижбулатов
3237c2172a GDK W32: Don't leak the atom name string
https://bugzilla.gnome.org/show_bug.cgi?id=786509
2017-12-02 10:38:33 +00:00
Руслан Ижбулатов
c4617d3268 GDK W32: Fix a typo in OLE2 DnD code
https://bugzilla.gnome.org/show_bug.cgi?id=786509
2017-12-02 10:38:32 +00:00
Руслан Ижбулатов
6a770517cc Only register application/x-rootwindow-drop on X11
application/x-rootwindow-drop is not useful anywhere else,
so put it under #ifdef GDK_WINDOWING_X11

On W32 this prevents toplevels from automatically becoming valid
drop targets with a useless drop type.

(This commit is cherry-picked from the gtk-3-22 branch)

https://bugzilla.gnome.org/show_bug.cgi?id=786509
2017-12-02 10:38:31 +00:00
Руслан Ижбулатов
33de691d9f GDK W32: More flexible modal operation mode
Instead of using a boolean to indicate a modal operation being in progress,
use a set of flags, and allow these to be set and unset independently.

Specifically, this allows WM_CAPTURECHANGED handler to only act when a drag-move or
drag-resize modal operation is in progress, and ignore DND (which can also cause
WM_CAPTURECHANGED to be posted). This avoids a crash due to assertion failure when
OLE2 DND code tries to end a modal operation that was already ended by the WM_CAPTURECHANGED
handler.

(This commit is cherry-picked from the gtk-3-22 branch)

https://bugzilla.gnome.org/show_bug.cgi?id=786121
2017-12-02 10:38:30 +00:00
Руслан Ижбулатов
323a601123 GDK W32: fix monitor pruning code
Decrement the counter for each removed element, otherwise we skip
one element every time we remove one. Also, no need for continue here.
2017-12-02 10:38:29 +00:00
Руслан Ижбулатов
50bbac6005 GDK W32: Correctly report window position in HiDPI mode
Window position returned by get_frame_extents() should be scaled.

Also take this opportunity to apply the same rounding that X11 backend
applies.

https://bugzilla.gnome.org/show_bug.cgi?id=788053
2017-12-02 10:38:28 +00:00
Chun-wei Fan
eb6d5b6b27 GDK-Win32: Fix AeroSnap on HiDPI
Commit 1d0fad3 revealed that there were some assumptions made that were
actually to compensate for the bug fixed by that commit, so we need to
remove those assumptions as they would result in AerSnap to not work
properly on HiDPI screens.

Also re-do how we set the x and y positions of our GdkWindow, so that we
are more consistent across the board when we go between a GDK window
coordinate and a Windows API window cooredinate.

This would also simplify the code a bit.

https://bugzilla.gnome.org/show_bug.cgi?id=785999
2017-12-02 10:38:27 +00:00
Руслан Ижбулатов
d7e2017c28 GDK W32: Handle drivers that do not send WT_CSRCHANGE after WT_PROXIMITY
Some drivers don't do that (not sure whether that is the correct behaviour
or not). Remember each WT_PROXIMITY with LOWORD(lParam) != 0 that we get,
then look for a WT_CSRCHANGE. If WT_CSRCHANGE doesn't come, but a WT_PACKET
does, assume that this device is the one that sent WT_PROXIMITY.

Also include fallback code to ensure that WT_PACKETs for an enabled device
disable the system pointer, because WT_PROXIMITY handler might have
enabled it by mistake, since it's not possible to know which device left
the proximity (it might have been a disabled device).

https://bugzilla.gnome.org/show_bug.cgi?id=778328
2017-12-02 10:38:26 +00:00
Руслан Ижбулатов
3c9b667d3e GDK W32: Apply HiDPI scale properly to monitors
Previously HiDPI scale was retrieved and applied too late in the initialization
process to affect monitor size and monitor workarea size, but the code that
initializes these sizes *did* try to use the scale, even though it was always
getting scale=1.

To fix this, move the too-late code into monitor enumeration routine.
This also fixes a probable semantic bug where width and height were divided
by scale, again.

Now monitor and workarea should be in application pixels (i.e. divided by scale),
as intended.

https://bugzilla.gnome.org/show_bug.cgi?id=778835
2017-12-02 10:38:25 +00:00
Руслан Ижбулатов
27ed9fb11d GDK W32: Different maximized window position for non-CSD windows
It seems that WM interprets the same MINMAXINFO contents differently
depending on which styles the window has. Play along.

https://bugzilla.gnome.org/show_bug.cgi?id=765161
2017-12-02 10:38:24 +00:00
Руслан Ижбулатов
58ba4d6a3e GDK W32: Ensure that we use made-up monitors when there are none
Previously GDK only made up monitors when it initially found none. Now it
also makes up monitors when it initially finds some, but later fails to get
their informatin in a normal way and finally prunes them out, being left with
zero monitors.

Having zero-length monitor array is unexpected and causes a number
of critical warnings and some critical functionality (such as displaying
drop-down menus) fails in such cases.

Ideally, there might be such a way to interrogate W32 API that produces the
information about non-real (but active) monitors out of it so that it isn't
necessary for us to make stuff up. However, this code is already complicated,
and i am not prepared to dig W32 API to find a way to do this.

This fixes the issues people had when they accessed a Windows desktop via RDP.

https://bugzilla.gnome.org/show_bug.cgi?id=777527
2017-12-02 10:38:23 +00:00
Руслан Ижбулатов
f7ae36739a GDK W32: Fix idiotic gdk_win32_display_get_monitor() implementation
Replace the code borrowed from the X11 backend with the code borrowed from Wayland backend. Now GTK doesn't crash when the number of monitors is zero.
2017-12-02 10:38:22 +00:00
Руслан Ижбулатов
c36d66bdb6 GDK W32: Use keyboard hook to detect AeroSnap combinations better
Windows WM handles AeroSnap for normal windows on keydown. We did this
on keyup only because we do not get a keydown message, even if Windows WM
does nothing with a combination. However, in some specific cases it DOES
do something - and we have no way to detect that. Specifically, winkey+downarrow
causes maximized window to be restored by WM, and GDK fails to detect that. Then
GDK gets a keyup message, figures that winkey+downarrow was pressed and released,
and handles the combination - by minimizing the window.

To overcome this, install a low-level keyboard hook (high-level ones have
the same problem as normal message loop - they don't get messages when
Windows WM handles combinations) and use it to detect interesting key combinations
before Windows WM has a chance to block them from being processed.

Once an interesting combination is detected, post a message to the window, which
will be handled in due order.

It should be noted that this code handles key repetitions in a very crude manner.

The downside is that AeroSnap will not work if hook installation function call fails.
Also, this is a global hook, and if the hook procedure does something wrong, bad things
can happen.

https://bugzilla.gnome.org/show_bug.cgi?id=776031
2017-12-02 10:38:21 +00:00
Руслан Ижбулатов
cba75d8239 GDK W32: Handle CapsLock as part of the key shift level
Instead of using some kind of flawed logic about modifying a keypress result
when CapsLock is toggled, just add a CapsLock shift level (and all derived
shift levels, i.e. Shift+CapsLock and CapsLock+AltGr and Shift+CapsLock+AltGr)
and query Windows keyboard layout API about the result of keypresses involving
CapsLock.

Keysym table is going to be (roughly) twice as large now, but CapsLock'ed
keypresses will give correct results for some keyboard layouts (such as
Czech keyboard layout, which without this change produces lowercase letters
for CapsLock->[0,2,3,4...] instead of uppercase ones).

Keymap update time also increases accordingly.

https://bugzilla.gnome.org/show_bug.cgi?id=165385
2017-12-02 10:38:20 +00:00
Руслан Ижбулатов
33442d953d GDK W32: Special handling for VK_PAUSE
Similar to VK_DIVIDE, this key can't be mapped to a scancode by
MapVirtualKeyEx(). Googling suggests that this is a known bug.

https://bugzilla.gnome.org/show_bug.cgi?id=769214
2017-12-02 10:38:19 +00:00
Руслан Ижбулатов
e1240b42ed GDK W32: Change WM_SYSMENU style switch logic
Instead of checking for window state and giving it extra styles that
fit, just give it all styles that it is missing. It turned out that
otherwise it is impossible to, for example, restore a maximized window
via sysmenu. Also, be more flexible towards GDK/WM window state mismatches
and consider the window minimized/maximized if *either* GDK or WM thinks so.

https://bugzilla.gnome.org/show_bug.cgi?id=776485
2017-12-02 10:38:19 +00:00
Руслан Ижбулатов
9e5fc16307 GDK W32: Remove unneeded assertion
Just set check_for_dpi_awareness = TRUE and eventually it will be handled
correctly, even if setDpiAwareFunc() returns E_ACCESSDENIED or shcore functions
are NULL.

https://bugzilla.gnome.org/show_bug.cgi?id=777031
2017-12-02 10:38:18 +00:00
Руслан Ижбулатов
285ebd58a8 GDK W32: Handle maximizing correctly for small primary monitors
When primary monitor is smaller than the actual monitor on which the
window is being maximized, the WM will do widnow size adjustments
that will completely screw the window size if we try to make it
smaller than 100% fullscreen (to account for taskbar size, for example).

Fix this by overriding maximized window size during WM_WINDOWPOSCHANGING.

https://bugzilla.gnome.org/show_bug.cgi?id=775808
2017-12-02 10:38:17 +00:00
Руслан Ижбулатов
c7bdf643c5 GDK: Make sure W32 backend compiles without GdkDeviceManager
https://bugzilla.gnome.org/show_bug.cgi?id=773299
2017-12-02 10:37:23 +00:00
Carlos Garnacho
645e67231e gtkeventcontrollerscroll: Add some docs 2017-12-02 00:29:37 +01:00
Matthias Clasen
7fcd3bee0d Add GtkEventControllerScroll to the docs
It is not actually documented yet, unfortunately.
2017-12-01 14:17:04 -08:00
Matthias Clasen
6241ae009e docs: Some revision to the migration docs
Cover more of the recent changes, and revise some of the wording.
2017-12-01 11:51:53 -05:00
Matthias Clasen
4930153413 Finish conversion of pixbuf cell renderer icon size
Change the name of the property from stock-size to icon-size,
and make it an enum property instead of uint. This makes it
impossible to specify invalid numeric values in ui files, and
at the same time makes it possible to refer to the existing
values by their nick.

Fix up the callers.
2017-12-01 10:36:17 -05:00
Matthias Clasen
1c59db9bff placesview: Drop the word stock from the docs
It does not really add anything here, and makes it harder
to grep for occurrences of stock ids.
2017-12-01 10:30:21 -05:00
Matthias Clasen
77d12c0451 recent chooser: Stop specifying stock-size
We were using a no-longer-existing numeric value here,
and we can just rely on the theme to set this now.
2017-12-01 10:30:21 -05:00
Matthias Clasen
dc12dc4495 toolbutton: Remove the word stock from internal docs
We no longer support stock items.
2017-12-01 10:30:20 -05:00
Matthias Clasen
60c3afe0fe recent chooser: Remove the word stock from the docs
We don't support stock items anymore.
2017-12-01 10:30:20 -05:00
Matthias Clasen
86ae1df257 filechooser: Remove the word stock from the docs
It does not really add anything here, and makes it harder
to grep for occurrences of stock ids.
2017-12-01 10:30:20 -05:00
Matthias Clasen
8c95071eea entry: Remove references to stock ids from the docs
We no longer support stock images.
2017-12-01 10:30:20 -05:00
Matthias Clasen
6de5cd57e7 image definition: Drop unused struct
We no longer support stock images.
2017-12-01 10:30:20 -05:00
Matthias Clasen
2218020db9 Fix the doc tools build 2017-12-01 10:30:11 -05:00
Matthias Clasen
b9035fc3a6 widget-factory: Fix up icon size handling
Make the icon grid on page 2 work with our new
approach to icon sizes.
2017-12-01 10:29:53 -05:00
Alexander Larsson
478b1d56f8 Revert "gtksnapshot: Merge trivial clip duplicates"
This reverts commit d95cbb2757.

This is better solved by commit 94184eda42
2017-12-01 09:08:57 +01:00
Timm Bäder
c42e026058 snapashot: Optimize rounded clip nodes
If the rounded clip node is rectilinear, we can simplify it to a normal
clip node. If not, we really need to use a rounded clip node. In both
cases, we can do the same check we do when collecting normal clips and
avoid the clip node altogether if the child node does not get clipped
anyway.

This saves between 3 and 10 nodes in the widget factory, depending on
what page gets rendered.
2017-12-01 08:14:01 +01:00
Timm Bäder
94184eda42 snapshot: Only create clip nodes if we need to
Clip nodes have a clip rect and we only need to actually create a clip
node if any child node gets clipped at all. If the clip rect conains the
child node bounds entirely, we don't need a clip node.
2017-12-01 07:38:43 +01:00
Timm Bäder
7b60ee9316 widgetbowl: Only use one widget type
Every added widget having a separate random widget type makes it useless
to use the widgetbowl demo for any sort of performance comparison.
Instead. use only one widget type for all the moving children but make
that changable.
2017-12-01 07:33:52 +01:00
Timm Bäder
dfc7a531db wayland: Never send NULL app id
The old gdk_get_program_class was never returning NULL, but
g_get_prgname might. So use the same fallback app id name we were using
before.
2017-12-01 07:30:25 +01:00
Timm Bäder
34e233e1c3 GskVulkanGlyphCache: Remove unused struct member 2017-12-01 07:30:25 +01:00
Timm Bäder
ff35fbf120 window: Plug a memory leak 2017-12-01 07:30:25 +01:00
Matthias Clasen
d005109133 Drop unused gtkcssstylefuncs.c
Clean up all the places where the header was still
included needlessly.
2017-11-30 18:46:54 -05:00
Matthias Clasen
eb32a2c228 css style funcs: Avoid pixbufs
We can get what we need with GdkTexture.
2017-11-30 17:40:41 -05:00
Matthias Clasen
dc15978ac8 Avoid GdkPixbuf in docs
GdkTexture is preferred now.
2017-11-30 17:32:05 -05:00
Matthias Clasen
a1c0b81bae icon helper: Avoid gratitious pixbuf use
We can just get the texture directly from the icontheme.
2017-11-30 17:31:17 -05:00
Matthias Clasen
029165638b mountoperation: Store icons as textures
This reduces the amount of pixbufs in this code.
2017-11-30 16:48:25 -05:00
Alexander Larsson
61ea8e8676 broadway: Add some (disabled) debugging tools 2017-11-30 21:57:42 +01:00
Alexander Larsson
af890e6677 broadway: Don't send node updates to browser if nothing changed 2017-11-30 21:57:42 +01:00
Alexander Larsson
d43008b2a5 broadway: Fix texture hash function 2017-11-30 21:57:42 +01:00
Alexander Larsson
d95cbb2757 gtksnapshot: Merge trivial clip duplicates
I got a lot of "clip in clip" cases, for example a CellClip with a
CellTextClip inside. It is really trivial to merge these when we
pop and makes it easier for all backends, so lets do that.
2017-11-30 21:57:42 +01:00
Alexander Larsson
f5e0986230 vulkan: Don't crash if vkEnumeratePhysicalDevices fails 2017-11-30 21:57:42 +01:00
Alexander Larsson
c30073793e broadway: Improve logging
We now log backwards, so that the latest is always visible.
Also, we use <pre> with a smaller size.
2017-11-30 21:57:42 +01:00
Alexander Larsson
521b09cc96 broadway: Send diffs of node trees
Reusing pre-created nodes is a lot faster both in terms of
dom modifications and of transfer sizes.
2017-11-30 21:57:42 +01:00
Alexander Larsson
3d4a9324e6 broadway: Add broadway_node_equal 2017-11-30 21:57:42 +01:00
Alexander Larsson
46c4869945 broadway: Prepare for implementing diff 2017-11-30 21:57:42 +01:00
Alexander Larsson
e43f031769 broadway: Add div for container nodes
We need this so that all nodes have divs, otherwise diffing is going
to be very hard.
2017-11-30 21:57:42 +01:00
Alexander Larsson
1820362b2b broadway: Deserialize node tree in server
This doesn't really change anything, but it is in preparation for diffing
the trees.
2017-11-30 21:57:42 +01:00
Alexander Larsson
907e071c90 broadway: Add a texture cache
This ensures we never upload a texture we already have locally available.
2017-11-30 21:57:42 +01:00
Alexander Larsson
d284c3fa85 broadway: Re-add seat and core device creation 2017-11-30 21:57:42 +01:00
Piotr Drąg
8cf2f3c3f1 Update POTFILES.in 2017-11-30 16:10:50 +01:00
Matthias Clasen
2edd3741f6 Use the new texture utils here
One less place where we juggle pixbufs.
2017-11-30 07:54:52 -05:00
Matthias Clasen
b8b33d1f36 Make texture variants of some pixbuf utils
This will let us avoid direct pixbuf use in some places.
2017-11-30 07:54:27 -05:00
Matthias Clasen
bd1a9c1afe recent manager: Drop an unused field 2017-11-30 07:03:20 -05:00
Matthias Clasen
a9f12892ea Fix up a doc comment 2017-11-29 23:39:06 -05:00
Matthias Clasen
f57aa47a40 Remove some unused includes
These show up in a grep for "pixbuf".
2017-11-29 23:39:06 -05:00
Matthias Clasen
b65f871929 Use a texture instead of a pixbuf in gtk_render_icon
This gets rid of more GdkPixbuf in the API.

Update all callers.
2017-11-29 23:30:47 -05:00
Matthias Clasen
0b39631464 textview: Replace pixbufs by textures
This affects a few apis, such as gtk_text_iter_get_pixbuf,
gtk_text_buffer_insert_pixbuf and GtkTextBuffer::insert-pixbuf,
which have all been replaced by texture equivalents.

Update all callers.
2017-11-29 23:22:13 -05:00
Benjamin Otte
3d4743ee62 textview: Remove serialization API
It's unused. Plain text is not using that framework, neither is
in-process same-display transmission.

So it was only useful for sharing text with custom tags across
applications, and nobody is doing that.
2017-11-29 23:03:33 -05:00
Benjamin Otte
138abdbc47 a11y: Remove AtkStreamableContent implementation
That is some old code that still uses IOChannels, and the only
pseudouser is at-spi-atk's commented out code that is still using
CORBA types.

So get rid of it now before I need to start adapting it to the new
clipboard.
2017-11-29 23:03:33 -05:00
Matthias Clasen
c088d69f93 icon theme: Remove unused code
The deprecated api to add builtin icons was removed
a year ago, so we don't need the code anymore that deals
with looking up builtin icons.
2017-11-29 22:25:57 -05:00
Matthias Clasen
0063145ed8 tooltip: Set icon from texture instead of pixbuf
Another part of removing GdkPixbuf from APIs.
2017-11-29 22:17:59 -05:00
Matthias Clasen
dfd194a5fa Drop gtk_cell_view_new_with_pixbuf
We have a texture-based alternative for this now.
2017-11-29 20:26:28 -05:00
Matthias Clasen
c750c0e571 Drop gdk_cursor_new_from_pixbuf
Part of the push to remove GdkPixbuf from the API.
2017-11-29 20:16:43 -05:00
Matthias Clasen
7217689e02 docs: Remove mentions of gdk_cursor_new_from_pixbuf
This function is going away.
2017-11-29 20:14:53 -05:00
Matthias Clasen
1fcfff6861 dnd: Stop using gdk_cursor_new_from_pixbuf
We can just use gdk_cursor_new_from_texture here.
2017-11-29 20:13:26 -05:00
Matthias Clasen
a8a156e63c Fix the build 2017-11-29 20:12:43 -05:00
Matthias Clasen
c2a38612a9 Drop gtk_drag_source_set_icon_pixbuf
Part of removing GdkPixbuf from the API.
2017-11-29 20:02:47 -05:00
Matthias Clasen
c51703be60 testdnd: Stop using gtk_drag_source_set_icon_pixbuf
We can avoid it here as well.
2017-11-29 20:02:01 -05:00
Matthias Clasen
c0d6fd4f86 icon-browser: Stop using gtk_drag_source_set_icon_pixbuf
We can just use gtk_drag_source_set_icon_name.
2017-11-29 20:01:32 -05:00
Matthias Clasen
2ac0df0b75 Drop gtk_css_image_surface_new_for_pixbuf
It is unused private api.
2017-11-29 19:47:57 -05:00
Matthias Clasen
8cdaaffd42 Avoid pixbufs when loading themed icons
We can directly get a texture from GtkIconTheme now.
2017-11-29 19:44:30 -05:00
Matthias Clasen
507ef68faa Add gtk_cell_view_new_with_texture
Just more api to replace pixbufs with textures.
2017-11-29 19:28:53 -05:00
Matthias Clasen
7b032a9862 Drop gtk_snapshot_render_icon
Its not used, and we are working towards removing
GdkPixbuf in the API.
2017-11-29 18:34:45 -05:00
Matthias Clasen
4db2426336 window: Stop using GdkPixbuf
We can get by with just using GdkTexture.
2017-11-29 17:28:15 -05:00
Matthias Clasen
83ab83043e Cosmetic formatting fixes 2017-11-29 17:28:15 -05:00
Christophe Fergeau
9259ca98f3 wayland: Fix indentation of previous commit 2017-11-29 12:21:19 +01:00
Christophe Fergeau
ff3da0818c wayland: emit GDK_SELECTION_CLEAR on owner changes
The wayland backend currently never emits GDK_SELECTION_CLEAR events.
GtkClipboard uses this signal in order to clear the clipboard owner when
the selection is set to something outside the application.
This commit ensures the wayland backend emits GDK_SELECTION_CLEAR before
setting the clipboard owner to NULL, as this means we lost the
selection.

Signed-off-by: Christophe Fergeau <cfergeau@redhat.com>

https://bugzilla.gnome.org/show_bug.cgi?id=790031
2017-11-29 11:29:30 +01:00
Christophe Fergeau
93f6f253ea wayland: Remove unused data structure
Signed-off-by: Christophe Fergeau <cfergeau@redhat.com>

https://bugzilla.gnome.org/show_bug.cgi?id=790031
2017-11-29 11:29:29 +01:00
Matthias Clasen
65808418e1 Drop gtk_application_is_inhibited
This function returns global session state that may
not be available to applications (e.g. in sandboxed
environments), and is not needed by applications,
so just drop it, instead of keeping a function around
that can't be guaranteed to work.
2017-11-28 23:02:58 -05:00
Matthias Clasen
4371f370bc Improve the docs
Document that gtk_application_is_inhibited can't
be guaranteed to work.
2017-11-28 22:52:44 -05:00
Benjamin Otte
4ebbb19e25 inspector: Reorganize stack
There are too many stack elements in the main stack. So add a substack
for the pages that display common global state. The appropriate name I
found for it was "Global".

It's used to house the General, Visual, Resources and Statistics pages
for now.
2017-11-29 04:22:53 +01:00
Benjamin Otte
c60df96deb inspector: remove visible=TRUE properties
This is the defualt these days.
2017-11-29 04:22:53 +01:00
Matthias Clasen
0dfe12fab0 gdk: Add some missing autocleanups
GdkMonitor and GdkSeat were missing here.
2017-11-28 15:03:48 -05:00
Rico Tzschichholz
2d797dd816 Fix some parameter name mismatches to make g-ir-scanner happier 2017-11-28 15:24:49 +01:00
Carlos Garnacho
cabfdd5c48 gdkseatdefault: Use TABLET_STYLUS capability for styli/erasers/cursors
Those are devices created for drawing tablets, so using the "pointer"
capability is far too generic.
2017-11-27 21:41:25 +01:00
Carlos Garnacho
7decad177c gdk/wayland: Emit GdkSeat::device-added/removed
Those were never sent in this backend...
2017-11-27 19:51:38 +01:00
Matthias Clasen
43e59258e4 Fix up _gtk_widget_list_devices
When I rewrote that function to not use GdkDeviceManager,
I overlooked that the window filtering needs to apply
to the master pointer as well, as other code assumes
that _gtk_widget_get_device_window will return non-NULL
on the devices in the list. Fix this.
2017-11-27 12:35:10 -05:00
Matthias Clasen
8747c7a42a Fix a typo
The signal is called ::unpaired-release.
2017-11-27 10:56:09 -05:00
Милош Поповић
2b14a82b72 Update Serbian translation 2017-11-27 10:38:07 +00:00
Matthias Clasen
268ebb3a46 listbox: Handle unpaired releases as well
Same as for flowbox in the previous commit.
2017-11-26 19:52:01 -05:00
Carlos Garnacho
0567b41f24 gtkflowbox: Activate items on ::unpaired-release
If the flowbox is single-click.

https://bugzilla.gnome.org/show_bug.cgi?id=789163
2017-11-26 19:42:03 -05:00
Carlos Garnacho
bce91555f5 gtkgesturemultipress: Add ::unpaired-release signal
This signal will be emitted whenever the gesture received a
button release or touch end event without a pairing button
press or touch begin. This usually happens when grabs transfer
input from one widget to another mid-press.

https://bugzilla.gnome.org/show_bug.cgi?id=789163
2017-11-26 19:42:03 -05:00
Matthias Clasen
b8c58f41b6 wayland: Don't provide gsetting if dconf is not available
This makes gtk+ fall back to reading ~/.config/gtk-3.0/settings.ini
on systems with Wayland, but without dconf (do those exist?).

https://bugzilla.gnome.org/show_bug.cgi?id=790201
2017-11-26 19:40:28 -05:00
Kjell Ahlstedt
7ef5858f8d GtkWindow: Fix the down-scaling in icon_from_list()
Must use floating-point division to get the correct scale factors.
cairo_set_source_surface() must be called after cairo_scale().

https://bugzilla.gnome.org/show_bug.cgi?id=790287
2017-11-26 18:54:59 -05:00
Piotr Drąg
70ff1ef216 Update POTFILES.in 2017-11-25 17:32:53 +01:00
Matthias Clasen
1884558470 wayland: Drop GdkWaylandDeviceManager
This object had no functionality left.
2017-11-25 11:04:15 -05:00
Matthias Clasen
05149a391f Drop GdkDeviceManager entirely
Nothing uses it anymore.
2017-11-25 11:04:15 -05:00
Matthias Clasen
7e40fcc344 Drop the ::device-manager property
Not used for anything anymore.
2017-11-25 11:04:15 -05:00
Matthias Clasen
bad53bc201 x11: Stop deriving from GdkDeviceManager
We can just derive from GObject.
2017-11-25 11:04:15 -05:00
Matthias Clasen
da8bcc7ed9 wayland: Stop deriving from GdkDeviceManager
We can just derive from GObject.
2017-11-25 11:04:15 -05:00
Matthias Clasen
01278e591c win32: Stop deriving from GdkDeviceManager
We can just derive from GObject.
2017-11-25 11:04:15 -05:00
Matthias Clasen
1471c64fb2 quartz: Stop deriving from GdkDeviceManager
We can just derive from GObject.
2017-11-25 11:04:15 -05:00
Matthias Clasen
fd958939be Drop the GdkDeviceManager::display property
Move this to the backends, and stop deriving
from GdkDeviceManager.
2017-11-25 11:04:15 -05:00
Matthias Clasen
7c33baabd2 Remove the get_client_pointer vfunc 2017-11-25 11:04:15 -05:00
Matthias Clasen
0ec491ea9d Drop the get_client_pointer vfunc
There is no api using this anymore.
2017-11-25 11:04:15 -05:00
Matthias Clasen
b6a634fe38 Drop the list_devices vfunc
We no longer have api that uses this.
2017-11-25 11:04:15 -05:00
Matthias Clasen
ecb96257b9 Drop gdk_device_manager_list_devices
It is not used and GdkDeviceManager is going away.
2017-11-25 11:04:15 -05:00
Matthias Clasen
30a037c4fe gdk: Drop devicemanager signals
Nobody is emitting them anymore.
2017-11-25 11:04:15 -05:00
Matthias Clasen
efbcb38fdf wayland: Stop emitting devicemanager signals
Nobody is listening to these signals anymore.
2017-11-25 11:04:15 -05:00
Matthias Clasen
c9261f50aa x11: Stop emitting devicemanager signals
Nobody is listening to these anymore, so there
is no point in emitting them.
2017-11-25 11:04:14 -05:00
Matthias Clasen
cd3d2badf0 display: Drop the device_manager for good
This is now entirely the backends responsibility.
2017-11-25 11:04:14 -05:00
Matthias Clasen
639d93687f wayland: Stop using display->device_manager
We can keep the device manager in the backend.
2017-11-25 11:04:14 -05:00
Matthias Clasen
95ae688072 quartz: Stop using display->device_manager
We can keep the device manager in the backend.
2017-11-25 11:04:14 -05:00
Matthias Clasen
ab0aea900c win32: Stop using gdk_display_get_device_manager
We can keep the devicemanager in the backend.
2017-11-25 11:04:14 -05:00
Matthias Clasen
aae4fafad2 x11: Stop using gdk_display_get_device_manager
We can keep the displaymanager in the backend.
2017-11-25 11:04:14 -05:00
Matthias Clasen
6489bc1929 broadway: Remove devicemanager implementation
It is not used and not needed anymore.
2017-11-25 11:04:14 -05:00
Matthias Clasen
1023249e31 broadway: Stop using GdkDeviceManager
We can use the GdkSeat apis for this.
2017-11-25 11:04:14 -05:00
Matthias Clasen
903959301b display: Stop using devicemanager internally
We can just use the seats to find out about device removals.
2017-11-25 11:04:14 -05:00
Matthias Clasen
1f6fb4e716 Drop GdkDeviceManager APIs
No longer used outside of the backends.
2017-11-25 11:04:14 -05:00
Matthias Clasen
a4cd4535dc Don't mention GdkDeviceManager in docs
It is going away.
2017-11-25 11:04:14 -05:00
Matthias Clasen
480ea400f3 Drop support for setting event masks for floating devices
These are very rarely needed, and are X11-specific.
If it turns out that somebody needs this, it can come
back as X11-specific functionality.
2017-11-25 11:04:14 -05:00
Matthias Clasen
4c40accbb9 gdk: Move gdk_disable_multidevice tot he X11 backend
This api only ever did something for X11, so move
it there. Update the docs and adapt the only caller.
2017-11-25 11:04:14 -05:00
Matthias Clasen
0cfc812a5d Drop gdk_display_get_device_manager API
GdkDeviceManager is being replaced by GdkSeat.
2017-11-25 11:04:14 -05:00
Matthias Clasen
835805ad61 treeview: Don't use GdkDeviceManager
We can just as well use GdkSeat to enumerate (attached)
devices. Note that this change excludes floating devices
from consideration.

This keeps the copy-pasted code in sync with gtkwindow.c
2017-11-25 11:04:14 -05:00
Matthias Clasen
7c0a1ddb05 window: Don't use GdkDeviceManager
We can just as well use GdkSeat to enumerate (attached)
devices. Note that this change excludes floating devices
from consideration.
2017-11-25 11:04:14 -05:00
Matthias Clasen
2250daeb53 widget: Don't use GdkDeviceManager
We can just as well use GdkSeat to enumerate the devices.
2017-11-25 11:04:13 -05:00
Matthias Clasen
c0d3ed0739 Fix the build
A stray GdkScreen leftover.
2017-11-25 11:02:29 -05:00
Matthias Clasen
371ea7cbe9 gdk: Remove a leftover GdkScreen 2017-11-25 10:17:19 -05:00
Matthias Clasen
9b582db492 gsk: Quiet a compiler warning
We insist on handling all cases in a switch, nowadays.
2017-11-24 08:51:22 -05:00
Daniel Boles
630f83957a Entry:show-emoji-icon is in GTK+ 3 too
Document the earliest version reached.
2017-11-23 17:21:36 +00:00
Daniel Boles
89c51f51e2 Be more specific in ::insert-emoji Since tag
I had been unsure whether to include the minor version, but
:show-emoji-icon already did, so do the same here to match.
2017-11-23 17:18:36 +00:00
Alexander Larsson
820f999f14 broadway: Disable fallback spew by default 2017-11-23 10:48:29 +01:00
Alexander Larsson
cfb76fedb6 broadway: Roundtrip each update to rate limit redraw 2017-11-23 10:48:29 +01:00
Alexander Larsson
12d3cd8f29 broadway: Handle cairo nodes
This means we can directly upload these as textures, rather than
create a new surface and draw it into that. We still have to upload,
but there isn't a lot we can do about this as for these nodes
we generally redraw everything each time.
2017-11-23 10:48:29 +01:00
Alexander Larsson
4d1eca0d57 broadway: Handle texture gsd nodes 2017-11-23 10:48:29 +01:00
Alexander Larsson
b74959a605 broadway: Add clip node 2017-11-23 10:48:29 +01:00
Alexander Larsson
7a180f554d broadway: Don't log cache hits 2017-11-23 10:48:29 +01:00
Alexander Larsson
0d4a26f148 broadway: Cache color translated textures
These happen a lot due to the recolored symbolics
2017-11-23 10:48:29 +01:00
Alexander Larsson
9e5a22bbe5 broadway: Add opacity node 2017-11-23 10:48:29 +01:00
Alexander Larsson
9b1f6acc2b broadway: Add shadow node 2017-11-23 10:48:29 +01:00
Alexander Larsson
cbbbf49043 broadway: Add node cache for text 2017-11-23 10:48:29 +01:00
Alexander Larsson
6cc96318c8 broadway: Remove inflate code
This is not used anymore
2017-11-23 10:48:29 +01:00
Alexander Larsson
278370c8e5 broadway: Add linear gradient node 2017-11-23 10:48:29 +01:00
Alexander Larsson
f7ff6dbb66 broadway: Add RoundedClip node 2017-11-23 10:48:29 +01:00
Alexander Larsson
0083c084e4 broadway: Add inset shadow 2017-11-23 10:48:29 +01:00
Alexander Larsson
35ceb8e626 broadway: Add outset shadow node 2017-11-23 10:48:29 +01:00
Alexander Larsson
0ad523038c broadway: Fix border node positioning 2017-11-23 10:48:29 +01:00
Alexander Larsson
cf03229a99 broadway: Add border node 2017-11-23 10:48:29 +01:00
Alexander Larsson
5a8d204c83 broadway: Clean up node parser 2017-11-23 10:48:29 +01:00
Alexander Larsson
0b38ab339e broadway: Add color nodes 2017-11-23 10:48:29 +01:00
Alexander Larsson
cfdb3952c6 broadway: Fix input events 2017-11-23 10:48:29 +01:00
Alexander Larsson
97c0d112af broadway: Don't swap node trees until all images are loaded 2017-11-23 10:48:29 +01:00
Alexander Larsson
fd0285de09 broadway: Rewrite textures in nodes to global 2017-11-23 10:48:29 +01:00
Alexander Larsson
54e7a8f0c0 broadway: Remove remaining unused window_update code 2017-11-23 10:48:29 +01:00
Alexander Larsson
f7d8ee041b broadway: Initial version of using actual render nodes 2017-11-23 10:48:29 +01:00
Alexander Larsson
cc7423855b broadway: Use textures to configure window contents
Instead of using the old buffer code, just use textures to define the
window contents.
2017-11-23 10:46:47 +01:00
Alexander Larsson
a4636a06a7 broadway: Actually upload textures to client 2017-11-23 10:46:47 +01:00
Alexander Larsson
ef79621c44 broadway: Introduce global ids for the textures 2017-11-23 10:46:47 +01:00
Alexander Larsson
48d587d255 broadway: Add support for uploading textures to daemon 2017-11-23 10:46:47 +01:00
Alexander Larsson
f31d7e1f91 broadway: Support fd passing in protocol
This will be used to pass buffers
2017-11-23 10:46:47 +01:00
Alexander Larsson
43a02da07b broadwayd: Read using socket API
This changes nothing, but it allows us to later recieve
unix messages and thus fd passing
2017-11-23 10:46:47 +01:00
Alexander Larsson
620d3cf402 broadway: Only support (non-abstract) sockets
We want to use fd passing, so drop tcp
2017-11-23 10:46:47 +01:00
Alexander Larsson
23845a57a9 broadway: Add GskBroadwayRenderer
This is a custom renderer for broadway windows, although at the
moment it doesn't really do anything other than the old cairo
fallbacks.
2017-11-23 10:46:47 +01:00
Daniel Boles
9fef90b0f7 Add Since to ::insert-emoji, and some trivialities
Document when these keybinding signals were added.
2017-11-22 22:36:31 +00:00
Matthias Clasen
567447456e text view: Support the Emoji chooser
Similar to GtkEntry, add an "Insert Emoji" context
menu item, and add the same keybindings. We don't
add the icon here, since it is not clear where it
would go.

https://bugzilla.gnome.org/show_bug.cgi?id=790029
2017-11-22 16:50:10 -05:00
Matthias Clasen
462a77ffb5 Fix indentation mishap 2017-11-22 16:50:10 -05:00
Daniel Boles
fecce75c73 SpinButton: Explain meaning of nullable Adjustment
configure() marked the @adj argument as (allow-none) but did not explain
what passing NULL would do. Fix that, and move it to (nullable) as well.
2017-11-22 20:58:28 +00:00
Daniel Boles
98c1f16002 doc: Replace uses of #NULL with %NULL 2017-11-22 20:58:28 +00:00
Daniel Boles
23f7208235 CellRendererPixbuf: Link stock-size doc → IconSize
Add a doc comment for :stock-size in order to link to GtkIconSize.
2017-11-22 20:48:11 +00:00
Daniel Boles
7c2e28c8c5 doc: TextLayout: Add missing (out) annotations
and move from (allow-none) to (optional)
2017-11-22 20:48:11 +00:00
Bastien Nocera
ef031d87be frame-clock: Fix typo in API documentation 2017-11-22 15:24:19 +01:00
Chun-wei Fan
e076cc7b1f GDK/Win32: Fix build after GDK Root Window and DND changes
Ensure that things build again, and instead use the Windows API to
acquire the screen dimensions (note: this may need to be scaled for
HiDPI, but since I do not own a WinTab-based device, I will need to
keep the dimensions as-is for now).

Also update the gdkdnd-win32.c code to use formats rather than targets.

https://bugzilla.gnome.org/show_bug.cgi?id=773299
2017-11-22 22:18:28 +08:00
Chun-wei Fan
a687fd9aeb gtk/gskpango.c: Use g_snprintf()
This fixes the build of GTK+ master on Visual Studio 2013 (and possibly
others) as snprintf() may not be supported even if the required C99
features are supported by the compiler.

https://bugzilla.gnome.org/show_bug.cgi?id=773299
2017-11-21 14:22:23 +08:00
Chun-wei Fan
8059975f74 gtk/gtkseclection.c: Don't build X11 items unconditionally
Limit building the X11 items only when GDK_WINDOWING_X11 is defined.

https://bugzilla.gnome.org/show_bug.cgi?id=773299
2017-11-21 14:16:19 +08:00
Chun-wei Fan
824837486b gtkimcontextime.c: Fix call to gtk_style_context_get()
The state argument was removed in commit 1518fe0 (API: stylecontext:
Remove state argument from getters), but we missed updating this file
until commit 5b94fe6 (stylecontext: Make first property name explicit),
as the compiler did not issue any warnings on the (now-defunct) usage.

https://bugzilla.gnome.org/show_bug.cgi?id=773299
2017-11-21 14:16:06 +08:00
Benjamin Otte
c82378ea57 gdk: Add GType support to GdkContentFormats
This is not used by anything yet, but add it now, so people looking at
this new code can make sense of it.
Plus, the documentation mentions it, so better have the docs make sense.

It will be used once we add support for conversions to GDK and allow
doing cipboard/dnd by GValue.
2017-11-20 23:22:28 +01:00
Benjamin Otte
1a70ca75e8 gdk: Sanitize GdkContentFormats API
Make sure the API reflects the idea that GdkContentFormats is a set
containing mime types. In particular, treat the object itself as a
plural - it's named content format`S' after all - and therefor use
the correct verb form.

Also make GdkContentFormats keep an array instead of a list, now that
it's immutable.
2017-11-20 23:15:11 +01:00
Benjamin Otte
fc2ce5a925 gdk: Make GdkContentFormats immutable 2017-11-20 23:13:10 +01:00
Benjamin Otte
1a482ad276 gdk: Add GdkContentFormatsBuilder
Yes, the name is too long.
No, I couldn't think of a shorter one.
2017-11-20 23:12:48 +01:00
Benjamin Otte
d6a209816b gdkdnd: Make GdkDragContext->formats a GdkContentFormats
Instead of it being a GList of GdkAtoms.
2017-11-20 23:12:33 +01:00
Benjamin Otte
9a6ec4e959 contentformats: Rename GtkTargetList
It's now called GdkContentsFormat
2017-11-20 23:12:33 +01:00
Benjamin Otte
0638bbb5d5 gdk: Move GtkTargetList to GDK
It's gonna be renamed next, so put it in the right source file already.

For now retain the old name to keep the diff small.
2017-11-20 23:12:33 +01:00
Benjamin Otte
0b40ad32f3 selection: Make GtkTargetList members private
Outside of the target list, don't access it directly, instead use public
APIs like the newly introduced gtk_target_list_intersects().
2017-11-20 23:12:33 +01:00
Benjamin Otte
c863ac0f90 dnd: Remove GtkTargetEntry and GtkTargetFlags
warning: We don't do any same-app checks anymore so you currently can
copy local data into external apps.

This will be fixed later.
2017-11-20 23:12:33 +01:00
Matthias Clasen
49d02eff93 emoji chooser: break out a helper function
This is just a small cleanup.
2017-11-19 22:43:36 -05:00
Matthias Clasen
5a6c6070d6 remove debug spew 2017-11-19 22:43:36 -05:00
Piotr Drąg
24ed997cfb Update POTFILES.in 2017-11-20 00:14:14 +01:00
Matthias Clasen
4d9b7b2359 entry: Add a key binding for the emoji chooser
Make Ctrl-. and Ctrl-; bring up the emoji chooser.

https://bugzilla.gnome.org/show_bug.cgi?id=789160
2017-11-19 18:06:19 -05:00
Matthias Clasen
1cd5df9404 emoji chooser: Make menu key work as expected
Whenever we have a right-click action, we should make
the menu key work as a keyboard-accessible alternative.
2017-11-19 18:04:38 -05:00
Matthias Clasen
d3a358b9bd Adwaita: Bring fix focus in flowbox
Bring back the focus rectangle for flowbox children.
Its absence makes keynav in flowboxes really difficult.
2017-11-19 18:04:31 -05:00
Matthias Clasen
5e748ce940 emoji chooser: handle right-click
Whereever we handle long-press for touch, it makes sense to handle
right-click as a faster alternative for mouse-based interaction.

This commit makes right-click work to bring up the variation
selector for Emojis.
2017-11-19 18:04:26 -05:00
Matthias Clasen
4d0a57fe0b listbox: Listen to ::stopped on the press gesture
Otherwise, we end up interpreting grab notify's as
button releases, which is not right. This matches
what GtkFlowBox does.
2017-11-19 14:49:58 -05:00
Matthias Clasen
2f9d980c93 Trivial cleanup
Better to use G_SOURCE_REMOVE than FALSE, for clarity.
2017-11-19 09:28:00 -05:00
Matthias Clasen
1f8debbac9 emoji chooser: Don't leak gestures
We were not freeing these gestures as we should.
2017-11-19 09:27:53 -05:00
Matthias Clasen
a8531605db Some more interning
This avoids more strdups at startup.
2017-11-18 08:18:11 -05:00
Matthias Clasen
997f0de4d5 a11y: Intern a string 2017-11-17 23:25:45 -05:00
Matthias Clasen
7dded559c0 cell area: Use GTK_PARAM_READWRITE consistently 2017-11-17 23:25:07 -05:00
Matthias Clasen
315db6d505 wayland: Intern signal names 2017-11-17 23:22:02 -05:00
Matthias Clasen
7c4a1a596f icon helper: Avoid a few string copies 2017-11-17 23:21:24 -05:00
Matthias Clasen
8c06cd5f98 styleproperty: Use G_PARAM_STATIC_STRINGS 2017-11-17 22:56:25 -05:00
Matthias Clasen
ffd6baec42 gtk: Intern css names
This avoids a bunch of strdups at startup.
2017-11-17 22:49:57 -05:00
Matthias Clasen
4dc4db56dc wayland: Intern settings keys 2017-11-17 22:47:49 -05:00
Matthias Clasen
3b06ae5072 gdk: Intern signal names
We were forgetting this in a few places.
2017-11-17 22:47:26 -05:00
Matthias Clasen
a129053ed9 gdk: Use G_PARAM_SPEC_STATIC_STRINGS throughout
This avoids some string copies at startup.
2017-11-17 21:38:08 -05:00
Matthias Clasen
dd7163a699 settings: Use gdk_display_set_cursor_theme
This allows us to reduce the amount of ifdef ugliness.
2017-11-17 17:56:03 -05:00
Matthias Clasen
c2f6208ce5 Add private api for setting cursor theme
This is implemented in multiple gdk backends,
and we can avoid and ugly ifdef cascade in gtk
by adding a vfunc for this.
2017-11-17 17:42:12 -05:00
Matthias Clasen
2d591cde78 Include gdk-private.h
This gives us access to private gdk api.
2017-11-17 16:34:04 -05:00
Matthias Clasen
1ec93bdda6 gdk: Move code around
Move the gdk_display functions to gdkdisplay.c.
They are misplaced in gdkevents.c.
2017-11-17 16:22:21 -05:00
Matthias Clasen
4865c3273a clipboard: Use gdk_display_get_last_seen_time
This removes the backend dependent code from gtkclipboard.c.
A good thing!
2017-11-17 15:40:49 -05:00
Matthias Clasen
dbb18ad5d8 gdk: Add a private method to get a server timestamp
This is needed in the clipboard code. We don't make
it public, since that code is destined to eventually
live in gdk anyway.
2017-11-17 15:39:08 -05:00
Piotr Drąg
fc579b121a Update POTFILES.in 2017-11-17 20:02:41 +01:00
Matthias Clasen
6263286c4a Drop gdkscreen.h
Nothing uses GdkScreen anymore, so we can get rid of it.
2017-11-17 13:54:04 -05:00
Matthias Clasen
0b8c88f7d6 quartz: Remove remaining uses of GdkScreen 2017-11-17 13:47:15 -05:00
Matthias Clasen
a62e75964c quartz: Make GdkQuartzScreen a plain object
No need to derive this from GdkScreen anymore.
2017-11-17 13:47:15 -05:00
Matthias Clasen
77f921f5de quartz: Drop an unused include
No GdkScreen apis are used in here.
2017-11-17 13:47:15 -05:00
Matthias Clasen
c7b5cb8e8e quartz: Avoid a screen argument
The screen is never used in _gdk_quartz_screen_get_setting,
so drop it.
2017-11-17 13:47:15 -05:00
Matthias Clasen
0f2d7d41f1 win32: Remove remaining uses of GdkScreen 2017-11-17 13:47:15 -05:00
Matthias Clasen
d24ae9c032 win32: Make GdkWin32Screen a plain object
No need to derive this from GdkScreen anymore.
2017-11-17 13:47:14 -05:00
Matthias Clasen
211d72e545 win32: Avoid a screen argument
The screen is never used in _gdk_win32_screen_get_setting,
so drop it.
2017-11-17 13:21:24 -05:00
Matthias Clasen
e8353eab26 win32: Remove an unused include
No GdkScreen apis are used in here.
2017-11-17 13:20:53 -05:00
Matthias Clasen
34fa61e13c Fix the build 2017-11-17 13:12:51 -05:00
Matthias Clasen
71c463ae85 x11: Drop GdkX11Visual as public api
There was no useful functionality left here,
so just remove this from the api altogether.
2017-11-17 13:03:11 -05:00
Matthias Clasen
8ced2c6478 x11: Stop using GdkScreen altogether
Derive GdkX11Screen directly from GObject, and
remove the last remaining uses of GdkScreen.
2017-11-17 10:51:55 -05:00
Matthias Clasen
2daa7d1a53 x11: Stop using GdkScreen in api
This type is going away, so switch to using GdkX11Screen
everywhere.
2017-11-17 10:51:55 -05:00
Matthias Clasen
abb1d59d4e Stop calling _gdk_screen_close
It does nothing useful, and is going away.
2017-11-17 10:51:55 -05:00
Matthias Clasen
a5e1276924 Stop including gdkscreen.h
It is not used anymore.
2017-11-17 10:51:55 -05:00
Philip Withnall
bd89ff4c9e broadway: Add missing dependency to build
The generated file clienthtml.h is #included by broadway-server.c, which
is one of the sources of the broadway library — so clienthtml.h needs to
be one of the sources of that library too.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

https://bugzilla.gnome.org/show_bug.cgi?id=790489
2017-11-17 10:14:42 +00:00
Alexander Larsson
810ba4edcf broadway: Fix toplevel handling
The toplevels list contains GdkWindowImplBroadways, and we shouldn't
free it.
2017-11-17 10:37:01 +01:00
Benjamin Otte
f4ec6290f8 gdk: Remove gdk_flush()
If you need to flush a display, use gdk_display_flush().

There is never a need to flush displays you don't know about.
2017-11-17 08:36:35 +01:00
Benjamin Otte
8d7d5343d8 gtk-demo: No need to gdk_flush() here
And if there was a need, GDK should have done it.
2017-11-17 08:36:35 +01:00
Benjamin Otte
594aae71e5 toolbar: Remove gdk_flush() calls
It's not 2003 anymore.
2017-11-17 08:07:27 +01:00
Benjamin Otte
0019178014 main: Don't gdk_flush() after every main loop wait
For a start, this makes gtk_main() work different from g_main_loop_run()
calls.

But most importantly, modern GDK does proper syncing itself and doesn't
need to rely on a catch-all to get it right.
2017-11-17 08:07:10 +01:00
Matthias Clasen
9629f9acc9 Add a comment
Document that gdk-private.h is meant for private gdk<>gtk apis.
2017-11-17 00:37:10 -05:00
Matthias Clasen
fc0f7dc217 Remove gdkprivate.h
This is one-too-many private headers. Move the few
declarations here to gdkinternals.h.
2017-11-17 00:34:04 -05:00
Matthias Clasen
cc97c71883 Drop generic error trap api from the docs 2017-11-17 00:17:29 -05:00
Matthias Clasen
38c8310969 Drop gdkmain.h 2017-11-17 00:16:09 -05:00
Matthias Clasen
3f0d42f74b Stop including gdkmain.h
It is empty now.
2017-11-17 00:16:09 -05:00
Matthias Clasen
26d5b04124 Drop an empty file
Nothing deprecated left!
2017-11-17 00:08:24 -05:00
Matthias Clasen
6e94be3f50 Drop the error trap vfuncs
No longer used.
2017-11-17 00:08:24 -05:00
Matthias Clasen
30e6a4c29d Drop the generic error trap api
This is only implemented on X11, so we don't
need generic api for it.
2017-11-17 00:08:24 -05:00
Matthias Clasen
fe93bc7627 tests: Test the x11-specific error trap api
The other one is gone.
2017-11-17 00:08:24 -05:00
Matthias Clasen
90d502fdbd x11: Fix error traps in the dnd code
The code for grabbing keys was using a generic
error trap call, and more concerning, it was forgetting
to pop the trap.
2017-11-16 23:56:11 -05:00
Matthias Clasen
daacd25344 selection: Use x11-specific traps
The generic trap api is going away.
2017-11-16 23:42:55 -05:00
Matthias Clasen
8b3e9fe35c mountoperation-x11: Use x11-specific traps
The generic trap api is going away.
2017-11-16 23:36:21 -05:00
Matthias Clasen
5517ab0651 Drop an unused variable
These are no longer used.
2017-11-16 23:27:14 -05:00
Matthias Clasen
92f49ed3e3 Drop a duplicate definition
GDK_PRIORITY_EVENTS is already defined in gdkevents.h
2017-11-16 23:23:42 -05:00
Matthias Clasen
6bf215bc15 Drop gdk_set_program_class
Together with the corresponding getter.
This is x11-specific functionality.
2017-11-16 23:22:08 -05:00
Matthias Clasen
d73898437f x11: Add gdk_x11_display_set_program_class
The program class is a very X-specific concept.
There should be x11-backend api to deal with it.
2017-11-16 23:21:06 -05:00
Matthias Clasen
49f3d86c84 wayland: Stop using gdk_get_program_class
This is an abuse, at best. If we need to pass the
app id down here, lets pass the app id.
2017-11-16 23:18:03 -05:00
Matthias Clasen
95876cbc9c Remove gdk/gdkx.h
It was just a kludge.
2017-11-16 23:00:01 -05:00
Matthias Clasen
39386275a4 Move some code around
Move gdk_disable_multidevice to gdkdisplaymanager.[hc].
2017-11-16 22:54:26 -05:00
Matthias Clasen
211f16d68b Drop gdk_notify_startup_complete
This function and its variant are just wrappers
around the display-specific function.
2017-11-16 22:45:52 -05:00
Matthias Clasen
dca8c8e189 gtk: Stop using gdk_notify_startup_complete_with_id
This function is about to go away. Instead, use the
display-specific function that this is a wrapper of.
2017-11-16 22:45:04 -05:00
Matthias Clasen
419a9af28c gdk: Move some headers around
Move gdk_flush and gdk_set_allowed_backends to where they
belong.
2017-11-16 22:18:45 -05:00
Matthias Clasen
baf40d35c5 Drop gdk_beep
This is an unnecessary wrapper around gdk_display_beep.
2017-11-16 22:10:26 -05:00
Matthias Clasen
9d9674a7ca im context thai: Stop using gdk_beep
It is about to go away.
2017-11-16 22:09:44 -05:00
Matthias Clasen
ce13dbba10 Drop gdk_set_double_click_time
This is an unnecessary and not-recommended-to-be-used
wrapper around gdk_display_set_double_click_time.
2017-11-16 22:04:25 -05:00
Benjamin Otte
3f5178dc21 selection: Remove the info uint
Instead of allowing people to pass a uint user-data, insist on them
comparing mime types.

The user data was a uint instead of a pointer anyway, so uniqueness
could not be guaranteed and it caused more issues than it was worth.
And that's ignoring the fact that it basically wasn't used.
2017-11-16 22:59:43 +01:00
Benjamin Otte
5da3059175 selection: Remove gtk_target_table_*() functions 2017-11-16 22:59:42 +01:00
Benjamin Otte
b200d4f099 textview: Stop playing shenanigans with the target list
This breaks GtkSourceView adding custom targets on top of GtkTextView,
but we'll fix that later.
2017-11-16 22:59:42 +01:00
Benjamin Otte
47e75b34a4 selection: Make GtkTargetEntry not allocatable
And remove it being registered as a boxed type (lol).
2017-11-16 22:59:42 +01:00
Matthias Clasen
e62ec97707 HighContrast: misc fixes
The HighContrast theme was not parsing anymore, due to
leftover widget style properties, and some missed cleanups,
like -gtk-icon-effect. Also update for the new focus handling,
and make checks and radios sharp again.
2017-11-15 18:08:46 -05:00
Matthias Clasen
a4c4df3b95 Adwaita: Make checks and radios sharp again
The assets we have are 14x14, set -gtk-icon-size to reflect that.
2017-11-15 18:07:52 -05:00
Matthias Clasen
d9a146f54a Change icon-size properties
We no longer support registering custom icon sizes, so
we can make these properties just enums. This also lets
us specify them by nick in ui files. Nice!
2017-11-15 14:22:17 -05:00
Matthias Clasen
a28cf475af image: Update docs
Mention the new icon-size style classes, update the docs
for removed arguments and return values, and add new
functions to the docs.
2017-11-15 14:22:17 -05:00
Matthias Clasen
f16fb1373e Document -gtk-icon-size
Add this property to the list of CSS properties.
2017-11-15 14:22:17 -05:00
Matthias Clasen
43a9b82797 Support -gtk-icon-size for builtins
This makes css icons more similar to themed icons, which
is the overall goal here.
2017-11-15 14:22:17 -05:00
Matthias Clasen
0d23606653 Drop gtk_icon_size_lookup
Add a new, private gtk_image_get_image_size to replace it, and
update the remaining callers in a suitable way.
2017-11-15 14:22:17 -05:00
Matthias Clasen
866ff2b8f0 recentchooser: Use GIcon instead of GdkPixbuf 2017-11-15 14:22:17 -05:00
Matthias Clasen
c6c3427507 iconhelper: Query size via CSS
Instead of looking at the icon size, look at the CSS value for
-gtk-icon-size. Set style classes depending on icon size instead.

Trivially change Adwaita and HighContrast to report the same values as
before.
2017-11-15 14:22:17 -05:00
Matthias Clasen
2301d8d90b enums: Change GtkIconSize values
The new values are the ones we intend to keep. The old ones had
duplicated meanings and nobody knew which one to take.
2017-11-15 14:22:17 -05:00
Benjamin Otte
e5da85631a image: Don't take icon size in set_from_definition() 2017-11-15 14:22:17 -05:00
Matthias Clasen
67268bcc23 filechooserwidget: icon size is always 16 2017-11-15 14:22:17 -05:00
Matthias Clasen
b598a5ab78 filechooserbutton: icon size is always 16
So define it that way.
2017-11-15 14:22:17 -05:00
Benjamin Otte
e0a5f4e081 cellrendererspinner: Don't track old icon size
It was only used to avoid gtk_icon_size_lookup() calls and those aren't
expensive.
2017-11-15 14:22:17 -05:00
Matthias Clasen
dbfaa99107 image: Remove icon-size argument from icon setters
Instead, add a function gtk_image_set_icon_size() for the cases where
overriding the icon size is necessary.

Treat icon sizes the same way as pixel sizes, too. So gtk_image_clear()
no longer unsets the icon size.
2017-11-15 14:22:17 -05:00
Benjamin Otte
049cc6aa01 image: Change getters
Instead of returning the icon size with them, make
gtk_image_get_icon_name() and gtk_image_get_gicon() only return the icon
itself.

As a benefit, we can turn them into regular getters that return values
instead of requiring out parameters.

Instead, provide gtk_image_get_icon_size() to query the icon size.
2017-11-15 14:22:17 -05:00
Benjamin Otte
f53b72e5ff button: Get rid of icon size
In fact, make gtk_button_new_from_icon_name() just set the icon-name
property instead of creating a GtkImage.
2017-11-15 14:22:16 -05:00
Benjamin Otte
3da65ff233 scalebutton: Remove icon size 2017-11-15 14:22:16 -05:00
Benjamin Otte
a7754a14b5 toolbar: Remove icon sizes 2017-11-15 14:22:16 -05:00
Benjamin Otte
8df61992d7 tooltips: Remove GtkIconSize usage 2017-11-15 14:22:16 -05:00
Benjamin Otte
129dc7d73b css: Add -gtk-icon-size
This will replace GtkIconSize in future patches.
2017-11-15 14:22:16 -05:00
Benjamin Otte
dcc2577b97 introspection: Fix build 2017-11-15 19:33:26 +01:00
Benjamin Otte
e9629a5149 wayland: Fix initial cursor
Make sure the initial cursor isn't random which would happen due to an
early exit when cursor == pointer->cursor triggered because both were
NULL.
2017-11-15 19:07:17 +01:00
Benjamin Otte
4c4e914806 gdk: Replace GDK_NONE with NULL 2017-11-15 19:07:17 +01:00
Benjamin Otte
cb941956d3 gdk: Turn GdkAtom into a const char *
Instead of an integer, it is now a char pointer. We also use
g_intern_string() instead of doing the interning ourselves.
2017-11-15 19:07:17 +01:00
Benjamin Otte
0451c6d30c gdk: Make GDK_NONE Atom translate to NULL
Instead of the string "NONE" we now use NULL.
2017-11-15 19:07:17 +01:00
Benjamin Otte
a385a50260 gdk: Get rid of magic special atoms 2017-11-15 19:07:17 +01:00
Benjamin Otte
41f9a174e2 x11: Remove special casing for GdkAtoms
This is in preparation for the GdkAtom removal
2017-11-15 19:07:17 +01:00
Benjamin Otte
5a1a11bcde dnd: Make GtkDragDest and GtkDragSource use GtkTargetList
This gets rid of GtkTargetEntry in the API and consistently uses
GtkTargetList.
2017-11-15 19:07:17 +01:00
Benjamin Otte
7efc5a1558 clipboard: Consistently use GtkTargetList
Some code was using GtkTargetList, some used GtkTargetEntry and some
GtkTargetPair.
2017-11-15 19:07:16 +01:00
Benjamin Otte
fb94f79094 selection: Remove #ifdef WAYLAND
Instead, turn the functions into backend API:
  gdk_broadway_display_add_selection_targets()
  gdk_broadway_display_clear_selection_targets()
Remove the old per-backend functions, too.
2017-11-15 19:07:16 +01:00
Benjamin Otte
13ca03efb1 cellrendererpixbuf: Remove stock-detail property
GTK3 didn't use that property already...
2017-11-14 18:37:38 -05:00
Benjamin Otte
515b13fdd5 messagedialog: Remove unused header 2017-11-14 18:24:43 -05:00
Matthias Clasen
0436cc44fc win32: Remove all checks for GDK_WINDOW_ROOT
We are no longer creating windows of this type, so no
need to check for it.
2017-11-14 18:16:19 -05:00
Matthias Clasen
e2682e62a8 win32: Remove all uses of get_root_window
This is following similar changes done in the x11 and
broadway backends, but it has not been built.
Some fixups may be needed.
2017-11-14 18:16:19 -05:00
Benjamin Otte
77efc60a15 placessiderbar: Fix sunny compilation
Make compilation not warn about unused variables when compiling with
HAVE_CLOUDPROVIDERS undefined.
2017-11-13 23:45:18 +01:00
Benjamin Otte
457bf3b604 widget: No need to update events
GtkWindow queues for all events anyway, so the needed ones are already
there.
2017-11-13 23:41:38 +01:00
Benjamin Otte
ed1b6a9bed gdkwindow: Remove event_mask arguments from constructors 2017-11-13 23:41:38 +01:00
Benjamin Otte
ef5a6835b2 window: Set ALL_EVENT_MASK
This is a trivial commit that does a big change: We now ignore event masks.

Further commits will clean up code, but if bisection ends up here, you
know it's because code is getting delivered events that it weren't getting
before.
2017-11-13 23:41:37 +01:00
Benjamin Otte
de40ced21c gdk: Fix GDK_ALL_EVENTS_MASK
This mask was forgotten to update when the last 2 event masks were
added, probably because it looks like it's already maxed.
2017-11-13 23:41:37 +01:00
Benjamin Otte
9d56cee622 widget: Remove gtk_widget_set_device_enabled()
Nobody is using it.
2017-11-13 23:41:37 +01:00
Matthias Clasen
5f73afae3d x11: Remove mentions of GDK_WINDOW_ROOT
This backend never creates a window of this type, so no
need to check for it anymore.
2017-11-13 16:47:50 -05:00
Matthias Clasen
964cdaf3a3 x11: Stop creating a root window
We no longer need it.
2017-11-13 16:39:54 -05:00
Matthias Clasen
5999b1c73a x11: Store toplevel list in GdkDisplay
This will let us get rid of the root window.
2017-11-13 16:32:34 -05:00
Matthias Clasen
8af666cb4f x11: Remove another use of the root window
We just need the X root window here.
2017-11-13 16:09:47 -05:00
Matthias Clasen
724863c275 icontheme: Add a trailing / when enumerating resources
This avoids extra string copies in GResource.
2017-11-13 12:13:42 -05:00
Carlos Soriano
1b1cb8295b gtkplacessidebar: Fix new tab/window handling for cloud accounts
It wasn't taking into account whether the sidebar had support for them
or not, resulting in a file chooser with open in new tab/window menu
items when it's not supported.

To fix it, do as with the other menus and check for the availability of
new tab/window flags.

https://bugzilla.gnome.org/show_bug.cgi?id=786123
2017-11-13 16:57:02 +01:00
Carlos Soriano
f54e7712c5 gtkplacessidebar: Adapt to libcloudproviders 0.2.x
And a few improvements on the way.

https://bugzilla.gnome.org/show_bug.cgi?id=786123
2017-11-13 16:55:10 +01:00
Matthias Clasen
2ff175938d application: Append a / to the icon resource path
g_resources_enumerate_children expects the path to end
in a '/' (even though thats not stated in the docs), and
will copy it if that isn't the case. Avoid the copy
by putting  a '/' there to begin with.
2017-11-13 07:35:18 -05:00
Matthias Clasen
ec1ea0db04 icontheme: Append a / to the resource path
g_resources_enumerate_children expects the path to end
in a '/' (even though thats not stated in the docs), and
will copy it if that isn't the case. Avoid the copy
by putting  a '/' there to begin with.
2017-11-13 07:33:35 -05:00
Benjamin Otte
e0d3602331 a11y: Handle a treeview with no columns
Code was spewing criticals to stderr because of nonexisting columns. So
check that there's actually an existing column first.
2017-11-13 03:51:53 +01:00
Benjamin Otte
b968147e0a treeview: Only update vadjustment in size_allocate()
The 2 calls even do different things, but because the one in allocate
always overrides the one here...
2017-11-13 01:53:45 +01:00
Benjamin Otte
f31a51a1c8 treeview: Pass height to allocate as argument
Instead of exporting a function to query it.
2017-11-13 01:28:16 +01:00
Benjamin Otte
b47ff72ebc progresstracker: Don't hand out NaN
When the duration is set to 0, clamp it to 1us. This way we're almost
correct: We should really instantly finish, but we don't. But we do
respect the delay.

Doing this properly would require some refactoring of how the progress
tracker actually maintains progress, and this is just a quick fix.
2017-11-12 06:22:34 +01:00
Benjamin Otte
6eead8f6a3 treeview: Use gtk_widget_get_width()
... instead of gtk_widget_get_allocated_width() and same for height.

This makes the treeview do the right thing when used with padding.
2017-11-12 05:46:06 +01:00
Benjamin Otte
61ecd10240 treeview: Don't allocate columns outside of size_allocate() 2017-11-12 05:38:58 +01:00
Benjamin Otte
5db1aa5401 treeview: Fix RTL column header allocation 2017-11-12 05:37:06 +01:00
Benjamin Otte
48de0bf741 treeview: width_changed is always true, so remove it
Also, sanitize the RTL correction code that made sure resizing the width
of a treeview would keep the contents glued to the right border instead
of the left border.
2017-11-12 05:31:21 +01:00
Matthias Clasen
7839e0d7d5 x11: Fix a crash
This was crashing the moment a second window is opened.
2017-11-11 12:07:11 -05:00
Matthias Clasen
f40b3bc5bc Fix up managed dnd
Since commit 6c56d04cee,
we were doing some calls twice in the managed dnd case,
leading to double drops.
2017-11-11 07:50:11 -05:00
Benjamin Otte
af13d474e8 textview: Remove GDK windows 2017-11-11 05:37:37 +01:00
Benjamin Otte
26909ee913 textview: Simplify gtk_text_view_buffer_to_window_coords()
... and gtk_text_view_window_to_buffer_coords()
2017-11-11 05:25:22 +01:00
Benjamin Otte
2533ad723a textview: Use text_window_get_width()/height()
Instead of poking the GdkWindow. They have the same size after all.
2017-11-11 05:12:07 +01:00
Benjamin Otte
17600b6bab textview: Make the semi-private headrs really private
Rename the files to have the private.h ending.

And remove gtktextdisplay.h from the installed files.
2017-11-11 05:01:31 +01:00
Benjamin Otte
d18b10a3d7 textview: Store border window sizes in a custom struct
That way, we don't need to have a GtKRequisition in every TextWindow.
2017-11-11 04:30:00 +01:00
Benjamin Otte
d65d5d0a84 gtktexttag: Remove GtkTextTag::event and gtk_text_tag_event()
GtkSourceView is not using it, so it's unneeded. And it's certainly
diving deep into event internals of GtkTextView which hinders a proper
gesturization.
2017-11-11 04:25:11 +01:00
Benjamin Otte
52424d8640 textview: Hide the selection bubble better
The selection bubble is not part of the text windows, so hiding it
during scroll should not be done in the text window code.

Also remove an unused variable that was only set in that code but never
read.
2017-11-11 02:49:08 +01:00
Benjamin Otte
e9dd5f327f flowbox: Compute view box from correct variables 2017-11-11 02:49:08 +01:00
599 changed files with 29687 additions and 30251 deletions

View File

@@ -150,7 +150,6 @@ query_for_toplevel (GdkDisplay *display,
g_object_unref (cursor);
gtk_widget_destroy (popup);
gdk_flush (); /* Really release the grab */
return toplevel;
}

View File

@@ -1,6 +1,6 @@
/* Clipboard
*
* GtkClipboard is used for clipboard handling. This demo shows how to
* GdkClipboard is used for clipboard handling. This demo shows how to
* copy and paste text to and from the clipboard.
*
* It also shows how to transfer images via the clipboard or via
@@ -13,74 +13,104 @@
#include <gtk/gtk.h>
#include <string.h>
static GtkWidget *window = NULL;
void
copy_button_clicked (GtkWidget *button,
gpointer user_data)
{
GtkWidget *entry;
GtkClipboard *clipboard;
GdkClipboard *clipboard;
entry = GTK_WIDGET (user_data);
/* Get the clipboard object */
clipboard = gtk_widget_get_clipboard (entry,
GDK_SELECTION_CLIPBOARD);
clipboard = gtk_widget_get_clipboard (entry);
/* Set clipboard text */
gtk_clipboard_set_text (clipboard, gtk_entry_get_text (GTK_ENTRY (entry)), -1);
gdk_clipboard_set_text (clipboard, gtk_entry_get_text (GTK_ENTRY (entry)));
}
void
paste_received (GtkClipboard *clipboard,
const gchar *text,
paste_received (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
GdkClipboard *clipboard;
GtkWidget *entry;
char *text;
GError *error = NULL;
clipboard = GDK_CLIPBOARD (source_object);
entry = GTK_WIDGET (user_data);
/* Set the entry text */
if(text)
gtk_entry_set_text (GTK_ENTRY (entry), text);
/* Get the resulting text of the read operation */
text = gdk_clipboard_read_text_finish (clipboard, result, &error);
if (text)
{
/* Set the entry text */
gtk_entry_set_text (GTK_ENTRY (entry), text);
g_free (text);
}
else
{
GtkWidget *dialog;
/* Show an error about why pasting failed.
* Usually you probably want to ignore such failures,
* but for demonstration purposes, we show the error.
*/
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Could not paste text: %s",
error->message);
g_signal_connect (dialog, "response",
G_CALLBACK (gtk_widget_destroy), NULL);
gtk_widget_show (dialog);
g_error_free (error);
}
}
void
paste_button_clicked (GtkWidget *button,
gpointer user_data)
gpointer user_data)
{
GtkWidget *entry;
GtkClipboard *clipboard;
GdkClipboard *clipboard;
entry = GTK_WIDGET (user_data);
/* Get the clipboard object */
clipboard = gtk_widget_get_clipboard (entry,
GDK_SELECTION_CLIPBOARD);
clipboard = gtk_widget_get_clipboard (entry);
/* Request the contents of the clipboard, contents_received will be
called when we do get the contents.
*/
gtk_clipboard_request_text (clipboard,
paste_received, entry);
gdk_clipboard_read_text_async (clipboard, NULL, paste_received, entry);
}
static cairo_surface_t *
get_image_surface (GtkImage *image)
static GdkTexture *
get_image_texture (GtkImage *image)
{
const gchar *icon_name;
GtkIconSize size;
GtkIconTheme *icon_theme;
int width;
GtkIconInfo *icon_info;
switch (gtk_image_get_storage_type (image))
{
case GTK_IMAGE_SURFACE:
return cairo_surface_reference (gtk_image_get_surface (image));
case GTK_IMAGE_TEXTURE:
return g_object_ref (gtk_image_get_texture (image));
case GTK_IMAGE_ICON_NAME:
gtk_image_get_icon_name (image, &icon_name, &size);
icon_name = gtk_image_get_icon_name (image);
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (image)));
gtk_icon_size_lookup (size, &width, NULL);
return gtk_icon_theme_load_surface (icon_theme, icon_name, width, 1, NULL, GTK_ICON_LOOKUP_GENERIC_FALLBACK, NULL);
icon_info = gtk_icon_theme_lookup_icon (icon_theme, icon_name, 48, GTK_ICON_LOOKUP_GENERIC_FALLBACK);
if (icon_info == NULL)
return NULL;
return gtk_icon_info_load_texture (icon_info);
default:
g_warning ("Image storage type %d not handled",
gtk_image_get_storage_type (image));
@@ -93,14 +123,11 @@ drag_begin (GtkWidget *widget,
GdkDragContext *context,
gpointer data)
{
cairo_surface_t *surface;
GdkTexture *texture;
surface = get_image_surface (GTK_IMAGE (widget));
if (surface)
{
cairo_surface_set_device_offset (surface, -2, -2);
gtk_drag_set_icon_surface (context, surface);
}
texture = get_image_texture (GTK_IMAGE (widget));
if (texture)
gtk_drag_set_icon_texture (context, texture, -2, -2);
}
void
@@ -111,30 +138,27 @@ drag_data_get (GtkWidget *widget,
guint time,
gpointer data)
{
cairo_surface_t *surface;
GdkTexture *texture;
surface = get_image_surface (GTK_IMAGE (data));
if (surface)
gtk_selection_data_set_surface (selection_data, surface);
texture = get_image_texture (GTK_IMAGE (widget));
if (texture)
gtk_selection_data_set_texture (selection_data, texture);
}
static void
drag_data_received (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection_data,
guint info,
guint32 time,
gpointer data)
{
if (gtk_selection_data_get_length (selection_data) > 0)
{
cairo_surface_t *surface;
GdkTexture *texture;
surface = gtk_selection_data_get_surface (selection_data);
gtk_image_set_from_surface (GTK_IMAGE (data), surface);
cairo_surface_destroy (surface);
texture = gtk_selection_data_get_texture (selection_data);
gtk_image_set_from_texture (GTK_IMAGE (data), texture);
g_object_unref (texture);
}
}
@@ -142,34 +166,45 @@ static void
copy_image (GtkMenuItem *item,
gpointer data)
{
GtkClipboard *clipboard;
cairo_surface_t *surface;
GdkClipboard *clipboard;
GdkTexture *texture;
clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
surface = get_image_surface (GTK_IMAGE (data));
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
texture = get_image_texture (GTK_IMAGE (data));
if (surface)
if (texture)
{
gtk_clipboard_set_surface (clipboard, surface);
cairo_surface_destroy (surface);
gdk_clipboard_set_texture (clipboard, texture);
g_object_unref (texture);
}
}
static void
paste_image_received (GObject *source,
GAsyncResult *result,
gpointer data)
{
GdkTexture *texture;
texture = gdk_clipboard_read_texture_finish (GDK_CLIPBOARD (source), result, NULL);
if (texture == NULL)
return;
gtk_image_set_from_texture (GTK_IMAGE (data), texture);
g_object_unref (texture);
}
static void
paste_image (GtkMenuItem *item,
gpointer data)
{
GtkClipboard *clipboard;
cairo_surface_t *surface;
GdkClipboard *clipboard;
clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
surface = gtk_clipboard_wait_for_surface (clipboard);
if (surface)
{
gtk_image_set_from_surface (GTK_IMAGE (data), surface);
cairo_surface_destroy (surface);
}
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
gdk_clipboard_read_texture_async (clipboard,
NULL,
paste_image_received,
data);
}
static gboolean
@@ -205,15 +240,12 @@ button_press (GtkWidget *widget,
GtkWidget *
do_clipboard (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *vbox, *hbox;
GtkWidget *label;
GtkWidget *entry, *button;
GtkWidget *image;
GtkClipboard *clipboard;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_display (GTK_WINDOW (window),
@@ -271,12 +303,11 @@ do_clipboard (GtkWidget *do_widget)
gtk_box_pack_start (GTK_BOX (vbox), hbox);
/* Create the first image */
image = gtk_image_new_from_icon_name ("dialog-warning",
GTK_ICON_SIZE_BUTTON);
image = gtk_image_new_from_icon_name ("dialog-warning");
gtk_container_add (GTK_CONTAINER (hbox), image);
/* make image a drag source */
gtk_drag_source_set (image, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY);
gtk_drag_source_set (image, GDK_BUTTON1_MASK, NULL, GDK_ACTION_COPY);
gtk_drag_source_add_image_targets (image);
g_signal_connect (image, "drag-begin",
G_CALLBACK (drag_begin), image);
@@ -285,7 +316,7 @@ do_clipboard (GtkWidget *do_widget)
/* accept drops on image */
gtk_drag_dest_set (image, GTK_DEST_DEFAULT_ALL,
NULL, 0, GDK_ACTION_COPY);
NULL, GDK_ACTION_COPY);
gtk_drag_dest_add_image_targets (image);
g_signal_connect (image, "drag-data-received",
G_CALLBACK (drag_data_received), image);
@@ -295,12 +326,11 @@ do_clipboard (GtkWidget *do_widget)
G_CALLBACK (button_press), image);
/* Create the second image */
image = gtk_image_new_from_icon_name ("process-stop",
GTK_ICON_SIZE_BUTTON);
image = gtk_image_new_from_icon_name ("process-stop");
gtk_container_add (GTK_CONTAINER (hbox), image);
/* make image a drag source */
gtk_drag_source_set (image, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY);
gtk_drag_source_set (image, GDK_BUTTON1_MASK, NULL, GDK_ACTION_COPY);
gtk_drag_source_add_image_targets (image);
g_signal_connect (image, "drag-begin",
G_CALLBACK (drag_begin), image);
@@ -309,7 +339,7 @@ do_clipboard (GtkWidget *do_widget)
/* accept drops on image */
gtk_drag_dest_set (image, GTK_DEST_DEFAULT_ALL,
NULL, 0, GDK_ACTION_COPY);
NULL, GDK_ACTION_COPY);
gtk_drag_dest_add_image_targets (image);
g_signal_connect (image, "drag-data-received",
G_CALLBACK (drag_data_received), image);
@@ -317,10 +347,6 @@ do_clipboard (GtkWidget *do_widget)
/* context menu on image */
g_signal_connect (image, "button-press-event",
G_CALLBACK (button_press), image);
/* tell the clipboard manager to make the data persistent */
clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
gtk_clipboard_set_can_store (clipboard, NULL, 0);
}
if (!gtk_widget_get_visible (window))

View File

@@ -151,6 +151,7 @@
<file>cursors.c</file>
<file>dialog.c</file>
<file>drawingarea.c</file>
<file>dnd.c</file>
<file>editable_cells.c</file>
<file>entry_buffer.c</file>
<file>entry_completion.c</file>
@@ -246,4 +247,7 @@
<gresource prefix="/modelbutton">
<file>modelbutton.ui</file>
</gresource>
<gresource prefix="/dnd">
<file>dnd.css</file>
</gresource>
</gresources>

View File

@@ -58,7 +58,8 @@ interactive_dialog_clicked (GtkButton *button,
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
gtk_box_pack_start (GTK_BOX (content_area), hbox);
image = gtk_image_new_from_icon_name ("dialog-question", GTK_ICON_SIZE_DIALOG);
image = gtk_image_new_from_icon_name ("dialog-question");
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
gtk_box_pack_start (GTK_BOX (hbox), image);
table = gtk_grid_new ();

377
demos/gtk-demo/dnd.c Normal file
View File

@@ -0,0 +1,377 @@
/* Drag-and-Drop
*
* I can't believe its not glade!
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <string.h>
typedef struct _GtkDemoWidget GtkDemoWidget;
struct _GtkDemoWidget
{
GType type;
union {
char *text;
gboolean active;
};
};
static gpointer
copy_demo_widget (gpointer data)
{
GtkDemoWidget *demo = g_memdup (data, sizeof (GtkDemoWidget));
if (demo->type == GTK_TYPE_LABEL)
demo->text = g_strdup (demo->text);
return demo;
}
static void
free_demo_widget (gpointer data)
{
GtkDemoWidget *demo = data;
if (demo->type == GTK_TYPE_LABEL)
g_free (demo->text);
g_free (demo);
}
#define GTK_TYPE_DEMO_WIDGET (gtk_demo_widget_get_type ())
G_DEFINE_BOXED_TYPE (GtkDemoWidget, gtk_demo_widget, copy_demo_widget, free_demo_widget)
static GtkDemoWidget *
serialize_widget (GtkWidget *widget)
{
GtkDemoWidget *demo;
demo = g_new0 (GtkDemoWidget, 1);
demo->type = G_OBJECT_TYPE (widget);
if (GTK_IS_LABEL (widget))
{
demo->text = g_strdup (gtk_label_get_text (GTK_LABEL (widget)));
}
else if (GTK_IS_SPINNER (widget))
{
g_object_get (widget, "active", &demo->active, NULL);
}
else
{
g_print ("Type %s not supported\n", g_type_name (demo->type));
}
return demo;
}
static GtkWidget *
deserialize_widget (GtkDemoWidget *demo)
{
GtkWidget *widget = NULL;
if (demo->type == GTK_TYPE_LABEL)
{
widget = gtk_label_new (demo->text);
}
else if (demo->type == GTK_TYPE_SPINNER)
{
widget = g_object_new (demo->type, "active", demo->active, NULL);
gtk_style_context_add_class (gtk_widget_get_style_context (widget), "demo");
}
else
{
g_print ("Type %s not supported\n", g_type_name (demo->type));
}
return widget;
}
static double pos_x, pos_y;
static void
new_label_cb (GtkMenuItem *item,
gpointer data)
{
GtkFixed *fixed = data;
GtkWidget *widget;
widget = gtk_label_new ("Label");
gtk_fixed_put (fixed, widget, pos_x, pos_y);
}
static void
new_spinner_cb (GtkMenuItem *item,
gpointer data)
{
GtkFixed *fixed = data;
GtkWidget *widget;
widget = gtk_spinner_new ();
gtk_style_context_add_class (gtk_widget_get_style_context (widget), "demo");
gtk_spinner_start (GTK_SPINNER (widget));
gtk_fixed_put (fixed, widget, pos_x, pos_y);
}
static void
copy_cb (GtkWidget *child)
{
GdkClipboard *clipboard;
GtkDemoWidget *demo;
g_print ("Copy %s\n", G_OBJECT_TYPE_NAME (child));
demo = serialize_widget (child);
clipboard = gdk_display_get_clipboard (gdk_display_get_default ());
gdk_clipboard_set (clipboard, GTK_TYPE_DEMO_WIDGET, demo);
}
static void
delete_cb (GtkWidget *child)
{
gtk_widget_destroy (child);
}
static void
cut_cb (GtkWidget *child)
{
copy_cb (child);
delete_cb (child);
}
static void
value_read (GObject *source,
GAsyncResult *res,
gpointer data)
{
GdkClipboard *clipboard = GDK_CLIPBOARD (source);
GError *error = NULL;
const GValue *value;
GtkDemoWidget *demo;
GtkWidget *widget = NULL;
value = gdk_clipboard_read_value_finish (clipboard, res, &error);
if (value == NULL)
{
g_print ("error: %s\n", error->message);
g_error_free (error);
return;
}
if (!G_VALUE_HOLDS (value, GTK_TYPE_DEMO_WIDGET))
{
g_print ("can't handle clipboard contents\n");
return;
}
demo = g_value_get_boxed (value);
widget = deserialize_widget (demo);
gtk_fixed_put (GTK_FIXED (data), widget, pos_x, pos_y);
}
static void
paste_cb (GtkWidget *fixed)
{
GdkClipboard *clipboard;
clipboard = gdk_display_get_clipboard (gdk_display_get_default ());
if (gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (clipboard), GTK_TYPE_DEMO_WIDGET))
{
g_print ("Paste %s\n", g_type_name (GTK_TYPE_DEMO_WIDGET));
gdk_clipboard_read_value_async (clipboard, GTK_TYPE_DEMO_WIDGET, 0, NULL, value_read, fixed);
}
else
g_print ("Don't know how to handle clipboard contents\n");
}
static void
edit_label_done (GtkWidget *entry, gpointer data)
{
GtkWidget *fixed = gtk_widget_get_parent (entry);
GtkWidget *label;
int x, y;
gtk_container_child_get (GTK_CONTAINER (fixed), entry, "x", &x, "y", &y, NULL);
label = GTK_WIDGET (g_object_get_data (G_OBJECT (entry), "label"));
gtk_label_set_text (GTK_LABEL (label), gtk_entry_get_text (GTK_ENTRY (entry)));
gtk_widget_destroy (entry);
}
static void
edit_cb (GtkWidget *child)
{
GtkWidget *fixed = gtk_widget_get_parent (child);
int x, y;
gtk_container_child_get (GTK_CONTAINER (fixed), child, "x", &x, "y", &y, NULL);
if (GTK_IS_LABEL (child))
{
GtkWidget *entry = gtk_entry_new ();
g_object_set_data (G_OBJECT (entry), "label", child);
gtk_entry_set_text (GTK_ENTRY (entry), gtk_label_get_text (GTK_LABEL (child)));
g_signal_connect (entry, "activate", G_CALLBACK (edit_label_done), NULL);
gtk_fixed_put (GTK_FIXED (fixed), entry, x, y);
gtk_widget_grab_focus (entry);
}
else if (GTK_IS_SPINNER (child))
{
gboolean active;
g_object_get (child, "active", &active, NULL);
g_object_set (child, "active", !active, NULL);
}
}
static void
pressed_cb (GtkGesture *gesture,
int n_press,
double x,
double y,
gpointer data)
{
GtkWidget *widget;
GtkWidget *child;
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
child = gtk_widget_pick (widget, x, y);
if (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)) == GDK_BUTTON_SECONDARY)
{
GdkRectangle rect;
GtkWidget *menu;
GtkWidget *item;
GdkClipboard *clipboard;
pos_x = x;
pos_y = y;
menu = gtk_menu_new ();
item = gtk_menu_item_new_with_label ("New Label");
g_signal_connect (item, "activate", G_CALLBACK (new_label_cb), widget);
gtk_container_add (GTK_CONTAINER (menu), item);
item = gtk_menu_item_new_with_label ("New Spinner");
g_signal_connect (item, "activate", G_CALLBACK (new_spinner_cb), widget);
gtk_container_add (GTK_CONTAINER (menu), item);
item = gtk_separator_menu_item_new ();
gtk_container_add (GTK_CONTAINER (menu), item);
item = gtk_menu_item_new_with_label ("Edit");
gtk_widget_set_sensitive (item, child != NULL && child != widget);
g_signal_connect_swapped (item, "activate", G_CALLBACK (edit_cb), child);
gtk_container_add (GTK_CONTAINER (menu), item);
item = gtk_separator_menu_item_new ();
gtk_container_add (GTK_CONTAINER (menu), item);
item = gtk_menu_item_new_with_label ("Cut");
gtk_widget_set_sensitive (item, child != NULL && child != widget);
g_signal_connect_swapped (item, "activate", G_CALLBACK (cut_cb), child);
gtk_container_add (GTK_CONTAINER (menu), item);
item = gtk_menu_item_new_with_label ("Copy");
gtk_widget_set_sensitive (item, child != NULL && child != widget);
g_signal_connect_swapped (item, "activate", G_CALLBACK (copy_cb), child);
gtk_container_add (GTK_CONTAINER (menu), item);
item = gtk_menu_item_new_with_label ("Paste");
clipboard = gdk_display_get_clipboard (gdk_display_get_default ());
gtk_widget_set_sensitive (item,
gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (clipboard), GTK_TYPE_DEMO_WIDGET));
g_signal_connect_swapped (item, "activate", G_CALLBACK (paste_cb), widget);
gtk_container_add (GTK_CONTAINER (menu), item);
item = gtk_menu_item_new_with_label ("Delete");
gtk_widget_set_sensitive (item, child != NULL && child != widget);
g_signal_connect_swapped (item, "activate", G_CALLBACK (delete_cb), child);
gtk_container_add (GTK_CONTAINER (menu), item);
rect.x = x;
rect.y = y;
rect.width = 0;
rect.height = 0;
gtk_menu_popup_at_rect (GTK_MENU (menu),
gtk_widget_get_window (widget),
&rect,
GDK_GRAVITY_NORTH_WEST,
GDK_GRAVITY_NORTH_WEST,
NULL);
return;
}
}
static void
released_cb (GtkGesture *gesture,
int n_press,
double x,
double y,
gpointer data)
{
GtkWidget *widget;
GtkWidget *child;
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
child = gtk_widget_pick (widget, x, y);
if (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)) == GDK_BUTTON_PRIMARY)
{
if (child != NULL && child != widget)
edit_cb (child);
}
}
static GtkWidget *window = NULL;
GtkWidget *
do_dnd (GtkWidget *do_widget)
{
if (!window)
{
GtkWidget *vbox, *fixed;
GtkGesture *multipress;
GtkCssProvider *provider;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Drag-and-drop");
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
fixed = gtk_fixed_new ();
gtk_box_pack_start (GTK_BOX (vbox), fixed);
gtk_widget_set_hexpand (fixed, TRUE);
gtk_widget_set_vexpand (fixed, TRUE);
multipress = gtk_gesture_multi_press_new (fixed);
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (multipress), 0);
g_signal_connect (multipress, "pressed", G_CALLBACK (pressed_cb), NULL);
g_signal_connect (multipress, "released", G_CALLBACK (released_cb), NULL);
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (provider, "/dnd/dnd.css");
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
800);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}

3
demos/gtk-demo/dnd.css Normal file
View File

@@ -0,0 +1,3 @@
spinner.demo {
opacity: 1;
}

View File

@@ -6,7 +6,7 @@
<child type="titlebar">
<object class="GtkHeaderBar" id="">
<property name="visible">True</property>
<property name="show-close-button">True</property>
<property name="show-title-buttons">True</property>
<child>
<object class="GtkLabel" id="info_label">
<property name="visible">True</property>

View File

@@ -84,7 +84,6 @@
<object class="GtkImage" id="kern_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -137,7 +136,6 @@
<object class="GtkImage" id="liga_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -169,7 +167,6 @@
<object class="GtkImage" id="dlig_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -201,7 +198,6 @@
<object class="GtkImage" id="hlig_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -233,7 +229,6 @@
<object class="GtkImage" id="clig_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -286,7 +281,6 @@
<object class="GtkImage" id="smcp_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -318,7 +312,6 @@
<object class="GtkImage" id="c2sc_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -350,7 +343,6 @@
<object class="GtkImage" id="pcap_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -382,7 +374,6 @@
<object class="GtkImage" id="c2pc_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -414,7 +405,6 @@
<object class="GtkImage" id="unic_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -446,7 +436,6 @@
<object class="GtkImage" id="cpsp_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -478,7 +467,6 @@
<object class="GtkImage" id="case_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -532,7 +520,6 @@
<property name="visible">1</property>
<property name="opacity">0</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -555,7 +542,6 @@
<object class="GtkImage" id="lnum_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -579,7 +565,6 @@
<object class="GtkImage" id="onum_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -625,7 +610,6 @@
<property name="visible">1</property>
<property name="opacity">0</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -648,7 +632,6 @@
<object class="GtkImage" id="pnum_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -672,7 +655,6 @@
<object class="GtkImage" id="tnum_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -718,7 +700,6 @@
<property name="visible">1</property>
<property name="opacity">0</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -741,7 +722,6 @@
<object class="GtkImage" id="frac_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -765,7 +745,6 @@
<object class="GtkImage" id="afrc_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -810,7 +789,6 @@
<object class="GtkImage" id="zero_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -842,7 +820,6 @@
<object class="GtkImage" id="nalt_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -874,7 +851,6 @@
<object class="GtkImage" id="sinf_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -927,7 +903,6 @@
<object class="GtkImage" id="swsh_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -959,7 +934,6 @@
<object class="GtkImage" id="cswh_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -991,7 +965,6 @@
<object class="GtkImage" id="locl_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -1023,7 +996,6 @@
<object class="GtkImage" id="calt_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -1055,7 +1027,6 @@
<object class="GtkImage" id="hist_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -1087,7 +1058,6 @@
<object class="GtkImage" id="salt_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -1119,7 +1089,6 @@
<object class="GtkImage" id="titl_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -1151,7 +1120,6 @@
<object class="GtkImage" id="rand_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -1183,7 +1151,6 @@
<object class="GtkImage" id="subs_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -1215,7 +1182,6 @@
<object class="GtkImage" id="sups_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -1268,7 +1234,6 @@
<object class="GtkImage" id="init_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -1300,7 +1265,6 @@
<object class="GtkImage" id="medi_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -1332,7 +1296,6 @@
<object class="GtkImage" id="fina_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -1364,7 +1327,6 @@
<object class="GtkImage" id="isol_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -1417,7 +1379,6 @@
<object class="GtkImage" id="ss01_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -1449,7 +1410,6 @@
<object class="GtkImage" id="ss02_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -1481,7 +1441,6 @@
<object class="GtkImage" id="ss03_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -1513,7 +1472,6 @@
<object class="GtkImage" id="ss04_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>
@@ -1545,7 +1503,6 @@
<object class="GtkImage" id="ss05_pres">
<property name="visible">1</property>
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<child>

View File

@@ -830,6 +830,7 @@ draw_spinbutton (GtkWidget *widget,
GtkIconTheme *icon_theme;
GtkIconInfo *icon_info;
GdkPixbuf *pixbuf;
GdkTexture *texture;
gint icon_width, icon_height, icon_size;
gint button_width;
gint contents_x, contents_y, contents_width, contents_height;
@@ -857,23 +858,26 @@ draw_spinbutton (GtkWidget *widget,
icon_size = MIN (icon_width, icon_height);
icon_info = gtk_icon_theme_lookup_icon (icon_theme, "list-add-symbolic", icon_size, 0);
pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info, up_context, NULL, NULL);
texture = gdk_texture_new_for_pixbuf (pixbuf);
g_object_unref (icon_info);
draw_style_common (up_context, cr, x + width - button_width, y, button_width, *height,
&contents_x, &contents_y, &contents_width, &contents_height);
gtk_render_icon (up_context, cr, pixbuf, contents_x, contents_y + (contents_height - icon_size) / 2);
gtk_render_icon (up_context, cr, texture, contents_x, contents_y + (contents_height - icon_size) / 2);
g_object_unref (pixbuf);
g_object_unref (texture);
gtk_style_context_get (down_context,
"min-width", &icon_width, "min-height", &icon_height, NULL);
icon_size = MIN (icon_width, icon_height);
icon_info = gtk_icon_theme_lookup_icon (icon_theme, "list-remove-symbolic", icon_size, 0);
pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info, down_context, NULL, NULL);
texture = gdk_texture_new_for_pixbuf (pixbuf);
g_object_unref (icon_info);
draw_style_common (down_context, cr, x + width - 2 * button_width, y, button_width, *height,
&contents_x, &contents_y, &contents_width, &contents_height);
gtk_render_icon (down_context, cr, pixbuf, contents_x, contents_y + (contents_height - icon_size) / 2);
gtk_render_icon (down_context, cr, texture, contents_x, contents_y + (contents_height - icon_size) / 2);
g_object_unref (pixbuf);
g_object_unref (texture);
g_object_unref (down_context);
g_object_unref (up_context);

View File

@@ -106,7 +106,18 @@ gtk_fishbowl_measure (GtkWidget *widget,
if (!gtk_widget_get_visible (child->widget))
continue;
gtk_widget_measure (child->widget, orientation, -1, &child_min, &child_nat, NULL, NULL);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
gtk_widget_measure (child->widget, orientation, -1, &child_min, &child_nat, NULL, NULL);
}
else
{
int min_width;
gtk_widget_measure (child->widget, GTK_ORIENTATION_HORIZONTAL, -1, &min_width, NULL, NULL, NULL);
gtk_widget_measure (child->widget, orientation, min_width, &child_min, &child_nat, NULL, NULL);
}
*minimum = MAX (*minimum, child_min);
*natural = MAX (*natural, child_nat);
@@ -411,8 +422,10 @@ gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
GtkWidget *new_widget;
if (priv->use_icons)
new_widget = gtk_image_new_from_icon_name (get_random_icon_name (gtk_icon_theme_get_default ()),
GTK_ICON_SIZE_DIALOG);
{
new_widget = gtk_image_new_from_icon_name (get_random_icon_name (gtk_icon_theme_get_default ()));
gtk_image_set_icon_size (GTK_IMAGE (new_widget), GTK_ICON_SIZE_LARGE);
}
else
new_widget = g_object_new (get_random_widget_type (), NULL);

View File

@@ -30,13 +30,13 @@ do_headerbar (GtkWidget *do_widget)
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
header = gtk_header_bar_new ();
gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (header), TRUE);
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Welcome to Facebook - Log in, sign up or learn more");
gtk_header_bar_set_has_subtitle (GTK_HEADER_BAR (header), FALSE);
button = gtk_button_new ();
icon = g_themed_icon_new ("mail-send-receive-symbolic");
image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_BUTTON);
image = gtk_image_new_from_gicon (icon);
g_object_unref (icon);
gtk_container_add (GTK_CONTAINER (button), image);
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button);
@@ -44,10 +44,10 @@ do_headerbar (GtkWidget *do_widget)
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_style_context_add_class (gtk_widget_get_style_context (box), "linked");
button = gtk_button_new ();
gtk_container_add (GTK_CONTAINER (button), gtk_image_new_from_icon_name ("pan-start-symbolic", GTK_ICON_SIZE_BUTTON));
gtk_container_add (GTK_CONTAINER (button), gtk_image_new_from_icon_name ("pan-start-symbolic"));
gtk_container_add (GTK_CONTAINER (box), button);
button = gtk_button_new ();
gtk_container_add (GTK_CONTAINER (button), gtk_image_new_from_icon_name ("pan-end-symbolic", GTK_ICON_SIZE_BUTTON));
gtk_container_add (GTK_CONTAINER (button), gtk_image_new_from_icon_name ("pan-end-symbolic"));
gtk_container_add (GTK_CONTAINER (box), button);
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), box);

View File

@@ -353,7 +353,8 @@ do_images (GtkWidget *do_widget)
gtk_widget_set_valign (frame, GTK_ALIGN_CENTER);
gtk_box_pack_start (GTK_BOX (vbox), frame);
image = gtk_image_new_from_icon_name ("gtk3-demo", GTK_ICON_SIZE_DIALOG);
image = gtk_image_new_from_icon_name ("gtk3-demo");
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
gtk_container_add (GTK_CONTAINER (frame), image);
@@ -389,7 +390,8 @@ do_images (GtkWidget *do_widget)
gtk_box_pack_start (GTK_BOX (vbox), frame);
gicon = g_themed_icon_new_with_default_fallbacks ("battery-caution-charging-symbolic");
image = gtk_image_new_from_gicon (gicon, GTK_ICON_SIZE_DIALOG);
image = gtk_image_new_from_gicon (gicon);
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
gtk_container_add (GTK_CONTAINER (frame), image);

View File

@@ -197,7 +197,10 @@ gtk_message_row_update (GtkMessageRow *row)
gtk_button_set_label (GTK_BUTTON (priv->resent_by_button), priv->message->resent_by);
if (strcmp (priv->message->sender_nick, "@GTKtoolkit") == 0)
gtk_image_set_from_icon_name (priv->avatar_image, "gtk3-demo", GTK_ICON_SIZE_DND);
{
gtk_image_set_from_icon_name (priv->avatar_image, "gtk3-demo");
gtk_image_set_icon_size (priv->avatar_image, GTK_ICON_SIZE_LARGE);
}
else
gtk_image_set_from_pixbuf (priv->avatar_image, avatar_pixbuf_other);

View File

@@ -256,7 +256,7 @@ static gchar *types[] =
"GtkTreeIter ",
"GtkTreeViewColumn ",
"GdkDisplayManager ",
"GtkClipboard ",
"GdkClipboard ",
"GtkIconSize ",
"GtkImage ",
"GdkDragContext ",

View File

@@ -24,7 +24,7 @@
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar">
<property name="visible">1</property>
<property name="show-close-button">1</property>
<property name="show-title-buttons">1</property>
<child>
<object class="GtkButton">
<property name="visible">1</property>

View File

@@ -68,7 +68,7 @@ do_markup (GtkWidget *do_widget)
g_signal_connect (show_source, "toggled", G_CALLBACK (source_toggled), stack);
header = gtk_header_bar_new ();
gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (header), TRUE);
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), show_source);
gtk_window_set_titlebar (GTK_WINDOW (window), header);

View File

@@ -18,6 +18,7 @@ demos = files([
'cursors.c',
'dialog.c',
'drawingarea.c',
'dnd.c',
'editable_cells.c',
'entry_buffer.c',
'entry_completion.c',

View File

@@ -5,7 +5,7 @@
<child type="titlebar">
<object class="GtkHeaderBar">
<property name="visible">1</property>
<property name="show-close-button">1</property>
<property name="show-title-buttons">1</property>
<property name="title" translatable="yes">Model Button</property>
</object>
</child>

View File

@@ -19,7 +19,7 @@
<object class="GtkImage">
<property name="visible">1</property>
<property name="icon-name">face-cool-symbolic</property>
<property name="icon-size">6</property>
<property name="icon-size">large</property>
</object>
</child>
</object>
@@ -37,7 +37,7 @@
<object class="GtkImage">
<property name="visible">1</property>
<property name="icon-name">face-cool-symbolic</property>
<property name="icon-size">6</property>
<property name="icon-size">large</property>
</object>
</child>
</object>
@@ -55,7 +55,7 @@
<object class="GtkImage">
<property name="visible">1</property>
<property name="icon-name">face-cool-symbolic</property>
<property name="icon-size">6</property>
<property name="icon-size">large</property>
</object>
</child>
</object>
@@ -72,7 +72,7 @@
<object class="GtkImage">
<property name="visible">1</property>
<property name="icon-name">face-cool-symbolic</property>
<property name="icon-size">6</property>
<property name="icon-size">large</property>
</object>
</child>
</object>
@@ -90,7 +90,7 @@
<object class="GtkImage">
<property name="visible">1</property>
<property name="icon-name">face-cool-symbolic</property>
<property name="icon-size">6</property>
<property name="icon-size">large</property>
</object>
</child>
</object>
@@ -108,7 +108,7 @@
<object class="GtkImage">
<property name="visible">1</property>
<property name="icon-name">face-cool-symbolic</property>
<property name="icon-size">6</property>
<property name="icon-size">large</property>
</object>
</child>
</object>
@@ -126,7 +126,7 @@
<object class="GtkImage">
<property name="visible">1</property>
<property name="icon-name">face-cool-symbolic</property>
<property name="icon-size">6</property>
<property name="icon-size">large</property>
</object>
</child>
</object>
@@ -143,7 +143,7 @@
<object class="GtkImage">
<property name="visible">1</property>
<property name="icon-name">face-cool-symbolic</property>
<property name="icon-size">6</property>
<property name="icon-size">large</property>
</object>
</child>
</object>
@@ -161,7 +161,7 @@
<object class="GtkImage">
<property name="visible">1</property>
<property name="icon-name">face-cool-symbolic</property>
<property name="icon-size">6</property>
<property name="icon-size">large</property>
</object>
</child>
</object>

View File

@@ -40,7 +40,7 @@ do_sidebar (GtkWidget *do_widget)
gtk_widget_set_size_request (window, 500, 350);
header = gtk_header_bar_new ();
gtk_header_bar_set_show_close_button (GTK_HEADER_BAR(header), TRUE);
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR(header), TRUE);
gtk_window_set_titlebar (GTK_WINDOW(window), header);
gtk_window_set_title (GTK_WINDOW(window), "Stack Sidebar");
@@ -65,7 +65,7 @@ do_sidebar (GtkWidget *do_widget)
{
if (i == 0)
{
widget = gtk_image_new_from_icon_name ("help-about", GTK_ICON_SIZE_MENU);
widget = gtk_image_new_from_icon_name ("help-about");
gtk_image_set_pixel_size (GTK_IMAGE (widget), 256);
}
else

View File

@@ -129,6 +129,7 @@ insert_text (GtkTextBuffer *buffer)
GtkTextIter iter;
GtkTextIter start, end;
GdkPixbuf *pixbuf;
GdkTexture *texture;
GtkIconTheme *icon_theme;
icon_theme = gtk_icon_theme_get_default ();
@@ -138,6 +139,7 @@ insert_text (GtkTextBuffer *buffer)
GTK_ICON_LOOKUP_GENERIC_FALLBACK,
NULL);
g_assert (pixbuf);
texture = gdk_texture_new_for_pixbuf (pixbuf);
/* get start of buffer; each insertion will revalidate the
* iterator to point to just after the inserted text.
@@ -232,9 +234,9 @@ insert_text (GtkTextBuffer *buffer)
"heading", NULL);
gtk_text_buffer_insert (buffer, &iter, "The buffer can have images in it: ", -1);
gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
gtk_text_buffer_insert_texture (buffer, &iter, texture);
gtk_text_buffer_insert_texture (buffer, &iter, texture);
gtk_text_buffer_insert_texture (buffer, &iter, texture);
gtk_text_buffer_insert (buffer, &iter, " for example.\n\n", -1);
gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Spacing. ", -1,
@@ -378,6 +380,7 @@ insert_text (GtkTextBuffer *buffer)
gtk_text_buffer_apply_tag_by_name (buffer, "word_wrap", &start, &end);
g_object_unref (pixbuf);
g_object_unref (texture);
}
static gboolean

View File

@@ -39,14 +39,12 @@ canvas_item_new (GtkWidget *widget,
const gchar *icon_name;
GdkPixbuf *pixbuf;
GtkIconTheme *icon_theme;
int width;
icon_name = gtk_tool_button_get_icon_name (button);
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (widget));
gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &width, NULL);
pixbuf = gtk_icon_theme_load_icon (icon_theme,
icon_name,
width,
48,
GTK_ICON_LOOKUP_GENERIC_FALLBACK,
NULL);
@@ -168,7 +166,6 @@ palette_drag_data_received (GtkWidget *widget,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time,
gpointer data)
{
@@ -212,7 +209,6 @@ passive_canvas_drag_data_received (GtkWidget *widget,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time,
gpointer data)
{
@@ -287,7 +283,6 @@ interactive_canvas_drag_data_received (GtkWidget *widget,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time,
gpointer data)
@@ -327,7 +322,7 @@ interactive_canvas_drag_data_received (GtkWidget *widget,
canvas_items = g_list_append (canvas_items, item);
drop_item = NULL;
gtk_drag_finish (context, TRUE, FALSE, time);
gtk_drag_finish (context, TRUE, time);
} else
{
drop_item = item;
@@ -568,8 +563,8 @@ do_toolpalette (GtkWidget *do_widget)
contents = gtk_drawing_area_new ();
g_object_connect (contents,
"signal::draw", canvas_draw, NULL,
"signal::drag-data-received", passive_canvas_drag_data_received, NULL,
"draw", canvas_draw, NULL,
"drag-data-received", passive_canvas_drag_data_received, NULL,
NULL);
gtk_tool_palette_add_drag_dest (GTK_TOOL_PALETTE (palette),
@@ -594,11 +589,11 @@ do_toolpalette (GtkWidget *do_widget)
contents = gtk_drawing_area_new ();
g_object_connect (contents,
"signal::draw", canvas_draw, NULL,
"signal::drag-motion", interactive_canvas_drag_motion, NULL,
"signal::drag-data-received", interactive_canvas_drag_data_received, NULL,
"signal::drag-leave", interactive_canvas_drag_leave, contents,
"signal::drag-drop", interactive_canvas_drag_drop, NULL,
"draw", canvas_draw, NULL,
"drag-motion", interactive_canvas_drag_motion, NULL,
"drag-data-received", interactive_canvas_drag_data_received, NULL,
"drag-leave", interactive_canvas_drag_leave, contents,
"drag-drop", interactive_canvas_drag_drop, NULL,
NULL);
gtk_tool_palette_add_drag_dest (GTK_TOOL_PALETTE (palette),

View File

@@ -9,12 +9,106 @@
#include "gtkfishbowl.h"
GtkWidget *allow_changes;
GtkWidget *fishbowl;
static GtkWidget *
create_button (void)
{
return gtk_button_new_with_label ("Button");;
}
static GtkWidget *
create_font_button (void)
{
return gtk_font_button_new ();
}
static GtkWidget *
create_level_bar (void)
{
GtkWidget *w = gtk_level_bar_new_for_interval (0, 100);
gtk_level_bar_set_value (GTK_LEVEL_BAR (w), 50);
/* Force them to be a bit larger */
gtk_widget_set_size_request (w, 200, -1);
return w;
}
static GtkWidget *
create_spinner (void)
{
GtkWidget *w = gtk_spinner_new ();
gtk_spinner_start (GTK_SPINNER (w));
return w;
}
static GtkWidget *
create_spinbutton (void)
{
GtkWidget *w = gtk_spin_button_new_with_range (0, 10, 1);
return w;
}
static GtkWidget *
create_label (void)
{
GtkWidget *w = gtk_label_new ("pLorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.");
gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
gtk_label_set_max_width_chars (GTK_LABEL (w), 100);
return w;
}
static const struct {
const char *name;
GtkWidget * (*create_func) (void);
} widget_types[] = {
{ "Button", create_button },
{ "Fontbutton", create_font_button },
{ "Levelbar" , create_level_bar },
{ "Label" , create_label },
{ "Spinner" , create_spinner },
{ "Spinbutton", create_spinbutton },
};
static int selected_widget_type = -1;
static const int N_WIDGET_TYPES = G_N_ELEMENTS (widget_types);
#define N_STATS 5
#define STATS_UPDATE_TIME G_USEC_PER_SEC
static void
set_widget_type (GtkWidget *headerbar,
int widget_type_index)
{
GList *children, *l;
if (widget_type_index == selected_widget_type)
return;
/* Remove everything */
children = gtk_container_get_children (GTK_CONTAINER (fishbowl));
for (l = children; l; l = l->next)
{
gtk_container_remove (GTK_CONTAINER (fishbowl), (GtkWidget*)l->data);
}
g_list_free (children);
selected_widget_type = widget_type_index;
gtk_header_bar_set_title (GTK_HEADER_BAR (headerbar),
widget_types[selected_widget_type].name);
}
typedef struct _Stats Stats;
struct _Stats {
gint64 last_stats;
@@ -69,7 +163,7 @@ do_stats (GtkWidget *widget,
{
n_frames += stats->frame_counter[i];
}
new_label = g_strdup_printf ("widgets - %.1f fps",
(double) G_USEC_PER_SEC * n_frames
/ (N_STATS * STATS_UPDATE_TIME));
@@ -96,7 +190,7 @@ do_stats (GtkWidget *widget,
stats->frame_counter[stats->stats_index] = 0;
stats->item_counter[stats->stats_index] = stats->item_counter[(stats->stats_index + N_STATS - 1) % N_STATS];
stats->last_stats = frame_time;
if (suggested_change)
*suggested_change = stats->last_suggestion;
else
@@ -129,18 +223,74 @@ move_fish (GtkWidget *bowl,
gpointer info_label)
{
gint suggested_change = 0;
do_stats (bowl,
info_label,
!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (allow_changes)) ? &suggested_change : NULL);
gtk_fishbowl_set_count (GTK_FISHBOWL (bowl),
gtk_fishbowl_get_count (GTK_FISHBOWL (bowl)) + suggested_change);
do_stats (bowl, info_label, &suggested_change);
if (suggested_change > 0)
{
int i;
for (i = 0; i < suggested_change; i ++)
{
GtkWidget *new_widget = widget_types[selected_widget_type].create_func ();
gtk_container_add (GTK_CONTAINER (fishbowl), new_widget);
}
}
else if (suggested_change < 0)
{
GList *children, *l;
int n_removed = 0;
children = gtk_container_get_children (GTK_CONTAINER (fishbowl));
for (l = children; l; l = l->next)
{
gtk_container_remove (GTK_CONTAINER (fishbowl), (GtkWidget *)l->data);
n_removed ++;
if (n_removed >= (-suggested_change))
break;
}
g_list_free (children);
}
stats_update (bowl);
return G_SOURCE_CONTINUE;
}
static void
next_button_clicked_cb (GtkButton *source,
gpointer user_data)
{
GtkWidget *headerbar = user_data;
int new_index;
if (selected_widget_type + 1 >= N_WIDGET_TYPES)
new_index = 0;
else
new_index = selected_widget_type + 1;
set_widget_type (headerbar, new_index);
}
static void
prev_button_clicked_cb (GtkButton *source,
gpointer user_data)
{
GtkWidget *headerbar = user_data;
int new_index;
if (selected_widget_type - 1 < 0)
new_index = N_WIDGET_TYPES - 1;
else
new_index = selected_widget_type - 1;
set_widget_type (headerbar, new_index);
}
GtkWidget *
do_widgetbowl (GtkWidget *do_widget)
{
@@ -148,25 +298,55 @@ do_widgetbowl (GtkWidget *do_widget)
if (!window)
{
GtkBuilder *builder;
GtkWidget *bowl, *info_label;
GtkWidget *info_label;
GtkWidget *count_label;
GtkWidget *titlebar;
GtkWidget *title_box;
GtkWidget *left_box;
GtkWidget *next_button;
GtkWidget *prev_button;
g_type_ensure (GTK_TYPE_FISHBOWL);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
titlebar = gtk_header_bar_new ();
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (titlebar), TRUE);
info_label = gtk_label_new ("widget - 00.0 fps");
count_label = gtk_label_new ("0");
fishbowl = gtk_fishbowl_new ();
title_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
prev_button = gtk_button_new_from_icon_name ("pan-start-symbolic");
next_button = gtk_button_new_from_icon_name ("pan-end-symbolic");
left_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
g_object_bind_property (fishbowl, "count", count_label, "label", 0);
g_signal_connect (next_button, "clicked", G_CALLBACK (next_button_clicked_cb), titlebar);
g_signal_connect (prev_button, "clicked", G_CALLBACK (prev_button_clicked_cb), titlebar);
gtk_fishbowl_set_animating (GTK_FISHBOWL (fishbowl), TRUE);
gtk_widget_set_hexpand (title_box, TRUE);
gtk_widget_set_halign (title_box, GTK_ALIGN_END);
gtk_window_set_titlebar (GTK_WINDOW (window), titlebar);
gtk_container_add (GTK_CONTAINER (title_box), count_label);
gtk_container_add (GTK_CONTAINER (title_box), info_label);
gtk_header_bar_pack_end (GTK_HEADER_BAR (titlebar), title_box);
gtk_container_add (GTK_CONTAINER (window), fishbowl);
gtk_style_context_add_class (gtk_widget_get_style_context (left_box), "linked");
gtk_container_add (GTK_CONTAINER (left_box), prev_button);
gtk_container_add (GTK_CONTAINER (left_box), next_button);
gtk_header_bar_pack_start (GTK_HEADER_BAR (titlebar), left_box);
builder = gtk_builder_new_from_resource ("/fishbowl/fishbowl.ui");
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
bowl = GTK_WIDGET (gtk_builder_get_object (builder, "bowl"));
gtk_fishbowl_set_use_icons (GTK_FISHBOWL (bowl), FALSE);
info_label = GTK_WIDGET (gtk_builder_get_object (builder, "info_label"));
allow_changes = GTK_WIDGET (gtk_builder_get_object (builder, "changes_allow"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
gtk_widget_realize (window);
gtk_widget_add_tick_callback (bowl, move_fish, info_label, NULL);
gtk_widget_add_tick_callback (fishbowl, move_fish, info_label, NULL);
set_widget_type (titlebar, 0);
}
if (!gtk_widget_get_visible (window))

View File

@@ -5,8 +5,8 @@
#include <gtk/gtk.h>
/* Drag 'n Drop */
static GtkTargetEntry target_table[] = {
{ "text/uri-list", 0, 0 },
static const char *target_table[] = {
"text/uri-list"
};
typedef struct
@@ -94,13 +94,9 @@ get_icon (GtkWidget *image, const gchar *name, gint size)
static void
set_image (GtkWidget *image, const gchar *name, gint size)
{
GdkPixbuf *pixbuf;
gtk_image_set_from_icon_name (GTK_IMAGE (image), name, 1);
gtk_image_set_from_icon_name (GTK_IMAGE (image), name);
gtk_image_set_pixel_size (GTK_IMAGE (image), size);
pixbuf = get_icon (image, name, size);
gtk_drag_source_set_icon_pixbuf (image, pixbuf);
g_object_unref (pixbuf);
gtk_drag_source_set_icon_name (image, name);
}
static void
@@ -303,10 +299,10 @@ static void
copy_to_clipboard (GtkButton *button,
IconBrowserWindow *win)
{
GtkClipboard *clipboard;
GdkClipboard *clipboard;
clipboard = gtk_clipboard_get_default (gdk_display_get_default ());
gtk_clipboard_set_text (clipboard, gtk_window_get_title (GTK_WINDOW (win->details)), -1);
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (win));
gdk_clipboard_set_text (clipboard, gtk_window_get_title (GTK_WINDOW (win->details)));
}
static gboolean
@@ -390,7 +386,7 @@ get_image_data (GtkWidget *widget,
image = gtk_bin_get_child (GTK_BIN (widget));
gtk_image_get_icon_name (GTK_IMAGE (image), &name, NULL);
name = gtk_image_get_icon_name (GTK_IMAGE (image));
size = gtk_image_get_pixel_size (GTK_IMAGE (image));
pixbuf = get_icon (image, name, size);
@@ -413,7 +409,7 @@ get_scalable_image_data (GtkWidget *widget,
const gchar *name;
image = gtk_bin_get_child (GTK_BIN (widget));
gtk_image_get_icon_name (GTK_IMAGE (image), &name, NULL);
name = gtk_image_get_icon_name (GTK_IMAGE (image));
info = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_default (), name, -1, 0);
file = g_file_new_for_path (gtk_icon_info_get_filename (info));
@@ -430,7 +426,7 @@ get_scalable_image_data (GtkWidget *widget,
static void
setup_image_dnd (GtkWidget *image)
{
gtk_drag_source_set (image, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY);
gtk_drag_source_set (image, GDK_BUTTON1_MASK, NULL, GDK_ACTION_COPY);
gtk_drag_source_add_image_targets (image);
g_signal_connect (image, "drag-data-get", G_CALLBACK (get_image_data), NULL);
}
@@ -439,11 +435,14 @@ static void
setup_scalable_image_dnd (GtkWidget *image)
{
GtkWidget *parent;
GdkContentFormats *targets;
parent = gtk_widget_get_parent (image);
targets = gdk_content_formats_new (target_table, G_N_ELEMENTS (target_table));
gtk_drag_source_set (parent, GDK_BUTTON1_MASK,
target_table, G_N_ELEMENTS (target_table),
targets,
GDK_ACTION_COPY);
gdk_content_formats_unref (targets);
g_signal_connect (parent, "drag-data-get", G_CALLBACK (get_scalable_image_data), NULL);
}
@@ -451,23 +450,17 @@ setup_scalable_image_dnd (GtkWidget *image)
static void
icon_browser_window_init (IconBrowserWindow *win)
{
GtkTargetList *list;
GtkTargetEntry *targets;
gint n_targets;
GdkContentFormats *list;
gtk_widget_init_template (GTK_WIDGET (win));
list = gtk_target_list_new (NULL, 0);
gtk_target_list_add_text_targets (list, 0);
targets = gtk_target_table_new_from_list (list, &n_targets);
gtk_target_list_unref (list);
list = gdk_content_formats_new (NULL, 0);
list = gtk_content_formats_add_text_targets (list);
gtk_icon_view_enable_model_drag_source (GTK_ICON_VIEW (win->list),
GDK_BUTTON1_MASK,
targets, n_targets,
list,
GDK_ACTION_COPY);
gtk_target_table_free (targets, n_targets);
gdk_content_formats_unref (list);
setup_image_dnd (win->image1);
setup_image_dnd (win->image2);

View File

@@ -15,7 +15,7 @@
<object class="GtkHeaderBar" id="header">
<property name="visible">True</property>
<property name="title" translatable="yes">Icon Browser</property>
<property name="show-close-button">True</property>
<property name="show-title-buttons">True</property>
<child type="title">
<object class="GtkBox">
<property name="visible">True</property>
@@ -50,7 +50,6 @@
<object class="GtkImage" id="search-icon">
<property name="visible">True</property>
<property name="icon-name">edit-find-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
</object>

View File

@@ -1232,10 +1232,10 @@ static void
handle_cutcopypaste (GtkWidget *button, GtkWidget *textview)
{
GtkTextBuffer *buffer;
GtkClipboard *clipboard;
GdkClipboard *clipboard;
const gchar *id;
clipboard = gtk_widget_get_clipboard (textview, GDK_SELECTION_CLIPBOARD);
clipboard = gtk_widget_get_clipboard (textview);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview));
id = gtk_buildable_get_name (GTK_BUILDABLE (button));
@@ -1250,13 +1250,13 @@ handle_cutcopypaste (GtkWidget *button, GtkWidget *textview)
}
static void
clipboard_owner_change (GtkClipboard *clipboard, GdkEvent *event, GtkWidget *button)
clipboard_formats_notify (GdkClipboard *clipboard, GdkEvent *event, GtkWidget *button)
{
const gchar *id;
gboolean has_text;
id = gtk_buildable_get_name (GTK_BUILDABLE (button));
has_text = gtk_clipboard_wait_is_text_available (clipboard);
has_text = gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (clipboard), GTK_TYPE_TEXT_BUFFER);
if (strcmp (id, "pastebutton") == 0)
gtk_widget_set_sensitive (button, has_text);
@@ -1278,8 +1278,13 @@ textbuffer_notify_selection (GObject *object, GParamSpec *pspec, GtkWidget *butt
}
static gboolean
osd_frame_button_press (GtkWidget *frame, GdkEventButton *event, gpointer data)
osd_frame_pressed (GtkGestureMultiPress *gesture,
int press,
double x,
double y,
gpointer data)
{
GtkWidget *frame = data;
GtkWidget *osd;
gboolean visible;
@@ -1523,17 +1528,17 @@ g_test_permission_class_init (GTestPermissionClass *class)
permission_class->release_finish = release_finish;
}
static int icon_sizes[] = {0, 1, 2, 3, 4, 5, 6};
static void
update_buttons (GtkWidget *iv, int pos)
update_buttons (GtkWidget *iv, GtkIconSize size)
{
GtkWidget *button;
button = GTK_WIDGET (g_object_get_data (G_OBJECT (iv), "increase_button"));
gtk_widget_set_sensitive (button, pos + 1 < G_N_ELEMENTS (icon_sizes));
gtk_widget_set_sensitive (button, size != GTK_ICON_SIZE_LARGE);
button = GTK_WIDGET (g_object_get_data (G_OBJECT (iv), "decrease_button"));
gtk_widget_set_sensitive (button, pos > 0);
gtk_widget_set_sensitive (button, size != GTK_ICON_SIZE_NORMAL);
button = GTK_WIDGET (g_object_get_data (G_OBJECT (iv), "reset_button"));
gtk_widget_set_sensitive (button, size != GTK_ICON_SIZE_INHERIT);
}
static void
@@ -1541,17 +1546,14 @@ increase_icon_size (GtkWidget *iv)
{
GList *cells;
GtkCellRendererPixbuf *cell;
GtkIconSize size;
cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (iv));
cell = cells->data;
g_list_free (cells);
g_object_get (cell, "stock-size", &size, NULL);
size = MIN (size + 1, G_N_ELEMENTS (icon_sizes) - 1);
g_object_set (cell, "stock-size", size, NULL);
g_object_set (cell, "icon-size", GTK_ICON_SIZE_LARGE, NULL);
update_buttons (iv, size);
update_buttons (iv, GTK_ICON_SIZE_LARGE);
gtk_widget_queue_resize (iv);
}
@@ -1561,17 +1563,14 @@ decrease_icon_size (GtkWidget *iv)
{
GList *cells;
GtkCellRendererPixbuf *cell;
GtkIconSize size;
cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (iv));
cell = cells->data;
g_list_free (cells);
g_object_get (cell, "stock-size", &size, NULL);
size = MAX (size - 1, 1);
g_object_set (cell, "stock-size", size, NULL);
g_object_set (cell, "icon-size", GTK_ICON_SIZE_NORMAL, NULL);
update_buttons (iv, size);
update_buttons (iv, GTK_ICON_SIZE_NORMAL);
gtk_widget_queue_resize (iv);
}
@@ -1586,9 +1585,9 @@ reset_icon_size (GtkWidget *iv)
cell = cells->data;
g_list_free (cells);
g_object_set (cell, "stock-size", 2, NULL);
g_object_set (cell, "icon-size", GTK_ICON_SIZE_INHERIT, NULL);
update_buttons (iv, 2);
update_buttons (iv, GTK_ICON_SIZE_INHERIT);
gtk_widget_queue_resize (iv);
}
@@ -1656,6 +1655,7 @@ activate (GApplication *app)
gint i;
GPermission *permission;
GAction *action;
GtkGesture *gesture;
g_type_ensure (my_text_view_get_type ());
@@ -1674,7 +1674,6 @@ activate (GApplication *app)
gtk_builder_add_callback_symbol (builder, "on_page_combo_changed", (GCallback)on_page_combo_changed);
gtk_builder_add_callback_symbol (builder, "on_range_from_changed", (GCallback)on_range_from_changed);
gtk_builder_add_callback_symbol (builder, "on_range_to_changed", (GCallback)on_range_to_changed);
gtk_builder_add_callback_symbol (builder, "osd_frame_button_press", (GCallback)osd_frame_button_press);
gtk_builder_add_callback_symbol (builder, "tab_close_cb", (GCallback)tab_close_cb);
gtk_builder_add_callback_symbol (builder, "increase_icon_size", (GCallback)increase_icon_size);
gtk_builder_add_callback_symbol (builder, "decrease_icon_size", (GCallback)decrease_icon_size);
@@ -1843,8 +1842,8 @@ activate (GApplication *app)
G_CALLBACK (textbuffer_notify_selection), widget);
widget = (GtkWidget *)gtk_builder_get_object (builder, "pastebutton");
g_signal_connect (widget, "clicked", G_CALLBACK (handle_cutcopypaste), widget2);
g_signal_connect_object (gtk_widget_get_clipboard (widget2, GDK_SELECTION_CLIPBOARD), "owner-change",
G_CALLBACK (clipboard_owner_change), widget, 0);
g_signal_connect_object (gtk_widget_get_clipboard (widget2), "notify::formats",
G_CALLBACK (clipboard_formats_notify), widget, 0);
widget = (GtkWidget *)gtk_builder_get_object (builder, "osd_frame");
widget2 = (GtkWidget *)gtk_builder_get_object (builder, "totem_like_osd");
@@ -1888,6 +1887,9 @@ activate (GApplication *app)
g_object_set_data (G_OBJECT (widget), "increase_button", widget2);
widget2 = (GtkWidget *)gtk_builder_get_object (builder, "decrease_button");
g_object_set_data (G_OBJECT (widget), "decrease_button", widget2);
widget2 = (GtkWidget *)gtk_builder_get_object (builder, "reset_button");
g_object_set_data (G_OBJECT (widget), "reset_button", widget2);
reset_icon_size (widget);
adj = (GtkAdjustment *)gtk_builder_get_object (builder, "adjustment3");
widget = (GtkWidget *)gtk_builder_get_object (builder, "progressbar1");
@@ -1895,6 +1897,10 @@ activate (GApplication *app)
g_signal_connect (adj, "value-changed", G_CALLBACK (adjustment3_value_changed), widget);
g_signal_connect (adj, "value-changed", G_CALLBACK (adjustment3_value_changed), widget2);
widget = (GtkWidget *)gtk_builder_get_object (builder, "osd_frame");
gesture = gtk_gesture_multi_press_new (widget);
g_signal_connect (gesture, "pressed", G_CALLBACK (osd_frame_pressed), widget);
gtk_widget_show (GTK_WIDGET (window));
g_object_unref (builder);

View File

@@ -400,7 +400,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="title">GTK+ Widget Factory</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar1">
<property name="show-close-button">1</property>
<property name="show-title-buttons">1</property>
<child type="title">
<object class="GtkStackSwitcher" id="stack_switcher">
<property name="stack">toplevel_stack</property>
@@ -1851,7 +1851,6 @@ microphone-sensitivity-medium-symbolic</property>
<child>
<object class="GtkImage" id="listboxrow3image">
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="margin-top">6</property>
@@ -1881,7 +1880,6 @@ microphone-sensitivity-medium-symbolic</property>
<child>
<object class="GtkImage">
<property name="icon-name">object-select-symbolic</property>
<property name="icon-size">1</property>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="margin-top">6</property>
@@ -2402,7 +2400,6 @@ microphone-sensitivity-medium-symbolic</property>
<property name="model">iconsmodel</property>
<child>
<object class="GtkCellRendererPixbuf" id="iconviewcell">
<property name="stock-size">2</property>
</object>
<attributes>
<attribute name="icon-name">0</attribute>
@@ -2414,7 +2411,6 @@ microphone-sensitivity-medium-symbolic</property>
</child>
<child>
<object class="GtkToolbar">
<property name="icon-size">1</property>
<property name="toolbar-style">icons</property>
<style>
<class name="inline-toolbar"/>
@@ -2422,21 +2418,21 @@ microphone-sensitivity-medium-symbolic</property>
<child>
<object class="GtkToolButton" id="decrease_button">
<property name="icon-name">zoom-out-symbolic</property>
<property name="label">Remove item</property>
<property name="tooltip-text">Normal icons</property>
<signal name="clicked" handler="decrease_icon_size" object="iconview1" swapped="yes"/>
</object>
</child>
<child>
<object class="GtkToolButton" id="increase_button">
<property name="icon-name">zoom-in-symbolic</property>
<property name="label">Add item</property>
<property name="tooltip-text">Large icons</property>
<signal name="clicked" handler="increase_icon_size" object="iconview1" swapped="yes"/>
</object>
</child>
<child>
<object class="GtkToolButton" id="reset_button">
<property name="icon-name">zoom-original-symbolic</property>
<property name="label">Refresh</property>
<property name="tooltip-text">Inherited icon size</property>
<signal name="clicked" handler="reset_icon_size" object="iconview1" swapped="yes"/>
</object>
</child>
@@ -2900,7 +2896,6 @@ microphone-sensitivity-medium-symbolic</property>
<object class="GtkToolbar">
<property name="orientation">vertical</property>
<property name="toolbar-style">icons</property>
<property name="icon-size">1</property>
<child>
<object class="GtkToolButton" id="toolbutton1">
<property name="icon-name">document-open-symbolic</property>
@@ -3037,7 +3032,6 @@ microphone-sensitivity-medium-symbolic</property>
</child>
<child>
<object class="GtkFrame" id="osd_frame">
<signal name="button-press-event" handler="osd_frame_button_press"/>
<child>
<object class="GtkPaned">
<property name="wide-handle">1</property>

View File

@@ -21,7 +21,6 @@
<xi:include href="xml/general.xml" />
<xi:include href="xml/gdkdisplaymanager.xml" />
<xi:include href="xml/gdkdisplay.xml" />
<xi:include href="xml/gdkscreen.xml" />
<xi:include href="xml/gdkseat.xml" />
<xi:include href="xml/gdkmonitor.xml" />
<xi:include href="xml/gdkdevice.xml" />
@@ -41,6 +40,11 @@
<xi:include href="xml/event_structs.xml" />
<xi:include href="xml/keys.xml" />
<xi:include href="xml/selections.xml" />
<xi:include href="xml/gdkcontentformats.xml" />
<xi:include href="xml/gdkcontentprovider.xml" />
<xi:include href="xml/gdkcontentserializer.xml" />
<xi:include href="xml/gdkcontentdeserializer.xml" />
<xi:include href="xml/gdkclipboard.xml" />
<xi:include href="xml/dnd.xml" />
<xi:include href="xml/properties.xml" />
<xi:include href="xml/threads.xml" />
@@ -51,11 +55,6 @@
<xi:include href="xml/gdkapplaunchcontext.xml" />
</reference>
<reference>
<title>Deprecated</title>
<xi:include href="xml/gdkdevicemanager.xml" />
</reference>
<index id="api-index-full">
<title>Index of all symbols</title>
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>

View File

@@ -4,29 +4,6 @@
<SECTION>
<TITLE>General</TITLE>
<FILE>general</FILE>
gdk_notify_startup_complete
gdk_notify_startup_complete_with_id
gdk_set_allowed_backends
<SUBSECTION>
gdk_get_program_class
gdk_set_program_class
<SUBSECTION>
gdk_flush
<SUBSECTION>
GdkGrabStatus
gdk_set_double_click_time
<SUBSECTION>
gdk_beep
<SUBSECTION>
gdk_error_trap_push
gdk_error_trap_pop
gdk_error_trap_pop_ignored
<SUBSECTION>
GDK_WINDOWING_X11
@@ -95,7 +72,6 @@ GdkDisplay
gdk_display_open
gdk_display_get_default
gdk_display_get_name
gdk_display_get_device_manager
gdk_display_device_is_grabbed
gdk_display_beep
gdk_display_sync
@@ -106,8 +82,6 @@ gdk_display_get_event
gdk_display_peek_event
gdk_display_put_event
gdk_display_has_pending
gdk_display_set_double_click_time
gdk_display_set_double_click_distance
gdk_display_is_rgba
gdk_display_is_composited
gdk_display_supports_cursor_color
@@ -130,6 +104,9 @@ gdk_display_get_monitor
gdk_display_get_primary_monitor
gdk_display_get_monitor_at_point
gdk_display_get_monitor_at_window
gdk_display_get_clipboard
gdk_display_get_primary_clipboard
gdk_display_get_setting
<SUBSECTION Standard>
GDK_DISPLAY
@@ -155,6 +132,9 @@ gdk_display_manager_set_default_display
gdk_display_manager_list_displays
gdk_display_manager_open_display
<SUBSECTION>
gdk_set_allowed_backends
<SUBSECTION Standard>
GDK_DISPLAY_MANAGER
GDK_DISPLAY_MANAGER_CLASS
@@ -197,7 +177,7 @@ gdk_rgba_get_type
<FILE>windows</FILE>
GdkWindow
GdkWindowType
GdkWindowWindowClass
GdkWindowClass
GdkWindowHints
GdkGeometry
GdkGravity
@@ -348,8 +328,6 @@ gdk_window_get_device_cursor
gdk_window_set_device_cursor
gdk_window_get_device_events
gdk_window_set_device_events
gdk_window_get_source_events
gdk_window_set_source_events
gdk_window_get_event_compression
gdk_window_set_event_compression
@@ -386,6 +364,48 @@ gdk_window_impl_get_type
gdk_fullscreen_mode_get_type
</SECTION>
<SECTION>
<FILE>gdkcontentformats</FILE>
<TITLE>Content Formats</TITLE>
gdk_intern_mime_type
<SUBSECTION>
GdkContentFormats
gdk_content_formats_new
gdk_content_formats_new_for_gtype
gdk_content_formats_ref
gdk_content_formats_unref
gdk_content_formats_print
gdk_content_formats_to_string
gdk_content_formats_get_gtypes
gdk_content_formats_get_mime_types
gdk_content_formats_union
gdk_content_formats_match
gdk_content_formats_match_gtype
gdk_content_formats_match_mime_type
gdk_content_formats_contain_gtype
gdk_content_formats_contain_mime_type
<SUBSECTION>
gdk_content_formats_union_serialize_gtypes
gdk_content_formats_union_deserialize_gtypes
gdk_content_formats_union_serialize_mime_types
gdk_content_formats_union_deserialize_mime_types
<SUBSECTION>
GdkContentFormatsBuilder
gdk_content_formats_builder_new
gdk_content_formats_builder_free
gdk_content_formats_builder_add_formats
gdk_content_formats_builder_add_gtype
gdk_content_formats_builder_add_mime_type
<SUBSECTION Private>
GDK_TYPE_FILE_LIST
gdk_file_list_get_type
gdk_content_formats_get_type
</SECTION>
<SECTION>
<TITLE>Selections</TITLE>
<FILE>selections</FILE>
@@ -421,7 +441,6 @@ gdk_selection_send_notify_for_display
GdkAtom
GDK_ATOM_TO_POINTER
GDK_POINTER_TO_ATOM
GDK_NONE
gdk_text_property_to_utf8_list_for_display
gdk_utf8_to_string_target
gdk_atom_intern
@@ -645,6 +664,7 @@ gdk_device_pad_get_type
<FILE>gdkseat</FILE>
GdkSeat
GdkSeatCapabilities
GdkGrabStatus
GdkSeatGrabPrepareFunc
gdk_seat_get_display
gdk_seat_grab
@@ -653,6 +673,7 @@ gdk_seat_get_capabilities
gdk_seat_get_pointer
gdk_seat_get_keyboard
gdk_seat_get_slaves
gdk_seat_get_master_pointers
<SUBSECTION Standard>
GDK_SEAT
@@ -665,27 +686,6 @@ gdk_seat_get_type
gdk_seat_capabilities_get_type
</SECTION>
<SECTION>
<TITLE>GdkDeviceManager</TITLE>
<FILE>gdkdevicemanager</FILE>
GdkDeviceManager
gdk_disable_multidevice
gdk_device_manager_get_display
gdk_device_manager_list_devices
<SUBSECTION Standard>
GDK_DEVICE_MANAGER
GDK_DEVICE_MANAGER_CLASS
GDK_DEVICE_MANAGER_GET_CLASS
GDK_IS_DEVICE_MANAGER
GDK_IS_DEVICE_MANAGER_CLASS
GDK_TYPE_DEVICE_MANAGER
<SUBSECTION Private>
GdkDeviceManagerClass
gdk_device_manager_get_type
</SECTION>
<SECTION>
<TITLE>Events</TITLE>
<FILE>events</FILE>
@@ -701,10 +701,6 @@ GDK_BUTTON_MIDDLE
GDK_BUTTON_SECONDARY
<SUBSECTION>
gdk_events_pending
gdk_event_peek
gdk_event_get
gdk_event_put
gdk_event_new
gdk_event_copy
gdk_event_free
@@ -789,7 +785,6 @@ GdkCrossingMode
GdkNotifyType
GdkPropertyState
GdkWindowState
GdkOwnerChange
<SUBSECTION Standard>
GDK_TYPE_CROSSING_MODE
@@ -810,32 +805,32 @@ gdk_owner_change_get_type
<FILE>textures</FILE>
GdkTexture
gdk_texture_new_for_data
gdk_texture_new_for_surface
gdk_texture_new_for_pixbuf
gdk_texture_new_from_resource
gdk_texture_new_from_file
gdk_texture_get_width
gdk_texture_get_height
gdk_texture_download
<SUBSECTION Standard>
GdkTextureClass
gdk_texture_get_type
GDK_TYPE_TEXTURE
GDK_IS_TEXTURE
GDK_TEXTURE
</SECTION>
<SECTION>
<TITLE>Cursors</TITLE>
<FILE>cursors</FILE>
GdkCursor
gdk_cursor_new_from_pixbuf
gdk_cursor_new_from_surface
gdk_cursor_new_from_texture
gdk_cursor_new_from_name
gdk_cursor_get_display
gdk_cursor_get_fallback
gdk_cursor_get_name
gdk_cursor_get_texture
gdk_cursor_get_hotspot_x
gdk_cursor_get_hotspot_y
gdk_cursor_get_texture
<SUBSECTION Standard>
GDK_TYPE_CURSOR
@@ -851,34 +846,25 @@ gdk_cursor_get_type
GdkDragContext
GdkDragCancelReason
gdk_drag_get_selection
gdk_drag_abort
gdk_drop_reply
gdk_drag_drop
gdk_drag_drop_done
gdk_drag_find_window
gdk_drag_begin
gdk_drag_begin_for_device
gdk_drag_begin_from_point
gdk_drag_motion
gdk_drop_finish
GdkDragProtocol
GdkDragAction
gdk_drag_status
gdk_drag_drop_succeeded
gdk_window_get_drag_protocol
gdk_drag_context_get_display
gdk_drag_context_get_actions
gdk_drag_context_get_suggested_action
gdk_drag_context_get_selected_action
gdk_drag_context_list_targets
gdk_drag_context_get_formats
gdk_drag_context_get_device
gdk_drag_context_set_device
gdk_drag_context_get_source_window
gdk_drag_context_get_dest_window
gdk_drag_context_get_protocol
gdk_drag_context_get_drag_window
gdk_drag_context_set_hotspot
gdk_drag_context_manage_dnd
<SUBSECTION Standard>
GDK_DRAG_CONTEXT
@@ -907,7 +893,9 @@ gdk_x11_lookup_xdisplay
gdk_x11_get_server_time
gdk_x11_device_get_id
gdk_x11_device_manager_lookup
gdk_disable_multidevice
gdk_x11_display_open
gdk_x11_display_set_program_class
gdk_x11_display_get_user_time
gdk_x11_display_broadcast_startup_message
gdk_x11_display_get_startup_notification_id
@@ -936,7 +924,6 @@ gdk_x11_screen_get_current_desktop
gdk_x11_window_foreign_new_for_display
gdk_x11_window_lookup_for_display
gdk_x11_window_get_xid
gdk_x11_window_set_hide_titlebar_when_maximized
gdk_x11_window_set_theme_variant
gdk_x11_window_set_user_time
gdk_x11_window_move_to_current_desktop
@@ -1077,7 +1064,6 @@ gdk_wayland_device_get_wl_pointer
gdk_wayland_device_get_wl_seat
gdk_wayland_display_get_wl_compositor
gdk_wayland_display_get_wl_display
gdk_wayland_display_get_xdg_shell
gdk_wayland_window_new_subsurface
gdk_wayland_window_get_wl_surface
gdk_wayland_window_set_use_custom_surface
@@ -1124,7 +1110,6 @@ gdk_wayland_window_get_type
<TITLE>Application launching</TITLE>
<FILE>gdkapplaunchcontext</FILE>
GdkAppLaunchContext
gdk_app_launch_context_set_screen
gdk_app_launch_context_set_desktop
gdk_app_launch_context_set_timestamp
gdk_app_launch_context_set_icon
@@ -1265,6 +1250,7 @@ gdk_drawing_context_get_window
gdk_drawing_context_get_clip
gdk_drawing_context_get_cairo_context
gdk_drawing_context_is_valid
gdk_drawing_context_get_paint_context
<SUBSECTION Standard>
gdk_drawing_context_get_type
@@ -1277,6 +1263,7 @@ GDK_IS_DRAWING_CONTEXT
<SECTION>
<FILE>gdkvulkancontext</FILE>
GdkVulkanContext
GdkVulkanError
gdk_vulkan_context_get_device
gdk_vulkan_context_get_draw_index
gdk_vulkan_context_get_draw_semaphore
@@ -1293,3 +1280,107 @@ gdk_vulkan_context_get_type
gdk_vulkan_error_quark
gdk_vulkan_strerror
</SECTION>
<SECTION>
<FILE>gdkclipboard</FILE>
GdkClipboard
gdk_clipboard_get_display
gdk_clipboard_get_formats
gdk_clipboard_is_local
gdk_clipboard_get_content
gdk_clipboard_store_async
gdk_clipboard_store_finish
gdk_clipboard_read_async
gdk_clipboard_read_finish
gdk_clipboard_read_value_async
gdk_clipboard_read_value_finish
gdk_clipboard_read_texture_async
gdk_clipboard_read_texture_finish
gdk_clipboard_read_text_async
gdk_clipboard_read_text_finish
gdk_clipboard_set_content
gdk_clipboard_set
gdk_clipboard_set_valist
gdk_clipboard_set_value
gdk_clipboard_set_text
gdk_clipboard_set_texture
<SUBSECTION Standard>
GDK_TYPE_CLIPBOARD
GDK_CLIPBOARD
GDK_IS_CLIPBOARD
gdk_clipboard_get_type
</SECTION>
<SECTION>
<FILE>gdkcontentprovider</FILE>
GdkContentProvider
gdk_content_provider_new_for_value
gdk_content_provider_new_for_bytes
gdk_content_provider_ref_formats
gdk_content_provider_ref_storable_formats
gdk_content_provider_content_changed
gdk_content_provider_write_mime_type_async
gdk_content_provider_write_mime_type_finish
gdk_content_provider_get_value
<SUBSECTION Standard>
GdkContentProviderClass
gdk_content_provider_get_type
</SECTION>
<SECTION>
<FILE>gdkcontentserializer</FILE>
GdkContentSerializer
GdkContentSerializeFunc
gdk_content_serializer_get_mime_type
gdk_content_serializer_get_gtype
gdk_content_serializer_get_value
gdk_content_serializer_get_output_stream
gdk_content_serializer_get_priority
gdk_content_serializer_get_cancellable
gdk_content_serializer_get_user_data
gdk_content_serializer_set_task_data
gdk_content_serializer_get_task_data
gdk_content_serializer_return_success
gdk_content_serializer_return_error
<SUBSECTION>
gdk_content_register_serializer
gdk_content_serialize_async
gdk_content_serialize_finish
<SUBSECTION Standard>
GDK_TYPE_CONTENT_SERIALIZER
GDK_CONTENT_SERIALIZER
GDK_IS_CONTENT_SERIALIZER
gdk_content_serializer_get_type
</SECTION>
<SECTION>
<FILE>gdkcontentdeserializer</FILE>
GdkContentDeserializer
GdkContentDeserializeFunc
gdk_content_deserializer_get_mime_type
gdk_content_deserializer_get_gtype
gdk_content_deserializer_get_value
gdk_content_deserializer_get_input_stream
gdk_content_deserializer_get_priority
gdk_content_deserializer_get_cancellable
gdk_content_deserializer_get_user_data
gdk_content_deserializer_set_task_data
gdk_content_deserializer_get_task_data
gdk_content_deserializer_return_success
gdk_content_deserializer_return_error
<SUBSECTION>
gdk_content_register_deserializer
gdk_content_deserialize_async
gdk_content_deserialize_finish
<SUBSECTION Standard>
GDK_TYPE_CONTENT_DESERIALIZER
GDK_CONTENT_DESERIALIZER
GDK_IS_CONTENT_DESERIALIZER
gdk_content_deserializer_get_type
</SECTION>

View File

@@ -1,7 +1,6 @@
gdk_app_launch_context_get_type
gdk_cursor_get_type
gdk_device_get_type
gdk_device_manager_get_type
gdk_device_pad_get_type
gdk_display_get_type
gdk_display_manager_get_type
@@ -11,7 +10,9 @@ gdk_frame_clock_get_type
gdk_gl_context_get_type
gdk_keymap_get_type
gdk_monitor_get_type
gdk_screen_get_type
gdk_seat_get_type
gdk_visual_get_type
gdk_window_get_type
gdk_content_serializer_get_type
gdk_content_deserializer_get_type
gdk_clipboard_get_type
gdk_content_formats_get_type

View File

@@ -6,8 +6,10 @@ private_headers = [
'gdkprivate.h',
'gdk-private.h',
'gdkapplaunchcontextprivate.h',
'gdkclipboardprivate.h',
'gdkcontentformatsprivate.h',
'gdkcontentproviderprivate.h',
'gdkcursorprivate.h',
'gdkdevicemanagerprivate.h',
'gdkdeviceprivate.h',
'gdkdisplaymanagerprivate.h',
'gdkdisplayprivate.h',
@@ -17,17 +19,17 @@ private_headers = [
'gdkglcontextprivate.h',
'gdkkeysprivate.h',
'gdkmonitorprivate.h',
'gdkpipeiostreamprivate.h',
'gdkscreenprivate.h',
'gdkseatdefaultprivate.h',
'gdkseatprivate.h',
'gdktextureprivate.h',
'gdkvisualprivate.h',
'gdkvulkancontextprivate.h',
'keyname-table.h',
'win32',
'x11',
'quartz',
'broadway',
'wayland',
'broadway'
]
images = [

View File

@@ -3,8 +3,6 @@
gsk_renderer_new_for_window
gsk_renderer_set_viewport
gsk_renderer_get_viewport
gsk_renderer_set_scale_factor
gsk_renderer_get_scale_factor
gsk_renderer_get_window
gsk_renderer_get_display
gsk_renderer_realize
@@ -35,7 +33,6 @@ gsk_render_node_serialize
gsk_render_node_deserialize
gsk_render_node_write_to_file
GskScalingFilter
gsk_render_node_set_scaling_filters
gsk_render_node_set_name
gsk_render_node_get_name
gsk_render_node_get_bounds

View File

@@ -470,8 +470,17 @@ We use <literallayout> for syntax productions, and each line is put in a <code>
<entry><code>none</code></entry>
<entry></entry>
<entry></entry>
<entry></entry>
<entry><ulink url="https://drafts.fxtf.org/filters/#FilterProperty">CSS3</ulink></entry>
<entry></entry>
</row>
<row>
<entry>gtkiconsize</entry>
<entry><code>〈length〉</code></entry>
<entry><code>none</code></entry>
<entry></entry>
<entry></entry>
<entry></entry>
<entry>Determines the size at which icons are displayed</entry>
</row>
</tbody>
</tgroup>

View File

@@ -294,6 +294,8 @@
<chapter id="Gestures">
<title>Gestures and event handling</title>
<xi:include href="xml/gtkeventcontroller.xml" />
<xi:include href="xml/gtkeventcontrollerscroll.xml" />
<xi:include href="xml/gtkeventcontrollermotion.xml" />
<xi:include href="xml/gtkgesture.xml" />
<xi:include href="xml/gtkgesturesingle.xml" />
<xi:include href="xml/gtkgesturedrag.xml" />

View File

@@ -358,7 +358,7 @@ gtk_center_box_get_center_widget
gtk_center_box_get_end_widget
gtk_center_box_set_baseline_position
gtk_center_box_get_baseline_position
<PRIVATE>
<SUBSECTION Private>
GTK_TYPE_CENTER_BOX
GTK_CENTER_BOX
GTK_CENTER_BOX_CLASS
@@ -1509,6 +1509,8 @@ gtk_image_clear
gtk_image_new
gtk_image_set_pixel_size
gtk_image_get_pixel_size
gtk_image_set_icon_size
gtk_image_get_icon_size
<SUBSECTION Standard>
GTK_IMAGE
GTK_IS_IMAGE
@@ -1596,9 +1598,6 @@ GtkIMMulticontextPrivate
<TITLE>GtkInvisible</TITLE>
GtkInvisible
gtk_invisible_new
gtk_invisible_new_for_screen
gtk_invisible_set_screen
gtk_invisible_get_screen
<SUBSECTION Standard>
GTK_INVISIBLE
GTK_IS_INVISIBLE
@@ -1927,8 +1926,8 @@ gtk_info_bar_set_message_type
gtk_info_bar_get_message_type
gtk_info_bar_get_action_area
gtk_info_bar_get_content_area
gtk_info_bar_get_show_close_button
gtk_info_bar_set_show_close_button
gtk_info_bar_get_show_title_buttons
gtk_info_bar_set_show_title_buttons
gtk_info_bar_get_revealed
gtk_info_bar_set_revealed
@@ -2840,7 +2839,7 @@ gtk_text_buffer_backspace
gtk_text_buffer_set_text
gtk_text_buffer_get_text
gtk_text_buffer_get_slice
gtk_text_buffer_insert_pixbuf
gtk_text_buffer_insert_texture
gtk_text_buffer_insert_child_anchor
gtk_text_buffer_create_child_anchor
gtk_text_buffer_create_mark
@@ -2882,25 +2881,6 @@ gtk_text_buffer_end_user_action
gtk_text_buffer_add_selection_clipboard
gtk_text_buffer_remove_selection_clipboard
<SUBSECTION Serialization>
GtkTextBufferTargetInfo
GtkTextBufferDeserializeFunc
gtk_text_buffer_deserialize
gtk_text_buffer_deserialize_get_can_create_tags
gtk_text_buffer_deserialize_set_can_create_tags
gtk_text_buffer_get_copy_target_list
gtk_text_buffer_get_deserialize_formats
gtk_text_buffer_get_paste_target_list
gtk_text_buffer_get_serialize_formats
gtk_text_buffer_register_deserialize_format
gtk_text_buffer_register_deserialize_tagset
gtk_text_buffer_register_serialize_format
gtk_text_buffer_register_serialize_tagset
GtkTextBufferSerializeFunc
gtk_text_buffer_serialize
gtk_text_buffer_unregister_deserialize_format
gtk_text_buffer_unregister_serialize_format
<SUBSECTION Standard>
GTK_TEXT_BUFFER
GTK_IS_TEXT_BUFFER
@@ -2932,7 +2912,7 @@ gtk_text_iter_get_slice
gtk_text_iter_get_text
gtk_text_iter_get_visible_slice
gtk_text_iter_get_visible_text
gtk_text_iter_get_pixbuf
gtk_text_iter_get_texture
gtk_text_iter_get_marks
gtk_text_iter_get_toggled_tags
gtk_text_iter_get_child_anchor
@@ -3044,7 +3024,6 @@ GtkTextTag
gtk_text_tag_new
gtk_text_tag_get_priority
gtk_text_tag_set_priority
gtk_text_tag_event
gtk_text_tag_changed
<SUBSECTION Standard>
GTK_TEXT_TAG
@@ -3108,8 +3087,6 @@ gtk_text_view_get_iter_at_location
gtk_text_view_get_iter_at_position
gtk_text_view_buffer_to_window_coords
gtk_text_view_window_to_buffer_coords
gtk_text_view_get_window
gtk_text_view_get_window_type
gtk_text_view_set_border_window_size
gtk_text_view_get_border_window_size
gtk_text_view_forward_display_line
@@ -3215,7 +3192,6 @@ GtkToggleButtonPrivate
GtkToolShell
GtkToolShellIface
gtk_tool_shell_get_ellipsize_mode
gtk_tool_shell_get_icon_size
gtk_tool_shell_get_orientation
gtk_tool_shell_get_style
gtk_tool_shell_get_text_alignment
@@ -3245,13 +3221,10 @@ gtk_toolbar_get_nth_item
gtk_toolbar_get_drop_index
gtk_toolbar_set_drop_highlight_item
gtk_toolbar_set_show_arrow
gtk_toolbar_unset_icon_size
gtk_toolbar_get_show_arrow
gtk_toolbar_get_style
gtk_toolbar_get_icon_size
gtk_toolbar_set_style
gtk_toolbar_set_icon_size
gtk_toolbar_unset_style
<SUBSECTION Standard>
@@ -3285,7 +3258,6 @@ gtk_tool_item_get_visible_vertical
gtk_tool_item_set_is_important
gtk_tool_item_get_is_important
gtk_tool_item_get_ellipsize_mode
gtk_tool_item_get_icon_size
gtk_tool_item_get_orientation
gtk_tool_item_get_toolbar_style
gtk_tool_item_get_text_alignment
@@ -3477,9 +3449,6 @@ gtk_tool_palette_get_expand
gtk_tool_palette_set_expand
gtk_tool_palette_get_group_position
gtk_tool_palette_set_group_position
gtk_tool_palette_get_icon_size
gtk_tool_palette_set_icon_size
gtk_tool_palette_unset_icon_size
gtk_tool_palette_get_style
gtk_tool_palette_set_style
gtk_tool_palette_unset_style
@@ -3989,7 +3958,7 @@ gtk_cell_view_new
gtk_cell_view_new_with_context
gtk_cell_view_new_with_text
gtk_cell_view_new_with_markup
gtk_cell_view_new_with_pixbuf
gtk_cell_view_new_with_texture
gtk_cell_view_set_model
gtk_cell_view_get_model
gtk_cell_view_set_displayed_row
@@ -4470,7 +4439,6 @@ gtk_snapshot_render_frame
gtk_snapshot_render_focus
gtk_snapshot_render_layout
gtk_snapshot_render_insertion_cursor
gtk_snapshot_render_icon
</SECTION>
<SECTION>
@@ -4521,8 +4489,6 @@ gtk_widget_set_sensitive
gtk_widget_set_parent
gtk_widget_set_parent_window
gtk_widget_get_parent_window
gtk_widget_set_device_enabled
gtk_widget_get_device_enabled
gtk_widget_get_toplevel
gtk_widget_get_ancestor
gtk_widget_is_ancestor
@@ -4559,6 +4525,7 @@ gtk_widget_get_child_visible
gtk_widget_get_parent
gtk_widget_get_settings
gtk_widget_get_clipboard
gtk_widget_get_primary_clipboard
gtk_widget_get_display
gtk_widget_get_size_request
gtk_widget_set_child_visible
@@ -4979,7 +4946,6 @@ gtk_widget_path_get_type
<SECTION>
<FILE>gtkstyleprovider</FILE>
<TITLE>GtkStyleProvider</TITLE>
GtkStyleProviderIface
GtkStyleProvider
GTK_STYLE_PROVIDER_PRIORITY_FALLBACK
GTK_STYLE_PROVIDER_PRIORITY_THEME
@@ -5219,25 +5185,6 @@ gtk_css_section_get_type
<FILE>gtkselection</FILE>
<TITLE>Selections</TITLE>
GtkSelectionData
GtkTargetEntry
GtkTargetList
GtkTargetPair
gtk_target_entry_new
gtk_target_entry_copy
gtk_target_entry_free
gtk_target_list_new
gtk_target_list_ref
gtk_target_list_unref
gtk_target_list_add
gtk_target_list_add_table
gtk_target_list_add_text_targets
gtk_target_list_add_image_targets
gtk_target_list_add_uri_targets
gtk_target_list_add_rich_text_targets
gtk_target_list_remove
gtk_target_list_find
gtk_target_table_free
gtk_target_table_new_from_list
gtk_selection_owner_set
gtk_selection_owner_set_for_display
gtk_selection_add_target
@@ -5251,13 +5198,14 @@ gtk_selection_data_set_pixbuf
gtk_selection_data_get_pixbuf
gtk_selection_data_set_surface
gtk_selection_data_get_surface
gtk_selection_data_set_texture
gtk_selection_data_get_texture
gtk_selection_data_set_uris
gtk_selection_data_get_uris
gtk_selection_data_get_targets
gtk_selection_data_targets_include_image
gtk_selection_data_targets_include_text
gtk_selection_data_targets_include_uri
gtk_selection_data_targets_include_rich_text
gtk_selection_data_get_selection
gtk_selection_data_get_data
gtk_selection_data_get_length
@@ -5269,7 +5217,6 @@ gtk_selection_data_get_target
gtk_targets_include_image
gtk_targets_include_text
gtk_targets_include_uri
gtk_targets_include_rich_text
gtk_selection_remove_all
gtk_selection_data_copy
gtk_selection_data_free
@@ -5278,67 +5225,12 @@ GTK_TYPE_SELECTION_DATA
GTK_TYPE_TARGET_LIST
<SUBSECTION Private>
gtk_selection_data_get_type
gtk_target_list_get_type
gtk_target_entry_get_type
</SECTION>
<SECTION>
<FILE>gtkclipboard</FILE>
<TITLE>Clipboards</TITLE>
GtkClipboard
GtkClipboardReceivedFunc
GtkClipboardTextReceivedFunc
GtkClipboardImageReceivedFunc
GtkClipboardTargetsReceivedFunc
GtkClipboardRichTextReceivedFunc
GtkClipboardURIReceivedFunc
GtkClipboardGetFunc
GtkClipboardClearFunc
gtk_clipboard_get
gtk_clipboard_get_for_display
gtk_clipboard_get_display
gtk_clipboard_get_default
gtk_clipboard_set_with_data
gtk_clipboard_set_with_owner
gtk_clipboard_get_owner
gtk_clipboard_clear
gtk_clipboard_set_text
gtk_clipboard_set_image
gtk_clipboard_set_surface
gtk_clipboard_request_contents
gtk_clipboard_request_text
gtk_clipboard_request_image
gtk_clipboard_request_targets
gtk_clipboard_request_rich_text
gtk_clipboard_request_uris
gtk_clipboard_wait_for_contents
gtk_clipboard_wait_for_text
gtk_clipboard_wait_for_image
gtk_clipboard_wait_for_surface
gtk_clipboard_wait_for_rich_text
gtk_clipboard_wait_for_uris
gtk_clipboard_wait_is_text_available
gtk_clipboard_wait_is_image_available
gtk_clipboard_wait_is_rich_text_available
gtk_clipboard_wait_is_uris_available
gtk_clipboard_wait_for_targets
gtk_clipboard_wait_is_target_available
gtk_clipboard_set_can_store
gtk_clipboard_store
gtk_clipboard_get_selection
<SUBSECTION Standard>
GTK_CLIPBOARD
GTK_TYPE_CLIPBOARD
GTK_IS_CLIPBOARD
<SUBSECTION Private>
gtk_clipboard_get_type
</SECTION>
<SECTION>
<FILE>gtkdnd</FILE>
<TITLE>Drag and Drop</TITLE>
GtkDestDefaults
GtkTargetFlags
GtkDragResult
<SUBSECTION Destination Side>
gtk_drag_dest_set
@@ -5361,12 +5253,12 @@ gtk_drag_begin_with_coordinates
gtk_drag_cancel
gtk_drag_set_icon_widget
gtk_drag_set_icon_surface
gtk_drag_set_icon_texture
gtk_drag_set_icon_name
gtk_drag_set_icon_gicon
gtk_drag_set_icon_default
gtk_drag_check_threshold
gtk_drag_source_set
gtk_drag_source_set_icon_pixbuf
gtk_drag_source_set_icon_surface
gtk_drag_source_set_icon_name
gtk_drag_source_set_icon_gicon
@@ -5449,7 +5341,6 @@ gtk_icon_theme_lookup_by_gicon_for_scale
gtk_icon_theme_load_icon
gtk_icon_theme_load_icon_for_scale
gtk_icon_theme_load_surface
gtk_icon_theme_load_texture
gtk_icon_theme_list_contexts
gtk_icon_theme_list_icons
gtk_icon_theme_get_icon_sizes
@@ -5461,6 +5352,7 @@ gtk_icon_info_get_base_scale
gtk_icon_info_get_filename
gtk_icon_info_load_icon
gtk_icon_info_load_surface
gtk_icon_info_load_texture
gtk_icon_info_load_icon_async
gtk_icon_info_load_icon_finish
gtk_icon_info_load_symbolic
@@ -6057,7 +5949,6 @@ gtk_application_get_active_window
GtkApplicationInhibitFlags
gtk_application_inhibit
gtk_application_uninhibit
gtk_application_is_inhibited
<SUBSECTION>
gtk_application_prefers_app_menu
@@ -6787,6 +6678,45 @@ GTK_GESTURE_SINGLE_GET_CLASS
gtk_gesture_single_get_type
</SECTION>
<SECTION>
<FILE>gtkeventcontrollerscroll</FILE>
<TITLE>GtkEventControlerScroll</TITLE>
GtkEventControllerScroll
GtkEventControllerScrollFlags
gtk_event_controller_scroll_new
gtk_event_controller_scroll_set_flags
gtk_event_controller_scroll_get_flags
<SUBSECTION Standard>
GTK_TYPE_EVENT_CONTROLLER_SCROLL
GTK_EVENT_CONTROLLER_SCROLL
GTK_EVENT_CONTROLLER_SCROLL_CLASS
GTK_IS_EVENT_CONTROLLER_SCROLL
GTK_IS_EVENT_CONTROLLER_SCROLL_CLASS
GTK_EVENT_CONTROLLER_SCROLL_GET_CLASS
<SUBSECTION Private>
gtk_event_controller_scroll_get_type
</SECTION>
<SECTION>
<FILE>gtkeventcontrollermotion</FILE>
<TITLE>GtkEventControlerMotion</TITLE>
GtkEventControllerMotion
gtk_event_controller_motion_new
<SUBSECTION Standard>
GTK_TYPE_EVENT_CONTROLLER_MOTION
GTK_EVENT_CONTROLLER_MOTION
GTK_EVENT_CONTROLLER_MOTION_CLASS
GTK_IS_EVENT_CONTROLLER_MOTION
GTK_IS_EVENT_CONTROLLER_MOTION_CLASS
GTK_EVENT_CONTROLLER_MOTION_GET_CLASS
<SUBSECTION Private>
gtk_event_controller_motion_get_type
</SECTION>
<SECTION>
<FILE>gtkgesturedrag</FILE>
<TITLE>GtkGestureDrag</TITLE>

View File

@@ -38,7 +38,6 @@ gtk_cell_renderer_toggle_get_type
gtk_cell_view_get_type
gtk_check_button_get_type
gtk_check_menu_item_get_type
gtk_clipboard_get_type
gtk_color_button_get_type
gtk_color_chooser_get_type
gtk_color_chooser_dialog_get_type
@@ -54,6 +53,8 @@ gtk_entry_buffer_get_type
gtk_entry_completion_get_type
gtk_entry_get_type
gtk_event_controller_get_type
gtk_event_controller_scroll_get_type
gtk_event_controller_motion_get_type
gtk_expander_get_type
gtk_file_chooser_button_get_type
gtk_file_chooser_dialog_get_type

View File

@@ -24,7 +24,7 @@
release of GTK+ 3.x. It includes all the necessary APIs and tools
to help you port your application to GTK+ 4. If you are still using
an older version of GTK+ 3.x, you should first get your application
to build and work with 3.22.
to build and work with the latest minor release in the 3.22 series.
</para>
<section>
@@ -56,7 +56,7 @@
<title>Do not use widget style properties</title>
<para>
Style properties do not exist in GTK+ 4. You should stop using them in
your custom CSS.
your custom CSS and in your code.
</para>
</section>
@@ -85,6 +85,11 @@
GTK+ 4 always uses RGBA visuals for its windows; you should make
sure that your code works with that.
</para>
<para>
At the same time, you should stop using GdkVisual APIs, this object
not longer exist in GTK+ 4. Most of its APIs are deprecated already
and not useful when dealing with RGBA visuals.
</para>
</section>
<section>
@@ -100,7 +105,7 @@
widgets. If you previously set the fill child property to %TRUE, you can
achieve the same effect by setting the halign or valign properties to
%GTK_ALIGN_FILL, depending on the parent box -- halign for a horizontal
box, valign for a vertial one.
box, valign for a vertical one.
</para>
<para>
#GtkBox also uses the expand child property. It can be replaced by setting
@@ -108,12 +113,13 @@
old behavior of the #GtkBox's expand child property, you need to set
#GtkWidget:hexpand on the child widgets of a horizontal #GtkBox and
#GtkWidget:vexpand on the child widgets of a vertical #GtkBox.
</para>
<para>
Note that there's a subtle but important difference between #GtkBox's
expand and fill child properties and the ones in #GtkWidget: setting
#GtkWidget:hexpand or #GtkWidget:vexpand to %TRUE will propagate up
the widget hierarchy, so a pixel-perfect port migth require a reset
of the expansion flags to %FALSE in a parent widget higher up the hierarchy.
the widget hierarchy, so a pixel-perfect port might require you to reset
the expansion flags to %FALSE in a parent widget higher up the hierarchy.
</para>
</section>
@@ -123,8 +129,8 @@
The getters in the GtkStyleContext API, such as
gtk_style_context_get_property(), gtk_style_context_get(),
or gtk_style_context_get_color() only accept the context's current
state for their state argument. Update all callers to pass the current
state.
state for their state argument. You should update all callers to pass
the current state.
</para>
</section>
@@ -148,6 +154,33 @@
have been either impossible or impractical.
</para>
<section>
<title>Stop using GdkScreen</title>
<para>
The GdkScreen object has been removed in GTK+ 4. Most of its APIs already
had replacements in GTK+ 3 and were deprecated, a few remaining replacements
have been added to GdkDisplay.
</para>
</section>
<section>
<title>Stop using the root window</title>
<para>
The root window is an X11-centric concept that is no longer exposed in the
backend-neutral GDK API. gdk_window_get_parent() will return %NULL for toplevel
windows. If you need to interact with the X11 root window, you can use
gdk_x11_display_get_xrootwindow() to get its XID.
</para>
</section>
<section>
<title>Stop using GdkDeviceManager</title>
<para>
The GdkDeviceManager object has been removed in GTK+ 4. Most of its APIs already
had replacements in GTK+ 3 and were deprecated in favor of GdkSeat.
</para>
</section>
<section>
<title>Adapt to GdkWindow API changes</title>
<para>
@@ -166,6 +199,23 @@
</para>
</section>
<section>
<title>Stop accessing GdkEvent fields</title>
<para>
Direct access to GdkEvent structs is no longer possible in GTK+ 4. Some
frequently-used fields already had accessors in GTK+ 3, and the remaining
fields have gained accessors in GTK+ 4.
</para>
</section>
<section>
<title>Adapt to GtkHeaderBar API changes</title>
<para>
The gtk_header_bar_set_show_close_button() function has been renamed to
the more accurate name gtk_header_bar_set_show_title_buttons().
</para>
</section>
<section>
<title>Adapt to GtkStyleContext API changes</title>
<para>
@@ -269,7 +319,7 @@
<para>
A number of APIs for querying special-purpose windows have been removed,
since these windows are no longer publically available:
gtk_tree_view_get_pin_window(), gtk_viewport_get_bin_window(),
gtk_tree_view_get_bin_window(), gtk_viewport_get_bin_window(),
gtk_viewport_get_view_window().
</para>
</section>
@@ -299,8 +349,55 @@
<section>
<title>GdkPixbuf is deemphasized</title>
<para>
A number of GdkPixbuf-based APIs have been removed. Use the available
surface-based replacements instead.
A number of GdkPixbuf-based APIs have been removed. The available replacements
are either using cairo_surface_t or the newly introduced GdkTexture class
instead.
</para>
<para>
If you are still dealing with pixbufs, you will likely want to use
gdk_texture_new_for_pixbuf() to convert them to texture objects where needed.
</para>
</section>
<section>
<title>GtkWidget event signals are deemphasized</title>
<para>
GtkGesture classes have already been introduced in GTK+ 3 to handle input for
many cases. In GTK+ 4, even more are available, such as GtkEventControllerScroll.
</para>
</section>
<section>
<title>The gtk_window_fullscreen_on_monitor() API has changed</title>
<para>
Instead of a monitor number, it now takes a GdkMonitor argument.
</para>
</section>
<section>
<title>Adapt to cursor API changes</title>
<para>
Use the new gtk_widget_set_cursor() function to set cursors, instead of
setting the cursor on the underlying window directly. This is necessary
because most widgets don't have their own window anymore, turning any
such calls into global cursor changes.
</para>
<para>
For creating standard cursors, gdk_cursor_new_for_display() has been removed,
you have to use cursor names instead of GdkCursorType. For creating custom cursors,
use gdk_cursor_new_from_texture(). The ability to get cursor images has been removed.
</para>
</section>
<section>
<title>Adapt to icon-size API changes</title>
<para>
Instead of the existing extensible set of symbolic icon sizes, GTK+ now only
supports normal and large icons. The actual sizes can be defined by themes via
the CSS property -gtk-icon-size.
</para>
<para>
The GtkCellRendererPixbuf::stock-size property has been renamed to ::icon-size.
</para>
</section>
</section>

View File

@@ -144,7 +144,7 @@ create_menu_button (void)
widget = gtk_menu_button_new ();
image = gtk_image_new ();
gtk_image_set_from_icon_name (GTK_IMAGE (image), "emblem-system-symbolic", GTK_ICON_SIZE_MENU);
gtk_image_set_from_icon_name (GTK_IMAGE (image), "emblem-system-symbolic");
gtk_container_add (GTK_CONTAINER (widget), image);
menu = gtk_menu_new ();
gtk_menu_button_set_popup (GTK_MENU_BUTTON (widget), menu);
@@ -425,10 +425,10 @@ create_action_bar (void)
widget = gtk_action_bar_new ();
button = gtk_button_new_from_icon_name ("object-select-symbolic", GTK_ICON_SIZE_MENU);
button = gtk_button_new_from_icon_name ("object-select-symbolic");
gtk_widget_show (button);
gtk_container_add (GTK_CONTAINER (widget), button);
button = gtk_button_new_from_icon_name ("call-start-symbolic", GTK_ICON_SIZE_MENU);
button = gtk_button_new_from_icon_name ("call-start-symbolic");
gtk_widget_show (button);
gtk_container_add (GTK_CONTAINER (widget), button);
g_object_set (gtk_widget_get_parent (button), "margin", 6, "spacing", 6, NULL);
@@ -1074,8 +1074,8 @@ create_image (void)
GtkWidget *widget;
GtkWidget *vbox;
widget = gtk_image_new_from_icon_name ("applications-graphics",
GTK_ICON_SIZE_DIALOG);
widget = gtk_image_new_from_icon_name ("applications-graphics");
gtk_image_set_icon_size (GTK_IMAGE (widget), GTK_ICON_SIZE_LARGE);
gtk_widget_set_halign (widget, GTK_ALIGN_CENTER);
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
@@ -1237,7 +1237,7 @@ create_headerbar (void)
gtk_header_bar_set_subtitle (GTK_HEADER_BAR (bar), "(subtitle)");
gtk_window_set_titlebar (GTK_WINDOW (window), bar);
button = gtk_button_new ();
gtk_container_add (GTK_CONTAINER (button), gtk_image_new_from_icon_name ("bookmark-new-symbolic", GTK_ICON_SIZE_BUTTON));
gtk_container_add (GTK_CONTAINER (button), gtk_image_new_from_icon_name ("bookmark-new-symbolic"));
gtk_header_bar_pack_end (GTK_HEADER_BAR (bar), button);
return new_widget_info ("headerbar", window, ASIS);

View File

@@ -8,7 +8,7 @@
<child type="titlebar">
<object class="GtkHeaderBar" id="header">
<property name="visible">True</property>
<property name="show-close-button">True</property>
<property name="show-title-buttons">True</property>
<child>
<object class="GtkLabel" id="lines_label">
<property name="visible">False</property>
@@ -43,7 +43,6 @@
<object class="GtkImage" id="search-icon">
<property name="visible">True</property>
<property name="icon-name">edit-find-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
</object>

View File

@@ -29,7 +29,6 @@
<object class="GtkImage" id="search-icon">
<property name="visible">True</property>
<property name="icon-name">edit-find-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
</object>

View File

@@ -29,7 +29,6 @@
<object class="GtkImage" id="search-icon">
<property name="visible">True</property>
<property name="icon-name">edit-find-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
</object>

View File

@@ -46,7 +46,6 @@
<object class="GtkImage" id="search-icon">
<property name="visible">True</property>
<property name="icon-name">edit-find-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
</object>

View File

@@ -93,12 +93,6 @@ change_justify_state (GSimpleAction *action,
g_simple_action_set_state (action, state);
}
static GtkClipboard *
get_clipboard (GtkWidget *widget)
{
return gtk_widget_get_clipboard (widget, gdk_atom_intern_static_string ("CLIPBOARD"));
}
static void
window_copy (GSimpleAction *action,
GVariant *parameter,
@@ -108,7 +102,7 @@ window_copy (GSimpleAction *action,
GtkTextView *text = g_object_get_data ((GObject*)window, "bloatpad-text");
gtk_text_buffer_copy_clipboard (gtk_text_view_get_buffer (text),
get_clipboard ((GtkWidget*) text));
gtk_widget_get_clipboard (GTK_WIDGET (text)));
}
static void
@@ -120,7 +114,7 @@ window_paste (GSimpleAction *action,
GtkTextView *text = g_object_get_data ((GObject*)window, "bloatpad-text");
gtk_text_buffer_paste_clipboard (gtk_text_view_get_buffer (text),
get_clipboard ((GtkWidget*) text),
gtk_widget_get_clipboard (GTK_WIDGET (text)),
NULL,
TRUE);

View File

@@ -38,12 +38,6 @@ change_fullscreen_state (GSimpleAction *action,
g_simple_action_set_state (action, state);
}
static GtkClipboard *
get_clipboard (GtkWidget *widget)
{
return gtk_widget_get_clipboard (widget, gdk_atom_intern_static_string ("CLIPBOARD"));
}
static void
window_copy (GSimpleAction *action,
GVariant *parameter,
@@ -53,7 +47,7 @@ window_copy (GSimpleAction *action,
GtkTextView *text = g_object_get_data ((GObject*)window, "plugman-text");
gtk_text_buffer_copy_clipboard (gtk_text_view_get_buffer (text),
get_clipboard ((GtkWidget*) text));
gtk_widget_get_clipboard (GTK_WIDGET (text)));
}
static void
@@ -65,7 +59,7 @@ window_paste (GSimpleAction *action,
GtkTextView *text = g_object_get_data ((GObject*)window, "plugman-text");
gtk_text_buffer_paste_clipboard (gtk_text_view_get_buffer (text),
get_clipboard ((GtkWidget*) text),
gtk_widget_get_clipboard (GTK_WIDGET (text)),
NULL,
TRUE);

View File

@@ -17,7 +17,7 @@ new_window (GApplication *app,
header = gtk_header_bar_new ();
gtk_widget_show (header);
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Sunny");
gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (header), TRUE);
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
overlay = gtk_overlay_new ();

View File

@@ -1,528 +0,0 @@
#include "config.h"
#include "broadway-buffer.h"
#include <string.h>
/* This code is based on some code from weston with this license:
*
* Copyright © 2012 Intel Corporation
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of the copyright holders not be used in
* advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. The copyright holders make
* no representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
struct entry {
int count;
int matches;
guint32 hash;
int x, y;
int index;
};
struct _BroadwayBuffer {
guint8 *data;
struct entry *table;
int width, height, stride;
int encoded;
int block_stride, length, block_count, shift;
int stats[5];
int clashes;
};
static const guint32 prime = 0x1f821e2d;
static const guint32 end_prime = 0xf907ec81; /* prime^block_size */
#if 0
static const guint32 vprime = 0x0137b89d;
static const guint32 end_vprime = 0xaea9a281; /* vprime^block_size */
#else
static const guint32 vprime = 0xf907ec81;
static const guint32 end_vprime = 0xcdb99001; /* vprime^block_size */
#endif
static const guint32 step = 0x0ac93019;
static const int block_size = 32, block_mask = 31;
static gboolean
verify_block_match (BroadwayBuffer *buffer, int x, int y,
BroadwayBuffer *prev, struct entry *entry)
{
int i;
void *old, *match;
int w1, w2, h1, h2;
w1 = block_size;
if (x + block_size > buffer->width)
w1 = buffer->width - x;
h1 = block_size;
if (y + block_size > buffer->height)
h1 = buffer->height - y;
w2 = block_size;
if (entry->x + block_size > prev->width)
w2 = prev->width - entry->x;
h2 = block_size;
if (entry->y + block_size > prev->height)
h2 = prev->height - entry->y;
if (w1 != w2 || h1 != h2)
return FALSE;
for (i = 0; i < h1; i++)
{
match = buffer->data + (y + i) * buffer->stride + x * 4;
old = prev->data + (entry->y + i) * prev->stride + entry->x * 4;
if (memcmp (match, old, w1 * 4) != 0)
{
buffer->clashes++;
return FALSE;
}
}
return TRUE;
}
static void
insert_block (BroadwayBuffer *buffer, guint32 h, int x, int y)
{
struct entry *entry;
int i;
guint32 collision = 0;
entry = &buffer->table[h >> buffer->shift];
for (i = step; entry->count > 0 && entry->hash != h; i += step)
{
entry = &buffer->table[(h + i) >> buffer->shift];
collision++;
}
entry->hash = h;
entry->count++;
entry->x = x;
entry->y = y;
entry->index = (buffer->block_stride * y + x) / block_size;
if (collision > G_N_ELEMENTS (buffer->stats) - 1)
collision = G_N_ELEMENTS (buffer->stats) - 1;
buffer->stats[collision]++;
}
static struct entry *
lookup_block (BroadwayBuffer *prev, guint32 h)
{
guint32 i;
struct entry *entry;
int shift = prev->shift;
for (i = h;
entry = &prev->table[i >> shift], entry->count > 0;
i += step)
{
if (entry->hash == h)
return entry;
}
return NULL;
}
struct encoder {
guint32 color;
guint32 color_run;
guint32 delta;
guint32 delta_run;
GString *dest;
int bytes;
};
/* Encoding:
*
* - all 1 pixel colors are encoded literally
*
* - We dont need to support colors with alpha 0 and non-zero
* color components, as they mean the same on the canvas anyway.
* So we use these as special codes:
*
* - 0x00 00 00 00 : one alpha 0 pixel
* - 0xaa rr gg bb : one color pixel, alpha > 0
* - 0x00 1x xx xx : delta 0 run, x is length, (20 bits)
* - 0x00 2x xx xx 0x xxxx yyyy: block ref, block number x (20 bits) at x, y
* - 0x00 3x xx xx 0xaarrggbb : solid color run, length x
* - 0x00 4x xx xx 0xaarrggbb : delta run, length x
*
*/
static void
emit (struct encoder *encoder, guint32 symbol)
{
g_string_append_len (encoder->dest, (char *)&symbol, sizeof (guint32));
encoder->bytes += sizeof (guint32);
}
static void
encode_run (struct encoder *encoder)
{
if (encoder->color_run == 0 && encoder->delta_run == 0)
return;
if (encoder->color_run >= encoder->delta_run)
{
if (encoder->color_run == 1)
emit (encoder, encoder->color);
else
{
emit (encoder, 0x00300000 | encoder->color_run);
emit (encoder, encoder->color);
}
}
else
{
if (encoder->delta == 0)
emit(encoder, 0x00100000 | encoder->delta_run);
else
{
emit(encoder, 0x00400000 | encoder->delta_run);
emit(encoder, encoder->delta);
}
}
}
static void
encode_pixel (struct encoder *encoder, guint32 color, guint32 prev_color)
{
guint32 delta = 0;
guint32 a, r, g, b;
if (color == prev_color)
delta = 0;
else if (prev_color == 0)
delta = color;
else
{
a = ((color & 0xff000000) - (prev_color & 0xff000000)) & 0xff000000;
r = ((color & 0x00ff0000) - (prev_color & 0x00ff0000)) & 0x00ff0000;
g = ((color & 0x0000ff00) - (prev_color & 0x0000ff00)) & 0x0000ff00;
b = ((color & 0x000000ff) - (prev_color & 0x000000ff)) & 0x000000ff;
delta = a | r | g | b;
}
if ((encoder->color != color &&
encoder->color_run > encoder->delta_run) ||
(encoder->delta != delta &&
encoder->delta_run > encoder->color_run) ||
(encoder->delta != delta && encoder->color != color) ||
(encoder->delta_run == 0xFFFFF || encoder->color_run == 0xFFFFF))
{
encode_run (encoder);
encoder->color_run = 1;
encoder->color = color;
encoder->delta_run = 1;
encoder->delta = delta;
return;
}
if (encoder->color == color)
encoder->color_run++;
else
{
encoder->color_run = 1;
encoder->color = color;
}
if (encoder->delta == delta)
encoder->delta_run++;
else
{
encoder->delta_run = 1;
encoder->delta = delta;
}
}
static void
encoder_flush (struct encoder *encoder)
{
encode_run (encoder);
}
static void
encode_block (struct encoder *encoder, struct entry *entry, int x, int y)
{
/* 0x00 2x xx xx 0x xxxx yyyy:
* block ref, block number x (20 bits) at x, y */
/* FIXME: Maybe don't encode pixels under blocks and just emit
* blocks at their position within the stream. */
emit (encoder, 0x00200000 | entry->index);
emit (encoder, (x << 16) | y);
}
void
broadway_buffer_destroy (BroadwayBuffer *buffer)
{
g_free (buffer->data);
g_free (buffer->table);
g_free (buffer);
}
int
broadway_buffer_get_width (BroadwayBuffer *buffer)
{
return buffer->width;
}
int
broadway_buffer_get_height (BroadwayBuffer *buffer)
{
return buffer->height;
}
static void
unpremultiply_line (void *destp, void *srcp, int width)
{
guint32 *src = srcp;
guint32 *dest = destp;
guint32 *end = src + width;
while (src < end)
{
guint32 pixel;
guint8 alpha, r, g, b;
pixel = *src++;
alpha = (pixel & 0xff000000) >> 24;
if (alpha == 0xff)
*dest++ = pixel;
else if (alpha == 0)
*dest++ = 0;
else
{
r = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
g = (((pixel & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha;
b = (((pixel & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha;
*dest++ = (guint32)alpha << 24 | (guint32)r << 16 | (guint32)g << 8 | (guint32)b;
}
}
}
BroadwayBuffer *
broadway_buffer_create (int width, int height, guint8 *data, int stride)
{
BroadwayBuffer *buffer;
int y, bits_required;
buffer = g_new0 (BroadwayBuffer, 1);
buffer->width = width;
buffer->stride = width * 4;
buffer->height = height;
buffer->block_stride = (width + block_size - 1) / block_size;
buffer->block_count =
buffer->block_stride * ((height + block_size - 1) / block_size);
bits_required = g_bit_storage (buffer->block_count * 4);
buffer->shift = 32 - bits_required;
buffer->length = 1 << bits_required;
buffer->table = g_malloc0 (buffer->length * sizeof buffer->table[0]);
memset (buffer->stats, 0, sizeof buffer->stats);
buffer->clashes = 0;
buffer->data = g_malloc (buffer->stride * height);
for (y = 0; y < height; y++)
unpremultiply_line (buffer->data + y * buffer->stride, data + y * stride, width);
return buffer;
}
void
broadway_buffer_encode (BroadwayBuffer *buffer, BroadwayBuffer *prev, GString *dest)
{
struct entry *entry;
int i, j, k;
int x0, x1, y0, y1;
guint32 *block_hashes;
guint32 hash, bottom_hash, h, *line, *bottom, *prev_line;
int width, height;
struct encoder encoder = { 0 };
int *skyline, skyline_pixels;
int matches;
width = buffer->width;
height = buffer->height;
x0 = 0;
x1 = width;
y0 = 0;
y1 = height;
skyline = g_malloc0 ((width + block_size) * sizeof skyline[0]);
block_hashes = g_malloc0 (width * sizeof block_hashes[0]);
matches = 0;
encoder.dest = dest;
// Calculate the block hashes for the first row
for (i = y0; i < MIN(y1, y0 + block_size); i++)
{
line = (guint32 *)(buffer->data + i * buffer->stride);
hash = 0;
for (j = x0; j < MIN(x1, x0 + block_size); j++)
hash = hash * prime + line[j];
for (; j < x0 + block_size; j++)
hash = hash * prime;
for (j = x0; j < x1; j++)
{
block_hashes[j] = block_hashes[j] * vprime + hash;
hash = hash * prime - line[j] * end_prime;
if (j + block_size < width)
hash += line[j + block_size];
}
}
// Do the last rows if height < block_size
for (; i < y0 + block_size; i++)
{
for (j = x0; j < x1; j++)
block_hashes[j] = block_hashes[j] * vprime;
}
for (i = y0; i < y1; i++)
{
line = (guint32 *) (buffer->data + i * buffer->stride);
bottom = (guint32 *) (buffer->data + (i + block_size) * buffer->stride);
bottom_hash = 0;
hash = 0;
skyline_pixels = 0;
if (prev && i < prev->height)
prev_line = (guint32 *) (prev->data + i * prev->stride);
else
prev_line = NULL;
for (j = x0; j < x0 + block_size; j++)
{
hash = hash * prime;
if (j < width)
hash += line[j];
if (i + block_size < height)
{
bottom_hash = bottom_hash * prime;
if (j < width)
bottom_hash += bottom[j];
}
if (i < skyline[j])
skyline_pixels = 0;
else
skyline_pixels++;
}
for (j = x0; j < x1; j++)
{
if (i < skyline[j])
encode_pixel (&encoder, line[j], line[j]);
else if (prev)
{
/* FIXME: Add back overlap exception
* for consecutive blocks */
h = block_hashes[j];
entry = lookup_block (prev, h);
if (entry && entry->count < 2 &&
skyline_pixels >= block_size &&
verify_block_match (buffer, j, i, prev, entry) &&
(entry->x != j || entry->y != i))
{
matches++;
encode_block (&encoder, entry, j, i);
for (k = 0; k < block_size; k++)
skyline[j + k] = i + block_size;
encode_pixel (&encoder, line[j], line[j]);
}
else
{
if (prev_line && j < prev->width)
encode_pixel (&encoder, line[j],
prev_line[j]);
else
encode_pixel (&encoder, line[j], 0);
}
}
else
encode_pixel (&encoder, line[j], 0);
if (i < skyline[j + block_size])
skyline_pixels = 0;
else
skyline_pixels++;
/* Insert block in hash table if we're on a
* grid point. */
if (((i | j) & block_mask) == 0 && !buffer->encoded)
insert_block (buffer, block_hashes[j], j, i);
/* Update sliding block hash */
block_hashes[j] =
block_hashes[j] * vprime + bottom_hash -
hash * end_vprime;
if (i + block_size < height)
{
bottom_hash = bottom_hash * prime - bottom[j] * end_prime;
if (j + block_size < width)
bottom_hash += bottom[j + block_size];
}
hash = hash * prime - line[j] * end_prime;
if (j + block_size < width)
hash += line[j + block_size] ;
}
}
encoder_flush (&encoder);
#if 0
fprintf(stderr, "collision stats:");
for (i = 0; i < (int) G_N_ELEMENTS(buffer->stats); i++)
fprintf(stderr, "%c%d", i == 0 ? ' ' : '/', buffer->stats[i]);
fprintf(stderr, "\n");
fprintf(stderr, "%d / %d blocks (%d%%) matched, %d clashes\n",
matches, buffer->block_count,
100 * matches / buffer->block_count, buffer->clashes);
fprintf(stderr, "output stream %d bytes, raw buffer %d bytes (%d%%)\n",
encoder.bytes, height * buffer->stride,
100 * encoder.bytes / (height * buffer->stride));
#endif
g_free (skyline);
g_free (block_hashes);
buffer->encoded = TRUE;
}

View File

@@ -1,20 +0,0 @@
#ifndef __BROADWAY_BUFFER__
#define __BROADWAY_BUFFER__
#include "broadway-protocol.h"
#include <glib-object.h>
typedef struct _BroadwayBuffer BroadwayBuffer;
BroadwayBuffer *broadway_buffer_create (int width,
int height,
guint8 *data,
int stride);
void broadway_buffer_destroy (BroadwayBuffer *buffer);
void broadway_buffer_encode (BroadwayBuffer *buffer,
BroadwayBuffer *prev,
GString *dest);
int broadway_buffer_get_width (BroadwayBuffer *buffer);
int broadway_buffer_get_height (BroadwayBuffer *buffer);
#endif /* __BROADWAY_BUFFER__ */

View File

@@ -7,6 +7,8 @@
#include "broadway-output.h"
//#define DEBUG_NODE_SENDING
/************************************************************************
* Basic I/O primitives *
************************************************************************/
@@ -20,8 +22,8 @@ struct BroadwayOutput {
static void
broadway_output_send_cmd (BroadwayOutput *output,
gboolean fin, BroadwayWSOpCode code,
const void *buf, gsize count)
gboolean fin, BroadwayWSOpCode code,
const void *buf, gsize count)
{
gboolean mask = FALSE;
guchar header[16];
@@ -100,7 +102,7 @@ broadway_output_get_next_serial (BroadwayOutput *output)
void
broadway_output_set_next_serial (BroadwayOutput *output,
guint32 serial)
guint32 serial)
{
output->serial = serial;
}
@@ -154,6 +156,19 @@ append_uint32 (BroadwayOutput *output, guint32 v)
buf[3] = (v >> 24) & 0xff;
}
static void
patch_uint32 (BroadwayOutput *output, guint32 v, gsize offset)
{
guint8 *buf;
buf = (guint8 *)output->buf->str + offset;
buf[0] = (v >> 0) & 0xff;
buf[1] = (v >> 8) & 0xff;
buf[2] = (v >> 16) & 0xff;
buf[3] = (v >> 24) & 0xff;
}
static void
write_header(BroadwayOutput *output, char op)
{
@@ -163,8 +178,8 @@ write_header(BroadwayOutput *output, char op)
void
broadway_output_grab_pointer (BroadwayOutput *output,
int id,
gboolean owner_event)
int id,
gboolean owner_event)
{
write_header (output, BROADWAY_OP_GRAB_POINTER);
append_uint16 (output, id);
@@ -184,8 +199,8 @@ broadway_output_ungrab_pointer (BroadwayOutput *output)
void
broadway_output_new_surface(BroadwayOutput *output,
int id, int x, int y, int w, int h,
gboolean is_temp)
int id, int x, int y, int w, int h,
gboolean is_temp)
{
write_header (output, BROADWAY_OP_NEW_SURFACE);
append_uint16 (output, id);
@@ -237,6 +252,16 @@ broadway_output_destroy_surface(BroadwayOutput *output, int id)
append_uint16 (output, id);
}
void
broadway_output_roundtrip (BroadwayOutput *output,
int id,
guint32 tag)
{
write_header (output, BROADWAY_OP_ROUNDTRIP);
append_uint16 (output, id);
append_uint32 (output, tag);
}
void
broadway_output_set_show_keyboard (BroadwayOutput *output,
gboolean show)
@@ -247,13 +272,13 @@ broadway_output_set_show_keyboard (BroadwayOutput *output,
void
broadway_output_move_resize_surface (BroadwayOutput *output,
int id,
gboolean has_pos,
int x,
int y,
gboolean has_size,
int w,
int h)
int id,
gboolean has_pos,
int x,
int y,
gboolean has_size,
int w,
int h)
{
int val;
@@ -278,55 +303,136 @@ broadway_output_move_resize_surface (BroadwayOutput *output,
void
broadway_output_set_transient_for (BroadwayOutput *output,
int id,
int parent_id)
int id,
int parent_id)
{
write_header (output, BROADWAY_OP_SET_TRANSIENT_FOR);
append_uint16 (output, id);
append_uint16 (output, parent_id);
}
void
broadway_output_put_buffer (BroadwayOutput *output,
int id,
BroadwayBuffer *prev_buffer,
BroadwayBuffer *buffer)
static gint append_node_depth = -1;
static void
append_type (BroadwayOutput *output, guint32 type, BroadwayNode *node)
{
gsize len;
int w, h;
GZlibCompressor *compressor;
GOutputStream *out, *out_mem;
GString *encoded;
#ifdef DEBUG_NODE_SENDING
g_print ("%*s%s", append_node_depth*2, "", broadway_node_type_names[type]);
if (type == BROADWAY_NODE_TEXTURE)
g_print (" %u", node->data[4]);
g_print ("\n");
#endif
write_header (output, BROADWAY_OP_PUT_BUFFER);
append_uint32 (output, type);
}
w = broadway_buffer_get_width (buffer);
h = broadway_buffer_get_height (buffer);
/***********************************
* This outputs the tree to the client, while at the same time diffing
* against the old tree. This allows us to avoid sending certain
* parts.
*
* Reusing existing dom nodes are problematic because doing so
* automatically inherits all their children. There are two cases
* where we do this:
*
* If the entire sub tree is identical we emit a KEEP_ALL node which
* just reuses the entire old dom subtree.
*
* If a the node is unchanged (but some descendant may have changed),
* and all parents are also unchanged, then we can just avoid
* changing the dom node at all, and we emit a KEEP_THIS node.
*
***********************************/
static void
append_node (BroadwayOutput *output,
BroadwayNode *node,
BroadwayNode *old_node,
gboolean all_parents_are_kept)
{
guint32 i;
append_node_depth++;
if (old_node != NULL && broadway_node_equal (node, old_node))
{
if (broadway_node_deep_equal (node, old_node))
{
append_type (output, BROADWAY_NODE_KEEP_ALL, node);
goto out;
}
if (all_parents_are_kept)
{
append_type (output, BROADWAY_NODE_KEEP_THIS, node);
append_uint32 (output, node->n_children);
for (i = 0; i < node->n_children; i++)
append_node (output, node->children[i],
i < old_node->n_children ? old_node->children[i] : NULL,
TRUE);
goto out;
}
}
append_type (output, node->type, node);
for (i = 0; i < node->n_data; i++)
append_uint32 (output, node->data[i]);
for (i = 0; i < node->n_children; i++)
append_node (output,
node->children[i],
(old_node != NULL && i < old_node->n_children) ? old_node->children[i] : NULL,
FALSE);
out:
append_node_depth--;
}
void
broadway_output_surface_set_nodes (BroadwayOutput *output,
int id,
BroadwayNode *root,
BroadwayNode *old_root)
{
gsize size_pos, start, end;
/* Early return if nothing changed */
if (old_root != NULL &&
broadway_node_deep_equal (root, old_root))
return;
write_header (output, BROADWAY_OP_SET_NODES);
append_uint16 (output, id);
append_uint16 (output, w);
append_uint16 (output, h);
encoded = g_string_new ("");
broadway_buffer_encode (buffer, prev_buffer, encoded);
size_pos = output->buf->len;
append_uint32 (output, 0);
compressor = g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_RAW, -1);
out_mem = g_memory_output_stream_new_resizable ();
out = g_converter_output_stream_new (out_mem, G_CONVERTER (compressor));
g_object_unref (compressor);
if (!g_output_stream_write_all (out, encoded->str, encoded->len,
NULL, NULL, NULL) ||
!g_output_stream_close (out, NULL, NULL))
g_warning ("compression failed");
len = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (out_mem));
append_uint32 (output, len);
g_string_append_len (output->buf, g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (out_mem)), len);
g_string_free (encoded, TRUE);
g_object_unref (out);
g_object_unref (out_mem);
start = output->buf->len;
#ifdef DEBUG_NODE_SENDING
g_print ("====== node tree for %d =======\n", id);
#endif
append_node (output, root, old_root, TRUE);
end = output->buf->len;
patch_uint32 (output, (end - start) / 4, size_pos);
}
void
broadway_output_upload_texture (BroadwayOutput *output,
guint32 id,
GBytes *texture)
{
gsize len = g_bytes_get_size (texture);
write_header (output, BROADWAY_OP_UPLOAD_TEXTURE);
append_uint32 (output, id);
append_uint32 (output, (guint32)len);
g_string_append_len (output->buf, g_bytes_get_data (texture, NULL), len);
}
void
broadway_output_release_texture (BroadwayOutput *output,
guint32 id)
{
write_header (output, BROADWAY_OP_RELEASE_TEXTURE);
append_uint32 (output, id);
}

View File

@@ -4,7 +4,7 @@
#include <glib.h>
#include <gio/gio.h>
#include "broadway-protocol.h"
#include "broadway-buffer.h"
#include "broadway-server.h"
typedef struct BroadwayOutput BroadwayOutput;
@@ -17,53 +17,61 @@ typedef enum {
BROADWAY_WS_CNX_PONG = 0xa
} BroadwayWSOpCode;
BroadwayOutput *broadway_output_new (GOutputStream *out,
guint32 serial);
void broadway_output_free (BroadwayOutput *output);
int broadway_output_flush (BroadwayOutput *output);
int broadway_output_has_error (BroadwayOutput *output);
void broadway_output_set_next_serial (BroadwayOutput *output,
guint32 serial);
guint32 broadway_output_get_next_serial (BroadwayOutput *output);
void broadway_output_new_surface (BroadwayOutput *output,
int id,
int x,
int y,
int w,
int h,
gboolean is_temp);
void broadway_output_disconnected (BroadwayOutput *output);
void broadway_output_show_surface (BroadwayOutput *output,
int id);
void broadway_output_hide_surface (BroadwayOutput *output,
int id);
void broadway_output_raise_surface (BroadwayOutput *output,
int id);
void broadway_output_lower_surface (BroadwayOutput *output,
int id);
void broadway_output_destroy_surface (BroadwayOutput *output,
int id);
BroadwayOutput *broadway_output_new (GOutputStream *out,
guint32 serial);
void broadway_output_free (BroadwayOutput *output);
int broadway_output_flush (BroadwayOutput *output);
int broadway_output_has_error (BroadwayOutput *output);
void broadway_output_set_next_serial (BroadwayOutput *output,
guint32 serial);
guint32 broadway_output_get_next_serial (BroadwayOutput *output);
void broadway_output_new_surface (BroadwayOutput *output,
int id,
int x,
int y,
int w,
int h,
gboolean is_temp);
void broadway_output_disconnected (BroadwayOutput *output);
void broadway_output_show_surface (BroadwayOutput *output,
int id);
void broadway_output_hide_surface (BroadwayOutput *output,
int id);
void broadway_output_raise_surface (BroadwayOutput *output,
int id);
void broadway_output_lower_surface (BroadwayOutput *output,
int id);
void broadway_output_destroy_surface (BroadwayOutput *output,
int id);
void broadway_output_roundtrip (BroadwayOutput *output,
int id,
guint32 tag);
void broadway_output_move_resize_surface (BroadwayOutput *output,
int id,
gboolean has_pos,
int x,
int y,
gboolean has_size,
int w,
int h);
void broadway_output_set_transient_for (BroadwayOutput *output,
int id,
int parent_id);
void broadway_output_put_buffer (BroadwayOutput *output,
int id,
BroadwayBuffer *prev_buffer,
BroadwayBuffer *buffer);
void broadway_output_grab_pointer (BroadwayOutput *output,
int id,
gboolean owner_event);
guint32 broadway_output_ungrab_pointer (BroadwayOutput *output);
void broadway_output_pong (BroadwayOutput *output);
void broadway_output_set_show_keyboard (BroadwayOutput *output,
gboolean show);
int id,
gboolean has_pos,
int x,
int y,
gboolean has_size,
int w,
int h);
void broadway_output_set_transient_for (BroadwayOutput *output,
int id,
int parent_id);
void broadway_output_surface_set_nodes (BroadwayOutput *output,
int id,
BroadwayNode *root,
BroadwayNode *old_root);
void broadway_output_upload_texture (BroadwayOutput *output,
guint32 id,
GBytes *texture);
void broadway_output_release_texture (BroadwayOutput *output,
guint32 id);
void broadway_output_grab_pointer (BroadwayOutput *output,
int id,
gboolean owner_event);
guint32 broadway_output_ungrab_pointer (BroadwayOutput *output);
void broadway_output_pong (BroadwayOutput *output);
void broadway_output_set_show_keyboard (BroadwayOutput *output,
gboolean show);
#endif /* __BROADWAY_H__ */

View File

@@ -8,6 +8,38 @@ typedef struct {
gint32 width, height;
} BroadwayRect;
typedef enum { /* Sync changes with broadway.js */
BROADWAY_NODE_TEXTURE = 0,
BROADWAY_NODE_CONTAINER = 1,
BROADWAY_NODE_COLOR = 2,
BROADWAY_NODE_BORDER = 3,
BROADWAY_NODE_OUTSET_SHADOW = 4,
BROADWAY_NODE_INSET_SHADOW = 5,
BROADWAY_NODE_ROUNDED_CLIP = 6,
BROADWAY_NODE_LINEAR_GRADIENT = 7,
BROADWAY_NODE_SHADOW = 8,
BROADWAY_NODE_OPACITY = 9,
BROADWAY_NODE_CLIP = 10,
BROADWAY_NODE_KEEP_ALL = 11,
BROADWAY_NODE_KEEP_THIS = 12,
} BroadwayNodeType;
static const char *broadway_node_type_names[] G_GNUC_UNUSED = {
"TEXTURE",
"CONTAINER",
"COLOR",
"BORDER",
"OUTSET_SHADOW",
"INSET_SHADOW",
"ROUNDED_CLIP",
"LINEAR_GRADIENT",
"SHADOW",
"OPACITY",
"CLIP",
"KEEP_ALL",
"KEEP_THIS",
};
typedef enum {
BROADWAY_EVENT_ENTER = 'e',
BROADWAY_EVENT_LEAVE = 'l',
@@ -21,9 +53,9 @@ typedef enum {
BROADWAY_EVENT_GRAB_NOTIFY = 'g',
BROADWAY_EVENT_UNGRAB_NOTIFY = 'u',
BROADWAY_EVENT_CONFIGURE_NOTIFY = 'w',
BROADWAY_EVENT_DELETE_NOTIFY = 'W',
BROADWAY_EVENT_SCREEN_SIZE_CHANGED = 'd',
BROADWAY_EVENT_FOCUS = 'f'
BROADWAY_EVENT_FOCUS = 'f',
BROADWAY_EVENT_ROUNDTRIP_NOTIFY = 'F',
} BroadwayEventType;
typedef enum {
@@ -41,8 +73,12 @@ typedef enum {
BROADWAY_OP_REQUEST_AUTH = 'l',
BROADWAY_OP_AUTH_OK = 'L',
BROADWAY_OP_DISCONNECTED = 'D',
BROADWAY_OP_PUT_BUFFER = 'b',
BROADWAY_OP_SURFACE_UPDATE = 'b',
BROADWAY_OP_SET_SHOW_KEYBOARD = 'k',
BROADWAY_OP_UPLOAD_TEXTURE = 't',
BROADWAY_OP_RELEASE_TEXTURE = 'T',
BROADWAY_OP_SET_NODES = 'n',
BROADWAY_OP_ROUNDTRIP = 'F',
} BroadwayOpType;
typedef struct {
@@ -53,8 +89,8 @@ typedef struct {
typedef struct {
BroadwayInputBaseMsg base;
guint32 mouse_window_id; /* The real window, not taking grabs into account */
guint32 event_window_id;
guint32 mouse_surface_id; /* The real surface, not taking grabs into account */
guint32 event_surface_id;
gint32 root_x;
gint32 root_y;
gint32 win_x;
@@ -80,7 +116,7 @@ typedef struct {
typedef struct {
BroadwayInputBaseMsg base;
guint32 touch_type;
guint32 event_window_id;
guint32 event_surface_id;
guint32 sequence_id;
guint32 is_emulated;
gint32 root_x;
@@ -92,7 +128,7 @@ typedef struct {
typedef struct {
BroadwayInputBaseMsg base;
guint32 window_id;
guint32 surface_id;
guint32 state;
gint32 key;
} BroadwayInputKeyMsg;
@@ -111,6 +147,13 @@ typedef struct {
gint32 height;
} BroadwayInputConfigureNotify;
typedef struct {
BroadwayInputBaseMsg base;
gint32 id;
guint32 tag;
guint32 local;
} BroadwayInputRoundtripNotify;
typedef struct {
BroadwayInputBaseMsg base;
guint32 width;
@@ -138,26 +181,30 @@ typedef union {
BroadwayInputKeyMsg key;
BroadwayInputGrabReply grab_reply;
BroadwayInputConfigureNotify configure_notify;
BroadwayInputRoundtripNotify roundtrip_notify;
BroadwayInputDeleteNotify delete_notify;
BroadwayInputScreenResizeNotify screen_resize_notify;
BroadwayInputFocusMsg focus;
} BroadwayInputMsg;
typedef enum {
BROADWAY_REQUEST_NEW_WINDOW,
BROADWAY_REQUEST_NEW_SURFACE,
BROADWAY_REQUEST_FLUSH,
BROADWAY_REQUEST_SYNC,
BROADWAY_REQUEST_QUERY_MOUSE,
BROADWAY_REQUEST_DESTROY_WINDOW,
BROADWAY_REQUEST_SHOW_WINDOW,
BROADWAY_REQUEST_HIDE_WINDOW,
BROADWAY_REQUEST_DESTROY_SURFACE,
BROADWAY_REQUEST_SHOW_SURFACE,
BROADWAY_REQUEST_HIDE_SURFACE,
BROADWAY_REQUEST_SET_TRANSIENT_FOR,
BROADWAY_REQUEST_UPDATE,
BROADWAY_REQUEST_MOVE_RESIZE,
BROADWAY_REQUEST_GRAB_POINTER,
BROADWAY_REQUEST_UNGRAB_POINTER,
BROADWAY_REQUEST_FOCUS_WINDOW,
BROADWAY_REQUEST_SET_SHOW_KEYBOARD
BROADWAY_REQUEST_FOCUS_SURFACE,
BROADWAY_REQUEST_SET_SHOW_KEYBOARD,
BROADWAY_REQUEST_UPLOAD_TEXTURE,
BROADWAY_REQUEST_RELEASE_TEXTURE,
BROADWAY_REQUEST_SET_NODES,
BROADWAY_REQUEST_ROUNDTRIP,
} BroadwayRequestType;
typedef struct {
@@ -169,7 +216,13 @@ typedef struct {
typedef struct {
BroadwayRequestBase base;
guint32 id;
} BroadwayRequestDestroyWindow, BroadwayRequestShowWindow, BroadwayRequestHideWindow, BroadwayRequestFocusWindow;
} BroadwayRequestDestroySurface, BroadwayRequestShowSurface, BroadwayRequestHideSurface, BroadwayRequestFocusSurface;
typedef struct {
BroadwayRequestBase base;
guint32 id;
guint32 tag;
} BroadwayRequestRoundtrip;
typedef struct {
BroadwayRequestBase base;
@@ -180,19 +233,21 @@ typedef struct {
typedef struct {
BroadwayRequestBase base;
guint32 id;
gint32 dx;
gint32 dy;
guint32 n_rects;
BroadwayRect rects[1];
} BroadwayRequestTranslate;
guint32 offset;
guint32 size;
} BroadwayRequestUploadTexture;
typedef struct {
BroadwayRequestBase base;
guint32 id;
char name[36];
guint32 width;
guint32 height;
} BroadwayRequestUpdate;
} BroadwayRequestReleaseTexture;
typedef struct {
BroadwayRequestBase base;
guint32 id;
guint32 data[1];
} BroadwayRequestSetNodes;
typedef struct {
BroadwayRequestBase base;
@@ -214,7 +269,7 @@ typedef struct {
guint32 width;
guint32 height;
guint32 is_temp;
} BroadwayRequestNewWindow;
} BroadwayRequestNewSurface;
typedef struct {
BroadwayRequestBase base;
@@ -233,28 +288,30 @@ typedef struct {
typedef union {
BroadwayRequestBase base;
BroadwayRequestNewWindow new_window;
BroadwayRequestNewSurface new_surface;
BroadwayRequestFlush flush;
BroadwayRequestSync sync;
BroadwayRequestRoundtrip roundtrip;
BroadwayRequestQueryMouse query_mouse;
BroadwayRequestDestroyWindow destroy_window;
BroadwayRequestShowWindow show_window;
BroadwayRequestHideWindow hide_window;
BroadwayRequestDestroySurface destroy_surface;
BroadwayRequestShowSurface show_surface;
BroadwayRequestHideSurface hide_surface;
BroadwayRequestSetTransientFor set_transient_for;
BroadwayRequestUpdate update;
BroadwayRequestMoveResize move_resize;
BroadwayRequestGrabPointer grab_pointer;
BroadwayRequestUngrabPointer ungrab_pointer;
BroadwayRequestTranslate translate;
BroadwayRequestFocusWindow focus_window;
BroadwayRequestFocusSurface focus_surface;
BroadwayRequestSetShowKeyboard set_show_keyboard;
BroadwayRequestUploadTexture upload_texture;
BroadwayRequestReleaseTexture release_texture;
BroadwayRequestSetNodes set_nodes;
} BroadwayRequest;
typedef enum {
BROADWAY_REPLY_EVENT,
BROADWAY_REPLY_SYNC,
BROADWAY_REPLY_QUERY_MOUSE,
BROADWAY_REPLY_NEW_WINDOW,
BROADWAY_REPLY_NEW_SURFACE,
BROADWAY_REPLY_GRAB_POINTER,
BROADWAY_REPLY_UNGRAB_POINTER
} BroadwayReplyType;
@@ -268,7 +325,7 @@ typedef struct {
typedef struct {
BroadwayReplyBase base;
guint32 id;
} BroadwayReplyNewWindow;
} BroadwayReplyNewSurface;
typedef struct {
BroadwayReplyBase base;
@@ -277,7 +334,7 @@ typedef struct {
typedef struct {
BroadwayReplyBase base;
guint32 toplevel;
guint32 surface;
gint32 root_x;
gint32 root_y;
guint32 mask;
@@ -292,7 +349,7 @@ typedef union {
BroadwayReplyBase base;
BroadwayReplyEvent event;
BroadwayReplyQueryMouse query_mouse;
BroadwayReplyNewWindow new_window;
BroadwayReplyNewSurface new_surface;
BroadwayReplyGrabPointer grab_pointer;
BroadwayReplyUngrabPointer ungrab_pointer;
} BroadwayReply;

File diff suppressed because it is too large Load Diff

View File

@@ -18,82 +18,99 @@ typedef struct _BroadwayServerClass BroadwayServerClass;
#define BROADWAY_IS_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), BROADWAY_TYPE_SERVER))
#define BROADWAY_SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), BROADWAY_TYPE_SERVER, BroadwayServerClass))
typedef struct _BroadwayNode BroadwayNode;
struct _BroadwayNode {
guint32 type;
guint32 hash; /* deep hash */
guint32 n_children;
BroadwayNode **children;
guint32 n_data;
guint32 data[1];
};
gboolean broadway_node_equal (BroadwayNode *a,
BroadwayNode *b);
gboolean broadway_node_deep_equal (BroadwayNode *a,
BroadwayNode *b);
BroadwayServer *broadway_server_new (char *address,
int port,
const char *ssl_cert,
const char *ssl_key,
GError **error);
BroadwayServer *broadway_server_on_unix_socket_new (char *address,
GError **error);
gboolean broadway_server_has_client (BroadwayServer *server);
void broadway_server_flush (BroadwayServer *server);
void broadway_server_sync (BroadwayServer *server);
void broadway_server_roundtrip (BroadwayServer *server,
gint id,
guint32 tag);
void broadway_server_get_screen_size (BroadwayServer *server,
guint32 *width,
guint32 *height);
guint32 broadway_server_get_next_serial (BroadwayServer *server);
guint32 broadway_server_get_last_seen_time (BroadwayServer *server);
gboolean broadway_server_lookahead_event (BroadwayServer *server,
const char *types);
void broadway_server_query_mouse (BroadwayServer *server,
guint32 *surface,
gint32 *root_x,
gint32 *root_y,
guint32 *mask);
guint32 broadway_server_grab_pointer (BroadwayServer *server,
gint client_id,
gint id,
gboolean owner_events,
guint32 event_mask,
guint32 time_);
guint32 broadway_server_ungrab_pointer (BroadwayServer *server,
guint32 time_);
gint32 broadway_server_get_mouse_surface (BroadwayServer *server);
void broadway_server_set_show_keyboard (BroadwayServer *server,
gboolean show);
guint32 broadway_server_new_surface (BroadwayServer *server,
int x,
int y,
int width,
int height,
gboolean is_temp);
void broadway_server_destroy_surface (BroadwayServer *server,
gint id);
gboolean broadway_server_surface_show (BroadwayServer *server,
gint id);
gboolean broadway_server_surface_hide (BroadwayServer *server,
gint id);
void broadway_server_surface_raise (BroadwayServer *server,
gint id);
void broadway_server_surface_lower (BroadwayServer *server,
gint id);
void broadway_server_surface_set_transient_for (BroadwayServer *server,
gint id,
gint parent);
gboolean broadway_server_surface_translate (BroadwayServer *server,
gint id,
cairo_region_t *area,
gint dx,
gint dy);
guint32 broadway_server_upload_texture (BroadwayServer *server,
GBytes *texture);
void broadway_server_release_texture (BroadwayServer *server,
guint32 id);
cairo_surface_t * broadway_server_create_surface (int width,
int height);
void broadway_server_surface_set_nodes (BroadwayServer *server,
gint id,
BroadwayNode *root);
gboolean broadway_server_surface_move_resize (BroadwayServer *server,
gint id,
gboolean with_move,
int x,
int y,
int width,
int height);
void broadway_server_focus_surface (BroadwayServer *server,
gint new_focused_surface);
BroadwayServer *broadway_server_new (char *address,
int port,
const char *ssl_cert,
const char *ssl_key,
GError **error);
BroadwayServer *broadway_server_on_unix_socket_new (char *address,
GError **error);
gboolean broadway_server_has_client (BroadwayServer *server);
void broadway_server_flush (BroadwayServer *server);
void broadway_server_sync (BroadwayServer *server);
void broadway_server_get_screen_size (BroadwayServer *server,
guint32 *width,
guint32 *height);
guint32 broadway_server_get_next_serial (BroadwayServer *server);
guint32 broadway_server_get_last_seen_time (BroadwayServer *server);
gboolean broadway_server_lookahead_event (BroadwayServer *server,
const char *types);
void broadway_server_query_mouse (BroadwayServer *server,
guint32 *toplevel,
gint32 *root_x,
gint32 *root_y,
guint32 *mask);
guint32 broadway_server_grab_pointer (BroadwayServer *server,
gint client_id,
gint id,
gboolean owner_events,
guint32 event_mask,
guint32 time_);
guint32 broadway_server_ungrab_pointer (BroadwayServer *server,
guint32 time_);
gint32 broadway_server_get_mouse_toplevel (BroadwayServer *server);
void broadway_server_set_show_keyboard (BroadwayServer *server,
gboolean show);
guint32 broadway_server_new_window (BroadwayServer *server,
int x,
int y,
int width,
int height,
gboolean is_temp);
void broadway_server_destroy_window (BroadwayServer *server,
gint id);
gboolean broadway_server_window_show (BroadwayServer *server,
gint id);
gboolean broadway_server_window_hide (BroadwayServer *server,
gint id);
void broadway_server_window_raise (BroadwayServer *server,
gint id);
void broadway_server_window_lower (BroadwayServer *server,
gint id);
void broadway_server_window_set_transient_for (BroadwayServer *server,
gint id,
gint parent);
gboolean broadway_server_window_translate (BroadwayServer *server,
gint id,
cairo_region_t *area,
gint dx,
gint dy);
cairo_surface_t * broadway_server_create_surface (int width,
int height);
void broadway_server_window_update (BroadwayServer *server,
gint id,
cairo_surface_t *surface);
gboolean broadway_server_window_move_resize (BroadwayServer *server,
gint id,
gboolean with_move,
int x,
int y,
int width,
int height);
void broadway_server_focus_window (BroadwayServer *server,
gint new_focused_window);
cairo_surface_t * broadway_server_open_surface (BroadwayServer *server,
guint32 id,
char *name,
int width,
int height);
#endif /* __BROADWAY_SERVER__ */

File diff suppressed because it is too large Load Diff

View File

@@ -8,11 +8,13 @@
#include <stdlib.h>
#include <stdio.h>
#include <locale.h>
#include <errno.h>
#include <glib.h>
#include <gio/gio.h>
#ifdef G_OS_UNIX
#include <gio/gunixsocketaddress.h>
#include <gio/gunixfdmessage.h>
#endif
#include "broadway-server.h"
@@ -48,27 +50,42 @@ typedef struct {
typedef struct {
guint32 id;
GSocketConnection *connection;
GBufferedInputStream *in;
GInputStream *in;
GString *buffer;
GSource *source;
GSList *serial_mappings;
GList *windows;
GList *surfaces;
guint disconnect_idle;
GList *fds;
GHashTable *textures;
} BroadwayClient;
static void
close_fd (void *data)
{
close (GPOINTER_TO_INT (data));
}
static void
client_free (BroadwayClient *client)
{
g_assert (client->windows == NULL);
g_assert (client->surfaces == NULL);
g_assert (client->disconnect_idle == 0);
clients = g_list_remove (clients, client);
g_object_unref (client->connection);
g_object_unref (client->in);
g_string_free (client->buffer, TRUE);
g_slist_free_full (client->serial_mappings, g_free);
g_list_free_full (client->fds, close_fd);
g_hash_table_destroy (client->textures);
g_free (client);
}
static void
client_disconnected (BroadwayClient *client)
{
GHashTableIter iter;
gpointer key, value;
GList *l;
if (client->disconnect_idle != 0)
@@ -77,11 +94,21 @@ client_disconnected (BroadwayClient *client)
client->disconnect_idle = 0;
}
for (l = client->windows; l != NULL; l = l->next)
broadway_server_destroy_window (server,
GPOINTER_TO_UINT (l->data));
g_list_free (client->windows);
client->windows = NULL;
if (client->source != 0)
{
g_source_destroy (client->source);
client->source = 0;
}
for (l = client->surfaces; l != NULL; l = l->next)
broadway_server_destroy_surface (server,
GPOINTER_TO_UINT (l->data));
g_list_free (client->surfaces);
client->surfaces = NULL;
g_hash_table_iter_init (&iter, client->textures);
while (g_hash_table_iter_next (&iter, &key, &value))
broadway_server_release_texture (server, GPOINTER_TO_INT (value));
broadway_server_flush (server);
@@ -106,10 +133,10 @@ client_disconnect_in_idle (BroadwayClient *client)
static void
send_reply (BroadwayClient *client,
BroadwayRequest *request,
BroadwayReply *reply,
gsize size,
guint32 type)
BroadwayRequest *request,
BroadwayReply *reply,
gsize size,
guint32 type)
{
GOutputStream *output;
@@ -127,8 +154,8 @@ send_reply (BroadwayClient *client,
static void
add_client_serial_mapping (BroadwayClient *client,
guint32 client_serial,
guint32 daemon_serial)
guint32 client_serial,
guint32 daemon_serial)
{
BroadwaySerialMapping *map;
GSList *last;
@@ -141,10 +168,10 @@ add_client_serial_mapping (BroadwayClient *client,
/* If we have no web client, don't grow forever */
if (map->daemon_serial == daemon_serial)
{
map->client_serial = client_serial;
return;
}
{
map->client_serial = client_serial;
return;
}
}
map = g_new0 (BroadwaySerialMapping, 1);
@@ -168,57 +195,167 @@ get_client_serial (BroadwayClient *client, guint32 daemon_serial)
map = l->data;
if (map->daemon_serial <= daemon_serial)
{
found = l;
client_serial = map->client_serial;
}
{
found = l;
client_serial = map->client_serial;
}
else
break;
break;
}
/* Remove mappings before the found one, they will never more be used */
while (found != NULL &&
client->serial_mappings != found)
client->serial_mappings != found)
{
g_free (client->serial_mappings->data);
client->serial_mappings =
g_slist_delete_link (client->serial_mappings, client->serial_mappings);
g_slist_delete_link (client->serial_mappings, client->serial_mappings);
}
return client_serial;
}
#define NODE_SIZE_COLOR 1
#define NODE_SIZE_FLOAT 1
#define NODE_SIZE_POINT 2
#define NODE_SIZE_SIZE 2
#define NODE_SIZE_RECT (NODE_SIZE_POINT + NODE_SIZE_SIZE)
#define NODE_SIZE_RRECT (NODE_SIZE_RECT + 4 * NODE_SIZE_SIZE)
#define NODE_SIZE_COLOR_STOP (NODE_SIZE_FLOAT + NODE_SIZE_COLOR)
#define NODE_SIZE_SHADOW (NODE_SIZE_COLOR + 3 * NODE_SIZE_FLOAT)
static guint32
rotl (guint32 value, int shift)
{
if ((shift &= 32 - 1) == 0)
return value;
return (value << shift) | (value >> (32 - shift));
}
static BroadwayNode *
decode_nodes (BroadwayClient *client,
int len, guint32 data[], int *pos)
{
BroadwayNode *node;
guint32 type;
guint32 i, n_stops, n_shadows;
guint32 size, n_children;
gint32 texture_offset;
guint32 hash;
g_assert (*pos < len);
size = 0;
n_children = 0;
texture_offset = -1;
type = data[(*pos)++];
switch (type) {
case BROADWAY_NODE_COLOR:
size = NODE_SIZE_RECT + NODE_SIZE_COLOR;
break;
case BROADWAY_NODE_BORDER:
size = NODE_SIZE_RRECT + 4 * NODE_SIZE_FLOAT + 4 * NODE_SIZE_COLOR;
break;
case BROADWAY_NODE_INSET_SHADOW:
case BROADWAY_NODE_OUTSET_SHADOW:
size = NODE_SIZE_RRECT + NODE_SIZE_COLOR + 4 * NODE_SIZE_FLOAT;
break;
case BROADWAY_NODE_TEXTURE:
texture_offset = 4;
size = 5;
break;
case BROADWAY_NODE_CONTAINER:
size = 1;
n_children = data[*pos];
break;
case BROADWAY_NODE_ROUNDED_CLIP:
size = NODE_SIZE_RRECT;
n_children = 1;
break;
case BROADWAY_NODE_CLIP:
size = NODE_SIZE_RECT;
n_children = 1;
break;
case BROADWAY_NODE_LINEAR_GRADIENT:
size = NODE_SIZE_RECT + 2 * NODE_SIZE_POINT;
n_stops = data[*pos + size++];
size += n_stops * NODE_SIZE_COLOR_STOP;
break;
case BROADWAY_NODE_SHADOW:
size = 1;
n_shadows = data[*pos];
size += n_shadows * NODE_SIZE_SHADOW;
n_children = 1;
break;
case BROADWAY_NODE_OPACITY:
size = NODE_SIZE_FLOAT;
n_children = 1;
break;
default:
g_assert_not_reached ();
}
node = g_malloc (sizeof(BroadwayNode) + (size - 1) * sizeof(guint32) + n_children * sizeof (BroadwayNode *));
node->type = type;
node->n_children = n_children;
node->children = (BroadwayNode **)((char *)node + sizeof(BroadwayNode) + (size - 1) * sizeof(guint32));
node->n_data = size;
for (i = 0; i < size; i++)
{
node->data[i] = data[(*pos)++];
if (i == texture_offset)
node->data[i] = GPOINTER_TO_INT (g_hash_table_lookup (client->textures,
GINT_TO_POINTER (node->data[i])));
}
for (i = 0; i < n_children; i++)
node->children[i] = decode_nodes (client, len, data, pos);
hash = node->type << 16;
for (i = 0; i < size; i++)
hash ^= rotl (node->data[i], i);
for (i = 0; i < n_children; i++)
hash ^= rotl (node->children[i]->hash, i);
node->hash = hash;
return node;
}
static void
client_handle_request (BroadwayClient *client,
BroadwayRequest *request)
BroadwayRequest *request)
{
BroadwayReplyNewWindow reply_new_window;
BroadwayReplyNewSurface reply_new_surface;
BroadwayReplySync reply_sync;
BroadwayReplyQueryMouse reply_query_mouse;
BroadwayReplyGrabPointer reply_grab_pointer;
BroadwayReplyUngrabPointer reply_ungrab_pointer;
cairo_surface_t *surface;
guint32 before_serial, now_serial;
guint32 global_id;
int fd;
before_serial = broadway_server_get_next_serial (server);
switch (request->base.type)
{
case BROADWAY_REQUEST_NEW_WINDOW:
reply_new_window.id =
broadway_server_new_window (server,
request->new_window.x,
request->new_window.y,
request->new_window.width,
request->new_window.height,
request->new_window.is_temp);
client->windows =
g_list_prepend (client->windows,
GUINT_TO_POINTER (reply_new_window.id));
case BROADWAY_REQUEST_NEW_SURFACE:
reply_new_surface.id =
broadway_server_new_surface (server,
request->new_surface.x,
request->new_surface.y,
request->new_surface.width,
request->new_surface.height,
request->new_surface.is_temp);
client->surfaces =
g_list_prepend (client->surfaces,
GUINT_TO_POINTER (reply_new_surface.id));
send_reply (client, request, (BroadwayReply *)&reply_new_window, sizeof (reply_new_window),
BROADWAY_REPLY_NEW_WINDOW);
send_reply (client, request, (BroadwayReply *)&reply_new_surface, sizeof (reply_new_surface),
BROADWAY_REPLY_NEW_SURFACE);
break;
case BROADWAY_REQUEST_FLUSH:
broadway_server_flush (server);
@@ -226,77 +363,137 @@ client_handle_request (BroadwayClient *client,
case BROADWAY_REQUEST_SYNC:
broadway_server_flush (server);
send_reply (client, request, (BroadwayReply *)&reply_sync, sizeof (reply_sync),
BROADWAY_REPLY_SYNC);
BROADWAY_REPLY_SYNC);
break;
case BROADWAY_REQUEST_ROUNDTRIP:
broadway_server_roundtrip (server,
request->roundtrip.id,
request->roundtrip.tag);
break;
case BROADWAY_REQUEST_QUERY_MOUSE:
broadway_server_query_mouse (server,
&reply_query_mouse.toplevel,
&reply_query_mouse.root_x,
&reply_query_mouse.root_y,
&reply_query_mouse.mask);
&reply_query_mouse.surface,
&reply_query_mouse.root_x,
&reply_query_mouse.root_y,
&reply_query_mouse.mask);
send_reply (client, request, (BroadwayReply *)&reply_query_mouse, sizeof (reply_query_mouse),
BROADWAY_REPLY_QUERY_MOUSE);
BROADWAY_REPLY_QUERY_MOUSE);
break;
case BROADWAY_REQUEST_DESTROY_WINDOW:
client->windows =
g_list_remove (client->windows,
GUINT_TO_POINTER (request->destroy_window.id));
broadway_server_destroy_window (server, request->destroy_window.id);
case BROADWAY_REQUEST_DESTROY_SURFACE:
client->surfaces =
g_list_remove (client->surfaces,
GUINT_TO_POINTER (request->destroy_surface.id));
broadway_server_destroy_surface (server, request->destroy_surface.id);
break;
case BROADWAY_REQUEST_SHOW_WINDOW:
broadway_server_window_show (server, request->show_window.id);
case BROADWAY_REQUEST_SHOW_SURFACE:
broadway_server_surface_show (server, request->show_surface.id);
break;
case BROADWAY_REQUEST_HIDE_WINDOW:
broadway_server_window_hide (server, request->hide_window.id);
case BROADWAY_REQUEST_HIDE_SURFACE:
broadway_server_surface_hide (server, request->hide_surface.id);
break;
case BROADWAY_REQUEST_SET_TRANSIENT_FOR:
broadway_server_window_set_transient_for (server,
request->set_transient_for.id,
request->set_transient_for.parent);
broadway_server_surface_set_transient_for (server,
request->set_transient_for.id,
request->set_transient_for.parent);
break;
case BROADWAY_REQUEST_UPDATE:
surface = broadway_server_open_surface (server,
request->update.id,
request->update.name,
request->update.width,
request->update.height);
if (surface != NULL)
{
broadway_server_window_update (server,
request->update.id,
surface);
cairo_surface_destroy (surface);
}
case BROADWAY_REQUEST_SET_NODES:
{
gsize array_size = request->base.size - sizeof (BroadwayRequestSetNodes) + sizeof(guint32);
int n_data = array_size / sizeof(guint32);
int pos = 0;
BroadwayNode *node;
node = decode_nodes (client, n_data, request->set_nodes.data, &pos);
broadway_server_surface_set_nodes (server, request->set_nodes.id,
node);
}
break;
case BROADWAY_REQUEST_UPLOAD_TEXTURE:
if (client->fds == NULL)
g_warning ("FD passing mismatch for texture upload %d", request->release_texture.id);
else
{
char *data, *p;
gsize to_read;
gssize num_read;
GBytes *texture;
fd = GPOINTER_TO_INT (client->fds->data);
client->fds = g_list_delete_link (client->fds, client->fds);
data = g_malloc (request->upload_texture.size);
to_read = request->upload_texture.size;
lseek (fd, request->upload_texture.offset, SEEK_SET);
p = data;
do
{
num_read = read (fd, p, to_read);
if (num_read == -1 && errno == EAGAIN)
continue;
if (num_read > 0)
{
p += num_read;
to_read -= num_read;
}
else
{
g_warning ("Unexpected short read of texture");
break;
}
}
while (to_read > 0);
close (fd);
texture = g_bytes_new_take (data, request->upload_texture.size);
global_id = broadway_server_upload_texture (server, texture);
g_bytes_unref (texture);
g_hash_table_replace (client->textures,
GINT_TO_POINTER (request->release_texture.id),
GINT_TO_POINTER (global_id));
}
break;
case BROADWAY_REQUEST_RELEASE_TEXTURE:
global_id = GPOINTER_TO_INT (g_hash_table_lookup (client->textures,
GINT_TO_POINTER (request->release_texture.id)));
if (global_id != 0)
broadway_server_release_texture (server, global_id);
g_hash_table_remove (client->textures,
GINT_TO_POINTER (request->release_texture.id));
break;
case BROADWAY_REQUEST_MOVE_RESIZE:
broadway_server_window_move_resize (server,
request->move_resize.id,
request->move_resize.with_move,
request->move_resize.x,
request->move_resize.y,
request->move_resize.width,
request->move_resize.height);
broadway_server_surface_move_resize (server,
request->move_resize.id,
request->move_resize.with_move,
request->move_resize.x,
request->move_resize.y,
request->move_resize.width,
request->move_resize.height);
break;
case BROADWAY_REQUEST_GRAB_POINTER:
reply_grab_pointer.status =
broadway_server_grab_pointer (server,
client->id,
request->grab_pointer.id,
request->grab_pointer.owner_events,
request->grab_pointer.event_mask,
request->grab_pointer.time_);
broadway_server_grab_pointer (server,
client->id,
request->grab_pointer.id,
request->grab_pointer.owner_events,
request->grab_pointer.event_mask,
request->grab_pointer.time_);
send_reply (client, request, (BroadwayReply *)&reply_grab_pointer, sizeof (reply_grab_pointer),
BROADWAY_REPLY_GRAB_POINTER);
BROADWAY_REPLY_GRAB_POINTER);
break;
case BROADWAY_REQUEST_UNGRAB_POINTER:
reply_ungrab_pointer.status =
broadway_server_ungrab_pointer (server,
request->ungrab_pointer.time_);
broadway_server_ungrab_pointer (server,
request->ungrab_pointer.time_);
send_reply (client, request, (BroadwayReply *)&reply_ungrab_pointer, sizeof (reply_ungrab_pointer),
BROADWAY_REPLY_UNGRAB_POINTER);
BROADWAY_REPLY_UNGRAB_POINTER);
break;
case BROADWAY_REQUEST_FOCUS_WINDOW:
broadway_server_focus_window (server, request->focus_window.id);
case BROADWAY_REQUEST_FOCUS_SURFACE:
broadway_server_focus_surface (server, request->focus_surface.id);
break;
case BROADWAY_REQUEST_SET_SHOW_KEYBOARD:
broadway_server_set_show_keyboard (server, request->set_show_keyboard.show_keyboard);
@@ -312,66 +509,97 @@ client_handle_request (BroadwayClient *client,
update old mapping for previously sent daemon serial */
if (now_serial != before_serial)
add_client_serial_mapping (client,
request->base.serial,
before_serial);
request->base.serial,
before_serial);
else
add_client_serial_mapping (client,
request->base.serial,
before_serial - 1);
request->base.serial,
before_serial - 1);
}
static void
client_fill_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
#define INPUT_BUFFER_SIZE 8192
static gboolean
client_input_cb (GPollableInputStream *stream,
gpointer user_data)
{
BroadwayClient *client = user_data;
GSocket *socket = g_socket_connection_get_socket (client->connection);
gssize res;
gsize old_len;
guchar *buffer;
gsize buffer_len;
GInputVector input_vector;
GSocketControlMessage **messages = NULL;
int i, num_messages;
res = g_buffered_input_stream_fill_finish (client->in, result, NULL);
if (res > 0)
old_len = client->buffer->len;
/* Ensure we have at least INPUT_BUFFER_SIZE extra space */
g_string_set_size (client->buffer, old_len + INPUT_BUFFER_SIZE);
g_string_set_size (client->buffer, old_len);
input_vector.buffer = client->buffer->str + old_len;
input_vector.size = client->buffer->allocated_len - client->buffer->len -1;
res = g_socket_receive_message (socket, NULL,
&input_vector, 1,
&messages, &num_messages,
NULL, NULL, NULL);
if (res <= 0)
{
client->source = NULL;
client_disconnected (client);
return G_SOURCE_REMOVE;
}
for (i = 0; i < num_messages; i++)
{
if (G_IS_UNIX_FD_MESSAGE (messages[i]))
{
int j, n_fds;
int *fds = g_unix_fd_message_steal_fds (G_UNIX_FD_MESSAGE (messages[i]), &n_fds);
for (j = 0; j < n_fds; j++)
{
int fd = fds[i];
client->fds = g_list_append (client->fds, GINT_TO_POINTER (fd));
}
g_free (fds);
}
g_object_unref (messages[i]);
}
g_free (messages);
g_string_set_size (client->buffer, old_len + res);
buffer = (guchar *)client->buffer->str;
buffer_len = client->buffer->len;
while (buffer_len >= sizeof (guint32))
{
guint32 size;
gsize count, remaining;
guint8 *buffer;
buffer = (guint8 *)g_buffered_input_stream_peek_buffer (client->in, &count);
memcpy (&size, buffer, sizeof (guint32));
if (size <= buffer_len)
{
client_handle_request (client, (BroadwayRequest *)buffer);
remaining = count;
while (remaining >= sizeof (guint32))
{
memcpy (&size, buffer, sizeof (guint32));
if (size <= remaining)
{
client_handle_request (client, (BroadwayRequest *)buffer);
remaining -= size;
buffer += size;
}
}
/* This is guaranteed not to block */
g_input_stream_skip (G_INPUT_STREAM (client->in), count - remaining, NULL, NULL);
g_buffered_input_stream_fill_async (client->in,
4*1024,
0,
NULL,
client_fill_cb, client);
}
else
{
client_disconnected (client);
buffer_len -= size;
buffer += size;
}
else
break;
}
g_string_erase (client->buffer, 0, client->buffer->len - buffer_len);
return G_SOURCE_CONTINUE;
}
static gboolean
incoming_client (GSocketService *service,
GSocketConnection *connection,
GObject *source_object)
GSocketConnection *connection,
GObject *source_object)
{
BroadwayClient *client;
GInputStream *input;
@@ -380,28 +608,28 @@ incoming_client (GSocketService *service,
client = g_new0 (BroadwayClient, 1);
client->id = client_id_count++;
client->connection = g_object_ref (connection);
client->textures = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
input = g_io_stream_get_input_stream (G_IO_STREAM (client->connection));
client->in = (GBufferedInputStream *)g_buffered_input_stream_new (input);
client->in = input;
client->buffer = g_string_sized_new (INPUT_BUFFER_SIZE);
client->source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (input), NULL);
g_source_set_callback (client->source, (GSourceFunc) client_input_cb, client, NULL);
g_source_attach (client->source, NULL);
clients = g_list_prepend (clients, client);
g_buffered_input_stream_fill_async (client->in,
4*1024,
0,
NULL,
client_fill_cb, client);
/* Send initial resize notify */
ev.base.type = BROADWAY_EVENT_SCREEN_SIZE_CHANGED;
ev.base.serial = broadway_server_get_next_serial (server) - 1;
ev.base.time = broadway_server_get_last_seen_time (server);
broadway_server_get_screen_size (server,
&ev.screen_resize_notify.width,
&ev.screen_resize_notify.height);
&ev.screen_resize_notify.width,
&ev.screen_resize_notify.height);
broadway_events_got_input (&ev,
client->id);
client->id);
return TRUE;
}
@@ -413,7 +641,6 @@ main (int argc, char *argv[])
GError *error = NULL;
GOptionContext *context;
GMainLoop *loop;
GInetAddress *inet;
GSocketAddress *address;
GSocketService *listener;
char *http_address = NULL;
@@ -448,34 +675,17 @@ main (int argc, char *argv[])
if (argc > 1)
{
if (*argv[1] != ':')
{
g_printerr ("Usage gtk4-broadwayd [:DISPLAY]\n");
exit (1);
}
{
g_printerr ("Usage gtk4-broadwayd [:DISPLAY]\n");
exit (1);
}
display = argv[1];
}
if (display == NULL)
{
#ifdef G_OS_UNIX
if (g_unix_socket_address_abstract_names_supported ())
display = ":0";
else
#endif
display = ":tcp";
}
display = ":0";
if (g_str_has_prefix (display, ":tcp"))
{
port = strtol (display + strlen (":tcp"), NULL, 10);
inet = g_inet_address_new_from_string ("127.0.0.1");
g_print ("Listening on 127.0.0.1:%d\n", port + 9090);
address = g_inet_socket_address_new (inet, port + 9090);
g_object_unref (inet);
}
#ifdef G_OS_UNIX
else if (display[0] == ':' && g_ascii_isdigit(display[1]))
if (display[0] == ':' && g_ascii_isdigit(display[1]))
{
char *path, *basename;
@@ -484,12 +694,13 @@ main (int argc, char *argv[])
path = g_build_filename (g_get_user_runtime_dir (), basename, NULL);
g_free (basename);
unlink (path);
g_print ("Listening on %s\n", path);
address = g_unix_socket_address_new_with_type (path, -1,
G_UNIX_SOCKET_ADDRESS_ABSTRACT);
G_UNIX_SOCKET_ADDRESS_PATH);
g_free (path);
}
#endif
else
{
g_printerr ("Failed to parse display %s\n", display);
@@ -516,12 +727,12 @@ main (int argc, char *argv[])
listener = g_socket_service_new ();
if (!g_socket_listener_add_address (G_SOCKET_LISTENER (listener),
address,
G_SOCKET_TYPE_STREAM,
G_SOCKET_PROTOCOL_DEFAULT,
G_OBJECT (server),
NULL,
&error))
address,
G_SOCKET_TYPE_STREAM,
G_SOCKET_PROTOCOL_DEFAULT,
G_OBJECT (server),
NULL,
&error))
{
g_printerr ("Can't listen: %s\n", error->message);
return 1;
@@ -562,8 +773,8 @@ get_event_size (int type)
return sizeof (BroadwayInputGrabReply);
case BROADWAY_EVENT_CONFIGURE_NOTIFY:
return sizeof (BroadwayInputConfigureNotify);
case BROADWAY_EVENT_DELETE_NOTIFY:
return sizeof (BroadwayInputDeleteNotify);
case BROADWAY_EVENT_ROUNDTRIP_NOTIFY:
return sizeof (BroadwayInputRoundtripNotify);
case BROADWAY_EVENT_SCREEN_SIZE_CHANGED:
return sizeof (BroadwayInputScreenResizeNotify);
case BROADWAY_EVENT_FOCUS:
@@ -576,7 +787,7 @@ get_event_size (int type)
void
broadway_events_got_input (BroadwayInputMsg *message,
gint32 client_id)
gint32 client_id)
{
GList *l;
BroadwayReplyEvent reply_event;
@@ -596,13 +807,13 @@ broadway_events_got_input (BroadwayInputMsg *message,
BroadwayClient *client = l->data;
if (client_id == -1 ||
client->id == client_id)
{
reply_event.msg.base.serial = get_client_serial (client, daemon_serial);
client->id == client_id)
{
reply_event.msg.base.serial = get_client_serial (client, daemon_serial);
send_reply (client, NULL, (BroadwayReply *)&reply_event,
G_STRUCT_OFFSET (BroadwayReplyEvent, msg) + size,
BROADWAY_REPLY_EVENT);
}
send_reply (client, NULL, (BroadwayReply *)&reply_event,
G_STRUCT_OFFSET (BroadwayReplyEvent, msg) + size,
BROADWAY_REPLY_EVENT);
}
}
}

View File

@@ -1,5 +1,9 @@
#include "config.h"
#ifdef HAVE_LINUX_MEMFD_H
#include <linux/memfd.h>
#endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
@@ -9,12 +13,12 @@
#include "gdkbroadway-server.h"
#include "gdkprivate-broadway.h"
#include <gdk/gdktextureprivate.h>
#include <glib.h>
#include <glib/gprintf.h>
#ifdef G_OS_UNIX
#include <gio/gunixsocketaddress.h>
#endif
#include <gio/gunixfdmessage.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
@@ -36,6 +40,7 @@ struct _GdkBroadwayServer {
GObject parent_instance;
guint32 next_serial;
guint32 next_texture_id;
GSocketConnection *connection;
guint32 recv_buffer_size;
@@ -43,7 +48,6 @@ struct _GdkBroadwayServer {
guint process_input_idle;
GList *incomming;
};
struct _GdkBroadwayServerClass
@@ -61,6 +65,7 @@ static void
gdk_broadway_server_init (GdkBroadwayServer *server)
{
server->next_serial = 1;
server->next_texture_id = 1;
}
static void
@@ -79,9 +84,8 @@ gdk_broadway_server_class_init (GdkBroadwayServerClass * class)
gboolean
_gdk_broadway_server_lookahead_event (GdkBroadwayServer *server,
const char *types)
const char *types)
{
return FALSE;
}
@@ -97,7 +101,6 @@ _gdk_broadway_server_new (const char *display, GError **error)
GdkBroadwayServer *server;
GSocketClient *client;
GSocketConnection *connection;
GInetAddress *inet;
GSocketAddress *address;
GPollableInputStream *pollable;
GInputStream *in;
@@ -106,25 +109,9 @@ _gdk_broadway_server_new (const char *display, GError **error)
int port;
if (display == NULL)
{
#ifdef G_OS_UNIX
if (g_unix_socket_address_abstract_names_supported ())
display = ":0";
else
#endif
display = ":tcp";
}
display = ":0";
if (g_str_has_prefix (display, ":tcp"))
{
port = 9090 + strtol (display + strlen (":tcp"), NULL, 10);
inet = g_inet_address_new_from_string ("127.0.0.1");
address = g_inet_socket_address_new (inet, port);
g_object_unref (inet);
}
#ifdef G_OS_UNIX
else if (display[0] == ':' && g_ascii_isdigit(display[1]))
if (display[0] == ':' && g_ascii_isdigit(display[1]))
{
char *path, *basename;
@@ -134,14 +121,13 @@ _gdk_broadway_server_new (const char *display, GError **error)
g_free (basename);
address = g_unix_socket_address_new_with_type (path, -1,
G_UNIX_SOCKET_ADDRESS_ABSTRACT);
G_UNIX_SOCKET_ADDRESS_PATH);
g_free (path);
}
#endif
else
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("Broadway display type not supported: %s"), display);
_("Broadway display type not supported: %s"), display);
return NULL;
}
@@ -178,30 +164,72 @@ _gdk_broadway_server_get_last_seen_time (GdkBroadwayServer *server)
static guint32
gdk_broadway_server_send_message_with_size (GdkBroadwayServer *server, BroadwayRequestBase *base,
gsize size, guint32 type)
gsize size, guint32 type, int fd)
{
GOutputStream *out;
gsize written;
guchar *buf;
base->size = size;
base->type = type;
base->serial = server->next_serial++;
out = g_io_stream_get_output_stream (G_IO_STREAM (server->connection));
buf = (guchar *)base;
if (!g_output_stream_write_all (out, base, size, &written, NULL, NULL))
if (fd != -1)
{
g_printerr ("Unable to write to server\n");
exit (1);
GUnixFDList *fd_list = g_unix_fd_list_new_from_array (&fd, 1);
GSocketControlMessage *control_message = g_unix_fd_message_new_with_fd_list (fd_list);
GSocket *socket = g_socket_connection_get_socket (server->connection);
GOutputVector vector;
gssize bytes_written;
vector.buffer = buf;
vector.size = size;
bytes_written = g_socket_send_message (socket,
NULL, /* address */
&vector,
1,
&control_message, 1,
G_SOCKET_MSG_NONE,
NULL,
NULL);
if (bytes_written <= 0)
{
g_printerr ("Unable to write to server\n");
exit (1);
}
buf += bytes_written;
size -= bytes_written;
g_object_unref (control_message);
g_object_unref (fd_list);
}
if (size > 0)
{
out = g_io_stream_get_output_stream (G_IO_STREAM (server->connection));
if (!g_output_stream_write_all (out, buf, size, &written, NULL, NULL))
{
g_printerr ("Unable to write to server\n");
exit (1);
}
g_assert (written == size);
}
g_assert (written == size);
return base->serial;
}
#define gdk_broadway_server_send_message(_server, _msg, _type) \
gdk_broadway_server_send_message_with_size(_server, (BroadwayRequestBase *)&_msg, sizeof (_msg), _type)
gdk_broadway_server_send_message_with_size(_server, (BroadwayRequestBase *)&_msg, sizeof (_msg), _type, -1)
#define gdk_broadway_server_send_fd_message(_server, _msg, _type, _fd) \
gdk_broadway_server_send_message_with_size(_server, (BroadwayRequestBase *)&_msg, sizeof (_msg), _type, _fd)
static void
parse_all_input (GdkBroadwayServer *server)
@@ -217,7 +245,7 @@ parse_all_input (GdkBroadwayServer *server)
{
memcpy (&size, p, sizeof (guint32));
if (p + size > end)
break;
break;
reply = g_memdup (p, size);
p += size;
@@ -240,8 +268,8 @@ read_some_input_blocking (GdkBroadwayServer *server)
g_assert (server->recv_buffer_size < sizeof (server->recv_buffer));
res = g_input_stream_read (in, &server->recv_buffer[server->recv_buffer_size],
sizeof (server->recv_buffer) - server->recv_buffer_size,
NULL, NULL);
sizeof (server->recv_buffer) - server->recv_buffer_size,
NULL, NULL);
if (res <= 0)
{
@@ -266,8 +294,8 @@ read_some_input_nonblocking (GdkBroadwayServer *server)
g_assert (server->recv_buffer_size < sizeof (server->recv_buffer));
error = NULL;
res = g_pollable_input_stream_read_nonblocking (pollable, &server->recv_buffer[server->recv_buffer_size],
sizeof (server->recv_buffer) - server->recv_buffer_size,
NULL, &error);
sizeof (server->recv_buffer) - server->recv_buffer_size,
NULL, &error);
if (res < 0 && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
{
@@ -293,7 +321,7 @@ find_response_by_serial (GdkBroadwayServer *server, guint32 serial)
BroadwayReply *reply = l->data;
if (reply->base.in_reply_to == serial)
return reply;
return reply;
}
return NULL;
@@ -314,13 +342,13 @@ process_input_messages (GdkBroadwayServer *server)
{
reply = server->incomming->data;
server->incomming =
g_list_delete_link (server->incomming,
server->incomming);
g_list_delete_link (server->incomming,
server->incomming);
if (reply->base.type == BROADWAY_REPLY_EVENT)
_gdk_broadway_events_got_input (&reply->event.msg);
_gdk_broadway_events_got_input (&reply->event.msg);
else
g_warning ("Unhandled reply type %d", reply->base.type);
g_warning ("Unhandled reply type %d", reply->base.type);
g_free (reply);
}
}
@@ -356,7 +384,7 @@ input_available_cb (gpointer stream, gpointer user_data)
static BroadwayReply *
gdk_broadway_server_wait_for_reply (GdkBroadwayServer *server,
guint32 serial)
guint32 serial)
{
BroadwayReply *reply;
@@ -364,10 +392,10 @@ gdk_broadway_server_wait_for_reply (GdkBroadwayServer *server,
{
reply = find_response_by_serial (server, serial);
if (reply)
{
server->incomming = g_list_remove (server->incomming, reply);
break;
}
{
server->incomming = g_list_remove (server->incomming, reply);
break;
}
read_some_input_blocking (server);
parse_all_input (server);
@@ -382,7 +410,7 @@ _gdk_broadway_server_flush (GdkBroadwayServer *server)
{
BroadwayRequestFlush msg;
gdk_broadway_server_send_message(server, msg, BROADWAY_REQUEST_FLUSH);
gdk_broadway_server_send_message (server, msg, BROADWAY_REQUEST_FLUSH);
}
void
@@ -393,7 +421,7 @@ _gdk_broadway_server_sync (GdkBroadwayServer *server)
BroadwayReply *reply;
serial = gdk_broadway_server_send_message (server, msg,
BROADWAY_REQUEST_SYNC);
BROADWAY_REQUEST_SYNC);
reply = gdk_broadway_server_wait_for_reply (server, serial);
g_assert (reply->base.type == BROADWAY_REPLY_SYNC);
@@ -403,44 +431,57 @@ _gdk_broadway_server_sync (GdkBroadwayServer *server)
return;
}
void
_gdk_broadway_server_roundtrip (GdkBroadwayServer *server,
gint32 id,
guint32 tag)
{
BroadwayRequestRoundtrip msg;
msg.id = id;
msg.tag = tag;
gdk_broadway_server_send_message (server, msg,
BROADWAY_REQUEST_ROUNDTRIP);
}
void
_gdk_broadway_server_query_mouse (GdkBroadwayServer *server,
guint32 *toplevel,
gint32 *root_x,
gint32 *root_y,
guint32 *mask)
guint32 *surface,
gint32 *root_x,
gint32 *root_y,
guint32 *mask)
{
BroadwayRequestQueryMouse msg;
guint32 serial;
BroadwayReply *reply;
serial = gdk_broadway_server_send_message (server, msg,
BROADWAY_REQUEST_QUERY_MOUSE);
BROADWAY_REQUEST_QUERY_MOUSE);
reply = gdk_broadway_server_wait_for_reply (server, serial);
g_assert (reply->base.type == BROADWAY_REPLY_QUERY_MOUSE);
if (toplevel)
*toplevel = reply->query_mouse.toplevel;
if (surface)
*surface = reply->query_mouse.surface;
if (root_x)
*root_x = reply->query_mouse.root_x;
if (root_y)
*root_y = reply->query_mouse.root_y;
if (mask)
*mask = reply->query_mouse.mask;
g_free (reply);
}
guint32
_gdk_broadway_server_new_window (GdkBroadwayServer *server,
int x,
int y,
int width,
int height,
gboolean is_temp)
_gdk_broadway_server_new_surface (GdkBroadwayServer *server,
int x,
int y,
int width,
int height,
gboolean is_temp)
{
BroadwayRequestNewWindow msg;
BroadwayRequestNewSurface msg;
guint32 serial, id;
BroadwayReply *reply;
@@ -449,316 +490,218 @@ _gdk_broadway_server_new_window (GdkBroadwayServer *server,
msg.width = width;
msg.height = height;
msg.is_temp = is_temp;
serial = gdk_broadway_server_send_message (server, msg,
BROADWAY_REQUEST_NEW_WINDOW);
BROADWAY_REQUEST_NEW_SURFACE);
reply = gdk_broadway_server_wait_for_reply (server, serial);
g_assert (reply->base.type == BROADWAY_REPLY_NEW_WINDOW);
g_assert (reply->base.type == BROADWAY_REPLY_NEW_SURFACE);
id = reply->new_surface.id;
id = reply->new_window.id;
g_free (reply);
return id;
}
void
_gdk_broadway_server_destroy_window (GdkBroadwayServer *server,
gint id)
_gdk_broadway_server_destroy_surface (GdkBroadwayServer *server,
gint id)
{
BroadwayRequestDestroyWindow msg;
BroadwayRequestDestroySurface msg;
msg.id = id;
gdk_broadway_server_send_message (server, msg,
BROADWAY_REQUEST_DESTROY_WINDOW);
BROADWAY_REQUEST_DESTROY_SURFACE);
}
gboolean
_gdk_broadway_server_window_show (GdkBroadwayServer *server,
gint id)
_gdk_broadway_server_surface_show (GdkBroadwayServer *server,
gint id)
{
BroadwayRequestShowWindow msg;
BroadwayRequestShowSurface msg;
msg.id = id;
gdk_broadway_server_send_message (server, msg,
BROADWAY_REQUEST_SHOW_WINDOW);
BROADWAY_REQUEST_SHOW_SURFACE);
return TRUE;
}
gboolean
_gdk_broadway_server_window_hide (GdkBroadwayServer *server,
gint id)
_gdk_broadway_server_surface_hide (GdkBroadwayServer *server,
gint id)
{
BroadwayRequestHideWindow msg;
BroadwayRequestHideSurface msg;
msg.id = id;
gdk_broadway_server_send_message (server, msg,
BROADWAY_REQUEST_HIDE_WINDOW);
BROADWAY_REQUEST_HIDE_SURFACE);
return TRUE;
}
void
_gdk_broadway_server_window_focus (GdkBroadwayServer *server,
gint id)
_gdk_broadway_server_surface_focus (GdkBroadwayServer *server,
gint id)
{
BroadwayRequestFocusWindow msg;
BroadwayRequestFocusSurface msg;
msg.id = id;
gdk_broadway_server_send_message (server, msg,
BROADWAY_REQUEST_FOCUS_WINDOW);
BROADWAY_REQUEST_FOCUS_SURFACE);
}
void
_gdk_broadway_server_window_set_transient_for (GdkBroadwayServer *server,
gint id, gint parent)
_gdk_broadway_server_surface_set_transient_for (GdkBroadwayServer *server,
gint id, gint parent)
{
BroadwayRequestSetTransientFor msg;
msg.id = id;
msg.parent = parent;
gdk_broadway_server_send_message (server, msg,
BROADWAY_REQUEST_SET_TRANSIENT_FOR);
BROADWAY_REQUEST_SET_TRANSIENT_FOR);
}
static void *
map_named_shm (char *name, gsize size, gboolean *is_shm)
static int
open_shared_memory (void)
{
#ifdef G_OS_UNIX
static gboolean force_shm_open = FALSE;
int ret = -1;
char *filename = NULL;
int fd;
void *ptr;
int res;
fd = shm_open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
if (fd == -1)
{
if (errno == EEXIST)
return NULL;
filename = g_build_filename (g_get_tmp_dir (), name, NULL);
fd = open (filename, O_RDWR | O_CREAT | O_EXCL, 0600);
g_free (filename);
if (fd == -1)
{
if (errno != EEXIST)
g_error ("Unable to allocate shared mem for window");
return NULL;
}
else
*is_shm = FALSE;
}
else
*is_shm = TRUE;
res = ftruncate (fd, size);
g_assert (res != -1);
#ifdef HAVE_POSIX_FALLOCATE
res = posix_fallocate (fd, 0, size);
if (res != 0 && errno == ENOSPC)
{
if (filename)
unlink (filename);
else
shm_unlink (name);
g_error ("Not enough shared memory for window surface");
}
#if !defined (__NR_memfd_create)
force_shm_open = TRUE;
#endif
ptr = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
(void) close(fd);
return ptr;
#elif defined(G_OS_WIN32)
int fd;
void *ptr;
char *shmpath;
void *map = ((void *)-1);
int res;
if (*name == '/')
++name;
shmpath = g_build_filename (g_get_tmp_dir (), name, NULL);
fd = open(shmpath, O_RDWR|O_CREAT|O_EXCL, 0600);
g_free (shmpath);
if (fd == -1)
do
{
if (errno != EEXIST)
g_error ("Unable to allocate shared mem for window");
return NULL;
}
#if defined (__NR_memfd_create)
if (!force_shm_open)
{
ret = syscall (__NR_memfd_create, "gdk-broadway", MFD_CLOEXEC);
*is_shm = TRUE;
res = ftruncate (fd, size);
g_assert (res != -1);
if (size == 0)
ptr = map;
else
{
HANDLE h, fm;
h = (HANDLE)_get_osfhandle (fd);
fm = CreateFileMapping (h, NULL, PAGE_READWRITE, 0, (DWORD)size, NULL);
ptr = MapViewOfFile (fm, FILE_MAP_WRITE, 0, 0, (size_t)size);
CloseHandle (fm);
}
(void) close(fd);
return ptr;
#else
#error "No shm mapping supported"
return NULL;
/* fall back to shm_open until debian stops shipping 3.16 kernel
* See bug 766341
*/
if (ret < 0 && errno == ENOSYS)
force_shm_open = TRUE;
}
#endif
}
static char
make_valid_fs_char (char c)
{
char chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890";
if (force_shm_open)
{
char name[NAME_MAX - 1] = "";
return chars[c % (sizeof (chars) - 1)];
}
sprintf (name, "/gdk-broadway-%x", g_random_int ());
/* name must have at least space for 34 bytes */
static gpointer
create_random_shm (char *name, gsize size, gboolean *is_shm)
{
guint32 r;
int i, o;
gpointer ptr;
ret = shm_open (name, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC, 0600);
while (TRUE)
{
o = 0;
name[o++] = '/';
name[o++] = 'b';
name[o++] = 'd';
name[o++] = 'w';
name[o++] = '-';
for (i = 0; i < 32/4 - 1; i++)
{
r = g_random_int ();
name[o++] = make_valid_fs_char ((r >> 0) & 0xff);
name[o++] = make_valid_fs_char ((r >> 8) & 0xff);
name[o++] = make_valid_fs_char ((r >> 16) & 0xff);
name[o++] = make_valid_fs_char ((r >> 24) & 0xff);
}
name[o++] = 0;
ptr = map_named_shm (name, size, is_shm);
if (ptr)
return ptr;
if (ret >= 0)
shm_unlink (name);
else if (errno == EEXIST)
continue;
}
}
}
while (ret < 0 && errno == EINTR);
static const cairo_user_data_key_t gdk_broadway_shm_cairo_key;
if (ret < 0)
g_critical (G_STRLOC ": creating shared memory file (using %s) failed: %m",
force_shm_open? "shm_open" : "memfd_create");
return ret;
}
typedef struct {
char name[36];
void *data;
gsize data_size;
gboolean is_shm;
} BroadwayShmSurfaceData;
int fd;
gsize size;
} PngData;
static void
shm_data_destroy (void *_data)
static cairo_status_t
write_png_cb (void *closure,
const guchar *data,
unsigned int length)
{
BroadwayShmSurfaceData *data = _data;
PngData *png_data = closure;
int fd = png_data->fd;
#ifdef G_OS_UNIX
munmap (data->data, data->data_size);
if (data->is_shm)
shm_unlink (data->name);
else
while (length)
{
char *filename = g_build_filename (g_get_tmp_dir (), data->name, NULL);
unlink (filename);
g_free (filename);
gssize ret = write (fd, data, length);
if (ret <= 0)
return CAIRO_STATUS_WRITE_ERROR;
png_data->size += ret;
length -= ret;
data += ret;
}
#elif defined(G_OS_WIN32)
char *name = data->name;
char *shmpath;
if (*name == '/')
++name;
shmpath = g_build_filename (g_get_tmp_dir (), name, NULL);
UnmapViewOfFile (data->data);
remove (shmpath);
g_free (shmpath);
#endif
g_free (data);
return CAIRO_STATUS_SUCCESS;
}
cairo_surface_t *
_gdk_broadway_server_create_surface (int width,
int height)
guint32
gdk_broadway_server_upload_texture (GdkBroadwayServer *server,
GdkTexture *texture)
{
BroadwayShmSurfaceData *data;
cairo_surface_t *surface;
guint32 id;
cairo_surface_t *surface = gdk_texture_download_surface (texture);
BroadwayRequestUploadTexture msg;
PngData data;
data = g_new (BroadwayShmSurfaceData, 1);
data->data_size = width * height * sizeof (guint32);
data->data = create_random_shm (data->name, data->data_size, &data->is_shm);
id = server->next_texture_id++;
surface = cairo_image_surface_create_for_data ((guchar *)data->data,
CAIRO_FORMAT_ARGB32, width, height, width * sizeof (guint32));
g_assert (surface != NULL);
cairo_surface_set_user_data (surface, &gdk_broadway_shm_cairo_key,
data, shm_data_destroy);
data.fd = open_shared_memory ();
data.size = 0;
cairo_surface_write_to_png_stream (surface, write_png_cb, &data);
return surface;
msg.id = id;
msg.offset = 0;
msg.size = data.size;
/* This passes ownership of fd */
gdk_broadway_server_send_fd_message (server, msg,
BROADWAY_REQUEST_UPLOAD_TEXTURE, data.fd);
return id;
}
void
gdk_broadway_server_release_texture (GdkBroadwayServer *server,
guint32 id)
{
BroadwayRequestReleaseTexture msg;
msg.id = id;
gdk_broadway_server_send_message (server, msg,
BROADWAY_REQUEST_RELEASE_TEXTURE);
}
void
_gdk_broadway_server_window_update (GdkBroadwayServer *server,
gint id,
cairo_surface_t *surface)
gdk_broadway_server_surface_set_nodes (GdkBroadwayServer *server,
guint32 id,
GArray *nodes)
{
BroadwayRequestUpdate msg;
BroadwayShmSurfaceData *data;
gsize size = sizeof(BroadwayRequestSetNodes) + sizeof(guint32) * (nodes->len - 1);
BroadwayRequestSetNodes *msg = g_alloca (size);
int i;
if (surface == NULL)
return;
for (i = 0; i < nodes->len; i++)
msg->data[i] = g_array_index (nodes, guint32, i);
data = cairo_surface_get_user_data (surface, &gdk_broadway_shm_cairo_key);
g_assert (data != NULL);
msg.id = id;
memcpy (msg.name, data->name, 36);
msg.width = cairo_image_surface_get_width (surface);
msg.height = cairo_image_surface_get_height (surface);
gdk_broadway_server_send_message (server, msg,
BROADWAY_REQUEST_UPDATE);
msg->id = id;
gdk_broadway_server_send_message_with_size (server, (BroadwayRequestBase *) msg, size, BROADWAY_REQUEST_SET_NODES, -1);
}
gboolean
_gdk_broadway_server_window_move_resize (GdkBroadwayServer *server,
gint id,
gboolean with_move,
int x,
int y,
int width,
int height)
_gdk_broadway_server_surface_move_resize (GdkBroadwayServer *server,
gint id,
gboolean with_move,
int x,
int y,
int width,
int height)
{
BroadwayRequestMoveResize msg;
@@ -770,17 +713,17 @@ _gdk_broadway_server_window_move_resize (GdkBroadwayServer *server,
msg.height = height;
gdk_broadway_server_send_message (server, msg,
BROADWAY_REQUEST_MOVE_RESIZE);
BROADWAY_REQUEST_MOVE_RESIZE);
return TRUE;
}
GdkGrabStatus
_gdk_broadway_server_grab_pointer (GdkBroadwayServer *server,
gint id,
gboolean owner_events,
guint32 event_mask,
guint32 time_)
gint id,
gboolean owner_events,
guint32 event_mask,
guint32 time_)
{
BroadwayRequestGrabPointer msg;
guint32 serial, status;
@@ -792,7 +735,7 @@ _gdk_broadway_server_grab_pointer (GdkBroadwayServer *server,
msg.time_ = time_;
serial = gdk_broadway_server_send_message (server, msg,
BROADWAY_REQUEST_GRAB_POINTER);
BROADWAY_REQUEST_GRAB_POINTER);
reply = gdk_broadway_server_wait_for_reply (server, serial);
g_assert (reply->base.type == BROADWAY_REPLY_GRAB_POINTER);
@@ -806,7 +749,7 @@ _gdk_broadway_server_grab_pointer (GdkBroadwayServer *server,
guint32
_gdk_broadway_server_ungrab_pointer (GdkBroadwayServer *server,
guint32 time_)
guint32 time_)
{
BroadwayRequestUngrabPointer msg;
guint32 serial, status;
@@ -815,7 +758,7 @@ _gdk_broadway_server_ungrab_pointer (GdkBroadwayServer *server,
msg.time_ = time_;
serial = gdk_broadway_server_send_message (server, msg,
BROADWAY_REQUEST_UNGRAB_POINTER);
BROADWAY_REQUEST_UNGRAB_POINTER);
reply = gdk_broadway_server_wait_for_reply (server, serial);
g_assert (reply->base.type == BROADWAY_REPLY_UNGRAB_POINTER);
@@ -835,5 +778,5 @@ _gdk_broadway_server_set_show_keyboard (GdkBroadwayServer *server,
msg.show_keyboard = show;
gdk_broadway_server_send_message (server, msg,
BROADWAY_REQUEST_SET_SHOW_KEYBOARD);
BROADWAY_REQUEST_SET_SHOW_KEYBOARD);
}

View File

@@ -18,12 +18,15 @@ GdkBroadwayServer *_gdk_broadway_server_new (const char
GError **error);
void _gdk_broadway_server_flush (GdkBroadwayServer *server);
void _gdk_broadway_server_sync (GdkBroadwayServer *server);
void _gdk_broadway_server_roundtrip (GdkBroadwayServer *server,
gint32 id,
guint32 tag);
gulong _gdk_broadway_server_get_next_serial (GdkBroadwayServer *server);
guint32 _gdk_broadway_server_get_last_seen_time (GdkBroadwayServer *server);
gboolean _gdk_broadway_server_lookahead_event (GdkBroadwayServer *server,
const char *types);
void _gdk_broadway_server_query_mouse (GdkBroadwayServer *server,
guint32 *toplevel,
guint32 *surface,
gint32 *root_x,
gint32 *root_y,
guint32 *mask);
@@ -34,37 +37,39 @@ GdkGrabStatus _gdk_broadway_server_grab_pointer (GdkBroadwaySer
guint32 time_);
guint32 _gdk_broadway_server_ungrab_pointer (GdkBroadwayServer *server,
guint32 time_);
gint32 _gdk_broadway_server_get_mouse_toplevel (GdkBroadwayServer *server);
guint32 _gdk_broadway_server_new_window (GdkBroadwayServer *server,
gint32 _gdk_broadway_server_get_mouse_surface (GdkBroadwayServer *server);
guint32 _gdk_broadway_server_new_surface (GdkBroadwayServer *server,
int x,
int y,
int width,
int height,
gboolean is_temp);
void _gdk_broadway_server_destroy_window (GdkBroadwayServer *server,
void _gdk_broadway_server_destroy_surface (GdkBroadwayServer *server,
gint id);
gboolean _gdk_broadway_server_window_show (GdkBroadwayServer *server,
gboolean _gdk_broadway_server_surface_show (GdkBroadwayServer *server,
gint id);
gboolean _gdk_broadway_server_window_hide (GdkBroadwayServer *server,
gboolean _gdk_broadway_server_surface_hide (GdkBroadwayServer *server,
gint id);
void _gdk_broadway_server_window_focus (GdkBroadwayServer *server,
void _gdk_broadway_server_surface_focus (GdkBroadwayServer *server,
gint id);
void _gdk_broadway_server_window_set_transient_for (GdkBroadwayServer *server,
void _gdk_broadway_server_surface_set_transient_for (GdkBroadwayServer *server,
gint id,
gint parent);
void _gdk_broadway_server_set_show_keyboard (GdkBroadwayServer *server,
gboolean show_keyboard);
gboolean _gdk_broadway_server_window_translate (GdkBroadwayServer *server,
gboolean _gdk_broadway_server_surface_translate (GdkBroadwayServer *server,
gint id,
cairo_region_t *area,
gint dx,
gint dy);
cairo_surface_t *_gdk_broadway_server_create_surface (int width,
int height);
void _gdk_broadway_server_window_update (GdkBroadwayServer *server,
gint id,
cairo_surface_t *surface);
gboolean _gdk_broadway_server_window_move_resize (GdkBroadwayServer *server,
guint32 gdk_broadway_server_upload_texture (GdkBroadwayServer *server,
GdkTexture *texture);
void gdk_broadway_server_release_texture (GdkBroadwayServer *server,
guint32 id);
void gdk_broadway_server_surface_set_nodes (GdkBroadwayServer *server,
guint32 id,
GArray *nodes);
gboolean _gdk_broadway_server_surface_move_resize (GdkBroadwayServer *server,
gint id,
gboolean with_move,
int x,

View File

@@ -91,8 +91,8 @@ gdk_broadway_device_init (GdkBroadwayDevice *device_core)
device = GDK_DEVICE (device_core);
_gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1);
_gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
_gdk_device_add_axis (device, NULL, GDK_AXIS_X, 0, 0, 1);
_gdk_device_add_axis (device, NULL, GDK_AXIS_Y, 0, 0, 1);
}
static gboolean

View File

@@ -1,178 +0,0 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gdkdevicemanager-broadway.h"
#include "gdktypes.h"
#include "gdkdevicemanager.h"
#include "gdkdevice-broadway.h"
#include "gdkkeysyms.h"
#include "gdkprivate-broadway.h"
#include "gdkseatdefaultprivate.h"
#define HAS_FOCUS(toplevel) \
((toplevel)->has_focus || (toplevel)->has_pointer_focus)
static void gdk_broadway_device_manager_finalize (GObject *object);
static void gdk_broadway_device_manager_constructed (GObject *object);
static GList * gdk_broadway_device_manager_list_devices (GdkDeviceManager *device_manager,
GdkDeviceType type);
static GdkDevice * gdk_broadway_device_manager_get_client_pointer (GdkDeviceManager *device_manager);
G_DEFINE_TYPE (GdkBroadwayDeviceManager, gdk_broadway_device_manager, GDK_TYPE_DEVICE_MANAGER)
static void
gdk_broadway_device_manager_class_init (GdkBroadwayDeviceManagerClass *klass)
{
GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gdk_broadway_device_manager_finalize;
object_class->constructed = gdk_broadway_device_manager_constructed;
device_manager_class->list_devices = gdk_broadway_device_manager_list_devices;
device_manager_class->get_client_pointer = gdk_broadway_device_manager_get_client_pointer;
}
static GdkDevice *
create_core_pointer (GdkDeviceManager *device_manager,
GdkDisplay *display)
{
return g_object_new (GDK_TYPE_BROADWAY_DEVICE,
"name", "Core Pointer",
"type", GDK_DEVICE_TYPE_MASTER,
"input-source", GDK_SOURCE_MOUSE,
"input-mode", GDK_MODE_SCREEN,
"has-cursor", TRUE,
"display", display,
"device-manager", device_manager,
NULL);
}
static GdkDevice *
create_core_keyboard (GdkDeviceManager *device_manager,
GdkDisplay *display)
{
return g_object_new (GDK_TYPE_BROADWAY_DEVICE,
"name", "Core Keyboard",
"type", GDK_DEVICE_TYPE_MASTER,
"input-source", GDK_SOURCE_KEYBOARD,
"input-mode", GDK_MODE_SCREEN,
"has-cursor", FALSE,
"display", display,
"device-manager", device_manager,
NULL);
}
static GdkDevice *
create_touchscreen (GdkDeviceManager *device_manager,
GdkDisplay *display)
{
return g_object_new (GDK_TYPE_BROADWAY_DEVICE,
"name", "Touchscreen",
"type", GDK_DEVICE_TYPE_SLAVE,
"input-source", GDK_SOURCE_TOUCHSCREEN,
"input-mode", GDK_MODE_SCREEN,
"has-cursor", FALSE,
"display", display,
"device-manager", device_manager,
NULL);
}
static void
gdk_broadway_device_manager_init (GdkBroadwayDeviceManager *device_manager)
{
}
static void
gdk_broadway_device_manager_finalize (GObject *object)
{
GdkBroadwayDeviceManager *device_manager;
device_manager = GDK_BROADWAY_DEVICE_MANAGER (object);
g_object_unref (device_manager->core_pointer);
g_object_unref (device_manager->core_keyboard);
g_object_unref (device_manager->touchscreen);
G_OBJECT_CLASS (gdk_broadway_device_manager_parent_class)->finalize (object);
}
static void
gdk_broadway_device_manager_constructed (GObject *object)
{
GdkBroadwayDeviceManager *device_manager;
GdkDisplay *display;
GdkSeat *seat;
device_manager = GDK_BROADWAY_DEVICE_MANAGER (object);
display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
device_manager->core_pointer = create_core_pointer (GDK_DEVICE_MANAGER (device_manager), display);
device_manager->core_keyboard = create_core_keyboard (GDK_DEVICE_MANAGER (device_manager), display);
device_manager->touchscreen = create_touchscreen (GDK_DEVICE_MANAGER (device_manager), display);
_gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard);
_gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer);
_gdk_device_set_associated_device (device_manager->touchscreen, device_manager->core_pointer);
_gdk_device_add_slave (device_manager->core_pointer, device_manager->touchscreen);
seat = gdk_seat_default_new_for_master_pair (device_manager->core_pointer,
device_manager->core_keyboard);
gdk_display_add_seat (display, seat);
gdk_seat_default_add_slave (GDK_SEAT_DEFAULT (seat), device_manager->touchscreen);
g_object_unref (seat);
}
static GList *
gdk_broadway_device_manager_list_devices (GdkDeviceManager *device_manager,
GdkDeviceType type)
{
GdkBroadwayDeviceManager *broadway_device_manager = (GdkBroadwayDeviceManager *) device_manager;
GList *devices = NULL;
if (type == GDK_DEVICE_TYPE_MASTER)
{
devices = g_list_prepend (devices, broadway_device_manager->core_keyboard);
devices = g_list_prepend (devices, broadway_device_manager->core_pointer);
}
if (type == GDK_DEVICE_TYPE_SLAVE)
{
devices = g_list_prepend (devices, broadway_device_manager->touchscreen);
}
return devices;
}
static GdkDevice *
gdk_broadway_device_manager_get_client_pointer (GdkDeviceManager *device_manager)
{
GdkBroadwayDeviceManager *broadway_device_manager = (GdkBroadwayDeviceManager *) device_manager;
return broadway_device_manager->core_pointer;
}
GdkDeviceManager *
_gdk_broadway_device_manager_new (GdkDisplay *display)
{
return g_object_new (GDK_TYPE_BROADWAY_DEVICE_MANAGER,
"display", display,
NULL);
}

View File

@@ -1,53 +0,0 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GDK_DEVICE_MANAGER_BROADWAY_H__
#define __GDK_DEVICE_MANAGER_BROADWAY_H__
#include <gdk/gdkdevicemanagerprivate.h>
G_BEGIN_DECLS
#define GDK_TYPE_BROADWAY_DEVICE_MANAGER (gdk_broadway_device_manager_get_type ())
#define GDK_BROADWAY_DEVICE_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_BROADWAY_DEVICE_MANAGER, GdkBroadwayDeviceManager))
#define GDK_BROADWAY_DEVICE_MANAGER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_BROADWAY_DEVICE_MANAGER, GdkBroadwayDeviceManagerClass))
#define GDK_IS_BROADWAY_DEVICE_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_BROADWAY_DEVICE_MANAGER))
#define GDK_IS_BROADWAY_DEVICE_MANAGER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_BROADWAY_DEVICE_MANAGER))
#define GDK_BROADWAY_DEVICE_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_BROADWAY_DEVICE_MANAGER, GdkBroadwayDeviceManagerClass))
typedef struct _GdkBroadwayDeviceManager GdkBroadwayDeviceManager;
typedef struct _GdkBroadwayDeviceManagerClass GdkBroadwayDeviceManagerClass;
struct _GdkBroadwayDeviceManager
{
GdkDeviceManager parent_object;
GdkDevice *core_pointer;
GdkDevice *core_keyboard;
GdkDevice *touchscreen;
};
struct _GdkBroadwayDeviceManagerClass
{
GdkDeviceManagerClass parent_class;
};
GType gdk_broadway_device_manager_get_type (void) G_GNUC_CONST;
GdkDeviceManager *_gdk_broadway_device_manager_new (GdkDisplay *display);
G_END_DECLS
#endif /* __GDK_DEVICE_MANAGER_BROADWAY_H__ */

View File

@@ -27,9 +27,11 @@
#include "gdkdisplay.h"
#include "gdkeventsource.h"
#include "gdkmonitor-broadway.h"
#include "gdkseatdefaultprivate.h"
#include "gdkdevice-broadway.h"
#include "gdkinternals.h"
#include "gdkdeviceprivate.h"
#include "gdkdevicemanager-broadway.h"
#include <gdk/gdktextureprivate.h>
#include <glib.h>
#include <glib/gprintf.h>
@@ -41,6 +43,92 @@
#endif
#include <sys/types.h>
static gboolean
compare_surface (cairo_surface_t *a,
cairo_surface_t *b,
int width,
int height)
{
unsigned char *data_a, *data_b;
int stride_a, stride_b;
int y;
data_a = cairo_image_surface_get_data (a);
stride_a = cairo_image_surface_get_stride (a);
data_b = cairo_image_surface_get_data (b);
stride_b = cairo_image_surface_get_stride (b);
for (y = 0; y < height; y++)
{
if (memcmp (data_a, data_b, 4 * width) != 0)
return FALSE;
data_a += stride_a;
data_b += stride_b;
}
return TRUE;
}
static gboolean
gdk_texture_equal (GdkTexture *a,
GdkTexture *b)
{
cairo_surface_t *surface_a;
cairo_surface_t *surface_b;
gboolean res;
if (a == b)
return TRUE;
if (a->width != b->width ||
a->height != b->height)
return FALSE;
surface_a = gdk_texture_download_surface (a);
surface_b = gdk_texture_download_surface (b);
res = compare_surface (surface_a, surface_b, a->width, a->height);
cairo_surface_destroy (surface_a);
cairo_surface_destroy (surface_b);
return res;
}
static guint
gdk_texture_hash (GdkTexture *self)
{
cairo_surface_t *surface;
unsigned char *data;
int stride;
guint32 *row;
guint64 sum;
int x, y, width, height;
guint h;
surface = gdk_texture_download_surface (self);
data = cairo_image_surface_get_data (surface);
stride = cairo_image_surface_get_stride (surface);
width = MIN (self->width, 4);
height = MIN (self->height, 4);
sum = 0;
for (y = 0; y < height; y++, data += stride)
{
row = (guint32 *)data;
for (x = 0; x < width; x++)
sum += row[x];
}
cairo_surface_destroy (surface);
h = sum / (width * height);
return h ^ self->width ^ (self->height << 16);
}
static void gdk_broadway_display_dispose (GObject *object);
static void gdk_broadway_display_finalize (GObject *object);
@@ -60,6 +148,7 @@ gdk_broadway_display_init (GdkBroadwayDisplay *display)
NULL);
gdk_monitor_set_manufacturer (display->monitor, "browser");
gdk_monitor_set_model (display->monitor, "0");
display->texture_cache = g_hash_table_new ((GHashFunc)gdk_texture_hash, (GEqualFunc)gdk_texture_equal);
}
static void
@@ -92,16 +181,51 @@ _gdk_broadway_display_size_changed (GdkDisplay *display,
toplevels = broadway_display->toplevels;
for (l = toplevels; l != NULL; l = l->next)
{
GdkWindow *toplevel = l->data;
GdkWindowImplBroadway *toplevel_impl = GDK_WINDOW_IMPL_BROADWAY (toplevel->impl);
GdkWindowImplBroadway *toplevel_impl = l->data;
if (toplevel_impl->maximized)
gdk_window_move_resize (toplevel, 0, 0, msg->width, msg->height);
gdk_window_move_resize (toplevel_impl->wrapper, 0, 0, msg->width, msg->height);
}
g_list_free (toplevels);
}
static GdkDevice *
create_core_pointer (GdkDisplay *display)
{
return g_object_new (GDK_TYPE_BROADWAY_DEVICE,
"name", "Core Pointer",
"type", GDK_DEVICE_TYPE_MASTER,
"input-source", GDK_SOURCE_MOUSE,
"input-mode", GDK_MODE_SCREEN,
"has-cursor", TRUE,
"display", display,
NULL);
}
static GdkDevice *
create_core_keyboard (GdkDisplay *display)
{
return g_object_new (GDK_TYPE_BROADWAY_DEVICE,
"name", "Core Keyboard",
"type", GDK_DEVICE_TYPE_MASTER,
"input-source", GDK_SOURCE_KEYBOARD,
"input-mode", GDK_MODE_SCREEN,
"has-cursor", FALSE,
"display", display,
NULL);
}
static GdkDevice *
create_touchscreen (GdkDisplay *display)
{
return g_object_new (GDK_TYPE_BROADWAY_DEVICE,
"name", "Touchscreen",
"type", GDK_DEVICE_TYPE_SLAVE,
"input-source", GDK_SOURCE_TOUCHSCREEN,
"input-mode", GDK_MODE_SCREEN,
"has-cursor", FALSE,
"display", display,
NULL);
}
GdkDisplay *
_gdk_broadway_display_open (const gchar *display_name)
@@ -109,11 +233,25 @@ _gdk_broadway_display_open (const gchar *display_name)
GdkDisplay *display;
GdkBroadwayDisplay *broadway_display;
GError *error = NULL;
GdkSeat *seat;
display = g_object_new (GDK_TYPE_BROADWAY_DISPLAY, NULL);
broadway_display = GDK_BROADWAY_DISPLAY (display);
display->device_manager = _gdk_broadway_device_manager_new (display);
broadway_display->core_pointer = create_core_pointer (display);
broadway_display->core_keyboard = create_core_keyboard (display);
broadway_display->touchscreen = create_touchscreen (display);
_gdk_device_set_associated_device (broadway_display->core_pointer, broadway_display->core_keyboard);
_gdk_device_set_associated_device (broadway_display->core_keyboard, broadway_display->core_pointer);
_gdk_device_set_associated_device (broadway_display->touchscreen, broadway_display->core_pointer);
_gdk_device_add_slave (broadway_display->core_pointer, broadway_display->touchscreen);
seat = gdk_seat_default_new_for_master_pair (broadway_display->core_pointer,
broadway_display->core_keyboard);
gdk_display_add_seat (display, seat);
gdk_seat_default_add_slave (GDK_SEAT_DEFAULT (seat), broadway_display->touchscreen);
g_object_unref (seat);
gdk_event_init (display);
@@ -320,6 +458,88 @@ gdk_broadway_display_get_setting (GdkDisplay *display,
return FALSE;
}
static guint32
gdk_broadway_display_get_last_seen_time (GdkDisplay *display)
{
return _gdk_broadway_server_get_last_seen_time (GDK_BROADWAY_DISPLAY (display)->server);
}
typedef struct {
int id;
GdkDisplay *display;
GdkTexture *in_cache;
GList *textures;
} BroadwayTextureData;
static void
broadway_texture_data_notify (BroadwayTextureData *data,
GdkTexture *disposed_texture)
{
GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (data->display);
if (data->in_cache == disposed_texture)
{
g_hash_table_remove (broadway_display->texture_cache, disposed_texture);
data->in_cache = NULL;
}
g_object_set_data (G_OBJECT (disposed_texture), "broadway-data", NULL);
data->textures = g_list_remove (data->textures, disposed_texture);
if (data->textures == NULL)
{
gdk_broadway_server_release_texture (broadway_display->server, data->id);
g_object_unref (data->display);
g_free (data);
}
else if (data->in_cache == NULL)
{
GdkTexture *first = data->textures->data;
data->in_cache = first;
g_hash_table_replace (broadway_display->texture_cache,
data->in_cache, data->in_cache);
}
}
guint32
gdk_broadway_display_ensure_texture (GdkDisplay *display,
GdkTexture *texture)
{
GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (display);
BroadwayTextureData *data;
guint32 id;
GdkTexture *cached;
data = g_object_get_data (G_OBJECT (texture), "broadway-data");
if (data != NULL)
return data->id;
cached = g_hash_table_lookup (broadway_display->texture_cache, texture);
if (cached)
data = g_object_get_data (G_OBJECT (cached), "broadway-data");
if (data == NULL)
{
id = gdk_broadway_server_upload_texture (broadway_display->server, texture);
data = g_new0 (BroadwayTextureData, 1);
data->id = id;
data->display = g_object_ref (display);
data->in_cache = texture;
g_hash_table_replace (broadway_display->texture_cache,
data->in_cache, data->in_cache);
}
data->textures = g_list_prepend (data->textures, texture);
g_object_weak_ref (G_OBJECT (texture), (GWeakNotify)broadway_texture_data_notify, data);
g_object_set_data (G_OBJECT (texture), "broadway-data", data);
return data->id;
}
static void
gdk_broadway_display_class_init (GdkBroadwayDisplayClass * class)
{
@@ -357,6 +577,8 @@ gdk_broadway_display_class_init (GdkBroadwayDisplayClass * class)
display_class->set_selection_owner = _gdk_broadway_display_set_selection_owner;
display_class->send_selection_notify = _gdk_broadway_display_send_selection_notify;
display_class->get_selection_property = _gdk_broadway_display_get_selection_property;
display_class->clear_selection_targets = gdk_broadway_display_clear_selection_targets;
display_class->add_selection_targets = gdk_broadway_display_add_selection_targets;
display_class->convert_selection = _gdk_broadway_display_convert_selection;
display_class->text_property_to_utf8_list = _gdk_broadway_display_text_property_to_utf8_list;
display_class->utf8_to_string_target = _gdk_broadway_display_utf8_to_string_target;
@@ -365,4 +587,5 @@ gdk_broadway_display_class_init (GdkBroadwayDisplayClass * class)
display_class->get_monitor = gdk_broadway_display_get_monitor;
display_class->get_primary_monitor = gdk_broadway_display_get_primary_monitor;
display_class->get_setting = gdk_broadway_display_get_setting;
display_class->get_last_seen_time = gdk_broadway_display_get_last_seen_time;
}

View File

@@ -28,7 +28,6 @@
#include "gdkkeys.h"
#include "gdkwindow.h"
#include "gdkinternals.h"
#include "gdkmain.h"
#include "gdkbroadway-server.h"
#include "gdkmonitorprivate.h"
@@ -41,6 +40,10 @@ struct _GdkBroadwayDisplay
GHashTable *id_ht;
GList *toplevels;
GdkDevice *core_pointer;
GdkDevice *core_keyboard;
GdkDevice *touchscreen;
GSource *event_source;
/* Keyboard related information */
@@ -54,6 +57,8 @@ struct _GdkBroadwayDisplay
gpointer move_resize_data;
GdkMonitor *monitor;
GHashTable *texture_cache;
};
struct _GdkBroadwayDisplayClass

View File

@@ -84,11 +84,12 @@ gdk_broadway_drag_context_finalize (GObject *object)
/* Drag Contexts */
GdkDragContext *
_gdk_broadway_window_drag_begin (GdkWindow *window,
GdkDevice *device,
GList *targets,
gint x_root,
gint y_root)
_gdk_broadway_window_drag_begin (GdkWindow *window,
GdkDevice *device,
GdkContentFormats *formats,
GdkDragAction actions,
gint dx,
gint dy)
{
GdkDragContext *new_context;
@@ -96,19 +97,12 @@ _gdk_broadway_window_drag_begin (GdkWindow *window,
g_return_val_if_fail (GDK_WINDOW_IS_BROADWAY (window), NULL);
new_context = g_object_new (GDK_TYPE_BROADWAY_DRAG_CONTEXT,
"display", gdk_window_get_display (window),
NULL);
new_context->display = gdk_window_get_display (window);
return new_context;
}
GdkDragProtocol
_gdk_broadway_window_get_drag_protocol (GdkWindow *window,
GdkWindow **target)
{
return GDK_DRAG_PROTO_NONE;
}
static GdkWindow *
gdk_broadway_drag_context_find_window (GdkDragContext *context,
GdkWindow *drag_window,
@@ -184,9 +178,9 @@ _gdk_broadway_window_register_dnd (GdkWindow *window)
static GdkAtom
gdk_broadway_drag_context_get_selection (GdkDragContext *context)
{
g_return_val_if_fail (context != NULL, GDK_NONE);
g_return_val_if_fail (context != NULL, NULL);
return GDK_NONE;
return NULL;
}
static gboolean

View File

@@ -18,9 +18,10 @@
#include "config.h"
#include "gdkeventsource.h"
#include "gdkdevicemanager-broadway.h"
#include "gdkseat.h"
#include "gdkinternals.h"
#include "gdkframeclockprivate.h"
#include <stdlib.h>
@@ -32,7 +33,7 @@ static gboolean gdk_event_source_dispatch (GSource *source,
gpointer user_data);
static void gdk_event_source_finalize (GSource *source);
#define HAS_FOCUS(toplevel) \
#define HAS_FOCUS(toplevel) \
((toplevel)->has_focus || (toplevel)->has_pointer_focus)
struct _GdkEventSource
@@ -94,7 +95,7 @@ _gdk_broadway_events_got_input (BroadwayInputMsg *message)
{
GdkDisplay *display;
GdkBroadwayDisplay *display_broadway;
GdkBroadwayDeviceManager *device_manager;
GdkSeat *seat;
GdkWindow *window;
GdkEvent *event = NULL;
GList *node;
@@ -116,124 +117,122 @@ _gdk_broadway_events_got_input (BroadwayInputMsg *message)
g_assert (display != NULL);
display_broadway = GDK_BROADWAY_DISPLAY (display);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
device_manager = GDK_BROADWAY_DEVICE_MANAGER (gdk_display_get_device_manager (display));
G_GNUC_END_IGNORE_DEPRECATIONS;
seat = gdk_display_get_default_seat (display);
switch (message->base.type) {
case BROADWAY_EVENT_ENTER:
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_window_id));
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_surface_id));
if (window)
{
event = gdk_event_new (GDK_ENTER_NOTIFY);
event->crossing.window = g_object_ref (window);
event->crossing.time = message->base.time;
event->crossing.x = message->pointer.win_x;
event->crossing.y = message->pointer.win_y;
event->crossing.x_root = message->pointer.root_x;
event->crossing.y_root = message->pointer.root_y;
event->crossing.state = message->pointer.state;
event->crossing.mode = message->crossing.mode;
event->crossing.detail = GDK_NOTIFY_ANCESTOR;
gdk_event_set_device (event, device_manager->core_pointer);
gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer));
event = gdk_event_new (GDK_ENTER_NOTIFY);
event->crossing.window = g_object_ref (window);
event->crossing.time = message->base.time;
event->crossing.x = message->pointer.win_x;
event->crossing.y = message->pointer.win_y;
event->crossing.x_root = message->pointer.root_x;
event->crossing.y_root = message->pointer.root_y;
event->crossing.state = message->pointer.state;
event->crossing.mode = message->crossing.mode;
event->crossing.detail = GDK_NOTIFY_ANCESTOR;
gdk_event_set_device (event, gdk_seat_get_pointer (seat));
gdk_event_set_seat (event, seat);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
}
break;
case BROADWAY_EVENT_LEAVE:
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_window_id));
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_surface_id));
if (window)
{
event = gdk_event_new (GDK_LEAVE_NOTIFY);
event->crossing.window = g_object_ref (window);
event->crossing.time = message->base.time;
event->crossing.x = message->pointer.win_x;
event->crossing.y = message->pointer.win_y;
event->crossing.x_root = message->pointer.root_x;
event->crossing.y_root = message->pointer.root_y;
event->crossing.state = message->pointer.state;
event->crossing.mode = message->crossing.mode;
event->crossing.detail = GDK_NOTIFY_ANCESTOR;
gdk_event_set_device (event, device_manager->core_pointer);
gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer));
event = gdk_event_new (GDK_LEAVE_NOTIFY);
event->crossing.window = g_object_ref (window);
event->crossing.time = message->base.time;
event->crossing.x = message->pointer.win_x;
event->crossing.y = message->pointer.win_y;
event->crossing.x_root = message->pointer.root_x;
event->crossing.y_root = message->pointer.root_y;
event->crossing.state = message->pointer.state;
event->crossing.mode = message->crossing.mode;
event->crossing.detail = GDK_NOTIFY_ANCESTOR;
gdk_event_set_device (event, gdk_seat_get_pointer (seat));
gdk_event_set_seat (event, seat);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
}
break;
case BROADWAY_EVENT_POINTER_MOVE:
if (_gdk_broadway_moveresize_handle_event (display, message))
break;
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_window_id));
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_surface_id));
if (window)
{
event = gdk_event_new (GDK_MOTION_NOTIFY);
event->motion.window = g_object_ref (window);
event->motion.time = message->base.time;
event->motion.x = message->pointer.win_x;
event->motion.y = message->pointer.win_y;
event->motion.x_root = message->pointer.root_x;
event->motion.y_root = message->pointer.root_y;
event->motion.state = message->pointer.state;
gdk_event_set_device (event, device_manager->core_pointer);
gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer));
event = gdk_event_new (GDK_MOTION_NOTIFY);
event->motion.window = g_object_ref (window);
event->motion.time = message->base.time;
event->motion.x = message->pointer.win_x;
event->motion.y = message->pointer.win_y;
event->motion.x_root = message->pointer.root_x;
event->motion.y_root = message->pointer.root_y;
event->motion.state = message->pointer.state;
gdk_event_set_device (event, gdk_seat_get_pointer (seat));
gdk_event_set_seat (event, seat);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
}
break;
case BROADWAY_EVENT_BUTTON_PRESS:
case BROADWAY_EVENT_BUTTON_RELEASE:
if (message->base.type != 'b' &&
_gdk_broadway_moveresize_handle_event (display, message))
_gdk_broadway_moveresize_handle_event (display, message))
break;
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_window_id));
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_surface_id));
if (window)
{
event = gdk_event_new (message->base.type == 'b' ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
event->button.window = g_object_ref (window);
event->button.time = message->base.time;
event->button.x = message->pointer.win_x;
event->button.y = message->pointer.win_y;
event->button.x_root = message->pointer.root_x;
event->button.y_root = message->pointer.root_y;
event->button.button = message->button.button;
event->button.state = message->pointer.state;
gdk_event_set_device (event, device_manager->core_pointer);
gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer));
event = gdk_event_new (message->base.type == 'b' ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
event->button.window = g_object_ref (window);
event->button.time = message->base.time;
event->button.x = message->pointer.win_x;
event->button.y = message->pointer.win_y;
event->button.x_root = message->pointer.root_x;
event->button.y_root = message->pointer.root_y;
event->button.button = message->button.button;
event->button.state = message->pointer.state;
gdk_event_set_device (event, gdk_seat_get_pointer (seat));
gdk_event_set_seat (event, seat);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
}
break;
case BROADWAY_EVENT_SCROLL:
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_window_id));
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_surface_id));
if (window)
{
event = gdk_event_new (GDK_SCROLL);
event->scroll.window = g_object_ref (window);
event->scroll.time = message->base.time;
event->scroll.x = message->pointer.win_x;
event->scroll.y = message->pointer.win_y;
event->scroll.x_root = message->pointer.root_x;
event->scroll.y_root = message->pointer.root_y;
event->scroll.direction = message->scroll.dir == 0 ? GDK_SCROLL_UP : GDK_SCROLL_DOWN;
gdk_event_set_device (event, device_manager->core_pointer);
gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer));
event = gdk_event_new (GDK_SCROLL);
event->scroll.window = g_object_ref (window);
event->scroll.time = message->base.time;
event->scroll.x = message->pointer.win_x;
event->scroll.y = message->pointer.win_y;
event->scroll.x_root = message->pointer.root_x;
event->scroll.y_root = message->pointer.root_y;
event->scroll.direction = message->scroll.dir == 0 ? GDK_SCROLL_UP : GDK_SCROLL_DOWN;
gdk_event_set_device (event, gdk_seat_get_pointer (seat));
gdk_event_set_seat (event, seat);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
}
break;
case BROADWAY_EVENT_TOUCH:
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->touch.event_window_id));
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->touch.event_surface_id));
if (window)
{
GdkEventType event_type = 0;
@@ -256,20 +255,26 @@ _gdk_broadway_events_got_input (BroadwayInputMsg *message)
message->touch.is_emulated && _gdk_broadway_moveresize_handle_event (display, message))
break;
event = gdk_event_new (event_type);
event->touch.window = g_object_ref (window);
event->touch.sequence = GUINT_TO_POINTER(message->touch.sequence_id);
event->touch.emulating_pointer = message->touch.is_emulated;
event->touch.time = message->base.time;
event->touch.x = message->touch.win_x;
event->touch.y = message->touch.win_y;
event->touch.x_root = message->touch.root_x;
event->touch.y_root = message->touch.root_y;
event->touch.state = message->touch.state;
event = gdk_event_new (event_type);
event->touch.window = g_object_ref (window);
event->touch.sequence = GUINT_TO_POINTER(message->touch.sequence_id);
event->touch.emulating_pointer = message->touch.is_emulated;
event->touch.time = message->base.time;
event->touch.x = message->touch.win_x;
event->touch.y = message->touch.win_y;
event->touch.x_root = message->touch.root_x;
event->touch.y_root = message->touch.root_y;
event->touch.state = message->touch.state;
gdk_event_set_device (event, device_manager->core_pointer);
gdk_event_set_source_device (event, device_manager->touchscreen);
gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer));
gdk_event_set_device (event, gdk_seat_get_pointer (seat));
{
GList *devices;
devices = gdk_seat_get_slaves (seat, GDK_SEAT_CAPABILITY_TOUCH);
if (devices)
gdk_event_set_source_device (event, GDK_DEVICE (devices->data));
g_list_free (devices);
}
gdk_event_set_seat (event, seat);
if (message->touch.is_emulated)
gdk_event_set_pointer_emulated (event, TRUE);
@@ -277,75 +282,69 @@ _gdk_broadway_events_got_input (BroadwayInputMsg *message)
if (event_type == GDK_TOUCH_BEGIN || event_type == GDK_TOUCH_UPDATE)
event->touch.state |= GDK_BUTTON1_MASK;
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
}
break;
case BROADWAY_EVENT_KEY_PRESS:
case BROADWAY_EVENT_KEY_RELEASE:
window = g_hash_table_lookup (display_broadway->id_ht,
GINT_TO_POINTER (message->key.window_id));
GINT_TO_POINTER (message->key.surface_id));
if (window)
{
event = gdk_event_new (message->base.type == 'k' ? GDK_KEY_PRESS : GDK_KEY_RELEASE);
event->key.window = g_object_ref (window);
event->key.time = message->base.time;
event->key.keyval = message->key.key;
event->key.state = message->key.state;
event->key.hardware_keycode = message->key.key;
event = gdk_event_new (message->base.type == 'k' ? GDK_KEY_PRESS : GDK_KEY_RELEASE);
event->key.window = g_object_ref (window);
event->key.time = message->base.time;
event->key.keyval = message->key.key;
event->key.state = message->key.state;
event->key.hardware_keycode = message->key.key;
gdk_event_set_scancode (event, message->key.key);
event->key.length = 0;
gdk_event_set_device (event, device_manager->core_keyboard);
gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_keyboard));
event->key.length = 0;
gdk_event_set_device (event, gdk_seat_get_keyboard (seat));
gdk_event_set_seat (event, seat);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
}
break;
case BROADWAY_EVENT_GRAB_NOTIFY:
case BROADWAY_EVENT_UNGRAB_NOTIFY:
_gdk_display_device_grab_update (display, device_manager->core_pointer, device_manager->core_pointer, message->base.serial);
_gdk_display_device_grab_update (display, gdk_seat_get_pointer (seat), gdk_seat_get_pointer (seat), message->base.serial);
break;
case BROADWAY_EVENT_CONFIGURE_NOTIFY:
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->configure_notify.id));
if (window)
{
window->x = message->configure_notify.x;
window->y = message->configure_notify.y;
window->x = message->configure_notify.x;
window->y = message->configure_notify.y;
event = gdk_event_new (GDK_CONFIGURE);
event->configure.window = g_object_ref (window);
event->configure.x = message->configure_notify.x;
event->configure.y = message->configure_notify.y;
event->configure.width = message->configure_notify.width;
event->configure.height = message->configure_notify.height;
event = gdk_event_new (GDK_CONFIGURE);
event->configure.window = g_object_ref (window);
event->configure.x = message->configure_notify.x;
event->configure.y = message->configure_notify.y;
event->configure.width = message->configure_notify.width;
event->configure.height = message->configure_notify.height;
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
if (window->resize_count >= 1)
{
window->resize_count -= 1;
if (window->resize_count >= 1)
{
window->resize_count -= 1;
if (window->resize_count == 0)
_gdk_broadway_moveresize_configure_done (display, window);
}
if (window->resize_count == 0)
_gdk_broadway_moveresize_configure_done (display, window);
}
}
break;
case BROADWAY_EVENT_DELETE_NOTIFY:
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->delete_notify.id));
case BROADWAY_EVENT_ROUNDTRIP_NOTIFY:
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->roundtrip_notify.id));
if (window)
{
event = gdk_event_new (GDK_DELETE);
event->any.window = g_object_ref (window);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
}
_gdk_broadway_roundtrip_notify (window, message->roundtrip_notify.tag, message->roundtrip_notify.local);
break;
case BROADWAY_EVENT_SCREEN_SIZE_CHANGED:
@@ -356,24 +355,24 @@ _gdk_broadway_events_got_input (BroadwayInputMsg *message)
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->focus.old_id));
if (window)
{
event = gdk_event_new (GDK_FOCUS_CHANGE);
event->focus_change.window = g_object_ref (window);
event->focus_change.in = FALSE;
gdk_event_set_device (event, device_manager->core_pointer);
gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer));
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
event = gdk_event_new (GDK_FOCUS_CHANGE);
event->focus_change.window = g_object_ref (window);
event->focus_change.in = FALSE;
gdk_event_set_device (event, gdk_seat_get_pointer (seat));
gdk_event_set_seat (event, seat);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
}
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->focus.new_id));
if (window)
{
event = gdk_event_new (GDK_FOCUS_CHANGE);
event->focus_change.window = g_object_ref (window);
event->focus_change.in = TRUE;
gdk_event_set_device (event, device_manager->core_pointer);
gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer));
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
event = gdk_event_new (GDK_FOCUS_CHANGE);
event->focus_change.window = g_object_ref (window);
event->focus_change.in = TRUE;
gdk_event_set_device (event, gdk_seat_get_pointer (seat));
gdk_event_set_seat (event, seat);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
}
break;
@@ -429,7 +428,7 @@ _gdk_broadway_event_source_new (GdkDisplay *display)
source = g_source_new (&event_funcs, sizeof (GdkEventSource));
name = g_strdup_printf ("GDK Broadway Event source (%s)",
gdk_display_get_name (display));
gdk_display_get_name (display));
g_source_set_name (source, name);
g_free (name);
event_source = (GdkEventSource *) source;

View File

@@ -30,7 +30,6 @@
#define __GDK_PRIVATE_BROADWAY_H__
#include <gdk/gdkcursor.h>
#include <gdk/gdkprivate.h>
#include <gdk/gdkinternals.h>
#include "gdkwindow-broadway.h"
#include "gdkdisplay-broadway.h"
@@ -40,12 +39,20 @@
void _gdk_broadway_resync_windows (void);
guint32 gdk_broadway_display_ensure_texture (GdkDisplay *display,
GdkTexture *texture);
void gdk_broadway_window_set_nodes (GdkWindow *window,
GArray *nodes,
GPtrArray *node_textures);
void _gdk_broadway_window_register_dnd (GdkWindow *window);
GdkDragContext * _gdk_broadway_window_drag_begin (GdkWindow *window,
GdkDevice *device,
GList *targets,
gint x_root,
gint y_root);
GdkDragContext * _gdk_broadway_window_drag_begin (GdkWindow *window,
GdkDevice *device,
GdkContentFormats *formats,
GdkDragAction actions,
gint dx,
gint dy);
void _gdk_broadway_window_translate (GdkWindow *window,
cairo_region_t *area,
gint dx,
@@ -73,8 +80,9 @@ gboolean _gdk_broadway_moveresize_handle_event (GdkDisplay *display,
BroadwayInputMsg *msg);
gboolean _gdk_broadway_moveresize_configure_done (GdkDisplay *display,
GdkWindow *window);
void _gdk_broadway_roundtrip_notify (GdkWindow *window,
guint32 tag,
gboolean local_reply);
void _gdk_broadway_selection_window_destroyed (GdkWindow *window);
void _gdk_broadway_window_grab_check_destroy (GdkWindow *window);
void _gdk_broadway_window_grab_check_unmap (GdkWindow *window,
@@ -97,8 +105,6 @@ void _gdk_broadway_display_init_root_window (GdkDisplay *display);
void _gdk_broadway_display_init_dnd (GdkDisplay *display);
GdkDisplay * _gdk_broadway_display_open (const gchar *display_name);
void _gdk_broadway_display_queue_events (GdkDisplay *display);
GdkDragProtocol _gdk_broadway_window_get_drag_protocol (GdkWindow *window,
GdkWindow **target);
GdkCursor*_gdk_broadway_display_get_cursor_for_name (GdkDisplay *display,
const gchar *name);
GdkCursor *_gdk_broadway_display_get_cursor_for_texture (GdkDisplay *display,
@@ -130,6 +136,13 @@ gint _gdk_broadway_display_get_selection_property (GdkDisplay *display,
guchar **data,
GdkAtom *ret_type,
gint *ret_format);
void gdk_broadway_display_clear_selection_targets (GdkDisplay *display,
GdkAtom selection);
void gdk_broadway_display_add_selection_targets (GdkDisplay *display,
GdkWindow *window,
GdkAtom selection,
GdkAtom *targets,
guint ntargets);
void _gdk_broadway_display_send_selection_notify (GdkDisplay *display,
GdkWindow *requestor,
GdkAtom selection,

View File

@@ -26,8 +26,6 @@
#include "gdkproperty.h"
#include "gdkmain.h"
#include "gdkprivate.h"
#include "gdkinternals.h"
#include "gdkdisplay-broadway.h"
#include "gdkprivate-broadway.h"

View File

@@ -27,7 +27,6 @@
#include "gdkselection.h"
#include "gdkproperty.h"
#include "gdkprivate.h"
#include "gdkprivate-broadway.h"
#include "gdkdisplay-broadway.h"
@@ -147,7 +146,7 @@ _gdk_broadway_display_get_selection_property (GdkDisplay *display,
gint *ret_format)
{
if (ret_type)
*ret_type = GDK_NONE;
*ret_type = NULL;
if (ret_format)
*ret_format = 0;
if (data)
@@ -158,6 +157,21 @@ _gdk_broadway_display_get_selection_property (GdkDisplay *display,
return 0;
}
void
gdk_broadway_display_clear_selection_targets (GdkDisplay *display,
GdkAtom selection)
{
}
void
gdk_broadway_display_add_selection_targets (GdkDisplay *display,
GdkWindow *window,
GdkAtom selection,
GdkAtom *targets,
guint ntargets)
{
}
void
_gdk_broadway_display_send_selection_notify (GdkDisplay *display,
GdkWindow *requestor,

File diff suppressed because it is too large Load Diff

View File

@@ -48,10 +48,6 @@ struct _GdkWindowImplBroadway
GdkWindow *wrapper;
cairo_surface_t *surface;
cairo_surface_t *last_surface;
cairo_surface_t *ref_surface;
GdkCursor *cursor;
int id;
@@ -71,6 +67,9 @@ struct _GdkWindowImplBroadway
GdkGeometry geometry_hints;
GdkWindowHints geometry_hints_mask;
GArray *node_data;
GPtrArray *node_data_textures;
};
struct _GdkWindowImplBroadwayClass

View File

@@ -1,12 +1,10 @@
gdk_broadway_sources = files([
'broadway-buffer.c',
'broadway-output.c',
'broadway-server.c',
'broadwayd.c',
'gdkbroadway-server.c',
'gdkcursor-broadway.c',
'gdkdevice-broadway.c',
'gdkdevicemanager-broadway.c',
'gdkdisplay-broadway.c',
'gdkdnd-broadway.c',
'gdkeventsource.c',
@@ -31,7 +29,14 @@ gdk_broadway_public_headers = [
gdk_broadway_deps = [shmlib]
clienthtml_h = custom_target('clienthtml.h',
input : 'client.html',
output : 'clienthtml.h',
command : [find_program('toarray.pl'), 'client_html', '@INPUT@'],
capture : true)
libgdk_broadway = static_library('gdk-broadway',
clienthtml_h,
gdk_broadway_sources, gdkconfig, gdkenum_h,
include_directories: [confinc, gdkinc],
c_args: [
@@ -45,21 +50,15 @@ libgdk_broadway = static_library('gdk-broadway',
broadwayd_syslib = os_win32 ? find_library('ws2_32') : shmlib
clienthtml_h = custom_target('clienthtml.h',
input : 'client.html',
output : 'clienthtml.h',
command : [find_program('toarray.pl'), 'client_html', '@INPUT@'],
capture : true)
broadwayjs_h = custom_target('broadwayjs.h',
input : ['broadway.js', 'rawinflate.min.js'],
input : ['broadway.js'],
output : 'broadwayjs.h',
command : [find_program('toarray.pl'), 'broadway_js', '@INPUT0@', '@INPUT1@'],
command : [find_program('toarray.pl'), 'broadway_js', '@INPUT0@'],
capture : true)
executable('gtk4-broadwayd',
clienthtml_h, broadwayjs_h,
'broadwayd.c', 'broadway-server.c', 'broadway-buffer.c', 'broadway-output.c',
'broadwayd.c', 'broadway-server.c', 'broadway-output.c',
include_directories: [confinc, gdkinc],
c_args: ['-DGDK_COMPILATION', '-DG_LOG_DOMAIN="Gdk"', ],
dependencies : [broadwayd_syslib, gdk_deps],

View File

@@ -1,15 +0,0 @@
/** @license zlib.js 2012 - imaya [ https://github.com/imaya/zlib.js ] The MIT License */(function() {'use strict';var l=void 0,p=this;function q(c,d){var a=c.split("."),b=p;!(a[0]in b)&&b.execScript&&b.execScript("var "+a[0]);for(var e;a.length&&(e=a.shift());)!a.length&&d!==l?b[e]=d:b=b[e]?b[e]:b[e]={}};var r="undefined"!==typeof Uint8Array&&"undefined"!==typeof Uint16Array&&"undefined"!==typeof Uint32Array;function u(c){var d=c.length,a=0,b=Number.POSITIVE_INFINITY,e,f,g,h,k,m,s,n,t;for(n=0;n<d;++n)c[n]>a&&(a=c[n]),c[n]<b&&(b=c[n]);e=1<<a;f=new (r?Uint32Array:Array)(e);g=1;h=0;for(k=2;g<=a;){for(n=0;n<d;++n)if(c[n]===g){m=0;s=h;for(t=0;t<g;++t)m=m<<1|s&1,s>>=1;for(t=m;t<e;t+=k)f[t]=g<<16|n;++h}++g;h<<=1;k<<=1}return[f,a,b]};function v(c,d){this.g=[];this.h=32768;this.c=this.f=this.d=this.k=0;this.input=r?new Uint8Array(c):c;this.l=!1;this.i=w;this.p=!1;if(d||!(d={}))d.index&&(this.d=d.index),d.bufferSize&&(this.h=d.bufferSize),d.bufferType&&(this.i=d.bufferType),d.resize&&(this.p=d.resize);switch(this.i){case x:this.a=32768;this.b=new (r?Uint8Array:Array)(32768+this.h+258);break;case w:this.a=0;this.b=new (r?Uint8Array:Array)(this.h);this.e=this.u;this.m=this.r;this.j=this.s;break;default:throw Error("invalid inflate mode");
}}var x=0,w=1;
v.prototype.t=function(){for(;!this.l;){var c=y(this,3);c&1&&(this.l=!0);c>>>=1;switch(c){case 0:var d=this.input,a=this.d,b=this.b,e=this.a,f=l,g=l,h=l,k=b.length,m=l;this.c=this.f=0;f=d[a++];if(f===l)throw Error("invalid uncompressed block header: LEN (first byte)");g=f;f=d[a++];if(f===l)throw Error("invalid uncompressed block header: LEN (second byte)");g|=f<<8;f=d[a++];if(f===l)throw Error("invalid uncompressed block header: NLEN (first byte)");h=f;f=d[a++];if(f===l)throw Error("invalid uncompressed block header: NLEN (second byte)");h|=
f<<8;if(g===~h)throw Error("invalid uncompressed block header: length verify");if(a+g>d.length)throw Error("input buffer is broken");switch(this.i){case x:for(;e+g>b.length;){m=k-e;g-=m;if(r)b.set(d.subarray(a,a+m),e),e+=m,a+=m;else for(;m--;)b[e++]=d[a++];this.a=e;b=this.e();e=this.a}break;case w:for(;e+g>b.length;)b=this.e({o:2});break;default:throw Error("invalid inflate mode");}if(r)b.set(d.subarray(a,a+g),e),e+=g,a+=g;else for(;g--;)b[e++]=d[a++];this.d=a;this.a=e;this.b=b;break;case 1:this.j(z,
A);break;case 2:B(this);break;default:throw Error("unknown BTYPE: "+c);}}return this.m()};
var C=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],D=r?new Uint16Array(C):C,E=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,258,258],F=r?new Uint16Array(E):E,G=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0],H=r?new Uint8Array(G):G,I=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],J=r?new Uint16Array(I):I,K=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,
13],L=r?new Uint8Array(K):K,M=new (r?Uint8Array:Array)(288),N,O;N=0;for(O=M.length;N<O;++N)M[N]=143>=N?8:255>=N?9:279>=N?7:8;var z=u(M),P=new (r?Uint8Array:Array)(30),Q,R;Q=0;for(R=P.length;Q<R;++Q)P[Q]=5;var A=u(P);function y(c,d){for(var a=c.f,b=c.c,e=c.input,f=c.d,g;b<d;){g=e[f++];if(g===l)throw Error("input buffer is broken");a|=g<<b;b+=8}g=a&(1<<d)-1;c.f=a>>>d;c.c=b-d;c.d=f;return g}
function S(c,d){for(var a=c.f,b=c.c,e=c.input,f=c.d,g=d[0],h=d[1],k,m,s;b<h;){k=e[f++];if(k===l)break;a|=k<<b;b+=8}m=g[a&(1<<h)-1];s=m>>>16;c.f=a>>s;c.c=b-s;c.d=f;return m&65535}
function B(c){function d(a,c,b){var d,f,e,g;for(g=0;g<a;)switch(d=S(this,c),d){case 16:for(e=3+y(this,2);e--;)b[g++]=f;break;case 17:for(e=3+y(this,3);e--;)b[g++]=0;f=0;break;case 18:for(e=11+y(this,7);e--;)b[g++]=0;f=0;break;default:f=b[g++]=d}return b}var a=y(c,5)+257,b=y(c,5)+1,e=y(c,4)+4,f=new (r?Uint8Array:Array)(D.length),g,h,k,m;for(m=0;m<e;++m)f[D[m]]=y(c,3);g=u(f);h=new (r?Uint8Array:Array)(a);k=new (r?Uint8Array:Array)(b);c.j(u(d.call(c,a,g,h)),u(d.call(c,b,g,k)))}
v.prototype.j=function(c,d){var a=this.b,b=this.a;this.n=c;for(var e=a.length-258,f,g,h,k;256!==(f=S(this,c));)if(256>f)b>=e&&(this.a=b,a=this.e(),b=this.a),a[b++]=f;else{g=f-257;k=F[g];0<H[g]&&(k+=y(this,H[g]));f=S(this,d);h=J[f];0<L[f]&&(h+=y(this,L[f]));b>=e&&(this.a=b,a=this.e(),b=this.a);for(;k--;)a[b]=a[b++-h]}for(;8<=this.c;)this.c-=8,this.d--;this.a=b};
v.prototype.s=function(c,d){var a=this.b,b=this.a;this.n=c;for(var e=a.length,f,g,h,k;256!==(f=S(this,c));)if(256>f)b>=e&&(a=this.e(),e=a.length),a[b++]=f;else{g=f-257;k=F[g];0<H[g]&&(k+=y(this,H[g]));f=S(this,d);h=J[f];0<L[f]&&(h+=y(this,L[f]));b+k>e&&(a=this.e(),e=a.length);for(;k--;)a[b]=a[b++-h]}for(;8<=this.c;)this.c-=8,this.d--;this.a=b};
v.prototype.e=function(){var c=new (r?Uint8Array:Array)(this.a-32768),d=this.a-32768,a,b,e=this.b;if(r)c.set(e.subarray(32768,c.length));else{a=0;for(b=c.length;a<b;++a)c[a]=e[a+32768]}this.g.push(c);this.k+=c.length;if(r)e.set(e.subarray(d,d+32768));else for(a=0;32768>a;++a)e[a]=e[d+a];this.a=32768;return e};
v.prototype.u=function(c){var d,a=this.input.length/this.d+1|0,b,e,f,g=this.input,h=this.b;c&&("number"===typeof c.o&&(a=c.o),"number"===typeof c.q&&(a+=c.q));2>a?(b=(g.length-this.d)/this.n[2],f=258*(b/2)|0,e=f<h.length?h.length+f:h.length<<1):e=h.length*a;r?(d=new Uint8Array(e),d.set(h)):d=h;return this.b=d};
v.prototype.m=function(){var c=0,d=this.b,a=this.g,b,e=new (r?Uint8Array:Array)(this.k+(this.a-32768)),f,g,h,k;if(0===a.length)return r?this.b.subarray(32768,this.a):this.b.slice(32768,this.a);f=0;for(g=a.length;f<g;++f){b=a[f];h=0;for(k=b.length;h<k;++h)e[c++]=b[h]}f=32768;for(g=this.a;f<g;++f)e[c++]=d[f];this.g=[];return this.buffer=e};
v.prototype.r=function(){var c,d=this.a;r?this.p?(c=new Uint8Array(d),c.set(this.b.subarray(0,d))):c=this.b.subarray(0,d):(this.b.length>d&&(this.b.length=d),c=this.b);return this.buffer=c};q("Zlib.RawInflate",v);q("Zlib.RawInflate.prototype.decompress",v.prototype.t);var T={ADAPTIVE:w,BLOCK:x},U,V,W,X;if(Object.keys)U=Object.keys(T);else for(V in U=[],W=0,T)U[W++]=V;W=0;for(X=U.length;W<X;++W)V=U[W],q("Zlib.RawInflate.BufferType."+V,T[V]);}).call(this); //@ sourceMappingURL=rawinflate.min.js.map

View File

@@ -24,15 +24,17 @@
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkAppLaunchContext, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkCursor, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDevice, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDeviceManager, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDisplay, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDisplayManager, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDragContext, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkFrameClock, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkGLContext, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkKeymap, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkMonitor, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkSeat, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkWindow, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkContentFormats, gdk_content_formats_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkEvent, gdk_event_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkFrameTimings, gdk_frame_timings_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkRGBA, gdk_rgba_free)

View File

@@ -4,6 +4,8 @@
#include <gdk/gdk.h>
#include "gdk/gdkinternals.h"
/* Private API for use in GTK+ */
GdkDisplay * gdk_display_open_default (void);
gboolean gdk_device_grab_info (GdkDisplay *display,
@@ -37,4 +39,14 @@ void gdk_window_move_to_rect (GdkWindow *window,
GObject * gdk_event_get_user_data (const GdkEvent *event);
guint32 gdk_display_get_last_seen_time (GdkDisplay *display);
void gdk_display_set_double_click_time (GdkDisplay *display,
guint msec);
void gdk_display_set_double_click_distance (GdkDisplay *display,
guint distance);
void gdk_display_set_cursor_theme (GdkDisplay *display,
const char *theme,
int size);
#endif /* __GDK__PRIVATE_H__ */

View File

@@ -25,7 +25,6 @@
#include "config.h"
#include "gdkversionmacros.h"
#include "gdkmain.h"
#include "gdkinternals.h"
#include "gdkintl.h"
@@ -131,9 +130,6 @@ static int gdk_initialized = 0; /* 1 if the library is initi
* 0 otherwise.
*/
static gchar *gdk_progclass = NULL;
static gboolean gdk_progclass_overridden;
static GMutex gdk_threads_mutex;
static GCallback gdk_threads_lock = NULL;
@@ -170,7 +166,9 @@ static const GDebugKey gdk_debug_keys[] = {
{ "frames", GDK_DEBUG_FRAMES },
{ "settings", GDK_DEBUG_SETTINGS },
{ "opengl", GDK_DEBUG_OPENGL },
{ "vulkan", GDK_DEBUG_VULKAN }
{ "vulkan", GDK_DEBUG_VULKAN },
{ "selection", GDK_DEBUG_SELECTION },
{ "clipboard", GDK_DEBUG_CLIPBOARD }
};
#endif
@@ -200,13 +198,6 @@ gdk_pre_parse (void)
gdk_ensure_resources ();
/* We set the fallback program class here, rather than lazily in
* gdk_get_program_class, since we don't want -name to override it.
*/
gdk_progclass = g_strdup (g_get_prgname ());
if (gdk_progclass && gdk_progclass[0])
gdk_progclass[0] = g_ascii_toupper (gdk_progclass[0]);
#ifdef G_ENABLE_DEBUG
{
gchar *debug_string = getenv("GDK_DEBUG");
@@ -710,67 +701,3 @@ gdk_threads_add_timeout_seconds (guint interval,
return gdk_threads_add_timeout_seconds_full (G_PRIORITY_DEFAULT,
interval, function, data, NULL);
}
/**
* gdk_get_program_class:
*
* Gets the program class. Unless the program class has explicitly
* been set with gdk_set_program_class() or with the `--class`
* commandline option, the default value is the program name (determined
* with g_get_prgname()) with the first character converted to uppercase.
*
* Returns: the program class.
*/
const char *
gdk_get_program_class (void)
{
if (gdk_progclass)
return gdk_progclass;
return "GTK+ Application";
}
/**
* gdk_set_program_class:
* @program_class: a string.
*
* Sets the program class. The X11 backend uses the program class to set
* the class name part of the `WM_CLASS` property on
* toplevel windows; see the ICCCM.
*
* The program class can still be overridden with the --class command
* line option.
*/
void
gdk_set_program_class (const char *program_class)
{
if (gdk_progclass_overridden)
return;
g_free (gdk_progclass);
gdk_progclass = g_strdup (program_class);
}
/**
* gdk_disable_multidevice:
*
* Disables multidevice support in GDK. This call must happen prior
* to gdk_display_open(), gtk_init() or
* gtk_init_check() in order to take effect.
*
* Most common GTK+ applications wont ever need to call this. Only
* applications that do mixed GDK/Xlib calls could want to disable
* multidevice support if such Xlib code deals with input devices in
* any way and doesnt observe the presence of XInput 2.
*
* Since: 3.0
*/
void
gdk_disable_multidevice (void)
{
if (gdk_initialized)
return;
_gdk_disable_multidevice = TRUE;
}

View File

@@ -31,11 +31,16 @@
#include <gdk/gdkversionmacros.h>
#include <gdk/gdkapplaunchcontext.h>
#include <gdk/gdkcairo.h>
#include <gdk/gdkclipboard.h>
#include <gdk/gdkcontentdeserializer.h>
#include <gdk/gdkcontentformats.h>
#include <gdk/gdkcontentprovider.h>
#include <gdk/gdkcontentproviderimpl.h>
#include <gdk/gdkcontentserializer.h>
#include <gdk/gdkcursor.h>
#include <gdk/gdkdevice.h>
#include <gdk/gdkdevicepad.h>
#include <gdk/gdkdevicetool.h>
#include <gdk/gdkdevicemanager.h>
#include <gdk/gdkdisplay.h>
#include <gdk/gdkdisplaymanager.h>
#include <gdk/gdkdnd.h>
@@ -48,7 +53,6 @@
#include <gdk/gdkglcontext.h>
#include <gdk/gdkkeys.h>
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkmain.h>
#include <gdk/gdkmonitor.h>
#include <gdk/gdkpango.h>
#include <gdk/gdkpixbuf.h>

View File

@@ -21,7 +21,7 @@
#include "config.h"
#include "gdkapplaunchcontextprivate.h"
#include "gdkscreen.h"
#include "gdkdisplay.h"
#include "gdkintl.h"

View File

@@ -25,7 +25,6 @@
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gio/gio.h>
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>

View File

@@ -18,7 +18,6 @@
#ifndef __GDK_APP_LAUNCH_CONTEXT_PRIVATE_H__
#define __GDK_APP_LAUNCH_CONTEXT_PRIVATE_H__
#include <gio/gio.h>
#include "gdkapplaunchcontext.h"
#include "gdktypes.h"

1350
gdk/gdkclipboard.c Normal file

File diff suppressed because it is too large Load Diff

125
gdk/gdkclipboard.h Normal file
View File

@@ -0,0 +1,125 @@
/* GDK - The GIMP Drawing Kit
*
* Copyright (C) 2017 Benjamin Otte <otte@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GDK_CLIPBOARD_H__
#define __GDK_CLIPBOARD_H__
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
#include <gio/gio.h>
G_BEGIN_DECLS
#define GDK_TYPE_CLIPBOARD (gdk_clipboard_get_type ())
#define GDK_CLIPBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_CLIPBOARD, GdkClipboard))
#define GDK_IS_CLIPBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_CLIPBOARD))
GDK_AVAILABLE_IN_3_94
GType gdk_clipboard_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_3_94
GdkDisplay * gdk_clipboard_get_display (GdkClipboard *clipboard);
GDK_AVAILABLE_IN_3_94
GdkContentFormats * gdk_clipboard_get_formats (GdkClipboard *clipboard);
GDK_AVAILABLE_IN_3_94
gboolean gdk_clipboard_is_local (GdkClipboard *clipboard);
GDK_AVAILABLE_IN_3_94
GdkContentProvider * gdk_clipboard_get_content (GdkClipboard *clipboard);
GDK_AVAILABLE_IN_3_94
void gdk_clipboard_store_async (GdkClipboard *clipboard,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GDK_AVAILABLE_IN_3_94
gboolean gdk_clipboard_store_finish (GdkClipboard *clipboard,
GAsyncResult *result,
GError **error);
GDK_AVAILABLE_IN_3_94
void gdk_clipboard_read_async (GdkClipboard *clipboard,
const char **mime_types,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GDK_AVAILABLE_IN_3_94
GInputStream * gdk_clipboard_read_finish (GdkClipboard *clipboard,
const char **out_mime_type,
GAsyncResult *result,
GError **error);
GDK_AVAILABLE_IN_3_94
void gdk_clipboard_read_value_async (GdkClipboard *clipboard,
GType type,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GDK_AVAILABLE_IN_3_94
const GValue * gdk_clipboard_read_value_finish (GdkClipboard *clipboard,
GAsyncResult *result,
GError **error);
GDK_AVAILABLE_IN_3_94
void gdk_clipboard_read_texture_async(GdkClipboard *clipboard,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GDK_AVAILABLE_IN_3_94
GdkTexture * gdk_clipboard_read_texture_finish (GdkClipboard *clipboard,
GAsyncResult *result,
GError **error);
GDK_AVAILABLE_IN_3_94
void gdk_clipboard_read_text_async (GdkClipboard *clipboard,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GDK_AVAILABLE_IN_3_94
char * gdk_clipboard_read_text_finish (GdkClipboard *clipboard,
GAsyncResult *result,
GError **error);
GDK_AVAILABLE_IN_3_94
gboolean gdk_clipboard_set_content (GdkClipboard *clipboard,
GdkContentProvider *provider);
GDK_AVAILABLE_IN_3_94
void gdk_clipboard_set (GdkClipboard *clipboard,
GType type,
...);
GDK_AVAILABLE_IN_3_94
void gdk_clipboard_set_valist (GdkClipboard *clipboard,
GType type,
va_list args);
GDK_AVAILABLE_IN_3_94
void gdk_clipboard_set_value (GdkClipboard *clipboard,
const GValue *value);
GDK_AVAILABLE_IN_3_94
void gdk_clipboard_set_text (GdkClipboard *clipboard,
const char *text);
GDK_AVAILABLE_IN_3_94
void gdk_clipboard_set_texture (GdkClipboard *clipboard,
GdkTexture *texture);
G_END_DECLS
#endif /* __GDK_CLIPBOARD_H__ */

85
gdk/gdkclipboardprivate.h Normal file
View File

@@ -0,0 +1,85 @@
/*
* Copyright (C) 2017 Benjamin Otte <otte@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GDK_CLIPBOARD_PRIVATE_H__
#define __GDK_CLIPBOARD_PRIVATE_H__
#include <gdk/gdkclipboard.h>
G_BEGIN_DECLS
#define GDK_CLIPBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_CLIPBOARD, GdkClipboardClass))
#define GDK_IS_CLIPBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_CLIPBOARD))
#define GDK_CLIPBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_CLIPBOARD, GdkClipboardClass))
typedef struct _GdkClipboardClass GdkClipboardClass;
struct _GdkClipboard
{
GObject parent;
};
struct _GdkClipboardClass
{
GObjectClass parent_class;
/* signals */
void (* changed) (GdkClipboard *clipboard);
/* vfuncs */
gboolean (* claim) (GdkClipboard *clipboard,
GdkContentFormats *formats,
gboolean local,
GdkContentProvider *content);
void (* store_async) (GdkClipboard *clipboard,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean (* store_finish) (GdkClipboard *clipboard,
GAsyncResult *result,
GError **error);
void (* read_async) (GdkClipboard *clipboard,
GdkContentFormats *formats,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GInputStream * (* read_finish) (GdkClipboard *clipboard,
const char **out_mime_type,
GAsyncResult *result,
GError **error);
};
GdkClipboard * gdk_clipboard_new (GdkDisplay *display);
void gdk_clipboard_claim_remote (GdkClipboard *clipboard,
GdkContentFormats *formats);
void gdk_clipboard_write_async (GdkClipboard *clipboard,
const char *mime_type,
GOutputStream *stream,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean gdk_clipboard_write_finish (GdkClipboard *clipboard,
GAsyncResult *result,
GError **error);
G_END_DECLS
#endif /* __GDK_CLIPBOARD_PRIVATE_H__ */

View File

@@ -0,0 +1,709 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2017 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gio/gio.h>
#include "gdkcontentdeserializer.h"
#include "gdkcontentformats.h"
#include "gdktexture.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
/**
* SECTION:gdkcontentdeserializer
* @Short_description: Deserialize content for transfer
* @Title: GdkContentSerializer
* @See_also: #GdkContentDeserializer
*
* A GdkContentDeserializer is used to deserialize content for inter-application
* data transfers.
*/
typedef struct _Deserializer Deserializer;
struct _Deserializer
{
const char * mime_type; /* interned */
GType type;
GdkContentDeserializeFunc deserialize;
gpointer data;
GDestroyNotify notify;
};
GQueue deserializers = G_QUEUE_INIT;
static void init (void);
#define GDK_CONTENT_DESERIALIZER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_CONTENT_DESERIALIZER, GdkContentDeserializerClass))
#define GDK_IS_CONTENT_DESERIALIZER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_CONTENT_DESERIALIZER))
#define GDK_CONTENT_DESERIALIZER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_CONTENT_DESERIALIZER, GdkContentDeserializerClass))
typedef struct _GdkContentDeserializerClass GdkContentDeserializerClass;
struct _GdkContentDeserializer
{
GObject parent_instance;
const char *mime_type; /* interned */
GValue value;
GInputStream *stream;
int priority;
GCancellable *cancellable;
gpointer user_data;
GAsyncReadyCallback callback;
gpointer callback_data;
gpointer task_data;
GDestroyNotify task_notify;
GError *error;
gboolean returned;
};
struct _GdkContentDeserializerClass
{
GObjectClass parent_class;
};
static gpointer
gdk_content_deserializer_async_result_get_user_data (GAsyncResult *res)
{
return GDK_CONTENT_DESERIALIZER (res)->callback_data;
}
static GObject *
gdk_content_deserializer_async_result_get_source_object (GAsyncResult *res)
{
return NULL;
}
static void
gdk_content_deserializer_async_result_iface_init (GAsyncResultIface *iface)
{
iface->get_user_data = gdk_content_deserializer_async_result_get_user_data;
iface->get_source_object = gdk_content_deserializer_async_result_get_source_object;
}
G_DEFINE_TYPE_WITH_CODE (GdkContentDeserializer, gdk_content_deserializer, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT, gdk_content_deserializer_async_result_iface_init))
static void
gdk_content_deserializer_finalize (GObject *object)
{
GdkContentDeserializer *deserializer = GDK_CONTENT_DESERIALIZER (object);
g_value_unset (&deserializer->value);
g_clear_object (&deserializer->stream);
g_clear_object (&deserializer->cancellable);
g_clear_error (&deserializer->error);
if (deserializer->task_notify)
deserializer->task_notify (deserializer->task_data);
G_OBJECT_CLASS (gdk_content_deserializer_parent_class)->finalize (object);
}
static void
gdk_content_deserializer_class_init (GdkContentDeserializerClass *content_deserializer_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (content_deserializer_class);
object_class->finalize = gdk_content_deserializer_finalize;
}
static void
gdk_content_deserializer_init (GdkContentDeserializer *content_deserializer)
{
}
static void
gdk_content_deserializer_run (const char *mime_type,
GType type,
GInputStream *stream,
int priority,
GCancellable *cancellable,
GdkContentDeserializeFunc deserialize_func,
gpointer user_data,
GAsyncReadyCallback callback,
gpointer callback_data)
{
GdkContentDeserializer *deserializer;
deserializer = g_object_new (GDK_TYPE_CONTENT_DESERIALIZER, NULL);
deserializer->mime_type = mime_type;
g_value_init (&deserializer->value, type);
deserializer->stream = g_object_ref (stream);
deserializer->priority = priority;
if (cancellable)
deserializer->cancellable = g_object_ref (cancellable);
deserializer->user_data = user_data;
deserializer->callback = callback;
deserializer->callback_data = callback_data;
deserialize_func (deserializer);
}
const char *
gdk_content_deserializer_get_mime_type (GdkContentDeserializer *deserializer)
{
g_return_val_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer), NULL);
return deserializer->mime_type;
}
GType
gdk_content_deserializer_get_gtype (GdkContentDeserializer *deserializer)
{
g_return_val_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer), G_TYPE_INVALID);
return G_VALUE_TYPE (&deserializer->value);
}
GValue *
gdk_content_deserializer_get_value (GdkContentDeserializer *deserializer)
{
g_return_val_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer), NULL);
return &deserializer->value;
}
GInputStream *
gdk_content_deserializer_get_input_stream (GdkContentDeserializer *deserializer)
{
g_return_val_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer), NULL);
return deserializer->stream;
}
int
gdk_content_deserializer_get_priority (GdkContentDeserializer *deserializer)
{
g_return_val_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer), G_PRIORITY_DEFAULT);
return deserializer->priority;
}
GCancellable *
gdk_content_deserializer_get_cancellable (GdkContentDeserializer *deserializer)
{
g_return_val_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer), NULL);
return deserializer->cancellable;
}
gpointer
gdk_content_deserializer_get_user_data (GdkContentDeserializer *deserializer)
{
g_return_val_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer), NULL);
return deserializer->user_data;
}
void
gdk_content_deserializer_set_task_data (GdkContentDeserializer *deserializer,
gpointer data,
GDestroyNotify notify)
{
g_return_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer));
if (deserializer->task_notify)
deserializer->task_notify (deserializer->task_data);
deserializer->task_data = data;
deserializer->task_notify = notify;
}
gpointer
gdk_content_deserializer_get_task_data (GdkContentDeserializer *deserializer)
{
g_return_val_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer), NULL);
return deserializer->task_data;
}
static gboolean
gdk_content_deserializer_emit_callback (gpointer data)
{
GdkContentDeserializer *deserializer = data;
if (deserializer->callback)
{
deserializer->callback (NULL, G_ASYNC_RESULT (deserializer), deserializer->callback_data);
}
return G_SOURCE_REMOVE;
}
void
gdk_content_deserializer_return_success (GdkContentDeserializer *deserializer)
{
g_return_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer));
g_return_if_fail (!deserializer->returned);
deserializer->returned = TRUE;
g_idle_add_full (deserializer->priority,
gdk_content_deserializer_emit_callback,
deserializer,
g_object_unref);
/* NB: the idle will destroy our reference */
}
void
gdk_content_deserializer_return_error (GdkContentDeserializer *deserializer,
GError *error)
{
g_return_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer));
g_return_if_fail (!deserializer->returned);
g_return_if_fail (error != NULL);
deserializer->error = error;
/* FIXME: naming */
gdk_content_deserializer_return_success (deserializer);
}
void
gdk_content_register_deserializer (const char *mime_type,
GType type,
GdkContentDeserializeFunc deserialize,
gpointer data,
GDestroyNotify notify)
{
Deserializer *deserializer;
g_return_if_fail (mime_type != NULL);
g_return_if_fail (deserialize != NULL);
init ();
deserializer = g_slice_new0 (Deserializer);
deserializer->mime_type = g_intern_string (mime_type);
deserializer->type = type;
deserializer->deserialize = deserialize;
deserializer->data = data;
deserializer->notify = notify;
g_queue_push_tail (&deserializers, deserializer);
}
static Deserializer *
lookup_deserializer (const char *mime_type,
GType type)
{
GList *l;
g_return_val_if_fail (mime_type != NULL, NULL);
init ();
mime_type = g_intern_string (mime_type);
for (l = g_queue_peek_head_link (&deserializers); l; l = l->next)
{
Deserializer *deserializer = l->data;
if (deserializer->mime_type == mime_type &&
deserializer->type == type)
return deserializer;
}
return NULL;
}
GdkContentFormats *
gdk_content_formats_union_deserialize_gtypes (GdkContentFormats *formats)
{
GdkContentFormatsBuilder *builder;
GList *l;
g_return_val_if_fail (formats != NULL, NULL);
init ();
builder = gdk_content_formats_builder_new ();
gdk_content_formats_builder_add_formats (builder, formats);
for (l = g_queue_peek_head_link (&deserializers); l; l = l->next)
{
Deserializer *deserializer = l->data;
if (gdk_content_formats_contain_mime_type (formats, deserializer->mime_type))
gdk_content_formats_builder_add_gtype (builder, deserializer->type);
}
gdk_content_formats_unref (formats);
return gdk_content_formats_builder_free (builder);
}
GdkContentFormats *
gdk_content_formats_union_deserialize_mime_types (GdkContentFormats *formats)
{
GdkContentFormatsBuilder *builder;
GList *l;
g_return_val_if_fail (formats != NULL, NULL);
init ();
builder = gdk_content_formats_builder_new ();
gdk_content_formats_builder_add_formats (builder, formats);
for (l = g_queue_peek_head_link (&deserializers); l; l = l->next)
{
Deserializer *deserializer = l->data;
if (gdk_content_formats_contain_gtype (formats, deserializer->type))
gdk_content_formats_builder_add_mime_type (builder, deserializer->mime_type);
}
gdk_content_formats_unref (formats);
return gdk_content_formats_builder_free (builder);
}
static void
deserialize_not_found (GdkContentDeserializer *deserializer)
{
GError *error = g_error_new (G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
"Could not convert data from %s to %s",
gdk_content_deserializer_get_mime_type (deserializer),
g_type_name (gdk_content_deserializer_get_gtype (deserializer)));
gdk_content_deserializer_return_error (deserializer, error);
}
void
gdk_content_deserialize_async (GInputStream *stream,
const char *mime_type,
GType type,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
Deserializer *deserializer;
g_return_if_fail (G_IS_INPUT_STREAM (stream));
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
g_return_if_fail (callback != NULL);
deserializer = lookup_deserializer (mime_type, type);
gdk_content_deserializer_run (mime_type,
type,
stream,
io_priority,
cancellable,
deserializer ? deserializer->deserialize : deserialize_not_found,
deserializer ? deserializer->data : NULL,
callback,
user_data);
}
gboolean
gdk_content_deserialize_finish (GAsyncResult *result,
GValue *value,
GError **error)
{
GdkContentDeserializer *deserializer;
g_return_val_if_fail (GDK_IS_CONTENT_DESERIALIZER (result), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
deserializer = GDK_CONTENT_DESERIALIZER (result);
g_return_val_if_fail (G_VALUE_HOLDS (value, G_VALUE_TYPE (&deserializer->value)), FALSE);
if (deserializer->error)
{
if (error)
*error = g_error_copy (deserializer->error);
return FALSE;
}
g_value_copy (&deserializer->value, value);
return TRUE;
}
/*** DESERIALIZERS ***/
static void
pixbuf_deserializer_finish (GObject *source,
GAsyncResult *res,
gpointer deserializer)
{
GdkPixbuf *pixbuf;
GValue *value;
GError *error = NULL;
pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error);
if (pixbuf == NULL)
{
gdk_content_deserializer_return_error (deserializer, error);
return;
}
value = gdk_content_deserializer_get_value (deserializer);
if (G_VALUE_HOLDS (value, GDK_TYPE_PIXBUF))
{
g_value_take_object (value, pixbuf);
}
else if (G_VALUE_HOLDS (value, GDK_TYPE_TEXTURE))
{
GdkTexture *texture;
texture = gdk_texture_new_for_pixbuf (pixbuf);
g_object_unref (pixbuf);
g_value_take_object (value, texture);
}
else
{
g_assert_not_reached ();
}
gdk_content_deserializer_return_success (deserializer);
}
static void
pixbuf_deserializer (GdkContentDeserializer *deserializer)
{
gdk_pixbuf_new_from_stream_async (gdk_content_deserializer_get_input_stream (deserializer),
gdk_content_deserializer_get_cancellable (deserializer),
pixbuf_deserializer_finish,
deserializer);
}
static void
string_deserializer_finish (GObject *source,
GAsyncResult *result,
gpointer deserializer)
{
GOutputStream *stream = G_OUTPUT_STREAM (source);
GError *error = NULL;
gssize written;
written = g_output_stream_splice_finish (stream, result, &error);
if (written < 0)
{
gdk_content_deserializer_return_error (deserializer, error);
return;
}
else if (written == 0)
{
/* Never return NULL, we only return that on error */
g_value_set_string (gdk_content_deserializer_get_value (deserializer), "");
}
else
{
g_value_take_string (gdk_content_deserializer_get_value (deserializer),
g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (
g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (stream)))));
}
gdk_content_deserializer_return_success (deserializer);
}
static void
string_deserializer (GdkContentDeserializer *deserializer)
{
GOutputStream *output, *filter;
GCharsetConverter *converter;
GError *error = NULL;
converter = g_charset_converter_new ("utf-8",
gdk_content_deserializer_get_user_data (deserializer),
&error);
if (converter == NULL)
{
gdk_content_deserializer_return_error (deserializer, error);
return;
}
g_charset_converter_set_use_fallback (converter, TRUE);
output = g_memory_output_stream_new_resizable ();
filter = g_converter_output_stream_new (output, G_CONVERTER (converter));
g_object_unref (output);
g_object_unref (converter);
g_output_stream_splice_async (filter,
gdk_content_deserializer_get_input_stream (deserializer),
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
gdk_content_deserializer_get_priority (deserializer),
gdk_content_deserializer_get_cancellable (deserializer),
string_deserializer_finish,
deserializer);
g_object_unref (filter);
}
static void
file_uri_deserializer_finish (GObject *source,
GAsyncResult *result,
gpointer deserializer)
{
GOutputStream *stream = G_OUTPUT_STREAM (source);
GError *error = NULL;
gssize written;
GValue *value;
char *str;
char **uris;
written = g_output_stream_splice_finish (stream, result, &error);
if (written < 0)
{
gdk_content_deserializer_return_error (deserializer, error);
return;
}
/* write terminating NULL */
if (!g_output_stream_write (stream, "", 1, NULL, &error))
{
gdk_content_deserializer_return_error (deserializer, error);
return;
}
str = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (
g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (stream))));
uris = g_uri_list_extract_uris (str);
g_free (str);
value = gdk_content_deserializer_get_value (deserializer);
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
{
if (uris[0] != NULL)
g_value_take_object (value, g_file_new_for_uri (uris[0]));
}
else
{
GSList *l = NULL;
gsize i;
for (i = 0; uris[i] != NULL; i++)
l = g_slist_prepend (l, g_file_new_for_uri (uris[i]));
g_value_take_boxed (value, g_slist_reverse (l));
}
g_strfreev (uris);
}
static void
file_uri_deserializer (GdkContentDeserializer *deserializer)
{
GOutputStream *output;
output = g_memory_output_stream_new_resizable ();
g_output_stream_splice_async (output,
gdk_content_deserializer_get_input_stream (deserializer),
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
gdk_content_deserializer_get_priority (deserializer),
gdk_content_deserializer_get_cancellable (deserializer),
file_uri_deserializer_finish,
deserializer);
g_object_unref (output);
}
static void
init (void)
{
static gboolean initialized = FALSE;
GSList *formats, *f;
const char *charset;
if (initialized)
return;
initialized = TRUE;
formats = gdk_pixbuf_get_formats ();
/* Make sure png comes first */
for (f = formats; f; f = f->next)
{
GdkPixbufFormat *fmt = f->data;
gchar *name;
name = gdk_pixbuf_format_get_name (fmt);
if (g_str_equal (name, "png"))
{
formats = g_slist_delete_link (formats, f);
formats = g_slist_prepend (formats, fmt);
g_free (name);
break;
}
g_free (name);
}
for (f = formats; f; f = f->next)
{
GdkPixbufFormat *fmt = f->data;
gchar **mimes, **m;
mimes = gdk_pixbuf_format_get_mime_types (fmt);
for (m = mimes; *m; m++)
{
gdk_content_register_deserializer (*m,
GDK_TYPE_TEXTURE,
pixbuf_deserializer,
NULL,
NULL);
gdk_content_register_deserializer (*m,
GDK_TYPE_PIXBUF,
pixbuf_deserializer,
NULL,
NULL);
}
g_strfreev (mimes);
}
g_slist_free (formats);
gdk_content_register_deserializer ("text/uri-list",
GDK_TYPE_FILE_LIST,
file_uri_deserializer,
NULL,
NULL);
gdk_content_register_deserializer ("text/uri-list",
G_TYPE_FILE,
file_uri_deserializer,
NULL,
NULL);
gdk_content_register_deserializer ("text/plain;charset=utf-8",
G_TYPE_STRING,
string_deserializer,
(gpointer) "utf-8",
NULL);
if (!g_get_charset (&charset))
{
char *mime = g_strdup_printf ("text/plain;charset=%s", charset);
gdk_content_register_deserializer (mime,
G_TYPE_STRING,
string_deserializer,
mime,
g_free);
}
gdk_content_register_deserializer ("text/plain",
G_TYPE_STRING,
string_deserializer,
(gpointer) "ASCII",
NULL);
}

View File

@@ -0,0 +1,96 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2017 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_CONTENT_DESERIALIZER_H__
#define __GTK_CONTENT_DESERIALIZER_H__
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
G_BEGIN_DECLS
#define GDK_TYPE_CONTENT_DESERIALIZER (gdk_content_deserializer_get_type ())
#define GDK_CONTENT_DESERIALIZER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_CONTENT_DESERIALIZER, GdkContentDeserializer))
#define GDK_IS_CONTENT_DESERIALIZER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_CONTENT_DESERIALIZER))
typedef struct _GdkContentDeserializer GdkContentDeserializer;
typedef void (* GdkContentDeserializeFunc) (GdkContentDeserializer *deserializer);
GDK_AVAILABLE_IN_3_94
GType gdk_content_deserializer_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_3_94
const char * gdk_content_deserializer_get_mime_type (GdkContentDeserializer *deserializer);
GDK_AVAILABLE_IN_3_94
GType gdk_content_deserializer_get_gtype (GdkContentDeserializer *deserializer);
GDK_AVAILABLE_IN_3_94
GValue * gdk_content_deserializer_get_value (GdkContentDeserializer *deserializer);
GDK_AVAILABLE_IN_3_94
GInputStream * gdk_content_deserializer_get_input_stream (GdkContentDeserializer *deserializer);
GDK_AVAILABLE_IN_3_94
int gdk_content_deserializer_get_priority (GdkContentDeserializer *deserializer);
GDK_AVAILABLE_IN_3_94
GCancellable * gdk_content_deserializer_get_cancellable (GdkContentDeserializer *deserializer);
GDK_AVAILABLE_IN_3_94
gpointer gdk_content_deserializer_get_user_data (GdkContentDeserializer *deserializer);
GDK_AVAILABLE_IN_3_94
void gdk_content_deserializer_set_task_data (GdkContentDeserializer *deserializer,
gpointer data,
GDestroyNotify notify);
GDK_AVAILABLE_IN_3_94
gpointer gdk_content_deserializer_get_task_data (GdkContentDeserializer *deserializer);
GDK_AVAILABLE_IN_3_94
void gdk_content_deserializer_return_success (GdkContentDeserializer *deserializer);
GDK_AVAILABLE_IN_3_94
void gdk_content_deserializer_return_error (GdkContentDeserializer *deserializer,
GError *error);
GDK_AVAILABLE_IN_3_94
GdkContentFormats * gdk_content_formats_union_deserialize_gtypes (GdkContentFormats *formats);
GDK_AVAILABLE_IN_3_94
GdkContentFormats * gdk_content_formats_union_deserialize_mime_types(GdkContentFormats *formats);
GDK_AVAILABLE_IN_3_94
void gdk_content_register_deserializer (const char *mime_type,
GType type,
GdkContentDeserializeFunc deserialize,
gpointer data,
GDestroyNotify notify);
GDK_AVAILABLE_IN_3_94
void gdk_content_deserialize_async (GInputStream *stream,
const char *mime_type,
GType type,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GDK_AVAILABLE_IN_3_94
gboolean gdk_content_deserialize_finish (GAsyncResult *result,
GValue *value,
GError **error);
G_END_DECLS
#endif /* __GDK_CONTENT_DESERIALIZER_H__ */

660
gdk/gdkcontentformats.c Normal file
View File

@@ -0,0 +1,660 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2017 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* SECTION:gdkcontentformats
* @Title: Content Formats
* @Short_description: Advertising and negotiating of content
* exchange formats
* @See_also: #GdkDragContext, #GdkClipboard, #GdkContentProvider
*
* This section describes the #GdkContentFormats structure that is used to
* advertise and negotiate the format of content passed between different
* widgets, windows or applications using for example the clipboard or
* drag'n'drop.
*
* GDK supports content in 2 forms: #GType and mime type.
* Using #GTypes is meant only for in-process content transfers. Mime types
* are meant to be used for data passing both in-process and out-of-process.
* The details of how data is passed is described in the documentation of
* the actual implementations.
*
* A #GdkContentFormats describes a set of possible formats content can be
* exchanged in. It is assumed that this set is ordered. #GTypes are more
* important than mime types. Order between different #Gtypes or mime types
* is the order they were added in, most important first. Functions that
* care about order, such as gdk_content_formats_union() will describe in
* their documentation how they interpret that order, though in general the
* order of the first argument is considered the primary order of the result,
* followed by the order of further arguments.
*
* For debugging purposes, the function gdk_content_formats_to_string() exists.
* It will print a comma-seperated formats of formats from most important to least
* important.
*
* #GdkContentFormats is an immutable struct. After creation, you cannot change
* the types it represents. Instead, new #GdkContentFormats have to be created.
* The #GdkContentFormatsBuilder structure is meant to help in this endeavor.
*/
/**
* GdkContentFormats:
*
* A #GdkContentFormats struct is a reference counted struct
* and should be treated as opaque.
*/
#include "config.h"
#include "gdkcontentformats.h"
#include "gdkcontentformatsprivate.h"
#include <string.h>
struct _GdkContentFormats
{
/*< private >*/
guint ref_count;
const char **mime_types; /* interned */
gsize n_mime_types;
GType *gtypes;
gsize n_gtypes;
};
G_DEFINE_BOXED_TYPE (GdkContentFormats, gdk_content_formats,
gdk_content_formats_ref,
gdk_content_formats_unref)
/**
* gdk_intern_mime_type:
* @string: (transfer none): string of a potential mime type
*
* Canonicalizes the given mime type and interns the result.
*
* If @string is not a valid mime type, %NULL is returned instead.
* See RFC 2048 for the syntax if mime types.
*
* Returns: An interned string for the canonicalized mime type
* or %NULL if the string wasn't a valid mime type
**/
const char *
gdk_intern_mime_type (const char *string)
{
char *tmp;
g_return_val_if_fail (string != NULL, NULL);
if (!strchr (string, '/'))
return NULL;
tmp = g_ascii_strdown (string, -1);
string = g_intern_string (tmp);
g_free (tmp);
return string;
}
static GdkContentFormats *
gdk_content_formats_new_take (GType * gtypes,
gsize n_gtypes,
const char **mime_types,
gsize n_mime_types)
{
GdkContentFormats *result = g_slice_new0 (GdkContentFormats);
result->ref_count = 1;
result->gtypes = gtypes;
result->n_gtypes = n_gtypes;
result->mime_types = mime_types;
result->n_mime_types = n_mime_types;
return result;
}
/**
* gdk_content_formats_new:
* @mime_types: (array length=n_mime_types) (allow-none): Pointer to an
* array of mime types
* @n_mime_types: number of entries in @mime_types.
*
* Creates a new #GdkContentFormats from an array of mime types.
*
* The mime types must be valid and different from each other or the
* behavior of the return value is undefined. If you cannot guarantee
* this, use #GdkContentFormatsBuilder instead.
*
* Returns: (transfer full): the new #GdkContentFormats.
**/
GdkContentFormats *
gdk_content_formats_new (const char **mime_types,
guint n_mime_types)
{
GPtrArray *array;
guint i;
if (n_mime_types == 0)
return gdk_content_formats_new_take (NULL, 0, NULL, 0);
array = g_ptr_array_new ();
for (i = 0; i < n_mime_types; i++)
g_ptr_array_add (array, (gpointer) g_intern_string (mime_types[i]));
g_ptr_array_add (array, NULL);
return gdk_content_formats_new_take (NULL, 0, (const char **) g_ptr_array_free (array, FALSE), n_mime_types);
}
/**
* gdk_content_formats_new_for_gtype:
* @type: a $GType
*
* Creates a new #GdkContentFormats for a given #GType.
*
* Returns: a new #GdkContentFormats
**/
GdkContentFormats *
gdk_content_formats_new_for_gtype (GType type)
{
GType *data;
g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
data = g_new (GType, 2);
data[0] = type;
data[1] = G_TYPE_INVALID;
return gdk_content_formats_new_take (data, 1, NULL, 0);
}
/**
* gdk_content_formats_ref:
* @formats: a #GdkContentFormats
*
* Increases the reference count of a #GdkContentFormats by one.
*
* Returns: the passed in #GdkContentFormats.
**/
GdkContentFormats *
gdk_content_formats_ref (GdkContentFormats *formats)
{
g_return_val_if_fail (formats != NULL, NULL);
formats->ref_count++;
return formats;
}
/**
* gdk_content_formats_unref:
* @formats: a #GdkContentFormats
*
* Decreases the reference count of a #GdkContentFormats by one.
* If the resulting reference count is zero, frees the formats.
**/
void
gdk_content_formats_unref (GdkContentFormats *formats)
{
g_return_if_fail (formats != NULL);
g_return_if_fail (formats->ref_count > 0);
formats->ref_count--;
if (formats->ref_count > 0)
return;
g_free (formats->gtypes);
g_free (formats->mime_types);
g_slice_free (GdkContentFormats, formats);
}
/**
* gdk_content_formats_print:
* @formats: a #GdkContentFormats
* @string: a #GString to print into
*
* Prints the given @formats into a string for human consumption.
* This is meant for debugging and logging.
*
* The form of the representation may change at any time and is
* not guranteed to stay identical.
**/
void
gdk_content_formats_print (GdkContentFormats *formats,
GString *string)
{
gsize i;
g_return_if_fail (formats != NULL);
g_return_if_fail (string != NULL);
g_string_append (string, "{ ");
for (i = 0; i < formats->n_gtypes; i++)
{
if (i > 0)
g_string_append (string, ", ");
g_string_append (string, g_type_name (formats->gtypes[i]));
}
for (i = 0; i < formats->n_mime_types; i++)
{
if (i > 0 || formats->n_gtypes > 0)
g_string_append (string, ", ");
g_string_append (string, formats->mime_types[i]);
}
g_string_append (string, " }");
}
/**
* gdk_content_formats_to_string:
* @formats: a #GdkContentFormats
*
* Prints the given @formats into a human-readable string.
* This is a small wrapper around gdk_content_formats_print() to help
* when debugging.
*
* Returns: (transfer full): a new string
**/
char *
gdk_content_formats_to_string (GdkContentFormats *formats)
{
GString *string;
g_return_val_if_fail (formats != NULL, NULL);
string = g_string_new (NULL);
gdk_content_formats_print (formats, string);
return g_string_free (string, FALSE);
}
/**
* gdk_content_formats_union:
* @first: (transfer full): the #GdkContentFormats to merge into
* @second: (transfer none): the #GdkContentFormats to merge from
*
* Append all missing types from @second to @first, in the order
* they had in @second.
*
* Returns: a new #GdkContentFormats
*/
GdkContentFormats *
gdk_content_formats_union (GdkContentFormats *first,
const GdkContentFormats *second)
{
GdkContentFormatsBuilder *builder;
g_return_val_if_fail (first != NULL, NULL);
g_return_val_if_fail (second != NULL, NULL);
builder = gdk_content_formats_builder_new ();
gdk_content_formats_builder_add_formats (builder, first);
gdk_content_formats_unref (first);
gdk_content_formats_builder_add_formats (builder, second);
return gdk_content_formats_builder_free (builder);
}
static gboolean
gdk_content_formats_contain_interned_mime_type (const GdkContentFormats *formats,
const char *mime_type)
{
gsize i;
for (i = 0; i < formats->n_mime_types; i++)
{
if (mime_type == formats->mime_types[i])
return TRUE;
}
return FALSE;
}
/**
* gdk_content_formats_match:
* @first: the primary #GdkContentFormats to intersect
* @second: the #GdkContentFormats to intersect with
*
* Checks if @first and @second have any matching formats.
*
* Returns: %TRUE if a matching format was found.
*/
gboolean
gdk_content_formats_match (const GdkContentFormats *first,
const GdkContentFormats *second)
{
g_return_val_if_fail (first != NULL, FALSE);
g_return_val_if_fail (second != NULL, FALSE);
return gdk_content_formats_match_gtype (first, second) != G_TYPE_INVALID
|| gdk_content_formats_match_mime_type (first, second) != NULL;
}
/**
* gdk_content_formats_match_gtype:
* @first: the primary #GdkContentFormats to intersect
* @second: the #GdkContentFormats to intersect with
*
* Finds the first #GType from @first that is also contained
* in @second. If no matching #GType is found, %G_TYPE_INVALID
* is returned.
*
* Returns: The first common #GType or %G_TYPE_INVALID if none.
**/
GType
gdk_content_formats_match_gtype (const GdkContentFormats *first,
const GdkContentFormats *second)
{
gsize i;
g_return_val_if_fail (first != NULL, FALSE);
g_return_val_if_fail (second != NULL, FALSE);
for (i = 0; i < first->n_gtypes; i++)
{
if (gdk_content_formats_contain_gtype (second, first->gtypes[i]))
return first->gtypes[i];
}
return G_TYPE_INVALID;
}
/**
* gdk_content_formats_match_mime_type:
* @first: the primary #GdkContentFormats to intersect
* @second: the #GdkContentFormats to intersect with
*
* Finds the first mime type from @first that is also contained
* in @second. If no matching mime type is found, %NULL is
* returned.
*
* Returns: The first common mime type or %NULL if none.
**/
const char *
gdk_content_formats_match_mime_type (const GdkContentFormats *first,
const GdkContentFormats *second)
{
gsize i;
g_return_val_if_fail (first != NULL, FALSE);
g_return_val_if_fail (second != NULL, FALSE);
for (i = 0; i < first->n_mime_types; i++)
{
if (gdk_content_formats_contain_interned_mime_type (second, first->mime_types[i]))
return first->mime_types[i];
}
return NULL;
}
/**
* gdk_content_formats_contain_gtype:
* @formats: a #GdkContentFormats
* @type: the #GType to search for
*
* Checks if a given #GType is part of the given @formats.
*
* Returns: %TRUE if the #GType was found
**/
gboolean
gdk_content_formats_contain_gtype (const GdkContentFormats *formats,
GType type)
{
g_return_val_if_fail (formats != NULL, FALSE);
gsize i;
for (i = 0; i < formats->n_gtypes; i++)
{
if (type == formats->gtypes[i])
return TRUE;
}
return FALSE;
}
/**
* gdk_content_formats_contain_mime_type:
* @formats: a #GdkContentFormats
* @mime_type: the mime type to search for
*
* Checks if a given mime type is part of the given @formats.
*
* Returns: %TRUE if the mime_type was found
**/
gboolean
gdk_content_formats_contain_mime_type (const GdkContentFormats *formats,
const char *mime_type)
{
g_return_val_if_fail (formats != NULL, FALSE);
g_return_val_if_fail (mime_type != NULL, FALSE);
return gdk_content_formats_contain_interned_mime_type (formats,
g_intern_string (mime_type));
}
/**
* gdk_content_formats_get_gtypes:
* @formats: a #GdkContentFormats
* @n_gtypes: (out) (allow-none): optional pointer to take the
* number of #GTypes contained in the return value
*
* Gets the #GTypes included in @formats. Note that @formats may not
* contain any #GTypes, in particular when they are empty. In that
* case %NULL will be returned.
*
* Returns: (transfer none) (nullable): %G_TYPE_INVALID-terminated array of
* types included in @formats or %NULL if none.
**/
const GType *
gdk_content_formats_get_gtypes (GdkContentFormats *formats,
gsize *n_gtypes)
{
g_return_val_if_fail (formats != NULL, NULL);
if (n_gtypes)
*n_gtypes = formats->n_gtypes;
return formats->gtypes;
}
/**
* gdk_content_formats_get_mime_types:
* @formats: a #GdkContentFormats
* @n_mime_types: (out) (allow-none): optional pointer to take the
* number of mime types contained in the return value
*
* Gets the mime types included in @formats. Note that @formats may not
* contain any mime types, in particular when they are empty. In that
* case %NULL will be returned.
*
* Returns: (transfer none) (nullable): %NULL-terminated array of
* interned strings of mime types included in @formats or %NULL
* if none.
**/
const char * const *
gdk_content_formats_get_mime_types (GdkContentFormats *formats,
gsize *n_mime_types)
{
g_return_val_if_fail (formats != NULL, NULL);
if (n_mime_types)
*n_mime_types = formats->n_mime_types;
return formats->mime_types;
}
/**
* GdkContentFormatsBuilder:
*
* A #GdkContentFormatsBuilder struct is an opaque struct. It is meant to
* not be kept around and only be used to create new #GdkContentFormats
* objects.
*/
struct _GdkContentFormatsBuilder
{
GSList *gtypes;
gsize n_gtypes;
GSList *mime_types;
gsize n_mime_types;
};
/**
* gdk_content_formats_builder_new:
*
* Create a new #GdkContentFormatsBuilder object. The resulting builder
* would create an empty #GdkContentFormats. Use addition functions to add
* types to it.
*
* Returns: a new #GdkContentFormatsBuilder
**/
GdkContentFormatsBuilder *
gdk_content_formats_builder_new (void)
{
return g_slice_new0 (GdkContentFormatsBuilder);
}
/**
* gdk_content_formats_builder_free:
* @builder: a #GdkContentFormatsBuilder
*
* Frees @builder and creates a new #GdkContentFormats from it.
*
* Returns: a new #GdkContentFormats with all the formats added to @builder
**/
GdkContentFormats *
gdk_content_formats_builder_free (GdkContentFormatsBuilder *builder)
{
GdkContentFormats *result;
GType *gtypes;
const char **mime_types;
GSList *l;
gsize i;
g_return_val_if_fail (builder != NULL, NULL);
gtypes = g_new (GType, builder->n_gtypes + 1);
i = builder->n_gtypes;
gtypes[i--] = G_TYPE_INVALID;
/* add backwards because most important type is last in the list */
for (l = builder->gtypes; l; l = l->next)
gtypes[i--] = GPOINTER_TO_SIZE (l->data);
mime_types = g_new (const char *, builder->n_mime_types + 1);
i = builder->n_mime_types;
mime_types[i--] = NULL;
/* add backwards because most important type is last in the list */
for (l = builder->mime_types; l; l = l->next)
mime_types[i--] = l->data;
result = gdk_content_formats_new_take (gtypes, builder->n_gtypes,
mime_types, builder->n_mime_types);
g_slist_free (builder->gtypes);
g_slist_free (builder->mime_types);
g_slice_free (GdkContentFormatsBuilder, builder);
return result;
}
/**
* gdk_content_formats_builder_add_formats:
* @builder: a #GdkContentFormatsBuilder
* @formats: the formats to add
*
* Appends all formats from @formats to @builder, skipping those that
* already exist.
**/
void
gdk_content_formats_builder_add_formats (GdkContentFormatsBuilder *builder,
const GdkContentFormats *formats)
{
gsize i;
g_return_if_fail (builder != NULL);
g_return_if_fail (formats != NULL);
for (i = 0; i < formats->n_gtypes; i++)
gdk_content_formats_builder_add_gtype (builder, formats->gtypes[i]);
for (i = 0; i < formats->n_mime_types; i++)
gdk_content_formats_builder_add_mime_type (builder, formats->mime_types[i]);
}
/**
* gdk_content_formats_builder_add_gtype:
* @builder: a #GdkContentFormatsBuilder
* @type: a #GType
*
* Appends @gtype to @builder if it has not already been added.
**/
void
gdk_content_formats_builder_add_gtype (GdkContentFormatsBuilder *builder,
GType type)
{
g_return_if_fail (builder != NULL);
g_return_if_fail (type != G_TYPE_INVALID);
if (g_slist_find (builder->gtypes, GSIZE_TO_POINTER (type)))
return;
builder->gtypes = g_slist_prepend (builder->gtypes, GSIZE_TO_POINTER (type));
builder->n_gtypes++;
}
/**
* gdk_content_formats_builder_add_mime_type:
* @builder: a #GdkContentFormatsBuilder
* @mime_type: a mime type
*
* Appends @mime_type to @builder if it has not already been added.
**/
void
gdk_content_formats_builder_add_mime_type (GdkContentFormatsBuilder *builder,
const char *mime_type)
{
g_return_if_fail (builder != NULL);
g_return_if_fail (mime_type != NULL);
mime_type = g_intern_string (mime_type);
if (g_slist_find (builder->mime_types, mime_type))
return;
builder->mime_types = g_slist_prepend (builder->mime_types, (gpointer) mime_type);
builder->n_mime_types++;
}
/* G_DEFINE_BOXED wants this */
typedef gpointer GdkFileList;
static gpointer
gdk_file_list_copy (gpointer list)
{
return g_slist_copy_deep (list, (GCopyFunc) g_object_ref, NULL);
}
static void
gdk_file_list_free (gpointer list)
{
g_slist_free_full (list, g_object_unref);
}
G_DEFINE_BOXED_TYPE (GdkFileList, gdk_file_list, gdk_file_list_copy, gdk_file_list_free)

104
gdk/gdkcontentformats.h Normal file
View File

@@ -0,0 +1,104 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2017 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_CONTENT_FORMATS_H__
#define __GTK_CONTENT_FORMATS_H__
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
G_BEGIN_DECLS
#define GDK_TYPE_CONTENT_FORMATS (gdk_content_formats_get_type ())
GDK_AVAILABLE_IN_3_94
const char * gdk_intern_mime_type (const char *string);
GDK_AVAILABLE_IN_3_94
GType gdk_content_formats_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_3_94
GdkContentFormats * gdk_content_formats_new (const char **mime_types,
guint n_mime_types);
GDK_AVAILABLE_IN_3_94
GdkContentFormats * gdk_content_formats_new_for_gtype (GType type);
GDK_AVAILABLE_IN_3_94
GdkContentFormats * gdk_content_formats_ref (GdkContentFormats *formats);
GDK_AVAILABLE_IN_3_94
void gdk_content_formats_unref (GdkContentFormats *formats);
GDK_AVAILABLE_IN_3_94
void gdk_content_formats_print (GdkContentFormats *formats,
GString *string);
GDK_AVAILABLE_IN_3_94
char * gdk_content_formats_to_string (GdkContentFormats *formats);
GDK_AVAILABLE_IN_3_94
const GType * gdk_content_formats_get_gtypes (GdkContentFormats *formats,
gsize *n_gtypes);
GDK_AVAILABLE_IN_3_94
const char * const * gdk_content_formats_get_mime_types (GdkContentFormats *formats,
gsize *n_mime_types);
GDK_AVAILABLE_IN_3_94
GdkContentFormats * gdk_content_formats_union (GdkContentFormats *first,
const GdkContentFormats *second) G_GNUC_WARN_UNUSED_RESULT;
GDK_AVAILABLE_IN_3_94
gboolean gdk_content_formats_match (const GdkContentFormats *first,
const GdkContentFormats *second);
GDK_AVAILABLE_IN_3_94
GType gdk_content_formats_match_gtype (const GdkContentFormats *first,
const GdkContentFormats *second);
GDK_AVAILABLE_IN_3_94
const char * gdk_content_formats_match_mime_type (const GdkContentFormats *first,
const GdkContentFormats *second);
GDK_AVAILABLE_IN_3_94
gboolean gdk_content_formats_contain_gtype (const GdkContentFormats *formats,
GType type);
GDK_AVAILABLE_IN_3_94
gboolean gdk_content_formats_contain_mime_type (const GdkContentFormats *formats,
const char *mime_type);
typedef struct _GdkContentFormatsBuilder GdkContentFormatsBuilder;
GDK_AVAILABLE_IN_3_94
GdkContentFormatsBuilder*gdk_content_formats_builder_new (void);
GDK_AVAILABLE_IN_3_94
GdkContentFormats * gdk_content_formats_builder_free (GdkContentFormatsBuilder *builder) G_GNUC_WARN_UNUSED_RESULT;
GDK_AVAILABLE_IN_3_94
void gdk_content_formats_builder_add_formats (GdkContentFormatsBuilder *builder,
const GdkContentFormats *formats);
GDK_AVAILABLE_IN_3_94
void gdk_content_formats_builder_add_mime_type(GdkContentFormatsBuilder *builder,
const char *mime_type);
GDK_AVAILABLE_IN_3_94
void gdk_content_formats_builder_add_gtype (GdkContentFormatsBuilder *builder,
GType type);
/* dunno where else to put this */
#define GDK_TYPE_FILE_LIST (gdk_file_list_get_type ())
GDK_AVAILABLE_IN_3_94
GType gdk_file_list_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif /* __GTK_CONTENT_FORMATS_H__ */

View File

@@ -0,0 +1,32 @@
/* GTK - The GIMP Toolkit
*
* Copyright (C) 2017 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_CONTENT_FORMATS_PRIVATE_H__
#define __GTK_CONTENT_FORMATS_PRIVATE_H__
#include "gdkcontentformats.h"
G_BEGIN_DECLS
G_END_DECLS
#endif /* __GTK_CONTENT_FORMATS_PRIVATE_H__ */

399
gdk/gdkcontentprovider.c Normal file
View File

@@ -0,0 +1,399 @@
/* GDK - The GIMP Drawing Kit
*
* Copyright (C) 2017 Benjamin Otte <otte@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gdkcontentproviderprivate.h"
#include "gdkclipboard.h"
#include "gdkcontentformats.h"
#include "gdkintl.h"
/**
* SECTION:gdkcontentprovider
* @Short_description: Provides content for data transfer between applications
* @Title: GdkContentProvider
* @See_also: #GdkContentSerializer, #GdkContentDeserializer
*
* A GdkContentProvider is used to provide content for the clipboard in
* a number of formats.
*
* To create a GdkContentProvider, use gdk_content_provider_new_for_value() or
* gdk_content_provider_new_for_bytes().
*
* GDK knows how to handle common text and image formats out-of-the-box. See
* #GdkContentSerializer and #GdkContentDeserializer if you want to add support
* for application-specific data formats.
*/
typedef struct _GdkContentProviderPrivate GdkContentProviderPrivate;
struct _GdkContentProviderPrivate
{
GdkContentFormats *formats;
};
enum {
PROP_0,
PROP_FORMATS,
PROP_STORABLE_FORMATS,
N_PROPERTIES
};
enum {
CONTENT_CHANGED,
N_SIGNALS
};
static GParamSpec *properties[N_PROPERTIES] = { NULL, };
static guint signals[N_SIGNALS] = { 0 };
G_DEFINE_TYPE_WITH_PRIVATE (GdkContentProvider, gdk_content_provider, G_TYPE_OBJECT)
static void
gdk_content_provider_real_attach_clipboard (GdkContentProvider *provider,
GdkClipboard *clipboard)
{
}
static void
gdk_content_provider_real_detach_clipboard (GdkContentProvider *provider,
GdkClipboard *clipboard)
{
}
static GdkContentFormats *
gdk_content_provider_real_ref_formats (GdkContentProvider *provider)
{
return gdk_content_formats_new (NULL, 0);
}
static GdkContentFormats *
gdk_content_provider_real_ref_storable_formats (GdkContentProvider *provider)
{
return gdk_content_provider_ref_formats (provider);
}
static void
gdk_content_provider_real_write_mime_type_async (GdkContentProvider *provider,
const char *mime_type,
GOutputStream *stream,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTask *task;
task = g_task_new (provider, cancellable, callback, user_data);
g_task_set_priority (task, io_priority);
g_task_set_source_tag (task, gdk_content_provider_real_write_mime_type_async);
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("Cannot provide contents as “%s”"), mime_type);
g_object_unref (task);
}
static gboolean
gdk_content_provider_real_write_mime_type_finish (GdkContentProvider *provider,
GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (g_task_is_valid (result, provider), FALSE);
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_content_provider_real_write_mime_type_async, FALSE);
return g_task_propagate_boolean (G_TASK (result), error);
}
static gboolean
gdk_content_provider_real_get_value (GdkContentProvider *provider,
GValue *value,
GError **error)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("Cannot provide contents as %s"), G_VALUE_TYPE_NAME (value));
return FALSE;
}
static void
gdk_content_provider_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GdkContentProvider *provider = GDK_CONTENT_PROVIDER (gobject);
switch (prop_id)
{
case PROP_FORMATS:
g_value_take_boxed (value, gdk_content_provider_ref_formats (provider));
break;
case PROP_STORABLE_FORMATS:
g_value_take_boxed (value, gdk_content_provider_ref_storable_formats (provider));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
gdk_content_provider_class_init (GdkContentProviderClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->get_property = gdk_content_provider_get_property;
class->attach_clipboard = gdk_content_provider_real_attach_clipboard;
class->detach_clipboard = gdk_content_provider_real_detach_clipboard;
class->ref_formats = gdk_content_provider_real_ref_formats;
class->ref_storable_formats = gdk_content_provider_real_ref_storable_formats;
class->write_mime_type_async = gdk_content_provider_real_write_mime_type_async;
class->write_mime_type_finish = gdk_content_provider_real_write_mime_type_finish;
class->get_value = gdk_content_provider_real_get_value;
/**
* GdkContentProvider:formats:
*
* The possible formats that the provider can provide its data in.
*
* Since: 3.94
*/
properties[PROP_FORMATS] =
g_param_spec_boxed ("formats",
"Formats",
"The possible formats for data",
GDK_TYPE_CONTENT_FORMATS,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS |
G_PARAM_EXPLICIT_NOTIFY);
/**
* GdkContentProvider:storable-formats:
*
* The subset of formats that clipboard managers should store this provider's data in.
*
* Since: 3.94
*/
properties[PROP_STORABLE_FORMATS] =
g_param_spec_boxed ("storable-formats",
"Storable formats",
"The formats that data should be stored in",
GDK_TYPE_CONTENT_FORMATS,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS |
G_PARAM_EXPLICIT_NOTIFY);
/**
* GdkContentProvider:content-changed:
*
* Emitted whenever the content provided by this provider has changed.
*
* Since: 3.94
*/
signals[CONTENT_CHANGED] =
g_signal_new ("content-changed",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GdkContentProviderClass, content_changed),
NULL, NULL, NULL,
G_TYPE_NONE, 0);
g_object_class_install_properties (object_class, N_PROPERTIES, properties);
}
static void
gdk_content_provider_init (GdkContentProvider *provider)
{
}
/**
* gdk_content_provider_ref_formats:
* @provider: a #GdkContentProvider
*
* Gets the formats that the provider can provide its current contents in.
*
* Returns: (transfer full): The formats of the provider
**/
GdkContentFormats *
gdk_content_provider_ref_formats (GdkContentProvider *provider)
{
g_return_val_if_fail (GDK_IS_CONTENT_PROVIDER (provider), NULL);
return GDK_CONTENT_PROVIDER_GET_CLASS (provider)->ref_formats (provider);
}
/**
* gdk_content_provider_ref_storable_formats:
* @provider: a #GdkContentProvider
*
* Gets the formats that the provider suggests other applications to store
* the data in.
* An example of such an application would be a clipboard manager.
*
* This can be assumed to be a subset of gdk_content_provider_ref_formats().
*
* Returns: (transfer full): The storable formats of the provider
**/
GdkContentFormats *
gdk_content_provider_ref_storable_formats (GdkContentProvider *provider)
{
g_return_val_if_fail (GDK_IS_CONTENT_PROVIDER (provider), NULL);
return GDK_CONTENT_PROVIDER_GET_CLASS (provider)->ref_storable_formats (provider);
}
/**
* gdk_content_provider_content_changed:
* @provider: a #GdkContentProvider
*
* Emits the #GdkContentProvider::contents-changed signal.
*/
void
gdk_content_provider_content_changed (GdkContentProvider *provider)
{
g_return_if_fail (GDK_IS_CONTENT_PROVIDER (provider));
g_signal_emit (provider, signals[CONTENT_CHANGED], 0);
g_object_notify_by_pspec (G_OBJECT (provider), properties[PROP_FORMATS]);
}
/**
* gdk_content_provider_write_mime_type_async:
* @provider: a #GdkContentProvider
* @mime_type: the mime type to provide the data in
* @stream: the #GOutputStream to write to
* @io_priority: the [I/O priority][io-priority]
* of the request.
* @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
* @callback: (scope async): callback to call when the request is satisfied
* @user_data: (closure): the data to pass to callback function
*
* Asynchronously writes the contents of @provider to @stream in the given
* @mime_type. When the operation is finished @callback will be called. You
* can then call gdk_content_provider_write_mime_type_finish() to get the
* result of the operation.
*
* The given mime type does not need to be listed in the formats returned by
* gdk_content_provider_ref_formats(). However, if the given #GType is not
* supported, #G_IO_ERROR_NOT_SUPPORTED will be reported.
*
* The given @stream will not be closed.
**/
void
gdk_content_provider_write_mime_type_async (GdkContentProvider *provider,
const char *mime_type,
GOutputStream *stream,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_return_if_fail (GDK_IS_CONTENT_PROVIDER (provider));
g_return_if_fail (mime_type != NULL);
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
GDK_CONTENT_PROVIDER_GET_CLASS (provider)->write_mime_type_async (provider,
g_intern_string (mime_type),
stream,
io_priority,
cancellable,
callback,
user_data);
}
/**
* gdk_content_provider_write_mime_type_finish:
* @provider: a #GdkContentProvider
* @result: a #GAsyncResult
* @error: a #GError location to store the error occurring, or %NULL to
* ignore.
*
* Finishes an asynchronous write operation started with
* gdk_content_provider_write_mime_type_async().
*
* Returns: %TRUE if the operation was completed successfully. Otherwise
* @error will be set to describe the failure.
**/
gboolean
gdk_content_provider_write_mime_type_finish (GdkContentProvider *provider,
GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (GDK_IS_CONTENT_PROVIDER (provider), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
return GDK_CONTENT_PROVIDER_GET_CLASS (provider)->write_mime_type_finish (provider, result, error);
}
/**
* gdk_content_provider_get_value:
* @provider: a #GdkContentProvider
* @value: the #GValue to fill
* @error: a #GError location to store the error occurring, or %NULL to
* ignore.
*
* Gets the convtents of @provider stored in @value.
*
* The @value will have been initialized to the #GType the value should be
* provided in. This given #GType does not need to be listed in the formats
* returned by gdk_content_provider_ref_formats(). However, if the given
* #GType is not supported, this operation can fail and
* #G_IO_ERROR_NOT_SUPPORTED will be reported.
*
* Returns: %TRUE if the value was set successfully. Otherwise
* @error will be set to describe the failure.
**/
gboolean
gdk_content_provider_get_value (GdkContentProvider *provider,
GValue *value,
GError **error)
{
g_return_val_if_fail (GDK_IS_CONTENT_PROVIDER (provider), FALSE);
g_return_val_if_fail (G_IS_VALUE (value), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
return GDK_CONTENT_PROVIDER_GET_CLASS (provider)->get_value (provider,
value,
error);
}
void
gdk_content_provider_attach_clipboard (GdkContentProvider *provider,
GdkClipboard *clipboard)
{
g_return_if_fail (GDK_IS_CONTENT_PROVIDER (provider));
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
return GDK_CONTENT_PROVIDER_GET_CLASS (provider)->attach_clipboard (provider, clipboard);
}
void
gdk_content_provider_detach_clipboard (GdkContentProvider *provider,
GdkClipboard *clipboard)
{
g_return_if_fail (GDK_IS_CONTENT_PROVIDER (provider));
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
return GDK_CONTENT_PROVIDER_GET_CLASS (provider)->detach_clipboard (provider, clipboard);
}

117
gdk/gdkcontentprovider.h Normal file
View File

@@ -0,0 +1,117 @@
/* GDK - The GIMP Drawing Kit
*
* Copyright (C) 2017 Benjamin Otte <otte@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GDK_CONTENT_PROVIDER_H__
#define __GDK_CONTENT_PROVIDER_H__
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
G_BEGIN_DECLS
#define GDK_TYPE_CONTENT_PROVIDER (gdk_content_provider_get_type ())
#define GDK_CONTENT_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_CONTENT_PROVIDER, GdkContentProvider))
#define GDK_IS_CONTENT_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_CONTENT_PROVIDER))
#define GDK_CONTENT_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_CONTENT_PROVIDER, GdkContentProviderClass))
#define GDK_IS_CONTENT_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_CONTENT_PROVIDER))
#define GDK_CONTENT_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_CONTENT_PROVIDER, GdkContentProviderClass))
typedef struct _GdkContentProviderClass GdkContentProviderClass;
struct _GdkContentProvider
{
GObject parent;
};
struct _GdkContentProviderClass
{
GObjectClass parent_class;
/* signals */
void (* content_changed) (GdkContentProvider *provider);
/* vfuncs */
void (* attach_clipboard) (GdkContentProvider *provider,
GdkClipboard *clipboard);
void (* detach_clipboard) (GdkContentProvider *provider,
GdkClipboard *clipboard);
GdkContentFormats * (* ref_formats) (GdkContentProvider *provider);
GdkContentFormats * (* ref_storable_formats) (GdkContentProvider *provider);
void (* write_mime_type_async) (GdkContentProvider *provider,
const char *mime_type,
GOutputStream *stream,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean (* write_mime_type_finish) (GdkContentProvider *provider,
GAsyncResult *result,
GError **error);
gboolean (* get_value) (GdkContentProvider *provider,
GValue *value,
GError **error);
/*< private >*/
/* Padding for future expansion */
void (*_gdk_reserved1) (void);
void (*_gdk_reserved2) (void);
void (*_gdk_reserved3) (void);
void (*_gdk_reserved4) (void);
void (*_gdk_reserved5) (void);
void (*_gdk_reserved6) (void);
void (*_gdk_reserved7) (void);
void (*_gdk_reserved8) (void);
};
GDK_AVAILABLE_IN_3_94
GType gdk_content_provider_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_3_94
GdkContentFormats * gdk_content_provider_ref_formats (GdkContentProvider *provider);
GDK_AVAILABLE_IN_3_94
GdkContentFormats * gdk_content_provider_ref_storable_formats (GdkContentProvider *provider);
GDK_AVAILABLE_IN_3_94
void gdk_content_provider_content_changed (GdkContentProvider *provider);
GDK_AVAILABLE_IN_3_94
void gdk_content_provider_write_mime_type_async (GdkContentProvider *provider,
const char *mime_type,
GOutputStream *stream,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GDK_AVAILABLE_IN_3_94
gboolean gdk_content_provider_write_mime_type_finish (GdkContentProvider *provider,
GAsyncResult *result,
GError **error);
GDK_AVAILABLE_IN_3_94
gboolean gdk_content_provider_get_value (GdkContentProvider *provider,
GValue *value,
GError **error);
G_END_DECLS
#endif /* __GDK_CONTENT_PROVIDER_H__ */

View File

@@ -0,0 +1,282 @@
/* GDK - The GIMP Drawing Kit
*
* Copyright (C) 2017 Benjamin Otte <otte@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gdkcontentprovider.h"
#include "gdkcontentformats.h"
#include "gdkintl.h"
#include "gdkcontentproviderimpl.h"
#define GDK_TYPE_CONTENT_PROVIDER_VALUE (gdk_content_provider_value_get_type ())
#define GDK_CONTENT_PROVIDER_VALUE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_CONTENT_PROVIDER_VALUE, GdkContentProviderValue))
#define GDK_IS_CONTENT_PROVIDER_VALUE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_CONTENT_PROVIDER_VALUE))
#define GDK_CONTENT_PROVIDER_VALUE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_CONTENT_PROVIDER_VALUE, GdkContentProviderValueClass))
#define GDK_IS_CONTENT_PROVIDER_VALUE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_CONTENT_PROVIDER_VALUE))
#define GDK_CONTENT_PROVIDER_VALUE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_CONTENT_PROVIDER_VALUE, GdkContentProviderValueClass))
typedef struct _GdkContentProviderValue GdkContentProviderValue;
typedef struct _GdkContentProviderValueClass GdkContentProviderValueClass;
struct _GdkContentProviderValue
{
GdkContentProvider parent;
GValue value;
};
struct _GdkContentProviderValueClass
{
GdkContentProviderClass parent_class;
};
GType gdk_content_provider_value_get_type (void) G_GNUC_CONST;
G_DEFINE_TYPE (GdkContentProviderValue, gdk_content_provider_value, GDK_TYPE_CONTENT_PROVIDER)
static void
gdk_content_provider_value_finalize (GObject *object)
{
GdkContentProviderValue *content = GDK_CONTENT_PROVIDER_VALUE (object);
g_value_unset (&content->value);
G_OBJECT_CLASS (gdk_content_provider_value_parent_class)->finalize (object);
}
static GdkContentFormats *
gdk_content_provider_value_ref_formats (GdkContentProvider *provider)
{
GdkContentProviderValue *content = GDK_CONTENT_PROVIDER_VALUE (provider);
return gdk_content_formats_new_for_gtype (G_VALUE_TYPE (&content->value));
}
static gboolean
gdk_content_provider_value_get_value (GdkContentProvider *provider,
GValue *value,
GError **error)
{
GdkContentProviderValue *content = GDK_CONTENT_PROVIDER_VALUE (provider);
if (G_VALUE_HOLDS (value, G_VALUE_TYPE (&content->value)))
{
g_value_copy (&content->value, value);
return TRUE;
}
return GDK_CONTENT_PROVIDER_CLASS (gdk_content_provider_value_parent_class)->get_value (provider, value, error);
}
static void
gdk_content_provider_value_class_init (GdkContentProviderValueClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GdkContentProviderClass *provider_class = GDK_CONTENT_PROVIDER_CLASS (class);
object_class->finalize = gdk_content_provider_value_finalize;
provider_class->ref_formats = gdk_content_provider_value_ref_formats;
provider_class->get_value = gdk_content_provider_value_get_value;
}
static void
gdk_content_provider_value_init (GdkContentProviderValue *content)
{
}
/**
* gdk_content_provider_new_for_value:
* @value: a #GValue
*
* Create a content provider that provides the given @value.
*
* Returns: a new #GdkContentProvider
**/
GdkContentProvider *
gdk_content_provider_new_for_value (const GValue *value)
{
GdkContentProviderValue *content;
g_return_val_if_fail (G_IS_VALUE (value), NULL);
content = g_object_new (GDK_TYPE_CONTENT_PROVIDER_VALUE, NULL);
g_value_init (&content->value, G_VALUE_TYPE (value));
g_value_copy (value, &content->value);
return GDK_CONTENT_PROVIDER (content);
}
#define GDK_TYPE_CONTENT_PROVIDER_BYTES (gdk_content_provider_bytes_get_type ())
#define GDK_CONTENT_PROVIDER_BYTES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_CONTENT_PROVIDER_BYTES, GdkContentProviderBytes))
#define GDK_IS_CONTENT_PROVIDER_BYTES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_CONTENT_PROVIDER_BYTES))
#define GDK_CONTENT_PROVIDER_BYTES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_CONTENT_PROVIDER_BYTES, GdkContentProviderBytesClass))
#define GDK_IS_CONTENT_PROVIDER_BYTES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_CONTENT_PROVIDER_BYTES))
#define GDK_CONTENT_PROVIDER_BYTES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_CONTENT_PROVIDER_BYTES, GdkContentProviderBytesClass))
typedef struct _GdkContentProviderBytes GdkContentProviderBytes;
typedef struct _GdkContentProviderBytesClass GdkContentProviderBytesClass;
struct _GdkContentProviderBytes
{
GdkContentProvider parent;
/* interned */const char *mime_type;
GBytes *bytes;
};
struct _GdkContentProviderBytesClass
{
GdkContentProviderClass parent_class;
};
GType gdk_content_provider_bytes_get_type (void) G_GNUC_CONST;
G_DEFINE_TYPE (GdkContentProviderBytes, gdk_content_provider_bytes, GDK_TYPE_CONTENT_PROVIDER)
static void
gdk_content_provider_bytes_finalize (GObject *object)
{
GdkContentProviderBytes *content = GDK_CONTENT_PROVIDER_BYTES (object);
g_bytes_unref (content->bytes);
G_OBJECT_CLASS (gdk_content_provider_bytes_parent_class)->finalize (object);
}
static GdkContentFormats *
gdk_content_provider_bytes_ref_formats (GdkContentProvider *provider)
{
GdkContentProviderBytes *content = GDK_CONTENT_PROVIDER_BYTES (provider);
GdkContentFormatsBuilder *builder;
builder = gdk_content_formats_builder_new ();
gdk_content_formats_builder_add_mime_type (builder, content->mime_type);
return gdk_content_formats_builder_free (builder);
}
static void
gdk_content_provider_bytes_write_mime_type_done (GObject *stream,
GAsyncResult *result,
gpointer task)
{
GError *error = NULL;
if (!g_output_stream_write_all_finish (G_OUTPUT_STREAM (stream),
result,
NULL,
&error))
{
g_task_return_error (task, error);
}
else
{
g_task_return_boolean (task, TRUE);
}
g_object_unref (task);
}
static void
gdk_content_provider_bytes_write_mime_type_async (GdkContentProvider *provider,
const char *mime_type,
GOutputStream *stream,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GdkContentProviderBytes *content = GDK_CONTENT_PROVIDER_BYTES (provider);
GTask *task;
task = g_task_new (content, cancellable, callback, user_data);
g_task_set_priority (task, io_priority);
g_task_set_source_tag (task, gdk_content_provider_bytes_write_mime_type_async);
if (mime_type != content->mime_type)
{
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("Cannot provide contents as “%s”"), mime_type);
g_object_unref (task);
return;
}
g_output_stream_write_all_async (stream,
g_bytes_get_data (content->bytes, NULL),
g_bytes_get_size (content->bytes),
io_priority,
cancellable,
gdk_content_provider_bytes_write_mime_type_done,
task);
}
static gboolean
gdk_content_provider_bytes_write_mime_type_finish (GdkContentProvider *provider,
GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (g_task_is_valid (result, provider), FALSE);
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_content_provider_bytes_write_mime_type_async, FALSE);
return g_task_propagate_boolean (G_TASK (result), error);
}
static void
gdk_content_provider_bytes_class_init (GdkContentProviderBytesClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GdkContentProviderClass *provider_class = GDK_CONTENT_PROVIDER_CLASS (class);
object_class->finalize = gdk_content_provider_bytes_finalize;
provider_class->ref_formats = gdk_content_provider_bytes_ref_formats;
provider_class->write_mime_type_async = gdk_content_provider_bytes_write_mime_type_async;
provider_class->write_mime_type_finish = gdk_content_provider_bytes_write_mime_type_finish;
}
static void
gdk_content_provider_bytes_init (GdkContentProviderBytes *content)
{
}
/**
* gdk_content_provider_new_for_bytes:
* @mime_type: the mime type
* @bytes: (transfer none): a #GBytes with the data for @mime_type
*
* Create a content provider that provides the given @bytes as data for
* the given @mime_type.
*
* Returns: a new #GdkContentProvider
**/
GdkContentProvider *
gdk_content_provider_new_for_bytes (const char *mime_type,
GBytes *bytes)
{
GdkContentProviderBytes *content;
g_return_val_if_fail (mime_type != NULL, NULL);
g_return_val_if_fail (bytes != NULL, NULL);
content = g_object_new (GDK_TYPE_CONTENT_PROVIDER_BYTES, NULL);
content->mime_type = g_intern_string (mime_type);
content->bytes = g_bytes_ref (bytes);
return GDK_CONTENT_PROVIDER (content);
}

View File

@@ -1,5 +1,6 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
*
* Copyright (C) 2017 Benjamin Otte <otte@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -15,32 +16,26 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GDK_DEVICE_MANAGER_H__
#define __GDK_DEVICE_MANAGER_H__
#ifndef __GDK_CONTENT_PROVIDER_IMPL_H__
#define __GDK_CONTENT_PROVIDER_IMPL_H__
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
#include <gdk/gdkdevice.h>
G_BEGIN_DECLS
#define GDK_TYPE_DEVICE_MANAGER (gdk_device_manager_get_type ())
#define GDK_DEVICE_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_MANAGER, GdkDeviceManager))
#define GDK_IS_DEVICE_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_MANAGER))
GDK_AVAILABLE_IN_3_94
GdkContentProvider * gdk_content_provider_new_for_value (const GValue *value);
GDK_AVAILABLE_IN_3_94
GdkContentProvider * gdk_content_provider_new_for_bytes (const char *mime_type,
GBytes *bytes);
GDK_AVAILABLE_IN_ALL
GType gdk_device_manager_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GdkDisplay * gdk_device_manager_get_display (GdkDeviceManager *device_manager);
GDK_DEPRECATED_IN_3_20
GList * gdk_device_manager_list_devices (GdkDeviceManager *device_manager,
GdkDeviceType type);
G_END_DECLS
#endif /* __GDK_DEVICE_MANAGER_H__ */
#endif /* __GDK_CONTENT_PROVIDER_IMPL_H__ */

View File

@@ -1,5 +1,5 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2010 Red Hat, Inc.
/*
* Copyright (C) 2017 Benjamin Otte <otte@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -15,31 +15,19 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GDK_SCREEN_PRIVATE_H__
#define __GDK_SCREEN_PRIVATE_H__
#ifndef __GDK_CONTENT_PROVIDER_PRIVATE_H__
#define __GDK_CONTENT_PROVIDER_PRIVATE_H__
#include "gdkscreen.h"
#include <gdk/gdkcontentprovider.h>
G_BEGIN_DECLS
#define GDK_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_SCREEN, GdkScreenClass))
#define GDK_IS_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_SCREEN))
#define GDK_SCREEN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_SCREEN, GdkScreenClass))
typedef struct _GdkScreenClass GdkScreenClass;
struct _GdkScreen
{
GObject parent_instance;
guint closed : 1;
};
struct _GdkScreenClass
{
GObjectClass parent_class;
};
void gdk_content_provider_attach_clipboard (GdkContentProvider *provider,
GdkClipboard *clipboard);
void gdk_content_provider_detach_clipboard (GdkContentProvider *provider,
GdkClipboard *clipboard);
G_END_DECLS
#endif
#endif /* __GDK_CONTENT_PROVIDER_PRIVATE_H__ */

768
gdk/gdkcontentserializer.c Normal file
View File

@@ -0,0 +1,768 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2017 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gio/gio.h>
#include "gdkcontentserializer.h"
#include "gdkcontentformats.h"
#include "gdkpixbuf.h"
#include "gdktextureprivate.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <string.h>
/**
* SECTION:gdkcontentserializer
* @Short_description: Serialize content for transfer
* @Title: GdkContentSerializer
* @See_also: #GdkContentDeserializer, #GdkContentProvider
*
* A GdkContentSerializer is used to serialize content for inter-application
* data transfers.
*/
typedef struct _Serializer Serializer;
struct _Serializer
{
const char * mime_type; /* interned */
GType type;
GdkContentSerializeFunc serialize;
gpointer data;
GDestroyNotify notify;
};
GQueue serializers = G_QUEUE_INIT;
static void init (void);
#define GDK_CONTENT_SERIALIZER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_CONTENT_SERIALIZER, GdkContentSerializerClass))
#define GDK_IS_CONTENT_SERIALIZER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_CONTENT_SERIALIZER))
#define GDK_CONTENT_SERIALIZER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_CONTENT_SERIALIZER, GdkContentSerializerClass))
typedef struct _GdkContentSerializerClass GdkContentSerializerClass;
struct _GdkContentSerializer
{
GObject parent_instance;
const char *mime_type; /* interned */
GValue value;
GOutputStream *stream;
int priority;
GCancellable *cancellable;
gpointer user_data;
GAsyncReadyCallback callback;
gpointer callback_data;
gpointer task_data;
GDestroyNotify task_notify;
GError *error;
gboolean returned;
};
struct _GdkContentSerializerClass
{
GObjectClass parent_class;
};
static gpointer
gdk_content_serializer_async_result_get_user_data (GAsyncResult *res)
{
return GDK_CONTENT_SERIALIZER (res)->callback_data;
}
static GObject *
gdk_content_serializer_async_result_get_source_object (GAsyncResult *res)
{
return NULL;
}
static void
gdk_content_serializer_async_result_iface_init (GAsyncResultIface *iface)
{
iface->get_user_data = gdk_content_serializer_async_result_get_user_data;
iface->get_source_object = gdk_content_serializer_async_result_get_source_object;
}
G_DEFINE_TYPE_WITH_CODE (GdkContentSerializer, gdk_content_serializer, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT, gdk_content_serializer_async_result_iface_init))
static void
gdk_content_serializer_finalize (GObject *object)
{
GdkContentSerializer *serializer = GDK_CONTENT_SERIALIZER (object);
g_value_unset (&serializer->value);
g_clear_object (&serializer->stream);
g_clear_object (&serializer->cancellable);
g_clear_error (&serializer->error);
if (serializer->task_notify)
serializer->task_notify (serializer->task_data);
G_OBJECT_CLASS (gdk_content_serializer_parent_class)->finalize (object);
}
static void
gdk_content_serializer_class_init (GdkContentSerializerClass *content_serializer_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (content_serializer_class);
object_class->finalize = gdk_content_serializer_finalize;
}
static void
gdk_content_serializer_init (GdkContentSerializer *content_serializer)
{
}
static void
gdk_content_serializer_run (const char *mime_type,
const GValue *value,
GOutputStream *stream,
int priority,
GCancellable *cancellable,
GdkContentSerializeFunc serialize_func,
gpointer user_data,
GAsyncReadyCallback callback,
gpointer callback_data)
{
GdkContentSerializer *serializer;
serializer = g_object_new (GDK_TYPE_CONTENT_SERIALIZER, NULL);
serializer->mime_type = mime_type;
g_value_init (&serializer->value, G_VALUE_TYPE (value));
g_value_copy (value, &serializer->value);
serializer->stream = g_object_ref (stream);
serializer->priority = priority;
if (cancellable)
serializer->cancellable = g_object_ref (cancellable);
serializer->user_data = user_data;
serializer->callback = callback;
serializer->callback_data = callback_data;
serialize_func (serializer);
}
const char *
gdk_content_serializer_get_mime_type (GdkContentSerializer *serializer)
{
g_return_val_if_fail (GDK_IS_CONTENT_SERIALIZER (serializer), NULL);
return serializer->mime_type;
}
GType
gdk_content_serializer_get_gtype (GdkContentSerializer *serializer)
{
g_return_val_if_fail (GDK_IS_CONTENT_SERIALIZER (serializer), G_TYPE_INVALID);
return G_VALUE_TYPE (&serializer->value);
}
const GValue *
gdk_content_serializer_get_value (GdkContentSerializer *serializer)
{
g_return_val_if_fail (GDK_IS_CONTENT_SERIALIZER (serializer), NULL);
return &serializer->value;
}
GOutputStream *
gdk_content_serializer_get_output_stream (GdkContentSerializer *serializer)
{
g_return_val_if_fail (GDK_IS_CONTENT_SERIALIZER (serializer), NULL);
return serializer->stream;
}
int
gdk_content_serializer_get_priority (GdkContentSerializer *serializer)
{
g_return_val_if_fail (GDK_IS_CONTENT_SERIALIZER (serializer), G_PRIORITY_DEFAULT);
return serializer->priority;
}
GCancellable *
gdk_content_serializer_get_cancellable (GdkContentSerializer *serializer)
{
g_return_val_if_fail (GDK_IS_CONTENT_SERIALIZER (serializer), NULL);
return serializer->cancellable;
}
gpointer
gdk_content_serializer_get_user_data (GdkContentSerializer *serializer)
{
g_return_val_if_fail (GDK_IS_CONTENT_SERIALIZER (serializer), NULL);
return serializer->user_data;
}
void
gdk_content_serializer_set_task_data (GdkContentSerializer *serializer,
gpointer data,
GDestroyNotify notify)
{
g_return_if_fail (GDK_IS_CONTENT_SERIALIZER (serializer));
if (serializer->task_notify)
serializer->task_notify (serializer->task_data);
serializer->task_data = data;
serializer->task_notify = notify;
}
gpointer
gdk_content_serializer_get_task_data (GdkContentSerializer *serializer)
{
g_return_val_if_fail (GDK_IS_CONTENT_SERIALIZER (serializer), NULL);
return serializer->task_data;
}
static gboolean
gdk_content_serializer_emit_callback (gpointer data)
{
GdkContentSerializer *serializer = data;
if (serializer->callback)
{
serializer->callback (NULL, G_ASYNC_RESULT (serializer), serializer->callback_data);
}
return G_SOURCE_REMOVE;
}
void
gdk_content_serializer_return_success (GdkContentSerializer *serializer)
{
g_return_if_fail (GDK_IS_CONTENT_SERIALIZER (serializer));
g_return_if_fail (!serializer->returned);
serializer->returned = TRUE;
g_idle_add_full (serializer->priority,
gdk_content_serializer_emit_callback,
serializer,
g_object_unref);
/* NB: the idle will destroy our reference */
}
void
gdk_content_serializer_return_error (GdkContentSerializer *serializer,
GError *error)
{
g_return_if_fail (GDK_IS_CONTENT_SERIALIZER (serializer));
g_return_if_fail (!serializer->returned);
g_return_if_fail (error != NULL);
serializer->error = error;
/* FIXME: naming */
gdk_content_serializer_return_success (serializer);
}
void
gdk_content_register_serializer (GType type,
const char *mime_type,
GdkContentSerializeFunc serialize,
gpointer data,
GDestroyNotify notify)
{
Serializer *serializer;
g_return_if_fail (mime_type != NULL);
g_return_if_fail (serialize != NULL);
init ();
serializer = g_slice_new0 (Serializer);
serializer->mime_type = g_intern_string (mime_type);
serializer->type = type;
serializer->serialize = serialize;
serializer->data = data;
serializer->notify = notify;
g_queue_push_tail (&serializers, serializer);
}
static Serializer *
lookup_serializer (const char *mime_type,
GType type)
{
GList *l;
g_return_val_if_fail (mime_type != NULL, NULL);
init ();
mime_type = g_intern_string (mime_type);
for (l = g_queue_peek_head_link (&serializers); l; l = l->next)
{
Serializer *serializer = l->data;
if (serializer->mime_type == mime_type &&
serializer->type == type)
return serializer;
}
return NULL;
}
GdkContentFormats *
gdk_content_formats_union_serialize_gtypes (GdkContentFormats *formats)
{
GdkContentFormatsBuilder *builder;
GList *l;
g_return_val_if_fail (formats != NULL, NULL);
init ();
builder = gdk_content_formats_builder_new ();
gdk_content_formats_builder_add_formats (builder, formats);
for (l = g_queue_peek_head_link (&serializers); l; l = l->next)
{
Serializer *serializer = l->data;
if (gdk_content_formats_contain_mime_type (formats, serializer->mime_type))
gdk_content_formats_builder_add_gtype (builder, serializer->type);
}
gdk_content_formats_unref (formats);
return gdk_content_formats_builder_free (builder);
}
GdkContentFormats *
gdk_content_formats_union_serialize_mime_types (GdkContentFormats *formats)
{
GdkContentFormatsBuilder *builder;
GList *l;
g_return_val_if_fail (formats != NULL, NULL);
init ();
builder = gdk_content_formats_builder_new ();
gdk_content_formats_builder_add_formats (builder, formats);
for (l = g_queue_peek_head_link (&serializers); l; l = l->next)
{
Serializer *serializer = l->data;
if (gdk_content_formats_contain_gtype (formats, serializer->type))
gdk_content_formats_builder_add_mime_type (builder, serializer->mime_type);
}
gdk_content_formats_unref (formats);
return gdk_content_formats_builder_free (builder);
}
static void
serialize_not_found (GdkContentSerializer *serializer)
{
GError *error = g_error_new (G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
"Could not convert data from %s to %s",
g_type_name (gdk_content_serializer_get_gtype (serializer)),
gdk_content_serializer_get_mime_type (serializer));
gdk_content_serializer_return_error (serializer, error);
}
void
gdk_content_serialize_async (GOutputStream *stream,
const char *mime_type,
const GValue *value,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
Serializer *serializer;
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
g_return_if_fail (callback != NULL);
serializer = lookup_serializer (mime_type, G_VALUE_TYPE (value));
gdk_content_serializer_run (mime_type,
value,
stream,
io_priority,
cancellable,
serializer ? serializer->serialize : serialize_not_found,
serializer ? serializer->data : NULL,
callback,
user_data);
}
gboolean
gdk_content_serialize_finish (GAsyncResult *result,
GError **error)
{
GdkContentSerializer *serializer;
g_return_val_if_fail (GDK_IS_CONTENT_SERIALIZER (result), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
serializer = GDK_CONTENT_SERIALIZER (result);
if (serializer->error)
{
if (error)
*error = g_error_copy (serializer->error);
return FALSE;
}
return TRUE;
}
/*** SERIALIZERS ***/
static void
pixbuf_serializer_finish (GObject *source,
GAsyncResult *res,
gpointer serializer)
{
GError *error = NULL;
if (!gdk_pixbuf_save_to_stream_finish (res, &error))
gdk_content_serializer_return_error (serializer, error);
else
gdk_content_serializer_return_success (serializer);
}
static void
pixbuf_serializer (GdkContentSerializer *serializer)
{
const GValue *value;
GdkPixbuf *pixbuf;
const char *name;
name = gdk_content_serializer_get_user_data (serializer);
value = gdk_content_serializer_get_value (serializer);
if (G_VALUE_HOLDS (value, GDK_TYPE_PIXBUF))
{
pixbuf = g_value_dup_object (value);
}
else if (G_VALUE_HOLDS (value, GDK_TYPE_TEXTURE))
{
GdkTexture *texture = g_value_get_object (value);
cairo_surface_t *surface = gdk_texture_download_surface (texture);
pixbuf = gdk_pixbuf_get_from_surface (surface,
0, 0,
gdk_texture_get_width (texture), gdk_texture_get_height (texture));
cairo_surface_destroy (surface);
}
else
{
g_assert_not_reached ();
}
gdk_pixbuf_save_to_stream_async (pixbuf,
gdk_content_serializer_get_output_stream (serializer),
name,
gdk_content_serializer_get_cancellable (serializer),
pixbuf_serializer_finish,
serializer,
g_str_equal (name, "png") ? "compression" : NULL, "2",
NULL);
g_object_unref (pixbuf);
}
static void
string_serializer_finish (GObject *source,
GAsyncResult *result,
gpointer serializer)
{
GOutputStream *stream = G_OUTPUT_STREAM (source);
GError *error = NULL;
if (!g_output_stream_write_all_finish (stream, result, NULL, &error))
gdk_content_serializer_return_error (serializer, error);
else
gdk_content_serializer_return_success (serializer);
}
static void
string_serializer (GdkContentSerializer *serializer)
{
GOutputStream *filter;
GCharsetConverter *converter;
GError *error = NULL;
const char *text;
converter = g_charset_converter_new (gdk_content_serializer_get_user_data (serializer),
"utf-8",
&error);
if (converter == NULL)
{
gdk_content_serializer_return_error (serializer, error);
return;
}
g_charset_converter_set_use_fallback (converter, TRUE);
filter = g_converter_output_stream_new (gdk_content_serializer_get_output_stream (serializer),
G_CONVERTER (converter));
g_object_unref (converter);
text = g_value_get_string (gdk_content_serializer_get_value (serializer));
if (text == NULL)
text = "";
g_output_stream_write_all_async (filter,
text,
strlen (text) + 1,
gdk_content_serializer_get_priority (serializer),
gdk_content_serializer_get_cancellable (serializer),
string_serializer_finish,
serializer);
g_object_unref (filter);
}
static void
file_serializer_finish (GObject *source,
GAsyncResult *result,
gpointer serializer)
{
GOutputStream *stream = G_OUTPUT_STREAM (source);
GError *error = NULL;
if (!g_output_stream_write_all_finish (stream, result, NULL, &error))
gdk_content_serializer_return_error (serializer, error);
else
gdk_content_serializer_return_success (serializer);
}
static void
file_uri_serializer (GdkContentSerializer *serializer)
{
GFile *file;
GString *str;
const GValue *value;
char *uri;
str = g_string_new (NULL);
value = gdk_content_serializer_get_value (serializer);
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
{
file = g_value_get_object (gdk_content_serializer_get_value (serializer));
if (file)
{
uri = g_file_get_uri (file);
g_string_append (str, uri);
g_free (uri);
}
else
{
g_string_append (str, "# GTK does not crash when copying a NULL GFile!");
}
g_string_append (str, "\r\n");
}
else if (G_VALUE_HOLDS (value, GDK_TYPE_FILE_LIST))
{
GSList *l;
for (l = g_value_get_boxed (value); l; l = l->next)
{
uri = g_file_get_uri (l->data);
g_string_append (str, uri);
g_free (uri);
g_string_append (str, "\r\n");
}
}
g_output_stream_write_all_async (gdk_content_serializer_get_output_stream (serializer),
str->str,
str->len,
gdk_content_serializer_get_priority (serializer),
gdk_content_serializer_get_cancellable (serializer),
file_serializer_finish,
serializer);
gdk_content_serializer_set_task_data (serializer, g_string_free (str, FALSE), g_free);
}
static void
file_text_serializer (GdkContentSerializer *serializer)
{
const GValue *value;
char *path = NULL;
value = gdk_content_serializer_get_value (serializer);
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
{
GFile *file;
file = g_value_get_object (value);
if (file)
{
path = g_file_get_path (file);
if (path == NULL)
path = g_file_get_uri (file);
}
}
else if (G_VALUE_HOLDS (value, GDK_TYPE_FILE_LIST))
{
GString *str;
GSList *l;
str = g_string_new (NULL);
for (l = g_value_get_boxed (value); l; l = l->next)
{
path = g_file_get_path (l->data);
if (path == NULL)
path = g_file_get_uri (l->data);
g_string_append (str, path);
g_free (path);
if (l->next)
g_string_append (str, " ");
}
path = g_string_free (str, FALSE);
}
g_assert (path != NULL);
g_output_stream_write_all_async (gdk_content_serializer_get_output_stream (serializer),
path,
strlen (path),
gdk_content_serializer_get_priority (serializer),
gdk_content_serializer_get_cancellable (serializer),
file_serializer_finish,
serializer);
gdk_content_serializer_set_task_data (serializer, path, g_free);
}
static void
init (void)
{
static gboolean initialized = FALSE;
GSList *formats, *f;
const char *charset;
if (initialized)
return;
initialized = TRUE;
formats = gdk_pixbuf_get_formats ();
/* Make sure png comes first */
for (f = formats; f; f = f->next)
{
GdkPixbufFormat *fmt = f->data;
gchar *name;
name = gdk_pixbuf_format_get_name (fmt);
if (g_str_equal (name, "png"))
{
formats = g_slist_delete_link (formats, f);
formats = g_slist_prepend (formats, fmt);
g_free (name);
break;
}
g_free (name);
}
for (f = formats; f; f = f->next)
{
GdkPixbufFormat *fmt = f->data;
gchar **mimes, **m;
if (!gdk_pixbuf_format_is_writable (fmt))
continue;
mimes = gdk_pixbuf_format_get_mime_types (fmt);
for (m = mimes; *m; m++)
{
gdk_content_register_serializer (GDK_TYPE_TEXTURE,
*m,
pixbuf_serializer,
g_strdup (gdk_pixbuf_format_get_name (fmt)),
g_free);
gdk_content_register_serializer (GDK_TYPE_PIXBUF,
*m,
pixbuf_serializer,
g_strdup (gdk_pixbuf_format_get_name (fmt)),
g_free);
}
g_strfreev (mimes);
}
g_slist_free (formats);
gdk_content_register_serializer (G_TYPE_FILE,
"text/uri-list",
file_uri_serializer,
NULL,
NULL);
gdk_content_register_serializer (G_TYPE_FILE,
"text/plain;charset=utf-8",
file_text_serializer,
NULL,
NULL);
gdk_content_register_serializer (GDK_TYPE_FILE_LIST,
"text/uri-list",
file_uri_serializer,
NULL,
NULL);
gdk_content_register_serializer (GDK_TYPE_FILE_LIST,
"text/plain;charset=utf-8",
file_text_serializer,
NULL,
NULL);
gdk_content_register_serializer (G_TYPE_STRING,
"text/plain;charset=utf-8",
string_serializer,
(gpointer) "utf-8",
NULL);
if (!g_get_charset (&charset))
{
char *mime = g_strdup_printf ("text/plain;charset=%s", charset);
gdk_content_register_serializer (G_TYPE_STRING,
mime,
string_serializer,
mime,
g_free);
}
gdk_content_register_serializer (G_TYPE_STRING,
"text/plain",
string_serializer,
(gpointer) "ASCII",
NULL);
}

View File

@@ -0,0 +1,95 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2017 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_CONTENT_SERIALIZER_H__
#define __GTK_CONTENT_SERIALIZER_H__
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
G_BEGIN_DECLS
#define GDK_TYPE_CONTENT_SERIALIZER (gdk_content_serializer_get_type ())
#define GDK_CONTENT_SERIALIZER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_CONTENT_SERIALIZER, GdkContentSerializer))
#define GDK_IS_CONTENT_SERIALIZER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_CONTENT_SERIALIZER))
typedef struct _GdkContentSerializer GdkContentSerializer;
typedef void (* GdkContentSerializeFunc) (GdkContentSerializer *serializer);
GDK_AVAILABLE_IN_3_94
GType gdk_content_serializer_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_3_94
const char * gdk_content_serializer_get_mime_type (GdkContentSerializer *serializer);
GDK_AVAILABLE_IN_3_94
GType gdk_content_serializer_get_gtype (GdkContentSerializer *serializer);
GDK_AVAILABLE_IN_3_94
const GValue * gdk_content_serializer_get_value (GdkContentSerializer *serializer);
GDK_AVAILABLE_IN_3_94
GOutputStream * gdk_content_serializer_get_output_stream (GdkContentSerializer *serializer);
GDK_AVAILABLE_IN_3_94
int gdk_content_serializer_get_priority (GdkContentSerializer *serializer);
GDK_AVAILABLE_IN_3_94
GCancellable * gdk_content_serializer_get_cancellable (GdkContentSerializer *serializer);
GDK_AVAILABLE_IN_3_94
gpointer gdk_content_serializer_get_user_data (GdkContentSerializer *serializer);
GDK_AVAILABLE_IN_3_94
void gdk_content_serializer_set_task_data (GdkContentSerializer *serializer,
gpointer data,
GDestroyNotify notify);
GDK_AVAILABLE_IN_3_94
gpointer gdk_content_serializer_get_task_data (GdkContentSerializer *serializer);
GDK_AVAILABLE_IN_3_94
void gdk_content_serializer_return_success (GdkContentSerializer *serializer);
GDK_AVAILABLE_IN_3_94
void gdk_content_serializer_return_error (GdkContentSerializer *serializer,
GError *error);
GDK_AVAILABLE_IN_3_94
GdkContentFormats * gdk_content_formats_union_serialize_gtypes (GdkContentFormats *formats);
GDK_AVAILABLE_IN_3_94
GdkContentFormats * gdk_content_formats_union_serialize_mime_types (GdkContentFormats *formats);
GDK_AVAILABLE_IN_3_94
void gdk_content_register_serializer (GType type,
const char *mime_type,
GdkContentSerializeFunc serialize,
gpointer data,
GDestroyNotify notify);
GDK_AVAILABLE_IN_3_94
void gdk_content_serialize_async (GOutputStream *stream,
const char *mime_type,
const GValue *value,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GDK_AVAILABLE_IN_3_94
gboolean gdk_content_serialize_finish (GAsyncResult *result,
GError **error);
G_END_DECLS
#endif /* __GDK_CONTENT_SERIALIZER_H__ */

View File

@@ -29,6 +29,7 @@
#include "gdkcursor.h"
#include "gdkcursorprivate.h"
#include "gdktexture.h"
#include "gdkintl.h"
#include "gdkinternals.h"
@@ -182,35 +183,40 @@ gdk_cursor_class_init (GdkCursorClass *cursor_class)
P_("Fallback"),
P_("Cursor image to fall back to if this cursor cannot be displayed"),
GDK_TYPE_CURSOR,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class,
PROP_HOTSPOT_X,
g_param_spec_int ("hotspot-x",
P_("Hotspot X"),
P_("Horizontal offset of the cursor hotspot"),
0, G_MAXINT, 0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class,
PROP_HOTSPOT_Y,
g_param_spec_int ("hotspot-y",
P_("Hotspot Y"),
P_("Vertical offset of the cursor hotspot"),
0, G_MAXINT, 0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class,
PROP_NAME,
g_param_spec_string ("name",
P_("Name"),
P_("Name of this cursor"),
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class,
PROP_TEXTURE,
g_param_spec_object ("texture",
P_("Texture"),
P_("The texture displayed by this cursor"),
GDK_TYPE_TEXTURE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
}
static void
@@ -330,83 +336,6 @@ gdk_cursor_new_from_name (const gchar *name,
NULL);
}
/**
* gdk_cursor_new_from_pixbuf:
* @pixbuf: the #GdkPixbuf containing the cursor image
* @x: the horizontal offset of the “hotspot” of the cursor.
* @y: the vertical offset of the “hotspot” of the cursor.
* @fallback: (allow-none): %NULL or the #GdkCursor to fall back to when
* this one cannot be supported
*
* Creates a new cursor from a pixbuf.
*
* Not all GDK backends support RGBA cursors. If they are not
* supported, a monochrome approximation will be displayed.
* The functions gdk_display_supports_cursor_alpha() and
* gdk_display_supports_cursor_color() can be used to determine
* whether RGBA cursors are supported;
* gdk_display_get_default_cursor_size() and
* gdk_display_get_maximal_cursor_size() give information about
* cursor sizes.
*
* If @x or @y are `-1`, the pixbuf must have
* options named “x_hot” and “y_hot”, resp., containing
* integer values between `0` and the width resp. height of
* the pixbuf. (Since: 3.0)
*
* On the X backend, support for RGBA cursors requires a
* sufficently new version of the X Render extension.
*
* Returns: a new #GdkCursor.
*
* Since: 2.4
*/
GdkCursor *
gdk_cursor_new_from_pixbuf (GdkPixbuf *pixbuf,
gint x,
gint y,
GdkCursor *fallback)
{
GdkTexture *texture;
const char *option;
char *end;
gint64 value;
GdkCursor *cursor;
g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
g_return_val_if_fail (fallback == NULL || GDK_IS_CURSOR (fallback), NULL);
if (x == -1 && (option = gdk_pixbuf_get_option (pixbuf, "x_hot")))
{
errno = 0;
end = NULL;
value = g_ascii_strtoll (option, &end, 10);
if (errno == 0 &&
end != option &&
value >= 0 && value < G_MAXINT)
x = (gint) value;
}
if (y == -1 && (option = gdk_pixbuf_get_option (pixbuf, "y_hot")))
{
errno = 0;
end = NULL;
value = g_ascii_strtoll (option, &end, 10);
if (errno == 0 &&
end != option &&
value >= 0 && value < G_MAXINT)
y = (gint) value;
}
texture = gdk_texture_new_for_pixbuf (pixbuf);
cursor = gdk_cursor_new_from_texture (texture, x, y, fallback);
g_object_unref (texture);
return cursor;
}
/**
* gdk_cursor_new_from_texture:
* @texture: the texture providing the pixel data

View File

@@ -31,7 +31,6 @@
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
G_BEGIN_DECLS
@@ -45,11 +44,6 @@ G_BEGIN_DECLS
GDK_AVAILABLE_IN_ALL
GType gdk_cursor_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GdkCursor* gdk_cursor_new_from_pixbuf (GdkPixbuf *pixbuf,
gint x,
gint y,
GdkCursor *fallback);
GDK_AVAILABLE_IN_3_94
GdkCursor* gdk_cursor_new_from_texture (GdkTexture *texture,
int hotspot_x,
@@ -58,7 +52,7 @@ GdkCursor* gdk_cursor_new_from_texture (GdkTexture *texture,
GDK_AVAILABLE_IN_ALL
GdkCursor* gdk_cursor_new_from_name (const gchar *name,
GdkCursor *fallback);
GDK_AVAILABLE_IN_3_94
GdkCursor * gdk_cursor_get_fallback (GdkCursor *cursor);
GDK_AVAILABLE_IN_3_94

View File

@@ -1,30 +0,0 @@
/* GDK - The GIMP Drawing Kit
* gdkdeprecated.c
*
* Copyright 1995-2011 Red Hat Inc.
*
* Benjamin Otte <otte@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#define GDK_DISABLE_DEPRECATION_WARNINGS
#include "config.h"
#include "gdkdisplay.h"
#include "gdkmain.h"
#include "gdkwindow.h"

View File

@@ -32,12 +32,12 @@
* SECTION:gdkdevice
* @Short_description: Object representing an input device
* @Title: GdkDevice
* @See_also: #GdkDeviceManager
* @See_also: #GdkSeat
*
* The #GdkDevice object represents a single input device, such
* as a keyboard, a mouse, a touchpad, etc.
*
* See the #GdkDeviceManager documentation for more information
* See the #GdkSeat documentation for more information
* about the various kinds of master and slave devices, and their
* relationships.
*/
@@ -82,7 +82,6 @@ G_DEFINE_ABSTRACT_TYPE (GdkDevice, gdk_device, G_TYPE_OBJECT)
enum {
PROP_0,
PROP_DISPLAY,
PROP_DEVICE_MANAGER,
PROP_NAME,
PROP_ASSOCIATED_DEVICE,
PROP_TYPE,
@@ -123,23 +122,8 @@ gdk_device_class_init (GdkDeviceClass *klass)
P_("Device Display"),
P_("Display which the device belongs to"),
GDK_TYPE_DISPLAY,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
/**
* GdkDevice:device-manager:
*
* The #GdkDeviceManager the #GdkDevice pertains to.
*
* Since: 3.0
*/
device_props[PROP_DEVICE_MANAGER] =
g_param_spec_object ("device-manager",
P_("Device manager"),
P_("Device manager which the device belongs to"),
GDK_TYPE_DEVICE_MANAGER,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
/**
* GdkDevice:name:
*
@@ -434,9 +418,6 @@ gdk_device_set_property (GObject *object,
case PROP_DISPLAY:
device->display = g_value_get_object (value);
break;
case PROP_DEVICE_MANAGER:
device->manager = g_value_get_object (value);
break;
case PROP_NAME:
g_free (device->name);
@@ -485,9 +466,6 @@ gdk_device_get_property (GObject *object,
case PROP_DISPLAY:
g_value_set_object (value, device->display);
break;
case PROP_DEVICE_MANAGER:
g_value_set_object (value, device->manager);
break;
case PROP_ASSOCIATED_DEVICE:
g_value_set_object (value, device->associated);
break;
@@ -1377,7 +1355,7 @@ get_native_grab_event_mask (GdkEventMask grab_mask)
* gdk_device_grab:
* @device: a #GdkDevice. To get the device you can use gtk_get_current_event_device()
* or gdk_event_get_device() if the grab is in reaction to an event. Also, you can use
* gdk_device_manager_get_client_pointer() but only in code that isnt triggered by a
* gdk_seat_get_pointer() but only in code that isnt triggered by a
* #GdkEvent and there arent other means to get a meaningful #GdkDevice to operate on.
* @window: the #GdkWindow which will own the grab (the grab window)
* @grab_ownership: specifies the grab ownership.

View File

@@ -93,10 +93,9 @@ typedef enum
* be an associated focus indicator on the screen.
* @GDK_DEVICE_TYPE_SLAVE: Device is a slave (or physical) device.
* @GDK_DEVICE_TYPE_FLOATING: Device is a physical device, currently not attached to
* any virtual device.
* any seat.
*
* Indicates the device type. See [above][GdkDeviceManager.description]
* for more information about the meaning of these device types.
* Indicates the device type.
*/
typedef enum {
GDK_DEVICE_TYPE_MASTER,

View File

@@ -1,340 +0,0 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gdkdevicemanagerprivate.h"
#include "gdkdisplay.h"
#include "gdkintl.h"
/**
* SECTION:gdkdevicemanager
* @Short_description: Functions for handling input devices
* @Title: GdkDeviceManager
* @See_also: #GdkDevice, #GdkEvent
*
* In addition to a single pointer and keyboard for user interface input,
* GDK contains support for a variety of input devices, including graphics
* tablets, touchscreens and multiple pointers/keyboards interacting
* simultaneously with the user interface. Such input devices often have
* additional features, such as sub-pixel positioning information and
* additional device-dependent information.
*
* In order to query the device hierarchy and be aware of changes in the
* device hierarchy (such as virtual devices being created or removed, or
* physical devices being plugged or unplugged), GDK provides
* #GdkDeviceManager.
*
* By default, and if the platform supports it, GDK is aware of multiple
* keyboard/pointer pairs and multitouch devices. This behavior can be
* changed by calling gdk_disable_multidevice() before gdk_display_open().
* There should rarely be a need to do that though, since GDK defaults
* to a compatibility mode in which it will emit just one enter/leave
* event pair for all devices on a window. To enable per-device
* enter/leave events and other multi-pointer interaction features,
* gdk_window_set_support_multidevice() must be called on
* #GdkWindows (or gtk_widget_set_support_multidevice() on widgets).
* window. See the gdk_window_set_support_multidevice() documentation
* for more information.
*
* On X11, multi-device support is implemented through XInput 2.
* Unless gdk_disable_multidevice() is called, the XInput 2
* #GdkDeviceManager implementation will be used as the input source.
* Otherwise either the core or XInput 1 implementations will be used.
*
* For simple applications that dont have any special interest in
* input devices, the so-called “client pointer”
* provides a reasonable approximation to a simple setup with a single
* pointer and keyboard. The device that has been set as the client
* pointer can be accessed via gdk_device_manager_get_client_pointer().
*
* Conceptually, in multidevice mode there are 2 device types. Virtual
* devices (or master devices) are represented by the pointer cursors
* and keyboard foci that are seen on the screen. Physical devices (or
* slave devices) represent the hardware that is controlling the virtual
* devices, and thus have no visible cursor on the screen.
*
* Virtual devices are always paired, so there is a keyboard device for every
* pointer device. Associations between devices may be inspected through
* gdk_device_get_associated_device().
*
* There may be several virtual devices, and several physical devices could
* be controlling each of these virtual devices. Physical devices may also
* be “floating”, which means they are not attached to any virtual device.
*
* # Master and slave devices
*
* |[
* carlos@sacarino:~$ xinput list
* ⎡ Virtual core pointer id=2 [master pointer (3)]
* ⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
* ⎜ ↳ Wacom ISDv4 E6 Pen stylus id=10 [slave pointer (2)]
* ⎜ ↳ Wacom ISDv4 E6 Finger touch id=11 [slave pointer (2)]
* ⎜ ↳ SynPS/2 Synaptics TouchPad id=13 [slave pointer (2)]
* ⎜ ↳ TPPS/2 IBM TrackPoint id=14 [slave pointer (2)]
* ⎜ ↳ Wacom ISDv4 E6 Pen eraser id=16 [slave pointer (2)]
* ⎣ Virtual core keyboard id=3 [master keyboard (2)]
* ↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
* ↳ Power Button id=6 [slave keyboard (3)]
* ↳ Video Bus id=7 [slave keyboard (3)]
* ↳ Sleep Button id=8 [slave keyboard (3)]
* ↳ Integrated Camera id=9 [slave keyboard (3)]
* ↳ AT Translated Set 2 keyboard id=12 [slave keyboard (3)]
* ↳ ThinkPad Extra Buttons id=15 [slave keyboard (3)]
* ]|
*
* By default, GDK will automatically listen for events coming from all
* master devices, setting the #GdkDevice for all events coming from input
* devices. Events containing device information are #GDK_MOTION_NOTIFY,
* #GDK_BUTTON_PRESS, #GDK_BUTTON_RELEASE, #GDK_SCROLL, #GDK_KEY_PRESS, #GDK_KEY_RELEASE,
* #GDK_ENTER_NOTIFY, #GDK_LEAVE_NOTIFY, #GDK_FOCUS_CHANGE,
* #GDK_PROXIMITY_IN, #GDK_PROXIMITY_OUT, #GDK_DRAG_ENTER, #GDK_DRAG_LEAVE,
* #GDK_DRAG_MOTION, #GDK_DRAG_STATUS, #GDK_DROP_START, #GDK_DROP_FINISHED
* and #GDK_GRAB_BROKEN. When dealing with an event on a master device,
* it is possible to get the source (slave) device that the event originated
* from via gdk_event_get_source_device().
*
* On a standard session, all physical devices are connected by default to
* the "Virtual Core Pointer/Keyboard" master devices, hence routing all events
* through these. This behavior is only modified by device grabs, where the
* slave device is temporarily detached for as long as the grab is held, and
* more permanently by user modifications to the device hierarchy.
*
* On certain application specific setups, it may make sense
* to detach a physical device from its master pointer, and mapping it to
* an specific window. This can be achieved by the combination of
* gdk_device_grab() and gdk_device_set_mode().
*
* In order to listen for events coming from devices
* other than a virtual device, gdk_window_set_device_events() must be
* called. Generally, this function can be used to modify the event mask
* for any given device.
*
* Input devices may also provide additional information besides X/Y.
* For example, graphics tablets may also provide pressure and X/Y tilt
* information. This information is device-dependent, and may be
* queried through gdk_device_get_axis(). In multidevice mode, virtual
* devices will change axes in order to always represent the physical
* device that is routing events through it. Whenever the physical device
* changes, the #GdkDevice:n-axes property will be notified, and
* gdk_device_list_axes() will return the new device axes.
*
* Devices may also have associated “keys” or
* macro buttons. Such keys can be globally set to map into normal X
* keyboard events. The mapping is set using gdk_device_set_key().
*
* In GTK+ 3.20, a new #GdkSeat object has been introduced that
* supersedes #GdkDeviceManager and should be preferred in newly
* written code.
*/
static void gdk_device_manager_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void gdk_device_manager_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
G_DEFINE_ABSTRACT_TYPE (GdkDeviceManager, gdk_device_manager, G_TYPE_OBJECT)
enum {
PROP_0,
PROP_DISPLAY
};
enum {
DEVICE_ADDED,
DEVICE_REMOVED,
DEVICE_CHANGED,
LAST_SIGNAL
};
static guint signals [LAST_SIGNAL] = { 0 };
static void
gdk_device_manager_class_init (GdkDeviceManagerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->set_property = gdk_device_manager_set_property;
object_class->get_property = gdk_device_manager_get_property;
g_object_class_install_property (object_class,
PROP_DISPLAY,
g_param_spec_object ("display",
P_("Display"),
P_("Display for the device manager"),
GDK_TYPE_DISPLAY,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
* GdkDeviceManager::device-added:
* @device_manager: the object on which the signal is emitted
* @device: the newly added #GdkDevice.
*
* The ::device-added signal is emitted either when a new master
* pointer is created, or when a slave (Hardware) input device
* is plugged in.
*/
signals [DEVICE_ADDED] =
g_signal_new (g_intern_static_string ("device-added"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GdkDeviceManagerClass, device_added),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GDK_TYPE_DEVICE);
/**
* GdkDeviceManager::device-removed:
* @device_manager: the object on which the signal is emitted
* @device: the just removed #GdkDevice.
*
* The ::device-removed signal is emitted either when a master
* pointer is removed, or when a slave (Hardware) input device
* is unplugged.
*/
signals [DEVICE_REMOVED] =
g_signal_new (g_intern_static_string ("device-removed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GdkDeviceManagerClass, device_removed),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GDK_TYPE_DEVICE);
/**
* GdkDeviceManager::device-changed:
* @device_manager: the object on which the signal is emitted
* @device: the #GdkDevice that changed.
*
* The ::device-changed signal is emitted whenever a device
* has changed in the hierarchy, either slave devices being
* disconnected from their master device or connected to
* another one, or master devices being added or removed
* a slave device.
*
* If a slave device is detached from all master devices
* (gdk_device_get_associated_device() returns %NULL), its
* #GdkDeviceType will change to %GDK_DEVICE_TYPE_FLOATING,
* if it's attached, it will change to %GDK_DEVICE_TYPE_SLAVE.
*/
signals [DEVICE_CHANGED] =
g_signal_new (g_intern_static_string ("device-changed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GdkDeviceManagerClass, device_changed),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GDK_TYPE_DEVICE);
}
static void
gdk_device_manager_init (GdkDeviceManager *device_manager)
{
}
static void
gdk_device_manager_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
switch (prop_id)
{
case PROP_DISPLAY:
GDK_DEVICE_MANAGER (object)->display = g_value_get_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gdk_device_manager_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
switch (prop_id)
{
case PROP_DISPLAY:
g_value_set_object (value, GDK_DEVICE_MANAGER (object)->display);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/**
* gdk_device_manager_get_display:
* @device_manager: a #GdkDeviceManager
*
* Gets the #GdkDisplay associated to @device_manager.
*
* Returns: (nullable) (transfer none): the #GdkDisplay to which
* @device_manager is associated to, or #NULL. This memory is
* owned by GDK and must not be freed or unreferenced.
*
* Since: 3.0
**/
GdkDisplay *
gdk_device_manager_get_display (GdkDeviceManager *device_manager)
{
g_return_val_if_fail (GDK_IS_DEVICE_MANAGER (device_manager), NULL);
return device_manager->display;
}
/**
* gdk_device_manager_list_devices:
* @device_manager: a #GdkDeviceManager
* @type: device type to get.
*
* Returns the list of devices of type @type currently attached to
* @device_manager.
*
* Returns: (transfer container) (element-type Gdk.Device): a list of
* #GdkDevices. The returned list must be
* freed with g_list_free (). The list elements are owned by
* GTK+ and must not be freed or unreffed.
*
* Since: 3.0
*
* Deprecated: 3.20, use gdk_seat_get_pointer(), gdk_seat_get_keyboard()
* and gdk_seat_get_slaves() instead.
**/
GList *
gdk_device_manager_list_devices (GdkDeviceManager *device_manager,
GdkDeviceType type)
{
g_return_val_if_fail (GDK_IS_DEVICE_MANAGER (device_manager), NULL);
return GDK_DEVICE_MANAGER_GET_CLASS (device_manager)->list_devices (device_manager, type);
}

View File

@@ -1,61 +0,0 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2010 Red Hat, Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GDK_DEVICE_MANAGER_PRIVATE_H__
#define __GDK_DEVICE_MANAGER_PRIVATE_H__
#include "gdkdevicemanager.h"
G_BEGIN_DECLS
#define GDK_DEVICE_MANAGER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_MANAGER, GdkDeviceManagerClass))
#define GDK_IS_DEVICE_MANAGER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_MANAGER))
#define GDK_DEVICE_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_MANAGER, GdkDeviceManagerClass))
typedef struct _GdkDeviceManagerClass GdkDeviceManagerClass;
struct _GdkDeviceManager
{
GObject parent_instance;
/*< private >*/
GdkDisplay *display;
};
struct _GdkDeviceManagerClass
{
GObjectClass parent_class;
/* Signals */
void (* device_added) (GdkDeviceManager *device_manager,
GdkDevice *device);
void (* device_removed) (GdkDeviceManager *device_manager,
GdkDevice *device);
void (* device_changed) (GdkDeviceManager *device_manager,
GdkDevice *device);
/* VMethods */
GList * (* list_devices) (GdkDeviceManager *device_manager,
GdkDeviceType type);
GdkDevice * (* get_client_pointer) (GdkDeviceManager *device_manager);
};
G_END_DECLS
#endif

View File

@@ -20,7 +20,6 @@
#include "gdkdevice.h"
#include "gdkdevicetool.h"
#include "gdkdevicemanager.h"
#include "gdkevents.h"
#include "gdkseat.h"
@@ -50,7 +49,6 @@ struct _GdkDevice
gint num_keys;
GdkAxisFlags axis_flags;
GdkDeviceKey *keys;
GdkDeviceManager *manager;
GdkDisplay *display;
/* Paired master for master,
* associated master for slaves

Some files were not shown because too many files have changed in this diff Show More