Compare commits
271 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bd2f564550 | |||
| 879386022f | |||
| 3c084768ad | |||
| 1e47f687ad | |||
| 67d71439c5 | |||
| 25d90b843d | |||
| 25630a7b6c | |||
| 30e654e71b | |||
| 81df15dbd4 | |||
| f7c5f43a72 | |||
| 963ceb9356 | |||
| 61e13c4c77 | |||
| 82c31ad22b | |||
| f2a519b6b3 | |||
| f4adc0dba4 | |||
| 4dc5a17c15 | |||
| d00889a3ed | |||
| 025b50b977 | |||
| 2b41c5d460 | |||
| 665ecdb8ec | |||
| 02ec92b2ed | |||
| b439c49898 | |||
| f34d6dbbe9 | |||
| 2020453616 | |||
| aa5c0cb2d2 | |||
| 76900792f4 | |||
| 249b9c1218 | |||
| afef1cc9db | |||
| a114bc7096 | |||
| 8daf239a03 | |||
| 70076454c6 | |||
| 8996a22718 | |||
| eb924984dc | |||
| 21ce0b3f20 | |||
| 27129904a9 | |||
| f1fdab1574 | |||
| d0e1b8482b | |||
| f36342b52d | |||
| 79b790a09b | |||
| cffa661b92 | |||
| cdcbdeaf44 | |||
| cfeee35965 | |||
| 70e6af9504 | |||
| ed31e5a048 | |||
| 29e1292636 | |||
| 3a8845dafc | |||
| c7d2a3cfd3 | |||
| 7dc629c56d | |||
| a97f96b8d5 | |||
| 4190964158 | |||
| b4c44e4c42 | |||
| f911da5e90 | |||
| 3c1da10415 | |||
| 5233d0baf4 | |||
| bce254c912 | |||
| 09ab5502c2 | |||
| 361743d885 | |||
| 4585e13bb2 | |||
| 3e5714b31b | |||
| f560ca2abf | |||
| 2888c662b4 | |||
| a6148c464b | |||
| 10eb81cc03 | |||
| e8a9c6d40c | |||
| 0406f5c2f8 | |||
| deff88d90c | |||
| 02defda7a2 | |||
| 591368e293 | |||
| b201a24ed2 | |||
| 816acf018f | |||
| 41045df10d | |||
| 52897dca78 | |||
| 3787535900 | |||
| 617c2261ae | |||
| f05ed3f6da | |||
| 56f933309d | |||
| 4fe91ca0a9 | |||
| a796b1f9bc | |||
| 4d6333f0bf | |||
| 8900c03e11 | |||
| 2b18858303 | |||
| 6c2bc78064 | |||
| cd592c2645 | |||
| 6413017f03 | |||
| a44db0c5c4 | |||
| 7266f9a800 | |||
| c1f8ca5929 | |||
| 5446f039d2 | |||
| 2b2719befc | |||
| 6fb41ab84b | |||
| 06332e35e6 | |||
| a7343b31c3 | |||
| 4db49dde07 | |||
| ca55b116a8 | |||
| 9171e7438f | |||
| bdb5f882ab | |||
| 323dffbc3b | |||
| af554cb133 | |||
| 2e6649ba17 | |||
| 733d0c9154 | |||
| db9ce55567 | |||
| c214874a8c | |||
| 175146c46d | |||
| fd551b2522 | |||
| e2d90b91c1 | |||
| f979c5c56e | |||
| a7ce2ab638 | |||
| 49639a9cd1 | |||
| 6f1882c24c | |||
| 2a98a16650 | |||
| 6f3cb8b1e1 | |||
| fa57ef8aef | |||
| 4ec3a1d6bd | |||
| f23bda0aad | |||
| cb32f70d20 | |||
| 4e59943375 | |||
| aa36444d7b | |||
| 6c7d7624de | |||
| 8c204e5162 | |||
| cf41b53d71 | |||
| 7608f14b65 | |||
| 8291422086 | |||
| 4a34b201cb | |||
| 1c575522c7 | |||
| 4d67d33f02 | |||
| 7c02992921 | |||
| 50ff8e97f9 | |||
| 7cd37d663b | |||
| 06a15ebedb | |||
| 5bbe06755f | |||
| 154f5dad5b | |||
| d9a12031a2 | |||
| 304f9655f9 | |||
| e9786ce85d | |||
| 96ad6fc4bf | |||
| df8a418a8f | |||
| 7cf485c594 | |||
| 0b9bdc7987 | |||
| 781d7b3364 | |||
| 1a12599fdb | |||
| f1331d8410 | |||
| 529fb0f44f | |||
| ac680cad1e | |||
| 632ce3d3ae | |||
| cf098bba4b | |||
| b4fa63e261 | |||
| b5b88a69aa | |||
| 02f7f14cf2 | |||
| b741e5d3a4 | |||
| ad7adfb4e3 | |||
| e782c03412 | |||
| 0fe0cbaf0c | |||
| 8faf265c12 | |||
| faec05473d | |||
| e753dc2e5a | |||
| b85ef7f732 | |||
| ebe22cd6d3 | |||
| ef50ede3b6 | |||
| 292b331f5b | |||
| eb86193b07 | |||
| c518a56720 | |||
| 204d0e0003 | |||
| af19500ed3 | |||
| f408e1f17f | |||
| c3e91c2604 | |||
| bcd4a8cdb3 | |||
| a7df1508a6 | |||
| 8dbbf8321b | |||
| 3cc2f664cd | |||
| 4fb311b311 | |||
| 96425d2e3c | |||
| 34121a9108 | |||
| ce88affe29 | |||
| af65cdb24e | |||
| 5ca944a813 | |||
| 8f382907d7 | |||
| 4915dc0ef8 | |||
| 105deb1810 | |||
| 3a364cd602 | |||
| 0ed32754f4 | |||
| f740c34dcb | |||
| c8a682947a | |||
| d004f2901e | |||
| 569090f11e | |||
| 32eed3d40a | |||
| 37c0651b95 | |||
| bb6dd7da57 | |||
| 2fb484d7cc | |||
| d0c98af5f8 | |||
| bec6655a7c | |||
| d436ab3def | |||
| 6da13b2f0a | |||
| 35f8965bed | |||
| d516dac5b2 | |||
| b55a0e4921 | |||
| 71d1467304 | |||
| 41bf2931d2 | |||
| aad633f661 | |||
| d29d5fd365 | |||
| f3e0bab511 | |||
| 34b133c8b9 | |||
| 876528e16b | |||
| 5f1caa9779 | |||
| 9f18204cc5 | |||
| 798e56c1e9 | |||
| 0c18fe881b | |||
| ce4015d2ec | |||
| 3ac2421694 | |||
| 9846287396 | |||
| 5b9f86b96a | |||
| c1a4a4cd56 | |||
| 516d2b85e5 | |||
| 24739f4261 | |||
| f6e4a6ae2b | |||
| 3d7693a13c | |||
| 4f525073c6 | |||
| 9e4e9889da | |||
| fbbd38ddb1 | |||
| 6e92d31415 | |||
| a075ca97ed | |||
| af177c8c1c | |||
| e0e5f1fd52 | |||
| 1594006ba2 | |||
| 087ea955d9 | |||
| 41e1167283 | |||
| 0988088c47 | |||
| 47a464fcb6 | |||
| 78068978a0 | |||
| 7bdde1e104 | |||
| f951eff62e | |||
| 653190b0df | |||
| 6caac23b8e | |||
| 2c2fdce82f | |||
| 205be12b37 | |||
| 245e344eff | |||
| d9fb9d5963 | |||
| be8d1d14b7 | |||
| 1322998cd6 | |||
| 5d2c80e124 | |||
| 0e7ede9036 | |||
| cd396b22ae | |||
| a2e52bc8cc | |||
| fffd34a24d | |||
| 39043b9dcc | |||
| 5d21cd3b72 | |||
| fccbe77810 | |||
| 79648eb953 | |||
| 458d964173 | |||
| 1cf67fae1b | |||
| 4635094c2f | |||
| 809c1777a4 | |||
| 61fddfc0ef | |||
| d9808b04bb | |||
| 457e5acb0b | |||
| 37976d540d | |||
| 4b38323296 | |||
| 4c9adc8d19 | |||
| 3c032484c1 | |||
| 20016b1511 | |||
| b95a071007 | |||
| fa98ac6287 | |||
| e3f5861fa0 | |||
| c5f53b623c | |||
| e6fbe340fa | |||
| 0f205e9172 | |||
| f48cdf2100 | |||
| b834eee6c6 | |||
| 620c316530 | |||
| db0bc7fb3b | |||
| bcf28d3444 | |||
| e69970bd65 |
+1360
File diff suppressed because it is too large
Load Diff
+1360
File diff suppressed because it is too large
Load Diff
+1360
File diff suppressed because it is too large
Load Diff
@@ -18,8 +18,8 @@ GTK+ requires the following packages:
|
||||
Simple install procedure
|
||||
========================
|
||||
|
||||
% gzip -cd gtk+-2.4.1.tar.gz | tar xvf - # unpack the sources
|
||||
% cd gtk+-2.4.1 # change to the toplevel directory
|
||||
% gzip -cd gtk+-2.4.6.tar.gz | tar xvf - # unpack the sources
|
||||
% cd gtk+-2.4.6 # change to the toplevel directory
|
||||
% ./configure # run the `configure' script
|
||||
% make # build GTK
|
||||
[ Become root if necessary ]
|
||||
|
||||
@@ -1,3 +1,130 @@
|
||||
Overview of Changes from GTK+ 2.4.4 to GTK+ 2.4.6
|
||||
=================================================
|
||||
* GtkFileChooser
|
||||
- Set busy cursor while mounting [Federico Mena Quintero]
|
||||
- Set accessible name [Padraig O'Briain]
|
||||
- Improve activation on focus [Federico]
|
||||
- Accept paths in entry [Federico]
|
||||
* GtkTreeView
|
||||
- Draw focus indicator for empty tree views [Federico]
|
||||
- Make column dragging more robust [Matthias Clasen,
|
||||
Christian Biere]
|
||||
- Prevent DND on non-sources [Pawel Salek]
|
||||
* GtkUIManager
|
||||
- Accept paths with a leading / [David Malcolm]
|
||||
* Gdk
|
||||
- Fix handling of keep-above and keep-below
|
||||
state [Matthew Garret]
|
||||
- Add some missing error traps [Thomas Leonard]
|
||||
* gdk-pixbuf
|
||||
- Make incremental loading work for 8bit pcx
|
||||
files [Magnus Bergman]
|
||||
- Handle edge pixels consistently [Brian Cameron,
|
||||
Matthias]
|
||||
- Handle OS/2 BMPs [Jon-Kare Hellan]
|
||||
* Bug fixes for Copy-Paste behaviour in text widgets
|
||||
[Mikael Hallendal, Scott Bronson]
|
||||
* Memory leak fixes in multiple widgets [Kjartan Maraas,
|
||||
Tommi Komulainen, Crispin Flowerday, Matthias]
|
||||
* Win32 fixes [Robert Ögren, Tor Lillqvist, Hans Breuer
|
||||
* Other bug fixes [John Cupitt, Elke Meier, Matthias,
|
||||
Peter Zelezny, Guilherme Salgado, John Finlay, Tommi,
|
||||
Padaig, Olivier Sessink, Nicolas Deves, Lorenzo Gil
|
||||
Sanchez, Christian Persch, Morten Welinder, Markku Vire,
|
||||
Markus Lausser, Abel Daniel]
|
||||
* Documentation improvements [Owen Taylor, Matthias, Axel
|
||||
Simon, David, Federico, Mariano Suarez-Alvarez]
|
||||
* Updated translations (ang,az,bg,br,ca,cs,en_CA,es,fi,fr,hi,hu,
|
||||
it,ja,ko,mn,nb,nl,no,pl,pt,pt_BR,ru,sq,sr,sr@Latn,sr@ije,sv,uz,
|
||||
wa,zh_CN)
|
||||
|
||||
Overview of Changes from GTK+ 2.4.3 to GTK+ 2.4.4
|
||||
=================================================
|
||||
* GtkFileChooser
|
||||
- Use Save button in save mode. [Federico Mena Quintero]
|
||||
- Check for errors when opening folders [Federico]
|
||||
- Fall back to stock icons if icon theme is not found [Federico]
|
||||
- Bug fixes [Federico, Alex Roitman, Owen Taylor]
|
||||
* GtkComboBox
|
||||
- Make it work without a model [Mariano Suarez-Alvarez, Christian Persch]
|
||||
- Improve placement of popup [David A. Knight]
|
||||
* GtkImage
|
||||
- Fix issues with partial redrawing [John Ehresman, Felipe Heidrich,
|
||||
Billy Biggs]
|
||||
* GtkEntry
|
||||
- Fix cursor movement with combining marks [Theppitak Karoonboonyanan]
|
||||
- Protect passwords better [Morten Welinder]
|
||||
* Win32 fixes
|
||||
- Fix build without wintab [J. Ali Harlow]
|
||||
- Improve Clipboard handling [Tor Lillqvist, John Ehresman]
|
||||
* Gdk
|
||||
- Make RGBA cursors work [Michael Natterer]
|
||||
- Work with odd XServers [Bastien Nocera]
|
||||
- Handle _NET_WM_STATE_ABOVE/_BELOW better [Billy Biggs]
|
||||
- Don't leak DND contexts [Alex Larsson]
|
||||
* gdk-pixbuf
|
||||
- Make tiff loader work with libtiff 3.6.1 [Marco Ghirlanda]
|
||||
- Fix math for GDK_INTERP_HYPER [Brian Cameron]
|
||||
- Fix Win32 exported symbols [Tor Lillqvist]
|
||||
* Documentation improvements [Billy Biggs, Matthias Clasen,
|
||||
Oliver Andrieu]
|
||||
* Other bug fixes [Federico, Michael, Matthias, Philip Kendall,
|
||||
Jean-François Wauthy, John Finlay, Jeff Franks, Tim Janik,
|
||||
Nickolay V. Shmyrev, Sampo Nurmentaus, William Jon McCann,
|
||||
Jan-Marek Glogowski, Yevgen Muntyan, Pawel Salek,
|
||||
Jonathan Blandford, Sunil, Dimitiry. M Shatrov]
|
||||
* Updated translations (bg,he,hu,ne,sq)
|
||||
|
||||
Overview of Changes from GTK+ 2.4.2 to GTK+ 2.4.3
|
||||
=================================================
|
||||
* GtkButton
|
||||
- Give extra space to children of !CAN_FOCUS buttons [Matthias Clasen]
|
||||
* GtkFileChooser
|
||||
- Make DND work when the dialog is modal [Federico Mena Quintero]
|
||||
* GtkToolbar
|
||||
- Don't show empty overflow menu [Soeren Sandmann]
|
||||
- Don't show initial separator in overflow menu [Soeren]
|
||||
- Handle dynamic changes to overflow menu [Soeren]
|
||||
* Documentation improvements [Bastien Nocera, Matthias]
|
||||
* Other bug fixes [Matthias, Soeren, Sven Neumann]
|
||||
* Updated translations (hu,ne)
|
||||
|
||||
Overview of Changes from GTK+ 2.4.1 to GTK+ 2.4.2
|
||||
=================================================
|
||||
* GtkUIManager
|
||||
- Install signals correctly [Michael Natterer]
|
||||
- Make the output of gtk_ui_manager_get_ui() parsable. [Michael]
|
||||
- Add a way to suppress stock accelerators. [David A Knight]
|
||||
* GtkClipboard
|
||||
- Fix INCRemental transfer of MULTIPLE targets [Matthias Clasen]
|
||||
- Increase the chunk size for INCRemental transfers [Matthias]
|
||||
* GtkFileChooser
|
||||
- Hide the combo box when appropriate [Christian Neumair]
|
||||
- bug fixes [Federico Mena Quintero]
|
||||
* GtkComboBox
|
||||
- add mouse/wheel bindings on the cellview [Matthias]
|
||||
- improve positioning of popup [Matthias]
|
||||
- make the selection follow the mouse [Matthias]
|
||||
* GtkEntryCompletion
|
||||
- make the selection follow the mouse [Matthias]
|
||||
- restrict popup size to monitor size [Matthias, DmD Ljungmark]
|
||||
- don't complete on paste [Anders Carlsson]
|
||||
* Win32
|
||||
- bug fixes [Benoît Carpentier, Hans Breuer, John Ehresman,
|
||||
Tor Lillqvist, Robert Ögren]
|
||||
* GtkButton/GtkArrow
|
||||
- Don't draw the focus over the button child [Matthias]
|
||||
- Increase default arrow size to compensate [Matthias]
|
||||
* Documentation improvements [Doug Quale, Matthias,
|
||||
Steffen Röcker, Steve Chaplin, Tommi Komulainen]
|
||||
* Other bug fixes [Billy Biggs, Crispin Flowerday,
|
||||
David Hawthorne, Federico, Havoc Pennington, John Finlay,
|
||||
Kouichirou Hiratsuka, Mark McLoughlin, Matthias, Michael,
|
||||
Michal Pasternak, Morten Welinder, Olivier Andrieu,
|
||||
Owen Taylor, Padraig O'Briain, Sam Stevenson, Scott Tsai,
|
||||
Soeren Sandmann, Sven Neumann]
|
||||
* Updated translations (bg,it,nl,tk,wa,zh_CN)
|
||||
|
||||
Overview of Changes from GTK+ 2.4.0 to GTK+ 2.4.1
|
||||
=================================================
|
||||
* GtkFileChooser
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
General Information
|
||||
===================
|
||||
|
||||
This is GTK+ version 2.4.1. GTK+ is a multi-platform toolkit for
|
||||
This is GTK+ version 2.4.6. GTK+ is a multi-platform toolkit for
|
||||
creating graphical user interfaces. Offering a complete set of widgets,
|
||||
GTK+ is suitable for projects ranging from small one-off projects to
|
||||
complete application suites.
|
||||
|
||||
+3
-3
@@ -12,10 +12,10 @@ AC_PREREQ(2.54)
|
||||
|
||||
m4_define([gtk_major_version], [2])
|
||||
m4_define([gtk_minor_version], [4])
|
||||
m4_define([gtk_micro_version], [1])
|
||||
m4_define([gtk_micro_version], [6])
|
||||
m4_define([gtk_version],
|
||||
[gtk_major_version.gtk_minor_version.gtk_micro_version])
|
||||
m4_define([gtk_interface_age], [1])
|
||||
m4_define([gtk_interface_age], [6])
|
||||
m4_define([gtk_binary_age],
|
||||
[m4_eval(100 * gtk_minor_version + gtk_micro_version)])
|
||||
# This is the X.Y used in -lgtk-FOO-X.Y
|
||||
@@ -401,7 +401,7 @@ fi
|
||||
# sure that both po/ and po-properties/ have .po files that correspond
|
||||
# to your language. If you only add one to po/, the build will break
|
||||
# in po-properties/.
|
||||
ALL_LINGUAS="af am ar az be bg bn br ca cs cy da de el en_CA en_GB es et eu fa fi fr ga gl gu he hi hr hu ia id is it ja ko li lt lv mi mk ml mn mr ms ne nl nn no pa pl pt pt_BR ro ru sk sl sq sr sr@ije sr@Latn sv ta th tr uk uz uz@Latn vi wa yi zh_CN zh_TW"
|
||||
ALL_LINGUAS="af am ar az be bg bn br ca cs cy da de el en_CA en_GB es et eu fa fi fr ga gl gu he hi hr hu ia id is it ja ko li lt lv mi mk ml mn mr ms nb ne nl nn no pa pl pt pt_BR ro ru sk sl sq sr sr@ije sr@Latn sv ta th tk tr uk uz uz@Latn vi wa yi zh_CN zh_TW"
|
||||
AM_GLIB_GNU_GETTEXT
|
||||
LIBS="$LIBS $INTLLIBS"
|
||||
AC_OUTPUT_COMMANDS([case "$CONFIG_FILES" in *po-properties/Makefile.in*)
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
Tue Jul 20 23:27:12 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gdk-pixbuf-xlibrgb.c: Include config.h first. (#148034)
|
||||
|
||||
Tue Mar 9 09:33:54 2004 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* === Released 2.3.6 ===
|
||||
|
||||
@@ -47,8 +47,6 @@
|
||||
* Shawn T. Amundson <amundson@gtk.org>
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
# if STDC_HEADERS
|
||||
@@ -61,6 +59,8 @@
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define ENABLE_GRAYSCALE
|
||||
|
||||
/* include this before so that we can get endian definitions if
|
||||
|
||||
@@ -132,7 +132,7 @@ static guint n_color_entries = G_N_ELEMENTS (color_entries);
|
||||
enum {
|
||||
SHAPE_SQUARE,
|
||||
SHAPE_RECTANGLE,
|
||||
SHAPE_OVAL,
|
||||
SHAPE_OVAL
|
||||
};
|
||||
|
||||
static GtkRadioActionEntry shape_entries[] = {
|
||||
|
||||
@@ -89,7 +89,7 @@ static guint n_color_entries = G_N_ELEMENTS (color_entries);
|
||||
enum {
|
||||
SHAPE_SQUARE,
|
||||
SHAPE_RECTANGLE,
|
||||
SHAPE_OVAL,
|
||||
SHAPE_OVAL
|
||||
};
|
||||
|
||||
static GtkRadioActionEntry shape_entries[] = {
|
||||
|
||||
@@ -1,392 +0,0 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <demos.h>
|
||||
|
||||
static GtkTextBuffer *info_buffer;
|
||||
static GtkTextBuffer *source_buffer;
|
||||
|
||||
static gchar *current_file = NULL;
|
||||
|
||||
enum {
|
||||
TITLE_COLUMN,
|
||||
FILENAME_COLUMN,
|
||||
FUNC_COLUMN,
|
||||
ITALIC_COLUMN,
|
||||
NUM_COLUMNS
|
||||
};
|
||||
|
||||
gboolean
|
||||
read_line (FILE *stream, GString *str)
|
||||
{
|
||||
int n_read = 0;
|
||||
|
||||
flockfile (stream);
|
||||
|
||||
g_string_truncate (str, 0);
|
||||
|
||||
while (1)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = getc_unlocked (stream);
|
||||
|
||||
if (c == EOF)
|
||||
goto done;
|
||||
else
|
||||
n_read++;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '\r':
|
||||
case '\n':
|
||||
{
|
||||
int next_c = getc_unlocked (stream);
|
||||
|
||||
if (!(next_c == EOF ||
|
||||
(c == '\r' && next_c == '\n') ||
|
||||
(c == '\n' && next_c == '\r')))
|
||||
ungetc (next_c, stream);
|
||||
|
||||
goto done;
|
||||
}
|
||||
default:
|
||||
g_string_append_c (str, c);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
funlockfile (stream);
|
||||
|
||||
return n_read > 0;
|
||||
}
|
||||
|
||||
void
|
||||
load_file (const gchar *filename)
|
||||
{
|
||||
FILE *file;
|
||||
GtkTextIter start, end;
|
||||
GString *buffer = g_string_new (NULL);
|
||||
int state = 0;
|
||||
gboolean in_para = 0;
|
||||
|
||||
if (current_file && !strcmp (current_file, filename))
|
||||
return;
|
||||
|
||||
g_free (current_file);
|
||||
current_file = g_strdup (filename);
|
||||
|
||||
gtk_text_buffer_get_bounds (info_buffer, &start, &end);
|
||||
gtk_text_buffer_delete (info_buffer, &start, &end);
|
||||
|
||||
gtk_text_buffer_get_bounds (source_buffer, &start, &end);
|
||||
gtk_text_buffer_delete (source_buffer, &start, &end);
|
||||
|
||||
file = fopen (filename, "r");
|
||||
if (!file)
|
||||
{
|
||||
g_warning ("Cannot open %s: %s\n", filename, g_strerror (errno));
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_text_buffer_get_iter_at_offset (info_buffer, &start, 0);
|
||||
while (read_line (file, buffer))
|
||||
{
|
||||
gchar *p = buffer->str;
|
||||
gchar *q;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case 0:
|
||||
/* Reading title */
|
||||
while (*p == '/' || *p == '*' || isspace (*p))
|
||||
p++;
|
||||
q = p + strlen (p);
|
||||
while (q > p && isspace (*(q - 1)))
|
||||
q--;
|
||||
|
||||
if (q > p)
|
||||
{
|
||||
int len_chars = g_utf8_pointer_to_offset (p, q);
|
||||
|
||||
end = start;
|
||||
|
||||
g_assert (strlen (p) >= q - p);
|
||||
gtk_text_buffer_insert (info_buffer, &end, p, q - p);
|
||||
start = end;
|
||||
|
||||
gtk_text_iter_backward_chars (&start, len_chars);
|
||||
gtk_text_buffer_apply_tag_by_name (info_buffer, "title", &start, &end);
|
||||
|
||||
start = end;
|
||||
|
||||
state++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* Reading body of info section */
|
||||
while (isspace (*p))
|
||||
p++;
|
||||
if (*p == '*' && *(p + 1) == '/')
|
||||
{
|
||||
gtk_text_buffer_get_iter_at_offset (source_buffer, &start, 0);
|
||||
state++;
|
||||
}
|
||||
else
|
||||
{
|
||||
int len;
|
||||
|
||||
while (*p == '*' || isspace (*p))
|
||||
p++;
|
||||
|
||||
len = strlen (p);
|
||||
while (isspace (*(p + len - 1)))
|
||||
len--;
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
if (in_para)
|
||||
gtk_text_buffer_insert (info_buffer, &start, " ", 1);
|
||||
|
||||
g_assert (strlen (p) >= len);
|
||||
gtk_text_buffer_insert (info_buffer, &start, p, len);
|
||||
in_para = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_text_buffer_insert (info_buffer, &start, "\n", 1);
|
||||
in_para = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* Skipping blank lines */
|
||||
while (isspace (*p))
|
||||
p++;
|
||||
if (*p)
|
||||
{
|
||||
p = buffer->str;
|
||||
state++;
|
||||
/* Fall through */
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* Reading program body */
|
||||
gtk_text_buffer_insert (source_buffer, &start, p, -1);
|
||||
gtk_text_buffer_insert (info_buffer, &start, "\n", 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gtk_text_buffer_get_bounds (source_buffer, &start, &end);
|
||||
gtk_text_buffer_apply_tag_by_name (info_buffer, "source", &start, &end);
|
||||
}
|
||||
|
||||
gboolean
|
||||
button_press_event_cb (GtkTreeView *tree_view,
|
||||
GdkEventButton *event,
|
||||
GtkTreeModel *model)
|
||||
{
|
||||
if (event->type == GDK_2BUTTON_PRESS)
|
||||
{
|
||||
GtkTreePath *path = NULL;
|
||||
|
||||
gtk_tree_view_get_path_at_pos (tree_view,
|
||||
event->window,
|
||||
event->x,
|
||||
event->y,
|
||||
&path,
|
||||
NULL);
|
||||
|
||||
if (path)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
gboolean italic;
|
||||
GVoidFunc func;
|
||||
|
||||
gtk_tree_model_get_iter (model, &iter, path);
|
||||
gtk_tree_store_get (GTK_TREE_STORE (model),
|
||||
&iter,
|
||||
FUNC_COLUMN, &func,
|
||||
ITALIC_COLUMN, &italic,
|
||||
-1);
|
||||
(func) ();
|
||||
gtk_tree_store_set (GTK_TREE_STORE (model),
|
||||
&iter,
|
||||
ITALIC_COLUMN, !italic,
|
||||
-1);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
|
||||
gtk_signal_emit_stop_by_name (GTK_OBJECT (tree_view),
|
||||
"button_press_event");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
selection_cb (GtkTreeSelection *selection,
|
||||
GtkTreeModel *model)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GValue value = {0, };
|
||||
|
||||
if (! gtk_tree_selection_get_selected (selection, NULL, &iter))
|
||||
return;
|
||||
|
||||
gtk_tree_model_get_value (model, &iter,
|
||||
FILENAME_COLUMN,
|
||||
&value);
|
||||
load_file (g_value_get_string (&value));
|
||||
g_value_unset (&value);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_text (GtkTextBuffer **buffer,
|
||||
gboolean is_source)
|
||||
{
|
||||
GtkWidget *scrolled_window;
|
||||
GtkWidget *text_view;
|
||||
PangoFontDescription *font_desc;
|
||||
|
||||
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
|
||||
GTK_SHADOW_IN);
|
||||
|
||||
text_view = gtk_text_view_new ();
|
||||
gtk_container_add (GTK_CONTAINER (scrolled_window), text_view);
|
||||
|
||||
*buffer = gtk_text_buffer_new (NULL);
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (text_view), *buffer);
|
||||
gtk_text_view_set_editable (GTK_TEXT_VIEW (text_view), FALSE);
|
||||
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (text_view), FALSE);
|
||||
|
||||
if (is_source)
|
||||
{
|
||||
font_desc = pango_font_description_from_string ("Courier 10");
|
||||
gtk_widget_modify_font (text_view, font_desc);
|
||||
pango_font_description_free (font_desc);
|
||||
}
|
||||
|
||||
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_view), !is_source);
|
||||
|
||||
return scrolled_window;
|
||||
}
|
||||
|
||||
/* Technically a list, but if we do go to 80 demos, we may want to move to a tree */
|
||||
static GtkWidget *
|
||||
create_tree (void)
|
||||
{
|
||||
GtkTreeSelection *selection;
|
||||
GtkCellRenderer *cell;
|
||||
GtkWidget *tree_view;
|
||||
GtkTreeViewColumn *column;
|
||||
GtkTreeStore *model;
|
||||
GtkTreeIter iter;
|
||||
gint i;
|
||||
|
||||
model = gtk_tree_store_new_with_types (NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN);
|
||||
tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
|
||||
|
||||
gtk_tree_selection_set_type (GTK_TREE_SELECTION (selection),
|
||||
GTK_TREE_SELECTION_SINGLE);
|
||||
gtk_widget_set_usize (tree_view, 200, -1);
|
||||
|
||||
for (i=0; i < G_N_ELEMENTS (testgtk_demos); i++)
|
||||
{
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
|
||||
gtk_tree_store_set (GTK_TREE_STORE (model),
|
||||
&iter,
|
||||
TITLE_COLUMN, testgtk_demos[i].title,
|
||||
FILENAME_COLUMN, testgtk_demos[i].filename,
|
||||
FUNC_COLUMN, testgtk_demos[i].func,
|
||||
ITALIC_COLUMN, FALSE,
|
||||
-1);
|
||||
}
|
||||
|
||||
cell = gtk_cell_renderer_text_new ();
|
||||
column = gtk_tree_view_column_new_with_attributes ("Widget",
|
||||
cell,
|
||||
"text", TITLE_COLUMN,
|
||||
"italic", ITALIC_COLUMN,
|
||||
NULL);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view),
|
||||
GTK_TREE_VIEW_COLUMN (column));
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (selection), "selection_changed", selection_cb, model);
|
||||
gtk_signal_connect (GTK_OBJECT (tree_view), "button_press_event", GTK_SIGNAL_FUNC (button_press_event_cb), model);
|
||||
|
||||
return tree_view;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *notebook;
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *tree;
|
||||
GtkTextTag *tag;
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_signal_connect (GTK_OBJECT (window), "destroy",
|
||||
GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
|
||||
|
||||
hbox = gtk_hbox_new (FALSE, 0);
|
||||
gtk_container_add (GTK_CONTAINER (window), hbox);
|
||||
|
||||
tree = create_tree ();
|
||||
gtk_box_pack_start (GTK_BOX (hbox), tree, FALSE, FALSE, 0);
|
||||
|
||||
notebook = gtk_notebook_new ();
|
||||
gtk_box_pack_start (GTK_BOX (hbox), notebook, TRUE, TRUE, 0);
|
||||
|
||||
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
|
||||
create_text (&info_buffer, FALSE),
|
||||
gtk_label_new ("Info"));
|
||||
|
||||
|
||||
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
|
||||
create_text (&source_buffer, TRUE),
|
||||
gtk_label_new ("Source"));
|
||||
|
||||
tag = gtk_text_buffer_create_tag (info_buffer, "title");
|
||||
gtk_object_set (GTK_OBJECT (tag),
|
||||
"font", "Sans 18",
|
||||
NULL);
|
||||
|
||||
tag = gtk_text_buffer_create_tag (info_buffer, "source");
|
||||
gtk_object_set (GTK_OBJECT (tag),
|
||||
"font", "Courier 10",
|
||||
"pixels_above_lines", 0,
|
||||
"pixels_below_lines", 0,
|
||||
NULL);
|
||||
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||
gtk_widget_show_all (window);
|
||||
|
||||
|
||||
load_file (testgtk_demos[0].filename);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
+4
-2
@@ -16,8 +16,9 @@ Without those packages make distcheck will *not* pass.
|
||||
0) Blow away your gtk+ directory, check a new version out
|
||||
1) autogen and build it, make sure to enable docs.
|
||||
2) Update NEWS based on the various ChangeLog files
|
||||
3) Update version in configure.in, increase micro and interface age by 1.
|
||||
(Note that this is critical, a slip-up here will cause the soname to change).
|
||||
3) Verify that the version in configure.in has been bumped after the last
|
||||
release. (Note that this is critical, a slip-up here will cause the soname
|
||||
to change).
|
||||
4) Add === Released 2.x.y === at the top of all ChangeLog files
|
||||
5) make distcheck
|
||||
6) Fix broken stuff found by 5) repeat
|
||||
@@ -34,3 +35,4 @@ create a new message in the same form, replacing version numbers, commentary
|
||||
at the top about "what this release is about" and the Summary of changes.
|
||||
12) Send it to gnome-announce-list, gtk-list, gtk-app-devel-list and
|
||||
gtk-devel-list. Set reply-to to gnome-hackers.
|
||||
13) Bump the version number in configure.in.
|
||||
|
||||
@@ -429,7 +429,7 @@ in which they need to be installed:</para>
|
||||
|
||||
<itemizedlist spacing=compact>
|
||||
<listitem><simpara> pkg-config
|
||||
(<ulink url="http://www.freedesktop.org/software/pkgconfig/">
|
||||
(<ulink url="http://www.freedesktop.org/software/pkgconfig">
|
||||
pkg-config Site</ulink>)</simpara>
|
||||
</listitem>
|
||||
|
||||
|
||||
@@ -1,3 +1,93 @@
|
||||
2004-08-13 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* === Released 2.4.6 ===
|
||||
|
||||
Thu Aug 12 00:06:20 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gtk/tmpl/gtkuimanager.sgml: Add some information about
|
||||
allowed values for the name and action attributes.
|
||||
|
||||
2004-08-07 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* gtk/tmpl/gtkrc.sgml: Fix a typo. (#149470, Mariano
|
||||
Suarez-Alvarez)
|
||||
|
||||
2004-07-13 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* gtk/gtk-sections.txt: Add gtk_parse_args.
|
||||
|
||||
2004-07-12 Federico Mena Quintero <federico@ximian.com>
|
||||
|
||||
Merged from HEAD:
|
||||
|
||||
* gtk/glossary.xml: Start of the GTK+ glossary.
|
||||
|
||||
* gtk/Makefile.am (content_files): Added glossary.xml.
|
||||
|
||||
* gtk/gtk-docs.sgml: Likewise.
|
||||
|
||||
2004-07-10 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* === Released 2.4.4 ===
|
||||
|
||||
Sat Jul 3 23:44:45 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gtk/tmpl/gtksocket.sgml:
|
||||
* gtk/tmpl/gtkicontheme.sgml:
|
||||
* gtk/building.sgml:
|
||||
* gdk/tmpl/windows.sgml: Fix links to www.freedesktop.org.
|
||||
(#145210, Billy Biggs)
|
||||
|
||||
Tue Jun 22 21:54:24 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gdk-pixbuf/composite.dia:
|
||||
* gdk-pixbuf/composite.png: Flip the y axes in the diagrams.
|
||||
|
||||
Sun Jun 20 00:17:58 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gdk-pixbuf/composite.png: Add a figure which tries
|
||||
to expain pixbuf compositing.
|
||||
|
||||
* gdk-pixbuf/composite.dia:
|
||||
* gdk-pixbuf/apple-red-1a.png:
|
||||
* gdk-pixbuf/apple-red-2c.png:
|
||||
* gdk-pixbuf/gnome-gmush-1.png: Sources for composite.png.
|
||||
|
||||
* gdk-pixbuf/Makefile.am (HTML_IMAGES): Add composite.png.
|
||||
|
||||
Fri Jun 18 21:23:08 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gtk/tmpl/gtktreemodelfilter.sgml: Fix the docs for
|
||||
GtkTreeModelFilterVisibleFunc. (#144583, Olivier Andrieu)
|
||||
|
||||
2004-06-11 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* === Released 2.4.3 ===
|
||||
|
||||
2004-06-04 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* === Released 2.4.2 ===
|
||||
|
||||
Mon May 31 00:18:29 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gtk/tmpl/gtktable.sgml: Document the default attach
|
||||
options for gtk_table_attach_defaults(). (#143391,
|
||||
Steve Chaplin)
|
||||
|
||||
Fri May 28 14:35:53 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gtk/tmpl/gtkcontainer.sgml: Fix docs for
|
||||
gtk_container_border_width(). (#143309, Doug Quale)
|
||||
|
||||
Fri May 7 01:36:30 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gdk-pixbuf/gdk-pixbuf-csource.xml: Add an "Environment"
|
||||
section. (Jens Elkner)
|
||||
|
||||
Fri May 7 01:23:03 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gtk/tmpl/gtkicontheme.sgml: Fix example. (Steffen Röcker)
|
||||
|
||||
2004-05-04 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* gtk/tmpl/gtkuimanager.sgml: Fixes to the DTD.
|
||||
|
||||
@@ -57,7 +57,7 @@ content_files = \
|
||||
gdk-pixbuf-query-loaders.xml
|
||||
|
||||
# Images to copy into HTML directory
|
||||
HTML_IMAGES =
|
||||
HTML_IMAGES = composite.png
|
||||
|
||||
# Extra options to supply to gtkdoc-fixref
|
||||
FIXXREF_OPTIONS=
|
||||
@@ -65,7 +65,12 @@ FIXXREF_OPTIONS=
|
||||
include $(top_srcdir)/gtk-doc.make
|
||||
|
||||
# Other files to distribute
|
||||
EXTRA_DIST += version.xml.in
|
||||
EXTRA_DIST += version.xml.in \
|
||||
composite.png \
|
||||
composite.dia \
|
||||
apple-red-1a.png \
|
||||
apple-red-2c.png \
|
||||
gnome-gmush-1.png
|
||||
|
||||
########################################################################
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 104 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
@@ -155,7 +155,7 @@ ratio.
|
||||
Defines the reference point of a window and the meaning of coordinates
|
||||
passed to gtk_window_move(). See gtk_window_move() and the "implementation
|
||||
notes" section of the
|
||||
<ulink url="http://www.freedesktop.org/standards/wm-spec.html">extended
|
||||
<ulink url="http://www.freedesktop.org/standards/wm-spec">extended
|
||||
window manager hints</ulink> specification for more details.
|
||||
</para>
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ content_files = \
|
||||
changes-2.0.sgml \
|
||||
compiling.sgml \
|
||||
framebuffer.sgml \
|
||||
glossary.xml \
|
||||
migrating-checklist.sgml \
|
||||
migrating-GtkAction.sgml \
|
||||
migrating-GtkComboBox.sgml \
|
||||
|
||||
@@ -134,7 +134,7 @@ How to compile GTK+ itself
|
||||
<listitem>
|
||||
<para>
|
||||
<ulink
|
||||
url="http://www.freedesktop.org/software/pkgconfig/">pkg-config</ulink>
|
||||
url="http://www.freedesktop.org/software/pkgconfig">pkg-config</ulink>
|
||||
is a tool for tracking the compilation flags needed for
|
||||
libraries that are used by the GTK+ libraries. (For each
|
||||
library, a small <literal>.pc</literal> text file is installed in a standard
|
||||
|
||||
@@ -0,0 +1,307 @@
|
||||
<glossary id="glossary">
|
||||
<title>Glossary</title>
|
||||
|
||||
<glossentry id="allocation">
|
||||
<glossterm>allocation</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
The final size of a <glossterm
|
||||
linkend="widget">widget</glossterm> within its <glossterm
|
||||
linkend="parent">parent</glossterm>. For example, a widget
|
||||
may request a minimum size of 20×20 pixels, but its
|
||||
parent may decide to allocate 50×20 pixels for it
|
||||
instead.
|
||||
</para>
|
||||
<glossseealso>
|
||||
<glossterm linkend="requisition">requisition</glossterm>
|
||||
</glossseealso>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="bin">
|
||||
<glossterm>bin</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
A <glossterm linkend="container">container</glossterm> that
|
||||
can hold at most one child widget. The base class for bins is
|
||||
<link linkend="GtkBin">GtkBin</link>.
|
||||
</para>
|
||||
<glossseealso>
|
||||
<glossterm linkend="container">container</glossterm>
|
||||
</glossseealso>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="child">
|
||||
<glossterm>child</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
A <glossterm linkend="container">container's</glossterm> child
|
||||
is a <glossterm linkend="widget">widget</glossterm> contained
|
||||
inside it.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="column">
|
||||
<glossterm>column</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
FIXME
|
||||
</para>
|
||||
<glossseealso>model column</glossseealso>
|
||||
<glossseealso>view column</glossseealso>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="container">
|
||||
<glossterm>container</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
A <glossterm linkend="widget">widget</glossterm> that contains
|
||||
other widgets; in that case, the container is the
|
||||
<emphasis>parent</emphasis> of the <emphasis>child</emphasis>
|
||||
widgets. Some containers don't draw anything on their own,
|
||||
but rather just organize their children's <glossterm
|
||||
linkend="geometry">geometry</glossterm>; for example, <link
|
||||
linkend="GtkVBox">GtkVBox</link> lays out its children
|
||||
vertically without painting anything on its own. Other
|
||||
containers include decorative elements; for example, <link
|
||||
linkend="GtkFrame">GtkFrame</link> contains the frame's child
|
||||
and a label in addition to the shaded frame it draws. The
|
||||
base class for containers is <link
|
||||
linkend="GtkContainer">GtkContainer</link>.
|
||||
</para>
|
||||
<glossseealso>
|
||||
<glossterm linkend="container">widget</glossterm>
|
||||
<glossterm linkend="container">geometry</glossterm>
|
||||
</glossseealso>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="display">
|
||||
<glossterm>display</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
FIXME
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="event">
|
||||
<glossterm>event</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
FIXME
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="geometry">
|
||||
<glossterm>geometry</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
A <glossterm linkend="widget">widget's</glossterm> position
|
||||
and size. Within its parent, this is called the widget's
|
||||
<glossterm linkend="allocation">allocation</glossterm>.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="mapping">
|
||||
<glossterm>mapping</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
This is the step in a <glossterm
|
||||
linkend="widget">widget's</glossterm> life cycle where it
|
||||
actually shows the GdkWindows it created when it was
|
||||
<glossterm linkend="realization">realized</glossterm>. When a
|
||||
widget is mapped, it must turn on its
|
||||
<constant>GTK_MAPPED</constant> <link
|
||||
linkend="GtkWidgetFlags">flag</link>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Note that due to the asynchronous nature of the X window
|
||||
system, a widget's window may not appear on the screen
|
||||
immediatly after one calls <link
|
||||
linkend="gdk-window-show"><function>gdk_window_show()</function></link>:
|
||||
you must wait for the corresponding map <glossterm
|
||||
linkend="event">event</glossterm> to be received. You can do
|
||||
this with the <link
|
||||
linkend="GtkWidget-map-event"><methodname>GtkWidget::map-event</methodname>
|
||||
signal</link>.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="model-column">
|
||||
<glossterm>model column</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
FIXME
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="no-window">
|
||||
<glossterm>no-window widget</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
A widget that does not have a GdkWindow of its own on which to
|
||||
draw its contents, but rather shares its <glossterm
|
||||
linkend="parent">parent's</glossterm>. Such a widget has the
|
||||
<constant>GTK_NO_WINDOW</constant> <link
|
||||
linkend="GtkWidgetFlags">flag</link> set, and can be tested
|
||||
with the <link
|
||||
linkend="gtk-widget-no-window-caps"><function>GTK_WIDGET_NO_WINDOW()</function></link>
|
||||
macro.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="parent">
|
||||
<glossterm>parent</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
A <glossterm linkend="widget">widget's</glossterm> parent is
|
||||
the <glossterm linkend="container">container</glossterm>
|
||||
inside which it resides.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="realization">
|
||||
<glossterm>realization</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
This is the step in a <glossterm
|
||||
linkend="widget">widget's</glossterm> life cycle where it
|
||||
creates its own GdkWindow, or otherwise associates itself with
|
||||
its <glossterm linkend="parent">parent's</glossterm>
|
||||
GdkWindow. If the widget has its own window, then it must
|
||||
also attach a <glossterm linkend="style">style</glossterm> to
|
||||
it. A widget becomes unrealized by destroying its associated
|
||||
GdkWindow. When a widget is realized, it must turn on its
|
||||
<constant>GTK_REALIZED</constant> <link
|
||||
linkend="GtkWidgetFlags">flag</link>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Widgets that don't own the GdkWindow on which they draw are
|
||||
called <glossterm linkend="no-window">no-window
|
||||
widgets</glossterm>. This can be tested with the <link
|
||||
linkend="gtk-widget-no-window-caps"><function>GTK_WIDGET_NO_WINDOW()</function></link>
|
||||
macro. Normally, these widgets draw on their parent's
|
||||
GdkWindow.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Note that when a widget creates a window in its <link
|
||||
linkend="gtkwidget-realize"><methodname>::realize()</methodname></link>
|
||||
handler, it does not actually show the window. That is, the
|
||||
window's structure is just created in memory. The widget
|
||||
actually shows the window when it gets <glossterm
|
||||
linkend="mapping">mapped</glossterm>.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="requisition">
|
||||
<glossterm>requisition</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
The size requisition of a <glossterm
|
||||
linkend="widget">widget</glossterm> is the minimum amount of
|
||||
space it requests from its <glossterm
|
||||
linkend="parent">parent</glossterm>. Once the parent computes
|
||||
the widget's final size, it gives it its <glossterm
|
||||
linkend="allocation">size allocation</glossterm>.
|
||||
</para>
|
||||
<glossseealso>
|
||||
<glossterm linkend="allocation">allocation</glossterm>
|
||||
</glossseealso>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="screen">
|
||||
<glossterm>screen</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
FIXME
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="style">
|
||||
<glossterm>style</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
FIXME
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="toplevel">
|
||||
<glossterm>toplevel</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
A <glossterm linkend="widget">widget</glossterm> that does not
|
||||
require a <glossterm linkend="parent">parent</glossterm>
|
||||
container. The only toplevel widget in GTK+ is <link
|
||||
linkend="GtkWindow">GtkWindow</link>.
|
||||
</para>
|
||||
<glossseealso>
|
||||
<glossterm linkend="container">container</glossterm>
|
||||
</glossseealso>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="unmap">
|
||||
<glossterm>unmap</glossterm>
|
||||
<glosssee><glossterm linkend="mapping">mapping</glossterm></glosssee>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="unrealize">
|
||||
<glossterm>unrealize</glossterm>
|
||||
<glosssee><glossterm linkend="realization">realization</glossterm></glosssee>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="view-column">
|
||||
<glossterm>view column</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
FIXME
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id="widget">
|
||||
<glossterm>widget</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
A control in a graphical user interface. Widgets can draw
|
||||
themselves and process events from the mouse and keyboard.
|
||||
Widget types include buttons, menus, text entry lines, and
|
||||
lists. Widgets can be arranged into <glossterm
|
||||
linkend="container">containers</glossterm>, and these take
|
||||
care of assigning the <glossterm
|
||||
linkend="geometry">geometry</glossterm> of the widgets: every
|
||||
widget thus has a parent except those widgets which are
|
||||
<glossterm linkend="toplevel">toplevels</glossterm>. The base
|
||||
class for widgets is <link
|
||||
linkend="GtkWidget">GtkWidget</link>.
|
||||
</para>
|
||||
<glossseealso>
|
||||
<glossterm linkend="container">container</glossterm>
|
||||
</glossseealso>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossary>
|
||||
|
||||
<!--
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document: ("gtk-docs.sgml" "book" "glossary")
|
||||
End:
|
||||
-->
|
||||
@@ -185,6 +185,7 @@
|
||||
<!ENTITY gtk-migrating-GtkComboBox SYSTEM "migrating-GtkComboBox.sgml">
|
||||
<!ENTITY version SYSTEM "version.xml">
|
||||
<!ENTITY gtk-query-immodules SYSTEM "gtk-query-immodules-2.0.xml">
|
||||
<!ENTITY gtk-glossary SYSTEM "glossary.xml">
|
||||
]>
|
||||
<book id="index">
|
||||
<bookinfo>
|
||||
@@ -557,6 +558,8 @@ that is, GUI components such as <link linkend="GtkButton">GtkButton</link> or
|
||||
>k-query-immodules;
|
||||
</part>
|
||||
|
||||
>k-glossary;
|
||||
|
||||
<index/>
|
||||
|
||||
</book>
|
||||
|
||||
@@ -4496,6 +4496,7 @@ gtk_window_group_get_type
|
||||
gtk_set_locale
|
||||
gtk_disable_setlocale
|
||||
gtk_get_default_language
|
||||
gtk_parse_args
|
||||
gtk_init
|
||||
gtk_init_check
|
||||
gtk_exit
|
||||
|
||||
@@ -118,6 +118,8 @@ a widget used to choose from a list of items.
|
||||
</para>
|
||||
|
||||
@combo_box:
|
||||
@index_:
|
||||
<!-- # Unused Parameters # -->
|
||||
@index:
|
||||
|
||||
|
||||
|
||||
@@ -168,10 +168,10 @@ changes, use gtk_widget_child_notify().
|
||||
|
||||
<!-- ##### MACRO gtk_container_border_width ##### -->
|
||||
<para>
|
||||
Does the same as gtk_container_get_border_width().
|
||||
Does the same as gtk_container_set_border_width().
|
||||
</para>
|
||||
|
||||
@Deprecated: Use gtk_container_get_border_width() instead.
|
||||
@Deprecated: Use gtk_container_set_border_width() instead.
|
||||
|
||||
|
||||
<!-- ##### FUNCTION gtk_container_add ##### -->
|
||||
|
||||
@@ -170,8 +170,10 @@ A function which decides whether the row indicated by @iter matches a given
|
||||
</para>
|
||||
|
||||
@completion:
|
||||
@index:
|
||||
@index_:
|
||||
@text:
|
||||
<!-- # Unused Parameters # -->
|
||||
@index:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION gtk_entry_completion_insert_action_markup ##### -->
|
||||
@@ -180,8 +182,10 @@ A function which decides whether the row indicated by @iter matches a given
|
||||
</para>
|
||||
|
||||
@completion:
|
||||
@index:
|
||||
@index_:
|
||||
@markup:
|
||||
<!-- # Unused Parameters # -->
|
||||
@index:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION gtk_entry_completion_delete_action ##### -->
|
||||
@@ -190,6 +194,8 @@ A function which decides whether the row indicated by @iter matches a given
|
||||
</para>
|
||||
|
||||
@completion:
|
||||
@index_:
|
||||
<!-- # Unused Parameters # -->
|
||||
@index:
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ providing a filename is to allow different icons to be used
|
||||
depending on what <firstterm>icon theme</firstterm> is selecetd
|
||||
by the user. The operation of icon themes on Linux and Unix
|
||||
follows the <ulink
|
||||
url="http://www.freedesktop.org/standards/icon-theme-spec.html">Icon
|
||||
url="http://www.freedesktop.org/standards/icon-theme-spec">Icon
|
||||
Theme Specification</ulink>. There is a default icon theme,
|
||||
named <literal>hicolor</literal> where applications should install
|
||||
their icons, but more additional application themes can be
|
||||
@@ -80,7 +80,8 @@ icon_theme = gtk_icon_theme_get_default ();
|
||||
pixbuf = gtk_icon_theme_load_icon (icon_theme,
|
||||
"my-icon-name", /* icon name */
|
||||
48, /* size */
|
||||
0, /* flags */);
|
||||
0, /* flags */
|
||||
&error);
|
||||
if (!pixbuf)
|
||||
{
|
||||
g_warning ("Couldn't load icon: %s", error->message);
|
||||
|
||||
@@ -104,6 +104,16 @@ functions such as g_signal_connect().
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION gtk_parse_args ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@argc:
|
||||
@argv:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION gtk_init ##### -->
|
||||
<para>
|
||||
</para>
|
||||
|
||||
@@ -73,7 +73,7 @@ outermost to innermost. The difference is that in
|
||||
the widget path, the name assigned by
|
||||
gtk_widget_set_name() is used
|
||||
if present, otherwise the class name of the widget, while
|
||||
for the widget path, the class name is always used.
|
||||
for the class path, the class name is always used.
|
||||
</para>
|
||||
<para>
|
||||
So, if you have a #GtkEntry named
|
||||
|
||||
@@ -64,7 +64,7 @@ is running.
|
||||
|
||||
<para>
|
||||
The communication between a #GtkSocket and a #GtkPlug follows the
|
||||
<ulink url="http://www.freedesktop.org/standards/xembed.html">XEmbed</ulink>
|
||||
<ulink url="http://www.freedesktop.org/standards/xembed-spec">XEmbed</ulink>
|
||||
protocol. This protocol has also been implemented in other toolkits, e.g.
|
||||
<application>Qt</application>, allowing the same level of integration
|
||||
when embedding a <application>Qt</application> widget in GTK or vice versa.</para>
|
||||
@@ -85,7 +85,7 @@ as between a #GtkPlug and a #GtkSocket.</para>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><ulink url="http://www.freedesktop.org/standards/xembed.html">XEmbed</ulink></term>
|
||||
<term><ulink url="http://www.freedesktop.org/standards/xembed-spec">XEmbed</ulink></term>
|
||||
<listitem><para>the XEmbed Protocol Specification.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
@@ -210,7 +210,7 @@ and row numbers of the table. (Columns and rows are indexed from zero).
|
||||
|
||||
<!-- ##### FUNCTION gtk_table_attach_defaults ##### -->
|
||||
<para>
|
||||
As there are many options associated with gtk_table_attach(), this convenience function provides the programmer with a means to add children to a table with identical padding and expansion options.
|
||||
As there are many options associated with gtk_table_attach(), this convenience function provides the programmer with a means to add children to a table with identical padding and expansion options. The values used for the #GtkAttachOptions are <literal>GTK_EXPAND | GTK_FILL</literal>, and the padding is set to 0.
|
||||
</para>
|
||||
|
||||
@table: The table to add a new child widget to.
|
||||
|
||||
@@ -244,6 +244,8 @@ to a #GtkToolbar.
|
||||
|
||||
@toolbar:
|
||||
@tool_item:
|
||||
@index_:
|
||||
<!-- # Unused Parameters # -->
|
||||
@index:
|
||||
|
||||
|
||||
|
||||
@@ -55,8 +55,9 @@ The GtkTreeModelFilter struct contains only private fields.
|
||||
A function which decides whether the row indicated by @iter is visible.
|
||||
</para>
|
||||
|
||||
@model: the #GtkTreeModelFilter
|
||||
@iter: a #GtkTreeIter pointing to the row whose visibility is determined
|
||||
@model: the child model of the #GtkTreeModelFilter
|
||||
@iter: a #GtkTreeIter pointing to the row in @model whose visibility
|
||||
is determined
|
||||
@data: user data given to gtk_tree_model_filter_set_visible_func()
|
||||
@Returns: Whether the row indicated by @iter is visible.
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<!-- ##### SECTION Title ##### -->
|
||||
|
||||
GtkUIManager
|
||||
|
||||
<!-- ##### SECTION Short_Description ##### -->
|
||||
@@ -51,9 +52,15 @@ There are some additional restrictions beyond those specified in the
|
||||
DTD, e.g. every toolitem must have a toolbar in its anchestry and
|
||||
every menuitem must have a menubar or popup in its anchestry. Since
|
||||
a #GMarkup parser is used to parse the UI description, it must not only
|
||||
be valid XML, but valid #GMarkup. If a name is not specified, it defaults
|
||||
to the action. If an action is not specified either, the element name is
|
||||
used.
|
||||
be valid XML, but valid #GMarkup.
|
||||
</para>
|
||||
<para>
|
||||
If a name is not specified, it defaults to the action. If an action is
|
||||
not specified either, the element name is used. The name and action
|
||||
attributes must not contain '/' characters after parsing (since that
|
||||
would mess up path lookup) and must be usable as XML attributes when
|
||||
enclosed in doublequotes, thus they must not '"' characters or references
|
||||
to the &quot; entity.
|
||||
</para>
|
||||
<example>
|
||||
<title>A UI definition</title>
|
||||
|
||||
@@ -271,6 +271,11 @@ GtkButton
|
||||
|
||||
=====================
|
||||
|
||||
NOTE: Due to a bug that is basically unfixable in a sufficiently compatible
|
||||
NOTE: way, the button gives the space requested for focus_width and
|
||||
NOTE: focus_padding to the child (in addition to the space requested by
|
||||
NOTE: the child), if the button is !CAN_FOCUS.
|
||||
|
||||
Style properties
|
||||
|
||||
GtkWidget::interior_focus = TRUE
|
||||
|
||||
@@ -1,3 +1,88 @@
|
||||
2004-08-13 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* === Released 2.4.6 ===
|
||||
|
||||
Thu Aug 12 22:19:12 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* io-bmp.c (DecodeHeader): Properly determine the number of
|
||||
colors in an OS/2 BMP file. (#150003, Jon-Kare Hellan)
|
||||
|
||||
2004-08-12 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* pixops/pixops.c: Remove C99-isms. (#149967, Vincent Noel)
|
||||
|
||||
2004-08-11 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* pixops/pixops.c: Make scaling and compositing functions handle
|
||||
edge pixels consistently. (#111922, Brian Cameron)
|
||||
|
||||
Sun Aug 1 23:57:06 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* io-pcx.c (pcx_increment_load_data_1): Fix progressive
|
||||
loading of 8bit pcx files. (#148518, Magnus Bergman)
|
||||
|
||||
Tue Jul 20 22:23:26 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gdk-pixbuf-io.h: Remove trailing commas from
|
||||
enumerations. (#148035)
|
||||
|
||||
2004-07-10 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* === Released 2.4.4 ===
|
||||
|
||||
2004-07-07 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* gdk-pixbuf-features.h.in: Fix the build.
|
||||
|
||||
2004-07-06 Tor Lillqvist <tml@iki.fi>
|
||||
|
||||
* gdk-pixbuf-features.h.in
|
||||
* gdk-pixbuf.c: Mark the version variables for proper import and
|
||||
export from Windows DLLs. Thanks to Laurent Sansonetti for
|
||||
reporting the problem.
|
||||
|
||||
Sat Jul 3 00:41:44 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* pixops/pixops.c (bilinear_box_make_weights): Correct the
|
||||
math to calculate bilinear weights. (#112412, Brian Cameron)
|
||||
|
||||
Sun Jun 20 00:16:00 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gdk-pixbuf-scale.c (gdk_pixbuf_composite): Add a figure which
|
||||
explains pixbuf compositing.
|
||||
|
||||
2004-06-16 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* io-tiff.c: Make the tiff loader work with both
|
||||
libtiff 3.5.7 and libtiff 3.6.1. (#135541, Marco Ghirlanda)
|
||||
|
||||
2004-06-11 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* === Released 2.4.3 ===
|
||||
|
||||
Sat Jun 5 00:59:12 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gdk-pixbuf-animation.c:
|
||||
* gdk-pixbuf-io.c: Convert filenames to UTF-8 when embedding
|
||||
them in error messages. (#143654, Sven Neumann)
|
||||
|
||||
2004-06-04 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* === Released 2.4.2 ===
|
||||
|
||||
Sun May 16 22:55:49 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* io-pnm.c (pnm_read_next_value): Don't read integers
|
||||
partially. (#142584, Kouichirou Hiratsuka)
|
||||
|
||||
2004-05-10 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* pixops/timescale.c:
|
||||
* pixops/pixops.c:
|
||||
* pixops/pixops.h:
|
||||
* gdk-pixbuf-scale.c: _-prefix the nonstatic pixops_...
|
||||
functions. (#142233, Morten Welinder)
|
||||
|
||||
2004-04-30 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* === Released 2.4.1 ===
|
||||
|
||||
@@ -135,28 +135,36 @@ gdk_pixbuf_animation_new_from_file (const char *filename,
|
||||
FILE *f;
|
||||
guchar buffer [128];
|
||||
GdkPixbufModule *image_module;
|
||||
gchar *utf8_filename;
|
||||
|
||||
g_return_val_if_fail (filename != NULL, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
f = fopen (filename, "rb");
|
||||
if (!f) {
|
||||
utf8_filename = g_filename_to_utf8 (filename, -1,
|
||||
NULL, NULL, NULL);
|
||||
g_set_error (error,
|
||||
G_FILE_ERROR,
|
||||
g_file_error_from_errno (errno),
|
||||
_("Failed to open file '%s': %s"),
|
||||
filename, g_strerror (errno));
|
||||
utf8_filename ? utf8_filename : "???",
|
||||
g_strerror (errno));
|
||||
g_free (utf8_filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = fread (&buffer, 1, sizeof (buffer), f);
|
||||
|
||||
if (size == 0) {
|
||||
utf8_filename = g_filename_to_utf8 (filename, -1,
|
||||
NULL, NULL, NULL);
|
||||
g_set_error (error,
|
||||
GDK_PIXBUF_ERROR,
|
||||
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
|
||||
_("Image file '%s' contains no data"),
|
||||
filename);
|
||||
utf8_filename ? utf8_filename : "???");
|
||||
g_free (utf8_filename);
|
||||
|
||||
fclose (f);
|
||||
return NULL;
|
||||
@@ -192,11 +200,14 @@ gdk_pixbuf_animation_new_from_file (const char *filename,
|
||||
|
||||
g_warning ("Bug! gdk-pixbuf loader '%s' didn't set an error on failure.",
|
||||
image_module->module_name);
|
||||
utf8_filename = g_filename_to_utf8 (filename, -1,
|
||||
NULL, NULL, NULL);
|
||||
g_set_error (error,
|
||||
GDK_PIXBUF_ERROR,
|
||||
GDK_PIXBUF_ERROR_FAILED,
|
||||
_("Failed to load image '%s': reason not known, probably a corrupt image file"),
|
||||
filename);
|
||||
utf8_filename ? utf8_filename : "???");
|
||||
g_free (utf8_filename);
|
||||
}
|
||||
|
||||
if (pixbuf == NULL)
|
||||
@@ -220,11 +231,14 @@ gdk_pixbuf_animation_new_from_file (const char *filename,
|
||||
|
||||
g_warning ("Bug! gdk-pixbuf loader '%s' didn't set an error on failure.",
|
||||
image_module->module_name);
|
||||
utf8_filename = g_filename_to_utf8 (filename, -1,
|
||||
NULL, NULL, NULL);
|
||||
g_set_error (error,
|
||||
GDK_PIXBUF_ERROR,
|
||||
GDK_PIXBUF_ERROR_FAILED,
|
||||
_("Failed to load animation '%s': reason not known, probably a corrupt animation file"),
|
||||
filename);
|
||||
utf8_filename ? utf8_filename : "???");
|
||||
g_free (utf8_filename);
|
||||
}
|
||||
|
||||
fclose (f);
|
||||
|
||||
@@ -6,7 +6,34 @@
|
||||
#define GDK_PIXBUF_MICRO (@GDK_PIXBUF_MICRO@)
|
||||
#define GDK_PIXBUF_VERSION "@GDK_PIXBUF_VERSION@"
|
||||
|
||||
extern const guint gdk_pixbuf_major_version, gdk_pixbuf_minor_version, gdk_pixbuf_micro_version;
|
||||
extern const char *gdk_pixbuf_version;
|
||||
/* We prefix variable declarations so they can
|
||||
* properly get exported/imported from Windows DLLs.
|
||||
*/
|
||||
#ifndef GDK_PIXBUF_VAR
|
||||
# ifdef G_PLATFORM_WIN32
|
||||
# ifdef GDK_PIXBUF_STATIC_COMPILATION
|
||||
# define GDK_PIXBUF_VAR extern
|
||||
# else /* !GDK_PIXBUF_STATIC_COMPILATION */
|
||||
# ifdef GDK_PIXBUF_COMPILATION
|
||||
# ifdef DLL_EXPORT
|
||||
# define GDK_PIXBUF_VAR __declspec(dllexport)
|
||||
# else /* !DLL_EXPORT */
|
||||
# define GDK_PIXBUF_VAR extern
|
||||
# endif /* !DLL_EXPORT */
|
||||
# else /* !GDK_PIXBUF_COMPILATION */
|
||||
# define GDK_PIXBUF_VAR extern __declspec(dllimport)
|
||||
# endif /* !GDK_PIXBUF_COMPILATION */
|
||||
# endif /* !GDK_PIXBUF_STATIC_COMPILATION */
|
||||
# else /* !G_PLATFORM_WIN32 */
|
||||
# ifndef GDK_PIXBUF_COMPILATION
|
||||
# define GDK_PIXBUF_VAR extern
|
||||
# else
|
||||
# define GDK_PIXBUF_VAR
|
||||
# endif /* !GDK_PIXBUF_COMPILATION */
|
||||
# endif /* !G_PLATFORM_WIN32 */
|
||||
#endif /* GDK_PIXBUF_VAR */
|
||||
|
||||
GDK_PIXBUF_VAR const guint gdk_pixbuf_major_version, gdk_pixbuf_minor_version, gdk_pixbuf_micro_version;
|
||||
GDK_PIXBUF_VAR const char *gdk_pixbuf_version;
|
||||
|
||||
#endif
|
||||
|
||||
+62
-23
@@ -637,6 +637,8 @@ _gdk_pixbuf_get_module (guchar *buffer, guint size,
|
||||
|
||||
gint score, best = 0;
|
||||
GdkPixbufModule *selected = NULL;
|
||||
gchar *utf8_filename = NULL;
|
||||
|
||||
for (modules = get_file_formats (); modules; modules = g_slist_next (modules)) {
|
||||
GdkPixbufModule *module = (GdkPixbufModule *)modules->data;
|
||||
score = format_check (module, buffer, size);
|
||||
@@ -651,18 +653,24 @@ _gdk_pixbuf_get_module (guchar *buffer, guint size,
|
||||
return selected;
|
||||
|
||||
if (filename)
|
||||
g_set_error (error,
|
||||
GDK_PIXBUF_ERROR,
|
||||
GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
|
||||
_("Couldn't recognize the image file format for file '%s'"),
|
||||
filename);
|
||||
utf8_filename = g_filename_to_utf8 (filename, -1,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
if (utf8_filename) {
|
||||
g_set_error (error,
|
||||
GDK_PIXBUF_ERROR,
|
||||
GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
|
||||
_("Couldn't recognize the image file format for file '%s'"),
|
||||
utf8_filename);
|
||||
g_free (utf8_filename);
|
||||
}
|
||||
else
|
||||
g_set_error (error,
|
||||
GDK_PIXBUF_ERROR,
|
||||
GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
|
||||
_("Unrecognized image file format"));
|
||||
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -763,22 +771,28 @@ gdk_pixbuf_new_from_file (const char *filename,
|
||||
|
||||
f = fopen (filename, "rb");
|
||||
if (!f) {
|
||||
gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
|
||||
NULL, NULL, NULL);
|
||||
g_set_error (error,
|
||||
G_FILE_ERROR,
|
||||
g_file_error_from_errno (errno),
|
||||
_("Failed to open file '%s': %s"),
|
||||
filename, g_strerror (errno));
|
||||
utf8_filename ? utf8_filename : "???",
|
||||
g_strerror (errno));
|
||||
g_free (utf8_filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = fread (&buffer, 1, sizeof (buffer), f);
|
||||
if (size == 0) {
|
||||
gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
|
||||
NULL, NULL, NULL);
|
||||
g_set_error (error,
|
||||
GDK_PIXBUF_ERROR,
|
||||
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
|
||||
_("Image file '%s' contains no data"),
|
||||
filename);
|
||||
|
||||
utf8_filename ? utf8_filename : "???");
|
||||
g_free (utf8_filename);
|
||||
fclose (f);
|
||||
return NULL;
|
||||
}
|
||||
@@ -800,33 +814,41 @@ gdk_pixbuf_new_from_file (const char *filename,
|
||||
fclose (f);
|
||||
|
||||
if (pixbuf == NULL && error != NULL && *error == NULL) {
|
||||
|
||||
/* I don't trust these crufty longjmp()'ing image libs
|
||||
* to maintain proper error invariants, and I don't
|
||||
* want user code to segfault as a result. We need to maintain
|
||||
* the invariastable/gdk-pixbuf/nt that error gets set if NULL is returned.
|
||||
* the invariant that error gets set if NULL is returned.
|
||||
*/
|
||||
|
||||
|
||||
gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
g_warning ("Bug! gdk-pixbuf loader '%s' didn't set an error on failure.", image_module->module_name);
|
||||
g_set_error (error,
|
||||
GDK_PIXBUF_ERROR,
|
||||
GDK_PIXBUF_ERROR_FAILED,
|
||||
_("Failed to load image '%s': reason not known, probably a corrupt image file"),
|
||||
filename);
|
||||
|
||||
utf8_filename ? utf8_filename : "???");
|
||||
g_free (utf8_filename);
|
||||
} else if (error != NULL && *error != NULL) {
|
||||
|
||||
/* Add the filename to the error message */
|
||||
GError *e = *error;
|
||||
gchar *old;
|
||||
|
||||
gchar *old;
|
||||
gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
old = e->message;
|
||||
|
||||
e->message = g_strdup_printf (_("Failed to load image '%s': %s"),
|
||||
filename, old);
|
||||
utf8_filename ? utf8_filename : "???",
|
||||
old);
|
||||
|
||||
g_free (utf8_filename);
|
||||
g_free (old);
|
||||
}
|
||||
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
@@ -896,11 +918,15 @@ gdk_pixbuf_new_from_file_at_size (const char *filename,
|
||||
|
||||
f = fopen (filename, "rb");
|
||||
if (!f) {
|
||||
gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
|
||||
NULL, NULL, NULL);
|
||||
g_set_error (error,
|
||||
G_FILE_ERROR,
|
||||
g_file_error_from_errno (errno),
|
||||
_("Failed to open file '%s': %s"),
|
||||
filename, g_strerror (errno));
|
||||
utf8_filename ? utf8_filename : "???",
|
||||
g_strerror (errno));
|
||||
g_free (utf8_filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -908,7 +934,7 @@ gdk_pixbuf_new_from_file_at_size (const char *filename,
|
||||
|
||||
info.width = width;
|
||||
info.height = height;
|
||||
|
||||
|
||||
g_signal_connect (loader, "size-prepared", G_CALLBACK (size_prepared_cb), &info);
|
||||
|
||||
while (!feof (f) && !ferror (f)) {
|
||||
@@ -932,12 +958,17 @@ gdk_pixbuf_new_from_file_at_size (const char *filename,
|
||||
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
|
||||
|
||||
if (!pixbuf) {
|
||||
gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
g_object_unref (loader);
|
||||
g_set_error (error,
|
||||
|
||||
g_set_error (error,
|
||||
GDK_PIXBUF_ERROR,
|
||||
GDK_PIXBUF_ERROR_FAILED,
|
||||
_("Failed to load image '%s': reason not known, probably a corrupt image file"),
|
||||
filename);
|
||||
utf8_filename ? utf8_filename : "???");
|
||||
g_free (utf8_filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1405,11 +1436,15 @@ gdk_pixbuf_savev (GdkPixbuf *pixbuf,
|
||||
f = fopen (filename, "wb");
|
||||
|
||||
if (f == NULL) {
|
||||
gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
|
||||
NULL, NULL, NULL);
|
||||
g_set_error (error,
|
||||
G_FILE_ERROR,
|
||||
g_file_error_from_errno (errno),
|
||||
_("Failed to open '%s' for writing: %s"),
|
||||
filename, g_strerror (errno));
|
||||
utf8_filename ? utf8_filename : "???",
|
||||
g_strerror (errno));
|
||||
g_free (utf8_filename);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1426,11 +1461,15 @@ gdk_pixbuf_savev (GdkPixbuf *pixbuf,
|
||||
}
|
||||
|
||||
if (fclose (f) < 0) {
|
||||
gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
|
||||
NULL, NULL, NULL);
|
||||
g_set_error (error,
|
||||
G_FILE_ERROR,
|
||||
g_file_error_from_errno (errno),
|
||||
_("Failed to close '%s' while writing image, all data may not have been saved: %s"),
|
||||
filename, g_strerror (errno));
|
||||
utf8_filename ? utf8_filename : "???",
|
||||
g_strerror (errno));
|
||||
g_free (utf8_filename);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ gboolean gdk_pixbuf_set_option (GdkPixbuf *pixbuf,
|
||||
|
||||
typedef enum /*< skip >*/
|
||||
{
|
||||
GDK_PIXBUF_FORMAT_WRITABLE = 1 << 0,
|
||||
GDK_PIXBUF_FORMAT_WRITABLE = 1 << 0
|
||||
} GdkPixbufFormatFlags;
|
||||
|
||||
struct _GdkPixbufFormat {
|
||||
|
||||
@@ -72,13 +72,13 @@ gdk_pixbuf_scale (const GdkPixbuf *src,
|
||||
offset_x = floor (offset_x + 0.5);
|
||||
offset_y = floor (offset_y + 0.5);
|
||||
|
||||
pixops_scale (dest->pixels + dest_y * dest->rowstride + dest_x * dest->n_channels,
|
||||
dest_x - offset_x, dest_y - offset_y,
|
||||
dest_x + dest_width - offset_x, dest_y + dest_height - offset_y,
|
||||
dest->rowstride, dest->n_channels, dest->has_alpha,
|
||||
src->pixels, src->width, src->height,
|
||||
src->rowstride, src->n_channels, src->has_alpha,
|
||||
scale_x, scale_y, (PixopsInterpType)interp_type);
|
||||
_pixops_scale (dest->pixels + dest_y * dest->rowstride + dest_x * dest->n_channels,
|
||||
dest_x - offset_x, dest_y - offset_y,
|
||||
dest_x + dest_width - offset_x, dest_y + dest_height - offset_y,
|
||||
dest->rowstride, dest->n_channels, dest->has_alpha,
|
||||
src->pixels, src->width, src->height,
|
||||
src->rowstride, src->n_channels, src->has_alpha,
|
||||
scale_x, scale_y, (PixopsInterpType)interp_type);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,9 +97,20 @@ gdk_pixbuf_scale (const GdkPixbuf *src,
|
||||
* @overall_alpha: overall alpha for source image (0..255)
|
||||
*
|
||||
* Creates a transformation of the source image @src by scaling by
|
||||
* @scale_x and @scale_y then translating by @offset_x and @offset_y,
|
||||
* then composites the rectangle (@dest_x, @dest_y, @dest_width,
|
||||
* @dest_height) of the resulting image onto the destination image.
|
||||
* @scale_x and @scale_y then translating by @offset_x and @offset_y.
|
||||
* This gives an image in the coordinates of the destination pixbuf.
|
||||
* The rectangle (@dest_x, @dest_y, @dest_width, @dest_height)
|
||||
* is then composited onto the corresponding rectangle of the
|
||||
* original destination image.
|
||||
*
|
||||
* When the destination rectangle contains parts not in the source
|
||||
* image, the data at the edges of the source image is replicated
|
||||
* to infinity.
|
||||
*
|
||||
* <figure id="pixbuf-composite-diagram">
|
||||
* <title>Compositing of pixbufs</title>
|
||||
* <graphic fileref="composite.png" format="PNG"/>
|
||||
* </figure>
|
||||
**/
|
||||
void
|
||||
gdk_pixbuf_composite (const GdkPixbuf *src,
|
||||
@@ -123,13 +134,13 @@ gdk_pixbuf_composite (const GdkPixbuf *src,
|
||||
|
||||
offset_x = floor (offset_x + 0.5);
|
||||
offset_y = floor (offset_y + 0.5);
|
||||
pixops_composite (dest->pixels + dest_y * dest->rowstride + dest_x * dest->n_channels,
|
||||
dest_x - offset_x, dest_y - offset_y,
|
||||
dest_x + dest_width - offset_x, dest_y + dest_height - offset_y,
|
||||
dest->rowstride, dest->n_channels, dest->has_alpha,
|
||||
src->pixels, src->width, src->height,
|
||||
src->rowstride, src->n_channels, src->has_alpha,
|
||||
scale_x, scale_y, (PixopsInterpType)interp_type, overall_alpha);
|
||||
_pixops_composite (dest->pixels + dest_y * dest->rowstride + dest_x * dest->n_channels,
|
||||
dest_x - offset_x, dest_y - offset_y,
|
||||
dest_x + dest_width - offset_x, dest_y + dest_height - offset_y,
|
||||
dest->rowstride, dest->n_channels, dest->has_alpha,
|
||||
src->pixels, src->width, src->height,
|
||||
src->rowstride, src->n_channels, src->has_alpha,
|
||||
scale_x, scale_y, (PixopsInterpType)interp_type, overall_alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,14 +202,14 @@ gdk_pixbuf_composite_color (const GdkPixbuf *src,
|
||||
offset_x = floor (offset_x + 0.5);
|
||||
offset_y = floor (offset_y + 0.5);
|
||||
|
||||
pixops_composite_color (dest->pixels + dest_y * dest->rowstride + dest_x * dest->n_channels,
|
||||
dest_x - offset_x, dest_y - offset_y,
|
||||
dest_x + dest_width - offset_x, dest_y + dest_height - offset_y,
|
||||
dest->rowstride, dest->n_channels, dest->has_alpha,
|
||||
src->pixels, src->width, src->height,
|
||||
src->rowstride, src->n_channels, src->has_alpha,
|
||||
scale_x, scale_y, (PixopsInterpType)interp_type, overall_alpha, check_x, check_y,
|
||||
check_size, color1, color2);
|
||||
_pixops_composite_color (dest->pixels + dest_y * dest->rowstride + dest_x * dest->n_channels,
|
||||
dest_x - offset_x, dest_y - offset_y,
|
||||
dest_x + dest_width - offset_x, dest_y + dest_height - offset_y,
|
||||
dest->rowstride, dest->n_channels, dest->has_alpha,
|
||||
src->pixels, src->width, src->height,
|
||||
src->rowstride, src->n_channels, src->has_alpha,
|
||||
scale_x, scale_y, (PixopsInterpType)interp_type, overall_alpha, check_x, check_y,
|
||||
check_size, color1, color2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define GDK_PIXBUF_COMPILATION
|
||||
#include "gdk-pixbuf.h"
|
||||
#include "gdk-pixbuf-private.h"
|
||||
|
||||
@@ -518,11 +519,11 @@ gdk_pixbuf_get_rowstride (const GdkPixbuf *pixbuf)
|
||||
|
||||
|
||||
/* General initialization hooks */
|
||||
const guint gdk_pixbuf_major_version = GDK_PIXBUF_MAJOR;
|
||||
const guint gdk_pixbuf_minor_version = GDK_PIXBUF_MINOR;
|
||||
const guint gdk_pixbuf_micro_version = GDK_PIXBUF_MICRO;
|
||||
GDK_PIXBUF_VAR const guint gdk_pixbuf_major_version = GDK_PIXBUF_MAJOR;
|
||||
GDK_PIXBUF_VAR const guint gdk_pixbuf_minor_version = GDK_PIXBUF_MINOR;
|
||||
GDK_PIXBUF_VAR const guint gdk_pixbuf_micro_version = GDK_PIXBUF_MICRO;
|
||||
|
||||
const char *gdk_pixbuf_version = GDK_PIXBUF_VERSION;
|
||||
GDK_PIXBUF_VAR const char *gdk_pixbuf_version = GDK_PIXBUF_VERSION;
|
||||
|
||||
/* Error quark */
|
||||
GQuark
|
||||
|
||||
+5
-1
@@ -269,7 +269,11 @@ static gboolean DecodeHeader(unsigned char *BFH, unsigned char *BIH,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
clrUsed = (int) (BIH[35] << 24) + (BIH[34] << 16) + (BIH[33] << 8) + (BIH[32]);
|
||||
if (State->Header.size == 12)
|
||||
clrUsed = 1 << State->Header.depth;
|
||||
else
|
||||
clrUsed = (int) (BIH[35] << 24) + (BIH[34] << 16) + (BIH[33] << 8) + (BIH[32]);
|
||||
|
||||
if (clrUsed != 0)
|
||||
State->Header.n_colors = clrUsed;
|
||||
else
|
||||
|
||||
+1
-1
@@ -353,7 +353,7 @@ pcx_increment_load_data_1(struct pcx_context *context)
|
||||
}
|
||||
|
||||
if(context->updated_func)
|
||||
context->updated_func(context->pixbuf, 0, context->current_line, context->width, 1, context->user_data);
|
||||
context->updated_func(context->pixbuf, 0, 0, context->width, context->height, context->user_data);
|
||||
|
||||
context->current_line++;
|
||||
|
||||
|
||||
+1
-1
@@ -237,7 +237,7 @@ pnm_read_next_value (PnmIOBuffer *inbuf, guint *value, GError **error)
|
||||
*word = '\0';
|
||||
|
||||
/* hmmm, there must be more data to this 'word' */
|
||||
if (!g_ascii_isspace (*p) && (*p != '#') && (p - inptr < 128))
|
||||
if (p == inend || (!g_ascii_isspace (*p) && (*p != '#') && (p - inptr < 128)))
|
||||
return PNM_SUSPEND;
|
||||
|
||||
/* get the value */
|
||||
|
||||
+88
-67
@@ -145,34 +145,14 @@ static void free_buffer (guchar *pixels, gpointer data)
|
||||
g_free (pixels);
|
||||
}
|
||||
|
||||
static tileContigRoutine tiff_put_contig;
|
||||
static tileSeparateRoutine tiff_put_separate;
|
||||
|
||||
/* We're lucky that TIFFRGBAImage uses the same RGBA packing
|
||||
as gdk-pixbuf, thus we can simple reuse the default libtiff
|
||||
put routines, only adjusting the coordinate system.
|
||||
*/
|
||||
static void
|
||||
put_contig (TIFFRGBAImage *img, uint32 *raster,
|
||||
uint32 x, uint32 y, uint32 w, uint32 h,
|
||||
int32 fromskew, int32 toskew, unsigned char *cp)
|
||||
static gboolean tifflibversion (int *major, int *minor, int *revision)
|
||||
{
|
||||
uint32 *data = raster - y * img->width - x;
|
||||
if (sscanf (TIFFGetVersion(),
|
||||
"LIBTIFF, Version %d.%d.%d",
|
||||
major, minor, revision) < 3)
|
||||
return FALSE;
|
||||
|
||||
tiff_put_contig (img, data + img->width * (img->height - 1 - y) + x,
|
||||
x, y, w, h, fromskew, -toskew - 2*(int32)w, cp);
|
||||
}
|
||||
|
||||
static void
|
||||
put_separate (TIFFRGBAImage *img, uint32 *raster,
|
||||
uint32 x, uint32 y, uint32 w, uint32 h,
|
||||
int32 fromskew, int32 toskew,
|
||||
unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a)
|
||||
{
|
||||
uint32 *data = raster - y * img->width - x;
|
||||
|
||||
tiff_put_separate (img, data + img->width * (img->height - 1 - y) + x,
|
||||
x, y, w, h, fromskew, -toskew - 2*w, r, g, b, a);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GdkPixbuf *
|
||||
@@ -181,8 +161,9 @@ tiff_image_parse (TIFF *tiff, TiffContext *context, GError **error)
|
||||
guchar *pixels = NULL;
|
||||
gint width, height, rowstride, bytes;
|
||||
GdkPixbuf *pixbuf;
|
||||
TIFFRGBAImage img;
|
||||
gchar emsg[1024];
|
||||
#if TIFFLIB_VERSION >= 20031226
|
||||
gint major, minor, revision;
|
||||
#endif
|
||||
|
||||
/* We're called with the lock held. */
|
||||
|
||||
@@ -263,49 +244,89 @@ tiff_image_parse (TIFF *tiff, TiffContext *context, GError **error)
|
||||
if (context)
|
||||
(* context->prepare_func) (pixbuf, NULL, context->user_data);
|
||||
G_LOCK (tiff_loader);
|
||||
|
||||
if (!TIFFRGBAImageBegin (&img, tiff, 1, emsg) || global_error) {
|
||||
tiff_set_error (error,
|
||||
GDK_PIXBUF_ERROR_FAILED,
|
||||
_("Failed to load RGB data from TIFF file"));
|
||||
g_object_unref (pixbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (img.put.any == NULL) {
|
||||
tiff_set_error (error,
|
||||
GDK_PIXBUF_ERROR_FAILED,
|
||||
_("Unsupported TIFF variant"));
|
||||
g_object_unref (pixbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (img.isContig) {
|
||||
tiff_put_contig = img.put.contig;
|
||||
img.put.contig = put_contig;
|
||||
}
|
||||
else {
|
||||
tiff_put_separate = img.put.separate;
|
||||
img.put.separate = put_separate;
|
||||
}
|
||||
|
||||
TIFFRGBAImageGet (&img, (uint32 *)pixels, width, height);
|
||||
TIFFRGBAImageEnd (&img);
|
||||
#if TIFFLIB_VERSION >= 20031226
|
||||
if (tifflibversion(&major, &minor, &revision) && major == 3 &&
|
||||
(minor > 6 || (minor == 6 && revision > 0))) {
|
||||
if (!TIFFReadRGBAImageOriented (tiff, width, height, (uint32 *)pixels, ORIENTATION_TOPLEFT, 1) || global_error)
|
||||
{
|
||||
tiff_set_error (error,
|
||||
GDK_PIXBUF_ERROR_FAILED,
|
||||
_("Failed to load RGB data from TIFF file"));
|
||||
g_object_unref (pixbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
/* Turns out that the packing used by TIFFRGBAImage depends on the host byte order... */
|
||||
while (pixels < pixbuf->pixels + bytes) {
|
||||
uint32 pixel = *(uint32 *)pixels;
|
||||
int r = TIFFGetR(pixel);
|
||||
int g = TIFFGetG(pixel);
|
||||
int b = TIFFGetB(pixel);
|
||||
int a = TIFFGetA(pixel);
|
||||
*pixels++ = r;
|
||||
*pixels++ = g;
|
||||
*pixels++ = b;
|
||||
*pixels++ = a;
|
||||
}
|
||||
/* Turns out that the packing used by TIFFRGBAImage depends on
|
||||
* the host byte order...
|
||||
*/
|
||||
while (pixels < pixbuf->pixels + bytes) {
|
||||
uint32 pixel = *(uint32 *)pixels;
|
||||
int r = TIFFGetR(pixel);
|
||||
int g = TIFFGetG(pixel);
|
||||
int b = TIFFGetB(pixel);
|
||||
int a = TIFFGetA(pixel);
|
||||
*pixels++ = r;
|
||||
*pixels++ = g;
|
||||
*pixels++ = b;
|
||||
*pixels++ = a;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
uint32 *rast, *tmp_rast;
|
||||
gint x, y;
|
||||
guchar *tmppix;
|
||||
|
||||
/* Yes, it needs to be _TIFFMalloc... */
|
||||
rast = (uint32 *) _TIFFmalloc (width * height * sizeof (uint32));
|
||||
if (!rast) {
|
||||
g_set_error (error,
|
||||
GDK_PIXBUF_ERROR,
|
||||
GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
|
||||
_("Insufficient memory to open TIFF file"));
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
if (!TIFFReadRGBAImage (tiff, width, height, rast, 1) || global_error) {
|
||||
tiff_set_error (error,
|
||||
GDK_PIXBUF_ERROR_FAILED,
|
||||
_("Failed to load RGB data from TIFF file"));
|
||||
g_object_unref (pixbuf);
|
||||
_TIFFfree (rast);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||
|
||||
g_assert (pixels);
|
||||
|
||||
tmppix = pixels;
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
/* Unexplainable...are tiffs backwards? */
|
||||
/* Also looking at the GIMP plugin, this
|
||||
* whole reading thing can be a bit more
|
||||
* robust.
|
||||
*/
|
||||
tmp_rast = rast + ((height - y - 1) * width);
|
||||
for (x = 0; x < width; x++) {
|
||||
tmppix[0] = TIFFGetR (*tmp_rast);
|
||||
tmppix[1] = TIFFGetG (*tmp_rast);
|
||||
tmppix[2] = TIFFGetB (*tmp_rast);
|
||||
tmppix[3] = TIFFGetA (*tmp_rast);
|
||||
tmp_rast++;
|
||||
tmppix += 4;
|
||||
}
|
||||
}
|
||||
|
||||
_TIFFfree (rast);
|
||||
}
|
||||
|
||||
G_UNLOCK (tiff_loader);
|
||||
if (context)
|
||||
|
||||
+139
-125
@@ -71,36 +71,49 @@ pixops_scale_nearest (guchar *dest_buf,
|
||||
double scale_x,
|
||||
double scale_y)
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
int x;
|
||||
int x_step = (1 << SCALE_SHIFT) / scale_x;
|
||||
int y_step = (1 << SCALE_SHIFT) / scale_y;
|
||||
int xmax, xstart, xstop, x_pos, y_pos;
|
||||
const guchar *p;
|
||||
|
||||
#define INNER_LOOP(SRC_CHANNELS,DEST_CHANNELS) \
|
||||
for (j=0; j < (render_x1 - render_x0); j++) \
|
||||
#define INNER_LOOP(SRC_CHANNELS,DEST_CHANNELS,ASSIGN_PIXEL) \
|
||||
xmax = x + (render_x1 - render_x0) * x_step; \
|
||||
xstart = MIN (0, xmax); \
|
||||
xstop = MIN (src_width << SCALE_SHIFT, xmax); \
|
||||
p = src + (CLAMP (x, xstart, xstop) >> SCALE_SHIFT) * SRC_CHANNELS; \
|
||||
while (x < xstart) \
|
||||
{ \
|
||||
const guchar *p = src + (x >> SCALE_SHIFT) * SRC_CHANNELS; \
|
||||
\
|
||||
dest[0] = p[0]; \
|
||||
dest[1] = p[1]; \
|
||||
dest[2] = p[2]; \
|
||||
\
|
||||
if (DEST_CHANNELS == 4) \
|
||||
{ \
|
||||
if (SRC_CHANNELS == 4) \
|
||||
dest[3] = p[3]; \
|
||||
else \
|
||||
dest[3] = 0xff; \
|
||||
} \
|
||||
\
|
||||
ASSIGN_PIXEL; \
|
||||
dest += DEST_CHANNELS; \
|
||||
x += x_step; \
|
||||
} \
|
||||
while (x < xstop) \
|
||||
{ \
|
||||
p = src + (x >> SCALE_SHIFT) * SRC_CHANNELS; \
|
||||
ASSIGN_PIXEL; \
|
||||
dest += DEST_CHANNELS; \
|
||||
x += x_step; \
|
||||
} \
|
||||
x_pos = x >> SCALE_SHIFT; \
|
||||
p = src + CLAMP (x_pos, 0, src_width - 1) * SRC_CHANNELS; \
|
||||
while (x < xmax) \
|
||||
{ \
|
||||
ASSIGN_PIXEL; \
|
||||
dest += DEST_CHANNELS; \
|
||||
x += x_step; \
|
||||
}
|
||||
|
||||
for (i = 0; i < (render_y1 - render_y0); i++)
|
||||
{
|
||||
const guchar *src = src_buf + (((i + render_y0) * y_step + y_step / 2) >> SCALE_SHIFT) * src_rowstride;
|
||||
guchar *dest = dest_buf + i * dest_rowstride;
|
||||
const guchar *src;
|
||||
guchar *dest;
|
||||
|
||||
y_pos = ((i + render_y0) * y_step + y_step / 2) >> SCALE_SHIFT;
|
||||
y_pos = CLAMP (y_pos, 0, src_height - 1);
|
||||
src = src_buf + y_pos * src_rowstride;
|
||||
dest = dest_buf + i * dest_rowstride;
|
||||
|
||||
x = render_x0 * x_step + x_step / 2;
|
||||
|
||||
@@ -108,36 +121,26 @@ pixops_scale_nearest (guchar *dest_buf,
|
||||
{
|
||||
if (dest_channels == 3)
|
||||
{
|
||||
INNER_LOOP (3, 3);
|
||||
INNER_LOOP (3, 3, dest[0]=p[0];dest[1]=p[1];dest[2]=p[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
INNER_LOOP (3, 4);
|
||||
INNER_LOOP (3, 4, dest[0]=p[0];dest[1]=p[1];dest[2]=p[2]);
|
||||
}
|
||||
}
|
||||
else if (src_channels == 4)
|
||||
{
|
||||
if (dest_channels == 3)
|
||||
{
|
||||
INNER_LOOP (4, 3);
|
||||
INNER_LOOP (4, 3, dest[0]=p[0];dest[1]=p[1];dest[2]=p[2];dest[3]=0xff);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j=0; j < (render_x1 - render_x0); j++)
|
||||
{
|
||||
const guchar *p = src + (x >> SCALE_SHIFT) * 4;
|
||||
guint32 *p32;
|
||||
|
||||
p32 = (guint32 *) dest;
|
||||
*p32 = *((guint32 *) p);
|
||||
|
||||
dest += 4;
|
||||
x += x_step;
|
||||
}
|
||||
guint32 *p32;
|
||||
INNER_LOOP(4, 4, p32=(guint32*)dest;*p32=*((guint32*)p));
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef INNER_LOOP
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -159,23 +162,28 @@ pixops_composite_nearest (guchar *dest_buf,
|
||||
double scale_y,
|
||||
int overall_alpha)
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
int x;
|
||||
int x_step = (1 << SCALE_SHIFT) / scale_x;
|
||||
int y_step = (1 << SCALE_SHIFT) / scale_y;
|
||||
int xmax, xstart, xstop, x_pos, y_pos;
|
||||
const guchar *p;
|
||||
unsigned int a0;
|
||||
|
||||
|
||||
for (i = 0; i < (render_y1 - render_y0); i++)
|
||||
{
|
||||
const guchar *src = src_buf + (((i + render_y0) * y_step + y_step / 2) >> SCALE_SHIFT) * src_rowstride;
|
||||
guchar *dest = dest_buf + i * dest_rowstride;
|
||||
const guchar *src;
|
||||
guchar *dest;
|
||||
|
||||
y_pos = ((i + render_y0) * y_step + y_step / 2) >> SCALE_SHIFT;
|
||||
y_pos = CLAMP (y_pos, 0, src_height - 1);
|
||||
src = src_buf + y_pos * src_rowstride;
|
||||
dest = dest_buf + i * dest_rowstride;
|
||||
|
||||
x = render_x0 * x_step + x_step / 2;
|
||||
|
||||
for (j=0; j < (render_x1 - render_x0); j++)
|
||||
{
|
||||
const guchar *p = src + (x >> SCALE_SHIFT) * src_channels;
|
||||
unsigned int a0;
|
||||
|
||||
INNER_LOOP(src_channels, dest_channels,
|
||||
if (src_has_alpha)
|
||||
a0 = (p[3] * overall_alpha) / 0xff;
|
||||
else
|
||||
@@ -218,9 +226,7 @@ pixops_composite_nearest (guchar *dest_buf,
|
||||
}
|
||||
break;
|
||||
}
|
||||
dest += dest_channels;
|
||||
x += x_step;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,14 +260,23 @@ pixops_composite_color_nearest (guchar *dest_buf,
|
||||
int y_step = (1 << SCALE_SHIFT) / scale_y;
|
||||
int r1, g1, b1, r2, g2, b2;
|
||||
int check_shift = get_check_shift (check_size);
|
||||
int xmax, xstart, xstop, x_pos, y_pos;
|
||||
const guchar *p;
|
||||
unsigned int a0;
|
||||
|
||||
for (i = 0; i < (render_y1 - render_y0); i++)
|
||||
{
|
||||
const guchar *src = src_buf + (((i + render_y0) * y_step + y_step/2) >> SCALE_SHIFT) * src_rowstride;
|
||||
guchar *dest = dest_buf + i * dest_rowstride;
|
||||
const guchar *src;
|
||||
guchar *dest;
|
||||
|
||||
y_pos = ((i + render_y0) * y_step + y_step / 2) >> SCALE_SHIFT;
|
||||
y_pos = CLAMP (y_pos, 0, src_height - 1);
|
||||
src = src_buf + y_pos * src_rowstride;
|
||||
dest = dest_buf + i * dest_rowstride;
|
||||
|
||||
x = render_x0 * x_step + x_step / 2;
|
||||
|
||||
|
||||
if (((i + check_y) >> check_shift) & 1)
|
||||
{
|
||||
r1 = (color2 & 0xff0000) >> 16;
|
||||
@@ -283,12 +298,8 @@ pixops_composite_color_nearest (guchar *dest_buf,
|
||||
b2 = color2 & 0xff;
|
||||
}
|
||||
|
||||
for (j=0 ; j < (render_x1 - render_x0); j++)
|
||||
{
|
||||
const guchar *p = src + (x >> SCALE_SHIFT) * src_channels;
|
||||
int a0;
|
||||
int tmp;
|
||||
|
||||
j = 0;
|
||||
INNER_LOOP(src_channels, dest_channels,
|
||||
if (src_has_alpha)
|
||||
a0 = (p[3] * overall_alpha + 0xff) >> 8;
|
||||
else
|
||||
@@ -316,6 +327,8 @@ pixops_composite_color_nearest (guchar *dest_buf,
|
||||
dest[2] = p[2];
|
||||
break;
|
||||
default:
|
||||
{
|
||||
unsigned int tmp;
|
||||
if (((j + check_x) >> check_shift) & 1)
|
||||
{
|
||||
tmp = ((int) p[0] - r2) * a0;
|
||||
@@ -334,17 +347,18 @@ pixops_composite_color_nearest (guchar *dest_buf,
|
||||
tmp = ((int) p[2] - b1) * a0;
|
||||
dest[2] = b1 + ((tmp + (tmp >> 8) + 0x80) >> 8);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (dest_channels == 4)
|
||||
dest[3] = 0xff;
|
||||
|
||||
dest += dest_channels;
|
||||
x += x_step;
|
||||
}
|
||||
j++;
|
||||
);
|
||||
}
|
||||
}
|
||||
#undef INNER_LOOP
|
||||
|
||||
static void
|
||||
composite_pixel (guchar *dest, int dest_x, int dest_channels, int dest_has_alpha,
|
||||
@@ -1312,7 +1326,7 @@ bilinear_box_make_weights (PixopsFilterDimension *dim,
|
||||
dim->n = n;
|
||||
dim->weights = pixel_weights;
|
||||
|
||||
for (offset =0 ; offset < SUBSAMPLE; offset++)
|
||||
for (offset = 0; offset < SUBSAMPLE; offset++)
|
||||
{
|
||||
double x = (double)offset / SUBSAMPLE;
|
||||
double a = x + 1 / scale;
|
||||
@@ -1320,7 +1334,7 @@ bilinear_box_make_weights (PixopsFilterDimension *dim,
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
w = linear_box_half (0.5 + i - a, 0.5 + i - x);
|
||||
w += linear_box_half (1.5 + x - i, 1.5 + a - i);
|
||||
w += linear_box_half (0.5 + x - i, 0.5 + a - i);
|
||||
|
||||
*(pixel_weights++) = w * scale;
|
||||
}
|
||||
@@ -1357,29 +1371,29 @@ make_weights (PixopsFilter *filter,
|
||||
}
|
||||
|
||||
void
|
||||
pixops_composite_color (guchar *dest_buf,
|
||||
int render_x0,
|
||||
int render_y0,
|
||||
int render_x1,
|
||||
int render_y1,
|
||||
int dest_rowstride,
|
||||
int dest_channels,
|
||||
gboolean dest_has_alpha,
|
||||
const guchar *src_buf,
|
||||
int src_width,
|
||||
int src_height,
|
||||
int src_rowstride,
|
||||
int src_channels,
|
||||
gboolean src_has_alpha,
|
||||
double scale_x,
|
||||
double scale_y,
|
||||
PixopsInterpType interp_type,
|
||||
int overall_alpha,
|
||||
int check_x,
|
||||
int check_y,
|
||||
int check_size,
|
||||
guint32 color1,
|
||||
guint32 color2)
|
||||
_pixops_composite_color (guchar *dest_buf,
|
||||
int render_x0,
|
||||
int render_y0,
|
||||
int render_x1,
|
||||
int render_y1,
|
||||
int dest_rowstride,
|
||||
int dest_channels,
|
||||
gboolean dest_has_alpha,
|
||||
const guchar *src_buf,
|
||||
int src_width,
|
||||
int src_height,
|
||||
int src_rowstride,
|
||||
int src_channels,
|
||||
gboolean src_has_alpha,
|
||||
double scale_x,
|
||||
double scale_y,
|
||||
PixopsInterpType interp_type,
|
||||
int overall_alpha,
|
||||
int check_x,
|
||||
int check_y,
|
||||
int check_size,
|
||||
guint32 color1,
|
||||
guint32 color2)
|
||||
{
|
||||
PixopsFilter filter;
|
||||
PixopsLineFunc line_func;
|
||||
@@ -1396,10 +1410,10 @@ pixops_composite_color (guchar *dest_buf,
|
||||
|
||||
if (!src_has_alpha && overall_alpha == 255)
|
||||
{
|
||||
pixops_scale (dest_buf, render_x0, render_y0, render_x1, render_y1,
|
||||
dest_rowstride, dest_channels, dest_has_alpha,
|
||||
src_buf, src_width, src_height, src_rowstride, src_channels,
|
||||
src_has_alpha, scale_x, scale_y, interp_type);
|
||||
_pixops_scale (dest_buf, render_x0, render_y0, render_x1, render_y1,
|
||||
dest_rowstride, dest_channels, dest_has_alpha,
|
||||
src_buf, src_width, src_height, src_rowstride, src_channels,
|
||||
src_has_alpha, scale_x, scale_y, interp_type);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1435,7 +1449,7 @@ pixops_composite_color (guchar *dest_buf,
|
||||
}
|
||||
|
||||
/**
|
||||
* pixops_composite:
|
||||
* _pixops_composite:
|
||||
* @dest_buf: pointer to location to store result
|
||||
* @render_x0: x0 of region of scaled source to store into @dest_buf
|
||||
* @render_y0: y0 of region of scaled source to store into @dest_buf
|
||||
@@ -1459,24 +1473,24 @@ pixops_composite_color (guchar *dest_buf,
|
||||
* of the result into the destination buffer.
|
||||
**/
|
||||
void
|
||||
pixops_composite (guchar *dest_buf,
|
||||
int render_x0,
|
||||
int render_y0,
|
||||
int render_x1,
|
||||
int render_y1,
|
||||
int dest_rowstride,
|
||||
int dest_channels,
|
||||
gboolean dest_has_alpha,
|
||||
const guchar *src_buf,
|
||||
int src_width,
|
||||
int src_height,
|
||||
int src_rowstride,
|
||||
int src_channels,
|
||||
gboolean src_has_alpha,
|
||||
double scale_x,
|
||||
double scale_y,
|
||||
PixopsInterpType interp_type,
|
||||
int overall_alpha)
|
||||
_pixops_composite (guchar *dest_buf,
|
||||
int render_x0,
|
||||
int render_y0,
|
||||
int render_x1,
|
||||
int render_y1,
|
||||
int dest_rowstride,
|
||||
int dest_channels,
|
||||
gboolean dest_has_alpha,
|
||||
const guchar *src_buf,
|
||||
int src_width,
|
||||
int src_height,
|
||||
int src_rowstride,
|
||||
int src_channels,
|
||||
gboolean src_has_alpha,
|
||||
double scale_x,
|
||||
double scale_y,
|
||||
PixopsInterpType interp_type,
|
||||
int overall_alpha)
|
||||
{
|
||||
PixopsFilter filter;
|
||||
PixopsLineFunc line_func;
|
||||
@@ -1493,10 +1507,10 @@ pixops_composite (guchar *dest_buf,
|
||||
|
||||
if (!src_has_alpha && overall_alpha == 255)
|
||||
{
|
||||
pixops_scale (dest_buf, render_x0, render_y0, render_x1, render_y1,
|
||||
dest_rowstride, dest_channels, dest_has_alpha,
|
||||
src_buf, src_width, src_height, src_rowstride, src_channels,
|
||||
src_has_alpha, scale_x, scale_y, interp_type);
|
||||
_pixops_scale (dest_buf, render_x0, render_y0, render_x1, render_y1,
|
||||
dest_rowstride, dest_channels, dest_has_alpha,
|
||||
src_buf, src_width, src_height, src_rowstride, src_channels,
|
||||
src_has_alpha, scale_x, scale_y, interp_type);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1536,23 +1550,23 @@ pixops_composite (guchar *dest_buf,
|
||||
}
|
||||
|
||||
void
|
||||
pixops_scale (guchar *dest_buf,
|
||||
int render_x0,
|
||||
int render_y0,
|
||||
int render_x1,
|
||||
int render_y1,
|
||||
int dest_rowstride,
|
||||
int dest_channels,
|
||||
gboolean dest_has_alpha,
|
||||
const guchar *src_buf,
|
||||
int src_width,
|
||||
int src_height,
|
||||
int src_rowstride,
|
||||
int src_channels,
|
||||
gboolean src_has_alpha,
|
||||
double scale_x,
|
||||
double scale_y,
|
||||
PixopsInterpType interp_type)
|
||||
_pixops_scale (guchar *dest_buf,
|
||||
int render_x0,
|
||||
int render_y0,
|
||||
int render_x1,
|
||||
int render_y1,
|
||||
int dest_rowstride,
|
||||
int dest_channels,
|
||||
gboolean dest_has_alpha,
|
||||
const guchar *src_buf,
|
||||
int src_width,
|
||||
int src_height,
|
||||
int src_rowstride,
|
||||
int src_channels,
|
||||
gboolean src_has_alpha,
|
||||
double scale_x,
|
||||
double scale_y,
|
||||
PixopsInterpType interp_type)
|
||||
{
|
||||
PixopsFilter filter;
|
||||
PixopsLineFunc line_func;
|
||||
|
||||
+42
-42
@@ -18,24 +18,24 @@ typedef enum {
|
||||
* render_x, render_y, render_width, render_height in the new
|
||||
* coordinate system into dest_buf starting at 0, 0
|
||||
*/
|
||||
void pixops_composite (guchar *dest_buf,
|
||||
int render_x0,
|
||||
int render_y0,
|
||||
int render_x1,
|
||||
int render_y1,
|
||||
int dest_rowstride,
|
||||
int dest_channels,
|
||||
int dest_has_alpha,
|
||||
const guchar *src_buf,
|
||||
int src_width,
|
||||
int src_height,
|
||||
int src_rowstride,
|
||||
int src_channels,
|
||||
int src_has_alpha,
|
||||
double scale_x,
|
||||
double scale_y,
|
||||
PixopsInterpType interp_type,
|
||||
int overall_alpha);
|
||||
void _pixops_composite (guchar *dest_buf,
|
||||
int render_x0,
|
||||
int render_y0,
|
||||
int render_x1,
|
||||
int render_y1,
|
||||
int dest_rowstride,
|
||||
int dest_channels,
|
||||
int dest_has_alpha,
|
||||
const guchar *src_buf,
|
||||
int src_width,
|
||||
int src_height,
|
||||
int src_rowstride,
|
||||
int src_channels,
|
||||
int src_has_alpha,
|
||||
double scale_x,
|
||||
double scale_y,
|
||||
PixopsInterpType interp_type,
|
||||
int overall_alpha);
|
||||
|
||||
/* Scale src_buf from src_width / src_height by factors scale_x, scale_y
|
||||
* and composite the portion corresponding to
|
||||
@@ -43,36 +43,36 @@ void pixops_composite (guchar *dest_buf,
|
||||
* coordinate system against a checkboard with checks of size check_size
|
||||
* of the colors color1 and color2 into dest_buf starting at 0, 0
|
||||
*/
|
||||
void pixops_composite_color (guchar *dest_buf,
|
||||
int render_x0,
|
||||
int render_y0,
|
||||
int render_x1,
|
||||
int render_y1,
|
||||
int dest_rowstride,
|
||||
int dest_channels,
|
||||
int dest_has_alpha,
|
||||
const guchar *src_buf,
|
||||
int src_width,
|
||||
int src_height,
|
||||
int src_rowstride,
|
||||
int src_channels,
|
||||
int src_has_alpha,
|
||||
double scale_x,
|
||||
double scale_y,
|
||||
PixopsInterpType interp_type,
|
||||
int overall_alpha,
|
||||
int check_x,
|
||||
int check_y,
|
||||
int check_size,
|
||||
guint32 color1,
|
||||
guint32 color2);
|
||||
void _pixops_composite_color (guchar *dest_buf,
|
||||
int render_x0,
|
||||
int render_y0,
|
||||
int render_x1,
|
||||
int render_y1,
|
||||
int dest_rowstride,
|
||||
int dest_channels,
|
||||
int dest_has_alpha,
|
||||
const guchar *src_buf,
|
||||
int src_width,
|
||||
int src_height,
|
||||
int src_rowstride,
|
||||
int src_channels,
|
||||
int src_has_alpha,
|
||||
double scale_x,
|
||||
double scale_y,
|
||||
PixopsInterpType interp_type,
|
||||
int overall_alpha,
|
||||
int check_x,
|
||||
int check_y,
|
||||
int check_size,
|
||||
guint32 color1,
|
||||
guint32 color2);
|
||||
|
||||
/* Scale src_buf from src_width / src_height by factors scale_x, scale_y
|
||||
* and composite the portion corresponding to
|
||||
* render_x, render_y, render_width, render_height in the new
|
||||
* coordinate system into dest_buf starting at 0, 0
|
||||
*/
|
||||
void pixops_scale (guchar *dest_buf,
|
||||
void _pixops_scale (guchar *dest_buf,
|
||||
int render_x0,
|
||||
int render_y0,
|
||||
int render_x1,
|
||||
|
||||
@@ -182,10 +182,10 @@ int main (int argc, char **argv)
|
||||
start_timing ();
|
||||
for (i = 0; i < ITERS; i++)
|
||||
{
|
||||
pixops_scale (dest_buf, 0, 0, dest_width, dest_height, dest_rowstride, dest_channels, dest_has_alpha,
|
||||
src_buf, src_width, src_height, src_rowstride, src_channels, src_has_alpha,
|
||||
(double)dest_width / src_width, (double)dest_height / src_height,
|
||||
filter_level);
|
||||
_pixops_scale (dest_buf, 0, 0, dest_width, dest_height, dest_rowstride, dest_channels, dest_has_alpha,
|
||||
src_buf, src_width, src_height, src_rowstride, src_channels, src_has_alpha,
|
||||
(double)dest_width / src_width, (double)dest_height / src_height,
|
||||
filter_level);
|
||||
}
|
||||
scale_times[src_index][dest_index][filter_level] =
|
||||
stop_timing (" scale\t\t", ITERS, dest_height * dest_width);
|
||||
@@ -194,10 +194,10 @@ int main (int argc, char **argv)
|
||||
start_timing ();
|
||||
for (i = 0; i < ITERS; i++)
|
||||
{
|
||||
pixops_composite (dest_buf, 0, 0, dest_width, dest_height, dest_rowstride, dest_channels, dest_has_alpha,
|
||||
src_buf, src_width, src_height, src_rowstride, src_channels, src_has_alpha,
|
||||
(double)dest_width / src_width, (double)dest_height / src_height,
|
||||
filter_level, 255);
|
||||
_pixops_composite (dest_buf, 0, 0, dest_width, dest_height, dest_rowstride, dest_channels, dest_has_alpha,
|
||||
src_buf, src_width, src_height, src_rowstride, src_channels, src_has_alpha,
|
||||
(double)dest_width / src_width, (double)dest_height / src_height,
|
||||
filter_level, 255);
|
||||
}
|
||||
composite_times[src_index][dest_index][filter_level] =
|
||||
stop_timing (" composite\t\t", ITERS, dest_height * dest_width);
|
||||
@@ -205,10 +205,10 @@ int main (int argc, char **argv)
|
||||
start_timing ();
|
||||
for (i = 0; i < ITERS; i++)
|
||||
{
|
||||
pixops_composite_color (dest_buf, 0, 0, dest_width, dest_height, dest_rowstride, dest_channels, dest_has_alpha,
|
||||
src_buf, src_width, src_height, src_rowstride, src_channels, src_has_alpha,
|
||||
(double)dest_width / src_width, (double)dest_height / src_height,
|
||||
filter_level, 255, 0, 0, 16, 0xaaaaaa, 0x555555);
|
||||
_pixops_composite_color (dest_buf, 0, 0, dest_width, dest_height, dest_rowstride, dest_channels, dest_has_alpha,
|
||||
src_buf, src_width, src_height, src_rowstride, src_channels, src_has_alpha,
|
||||
(double)dest_width / src_width, (double)dest_height / src_height,
|
||||
filter_level, 255, 0, 0, 16, 0xaaaaaa, 0x555555);
|
||||
}
|
||||
composite_color_times[src_index][dest_index][filter_level] =
|
||||
stop_timing (" composite color\t", ITERS, dest_height * dest_width);
|
||||
|
||||
+21
-21
@@ -40,27 +40,27 @@ static void gdk_display_dispose (GObject *object);
|
||||
static void gdk_display_finalize (GObject *object);
|
||||
|
||||
|
||||
void singlehead_get_pointer (GdkDisplay *display,
|
||||
static void singlehead_get_pointer (GdkDisplay *display,
|
||||
GdkScreen **screen,
|
||||
gint *x,
|
||||
gint *y,
|
||||
GdkModifierType *mask);
|
||||
GdkWindow* singlehead_window_get_pointer (GdkDisplay *display,
|
||||
GdkWindow *window,
|
||||
gint *x,
|
||||
gint *y,
|
||||
GdkModifierType *mask);
|
||||
GdkWindow* singlehead_window_at_pointer (GdkDisplay *display,
|
||||
gint *win_x,
|
||||
gint *win_y);
|
||||
static GdkWindow* singlehead_window_get_pointer (GdkDisplay *display,
|
||||
GdkWindow *window,
|
||||
gint *x,
|
||||
gint *y,
|
||||
GdkModifierType *mask);
|
||||
static GdkWindow* singlehead_window_at_pointer (GdkDisplay *display,
|
||||
gint *win_x,
|
||||
gint *win_y);
|
||||
|
||||
GdkWindow* singlehead_default_window_get_pointer (GdkWindow *window,
|
||||
gint *x,
|
||||
gint *y,
|
||||
GdkModifierType *mask);
|
||||
GdkWindow* singlehead_default_window_at_pointer (GdkScreen *screen,
|
||||
gint *win_x,
|
||||
gint *win_y);
|
||||
static GdkWindow* singlehead_default_window_get_pointer (GdkWindow *window,
|
||||
gint *x,
|
||||
gint *y,
|
||||
GdkModifierType *mask);
|
||||
static GdkWindow* singlehead_default_window_at_pointer (GdkScreen *screen,
|
||||
gint *win_x,
|
||||
gint *win_y);
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
@@ -558,7 +558,7 @@ gdk_display_set_pointer_hooks (GdkDisplay *display,
|
||||
return (GdkDisplayPointerHooks *)result;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
singlehead_get_pointer (GdkDisplay *display,
|
||||
GdkScreen **screen,
|
||||
gint *x,
|
||||
@@ -573,7 +573,7 @@ singlehead_get_pointer (GdkDisplay *display,
|
||||
singlehead_current_pointer_hooks->get_pointer (root_window, x, y, mask);
|
||||
}
|
||||
|
||||
GdkWindow*
|
||||
static GdkWindow*
|
||||
singlehead_window_get_pointer (GdkDisplay *display,
|
||||
GdkWindow *window,
|
||||
gint *x,
|
||||
@@ -583,7 +583,7 @@ singlehead_window_get_pointer (GdkDisplay *display,
|
||||
return singlehead_current_pointer_hooks->get_pointer (window, x, y, mask);
|
||||
}
|
||||
|
||||
GdkWindow*
|
||||
static GdkWindow*
|
||||
singlehead_window_at_pointer (GdkDisplay *display,
|
||||
gint *win_x,
|
||||
gint *win_y)
|
||||
@@ -594,7 +594,7 @@ singlehead_window_at_pointer (GdkDisplay *display,
|
||||
win_x, win_y);
|
||||
}
|
||||
|
||||
GdkWindow*
|
||||
static GdkWindow*
|
||||
singlehead_default_window_get_pointer (GdkWindow *window,
|
||||
gint *x,
|
||||
gint *y,
|
||||
@@ -604,7 +604,7 @@ singlehead_default_window_get_pointer (GdkWindow *window,
|
||||
window, x, y, mask);
|
||||
}
|
||||
|
||||
GdkWindow*
|
||||
static GdkWindow*
|
||||
singlehead_default_window_at_pointer (GdkScreen *screen,
|
||||
gint *win_x,
|
||||
gint *win_y)
|
||||
|
||||
+3
-1
@@ -130,7 +130,9 @@ typedef enum
|
||||
GDK_BUTTON3_MASK = 1 << 10,
|
||||
GDK_BUTTON4_MASK = 1 << 11,
|
||||
GDK_BUTTON5_MASK = 1 << 12,
|
||||
/* The next few modifiers are used by XKB, so we skip to the end
|
||||
/* The next few modifiers are used by XKB, so we skip to the end.
|
||||
* Bits 16 - 28 are currently unused, but will eventually
|
||||
* be used for "virtual modifiers". Bit 29 is used internally.
|
||||
*/
|
||||
GDK_RELEASE_MASK = 1 << 30,
|
||||
GDK_MODIFIER_MASK = GDK_RELEASE_MASK | 0x1fff
|
||||
|
||||
@@ -38,7 +38,8 @@
|
||||
#include "gdkregion-generic.h"
|
||||
#include <linux/fb.h>
|
||||
#include <stdio.h>
|
||||
#include <freetype/freetype.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
#define GDK_TYPE_DRAWABLE_IMPL_FBDATA (gdk_drawable_impl_fb_get_type ())
|
||||
#define GDK_DRAWABLE_IMPL_FBDATA(win) ((GdkDrawableFBData *)((GdkWindowObject *)(win))->impl)
|
||||
|
||||
@@ -1440,8 +1440,8 @@ gdk_window_set_transient_for (GdkWindow *window,
|
||||
}
|
||||
|
||||
void
|
||||
gdk_window_set_background (const GdkWindow *window,
|
||||
const GdkColor *color)
|
||||
gdk_window_set_background (GdkWindow *window,
|
||||
const GdkColor *color)
|
||||
{
|
||||
GdkWindowObject *private = (GdkWindowObject *)window;
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ typedef enum {
|
||||
#ifdef OLE2_DND
|
||||
|
||||
#define PRINT_GUID(guid) \
|
||||
g_print ("guid = %.08x-%.04x-%.04x-%.02x%.02x-%.02x%.02x%.02x%.02x%.02x%.02x", \
|
||||
g_print ("guid = %.08lx-%.04x-%.04x-%.02x%.02x-%.02x%.02x%.02x%.02x%.02x%.02x", \
|
||||
((gulong *) guid)[0], \
|
||||
((gushort *) guid)[2], \
|
||||
((gushort *) guid)[3], \
|
||||
@@ -88,6 +88,9 @@ static int nformats;
|
||||
* this is used on both source and destination sides.
|
||||
*/
|
||||
struct _GdkDragContextPrivateWin32 {
|
||||
#ifdef OLE2_DND
|
||||
gint ref_count;
|
||||
#endif
|
||||
guint16 last_x; /* Coordinates from last event */
|
||||
guint16 last_y;
|
||||
HWND dest_xid;
|
||||
@@ -139,6 +142,9 @@ gdk_drag_context_init (GdkDragContext *dragcontext)
|
||||
GdkDragContextPrivateWin32 *private = g_new0 (GdkDragContextPrivateWin32, 1);
|
||||
|
||||
dragcontext->windowing_data = private;
|
||||
#ifdef OLE2_DND
|
||||
private->ref_count = 1;
|
||||
#endif
|
||||
|
||||
contexts = g_list_prepend (contexts, dragcontext);
|
||||
}
|
||||
@@ -668,7 +674,7 @@ ienumformatetc_next (LPENUMFORMATETC This,
|
||||
enum_formats *en = (enum_formats *) This;
|
||||
int i, n;
|
||||
|
||||
GDK_NOTE (DND, g_print ("ienumformatetc_next %p %d %d\n", This, en->ix, celt));
|
||||
GDK_NOTE (DND, g_print ("ienumformatetc_next %p %d %ld\n", This, en->ix, celt));
|
||||
|
||||
n = 0;
|
||||
for (i = 0; i < celt; i++)
|
||||
@@ -694,7 +700,7 @@ ienumformatetc_skip (LPENUMFORMATETC This,
|
||||
{
|
||||
enum_formats *en = (enum_formats *) This;
|
||||
|
||||
GDK_NOTE (DND, g_print ("ienumformatetc_skip %p %d %d\n", This, en->ix, celt));
|
||||
GDK_NOTE (DND, g_print ("ienumformatetc_skip %p %d %ld\n", This, en->ix, celt));
|
||||
en->ix += celt;
|
||||
|
||||
return S_OK;
|
||||
@@ -1244,7 +1250,6 @@ gdk_drag_begin (GdkWindow *window,
|
||||
HRESULT hResult;
|
||||
DWORD dwEffect;
|
||||
HGLOBAL global;
|
||||
FORMATETC format;
|
||||
STGMEDIUM medium;
|
||||
|
||||
g_return_val_if_fail (window != NULL, NULL);
|
||||
@@ -1285,7 +1290,7 @@ gdk_drag_begin (GdkWindow *window,
|
||||
(hResult == DRAGDROP_S_DROP ? "DRAGDROP_S_DROP" :
|
||||
(hResult == DRAGDROP_S_CANCEL ? "DRAGDROP_S_CANCEL" :
|
||||
(hResult == E_UNEXPECTED ? "E_UNEXPECTED" :
|
||||
g_strdup_printf ("%#.8x", hResult))))));
|
||||
g_strdup_printf ("%#.8lx", hResult))))));
|
||||
|
||||
dobj->ido.lpVtbl->Release (&dobj->ido);
|
||||
ctx->ids.lpVtbl->Release (&ctx->ids);
|
||||
@@ -1362,8 +1367,8 @@ gdk_drag_find_window_for_screen (GdkDragContext *context,
|
||||
{
|
||||
find_window_enum_arg a;
|
||||
|
||||
a.x = x_root;
|
||||
a.y = y_root;
|
||||
a.x = x_root - _gdk_offset_x;
|
||||
a.y = y_root - _gdk_offset_y;
|
||||
a.ignore = drag_window ? GDK_WINDOW_HWND (drag_window) : NULL;
|
||||
a.result = NULL;
|
||||
|
||||
|
||||
@@ -1032,7 +1032,7 @@ gdk_win32_draw_text (GdkDrawable *drawable,
|
||||
{
|
||||
const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_FONT;
|
||||
wchar_t *wcstr, wc;
|
||||
gint wlen;
|
||||
glong wlen;
|
||||
gdk_draw_text_arg arg;
|
||||
|
||||
if (text_length == 0)
|
||||
@@ -1058,15 +1058,11 @@ gdk_win32_draw_text (GdkDrawable *drawable,
|
||||
}
|
||||
else
|
||||
{
|
||||
wcstr = g_new (wchar_t, text_length);
|
||||
if ((wlen = _gdk_utf8_to_ucs2 (wcstr, text, text_length, text_length)) == -1)
|
||||
g_warning ("gdk_win32_draw_text: _gdk_utf8_to_ucs2 failed");
|
||||
else
|
||||
_gdk_wchar_text_handle (font, wcstr, wlen, gdk_draw_text_handler, &arg);
|
||||
wcstr = g_utf8_to_utf16 (text, text_length, NULL, &wlen, NULL);
|
||||
_gdk_wchar_text_handle (font, wcstr, wlen, gdk_draw_text_handler, &arg);
|
||||
g_free (wcstr);
|
||||
}
|
||||
|
||||
|
||||
gdk_win32_hdc_release (drawable, gc, mask);
|
||||
}
|
||||
|
||||
|
||||
+61
-58
@@ -533,13 +533,13 @@ gdk_pointer_grab (GdkWindow *window,
|
||||
hcursor = NULL;
|
||||
else if ((hcursor = CopyCursor (cursor_private->hcursor)) == NULL)
|
||||
WIN32_API_FAILED ("CopyCursor");
|
||||
#if 0
|
||||
|
||||
return_val = _gdk_input_grab_pointer (window,
|
||||
owner_events,
|
||||
event_mask,
|
||||
confine_to,
|
||||
time);
|
||||
#endif
|
||||
|
||||
if (return_val == GDK_GRAB_SUCCESS)
|
||||
{
|
||||
if (!GDK_WINDOW_DESTROYED (window))
|
||||
@@ -615,9 +615,8 @@ gdk_display_pointer_ungrab (GdkDisplay *display,
|
||||
GDK_NOTE (EVENTS, g_print ("%sgdk_display_pointer_ungrab%s",
|
||||
(debug_indent > 0 ? "\n" : ""),
|
||||
(debug_indent == 0 ? "\n" : "")));
|
||||
#if 0
|
||||
|
||||
_gdk_input_ungrab_pointer (time);
|
||||
#endif
|
||||
|
||||
if (GetCapture () != NULL)
|
||||
ReleaseCapture ();
|
||||
@@ -1557,6 +1556,9 @@ translate_mouse_coords (GdkWindow *window1,
|
||||
msg->lParam = MAKELPARAM (pt.x, pt.y);
|
||||
}
|
||||
|
||||
/* The check_extended flag controls whether to check if the windows want
|
||||
* events from extended input devices and if the message should be skipped
|
||||
* because an extended input device is active */
|
||||
static gboolean
|
||||
propagate (GdkWindow **window,
|
||||
MSG *msg,
|
||||
@@ -1564,13 +1566,24 @@ propagate (GdkWindow **window,
|
||||
gboolean grab_owner_events,
|
||||
gint grab_mask,
|
||||
gboolean (*doesnt_want_it) (gint mask,
|
||||
MSG *msg))
|
||||
MSG *msg),
|
||||
gboolean check_extended)
|
||||
{
|
||||
gboolean in_propagation = FALSE;
|
||||
|
||||
if (grab_window != NULL && !grab_owner_events)
|
||||
{
|
||||
/* Event source is grabbed with owner_events FALSE */
|
||||
|
||||
/* See if the event should be ignored because an extended input device
|
||||
* is used */
|
||||
if (check_extended &&
|
||||
((GdkWindowObject *) grab_window)->extension_events != 0 &&
|
||||
_gdk_input_ignore_core)
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_print (" (ignored for grabber)"));
|
||||
return FALSE;
|
||||
}
|
||||
if ((*doesnt_want_it) (grab_mask, msg))
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_print (" (grabber doesn't want it)"));
|
||||
@@ -1585,7 +1598,16 @@ propagate (GdkWindow **window,
|
||||
}
|
||||
while (TRUE)
|
||||
{
|
||||
if ((*doesnt_want_it) (((GdkWindowObject *) *window)->event_mask, msg))
|
||||
/* See if the event should be ignored because an extended input device
|
||||
* is used */
|
||||
if (check_extended &&
|
||||
((GdkWindowObject *) *window)->extension_events != 0 &&
|
||||
_gdk_input_ignore_core)
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_print (" (ignored)"));
|
||||
return FALSE;
|
||||
}
|
||||
if ((*doesnt_want_it) (((GdkWindowObject *) *window)->event_mask, msg))
|
||||
{
|
||||
/* Owner doesn't want it, propagate to parent. */
|
||||
GdkWindow *parent = gdk_window_get_parent (*window);
|
||||
@@ -1595,6 +1617,16 @@ propagate (GdkWindow **window,
|
||||
if (grab_window != NULL)
|
||||
{
|
||||
/* Event source is grabbed with owner_events TRUE */
|
||||
|
||||
/* See if the event should be ignored because an extended
|
||||
* input device is used */
|
||||
if (check_extended &&
|
||||
((GdkWindowObject *) grab_window)->extension_events != 0 &&
|
||||
_gdk_input_ignore_core)
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_print (" (ignored for grabber)"));
|
||||
return FALSE;
|
||||
}
|
||||
if ((*doesnt_want_it) (grab_mask, msg))
|
||||
{
|
||||
/* Grabber doesn't want it either */
|
||||
@@ -1691,8 +1723,12 @@ handle_configure_event (MSG *msg,
|
||||
point.x = client_rect.left; /* always 0 */
|
||||
point.y = client_rect.top;
|
||||
/* top level windows need screen coords */
|
||||
if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
|
||||
ClientToScreen (msg->hwnd, &point);
|
||||
if (gdk_window_get_parent (window) == _gdk_parent_root)
|
||||
{
|
||||
ClientToScreen (msg->hwnd, &point);
|
||||
point.x += _gdk_offset_x;
|
||||
point.y += _gdk_offset_y;
|
||||
}
|
||||
|
||||
GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->width = client_rect.right - client_rect.left;
|
||||
GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->height = client_rect.bottom - client_rect.top;
|
||||
@@ -1712,12 +1748,6 @@ handle_configure_event (MSG *msg,
|
||||
event->configure.x = point.x;
|
||||
event->configure.y = point.y;
|
||||
|
||||
if (gdk_window_get_parent (window) == _gdk_parent_root)
|
||||
{
|
||||
event->configure.x += _gdk_offset_x;
|
||||
event->configure.y += _gdk_offset_y;
|
||||
}
|
||||
|
||||
append_event (gdk_drawable_get_display (window), event);
|
||||
}
|
||||
}
|
||||
@@ -2168,16 +2198,9 @@ gdk_event_translate (GdkDisplay *display,
|
||||
|
||||
assign_object (&window, new_window);
|
||||
|
||||
if (((GdkWindowObject *) window)->extension_events != 0 &&
|
||||
_gdk_input_ignore_core)
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_print (" (ignored)"));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!propagate (&window, msg,
|
||||
p_grab_window, p_grab_owner_events, p_grab_mask,
|
||||
doesnt_want_scroll))
|
||||
doesnt_want_scroll, TRUE))
|
||||
goto done;
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (window))
|
||||
@@ -2319,7 +2342,7 @@ gdk_event_translate (GdkDisplay *display,
|
||||
|
||||
if (!propagate (&window, msg,
|
||||
k_grab_window, k_grab_owner_events, GDK_ALL_EVENTS_MASK,
|
||||
doesnt_want_key))
|
||||
doesnt_want_key, FALSE))
|
||||
break;
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (window))
|
||||
@@ -2401,7 +2424,7 @@ gdk_event_translate (GdkDisplay *display,
|
||||
|
||||
if (!propagate (&window, msg,
|
||||
k_grab_window, k_grab_owner_events, GDK_ALL_EVENTS_MASK,
|
||||
doesnt_want_char))
|
||||
doesnt_want_char, FALSE))
|
||||
break;
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (window))
|
||||
@@ -2479,16 +2502,9 @@ gdk_event_translate (GdkDisplay *display,
|
||||
synthesize_crossing_events (window, GDK_CROSSING_NORMAL, msg);
|
||||
}
|
||||
|
||||
if (((GdkWindowObject *) window)->extension_events != 0 &&
|
||||
_gdk_input_ignore_core)
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_print (" (ignored)"));
|
||||
break;
|
||||
}
|
||||
|
||||
if (!propagate (&window, msg,
|
||||
p_grab_window, p_grab_owner_events, p_grab_mask,
|
||||
doesnt_want_button_press))
|
||||
doesnt_want_button_press, TRUE))
|
||||
break;
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (window))
|
||||
@@ -2568,16 +2584,18 @@ gdk_event_translate (GdkDisplay *display,
|
||||
synthesize_crossing_events (window, GDK_CROSSING_NORMAL, msg);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (((GdkWindowObject *) window)->extension_events != 0 &&
|
||||
_gdk_input_ignore_core)
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_print (" (ignored)"));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!propagate (&window, msg,
|
||||
p_grab_window, p_grab_owner_events, p_grab_mask,
|
||||
doesnt_want_button_release))
|
||||
doesnt_want_button_release, TRUE))
|
||||
{
|
||||
}
|
||||
else if (!GDK_WINDOW_DESTROYED (window))
|
||||
@@ -2640,16 +2658,9 @@ gdk_event_translate (GdkDisplay *display,
|
||||
synthesize_crossing_events (window, GDK_CROSSING_NORMAL, msg);
|
||||
}
|
||||
|
||||
if (((GdkWindowObject *) window)->extension_events != 0 &&
|
||||
_gdk_input_ignore_core)
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_print (" (ignored)"));
|
||||
break;
|
||||
}
|
||||
|
||||
if (!propagate (&window, msg,
|
||||
p_grab_window, p_grab_owner_events, p_grab_mask,
|
||||
doesnt_want_button_motion))
|
||||
doesnt_want_button_motion, TRUE))
|
||||
break;
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (window))
|
||||
@@ -2747,16 +2758,9 @@ gdk_event_translate (GdkDisplay *display,
|
||||
assign_object (&window, new_window);
|
||||
}
|
||||
|
||||
if (((GdkWindowObject *) window)->extension_events != 0 &&
|
||||
_gdk_input_ignore_core)
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_print (" (ignored)"));
|
||||
break;
|
||||
}
|
||||
|
||||
if (!propagate (&window, msg,
|
||||
p_grab_window, p_grab_owner_events, p_grab_mask,
|
||||
doesnt_want_scroll))
|
||||
doesnt_want_scroll, TRUE))
|
||||
break;
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (window))
|
||||
@@ -2988,15 +2992,19 @@ gdk_event_translate (GdkDisplay *display,
|
||||
point.x = client_rect.left; /* always 0 */
|
||||
point.y = client_rect.top;
|
||||
/* top level windows need screen coords */
|
||||
if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
|
||||
ClientToScreen (msg->hwnd, &point);
|
||||
if (gdk_window_get_parent (window) == _gdk_parent_root)
|
||||
{
|
||||
ClientToScreen (msg->hwnd, &point);
|
||||
point.x += _gdk_offset_x;
|
||||
point.y += _gdk_offset_y;
|
||||
}
|
||||
|
||||
GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->width = client_rect.right - client_rect.left;
|
||||
GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->height = client_rect.bottom - client_rect.top;
|
||||
|
||||
((GdkWindowObject *) window)->x = point.x;
|
||||
((GdkWindowObject *) window)->y = point.y;
|
||||
|
||||
|
||||
if (((GdkWindowObject *) window)->event_mask & GDK_STRUCTURE_MASK)
|
||||
{
|
||||
GdkEvent *event = gdk_event_new (GDK_CONFIGURE);
|
||||
@@ -3009,12 +3017,6 @@ gdk_event_translate (GdkDisplay *display,
|
||||
event->configure.x = point.x;
|
||||
event->configure.y = point.y;
|
||||
|
||||
if (gdk_window_get_parent (window) == _gdk_parent_root)
|
||||
{
|
||||
event->configure.x += _gdk_offset_x;
|
||||
event->configure.y += _gdk_offset_y;
|
||||
}
|
||||
|
||||
if (((GdkWindowObject *) window)->resize_count > 1)
|
||||
((GdkWindowObject *) window)->resize_count -= 1;
|
||||
|
||||
@@ -3301,6 +3303,7 @@ gdk_event_translate (GdkDisplay *display,
|
||||
|
||||
event = gdk_event_new (GDK_NOTHING);
|
||||
event->any.window = window;
|
||||
g_object_ref (window);
|
||||
if (_gdk_input_other_event (event, msg, window))
|
||||
append_event (display, event);
|
||||
else
|
||||
|
||||
@@ -1592,8 +1592,8 @@ gdk_text_extents (GdkFont *font,
|
||||
gint *descent)
|
||||
{
|
||||
gdk_text_size_arg arg;
|
||||
gint wlen;
|
||||
wchar_t *wcstr;
|
||||
glong wlen;
|
||||
wchar_t *wcstr, wc;
|
||||
|
||||
g_return_if_fail (font != NULL);
|
||||
g_return_if_fail (text != NULL);
|
||||
@@ -1617,22 +1617,18 @@ gdk_text_extents (GdkFont *font,
|
||||
|
||||
arg.total.cx = arg.total.cy = 0;
|
||||
|
||||
wcstr = g_new (wchar_t, text_length);
|
||||
if (text_length == 1)
|
||||
{
|
||||
wcstr[0] = (guchar) text[0];
|
||||
_gdk_wchar_text_handle (font, wcstr, 1, gdk_text_size_handler, &arg);
|
||||
wc = (guchar) text[0];
|
||||
_gdk_wchar_text_handle (font, &wc, 1, gdk_text_size_handler, &arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((wlen = _gdk_utf8_to_ucs2 (wcstr, text, text_length, text_length)) == -1)
|
||||
g_warning ("gdk_text_extents: _gdk_utf8_to_ucs2 failed");
|
||||
else
|
||||
_gdk_wchar_text_handle (font, wcstr, wlen, gdk_text_size_handler, &arg);
|
||||
wcstr = g_utf8_to_utf16 (text, text_length, NULL, &wlen, NULL);
|
||||
_gdk_wchar_text_handle (font, wcstr, wlen, gdk_text_size_handler, &arg);
|
||||
g_free (wcstr);
|
||||
}
|
||||
|
||||
g_free (wcstr);
|
||||
|
||||
/* XXX This is quite bogus */
|
||||
if (lbearing)
|
||||
*lbearing = 0;
|
||||
|
||||
@@ -51,8 +51,8 @@ WORD _cf_rtf;
|
||||
WORD _cf_utf8_string;
|
||||
|
||||
GdkAtom _utf8_string;
|
||||
GdkAtom _compound_text;
|
||||
GdkAtom _text_uri_list;
|
||||
GdkAtom _targets;
|
||||
|
||||
GdkAtom _local_dnd;
|
||||
GdkAtom _gdk_win32_dropfiles;
|
||||
|
||||
+21
-307
@@ -1,6 +1,6 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
* Copyright (C) 1998-2002 Tor Lillqvist
|
||||
* Copyright (C) 1998-2004 Tor Lillqvist
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -58,321 +58,35 @@ gdk_set_locale (void)
|
||||
return g_win32_getlocale ();
|
||||
}
|
||||
|
||||
/*
|
||||
* gdk_wcstombs
|
||||
*
|
||||
* Returns a multi-byte string converted from the specified array
|
||||
* of wide characters. The string is newly allocated. The array of
|
||||
* wide characters must be null-terminated. If the conversion is
|
||||
* failed, it returns NULL.
|
||||
*
|
||||
* On Win32, we always use UTF-8.
|
||||
*/
|
||||
gchar *
|
||||
gdk_wcstombs (const GdkWChar *src)
|
||||
{
|
||||
gint len;
|
||||
const GdkWChar *wcp;
|
||||
guchar *mbstr, *bp;
|
||||
gchar *utf8;
|
||||
gchar *retval;
|
||||
const gchar *charset;
|
||||
|
||||
wcp = src;
|
||||
len = 0;
|
||||
while (*wcp)
|
||||
{
|
||||
const GdkWChar c = *wcp++;
|
||||
|
||||
if (c < 0x80)
|
||||
len += 1;
|
||||
else if (c < 0x800)
|
||||
len += 2;
|
||||
else if (c < 0x10000)
|
||||
len += 3;
|
||||
else if (c < 0x200000)
|
||||
len += 4;
|
||||
else if (c < 0x4000000)
|
||||
len += 5;
|
||||
else
|
||||
len += 6;
|
||||
}
|
||||
|
||||
mbstr = g_malloc (len + 1);
|
||||
|
||||
wcp = src;
|
||||
bp = mbstr;
|
||||
while (*wcp)
|
||||
{
|
||||
int first;
|
||||
GdkWChar c = *wcp++;
|
||||
|
||||
if (c < 0x80)
|
||||
{
|
||||
first = 0;
|
||||
len = 1;
|
||||
}
|
||||
else if (c < 0x800)
|
||||
{
|
||||
first = 0xc0;
|
||||
len = 2;
|
||||
}
|
||||
else if (c < 0x10000)
|
||||
{
|
||||
first = 0xe0;
|
||||
len = 3;
|
||||
}
|
||||
else if (c < 0x200000)
|
||||
{
|
||||
first = 0xf0;
|
||||
len = 4;
|
||||
}
|
||||
else if (c < 0x4000000)
|
||||
{
|
||||
first = 0xf8;
|
||||
len = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
first = 0xfc;
|
||||
len = 6;
|
||||
}
|
||||
|
||||
/* Woo-hoo! */
|
||||
switch (len)
|
||||
{
|
||||
case 6: bp[5] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
|
||||
case 5: bp[4] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
|
||||
case 4: bp[3] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
|
||||
case 3: bp[2] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
|
||||
case 2: bp[1] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
|
||||
case 1: bp[0] = c | first;
|
||||
}
|
||||
|
||||
bp += len;
|
||||
}
|
||||
*bp = 0;
|
||||
return mbstr;
|
||||
g_get_charset (&charset);
|
||||
return g_convert (src, -1, charset, "UCS-4LE", NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/* A vesion that converts from wchar_t strings to UTF-8 */
|
||||
|
||||
gchar *
|
||||
_gdk_ucs2_to_utf8 (const wchar_t *src,
|
||||
gint src_len)
|
||||
{
|
||||
gint len;
|
||||
const wchar_t *wcp;
|
||||
guchar *mbstr, *bp;
|
||||
|
||||
wcp = src;
|
||||
len = 0;
|
||||
while (wcp < src + src_len)
|
||||
{
|
||||
const wchar_t c = *wcp++;
|
||||
|
||||
if (c < 0x80)
|
||||
len += 1;
|
||||
else if (c < 0x800)
|
||||
len += 2;
|
||||
else
|
||||
len += 3;
|
||||
}
|
||||
|
||||
mbstr = g_malloc (len + 1);
|
||||
|
||||
wcp = src;
|
||||
bp = mbstr;
|
||||
while (wcp < src + src_len)
|
||||
{
|
||||
int first;
|
||||
wchar_t c = *wcp++;
|
||||
|
||||
if (c < 0x80)
|
||||
{
|
||||
first = 0;
|
||||
len = 1;
|
||||
}
|
||||
else if (c < 0x800)
|
||||
{
|
||||
first = 0xc0;
|
||||
len = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
first = 0xe0;
|
||||
len = 3;
|
||||
}
|
||||
|
||||
/* Woo-hoo! */
|
||||
switch (len)
|
||||
{
|
||||
case 3: bp[2] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
|
||||
case 2: bp[1] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
|
||||
case 1: bp[0] = c | first;
|
||||
}
|
||||
|
||||
bp += len;
|
||||
}
|
||||
*bp = 0;
|
||||
|
||||
return mbstr;
|
||||
}
|
||||
|
||||
/* Convert from UTF-8 to GdkWChar */
|
||||
|
||||
gint
|
||||
_gdk_utf8_to_wcs (GdkWChar *dest,
|
||||
const gchar *src,
|
||||
gint src_len,
|
||||
gint dest_max)
|
||||
{
|
||||
guchar *cp, *end;
|
||||
gint n;
|
||||
|
||||
cp = (guchar *) src;
|
||||
end = cp + src_len;
|
||||
n = 0;
|
||||
while (cp != end && dest != dest + dest_max)
|
||||
{
|
||||
gint i, mask = 0, len;
|
||||
guchar c = *cp;
|
||||
|
||||
if (c < 0x80)
|
||||
{
|
||||
len = 1;
|
||||
mask = 0x7f;
|
||||
}
|
||||
else if ((c & 0xe0) == 0xc0)
|
||||
{
|
||||
len = 2;
|
||||
mask = 0x1f;
|
||||
}
|
||||
else if ((c & 0xf0) == 0xe0)
|
||||
{
|
||||
len = 3;
|
||||
mask = 0x0f;
|
||||
}
|
||||
else if ((c & 0xf8) == 0xf0)
|
||||
{
|
||||
len = 4;
|
||||
mask = 0x07;
|
||||
}
|
||||
else if ((c & 0xfc) == 0xf8)
|
||||
{
|
||||
len = 5;
|
||||
mask = 0x03;
|
||||
}
|
||||
else if ((c & 0xfc) == 0xfc)
|
||||
{
|
||||
len = 6;
|
||||
mask = 0x01;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
||||
if (cp + len > end)
|
||||
return -1;
|
||||
|
||||
*dest = (cp[0] & mask);
|
||||
for (i = 1; i < len; i++)
|
||||
{
|
||||
if ((cp[i] & 0xc0) != 0x80)
|
||||
return -1;
|
||||
*dest <<= 6;
|
||||
*dest |= (cp[i] & 0x3f);
|
||||
}
|
||||
if (*dest == -1)
|
||||
return -1;
|
||||
|
||||
cp += len;
|
||||
dest++;
|
||||
n++;
|
||||
}
|
||||
if (cp != end)
|
||||
return -1;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* gdk_mbstowcs
|
||||
*
|
||||
* Converts the specified string into GDK wide characters, and,
|
||||
* returns the number of wide characters written. The string 'src'
|
||||
* must be null-terminated. If the conversion is failed, it returns
|
||||
* -1.
|
||||
*
|
||||
* On Win32, the string is assumed to be in UTF-8. Also note that
|
||||
* GdkWChar is 32 bits, while wchar_t, and the wide characters the
|
||||
* Windows API uses, are 16 bits!
|
||||
*/
|
||||
|
||||
gint
|
||||
gdk_mbstowcs (GdkWChar *dest,
|
||||
const gchar *src,
|
||||
gint dest_max)
|
||||
{
|
||||
return _gdk_utf8_to_wcs (dest, src, strlen (src), dest_max);
|
||||
}
|
||||
|
||||
|
||||
/* A version that converts to a wchar_t string */
|
||||
|
||||
gint
|
||||
_gdk_utf8_to_ucs2 (wchar_t *dest,
|
||||
const gchar *src,
|
||||
gint src_len,
|
||||
gint dest_max)
|
||||
{
|
||||
wchar_t *wcp;
|
||||
guchar *cp, *end;
|
||||
gint n;
|
||||
|
||||
wcp = dest;
|
||||
cp = (guchar *) src;
|
||||
end = cp + src_len;
|
||||
n = 0;
|
||||
while (cp != end && wcp != dest + dest_max)
|
||||
{
|
||||
gint i, mask = 0, len;
|
||||
guchar c = *cp;
|
||||
|
||||
if (c < 0x80)
|
||||
{
|
||||
len = 1;
|
||||
mask = 0x7f;
|
||||
}
|
||||
else if ((c & 0xe0) == 0xc0)
|
||||
{
|
||||
len = 2;
|
||||
mask = 0x1f;
|
||||
}
|
||||
else if ((c & 0xf0) == 0xe0)
|
||||
{
|
||||
len = 3;
|
||||
mask = 0x0f;
|
||||
}
|
||||
else /* Other lengths are not possible with 16-bit wchar_t! */
|
||||
return -1;
|
||||
|
||||
if (cp + len > end)
|
||||
return -1;
|
||||
|
||||
*wcp = (cp[0] & mask);
|
||||
for (i = 1; i < len; i++)
|
||||
{
|
||||
if ((cp[i] & 0xc0) != 0x80)
|
||||
return -1;
|
||||
*wcp <<= 6;
|
||||
*wcp |= (cp[i] & 0x3f);
|
||||
}
|
||||
if (*wcp == 0xFFFF)
|
||||
return -1;
|
||||
|
||||
cp += len;
|
||||
wcp++;
|
||||
n++;
|
||||
}
|
||||
if (cp != end)
|
||||
return -1;
|
||||
|
||||
return n;
|
||||
gint retval;
|
||||
gsize nwritten;
|
||||
gint n_ucs4;
|
||||
gunichar *ucs4;
|
||||
const gchar *charset;
|
||||
|
||||
g_get_charset (&charset);
|
||||
ucs4 = g_convert (src, -1, "UCS-4LE", charset, NULL, &nwritten, NULL);
|
||||
n_ucs4 = nwritten * sizeof (GdkWChar);
|
||||
|
||||
retval = MIN (dest_max, n_ucs4);
|
||||
memmove (dest, ucs4, retval * sizeof (GdkWChar));
|
||||
g_free (ucs4);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
+139
-49
@@ -77,6 +77,16 @@ static GdkWindow *wintab_window;
|
||||
|
||||
#endif /* HAVE_WINTAB */
|
||||
|
||||
#ifdef HAVE_SOME_XINPUT
|
||||
|
||||
static GdkWindow *x_grab_window = NULL; /* Window that currently holds
|
||||
* the extended inputs grab
|
||||
*/
|
||||
static GdkEventMask x_grab_mask;
|
||||
static gboolean x_grab_owner_events;
|
||||
|
||||
#endif /* HAVE_SOME_XINPUT */
|
||||
|
||||
#ifdef HAVE_WINTAB
|
||||
|
||||
static GdkDevicePrivate *
|
||||
@@ -109,7 +119,6 @@ print_lc(LOGCONTEXT *lc)
|
||||
if (lc->lcOptions & CXO_MARGIN) g_print (" CXO_MARGIN");
|
||||
if (lc->lcOptions & CXO_MGNINSIDE) g_print (" CXO_MGNINSIDE");
|
||||
if (lc->lcOptions & CXO_CSRMESSAGES) g_print (" CXO_CSRMESSAGES");
|
||||
if (lc->lcOptions & CXO_CSRMESSAGES) g_print (" CXO_CSRMESSAGES");
|
||||
g_print ("\n");
|
||||
g_print ("lcStatus =");
|
||||
if (lc->lcStatus & CXS_DISABLED) g_print (" CXS_DISABLED");
|
||||
@@ -346,6 +355,20 @@ gdk_input_wintab_init (void)
|
||||
GDK_NOTE (INPUT, (g_print("context for device %d after WTOpen:\n", devix),
|
||||
print_lc(&lc)));
|
||||
#endif
|
||||
/* Increase packet queue size to reduce the risk of lost packets */
|
||||
/* According to the specs, if the function fails we must try again */
|
||||
/* with a smaller queue size */
|
||||
GDK_NOTE (INPUT, g_print("Attempting to increase queue size\n"));
|
||||
for (i = 128; i >= 1; i >>= 1)
|
||||
{
|
||||
if (WTQueueSizeSet(*hctx, i))
|
||||
{
|
||||
GDK_NOTE (INPUT, g_print("Queue size set to %d\n", i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!i)
|
||||
GDK_NOTE (INPUT, g_print("Whoops, no queue size could be set\n"));
|
||||
for (cursorix = firstcsr; cursorix < firstcsr + ncsrtypes; cursorix++)
|
||||
{
|
||||
active = FALSE;
|
||||
@@ -399,7 +422,7 @@ gdk_input_wintab_init (void)
|
||||
gdkdev->axes[k].max_value = axis_x.axMax;
|
||||
gdkdev->info.axes[k].use = GDK_AXIS_X;
|
||||
gdkdev->info.axes[k].min = axis_x.axMin;
|
||||
gdkdev->info.axes[k].min = axis_x.axMax;
|
||||
gdkdev->info.axes[k].max = axis_x.axMax;
|
||||
k++;
|
||||
}
|
||||
if (gdkdev->pktdata & PK_Y)
|
||||
@@ -412,7 +435,7 @@ gdk_input_wintab_init (void)
|
||||
gdkdev->axes[k].max_value = axis_y.axMax;
|
||||
gdkdev->info.axes[k].use = GDK_AXIS_Y;
|
||||
gdkdev->info.axes[k].min = axis_y.axMin;
|
||||
gdkdev->info.axes[k].min = axis_y.axMax;
|
||||
gdkdev->info.axes[k].max = axis_y.axMax;
|
||||
k++;
|
||||
}
|
||||
if (gdkdev->pktdata & PK_NORMAL_PRESSURE)
|
||||
@@ -424,8 +447,9 @@ gdk_input_wintab_init (void)
|
||||
gdkdev->axes[k].xmax_value =
|
||||
gdkdev->axes[k].max_value = axis_npressure.axMax;
|
||||
gdkdev->info.axes[k].use = GDK_AXIS_PRESSURE;
|
||||
gdkdev->info.axes[k].min = axis_npressure.axMin;
|
||||
gdkdev->info.axes[k].min = axis_npressure.axMax;
|
||||
/* GIMP seems to expect values in the range 0-1 */
|
||||
gdkdev->info.axes[k].min = 0.0; /*axis_npressure.axMin;*/
|
||||
gdkdev->info.axes[k].max = 1.0; /*axis_npressure.axMax;*/
|
||||
k++;
|
||||
}
|
||||
if (gdkdev->pktdata & PK_ORIENTATION)
|
||||
@@ -447,7 +471,7 @@ gdk_input_wintab_init (void)
|
||||
gdkdev->axes[k].max_value = 1000;
|
||||
gdkdev->info.axes[k].use = axis;
|
||||
gdkdev->info.axes[k].min = -1000;
|
||||
gdkdev->info.axes[k].min = 1000;
|
||||
gdkdev->info.axes[k].max = 1000;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
@@ -670,6 +694,31 @@ _gdk_input_enter_event (GdkWindow *window)
|
||||
input_window->root_y = root_y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the currently active keyboard modifiers (ignoring the mouse buttons)
|
||||
* We could use gdk_window_get_pointer but that function does a lot of other
|
||||
* expensive things besides getting the modifiers. This code is somewhat based
|
||||
* on build_pointer_event_state from gdkevents-win32.c
|
||||
*/
|
||||
static guint
|
||||
get_modifier_key_state (void)
|
||||
{
|
||||
guint state;
|
||||
|
||||
state = 0;
|
||||
/* High-order bit is up/down, low order bit is toggled/untoggled */
|
||||
if (GetKeyState (VK_CONTROL) < 0)
|
||||
state |= GDK_CONTROL_MASK;
|
||||
if (GetKeyState (VK_SHIFT) < 0)
|
||||
state |= GDK_SHIFT_MASK;
|
||||
if (GetKeyState (VK_MENU) < 0)
|
||||
state |= GDK_MOD1_MASK;
|
||||
if (GetKeyState (VK_CAPITAL) & 0x1)
|
||||
state |= GDK_LOCK_MASK;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_input_other_event (GdkEvent *event,
|
||||
MSG *msg,
|
||||
@@ -680,11 +729,11 @@ _gdk_input_other_event (GdkEvent *event,
|
||||
GdkWindow *current_window;
|
||||
#endif
|
||||
GdkDisplay *display;
|
||||
GdkWindowObject *obj;
|
||||
GdkWindowImplWin32 *impl;
|
||||
GdkWindowObject *obj, *grab_obj;
|
||||
GdkInputWindow *input_window;
|
||||
GdkDevicePrivate *gdkdev = NULL;
|
||||
GdkEventMask masktest;
|
||||
guint key_state;
|
||||
POINT pt;
|
||||
|
||||
PACKET packet;
|
||||
@@ -727,12 +776,11 @@ _gdk_input_other_event (GdkEvent *event,
|
||||
}
|
||||
|
||||
obj = GDK_WINDOW_OBJECT (window);
|
||||
impl = GDK_WINDOW_IMPL_WIN32 (obj->impl);
|
||||
|
||||
switch (msg->message)
|
||||
{
|
||||
case WT_PACKET:
|
||||
if (window == _gdk_parent_root)
|
||||
if (window == _gdk_parent_root && x_grab_window == NULL)
|
||||
{
|
||||
GDK_NOTE (EVENTS_OR_INPUT, g_print ("...is root\n"));
|
||||
return FALSE;
|
||||
@@ -791,17 +839,46 @@ _gdk_input_other_event (GdkEvent *event,
|
||||
masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON3_MOTION_MASK;
|
||||
}
|
||||
|
||||
/* See if input is grabbed */
|
||||
/* FIXME: x_grab_owner_events should probably be handled somehow */
|
||||
if (x_grab_window != NULL)
|
||||
{
|
||||
grab_obj = GDK_WINDOW_OBJECT (x_grab_window);
|
||||
if (!GDK_WINDOW_IMPL_WIN32 (grab_obj->impl)->extension_events_selected
|
||||
|| !(grab_obj->extension_events & masktest)
|
||||
|| !(x_grab_mask && masktest))
|
||||
{
|
||||
GDK_NOTE (EVENTS_OR_INPUT,
|
||||
g_print ("...grabber doesn't want it\n"));
|
||||
return FALSE;
|
||||
}
|
||||
GDK_NOTE (EVENTS_OR_INPUT, g_print ("...to grabber\n"));
|
||||
|
||||
g_object_ref(x_grab_window);
|
||||
g_object_unref(window);
|
||||
window = x_grab_window;
|
||||
obj = grab_obj;
|
||||
}
|
||||
/* Now we can check if the window wants the event, and
|
||||
* propagate if necessary.
|
||||
*/
|
||||
dijkstra:
|
||||
if (!impl->extension_events_selected
|
||||
if (!GDK_WINDOW_IMPL_WIN32 (obj->impl)->extension_events_selected
|
||||
|| !(obj->extension_events & masktest))
|
||||
{
|
||||
GDK_NOTE (EVENTS_OR_INPUT, g_print ("...not selected\n"));
|
||||
|
||||
if (obj->parent == GDK_WINDOW_OBJECT (_gdk_parent_root))
|
||||
return FALSE;
|
||||
|
||||
/* It is not good to propagate the extended events up to the parent
|
||||
* if this window wants normal (not extended) motion/button events */
|
||||
if (obj->event_mask & masktest)
|
||||
{
|
||||
GDK_NOTE (EVENTS_OR_INPUT,
|
||||
g_print ("...wants ordinary event, ignoring this\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
@@ -827,7 +904,7 @@ _gdk_input_other_event (GdkEvent *event,
|
||||
return FALSE;
|
||||
|
||||
event->any.window = window;
|
||||
|
||||
key_state = get_modifier_key_state ();
|
||||
if (event->any.type == GDK_BUTTON_PRESS
|
||||
|| event->any.type == GDK_BUTTON_RELEASE)
|
||||
{
|
||||
@@ -841,16 +918,26 @@ _gdk_input_other_event (GdkEvent *event,
|
||||
return FALSE;
|
||||
#endif
|
||||
#endif
|
||||
event->button.axes = g_new(gdouble, gdkdev->info.num_axes);
|
||||
|
||||
gdk_input_translate_coordinates (gdkdev, input_window,
|
||||
gdkdev->last_axis_data,
|
||||
event->button.axes,
|
||||
&event->button.x,
|
||||
&event->button.y);
|
||||
|
||||
/* Also calculate root coordinates. Note that input_window->root_x
|
||||
is in Win32 screen coordinates. */
|
||||
event->button.x_root = event->button.x + input_window->root_x
|
||||
+ _gdk_offset_x;
|
||||
event->button.y_root = event->button.y + input_window->root_y
|
||||
+ _gdk_offset_y;
|
||||
|
||||
event->button.state = ((gdkdev->button_state << 8)
|
||||
& (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
|
||||
| GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
|
||||
| GDK_BUTTON5_MASK));
|
||||
| GDK_BUTTON5_MASK))
|
||||
| key_state;
|
||||
GDK_NOTE (EVENTS_OR_INPUT,
|
||||
g_print ("WINTAB button %s:%d %g,%g\n",
|
||||
(event->button.type == GDK_BUTTON_PRESS ?
|
||||
@@ -864,16 +951,26 @@ _gdk_input_other_event (GdkEvent *event,
|
||||
event->motion.is_hint = FALSE;
|
||||
event->motion.device = &gdkdev->info;
|
||||
|
||||
event->motion.axes = g_new(gdouble, gdkdev->info.num_axes);
|
||||
|
||||
gdk_input_translate_coordinates (gdkdev, input_window,
|
||||
gdkdev->last_axis_data,
|
||||
event->motion.axes,
|
||||
&event->motion.x,
|
||||
&event->motion.y);
|
||||
|
||||
/* Also calculate root coordinates. Note that input_window->root_x
|
||||
is in Win32 screen coordinates. */
|
||||
event->motion.x_root = event->motion.x + input_window->root_x
|
||||
+ _gdk_offset_x;
|
||||
event->motion.y_root = event->motion.y + input_window->root_y
|
||||
+ _gdk_offset_y;
|
||||
|
||||
event->motion.state = ((gdkdev->button_state << 8)
|
||||
& (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
|
||||
| GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
|
||||
| GDK_BUTTON5_MASK));
|
||||
| GDK_BUTTON5_MASK))
|
||||
| key_state;
|
||||
|
||||
GDK_NOTE (EVENTS_OR_INPUT,
|
||||
g_print ("WINTAB motion: %g,%g\n",
|
||||
@@ -885,7 +982,7 @@ _gdk_input_other_event (GdkEvent *event,
|
||||
*/
|
||||
if ((gdkdev->pktdata & PK_NORMAL_PRESSURE
|
||||
&& (event->motion.state & GDK_BUTTON1_MASK)
|
||||
&& packet.pkNormalPressure <= MAX (0, gdkdev->npbtnmarks[0] - 2))
|
||||
&& packet.pkNormalPressure <= MAX (0, (gint) gdkdev->npbtnmarks[0] - 2))
|
||||
|| (gdkdev->pktdata & PK_NORMAL_PRESSURE
|
||||
&& !(event->motion.state & GDK_BUTTON1_MASK)
|
||||
&& packet.pkNormalPressure > gdkdev->npbtnmarks[1] + 2))
|
||||
@@ -904,7 +1001,8 @@ _gdk_input_other_event (GdkEvent *event,
|
||||
event2->button.state = ((gdkdev->button_state << 8)
|
||||
& (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
|
||||
| GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
|
||||
| GDK_BUTTON5_MASK));
|
||||
| GDK_BUTTON5_MASK))
|
||||
| key_state;
|
||||
event2->button.button = 1;
|
||||
GDK_NOTE (EVENTS_OR_INPUT,
|
||||
g_print ("WINTAB synthesized button %s: %d %g,%gg\n",
|
||||
@@ -1008,6 +1106,11 @@ _gdk_input_grab_pointer (GdkWindow *window,
|
||||
if (new_window)
|
||||
{
|
||||
new_window->grabbed = TRUE;
|
||||
x_grab_window = window;
|
||||
x_grab_mask = event_mask;
|
||||
x_grab_owner_events = owner_events;
|
||||
|
||||
/* FIXME: Do we need to handle confine_to and time? */
|
||||
|
||||
tmp_list = _gdk_input_devices;
|
||||
while (tmp_list)
|
||||
@@ -1037,6 +1140,7 @@ _gdk_input_grab_pointer (GdkWindow *window,
|
||||
}
|
||||
else
|
||||
{
|
||||
x_grab_window = NULL;
|
||||
tmp_list = _gdk_input_devices;
|
||||
while (tmp_list)
|
||||
{
|
||||
@@ -1094,6 +1198,7 @@ _gdk_input_ungrab_pointer (guint32 time)
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
}
|
||||
x_grab_window = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1134,42 +1239,27 @@ gdk_device_get_state (GdkDevice *device,
|
||||
GdkDevicePrivate *gdkdev;
|
||||
GdkInputWindow *input_window;
|
||||
|
||||
if (mask)
|
||||
gdk_window_get_pointer (window, NULL, NULL, mask);
|
||||
|
||||
gdkdev = (GdkDevicePrivate *)device;
|
||||
/* For now just use the last known button and axis state of the device.
|
||||
* Since graphical tablets send an insane amount of motion events each
|
||||
* second, the info should be fairly up to date */
|
||||
if (mask)
|
||||
{
|
||||
gdk_window_get_pointer (window, NULL, NULL, mask);
|
||||
*mask &= 0xFF; /* Mask away core pointer buttons */
|
||||
*mask |= ((gdkdev->button_state << 8)
|
||||
& (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
|
||||
| GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
|
||||
| GDK_BUTTON5_MASK));
|
||||
}
|
||||
input_window = _gdk_input_window_find (window);
|
||||
g_return_if_fail (input_window != NULL);
|
||||
|
||||
#if 0 /* FIXME */
|
||||
state = XQueryDeviceState (gdk_display, gdkdev->xdevice);
|
||||
input_class = state->data;
|
||||
for (i = 0; i < state->num_classes; i++)
|
||||
{
|
||||
switch (input_class->class)
|
||||
{
|
||||
case ValuatorClass:
|
||||
if (axes)
|
||||
gdk_input_translate_coordinates (gdkdev, input_window,
|
||||
((XValuatorState *)input_class)->valuators,
|
||||
axes, NULL, NULL);
|
||||
break;
|
||||
|
||||
case ButtonClass:
|
||||
if (mask)
|
||||
{
|
||||
*mask &= 0xFF;
|
||||
if (((XButtonState *)input_class)->num_buttons > 0)
|
||||
*mask |= ((XButtonState *)input_class)->buttons[0] << 7;
|
||||
/* GDK_BUTTON1_MASK = 1 << 8, and button n is stored
|
||||
* in bit 1<<(n%8) in byte n/8. n = 1,2,... */
|
||||
}
|
||||
break;
|
||||
}
|
||||
input_class = (XInputClass *)(((char *)input_class)+input_class->length);
|
||||
}
|
||||
XFreeDeviceState (state);
|
||||
#endif
|
||||
/* For some reason, input_window is sometimes NULL when I use The GIMP 2
|
||||
* (bug #141543?). Avoid crashing if debugging is disabled. */
|
||||
if (axes && gdkdev->last_axis_data && input_window)
|
||||
gdk_input_translate_coordinates (gdkdev, input_window,
|
||||
gdkdev->last_axis_data,
|
||||
axes, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -203,8 +203,6 @@ update_keymap (void)
|
||||
*ksymp = GDK_KP_Separator; break;
|
||||
case VK_SUBTRACT:
|
||||
*ksymp = GDK_KP_Subtract; break;
|
||||
case VK_DECIMAL:
|
||||
*ksymp = GDK_KP_Decimal; break;
|
||||
case VK_DIVIDE:
|
||||
*ksymp = GDK_KP_Divide; break;
|
||||
case VK_F1:
|
||||
|
||||
@@ -115,8 +115,8 @@ _gdk_windowing_init (gint *argc,
|
||||
_cf_utf8_string = RegisterClipboardFormat ("UTF8_STRING");
|
||||
|
||||
_utf8_string = gdk_atom_intern ("UTF8_STRING", FALSE);
|
||||
_compound_text = gdk_atom_intern ("COMPOUND_TEXT", FALSE);
|
||||
_text_uri_list = gdk_atom_intern ("text/uri-list", FALSE);
|
||||
_targets = gdk_atom_intern ("TARGETS", FALSE);
|
||||
|
||||
_local_dnd = gdk_atom_intern ("LocalDndSelection", FALSE);
|
||||
_gdk_win32_dropfiles = gdk_atom_intern ("DROPFILES_DND", FALSE);
|
||||
|
||||
@@ -363,24 +363,10 @@ void _gdk_win32_adjust_client_rect (GdkWindow *window,
|
||||
void _gdk_win32_get_adjusted_client_rect (GdkWindow *window,
|
||||
RECT *RECT);
|
||||
|
||||
void _gdk_selection_property_store (GdkWindow *owner,
|
||||
GdkAtom type,
|
||||
gint format,
|
||||
guchar *data,
|
||||
gint length);
|
||||
|
||||
void _gdk_selection_property_delete (GdkWindow *);
|
||||
|
||||
void _gdk_dropfiles_store (gchar *data);
|
||||
|
||||
gint _gdk_utf8_to_ucs2 (wchar_t *dest,
|
||||
const gchar *src,
|
||||
gint src_len,
|
||||
gint dest_max);
|
||||
|
||||
gchar *_gdk_ucs2_to_utf8 (const wchar_t *src,
|
||||
gint src_len);
|
||||
|
||||
void _gdk_wchar_text_handle (GdkFont *font,
|
||||
const wchar_t *wcstr,
|
||||
int wclen,
|
||||
@@ -491,6 +477,7 @@ extern WORD _cf_utf8_string;
|
||||
extern GdkAtom _utf8_string;
|
||||
extern GdkAtom _compound_text;
|
||||
extern GdkAtom _text_uri_list;
|
||||
extern GdkAtom _targets;
|
||||
|
||||
/* DND selections */
|
||||
extern GdkAtom _local_dnd;
|
||||
|
||||
@@ -198,12 +198,10 @@ find_common_locale (const guchar *data,
|
||||
* bytes for each Unicode char should be enough, Windows code pages
|
||||
* are either single- or double-byte.
|
||||
*/
|
||||
*bufp = g_malloc ((nchars+1) * 2);
|
||||
wcs = g_new (wchar_t, nchars+1);
|
||||
*bufp = g_malloc ((nchars+1)*2);
|
||||
|
||||
/* Convert to Windows wide chars into temp buf */
|
||||
_gdk_utf8_to_ucs2 (wcs, data, nelements, nchars);
|
||||
wcs[nchars] = 0;
|
||||
wcs = g_utf8_to_utf16 (data, nelements, NULL, NULL, NULL);
|
||||
|
||||
/* For each code page that is the default for an installed locale: */
|
||||
for (i = 0; i < G_N_ELEMENTS (locales); i++)
|
||||
@@ -254,7 +252,8 @@ gdk_property_change (GdkWindow *window,
|
||||
gchar *prop_name, *type_name;
|
||||
guchar *ucptr, *buf = NULL;
|
||||
wchar_t *wcptr;
|
||||
enum { PLAIN_ASCII, UNICODE_TEXT, SINGLE_LOCALE, RICH_TEXT } method;
|
||||
glong wclen;
|
||||
enum { SYSTEM_CODEPAGE, UNICODE_TEXT, SINGLE_LOCALE, RICH_TEXT } method;
|
||||
gboolean ok = TRUE;
|
||||
|
||||
g_return_if_fail (window != NULL);
|
||||
@@ -279,7 +278,8 @@ gdk_property_change (GdkWindow *window,
|
||||
g_free (type_name)));
|
||||
|
||||
if (property == _gdk_selection_property
|
||||
&& type == GDK_TARGET_STRING
|
||||
&& ((type == GDK_TARGET_STRING && GetACP () == 1252) ||
|
||||
type == _utf8_string)
|
||||
&& format == 8
|
||||
&& mode == GDK_PROP_MODE_REPLACE)
|
||||
{
|
||||
@@ -289,22 +289,31 @@ gdk_property_change (GdkWindow *window,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if only ASCII */
|
||||
for (i = 0; i < nelements; i++)
|
||||
if (data[i] >= 0200)
|
||||
break;
|
||||
if (type == _utf8_string)
|
||||
{
|
||||
/* Check if only ASCII */
|
||||
for (i = 0; i < nelements; i++)
|
||||
if (data[i] >= 0200)
|
||||
break;
|
||||
}
|
||||
else /* if (type == GDK_TARGET_STRING) */
|
||||
{
|
||||
/* Check that no 0200..0240 chars present, as they
|
||||
* differ between ISO-8859-1 and CP1252.
|
||||
*/
|
||||
for (i = 0; i < nelements; i++)
|
||||
if (data[i] >= 0200 && data[i] < 0240)
|
||||
break;
|
||||
}
|
||||
nchars = g_utf8_strlen (data, nelements);
|
||||
|
||||
if (i == nelements)
|
||||
nchars = nelements;
|
||||
else
|
||||
nchars = g_utf8_strlen (data, nelements);
|
||||
|
||||
GDK_NOTE (DND, g_print ("...nchars:%d\n", nchars));
|
||||
|
||||
if (i == nelements)
|
||||
{
|
||||
/* If only ASCII, use CF_TEXT and the data as such. */
|
||||
method = PLAIN_ASCII;
|
||||
/* If UTF-8 and only ASCII, or if STRING (ISO-8859-1) and
|
||||
* system codepage is CP1252, use CF_TEXT and the data as
|
||||
* such.
|
||||
*/
|
||||
method = SYSTEM_CODEPAGE;
|
||||
size = nelements;
|
||||
for (i = 0; i < nelements; i++)
|
||||
if (data[i] == '\n')
|
||||
@@ -314,9 +323,15 @@ gdk_property_change (GdkWindow *window,
|
||||
}
|
||||
else if (IS_WIN_NT ())
|
||||
{
|
||||
/* On NT, use CF_UNICODETEXT if any non-ASCII char present */
|
||||
/* On NT, use CF_UNICODETEXT if any non-system codepage char
|
||||
* present.
|
||||
*/
|
||||
method = UNICODE_TEXT;
|
||||
size = (nchars + 1) * 2;
|
||||
|
||||
wcptr = g_utf8_to_utf16 (data, nelements, NULL, &wclen, NULL);
|
||||
|
||||
wclen++; /* Terminating 0 */
|
||||
size = wclen * 2;
|
||||
GDK_NOTE (DND, g_print ("...as Unicode\n"));
|
||||
}
|
||||
else if (find_common_locale (data, nelements, nchars, &lcid, &buf, &size))
|
||||
@@ -347,7 +362,7 @@ gdk_property_change (GdkWindow *window,
|
||||
rtf = g_string_append_c (rtf, *p);
|
||||
p++;
|
||||
}
|
||||
else if (*p < 0200)
|
||||
else if (*p < 0200 && *p >= ' ')
|
||||
{
|
||||
rtf = g_string_append_c (rtf, *p);
|
||||
p++;
|
||||
@@ -388,7 +403,7 @@ gdk_property_change (GdkWindow *window,
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case PLAIN_ASCII:
|
||||
case SYSTEM_CODEPAGE:
|
||||
cf = CF_TEXT;
|
||||
for (i = 0; i < nelements; i++)
|
||||
{
|
||||
@@ -401,10 +416,8 @@ gdk_property_change (GdkWindow *window,
|
||||
|
||||
case UNICODE_TEXT:
|
||||
cf = CF_UNICODETEXT;
|
||||
wcptr = (wchar_t *) ucptr;
|
||||
if (_gdk_utf8_to_ucs2 (wcptr, data, nelements, nchars) == -1)
|
||||
g_warning ("_gdk_utf8_to_ucs2() failed");
|
||||
wcptr[nchars] = 0;
|
||||
memmove (ucptr, wcptr, size);
|
||||
g_free (wcptr);
|
||||
break;
|
||||
|
||||
case SINGLE_LOCALE:
|
||||
|
||||
+230
-226
@@ -41,7 +41,7 @@
|
||||
|
||||
typedef struct {
|
||||
guchar *data;
|
||||
gint length;
|
||||
gsize length;
|
||||
gint format;
|
||||
GdkAtom type;
|
||||
} GdkSelProp;
|
||||
@@ -62,7 +62,73 @@ _gdk_win32_selection_init (void)
|
||||
sel_owner_table = g_hash_table_new (NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
/* The specifications for COMPOUND_TEXT and STRING specify that C0 and
|
||||
* C1 are not allowed except for \n and \t, however the X conversions
|
||||
* routines for COMPOUND_TEXT only enforce this in one direction,
|
||||
* causing cut-and-paste of \r and \r\n separated text to fail.
|
||||
* This routine strips out all non-allowed C0 and C1 characters
|
||||
* from the input string and also canonicalizes \r, and \r\n to \n
|
||||
*/
|
||||
static gchar *
|
||||
sanitize_utf8 (const gchar *src,
|
||||
gint length)
|
||||
{
|
||||
GString *result = g_string_sized_new (length + 1);
|
||||
const gchar *p = src;
|
||||
const gchar *endp = src + length;
|
||||
|
||||
while (p < endp)
|
||||
{
|
||||
if (*p == '\r')
|
||||
{
|
||||
p++;
|
||||
if (*p == '\n')
|
||||
p++;
|
||||
|
||||
g_string_append_c (result, '\n');
|
||||
}
|
||||
else
|
||||
{
|
||||
gunichar ch = g_utf8_get_char (p);
|
||||
char buf[7];
|
||||
gint buflen;
|
||||
|
||||
if (!((ch < 0x20 && ch != '\t' && ch != '\n') || (ch >= 0x7f && ch < 0xa0)))
|
||||
{
|
||||
buflen = g_unichar_to_utf8 (ch, buf);
|
||||
g_string_append_len (result, buf, buflen);
|
||||
}
|
||||
|
||||
p = g_utf8_next_char (p);
|
||||
}
|
||||
}
|
||||
g_string_append_c (result, '\0');
|
||||
|
||||
return g_string_free (result, FALSE);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
_gdk_utf8_to_string_target_internal (const gchar *str,
|
||||
gint length)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
gchar *tmp_str = sanitize_utf8 (str, length);
|
||||
gchar *result = g_convert_with_fallback (tmp_str, -1,
|
||||
"ISO-8859-1", "UTF-8",
|
||||
NULL, NULL, NULL, &error);
|
||||
if (!result)
|
||||
{
|
||||
g_warning ("Error converting from UTF-8 to STRING: %s",
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_free (tmp_str);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_selection_property_store (GdkWindow *owner,
|
||||
GdkAtom type,
|
||||
gint format,
|
||||
@@ -78,8 +144,27 @@ _gdk_selection_property_store (GdkWindow *owner,
|
||||
g_hash_table_remove (sel_prop_table, GDK_WINDOW_HWND (owner));
|
||||
}
|
||||
prop = g_new (GdkSelProp, 1);
|
||||
prop->data = data;
|
||||
prop->length = length;
|
||||
|
||||
if (type == GDK_TARGET_STRING)
|
||||
{
|
||||
/* We know that data is UTF-8 */
|
||||
prop->data = _gdk_utf8_to_string_target_internal (data, length);
|
||||
g_free (data);
|
||||
|
||||
if (!prop->data)
|
||||
{
|
||||
g_free (prop);
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
prop->length = strlen (prop->data + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
prop->data = data;
|
||||
prop->length = length;
|
||||
}
|
||||
prop->format = format;
|
||||
prop->type = type;
|
||||
g_hash_table_insert (sel_prop_table, GDK_WINDOW_HWND (owner), prop);
|
||||
@@ -120,7 +205,8 @@ gdk_selection_owner_set_for_display (GdkDisplay *display,
|
||||
GdkEvent tmp_event;
|
||||
gchar *sel_name;
|
||||
|
||||
g_return_val_if_fail (display == gdk_display_get_default (), FALSE);
|
||||
g_return_val_if_fail (display == _gdk_display, FALSE);
|
||||
g_return_val_if_fail (selection != GDK_NONE, FALSE);
|
||||
|
||||
GDK_NOTE (DND,
|
||||
(sel_name = gdk_atom_name (selection),
|
||||
@@ -176,7 +262,7 @@ gdk_selection_owner_set_for_display (GdkDisplay *display,
|
||||
tmp_event.selection.window = owner;
|
||||
tmp_event.selection.send_event = FALSE;
|
||||
tmp_event.selection.selection = selection;
|
||||
tmp_event.selection.target = GDK_TARGET_STRING;
|
||||
tmp_event.selection.target = _utf8_string;
|
||||
tmp_event.selection.property = _gdk_selection_property;
|
||||
tmp_event.selection.requestor = (guint32) hwnd;
|
||||
tmp_event.selection.time = time;
|
||||
@@ -194,12 +280,13 @@ gdk_selection_owner_get_for_display (GdkDisplay *display,
|
||||
GdkWindow *window;
|
||||
gchar *sel_name;
|
||||
|
||||
g_return_val_if_fail (display == gdk_display_get_default (), NULL);
|
||||
g_return_val_if_fail (display == _gdk_display, NULL);
|
||||
g_return_val_if_fail (selection != GDK_NONE, NULL);
|
||||
|
||||
/* Return NULL for CLIPBOARD, because otherwise cut&paste
|
||||
* inside the same application doesn't work. We must pretend to gtk
|
||||
* that we don't have the selection, so that we always fetch it from
|
||||
* the Windows clipboard. See also comments in
|
||||
/* Return NULL for CLIPBOARD, because otherwise cut&paste inside the
|
||||
* same application doesn't work. We must pretend to gtk that we
|
||||
* don't have the selection, so that we always fetch it from the
|
||||
* Windows clipboard. See also comments in
|
||||
* gdk_selection_send_notify().
|
||||
*/
|
||||
if (selection == GDK_SELECTION_CLIPBOARD)
|
||||
@@ -247,8 +334,11 @@ gdk_selection_convert (GdkWindow *requestor,
|
||||
HGLOBAL hdata;
|
||||
GdkAtom property = _gdk_selection_property;
|
||||
gchar *sel_name, *tgt_name;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_if_fail (selection != GDK_NONE);
|
||||
g_return_if_fail (requestor != NULL);
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (requestor))
|
||||
return;
|
||||
|
||||
@@ -262,8 +352,7 @@ gdk_selection_convert (GdkWindow *requestor,
|
||||
g_free (sel_name),
|
||||
g_free (tgt_name)));
|
||||
|
||||
if (selection == GDK_SELECTION_CLIPBOARD &&
|
||||
target == gdk_atom_intern ("TARGETS", FALSE))
|
||||
if (selection == GDK_SELECTION_CLIPBOARD && target == _targets)
|
||||
{
|
||||
/* He wants to know what formats are on the clipboard. If there
|
||||
* is some kind of text, tell him so.
|
||||
@@ -276,7 +365,7 @@ gdk_selection_convert (GdkWindow *requestor,
|
||||
IsClipboardFormatAvailable (CF_TEXT))
|
||||
{
|
||||
GdkAtom *data = g_new (GdkAtom, 1);
|
||||
*data = GDK_TARGET_STRING;
|
||||
*data = _utf8_string;
|
||||
_gdk_selection_property_store (requestor, GDK_SELECTION_TYPE_ATOM,
|
||||
32, (guchar *) data, 1 * sizeof (GdkAtom));
|
||||
}
|
||||
@@ -286,36 +375,36 @@ gdk_selection_convert (GdkWindow *requestor,
|
||||
API_CALL (CloseClipboard, ());
|
||||
}
|
||||
else if (selection == GDK_SELECTION_CLIPBOARD &&
|
||||
(target == _compound_text ||
|
||||
target == GDK_TARGET_STRING))
|
||||
(target == GDK_TARGET_STRING ||
|
||||
target == _utf8_string))
|
||||
{
|
||||
/* Converting the CLIPBOARD selection means he wants the
|
||||
* contents of the clipboard. Get the clipboard data,
|
||||
* and store it for later.
|
||||
* contents of the clipboard. Get the clipboard data, and store
|
||||
* it for later.
|
||||
*/
|
||||
if (!API_CALL (OpenClipboard, (GDK_WINDOW_HWND (requestor))))
|
||||
return;
|
||||
|
||||
/* Try various formats. First the simplest, CF_UNICODETEXT. */
|
||||
if ((hdata = GetClipboardData (CF_UNICODETEXT)) != NULL)
|
||||
if (IS_WIN_NT () && (hdata = GetClipboardData (CF_UNICODETEXT)) != NULL)
|
||||
{
|
||||
wchar_t *ptr, *wcs, *p, *q;
|
||||
guchar *data;
|
||||
gint length, wclen;
|
||||
glong length, wclen;
|
||||
|
||||
if ((ptr = GlobalLock (hdata)) != NULL)
|
||||
{
|
||||
length = GlobalSize (hdata);
|
||||
|
||||
GDK_NOTE (DND, g_print ("...CF_UNICODETEXT: %d bytes\n",
|
||||
GDK_NOTE (DND, g_print ("...CF_UNICODETEXT: %ld bytes\n",
|
||||
length));
|
||||
|
||||
/* Strip out \r */
|
||||
wcs = g_new (wchar_t, (length + 1) * 2);
|
||||
wcs = g_new (wchar_t, length / 2 + 1);
|
||||
p = ptr;
|
||||
q = wcs;
|
||||
wclen = 0;
|
||||
while (*p)
|
||||
while (p < ptr + length / 2)
|
||||
{
|
||||
if (*p != '\r')
|
||||
{
|
||||
@@ -325,11 +414,16 @@ gdk_selection_convert (GdkWindow *requestor,
|
||||
p++;
|
||||
}
|
||||
|
||||
data = _gdk_ucs2_to_utf8 (wcs, wclen);
|
||||
data = g_utf16_to_utf8 (wcs, wclen, NULL, NULL, &error);
|
||||
g_free (wcs);
|
||||
|
||||
_gdk_selection_property_store (requestor, target, 8,
|
||||
data, strlen (data) + 1);
|
||||
|
||||
if (!data)
|
||||
{
|
||||
g_error_free (error);
|
||||
}
|
||||
else
|
||||
_gdk_selection_property_store (requestor, target, 8,
|
||||
data, strlen (data) + 1);
|
||||
GlobalUnlock (hdata);
|
||||
}
|
||||
}
|
||||
@@ -347,7 +441,7 @@ gdk_selection_convert (GdkWindow *requestor,
|
||||
length, ptr));
|
||||
|
||||
_gdk_selection_property_store (requestor, target, 8,
|
||||
g_strdup (ptr), strlen (ptr) + 1);
|
||||
g_memdup (ptr, length), length);
|
||||
GlobalUnlock (hdata);
|
||||
}
|
||||
}
|
||||
@@ -361,13 +455,13 @@ gdk_selection_convert (GdkWindow *requestor,
|
||||
UINT cp = CP_ACP;
|
||||
wchar_t *wcs, *wcs2, *p, *q;
|
||||
guchar *ptr, *data;
|
||||
gint length, wclen;
|
||||
glong length, wclen, wclen2;
|
||||
|
||||
if ((ptr = GlobalLock (hdata)) != NULL)
|
||||
{
|
||||
length = GlobalSize (hdata);
|
||||
|
||||
GDK_NOTE (DND, g_print ("...CF_TEXT: %d bytes: %.10s\n",
|
||||
GDK_NOTE (DND, g_print ("...CF_TEXT: %ld bytes: %.10s\n",
|
||||
length, ptr));
|
||||
|
||||
if ((hlcid = GetClipboardData (CF_LOCALE)) != NULL)
|
||||
@@ -385,30 +479,33 @@ gdk_selection_convert (GdkWindow *requestor,
|
||||
}
|
||||
|
||||
wcs = g_new (wchar_t, length + 1);
|
||||
wclen = MultiByteToWideChar (cp, 0, ptr, -1,
|
||||
wclen = MultiByteToWideChar (cp, 0, ptr, length,
|
||||
wcs, length + 1);
|
||||
|
||||
/* Strip out \r */
|
||||
wcs2 = g_new (wchar_t, wclen);
|
||||
p = wcs;
|
||||
q = wcs2;
|
||||
wclen = 0;
|
||||
while (*p)
|
||||
wclen2 = 0;
|
||||
while (p < wcs + wclen)
|
||||
{
|
||||
if (*p != '\r')
|
||||
{
|
||||
*q++ = *p;
|
||||
wclen++;
|
||||
wclen2++;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
g_free (wcs);
|
||||
|
||||
data = _gdk_ucs2_to_utf8 (wcs2, wclen);
|
||||
data = g_utf16_to_utf8 (wcs2, wclen2, NULL, &length, &error);
|
||||
g_free (wcs2);
|
||||
|
||||
_gdk_selection_property_store (requestor, target, 8,
|
||||
data, strlen (data) + 1);
|
||||
|
||||
if (!data)
|
||||
g_error_free (error);
|
||||
else
|
||||
_gdk_selection_property_store (requestor, target, 8,
|
||||
data, length + 1);
|
||||
GlobalUnlock (hdata);
|
||||
}
|
||||
}
|
||||
@@ -498,16 +595,16 @@ _gdk_selection_property_delete (GdkWindow *window)
|
||||
|
||||
void
|
||||
gdk_selection_send_notify_for_display (GdkDisplay *display,
|
||||
guint32 requestor,
|
||||
GdkAtom selection,
|
||||
GdkAtom target,
|
||||
GdkAtom property,
|
||||
guint32 time)
|
||||
guint32 requestor,
|
||||
GdkAtom selection,
|
||||
GdkAtom target,
|
||||
GdkAtom property,
|
||||
guint32 time)
|
||||
{
|
||||
GdkEvent tmp_event;
|
||||
gchar *sel_name, *tgt_name, *prop_name;
|
||||
|
||||
g_return_if_fail (display == gdk_display_get_default ());
|
||||
g_return_if_fail (display == _gdk_display);
|
||||
|
||||
GDK_NOTE (DND,
|
||||
(sel_name = gdk_atom_name (selection),
|
||||
@@ -522,12 +619,13 @@ gdk_selection_send_notify_for_display (GdkDisplay *display,
|
||||
g_free (tgt_name),
|
||||
g_free (prop_name)));
|
||||
|
||||
/* Send ourselves a selection clear message so that gtk thinks we don't
|
||||
* have the selection, and will claim it anew when needed, and
|
||||
/* Send ourselves a selection clear message so that gtk thinks we
|
||||
* don't have the selection, and will claim it anew when needed, and
|
||||
* we thus get a chance to store data in the Windows clipboard.
|
||||
* Otherwise, if a gtkeditable does a copy to CLIPBOARD several times
|
||||
* only the first one actually gets copied to the Windows clipboard,
|
||||
* as only the first one causes a call to gdk_property_change().
|
||||
* Otherwise, if a gtkeditable does a copy to CLIPBOARD several
|
||||
* times only the first one actually gets copied to the Windows
|
||||
* clipboard, as only the first one causes a call to
|
||||
* gdk_property_change().
|
||||
*
|
||||
* Hmm, there is something fishy with this. Cut and paste inside the
|
||||
* same app didn't work, the gtkeditable immediately forgot the
|
||||
@@ -548,19 +646,25 @@ gdk_selection_send_notify_for_display (GdkDisplay *display,
|
||||
gdk_event_put (&tmp_event);
|
||||
}
|
||||
|
||||
/* Simplistic implementations of text list and compound text functions */
|
||||
|
||||
/* It's hard to say whether implementing this actually is of any use
|
||||
* on the Win32 platform? gtk calls only
|
||||
* gdk_text_property_to_utf8_list_for_display().
|
||||
*/
|
||||
gint
|
||||
gdk_text_property_to_text_list_for_display (GdkDisplay *display,
|
||||
gdk_text_property_to_text_list_for_display (GdkDisplay *display,
|
||||
GdkAtom encoding,
|
||||
gint format,
|
||||
const guchar *text,
|
||||
gint length,
|
||||
gchar ***list)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gchar *enc_name;
|
||||
gchar *result;
|
||||
const gchar *charset;
|
||||
const gchar *source_charset = NULL;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
|
||||
g_return_val_if_fail (display == _gdk_display, 0);
|
||||
|
||||
GDK_NOTE (DND, (enc_name = gdk_atom_name (encoding),
|
||||
g_print ("gdk_text_property_to_text_list: %s %d %.20s %d\n",
|
||||
@@ -570,8 +674,25 @@ gdk_text_property_to_text_list_for_display (GdkDisplay *display,
|
||||
if (!list)
|
||||
return 0;
|
||||
|
||||
if (encoding == GDK_TARGET_STRING)
|
||||
source_charset = "ISO-8859-1";
|
||||
else if (encoding == _utf8_string)
|
||||
source_charset = "UTF-8";
|
||||
else
|
||||
source_charset = gdk_atom_name (encoding);
|
||||
|
||||
g_get_charset (&charset);
|
||||
|
||||
result = g_convert (text, length, charset, source_charset,
|
||||
NULL, NULL, &error);
|
||||
if (!result)
|
||||
{
|
||||
g_error_free (error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*list = g_new (gchar *, 1);
|
||||
**list = g_strdup (text);
|
||||
**list = result;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -585,47 +706,6 @@ gdk_free_text_list (gchar **list)
|
||||
g_free (list);
|
||||
}
|
||||
|
||||
gint
|
||||
gdk_string_to_compound_text_for_display (GdkDisplay *display,
|
||||
const gchar *str,
|
||||
GdkAtom *encoding,
|
||||
gint *format,
|
||||
guchar **ctext,
|
||||
gint *length)
|
||||
{
|
||||
g_return_val_if_fail (str != NULL, 0);
|
||||
g_return_val_if_fail (length >= 0, 0);
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
|
||||
|
||||
GDK_NOTE (DND, g_print ("gdk_string_to_compound_text: %.20s\n", str));
|
||||
|
||||
if (encoding)
|
||||
*encoding = _compound_text;
|
||||
|
||||
if (format)
|
||||
*format = 8;
|
||||
|
||||
if (ctext)
|
||||
*ctext = g_strdup (str);
|
||||
|
||||
if (length)
|
||||
*length = strlen (str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_free_compound_text (guchar *ctext)
|
||||
{
|
||||
g_free (ctext);
|
||||
}
|
||||
|
||||
/* These are lifted from gdkselection-x11.c, just to get GTK+ to build.
|
||||
* These functions probably don't make much sense at all in Windows.
|
||||
*/
|
||||
|
||||
/* FIXME */
|
||||
|
||||
static gint
|
||||
make_list (const gchar *text,
|
||||
gint length,
|
||||
@@ -705,7 +785,7 @@ gdk_text_property_to_utf8_list_for_display (GdkDisplay *display,
|
||||
{
|
||||
g_return_val_if_fail (text != NULL, 0);
|
||||
g_return_val_if_fail (length >= 0, 0);
|
||||
g_return_val_if_fail (display == gdk_display_get_default (), 0);
|
||||
g_return_val_if_fail (display == _gdk_display, 0);
|
||||
|
||||
if (encoding == GDK_TARGET_STRING)
|
||||
{
|
||||
@@ -717,164 +797,88 @@ gdk_text_property_to_utf8_list_for_display (GdkDisplay *display,
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar **local_list;
|
||||
gint local_count;
|
||||
gint i;
|
||||
const gchar *charset = NULL;
|
||||
gboolean need_conversion = g_get_charset (&charset);
|
||||
gint count = 0;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Probably COMPOUND text, we fall back to Xlib routines
|
||||
*/
|
||||
local_count = gdk_text_property_to_text_list (encoding,
|
||||
format,
|
||||
text,
|
||||
length,
|
||||
&local_list);
|
||||
if (list)
|
||||
*list = g_new (gchar *, local_count + 1);
|
||||
|
||||
for (i=0; i<local_count; i++)
|
||||
{
|
||||
/* list contains stuff in our default encoding
|
||||
*/
|
||||
if (need_conversion)
|
||||
{
|
||||
gchar *utf = g_convert (local_list[i], -1,
|
||||
"UTF-8", charset,
|
||||
NULL, NULL, &error);
|
||||
if (utf)
|
||||
{
|
||||
if (list)
|
||||
(*list)[count++] = utf;
|
||||
else
|
||||
g_free (utf);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Error converting to UTF-8 from '%s': %s",
|
||||
charset, error->message);
|
||||
g_error_free (error);
|
||||
error = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (list)
|
||||
(*list)[count++] = g_strdup (local_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
gdk_free_text_list (local_list);
|
||||
(*list)[count] = NULL;
|
||||
g_warning ("gdk_text_property_to_utf8_list_for_display: encoding %s not handled\n", gdk_atom_name (encoding));
|
||||
|
||||
return count;
|
||||
if (list)
|
||||
*list = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* The specifications for COMPOUND_TEXT and STRING specify that C0 and
|
||||
* C1 are not allowed except for \n and \t, however the X conversions
|
||||
* routines for COMPOUND_TEXT only enforce this in one direction,
|
||||
* causing cut-and-paste of \r and \r\n separated text to fail.
|
||||
* This routine strips out all non-allowed C0 and C1 characters
|
||||
* from the input string and also canonicalizes \r, and \r\n to \n
|
||||
*/
|
||||
static gchar *
|
||||
sanitize_utf8 (const gchar *src)
|
||||
gint
|
||||
gdk_string_to_compound_text_for_display (GdkDisplay *display,
|
||||
const gchar *str,
|
||||
GdkAtom *encoding,
|
||||
gint *format,
|
||||
guchar **ctext,
|
||||
gint *length)
|
||||
{
|
||||
gint len = strlen (src);
|
||||
GString *result = g_string_sized_new (len);
|
||||
const gchar *p = src;
|
||||
g_return_val_if_fail (str != NULL, 0);
|
||||
g_return_val_if_fail (length >= 0, 0);
|
||||
g_return_val_if_fail (display == _gdk_display, 0);
|
||||
|
||||
while (*p)
|
||||
{
|
||||
if (*p == '\r')
|
||||
{
|
||||
p++;
|
||||
if (*p == '\n')
|
||||
p++;
|
||||
GDK_NOTE (DND, g_print ("gdk_string_to_compound_text_for_display: %.20s\n", str));
|
||||
|
||||
g_string_append_c (result, '\n');
|
||||
}
|
||||
else
|
||||
{
|
||||
gunichar ch = g_utf8_get_char (p);
|
||||
char buf[7];
|
||||
gint buflen;
|
||||
|
||||
if (!((ch < 0x20 && ch != '\t' && ch != '\n') || (ch >= 0x7f && ch < 0xa0)))
|
||||
{
|
||||
buflen = g_unichar_to_utf8 (ch, buf);
|
||||
g_string_append_len (result, buf, buflen);
|
||||
}
|
||||
/* Always fail on Win32. No COMPOUND_TEXT support. */
|
||||
|
||||
p = g_utf8_next_char (p);
|
||||
}
|
||||
}
|
||||
if (encoding)
|
||||
*encoding = GDK_NONE;
|
||||
|
||||
return g_string_free (result, FALSE);
|
||||
if (format)
|
||||
*format = 0;
|
||||
|
||||
if (ctext)
|
||||
*ctext = NULL;
|
||||
|
||||
if (length)
|
||||
*length = 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
gchar *
|
||||
gdk_utf8_to_string_target (const gchar *str)
|
||||
{
|
||||
return sanitize_utf8 (str);
|
||||
return _gdk_utf8_to_string_target_internal (str, strlen (str));
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_utf8_to_compound_text_for_display (GdkDisplay *display,
|
||||
gdk_utf8_to_compound_text_for_display (GdkDisplay *display,
|
||||
const gchar *str,
|
||||
GdkAtom *encoding,
|
||||
gint *format,
|
||||
guchar **ctext,
|
||||
gint *length)
|
||||
{
|
||||
gboolean need_conversion;
|
||||
const gchar *charset;
|
||||
gchar *locale_str, *tmp_str;
|
||||
GError *error = NULL;
|
||||
gboolean result;
|
||||
|
||||
g_return_val_if_fail (str != NULL, FALSE);
|
||||
g_return_val_if_fail (display == gdk_display_get_default (), FALSE);
|
||||
g_return_val_if_fail (display == _gdk_display, FALSE);
|
||||
|
||||
need_conversion = !g_get_charset (&charset);
|
||||
GDK_NOTE (DND, g_print ("gdk_utf8_to_compound_text_for_display: %.20s\n", str));
|
||||
|
||||
tmp_str = sanitize_utf8 (str);
|
||||
/* Always fail on Win32. No COMPOUND_TEXT support. */
|
||||
|
||||
if (need_conversion)
|
||||
{
|
||||
locale_str = g_convert_with_fallback (tmp_str, -1,
|
||||
charset, "UTF-8",
|
||||
NULL, NULL, NULL, &error);
|
||||
g_free (tmp_str);
|
||||
if (encoding)
|
||||
*encoding = GDK_NONE;
|
||||
|
||||
if (!locale_str)
|
||||
{
|
||||
g_warning ("Error converting from UTF-8 to '%s': %s",
|
||||
charset, error->message);
|
||||
g_error_free (error);
|
||||
|
||||
if (encoding)
|
||||
*encoding = GDK_NONE;
|
||||
if (format)
|
||||
*format = GPOINTER_TO_UINT (GDK_ATOM_TO_POINTER (GDK_NONE));
|
||||
if (ctext)
|
||||
*ctext = NULL;
|
||||
if (length)
|
||||
*length = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
locale_str = tmp_str;
|
||||
|
||||
result = gdk_string_to_compound_text (locale_str,
|
||||
encoding, format, ctext, length);
|
||||
if (format)
|
||||
*format = 0;
|
||||
|
||||
g_free (locale_str);
|
||||
if (ctext)
|
||||
*ctext = NULL;
|
||||
|
||||
return result;
|
||||
if (length)
|
||||
*length = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_free_compound_text (guchar *ctext)
|
||||
{
|
||||
/* As we never generate anything claimed to be COMPOUND_TEXT, this
|
||||
* should never be called. Or if it is called, ctext should be the
|
||||
* NULL returned for conversions to COMPOUND_TEXT above.
|
||||
*/
|
||||
g_return_if_fail (ctext == NULL);
|
||||
}
|
||||
|
||||
@@ -529,7 +529,19 @@ gdk_window_new (GdkWindow *parent,
|
||||
impl->width = (attributes->width > 1) ? (attributes->width) : (1);
|
||||
impl->height = (attributes->height > 1) ? (attributes->height) : (1);
|
||||
impl->extension_events_selected = FALSE;
|
||||
private->window_type = attributes->window_type;
|
||||
if (attributes->wclass == GDK_INPUT_ONLY)
|
||||
{
|
||||
/* Backwards compatiblity - we've always ignored
|
||||
* attributes->window_type for input-only windows
|
||||
* before
|
||||
*/
|
||||
if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
|
||||
private->window_type = GDK_WINDOW_TEMP;
|
||||
else
|
||||
private->window_type = GDK_WINDOW_CHILD;
|
||||
}
|
||||
else
|
||||
private->window_type = attributes->window_type;
|
||||
|
||||
if (attributes->wclass == GDK_INPUT_OUTPUT)
|
||||
{
|
||||
|
||||
+23
-15
@@ -305,16 +305,14 @@ gdk_cursor_get_display (GdkCursor *cursor)
|
||||
#ifdef HAVE_XCURSOR
|
||||
|
||||
static XcursorImage*
|
||||
create_cursor_image (GdkPixbuf *pixbuf,
|
||||
gint x,
|
||||
create_cursor_image (GdkPixbuf *pixbuf,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
guint width, height, rowstride, n_channels;
|
||||
guchar *pixels, *src;
|
||||
XcursorImage *xcimage;
|
||||
XcursorPixel *dest;
|
||||
guchar a;
|
||||
gint i, j;
|
||||
|
||||
width = gdk_pixbuf_get_width (pixbuf);
|
||||
height = gdk_pixbuf_get_height (pixbuf);
|
||||
@@ -324,27 +322,37 @@ create_cursor_image (GdkPixbuf *pixbuf,
|
||||
pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||
|
||||
xcimage = XcursorImageCreate (width, height);
|
||||
|
||||
|
||||
xcimage->xhot = x;
|
||||
xcimage->yhot = y;
|
||||
|
||||
dest = xcimage->pixels;
|
||||
|
||||
for (j = 0; j < height; j++)
|
||||
if (n_channels == 3)
|
||||
{
|
||||
src = pixels + j * rowstride;
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
if (n_channels == 3)
|
||||
a = 0xff;
|
||||
else
|
||||
a = src[3];
|
||||
|
||||
*dest = (a << 24) | (src[0] << 16) | (src[1] << 8) | src[2];
|
||||
gint i, j;
|
||||
|
||||
for (j = 0; j < height; j++)
|
||||
{
|
||||
src = pixels + j * rowstride;
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
*dest = (0xff << 24) | (src[0] << 16) | (src[1] << 8) | src[2];
|
||||
}
|
||||
|
||||
src += n_channels;
|
||||
dest++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_gdk_x11_convert_to_format (pixels, rowstride,
|
||||
(guchar *) dest, 4 * width,
|
||||
GDK_X11_FORMAT_ARGB,
|
||||
(G_BYTE_ORDER == G_BIG_ENDIAN) ?
|
||||
GDK_MSB_FIRST : GDK_LSB_FIRST,
|
||||
width, height);
|
||||
}
|
||||
|
||||
return xcimage;
|
||||
}
|
||||
|
||||
@@ -813,7 +813,7 @@ _gdk_windowing_set_default_display (GdkDisplay *display)
|
||||
}
|
||||
}
|
||||
|
||||
char*
|
||||
static char*
|
||||
escape_for_xmessage (const char *str)
|
||||
{
|
||||
GString *retval;
|
||||
|
||||
@@ -2193,7 +2193,10 @@ xdnd_send_xevent (GdkDragContext *context,
|
||||
temp_event.any.window = window;
|
||||
|
||||
if ((*xdnd_filters[i].func) (event_send, &temp_event, NULL) == GDK_FILTER_TRANSLATE)
|
||||
gdk_event_put (&temp_event);
|
||||
{
|
||||
gdk_event_put (&temp_event);
|
||||
g_object_unref (temp_event.dnd.context);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+31
-37
@@ -921,14 +921,8 @@ gdk_x11_drawable_get_xid (GdkDrawable *drawable)
|
||||
* what's the fastest depending on the available picture formats,
|
||||
* whether we can used shared pixmaps, etc.
|
||||
*/
|
||||
typedef enum {
|
||||
FORMAT_NONE,
|
||||
FORMAT_EXACT_MASK,
|
||||
FORMAT_ARGB_MASK,
|
||||
FORMAT_ARGB
|
||||
} FormatType;
|
||||
|
||||
static FormatType
|
||||
static GdkX11FormatType
|
||||
select_format (GdkDisplay *display,
|
||||
XRenderPictFormat **format,
|
||||
XRenderPictFormat **mask)
|
||||
@@ -937,7 +931,7 @@ select_format (GdkDisplay *display,
|
||||
XRenderPictFormat pf;
|
||||
|
||||
if (!_gdk_x11_have_render (display))
|
||||
return FORMAT_NONE;
|
||||
return GDK_X11_FORMAT_NONE;
|
||||
|
||||
/* Look for a 32-bit xRGB and Axxx formats that exactly match the
|
||||
* in memory data format. We can use them as pixmap and mask
|
||||
@@ -993,7 +987,7 @@ select_format (GdkDisplay *display,
|
||||
0);
|
||||
|
||||
if (*format && *mask)
|
||||
return FORMAT_EXACT_MASK;
|
||||
return GDK_X11_FORMAT_EXACT_MASK;
|
||||
|
||||
/* OK, that failed, now look for xRGB and Axxx formats in
|
||||
* RENDER's preferred order
|
||||
@@ -1023,7 +1017,7 @@ select_format (GdkDisplay *display,
|
||||
0);
|
||||
|
||||
if (*format && *mask)
|
||||
return FORMAT_ARGB_MASK;
|
||||
return GDK_X11_FORMAT_ARGB_MASK;
|
||||
|
||||
/* Finally, if neither of the above worked, fall back to
|
||||
* looking for combined ARGB -- we'll premultiply ourselves.
|
||||
@@ -1048,9 +1042,9 @@ select_format (GdkDisplay *display,
|
||||
*mask = NULL;
|
||||
|
||||
if (*format)
|
||||
return FORMAT_ARGB;
|
||||
return GDK_X11_FORMAT_ARGB;
|
||||
|
||||
return FORMAT_NONE;
|
||||
return GDK_X11_FORMAT_NONE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
@@ -1081,15 +1075,15 @@ list_formats (XRenderPictFormat *pf)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
convert_to_format (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
FormatType dest_format,
|
||||
GdkByteOrder dest_byteorder,
|
||||
gint width,
|
||||
gint height)
|
||||
void
|
||||
_gdk_x11_convert_to_format (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
GdkX11FormatType dest_format,
|
||||
GdkByteOrder dest_byteorder,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
gint i;
|
||||
|
||||
@@ -1097,14 +1091,14 @@ convert_to_format (guchar *src_buf,
|
||||
{
|
||||
switch (dest_format)
|
||||
{
|
||||
case FORMAT_EXACT_MASK:
|
||||
case GDK_X11_FORMAT_EXACT_MASK:
|
||||
{
|
||||
memcpy (dest_buf + i * dest_rowstride,
|
||||
src_buf + i * src_rowstride,
|
||||
width * 4);
|
||||
break;
|
||||
}
|
||||
case FORMAT_ARGB_MASK:
|
||||
case GDK_X11_FORMAT_ARGB_MASK:
|
||||
{
|
||||
guchar *row = src_buf + i * src_rowstride;
|
||||
if (((gsize)row & 3) != 0)
|
||||
@@ -1182,7 +1176,7 @@ convert_to_format (guchar *src_buf,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FORMAT_ARGB:
|
||||
case GDK_X11_FORMAT_ARGB:
|
||||
{
|
||||
guchar *p = (src_buf + i * src_rowstride);
|
||||
guchar *q = (dest_buf + i * dest_rowstride);
|
||||
@@ -1218,7 +1212,7 @@ convert_to_format (guchar *src_buf,
|
||||
#undef MULT
|
||||
break;
|
||||
}
|
||||
case FORMAT_NONE:
|
||||
case GDK_X11_FORMAT_NONE:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
@@ -1228,7 +1222,7 @@ convert_to_format (guchar *src_buf,
|
||||
static void
|
||||
draw_with_images (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
FormatType format_type,
|
||||
GdkX11FormatType format_type,
|
||||
XRenderPictFormat *format,
|
||||
XRenderPictFormat *mask_format,
|
||||
guchar *src_rgb,
|
||||
@@ -1273,10 +1267,10 @@ draw_with_images (GdkDrawable *drawable,
|
||||
|
||||
image = _gdk_image_get_scratch (screen, width1, height1, 32, &xs0, &ys0);
|
||||
|
||||
convert_to_format (src_rgb + y0 * src_rowstride + 4 * x0, src_rowstride,
|
||||
(guchar *)image->mem + ys0 * image->bpl + xs0 * image->bpp, image->bpl,
|
||||
format_type, image->byte_order,
|
||||
width1, height1);
|
||||
_gdk_x11_convert_to_format (src_rgb + y0 * src_rowstride + 4 * x0, src_rowstride,
|
||||
(guchar *)image->mem + ys0 * image->bpl + xs0 * image->bpp, image->bpl,
|
||||
format_type, image->byte_order,
|
||||
width1, height1);
|
||||
|
||||
gdk_draw_image (pix, pix_gc,
|
||||
image, xs0, ys0, x0, y0, width1, height1);
|
||||
@@ -1352,7 +1346,7 @@ get_shm_pixmap_for_image (Display *xdisplay,
|
||||
static gboolean
|
||||
draw_with_pixmaps (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
FormatType format_type,
|
||||
GdkX11FormatType format_type,
|
||||
XRenderPictFormat *format,
|
||||
XRenderPictFormat *mask_format,
|
||||
guchar *src_rgb,
|
||||
@@ -1386,10 +1380,10 @@ draw_with_pixmaps (GdkDrawable *drawable,
|
||||
if (!get_shm_pixmap_for_image (xdisplay, image, format, mask_format, &pix, &pict, &mask))
|
||||
return FALSE;
|
||||
|
||||
convert_to_format (src_rgb + y0 * src_rowstride + 4 * x0, src_rowstride,
|
||||
(guchar *)image->mem + ys0 * image->bpl + xs0 * image->bpp, image->bpl,
|
||||
format_type, image->byte_order,
|
||||
width1, height1);
|
||||
_gdk_x11_convert_to_format (src_rgb + y0 * src_rowstride + 4 * x0, src_rowstride,
|
||||
(guchar *)image->mem + ys0 * image->bpl + xs0 * image->bpp, image->bpl,
|
||||
format_type, image->byte_order,
|
||||
width1, height1);
|
||||
|
||||
XRenderComposite (xdisplay, PictOpOver, pict, mask, dest_pict,
|
||||
xs0, ys0, xs0, ys0, x0 + dest_x, y0 + dest_y,
|
||||
@@ -1415,7 +1409,7 @@ gdk_x11_draw_pixbuf (GdkDrawable *drawable,
|
||||
gint x_dither,
|
||||
gint y_dither)
|
||||
{
|
||||
FormatType format_type;
|
||||
GdkX11FormatType format_type;
|
||||
XRenderPictFormat *format, *mask_format;
|
||||
gint rowstride;
|
||||
#ifdef USE_SHM
|
||||
@@ -1425,7 +1419,7 @@ gdk_x11_draw_pixbuf (GdkDrawable *drawable,
|
||||
format_type = select_format (gdk_drawable_get_display (drawable),
|
||||
&format, &mask_format);
|
||||
|
||||
if (format_type == FORMAT_NONE ||
|
||||
if (format_type == GDK_X11_FORMAT_NONE ||
|
||||
!gdk_pixbuf_get_has_alpha (pixbuf) ||
|
||||
gdk_drawable_get_depth (drawable) == 1 ||
|
||||
(dither == GDK_RGB_DITHER_MAX && gdk_drawable_get_depth (drawable) != 24) ||
|
||||
|
||||
@@ -41,6 +41,14 @@ extern "C" {
|
||||
/* Drawable implementation for X11
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GDK_X11_FORMAT_NONE,
|
||||
GDK_X11_FORMAT_EXACT_MASK,
|
||||
GDK_X11_FORMAT_ARGB_MASK,
|
||||
GDK_X11_FORMAT_ARGB
|
||||
} GdkX11FormatType;
|
||||
|
||||
typedef struct _GdkDrawableImplX11 GdkDrawableImplX11;
|
||||
typedef struct _GdkDrawableImplX11Class GdkDrawableImplX11Class;
|
||||
|
||||
@@ -73,6 +81,15 @@ struct _GdkDrawableImplX11Class
|
||||
|
||||
GType _gdk_drawable_impl_x11_get_type (void);
|
||||
|
||||
void _gdk_x11_convert_to_format (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
GdkX11FormatType dest_format,
|
||||
GdkByteOrder dest_byteorder,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
@@ -455,12 +455,15 @@ gdk_check_wm_desktop_changed (GdkWindow *window)
|
||||
{
|
||||
gulong *desktop;
|
||||
|
||||
type = None;
|
||||
gdk_error_trap_push ();
|
||||
XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
|
||||
GDK_WINDOW_XID (window),
|
||||
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"),
|
||||
0, G_MAXLONG, False, XA_CARDINAL, &type,
|
||||
&format, &nitems,
|
||||
&bytes_after, (guchar **)&desktop);
|
||||
gdk_error_trap_pop ();
|
||||
|
||||
if (type != None)
|
||||
{
|
||||
@@ -494,10 +497,13 @@ gdk_check_wm_state_changed (GdkWindow *window)
|
||||
toplevel->have_maxhorz = FALSE;
|
||||
toplevel->have_fullscreen = FALSE;
|
||||
|
||||
type = None;
|
||||
gdk_error_trap_push ();
|
||||
XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
|
||||
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
|
||||
0, G_MAXLONG, False, XA_ATOM, &type, &format, &nitems,
|
||||
&bytes_after, (guchar **)&atoms);
|
||||
gdk_error_trap_pop ();
|
||||
|
||||
if (type != None)
|
||||
{
|
||||
@@ -783,14 +789,14 @@ get_real_window (GdkDisplay *display,
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static const char notify_modes[][18] = {
|
||||
static const char notify_modes[][19] = {
|
||||
"NotifyNormal",
|
||||
"NotifyGrab",
|
||||
"NotifyUngrab",
|
||||
"NotifyWhileGrabbed"
|
||||
};
|
||||
|
||||
static const char notify_details[][22] = {
|
||||
static const char notify_details[][23] = {
|
||||
"NotifyAncestor",
|
||||
"NotifyVirtual",
|
||||
"NotifyInferior",
|
||||
|
||||
@@ -866,7 +866,7 @@ gdk_window_postmove (GdkWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
Bool
|
||||
static Bool
|
||||
expose_serial_predicate (Display *xdisplay,
|
||||
XEvent *xev,
|
||||
XPointer arg)
|
||||
|
||||
+22
-8
@@ -206,12 +206,26 @@ gdk_keymap_get_for_display (GdkDisplay *display)
|
||||
}
|
||||
|
||||
/* Find the index of the group/level pair within the keysyms for a key.
|
||||
* We round up the number of keysyms per keycode to the next even number,
|
||||
* otherwise we lose a whole group of keys
|
||||
*/
|
||||
#define KEYSYM_INDEX(keymap_impl, group, level) \
|
||||
(2 * ((group) % (keymap_impl->keysyms_per_keycode / 2)) + (level))
|
||||
(2 * ((group) % (int)((keymap_impl->keysyms_per_keycode + 1) / 2)) + (level))
|
||||
#define KEYSYM_IS_KEYPAD(s) (((s) >= 0xff80 && (s) <= 0xffbd) || \
|
||||
((s) >= 0x11000000 && (s) <= 0x1100ffff))
|
||||
|
||||
static int
|
||||
get_symbol (const KeySym *syms, GdkKeymapX11 *keymap_x11, int group, int level)
|
||||
{
|
||||
int index;
|
||||
|
||||
index = KEYSYM_INDEX(keymap_x11, group, level);
|
||||
if (index > keymap_x11->keysyms_per_keycode)
|
||||
return NoSymbol;
|
||||
|
||||
return syms[index];
|
||||
}
|
||||
|
||||
static void
|
||||
update_keymaps (GdkKeymapX11 *keymap_x11)
|
||||
{
|
||||
@@ -256,7 +270,7 @@ update_keymaps (GdkKeymapX11 *keymap_x11)
|
||||
/* Check both groups */
|
||||
for (i = 0 ; i < 2 ; i++)
|
||||
{
|
||||
if (syms[KEYSYM_INDEX (keymap_x11, i, 0)] == GDK_Tab)
|
||||
if (get_symbol (syms, keymap_x11, i, 0) == GDK_Tab)
|
||||
syms[KEYSYM_INDEX (keymap_x11, i, 1)] = GDK_ISO_Left_Tab;
|
||||
}
|
||||
|
||||
@@ -264,12 +278,12 @@ update_keymaps (GdkKeymapX11 *keymap_x11)
|
||||
* If there is one keysym and the key symbol has upper and lower
|
||||
* case variants fudge the keymap
|
||||
*/
|
||||
if (syms[KEYSYM_INDEX (keymap_x11, 0, 1)] == 0)
|
||||
if (get_symbol (syms, keymap_x11, 0, 1) == 0)
|
||||
{
|
||||
guint lower;
|
||||
guint upper;
|
||||
|
||||
gdk_keyval_convert_case (syms[KEYSYM_INDEX (keymap_x11, 0, 0)], &lower, &upper);
|
||||
gdk_keyval_convert_case (get_symbol (syms, keymap_x11, 0, 0), &lower, &upper);
|
||||
if (lower != upper)
|
||||
{
|
||||
syms[KEYSYM_INDEX (keymap_x11, 0, 0)] = lower;
|
||||
@@ -380,9 +394,9 @@ get_keymap (GdkKeymapX11 *keymap_x11)
|
||||
|
||||
#define GET_EFFECTIVE_KEYMAP(keymap) get_effective_keymap ((keymap), G_STRFUNC)
|
||||
|
||||
GdkKeymap *
|
||||
static GdkKeymap *
|
||||
get_effective_keymap (GdkKeymap *keymap,
|
||||
const char *function)
|
||||
const char *function)
|
||||
{
|
||||
if (!keymap)
|
||||
{
|
||||
@@ -845,7 +859,7 @@ gdk_keymap_lookup_key (GdkKeymap *keymap,
|
||||
{
|
||||
const KeySym *map = get_keymap (keymap_x11);
|
||||
const KeySym *syms = map + (key->keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode;
|
||||
return syms [KEYSYM_INDEX (keymap_x11, key->group, key->level)];
|
||||
return get_symbol (syms, keymap_x11, key->group, key->level);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -995,7 +1009,7 @@ translate_keysym (GdkKeymapX11 *keymap_x11,
|
||||
const KeySym *map = get_keymap (keymap_x11);
|
||||
const KeySym *syms = map + (hardware_keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode;
|
||||
|
||||
#define SYM(k,g,l) syms[KEYSYM_INDEX (k,g,l)]
|
||||
#define SYM(k,g,l) get_symbol (syms, k,g,l)
|
||||
|
||||
GdkModifierType shift_modifiers;
|
||||
gint shift_level;
|
||||
|
||||
+36
-11
@@ -1099,6 +1099,20 @@ set_initial_hints (GdkWindow *window)
|
||||
++i;
|
||||
}
|
||||
|
||||
if (private->state & GDK_WINDOW_STATE_ABOVE)
|
||||
{
|
||||
atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
|
||||
"_NET_WM_STATE_ABOVE");
|
||||
++i;
|
||||
}
|
||||
|
||||
if (private->state & GDK_WINDOW_STATE_BELOW)
|
||||
{
|
||||
atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
|
||||
"_NET_WM_STATE_BELOW");
|
||||
++i;
|
||||
}
|
||||
|
||||
if (private->state & GDK_WINDOW_STATE_STICKY)
|
||||
{
|
||||
atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
|
||||
@@ -3335,6 +3349,7 @@ _gdk_x11_window_set_user_time (GdkWindow *window,
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkDisplayX11 *display_x11;
|
||||
glong timestamp_long = (glong)timestamp;
|
||||
|
||||
g_return_if_fail (window != NULL);
|
||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||
@@ -3348,10 +3363,10 @@ _gdk_x11_window_set_user_time (GdkWindow *window,
|
||||
XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
|
||||
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_USER_TIME"),
|
||||
XA_CARDINAL, 32, PropModeReplace,
|
||||
(guchar *)×tamp, 1);
|
||||
(guchar *)×tamp_long, 1);
|
||||
|
||||
if (timestamp != GDK_CURRENT_TIME)
|
||||
display_x11->user_time = timestamp;
|
||||
if (timestamp_long != GDK_CURRENT_TIME)
|
||||
display_x11->user_time = timestamp_long;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3953,10 +3968,15 @@ gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
|
||||
return;
|
||||
|
||||
if (GDK_WINDOW_IS_MAPPED (window))
|
||||
gdk_wmspec_change_state (setting, window,
|
||||
gdk_atom_intern ("_NET_WM_STATE_ABOVE", setting),
|
||||
setting ? gdk_atom_intern ("_NET_WM_STATE_BELOW", FALSE)
|
||||
: GDK_NONE);
|
||||
{
|
||||
if (setting)
|
||||
gdk_wmspec_change_state (FALSE, window,
|
||||
gdk_atom_intern ("_NET_WM_STATE_BELOW", FALSE),
|
||||
GDK_NONE);
|
||||
gdk_wmspec_change_state (setting, window,
|
||||
gdk_atom_intern ("_NET_WM_STATE_ABOVE", FALSE),
|
||||
GDK_NONE);
|
||||
}
|
||||
else
|
||||
gdk_synthesize_window_state (window,
|
||||
setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
|
||||
@@ -3989,10 +4009,15 @@ gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
|
||||
return;
|
||||
|
||||
if (GDK_WINDOW_IS_MAPPED (window))
|
||||
gdk_wmspec_change_state (setting, window,
|
||||
gdk_atom_intern ("_NET_WM_STATE_BELOW", setting),
|
||||
setting ? gdk_atom_intern ("_NET_WM_STATE_ABOVE", FALSE)
|
||||
: GDK_NONE);
|
||||
{
|
||||
if (setting)
|
||||
gdk_wmspec_change_state (FALSE, window,
|
||||
gdk_atom_intern ("_NET_WM_STATE_ABOVE", FALSE),
|
||||
GDK_NONE);
|
||||
gdk_wmspec_change_state (setting, window,
|
||||
gdk_atom_intern ("_NET_WM_STATE_BELOW", FALSE),
|
||||
GDK_NONE);
|
||||
}
|
||||
else
|
||||
gdk_synthesize_window_state (window,
|
||||
setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
|
||||
|
||||
+80
-79
@@ -79,7 +79,8 @@ get_unescaped_char (const char **str,
|
||||
static gboolean
|
||||
gtk_fnmatch_intern (const char *pattern,
|
||||
const char *string,
|
||||
gboolean component_start)
|
||||
gboolean component_start,
|
||||
gboolean no_leading_period)
|
||||
{
|
||||
const char *p = pattern, *n = string;
|
||||
|
||||
@@ -97,7 +98,7 @@ gtk_fnmatch_intern (const char *pattern,
|
||||
return FALSE;
|
||||
else if (nc == G_DIR_SEPARATOR)
|
||||
return FALSE;
|
||||
else if (nc == '.' && component_start)
|
||||
else if (nc == '.' && component_start && no_leading_period)
|
||||
return FALSE;
|
||||
break;
|
||||
case '\\':
|
||||
@@ -107,7 +108,7 @@ gtk_fnmatch_intern (const char *pattern,
|
||||
return FALSE;
|
||||
break;
|
||||
case '*':
|
||||
if (nc == '.' && component_start)
|
||||
if (nc == '.' && component_start && no_leading_period)
|
||||
return FALSE;
|
||||
|
||||
{
|
||||
@@ -148,7 +149,7 @@ gtk_fnmatch_intern (const char *pattern,
|
||||
for (p = last_p; nc != '\0';)
|
||||
{
|
||||
if ((c == '[' || nc == c) &&
|
||||
gtk_fnmatch_intern (p, last_n, component_start))
|
||||
gtk_fnmatch_intern (p, last_n, component_start, no_leading_period))
|
||||
return TRUE;
|
||||
|
||||
component_start = (nc == G_DIR_SEPARATOR);
|
||||
@@ -168,7 +169,7 @@ gtk_fnmatch_intern (const char *pattern,
|
||||
if (nc == '\0' || nc == G_DIR_SEPARATOR)
|
||||
return FALSE;
|
||||
|
||||
if (nc == '.' && component_start)
|
||||
if (nc == '.' && component_start && no_leading_period)
|
||||
return FALSE;
|
||||
|
||||
not = (*p == '!' || *p == '^');
|
||||
@@ -245,116 +246,116 @@ gtk_fnmatch_intern (const char *pattern,
|
||||
*
|
||||
* FNM_FILE_NAME - always set
|
||||
* FNM_LEADING_DIR - never set
|
||||
* FNM_PERIOD - always set
|
||||
* FNM_NOESCAPE - set only on windows
|
||||
* FNM_CASEFOLD - set only on windows
|
||||
*/
|
||||
gboolean
|
||||
_gtk_fnmatch (const char *pattern,
|
||||
const char *string)
|
||||
const char *string,
|
||||
gboolean no_leading_period)
|
||||
{
|
||||
return gtk_fnmatch_intern (pattern, string, TRUE);
|
||||
return gtk_fnmatch_intern (pattern, string, TRUE, no_leading_period);
|
||||
}
|
||||
|
||||
#undef FNMATCH_TEST_CASES
|
||||
#ifdef FNMATCH_TEST_CASES
|
||||
|
||||
#define TEST(pat, str, result) \
|
||||
g_assert (_gtk_fnmatch ((pat), (str)) == result)
|
||||
#define TEST(pat, str, no_leading_period, result) \
|
||||
g_assert (_gtk_fnmatch ((pat), (str), (no_leading_period)) == result)
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
TEST ("[a-]", "-", TRUE);
|
||||
TEST ("[a-]", "-", TRUE, TRUE);
|
||||
|
||||
TEST ("a", "a", TRUE);
|
||||
TEST ("a", "b", FALSE);
|
||||
TEST ("a", "a", TRUE, TRUE);
|
||||
TEST ("a", "b", TRUE, FALSE);
|
||||
|
||||
/* Test what ? matches */
|
||||
TEST ("?", "a", TRUE);
|
||||
TEST ("?", ".", FALSE);
|
||||
TEST ("a?", "a.", TRUE);
|
||||
TEST ("a/?", "a/b", TRUE);
|
||||
TEST ("a/?", "a/.", FALSE);
|
||||
TEST ("?", "/", FALSE);
|
||||
TEST ("?", "a", TRUE, TRUE);
|
||||
TEST ("?", ".", TRUE, FALSE);
|
||||
TEST ("a?", "a.", TRUE, TRUE);
|
||||
TEST ("a/?", "a/b", TRUE, TRUE);
|
||||
TEST ("a/?", "a/.", TRUE, FALSE);
|
||||
TEST ("?", "/", TRUE, FALSE);
|
||||
|
||||
/* Test what * matches */
|
||||
TEST ("*", "a", TRUE);
|
||||
TEST ("*", ".", FALSE);
|
||||
TEST ("a*", "a.", TRUE);
|
||||
TEST ("a/*", "a/b", TRUE);
|
||||
TEST ("a/*", "a/.", FALSE);
|
||||
TEST ("*", "/", FALSE);
|
||||
TEST ("*", "a", TRUE, TRUE);
|
||||
TEST ("*", ".", TRUE, FALSE);
|
||||
TEST ("a*", "a.", TRUE, TRUE);
|
||||
TEST ("a/*", "a/b", TRUE, TRUE);
|
||||
TEST ("a/*", "a/.", TRUE, FALSE);
|
||||
TEST ("*", "/", TRUE, FALSE);
|
||||
|
||||
/* Range tests */
|
||||
TEST ("[ab]", "a", TRUE);
|
||||
TEST ("[ab]", "c", FALSE);
|
||||
TEST ("[^ab]", "a", FALSE);
|
||||
TEST ("[!ab]", "a", FALSE);
|
||||
TEST ("[^ab]", "c", TRUE);
|
||||
TEST ("[!ab]", "c", TRUE);
|
||||
TEST ("[a-c]", "b", TRUE);
|
||||
TEST ("[a-c]", "d", FALSE);
|
||||
TEST ("[a-]", "-", TRUE);
|
||||
TEST ("[]]", "]", TRUE);
|
||||
TEST ("[^]]", "a", TRUE);
|
||||
TEST ("[!]]", "a", TRUE);
|
||||
TEST ("[ab]", "a", TRUE, TRUE);
|
||||
TEST ("[ab]", "c", TRUE, FALSE);
|
||||
TEST ("[^ab]", "a", TRUE, FALSE);
|
||||
TEST ("[!ab]", "a", TRUE, FALSE);
|
||||
TEST ("[^ab]", "c", TRUE, TRUE);
|
||||
TEST ("[!ab]", "c", TRUE, TRUE);
|
||||
TEST ("[a-c]", "b", TRUE, TRUE);
|
||||
TEST ("[a-c]", "d", TRUE, FALSE);
|
||||
TEST ("[a-]", "-", TRUE, TRUE);
|
||||
TEST ("[]]", "]", TRUE, TRUE);
|
||||
TEST ("[^]]", "a", TRUE, TRUE);
|
||||
TEST ("[!]]", "a", TRUE, TRUE);
|
||||
|
||||
/* Various unclosed ranges */
|
||||
TEST ("[ab", "a", FALSE);
|
||||
TEST ("[a-", "a", FALSE);
|
||||
TEST ("[ab", "c", FALSE);
|
||||
TEST ("[a-", "c", FALSE);
|
||||
TEST ("[^]", "a", FALSE);
|
||||
TEST ("[ab", "a", TRUE, FALSE);
|
||||
TEST ("[a-", "a", TRUE, FALSE);
|
||||
TEST ("[ab", "c", TRUE, FALSE);
|
||||
TEST ("[a-", "c", TRUE, FALSE);
|
||||
TEST ("[^]", "a", TRUE, FALSE);
|
||||
|
||||
/* Ranges and special no-wildcard matches */
|
||||
TEST ("[.]", ".", FALSE);
|
||||
TEST ("a[.]", "a.", TRUE);
|
||||
TEST ("a/[.]", "a/.", FALSE);
|
||||
TEST ("[/]", "/", FALSE);
|
||||
TEST ("[^/]", "a", TRUE);
|
||||
TEST ("[.]", ".", TRUE, FALSE);
|
||||
TEST ("a[.]", "a.", TRUE, TRUE);
|
||||
TEST ("a/[.]", "a/.", TRUE, FALSE);
|
||||
TEST ("[/]", "/", TRUE, FALSE);
|
||||
TEST ("[^/]", "a", TRUE, TRUE);
|
||||
|
||||
/* Basic tests of * (and combinations of * and ?) */
|
||||
TEST ("a*b", "ab", TRUE);
|
||||
TEST ("a*b", "axb", TRUE);
|
||||
TEST ("a*b", "axxb", TRUE);
|
||||
TEST ("a**b", "ab", TRUE);
|
||||
TEST ("a**b", "axb", TRUE);
|
||||
TEST ("a**b", "axxb", TRUE);
|
||||
TEST ("a*?*b", "ab", FALSE);
|
||||
TEST ("a*?*b", "axb", TRUE);
|
||||
TEST ("a*?*b", "axxb", TRUE);
|
||||
TEST ("a*b", "ab", TRUE, TRUE);
|
||||
TEST ("a*b", "axb", TRUE, TRUE);
|
||||
TEST ("a*b", "axxb", TRUE, TRUE);
|
||||
TEST ("a**b", "ab", TRUE, TRUE);
|
||||
TEST ("a**b", "axb", TRUE, TRUE);
|
||||
TEST ("a**b", "axxb", TRUE, TRUE);
|
||||
TEST ("a*?*b", "ab", TRUE, FALSE);
|
||||
TEST ("a*?*b", "axb", TRUE, TRUE);
|
||||
TEST ("a*?*b", "axxb", TRUE, TRUE);
|
||||
|
||||
/* Test of *[range] */
|
||||
TEST ("a*[cd]", "ac", TRUE);
|
||||
TEST ("a*[cd]", "axc", TRUE);
|
||||
TEST ("a*[cd]", "axx", FALSE);
|
||||
TEST ("a*[cd]", "ac", TRUE, TRUE);
|
||||
TEST ("a*[cd]", "axc", TRUE, TRUE);
|
||||
TEST ("a*[cd]", "axx", TRUE, FALSE);
|
||||
|
||||
TEST ("a/[.]", "a/.", FALSE);
|
||||
TEST ("a*[.]", "a/.", FALSE);
|
||||
TEST ("a/[.]", "a/.", TRUE, FALSE);
|
||||
TEST ("a*[.]", "a/.", TRUE, FALSE);
|
||||
|
||||
/* Test of UTF-8 */
|
||||
|
||||
TEST ("ä", "ä", TRUE); /* TEST ("ä", "ä", TRUE); */
|
||||
TEST ("?", "ä", TRUE); /* TEST ("?", "ä", TRUE); */
|
||||
TEST ("*ö", "äö", TRUE); /* TEST ("*ö", "äö", TRUE); */
|
||||
TEST ("*ö", "ääö", TRUE); /* TEST ("*ö", "ääö", TRUE); */
|
||||
TEST ("[ä]", "ä", TRUE); /* TEST ("[ä]", "ä", TRUE); */
|
||||
TEST ("[ä-ö]", "é", TRUE); /* TEST ("[ä-ö]", "é", TRUE); */
|
||||
TEST ("[ä-ö]", "a", FALSE); /* TEST ("[ä-ö]", "a", FALSE); */
|
||||
TEST ("ä", "ä", TRUE, TRUE); /* TEST ("ä", "ä", TRUE); */
|
||||
TEST ("?", "ä", TRUE, TRUE); /* TEST ("?", "ä", TRUE); */
|
||||
TEST ("*ö", "äö", TRUE, TRUE); /* TEST ("*ö", "äö", TRUE); */
|
||||
TEST ("*ö", "ääö", TRUE, TRUE); /* TEST ("*ö", "ääö", TRUE); */
|
||||
TEST ("[ä]", "ä", TRUE, TRUE); /* TEST ("[ä]", "ä", TRUE); */
|
||||
TEST ("[ä-ö]", "é", TRUE, TRUE); /* TEST ("[ä-ö]", "é", TRUE); */
|
||||
TEST ("[ä-ö]", "a", TRUE, FALSE); /* TEST ("[ä-ö]", "a", FALSE); */
|
||||
|
||||
#ifdef DO_ESCAPE
|
||||
/* Tests of escaping */
|
||||
TEST ("\\\\", "\\", TRUE);
|
||||
TEST ("\\?", "?", TRUE);
|
||||
TEST ("\\?", "a", FALSE);
|
||||
TEST ("\\*", "*", TRUE);
|
||||
TEST ("\\*", "a", FALSE);
|
||||
TEST ("\\[a-b]", "[a-b]", TRUE);
|
||||
TEST ("[\\\\]", "\\", TRUE);
|
||||
TEST ("[\\^a]", "a", TRUE);
|
||||
TEST ("[a\\-c]", "b", FALSE);
|
||||
TEST ("[a\\-c]", "-", TRUE);
|
||||
TEST ("[a\\]", "a", FALSE);
|
||||
TEST ("\\\\", "\\", TRUE, TRUE);
|
||||
TEST ("\\?", "?", TRUE, TRUE);
|
||||
TEST ("\\?", "a", TRUE, FALSE);
|
||||
TEST ("\\*", "*", TRUE, TRUE);
|
||||
TEST ("\\*", "a", TRUE, FALSE);
|
||||
TEST ("\\[a-b]", "[a-b]", TRUE, TRUE);
|
||||
TEST ("[\\\\]", "\\", TRUE, TRUE);
|
||||
TEST ("[\\^a]", "a", TRUE, TRUE);
|
||||
TEST ("[a\\-c]", "b", TRUE, FALSE);
|
||||
TEST ("[a\\-c]", "-", TRUE, TRUE);
|
||||
TEST ("[a\\]", "a", TRUE, FALSE);
|
||||
#endif /* DO_ESCAPE */
|
||||
|
||||
return 0;
|
||||
|
||||
+1
-1
@@ -121,7 +121,7 @@ _gtk_accel_path_is_valid (const gchar *accel_path)
|
||||
accel_path[1] == '<' || accel_path[1] == '>' || !accel_path[1])
|
||||
return FALSE;
|
||||
p = strchr (accel_path, '>');
|
||||
if (!p || p[1] != '/')
|
||||
if (!p || p[1] != 0 && p[1] != '/')
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+9
-7
@@ -339,6 +339,8 @@ gtk_action_init (GtkAction *action)
|
||||
* Creates a new #GtkAction object. To add the action to a
|
||||
* #GtkActionGroup and set the accelerator for the action,
|
||||
* call gtk_action_group_add_action_with_accel().
|
||||
* See <xref linkend="XML-UI"/> for information on allowed action
|
||||
* names.
|
||||
*
|
||||
* Return value: a new #GtkAction
|
||||
*
|
||||
@@ -822,7 +824,7 @@ connect_proxy (GtkAction *action,
|
||||
}
|
||||
gtk_image_set_from_stock (GTK_IMAGE (image),
|
||||
action->private_data->stock_id, GTK_ICON_SIZE_MENU);
|
||||
g_signal_connect_object (action, "notify::stock_id",
|
||||
g_signal_connect_object (action, "notify::stock-id",
|
||||
G_CALLBACK (gtk_action_sync_stock_id),
|
||||
proxy, 0);
|
||||
}
|
||||
@@ -845,13 +847,13 @@ connect_proxy (GtkAction *action,
|
||||
/* FIXME: we should set the tooltip here, but the current api
|
||||
* doesn't allow it before the item is added to a toolbar.
|
||||
*/
|
||||
g_signal_connect_object (action, "notify::visible_horizontal",
|
||||
g_signal_connect_object (action, "notify::visible-horizontal",
|
||||
G_CALLBACK (gtk_action_sync_property),
|
||||
proxy, 0);
|
||||
g_signal_connect_object (action, "notify::visible_vertical",
|
||||
g_signal_connect_object (action, "notify::visible-vertical",
|
||||
G_CALLBACK (gtk_action_sync_property),
|
||||
proxy, 0);
|
||||
g_signal_connect_object (action, "notify::is_important",
|
||||
g_signal_connect_object (action, "notify::is-important",
|
||||
G_CALLBACK (gtk_action_sync_property),
|
||||
proxy, 0);
|
||||
g_signal_connect_object (action, "notify::tooltip",
|
||||
@@ -873,10 +875,10 @@ connect_proxy (GtkAction *action,
|
||||
/* FIXME: we should set the tooltip here, but the current api
|
||||
* doesn't allow it before the item is added to a toolbar.
|
||||
*/
|
||||
g_signal_connect_object (action, "notify::short_label",
|
||||
g_signal_connect_object (action, "notify::short-label",
|
||||
G_CALLBACK (gtk_action_sync_short_label),
|
||||
proxy, 0);
|
||||
g_signal_connect_object (action, "notify::stock_id",
|
||||
g_signal_connect_object (action, "notify::stock-id",
|
||||
G_CALLBACK (gtk_action_sync_property),
|
||||
proxy, 0);
|
||||
g_signal_connect_object (proxy, "clicked",
|
||||
@@ -893,7 +895,7 @@ connect_proxy (GtkAction *action,
|
||||
"label", action->private_data->short_label,
|
||||
"use_underline", TRUE,
|
||||
NULL);
|
||||
g_signal_connect_object (action, "notify::short_label",
|
||||
g_signal_connect_object (action, "notify::short-label",
|
||||
G_CALLBACK (gtk_action_sync_short_label),
|
||||
proxy, 0);
|
||||
|
||||
|
||||
+14
-9
@@ -202,7 +202,7 @@ gtk_action_group_class_init (GtkActionGroupClass *klass)
|
||||
GTK_TYPE_ACTION, GTK_TYPE_WIDGET);
|
||||
|
||||
/**
|
||||
* GtkActionGroup::pre_activate:
|
||||
* GtkActionGroup::pre-activate:
|
||||
* @action_group: the group
|
||||
* @action: the action
|
||||
*
|
||||
@@ -223,7 +223,7 @@ gtk_action_group_class_init (GtkActionGroupClass *klass)
|
||||
GTK_TYPE_ACTION);
|
||||
|
||||
/**
|
||||
* GtkActionGroup::post_activate:
|
||||
* GtkActionGroup::post-activate:
|
||||
* @action_group: the group
|
||||
* @action: the action
|
||||
*
|
||||
@@ -553,13 +553,13 @@ gtk_action_group_add_action (GtkActionGroup *action_group,
|
||||
* @action_group: the action group
|
||||
* @action: the action to add
|
||||
* @accelerator: the accelerator for the action, in
|
||||
* the format understood by gtk_accelerator_parse(), or %NULL to use the
|
||||
* stock accelerator
|
||||
* the format understood by gtk_accelerator_parse(), or "" for no accelerator, or
|
||||
* %NULL to use the stock accelerator
|
||||
*
|
||||
* Adds an action object to the action group and sets up the accelerator.
|
||||
*
|
||||
* If @accelerator is %NULL, attempts to use the accelerator associated
|
||||
* with the stock_id of the action.
|
||||
* with the stock_id of the action.
|
||||
*
|
||||
* Accel paths are set to
|
||||
* <literal><Actions>/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.
|
||||
@@ -585,10 +585,15 @@ gtk_action_group_add_action_with_accel (GtkActionGroup *action_group,
|
||||
|
||||
if (accelerator)
|
||||
{
|
||||
gtk_accelerator_parse (accelerator, &accel_key, &accel_mods);
|
||||
if (accel_key == 0)
|
||||
g_warning ("Unable to parse accelerator '%s' for action '%s'",
|
||||
accelerator, name);
|
||||
if (accelerator[0] == 0)
|
||||
accel_key = 0;
|
||||
else
|
||||
{
|
||||
gtk_accelerator_parse (accelerator, &accel_key, &accel_mods);
|
||||
if (accel_key == 0)
|
||||
g_warning ("Unable to parse accelerator '%s' for action '%s'",
|
||||
accelerator, name);
|
||||
}
|
||||
}
|
||||
else if (stock_id && gtk_stock_lookup (stock_id, &stock_item))
|
||||
{
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@
|
||||
#include "gtkarrow.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
#define MIN_ARROW_SIZE 11
|
||||
#define MIN_ARROW_SIZE 15
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
|
||||
+16
-2
@@ -884,11 +884,10 @@ gtk_button_size_request (GtkWidget *widget,
|
||||
{
|
||||
GtkButton *button = GTK_BUTTON (widget);
|
||||
GtkBorder default_border;
|
||||
gboolean interior_focus;
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
|
||||
gtk_button_get_props (button, &default_border, NULL, &interior_focus);
|
||||
gtk_button_get_props (button, &default_border, NULL, NULL);
|
||||
gtk_widget_style_get (GTK_WIDGET (widget),
|
||||
"focus-line-width", &focus_width,
|
||||
"focus-padding", &focus_pad,
|
||||
@@ -930,8 +929,15 @@ gtk_button_size_allocate (GtkWidget *widget,
|
||||
gint xthickness = GTK_WIDGET (widget)->style->xthickness;
|
||||
gint ythickness = GTK_WIDGET (widget)->style->ythickness;
|
||||
GtkBorder default_border;
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
|
||||
gtk_button_get_props (button, &default_border, NULL, NULL);
|
||||
gtk_widget_style_get (GTK_WIDGET (widget),
|
||||
"focus-line-width", &focus_width,
|
||||
"focus-padding", &focus_pad,
|
||||
NULL);
|
||||
|
||||
|
||||
widget->allocation = *allocation;
|
||||
|
||||
@@ -960,6 +966,14 @@ gtk_button_size_allocate (GtkWidget *widget,
|
||||
child_allocation.height = MAX (1, child_allocation.height - default_border.top - default_border.bottom);
|
||||
}
|
||||
|
||||
if (GTK_WIDGET_CAN_FOCUS (button))
|
||||
{
|
||||
child_allocation.x += focus_width + focus_pad;
|
||||
child_allocation.y += focus_width + focus_pad;
|
||||
child_allocation.width = MAX (1, child_allocation.width - (focus_width + focus_pad) * 2);
|
||||
child_allocation.height = MAX (1, child_allocation.height - (focus_width + focus_pad) * 2);
|
||||
}
|
||||
|
||||
if (button->depressed)
|
||||
{
|
||||
gint child_displacement_x;
|
||||
|
||||
+12
-9
@@ -599,13 +599,13 @@ gtk_calendar_class_init (GtkCalendarClass *class)
|
||||
|
||||
enum
|
||||
{
|
||||
TARGET_TEXT,
|
||||
TARGET_TEXT
|
||||
};
|
||||
|
||||
static const GtkTargetEntry target_table[] = {
|
||||
{ "TEXT", 0, TARGET_TEXT },
|
||||
{ "STRING", 0, TARGET_TEXT },
|
||||
{ "UTF8_STRING", 0, TARGET_TEXT },
|
||||
{ "UTF8_STRING", 0, TARGET_TEXT }
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -1021,11 +1021,11 @@ gtk_calendar_main_button (GtkWidget *widget,
|
||||
if (!GTK_WIDGET_HAS_FOCUS (widget))
|
||||
gtk_widget_grab_focus (widget);
|
||||
|
||||
gtk_calendar_select_and_focus_day (calendar, day);
|
||||
|
||||
private_data->in_drag = 1;
|
||||
private_data->drag_start_x = x;
|
||||
private_data->drag_start_y = y;
|
||||
|
||||
gtk_calendar_select_and_focus_day (calendar, day);
|
||||
}
|
||||
else if (event->type == GDK_2BUTTON_PRESS)
|
||||
{
|
||||
@@ -2747,10 +2747,10 @@ gtk_calendar_button_press (GtkWidget *widget,
|
||||
/* only call the action on single click, not double */
|
||||
if (event->type == GDK_BUTTON_PRESS)
|
||||
{
|
||||
arrow_action (calendar, arrow);
|
||||
|
||||
if (event->button == 1)
|
||||
start_spinning (widget, arrow);
|
||||
|
||||
arrow_action (calendar, arrow);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -3066,7 +3066,10 @@ gtk_calendar_state_changed (GtkWidget *widget,
|
||||
private_data = GTK_CALENDAR_PRIVATE_DATA (widget);
|
||||
|
||||
if (!GTK_WIDGET_IS_SENSITIVE (widget))
|
||||
stop_spinning (widget);
|
||||
{
|
||||
private_data->in_drag = 0;
|
||||
stop_spinning (widget);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
if (GTK_WIDGET_IS_SENSITIVE (widget))
|
||||
@@ -3368,7 +3371,7 @@ gtk_calendar_drag_data_get (GtkWidget *widget,
|
||||
gchar str[128];
|
||||
gsize len;
|
||||
|
||||
date = g_date_new_dmy (calendar->selected_day, calendar->month, calendar->year);
|
||||
date = g_date_new_dmy (calendar->selected_day, calendar->month + 1, calendar->year);
|
||||
len = g_date_strftime (str, 127, "%x", date);
|
||||
gtk_selection_data_set_text (selection_data, str, len);
|
||||
|
||||
@@ -3529,7 +3532,7 @@ gtk_calendar_drag_data_received (GtkWidget *widget,
|
||||
g_object_freeze_notify (G_OBJECT (calendar));
|
||||
if (!(calendar->display_flags & GTK_CALENDAR_NO_MONTH_CHANGE)
|
||||
&& (calendar->display_flags & GTK_CALENDAR_SHOW_HEADING))
|
||||
gtk_calendar_select_month (calendar, month, year);
|
||||
gtk_calendar_select_month (calendar, month - 1, year);
|
||||
gtk_calendar_select_day (calendar, day);
|
||||
g_object_thaw_notify (G_OBJECT (calendar));
|
||||
}
|
||||
|
||||
+9
-1
@@ -294,7 +294,15 @@ gtk_cell_view_style_set (GtkWidget *widget,
|
||||
static void
|
||||
gtk_cell_view_finalize (GObject *object)
|
||||
{
|
||||
gtk_cell_view_cell_layout_clear (GTK_CELL_LAYOUT (object));
|
||||
GtkCellView *cellview = GTK_CELL_VIEW (object);
|
||||
|
||||
gtk_cell_view_cell_layout_clear (GTK_CELL_LAYOUT (cellview));
|
||||
|
||||
if (cellview->priv->model)
|
||||
g_object_unref (cellview->priv->model);
|
||||
|
||||
if (cellview->priv->displayed_row)
|
||||
gtk_tree_row_reference_free (cellview->priv->displayed_row);
|
||||
|
||||
if (G_OBJECT_CLASS (parent_class)->finalize)
|
||||
(* G_OBJECT_CLASS (parent_class)->finalize) (object);
|
||||
|
||||
+186
-94
@@ -34,6 +34,7 @@
|
||||
#include "gtkmenu.h"
|
||||
#include "gtktogglebutton.h"
|
||||
#include "gtktreeselection.h"
|
||||
#include "gtktreeprivate.h"
|
||||
#include "gtkvseparator.h"
|
||||
#include "gtkwindow.h"
|
||||
|
||||
@@ -114,8 +115,9 @@ struct _GtkComboBoxPrivate
|
||||
* cell_view -> GtkCellView, regular child
|
||||
* cell_view_frame -> NULL
|
||||
* button -> GtkToggleButton set_parent to combo
|
||||
* arrow -> GtkArrow set_parent to button
|
||||
* separator -> GtkVSepator set_parent to button
|
||||
* box -> child of button
|
||||
* arrow -> child of box
|
||||
* separator -> child of box
|
||||
* popup_widget -> GtkMenu
|
||||
* popup_window -> NULL
|
||||
* popup_frame -> NULL
|
||||
@@ -126,6 +128,7 @@ struct _GtkComboBoxPrivate
|
||||
* cell_view -> NULL
|
||||
* cell_view_frame -> NULL
|
||||
* button -> GtkToggleButton set_parent to combo
|
||||
* box -> NULL
|
||||
* arrow -> GtkArrow, child of button
|
||||
* separator -> NULL
|
||||
* popup_widget -> GtkMenu
|
||||
@@ -138,6 +141,7 @@ struct _GtkComboBoxPrivate
|
||||
* cell_view -> GtkCellView, regular child
|
||||
* cell_view_frame -> GtkFrame, set parent to combo
|
||||
* button -> GtkToggleButton, set_parent to combo
|
||||
* box -> NULL
|
||||
* arrow -> GtkArrow, child of button
|
||||
* separator -> NULL
|
||||
* popup_widget -> tree_view
|
||||
@@ -150,6 +154,7 @@ struct _GtkComboBoxPrivate
|
||||
* cell_view -> NULL
|
||||
* cell_view_frame -> NULL
|
||||
* button -> GtkToggleButton, set_parent to combo
|
||||
* box -> NULL
|
||||
* arrow -> GtkArrow, child of button
|
||||
* separator -> NULL
|
||||
* popup_widget -> tree_view
|
||||
@@ -337,9 +342,6 @@ static void gtk_combo_box_menu_row_changed (GtkTreeModel *model,
|
||||
static gboolean gtk_combo_box_menu_key_press (GtkWidget *widget,
|
||||
GdkEventKey *event,
|
||||
gpointer data);
|
||||
static void gtk_combo_box_menu_state_changed (GtkWidget *widget,
|
||||
GtkStateType previous,
|
||||
gpointer data);
|
||||
|
||||
/* cell layout */
|
||||
static void gtk_combo_box_cell_layout_pack_start (GtkCellLayout *layout,
|
||||
@@ -499,9 +501,9 @@ gtk_combo_box_class_init (GtkComboBoxClass *klass)
|
||||
g_param_spec_int ("active",
|
||||
P_("Active item"),
|
||||
P_("The item which is currently active"),
|
||||
0,
|
||||
-1,
|
||||
G_MAXINT,
|
||||
0,
|
||||
-1,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
gtk_widget_class_install_style_property (widget_class,
|
||||
@@ -913,31 +915,53 @@ gtk_combo_box_menu_position_below (GtkMenu *menu,
|
||||
gint *push_in,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkComboBox *combo_box = GTK_COMBO_BOX (user_data);
|
||||
gint sx, sy;
|
||||
GtkWidget *child;
|
||||
GtkRequisition req;
|
||||
GtkComboBox *combo_box = GTK_COMBO_BOX (user_data);
|
||||
GdkScreen *screen;
|
||||
gint monitor_num;
|
||||
GdkRectangle monitor;
|
||||
|
||||
/* FIXME: is using the size request here broken? */
|
||||
child = GTK_BIN (combo_box)->child;
|
||||
|
||||
gdk_window_get_origin (child->window, &sx, &sy);
|
||||
|
||||
if (GTK_WIDGET_NO_WINDOW (child))
|
||||
{
|
||||
sx += child->allocation.x;
|
||||
sy += child->allocation.y;
|
||||
}
|
||||
|
||||
gtk_widget_size_request (GTK_WIDGET (menu), &req);
|
||||
|
||||
|
||||
if (gtk_widget_get_direction (GTK_WIDGET (combo_box)) == GTK_TEXT_DIR_LTR)
|
||||
*x = sx;
|
||||
else
|
||||
*x = sx + child->allocation.width - req.width;
|
||||
*y = sy + child->allocation.height;
|
||||
|
||||
if (GTK_WIDGET_NO_WINDOW (child))
|
||||
{
|
||||
*x += child->allocation.x;
|
||||
*y += child->allocation.y;
|
||||
}
|
||||
|
||||
*push_in = TRUE;
|
||||
*y = sy;
|
||||
|
||||
screen = gtk_widget_get_screen (GTK_WIDGET (combo_box));
|
||||
monitor_num = gdk_screen_get_monitor_at_window (screen,
|
||||
GTK_WIDGET (combo_box)->window);
|
||||
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
|
||||
|
||||
if (*x < monitor.x)
|
||||
*x = monitor.x;
|
||||
else if (*x + req.width > monitor.x + monitor.width)
|
||||
*x = monitor.x + monitor.width - req.width;
|
||||
|
||||
if (monitor.y + monitor.height - *y - child->allocation.height >= req.height)
|
||||
*y += child->allocation.height;
|
||||
else if (*y - monitor.y >= req.height)
|
||||
*y -= req.height;
|
||||
else if (monitor.y + monitor.height - *y - child->allocation.height > *y - monitor.y)
|
||||
*y += child->allocation.height;
|
||||
else
|
||||
*y -= req.height;
|
||||
|
||||
*push_in = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1115,6 +1139,17 @@ gtk_combo_box_popup (GtkComboBox *combo_box)
|
||||
gtk_menu_set_active (GTK_MENU (combo_box->priv->popup_widget),
|
||||
combo_box->priv->active_item);
|
||||
|
||||
if (combo_box->priv->wrap_width == 0)
|
||||
{
|
||||
GtkRequisition requisition;
|
||||
|
||||
width = GTK_WIDGET (combo_box)->allocation.width;
|
||||
gtk_widget_size_request (combo_box->priv->popup_widget, &requisition);
|
||||
|
||||
gtk_widget_set_size_request (combo_box->priv->popup_widget,
|
||||
MAX (width, requisition.width), -1);
|
||||
}
|
||||
|
||||
gtk_menu_popup (GTK_MENU (combo_box->priv->popup_widget),
|
||||
NULL, NULL,
|
||||
gtk_combo_box_menu_position, combo_box,
|
||||
@@ -1168,6 +1203,9 @@ gtk_combo_box_popdown (GtkComboBox *combo_box)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_COMBO_BOX (combo_box));
|
||||
|
||||
if (!GTK_WIDGET_REALIZED (GTK_WIDGET (combo_box)))
|
||||
return;
|
||||
|
||||
if (GTK_IS_MENU (combo_box->priv->popup_widget))
|
||||
{
|
||||
gtk_menu_popdown (GTK_MENU (combo_box->priv->popup_widget));
|
||||
@@ -1213,7 +1251,8 @@ gtk_combo_box_remeasure (GtkComboBox *combo_box)
|
||||
GtkTreePath *path;
|
||||
gint padding = 0;
|
||||
|
||||
if (!gtk_tree_model_get_iter_first (combo_box->priv->model, &iter))
|
||||
if (!combo_box->priv->model ||
|
||||
!gtk_tree_model_get_iter_first (combo_box->priv->model, &iter))
|
||||
return;
|
||||
|
||||
combo_box->priv->width = 0;
|
||||
@@ -1264,6 +1303,8 @@ gtk_combo_box_size_request (GtkWidget *widget,
|
||||
gtk_combo_box_remeasure (combo_box);
|
||||
bin_req.width = MAX (bin_req.width, combo_box->priv->width);
|
||||
|
||||
gtk_combo_box_check_appearance (combo_box);
|
||||
|
||||
if (!combo_box->priv->tree_view)
|
||||
{
|
||||
/* menu mode */
|
||||
@@ -1342,6 +1383,8 @@ gtk_combo_box_size_allocate (GtkWidget *widget,
|
||||
|
||||
widget->allocation = *allocation;
|
||||
|
||||
gtk_combo_box_check_appearance (combo_box);
|
||||
|
||||
if (!combo_box->priv->tree_view)
|
||||
{
|
||||
if (combo_box->priv->cell_view)
|
||||
@@ -1360,12 +1403,12 @@ gtk_combo_box_size_allocate (GtkWidget *widget,
|
||||
child.x = allocation->x + border_width + 1 + xthickness + 2;
|
||||
child.y = allocation->y + border_width + 1 + ythickness + 2;
|
||||
|
||||
width = allocation->width - (border_width + 1 + xthickness * 2 + 4);
|
||||
width = MAX(1, allocation->width - (border_width + 1 + xthickness * 2 + 4));
|
||||
|
||||
/* handle the children */
|
||||
gtk_widget_size_request (combo_box->priv->arrow, &req);
|
||||
child.width = req.width;
|
||||
child.height = allocation->height - 2 * (child.y - allocation->y);
|
||||
child.height = MAX(1, allocation->height - 2 * (child.y - allocation->y));
|
||||
if (!is_rtl)
|
||||
child.x += width - req.width;
|
||||
gtk_widget_size_allocate (combo_box->priv->arrow, &child);
|
||||
@@ -1380,14 +1423,14 @@ gtk_combo_box_size_allocate (GtkWidget *widget,
|
||||
if (is_rtl)
|
||||
{
|
||||
child.x += req.width;
|
||||
child.width = allocation->x + allocation->width
|
||||
- (border_width + 1 + xthickness + 2) - child.x;
|
||||
child.width = MAX(1, allocation->x + allocation->width
|
||||
- (border_width + 1 + xthickness + 2) - child.x);
|
||||
}
|
||||
else
|
||||
{
|
||||
child.width = child.x;
|
||||
child.x = allocation->x + border_width + 1 + xthickness + 2;
|
||||
child.width -= child.x;
|
||||
child.width = MAX(1, child.width - child.x);
|
||||
}
|
||||
|
||||
gtk_widget_size_allocate (GTK_BIN (widget)->child, &child);
|
||||
@@ -1409,7 +1452,7 @@ gtk_combo_box_size_allocate (GtkWidget *widget,
|
||||
else
|
||||
child.x = allocation->x;
|
||||
child.y = allocation->y;
|
||||
child.width = allocation->width - req.width;
|
||||
child.width = MAX(1, allocation->width - req.width);
|
||||
gtk_widget_size_allocate (GTK_BIN (widget)->child, &child);
|
||||
}
|
||||
}
|
||||
@@ -1434,7 +1477,7 @@ gtk_combo_box_size_allocate (GtkWidget *widget,
|
||||
else
|
||||
child.x = allocation->x;
|
||||
child.y = allocation->y;
|
||||
child.width = allocation->width - req.width;
|
||||
child.width = MAX (1, allocation->width - req.width);
|
||||
child.height = allocation->height;
|
||||
|
||||
if (combo_box->priv->cell_view_frame)
|
||||
@@ -1451,9 +1494,11 @@ gtk_combo_box_size_allocate (GtkWidget *widget,
|
||||
child.width -= 2 * (
|
||||
GTK_CONTAINER (combo_box->priv->cell_view_frame)->border_width +
|
||||
GTK_WIDGET (combo_box->priv->cell_view_frame)->style->xthickness);
|
||||
child.width = MAX(1,child.width);
|
||||
child.height -= 2 * (
|
||||
GTK_CONTAINER (combo_box->priv->cell_view_frame)->border_width +
|
||||
GTK_WIDGET (combo_box->priv->cell_view_frame)->style->ythickness);
|
||||
child.height = MAX(1,child.height);
|
||||
}
|
||||
|
||||
gtk_widget_size_allocate (GTK_BIN (combo_box)->child, &child);
|
||||
@@ -1488,6 +1533,9 @@ gtk_combo_box_unset_model (GtkComboBox *combo_box)
|
||||
g_object_unref (G_OBJECT (combo_box->priv->model));
|
||||
combo_box->priv->model = NULL;
|
||||
}
|
||||
|
||||
if (combo_box->priv->cell_view)
|
||||
gtk_cell_view_set_displayed_row (GTK_CELL_VIEW (combo_box->priv->cell_view), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1502,12 +1550,6 @@ gtk_combo_box_forall (GtkContainer *container,
|
||||
{
|
||||
if (combo_box->priv->button)
|
||||
(* callback) (combo_box->priv->button, callback_data);
|
||||
if (combo_box->priv->box)
|
||||
(* callback) (combo_box->priv->box, callback_data);
|
||||
if (combo_box->priv->separator)
|
||||
(* callback) (combo_box->priv->separator, callback_data);
|
||||
if (combo_box->priv->arrow)
|
||||
(* callback) (combo_box->priv->arrow, callback_data);
|
||||
if (combo_box->priv->cell_view_frame)
|
||||
(* callback) (combo_box->priv->cell_view_frame, callback_data);
|
||||
}
|
||||
@@ -1653,9 +1695,6 @@ gtk_combo_box_menu_setup (GtkComboBox *combo_box,
|
||||
g_signal_connect (combo_box->priv->button, "button_press_event",
|
||||
G_CALLBACK (gtk_combo_box_menu_button_press),
|
||||
combo_box);
|
||||
g_signal_connect (combo_box->priv->button, "state_changed",
|
||||
G_CALLBACK (gtk_combo_box_menu_state_changed),
|
||||
combo_box);
|
||||
|
||||
/* create our funky menu */
|
||||
menu = gtk_menu_new ();
|
||||
@@ -1714,10 +1753,6 @@ gtk_combo_box_menu_destroy (GtkComboBox *combo_box)
|
||||
G_SIGNAL_MATCH_DATA,
|
||||
0, 0, NULL,
|
||||
gtk_combo_box_menu_button_press, NULL);
|
||||
g_signal_handlers_disconnect_matched (combo_box->priv->button,
|
||||
G_SIGNAL_MATCH_DATA,
|
||||
0, 0, NULL,
|
||||
gtk_combo_box_menu_state_changed, NULL);
|
||||
|
||||
/* unparent will remove our latest ref */
|
||||
gtk_widget_unparent (combo_box->priv->button);
|
||||
@@ -1736,13 +1771,13 @@ gtk_combo_box_menu_destroy (GtkComboBox *combo_box)
|
||||
|
||||
static void
|
||||
gtk_combo_box_item_get_size (GtkComboBox *combo_box,
|
||||
gint index,
|
||||
gint index_,
|
||||
gint *cols,
|
||||
gint *rows)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
|
||||
gtk_tree_model_iter_nth_child (combo_box->priv->model, &iter, NULL, index);
|
||||
gtk_tree_model_iter_nth_child (combo_box->priv->model, &iter, NULL, index_);
|
||||
|
||||
if (cols)
|
||||
{
|
||||
@@ -1811,8 +1846,8 @@ gtk_combo_box_relayout_item (GtkComboBox *combo_box,
|
||||
{
|
||||
gint current_col = 0, current_row = 0;
|
||||
gint rows, cols;
|
||||
GList *list;
|
||||
GtkWidget *item;
|
||||
GList *list, *nth;
|
||||
GtkWidget *item, *last;
|
||||
GtkWidget *menu;
|
||||
|
||||
menu = combo_box->priv->popup_widget;
|
||||
@@ -1820,26 +1855,49 @@ gtk_combo_box_relayout_item (GtkComboBox *combo_box,
|
||||
return;
|
||||
|
||||
list = gtk_container_get_children (GTK_CONTAINER (menu));
|
||||
item = g_list_nth_data (list, index);
|
||||
nth = g_list_nth (list, index);
|
||||
item = nth->data;
|
||||
if (nth->prev)
|
||||
last = nth->prev->data;
|
||||
else
|
||||
last = NULL;
|
||||
g_list_free (list);
|
||||
|
||||
gtk_combo_box_item_get_size (combo_box, index, &cols, &rows);
|
||||
|
||||
/* look for a good spot */
|
||||
while (1)
|
||||
|
||||
if (combo_box->priv->col_column == -1 &&
|
||||
combo_box->priv->row_column == -1 &&
|
||||
last)
|
||||
{
|
||||
gtk_container_child_get (GTK_CONTAINER (menu),
|
||||
last,
|
||||
"right_attach", ¤t_col,
|
||||
"top_attach", ¤t_row,
|
||||
NULL);
|
||||
if (current_col + cols > combo_box->priv->wrap_width)
|
||||
{
|
||||
current_col = 0;
|
||||
current_row++;
|
||||
}
|
||||
|
||||
if (!menu_occupied (GTK_MENU (menu),
|
||||
current_col, current_col + cols,
|
||||
current_row, current_row + rows))
|
||||
break;
|
||||
|
||||
current_col++;
|
||||
{
|
||||
current_col = 0;
|
||||
current_row++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* look for a good spot */
|
||||
while (1)
|
||||
{
|
||||
if (current_col + cols > combo_box->priv->wrap_width)
|
||||
{
|
||||
current_col = 0;
|
||||
current_row++;
|
||||
}
|
||||
|
||||
if (!menu_occupied (GTK_MENU (menu),
|
||||
current_col, current_col + cols,
|
||||
current_row, current_row + rows))
|
||||
break;
|
||||
|
||||
current_col++;
|
||||
}
|
||||
}
|
||||
|
||||
/* set attach props */
|
||||
@@ -1890,6 +1948,18 @@ gtk_combo_box_menu_button_press (GtkWidget *widget,
|
||||
gtk_menu_set_active (GTK_MENU (combo_box->priv->popup_widget),
|
||||
combo_box->priv->active_item);
|
||||
|
||||
if (combo_box->priv->wrap_width == 0)
|
||||
{
|
||||
GtkRequisition requisition;
|
||||
gint width;
|
||||
|
||||
width = GTK_WIDGET (combo_box)->allocation.width;
|
||||
gtk_widget_size_request (combo_box->priv->popup_widget, &requisition);
|
||||
|
||||
gtk_widget_set_size_request (combo_box->priv->popup_widget,
|
||||
MAX (width, requisition.width), -1);
|
||||
}
|
||||
|
||||
gtk_menu_popup (GTK_MENU (combo_box->priv->popup_widget),
|
||||
NULL, NULL,
|
||||
gtk_combo_box_menu_position, combo_box,
|
||||
@@ -1901,22 +1971,6 @@ gtk_combo_box_menu_button_press (GtkWidget *widget,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_combo_box_menu_state_changed (GtkWidget *widget,
|
||||
GtkStateType previous,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkComboBox *combo_box = GTK_COMBO_BOX (user_data);
|
||||
|
||||
if (combo_box->priv->cell_view)
|
||||
{
|
||||
gtk_widget_set_state (combo_box->priv->cell_view,
|
||||
GTK_WIDGET_STATE (widget));
|
||||
|
||||
gtk_widget_queue_draw (combo_box->priv->cell_view);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_combo_box_menu_item_activate (GtkWidget *item,
|
||||
gpointer user_data)
|
||||
@@ -2147,14 +2201,27 @@ gtk_combo_box_list_setup (GtkComboBox *combo_box)
|
||||
gtk_cell_view_set_background_color (GTK_CELL_VIEW (combo_box->priv->cell_view),
|
||||
>K_WIDGET (combo_box)->style->base[GTK_WIDGET_STATE (combo_box)]);
|
||||
|
||||
gtk_widget_show (combo_box->priv->cell_view_frame);
|
||||
combo_box->priv->box = gtk_event_box_new ();
|
||||
gtk_event_box_set_visible_window (GTK_EVENT_BOX (combo_box->priv->box),
|
||||
FALSE);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (combo_box->priv->cell_view_frame),
|
||||
combo_box->priv->box);
|
||||
|
||||
gtk_widget_show_all (combo_box->priv->cell_view_frame);
|
||||
|
||||
g_signal_connect (combo_box->priv->box, "button_press_event",
|
||||
G_CALLBACK (gtk_combo_box_list_button_pressed),
|
||||
combo_box);
|
||||
}
|
||||
|
||||
combo_box->priv->tree_view = gtk_tree_view_new ();
|
||||
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (combo_box->priv->tree_view));
|
||||
gtk_tree_selection_set_mode (sel, GTK_SELECTION_SINGLE);
|
||||
gtk_tree_selection_set_mode (sel, GTK_SELECTION_BROWSE);
|
||||
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (combo_box->priv->tree_view),
|
||||
FALSE);
|
||||
_gtk_tree_view_set_hover_selection (GTK_TREE_VIEW (combo_box->priv->tree_view),
|
||||
TRUE);
|
||||
if (combo_box->priv->model)
|
||||
gtk_tree_view_set_model (GTK_TREE_VIEW (combo_box->priv->tree_view),
|
||||
combo_box->priv->model);
|
||||
@@ -2226,6 +2293,12 @@ gtk_combo_box_list_destroy (GtkComboBox *combo_box)
|
||||
0, 0, NULL,
|
||||
gtk_combo_box_list_button_pressed,
|
||||
NULL);
|
||||
if (combo_box->priv->box)
|
||||
g_signal_handlers_disconnect_matched (combo_box->priv->box,
|
||||
G_SIGNAL_MATCH_DATA,
|
||||
0, 0, NULL,
|
||||
gtk_combo_box_list_button_pressed,
|
||||
NULL);
|
||||
|
||||
/* destroy things (unparent will kill the latest ref from us)
|
||||
* last unref on button will destroy the arrow
|
||||
@@ -2245,6 +2318,7 @@ gtk_combo_box_list_destroy (GtkComboBox *combo_box)
|
||||
{
|
||||
gtk_widget_unparent (combo_box->priv->cell_view_frame);
|
||||
combo_box->priv->cell_view_frame = NULL;
|
||||
combo_box->priv->box = NULL;
|
||||
}
|
||||
|
||||
gtk_widget_destroy (combo_box->priv->tree_view);
|
||||
@@ -2280,7 +2354,7 @@ gtk_combo_box_list_button_pressed (GtkWidget *widget,
|
||||
if (ewidget == combo_box->priv->tree_view)
|
||||
return TRUE;
|
||||
|
||||
if ((ewidget != combo_box->priv->button) ||
|
||||
if ((ewidget != combo_box->priv->button && ewidget != combo_box->priv->box) ||
|
||||
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (combo_box->priv->button)))
|
||||
return FALSE;
|
||||
|
||||
@@ -2359,10 +2433,13 @@ gtk_combo_box_key_press (GtkWidget *widget,
|
||||
{
|
||||
GtkComboBox *combo_box = GTK_COMBO_BOX (data);
|
||||
guint state = event->state & gtk_accelerator_get_default_mod_mask ();
|
||||
gint items = gtk_tree_model_iter_n_children (combo_box->priv->model, NULL);
|
||||
gint items = 0;
|
||||
gint index = gtk_combo_box_get_active (combo_box);
|
||||
gint new_index;
|
||||
|
||||
if (combo_box->priv->model)
|
||||
items = gtk_tree_model_iter_n_children (combo_box->priv->model, NULL);
|
||||
|
||||
if ((event->keyval == GDK_Down || event->keyval == GDK_KP_Down) &&
|
||||
state == GDK_MOD1_MASK)
|
||||
{
|
||||
@@ -2396,8 +2473,9 @@ gtk_combo_box_key_press (GtkWidget *widget,
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gtk_combo_box_set_active (combo_box, CLAMP (new_index, 0, items - 1));
|
||||
|
||||
if (items > 0)
|
||||
gtk_combo_box_set_active (combo_box, CLAMP (new_index, 0, items - 1));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -2445,12 +2523,16 @@ gtk_combo_box_list_key_press (GtkWidget *widget,
|
||||
if (event->keyval == GDK_Return || event->keyval == GDK_KP_Enter ||
|
||||
event->keyval == GDK_space || event->keyval == GDK_KP_Space)
|
||||
{
|
||||
gboolean ret;
|
||||
gboolean ret = FALSE;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model = NULL;
|
||||
GtkTreeSelection *sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (combo_box->priv->tree_view));
|
||||
|
||||
ret = gtk_tree_selection_get_selected (sel, &model, &iter);
|
||||
if (combo_box->priv->model)
|
||||
{
|
||||
GtkTreeSelection *sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (combo_box->priv->tree_view));
|
||||
|
||||
ret = gtk_tree_selection_get_selected (sel, &model, &iter);
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
GtkTreePath *path;
|
||||
@@ -3035,7 +3117,7 @@ gtk_combo_box_get_active (GtkComboBox *combo_box)
|
||||
/**
|
||||
* gtk_combo_box_set_active:
|
||||
* @combo_box: A #GtkComboBox.
|
||||
* @index: An index in the model passed during construction, or -1 to have
|
||||
* @index_: An index in the model passed during construction, or -1 to have
|
||||
* no active item.
|
||||
*
|
||||
* Sets the active item of @combo_box to be the item at @index.
|
||||
@@ -3044,16 +3126,16 @@ gtk_combo_box_get_active (GtkComboBox *combo_box)
|
||||
*/
|
||||
void
|
||||
gtk_combo_box_set_active (GtkComboBox *combo_box,
|
||||
gint index)
|
||||
gint index_)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_COMBO_BOX (combo_box));
|
||||
/* -1 means "no item selected" */
|
||||
g_return_if_fail (index >= -1);
|
||||
g_return_if_fail (index_ >= -1);
|
||||
|
||||
if (combo_box->priv->active_item == index)
|
||||
if (combo_box->priv->active_item == index_)
|
||||
return;
|
||||
|
||||
gtk_combo_box_set_active_internal (combo_box, index);
|
||||
gtk_combo_box_set_active_internal (combo_box, index_);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3169,6 +3251,7 @@ gtk_combo_box_set_active_iter (GtkComboBox *combo_box,
|
||||
*
|
||||
* Sets the model used by @combo_box to be @model. Will unset a
|
||||
* previously set model (if applicable).
|
||||
* If @model is %NULL, then it will unset the model.
|
||||
*
|
||||
* Since: 2.4
|
||||
*/
|
||||
@@ -3177,6 +3260,13 @@ gtk_combo_box_set_model (GtkComboBox *combo_box,
|
||||
GtkTreeModel *model)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_COMBO_BOX (combo_box));
|
||||
|
||||
if (!model)
|
||||
{
|
||||
gtk_combo_box_unset_model (combo_box);
|
||||
return;
|
||||
}
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_MODEL (model));
|
||||
|
||||
if (model == combo_box->priv->model)
|
||||
@@ -3267,8 +3357,8 @@ gtk_combo_box_new_text (void)
|
||||
GtkListStore *store;
|
||||
|
||||
store = gtk_list_store_new (1, G_TYPE_STRING);
|
||||
|
||||
combo_box = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
|
||||
g_object_unref (store);
|
||||
|
||||
cell = gtk_cell_renderer_text_new ();
|
||||
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), cell, TRUE);
|
||||
@@ -3411,10 +3501,11 @@ gtk_combo_box_destroy (GtkObject *object)
|
||||
{
|
||||
GtkComboBox *combo_box = GTK_COMBO_BOX (object);
|
||||
|
||||
gtk_combo_box_popdown (combo_box);
|
||||
|
||||
combo_box->priv->destroying = 1;
|
||||
|
||||
GTK_OBJECT_CLASS (parent_class)->destroy (object);
|
||||
|
||||
combo_box->priv->cell_view = NULL;
|
||||
|
||||
combo_box->priv->destroying = 0;
|
||||
@@ -3427,7 +3518,11 @@ gtk_combo_box_finalize (GObject *object)
|
||||
GSList *i;
|
||||
|
||||
if (GTK_IS_MENU (combo_box->priv->popup_widget))
|
||||
gtk_combo_box_menu_destroy (combo_box);
|
||||
{
|
||||
gtk_combo_box_menu_destroy (combo_box);
|
||||
gtk_menu_detach (GTK_MENU (combo_box->priv->popup_widget));
|
||||
combo_box->priv->popup_widget = NULL;
|
||||
}
|
||||
|
||||
if (GTK_IS_TREE_VIEW (combo_box->priv->tree_view))
|
||||
gtk_combo_box_list_destroy (combo_box);
|
||||
@@ -3437,9 +3532,6 @@ gtk_combo_box_finalize (GObject *object)
|
||||
|
||||
gtk_combo_box_unset_model (combo_box);
|
||||
|
||||
if (combo_box->priv->model)
|
||||
g_object_unref (combo_box->priv->model);
|
||||
|
||||
for (i = combo_box->priv->cells; i; i = i->next)
|
||||
{
|
||||
ComboCellInfo *info = (ComboCellInfo *)i->data;
|
||||
|
||||
+1
-1
@@ -76,7 +76,7 @@ void gtk_combo_box_set_column_span_column (GtkComboBox *combo_box,
|
||||
/* get/set active item */
|
||||
gint gtk_combo_box_get_active (GtkComboBox *combo_box);
|
||||
void gtk_combo_box_set_active (GtkComboBox *combo_box,
|
||||
gint index);
|
||||
gint index_);
|
||||
gboolean gtk_combo_box_get_active_iter (GtkComboBox *combo_box,
|
||||
GtkTreeIter *iter);
|
||||
void gtk_combo_box_set_active_iter (GtkComboBox *combo_box,
|
||||
|
||||
@@ -363,8 +363,8 @@ gtk_combo_box_entry_new_text (void)
|
||||
GtkListStore *store;
|
||||
|
||||
store = gtk_list_store_new (1, G_TYPE_STRING);
|
||||
|
||||
entry_box = gtk_combo_box_entry_new_with_model (GTK_TREE_MODEL (store), 0);
|
||||
g_object_unref (store);
|
||||
|
||||
return entry_box;
|
||||
}
|
||||
|
||||
+127
-18
@@ -73,6 +73,7 @@ typedef struct _GtkEntryPrivate GtkEntryPrivate;
|
||||
struct _GtkEntryPrivate
|
||||
{
|
||||
gfloat xalign;
|
||||
gint insert_pos;
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -133,6 +134,7 @@ static void gtk_entry_get_property (GObject *object,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gtk_entry_finalize (GObject *object);
|
||||
static void gtk_entry_destroy (GtkObject *object);
|
||||
|
||||
/* GtkWidget methods
|
||||
*/
|
||||
@@ -405,9 +407,11 @@ gtk_entry_class_init (GtkEntryClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class;
|
||||
GtkObjectClass *gtk_object_class;
|
||||
GtkBindingSet *binding_set;
|
||||
|
||||
widget_class = (GtkWidgetClass*) class;
|
||||
gtk_object_class = (GtkObjectClass *)class;
|
||||
parent_class = g_type_class_peek_parent (class);
|
||||
|
||||
gobject_class->finalize = gtk_entry_finalize;
|
||||
@@ -442,6 +446,8 @@ gtk_entry_class_init (GtkEntryClass *class)
|
||||
|
||||
widget_class->popup_menu = gtk_entry_popup_menu;
|
||||
|
||||
gtk_object_class->destroy = gtk_entry_destroy;
|
||||
|
||||
class->move_cursor = gtk_entry_move_cursor;
|
||||
class->insert_at_cursor = gtk_entry_insert_at_cursor;
|
||||
class->delete_from_cursor = gtk_entry_delete_from_cursor;
|
||||
@@ -547,6 +553,14 @@ gtk_entry_class_init (GtkEntryClass *class)
|
||||
"",
|
||||
G_PARAM_READABLE | G_PARAM_WRITABLE));
|
||||
|
||||
/**
|
||||
* GtkEntry:xalign:
|
||||
*
|
||||
* The horizontal alignment, from 0 (left) to 1 (right).
|
||||
* Reversed for RTL layouts.
|
||||
*
|
||||
* Since: 2.4
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_XALIGN,
|
||||
g_param_spec_float ("xalign",
|
||||
@@ -971,6 +985,36 @@ gtk_entry_init (GtkEntry *entry)
|
||||
G_CALLBACK (gtk_entry_delete_surrounding_cb), entry);
|
||||
}
|
||||
|
||||
/*
|
||||
* Overwrite a memory that might contain sensitive information.
|
||||
*/
|
||||
static void
|
||||
trash_area (gchar *area, gsize len)
|
||||
{
|
||||
volatile gchar *varea = (volatile gchar *)area;
|
||||
while (len-- > 0)
|
||||
*varea++ = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_destroy (GtkObject *object)
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY (object);
|
||||
|
||||
entry->n_bytes = 0;
|
||||
entry->current_pos = entry->selection_bound = entry->text_length = 0;
|
||||
gtk_entry_reset_im_context (entry);
|
||||
gtk_entry_reset_layout (entry);
|
||||
|
||||
if (!entry->visible)
|
||||
{
|
||||
/* We want to trash the text here because the entry might be leaked. */
|
||||
trash_area (entry->text, strlen (entry->text));
|
||||
}
|
||||
|
||||
GTK_OBJECT_CLASS (parent_class)->destroy (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_finalize (GObject *object)
|
||||
{
|
||||
@@ -992,8 +1036,12 @@ gtk_entry_finalize (GObject *object)
|
||||
entry->text_size = 0;
|
||||
|
||||
if (entry->text)
|
||||
g_free (entry->text);
|
||||
entry->text = NULL;
|
||||
{
|
||||
if (!entry->visible)
|
||||
trash_area (entry->text, strlen (entry->text));
|
||||
g_free (entry->text);
|
||||
entry->text = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
@@ -1330,6 +1378,7 @@ gtk_entry_button_press (GtkWidget *widget,
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY (widget);
|
||||
GtkEditable *editable = GTK_EDITABLE (widget);
|
||||
GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
|
||||
gint tmp_pos;
|
||||
gint sel_start, sel_end;
|
||||
|
||||
@@ -1458,7 +1507,7 @@ gtk_entry_button_press (GtkWidget *widget,
|
||||
}
|
||||
else if (event->button == 2 && event->type == GDK_BUTTON_PRESS && entry->editable)
|
||||
{
|
||||
gtk_editable_select_region (editable, tmp_pos, tmp_pos);
|
||||
priv->insert_pos = tmp_pos;
|
||||
gtk_entry_paste (entry, GDK_SELECTION_PRIMARY);
|
||||
|
||||
return TRUE;
|
||||
@@ -1822,9 +1871,12 @@ gtk_entry_insert_text (GtkEditable *editable,
|
||||
|
||||
text[new_text_length] = '\0';
|
||||
strncpy (text, new_text, new_text_length);
|
||||
|
||||
|
||||
g_signal_emit_by_name (editable, "insert_text", text, new_text_length, position);
|
||||
|
||||
if (!entry->visible)
|
||||
trash_area (text, new_text_length);
|
||||
|
||||
if (new_text_length > 63)
|
||||
g_free (text);
|
||||
|
||||
@@ -2024,6 +2076,8 @@ gtk_entry_real_insert_text (GtkEditable *editable,
|
||||
|
||||
if (new_text_length + entry->n_bytes + 1 > entry->text_size)
|
||||
{
|
||||
gsize prev_size = entry->text_size;
|
||||
|
||||
while (new_text_length + entry->n_bytes + 1 > entry->text_size)
|
||||
{
|
||||
if (entry->text_size == 0)
|
||||
@@ -2047,7 +2101,17 @@ gtk_entry_real_insert_text (GtkEditable *editable,
|
||||
}
|
||||
}
|
||||
|
||||
entry->text = g_realloc (entry->text, entry->text_size);
|
||||
if (entry->visible)
|
||||
entry->text = g_realloc (entry->text, entry->text_size);
|
||||
else
|
||||
{
|
||||
/* Same thing, just slower and without leaving stuff in memory. */
|
||||
gchar *et_new = g_malloc (entry->text_size);
|
||||
memcpy (et_new, entry->text, MIN (prev_size, entry->text_size));
|
||||
trash_area (entry->text, prev_size);
|
||||
g_free (entry->text);
|
||||
entry->text = et_new;
|
||||
}
|
||||
}
|
||||
|
||||
index = g_utf8_offset_to_pointer (entry->text, *position) - entry->text;
|
||||
@@ -2097,6 +2161,13 @@ gtk_entry_real_delete_text (GtkEditable *editable,
|
||||
g_memmove (entry->text + start_index, entry->text + end_index, entry->n_bytes + 1 - end_index);
|
||||
entry->text_length -= (end_pos - start_pos);
|
||||
entry->n_bytes -= (end_index - start_index);
|
||||
|
||||
/* In password-mode, make sure we don't leave anything sensitive after
|
||||
* the terminating zero. Note, that the terminating zero already trashed
|
||||
* one byte.
|
||||
*/
|
||||
if (!entry->visible)
|
||||
trash_area (entry->text + entry->n_bytes + 1, end_index - start_index - 1);
|
||||
|
||||
current_pos = entry->current_pos;
|
||||
if (current_pos > start_pos)
|
||||
@@ -2706,7 +2777,12 @@ gtk_entry_create_layout (GtkEntry *entry,
|
||||
{
|
||||
PangoDirection pango_dir;
|
||||
|
||||
pango_dir = pango_find_base_dir (entry->text, entry->n_bytes);
|
||||
if (entry->visible)
|
||||
pango_dir = pango_find_base_dir (entry->text, entry->n_bytes);
|
||||
|
||||
else
|
||||
pango_dir = PANGO_DIRECTION_NEUTRAL;
|
||||
|
||||
if (pango_dir == PANGO_DIRECTION_NEUTRAL)
|
||||
{
|
||||
if (GTK_WIDGET_HAS_FOCUS (widget))
|
||||
@@ -3226,13 +3302,13 @@ gtk_entry_move_visually (GtkEntry *entry,
|
||||
count++;
|
||||
}
|
||||
|
||||
if (new_index < 0 || new_index == G_MAXINT)
|
||||
break;
|
||||
|
||||
index = new_index;
|
||||
if (new_index < 0)
|
||||
index = 0;
|
||||
else if (new_index != G_MAXINT)
|
||||
index = new_index;
|
||||
|
||||
while (new_trailing--)
|
||||
index = g_utf8_next_char (text + new_index) - text;
|
||||
index = g_utf8_next_char (text + index) - text;
|
||||
}
|
||||
|
||||
return g_utf8_pointer_to_offset (text, text + index);
|
||||
@@ -3414,17 +3490,38 @@ paste_received (GtkClipboard *clipboard,
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY (data);
|
||||
GtkEditable *editable = GTK_EDITABLE (entry);
|
||||
GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
|
||||
|
||||
if (entry->button == 2)
|
||||
{
|
||||
gint pos, start, end;
|
||||
pos = priv->insert_pos;
|
||||
gtk_editable_get_selection_bounds (editable, &start, &end);
|
||||
if (!((start <= pos && pos <= end) || (end <= pos && pos <= start)))
|
||||
gtk_editable_select_region (editable, pos, pos);
|
||||
}
|
||||
|
||||
if (text)
|
||||
{
|
||||
gint pos, start, end;
|
||||
|
||||
GtkEntryCompletion *completion = gtk_entry_get_completion (entry);
|
||||
|
||||
if (completion)
|
||||
{
|
||||
g_signal_handler_block (entry, completion->priv->changed_id);
|
||||
if (GTK_WIDGET_MAPPED (completion->priv->popup_window))
|
||||
_gtk_entry_completion_popdown (completion);
|
||||
}
|
||||
|
||||
if (gtk_editable_get_selection_bounds (editable, &start, &end))
|
||||
gtk_editable_delete_text (editable, start, end);
|
||||
|
||||
pos = entry->current_pos;
|
||||
gtk_editable_insert_text (editable, text, -1, &pos);
|
||||
gtk_editable_set_position (editable, pos);
|
||||
|
||||
if (completion)
|
||||
g_signal_handler_unblock (entry, completion->priv->changed_id);
|
||||
}
|
||||
|
||||
g_object_unref (entry);
|
||||
@@ -3995,7 +4092,7 @@ gtk_entry_text_index_to_layout_index (GtkEntry *entry,
|
||||
* is clicked.
|
||||
*
|
||||
* Note that as the user scrolls around in the entry the offsets will
|
||||
* change; you'll need to connect to the "notify::scroll_offset"
|
||||
* change; you'll need to connect to the "notify::scroll-offset"
|
||||
* signal to track this. Remember when using the #PangoLayout
|
||||
* functions you need to convert to and from pixels using
|
||||
* PANGO_PIXELS() or #PANGO_SCALE.
|
||||
@@ -4038,6 +4135,8 @@ gtk_entry_get_layout_offsets (GtkEntry *entry,
|
||||
* Sets the alignment for the contents of the entry. This controls
|
||||
* the horizontal positioning of the contents when the displayed
|
||||
* text is shorter than the width of the entry.
|
||||
*
|
||||
* Since: 2.4
|
||||
**/
|
||||
void
|
||||
gtk_entry_set_alignment (GtkEntry *entry, gfloat xalign)
|
||||
@@ -4070,6 +4169,8 @@ gtk_entry_set_alignment (GtkEntry *entry, gfloat xalign)
|
||||
* Gets the value set by gtk_entry_set_alignment().
|
||||
*
|
||||
* Return value: the alignment
|
||||
*
|
||||
* Since: 2.4
|
||||
**/
|
||||
gfloat
|
||||
gtk_entry_get_alignment (GtkEntry *entry)
|
||||
@@ -4139,18 +4240,26 @@ popup_position_func (GtkMenu *menu,
|
||||
GtkWidget *widget = GTK_WIDGET (entry);
|
||||
GdkScreen *screen = gtk_widget_get_screen (widget);
|
||||
GtkRequisition req;
|
||||
gint monitor_num;
|
||||
GdkRectangle monitor;
|
||||
|
||||
g_return_if_fail (GTK_WIDGET_REALIZED (entry));
|
||||
|
||||
gdk_window_get_origin (widget->window, x, y);
|
||||
|
||||
gdk_window_get_origin (widget->window, x, y);
|
||||
|
||||
gtk_widget_size_request (entry->popup_menu, &req);
|
||||
|
||||
*x += widget->allocation.width / 2;
|
||||
*y += widget->allocation.height;
|
||||
|
||||
*x = CLAMP (*x, 0, MAX (0, gdk_screen_get_width (screen) - req.width));
|
||||
*y = CLAMP (*y, 0, MAX (0, gdk_screen_get_height (screen) - req.height));
|
||||
monitor_num = gdk_screen_get_monitor_at_point (screen, *x, *y);
|
||||
gtk_menu_set_monitor (menu, monitor_num);
|
||||
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
|
||||
|
||||
*x = CLAMP (*x, monitor.x, monitor.x + MAX (0, monitor.width - req.width));
|
||||
*y = CLAMP (*y, monitor.y, monitor.y + MAX (0, monitor.height - req.height));
|
||||
|
||||
*push_in = FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -4632,7 +4741,7 @@ gtk_entry_completion_timeout (gpointer data)
|
||||
|
||||
completion->priv->completion_timeout = 0;
|
||||
|
||||
if (strlen (gtk_entry_get_text (GTK_ENTRY (completion->priv->entry)))
|
||||
if (g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (completion->priv->entry)), -1)
|
||||
>= completion->priv->minimum_key_length)
|
||||
{
|
||||
gint matches;
|
||||
|
||||
+80
-29
@@ -34,6 +34,7 @@
|
||||
#include "gtkmain.h"
|
||||
#include "gtksignal.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtktreeprivate.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -108,7 +109,12 @@ static gboolean gtk_entry_completion_action_button_press (GtkWidget
|
||||
gpointer user_data);
|
||||
static void gtk_entry_completion_selection_changed (GtkTreeSelection *selection,
|
||||
gpointer data);
|
||||
|
||||
static gboolean gtk_entry_completion_list_enter_notify (GtkWidget *widget,
|
||||
GdkEventCrossing *event,
|
||||
gpointer data);
|
||||
static gboolean gtk_entry_completion_list_motion_notify (GtkWidget *widget,
|
||||
GdkEventMotion *event,
|
||||
gpointer data);
|
||||
static void gtk_entry_completion_insert_action (GtkEntryCompletion *completion,
|
||||
gint index,
|
||||
const gchar *string,
|
||||
@@ -270,7 +276,14 @@ gtk_entry_completion_init (GtkEntryCompletion *completion)
|
||||
g_signal_connect (priv->tree_view, "button_press_event",
|
||||
G_CALLBACK (gtk_entry_completion_list_button_press),
|
||||
completion);
|
||||
g_signal_connect (priv->tree_view, "enter_notify_event",
|
||||
G_CALLBACK (gtk_entry_completion_list_enter_notify),
|
||||
completion);
|
||||
g_signal_connect (priv->tree_view, "motion_notify_event",
|
||||
G_CALLBACK (gtk_entry_completion_list_motion_notify),
|
||||
completion);
|
||||
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->tree_view), FALSE);
|
||||
_gtk_tree_view_set_hover_selection (GTK_TREE_VIEW (priv->tree_view), TRUE);
|
||||
|
||||
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_view));
|
||||
gtk_tree_selection_set_mode (sel, GTK_SELECTION_SINGLE);
|
||||
@@ -301,7 +314,14 @@ gtk_entry_completion_init (GtkEntryCompletion *completion)
|
||||
g_signal_connect (priv->action_view, "button_press_event",
|
||||
G_CALLBACK (gtk_entry_completion_action_button_press),
|
||||
completion);
|
||||
g_signal_connect (priv->action_view, "enter_notify_event",
|
||||
G_CALLBACK (gtk_entry_completion_list_enter_notify),
|
||||
completion);
|
||||
g_signal_connect (priv->action_view, "motion_notify_event",
|
||||
G_CALLBACK (gtk_entry_completion_list_motion_notify),
|
||||
completion);
|
||||
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->action_view), FALSE);
|
||||
_gtk_tree_view_set_hover_selection (GTK_TREE_VIEW (priv->action_view), TRUE);
|
||||
|
||||
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->action_view));
|
||||
gtk_tree_selection_set_mode (sel, GTK_SELECTION_SINGLE);
|
||||
@@ -790,6 +810,7 @@ gtk_entry_completion_get_entry (GtkEntryCompletion *completion)
|
||||
*
|
||||
* Sets the model for a #GtkEntryCompletion. If @completion already has
|
||||
* a model set, it will remove it before setting the new model.
|
||||
* If @model is %NULL, then it will unset the model.
|
||||
*
|
||||
* Since: 2.4
|
||||
*/
|
||||
@@ -798,7 +819,7 @@ gtk_entry_completion_set_model (GtkEntryCompletion *completion,
|
||||
GtkTreeModel *model)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
|
||||
g_return_if_fail (GTK_IS_TREE_MODEL (model));
|
||||
g_return_if_fail (model == NULL || GTK_IS_TREE_MODEL (model));
|
||||
|
||||
/* code will unref the old filter model (if any) */
|
||||
completion->priv->filter_model =
|
||||
@@ -960,10 +981,10 @@ gtk_entry_completion_insert_action (GtkEntryCompletion *completion,
|
||||
/**
|
||||
* gtk_entry_completion_insert_action_text:
|
||||
* @completion: A #GtkEntryCompletion.
|
||||
* @index: The index of the item to insert.
|
||||
* @index_: The index of the item to insert.
|
||||
* @text: Text of the item to insert.
|
||||
*
|
||||
* Inserts an action in @completion's action item list at position @index
|
||||
* Inserts an action in @completion's action item list at position @index_
|
||||
* with text @text. If you want the action item to have markup, use
|
||||
* gtk_entry_completion_insert_action_markup().
|
||||
*
|
||||
@@ -971,57 +992,57 @@ gtk_entry_completion_insert_action (GtkEntryCompletion *completion,
|
||||
*/
|
||||
void
|
||||
gtk_entry_completion_insert_action_text (GtkEntryCompletion *completion,
|
||||
gint index,
|
||||
gint index_,
|
||||
const gchar *text)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
|
||||
g_return_if_fail (text != NULL);
|
||||
|
||||
gtk_entry_completion_insert_action (completion, index, text, FALSE);
|
||||
gtk_entry_completion_insert_action (completion, index_, text, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_entry_completion_insert_action_markup:
|
||||
* @completion: A #GtkEntryCompletion.
|
||||
* @index: The index of the item to insert.
|
||||
* @index_: The index of the item to insert.
|
||||
* @markup: Markup of the item to insert.
|
||||
*
|
||||
* Inserts an action in @completion's action item list at position @index
|
||||
* Inserts an action in @completion's action item list at position @index_
|
||||
* with markup @markup.
|
||||
*
|
||||
* Since: 2.4
|
||||
*/
|
||||
void
|
||||
gtk_entry_completion_insert_action_markup (GtkEntryCompletion *completion,
|
||||
gint index,
|
||||
gint index_,
|
||||
const gchar *markup)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
|
||||
g_return_if_fail (markup != NULL);
|
||||
|
||||
gtk_entry_completion_insert_action (completion, index, markup, TRUE);
|
||||
gtk_entry_completion_insert_action (completion, index_, markup, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_entry_completion_delete_action:
|
||||
* @completion: A #GtkEntryCompletion.
|
||||
* @index: The index of the item to Delete.
|
||||
* @index_: The index of the item to Delete.
|
||||
*
|
||||
* Deletes the action at @index from @completion's action list.
|
||||
* Deletes the action at @index_ from @completion's action list.
|
||||
*
|
||||
* Since: 2.4
|
||||
*/
|
||||
void
|
||||
gtk_entry_completion_delete_action (GtkEntryCompletion *completion,
|
||||
gint index)
|
||||
gint index_)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
|
||||
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
|
||||
g_return_if_fail (index >= 0);
|
||||
g_return_if_fail (index_ >= 0);
|
||||
|
||||
gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (completion->priv->actions),
|
||||
&iter, NULL, index);
|
||||
&iter, NULL, index_);
|
||||
gtk_list_store_remove (completion->priv->actions, &iter);
|
||||
}
|
||||
|
||||
@@ -1093,6 +1114,29 @@ get_borders (GtkEntry *entry,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_entry_completion_list_enter_notify (GtkWidget *widget,
|
||||
GdkEventCrossing *event,
|
||||
gpointer data)
|
||||
{
|
||||
GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (data);
|
||||
|
||||
return completion->priv->ignore_enter;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_entry_completion_list_motion_notify (GtkWidget *widget,
|
||||
GdkEventMotion *event,
|
||||
gpointer data)
|
||||
{
|
||||
GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (data);
|
||||
|
||||
completion->priv->ignore_enter = FALSE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* some nasty size requisition */
|
||||
gboolean
|
||||
_gtk_entry_completion_resize_popup (GtkEntryCompletion *completion)
|
||||
@@ -1103,9 +1147,11 @@ _gtk_entry_completion_resize_popup (GtkEntryCompletion *completion)
|
||||
gint monitor_num;
|
||||
GdkRectangle monitor;
|
||||
GtkRequisition popup_req;
|
||||
GtkRequisition entry_req;
|
||||
GtkTreePath *path;
|
||||
gboolean above;
|
||||
|
||||
gint width;
|
||||
|
||||
gdk_window_get_origin (completion->priv->entry->window, &x, &y);
|
||||
get_borders (GTK_ENTRY (completion->priv->entry), &x_border, &y_border);
|
||||
|
||||
@@ -1124,9 +1170,14 @@ _gtk_entry_completion_resize_popup (GtkEntryCompletion *completion)
|
||||
else
|
||||
gtk_widget_show (completion->priv->scrolled_window);
|
||||
|
||||
screen = gtk_widget_get_screen (GTK_WIDGET (completion->priv->entry));
|
||||
monitor_num = gdk_screen_get_monitor_at_window (screen,
|
||||
GTK_WIDGET (completion->priv->entry)->window);
|
||||
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
|
||||
|
||||
width = MIN (completion->priv->entry->allocation.width, monitor.width);
|
||||
gtk_widget_set_size_request (completion->priv->tree_view,
|
||||
completion->priv->entry->allocation.width - 2 * x_border,
|
||||
items * height);
|
||||
width - 2 * x_border, items * height);
|
||||
|
||||
/* default on no match */
|
||||
completion->priv->current_selected = -1;
|
||||
@@ -1142,27 +1193,22 @@ _gtk_entry_completion_resize_popup (GtkEntryCompletion *completion)
|
||||
&height);
|
||||
|
||||
gtk_widget_set_size_request (completion->priv->action_view,
|
||||
completion->priv->entry->allocation.width - 2 * x_border,
|
||||
items * height);
|
||||
width - 2 * x_border, items * height);
|
||||
}
|
||||
else
|
||||
gtk_widget_hide (completion->priv->action_view);
|
||||
|
||||
gtk_widget_size_request (completion->priv->popup_window, &popup_req);
|
||||
|
||||
screen = gtk_widget_get_screen (GTK_WIDGET (completion->priv->entry));
|
||||
monitor_num = gdk_screen_get_monitor_at_window (screen,
|
||||
GTK_WIDGET (completion->priv->entry)->window);
|
||||
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
|
||||
gtk_widget_size_request (completion->priv->entry, &entry_req);
|
||||
|
||||
if (x < monitor.x)
|
||||
x = monitor.x;
|
||||
else if (x + popup_req.width > monitor.x + monitor.width)
|
||||
x = monitor.x + monitor.width - popup_req.width;
|
||||
|
||||
if (y + height + popup_req.height <= monitor.y + monitor.height)
|
||||
if (y + entry_req.height + popup_req.height <= monitor.y + monitor.height)
|
||||
{
|
||||
y += height;
|
||||
y += entry_req.height;
|
||||
above = FALSE;
|
||||
}
|
||||
else
|
||||
@@ -1193,8 +1239,8 @@ _gtk_entry_completion_popup (GtkEntryCompletion *completion)
|
||||
if (GTK_WIDGET_MAPPED (completion->priv->popup_window))
|
||||
return;
|
||||
|
||||
completion->priv->may_wrap = TRUE;
|
||||
|
||||
completion->priv->ignore_enter = TRUE;
|
||||
|
||||
column = gtk_tree_view_get_column (GTK_TREE_VIEW (completion->priv->action_view), 0);
|
||||
renderers = gtk_tree_view_column_get_cell_renderers (column);
|
||||
gtk_widget_ensure_style (completion->priv->tree_view);
|
||||
@@ -1220,6 +1266,11 @@ _gtk_entry_completion_popup (GtkEntryCompletion *completion)
|
||||
void
|
||||
_gtk_entry_completion_popdown (GtkEntryCompletion *completion)
|
||||
{
|
||||
if (!GTK_WIDGET_MAPPED (completion->priv->popup_window))
|
||||
return;
|
||||
|
||||
completion->priv->ignore_enter = FALSE;
|
||||
|
||||
gdk_pointer_ungrab (GDK_CURRENT_TIME);
|
||||
gtk_grab_remove (completion->priv->popup_window);
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ struct _GtkEntryCompletionClass
|
||||
GtkTreeModel *model,
|
||||
GtkTreeIter *iter);
|
||||
void (* action_activated) (GtkEntryCompletion *completion,
|
||||
gint index);
|
||||
gint index_);
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_gtk_reserved0) (void);
|
||||
@@ -91,13 +91,13 @@ gint gtk_entry_completion_get_minimum_key_length (GtkEntryComplet
|
||||
void gtk_entry_completion_complete (GtkEntryCompletion *completion);
|
||||
|
||||
void gtk_entry_completion_insert_action_text (GtkEntryCompletion *completion,
|
||||
gint index,
|
||||
gint index_,
|
||||
const gchar *text);
|
||||
void gtk_entry_completion_insert_action_markup (GtkEntryCompletion *completion,
|
||||
gint index,
|
||||
gint index_,
|
||||
const gchar *markup);
|
||||
void gtk_entry_completion_delete_action (GtkEntryCompletion *completion,
|
||||
gint index);
|
||||
gint index_);
|
||||
|
||||
/* convenience */
|
||||
void gtk_entry_completion_set_text_column (GtkEntryCompletion *completion,
|
||||
|
||||
@@ -58,7 +58,7 @@ struct _GtkEntryCompletionPrivate
|
||||
gulong key_press_id;
|
||||
gulong key_release_id;
|
||||
|
||||
gboolean may_wrap;
|
||||
gboolean ignore_enter;
|
||||
};
|
||||
|
||||
gboolean _gtk_entry_completion_resize_popup (GtkEntryCompletion *completion);
|
||||
|
||||
+9
-2
@@ -614,9 +614,16 @@ gtk_expander_size_allocate (GtkWidget *widget,
|
||||
|
||||
ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL;
|
||||
|
||||
label_allocation.x = widget->allocation.x + border_width + focus_width + focus_pad;
|
||||
if (ltr)
|
||||
label_allocation.x += expander_size + 2 * expander_spacing;
|
||||
label_allocation.x = (widget->allocation.x +
|
||||
border_width + focus_width + focus_pad +
|
||||
expander_size + 2 * expander_spacing);
|
||||
else
|
||||
label_allocation.x = (widget->allocation.x + widget->allocation.width -
|
||||
(label_requisition.width +
|
||||
border_width + focus_width + focus_pad +
|
||||
expander_size + 2 * expander_spacing));
|
||||
|
||||
label_allocation.y = widget->allocation.y + border_width + focus_width + focus_pad;
|
||||
|
||||
label_allocation.width = MIN (label_requisition.width,
|
||||
|
||||
@@ -1641,7 +1641,7 @@ gtk_file_chooser_remove_shortcut_folder (GtkFileChooser *chooser,
|
||||
* @chooser: a #GtkFileChooser
|
||||
*
|
||||
* Queries the list of shortcut folders in the file chooser, as set by
|
||||
* gtk_file_chooser_set_shortcut_folders().
|
||||
* gtk_file_chooser_add_shortcut_folder().
|
||||
*
|
||||
* Return value: A list of folder filenames, or %NULL if there are no shortcut
|
||||
* folders. Free the returned list with g_slist_free(), and the filenames with
|
||||
@@ -1760,7 +1760,7 @@ gtk_file_chooser_remove_shortcut_folder_uri (GtkFileChooser *chooser,
|
||||
* @chooser: a #GtkFileChooser
|
||||
*
|
||||
* Queries the list of shortcut folders in the file chooser, as set by
|
||||
* gtk_file_chooser_set_shortcut_folder_uris().
|
||||
* gtk_file_chooser_add_shortcut_folder_uri().
|
||||
*
|
||||
* Return value: A list of folder URIs, or %NULL if there are no shortcut
|
||||
* folders. Free the returned list with g_slist_free(), and the URIs with
|
||||
|
||||
+397
-189
@@ -137,8 +137,8 @@ struct _GtkFileChooserDefault
|
||||
int num_shortcuts;
|
||||
int num_bookmarks;
|
||||
|
||||
guint volumes_changed_id;
|
||||
guint bookmarks_changed_id;
|
||||
gulong volumes_changed_id;
|
||||
gulong bookmarks_changed_id;
|
||||
|
||||
GtkFilePath *current_volume_path;
|
||||
GtkFilePath *current_folder;
|
||||
@@ -148,9 +148,15 @@ struct _GtkFileChooserDefault
|
||||
GtkTreeViewColumn *list_name_column;
|
||||
GtkCellRenderer *list_name_renderer;
|
||||
|
||||
guint settings_signal_id;
|
||||
GSource *edited_idle;
|
||||
char *edited_new_text;
|
||||
|
||||
gulong settings_signal_id;
|
||||
int icon_size;
|
||||
|
||||
gulong toplevel_set_focus_id;
|
||||
GtkWidget *toplevel_last_focus_widget;
|
||||
|
||||
#if 0
|
||||
GdkDragContext *shortcuts_drag_context;
|
||||
GSource *shortcuts_drag_outside_idle;
|
||||
@@ -271,6 +277,8 @@ static void gtk_file_chooser_default_get_property (GObject *ob
|
||||
GParamSpec *pspec);
|
||||
static void gtk_file_chooser_default_dispose (GObject *object);
|
||||
static void gtk_file_chooser_default_show_all (GtkWidget *widget);
|
||||
static void gtk_file_chooser_default_hierarchy_changed (GtkWidget *widget,
|
||||
GtkWidget *previous_toplevel);
|
||||
static void gtk_file_chooser_default_style_set (GtkWidget *widget,
|
||||
GtkStyle *previous_style);
|
||||
static void gtk_file_chooser_default_screen_changed (GtkWidget *widget,
|
||||
@@ -340,8 +348,8 @@ static gboolean shortcuts_select_func (GtkTreeSelection *selection,
|
||||
GtkTreePath *path,
|
||||
gboolean path_currently_selected,
|
||||
gpointer data);
|
||||
static void shortcuts_activate_item (GtkFileChooserDefault *impl,
|
||||
int item_num);
|
||||
static void shortcuts_activate_iter (GtkFileChooserDefault *impl,
|
||||
GtkTreeIter *iter);
|
||||
static int shortcuts_get_index (GtkFileChooserDefault *impl,
|
||||
ShortcutsIndex where);
|
||||
static int shortcut_find_position (GtkFileChooserDefault *impl,
|
||||
@@ -484,6 +492,7 @@ gtk_file_chooser_default_class_init (GtkFileChooserDefaultClass *class)
|
||||
gobject_class->dispose = gtk_file_chooser_default_dispose;
|
||||
|
||||
widget_class->show_all = gtk_file_chooser_default_show_all;
|
||||
widget_class->hierarchy_changed = gtk_file_chooser_default_hierarchy_changed;
|
||||
widget_class->style_set = gtk_file_chooser_default_style_set;
|
||||
widget_class->screen_changed = gtk_file_chooser_default_screen_changed;
|
||||
|
||||
@@ -654,6 +663,8 @@ gtk_file_chooser_default_finalize (GObject *object)
|
||||
|
||||
g_free (impl->preview_display_name);
|
||||
|
||||
g_free (impl->edited_new_text);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -780,12 +791,26 @@ change_folder_and_display_error (GtkFileChooserDefault *impl,
|
||||
{
|
||||
GError *error;
|
||||
gboolean result;
|
||||
GtkFilePath *path_copy;
|
||||
|
||||
/* We copy the path because of this case:
|
||||
*
|
||||
* list_row_activated()
|
||||
* fetches path from model; path belongs to the model (*)
|
||||
* calls change_folder_and_display_error()
|
||||
* calls _gtk_file_chooser_set_current_folder_path()
|
||||
* changing folders fails, sets model to NULL, thus freeing the path in (*)
|
||||
*/
|
||||
|
||||
path_copy = gtk_file_path_copy (path);
|
||||
|
||||
error = NULL;
|
||||
result = _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), path, &error);
|
||||
result = _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), path_copy, &error);
|
||||
|
||||
if (!result)
|
||||
error_changing_folder_dialog (impl, path, error);
|
||||
error_changing_folder_dialog (impl, path_copy, error);
|
||||
|
||||
gtk_file_path_free (path_copy);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1468,6 +1493,9 @@ new_folder_button_clicked (GtkButton *button,
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
|
||||
if (!impl->browse_files_model)
|
||||
return; /* FIXME: this sucks. Disable the New Folder button or something. */
|
||||
|
||||
_gtk_file_system_model_add_editable (impl->browse_files_model, &iter);
|
||||
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->browse_files_model), &iter);
|
||||
@@ -1482,6 +1510,69 @@ new_folder_button_clicked (GtkButton *button,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
/* Idle handler for creating a new folder after editing its name cell, or for
|
||||
* canceling the editing.
|
||||
*/
|
||||
static gboolean
|
||||
edited_idle_cb (GtkFileChooserDefault *impl)
|
||||
{
|
||||
g_source_destroy (impl->edited_idle);
|
||||
impl->edited_idle = NULL;
|
||||
|
||||
_gtk_file_system_model_remove_editable (impl->browse_files_model);
|
||||
g_object_set (impl->list_name_renderer, "editable", FALSE, NULL);
|
||||
|
||||
if (impl->edited_new_text) /* not cancelled? */
|
||||
{
|
||||
GError *error;
|
||||
GtkFilePath *file_path;
|
||||
|
||||
error = NULL;
|
||||
file_path = gtk_file_system_make_path (impl->file_system, impl->current_folder, impl->edited_new_text,
|
||||
&error);
|
||||
if (file_path)
|
||||
{
|
||||
error = NULL;
|
||||
if (gtk_file_system_create_folder (impl->file_system, file_path, &error))
|
||||
change_folder_and_display_error (impl, file_path);
|
||||
else
|
||||
error_dialog (impl,
|
||||
_("Could not create folder %s:\n%s"),
|
||||
file_path, error);
|
||||
|
||||
gtk_file_path_free (file_path);
|
||||
}
|
||||
else
|
||||
error_building_filename_dialog (impl, impl->current_folder, impl->edited_new_text, error);
|
||||
|
||||
g_free (impl->edited_new_text);
|
||||
impl->edited_new_text = NULL;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
queue_edited_idle (GtkFileChooserDefault *impl,
|
||||
const gchar *new_text)
|
||||
{
|
||||
/* We create the folder in an idle handler so that we don't modify the tree
|
||||
* just now.
|
||||
*/
|
||||
|
||||
g_assert (!impl->edited_idle);
|
||||
g_assert (!impl->edited_new_text);
|
||||
|
||||
impl->edited_idle = g_idle_source_new ();
|
||||
g_source_set_closure (impl->edited_idle,
|
||||
g_cclosure_new_object (G_CALLBACK (edited_idle_cb),
|
||||
G_OBJECT (impl)));
|
||||
g_source_attach (impl->edited_idle, NULL);
|
||||
|
||||
if (new_text)
|
||||
impl->edited_new_text = g_strdup (new_text);
|
||||
}
|
||||
|
||||
/* Callback used from the text cell renderer when the new folder is named */
|
||||
static void
|
||||
renderer_edited_cb (GtkCellRendererText *cell_renderer_text,
|
||||
@@ -1489,31 +1580,7 @@ renderer_edited_cb (GtkCellRendererText *cell_renderer_text,
|
||||
const gchar *new_text,
|
||||
GtkFileChooserDefault *impl)
|
||||
{
|
||||
GError *error;
|
||||
GtkFilePath *file_path;
|
||||
|
||||
_gtk_file_system_model_remove_editable (impl->browse_files_model);
|
||||
g_object_set (impl->list_name_renderer, "editable", FALSE, NULL);
|
||||
|
||||
error = NULL;
|
||||
file_path = gtk_file_system_make_path (impl->file_system, impl->current_folder, new_text, &error);
|
||||
if (!file_path)
|
||||
{
|
||||
error_building_filename_dialog (impl, impl->current_folder, new_text, error);
|
||||
return;
|
||||
}
|
||||
|
||||
error = NULL;
|
||||
if (!gtk_file_system_create_folder (impl->file_system, file_path, &error))
|
||||
{
|
||||
error_dialog (impl,
|
||||
_("Could not create folder %s:\n%s"),
|
||||
file_path, error);
|
||||
}
|
||||
|
||||
gtk_file_path_free (file_path);
|
||||
|
||||
/* FIXME: scroll to the new folder and select it */
|
||||
queue_edited_idle (impl, new_text);
|
||||
}
|
||||
|
||||
/* Callback used from the text cell renderer when the new folder edition gets
|
||||
@@ -1523,8 +1590,7 @@ static void
|
||||
renderer_editing_canceled_cb (GtkCellRendererText *cell_renderer_text,
|
||||
GtkFileChooserDefault *impl)
|
||||
{
|
||||
_gtk_file_system_model_remove_editable (impl->browse_files_model);
|
||||
g_object_set (impl->list_name_renderer, "editable", FALSE, NULL);
|
||||
queue_edited_idle (impl, NULL);
|
||||
}
|
||||
|
||||
/* Creates the widgets for the filter combo box */
|
||||
@@ -1707,22 +1773,40 @@ add_bookmark_button_clicked_cb (GtkButton *button,
|
||||
impl);
|
||||
}
|
||||
|
||||
/* Returns TRUE plus an iter in the shortcuts_model if a row is selected;
|
||||
* returns FALSE if no shortcut is selected.
|
||||
*/
|
||||
static gboolean
|
||||
shortcuts_get_selected (GtkFileChooserDefault *impl,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
GtkTreeSelection *selection;
|
||||
GtkTreeIter parent_iter;
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view));
|
||||
|
||||
if (!gtk_tree_selection_get_selected (selection, NULL, &parent_iter))
|
||||
return FALSE;
|
||||
|
||||
gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_filter_model),
|
||||
iter,
|
||||
&parent_iter);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Removes the selected bookmarks */
|
||||
static void
|
||||
remove_selected_bookmarks (GtkFileChooserDefault *impl)
|
||||
{
|
||||
GtkTreeSelection *selection;
|
||||
GtkTreeIter iter;
|
||||
GtkFilePath *path;
|
||||
gboolean removable;
|
||||
GError *error;
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view));
|
||||
|
||||
if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
|
||||
if (!shortcuts_get_selected (impl, &iter))
|
||||
return;
|
||||
|
||||
gtk_tree_model_get (impl->shortcuts_filter_model, &iter,
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
|
||||
SHORTCUTS_COL_PATH, &path,
|
||||
SHORTCUTS_COL_REMOVABLE, &removable, -1);
|
||||
if (!removable)
|
||||
@@ -1835,10 +1919,8 @@ selection_check (GtkFileChooserDefault *impl,
|
||||
static void
|
||||
bookmarks_check_add_sensitivity (GtkFileChooserDefault *impl)
|
||||
{
|
||||
GtkTreeSelection *selection;
|
||||
gboolean active;
|
||||
|
||||
/* Check selection */
|
||||
GtkTreeSelection *selection;
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
|
||||
|
||||
@@ -1863,14 +1945,11 @@ bookmarks_check_add_sensitivity (GtkFileChooserDefault *impl)
|
||||
static void
|
||||
bookmarks_check_remove_sensitivity (GtkFileChooserDefault *impl)
|
||||
{
|
||||
GtkTreeSelection *selection;
|
||||
GtkTreeIter iter;
|
||||
gboolean removable = FALSE;
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view));
|
||||
|
||||
if (gtk_tree_selection_get_selected (selection, NULL, &iter))
|
||||
gtk_tree_model_get (impl->shortcuts_filter_model, &iter,
|
||||
if (shortcuts_get_selected (impl, &iter))
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
|
||||
SHORTCUTS_COL_REMOVABLE, &removable,
|
||||
-1);
|
||||
|
||||
@@ -1939,8 +2018,7 @@ shortcuts_drag_set_delete_cursor (GtkFileChooserDefault *impl,
|
||||
gboolean delete)
|
||||
{
|
||||
GtkTreeView *tree_view;
|
||||
GtkTreeSelection *selection;
|
||||
GtkTreeIter iter, child_iter;
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
GdkPixmap *row_pixmap;
|
||||
GdkBitmap *mask;
|
||||
@@ -1951,15 +2029,10 @@ shortcuts_drag_set_delete_cursor (GtkFileChooserDefault *impl,
|
||||
|
||||
/* Find the selected path and get its drag pixmap */
|
||||
|
||||
selection = gtk_tree_view_get_selection (tree_view);
|
||||
if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
|
||||
if (!shortcuts_get_selected (impl, &iter))
|
||||
g_assert_not_reached ();
|
||||
|
||||
gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_filter_model),
|
||||
&child_iter,
|
||||
&iter);
|
||||
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &child_iter);
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &iter);
|
||||
|
||||
row_pixmap = gtk_tree_view_create_row_drag_icon (tree_view, path);
|
||||
gtk_tree_path_free (path);
|
||||
@@ -2343,8 +2416,7 @@ static void
|
||||
shortcuts_reorder (GtkFileChooserDefault *impl,
|
||||
int new_position)
|
||||
{
|
||||
GtkTreeSelection *selection;
|
||||
GtkTreeIter iter, child_iter;
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
int old_position;
|
||||
int bookmarks_index;
|
||||
@@ -2354,15 +2426,10 @@ shortcuts_reorder (GtkFileChooserDefault *impl,
|
||||
|
||||
/* Get the selected path */
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view));
|
||||
if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
|
||||
if (!shortcuts_get_selected (impl, &iter))
|
||||
g_assert_not_reached ();
|
||||
|
||||
gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_filter_model),
|
||||
&child_iter,
|
||||
&iter);
|
||||
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &child_iter);
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &iter);
|
||||
old_position = *gtk_tree_path_get_indices (path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
@@ -2370,7 +2437,7 @@ shortcuts_reorder (GtkFileChooserDefault *impl,
|
||||
old_position -= bookmarks_index;
|
||||
g_assert (old_position >= 0 && old_position < impl->num_bookmarks);
|
||||
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &child_iter,
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
|
||||
SHORTCUTS_COL_PATH, &file_path,
|
||||
-1);
|
||||
file_path_copy = gtk_file_path_copy (file_path); /* removal below will free file_path, so we need a copy */
|
||||
@@ -2464,6 +2531,7 @@ shortcuts_list_create (GtkFileChooserDefault *impl)
|
||||
/* Tree */
|
||||
|
||||
impl->browse_shortcuts_tree_view = gtk_tree_view_new ();
|
||||
atk_object_set_name (gtk_widget_get_accessible (impl->browse_shortcuts_tree_view), _("Shortcuts"));
|
||||
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view), FALSE);
|
||||
|
||||
gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view), impl->shortcuts_filter_model);
|
||||
@@ -2608,10 +2676,12 @@ trap_activate_cb (GtkWidget *widget,
|
||||
&& widget != window->default_widget
|
||||
&& !(widget == window->focus_widget &&
|
||||
(!window->default_widget || !GTK_WIDGET_SENSITIVE (window->default_widget))))
|
||||
gtk_window_activate_default (window);
|
||||
|
||||
return TRUE;
|
||||
{
|
||||
gtk_window_activate_default (window);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -2668,28 +2738,57 @@ file_list_build_popup_menu (GtkFileChooserDefault *impl)
|
||||
G_CALLBACK (show_hidden_toggled_cb), impl);
|
||||
}
|
||||
|
||||
static void
|
||||
popup_position_func (GtkMenu *menu,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gboolean *push_in,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (user_data);
|
||||
GdkScreen *screen = gtk_widget_get_screen (widget);
|
||||
GtkRequisition req;
|
||||
gint monitor_num;
|
||||
GdkRectangle monitor;
|
||||
|
||||
g_return_if_fail (GTK_WIDGET_REALIZED (widget));
|
||||
|
||||
gdk_window_get_origin (widget->window, x, y);
|
||||
|
||||
gtk_widget_size_request (GTK_WIDGET (menu), &req);
|
||||
|
||||
*x += (widget->allocation.width - req.width) / 2;
|
||||
*y += (widget->allocation.height - req.height) / 2;
|
||||
|
||||
monitor_num = gdk_screen_get_monitor_at_point (screen, *x, *y);
|
||||
gtk_menu_set_monitor (menu, monitor_num);
|
||||
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
|
||||
|
||||
*x = CLAMP (*x, monitor.x, monitor.x + MAX (0, monitor.width - req.width));
|
||||
*y = CLAMP (*y, monitor.y, monitor.y + MAX (0, monitor.height - req.height));
|
||||
|
||||
*push_in = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
file_list_popup_menu (GtkFileChooserDefault *impl,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
int button;
|
||||
guint32 timestamp;
|
||||
|
||||
file_list_build_popup_menu (impl);
|
||||
if (event)
|
||||
{
|
||||
button = event->button;
|
||||
timestamp = event->time;
|
||||
}
|
||||
gtk_menu_popup (GTK_MENU (impl->browse_files_popup_menu),
|
||||
NULL, NULL, NULL, NULL,
|
||||
event->button, event->time);
|
||||
else
|
||||
{
|
||||
button = 0;
|
||||
timestamp = GDK_CURRENT_TIME;
|
||||
gtk_menu_popup (GTK_MENU (impl->browse_files_popup_menu),
|
||||
NULL, NULL,
|
||||
popup_position_func, impl->browse_files_tree_view,
|
||||
0, GDK_CURRENT_TIME);
|
||||
gtk_menu_shell_select_first (GTK_MENU_SHELL (impl->browse_files_popup_menu),
|
||||
FALSE);
|
||||
}
|
||||
|
||||
file_list_build_popup_menu (impl);
|
||||
gtk_menu_popup (GTK_MENU (impl->browse_files_popup_menu),
|
||||
NULL, NULL, NULL, NULL,
|
||||
button, timestamp);
|
||||
}
|
||||
|
||||
/* Callback used for the GtkWidget::popup-menu signal of the file list */
|
||||
@@ -2737,6 +2836,7 @@ create_file_list (GtkFileChooserDefault *impl)
|
||||
|
||||
impl->browse_files_tree_view = gtk_tree_view_new ();
|
||||
g_object_set_data (G_OBJECT (impl->browse_files_tree_view), "GtkFileChooserDefault", impl);
|
||||
atk_object_set_name (gtk_widget_get_accessible (impl->browse_files_tree_view), _("Files"));
|
||||
|
||||
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (impl->browse_files_tree_view), TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (swin), impl->browse_files_tree_view);
|
||||
@@ -2892,16 +2992,13 @@ static void
|
||||
save_folder_combo_changed_cb (GtkComboBox *combo,
|
||||
GtkFileChooserDefault *impl)
|
||||
{
|
||||
int active;
|
||||
GtkTreeIter iter;
|
||||
|
||||
if (impl->changing_folder)
|
||||
return;
|
||||
|
||||
active = gtk_combo_box_get_active (combo);
|
||||
if (active == -1)
|
||||
return;
|
||||
|
||||
shortcuts_activate_item (impl, active);
|
||||
if (gtk_combo_box_get_active_iter (combo, &iter))
|
||||
shortcuts_activate_iter (impl, &iter);
|
||||
}
|
||||
|
||||
/* Creates the combo box with the save folders */
|
||||
@@ -2960,7 +3057,9 @@ save_widgets_create (GtkFileChooserDefault *impl)
|
||||
0, 0);
|
||||
gtk_widget_show (widget);
|
||||
|
||||
impl->save_file_name_entry = gtk_entry_new ();
|
||||
impl->save_file_name_entry = _gtk_file_chooser_entry_new ();
|
||||
_gtk_file_chooser_entry_set_file_system (GTK_FILE_CHOOSER_ENTRY (impl->save_file_name_entry),
|
||||
impl->file_system);
|
||||
gtk_entry_set_width_chars (GTK_ENTRY (impl->save_file_name_entry), 45);
|
||||
gtk_entry_set_activates_default (GTK_ENTRY (impl->save_file_name_entry), TRUE);
|
||||
gtk_table_attach (GTK_TABLE (table), impl->save_file_name_entry,
|
||||
@@ -3405,7 +3504,9 @@ gtk_file_chooser_default_set_property (GObject *object,
|
||||
if (show_hidden != impl->show_hidden)
|
||||
{
|
||||
impl->show_hidden = show_hidden;
|
||||
_gtk_file_system_model_set_show_hidden (impl->browse_files_model, show_hidden);
|
||||
|
||||
if (impl->browse_files_model)
|
||||
_gtk_file_system_model_set_show_hidden (impl->browse_files_model, show_hidden);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -3505,6 +3606,48 @@ gtk_file_chooser_default_show_all (GtkWidget *widget)
|
||||
gtk_widget_show_all (impl->extra_widget);
|
||||
}
|
||||
|
||||
/* Handler for GtkWindow::set-focus; this is where we save the last-focused
|
||||
* widget on our toplevel. See gtk_file_chooser_default_hierarchy_changed()
|
||||
*/
|
||||
static void
|
||||
toplevel_set_focus_cb (GtkWindow *window,
|
||||
GtkWidget *focus,
|
||||
GtkFileChooserDefault *impl)
|
||||
{
|
||||
impl->toplevel_last_focus_widget = gtk_window_get_focus (window);
|
||||
}
|
||||
|
||||
/* We monitor the focus widget on our toplevel to be able to know which widget
|
||||
* was last focused at the time our "should_respond" method gets called.
|
||||
*/
|
||||
static void
|
||||
gtk_file_chooser_default_hierarchy_changed (GtkWidget *widget,
|
||||
GtkWidget *previous_toplevel)
|
||||
{
|
||||
GtkFileChooserDefault *impl;
|
||||
GtkWidget *toplevel;
|
||||
|
||||
impl = GTK_FILE_CHOOSER_DEFAULT (widget);
|
||||
|
||||
if (previous_toplevel)
|
||||
{
|
||||
g_assert (impl->toplevel_set_focus_id != 0);
|
||||
g_signal_handler_disconnect (previous_toplevel, impl->toplevel_set_focus_id);
|
||||
impl->toplevel_set_focus_id = 0;
|
||||
impl->toplevel_last_focus_widget = NULL;
|
||||
}
|
||||
else
|
||||
g_assert (impl->toplevel_set_focus_id == 0);
|
||||
|
||||
toplevel = gtk_widget_get_toplevel (widget);
|
||||
if (GTK_IS_WINDOW (toplevel))
|
||||
{
|
||||
impl->toplevel_set_focus_id = g_signal_connect (toplevel, "set-focus",
|
||||
G_CALLBACK (toplevel_set_focus_cb), impl);
|
||||
impl->toplevel_last_focus_widget = gtk_window_get_focus (GTK_WINDOW (toplevel));
|
||||
}
|
||||
}
|
||||
|
||||
/* Changes the icons wherever it is needed */
|
||||
static void
|
||||
change_icon_theme (GtkFileChooserDefault *impl)
|
||||
@@ -3560,8 +3703,8 @@ check_icon_theme (GtkFileChooserDefault *impl)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_chooser_default_style_set (GtkWidget *widget,
|
||||
GtkStyle *previous_style)
|
||||
gtk_file_chooser_default_style_set (GtkWidget *widget,
|
||||
GtkStyle *previous_style)
|
||||
{
|
||||
GtkFileChooserDefault *impl;
|
||||
|
||||
@@ -3570,7 +3713,8 @@ gtk_file_chooser_default_style_set (GtkWidget *widget,
|
||||
if (GTK_WIDGET_CLASS (parent_class)->style_set)
|
||||
GTK_WIDGET_CLASS (parent_class)->style_set (widget, previous_style);
|
||||
|
||||
check_icon_theme (impl);
|
||||
if (gtk_widget_has_screen (GTK_WIDGET (impl)))
|
||||
change_icon_theme (impl);
|
||||
|
||||
g_signal_emit_by_name (widget, "default-size-changed");
|
||||
}
|
||||
@@ -3647,6 +3791,8 @@ list_model_filter_func (GtkFileSystemModel *model,
|
||||
static void
|
||||
install_list_model_filter (GtkFileChooserDefault *impl)
|
||||
{
|
||||
g_assert (impl->browse_files_model != NULL);
|
||||
|
||||
if (impl->current_filter)
|
||||
_gtk_file_system_model_set_filter (impl->browse_files_model,
|
||||
list_model_filter_func,
|
||||
@@ -3766,20 +3912,32 @@ browse_files_model_finished_loading_cb (GtkFileSystemModel *model,
|
||||
}
|
||||
|
||||
/* Gets rid of the old list model and creates a new one for the current folder */
|
||||
static void
|
||||
set_list_model (GtkFileChooserDefault *impl)
|
||||
static gboolean
|
||||
set_list_model (GtkFileChooserDefault *impl,
|
||||
GError **error)
|
||||
{
|
||||
if (impl->browse_files_model)
|
||||
{
|
||||
g_object_unref (impl->browse_files_model);
|
||||
impl->browse_files_model = NULL;
|
||||
|
||||
g_object_unref (impl->sort_model);
|
||||
impl->sort_model = NULL;
|
||||
}
|
||||
|
||||
set_busy_cursor (impl, TRUE);
|
||||
|
||||
impl->browse_files_model = _gtk_file_system_model_new (impl->file_system,
|
||||
impl->current_folder, 0,
|
||||
GTK_FILE_INFO_ALL);
|
||||
GTK_FILE_INFO_ALL,
|
||||
error);
|
||||
if (!impl->browse_files_model)
|
||||
{
|
||||
set_busy_cursor (impl, FALSE);
|
||||
gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_signal_connect (impl->browse_files_model, "finished-loading",
|
||||
G_CALLBACK (browse_files_model_finished_loading_cb), impl);
|
||||
|
||||
@@ -3815,6 +3973,8 @@ set_list_model (GtkFileChooserDefault *impl)
|
||||
gtk_tree_view_columns_autosize (GTK_TREE_VIEW (impl->browse_files_tree_view));
|
||||
gtk_tree_view_set_search_column (GTK_TREE_VIEW (impl->browse_files_tree_view),
|
||||
GTK_FILE_SYSTEM_MODEL_DISPLAY_NAME);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3841,8 +4001,8 @@ update_chooser_entry (GtkFileChooserDefault *impl)
|
||||
info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
|
||||
|
||||
if (!gtk_file_info_get_is_folder (info))
|
||||
gtk_entry_set_text (GTK_ENTRY (impl->save_file_name_entry),
|
||||
gtk_file_info_get_display_name (info));
|
||||
_gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->save_file_name_entry),
|
||||
gtk_file_info_get_display_name (info));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -3851,6 +4011,7 @@ gtk_file_chooser_default_set_current_folder (GtkFileChooser *chooser,
|
||||
GError **error)
|
||||
{
|
||||
GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
|
||||
gboolean result;
|
||||
|
||||
if (impl->local_only &&
|
||||
!gtk_file_system_path_is_local (impl->file_system, path))
|
||||
@@ -3889,8 +4050,16 @@ gtk_file_chooser_default_set_current_folder (GtkFileChooser *chooser,
|
||||
impl->changing_folder = FALSE;
|
||||
}
|
||||
|
||||
/* Create a new list model */
|
||||
set_list_model (impl);
|
||||
/* Set the folder on the save entry */
|
||||
|
||||
_gtk_file_chooser_entry_set_base_folder (GTK_FILE_CHOOSER_ENTRY (impl->save_file_name_entry),
|
||||
impl->current_folder);
|
||||
|
||||
/* Create a new list model. This is slightly evil; we store the result value
|
||||
* but perform more actions rather than returning immediately even if it
|
||||
* generates an error.
|
||||
*/
|
||||
result = set_list_model (impl, error);
|
||||
|
||||
/* Refresh controls */
|
||||
|
||||
@@ -3903,7 +4072,7 @@ gtk_file_chooser_default_set_current_folder (GtkFileChooser *chooser,
|
||||
|
||||
g_signal_emit_by_name (impl, "selection-changed", 0);
|
||||
|
||||
return TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
static GtkFilePath *
|
||||
@@ -3923,7 +4092,7 @@ gtk_file_chooser_default_set_current_name (GtkFileChooser *chooser,
|
||||
g_return_if_fail (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
|
||||
|| impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
|
||||
|
||||
gtk_entry_set_text (GTK_ENTRY (impl->save_file_name_entry), name);
|
||||
_gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->save_file_name_entry), name);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4024,6 +4193,9 @@ gtk_file_chooser_default_unselect_path (GtkFileChooser *chooser,
|
||||
{
|
||||
GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
|
||||
|
||||
if (!impl->browse_files_model)
|
||||
return;
|
||||
|
||||
_gtk_file_system_model_path_do (impl->browse_files_model, path,
|
||||
unselect_func, impl);
|
||||
}
|
||||
@@ -4054,16 +4226,21 @@ check_save_entry (GtkFileChooserDefault *impl,
|
||||
gboolean *is_valid,
|
||||
gboolean *is_empty)
|
||||
{
|
||||
const char *filename;
|
||||
GtkFileChooserEntry *chooser_entry;
|
||||
const GtkFilePath *current_folder;
|
||||
const char *file_part;
|
||||
GtkFilePath *path;
|
||||
GError *error;
|
||||
|
||||
g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
|
||||
|| impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
|
||||
|
||||
filename = gtk_entry_get_text (GTK_ENTRY (impl->save_file_name_entry));
|
||||
chooser_entry = GTK_FILE_CHOOSER_ENTRY (impl->save_file_name_entry);
|
||||
|
||||
if (!filename || filename[0] == '\0')
|
||||
current_folder = _gtk_file_chooser_entry_get_current_folder (chooser_entry);
|
||||
file_part = _gtk_file_chooser_entry_get_file_part (chooser_entry);
|
||||
|
||||
if (!file_part || file_part[0] == '\0')
|
||||
{
|
||||
*is_valid = FALSE;
|
||||
*is_empty = TRUE;
|
||||
@@ -4073,11 +4250,11 @@ check_save_entry (GtkFileChooserDefault *impl,
|
||||
*is_empty = FALSE;
|
||||
|
||||
error = NULL;
|
||||
path = gtk_file_system_make_path (impl->file_system, impl->current_folder, filename, &error);
|
||||
path = gtk_file_system_make_path (impl->file_system, current_folder, file_part, &error);
|
||||
|
||||
if (!path)
|
||||
{
|
||||
error_building_filename_dialog (impl, impl->current_folder, filename, error);
|
||||
error_building_filename_dialog (impl, current_folder, file_part, error);
|
||||
*is_valid = FALSE;
|
||||
return NULL;
|
||||
}
|
||||
@@ -4493,9 +4670,6 @@ switch_to_selected_folder (GtkFileChooserDefault *impl)
|
||||
GtkTreeSelection *selection;
|
||||
struct switch_folder_closure closure;
|
||||
|
||||
g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
|
||||
|| impl->action == GTK_FILE_CHOOSER_ACTION_SAVE);
|
||||
|
||||
/* We do this with foreach() rather than get_selected() as we may be in
|
||||
* multiple selection mode
|
||||
*/
|
||||
@@ -4517,68 +4691,92 @@ static gboolean
|
||||
gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed)
|
||||
{
|
||||
GtkFileChooserDefault *impl;
|
||||
GtkTreeSelection *selection;
|
||||
int num_selected;
|
||||
GtkWidget *toplevel;
|
||||
GtkWidget *current_focus;
|
||||
|
||||
impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed);
|
||||
|
||||
/* First, check the save entry. If it has a valid name, we are done */
|
||||
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (impl));
|
||||
g_assert (GTK_IS_WINDOW (toplevel));
|
||||
|
||||
if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
|
||||
|| impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
|
||||
{
|
||||
GtkFilePath *path;
|
||||
gboolean is_valid, is_empty;
|
||||
|
||||
path = check_save_entry (impl, &is_valid, &is_empty);
|
||||
|
||||
if (is_valid)
|
||||
{
|
||||
gtk_file_path_free (path);
|
||||
return TRUE;
|
||||
}
|
||||
else if (!is_empty)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Second, do we have an empty selection */
|
||||
if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
|
||||
|| impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
|
||||
{
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
|
||||
num_selected = gtk_tree_selection_count_selected_rows (selection);
|
||||
if (num_selected == 0)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Third, should we return file names or folder names? */
|
||||
|
||||
if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
|
||||
|| impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
|
||||
current_focus = gtk_window_get_focus (GTK_WINDOW (toplevel));
|
||||
g_assert (current_focus != NULL);
|
||||
|
||||
if (current_focus == impl->browse_files_tree_view)
|
||||
{
|
||||
int num_selected;
|
||||
gboolean all_files, all_folders;
|
||||
|
||||
selection_check (impl, NULL, &all_files, &all_folders);
|
||||
file_list:
|
||||
|
||||
if (num_selected == 1)
|
||||
selection_check (impl, &num_selected, &all_files, &all_folders);
|
||||
|
||||
if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER && num_selected != 1)
|
||||
return TRUE; /* zero means current folder; more than one means use the whole selection */
|
||||
|
||||
if (num_selected == 0)
|
||||
{
|
||||
if (all_folders)
|
||||
{
|
||||
switch_to_selected_folder (impl);
|
||||
return FALSE;
|
||||
}
|
||||
else if (all_files)
|
||||
return TRUE;
|
||||
if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
|
||||
|| impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
|
||||
goto save_entry; /* it makes sense to use the typed name */
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (num_selected == 1 && all_folders)
|
||||
{
|
||||
switch_to_selected_folder (impl);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
return all_files;
|
||||
}
|
||||
else if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
|
||||
|| impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
|
||||
/* There can be no files selected in folder mode since we don't show them,
|
||||
* anyway.
|
||||
*/
|
||||
return TRUE;
|
||||
else if (current_focus == impl->save_file_name_entry)
|
||||
{
|
||||
GtkFilePath *path;
|
||||
gboolean is_valid, is_empty;
|
||||
gboolean is_folder;
|
||||
gboolean retval;
|
||||
|
||||
save_entry:
|
||||
|
||||
g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
|
||||
|| impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
|
||||
|
||||
path = check_save_entry (impl, &is_valid, &is_empty);
|
||||
|
||||
if (!is_valid)
|
||||
return FALSE;
|
||||
|
||||
is_folder = check_is_folder (impl->file_system, path, NULL);
|
||||
if (is_folder)
|
||||
{
|
||||
change_folder_and_display_error (impl, path);
|
||||
retval = FALSE;
|
||||
}
|
||||
else
|
||||
retval = TRUE;
|
||||
|
||||
gtk_file_path_free (path);
|
||||
return retval;
|
||||
}
|
||||
else if (impl->toplevel_last_focus_widget == impl->browse_shortcuts_tree_view)
|
||||
{
|
||||
/* The focus is on a dialog's action area button, *and* the widget that
|
||||
* was focused immediately before it is the shortcuts list. Switch to the
|
||||
* selected shortcut and tell the caller not to respond.
|
||||
*/
|
||||
GtkTreeIter iter;
|
||||
|
||||
if (shortcuts_get_selected (impl, &iter))
|
||||
shortcuts_activate_iter (impl, &iter);
|
||||
else
|
||||
goto file_list;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
goto file_list; /* The focus is on a dialog's action area button or something else */
|
||||
|
||||
g_assert_not_reached ();
|
||||
return FALSE;
|
||||
@@ -4643,7 +4841,8 @@ set_current_filter (GtkFileChooserDefault *impl,
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (impl->filter_combo),
|
||||
filter_index);
|
||||
|
||||
install_list_model_filter (impl);
|
||||
if (impl->browse_files_model)
|
||||
install_list_model_filter (impl);
|
||||
|
||||
g_object_notify (G_OBJECT (impl), "filter");
|
||||
}
|
||||
@@ -4667,7 +4866,7 @@ check_preview_change (GtkFileChooserDefault *impl)
|
||||
const GtkFileInfo *new_info;
|
||||
|
||||
gtk_tree_view_get_cursor (GTK_TREE_VIEW (impl->browse_files_tree_view), &cursor_path, NULL);
|
||||
if (cursor_path)
|
||||
if (cursor_path && impl->sort_model)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreeIter child_iter;
|
||||
@@ -4723,12 +4922,22 @@ shortcuts_activate_volume (GtkFileChooserDefault *impl,
|
||||
{
|
||||
GtkFilePath *path;
|
||||
|
||||
/* We ref the file chooser since volume_mount() may run a main loop, and the
|
||||
* user could close the file chooser window in the meantime.
|
||||
*/
|
||||
g_object_ref (impl);
|
||||
|
||||
if (!gtk_file_system_volume_get_is_mounted (impl->file_system, volume))
|
||||
{
|
||||
GError *error;
|
||||
gboolean result;
|
||||
|
||||
set_busy_cursor (impl, TRUE);
|
||||
|
||||
error = NULL;
|
||||
if (!gtk_file_system_volume_mount (impl->file_system, volume, &error))
|
||||
result = gtk_file_system_volume_mount (impl->file_system, volume, &error);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
char *msg;
|
||||
|
||||
@@ -4738,39 +4947,44 @@ shortcuts_activate_volume (GtkFileChooserDefault *impl,
|
||||
error_message (impl, msg);
|
||||
g_free (msg);
|
||||
g_error_free (error);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
set_busy_cursor (impl, FALSE);
|
||||
|
||||
if (!result)
|
||||
goto out;
|
||||
}
|
||||
|
||||
path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
|
||||
change_folder_and_display_error (impl, path);
|
||||
gtk_file_path_free (path);
|
||||
|
||||
out:
|
||||
|
||||
g_object_unref (impl);
|
||||
}
|
||||
|
||||
/* Opens the folder or volume at the specified index in the shortcuts list */
|
||||
/* Opens the folder or volume at the specified iter in the shortcuts model */
|
||||
static void
|
||||
shortcuts_activate_item (GtkFileChooserDefault *impl,
|
||||
int item_num)
|
||||
shortcuts_activate_iter (GtkFileChooserDefault *impl,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
GtkTreePath *path;
|
||||
gboolean result;
|
||||
GtkTreeIter iter;
|
||||
int item_num;
|
||||
gpointer data;
|
||||
int start_row;
|
||||
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), iter);
|
||||
g_assert (path != NULL);
|
||||
|
||||
item_num = *gtk_tree_path_get_indices (path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
if (item_num == shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS_SEPARATOR)
|
||||
|| item_num == shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR))
|
||||
return;
|
||||
|
||||
path = gtk_tree_path_new_from_indices (item_num, -1);
|
||||
result = gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->shortcuts_model), &iter, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
if (!result)
|
||||
return;
|
||||
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter, SHORTCUTS_COL_PATH, &data, -1);
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), iter, SHORTCUTS_COL_PATH, &data, -1);
|
||||
|
||||
start_row = shortcuts_get_index (impl, SHORTCUTS_VOLUMES);
|
||||
if ((item_num >= start_row && item_num < start_row + impl->num_volumes)
|
||||
@@ -4797,10 +5011,8 @@ shortcuts_row_activated_cb (GtkTreeView *tree_view,
|
||||
GtkTreeViewColumn *column,
|
||||
GtkFileChooserDefault *impl)
|
||||
{
|
||||
int selected;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeIter child_iter;
|
||||
GtkTreePath *child_path;
|
||||
|
||||
if (!gtk_tree_model_get_iter (impl->shortcuts_filter_model, &iter, path))
|
||||
return;
|
||||
@@ -4808,14 +5020,7 @@ shortcuts_row_activated_cb (GtkTreeView *tree_view,
|
||||
gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_filter_model),
|
||||
&child_iter,
|
||||
&iter);
|
||||
child_path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &child_iter);
|
||||
if (!child_path)
|
||||
return;
|
||||
|
||||
selected = *gtk_tree_path_get_indices (child_path);
|
||||
gtk_tree_path_free (child_path);
|
||||
|
||||
shortcuts_activate_item (impl, selected);
|
||||
shortcuts_activate_iter (impl, &child_iter);
|
||||
}
|
||||
|
||||
/* Handler for GtkWidget::key-press-event on the shortcuts list */
|
||||
@@ -5281,7 +5486,8 @@ location_popup_handler (GtkFileChooserDefault *impl)
|
||||
GtkWidget *label;
|
||||
GtkWidget *entry;
|
||||
gboolean refocus;
|
||||
char *title;
|
||||
const char *title;
|
||||
const char *accept_stock;
|
||||
|
||||
/* Create dialog */
|
||||
|
||||
@@ -5291,19 +5497,21 @@ location_popup_handler (GtkFileChooserDefault *impl)
|
||||
|| impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
|
||||
{
|
||||
title = _("Open Location");
|
||||
accept_stock = GTK_STOCK_OPEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
|
||||
|| impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
|
||||
title = _("Save in Location");
|
||||
accept_stock = GTK_STOCK_SAVE;
|
||||
}
|
||||
|
||||
dialog = gtk_dialog_new_with_buttons (title,
|
||||
toplevel,
|
||||
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||
accept_stock, GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
gtk_window_set_default_size (GTK_WINDOW (dialog), 300, -1);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
|
||||
|
||||
@@ -841,6 +841,7 @@ _gtk_file_chooser_entry_set_base_folder (GtkFileChooserEntry *chooser_entry,
|
||||
|
||||
chooser_entry->base_folder = gtk_file_path_copy (path);
|
||||
|
||||
gtk_file_chooser_entry_changed (GTK_EDITABLE (chooser_entry));
|
||||
gtk_editable_select_region (GTK_EDITABLE (chooser_entry), 0, -1);
|
||||
}
|
||||
|
||||
|
||||
@@ -145,8 +145,8 @@ _gtk_file_chooser_delegate_iface_init (GtkFileChooserIface *iface)
|
||||
|
||||
/**
|
||||
* _gtk_file_chooser_set_delegate:
|
||||
* @receiver: a GOobject implementing #GtkFileChooser
|
||||
* @delegate: another GObject implementing #GtkFileChooser
|
||||
* @receiver: a #GObject implementing #GtkFileChooser
|
||||
* @delegate: another #GObject implementing #GtkFileChooser
|
||||
*
|
||||
* Establishes that calls on @receiver for #GtkFileChooser
|
||||
* methods should be delegated to @delegate, and that
|
||||
@@ -162,7 +162,6 @@ _gtk_file_chooser_set_delegate (GtkFileChooser *receiver,
|
||||
g_return_if_fail (GTK_IS_FILE_CHOOSER (delegate));
|
||||
|
||||
g_object_set_data (G_OBJECT (receiver), "gtk-file-chooser-delegate", delegate);
|
||||
|
||||
g_signal_connect (delegate, "notify",
|
||||
G_CALLBACK (delegate_notify), receiver);
|
||||
g_signal_connect (delegate, "current-folder-changed",
|
||||
@@ -294,11 +293,12 @@ delegate_notify (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
gpointer data)
|
||||
{
|
||||
if (pspec->param_id >= GTK_FILE_CHOOSER_PROP_FIRST &&
|
||||
pspec->param_id <= GTK_FILE_CHOOSER_PROP_LAST)
|
||||
{
|
||||
g_object_notify (data, pspec->name);
|
||||
}
|
||||
gpointer iface;
|
||||
|
||||
iface = g_type_interface_peek (g_type_class_peek (G_OBJECT_TYPE (object)),
|
||||
gtk_file_chooser_get_type ());
|
||||
if (g_object_interface_find_property (iface, pspec->name))
|
||||
g_object_notify (data, pspec->name);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user