Compare commits

...
Sign in to create a new pull request.
Author SHA1 Message Date
05ce737f08 gdk: add touch and smooth scroll event support 2026-08-12 23:42:32 +02:00
09131ada3a fontsel: reduce font list sorting overhead
Precompute locale collation keys for font families instead of repeatedly collating names from the qsort comparator.

Describe each font face once before sorting rather than allocating and freeing descriptions for every comparison, and populate the list stores with insert_with_values.

Keep selection callbacks immediate and preserve GTK2-NG's restricted translation of standard font style names.

This reduces FontSelection creation work substantially while keeping the resulting family, face and size models unchanged.
2026-08-12 23:17:34 +02:00
be71ea43fc updateiconcache: make directory scans deterministic and leaner
Sort directory entries before scanning so cache layout does not depend on filesystem enumeration order.

Classify entries with one stat operation, reuse the sorted name buffers for suffix and basename handling, and release transient scan and cache-building resources once writing is complete. This preserves the sorted cache output while reducing filesystem metadata calls and eliminating observed leaks.

Provide compile-time S_ISDIR and S_ISREG fallbacks for MSVC.

Based on the openSUSE gtk2-updateiconcache_sort.patch.
2026-08-12 21:54:38 +02:00
f8ff879dd2 x11: size available depth array correctly
Visual initialization considers eight possible depths, but GdkScreenX11 only reserved space for seven. Reserve all eight entries so a server exposing every considered depth cannot write past the array.
2026-08-12 20:59:11 +02:00
fa2e5d3293 cups: remember authentication with Secret Service
Look up and store CUPS authentication information through the Secret Service D-Bus API.

Enable the feature by default when CUPS support is built, requiring the libsecret development files unless explicitly disabled. Keep the print backend free of a runtime libsecret dependency so authentication continues to work when Secret Service is unavailable.
2026-08-12 19:38:55 +02:00
399e6ee64e cups: reduce authentication allocation overhead
Avoid unnecessary copies and heap allocations in the CUPS authentication paths.

Use borrowed strings where their lifetime is sufficient, use stack storage for the fixed password prompt fields, replace manual auth-info copying with g_strdupv(), and remove unused per-request hostname processing.

Also free auth_info_visible in request_auth_info().
2026-08-11 10:48:41 +02:00
efcc412ca2 filechooser: reduce view mode startup overhead
Replace the two-item GtkComboBoxText with a lightweight toggle and create icon-view zoom controls only when icon view is first used.

Keep the existing icon-view zoom, cache invalidation and settings behavior while avoiding their startup cost for the default list view. Keep the zoom event boxes local instead of storing unused widget pointers.
2026-08-11 09:53:27 +02:00
212df8a74e fontsel: localize common font style names 2026-08-10 14:08:34 +02:00
0f4142b31a introspection: add GdkWin32 GIR generation 2026-08-10 12:05:31 +02:00
f14303e16f introspection: pass compiler and GTK DLL path to scanner 2026-08-09 23:10:13 +02:00
ea73f6812c gtk: replace deprecated tooltip timestamp ABI field 2026-08-07 08:53:00 +02:00
782a2948b8 gail: update AtkValue test modules
Use a shared private compatibility helper in the GAIL test modules.

Exercise the modern AtkValue API when ATK 2.12 or newer is available while retaining the legacy test path for older ATK versions.

Initialize temporary GValues explicitly and keep the helper symbols private to the test modules.
2026-08-07 08:53:00 +02:00
a116a5d13b gail: implement modern AtkValue interface
Add compile-time support for the modern AtkValue API available since ATK 2.12 while retaining compatibility with older ATK versions.

Implement direct modern value, range, increment and setter methods for adjustments, paned widgets, progress bars, ranges, scale buttons and spin buttons.

Keep the implementation private, avoid per-instance memory overhead and preserve the existing exported ABI.
2026-08-07 08:53:00 +02:00
d0c4346396 cups: use modern HTTP connection helpers when available
Detect httpConnect2 and httpReconnect2 at configure time.

Preserve blocking, encryption, timeout and reconnect semantics while retaining the legacy CUPS APIs as compile-time fallbacks.
2026-08-07 08:53:00 +02:00
0911aa2f2f gtk: remove unused IM module query function pointers
Keep symbol validation while avoiding unused typed variables and assignments.
2026-08-07 08:53:00 +02:00
672b195592 gtk: reuse cached module path list
Avoid computing and allocating the module path list a second time.
2026-08-07 08:53:00 +02:00
450e784037 gtk: replace deprecated IM module parser helpers
Use local compile-time selected parser helpers with a legacy Pango fallback.

Avoid temporary string decompression allocations and use unlocked stdio where available.
2026-08-07 08:53:00 +02:00
73183e1a30 gdk: add high-depth RGB image drawing
Add RGB48 and RGBX64 drawing APIs with direct conversion for common 15-, 16-, 24-, 30- and 32-bit TrueColor visuals. Preserve the existing GdkRGB path as a fallback for unsupported visuals and maximum dithering.
2026-08-05 12:15:23 +02:00
8984300bba gdk: optimize packed StaticColor conversion 2026-08-04 21:26:05 +02:00
a923aa3120 gdk: fix packed StaticColor dithering 2026-08-04 19:41:58 +02:00
b58fc23765 gdk: support 2-bit StaticColor visuals 2026-08-04 19:08:54 +02:00
e92e770558 gdk: support 3-bit StaticColor visuals 2026-08-04 18:52:31 +02:00
be64a902a5 gdk: optimize native big-endian RGB565 paths
Add native big-endian four-pixel converters for RGB565, grayscale RGB565, and dithered RGB565.

Select the block converters only where cross-target code generation is favorable: RGB on PowerPC, s390x, ARMv5+, and AArch64; grayscale on PowerPC, ARMv5+, AArch64, and m68k; and dither on PowerPC. Retain the scalar fallbacks everywhere else.

The little-endian machine code remains byte-for-byte unchanged. No runtime endian checks, allocations, or additional image buffers are introduced.

Validated with a complete build and test suite, deterministic and randomized big-endian formula tests, exact little-endian .text comparison, and cross-target code-generation checks.
2026-08-04 17:57:34 +02:00
71023e0333 gdk: add endian-aware 30-bit RGB converters
Add specialized converters for both 10:10:10 channel layouts and both X image byte orders.

Preserve depth-30 padding bits, avoid invalid negative shifts in the generic converter and select endian conversion at compile time.

Validated with a real Xvfb 30-bit A/B pixel test and cross-target endian store checks.

Derived from downstream commit 02a2c61f2d.

Co-authored-by: Daemonratte <daemonratte@daemonratte.net>
2026-08-04 15:34:12 +02:00
00177dd11c docs: use top_srcdir for GDK X11 header reference
Based on the MSYS2 0005-Fix-header-ref.all.patch.

Use an explicit top_srcdir-relative path for gdkx.h in the GDK reference documentation instead of a fragile relative path.
2026-08-04 14:02:32 +02:00
b622340b5b print: preserve default-printer wait during status updates
Based on the openSUSE gtk2-default-printer.patch.

Avoid treating printer status updates as user-driven printer selection changes, so the print dialog can continue waiting for a default printer that may appear later.
2026-08-04 12:41:19 +02:00
757774345d win32: quote icon cache manifest in resource file
Based on the MSYS2 0024-gtk-update-icon-cache-rc-quote.patch.

Quote the manifest path when generating the gtk-update-icon-cache resource file so windres parses it correctly.
2026-08-04 09:00:57 +02:00
4d7fc95583 win32: initialize key state before updating keymap
Based on the MSYS2 0023-gdkkeys-win32.c-fix-initialisation-of-key_state-in-u.patch.

Clear the key_state array before using it during keymap updates so stale state cannot affect layout handling, including Japanese IME input.
2026-08-04 09:00:57 +02:00
d181fe8fc3 icontheme: detect SVG icons by extension on Win32
Based on the MSYS2 0022-icontheme-win32-detect-SVG-files-by-extension.patch.

Some Windows systems report .svg files with a generic or incorrect content type. On Win32, fall back to the .svg extension so SVG icons can still be detected.
2026-08-04 09:00:57 +02:00
65f949bcde win32: improve mouse window lookup through transparent children
Based on the MSYS2 0013_fix_mouse_events.patch.

Use CWP_SKIPTRANSPARENT while walking from the desktop window, but stop skipping transparent windows after the first level so transparent child windows are still considered correctly.
2026-08-04 09:00:57 +02:00
8d4015ee54 quartz: avoid extra resize-idle updates on Big Sur and newer
Based on part of the MacPorts Big Sur performance patch for GIMP issue 5989.

Keep the existing gdk_window_process_all_updates() call for non-Quartz targets and for older macOS releases, but avoid this extra resize-idle update path on Big Sur and newer where it can contribute to expensive full-window redraw behaviour.
2026-08-04 08:45:38 +02:00
c1fc6ed642 quartz: avoid extra content invalidation on Big Sur and newer
Based on part of the MacPorts Big Sur performance patch for GIMP issue 5989.

Keep the existing Mojave-era setNeedsDisplay workaround for macOS 10.14 and 10.15, but avoid the extra full-window invalidation on Big Sur and newer where it can cause expensive redraw behaviour.
2026-08-04 08:45:38 +02:00
9d7c7e63d6 quartz: request 8-bit layer contents on Big Sur and newer
Based on part of the MacPorts Big Sur performance patch for GIMP issue 5989.

Use a dynamic Objective-C call to request 8-bit layer contents on macOS 11 and newer, avoiding a hard QuartzCore/CALayer compile-time dependency and preserving old behaviour on older macOS releases.
2026-08-04 08:45:38 +02:00
fe45d0944c quartz: avoid screen update suppression on Mojave and newer
Based on part of the MacPorts Big Sur performance patch for GIMP issue 5989.

NSDisableScreenUpdates and NSEnableScreenUpdates are deprecated on newer macOS releases. Keep using them for older macOS versions, but avoid them on Mojave and newer.
2026-08-04 08:45:38 +02:00
21fdf2eeaa quartz: use CGContext accessor on Yosemite and newer
Based on part of the MacPorts Big Sur performance patch for GIMP issue 5989.

Use the modern NSGraphicsContext CGContext accessor on Yosemite and newer, matching the existing Quartz window code, while preserving graphicsPort for older macOS versions.
2026-08-04 08:45:38 +02:00
8b7fda063e quartz: map macOS 11 and newer to internal OS versions
Based on part of the MacPorts Big Sur performance patch for GIMP issue 5989.

GTK2 represents macOS 10.x releases by their minor version. Read the major version as well and map macOS 11 and newer into the same sequence so Big Sur and later releases can be detected correctly.
2026-08-04 08:45:38 +02:00
0bc8029032 quartz: avoid focus locking on Mojave and newer
Based on part of the MacPorts Big Sur performance patch for GIMP issue 5989.

The NSView focus-locking API is deprecated on newer macOS releases and can cause expensive redraw behaviour. Keep the old path for older macOS versions, but avoid lockFocusIfCanDraw/unlockFocus on Mojave and newer.
2026-08-04 08:45:38 +02:00
72dcfc7ca5 quartz: add newer macOS version constants
Based on the MacPorts patch-gdkquartz-osx-versions.diff.

Extend the Quartz OS version enum so later macOS-specific code can
distinguish Catalina, Big Sur, Monterey, Ventura, Sonoma, and Sequoia
while preserving the existing older constants.
2026-08-04 08:45:38 +02:00
292e512bc4 build: disable GNU visibility aliases on Apple platforms
Based on the MacPorts patch-aliases.diff.

Keep the existing GNU visibility alias generation on other platforms, but avoid it on Apple targets where this alias mechanism is not suitable.
2026-08-04 08:45:38 +02:00
d8b26dc0b7 gtktrayicon: use explicit void prototypes for reserved slots
Based on the Mageia gtk+-2.24.32-warnings.patch.

Declare the reserved GtkTrayIconClass function pointers with explicit void parameter lists to avoid strict-prototype warnings without changing the class layout.
2026-08-04 08:37:17 +02:00
790b8c2b69 gtkrc: search XDG data dirs for themes
Based on the Guix gtk2-theme-paths.patch by Jookia.

Keep the existing ~/.themes and gtk_rc_get_theme_dir() lookup paths, but check g_get_system_data_dirs() in between so profile- and prefix-based theme installations can be found.
2026-08-03 16:06:17 +02:00
0e8d6a76b6 tests: fix GtkBuilder signal callback prototypes
Based on the Guix gtk2-fix-builder-test.patch.

The callbacks are connected to notify-style signals and must take a
GParamSpec pointer, not a GParamSpec by value. This avoids stack/register
ABI problems on platforms such as ppc64el.
2026-08-03 15:55:03 +02:00
59 changed files with 3491 additions and 464 deletions

View file

@ -399,6 +399,11 @@ PKG_CHECK_MODULES(BASE_DEPENDENCIES,
gdk-pixbuf-2.0 >= gdk_pixbuf_required_version dnl
fribidi >= fribidi_required_version])
PKG_CHECK_EXISTS([atk >= 2.12],
[AC_DEFINE([HAVE_ATK_VALUE_2_12], [1],
[Define if ATK provides the 2.12 AtkValue interface])])
## In addition to checking that cairo is present, we also need to
## check that the correct cairo backend is there. E.g. if the GDK
## target is win32 we need the cairo-win32 backend and so on.
@ -469,7 +474,7 @@ if test "x$enable_rebuilds" = "xyes" && \
fi
AC_SUBST(REBUILD)
AC_CHECK_FUNCS(lstat mkstemp flockfile getc_unlocked)
AC_CHECK_FUNCS(lstat mkstemp flockfile getc_unlocked _getc_nolock)
AC_CHECK_FUNCS(localtime_r)
# _NL_TIME_FIRST_WEEKDAY is an enum and not a define
@ -1533,6 +1538,11 @@ LIBS="$old_LIBS"
# Printing system checks
################################################################
AC_ARG_ENABLE(cups-secret-service,
[AS_HELP_STRING([--disable-cups-secret-service]
[disable Secret Service support in the cups print backend])],,
[enable_cups_secret_service=yes])
AC_ARG_ENABLE(cups,
[AS_HELP_STRING([--disable-cups]
[disable cups print backend])],,
@ -1579,6 +1589,17 @@ else
AM_CONDITIONAL(HAVE_CUPS, true)
if test "x$enable_cups_secret_service" != "xno"; then
PKG_CHECK_EXISTS([libsecret-1], [],
[AC_MSG_ERROR([
*** libsecret-1 is required when CUPS Secret Service support is enabled.
*** Install the libsecret development files or configure
*** with --disable-cups-secret-service.
])])
AC_DEFINE([HAVE_CUPS_SECRET_SERVICE], [1],
[Define to 1 if CUPS Secret Service support is enabled])
fi
gtk_save_cflags="$CFLAGS"
CFLAGS="$CUPS_CFLAGS"
AC_COMPILE_IFELSE(
@ -1594,6 +1615,7 @@ else
gtk_save_libs="$LIBS"
LIBS="$CUPS_LIBS"
AC_CHECK_FUNCS(httpGetAuthString)
AC_CHECK_FUNCS(httpConnect2 httpReconnect2)
LIBS="$gtk_save_libs"
fi
fi

View file

@ -37,7 +37,7 @@ IGNORE_HFILES= \
# Extra files to add when scanning (relative to $srcdir)
EXTRA_HFILES= \
../../../gdk/x11/gdkx.h
$(top_srcdir)/gdk/x11/gdkx.h
# CFLAGS and LDFLAGS for compiling scan program. Only needed
# if $(DOC_MODULE).types is non-empty.

View file

@ -335,6 +335,10 @@ gdk_draw_indexed_image
gdk_draw_gray_image
gdk_draw_rgb_32_image
gdk_draw_rgb_32_image_dithalign
gdk_draw_rgb_48_image
gdk_draw_rgb_48_image_dithalign
gdk_draw_rgbx_64_image
gdk_draw_rgbx_64_image_dithalign
GdkRgbDither
<SUBSECTION>
@ -1153,6 +1157,7 @@ gdk_event_get_state
gdk_event_get_axis
gdk_event_get_coords
gdk_event_get_root_coords
gdk_event_get_scroll_deltas
gdk_event_request_motions
<SUBSECTION>
@ -1188,6 +1193,7 @@ GdkEvent
GdkEventAny
GdkEventKey
GdkEventButton
GdkEventTouch
GdkEventScroll
GdkEventMotion
GdkEventExpose

View file

@ -145,6 +145,7 @@ gdk_c_sources = \
gdkrectangle.c \
gdkregion-generic.c \
gdkrgb.c \
gdkrgb16.c \
gdkscreen.c \
gdkselection.c \
gdkvisual.c \
@ -213,6 +214,11 @@ Gdk_2_0_gir_CFLAGS = \
-I$(top_builddir) \
-I$(top_builddir)/gdk \
$(INCLUDES)
if OS_WIN32
Gdk_2_0_gir_CFLAGS += -I$(srcdir)/win32 -I$(srcdir)
endif
INTROSPECTION_GIRS += Gdk-2.0.gir
if USE_X11
@ -268,6 +274,69 @@ introspection_files += $(filter-out x11/gdkx.h, $(x11_introspection_files))
endif # USE_X11
if OS_WIN32
win32_introspection_files = \
win32/gdkapplaunchcontext-win32.c \
win32/gdkcolor-win32.c \
win32/gdkcursor-win32.c \
win32/gdkdisplay-win32.c \
win32/gdkdnd-win32.c \
win32/gdkdrawable-win32.c \
win32/gdkdrawable-win32.h \
win32/gdkevents-win32.c \
win32/gdkfont-win32.c \
win32/gdkgc-win32.c \
win32/gdkgeometry-win32.c \
win32/gdkglobals-win32.c \
win32/gdkimage-win32.c \
win32/gdkim-win32.c \
win32/gdkinput.c \
win32/gdkinput-win32.c \
win32/gdkinput-win32.h \
win32/gdkkeys-win32.c \
win32/gdkmain-win32.c \
win32/gdkpixmap-win32.c \
win32/gdkpixmap-win32.h \
win32/gdkprivate-win32.h \
win32/gdkproperty-win32.c \
win32/gdkscreen-win32.c \
win32/gdkselection-win32.c \
win32/gdkspawn-win32.c \
win32/gdktestutils-win32.c \
win32/gdkvisual-win32.c \
win32/gdkwin32.h \
win32/gdkwin32id.c \
win32/gdkwin32keys.h \
win32/gdkwindow-win32.c \
win32/gdkwindow-win32.h
GdkWin32-2.0.gir: $(gdktargetlib) Gdk-2.0.gir Makefile
GdkWin32_2_0_gir_SCANNERFLAGS = --identifier-prefix=Gdk --symbol-prefix=gdk --include-uninstalled=Gdk-2.0.gir
GdkWin32_2_0_gir_INCLUDES = Gio-2.0 GdkPixbuf-2.0 Pango-1.0
GdkWin32_2_0_gir_LIBS = $(gdktargetlib)
GdkWin32_2_0_gir_FILES = $(filter-out \
win32/gdkdrawable-win32.h \
win32/gdkinput-win32.h \
win32/gdkpixmap-win32.h \
win32/gdkprivate-win32.h \
win32/gdkwindow-win32.h, \
$(win32_introspection_files))
GdkWin32_2_0_gir_EXPORT_PACKAGES = gdk-win32-2.0
GdkWin32_2_0_gir_CFLAGS = \
-DGDK_COMPILATION \
-I$(top_srcdir) \
-I$(top_builddir) \
-I$(top_builddir)/gdk \
-I$(srcdir)/win32 \
-I$(srcdir) \
$(INCLUDES) \
-L$(top_builddir)/gdk
INTROSPECTION_GIRS += GdkWin32-2.0.gir
introspection_files += $(filter-out win32/gdkwin32.h, $(win32_introspection_files))
endif # OS_WIN32
girdir = $(datadir)/gir-1.0
gir_DATA = $(INTROSPECTION_GIRS)

View file

@ -142,8 +142,17 @@ static const guint type_masks[] =
GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28, */
GDK_VISIBILITY_NOTIFY_MASK,/* GDK_VISIBILITY_NOTIFY = 29, */
GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30, */
GDK_SCROLL_MASK /* GDK_SCROLL = 31 */
GDK_SCROLL_MASK, /* GDK_SCROLL = 31 */
0, /* GDK_WINDOW_STATE = 32 */
0, /* GDK_SETTING = 33 */
0, /* GDK_OWNER_CHANGE = 34 */
0, /* GDK_GRAB_BROKEN = 35 */
0, /* GDK_DAMAGE = 36 */
GDK_TOUCH_BEGIN_MASK, /* GDK_TOUCH_BEGIN = 37 */
GDK_TOUCH_UPDATE_MASK, /* GDK_TOUCH_UPDATE = 38 */
GDK_TOUCH_END_MASK /* GDK_TOUCH_END = 39 */
};
G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST);
GdkWindow *
gdk_directfb_other_event_window (GdkWindow *window,

View file

@ -45,6 +45,7 @@ gdk_event_get
gdk_event_get_axis
gdk_event_get_coords
gdk_event_get_root_coords
gdk_event_get_scroll_deltas
gdk_event_get_screen
gdk_event_get_state
gdk_event_get_time
@ -1118,6 +1119,15 @@ gdk_draw_rgb_image_dithalign
#endif
#endif
#if IN_HEADER(__GDK_RGB_H__)
#if IN_FILE(__GDK_RGB16_C__)
gdk_draw_rgb_48_image
gdk_draw_rgb_48_image_dithalign
gdk_draw_rgbx_64_image
gdk_draw_rgbx_64_image_dithalign
#endif
#endif
#if IN_HEADER(__GDK_SCREEN_H__)
#if IN_FILE(__GDK_SCREEN_C__)
gdk_screen_get_type G_GNUC_CONST

View file

@ -67,6 +67,18 @@ GdkEventFunc _gdk_event_func = NULL; /* Callback for events */
gpointer _gdk_event_data = NULL;
GDestroyNotify _gdk_event_notify = NULL;
/* Store smooth-scroll deltas in storage already covered by GdkEvent. */
typedef struct
{
GdkEventScroll scroll;
gfloat delta_x;
gfloat delta_y;
} GdkEventScrollPrivate;
G_STATIC_ASSERT (sizeof (GdkEventTouch) <= sizeof (GdkEventCrossing));
G_STATIC_ASSERT (sizeof (GdkEventScrollPrivate) <= sizeof (GdkEventCrossing));
/*********************************************
* Functions for maintaining the event queue *
*********************************************/
@ -406,6 +418,14 @@ gdk_event_new (GdkEventType type)
new_event->button.x_root = 0.;
new_event->button.y_root = 0.;
break;
case GDK_TOUCH_BEGIN:
case GDK_TOUCH_UPDATE:
case GDK_TOUCH_END:
new_event->touch.x = 0.;
new_event->touch.y = 0.;
new_event->touch.x_root = 0.;
new_event->touch.y_root = 0.;
break;
case GDK_SCROLL:
new_event->scroll.x = 0.;
new_event->scroll.y = 0.;
@ -435,6 +455,24 @@ gdk_event_is_allocated (const GdkEvent *event)
return FALSE;
}
void
_gdk_event_set_scroll_deltas (GdkEvent *event,
gdouble delta_x,
gdouble delta_y)
{
gfloat deltas[2];
deltas[0] = (gfloat) delta_x;
deltas[1] = (gfloat) delta_y;
event->scroll.direction = GDK_SCROLL_SMOOTH;
memcpy (((guchar *) event) +
G_STRUCT_OFFSET (GdkEventScrollPrivate, delta_x),
deltas, sizeof (deltas));
}
/**
* gdk_event_copy:
* @event: a #GdkEvent
@ -613,6 +651,10 @@ gdk_event_get_time (const GdkEvent *event)
case GDK_3BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
return event->button.time;
case GDK_TOUCH_BEGIN:
case GDK_TOUCH_UPDATE:
case GDK_TOUCH_END:
return event->touch.time;
case GDK_SCROLL:
return event->scroll.time;
case GDK_KEY_PRESS:
@ -691,6 +733,11 @@ gdk_event_get_state (const GdkEvent *event,
case GDK_BUTTON_RELEASE:
*state = event->button.state;
return TRUE;
case GDK_TOUCH_BEGIN:
case GDK_TOUCH_UPDATE:
case GDK_TOUCH_END:
*state = event->touch.state;
return TRUE;
case GDK_SCROLL:
*state = event->scroll.state;
return TRUE;
@ -787,6 +834,12 @@ gdk_event_get_coords (const GdkEvent *event,
x = event->motion.x;
y = event->motion.y;
break;
case GDK_TOUCH_BEGIN:
case GDK_TOUCH_UPDATE:
case GDK_TOUCH_END:
x = event->touch.x;
y = event->touch.y;
break;
default:
fetched = FALSE;
break;
@ -837,6 +890,12 @@ gdk_event_get_root_coords (const GdkEvent *event,
x = event->button.x_root;
y = event->button.y_root;
break;
case GDK_TOUCH_BEGIN:
case GDK_TOUCH_UPDATE:
case GDK_TOUCH_END:
x = event->touch.x_root;
y = event->touch.y_root;
break;
case GDK_ENTER_NOTIFY:
case GDK_LEAVE_NOTIFY:
x = event->crossing.x_root;
@ -864,6 +923,45 @@ gdk_event_get_root_coords (const GdkEvent *event,
return fetched;
}
/**
* gdk_event_get_scroll_deltas:
* @event: a #GdkEvent
* @delta_x: (out) (allow-none): return location for horizontal delta
* @delta_y: (out) (allow-none): return location for vertical delta
*
* Extracts precise scroll deltas from a scroll event.
*
* Return value: %TRUE if precise scroll deltas are available
**/
gboolean
gdk_event_get_scroll_deltas (const GdkEvent *event,
gdouble *delta_x,
gdouble *delta_y)
{
gfloat deltas[2] = { 0.f, 0.f };
gboolean fetched = FALSE;
g_return_val_if_fail (event != NULL, FALSE);
if (event->type == GDK_SCROLL &&
event->scroll.direction == GDK_SCROLL_SMOOTH)
{
memcpy (deltas,
((const guchar *) event) +
G_STRUCT_OFFSET (GdkEventScrollPrivate, delta_x),
sizeof (deltas));
fetched = TRUE;
}
if (delta_x)
*delta_x = deltas[0];
if (delta_y)
*delta_y = deltas[1];
return fetched;
}
/**
* gdk_event_get_axis:
* @event: a #GdkEvent

View file

@ -50,6 +50,7 @@ typedef struct _GdkEventNoExpose GdkEventNoExpose;
typedef struct _GdkEventVisibility GdkEventVisibility;
typedef struct _GdkEventMotion GdkEventMotion;
typedef struct _GdkEventButton GdkEventButton;
typedef struct _GdkEventTouch GdkEventTouch;
typedef struct _GdkEventScroll GdkEventScroll;
typedef struct _GdkEventKey GdkEventKey;
typedef struct _GdkEventFocus GdkEventFocus;
@ -152,6 +153,9 @@ typedef enum
GDK_OWNER_CHANGE = 34,
GDK_GRAB_BROKEN = 35,
GDK_DAMAGE = 36,
GDK_TOUCH_BEGIN = 37,
GDK_TOUCH_UPDATE = 38,
GDK_TOUCH_END = 39,
GDK_EVENT_LAST /* helper variable for decls */
} GdkEventType;
@ -181,7 +185,10 @@ typedef enum
GDK_PROXIMITY_OUT_MASK = 1 << 19,
GDK_SUBSTRUCTURE_MASK = 1 << 20,
GDK_SCROLL_MASK = 1 << 21,
GDK_ALL_EVENTS_MASK = 0x3FFFFE
GDK_TOUCH_BEGIN_MASK = 1 << 22,
GDK_TOUCH_UPDATE_MASK = 1 << 23,
GDK_TOUCH_END_MASK = 1 << 24,
GDK_ALL_EVENTS_MASK = 0x1FFFFFE
} GdkEventMask;
typedef enum
@ -196,7 +203,8 @@ typedef enum
GDK_SCROLL_UP,
GDK_SCROLL_DOWN,
GDK_SCROLL_LEFT,
GDK_SCROLL_RIGHT
GDK_SCROLL_RIGHT,
GDK_SCROLL_SMOOTH
} GdkScrollDirection;
/* Types of enter/leave notifications.
@ -325,6 +333,21 @@ struct _GdkEventButton
gdouble x_root, y_root;
};
struct _GdkEventTouch
{
GdkEventType type;
GdkWindow *window;
gint8 send_event;
guint32 time;
gdouble x;
gdouble y;
guint state;
guint sequence;
guint flags;
guint deviceid;
gdouble x_root, y_root;
};
struct _GdkEventScroll
{
GdkEventType type;
@ -497,6 +520,7 @@ union _GdkEvent
GdkEventVisibility visibility;
GdkEventMotion motion;
GdkEventButton button;
GdkEventTouch touch;
GdkEventScroll scroll;
GdkEventKey key;
GdkEventCrossing crossing;
@ -537,6 +561,9 @@ gboolean gdk_event_get_coords (const GdkEvent *event,
gboolean gdk_event_get_root_coords (const GdkEvent *event,
gdouble *x_root,
gdouble *y_root);
gboolean gdk_event_get_scroll_deltas (const GdkEvent *event,
gdouble *delta_x,
gdouble *delta_y);
gboolean gdk_event_get_axis (const GdkEvent *event,
GdkAxisUse axis_use,
gdouble *value);

View file

@ -299,6 +299,10 @@ extern gchar *_gdk_display_arg_name;
void _gdk_events_queue (GdkDisplay *display);
GdkEvent* _gdk_event_unqueue (GdkDisplay *display);
void _gdk_event_set_scroll_deltas (GdkEvent *event,
gdouble delta_x,
gdouble delta_y);
void _gdk_event_filter_unref (GdkWindow *window,
GdkEventFilter *filter);

View file

@ -1464,19 +1464,33 @@ gdk_rgb_convert_gray8_gray (GdkRgbInfo *image_info, GdkImage *image,
}
}
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
#define HAIRY_CONVERT_565
#if G_BYTE_ORDER == G_BIG_ENDIAN
#if defined(__powerpc__) || defined(__powerpc64__) || \
defined(__ppc__) || defined(__ppc64__) || \
defined(__PPC__) || defined(__PPC64__) || \
defined(__POWERPC__) || defined(_ARCH_PPC)
#define GDK_RGB_FAST_BE565_RGB
#define GDK_RGB_FAST_BE565_GRAY
#define GDK_RGB_FAST_BE565_DITHER
#elif defined(__s390x__)
#define GDK_RGB_FAST_BE565_RGB
#elif defined(__aarch64__)
#define GDK_RGB_FAST_BE565_RGB
#define GDK_RGB_FAST_BE565_GRAY
#elif defined(__arm__) && defined(__ARM_ARCH) && \
__ARM_ARCH >= 5
#define GDK_RGB_FAST_BE565_RGB
#define GDK_RGB_FAST_BE565_GRAY
#elif defined(__m68k__)
#define GDK_RGB_FAST_BE565_GRAY
#endif
#endif
#ifdef HAIRY_CONVERT_565
/* Render a 24-bit RGB image in buf into the GdkImage, without dithering.
This assumes native byte ordering - what should really be done is to
check whether the image byte_order is consistent with the _ENDIAN
config flag, and if not, use a different function.
This one is even faster than the one below - its inner loop loads 3
words (i.e. 4 24-bit pixels), does a lot of shifting and masking,
then writes 2 words. */
The four-pixel inner loop uses compile-time-specialized native word
layouts for little- and big-endian systems. */
#if G_BYTE_ORDER == G_LITTLE_ENDIAN || defined(GDK_RGB_FAST_BE565_RGB)
static void
gdk_rgb_convert_565 (GdkRgbInfo *image_info, GdkImage *image,
gint x0, gint y0, gint width, gint height,
@ -1520,6 +1534,7 @@ gdk_rgb_convert_565 (GdkRgbInfo *image_info, GdkImage *image,
r1b0g0r0 = ((guint32 *)bp2)[0];
g2r2b1g1 = ((guint32 *)bp2)[1];
b3g3r3b2 = ((guint32 *)bp2)[2];
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
((guint32 *)obptr)[0] =
((r1b0g0r0 & 0xf8) << 8) |
((r1b0g0r0 & 0xfc00) >> 5) |
@ -1534,6 +1549,22 @@ gdk_rgb_convert_565 (GdkRgbInfo *image_info, GdkImage *image,
((b3g3r3b2 & 0xf800) << 16) |
((b3g3r3b2 & 0xfc0000) << 3) |
((b3g3r3b2 & 0xf8000000) >> 11);
#else
((guint32 *)obptr)[0] =
(r1b0g0r0 & 0xf8000000) |
((r1b0g0r0 & 0x00fc0000) << 3) |
((r1b0g0r0 & 0x0000f800) << 5) |
((r1b0g0r0 & 0x000000f8) << 8) |
((g2r2b1g1 & 0xfc000000) >> 21) |
((g2r2b1g1 & 0x00f80000) >> 19);
((guint32 *)obptr)[1] =
((g2r2b1g1 & 0x0000f800) << 16) |
((g2r2b1g1 & 0x000000fc) << 19) |
((b3g3r3b2 & 0xf8000000) >> 11) |
((b3g3r3b2 & 0x00f80000) >> 8) |
((b3g3r3b2 & 0x0000fc00) >> 5) |
((b3g3r3b2 & 0x000000f8) >> 3);
#endif
bp2 += 12;
obptr += 8;
}
@ -1553,27 +1584,6 @@ gdk_rgb_convert_565 (GdkRgbInfo *image_info, GdkImage *image,
}
}
#else
/* Render a 24-bit RGB image in buf into the GdkImage, without dithering.
This assumes native byte ordering - what should really be done is to
check whether the image byte_order is consistent with the _ENDIAN
config flag, and if not, use a different function.
This routine is faster than the one included with Gtk 1.0 for a number
of reasons:
1. Shifting instead of lookup tables (less memory traffic).
2. Much less register pressure, especially because shifts are
in the code.
3. A memcpy is avoided (i.e. the transfer function).
4. On big-endian architectures, byte swapping is avoided.
That said, it wouldn't be hard to make it even faster - just make an
inner loop that reads 3 words (i.e. 4 24-bit pixels), does a lot of
shifting and masking, then writes 2 words.
*/
static void
gdk_rgb_convert_565 (GdkRgbInfo *image_info, GdkImage *image,
gint x0, gint y0, gint width, gint height,
@ -1607,7 +1617,7 @@ gdk_rgb_convert_565 (GdkRgbInfo *image_info, GdkImage *image,
}
#endif
#ifdef HAIRY_CONVERT_565
#if G_BYTE_ORDER == G_LITTLE_ENDIAN || defined(GDK_RGB_FAST_BE565_GRAY)
static void
gdk_rgb_convert_565_gray (GdkRgbInfo *image_info, GdkImage *image,
gint x0, gint y0, gint width, gint height,
@ -1645,6 +1655,7 @@ gdk_rgb_convert_565_gray (GdkRgbInfo *image_info, GdkImage *image,
guint32 g3g2g1g0;
g3g2g1g0 = ((guint32 *)bp2)[0];
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
((guint32 *)obptr)[0] =
((g3g2g1g0 & 0xf8) << 8) |
((g3g2g1g0 & 0xfc) << 3) |
@ -1659,6 +1670,22 @@ gdk_rgb_convert_565_gray (GdkRgbInfo *image_info, GdkImage *image,
(g3g2g1g0 & 0xf8000000) |
((g3g2g1g0 & 0xfc000000) >> 5) |
((g3g2g1g0 & 0xf8000000) >> 11);
#else
((guint32 *)obptr)[0] =
(g3g2g1g0 & 0xf8000000) |
((g3g2g1g0 & 0xfc000000) >> 5) |
((g3g2g1g0 & 0xf8000000) >> 11) |
((g3g2g1g0 & 0x00f80000) >> 8) |
((g3g2g1g0 & 0x00fc0000) >> 13) |
((g3g2g1g0 & 0x00f80000) >> 19);
((guint32 *)obptr)[1] =
((g3g2g1g0 & 0x0000f800) << 16) |
((g3g2g1g0 & 0x0000fc00) << 11) |
((g3g2g1g0 & 0x0000f800) << 5) |
((g3g2g1g0 & 0x000000f8) << 8) |
((g3g2g1g0 & 0x000000fc) << 3) |
((g3g2g1g0 & 0x000000f8) >> 3);
#endif
bp2 += 4;
obptr += 8;
}
@ -1745,7 +1772,7 @@ gdk_rgb_convert_565_br (GdkRgbInfo *image_info, GdkImage *image,
/* Thanks to Ray Lehtiniemi for a patch that resulted in a ~25% speedup
in this mode. */
#ifdef HAIRY_CONVERT_565
#if G_BYTE_ORDER == G_LITTLE_ENDIAN || defined(GDK_RGB_FAST_BE565_DITHER)
static void
gdk_rgb_convert_565_d (GdkRgbInfo *image_info, GdkImage *image,
gint x0, gint y0, gint width, gint height,
@ -1800,6 +1827,7 @@ gdk_rgb_convert_565_d (GdkRgbInfo *image_info, GdkImage *image,
r1b0g0r0 = ((guint32 *)bp2)[0];
g2r2b1g1 = ((guint32 *)bp2)[1];
b3g3r3b2 = ((guint32 *)bp2)[2];
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
rgb02 =
((r1b0g0r0 & 0xff) << 20) +
((r1b0g0r0 & 0xff00) << 2) +
@ -1846,6 +1874,54 @@ gdk_rgb_convert_565_d (GdkRgbInfo *image_info, GdkImage *image,
((rgb13 & 0x0f800000) << 4) |
((rgb13 & 0x0003f000) << 9) |
((rgb13 & 0x000000f8) << 13);
#else
rgb02 =
((r1b0g0r0 & 0xff000000) >> 4) +
((r1b0g0r0 & 0x00ff0000) >> 6) +
((r1b0g0r0 & 0x0000ff00) >> 8) +
dmp[x & (DM_WIDTH - 1)];
rgb02 += 0x10040100
- ((rgb02 & 0x1e0001e0) >> 5)
- ((rgb02 & 0x00070000) >> 6);
rgb13 =
((r1b0g0r0 & 0x000000ff) << 20) +
((g2r2b1g1 & 0xff000000) >> 14) +
((g2r2b1g1 & 0x00ff0000) >> 16) +
dmp[(x + 1) & (DM_WIDTH - 1)];
rgb13 += 0x10040100
- ((rgb13 & 0x1e0001e0) >> 5)
- ((rgb13 & 0x00070000) >> 6);
((guint32 *)obptr)[0] =
((rgb02 & 0x0f800000) << 4) |
((rgb02 & 0x0003f000) << 9) |
((rgb02 & 0x000000f8) << 13) |
((rgb13 & 0x0f800000) >> 12) |
((rgb13 & 0x0003f000) >> 7) |
((rgb13 & 0x000000f8) >> 3);
rgb02 =
((g2r2b1g1 & 0x0000ff00) << 12) +
((g2r2b1g1 & 0x000000ff) << 10) +
((b3g3r3b2 & 0xff000000) >> 24) +
dmp[(x + 2) & (DM_WIDTH - 1)];
rgb02 += 0x10040100
- ((rgb02 & 0x1e0001e0) >> 5)
- ((rgb02 & 0x00070000) >> 6);
rgb13 =
((b3g3r3b2 & 0x00ff0000) << 4) +
((b3g3r3b2 & 0x0000ff00) << 2) +
(b3g3r3b2 & 0x000000ff) +
dmp[(x + 3) & (DM_WIDTH - 1)];
rgb13 += 0x10040100
- ((rgb13 & 0x1e0001e0) >> 5)
- ((rgb13 & 0x00070000) >> 6);
((guint32 *)obptr)[1] =
((rgb02 & 0x0f800000) << 4) |
((rgb02 & 0x0003f000) << 9) |
((rgb02 & 0x000000f8) << 13) |
((rgb13 & 0x0f800000) >> 12) |
((rgb13 & 0x0003f000) >> 7) |
((rgb13 & 0x000000f8) >> 3);
#endif
bp2 += 12;
obptr += 8;
}
@ -1916,6 +1992,10 @@ gdk_rgb_convert_565_d (GdkRgbInfo *image_info, GdkImage *image,
}
#endif
#undef GDK_RGB_FAST_BE565_RGB
#undef GDK_RGB_FAST_BE565_GRAY
#undef GDK_RGB_FAST_BE565_DITHER
static void
gdk_rgb_convert_555 (GdkRgbInfo *image_info, GdkImage *image,
gint x0, gint y0, gint width, gint height,
@ -2242,6 +2322,68 @@ gdk_rgb_convert_8880_br (GdkRgbInfo *image_info, GdkImage *image,
}
}
#define DEFINE_GDK_RGB_CONVERT_101010(name, high, low, to_order) \
static void \
name (GdkRgbInfo *image_info, GdkImage *image, \
gint x0, gint y0, gint width, gint height, \
const guchar *buf, int rowstride, \
gint x_align, gint y_align, GdkRgbCmap *cmap) \
{ \
int y, w; \
guchar *obuf, *p; \
gint bpl; \
const guchar *bptr, *bp2; \
guint32 r, g, b; \
guint32 pixel; \
guint32 alpha_mask; \
\
alpha_mask = image_info->visual->depth == 32 ? 0xc0000000U : 0; \
\
bptr = buf; \
bpl = image->bpl; \
obuf = ((guchar *) image->mem) + y0 * bpl + x0 * 4; \
\
for (y = 0; y < height; y++) \
{ \
bp2 = bptr; \
p = obuf; \
w = width; \
\
while (w--) \
{ \
r = *bp2++; \
g = *bp2++; \
b = *bp2++; \
\
r = (r << 2) | (r >> 6); \
g = (g << 2) | (g >> 6); \
b = (b << 2) | (b >> 6); \
\
pixel = alpha_mask | \
(high << 20) | \
(g << 10) | \
low; \
\
*((guint32 *) p) = to_order (pixel); \
p += 4; \
} \
\
bptr += rowstride; \
obuf += bpl; \
} \
}
DEFINE_GDK_RGB_CONVERT_101010 (gdk_rgb_convert_101010_r_low_lsb,
b, r, GUINT32_TO_LE)
DEFINE_GDK_RGB_CONVERT_101010 (gdk_rgb_convert_101010_b_low_lsb,
r, b, GUINT32_TO_LE)
DEFINE_GDK_RGB_CONVERT_101010 (gdk_rgb_convert_101010_r_low_msb,
b, r, GUINT32_TO_BE)
DEFINE_GDK_RGB_CONVERT_101010 (gdk_rgb_convert_101010_b_low_msb,
r, b, GUINT32_TO_BE)
#undef DEFINE_GDK_RGB_CONVERT_101010
/* Generic truecolor/directcolor conversion function. Slow, but these
are oddball modes. */
static void
@ -2555,7 +2697,7 @@ gdk_rgb_convert_4_pack (GdkRgbInfo *image_info, GdkImage *image,
r = *bp2++;
g = *bp2++;
b = *bp2++;
dith = (dmp[(x_align + x + 1) & (DM_WIDTH - 1)] << 2) | 3;
dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) | 3;
ix = (((r + dith) & 0x100) >> 2) |
(((g + 258 - dith) & 0x100) >> 5) |
(((b + dith) & 0x100) >> 8);
@ -2564,7 +2706,7 @@ gdk_rgb_convert_4_pack (GdkRgbInfo *image_info, GdkImage *image,
obptr++;
x++;
}
while (x < width)
while (x + 1 < width)
{
r = *bp2++;
g = *bp2++;
@ -2575,14 +2717,11 @@ gdk_rgb_convert_4_pack (GdkRgbInfo *image_info, GdkImage *image,
(((b + dith) & 0x100) >> 8);
pix0 = (colorcube_d[ix]);
x++;
if (x == width)
pix1 = (*obptr & 0x0F);
else
{
r = *bp2++;
g = *bp2++;
b = *bp2++;
dith = (dmp[(x_align + x + 1) & (DM_WIDTH - 1)] << 2) | 3;
dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) | 3;
ix = (((r + dith) & 0x100) >> 2) |
(((g + 258 - dith) & 0x100) >> 5) |
(((b + dith) & 0x100) >> 8);
@ -2591,6 +2730,18 @@ gdk_rgb_convert_4_pack (GdkRgbInfo *image_info, GdkImage *image,
}
*obptr++ = (pix0 << 4) | pix1;
}
if (x < width)
{
r = *bp2++;
g = *bp2++;
b = *bp2++;
dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) | 3;
ix = (((r + dith) & 0x100) >> 2) |
(((g + 258 - dith) & 0x100) >> 5) |
(((b + dith) & 0x100) >> 8);
pix0 = (colorcube_d[ix]);
*obptr = (pix0 << 4) | (*obptr & 0x0F);
}
bptr += rowstride;
obuf += bpl;
}
@ -3195,6 +3346,34 @@ gdk_rgb_select_conv (GdkRgbInfo *image_info)
#endif
}
#endif
else if (bpp == 32 && (depth == 30 || depth == 32) &&
vtype == GDK_VISUAL_TRUE_COLOR &&
byte_order == GDK_LSB_FIRST &&
red_mask == 0x000003ff &&
green_mask == 0x000ffc00 &&
blue_mask == 0x3ff00000)
conv = gdk_rgb_convert_101010_r_low_lsb;
else if (bpp == 32 && (depth == 30 || depth == 32) &&
vtype == GDK_VISUAL_TRUE_COLOR &&
byte_order == GDK_LSB_FIRST &&
red_mask == 0x3ff00000 &&
green_mask == 0x000ffc00 &&
blue_mask == 0x000003ff)
conv = gdk_rgb_convert_101010_b_low_lsb;
else if (bpp == 32 && (depth == 30 || depth == 32) &&
vtype == GDK_VISUAL_TRUE_COLOR &&
byte_order == GDK_MSB_FIRST &&
red_mask == 0x000003ff &&
green_mask == 0x000ffc00 &&
blue_mask == 0x3ff00000)
conv = gdk_rgb_convert_101010_r_low_msb;
else if (bpp == 32 && (depth == 30 || depth == 32) &&
vtype == GDK_VISUAL_TRUE_COLOR &&
byte_order == GDK_MSB_FIRST &&
red_mask == 0x3ff00000 &&
green_mask == 0x000ffc00 &&
blue_mask == 0x000003ff)
conv = gdk_rgb_convert_101010_b_low_msb;
else if (vtype == GDK_VISUAL_TRUE_COLOR && byte_order == GDK_LSB_FIRST)
{
conv = gdk_rgb_convert_truecolor_lsb;
@ -3261,7 +3440,7 @@ gdk_rgb_select_conv (GdkRgbInfo *image_info)
conv = gdk_rgb_convert_gray4_pack;
conv_d = gdk_rgb_convert_gray4_d_pack;
}
else if (bpp == 4 && depth == 4 &&
else if (bpp == 4 && depth <= 4 && depth >= 2 &&
vtype == GDK_VISUAL_STATIC_COLOR)
conv = gdk_rgb_convert_4_pack;

View file

@ -147,6 +147,48 @@ gboolean gdk_rgb_colormap_ditherable (GdkColormap *cmap);
#endif
#endif /* GDK_DISABLE_DEPRECATED */
void gdk_draw_rgb_48_image (GdkDrawable *drawable,
GdkGC *gc,
gint x,
gint y,
gint width,
gint height,
GdkRgbDither dith,
const guint16 *rgb_buf,
gint rowstride);
void gdk_draw_rgb_48_image_dithalign (GdkDrawable *drawable,
GdkGC *gc,
gint x,
gint y,
gint width,
gint height,
GdkRgbDither dith,
const guint16 *rgb_buf,
gint rowstride,
gint xdith,
gint ydith);
void gdk_draw_rgbx_64_image (GdkDrawable *drawable,
GdkGC *gc,
gint x,
gint y,
gint width,
gint height,
GdkRgbDither dith,
const guint16 *rgbx_buf,
gint rowstride);
void gdk_draw_rgbx_64_image_dithalign
(GdkDrawable *drawable,
GdkGC *gc,
gint x,
gint y,
gint width,
gint height,
GdkRgbDither dith,
const guint16 *rgbx_buf,
gint rowstride,
gint xdith,
gint ydith);
G_END_DECLS

742
gdk/gdkrgb16.c Normal file
View file

@ -0,0 +1,742 @@
/* GTK - The GIMP Toolkit
* High-precision GdkRGB image conversion
*
* 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.
*/
#include "config.h"
#include <string.h>
#include "gdkinternals.h"
#include "gdkrgb.h"
#include "gdkscreen.h"
#include "gdkalias.h"
typedef void (*GdkRgb16ConvFunc) (GdkImage *image,
gint x0,
gint y0,
gint width,
gint height,
const guint16 *buf,
gint rowstride);
#define GDK_RGB16_STORE_RGB(p, r, g, b, a) G_STMT_START { \
(p)[0] = (r) >> 8; \
(p)[1] = (g) >> 8; \
(p)[2] = (b) >> 8; \
(p) += 3; \
} G_STMT_END
#define GDK_RGB16_STORE_BGR(p, r, g, b, a) G_STMT_START { \
(p)[0] = (b) >> 8; \
(p)[1] = (g) >> 8; \
(p)[2] = (r) >> 8; \
(p) += 3; \
} G_STMT_END
#define GDK_RGB16_STORE_BGRA(p, r, g, b, a) G_STMT_START { \
(p)[0] = (b) >> 8; \
(p)[1] = (g) >> 8; \
(p)[2] = (r) >> 8; \
(p)[3] = 0xff; \
(p) += 4; \
} G_STMT_END
#define GDK_RGB16_STORE_ARGB(p, r, g, b, a) G_STMT_START { \
(p)[0] = 0xff; \
(p)[1] = (r) >> 8; \
(p)[2] = (g) >> 8; \
(p)[3] = (b) >> 8; \
(p) += 4; \
} G_STMT_END
#define GDK_RGB16_STORE_RGB0_NATIVE(p, r, g, b, a) G_STMT_START { \
guint32 pixel__ = (((b) >> 8) << 16) | \
(((g) >> 8) << 8) | \
((r) >> 8); \
memcpy ((p), &pixel__, sizeof (pixel__)); \
(p) += 4; \
} G_STMT_END
#define GDK_RGB16_STORE_565(p, r, g, b, a) G_STMT_START { \
guint16 pixel__ = ((r) & 0xf800) | \
(((g) & 0xfc00) >> 5) | \
((b) >> 11); \
memcpy ((p), &pixel__, sizeof (pixel__)); \
(p) += 2; \
} G_STMT_END
#define GDK_RGB16_STORE_565_BR(p, r, g, b, a) G_STMT_START { \
guint16 pixel__ = ((r) & 0xf800) | \
(((g) & 0xfc00) >> 5) | \
((b) >> 11); \
pixel__ = (pixel__ >> 8) | (pixel__ << 8); \
memcpy ((p), &pixel__, sizeof (pixel__)); \
(p) += 2; \
} G_STMT_END
#define GDK_RGB16_STORE_555(p, r, g, b, a) G_STMT_START { \
guint16 pixel__ = (((r) & 0xf800) >> 1) | \
(((g) & 0xf800) >> 6) | \
((b) >> 11); \
memcpy ((p), &pixel__, sizeof (pixel__)); \
(p) += 2; \
} G_STMT_END
#define GDK_RGB16_STORE_555_BR(p, r, g, b, a) G_STMT_START { \
guint16 pixel__ = (((r) & 0xf800) >> 1) | \
(((g) & 0xf800) >> 6) | \
((b) >> 11); \
pixel__ = (pixel__ >> 8) | (pixel__ << 8); \
memcpy ((p), &pixel__, sizeof (pixel__)); \
(p) += 2; \
} G_STMT_END
#define GDK_RGB16_STORE_101010_R_LOW_LE(p, r, g, b, a) \
G_STMT_START { \
guint32 pixel__ = (a) | \
(((b) >> 6) << 20) | \
(((g) >> 6) << 10) | \
((r) >> 6); \
pixel__ = GUINT32_TO_LE (pixel__); \
memcpy ((p), &pixel__, sizeof (pixel__)); \
(p) += 4; \
} G_STMT_END
#define GDK_RGB16_STORE_101010_B_LOW_LE(p, r, g, b, a) \
G_STMT_START { \
guint32 pixel__ = (a) | \
(((r) >> 6) << 20) | \
(((g) >> 6) << 10) | \
((b) >> 6); \
pixel__ = GUINT32_TO_LE (pixel__); \
memcpy ((p), &pixel__, sizeof (pixel__)); \
(p) += 4; \
} G_STMT_END
#define GDK_RGB16_STORE_101010_R_LOW_BE(p, r, g, b, a) \
G_STMT_START { \
guint32 pixel__ = (a) | \
(((b) >> 6) << 20) | \
(((g) >> 6) << 10) | \
((r) >> 6); \
pixel__ = GUINT32_TO_BE (pixel__); \
memcpy ((p), &pixel__, sizeof (pixel__)); \
(p) += 4; \
} G_STMT_END
#define GDK_RGB16_STORE_101010_B_LOW_BE(p, r, g, b, a) \
G_STMT_START { \
guint32 pixel__ = (a) | \
(((r) >> 6) << 20) | \
(((g) >> 6) << 10) | \
((b) >> 6); \
pixel__ = GUINT32_TO_BE (pixel__); \
memcpy ((p), &pixel__, sizeof (pixel__)); \
(p) += 4; \
} G_STMT_END
#define DEFINE_GDK_RGB16_CONVERTER(name, words, pixel_bytes, store) \
static void \
name (GdkImage *image, \
gint x0, \
gint y0, \
gint width, \
gint height, \
const guint16 *buf, \
gint rowstride) \
{ \
const guchar *row; \
const guint16 *src; \
guchar *dst_row; \
guchar *dst; \
guint32 r, g, b; \
guint32 alpha_mask; \
gint x, y; \
\
row = (const guchar *) buf; \
dst_row = ((guchar *) image->mem) + \
y0 * image->bpl + x0 * (pixel_bytes); \
alpha_mask = image->depth == 32 ? 0xc0000000U : 0; \
(void) alpha_mask; \
\
for (y = 0; y < height; y++) \
{ \
src = (const guint16 *) row; \
dst = dst_row; \
\
for (x = 0; x < width; x++) \
{ \
r = src[0]; \
g = src[1]; \
b = src[2]; \
src += (words); \
store (dst, r, g, b, alpha_mask); \
} \
\
row += rowstride; \
dst_row += image->bpl; \
} \
}
#define DEFINE_GDK_RGB16_PAIR(suffix, pixel_bytes, store) \
DEFINE_GDK_RGB16_CONVERTER (gdk_rgb48_convert_ ## suffix, \
3, pixel_bytes, store) \
DEFINE_GDK_RGB16_CONVERTER (gdk_rgbx64_convert_ ## suffix, \
4, pixel_bytes, store)
DEFINE_GDK_RGB16_PAIR (rgb, 3, GDK_RGB16_STORE_RGB)
DEFINE_GDK_RGB16_PAIR (bgr, 3, GDK_RGB16_STORE_BGR)
DEFINE_GDK_RGB16_PAIR (bgra, 4, GDK_RGB16_STORE_BGRA)
DEFINE_GDK_RGB16_PAIR (argb, 4, GDK_RGB16_STORE_ARGB)
DEFINE_GDK_RGB16_PAIR (rgb0_native, 4, GDK_RGB16_STORE_RGB0_NATIVE)
DEFINE_GDK_RGB16_PAIR (565, 2, GDK_RGB16_STORE_565)
DEFINE_GDK_RGB16_PAIR (565_br, 2, GDK_RGB16_STORE_565_BR)
DEFINE_GDK_RGB16_PAIR (555, 2, GDK_RGB16_STORE_555)
DEFINE_GDK_RGB16_PAIR (555_br, 2, GDK_RGB16_STORE_555_BR)
DEFINE_GDK_RGB16_PAIR (101010_r_low_le, 4,
GDK_RGB16_STORE_101010_R_LOW_LE)
DEFINE_GDK_RGB16_PAIR (101010_b_low_le, 4,
GDK_RGB16_STORE_101010_B_LOW_LE)
DEFINE_GDK_RGB16_PAIR (101010_r_low_be, 4,
GDK_RGB16_STORE_101010_R_LOW_BE)
DEFINE_GDK_RGB16_PAIR (101010_b_low_be, 4,
GDK_RGB16_STORE_101010_B_LOW_BE)
#undef DEFINE_GDK_RGB16_PAIR
#undef DEFINE_GDK_RGB16_CONVERTER
#undef GDK_RGB16_STORE_RGB
#undef GDK_RGB16_STORE_BGR
#undef GDK_RGB16_STORE_BGRA
#undef GDK_RGB16_STORE_ARGB
#undef GDK_RGB16_STORE_RGB0_NATIVE
#undef GDK_RGB16_STORE_565
#undef GDK_RGB16_STORE_565_BR
#undef GDK_RGB16_STORE_555
#undef GDK_RGB16_STORE_555_BR
#undef GDK_RGB16_STORE_101010_R_LOW_LE
#undef GDK_RGB16_STORE_101010_B_LOW_LE
#undef GDK_RGB16_STORE_101010_R_LOW_BE
#undef GDK_RGB16_STORE_101010_B_LOW_BE
static GdkRgb16ConvFunc
gdk_rgb16_select_converter (GdkDrawable *drawable,
gboolean is_rgbx,
GdkRgbDither dith)
{
GdkVisual *visual;
GdkByteOrder byte_order;
GdkScreen *screen;
guint32 red_mask, green_mask, blue_mask;
gint depth;
gint bits_per_pixel;
gboolean byte_reversed;
gboolean mask_rgb;
gboolean mask_bgr;
#define SELECT_PAIR(suffix) \
return is_rgbx ? gdk_rgbx64_convert_ ## suffix \
: gdk_rgb48_convert_ ## suffix
/*
* Preserve the existing GdkRGB dither path for maximum dithering
* and for unknown future values.
*/
if (dith != GDK_RGB_DITHER_NONE &&
dith != GDK_RGB_DITHER_NORMAL)
return NULL;
visual = gdk_drawable_get_visual (drawable);
if (visual == NULL)
return NULL;
if (gdk_visual_get_visual_type (visual) != GDK_VISUAL_TRUE_COLOR)
return NULL;
screen = gdk_visual_get_screen (visual);
depth = gdk_visual_get_depth (visual);
byte_order = gdk_visual_get_byte_order (visual);
gdk_visual_get_red_pixel_details (visual, &red_mask, NULL, NULL);
gdk_visual_get_green_pixel_details (visual, &green_mask, NULL, NULL);
gdk_visual_get_blue_pixel_details (visual, &blue_mask, NULL, NULL);
bits_per_pixel = _gdk_windowing_get_bits_for_depth
(gdk_screen_get_display (screen), depth);
#if G_BYTE_ORDER == G_BIG_ENDIAN
byte_reversed = byte_order == GDK_LSB_FIRST;
#else
byte_reversed = byte_order == GDK_MSB_FIRST;
#endif
mask_rgb = red_mask == 0xff0000 &&
green_mask == 0x00ff00 &&
blue_mask == 0x0000ff;
mask_bgr = red_mask == 0x0000ff &&
green_mask == 0x00ff00 &&
blue_mask == 0xff0000;
if (bits_per_pixel == 16 &&
depth == 16 &&
red_mask == 0xf800 &&
green_mask == 0x07e0 &&
blue_mask == 0x001f)
{
if (byte_reversed)
SELECT_PAIR (565_br);
SELECT_PAIR (565);
}
if (bits_per_pixel == 16 &&
depth == 15 &&
red_mask == 0x7c00 &&
green_mask == 0x03e0 &&
blue_mask == 0x001f)
{
if (byte_reversed)
SELECT_PAIR (555_br);
SELECT_PAIR (555);
}
if (bits_per_pixel == 24 &&
depth == 24 &&
((mask_rgb && byte_order == GDK_LSB_FIRST) ||
(mask_bgr && byte_order == GDK_MSB_FIRST)))
SELECT_PAIR (bgr);
if (bits_per_pixel == 24 &&
depth == 24 &&
((mask_rgb && byte_order == GDK_MSB_FIRST) ||
(mask_bgr && byte_order == GDK_LSB_FIRST)))
SELECT_PAIR (rgb);
if (bits_per_pixel == 32 &&
(depth == 24 || depth == 32) &&
mask_rgb &&
byte_order == GDK_MSB_FIRST)
SELECT_PAIR (argb);
if (bits_per_pixel == 32 &&
(depth == 24 || depth == 32) &&
mask_rgb &&
byte_order == GDK_LSB_FIRST)
SELECT_PAIR (bgra);
#if G_BYTE_ORDER == G_BIG_ENDIAN
if (bits_per_pixel == 32 &&
depth == 24 &&
mask_bgr &&
byte_order == GDK_MSB_FIRST)
SELECT_PAIR (rgb0_native);
#else
if (bits_per_pixel == 32 &&
depth == 24 &&
mask_bgr &&
byte_order == GDK_LSB_FIRST)
SELECT_PAIR (rgb0_native);
#endif
if (bits_per_pixel == 32 &&
(depth == 30 || depth == 32) &&
byte_order == GDK_LSB_FIRST &&
red_mask == 0x000003ff &&
green_mask == 0x000ffc00 &&
blue_mask == 0x3ff00000)
SELECT_PAIR (101010_r_low_le);
if (bits_per_pixel == 32 &&
(depth == 30 || depth == 32) &&
byte_order == GDK_LSB_FIRST &&
red_mask == 0x3ff00000 &&
green_mask == 0x000ffc00 &&
blue_mask == 0x000003ff)
SELECT_PAIR (101010_b_low_le);
if (bits_per_pixel == 32 &&
(depth == 30 || depth == 32) &&
byte_order == GDK_MSB_FIRST &&
red_mask == 0x000003ff &&
green_mask == 0x000ffc00 &&
blue_mask == 0x3ff00000)
SELECT_PAIR (101010_r_low_be);
if (bits_per_pixel == 32 &&
(depth == 30 || depth == 32) &&
byte_order == GDK_MSB_FIRST &&
red_mask == 0x3ff00000 &&
green_mask == 0x000ffc00 &&
blue_mask == 0x000003ff)
SELECT_PAIR (101010_b_low_be);
#undef SELECT_PAIR
return NULL;
}
static void
gdk_rgb16_draw_direct (GdkDrawable *drawable,
GdkGC *gc,
gint x,
gint y,
gint width,
gint height,
const guint16 *buf,
gint pixel_words,
gint rowstride,
GdkRgb16ConvFunc converter)
{
GdkScreen *screen;
GdkImage *image;
const guint16 *tile;
gint depth;
gint x0, y0;
gint xs0, ys0;
gint width1, height1;
screen = gdk_drawable_get_screen (drawable);
depth = gdk_drawable_get_depth (drawable);
for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
{
height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT);
for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH)
{
width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
tile = (const guint16 *)
((const guchar *) buf +
y0 * rowstride +
x0 * pixel_words * sizeof (guint16));
image = _gdk_image_get_scratch (screen,
width1,
height1,
depth,
&xs0,
&ys0);
converter (image,
xs0,
ys0,
width1,
height1,
tile,
rowstride);
gdk_draw_image (drawable,
gc,
image,
xs0,
ys0,
x + x0,
y + y0,
width1,
height1);
}
}
}
static void
gdk_rgb16_draw_fallback (GdkDrawable *drawable,
GdkGC *gc,
gint x,
gint y,
gint width,
gint height,
GdkRgbDither dith,
const guint16 *buf,
gint pixel_words,
gint rowstride,
gint xdith,
gint ydith)
{
const guchar *input_row;
const guint16 *input;
guchar *stage;
guchar *output;
gint stage_rowstride;
gint x0, y0;
gint x1, y1;
gint width1, height1;
stage = g_malloc (MIN (width, GDK_SCRATCH_IMAGE_WIDTH) *
MIN (height, GDK_SCRATCH_IMAGE_HEIGHT) * 3);
for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
{
height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT);
for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH)
{
width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
stage_rowstride = width1 * 3;
input_row = (const guchar *) buf +
y0 * rowstride +
x0 * pixel_words * sizeof (guint16);
output = stage;
for (y1 = 0; y1 < height1; y1++)
{
input = (const guint16 *) input_row;
for (x1 = 0; x1 < width1; x1++)
{
*output++ = input[0] >> 8;
*output++ = input[1] >> 8;
*output++ = input[2] >> 8;
input += pixel_words;
}
input_row += rowstride;
}
gdk_draw_rgb_image_dithalign (drawable,
gc,
x + x0,
y + y0,
width1,
height1,
dith,
stage,
stage_rowstride,
xdith,
ydith);
}
}
g_free (stage);
}
static void
gdk_draw_rgb16_image (GdkDrawable *drawable,
GdkGC *gc,
gint x,
gint y,
gint width,
gint height,
GdkRgbDither dith,
const guint16 *buf,
gint rowstride,
gint xdith,
gint ydith,
gboolean is_rgbx)
{
GdkRgb16ConvFunc converter;
gint pixel_words;
g_return_if_fail (GDK_IS_DRAWABLE (drawable));
g_return_if_fail (GDK_IS_GC (gc));
g_return_if_fail (buf != NULL);
g_return_if_fail ((((guintptr) buf) & 1) == 0);
g_return_if_fail ((rowstride & 1) == 0);
if (width <= 0 || height <= 0)
return;
pixel_words = is_rgbx ? 4 : 3;
converter = gdk_rgb16_select_converter (drawable, is_rgbx, dith);
if (converter != NULL)
gdk_rgb16_draw_direct (drawable,
gc,
x,
y,
width,
height,
buf,
pixel_words,
rowstride,
converter);
else
gdk_rgb16_draw_fallback (drawable,
gc,
x,
y,
width,
height,
dith,
buf,
pixel_words,
rowstride,
xdith,
ydith);
}
/**
* gdk_draw_rgb_48_image:
* @drawable: a #GdkDrawable
* @gc: a #GdkGC
* @x: destination X coordinate
* @y: destination Y coordinate
* @width: image width
* @height: image height
* @dith: dithering mode
* @rgb_buf: host-endian RGB data with three 16-bit channels per pixel
* @rowstride: number of bytes between consecutive rows
*
* Draws 48-bit RGB image data.
**/
void
gdk_draw_rgb_48_image (GdkDrawable *drawable,
GdkGC *gc,
gint x,
gint y,
gint width,
gint height,
GdkRgbDither dith,
const guint16 *rgb_buf,
gint rowstride)
{
gdk_draw_rgb16_image (drawable,
gc,
x,
y,
width,
height,
dith,
rgb_buf,
rowstride,
0,
0,
FALSE);
}
/**
* gdk_draw_rgb_48_image_dithalign:
* @drawable: a #GdkDrawable
* @gc: a #GdkGC
* @x: destination X coordinate
* @y: destination Y coordinate
* @width: image width
* @height: image height
* @dith: dithering mode
* @rgb_buf: host-endian RGB data with three 16-bit channels per pixel
* @rowstride: number of bytes between consecutive rows
* @xdith: X dither offset
* @ydith: Y dither offset
*
* Draws 48-bit RGB image data with explicit dither alignment.
**/
void
gdk_draw_rgb_48_image_dithalign (GdkDrawable *drawable,
GdkGC *gc,
gint x,
gint y,
gint width,
gint height,
GdkRgbDither dith,
const guint16 *rgb_buf,
gint rowstride,
gint xdith,
gint ydith)
{
gdk_draw_rgb16_image (drawable,
gc,
x,
y,
width,
height,
dith,
rgb_buf,
rowstride,
xdith,
ydith,
FALSE);
}
/**
* gdk_draw_rgbx_64_image:
* @drawable: a #GdkDrawable
* @gc: a #GdkGC
* @x: destination X coordinate
* @y: destination Y coordinate
* @width: image width
* @height: image height
* @dith: dithering mode
* @rgbx_buf: host-endian RGBX data with four 16-bit channels per pixel
* @rowstride: number of bytes between consecutive rows
*
* Draws 64-bit RGBX image data. The X channel is ignored.
**/
void
gdk_draw_rgbx_64_image (GdkDrawable *drawable,
GdkGC *gc,
gint x,
gint y,
gint width,
gint height,
GdkRgbDither dith,
const guint16 *rgbx_buf,
gint rowstride)
{
gdk_draw_rgb16_image (drawable,
gc,
x,
y,
width,
height,
dith,
rgbx_buf,
rowstride,
0,
0,
TRUE);
}
/**
* gdk_draw_rgbx_64_image_dithalign:
* @drawable: a #GdkDrawable
* @gc: a #GdkGC
* @x: destination X coordinate
* @y: destination Y coordinate
* @width: image width
* @height: image height
* @dith: dithering mode
* @rgbx_buf: host-endian RGBX data with four 16-bit channels per pixel
* @rowstride: number of bytes between consecutive rows
* @xdith: X dither offset
* @ydith: Y dither offset
*
* Draws 64-bit RGBX image data with explicit dither alignment.
* The X channel is ignored.
**/
void
gdk_draw_rgbx_64_image_dithalign (GdkDrawable *drawable,
GdkGC *gc,
gint x,
gint y,
gint width,
gint height,
GdkRgbDither dith,
const guint16 *rgbx_buf,
gint rowstride,
gint xdith,
gint ydith)
{
gdk_draw_rgb16_image (drawable,
gc,
x,
y,
width,
height,
dith,
rgbx_buf,
rowstride,
xdith,
ydith,
TRUE);
}
#define __GDK_RGB16_C__
#include "gdkaliasdef.c"

View file

@ -9855,6 +9855,9 @@ static const guint type_masks[] = {
0, /* GDK_OWNER_CHANGE = 34 */
0, /* GDK_GRAB_BROKEN = 35 */
0, /* GDK_DAMAGE = 36 */
GDK_TOUCH_BEGIN_MASK, /* GDK_TOUCH_BEGIN = 37 */
GDK_TOUCH_UPDATE_MASK, /* GDK_TOUCH_UPDATE = 38 */
GDK_TOUCH_END_MASK, /* GDK_TOUCH_END = 39 */
};
G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST);

View file

@ -92,6 +92,7 @@ gdk_OBJECTS = \
gdkrectangle.obj \
gdkregion-generic.obj \
gdkrgb.obj \
gdkrgb16.obj \
gdkscreen.obj \
gdkselection.obj \
gdkvisual.obj \

View file

@ -14,7 +14,7 @@ print <<EOF;
#include <glib.h>
#ifdef G_HAVE_GNUC_VISIBILITY
#if defined(G_HAVE_GNUC_VISIBILITY) && !defined(__APPLE__)
EOF

View file

@ -599,6 +599,25 @@
gdk_screen_get_rgba_colormap (_gdk_screen);
}
-(void)viewWillDraw
{
/* macOS 11 (Big Sur) and newer may use a higher precision backing
* format for layer contents. For GTK2's 8-bit drawing this can add
* avoidable conversion overhead. Use a dynamic Objective-C call here
* instead of a hard QuartzCore/CALayer dependency, so old SDKs and old
* macOS targets keep building and keep their old behaviour.
*/
if (gdk_quartz_osx_version () >= GDK_OSX_BIG_SUR)
{
id layer = [self layer];
if (layer && [layer respondsToSelector: @selector(setContentsFormat:)])
[layer setValue: @"RGBA8Uint" forKey: @"contentsFormat"];
}
[super viewWillDraw];
}
-(void)drawRect: (NSRect)rect
{
GdkRectangle gdk_rect;

View file

@ -893,7 +893,8 @@ gdk_quartz_drawable_release_context (GdkDrawable *drawable,
if (window_impl->in_paint_rect_count == 0)
{
_gdk_quartz_drawable_flush (drawable);
[window_impl->view unlockFocus];
if (gdk_quartz_osx_version () < GDK_OSX_MOJAVE)
[window_impl->view unlockFocus];
}
}
else if (GDK_IS_PIXMAP_IMPL_QUARTZ (drawable))

View file

@ -34,9 +34,20 @@ gdk_quartz_osx_version (void)
if (minor == GDK_OSX_UNSUPPORTED)
{
OSErr err = Gestalt (gestaltSystemVersionMinor, (SInt32*)&minor);
gint32 major = GDK_OSX_UNSUPPORTED;
OSErr err = Gestalt (gestaltSystemVersionMajor, (SInt32*)&major);
g_return_val_if_fail (err == noErr, GDK_OSX_UNSUPPORTED);
err = Gestalt (gestaltSystemVersionMinor, (SInt32*)&minor);
g_return_val_if_fail (err == noErr, GDK_OSX_UNSUPPORTED);
/* GTK2 encodes macOS 10.x releases by their minor version.
* Map macOS 11+ into the same sequence:
* 11 -> 16, 12 -> 17, 13 -> 18, ...
*/
if (major > 10)
minor = major + 5;
}
if (minor < GDK_OSX_MIN)

View file

@ -54,7 +54,13 @@ typedef enum
GDK_OSX_SIERRA = 12,
GDK_OSX_HIGH_SIERRA = 13,
GDK_OSX_MOJAVE = 14,
GDK_OSX_CURRENT = 14,
GDK_OSX_CATALINA = 15,
GDK_OSX_BIG_SUR = 16,
GDK_OSX_MONTEREY = 17,
GDK_OSX_VENTURA = 18,
GDK_OSX_SONOMA = 19,
GDK_OSX_SEQUOIA = 20,
GDK_OSX_CURRENT = 20,
GDK_OSX_NEW = 99
} GdkOSXVersion;

View file

@ -104,7 +104,8 @@ gdk_window_impl_quartz_get_context (GdkDrawable *drawable,
* and for widgets that send fake expose events like the arrow
* buttons in spinbuttons or the position marker in rulers.
*/
if (window_impl->in_paint_rect_count == 0)
if (window_impl->in_paint_rect_count == 0 &&
gdk_quartz_osx_version () < GDK_OSX_MOJAVE)
{
if (![window_impl->view lockFocusIfCanDraw])
return NULL;
@ -468,7 +469,8 @@ _gdk_windowing_before_process_all_updates (void)
{
in_process_all_updates = TRUE;
NSDisableScreenUpdates ();
if (gdk_quartz_osx_version () < GDK_OSX_MOJAVE)
NSDisableScreenUpdates ();
}
void
@ -489,8 +491,9 @@ _gdk_windowing_after_process_all_updates (void)
/* 10.14 needs to be told that the view needs to be redrawn, see
* https://gitlab.gnome.org/GNOME/gtk/issues/1479 */
if (gdk_quartz_osx_version() >= GDK_OSX_MOJAVE)
[[nswindow contentView] setNeedsDisplay:YES];
if (gdk_quartz_osx_version () >= GDK_OSX_MOJAVE &&
gdk_quartz_osx_version () < GDK_OSX_BIG_SUR)
[[nswindow contentView] setNeedsDisplay:YES];
[nswindow enableFlushWindow];
[nswindow flushWindow];
[nswindow release];
@ -502,7 +505,8 @@ _gdk_windowing_after_process_all_updates (void)
in_process_all_updates = FALSE;
NSEnableScreenUpdates ();
if (gdk_quartz_osx_version () < GDK_OSX_MOJAVE)
NSEnableScreenUpdates ();
}
static void

View file

@ -692,6 +692,7 @@ update_keymap (GdkKeymap *gdk_keymap)
if (hkls_len != keymap->layout_handles->len)
keymap->keysym_tab = g_renew (guint, keymap->keysym_tab, keysym_tab_size);
memset (key_state, 0, sizeof(key_state));
memset (keymap->keysym_tab, 0, keysym_tab_size);
g_array_set_size (keymap->layout_handles, hkls_len);
g_array_set_size (keymap->options, hkls_len);

View file

@ -2767,6 +2767,10 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display,
* WindowFromPoint() can find our windows, we follow similar logic
* here, and ignore invisible and disabled windows.
*/
UINT cwp_flags = CWP_SKIPDISABLED |
CWP_SKIPINVISIBLE |
CWP_SKIPTRANSPARENT;
hwnd = GetDesktopWindow ();
do {
window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
@ -2777,8 +2781,7 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display,
break;
screen_to_client (hwnd, screen_pt, &client_pt);
hwndc = ChildWindowFromPointEx (hwnd, client_pt, CWP_SKIPDISABLED |
CWP_SKIPINVISIBLE);
hwndc = ChildWindowFromPointEx (hwnd, client_pt, cwp_flags);
/* Verify that we're really inside the client area of the window */
if (hwndc != hwnd)
@ -2789,6 +2792,8 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display,
hwndc = hwnd;
}
/* Only ignore top-level transparent windows */
cwp_flags &= ~CWP_SKIPTRANSPARENT;
} while (hwndc != hwnd && (hwnd = hwndc, 1));
}

View file

@ -73,7 +73,7 @@ struct _GdkScreenX11
GdkVisualPrivate *system_visual;
GdkVisualPrivate **visuals;
gint nvisuals;
gint available_depths[7];
gint available_depths[8];
gint navailable_depths;
GdkVisualType available_types[6];
gint navailable_types;

View file

@ -2,6 +2,9 @@
include $(top_srcdir)/Makefile.decl
-include $(INTROSPECTION_MAKEFILE)
INTROSPECTION_GIRS =
if OS_WIN32
INTROSPECTION_SCANNER_ENV = PATH="$(builddir):$(builddir)/.libs:$${PATH}"
endif
INTROSPECTION_SCANNER_ARGS = \
--warn-all \
--add-include-path=../gdk
@ -1139,7 +1142,7 @@ $(GTK_UPDATE_ICON_CACHE_MANIFEST):
echo '</assembly>' ) >$@
$(GTK_UPDATE_ICON_CACHE_RC):
(echo -e '#include <winbase.h>\nCREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST '$(GTK_UPDATE_ICON_CACHE_MANIFEST)) >$@
(echo -e '#include <winbase.h>\nCREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "'$(GTK_UPDATE_ICON_CACHE_MANIFEST)'"') >$@
$(GTK_UPDATE_ICON_CACHE_MANIFEST_OBJECT): $(GTK_UPDATE_ICON_CACHE_RC) $(GTK_UPDATE_ICON_CACHE_MANIFEST)
$(WINDRES) --input $< --output $@ --output-format=coff

View file

@ -40,6 +40,9 @@
#include "gtktoolbar.h"
#include <gobject/gobjectnotifyqueue.c>
#include <gobject/gvaluecollector.h>
#ifdef GDK_WINDOWING_QUARTZ
#include "gdk/quartz/gdkquartz.h"
#endif
#include "gtkalias.h"
@ -1357,7 +1360,16 @@ gtk_container_idle_sizer (gpointer data)
gtk_container_check_resize (GTK_CONTAINER (widget));
}
#ifdef GDK_WINDOWING_QUARTZ
/* macOS 11 and newer can trigger expensive full-window redraws here.
* Keep the traditional update processing path for older Quartz targets,
* but let the normal GDK update idle handle updates on Big Sur and newer.
*/
if (gdk_quartz_osx_version () < GDK_OSX_BIG_SUR)
gdk_window_process_all_updates ();
#else
gdk_window_process_all_updates ();
#endif
return FALSE;
}

View file

@ -410,7 +410,8 @@ static void load_remove_timer (GtkFileChooserDefault *impl, LoadState new_load_s
static void browse_files_center_selected_row (GtkFileChooserDefault *impl);
static void view_mode_set (GtkFileChooserDefault *impl, ViewMode view_mode);
static void view_mode_combo_box_changed_cb (GtkComboBox *combo,
static void icon_view_scale_create (GtkFileChooserDefault *impl);
static void view_mode_toggle_button_toggled_cb (GtkToggleButton *toggle,
GtkFileChooserDefault *impl);
static void icon_view_scale_value_changed_cb (GtkRange *range,
@ -5208,12 +5209,22 @@ view_mode_set (GtkFileChooserDefault *impl, ViewMode view_mode)
return;
impl->view_mode = view_mode;
gtk_combo_box_set_active (GTK_COMBO_BOX (impl->view_mode_combo_box),
view_mode);
gtk_toggle_button_set_active (
GTK_TOGGLE_BUTTON (impl->view_mode_toggle_button),
view_mode == VIEW_MODE_ICON);
/* Creating the target view */
if (view_mode == VIEW_MODE_ICON)
{
if (!impl->icon_view_scale_hbox)
{
icon_view_scale_create (impl);
gtk_box_pack_end (
GTK_BOX (impl->browse_path_bar_hbox),
impl->icon_view_scale_hbox,
FALSE, FALSE, 0);
}
create_browse_files_icon_view (impl);
impl->browse_files_current_view = impl->browse_files_icon_view;
old_view = impl->browse_files_tree_view;
@ -5246,7 +5257,8 @@ view_mode_set (GtkFileChooserDefault *impl, ViewMode view_mode)
impl->browse_files_icon_view = NULL;
impl->list_icon_renderer = NULL;
impl->list_name_renderer = NULL;
gtk_widget_hide (impl->icon_view_scale_hbox);
if (impl->icon_view_scale_hbox)
gtk_widget_hide (impl->icon_view_scale_hbox);
}
else
g_assert_not_reached ();
@ -5264,12 +5276,14 @@ view_mode_set (GtkFileChooserDefault *impl, ViewMode view_mode)
browse_files_center_selected_row (impl);
}
/* Callback used when view mode combo box active item is changed */
/* Callback used when the view mode toggle button is toggled. */
static void
view_mode_combo_box_changed_cb (GtkComboBox *combo,
view_mode_toggle_button_toggled_cb (GtkToggleButton *toggle,
GtkFileChooserDefault *impl)
{
ViewMode target = gtk_combo_box_get_active (combo);
ViewMode target = gtk_toggle_button_get_active (toggle)
? VIEW_MODE_ICON
: VIEW_MODE_LIST;
view_mode_set (impl, target);
}
@ -5698,20 +5712,15 @@ location_button_toggled_cb (GtkToggleButton *toggle,
location_mode_set (impl, new_mode, FALSE);
}
/* Creates a combo box with two items: List View and Icon View. */
/* Creates the view mode toggle. */
static void
view_mode_combo_box_create (GtkFileChooserDefault *impl)
view_mode_toggle_button_create (GtkFileChooserDefault *impl)
{
impl->view_mode_combo_box = gtk_combo_box_text_new ();
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(impl->view_mode_combo_box),
_("List View")); /* VIEW_MODE_LIST */
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(impl->view_mode_combo_box),
_("Icon View")); /* VIEW_MODE_ICON */
gtk_combo_box_set_active (GTK_COMBO_BOX(impl->view_mode_combo_box),
VIEW_MODE_LIST);
impl->view_mode_toggle_button =
gtk_toggle_button_new_with_label (_("Icon View"));
g_signal_connect (impl->view_mode_combo_box, "changed",
G_CALLBACK (view_mode_combo_box_changed_cb), impl);
g_signal_connect (impl->view_mode_toggle_button, "toggled",
G_CALLBACK (view_mode_toggle_button_toggled_cb), impl);
}
/* Creates a hscale for the icon view. */
@ -5719,46 +5728,48 @@ static void
icon_view_scale_create (GtkFileChooserDefault *impl)
{
GtkObject *adj;
GtkWidget *zoom_icon;
GtkWidget *image;
impl->icon_view_scale_hbox = gtk_hbox_new (FALSE, 12);
impl->icon_view_scale_zoom_out_icon = gtk_event_box_new ();
gtk_event_box_set_visible_window (GTK_EVENT_BOX (impl->icon_view_scale_zoom_out_icon), FALSE);
zoom_icon = gtk_event_box_new ();
gtk_event_box_set_visible_window (GTK_EVENT_BOX (zoom_icon), FALSE);
image = gtk_image_new_from_stock (GTK_STOCK_ZOOM_OUT, GTK_ICON_SIZE_BUTTON);
gtk_container_add (GTK_CONTAINER (impl->icon_view_scale_zoom_out_icon), image);
gtk_container_add (GTK_CONTAINER (zoom_icon), image);
gtk_widget_show (image);
g_object_set_data (G_OBJECT (impl->icon_view_scale_zoom_out_icon),
g_object_set_data (G_OBJECT (zoom_icon),
"gtk-file-chooser-zoom-direction",
GINT_TO_POINTER (-1));
gtk_widget_set_tooltip_text (impl->icon_view_scale_zoom_out_icon, _("Zoom out"));
g_signal_connect (impl->icon_view_scale_zoom_out_icon, "button-press-event",
gtk_widget_set_tooltip_text (zoom_icon, _("Zoom out"));
g_signal_connect (zoom_icon, "button-press-event",
G_CALLBACK (icon_view_zoom_button_press_cb), impl);
gtk_size_group_add_widget (impl->browse_path_bar_size_group, impl->icon_view_scale_zoom_out_icon);
gtk_box_pack_start (GTK_BOX (impl->icon_view_scale_hbox), impl->icon_view_scale_zoom_out_icon, FALSE, FALSE, 0);
gtk_widget_show (impl->icon_view_scale_zoom_out_icon);
gtk_size_group_add_widget (impl->browse_path_bar_size_group, zoom_icon);
gtk_box_pack_start (GTK_BOX (impl->icon_view_scale_hbox), zoom_icon, FALSE, FALSE, 0);
gtk_widget_show (zoom_icon);
adj = gtk_adjustment_new (32, 32, 256, 16, 16, 0);
adj = gtk_adjustment_new (impl->icon_view_icon_size,
32, 256, 16, 16, 0);
impl->icon_view_scale = gtk_hscale_new (GTK_ADJUSTMENT (adj));
gtk_scale_set_draw_value (GTK_SCALE (impl->icon_view_scale), FALSE);
gtk_widget_set_size_request (impl->icon_view_scale, 100, -1);
gtk_box_pack_start (GTK_BOX (impl->icon_view_scale_hbox), impl->icon_view_scale, FALSE, FALSE, 0);
gtk_widget_show (impl->icon_view_scale);
impl->icon_view_scale_zoom_in_icon = gtk_event_box_new ();
gtk_event_box_set_visible_window (GTK_EVENT_BOX (impl->icon_view_scale_zoom_in_icon), FALSE);
zoom_icon = gtk_event_box_new ();
gtk_event_box_set_visible_window (GTK_EVENT_BOX (zoom_icon), FALSE);
image = gtk_image_new_from_stock (GTK_STOCK_ZOOM_IN, GTK_ICON_SIZE_BUTTON);
gtk_container_add (GTK_CONTAINER (impl->icon_view_scale_zoom_in_icon), image);
gtk_container_add (GTK_CONTAINER (zoom_icon), image);
gtk_widget_show (image);
g_object_set_data (G_OBJECT (impl->icon_view_scale_zoom_in_icon),
g_object_set_data (G_OBJECT (zoom_icon),
"gtk-file-chooser-zoom-direction",
GINT_TO_POINTER (1));
gtk_widget_set_tooltip_text (impl->icon_view_scale_zoom_in_icon, _("Zoom in"));
g_signal_connect (impl->icon_view_scale_zoom_in_icon, "button-press-event",
gtk_widget_set_tooltip_text (zoom_icon, _("Zoom in"));
g_signal_connect (zoom_icon, "button-press-event",
G_CALLBACK (icon_view_zoom_button_press_cb), impl);
gtk_size_group_add_widget (impl->browse_path_bar_size_group, impl->icon_view_scale_zoom_in_icon);
gtk_box_pack_start (GTK_BOX (impl->icon_view_scale_hbox), impl->icon_view_scale_zoom_in_icon, FALSE, FALSE, 0);
gtk_widget_show (impl->icon_view_scale_zoom_in_icon);
gtk_size_group_add_widget (impl->browse_path_bar_size_group, zoom_icon);
gtk_box_pack_start (GTK_BOX (impl->icon_view_scale_hbox), zoom_icon, FALSE, FALSE, 0);
gtk_widget_show (zoom_icon);
g_signal_connect (impl->icon_view_scale, "value-changed",
G_CALLBACK (icon_view_scale_value_changed_cb), impl);
@ -5883,9 +5894,9 @@ path_bar_widgets_create (GtkFileChooserDefault *impl)
impl->browse_path_bar_size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
gtk_size_group_set_ignore_hidden (impl->browse_path_bar_size_group, FALSE);
/* View mode combo box */
view_mode_combo_box_create (impl);
gtk_box_pack_start (GTK_BOX (impl->browse_path_bar_hbox), impl->view_mode_combo_box, FALSE, FALSE, 0);
/* View mode selector */
view_mode_toggle_button_create (impl);
gtk_box_pack_start (GTK_BOX (impl->browse_path_bar_hbox), impl->view_mode_toggle_button, FALSE, FALSE, 0);
/* Location button */
location_button_create (impl);
@ -5908,10 +5919,6 @@ path_bar_widgets_create (GtkFileChooserDefault *impl)
/* Widgets for special modes (recently-used in Open mode, Search mode) */
special_mode_widgets_create (impl);
/* Icon view scale */
icon_view_scale_create (impl);
gtk_box_pack_end (GTK_BOX (impl->browse_path_bar_hbox), impl->icon_view_scale_hbox, FALSE, FALSE, 0);
/* Create Folder */
impl->browse_new_folder_button = gtk_button_new_with_mnemonic (_("Create Fo_lder"));
g_signal_connect (impl->browse_new_folder_button, "clicked",
@ -6477,9 +6484,9 @@ update_appearance (GtkFileChooserDefault *impl)
if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
gtk_widget_show (impl->view_mode_combo_box);
gtk_widget_show (impl->view_mode_toggle_button);
else
gtk_widget_hide (impl->view_mode_combo_box);
gtk_widget_hide (impl->view_mode_toggle_button);
if (impl->location_entry)
_gtk_file_chooser_entry_set_action (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->action);
@ -7043,13 +7050,16 @@ settings_load (GtkFileChooserDefault *impl)
location_mode_set (impl, location_mode, TRUE);
g_signal_handlers_block_by_func (impl->icon_view_scale,
G_CALLBACK (icon_view_scale_value_changed_cb),
impl);
gtk_range_set_value (GTK_RANGE (impl->icon_view_scale), icon_view_scale);
g_signal_handlers_unblock_by_func (impl->icon_view_scale,
G_CALLBACK (icon_view_scale_value_changed_cb),
impl);
if (impl->icon_view_scale)
{
g_signal_handlers_block_by_func (impl->icon_view_scale,
G_CALLBACK (icon_view_scale_value_changed_cb),
impl);
gtk_range_set_value (GTK_RANGE (impl->icon_view_scale), icon_view_scale);
g_signal_handlers_unblock_by_func (impl->icon_view_scale,
G_CALLBACK (icon_view_scale_value_changed_cb),
impl);
}
view_mode_set (impl, view_mode);

View file

@ -227,11 +227,9 @@ struct _GtkFileChooserDefault
GtkWidget *extra_align;
GtkWidget *extra_widget;
GtkWidget *view_mode_combo_box;
GtkWidget *view_mode_toggle_button;
GtkWidget *icon_view_scale_hbox;
GtkWidget *icon_view_scale;
GtkWidget *icon_view_scale_zoom_in_icon;
GtkWidget *icon_view_scale_zoom_out_icon;
guint icon_view_scale_timeout_id;
guint icon_view_scale_visible_timeout_id;
guint icon_view_scale_after_layout_id;

View file

@ -889,7 +889,8 @@ gtk_font_button_update_font_info (GtkFontButton *font_button)
if (style == NULL || !g_ascii_strcasecmp (style, "Regular"))
family_style = g_strdup (family);
else
family_style = g_strdup_printf ("%s %s", family, style);
family_style = g_strdup_printf ("%s %s", family,
_gtk_font_style_name_translate (style));
gtk_label_set_text (GTK_LABEL (font_button->priv->font_label), family_style);

View file

@ -76,6 +76,91 @@
#define DEFAULT_FONT_NAME "Sans 10"
#ifdef ENABLE_NLS
/* Pango uses these standard English names for common font faces.
* Keep the msgids explicit for gettext, but only translate exact matches:
* font-specific face names must remain untouched.
*/
#define FONT_STYLE_ULTRA_LIGHT N_("Ultra-Light")
#define FONT_STYLE_LIGHT N_("Light")
#define FONT_STYLE_MEDIUM N_("Medium")
#define FONT_STYLE_NORMAL N_("Normal")
#define FONT_STYLE_REGULAR N_("Regular")
#define FONT_STYLE_ITALIC N_("Italic")
#define FONT_STYLE_OBLIQUE N_("Oblique")
#define FONT_STYLE_SEMI_BOLD N_("Semi-Bold")
#define FONT_STYLE_BOLD N_("Bold")
#define FONT_STYLE_ULTRA_BOLD N_("Ultra-Bold")
#define FONT_STYLE_HEAVY N_("Heavy")
#define FONT_STYLE_BOLD_ITALIC N_("Bold Italic")
const gchar *
_gtk_font_style_name_translate (const gchar *name)
{
switch (name[0])
{
case 'B':
if (strcmp (name, FONT_STYLE_BOLD) == 0)
return _(FONT_STYLE_BOLD);
if (strcmp (name, FONT_STYLE_BOLD_ITALIC) == 0)
return _(FONT_STYLE_BOLD_ITALIC);
break;
case 'H':
if (strcmp (name, FONT_STYLE_HEAVY) == 0)
return _(FONT_STYLE_HEAVY);
break;
case 'I':
if (strcmp (name, FONT_STYLE_ITALIC) == 0)
return _(FONT_STYLE_ITALIC);
break;
case 'L':
if (strcmp (name, FONT_STYLE_LIGHT) == 0)
return _(FONT_STYLE_LIGHT);
break;
case 'M':
if (strcmp (name, FONT_STYLE_MEDIUM) == 0)
return _(FONT_STYLE_MEDIUM);
break;
case 'N':
if (strcmp (name, FONT_STYLE_NORMAL) == 0)
return _(FONT_STYLE_NORMAL);
break;
case 'O':
if (strcmp (name, FONT_STYLE_OBLIQUE) == 0)
return _(FONT_STYLE_OBLIQUE);
break;
case 'R':
if (strcmp (name, FONT_STYLE_REGULAR) == 0)
return _(FONT_STYLE_REGULAR);
break;
case 'S':
if (strcmp (name, FONT_STYLE_SEMI_BOLD) == 0)
return _(FONT_STYLE_SEMI_BOLD);
break;
case 'U':
if (strcmp (name, FONT_STYLE_ULTRA_LIGHT) == 0)
return _(FONT_STYLE_ULTRA_LIGHT);
if (strcmp (name, FONT_STYLE_ULTRA_BOLD) == 0)
return _(FONT_STYLE_ULTRA_BOLD);
break;
default:
break;
}
return name;
}
#endif /* ENABLE_NLS */
/* This is the initial and maximum height of the preview entry (it expands
when large font sizes are selected). Initial height is also the minimum. */
#define INITIAL_PREVIEW_HEIGHT 44
@ -734,13 +819,22 @@ gtk_font_selection_select_font (GtkTreeSelection *selection,
}
}
static int
cmp_families (const void *a, const void *b)
typedef struct
{
const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
PangoFontFamily *family;
const gchar *name;
gchar *collate_key;
} FontFamilySortInfo;
return g_utf8_collate (a_name, b_name);
static int
cmp_families (const void *a,
const void *b)
{
const FontFamilySortInfo *family_a = a;
const FontFamilySortInfo *family_b = b;
return strcmp (family_a->collate_key,
family_b->collate_key);
}
static void
@ -748,6 +842,7 @@ gtk_font_selection_show_available_fonts (GtkFontSelection *fontsel)
{
GtkListStore *model;
PangoFontFamily **families;
FontFamilySortInfo *sorted_families;
PangoFontFamily *match_family = NULL;
gint n_families, i;
GtkTreeIter match_row;
@ -755,27 +850,37 @@ gtk_font_selection_show_available_fonts (GtkFontSelection *fontsel)
model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fontsel->family_list)));
pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
&families, &n_families);
qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
&families, &n_families);
sorted_families = g_new (FontFamilySortInfo, n_families);
for (i = 0; i < n_families; i++)
{
const gchar *name = pango_font_family_get_name (families[i]);
sorted_families[i].family = families[i];
sorted_families[i].name = name;
sorted_families[i].collate_key = g_utf8_collate_key (name ? name : "", -1);
}
qsort (sorted_families, n_families, sizeof (FontFamilySortInfo), cmp_families);
gtk_list_store_clear (model);
for (i=0; i<n_families; i++)
for (i = 0; i < n_families; i++)
{
const gchar *name = pango_font_family_get_name (families[i]);
const gchar *name = sorted_families[i].name;
GtkTreeIter iter;
gtk_list_store_append (model, &iter);
gtk_list_store_set (model, &iter,
FAMILY_COLUMN, families[i],
FAMILY_NAME_COLUMN, name,
-1);
gtk_list_store_insert_with_values (model, &iter, -1,
FAMILY_COLUMN, sorted_families[i].family,
FAMILY_NAME_COLUMN, name,
-1);
if (i == 0 || !g_ascii_strcasecmp (name, "sans"))
{
match_family = families[i];
match_row = iter;
}
{
match_family = sorted_families[i].family;
match_row = iter;
}
}
gtk_font_selection_ref_family (fontsel, match_family);
@ -784,10 +889,14 @@ gtk_font_selection_show_available_fonts (GtkFontSelection *fontsel)
set_cursor_to_iter (GTK_TREE_VIEW (fontsel->family_list), &match_row);
#ifdef INCLUDE_FONT_ENTRIES
gtk_entry_set_text (GTK_ENTRY (fontsel->font_entry),
pango_font_family_get_name (match_family));
pango_font_family_get_name (match_family));
#endif /* INCLUDE_FONT_ENTRIES */
}
for (i = 0; i < n_families; i++)
g_free (sorted_families[i].collate_key);
g_free (sorted_families);
g_free (families);
}
@ -813,18 +922,22 @@ compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescrip
return 0;
}
static int
faces_sort_func (const void *a, const void *b)
typedef struct
{
PangoFontDescription *desc_a = pango_font_face_describe (*(PangoFontFace **)a);
PangoFontDescription *desc_b = pango_font_face_describe (*(PangoFontFace **)b);
PangoFontFace *face;
PangoFontDescription *desc;
const gchar *name;
} FontFaceSortInfo;
int ord = compare_font_descriptions (desc_a, desc_b);
static int
faces_sort_func (const void *a,
const void *b)
{
const FontFaceSortInfo *face_a = a;
const FontFaceSortInfo *face_b = b;
pango_font_description_free (desc_a);
pango_font_description_free (desc_b);
return ord;
return compare_font_descriptions (face_a->desc,
face_b->desc);
}
static gboolean
@ -844,6 +957,7 @@ gtk_font_selection_show_available_styles (GtkFontSelection *fontsel)
{
gint n_faces, i;
PangoFontFace **faces;
FontFaceSortInfo *sorted_faces;
PangoFontDescription *old_desc;
GtkListStore *model;
GtkTreeIter match_row;
@ -857,38 +971,40 @@ gtk_font_selection_show_available_styles (GtkFontSelection *fontsel)
old_desc= NULL;
pango_font_family_list_faces (fontsel->family, &faces, &n_faces);
qsort (faces, n_faces, sizeof (PangoFontFace *), faces_sort_func);
sorted_faces = g_new (FontFaceSortInfo, n_faces);
for (i = 0; i < n_faces; i++)
{
sorted_faces[i].face = faces[i];
sorted_faces[i].desc = pango_font_face_describe (faces[i]);
sorted_faces[i].name = pango_font_face_get_face_name (faces[i]);
}
qsort (sorted_faces, n_faces, sizeof (FontFaceSortInfo), faces_sort_func);
gtk_list_store_clear (model);
for (i=0; i < n_faces; i++)
for (i = 0; i < n_faces; i++)
{
GtkTreeIter iter;
const gchar *str = pango_font_face_get_face_name (faces[i]);
const gchar *str = sorted_faces[i].name;
gtk_list_store_append (model, &iter);
gtk_list_store_set (model, &iter,
FACE_COLUMN, faces[i],
FACE_NAME_COLUMN, str,
-1);
gtk_list_store_insert_with_values (model, &iter, -1,
FACE_COLUMN, sorted_faces[i].face,
FACE_NAME_COLUMN, _gtk_font_style_name_translate (str),
-1);
if (i == 0)
{
match_row = iter;
match_face = faces[i];
}
else if (old_desc)
{
PangoFontDescription *tmp_desc = pango_font_face_describe (faces[i]);
if (font_description_style_equal (tmp_desc, old_desc))
{
match_row = iter;
match_face = faces[i];
}
pango_font_description_free (tmp_desc);
}
{
match_row = iter;
match_face = sorted_faces[i].face;
}
else if (old_desc &&
font_description_style_equal (sorted_faces[i].desc, old_desc))
{
match_row = iter;
match_face = sorted_faces[i].face;
}
}
if (old_desc)
@ -905,6 +1021,10 @@ gtk_font_selection_show_available_styles (GtkFontSelection *fontsel)
set_cursor_to_iter (GTK_TREE_VIEW (fontsel->face_list), &match_row);
}
for (i = 0; i < n_faces; i++)
pango_font_description_free (sorted_faces[i].desc);
g_free (sorted_faces);
g_free (faces);
}
@ -975,8 +1095,9 @@ gtk_font_selection_show_available_sizes (GtkFontSelection *fontsel,
{
GtkTreeIter iter;
gtk_list_store_append (model, &iter);
gtk_list_store_set (model, &iter, SIZE_COLUMN, font_sizes[i], -1);
gtk_list_store_insert_with_values (model, &iter, -1,
SIZE_COLUMN, font_sizes[i],
-1);
if (font_sizes[i] * PANGO_SCALE == fontsel->size)
set_cursor_to_iter (GTK_TREE_VIEW (fontsel->size_list), &iter);

View file

@ -2945,6 +2945,10 @@ icon_info_ensure_scale_and_pixbuf (GtkIconInfo *icon_info,
if (mime_type && strcmp (mime_type, "image/svg+xml") == 0)
is_svg = TRUE;
#ifdef G_OS_WIN32
else if (content_type && strcmp (content_type, ".svg") == 0)
is_svg = TRUE;
#endif
}
g_object_unref (file_info);

View file

@ -309,11 +309,186 @@ add_builtin_module (const gchar *module_name,
return module;
}
/*
* Keep IM module parsing independent of Pango's deprecated helpers.
*/
/*
* Use unlocked input for the privately owned module-cache stream.
*/
#if defined(HAVE_GETC_UNLOCKED)
#define GTK_IM_MODULE_GETC(stream) getc_unlocked (stream)
#elif defined(HAVE__GETC_NOLOCK)
#define GTK_IM_MODULE_GETC(stream) _getc_nolock (stream)
#else
#define GTK_IM_MODULE_GETC(stream) getc (stream)
#endif
static gchar *
gtk_im_module_scan_string (const gchar **pos)
{
const gchar *p;
const gchar *q;
gchar *result;
gchar *out;
gsize len;
p = *pos;
while (g_ascii_isspace (*p))
p++;
if (*p != '"')
return NULL;
p++;
q = p;
len = 0;
while (*q && *q != '"')
{
if (*q == '\\')
{
q++;
if (!*q)
return NULL;
}
q++;
len++;
}
if (*q != '"')
return NULL;
result = g_malloc (len + 1);
out = result;
while (p < q)
{
gchar c;
c = *p++;
if (c == '\\')
{
c = *p++;
switch (c)
{
case 'b': c = '\b'; break;
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'v': c = '\v'; break;
default: break;
}
}
*out++ = c;
}
*out = '\0';
*pos = q + 1;
return result;
}
static gboolean
gtk_im_module_skip_space (const gchar **pos)
{
while (g_ascii_isspace (**pos))
(*pos)++;
return **pos != '\0';
}
static gint
gtk_im_module_read_line (FILE *stream,
GString *str)
{
gboolean escaped;
gboolean comment;
gint n_read;
gint lines;
gint c;
gint next_c;
escaped = FALSE;
comment = FALSE;
n_read = 0;
lines = 1;
g_string_truncate (str, 0);
while (TRUE)
{
c = GTK_IM_MODULE_GETC (stream);
if (c == EOF)
{
if (escaped)
g_string_append_c (str, '\\');
break;
}
n_read++;
if (c == '\r' || c == '\n')
{
next_c = GTK_IM_MODULE_GETC (stream);
if (next_c != EOF &&
!((c == '\r' && next_c == '\n') ||
(c == '\n' && next_c == '\r')))
ungetc (next_c, stream);
if (escaped)
{
escaped = FALSE;
lines++;
continue;
}
break;
}
if (escaped)
{
escaped = FALSE;
if (c == '#')
g_string_append_c (str, '#');
else
{
g_string_append_c (str, '\\');
g_string_append_c (str, c);
}
}
else if (!comment)
{
if (c == '#')
comment = TRUE;
else if (c == '\\')
escaped = TRUE;
else
g_string_append_c (str, c);
}
}
return n_read > 0 ? lines : 0;
}
#undef GTK_IM_MODULE_GETC
static void
gtk_im_module_initialize (void)
{
GString *line_buf = g_string_new (NULL);
GString *tmp_buf = g_string_new (NULL);
gchar *filename = gtk_rc_get_im_module_file();
FILE *file;
gboolean have_error = FALSE;
@ -387,18 +562,17 @@ gtk_im_module_initialize (void)
* we allow no file at all.
*/
g_string_free (line_buf, TRUE);
g_string_free (tmp_buf, TRUE);
g_free (filename);
return;
}
while (!have_error && pango_read_line (file, line_buf))
while (!have_error && gtk_im_module_read_line (file, line_buf))
{
const char *p;
p = line_buf->str;
if (!pango_skip_space (&p))
if (!gtk_im_module_skip_space (&p))
{
/* Blank line marking the end of a module
*/
@ -413,61 +587,62 @@ gtk_im_module_initialize (void)
}
if (!module)
{
/* Read a module location
*/
module = g_object_new (GTK_TYPE_IM_MODULE, NULL);
{
/* Read a module location
*/
module = g_object_new (GTK_TYPE_IM_MODULE, NULL);
module->path = gtk_im_module_scan_string (&p);
if (!pango_scan_string (&p, tmp_buf) ||
pango_skip_space (&p))
{
g_warning ("Error parsing context info in '%s'\n %s",
filename, line_buf->str);
have_error = TRUE;
}
if (!module->path || gtk_im_module_skip_space (&p))
{
g_warning ("Error parsing context info in '%s'\n %s",
filename, line_buf->str);
have_error = TRUE;
continue;
}
module->path = g_strdup (tmp_buf->str);
#ifdef G_OS_WIN32
correct_libdir_prefix (&module->path);
correct_libdir_prefix (&module->path);
#endif
g_type_module_set_name (G_TYPE_MODULE (module), module->path);
}
g_type_module_set_name (G_TYPE_MODULE (module), module->path);
}
else
{
GtkIMContextInfo *info = g_new0 (GtkIMContextInfo, 1);
/* Read information about a context type
*/
if (!pango_scan_string (&p, tmp_buf))
goto context_error;
info->context_id = g_strdup (tmp_buf->str);
info->context_id = gtk_im_module_scan_string (&p);
if (!info->context_id)
goto context_error;
if (!pango_scan_string (&p, tmp_buf))
goto context_error;
info->context_name = g_strdup (tmp_buf->str);
info->context_name = gtk_im_module_scan_string (&p);
if (!info->context_name)
goto context_error;
if (!pango_scan_string (&p, tmp_buf))
goto context_error;
info->domain = g_strdup (tmp_buf->str);
info->domain = gtk_im_module_scan_string (&p);
if (!info->domain)
goto context_error;
if (!pango_scan_string (&p, tmp_buf))
goto context_error;
info->domain_dirname = g_strdup (tmp_buf->str);
info->domain_dirname = gtk_im_module_scan_string (&p);
if (!info->domain_dirname)
goto context_error;
#ifdef G_OS_WIN32
correct_localedir_prefix ((char **) &info->domain_dirname);
#endif
if (!pango_scan_string (&p, tmp_buf))
goto context_error;
info->default_locales = g_strdup (tmp_buf->str);
info->default_locales = gtk_im_module_scan_string (&p);
if (!info->default_locales)
goto context_error;
if (pango_skip_space (&p))
if (gtk_im_module_skip_space (&p))
goto context_error;
infos = g_slist_prepend (infos, info);
continue;
context_error:
free_info (info);
g_warning ("Error parsing context info in '%s'\n %s",
filename, line_buf->str);
have_error = TRUE;
@ -491,7 +666,6 @@ gtk_im_module_initialize (void)
fclose (file);
g_string_free (line_buf, TRUE);
g_string_free (tmp_buf, TRUE);
g_free (filename);
}

View file

@ -192,7 +192,7 @@ _gtk_get_module_path (const gchar *type)
result = g_new (gchar *, count * 5 + 1);
count = 0;
for (path = get_module_path (); *path; path++)
for (path = paths; *path; path++)
{
gint use_version, use_host;

View file

@ -48,8 +48,22 @@ struct _GtkPrintBackendPrivate
GtkPrintBackendStatus status;
char **auth_info_required;
char **auth_info;
#ifdef HAVE_CUPS_SECRET_SERVICE
guint store_auth_info : 1;
#endif
};
#ifdef HAVE_CUPS_SECRET_SERVICE
typedef gboolean (*GtkPrintBackendCanStoreAuthInfoFunc)
(GtkPrintBackend *backend);
typedef void (*GtkPrintBackendSetPasswordFullFunc)
(GtkPrintBackend *backend,
gchar **auth_info_required,
gchar **auth_info,
gboolean store_auth_info);
#endif
enum {
PRINTER_LIST_CHANGED,
PRINTER_LIST_DONE,
@ -459,6 +473,9 @@ gtk_print_backend_init (GtkPrintBackend *backend)
(GDestroyNotify) g_object_unref);
priv->auth_info_required = NULL;
priv->auth_info = NULL;
#ifdef HAVE_CUPS_SECRET_SERVICE
priv->store_auth_info = FALSE;
#endif
}
static void
@ -675,6 +692,41 @@ gtk_print_backend_set_password (GtkPrintBackend *backend,
GTK_PRINT_BACKEND_GET_CLASS (backend)->set_password (backend, auth_info_required, auth_info);
}
#ifdef HAVE_CUPS_SECRET_SERVICE
static void
gtk_print_backend_set_password_full (GtkPrintBackend *backend,
gchar **auth_info_required,
gchar **auth_info,
gboolean store_auth_info)
{
GtkPrintBackendClass *class;
class = GTK_PRINT_BACKEND_GET_CLASS (backend);
if (class->_gtk_reserved2 != NULL)
((GtkPrintBackendSetPasswordFullFunc) class->_gtk_reserved2)
(backend,
auth_info_required,
auth_info,
store_auth_info);
else
gtk_print_backend_set_password (backend,
auth_info_required,
auth_info);
}
static void
store_auth_info_toggled (GtkToggleButton *button,
GtkPrintBackend *backend)
{
backend->priv->store_auth_info =
gtk_toggle_button_get_active (button);
}
#endif
static void
store_entry (GtkEntry *entry,
gpointer user_data)
@ -698,10 +750,23 @@ password_dialog_response (GtkWidget *dialog,
GtkPrintBackendPrivate *priv = backend->priv;
gint i;
#ifdef HAVE_CUPS_SECRET_SERVICE
if (response_id == GTK_RESPONSE_OK)
gtk_print_backend_set_password_full (backend,
priv->auth_info_required,
priv->auth_info,
priv->store_auth_info);
else
gtk_print_backend_set_password_full (backend,
priv->auth_info_required,
NULL,
FALSE);
#else
if (response_id == GTK_RESPONSE_OK)
gtk_print_backend_set_password (backend, priv->auth_info_required, priv->auth_info);
else
gtk_print_backend_set_password (backend, priv->auth_info_required, NULL);
#endif
for (i = 0; i < g_strv_length (priv->auth_info_required); i++)
if (priv->auth_info[i] != NULL)
@ -738,10 +803,23 @@ request_password (GtkPrintBackend *backend,
gchar **ai_default = (gchar **) auth_info_default;
gchar **ai_display = (gchar **) auth_info_display;
gboolean *ai_visible = (gboolean *) auth_info_visible;
#ifdef HAVE_CUPS_SECRET_SERVICE
GtkPrintBackendClass *class;
gboolean can_store_auth_info = FALSE;
#endif
priv->auth_info_required = g_strdupv (ai_required);
length = g_strv_length (ai_required);
priv->auth_info = g_new0 (gchar *, length + 1);
#ifdef HAVE_CUPS_SECRET_SERVICE
priv->store_auth_info = FALSE;
class = GTK_PRINT_BACKEND_GET_CLASS (backend);
if (class->_gtk_reserved1 != NULL)
can_store_auth_info =
((GtkPrintBackendCanStoreAuthInfoFunc) class->_gtk_reserved1)
(backend);
#endif
dialog = gtk_dialog_new_with_buttons ( _("Authentication"), NULL, GTK_DIALOG_MODAL,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
@ -810,6 +888,18 @@ request_password (GtkPrintBackend *backend,
}
}
#ifdef HAVE_CUPS_SECRET_SERVICE
if (can_store_auth_info)
{
GtkWidget *remember;
remember = gtk_check_button_new_with_mnemonic (_("_Remember password"));
gtk_box_pack_start (GTK_BOX (vbox), remember, FALSE, FALSE, 6);
g_signal_connect (remember, "toggled",
G_CALLBACK (store_auth_info_toggled), backend);
}
#endif
if (focus != NULL)
{
gtk_widget_grab_focus (focus);

View file

@ -796,7 +796,9 @@ printer_status_cb (GtkPrintBackend *backend,
/* When the pause state change then we need to update sensitive property
* of GTK_RESPONSE_OK button inside of selected_printer_changed function. */
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->printer_treeview));
priv->internal_printer_change = TRUE;
selected_printer_changed (selection, dialog);
priv->internal_printer_change = FALSE;
if (gtk_print_backend_printer_list_is_done (backend) &&
gtk_printer_is_default (printer) &&

View file

@ -134,6 +134,13 @@ const gchar *_gtk_get_data_prefix ();
#endif /* G_OS_WIN32 */
#ifdef ENABLE_NLS
G_GNUC_INTERNAL
const gchar *_gtk_font_style_name_translate (const gchar *name);
#else
#define _gtk_font_style_name_translate(name) (name)
#endif
gboolean _gtk_fnmatch (const char *pattern,
const char *string,
gboolean no_leading_period);

View file

@ -67,7 +67,10 @@ _gtk_quartz_create_image_from_pixbuf (GdkPixbuf *pixbuf)
}
[nsimage lockFocus];
context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
if (gdk_quartz_osx_version () < GDK_OSX_YOSEMITE)
context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
else
context = [[NSGraphicsContext currentContext] CGContext];
CGContextDrawImage (context, CGRectMake (0, 0, pixbuf_width, pixbuf_height), image);
[nsimage unlockFocus];

View file

@ -808,6 +808,8 @@ gtk_rc_parse_named (GtkRcContext *context,
gchar *path = NULL;
const gchar *home_dir;
gchar *subpath;
const gchar * const *xdg_data_dirs;
gint i;
if (type)
subpath = g_strconcat ("gtk-2.0-", type,
@ -829,6 +831,22 @@ gtk_rc_parse_named (GtkRcContext *context,
}
}
if (!path)
{
xdg_data_dirs = g_get_system_data_dirs ();
for (i = 0; xdg_data_dirs[i]; i++)
{
path = g_build_filename (xdg_data_dirs[i], "themes", name, subpath, NULL);
if (g_file_test (path, G_FILE_TEST_EXISTS))
break;
else
{
g_free (path);
path = NULL;
}
}
}
if (!path)
{
gchar *theme_dir = gtk_rc_get_theme_dir ();

View file

@ -74,7 +74,11 @@ struct _GtkTooltips
guint have_grab : 1;
guint use_sticky_delay : 1;
gint timer_tag;
GTimeVal last_popdown;
struct
{
glong tv_sec;
glong tv_usec;
} last_popdown;
};
struct _GtkTooltipsClass

View file

@ -46,12 +46,12 @@ struct _GtkTrayIconClass
{
GtkPlugClass parent_class;
void (*__gtk_reserved1);
void (*__gtk_reserved2);
void (*__gtk_reserved3);
void (*__gtk_reserved4);
void (*__gtk_reserved5);
void (*__gtk_reserved6);
void (*__gtk_reserved1) (void);
void (*__gtk_reserved2) (void);
void (*__gtk_reserved3) (void);
void (*__gtk_reserved4) (void);
void (*__gtk_reserved5) (void);
void (*__gtk_reserved6) (void);
};
GType gtk_tray_icon_get_type (void) G_GNUC_CONST;

View file

@ -14,7 +14,7 @@ print <<EOF;
#include <glib.h>
#ifdef G_HAVE_GNUC_VISIBILITY
#if defined(G_HAVE_GNUC_VISIBILITY) && !defined(__APPLE__)
EOF

View file

@ -159,9 +159,6 @@ query_module (const char *dir, const char *name, GString *contents)
{
void (*list) (const GtkIMContextInfo ***contexts,
guint *n_contexts);
G_GNUC_UNUSED void (*init) (GTypeModule *type_module);
G_GNUC_UNUSED void (*exit) (void);
G_GNUC_UNUSED GtkIMContext *(*create) (const gchar *context_id);
gpointer list_ptr;
gpointer init_ptr;
@ -196,9 +193,6 @@ query_module (const char *dir, const char *name, GString *contents)
int i;
list = list_ptr;
init = init_ptr;
exit = exit_ptr;
create = create_ptr;
print_escaped (contents, path);
g_string_append_c (contents, '\n');

View file

@ -132,7 +132,7 @@ static int object = 0;
static int object_after = 0;
void /* exported for GtkBuilder */
signal_normal (GtkWindow *window, GParamSpec spec)
signal_normal (GtkWindow *window, GParamSpec *spec)
{
g_assert (GTK_IS_WINDOW (window));
g_assert (normal == 0);
@ -142,7 +142,7 @@ signal_normal (GtkWindow *window, GParamSpec spec)
}
void /* exported for GtkBuilder */
signal_after (GtkWindow *window, GParamSpec spec)
signal_after (GtkWindow *window, GParamSpec *spec)
{
g_assert (GTK_IS_WINDOW (window));
g_assert (normal == 1);
@ -152,7 +152,7 @@ signal_after (GtkWindow *window, GParamSpec spec)
}
void /* exported for GtkBuilder */
signal_object (GtkButton *button, GParamSpec spec)
signal_object (GtkButton *button, GParamSpec *spec)
{
g_assert (GTK_IS_BUTTON (button));
g_assert (object == 0);
@ -162,7 +162,7 @@ signal_object (GtkButton *button, GParamSpec spec)
}
void /* exported for GtkBuilder */
signal_object_after (GtkButton *button, GParamSpec spec)
signal_object_after (GtkButton *button, GParamSpec *spec)
{
g_assert (GTK_IS_BUTTON (button));
g_assert (object == 1);
@ -172,28 +172,28 @@ signal_object_after (GtkButton *button, GParamSpec spec)
}
void /* exported for GtkBuilder */
signal_first (GtkButton *button, GParamSpec spec)
signal_first (GtkButton *button, GParamSpec *spec)
{
g_assert (normal == 0);
normal = 10;
}
void /* exported for GtkBuilder */
signal_second (GtkButton *button, GParamSpec spec)
signal_second (GtkButton *button, GParamSpec *spec)
{
g_assert (normal == 10);
normal = 20;
}
void /* exported for GtkBuilder */
signal_extra (GtkButton *button, GParamSpec spec)
signal_extra (GtkButton *button, GParamSpec *spec)
{
g_assert (normal == 20);
normal = 30;
}
void /* exported for GtkBuilder */
signal_extra2 (GtkButton *button, GParamSpec spec)
signal_extra2 (GtkButton *button, GParamSpec *spec)
{
g_assert (normal == 30);
normal = 40;

View file

@ -25,6 +25,15 @@
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef _MSC_VER
#ifndef S_ISDIR
#define S_ISDIR(mode) (((mode) & _S_IFMT) == _S_IFDIR)
#endif
#ifndef S_ISREG
#define S_ISREG(mode) (((mode) & _S_IFMT) == _S_IFREG)
#endif
#endif
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@ -608,6 +617,16 @@ replace_backslashes_with_slashes (gchar *path)
path[i] = '/';
}
static gint
compare_string_pointers (gconstpointer a,
gconstpointer b)
{
const gchar * const *str_a = a;
const gchar * const *str_b = b;
return strcmp (*str_a, *str_b);
}
static GList *
scan_directory (const gchar *base_path,
const gchar *subdir,
@ -617,10 +636,13 @@ scan_directory (const gchar *base_path,
{
GHashTable *dir_hash;
GDir *dir;
const gchar *name;
GPtrArray *names;
const gchar *entry_name;
gchar *name;
gchar *dir_path;
gboolean dir_added = FALSE;
guint dir_index = 0xffff;
guint i;
dir_path = g_build_path ("/", base_path, subdir, NULL);
@ -628,91 +650,103 @@ scan_directory (const gchar *base_path,
dir = g_dir_open (dir_path, 0, NULL);
if (!dir)
return directories;
{
g_free (dir_path);
return directories;
}
names = g_ptr_array_new_with_free_func (g_free);
while ((entry_name = g_dir_read_name (dir)))
g_ptr_array_add (names, g_strdup (entry_name));
g_dir_close (dir);
g_ptr_array_sort (names, compare_string_pointers);
dir_hash = g_hash_table_new (g_str_hash, g_str_equal);
while ((name = g_dir_read_name (dir)))
for (i = 0; i < names->len; i++)
{
GStatBuf stat_buf;
gchar *path;
gboolean retval;
int flags = 0;
Image *image;
gchar *basename, *dot;
name = g_ptr_array_index (names, i);
path = g_build_filename (dir_path, name, NULL);
retval = g_file_test (path, G_FILE_TEST_IS_DIR);
if (retval)
{
gchar *subsubdir;
if (g_stat (path, &stat_buf) == 0)
{
if (S_ISDIR (stat_buf.st_mode))
{
gchar *subsubdir;
if (subdir)
subsubdir = g_build_path ("/", subdir, name, NULL);
else
subsubdir = g_strdup (name);
directories = scan_directory (base_path, subsubdir, files,
directories, depth + 1);
g_free (subsubdir);
if (subdir)
subsubdir = g_build_path ("/", subdir, name, NULL);
else
subsubdir = g_strdup (name);
continue;
}
directories = scan_directory (base_path, subsubdir, files,
directories, depth + 1);
g_free (subsubdir);
}
else if (subdir != NULL && S_ISREG (stat_buf.st_mode))
{
gint flags = 0;
Image *image;
gchar *dot;
/* ignore images in the toplevel directory */
if (subdir == NULL)
continue;
dot = strrchr (name, '.');
retval = g_file_test (path, G_FILE_TEST_IS_REGULAR);
if (retval)
{
if (g_str_has_suffix (name, ".png"))
flags |= HAS_SUFFIX_PNG;
else if (g_str_has_suffix (name, ".svg"))
flags |= HAS_SUFFIX_SVG;
else if (g_str_has_suffix (name, ".xpm"))
flags |= HAS_SUFFIX_XPM;
else if (g_str_has_suffix (name, ".icon"))
flags |= HAS_ICON_FILE;
if (dot != NULL)
{
if (strcmp (dot, ".png") == 0)
flags = HAS_SUFFIX_PNG;
else if (strcmp (dot, ".svg") == 0)
flags = HAS_SUFFIX_SVG;
else if (strcmp (dot, ".xpm") == 0)
flags = HAS_SUFFIX_XPM;
else if (strcmp (dot, ".icon") == 0)
flags = HAS_ICON_FILE;
}
if (flags == 0)
continue;
if (flags != 0)
{
*dot = '\0';
basename = g_strdup (name);
dot = strrchr (basename, '.');
*dot = '\0';
image = g_hash_table_lookup (dir_hash, name);
if (!image)
{
if (!dir_added)
{
dir_added = TRUE;
dir_index = g_list_length (directories);
directories =
g_list_append (directories,
g_strdup (subdir));
}
image = g_hash_table_lookup (dir_hash, basename);
if (!image)
{
if (!dir_added)
{
dir_added = TRUE;
if (subdir)
{
dir_index = g_list_length (directories);
directories = g_list_append (directories, g_strdup (subdir));
}
else
continue;
}
image = g_new0 (Image, 1);
image->dir_index = dir_index;
g_hash_table_insert (dir_hash,
g_strdup (name),
image);
}
image = g_new0 (Image, 1);
image->dir_index = dir_index;
g_hash_table_insert (dir_hash, g_strdup (basename), image);
}
image->flags |= flags;
image->flags |= flags;
maybe_cache_image_data (image, path);
maybe_cache_icon_data (image, path);
maybe_cache_image_data (image, path);
maybe_cache_icon_data (image, path);
g_free (basename);
}
*dot = '.';
}
}
}
g_free (path);
}
g_dir_close (dir);
g_ptr_array_free (names, TRUE);
g_free (dir_path);
/* Move dir into the big file hash */
g_hash_table_foreach_remove (dir_hash, foreach_remove_func, files);
@ -1375,6 +1409,34 @@ write_dir_index (FILE *cache, int offset, GList *directories)
return TRUE;
}
static void
free_hash_context (HashContext *context)
{
gint i;
for (i = 0; i < context->size; i++)
{
HashNode *node = context->nodes[i];
while (node)
{
HashNode *next = node->next;
GList *l;
for (l = node->image_list; l; l = l->next)
g_free (l->data);
g_list_free (node->image_list);
g_free (node->name);
g_free (node);
node = next;
}
}
g_free (context->nodes);
}
static gboolean
write_file (FILE *cache, GHashTable *files, GList *directories)
{
@ -1418,6 +1480,11 @@ write_file (FILE *cache, GHashTable *files, GList *directories)
return FALSE;
}
g_hash_table_destroy (string_pool);
string_pool = NULL;
free_hash_context (&context);
return TRUE;
}
@ -1544,6 +1611,8 @@ opentmp:
exit (1);
}
g_hash_table_destroy (files);
if (!safe_fclose (cache))
{
g_printerr (_("Failed to write cache file: %s\n"), g_strerror (errno));
@ -1623,6 +1692,9 @@ opentmp:
if (!quiet)
g_printerr (_("Cache file created successfully.\n"));
g_free (tmp_cache_path);
g_free (cache_path);
}
static void
@ -1658,6 +1730,9 @@ write_csource (const gchar *path)
}
g_printf ("0x%02x\n};\n", (guint8)data[i]);
g_free (data);
g_free (cache_path);
}
static GOptionEntry args[] = {
@ -1721,6 +1796,7 @@ main (int argc, char **argv)
g_option_context_add_main_entries (context, args, GETTEXT_PACKAGE);
g_option_context_parse (context, &argc, &argv, NULL);
g_option_context_free (context);
path = argv[1];
#ifdef G_OS_WIN32

View file

@ -72,6 +72,7 @@ libgailincludedir=$(includedir)/gail-1.0/gail
gail_private_h_sources = \
gail.h \
gailvalue.h \
gailadjustment.h \
gailarrow.h \
gailbooleancell.h \

View file

@ -22,6 +22,7 @@
#include <string.h>
#include <gtk/gtk.h>
#include "gailadjustment.h"
#include "gailvalue.h"
static void gail_adjustment_class_init (GailAdjustmentClass *klass);
@ -32,16 +33,25 @@ static void gail_adjustment_real_initialize (AtkObject *obj,
static void atk_value_interface_init (AtkValueIface *iface);
static void gail_adjustment_get_current_value (AtkValue *obj,
GValue *value);
static void gail_adjustment_get_maximum_value (AtkValue *obj,
GValue *value);
static void gail_adjustment_get_minimum_value (AtkValue *obj,
GValue *value);
static void gail_adjustment_get_minimum_increment (AtkValue *obj,
GValue *value);
static gboolean gail_adjustment_set_current_value (AtkValue *obj,
const GValue *value);
#ifdef HAVE_ATK_VALUE_2_12
GAIL_DEFINE_ADJUSTMENT_VALUE_READERS (
gail_adjustment, GAIL_ADJUSTMENT (obj)->adjustment,
adjustment->value, adjustment->upper)
GAIL_DEFINE_ADJUSTMENT_VALUE_INCREMENT (
gail_adjustment, GAIL_ADJUSTMENT (obj)->adjustment,
GAIL_VALUE_MINIMUM_INCREMENT (adjustment))
static void
gail_adjustment_set_value (AtkValue *obj, gdouble value)
{
GtkAdjustment *adjustment;
adjustment = GAIL_ADJUSTMENT (obj)->adjustment;
if (adjustment != NULL)
gtk_adjustment_set_value (adjustment, value);
}
#endif
static void gail_adjustment_destroyed (GtkAdjustment *adjustment,
GailAdjustment *gail_adjustment);
@ -105,9 +115,15 @@ atk_value_interface_init (AtkValueIface *iface)
iface->get_minimum_value = gail_adjustment_get_minimum_value;
iface->get_minimum_increment = gail_adjustment_get_minimum_increment;
iface->set_current_value = gail_adjustment_set_current_value;
#ifdef HAVE_ATK_VALUE_2_12
iface->get_value_and_text = gail_adjustment_get_value_and_text;
iface->get_range = gail_adjustment_get_range;
iface->get_increment = gail_adjustment_get_increment;
iface->set_value = gail_adjustment_set_value;
#endif
}
static void
void
gail_adjustment_get_current_value (AtkValue *obj,
GValue *value)
{
@ -127,7 +143,7 @@ gail_adjustment_get_current_value (AtkValue *obj,
g_value_set_double (value,current_value);
}
static void
void
gail_adjustment_get_maximum_value (AtkValue *obj,
GValue *value)
{
@ -147,7 +163,7 @@ gail_adjustment_get_maximum_value (AtkValue *obj,
g_value_set_double (value, maximum_value);
}
static void
void
gail_adjustment_get_minimum_value (AtkValue *obj,
GValue *value)
{
@ -167,48 +183,20 @@ gail_adjustment_get_minimum_value (AtkValue *obj,
g_value_set_double (value, minimum_value);
}
static void
gail_adjustment_get_minimum_increment (AtkValue *obj,
GValue *value)
void
gail_adjustment_get_minimum_increment (AtkValue *obj, GValue *value)
{
GtkAdjustment* adjustment;
gdouble minimum_increment;
GtkAdjustment *adjustment = GAIL_ADJUSTMENT (obj)->adjustment;
adjustment = GAIL_ADJUSTMENT (obj)->adjustment;
if (adjustment == NULL)
{
/* State is defunct */
return;
}
if (adjustment->step_increment != 0 &&
adjustment->page_increment != 0)
{
if (ABS (adjustment->step_increment) < ABS (adjustment->page_increment))
minimum_increment = adjustment->step_increment;
else
minimum_increment = adjustment->page_increment;
}
else if (adjustment->step_increment == 0 &&
adjustment->page_increment == 0)
{
minimum_increment = 0;
}
else if (adjustment->step_increment == 0)
{
minimum_increment = adjustment->page_increment;
}
else
{
minimum_increment = adjustment->step_increment;
}
memset (value, 0, sizeof (GValue));
memset (value, 0, sizeof (GValue));
g_value_init (value, G_TYPE_DOUBLE);
g_value_set_double (value, minimum_increment);
g_value_set_double (value, GAIL_VALUE_MINIMUM_INCREMENT (adjustment));
}
static gboolean
gboolean
gail_adjustment_set_current_value (AtkValue *obj,
const GValue *value)
{

View file

@ -50,6 +50,22 @@ struct _GailAdjustmentClass
AtkObject *gail_adjustment_new (GtkAdjustment *adjustment);
G_GNUC_INTERNAL void
gail_adjustment_get_current_value (AtkValue *obj,
GValue *value);
G_GNUC_INTERNAL void
gail_adjustment_get_maximum_value (AtkValue *obj,
GValue *value);
G_GNUC_INTERNAL void
gail_adjustment_get_minimum_value (AtkValue *obj,
GValue *value);
G_GNUC_INTERNAL void
gail_adjustment_get_minimum_increment (AtkValue *obj,
GValue *value);
G_GNUC_INTERNAL gboolean
gail_adjustment_set_current_value (AtkValue *obj,
const GValue *value);
G_END_DECLS
#endif /* __GAIL_ADJUSTMENT_H__ */

View file

@ -22,6 +22,7 @@
#include <string.h>
#include <gtk/gtk.h>
#include "gailpaned.h"
#include "gailvalue.h"
static void gail_paned_class_init (GailPanedClass *klass);
@ -44,6 +45,35 @@ static void gail_paned_get_minimum_value (AtkValue *obj,
static gboolean gail_paned_set_current_value (AtkValue *obj,
const GValue *value);
#ifdef HAVE_ATK_VALUE_2_12
static void
gail_paned_get_value_and_text (AtkValue *obj, gdouble *value, gchar **text)
{
GtkWidget *widget = GTK_ACCESSIBLE (obj)->widget;
if (text != NULL)
*text = NULL;
if (value != NULL)
*value = widget != NULL
? gtk_paned_get_position (GTK_PANED (widget)) : 0.0;
}
static AtkRange *
gail_paned_get_range (AtkValue *obj)
{
GtkWidget *widget = GTK_ACCESSIBLE (obj)->widget;
GtkPaned *paned;
if (widget == NULL)
return NULL;
paned = GTK_PANED (widget);
return atk_range_new (paned->min_position, paned->max_position, NULL);
}
GAIL_DEFINE_WIDGET_VALUE_SETTER (
gail_paned, GTK_PANED, gtk_paned_set_position, (gint) value)
#endif
G_DEFINE_TYPE_WITH_CODE (GailPaned, gail_paned, GAIL_TYPE_CONTAINER,
G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init))
@ -112,6 +142,11 @@ atk_value_interface_init (AtkValueIface *iface)
iface->get_maximum_value = gail_paned_get_maximum_value;
iface->get_minimum_value = gail_paned_get_minimum_value;
iface->set_current_value = gail_paned_set_current_value;
#ifdef HAVE_ATK_VALUE_2_12
iface->get_value_and_text = gail_paned_get_value_and_text;
iface->get_range = gail_paned_get_range;
iface->set_value = gail_paned_set_value;
#endif
}
static void

View file

@ -26,6 +26,7 @@
#include <gtk/gtk.h>
#include "gailprogressbar.h"
#include "gailvalue.h"
#include "gailadjustment.h"
static void gail_progress_bar_class_init (GailProgressBarClass *klass);
@ -50,6 +51,13 @@ static void gail_progress_bar_get_minimum_value (AtkValue *obj,
static void gail_progress_bar_value_changed (GtkAdjustment *adjustment,
gpointer data);
#ifdef HAVE_ATK_VALUE_2_12
GAIL_DEFINE_ADJUSTMENT_VALUE_READERS (
gail_progress_bar,
GAIL_VALUE_ADJUSTMENT (GAIL_PROGRESS_BAR (obj)->adjustment),
adjustment->value, adjustment->upper)
#endif
G_DEFINE_TYPE_WITH_CODE (GailProgressBar, gail_progress_bar, GAIL_TYPE_WIDGET,
G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init))
@ -108,6 +116,10 @@ atk_value_interface_init (AtkValueIface *iface)
iface->get_current_value = gail_progress_bar_get_current_value;
iface->get_maximum_value = gail_progress_bar_get_maximum_value;
iface->get_minimum_value = gail_progress_bar_get_minimum_value;
#ifdef HAVE_ATK_VALUE_2_12
iface->get_value_and_text = gail_progress_bar_get_value_and_text;
iface->get_range = gail_progress_bar_get_range;
#endif
}
static void
@ -125,7 +137,7 @@ gail_progress_bar_get_current_value (AtkValue *obj,
*/
return;
atk_value_get_current_value (ATK_VALUE (progress_bar->adjustment), value);
gail_adjustment_get_current_value (ATK_VALUE (progress_bar->adjustment), value);
}
static void
@ -143,7 +155,7 @@ gail_progress_bar_get_maximum_value (AtkValue *obj,
*/
return;
atk_value_get_maximum_value (ATK_VALUE (progress_bar->adjustment), value);
gail_adjustment_get_maximum_value (ATK_VALUE (progress_bar->adjustment), value);
}
static void
@ -161,7 +173,7 @@ gail_progress_bar_get_minimum_value (AtkValue *obj,
*/
return;
atk_value_get_minimum_value (ATK_VALUE (progress_bar->adjustment), value);
gail_adjustment_get_minimum_value (ATK_VALUE (progress_bar->adjustment), value);
}
static void

View file

@ -23,6 +23,7 @@
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "gailrange.h"
#include "gailvalue.h"
#include "gailadjustment.h"
#include "gail-private-macros.h"
@ -70,6 +71,28 @@ static gboolean gail_range_set_description (AtkAction *action,
gint i,
const gchar *desc);
#ifdef HAVE_ATK_VALUE_2_12
#define GAIL_RANGE_ADJUSTMENT(obj) \
(GTK_ACCESSIBLE (obj)->widget != NULL \
? GAIL_VALUE_ADJUSTMENT (GAIL_RANGE (obj)->adjustment) : NULL)
#define GAIL_RANGE_UPPER(obj, adjustment) \
(gtk_range_get_restrict_to_fill_level ( \
GTK_RANGE (GTK_ACCESSIBLE (obj)->widget)) \
? MIN ((adjustment)->upper - (adjustment)->page_size, \
gtk_range_get_fill_level ( \
GTK_RANGE (GTK_ACCESSIBLE (obj)->widget))) \
: (adjustment)->upper - (adjustment)->page_size)
GAIL_DEFINE_ADJUSTMENT_VALUE_READERS (
gail_range, GAIL_RANGE_ADJUSTMENT (obj), adjustment->value,
GAIL_RANGE_UPPER (obj, adjustment))
GAIL_DEFINE_ADJUSTMENT_VALUE_INCREMENT (
gail_range, GAIL_RANGE_ADJUSTMENT (obj),
GAIL_VALUE_MINIMUM_INCREMENT (adjustment))
GAIL_DEFINE_WIDGET_VALUE_SETTER (
gail_range, GTK_RANGE, gtk_range_set_value, value)
#endif
G_DEFINE_TYPE_WITH_CODE (GailRange, gail_range, GAIL_TYPE_WIDGET,
G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init))
@ -163,6 +186,12 @@ atk_value_interface_init (AtkValueIface *iface)
iface->get_minimum_value = gail_range_get_minimum_value;
iface->get_minimum_increment = gail_range_get_minimum_increment;
iface->set_current_value = gail_range_set_current_value;
#ifdef HAVE_ATK_VALUE_2_12
iface->get_value_and_text = gail_range_get_value_and_text;
iface->get_range = gail_range_get_range;
iface->get_increment = gail_range_get_increment;
iface->set_value = gail_range_set_value;
#endif
}
static void
@ -180,7 +209,7 @@ gail_range_get_current_value (AtkValue *obj,
*/
return;
atk_value_get_current_value (ATK_VALUE (range->adjustment), value);
gail_adjustment_get_current_value (ATK_VALUE (range->adjustment), value);
}
static void
@ -201,7 +230,7 @@ gail_range_get_maximum_value (AtkValue *obj,
*/
return;
atk_value_get_maximum_value (ATK_VALUE (range->adjustment), value);
gail_adjustment_get_maximum_value (ATK_VALUE (range->adjustment), value);
gtk_range = GTK_RANGE (gtk_accessible_get_widget (GTK_ACCESSIBLE (range)));
g_return_if_fail (gtk_range);
@ -231,7 +260,7 @@ gail_range_get_minimum_value (AtkValue *obj,
*/
return;
atk_value_get_minimum_value (ATK_VALUE (range->adjustment), value);
gail_adjustment_get_minimum_value (ATK_VALUE (range->adjustment), value);
}
static void
@ -248,7 +277,7 @@ gail_range_get_minimum_increment (AtkValue *obj, GValue *value)
*/
return;
atk_value_get_minimum_increment (ATK_VALUE (range->adjustment), value);
gail_adjustment_get_minimum_increment (ATK_VALUE (range->adjustment), value);
}
static gboolean gail_range_set_current_value (AtkValue *obj,
@ -519,5 +548,3 @@ gail_range_set_description (AtkAction *action,
else
return FALSE;
}

View file

@ -21,6 +21,7 @@
#include <gtk/gtk.h>
#include "gailscalebutton.h"
#include "gailvalue.h"
#include "gailadjustment.h"
#include "gail-private-macros.h"
@ -65,6 +66,24 @@ static void gail_scale_button_get_minimum_increment (AtkValue *obj,
static gboolean gail_scale_button_set_current_value (AtkValue *obj,
const GValue *value);
#ifdef HAVE_ATK_VALUE_2_12
#define GAIL_SCALE_BUTTON_ADJUSTMENT(obj) \
(GTK_ACCESSIBLE (obj)->widget != NULL \
? gtk_scale_button_get_adjustment ( \
GTK_SCALE_BUTTON (GTK_ACCESSIBLE (obj)->widget)) : NULL)
GAIL_DEFINE_ADJUSTMENT_VALUE_READERS (
gail_scale_button, GAIL_SCALE_BUTTON_ADJUSTMENT (obj),
gtk_scale_button_get_value (
GTK_SCALE_BUTTON (GTK_ACCESSIBLE (obj)->widget)),
adjustment->upper)
GAIL_DEFINE_ADJUSTMENT_VALUE_INCREMENT (
gail_scale_button, GAIL_SCALE_BUTTON_ADJUSTMENT (obj),
adjustment->step_increment)
GAIL_DEFINE_WIDGET_VALUE_SETTER (
gail_scale_button, GTK_SCALE_BUTTON, gtk_scale_button_set_value, value)
#endif
G_DEFINE_TYPE_WITH_CODE (GailScaleButton, gail_scale_button, GAIL_TYPE_BUTTON,
G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init));
@ -181,6 +200,12 @@ atk_value_interface_init (AtkValueIface *iface)
iface->get_minimum_value = gail_scale_button_get_minimum_value;
iface->get_minimum_increment = gail_scale_button_get_minimum_increment;
iface->set_current_value = gail_scale_button_set_current_value;
#ifdef HAVE_ATK_VALUE_2_12
iface->get_value_and_text = gail_scale_button_get_value_and_text;
iface->get_range = gail_scale_button_get_range;
iface->get_increment = gail_scale_button_get_increment;
iface->set_value = gail_scale_button_set_value;
#endif
}
static void
@ -295,5 +320,3 @@ gail_scale_button_notify_gtk (GObject *obj,
GAIL_WIDGET_CLASS (gail_scale_button_parent_class)->notify_gtk (obj, pspec);
}
}

View file

@ -22,6 +22,7 @@
#include <string.h>
#include <gtk/gtk.h>
#include "gailspinbutton.h"
#include "gailvalue.h"
#include "gailadjustment.h"
#include "gail-private-macros.h"
@ -49,6 +50,19 @@ static gboolean gail_spin_button_set_current_value (AtkValue *obj,
static void gail_spin_button_value_changed (GtkAdjustment *adjustment,
gpointer data);
#ifdef HAVE_ATK_VALUE_2_12
GAIL_DEFINE_ADJUSTMENT_VALUE_READERS (
gail_spin_button,
GAIL_VALUE_ADJUSTMENT (GAIL_SPIN_BUTTON (obj)->adjustment),
adjustment->value, adjustment->upper)
GAIL_DEFINE_ADJUSTMENT_VALUE_INCREMENT (
gail_spin_button,
GAIL_VALUE_ADJUSTMENT (GAIL_SPIN_BUTTON (obj)->adjustment),
GAIL_VALUE_MINIMUM_INCREMENT (adjustment))
GAIL_DEFINE_WIDGET_VALUE_SETTER (
gail_spin_button, GTK_SPIN_BUTTON, gtk_spin_button_set_value, value)
#endif
G_DEFINE_TYPE_WITH_CODE (GailSpinButton, gail_spin_button, GAIL_TYPE_ENTRY,
G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init))
@ -110,6 +124,12 @@ atk_value_interface_init (AtkValueIface *iface)
iface->get_minimum_value = gail_spin_button_get_minimum_value;
iface->get_minimum_increment = gail_spin_button_get_minimum_increment;
iface->set_current_value = gail_spin_button_set_current_value;
#ifdef HAVE_ATK_VALUE_2_12
iface->get_value_and_text = gail_spin_button_get_value_and_text;
iface->get_range = gail_spin_button_get_range;
iface->get_increment = gail_spin_button_get_increment;
iface->set_value = gail_spin_button_set_value;
#endif
}
static void
@ -127,7 +147,7 @@ gail_spin_button_get_current_value (AtkValue *obj,
*/
return;
atk_value_get_current_value (ATK_VALUE (spin_button->adjustment), value);
gail_adjustment_get_current_value (ATK_VALUE (spin_button->adjustment), value);
}
static void
@ -145,7 +165,7 @@ gail_spin_button_get_maximum_value (AtkValue *obj,
*/
return;
atk_value_get_maximum_value (ATK_VALUE (spin_button->adjustment), value);
gail_adjustment_get_maximum_value (ATK_VALUE (spin_button->adjustment), value);
}
static void
@ -163,7 +183,7 @@ gail_spin_button_get_minimum_value (AtkValue *obj,
*/
return;
atk_value_get_minimum_value (ATK_VALUE (spin_button->adjustment), value);
gail_adjustment_get_minimum_value (ATK_VALUE (spin_button->adjustment), value);
}
static void
@ -180,7 +200,7 @@ gail_spin_button_get_minimum_increment (AtkValue *obj, GValue *value)
*/
return;
atk_value_get_minimum_increment (ATK_VALUE (spin_button->adjustment), value);
gail_adjustment_get_minimum_increment (ATK_VALUE (spin_button->adjustment), value);
}
static gboolean
@ -198,7 +218,7 @@ gail_spin_button_set_current_value (AtkValue *obj,
*/
return FALSE;
return atk_value_set_current_value (ATK_VALUE (spin_button->adjustment), value);
return gail_adjustment_set_current_value (ATK_VALUE (spin_button->adjustment), value);
}
static void
@ -264,4 +284,3 @@ gail_spin_button_value_changed (GtkAdjustment *adjustment,
g_object_notify (G_OBJECT (spin_button), "accessible-value");
}

View file

@ -0,0 +1,56 @@
/* GAIL - The GNOME Accessibility Implementation Library
*
* 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.
*/
#ifndef __GAIL_VALUE_H__
#define __GAIL_VALUE_H__
#include <gtk/gtk.h>
#define GAIL_VALUE_ADJUSTMENT(accessible) \
((accessible) != NULL ? GAIL_ADJUSTMENT (accessible)->adjustment : NULL)
#define GAIL_VALUE_MINIMUM_INCREMENT(a) \
((a)->step_increment == 0.0 ? (a)->page_increment : \
(a)->page_increment == 0.0 ? (a)->step_increment : \
ABS ((a)->step_increment) < ABS ((a)->page_increment) \
? (a)->step_increment : (a)->page_increment)
#ifdef HAVE_ATK_VALUE_2_12
#define GAIL_DEFINE_ADJUSTMENT_VALUE_READERS(prefix, a_expr, value_expr, max_expr) \
static void prefix##_get_value_and_text (AtkValue *obj, gdouble *value, gchar **text) \
{ \
GtkAdjustment *adjustment = (a_expr); \
if (text != NULL) *text = NULL; \
if (value != NULL) *value = adjustment != NULL ? (value_expr) : 0.0; \
} \
static AtkRange *prefix##_get_range (AtkValue *obj) \
{ \
GtkAdjustment *adjustment = (a_expr); \
return adjustment != NULL \
? atk_range_new (adjustment->lower, (max_expr), NULL) : NULL; \
}
#define GAIL_DEFINE_ADJUSTMENT_VALUE_INCREMENT(prefix, a_expr, increment_expr) \
static gdouble prefix##_get_increment (AtkValue *obj) \
{ \
GtkAdjustment *adjustment = (a_expr); \
return adjustment != NULL ? (increment_expr) : 0.0; \
}
#define GAIL_DEFINE_WIDGET_VALUE_SETTER(prefix, cast, setter, value_expr) \
static void prefix##_set_value (AtkValue *obj, gdouble value) \
{ \
GtkWidget *widget = GTK_ACCESSIBLE (obj)->widget; \
if (widget != NULL) setter (cast (widget), (value_expr)); \
}
#endif
#endif /* __GAIL_VALUE_H__ */

View file

@ -12,6 +12,8 @@ module_LTLIBRARIES = \
libferret.la
endif
noinst_HEADERS = testvalue.h
noinst_LTLIBRARIES = \
libtestaction.la \
libtestbutton.la \

View file

@ -16,6 +16,7 @@
#include <strings.h>
#include "testlib.h"
#include "testvalue.h"
typedef enum
{
@ -1389,7 +1390,8 @@ _print_text_attributes (AtkText *aobject)
static gint
_print_value (AtkValue *aobject)
{
GValue *value_back, val;
GValue val = { 0, };
GValue *value_back;
gint group_num;
TabNumber tab_n = VALUE;
@ -1398,11 +1400,11 @@ _print_value (AtkValue *aobject)
group_num = _print_groupname(tab_n, VALUE_INTERFACE,
"Value Interface");
atk_value_get_current_value(aobject, value_back);
gail_test_value_get_current_value(aobject, value_back);
_print_value_type(group_num, "Value", value_back);
atk_value_get_minimum_value(aobject, value_back);
gail_test_value_get_minimum_value(aobject, value_back);
_print_value_type(group_num, "Minimum Value", value_back);
atk_value_get_maximum_value(aobject, value_back);
gail_test_value_get_maximum_value(aobject, value_back);
_print_value_type(group_num, "Maximum Value", value_back);
return(group_num);
}

View file

@ -2,6 +2,7 @@
#include <stdlib.h>
#include <gtk/gtk.h>
#include <testlib.h>
#include "testvalue.h"
static gint _test_paned (gpointer data);
static void _check_paned (AtkObject *obj);
@ -31,17 +32,17 @@ static void _property_change_handler (AtkObject *obj,
value = &val;
memset (value, 0, sizeof (GValue));
atk_value_get_current_value (ATK_VALUE (obj), value);
gail_test_value_get_current_value (ATK_VALUE (obj), value);
g_return_if_fail (G_VALUE_HOLDS_INT (value));
position = g_value_get_int (value);
g_print ("Position is %d previous position was %d\n",
position, last_position);
last_position = position;
atk_value_get_minimum_value (ATK_VALUE (obj), value);
gail_test_value_get_minimum_value (ATK_VALUE (obj), value);
g_return_if_fail (G_VALUE_HOLDS_INT (value));
position = g_value_get_int (value);
g_print ("Minimum Value is %d\n", position);
atk_value_get_maximum_value (ATK_VALUE (obj), value);
gail_test_value_get_maximum_value (ATK_VALUE (obj), value);
g_return_if_fail (G_VALUE_HOLDS_INT (value));
position = g_value_get_int (value);
g_print ("Maximum Value is %d\n", position);
@ -61,14 +62,14 @@ static gint _test_paned (gpointer data)
value = &val;
memset (value, 0, sizeof (GValue));
atk_value_get_current_value (ATK_VALUE (obj), value);
gail_test_value_get_current_value (ATK_VALUE (obj), value);
g_return_val_if_fail (G_VALUE_HOLDS_INT (value), FALSE);
position = g_value_get_int (value);
g_print ("Position is : %d\n", position);
last_position = position;
position *= 2;
g_value_set_int (value, position);
atk_value_set_current_value (ATK_VALUE (obj), value);
gail_test_value_set_current_value (ATK_VALUE (obj), value);
times++;
}
if (times < 4)

View file

@ -0,0 +1,98 @@
#ifndef __GAIL_TEST_VALUE_H__
#define __GAIL_TEST_VALUE_H__
#include "config.h"
#include <atk/atk.h>
#ifdef HAVE_ATK_VALUE_2_12
static void
gail_test_value_store_number (AtkValue *value,
GValue *result,
gdouble number)
{
if (G_VALUE_TYPE (result) == 0)
g_value_init (result,
atk_object_get_role (ATK_OBJECT (value)) ==
ATK_ROLE_SPLIT_PANE ? G_TYPE_INT : G_TYPE_DOUBLE);
if (G_VALUE_HOLDS_INT (result))
g_value_set_int (result, (gint) number);
else
{
g_return_if_fail (G_VALUE_HOLDS_DOUBLE (result));
g_value_set_double (result, number);
}
}
static void
gail_test_value_get_current_value (AtkValue *value,
GValue *result)
{
gdouble number;
atk_value_get_value_and_text (value, &number, NULL);
gail_test_value_store_number (value, result, number);
}
static void
gail_test_value_get_limit (AtkValue *value,
GValue *result,
gboolean upper)
{
AtkRange *range;
gdouble number;
range = atk_value_get_range (value);
g_return_if_fail (range != NULL);
if (upper)
number = atk_range_get_upper_limit (range);
else
number = atk_range_get_lower_limit (range);
atk_range_free (range);
gail_test_value_store_number (value, result, number);
}
#define gail_test_value_get_minimum_value(value, result) \
gail_test_value_get_limit ((value), (result), FALSE)
#define gail_test_value_get_maximum_value(value, result) \
gail_test_value_get_limit ((value), (result), TRUE)
#define GAIL_TEST_VALUE_NUMBER(value) \
(G_VALUE_HOLDS_INT (value) \
? (gdouble) g_value_get_int (value) \
: g_value_get_double (value))
#define gail_test_value_set_current_value(value, new_value) \
(atk_value_set_value ((value), \
GAIL_TEST_VALUE_NUMBER (new_value)), \
TRUE)
#else
#define GAIL_TEST_VALUE_IFACE(value) \
ATK_VALUE_GET_IFACE (value)
#define gail_test_value_get_current_value(value, result) \
(GAIL_TEST_VALUE_IFACE (value)->get_current_value ( \
(value), (result)))
#define gail_test_value_get_minimum_value(value, result) \
(GAIL_TEST_VALUE_IFACE (value)->get_minimum_value ( \
(value), (result)))
#define gail_test_value_get_maximum_value(value, result) \
(GAIL_TEST_VALUE_IFACE (value)->get_maximum_value ( \
(value), (result)))
#define gail_test_value_set_current_value(value, new_value) \
(GAIL_TEST_VALUE_IFACE (value)->set_current_value ( \
(value), (new_value)))
#endif
#endif /* __GAIL_TEST_VALUE_H__ */

View file

@ -1,6 +1,7 @@
#include <string.h>
#include <atk/atk.h>
#include <gtk/gtk.h>
#include "testvalue.h"
static void _traverse_children (AtkObject *obj);
static void _add_handler (AtkObject *obj);
@ -14,8 +15,8 @@ static void _value_change_handler (AtkObject *obj,
AtkPropertyValues *values)
{
const gchar *type_name = g_type_name (G_TYPE_FROM_INSTANCE (obj));
GValue *value_back, val;
GValue val = { 0, };
GValue *value_back;
value_back = &val;
if (!ATK_IS_VALUE (obj)) {
@ -33,17 +34,17 @@ static void _value_change_handler (AtkObject *obj,
g_print("Now calling the AtkValue interface functions\n");
atk_value_get_current_value (ATK_VALUE(obj), value_back);
gail_test_value_get_current_value (ATK_VALUE(obj), value_back);
g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value_back));
g_print ("atk_value_get_current_value returns %f\n",
g_value_get_double (value_back) );
atk_value_get_maximum_value (ATK_VALUE (obj), value_back);
gail_test_value_get_maximum_value (ATK_VALUE (obj), value_back);
g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value_back));
g_print ("atk_value_get_maximum returns %f\n",
g_value_get_double (value_back));
atk_value_get_minimum_value (ATK_VALUE (obj), value_back);
gail_test_value_get_minimum_value (ATK_VALUE (obj), value_back);
g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value_back));
g_print ("atk_value_get_minimum returns %f\n",
g_value_get_double (value_back));
@ -103,7 +104,8 @@ static void _add_handler (AtkObject *obj)
static void _set_values (AtkObject *obj) {
GValue *value_back, val;
GValue val = { 0, };
GValue *value_back;
static gint count = 0;
gdouble double_value;
@ -125,7 +127,7 @@ static void _set_values (AtkObject *obj) {
text = "5.7";
atk_editable_text_set_text_contents(ATK_EDITABLE_TEXT(obj),text);
g_print("Set text to %s\n",text);
atk_value_get_current_value(ATK_VALUE(obj), value_back);
gail_test_value_get_current_value(ATK_VALUE(obj), value_back);
g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value_back));
g_print("atk_value_get_current_value returns %f\n",
g_value_get_double( value_back));
@ -134,7 +136,7 @@ static void _set_values (AtkObject *obj) {
memset (value_back, 0, sizeof (GValue));
g_value_init (value_back, G_TYPE_DOUBLE);
g_value_set_double (value_back, 10.0);
if (atk_value_set_current_value (ATK_VALUE (obj), value_back))
if (gail_test_value_set_current_value (ATK_VALUE (obj), value_back))
{
double_value = g_value_get_double (value_back);
g_print("atk_value_set_current_value returns %f\n",

View file

@ -34,6 +34,11 @@
typedef void (*GtkCupsRequestStateFunc) (GtkCupsRequest *request);
static http_t *gtk_cups_http_connect (const char *host,
int port,
http_encryption_t encryption);
static int gtk_cups_http_reconnect (http_t *http);
static void _connect (GtkCupsRequest *request);
static void _post_send (GtkCupsRequest *request);
static void _post_write_request (GtkCupsRequest *request);
@ -171,7 +176,7 @@ gtk_cups_request_new_with_username (http_t *connection,
else
{
request->http = NULL;
request->http = httpConnectEncrypt (request->server,
request->http = gtk_cups_http_connect (request->server,
ippPort (),
cupsEncryption ());
@ -681,6 +686,29 @@ gtk_cups_request_set_ipp_version (GtkCupsRequest *request,
ippSetVersion (request->ipp_request, major, minor);
}
static http_t *
gtk_cups_http_connect (const char *host,
int port,
http_encryption_t encryption)
{
#ifdef HAVE_HTTPCONNECT2
return httpConnect2 (host, port, NULL, AF_UNSPEC, encryption, 1, 30000, NULL);
#else
return httpConnectEncrypt (host, port, encryption);
#endif
}
static int
gtk_cups_http_reconnect (http_t *http)
{
#ifdef HAVE_HTTPRECONNECT2
return httpReconnect2 (http, 30000, NULL);
#else
return httpReconnect (http);
#endif
}
static void
_connect (GtkCupsRequest *request)
{
@ -689,7 +717,7 @@ _connect (GtkCupsRequest *request)
if (request->http == NULL)
{
request->http = httpConnectEncrypt (request->server,
request->http = gtk_cups_http_connect (request->server,
ippPort (),
cupsEncryption ());
@ -744,7 +772,7 @@ _post_send (GtkCupsRequest *request)
if (httpPost (request->http, request->resource))
{
if (httpReconnect (request->http))
if (gtk_cups_http_reconnect (request->http))
{
request->state = GTK_CUPS_POST_DONE;
request->poll_state = GTK_CUPS_HTTP_IDLE;
@ -1046,7 +1074,7 @@ _post_check (GtkCupsRequest *request)
}
if (auth_result ||
httpReconnect (request->http))
gtk_cups_http_reconnect (request->http))
{
/* if the password has been used, reset password_state
* so that we ask for a new one next time around
@ -1105,7 +1133,7 @@ _post_check (GtkCupsRequest *request)
request->state = GTK_CUPS_POST_CONNECT;
/* Reconnect... */
httpReconnect (request->http);
gtk_cups_http_reconnect (request->http);
/* Upgrade with encryption... */
httpEncryption (request->http, HTTP_ENCRYPT_REQUIRED);
@ -1232,7 +1260,7 @@ _get_send (GtkCupsRequest *request)
if (httpGet (request->http, request->resource))
{
if (httpReconnect (request->http))
if (gtk_cups_http_reconnect (request->http))
{
request->state = GTK_CUPS_GET_DONE;
request->poll_state = GTK_CUPS_HTTP_IDLE;
@ -1341,7 +1369,7 @@ _get_check (GtkCupsRequest *request)
}
if (auth_result ||
httpReconnect (request->http))
gtk_cups_http_reconnect (request->http))
{
/* if the password has been used, reset password_state
* so that we ask for a new one next time around
@ -1373,7 +1401,7 @@ _get_check (GtkCupsRequest *request)
request->state = GTK_CUPS_GET_CONNECT;
/* Reconnect... */
httpReconnect (request->http);
gtk_cups_http_reconnect (request->http);
/* Upgrade with encryption... */
httpEncryption (request->http, HTTP_ENCRYPT_REQUIRED);

File diff suppressed because it is too large Load diff