Compare commits

..

69 Commits

Author SHA1 Message Date
Carlos Garnacho
d94d6e560b gtk,range: Have slider jump to the pointer coordinates on touch devices
This widget is too narrow to make touch interaction tricky enough, so
don't add the penalty of having the slider run farther from the touch
coordinates if it happens to miss the slider.
2012-01-05 02:03:26 +01:00
Carlos Garnacho
33b160569f gtk,scrolledwindow: Ensure the view snaps back when overshooting
Instead of just stopping the acceleration source ID, check whether
it's overshooting, and let it snap back if needed after ::grab-notify
and ::button-release-event
2012-01-05 01:38:16 +01:00
Carlos Garnacho
fd941bd764 gtk,scrolledwindow: set slower inverse acceleration on the overshoot area
This is so snapping back is more fluid and noticeable.
2012-01-05 01:37:13 +01:00
Carlos Garnacho
18e451da6e gtk,scrolledwindow: Improve initial velocity calculation
Velocity calculation has been refactored out of the captured motion events
handler, and also has more tolerance defore determining that a drag is actually
still.
2012-01-05 01:37:13 +01:00
Carlos Garnacho
0e05d33eee gtk,menu: Don't popdown submenus on button release for touch devices
This is so submenus stay open as the parent menu item is pressed/released,
as the user would typically lift the finger in order to select a submenu
item.
2012-01-05 01:37:12 +01:00
Carlos Garnacho
e5b2e528ca gtk,settings: Deprecate gtk-touchscreen-mode
It's not used anywhere in GTK+ anymore.
2012-01-05 01:37:12 +01:00
Carlos Garnacho
355a4cdc14 gtk,range: Remove gtk-touchscreen-mode usage
Emulated crossing events with mode GDK_CROSSING_TOUCH_PRESS/RELEASE
already catter dinamically for the "don't prelight on touch devices"
usecase.
2012-01-05 01:37:12 +01:00
Carlos Garnacho
d45dc8f3c3 gtk,togglebutton: Remove gtk-touchcreen-mode usage
Emulated crossing events with mode GDK_CROSSING_TOUCH_PRESS/RELEASE
already catter dinamically for the "don't prelight on touch devices"
usecase.
2012-01-05 01:37:12 +01:00
Carlos Garnacho
dd8cf478b0 gtk,menushell: Remove gtk-touchscreen-mode usage
This usage in a keybinding signal is hardly related to touchscreens,
so just remove it.
2012-01-05 01:37:12 +01:00
Carlos Garnacho
c33786446c gtk,menu: Remove gtk-touchscreen-mode from scrolling code
scrolling is handled via ::captured-event dynamically, so remove
this now unused code.
2012-01-05 01:37:12 +01:00
Carlos Garnacho
c4b7848aeb gtk,menu: Select the first item for touch devices
This was done through gtk-touchscreen-mode, now is handled
dynamically on the current event source device.
2012-01-05 01:37:12 +01:00
Carlos Garnacho
2d88021014 gtk,menu: Implement scrolling through ::captured-event for touch devices
This makes overflown menus scrollable via direct manipulation. Once past
the threshold, the item below the pointer is unselected and scrolling
starts.
2012-01-05 01:37:12 +01:00
Carlos Garnacho
5cf832da40 gtk,menu: handle item selection for touch devices dynamically
Instead of using gtk-touchscreen-mode, the behavior changes depending
on the source device in use.
2012-01-05 01:37:12 +01:00
Carlos Garnacho
bbbc5198a3 gtk,textview: Pop up context menu on press-and-hold 2012-01-05 01:37:12 +01:00
Carlos Garnacho
2e4eaa7cfd gtk,textview: Also cancel DnD on ::grab-notify
If is about to start when the drag device is grabbed
somewhere else, unset drag start x/y so DnD doesn't
happen anyway.
2012-01-05 01:37:12 +01:00
Carlos Garnacho
07a4c8174f gtk,entry: Pop up menu on press-and-hold 2012-01-05 01:37:12 +01:00
Carlos Garnacho
5f20868ec8 gtk,label: Pop up menu on press-and-hold 2012-01-05 01:37:12 +01:00
Carlos Garnacho
5d2c04b9d1 xi2: Get the effective group state by ORing the XIGroupState values 2012-01-05 01:37:12 +01:00
Carlos Garnacho
62c32d742e gdk: Ensure that GdkPointerWindowInfo is only generated for pointers 2012-01-05 01:37:11 +01:00
Carlos Garnacho
736438ecfb gtk: Only set widget under device on non-virtual crossing events
_gtk_widget_set_device_window() is suppose to make accounting of
the topmost widget under the device at each time, so avoid setting
it on virtual crossing events as the device is already in another
window.
2012-01-05 01:37:11 +01:00
Carlos Garnacho
b02c3cf4a9 gtk,scrolledwindow: remove scrollbars auto-hide
This is in a really sorry state, and scrollbars need to be
thought out for the new design anyway.
2012-01-05 01:37:11 +01:00
Carlos Garnacho
cf4b293b75 gtk,scrolledwindow: capture crossing events when dragging
Also, instead of connecting 2 more times to ::captured-event,
have it all go through a single handler.
2012-01-05 01:37:11 +01:00
Carlos Garnacho
64534d1fc2 gtk,scrolledwindow: Add GtkKineticScrollingFlags
gtk_scrolled_window_set_kinetic_scrolling() now takes a set of flags,
GTK_KINETIC_SCROLLING_CAPTURE_BUTTON_PRESS makes the "capture button
press and maybe replay later" vs "let button press go through, but
trust in ::grab-broken to undo things" an opt-in, by default that
flag is set, which is the most conservative approach.
2012-01-05 01:37:11 +01:00
Carlos Garnacho
380299681a gtk,scrolledwindow: Grab only after starting drag
This is so the grab doesn't break the implicit grab on the
child widget's window, which avoids that the button press and
release are possibly sent to different windows, and after the
grab was actually broken.
2012-01-05 01:37:11 +01:00
Carlos Garnacho
bbe6075408 gdk: Generate crossing events around touch devices' press/release
Anytime a touch device interacts, the crossing events generation
will change to a touch mode where only events with mode
GDK_CROSSING_TOUCH_PRESS/RELEASE are handled, and those are sent
around button press/release. Those are virtual as the master
device may still stay on the window.

Whenever there is a switch of slave device (the user starts
using another non-touch device), a crossing event with mode
GDK_CROSSING_DEVICE_SWITCH may generated if needed, and the normal
crossing event handling is resumed.
2012-01-05 01:37:11 +01:00
Carlos Garnacho
9615fa61a0 gdk: Keep track of the last slave device used
This last slave device (stored per master) is used to fill
in the missing slave device in synthesized crossing events
not directly caused by a device event (ie. due to configure
events or grabs)
2012-01-05 01:37:11 +01:00
Carlos Garnacho
5a0ec9859e gtk,tooltips: Use the source device instead of gtk-touchscreen-mode
This makes tooltips behavior dynamic based on the interacting device.
2012-01-05 01:37:11 +01:00
Carlos Garnacho
03d89b557a gtk,scrolledwindow: Clamp early overshooting when snapping back
Fixes the situation where overshooting in scrolled windows with a
small viewport could end up overshooting right to the opposite
side, and then back again indefinitely.
2012-01-05 01:37:11 +01:00
Carlos Garnacho
d12924f241 gtk: Handle motion hints for ::captured-event
Request automatically more motion events in behalf of
the original widget if it listens to motion hints. So
the capturing widget doesn't need to handle such
implementation details.
2012-01-05 01:37:11 +01:00
Carlos Garnacho
e349e46abd gtk,scrolledwindow: capture motions until the kinetic scrolling cancellation
If the widget which events are captured listens to motion hints, there
are situations where neither the scrolled window or the child widget
request more motions.
2012-01-05 01:37:11 +01:00
Carlos Garnacho
888be799d9 gtk,pah: Show a bigger press-and-hold indicator on touchscreens
On touch devices it uses a 2.5cm diameter via gdk_screen_get_width_mm()
in the hope that it'll pop out of the finger area.
2012-01-05 01:37:11 +01:00
Carlos Garnacho
365a4f7535 gtk,scrolledwindow: Unset dragging device on ::grab-notify
The child widget may still call gtk_(device_)grab_add, which left
the scrolled window in an inconsistent state.
2012-01-05 01:37:10 +01:00
Carlos Garnacho
6468ae821f gtk,scrolledwindow: Rework physics behind kinetic scrolling
The maths being used didn't resemble much about velocities or
friction/deceleration, so reimplement it in terms of velocity
vectors and decelerations, measured in pixels/ms^2.

Overshooting is also handled within the deceleration effect,
turning into a constant acceleration vector in the opposite
direction so it returns elastically within the boundaries.
2012-01-05 01:37:10 +01:00
Carlos Garnacho
4f04075a8f gtk,scrolledwindow: Implement overshooting
An extra GdkWindow has been added, this window is the parent
of the child widget, and is the one getting resized/moved when
overshooting.

The unclamped adjustments' values are also stored in
GtkScrolledWindowPrivate as a separate value, overshooting is
pretty specific to GtkScrolledWindow and it isn't worth to
expose API in GtkAlignment for this single purpose.

This method allows GtkScrollable children to be blissfully
unaware of overshooting, as otherwise they'd have to handle
rather odd adjustment values themselves.
2012-01-05 01:37:10 +01:00
Carlos Garnacho
ae058ae7ef gtk,scrolledwindow: Add window for overshooting
This window is the child widget's parent window, and will
be the one that's moved when overshooting.
2012-01-05 01:37:10 +01:00
Carlos Garnacho
7f0fe69b6e scrolledwindow: Handle nested scrolled windows in kinetic scrolling
The innermost scrolled window always gets to capture the events, all
scrolled windows above it just let the event go through. Ideally
reaching a limit on the innermost scrolled window would propagate
the dragging up the hierarchy in order to keep following the touch
coords, although that'd involve rather evil hacks just to cater
for broken UIs.
2012-01-05 01:37:10 +01:00
Carlos Garnacho
ce879ae739 gtk: Add event storing/replaying to GtkWidget::captured-event
It now returns a GtkCapturedEventFlags which tells whether the
widget captured the event, and additionally whether the event
should be stored for later replay.

gtk_widget_release_captured_events() has been added too so
all stored events are released onto the widget that was initially
to receive the events.
2012-01-05 01:37:10 +01:00
Carlos Garnacho
df2bb4a92d scrolledwindow: Use event times when calculating deceleration
Using g_get_current_time() isn't going to be realistic on lagging
events.
2012-01-05 01:37:10 +01:00
Carlos Garnacho
e45d9994a4 scrolledwindow: bypass kinetic scrolling if no scrollbars are shown 2012-01-05 01:37:10 +01:00
Carlos Garnacho
447ddb08fc scrolledwindow: Remove priv->event_window
It looks like a leftover from pre-captured-event iterations of
the patch, it is completely unnecessary now.
2012-01-05 01:37:10 +01:00
Carlos Garnacho
0df96ac738 scrolledwindow: Don't use p-a-h for the "let event go through" timeout
Just use a timeout there, the press-and-hold feedback is undesirable
here.
2012-01-05 01:37:10 +01:00
Carlos Garnacho
688d8c0796 gtk,pah: Hook directly into gtk_main_do_event()
Press and hold couldn't reasonably work if nested widgets
handle ::captured-event, once the widget inits press-and-hold,
it'd better also handle possible cancellation on motion and
button release, which isn't guaranteed with ::capture-event.

Also, tentatively start press-and-hold by default on the
grab_widget, and before event capturing happens, this avoids
awkward situations like the scrolled window preventing/delaying
press-and-hold to happen on the child textview for example.
2012-01-05 01:37:10 +01:00
Carlos Garnacho
fb7047d212 scrolledwindow: Enable kinetic scrolling by default 2012-01-05 01:37:10 +01:00
Carlos Garnacho
1bb03e26a4 scrolledwindow: add another shortcut to bypass event capture
When clicked again close to the previous button press location
(assuming it had ~0 movement), the scrolled window wil allow
the child to handle the events immediately.

This is so the user doesn't have to wait to the p-a-h timeout
in order to operate on the scrolledwindow child.
2012-01-05 01:37:10 +01:00
Carlos Garnacho
7df706715c scrolledwindow: Only do kinetic scrolling on touch devices
This is sort of meaningless on pointer devices, besides it implies
a different input event handling on child widgets that's unnecessary
there.
2012-01-05 01:37:09 +01:00
Carlos Garnacho
40455db2f5 scrolledwindow: Don't crash on 0-sized motion buffer 2012-01-05 01:37:09 +01:00
Carlos Garnacho
64ec631874 scrolledwindow: Set also a GTK+ grab on p-a-h scrolling
This is so the widget is ensured to receive the events
regardless of the pointer position.
2012-01-05 01:37:09 +01:00
Carlos Garnacho
de593da052 scrolledwindow: Add GdkDevice parameter to ::press-and-hold handler 2012-01-05 01:37:09 +01:00
Carlos Garnacho
a308c35112 gtk: Handle press-and-hold for touch devices
Also, only react to the first button
2012-01-05 01:37:09 +01:00
Carlos Garnacho
412ba5cc2d gtk: Add a GdkDevice parameter to ::press-and-hold
This would be useful when popping up menus, just so we
know what device to trigger it for.
2012-01-05 01:37:09 +01:00
Carlos Garnacho
e4e11aa4a2 gtk: Clean up press-and-hold code
The press and hold animation now fully relies on style context
transitions, finishing the p-a-h operation right after it
finishes. There's also no need to connect to ::drag-begin as
::grab-notify will also tell when a grab begins.
2012-01-05 01:37:09 +01:00
Carlos Garnacho
e48285f759 tests: Add an entry to testpressandhold
Useful for checking behavior while selecting,
starting drags, subwindows...
2012-01-05 01:37:09 +01:00
Carlos Garnacho
dcd2dba384 entry: Handle ::grab-notify
Store the device, and unset private fields whenever the device
is shadowed by another GTK+ grab, so popping up menus while
selecting (i.e. press-and-hold) doesn't leave it in a confused
state.
2012-01-05 01:37:09 +01:00
Carlos Garnacho
1a6a1118a4 gtk: Do not use deprecated APIs on press-and-hold 2012-01-05 01:37:09 +01:00
Carlos Garnacho
d6476eb99a tests: Update testkineticscrolling to use GtkGrid 2012-01-05 01:37:09 +01:00
Carlos Garnacho
cdd97bbff7 gtk: connect to grab-notify for press and hold
This is so press and hold is cancelled if a click actually
causes an inner widget to do a GTK+ grab.
2012-01-05 01:37:09 +01:00
Carlos Garnacho
a447b2fee2 gtk: Propagate ::captured-event up the hierarchy for crossing events 2012-01-05 01:37:09 +01:00
Carlos Garnacho
4af317307f gtk: emit ::captured-event starting from the GTK grab widget 2012-01-05 01:37:09 +01:00
Carlos Garcia Campos
aa0c220f7d scrolledwindow: Allow selections and drag-and-drop when kinetic scrolling is enabled
If the scrolling doesn't start after a long press, the scrolling is
cancelled and events are handled by child widget normally.
2012-01-05 01:37:08 +01:00
Carlos Garcia Campos
39966dbaf8 Add GtkWidget::press-and-hold signal
Press-and-hold signal is emitted when the mouse button is pressed for a
given amount of time, specified in the new "press-and-hold-timeout"
GtkSetting. It's commonly used in mobile platforms to emulate a right
click to show a context menu. This patch is based on previous patches by
Kristian Rietveld and Danielle Madeley.

https://bugzilla.gnome.org/show_bug.cgi?id=315645
2012-01-05 01:37:08 +01:00
Carlos Garnacho
fbb70becef gtksettings: Set animation for press-and-hold through GtkStyleProvider
The "gtk-press-and-hold-timeout" setting has also been added, to control
its duration.
2012-01-05 01:37:08 +01:00
Carlos Garnacho
388dcb4234 themingengine: Implement press-and-hold notification renderer
gtk_render_activity() uses it for the GTK_STYLE_CLASS_PRESS_AND_HOLD
style class.
2012-01-05 01:25:39 +01:00
Carlos Garcia Campos
e8a9fad467 scrolledwindow: Add auto-hide-scrollbars style property
To hide the scrollbars in kinetic mode when not scrolling.
2012-01-05 01:25:38 +01:00
Carlos Garcia Campos
ccb7da408e tests: Add new test for kinetic scrolling 2012-01-05 01:25:38 +01:00
Carlos Garcia Campos
1764558d8c test: Add checkbox to enable/disable kinetic scrolling in scrolled window test 2012-01-05 01:25:38 +01:00
Carlos Garcia Campos
90ee273c66 scrolledwindow: Initial kinetic scrolling support 2012-01-05 01:25:38 +01:00
Carlos Garcia Campos
b0b26cc2e0 timeline: Add _gtk_timeline_get_elapsed_time()
To get the time in milliseconds since the last frame
2012-01-05 01:25:38 +01:00
Carlos Garcia Campos
990e049510 Add GtkWidget::captured-event signal
https://bugzilla.gnome.org/show_bug.cgi?id=641836
2012-01-05 01:25:38 +01:00
Carlos Garnacho
8f013f4055 gdk: Add GDK_SOURCE_TOUCH
This device source applies to touch capable devices, most
notably touchscreens.
2012-01-05 01:25:38 +01:00
519 changed files with 37779 additions and 72134 deletions

View File

@@ -10,7 +10,7 @@ TEST_PROGS =
### testing rules
# Xvfb based test rules
XVFB = Xvfb -ac -noreset -screen 0 1024x768x16
XVFB = Xvfb -ac -noreset -screen 0 800x600x16
XIDS = 101 102 103 104 105 106 107 197 199 211 223 227 293 307 308 309 310 311 \
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 \
991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 \
@@ -29,7 +29,7 @@ endif
XVFB_START = \
${XVFB} -help 2>/dev/null 1>&2 \
&& XID=`for id in $(XIDS) ; do test -e /tmp/.X$$id-lock || { echo $$id; exit 0; }; done; exit 1` \
&& { ${XVFB} :$$XID -nolisten tcp -auth /dev/null >/dev/null 2>&1 & \
&& { ${XVFB} :$$XID -screen 0 800x600x16 -nolisten tcp -auth /dev/null >/dev/null 2>&1 & \
trap "kill -15 $$! " 0 HUP INT QUIT TRAP USR1 PIPE TERM ; } \
|| { echo "Gtk+Tests:ERROR: Failed to start Xvfb environment for X11 target tests."; exit 1; } \
&& DISPLAY=:$$XID && export DISPLAY

143
NEWS
View File

@@ -1,146 +1,3 @@
Overview of Changes in GTK+ 3.3.14
==================================
* Theming
- Fixes for border handling in GtkEntry,
GtkCellRendererText, GtkComboBox
- Parse values more carefully, supporting
percentages, angles
- Implement CSS linear-gradient syntax
- Support background-size
- Support a gtk.gresource file in themes
* Bugs fixed
543520 Cups custom options are not sent properly
649121 Crash in GtkAppChooserDialog packagekit button
669176 Regression: atk-add-key-event-listener doesn't work
* Updated translations
Galician
Norwegian bokmål
Spanish
Overview of Changes in GTK+ 3.3.10
==================================
* GtkApplication:
- Move application menu handling over from GIO
- Fix resize grip positioning in GtkApplicationWindow
* Wayland:
- Make combo boxes work
- Make key modifiers work like on X11
- Make mouse buttons work correctly
* Quartz:
- Make key modifiers work more like they do on X11
* Printing:
- Fix handling of custom cups options
* Accessibility:
- Bring key snooping support back for now
* Translation updates:
Spanish
Overview of Changes in GTK+ 3.3.8
=================================
* GtkApplication:
- Supports logout notification and inhibiting
- Buttons, toolbuttons and switches can now be connected
to GActions
* GtkSpinButton no longer allows to change the value
when not editable
* GtkLabel link support has been rewritten to be be
more robust
* GtkBuilder:
- Supports the 'id' in GtkComboBoxText
- Can parse GVariant-valued properties
- Support loading from a GResource
* GtkImage:
- Support loading from a GResource
* GtkUIManager:
- Support loading from a GResource
* Accessibility:
- key snooping support has been removed
* Wayland backend:
- Cursor handling updates
- Look for cursors in the 'weston' directory
- Make resize grips work
- Implement device grabs
- Implement window geometry hints
- Set surface type based on window type hint
- Add basic clipboard and selection implementations
- Implement client-side keyboard repeat
- Update GdkWindow focus state to match reality
* Theming:
- Improved CSS compliance for selector matching
- Improved CSS compliance for value resolution,
including full support for 'inherit', 'initial',
'currentColor', 'none'
- Support border-style properties
- 'window-unfocused' has been renamed to 'backdrop'
* New deprecations:
- GdkColor
- GtkButton::inner-border
* Miscellaneous:
- Turn default theme css files and dnd cursors into
GResources
* Bugs fixed:
543520 Cups custom options are not sent properly
612396 ...default of entry-text-column for GtkComboBoxText
613728 Rationalize GtkTreeView focus
620240 GNOME Drag & Drop broken for remote X sessions
629878 Missing "Back" and "Forward" icons for Firefox
631414 Add symbolic constants for event emission control
639875 crashes when unparenting a tab from a window...
657367 GtkAction: Hold a reference to proxy widgets
659516 gtk_css_provider_to_string lacks "since" tag
660139 GtkGrid gives Gtk-Warnings about negative sizes when empty
660309 check x11 backend when create xim module
663479 "Finishing" ("Completion") and "Advanced" tabs are empty
665015 "Widget (%s) has more than one label" unwanted warnings
666103 Should be able to match the parent where a dropdown menu...
666600 allocate the CSS border and deprecate GtkButton-inner-border
666685 SIGSEGV in _gtk_tree_selection_internal_select_node
666710 Fix compose sequences disabling other sequences
666842 [patch] "sticky" window state reported wrongly on X11
667018 Fix compilation on Windows
667229 gtkspinbutton: Respect value of inherited 'editable' property
667394 Gtk(Tool)Button: add an 'action-name' property
667473 gdk_rgba_free (NULL)
667485 gdk_rgba_parse error checking
667534 Non-XInput2 build fix
667546 GApplication doc mentions g_application_set_app_menu
667628 GtkWindow:application property should have G_PARAM_CONSTRUCT
667695 GAction leaked in examples/plugman.c
667705 fix up GtkApplication on OS X
666921 Fix the _NET_SUPPORTING_WM_CHECK window fetch to be spec...
* Translation updates:
Arabic
Bulgarian
Finnish
Hebrew
Norwegian bokmål
Spanish
Overview of Changes in GTK+ 3.3.6
=================================

View File

@@ -565,9 +565,7 @@ mkdir $(CopyDir)\share\glib-2.0\schemas
copy ..\..\..\gtk\org.gtk.Settings.FileChooser.gschema.xml $(CopyDir)\share\glib-2.0\schemas
copy ..\..\..\gtk\org.gtk.WindowState.gschema.xml $(CopyDir)\share\glib-2.0\schemas
echo "Compiling gsettings XML Files..."
echo "Compiling gsettings XML File(s)..."
$(CopyDir)\bin\glib-compile-schemas.exe $(CopyDir)\share\glib-2.0\schemas

View File

@@ -339,8 +339,7 @@ copy $(ConfigurationName)\$(PlatformName)\bin\gailutil.lib $(OutDir)\lib
&#
mkdir $(OutDir)\share\glib-2.0\schemas

copy ..\..\..\gtk\org.gtk.Settings.FileChooser.gschema.xml $(OutDir)\share\glib-2.0\schemas

copy ..\..\..\gtk\org.gtk.WindowState.gschema.xml $(OutDir)\share\glib-2.0\schemas

echo "Compiling gsettings XML Files..."

echo "Compiling gsettings XML File(s)..."

$(OutDir)\bin\glib-compile-schemas.exe $(OutDir)\share\glib-2.0\schemas

"
/>

View File

@@ -10,7 +10,7 @@
m4_define([gtk_major_version], [3])
m4_define([gtk_minor_version], [3])
m4_define([gtk_micro_version], [15])
m4_define([gtk_micro_version], [7])
m4_define([gtk_interface_age], [0])
m4_define([gtk_binary_age],
[m4_eval(100 * gtk_minor_version + gtk_micro_version)])
@@ -39,11 +39,11 @@ AC_CONFIG_AUX_DIR([build-aux])
m4_define([gtk_binary_version], [3.0.0])
# required versions of other packages
m4_define([glib_required_version], [2.31.14])
m4_define([glib_required_version], [2.31.6])
m4_define([pango_required_version], [1.29.0])
m4_define([atk_required_version], [2.1.5])
m4_define([cairo_required_version], [1.10.0])
m4_define([gdk_pixbuf_required_version], [2.25.2])
m4_define([gdk_pixbuf_required_version], [2.23.5])
m4_define([introspection_required_version], [0.10.1])
GLIB_REQUIRED_VERSION=glib_required_version
PANGO_REQUIRED_VERSION=pango_required_version
@@ -935,7 +935,7 @@ if test "x$enable_x11_backend" = xyes; then
have_base_x_pc=true
X_PACKAGES="$X_PACKAGES x11 xext"
x_libs="`$PKG_CONFIG --libs x11 xext`"
X_CFLAGS="`$PKG_CONFIG --cflags x11 xext` -DXINPUT2_1_USE_UNSTABLE_PROTOCOL -DXINPUT2_2_USE_UNSTABLE_PROTOCOL"
X_CFLAGS="`$PKG_CONFIG --cflags x11 xext`"
# Strip out any .la files that pkg-config might give us (this happens
# with -uninstalled.pc files)
@@ -1126,10 +1126,6 @@ if test "x$enable_x11_backend" = xyes; then
AC_DEFINE(XINPUT_2, 1, [Define to 1 if XInput 2.0 is available]),
X_EXTENSIONS="$X_EXTENSIONS XInput")
gtk_save_LIBS="$LIBS"
LIBS="$LIBS -lXi"
AC_CHECK_FUNC(XIAllowTouchEvents, AC_DEFINE(XINPUT_2_2, 1, [Define to 1 if XInput 2.2 is available]))
LIBS="$gtk_save_LIBS"
else
AC_DEFINE(XINPUT_NONE, 1,
[Define to 1 if no XInput should be used])
@@ -1533,13 +1529,6 @@ fi
GLIB_GSETTINGS
#############
# Resources #
#############
GLIB_COMPILE_RESOURCES=`$PKG_CONFIG --variable glib_compile_resources gio-2.0`
AC_SUBST(GLIB_COMPILE_RESOURCES)
##################################################
# GObject introspection
##################################################
@@ -1752,14 +1741,12 @@ demos/Makefile
demos/gtk-demo/Makefile
demos/gtk-demo/geninclude.pl
demos/pixbuf-demo/Makefile
demos/widget-factory/Makefile
examples/Makefile
tests/Makefile
tests/a11y/Makefile
tests/css/Makefile
tests/css/parser/Makefile
tests/reftests/Makefile
tests/visuals/Makefile
docs/Makefile
docs/reference/Makefile
docs/reference/gdk/Makefile

18
debian/README.debian vendored Normal file
View File

@@ -0,0 +1,18 @@
libgtk1 for Debian
----------------------
The GIMP Tool Kit (gtk) is a set of widgets to help you program
programs for the X Windowing System easily and powerfully.
gtk is the moving force behind The GNU Image Manipulation Program (The
GIMP) -- the number one freely-available image editing and creation
program available.
gtk is rapidly under development, and the source tree has officially
been separated from The GIMP now, as other teams of programmers
are beginning to write software using its great widget set -- like
GNOME, a desktop interface for X, and gzilla, a freely available
web browser for X.
Ben Gertzfield <che@debian.org>, Mon, 29 Sep 1997 13:11:45 -0700

62
debian/build vendored Executable file
View File

@@ -0,0 +1,62 @@
#!/usr/bin/perl -w
# Adjust debian/changelog and build a new
# Debian package of a CVS archive.
# Written 17 November 1998 by Ben Gertzfield
# <che@debian.org>
# This work is released under the GNU
# General Public License, version 2 or
# later.
use strict;
use diagnostics;
use File::Copy;
my $maintainer = 'Ben Gertzfield <che@debian.org>';
my @date = localtime;
my $datestr = sprintf("%d%.2d%.2d", $date[5] + 1900, $date[4] + 1, $date[3]);
my $revision = '01';
open (CHANGELOG, 'debian/changelog') or die "Couldn't open debian/changelog: $!\n";
$_ = <CHANGELOG>;
chomp;
close CHANGELOG;
my ($package, $last_date, $last_revision) = /^(.*?) \((.*?)\.(.*)?\)/;
if ($last_date eq $datestr) {
$revision = sprintf("%.2d", $last_revision + 1);
}
my $new_version = "$datestr.$revision";
copy('debian/changelog', 'debian/changelog.old') or die "Couldn't copy debian/changelog to debian/changelog.old: $!\n";
open(NEWCHANGELOG, ">debian/changelog") or die "Couldn't open debian/changelog for writing: $!\n";
print NEWCHANGELOG "$package ($new_version) unstable; urgency=low\n\n * CVS snapshot build at " . scalar localtime() . "\n\n -- $maintainer " . `date -R` . "\n";
open(OLDCHANGELOG, "debian/changelog.old") or die "Couldn't open debian/changelog.old: $!\n";
while (<OLDCHANGELOG>) {
print NEWCHANGELOG;
}
close OLDCHANGELOG;
close NEWCHANGELOG;
unlink('debian/changelog.old') or die "Couldn't unlink debian/changelog.old: $!\n";
open(NEWVERSION, '>debian/version') or die "Couldn't open debian/version for writing: $!\n";
print NEWVERSION "$new_version\n";
close NEWVERSION;
system('dpkg-buildpackage -b -rfakeroot -us -uc');
unlink 'debian/version' or die "Couldn't unlink debian/version: $!\n";

10
debian/changelog vendored Normal file
View File

@@ -0,0 +1,10 @@
gtk+-cvs (19981116.01) unstable; urgency=low
* First test build from CVS
-- Ben Gertzfield <che@debian.org> Tue, 17 Nov 1998 12:02:13 -0800
Local variables:
mode: debian-changelog
add-log-mailing-address: "che@debian.org"
End:

81
debian/control vendored Normal file
View File

@@ -0,0 +1,81 @@
Source: gtk+-cvs
Priority: extra
Section: libs
Maintainer: Ben Gertzfield <che@debian.org>
Standards-Version: 2.4.0.0
Package: libgtk-cvs-1.1
Architecture: any
Section: libs
Depends: ${shlibs:Depends}
Conflicts: libgtk-dev (<< 1:1.0.2), libgtk1.1
Description: CVS build of the GIMP Toolkit set of widgets for X
**THIS IS NOT AN OFFICIAL DEBIAN PACKAGE! THIS IS AN AUTOMATED CVS
BUILD OF THE GTK+ LIBRARIES! BEWARE! IT MAY NOT WORK!**
.
The GIMP Toolkit is a freely available set of widgets for X.
GTK is easy to use, and has been implemented in such projects as
The GNU Image Manipulation Program (The GIMP), GNOME, a GNU
desktop set of utilities for X, and gzilla, a GNU web-browser.
.
This is the unstable 1.1 branch of GTK. It is not intended for use
with stable projects!
Package: libgtk-cvs-dev
Architecture: any
Section: devel
Depends: libgtk-cvs-1.1 (=${Source-Version}), libglib-cvs-dev
Suggests: libgtk-cvs-doc
Provides: libgtk1.1-dev
Replaces: libgtk1.1-dev
Conflicts: libgtk-dev, libgtk1 (<< 1:1.0.4), libgtk1.1-dev
Description: CVS build of development files for the GIMP Toolkit
**THIS IS NOT AN OFFICIAL DEBIAN PACKAGE! THIS IS AN AUTOMATED CVS
BUILD OF THE GTK+ LIBRARIES! BEWARE! IT MAY NOT WORK!**
.
This package contains the header files and static libraries for the
GIMP Toolkit set of widgets for X.
.
This is the unstable, 1.1 branch of GTK+. This is not intended for
use with stable releases of programs!
.
Install this package if you wish to develop your own X programs using
the GIMP Toolkit 1.1, or if you wish to compile your own plug-ins for
The GIMP.
Package: libgtk-cvs-doc
Architecture: all
Section: doc
Conflicts: libgtk-dev (<< 1:0.99.4), libgtk-doc, libgtk1.1-doc
Description: CVS build of documentation for the GIMP Toolkit
**THIS IS NOT AN OFFICIAL DEBIAN PACKAGE! THIS IS AN AUTOMATED CVS
BUILD OF THE GTK+ LIBRARIES! BEWARE! IT MAY NOT WORK!**
.
This package contains lots of info-files, HTML docs, FAQs, and
other handy documentation about the GIMP Toolkit set of widgets
for X.
.
This package documents the unstable 1.1 release of the GIMP Toolkit.
.
Install this package if you want to have lots of info about the
GIMP toolkit when you're programming.
Package: libgtk-cvs-dbg
Architecture: any
Section: devel
Depends: libgtk-cvs-1.1 (= ${Source-Version}), libgtk-cvs-dev (= ${Source-Version})
Suggests: libgtk-cvs-doc
Conflicts: libgtk1.1-dbg
Description: CVS build of debugging files for the GIMP Toolkit
**THIS IS NOT AN OFFICIAL DEBIAN PACKAGE! THIS IS AN AUTOMATED CVS
BUILD OF THE GTK+ LIBRARIES! BEWARE! IT MAY NOT WORK!**
.
This package contains the debugging static libraries for the
GIMP Toolkit set of widgets for X.
.
This is the unstable, 1.1 branch of GTK+. This is not intended for
use with stable releases of programs!
.
Install this package if you wish to debug your own X programs using
the GIMP Toolkit 1.1, or if you wish to debug your own plug-ins for
The GIMP.

8
debian/copyright vendored Normal file
View File

@@ -0,0 +1,8 @@
This package was debianized by Ben Gertzfield <che@debian.org> on
Tue, 17 Nov 1998 12:07:17 -0800
It was produced from the CVS repository at cvs.gimp.org.
It may be redistributed under the terms of the GNU LGPL, Version 2 or
later, found on Debian systems in the file /usr/doc/copyright/LGPL.

9
debian/libgtk-cvs-dev.files vendored Normal file
View File

@@ -0,0 +1,9 @@
usr/lib/libgdk.so
usr/lib/libgdk.a
usr/lib/libgtk.so
usr/lib/libgtk.a
usr/include/gdk/
usr/include/gtk/
usr/bin/gtk-config
usr/man/man1/gtk-config.1
usr/share/aclocal/gtk.m4

5
debian/libgtk-cvs-dev.postinst vendored Normal file
View File

@@ -0,0 +1,5 @@
#!/bin/sh
set -e
#DEBHELPER#

6
debian/libgtk-cvs-dev.prerm vendored Normal file
View File

@@ -0,0 +1,6 @@
#!/bin/sh
set -e
install-info --quiet --remove gtk
#DEBHELPER#

8
debian/libgtk-cvs-doc.files vendored Normal file
View File

@@ -0,0 +1,8 @@
usr/info/gdk.info
usr/info/gtk.info
usr/info/gtk.info-1
usr/info/gtk.info-2
usr/info/gtk.info-3
usr/info/gtk.info-4
usr/info/gtk.info-5

11
debian/libgtk-cvs-doc.postinst vendored Normal file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
set -e
install-info --quiet --description="The GIMP Toolkit." \
--section "The GIMP" "The GIMP" /usr/info/gtk.info.gz
install-info --quiet --description="The GIMP Drawing Kit." \
--section "The GIMP" "The GIMP" /usr/info/gdk.info.gz
#DEBHELPER#

7
debian/libgtk-cvs-doc.prerm vendored Normal file
View File

@@ -0,0 +1,7 @@
#!/bin/sh
set -e
install-info --quiet --remove gtk
install-info --quiet --remove gdk
#DEBHELPER#

7
debian/postinst vendored Normal file
View File

@@ -0,0 +1,7 @@
#!/bin/sh
set -e
ldconfig
#DEBHELPER#

160
debian/rules vendored Executable file
View File

@@ -0,0 +1,160 @@
#!/usr/bin/make -f
# debian/rules file for gtk+ Debian package
# written April 1998 by Ben Gertzfield <che@debian.org
build: build-stamp
build-stamp:
dh_testdir
./autogen.sh --prefix=/usr --with-xinput=xfree
$(MAKE)
cd docs && make distdocs
cd ..
touch build-stamp
build-dbg: build-dbg-stamp
build-dbg-stamp:
dh_testdir
./configure --prefix=/usr --with-xinput=xfree --enable-debug=yes
$(MAKE)
touch build-dbg-stamp
clean:
dh_testdir
dh_testroot
rm -f build-stamp build-dbg-stamp install-stamp install-dbg-stamp
# Add here commands to clean up after the build process.
-$(MAKE) clean
cd docs
-$(MAKE) maintainer-clean
cd ..
-$(MAKE) distclean
find . -name '*.o' -o -name '_libs' -o -name '*.lo' -o -name '*.a' -o -name '.deps' | xargs rm -rf
dh_clean
clean-dbg:
dh_testdir
dh_testroot
rm -f build-stamp build-dbg-stamp install-stamp install-dbg-stamp
# Add here commands to clean up after the build process.
-$(MAKE) clean
cd docs
-$(MAKE) maintainer-clean
cd ..
-$(MAKE) distclean
find . -name '*.o' -o -name '_libs' -o -name '*.lo' -o -name '*.a' -o -name '.deps' | xargs rm -rf
dh_clean -k
install: install-stamp
install-stamp: build
dh_testdir
dh_testroot
dh_clean
$(MAKE) prefix=`pwd`/debian/tmp/usr install
touch install-stamp
install-dbg: install-dbg-stamp
install-dbg-stamp: build-dbg
dh_testdir
dh_testroot
dh_clean -k
$(MAKE) prefix=`pwd`/debian/libgtk-cvs-dbg/usr install
touch install-dbg-stamp
# Build architecture-independent files here.
binary-indep: build install libgtk-cvs-doc
# We have nothing to do by default.
# Build architecture-dependent files here.
binary-arch: build install libgtk-cvs-dev libgtk-cvs-1.1 libgtk-cvs-dbg
libgtk-cvs-1.1: build
dh_testdir -plibgtk-cvs-1.1
dh_testroot -plibgtk-cvs-1.1
dh_installdirs -plibgtk-cvs-1.1
# Add here commands to install the files into debian/tmp
rm -rf debian/tmp/usr/bin debian/tmp/usr/include debian/tmp/usr/info debian/tmp/usr/lib/glib debian/tmp/usr/share/aclocal debian/tmp/usr/man debian/tmp/usr/lib/*.la
dh_installdocs -plibgtk-cvs-1.1
dh_installchangelogs -plibgtk-cvs-1.1
dh_strip -plibgtk-cvs-1.1
dh_compress -plibgtk-cvs-1.1
dh_fixperms -plibgtk-cvs-1.1
dh_installdeb -plibgtk-cvs-1.1
dh_shlibdeps -plibgtk-cvs-1.1
dh_gencontrol -plibgtk-cvs-1.1
dh_makeshlibs -plibgtk-cvs-1.1 -V 'libgtk-cvs-1.1 (='`cat debian/version`')'
dh_md5sums -plibgtk-cvs-1.1
dh_builddeb -plibgtk-cvs-1.1
libgtk-cvs-dev: build
dh_testdir -plibgtk-cvs-dev
dh_testroot -plibgtk-cvs-dev
dh_clean -plibgtk-cvs-dev -k
dh_installdirs -plibgtk-cvs-dev
# Add here commands to install the files into debian/tmp
dh_movefiles -plibgtk-cvs-dev
cp gtk-config debian/tmp/usr/bin
dh_installdocs -plibgtk-cvs-dev
dh_installchangelogs -plibgtk-cvs-dev
dh_strip -plibgtk-cvs-dev
dh_compress -plibgtk-cvs-dev
dh_fixperms -plibgtk-cvs-dev
dh_installdeb -plibgtk-cvs-dev
dh_shlibdeps -plibgtk-cvs-dev
dh_gencontrol -plibgtk-cvs-dev
dh_md5sums -plibgtk-cvs-dev
dh_builddeb -plibgtk-cvs-dev
libgtk-cvs-doc:
dh_testdir -plibgtk-cvs-doc
dh_testroot -plibgtk-cvs-doc
dh_clean -plibgtk-cvs-doc -k
dh_installdirs -plibgtk-cvs-doc usr/doc/libgtk-cvs-doc/faq-html \
usr/doc/libgtk-cvs-doc/tutorial-html usr/doc/libgtk-cvs-doc/italian-tutorial-html usr/doc/libgtk-cvs-doc/french-tutorial-html usr/doc/libgtk-cvs-doc/gdk-html
dh_movefiles -plibgtk-cvs-doc
cp docs/html/gtkfaq*.html debian/libgtk-cvs-doc/usr/doc/libgtk-cvs-doc/faq-html
cp docs/html/gtk_tut-*.html debian/libgtk-cvs-doc/usr/doc/libgtk-cvs-doc/tutorial-html
cp docs/html/*.gif debian/libgtk-cvs-doc/usr/doc/libgtk-cvs-doc/tutorial-html
cp docs/html/gtk_tut.html debian/libgtk-cvs-doc/usr/doc/libgtk-cvs-doc/tutorial-html
cp docs/html/gtk_tut_it*.html debian/libgtk-cvs-doc/usr/doc/libgtk-cvs-doc/italian-tutorial-html
cp docs/html/*.gif debian/libgtk-cvs-doc/usr/doc/libgtk-cvs-doc/italian-tutorial-html
cp docs/html/gtk_tut_fr*.html debian/libgtk-cvs-doc/usr/doc/libgtk-cvs-doc/french-tutorial-html
cp docs/html/*.gif debian/libgtk-cvs-doc/usr/doc/libgtk-cvs-doc/french-tutorial-html
cp docs/html/gdk* debian/libgtk-cvs-doc/usr/doc/libgtk-cvs-doc/gdk-html
cp docs/text/*.txt debian/libgtk-cvs-doc/usr/doc/libgtk-cvs-doc/
dh_installdocs -plibgtk-cvs-doc docs/{debugging,developers,styles,text_widget,widget_system,gtk-config,refcounting}.txt TODO NEWS
dh_installchangelogs -plibgtk-cvs-doc
dh_strip -plibgtk-cvs-doc
dh_compress -plibgtk-cvs-doc
dh_fixperms -plibgtk-cvs-doc
dh_installdeb -plibgtk-cvs-doc
dh_shlibdeps -plibgtk-cvs-doc
dh_gencontrol -plibgtk-cvs-doc
dh_md5sums -plibgtk-cvs-doc
dh_builddeb -plibgtk-cvs-doc
libgtk-cvs-dbg: clean-dbg install-dbg
dh_testdir -plibgtk-cvs-dbg
dh_testroot -plibgtk-cvs-dbg
dh_installdirs -plibgtk-cvs-dbg
# Add here commands to install the files into debian/libgtk-cvs-dbg
rm -rf debian/libgtk-cvs-dbg/usr/bin debian/libgtk-cvs-dbg/usr/include debian/libgtk-cvs-dbg/usr/info debian/libgtk-cvs-dbg/usr/lib/glib debian/libgtk-cvs-dbg/usr/man debian/libgtk-cvs-dbg/usr/share debian/libgtk-cvs-dbg/usr/lib/*.{la,so*}
for file in `find debian/libgtk-cvs-dbg/usr/lib -name '*.a'` ; do \
mv $$file debian/libgtk-cvs-dbg/usr/lib/`basename $$file .a`_g.a; \
done
dh_installdocs -plibgtk-cvs-dbg
dh_installchangelogs -plibgtk-cvs-dbg
dh_compress -plibgtk-cvs-dbg
dh_fixperms -plibgtk-cvs-dbg
dh_installdeb -plibgtk-cvs-dbg
dh_shlibdeps -plibgtk-cvs-dbg
dh_gencontrol -plibgtk-cvs-dbg
dh_md5sums -plibgtk-cvs-dbg
dh_builddeb -plibgtk-cvs-dbg
source diff:
@echo >&2 'source and diff are obsolete - use dpkg-source -b'; false
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary

View File

@@ -1,6 +1,6 @@
## Makefile.am for gtk+/demos
include $(top_srcdir)/Makefile.decl
SUBDIRS = gtk-demo widget-factory pixbuf-demo
SUBDIRS = gtk-demo pixbuf-demo
-include $(top_srcdir)/git.mk

View File

@@ -6,7 +6,6 @@ democodedir=$(datadir)/gtk-$(GTK_API_VERSION)/demo
## These should be in the order you want them to appear in the
## demo app, which means alphabetized by demo title, not filename
demos = \
application.c \
appwindow.c \
assistant.c \
builder.c \
@@ -29,7 +28,6 @@ demos = \
links.c \
list_store.c \
menus.c \
multitouch.c \
offscreen_window.c \
offscreen_window2.c \
overlay.c \
@@ -67,24 +65,13 @@ LDADDS = \
$(GTK_DEP_LIBS) \
-lm
bin_PROGRAMS = gtk3-demo gtk3-demo-application
bin_PROGRAMS = gtk3-demo
BUILT_SOURCES = demos.h application_resources.c
BUILT_SOURCES = demos.h
EXTRA_DIST += \
$(IMAGEFILES) \
demo.ui \
application.gresource.xml \
application.ui \
menus.ui \
gtk-logo-24.png \
gtk-logo-48.png \
org.gtk.Demo.gschema.xml
gsettings_SCHEMAS = \
org.gtk.Demo.gschema.xml
@GSETTINGS_RULES@
EXTRA_DIST += \
$(IMAGEFILES) \
demo.ui
demos.h: @REBUILD@ $(demos) geninclude.pl
$(AM_V_GEN) (here=`pwd` ; cd $(srcdir) && $(PERL) $$here/geninclude.pl $(demos)) > demos.h
@@ -99,17 +86,8 @@ gtk3_demo_DEPENDENCIES = $(DEPS)
gtk3_demo_LDADD = $(LDADDS)
gtk3_demo_LDFLAGS = -export-dynamic
gtk3_demo_application_SOURCES = \
application-standalone.c \
application_resources.c
gtk3_demo_application_LDADD = $(LDADDS)
application_resources.c: application.gresource.xml gtk-logo-24.png gtk-logo-48.png application.ui menus.ui
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --generate-source $(srcdir)/application.gresource.xml
IMAGEFILES= alphatest.png \
apple-red.png \
apple-red.png \
background.jpg \
floppybuddy.gif \
gnome-applets.png \

View File

@@ -1,3 +0,0 @@
#define STANDALONE
#include "application.c"

View File

@@ -1,479 +0,0 @@
/* Application class
*
* Demonstrates a simple application.
*
* This examples uses GtkApplication, GtkApplicationWindow, GtkBuilder
* as well as GMenu and GResource. Due to the way GtkApplication is structured,
* it is run as a separate process.
*/
#include "config.h"
#include <gtk/gtk.h>
#ifdef STANDALONE
static void
show_action_dialog (GSimpleAction *action)
{
const gchar *name;
GtkWidget *dialog;
name = g_action_get_name (G_ACTION (action));
dialog = gtk_message_dialog_new (NULL,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
GTK_BUTTONS_CLOSE,
"You activated action: \"%s\"",
name);
g_signal_connect (dialog, "response",
G_CALLBACK (gtk_widget_destroy), NULL);
gtk_widget_show (dialog);
}
static void
show_action_infobar (GSimpleAction *action,
GVariant *parameter,
gpointer window)
{
GtkWidget *infobar;
GtkWidget *message;
gchar *text;
const gchar *name;
const gchar *value;
name = g_action_get_name (G_ACTION (action));
value = g_variant_get_string (parameter, NULL);
message = g_object_get_data (G_OBJECT (window), "message");
infobar = g_object_get_data (G_OBJECT (window), "infobar");
text = g_strdup_printf ("You activated radio action: \"%s\".\n"
"Current value: %s", name, value);
gtk_label_set_text (GTK_LABEL (message), text);
gtk_widget_show (infobar);
g_free (text);
}
static void
activate_action (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
show_action_dialog (action);
}
static void
activate_toggle (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GVariant *state;
show_action_dialog (action);
state = g_action_get_state (G_ACTION (action));
g_action_change_state (G_ACTION (action), g_variant_new_boolean (!g_variant_get_boolean (state)));
g_variant_unref (state);
}
static void
activate_radio (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
show_action_infobar (action, parameter, user_data);
g_action_change_state (G_ACTION (action), parameter);
}
static void
activate_about (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GtkWidget *window = user_data;
GdkPixbuf *pixbuf;
const gchar *authors[] = {
"Peter Mattis",
"Spencer Kimball",
"Josh MacDonald",
"and many more...",
NULL
};
const gchar *documentors[] = {
"Owen Taylor",
"Tony Gale",
"Matthias Clasen <mclasen@redhat.com>",
"and many more...",
NULL
};
pixbuf = gdk_pixbuf_new_from_resource ("/logos/gtk-logo-48.png", NULL);
gtk_show_about_dialog (GTK_WINDOW (window),
"program-name", "GTK+ Code Demos",
"version", g_strdup_printf ("%s,\nRunning against GTK+ %d.%d.%d",
PACKAGE_VERSION,
gtk_get_major_version (),
gtk_get_minor_version (),
gtk_get_micro_version ()),
"copyright", "(C) 1997-2009 The GTK+ Team",
"license-type", GTK_LICENSE_LGPL_2_1,
"website", "http://www.gtk.org",
"comments", "Program to demonstrate GTK+ functions.",
"authors", authors,
"documenters", documentors,
"logo", pixbuf,
"title", "About GTK+ Code Demos",
NULL);
g_object_unref (pixbuf);
}
static void
activate_quit (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GtkApplication *app = user_data;
GtkWidget *win;
GList *list, *next;
list = gtk_application_get_windows (app);
while (list)
{
win = list->data;
next = list->next;
gtk_widget_destroy (GTK_WIDGET (win));
list = next;
}
}
static void
register_stock_icons (void)
{
static gboolean registered = FALSE;
if (!registered)
{
GdkPixbuf *pixbuf;
GtkIconFactory *factory;
GtkIconSet *icon_set;
static GtkStockItem items[] = {
{ "demo-gtk-logo", "_GTK!", 0, 0, NULL }
};
registered = TRUE;
gtk_stock_add (items, G_N_ELEMENTS (items));
factory = gtk_icon_factory_new ();
gtk_icon_factory_add_default (factory);
pixbuf = gdk_pixbuf_new_from_resource ("/logos/gtk-logo-24.png", NULL);
icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
gtk_icon_factory_add (factory, "demo-gtk-logo", icon_set);
gtk_icon_set_unref (icon_set);
g_object_unref (pixbuf);
/* Drop our reference to the factory, GTK will hold a reference. */
g_object_unref (factory);
}
}
static void
update_statusbar (GtkTextBuffer *buffer,
GtkStatusbar *statusbar)
{
gchar *msg;
gint row, col;
gint count;
GtkTextIter iter;
/* clear any previous message, underflow is allowed */
gtk_statusbar_pop (statusbar, 0);
count = gtk_text_buffer_get_char_count (buffer);
gtk_text_buffer_get_iter_at_mark (buffer,
&iter,
gtk_text_buffer_get_insert (buffer));
row = gtk_text_iter_get_line (&iter);
col = gtk_text_iter_get_line_offset (&iter);
msg = g_strdup_printf ("Cursor at row %d column %d - %d chars in document",
row, col, count);
gtk_statusbar_push (statusbar, 0, msg);
g_free (msg);
}
static void
mark_set_callback (GtkTextBuffer *buffer,
const GtkTextIter *new_location,
GtkTextMark *mark,
gpointer data)
{
update_statusbar (buffer, GTK_STATUSBAR (data));
}
static void
change_theme_state (GSimpleAction *action,
GVariant *state,
gpointer user_data)
{
GtkSettings *settings = gtk_settings_get_default ();
g_object_set (G_OBJECT (settings),
"gtk-application-prefer-dark-theme",
g_variant_get_boolean (state),
NULL);
g_simple_action_set_state (action, state);
}
static void
change_titlebar_state (GSimpleAction *action,
GVariant *state,
gpointer user_data)
{
GtkWindow *window = user_data;
gtk_window_set_hide_titlebar_when_maximized (GTK_WINDOW (window),
g_variant_get_boolean (state));
g_simple_action_set_state (action, state);
}
static void
change_radio_state (GSimpleAction *action,
GVariant *state,
gpointer user_data)
{
g_simple_action_set_state (action, state);
}
static GActionEntry app_entries[] = {
{ "new", activate_action, NULL, NULL, NULL },
{ "open", activate_action, NULL, NULL, NULL },
{ "save", activate_action, NULL, NULL, NULL },
{ "save-as", activate_action, NULL, NULL, NULL },
{ "quit", activate_quit, NULL, NULL, NULL },
{ "dark", activate_toggle, NULL, "false", change_theme_state }
};
static GActionEntry win_entries[] = {
{ "titlebar", activate_toggle, NULL, "false", change_titlebar_state },
{ "shape", activate_radio, "s", "'oval'", change_radio_state },
{ "bold", activate_toggle, NULL, "false", NULL },
{ "about", activate_about, NULL, NULL, NULL },
{ "file1", activate_action, NULL, NULL, NULL },
{ "logo", activate_action, NULL, NULL, NULL }
};
static void
clicked_cb (GtkWidget *widget, GtkWidget *info)
{
gtk_widget_hide (info);
}
static void
startup (GApplication *app)
{
GtkBuilder *builder;
GMenuModel *appmenu;
GMenuModel *menubar;
builder = gtk_builder_new ();
gtk_builder_add_from_resource (builder, "/ui/menus.ui", NULL);
appmenu = (GMenuModel *)gtk_builder_get_object (builder, "appmenu");
menubar = (GMenuModel *)gtk_builder_get_object (builder, "menubar");
gtk_application_set_app_menu (GTK_APPLICATION (app), appmenu);
gtk_application_set_menubar (GTK_APPLICATION (app), menubar);
g_object_unref (builder);
}
static void
activate (GApplication *app)
{
GtkBuilder *builder;
GtkWidget *window;
GtkWidget *grid;
GtkWidget *contents;
GtkWidget *status;
GtkWidget *message;
GtkWidget *button;
GtkWidget *infobar;
GtkWidget *menutool;
GMenuModel *toolmenu;
GtkTextBuffer *buffer;
window = gtk_application_window_new (GTK_APPLICATION (app));
gtk_window_set_title (GTK_WINDOW (window), "Application Class");
gtk_window_set_icon_name (GTK_WINDOW (window), "document-open");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
g_action_map_add_action_entries (G_ACTION_MAP (window),
win_entries, G_N_ELEMENTS (win_entries),
window);
builder = gtk_builder_new ();
gtk_builder_add_from_resource (builder, "/ui/application.ui", NULL);
grid = (GtkWidget *)gtk_builder_get_object (builder, "grid");
contents = (GtkWidget *)gtk_builder_get_object (builder, "contents");
status = (GtkWidget *)gtk_builder_get_object (builder, "status");
message = (GtkWidget *)gtk_builder_get_object (builder, "message");
button = (GtkWidget *)gtk_builder_get_object (builder, "button");
infobar = (GtkWidget *)gtk_builder_get_object (builder, "infobar");
menutool = (GtkWidget *)gtk_builder_get_object (builder, "menutool");
toolmenu = (GMenuModel *)gtk_builder_get_object (builder, "toolmenu");
g_object_set_data (G_OBJECT (window), "message", message);
g_object_set_data (G_OBJECT (window), "infobar", infobar);
gtk_container_add (GTK_CONTAINER (window), grid);
gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (menutool),
gtk_menu_new_from_model (toolmenu));
gtk_widget_grab_focus (contents);
g_signal_connect (button, "clicked", G_CALLBACK (clicked_cb), infobar);
/* Show text widget info in the statusbar */
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (contents));
g_signal_connect_object (buffer, "changed",
G_CALLBACK (update_statusbar), status, 0);
g_signal_connect_object (buffer, "mark-set",
G_CALLBACK (mark_set_callback), status, 0);
update_statusbar (buffer, GTK_STATUSBAR (status));
gtk_widget_show_all (window);
g_object_unref (builder);
}
int
main (int argc, char *argv[])
{
GtkApplication *app;
GSettings *settings;
GAction *action;
gtk_init (NULL, NULL);
register_stock_icons ();
app = gtk_application_new ("org.gtk.Demo", 0);
settings = g_settings_new ("org.gtk.Demo");
g_action_map_add_action_entries (G_ACTION_MAP (app),
app_entries, G_N_ELEMENTS (app_entries),
app);
action = g_settings_create_action (settings, "color");
g_action_map_add_action (G_ACTION_MAP (app), action);
g_signal_connect (app, "startup", G_CALLBACK (startup), NULL);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
g_application_run (G_APPLICATION (app), 0, NULL);
return 0;
}
#else /* !STANDALONE */
static gboolean name_seen;
static GtkWidget *placeholder;
static void
on_name_appeared (GDBusConnection *connection,
const gchar *name,
const gchar *name_owner,
gpointer user_data)
{
name_seen = TRUE;
}
static void
on_name_vanished (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
if (!name_seen)
return;
if (placeholder)
{
gtk_widget_destroy (placeholder);
g_object_unref (placeholder);
placeholder = NULL;
}
}
GtkWidget *
do_application (GtkWidget *toplevel)
{
static guint watch = 0;
if (watch == 0)
watch = g_bus_watch_name (G_BUS_TYPE_SESSION,
"org.gtk.Demo",
0,
on_name_appeared,
on_name_vanished,
NULL, NULL);
if (placeholder == NULL)
{
const gchar *command;
GError *error = NULL;
if (g_file_test ("./gtk3-demo-application", G_FILE_TEST_IS_EXECUTABLE))
command = "./gtk3-demo-application";
else
command = "gtk3-demo-application";
if (!g_spawn_command_line_async (command, &error))
{
g_warning ("%s", error->message);
g_error_free (error);
}
placeholder = gtk_label_new ("");
g_object_ref_sink (placeholder);
}
else
{
g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL),
"org.gtk.Demo",
"/org/gtk/Demo",
"org.gtk.Actions",
"Activate",
g_variant_new ("(sava{sv})", "quit", NULL, NULL),
NULL,
0,
G_MAXINT,
NULL, NULL);
}
return placeholder;
}
#endif

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/logos">
<file preprocess="to-pixdata">gtk-logo-24.png</file>
<file preprocess="to-pixdata">gtk-logo-48.png</file>
</gresource>
<gresource prefix="/ui">
<file preprocess="xml-stripblanks">application.ui</file>
<file preprocess="xml-stripblanks">menus.ui</file>
</gresource>
</gresources>

View File

@@ -1,104 +0,0 @@
<?xml version="1.0"?>
<interface>
<object class="GtkGrid" id="grid">
<child>
<object class="GtkToolbar" id="toolbar">
<property name="orientation">horizontal</property>
<property name="halign">fill</property>
<property name="hexpand">True</property>
<child>
<object class="GtkMenuToolButton" id="menutool">
<property name="stock-id">gtk-open</property>
</object>
</child>
<child>
<object class="GtkToolButton" id="quit">
<property name="stock-id">gtk-quit</property>
<property name="action-name">app.quit</property>
</object>
</child>
<child>
<object class="GtkSeparatorToolItem" id="sep"/>
</child>
<child>
<object class="GtkToolButton" id="logo">
<property name="stock-id">demo-gtk-logo</property>
<property name="action-name">win.logo</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkInfoBar" id="infobar">
<property name="no-show-all">True</property>
<property name="halign">fill</property>
<property name="hexpand">True</property>
<child internal-child="content_area">
<object class="GtkBox" id="content_area">
<child>
<object class="GtkLabel" id="message">
<property name="visible">True</property>
<property name="hexpand">True</property>
<property name="halign">fill</property>
</object>
</child>
</object>
</child>
<child internal-child="action_area">
<object class="GtkBox" id="action_area">
<child>
<object class="GtkButton" id="button">
<property name="visible">True</property>
<property name="valign">center</property>
<property name="label">gtk-ok</property>
<property name="use-stock">True</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="sw">
<property name="shadow-type">in</property>
<child>
<object class="GtkTextView" id="contents">
<property name="halign">fill</property>
<property name="valign">fill</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
</packing>
</child>
<child>
<object class="GtkStatusbar" id="status">
<property name="halign">fill</property>
<property name="hexpand">True</property>
<property name="visible">True</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
</packing>
</child>
</object>
<menu id="toolmenu">
<item>
<attribute name="label">File1</attribute>
<attribute name="action">win.file1</attribute>
</item>
</menu>
</interface>

View File

@@ -1,8 +1,6 @@
/* Application window
/* Application main window
*
* Demonstrates a typical application window with menubar, toolbar, statusbar.
*
* This example uses GtkUIManager and GtkActionGroup.
*/
#include <gtk/gtk.h>

View File

@@ -23,14 +23,14 @@ apply_changes_gradually (gpointer data)
if (fraction < 1.0)
{
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress_bar), fraction);
return G_SOURCE_CONTINUE;
return TRUE;
}
else
{
/* Close automatically once changes are fully applied. */
gtk_widget_destroy (assistant);
assistant = NULL;
return G_SOURCE_REMOVE;
return FALSE;
}
}

View File

@@ -172,7 +172,7 @@ button_press (GtkWidget *widget,
GtkWidget *menu;
GtkWidget *item;
if (button->button != GDK_BUTTON_SECONDARY)
if (button->button != 3)
return FALSE;
menu = gtk_menu_new ();

View File

@@ -36,17 +36,26 @@ change_color_callback (GtkWidget *button,
{
GtkWidget *dialog;
GtkColorSelection *colorsel;
GtkColorChooserDialog *selection_dialog;
GtkColorSelectionDialog *selection_dialog;
gint response;
dialog = gtk_color_chooser_dialog_new ("Changing color", GTK_WINDOW (window));
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (dialog), &color);
dialog = gtk_color_selection_dialog_new ("Changing color");
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window));
selection_dialog = GTK_COLOR_SELECTION_DIALOG (dialog);
colorsel = GTK_COLOR_SELECTION (gtk_color_selection_dialog_get_color_selection (selection_dialog));
gtk_color_selection_set_previous_rgba (colorsel, &color);
gtk_color_selection_set_current_rgba (colorsel, &color);
gtk_color_selection_set_has_palette (colorsel, TRUE);
response = gtk_dialog_run (GTK_DIALOG (dialog));
if (response == GTK_RESPONSE_OK)
{
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (dialog), &color);
gtk_color_selection_get_current_rgba (colorsel, &color);
gtk_widget_override_background_color (da, 0, &color);
}

View File

@@ -97,7 +97,7 @@ scribble_button_press_event (GtkWidget *widget,
if (surface == NULL)
return FALSE; /* paranoia check, in case we haven't gotten a configure event */
if (event->button == GDK_BUTTON_PRIMARY)
if (event->button == 1)
draw_brush (widget, event->x, event->y);
/* We've handled the event, stop processing */

View File

@@ -116,7 +116,7 @@ if (defined @child_arrays) {
}
# toplevel
print "\nDemo gtk_demos[] = {\n";
print "\nDemo testgtk_demos[] = {\n";
$first = 1;
foreach $href (@demos) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 674 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -144,7 +144,7 @@ event_after (GtkWidget *text_view,
event = (GdkEventButton *)ev;
if (event->button != GDK_BUTTON_PRIMARY)
if (event->button != 1)
return FALSE;
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));

View File

@@ -63,13 +63,7 @@ do_links (GtkWidget *do_widget)
label = gtk_label_new ("Some <a href=\"http://en.wikipedia.org/wiki/Text\""
"title=\"plain text\">text</a> may be marked up\n"
"as hyperlinks, which can be clicked\n"
"or activated via <a href=\"keynav\">keynav</a>\n"
"and they work fine with other markup, like when\n"
"searching on <a href=\"http://www.google.com/\">"
"<span color=\"#0266C8\">G</span><span color=\"#F90101\">o</span>"
"<span color=\"#F2B50F\">o</span><span color=\"#0266C8\">g</span>"
"<span color=\"#00933B\">l</span><span color=\"#F90101\">e</span>"
"</a>.");
"or activated via <a href=\"keynav\">keynav</a>");
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
g_signal_connect (label, "activate-link", G_CALLBACK (activate_link), NULL);
gtk_container_add (GTK_CONTAINER (window), label);

View File

@@ -60,7 +60,7 @@ spinner_timeout (gpointer data)
guint pulse;
if (model == NULL)
return G_SOURCE_REMOVE;
return FALSE;
gtk_tree_model_get_iter_first (model, &iter);
gtk_tree_model_get (model, &iter,
@@ -77,7 +77,7 @@ spinner_timeout (gpointer data)
COLUMN_ACTIVE, TRUE,
-1);
return G_SOURCE_CONTINUE;
return TRUE;
}
static GtkTreeModel *

View File

@@ -782,7 +782,7 @@ create_tree (void)
GtkTreeIter iter;
GtkWidget *box, *label, *scrolled_window;
Demo *d = gtk_demos;
Demo *d = testgtk_demos;
model = gtk_tree_store_new (NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_INT);
tree_view = gtk_tree_view_new ();
@@ -936,8 +936,10 @@ main (int argc, char **argv)
* these few lines, which are just a hack so gtk-demo will work
* in the GTK tree without installing it.
*/
if (g_file_test ("../../modules/input/immodules.cache", G_FILE_TEST_EXISTS))
if (g_file_test ("../../gdk-pixbuf/libpixbufloader-pnm.la",
G_FILE_TEST_EXISTS))
{
g_setenv ("GDK_PIXBUF_MODULE_FILE", "../../gdk-pixbuf/loaders.cache", TRUE);
g_setenv ("GTK_IM_MODULE_FILE", "../../modules/input/immodules.cache", TRUE);
}
/* -- End of hack -- */
@@ -1000,7 +1002,7 @@ main (int argc, char **argv)
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
gtk_widget_show_all (window);
load_file (gtk_demos[0].filename);
load_file (testgtk_demos[0].filename);
gtk_main ();

View File

@@ -1,107 +0,0 @@
<?xml version="1.0"?>
<interface>
<menu id="appmenu">
<section>
<item>
<attribute name="label" translatable="yes">_New</attribute>
<attribute name="action">app.new</attribute>
<attribute name="accel">&lt;Primary&gt;n</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Open</attribute>
<attribute name="action">app.open</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Save</attribute>
<attribute name="action">app.save</attribute>
<attribute name="accel">&lt;Primary&gt;s</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Save _As...</attribute>
<attribute name="action">app.save-as</attribute>
<attribute name="accel">&lt;Primary&gt;s</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Quit</attribute>
<attribute name="action">app.quit</attribute>
<attribute name="accel">&lt;Primary&gt;q</attribute>
</item>
</section>
</menu>
<menu id="menubar">
<submenu>
<attribute name="label" translatable="yes">_Preferences</attribute>
<section>
<item>
<attribute name="label" translatable="yes">_Prefer Dark Theme</attribute>
<attribute name="action">app.dark</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Hide Titlebar when maximized</attribute>
<attribute name="action">win.titlebar</attribute>
</item>
<submenu>
<attribute name="label" translatable="yes">_Color</attribute>
<section>
<item>
<attribute name="label" translatable="yes">_Red</attribute>
<attribute name="action">app.color</attribute>
<attribute name="target">red</attribute>
<attribute name="accel">&lt;Primary&gt;r</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Green</attribute>
<attribute name="action">app.color</attribute>
<attribute name="target">green</attribute>
<attribute name="accel">&lt;Primary&gt;g</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Blue</attribute>
<attribute name="action">app.color</attribute>
<attribute name="target">blue</attribute>
<attribute name="accel">&lt;Primary&gt;b</attribute>
</item>
</section>
</submenu>
<submenu>
<attribute name="label" translatable="yes">_Shape</attribute>
<section>
<item>
<attribute name="label" translatable="yes">_Square</attribute>
<attribute name="action">win.shape</attribute>
<attribute name="target">square</attribute>
<attribute name="accel">&lt;Primary&gt;s</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Rectangle</attribute>
<attribute name="action">win.shape</attribute>
<attribute name="target">rectangle</attribute>
<attribute name="accel">&lt;Primary&gt;r</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Oval</attribute>
<attribute name="action">win.shape</attribute>
<attribute name="target">oval</attribute>
<attribute name="accel">&lt;Primary&gt;o</attribute>
</item>
</section>
</submenu>
<item>
<attribute name="label" translatable="yes">_Bold</attribute>
<attribute name="action">win.bold</attribute>
<attribute name="accel">&lt;Primary&gt;b</attribute>
</item>
</section>
</submenu>
<submenu>
<attribute name="label" translatable="yes">_Help</attribute>
<item>
<attribute name="label" translatable="yes">_About</attribute>
<attribute name="action">win.about</attribute>
<attribute name="accel">&lt;Primary&gt;a</attribute>
</item>
</submenu>
</menu>
</interface>

View File

@@ -1,698 +0,0 @@
/* Multitouch
*
* Demonstrates some general multitouch event handling,
* using GdkTouchCluster in order to get grouped motion
* events for the touches within a cluster. Each of the
* created rectangles has one of those GdkTouchCluster
* objects.
*
* Touch events are also enabled on additional widgets,
* enabling simultaneous touch interaction on those. Not
* all widgets are prepared for multitouch interaction,
* as there are constraints that not all widgets may
* apply to.
*/
#include <math.h>
#include <gtk/gtk.h>
#include "demo-common.h"
#define RECT_BORDER_WIDTH 6
static GtkWidget *window = NULL;
static GtkWidget *area = NULL;
static GtkWidget *red = NULL;
static GtkWidget *green = NULL;
static GtkWidget *blue = NULL;
static GtkWidget *alpha = NULL;
static GQueue *shapes = NULL;
typedef struct {
GdkTouchCluster *cluster;
GdkRGBA color;
gdouble angle;
gdouble zoom;
gdouble center_x;
gdouble center_y;
gdouble x;
gdouble y;
gdouble width;
gdouble height;
gdouble base_zoom;
gdouble base_angle;
gdouble initial_distance;
gdouble initial_angle;
GdkPoint points[4];
} ShapeInfo;
static void
calculate_rotated_point (gdouble angle,
gdouble zoom,
gdouble center_x,
gdouble center_y,
gdouble point_x,
gdouble point_y,
gdouble *ret_x,
gdouble *ret_y)
{
gdouble distance, xd, yd, ang;
if (angle == 0)
{
*ret_x = point_x;
*ret_y = point_y;
return;
}
xd = center_x - point_x;
yd = center_y - point_y;
if (xd == 0 && yd == 0)
{
*ret_x = center_x;
*ret_y = center_y;
return;
}
distance = sqrt ((xd * xd) + (yd * yd));
distance *= zoom;
ang = atan2 (xd, yd);
/* Invert angle */
ang = (2 * G_PI) - ang;
/* Shift it 270° */
ang += 3 * (G_PI / 2);
/* And constraint it to 0°-360° */
ang = fmod (ang, 2 * G_PI);
ang += angle;
*ret_x = center_x + (distance * cos (ang));
*ret_y = center_y + (distance * sin (ang));
}
static void
shape_info_allocate_input_rect (ShapeInfo *info)
{
gint width, height, i;
width = info->width;
height = info->height;
/* Top/left */
info->points[0].x = info->x - info->center_x;
info->points[0].y = info->y - info->center_y;
/* Top/right */
info->points[1].x = info->x - info->center_x + width;
info->points[1].y = info->y - info->center_y;
/* Bottom/right */
info->points[2].x = info->x - info->center_x + width;
info->points[2].y = info->y - info->center_y + height;
/* Bottom/left */
info->points[3].x = info->x - info->center_x;
info->points[3].y = info->y - info->center_y + height;
for (i = 0; i < 4; i++)
{
gdouble ret_x, ret_y;
calculate_rotated_point (info->angle,
info->zoom,
info->x,
info->y,
(gdouble) info->points[i].x,
(gdouble) info->points[i].y,
&ret_x,
&ret_y);
info->points[i].x = (gint) ret_x;
info->points[i].y = (gint) ret_y;
}
}
static void
shape_info_bounding_rect (ShapeInfo *info,
GdkRectangle *rect)
{
gint i, left, right, top, bottom;
left = top = G_MAXINT;
right = bottom = 0;
for (i = 0; i < 4; i++)
{
if (info->points[i].x < left)
left = info->points[i].x;
if (info->points[i].x > right)
right = info->points[i].x;
if (info->points[i].y < top)
top = info->points[i].y;
if (info->points[i].y > bottom)
bottom = info->points[i].y;
}
rect->x = left - 20;
rect->y = top - 20;
rect->width = right - left + 40;
rect->height = bottom - top + 40;
}
static gboolean
shape_info_point_in (ShapeInfo *info,
gint x,
gint y)
{
GdkPoint *left, *right, *top, *bottom;
gint i;
left = right = top = bottom = NULL;
for (i = 0; i < 4; i++)
{
GdkPoint *p = &info->points[i];
if (!left ||
p->x < left->x ||
(p->x == left->x && p->y > left->y))
left = p;
if (!right ||
p->x > right->x ||
(p->x == right->x && p->y < right->y))
right = p;
}
for (i = 0; i < 4; i++)
{
GdkPoint *p = &info->points[i];
if (p == left || p == right)
continue;
if (!top ||
p->y < top->y)
top = p;
if (!bottom ||
p->y > bottom->y)
bottom = p;
}
g_assert (left && right && top && bottom);
if (x < left->x ||
x > right->x ||
y < top->y ||
y > bottom->y)
return FALSE;
/* Check whether point is above the sides
* between leftmost and topmost, and
* topmost and rightmost corners.
*/
if (x <= top->x)
{
if (left->y - ((left->y - top->y) * (((gdouble) x - left->x) / (top->x - left->x))) > y)
return FALSE;
}
else
{
if (top->y + ((right->y - top->y) * (((gdouble) x - top->x) / (right->x - top->x))) > y)
return FALSE;
}
/* Check whether point is below the sides
* between leftmost and bottom, and
* bottom and rightmost corners.
*/
if (x <= bottom->x)
{
if (left->y + ((bottom->y - left->y) * (((gdouble) x - left->x) / (bottom->x - left->x))) < y)
return FALSE;
}
else
{
if (bottom->y - ((bottom->y - right->y) * (((gdouble) x - bottom->x) / (right->x - bottom->x))) < y)
return FALSE;
}
return TRUE;
}
static ShapeInfo *
shape_info_new (gdouble x,
gdouble y,
gdouble width,
gdouble height,
GdkRGBA *color)
{
ShapeInfo *info;
info = g_slice_new0 (ShapeInfo);
info->cluster = NULL;
info->color = *color;
info->x = x;
info->y = y;
info->width = width;
info->height = height;
info->angle = 0;
info->zoom = 1;
info->base_zoom = 1;
info->base_angle = 0;
info->initial_distance = 0;
info->initial_angle = 0;
shape_info_allocate_input_rect (info);
g_queue_push_tail (shapes, info);
return info;
}
static void
shape_info_free (ShapeInfo *info)
{
g_slice_free (ShapeInfo, info);
}
static void
shape_info_draw (cairo_t *cr,
ShapeInfo *info)
{
cairo_save (cr);
cairo_translate (cr,
info->points[0].x + RECT_BORDER_WIDTH / 2,
info->points[0].y + RECT_BORDER_WIDTH / 2);
cairo_scale (cr, info->zoom, info->zoom);
cairo_rotate (cr, info->angle);
cairo_rectangle (cr, 0, 0,
info->width - RECT_BORDER_WIDTH,
info->height - RECT_BORDER_WIDTH);
gdk_cairo_set_source_rgba (cr, &info->color);
cairo_fill_preserve (cr);
cairo_set_line_width (cr, RECT_BORDER_WIDTH);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_stroke (cr);
cairo_restore (cr);
}
static void
shape_update_scales (ShapeInfo *info)
{
gtk_range_set_value (GTK_RANGE (red), info->color.red);
gtk_range_set_value (GTK_RANGE (green), info->color.green);
gtk_range_set_value (GTK_RANGE (blue), info->color.blue);
gtk_range_set_value (GTK_RANGE (alpha), info->color.alpha);
}
static void
range_value_changed_cb (GtkRange *range,
gpointer user_data)
{
GtkWidget *widget;
GdkRectangle rect;
ShapeInfo *shape;
gdouble value;
widget = GTK_WIDGET (range);
shape = g_queue_peek_head (shapes);
if (!shape)
return;
value = gtk_range_get_value (range);
if (widget == red)
shape->color.red = value;
else if (widget == green)
shape->color.green = value;
else if (widget == blue)
shape->color.blue = value;
else if (widget == alpha)
shape->color.alpha = value;
shape_info_bounding_rect (shape, &rect);
gdk_window_invalidate_rect (gtk_widget_get_window (area),
&rect, FALSE);
}
static gboolean
draw_cb (GtkWidget *widget,
cairo_t *cr,
gpointer user_data)
{
GList *l;
cairo_save (cr);
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_paint (cr);
for (l = shapes->tail; l; l = l->prev)
shape_info_draw (cr, l->data);
cairo_restore (cr);
return FALSE;
}
static gboolean
button_press_cb (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
{
ShapeInfo *shape = NULL;
guint touch_id;
if (gdk_event_get_touch_id (event, &touch_id))
{
GList *l;
for (l = shapes->tail; l; l = l->prev)
{
ShapeInfo *info = l->data;
if (shape_info_point_in (info,
(gint) event->button.x,
(gint) event->button.y))
shape = info;
}
if (!shape)
return FALSE;
/* Put on top */
g_queue_remove (shapes, shape);
g_queue_push_head (shapes, shape);
shape_update_scales (shape);
if (!shape->cluster)
shape->cluster = gdk_window_create_touch_cluster (gtk_widget_get_window (widget),
gdk_event_get_device (event));
else if (gdk_touch_cluster_get_n_touches (shape->cluster) == 0)
{
/* Only change cluster device if there were no touches */
gdk_touch_cluster_set_device (shape->cluster,
gdk_event_get_device (event));
}
gdk_touch_cluster_add_touch (shape->cluster, touch_id);
return TRUE;
}
return FALSE;
}
static gboolean
multitouch_cb (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
{
ShapeInfo *info = NULL;
gboolean new_center = FALSE;
gboolean new_position = FALSE;
gdouble event_x, event_y;
cairo_region_t *region;
GdkRectangle rect;
GList *l;
for (l = shapes->head; l; l = l->next)
{
ShapeInfo *shape = l->data;
if (event->multitouch.group == shape->cluster)
{
info = shape;
break;
}
}
if (!info)
return FALSE;
shape_info_bounding_rect (info, &rect);
region = cairo_region_create_rectangle ((cairo_rectangle_int_t *) &rect);
if (event->multitouch.n_events == 1)
{
/* Update center if we just got to
* this situation from either way */
if (event->type == GDK_MULTITOUCH_ADDED ||
event->type == GDK_MULTITOUCH_REMOVED)
new_center = TRUE;
event_x = event->multitouch.events[0]->x;
event_y = event->multitouch.events[0]->y;
new_position = TRUE;
}
else if (event->multitouch.n_events == 2)
{
gdouble distance, angle;
gdk_events_get_center ((GdkEvent *) event->multitouch.events[0],
(GdkEvent *) event->multitouch.events[1],
&event_x, &event_y);
gdk_events_get_distance ((GdkEvent *) event->multitouch.events[0],
(GdkEvent *) event->multitouch.events[1],
&distance);
gdk_events_get_angle ((GdkEvent *) event->multitouch.events[0],
(GdkEvent *) event->multitouch.events[1],
&angle);
if (event->type == GDK_MULTITOUCH_ADDED)
{
/* Second touch was just added, update base zoom/angle */
info->base_zoom = info->zoom;
info->base_angle = info->angle;
info->initial_angle = angle;
info->initial_distance = distance;
new_center = TRUE;
}
info->zoom = MAX (info->base_zoom * (distance / info->initial_distance), 1.0);
info->angle = info->base_angle + (angle - info->initial_angle);
new_position = TRUE;
}
if (new_center)
{
gdouble origin_x, origin_y;
origin_x = info->x - info->center_x;
origin_y = info->y - info->center_y;
calculate_rotated_point (- info->angle,
1 / info->zoom,
info->x - origin_x,
info->y - origin_y,
event_x - origin_x,
event_y - origin_y,
&info->center_x,
&info->center_y);
}
if (new_position)
{
info->x = event_x;
info->y = event_y;
}
shape_info_allocate_input_rect (info);
shape_info_bounding_rect (info, &rect);
cairo_region_union_rectangle (region, (cairo_rectangle_int_t *) &rect);
gdk_window_invalidate_region (gtk_widget_get_window (widget), region, FALSE);
return TRUE;
}
static void
window_destroyed_cb (GtkWidget *widget,
gpointer user_data)
{
g_queue_foreach (shapes, (GFunc) shape_info_free, NULL);
g_queue_free (shapes);
shapes = NULL;
window = NULL;
}
static void
new_rectangle_clicked_cb (GtkButton *button,
gpointer user_data)
{
GdkRectangle rect;
ShapeInfo *info;
GdkRGBA color;
color.red = color.green = color.blue = color.alpha = 0.5;
info = shape_info_new (0, 0, 100, 150, &color);
shape_info_bounding_rect (info, &rect);
gdk_window_invalidate_rect (gtk_widget_get_window (area), &rect, FALSE);
}
GtkWidget *
create_drawing_area (void)
{
area = gtk_drawing_area_new ();
gtk_widget_add_events (area,
GDK_TOUCH_MASK |
GDK_POINTER_MOTION_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK);
gtk_widget_set_size_request (area, 600, 600);
g_signal_connect (area, "draw",
G_CALLBACK (draw_cb), NULL);
g_signal_connect (area, "button-press-event",
G_CALLBACK (button_press_cb), NULL);
g_signal_connect (area, "multitouch-event",
G_CALLBACK (multitouch_cb), NULL);
return area;
}
GtkWidget *
create_scale (void)
{
GtkWidget *scale;
scale = gtk_scale_new_with_range (GTK_ORIENTATION_VERTICAL, 0, 1, 0.01);
gtk_range_set_inverted (GTK_RANGE (scale), TRUE);
gtk_widget_set_vexpand (scale, TRUE);
gtk_widget_set_margin_left (scale, 15);
gtk_widget_set_margin_right (scale, 15);
gtk_widget_add_events (scale, GDK_TOUCH_MASK);
g_signal_connect (scale, "value-changed",
G_CALLBACK (range_value_changed_cb), NULL);
return scale;
}
GtkWidget *
create_window (void)
{
GtkWidget *grid, *label, *button;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Multitouch demo");
g_signal_connect (window, "destroy",
G_CALLBACK (window_destroyed_cb), NULL);
grid = gtk_grid_new ();
gtk_container_add (GTK_CONTAINER (window), grid);
area = create_drawing_area ();
gtk_grid_attach (GTK_GRID (grid),
area, 0, 0, 1, 3);
gtk_widget_set_hexpand (area, TRUE);
gtk_widget_set_vexpand (area, TRUE);
/* "red" label/scale */
label = gtk_label_new ("Red");
gtk_widget_set_vexpand (label, FALSE);
gtk_grid_attach (GTK_GRID (grid),
label, 1, 0, 1, 1);
red = create_scale ();
gtk_grid_attach (GTK_GRID (grid),
red, 1, 1, 1, 1);
/* "green" label/scale */
label = gtk_label_new ("Green");
gtk_widget_set_vexpand (label, FALSE);
gtk_grid_attach (GTK_GRID (grid),
label, 2, 0, 1, 1);
green = create_scale ();
gtk_grid_attach (GTK_GRID (grid),
green, 2, 1, 1, 1);
/* "blue" label/scale */
label = gtk_label_new ("Blue");
gtk_widget_set_vexpand (label, FALSE);
gtk_grid_attach (GTK_GRID (grid),
label, 3, 0, 1, 1);
blue = create_scale ();
gtk_grid_attach (GTK_GRID (grid),
blue, 3, 1, 1, 1);
/* "alpha" label/scale */
label = gtk_label_new ("Alpha");
gtk_widget_set_vexpand (label, FALSE);
gtk_grid_attach (GTK_GRID (grid),
label, 4, 0, 1, 1);
alpha = create_scale ();
gtk_grid_attach (GTK_GRID (grid),
alpha, 4, 1, 1, 1);
/* button */
button = gtk_button_new_from_stock (GTK_STOCK_NEW);
gtk_widget_add_events (button, GDK_TOUCH_MASK);
gtk_grid_attach (GTK_GRID (grid),
button, 1, 2, 4, 1);
gtk_widget_set_vexpand (button, FALSE);
g_signal_connect (button, "clicked",
G_CALLBACK (new_rectangle_clicked_cb), NULL);
gtk_widget_show_all (grid);
return window;
}
GtkWidget *
do_multitouch (GtkWidget *do_widget)
{
if (!shapes)
shapes = g_queue_new ();
if (!window)
window = create_window ();
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
{
gtk_widget_destroy (window);
window = NULL;
g_queue_foreach (shapes, (GFunc) shape_info_free, NULL);
g_queue_free (shapes);
shapes = NULL;
}
return window;
}

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<schemalist>
<enum id='org.gtk.Demo.Color'>
<value nick='red' value='0'/>
<value nick='green' value='1'/>
<value nick='blue' value='2'/>
</enum>
<schema id='org.gtk.Demo' path='/org/gtk/Demo/'>
<key name='color' enum='org.gtk.Demo.Color'>
<default>'red'</default>
</key>
</schema>
</schemalist>

View File

@@ -180,7 +180,7 @@ timeout (gpointer data)
GDK_THREADS_LEAVE ();
frame_num++;
return G_SOURCE_CONTINUE;
return TRUE;
}
static guint timeout_id;

View File

@@ -29,7 +29,8 @@ static gboolean
search_progress (gpointer data)
{
gtk_entry_progress_pulse (GTK_ENTRY (data));
return G_SOURCE_CONTINUE;
return TRUE;
}
static void

View File

@@ -49,7 +49,7 @@ scroll_to_end (GtkTextView *textview)
if (count > 150)
count = 0;
return G_SOURCE_CONTINUE;
return TRUE;
}
/* Scroll to the bottom of the buffer.
@@ -100,7 +100,7 @@ scroll_to_bottom (GtkTextView *textview)
if (count > 40)
count = 0;
return G_SOURCE_CONTINUE;
return TRUE;
}
static guint

View File

@@ -350,7 +350,7 @@ interactive_canvas_real_drag_leave (gpointer data)
gtk_widget_queue_draw (widget);
}
return G_SOURCE_REMOVE;
return FALSE;
}
static void

View File

@@ -1,31 +0,0 @@
include $(top_srcdir)/Makefile.decl
bin_PROGRAMS = gtk3-widget-factory
gtk3_widget_factory_SOURCES = \
widget-factory.c \
widget_factory_resources.c
BUILT_SOURCES = \
widget_factory_resources.c
gtk3_widget_factory_DEPENDENCIES = \
$(top_builddir)/gtk/libgtk-3.la
gtk3_widget_factory_CPPFLAGS = \
-I$(top_srcdir) \
$(GTK_DEBUG_FLAGS) \
$(GTK_DEP_CFLAGS)
gtk3_widget_factory_LDADD = \
$(top_builddir)/gdk/libgdk-3.la \
$(top_builddir)/gtk/libgtk-3.la \
$(GTK_DEP_LIBS)
widget_factory_resources.c: widget-factory.gresource.xml $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies $(srcdir)/widget-factory.gresource.xml)
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --generate-source $<
EXTRA_DIST += \
widget-factory.ui \
widget-factory.gresource.xml \
gtk-logo-256.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/logos">
<file>gtk-logo-256.png</file>
</gresource>
<gresource prefix="/ui">
<file preprocess="xml-stripblanks">widget-factory.ui</file>
</gresource>
</gresources>

View File

@@ -33,7 +33,6 @@
<xi:include href="xml/windows.xml" />
<xi:include href="xml/events.xml" />
<xi:include href="xml/event_structs.xml" />
<xi:include href="xml/touchcluster.xml" />
<xi:include href="xml/keys.xml" />
<xi:include href="xml/selections.xml" />
<xi:include href="xml/dnd.xml" />

View File

@@ -759,9 +759,6 @@ GDK_PRIORITY_EVENTS
GDK_PRIORITY_REDRAW
GDK_EVENT_PROPAGATE
GDK_EVENT_STOP
GDK_BUTTON_PRIMARY
GDK_BUTTON_MIDDLE
GDK_BUTTON_SECONDARY
<SUBSECTION>
gdk_events_pending
@@ -781,13 +778,11 @@ gdk_event_get_root_coords
gdk_event_get_scroll_direction
gdk_event_get_state
gdk_event_get_time
gdk_event_get_touch_id
gdk_event_request_motions
gdk_events_get_angle
gdk_events_get_center
gdk_events_get_distance
gdk_event_triggers_context_menu
gdk_event_get_touch_id
<SUBSECTION>
gdk_event_handler_set
@@ -835,7 +830,6 @@ GdkEventWindowState
GdkEventSetting
GdkEventOwnerChange
GdkEventGrabBroken
GdkEventMultiTouch
<SUBSECTION>
GdkScrollDirection
@@ -863,29 +857,6 @@ gdk_event_get_type
gdk_owner_change_get_type
</SECTION>
<SECTION>
<TITLE>Multitouch</TITLE>
<FILE>touchcluster</FILE>
GdkTouchCluster
gdk_touch_cluster_add_touch
gdk_touch_cluster_remove_touch
gdk_touch_cluster_remove_all
gdk_touch_cluster_set_device
gdk_touch_cluster_get_device
gdk_touch_cluster_get_touches
<SUBSECTION>
gdk_window_create_touch_cluster
gdk_window_remove_touch_cluster
<SUBSECTION Standard>
GDK_TYPE_TOUCH_CLUSTER
<SUBSECTION Private>
gdk_touch_cluster_get_type
</SECTION>
<SECTION>
<TITLE>Cursors</TITLE>
<FILE>cursors</FILE>

View File

@@ -9,6 +9,5 @@ gdk_display_manager_get_type
gdk_drag_context_get_type
gdk_keymap_get_type
gdk_screen_get_type
gdk_touch_cluster_get_type
gdk_visual_get_type
gdk_window_get_type

View File

@@ -119,13 +119,11 @@ content_files = \
running.sgml \
building.sgml \
compiling.sgml \
device-interaction-patterns.xml \
drawing-model.xml \
glossary.xml \
migrating-2to3.xml \
migrating-checklist.sgml \
migrating-unique-GtkApplication.xml \
migrating-smclient-GtkApplication.xml \
migrating-GtkApplication.xml \
migrating-GtkGrid.xml \
migrating-GtkStyleContext.xml \
objects_grouped.sgml \
@@ -143,14 +141,12 @@ content_files = \
overview.xml
expand_content_files = \
device-interaction-patterns.xml \
drawing-model.xml \
getting_started.xml \
glossary.xml \
migrating-2to3.xml \
migrating-checklist.sgml \
migrating-unique-GtkApplication.xml \
migrating-smclient-GtkApplication.xml \
migrating-GtkApplication.xml \
migrating-GtkGrid.xml \
migrating-GtkStyleContext.xml \
question_index.sgml \
@@ -289,7 +285,6 @@ HTML_IMAGES = \
$(srcdir)/images/check-button.png \
$(srcdir)/images/color-button.png \
$(srcdir)/images/colorsel.png \
$(srcdir)/images/colorchooser.png \
$(srcdir)/images/combo-box.png \
$(srcdir)/images/combo-box-entry.png \
$(srcdir)/images/entry.png \
@@ -299,7 +294,6 @@ HTML_IMAGES = \
$(srcdir)/images/filechooser.png \
$(srcdir)/images/font-button.png \
$(srcdir)/images/fontsel.png \
$(srcdir)/images/fontchooser.png \
$(srcdir)/images/frame.png \
$(srcdir)/images/icon-view.png \
$(srcdir)/images/image.png \

View File

@@ -1,578 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="gtk-device-interaction-patterns">
<title>Multitouch and other device interaction patterns</title>
<para>
Depending on the platform, GTK+ is able to handle a wide range of input
devices. Those are offered to applications in a 2-level hierarchy, with
virtual devices (or master devices) representing the visual cursors
displayed in the screen, which are each controlled by a number of physical
devices (or slave devices). Those devices can respectively be retrieved
from an input event with gdk_event_get_device() and
gdk_event_get_source_device().
</para>
<para>
In X11, GTK+ uses XInput2 for input events, which caters for a fully dynamic
device hierarchy, and support for multiple virtual pointer/keyboard pairs.
</para>
<example>
<title>Listing and modifying the device hierarchy</title>
<programlisting>
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)]
carlos@sacarino:~$ xinput create-master eek
carlos@sacarino:~$ xinput list
...
⎡ eek pointer id=17 [master pointer (18)]
⎜ ↳ eek XTEST pointer id=19 [slave pointer (17)]
⎣ eek keyboard id=18 [master keyboard (17)]
↳ eek XTEST keyboard id=20 [slave keyboard (18)]
carlos@sacarino:~$ xinput reattach 10 17
carlos@sacarino:~$ xinput list
...
⎡ eek pointer id=17 [master pointer (18)]
⎜ ↳ Wacom ISDv4 E6 Pen stylus id=10 [slave pointer (17)]
⎜ ↳ eek XTEST pointer id=19 [slave pointer (17)]
⎣ eek keyboard id=18 [master keyboard (17)]
↳ eek XTEST keyboard id=20 [slave keyboard (18)]
</programlisting>
</example>
<para>
Anytime a virtual device is added or removed, or a physical device
is attached to another virtual device, or left floating (detached
from any virtual device), #GdkDeviceManager will emit the corresponding
#GdkDeviceManager::device-added, #GdkDeviceManager::device-removed, or
#GdkDeviceManager::device-changed signals.
</para>
<section id="gtk-device-patterns-client-pointer">
<title>The client pointer</title>
<para>
In X11, Under the presence of multiple virtual pointers, GDK and XInput2
use the "client pointer" principle to allow several legacy applications
to interact simultaneously with different virtual pointer/keyboard pairs,
it would be usually set by the window manager for a focused window, so
different application windows could operate on different client pointers.
gdk_device_manager_get_client_pointer() may be called to get the client
pointer #GdkDevice
</para>
<para>
Under the hood, X11 uses the client pointer (or its paired keyboard) to
satisfy core calls such as XGrabPointer/Keyboard, XQueryPointer and
others that have been superseded by XInput2.
</para>
<para>
In platforms without multidevice features, gdk_device_manager_get_client_pointer()
will return the only virtual pointer available.
</para>
</section>
<section id="gtk-device-patterns-simple">
<title>Simple device handling</title>
<para>
There are applications that could have little gain in knowing about
multiple devices, although there are situations where a device could
be needed (i.e. popping up a menu on the pointer coordinates).
</para>
<para>
For such applications, the client pointer may be a good enough
approximation for these operations. Under the presence of multiple
device pairs, this gives a behavior that is most similar to that
of legacy applications (i.e. gtk+2).
</para>
<example>
<title>Getting the client pointer and keyboard</title>
<programlisting>
GdkDisplay *display;
GdkDeviceManager *device_manager;
GdkDevice *client_pointer, client_keyboard;
display = gdk_display_get_default ();
device_manager = gdk_display_get_device_manager (display);
client_pointer = gdk_device_manager_get_client_pointer (device_manager);
/* Or if we need a keyboard too */
client_keyboard = gdk_device_get_associated_device (client_pointer);
</programlisting>
</example>
</section>
<section id="gtk-device-patterns-multiple-devices">
<title>Dealing with multiple devices</title>
<para>
There may be several usecases to deal with multiple devices, including,
but not limited to:
</para>
<orderedlist>
<listitem>
Retrieving advanced information from an input device: i.e. stylus pressure/tilt
in drawing applications.
</listitem>
<listitem>
Receiving events from a dedicated input device: i.e. joysticks in games.
</listitem>
<listitem>
Collaborative interfaces, handling simultaneous input from multiple users.
</listitem>
</orderedlist>
<para>
However, the patterns to make them work are very similar.
</para>
<section>
<title>Event handling</title>
<para>
Each device will emit its own event stream, this means
that you will need to check the GdkEvent you get in
your event handlers
</para>
<example>
<title>Reacting differently to devices</title>
<programlisting>
static gboolean
my_widget_motion_notify (GtkWidget *widget,
GdkEventMotion *event)
{
GdkDevice *device, *source_device;
device = gdk_event_get_device ((GdkEvent *) event);
source_device = gdk_event_get_source_device ((GdkEvent *) event);
g_print ("Motion event by '%s', coming from HW device '%s'\n",
gdk_device_get_name (device),
gdk_device_get_name (source_device));
/* Handle touch devices differently */
if (gdk_device_get_source (source_device) == GDK_SOURCE_TOUCH)
{
...
}
else
{
...
}
return TRUE;
}
</programlisting>
</example>
<para>
The mechanism above could also be used for fine grained event discarding
(i.e. so rubberband selection doesn't jump to another pointer entering
the widget for example)
</para>
<example>
<title>Reacting differently to devices</title>
<programlisting>
static gboolean
my_widget_button_press (Gtkwidget *widget,
GdkEventButton *event)
{
GET_PRIV(widget)->current_pointer = gdk_event_get_device ((GdkEvent *) event);
...
}
static gboolean
my_widget_button_release (Gtkwidget *widget,
GdkEventButton *event)
{
GET_PRIV(widget)->current_pointer = NULL;
...
}
static gboolean
my_widget_motion_notify (Gtkwidget *widget,
GdkEventMotion *event)
{
if (gdk_event_get_device (event) !=
GET_PRIV(widget)->current_pointer)
return FALSE;
...
}
</programlisting>
</example>
</section>
<section>
<title>Grabs</title>
<para>
Grabs are a mechanism to coerce a device into sending events to
a window, but with multidevice there's an other side of the coin,
how other devices are supposed to interact while the grab is in
effect.
</para>
<para>
The GdkGrabOwnership enum passed to gdk_device_grab() may be used
to block other devices' interaction. %GDK_OWNERSHIP_NONE applies
no restrictions, allowing other devices to interact, even with
the grab window. %GDK_OWNERSHIP_WINDOW blocks other devices from
interacting with the grab window, but they'll still be able to
interact with the rest of the application, whereas
%GDK_OWNERSHIP_APPLICATION will render the whole application
insensitive to input from other devices. Different devices may
have simultaneous grabs on the same or different windows.
</para>
<example>
<title>Grabbing as a result of an input event</title>
<programlisting>
gboolean
my_widget_button_press (GtkWidget *widget,
GdkEventButton *event)
{
GdkDevice *pointer, *keyboard;
pointer = gdk_event_get_device ((GdkEvent *) event);
keyboard = gdk_device_get_associated_device (pointer);
/* Grab both keyboard/pointer, other devices will be
* unable to interact with the widget window meanwhile
*/
gdk_device_grab (pointer,
gtk_widget_get_window (widget),
GDK_OWNERSHIP_WINDOW,
...);
gdk_device_grab (keyboard,
gtk_widget_get_window (widget),
GDK_OWNERSHIP_WINDOW,
...);
return FALSE;
}
</programlisting>
</example>
<para>
For GTK+ grabs, there's only a boolean value, equivalent to
%GDK_OWNERSHIP_NONE and %GDK_OWNERSHIP_WINDOW, but the mechanism
is quite similar.
</para>
<para>
Once the device is grabbed, there may be different situations
that could break the grabs, so the widget needs to listen to
#GdkGrabBrokenEvent and the #GtkWidget::grab-notify signal to
handle these situations.
</para>
<example>
<title>Handling broken grabs</title>
<programlisting>
static gboolean
my_widget_grab_broken (GtkWidget *widget,
GdkEventGrabBroken *event)
{
MyWidgetPrivate *priv = GET_PRIV (widget);
if (gdk_event_get_device (event) == priv->grab_pointer)
{
/* Undo state */
...
priv->grab_pointer = NULL;
return TRUE;
}
return FALSE;
}
static void
my_widget_grab_notify (GtkWidget *widget,
gboolean was_grabbed)
{
MyWidgetPrivate *priv = GET_PRIV (widget);
if (gtk_widget_device_is_shadowed (widget, priv->grab_device))
{
/* Device was "shadowed" by another widget's grab,
* release and undo state
*/
...
priv->grab_pointer = NULL;
}
}
</programlisting>
</example>
</section>
<section>
<title>Handling multipointer</title>
<para>
Widgets do react by default to every virtual device, although
by default they are set in a compatibility mode that makes them
behave better with multiple pointers, without necessarily
being multipointer aware.
</para>
<para>
This compatibility mode most notably disables per-device
enter/leave events, so these are stacked, and the crossing
events are only emitted when the first pointer enters the
window, and after the last pointer leaves it. This behavior
is controlled through gtk_widget_set_support_multidevice()
</para>
</section>
<section>
<title>Reading device axis values</title>
<para>
Button and motion events provide further information about
the device axes' current state. Note the device axes are
hardware and driver dependent, therefore the set of axes
is not set in stone, although there are a few more common ones.
</para>
<example>
<title>Getting to know the axes provided by a device</title>
<programlisting>
carlos@sacarino:~$ xinput list "Wacom ISDv4 E6 Pen stylus" |grep "Label"
Label: Abs X
Label: Abs Y
Label: Abs Pressure
Label: Abs Tilt X
Label: Abs Tilt Y
Label: Abs Wheel
</programlisting>
</example>
<example>
<title>Getting an axis value</title>
<programlisting>
gboolean
my_widget_motion_notify (GtkWidget *widget,
GdkEventMotion *event)
{
GdkAtom *label_atom;
gdouble pressure;
label_atom = gdk_atom_intern_static_string ("Abs Pressure");
gdk_device_get_axis_value (gdk_event_get_device ((GdkEvent *) event),
event->axes, label_atom, &amp;pressure);
/* Do something with pressure */
...
return TRUE;
}
</programlisting>
</example>
<para>
All pointer devices report axes information, master and slave. to
achieve this, master pointers modify their list of axes at runtime
to reflect those of the currently routed slave, emitting
#GdkDevice::changed as the routed slave device changes.
</para>
</section>
<section>
<title>Dealing with slave (or floating) devices</title>
<para>
By default, GTK+ listens to all master devices, and typically
all slave devices will be attached to a master device. so
gdk_event_get_source_device() is the recommended way to deal
with the physical device triggering the event.
</para>
<para>
In more specialized setups, some devices could be floating
(i.e. tablets that don't route events through any virtual
pointer, but are expected to interact with drawing applications).
In that case, such specialized applications could want to interact
directly with the device. To do so, the device must be enabled,
and the widget wanting its events needs to add the event mask.
</para>
<example>
<title>Enabling events for a slave device</title>
<programlisting>
GdkDevice *device;
/* Gets the first device found with the given GdkInputSource */
device = get_device (gtk_widget_get_display (widget),
GDK_SOURCE_PEN);
gdk_device_set_mode (device, GDK_MODE_SCREEN);
gtk_widget_add_device_events (widget, device,
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_POINTER_MOTION_MASK);
</programlisting>
</example>
<para>
After these calls, the widget would specifically receive events
from the physical device, regardless of it being floating or
connected to a master device. In this second case, and if you
want exclusive control of the device, you can temporarily detach
the stylus device from its master by doing a GDK grab on it.
</para>
<para>
For events coming directly from slave devices, both
gdk_event_get_device() and gdk_event_get_source_device() will
return the same device of type %GDK_DEVICE_TYPE_SLAVE or
%GDK_DEVICE_TYPE_FLOATING.
</para>
<note>
This is less useful than it used to be in GTK+2/XInput1, at least
for attached slaves, as there is gdk_event_get_source_device(),
and master devices' events provide axes information.
</note>
</section>
</section>
<section id="gtk-device-patterns-multitouch-widgets">
<title>Multitouch in GTK+ widgets</title>
<para>
Since version 3.4, GTK+ offers support for multitouch devices through a new
set of events and higher level tools like #GdkTouchCluster and
#GtkGesturesInterpreter.
</para>
<para>
If the widget does not have %GDK_TOUCH_MASK set in the event mask, it will
only be allowed to interact with the touch emulating pointer events, and will
only receive pointer events.
</para>
<para>
If the widget does have %GDK_TOUCH_MASK enabled, it will be able to receive
events of type %GDK_TOUCH_PRESS, %GDK_TOUCH_RELEASE and %GDK_TOUCH_MOTION,
which will be respectively emitted through the #GtkWidget::button-press-event,
#GtkWidget::button-release-event and #GtkWidget::motion-notify-event signals.
There may be multiple, simultaneous sequences of events, those will be
recognized and referenced by their touch ID. See gdk_event_get_touch_id().
</para>
<para>
#GtkWidget<!-- -->s may create GdkTouchCluster<!-- -->s via
gdk_window_create_touch_cluster(), those may be used to group
touch events together, which are notified through #GdkEventMultitouch,
this event will be emitted in #GtkWidget<!-- -->s through the
#GtkWidget::multitouch-event signal.
</para>
<para>
Widgets may also handle gestures being performed on them,
gtk_widget_enable_gesture() and gtk_widget_disable_gesture() are
provided as a simple API, although widgets may also create a
#GtkGesturesInterpreter and feed it events directly.
</para>
</section>
<section id="gtk-device-patterns-multitouch">
<title>Multitouch across a widget hierarchy</title>
<para>
Fully touch driven applications might not want to confine multitouch
operations within a single widget, but rather offer simultaneous
interaction with multiple widgets.
</para>
<para>
GTK+ is able to provide such experience, although it does not enable
%GDK_TOUCH_MASK by default on its stock widgets. If a widget meets the
following requirements, it is ready to be used in a multitouch UI:
</para>
<orderedlist>
<listitem>
The widget handles #GtkWidget::button-press-event, #GtkWidget::button-release-event
and #GtkWidget::motion-notify-event, and does something meaningful while the button 1
is pressed. If any explicit check on the event type being %GDK_BUTTON_PRESS,
%GDK_BUTTON_RELEASE or %GDK_MOTION_NOTIFY is performed, the event types
%GDK_TOUCH_PRESS, %GDK_TOUCH_RELEASE or %GDK_TOUCH_MOTION also need to be handled.
</listitem>
<listitem>
The widget relies on the implicit grab as long as the button press/touch is active,
GDK or GTK+ grabs would break the implicit grabs other touch sequences may have on
other widgets.
</listitem>
<listitem>
The widget does not require (or opts out) keyboard interaction while a touch is
active on it. Touch interaction does not necessarily bring the keyboard focus with it.
</listitem>
<listitem>
If the widget is only meant to interact with one touch sequence at a time (i.e.
buttons), it has to be able to discern and reject operations on any later touch
sequence as long as the touch it is interacting with remains active.
</listitem>
</orderedlist>
<para>
If a widget meets those requirements, enabling %GDK_TOUCH_MASK on it will suffice
to make it handle multitouch events in a way that doesn't disrupt other touch
operations.
</para>
<example>
<title>Enabling touch events on a widget</title>
<programlisting>
gtk_widget_add_events (widget, GDK_TOUCH_MASK);
</programlisting>
</example>
<note>
Not all GTK+ stock widgets are immediately suitable for handling touch
events, there could be even design reasons on some of those which render
them unsuitable.
</note>
</section>
<section id="gtk-device-patterns-recommendations">
<title>Recommendations</title>
<orderedlist>
<listitem>
Device operations often come up as a result of input events, favor
gdk_event_get_device() and gtk_get_current_event_device() before
gdk_device_manager_get_client_pointer().
</listitem>
<listitem>
Store the devices the widget is currently interacting with, handle
GdkEventGrabBroken and #GtkWidget::grab-notify to undo/nullify these.
</listitem>
</orderedlist>
</section>
</chapter>

View File

@@ -68,12 +68,6 @@
<xi:include href="xml/gtkstyle.xml" />
</part>
<part id="multitouch-and-multidevice">
<title>Interacting with input devices</title>
<xi:include href="xml/device-interaction-patterns.xml" />
<xi:include href="xml/gtkgesturesinterpreter.xml" />
</part>
<part id="gtkobjects">
<title>GTK+ Widgets and Objects</title>
@@ -215,22 +209,18 @@
<chapter id="SelectorWidgets">
<title>Selectors (Color/File/Font)</title>
<xi:include href="xml/gtkcolorchooser.xml" />
<xi:include href="xml/gtkcolorbutton.xml" />
<xi:include href="xml/gtkcolorchooserwidget.xml" />
<xi:include href="xml/gtkcolorchooserdialog.xml" />
<xi:include href="xml/gtkcolorsel.xml" />
<xi:include href="xml/gtkcolorseldlg.xml" />
<xi:include href="xml/gtkcolorsel.xml" />
<xi:include href="xml/gtkhsv.xml" />
<xi:include href="xml/gtkfilechooser.xml" />
<xi:include href="xml/gtkfilechooserbutton.xml" />
<xi:include href="xml/gtkfilechooserdialog.xml" />
<xi:include href="xml/gtkfilechooserwidget.xml" />
<xi:include href="xml/gtkfilefilter.xml" />
<xi:include href="xml/gtkfontchooser.xml" />
<xi:include href="xml/gtkfontbutton.xml" />
<xi:include href="xml/gtkfontchooserwidget.xml" />
<xi:include href="xml/gtkfontchooserdialog.xml" />
<xi:include href="xml/gtkfontchooser.xml" />
<xi:include href="xml/gtkfontchooserdlg.xml" />
<xi:include href="xml/gtkfontsel.xml" />
<xi:include href="xml/gtkfontseldlg.xml" />
</chapter>
@@ -349,7 +339,6 @@
<title>Application support</title>
<xi:include href="xml/gtkapplication.xml" />
<xi:include href="xml/gtkapplicationwindow.xml" />
<xi:include href="xml/gtkactionable.xml" />
</chapter>
</part>
@@ -366,12 +355,11 @@
</para>
</partintro>
<xi:include href="xml/migrating-checklist.sgml" />
<xi:include href="xml/migrating-2to3.xml" />
<xi:include href="xml/migrating-GtkStyleContext.xml" />
<xi:include href="xml/migrating-unique-GtkApplication.xml" />
<xi:include href="xml/migrating-smclient-GtkApplication.xml" />
<xi:include href="xml/migrating-GtkApplication.xml" />
<xi:include href="xml/migrating-GtkGrid.xml" />
<xi:include href="xml/migrating-checklist.sgml" />
</part>
<part>

View File

@@ -37,7 +37,6 @@ gtk_about_dialog_get_logo
gtk_about_dialog_set_logo
gtk_about_dialog_get_logo_icon_name
gtk_about_dialog_set_logo_icon_name
gtk_about_dialog_add_credit_section
gtk_show_about_dialog
<SUBSECTION Standard>
GTK_ABOUT_DIALOG
@@ -1535,7 +1534,7 @@ gtk_font_chooser_widget_get_type
</SECTION>
<SECTION>
<FILE>gtkfontchooserdialog</FILE>
<FILE>gtkfontchooserdlg</FILE>
<TITLE>GtkFontChooserDialog</TITLE>
GtkFontChooserDialog
gtk_font_chooser_dialog_new
@@ -1579,51 +1578,6 @@ GtkFramePrivate
gtk_frame_get_type
</SECTION>
<SECTION>
<FILE>gtkgesturesinterpreter</FILE>
<TITLE>GtkGesturesInterpreter</TITLE>
GtkGesturesInterpreter
GtkGestureType
gtk_gestures_interpreter_new
gtk_gestures_interpreter_add_gesture
gtk_gestures_interpreter_remove_gesture
gtk_gestures_interpreter_feed_event
gtk_gestures_interpreter_finish
gtk_gestures_interpreter_get_n_active_strokes
<SUBSECTION Gestures>
GtkGestureStroke
gtk_gesture_stroke_new
gtk_gesture_stroke_copy
gtk_gesture_stroke_free
gtk_gesture_stroke_append_vector
gtk_gesture_stroke_get_n_vectors
gtk_gesture_stroke_get_vector
GtkGesture
GtkGestureFlags
gtk_gesture_new
gtk_gesture_copy
gtk_gesture_free
gtk_gesture_add_stroke
gtk_gesture_get_n_strokes
gtk_gesture_get_stroke
gtk_gesture_get_flags
gtk_gesture_register
gtk_gesture_register_static
gtk_gesture_lookup
<SUBSECTION Standard>
GTK_GESTURES_INTERPRETER
GTK_IS_GESTURES_INTERPRETER
GTK_TYPE_GESTURES_INTERPRETER
GTK_IS_GESTURES_INTERPRETER_CLASS
GTK_GESTURES_INTERPRETER_GET_CLASS
<SUBSECTION Private>
gtk_gestures_interpreter_get_type
gtk_gesture_stroke_get_type
gtk_gesture_get_type
</SECTION>
<SECTION>
<FILE>gtkhandlebox</FILE>
<TITLE>GtkHandleBox</TITLE>
@@ -2105,7 +2059,6 @@ gtk_link_button_get_type
<TITLE>GtkMenu</TITLE>
GtkMenu
gtk_menu_new
gtk_menu_new_from_model
gtk_menu_set_screen
gtk_menu_reorder_child
gtk_menu_attach
@@ -2150,7 +2103,6 @@ gtk_menu_get_type
<TITLE>GtkMenuBar</TITLE>
GtkMenuBar
gtk_menu_bar_new
gtk_menu_bar_new_from_model
GtkPackDirection
gtk_menu_bar_set_pack_direction
gtk_menu_bar_get_pack_direction
@@ -5076,7 +5028,6 @@ GtkAllocation
GtkSelectionData
GtkWidgetAuxInfo
GtkWidgetHelpType
GtkCapturedEventFlags
gtk_widget_new
gtk_widget_destroy
gtk_widget_in_destruction
@@ -5262,7 +5213,6 @@ gtk_widget_get_mapped
gtk_widget_get_requisition
gtk_widget_device_is_shadowed
gtk_widget_get_modifier_mask
gtk_widget_release_captured_events
<SUBSECTION>
gtk_widget_get_path
@@ -5312,10 +5262,6 @@ gtk_widget_set_vexpand_set
gtk_widget_queue_compute_expand
gtk_widget_compute_expand
<SUBSECTION Gestures>
gtk_widget_enable_gesture
gtk_widget_disable_gesture
<SUBSECTION Standard>
GTK_WIDGET
GTK_IS_WIDGET
@@ -5351,7 +5297,6 @@ gtk_window_set_gravity
gtk_window_get_gravity
gtk_window_set_position
gtk_window_set_transient_for
gtk_window_set_attached_to
gtk_window_set_destroy_with_parent
gtk_window_set_hide_titlebar_when_maximized
gtk_window_set_screen
@@ -5410,7 +5355,6 @@ gtk_window_get_role
gtk_window_get_size
gtk_window_get_title
gtk_window_get_transient_for
gtk_window_get_attached_to
gtk_window_get_type_hint
gtk_window_get_skip_taskbar_hint
gtk_window_get_skip_pager_hint
@@ -5739,7 +5683,6 @@ gtk_style_context_add_provider_for_screen
gtk_style_context_get
gtk_style_context_get_direction
gtk_style_context_get_junction_sides
gtk_style_context_set_parent
gtk_style_context_get_path
gtk_style_context_get_property
gtk_style_context_get_screen
@@ -5748,7 +5691,6 @@ gtk_style_context_get_style
gtk_style_context_get_style_property
gtk_style_context_get_style_valist
gtk_style_context_get_valist
gtk_style_context_get_section
gtk_style_context_get_color
gtk_style_context_get_background_color
gtk_style_context_get_border_color
@@ -5773,7 +5715,6 @@ gtk_style_context_restore
gtk_style_context_save
gtk_style_context_set_direction
gtk_style_context_set_junction_sides
gtk_style_context_set_parent
gtk_style_context_set_path
gtk_style_context_add_class
gtk_style_context_remove_class
@@ -7068,14 +7009,6 @@ gtk_application_add_window
gtk_application_remove_window
gtk_application_get_windows
<SUBSECTION>
GtkApplicationInhibitFlags
gtk_application_inhibit
gtk_application_uninhibit
gtk_application_is_inhibited
GtkApplicationEndSessionStyle
gtk_application_end_session
<SUBSECTION>
gtk_application_get_app_menu
gtk_application_set_app_menu
@@ -7117,32 +7050,6 @@ gtk_application_window_get_type
GtkApplicationWindowPrivate
</SECTION>
<SECTION>
<FILE>gtkactionable</FILE>
<TITLE>GtkActionable</TITLE>
GtkActionable
GtkActionableInterface
<SUBSECTION>
gtk_actionable_get_action_name
gtk_actionable_set_action_name
<SUBSECTION>
gtk_actionable_get_action_target_value
gtk_actionable_set_action_target_value
gtk_actionable_set_action_target
<SUBSECTION>
gtk_actionable_set_detailed_action_name
<SUBSECTION Standard>
gtk_actionable_get_type
GTK_ACTIONABLE
GTK_ACTIONABLE_GET_IFACE
GTK_IS_ACTIONABLE
GTK_TYPE_ACTIONABLE
</SECTION>
<SECTION>
<FILE>gtkgrid</FILE>
<TITLE>GtkGrid</TITLE>
@@ -7352,61 +7259,3 @@ GtkOverlayClass
gtk_overlay_get_type
GtkOverlayPrivate
</SECTION>
<SECTION>
<FILE>gtkcolorchooser</FILE>
<TITLE>GtkColorChooser</TITLE>
GtkColorChooser
gtk_color_chooser_get_rgba
gtk_color_chooser_set_rgba
gtk_color_chooser_get_use_alpha
gtk_color_chooser_set_use_alpha
gtk_color_chooser_add_palette
<SUBSECTION Standard>
GTK_TYPE_COLOR_CHOOSER
GTK_COLOR_CHOOSER
GTK_IS_COLOR_CHOOSER
GTK_COLOR_CHOOSER_GET_IFACE
<SUBSECTION Private>
gtk_color_chooser_get_type
</SECTION>
<SECTION>
<FILE>gtkcolorchooserwidget</FILE>
<TITLE>GtkColorChooserWidget</TITLE>
GtkColorChooserWidget
gtk_color_chooser_widget_new
<SUBSECTION Standard>
GTK_TYPE_COLOR_CHOOSER_WIDGET
GTK_COLOR_CHOOSER_WIDGET
GTK_COLOR_CHOOSER_WIDGET_CLASS
GTK_IS_COLOR_CHOOSER_WIDGET
GTK_IS_COLOR_CHOOSER_WIDGET_CLASS
GTK_COLOR_CHOOSER_WIDGET_GET_CLASS
<SUBSECTION Private>
gtk_color_chooser_widget_get_type
GtkColorChooserWidgetPrivate
</SECTION>
<SECTION>
<FILE>gtkcolorchooserdialog</FILE>
<TITLE>GtkColorChooserDialog</TITLE>
GtkColorChooserDialog
gtk_color_chooser_dialog_new
<SUBSECTION Standard>
GTK_TYPE_COLOR_CHOOSER_DIALOG
GTK_COLOR_CHOOSER_DIALOG
GTK_COLOR_CHOOSER_DIALOG_CLASS
GTK_IS_COLOR_CHOOSER_DIALOG
GTK_IS_COLOR_CHOOSER_DIALOG_CLASS
GTK_COLOR_CHOOSER_DIALOG_GET_CLASS
<SUBSECTION Private>
GtkColorChooserDialogPrivate
gtk_color_chooser_dialog_get_type
</SECTION>

View File

@@ -6,7 +6,6 @@ gtk_accel_group_get_type
gtk_accel_label_get_type
gtk_accel_map_get_type
gtk_accessible_get_type
gtk_actionable_get_type
gtk_action_get_type
gtk_action_group_get_type
gtk_activatable_get_type
@@ -47,9 +46,6 @@ 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
gtk_color_chooser_widget_get_type
gtk_color_selection_dialog_get_type
gtk_color_selection_get_type
gtk_combo_box_get_type
@@ -77,7 +73,6 @@ gtk_font_chooser_widget_get_type
gtk_font_selection_dialog_get_type
gtk_font_selection_get_type
gtk_frame_get_type
gtk_gestures_interpreter_get_type
gtk_grid_get_type
gtk_handle_box_get_type
gtk_hbox_get_type

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

View File

@@ -2,7 +2,7 @@
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="gtk-migrating-unique-GtkApplication">
<chapter id="gtk-migrating-GtkApplication">
<title>Migrating from libunique to GApplication or GtkApplication</title>
@@ -20,7 +20,7 @@
<example><title>A unique application</title>
<para>Here is a simple application using libunique:
<informalexample><programlisting>
<programlisting>
int
main (int argc, char *argv[])
{
@@ -53,9 +53,9 @@ main (int argc, char *argv[])
return 0;
}
</programlisting></informalexample>
</programlisting>
The same application using GtkApplication:
<informalexample><programlisting>
<programlisting>
static void
activate (GtkApplication *app)
{
@@ -85,13 +85,13 @@ main (int argc, char *argv[])
app = gtk_application_new ("org.gtk.TestApplication", 0);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
status = g_application_run (app);
g_object_unref (app);
return status;
}
</programlisting></informalexample>
</programlisting>
</para>
</example>
<section><title>Uniqueness</title>

View File

@@ -3,10 +3,10 @@
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="gtk-migrating-checklist">
<title>Migration Details Checklist</title>
<title>Migration Checklist</title>
<para>
This chapter includes a checklist of smaller things you need to do to
This chapter includes a checklist of things you need to do to
ensure that your programs are good citizens in the GTK+ world. By
paying attention to the points in the checklist, you ensure that
many automatic features of GTK+ will work correctly in your

View File

@@ -1,48 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="gtk-migrating-smclient-GtkApplication">
<title>Migrating from EggSMClient to GtkApplication</title>
<para>
EggSMClient provides 'session management' support for applications.
This means a number of things:
<itemizedlist>
<listitem>logout notification and negotiation</listitem>
<listitem>application state saving</listitem>
<listitem>restarting of applications with saved state</listitem>
</itemizedlist>
EggSMClient supports this functionality to varying degrees on
Windows and OS X, as well as with XSMP and D-Bus based session
managers in X11.
</para>
<para>
Starting with GTK+ 3.4, #GtkApplication supports logout notification
and negotiation similar to EggSMClient.
</para>
<table>
<tgroup cols="2">
<title>EggSMClient to GtkApplication</title>
<thead>
<row><entry>EggSMClient</entry><entry>GtkApplication</entry></row>
</thead>
<tbody>
<row><entry>EggSMClient::quit-requested</entry><entry>instead of calling will_quit (FALSE,...) in response to this signal, install an inhibitor</entry></row>
<row><entry>EggSMClient::quit</entry><entry>the #GtkApplication::quit signal</entry></row>
<row><entry>EggSMClient::quit-cancelled</entry><entry></entry></row>
<row><entry>egg_sm_client_will_quit</entry><entry>instead of calling will_quit (FALSE,...), install an inhibitor</entry></row>
<row><entry>egg_sm_client_end_session</entry><entry>gtk_application_end_session()</entry></row>
</tbody>
</tgroup>
</table>
<para>
At this point, GtkApplication has no special support for state saving.
Applications can use GSettings or GKeyFile and save as much state as
they see fit in response to #GtkApplication::quit or whenever they
consider appropriate.
</para>
</chapter>

View File

@@ -121,9 +121,9 @@ Here's a simple example:
do_small_part_of_task ();
if (task_complete)
return G_SOURCE_REMOVE; /* removes the idle handler */
return FALSE; /* removes the idle handler */
else
return G_SOURCE_CONTINUE; /* runs the idle handler again */
return TRUE; /* runs the idle handler again */
}
g_idle_add (my_idle_handler, NULL);

View File

@@ -135,10 +135,4 @@
<link linkend="GtkSwitch">
<inlinegraphic fileref="switch.png" format="PNG"></inlinegraphic>
</link>
<link linkend="GtkColorChooserDialog">
<inlinegraphic fileref="colorchooser.png" format="PNG"></inlinegraphic>
</link>
<link linkend="GtkFontChooserDialog">
<inlinegraphic fileref="fontchooser.png" format="PNG"></inlinegraphic>
</link>
</para>

View File

@@ -1154,33 +1154,6 @@ create_appchooserdialog (void)
return info;
}
static WidgetInfo *
create_fontchooserdialog (void)
{
WidgetInfo *info;
GtkWidget *widget;
widget = gtk_font_chooser_dialog_new ("Font Chooser Dialog", NULL);
gtk_window_set_default_size (GTK_WINDOW (widget), 200, 300);
info = new_widget_info ("fontchooser", widget, ASIS);
info->include_decorations = TRUE;
return info;
}
static WidgetInfo *
create_colorchooserdialog (void)
{
WidgetInfo *info;
GtkWidget *widget;
widget = gtk_color_chooser_dialog_new ("Color Chooser Dialog", NULL);
info = new_widget_info ("colorchooser", widget, ASIS);
info->include_decorations = TRUE;
return info;
}
GList *
get_all_widgets (void)
{
@@ -1231,8 +1204,6 @@ get_all_widgets (void)
retval = g_list_prepend (retval, create_appchooserbutton ());
retval = g_list_prepend (retval, create_appchooserdialog ());
retval = g_list_prepend (retval, create_lockbutton ());
retval = g_list_prepend (retval, create_fontchooserdialog ());
retval = g_list_prepend (retval, create_colorchooserdialog ());
return retval;
}

View File

@@ -13,14 +13,6 @@ activate_toggle (GSimpleAction *action,
g_variant_unref (state);
}
static void
activate_radio (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
g_action_change_state (G_ACTION (action), parameter);
}
static void
change_fullscreen_state (GSimpleAction *action,
GVariant *state,
@@ -34,29 +26,6 @@ change_fullscreen_state (GSimpleAction *action,
g_simple_action_set_state (action, state);
}
static void
change_justify_state (GSimpleAction *action,
GVariant *state,
gpointer user_data)
{
GtkTextView *text = g_object_get_data (user_data, "bloatpad-text");
const gchar *str;
str = g_variant_get_string (state, NULL);
if (g_str_equal (str, "left"))
gtk_text_view_set_justification (text, GTK_JUSTIFY_LEFT);
else if (g_str_equal (str, "center"))
gtk_text_view_set_justification (text, GTK_JUSTIFY_CENTER);
else if (g_str_equal (str, "right"))
gtk_text_view_set_justification (text, GTK_JUSTIFY_RIGHT);
else
/* ignore this attempted change */
return;
g_simple_action_set_state (action, state);
}
static GtkClipboard *
get_clipboard (GtkWidget *widget)
{
@@ -93,8 +62,7 @@ window_paste (GSimpleAction *action,
static GActionEntry win_entries[] = {
{ "copy", window_copy, NULL, NULL, NULL },
{ "paste", window_paste, NULL, NULL, NULL },
{ "fullscreen", activate_toggle, NULL, "false", change_fullscreen_state },
{ "justify", activate_radio, "s", "'left'", change_justify_state }
{ "fullscreen", activate_toggle, NULL, "false", change_fullscreen_state }
};
static void
@@ -102,9 +70,6 @@ new_window (GApplication *app,
GFile *file)
{
GtkWidget *window, *grid, *scrolled, *view;
GtkWidget *toolbar;
GtkToolItem *button;
GtkWidget *sw, *box, *label;
window = gtk_application_window_new (GTK_APPLICATION (app));
gtk_window_set_default_size ((GtkWindow*)window, 640, 480);
@@ -114,36 +79,6 @@ new_window (GApplication *app,
grid = gtk_grid_new ();
gtk_container_add (GTK_CONTAINER (window), grid);
toolbar = gtk_toolbar_new ();
button = gtk_toggle_tool_button_new_from_stock (GTK_STOCK_JUSTIFY_LEFT);
gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button), "win.justify::left");
gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (button));
button = gtk_toggle_tool_button_new_from_stock (GTK_STOCK_JUSTIFY_CENTER);
gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button), "win.justify::center");
gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (button));
button = gtk_toggle_tool_button_new_from_stock (GTK_STOCK_JUSTIFY_RIGHT);
gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button), "win.justify::right");
gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (button));
button = gtk_separator_tool_item_new ();
gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (button), FALSE);
gtk_tool_item_set_expand (GTK_TOOL_ITEM (button), TRUE);
gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (button));
button = gtk_tool_item_new ();
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_container_add (GTK_CONTAINER (button), box);
label = gtk_label_new ("Fullscreen:");
gtk_container_add (GTK_CONTAINER (box), label);
sw = gtk_switch_new ();
gtk_actionable_set_action_name (GTK_ACTIONABLE (sw), "win.fullscreen");
gtk_container_add (GTK_CONTAINER (box), sw);
gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (button));
gtk_grid_attach (GTK_GRID (grid), toolbar, 0, 0, 1, 1);
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE);
@@ -153,7 +88,7 @@ new_window (GApplication *app,
gtk_container_add (GTK_CONTAINER (scrolled), view);
gtk_grid_attach (GTK_GRID (grid), scrolled, 0, 1, 1, 1);
gtk_grid_attach (GTK_GRID (grid), scrolled, 0, 0, 1, 1);
if (file != NULL)
{
@@ -207,15 +142,13 @@ new_activated (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GApplication *app = user_data;
g_application_activate (app);
g_application_activate (user_data);
}
static void
about_activated (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
show_about (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
gtk_show_about_dialog (NULL,
"program-name", "Bloatpad",
@@ -225,14 +158,16 @@ about_activated (GSimpleAction *action,
}
static void
quit_app (GtkApplication *app)
quit_app (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GList *list, *next;
GtkWindow *win;
g_print ("Going down...\n");
list = gtk_application_get_windows (app);
list = gtk_application_get_windows (GTK_APPLICATION (g_application_get_default ()));
while (list)
{
win = list->data;
@@ -244,20 +179,10 @@ quit_app (GtkApplication *app)
}
}
static void
quit_activated (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GtkApplication *app = user_data;
quit_app (app);
}
static GActionEntry app_entries[] = {
{ "new", new_activated, NULL, NULL, NULL },
{ "about", about_activated, NULL, NULL, NULL },
{ "quit", quit_activated, NULL, NULL, NULL },
{ "about", show_about, NULL, NULL, NULL },
{ "quit", quit_app, NULL, NULL, NULL },
};
static void
@@ -275,50 +200,25 @@ bloat_pad_startup (GApplication *application)
"<interface>"
" <menu id='app-menu'>"
" <section>"
" <item>"
" <attribute name='label' translatable='yes'>_New Window</attribute>"
" <attribute name='action'>app.new</attribute>"
" <attribute name='accel'>&lt;Primary&gt;n</attribute>"
" </item>"
" <item label='_New Window' action='app.new' accel='<Primary>n'/>"
" </section>"
" <section>"
" <item>"
" <attribute name='label' translatable='yes'>_About Bloatpad</attribute>"
" <attribute name='action'>app.about</attribute>"
" </item>"
" <item label='_About Bloatpad' action='app.about'/>"
" </section>"
" <section>"
" <item>"
" <attribute name='label' translatable='yes'>_Quit</attribute>"
" <attribute name='action'>app.quit</attribute>"
" <attribute name='accel'>&lt;Primary&gt;q</attribute>"
" </item>"
" <item label='_Quit' action='app.quit' accel='<Primary>q'/>"
" </section>"
" </menu>"
" <menu id='menubar'>"
" <submenu>"
" <attribute name='label' translatable='yes'>_Edit</attribute>"
" <submenu label='_Edit'>"
" <section>"
" <item>"
" <attribute name='label' translatable='yes'>_Copy</attribute>"
" <attribute name='action'>win.copy</attribute>"
" <attribute name='accel'>&lt;Primary&gt;c</attribute>"
" </item>"
" <item>"
" <attribute name='label' translatable='yes'>_Parse</attribute>"
" <attribute name='action'>win.parse</attribute>"
" <attribute name='accel'>&lt;Primary&gt;v</attribute>"
" </item>"
" <item label='_Copy' action='win.copy' accel='<Primary>c'/>"
" <item label='_Paste' action='win.paste' accel='<Primary>v'/>"
" </section>"
" </submenu>"
" <submenu>"
" <attribute name='label' translatable='yes'>_View</attribute>"
" <submenu label='_View'>"
" <section>"
" <item>"
" <attribute name='label' translatable='yes'>_Fullscreen</attribute>"
" <attribute name='action'>win.fullscreen</attribute>"
" <attribute name='accel'>F11</attribute>"
" </item>"
" <item label='_Fullscreen' action='win.fullscreen'/>"
" </section>"
" </submenu>"
" </menu>"
@@ -347,33 +247,15 @@ bloat_pad_class_init (BloatPadClass *class)
}
static void
quit_cb (GtkApplication *app)
{
g_print ("Session manager to us to quit\n");
quit_app (app);
}
BloatPad *
bloat_pad_new (void)
{
GtkApplication *bloat_pad;
g_type_init ();
g_set_application_name ("Bloatpad");
bloat_pad = g_object_new (bloat_pad_get_type (),
"application-id", "org.gtk.Test.bloatpad",
"flags", G_APPLICATION_HANDLES_OPEN,
"inactivity-timeout", 30000,
"register-session", TRUE,
NULL);
g_signal_connect (bloat_pad, "quit", G_CALLBACK (quit_cb), NULL);
return bloat_pad;
return g_object_new (bloat_pad_get_type (),
"application-id", "org.gtk.Test.bloatpad",
"flags", G_APPLICATION_HANDLES_OPEN,
NULL);
}
int
@@ -383,12 +265,9 @@ main (int argc, char **argv)
int status;
bloat_pad = bloat_pad_new ();
gtk_application_add_accelerator (GTK_APPLICATION (bloat_pad),
"F11", "win.fullscreen", NULL);
status = g_application_run (G_APPLICATION (bloat_pad), argc, argv);
g_object_unref (bloat_pad);
return status;

View File

@@ -86,11 +86,11 @@ button_press_event_cb (GtkWidget *widget,
if (surface == NULL)
return FALSE;
if (event->button == GDK_BUTTON_PRIMARY)
if (event->button == 1)
{
draw_brush (widget, event->x, event->y);
}
else if (event->button == GDK_BUTTON_SECONDARY)
else if (event->button == 3)
{
clear_surface ();
gtk_widget_queue_draw (widget);

View File

@@ -223,7 +223,6 @@ enable_plugin (const gchar *name)
g_signal_connect (action, "activate", G_CALLBACK (plugin_action), (gpointer)name);
g_action_map_add_action (G_ACTION_MAP (g_application_get_default ()), action);
g_print ("Actions of '%s' plugin added\n", name);
g_object_unref (action);
plugin_menu = find_plugin_menu ();
if (plugin_menu)
@@ -231,14 +230,14 @@ enable_plugin (const gchar *name)
GMenu *section;
GMenuItem *item;
gchar *label;
gchar *action_name;
gchar *action;
section = g_menu_new ();
label = g_strdup_printf ("Turn text %s", name);
action_name = g_strconcat ("app.", name, NULL);
g_menu_insert (section, 0, label, action_name);
action = g_strconcat ("app.", name, NULL);
g_menu_insert (section, 0, label, action);
g_free (label);
g_free (action_name);
g_free (action);
item = g_menu_item_new_section (NULL, (GMenuModel*)section);
g_menu_item_set_attribute (item, "id", "s", name);
g_menu_append_item (G_MENU (plugin_menu), item);

View File

@@ -88,7 +88,6 @@ gdk_public_h_sources = \
gdkselection.h \
gdktestutils.h \
gdkthreads.h \
gdktouchcluster.h \
gdktypes.h \
gdkvisual.h \
gdkwindow.h
@@ -131,7 +130,6 @@ gdk_c_sources = \
gdkrgba.c \
gdkscreen.c \
gdkselection.c \
gdktouchcluster.c \
gdkvisual.c \
gdkwindow.c \
gdkwindowimpl.c

View File

@@ -362,7 +362,7 @@ parse_input (BroadwayInput *input)
gsize len, payload_len;
BroadwayWSOpCode code;
gboolean is_mask, fin;
guchar *buf, *data, *mask;
guchar *buf, *data;
buf = input->buffer->data;
len = input->buffer->len;
@@ -391,16 +391,6 @@ parse_input (BroadwayInput *input)
payload_len = GUINT64_FROM_BE( *(guint64 *) data );
data += 8;
}
mask = NULL;
if (is_mask)
{
if (data - buf + 4 > len)
return;
mask = data;
data += 4;
}
if (data - buf + payload_len > len)
return; /* wait to accumulate more */
@@ -408,7 +398,8 @@ parse_input (BroadwayInput *input)
{
gsize i;
for (i = 0; i < payload_len; i++)
data[i] ^= mask[i%4];
data[i + 4] ^= data[i%4];
data += 4;
}
switch (code) {
@@ -422,11 +413,7 @@ parse_input (BroadwayInput *input)
#endif
}
else
{
char *terminated = g_strndup((char *)data, payload_len);
parse_input_message (input, terminated);
g_free (terminated);
}
parse_input_message (input, (char *)data);
break;
case BROADWAY_WS_CNX_PING:
broadway_output_pong (broadway_display->output);
@@ -487,7 +474,7 @@ process_input_idle_cb (GdkBroadwayDisplay *display)
{
display->process_input_idle = 0;
process_input_messages (display);
return G_SOURCE_REMOVE;
return FALSE;
}
static void
@@ -1016,7 +1003,7 @@ got_http_request_line (GInputStream *stream,
/* Protect against overflow in request length */
if (request->request->len > 1024 * 5)
{
send_error (request, 400, "Request too long");
send_error (request, 400, "Request to long");
}
else
{
@@ -1226,7 +1213,8 @@ gdk_broadway_display_finalize (GObject *object)
_gdk_broadway_cursor_display_finalize (GDK_DISPLAY_OBJECT(broadway_display));
/* input GdkDevice list */
g_list_free_full (broadway_display->input_devices, g_object_unref);
g_list_foreach (broadway_display->input_devices, (GFunc) g_object_unref, NULL);
g_list_free (broadway_display->input_devices);
/* Free all GdkScreens */
g_object_unref (broadway_display->screens[0]);
g_free (broadway_display->screens);

View File

@@ -895,7 +895,7 @@ gdk_threads_add_idle (GSourceFunc function,
*
* self->timeout_id = 0;
*
* return G_SOURCE_REMOVE;
* return FALSE;
* }
*
* static void some_widget_do_stuff_later (SomeWidget *self)

View File

@@ -53,7 +53,6 @@
#include <gdk/gdkselection.h>
#include <gdk/gdktestutils.h>
#include <gdk/gdkthreads.h>
#include <gdk/gdktouchcluster.h>
#include <gdk/gdktypes.h>
#include <gdk/gdkvisual.h>
#include <gdk/gdkwindow.h>

View File

@@ -168,7 +168,6 @@ gdk_event_get_scroll_direction
gdk_event_get_source_device
gdk_event_get_state
gdk_event_get_time
gdk_event_get_touch_id
gdk_event_get_type
gdk_event_handler_set
gdk_event_mask_get_type
@@ -328,11 +327,6 @@ gdk_threads_enter
gdk_threads_init
gdk_threads_leave
gdk_threads_set_lock_functions
gdk_touch_cluster_add_touch
gdk_touch_cluster_get_device
gdk_touch_cluster_get_type G_GNUC_CONST
gdk_touch_cluster_list_touches
gdk_touch_cluster_remove_touch
gdk_unicode_to_keyval
gdk_utf8_to_string_target
gdk_visibility_state_get_type

View File

@@ -38,7 +38,6 @@
* screen or workspace.
* <example>
* <title>Launching an application</title>
* <informalexample>
* <programlisting>
* GdkAppLaunchContext *context;
*
@@ -52,7 +51,6 @@
*
* g_object_unref (context);
* </programlisting>
* </informalexample>
* </example>
*/

View File

@@ -154,7 +154,8 @@ free_device_grabs_foreach (gpointer key,
{
GList *list = value;
g_list_free_full (list, (GDestroyNotify) free_device_grab);
g_list_foreach (list, (GFunc) free_device_grab, NULL);
g_list_free (list);
return TRUE;
}
@@ -188,7 +189,6 @@ gdk_display_init (GdkDisplay *display)
display->double_click_time = 250;
display->double_click_distance = 5;
display->touch_implicit_grabs = g_array_new (FALSE, FALSE, sizeof (GdkTouchGrabInfo));
display->device_grabs = g_hash_table_new (NULL, NULL);
display->motion_hint_info = g_hash_table_new_full (NULL, NULL, NULL,
(GDestroyNotify) g_free);
@@ -211,7 +211,8 @@ gdk_display_dispose (GObject *object)
device_manager = gdk_display_get_device_manager (GDK_DISPLAY (object));
g_list_free_full (display->queued_events, (GDestroyNotify) gdk_event_free);
g_list_foreach (display->queued_events, (GFunc)gdk_event_free, NULL);
g_list_free (display->queued_events);
display->queued_events = NULL;
display->queued_tail = NULL;
@@ -237,8 +238,6 @@ gdk_display_finalize (GObject *object)
NULL);
g_hash_table_destroy (display->device_grabs);
g_array_free (display->touch_implicit_grabs, TRUE);
g_hash_table_destroy (display->motion_hint_info);
g_hash_table_destroy (display->pointers_info);
g_hash_table_destroy (display->multiple_click_info);
@@ -697,81 +696,6 @@ _gdk_display_add_device_grab (GdkDisplay *display,
return info;
}
static void
_gdk_display_break_touch_grabs (GdkDisplay *display,
GdkDevice *device,
GdkWindow *new_grab_window)
{
guint i = 0;
while (i < display->touch_implicit_grabs->len)
{
GdkTouchGrabInfo *info;
info = &g_array_index (display->touch_implicit_grabs,
GdkTouchGrabInfo, i);
if (info->device == device &&
info->window != new_grab_window)
{
generate_grab_broken_event (GDK_WINDOW (info->window),
device, TRUE, new_grab_window);
_gdk_window_finish_touch_id (info->window, device, info->touch_id);
g_array_remove_index_fast (display->touch_implicit_grabs, i);
}
else
i++;
}
}
void
_gdk_display_add_touch_grab (GdkDisplay *display,
GdkDevice *device,
guint touch_id,
GdkWindow *window,
GdkWindow *native_window,
GdkEventMask event_mask,
unsigned long serial,
guint32 time)
{
GdkTouchGrabInfo info;
info.device = device;
info.touch_id = touch_id;
info.window = g_object_ref (window);
info.native_window = g_object_ref (native_window);
info.serial = serial;
info.event_mask = event_mask;
info.time = time;
g_array_append_val (display->touch_implicit_grabs, info);
}
gboolean
_gdk_display_end_touch_grab (GdkDisplay *display,
GdkDevice *device,
guint touch_id)
{
guint i;
for (i = 0; i < display->touch_implicit_grabs->len; i++)
{
GdkTouchGrabInfo *info;
info = &g_array_index (display->touch_implicit_grabs,
GdkTouchGrabInfo, i);
if (info->device == device &&
info->touch_id == touch_id)
{
g_array_remove_index_fast (display->touch_implicit_grabs, i);
return TRUE;
}
}
return FALSE;
}
/* _gdk_synthesize_crossing_events only works inside one toplevel.
This function splits things into two calls if needed, converting the
coordinates to the right toplevel */
@@ -1052,15 +976,12 @@ _gdk_display_device_grab_update (GdkDisplay *display,
next_grab = NULL; /* Actually its not yet active */
}
if (next_grab)
_gdk_display_break_touch_grabs (display, device, next_grab->window);
if ((next_grab == NULL && current_grab->implicit_ungrab) ||
(next_grab != NULL && current_grab->window != next_grab->window))
generate_grab_broken_event (GDK_WINDOW (current_grab->window),
(next_grab != NULL && current_grab->window != next_grab->window))
generate_grab_broken_event (GDK_WINDOW (current_grab->window),
device,
current_grab->implicit,
next_grab? next_grab->window : NULL);
current_grab->implicit,
next_grab? next_grab->window : NULL);
/* Remove old grab */
grabs = g_list_delete_link (grabs, grabs);
@@ -1119,34 +1040,6 @@ _gdk_display_has_device_grab (GdkDisplay *display,
return NULL;
}
GdkTouchGrabInfo *
_gdk_display_has_touch_grab (GdkDisplay *display,
GdkDevice *device,
guint touch_id,
gulong serial)
{
guint i;
for (i = 0; i < display->touch_implicit_grabs->len; i++)
{
GdkTouchGrabInfo *info;
info = &g_array_index (display->touch_implicit_grabs,
GdkTouchGrabInfo, i);
if (info->device == device &&
info->touch_id == touch_id)
{
if (serial >= info->serial)
return info;
else
return NULL;
}
}
return NULL;
}
/* Returns true if last grab was ended
* If if_child is non-NULL, end the grab only if the grabbed
* window is the same as if_child or a descendant of it */

View File

@@ -60,19 +60,6 @@ typedef struct
guint implicit : 1;
} GdkDeviceGrabInfo;
/* Tracks information about a touch implicit grab on this display */
typedef struct
{
GdkDevice *device;
guint touch_id;
GdkWindow *window;
GdkWindow *native_window;
gulong serial;
guint event_mask;
guint32 time;
} GdkTouchGrabInfo;
/* Tracks information about which window and position the pointer last was in.
* This is useful when we need to synthesize events later.
* Note that we track toplevel_under_pointer using enter/leave events,
@@ -118,7 +105,6 @@ struct _GdkDisplay
guint closed : 1; /* Whether this display has been closed */
guint ignore_core_events : 1; /* Don't send core motion and button event */
GArray *touch_implicit_grabs;
GHashTable *device_grabs;
GHashTable *motion_hint_info;
GdkDeviceManager *device_manager;
@@ -276,21 +262,6 @@ gboolean _gdk_display_end_device_grab (GdkDisplay *display
gboolean _gdk_display_check_grab_ownership (GdkDisplay *display,
GdkDevice *device,
gulong serial);
void _gdk_display_add_touch_grab (GdkDisplay *display,
GdkDevice *device,
guint touch_id,
GdkWindow *window,
GdkWindow *native_window,
GdkEventMask event_mask,
unsigned long serial_start,
guint32 time);
GdkTouchGrabInfo * _gdk_display_has_touch_grab (GdkDisplay *display,
GdkDevice *device,
guint touch_id,
gulong serial);
gboolean _gdk_display_end_touch_grab (GdkDisplay *display,
GdkDevice *device,
guint touch_id);
void _gdk_display_enable_motion_hints (GdkDisplay *display,
GdkDevice *device);
GdkPointerWindowInfo * _gdk_display_get_pointer_info (GdkDisplay *display,

View File

@@ -445,7 +445,6 @@ gdk_event_new (GdkEventType type)
switch (type)
{
case GDK_MOTION_NOTIFY:
case GDK_TOUCH_MOTION:
new_event->motion.x = 0.;
new_event->motion.y = 0.;
new_event->motion.x_root = 0.;
@@ -455,8 +454,6 @@ gdk_event_new (GdkEventType type)
case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
case GDK_TOUCH_PRESS:
case GDK_TOUCH_RELEASE:
new_event->button.x = 0.;
new_event->button.y = 0.;
new_event->button.x_root = 0.;
@@ -490,31 +487,7 @@ gdk_event_is_allocated (const GdkEvent *event)
return FALSE;
}
void
_gdk_event_set_pointer_emulated (GdkEvent *event,
gboolean emulated)
{
if (gdk_event_is_allocated (event))
{
GdkEventPrivate *private = (GdkEventPrivate *) event;
if (emulated)
private->flags |= GDK_EVENT_POINTER_EMULATED;
else
private->flags &= ~(GDK_EVENT_POINTER_EMULATED);
}
}
gboolean
_gdk_event_get_pointer_emulated (GdkEvent *event)
{
if (gdk_event_is_allocated (event))
return (((GdkEventPrivate *) event)->flags & GDK_EVENT_POINTER_EMULATED) != 0;
return FALSE;
}
/**
* gdk_event_copy:
* @event: a #GdkEvent
@@ -585,15 +558,12 @@ gdk_event_copy (const GdkEvent *event)
case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
case GDK_TOUCH_PRESS:
case GDK_TOUCH_RELEASE:
if (event->button.axes)
new_event->button.axes = g_memdup (event->button.axes,
sizeof (gdouble) * gdk_device_get_n_axes (event->button.device));
break;
case GDK_MOTION_NOTIFY:
case GDK_TOUCH_MOTION:
if (event->motion.axes)
new_event->motion.axes = g_memdup (event->motion.axes,
sizeof (gdouble) * gdk_device_get_n_axes (event->motion.device));
@@ -613,22 +583,6 @@ gdk_event_copy (const GdkEvent *event)
g_object_ref (new_event->selection.requestor);
break;
case GDK_MULTITOUCH_ADDED:
case GDK_MULTITOUCH_REMOVED:
case GDK_MULTITOUCH_UPDATED:
{
GdkEventMotion **motion_events;
guint i;
motion_events = g_new0 (GdkEventMotion*, event->multitouch.n_events);
for (i = 0; i < event->multitouch.n_events; i++)
motion_events[i] = (GdkEventMotion *) gdk_event_copy ((GdkEvent *) event->multitouch.events[i]);
new_event->multitouch.events = motion_events;
}
break;
default:
break;
}
@@ -685,8 +639,6 @@ gdk_event_free (GdkEvent *event)
case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
case GDK_TOUCH_PRESS:
case GDK_TOUCH_RELEASE:
g_free (event->button.axes);
break;
@@ -697,7 +649,6 @@ gdk_event_free (GdkEvent *event)
break;
case GDK_MOTION_NOTIFY:
case GDK_TOUCH_MOTION:
g_free (event->motion.axes);
break;
@@ -717,20 +668,6 @@ gdk_event_free (GdkEvent *event)
g_object_unref (event->selection.requestor);
break;
case GDK_MULTITOUCH_ADDED:
case GDK_MULTITOUCH_REMOVED:
case GDK_MULTITOUCH_UPDATED:
if (event->multitouch.events)
{
guint i;
for (i = 0; i < event->multitouch.n_events; i++)
gdk_event_free ((GdkEvent *) event->multitouch.events[i]);
g_free (event->multitouch.events);
}
break;
default:
break;
}
@@ -759,14 +696,11 @@ gdk_event_get_time (const GdkEvent *event)
switch (event->type)
{
case GDK_MOTION_NOTIFY:
case GDK_TOUCH_MOTION:
return event->motion.time;
case GDK_BUTTON_PRESS:
case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
case GDK_TOUCH_PRESS:
case GDK_TOUCH_RELEASE:
return event->button.time;
case GDK_SCROLL:
return event->scroll.time;
@@ -792,10 +726,6 @@ gdk_event_get_time (const GdkEvent *event)
case GDK_DROP_START:
case GDK_DROP_FINISHED:
return event->dnd.time;
case GDK_MULTITOUCH_ADDED:
case GDK_MULTITOUCH_REMOVED:
case GDK_MULTITOUCH_UPDATED:
return event->multitouch.time;
case GDK_CLIENT_EVENT:
case GDK_VISIBILITY_NOTIFY:
case GDK_CONFIGURE:
@@ -841,15 +771,12 @@ gdk_event_get_state (const GdkEvent *event,
switch (event->type)
{
case GDK_MOTION_NOTIFY:
case GDK_TOUCH_MOTION:
*state = event->motion.state;
return TRUE;
case GDK_BUTTON_PRESS:
case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
case GDK_TOUCH_PRESS:
case GDK_TOUCH_RELEASE:
*state = event->button.state;
return TRUE;
case GDK_SCROLL:
@@ -863,11 +790,6 @@ gdk_event_get_state (const GdkEvent *event,
case GDK_LEAVE_NOTIFY:
*state = event->crossing.state;
return TRUE;
case GDK_MULTITOUCH_ADDED:
case GDK_MULTITOUCH_REMOVED:
case GDK_MULTITOUCH_UPDATED:
*state = event->multitouch.state;
return TRUE;
case GDK_PROPERTY_NOTIFY:
case GDK_VISIBILITY_NOTIFY:
case GDK_CLIENT_EVENT:
@@ -943,13 +865,10 @@ gdk_event_get_coords (const GdkEvent *event,
case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
case GDK_TOUCH_PRESS:
case GDK_TOUCH_RELEASE:
x = event->button.x;
y = event->button.y;
break;
case GDK_MOTION_NOTIFY:
case GDK_TOUCH_MOTION:
x = event->motion.x;
y = event->motion.y;
break;
@@ -989,7 +908,6 @@ gdk_event_get_root_coords (const GdkEvent *event,
switch (event->type)
{
case GDK_MOTION_NOTIFY:
case GDK_TOUCH_MOTION:
x = event->motion.x_root;
y = event->motion.y_root;
break;
@@ -1001,8 +919,6 @@ gdk_event_get_root_coords (const GdkEvent *event,
case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
case GDK_TOUCH_PRESS:
case GDK_TOUCH_RELEASE:
x = event->button.x_root;
y = event->button.y_root;
break;
@@ -1246,8 +1162,7 @@ gdk_event_get_axis (const GdkEvent *event,
switch (event->type)
{
case GDK_MOTION_NOTIFY:
case GDK_TOUCH_MOTION:
case GDK_MOTION_NOTIFY:
x = event->motion.x;
y = event->motion.y;
break;
@@ -1257,8 +1172,6 @@ gdk_event_get_axis (const GdkEvent *event,
break;
case GDK_BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
case GDK_TOUCH_PRESS:
case GDK_TOUCH_RELEASE:
x = event->button.x;
y = event->button.y;
break;
@@ -1280,15 +1193,12 @@ gdk_event_get_axis (const GdkEvent *event,
return TRUE;
}
else if (event->type == GDK_BUTTON_PRESS ||
event->type == GDK_BUTTON_RELEASE ||
event->type == GDK_TOUCH_PRESS ||
event->type == GDK_TOUCH_RELEASE)
event->type == GDK_BUTTON_RELEASE)
{
device = event->button.device;
axes = event->button.axes;
}
else if (event->type == GDK_MOTION_NOTIFY ||
event->type == GDK_TOUCH_MOTION)
else if (event->type == GDK_MOTION_NOTIFY)
{
device = event->motion.device;
axes = event->motion.axes;
@@ -1325,15 +1235,12 @@ gdk_event_set_device (GdkEvent *event,
switch (event->type)
{
case GDK_MOTION_NOTIFY:
case GDK_TOUCH_MOTION:
event->motion.device = device;
break;
case GDK_BUTTON_PRESS:
case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
case GDK_TOUCH_PRESS:
case GDK_TOUCH_RELEASE:
event->button.device = device;
break;
case GDK_SCROLL:
@@ -1343,10 +1250,6 @@ gdk_event_set_device (GdkEvent *event,
case GDK_PROXIMITY_OUT:
event->proximity.device = device;
break;
case GDK_MULTITOUCH_ADDED:
case GDK_MULTITOUCH_REMOVED:
case GDK_MULTITOUCH_UPDATED:
event->multitouch.device = device;
default:
break;
}
@@ -1379,24 +1282,17 @@ gdk_event_get_device (const GdkEvent *event)
switch (event->type)
{
case GDK_MOTION_NOTIFY:
case GDK_TOUCH_MOTION:
return event->motion.device;
case GDK_BUTTON_PRESS:
case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
case GDK_TOUCH_PRESS:
case GDK_TOUCH_RELEASE:
return event->button.device;
case GDK_SCROLL:
return event->scroll.device;
case GDK_PROXIMITY_IN:
case GDK_PROXIMITY_OUT:
return event->proximity.device;
case GDK_MULTITOUCH_ADDED:
case GDK_MULTITOUCH_REMOVED:
case GDK_MULTITOUCH_UPDATED:
return event->multitouch.device;
default:
break;
}
@@ -1405,13 +1301,10 @@ gdk_event_get_device (const GdkEvent *event)
switch (event->type)
{
case GDK_MOTION_NOTIFY:
case GDK_TOUCH_MOTION:
case GDK_BUTTON_PRESS:
case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
case GDK_TOUCH_PRESS:
case GDK_TOUCH_RELEASE:
case GDK_ENTER_NOTIFY:
case GDK_LEAVE_NOTIFY:
case GDK_FOCUS_CHANGE:
@@ -1427,9 +1320,6 @@ gdk_event_get_device (const GdkEvent *event)
case GDK_GRAB_BROKEN:
case GDK_KEY_PRESS:
case GDK_KEY_RELEASE:
case GDK_MULTITOUCH_ADDED:
case GDK_MULTITOUCH_REMOVED:
case GDK_MULTITOUCH_UPDATED:
{
GdkDisplay *display;
GdkDeviceManager *device_manager;
@@ -1570,7 +1460,7 @@ gdk_event_request_motions (const GdkEventMotion *event)
* also trigger a context menu if this modifier is pressed.
*
* This function should always be used instead of simply checking for
* event->button == %GDK_BUTTON_SECONDARY.
* event->button == 3.
*
* Returns: %TRUE if the event should trigger a context menu.
*
@@ -1589,7 +1479,7 @@ gdk_event_triggers_context_menu (const GdkEvent *event)
g_return_val_if_fail (GDK_IS_WINDOW (bevent->window), FALSE);
if (bevent->button == GDK_BUTTON_SECONDARY &&
if (bevent->button == 3 &&
! (bevent->state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK)))
return TRUE;
@@ -1599,7 +1489,7 @@ gdk_event_triggers_context_menu (const GdkEvent *event)
GDK_MODIFIER_INTENT_CONTEXT_MENU);
if (modifier != 0 &&
bevent->button == GDK_BUTTON_PRIMARY &&
bevent->button == 1 &&
! (bevent->state & (GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) &&
(bevent->state & modifier))
return TRUE;
@@ -1796,138 +1686,6 @@ gdk_event_get_screen (const GdkEvent *event)
return NULL;
}
/**
* gdk_event_get_touch_id:
* @event: a #GdkEvent
* @touch_id: return location of the touch ID of a touch event
*
* If @event if of type %GDK_TOUCH_MOTION, %GDK_TOUCH_PRESS or
* %GDK_TOUCH_RELEASE, fills in @touch_id and returns %TRUE,
* else it returns %FALSE.
*
* Returns: %TRUE if the touch ID can be extracted from @event.
*
* Since: 3.4
**/
gboolean
gdk_event_get_touch_id (const GdkEvent *event,
guint *touch_id)
{
if (!event)
return FALSE;
if (event->type == GDK_TOUCH_MOTION)
{
if (touch_id)
*touch_id = event->motion.touch_id;
return TRUE;
}
else if (event->type == GDK_TOUCH_PRESS ||
event->type == GDK_TOUCH_RELEASE)
{
if (touch_id)
*touch_id = event->button.touch_id;
return TRUE;
}
else
{
if (touch_id)
*touch_id = 0;
return FALSE;
}
}
/**
* gdk_event_get_touch_area:
* @event: a #GdkEvent
*
* This function takes a #GdkEvent coming from a touch device
* (eg. gdk_event_get_source_device() returns a device of type
* %GDK_SOURCE_TOUCH), and returns the area covered by the touch
* as a #cairo_region_t. or %NULL if the device doesn't provide
* this information, or the touch area information couldn't be
* extracted from the event.
*
* <note><warning>Not all touch capable devices provide this
* information, so provide fallbacks to this function returning
* %NULL, even if the window receiving events is only meant
* to react to touch events.</warning></note>
*
* Returns: (transfer full): the touch region, or %NULL if unavailable
*
* Since: 3.4
**/
cairo_region_t *
gdk_event_get_touch_area (GdkEvent *event)
{
gdouble *axes, minor_axis, major_axis, orientation_axis;
GdkAtom major, minor, orientation;
GdkDevice *device;
g_return_val_if_fail (event != NULL, NULL);
device = gdk_event_get_source_device (event);
if (!device)
return NULL;
if (event->type == GDK_MOTION_NOTIFY ||
event->type == GDK_TOUCH_MOTION)
axes = event->motion.axes;
else if (event->type == GDK_BUTTON_PRESS ||
event->type == GDK_2BUTTON_PRESS ||
event->type == GDK_3BUTTON_PRESS ||
event->type == GDK_BUTTON_RELEASE)
axes = event->button.axes;
else
return NULL;
major = gdk_atom_intern_static_string ("Abs MT Touch Major");
minor = gdk_atom_intern_static_string ("Abs MT Touch Minor");
orientation = gdk_atom_intern_static_string ("Abs MT Orientation");
if (gdk_device_get_axis_value (device, axes, major, &major_axis) &&
gdk_device_get_axis_value (device, axes, minor, &minor_axis) &&
gdk_device_get_axis_value (device, axes, orientation, &orientation_axis))
{
cairo_rectangle_int_t rect;
GdkScreen *screen;
gdouble x, y;
/* FIXME: We're assuming the device is mapped to a single screen,
* could lead to stretched/shrinked shapes in multimonitor, although
* that'd be an unusual setup for touchscreens.
*/
screen = gdk_window_get_screen (event->any.window);
gdk_event_get_coords (event, &x, &y);
if (orientation_axis == 0)
{
/* Orientation is horizontal */
rect.width = (gint) gdk_screen_get_width (screen) * major_axis;
rect.height = (gint) gdk_screen_get_height (screen) * minor_axis;
}
else
{
/* Orientation is vertical */
rect.height = (gint) gdk_screen_get_height (screen) * major_axis;
rect.width = (gint) gdk_screen_get_width (screen) * minor_axis;
}
/* Something is wrong here */
if (rect.width == 0 ||
rect.height == 0)
return NULL;
rect.x = x - rect.width / 2;
rect.y = y - rect.height / 2;
return cairo_region_create_rectangle (&rect);
}
return NULL;
}
/**
* gdk_set_show_events:
* @show_events: %TRUE to output event debugging information.

View File

@@ -35,7 +35,6 @@
#include <gdk/gdktypes.h>
#include <gdk/gdkdnd.h>
#include <gdk/gdkdevice.h>
#include <gdk/gdktouchcluster.h>
G_BEGIN_DECLS
@@ -95,37 +94,6 @@ G_BEGIN_DECLS
*/
#define GDK_EVENT_STOP (TRUE)
/**
* GDK_BUTTON_PRIMARY:
*
* The primary button. This is typically the left mouse button, or the
* right button in a left-handed setup.
*
* Since: 3.4
*/
#define GDK_BUTTON_PRIMARY (1)
/**
* GDK_BUTTON_MIDDLE:
*
* The middle button.
*
* Since: 3.4
*/
#define GDK_BUTTON_MIDDLE (2)
/**
* GDK_BUTTON_SECONDARY:
*
* The secondary button. This is typically the right mouse button, or the
* left button in a left-handed setup.
*
* Since: 3.4
*/
#define GDK_BUTTON_SECONDARY (3)
typedef struct _GdkEventAny GdkEventAny;
typedef struct _GdkEventExpose GdkEventExpose;
typedef struct _GdkEventVisibility GdkEventVisibility;
@@ -144,7 +112,6 @@ typedef struct _GdkEventDND GdkEventDND;
typedef struct _GdkEventWindowState GdkEventWindowState;
typedef struct _GdkEventSetting GdkEventSetting;
typedef struct _GdkEventGrabBroken GdkEventGrabBroken;
typedef struct _GdkEventMultiTouch GdkEventMultiTouch;
typedef union _GdkEvent GdkEvent;
@@ -265,18 +232,6 @@ typedef GdkFilterReturn (*GdkFilterFunc) (GdkXEvent *xevent,
* was added in 2.8.
* @GDK_DAMAGE: the content of the window has been changed. This event type
* was added in 2.14.
* @GDK_TOUCH_MOTION: A touch device has been updated. This event type was
* added in 3.4.
* @GDK_TOUCH_PRESS: A new touch stream has just started. This event type was
* added in 3.4.
* @GDK_TOUCH_RELEASE: A touch stream has finished. This event type was
* added in 3.4.
* @GDK_MULTITOUCH_ADDED: A touch ID was added to a #GdkTouchCluster. This
* event type was added in 3.4.
* @GDK_MULTITOUCH_UPDATED: A touch within a #GdkTouchCluster has been updated.
* This event type was added in 3.4.
* @GDK_MULTITOUCH_REMOVED: A touch ID was removed from a #GdkTouchCluster. This
* event type was added in 3.4.
* @GDK_EVENT_LAST: marks the end of the GdkEventType enumeration. Added in 2.18
*
* Specifies the type of the event.
@@ -324,12 +279,6 @@ typedef enum
GDK_OWNER_CHANGE = 34,
GDK_GRAB_BROKEN = 35,
GDK_DAMAGE = 36,
GDK_TOUCH_MOTION = 37,
GDK_TOUCH_PRESS = 38,
GDK_TOUCH_RELEASE = 39,
GDK_MULTITOUCH_ADDED = 40,
GDK_MULTITOUCH_UPDATED = 41,
GDK_MULTITOUCH_REMOVED = 42,
GDK_EVENT_LAST /* helper variable for decls */
} GdkEventType;
@@ -405,6 +354,8 @@ typedef enum
* @GDK_CROSSING_GTK_UNGRAB: crossing because a GTK+ grab is deactivated.
* @GDK_CROSSING_STATE_CHANGED: crossing because a GTK+ widget changed
* state (e.g. sensitivity).
* @GDK_CROSSING_STATE_CHANGED: crossing because a GTK+ widget changed
* state (e.g. sensitivity).
* @GDK_CROSSING_TOUCH_PRESS: crossing because a touch device was pressed,
* this event is synthetic as the pointer might have not left the window.
* @GDK_CROSSING_TOUCH_RELEASE: crossing because a touch device was released.
@@ -582,13 +533,8 @@ struct _GdkEventVisibility
* screen.
* @y_root: the y coordinate of the pointer relative to the root of the
* screen.
* @touch_id: touch ID, only meaningful if event is of type %GDK_TOUCH_MOTION.
*
* Generated when the pointer/touch moves.
*
* If the event has a type of %GDK_TOUCH_MOTION, this event will
* pertain to a sequence identified by gdk_event_get_touch_id().
* With multitouch devices, there may be several ongoing sequences.
* Generated when the pointer moves.
*/
struct _GdkEventMotion
{
@@ -603,63 +549,12 @@ struct _GdkEventMotion
gint16 is_hint;
GdkDevice *device;
gdouble x_root, y_root;
guint touch_id;
};
/**
* GdkEventMultiTouch:
* @type: the type of the event (%GDK_MULTITOUCH_ADDED, %GDK_MULTITOUCH_UPDATED
* or %GDK_MULTITOUCH_REMOVED).
* @window: the window which received the event.
* @send_event: %TRUE if the event was sent explicitly (e.g. using
* <function>XSendEvent</function>).
* @time: the time of the event in milliseconds.
* @state: (type GdkModifierType): a bit-mask representing the state of
* the modifier keys (e.g. Control, Shift and Alt) and the pointer
* buttons. See #GdkModifierType.
* @device: the device where the event originated.
* @group: the #GdkTouchCluster containing the touches that generated this event
* @events: an array of events of type %GDK_TOUCH_MOTION for the touches in @group
* @updated_touch_id: the touch ID that caused this event to be generated
* @n_events: the number of events in @events
* @n_updated_event: the index in @events of the event corresponding to
* @updated_touch_id, or -1 for %GDK_MULTITOUCH_REMOVED events.
*
* Used for multitouch events. The @type field will be one of
* %GDK_MULTITOUCH_ADDED, %GDK_MULTITOUCH_UPDATED or
* %GDK_MULTITOUCH_REMOVED.
*
* Multitouch events group the events from the touches in a
* #GdkTouchCluster, so one of these events is generated
* whenever a touch ID generates a new event, or a touch ID
* is added or removed.
*
* For any given touch ID, %GDK_MULTITOUCH_ADDED and
* %GDK_MULTITOUCH_REMOVED events are always paired,
* with any number of %GDK_MULTITOUCH_UPDATED
* events in between. The minimum event stream is an
* added/removed pair.
*/
struct _GdkEventMultiTouch
{
GdkEventType type;
GdkWindow *window;
gint8 send_event;
guint32 time;
guint state;
GdkDevice *device;
GdkTouchCluster *group;
GdkEventMotion **events;
guint updated_touch_id;
gint8 n_events;
gint8 n_updated_event;
};
/**
* GdkEventButton:
* @type: the type of the event (%GDK_BUTTON_PRESS, %GDK_2BUTTON_PRESS,
* %GDK_3BUTTON_PRESS, %GDK_BUTTON_RELEASE, %GDK_TOUCH_PRESS or
* %GDK_TOUCH_RELEASE).
* %GDK_3BUTTON_PRESS or %GDK_BUTTON_RELEASE).
* @window: the window which received the event.
* @send_event: %TRUE if the event was sent explicitly (e.g. using
* <function>XSendEvent</function>).
@@ -680,13 +575,10 @@ struct _GdkEventMultiTouch
* screen.
* @y_root: the y coordinate of the pointer relative to the root of the
* screen.
* @touch_id: touch ID, only meaningful if event is of type %GDK_TOUCH_PRESS
* or %GDK_TOUCH_RELEASE.
*
* Used for button press and button release events. The
* @type field will be one of %GDK_BUTTON_PRESS,
* %GDK_2BUTTON_PRESS, %GDK_3BUTTON_PRESS, %GDK_BUTTON_RELEASE,
* %GDK_TOUCH_PRESS and %GDK_TOUCH_RELEASE.
* %GDK_2BUTTON_PRESS, %GDK_3BUTTON_PRESS, and %GDK_BUTTON_RELEASE.
*
* Double and triple-clicks result in a sequence of events being received.
* For double-clicks the order of events will be:
@@ -718,11 +610,6 @@ struct _GdkEventMultiTouch
* For a double click to occur, the second button press must occur within
* 1/4 of a second of the first. For a triple click to occur, the third
* button press must also occur within 1/2 second of the first button press.
*
* If the event has a type of %GDK_TOUCH_PRESS or %GDK_TOUCH_RELEASE,
* this event will pertain to a sequence identified by
* gdk_event_get_touch_id(). With multitouch devices, there may be
* several ongoing sequences.
*/
struct _GdkEventButton
{
@@ -737,7 +624,6 @@ struct _GdkEventButton
guint button;
GdkDevice *device;
gdouble x_root, y_root;
guint touch_id;
};
/**
@@ -1181,7 +1067,6 @@ union _GdkEvent
GdkEventWindowState window_state;
GdkEventSetting setting;
GdkEventGrabBroken grab_broken;
GdkEventMultiTouch multitouch;
};
GType gdk_event_get_type (void) G_GNUC_CONST;
@@ -1246,10 +1131,6 @@ void gdk_event_set_screen (GdkEvent *event,
GdkScreen *screen);
GdkScreen *gdk_event_get_screen (const GdkEvent *event);
gboolean gdk_event_get_touch_id (const GdkEvent *event,
guint *touch_id);
cairo_region_t * gdk_event_get_touch_area (GdkEvent *event);
void gdk_set_show_events (gboolean show_events);
gboolean gdk_get_show_events (void);

View File

@@ -150,13 +150,7 @@ typedef enum
/* Following flag is set for events on the event queue during
* translation and cleared afterwards.
*/
GDK_EVENT_PENDING = 1 << 0,
/* The following flag is set for:
* 1) touch events emulating pointer events
* 2) pointer events being emulated by a touch sequence.
*/
GDK_EVENT_POINTER_EMULATED = 1 << 1
GDK_EVENT_PENDING = 1 << 0
} GdkEventFlags;
struct _GdkEventPrivate
@@ -266,12 +260,6 @@ struct _GdkWindow
gulong device_changed_handler_id;
guint num_offscreen_children;
/* Store of latest per-touch events, keys are
* GdkDevices, values are hashtables of touchID/info
*/
GHashTable *touch_event_tracker;
GList *touch_clusters;
};
#define GDK_WINDOW_TYPE(d) (((GDK_WINDOW (d)))->window_type)
@@ -287,10 +275,6 @@ GdkEvent* _gdk_event_unqueue (GdkDisplay *display);
void _gdk_event_filter_unref (GdkWindow *window,
GdkEventFilter *filter);
void _gdk_event_set_pointer_emulated (GdkEvent *event,
gboolean emulated);
gboolean _gdk_event_get_pointer_emulated (GdkEvent *event);
void _gdk_event_emit (GdkEvent *event);
GList* _gdk_event_queue_find_first (GdkDisplay *display);
void _gdk_event_queue_remove_link (GdkDisplay *display,
@@ -334,9 +318,6 @@ gboolean _gdk_window_update_viewable (GdkWindow *window);
void _gdk_window_process_updates_recurse (GdkWindow *window,
cairo_region_t *expose_region);
gboolean _gdk_window_finish_touch_id (GdkWindow *window,
GdkDevice *device,
guint touch_id);
void _gdk_screen_close (GdkScreen *screen);

View File

@@ -145,12 +145,19 @@ _gdk_offscreen_window_create_surface (GdkWindow *offscreen,
{
cairo_surface_t *similar;
cairo_surface_t *surface;
cairo_content_t content = CAIRO_CONTENT_COLOR;
g_return_val_if_fail (GDK_IS_OFFSCREEN_WINDOW (offscreen->impl), NULL);
similar = _gdk_window_ref_cairo_surface (offscreen->parent);
surface = cairo_surface_create_similar (similar, CAIRO_CONTENT_COLOR_ALPHA, width, height);
if (gdk_window_get_visual (offscreen) ==
gdk_screen_get_rgba_visual (gdk_window_get_screen (offscreen)))
{
content = CAIRO_CONTENT_COLOR_ALPHA;
}
surface = cairo_surface_create_similar (similar, content, width, height);
cairo_surface_destroy (similar);

View File

@@ -27,8 +27,6 @@
#include "config.h"
#include "gdkrgba.h"
#include <string.h>
#include <errno.h>
#include <math.h>
/**
* SECTION:rgba_colors
@@ -73,7 +71,15 @@ G_DEFINE_BOXED_TYPE (GdkRGBA, gdk_rgba,
GdkRGBA *
gdk_rgba_copy (const GdkRGBA *rgba)
{
return g_slice_dup (GdkRGBA, rgba);
GdkRGBA *copy;
copy = g_slice_new (GdkRGBA);
copy->red = rgba->red;
copy->green = rgba->green;
copy->blue = rgba->blue;
copy->alpha = rgba->alpha;
return copy;
}
/**
@@ -103,17 +109,14 @@ gdk_rgba_free (GdkRGBA *rgba)
* - We accept mixed percentages and non-percentages in a single
* rgb() or rgba() specification.
*/
static gboolean
parse_rgb_value (const gchar *str,
gchar **endp,
gdouble *number)
static double
parse_rgb_value (const char *str,
char **endp)
{
double number;
const char *p;
*number = g_ascii_strtod (str, endp);
if (errno == ERANGE || *endp == str ||
isinf (*number) || isnan (*number))
return FALSE;
number = g_ascii_strtod (str, endp);
p = *endp;
@@ -122,14 +125,12 @@ parse_rgb_value (const gchar *str,
if (*p == '%')
{
*endp = (char *)(p + 1);
*number = CLAMP(*number / 100., 0., 1.);
return CLAMP(number / 100., 0., 1.);
}
else
{
*number = CLAMP(*number / 255., 0., 1.);
return CLAMP(number / 255., 0., 1.);
}
return TRUE;
}
/**
@@ -175,7 +176,6 @@ gdk_rgba_parse (GdkRGBA *rgba,
gboolean has_alpha;
gdouble r, g, b, a;
gchar *str = (gchar *) spec;
gchar *p;
if (strncmp (str, "rgba", 4) == 0)
{
@@ -220,8 +220,7 @@ gdk_rgba_parse (GdkRGBA *rgba,
/* Parse red */
SKIP_WHITESPACES (str);
if (!parse_rgb_value (str, &str, &r))
return FALSE;
r = parse_rgb_value (str, &str);
SKIP_WHITESPACES (str);
if (*str != ',')
@@ -231,8 +230,7 @@ gdk_rgba_parse (GdkRGBA *rgba,
/* Parse green */
SKIP_WHITESPACES (str);
if (!parse_rgb_value (str, &str, &g))
return FALSE;
g = parse_rgb_value (str, &str);
SKIP_WHITESPACES (str);
if (*str != ',')
@@ -242,8 +240,7 @@ gdk_rgba_parse (GdkRGBA *rgba,
/* Parse blue */
SKIP_WHITESPACES (str);
if (!parse_rgb_value (str, &str, &b))
return FALSE;
b = parse_rgb_value (str, &str);
SKIP_WHITESPACES (str);
if (has_alpha)
@@ -254,24 +251,13 @@ gdk_rgba_parse (GdkRGBA *rgba,
str++;
SKIP_WHITESPACES (str);
a = g_ascii_strtod (str, &p);
if (errno == ERANGE || p == str ||
isinf (a) || isnan (a))
return FALSE;
str = p;
a = g_ascii_strtod (str, &str);
SKIP_WHITESPACES (str);
}
if (*str != ')')
return FALSE;
str++;
SKIP_WHITESPACES (str);
if (*str != '\0')
return FALSE;
if (rgba)
{
rgba->red = CLAMP (r, 0, 1);

View File

@@ -1,448 +0,0 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2011 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, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include "gdktouchcluster.h"
#include "gdkintl.h"
/**
* SECTION:touchcluster
* @Short_description: Multitouch handling
* @Title: Multitouch
* @See_also: #GdkEventMultiTouch
*
* #GdkTouchCluster is an object that gathers touch IDs from a
* #GdkDevice, in order to send #GdkEventMultiTouch events
* whenever a touch ID that is contained in the cluster sends
* an event.
*
* #GdkTouchCluster<!-- -->s are always associated to a window,
* you need to create them through gdk_window_create_touch_cluster(),
* and free them through gdk_window_remove_touch_cluster().
*
* Touch IDs from devices can be obtained from %GDK_TOUCH_PRESS,
* %GDK_TOUCH_MOTION or %GDK_TOUCH_RELEASE events through
* gdk_event_get_touch_id(), and then be added via
* gdk_touch_cluster_add_touch(). Note that touch IDs are
* very transient, and they must be dealt with as such.
* touch IDs must not be stored after a GDK_TOUCH_RELEASE,
* and should always be retrieved from the events being
* currently received.
*
* <example>
* <title>Adding touch IDs to a cluster in a GTK+ widget</title>
* <programlisting>
* static gboolean
* widget_button_press (GtkWidget *widget,
* GdkEvent *event)
* {
* guint touch_id;
*
* if (gdk_event_get_touch_id (event, &touch_id))
* {
* /<!-- -->* It is a touch event, delegate processing
* * to the multitouch event handler
* *<!-- -->/
* gdk_touch_cluster_add_touch (priv->touch_cluster, touch_id);
* return TRUE;
* }
*
* /<!-- -->* Normal button processing *<!-- -->/
* ...
* }
* </programlisting>
* </example>
*
* Anytime a touch ID is within a cluster, no %GDK_TOUCH_PRESS,
* %GDK_TOUCH_MOTION or %GDK_TOUCH_RELEASE events will happen
* for the individual touch. The event will be available instead
* as part of the #GdkMultitouchEvent that will be emitted. This
* will hold true until gdk_touch_cluster_remove_touch() is
* called for it. Note that GTK+ will automatically take a
* touch ID out of any cluster if %GDK_TOUCH_RELEASE is gotten
* internally.
*
* <example>
* <title>Typical multitouch event handler</title>
* <programlisting>
* static gboolean
* widget_multitouch_event (GtkWidget *widget,
* GdkEvent *event)
* {
* if (event->type == GDK_MULTITOUCH_ADDED ||
* event->type == GDK_MULTITOUCH_REMOVED)
* {
* /<!-- -->* Update control mode based
* * on the current number of touches
* *<!-- -->/
* priv->control_mode = update_control_mode (event->multitouch.n_events);
* }
* else
* {
* /<!-- -->* A touch ID in the cluster has updated
* * its coordinates, update widget based on the
* * current control mode.
* *<!-- -->/
* update_view (widget, priv->control_mode,
* event->multitouch.events,
* event->multitouch.n_events);
* }
*
* return TRUE;
* }
* </programlisting>
* </example>
*/
typedef struct GdkTouchClusterPrivate GdkTouchClusterPrivate;
struct GdkTouchClusterPrivate
{
GdkDevice *device;
GArray *touches;
};
enum {
PROP_0,
PROP_DEVICE
};
enum {
TOUCH_ADDED,
TOUCH_REMOVED,
LAST_SIGNAL
};
static guint signals [LAST_SIGNAL] = { 0 };
static void gdk_touch_cluster_finalize (GObject *object);
static void gdk_touch_cluster_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void gdk_touch_cluster_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
G_DEFINE_TYPE (GdkTouchCluster, gdk_touch_cluster, G_TYPE_OBJECT)
static void
gdk_touch_cluster_class_init (GdkTouchClusterClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gdk_touch_cluster_finalize;
object_class->get_property = gdk_touch_cluster_get_property;
object_class->set_property = gdk_touch_cluster_set_property;
g_object_class_install_property (object_class,
PROP_DEVICE,
g_param_spec_object ("device",
P_("Device"),
P_("Device attached to the cluster"),
GDK_TYPE_DEVICE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
signals[TOUCH_ADDED] =
g_signal_new (g_intern_static_string ("touch-added"),
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GdkTouchClusterClass, touch_added),
NULL, NULL,
g_cclosure_marshal_VOID__UINT,
G_TYPE_NONE, 1, G_TYPE_UINT);
signals[TOUCH_REMOVED] =
g_signal_new (g_intern_static_string ("touch-removed"),
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GdkTouchClusterClass, touch_removed),
NULL, NULL,
g_cclosure_marshal_VOID__UINT,
G_TYPE_NONE, 1, G_TYPE_UINT);
g_type_class_add_private (object_class, sizeof (GdkTouchClusterPrivate));
}
static void
gdk_touch_cluster_init (GdkTouchCluster *cluster)
{
GdkTouchClusterPrivate *priv;
priv = cluster->priv = G_TYPE_INSTANCE_GET_PRIVATE (cluster,
GDK_TYPE_TOUCH_CLUSTER,
GdkTouchClusterPrivate);
priv->touches = g_array_new (FALSE, FALSE, sizeof (guint));
}
static void
gdk_touch_cluster_finalize (GObject *object)
{
GdkTouchClusterPrivate *priv;
priv = GDK_TOUCH_CLUSTER (object)->priv;
g_array_free (priv->touches, TRUE);
G_OBJECT_CLASS (gdk_touch_cluster_parent_class)->finalize (object);
}
static void
gdk_touch_cluster_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
switch (prop_id)
{
case PROP_DEVICE:
gdk_touch_cluster_set_device (GDK_TOUCH_CLUSTER (object),
g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gdk_touch_cluster_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GdkTouchClusterPrivate *priv;
priv = GDK_TOUCH_CLUSTER (object)->priv;
switch (prop_id)
{
case PROP_DEVICE:
g_value_set_object (value, priv->device);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/**
* gdk_touch_cluster_add_touch:
* @cluster: a #GdkTouchCluster
* @touch_id: a touch ID from a touch event
*
* Adds a touch ID to @cluster, so it will generate a
* %GDK_MULTITOUCH_ADDED event, followed by %GDK_MULTITOUCH_UPDATED
* events whenever this touch ID is updated.
*
* If @touch_id already pertained to another #GdkTouchCluster, it
* will be removed from it, generating a %GDK_MULTITOUCH_REMOVED
* for that another cluster.
*
* Since: 3.4
**/
void
gdk_touch_cluster_add_touch (GdkTouchCluster *cluster,
guint touch_id)
{
GdkTouchClusterPrivate *priv;
gint i;
g_return_if_fail (GDK_IS_TOUCH_CLUSTER (cluster));
priv = cluster->priv;
for (i = 0; i < priv->touches->len; i++)
{
if (touch_id == g_array_index (priv->touches, guint, i))
return;
}
g_array_append_val (priv->touches, touch_id);
g_signal_emit (cluster, signals [TOUCH_ADDED], 0, touch_id);
}
/**
* gdk_touch_cluster_remove_touch:
* @cluster: a #GdkTouchCluster
* @touch_id: a touch ID from a touch event
*
* Removes a touch ID from @cluster, generating a %GDK_MULTITOUCH_REMOVED
* event for @cluster, and causing any further input from @touch_id
* to be reported trough %GDK_TOUCH_MOTION events.
*
* <note><para>
* Note that GTK+ automatically removes a touch ID from any cluster
* if a %GDK_TOUCH_RELEASE event is gotten internally.
* </para></note>
*
* Since: 3.4
**/
void
gdk_touch_cluster_remove_touch (GdkTouchCluster *cluster,
guint touch_id)
{
GdkTouchClusterPrivate *priv;
gint i;
g_return_if_fail (GDK_IS_TOUCH_CLUSTER (cluster));
priv = cluster->priv;
for (i = 0; i < priv->touches->len; i++)
{
if (touch_id == g_array_index (priv->touches, guint, i))
{
g_array_remove_index_fast (priv->touches, i);
g_signal_emit (cluster, signals [TOUCH_REMOVED], 0, touch_id);
return;
}
}
}
/**
* gdk_touch_cluster_remove_all:
* @cluster: a #GdkTouchCluster
*
* Removes all touch IDs from @cluster.
*
* Since: 3.4
**/
void
gdk_touch_cluster_remove_all (GdkTouchCluster *cluster)
{
GdkTouchClusterPrivate *priv;
guint touch_id;
gint i;
g_return_if_fail (GDK_IS_TOUCH_CLUSTER (cluster));
priv = cluster->priv;
for (i = priv->touches->len - 1; i >= 0; i--)
{
touch_id = g_array_index (priv->touches, guint, i);
g_signal_emit (cluster, signals [TOUCH_REMOVED], 0, touch_id);
g_array_remove_index_fast (priv->touches, i);
}
}
/**
* gdk_touch_cluster_get_touches:
* @cluster: a #GdkTouchCluster
* @length: return location for the number of touches returned
*
* Returns the list of touches as an array of @guint.
*
* Returns: (transfer full) (array zero-terminated=0 length=length) (element-type uint): A list of touch IDs.
*
* Since: 3.4
**/
guint *
gdk_touch_cluster_get_touches (GdkTouchCluster *cluster,
gint *len)
{
GdkTouchClusterPrivate *priv;
g_return_val_if_fail (GDK_IS_TOUCH_CLUSTER (cluster), NULL);
priv = cluster->priv;
if (len)
*len = (gint) priv->touches->len;
return g_memdup (priv->touches->data,
sizeof (guint) * priv->touches->len);
}
/**
* gdk_touch_cluster_get_n_touches:
* @cluster: a #GdkTouchCluster
*
* Returns the number of touches contained in @cluster.
*
* Returns: The number of touches.
*
* Since: 3.4
**/
gint
gdk_touch_cluster_get_n_touches (GdkTouchCluster *cluster)
{
GdkTouchClusterPrivate *priv;
g_return_val_if_fail (GDK_IS_TOUCH_CLUSTER (cluster), 0);
priv = cluster->priv;
return (gint) priv->touches->len;
}
/**
* gdk_touch_cluster_set_device:
* @cluster: a #GdkTouchCluster
* @device: a #GdkDevice
*
* Sets the current device associated to @cluster, all contained
* touch IDs must pertain to this device. As a consequence,
* gdk_touch_cluster_remove_all() will be called on @cluster
* if the current device changes.
*
* Since: 3.4
**/
void
gdk_touch_cluster_set_device (GdkTouchCluster *cluster,
GdkDevice *device)
{
GdkTouchClusterPrivate *priv;
g_return_if_fail (GDK_IS_TOUCH_CLUSTER (cluster));
g_return_if_fail (!device || GDK_IS_DEVICE (device));
priv = cluster->priv;
if (priv->device != device)
gdk_touch_cluster_remove_all (cluster);
priv->device = device;
}
/**
* gdk_touch_cluster_get_device:
* @cluster: a #GdkTouchCluster
*
* Returns the slave/floating device this touch cluster pertains to,
* only touch IDs from this device can be included in @cluster.
* the #GdkDevice will typically have the %GDK_SOURCE_TOUCH input source.
*
* Returns: (transfer none): The #GdkDevice generating the contained touch IDs
*
* Since: 3.4
**/
GdkDevice *
gdk_touch_cluster_get_device (GdkTouchCluster *cluster)
{
GdkTouchClusterPrivate *priv;
g_return_val_if_fail (GDK_IS_TOUCH_CLUSTER (cluster), NULL);
priv = cluster->priv;
return priv->device;
}

View File

@@ -1,71 +0,0 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2011 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, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GDK_TOUCH_CLUSTER_H__
#define __GDK_TOUCH_CLUSTER_H__
#include <glib-object.h>
#include <gdk/gdkdevice.h>
G_BEGIN_DECLS
#define GDK_TYPE_TOUCH_CLUSTER (gdk_touch_cluster_get_type ())
#define GDK_TOUCH_CLUSTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_TOUCH_CLUSTER, GdkTouchCluster))
#define GDK_IS_TOUCH_CLUSTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_TOUCH_CLUSTER))
typedef struct _GdkTouchCluster GdkTouchCluster;
typedef struct _GdkTouchClusterClass GdkTouchClusterClass;
struct _GdkTouchCluster
{
GObject parent_instance;
gpointer priv;
};
struct _GdkTouchClusterClass
{
GObjectClass parent_class;
void (* touch_added) (GdkTouchCluster *cluster,
guint touch_id);
void (* touch_removed) (GdkTouchCluster *cluster,
guint touch_id);
gpointer padding[16];
};
GType gdk_touch_cluster_get_type (void) G_GNUC_CONST;
void gdk_touch_cluster_add_touch (GdkTouchCluster *cluster,
guint touch_id);
void gdk_touch_cluster_remove_touch (GdkTouchCluster *cluster,
guint touch_id);
void gdk_touch_cluster_remove_all (GdkTouchCluster *cluster);
guint * gdk_touch_cluster_get_touches (GdkTouchCluster *cluster,
gint *length);
gint gdk_touch_cluster_get_n_touches (GdkTouchCluster *cluster);
void gdk_touch_cluster_set_device (GdkTouchCluster *cluster,
GdkDevice *device);
GdkDevice * gdk_touch_cluster_get_device (GdkTouchCluster *cluster);
G_END_DECLS
#endif /* __GDK_TOUCH_CLUSTER_H__ */

View File

@@ -350,7 +350,6 @@ typedef enum
* @GDK_SUBSTRUCTURE_MASK: receive events about window configuration changes of
* child windows
* @GDK_SCROLL_MASK: receive scroll events
* @GDK_TOUCH_MASK: receive (multi)touch events
* @GDK_ALL_EVENTS_MASK: the combination of all the above event masks.
*
* A set of bit-flags to indicate which events a window is to receive.
@@ -366,13 +365,6 @@ typedef enum
* some of which are marked as a hint (the is_hint member is %TRUE).
* To receive more motion events after a motion hint event, the application
* needs to asks for more, by calling gdk_event_request_motions().
*
* If %GDK_TOUCH_MASK is enabled, the window will receive (multi)touch events
* from touch-enabled devices. Those will come as sequences #GdkEventMotion
* with type %GDK_TOUCH_MOTION, enclosed by 2 #GdkEventButton events with
* type %GDK_TOUCH_PRESS / %GDK_TOUCH_RELEASE. gdk_event_get_touch_id() will
* return the touch ID on those events, so different sequences may be
* distinguished.
*/
typedef enum
{
@@ -397,8 +389,7 @@ typedef enum
GDK_PROXIMITY_OUT_MASK = 1 << 19,
GDK_SUBSTRUCTURE_MASK = 1 << 20,
GDK_SCROLL_MASK = 1 << 21,
GDK_TOUCH_MASK = 1 << 22,
GDK_ALL_EVENTS_MASK = 0x3FFFFF
GDK_ALL_EVENTS_MASK = 0x3FFFFE
} GdkEventMask;
/**

File diff suppressed because it is too large Load Diff

View File

@@ -33,7 +33,6 @@
#include <gdk/gdktypes.h>
#include <gdk/gdkevents.h>
#include <gdk/gdktouchcluster.h>
G_BEGIN_DECLS
@@ -879,12 +878,6 @@ void gdk_window_set_support_multidevice (GdkWindow *window,
gboolean support_multidevice);
gboolean gdk_window_get_support_multidevice (GdkWindow *window);
/* Multitouch support */
GdkTouchCluster * gdk_window_create_touch_cluster (GdkWindow *window,
GdkDevice *device);
void gdk_window_remove_touch_cluster (GdkWindow *window,
GdkTouchCluster *cluster);
G_END_DECLS
#endif /* __GDK_WINDOW_H__ */

View File

@@ -180,7 +180,7 @@ create_builtin_cursor (GdkCursorType cursor_type)
cursor = gdk_quartz_cursor_new_from_nscursor (nscursor, GDK_CURSOR_IS_PIXMAP);
cached_xcursors[cursor_type] = g_object_ref (cursor);
cached_xcursors[cursor_type] = gdk_cursor_ref (cursor);
GDK_QUARTZ_RELEASE_POOL;
@@ -243,7 +243,7 @@ _gdk_quartz_display_get_cursor_for_type (GdkDisplay *display,
case GDK_BLANK_CURSOR:
return create_blank_cursor ();
default:
return g_object_ref (create_builtin_cursor (cursor_type));
return gdk_cursor_ref (create_builtin_cursor (cursor_type));
}
[nscursor retain];

View File

@@ -308,7 +308,8 @@ gdk_quartz_display_finalize (GObject *object)
{
GdkQuartzDisplay *display_quartz = GDK_QUARTZ_DISPLAY (object);
g_list_free_full (display_quartz->input_devices, g_object_unref);
g_list_foreach (display_quartz->input_devices, (GFunc) g_object_unref, NULL);
g_list_free (display_quartz->input_devices);
G_OBJECT_CLASS (gdk_quartz_display_parent_class)->finalize (object);
}

View File

@@ -963,13 +963,6 @@ fill_key_event (GdkWindow *window,
event->key.state |= _gdk_quartz_events_get_current_mouse_modifiers ();
/* The X11 backend adds the first virtual modifier MOD2..MOD5 are
* mapped to. Since we only have one virtual modifier in the quartz
* backend, calling the standard function will do.
*/
gdk_keymap_add_virtual_modifiers (gdk_keymap_get_for_display (_gdk_display),
&event->key.state);
event->key.string = NULL;
/* Fill in ->string since apps depend on it, taken from the x11 backend. */

View File

@@ -1630,18 +1630,7 @@ gdk_window_quartz_restack_toplevel (GdkWindow *window,
GdkWindow *sibling,
gboolean above)
{
GdkWindowImplQuartz *impl;
gint sibling_num;
impl = GDK_WINDOW_IMPL_QUARTZ (sibling->impl);
sibling_num = [impl->toplevel windowNumber];
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
if (above)
[impl->toplevel orderWindow:NSWindowAbove relativeTo:sibling_num];
else
[impl->toplevel orderWindow:NSWindowBelow relativeTo:sibling_num];
/* FIXME: Implement this */
}
static void

View File

@@ -19,9 +19,9 @@ progs_ldadd = \
#check_gdk_cairo_SOURCES = check-gdk-cairo.c
#check_gdk_cairo_LDADD = $(progs_ldadd)
TEST_PROGS += rgba
rgba_SOURCES = rgba.c
rgba_LDADD = $(progs_ldadd)
TEST_PROGS += gdk-color
gdk_color_SOURCES = gdk-color.c
gdk_color_LDADD = $(progs_ldadd)
TEST_PROGS += encoding
encoding_SOURCES = encoding.c

View File

@@ -49,14 +49,6 @@ test_color_parse (void)
res = gdk_rgba_parse (&color, "#0080ff");
g_assert (res);
g_assert (gdk_rgba_equal (&color, &expected));
expected.red = 0.0;
expected.green = 0.0;
expected.blue = 0.0;
expected.alpha = 1.0;
res = gdk_rgba_parse (&color, "rgb(0,0,0)");
g_assert (res);
g_assert (gdk_rgba_equal (&color, &expected));
}
static void
@@ -98,67 +90,13 @@ test_color_to_string (void)
g_free (orig);
}
static void
test_color_copy (void)
{
GdkRGBA rgba;
GdkRGBA *out;
rgba.red = 0.0;
rgba.green = 0.1;
rgba.blue = 0.6;
rgba.alpha = 0.9;
out = gdk_rgba_copy (&rgba);
g_assert (gdk_rgba_equal (&rgba, out));
gdk_rgba_free (out);
}
static void
test_color_parse_nonsense (void)
{
GdkRGBA color;
gboolean res;
g_test_bug ("667485");
res = gdk_rgba_parse (&color, "rgb(,,)");
g_assert (!res);
res = gdk_rgba_parse (&color, "rgb(%,%,%)");
g_assert (!res);
res = gdk_rgba_parse (&color, "rgb(nan,nan,nan)");
g_assert (!res);
res = gdk_rgba_parse (&color, "rgb(inf,inf,inf)");
g_assert (!res);
res = gdk_rgba_parse (&color, "rgb(1p12,0,0)");
g_assert (!res);
res = gdk_rgba_parse (&color, "rgb(5d1%,1,1)");
g_assert (!res);
res = gdk_rgba_parse (&color, "rgb(0,0,0)moo");
g_assert (!res);
res = gdk_rgba_parse (&color, "rgb(0,0,0) moo");
g_assert (!res);
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_bug_base ("http://bugzilla.gnome.org");
g_test_add_func ("/rgba/parse", test_color_parse);
g_test_add_func ("/rgba/parse/nonsense", test_color_parse_nonsense);
g_test_add_func ("/rgba/to-string", test_color_to_string);
g_test_add_func ("/rgba/copy", test_color_copy);
g_test_add_func ("/color/parse", test_color_parse);
g_test_add_func ("/color/to-string", test_color_to_string);
return g_test_run ();
}

View File

@@ -227,7 +227,7 @@ create_cursor(GdkDisplayWayland *display, GdkPixbuf *pixbuf, int x, int y)
fd,
cursor->width,
cursor->height,
stride, WL_SHM_FORMAT_ARGB8888);
stride, WL_SHM_FORMAT_ARGB32);
close(fd);
@@ -293,7 +293,7 @@ _gdk_wayland_display_get_cursor_for_type (GdkDisplay *display,
{
gchar *filename;
filename = g_build_filename (directories[j],
"weston",
"wayland",
cursor_definitions[i].filename,
NULL);
if (g_file_test (filename, G_FILE_TEST_EXISTS))

View File

@@ -17,11 +17,6 @@
* Boston, MA 02111-1307, USA.
*/
#define _GNU_SOURCE
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include "config.h"
#include <string.h>
@@ -37,8 +32,6 @@
#include <X11/extensions/XKBcommon.h>
#include <X11/keysym.h>
#include <sys/time.h>
#define GDK_TYPE_DEVICE_CORE (gdk_device_core_get_type ())
#define GDK_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCore))
#define GDK_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass))
@@ -52,8 +45,6 @@ typedef struct _GdkWaylandDevice GdkWaylandDevice;
typedef struct _DataOffer DataOffer;
typedef struct _GdkWaylandSelectionOffer GdkWaylandSelectionOffer;
struct _GdkWaylandDevice
{
GdkDisplay *display;
@@ -66,16 +57,9 @@ struct _GdkWaylandDevice
struct wl_data_device *data_device;
int32_t x, y, surface_x, surface_y;
uint32_t time;
GdkWindow *pointer_grab_window;
uint32_t pointer_grab_time;
guint32 repeat_timer;
guint32 repeat_key;
guint32 repeat_count;
DataOffer *drag_offer;
DataOffer *selection_offer;
GdkWaylandSelectionOffer *selection_offer_out;
};
struct _GdkDeviceCore
@@ -155,20 +139,14 @@ gdk_device_core_set_window_cursor (GdkDevice *device,
int x, y;
if (cursor)
g_object_ref (cursor);
/* Setting the cursor to NULL means that we should use the default cursor */
if (!cursor)
{
/* FIXME: Is this the best sensible default ? */
cursor = _gdk_wayland_display_get_cursor_for_type (device->display,
GDK_LEFT_PTR);
buffer = _gdk_wayland_cursor_get_buffer(cursor, &x, &y);
wl_input_device_attach(wd->device, wd->time, buffer, x, y);
}
else
{
wl_input_device_attach(wd->device, wd->time, NULL, 0, 0);
}
buffer = _gdk_wayland_cursor_get_buffer(cursor, &x, &y);
wl_input_device_attach(wd->device, wd->time, buffer, x, y);
g_object_unref (cursor);
}
static void
@@ -223,30 +201,6 @@ gdk_device_core_grab (GdkDevice *device,
GdkCursor *cursor,
guint32 time_)
{
GdkWaylandDevice *wayland_device = GDK_DEVICE_CORE (device)->device;
if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
{
/* Device is a keyboard */
return GDK_GRAB_SUCCESS;
}
else
{
/* Device is a pointer */
if (wayland_device->pointer_grab_window != NULL &&
time_ != 0 && wayland_device->pointer_grab_time > time_)
{
return GDK_GRAB_ALREADY_GRABBED;
}
if (time_ == 0)
time_ = wayland_device->time;
wayland_device->pointer_grab_window = window;
wayland_device->pointer_grab_time = time_;
}
return GDK_GRAB_SUCCESS;
}
@@ -254,23 +208,6 @@ static void
gdk_device_core_ungrab (GdkDevice *device,
guint32 time_)
{
GdkDisplay *display;
GdkDeviceGrabInfo *grab;
display = gdk_device_get_display (device);
if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
{
/* Device is a keyboard */
}
else
{
/* Device is a pointer */
grab = _gdk_display_get_last_device_grab (display, device);
if (grab)
grab->serial_end = grab->serial_start;
}
}
static GdkWindow *
@@ -378,19 +315,6 @@ input_handle_button(void *data, struct wl_input_device *input_device,
GdkDisplayWayland *display = GDK_DISPLAY_WAYLAND (device->display);
GdkEvent *event;
uint32_t modifier;
int gdk_button;
switch (button) {
case 273:
gdk_button = 3;
break;
case 274:
gdk_button = 2;
break;
default:
gdk_button = button - 271;
break;
}
device->time = time;
event = gdk_event_new (state ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
@@ -403,10 +327,10 @@ input_handle_button(void *data, struct wl_input_device *input_device,
event->button.y_root = (gdouble) device->y;
event->button.axes = NULL;
event->button.state = device->modifiers;
event->button.button = gdk_button;
event->button.button = button - 271;
gdk_event_set_screen (event, display->screen);
modifier = 1 << (8 + gdk_button - 1);
modifier = 1 << (8 + button - 272);
if (state)
device->modifiers |= modifier;
else
@@ -484,13 +408,11 @@ translate_keyboard_string (GdkEventKey *event)
}
}
static gboolean
keyboard_repeat (gpointer data);
static gboolean
deliver_key_event(GdkWaylandDevice *device,
uint32_t time, uint32_t key, uint32_t state)
static void
input_handle_key(void *data, struct wl_input_device *input_device,
uint32_t time, uint32_t key, uint32_t state)
{
GdkWaylandDevice *device = data;
GdkEvent *event;
uint32_t code, modifier, level;
struct xkb_desc *xkb;
@@ -533,60 +455,6 @@ deliver_key_event(GdkWaylandDevice *device,
"string %s, mods 0x%x",
code, event->key.keyval,
event->key.string, event->key.state));
device->repeat_count++;
device->repeat_key = key;
if (state == 0)
{
if (device->repeat_timer)
{
g_source_remove (device->repeat_timer);
device->repeat_timer = 0;
}
return FALSE;
}
else if (modifier)
{
return FALSE;
}
else switch (device->repeat_count)
{
case 1:
if (device->repeat_timer)
{
g_source_remove (device->repeat_timer);
device->repeat_timer = 0;
}
device->repeat_timer =
gdk_threads_add_timeout (400, keyboard_repeat, device);
return TRUE;
case 2:
device->repeat_timer =
gdk_threads_add_timeout (80, keyboard_repeat, device);
return FALSE;
default:
return TRUE;
}
}
static gboolean
keyboard_repeat (gpointer data)
{
GdkWaylandDevice *device = data;
return deliver_key_event (device, device->time, device->repeat_key, 1);
}
static void
input_handle_key(void *data, struct wl_input_device *input_device,
uint32_t time, uint32_t key, uint32_t state)
{
GdkWaylandDevice *device = data;
device->repeat_count = 0;
deliver_key_event (data, time, key, state);
}
static void
@@ -688,7 +556,6 @@ input_handle_keyboard_focus(void *data,
device->time = time;
if (device->keyboard_focus)
{
_gdk_wayland_window_remove_focus (device->keyboard_focus);
event = gdk_event_new (GDK_FOCUS_CHANGE);
event->focus_change.window = g_object_ref (device->keyboard_focus);
event->focus_change.send_event = FALSE;
@@ -723,8 +590,6 @@ input_handle_keyboard_focus(void *data,
device, device->keyboard_focus));
_gdk_wayland_display_deliver_event (device->display, event);
_gdk_wayland_window_add_focus (device->keyboard_focus);
}
}
@@ -858,21 +723,14 @@ data_device_selection (void *data,
struct wl_data_offer *offer)
{
GdkWaylandDevice *device = (GdkWaylandDevice *)data;
GdkDeviceManager *device_manager =
gdk_display_get_device_manager (device->display);
GdkDeviceManagerCore *device_manager_core =
GDK_DEVICE_MANAGER_CORE (device_manager);
g_debug (G_STRLOC ": %s wl_data_device = %p wl_data_offer = %p",
G_STRFUNC, wl_data_device, offer);
if (!offer)
{
if (device->selection_offer)
{
data_offer_unref (device->selection_offer);
device->selection_offer = NULL;
}
return;
}
if (device->selection_offer)
{
data_offer_unref (device->selection_offer);
@@ -953,7 +811,7 @@ _gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager,
}
static void
free_device (gpointer data)
free_device (void *data, void *user_data)
{
g_object_unref (data);
}
@@ -965,7 +823,8 @@ gdk_device_manager_core_finalize (GObject *object)
device_manager_core = GDK_DEVICE_MANAGER_CORE (object);
g_list_free_full (device_manager_core->devices, free_device);
g_list_foreach (device_manager_core->devices, free_device, NULL);
g_list_free (device_manager_core->devices);
G_OBJECT_CLASS (gdk_device_manager_core_parent_class)->finalize (object);
}
@@ -1018,290 +877,3 @@ _gdk_wayland_device_manager_new (GdkDisplay *display)
"display", display,
NULL);
}
gint
gdk_wayland_device_get_selection_type_atoms (GdkDevice *gdk_device,
GdkAtom **atoms_out)
{
gint i;
GdkAtom *atoms;
GdkWaylandDevice *device;
g_return_val_if_fail (GDK_IS_DEVICE_CORE (gdk_device), 0);
g_return_val_if_fail (atoms_out != NULL, 0);
device = GDK_DEVICE_CORE (gdk_device)->device;
if (!device->selection_offer || device->selection_offer->types->len == 0)
{
*atoms_out = NULL;
return 0;
}
atoms = g_new0 (GdkAtom, device->selection_offer->types->len);
/* Convert list of targets to atoms */
for (i = 0; i < device->selection_offer->types->len; i++)
{
atoms[i] = gdk_atom_intern (device->selection_offer->types->pdata[i],
FALSE);
GDK_NOTE (MISC,
g_message (G_STRLOC ": Adding atom for %s",
(char *)device->selection_offer->types->pdata[i]));
}
*atoms_out = atoms;
return device->selection_offer->types->len;
}
typedef struct
{
GdkWaylandDevice *device;
DataOffer *offer;
GIOChannel *channel;
GdkDeviceWaylandRequestContentCallback cb;
gpointer userdata;
} RequestContentClosure;
static gboolean
_request_content_io_func (GIOChannel *channel,
GIOCondition condition,
gpointer userdata)
{
RequestContentClosure *closure = (RequestContentClosure *)userdata;
gchar *data = NULL;
gsize len = 0;
GError *error = NULL;
/* FIXME: We probably want to do something better than this to avoid
* blocking on the transfer of large pieces of data: call the callback
* multiple times I should think.
*/
if (g_io_channel_read_to_end (channel,
&data,
&len,
&error) != G_IO_STATUS_NORMAL)
{
g_warning (G_STRLOC ": Error reading content from pipe: %s", error->message);
g_clear_error (&error);
}
/* Since we use _read_to_end we've got a guaranteed EOF and thus can go
* ahead and close the fd
*/
g_io_channel_shutdown (channel, TRUE, NULL);
closure->cb (closure->device->pointer, data, len, closure->userdata);
g_free (data);
data_offer_unref (closure->offer);
g_io_channel_unref (channel);
g_free (closure);
return FALSE;
}
gboolean
gdk_wayland_device_request_selection_content (GdkDevice *gdk_device,
const gchar *requested_mime_type,
GdkDeviceWaylandRequestContentCallback cb,
gpointer userdata)
{
int pipe_fd[2];
RequestContentClosure *closure;
GdkWaylandDevice *device;
GError *error = NULL;
g_return_val_if_fail (GDK_IS_DEVICE_CORE (gdk_device), FALSE);
g_return_val_if_fail (requested_mime_type != NULL, FALSE);
g_return_val_if_fail (cb != NULL, FALSE);
device = GDK_DEVICE_CORE (gdk_device)->device;
if (!device->selection_offer)
return FALSE;
/* TODO: Check mimetypes */
closure = g_new0 (RequestContentClosure, 1);
device->selection_offer->ref_count++;
pipe2 (pipe_fd, O_CLOEXEC);
wl_data_offer_receive (device->selection_offer->offer,
requested_mime_type,
pipe_fd[1]);
close (pipe_fd[1]);
closure->device = device;
closure->offer = device->selection_offer;
closure->channel = g_io_channel_unix_new (pipe_fd[0]);
closure->cb = cb;
closure->userdata = userdata;
if (!g_io_channel_set_encoding (closure->channel, NULL, &error))
{
g_warning (G_STRLOC ": Error setting encoding on channel: %s",
error->message);
g_clear_error (&error);
goto error;
}
g_io_add_watch (closure->channel,
G_IO_IN,
_request_content_io_func,
closure);
return TRUE;
error:
data_offer_unref (closure->offer);
g_io_channel_unref (closure->channel);
close (pipe_fd[1]);
g_free (closure);
return FALSE;
}
struct _GdkWaylandSelectionOffer {
GdkDeviceWaylandOfferContentCallback cb;
gpointer userdata;
struct wl_data_source *source;
GdkWaylandDevice *device;
};
static void
data_source_target (void *data,
struct wl_data_source *source,
const char *mime_type)
{
g_debug (G_STRLOC ": %s source = %p, mime_type = %s",
G_STRFUNC, source, mime_type);
}
static void
data_source_send (void *data,
struct wl_data_source *source,
const char *mime_type,
int32_t fd)
{
GdkWaylandSelectionOffer *offer = (GdkWaylandSelectionOffer *)data;;
gchar *buf;
gssize len, bytes_written = 0;
g_debug (G_STRLOC ": %s source = %p, mime_type = %s fd = %d",
G_STRFUNC, source, mime_type, fd);
buf = offer->cb (offer->device->pointer, mime_type, &len, offer->userdata);
while (len > 0)
{
bytes_written += write (fd, buf + bytes_written, len);
if (bytes_written == -1)
goto error;
len -= bytes_written;
}
close (fd);
g_free (buf);
return;
error:
g_warning (G_STRLOC ": Error writing data to client: %s",
g_strerror (errno));
close (fd);
g_free (buf);
}
static void
data_source_cancelled (void *data,
struct wl_data_source *source)
{
g_debug (G_STRLOC ": %s source = %p",
G_STRFUNC, source);
}
static const struct wl_data_source_listener data_source_listener = {
data_source_target,
data_source_send,
data_source_cancelled
};
static guint32
_wl_time_now (void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
gboolean
gdk_wayland_device_offer_selection_content (GdkDevice *gdk_device,
const gchar **mime_types,
gint nr_mime_types,
GdkDeviceWaylandOfferContentCallback cb,
gpointer userdata)
{
GdkDisplay *display;
GdkDisplayWayland *display_wayland;
GdkWaylandSelectionOffer *offer;
GdkWaylandDevice *device;
gint i;
g_return_val_if_fail (GDK_IS_DEVICE_CORE (gdk_device), 0);
device = GDK_DEVICE_CORE (gdk_device)->device;
display = device->display;
display_wayland = GDK_DISPLAY_WAYLAND (display);
offer = g_new0 (GdkWaylandSelectionOffer, 1);
offer->cb = cb;
offer->userdata = userdata;
offer->source =
wl_data_device_manager_create_data_source (display_wayland->data_device_manager);
offer->device = device;
for (i = 0; i < nr_mime_types; i++)
{
wl_data_source_offer (offer->source,
mime_types[i]);
}
wl_data_source_add_listener (offer->source,
&data_source_listener,
offer);
wl_data_device_set_selection (device->data_device,
offer->source,
_wl_time_now ());
device->selection_offer_out = offer;
return TRUE;
}
gboolean
gdk_wayland_device_clear_selection_content (GdkDevice *gdk_device)
{
GdkWaylandDevice *device;
g_return_val_if_fail (GDK_IS_DEVICE_CORE (gdk_device), 0);
device = GDK_DEVICE_CORE (gdk_device)->device;
if (!device->selection_offer_out)
return FALSE;
wl_data_device_set_selection (device->data_device,
NULL,
_wl_time_now ());
wl_data_source_destroy (device->selection_offer_out->source);
g_free (device->selection_offer_out);
device->selection_offer_out = NULL;
return TRUE;
}

View File

@@ -274,7 +274,8 @@ gdk_wayland_display_finalize (GObject *object)
g_object_unref (display_wayland->keymap);
/* input GdkDevice list */
g_list_free_full (display_wayland->input_devices, g_object_unref);
g_list_foreach (display_wayland->input_devices, (GFunc) g_object_unref, NULL);
g_list_free (display_wayland->input_devices);
g_object_unref (display_wayland->screen);
@@ -425,8 +426,7 @@ gdk_wayland_display_after_process_all_updates (GdkDisplay *display)
static gulong
gdk_wayland_display_get_next_serial (GdkDisplay *display)
{
static gulong serial = 0;
return ++serial;
return 0;
}
void

View File

@@ -135,8 +135,8 @@ gdk_wayland_display_manager_get_atom_name (GdkDisplayManager *manager_in,
while (g_hash_table_iter_next (&iter, &key, &value))
{
if (GDK_POINTER_TO_ATOM (value) == atom)
return g_strdup (key);
if (GDK_POINTER_TO_ATOM (key) == atom)
return g_strdup (value);
}
return NULL;

View File

@@ -113,10 +113,10 @@ void
_gdk_wayland_display_deliver_event (GdkDisplay *display, GdkEvent *event)
{
GList *node;
static int serial;
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event,
_gdk_display_get_next_serial (display));
_gdk_windowing_got_event (display, node, event, serial++);
}
GSource *

View File

@@ -515,10 +515,12 @@ gdk_wayland_keymap_add_virtual_modifiers (GdkKeymap *keymap,
wayland_keymap = GDK_WAYLAND_KEYMAP (keymap);
for (i = 4; i < 8; i++)
for (i = 3; i < 8; i++)
{
if ((1 << i) & *state)
{
if (wayland_keymap->modmap[i] & GDK_MOD1_MASK)
*state |= GDK_MOD1_MASK;
if (wayland_keymap->modmap[i] & GDK_SUPER_MASK)
*state |= GDK_SUPER_MASK;
if (wayland_keymap->modmap[i] & GDK_HYPER_MASK)
@@ -538,7 +540,7 @@ gdk_wayland_keymap_map_virtual_modifiers (GdkKeymap *keymap,
};
int i, j;
GdkWaylandKeymap *wayland_keymap;
gboolean retval = TRUE;
gboolean retval;
wayland_keymap = GDK_WAYLAND_KEYMAP (keymap);
@@ -546,7 +548,7 @@ gdk_wayland_keymap_map_virtual_modifiers (GdkKeymap *keymap,
{
if (*state & vmods[j])
{
for (i = 4; i < 8; i++)
for (i = 3; i < 8; i++)
{
if (wayland_keymap->modmap[i] & vmods[j])
{

View File

@@ -45,8 +45,10 @@
#define GDK_WINDOW_IS_WAYLAND(win) (GDK_IS_WINDOW_IMPL_WAYLAND (((GdkWindow *)win)->impl))
GType _gdk_wayland_window_get_type (void);
void _gdk_wayland_window_add_focus (GdkWindow *window);
void _gdk_wayland_window_remove_focus (GdkWindow *window);
void _gdk_wayland_window_update_size (GdkWindow *window,
int32_t width,
int32_t height,
uint32_t edges);
GdkKeymap *_gdk_wayland_keymap_new (GdkDisplay *display);
struct xkb_desc *_gdk_wayland_keymap_get_xkb_desc (GdkKeymap *keymap);

View File

@@ -33,36 +33,6 @@ G_BEGIN_DECLS
GType gdk_wayland_display_manager_get_type (void);
#if defined (GTK_COMPILATION) || defined (GDK_COMPILATION)
#define gdk_wayland_device_get_selection_type_atoms gdk_wayland_device_get_selection_type_atoms_libgtk_only
int
gdk_wayland_device_get_selection_type_atoms (GdkDevice *device,
GdkAtom **atoms_out);
typedef void (*GdkDeviceWaylandRequestContentCallback) (GdkDevice *device, const gchar *data, gsize len, gpointer userdata);
#define gdk_wayland_device_request_selection_content gdk_wayland_device_request_selection_content_libgtk_only
gboolean
gdk_wayland_device_request_selection_content (GdkDevice *device,
const gchar *requested_mime_type,
GdkDeviceWaylandRequestContentCallback cb,
gpointer userdata);
typedef gchar *(*GdkDeviceWaylandOfferContentCallback) (GdkDevice *device, const gchar *mime_type, gssize *len, gpointer userdata);
#define gdk_wayland_device_offer_selection_content gdk_wayland_device_offer_selection_content_libgtk_only
gboolean
gdk_wayland_device_offer_selection_content (GdkDevice *gdk_device,
const gchar **mime_types,
gint nr_mime_types,
GdkDeviceWaylandOfferContentCallback cb,
gpointer userdata);
#define gdk_wayland_device_clear_selection_content gdk_wayland_device_clear_selection_content_libgtk_only
gboolean
gdk_wayland_device_clear_selection_content (GdkDevice *gdk_device);
#endif
G_END_DECLS
#endif /* __GDK_WAYLAND_H__ */

View File

@@ -102,14 +102,42 @@ struct _GdkWindowImplWayland
struct wl_shell_surface *shell_surface;
unsigned int mapped : 1;
GdkWindow *transient_for;
GdkWindowTypeHint hint;
cairo_surface_t *cairo_surface;
cairo_surface_t *server_surface;
GLuint texture;
uint32_t resize_edges;
int focus_count;
/* Set if the window, or any descendent of it, is the server's focus window
*/
guint has_focus_window : 1;
/* Set if window->has_focus_window and the focus isn't grabbed elsewhere.
*/
guint has_focus : 1;
/* Set if the pointer is inside this window. (This is needed for
* for focus tracking)
*/
guint has_pointer : 1;
/* Set if the window is a descendent of the focus window and the pointer is
* inside it. (This is the case where the window will receive keystroke
* events even window->has_focus_window is FALSE)
*/
guint has_pointer_focus : 1;
/* Set if we are requesting these hints */
guint skip_taskbar_hint : 1;
guint skip_pager_hint : 1;
guint urgency_hint : 1;
guint on_all_desktops : 1; /* _NET_WM_STICKY == 0xFFFFFFFF */
guint have_sticky : 1; /* _NET_WM_STATE_STICKY */
guint have_maxvert : 1; /* _NET_WM_STATE_MAXIMIZED_VERT */
guint have_maxhorz : 1; /* _NET_WM_STATE_MAXIMIZED_HORZ */
guint have_fullscreen : 1; /* _NET_WM_STATE_FULLSCREEN */
gulong map_serial; /* Serial of last transition from unmapped */
@@ -118,9 +146,6 @@ struct _GdkWindowImplWayland
/* Time of most recent user interaction. */
gulong user_time;
GdkGeometry geometry_hints;
GdkWindowHints geometry_mask;
};
struct _GdkWindowImplWaylandClass
@@ -136,36 +161,16 @@ _gdk_window_impl_wayland_init (GdkWindowImplWayland *impl)
impl->toplevel_window_type = -1;
}
void
_gdk_wayland_window_add_focus (GdkWindow *window)
{
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
impl->focus_count++;
if (impl->focus_count == 1)
gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FOCUSED);
}
void
_gdk_wayland_window_remove_focus (GdkWindow *window)
{
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
impl->focus_count--;
if (impl->focus_count == 0)
gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FOCUSED, 0);
}
/**
* gdk_wayland_window_update_size:
* _gdk_wayland_window_update_size:
* @drawable: a #GdkDrawableImplWayland.
*
* Updates the state of the drawable (in particular the drawable's
* cairo surface) when its size has changed.
**/
static void
gdk_wayland_window_update_size (GdkWindow *window,
int32_t width, int32_t height, uint32_t edges)
void
_gdk_wayland_window_update_size (GdkWindow *window,
int32_t width, int32_t height, uint32_t edges)
{
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
GdkRectangle area;
@@ -436,33 +441,6 @@ gdk_wayland_window_ref_cairo_surface (GdkWindow *window)
return impl->cairo_surface;
}
static void
gdk_wayland_window_configure (GdkWindow *window,
int width, int height, int edges)
{
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
GdkDisplay *display;
GdkEvent *event;
display = gdk_window_get_display (window);
/* TODO: Only generate a configure event if width or height have actually
* changed?
*/
event = gdk_event_new (GDK_CONFIGURE);
event->configure.window = window;
event->configure.send_event = FALSE;
event->configure.width = width;
event->configure.height = height;
_gdk_window_update_size (window);
gdk_wayland_window_update_size (window, width, height, edges);
g_object_ref(window);
_gdk_wayland_display_deliver_event (display, event);
}
static void
gdk_wayland_window_set_user_time (GdkWindow *window, guint32 user_time)
{
@@ -503,16 +481,23 @@ shell_surface_handle_configure(void *data,
int32_t height)
{
GdkWindow *window = GDK_WINDOW (data);
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
GdkDisplay *display;
GdkEvent *event;
gdk_window_constrain_size (&impl->geometry_hints,
impl->geometry_mask,
width,
height,
&width,
&height);
display = gdk_window_get_display (window);
gdk_wayland_window_configure (window, width, height, edges);
event = gdk_event_new (GDK_CONFIGURE);
event->configure.window = window;
event->configure.send_event = FALSE;
event->configure.width = width;
event->configure.height = height;
_gdk_window_update_size (window);
_gdk_wayland_window_update_size (window, width, height, edges);
g_object_ref(window);
_gdk_wayland_display_deliver_event (display, event);
}
static const struct wl_shell_surface_listener shell_surface_listener = {
@@ -543,8 +528,6 @@ gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped)
wl_shell_surface_add_listener(impl->shell_surface,
&shell_surface_listener, window);
gdk_window_set_type_hint (window, impl->hint);
_gdk_make_event (window, GDK_MAP, NULL, FALSE);
event = _gdk_make_event (window, GDK_VISIBILITY_NOTIFY, NULL, FALSE);
event->visibility.state = GDK_VISIBILITY_UNOBSCURED;
@@ -646,11 +629,7 @@ gdk_window_wayland_move_resize (GdkWindow *window,
window->x = x;
window->y = y;
/* If this function is called with width and height = -1 then that means
* just move the window - don't update its size
*/
if (width > 0 && height > 0)
gdk_wayland_window_configure (window, width, height, 0);
_gdk_wayland_window_update_size (window, width, height, 0);
}
static void
@@ -819,7 +798,6 @@ gdk_wayland_window_destroy (GdkWindow *window,
{
if (GDK_WINDOW_IMPL_WAYLAND (window->impl)->surface)
wl_surface_destroy(GDK_WINDOW_IMPL_WAYLAND (window->impl)->surface);
wl_shell_surface_destroy(GDK_WINDOW_IMPL_WAYLAND (window->impl)->shell_surface);
}
}
@@ -860,20 +838,16 @@ static void
gdk_wayland_window_set_type_hint (GdkWindow *window,
GdkWindowTypeHint hint)
{
GdkWindowImplWayland *impl;
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
if (GDK_WINDOW_DESTROYED (window))
return;
impl->hint = hint;
switch (hint)
{
case GDK_WINDOW_TYPE_HINT_DIALOG:
case GDK_WINDOW_TYPE_HINT_MENU:
case GDK_WINDOW_TYPE_HINT_TOOLBAR:
case GDK_WINDOW_TYPE_HINT_UTILITY:
case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
case GDK_WINDOW_TYPE_HINT_DOCK:
case GDK_WINDOW_TYPE_HINT_DESKTOP:
case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
@@ -886,11 +860,7 @@ gdk_wayland_window_set_type_hint (GdkWindow *window,
default:
g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
/* Fall thru */
case GDK_WINDOW_TYPE_HINT_DIALOG:
case GDK_WINDOW_TYPE_HINT_NORMAL:
case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
if (impl->shell_surface)
wl_shell_surface_set_toplevel (impl->shell_surface);
break;
}
}
@@ -930,17 +900,10 @@ gdk_wayland_window_set_geometry_hints (GdkWindow *window,
const GdkGeometry *geometry,
GdkWindowHints geom_mask)
{
GdkWindowImplWayland *impl;
if (GDK_WINDOW_DESTROYED (window) ||
!WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
return;
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
impl->geometry_hints = *geometry;
impl->geometry_mask = geom_mask;
/*
* GDK_HINT_POS
* GDK_HINT_USER_POS
@@ -1231,14 +1194,9 @@ gdk_wayland_window_begin_resize_drag (GdkWindow *window,
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
wl_shell_surface_resize (impl->shell_surface,
_gdk_wayland_device_get_device (device),
timestamp, grab_type);
/* This is needed since Wayland will absorb all the pointer events after the
* above function - FIXME: Is this always safe..?
*/
gdk_device_ungrab (device, timestamp);
wl_shell_surface_resize(impl->shell_surface,
_gdk_wayland_device_get_device (device),
timestamp, grab_type);
}
static void
@@ -1249,6 +1207,7 @@ gdk_wayland_window_begin_move_drag (GdkWindow *window,
gint root_y,
guint32 timestamp)
{
GdkDisplay *display = gdk_window_get_display (window);
GdkWindowImplWayland *impl;
if (GDK_WINDOW_DESTROYED (window) ||
@@ -1257,13 +1216,8 @@ gdk_wayland_window_begin_move_drag (GdkWindow *window,
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
wl_shell_surface_move (impl->shell_surface,
_gdk_wayland_device_get_device (device), timestamp);
/* This is needed since Wayland will absorb all the pointer events after the
* above function - FIXME: Is this always safe..?
*/
gdk_device_ungrab (device, timestamp);
wl_shell_surface_move(impl->shell_surface,
_gdk_wayland_device_get_device (device), timestamp);
}
static void

View File

@@ -1503,11 +1503,7 @@ gdk_win32_window_raise (GdkWindow *window)
0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
else if (window->accept_focus)
/* Do not wrap this in an API_CALL macro as SetForegroundWindow might
* fail when for example dragging a window belonging to a different
* application at the time of a gtk_window_present() call due to focus
* stealing prevention. */
SetForegroundWindow (GDK_WINDOW_HWND (window));
API_CALL (BringWindowToTop, (GDK_WINDOW_HWND (window)));
else
API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
0, 0, 0, 0,

View File

@@ -7,8 +7,6 @@ libgdkx11includedir = $(includedir)/gtk-3.0/gdk/x11
AM_CPPFLAGS = \
-DG_LOG_DOMAIN=\"Gdk\" \
-DGDK_COMPILATION \
-DXINPUT2_2_USE_UNSTABLE_PROTOCOL \
-DXINPUT2_1_USE_UNSTABLE_PROTOCOL \
-I$(top_srcdir) \
-I$(top_srcdir)/gdk \
-I$(top_builddir)/gdk \

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