summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas James Alexander Thurman <tthurman@src.gnome.org>2009-01-22 05:14:00 +0000
committerThomas James Alexander Thurman <tthurman@src.gnome.org>2009-01-22 05:14:00 +0000
commit3945cdefdaad26979226be0940a7758fad41874e (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /src
parent1b35154e2baec3f0a6854a2f5538444bcebac1d0 (diff)
downloadmetacity-git-migration-mbus.tar.gz
svn path=/tags/git-migration-mbus; revision=4083
Diffstat (limited to 'src')
-rw-r--r--src/.cvsignore15
-rw-r--r--src/50-metacity-desktop-key.xml.in20
-rw-r--r--src/50-metacity-key.xml.in269
-rw-r--r--src/Makefile.am221
-rw-r--r--src/compositor/compositor-private.h54
-rw-r--r--src/compositor/compositor-xrender.c3078
-rw-r--r--src/compositor/compositor-xrender.h31
-rw-r--r--src/compositor/compositor.c159
-rw-r--r--src/core/async-getprop.c680
-rw-r--r--src/core/async-getprop.h67
-rw-r--r--src/core/atomnames.h166
-rw-r--r--src/core/bell.c363
-rw-r--r--src/core/bell.h108
-rw-r--r--src/core/boxes.c1926
-rw-r--r--src/core/constraints.c1372
-rw-r--r--src/core/constraints.h48
-rw-r--r--src/core/core.c776
-rw-r--r--src/core/delete.c505
-rw-r--r--src/core/display-private.h500
-rw-r--r--src/core/display.c5189
-rw-r--r--src/core/edge-resistance.c1277
-rw-r--r--src/core/edge-resistance.h48
-rw-r--r--src/core/effects.c735
-rw-r--r--src/core/effects.h170
-rw-r--r--src/core/errors.c288
-rw-r--r--src/core/eventqueue.c184
-rw-r--r--src/core/eventqueue.h40
-rw-r--r--src/core/frame-private.h88
-rw-r--r--src/core/frame.c420
-rw-r--r--src/core/group-private.h43
-rw-r--r--src/core/group-props.c234
-rw-r--r--src/core/group-props.h37
-rw-r--r--src/core/group.c274
-rw-r--r--src/core/group.h53
-rw-r--r--src/core/iconcache.c849
-rw-r--r--src/core/iconcache.h79
-rw-r--r--src/core/keybindings.c3350
-rw-r--r--src/core/keybindings.h60
-rw-r--r--src/core/main.c620
-rw-r--r--src/core/metacity-Xatomtype.h136
-rw-r--r--src/core/place.c932
-rw-r--r--src/core/place.h37
-rw-r--r--src/core/prefs.c2776
-rw-r--r--src/core/schema-bindings.c191
-rw-r--r--src/core/screen-private.h225
-rw-r--r--src/core/screen.c2802
-rw-r--r--src/core/session.c1900
-rw-r--r--src/core/session.h91
-rw-r--r--src/core/stack.c1661
-rw-r--r--src/core/stack.h402
-rw-r--r--src/core/testasyncgetprop.c497
-rw-r--r--src/core/testboxes.c1416
-rw-r--r--src/core/util.c611
-rw-r--r--src/core/window-private.h632
-rw-r--r--src/core/window-props.c1636
-rw-r--r--src/core/window-props.h125
-rw-r--r--src/core/window.c8262
-rw-r--r--src/core/workspace.c976
-rw-r--r--src/core/workspace.h113
-rw-r--r--src/core/xprops.c1238
-rw-r--r--src/default_icon.pngbin1184 -> 0 bytes
-rw-r--r--src/include/all-keybindings.h386
-rw-r--r--src/include/boxes.h290
-rw-r--r--src/include/common.h292
-rw-r--r--src/include/compositor.h76
-rw-r--r--src/include/core.h208
-rw-r--r--src/include/display.h48
-rw-r--r--src/include/errors.h51
-rw-r--r--src/include/frame.h31
-rw-r--r--src/include/main.h43
-rw-r--r--src/include/prefs.h226
-rw-r--r--src/include/resizepopup.h47
-rw-r--r--src/include/screen.h48
-rw-r--r--src/include/tabpopup.h67
-rw-r--r--src/include/types.h31
-rw-r--r--src/include/ui.h209
-rw-r--r--src/include/util.h132
-rw-r--r--src/include/window.h39
-rw-r--r--src/include/xprops.h227
-rw-r--r--src/libmetacity-private.pc.in12
-rw-r--r--src/metacity-wm.desktop.in21
-rw-r--r--src/metacity.desktop.in18
-rw-r--r--src/metacity.schemas.in.in554
-rwxr-xr-xsrc/run-metacity.sh109
-rw-r--r--src/stock_delete.pngbin220 -> 0 bytes
-rw-r--r--src/stock_maximize.pngbin166 -> 0 bytes
-rw-r--r--src/stock_minimize.pngbin145 -> 0 bytes
-rw-r--r--src/themes/.cvsignore2
-rw-r--r--src/themes/AgingGorilla/README7
-rw-r--r--src/themes/AgingGorilla/active-button.pngbin844 -> 0 bytes
-rw-r--r--src/themes/AgingGorilla/active-close-button.pngbin896 -> 0 bytes
-rw-r--r--src/themes/AgingGorilla/active-close-menu-icon.pngbin258 -> 0 bytes
-rw-r--r--src/themes/AgingGorilla/active-maximize-button.pngbin886 -> 0 bytes
-rw-r--r--src/themes/AgingGorilla/active-maximize-menu-icon.pngbin284 -> 0 bytes
-rw-r--r--src/themes/AgingGorilla/active-menu-button.pngbin873 -> 0 bytes
-rw-r--r--src/themes/AgingGorilla/active-minimize-button.pngbin914 -> 0 bytes
-rw-r--r--src/themes/AgingGorilla/active-minimize-menu-icon.pngbin332 -> 0 bytes
-rw-r--r--src/themes/AgingGorilla/gorilla.xcf.bz2bin11040 -> 0 bytes
-rw-r--r--src/themes/AgingGorilla/inactive-close-button.pngbin919 -> 0 bytes
-rw-r--r--src/themes/AgingGorilla/inactive-maximize-button.pngbin903 -> 0 bytes
-rw-r--r--src/themes/AgingGorilla/inactive-menu-button.pngbin900 -> 0 bytes
-rw-r--r--src/themes/AgingGorilla/inactive-minimize-button.pngbin927 -> 0 bytes
-rw-r--r--src/themes/AgingGorilla/metacity-theme-1.xml291
-rw-r--r--src/themes/Atlanta/metacity-theme-1.xml350
-rw-r--r--src/themes/Bright/metacity-theme-1.xml376
-rw-r--r--src/themes/Bright/metacity-theme-2.xml546
-rw-r--r--src/themes/Crux/active-above-button.pngbin197 -> 0 bytes
-rw-r--r--src/themes/Crux/active-border-top-left-border.pngbin147 -> 0 bytes
-rw-r--r--src/themes/Crux/active-border-top-right-border.pngbin147 -> 0 bytes
-rw-r--r--src/themes/Crux/active-bottom-left-border.pngbin154 -> 0 bytes
-rw-r--r--src/themes/Crux/active-bottom-left-corner.pngbin166 -> 0 bytes
-rw-r--r--src/themes/Crux/active-bottom-mid-left-border.pngbin171 -> 0 bytes
-rw-r--r--src/themes/Crux/active-bottom-mid-right-border.pngbin276 -> 0 bytes
-rw-r--r--src/themes/Crux/active-bottom-right-border.pngbin154 -> 0 bytes
-rw-r--r--src/themes/Crux/active-bottom-right-corner.pngbin171 -> 0 bytes
-rw-r--r--src/themes/Crux/active-button-prelight.pngbin385 -> 0 bytes
-rw-r--r--src/themes/Crux/active-button-pressed.pngbin391 -> 0 bytes
-rw-r--r--src/themes/Crux/active-button.pngbin396 -> 0 bytes
-rw-r--r--src/themes/Crux/active-close-button.pngbin341 -> 0 bytes
-rw-r--r--src/themes/Crux/active-left-border.pngbin138 -> 0 bytes
-rw-r--r--src/themes/Crux/active-left-top-border-shaded.pngbin160 -> 0 bytes
-rw-r--r--src/themes/Crux/active-left-top-border.pngbin224 -> 0 bytes
-rw-r--r--src/themes/Crux/active-maximize-button.pngbin184 -> 0 bytes
-rw-r--r--src/themes/Crux/active-menu-button-prelight.pngbin455 -> 0 bytes
-rw-r--r--src/themes/Crux/active-menu-button-pressed.pngbin424 -> 0 bytes
-rw-r--r--src/themes/Crux/active-menu-button.pngbin436 -> 0 bytes
-rw-r--r--src/themes/Crux/active-minimize-button.pngbin257 -> 0 bytes
-rw-r--r--src/themes/Crux/active-restore-button.pngbin171 -> 0 bytes
-rw-r--r--src/themes/Crux/active-right-border.pngbin136 -> 0 bytes
-rw-r--r--src/themes/Crux/active-right-top-border-shaded.pngbin274 -> 0 bytes
-rw-r--r--src/themes/Crux/active-right-top-border.pngbin282 -> 0 bytes
-rw-r--r--src/themes/Crux/active-shade-button.pngbin296 -> 0 bytes
-rw-r--r--src/themes/Crux/active-stick-button.pngbin249 -> 0 bytes
-rw-r--r--src/themes/Crux/active-top-center-left.pngbin238 -> 0 bytes
-rw-r--r--src/themes/Crux/active-top-center-mid-left.pngbin902 -> 0 bytes
-rw-r--r--src/themes/Crux/active-top-center-mid-right.pngbin1083 -> 0 bytes
-rw-r--r--src/themes/Crux/active-top-center-right.pngbin312 -> 0 bytes
-rw-r--r--src/themes/Crux/active-top-left-border.pngbin168 -> 0 bytes
-rw-r--r--src/themes/Crux/active-top-left-corner.pngbin162 -> 0 bytes
-rw-r--r--src/themes/Crux/active-top-mid-left-border.pngbin210 -> 0 bytes
-rw-r--r--src/themes/Crux/active-top-mid-right-border.pngbin276 -> 0 bytes
-rw-r--r--src/themes/Crux/active-top-right-border.pngbin170 -> 0 bytes
-rw-r--r--src/themes/Crux/active-top-right-corner.pngbin171 -> 0 bytes
-rw-r--r--src/themes/Crux/active-unabove-button.pngbin205 -> 0 bytes
-rw-r--r--src/themes/Crux/active-unshade-button.pngbin261 -> 0 bytes
-rw-r--r--src/themes/Crux/active-unstick-button.pngbin248 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-above-button.pngbin205 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-border-top-left-border.pngbin153 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-border-top-right-border.pngbin154 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-bottom-left-border.pngbin158 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-bottom-left-corner.pngbin176 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-bottom-mid-border.pngbin254 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-bottom-right-border.pngbin148 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-bottom-right-corner.pngbin188 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-button-prelight.pngbin357 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-button-pressed.pngbin379 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-button.pngbin390 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-close-button.pngbin211 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-left-border.pngbin137 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-left-top-border-shaded.pngbin212 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-left-top-border.pngbin264 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-maximize-button.pngbin264 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-menu-button-prelight.pngbin410 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-menu-button-pressed.pngbin375 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-menu-button.pngbin374 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-minimize-button.pngbin255 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-restore-button.pngbin249 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-right-border.pngbin140 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-right-top-border-shaded.pngbin267 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-right-top-border.pngbin262 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-shade-button.pngbin213 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-stick-button.pngbin200 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-top-center-left.pngbin232 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-top-center-mid.pngbin981 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-top-center-right.pngbin238 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-top-left-border.pngbin157 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-top-left-corner.pngbin163 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-top-mid-border.pngbin252 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-top-right-border.pngbin159 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-top-right-corner.pngbin176 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-unabove-button.pngbin212 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-unshade-button.pngbin204 -> 0 bytes
-rw-r--r--src/themes/Crux/inactive-unstick-button.pngbin190 -> 0 bytes
-rw-r--r--src/themes/Crux/metacity-theme-1.xml579
-rw-r--r--src/themes/Crux/metacity-theme-2.xml832
-rw-r--r--src/themes/Esco/metacity-theme-1.xml990
-rw-r--r--src/themes/Gorilla/README7
-rw-r--r--src/themes/Gorilla/active-button.pngbin844 -> 0 bytes
-rw-r--r--src/themes/Gorilla/active-close-button.pngbin896 -> 0 bytes
-rw-r--r--src/themes/Gorilla/active-close-menu-icon.pngbin258 -> 0 bytes
-rw-r--r--src/themes/Gorilla/active-maximize-button.pngbin886 -> 0 bytes
-rw-r--r--src/themes/Gorilla/active-maximize-menu-icon.pngbin284 -> 0 bytes
-rw-r--r--src/themes/Gorilla/active-menu-button.pngbin873 -> 0 bytes
-rw-r--r--src/themes/Gorilla/active-minimize-button.pngbin914 -> 0 bytes
-rw-r--r--src/themes/Gorilla/active-minimize-menu-icon.pngbin332 -> 0 bytes
-rw-r--r--src/themes/Gorilla/gorilla.xcf.bz2bin11040 -> 0 bytes
-rw-r--r--src/themes/Gorilla/inactive-close-button.pngbin919 -> 0 bytes
-rw-r--r--src/themes/Gorilla/inactive-maximize-button.pngbin903 -> 0 bytes
-rw-r--r--src/themes/Gorilla/inactive-menu-button.pngbin900 -> 0 bytes
-rw-r--r--src/themes/Gorilla/inactive-minimize-button.pngbin927 -> 0 bytes
-rw-r--r--src/themes/Gorilla/metacity-theme-1.xml260
-rw-r--r--src/themes/Makefile.am50
-rw-r--r--src/themes/Metabox/metacity-theme-1.xml479
-rw-r--r--src/themes/Simple/close.pngbin333 -> 0 bytes
-rw-r--r--src/themes/Simple/maximize.pngbin291 -> 0 bytes
-rw-r--r--src/themes/Simple/maximized.pngbin340 -> 0 bytes
-rw-r--r--src/themes/Simple/metacity-theme-1.xml346
-rw-r--r--src/themes/Simple/minimize.pngbin199 -> 0 bytes
-rw-r--r--src/tools/.cvsignore8
-rw-r--r--src/tools/Makefile.am33
-rw-r--r--src/tools/metacity-grayscale.c109
-rw-r--r--src/tools/metacity-mag.c285
-rw-r--r--src/tools/metacity-message.c187
-rw-r--r--src/tools/metacity-window-demo.c997
-rw-r--r--src/tools/metacity-window-demo.pngbin3453 -> 0 bytes
-rw-r--r--src/ui/draw-workspace.c232
-rw-r--r--src/ui/draw-workspace.h61
-rw-r--r--src/ui/fixedtip.c131
-rw-r--r--src/ui/fixedtip.h69
-rw-r--r--src/ui/frames.c2848
-rw-r--r--src/ui/frames.h162
-rw-r--r--src/ui/gradient.c842
-rw-r--r--src/ui/gradient.h65
-rw-r--r--src/ui/menu.c532
-rw-r--r--src/ui/menu.h62
-rw-r--r--src/ui/metaaccellabel.c456
-rw-r--r--src/ui/metaaccellabel.h106
-rw-r--r--src/ui/metacity-dialog.c438
-rw-r--r--src/ui/preview-widget.c593
-rw-r--r--src/ui/preview-widget.h87
-rw-r--r--src/ui/resizepopup.c217
-rw-r--r--src/ui/tabpopup.c948
-rw-r--r--src/ui/testgradient.c348
-rw-r--r--src/ui/theme-parser.c4090
-rw-r--r--src/ui/theme-parser.h32
-rw-r--r--src/ui/theme-viewer.c1336
-rw-r--r--src/ui/theme.c6480
-rw-r--r--src/ui/theme.h1139
-rw-r--r--src/ui/themewidget.c183
-rw-r--r--src/ui/themewidget.h78
-rw-r--r--src/ui/ui.c999
-rw-r--r--src/wm-tester/.cvsignore7
-rw-r--r--src/wm-tester/Makefile.am25
-rw-r--r--src/wm-tester/focus-window.c37
-rw-r--r--src/wm-tester/main.c245
-rw-r--r--src/wm-tester/test-gravity.c308
-rw-r--r--src/wm-tester/test-resizing.c257
-rw-r--r--src/wm-tester/test-size-hints.c136
248 files changed, 0 insertions, 84503 deletions
diff --git a/src/.cvsignore b/src/.cvsignore
deleted file mode 100644
index f62415b3..00000000
--- a/src/.cvsignore
+++ /dev/null
@@ -1,15 +0,0 @@
-.libs
-Makefile.in
-Makefile
-.deps
-metacity
-metacity-theme-viewer
-metacity-dialog
-testboxes
-testgradient
-inlinepixbufs.h
-metacity.desktop
-metacity-wm.desktop
-metacity.schemas
-libmetacity-private.pc
-testasyncgetprop
diff --git a/src/50-metacity-desktop-key.xml.in b/src/50-metacity-desktop-key.xml.in
deleted file mode 100644
index dbd5d75a..00000000
--- a/src/50-metacity-desktop-key.xml.in
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<KeyListEntries _name="Desktop" wm_name="Metacity" package="metacity">
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/panel_run_dialog" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/panel_main_menu" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/run_command_screenshot" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/run_command_window_screenshot" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/run_command_terminal" />
-
-</KeyListEntries>
-
diff --git a/src/50-metacity-key.xml.in b/src/50-metacity-key.xml.in
deleted file mode 100644
index d6113a29..00000000
--- a/src/50-metacity-key.xml.in
+++ /dev/null
@@ -1,269 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<KeyListEntries _name="Window Management" wm_name="Metacity" package="metacity">
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/activate_window_menu" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/toggle_fullscreen" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/toggle_maximized" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/maximize" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/unmaximize" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/toggle_shaded" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/close" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/minimize" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/begin_move" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/begin_resize" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/toggle_on_all_workspaces"
- value="1"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/raise_or_lower" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/raise" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/lower" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/maximize_vertically" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/maximize_horizontally" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/move_to_workspace_1"
- value="1"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/move_to_workspace_2"
- value="1"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/move_to_workspace_3"
- value="2"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/move_to_workspace_4"
- value="3"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/move_to_workspace_5"
- value="4"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/move_to_workspace_6"
- value="5"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/move_to_workspace_7"
- value="6"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/move_to_workspace_8"
- value="7"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/move_to_workspace_9"
- value="8"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/move_to_workspace_10"
- value="9"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/move_to_workspace_11"
- value="10"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/move_to_workspace_12"
- value="11"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/move_to_workspace_left"
- value="1"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/move_to_workspace_right"
- value="1"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/move_to_workspace_up"
- value="1"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/window_keybindings/move_to_workspace_down"
- value="1"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/switch_windows" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/switch_group" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/switch_panels" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/cycle_windows" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/cycle_group" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/cycle_panels" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/show_desktop" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/switch_to_workspace_1"
- value="1"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/switch_to_workspace_2"
- value="1"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/switch_to_workspace_3"
- value="2"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/switch_to_workspace_4"
- value="3"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/switch_to_workspace_5"
- value="4"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/switch_to_workspace_6"
- value="5"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/switch_to_workspace_7"
- value="6"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/switch_to_workspace_8"
- value="7"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/switch_to_workspace_9"
- value="8"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/switch_to_workspace_10"
- value="9"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/switch_to_workspace_11"
- value="10"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/switch_to_workspace_12"
- value="11"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/switch_to_workspace_left"
- value="1"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/switch_to_workspace_right"
- value="1"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/switch_to_workspace_up"
- value="1"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
- <KeyListEntry
- name="/apps/metacity/global_keybindings/switch_to_workspace_down"
- value="1"
- key="/apps/metacity/general/num_workspaces"
- comparison="gt" />
-
-</KeyListEntries>
-
diff --git a/src/Makefile.am b/src/Makefile.am
deleted file mode 100644
index 4c9e39cc..00000000
--- a/src/Makefile.am
+++ /dev/null
@@ -1,221 +0,0 @@
-lib_LTLIBRARIES = libmetacity-private.la
-
-SUBDIRS=wm-tester tools themes
-
-INCLUDES=-I$(srcdir)/include -DMETACITY_LIBEXECDIR=\"$(libexecdir)\" -DHOST_ALIAS=\"@HOST_ALIAS@\" -DMETACITY_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" -DMETACITY_PKGDATADIR=\"$(pkgdatadir)\" -DMETACITY_DATADIR=\"$(datadir)\" -DG_LOG_DOMAIN=\"metacity\" -DSN_API_NOT_YET_FROZEN=1 @METACITY_CFLAGS@
-
-metacity_SOURCES= \
- core/async-getprop.c \
- core/async-getprop.h \
- core/atomnames.h \
- core/bell.c \
- core/bell.h \
- core/boxes.c \
- include/boxes.h \
- compositor/compositor.c \
- compositor/compositor-private.h \
- compositor/compositor-xrender.c \
- compositor/compositor-xrender.h \
- include/compositor.h \
- core/constraints.c \
- core/constraints.h \
- core/core.c \
- core/delete.c \
- core/display.c \
- core/display-private.h \
- include/display.h \
- ui/draw-workspace.c \
- ui/draw-workspace.h \
- core/edge-resistance.c \
- core/edge-resistance.h \
- core/effects.c \
- core/effects.h \
- core/errors.c \
- include/errors.h \
- core/eventqueue.c \
- core/eventqueue.h \
- core/frame.c \
- core/frame-private.h \
- include/frame.h \
- ui/gradient.c \
- ui/gradient.h \
- core/group-private.h \
- core/group-props.c \
- core/group-props.h \
- core/group.c \
- core/group.h \
- core/iconcache.c \
- core/iconcache.h \
- core/keybindings.c \
- core/keybindings.h \
- core/main.c \
- include/main.h \
- core/metacity-Xatomtype.h \
- core/place.c \
- core/place.h \
- core/prefs.c \
- include/prefs.h \
- core/screen.c \
- core/screen-private.h \
- include/screen.h \
- include/types.h \
- core/session.c \
- core/session.h \
- core/stack.c \
- core/stack.h \
- core/util.c \
- include/util.h \
- core/window-props.c \
- core/window-props.h \
- core/window.c \
- core/window-private.h \
- include/window.h \
- core/workspace.c \
- core/workspace.h \
- core/xprops.c \
- include/xprops.h \
- include/common.h \
- include/core.h \
- include/ui.h \
- inlinepixbufs.h \
- ui/fixedtip.c \
- ui/fixedtip.h \
- ui/frames.c \
- ui/frames.h \
- ui/menu.c \
- ui/menu.h \
- ui/metaaccellabel.c \
- ui/metaaccellabel.h \
- ui/resizepopup.c \
- include/resizepopup.h \
- ui/tabpopup.c \
- include/tabpopup.h \
- ui/theme-parser.c \
- ui/theme-parser.h \
- ui/theme.c \
- ui/theme.h \
- ui/themewidget.c \
- ui/themewidget.h \
- ui/ui.c \
- include/all-keybindings.h
-
-# by setting libmetacity_private_la_CFLAGS, the files shared with
-# metacity proper will be compiled with different names.
-libmetacity_private_la_CFLAGS =
-libmetacity_private_la_SOURCES= \
- core/boxes.c \
- include/boxes.h \
- ui/gradient.c \
- ui/gradient.h \
- core/util.c \
- include/util.h \
- include/common.h \
- ui/preview-widget.c \
- ui/preview-widget.h \
- ui/theme-parser.c \
- ui/theme-parser.h \
- ui/theme.c \
- ui/theme.h
-
-libmetacity_private_la_LDFLAGS = -no-undefined
-libmetacity_private_la_LIBADD = @METACITY_LIBS@
-
-libmetacityincludedir = $(includedir)/metacity-1/metacity-private
-
-libmetacityinclude_HEADERS = \
- include/boxes.h \
- ui/gradient.h \
- include/util.h \
- include/common.h \
- ui/preview-widget.h \
- ui/theme-parser.h \
- ui/theme.h
-
-metacity_theme_viewer_SOURCES= \
- ui/theme-viewer.c
-
-metacity_dialog_SOURCES= \
- ui/metacity-dialog.c
-
-schema_bindings_SOURCES = \
- core/schema-bindings.c \
- metacity.schemas.in.in
-
-schema_bindings_LDADD = @METACITY_LIBS@
-metacity.schemas.in: schema_bindings ${srcdir}/metacity.schemas.in.in
- @echo Generating keybinding schemas... ${srcdir}/metacity.schemas.in.in
- ${builddir}/schema_bindings ${srcdir}/metacity.schemas.in.in ${builddir}/metacity.schemas.in
-
-bin_PROGRAMS=metacity metacity-theme-viewer
-libexec_PROGRAMS=metacity-dialog
-
-EFENCE=
-metacity_LDADD=@METACITY_LIBS@ $(EFENCE)
-metacity_theme_viewer_LDADD= @METACITY_LIBS@ libmetacity-private.la
-metacity_dialog_LDADD=@METACITY_LIBS@
-
-testboxes_SOURCES=include/util.h core/util.c include/boxes.h core/boxes.c core/testboxes.c
-testgradient_SOURCES=ui/gradient.h ui/gradient.c ui/testgradient.c
-testasyncgetprop_SOURCES=core/async-getprop.h core/async-getprop.c core/testasyncgetprop.c
-
-noinst_PROGRAMS=testboxes testgradient testasyncgetprop schema_bindings
-
-testboxes_LDADD= @METACITY_LIBS@
-testgradient_LDADD= @METACITY_LIBS@
-testasyncgetprop_LDADD= @METACITY_LIBS@
-
-@INTLTOOL_DESKTOP_RULE@
-
-desktopfilesdir=$(datadir)/applications
-desktopfiles_in_files=metacity.desktop.in
-desktopfiles_files=$(desktopfiles_in_files:.desktop.in=.desktop)
-desktopfiles_DATA = $(desktopfiles_files)
-
-wmpropertiesdir=$(datadir)/gnome/wm-properties
-wmproperties_in_files=metacity-wm.desktop.in
-wmproperties_files=$(wmproperties_in_files:.desktop.in=.desktop)
-wmproperties_DATA = $(wmproperties_files)
-
-schemadir = @GCONF_SCHEMA_FILE_DIR@
-schema_in_files = metacity.schemas.in
-schema_DATA = $(schema_in_files:.schemas.in=.schemas)
-
-@INTLTOOL_XML_NOMERGE_RULE@
-
-xmldir = @GNOME_KEYBINDINGS_KEYSDIR@
-xml_in_files = 50-metacity-desktop-key.xml.in 50-metacity-key.xml.in
-xml_DATA = $(xml_in_files:.xml.in=.xml)
-
-@INTLTOOL_SCHEMAS_RULE@
-
-if GCONF_SCHEMAS_INSTALL
-install-data-local:
- GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(schema_DATA)
-else
-install-data-local:
-endif
-
-IMAGES=stock_maximize.png stock_minimize.png stock_delete.png
-VARIABLES=stock_maximize_data $(srcdir)/stock_maximize.png \
- stock_minimize_data $(srcdir)/stock_minimize.png \
- stock_delete_data $(srcdir)/stock_delete.png
-
-BUILT_SOURCES = inlinepixbufs.h
-CLEANFILES = inlinepixbufs.h metacity.desktop metacity-wm.desktop metacity.schemas metacity.schemas.in 50-metacity-desktop-key.xml 50-metacity-key.xml
-
-inlinepixbufs.h: $(IMAGES)
- $(GDK_PIXBUF_CSOURCE) --raw --build-list $(VARIABLES) >$(srcdir)/inlinepixbufs.h
-
-pkgconfigdir = $(libdir)/pkgconfig
-
-pkgconfig_DATA = libmetacity-private.pc
-
-EXTRA_DIST=$(desktopfiles_files) \
- $(wmproperties_files) \
- $(IMAGES) $(schema_DATA) \
- $(desktopfiles_in_files) \
- $(wmproperties_in_files) \
- $(schema_in_files) \
- $(xml_in_files) \
- libmetacity-private.pc.in
-
diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h
deleted file mode 100644
index ef9f8023..00000000
--- a/src/compositor/compositor-private.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2008 Iain Holmes
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_COMPOSITOR_PRIVATE_H
-#define META_COMPOSITOR_PRIVATE_H
-
-#include "compositor.h"
-
-struct _MetaCompositor
-{
- void (* destroy) (MetaCompositor *compositor);
-
- void (*manage_screen) (MetaCompositor *compositor,
- MetaScreen *screen);
- void (*unmanage_screen) (MetaCompositor *compositor,
- MetaScreen *screen);
- void (*add_window) (MetaCompositor *compositor,
- MetaWindow *window,
- Window xwindow,
- XWindowAttributes *attrs);
- void (*remove_window) (MetaCompositor *compositor,
- Window xwindow);
- void (*set_updates) (MetaCompositor *compositor,
- MetaWindow *window,
- gboolean update);
- void (*process_event) (MetaCompositor *compositor,
- XEvent *event,
- MetaWindow *window);
- Pixmap (*get_window_pixmap) (MetaCompositor *compositor,
- MetaWindow *window);
- void (*set_active_window) (MetaCompositor *compositor,
- MetaScreen *screen,
- MetaWindow *window);
-};
-
-#endif
diff --git a/src/compositor/compositor-xrender.c b/src/compositor/compositor-xrender.c
deleted file mode 100644
index 8c06d1f7..00000000
--- a/src/compositor/compositor-xrender.c
+++ /dev/null
@@ -1,3078 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2007 Iain Holmes
- * Based on xcompmgr - (c) 2003 Keith Packard
- * xfwm4 - (c) 2005-2007 Olivier Fourdan
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#define _GNU_SOURCE
-#define _XOPEN_SOURCE 500 /* for usleep() */
-
-#include <config.h>
-
-#ifdef HAVE_COMPOSITE_EXTENSIONS
-
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <unistd.h>
-
-#include <gdk/gdk.h>
-
-#include "display.h"
-#include "screen.h"
-#include "frame.h"
-#include "errors.h"
-#include "window.h"
-#include "compositor-private.h"
-#include "compositor-xrender.h"
-#include "xprops.h"
-#include <X11/Xatom.h>
-#include <X11/extensions/shape.h>
-#include <X11/extensions/Xcomposite.h>
-#include <X11/extensions/Xdamage.h>
-#include <X11/extensions/Xfixes.h>
-#include <X11/extensions/Xrender.h>
-
-#if COMPOSITE_MAJOR > 0 || COMPOSITE_MINOR >= 2
-#define HAVE_NAME_WINDOW_PIXMAP 1
-#endif
-
-#if COMPOSITE_MAJOR > 0 || COMPOSITE_MINOR >= 3
-#define HAVE_COW 1
-#else
-/* Don't have a cow man...HAAHAAHAA */
-#endif
-
-#define USE_IDLE_REPAINT 1
-
-#ifdef HAVE_COMPOSITE_EXTENSIONS
-static inline gboolean
-composite_at_least_version (MetaDisplay *display,
- int maj, int min)
-{
- static int major = -1;
- static int minor = -1;
-
- if (major == -1)
- meta_display_get_compositor_version (display, &major, &minor);
-
- return (major > maj || (major == maj && minor >= min));
-}
-
-#define have_name_window_pixmap(display) \
- composite_at_least_version (display, 0, 2)
-#define have_cow(display) \
- composite_at_least_version (display, 0, 3)
-
-#endif
-
-typedef enum _MetaCompWindowType
-{
- META_COMP_WINDOW_NORMAL,
- META_COMP_WINDOW_DND,
- META_COMP_WINDOW_DESKTOP,
- META_COMP_WINDOW_DOCK,
- META_COMP_WINDOW_MENU,
- META_COMP_WINDOW_DROP_DOWN_MENU,
- META_COMP_WINDOW_TOOLTIP,
-} MetaCompWindowType;
-
-typedef enum _MetaShadowType
-{
- META_SHADOW_SMALL,
- META_SHADOW_MEDIUM,
- META_SHADOW_LARGE,
- LAST_SHADOW_TYPE
-} MetaShadowType;
-
-typedef struct _MetaCompositorXRender
-{
- MetaCompositor compositor;
-
- MetaDisplay *display;
-
- Atom atom_x_root_pixmap;
- Atom atom_x_set_root;
- Atom atom_net_wm_window_opacity;
- Atom atom_net_wm_window_type_dnd;
-
- Atom atom_net_wm_window_type;
- Atom atom_net_wm_window_type_desktop;
- Atom atom_net_wm_window_type_dock;
- Atom atom_net_wm_window_type_menu;
- Atom atom_net_wm_window_type_dialog;
- Atom atom_net_wm_window_type_normal;
- Atom atom_net_wm_window_type_utility;
- Atom atom_net_wm_window_type_splash;
- Atom atom_net_wm_window_type_toolbar;
- Atom atom_net_wm_window_type_dropdown_menu;
- Atom atom_net_wm_window_type_tooltip;
-
-#ifdef USE_IDLE_REPAINT
- guint repaint_id;
-#endif
- guint enabled : 1;
- guint show_redraw : 1;
- guint debug : 1;
-} MetaCompositorXRender;
-
-typedef struct _conv
-{
- int size;
- double *data;
-} conv;
-
-typedef struct _shadow
-{
- conv *gaussian_map;
- guchar *shadow_corner;
- guchar *shadow_top;
-} shadow;
-
-typedef struct _MetaCompScreen
-{
- MetaScreen *screen;
- GList *windows;
- GHashTable *windows_by_xid;
-
- MetaWindow *focus_window;
-
- Window output;
-
- gboolean have_shadows;
- shadow *shadows[LAST_SHADOW_TYPE];
-
- Picture root_picture;
- Picture root_buffer;
- Picture black_picture;
- Picture trans_black_picture;
- Picture root_tile;
- XserverRegion all_damage;
-
- guint overlays;
- gboolean compositor_active;
- gboolean clip_changed;
-
- GSList *dock_windows;
-} MetaCompScreen;
-
-typedef struct _MetaCompWindow
-{
- MetaScreen *screen;
- MetaWindow *window; /* May be NULL if this window isn't managed by Metacity */
- Window id;
- XWindowAttributes attrs;
-
-#ifdef HAVE_NAME_WINDOW_PIXMAP
- Pixmap back_pixmap;
-
- /* When the window is shaded back_pixmap will be replaced with the pixmap
- for the shaded window. This is a copy of the original unshaded window
- so that we can still see what the window looked like when it is needed
- for the _get_window_pixmap function */
- Pixmap shaded_back_pixmap;
-#endif
-
- int mode;
-
- gboolean damaged;
- gboolean shaped;
-
- MetaCompWindowType type;
-
- Damage damage;
- Picture picture;
- Picture alpha_pict;
-
- gboolean needs_shadow;
- MetaShadowType shadow_type;
- Picture shadow_pict;
-
- XserverRegion border_size;
- XserverRegion extents;
-
- Picture shadow;
- int shadow_dx;
- int shadow_dy;
- int shadow_width;
- int shadow_height;
-
- guint opacity;
-
- XserverRegion border_clip;
-
- gboolean updates_frozen;
- gboolean update_pending;
-} MetaCompWindow;
-
-#define OPAQUE 0xffffffff
-
-#define WINDOW_SOLID 0
-#define WINDOW_ARGB 1
-
-#define SHADOW_SMALL_RADIUS 3.0
-#define SHADOW_MEDIUM_RADIUS 6.0
-#define SHADOW_LARGE_RADIUS 12.0
-
-#define SHADOW_SMALL_OFFSET_X (SHADOW_SMALL_RADIUS * -3 / 2)
-#define SHADOW_SMALL_OFFSET_Y (SHADOW_SMALL_RADIUS * -3 / 2)
-#define SHADOW_MEDIUM_OFFSET_X (SHADOW_MEDIUM_RADIUS * -3 / 2)
-#define SHADOW_MEDIUM_OFFSET_Y (SHADOW_MEDIUM_RADIUS * -5 / 4)
-#define SHADOW_LARGE_OFFSET_X -15
-#define SHADOW_LARGE_OFFSET_Y -15
-
-#define SHADOW_OPACITY 0.66
-
-#define TRANS_OPACITY 0.75
-
-#define DISPLAY_COMPOSITOR(display) ((MetaCompositorXRender *) meta_display_get_compositor (display))
-
-/* Gaussian stuff for creating the shadows */
-static double
-gaussian (double r,
- double x,
- double y)
-{
- return ((1 / (sqrt (2 * G_PI * r))) *
- exp ((- (x * x + y * y)) / (2 * r * r)));
-}
-
-static conv *
-make_gaussian_map (double r)
-{
- conv *c;
- int size, centre;
- int x, y;
- double t, g;
-
- size = ((int) ceil ((r * 3)) + 1) & ~1;
- centre = size / 2;
- c = g_malloc (sizeof (conv) + size * size * sizeof (double));
- c->size = size;
- c->data = (double *) (c + 1);
- t = 0.0;
-
- for (y = 0; y < size; y++)
- {
- for (x = 0; x < size; x++)
- {
- g = gaussian (r, (double) (x - centre), (double) (y - centre));
- t += g;
- c->data[y * size + x] = g;
- }
- }
-
- for (y = 0; y < size; y++)
- {
- for (x = 0; x < size; x++)
- {
- c->data[y * size + x] /= t;
- }
- }
-
- return c;
-}
-
-static void
-dump_xserver_region (const char *location,
- MetaDisplay *display,
- XserverRegion region)
-{
- MetaCompositorXRender *compositor = DISPLAY_COMPOSITOR (display);
- Display *xdisplay = meta_display_get_xdisplay (display);
- int nrects;
- XRectangle *rects;
- XRectangle bounds;
-
- if (!compositor->debug)
- return;
-
- if (region)
- {
- rects = XFixesFetchRegionAndBounds (xdisplay, region, &nrects, &bounds);
- if (nrects > 0)
- {
- int i;
- fprintf (stderr, "%s (XSR): %d rects, bounds: %d,%d (%d,%d)\n",
- location, nrects, bounds.x, bounds.y, bounds.width, bounds.height);
- for (i = 1; i < nrects; i++)
- fprintf (stderr, "\t%d,%d (%d,%d)\n",
- rects[i].x, rects[i].y, rects[i].width, rects[i].height);
- }
- else
- fprintf (stderr, "%s (XSR): empty\n", location);
- XFree (rects);
- }
- else
- fprintf (stderr, "%s (XSR): null\n", location);
-}
-
-/*
-* A picture will help
-*
-* -center 0 width width+center
-* -center +-----+-------------------+-----+
-* | | | |
-* | | | |
-* 0 +-----+-------------------+-----+
-* | | | |
-* | | | |
-* | | | |
-* height +-----+-------------------+-----+
-* | | | |
-* height+ | | | |
-* center +-----+-------------------+-----+
-*/
-static guchar
-sum_gaussian (conv *map,
- double opacity,
- int x,
- int y,
- int width,
- int height)
-{
- double *g_data, *g_line;
- double v;
- int fx, fy;
- int fx_start, fx_end;
- int fy_start, fy_end;
- int g_size, centre;
-
- g_line = map->data;
- g_size = map->size;
- centre = g_size / 2;
- fx_start = centre - x;
- if (fx_start < 0)
- fx_start = 0;
-
- fx_end = width + centre - x;
- if (fx_end > g_size)
- fx_end = g_size;
-
- fy_start = centre - y;
- if (fy_start < 0)
- fy_start = 0;
-
- fy_end = height + centre - y;
- if (fy_end > g_size)
- fy_end = g_size;
-
- g_line = g_line + fy_start * g_size + fx_start;
-
- v = 0.0;
- for (fy = fy_start; fy < fy_end; fy++)
- {
- g_data = g_line;
- g_line += g_size;
-
- for (fx = fx_start; fx < fx_end; fx++)
- v += *g_data++;
- }
-
- if (v > 1.0)
- v = 1.0;
-
- return ((guchar) (v * opacity * 255.0));
-}
-
-/* precompute shadow corners and sides to save time for large windows */
-static void
-presum_gaussian (shadow *shad)
-{
- int centre;
- int opacity, x, y;
- int msize;
- conv *map;
-
- map = shad->gaussian_map;
- msize = map->size;
- centre = map->size / 2;
-
- if (shad->shadow_corner)
- g_free (shad->shadow_corner);
- if (shad->shadow_top)
- g_free (shad->shadow_top);
-
- shad->shadow_corner = (guchar *)(g_malloc ((msize + 1) * (msize + 1) * 26));
- shad->shadow_top = (guchar *) (g_malloc ((msize + 1) * 26));
-
- for (x = 0; x <= msize; x++)
- {
-
- shad->shadow_top[25 * (msize + 1) + x] =
- sum_gaussian (map, 1, x - centre, centre, msize * 2, msize * 2);
- for (opacity = 0; opacity < 25; opacity++)
- {
- shad->shadow_top[opacity * (msize + 1) + x] =
- shad->shadow_top[25 * (msize + 1) + x] * opacity / 25;
- }
-
- for (y = 0; y <= x; y++)
- {
- shad->shadow_corner[25 * (msize + 1) * (msize + 1)
- + y * (msize + 1)
- + x]
- = sum_gaussian (map, 1, x - centre, y - centre,
- msize * 2, msize * 2);
-
- shad->shadow_corner[25 * (msize + 1) * (msize + 1)
- + x * (msize + 1) + y] =
- shad->shadow_corner[25 * (msize + 1) * (msize + 1)
- + y * (msize + 1) + x];
-
- for (opacity = 0; opacity < 25; opacity++)
- {
- shad->shadow_corner[opacity * (msize + 1) * (msize + 1)
- + y * (msize + 1) + x]
- = shad->shadow_corner[opacity * (msize + 1) * (msize + 1)
- + x * (msize + 1) + y]
- = shad->shadow_corner[25 * (msize + 1) * (msize + 1)
- + y * (msize + 1) + x] * opacity / 25;
- }
- }
- }
-}
-
-static void
-generate_shadows (MetaCompScreen *info)
-{
- double radii[LAST_SHADOW_TYPE] = {SHADOW_SMALL_RADIUS,
- SHADOW_MEDIUM_RADIUS,
- SHADOW_LARGE_RADIUS};
- int i;
-
- for (i = 0; i < LAST_SHADOW_TYPE; i++) {
- shadow *shad = g_new0 (shadow, 1);
-
- shad->gaussian_map = make_gaussian_map (radii[i]);
- presum_gaussian (shad);
-
- info->shadows[i] = shad;
- }
-}
-
-static XImage *
-make_shadow (MetaDisplay *display,
- MetaScreen *screen,
- MetaShadowType shadow_type,
- double opacity,
- int width,
- int height)
-{
- MetaCompScreen *info = meta_screen_get_compositor_data (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- XImage *ximage;
- guchar *data;
- shadow *shad;
- int msize;
- int ylimit, xlimit;
- int swidth, sheight;
- int centre;
- int x, y;
- guchar d;
- int x_diff;
- int opacity_int = (int)(opacity * 25);
- int screen_number = meta_screen_get_screen_number (screen);
-
- if (info==NULL)
- {
- return NULL;
- }
-
- shad = info->shadows[shadow_type];
- msize = shad->gaussian_map->size;
- swidth = width + msize;
- sheight = height + msize;
- centre = msize / 2;
-
- data = g_malloc (swidth * sheight * sizeof (guchar));
-
- ximage = XCreateImage (xdisplay, DefaultVisual (xdisplay, screen_number),
- 8, ZPixmap, 0, (char *) data,
- swidth, sheight, 8, swidth * sizeof (guchar));
- if (!ximage)
- {
- g_free (data);
- return NULL;
- }
-
- /*
- * Build the gaussian in sections
- */
-
- /*
- * centre (fill the complete data array
- */
- if (msize > 0)
- d = shad->shadow_top[opacity_int * (msize + 1) + msize];
- else
- d = sum_gaussian (shad->gaussian_map, opacity, centre,
- centre, width, height);
- memset (data, d, sheight * swidth);
-
- /*
- * corners
- */
- ylimit = msize;
- if (ylimit > sheight / 2)
- ylimit = (sheight + 1) / 2;
-
- xlimit = msize;
- if (xlimit > swidth / 2)
- xlimit = (swidth + 1) / 2;
-
- for (y = 0; y < ylimit; y++)
- {
- for (x = 0; x < xlimit; x++)
- {
-
- if (xlimit == msize && ylimit == msize)
- d = shad->shadow_corner[opacity_int * (msize + 1) * (msize + 1) + y * (msize + 1) + x];
- else
- d = sum_gaussian (shad->gaussian_map, opacity, x - centre,
- y - centre, width, height);
-
- data[y * swidth + x] = d;
- data[(sheight - y - 1) * swidth + x] = d;
- data[(sheight - y - 1) * swidth + (swidth - x - 1)] = d;
- data[y * swidth + (swidth - x - 1)] = d;
- }
- }
-
- /* top/bottom */
- x_diff = swidth - (msize * 2);
- if (x_diff > 0 && ylimit > 0)
- {
- for (y = 0; y < ylimit; y++)
- {
- if (ylimit == msize)
- d = shad->shadow_top[opacity_int * (msize + 1) + y];
- else
- d = sum_gaussian (shad->gaussian_map, opacity, centre,
- y - centre, width, height);
-
- memset (&data[y * swidth + msize], d, x_diff);
- memset (&data[(sheight - y - 1) * swidth + msize], d, x_diff);
- }
- }
-
- /*
- * sides
- */
- for (x = 0; x < xlimit; x++)
- {
- if (xlimit == msize)
- d = shad->shadow_top[opacity_int * (msize + 1) + x];
- else
- d = sum_gaussian (shad->gaussian_map, opacity, x - centre,
- centre, width, height);
-
- for (y = msize; y < sheight - msize; y++)
- {
- data[y * swidth + x] = d;
- data[y * swidth + (swidth - x - 1)] = d;
- }
- }
-
- return ximage;
-}
-
-static Picture
-shadow_picture (MetaDisplay *display,
- MetaScreen *screen,
- MetaShadowType shadow_type,
- double opacity,
- Picture alpha_pict,
- int width,
- int height,
- int *wp,
- int *hp)
-{
- Display *xdisplay = meta_display_get_xdisplay (display);
- XImage *shadow_image;
- Pixmap shadow_pixmap;
- Picture shadow_picture;
- Window xroot = meta_screen_get_xroot (screen);
- GC gc;
-
- shadow_image = make_shadow (display, screen, shadow_type,
- opacity, width, height);
- if (!shadow_image)
- return None;
-
- shadow_pixmap = XCreatePixmap (xdisplay, xroot,
- shadow_image->width, shadow_image->height, 8);
- if (!shadow_pixmap)
- {
- XDestroyImage (shadow_image);
- return None;
- }
-
- shadow_picture = XRenderCreatePicture (xdisplay, shadow_pixmap,
- XRenderFindStandardFormat (xdisplay,
-PictStandardA8),
- 0, 0);
- if (!shadow_picture)
- {
- XDestroyImage (shadow_image);
- XFreePixmap (xdisplay, shadow_pixmap);
- return None;
- }
-
- gc = XCreateGC (xdisplay, shadow_pixmap, 0, 0);
- if (!gc)
- {
- XDestroyImage (shadow_image);
- XFreePixmap (xdisplay, shadow_pixmap);
- XRenderFreePicture (xdisplay, shadow_picture);
- return None;
- }
-
- XPutImage (xdisplay, shadow_pixmap, gc, shadow_image, 0, 0, 0, 0,
- shadow_image->width, shadow_image->height);
- *wp = shadow_image->width;
- *hp = shadow_image->height;
-
- XFreeGC (xdisplay, gc);
- XDestroyImage (shadow_image);
- XFreePixmap (xdisplay, shadow_pixmap);
-
- return shadow_picture;
-}
-
-static MetaCompWindow *
-find_window_for_screen (MetaScreen *screen,
- Window xwindow)
-{
- MetaCompScreen *info = meta_screen_get_compositor_data (screen);
-
- if (info == NULL)
- return NULL;
-
- return g_hash_table_lookup (info->windows_by_xid, (gpointer) xwindow);
-}
-
-static MetaCompWindow *
-find_window_in_display (MetaDisplay *display,
- Window xwindow)
-{
- GSList *index;
-
- for (index = meta_display_get_screens (display); index; index = index->next)
- {
- MetaCompWindow *cw = find_window_for_screen (index->data, xwindow);
-
- if (cw != NULL)
- return cw;
- }
-
- return NULL;
-}
-
-static MetaCompWindow *
-find_window_for_child_window_in_display (MetaDisplay *display,
- Window xwindow)
-{
- Window ignored1, *ignored2;
- Window parent;
- guint ignored_children;
-
- XQueryTree (meta_display_get_xdisplay (display), xwindow, &ignored1,
- &parent, &ignored2, &ignored_children);
-
- if (parent != None)
- return find_window_in_display (display, parent);
-
- return NULL;
-}
-
-static Picture
-solid_picture (MetaDisplay *display,
- MetaScreen *screen,
- gboolean argb,
- double a,
- double r,
- double g,
- double b)
-{
- Display *xdisplay = meta_display_get_xdisplay (display);
- Pixmap pixmap;
- Picture picture;
- XRenderPictureAttributes pa;
- XRenderPictFormat *render_format;
- XRenderColor c;
- Window xroot = meta_screen_get_xroot (screen);
-
- render_format = XRenderFindStandardFormat (xdisplay,
- argb ? PictStandardARGB32 : PictStandardA8);
-
- pixmap = XCreatePixmap (xdisplay, xroot, 1, 1, argb ? 32 : 8);
- g_return_val_if_fail (pixmap != None, None);
-
- pa.repeat = TRUE;
- picture = XRenderCreatePicture (xdisplay, pixmap, render_format,
- CPRepeat, &pa);
- if (picture == None)
- {
- XFreePixmap (xdisplay, pixmap);
- g_warning ("(picture != None) failed");
- return None;
- }
-
- c.alpha = a * 0xffff;
- c.red = r * 0xffff;
- c.green = g * 0xffff;
- c.blue = b * 0xffff;
-
- XRenderFillRectangle (xdisplay, PictOpSrc, picture, &c, 0, 0, 1, 1);
- XFreePixmap (xdisplay, pixmap);
-
- return picture;
-}
-
-static Picture
-root_tile (MetaScreen *screen)
-{
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- Picture picture;
- Pixmap pixmap;
- gboolean fill = FALSE;
- XRenderPictureAttributes pa;
- XRenderPictFormat *format;
- int p;
- Atom background_atoms[2];
- Atom pixmap_atom;
- int screen_number = meta_screen_get_screen_number (screen);
- Window xroot = meta_screen_get_xroot (screen);
-
- pixmap = None;
- background_atoms[0] = DISPLAY_COMPOSITOR (display)->atom_x_root_pixmap;
- background_atoms[1] = DISPLAY_COMPOSITOR (display)->atom_x_set_root;
-
- pixmap_atom = XInternAtom (xdisplay, "PIXMAP", False);
- for (p = 0; p < 2; p++)
- {
- Atom actual_type;
- int actual_format;
- gulong nitems, bytes_after;
- guchar *prop;
-
- if (XGetWindowProperty (xdisplay, xroot,
- background_atoms[p],
- 0, 4, FALSE, AnyPropertyType,
- &actual_type, &actual_format,
- &nitems, &bytes_after, &prop) == Success)
- {
- if (actual_type == pixmap_atom &&
- actual_format == 32 &&
- nitems == 1)
- {
- memcpy (&pixmap, prop, 4);
- XFree (prop);
- fill = FALSE;
- break;
- }
- }
- }
-
- if (!pixmap)
- {
- pixmap = XCreatePixmap (xdisplay, xroot, 1, 1,
- DefaultDepth (xdisplay, screen_number));
- g_return_val_if_fail (pixmap != None, None);
- fill = TRUE;
- }
-
- pa.repeat = TRUE;
- format = XRenderFindVisualFormat (xdisplay, DefaultVisual (xdisplay,
- screen_number));
- g_return_val_if_fail (format != NULL, None);
-
- picture = XRenderCreatePicture (xdisplay, pixmap, format, CPRepeat, &pa);
- if ((picture != None) && (fill))
- {
- XRenderColor c;
-
- /* Background default to just plain ugly grey */
- c.red = 0x8080;
- c.green = 0x8080;
- c.blue = 0x8080;
- c.alpha = 0xffff;
-
- XRenderFillRectangle (xdisplay, PictOpSrc, picture, &c, 0, 0, 1, 1);
- XFreePixmap (xdisplay, pixmap);
- }
-
- return picture;
-}
-
-static Picture
-create_root_buffer (MetaScreen *screen)
-{
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- MetaCompScreen *info = meta_screen_get_compositor_data (screen);
- Picture pict;
- XRenderPictFormat *format;
- Pixmap root_pixmap;
- Visual *visual;
- int depth, screen_width, screen_height, screen_number;
-
- if (info == NULL)
- {
- return None;
- }
-
- meta_screen_get_size (screen, &screen_width, &screen_height);
- screen_number = meta_screen_get_screen_number (screen);
- visual = DefaultVisual (xdisplay, screen_number);
- depth = DefaultDepth (xdisplay, screen_number);
-
- format = XRenderFindVisualFormat (xdisplay, visual);
- g_return_val_if_fail (format != NULL, None);
-
- root_pixmap = XCreatePixmap (xdisplay, info->output,
- screen_width, screen_height, depth);
- g_return_val_if_fail (root_pixmap != None, None);
-
- pict = XRenderCreatePicture (xdisplay, root_pixmap, format, 0, NULL);
- XFreePixmap (xdisplay, root_pixmap);
-
- return pict;
-}
-
-static void
-paint_root (MetaScreen *screen,
- Picture root_buffer)
-{
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- MetaCompScreen *info = meta_screen_get_compositor_data (screen);
- int width, height;
-
- if (info == NULL)
- {
- return;
- }
-
- g_return_if_fail (root_buffer != None);
-
- if (info->root_tile == None)
- {
- info->root_tile = root_tile (screen);
- g_return_if_fail (info->root_tile != None);
- }
-
- meta_screen_get_size (screen, &width, &height);
- XRenderComposite (xdisplay, PictOpSrc, info->root_tile, None, root_buffer,
- 0, 0, 0, 0, 0, 0, width, height);
-}
-
-static gboolean
-window_has_shadow (MetaCompWindow *cw)
-{
- MetaCompScreen *info = meta_screen_get_compositor_data (cw->screen);
-
- if (info == NULL || info->have_shadows == FALSE)
- return FALSE;
-
- /* Always put a shadow around windows with a frame - This should override
- the restriction about not putting a shadow around shaped windows
- as the frame might be the reason the window is shaped */
- if (cw->window)
- {
- if (meta_window_get_frame (cw->window)) {
- meta_verbose ("Window has shadow because it has a frame\n");
- return TRUE;
- }
- }
-
- /* Never put a shadow around shaped windows */
- if (cw->shaped) {
- meta_verbose ("Window has no shadow as it is shaped\n");
- return FALSE;
- }
-
- /* Don't put shadow around DND icon windows */
- if (cw->type == META_COMP_WINDOW_DND ||
- cw->type == META_COMP_WINDOW_DESKTOP) {
- meta_verbose ("Window has no shadow as it is DND or Desktop\n");
- return FALSE;
- }
-
- if (cw->mode != WINDOW_ARGB) {
- meta_verbose ("Window has shadow as it is not ARGB\n");
- return TRUE;
- }
-
- if (cw->type == META_COMP_WINDOW_MENU ||
- cw->type == META_COMP_WINDOW_DROP_DOWN_MENU) {
- meta_verbose ("Window has shadow as it is a menu\n");
- return TRUE;
- }
-
- if (cw->type == META_COMP_WINDOW_TOOLTIP) {
- meta_verbose ("Window has shadow as it is a tooltip\n");
- return TRUE;
- }
-
- meta_verbose ("Window has no shadow as it fell through\n");
- return FALSE;
-}
-
-double shadow_offsets_x[LAST_SHADOW_TYPE] = {SHADOW_SMALL_OFFSET_X,
- SHADOW_MEDIUM_OFFSET_X,
- SHADOW_LARGE_OFFSET_X};
-double shadow_offsets_y[LAST_SHADOW_TYPE] = {SHADOW_SMALL_OFFSET_Y,
- SHADOW_MEDIUM_OFFSET_Y,
- SHADOW_LARGE_OFFSET_Y};
-static XserverRegion
-win_extents (MetaCompWindow *cw)
-{
- MetaScreen *screen = cw->screen;
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- XRectangle r;
-
- r.x = cw->attrs.x;
- r.y = cw->attrs.y;
- r.width = cw->attrs.width + cw->attrs.border_width * 2;
- r.height = cw->attrs.height + cw->attrs.border_width * 2;
-
- if (cw->needs_shadow)
- {
- XRectangle sr;
-
- cw->shadow_dx = shadow_offsets_x [cw->shadow_type];
- cw->shadow_dy = shadow_offsets_y [cw->shadow_type];
-
- if (!cw->shadow)
- {
- double opacity = SHADOW_OPACITY;
- if (cw->opacity != (guint) OPAQUE)
- opacity = opacity * ((double) cw->opacity) / ((double) OPAQUE);
-
- cw->shadow = shadow_picture (display, screen, cw->shadow_type,
- opacity, cw->alpha_pict,
- cw->attrs.width + cw->attrs.border_width * 2,
- cw->attrs.height + cw->attrs.border_width * 2,
- &cw->shadow_width, &cw->shadow_height);
- }
-
- sr.x = cw->attrs.x + cw->shadow_dx;
- sr.y = cw->attrs.y + cw->shadow_dy;
- sr.width = cw->shadow_width;
- sr.height = cw->shadow_height;
-
- if (sr.x < r.x)
- {
- r.width = (r.x + r.width) - sr.x;
- r.x = sr.x;
- }
-
- if (sr.y < r.y)
- {
- r.height = (r.y + r.height) - sr.y;
- r.y = sr.y;
- }
-
- if (sr.x + sr.width > r.x + r.width)
- r.width = sr.x + sr.width - r.x;
-
- if (sr.y + sr.height > r.y + r.height)
- r.height = sr.y + sr.height - r.y;
- }
-
- return XFixesCreateRegion (xdisplay, &r, 1);
-}
-
-static XserverRegion
-border_size (MetaCompWindow *cw)
-{
- MetaScreen *screen = cw->screen;
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- XserverRegion border;
-
- meta_error_trap_push (display);
- border = XFixesCreateRegionFromWindow (xdisplay, cw->id,
- WindowRegionBounding);
- meta_error_trap_pop (display, FALSE);
-
- g_return_val_if_fail (border != None, None);
- XFixesTranslateRegion (xdisplay, border,
- cw->attrs.x + cw->attrs.border_width,
- cw->attrs.y + cw->attrs.border_width);
- return border;
-}
-
-static XRenderPictFormat *
-get_window_format (MetaCompWindow *cw)
-{
- MetaScreen *screen = cw->screen;
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- XRenderPictFormat *format;
- int screen_number = meta_screen_get_screen_number (screen);
-
- format = XRenderFindVisualFormat (xdisplay, cw->attrs.visual);
- if (!format)
- format = XRenderFindVisualFormat (xdisplay,
- DefaultVisual (xdisplay, screen_number));
- return format;
-}
-
-static Picture
-get_window_picture (MetaCompWindow *cw)
-{
- MetaScreen *screen = cw->screen;
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- XRenderPictureAttributes pa;
- XRenderPictFormat *format;
- Drawable draw;
-
- draw = cw->id;
-
- meta_error_trap_push (display);
-
-#ifdef HAVE_NAME_WINDOW_PIXMAP
- if (have_name_window_pixmap (display))
- {
- if (cw->back_pixmap == None)
- cw->back_pixmap = XCompositeNameWindowPixmap (xdisplay, cw->id);
-
- if (cw->back_pixmap != None)
- draw = cw->back_pixmap;
- }
-#endif
-
- format = get_window_format (cw);
- if (format)
- {
- Picture pict;
-
- pa.subwindow_mode = IncludeInferiors;
-
- pict = XRenderCreatePicture (xdisplay, draw, format, CPSubwindowMode, &pa);
- meta_error_trap_pop (display, FALSE);
-
- return pict;
- }
-
- meta_error_trap_pop (display, FALSE);
- return None;
-}
-
-static void
-paint_dock_shadows (MetaScreen *screen,
- Picture root_buffer,
- XserverRegion region)
-{
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- MetaCompScreen *info = meta_screen_get_compositor_data (screen);
- GSList *d;
-
- if (info == NULL)
- {
- return;
- }
-
- for (d = info->dock_windows; d; d = d->next)
- {
- MetaCompWindow *cw = d->data;
- XserverRegion shadow_clip;
-
- if (cw->shadow)
- {
- shadow_clip = XFixesCreateRegion (xdisplay, NULL, 0);
- XFixesIntersectRegion (xdisplay, shadow_clip,
- cw->border_clip, region);
-
- XFixesSetPictureClipRegion (xdisplay, root_buffer, 0, 0, shadow_clip);
-
- XRenderComposite (xdisplay, PictOpOver, info->black_picture,
- cw->shadow, root_buffer,
- 0, 0, 0, 0,
- cw->attrs.x + cw->shadow_dx,
- cw->attrs.y + cw->shadow_dy,
- cw->shadow_width, cw->shadow_height);
- XFixesDestroyRegion (xdisplay, shadow_clip);
- }
- }
-}
-
-static void
-paint_windows (MetaScreen *screen,
- GList *windows,
- Picture root_buffer,
- XserverRegion region)
-{
- MetaDisplay *display = meta_screen_get_display (screen);
- MetaCompScreen *info = meta_screen_get_compositor_data (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- GList *index, *last;
- int screen_width, screen_height, screen_number;
- Window xroot;
- MetaCompWindow *cw;
- XserverRegion paint_region, desktop_region;
-
- if (info == NULL)
- {
- return;
- }
-
- meta_screen_get_size (screen, &screen_width, &screen_height);
- screen_number = meta_screen_get_screen_number (screen);
- xroot = meta_screen_get_xroot (screen);
-
- if (region == None)
- {
- XRectangle r;
- r.x = 0;
- r.y = 0;
- r.width = screen_width;
- r.height = screen_height;
- paint_region = XFixesCreateRegion (xdisplay, &r, 1);
- }
- else
- {
- paint_region = XFixesCreateRegion (xdisplay, NULL, 0);
- XFixesCopyRegion (xdisplay, paint_region, region);
- }
-
- desktop_region = None;
-
- /*
- * Painting from top to bottom, reducing the clipping area at
- * each iteration. Only the opaque windows are painted 1st.
- */
- last = NULL;
- for (index = windows; index; index = index->next)
- {
- /* Store the last window we dealt with */
- last = index;
-
- cw = (MetaCompWindow *) index->data;
- if (!cw->damaged)
- {
- /* Not damaged */
- continue;
- }
-
-#if 0
- if ((cw->attrs.x + cw->attrs.width < 1) ||
- (cw->attrs.y + cw->attrs.height < 1) ||
- (cw->attrs.x >= screen_width) || (cw->attrs.y >= screen_height))
- {
- /* Off screen */
- continue;
- }
-#endif
-
- if (cw->picture == None)
- cw->picture = get_window_picture (cw);
-
- /* If the clip region of the screen has been changed
- then we need to recreate the extents of the window */
- if (info->clip_changed)
- {
- if (cw->border_size)
- {
- XFixesDestroyRegion (xdisplay, cw->border_size);
- cw->border_size = None;
- }
-
-#if 0
- if (cw->extents)
- {
- XFixesDestroyRegion (xdisplay, cw->extents);
- cw->extents = None;
- }
-#endif
- }
-
- if (cw->border_size == None)
- cw->border_size = border_size (cw);
-
- if (cw->extents == None)
- cw->extents = win_extents (cw);
-
- if (cw->mode == WINDOW_SOLID)
- {
- int x, y, wid, hei;
-
-#ifdef HAVE_NAME_WINDOW_PIXMAP
- if (have_name_window_pixmap (display))
- {
- x = cw->attrs.x;
- y = cw->attrs.y;
- wid = cw->attrs.width + cw->attrs.border_width * 2;
- hei = cw->attrs.height + cw->attrs.border_width * 2;
- }
- else
-#endif
- {
- x = cw->attrs.x + cw->attrs.border_width;
- y = cw->attrs.y + cw->attrs.border_width;
- wid = cw->attrs.width;
- hei = cw->attrs.height;
- }
-
- XFixesSetPictureClipRegion (xdisplay, root_buffer,
- 0, 0, paint_region);
- XRenderComposite (xdisplay, PictOpSrc, cw->picture,
- None, root_buffer, 0, 0, 0, 0,
- x, y, wid, hei);
-
- if (cw->type == META_COMP_WINDOW_DESKTOP)
- {
- desktop_region = XFixesCreateRegion (xdisplay, 0, 0);
- XFixesCopyRegion (xdisplay, desktop_region, paint_region);
- }
-
- XFixesSubtractRegion (xdisplay, paint_region,
- paint_region, cw->border_size);
- }
-
- if (!cw->border_clip)
- {
- cw->border_clip = XFixesCreateRegion (xdisplay, 0, 0);
- XFixesCopyRegion (xdisplay, cw->border_clip, paint_region);
- }
- }
-
- XFixesSetPictureClipRegion (xdisplay, root_buffer, 0, 0, paint_region);
- paint_root (screen, root_buffer);
-
- paint_dock_shadows (screen, root_buffer, desktop_region == None ?
- paint_region : desktop_region);
- if (desktop_region != None)
- XFixesDestroyRegion (xdisplay, desktop_region);
-
- /*
- * Painting from bottom to top, translucent windows and shadows are painted
- */
- for (index = last; index; index = index->prev)
- {
- cw = (MetaCompWindow *) index->data;
-
- if (cw->picture)
- {
- if (cw->shadow && cw->type != META_COMP_WINDOW_DOCK)
- {
- XserverRegion shadow_clip;
-
- shadow_clip = XFixesCreateRegion (xdisplay, NULL, 0);
- XFixesSubtractRegion (xdisplay, shadow_clip, cw->border_clip,
- cw->border_size);
- XFixesSetPictureClipRegion (xdisplay, root_buffer, 0, 0,
- shadow_clip);
-
- XRenderComposite (xdisplay, PictOpOver, info->black_picture,
- cw->shadow, root_buffer,
- 0, 0, 0, 0,
- cw->attrs.x + cw->shadow_dx,
- cw->attrs.y + cw->shadow_dy,
- cw->shadow_width, cw->shadow_height);
- if (shadow_clip)
- XFixesDestroyRegion (xdisplay, shadow_clip);
- }
-
- if ((cw->opacity != (guint) OPAQUE) && !(cw->alpha_pict))
- {
- cw->alpha_pict = solid_picture (display, screen, FALSE,
- (double) cw->opacity / OPAQUE,
- 0, 0, 0);
- }
-
- XFixesIntersectRegion (xdisplay, cw->border_clip, cw->border_clip,
- cw->border_size);
- XFixesSetPictureClipRegion (xdisplay, root_buffer, 0, 0,
- cw->border_clip);
- if (cw->mode == WINDOW_ARGB)
- {
- int x, y, wid, hei;
-#ifdef HAVE_NAME_WINDOW_PIXMAP
- if (have_name_window_pixmap (display))
- {
- x = cw->attrs.x;
- y = cw->attrs.y;
- wid = cw->attrs.width + cw->attrs.border_width * 2;
- hei = cw->attrs.height + cw->attrs.border_width * 2;
- }
- else
-#endif
- {
- x = cw->attrs.x + cw->attrs.border_width;
- y = cw->attrs.y + cw->attrs.border_width;
- wid = cw->attrs.width;
- hei = cw->attrs.height;
- }
-
- XRenderComposite (xdisplay, PictOpOver, cw->picture,
- cw->alpha_pict, root_buffer, 0, 0, 0, 0,
- x, y, wid, hei);
- }
- }
-
- if (cw->border_clip)
- {
- XFixesDestroyRegion (xdisplay, cw->border_clip);
- cw->border_clip = None;
- }
- }
-
- XFixesDestroyRegion (xdisplay, paint_region);
-}
-
-static void
-paint_all (MetaScreen *screen,
- XserverRegion region)
-{
- MetaCompScreen *info = meta_screen_get_compositor_data (screen);
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- int screen_width, screen_height;
-
- /* Set clipping to the given region */
- XFixesSetPictureClipRegion (xdisplay, info->root_picture, 0, 0, region);
-
- meta_screen_get_size (screen, &screen_width, &screen_height);
-
- if (DISPLAY_COMPOSITOR (display)->show_redraw)
- {
- Picture overlay;
-
- dump_xserver_region ("paint_all", display, region);
-
- /* Make a random colour overlay */
- overlay = solid_picture (display, screen, TRUE, 1, /* 0.3, alpha */
- ((double) (rand () % 100)) / 100.0,
- ((double) (rand () % 100)) / 100.0,
- ((double) (rand () % 100)) / 100.0);
-
- XRenderComposite (xdisplay, PictOpOver, overlay, None, info->root_picture,
- 0, 0, 0, 0, 0, 0, screen_width, screen_height);
- XRenderFreePicture (xdisplay, overlay);
- XFlush (xdisplay);
- usleep (100 * 1000);
- }
-
- if (info->root_buffer == None)
- info->root_buffer = create_root_buffer (screen);
-
- paint_windows (screen, info->windows, info->root_buffer, region);
-
- XFixesSetPictureClipRegion (xdisplay, info->root_buffer, 0, 0, region);
- XRenderComposite (xdisplay, PictOpSrc, info->root_buffer, None,
- info->root_picture, 0, 0, 0, 0, 0, 0,
- screen_width, screen_height);
-}
-
-static void
-repair_screen (MetaScreen *screen)
-{
- MetaCompScreen *info = meta_screen_get_compositor_data (screen);
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
-
- if (info!=NULL && info->all_damage != None)
- {
- meta_error_trap_push (display);
- paint_all (screen, info->all_damage);
- XFixesDestroyRegion (xdisplay, info->all_damage);
- info->all_damage = None;
- info->clip_changed = FALSE;
- meta_error_trap_pop (display, FALSE);
- }
-}
-
-static void
-repair_display (MetaDisplay *display)
-{
- GSList *screens = meta_display_get_screens (display);
- MetaCompositorXRender *compositor = DISPLAY_COMPOSITOR (display);
-
-#ifdef USE_IDLE_REPAINT
- if (compositor->repaint_id > 0)
- {
- g_source_remove (compositor->repaint_id);
- compositor->repaint_id = 0;
- }
-#endif
-
- for (; screens; screens = screens->next)
- repair_screen ((MetaScreen *) screens->data);
-}
-
-#ifdef USE_IDLE_REPAINT
-static gboolean
-compositor_idle_cb (gpointer data)
-{
- MetaCompositorXRender *compositor = (MetaCompositorXRender *) data;
-
- compositor->repaint_id = 0;
- repair_display (compositor->display);
-
- return FALSE;
-}
-
-static void
-add_repair (MetaDisplay *display)
-{
- MetaCompositorXRender *compositor = DISPLAY_COMPOSITOR (display);
-
- if (compositor->repaint_id > 0)
- return;
-
-#if 1
- compositor->repaint_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE,
- compositor_idle_cb, compositor,
- NULL);
-#else
- /* Limit it to 50fps */
- compositor->repaint_id = g_timeout_add_full (G_PRIORITY_HIGH, 20,
- compositor_idle_cb, compositor,
- NULL);
-#endif
-}
-#endif
-
-static void
-add_damage (MetaScreen *screen,
- XserverRegion damage)
-{
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- MetaCompScreen *info = meta_screen_get_compositor_data (screen);
-
- /* dump_xserver_region ("add_damage", display, damage); */
-
- if (info != NULL && info->all_damage)
- {
- XFixesUnionRegion (xdisplay, info->all_damage, info->all_damage, damage);
- XFixesDestroyRegion (xdisplay, damage);
- }
- else
- info->all_damage = damage;
-
-#ifdef USE_IDLE_REPAINT
- add_repair (display);
-#endif
-}
-
-static void
-damage_screen (MetaScreen *screen)
-{
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- XserverRegion region;
- int width, height;
- XRectangle r;
-
- r.x = 0;
- r.y = 0;
- meta_screen_get_size (screen, &width, &height);
- r.width = width;
- r.height = height;
-
- region = XFixesCreateRegion (xdisplay, &r, 1);
- dump_xserver_region ("damage_screen", display, region);
- add_damage (screen, region);
-}
-
-static void
-repair_win (MetaCompWindow *cw)
-{
- MetaScreen *screen = cw->screen;
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- XserverRegion parts;
-
- meta_error_trap_push (display);
- if (!cw->damaged)
- {
- parts = win_extents (cw);
- XDamageSubtract (xdisplay, cw->damage, None, None);
- }
- else
- {
- parts = XFixesCreateRegion (xdisplay, 0, 0);
- XDamageSubtract (xdisplay, cw->damage, None, parts);
- XFixesTranslateRegion (xdisplay, parts,
- cw->attrs.x + cw->attrs.border_width,
- cw->attrs.y + cw->attrs.border_width);
- }
-
- meta_error_trap_pop (display, FALSE);
-
- dump_xserver_region ("repair_win", display, parts);
- add_damage (screen, parts);
- cw->damaged = TRUE;
-}
-
-static void
-free_win (MetaCompWindow *cw,
- gboolean destroy)
-{
- MetaDisplay *display = meta_screen_get_display (cw->screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- MetaCompScreen *info = meta_screen_get_compositor_data (cw->screen);
-
-#ifdef HAVE_NAME_WINDOW_PIXMAP
- if (have_name_window_pixmap (display))
- {
- /* See comment in map_win */
- if (cw->back_pixmap && destroy)
- {
- XFreePixmap (xdisplay, cw->back_pixmap);
- cw->back_pixmap = None;
- }
-
- if (cw->shaded_back_pixmap && destroy)
- {
- XFreePixmap (xdisplay, cw->shaded_back_pixmap);
- cw->shaded_back_pixmap = None;
- }
- }
-#endif
-
- if (cw->picture)
- {
- XRenderFreePicture (xdisplay, cw->picture);
- cw->picture = None;
- }
-
- if (cw->shadow)
- {
- XRenderFreePicture (xdisplay, cw->shadow);
- cw->shadow = None;
- }
-
- if (cw->alpha_pict)
- {
- XRenderFreePicture (xdisplay, cw->alpha_pict);
- cw->alpha_pict = None;
- }
-
- if (cw->shadow_pict)
- {
- XRenderFreePicture (xdisplay, cw->shadow_pict);
- cw->shadow_pict = None;
- }
-
- if (cw->border_size)
- {
- XFixesDestroyRegion (xdisplay, cw->border_size);
- cw->border_size = None;
- }
-
- if (cw->border_clip)
- {
- XFixesDestroyRegion (xdisplay, cw->border_clip);
- cw->border_clip = None;
- }
-
- if (cw->extents)
- {
- XFixesDestroyRegion (xdisplay, cw->extents);
- cw->extents = None;
- }
-
- if (destroy)
- {
- if (cw->damage != None) {
- meta_error_trap_push (display);
- XDamageDestroy (xdisplay, cw->damage);
- meta_error_trap_pop (display, FALSE);
-
- cw->damage = None;
- }
-
- /* The window may not have been added to the list in this case,
- but we can check anyway */
- if (info!=NULL && cw->type == META_COMP_WINDOW_DOCK)
- info->dock_windows = g_slist_remove (info->dock_windows, cw);
-
- g_free (cw);
- }
-}
-
-static void
-map_win (MetaDisplay *display,
- MetaScreen *screen,
- Window id)
-{
- MetaCompWindow *cw = find_window_for_screen (screen, id);
- Display *xdisplay = meta_display_get_xdisplay (display);
-
- if (cw == NULL)
- return;
-
-#ifdef HAVE_NAME_WINDOW_PIXMAP
- /* The reason we deallocate this here and not in unmap
- is so that we will still have a valid pixmap for
- whenever the window is unmapped */
- if (cw->back_pixmap)
- {
- XFreePixmap (xdisplay, cw->back_pixmap);
- cw->back_pixmap = None;
- }
-
- if (cw->shaded_back_pixmap)
- {
- XFreePixmap (xdisplay, cw->shaded_back_pixmap);
- cw->shaded_back_pixmap = None;
- }
-#endif
-
- cw->attrs.map_state = IsViewable;
- cw->damaged = FALSE;
-}
-
-static void
-unmap_win (MetaDisplay *display,
- MetaScreen *screen,
- Window id)
-{
- MetaCompWindow *cw = find_window_for_screen (screen, id);
- MetaCompScreen *info = meta_screen_get_compositor_data (screen);
-
- if (cw == NULL || info == NULL)
- {
- return;
- }
-
- if (cw->window && cw->window == info->focus_window)
- info->focus_window = NULL;
-
- cw->attrs.map_state = IsUnmapped;
- cw->damaged = FALSE;
-
- if (cw->extents != None)
- {
- dump_xserver_region ("unmap_win", display, cw->extents);
- add_damage (screen, cw->extents);
- cw->extents = None;
- }
-
- free_win (cw, FALSE);
- info->clip_changed = TRUE;
-}
-
-static void
-determine_mode (MetaDisplay *display,
- MetaScreen *screen,
- MetaCompWindow *cw)
-{
- XRenderPictFormat *format;
- Display *xdisplay = meta_display_get_xdisplay (display);
-
- if (cw->alpha_pict)
- {
- XRenderFreePicture (xdisplay, cw->alpha_pict);
- cw->alpha_pict = None;
- }
-
- if (cw->shadow_pict)
- {
- XRenderFreePicture (xdisplay, cw->shadow_pict);
- cw->shadow_pict = None;
- }
-
- if (cw->attrs.class == InputOnly)
- format = NULL;
- else
- format = XRenderFindVisualFormat (xdisplay, cw->attrs.visual);
-
- if ((format && format->type == PictTypeDirect && format->direct.alphaMask)
- || cw->opacity != (guint) OPAQUE)
- cw->mode = WINDOW_ARGB;
- else
- cw->mode = WINDOW_SOLID;
-
- if (cw->extents)
- {
- XserverRegion damage;
- damage = XFixesCreateRegion (xdisplay, NULL, 0);
- XFixesCopyRegion (xdisplay, damage, cw->extents);
-
- dump_xserver_region ("determine_mode", display, damage);
- add_damage (screen, damage);
- }
-}
-
-static gboolean
-is_shaped (MetaDisplay *display,
- Window xwindow)
-{
- Display *xdisplay = meta_display_get_xdisplay (display);
- int xws, yws, xbs, ybs;
- unsigned wws, hws, wbs, hbs;
- int bounding_shaped, clip_shaped;
-
- if (meta_display_has_shape (display))
- {
- XShapeQueryExtents (xdisplay, xwindow, &bounding_shaped,
- &xws, &yws, &wws, &hws, &clip_shaped,
- &xbs, &ybs, &wbs, &hbs);
- return (bounding_shaped != 0);
- }
-
- return FALSE;
-}
-
-static void
-get_window_type (MetaDisplay *display,
- MetaCompWindow *cw)
-{
- MetaCompositorXRender *compositor = DISPLAY_COMPOSITOR (display);
- int n_atoms;
- Atom *atoms, type_atom;
- int i;
-
- type_atom = None;
- n_atoms = 0;
- atoms = NULL;
-
- meta_prop_get_atom_list (display, cw->id,
- compositor->atom_net_wm_window_type,
- &atoms, &n_atoms);
-
- for (i = 0; i < n_atoms; i++)
- {
- if (atoms[i] == compositor->atom_net_wm_window_type_dnd ||
- atoms[i] == compositor->atom_net_wm_window_type_desktop ||
- atoms[i] == compositor->atom_net_wm_window_type_dock ||
- atoms[i] == compositor->atom_net_wm_window_type_toolbar ||
- atoms[i] == compositor->atom_net_wm_window_type_menu ||
- atoms[i] == compositor->atom_net_wm_window_type_dialog ||
- atoms[i] == compositor->atom_net_wm_window_type_normal ||
- atoms[i] == compositor->atom_net_wm_window_type_utility ||
- atoms[i] == compositor->atom_net_wm_window_type_splash ||
- atoms[i] == compositor->atom_net_wm_window_type_dropdown_menu ||
- atoms[i] == compositor->atom_net_wm_window_type_tooltip)
- {
- type_atom = atoms[i];
- break;
- }
- }
-
- meta_XFree (atoms);
-
- if (type_atom == compositor->atom_net_wm_window_type_dnd)
- cw->type = META_COMP_WINDOW_DND;
- else if (type_atom == compositor->atom_net_wm_window_type_desktop)
- cw->type = META_COMP_WINDOW_DESKTOP;
- else if (type_atom == compositor->atom_net_wm_window_type_dock)
- cw->type = META_COMP_WINDOW_DOCK;
- else if (type_atom == compositor->atom_net_wm_window_type_menu)
- cw->type = META_COMP_WINDOW_MENU;
- else if (type_atom == compositor->atom_net_wm_window_type_dropdown_menu)
- cw->type = META_COMP_WINDOW_DROP_DOWN_MENU;
- else if (type_atom == compositor->atom_net_wm_window_type_tooltip)
- cw->type = META_COMP_WINDOW_TOOLTIP;
- else
- cw->type = META_COMP_WINDOW_NORMAL;
-
-/* meta_verbose ("Window is %d\n", cw->type); */
-}
-
-/* Must be called with an error trap in place */
-static void
-add_win (MetaScreen *screen,
- MetaWindow *window,
- Window xwindow)
-{
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- MetaCompScreen *info = meta_screen_get_compositor_data (screen);
- MetaCompWindow *cw;
- gulong event_mask;
-
- if (info == NULL)
- return;
-
- if (xwindow == info->output)
- return;
-
- cw = g_new0 (MetaCompWindow, 1);
- cw->screen = screen;
- cw->window = window;
- cw->id = xwindow;
-
- if (!XGetWindowAttributes (xdisplay, xwindow, &cw->attrs))
- {
- g_free (cw);
- return;
- }
- get_window_type (display, cw);
-
- /* If Metacity has decided not to manage this window then the input events
- won't have been set on the window */
- event_mask = cw->attrs.your_event_mask | PropertyChangeMask;
-
- XSelectInput (xdisplay, xwindow, event_mask);
-
-
-#ifdef HAVE_NAME_WINDOW_PIXMAP
- cw->back_pixmap = None;
- cw->shaded_back_pixmap = None;
-#endif
-
- cw->damaged = FALSE;
- cw->shaped = is_shaped (display, xwindow);
-
- if (cw->attrs.class == InputOnly)
- cw->damage = None;
- else
- cw->damage = XDamageCreate (xdisplay, xwindow, XDamageReportNonEmpty);
-
- cw->alpha_pict = None;
- cw->shadow_pict = None;
- cw->border_size = None;
- cw->extents = None;
- cw->shadow = None;
- cw->shadow_dx = 0;
- cw->shadow_dy = 0;
- cw->shadow_width = 0;
- cw->shadow_height = 0;
-
- if (window && meta_window_has_focus (window))
- cw->shadow_type = META_SHADOW_LARGE;
- else
- cw->shadow_type = META_SHADOW_MEDIUM;
-
- cw->opacity = OPAQUE;
-
- cw->border_clip = None;
-
- determine_mode (display, screen, cw);
- cw->needs_shadow = window_has_shadow (cw);
-
- /* Only add the window to the list of docks if it needs a shadow */
- if (cw->type == META_COMP_WINDOW_DOCK && cw->needs_shadow)
- {
- meta_verbose ("Appending %p to dock windows\n", cw);
- info->dock_windows = g_slist_append (info->dock_windows, cw);
- }
-
- /* Add this to the list at the top of the stack
- before it is mapped so that map_win can find it again */
- info->windows = g_list_prepend (info->windows, cw);
- g_hash_table_insert (info->windows_by_xid, (gpointer) xwindow, cw);
-
- if (cw->attrs.map_state == IsViewable)
- map_win (display, screen, xwindow);
-}
-
-static void
-destroy_win (MetaDisplay *display,
- Window xwindow,
- gboolean gone)
-{
- MetaScreen *screen;
- MetaCompScreen *info;
- MetaCompWindow *cw;
-
- cw = find_window_in_display (display, xwindow);
-
- if (cw == NULL)
- return;
-
- screen = cw->screen;
-
- if (cw->extents != None)
- {
- dump_xserver_region ("destroy_win", display, cw->extents);
- add_damage (screen, cw->extents);
- cw->extents = None;
- }
-
- info = meta_screen_get_compositor_data (screen);
- if (info != NULL)
- {
- info->windows = g_list_remove (info->windows, (gconstpointer) cw);
- g_hash_table_remove (info->windows_by_xid, (gpointer) xwindow);
- }
-
- free_win (cw, TRUE);
-}
-
-static void
-restack_win (MetaCompWindow *cw,
- Window above)
-{
- MetaScreen *screen;
- MetaCompScreen *info;
- Window previous_above;
- GList *sibling, *next;
-
- screen = cw->screen;
- info = meta_screen_get_compositor_data (screen);
-
- if (info == NULL)
- {
- return;
- }
-
- sibling = g_list_find (info->windows, (gconstpointer) cw);
- next = g_list_next (sibling);
- previous_above = None;
-
- if (next)
- {
- MetaCompWindow *ncw = (MetaCompWindow *) next->data;
- previous_above = ncw->id;
- }
-
- /* If above is set to None, the window whose state was changed is on
- * the bottom of the stack with respect to sibling.
- */
- if (above == None)
- {
- /* Insert at bottom of window stack */
- info->windows = g_list_delete_link (info->windows, sibling);
- info->windows = g_list_append (info->windows, cw);
- }
- else if (previous_above != above)
- {
- GList *index;
-
- for (index = info->windows; index; index = index->next) {
- MetaCompWindow *cw2 = (MetaCompWindow *) index->data;
- if (cw2->id == above)
- break;
- }
-
- if (index != NULL)
- {
- info->windows = g_list_delete_link (info->windows, sibling);
- info->windows = g_list_insert_before (info->windows, index, cw);
- }
- }
-}
-
-static void
-resize_win (MetaCompWindow *cw,
- int x,
- int y,
- int width,
- int height,
- int border_width,
- gboolean override_redirect)
-{
- MetaScreen *screen = cw->screen;
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- MetaCompScreen *info = meta_screen_get_compositor_data (screen);
- XserverRegion damage;
- gboolean debug;
-
- debug = DISPLAY_COMPOSITOR (display)->debug;
-
- if (cw->extents)
- {
- damage = XFixesCreateRegion (xdisplay, NULL, 0);
- XFixesCopyRegion (xdisplay, damage, cw->extents);
- }
- else
- {
- damage = None;
- if (debug)
- fprintf (stderr, "no extents to damage !\n");
- }
-
- /* { // Damage whole screen each time ! ;-)
- XRectangle r;
-
- r.x = 0;
- r.y = 0;
- meta_screen_get_size (screen, &r.width, &r.height);
- fprintf (stderr, "Damage whole screen %d,%d (%d %d)\n",
- r.x, r.y, r.width, r.height);
-
- damage = XFixesCreateRegion (xdisplay, &r, 1);
- } */
-
- cw->attrs.x = x;
- cw->attrs.y = y;
-
- if (cw->attrs.width != width || cw->attrs.height != height)
- {
-#ifdef HAVE_NAME_WINDOW_PIXMAP
- if (have_name_window_pixmap (display))
- {
- if (cw->shaded_back_pixmap)
- {
- XFreePixmap (xdisplay, cw->shaded_back_pixmap);
- cw->shaded_back_pixmap = None;
- }
-
- if (cw->back_pixmap)
- {
- /* If the window is shaded, we store the old backing pixmap
- so we can return a proper image of the window */
- if (cw->window && meta_window_is_shaded (cw->window))
- {
- cw->shaded_back_pixmap = cw->back_pixmap;
- cw->back_pixmap = None;
- }
- else
- {
- XFreePixmap (xdisplay, cw->back_pixmap);
- cw->back_pixmap = None;
- }
- }
- }
-#endif
- if (cw->picture)
- {
- XRenderFreePicture (xdisplay, cw->picture);
- cw->picture = None;
- }
-
- if (cw->shadow)
- {
- XRenderFreePicture (xdisplay, cw->shadow);
- cw->shadow = None;
- }
- }
-
- cw->attrs.width = width;
- cw->attrs.height = height;
- cw->attrs.border_width = border_width;
- cw->attrs.override_redirect = override_redirect;
-
- if (cw->extents)
- XFixesDestroyRegion (xdisplay, cw->extents);
-
- cw->extents = win_extents (cw);
-
- if (damage)
- {
- if (debug)
- fprintf (stderr, "Inexplicable intersection with new extents!\n");
-
- XFixesUnionRegion (xdisplay, damage, damage, cw->extents);
- }
- else
- {
- damage = XFixesCreateRegion (xdisplay, NULL, 0);
- XFixesCopyRegion (xdisplay, damage, cw->extents);
- }
-
- dump_xserver_region ("resize_win", display, damage);
- add_damage (screen, damage);
-
- if (info != NULL)
- {
- info->clip_changed = TRUE;
- }
-}
-
-/* event processors must all be called with an error trap in place */
-static void
-process_circulate_notify (MetaCompositorXRender *compositor,
- XCirculateEvent *event)
-{
- MetaCompWindow *cw = find_window_in_display (compositor->display,
- event->window);
- MetaCompWindow *top;
- MetaCompScreen *info;
- MetaScreen *screen;
- GList *first;
- Window above;
-
- if (!cw)
- return;
-
- screen = cw->screen;
- info = meta_screen_get_compositor_data (screen);
- first = info->windows;
- top = (MetaCompWindow *) first->data;
-
- if ((event->place == PlaceOnTop) && top)
- above = top->id;
- else
- above = None;
- restack_win (cw, above);
-
- if (info != NULL)
- {
- info->clip_changed = TRUE;
- }
-
-#ifdef USE_IDLE_REPAINT
- add_repair (compositor->display);
-#endif
-}
-
-static void
-process_configure_notify (MetaCompositorXRender *compositor,
- XConfigureEvent *event)
-{
- MetaDisplay *display = compositor->display;
- Display *xdisplay = meta_display_get_xdisplay (display);
- MetaCompWindow *cw = find_window_in_display (display, event->window);
-
- if (cw)
- {
-#if 0
- int x = -1, y = -1, width = -1, height = -1;
- int ex = -1, ey = -1, ewidth = -1, eheight = -1;
- MetaRectangle *rect;
-
- if (cw->window) {
- rect = meta_window_get_rect (cw->window);
- x = rect->x;
- y = rect->y;
- width = rect->width;
- height = rect->height;
- }
- fprintf (stderr, "configure notify xy (%d %d) -> (%d %d), wh (%d %d) -> (%d %d)\n",
- x, y, event->x, event->y,
- width, height, event->width, event->height);
-#endif
-
- if (compositor->debug)
- {
- fprintf (stderr, "configure notify %d %d %d\n", cw->damaged,
- cw->shaped, cw->needs_shadow);
- dump_xserver_region ("\textents", display, cw->extents);
- fprintf (stderr, "\txy (%d %d), wh (%d %d)\n",
- event->x, event->y, event->width, event->height);
- }
-
- restack_win (cw, event->above);
- resize_win (cw, event->x, event->y, event->width, event->height,
- event->border_width, event->override_redirect);
- }
- else
- {
- MetaScreen *screen;
- MetaCompScreen *info;
-
- /* Might be the root window? */
- screen = meta_display_screen_for_root (display, event->window);
- if (screen == NULL)
- return;
-
- info = meta_screen_get_compositor_data (screen);
- if (info != NULL && info->root_buffer)
- {
- XRenderFreePicture (xdisplay, info->root_buffer);
- info->root_buffer = None;
- }
-
- damage_screen (screen);
- }
-}
-
-static void
-process_property_notify (MetaCompositorXRender *compositor,
- XPropertyEvent *event)
-{
- MetaDisplay *display = compositor->display;
- Display *xdisplay = meta_display_get_xdisplay (display);
- MetaScreen *screen;
- int p;
- Atom background_atoms[2];
-
- /* Check for the background property changing */
- background_atoms[0] = compositor->atom_x_root_pixmap;
- background_atoms[1] = compositor->atom_x_set_root;
-
- for (p = 0; p < 2; p++)
- {
- if (event->atom == background_atoms[p])
- {
- screen = meta_display_screen_for_root (display, event->window);
- if (screen)
- {
- MetaCompScreen *info = meta_screen_get_compositor_data (screen);
- Window xroot = meta_screen_get_xroot (screen);
-
- if (info != NULL && info->root_tile)
- {
- XClearArea (xdisplay, xroot, 0, 0, 0, 0, TRUE);
- XRenderFreePicture (xdisplay, info->root_tile);
- info->root_tile = None;
-
- /* Damage the whole screen as we may need to redraw the
- background ourselves */
- damage_screen (screen);
-#ifdef USE_IDLE_REPAINT
- add_repair (display);
-#endif
-
- return;
- }
- }
- }
- }
-
- /* Check for the opacity changing */
- if (event->atom == compositor->atom_net_wm_window_opacity)
- {
- MetaCompWindow *cw = find_window_in_display (display, event->window);
- gulong value;
-
- if (!cw)
- {
- /* Applications can set this for their toplevel windows, so
- * this must be propagated to the window managed by the compositor
- */
- cw = find_window_for_child_window_in_display (display, event->window);
- }
-
- if (!cw)
- return;
-
- if (meta_prop_get_cardinal (display, event->window,
- compositor->atom_net_wm_window_opacity,
- &value) == FALSE)
- value = OPAQUE;
-
- cw->opacity = (guint)value;
- determine_mode (display, cw->screen, cw);
- cw->needs_shadow = window_has_shadow (cw);
-
- if (cw->shadow)
- {
- XRenderFreePicture (xdisplay, cw->shadow);
- cw->shadow = None;
- }
-
- if (cw->extents)
- XFixesDestroyRegion (xdisplay, cw->extents);
- cw->extents = win_extents (cw);
-
- cw->damaged = TRUE;
-#ifdef USE_IDLE_REPAINT
- add_repair (display);
-#endif
-
- return;
- }
-
- if (event->atom == compositor->atom_net_wm_window_type) {
- MetaCompWindow *cw = find_window_in_display (display, event->window);
-
- if (!cw)
- return;
-
- get_window_type (display, cw);
- cw->needs_shadow = window_has_shadow (cw);
- return;
- }
-}
-
-static void
-expose_area (MetaScreen *screen,
- XRectangle *rects,
- int nrects)
-{
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- XserverRegion region;
-
- region = XFixesCreateRegion (xdisplay, rects, nrects);
-
- dump_xserver_region ("expose_area", display, region);
- add_damage (screen, region);
-}
-
-static void
-process_expose (MetaCompositorXRender *compositor,
- XExposeEvent *event)
-{
- MetaCompWindow *cw = find_window_in_display (compositor->display,
- event->window);
- MetaScreen *screen = NULL;
- XRectangle rect[1];
- int origin_x = 0, origin_y = 0;
-
- if (cw != NULL)
- {
- screen = cw->screen;
- origin_x = cw->attrs.x; /* + cw->attrs.border_width; ? */
- origin_y = cw->attrs.y; /* + cw->attrs.border_width; ? */
- }
- else
- {
- screen = meta_display_screen_for_root (compositor->display,
- event->window);
- if (screen == NULL)
- return;
- }
-
- rect[0].x = event->x + origin_x;
- rect[0].y = event->y + origin_y;
- rect[0].width = event->width;
- rect[0].height = event->height;
-
- expose_area (screen, rect, 1);
-}
-
-static void
-process_unmap (MetaCompositorXRender *compositor,
- XUnmapEvent *event)
-{
- MetaCompWindow *cw;
-
- if (event->from_configure)
- {
- /* Ignore unmap caused by parent's resize */
- return;
- }
-
-
- cw = find_window_in_display (compositor->display, event->window);
- if (cw)
- unmap_win (compositor->display, cw->screen, event->window);
-}
-
-static void
-process_map (MetaCompositorXRender *compositor,
- XMapEvent *event)
-{
- MetaCompWindow *cw = find_window_in_display (compositor->display,
- event->window);
-
- if (cw)
- map_win (compositor->display, cw->screen, event->window);
-}
-
-static void
-process_reparent (MetaCompositorXRender *compositor,
- XReparentEvent *event,
- MetaWindow *window)
-{
- MetaScreen *screen;
-
- screen = meta_display_screen_for_root (compositor->display, event->parent);
- if (screen != NULL)
- add_win (screen, window, event->window);
- else
- destroy_win (compositor->display, event->window, FALSE);
-}
-
-static void
-process_create (MetaCompositorXRender *compositor,
- XCreateWindowEvent *event,
- MetaWindow *window)
-{
- MetaScreen *screen;
- /* We are only interested in top level windows, others will
- be caught by normal metacity functions */
-
- screen = meta_display_screen_for_root (compositor->display, event->parent);
- if (screen == NULL)
- return;
-
- if (!find_window_in_display (compositor->display, event->window))
- add_win (screen, window, event->window);
-}
-
-static void
-process_destroy (MetaCompositorXRender *compositor,
- XDestroyWindowEvent *event)
-{
- destroy_win (compositor->display, event->window, FALSE);
-}
-
-static void
-process_damage (MetaCompositorXRender *compositor,
- XDamageNotifyEvent *event)
-{
- MetaCompWindow *cw = find_window_in_display (compositor->display,
- event->drawable);
- if (cw == NULL)
- return;
-
- repair_win (cw);
-
-#ifdef USE_IDLE_REPAINT
- if (event->more == FALSE)
- add_repair (compositor->display);
-#endif
-}
-
-static void
-process_shape (MetaCompositorXRender *compositor,
- XShapeEvent *event)
-{
- MetaCompWindow *cw = find_window_in_display (compositor->display,
- event->window);
-
- if (cw == NULL)
- return;
-
- if (event->kind == ShapeBounding)
- {
- if (!event->shaped && cw->shaped)
- cw->shaped = FALSE;
-
- resize_win (cw, cw->attrs.x, cw->attrs.y,
- event->width + event->x, event->height + event->y,
- cw->attrs.border_width, cw->attrs.override_redirect);
-
- if (event->shaped && !cw->shaped)
- cw->shaped = TRUE;
- }
-}
-
-static int
-timeout_debug (MetaCompositorXRender *compositor)
-{
- compositor->show_redraw = (g_getenv ("METACITY_DEBUG_REDRAWS") != NULL);
- compositor->debug = (g_getenv ("METACITY_DEBUG_COMPOSITOR") != NULL);
-
- return FALSE;
-}
-
-static void
-xrender_add_window (MetaCompositor *compositor,
- MetaWindow *window,
- Window xwindow,
- XWindowAttributes *attrs)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- MetaCompositorXRender *xrc = (MetaCompositorXRender *) compositor;
- MetaScreen *screen = meta_screen_for_x_screen (attrs->screen);
-
- meta_error_trap_push (xrc->display);
- add_win (screen, window, xwindow);
- meta_error_trap_pop (xrc->display, FALSE);
-#endif
-}
-
-static void
-xrender_remove_window (MetaCompositor *compositor,
- Window xwindow)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
-#endif
-}
-
-static void
-show_overlay_window (MetaScreen *screen,
- Window cow)
-{
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
-
-#ifdef HAVE_COW
- if (have_cow (display))
- {
- XserverRegion region;
-
- region = XFixesCreateRegion (xdisplay, NULL, 0);
-
- XFixesSetWindowShapeRegion (xdisplay, cow, ShapeBounding, 0, 0, 0);
- XFixesSetWindowShapeRegion (xdisplay, cow, ShapeInput, 0, 0, region);
-
- XFixesDestroyRegion (xdisplay, region);
-
- damage_screen (screen);
- }
-#endif
-}
-
-static void
-hide_overlay_window (MetaScreen *screen,
- Window cow)
-{
-#ifdef HAVE_COW
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- XserverRegion region;
-
- region = XFixesCreateRegion (xdisplay, NULL, 0);
- XFixesSetWindowShapeRegion (xdisplay, cow, ShapeBounding, 0, 0, region);
- XFixesDestroyRegion (xdisplay, region);
-#endif
-}
-
-static Window
-get_output_window (MetaScreen *screen)
-{
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- Window output, xroot;
-
- xroot = meta_screen_get_xroot (screen);
-
-#ifdef HAVE_COW
- if (have_cow (display))
- {
- output = XCompositeGetOverlayWindow (xdisplay, xroot);
- XSelectInput (xdisplay, output, ExposureMask);
- }
- else
-#endif
- {
- output = xroot;
- }
-
- return output;
-}
-
-static void
-xrender_manage_screen (MetaCompositor *compositor,
- MetaScreen *screen)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- MetaCompScreen *info;
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- XRenderPictureAttributes pa;
- XRenderPictFormat *visual_format;
- int screen_number = meta_screen_get_screen_number (screen);
- Window xroot = meta_screen_get_xroot (screen);
-
- /* Check if the screen is already managed */
- if (meta_screen_get_compositor_data (screen))
- return;
-
- gdk_error_trap_push ();
- XCompositeRedirectSubwindows (xdisplay, xroot, CompositeRedirectManual);
- XSync (xdisplay, FALSE);
-
- if (gdk_error_trap_pop ())
- {
- g_warning ("Another compositing manager is running on screen %i",
- screen_number);
- return;
- }
-
- info = g_new0 (MetaCompScreen, 1);
- info->screen = screen;
-
- meta_screen_set_compositor_data (screen, info);
-
- visual_format = XRenderFindVisualFormat (xdisplay, DefaultVisual (xdisplay,
- screen_number));
- if (!visual_format)
- {
- g_warning ("Cannot find visual format on screen %i", screen_number);
- return;
- }
-
- info->output = get_output_window (screen);
-
- pa.subwindow_mode = IncludeInferiors;
- info->root_picture = XRenderCreatePicture (xdisplay, info->output,
- visual_format,
- CPSubwindowMode, &pa);
- if (info->root_picture == None)
- {
- g_warning ("Cannot create root picture on screen %i", screen_number);
- return;
- }
-
- info->root_buffer = None;
- info->black_picture = solid_picture (display, screen, TRUE, 1, 0, 0, 0);
-
- info->root_tile = None;
- info->all_damage = None;
-
- info->windows = NULL;
- info->windows_by_xid = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- info->focus_window = meta_display_get_focus_window (display);
-
- info->compositor_active = TRUE;
- info->overlays = 0;
- info->clip_changed = TRUE;
-
- info->have_shadows = (g_getenv("META_DEBUG_NO_SHADOW") == NULL);
- if (info->have_shadows)
- {
- meta_verbose ("Enabling shadows\n");
- generate_shadows (info);
- }
- else
- meta_verbose ("Disabling shadows\n");
-
- XClearArea (xdisplay, info->output, 0, 0, 0, 0, TRUE);
-
- meta_screen_set_cm_selection (screen);
-
- /* Now we're up and running we can show the output if needed */
- show_overlay_window (screen, info->output);
-#endif
-}
-
-static void
-xrender_unmanage_screen (MetaCompositor *compositor,
- MetaScreen *screen)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- MetaCompScreen *info;
- Window xroot = meta_screen_get_xroot (screen);
- GList *index;
-
- info = meta_screen_get_compositor_data (screen);
-
- /* This screen isn't managed */
- if (info == NULL)
- return;
-
- hide_overlay_window (screen, info->output);
-
- /* Destroy the windows */
- for (index = info->windows; index; index = index->next)
- {
- MetaCompWindow *cw = (MetaCompWindow *) index->data;
- free_win (cw, TRUE);
- }
- g_list_free (info->windows);
- g_hash_table_destroy (info->windows_by_xid);
-
- if (info->root_picture)
- XRenderFreePicture (xdisplay, info->root_picture);
-
- if (info->black_picture)
- XRenderFreePicture (xdisplay, info->black_picture);
-
- if (info->have_shadows)
- {
- int i;
-
- for (i = 0; i < LAST_SHADOW_TYPE; i++)
- g_free (info->shadows[i]->gaussian_map);
- }
-
- XCompositeUnredirectSubwindows (xdisplay, xroot,
- CompositeRedirectManual);
- meta_screen_unset_cm_selection (screen);
-
-#ifdef HAVE_COW
- XCompositeReleaseOverlayWindow (xdisplay, info->output);
-#endif
-
- g_free (info);
-
- meta_screen_set_compositor_data (screen, NULL);
-#endif
-}
-
-static void
-xrender_set_updates (MetaCompositor *compositor,
- MetaWindow *window,
- gboolean updates)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
-
-#endif
-}
-
-static void
-xrender_destroy (MetaCompositor *compositor)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- g_free (compositor);
-#endif
-}
-
-#if 0
-/* Taking these out because they're empty and never called, and the
- * compiler complains -- tthurman
- */
-
-static void
-xrender_begin_move (MetaCompositor *compositor,
- MetaWindow *window,
- MetaRectangle *initial,
- int grab_x,
- int grab_y)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
-#endif
-}
-
-static void
-xrender_update_move (MetaCompositor *compositor,
- MetaWindow *window,
- int x,
- int y)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
-#endif
-}
-
-static void
-xrender_end_move (MetaCompositor *compositor,
- MetaWindow *window)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
-#endif
-}
-
-static void
-xrender_free_window (MetaCompositor *compositor,
- MetaWindow *window)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- /* FIXME: When an undecorated window is hidden this is called,
- but the window does not get readded if it is subsequentally shown again
- See http://bugzilla.gnome.org/show_bug.cgi?id=504876
-
- I don't *think* theres any need for this call anyway, leaving it out
- does not seem to cause any side effects so far, but I should check with
- someone who understands more. */
- /* destroy_win (compositor->display, window->xwindow, FALSE); */
-#endif
-}
-#endif /* 0 */
-
-static void
-xrender_process_event (MetaCompositor *compositor,
- XEvent *event,
- MetaWindow *window)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- MetaCompositorXRender *xrc = (MetaCompositorXRender *) compositor;
- /*
- * This trap is so that none of the compositor functions cause
- * X errors. This is really a hack, but I'm afraid I don't understand
- * enough about Metacity/X to know how else you are supposed to do it
- */
- meta_error_trap_push (xrc->display);
- switch (event->type)
- {
- case CirculateNotify:
- process_circulate_notify (xrc, (XCirculateEvent *) event);
- break;
-
- case ConfigureNotify:
- process_configure_notify (xrc, (XConfigureEvent *) event);
- break;
-
- case PropertyNotify:
- process_property_notify (xrc, (XPropertyEvent *) event);
- break;
-
- case Expose:
- process_expose (xrc, (XExposeEvent *) event);
- break;
-
- case UnmapNotify:
- process_unmap (xrc, (XUnmapEvent *) event);
- break;
-
- case MapNotify:
- process_map (xrc, (XMapEvent *) event);
- break;
-
- case ReparentNotify:
- process_reparent (xrc, (XReparentEvent *) event, window);
- break;
-
- case CreateNotify:
- process_create (xrc, (XCreateWindowEvent *) event, window);
- break;
-
- case DestroyNotify:
- process_destroy (xrc, (XDestroyWindowEvent *) event);
- break;
-
- default:
- if (event->type == meta_display_get_damage_event_base (xrc->display) + XDamageNotify)
- process_damage (xrc, (XDamageNotifyEvent *) event);
-#ifdef HAVE_SHAPE
- else if (event->type == meta_display_get_shape_event_base (xrc->display) + ShapeNotify)
- process_shape (xrc, (XShapeEvent *) event);
-#endif /* HAVE_SHAPE */
- else
- {
- meta_error_trap_pop (xrc->display, FALSE);
- return;
- }
- break;
- }
-
- meta_error_trap_pop (xrc->display, FALSE);
-#ifndef USE_IDLE_REPAINT
- repair_display (xrc->display);
-#endif
-
- return;
-#endif
-}
-
-static Pixmap
-xrender_get_window_pixmap (MetaCompositor *compositor,
- MetaWindow *window)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- MetaCompWindow *cw = NULL;
- MetaScreen *screen = meta_window_get_screen (window);
- MetaFrame *frame = meta_window_get_frame (window);
-
- cw = find_window_for_screen (screen, frame ? meta_frame_get_xwindow (frame) :
- meta_window_get_xwindow (window));
- if (cw == NULL)
- return None;
-
-#ifdef HAVE_NAME_WINDOW_PIXMAP
- if (have_name_window_pixmap (meta_window_get_display (window)))
- {
- if (meta_window_is_shaded (window))
- return cw->shaded_back_pixmap;
- else
- return cw->back_pixmap;
- }
- else
-#endif
- return None;
-#endif
-}
-
-static void
-xrender_set_active_window (MetaCompositor *compositor,
- MetaScreen *screen,
- MetaWindow *window)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- MetaCompositorXRender *xrc = (MetaCompositorXRender *) compositor;
- MetaDisplay *display;
- Display *xdisplay;
- MetaCompWindow *old_focus = NULL, *new_focus = NULL;
- MetaCompScreen *info = NULL;
- MetaWindow *old_focus_win = NULL;
-
- if (compositor == NULL)
- return;
-
- display = xrc->display;
- xdisplay = meta_display_get_xdisplay (display);
- info = meta_screen_get_compositor_data (screen);
-
- if (info != NULL)
- {
- old_focus_win = info->focus_window;
- }
-
- if (old_focus_win)
- {
- MetaFrame *f = meta_window_get_frame (old_focus_win);
-
- old_focus = find_window_for_screen (screen,
- f ? meta_frame_get_xwindow (f) :
- meta_window_get_xwindow (old_focus_win));
- }
-
- if (window)
- {
- MetaFrame *f = meta_window_get_frame (window);
- new_focus = find_window_for_screen (screen,
- f ? meta_frame_get_xwindow (f) :
- meta_window_get_xwindow (window));
- }
-
- if (info != NULL)
- {
- info->focus_window = window;
- }
-
- if (old_focus)
- {
- XserverRegion damage;
-
- /* Tear down old shadows */
- old_focus->shadow_type = META_SHADOW_MEDIUM;
- determine_mode (display, screen, old_focus);
- old_focus->needs_shadow = window_has_shadow (old_focus);
-
- if (old_focus->attrs.map_state == IsViewable)
- {
- if (old_focus->shadow)
- {
- XRenderFreePicture (xdisplay, old_focus->shadow);
- old_focus->shadow = None;
- }
-
- if (old_focus->extents)
- {
- damage = XFixesCreateRegion (xdisplay, NULL, 0);
- XFixesCopyRegion (xdisplay, damage, old_focus->extents);
- XFixesDestroyRegion (xdisplay, old_focus->extents);
- }
- else
- damage = None;
-
- /* Build new extents */
- old_focus->extents = win_extents (old_focus);
-
- if (damage)
- XFixesUnionRegion (xdisplay, damage, damage, old_focus->extents);
- else
- {
- damage = XFixesCreateRegion (xdisplay, NULL, 0);
- XFixesCopyRegion (xdisplay, damage, old_focus->extents);
- }
-
- dump_xserver_region ("resize_win", display, damage);
- add_damage (screen, damage);
-
- if (info != NULL)
- {
- info->clip_changed = TRUE;
- }
- }
- }
-
- if (new_focus)
- {
- XserverRegion damage;
-
- new_focus->shadow_type = META_SHADOW_LARGE;
- determine_mode (display, screen, new_focus);
- new_focus->needs_shadow = window_has_shadow (new_focus);
-
- if (new_focus->shadow)
- {
- XRenderFreePicture (xdisplay, new_focus->shadow);
- new_focus->shadow = None;
- }
-
- if (new_focus->extents)
- {
- damage = XFixesCreateRegion (xdisplay, NULL, 0);
- XFixesCopyRegion (xdisplay, damage, new_focus->extents);
- XFixesDestroyRegion (xdisplay, new_focus->extents);
- }
- else
- damage = None;
-
- /* Build new extents */
- new_focus->extents = win_extents (new_focus);
-
- if (damage)
- XFixesUnionRegion (xdisplay, damage, damage, new_focus->extents);
- else
- {
- damage = XFixesCreateRegion (xdisplay, NULL, 0);
- XFixesCopyRegion (xdisplay, damage, new_focus->extents);
- }
-
- dump_xserver_region ("resize_win", display, damage);
- add_damage (screen, damage);
-
- if (info != NULL)
- {
- info->clip_changed = TRUE;
- }
- }
-#ifdef USE_IDLE_REPAINT
- add_repair (display);
-#endif
-#endif
-}
-
-static MetaCompositor comp_info = {
- xrender_destroy,
- xrender_manage_screen,
- xrender_unmanage_screen,
- xrender_add_window,
- xrender_remove_window,
- xrender_set_updates,
- xrender_process_event,
- xrender_get_window_pixmap,
- xrender_set_active_window
-};
-
-MetaCompositor *
-meta_compositor_xrender_new (MetaDisplay *display)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- char *atom_names[] = {
- "_XROOTPMAP_ID",
- "_XSETROOT_ID",
- "_NET_WM_WINDOW_OPACITY",
- "_NET_WM_WINDOW_TYPE_DND",
- "_NET_WM_WINDOW_TYPE",
- "_NET_WM_WINDOW_TYPE_DESKTOP",
- "_NET_WM_WINDOW_TYPE_DOCK",
- "_NET_WM_WINDOW_TYPE_MENU",
- "_NET_WM_WINDOW_TYPE_DIALOG",
- "_NET_WM_WINDOW_TYPE_NORMAL",
- "_NET_WM_WINDOW_TYPE_UTILITY",
- "_NET_WM_WINDOW_TYPE_SPLASH",
- "_NET_WM_WINDOW_TYPE_TOOLBAR",
- "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU",
- "_NET_WM_WINDOW_TYPE_TOOLTIP"
- };
- Atom atoms[G_N_ELEMENTS(atom_names)];
- MetaCompositorXRender *xrc;
- MetaCompositor *compositor;
- Display *xdisplay = meta_display_get_xdisplay (display);
-
- xrc = g_new (MetaCompositorXRender, 1);
- xrc->compositor = comp_info;
-
- compositor = (MetaCompositor *) xrc;
-
- xrc->display = display;
-
- meta_verbose ("Creating %d atoms\n", (int) G_N_ELEMENTS (atom_names));
- XInternAtoms (xdisplay, atom_names, G_N_ELEMENTS (atom_names),
- False, atoms);
-
- xrc->atom_x_root_pixmap = atoms[0];
- xrc->atom_x_set_root = atoms[1];
- xrc->atom_net_wm_window_opacity = atoms[2];
- xrc->atom_net_wm_window_type_dnd = atoms[3];
- xrc->atom_net_wm_window_type = atoms[4];
- xrc->atom_net_wm_window_type_desktop = atoms[5];
- xrc->atom_net_wm_window_type_dock = atoms[6];
- xrc->atom_net_wm_window_type_menu = atoms[7];
- xrc->atom_net_wm_window_type_dialog = atoms[8];
- xrc->atom_net_wm_window_type_normal = atoms[9];
- xrc->atom_net_wm_window_type_utility = atoms[10];
- xrc->atom_net_wm_window_type_splash = atoms[11];
- xrc->atom_net_wm_window_type_toolbar = atoms[12];
- xrc->atom_net_wm_window_type_dropdown_menu = atoms[13];
- xrc->atom_net_wm_window_type_tooltip = atoms[14];
-
-#ifdef USE_IDLE_REPAINT
- meta_verbose ("Using idle repaint\n");
- xrc->repaint_id = 0;
-#endif
-
- xrc->enabled = TRUE;
- g_timeout_add (2000, (GSourceFunc) timeout_debug, xrc);
-
- return compositor;
-#else
- return NULL;
-#endif
-}
-
-#endif /* HAVE_COMPOSITE_EXTENSIONS */
-
diff --git a/src/compositor/compositor-xrender.h b/src/compositor/compositor-xrender.h
deleted file mode 100644
index 5c8a36c0..00000000
--- a/src/compositor/compositor-xrender.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2007 Iain Holmes
- * Based on xcompmgr - (c) 2003 Keith Packard
- * xfwm4 - (c) 2005-2007 Olivier Fourdan
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_COMPOSITOR_XRENDER_H_
-#define META_COMPOSITOR_XRENDER_H_
-
-#include "types.h"
-
-MetaCompositor *meta_compositor_xrender_new (MetaDisplay *display);
-
-#endif
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
deleted file mode 100644
index 975bf341..00000000
--- a/src/compositor/compositor.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2008 Iain Holmes
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include "compositor-private.h"
-#include "compositor-xrender.h"
-
-MetaCompositor *
-meta_compositor_new (MetaDisplay *display)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- /* At some point we would have a way to select between backends */
- return meta_compositor_xrender_new (display);
-#else
- return NULL;
-#endif
-}
-
-void
-meta_compositor_destroy (MetaCompositor *compositor)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- if (compositor && compositor->destroy)
- compositor->destroy (compositor);
-#endif
-}
-
-void
-meta_compositor_add_window (MetaCompositor *compositor,
- MetaWindow *window,
- Window xwindow,
- XWindowAttributes *attrs)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- if (compositor && compositor->add_window)
- compositor->add_window (compositor, window, xwindow, attrs);
-#endif
-}
-
-void
-meta_compositor_remove_window (MetaCompositor *compositor,
- Window xwindow)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- if (compositor && compositor->remove_window)
- compositor->remove_window (compositor, xwindow);
-#endif
-}
-
-void
-meta_compositor_manage_screen (MetaCompositor *compositor,
- MetaScreen *screen)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- if (compositor && compositor->manage_screen)
- compositor->manage_screen (compositor, screen);
-#endif
-}
-
-void
-meta_compositor_unmanage_screen (MetaCompositor *compositor,
- MetaScreen *screen)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- if (compositor && compositor->unmanage_screen)
- compositor->unmanage_screen (compositor, screen);
-#endif
-}
-
-void
-meta_compositor_set_updates (MetaCompositor *compositor,
- MetaWindow *window,
- gboolean updates)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- if (compositor && compositor->set_updates)
- compositor->set_updates (compositor, window, updates);
-#endif
-}
-
-void
-meta_compositor_process_event (MetaCompositor *compositor,
- XEvent *event,
- MetaWindow *window)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- if (compositor && compositor->process_event)
- compositor->process_event (compositor, event, window);
-#endif
-}
-
-Pixmap
-meta_compositor_get_window_pixmap (MetaCompositor *compositor,
- MetaWindow *window)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- if (compositor && compositor->get_window_pixmap)
- return compositor->get_window_pixmap (compositor, window);
- else
- return None;
-#else
- return None;
-#endif
-}
-
-void
-meta_compositor_set_active_window (MetaCompositor *compositor,
- MetaScreen *screen,
- MetaWindow *window)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- if (compositor && compositor->set_active_window)
- compositor->set_active_window (compositor, screen, window);
-#endif
-}
-
-/* These functions are unused at the moment */
-void meta_compositor_begin_move (MetaCompositor *compositor,
- MetaWindow *window,
- MetaRectangle *initial,
- int grab_x,
- int grab_y)
-{
-}
-
-void meta_compositor_update_move (MetaCompositor *compositor,
- MetaWindow *window,
- int x,
- int y)
-{
-}
-
-void meta_compositor_end_move (MetaCompositor *compositor,
- MetaWindow *window)
-{
-}
-
-void meta_compositor_free_window (MetaCompositor *compositor,
- MetaWindow *window)
-{
-}
diff --git a/src/core/async-getprop.c b/src/core/async-getprop.c
deleted file mode 100644
index 31b0edc3..00000000
--- a/src/core/async-getprop.c
+++ /dev/null
@@ -1,680 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Asynchronous X property getting hack */
-
-/*
- * Copyright (C) 2002 Havoc Pennington
- * Copyright (C) 1986, 1998 The Open Group
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without
- * fee, provided that the above copyright notice appear in all copies
- * and that both that copyright notice and this permission notice
- * appear in supporting documentation.
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of The Open Group shall not be
- * used in advertising or otherwise to promote the sale, use or other dealings
- * in this Software without prior written authorization from The Open Group.
- */
-
-#include <assert.h>
-
-#undef DEBUG_SPEW
-#ifdef DEBUG_SPEW
-#include <stdio.h>
-#endif
-
-#include "async-getprop.h"
-
-#define NEED_REPLIES
-#include <X11/Xlibint.h>
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-typedef struct _ListNode ListNode;
-typedef struct _AgPerDisplayData AgPerDisplayData;
-
-struct _ListNode
-{
- ListNode *next;
-};
-
-struct _AgGetPropertyTask
-{
- ListNode node;
-
- AgPerDisplayData *dd;
- Window window;
- Atom property;
-
- unsigned long request_seq;
- int error;
-
- Atom actual_type;
- int actual_format;
-
- unsigned long n_items;
- unsigned long bytes_after;
- char *data;
-
- Bool have_reply;
-};
-
-struct _AgPerDisplayData
-{
- ListNode node;
- _XAsyncHandler async;
-
- Display *display;
- ListNode *pending_tasks;
- ListNode *pending_tasks_tail;
- ListNode *completed_tasks;
- ListNode *completed_tasks_tail;
- int n_tasks_pending;
- int n_tasks_completed;
-};
-
-static ListNode *display_datas = NULL;
-static ListNode *display_datas_tail = NULL;
-
-static void
-append_to_list (ListNode **head,
- ListNode **tail,
- ListNode *task)
-{
- task->next = NULL;
-
- if (*tail == NULL)
- {
- assert (*head == NULL);
- *head = task;
- *tail = task;
- }
- else
- {
- (*tail)->next = task;
- *tail = task;
- }
-}
-
-static void
-remove_from_list (ListNode **head,
- ListNode **tail,
- ListNode *task)
-{
- ListNode *prev;
- ListNode *node;
-
- prev = NULL;
- node = *head;
- while (node != NULL)
- {
- if (node == task)
- {
- if (prev)
- prev->next = node->next;
- else
- *head = node->next;
-
- if (node == *tail)
- *tail = prev;
-
- break;
- }
-
- prev = node;
- node = node->next;
- }
-
- /* can't remove what's not there */
- assert (node != NULL);
-
- node->next = NULL;
-}
-
-static void
-move_to_completed (AgPerDisplayData *dd,
- AgGetPropertyTask *task)
-{
- remove_from_list (&dd->pending_tasks,
- &dd->pending_tasks_tail,
- &task->node);
-
- append_to_list (&dd->completed_tasks,
- &dd->completed_tasks_tail,
- &task->node);
-
- dd->n_tasks_pending -= 1;
- dd->n_tasks_completed += 1;
-}
-
-static AgGetPropertyTask*
-find_pending_by_request_sequence (AgPerDisplayData *dd,
- unsigned long request_seq)
-{
- ListNode *node;
-
- /* if the sequence is after our last pending task, we
- * aren't going to find a match
- */
- {
- AgGetPropertyTask *task = (AgGetPropertyTask*) dd->pending_tasks_tail;
- if (task != NULL)
- {
- if (task->request_seq < request_seq)
- return NULL;
- else if (task->request_seq == request_seq)
- return task; /* why not check this */
- }
- }
-
- /* Generally we should get replies in the order we sent
- * requests, so we should usually be using the task
- * at the head of the list, if we use any task at all.
- * I'm not sure this is 100% guaranteed, if it is,
- * it would be a big speedup.
- */
-
- node = dd->pending_tasks;
- while (node != NULL)
- {
- AgGetPropertyTask *task = (AgGetPropertyTask*) node;
-
- if (task->request_seq == request_seq)
- return task;
-
- node = node->next;
- }
-
- return NULL;
-}
-
-static Bool
-async_get_property_handler (Display *dpy,
- xReply *rep,
- char *buf,
- int len,
- XPointer data)
-{
- xGetPropertyReply replbuf;
- xGetPropertyReply *reply;
- AgGetPropertyTask *task;
- AgPerDisplayData *dd;
- int bytes_read;
-
- dd = (AgPerDisplayData*) data;
-
-#if 0
- printf ("%s: seeing request seq %ld buflen %d\n", __FUNCTION__,
- dpy->last_request_read, len);
-#endif
-
- task = find_pending_by_request_sequence (dd, dpy->last_request_read);
-
- if (task == NULL)
- return False;
-
- assert (dpy->last_request_read == task->request_seq);
-
- task->have_reply = True;
- move_to_completed (dd, task);
-
- /* read bytes so far */
- bytes_read = SIZEOF (xReply);
-
- if (rep->generic.type == X_Error)
- {
- xError errbuf;
-
- task->error = rep->error.errorCode;
-
-#ifdef DEBUG_SPEW
- printf ("%s: error code = %d (ignoring error, eating %d bytes, generic.length = %ld)\n",
- __FUNCTION__, task->error, (SIZEOF (xError) - bytes_read),
- rep->generic.length);
-#endif
-
- /* We return True (meaning we consumed the reply)
- * because otherwise it would invoke the X error handler,
- * and an async API is useless if you have to synchronously
- * trap X errors. Also GetProperty can always fail, pretty
- * much, so trapping errors is always what you want.
- *
- * We have to eat all the error reply data here.
- * (kind of a charade as we know sizeof(xError) == sizeof(xReply))
- *
- * Passing discard = True seems to break things; I don't understand
- * why, because there should be no extra data in an error reply,
- * right?
- */
- _XGetAsyncReply (dpy, (char *)&errbuf, rep, buf, len,
- (SIZEOF (xError) - bytes_read) >> 2, /* in 32-bit words */
- False); /* really seems like it should be True */
-
- return True;
- }
-
-#ifdef DEBUG_SPEW
- printf ("%s: already read %d bytes reading %d more for total of %d; generic.length = %ld\n",
- __FUNCTION__, bytes_read, (SIZEOF (xGetPropertyReply) - bytes_read) >> 2,
- SIZEOF (xGetPropertyReply), rep->generic.length);
-#endif
-
- /* (kind of a silly as we know sizeof(xGetPropertyReply) == sizeof(xReply)) */
- reply = (xGetPropertyReply *)
- _XGetAsyncReply (dpy, (char *)&replbuf, rep, buf, len,
- (SIZEOF (xGetPropertyReply) - bytes_read) >> 2, /* in 32-bit words */
- False); /* False means expecting more data to follow,
- * don't eat the rest of the reply
- */
-
- bytes_read = SIZEOF (xGetPropertyReply);
-
-#ifdef DEBUG_SPEW
- printf ("%s: have reply propertyType = %ld format = %d n_items = %ld\n",
- __FUNCTION__, reply->propertyType, reply->format, reply->nItems);
-#endif
-
- assert (task->data == NULL);
-
- /* This is all copied from XGetWindowProperty(). Not sure we should
- * LockDisplay(). Not sure I'm passing the right args to
- * XGetAsyncData(). Not sure about a lot of things.
- */
-
- /* LockDisplay (dpy); */
-
- if (reply->propertyType != None)
- {
- long nbytes, netbytes;
-
- /* this alignment macro from orbit2 */
-#define ALIGN_VALUE(this, boundary) \
- (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
-
- switch (reply->format)
- {
- /*
- * One extra byte is malloced than is needed to contain the property
- * data, but this last byte is null terminated and convenient for
- * returning string properties, so the client doesn't then have to
- * recopy the string to make it null terminated.
- */
- case 8:
- nbytes = reply->nItems;
- /* there's padding to word boundary */
- netbytes = ALIGN_VALUE (nbytes, 4);
- if (nbytes + 1 > 0 &&
- (task->data = (char *) Xmalloc ((unsigned)nbytes + 1)))
- {
-#ifdef DEBUG_SPEW
- printf ("%s: already read %d bytes using %ld, more eating %ld more\n",
- __FUNCTION__, bytes_read, nbytes, netbytes);
-#endif
- /* _XReadPad (dpy, (char *) task->data, netbytes); */
- _XGetAsyncData (dpy, task->data, buf, len,
- bytes_read, nbytes,
- netbytes);
- }
- break;
-
- case 16:
- nbytes = reply->nItems * sizeof (short);
- netbytes = reply->nItems << 1;
- netbytes = ALIGN_VALUE (netbytes, 4); /* align to word boundary */
- if (nbytes + 1 > 0 &&
- (task->data = (char *) Xmalloc ((unsigned)nbytes + 1)))
- {
-#ifdef DEBUG_SPEW
- printf ("%s: already read %d bytes using %ld more, eating %ld more\n",
- __FUNCTION__, bytes_read, nbytes, netbytes);
-#endif
- /* _XRead16Pad (dpy, (short *) task->data, netbytes); */
- _XGetAsyncData (dpy, task->data, buf, len,
- bytes_read, nbytes, netbytes);
- }
- break;
-
- case 32:
- /* NOTE buffer is in longs to match XGetWindowProperty() */
- nbytes = reply->nItems * sizeof (long);
- netbytes = reply->nItems << 2; /* wire size is always 32 bits though */
- if (nbytes + 1 > 0 &&
- (task->data = (char *) Xmalloc ((unsigned)nbytes + 1)))
- {
-#ifdef DEBUG_SPEW
- printf ("%s: already read %d bytes using %ld more, eating %ld more\n",
- __FUNCTION__, bytes_read, nbytes, netbytes);
-#endif
-
- /* We have to copy the XGetWindowProperty() crackrock
- * and get format 32 as long even on 64-bit platforms.
- */
- if (sizeof (long) == 8)
- {
- char *netdata;
- char *lptr;
- char *end_lptr;
-
- /* Store the 32-bit values in the end of the array */
- netdata = task->data + nbytes / 2;
-
- _XGetAsyncData (dpy, netdata, buf, len,
- bytes_read, netbytes,
- netbytes);
-
- /* Now move the 32-bit values to the front */
-
- lptr = task->data;
- end_lptr = task->data + nbytes;
- while (lptr != end_lptr)
- {
- *(long*) lptr = *(CARD32*) netdata;
- lptr += sizeof (long);
- netdata += sizeof (CARD32);
- }
- }
- else
- {
- /* Here the wire format matches our actual format */
- _XGetAsyncData (dpy, task->data, buf, len,
- bytes_read, netbytes,
- netbytes);
- }
- }
- break;
-
- default:
- /*
- * This part of the code should never be reached. If it is,
- * the server sent back a property with an invalid format.
- * This is a BadImplementation error.
- *
- * However this async GetProperty API doesn't report errors
- * via the standard X mechanism, so don't do anything about
- * it, other than store it in task->error.
- */
- {
-#if 0
- xError error;
-#endif
-
- task->error = BadImplementation;
-
-#if 0
- error.sequenceNumber = task->request_seq;
- error.type = X_Error;
- error.majorCode = X_GetProperty;
- error.minorCode = 0;
- error.errorCode = BadImplementation;
-
- _XError (dpy, &error);
-#endif
- }
-
- nbytes = netbytes = 0L;
- break;
- }
-
- if (task->data == NULL)
- {
- task->error = BadAlloc;
-
-#ifdef DEBUG_SPEW
- printf ("%s: already read %d bytes eating %ld\n",
- __FUNCTION__, bytes_read, netbytes);
-#endif
- /* _XEatData (dpy, (unsigned long) netbytes); */
- _XGetAsyncData (dpy, NULL, buf, len,
- bytes_read, 0, netbytes);
-
- /* UnlockDisplay (dpy); */
- return BadAlloc; /* not Success */
- }
-
- (task->data)[nbytes] = '\0';
- }
-
-#ifdef DEBUG_SPEW
- printf ("%s: have data\n", __FUNCTION__);
-#endif
-
- task->actual_type = reply->propertyType;
- task->actual_format = reply->format;
- task->n_items = reply->nItems;
- task->bytes_after = reply->bytesAfter;
-
- /* UnlockDisplay (dpy); */
-
- return True;
-}
-
-static AgPerDisplayData*
-get_display_data (Display *display,
- Bool create)
-{
- ListNode *node;
- AgPerDisplayData *dd;
-
- node = display_datas;
- while (node != NULL)
- {
- dd = (AgPerDisplayData*) node;
-
- if (dd->display == display)
- return dd;
-
- node = node->next;
- }
-
- if (!create)
- return NULL;
-
- dd = Xcalloc (1, sizeof (AgPerDisplayData));
- if (dd == NULL)
- return NULL;
-
- dd->display = display;
- dd->async.next = display->async_handlers;
- dd->async.handler = async_get_property_handler;
- dd->async.data = (XPointer) dd;
- dd->display->async_handlers = &dd->async;
-
- append_to_list (&display_datas,
- &display_datas_tail,
- &dd->node);
-
- return dd;
-}
-
-static void
-maybe_free_display_data (AgPerDisplayData *dd)
-{
- if (dd->pending_tasks == NULL &&
- dd->completed_tasks == NULL)
- {
- DeqAsyncHandler (dd->display, &dd->async);
- remove_from_list (&display_datas, &display_datas_tail,
- &dd->node);
- XFree (dd);
- }
-}
-
-AgGetPropertyTask*
-ag_task_create (Display *dpy,
- Window window,
- Atom property,
- long offset,
- long length,
- Bool delete,
- Atom req_type)
-{
- AgGetPropertyTask *task;
- xGetPropertyReq *req;
- AgPerDisplayData *dd;
-
- /* Fire up our request */
- LockDisplay (dpy);
-
- dd = get_display_data (dpy, True);
- if (dd == NULL)
- {
- UnlockDisplay (dpy);
- return NULL;
- }
-
- GetReq (GetProperty, req);
- req->window = window;
- req->property = property;
- req->type = req_type;
- req->delete = delete;
- req->longOffset = offset;
- req->longLength = length;
-
- /* Queue up our async task */
- task = Xcalloc (1, sizeof (AgGetPropertyTask));
- if (task == NULL)
- {
- UnlockDisplay (dpy);
- return NULL;
- }
-
- task->dd = dd;
- task->window = window;
- task->property = property;
- task->request_seq = dpy->request;
-
- append_to_list (&dd->pending_tasks,
- &dd->pending_tasks_tail,
- &task->node);
- dd->n_tasks_pending += 1;
-
- UnlockDisplay (dpy);
-
- SyncHandle ();
-
- return task;
-}
-
-static void
-free_task (AgGetPropertyTask *task)
-{
- remove_from_list (&task->dd->completed_tasks,
- &task->dd->completed_tasks_tail,
- &task->node);
- task->dd->n_tasks_completed -= 1;
- maybe_free_display_data (task->dd);
- XFree (task);
-}
-
-Status
-ag_task_get_reply_and_free (AgGetPropertyTask *task,
- Atom *actual_type,
- int *actual_format,
- unsigned long *nitems,
- unsigned long *bytesafter,
- unsigned char **prop)
-{
- Display *dpy;
-
- *prop = NULL;
-
- dpy = task->dd->display; /* Xlib macros require a variable named "dpy" */
-
- if (task->error != Success)
- {
- Status s = task->error;
-
- free_task (task);
-
- return s;
- }
-
- if (!task->have_reply)
- {
- free_task (task);
-
- return BadAlloc; /* not Success */
- }
-
- *actual_type = task->actual_type;
- *actual_format = task->actual_format;
- *nitems = task->n_items;
- *bytesafter = task->bytes_after;
-
- *prop = (unsigned char*) task->data; /* pass out ownership of task->data */
-
- SyncHandle ();
-
- free_task (task);
-
- return Success;
-}
-
-Bool
-ag_task_have_reply (AgGetPropertyTask *task)
-{
- return task->have_reply;
-}
-
-Atom
-ag_task_get_property (AgGetPropertyTask *task)
-{
- return task->property;
-}
-
-Window
-ag_task_get_window (AgGetPropertyTask *task)
-{
- return task->window;
-}
-
-Display*
-ag_task_get_display (AgGetPropertyTask *task)
-{
- return task->dd->display;
-}
-
-AgGetPropertyTask*
-ag_get_next_completed_task (Display *display)
-{
- AgPerDisplayData *dd;
-
- dd = get_display_data (display, False);
-
- if (dd == NULL)
- return NULL;
-
-#ifdef DEBUG_SPEW
- printf ("%d pending %d completed\n",
- dd->n_tasks_pending,
- dd->n_tasks_completed);
-#endif
-
- return (AgGetPropertyTask*) dd->completed_tasks;
-}
-
-void*
-ag_Xmalloc (unsigned long bytes)
-{
- return (void*) Xmalloc (bytes);
-}
-
-void*
-ag_Xmalloc0 (unsigned long bytes)
-{
- return (void*) Xcalloc (bytes, 1);
-}
diff --git a/src/core/async-getprop.h b/src/core/async-getprop.h
deleted file mode 100644
index c857e930..00000000
--- a/src/core/async-getprop.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Asynchronous X property getting hack */
-
-/*
- * Copyright (C) 2002 Havoc Pennington
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without
- * fee, provided that the above copyright notice appear in all copies
- * and that both that copyright notice and this permission notice
- * appear in supporting documentation.
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of The Open Group shall not be
- * used in advertising or otherwise to promote the sale, use or other dealings
- * in this Software without prior written authorization from The Open Group.
- */
-
-#ifndef ASYNC_GETPROP_H
-#define ASYNC_GETPROP_H
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-typedef struct _AgGetPropertyTask AgGetPropertyTask;
-
-AgGetPropertyTask* ag_task_create (Display *display,
- Window window,
- Atom property,
- long offset,
- long length,
- Bool delete,
- Atom req_type);
-Status ag_task_get_reply_and_free (AgGetPropertyTask *task,
- Atom *actual_type,
- int *actual_format,
- unsigned long *nitems,
- unsigned long *bytesafter,
- unsigned char **prop);
-
-Bool ag_task_have_reply (AgGetPropertyTask *task);
-Atom ag_task_get_property (AgGetPropertyTask *task);
-Window ag_task_get_window (AgGetPropertyTask *task);
-Display* ag_task_get_display (AgGetPropertyTask *task);
-
-AgGetPropertyTask* ag_get_next_completed_task (Display *display);
-
-/* so other headers don't have to include internal Xlib goo */
-void* ag_Xmalloc (unsigned long bytes);
-void* ag_Xmalloc0 (unsigned long bytes);
-
-#endif
-
-
-
-
diff --git a/src/core/atomnames.h b/src/core/atomnames.h
deleted file mode 100644
index 43710f37..00000000
--- a/src/core/atomnames.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2002, 2003, 2004 Red Hat, Inc.
- * Copyright (C) 2003, 2004 Rob Adams
- * Copyright (C) 2004-2006 Elijah Newren
- * Copyright (C) 2008 Thomas Thurman
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-/**
- * \file atomnames.h A list of atom names.
- *
- * This is a list of the names of all the X atoms that Metacity uses.
- * Each is wrapped in a macro "item()" which is undefined here; the
- * idea is that when you need to make a big list of all the X atoms,
- * you can define item(), include this file, and then undefine it
- * again.
- *
- * If you also define EWMH_ATOMS_ONLY then you will only get _NET_WM_*
- * atoms rather than all of them.
- */
-
-#ifndef item
-#error "item(x) must be defined when you include atomnames.h"
-#endif
-
-#ifndef EWMH_ATOMS_ONLY
-
-item(WM_PROTOCOLS)
-item(WM_TAKE_FOCUS)
-item(WM_DELETE_WINDOW)
-item(WM_STATE)
-item(_MOTIF_WM_HINTS)
-item(WM_CHANGE_STATE)
-item(SM_CLIENT_ID)
-item(WM_CLIENT_LEADER)
-item(WM_WINDOW_ROLE)
-item(UTF8_STRING)
-item(WM_ICON_SIZE)
-item(_KWM_WIN_ICON)
-item(_METACITY_RESTART_MESSAGE)
-item(_METACITY_RELOAD_THEME_MESSAGE)
-item(_METACITY_SET_KEYBINDINGS_MESSAGE)
-item(_METACITY_TOGGLE_VERBOSE)
-item(_GNOME_PANEL_ACTION)
-item(_GNOME_PANEL_ACTION_MAIN_MENU)
-item(_GNOME_PANEL_ACTION_RUN_DIALOG)
-item(_METACITY_SENTINEL)
-item(_METACITY_VERSION)
-item(WM_CLIENT_MACHINE)
-item(MANAGER)
-item(TARGETS)
-item(MULTIPLE)
-item(TIMESTAMP)
-item(VERSION)
-item(ATOM_PAIR)
-
-/* Oddities: These are used, and we need atoms for them,
- * but when we need all _NET_WM hints (i.e. when we're making
- * lists of which _NET_WM hints we support in order to advertise
- * it) we haven't historically listed them. I don't know what
- * the reason for this is. It may be a bug.
- */
-item(_NET_WM_SYNC_REQUEST)
-item(_NET_WM_SYNC_REQUEST_COUNTER)
-item(_NET_WM_VISIBLE_NAME)
-item(_NET_WM_VISIBLE_ICON_NAME)
-item(_NET_SUPPORTING_WM_CHECK)
-
-/* But I suppose it's quite reasonable not to advertise using
- * _NET_SUPPORTED that we support _NET_SUPPORTED :)
- */
-item(_NET_SUPPORTED)
-
-#endif /* !EWMH_ATOMS_ONLY */
-
-/**************************************************************************/
-
-item(_NET_WM_NAME)
-item(_NET_CLOSE_WINDOW)
-item(_NET_WM_STATE)
-item(_NET_WM_STATE_SHADED)
-item(_NET_WM_STATE_MAXIMIZED_HORZ)
-item(_NET_WM_STATE_MAXIMIZED_VERT)
-item(_NET_WM_DESKTOP)
-item(_NET_NUMBER_OF_DESKTOPS)
-item(_NET_CURRENT_DESKTOP)
-item(_NET_WM_WINDOW_TYPE)
-item(_NET_WM_WINDOW_TYPE_DESKTOP)
-item(_NET_WM_WINDOW_TYPE_DOCK)
-item(_NET_WM_WINDOW_TYPE_TOOLBAR)
-item(_NET_WM_WINDOW_TYPE_MENU)
-item(_NET_WM_WINDOW_TYPE_DIALOG)
-item(_NET_WM_WINDOW_TYPE_NORMAL)
-item(_NET_WM_STATE_MODAL)
-item(_NET_CLIENT_LIST)
-item(_NET_CLIENT_LIST_STACKING)
-item(_NET_WM_STATE_SKIP_TASKBAR)
-item(_NET_WM_STATE_SKIP_PAGER)
-item(_NET_WM_ICON_NAME)
-item(_NET_WM_ICON)
-item(_NET_WM_ICON_GEOMETRY)
-item(_NET_WM_MOVERESIZE)
-item(_NET_ACTIVE_WINDOW)
-item(_NET_WM_STRUT)
-item(_NET_WM_STATE_HIDDEN)
-item(_NET_WM_WINDOW_TYPE_UTILITY)
-item(_NET_WM_WINDOW_TYPE_SPLASH)
-item(_NET_WM_STATE_FULLSCREEN)
-item(_NET_WM_PING)
-item(_NET_WM_PID)
-item(_NET_WORKAREA)
-item(_NET_SHOWING_DESKTOP)
-item(_NET_DESKTOP_LAYOUT)
-item(_NET_DESKTOP_NAMES)
-item(_NET_WM_ALLOWED_ACTIONS)
-item(_NET_WM_ACTION_MOVE)
-item(_NET_WM_ACTION_RESIZE)
-item(_NET_WM_ACTION_SHADE)
-item(_NET_WM_ACTION_STICK)
-item(_NET_WM_ACTION_MAXIMIZE_HORZ)
-item(_NET_WM_ACTION_MAXIMIZE_VERT)
-item(_NET_WM_ACTION_CHANGE_DESKTOP)
-item(_NET_WM_ACTION_CLOSE)
-item(_NET_WM_STATE_ABOVE)
-item(_NET_WM_STATE_BELOW)
-item(_NET_STARTUP_ID)
-item(_NET_WM_STRUT_PARTIAL)
-item(_NET_WM_ACTION_FULLSCREEN)
-item(_NET_WM_ACTION_MINIMIZE)
-item(_NET_FRAME_EXTENTS)
-item(_NET_REQUEST_FRAME_EXTENTS)
-item(_NET_WM_USER_TIME)
-item(_NET_WM_STATE_DEMANDS_ATTENTION)
-item(_NET_MOVERESIZE_WINDOW)
-item(_NET_DESKTOP_GEOMETRY)
-item(_NET_DESKTOP_VIEWPORT)
-item(_NET_WM_USER_TIME_WINDOW)
-item(_NET_WM_ACTION_ABOVE)
-item(_NET_WM_ACTION_BELOW)
-item(_NET_WM_STATE_STICKY)
-item(_NET_WM_FULLSCREEN_MONITORS)
-
-#if 0
-/* We apparently never use: */
-/* item(_NET_RESTACK_WINDOW) */
-#endif
-
-/* eof atomnames.h */
-
diff --git a/src/core/bell.c b/src/core/bell.c
deleted file mode 100644
index 1b6022c8..00000000
--- a/src/core/bell.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity visual bell */
-
-/*
- * Copyright (C) 2002 Sun Microsystems Inc.
- * Copyright (C) 2005, 2006 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-/**
- * \file bell.c Ring the bell or flash the screen
- *
- * Sometimes, X programs "ring the bell", whatever that means. Metacity lets
- * the user configure the bell to be audible or visible (aka visual), and
- * if it's visual it can be configured to be frame-flash or fullscreen-flash.
- * We never get told about audible bells; X handles them just fine by itself.
- *
- * Visual bells come in at meta_bell_notify(), which checks we are actually
- * in visual mode and calls through to bell_visual_notify(). That
- * function then checks what kind of visual flash you like, and calls either
- * bell_flash_fullscreen()-- which calls bell_flash_screen() to do
- * its work-- or bell_flash_frame(), which flashes the focussed window
- * using bell_flash_window_frame(), unless there is no such window, in
- * which case it flashes the screen instead. bell_flash_window_frame()
- * flashes the frame and calls bell_unflash_frame() as a timeout to
- * remove the flash.
- *
- * The visual bell was the result of a discussion in Bugzilla here:
- * <http://bugzilla.gnome.org/show_bug.cgi?id=99886>.
- *
- * Several of the functions in this file are ifdeffed out entirely if we are
- * found not to have the XKB extension, which is required to do these clever
- * things with bells; some others are entirely no-ops in that case.
- */
-
-#include <config.h>
-#include "bell.h"
-#include "screen-private.h"
-#include "prefs.h"
-
-/**
- * Flashes one entire screen. This is done by making a window the size of the
- * whole screen (or reusing the old one, if it's still around), mapping it,
- * painting it white and then black, and then unmapping it. We set saveunder so
- * that all the windows behind it come back immediately.
- *
- * Unlike frame flashes, we don't do fullscreen flashes with a timeout; rather,
- * we do them in one go, because we don't have to rely on the theme code
- * redrawing the frame for us in order to do the flash.
- *
- * \param display The display which owns the screen (rather redundant)
- * \param screen The screen to flash
- *
- * \bug The way I read it, this appears not to do the flash
- * the first time we flash a particular display. Am I wrong?
- *
- * \bug This appears to destroy our current XSync status.
- */
-static void
-bell_flash_screen (MetaDisplay *display,
- MetaScreen *screen)
-{
- Window root = screen->xroot;
- int width = screen->rect.width;
- int height = screen->rect.height;
-
- if (screen->flash_window == None)
- {
- Visual *visual = (Visual *)CopyFromParent;
- XSetWindowAttributes xswa;
- int depth = CopyFromParent;
- xswa.save_under = True;
- xswa.override_redirect = True;
- /*
- * TODO: use XGetVisualInfo and determine which is an
- * overlay, if one is present, and use the Overlay visual
- * for this window (for performance reasons).
- * Not sure how to tell this yet...
- */
- screen->flash_window = XCreateWindow (display->xdisplay, root,
- 0, 0, width, height,
- 0, depth,
- InputOutput,
- visual,
- /* note: XSun doesn't like SaveUnder here */
- CWSaveUnder | CWOverrideRedirect,
- &xswa);
- XSelectInput (display->xdisplay, screen->flash_window, ExposureMask);
- XMapWindow (display->xdisplay, screen->flash_window);
- XSync (display->xdisplay, False);
- XFlush (display->xdisplay);
- XUnmapWindow (display->xdisplay, screen->flash_window);
- }
- else
- {
- /* just draw something in the window */
- GC gc = XCreateGC (display->xdisplay, screen->flash_window, 0, NULL);
- XMapWindow (display->xdisplay, screen->flash_window);
- XSetForeground (display->xdisplay, gc,
- WhitePixel (display->xdisplay,
- XScreenNumberOfScreen (screen->xscreen)));
- XFillRectangle (display->xdisplay, screen->flash_window, gc,
- 0, 0, width, height);
- XSetForeground (display->xdisplay, gc,
- BlackPixel (display->xdisplay,
- XScreenNumberOfScreen (screen->xscreen)));
- XFillRectangle (display->xdisplay, screen->flash_window, gc,
- 0, 0, width, height);
- XFlush (display->xdisplay);
- XSync (display->xdisplay, False);
- XUnmapWindow (display->xdisplay, screen->flash_window);
- XFreeGC (display->xdisplay, gc);
- }
-
- if (meta_prefs_get_focus_mode () != META_FOCUS_MODE_CLICK &&
- !display->mouse_mode)
- meta_display_increment_focus_sentinel (display);
- XFlush (display->xdisplay);
-}
-
-/**
- * Flashes one screen, or all screens, in response to a bell event.
- * If the event is on a particular window, flash the screen that
- * window is on. Otherwise, flash every screen on this display.
- *
- * If the configure script found we had no XKB, this does not exist.
- *
- * \param display The display the event came in on
- * \param xkb_ev The bell event
- */
-#ifdef HAVE_XKB
-static void
-bell_flash_fullscreen (MetaDisplay *display,
- XkbAnyEvent *xkb_ev)
-{
- XkbBellNotifyEvent *xkb_bell_ev = (XkbBellNotifyEvent *) xkb_ev;
- MetaScreen *screen;
-
- g_assert (xkb_ev->xkb_type == XkbBellNotify);
- if (xkb_bell_ev->window != None)
- {
- screen = meta_display_screen_for_xwindow (display, xkb_bell_ev->window);
- if (screen)
- bell_flash_screen (display, screen);
- }
- else
- {
- GSList *screen_list = display->screens;
- while (screen_list)
- {
- screen = (MetaScreen *) screen_list->data;
- bell_flash_screen (display, screen);
- screen_list = screen_list->next;
- }
- }
-}
-
-/**
- * Makes a frame be not flashed; this is the timeout half of
- * bell_flash_window_frame(). This is done simply by clearing the
- * flash flag and queuing a redraw of the frame.
- *
- * If the configure script found we had no XKB, this does not exist.
- *
- * \param data The frame to unflash, cast to a gpointer so it can go into
- * a callback function.
- * \return Always FALSE, so we don't get called again.
- *
- * \bug This is the parallel to bell_flash_window_frame(), so it should
- * really be called meta_bell_unflash_window_frame().
- */
-static gboolean
-bell_unflash_frame (gpointer data)
-{
- MetaFrame *frame = (MetaFrame *) data;
- frame->is_flashing = 0;
- meta_frame_queue_draw (frame);
- return FALSE;
-}
-
-/**
- * Makes a frame flash and then return to normal shortly afterwards.
- * This is done by setting a flag so that the theme
- * code will temporarily draw the frame as focussed if it's unfocussed and
- * vice versa, and then queueing a redraw. Lastly, we create a timeout so
- * that the flag can be unset and the frame re-redrawn.
- *
- * If the configure script found we had no XKB, this does not exist.
- *
- * \param window The window to flash
- */
-static void
-bell_flash_window_frame (MetaWindow *window)
-{
- g_assert (window->frame != NULL);
- window->frame->is_flashing = 1;
- meta_frame_queue_draw (window->frame);
- g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, 100,
- bell_unflash_frame, window->frame, NULL);
-}
-
-/**
- * Flashes the frame of the focussed window. If there is no focussed window,
- * flashes the screen.
- *
- * \param display The display the bell event came in on
- * \param xkb_ev The bell event we just received
- */
-static void
-bell_flash_frame (MetaDisplay *display,
- XkbAnyEvent *xkb_ev)
-{
- XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent *) xkb_ev;
- MetaWindow *window;
-
- g_assert (xkb_ev->xkb_type == XkbBellNotify);
- window = meta_display_lookup_x_window (display, xkb_bell_event->window);
- if (!window && (display->focus_window) && (display->focus_window->frame))
- {
- window = display->focus_window;
- }
- if (window)
- {
- bell_flash_window_frame (window);
- }
- else /* revert to fullscreen flash if there's no focussed window */
- {
- bell_flash_fullscreen (display, xkb_ev);
- }
-}
-
-/**
- * Gives the user some kind of visual bell substitute, in response to a
- * bell event. What this is depends on the "visual bell type" pref.
- *
- * If the configure script found we had no XKB, this does not exist.
- *
- * \param display The display the bell event came in on
- * \param xkb_ev The bell event we just received
- *
- * \bug This should be merged with meta_bell_notify().
- */
-static void
-bell_visual_notify (MetaDisplay *display,
- XkbAnyEvent *xkb_ev)
-{
- switch (meta_prefs_get_visual_bell_type ())
- {
- case META_VISUAL_BELL_FULLSCREEN_FLASH:
- bell_flash_fullscreen (display, xkb_ev);
- break;
- case META_VISUAL_BELL_FRAME_FLASH:
- bell_flash_frame (display, xkb_ev); /* does nothing yet */
- break;
- case META_VISUAL_BELL_INVALID:
- /* do nothing */
- break;
- }
-}
-
-void
-meta_bell_notify (MetaDisplay *display,
- XkbAnyEvent *xkb_ev)
-{
- /* flash something */
- if (meta_prefs_get_visual_bell ())
- bell_visual_notify (display, xkb_ev);
-}
-#endif /* HAVE_XKB */
-
-void
-meta_bell_set_audible (MetaDisplay *display, gboolean audible)
-{
-#ifdef HAVE_XKB
- XkbChangeEnabledControls (display->xdisplay,
- XkbUseCoreKbd,
- XkbAudibleBellMask,
- audible ? XkbAudibleBellMask : 0);
-#endif
-}
-
-gboolean
-meta_bell_init (MetaDisplay *display)
-{
-#ifdef HAVE_XKB
- int xkb_base_error_type, xkb_opcode;
-
- if (!XkbQueryExtension (display->xdisplay, &xkb_opcode,
- &display->xkb_base_event_type,
- &xkb_base_error_type,
- NULL, NULL))
- {
- display->xkb_base_event_type = -1;
- g_message ("could not find XKB extension.");
- return FALSE;
- }
- else
- {
- unsigned int mask = XkbBellNotifyMask;
- gboolean visual_bell_auto_reset = FALSE;
- /* TRUE if and when non-broken version is available */
- XkbSelectEvents (display->xdisplay,
- XkbUseCoreKbd,
- XkbBellNotifyMask,
- XkbBellNotifyMask);
- XkbChangeEnabledControls (display->xdisplay,
- XkbUseCoreKbd,
- XkbAudibleBellMask,
- meta_prefs_bell_is_audible ()
- ? XkbAudibleBellMask : 0);
- if (visual_bell_auto_reset) {
- XkbSetAutoResetControls (display->xdisplay,
- XkbAudibleBellMask,
- &mask,
- &mask);
- }
- return TRUE;
- }
-#endif
- return FALSE;
-}
-
-void
-meta_bell_shutdown (MetaDisplay *display)
-{
-#ifdef HAVE_XKB
- /* TODO: persist initial bell state in display, reset here */
- XkbChangeEnabledControls (display->xdisplay,
- XkbUseCoreKbd,
- XkbAudibleBellMask,
- XkbAudibleBellMask);
-#endif
-}
-
-/**
- * Deals with a frame being destroyed. This is important because if we're
- * using a visual bell, we might be flashing the edges of the frame, and
- * so we'd have a timeout function waiting ready to un-flash them. If the
- * frame's going away, we can tell the timeout not to bother.
- *
- * \param frame The frame which is being destroyed
- */
-void
-meta_bell_notify_frame_destroy (MetaFrame *frame)
-{
- if (frame->is_flashing)
- g_source_remove_by_funcs_user_data (&g_timeout_funcs, frame);
-}
diff --git a/src/core/bell.h b/src/core/bell.h
deleted file mode 100644
index 462d1ed7..00000000
--- a/src/core/bell.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * \file bell.h Ring the bell or flash the screen
- *
- * Sometimes, X programs "ring the bell", whatever that means. Metacity lets
- * the user configure the bell to be audible or visible (aka visual), and
- * if it's visual it can be configured to be frame-flash or fullscreen-flash.
- * We never get told about audible bells; X handles them just fine by itself.
- *
- * The visual bell was the result of a discussion in Bugzilla here:
- * <http://bugzilla.gnome.org/show_bug.cgi?id=99886>.
- */
-
-/*
- * Copyright (C) 2002 Sun Microsystems Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <X11/Xlib.h>
-#ifdef HAVE_XKB
-#include <X11/XKBlib.h>
-#endif
-#include "display-private.h"
-#include "frame-private.h"
-
-#ifdef HAVE_XKB
-/**
- * Gives the user some kind of visual bell; in fact, this is our response
- * to any kind of bell request, but we set it up so that we only get
- * notified about visual bells, and X deals with audible ones.
- *
- * If the configure script found we had no XKB, this does not exist.
- *
- * \param display The display the bell event came in on
- * \param xkb_ev The bell event we just received
- */
-void meta_bell_notify (MetaDisplay *display, XkbAnyEvent *xkb_ev);
-#endif
-
-/**
- * Turns the bell to audible or visual. This tells X what to do, but
- * not Metacity; you will need to set the "visual bell" pref for that.
- *
- * If the configure script found we had no XKB, this is a no-op.
- *
- * \param display The display we're configuring
- * \param audible True for an audible bell, false for a visual bell
- */
-void meta_bell_set_audible (MetaDisplay *display, gboolean audible);
-
-/**
- * Initialises the bell subsystem. This involves intialising
- * XKB (which, despite being a keyboard extension, is the
- * place to look for bell notifications), then asking it
- * to send us bell notifications, and then also switching
- * off the audible bell if we're using a visual one ourselves.
- *
- * Unlike most X extensions we use, we only initialise XKB here
- * (rather than in main()). It's possible that XKB is not
- * installed at all, but if that was known at build time
- * we will have HAVE_XKB undefined, which will cause this
- * function to be a no-op.
- *
- * \param display The display which is opening
- *
- * \bug There is a line of code that's never run that tells
- * XKB to reset the bell status after we quit. Bill H said
- * (<http://bugzilla.gnome.org/show_bug.cgi?id=99886#c12>)
- * that XFree86's implementation is broken so we shouldn't
- * call it, but that was in 2002. Is it working now?
- */
-gboolean meta_bell_init (MetaDisplay *display);
-
-/**
- * Shuts down the bell subsystem.
- *
- * \param display The display which is closing
- *
- * \bug This is never called! If we had XkbSetAutoResetControls
- * enabled in meta_bell_init(), this wouldn't be a problem, but
- * we don't.
- */
-void meta_bell_shutdown (MetaDisplay *display);
-
-/**
- * Deals with a frame being destroyed. This is important because if we're
- * using a visual bell, we might be flashing the edges of the frame, and
- * so we'd have a timeout function waiting ready to un-flash them. If the
- * frame's going away, we can tell the timeout not to bother.
- *
- * \param frame The frame which is being destroyed
- */
-void meta_bell_notify_frame_destroy (MetaFrame *frame);
diff --git a/src/core/boxes.c b/src/core/boxes.c
deleted file mode 100644
index 139f1736..00000000
--- a/src/core/boxes.c
+++ /dev/null
@@ -1,1926 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Simple box operations */
-
-/*
- * Copyright (C) 2005, 2006 Elijah Newren
- * [meta_rectangle_intersect() is copyright the GTK+ Team according to Havoc,
- * see gdkrectangle.c. As far as Havoc knows, he probably wrote
- * meta_rectangle_equal(), and I'm guessing it's (C) Red Hat. So...]
- * Copyright (C) 1995-2000 GTK+ Team
- * Copyright (C) 2002 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "boxes.h"
-#include "util.h"
-#include <X11/Xutil.h> /* Just for the definition of the various gravities */
-
-char*
-meta_rectangle_to_string (const MetaRectangle *rect,
- char *output)
-{
- /* 25 chars: 2 commas, space, plus, trailing \0 + 5 for each digit.
- * Should be more than enough space. Note that of this space, the
- * trailing \0 will be overwritten for all but the last rectangle.
- */
- g_snprintf (output, RECT_LENGTH, "%d,%d +%d,%d",
- rect->x, rect->y, rect->width, rect->height);
-
- return output;
-}
-
-char*
-meta_rectangle_region_to_string (GList *region,
- const char *separator_string,
- char *output)
-{
- /* 27 chars: 2 commas, 2 square brackets, space, plus, trailing \0 + 5
- * for each digit. Should be more than enough space. Note that of this
- * space, the trailing \0 will be overwritten for all but the last
- * rectangle.
- */
- char rect_string[RECT_LENGTH];
-
- GList *tmp = region;
- char *cur = output;
-
- if (region == NULL)
- g_snprintf (output, 10, "(EMPTY)");
-
- while (tmp)
- {
- MetaRectangle *rect = tmp->data;
- g_snprintf (rect_string, RECT_LENGTH, "[%d,%d +%d,%d]",
- rect->x, rect->y, rect->width, rect->height);
- cur = g_stpcpy (cur, rect_string);
- tmp = tmp->next;
- if (tmp)
- cur = g_stpcpy (cur, separator_string);
- }
-
- return output;
-}
-
-char*
-meta_rectangle_edge_to_string (const MetaEdge *edge,
- char *output)
-{
- /* 25 chars: 2 commas, space, plus, trailing \0 + 5 for each digit.
- * Should be more than enough space. Note that of this space, the
- * trailing \0 will be overwritten for all but the last rectangle.
- *
- * Plus 2 for parenthesis, 4 for 2 more numbers, 2 more commas, and
- * 2 more spaces, for a total of 10 more.
- */
- g_snprintf (output, EDGE_LENGTH, "[%d,%d +%d,%d], %2d, %2d",
- edge->rect.x, edge->rect.y, edge->rect.width, edge->rect.height,
- edge->side_type, edge->edge_type);
-
- return output;
-}
-
-char*
-meta_rectangle_edge_list_to_string (GList *edge_list,
- const char *separator_string,
- char *output)
-{
- /* 27 chars: 2 commas, 2 square brackets, space, plus, trailing \0 + 5 for
- * each digit. Should be more than enough space. Note that of this
- * space, the trailing \0 will be overwritten for all but the last
- * rectangle.
- *
- * Plus 2 for parenthesis, 4 for 2 more numbers, 2 more commas, and
- * 2 more spaces, for a total of 10 more.
- */
- char rect_string[EDGE_LENGTH];
-
- char *cur = output;
- GList *tmp = edge_list;
-
- if (edge_list == NULL)
- g_snprintf (output, 10, "(EMPTY)");
-
- while (tmp)
- {
- MetaEdge *edge = tmp->data;
- MetaRectangle *rect = &edge->rect;
- g_snprintf (rect_string, EDGE_LENGTH, "([%d,%d +%d,%d], %2d, %2d)",
- rect->x, rect->y, rect->width, rect->height,
- edge->side_type, edge->edge_type);
- cur = g_stpcpy (cur, rect_string);
- tmp = tmp->next;
- if (tmp)
- cur = g_stpcpy (cur, separator_string);
- }
-
- return output;
-}
-
-MetaRectangle
-meta_rect (int x, int y, int width, int height)
-{
- MetaRectangle temporary;
- temporary.x = x;
- temporary.y = y;
- temporary.width = width;
- temporary.height = height;
-
- return temporary;
-}
-
-int
-meta_rectangle_area (const MetaRectangle *rect)
-{
- g_return_val_if_fail (rect != NULL, 0);
- return rect->width * rect->height;
-}
-
-gboolean
-meta_rectangle_intersect (const MetaRectangle *src1,
- const MetaRectangle *src2,
- MetaRectangle *dest)
-{
- int dest_x, dest_y;
- int dest_w, dest_h;
- int return_val;
-
- g_return_val_if_fail (src1 != NULL, FALSE);
- g_return_val_if_fail (src2 != NULL, FALSE);
- g_return_val_if_fail (dest != NULL, FALSE);
-
- return_val = FALSE;
-
- dest_x = MAX (src1->x, src2->x);
- dest_y = MAX (src1->y, src2->y);
- dest_w = MIN (src1->x + src1->width, src2->x + src2->width) - dest_x;
- dest_h = MIN (src1->y + src1->height, src2->y + src2->height) - dest_y;
-
- if (dest_w > 0 && dest_h > 0)
- {
- dest->x = dest_x;
- dest->y = dest_y;
- dest->width = dest_w;
- dest->height = dest_h;
- return_val = TRUE;
- }
- else
- {
- dest->width = 0;
- dest->height = 0;
- }
-
- return return_val;
-}
-
-gboolean
-meta_rectangle_equal (const MetaRectangle *src1,
- const MetaRectangle *src2)
-{
- return ((src1->x == src2->x) &&
- (src1->y == src2->y) &&
- (src1->width == src2->width) &&
- (src1->height == src2->height));
-}
-
-void
-meta_rectangle_union (const MetaRectangle *rect1,
- const MetaRectangle *rect2,
- MetaRectangle *dest)
-{
- int dest_x, dest_y;
- int dest_w, dest_h;
-
- dest_x = rect1->x;
- dest_y = rect1->y;
- dest_w = rect1->width;
- dest_h = rect1->height;
-
- if (rect2->x < dest_x)
- {
- dest_w += dest_x - rect2->x;
- dest_x = rect2->x;
- }
- if (rect2->y < dest_y)
- {
- dest_h += dest_y - rect2->y;
- dest_y = rect2->y;
- }
- if (rect2->x + rect2->width > dest_x + dest_w)
- dest_w = rect2->x + rect2->width - dest_x;
- if (rect2->y + rect2->height > dest_y + dest_h)
- dest_h = rect2->y + rect2->height - dest_y;
-
- dest->x = dest_x;
- dest->y = dest_y;
- dest->width = dest_w;
- dest->height = dest_h;
-}
-
-gboolean
-meta_rectangle_overlap (const MetaRectangle *rect1,
- const MetaRectangle *rect2)
-{
- g_return_val_if_fail (rect1 != NULL, FALSE);
- g_return_val_if_fail (rect2 != NULL, FALSE);
-
- return !((rect1->x + rect1->width <= rect2->x) ||
- (rect2->x + rect2->width <= rect1->x) ||
- (rect1->y + rect1->height <= rect2->y) ||
- (rect2->y + rect2->height <= rect1->y));
-}
-
-gboolean
-meta_rectangle_vert_overlap (const MetaRectangle *rect1,
- const MetaRectangle *rect2)
-{
- return (rect1->y < rect2->y + rect2->height &&
- rect2->y < rect1->y + rect1->height);
-}
-
-gboolean
-meta_rectangle_horiz_overlap (const MetaRectangle *rect1,
- const MetaRectangle *rect2)
-{
- return (rect1->x < rect2->x + rect2->width &&
- rect2->x < rect1->x + rect1->width);
-}
-
-gboolean
-meta_rectangle_could_fit_rect (const MetaRectangle *outer_rect,
- const MetaRectangle *inner_rect)
-{
- return (outer_rect->width >= inner_rect->width &&
- outer_rect->height >= inner_rect->height);
-}
-
-gboolean
-meta_rectangle_contains_rect (const MetaRectangle *outer_rect,
- const MetaRectangle *inner_rect)
-{
- return
- inner_rect->x >= outer_rect->x &&
- inner_rect->y >= outer_rect->y &&
- inner_rect->x + inner_rect->width <= outer_rect->x + outer_rect->width &&
- inner_rect->y + inner_rect->height <= outer_rect->y + outer_rect->height;
-}
-
-void
-meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect,
- MetaRectangle *rect,
- int gravity,
- int new_width,
- int new_height)
-{
- /* FIXME: I'm too deep into this to know whether the below comment is
- * still clear or not now that I've moved it out of constraints.c.
- * boxes.h has a good comment, but I'm not sure if the below info is also
- * helpful on top of that (or whether it has superfluous info).
- */
-
- /* These formulas may look overly simplistic at first but you can work
- * everything out with a left_frame_with, right_frame_width,
- * border_width, and old and new client area widths (instead of old total
- * width and new total width) and you come up with the same formulas.
- *
- * Also, note that the reason we can treat NorthWestGravity and
- * StaticGravity the same is because we're not given a location at
- * which to place the window--the window was already placed
- * appropriately before. So, NorthWestGravity for this function
- * means to just leave the upper left corner of the outer window
- * where it already is, and StaticGravity for this function means to
- * just leave the upper left corner of the inner window where it
- * already is. But leaving either of those two corners where they
- * already are will ensure that the other corner is fixed as well
- * (since frame size doesn't change)--thus making the two
- * equivalent.
- */
-
- /* First, the x direction */
- int adjust = 0;
- switch (gravity)
- {
- case NorthWestGravity:
- case WestGravity:
- case SouthWestGravity:
- rect->x = old_rect->x;
- break;
-
- case NorthGravity:
- case CenterGravity:
- case SouthGravity:
- /* FIXME: Needing to adjust new_width kind of sucks, but not doing so
- * would cause drift.
- */
- new_width -= (old_rect->width - new_width) % 2;
- rect->x = old_rect->x + (old_rect->width - new_width)/2;
- break;
-
- case NorthEastGravity:
- case EastGravity:
- case SouthEastGravity:
- rect->x = old_rect->x + (old_rect->width - new_width);
- break;
-
- case StaticGravity:
- default:
- rect->x = old_rect->x;
- break;
- }
- rect->width = new_width;
-
- /* Next, the y direction */
- adjust = 0;
- switch (gravity)
- {
- case NorthWestGravity:
- case NorthGravity:
- case NorthEastGravity:
- rect->y = old_rect->y;
- break;
-
- case WestGravity:
- case CenterGravity:
- case EastGravity:
- /* FIXME: Needing to adjust new_height kind of sucks, but not doing so
- * would cause drift.
- */
- new_height -= (old_rect->height - new_height) % 2;
- rect->y = old_rect->y + (old_rect->height - new_height)/2;
- break;
-
- case SouthWestGravity:
- case SouthGravity:
- case SouthEastGravity:
- rect->y = old_rect->y + (old_rect->height - new_height);
- break;
-
- case StaticGravity:
- default:
- rect->y = old_rect->y;
- break;
- }
- rect->height = new_height;
-}
-
-/* Not so simple helper function for get_minimal_spanning_set_for_region() */
-static GList*
-merge_spanning_rects_in_region (GList *region)
-{
- /* NOTE FOR ANY OPTIMIZATION PEOPLE OUT THERE: Please see the
- * documentation of get_minimal_spanning_set_for_region() for performance
- * considerations that also apply to this function.
- */
-
- GList* compare;
- compare = region;
-
- if (region == NULL)
- {
- meta_warning ("Region to merge was empty! Either you have a some "
- "pathological STRUT list or there's a bug somewhere!\n");
- return NULL;
- }
-
- while (compare && compare->next)
- {
- MetaRectangle *a = compare->data;
- GList *other = compare->next;
-
- g_assert (a->width > 0 && a->height > 0);
-
- while (other)
- {
- MetaRectangle *b = other->data;
- GList *delete_me = NULL;
-
- g_assert (b->width > 0 && b->height > 0);
-
- /* If a contains b, just remove b */
- if (meta_rectangle_contains_rect (a, b))
- {
- delete_me = other;
- }
- /* If b contains a, just remove a */
- else if (meta_rectangle_contains_rect (a, b))
- {
- delete_me = compare;
- }
- /* If a and b might be mergeable horizontally */
- else if (a->y == b->y && a->height == b->height)
- {
- /* If a and b overlap */
- if (meta_rectangle_overlap (a, b))
- {
- int new_x = MIN (a->x, b->x);
- a->width = MAX (a->x + a->width, b->x + b->width) - new_x;
- a->x = new_x;
- delete_me = other;
- }
- /* If a and b are adjacent */
- else if (a->x + a->width == b->x || a->x == b->x + b->width)
- {
- int new_x = MIN (a->x, b->x);
- a->width = MAX (a->x + a->width, b->x + b->width) - new_x;
- a->x = new_x;
- delete_me = other;
- }
- }
- /* If a and b might be mergeable vertically */
- else if (a->x == b->x && a->width == b->width)
- {
- /* If a and b overlap */
- if (meta_rectangle_overlap (a, b))
- {
- int new_y = MIN (a->y, b->y);
- a->height = MAX (a->y + a->height, b->y + b->height) - new_y;
- a->y = new_y;
- delete_me = other;
- }
- /* If a and b are adjacent */
- else if (a->y + a->height == b->y || a->y == b->y + b->height)
- {
- int new_y = MIN (a->y, b->y);
- a->height = MAX (a->y + a->height, b->y + b->height) - new_y;
- a->y = new_y;
- delete_me = other;
- }
- }
-
- other = other->next;
-
- /* Delete any rectangle in the list that is no longer wanted */
- if (delete_me != NULL)
- {
- /* Deleting the rect we compare others to is a little tricker */
- if (compare == delete_me)
- {
- compare = compare->next;
- other = compare->next;
- a = compare->data;
- }
-
- /* Okay, we can free it now */
- g_free (delete_me->data);
- region = g_list_delete_link (region, delete_me);
- }
-
- }
-
- compare = compare->next;
- }
-
- return region;
-}
-
-/* Simple helper function for get_minimal_spanning_set_for_region()... */
-static gint
-compare_rect_areas (gconstpointer a, gconstpointer b)
-{
- const MetaRectangle *a_rect = (gconstpointer) a;
- const MetaRectangle *b_rect = (gconstpointer) b;
-
- int a_area = meta_rectangle_area (a_rect);
- int b_area = meta_rectangle_area (b_rect);
-
- return b_area - a_area; /* positive ret value denotes b > a, ... */
-}
-
-/* This function is trying to find a "minimal spanning set (of rectangles)"
- * for a given region.
- *
- * The region is given by taking basic_rect, then removing the areas
- * covered by all the rectangles in the all_struts list, and then expanding
- * the resulting region by the given number of pixels in each direction.
- *
- * A "minimal spanning set (of rectangles)" is the best name I could come
- * up with for the concept I had in mind. Basically, for a given region, I
- * want a set of rectangles with the property that a window is contained in
- * the region if and only if it is contained within at least one of the
- * rectangles.
- *
- * The GList* returned will be a list of (allocated) MetaRectangles.
- * The list will need to be freed by calling
- * meta_rectangle_free_spanning_set() on it (or by manually
- * implementing that function...)
- */
-GList*
-meta_rectangle_get_minimal_spanning_set_for_region (
- const MetaRectangle *basic_rect,
- const GSList *all_struts)
-{
- /* NOTE FOR OPTIMIZERS: This function *might* be somewhat slow,
- * especially due to the call to merge_spanning_rects_in_region() (which
- * is O(n^2) where n is the size of the list generated in this function).
- * This is made more onerous due to the fact that it involves a fair
- * number of memory allocation and deallocation calls. However, n is 1
- * for default installations of Gnome (because partial struts aren't used
- * by default and only partial struts increase the size of the spanning
- * set generated). With one partial strut, n will be 2 or 3. With 2
- * partial struts, n will probably be 4 or 5. So, n probably isn't large
- * enough to make this worth bothering. Further, it is only called from
- * workspace.c:ensure_work_areas_validated (at least as of the time of
- * writing this comment), which in turn should only be called if the
- * strut list changes or the screen or xinerama size changes. If it ever
- * does show up on profiles (most likely because people start using
- * ridiculously huge numbers of partial struts), possible optimizations
- * include:
- *
- * (1) rewrite merge_spanning_rects_in_region() to be O(n) or O(nlogn).
- * I'm not totally sure it's possible, but with a couple copies of
- * the list and sorting them appropriately, I believe it might be.
- * (2) only call merge_spanning_rects_in_region() with a subset of the
- * full list of rectangles. I believe from some of my preliminary
- * debugging and thinking about it that it is possible to figure out
- * apriori groups of rectangles which are only merge candidates with
- * each other. (See testboxes.c:get_screen_region() when which==2
- * and track the steps of this function carefully to see what gave
- * me the hint that this might work)
- * (3) figure out how to avoid merge_spanning_rects_in_region(). I think
- * it might be possible to modify this function to make that
- * possible, and I spent just a little while thinking about it, but n
- * wasn't large enough to convince me to care yet.
- * (4) Some of the stuff Rob mentioned at http://mail.gnome.org/archives\
- * /metacity-devel-list/2005-November/msg00028.html. (Sorry for the
- * URL splitting.)
- */
-
- GList *ret;
- GList *tmp_list;
- const GSList *strut_iter;
- MetaRectangle *temp_rect;
-
- /* The algorithm is basically as follows:
- * Initialize rectangle_set to basic_rect
- * Foreach strut:
- * Foreach rectangle in rectangle_set:
- * - Split the rectangle into new rectangles that don't overlap the
- * strut (but which are as big as possible otherwise)
- * - Remove the old (pre-split) rectangle from the rectangle_set,
- * and replace it with the new rectangles generated from the
- * splitting
- */
-
- temp_rect = g_new (MetaRectangle, 1);
- *temp_rect = *basic_rect;
- ret = g_list_prepend (NULL, temp_rect);
-
- strut_iter = all_struts;
- for (strut_iter = all_struts; strut_iter; strut_iter = strut_iter->next)
- {
- GList *rect_iter;
- MetaRectangle *strut_rect = &((MetaStrut*)strut_iter->data)->rect;
-
- tmp_list = ret;
- ret = NULL;
- rect_iter = tmp_list;
- while (rect_iter)
- {
- MetaRectangle *rect = (MetaRectangle*) rect_iter->data;
- if (!meta_rectangle_overlap (rect, strut_rect))
- ret = g_list_prepend (ret, rect);
- else
- {
- /* If there is area in rect left of strut */
- if (BOX_LEFT (*rect) < BOX_LEFT (*strut_rect))
- {
- temp_rect = g_new (MetaRectangle, 1);
- *temp_rect = *rect;
- temp_rect->width = BOX_LEFT (*strut_rect) - BOX_LEFT (*rect);
- ret = g_list_prepend (ret, temp_rect);
- }
- /* If there is area in rect right of strut */
- if (BOX_RIGHT (*rect) > BOX_RIGHT (*strut_rect))
- {
- int new_x;
- temp_rect = g_new (MetaRectangle, 1);
- *temp_rect = *rect;
- new_x = BOX_RIGHT (*strut_rect);
- temp_rect->width = BOX_RIGHT(*rect) - new_x;
- temp_rect->x = new_x;
- ret = g_list_prepend (ret, temp_rect);
- }
- /* If there is area in rect above strut */
- if (BOX_TOP (*rect) < BOX_TOP (*strut_rect))
- {
- temp_rect = g_new (MetaRectangle, 1);
- *temp_rect = *rect;
- temp_rect->height = BOX_TOP (*strut_rect) - BOX_TOP (*rect);
- ret = g_list_prepend (ret, temp_rect);
- }
- /* If there is area in rect below strut */
- if (BOX_BOTTOM (*rect) > BOX_BOTTOM (*strut_rect))
- {
- int new_y;
- temp_rect = g_new (MetaRectangle, 1);
- *temp_rect = *rect;
- new_y = BOX_BOTTOM (*strut_rect);
- temp_rect->height = BOX_BOTTOM (*rect) - new_y;
- temp_rect->y = new_y;
- ret = g_list_prepend (ret, temp_rect);
- }
- g_free (rect);
- }
- rect_iter = rect_iter->next;
- }
- g_list_free (tmp_list);
- }
-
- /* Sort by maximal area, just because I feel like it... */
- ret = g_list_sort (ret, compare_rect_areas);
-
- /* Merge rectangles if possible so that the list really is minimal */
- ret = merge_spanning_rects_in_region (ret);
-
- return ret;
-}
-
-GList*
-meta_rectangle_expand_region (GList *region,
- const int left_expand,
- const int right_expand,
- const int top_expand,
- const int bottom_expand)
-{
- return meta_rectangle_expand_region_conditionally (region,
- left_expand,
- right_expand,
- top_expand,
- bottom_expand,
- 0,
- 0);
-}
-
-GList*
-meta_rectangle_expand_region_conditionally (GList *region,
- const int left_expand,
- const int right_expand,
- const int top_expand,
- const int bottom_expand,
- const int min_x,
- const int min_y)
-{
- GList *tmp_list = region;
- while (tmp_list)
- {
- MetaRectangle *rect = (MetaRectangle*) tmp_list->data;
- if (rect->width >= min_x)
- {
- rect->x -= left_expand;
- rect->width += (left_expand + right_expand);
- }
- if (rect->height >= min_y)
- {
- rect->y -= top_expand;
- rect->height += (top_expand + bottom_expand);
- }
- tmp_list = tmp_list->next;
- }
-
- return region;
-}
-
-void
-meta_rectangle_expand_to_avoiding_struts (MetaRectangle *rect,
- const MetaRectangle *expand_to,
- const MetaDirection direction,
- const GSList *all_struts)
-{
- const GSList *strut_iter;
-
- /* If someone wants this function to handle more fine-grained
- * direction expanding in the future (e.g. only left, or fully
- * horizontal plus upward), feel free. But I'm hard-coding for both
- * horizontal directions (exclusive-)or both vertical directions.
- */
- g_assert ((direction == META_DIRECTION_HORIZONTAL) ^
- (direction == META_DIRECTION_VERTICAL ));
-
- if (direction == META_DIRECTION_HORIZONTAL)
- {
- rect->x = expand_to->x;
- rect->width = expand_to->width;
- }
- else
- {
- rect->y = expand_to->y;
- rect->height = expand_to->height;
- }
-
-
- /* Run over all struts */
- for (strut_iter = all_struts; strut_iter; strut_iter = strut_iter->next)
- {
- MetaStrut *strut = (MetaStrut*) strut_iter->data;
-
- /* Skip struts that don't overlap */
- if (!meta_rectangle_overlap (&strut->rect, rect))
- continue;
-
- if (direction == META_DIRECTION_HORIZONTAL)
- {
- if (strut->side == META_SIDE_LEFT)
- {
- int offset = BOX_RIGHT(strut->rect) - BOX_LEFT(*rect);
- rect->x += offset;
- rect->width -= offset;
- }
- else if (strut->side == META_SIDE_RIGHT)
- {
- int offset = BOX_RIGHT (*rect) - BOX_LEFT(strut->rect);
- rect->width -= offset;
- }
- /* else ignore the strut */
- }
- else /* direction == META_DIRECTION_VERTICAL */
- {
- if (strut->side == META_SIDE_TOP)
- {
- int offset = BOX_BOTTOM(strut->rect) - BOX_TOP(*rect);
- rect->y += offset;
- rect->height -= offset;
- }
- else if (strut->side == META_SIDE_BOTTOM)
- {
- int offset = BOX_BOTTOM(*rect) - BOX_TOP(strut->rect);
- rect->height -= offset;
- }
- /* else ignore the strut */
- }
- } /* end loop over struts */
-} /* end meta_rectangle_expand_to_avoiding_struts */
-
-void
-meta_rectangle_free_list_and_elements (GList *filled_list)
-{
- g_list_foreach (filled_list,
- (void (*)(gpointer,gpointer))&g_free, /* ew, for ugly */
- NULL);
- g_list_free (filled_list);
-}
-
-gboolean
-meta_rectangle_could_fit_in_region (const GList *spanning_rects,
- const MetaRectangle *rect)
-{
- const GList *temp;
- gboolean could_fit;
-
- temp = spanning_rects;
- could_fit = FALSE;
- while (!could_fit && temp != NULL)
- {
- could_fit = could_fit || meta_rectangle_could_fit_rect (temp->data, rect);
- temp = temp->next;
- }
-
- return could_fit;
-}
-
-gboolean
-meta_rectangle_contained_in_region (const GList *spanning_rects,
- const MetaRectangle *rect)
-{
- const GList *temp;
- gboolean contained;
-
- temp = spanning_rects;
- contained = FALSE;
- while (!contained && temp != NULL)
- {
- contained = contained || meta_rectangle_contains_rect (temp->data, rect);
- temp = temp->next;
- }
-
- return contained;
-}
-
-gboolean
-meta_rectangle_overlaps_with_region (const GList *spanning_rects,
- const MetaRectangle *rect)
-{
- const GList *temp;
- gboolean overlaps;
-
- temp = spanning_rects;
- overlaps = FALSE;
- while (!overlaps && temp != NULL)
- {
- overlaps = overlaps || meta_rectangle_overlap (temp->data, rect);
- temp = temp->next;
- }
-
- return overlaps;
-}
-
-
-void
-meta_rectangle_clamp_to_fit_into_region (const GList *spanning_rects,
- FixedDirections fixed_directions,
- MetaRectangle *rect,
- const MetaRectangle *min_size)
-{
- const GList *temp;
- const MetaRectangle *best_rect = NULL;
- int best_overlap = 0;
-
- /* First, find best rectangle from spanning_rects to which we can clamp
- * rect to fit into.
- */
- for (temp = spanning_rects; temp; temp = temp->next)
- {
- MetaRectangle *compare_rect = temp->data;
- int maximal_overlap_amount_for_compare;
-
- /* If x is fixed and the entire width of rect doesn't fit in compare,
- * skip this rectangle.
- */
- if ((fixed_directions & FIXED_DIRECTION_X) &&
- (compare_rect->x > rect->x ||
- compare_rect->x + compare_rect->width < rect->x + rect->width))
- continue;
-
- /* If y is fixed and the entire height of rect doesn't fit in compare,
- * skip this rectangle.
- */
- if ((fixed_directions & FIXED_DIRECTION_Y) &&
- (compare_rect->y > rect->y ||
- compare_rect->y + compare_rect->height < rect->y + rect->height))
- continue;
-
- /* If compare can't hold the min_size window, skip this rectangle. */
- if (compare_rect->width < min_size->width ||
- compare_rect->height < min_size->height)
- continue;
-
- /* Determine maximal overlap amount */
- maximal_overlap_amount_for_compare =
- MIN (rect->width, compare_rect->width) *
- MIN (rect->height, compare_rect->height);
-
- /* See if this is the best rect so far */
- if (maximal_overlap_amount_for_compare > best_overlap)
- {
- best_rect = compare_rect;
- best_overlap = maximal_overlap_amount_for_compare;
- }
- }
-
- /* Clamp rect appropriately */
- if (best_rect == NULL)
- {
- meta_warning ("No rect whose size to clamp to found!\n");
-
- /* If it doesn't fit, at least make it no bigger than it has to be */
- if (!(fixed_directions & FIXED_DIRECTION_X))
- rect->width = min_size->width;
- if (!(fixed_directions & FIXED_DIRECTION_Y))
- rect->height = min_size->height;
- }
- else
- {
- rect->width = MIN (rect->width, best_rect->width);
- rect->height = MIN (rect->height, best_rect->height);
- }
-}
-
-void
-meta_rectangle_clip_to_region (const GList *spanning_rects,
- FixedDirections fixed_directions,
- MetaRectangle *rect)
-{
- const GList *temp;
- const MetaRectangle *best_rect = NULL;
- int best_overlap = 0;
-
- /* First, find best rectangle from spanning_rects to which we will clip
- * rect into.
- */
- for (temp = spanning_rects; temp; temp = temp->next)
- {
- MetaRectangle *compare_rect = temp->data;
- MetaRectangle overlap;
- int maximal_overlap_amount_for_compare;
-
- /* If x is fixed and the entire width of rect doesn't fit in compare,
- * skip the rectangle.
- */
- if ((fixed_directions & FIXED_DIRECTION_X) &&
- (compare_rect->x > rect->x ||
- compare_rect->x + compare_rect->width < rect->x + rect->width))
- continue;
-
- /* If y is fixed and the entire height of rect doesn't fit in compare,
- * skip the rectangle.
- */
- if ((fixed_directions & FIXED_DIRECTION_Y) &&
- (compare_rect->y > rect->y ||
- compare_rect->y + compare_rect->height < rect->y + rect->height))
- continue;
-
- /* Determine maximal overlap amount */
- meta_rectangle_intersect (rect, compare_rect, &overlap);
- maximal_overlap_amount_for_compare = meta_rectangle_area (&overlap);
-
- /* See if this is the best rect so far */
- if (maximal_overlap_amount_for_compare > best_overlap)
- {
- best_rect = compare_rect;
- best_overlap = maximal_overlap_amount_for_compare;
- }
- }
-
- /* Clip rect appropriately */
- if (best_rect == NULL)
- meta_warning ("No rect to clip to found!\n");
- else
- {
- /* Extra precaution with checking fixed direction shouldn't be needed
- * due to logic above, but it shouldn't hurt either.
- */
- if (!(fixed_directions & FIXED_DIRECTION_X))
- {
- /* Find the new left and right */
- int new_x = MAX (rect->x, best_rect->x);
- rect->width = MIN ((rect->x + rect->width) - new_x,
- (best_rect->x + best_rect->width) - new_x);
- rect->x = new_x;
- }
-
- /* Extra precaution with checking fixed direction shouldn't be needed
- * due to logic above, but it shouldn't hurt either.
- */
- if (!(fixed_directions & FIXED_DIRECTION_Y))
- {
- /* Clip the top, if needed */
- int new_y = MAX (rect->y, best_rect->y);
- rect->height = MIN ((rect->y + rect->height) - new_y,
- (best_rect->y + best_rect->height) - new_y);
- rect->y = new_y;
- }
- }
-}
-
-void
-meta_rectangle_shove_into_region (const GList *spanning_rects,
- FixedDirections fixed_directions,
- MetaRectangle *rect)
-{
- const GList *temp;
- const MetaRectangle *best_rect = NULL;
- int best_overlap = 0;
- int shortest_distance = G_MAXINT;
-
- /* First, find best rectangle from spanning_rects to which we will shove
- * rect into.
- */
-
- for (temp = spanning_rects; temp; temp = temp->next)
- {
- MetaRectangle *compare_rect = temp->data;
- int maximal_overlap_amount_for_compare;
- int dist_to_compare;
-
- /* If x is fixed and the entire width of rect doesn't fit in compare,
- * skip this rectangle.
- */
- if ((fixed_directions & FIXED_DIRECTION_X) &&
- (compare_rect->x > rect->x ||
- compare_rect->x + compare_rect->width < rect->x + rect->width))
- continue;
-
- /* If y is fixed and the entire height of rect doesn't fit in compare,
- * skip this rectangle.
- */
- if ((fixed_directions & FIXED_DIRECTION_Y) &&
- (compare_rect->y > rect->y ||
- compare_rect->y + compare_rect->height < rect->y + rect->height))
- continue;
-
- /* Determine maximal overlap amount between rect & compare_rect */
- maximal_overlap_amount_for_compare =
- MIN (rect->width, compare_rect->width) *
- MIN (rect->height, compare_rect->height);
-
- /* Determine distance necessary to put rect into compare_rect */
- dist_to_compare = 0;
- if (compare_rect->x > rect->x)
- dist_to_compare += compare_rect->x - rect->x;
- if (compare_rect->x + compare_rect->width < rect->x + rect->width)
- dist_to_compare += (rect->x + rect->width) -
- (compare_rect->x + compare_rect->width);
- if (compare_rect->y > rect->y)
- dist_to_compare += compare_rect->y - rect->y;
- if (compare_rect->y + compare_rect->height < rect->y + rect->height)
- dist_to_compare += (rect->y + rect->height) -
- (compare_rect->y + compare_rect->height);
-
- /* See if this is the best rect so far */
- if ((maximal_overlap_amount_for_compare > best_overlap) ||
- (maximal_overlap_amount_for_compare == best_overlap &&
- dist_to_compare < shortest_distance))
- {
- best_rect = compare_rect;
- best_overlap = maximal_overlap_amount_for_compare;
- shortest_distance = dist_to_compare;
- }
- }
-
- /* Shove rect appropriately */
- if (best_rect == NULL)
- meta_warning ("No rect to shove into found!\n");
- else
- {
- /* Extra precaution with checking fixed direction shouldn't be needed
- * due to logic above, but it shouldn't hurt either.
- */
- if (!(fixed_directions & FIXED_DIRECTION_X))
- {
- /* Shove to the right, if needed */
- if (best_rect->x > rect->x)
- rect->x = best_rect->x;
-
- /* Shove to the left, if needed */
- if (best_rect->x + best_rect->width < rect->x + rect->width)
- rect->x = (best_rect->x + best_rect->width) - rect->width;
- }
-
- /* Extra precaution with checking fixed direction shouldn't be needed
- * due to logic above, but it shouldn't hurt either.
- */
- if (!(fixed_directions & FIXED_DIRECTION_Y))
- {
- /* Shove down, if needed */
- if (best_rect->y > rect->y)
- rect->y = best_rect->y;
-
- /* Shove up, if needed */
- if (best_rect->y + best_rect->height < rect->y + rect->height)
- rect->y = (best_rect->y + best_rect->height) - rect->height;
- }
- }
-}
-
-void
-meta_rectangle_find_linepoint_closest_to_point (double x1,
- double y1,
- double x2,
- double y2,
- double px,
- double py,
- double *valx,
- double *valy)
-{
- /* I'll use the shorthand rx, ry for the return values, valx & valy.
- * Now, we need (rx,ry) to be on the line between (x1,y1) and (x2,y2).
- * For that to happen, we first need the slope of the line from (x1,y1)
- * to (rx,ry) must match the slope of (x1,y1) to (x2,y2), i.e.:
- * (ry-y1) (y2-y1)
- * ------- = -------
- * (rx-x1) (x2-x1)
- * If x1==x2, though, this gives divide by zero errors, so we want to
- * rewrite the equation by multiplying both sides by (rx-x1)*(x2-x1):
- * (ry-y1)(x2-x1) = (y2-y1)(rx-x1)
- * This is a valid requirement even when x1==x2 (when x1==x2, this latter
- * equation will basically just mean that rx must be equal to both x1 and
- * x2)
- *
- * The other requirement that we have is that the line from (rx,ry) to
- * (px,py) must be perpendicular to the line from (x1,y1) to (x2,y2). So
- * we just need to get a vector in the direction of each line, take the
- * dot product of the two, and ensure that the result is 0:
- * (rx-px)*(x2-x1) + (ry-py)*(y2-y1) = 0.
- *
- * This gives us two equations and two unknowns:
- *
- * (ry-y1)(x2-x1) = (y2-y1)(rx-x1)
- * (rx-px)*(x2-x1) + (ry-py)*(y2-y1) = 0.
- *
- * This particular pair of equations is always solvable so long as
- * (x1,y1) and (x2,y2) are not the same point (and note that anyone who
- * calls this function that way is braindead because it means that they
- * really didn't specify a line after all). However, the caller should
- * be careful to avoid making (x1,y1) and (x2,y2) too close (e.g. like
- * 10^{-8} apart in each coordinate), otherwise roundoff error could
- * cause issues. Solving these equations by hand (or using Maple(TM) or
- * Mathematica(TM) or whatever) results in slightly messy expressions,
- * but that's all the below few lines do.
- */
-
- double diffx, diffy, den;
- diffx = x2 - x1;
- diffy = y2 - y1;
- den = diffx * diffx + diffy * diffy;
-
- *valx = (py * diffx * diffy + px * diffx * diffx +
- y2 * x1 * diffy - y1 * x2 * diffy) / den;
- *valy = (px * diffx * diffy + py * diffy * diffy +
- x2 * y1 * diffx - x1 * y2 * diffx) / den;
-}
-
-/***************************************************************************/
-/* */
-/* Switching gears to code for edges instead of just rectangles */
-/* */
-/***************************************************************************/
-
-gboolean
-meta_rectangle_edge_aligns (const MetaRectangle *rect, const MetaEdge *edge)
-{
- /* The reason for the usage of <= below instead of < is because we are
- * interested in in-the-way-or-adject'ness. So, a left (i.e. vertical
- * edge) occupying y positions 0-9 (which has a y of 0 and a height of
- * 10) and a rectangle with top at y=10 would be considered to "align" by
- * this function.
- */
- switch (edge->side_type)
- {
- case META_DIRECTION_LEFT:
- case META_DIRECTION_RIGHT:
- return BOX_TOP (*rect) <= BOX_BOTTOM (edge->rect) &&
- BOX_TOP (edge->rect) <= BOX_BOTTOM (*rect);
- case META_DIRECTION_TOP:
- case META_DIRECTION_BOTTOM:
- return BOX_LEFT (*rect) <= BOX_RIGHT (edge->rect) &&
- BOX_LEFT (edge->rect) <= BOX_RIGHT (*rect);
- default:
- g_assert_not_reached ();
- }
-}
-
-static GList*
-get_rect_minus_overlap (const GList *rect_in_list,
- MetaRectangle *overlap)
-{
- MetaRectangle *temp;
- MetaRectangle *rect = rect_in_list->data;
- GList *ret = NULL;
-
- if (BOX_LEFT (*rect) < BOX_LEFT (*overlap))
- {
- temp = g_new (MetaRectangle, 1);
- *temp = *rect;
- temp->width = BOX_LEFT (*overlap) - BOX_LEFT (*rect);
- ret = g_list_prepend (ret, temp);
- }
- if (BOX_RIGHT (*rect) > BOX_RIGHT (*overlap))
- {
- temp = g_new (MetaRectangle, 1);
- *temp = *rect;
- temp->x = BOX_RIGHT (*overlap);
- temp->width = BOX_RIGHT (*rect) - BOX_RIGHT (*overlap);
- ret = g_list_prepend (ret, temp);
- }
- if (BOX_TOP (*rect) < BOX_TOP (*overlap))
- {
- temp = g_new (MetaRectangle, 1);
- temp->x = overlap->x;
- temp->width = overlap->width;
- temp->y = BOX_TOP (*rect);
- temp->height = BOX_TOP (*overlap) - BOX_TOP (*rect);
- ret = g_list_prepend (ret, temp);
- }
- if (BOX_BOTTOM (*rect) > BOX_BOTTOM (*overlap))
- {
- temp = g_new (MetaRectangle, 1);
- temp->x = overlap->x;
- temp->width = overlap->width;
- temp->y = BOX_BOTTOM (*overlap);
- temp->height = BOX_BOTTOM (*rect) - BOX_BOTTOM (*overlap);
- ret = g_list_prepend (ret, temp);
- }
-
- return ret;
-}
-
-static GList*
-replace_rect_with_list (GList *old_element,
- GList *new_list)
-{
- GList *ret;
- g_assert (old_element != NULL);
-
- if (!new_list)
- {
- /* If there is no new list, just remove the old_element */
- ret = g_list_remove_link (old_element, old_element);
- }
- else
- {
- /* Fix up the prev and next pointers everywhere */
- ret = new_list;
- if (old_element->prev)
- {
- old_element->prev->next = new_list;
- new_list->prev = old_element->prev;
- }
- if (old_element->next)
- {
- GList *tmp = g_list_last (new_list);
- old_element->next->prev = tmp;
- tmp->next = old_element->next;
- }
- }
-
- /* Free the old_element and return the appropriate "next" point */
- g_free (old_element->data);
- g_list_free_1 (old_element);
- return ret;
-}
-
-/* Make a copy of the strut list, make sure that copy only contains parts
- * of the old_struts that intersect with the region rect, and then do some
- * magic to make all the new struts disjoint (okay, we we break up struts
- * that aren't disjoint in a way that the overlapping part is only included
- * once, so it's not really magic...).
- */
-static GList*
-get_disjoint_strut_rect_list_in_region (const GSList *old_struts,
- const MetaRectangle *region)
-{
- GList *strut_rects;
- GList *tmp;
-
- /* First, copy the list */
- strut_rects = NULL;
- while (old_struts)
- {
- MetaRectangle *cur = &((MetaStrut*)old_struts->data)->rect;
- MetaRectangle *copy = g_new (MetaRectangle, 1);
- *copy = *cur;
- if (meta_rectangle_intersect (copy, region, copy))
- strut_rects = g_list_prepend (strut_rects, copy);
- else
- g_free (copy);
-
- old_struts = old_struts->next;
- }
-
- /* Now, loop over the list and check for intersections, fixing things up
- * where they do intersect.
- */
- tmp = strut_rects;
- while (tmp)
- {
- GList *compare;
-
- MetaRectangle *cur = tmp->data;
-
- compare = tmp->next;
- while (compare)
- {
- MetaRectangle *comp = compare->data;
- MetaRectangle overlap;
-
- if (meta_rectangle_intersect (cur, comp, &overlap))
- {
- /* Get a list of rectangles for each strut that don't overlap
- * the intersection region.
- */
- GList *cur_leftover = get_rect_minus_overlap (tmp, &overlap);
- GList *comp_leftover = get_rect_minus_overlap (compare, &overlap);
-
- /* Add the intersection region to cur_leftover */
- MetaRectangle *overlap_allocated = g_new (MetaRectangle, 1);
- *overlap_allocated = overlap;
- cur_leftover = g_list_prepend (cur_leftover, overlap_allocated);
-
- /* Fix up tmp, compare, and cur -- maybe struts too */
- if (strut_rects == tmp)
- {
- strut_rects = replace_rect_with_list (tmp, cur_leftover);
- tmp = strut_rects;
- }
- else
- tmp = replace_rect_with_list (tmp, cur_leftover);
- compare = replace_rect_with_list (compare, comp_leftover);
-
- if (compare == NULL)
- break;
-
- cur = tmp->data;
- }
-
- compare = compare->next;
- }
-
- tmp = tmp->next;
- }
-
- return strut_rects;
-}
-
-gint
-meta_rectangle_edge_cmp_ignore_type (gconstpointer a, gconstpointer b)
-{
- const MetaEdge *a_edge_rect = (gconstpointer) a;
- const MetaEdge *b_edge_rect = (gconstpointer) b;
- int a_compare, b_compare;
-
- /* Edges must be both vertical or both horizontal, or it doesn't make
- * sense to compare them.
- */
- g_assert ((a_edge_rect->rect.width == 0 && b_edge_rect->rect.width == 0) ||
- (a_edge_rect->rect.height == 0 && b_edge_rect->rect.height == 0));
-
- a_compare = b_compare = 0; /* gcc-3.4.2 sucks at figuring initialized'ness */
-
- if (a_edge_rect->side_type == META_DIRECTION_LEFT ||
- a_edge_rect->side_type == META_DIRECTION_RIGHT)
- {
- a_compare = a_edge_rect->rect.x;
- b_compare = b_edge_rect->rect.x;
- if (a_compare == b_compare)
- {
- a_compare = a_edge_rect->rect.y;
- b_compare = b_edge_rect->rect.y;
- }
- }
- else if (a_edge_rect->side_type == META_DIRECTION_TOP ||
- a_edge_rect->side_type == META_DIRECTION_BOTTOM)
- {
- a_compare = a_edge_rect->rect.y;
- b_compare = b_edge_rect->rect.y;
- if (a_compare == b_compare)
- {
- a_compare = a_edge_rect->rect.x;
- b_compare = b_edge_rect->rect.x;
- }
- }
- else
- g_assert ("Some idiot wanted to sort sides of different types.\n");
-
- return a_compare - b_compare; /* positive value denotes a > b ... */
-}
-
-/* To make things easily testable, provide a nice way of sorting edges */
-gint
-meta_rectangle_edge_cmp (gconstpointer a, gconstpointer b)
-{
- const MetaEdge *a_edge_rect = (gconstpointer) a;
- const MetaEdge *b_edge_rect = (gconstpointer) b;
-
- int a_compare, b_compare;
-
- a_compare = a_edge_rect->side_type;
- b_compare = b_edge_rect->side_type;
-
- if (a_compare == b_compare)
- return meta_rectangle_edge_cmp_ignore_type (a, b);
-
- return a_compare - b_compare; /* positive value denotes a > b ... */
-}
-
-/* Determine whether two given edges overlap */
-static gboolean
-edges_overlap (const MetaEdge *edge1,
- const MetaEdge *edge2)
-{
- if (edge1->rect.width == 0 && edge2->rect.width == 0)
- {
- return meta_rectangle_vert_overlap (&edge1->rect, &edge2->rect) &&
- edge1->rect.x == edge2->rect.x;
- }
- else if (edge1->rect.height == 0 && edge2->rect.height == 0)
- {
- return meta_rectangle_horiz_overlap (&edge1->rect, &edge2->rect) &&
- edge1->rect.y == edge2->rect.y;
- }
- else
- {
- return FALSE;
- }
-}
-
-static gboolean
-rectangle_and_edge_intersection (const MetaRectangle *rect,
- const MetaEdge *edge,
- MetaEdge *overlap,
- int *handle_type)
-{
- const MetaRectangle *rect2 = &edge->rect;
- MetaRectangle *result = &overlap->rect;
- gboolean intersect = TRUE;
-
- /* We don't know how to set these, so set them to invalid values */
- overlap->edge_type = -1;
- overlap->side_type = -1;
-
- /* Figure out what the intersection is */
- result->x = MAX (rect->x, rect2->x);
- result->y = MAX (rect->y, rect2->y);
- result->width = MIN (BOX_RIGHT (*rect), BOX_RIGHT (*rect2)) - result->x;
- result->height = MIN (BOX_BOTTOM (*rect), BOX_BOTTOM (*rect2)) - result->y;
-
- /* Find out if the intersection is empty; have to do it this way since
- * edges have a thickness of 0
- */
- if ((result->width < 0 || result->height < 0) ||
- (result->width == 0 && result->height == 0))
- {
- result->width = 0;
- result->height = 0;
- intersect = FALSE;
- }
- else
- {
- /* Need to figure out the handle_type, a somewhat weird quantity:
- * 0 - overlap is in middle of rect
- * -1 - overlap is at the side of rect, and is on the opposite side
- * of rect than the edge->side_type side
- * 1 - overlap is at the side of rect, and the side of rect it is
- * on is the edge->side_type side
- */
- switch (edge->side_type)
- {
- case META_DIRECTION_LEFT:
- if (result->x == rect->x)
- *handle_type = 1;
- else if (result->x == BOX_RIGHT (*rect))
- *handle_type = -1;
- else
- *handle_type = 0;
- break;
- case META_DIRECTION_RIGHT:
- if (result->x == rect->x)
- *handle_type = -1;
- else if (result->x == BOX_RIGHT (*rect))
- *handle_type = 1;
- else
- *handle_type = 0;
- break;
- case META_DIRECTION_TOP:
- if (result->y == rect->y)
- *handle_type = 1;
- else if (result->y == BOX_BOTTOM (*rect))
- *handle_type = -1;
- else
- *handle_type = 0;
- break;
- case META_DIRECTION_BOTTOM:
- if (result->y == rect->y)
- *handle_type = -1;
- else if (result->y == BOX_BOTTOM (*rect))
- *handle_type = 1;
- else
- *handle_type = 0;
- break;
- default:
- g_assert_not_reached ();
- }
- }
- return intersect;
-}
-
-/* Add all edges of the given rect to cur_edges and return the result. If
- * rect_is_internal is false, the side types are switched (LEFT<->RIGHT and
- * TOP<->BOTTOM).
- */
-static GList*
-add_edges (GList *cur_edges,
- const MetaRectangle *rect,
- gboolean rect_is_internal)
-{
- MetaEdge *temp_edge;
- int i;
-
- for (i=0; i<4; i++)
- {
- temp_edge = g_new (MetaEdge, 1);
- temp_edge->rect = *rect;
- switch (i)
- {
- case 0:
- temp_edge->side_type =
- rect_is_internal ? META_DIRECTION_LEFT : META_DIRECTION_RIGHT;
- temp_edge->rect.width = 0;
- break;
- case 1:
- temp_edge->side_type =
- rect_is_internal ? META_DIRECTION_RIGHT : META_DIRECTION_LEFT;
- temp_edge->rect.x += temp_edge->rect.width;
- temp_edge->rect.width = 0;
- break;
- case 2:
- temp_edge->side_type =
- rect_is_internal ? META_DIRECTION_TOP : META_DIRECTION_BOTTOM;
- temp_edge->rect.height = 0;
- break;
- case 3:
- temp_edge->side_type =
- rect_is_internal ? META_DIRECTION_BOTTOM : META_DIRECTION_TOP;
- temp_edge->rect.y += temp_edge->rect.height;
- temp_edge->rect.height = 0;
- break;
- }
- temp_edge->edge_type = META_EDGE_SCREEN;
- cur_edges = g_list_prepend (cur_edges, temp_edge);
- }
-
- return cur_edges;
-}
-
-/* Remove any part of old_edge that intersects remove and add any resulting
- * edges to cur_list. Return cur_list when finished.
- */
-static GList*
-split_edge (GList *cur_list,
- const MetaEdge *old_edge,
- const MetaEdge *remove)
-{
- MetaEdge *temp_edge;
- switch (old_edge->side_type)
- {
- case META_DIRECTION_LEFT:
- case META_DIRECTION_RIGHT:
- g_assert (meta_rectangle_vert_overlap (&old_edge->rect, &remove->rect));
- if (BOX_TOP (old_edge->rect) < BOX_TOP (remove->rect))
- {
- temp_edge = g_new (MetaEdge, 1);
- *temp_edge = *old_edge;
- temp_edge->rect.height = BOX_TOP (remove->rect)
- - BOX_TOP (old_edge->rect);
- cur_list = g_list_prepend (cur_list, temp_edge);
- }
- if (BOX_BOTTOM (old_edge->rect) > BOX_BOTTOM (remove->rect))
- {
- temp_edge = g_new (MetaEdge, 1);
- *temp_edge = *old_edge;
- temp_edge->rect.y = BOX_BOTTOM (remove->rect);
- temp_edge->rect.height = BOX_BOTTOM (old_edge->rect)
- - BOX_BOTTOM (remove->rect);
- cur_list = g_list_prepend (cur_list, temp_edge);
- }
- break;
- case META_DIRECTION_TOP:
- case META_DIRECTION_BOTTOM:
- g_assert (meta_rectangle_horiz_overlap (&old_edge->rect, &remove->rect));
- if (BOX_LEFT (old_edge->rect) < BOX_LEFT (remove->rect))
- {
- temp_edge = g_new (MetaEdge, 1);
- *temp_edge = *old_edge;
- temp_edge->rect.width = BOX_LEFT (remove->rect)
- - BOX_LEFT (old_edge->rect);
- cur_list = g_list_prepend (cur_list, temp_edge);
- }
- if (BOX_RIGHT (old_edge->rect) > BOX_RIGHT (remove->rect))
- {
- temp_edge = g_new (MetaEdge, 1);
- *temp_edge = *old_edge;
- temp_edge->rect.x = BOX_RIGHT (remove->rect);
- temp_edge->rect.width = BOX_RIGHT (old_edge->rect)
- - BOX_RIGHT (remove->rect);
- cur_list = g_list_prepend (cur_list, temp_edge);
- }
- break;
- default:
- g_assert_not_reached ();
- }
-
- return cur_list;
-}
-
-/* Split up edge and remove preliminary edges from strut_edges depending on
- * if and how rect and edge intersect.
- */
-static void
-fix_up_edges (MetaRectangle *rect, MetaEdge *edge,
- GList **strut_edges, GList **edge_splits,
- gboolean *edge_needs_removal)
-{
- MetaEdge overlap;
- int handle_type;
-
- if (!rectangle_and_edge_intersection (rect, edge, &overlap, &handle_type))
- return;
-
- if (handle_type == 0 || handle_type == 1)
- {
- /* Put the result of removing overlap from edge into edge_splits */
- *edge_splits = split_edge (*edge_splits, edge, &overlap);
- *edge_needs_removal = TRUE;
- }
-
- if (handle_type == -1 || handle_type == 1)
- {
- /* Remove the overlap from strut_edges */
- /* First, loop over the edges of the strut */
- GList *tmp = *strut_edges;
- while (tmp)
- {
- MetaEdge *cur = tmp->data;
- /* If this is the edge that overlaps, then we need to split it */
- if (edges_overlap (cur, &overlap))
- {
- GList *delete_me = tmp;
-
- /* Split this edge into some new ones */
- *strut_edges = split_edge (*strut_edges, cur, &overlap);
-
- /* Delete the old one */
- tmp = tmp->next;
- g_free (cur);
- *strut_edges = g_list_delete_link (*strut_edges, delete_me);
- }
- else
- tmp = tmp->next;
- }
- }
-}
-
-/* This function removes intersections of edges with the rectangles from the
- * list of edges.
- */
-GList*
-meta_rectangle_remove_intersections_with_boxes_from_edges (
- GList *edges,
- const GSList *rectangles)
-{
- const GSList *rect_iter;
- const int opposing = 1;
-
- /* Now remove all intersections of rectangles with the edge list */
- rect_iter = rectangles;
- while (rect_iter)
- {
- MetaRectangle *rect = rect_iter->data;
- GList *edge_iter = edges;
- while (edge_iter)
- {
- MetaEdge *edge = edge_iter->data;
- MetaEdge overlap;
- int handle;
- gboolean edge_iter_advanced = FALSE;
-
- /* If this edge overlaps with this rect... */
- if (rectangle_and_edge_intersection (rect, edge, &overlap, &handle))
- {
-
- /* "Intersections" where the edges touch but are opposite
- * sides (e.g. a left edge against the right edge) should not
- * be split. Note that the comments in
- * rectangle_and_edge_intersection() say that opposing edges
- * occur when handle is -1, BUT you need to remember that we
- * treat the left side of a window as a right edge because
- * it's what the right side of the window being moved should
- * be-resisted-by/snap-to. So opposing is really 1. Anyway,
- * we just keep track of it in the opposing constant set up
- * above and if handle isn't equal to that, then we know the
- * edge should be split.
- */
- if (handle != opposing)
- {
- /* Keep track of this edge so we can delete it below */
- GList *delete_me = edge_iter;
- edge_iter = edge_iter->next;
- edge_iter_advanced = TRUE;
-
- /* Split the edge and add the result to beginning of edges */
- edges = split_edge (edges, edge, &overlap);
-
- /* Now free the edge... */
- g_free (edge);
- edges = g_list_delete_link (edges, delete_me);
- }
- }
-
- if (!edge_iter_advanced)
- edge_iter = edge_iter->next;
- }
-
- rect_iter = rect_iter->next;
- }
-
- return edges;
-}
-
-/* This function is trying to find all the edges of an onscreen region. */
-GList*
-meta_rectangle_find_onscreen_edges (const MetaRectangle *basic_rect,
- const GSList *all_struts)
-{
- GList *ret;
- GList *fixed_strut_rects;
- GList *edge_iter;
- const GList *strut_rect_iter;
-
- /* The algorithm is basically as follows:
- * Make sure the struts are disjoint
- * Initialize the edge_set to the edges of basic_rect
- * Foreach strut:
- * Put together a preliminary new edge from the edges of the strut
- * Foreach edge in edge_set:
- * - Split the edge if it is partially contained inside the strut
- * - If the edge matches an edge of the strut (i.e. a strut just
- * against the edge of the screen or a not-next-to-edge-of-screen
- * strut adjacent to another), then both the edge from the
- * edge_set and the preliminary edge for the strut will need to
- * be split
- * Add any remaining "preliminary" strut edges to the edge_set
- */
-
- /* Make sure the struts are disjoint */
- fixed_strut_rects =
- get_disjoint_strut_rect_list_in_region (all_struts, basic_rect);
-
- /* Start off the list with the edges of basic_rect */
- ret = add_edges (NULL, basic_rect, TRUE);
-
- strut_rect_iter = fixed_strut_rects;
- while (strut_rect_iter)
- {
- MetaRectangle *strut_rect = (MetaRectangle*) strut_rect_iter->data;
-
- /* Get the new possible edges we may need to add from the strut */
- GList *new_strut_edges = add_edges (NULL, strut_rect, FALSE);
-
- edge_iter = ret;
- while (edge_iter)
- {
- MetaEdge *cur_edge = edge_iter->data;
- GList *splits_of_cur_edge = NULL;
- gboolean edge_needs_removal = FALSE;
-
- fix_up_edges (strut_rect, cur_edge,
- &new_strut_edges, &splits_of_cur_edge,
- &edge_needs_removal);
-
- if (edge_needs_removal)
- {
- /* Delete the old edge */
- GList *delete_me = edge_iter;
- edge_iter = edge_iter->next;
- g_free (cur_edge);
- ret = g_list_delete_link (ret, delete_me);
-
- /* Add the new split parts of the edge */
- ret = g_list_concat (splits_of_cur_edge, ret);
- }
- else
- {
- edge_iter = edge_iter->next;
- }
-
- /* edge_iter was already advanced above */
- }
-
- ret = g_list_concat (new_strut_edges, ret);
- strut_rect_iter = strut_rect_iter->next;
- }
-
- /* Sort the list */
- ret = g_list_sort (ret, meta_rectangle_edge_cmp);
-
- /* Free the fixed struts list */
- meta_rectangle_free_list_and_elements (fixed_strut_rects);
-
- return ret;
-}
-
-GList*
-meta_rectangle_find_nonintersected_xinerama_edges (
- const GList *xinerama_rects,
- const GSList *all_struts)
-{
- /* This function cannot easily be merged with
- * meta_rectangle_find_onscreen_edges() because real screen edges
- * and strut edges both are of the type "there ain't anything
- * immediately on the other side"; xinerama edges are different.
- */
- GList *ret;
- const GList *cur;
- GSList *temp_rects;
-
- /* Initialize the return list to be empty */
- ret = NULL;
-
- /* start of ret with all the edges of xineramas that are adjacent to
- * another xinerama.
- */
- cur = xinerama_rects;
- while (cur)
- {
- MetaRectangle *cur_rect = cur->data;
- const GList *compare = xinerama_rects;
- while (compare)
- {
- MetaRectangle *compare_rect = compare->data;
-
- /* Check if cur might be horizontally adjacent to compare */
- if (meta_rectangle_vert_overlap(cur_rect, compare_rect))
- {
- MetaDirection side_type;
- int y = MAX (cur_rect->y, compare_rect->y);
- int height = MIN (BOX_BOTTOM (*cur_rect) - y,
- BOX_BOTTOM (*compare_rect) - y);
- int width = 0;
- int x;
-
- if (BOX_LEFT (*cur_rect) == BOX_RIGHT (*compare_rect))
- {
- /* compare_rect is to the left of cur_rect */
- x = BOX_LEFT (*cur_rect);
- side_type = META_DIRECTION_LEFT;
- }
- else if (BOX_RIGHT (*cur_rect) == BOX_LEFT (*compare_rect))
- {
- /* compare_rect is to the right of cur_rect */
- x = BOX_RIGHT (*cur_rect);
- side_type = META_DIRECTION_RIGHT;
- }
- else
- /* These rectangles aren't adjacent after all */
- x = INT_MIN;
-
- /* If the rectangles really are adjacent */
- if (x != INT_MIN)
- {
- /* We need a left edge for the xinerama on the right, and
- * a right edge for the xinerama on the left. Just fill
- * up the edges and stick 'em on the list.
- */
- MetaEdge *new_edge = g_new (MetaEdge, 1);
-
- new_edge->rect = meta_rect (x, y, width, height);
- new_edge->side_type = side_type;
- new_edge->edge_type = META_EDGE_XINERAMA;
-
- ret = g_list_prepend (ret, new_edge);
- }
- }
-
- /* Check if cur might be vertically adjacent to compare */
- if (meta_rectangle_horiz_overlap(cur_rect, compare_rect))
- {
- MetaDirection side_type;
- int x = MAX (cur_rect->x, compare_rect->x);
- int width = MIN (BOX_RIGHT (*cur_rect) - x,
- BOX_RIGHT (*compare_rect) - x);
- int height = 0;
- int y;
-
- if (BOX_TOP (*cur_rect) == BOX_BOTTOM (*compare_rect))
- {
- /* compare_rect is to the top of cur_rect */
- y = BOX_TOP (*cur_rect);
- side_type = META_DIRECTION_TOP;
- }
- else if (BOX_BOTTOM (*cur_rect) == BOX_TOP (*compare_rect))
- {
- /* compare_rect is to the bottom of cur_rect */
- y = BOX_BOTTOM (*cur_rect);
- side_type = META_DIRECTION_BOTTOM;
- }
- else
- /* These rectangles aren't adjacent after all */
- y = INT_MIN;
-
- /* If the rectangles really are adjacent */
- if (y != INT_MIN)
- {
- /* We need a top edge for the xinerama on the bottom, and
- * a bottom edge for the xinerama on the top. Just fill
- * up the edges and stick 'em on the list.
- */
- MetaEdge *new_edge = g_new (MetaEdge, 1);
-
- new_edge->rect = meta_rect (x, y, width, height);
- new_edge->side_type = side_type;
- new_edge->edge_type = META_EDGE_XINERAMA;
-
- ret = g_list_prepend (ret, new_edge);
- }
- }
-
- compare = compare->next;
- }
- cur = cur->next;
- }
-
- temp_rects = NULL;
- for (; all_struts; all_struts = all_struts->next)
- temp_rects = g_slist_prepend (temp_rects,
- &((MetaStrut*)all_struts->data)->rect);
- ret = meta_rectangle_remove_intersections_with_boxes_from_edges (ret,
- temp_rects);
- g_slist_free (temp_rects);
-
- /* Sort the list */
- ret = g_list_sort (ret, meta_rectangle_edge_cmp);
-
- return ret;
-}
diff --git a/src/core/constraints.c b/src/core/constraints.c
deleted file mode 100644
index 800b293a..00000000
--- a/src/core/constraints.c
+++ /dev/null
@@ -1,1372 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity size/position constraints */
-
-/*
- * Copyright (C) 2002, 2003 Red Hat, Inc.
- * Copyright (C) 2003, 2004 Rob Adams
- * Copyright (C) 2005, 2006 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include "constraints.h"
-#include "workspace.h"
-#include "place.h"
-
-#include <stdlib.h>
-#include <math.h>
-
-#if 0
- // This is the short and sweet version of how to hack on this file; see
- // doc/how-constraints-works.txt for the gory details. The basics of
- // understanding this file can be shown by the steps needed to add a new
- // constraint, which are:
- // 1) Add a new entry in the ConstraintPriority enum; higher values
- // have higher priority
- // 2) Write a new function following the format of the example below,
- // "constrain_whatever".
- // 3) Add your function to the all_constraints and all_constraint_names
- // arrays (the latter of which is for debugging purposes)
- //
- // An example constraint function, constrain_whatever:
- //
- // /* constrain_whatever does the following:
- // * Quits (returning true) if priority is higher than PRIORITY_WHATEVER
- // * If check_only is TRUE
- // * Returns whether the constraint is satisfied or not
- // * otherwise
- // * Enforces the constraint
- // * Note that the value of PRIORITY_WHATEVER is centralized with the
- // * priorities of other constraints in the definition of ConstrainPriority
- // * for easier maintenance and shuffling of priorities.
- // */
- // static gboolean
- // constrain_whatever (MetaWindow *window,
- // ConstraintInfo *info,
- // ConstraintPriority priority,
- // gboolean check_only)
- // {
- // if (priority > PRIORITY_WHATEVER)
- // return TRUE;
- //
- // /* Determine whether constraint applies; note that if the constraint
- // * cannot possibly be satisfied, constraint_applies should be set to
- // * false. If we don't do this, all constraints with a lesser priority
- // * will be dropped along with this one, and we'd rather apply as many as
- // * possible.
- // */
- // if (!constraint_applies)
- // return TRUE;
- //
- // /* Determine whether constraint is already satisfied; if we're only
- // * checking the status of whether the constraint is satisfied, we end
- // * here.
- // */
- // if (check_only || constraint_already_satisfied)
- // return constraint_already_satisfied;
- //
- // /* Enforce constraints */
- // return TRUE; /* Note that we exited early if check_only is FALSE; also,
- // * we know we can return TRUE here because we exited early
- // * if the constraint could not be satisfied; not that the
- // * return value is heeded in this case...
- // */
- // }
-#endif
-
-typedef enum
-{
- PRIORITY_MINIMUM = 0, /* Dummy value used for loop start = min(all priorities) */
- PRIORITY_ASPECT_RATIO = 0,
- PRIORITY_ENTIRELY_VISIBLE_ON_SINGLE_XINERAMA = 0,
- PRIORITY_ENTIRELY_VISIBLE_ON_WORKAREA = 1,
- PRIORITY_SIZE_HINTS_INCREMENTS = 1,
- PRIORITY_MAXIMIZATION = 2,
- PRIORITY_FULLSCREEN = 2,
- PRIORITY_SIZE_HINTS_LIMITS = 3,
- PRIORITY_TITLEBAR_VISIBLE = 4,
- PRIORITY_PARTIALLY_VISIBLE_ON_WORKAREA = 4,
- PRIORITY_MAXIMUM = 4 /* Dummy value used for loop end = max(all priorities) */
-} ConstraintPriority;
-
-typedef enum
-{
- ACTION_MOVE,
- ACTION_RESIZE,
- ACTION_MOVE_AND_RESIZE
-} ActionType;
-
-typedef struct
-{
- MetaRectangle orig;
- MetaRectangle current;
- MetaFrameGeometry *fgeom;
- ActionType action_type;
- gboolean is_user_action;
-
- /* I know that these two things probably look similar at first, but they
- * have much different uses. See doc/how-constraints-works.txt for for
- * explanation of the differences and similarity between resize_gravity
- * and fixed_directions
- */
- int resize_gravity;
- FixedDirections fixed_directions;
-
- /* work_area_xinerama - current xinerama region minus struts
- * entire_xinerama - current xienrama, including strut regions
- */
- MetaRectangle work_area_xinerama;
- MetaRectangle entire_xinerama;
-
- /* Spanning rectangles for the non-covered (by struts) region of the
- * screen and also for just the current xinerama
- */
- GList *usable_screen_region;
- GList *usable_xinerama_region;
-} ConstraintInfo;
-
-static gboolean constrain_maximization (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-static gboolean constrain_fullscreen (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-static gboolean constrain_size_increments (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-static gboolean constrain_size_limits (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-static gboolean constrain_aspect_ratio (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-static gboolean constrain_to_single_xinerama (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-static gboolean constrain_fully_onscreen (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-static gboolean constrain_titlebar_visible (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-static gboolean constrain_partially_onscreen (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-
-static void setup_constraint_info (ConstraintInfo *info,
- MetaWindow *window,
- MetaFrameGeometry *orig_fgeom,
- MetaMoveResizeFlags flags,
- int resize_gravity,
- const MetaRectangle *orig,
- MetaRectangle *new);
-static void place_window_if_needed (MetaWindow *window,
- ConstraintInfo *info);
-static void update_onscreen_requirements (MetaWindow *window,
- ConstraintInfo *info);
-static void extend_by_frame (MetaRectangle *rect,
- const MetaFrameGeometry *fgeom);
-static void unextend_by_frame (MetaRectangle *rect,
- const MetaFrameGeometry *fgeom);
-static inline void get_size_limits (const MetaWindow *window,
- const MetaFrameGeometry *fgeom,
- gboolean include_frame,
- MetaRectangle *min_size,
- MetaRectangle *max_size);
-
-typedef gboolean (* ConstraintFunc) (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-
-typedef struct {
- ConstraintFunc func;
- const char* name;
-} Constraint;
-
-static const Constraint all_constraints[] = {
- {constrain_maximization, "constrain_maximization"},
- {constrain_fullscreen, "constrain_fullscreen"},
- {constrain_size_increments, "constrain_size_increments"},
- {constrain_size_limits, "constrain_size_limits"},
- {constrain_aspect_ratio, "constrain_aspect_ratio"},
- {constrain_to_single_xinerama, "constrain_to_single_xinerama"},
- {constrain_fully_onscreen, "constrain_fully_onscreen"},
- {constrain_titlebar_visible, "constrain_titlebar_visible"},
- {constrain_partially_onscreen, "constrain_partially_onscreen"},
- {NULL, NULL}
-};
-
-static gboolean
-do_all_constraints (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- const Constraint *constraint;
- gboolean satisfied;
-
- constraint = &all_constraints[0];
- satisfied = TRUE;
- while (constraint->func != NULL)
- {
- satisfied = satisfied &&
- (*constraint->func) (window, info, priority, check_only);
-
- if (!check_only)
- {
- /* Log how the constraint modified the position */
- meta_topic (META_DEBUG_GEOMETRY,
- "info->current is %d,%d +%d,%d after %s\n",
- info->current.x, info->current.y,
- info->current.width, info->current.height,
- constraint->name);
- }
- else if (!satisfied)
- {
- /* Log which constraint was not satisfied */
- meta_topic (META_DEBUG_GEOMETRY,
- "constraint %s not satisfied.\n",
- constraint->name);
- return FALSE;
- }
- ++constraint;
- }
-
- return TRUE;
-}
-
-void
-meta_window_constrain (MetaWindow *window,
- MetaFrameGeometry *orig_fgeom,
- MetaMoveResizeFlags flags,
- int resize_gravity,
- const MetaRectangle *orig,
- MetaRectangle *new)
-{
- ConstraintInfo info;
- ConstraintPriority priority = PRIORITY_MINIMUM;
- gboolean satisfied = FALSE;
-
- /* WARNING: orig and new specify positions and sizes of the inner window,
- * not the outer. This is a common gotcha since half the constraints
- * deal with inner window position/size and half deal with outer. See
- * doc/how-constraints-works.txt for more information.
- */
- meta_topic (META_DEBUG_GEOMETRY,
- "Constraining %s in move from %d,%d %dx%d to %d,%d %dx%d\n",
- window->desc,
- orig->x, orig->y, orig->width, orig->height,
- new->x, new->y, new->width, new->height);
-
- setup_constraint_info (&info,
- window,
- orig_fgeom,
- flags,
- resize_gravity,
- orig,
- new);
- place_window_if_needed (window, &info);
-
- while (!satisfied && priority <= PRIORITY_MAXIMUM) {
- gboolean check_only = TRUE;
-
- /* Individually enforce all the high-enough priority constraints */
- do_all_constraints (window, &info, priority, !check_only);
-
- /* Check if all high-enough priority constraints are simultaneously
- * satisfied
- */
- satisfied = do_all_constraints (window, &info, priority, check_only);
-
- /* Drop the least important constraints if we can't satisfy them all */
- priority++;
- }
-
- /* Make sure we use the constrained position */
- *new = info.current;
-
- /* We may need to update window->require_fully_onscreen,
- * window->require_on_single_xinerama, and perhaps other quantities
- * if this was a user move or user move-and-resize operation.
- */
- update_onscreen_requirements (window, &info);
-
- /* Ew, what an ugly way to do things. Destructors (in a real OOP language,
- * not gobject-style--gobject would be more pain than it's worth) or
- * smart pointers would be so much nicer here. *shrug*
- */
- if (!orig_fgeom)
- g_free (info.fgeom);
-}
-
-static void
-setup_constraint_info (ConstraintInfo *info,
- MetaWindow *window,
- MetaFrameGeometry *orig_fgeom,
- MetaMoveResizeFlags flags,
- int resize_gravity,
- const MetaRectangle *orig,
- MetaRectangle *new)
-{
- const MetaXineramaScreenInfo *xinerama_info;
- MetaWorkspace *cur_workspace;
-
- info->orig = *orig;
- info->current = *new;
-
- /* Create a fake frame geometry if none really exists */
- if (orig_fgeom && !window->fullscreen)
- info->fgeom = orig_fgeom;
- else
- info->fgeom = g_new0 (MetaFrameGeometry, 1);
-
- if (flags & META_IS_MOVE_ACTION && flags & META_IS_RESIZE_ACTION)
- info->action_type = ACTION_MOVE_AND_RESIZE;
- else if (flags & META_IS_RESIZE_ACTION)
- info->action_type = ACTION_RESIZE;
- else if (flags & META_IS_MOVE_ACTION)
- info->action_type = ACTION_MOVE;
- else
- g_error ("BAD, BAD developer! No treat for you! (Fix your calls to "
- "meta_window_move_resize_internal()).\n");
-
- info->is_user_action = (flags & META_IS_USER_ACTION);
-
- info->resize_gravity = resize_gravity;
-
- /* FIXME: fixed_directions might be more sane if we (a) made it
- * depend on the grab_op type instead of current amount of movement
- * (thus implying that it only has effect when user_action is true,
- * and (b) ignored it for aspect ratio windows -- at least in those
- * cases where both directions do actually change size.
- */
- info->fixed_directions = FIXED_DIRECTION_NONE;
- /* If x directions don't change but either y direction does */
- if ( orig->x == new->x && orig->x + orig->width == new->x + new->width &&
- (orig->y != new->y || orig->y + orig->height != new->y + new->height))
- {
- info->fixed_directions = FIXED_DIRECTION_X;
- }
- /* If y directions don't change but either x direction does */
- if ( orig->y == new->y && orig->y + orig->height == new->y + new->height &&
- (orig->x != new->x || orig->x + orig->width != new->x + new->width ))
- {
- info->fixed_directions = FIXED_DIRECTION_Y;
- }
- /* The point of fixed directions is just that "move to nearest valid
- * position" is sometimes a poorer choice than "move to nearest
- * valid position but only change this coordinate" for windows the
- * user is explicitly moving. This isn't ever true for things that
- * aren't explicit user interaction, though, so just clear it out.
- */
- if (!info->is_user_action)
- info->fixed_directions = FIXED_DIRECTION_NONE;
-
- xinerama_info =
- meta_screen_get_xinerama_for_rect (window->screen, &info->current);
- meta_window_get_work_area_for_xinerama (window,
- xinerama_info->number,
- &info->work_area_xinerama);
-
- if (!window->fullscreen || window->fullscreen_monitors[0] == -1)
- {
- info->entire_xinerama = xinerama_info->rect;
- }
- else
- {
- int i = 0;
- long monitor;
-
- monitor = window->fullscreen_monitors[i];
- info->entire_xinerama =
- window->screen->xinerama_infos[monitor].rect;
- for (i = 1; i <= 3; i++)
- {
- monitor = window->fullscreen_monitors[i];
- meta_rectangle_union (&info->entire_xinerama,
- &window->screen->xinerama_infos[monitor].rect,
- &info->entire_xinerama);
- }
- }
-
- cur_workspace = window->screen->active_workspace;
- info->usable_screen_region =
- meta_workspace_get_onscreen_region (cur_workspace);
- info->usable_xinerama_region =
- meta_workspace_get_onxinerama_region (cur_workspace,
- xinerama_info->number);
-
- /* Workaround braindead legacy apps that don't know how to
- * fullscreen themselves properly.
- */
- if (meta_rectangle_equal (new, &xinerama_info->rect) &&
- window->has_fullscreen_func &&
- !window->fullscreen)
- {
- /*
- meta_topic (META_DEBUG_GEOMETRY,
- */
- meta_warning (
- "Treating resize request of legacy application %s as a "
- "fullscreen request\n",
- window->desc);
- meta_window_make_fullscreen_internal (window);
- }
-
- /* Log all this information for debugging */
- meta_topic (META_DEBUG_GEOMETRY,
- "Setting up constraint info:\n"
- " orig: %d,%d +%d,%d\n"
- " new : %d,%d +%d,%d\n"
- " fgeom: %d,%d,%d,%d\n"
- " action_type : %s\n"
- " is_user_action : %s\n"
- " resize_gravity : %s\n"
- " fixed_directions: %s\n"
- " work_area_xinerama: %d,%d +%d,%d\n"
- " entire_xinerama : %d,%d +%d,%d\n",
- info->orig.x, info->orig.y, info->orig.width, info->orig.height,
- info->current.x, info->current.y,
- info->current.width, info->current.height,
- info->fgeom->left_width, info->fgeom->right_width,
- info->fgeom->top_height, info->fgeom->bottom_height,
- (info->action_type == ACTION_MOVE) ? "Move" :
- (info->action_type == ACTION_RESIZE) ? "Resize" :
- (info->action_type == ACTION_MOVE_AND_RESIZE) ? "Move&Resize" :
- "Freakin' Invalid Stupid",
- (info->is_user_action) ? "true" : "false",
- meta_gravity_to_string (info->resize_gravity),
- (info->fixed_directions == FIXED_DIRECTION_NONE) ? "None" :
- (info->fixed_directions == FIXED_DIRECTION_X) ? "X fixed" :
- (info->fixed_directions == FIXED_DIRECTION_Y) ? "Y fixed" :
- "Freakin' Invalid Stupid",
- info->work_area_xinerama.x, info->work_area_xinerama.y,
- info->work_area_xinerama.width,
- info->work_area_xinerama.height,
- info->entire_xinerama.x, info->entire_xinerama.y,
- info->entire_xinerama.width, info->entire_xinerama.height);
-}
-
-static void
-place_window_if_needed(MetaWindow *window,
- ConstraintInfo *info)
-{
- gboolean did_placement;
-
- /* Do placement if any, so we go ahead and apply position
- * constraints in a move-only context. Don't place
- * maximized/minimized/fullscreen windows until they are
- * unmaximized, unminimized and unfullscreened.
- */
- did_placement = FALSE;
- if (!window->placed &&
- window->calc_placement &&
- !(window->maximized_horizontally ||
- window->maximized_vertically) &&
- !window->minimized &&
- !window->fullscreen)
- {
- MetaRectangle placed_rect = info->orig;
- MetaWorkspace *cur_workspace;
- const MetaXineramaScreenInfo *xinerama_info;
-
- meta_window_place (window, info->fgeom, info->orig.x, info->orig.y,
- &placed_rect.x, &placed_rect.y);
- did_placement = TRUE;
-
- /* placing the window may have changed the xinerama. Find the
- * new xinerama and update the ConstraintInfo
- */
- xinerama_info =
- meta_screen_get_xinerama_for_rect (window->screen, &placed_rect);
- info->entire_xinerama = xinerama_info->rect;
- meta_window_get_work_area_for_xinerama (window,
- xinerama_info->number,
- &info->work_area_xinerama);
- cur_workspace = window->screen->active_workspace;
- info->usable_xinerama_region =
- meta_workspace_get_onxinerama_region (cur_workspace,
- xinerama_info->number);
-
-
- info->current.x = placed_rect.x;
- info->current.y = placed_rect.y;
-
- /* Since we just barely placed the window, there's no reason to
- * consider any of the directions fixed.
- */
- info->fixed_directions = FIXED_DIRECTION_NONE;
- }
-
- if (window->placed || did_placement)
- {
- if (window->maximize_horizontally_after_placement ||
- window->maximize_vertically_after_placement)
- {
- /* define a sane saved_rect so that the user can unmaximize to
- * something reasonable.
- */
- if (info->current.width >= info->work_area_xinerama.width)
- {
- info->current.width = .75 * info->work_area_xinerama.width;
- info->current.x = info->work_area_xinerama.x +
- .125 * info->work_area_xinerama.width;
- }
- if (info->current.height >= info->work_area_xinerama.height)
- {
- info->current.height = .75 * info->work_area_xinerama.height;
- info->current.y = info->work_area_xinerama.y +
- .083 * info->work_area_xinerama.height;
- }
-
- if (window->maximize_horizontally_after_placement ||
- window->maximize_vertically_after_placement)
- meta_window_maximize_internal (window,
- (window->maximize_horizontally_after_placement ?
- META_MAXIMIZE_HORIZONTAL : 0 ) |
- (window->maximize_vertically_after_placement ?
- META_MAXIMIZE_VERTICAL : 0), &info->current);
-
- /* maximization may have changed frame geometry */
- if (window->frame && !window->fullscreen)
- meta_frame_calc_geometry (window->frame, info->fgeom);
-
- window->maximize_horizontally_after_placement = FALSE;
- window->maximize_vertically_after_placement = FALSE;
- }
- if (window->minimize_after_placement)
- {
- meta_window_minimize (window);
- window->minimize_after_placement = FALSE;
- }
- }
-}
-
-static void
-update_onscreen_requirements (MetaWindow *window,
- ConstraintInfo *info)
-{
- gboolean old;
-
- /* We only apply the various onscreen requirements to normal windows */
- if (window->type == META_WINDOW_DESKTOP ||
- window->type == META_WINDOW_DOCK)
- return;
-
- /* We don't want to update the requirements for fullscreen windows;
- * fullscreen windows are specially handled anyway, and it updating
- * the requirements when windows enter fullscreen mode mess up the
- * handling of the window when it leaves that mode (especially when
- * the application sends a bunch of configurerequest events). See
- * #353699.
- */
- if (window->fullscreen)
- return;
-
- /* USABILITY NOTE: Naturally, I only want the require_fully_onscreen,
- * require_on_single_xinerama, and require_titlebar_visible flags to
- * *become false* due to user interactions (which is allowed since
- * certain constraints are ignored for user interactions regardless of
- * the setting of these flags). However, whether to make these flags
- * *become true* due to just an application interaction is a little
- * trickier. It's possible that users may find not doing that strange
- * since two application interactions that resize in opposite ways don't
- * necessarily end up cancelling--but it may also be strange for the user
- * to have an application resize the window so that it's onscreen, the
- * user forgets about it, and then later the app is able to resize itself
- * off the screen. Anyway, for now, I think the latter is the more
- * problematic case but this may need to be revisited.
- */
-
- /* The require onscreen/on-single-xinerama and titlebar_visible
- * stuff is relative to the outer window, not the inner
- */
- extend_by_frame (&info->current, info->fgeom);
-
- /* Update whether we want future constraint runs to require the
- * window to be on fully onscreen.
- */
- old = window->require_fully_onscreen;
- window->require_fully_onscreen =
- meta_rectangle_contained_in_region (info->usable_screen_region,
- &info->current);
- if (old ^ window->require_fully_onscreen)
- meta_topic (META_DEBUG_GEOMETRY,
- "require_fully_onscreen for %s toggled to %s\n",
- window->desc,
- window->require_fully_onscreen ? "TRUE" : "FALSE");
-
- /* Update whether we want future constraint runs to require the
- * window to be on a single xinerama.
- */
- old = window->require_on_single_xinerama;
- window->require_on_single_xinerama =
- meta_rectangle_contained_in_region (info->usable_xinerama_region,
- &info->current);
- if (old ^ window->require_on_single_xinerama)
- meta_topic (META_DEBUG_GEOMETRY,
- "require_on_single_xinerama for %s toggled to %s\n",
- window->desc,
- window->require_on_single_xinerama ? "TRUE" : "FALSE");
-
- /* Update whether we want future constraint runs to require the
- * titlebar to be visible.
- */
- if (window->frame && window->decorated)
- {
- MetaRectangle titlebar_rect;
-
- titlebar_rect = info->current;
- titlebar_rect.height = info->fgeom->top_height;
- old = window->require_titlebar_visible;
- window->require_titlebar_visible =
- meta_rectangle_overlaps_with_region (info->usable_screen_region,
- &titlebar_rect);
- if (old ^ window->require_titlebar_visible)
- meta_topic (META_DEBUG_GEOMETRY,
- "require_titlebar_visible for %s toggled to %s\n",
- window->desc,
- window->require_titlebar_visible ? "TRUE" : "FALSE");
- }
-
- /* Don't forget to restore the position of the window */
- unextend_by_frame (&info->current, info->fgeom);
-}
-
-static void
-extend_by_frame (MetaRectangle *rect,
- const MetaFrameGeometry *fgeom)
-{
- rect->x -= fgeom->left_width;
- rect->y -= fgeom->top_height;
- rect->width += fgeom->left_width + fgeom->right_width;
- rect->height += fgeom->top_height + fgeom->bottom_height;
-}
-
-static void
-unextend_by_frame (MetaRectangle *rect,
- const MetaFrameGeometry *fgeom)
-{
- rect->x += fgeom->left_width;
- rect->y += fgeom->top_height;
- rect->width -= fgeom->left_width + fgeom->right_width;
- rect->height -= fgeom->top_height + fgeom->bottom_height;
-}
-
-static inline void
-get_size_limits (const MetaWindow *window,
- const MetaFrameGeometry *fgeom,
- gboolean include_frame,
- MetaRectangle *min_size,
- MetaRectangle *max_size)
-{
- /* We pack the results into MetaRectangle structs just for convienience; we
- * don't actually use the position of those rects.
- */
- min_size->width = window->size_hints.min_width;
- min_size->height = window->size_hints.min_height;
- max_size->width = window->size_hints.max_width;
- max_size->height = window->size_hints.max_height;
-
- if (include_frame)
- {
- int fw = fgeom->left_width + fgeom->right_width;
- int fh = fgeom->top_height + fgeom->bottom_height;
-
- min_size->width += fw;
- min_size->height += fh;
- max_size->width += fw;
- max_size->height += fh;
- }
-}
-
-static gboolean
-constrain_maximization (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- MetaRectangle target_size;
- MetaRectangle min_size, max_size;
- gboolean hminbad, vminbad;
- gboolean horiz_equal, vert_equal;
- gboolean constraint_already_satisfied;
-
- if (priority > PRIORITY_MAXIMIZATION)
- return TRUE;
-
- /* Determine whether constraint applies; exit if it doesn't */
- if (!window->maximized_horizontally && !window->maximized_vertically)
- return TRUE;
-
- /* Calculate target_size = maximized size of (window + frame) */
- if (window->maximized_horizontally && window->maximized_vertically)
- target_size = info->work_area_xinerama;
- else
- {
- /* Amount of maximization possible in a single direction depends
- * on which struts could occlude the window given its current
- * position. For example, a vertical partial strut on the right
- * is only relevant for a horizontally maximized window when the
- * window is at a vertical position where it could be occluded
- * by that partial strut.
- */
- MetaDirection direction;
- GSList *active_workspace_struts;
-
- if (window->maximized_horizontally)
- direction = META_DIRECTION_HORIZONTAL;
- else
- direction = META_DIRECTION_VERTICAL;
- active_workspace_struts = window->screen->active_workspace->all_struts;
-
- target_size = info->current;
- extend_by_frame (&target_size, info->fgeom);
- meta_rectangle_expand_to_avoiding_struts (&target_size,
- &info->entire_xinerama,
- direction,
- active_workspace_struts);
- }
- /* Now make target_size = maximized size of client window */
- unextend_by_frame (&target_size, info->fgeom);
-
- /* Check min size constraints; max size constraints are ignored for maximized
- * windows, as per bug 327543.
- */
- get_size_limits (window, info->fgeom, FALSE, &min_size, &max_size);
- hminbad = target_size.width < min_size.width && window->maximized_horizontally;
- vminbad = target_size.height < min_size.height && window->maximized_vertically;
- if (hminbad || vminbad)
- return TRUE;
-
- /* Determine whether constraint is already satisfied; exit if it is */
- horiz_equal = target_size.x == info->current.x &&
- target_size.width == info->current.width;
- vert_equal = target_size.y == info->current.y &&
- target_size.height == info->current.height;
- constraint_already_satisfied =
- (horiz_equal || !window->maximized_horizontally) &&
- (vert_equal || !window->maximized_vertically);
- if (check_only || constraint_already_satisfied)
- return constraint_already_satisfied;
-
- /*** Enforce constraint ***/
- if (window->maximized_horizontally)
- {
- info->current.x = target_size.x;
- info->current.width = target_size.width;
- }
- if (window->maximized_vertically)
- {
- info->current.y = target_size.y;
- info->current.height = target_size.height;
- }
- return TRUE;
-}
-
-static gboolean
-constrain_fullscreen (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- MetaRectangle min_size, max_size, xinerama;
- gboolean too_big, too_small, constraint_already_satisfied;
-
- if (priority > PRIORITY_FULLSCREEN)
- return TRUE;
-
- /* Determine whether constraint applies; exit if it doesn't */
- if (!window->fullscreen)
- return TRUE;
-
- xinerama = info->entire_xinerama;
-
- get_size_limits (window, info->fgeom, FALSE, &min_size, &max_size);
- too_big = !meta_rectangle_could_fit_rect (&xinerama, &min_size);
- too_small = !meta_rectangle_could_fit_rect (&max_size, &xinerama);
- if (too_big || too_small)
- return TRUE;
-
- /* Determine whether constraint is already satisfied; exit if it is */
- constraint_already_satisfied =
- meta_rectangle_equal (&info->current, &xinerama);
- if (check_only || constraint_already_satisfied)
- return constraint_already_satisfied;
-
- /*** Enforce constraint ***/
- info->current = xinerama;
- return TRUE;
-}
-
-static gboolean
-constrain_size_increments (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- int bh, hi, bw, wi, extra_height, extra_width;
- int new_width, new_height;
- gboolean constraint_already_satisfied;
- MetaRectangle *start_rect;
-
- if (priority > PRIORITY_SIZE_HINTS_INCREMENTS)
- return TRUE;
-
- /* Determine whether constraint applies; exit if it doesn't */
- if (META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
- info->action_type == ACTION_MOVE)
- return TRUE;
-
- /* Determine whether constraint is already satisfied; exit if it is */
- bh = window->size_hints.base_height;
- hi = window->size_hints.height_inc;
- bw = window->size_hints.base_width;
- wi = window->size_hints.width_inc;
- extra_height = (info->current.height - bh) % hi;
- extra_width = (info->current.width - bw) % wi;
- /* ignore size increments for maximized windows */
- if (window->maximized_horizontally)
- extra_width *= 0;
- if (window->maximized_vertically)
- extra_height *= 0;
- /* constraint is satisfied iff there is no extra height or width */
- constraint_already_satisfied =
- (extra_height == 0 && extra_width == 0);
-
- if (check_only || constraint_already_satisfied)
- return constraint_already_satisfied;
-
- /*** Enforce constraint ***/
- new_width = info->current.width - extra_width;
- new_height = info->current.height - extra_height;
-
- /* Adjusting down instead of up (as done in the above two lines) may
- * violate minimum size constraints; fix the adjustment if this
- * happens.
- */
- if (new_width < window->size_hints.min_width)
- new_width += ((window->size_hints.min_width - new_width)/wi + 1)*wi;
- if (new_height < window->size_hints.min_height)
- new_height += ((window->size_hints.min_height - new_height)/hi + 1)*hi;
-
- /* Figure out what original rect to pass to meta_rectangle_resize_with_gravity
- * See bug 448183
- */
- if (info->action_type == ACTION_MOVE_AND_RESIZE)
- start_rect = &info->current;
- else
- start_rect = &info->orig;
-
- /* Resize to the new size */
- meta_rectangle_resize_with_gravity (start_rect,
- &info->current,
- info->resize_gravity,
- new_width,
- new_height);
- return TRUE;
-}
-
-static gboolean
-constrain_size_limits (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- MetaRectangle min_size, max_size;
- gboolean too_big, too_small, constraint_already_satisfied;
- int new_width, new_height;
- MetaRectangle *start_rect;
-
- if (priority > PRIORITY_SIZE_HINTS_LIMITS)
- return TRUE;
-
- /* Determine whether constraint applies; exit if it doesn't.
- *
- * Note: The old code didn't apply this constraint for fullscreen or
- * maximized windows--but that seems odd to me. *shrug*
- */
- if (info->action_type == ACTION_MOVE)
- return TRUE;
-
- /* Determine whether constraint is already satisfied; exit if it is */
- get_size_limits (window, info->fgeom, FALSE, &min_size, &max_size);
- /* We ignore max-size limits for maximized windows; see #327543 */
- if (window->maximized_horizontally)
- max_size.width = MAX (max_size.width, info->current.width);
- if (window->maximized_vertically)
- max_size.height = MAX (max_size.height, info->current.height);
- too_small = !meta_rectangle_could_fit_rect (&info->current, &min_size);
- too_big = !meta_rectangle_could_fit_rect (&max_size, &info->current);
- constraint_already_satisfied = !too_big && !too_small;
- if (check_only || constraint_already_satisfied)
- return constraint_already_satisfied;
-
- /*** Enforce constraint ***/
- new_width = CLAMP (info->current.width, min_size.width, max_size.width);
- new_height = CLAMP (info->current.height, min_size.height, max_size.height);
-
- /* Figure out what original rect to pass to meta_rectangle_resize_with_gravity
- * See bug 448183
- */
- if (info->action_type == ACTION_MOVE_AND_RESIZE)
- start_rect = &info->current;
- else
- start_rect = &info->orig;
-
- meta_rectangle_resize_with_gravity (start_rect,
- &info->current,
- info->resize_gravity,
- new_width,
- new_height);
- return TRUE;
-}
-
-static gboolean
-constrain_aspect_ratio (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- double minr, maxr;
- gboolean constraints_are_inconsistent, constraint_already_satisfied;
- int fudge, new_width, new_height;
- double best_width, best_height;
- double alt_width, alt_height;
- MetaRectangle *start_rect;
-
- if (priority > PRIORITY_ASPECT_RATIO)
- return TRUE;
-
- /* Determine whether constraint applies; exit if it doesn't. */
- minr = window->size_hints.min_aspect.x /
- (double)window->size_hints.min_aspect.y;
- maxr = window->size_hints.max_aspect.x /
- (double)window->size_hints.max_aspect.y;
- constraints_are_inconsistent = minr > maxr;
- if (constraints_are_inconsistent ||
- META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
- info->action_type == ACTION_MOVE)
- return TRUE;
-
- /* Determine whether constraint is already satisfied; exit if it is. We
- * need the following to hold:
- *
- * width
- * minr <= ------ <= maxr
- * height
- *
- * But we need to allow for some slight fudging since width and height
- * are integers instead of floating point numbers (this is particularly
- * important when minr == maxr), so we allow width and height to be off
- * a little bit from strictly satisfying these equations. For just one
- * sided resizing, we have to make the fudge factor a little bigger
- * because of how meta_rectangle_resize_with_gravity treats those as
- * being a resize increment (FIXME: I should handle real resize
- * increments better here...)
- */
- switch (info->resize_gravity)
- {
- case WestGravity:
- case NorthGravity:
- case SouthGravity:
- case EastGravity:
- fudge = 2;
- break;
-
- case NorthWestGravity:
- case SouthWestGravity:
- case CenterGravity:
- case NorthEastGravity:
- case SouthEastGravity:
- case StaticGravity:
- default:
- fudge = 1;
- break;
- }
- constraint_already_satisfied =
- info->current.width - (info->current.height * minr ) > -minr*fudge &&
- info->current.width - (info->current.height * maxr ) < maxr*fudge;
- if (check_only || constraint_already_satisfied)
- return constraint_already_satisfied;
-
- /*** Enforce constraint ***/
- new_width = info->current.width;
- new_height = info->current.height;
-
- switch (info->resize_gravity)
- {
- case WestGravity:
- case EastGravity:
- /* Yeah, I suck for doing implicit rounding -- sue me */
- new_height = CLAMP (new_height, new_width / maxr, new_width / minr);
- break;
-
- case NorthGravity:
- case SouthGravity:
- /* Yeah, I suck for doing implicit rounding -- sue me */
- new_width = CLAMP (new_width, new_height * minr, new_height * maxr);
- break;
-
- case NorthWestGravity:
- case SouthWestGravity:
- case CenterGravity:
- case NorthEastGravity:
- case SouthEastGravity:
- case StaticGravity:
- default:
- /* Find what width would correspond to new_height, and what height would
- * correspond to new_width */
- alt_width = CLAMP (new_width, new_height * minr, new_height * maxr);
- alt_height = CLAMP (new_height, new_width / maxr, new_width / minr);
-
- /* The line connecting the points (alt_width, new_height) and
- * (new_width, alt_height) provide a range of
- * valid-for-the-aspect-ratio-constraint sizes. We want the
- * size in that range closest to the value requested, i.e. the
- * point on the line which is closest to the point (new_width,
- * new_height)
- */
- meta_rectangle_find_linepoint_closest_to_point (alt_width, new_height,
- new_width, alt_height,
- new_width, new_height,
- &best_width, &best_height);
-
- /* Yeah, I suck for doing implicit rounding -- sue me */
- new_width = best_width;
- new_height = best_height;
-
- break;
- }
-
- /* Figure out what original rect to pass to meta_rectangle_resize_with_gravity
- * See bug 448183
- */
- if (info->action_type == ACTION_MOVE_AND_RESIZE)
- start_rect = &info->current;
- else
- start_rect = &info->orig;
-
- meta_rectangle_resize_with_gravity (start_rect,
- &info->current,
- info->resize_gravity,
- new_width,
- new_height);
-
- return TRUE;
-}
-
-static gboolean
-do_screen_and_xinerama_relative_constraints (
- MetaWindow *window,
- GList *region_spanning_rectangles,
- ConstraintInfo *info,
- gboolean check_only)
-{
- gboolean exit_early = FALSE, constraint_satisfied;
- MetaRectangle how_far_it_can_be_smushed, min_size, max_size;
-
-#ifdef WITH_VERBOSE_MODE
- if (meta_is_verbose ())
- {
- /* First, log some debugging information */
- char spanning_region[1 + 28 * g_list_length (region_spanning_rectangles)];
-
- meta_topic (META_DEBUG_GEOMETRY,
- "screen/xinerama constraint; region_spanning_rectangles: %s\n",
- meta_rectangle_region_to_string (region_spanning_rectangles, ", ",
- spanning_region));
- }
-#endif
-
- /* Determine whether constraint applies; exit if it doesn't */
- how_far_it_can_be_smushed = info->current;
- get_size_limits (window, info->fgeom, TRUE, &min_size, &max_size);
- extend_by_frame (&info->current, info->fgeom);
-
- if (info->action_type != ACTION_MOVE)
- {
- if (!(info->fixed_directions & FIXED_DIRECTION_X))
- how_far_it_can_be_smushed.width = min_size.width;
-
- if (!(info->fixed_directions & FIXED_DIRECTION_Y))
- how_far_it_can_be_smushed.height = min_size.height;
- }
- if (!meta_rectangle_could_fit_in_region (region_spanning_rectangles,
- &how_far_it_can_be_smushed))
- exit_early = TRUE;
-
- /* Determine whether constraint is already satisfied; exit if it is */
- constraint_satisfied =
- meta_rectangle_contained_in_region (region_spanning_rectangles,
- &info->current);
- if (exit_early || constraint_satisfied || check_only)
- {
- unextend_by_frame (&info->current, info->fgeom);
- return constraint_satisfied;
- }
-
- /* Enforce constraint */
-
- /* Clamp rectangle size for resize or move+resize actions */
- if (info->action_type != ACTION_MOVE)
- meta_rectangle_clamp_to_fit_into_region (region_spanning_rectangles,
- info->fixed_directions,
- &info->current,
- &min_size);
-
- if (info->is_user_action && info->action_type == ACTION_RESIZE)
- /* For user resize, clip to the relevant region */
- meta_rectangle_clip_to_region (region_spanning_rectangles,
- info->fixed_directions,
- &info->current);
- else
- /* For everything else, shove the rectangle into the relevant region */
- meta_rectangle_shove_into_region (region_spanning_rectangles,
- info->fixed_directions,
- &info->current);
-
- unextend_by_frame (&info->current, info->fgeom);
- return TRUE;
-}
-
-static gboolean
-constrain_to_single_xinerama (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- if (priority > PRIORITY_ENTIRELY_VISIBLE_ON_SINGLE_XINERAMA)
- return TRUE;
-
- /* Exit early if we know the constraint won't apply--note that this constraint
- * is only meant for normal windows (e.g. we don't want docks to be shoved
- * "onscreen" by their own strut) and we can't apply it to frameless windows
- * or else users will be unable to move windows such as XMMS across xineramas.
- */
- if (window->type == META_WINDOW_DESKTOP ||
- window->type == META_WINDOW_DOCK ||
- window->screen->n_xinerama_infos == 1 ||
- !window->require_on_single_xinerama ||
- !window->frame ||
- info->is_user_action)
- return TRUE;
-
- /* Have a helper function handle the constraint for us */
- return do_screen_and_xinerama_relative_constraints (window,
- info->usable_xinerama_region,
- info,
- check_only);
-}
-
-static gboolean
-constrain_fully_onscreen (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- if (priority > PRIORITY_ENTIRELY_VISIBLE_ON_WORKAREA)
- return TRUE;
-
- /* Exit early if we know the constraint won't apply--note that this constraint
- * is only meant for normal windows (e.g. we don't want docks to be shoved
- * "onscreen" by their own strut).
- */
- if (window->type == META_WINDOW_DESKTOP ||
- window->type == META_WINDOW_DOCK ||
- window->fullscreen ||
- !window->require_fully_onscreen ||
- info->is_user_action)
- return TRUE;
-
- /* Have a helper function handle the constraint for us */
- return do_screen_and_xinerama_relative_constraints (window,
- info->usable_screen_region,
- info,
- check_only);
-}
-
-static gboolean
-constrain_titlebar_visible (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- gboolean unconstrained_user_action;
- gboolean retval;
- int bottom_amount;
- int horiz_amount_offscreen, vert_amount_offscreen;
- int horiz_amount_onscreen, vert_amount_onscreen;
-
- if (priority > PRIORITY_TITLEBAR_VISIBLE)
- return TRUE;
-
- /* Allow the titlebar beyond the top of the screen only if the user wasn't
- * clicking on the frame to start the move.
- */
- unconstrained_user_action =
- info->is_user_action && !window->display->grab_frame_action;
-
- /* Exit early if we know the constraint won't apply--note that this constraint
- * is only meant for normal windows (e.g. we don't want docks to be shoved
- * "onscreen" by their own strut).
- */
- if (window->type == META_WINDOW_DESKTOP ||
- window->type == META_WINDOW_DOCK ||
- window->fullscreen ||
- !window->require_titlebar_visible ||
- !window->decorated ||
- unconstrained_user_action)
- return TRUE;
-
- /* Determine how much offscreen things are allowed. We first need to
- * figure out how much must remain on the screen. For that, we use 25%
- * window width/height but clamp to the range of (10,75) pixels. This is
- * somewhat of a seat of my pants random guess at what might look good.
- * Then, the amount that is allowed off is just the window size minus
- * this amount (but no less than 0 for tiny windows).
- */
- horiz_amount_onscreen = info->current.width / 4;
- vert_amount_onscreen = info->current.height / 4;
- horiz_amount_onscreen = CLAMP (horiz_amount_onscreen, 10, 75);
- vert_amount_onscreen = CLAMP (vert_amount_onscreen, 10, 75);
- horiz_amount_offscreen = info->current.width - horiz_amount_onscreen;
- vert_amount_offscreen = info->current.height - vert_amount_onscreen;
- horiz_amount_offscreen = MAX (horiz_amount_offscreen, 0);
- vert_amount_offscreen = MAX (vert_amount_offscreen, 0);
- /* Allow the titlebar to touch the bottom panel; If there is no titlebar,
- * require vert_amount to remain on the screen.
- */
- if (window->frame)
- {
- bottom_amount = info->current.height + info->fgeom->bottom_height;
- vert_amount_onscreen = info->fgeom->top_height;
- }
- else
- bottom_amount = vert_amount_offscreen;
-
- /* Extend the region, have a helper function handle the constraint,
- * then return the region to its original size.
- */
- meta_rectangle_expand_region_conditionally (info->usable_screen_region,
- horiz_amount_offscreen,
- horiz_amount_offscreen,
- 0, /* Don't let titlebar off */
- bottom_amount,
- horiz_amount_onscreen,
- vert_amount_onscreen);
- retval =
- do_screen_and_xinerama_relative_constraints (window,
- info->usable_screen_region,
- info,
- check_only);
- meta_rectangle_expand_region_conditionally (info->usable_screen_region,
- -horiz_amount_offscreen,
- -horiz_amount_offscreen,
- 0, /* Don't let titlebar off */
- -bottom_amount,
- horiz_amount_onscreen,
- vert_amount_onscreen);
-
- return retval;
-}
-
-static gboolean
-constrain_partially_onscreen (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- gboolean retval;
- int top_amount, bottom_amount;
- int horiz_amount_offscreen, vert_amount_offscreen;
- int horiz_amount_onscreen, vert_amount_onscreen;
-
- if (priority > PRIORITY_PARTIALLY_VISIBLE_ON_WORKAREA)
- return TRUE;
-
- /* Exit early if we know the constraint won't apply--note that this constraint
- * is only meant for normal windows (e.g. we don't want docks to be shoved
- * "onscreen" by their own strut).
- */
- if (window->type == META_WINDOW_DESKTOP ||
- window->type == META_WINDOW_DOCK)
- return TRUE;
-
- /* Determine how much offscreen things are allowed. We first need to
- * figure out how much must remain on the screen. For that, we use 25%
- * window width/height but clamp to the range of (10,75) pixels. This is
- * somewhat of a seat of my pants random guess at what might look good.
- * Then, the amount that is allowed off is just the window size minus
- * this amount (but no less than 0 for tiny windows).
- */
- horiz_amount_onscreen = info->current.width / 4;
- vert_amount_onscreen = info->current.height / 4;
- horiz_amount_onscreen = CLAMP (horiz_amount_onscreen, 10, 75);
- vert_amount_onscreen = CLAMP (vert_amount_onscreen, 10, 75);
- horiz_amount_offscreen = info->current.width - horiz_amount_onscreen;
- vert_amount_offscreen = info->current.height - vert_amount_onscreen;
- horiz_amount_offscreen = MAX (horiz_amount_offscreen, 0);
- vert_amount_offscreen = MAX (vert_amount_offscreen, 0);
- top_amount = vert_amount_offscreen;
- /* Allow the titlebar to touch the bottom panel; If there is no titlebar,
- * require vert_amount to remain on the screen.
- */
- if (window->frame)
- {
- bottom_amount = info->current.height + info->fgeom->bottom_height;
- vert_amount_onscreen = info->fgeom->top_height;
- }
- else
- bottom_amount = vert_amount_offscreen;
-
- /* Extend the region, have a helper function handle the constraint,
- * then return the region to its original size.
- */
- meta_rectangle_expand_region_conditionally (info->usable_screen_region,
- horiz_amount_offscreen,
- horiz_amount_offscreen,
- top_amount,
- bottom_amount,
- horiz_amount_onscreen,
- vert_amount_onscreen);
- retval =
- do_screen_and_xinerama_relative_constraints (window,
- info->usable_screen_region,
- info,
- check_only);
- meta_rectangle_expand_region_conditionally (info->usable_screen_region,
- -horiz_amount_offscreen,
- -horiz_amount_offscreen,
- -top_amount,
- -bottom_amount,
- horiz_amount_onscreen,
- vert_amount_onscreen);
-
- return retval;
-}
diff --git a/src/core/constraints.h b/src/core/constraints.h
deleted file mode 100644
index 6ccad00e..00000000
--- a/src/core/constraints.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity size/position constraints */
-
-/*
- * Copyright (C) 2002 Red Hat, Inc.
- * Copyright (C) 2005 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_CONSTRAINTS_H
-#define META_CONSTRAINTS_H
-
-#include "util.h"
-#include "window-private.h"
-#include "frame-private.h"
-
-typedef enum
-{
- META_IS_CONFIGURE_REQUEST = 1 << 0,
- META_DO_GRAVITY_ADJUST = 1 << 1,
- META_IS_USER_ACTION = 1 << 2,
- META_IS_MOVE_ACTION = 1 << 3,
- META_IS_RESIZE_ACTION = 1 << 4
-} MetaMoveResizeFlags;
-
-void meta_window_constrain (MetaWindow *window,
- MetaFrameGeometry *orig_fgeom,
- MetaMoveResizeFlags flags,
- int resize_gravity,
- const MetaRectangle *orig,
- MetaRectangle *new);
-
-#endif /* META_CONSTRAINTS_H */
diff --git a/src/core/core.c b/src/core/core.c
deleted file mode 100644
index a63531fe..00000000
--- a/src/core/core.c
+++ /dev/null
@@ -1,776 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity interface used by GTK+ UI to talk to core */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2003 Rob Adams
- * Copyright (C) 2004-2006 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include "core.h"
-#include "frame-private.h"
-#include "workspace.h"
-#include "prefs.h"
-
-/* Looks up the MetaWindow representing the frame of the given X window.
- * Used as a helper function by a bunch of the functions below.
- *
- * FIXME: The functions that use this function throw the result away
- * after use. Many of these functions tend to be called in small groups,
- * which results in get_window() getting called several times in succession
- * with the same parameters. We should profile to see whether this wastes
- * much time, and if it does we should look into a generalised
- * meta_core_get_window_info() which takes a bunch of pointers to variables
- * to put its results in, and only fills in the non-null ones.
- */
-static MetaWindow *
-get_window (Display *xdisplay,
- Window frame_xwindow)
-{
- MetaDisplay *display;
- MetaWindow *window;
-
- display = meta_display_for_x_display (xdisplay);
- window = meta_display_lookup_x_window (display, frame_xwindow);
-
- if (window == NULL || window->frame == NULL)
- {
- meta_bug ("No such frame window 0x%lx!\n", frame_xwindow);
- return NULL;
- }
-
- return window;
-}
-
-void
-meta_core_get (Display *xdisplay,
- Window xwindow,
- ...)
-{
- va_list args;
- MetaCoreGetType request;
-
- MetaDisplay *display = meta_display_for_x_display (xdisplay);
- MetaWindow *window = meta_display_lookup_x_window (display, xwindow);
-
- va_start (args, xwindow);
-
- request = va_arg (args, MetaCoreGetType);
-
- /* Now, we special-case the first request slightly. Mostly, requests
- * for information on windows which have no frame are errors.
- * But sometimes we may want to know *whether* a window has a frame.
- * In this case, pass the key META_CORE_WINDOW_HAS_FRAME
- * as the *first* request, with a pointer to a boolean; if the window
- * has no frame, this will be set to False and meta_core_get will
- * exit immediately (so the values of any other requests will be
- * undefined). Otherwise it will be set to True and meta_core_get will
- * continue happily on its way.
- */
-
- if (request != META_CORE_WINDOW_HAS_FRAME &&
- (window == NULL || window->frame == NULL)) {
- meta_bug ("No such frame window 0x%lx!\n", xwindow);
- return;
- }
-
- while (request != META_CORE_GET_END) {
-
- gpointer answer = va_arg (args, gpointer);
-
- switch (request) {
- case META_CORE_WINDOW_HAS_FRAME:
- *((gboolean*)answer) = window != NULL && window->frame != NULL;
- if (!*((gboolean*)answer)) return; /* see above */
- break;
- case META_CORE_GET_CLIENT_WIDTH:
- *((gint*)answer) = window->rect.width;
- break;
- case META_CORE_GET_CLIENT_HEIGHT:
- *((gint*)answer) = window->rect.height;
- break;
- case META_CORE_IS_TITLEBAR_ONSCREEN:
- *((gboolean*)answer) = meta_window_titlebar_is_onscreen (window);
- break;
- case META_CORE_GET_CLIENT_XWINDOW:
- *((Window*)answer) = window->xwindow;
- break;
- case META_CORE_GET_FRAME_FLAGS:
- *((MetaFrameFlags*)answer) = meta_frame_get_flags (window->frame);
- break;
- case META_CORE_GET_FRAME_TYPE:
- {
- MetaFrameType base_type = META_FRAME_TYPE_LAST;
-
- switch (window->type)
- {
- case META_WINDOW_NORMAL:
- base_type = META_FRAME_TYPE_NORMAL;
- break;
-
- case META_WINDOW_DIALOG:
- base_type = META_FRAME_TYPE_DIALOG;
- break;
-
- case META_WINDOW_MODAL_DIALOG:
- base_type = META_FRAME_TYPE_MODAL_DIALOG;
- break;
-
- case META_WINDOW_MENU:
- base_type = META_FRAME_TYPE_MENU;
- break;
-
- case META_WINDOW_UTILITY:
- base_type = META_FRAME_TYPE_UTILITY;
- break;
-
- case META_WINDOW_DESKTOP:
- case META_WINDOW_DOCK:
- case META_WINDOW_TOOLBAR:
- case META_WINDOW_SPLASHSCREEN:
- /* No frame */
- base_type = META_FRAME_TYPE_LAST;
- break;
-
- }
-
- if (base_type == META_FRAME_TYPE_LAST)
- {
- /* can't add border if undecorated */
- *((MetaFrameType*)answer) = META_FRAME_TYPE_LAST;
- }
- else if (window->border_only)
- {
- /* override base frame type */
- *((MetaFrameType*)answer) = META_FRAME_TYPE_BORDER;
- }
- else
- {
- *((MetaFrameType*)answer) = base_type;
- }
-
- break;
- }
- case META_CORE_GET_MINI_ICON:
- *((GdkPixbuf**)answer) = window->mini_icon;
- break;
- case META_CORE_GET_ICON:
- *((GdkPixbuf**)answer) = window->icon;
- break;
- case META_CORE_GET_X:
- meta_window_get_position (window, (int*)answer, NULL);
- break;
- case META_CORE_GET_Y:
- meta_window_get_position (window, NULL, (int*)answer);
- break;
- case META_CORE_GET_FRAME_WORKSPACE:
- *((gint*)answer) = meta_window_get_net_wm_desktop (window);
- break;
- case META_CORE_GET_FRAME_X:
- *((gint*)answer) = window->frame->rect.x;
- break;
- case META_CORE_GET_FRAME_Y:
- *((gint*)answer) = window->frame->rect.y;
- break;
- case META_CORE_GET_FRAME_WIDTH:
- *((gint*)answer) = window->frame->rect.width;
- break;
- case META_CORE_GET_FRAME_HEIGHT:
- *((gint*)answer) = window->frame->rect.height;
- break;
- case META_CORE_GET_SCREEN_WIDTH:
- *((gint*)answer) = window->screen->rect.width;
- break;
- case META_CORE_GET_SCREEN_HEIGHT:
- *((gint*)answer) = window->screen->rect.height;
- break;
-
- default:
- meta_warning(_("Unknown window information request: %d"), request);
- }
-
- request = va_arg (args, MetaCoreGetType);
- }
-
- va_end (args);
-}
-
-void
-meta_core_queue_frame_resize (Display *xdisplay,
- Window frame_xwindow)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
-}
-
-void
-meta_core_user_move (Display *xdisplay,
- Window frame_xwindow,
- int x,
- int y)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- meta_window_move (window, TRUE, x, y);
-}
-
-void
-meta_core_user_resize (Display *xdisplay,
- Window frame_xwindow,
- int gravity,
- int width,
- int height)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- meta_window_resize_with_gravity (window, TRUE, width, height, gravity);
-}
-
-void
-meta_core_user_raise (Display *xdisplay,
- Window frame_xwindow)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- meta_window_raise (window);
-}
-
-void
-meta_core_user_lower_and_unfocus (Display *xdisplay,
- Window frame_xwindow,
- guint32 timestamp)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- meta_window_lower (window);
-
- if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK &&
- meta_prefs_get_raise_on_click ())
- {
- /* Move window to the back of the focusing workspace's MRU list.
- * Do extra sanity checks to avoid possible race conditions.
- * (Borrowed from window.c.)
- */
- if (window->screen->active_workspace &&
- meta_window_located_on_workspace (window,
- window->screen->active_workspace))
- {
- GList* link;
- link = g_list_find (window->screen->active_workspace->mru_list,
- window);
- g_assert (link);
-
- window->screen->active_workspace->mru_list =
- g_list_remove_link (window->screen->active_workspace->mru_list,
- link);
- g_list_free (link);
-
- window->screen->active_workspace->mru_list =
- g_list_append (window->screen->active_workspace->mru_list,
- window);
- }
- }
-
- /* focus the default window, if needed */
- if (window->has_focus)
- meta_workspace_focus_default_window (window->screen->active_workspace,
- NULL,
- timestamp);
-}
-
-void
-meta_core_user_focus (Display *xdisplay,
- Window frame_xwindow,
- guint32 timestamp)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- meta_window_focus (window, timestamp);
-}
-
-void
-meta_core_minimize (Display *xdisplay,
- Window frame_xwindow)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- meta_window_minimize (window);
-}
-
-void
-meta_core_maximize (Display *xdisplay,
- Window frame_xwindow)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- if (meta_prefs_get_raise_on_click ())
- meta_window_raise (window);
-
- meta_window_maximize (window,
- META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
-}
-
-void
-meta_core_toggle_maximize_vertically (Display *xdisplay,
- Window frame_xwindow)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- if (meta_prefs_get_raise_on_click ())
- meta_window_raise (window);
-
- if (META_WINDOW_MAXIMIZED_VERTICALLY (window))
- meta_window_unmaximize (window,
- META_MAXIMIZE_VERTICAL);
- else
- meta_window_maximize (window,
- META_MAXIMIZE_VERTICAL);
-}
-
-void
-meta_core_toggle_maximize_horizontally (Display *xdisplay,
- Window frame_xwindow)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- if (meta_prefs_get_raise_on_click ())
- meta_window_raise (window);
-
- if (META_WINDOW_MAXIMIZED_HORIZONTALLY (window))
- meta_window_unmaximize (window,
- META_MAXIMIZE_HORIZONTAL);
- else
- meta_window_maximize (window,
- META_MAXIMIZE_HORIZONTAL);
-}
-
-void
-meta_core_toggle_maximize (Display *xdisplay,
- Window frame_xwindow)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- if (meta_prefs_get_raise_on_click ())
- meta_window_raise (window);
-
- if (META_WINDOW_MAXIMIZED (window))
- meta_window_unmaximize (window,
- META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
- else
- meta_window_maximize (window,
- META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
-}
-
-void
-meta_core_unmaximize (Display *xdisplay,
- Window frame_xwindow)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- if (meta_prefs_get_raise_on_click ())
- meta_window_raise (window);
-
- meta_window_unmaximize (window,
- META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
-}
-
-void
-meta_core_delete (Display *xdisplay,
- Window frame_xwindow,
- guint32 timestamp)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- meta_window_delete (window, timestamp);
-}
-
-void
-meta_core_unshade (Display *xdisplay,
- Window frame_xwindow,
- guint32 timestamp)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- meta_window_unshade (window, timestamp);
-}
-
-void
-meta_core_shade (Display *xdisplay,
- Window frame_xwindow,
- guint32 timestamp)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- meta_window_shade (window, timestamp);
-}
-
-void
-meta_core_unstick (Display *xdisplay,
- Window frame_xwindow)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- meta_window_unstick (window);
-}
-
-void
-meta_core_make_above (Display *xdisplay,
- Window frame_xwindow)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- meta_window_make_above (window);
-}
-
-void
-meta_core_unmake_above (Display *xdisplay,
- Window frame_xwindow)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- meta_window_unmake_above (window);
-}
-
-void
-meta_core_stick (Display *xdisplay,
- Window frame_xwindow)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- meta_window_stick (window);
-}
-
-void
-meta_core_change_workspace (Display *xdisplay,
- Window frame_xwindow,
- int new_workspace)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- meta_window_change_workspace (window,
- meta_screen_get_workspace_by_index (window->screen,
- new_workspace));
-}
-
-int
-meta_core_get_num_workspaces (Screen *xscreen)
-{
- MetaScreen *screen;
-
- screen = meta_screen_for_x_screen (xscreen);
-
- return meta_screen_get_n_workspaces (screen);
-}
-
-int
-meta_core_get_active_workspace (Screen *xscreen)
-{
- MetaScreen *screen;
-
- screen = meta_screen_for_x_screen (xscreen);
-
- return meta_workspace_index (screen->active_workspace);
-}
-
-void
-meta_core_show_window_menu (Display *xdisplay,
- Window frame_xwindow,
- int root_x,
- int root_y,
- int button,
- guint32 timestamp)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
-
- if (meta_prefs_get_raise_on_click ())
- meta_window_raise (window);
- meta_window_focus (window, timestamp);
-
- meta_window_show_menu (window, root_x, root_y, button, timestamp);
-}
-
-void
-meta_core_get_menu_accelerator (MetaMenuOp menu_op,
- int workspace,
- unsigned int *keysym,
- MetaVirtualModifier *modifiers)
-{
- const char *name;
-
- name = NULL;
-
- switch (menu_op)
- {
- case META_MENU_OP_DELETE:
- name = "close";
- break;
- case META_MENU_OP_MINIMIZE:
- name = "minimize";
- break;
- case META_MENU_OP_UNMAXIMIZE:
- name = "unmaximize";
- break;
- case META_MENU_OP_MAXIMIZE:
- name = "maximize";
- break;
- case META_MENU_OP_UNSHADE:
- case META_MENU_OP_SHADE:
- name = "toggle_shaded";
- break;
- case META_MENU_OP_UNSTICK:
- case META_MENU_OP_STICK:
- name = "toggle_on_all_workspaces";
- break;
- case META_MENU_OP_ABOVE:
- case META_MENU_OP_UNABOVE:
- name = "toggle_above";
- break;
- case META_MENU_OP_WORKSPACES:
- switch (workspace)
- {
- case 1:
- name = "move_to_workspace_1";
- break;
- case 2:
- name = "move_to_workspace_2";
- break;
- case 3:
- name = "move_to_workspace_3";
- break;
- case 4:
- name = "move_to_workspace_4";
- break;
- case 5:
- name = "move_to_workspace_5";
- break;
- case 6:
- name = "move_to_workspace_6";
- break;
- case 7:
- name = "move_to_workspace_7";
- break;
- case 8:
- name = "move_to_workspace_8";
- break;
- case 9:
- name = "move_to_workspace_9";
- break;
- case 10:
- name = "move_to_workspace_10";
- break;
- case 11:
- name = "move_to_workspace_11";
- break;
- case 12:
- name = "move_to_workspace_12";
- break;
- }
- break;
- case META_MENU_OP_MOVE:
- name = "begin_move";
- break;
- case META_MENU_OP_RESIZE:
- name = "begin_resize";
- break;
- case META_MENU_OP_MOVE_LEFT:
- name = "move_to_workspace_left";
- break;
- case META_MENU_OP_MOVE_RIGHT:
- name = "move_to_workspace_right";
- break;
- case META_MENU_OP_MOVE_UP:
- name = "move_to_workspace_up";
- break;
- case META_MENU_OP_MOVE_DOWN:
- name = "move_to_workspace_down";
- break;
- case META_MENU_OP_RECOVER:
- /* No keybinding for this one */
- break;
- }
-
- if (name)
- {
- meta_prefs_get_window_binding (name, keysym, modifiers);
- }
- else
- {
- *keysym = 0;
- *modifiers = 0;
- }
-}
-
-const char*
-meta_core_get_workspace_name_with_index (Display *xdisplay,
- Window xroot,
- int index)
-{
- MetaDisplay *display;
- MetaScreen *screen;
- MetaWorkspace *workspace;
-
- display = meta_display_for_x_display (xdisplay);
- screen = meta_display_screen_for_root (display, xroot);
- g_assert (screen != NULL);
- workspace = meta_screen_get_workspace_by_index (screen, index);
- return workspace ? meta_workspace_get_name (workspace) : NULL;
-}
-
-gboolean
-meta_core_begin_grab_op (Display *xdisplay,
- Window frame_xwindow,
- MetaGrabOp op,
- gboolean pointer_already_grabbed,
- gboolean frame_action,
- int button,
- gulong modmask,
- guint32 timestamp,
- int root_x,
- int root_y)
-{
- MetaWindow *window = get_window (xdisplay, frame_xwindow);
- MetaDisplay *display;
- MetaScreen *screen;
-
- display = meta_display_for_x_display (xdisplay);
- screen = meta_display_screen_for_xwindow (display, frame_xwindow);
-
- g_assert (screen != NULL);
-
- return meta_display_begin_grab_op (display, screen, window,
- op, pointer_already_grabbed,
- frame_action,
- button, modmask,
- timestamp, root_x, root_y);
-}
-
-void
-meta_core_end_grab_op (Display *xdisplay,
- guint32 timestamp)
-{
- MetaDisplay *display;
-
- display = meta_display_for_x_display (xdisplay);
-
- meta_display_end_grab_op (display, timestamp);
-}
-
-MetaGrabOp
-meta_core_get_grab_op (Display *xdisplay)
-{
- MetaDisplay *display;
-
- display = meta_display_for_x_display (xdisplay);
-
- return display->grab_op;
-}
-
-Window
-meta_core_get_grab_frame (Display *xdisplay)
-{
- MetaDisplay *display;
-
- display = meta_display_for_x_display (xdisplay);
-
- g_assert (display != NULL);
- g_assert (display->grab_op == META_GRAB_OP_NONE ||
- display->grab_screen != NULL);
- g_assert (display->grab_op == META_GRAB_OP_NONE ||
- display->grab_screen->display->xdisplay == xdisplay);
-
- if (display->grab_op != META_GRAB_OP_NONE &&
- display->grab_window &&
- display->grab_window->frame)
- return display->grab_window->frame->xwindow;
- else
- return None;
-}
-
-int
-meta_core_get_grab_button (Display *xdisplay)
-{
- MetaDisplay *display;
-
- display = meta_display_for_x_display (xdisplay);
-
- if (display->grab_op == META_GRAB_OP_NONE)
- return -1;
-
- return display->grab_button;
-}
-
-void
-meta_core_grab_buttons (Display *xdisplay,
- Window frame_xwindow)
-{
- MetaDisplay *display;
-
- display = meta_display_for_x_display (xdisplay);
-
- meta_verbose ("Grabbing buttons on frame 0x%lx\n", frame_xwindow);
- meta_display_grab_window_buttons (display, frame_xwindow);
-}
-
-void
-meta_core_set_screen_cursor (Display *xdisplay,
- Window frame_on_screen,
- MetaCursor cursor)
-{
- MetaWindow *window = get_window (xdisplay, frame_on_screen);
-
- meta_frame_set_screen_cursor (window->frame, cursor);
-}
-
-void
-meta_core_increment_event_serial (Display *xdisplay)
-{
- MetaDisplay *display;
-
- display = meta_display_for_x_display (xdisplay);
-
- meta_display_increment_event_serial (display);
-}
-
-void
-meta_invalidate_default_icons (void)
-{
- MetaDisplay *display = meta_get_display ();
- GSList *windows;
- GSList *l;
-
- if (display == NULL)
- return; /* We can validly be called before the display is opened. */
-
- windows = meta_display_list_windows (display);
- for (l = windows; l != NULL; l = l->next)
- {
- MetaWindow *window = (MetaWindow*)l->data;
-
- if (window->icon_cache.origin == USING_FALLBACK_ICON)
- {
- meta_icon_cache_free (&(window->icon_cache));
- meta_window_update_icon_now (window);
- }
- }
-
- g_slist_free (windows);
-}
-
diff --git a/src/core/delete.c b/src/core/delete.c
deleted file mode 100644
index abd1fd2c..00000000
--- a/src/core/delete.c
+++ /dev/null
@@ -1,505 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity window deletion */
-
-/*
- * Copyright (C) 2001, 2002 Havoc Pennington
- * Copyright (C) 2004 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#define _GNU_SOURCE
-#define _SVID_SOURCE /* for gethostname() */
-
-#include <config.h>
-#include "util.h"
-#include "window-private.h"
-#include "errors.h"
-#include "workspace.h"
-
-#include <sys/types.h>
-#include <signal.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-static void meta_window_present_delete_dialog (MetaWindow *window,
- guint32 timestamp);
-
-static void
-delete_ping_reply_func (MetaDisplay *display,
- Window xwindow,
- guint32 timestamp,
- void *user_data)
-{
- meta_topic (META_DEBUG_PING,
- "Got reply to delete ping for %s\n",
- ((MetaWindow*)user_data)->desc);
-
- /* we do nothing */
-}
-
-static Window
-window_from_string (const char *str)
-{
- char *end;
- unsigned long l;
-
- end = NULL;
-
- l = strtoul (str, &end, 16);
-
- if (end == NULL || end == str)
- {
- meta_warning (_("Could not parse \"%s\" as an integer"),
- str);
- return None;
- }
-
- if (*end != '\0')
- {
- meta_warning (_("Did not understand trailing characters \"%s\" in string \"%s\""),
- end, str);
- return None;
- }
-
- return l;
-}
-
-static int
-pid_from_string (const char *str)
-{
- char *end;
- long l;
-
- end = NULL;
-
- l = strtol (str, &end, 10);
-
- if (end == NULL || end == str)
- {
- meta_warning (_("Could not parse \"%s\" as an integer"),
- str);
- return None;
- }
-
- if (*end != '\0')
- {
- meta_warning (_("Did not understand trailing characters \"%s\" in string \"%s\""),
- end, str);
- return None;
- }
-
- return l;
-}
-
-static gboolean
-parse_dialog_output (const char *str,
- int *pid_out,
- Window *win_out)
-{
- char **split;
-
- split = g_strsplit (str, "\n", 2);
- if (split && split[0] && split[1])
- {
- g_strchomp (split[0]);
- g_strchomp (split[1]);
-
- *pid_out = pid_from_string (split[0]);
- *win_out = window_from_string (split[1]);
-
- g_strfreev (split);
-
- return TRUE;
- }
- else
- {
- g_strfreev (split);
- meta_warning (_("Failed to parse message \"%s\" from dialog process\n"),
- str);
- return FALSE;
- }
-}
-
-static void
-search_and_destroy_window (int pid,
- Window xwindow)
-{
- /* Find the window with the given dialog PID,
- * double check that it matches "xwindow", then
- * kill the window.
- */
- GSList *tmp;
- gboolean found = FALSE;
- GSList *windows;
-
- if (xwindow == None)
- {
- meta_topic (META_DEBUG_PING,
- "Window to destroy is None, doing nothing\n");
- return;
- }
-
- windows = meta_display_list_windows (meta_get_display ());
- tmp = windows;
-
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
-
- if (w->dialog_pid == pid)
- {
- if (w->xwindow != xwindow)
- meta_topic (META_DEBUG_PING,
- "Dialog pid matches but not xwindow (0x%lx vs. 0x%lx)\n",
- w->xwindow, xwindow);
- else
- {
- meta_window_kill (w);
- found = TRUE;
- }
- }
-
- tmp = tmp->next;
- }
-
- g_slist_free (windows);
-
- if (!found)
- meta_topic (META_DEBUG_PING,
- "Did not find a window with dialog pid %d xwindow 0x%lx\n",
- pid, xwindow);
-}
-
-static void
-release_window_with_fd (int fd)
-{
- /* Find the window with the given dialog PID,
- * double check that it matches "xwindow", then
- * kill the window.
- */
- gboolean found = FALSE;
-
- GSList *windows = meta_display_list_windows (meta_get_display ());
- GSList *tmp = windows;
-
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
-
- if (w->dialog_pid >= 0 &&
- w->dialog_pipe == fd)
- {
- meta_topic (META_DEBUG_PING,
- "Removing dialog with fd %d pid %d from window %s\n",
- fd, w->dialog_pid, w->desc);
- meta_window_free_delete_dialog (w);
- found = TRUE;
- }
-
- tmp = tmp->next;
- }
-
- g_slist_free (windows);
-
- if (!found)
- meta_topic (META_DEBUG_PING,
- "Did not find a window with a dialog pipe %d\n",
- fd);
-}
-
-static gboolean
-io_from_ping_dialog (GIOChannel *channel,
- GIOCondition condition,
- gpointer data)
-{
- meta_topic (META_DEBUG_PING,
- "IO handler from ping dialog, condition = %x\n",
- condition);
-
- if (condition & G_IO_IN)
- {
- char *str;
- gsize len;
- GError *err;
-
- /* Go ahead and block for all data from child */
- str = NULL;
- len = 0;
- err = NULL;
- g_io_channel_read_to_end (channel,
- &str, &len,
- &err);
-
- if (err)
- {
- meta_warning (_("Error reading from dialog display process: %s\n"),
- err->message);
- g_error_free (err);
- }
-
- meta_topic (META_DEBUG_PING,
- "Read %" G_GSIZE_FORMAT " bytes strlen %d \"%s\" from child\n",
- len, str ? (int) strlen (str) : 0, str ? str : "NULL");
-
- if (len > 0)
- {
- /* We're supposed to kill the given window */
- int pid;
- Window xwindow;
-
- if (parse_dialog_output (str, &pid, &xwindow))
- search_and_destroy_window (pid, xwindow);
- }
-
- g_free (str);
- }
-
- release_window_with_fd (g_io_channel_unix_get_fd (channel));
-
- /* Remove the callback */
- return FALSE;
-}
-
-static void
-delete_ping_timeout_func (MetaDisplay *display,
- Window xwindow,
- guint32 timestamp,
- void *user_data)
-{
- MetaWindow *window = user_data;
- GError *err;
- int child_pid;
- int outpipe;
- char *argv[9];
- char numbuf[32];
- char timestampbuf[32];
- char *window_id_str;
- char *window_title;
- GIOChannel *channel;
-
- meta_topic (META_DEBUG_PING,
- "Got delete ping timeout for %s\n",
- window->desc);
-
- if (window->dialog_pid >= 0)
- {
- meta_window_present_delete_dialog (window, timestamp);
- return;
- }
-
- window_id_str = g_strdup_printf ("0x%lx", window->xwindow);
- window_title = g_locale_from_utf8 (window->title, -1, NULL, NULL, NULL);
-
- sprintf (numbuf, "%d", window->screen->number);
- sprintf (timestampbuf, "%u", timestamp);
-
- argv[0] = METACITY_LIBEXECDIR"/metacity-dialog";
- argv[1] = "--screen";
- argv[2] = numbuf;
- argv[3] = "--timestamp";
- argv[4] = timestampbuf;
- argv[5] = "--kill-window-question";
- argv[6] = window_title;
- argv[7] = window_id_str;
- argv[8] = NULL;
-
- err = NULL;
- if (!g_spawn_async_with_pipes ("/",
- argv,
- NULL,
- 0,
- NULL, NULL,
- &child_pid,
- NULL,
- &outpipe,
- NULL,
- &err))
- {
- meta_warning (_("Error launching metacity-dialog to ask about killing an application: %s\n"),
- err->message);
- g_error_free (err);
- goto out;
- }
-
- window->dialog_pid = child_pid;
- window->dialog_pipe = outpipe;
-
- channel = g_io_channel_unix_new (window->dialog_pipe);
- g_io_add_watch_full (channel, G_PRIORITY_DEFAULT,
- G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- io_from_ping_dialog,
- NULL, NULL);
- g_io_channel_unref (channel);
-
- out:
- g_free (window_title);
- g_free (window_id_str);
-}
-
-void
-meta_window_delete (MetaWindow *window,
- guint32 timestamp)
-{
- meta_error_trap_push (window->display);
- if (window->delete_window)
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Deleting %s with delete_window request\n",
- window->desc);
- meta_window_send_icccm_message (window,
- window->display->atom_WM_DELETE_WINDOW,
- timestamp);
- }
- else
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Deleting %s with explicit kill\n",
- window->desc);
- XKillClient (window->display->xdisplay, window->xwindow);
- }
- meta_error_trap_pop (window->display, FALSE);
-
- meta_display_ping_window (window->display,
- window,
- timestamp,
- delete_ping_reply_func,
- delete_ping_timeout_func,
- window);
-
- if (window->has_focus)
- {
- /* FIXME Clean this up someday
- * http://bugzilla.gnome.org/show_bug.cgi?id=108706
- */
-#if 0
- /* This is unfortunately going to result in weirdness
- * if the window doesn't respond to the delete event.
- * I don't know how to avoid that though.
- */
- meta_topic (META_DEBUG_FOCUS,
- "Focusing default window because focus window %s was deleted/killed\n",
- window->desc);
- meta_workspace_focus_default_window (window->screen->active_workspace,
- window);
-#else
- meta_topic (META_DEBUG_FOCUS,
- "Not unfocusing %s on delete/kill\n",
- window->desc);
-#endif
- }
- else
- {
- meta_topic (META_DEBUG_FOCUS,
- "Window %s was deleted/killed but didn't have focus\n",
- window->desc);
- }
-}
-
-
-void
-meta_window_kill (MetaWindow *window)
-{
- char buf[257];
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Killing %s brutally\n",
- window->desc);
-
- if (window->wm_client_machine != NULL &&
- window->net_wm_pid > 0)
- {
- if (gethostname (buf, sizeof(buf)-1) == 0)
- {
- if (strcmp (buf, window->wm_client_machine) == 0)
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Killing %s with kill()\n",
- window->desc);
-
- if (kill (window->net_wm_pid, 9) < 0)
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Failed to signal %s: %s\n",
- window->desc, strerror (errno));
- }
- }
- else
- {
- meta_warning (_("Failed to get hostname: %s\n"),
- strerror (errno));
- }
- }
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Disconnecting %s with XKillClient()\n",
- window->desc);
- meta_error_trap_push (window->display);
- XKillClient (window->display->xdisplay, window->xwindow);
- meta_error_trap_pop (window->display, FALSE);
-}
-
-void
-meta_window_free_delete_dialog (MetaWindow *window)
-{
- if (window->dialog_pid >= 0)
- {
- kill (window->dialog_pid, 9);
- close (window->dialog_pipe);
- window->dialog_pid = -1;
- window->dialog_pipe = -1;
- }
-}
-
-static void
-meta_window_present_delete_dialog (MetaWindow *window, guint32 timestamp)
-{
- meta_topic (META_DEBUG_PING,
- "Presenting existing ping dialog for %s\n",
- window->desc);
-
- if (window->dialog_pid >= 0)
- {
- GSList *windows;
- GSList *tmp;
-
- /* Activate transient for window that belongs to
- * metacity-dialog
- */
-
- windows = meta_display_list_windows (window->display);
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
-
- if (w->xtransient_for == window->xwindow &&
- w->res_class &&
- g_ascii_strcasecmp (w->res_class, "metacity-dialog") == 0)
- {
- meta_window_activate (w, timestamp);
- break;
- }
-
- tmp = tmp->next;
- }
-
- g_slist_free (windows);
- }
-}
diff --git a/src/core/display-private.h b/src/core/display-private.h
deleted file mode 100644
index 5f7dc487..00000000
--- a/src/core/display-private.h
+++ /dev/null
@@ -1,500 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity X display handler */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2002 Red Hat, Inc.
- * Copyright (C) 2003 Rob Adams
- * Copyright (C) 2004-2006 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_DISPLAY_PRIVATE_H
-#define META_DISPLAY_PRIVATE_H
-
-#ifndef PACKAGE
-#error "config.h not included"
-#endif
-
-#include <glib.h>
-#include <X11/Xlib.h>
-#include "eventqueue.h"
-#include "common.h"
-#include "boxes.h"
-#include "display.h"
-
-#ifdef HAVE_STARTUP_NOTIFICATION
-#include <libsn/sn.h>
-#endif
-
-#ifdef HAVE_XSYNC
-#include <X11/extensions/sync.h>
-#endif
-
-typedef struct _MetaKeyBinding MetaKeyBinding;
-typedef struct _MetaStack MetaStack;
-typedef struct _MetaUISlave MetaUISlave;
-typedef struct _MetaWorkspace MetaWorkspace;
-
-typedef struct _MetaWindowPropHooks MetaWindowPropHooks;
-typedef struct _MetaGroupPropHooks MetaGroupPropHooks;
-
-typedef struct MetaEdgeResistanceData MetaEdgeResistanceData;
-
-typedef void (* MetaWindowPingFunc) (MetaDisplay *display,
- Window xwindow,
- guint32 timestamp,
- gpointer user_data);
-
-
-#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
-#define _NET_WM_STATE_ADD 1 /* add/set property */
-#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
-
-/* This is basically a bogus number, just has to be large enough
- * to handle the expected case of the alt+tab operation, where
- * we want to ignore serials from UnmapNotify on the tab popup,
- * and the LeaveNotify/EnterNotify from the pointer ungrab
- */
-#define N_IGNORED_SERIALS 4
-
-struct _MetaDisplay
-{
- char *name;
- Display *xdisplay;
-
- Window leader_window;
- Window timestamp_pinging_window;
-
- /* Pull in all the names of atoms as fields; we will intern them when the
- * class is constructed.
- */
-#define item(x) Atom atom_##x;
-#include "atomnames.h"
-#undef item
-
- /* This is the actual window from focus events,
- * not the one we last set
- */
- MetaWindow *focus_window;
-
- /* window we are expecting a FocusIn event for or the current focus
- * window if we are not expecting any FocusIn/FocusOut events; not
- * perfect because applications can call XSetInputFocus directly.
- * (It could also be messed up if a timestamp later than current
- * time is sent to meta_display_set_input_focus_window, though that
- * would be a programming error). See bug 154598 for more info.
- */
- MetaWindow *expected_focus_window;
-
- /* last timestamp passed to XSetInputFocus */
- guint32 last_focus_time;
-
- /* last user interaction time in any app */
- guint32 last_user_time;
-
- /* whether we're using mousenav (only relevant for sloppy&mouse focus modes;
- * !mouse_mode means "keynav mode")
- */
- guint mouse_mode : 1;
-
- /* Helper var used when focus_new_windows setting is 'strict'; only
- * relevant in 'strict' mode and if the focus window is a terminal.
- * In that case, we don't allow new windows to take focus away from
- * a terminal, but if the user explicitly did something that should
- * allow a different window to gain focus (e.g. global keybinding or
- * clicking on a dock), then we will allow the transfer.
- */
- guint allow_terminal_deactivation : 1;
-
- guint static_gravity_works : 1;
-
- /*< private-ish >*/
- guint error_trap_synced_at_last_pop : 1;
- MetaEventQueue *events;
- GSList *screens;
- MetaScreen *active_screen;
- GHashTable *window_ids;
- int error_traps;
- int (* error_trap_handler) (Display *display,
- XErrorEvent *error);
- int server_grab_count;
-
- /* serials of leave/unmap events that may
- * correspond to an enter event we should
- * ignore
- */
- unsigned long ignored_serials[N_IGNORED_SERIALS];
- Window ungrab_should_not_cause_focus_window;
-
- guint32 current_time;
-
- /* Pings which we're waiting for a reply from */
- GSList *pending_pings;
-
- /* Pending autoraise */
- guint autoraise_timeout_id;
- MetaWindow* autoraise_window;
-
- /* Alt+click button grabs */
- unsigned int window_grab_modifiers;
-
- /* current window operation */
- MetaGrabOp grab_op;
- MetaScreen *grab_screen;
- MetaWindow *grab_window;
- Window grab_xwindow;
- int grab_button;
- int grab_anchor_root_x;
- int grab_anchor_root_y;
- MetaRectangle grab_anchor_window_pos;
- int grab_latest_motion_x;
- int grab_latest_motion_y;
- gulong grab_mask;
- guint grab_have_pointer : 1;
- guint grab_have_keyboard : 1;
- guint grab_wireframe_active : 1;
- guint grab_was_cancelled : 1; /* Only used in wireframe mode */
- guint grab_frame_action : 1;
- MetaRectangle grab_wireframe_rect;
- MetaRectangle grab_wireframe_last_xor_rect;
- MetaRectangle grab_initial_window_pos;
- int grab_initial_x, grab_initial_y; /* These are only relevant for */
- gboolean grab_threshold_movement_reached; /* raise_on_click == FALSE. */
- MetaResizePopup *grab_resize_popup;
- GTimeVal grab_last_moveresize_time;
- guint32 grab_motion_notify_time;
- int grab_wireframe_last_display_width;
- int grab_wireframe_last_display_height;
- GList* grab_old_window_stacking;
- MetaEdgeResistanceData *grab_edge_resistance_data;
- unsigned int grab_last_user_action_was_snap;
-
- /* we use property updates as sentinels for certain window focus events
- * to avoid some race conditions on EnterNotify events
- */
- int sentinel_counter;
-
-#ifdef HAVE_XKB
- int xkb_base_event_type;
- guint32 last_bell_time;
-#endif
-#ifdef HAVE_XSYNC
- /* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */
- XSyncAlarm grab_sync_request_alarm;
-#endif
- int grab_resize_timeout_id;
-
- /* Keybindings stuff */
- MetaKeyBinding *key_bindings;
- int n_key_bindings;
- int min_keycode;
- int max_keycode;
- KeySym *keymap;
- int keysyms_per_keycode;
- XModifierKeymap *modmap;
- unsigned int ignored_modifier_mask;
- unsigned int num_lock_mask;
- unsigned int scroll_lock_mask;
- unsigned int hyper_mask;
- unsigned int super_mask;
- unsigned int meta_mask;
-
- /* Xinerama cache */
- unsigned int xinerama_cache_invalidated : 1;
-
- /* Opening the display */
- unsigned int display_opening : 1;
-
- /* Closing down the display */
- int closing;
-
- /* Managed by group.c */
- GHashTable *groups_by_leader;
-
- /* currently-active window menu if any */
- MetaWindowMenu *window_menu;
- MetaWindow *window_with_menu;
-
- /* Managed by window-props.c */
- MetaWindowPropHooks *prop_hooks;
-
- /* Managed by group-props.c */
- MetaGroupPropHooks *group_prop_hooks;
-
- /* Managed by compositor.c */
- MetaCompositor *compositor;
-
-#ifdef HAVE_STARTUP_NOTIFICATION
- SnDisplay *sn_display;
-#endif
-#ifdef HAVE_XSYNC
- int xsync_event_base;
- int xsync_error_base;
-#endif
-#ifdef HAVE_SHAPE
- int shape_event_base;
- int shape_error_base;
-#endif
-#ifdef HAVE_RENDER
- int render_event_base;
- int render_error_base;
-#endif
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- int composite_event_base;
- int composite_error_base;
- int composite_major_version;
- int composite_minor_version;
- int damage_event_base;
- int damage_error_base;
- int xfixes_event_base;
- int xfixes_error_base;
-#endif
-#ifdef HAVE_XSYNC
- unsigned int have_xsync : 1;
-#define META_DISPLAY_HAS_XSYNC(display) ((display)->have_xsync)
-#else
-#define META_DISPLAY_HAS_XSYNC(display) FALSE
-#endif
-#ifdef HAVE_SHAPE
- unsigned int have_shape : 1;
-#define META_DISPLAY_HAS_SHAPE(display) ((display)->have_shape)
-#else
-#define META_DISPLAY_HAS_SHAPE(display) FALSE
-#endif
-#ifdef HAVE_RENDER
- unsigned int have_render : 1;
-#define META_DISPLAY_HAS_RENDER(display) ((display)->have_render)
-#else
-#define META_DISPLAY_HAS_RENDER(display) FALSE
-#endif
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- unsigned int have_composite : 1;
- unsigned int have_damage : 1;
- unsigned int have_xfixes : 1;
-#define META_DISPLAY_HAS_COMPOSITE(display) ((display)->have_composite)
-#define META_DISPLAY_HAS_DAMAGE(display) ((display)->have_damage)
-#define META_DISPLAY_HAS_XFIXES(display) ((display)->have_xfixes)
-#else
-#define META_DISPLAY_HAS_COMPOSITE(display) FALSE
-#define META_DISPLAY_HAS_DAMAGE(display) FALSE
-#define META_DISPLAY_HAS_XFIXES(display) FALSE
-#endif
-};
-
-/* Xserver time can wraparound, thus comparing two timestamps needs to take
- * this into account. Here's a little macro to help out. If no wraparound
- * has occurred, this is equivalent to
- * time1 < time2
- * Of course, the rest of the ugliness of this macro comes from accounting
- * for the fact that wraparound can occur and the fact that a timestamp of
- * 0 must be special-cased since it means older than anything else.
- *
- * Note that this is NOT an equivalent for time1 <= time2; if that's what
- * you need then you'll need to swap the order of the arguments and negate
- * the result.
- */
-#define XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS(time1, time2) \
- ( (( (time1) < (time2) ) && ( (time2) - (time1) < ((guint32)-1)/2 )) || \
- (( (time1) > (time2) ) && ( (time1) - (time2) > ((guint32)-1)/2 )) \
- )
-#define XSERVER_TIME_IS_BEFORE(time1, time2) \
- ( (time1) == 0 || \
- (XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS(time1, time2) && \
- (time2) != 0) \
- )
-
-gboolean meta_display_open (void);
-void meta_display_close (MetaDisplay *display,
- guint32 timestamp);
-MetaScreen* meta_display_screen_for_x_screen (MetaDisplay *display,
- Screen *screen);
-MetaScreen* meta_display_screen_for_xwindow (MetaDisplay *display,
- Window xindow);
-void meta_display_grab (MetaDisplay *display);
-void meta_display_ungrab (MetaDisplay *display);
-
-void meta_display_unmanage_screen (MetaDisplay *display,
- MetaScreen *screen,
- guint32 timestamp);
-
-void meta_display_unmanage_windows_for_screen (MetaDisplay *display,
- MetaScreen *screen,
- guint32 timestamp);
-
-/* Utility function to compare the stacking of two windows */
-int meta_display_stack_cmp (const void *a,
- const void *b);
-
-/* A given MetaWindow may have various X windows that "belong"
- * to it, such as the frame window.
- */
-MetaWindow* meta_display_lookup_x_window (MetaDisplay *display,
- Window xwindow);
-void meta_display_register_x_window (MetaDisplay *display,
- Window *xwindowp,
- MetaWindow *window);
-void meta_display_unregister_x_window (MetaDisplay *display,
- Window xwindow);
-/* Return whether the xwindow is a no focus window for any of the screens */
-gboolean meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display,
- Window xwindow);
-
-GSList* meta_display_list_windows (MetaDisplay *display);
-
-MetaDisplay* meta_display_for_x_display (Display *xdisplay);
-MetaDisplay* meta_get_display (void);
-
-Cursor meta_display_create_x_cursor (MetaDisplay *display,
- MetaCursor cursor);
-
-void meta_display_set_grab_op_cursor (MetaDisplay *display,
- MetaScreen *screen,
- MetaGrabOp op,
- gboolean change_pointer,
- Window grab_xwindow,
- guint32 timestamp);
-
-gboolean meta_display_begin_grab_op (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- MetaGrabOp op,
- gboolean pointer_already_grabbed,
- gboolean frame_action,
- int button,
- gulong modmask,
- guint32 timestamp,
- int root_x,
- int root_y);
-void meta_display_end_grab_op (MetaDisplay *display,
- guint32 timestamp);
-
-void meta_display_check_threshold_reached (MetaDisplay *display,
- int x,
- int y);
-void meta_display_grab_window_buttons (MetaDisplay *display,
- Window xwindow);
-void meta_display_ungrab_window_buttons (MetaDisplay *display,
- Window xwindow);
-
-void meta_display_grab_focus_window_button (MetaDisplay *display,
- MetaWindow *window);
-void meta_display_ungrab_focus_window_button (MetaDisplay *display,
- MetaWindow *window);
-
-/* Next two functions are defined in edge-resistance.c */
-void meta_display_compute_resistance_and_snapping_edges (MetaDisplay *display);
-void meta_display_cleanup_edges (MetaDisplay *display);
-
-/* make a request to ensure the event serial has changed */
-void meta_display_increment_event_serial (MetaDisplay *display);
-
-void meta_display_update_active_window_hint (MetaDisplay *display);
-
-guint32 meta_display_get_current_time (MetaDisplay *display);
-guint32 meta_display_get_current_time_roundtrip (MetaDisplay *display);
-
-/* utility goo */
-const char* meta_event_mode_to_string (int m);
-const char* meta_event_detail_to_string (int d);
-
-void meta_display_queue_retheme_all_windows (MetaDisplay *display);
-void meta_display_retheme_all (void);
-
-void meta_display_set_cursor_theme (const char *theme,
- int size);
-
-void meta_display_ping_window (MetaDisplay *display,
- MetaWindow *window,
- guint32 timestamp,
- MetaWindowPingFunc ping_reply_func,
- MetaWindowPingFunc ping_timeout_func,
- void *user_data);
-gboolean meta_display_window_has_pending_pings (MetaDisplay *display,
- MetaWindow *window);
-
-typedef enum
-{
- META_TAB_LIST_NORMAL,
- META_TAB_LIST_DOCKS,
- META_TAB_LIST_GROUP
-} MetaTabList;
-
-typedef enum
-{
- META_TAB_SHOW_ICON, /* Alt-Tab mode */
- META_TAB_SHOW_INSTANTLY /* Alt-Esc mode */
-} MetaTabShowType;
-
-GList* meta_display_get_tab_list (MetaDisplay *display,
- MetaTabList type,
- MetaScreen *screen,
- MetaWorkspace *workspace);
-
-MetaWindow* meta_display_get_tab_next (MetaDisplay *display,
- MetaTabList type,
- MetaScreen *screen,
- MetaWorkspace *workspace,
- MetaWindow *window,
- gboolean backward);
-
-MetaWindow* meta_display_get_tab_current (MetaDisplay *display,
- MetaTabList type,
- MetaScreen *screen,
- MetaWorkspace *workspace);
-
-int meta_resize_gravity_from_grab_op (MetaGrabOp op);
-
-gboolean meta_grab_op_is_moving (MetaGrabOp op);
-gboolean meta_grab_op_is_resizing (MetaGrabOp op);
-
-void meta_display_devirtualize_modifiers (MetaDisplay *display,
- MetaVirtualModifier modifiers,
- unsigned int *mask);
-
-void meta_display_increment_focus_sentinel (MetaDisplay *display);
-void meta_display_decrement_focus_sentinel (MetaDisplay *display);
-gboolean meta_display_focus_sentinel_clear (MetaDisplay *display);
-
-/* meta_display_set_input_focus_window is like XSetInputFocus, except
- * that (a) it can't detect timestamps later than the current time,
- * since Metacity isn't part of the XServer, and thus gives erroneous
- * behavior in this circumstance (so don't do it), (b) it uses
- * display->last_focus_time since we don't have access to the true
- * Xserver one, (c) it makes use of display->user_time since checking
- * whether a window should be allowed to be focused should depend
- * on user_time events (see bug 167358, comment 15 in particular)
- */
-void meta_display_set_input_focus_window (MetaDisplay *display,
- MetaWindow *window,
- gboolean focus_frame,
- guint32 timestamp);
-
-/* meta_display_focus_the_no_focus_window is called when the
- * designated no_focus_window should be focused, but is otherwise the
- * same as meta_display_set_input_focus_window
- */
-void meta_display_focus_the_no_focus_window (MetaDisplay *display,
- MetaScreen *screen,
- guint32 timestamp);
-
-void meta_display_queue_autoraise_callback (MetaDisplay *display,
- MetaWindow *window);
-void meta_display_remove_autoraise_callback (MetaDisplay *display);
-
-#endif
diff --git a/src/core/display.c b/src/core/display.c
deleted file mode 100644
index daac23f3..00000000
--- a/src/core/display.c
+++ /dev/null
@@ -1,5189 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity X display handler */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2002, 2003, 2004 Red Hat, Inc.
- * Copyright (C) 2003, 2004 Rob Adams
- * Copyright (C) 2004-2006 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-/**
- * \file display.c Handles operations on an X display.
- *
- * The display is represented as a MetaDisplay struct.
- */
-
-#include <config.h>
-#include "display-private.h"
-#include "util.h"
-#include "main.h"
-#include "screen-private.h"
-#include "window-private.h"
-#include "window-props.h"
-#include "group-props.h"
-#include "frame-private.h"
-#include "errors.h"
-#include "keybindings.h"
-#include "prefs.h"
-#include "resizepopup.h"
-#include "xprops.h"
-#include "workspace.h"
-#include "bell.h"
-#include "effects.h"
-#include "compositor.h"
-#include <X11/Xatom.h>
-#include <X11/cursorfont.h>
-#ifdef HAVE_SOLARIS_XINERAMA
-#include <X11/extensions/xinerama.h>
-#endif
-#ifdef HAVE_XFREE_XINERAMA
-#include <X11/extensions/Xinerama.h>
-#endif
-#ifdef HAVE_RANDR
-#include <X11/extensions/Xrandr.h>
-#endif
-#ifdef HAVE_SHAPE
-#include <X11/extensions/shape.h>
-#endif
-#ifdef HAVE_RENDER
-#include <X11/extensions/Xrender.h>
-#endif
-#ifdef HAVE_XKB
-#include <X11/XKBlib.h>
-#endif
-#ifdef HAVE_XCURSOR
-#include <X11/Xcursor/Xcursor.h>
-#endif
-#ifdef HAVE_COMPOSITE_EXTENSIONS
-#include <X11/extensions/Xcomposite.h>
-#include <X11/extensions/Xdamage.h>
-#include <X11/extensions/Xfixes.h>
-#endif
-#include <string.h>
-
-#define GRAB_OP_IS_WINDOW_SWITCH(g) \
- (g == META_GRAB_OP_KEYBOARD_TABBING_NORMAL || \
- g == META_GRAB_OP_KEYBOARD_TABBING_DOCK || \
- g == META_GRAB_OP_KEYBOARD_TABBING_GROUP || \
- g == META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL || \
- g == META_GRAB_OP_KEYBOARD_ESCAPING_DOCK || \
- g == META_GRAB_OP_KEYBOARD_ESCAPING_GROUP)
-
-/**
- * \defgroup pings Pings
- *
- * Sometimes we want to see whether a window is responding,
- * so we send it a "ping" message and see whether it sends us back a "pong"
- * message within a reasonable time. Here we have a system which lets us
- * nominate one function to be called if we get the pong in time and another
- * function if we don't. The system is rather more complicated than it needs
- * to be, since we only ever use it to destroy windows which are asked to
- * close themselves and don't do so within a reasonable amount of time, and
- * therefore we always use the same callbacks. It's possible that we might
- * use it for other things in future, or on the other hand we might decide
- * that we're never going to do so and simplify it a bit.
- */
-
-/**
- * Describes a ping on a window. When we send a ping to a window, we build
- * one of these structs, and it eventually gets passed to the timeout function
- * or to the function which handles the response from the window. If the window
- * does or doesn't respond to the ping, we use this information to deal with
- * these facts; we have a handler function for each.
- *
- * \ingroup pings
- */
-typedef struct
-{
- MetaDisplay *display;
- Window xwindow;
- guint32 timestamp;
- MetaWindowPingFunc ping_reply_func;
- MetaWindowPingFunc ping_timeout_func;
- void *user_data;
- guint ping_timeout_id;
-} MetaPingData;
-
-typedef struct
-{
- MetaDisplay *display;
- Window xwindow;
-} MetaAutoRaiseData;
-
-/**
- * The display we're managing. This is a singleton object. (Historically,
- * this was a list of displays, but there was never any way to add more
- * than one element to it.) The goofy name is because we don't want it
- * to shadow the parameter in its object methods.
- */
-static MetaDisplay *the_display = NULL;
-
-static void meta_spew_event (MetaDisplay *display,
- XEvent *event);
-
-static gboolean event_callback (XEvent *event,
- gpointer data);
-static Window event_get_modified_window (MetaDisplay *display,
- XEvent *event);
-static guint32 event_get_time (MetaDisplay *display,
- XEvent *event);
-static void process_request_frame_extents (MetaDisplay *display,
- XEvent *event);
-static void process_pong_message (MetaDisplay *display,
- XEvent *event);
-static void process_selection_request (MetaDisplay *display,
- XEvent *event);
-static void process_selection_clear (MetaDisplay *display,
- XEvent *event);
-
-static void update_window_grab_modifiers (MetaDisplay *display);
-
-static void prefs_changed_callback (MetaPreference pref,
- void *data);
-
-static void sanity_check_timestamps (MetaDisplay *display,
- guint32 known_good_timestamp);
-
-MetaGroup* get_focussed_group (MetaDisplay *display);
-
-/**
- * Destructor for MetaPingData structs. Will destroy the
- * event source for the struct as well.
- *
- * \ingroup pings
- */
-static void
-ping_data_free (MetaPingData *ping_data)
-{
- /* Remove the timeout */
- if (ping_data->ping_timeout_id != 0)
- g_source_remove (ping_data->ping_timeout_id);
-
- g_free (ping_data);
-}
-
-/**
- * Frees every pending ping structure for the given X window on the
- * given display. This means that we also destroy the timeouts.
- *
- * \param display The display the window appears on
- * \param xwindow The X ID of the window whose pings we should remove
- *
- * \ingroup pings
- *
- */
-static void
-remove_pending_pings_for_window (MetaDisplay *display, Window xwindow)
-{
- GSList *tmp;
- GSList *dead;
-
- /* could obviously be more efficient, don't care */
-
- /* build list to be removed */
- dead = NULL;
- for (tmp = display->pending_pings; tmp; tmp = tmp->next)
- {
- MetaPingData *ping_data = tmp->data;
-
- if (ping_data->xwindow == xwindow)
- dead = g_slist_prepend (dead, ping_data);
- }
-
- /* remove what we found */
- for (tmp = dead; tmp; tmp = tmp->next)
- {
- MetaPingData *ping_data = tmp->data;
-
- display->pending_pings = g_slist_remove (display->pending_pings, ping_data);
- ping_data_free (ping_data);
- }
-
- g_slist_free (dead);
-}
-
-
-#ifdef HAVE_STARTUP_NOTIFICATION
-static void
-sn_error_trap_push (SnDisplay *sn_display,
- Display *xdisplay)
-{
- MetaDisplay *display;
- display = meta_display_for_x_display (xdisplay);
- if (display != NULL)
- meta_error_trap_push (display);
-}
-
-static void
-sn_error_trap_pop (SnDisplay *sn_display,
- Display *xdisplay)
-{
- MetaDisplay *display;
- display = meta_display_for_x_display (xdisplay);
- if (display != NULL)
- meta_error_trap_pop (display, FALSE);
-}
-#endif
-
-static void
-enable_compositor (MetaDisplay *display,
- gboolean composite_windows)
-{
- GSList *list;
-
- if (!META_DISPLAY_HAS_COMPOSITE (display) ||
- !META_DISPLAY_HAS_DAMAGE (display) ||
- !META_DISPLAY_HAS_XFIXES (display) ||
- !META_DISPLAY_HAS_RENDER (display))
- {
- meta_warning (_("Missing %s extension required for compositing"),
- !META_DISPLAY_HAS_COMPOSITE (display) ? "composite" :
- !META_DISPLAY_HAS_DAMAGE (display) ? "damage" :
- !META_DISPLAY_HAS_XFIXES (display) ? "xfixes" : "render");
- return;
- }
-
- if (!display->compositor)
- display->compositor = meta_compositor_new (display);
-
- if (!display->compositor)
- return;
-
- for (list = display->screens; list != NULL; list = list->next)
- {
- MetaScreen *screen = list->data;
-
- meta_compositor_manage_screen (screen->display->compositor,
- screen);
-
- if (composite_windows)
- meta_screen_composite_all_windows (screen);
- }
-}
-
-static void
-disable_compositor (MetaDisplay *display)
-{
- GSList *list;
-
- if (!display->compositor)
- return;
-
- for (list = display->screens; list != NULL; list = list->next)
- {
- MetaScreen *screen = list->data;
-
- meta_compositor_unmanage_screen (screen->display->compositor,
- screen);
- }
-
- meta_compositor_destroy (display->compositor);
- display->compositor = NULL;
-}
-
-/**
- * Opens a new display, sets it up, initialises all the X extensions
- * we will need, and adds it to the list of displays.
- *
- * \return True if the display was opened successfully, and False
- * otherwise-- that is, if the display doesn't exist or it already
- * has a window manager.
- *
- * \ingroup main
- */
-gboolean
-meta_display_open (void)
-{
- Display *xdisplay;
- GSList *screens;
- GSList *tmp;
- int i;
- guint32 timestamp;
-
- /* A list of all atom names, so that we can intern them in one go. */
- char *atom_names[] = {
-#define item(x) #x,
-#include "atomnames.h"
-#undef item
- };
- Atom atoms[G_N_ELEMENTS(atom_names)];
-
- meta_verbose ("Opening display '%s'\n", XDisplayName (NULL));
-
- xdisplay = meta_ui_get_display ();
-
- if (xdisplay == NULL)
- {
- meta_warning (_("Failed to open X Window System display '%s'\n"),
- XDisplayName (NULL));
- return FALSE;
- }
-
- if (meta_is_syncing ())
- XSynchronize (xdisplay, True);
-
- g_assert (the_display == NULL);
- the_display = g_new (MetaDisplay, 1);
-
- the_display->closing = 0;
-
- /* here we use XDisplayName which is what the user
- * probably put in, vs. DisplayString(display) which is
- * canonicalized by XOpenDisplay()
- */
- the_display->name = g_strdup (XDisplayName (NULL));
- the_display->xdisplay = xdisplay;
- the_display->error_trap_synced_at_last_pop = TRUE;
- the_display->error_traps = 0;
- the_display->error_trap_handler = NULL;
- the_display->server_grab_count = 0;
- the_display->display_opening = TRUE;
-
- the_display->pending_pings = NULL;
- the_display->autoraise_timeout_id = 0;
- the_display->autoraise_window = NULL;
- the_display->focus_window = NULL;
- the_display->expected_focus_window = NULL;
- the_display->grab_old_window_stacking = NULL;
-
- the_display->mouse_mode = TRUE; /* Only relevant for mouse or sloppy focus */
- the_display->allow_terminal_deactivation = TRUE; /* Only relevant for when a
- terminal has the focus */
-
-#ifdef HAVE_XSYNC
- the_display->grab_sync_request_alarm = None;
-#endif
-
- /* FIXME copy the checks from GDK probably */
- the_display->static_gravity_works = g_getenv ("METACITY_USE_STATIC_GRAVITY") != NULL;
-
- meta_bell_init (the_display);
-
- meta_display_init_keys (the_display);
-
- update_window_grab_modifiers (the_display);
-
- meta_prefs_add_listener (prefs_changed_callback, the_display);
-
- meta_verbose ("Creating %d atoms\n", (int) G_N_ELEMENTS (atom_names));
- XInternAtoms (the_display->xdisplay, atom_names, G_N_ELEMENTS (atom_names),
- False, atoms);
- {
- int i = 0;
-#define item(x) the_display->atom_##x = atoms[i++];
-#include "atomnames.h"
-#undef item
- }
-
- the_display->prop_hooks = NULL;
- meta_display_init_window_prop_hooks (the_display);
- the_display->group_prop_hooks = NULL;
- meta_display_init_group_prop_hooks (the_display);
-
- /* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK,
- * created in screen_new
- */
- the_display->leader_window = None;
- the_display->timestamp_pinging_window = None;
-
- the_display->xinerama_cache_invalidated = TRUE;
-
- the_display->groups_by_leader = NULL;
-
- the_display->window_with_menu = NULL;
- the_display->window_menu = NULL;
-
- the_display->screens = NULL;
- the_display->active_screen = NULL;
-
-#ifdef HAVE_STARTUP_NOTIFICATION
- the_display->sn_display = sn_display_new (the_display->xdisplay,
- sn_error_trap_push,
- sn_error_trap_pop);
-#endif
-
- the_display->events = NULL;
-
- /* Get events */
- meta_ui_add_event_func (the_display->xdisplay,
- event_callback,
- the_display);
-
- the_display->window_ids = g_hash_table_new (meta_unsigned_long_hash,
- meta_unsigned_long_equal);
-
- i = 0;
- while (i < N_IGNORED_SERIALS)
- {
- the_display->ignored_serials[i] = 0;
- ++i;
- }
- the_display->ungrab_should_not_cause_focus_window = None;
-
- the_display->current_time = CurrentTime;
- the_display->sentinel_counter = 0;
-
- the_display->grab_resize_timeout_id = 0;
- the_display->grab_have_keyboard = FALSE;
-
-#ifdef HAVE_XKB
- the_display->last_bell_time = 0;
-#endif
-
- the_display->grab_op = META_GRAB_OP_NONE;
- the_display->grab_wireframe_active = FALSE;
- the_display->grab_window = NULL;
- the_display->grab_screen = NULL;
- the_display->grab_resize_popup = NULL;
-
- the_display->grab_edge_resistance_data = NULL;
-
-#ifdef HAVE_XSYNC
- {
- int major, minor;
-
- the_display->have_xsync = FALSE;
-
- the_display->xsync_error_base = 0;
- the_display->xsync_event_base = 0;
-
- /* I don't think we really have to fill these in */
- major = SYNC_MAJOR_VERSION;
- minor = SYNC_MINOR_VERSION;
-
- if (!XSyncQueryExtension (the_display->xdisplay,
- &the_display->xsync_event_base,
- &the_display->xsync_error_base) ||
- !XSyncInitialize (the_display->xdisplay,
- &major, &minor))
- {
- the_display->xsync_error_base = 0;
- the_display->xsync_event_base = 0;
- }
- else
- the_display->have_xsync = TRUE;
-
- meta_verbose ("Attempted to init Xsync, found version %d.%d error base %d event base %d\n",
- major, minor,
- the_display->xsync_error_base,
- the_display->xsync_event_base);
- }
-#else /* HAVE_XSYNC */
- meta_verbose ("Not compiled with Xsync support\n");
-#endif /* !HAVE_XSYNC */
-
-
-#ifdef HAVE_SHAPE
- {
- the_display->have_shape = FALSE;
-
- the_display->shape_error_base = 0;
- the_display->shape_event_base = 0;
-
- if (!XShapeQueryExtension (the_display->xdisplay,
- &the_display->shape_event_base,
- &the_display->shape_error_base))
- {
- the_display->shape_error_base = 0;
- the_display->shape_event_base = 0;
- }
- else
- the_display->have_shape = TRUE;
-
- meta_verbose ("Attempted to init Shape, found error base %d event base %d\n",
- the_display->shape_error_base,
- the_display->shape_event_base);
- }
-#else /* HAVE_SHAPE */
- meta_verbose ("Not compiled with Shape support\n");
-#endif /* !HAVE_SHAPE */
-
-#ifdef HAVE_RENDER
- {
- the_display->have_render = FALSE;
-
- the_display->render_error_base = 0;
- the_display->render_event_base = 0;
-
- if (!XRenderQueryExtension (the_display->xdisplay,
- &the_display->render_event_base,
- &the_display->render_error_base))
- {
- the_display->render_error_base = 0;
- the_display->render_event_base = 0;
- }
- else
- the_display->have_render = TRUE;
-
- meta_verbose ("Attempted to init Render, found error base %d event base %d\n",
- the_display->render_error_base,
- the_display->render_event_base);
- }
-#else /* HAVE_RENDER */
- meta_verbose ("Not compiled with Render support\n");
-#endif /* !HAVE_RENDER */
-
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- {
- the_display->have_composite = FALSE;
-
- the_display->composite_error_base = 0;
- the_display->composite_event_base = 0;
-
- if (!XCompositeQueryExtension (the_display->xdisplay,
- &the_display->composite_event_base,
- &the_display->composite_error_base))
- {
- the_display->composite_error_base = 0;
- the_display->composite_event_base = 0;
- }
- else
- {
- the_display->composite_major_version = 0;
- the_display->composite_minor_version = 0;
- if (XCompositeQueryVersion (the_display->xdisplay,
- &the_display->composite_major_version,
- &the_display->composite_minor_version))
- {
- the_display->have_composite = TRUE;
- }
- else
- {
- the_display->composite_major_version = 0;
- the_display->composite_minor_version = 0;
- }
- }
-
- meta_verbose ("Attempted to init Composite, found error base %d event base %d "
- "extn ver %d %d\n",
- the_display->composite_error_base,
- the_display->composite_event_base,
- the_display->composite_major_version,
- the_display->composite_minor_version);
-
- the_display->have_damage = FALSE;
-
- the_display->damage_error_base = 0;
- the_display->damage_event_base = 0;
-
- if (!XDamageQueryExtension (the_display->xdisplay,
- &the_display->damage_event_base,
- &the_display->damage_error_base))
- {
- the_display->damage_error_base = 0;
- the_display->damage_event_base = 0;
- }
- else
- the_display->have_damage = TRUE;
-
- meta_verbose ("Attempted to init Damage, found error base %d event base %d\n",
- the_display->damage_error_base,
- the_display->damage_event_base);
-
- the_display->have_xfixes = FALSE;
-
- the_display->xfixes_error_base = 0;
- the_display->xfixes_event_base = 0;
-
- if (!XFixesQueryExtension (the_display->xdisplay,
- &the_display->xfixes_event_base,
- &the_display->xfixes_error_base))
- {
- the_display->xfixes_error_base = 0;
- the_display->xfixes_event_base = 0;
- }
- else
- the_display->have_xfixes = TRUE;
-
- meta_verbose ("Attempted to init XFixes, found error base %d event base %d\n",
- the_display->xfixes_error_base,
- the_display->xfixes_event_base);
- }
-#else /* HAVE_COMPOSITE_EXTENSIONS */
- meta_verbose ("Not compiled with Composite support\n");
-#endif /* !HAVE_COMPOSITE_EXTENSIONS */
-
-#ifdef HAVE_XCURSOR
- {
- XcursorSetTheme (the_display->xdisplay, meta_prefs_get_cursor_theme ());
- XcursorSetDefaultSize (the_display->xdisplay, meta_prefs_get_cursor_size ());
- }
-#else /* HAVE_XCURSOR */
- meta_verbose ("Not compiled with Xcursor support\n");
-#endif /* !HAVE_XCURSOR */
-
- /* Create the leader window here. Set its properties and
- * use the timestamp from one of the PropertyNotify events
- * that will follow.
- */
- {
- gulong data[1];
- XEvent event;
-
- /* We only care about the PropertyChangeMask in the next 30 or so lines of
- * code. Note that gdk will at some point unset the PropertyChangeMask for
- * this window, so we can't rely on it still being set later. See bug
- * 354213 for details.
- */
- the_display->leader_window =
- meta_create_offscreen_window (the_display->xdisplay,
- DefaultRootWindow (the_display->xdisplay),
- PropertyChangeMask);
-
- meta_prop_set_utf8_string_hint (the_display,
- the_display->leader_window,
- the_display->atom__NET_WM_NAME,
- "Metacity");
-
- meta_prop_set_utf8_string_hint (the_display,
- the_display->leader_window,
- the_display->atom__METACITY_VERSION,
- VERSION);
-
- data[0] = the_display->leader_window;
- XChangeProperty (the_display->xdisplay,
- the_display->leader_window,
- the_display->atom__NET_SUPPORTING_WM_CHECK,
- XA_WINDOW,
- 32, PropModeReplace, (guchar*) data, 1);
-
- XWindowEvent (the_display->xdisplay,
- the_display->leader_window,
- PropertyChangeMask,
- &event);
-
- timestamp = event.xproperty.time;
-
- /* Make it painfully clear that we can't rely on PropertyNotify events on
- * this window, as per bug 354213.
- */
- XSelectInput(the_display->xdisplay,
- the_display->leader_window,
- NoEventMask);
- }
-
- /* Make a little window used only for pinging the server for timestamps; note
- * that meta_create_offscreen_window already selects for PropertyChangeMask.
- */
- the_display->timestamp_pinging_window =
- meta_create_offscreen_window (the_display->xdisplay,
- DefaultRootWindow (the_display->xdisplay),
- PropertyChangeMask);
-
- the_display->last_focus_time = timestamp;
- the_display->last_user_time = timestamp;
- the_display->compositor = NULL;
-
- screens = NULL;
-
- i = 0;
- while (i < ScreenCount (xdisplay))
- {
- MetaScreen *screen;
-
- screen = meta_screen_new (the_display, i, timestamp);
-
- if (screen)
- screens = g_slist_prepend (screens, screen);
- ++i;
- }
-
- the_display->screens = screens;
-
- if (screens == NULL)
- {
- /* This would typically happen because all the screens already
- * have window managers.
- */
- meta_display_close (the_display, timestamp);
- return FALSE;
- }
-
- /* We don't composite the windows here because they will be composited
- faster with the call to meta_screen_manage_all_windows further down
- the code */
- if (meta_prefs_get_compositing_manager ())
- enable_compositor (the_display, FALSE);
-
- meta_display_grab (the_display);
-
- /* Now manage all existing windows */
- tmp = the_display->screens;
- while (tmp != NULL)
- {
- MetaScreen *screen = tmp->data;
-
- meta_screen_manage_all_windows (screen);
-
- tmp = tmp->next;
- }
-
- {
- Window focus;
- int ret_to;
-
- /* kinda bogus because GetInputFocus has no possible errors */
- meta_error_trap_push (the_display);
-
- /* FIXME: This is totally broken; see comment 9 of bug 88194 about this */
- focus = None;
- ret_to = RevertToPointerRoot;
- XGetInputFocus (the_display->xdisplay, &focus, &ret_to);
-
- /* Force a new FocusIn (does this work?) */
-
- /* Use the same timestamp that was passed to meta_screen_new(),
- * as it is the most recent timestamp.
- */
- if (focus == None || focus == PointerRoot)
- /* Just focus the no_focus_window on the first screen */
- meta_display_focus_the_no_focus_window (the_display,
- the_display->screens->data,
- timestamp);
- else
- {
- MetaWindow * window;
- window = meta_display_lookup_x_window (the_display, focus);
- if (window)
- meta_display_set_input_focus_window (the_display, window, FALSE, timestamp);
- else
- /* Just focus the no_focus_window on the first screen */
- meta_display_focus_the_no_focus_window (the_display,
- the_display->screens->data,
- timestamp);
- }
-
- meta_error_trap_pop (the_display, FALSE);
- }
-
- meta_display_ungrab (the_display);
-
- /* Done opening new display */
- the_display->display_opening = FALSE;
-
- return TRUE;
-}
-
-static void
-listify_func (gpointer key, gpointer value, gpointer data)
-{
- GSList **listp;
-
- listp = data;
- *listp = g_slist_prepend (*listp, value);
-}
-
-static gint
-ptrcmp (gconstpointer a, gconstpointer b)
-{
- if (a < b)
- return -1;
- else if (a > b)
- return 1;
- else
- return 0;
-}
-
-GSList*
-meta_display_list_windows (MetaDisplay *display)
-{
- GSList *winlist;
- GSList *tmp;
- GSList *prev;
-
- winlist = NULL;
- g_hash_table_foreach (display->window_ids,
- listify_func,
- &winlist);
-
- /* Uniquify the list, since both frame windows and plain
- * windows are in the hash
- */
- winlist = g_slist_sort (winlist, ptrcmp);
-
- prev = NULL;
- tmp = winlist;
- while (tmp != NULL)
- {
- GSList *next;
-
- next = tmp->next;
-
- if (next &&
- next->data == tmp->data)
- {
- /* Delete tmp from list */
-
- if (prev)
- prev->next = next;
-
- if (tmp == winlist)
- winlist = next;
-
- g_slist_free_1 (tmp);
-
- /* leave prev unchanged */
- }
- else
- {
- prev = tmp;
- }
-
- tmp = next;
- }
-
- return winlist;
-}
-
-void
-meta_display_close (MetaDisplay *display,
- guint32 timestamp)
-{
- GSList *tmp;
-
- g_assert (display != NULL);
-
- if (display->closing != 0)
- {
- /* The display's already been closed. */
- return;
- }
-
- if (display->error_traps > 0)
- meta_bug ("Display closed with error traps pending\n");
-
- display->closing += 1;
-
- meta_prefs_remove_listener (prefs_changed_callback, display);
-
- meta_display_remove_autoraise_callback (display);
-
- if (display->grab_old_window_stacking)
- g_list_free (display->grab_old_window_stacking);
-
- /* Stop caring about events */
- meta_ui_remove_event_func (display->xdisplay,
- event_callback,
- display);
-
- /* Free all screens */
- tmp = display->screens;
- while (tmp != NULL)
- {
- MetaScreen *screen = tmp->data;
- meta_screen_free (screen, timestamp);
- tmp = tmp->next;
- }
-
- g_slist_free (display->screens);
- display->screens = NULL;
-
-#ifdef HAVE_STARTUP_NOTIFICATION
- if (display->sn_display)
- {
- sn_display_unref (display->sn_display);
- display->sn_display = NULL;
- }
-#endif
-
- /* Must be after all calls to meta_window_free() since they
- * unregister windows
- */
- g_hash_table_destroy (display->window_ids);
-
- if (display->leader_window != None)
- XDestroyWindow (display->xdisplay, display->leader_window);
-
- XFlush (display->xdisplay);
-
- meta_display_free_window_prop_hooks (display);
- meta_display_free_group_prop_hooks (display);
-
- g_free (display->name);
-
- meta_display_shutdown_keys (display);
-
- if (display->compositor)
- meta_compositor_destroy (display->compositor);
-
- g_free (display);
- display = NULL;
-
- meta_quit (META_EXIT_SUCCESS);
-}
-
-MetaScreen*
-meta_display_screen_for_root (MetaDisplay *display,
- Window xroot)
-{
- GSList *tmp;
-
- tmp = display->screens;
- while (tmp != NULL)
- {
- MetaScreen *screen = tmp->data;
-
- if (xroot == screen->xroot)
- return screen;
-
- tmp = tmp->next;
- }
-
- return NULL;
-}
-
-MetaScreen*
-meta_display_screen_for_xwindow (MetaDisplay *display,
- Window xwindow)
-{
- XWindowAttributes attr;
- int result;
-
- meta_error_trap_push (display);
- attr.screen = NULL;
- result = XGetWindowAttributes (display->xdisplay, xwindow, &attr);
- meta_error_trap_pop (display, TRUE);
-
- /* Note, XGetWindowAttributes is on all kinds of crack
- * and returns 1 on success 0 on failure, rather than Success
- * on success.
- */
- if (result == 0 || attr.screen == NULL)
- return NULL;
-
- return meta_display_screen_for_x_screen (display, attr.screen);
-}
-
-MetaScreen*
-meta_display_screen_for_x_screen (MetaDisplay *display,
- Screen *xscreen)
-{
- GSList *tmp;
-
- tmp = display->screens;
- while (tmp != NULL)
- {
- MetaScreen *screen = tmp->data;
-
- if (xscreen == screen->xscreen)
- return screen;
-
- tmp = tmp->next;
- }
-
- return NULL;
-}
-
-/* Grab/ungrab routines taken from fvwm */
-void
-meta_display_grab (MetaDisplay *display)
-{
- if (display->server_grab_count == 0)
- {
- XGrabServer (display->xdisplay);
- }
- display->server_grab_count += 1;
- meta_verbose ("Grabbing display, grab count now %d\n",
- display->server_grab_count);
-}
-
-void
-meta_display_ungrab (MetaDisplay *display)
-{
- if (display->server_grab_count == 0)
- meta_bug ("Ungrabbed non-grabbed server\n");
-
- display->server_grab_count -= 1;
- if (display->server_grab_count == 0)
- {
- /* FIXME we want to purge all pending "queued" stuff
- * at this point, such as window hide/show
- */
- XUngrabServer (display->xdisplay);
- XFlush (display->xdisplay);
- }
-
- meta_verbose ("Ungrabbing display, grab count now %d\n",
- display->server_grab_count);
-}
-
-/**
- * Returns the singleton MetaDisplay if "xdisplay" matches the X display it's
- * managing; otherwise gives a warning and returns NULL. When we were claiming
- * to be able to manage multiple displays, this was supposed to find the
- * display out of the list which matched that display. Now it's merely an
- * extra sanity check.
- *
- * \param xdisplay An X display
- * \return The singleton X display, or NULL if "xdisplay" isn't the one
- * we're managing.
- */
-MetaDisplay*
-meta_display_for_x_display (Display *xdisplay)
-{
- if (the_display->xdisplay == xdisplay)
- return the_display;
-
- meta_warning ("Could not find display for X display %p, probably going to crash\n",
- xdisplay);
-
- return NULL;
-}
-
-/**
- * Accessor for the singleton MetaDisplay.
- *
- * \return The only MetaDisplay there is. This can be NULL, but only
- * during startup.
- */
-MetaDisplay*
-meta_get_display (void)
-{
- return the_display;
-}
-
-#ifdef WITH_VERBOSE_MODE
-static gboolean dump_events = TRUE;
-#endif
-
-static gboolean
-grab_op_is_mouse_only (MetaGrabOp op)
-{
- switch (op)
- {
- case META_GRAB_OP_MOVING:
- case META_GRAB_OP_RESIZING_SE:
- case META_GRAB_OP_RESIZING_S:
- case META_GRAB_OP_RESIZING_SW:
- case META_GRAB_OP_RESIZING_N:
- case META_GRAB_OP_RESIZING_NE:
- case META_GRAB_OP_RESIZING_NW:
- case META_GRAB_OP_RESIZING_W:
- case META_GRAB_OP_RESIZING_E:
- return TRUE;
-
- default:
- return FALSE;
- }
-}
-
-static gboolean
-grab_op_is_mouse (MetaGrabOp op)
-{
- switch (op)
- {
- case META_GRAB_OP_MOVING:
- case META_GRAB_OP_RESIZING_SE:
- case META_GRAB_OP_RESIZING_S:
- case META_GRAB_OP_RESIZING_SW:
- case META_GRAB_OP_RESIZING_N:
- case META_GRAB_OP_RESIZING_NE:
- case META_GRAB_OP_RESIZING_NW:
- case META_GRAB_OP_RESIZING_W:
- case META_GRAB_OP_RESIZING_E:
- case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
- case META_GRAB_OP_KEYBOARD_RESIZING_S:
- case META_GRAB_OP_KEYBOARD_RESIZING_N:
- case META_GRAB_OP_KEYBOARD_RESIZING_W:
- case META_GRAB_OP_KEYBOARD_RESIZING_E:
- case META_GRAB_OP_KEYBOARD_RESIZING_SE:
- case META_GRAB_OP_KEYBOARD_RESIZING_NE:
- case META_GRAB_OP_KEYBOARD_RESIZING_SW:
- case META_GRAB_OP_KEYBOARD_RESIZING_NW:
- case META_GRAB_OP_KEYBOARD_MOVING:
- return TRUE;
-
- default:
- return FALSE;
- }
-}
-
-static gboolean
-grab_op_is_keyboard (MetaGrabOp op)
-{
- switch (op)
- {
- case META_GRAB_OP_KEYBOARD_MOVING:
- case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
- case META_GRAB_OP_KEYBOARD_RESIZING_S:
- case META_GRAB_OP_KEYBOARD_RESIZING_N:
- case META_GRAB_OP_KEYBOARD_RESIZING_W:
- case META_GRAB_OP_KEYBOARD_RESIZING_E:
- case META_GRAB_OP_KEYBOARD_RESIZING_SE:
- case META_GRAB_OP_KEYBOARD_RESIZING_NE:
- case META_GRAB_OP_KEYBOARD_RESIZING_SW:
- case META_GRAB_OP_KEYBOARD_RESIZING_NW:
- case META_GRAB_OP_KEYBOARD_TABBING_NORMAL:
- case META_GRAB_OP_KEYBOARD_TABBING_DOCK:
- case META_GRAB_OP_KEYBOARD_TABBING_GROUP:
- case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL:
- case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK:
- case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP:
- case META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING:
- return TRUE;
-
- default:
- return FALSE;
- }
-}
-
-gboolean
-meta_grab_op_is_resizing (MetaGrabOp op)
-{
- switch (op)
- {
- case META_GRAB_OP_RESIZING_SE:
- case META_GRAB_OP_RESIZING_S:
- case META_GRAB_OP_RESIZING_SW:
- case META_GRAB_OP_RESIZING_N:
- case META_GRAB_OP_RESIZING_NE:
- case META_GRAB_OP_RESIZING_NW:
- case META_GRAB_OP_RESIZING_W:
- case META_GRAB_OP_RESIZING_E:
- case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
- case META_GRAB_OP_KEYBOARD_RESIZING_S:
- case META_GRAB_OP_KEYBOARD_RESIZING_N:
- case META_GRAB_OP_KEYBOARD_RESIZING_W:
- case META_GRAB_OP_KEYBOARD_RESIZING_E:
- case META_GRAB_OP_KEYBOARD_RESIZING_SE:
- case META_GRAB_OP_KEYBOARD_RESIZING_NE:
- case META_GRAB_OP_KEYBOARD_RESIZING_SW:
- case META_GRAB_OP_KEYBOARD_RESIZING_NW:
- return TRUE;
-
- default:
- return FALSE;
- }
-}
-
-gboolean
-meta_grab_op_is_moving (MetaGrabOp op)
-{
- switch (op)
- {
- case META_GRAB_OP_MOVING:
- case META_GRAB_OP_KEYBOARD_MOVING:
- return TRUE;
-
- default:
- return FALSE;
- }
-}
-
-/* Get time of current event, or CurrentTime if none. */
-guint32
-meta_display_get_current_time (MetaDisplay *display)
-{
- return display->current_time;
-}
-
-/* Get a timestamp, even if it means a roundtrip */
-guint32
-meta_display_get_current_time_roundtrip (MetaDisplay *display)
-{
- guint32 timestamp;
-
- timestamp = meta_display_get_current_time (display);
- if (timestamp == CurrentTime)
- {
- XEvent property_event;
-
- /* Using the property XA_PRIMARY because it's safe; nothing
- * would use it as a property. The type doesn't matter.
- */
- XChangeProperty (display->xdisplay,
- display->timestamp_pinging_window,
- XA_PRIMARY, XA_STRING, 8,
- PropModeAppend, NULL, 0);
- XWindowEvent (display->xdisplay,
- display->timestamp_pinging_window,
- PropertyChangeMask,
- &property_event);
- timestamp = property_event.xproperty.time;
- }
-
- sanity_check_timestamps (display, timestamp);
-
- return timestamp;
-}
-
-static void
-add_ignored_serial (MetaDisplay *display,
- unsigned long serial)
-{
- int i;
-
- /* don't add the same serial more than once */
- if (display->ignored_serials[N_IGNORED_SERIALS-1] == serial)
- return;
-
- /* shift serials to the left */
- i = 0;
- while (i < (N_IGNORED_SERIALS - 1))
- {
- display->ignored_serials[i] = display->ignored_serials[i+1];
- ++i;
- }
- /* put new one on the end */
- display->ignored_serials[i] = serial;
-}
-
-static gboolean
-serial_is_ignored (MetaDisplay *display,
- unsigned long serial)
-{
- int i;
-
- i = 0;
- while (i < N_IGNORED_SERIALS)
- {
- if (display->ignored_serials[i] == serial)
- return TRUE;
- ++i;
- }
- return FALSE;
-}
-
-static void
-reset_ignores (MetaDisplay *display)
-{
- int i;
-
- i = 0;
- while (i < N_IGNORED_SERIALS)
- {
- display->ignored_serials[i] = 0;
- ++i;
- }
-
- display->ungrab_should_not_cause_focus_window = None;
-}
-
-static gboolean
-window_raise_with_delay_callback (void *data)
-{
- MetaWindow *window;
- MetaAutoRaiseData *auto_raise;
-
- auto_raise = data;
-
- meta_topic (META_DEBUG_FOCUS,
- "In autoraise callback for window 0x%lx\n",
- auto_raise->xwindow);
-
- auto_raise->display->autoraise_timeout_id = 0;
- auto_raise->display->autoraise_window = NULL;
-
- window = meta_display_lookup_x_window (auto_raise->display,
- auto_raise->xwindow);
-
- if (window == NULL)
- return FALSE;
-
- /* If we aren't already on top, check whether the pointer is inside
- * the window and raise the window if so.
- */
- if (meta_stack_get_top (window->screen->stack) != window)
- {
- int x, y, root_x, root_y;
- Window root, child;
- unsigned int mask;
- gboolean same_screen;
- gboolean point_in_window;
-
- meta_error_trap_push (window->display);
- same_screen = XQueryPointer (window->display->xdisplay,
- window->xwindow,
- &root, &child,
- &root_x, &root_y, &x, &y, &mask);
- meta_error_trap_pop (window->display, TRUE);
-
- point_in_window =
- (window->frame && POINT_IN_RECT (root_x, root_y, window->frame->rect)) ||
- (window->frame == NULL && POINT_IN_RECT (root_x, root_y, window->rect));
- if (same_screen && point_in_window)
- meta_window_raise (window);
- else
- meta_topic (META_DEBUG_FOCUS,
- "Pointer not inside window, not raising %s\n",
- window->desc);
- }
-
- return FALSE;
-}
-
-void
-meta_display_queue_autoraise_callback (MetaDisplay *display,
- MetaWindow *window)
-{
- MetaAutoRaiseData *auto_raise_data;
-
- meta_topic (META_DEBUG_FOCUS,
- "Queuing an autoraise timeout for %s with delay %d\n",
- window->desc,
- meta_prefs_get_auto_raise_delay ());
-
- auto_raise_data = g_new (MetaAutoRaiseData, 1);
- auto_raise_data->display = window->display;
- auto_raise_data->xwindow = window->xwindow;
-
- if (display->autoraise_timeout_id != 0)
- g_source_remove (display->autoraise_timeout_id);
-
- display->autoraise_timeout_id =
- g_timeout_add_full (G_PRIORITY_DEFAULT,
- meta_prefs_get_auto_raise_delay (),
- window_raise_with_delay_callback,
- auto_raise_data,
- g_free);
- display->autoraise_window = window;
-}
-
-#if 0
-static void
-handle_net_restack_window (MetaDisplay* display,
- XEvent *event)
-{
- MetaWindow *window;
-
- window = meta_display_lookup_x_window (display,
- event->xclient.window);
-
- if (window)
- {
- /* FIXME: The EWMH includes a sibling for the restack request, but we
- * (stupidly) don't currently support these types of raises.
- *
- * Also, unconditionally following these is REALLY stupid--we should
- * combine this code with the stuff in
- * meta_window_configure_request() which is smart about whether to
- * follow the request or do something else (though not smart enough
- * and is also too stupid to handle the sibling stuff).
- */
- switch (event->xclient.data.l[2])
- {
- case Above:
- meta_window_raise (window);
- break;
- case Below:
- meta_window_lower (window);
- break;
- case TopIf:
- case BottomIf:
- case Opposite:
- break;
- }
- }
-}
-#endif
-
-/**
- * This is the most important function in the whole program. It is the heart,
- * it is the nexus, it is the Grand Central Station of Metacity's world.
- * When we create a MetaDisplay, we ask GDK to pass *all* events for *all*
- * windows to this function. So every time anything happens that we might
- * want to know about, this function gets called. You see why it gets a bit
- * busy around here. Most of this function is a ginormous switch statement
- * dealing with all the kinds of events that might turn up.
- *
- * \param event The event that just happened
- * \param data The MetaDisplay that events are coming from, cast to a gpointer
- * so that it can be sent to a callback
- *
- * \ingroup main
- */
-static gboolean
-event_callback (XEvent *event,
- gpointer data)
-{
- MetaWindow *window;
- MetaWindow *property_for_window;
- MetaDisplay *display;
- Window modified;
- gboolean frame_was_receiver;
- gboolean filter_out_event;
-
- display = data;
-
-#ifdef WITH_VERBOSE_MODE
- if (dump_events)
- meta_spew_event (display, event);
-#endif
-
-#ifdef HAVE_STARTUP_NOTIFICATION
- sn_display_process_event (display->sn_display, event);
-#endif
-
- filter_out_event = FALSE;
- display->current_time = event_get_time (display, event);
- display->xinerama_cache_invalidated = TRUE;
-
- modified = event_get_modified_window (display, event);
-
- if (event->type == ButtonPress)
- {
- /* filter out scrollwheel */
- if (event->xbutton.button == 4 ||
- event->xbutton.button == 5)
- return FALSE;
- }
- else if (event->type == UnmapNotify)
- {
- if (meta_ui_window_should_not_cause_focus (display->xdisplay,
- modified))
- {
- add_ignored_serial (display, event->xany.serial);
- meta_topic (META_DEBUG_FOCUS,
- "Adding EnterNotify serial %lu to ignored focus serials\n",
- event->xany.serial);
- }
- }
- else if (event->type == LeaveNotify &&
- event->xcrossing.mode == NotifyUngrab &&
- modified == display->ungrab_should_not_cause_focus_window)
- {
- add_ignored_serial (display, event->xany.serial);
- meta_topic (META_DEBUG_FOCUS,
- "Adding LeaveNotify serial %lu to ignored focus serials\n",
- event->xany.serial);
- }
-
- if (modified != None)
- window = meta_display_lookup_x_window (display, modified);
- else
- window = NULL;
-
- /* We only want to respond to _NET_WM_USER_TIME property notify
- * events on _NET_WM_USER_TIME_WINDOW windows; in particular,
- * responding to UnmapNotify events is kind of bad.
- */
- property_for_window = NULL;
- if (window && modified == window->user_time_window)
- {
- property_for_window = window;
- window = NULL;
- }
-
-
- frame_was_receiver = FALSE;
- if (window &&
- window->frame &&
- modified == window->frame->xwindow)
- {
- /* Note that if the frame and the client both have an
- * XGrabButton (as is normal with our setup), the event
- * goes to the frame.
- */
- frame_was_receiver = TRUE;
- meta_topic (META_DEBUG_EVENTS, "Frame was receiver of event for %s\n",
- window->desc);
- }
-
-#ifdef HAVE_XSYNC
- if (META_DISPLAY_HAS_XSYNC (display) &&
- event->type == (display->xsync_event_base + XSyncAlarmNotify) &&
- ((XSyncAlarmNotifyEvent*)event)->alarm == display->grab_sync_request_alarm)
- {
- filter_out_event = TRUE; /* GTK doesn't want to see this really */
-
- if (display->grab_op != META_GRAB_OP_NONE &&
- display->grab_window != NULL &&
- grab_op_is_mouse (display->grab_op))
- meta_window_handle_mouse_grab_op_event (display->grab_window, event);
- }
-#endif /* HAVE_XSYNC */
-
-#ifdef HAVE_SHAPE
- if (META_DISPLAY_HAS_SHAPE (display) &&
- event->type == (display->shape_event_base + ShapeNotify))
- {
- filter_out_event = TRUE; /* GTK doesn't want to see this really */
-
- if (window && !frame_was_receiver)
- {
- XShapeEvent *sev = (XShapeEvent*) event;
-
- if (sev->kind == ShapeBounding)
- {
- if (sev->shaped && !window->has_shape)
- {
- window->has_shape = TRUE;
- meta_topic (META_DEBUG_SHAPES,
- "Window %s now has a shape\n",
- window->desc);
- }
- else if (!sev->shaped && window->has_shape)
- {
- window->has_shape = FALSE;
- meta_topic (META_DEBUG_SHAPES,
- "Window %s no longer has a shape\n",
- window->desc);
- }
- else
- {
- meta_topic (META_DEBUG_SHAPES,
- "Window %s shape changed\n",
- window->desc);
- }
-
- if (window->frame)
- {
- window->frame->need_reapply_frame_shape = TRUE;
- meta_warning("from event callback\n");
- meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
- }
- }
- }
- else
- {
- meta_topic (META_DEBUG_SHAPES,
- "ShapeNotify not on a client window (window %s frame_was_receiver = %d)\n",
- window ? window->desc : "(none)",
- frame_was_receiver);
- }
- }
-#endif /* HAVE_SHAPE */
-
- if (window && ((event->type == KeyPress) || (event->type == ButtonPress)))
- {
- if (CurrentTime == display->current_time)
- {
- /* We can't use missing (i.e. invalid) timestamps to set user time,
- * nor do we want to use them to sanity check other timestamps.
- * See bug 313490 for more details.
- */
- meta_warning ("Event has no timestamp! You may be using a broken "
- "program such as xse. Please ask the authors of that "
- "program to fix it.\n");
- }
- else
- {
- meta_window_set_user_time (window, display->current_time);
- sanity_check_timestamps (display, display->current_time);
- }
- }
-
- switch (event->type)
- {
- case KeyPress:
- case KeyRelease:
- meta_display_process_key_event (display, window, event);
- break;
- case ButtonPress:
- if ((window &&
- grab_op_is_mouse (display->grab_op) &&
- display->grab_button != (int) event->xbutton.button &&
- display->grab_window == window) ||
- grab_op_is_keyboard (display->grab_op))
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Ending grab op %u on window %s due to button press\n",
- display->grab_op,
- (display->grab_window ?
- display->grab_window->desc :
- "none"));
- if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op))
- {
- MetaScreen *screen;
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Syncing to old stack positions.\n");
- screen =
- meta_display_screen_for_root (display, event->xany.window);
-
- if (screen!=NULL)
- meta_stack_set_positions (screen->stack,
- display->grab_old_window_stacking);
- }
- meta_display_end_grab_op (display,
- event->xbutton.time);
- }
- else if (window && display->grab_op == META_GRAB_OP_NONE)
- {
- gboolean begin_move = FALSE;
- unsigned int grab_mask;
- gboolean unmodified;
-
- grab_mask = display->window_grab_modifiers;
- if (g_getenv ("METACITY_DEBUG_BUTTON_GRABS"))
- grab_mask |= ControlMask;
-
- /* Two possible sources of an unmodified event; one is a
- * client that's letting button presses pass through to the
- * frame, the other is our focus_window_grab on unmodified
- * button 1. So for all such events we focus the window.
- */
- unmodified = (event->xbutton.state & grab_mask) == 0;
-
- if (unmodified ||
- event->xbutton.button == 1)
- {
- /* don't focus if frame received, will be lowered in
- * frames.c or special-cased if the click was on a
- * minimize/close button.
- */
- if (!frame_was_receiver)
- {
- if (meta_prefs_get_raise_on_click ())
- meta_window_raise (window);
- else
- meta_topic (META_DEBUG_FOCUS,
- "Not raising window on click due to don't-raise-on-click option\n");
-
- /* Don't focus panels--they must explicitly request focus.
- * See bug 160470
- */
- if (window->type != META_WINDOW_DOCK)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Focusing %s due to unmodified button %u press (display.c)\n",
- window->desc, event->xbutton.button);
- meta_window_focus (window, event->xbutton.time);
- }
- else
- /* However, do allow terminals to lose focus due to new
- * window mappings after the user clicks on a panel.
- */
- display->allow_terminal_deactivation = TRUE;
- }
-
- /* you can move on alt-click but not on
- * the click-to-focus
- */
- if (!unmodified)
- begin_move = TRUE;
- }
- else if (!unmodified && event->xbutton.button == 2)
- {
- if (window->has_resize_func)
- {
- gboolean north, south;
- gboolean west, east;
- int root_x, root_y;
- MetaGrabOp op;
-
- meta_window_get_position (window, &root_x, &root_y);
-
- west = event->xbutton.x_root < (root_x + 1 * window->rect.width / 3);
- east = event->xbutton.x_root > (root_x + 2 * window->rect.width / 3);
- north = event->xbutton.y_root < (root_y + 1 * window->rect.height / 3);
- south = event->xbutton.y_root > (root_y + 2 * window->rect.height / 3);
-
- if (north && west)
- op = META_GRAB_OP_RESIZING_NW;
- else if (north && east)
- op = META_GRAB_OP_RESIZING_NE;
- else if (south && west)
- op = META_GRAB_OP_RESIZING_SW;
- else if (south && east)
- op = META_GRAB_OP_RESIZING_SE;
- else if (north)
- op = META_GRAB_OP_RESIZING_N;
- else if (west)
- op = META_GRAB_OP_RESIZING_W;
- else if (east)
- op = META_GRAB_OP_RESIZING_E;
- else if (south)
- op = META_GRAB_OP_RESIZING_S;
- else /* Middle region is no-op to avoid user triggering wrong action */
- op = META_GRAB_OP_NONE;
-
- if (op != META_GRAB_OP_NONE)
- meta_display_begin_grab_op (display,
- window->screen,
- window,
- op,
- TRUE,
- FALSE,
- event->xbutton.button,
- 0,
- event->xbutton.time,
- event->xbutton.x_root,
- event->xbutton.y_root);
- }
- }
- else if (event->xbutton.button == 3)
- {
- if (meta_prefs_get_raise_on_click ())
- meta_window_raise (window);
- meta_window_show_menu (window,
- event->xbutton.x_root,
- event->xbutton.y_root,
- event->xbutton.button,
- event->xbutton.time);
- }
-
- if (!frame_was_receiver && unmodified)
- {
- /* This is from our synchronous grab since
- * it has no modifiers and was on the client window
- */
- int mode;
-
- /* When clicking a different app in click-to-focus
- * in application-based mode, and the different
- * app is not a dock or desktop, eat the focus click.
- */
- if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK &&
- meta_prefs_get_application_based () &&
- !window->has_focus &&
- window->type != META_WINDOW_DOCK &&
- window->type != META_WINDOW_DESKTOP &&
- (display->focus_window == NULL ||
- !meta_window_same_application (window,
- display->focus_window)))
- mode = AsyncPointer; /* eat focus click */
- else
- mode = ReplayPointer; /* give event back */
-
- meta_verbose ("Allowing events mode %s time %u\n",
- mode == AsyncPointer ? "AsyncPointer" : "ReplayPointer",
- (unsigned int)event->xbutton.time);
-
- XAllowEvents (display->xdisplay,
- mode, event->xbutton.time);
- }
-
- if (begin_move && window->has_move_func)
- {
- meta_display_begin_grab_op (display,
- window->screen,
- window,
- META_GRAB_OP_MOVING,
- TRUE,
- FALSE,
- event->xbutton.button,
- 0,
- event->xbutton.time,
- event->xbutton.x_root,
- event->xbutton.y_root);
- }
- }
- break;
- case ButtonRelease:
- if (display->grab_window == window &&
- grab_op_is_mouse (display->grab_op))
- meta_window_handle_mouse_grab_op_event (window, event);
- break;
- case MotionNotify:
- if (display->grab_window == window &&
- grab_op_is_mouse (display->grab_op))
- meta_window_handle_mouse_grab_op_event (window, event);
- break;
- case EnterNotify:
- if (display->grab_window == window &&
- grab_op_is_mouse (display->grab_op))
- {
- meta_window_handle_mouse_grab_op_event (window, event);
- break;
- }
-
- /* If the mouse switches screens, active the default window on the new
- * screen; this will make keybindings and workspace-launched items
- * actually appear on the right screen.
- */
- {
- MetaScreen *new_screen =
- meta_display_screen_for_root (display, event->xcrossing.root);
-
- if (new_screen != NULL && display->active_screen != new_screen)
- meta_workspace_focus_default_window (new_screen->active_workspace,
- NULL,
- event->xcrossing.time);
- }
-
- /* Check if we've entered a window; do this even if window->has_focus to
- * avoid races.
- */
- if (window && !serial_is_ignored (display, event->xany.serial) &&
- event->xcrossing.mode != NotifyGrab &&
- event->xcrossing.mode != NotifyUngrab &&
- event->xcrossing.detail != NotifyInferior &&
- meta_display_focus_sentinel_clear (display))
- {
- switch (meta_prefs_get_focus_mode ())
- {
- case META_FOCUS_MODE_SLOPPY:
- case META_FOCUS_MODE_MOUSE:
- display->mouse_mode = TRUE;
- if (window->type != META_WINDOW_DOCK &&
- window->type != META_WINDOW_DESKTOP)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Focusing %s due to enter notify with serial %lu "
- "at time %lu, and setting display->mouse_mode to "
- "TRUE.\n",
- window->desc,
- event->xany.serial,
- event->xcrossing.time);
-
- meta_window_focus (window, event->xcrossing.time);
-
- /* stop ignoring stuff */
- reset_ignores (display);
-
- if (meta_prefs_get_auto_raise ())
- {
- meta_display_queue_autoraise_callback (display, window);
- }
- else
- {
- meta_topic (META_DEBUG_FOCUS,
- "Auto raise is disabled\n");
- }
- }
- /* In mouse focus mode, we defocus when the mouse *enters*
- * the DESKTOP window, instead of defocusing on LeaveNotify.
- * This is because having the mouse enter override-redirect
- * child windows unfortunately causes LeaveNotify events that
- * we can't distinguish from the mouse actually leaving the
- * toplevel window as we expect. But, since we filter out
- * EnterNotify events on override-redirect windows, this
- * alternative mechanism works great.
- */
- if (window->type == META_WINDOW_DESKTOP &&
- meta_prefs_get_focus_mode() == META_FOCUS_MODE_MOUSE &&
- display->expected_focus_window != NULL)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Unsetting focus from %s due to mouse entering "
- "the DESKTOP window\n",
- display->expected_focus_window->desc);
- meta_display_focus_the_no_focus_window (display,
- window->screen,
- event->xcrossing.time);
- }
- break;
- case META_FOCUS_MODE_CLICK:
- break;
- }
-
- if (window->type == META_WINDOW_DOCK)
- meta_window_raise (window);
- }
- break;
- case LeaveNotify:
- if (display->grab_window == window &&
- grab_op_is_mouse (display->grab_op))
- meta_window_handle_mouse_grab_op_event (window, event);
- else if (window != NULL)
- {
- if (window->type == META_WINDOW_DOCK &&
- event->xcrossing.mode != NotifyGrab &&
- event->xcrossing.mode != NotifyUngrab &&
- !window->has_focus)
- meta_window_lower (window);
- }
- break;
- case FocusIn:
- case FocusOut:
- if (window)
- {
- meta_window_notify_focus (window, event);
- }
- else if (meta_display_xwindow_is_a_no_focus_window (display,
- event->xany.window))
- {
- meta_topic (META_DEBUG_FOCUS,
- "Focus %s event received on no_focus_window 0x%lx "
- "mode %s detail %s\n",
- event->type == FocusIn ? "in" :
- event->type == FocusOut ? "out" :
- "???",
- event->xany.window,
- meta_event_mode_to_string (event->xfocus.mode),
- meta_event_detail_to_string (event->xfocus.detail));
- }
- else
- {
- MetaScreen *screen =
- meta_display_screen_for_root(display,
- event->xany.window);
- if (screen == NULL)
- break;
-
- meta_topic (META_DEBUG_FOCUS,
- "Focus %s event received on root window 0x%lx "
- "mode %s detail %s\n",
- event->type == FocusIn ? "in" :
- event->type == FocusOut ? "out" :
- "???",
- event->xany.window,
- meta_event_mode_to_string (event->xfocus.mode),
- meta_event_detail_to_string (event->xfocus.detail));
-
- if (event->type == FocusIn &&
- event->xfocus.detail == NotifyDetailNone)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Focus got set to None, probably due to "
- "brain-damage in the X protocol (see bug "
- "125492). Setting the default focus window.\n");
- meta_workspace_focus_default_window (screen->active_workspace,
- NULL,
- meta_display_get_current_time_roundtrip (display));
- }
- else if (event->type == FocusIn &&
- event->xfocus.mode == NotifyNormal &&
- event->xfocus.detail == NotifyInferior)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Focus got set to root window, probably due to "
- "gnome-session logout dialog usage (see bug "
- "153220). Setting the default focus window.\n");
- meta_workspace_focus_default_window (screen->active_workspace,
- NULL,
- meta_display_get_current_time_roundtrip (display));
- }
-
- }
- break;
- case KeymapNotify:
- break;
- case Expose:
- break;
- case GraphicsExpose:
- break;
- case NoExpose:
- break;
- case VisibilityNotify:
- break;
- case CreateNotify:
- break;
-
- case DestroyNotify:
- if (window)
- {
- /* FIXME: It sucks that DestroyNotify events don't come with
- * a timestamp; could we do something better here? Maybe X
- * will change one day?
- */
- guint32 timestamp;
- timestamp = meta_display_get_current_time_roundtrip (display);
-
- if (display->grab_op != META_GRAB_OP_NONE &&
- display->grab_window == window)
- meta_display_end_grab_op (display, timestamp);
-
- if (frame_was_receiver)
- {
- meta_warning ("Unexpected destruction of frame 0x%lx, not sure if this should silently fail or be considered a bug\n",
- window->frame->xwindow);
- meta_error_trap_push (display);
- meta_window_destroy_frame (window->frame->window);
- meta_error_trap_pop (display, FALSE);
- }
- else
- {
- /* Unmanage destroyed window */
- meta_window_free (window, timestamp);
- window = NULL;
- }
- }
- break;
- case UnmapNotify:
- if (window)
- {
- /* FIXME: It sucks that UnmapNotify events don't come with
- * a timestamp; could we do something better here? Maybe X
- * will change one day?
- */
- guint32 timestamp;
- timestamp = meta_display_get_current_time_roundtrip (display);
-
- if (display->grab_op != META_GRAB_OP_NONE &&
- display->grab_window == window &&
- ((window->frame == NULL) || !window->frame->mapped))
- meta_display_end_grab_op (display, timestamp);
-
- if (!frame_was_receiver)
- {
- if (window->unmaps_pending == 0)
- {
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Window %s withdrawn\n",
- window->desc);
-
- meta_effect_run_close (window, NULL, NULL);
-
- /* Unmanage withdrawn window */
- window->withdrawn = TRUE;
- meta_window_free (window, timestamp);
- window = NULL;
- }
- else
- {
- window->unmaps_pending -= 1;
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Received pending unmap, %d now pending\n",
- window->unmaps_pending);
- }
- }
-
- /* Unfocus on UnmapNotify, do this after the possible
- * window_free above so that window_free can see if window->has_focus
- * and move focus to another window
- */
- if (window)
- meta_window_notify_focus (window, event);
- }
- break;
- case MapNotify:
- break;
- case MapRequest:
- if (window == NULL)
- {
- window = meta_window_new (display, event->xmaprequest.window,
- FALSE);
- }
- /* if frame was receiver it's some malicious send event or something */
- else if (!frame_was_receiver && window)
- {
- meta_verbose ("MapRequest on %s mapped = %d minimized = %d\n",
- window->desc, window->mapped, window->minimized);
- if (window->minimized)
- {
- meta_window_unminimize (window);
- if (window->workspace != window->screen->active_workspace)
- {
- meta_verbose ("Changing workspace due to MapRequest mapped = %d minimized = %d\n",
- window->mapped, window->minimized);
- meta_window_change_workspace (window,
- window->screen->active_workspace);
- }
- }
- }
- break;
- case ReparentNotify:
- break;
- case ConfigureNotify:
- /* Handle screen resize */
- {
- MetaScreen *screen;
-
- screen = meta_display_screen_for_root (display,
- event->xconfigure.window);
-
- if (screen != NULL)
- {
-#ifdef HAVE_RANDR
- /* do the resize the official way */
- XRRUpdateConfiguration (event);
-#else
- /* poke around in Xlib */
- screen->xscreen->width = event->xconfigure.width;
- screen->xscreen->height = event->xconfigure.height;
-#endif
-
- meta_screen_resize (screen,
- event->xconfigure.width,
- event->xconfigure.height);
- }
- }
- break;
- case ConfigureRequest:
- /* This comment and code is found in both twm and fvwm */
- /*
- * According to the July 27, 1988 ICCCM draft, we should ignore size and
- * position fields in the WM_NORMAL_HINTS property when we map a window.
- * Instead, we'll read the current geometry. Therefore, we should respond
- * to configuration requests for windows which have never been mapped.
- */
- if (window == NULL)
- {
- unsigned int xwcm;
- XWindowChanges xwc;
-
- xwcm = event->xconfigurerequest.value_mask &
- (CWX | CWY | CWWidth | CWHeight | CWBorderWidth);
-
- xwc.x = event->xconfigurerequest.x;
- xwc.y = event->xconfigurerequest.y;
- xwc.width = event->xconfigurerequest.width;
- xwc.height = event->xconfigurerequest.height;
- xwc.border_width = event->xconfigurerequest.border_width;
-
- meta_verbose ("Configuring withdrawn window to %d,%d %dx%d border %d (some values may not be in mask)\n",
- xwc.x, xwc.y, xwc.width, xwc.height, xwc.border_width);
- meta_error_trap_push (display);
- XConfigureWindow (display->xdisplay, event->xconfigurerequest.window,
- xwcm, &xwc);
- meta_error_trap_pop (display, FALSE);
- }
- else
- {
- if (!frame_was_receiver)
- meta_window_configure_request (window, event);
- }
- break;
- case GravityNotify:
- break;
- case ResizeRequest:
- break;
- case CirculateNotify:
- break;
- case CirculateRequest:
- break;
- case PropertyNotify:
- {
- MetaGroup *group;
- MetaScreen *screen;
-
- if (window && !frame_was_receiver)
- meta_window_property_notify (window, event);
- else if (property_for_window && !frame_was_receiver)
- meta_window_property_notify (property_for_window, event);
-
- group = meta_display_lookup_group (display,
- event->xproperty.window);
- if (group != NULL)
- meta_group_property_notify (group, event);
-
- screen = NULL;
- if (window == NULL &&
- group == NULL) /* window/group != NULL means it wasn't a root window */
- screen = meta_display_screen_for_root (display,
- event->xproperty.window);
-
- if (screen != NULL)
- {
- if (event->xproperty.atom ==
- display->atom__NET_DESKTOP_LAYOUT)
- meta_screen_update_workspace_layout (screen);
- else if (event->xproperty.atom ==
- display->atom__NET_DESKTOP_NAMES)
- meta_screen_update_workspace_names (screen);
-#if 0
- else if (event->xproperty.atom ==
- display->atom__NET_RESTACK_WINDOW)
- handle_net_restack_window (display, event);
-#endif
-
- /* we just use this property as a sentinel to avoid
- * certain race conditions. See the comment for the
- * sentinel_counter variable declaration in display.h
- */
- if (event->xproperty.atom ==
- display->atom__METACITY_SENTINEL)
- {
- meta_display_decrement_focus_sentinel (display);
- }
- }
- }
- break;
- case SelectionClear:
- /* do this here instead of at end of function
- * so we can return
- */
-
- /* FIXME: Clearing display->current_time here makes no sense to
- * me; who put this here and why?
- */
- display->current_time = CurrentTime;
-
- process_selection_clear (display, event);
- /* Note that processing that may have resulted in
- * closing the display... so return right away.
- */
- return FALSE;
- case SelectionRequest:
- process_selection_request (display, event);
- break;
- case SelectionNotify:
- break;
- case ColormapNotify:
- if (window && !frame_was_receiver)
- window->colormap = event->xcolormap.colormap;
- break;
- case ClientMessage:
- if (window)
- {
- if (!frame_was_receiver)
- meta_window_client_message (window, event);
- }
- else
- {
- MetaScreen *screen;
-
- screen = meta_display_screen_for_root (display,
- event->xclient.window);
-
- if (screen)
- {
- if (event->xclient.message_type ==
- display->atom__NET_CURRENT_DESKTOP)
- {
- int space;
- MetaWorkspace *workspace;
- guint32 time;
-
- space = event->xclient.data.l[0];
- time = event->xclient.data.l[1];
-
- meta_verbose ("Request to change current workspace to %d with "
- "specified timestamp of %u\n",
- space, time);
-
- workspace =
- meta_screen_get_workspace_by_index (screen,
- space);
-
- /* Handle clients using the older version of the spec... */
- if (time == 0 && workspace)
- {
- meta_warning ("Received a NET_CURRENT_DESKTOP message "
- "from a broken (outdated) client who sent "
- "a 0 timestamp\n");
- time = meta_display_get_current_time_roundtrip (display);
- }
-
- if (workspace)
- meta_workspace_activate (workspace, time);
- else
- meta_verbose ("Don't know about workspace %d\n", space);
- }
- else if (event->xclient.message_type ==
- display->atom__NET_NUMBER_OF_DESKTOPS)
- {
- int num_spaces;
-
- num_spaces = event->xclient.data.l[0];
-
- meta_verbose ("Request to set number of workspaces to %d\n",
- num_spaces);
-
- meta_prefs_set_num_workspaces (num_spaces);
- }
- else if (event->xclient.message_type ==
- display->atom__NET_SHOWING_DESKTOP)
- {
- gboolean showing_desktop;
- guint32 timestamp;
-
- showing_desktop = event->xclient.data.l[0] != 0;
- /* FIXME: Braindead protocol doesn't have a timestamp */
- timestamp = meta_display_get_current_time_roundtrip (display);
- meta_verbose ("Request to %s desktop\n",
- showing_desktop ? "show" : "hide");
-
- if (showing_desktop)
- meta_screen_show_desktop (screen, timestamp);
- else
- {
- meta_screen_unshow_desktop (screen);
- meta_workspace_focus_default_window (screen->active_workspace, NULL, timestamp);
- }
- }
- else if (event->xclient.message_type ==
- display->atom__METACITY_RESTART_MESSAGE)
- {
- meta_verbose ("Received restart request\n");
- meta_restart ();
- }
- else if (event->xclient.message_type ==
- display->atom__METACITY_RELOAD_THEME_MESSAGE)
- {
- meta_verbose ("Received reload theme request\n");
- meta_ui_set_current_theme (meta_prefs_get_theme (),
- TRUE);
- meta_display_retheme_all ();
- }
- else if (event->xclient.message_type ==
- display->atom__METACITY_SET_KEYBINDINGS_MESSAGE)
- {
- meta_verbose ("Received set keybindings request = %d\n",
- (int) event->xclient.data.l[0]);
- meta_set_keybindings_disabled (!event->xclient.data.l[0]);
- }
- else if (event->xclient.message_type ==
- display->atom__METACITY_TOGGLE_VERBOSE)
- {
- meta_verbose ("Received toggle verbose message\n");
- meta_set_verbose (!meta_is_verbose ());
- }
- else if (event->xclient.message_type ==
- display->atom_WM_PROTOCOLS)
- {
- meta_verbose ("Received WM_PROTOCOLS message\n");
-
- if ((Atom)event->xclient.data.l[0] == display->atom__NET_WM_PING)
- {
- process_pong_message (display, event);
-
- /* We don't want ping reply events going into
- * the GTK+ event loop because gtk+ will treat
- * them as ping requests and send more replies.
- */
- filter_out_event = TRUE;
- }
- }
- }
-
- if (event->xclient.message_type ==
- display->atom__NET_REQUEST_FRAME_EXTENTS)
- {
- meta_verbose ("Received _NET_REQUEST_FRAME_EXTENTS message\n");
- process_request_frame_extents (display, event);
- }
- }
- break;
- case MappingNotify:
- {
- gboolean ignore_current;
-
- ignore_current = FALSE;
-
- /* Check whether the next event is an identical MappingNotify
- * event. If it is, ignore the current event, we'll update
- * when we get the next one.
- */
- if (XPending (display->xdisplay))
- {
- XEvent next_event;
-
- XPeekEvent (display->xdisplay, &next_event);
-
- if (next_event.type == MappingNotify &&
- next_event.xmapping.request == event->xmapping.request)
- ignore_current = TRUE;
- }
-
- if (!ignore_current)
- {
- /* Let XLib know that there is a new keyboard mapping.
- */
- XRefreshKeyboardMapping (&event->xmapping);
- meta_display_process_mapping_event (display, event);
- }
- }
- break;
- default:
-#ifdef HAVE_XKB
- if (event->type == display->xkb_base_event_type)
- {
- XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event;
-
- switch (xkb_ev->xkb_type)
- {
- case XkbBellNotify:
- if (XSERVER_TIME_IS_BEFORE(display->last_bell_time,
- xkb_ev->time - 1000))
- {
- display->last_bell_time = xkb_ev->time;
- meta_bell_notify (display, xkb_ev);
- }
- break;
- }
- }
-#endif
- break;
- }
-
- if (display->compositor)
- {
- meta_compositor_process_event (display->compositor,
- event,
- window);
- }
-
- display->current_time = CurrentTime;
- return filter_out_event;
-}
-
-/* Return the window this has to do with, if any, rather
- * than the frame or root window that was selecting
- * for substructure
- */
-static Window
-event_get_modified_window (MetaDisplay *display,
- XEvent *event)
-{
- switch (event->type)
- {
- case KeyPress:
- case KeyRelease:
- case ButtonPress:
- case ButtonRelease:
- case MotionNotify:
- case FocusIn:
- case FocusOut:
- case KeymapNotify:
- case Expose:
- case GraphicsExpose:
- case NoExpose:
- case VisibilityNotify:
- case ResizeRequest:
- case PropertyNotify:
- case SelectionClear:
- case SelectionRequest:
- case SelectionNotify:
- case ColormapNotify:
- case ClientMessage:
- case EnterNotify:
- case LeaveNotify:
- return event->xany.window;
-
- case CreateNotify:
- return event->xcreatewindow.window;
-
- case DestroyNotify:
- return event->xdestroywindow.window;
-
- case UnmapNotify:
- return event->xunmap.window;
-
- case MapNotify:
- return event->xmap.window;
-
- case MapRequest:
- return event->xmaprequest.window;
-
- case ReparentNotify:
- return event->xreparent.window;
-
- case ConfigureNotify:
- return event->xconfigure.window;
-
- case ConfigureRequest:
- return event->xconfigurerequest.window;
-
- case GravityNotify:
- return event->xgravity.window;
-
- case CirculateNotify:
- return event->xcirculate.window;
-
- case CirculateRequest:
- return event->xcirculaterequest.window;
-
- case MappingNotify:
- return None;
-
- default:
-#ifdef HAVE_SHAPE
- if (META_DISPLAY_HAS_SHAPE (display) &&
- event->type == (display->shape_event_base + ShapeNotify))
- {
- XShapeEvent *sev = (XShapeEvent*) event;
- return sev->window;
- }
-#endif
-
- return None;
- }
-}
-
-static guint32
-event_get_time (MetaDisplay *display,
- XEvent *event)
-{
- switch (event->type)
- {
- case KeyPress:
- case KeyRelease:
- return event->xkey.time;
-
- case ButtonPress:
- case ButtonRelease:
- return event->xbutton.time;
-
- case MotionNotify:
- return event->xmotion.time;
-
- case PropertyNotify:
- return event->xproperty.time;
-
- case SelectionClear:
- case SelectionRequest:
- case SelectionNotify:
- return event->xselection.time;
-
- case EnterNotify:
- case LeaveNotify:
- return event->xcrossing.time;
-
- case FocusIn:
- case FocusOut:
- case KeymapNotify:
- case Expose:
- case GraphicsExpose:
- case NoExpose:
- case MapNotify:
- case UnmapNotify:
- case VisibilityNotify:
- case ResizeRequest:
- case ColormapNotify:
- case ClientMessage:
- case CreateNotify:
- case DestroyNotify:
- case MapRequest:
- case ReparentNotify:
- case ConfigureNotify:
- case ConfigureRequest:
- case GravityNotify:
- case CirculateNotify:
- case CirculateRequest:
- case MappingNotify:
- default:
- return CurrentTime;
- }
-}
-
-#ifdef WITH_VERBOSE_MODE
-const char*
-meta_event_detail_to_string (int d)
-{
- const char *detail = "???";
- switch (d)
- {
- /* We are an ancestor in the A<->B focus change relationship */
- case NotifyAncestor:
- detail = "NotifyAncestor";
- break;
- case NotifyDetailNone:
- detail = "NotifyDetailNone";
- break;
- /* We are a descendant in the A<->B focus change relationship */
- case NotifyInferior:
- detail = "NotifyInferior";
- break;
- case NotifyNonlinear:
- detail = "NotifyNonlinear";
- break;
- case NotifyNonlinearVirtual:
- detail = "NotifyNonlinearVirtual";
- break;
- case NotifyPointer:
- detail = "NotifyPointer";
- break;
- case NotifyPointerRoot:
- detail = "NotifyPointerRoot";
- break;
- case NotifyVirtual:
- detail = "NotifyVirtual";
- break;
- }
-
- return detail;
-}
-#endif /* WITH_VERBOSE_MODE */
-
-#ifdef WITH_VERBOSE_MODE
-const char*
-meta_event_mode_to_string (int m)
-{
- const char *mode = "???";
- switch (m)
- {
- case NotifyNormal:
- mode = "NotifyNormal";
- break;
- case NotifyGrab:
- mode = "NotifyGrab";
- break;
- case NotifyUngrab:
- mode = "NotifyUngrab";
- break;
- /* not sure any X implementations are missing this, but
- * it seems to be absent from some docs.
- */
-#ifdef NotifyWhileGrabbed
- case NotifyWhileGrabbed:
- mode = "NotifyWhileGrabbed";
- break;
-#endif
- }
-
- return mode;
-}
-#endif /* WITH_VERBOSE_MODE */
-
-#ifdef WITH_VERBOSE_MODE
-static const char*
-stack_mode_to_string (int mode)
-{
- switch (mode)
- {
- case Above:
- return "Above";
- case Below:
- return "Below";
- case TopIf:
- return "TopIf";
- case BottomIf:
- return "BottomIf";
- case Opposite:
- return "Opposite";
- }
-
- return "Unknown";
-}
-#endif /* WITH_VERBOSE_MODE */
-
-#ifdef WITH_VERBOSE_MODE
-static char*
-key_event_description (Display *xdisplay,
- XEvent *event)
-{
- KeySym keysym;
- const char *str;
-
- keysym = XKeycodeToKeysym (xdisplay, event->xkey.keycode, 0);
-
- str = XKeysymToString (keysym);
-
- return g_strdup_printf ("Key '%s' state 0x%x",
- str ? str : "none", event->xkey.state);
-}
-#endif /* WITH_VERBOSE_MODE */
-
-#ifdef HAVE_XSYNC
-#ifdef WITH_VERBOSE_MODE
-static gint64
-sync_value_to_64 (const XSyncValue *value)
-{
- gint64 v;
-
- v = XSyncValueLow32 (*value);
- v |= (((gint64)XSyncValueHigh32 (*value)) << 32);
-
- return v;
-}
-#endif /* WITH_VERBOSE_MODE */
-
-#ifdef WITH_VERBOSE_MODE
-static const char*
-alarm_state_to_string (XSyncAlarmState state)
-{
- switch (state)
- {
- case XSyncAlarmActive:
- return "Active";
- case XSyncAlarmInactive:
- return "Inactive";
- case XSyncAlarmDestroyed:
- return "Destroyed";
- default:
- return "(unknown)";
- }
-}
-#endif /* WITH_VERBOSE_MODE */
-
-#endif /* HAVE_XSYNC */
-
-#ifdef WITH_VERBOSE_MODE
-static void
-meta_spew_event (MetaDisplay *display,
- XEvent *event)
-{
- const char *name = NULL;
- char *extra = NULL;
- char *winname;
- MetaScreen *screen;
-
- if (!meta_is_verbose())
- return;
-
- /* filter overnumerous events */
- if (event->type == Expose || event->type == MotionNotify ||
- event->type == NoExpose)
- return;
-
- switch (event->type)
- {
- case KeyPress:
- name = "KeyPress";
- extra = key_event_description (display->xdisplay, event);
- break;
- case KeyRelease:
- name = "KeyRelease";
- extra = key_event_description (display->xdisplay, event);
- break;
- case ButtonPress:
- name = "ButtonPress";
- extra = g_strdup_printf ("button %u state 0x%x x %d y %d root 0x%lx same_screen %d",
- event->xbutton.button,
- event->xbutton.state,
- event->xbutton.x,
- event->xbutton.y,
- event->xbutton.root,
- event->xbutton.same_screen);
- break;
- case ButtonRelease:
- name = "ButtonRelease";
- extra = g_strdup_printf ("button %u state 0x%x x %d y %d root 0x%lx same_screen %d",
- event->xbutton.button,
- event->xbutton.state,
- event->xbutton.x,
- event->xbutton.y,
- event->xbutton.root,
- event->xbutton.same_screen);
- break;
- case MotionNotify:
- name = "MotionNotify";
- extra = g_strdup_printf ("win: 0x%lx x: %d y: %d",
- event->xmotion.window,
- event->xmotion.x,
- event->xmotion.y);
- break;
- case EnterNotify:
- name = "EnterNotify";
- extra = g_strdup_printf ("win: 0x%lx root: 0x%lx subwindow: 0x%lx mode: %s detail: %s focus: %d x: %d y: %d",
- event->xcrossing.window,
- event->xcrossing.root,
- event->xcrossing.subwindow,
- meta_event_mode_to_string (event->xcrossing.mode),
- meta_event_detail_to_string (event->xcrossing.detail),
- event->xcrossing.focus,
- event->xcrossing.x,
- event->xcrossing.y);
- break;
- case LeaveNotify:
- name = "LeaveNotify";
- extra = g_strdup_printf ("win: 0x%lx root: 0x%lx subwindow: 0x%lx mode: %s detail: %s focus: %d x: %d y: %d",
- event->xcrossing.window,
- event->xcrossing.root,
- event->xcrossing.subwindow,
- meta_event_mode_to_string (event->xcrossing.mode),
- meta_event_detail_to_string (event->xcrossing.detail),
- event->xcrossing.focus,
- event->xcrossing.x,
- event->xcrossing.y);
- break;
- case FocusIn:
- name = "FocusIn";
- extra = g_strdup_printf ("detail: %s mode: %s\n",
- meta_event_detail_to_string (event->xfocus.detail),
- meta_event_mode_to_string (event->xfocus.mode));
- break;
- case FocusOut:
- name = "FocusOut";
- extra = g_strdup_printf ("detail: %s mode: %s\n",
- meta_event_detail_to_string (event->xfocus.detail),
- meta_event_mode_to_string (event->xfocus.mode));
- break;
- case KeymapNotify:
- name = "KeymapNotify";
- break;
- case Expose:
- name = "Expose";
- break;
- case GraphicsExpose:
- name = "GraphicsExpose";
- break;
- case NoExpose:
- name = "NoExpose";
- break;
- case VisibilityNotify:
- name = "VisibilityNotify";
- break;
- case CreateNotify:
- name = "CreateNotify";
- extra = g_strdup_printf ("parent: 0x%lx window: 0x%lx",
- event->xcreatewindow.parent,
- event->xcreatewindow.window);
- break;
- case DestroyNotify:
- name = "DestroyNotify";
- extra = g_strdup_printf ("event: 0x%lx window: 0x%lx",
- event->xdestroywindow.event,
- event->xdestroywindow.window);
- break;
- case UnmapNotify:
- name = "UnmapNotify";
- extra = g_strdup_printf ("event: 0x%lx window: 0x%lx from_configure: %d",
- event->xunmap.event,
- event->xunmap.window,
- event->xunmap.from_configure);
- break;
- case MapNotify:
- name = "MapNotify";
- extra = g_strdup_printf ("event: 0x%lx window: 0x%lx override_redirect: %d",
- event->xmap.event,
- event->xmap.window,
- event->xmap.override_redirect);
- break;
- case MapRequest:
- name = "MapRequest";
- extra = g_strdup_printf ("window: 0x%lx parent: 0x%lx\n",
- event->xmaprequest.window,
- event->xmaprequest.parent);
- break;
- case ReparentNotify:
- name = "ReparentNotify";
- extra = g_strdup_printf ("window: 0x%lx parent: 0x%lx event: 0x%lx\n",
- event->xreparent.window,
- event->xreparent.parent,
- event->xreparent.event);
- break;
- case ConfigureNotify:
- name = "ConfigureNotify";
- extra = g_strdup_printf ("x: %d y: %d w: %d h: %d above: 0x%lx override_redirect: %d",
- event->xconfigure.x,
- event->xconfigure.y,
- event->xconfigure.width,
- event->xconfigure.height,
- event->xconfigure.above,
- event->xconfigure.override_redirect);
- break;
- case ConfigureRequest:
- name = "ConfigureRequest";
- extra = g_strdup_printf ("parent: 0x%lx window: 0x%lx x: %d %sy: %d %sw: %d %sh: %d %sborder: %d %sabove: %lx %sstackmode: %s %s",
- event->xconfigurerequest.parent,
- event->xconfigurerequest.window,
- event->xconfigurerequest.x,
- event->xconfigurerequest.value_mask &
- CWX ? "" : "(unset) ",
- event->xconfigurerequest.y,
- event->xconfigurerequest.value_mask &
- CWY ? "" : "(unset) ",
- event->xconfigurerequest.width,
- event->xconfigurerequest.value_mask &
- CWWidth ? "" : "(unset) ",
- event->xconfigurerequest.height,
- event->xconfigurerequest.value_mask &
- CWHeight ? "" : "(unset) ",
- event->xconfigurerequest.border_width,
- event->xconfigurerequest.value_mask &
- CWBorderWidth ? "" : "(unset)",
- event->xconfigurerequest.above,
- event->xconfigurerequest.value_mask &
- CWSibling ? "" : "(unset)",
- stack_mode_to_string (event->xconfigurerequest.detail),
- event->xconfigurerequest.value_mask &
- CWStackMode ? "" : "(unset)");
- break;
- case GravityNotify:
- name = "GravityNotify";
- break;
- case ResizeRequest:
- name = "ResizeRequest";
- extra = g_strdup_printf ("width = %d height = %d",
- event->xresizerequest.width,
- event->xresizerequest.height);
- break;
- case CirculateNotify:
- name = "CirculateNotify";
- break;
- case CirculateRequest:
- name = "CirculateRequest";
- break;
- case PropertyNotify:
- {
- char *str;
- const char *state;
-
- name = "PropertyNotify";
-
- meta_error_trap_push (display);
- str = XGetAtomName (display->xdisplay,
- event->xproperty.atom);
- meta_error_trap_pop (display, TRUE);
-
- if (event->xproperty.state == PropertyNewValue)
- state = "PropertyNewValue";
- else if (event->xproperty.state == PropertyDelete)
- state = "PropertyDelete";
- else
- state = "???";
-
- extra = g_strdup_printf ("atom: %s state: %s",
- str ? str : "(unknown atom)",
- state);
- meta_XFree (str);
- }
- break;
- case SelectionClear:
- name = "SelectionClear";
- break;
- case SelectionRequest:
- name = "SelectionRequest";
- break;
- case SelectionNotify:
- name = "SelectionNotify";
- break;
- case ColormapNotify:
- name = "ColormapNotify";
- break;
- case ClientMessage:
- {
- char *str;
- name = "ClientMessage";
- meta_error_trap_push (display);
- str = XGetAtomName (display->xdisplay,
- event->xclient.message_type);
- meta_error_trap_pop (display, TRUE);
- extra = g_strdup_printf ("type: %s format: %d\n",
- str ? str : "(unknown atom)",
- event->xclient.format);
- meta_XFree (str);
- }
- break;
- case MappingNotify:
- name = "MappingNotify";
- break;
- default:
-#ifdef HAVE_XSYNC
- if (META_DISPLAY_HAS_XSYNC (display) &&
- event->type == (display->xsync_event_base + XSyncAlarmNotify))
- {
- XSyncAlarmNotifyEvent *aevent = (XSyncAlarmNotifyEvent*) event;
-
- name = "XSyncAlarmNotify";
- extra =
- g_strdup_printf ("alarm: 0x%lx"
- " counter_value: %" G_GINT64_FORMAT
- " alarm_value: %" G_GINT64_FORMAT
- " time: %u alarm state: %s",
- aevent->alarm,
- (gint64) sync_value_to_64 (&aevent->counter_value),
- (gint64) sync_value_to_64 (&aevent->alarm_value),
- (unsigned int)aevent->time,
- alarm_state_to_string (aevent->state));
- }
- else
-#endif /* HAVE_XSYNC */
-#ifdef HAVE_SHAPE
- if (META_DISPLAY_HAS_SHAPE (display) &&
- event->type == (display->shape_event_base + ShapeNotify))
- {
- XShapeEvent *sev = (XShapeEvent*) event;
-
- name = "ShapeNotify";
-
- extra =
- g_strdup_printf ("kind: %s "
- "x: %d y: %d w: %u h: %u "
- "shaped: %d",
- sev->kind == ShapeBounding ?
- "ShapeBounding" :
- (sev->kind == ShapeClip ?
- "ShapeClip" : "(unknown)"),
- sev->x, sev->y, sev->width, sev->height,
- sev->shaped);
- }
- else
-#endif /* HAVE_SHAPE */
- {
- name = "(Unknown event)";
- extra = g_strdup_printf ("type: %d", event->xany.type);
- }
- break;
- }
-
- screen = meta_display_screen_for_root (display, event->xany.window);
-
- if (screen)
- winname = g_strdup_printf ("root %d", screen->number);
- else
- winname = g_strdup_printf ("0x%lx", event->xany.window);
-
- meta_topic (META_DEBUG_EVENTS,
- "%s on %s%s %s %sserial %lu\n", name, winname,
- extra ? ":" : "", extra ? extra : "",
- event->xany.send_event ? "SEND " : "",
- event->xany.serial);
-
- g_free (winname);
-
- if (extra)
- g_free (extra);
-}
-#endif /* WITH_VERBOSE_MODE */
-
-MetaWindow*
-meta_display_lookup_x_window (MetaDisplay *display,
- Window xwindow)
-{
- return g_hash_table_lookup (display->window_ids, &xwindow);
-}
-
-void
-meta_display_register_x_window (MetaDisplay *display,
- Window *xwindowp,
- MetaWindow *window)
-{
- g_return_if_fail (g_hash_table_lookup (display->window_ids, xwindowp) == NULL);
-
- g_hash_table_insert (display->window_ids, xwindowp, window);
-}
-
-void
-meta_display_unregister_x_window (MetaDisplay *display,
- Window xwindow)
-{
- g_return_if_fail (g_hash_table_lookup (display->window_ids, &xwindow) != NULL);
-
- g_hash_table_remove (display->window_ids, &xwindow);
-
- /* Remove any pending pings */
- remove_pending_pings_for_window (display, xwindow);
-}
-
-gboolean
-meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display,
- Window xwindow)
-{
- gboolean is_a_no_focus_window = FALSE;
- GSList *temp = display->screens;
- while (temp != NULL) {
- MetaScreen *screen = temp->data;
- if (screen->no_focus_window == xwindow) {
- is_a_no_focus_window = TRUE;
- break;
- }
- temp = temp->next;
- }
-
- return is_a_no_focus_window;
-}
-
-Cursor
-meta_display_create_x_cursor (MetaDisplay *display,
- MetaCursor cursor)
-{
- Cursor xcursor;
- guint glyph;
-
- switch (cursor)
- {
- case META_CURSOR_DEFAULT:
- glyph = XC_left_ptr;
- break;
- case META_CURSOR_NORTH_RESIZE:
- glyph = XC_top_side;
- break;
- case META_CURSOR_SOUTH_RESIZE:
- glyph = XC_bottom_side;
- break;
- case META_CURSOR_WEST_RESIZE:
- glyph = XC_left_side;
- break;
- case META_CURSOR_EAST_RESIZE:
- glyph = XC_right_side;
- break;
- case META_CURSOR_SE_RESIZE:
- glyph = XC_bottom_right_corner;
- break;
- case META_CURSOR_SW_RESIZE:
- glyph = XC_bottom_left_corner;
- break;
- case META_CURSOR_NE_RESIZE:
- glyph = XC_top_right_corner;
- break;
- case META_CURSOR_NW_RESIZE:
- glyph = XC_top_left_corner;
- break;
- case META_CURSOR_MOVE_OR_RESIZE_WINDOW:
- glyph = XC_fleur;
- break;
- case META_CURSOR_BUSY:
- glyph = XC_watch;
- break;
-
- default:
- g_assert_not_reached ();
- glyph = 0; /* silence compiler */
- break;
- }
-
- xcursor = XCreateFontCursor (display->xdisplay, glyph);
-
- return xcursor;
-}
-
-static Cursor
-xcursor_for_op (MetaDisplay *display,
- MetaGrabOp op)
-{
- MetaCursor cursor = META_CURSOR_DEFAULT;
-
- switch (op)
- {
- case META_GRAB_OP_RESIZING_SE:
- case META_GRAB_OP_KEYBOARD_RESIZING_SE:
- cursor = META_CURSOR_SE_RESIZE;
- break;
- case META_GRAB_OP_RESIZING_S:
- case META_GRAB_OP_KEYBOARD_RESIZING_S:
- cursor = META_CURSOR_SOUTH_RESIZE;
- break;
- case META_GRAB_OP_RESIZING_SW:
- case META_GRAB_OP_KEYBOARD_RESIZING_SW:
- cursor = META_CURSOR_SW_RESIZE;
- break;
- case META_GRAB_OP_RESIZING_N:
- case META_GRAB_OP_KEYBOARD_RESIZING_N:
- cursor = META_CURSOR_NORTH_RESIZE;
- break;
- case META_GRAB_OP_RESIZING_NE:
- case META_GRAB_OP_KEYBOARD_RESIZING_NE:
- cursor = META_CURSOR_NE_RESIZE;
- break;
- case META_GRAB_OP_RESIZING_NW:
- case META_GRAB_OP_KEYBOARD_RESIZING_NW:
- cursor = META_CURSOR_NW_RESIZE;
- break;
- case META_GRAB_OP_RESIZING_W:
- case META_GRAB_OP_KEYBOARD_RESIZING_W:
- cursor = META_CURSOR_WEST_RESIZE;
- break;
- case META_GRAB_OP_RESIZING_E:
- case META_GRAB_OP_KEYBOARD_RESIZING_E:
- cursor = META_CURSOR_EAST_RESIZE;
- break;
- case META_GRAB_OP_MOVING:
- case META_GRAB_OP_KEYBOARD_MOVING:
- case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
- cursor = META_CURSOR_MOVE_OR_RESIZE_WINDOW;
- break;
-
- default:
- break;
- }
-
- if (cursor == META_CURSOR_DEFAULT)
- return None;
- return meta_display_create_x_cursor (display, cursor);
-}
-
-void
-meta_display_set_grab_op_cursor (MetaDisplay *display,
- MetaScreen *screen,
- MetaGrabOp op,
- gboolean change_pointer,
- Window grab_xwindow,
- guint32 timestamp)
-{
- Cursor cursor;
-
- cursor = xcursor_for_op (display, op);
-
-#define GRAB_MASK (PointerMotionMask | \
- ButtonPressMask | ButtonReleaseMask | \
- EnterWindowMask | LeaveWindowMask)
-
- if (change_pointer)
- {
- meta_error_trap_push_with_return (display);
- XChangeActivePointerGrab (display->xdisplay,
- GRAB_MASK,
- cursor,
- timestamp);
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Changed pointer with XChangeActivePointerGrab()\n");
-
- if (meta_error_trap_pop_with_return (display, FALSE) != Success)
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Error trapped from XChangeActivePointerGrab()\n");
- if (display->grab_have_pointer)
- display->grab_have_pointer = FALSE;
- }
- }
- else
- {
- g_assert (screen != NULL);
-
- meta_error_trap_push (display);
- if (XGrabPointer (display->xdisplay,
- grab_xwindow,
- False,
- GRAB_MASK,
- GrabModeAsync, GrabModeAsync,
- screen->xroot,
- cursor,
- timestamp) == GrabSuccess)
- {
- display->grab_have_pointer = TRUE;
- meta_topic (META_DEBUG_WINDOW_OPS,
- "XGrabPointer() returned GrabSuccess time %u\n",
- timestamp);
- }
- else
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "XGrabPointer() failed time %u\n",
- timestamp);
- }
- meta_error_trap_pop (display, TRUE);
- }
-
-#undef GRAB_MASK
-
- if (cursor != None)
- XFreeCursor (display->xdisplay, cursor);
-}
-
-gboolean
-meta_display_begin_grab_op (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- MetaGrabOp op,
- gboolean pointer_already_grabbed,
- gboolean frame_action,
- int button,
- gulong modmask,
- guint32 timestamp,
- int root_x,
- int root_y)
-{
- Window grab_xwindow;
-
- if (grab_op_is_mouse (op) && meta_grab_op_is_moving (op))
- {
- if (display->compositor)
- {
- meta_compositor_begin_move (display->compositor,
- window, &window->rect,
- root_x, root_y);
- }
- }
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Doing grab op %u on window %s button %d pointer already grabbed: %d pointer pos %d,%d\n",
- op, window ? window->desc : "none", button, pointer_already_grabbed,
- root_x, root_y);
-
- if (display->grab_op != META_GRAB_OP_NONE)
- {
- if (window)
- meta_warning ("Attempt to perform window operation %u on window %s when operation %u on %s already in effect\n",
- op, window->desc, display->grab_op,
- display->grab_window ? display->grab_window->desc : "none");
- return FALSE;
- }
-
- if (window &&
- (meta_grab_op_is_moving (op) || meta_grab_op_is_resizing (op)))
- {
- if (meta_prefs_get_raise_on_click ())
- meta_window_raise (window);
- else
- {
- display->grab_initial_x = root_x;
- display->grab_initial_y = root_y;
- display->grab_threshold_movement_reached = FALSE;
- }
- }
-
- /* FIXME:
- * If we have no MetaWindow we do our best
- * and try to do the grab on the RootWindow.
- * This will fail if anyone else has any
- * key grab on the RootWindow.
- */
- if (window)
- grab_xwindow = window->frame ? window->frame->xwindow : window->xwindow;
- else
- grab_xwindow = screen->xroot;
-
- display->grab_have_pointer = FALSE;
-
- if (pointer_already_grabbed)
- display->grab_have_pointer = TRUE;
-
- meta_display_set_grab_op_cursor (display, screen, op, FALSE, grab_xwindow,
- timestamp);
-
- if (!display->grab_have_pointer)
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "XGrabPointer() failed\n");
- return FALSE;
- }
-
- /* Grab keys for keyboard ops and mouse move/resizes; see #126497 */
- if (grab_op_is_keyboard (op) || grab_op_is_mouse_only (op))
- {
- if (window)
- display->grab_have_keyboard =
- meta_window_grab_all_keys (window, timestamp);
-
- else
- display->grab_have_keyboard =
- meta_screen_grab_all_keys (screen, timestamp);
-
- if (!display->grab_have_keyboard)
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "grabbing all keys failed, ungrabbing pointer\n");
- XUngrabPointer (display->xdisplay, timestamp);
- display->grab_have_pointer = FALSE;
- return FALSE;
- }
- }
-
- display->grab_op = op;
- display->grab_window = window;
- display->grab_screen = screen;
- display->grab_xwindow = grab_xwindow;
- display->grab_button = button;
- display->grab_mask = modmask;
- display->grab_anchor_root_x = root_x;
- display->grab_anchor_root_y = root_y;
- display->grab_latest_motion_x = root_x;
- display->grab_latest_motion_y = root_y;
- display->grab_last_moveresize_time.tv_sec = 0;
- display->grab_last_moveresize_time.tv_usec = 0;
- display->grab_motion_notify_time = 0;
- display->grab_old_window_stacking = NULL;
-#ifdef HAVE_XSYNC
- display->grab_sync_request_alarm = None;
- display->grab_last_user_action_was_snap = FALSE;
-#endif
- display->grab_was_cancelled = FALSE;
- display->grab_frame_action = frame_action;
-
- if (display->grab_resize_timeout_id)
- {
- g_source_remove (display->grab_resize_timeout_id);
- display->grab_resize_timeout_id = 0;
- }
-
- if (display->grab_window)
- {
- meta_window_get_client_root_coords (display->grab_window,
- &display->grab_initial_window_pos);
- display->grab_anchor_window_pos = display->grab_initial_window_pos;
-
- display->grab_wireframe_active =
- (meta_prefs_get_reduced_resources () && !meta_prefs_get_gnome_accessibility ()) &&
- (meta_grab_op_is_resizing (display->grab_op) ||
- meta_grab_op_is_moving (display->grab_op));
-
- if (display->grab_wireframe_active)
- {
- meta_window_calc_showing (display->grab_window);
- meta_window_begin_wireframe (window);
- }
-
-#ifdef HAVE_XSYNC
- if (!display->grab_wireframe_active &&
- meta_grab_op_is_resizing (display->grab_op) &&
- display->grab_window->sync_request_counter != None)
- {
- XSyncAlarmAttributes values;
- XSyncValue init;
-
- meta_error_trap_push_with_return (display);
-
- /* Set the counter to 0, so we know that the application's
- * responses to the client messages will always trigger
- * a PositiveTransition
- */
-
- XSyncIntToValue (&init, 0);
- XSyncSetCounter (display->xdisplay,
- display->grab_window->sync_request_counter, init);
-
- display->grab_window->sync_request_serial = 0;
- display->grab_window->sync_request_time.tv_sec = 0;
- display->grab_window->sync_request_time.tv_usec = 0;
-
- values.trigger.counter = display->grab_window->sync_request_counter;
- values.trigger.value_type = XSyncAbsolute;
- values.trigger.test_type = XSyncPositiveTransition;
- XSyncIntToValue (&values.trigger.wait_value,
- display->grab_window->sync_request_serial + 1);
-
- /* After triggering, increment test_value by this.
- * (NOT wait_value above)
- */
- XSyncIntToValue (&values.delta, 1);
-
- /* we want events (on by default anyway) */
- values.events = True;
-
- display->grab_sync_request_alarm = XSyncCreateAlarm (display->xdisplay,
- XSyncCACounter |
- XSyncCAValueType |
- XSyncCAValue |
- XSyncCATestType |
- XSyncCADelta |
- XSyncCAEvents,
- &values);
-
- if (meta_error_trap_pop_with_return (display, FALSE) != Success)
- display->grab_sync_request_alarm = None;
-
- meta_topic (META_DEBUG_RESIZING,
- "Created update alarm 0x%lx\n",
- display->grab_sync_request_alarm);
- }
-#endif
- }
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Grab op %u on window %s successful\n",
- display->grab_op, window ? window->desc : "(null)");
-
- g_assert (display->grab_window != NULL || display->grab_screen != NULL);
- g_assert (display->grab_op != META_GRAB_OP_NONE);
-
- /* If this is a move or resize, cache the window edges for
- * resistance/snapping
- */
- if (meta_grab_op_is_resizing (display->grab_op) ||
- meta_grab_op_is_moving (display->grab_op))
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Computing edges to resist-movement or snap-to for %s.\n",
- window->desc);
- meta_display_compute_resistance_and_snapping_edges (display);
- }
-
- /* Save the old stacking */
- if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op))
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Saving old stack positions; old pointer was %p.\n",
- display->grab_old_window_stacking);
- display->grab_old_window_stacking =
- meta_stack_get_positions (screen->stack);
- }
-
- /* Do this last, after everything is set up. */
- switch (op)
- {
- case META_GRAB_OP_KEYBOARD_TABBING_NORMAL:
- meta_screen_ensure_tab_popup (screen,
- META_TAB_LIST_NORMAL,
- META_TAB_SHOW_ICON);
- break;
- case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL:
- meta_screen_ensure_tab_popup (screen,
- META_TAB_LIST_NORMAL,
- META_TAB_SHOW_INSTANTLY);
- break;
-
- case META_GRAB_OP_KEYBOARD_TABBING_DOCK:
- meta_screen_ensure_tab_popup (screen,
- META_TAB_LIST_DOCKS,
- META_TAB_SHOW_ICON);
- break;
- case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK:
- meta_screen_ensure_tab_popup (screen,
- META_TAB_LIST_DOCKS,
- META_TAB_SHOW_INSTANTLY);
- break;
- case META_GRAB_OP_KEYBOARD_TABBING_GROUP:
- meta_screen_ensure_tab_popup (screen,
- META_TAB_LIST_GROUP,
- META_TAB_SHOW_ICON);
- break;
- case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP:
- meta_screen_ensure_tab_popup (screen,
- META_TAB_LIST_GROUP,
- META_TAB_SHOW_INSTANTLY);
-
- case META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING:
- meta_screen_ensure_workspace_popup (screen);
- break;
-
- default:
- break;
- }
-
- if (display->grab_window)
- {
- meta_window_refresh_resize_popup (display->grab_window);
- }
-
- return TRUE;
-}
-
-void
-meta_display_end_grab_op (MetaDisplay *display,
- guint32 timestamp)
-{
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Ending grab op %u at time %u\n", display->grab_op, timestamp);
-
- if (display->grab_op == META_GRAB_OP_NONE)
- return;
-
- if (display->grab_window != NULL)
- display->grab_window->shaken_loose = FALSE;
-
- if (display->grab_window != NULL &&
- !meta_prefs_get_raise_on_click () &&
- (meta_grab_op_is_moving (display->grab_op) ||
- meta_grab_op_is_resizing (display->grab_op)))
- {
- /* Only raise the window in orthogonal raise
- * ('do-not-raise-on-click') mode if the user didn't try to move
- * or resize the given window by at least a threshold amount.
- * For raise on click mode, the window was raised at the
- * beginning of the grab_op.
- */
- if (!display->grab_threshold_movement_reached)
- meta_window_raise (display->grab_window);
- }
-
- if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op) ||
- display->grab_op == META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING)
- {
- meta_ui_tab_popup_free (display->grab_screen->tab_popup);
- display->grab_screen->tab_popup = NULL;
-
- /* If the ungrab here causes an EnterNotify, ignore it for
- * sloppy focus
- */
- display->ungrab_should_not_cause_focus_window = display->grab_xwindow;
- }
-
- /* If this was a move or resize clear out the edge cache */
- if (meta_grab_op_is_resizing (display->grab_op) ||
- meta_grab_op_is_moving (display->grab_op))
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Clearing out the edges for resistance/snapping");
- meta_display_cleanup_edges (display);
- }
-
- if (display->grab_old_window_stacking != NULL)
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Clearing out the old stack position, which was %p.\n",
- display->grab_old_window_stacking);
- g_list_free (display->grab_old_window_stacking);
- display->grab_old_window_stacking = NULL;
- }
-
- if (display->grab_wireframe_active)
- {
- display->grab_wireframe_active = FALSE;
- meta_window_end_wireframe (display->grab_window);
-
- if (!display->grab_was_cancelled)
- {
- if (meta_grab_op_is_moving (display->grab_op))
- meta_window_move (display->grab_window,
- TRUE,
- display->grab_wireframe_rect.x,
- display->grab_wireframe_rect.y);
- if (meta_grab_op_is_resizing (display->grab_op))
- meta_window_resize_with_gravity (display->grab_window,
- TRUE,
- display->grab_wireframe_rect.width,
- display->grab_wireframe_rect.height,
- meta_resize_gravity_from_grab_op (display->grab_op));
- }
- meta_window_calc_showing (display->grab_window);
- }
-
- if (display->compositor &&
- display->grab_window &&
- grab_op_is_mouse (display->grab_op) &&
- meta_grab_op_is_moving (display->grab_op))
- {
- meta_compositor_end_move (display->compositor,
- display->grab_window);
- }
-
- if (display->grab_have_pointer)
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Ungrabbing pointer with timestamp %u\n", timestamp);
- XUngrabPointer (display->xdisplay, timestamp);
- }
-
- if (display->grab_have_keyboard)
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Ungrabbing all keys timestamp %u\n", timestamp);
- if (display->grab_window)
- meta_window_ungrab_all_keys (display->grab_window, timestamp);
- else
- meta_screen_ungrab_all_keys (display->grab_screen, timestamp);
- }
-
-#ifdef HAVE_XSYNC
- if (display->grab_sync_request_alarm != None)
- {
- XSyncDestroyAlarm (display->xdisplay,
- display->grab_sync_request_alarm);
- display->grab_sync_request_alarm = None;
- }
-#endif /* HAVE_XSYNC */
-
- display->grab_window = NULL;
- display->grab_screen = NULL;
- display->grab_xwindow = None;
- display->grab_op = META_GRAB_OP_NONE;
-
- if (display->grab_resize_popup)
- {
- meta_ui_resize_popup_free (display->grab_resize_popup);
- display->grab_resize_popup = NULL;
- }
-
- if (display->grab_resize_timeout_id)
- {
- g_source_remove (display->grab_resize_timeout_id);
- display->grab_resize_timeout_id = 0;
- }
-}
-
-void
-meta_display_check_threshold_reached (MetaDisplay *display,
- int x,
- int y)
-{
- /* Don't bother doing the check again if we've already reached the threshold */
- if (meta_prefs_get_raise_on_click () ||
- display->grab_threshold_movement_reached)
- return;
-
- if (ABS (display->grab_initial_x - x) >= 8 ||
- ABS (display->grab_initial_y - y) >= 8)
- display->grab_threshold_movement_reached = TRUE;
-}
-
-static void
-meta_change_button_grab (MetaDisplay *display,
- Window xwindow,
- gboolean grab,
- gboolean sync,
- int button,
- int modmask)
-{
- unsigned int ignored_mask;
-
- meta_verbose ("%s 0x%lx sync = %d button = %d modmask 0x%x\n",
- grab ? "Grabbing" : "Ungrabbing",
- xwindow,
- sync, button, modmask);
-
- meta_error_trap_push (display);
-
- ignored_mask = 0;
- while (ignored_mask <= display->ignored_modifier_mask)
- {
- if (ignored_mask & ~(display->ignored_modifier_mask))
- {
- /* Not a combination of ignored modifiers
- * (it contains some non-ignored modifiers)
- */
- ++ignored_mask;
- continue;
- }
-
- if (meta_is_debugging ())
- meta_error_trap_push_with_return (display);
-
- /* GrabModeSync means freeze until XAllowEvents */
-
- if (grab)
- XGrabButton (display->xdisplay, button, modmask | ignored_mask,
- xwindow, False,
- ButtonPressMask | ButtonReleaseMask |
- PointerMotionMask | PointerMotionHintMask,
- sync ? GrabModeSync : GrabModeAsync,
- GrabModeAsync,
- False, None);
- else
- XUngrabButton (display->xdisplay, button, modmask | ignored_mask,
- xwindow);
-
- if (meta_is_debugging ())
- {
- int result;
-
- result = meta_error_trap_pop_with_return (display, FALSE);
-
- if (result != Success)
- meta_verbose ("Failed to %s button %d with mask 0x%x for window 0x%lx error code %d\n",
- grab ? "grab" : "ungrab",
- button, modmask | ignored_mask, xwindow, result);
- }
-
- ++ignored_mask;
- }
-
- meta_error_trap_pop (display, FALSE);
-}
-
-void
-meta_display_grab_window_buttons (MetaDisplay *display,
- Window xwindow)
-{
- /* Grab Alt + button1 for moving window.
- * Grab Alt + button2 for resizing window.
- * Grab Alt + button3 for popping up window menu.
- * Grab Alt + Shift + button1 for snap-moving window.
- */
- meta_verbose ("Grabbing window buttons for 0x%lx\n", xwindow);
-
- /* FIXME If we ignored errors here instead of spewing, we could
- * put one big error trap around the loop and avoid a bunch of
- * XSync()
- */
-
- if (display->window_grab_modifiers != 0)
- {
- gboolean debug = g_getenv ("METACITY_DEBUG_BUTTON_GRABS") != NULL;
- int i;
- for (i = 1; i < 4; i++)
- {
- meta_change_button_grab (display, xwindow,
- TRUE,
- FALSE,
- i, display->window_grab_modifiers);
-
- /* This is for debugging, since I end up moving the Xnest
- * otherwise ;-)
- */
- if (debug)
- meta_change_button_grab (display, xwindow,
- TRUE,
- FALSE,
- i, ControlMask);
- }
-
- /* In addition to grabbing Alt+Button1 for moving the window,
- * grab Alt+Shift+Button1 for snap-moving the window. See bug
- * 112478. Unfortunately, this doesn't work with
- * Shift+Alt+Button1 for some reason; so at least part of the
- * order still matters, which sucks (please FIXME).
- */
- meta_change_button_grab (display, xwindow,
- TRUE,
- FALSE,
- 1, display->window_grab_modifiers | ShiftMask);
- }
-}
-
-void
-meta_display_ungrab_window_buttons (MetaDisplay *display,
- Window xwindow)
-{
- gboolean debug;
- int i;
-
- if (display->window_grab_modifiers == 0)
- return;
-
- debug = g_getenv ("METACITY_DEBUG_BUTTON_GRABS") != NULL;
- i = 1;
- while (i < 4)
- {
- meta_change_button_grab (display, xwindow,
- FALSE, FALSE, i,
- display->window_grab_modifiers);
-
- if (debug)
- meta_change_button_grab (display, xwindow,
- FALSE, FALSE, i, ControlMask);
-
- ++i;
- }
-}
-
-/* Grab buttons we only grab while unfocused in click-to-focus mode */
-#define MAX_FOCUS_BUTTON 4
-void
-meta_display_grab_focus_window_button (MetaDisplay *display,
- MetaWindow *window)
-{
- /* Grab button 1 for activating unfocused windows */
- meta_verbose ("Grabbing unfocused window buttons for %s\n", window->desc);
-
-#if 0
- /* FIXME:115072 */
- /* Don't grab at all unless in click to focus mode. In click to
- * focus, we may sometimes be clever about intercepting and eating
- * the focus click. But in mouse focus, we never do that since the
- * focus window may not be raised, and who wants to think about
- * mouse focus anyway.
- */
- if (meta_prefs_get_focus_mode () != META_FOCUS_MODE_CLICK)
- {
- meta_verbose (" (well, not grabbing since not in click to focus mode)\n");
- return;
- }
-#endif
-
- if (window->have_focus_click_grab)
- {
- meta_verbose (" (well, not grabbing since we already have the grab)\n");
- return;
- }
-
- /* FIXME If we ignored errors here instead of spewing, we could
- * put one big error trap around the loop and avoid a bunch of
- * XSync()
- */
-
- {
- int i = 1;
- while (i < MAX_FOCUS_BUTTON)
- {
- meta_change_button_grab (display,
- window->xwindow,
- TRUE, TRUE,
- i, 0);
-
- ++i;
- }
-
- window->have_focus_click_grab = TRUE;
- }
-}
-
-void
-meta_display_ungrab_focus_window_button (MetaDisplay *display,
- MetaWindow *window)
-{
- meta_verbose ("Ungrabbing unfocused window buttons for %s\n", window->desc);
-
- if (!window->have_focus_click_grab)
- return;
-
- {
- int i = 1;
- while (i < MAX_FOCUS_BUTTON)
- {
- meta_change_button_grab (display, window->xwindow,
- FALSE, FALSE, i, 0);
-
- ++i;
- }
-
- window->have_focus_click_grab = FALSE;
- }
-}
-
-void
-meta_display_increment_event_serial (MetaDisplay *display)
-{
- /* We just make some random X request */
- XDeleteProperty (display->xdisplay, display->leader_window,
- display->atom__MOTIF_WM_HINTS);
-}
-
-void
-meta_display_update_active_window_hint (MetaDisplay *display)
-{
- GSList *tmp;
-
- gulong data[1];
-
- if (display->focus_window)
- data[0] = display->focus_window->xwindow;
- else
- data[0] = None;
-
- tmp = display->screens;
- while (tmp != NULL)
- {
- MetaScreen *screen = tmp->data;
-
- meta_error_trap_push (display);
- XChangeProperty (display->xdisplay, screen->xroot,
- display->atom__NET_ACTIVE_WINDOW,
- XA_WINDOW,
- 32, PropModeReplace, (guchar*) data, 1);
-
- meta_error_trap_pop (display, FALSE);
-
- tmp = tmp->next;
- }
-}
-
-void
-meta_display_queue_retheme_all_windows (MetaDisplay *display)
-{
- GSList* windows;
- GSList *tmp;
-
- windows = meta_display_list_windows (display);
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *window = tmp->data;
-
- meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
- if (window->frame)
- {
- window->frame->need_reapply_frame_shape = TRUE;
-
- meta_frame_queue_draw (window->frame);
- }
-
- tmp = tmp->next;
- }
-
- g_slist_free (windows);
-}
-
-void
-meta_display_retheme_all (void)
-{
- meta_display_queue_retheme_all_windows (meta_get_display ());
-}
-
-void
-meta_display_set_cursor_theme (const char *theme,
- int size)
-{
-#ifdef HAVE_XCURSOR
- GSList *tmp;
-
- MetaDisplay *display = meta_get_display ();
-
- XcursorSetTheme (display->xdisplay, theme);
- XcursorSetDefaultSize (display->xdisplay, size);
-
- tmp = display->screens;
- while (tmp != NULL)
- {
- MetaScreen *screen = tmp->data;
-
- meta_screen_update_cursor (screen);
-
- tmp = tmp->next;
- }
-
-#endif
-}
-
-/**
- * Stores whether syncing is currently enabled.
- */
-static gboolean is_syncing = FALSE;
-
-/**
- * Returns whether X synchronisation is currently enabled.
- *
- * \return true if we must wait for events whenever we send X requests;
- * false otherwise.
- *
- * \bug This is *only* called by meta_display_open, but by that time
- * we have already turned syncing on or off on startup, and we don't
- * have any way to do so while Metacity is running, so it's rather
- * pointless.
- */
-gboolean
-meta_is_syncing (void)
-{
- return is_syncing;
-}
-
-/**
- * A handy way to turn on synchronisation on or off for every display.
- *
- * \bug Of course there is only one display ever anyway, so this can
- * be rather hugely simplified.
- */
-void
-meta_set_syncing (gboolean setting)
-{
- if (setting != is_syncing)
- {
- is_syncing = setting;
-
- XSynchronize (meta_get_display ()->xdisplay, is_syncing);
- }
-}
-
-/**
- * How long, in milliseconds, we should wait after pinging a window
- * before deciding it's not going to get back to us.
- */
-#define PING_TIMEOUT_DELAY 2250
-
-/**
- * Does whatever it is we decided to do when a window didn't respond
- * to a ping. We also remove the ping from the display's list of
- * pending pings. This function is called by the event loop when the timeout
- * times out which we created at the start of the ping.
- *
- * \param data All the information about this ping. It is a MetaPingData
- * cast to a void* in order to be passable to a timeout function.
- * This function will also free this parameter.
- *
- * \return Always returns false, because this function is called as a
- * timeout and we don't want to run the timer again.
- *
- * \ingroup pings
- */
-static gboolean
-meta_display_ping_timeout (gpointer data)
-{
- MetaPingData *ping_data;
-
- ping_data = data;
-
- ping_data->ping_timeout_id = 0;
-
- meta_topic (META_DEBUG_PING,
- "Ping %u on window %lx timed out\n",
- ping_data->timestamp, ping_data->xwindow);
-
- (* ping_data->ping_timeout_func) (ping_data->display, ping_data->xwindow,
- ping_data->timestamp, ping_data->user_data);
-
- ping_data->display->pending_pings =
- g_slist_remove (ping_data->display->pending_pings,
- ping_data);
- ping_data_free (ping_data);
-
- return FALSE;
-}
-
-/**
- * Sends a ping request to a window. The window must respond to
- * the request within a certain amount of time. If it does, we
- * will call one callback; if the time passes and we haven't had
- * a response, we call a different callback. The window must have
- * the hint showing that it can respond to a ping; if it doesn't,
- * we call the "got a response" callback immediately and return.
- * This function returns straight away after setting things up;
- * the callbacks will be called from the event loop.
- *
- * \param display The MetaDisplay that the window is on
- * \param window The MetaWindow to send the ping to
- * \param timestamp The timestamp of the ping. Used for uniqueness.
- * Cannot be CurrentTime; use a real timestamp!
- * \param ping_reply_func The callback to call if we get a response.
- * \param ping_timeout_func The callback to call if we don't get a response.
- * \param user_data Arbitrary data that will be passed to the callback
- * function. (In practice it's often a pointer to
- * the window.)
- *
- * \bug This should probably be a method on windows, rather than displays
- * for one of their windows.
- *
- * \ingroup pings
- */
-void
-meta_display_ping_window (MetaDisplay *display,
- MetaWindow *window,
- guint32 timestamp,
- MetaWindowPingFunc ping_reply_func,
- MetaWindowPingFunc ping_timeout_func,
- gpointer user_data)
-{
- MetaPingData *ping_data;
-
- if (timestamp == CurrentTime)
- {
- meta_warning ("Tried to ping a window with CurrentTime! Not allowed.\n");
- return;
- }
-
- if (!window->net_wm_ping)
- {
- if (ping_reply_func)
- (* ping_reply_func) (display, window->xwindow, timestamp, user_data);
-
- return;
- }
-
- ping_data = g_new (MetaPingData, 1);
- ping_data->display = display;
- ping_data->xwindow = window->xwindow;
- ping_data->timestamp = timestamp;
- ping_data->ping_reply_func = ping_reply_func;
- ping_data->ping_timeout_func = ping_timeout_func;
- ping_data->user_data = user_data;
- ping_data->ping_timeout_id = g_timeout_add (PING_TIMEOUT_DELAY,
- meta_display_ping_timeout,
- ping_data);
-
- display->pending_pings = g_slist_prepend (display->pending_pings, ping_data);
-
- meta_topic (META_DEBUG_PING,
- "Sending ping with timestamp %u to window %s\n",
- timestamp, window->desc);
- meta_window_send_icccm_message (window,
- display->atom__NET_WM_PING,
- timestamp);
-}
-
-static void
-process_request_frame_extents (MetaDisplay *display,
- XEvent *event)
-{
- /* The X window whose frame extents will be set. */
- Window xwindow = event->xclient.window;
- unsigned long data[4] = { 0, 0, 0, 0 };
-
- MotifWmHints *hints = NULL;
- gboolean hints_set = FALSE;
-
- meta_verbose ("Setting frame extents for 0x%lx\n", xwindow);
-
- /* See if the window is decorated. */
- hints_set = meta_prop_get_motif_hints (display,
- xwindow,
- display->atom__MOTIF_WM_HINTS,
- &hints);
- if ((hints_set && hints->decorations) || !hints_set)
- {
- int top = 0;
- int bottom = 0;
- int left = 0;
- int right = 0;
-
- MetaScreen *screen;
-
- screen = meta_display_screen_for_xwindow (display,
- event->xclient.window);
- if (screen == NULL)
- {
- meta_warning ("Received request to set _NET_FRAME_EXTENTS "
- "on 0x%lx which is on a screen we are not managing\n",
- event->xclient.window);
- meta_XFree (hints);
- return;
- }
-
- /* Return estimated frame extents for a normal window. */
- meta_ui_theme_get_frame_borders (screen->ui,
- META_FRAME_TYPE_NORMAL,
- 0,
- &top,
- &bottom,
- &left,
- &right);
-
- data[0] = left;
- data[1] = right;
- data[2] = top;
- data[3] = bottom;
- }
-
- meta_topic (META_DEBUG_GEOMETRY,
- "Setting _NET_FRAME_EXTENTS on unmanaged window 0x%lx "
- "to top = %lu, left = %lu, bottom = %lu, right = %lu\n",
- xwindow, data[0], data[1], data[2], data[3]);
-
- meta_error_trap_push (display);
- XChangeProperty (display->xdisplay, xwindow,
- display->atom__NET_FRAME_EXTENTS,
- XA_CARDINAL,
- 32, PropModeReplace, (guchar*) data, 4);
- meta_error_trap_pop (display, FALSE);
-
- meta_XFree (hints);
-}
-
-/**
- * Process the pong (the response message) from the ping we sent
- * to the window. This involves removing the timeout, calling the
- * reply handler function, and freeing memory.
- *
- * \param display the display we got the pong from
- * \param event the XEvent which is a pong; we can tell which
- * ping it corresponds to because it bears the
- * same timestamp.
- *
- * \ingroup pings
- */
-static void
-process_pong_message (MetaDisplay *display,
- XEvent *event)
-{
- GSList *tmp;
- guint32 timestamp = event->xclient.data.l[1];
-
- meta_topic (META_DEBUG_PING, "Received a pong with timestamp %u\n",
- timestamp);
-
- for (tmp = display->pending_pings; tmp; tmp = tmp->next)
- {
- MetaPingData *ping_data = tmp->data;
-
- if (timestamp == ping_data->timestamp)
- {
- meta_topic (META_DEBUG_PING,
- "Matching ping found for pong %u\n",
- ping_data->timestamp);
-
- /* Remove the ping data from the list */
- display->pending_pings = g_slist_remove (display->pending_pings,
- ping_data);
-
- /* Remove the timeout */
- if (ping_data->ping_timeout_id != 0)
- {
- g_source_remove (ping_data->ping_timeout_id);
- ping_data->ping_timeout_id = 0;
- }
-
- /* Call callback */
- (* ping_data->ping_reply_func) (display,
- ping_data->xwindow,
- ping_data->timestamp,
- ping_data->user_data);
-
- ping_data_free (ping_data);
-
- break;
- }
- }
-}
-
-/**
- * Finds whether a window has any pings waiting on it.
- *
- * \param display The MetaDisplay of the window.
- * \param window The MetaWindow whose pings we want to know about.
- *
- * \return True if there is at least one ping which has been sent
- * to the window without getting a response; false otherwise.
- *
- * \bug This should probably be a method on windows, rather than displays
- * for one of their windows.
- *
- * \ingroup pings
- */
-gboolean
-meta_display_window_has_pending_pings (MetaDisplay *display,
- MetaWindow *window)
-{
- GSList *tmp;
-
- for (tmp = display->pending_pings; tmp; tmp = tmp->next)
- {
- MetaPingData *ping_data = tmp->data;
-
- if (ping_data->xwindow == window->xwindow)
- return TRUE;
- }
-
- return FALSE;
-}
-
-MetaGroup*
-get_focussed_group (MetaDisplay *display)
-{
- if (display->focus_window)
- return display->focus_window->group;
- else
- return NULL;
-}
-
-#define IN_TAB_CHAIN(w,t) (((t) == META_TAB_LIST_NORMAL && META_WINDOW_IN_NORMAL_TAB_CHAIN (w)) \
- || ((t) == META_TAB_LIST_DOCKS && META_WINDOW_IN_DOCK_TAB_CHAIN (w)) \
- || ((t) == META_TAB_LIST_GROUP && META_WINDOW_IN_GROUP_TAB_CHAIN (w, get_focussed_group(w->display))))
-
-static MetaWindow*
-find_tab_forward (MetaDisplay *display,
- MetaTabList type,
- MetaScreen *screen,
- MetaWorkspace *workspace,
- GList *start,
- gboolean skip_first)
-{
- GList *tmp;
-
- g_return_val_if_fail (start != NULL, NULL);
- g_return_val_if_fail (workspace != NULL, NULL);
-
- tmp = start;
- if (skip_first)
- tmp = tmp->next;
-
- while (tmp != NULL)
- {
- MetaWindow *window = tmp->data;
-
- if (window->screen == screen &&
- IN_TAB_CHAIN (window, type))
- return window;
-
- tmp = tmp->next;
- }
-
- tmp = workspace->mru_list;
- while (tmp != start)
- {
- MetaWindow *window = tmp->data;
-
- if (IN_TAB_CHAIN (window, type))
- return window;
-
- tmp = tmp->next;
- }
-
- return NULL;
-}
-
-static MetaWindow*
-find_tab_backward (MetaDisplay *display,
- MetaTabList type,
- MetaScreen *screen,
- MetaWorkspace *workspace,
- GList *start,
- gboolean skip_last)
-{
- GList *tmp;
-
- g_return_val_if_fail (start != NULL, NULL);
- g_return_val_if_fail (workspace != NULL, NULL);
-
- tmp = start;
- if (skip_last)
- tmp = tmp->prev;
- while (tmp != NULL)
- {
- MetaWindow *window = tmp->data;
-
- if (window->screen == screen &&
- IN_TAB_CHAIN (window, type))
- return window;
-
- tmp = tmp->prev;
- }
-
- tmp = g_list_last (workspace->mru_list);
- while (tmp != start)
- {
- MetaWindow *window = tmp->data;
-
- if (IN_TAB_CHAIN (window, type))
- return window;
-
- tmp = tmp->prev;
- }
-
- return NULL;
-}
-
-GList*
-meta_display_get_tab_list (MetaDisplay *display,
- MetaTabList type,
- MetaScreen *screen,
- MetaWorkspace *workspace)
-{
- GList *tab_list;
-
- g_return_val_if_fail (workspace != NULL, NULL);
-
- /* Windows sellout mode - MRU order. Collect unminimized windows
- * then minimized so minimized windows aren't in the way so much.
- */
- {
- GList *tmp;
-
- tab_list = NULL;
- tmp = workspace->mru_list;
- while (tmp != NULL)
- {
- MetaWindow *window = tmp->data;
-
- if (!window->minimized &&
- window->screen == screen &&
- IN_TAB_CHAIN (window, type))
- tab_list = g_list_prepend (tab_list, window);
-
- tmp = tmp->next;
- }
- }
-
- {
- GList *tmp;
-
- tmp = workspace->mru_list;
- while (tmp != NULL)
- {
- MetaWindow *window = tmp->data;
-
- if (window->minimized &&
- window->screen == screen &&
- IN_TAB_CHAIN (window, type))
- tab_list = g_list_prepend (tab_list, window);
-
- tmp = tmp->next;
- }
- }
-
- tab_list = g_list_reverse (tab_list);
-
- {
- GSList *tmp;
- MetaWindow *l_window;
-
- tmp = meta_display_list_windows (display);
-
- /* Go through all windows */
- while (tmp != NULL)
- {
- l_window=tmp->data;
-
- /* Check to see if it demands attention */
- if (l_window->wm_state_demands_attention &&
- l_window->workspace!=workspace)
- {
- /* if it does, add it to the popup */
- tab_list = g_list_prepend (tab_list, l_window);
- }
-
- tmp = tmp->next;
- } /* End while tmp!=NULL */
- }
-
- return tab_list;
-}
-
-MetaWindow*
-meta_display_get_tab_next (MetaDisplay *display,
- MetaTabList type,
- MetaScreen *screen,
- MetaWorkspace *workspace,
- MetaWindow *window,
- gboolean backward)
-{
- gboolean skip;
- GList *tab_list;
- MetaWindow *ret;
- tab_list = meta_display_get_tab_list(display,
- type,
- screen,
- workspace);
-
- if (tab_list == NULL)
- return NULL;
-
- if (window != NULL)
- {
- g_assert (window->display == display);
-
- if (backward)
- ret = find_tab_backward (display, type, screen, workspace,
- g_list_find (tab_list,
- window),
- TRUE);
- else
- ret = find_tab_forward (display, type, screen, workspace,
- g_list_find (tab_list,
- window),
- TRUE);
- }
- else
- {
- skip = display->focus_window != NULL &&
- IN_TAB_CHAIN (display->focus_window, type);
- if (backward)
- ret = find_tab_backward (display, type, screen, workspace,
- tab_list, skip);
- else
- ret = find_tab_forward (display, type, screen, workspace,
- tab_list, skip);
- }
-
- g_list_free (tab_list);
- return ret;
-}
-
-MetaWindow*
-meta_display_get_tab_current (MetaDisplay *display,
- MetaTabList type,
- MetaScreen *screen,
- MetaWorkspace *workspace)
-{
- MetaWindow *window;
-
- window = display->focus_window;
-
- if (window != NULL &&
- window->screen == screen &&
- IN_TAB_CHAIN (window, type) &&
- (workspace == NULL ||
- meta_window_located_on_workspace (window, workspace)))
- return window;
- else
- return NULL;
-}
-
-int
-meta_resize_gravity_from_grab_op (MetaGrabOp op)
-{
- int gravity;
-
- gravity = -1;
- switch (op)
- {
- case META_GRAB_OP_RESIZING_SE:
- case META_GRAB_OP_KEYBOARD_RESIZING_SE:
- gravity = NorthWestGravity;
- break;
- case META_GRAB_OP_KEYBOARD_RESIZING_S:
- case META_GRAB_OP_RESIZING_S:
- gravity = NorthGravity;
- break;
- case META_GRAB_OP_KEYBOARD_RESIZING_SW:
- case META_GRAB_OP_RESIZING_SW:
- gravity = NorthEastGravity;
- break;
- case META_GRAB_OP_KEYBOARD_RESIZING_N:
- case META_GRAB_OP_RESIZING_N:
- gravity = SouthGravity;
- break;
- case META_GRAB_OP_KEYBOARD_RESIZING_NE:
- case META_GRAB_OP_RESIZING_NE:
- gravity = SouthWestGravity;
- break;
- case META_GRAB_OP_KEYBOARD_RESIZING_NW:
- case META_GRAB_OP_RESIZING_NW:
- gravity = SouthEastGravity;
- break;
- case META_GRAB_OP_KEYBOARD_RESIZING_E:
- case META_GRAB_OP_RESIZING_E:
- gravity = WestGravity;
- break;
- case META_GRAB_OP_KEYBOARD_RESIZING_W:
- case META_GRAB_OP_RESIZING_W:
- gravity = EastGravity;
- break;
- case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
- gravity = CenterGravity;
- break;
- default:
- break;
- }
-
- return gravity;
-}
-
-static MetaScreen*
-find_screen_for_selection (MetaDisplay *display,
- Window owner,
- Atom selection)
-{
- GSList *tmp;
-
- tmp = display->screens;
- while (tmp != NULL)
- {
- MetaScreen *screen = tmp->data;
-
- if (screen->wm_sn_selection_window == owner &&
- screen->wm_sn_atom == selection)
- return screen;
-
- tmp = tmp->next;
- }
-
- return NULL;
-}
-
-/* from fvwm2, Copyright Matthias Clasen, Dominik Vogt */
-static gboolean
-convert_property (MetaDisplay *display,
- MetaScreen *screen,
- Window w,
- Atom target,
- Atom property)
-{
-#define N_TARGETS 4
- Atom conversion_targets[N_TARGETS];
- long icccm_version[] = { 2, 0 };
-
- conversion_targets[0] = display->atom_TARGETS;
- conversion_targets[1] = display->atom_MULTIPLE;
- conversion_targets[2] = display->atom_TIMESTAMP;
- conversion_targets[3] = display->atom_VERSION;
-
- meta_error_trap_push_with_return (display);
- if (target == display->atom_TARGETS)
- XChangeProperty (display->xdisplay, w, property,
- XA_ATOM, 32, PropModeReplace,
- (unsigned char *)conversion_targets, N_TARGETS);
- else if (target == display->atom_TIMESTAMP)
- XChangeProperty (display->xdisplay, w, property,
- XA_INTEGER, 32, PropModeReplace,
- (unsigned char *)&screen->wm_sn_timestamp, 1);
- else if (target == display->atom_VERSION)
- XChangeProperty (display->xdisplay, w, property,
- XA_INTEGER, 32, PropModeReplace,
- (unsigned char *)icccm_version, 2);
- else
- {
- meta_error_trap_pop_with_return (display, FALSE);
- return FALSE;
- }
-
- if (meta_error_trap_pop_with_return (display, FALSE) != Success)
- return FALSE;
-
- /* Be sure the PropertyNotify has arrived so we
- * can send SelectionNotify
- */
- /* FIXME the error trap pop synced anyway, right? */
- meta_topic (META_DEBUG_SYNC, "Syncing on %s\n", G_STRFUNC);
- XSync (display->xdisplay, False);
-
- return TRUE;
-}
-
-/* from fvwm2, Copyright Matthias Clasen, Dominik Vogt */
-static void
-process_selection_request (MetaDisplay *display,
- XEvent *event)
-{
- XSelectionEvent reply;
- MetaScreen *screen;
-
- screen = find_screen_for_selection (display,
- event->xselectionrequest.owner,
- event->xselectionrequest.selection);
-
- if (screen == NULL)
- {
- char *str;
-
- meta_error_trap_push (display);
- str = XGetAtomName (display->xdisplay,
- event->xselectionrequest.selection);
- meta_error_trap_pop (display, TRUE);
-
- meta_verbose ("Selection request with selection %s window 0x%lx not a WM_Sn selection we recognize\n",
- str ? str : "(bad atom)", event->xselectionrequest.owner);
-
- meta_XFree (str);
-
- return;
- }
-
- reply.type = SelectionNotify;
- reply.display = display->xdisplay;
- reply.requestor = event->xselectionrequest.requestor;
- reply.selection = event->xselectionrequest.selection;
- reply.target = event->xselectionrequest.target;
- reply.property = None;
- reply.time = event->xselectionrequest.time;
-
- if (event->xselectionrequest.target == display->atom_MULTIPLE)
- {
- if (event->xselectionrequest.property != None)
- {
- Atom type, *adata;
- int i, format;
- unsigned long num, rest;
- unsigned char *data;
-
- meta_error_trap_push_with_return (display);
- if (XGetWindowProperty (display->xdisplay,
- event->xselectionrequest.requestor,
- event->xselectionrequest.property, 0, 256, False,
- display->atom_ATOM_PAIR,
- &type, &format, &num, &rest, &data) != Success)
- {
- meta_error_trap_pop_with_return (display, TRUE);
- return;
- }
-
- if (meta_error_trap_pop_with_return (display, TRUE) == Success)
- {
- /* FIXME: to be 100% correct, should deal with rest > 0,
- * but since we have 4 possible targets, we will hardly ever
- * meet multiple requests with a length > 8
- */
- adata = (Atom*)data;
- i = 0;
- while (i < (int) num)
- {
- if (!convert_property (display, screen,
- event->xselectionrequest.requestor,
- adata[i], adata[i+1]))
- adata[i+1] = None;
- i += 2;
- }
-
- meta_error_trap_push (display);
- XChangeProperty (display->xdisplay,
- event->xselectionrequest.requestor,
- event->xselectionrequest.property,
- display->atom_ATOM_PAIR,
- 32, PropModeReplace, data, num);
- meta_error_trap_pop (display, FALSE);
- meta_XFree (data);
- }
- }
- }
- else
- {
- if (event->xselectionrequest.property == None)
- event->xselectionrequest.property = event->xselectionrequest.target;
-
- if (convert_property (display, screen,
- event->xselectionrequest.requestor,
- event->xselectionrequest.target,
- event->xselectionrequest.property))
- reply.property = event->xselectionrequest.property;
- }
-
- XSendEvent (display->xdisplay,
- event->xselectionrequest.requestor,
- False, 0L, (XEvent*)&reply);
-
- meta_verbose ("Handled selection request\n");
-}
-
-static void
-process_selection_clear (MetaDisplay *display,
- XEvent *event)
-{
- /* We need to unmanage the screen on which we lost the selection */
- MetaScreen *screen;
-
- screen = find_screen_for_selection (display,
- event->xselectionclear.window,
- event->xselectionclear.selection);
-
-
- if (screen != NULL)
- {
- meta_verbose ("Got selection clear for screen %d on display %s\n",
- screen->number, display->name);
-
- meta_display_unmanage_screen (display,
- screen,
- event->xselectionclear.time);
-
- /* display and screen may both be invalid memory... */
-
- return;
- }
-
- {
- char *str;
-
- meta_error_trap_push (display);
- str = XGetAtomName (display->xdisplay,
- event->xselectionclear.selection);
- meta_error_trap_pop (display, TRUE);
-
- meta_verbose ("Selection clear with selection %s window 0x%lx not a WM_Sn selection we recognize\n",
- str ? str : "(bad atom)", event->xselectionclear.window);
-
- meta_XFree (str);
- }
-}
-
-void
-meta_display_unmanage_screen (MetaDisplay *display,
- MetaScreen *screen,
- guint32 timestamp)
-{
- meta_verbose ("Unmanaging screen %d on display %s\n",
- screen->number, display->name);
-
- g_return_if_fail (g_slist_find (display->screens, screen) != NULL);
-
- meta_screen_free (screen, timestamp);
- display->screens = g_slist_remove (display->screens, screen);
-
- if (display->screens == NULL)
- meta_display_close (display, timestamp);
-}
-
-void
-meta_display_unmanage_windows_for_screen (MetaDisplay *display,
- MetaScreen *screen,
- guint32 timestamp)
-{
- GSList *tmp;
- GSList *winlist;
-
- winlist = meta_display_list_windows (display);
- winlist = g_slist_sort (winlist, meta_display_stack_cmp);
-
- /* Unmanage all windows */
- tmp = winlist;
- while (tmp != NULL)
- {
- meta_window_free (tmp->data, timestamp);
-
- tmp = tmp->next;
- }
- g_slist_free (winlist);
-}
-
-int
-meta_display_stack_cmp (const void *a,
- const void *b)
-{
- MetaWindow *aw = (void*) a;
- MetaWindow *bw = (void*) b;
-
- if (aw->screen == bw->screen)
- return meta_stack_windows_cmp (aw->screen->stack, aw, bw);
- /* Then assume screens are stacked by number */
- else if (aw->screen->number < bw->screen->number)
- return -1;
- else if (aw->screen->number > bw->screen->number)
- return 1;
- else
- return 0; /* not reached in theory, if windows on same display */
-}
-
-void
-meta_display_devirtualize_modifiers (MetaDisplay *display,
- MetaVirtualModifier modifiers,
- unsigned int *mask)
-{
- *mask = 0;
-
- if (modifiers & META_VIRTUAL_SHIFT_MASK)
- *mask |= ShiftMask;
- if (modifiers & META_VIRTUAL_CONTROL_MASK)
- *mask |= ControlMask;
- if (modifiers & META_VIRTUAL_ALT_MASK)
- *mask |= Mod1Mask;
- if (modifiers & META_VIRTUAL_META_MASK)
- *mask |= display->meta_mask;
- if (modifiers & META_VIRTUAL_HYPER_MASK)
- *mask |= display->hyper_mask;
- if (modifiers & META_VIRTUAL_SUPER_MASK)
- *mask |= display->super_mask;
- if (modifiers & META_VIRTUAL_MOD2_MASK)
- *mask |= Mod2Mask;
- if (modifiers & META_VIRTUAL_MOD3_MASK)
- *mask |= Mod3Mask;
- if (modifiers & META_VIRTUAL_MOD4_MASK)
- *mask |= Mod4Mask;
- if (modifiers & META_VIRTUAL_MOD5_MASK)
- *mask |= Mod5Mask;
-}
-
-static void
-update_window_grab_modifiers (MetaDisplay *display)
-
-{
- MetaVirtualModifier virtual_mods;
- unsigned int mods;
-
- virtual_mods = meta_prefs_get_mouse_button_mods ();
- meta_display_devirtualize_modifiers (display, virtual_mods,
- &mods);
-
- display->window_grab_modifiers = mods;
-}
-
-static void
-prefs_changed_callback (MetaPreference pref,
- void *data)
-{
- MetaDisplay *display = data;
-
- /* It may not be obvious why we regrab on focus mode
- * change; it's because we handle focus clicks a
- * bit differently for the different focus modes.
- */
- if (pref == META_PREF_MOUSE_BUTTON_MODS ||
- pref == META_PREF_FOCUS_MODE)
- {
- MetaDisplay *display = data;
- GSList *windows;
- GSList *tmp;
-
- windows = meta_display_list_windows (display);
-
- /* Ungrab all */
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
- meta_display_ungrab_window_buttons (display, w->xwindow);
- meta_display_ungrab_focus_window_button (display, w);
- tmp = tmp->next;
- }
-
- /* change our modifier */
- if (pref == META_PREF_MOUSE_BUTTON_MODS)
- update_window_grab_modifiers (display);
-
- /* Grab all */
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
- if (w->type != META_WINDOW_DOCK)
- {
- meta_display_grab_focus_window_button (display, w);
- meta_display_grab_window_buttons (display, w->xwindow);
- }
- tmp = tmp->next;
- }
-
- g_slist_free (windows);
- }
- else if (pref == META_PREF_AUDIBLE_BELL)
- {
- meta_bell_set_audible (display, meta_prefs_bell_is_audible ());
- }
- else if (pref == META_PREF_COMPOSITING_MANAGER)
- {
- gboolean cm = meta_prefs_get_compositing_manager ();
-
- if (cm)
- enable_compositor (display, TRUE);
- else
- disable_compositor (display);
- }
-}
-
-void
-meta_display_increment_focus_sentinel (MetaDisplay *display)
-{
- unsigned long data[1];
-
- data[0] = meta_display_get_current_time (display);
-
- XChangeProperty (display->xdisplay,
- ((MetaScreen*) display->screens->data)->xroot,
- display->atom__METACITY_SENTINEL,
- XA_CARDINAL,
- 32, PropModeReplace, (guchar*) data, 1);
-
- display->sentinel_counter += 1;
-}
-
-void
-meta_display_decrement_focus_sentinel (MetaDisplay *display)
-{
- display->sentinel_counter -= 1;
-
- if (display->sentinel_counter < 0)
- display->sentinel_counter = 0;
-}
-
-gboolean
-meta_display_focus_sentinel_clear (MetaDisplay *display)
-{
- return (display->sentinel_counter == 0);
-}
-
-static void
-sanity_check_timestamps (MetaDisplay *display,
- guint32 timestamp)
-{
- if (XSERVER_TIME_IS_BEFORE (timestamp, display->last_focus_time))
- {
- meta_warning ("last_focus_time (%u) is greater than comparison "
- "timestamp (%u). This most likely represents a buggy "
- "client sending inaccurate timestamps in messages such as "
- "_NET_ACTIVE_WINDOW. Trying to work around...\n",
- display->last_focus_time, timestamp);
- display->last_focus_time = timestamp;
- }
- if (XSERVER_TIME_IS_BEFORE (timestamp, display->last_user_time))
- {
- GSList *windows;
- GSList *tmp;
-
- meta_warning ("last_user_time (%u) is greater than comparison "
- "timestamp (%u). This most likely represents a buggy "
- "client sending inaccurate timestamps in messages such as "
- "_NET_ACTIVE_WINDOW. Trying to work around...\n",
- display->last_user_time, timestamp);
- display->last_user_time = timestamp;
-
- windows = meta_display_list_windows (display);
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *window = tmp->data;
-
- if (XSERVER_TIME_IS_BEFORE (timestamp, window->net_wm_user_time))
- {
- meta_warning ("%s appears to be one of the offending windows "
- "with a timestamp of %u. Working around...\n",
- window->desc, window->net_wm_user_time);
- window->net_wm_user_time = timestamp;
- }
-
- tmp = tmp->next;
- }
-
- g_slist_free (windows);
- }
-}
-
-static gboolean
-timestamp_too_old (MetaDisplay *display,
- MetaWindow *window,
- guint32 *timestamp)
-{
- /* FIXME: If Soeren's suggestion in bug 151984 is implemented, it will allow
- * us to sanity check the timestamp here and ensure it doesn't correspond to
- * a future time (though we would want to rename to
- * timestamp_too_old_or_in_future).
- */
-
- if (*timestamp == CurrentTime)
- {
- meta_warning ("Got a request to focus %s with a timestamp of 0. This "
- "shouldn't happen!\n",
- window ? window->desc : "the no_focus_window");
- meta_print_backtrace ();
- *timestamp = meta_display_get_current_time_roundtrip (display);
- return FALSE;
- }
- else if (XSERVER_TIME_IS_BEFORE (*timestamp, display->last_focus_time))
- {
- if (XSERVER_TIME_IS_BEFORE (*timestamp, display->last_user_time))
- {
- meta_topic (META_DEBUG_FOCUS,
- "Ignoring focus request for %s since %u "
- "is less than %u and %u.\n",
- window ? window->desc : "the no_focus_window",
- *timestamp,
- display->last_user_time,
- display->last_focus_time);
- return TRUE;
- }
- else
- {
- meta_topic (META_DEBUG_FOCUS,
- "Received focus request for %s which is newer than most "
- "recent user_time, but less recent than "
- "last_focus_time (%u < %u < %u); adjusting "
- "accordingly. (See bug 167358)\n",
- window ? window->desc : "the no_focus_window",
- display->last_user_time,
- *timestamp,
- display->last_focus_time);
- *timestamp = display->last_focus_time;
- return FALSE;
- }
- }
-
- return FALSE;
-}
-
-void
-meta_display_set_input_focus_window (MetaDisplay *display,
- MetaWindow *window,
- gboolean focus_frame,
- guint32 timestamp)
-{
- if (timestamp_too_old (display, window, &timestamp))
- return;
-
- meta_error_trap_push (display);
- XSetInputFocus (display->xdisplay,
- focus_frame ? window->frame->xwindow : window->xwindow,
- RevertToPointerRoot,
- timestamp);
- meta_error_trap_pop (display, FALSE);
-
- display->expected_focus_window = window;
- display->last_focus_time = timestamp;
- display->active_screen = window->screen;
-
- if (window != display->autoraise_window)
- meta_display_remove_autoraise_callback (window->display);
-}
-
-void
-meta_display_focus_the_no_focus_window (MetaDisplay *display,
- MetaScreen *screen,
- guint32 timestamp)
-{
- if (timestamp_too_old (display, NULL, &timestamp))
- return;
-
- XSetInputFocus (display->xdisplay,
- screen->no_focus_window,
- RevertToPointerRoot,
- timestamp);
- display->expected_focus_window = NULL;
- display->last_focus_time = timestamp;
- display->active_screen = screen;
-
- meta_display_remove_autoraise_callback (display);
-}
-
-void
-meta_display_remove_autoraise_callback (MetaDisplay *display)
-{
- if (display->autoraise_timeout_id != 0)
- {
- g_source_remove (display->autoraise_timeout_id);
- display->autoraise_timeout_id = 0;
- display->autoraise_window = NULL;
- }
-}
-
-#ifdef HAVE_COMPOSITE_EXTENSIONS
-void
-meta_display_get_compositor_version (MetaDisplay *display,
- int *major,
- int *minor)
-{
- *major = display->composite_major_version;
- *minor = display->composite_minor_version;
-}
-#endif
-
-Display *
-meta_display_get_xdisplay (MetaDisplay *display)
-{
- return display->xdisplay;
-}
-
-MetaCompositor *
-meta_display_get_compositor (MetaDisplay *display)
-{
- return display->compositor;
-}
-
-GSList *
-meta_display_get_screens (MetaDisplay *display)
-{
- return display->screens;
-}
-
-gboolean
-meta_display_has_shape (MetaDisplay *display)
-{
- return META_DISPLAY_HAS_SHAPE (display);
-}
-
-MetaWindow *
-meta_display_get_focus_window (MetaDisplay *display)
-{
- return display->focus_window;
-}
-
-#ifdef HAVE_COMPOSITE_EXTENSIONS
-int
-meta_display_get_damage_event_base (MetaDisplay *display)
-{
- return display->damage_event_base;
-}
-#endif
-
-#ifdef HAVE_COMPOSITE_EXTENSIONS
-#ifdef HAVE_SHAPE
-int
-meta_display_get_shape_event_base (MetaDisplay *display)
-{
- return display->shape_event_base;
-}
-#endif
-#endif
diff --git a/src/core/edge-resistance.c b/src/core/edge-resistance.c
deleted file mode 100644
index fb7c2d2e..00000000
--- a/src/core/edge-resistance.c
+++ /dev/null
@@ -1,1277 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Edge resistance for move/resize operations */
-
-/*
- * Copyright (C) 2005, 2006 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include "edge-resistance.h"
-#include "boxes.h"
-#include "display-private.h"
-#include "workspace.h"
-
-/* A simple macro for whether a given window's edges are potentially
- * relevant for resistance/snapping during a move/resize operation
- */
-#define WINDOW_EDGES_RELEVANT(window, display) \
- meta_window_should_be_showing (window) && \
- window->screen == display->grab_screen && \
- window != display->grab_window && \
- window->type != META_WINDOW_DESKTOP && \
- window->type != META_WINDOW_MENU && \
- window->type != META_WINDOW_SPLASHSCREEN
-
-struct ResistanceDataForAnEdge
-{
- gboolean timeout_setup;
- guint timeout_id;
- int timeout_edge_pos;
- gboolean timeout_over;
- GSourceFunc timeout_func;
- MetaWindow *window;
- int keyboard_buildup;
-};
-typedef struct ResistanceDataForAnEdge ResistanceDataForAnEdge;
-
-struct MetaEdgeResistanceData
-{
- GArray *left_edges;
- GArray *right_edges;
- GArray *top_edges;
- GArray *bottom_edges;
-
- ResistanceDataForAnEdge left_data;
- ResistanceDataForAnEdge right_data;
- ResistanceDataForAnEdge top_data;
- ResistanceDataForAnEdge bottom_data;
-};
-
-/* !WARNING!: this function can return invalid indices (namely, either -1 or
- * edges->len); this is by design, but you need to remember this.
- */
-static int
-find_index_of_edge_near_position (const GArray *edges,
- int position,
- gboolean want_interval_min,
- gboolean horizontal)
-{
- /* This is basically like a binary search, except that we're trying to
- * find a range instead of an exact value. So, if we have in our array
- * Value: 3 27 316 316 316 505 522 800 1213
- * Index: 0 1 2 3 4 5 6 7 8
- * and we call this function with position=500 & want_interval_min=TRUE
- * then we should get 5 (because 505 is the first value bigger than 500).
- * If we call this function with position=805 and want_interval_min=FALSE
- * then we should get 7 (because 800 is the last value smaller than 800).
- * A couple more, to make things clear:
- * position want_interval_min correct_answer
- * 316 TRUE 2
- * 316 FALSE 4
- * 2 FALSE -1
- * 2000 TRUE 9
- */
- int low, high, mid;
- int compare;
- MetaEdge *edge;
-
- /* Initialize mid, edge, & compare in the off change that the array only
- * has one element.
- */
- mid = 0;
- edge = g_array_index (edges, MetaEdge*, mid);
- compare = horizontal ? edge->rect.x : edge->rect.y;
-
- /* Begin the search... */
- low = 0;
- high = edges->len - 1;
- while (low < high)
- {
- mid = low + (high - low)/2;
- edge = g_array_index (edges, MetaEdge*, mid);
- compare = horizontal ? edge->rect.x : edge->rect.y;
-
- if (compare == position)
- break;
-
- if (compare > position)
- high = mid - 1;
- else
- low = mid + 1;
- }
-
- /* mid should now be _really_ close to the index we want, so we start
- * linearly searching. However, note that we don't know if mid is less
- * than or greater than what we need and it's possible that there are
- * several equal values equal to what we were searching for and we ended
- * up in the middle of them instead of at the end. So we may need to
- * move mid multiple locations over.
- */
- if (want_interval_min)
- {
- while (compare >= position && mid > 0)
- {
- mid--;
- edge = g_array_index (edges, MetaEdge*, mid);
- compare = horizontal ? edge->rect.x : edge->rect.y;
- }
- while (compare < position && mid < (int)edges->len - 1)
- {
- mid++;
- edge = g_array_index (edges, MetaEdge*, mid);
- compare = horizontal ? edge->rect.x : edge->rect.y;
- }
-
- /* Special case for no values in array big enough */
- if (compare < position)
- return edges->len;
-
- /* Return the found value */
- return mid;
- }
- else
- {
- while (compare <= position && mid < (int)edges->len - 1)
- {
- mid++;
- edge = g_array_index (edges, MetaEdge*, mid);
- compare = horizontal ? edge->rect.x : edge->rect.y;
- }
- while (compare > position && mid > 0)
- {
- mid--;
- edge = g_array_index (edges, MetaEdge*, mid);
- compare = horizontal ? edge->rect.x : edge->rect.y;
- }
-
- /* Special case for no values in array small enough */
- if (compare > position)
- return -1;
-
- /* Return the found value */
- return mid;
- }
-}
-
-static gboolean
-points_on_same_side (int ref, int pt1, int pt2)
-{
- return (pt1 - ref) * (pt2 - ref) > 0;
-}
-
-static int
-find_nearest_position (const GArray *edges,
- int position,
- int old_position,
- const MetaRectangle *new_rect,
- gboolean horizontal,
- gboolean only_forward)
-{
- /* This is basically just a binary search except that we're looking
- * for the value closest to position, rather than finding that
- * actual value. Also, we ignore any edges that aren't relevant
- * given the horizontal/vertical position of new_rect.
- */
- int low, high, mid;
- int compare;
- MetaEdge *edge;
- int best, best_dist, i;
- gboolean edges_align;
-
- /* Initialize mid, edge, & compare in the off change that the array only
- * has one element.
- */
- mid = 0;
- edge = g_array_index (edges, MetaEdge*, mid);
- compare = horizontal ? edge->rect.x : edge->rect.y;
-
- /* Begin the search... */
- low = 0;
- high = edges->len - 1;
- while (low < high)
- {
- mid = low + (high - low)/2;
- edge = g_array_index (edges, MetaEdge*, mid);
- compare = horizontal ? edge->rect.x : edge->rect.y;
-
- if (compare == position)
- break;
-
- if (compare > position)
- high = mid - 1;
- else
- low = mid + 1;
- }
-
- /* mid should now be _really_ close to the index we want, so we
- * start searching nearby for something that overlaps and is closer
- * than the original position.
- */
- best = old_position;
- best_dist = INT_MAX;
-
- /* Start the search at mid */
- edge = g_array_index (edges, MetaEdge*, mid);
- compare = horizontal ? edge->rect.x : edge->rect.y;
- edges_align = meta_rectangle_edge_aligns (new_rect, edge);
- if (edges_align &&
- (!only_forward || !points_on_same_side (position, compare, old_position)))
- {
- int dist = ABS (compare - position);
- if (dist < best_dist)
- {
- best = compare;
- best_dist = dist;
- }
- }
-
- /* Now start searching higher than mid */
- for (i = mid + 1; i < (int)edges->len; i++)
- {
- edge = g_array_index (edges, MetaEdge*, i);
- compare = horizontal ? edge->rect.x : edge->rect.y;
-
- edges_align = horizontal ?
- meta_rectangle_vert_overlap (&edge->rect, new_rect) :
- meta_rectangle_horiz_overlap (&edge->rect, new_rect);
-
- if (edges_align &&
- (!only_forward ||
- !points_on_same_side (position, compare, old_position)))
- {
- int dist = ABS (compare - position);
- if (dist < best_dist)
- {
- best = compare;
- best_dist = dist;
- }
- break;
- }
- }
-
- /* Now start searching lower than mid */
- for (i = mid-1; i >= 0; i--)
- {
- edge = g_array_index (edges, MetaEdge*, i);
- compare = horizontal ? edge->rect.x : edge->rect.y;
-
- edges_align = horizontal ?
- meta_rectangle_vert_overlap (&edge->rect, new_rect) :
- meta_rectangle_horiz_overlap (&edge->rect, new_rect);
-
- if (edges_align &&
- (!only_forward ||
- !points_on_same_side (position, compare, old_position)))
- {
- int dist = ABS (compare - position);
- if (dist < best_dist)
- {
- best = compare;
- best_dist = dist;
- }
- break;
- }
- }
-
- /* Return the best one found */
- return best;
-}
-
-static gboolean
-movement_towards_edge (MetaDirection side, int increment)
-{
- switch (side)
- {
- case META_DIRECTION_LEFT:
- case META_DIRECTION_TOP:
- return increment < 0;
- case META_DIRECTION_RIGHT:
- case META_DIRECTION_BOTTOM:
- return increment > 0;
- default:
- g_assert_not_reached ();
- }
-}
-
-static gboolean
-edge_resistance_timeout (gpointer data)
-{
- ResistanceDataForAnEdge *resistance_data = data;
-
- resistance_data->timeout_over = TRUE;
- resistance_data->timeout_id = 0;
- (*resistance_data->timeout_func)(resistance_data->window);
-
- return FALSE;
-}
-
-static int
-apply_edge_resistance (MetaWindow *window,
- int old_pos,
- int new_pos,
- const MetaRectangle *old_rect,
- const MetaRectangle *new_rect,
- GArray *edges,
- ResistanceDataForAnEdge *resistance_data,
- GSourceFunc timeout_func,
- gboolean xdir,
- gboolean keyboard_op)
-{
- int i, begin, end;
- int last_edge;
- gboolean increasing = new_pos > old_pos;
- int increment = increasing ? 1 : -1;
-
- const int PIXEL_DISTANCE_THRESHOLD_TOWARDS_WINDOW = 16;
- const int PIXEL_DISTANCE_THRESHOLD_AWAYFROM_WINDOW = 0;
- const int PIXEL_DISTANCE_THRESHOLD_TOWARDS_XINERAMA = 32;
- const int PIXEL_DISTANCE_THRESHOLD_AWAYFROM_XINERAMA = 0;
- const int PIXEL_DISTANCE_THRESHOLD_TOWARDS_SCREEN = 32;
- const int PIXEL_DISTANCE_THRESHOLD_AWAYFROM_SCREEN = 0;
- const int TIMEOUT_RESISTANCE_LENGTH_MS_WINDOW = 0;
- const int TIMEOUT_RESISTANCE_LENGTH_MS_XINERAMA = 0;
- const int TIMEOUT_RESISTANCE_LENGTH_MS_SCREEN = 0;
-
- /* Quit if no movement was specified */
- if (old_pos == new_pos)
- return new_pos;
-
- /* Remove the old timeout if it's no longer relevant */
- if (resistance_data->timeout_setup &&
- ((resistance_data->timeout_edge_pos > old_pos &&
- resistance_data->timeout_edge_pos > new_pos) ||
- (resistance_data->timeout_edge_pos < old_pos &&
- resistance_data->timeout_edge_pos < new_pos)))
- {
- resistance_data->timeout_setup = FALSE;
- if (resistance_data->timeout_id != 0)
- {
- g_source_remove (resistance_data->timeout_id);
- resistance_data->timeout_id = 0;
- }
- }
-
- /* Get the range of indices in the edge array that we move past/to. */
- begin = find_index_of_edge_near_position (edges, old_pos, increasing, xdir);
- end = find_index_of_edge_near_position (edges, new_pos, !increasing, xdir);
-
- /* begin and end can be outside the array index, if the window is partially
- * off the screen
- */
- last_edge = edges->len - 1;
- begin = CLAMP (begin, 0, last_edge);
- end = CLAMP (end, 0, last_edge);
-
- /* Loop over all these edges we're moving past/to. */
- i = begin;
- while ((increasing && i <= end) ||
- (!increasing && i >= end))
- {
- gboolean edges_align;
- MetaEdge *edge = g_array_index (edges, MetaEdge*, i);
- int compare = xdir ? edge->rect.x : edge->rect.y;
-
- /* Find out if this edge is relevant */
- edges_align = meta_rectangle_edge_aligns (new_rect, edge) ||
- meta_rectangle_edge_aligns (old_rect, edge);
-
- /* Nothing to do unless the edges align */
- if (!edges_align)
- {
- /* Go to the next edge in the range */
- i += increment;
- continue;
- }
-
- /* Rest is easier to read if we split on keyboard vs. mouse op */
- if (keyboard_op)
- {
- if ((old_pos < compare && compare < new_pos) ||
- (old_pos > compare && compare > new_pos))
- return compare;
- }
- else /* mouse op */
- {
- int threshold;
-
- /* TIMEOUT RESISTANCE: If the edge is relevant and we're moving
- * towards it, then we may want to have some kind of time delay
- * before the user can move past this edge.
- */
- if (movement_towards_edge (edge->side_type, increment))
- {
- /* First, determine the length of time for the resistance */
- int timeout_length_ms = 0;
- switch (edge->edge_type)
- {
- case META_EDGE_WINDOW:
- timeout_length_ms = TIMEOUT_RESISTANCE_LENGTH_MS_WINDOW;
- break;
- case META_EDGE_XINERAMA:
- timeout_length_ms = TIMEOUT_RESISTANCE_LENGTH_MS_XINERAMA;
- break;
- case META_EDGE_SCREEN:
- timeout_length_ms = TIMEOUT_RESISTANCE_LENGTH_MS_SCREEN;
- break;
- }
-
- if (!resistance_data->timeout_setup &&
- timeout_length_ms != 0)
- {
- resistance_data->timeout_id =
- g_timeout_add (timeout_length_ms,
- edge_resistance_timeout,
- resistance_data);
- resistance_data->timeout_setup = TRUE;
- resistance_data->timeout_edge_pos = compare;
- resistance_data->timeout_over = FALSE;
- resistance_data->timeout_func = timeout_func;
- resistance_data->window = window;
- }
- if (!resistance_data->timeout_over &&
- timeout_length_ms != 0)
- return compare;
- }
-
- /* PIXEL DISTANCE MOUSE RESISTANCE: If the edge matters and the
- * user hasn't moved at least threshold pixels past this edge,
- * stop movement at this edge. (Note that this is different from
- * keyboard resistance precisely because keyboard move ops are
- * relative to previous positions, whereas mouse move ops are
- * relative to differences in mouse position and mouse position
- * is an absolute quantity rather than a relative quantity)
- */
-
- /* First, determine the threshold */
- threshold = 0;
- switch (edge->edge_type)
- {
- case META_EDGE_WINDOW:
- if (movement_towards_edge (edge->side_type, increment))
- threshold = PIXEL_DISTANCE_THRESHOLD_TOWARDS_WINDOW;
- else
- threshold = PIXEL_DISTANCE_THRESHOLD_AWAYFROM_WINDOW;
- break;
- case META_EDGE_XINERAMA:
- if (movement_towards_edge (edge->side_type, increment))
- threshold = PIXEL_DISTANCE_THRESHOLD_TOWARDS_XINERAMA;
- else
- threshold = PIXEL_DISTANCE_THRESHOLD_AWAYFROM_XINERAMA;
- break;
- case META_EDGE_SCREEN:
- if (movement_towards_edge (edge->side_type, increment))
- threshold = PIXEL_DISTANCE_THRESHOLD_TOWARDS_SCREEN;
- else
- threshold = PIXEL_DISTANCE_THRESHOLD_AWAYFROM_SCREEN;
- break;
- }
-
- if (ABS (compare - new_pos) < threshold)
- return compare;
- }
-
- /* Go to the next edge in the range */
- i += increment;
- }
-
- return new_pos;
-}
-
-static int
-apply_edge_snapping (int old_pos,
- int new_pos,
- const MetaRectangle *new_rect,
- GArray *edges,
- gboolean xdir,
- gboolean keyboard_op)
-{
- int snap_to;
-
- if (old_pos == new_pos)
- return new_pos;
-
- snap_to = find_nearest_position (edges,
- new_pos,
- old_pos,
- new_rect,
- xdir,
- keyboard_op);
-
- /* If mouse snap-moving, the user could easily accidentally move just a
- * couple pixels in a direction they didn't mean to move; so ignore snap
- * movement in those cases unless it's only a small number of pixels
- * anyway.
- */
- if (!keyboard_op &&
- ABS (snap_to - old_pos) >= 8 &&
- ABS (new_pos - old_pos) < 8)
- return old_pos;
- else
- /* Otherwise, return the snapping position found */
- return snap_to;
-}
-
-/* This function takes the position (including any frame) of the window and
- * a proposed new position (ignoring edge resistance/snapping), and then
- * applies edge resistance to EACH edge (separately) updating new_outer.
- * It returns true if new_outer is modified, false otherwise.
- *
- * display->grab_edge_resistance_data MUST already be setup or calling this
- * function will cause a crash.
- */
-static gboolean
-apply_edge_resistance_to_each_side (MetaDisplay *display,
- MetaWindow *window,
- const MetaRectangle *old_outer,
- MetaRectangle *new_outer,
- GSourceFunc timeout_func,
- gboolean auto_snap,
- gboolean keyboard_op,
- gboolean is_resize)
-{
- MetaEdgeResistanceData *edge_data;
- MetaRectangle modified_rect;
- gboolean modified;
- int new_left, new_right, new_top, new_bottom;
-
- g_assert (display->grab_edge_resistance_data != NULL);
- edge_data = display->grab_edge_resistance_data;
-
- if (auto_snap)
- {
- /* Do the auto snapping instead of normal edge resistance; in all
- * cases, we allow snapping to opposite kinds of edges (e.g. left
- * sides of windows to both left and right edges.
- */
-
- new_left = apply_edge_snapping (BOX_LEFT (*old_outer),
- BOX_LEFT (*new_outer),
- new_outer,
- edge_data->left_edges,
- TRUE,
- keyboard_op);
-
- new_right = apply_edge_snapping (BOX_RIGHT (*old_outer),
- BOX_RIGHT (*new_outer),
- new_outer,
- edge_data->right_edges,
- TRUE,
- keyboard_op);
-
- new_top = apply_edge_snapping (BOX_TOP (*old_outer),
- BOX_TOP (*new_outer),
- new_outer,
- edge_data->top_edges,
- FALSE,
- keyboard_op);
-
- new_bottom = apply_edge_snapping (BOX_BOTTOM (*old_outer),
- BOX_BOTTOM (*new_outer),
- new_outer,
- edge_data->bottom_edges,
- FALSE,
- keyboard_op);
- }
- else
- {
- /* Disable edge resistance for resizes when windows have size
- * increment hints; see #346782. For all other cases, apply
- * them.
- */
- if (!is_resize || window->size_hints.width_inc == 1)
- {
- /* Now, apply the normal horizontal edge resistance */
- new_left = apply_edge_resistance (window,
- BOX_LEFT (*old_outer),
- BOX_LEFT (*new_outer),
- old_outer,
- new_outer,
- edge_data->left_edges,
- &edge_data->left_data,
- timeout_func,
- TRUE,
- keyboard_op);
- new_right = apply_edge_resistance (window,
- BOX_RIGHT (*old_outer),
- BOX_RIGHT (*new_outer),
- old_outer,
- new_outer,
- edge_data->right_edges,
- &edge_data->right_data,
- timeout_func,
- TRUE,
- keyboard_op);
- }
- else
- {
- new_left = new_outer->x;
- new_right = new_outer->x + new_outer->width;
- }
- /* Same for vertical resizes... */
- if (!is_resize || window->size_hints.height_inc == 1)
- {
- new_top = apply_edge_resistance (window,
- BOX_TOP (*old_outer),
- BOX_TOP (*new_outer),
- old_outer,
- new_outer,
- edge_data->top_edges,
- &edge_data->top_data,
- timeout_func,
- FALSE,
- keyboard_op);
- new_bottom = apply_edge_resistance (window,
- BOX_BOTTOM (*old_outer),
- BOX_BOTTOM (*new_outer),
- old_outer,
- new_outer,
- edge_data->bottom_edges,
- &edge_data->bottom_data,
- timeout_func,
- FALSE,
- keyboard_op);
- }
- else
- {
- new_top = new_outer->y;
- new_bottom = new_outer->y + new_outer->height;
- }
- }
-
- /* Determine whether anything changed, and save the changes */
- modified_rect = meta_rect (new_left,
- new_top,
- new_right - new_left,
- new_bottom - new_top);
- modified = !meta_rectangle_equal (new_outer, &modified_rect);
- *new_outer = modified_rect;
- return modified;
-}
-
-void
-meta_display_cleanup_edges (MetaDisplay *display)
-{
- guint i,j;
- MetaEdgeResistanceData *edge_data = display->grab_edge_resistance_data;
- GHashTable *edges_to_be_freed;
-
- g_assert (edge_data != NULL);
-
- /* We first need to clean out any window edges */
- edges_to_be_freed = g_hash_table_new_full (g_direct_hash, g_direct_equal,
- g_free, NULL);
- for (i = 0; i < 4; i++)
- {
- GArray *tmp = NULL;
- MetaDirection dir;
- switch (i)
- {
- case 0:
- tmp = edge_data->left_edges;
- dir = META_DIRECTION_LEFT;
- break;
- case 1:
- tmp = edge_data->right_edges;
- dir = META_DIRECTION_RIGHT;
- break;
- case 2:
- tmp = edge_data->top_edges;
- dir = META_DIRECTION_TOP;
- break;
- case 3:
- tmp = edge_data->bottom_edges;
- dir = META_DIRECTION_BOTTOM;
- break;
- default:
- g_assert_not_reached ();
- }
-
- for (j = 0; j < tmp->len; j++)
- {
- MetaEdge *edge = g_array_index (tmp, MetaEdge*, j);
- if (edge->edge_type == META_EDGE_WINDOW &&
- edge->side_type == dir)
- {
- /* The same edge will appear in two arrays, and we can't free
- * it yet we still need to compare edge->side_type for the other
- * array that it is in. So store it in a hash table for later
- * freeing. Could also do this in a simple linked list.
- */
- g_hash_table_insert (edges_to_be_freed, edge, edge);
- }
- }
- }
-
- /* Now free all the window edges (the key destroy function is g_free) */
- g_hash_table_destroy (edges_to_be_freed);
-
- /* Now free the arrays and data */
- g_array_free (edge_data->left_edges, TRUE);
- g_array_free (edge_data->right_edges, TRUE);
- g_array_free (edge_data->top_edges, TRUE);
- g_array_free (edge_data->bottom_edges, TRUE);
- edge_data->left_edges = NULL;
- edge_data->right_edges = NULL;
- edge_data->top_edges = NULL;
- edge_data->bottom_edges = NULL;
-
- /* Cleanup the timeouts */
- if (edge_data->left_data.timeout_setup &&
- edge_data->left_data.timeout_id != 0)
- g_source_remove (edge_data->left_data.timeout_id);
- if (edge_data->right_data.timeout_setup &&
- edge_data->right_data.timeout_id != 0)
- g_source_remove (edge_data->right_data.timeout_id);
- if (edge_data->top_data.timeout_setup &&
- edge_data->top_data.timeout_id != 0)
- g_source_remove (edge_data->top_data.timeout_id);
- if (edge_data->bottom_data.timeout_setup &&
- edge_data->bottom_data.timeout_id != 0)
- g_source_remove (edge_data->bottom_data.timeout_id);
-
- g_free (display->grab_edge_resistance_data);
- display->grab_edge_resistance_data = NULL;
-}
-
-static int
-stupid_sort_requiring_extra_pointer_dereference (gconstpointer a,
- gconstpointer b)
-{
- const MetaEdge * const *a_edge = a;
- const MetaEdge * const *b_edge = b;
- return meta_rectangle_edge_cmp_ignore_type (*a_edge, *b_edge);
-}
-
-static void
-cache_edges (MetaDisplay *display,
- GList *window_edges,
- GList *xinerama_edges,
- GList *screen_edges)
-{
- MetaEdgeResistanceData *edge_data;
- GList *tmp;
- int num_left, num_right, num_top, num_bottom;
- int i;
-
- /*
- * 0th: Print debugging information to the log about the edges
- */
-#ifdef WITH_VERBOSE_MODE
- if (meta_is_verbose())
- {
- int max_edges = MAX (MAX( g_list_length (window_edges),
- g_list_length (xinerama_edges)),
- g_list_length (screen_edges));
- char big_buffer[(EDGE_LENGTH+2)*max_edges];
-
- meta_rectangle_edge_list_to_string (window_edges, ", ", big_buffer);
- meta_topic (META_DEBUG_EDGE_RESISTANCE,
- "Window edges for resistance : %s\n", big_buffer);
-
- meta_rectangle_edge_list_to_string (xinerama_edges, ", ", big_buffer);
- meta_topic (META_DEBUG_EDGE_RESISTANCE,
- "Xinerama edges for resistance: %s\n", big_buffer);
-
- meta_rectangle_edge_list_to_string (screen_edges, ", ", big_buffer);
- meta_topic (META_DEBUG_EDGE_RESISTANCE,
- "Screen edges for resistance : %s\n", big_buffer);
- }
-#endif
-
- /*
- * 1st: Get the total number of each kind of edge
- */
- num_left = num_right = num_top = num_bottom = 0;
- for (i = 0; i < 3; i++)
- {
- tmp = NULL;
- switch (i)
- {
- case 0:
- tmp = window_edges;
- break;
- case 1:
- tmp = xinerama_edges;
- break;
- case 2:
- tmp = screen_edges;
- break;
- default:
- g_assert_not_reached ();
- }
-
- while (tmp)
- {
- MetaEdge *edge = tmp->data;
- switch (edge->side_type)
- {
- case META_DIRECTION_LEFT:
- num_left++;
- break;
- case META_DIRECTION_RIGHT:
- num_right++;
- break;
- case META_DIRECTION_TOP:
- num_top++;
- break;
- case META_DIRECTION_BOTTOM:
- num_bottom++;
- break;
- default:
- g_assert_not_reached ();
- }
- tmp = tmp->next;
- }
- }
-
- /*
- * 2nd: Allocate the edges
- */
- g_assert (display->grab_edge_resistance_data == NULL);
- display->grab_edge_resistance_data = g_new (MetaEdgeResistanceData, 1);
- edge_data = display->grab_edge_resistance_data;
- edge_data->left_edges = g_array_sized_new (FALSE,
- FALSE,
- sizeof(MetaEdge*),
- num_left + num_right);
- edge_data->right_edges = g_array_sized_new (FALSE,
- FALSE,
- sizeof(MetaEdge*),
- num_left + num_right);
- edge_data->top_edges = g_array_sized_new (FALSE,
- FALSE,
- sizeof(MetaEdge*),
- num_top + num_bottom);
- edge_data->bottom_edges = g_array_sized_new (FALSE,
- FALSE,
- sizeof(MetaEdge*),
- num_top + num_bottom);
-
- /*
- * 3rd: Add the edges to the arrays
- */
- for (i = 0; i < 3; i++)
- {
- tmp = NULL;
- switch (i)
- {
- case 0:
- tmp = window_edges;
- break;
- case 1:
- tmp = xinerama_edges;
- break;
- case 2:
- tmp = screen_edges;
- break;
- default:
- g_assert_not_reached ();
- }
-
- while (tmp)
- {
- MetaEdge *edge = tmp->data;
- switch (edge->side_type)
- {
- case META_DIRECTION_LEFT:
- case META_DIRECTION_RIGHT:
- g_array_append_val (edge_data->left_edges, edge);
- g_array_append_val (edge_data->right_edges, edge);
- break;
- case META_DIRECTION_TOP:
- case META_DIRECTION_BOTTOM:
- g_array_append_val (edge_data->top_edges, edge);
- g_array_append_val (edge_data->bottom_edges, edge);
- break;
- default:
- g_assert_not_reached ();
- }
- tmp = tmp->next;
- }
- }
-
- /*
- * 4th: Sort the arrays (FIXME: This is kinda dumb since the arrays were
- * individually sorted earlier and we could have done this faster and
- * avoided this sort by sticking them into the array with some simple
- * merging of the lists).
- */
- g_array_sort (display->grab_edge_resistance_data->left_edges,
- stupid_sort_requiring_extra_pointer_dereference);
- g_array_sort (display->grab_edge_resistance_data->right_edges,
- stupid_sort_requiring_extra_pointer_dereference);
- g_array_sort (display->grab_edge_resistance_data->top_edges,
- stupid_sort_requiring_extra_pointer_dereference);
- g_array_sort (display->grab_edge_resistance_data->bottom_edges,
- stupid_sort_requiring_extra_pointer_dereference);
-}
-
-static void
-initialize_grab_edge_resistance_data (MetaDisplay *display)
-{
- MetaEdgeResistanceData *edge_data = display->grab_edge_resistance_data;
-
- edge_data->left_data.timeout_setup = FALSE;
- edge_data->right_data.timeout_setup = FALSE;
- edge_data->top_data.timeout_setup = FALSE;
- edge_data->bottom_data.timeout_setup = FALSE;
-
- edge_data->left_data.keyboard_buildup = 0;
- edge_data->right_data.keyboard_buildup = 0;
- edge_data->top_data.keyboard_buildup = 0;
- edge_data->bottom_data.keyboard_buildup = 0;
-}
-
-void
-meta_display_compute_resistance_and_snapping_edges (MetaDisplay *display)
-{
- GList *stacked_windows;
- GList *cur_window_iter;
- GList *edges;
- /* Lists of window positions (rects) and their relative stacking positions */
- int stack_position;
- GSList *obscuring_windows, *window_stacking;
- /* The portions of the above lists that still remain at the stacking position
- * in the layer that we are working on
- */
- GSList *rem_windows, *rem_win_stacking;
-
- /*
- * 1st: Get the list of relevant windows, from bottom to top
- */
- stacked_windows =
- meta_stack_list_windows (display->grab_screen->stack,
- display->grab_screen->active_workspace);
-
- /*
- * 2nd: we need to separate that stacked list into a list of windows that
- * can obscure other edges. To make sure we only have windows obscuring
- * those below it instead of going both ways, we also need to keep a
- * counter list. Messy, I know.
- */
- obscuring_windows = window_stacking = NULL;
- cur_window_iter = stacked_windows;
- stack_position = 0;
- while (cur_window_iter != NULL)
- {
- MetaWindow *cur_window = cur_window_iter->data;
- if (WINDOW_EDGES_RELEVANT (cur_window, display))
- {
- MetaRectangle *new_rect;
- new_rect = g_new (MetaRectangle, 1);
- meta_window_get_outer_rect (cur_window, new_rect);
- obscuring_windows = g_slist_prepend (obscuring_windows, new_rect);
- window_stacking =
- g_slist_prepend (window_stacking, GINT_TO_POINTER (stack_position));
- }
-
- stack_position++;
- cur_window_iter = cur_window_iter->next;
- }
- /* Put 'em in bottom to top order */
- rem_windows = g_slist_reverse (obscuring_windows);
- rem_win_stacking = g_slist_reverse (window_stacking);
-
- /*
- * 3rd: loop over the windows again, this time getting the edges from
- * them and removing intersections with the relevant obscuring_windows &
- * obscuring_docks.
- */
- edges = NULL;
- stack_position = 0;
- cur_window_iter = stacked_windows;
- while (cur_window_iter != NULL)
- {
- MetaRectangle cur_rect;
- MetaWindow *cur_window = cur_window_iter->data;
- meta_window_get_outer_rect (cur_window, &cur_rect);
-
- /* Check if we want to use this window's edges for edge
- * resistance (note that dock edges are considered screen edges
- * which are handled separately
- */
- if (WINDOW_EDGES_RELEVANT (cur_window, display) &&
- cur_window->type != META_WINDOW_DOCK)
- {
- GList *new_edges;
- MetaEdge *new_edge;
- MetaRectangle reduced;
-
- /* We don't care about snapping to any portion of the window that
- * is offscreen (we also don't care about parts of edges covered
- * by other windows or DOCKS, but that's handled below).
- */
- meta_rectangle_intersect (&cur_rect,
- &display->grab_screen->rect,
- &reduced);
-
- new_edges = NULL;
-
- /* Left side of this window is resistance for the right edge of
- * the window being moved.
- */
- new_edge = g_new (MetaEdge, 1);
- new_edge->rect = reduced;
- new_edge->rect.width = 0;
- new_edge->side_type = META_DIRECTION_RIGHT;
- new_edge->edge_type = META_EDGE_WINDOW;
- new_edges = g_list_prepend (new_edges, new_edge);
-
- /* Right side of this window is resistance for the left edge of
- * the window being moved.
- */
- new_edge = g_new (MetaEdge, 1);
- new_edge->rect = reduced;
- new_edge->rect.x += new_edge->rect.width;
- new_edge->rect.width = 0;
- new_edge->side_type = META_DIRECTION_LEFT;
- new_edge->edge_type = META_EDGE_WINDOW;
- new_edges = g_list_prepend (new_edges, new_edge);
-
- /* Top side of this window is resistance for the bottom edge of
- * the window being moved.
- */
- new_edge = g_new (MetaEdge, 1);
- new_edge->rect = reduced;
- new_edge->rect.height = 0;
- new_edge->side_type = META_DIRECTION_BOTTOM;
- new_edge->edge_type = META_EDGE_WINDOW;
- new_edges = g_list_prepend (new_edges, new_edge);
-
- /* Top side of this window is resistance for the bottom edge of
- * the window being moved.
- */
- new_edge = g_new (MetaEdge, 1);
- new_edge->rect = reduced;
- new_edge->rect.y += new_edge->rect.height;
- new_edge->rect.height = 0;
- new_edge->side_type = META_DIRECTION_TOP;
- new_edge->edge_type = META_EDGE_WINDOW;
- new_edges = g_list_prepend (new_edges, new_edge);
-
- /* Update the remaining windows to only those at a higher
- * stacking position than this one.
- */
- while (rem_win_stacking &&
- stack_position >= GPOINTER_TO_INT (rem_win_stacking->data))
- {
- rem_windows = rem_windows->next;
- rem_win_stacking = rem_win_stacking->next;
- }
-
- /* Remove edge portions overlapped by rem_windows and rem_docks */
- new_edges =
- meta_rectangle_remove_intersections_with_boxes_from_edges (
- new_edges,
- rem_windows);
-
- /* Save the new edges */
- edges = g_list_concat (new_edges, edges);
- }
-
- stack_position++;
- cur_window_iter = cur_window_iter->next;
- }
-
- /*
- * 4th: Free the extra memory not needed and sort the list
- */
- g_list_free (stacked_windows);
- /* Free the memory used by the obscuring windows/docks lists */
- g_slist_free (window_stacking);
- /* FIXME: Shouldn't there be a helper function to make this one line of code
- * to free a list instead of four ugly ones?
- */
- g_slist_foreach (obscuring_windows,
- (void (*)(gpointer,gpointer))&g_free, /* ew, for ugly */
- NULL);
- g_slist_free (obscuring_windows);
-
- /* Sort the list. FIXME: Should I bother with this sorting? I just
- * sort again later in cache_edges() anyway...
- */
- edges = g_list_sort (edges, meta_rectangle_edge_cmp);
-
- /*
- * 5th: Cache the combination of these edges with the onscreen and
- * xinerama edges in an array for quick access. Free the edges since
- * they've been cached elsewhere.
- */
- cache_edges (display,
- edges,
- display->grab_screen->active_workspace->xinerama_edges,
- display->grab_screen->active_workspace->screen_edges);
- g_list_free (edges);
-
- /*
- * 6th: Initialize the resistance timeouts and buildups
- */
- initialize_grab_edge_resistance_data (display);
-}
-
-/* Note that old_[xy] and new_[xy] are with respect to inner positions of
- * the window.
- */
-void
-meta_window_edge_resistance_for_move (MetaWindow *window,
- int old_x,
- int old_y,
- int *new_x,
- int *new_y,
- GSourceFunc timeout_func,
- gboolean snap,
- gboolean is_keyboard_op)
-{
- MetaRectangle old_outer, proposed_outer, new_outer;
- gboolean is_resize;
-
- if (window == window->display->grab_window &&
- window->display->grab_wireframe_active)
- {
- meta_window_get_xor_rect (window,
- &window->display->grab_wireframe_rect,
- &old_outer);
- }
- else
- {
- meta_window_get_outer_rect (window, &old_outer);
- }
- proposed_outer = old_outer;
- proposed_outer.x += (*new_x - old_x);
- proposed_outer.y += (*new_y - old_y);
- new_outer = proposed_outer;
-
- window->display->grab_last_user_action_was_snap = snap;
- is_resize = FALSE;
- if (apply_edge_resistance_to_each_side (window->display,
- window,
- &old_outer,
- &new_outer,
- timeout_func,
- snap,
- is_keyboard_op,
- is_resize))
- {
- /* apply_edge_resistance_to_each_side independently applies
- * resistance to both the right and left edges of new_outer as both
- * could meet areas of resistance. But we don't want a resize, so we
- * just have both edges move according to the stricter of the
- * resistances. Same thing goes for top & bottom edges.
- */
- MetaRectangle *reference;
- int left_change, right_change, smaller_x_change;
- int top_change, bottom_change, smaller_y_change;
-
- if (snap && !is_keyboard_op)
- reference = &proposed_outer;
- else
- reference = &old_outer;
-
- left_change = BOX_LEFT (new_outer) - BOX_LEFT (*reference);
- right_change = BOX_RIGHT (new_outer) - BOX_RIGHT (*reference);
- if ( snap && is_keyboard_op && left_change == 0)
- smaller_x_change = right_change;
- else if (snap && is_keyboard_op && right_change == 0)
- smaller_x_change = left_change;
- else if (ABS (left_change) < ABS (right_change))
- smaller_x_change = left_change;
- else
- smaller_x_change = right_change;
-
- top_change = BOX_TOP (new_outer) - BOX_TOP (*reference);
- bottom_change = BOX_BOTTOM (new_outer) - BOX_BOTTOM (*reference);
- if ( snap && is_keyboard_op && top_change == 0)
- smaller_y_change = bottom_change;
- else if (snap && is_keyboard_op && bottom_change == 0)
- smaller_y_change = top_change;
- else if (ABS (top_change) < ABS (bottom_change))
- smaller_y_change = top_change;
- else
- smaller_y_change = bottom_change;
-
- *new_x = old_x + smaller_x_change +
- (BOX_LEFT (*reference) - BOX_LEFT (old_outer));
- *new_y = old_y + smaller_y_change +
- (BOX_TOP (*reference) - BOX_TOP (old_outer));
-
- meta_topic (META_DEBUG_EDGE_RESISTANCE,
- "outer x & y move-to coordinate changed from %d,%d to %d,%d\n",
- proposed_outer.x, proposed_outer.y,
- old_outer.x + (*new_x - old_x),
- old_outer.y + (*new_y - old_y));
- }
-}
-
-/* Note that old_(width|height) and new_(width|height) are with respect to
- * sizes of the inner window.
- */
-void
-meta_window_edge_resistance_for_resize (MetaWindow *window,
- int old_width,
- int old_height,
- int *new_width,
- int *new_height,
- int gravity,
- GSourceFunc timeout_func,
- gboolean snap,
- gboolean is_keyboard_op)
-{
- MetaRectangle old_outer, new_outer;
- int proposed_outer_width, proposed_outer_height;
- gboolean is_resize;
-
- if (window == window->display->grab_window &&
- window->display->grab_wireframe_active)
- {
- meta_window_get_xor_rect (window,
- &window->display->grab_wireframe_rect,
- &old_outer);
- }
- else
- {
- meta_window_get_outer_rect (window, &old_outer);
- }
- proposed_outer_width = old_outer.width + (*new_width - old_width);
- proposed_outer_height = old_outer.height + (*new_height - old_height);
- meta_rectangle_resize_with_gravity (&old_outer,
- &new_outer,
- gravity,
- proposed_outer_width,
- proposed_outer_height);
-
- window->display->grab_last_user_action_was_snap = snap;
- is_resize = TRUE;
- if (apply_edge_resistance_to_each_side (window->display,
- window,
- &old_outer,
- &new_outer,
- timeout_func,
- snap,
- is_keyboard_op,
- is_resize))
- {
- *new_width = old_width + (new_outer.width - old_outer.width);
- *new_height = old_height + (new_outer.height - old_outer.height);
-
- meta_topic (META_DEBUG_EDGE_RESISTANCE,
- "outer width & height got changed from %d,%d to %d,%d\n",
- proposed_outer_width, proposed_outer_height,
- new_outer.width, new_outer.height);
- }
-}
diff --git a/src/core/edge-resistance.h b/src/core/edge-resistance.h
deleted file mode 100644
index 14ba17a0..00000000
--- a/src/core/edge-resistance.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Edge resistance for move/resize operations */
-
-/*
- * Copyright (C) 2005 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_EDGE_RESISTANCE_H
-#define META_EDGE_RESISTANCE_H
-
-#include "window-private.h"
-
-void meta_window_edge_resistance_for_move (MetaWindow *window,
- int old_x,
- int old_y,
- int *new_x,
- int *new_y,
- GSourceFunc timeout_func,
- gboolean snap,
- gboolean is_keyboard_op);
-void meta_window_edge_resistance_for_resize (MetaWindow *window,
- int old_width,
- int old_height,
- int *new_width,
- int *new_height,
- int gravity,
- GSourceFunc timeout_func,
- gboolean snap,
- gboolean is_keyboard_op);
-
-#endif /* META_EDGE_RESISTANCE_H */
-
diff --git a/src/core/effects.c b/src/core/effects.c
deleted file mode 100644
index be369799..00000000
--- a/src/core/effects.c
+++ /dev/null
@@ -1,735 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * \file effects.c "Special effects" other than compositor effects.
- *
- * Before we had a serious compositor, we supported swooping
- * rectangles for minimising and so on. These are still supported
- * today, even when the compositor is enabled. The file contains two
- * parts:
- *
- * 1) A set of functions, each of which implements a special effect.
- * (Only the minimize function does anything interesting; we should
- * probably get rid of the rest.)
- *
- * 2) A set of functions for moving a highlighted wireframe box around
- * the screen, optionally with height and width shown in the middle.
- * This is used for moving and resizing when reduced_resources is set.
- *
- * There was formerly a system which allowed callers to drop in their
- * own handlers for various things; it was never used (people who want
- * their own handlers can just modify this file, after all) and it added
- * a good deal of extra complexity, so it has been removed. If you want it,
- * it can be found in svn r3769.
- *
- * Once upon a time there were three different ways of drawing the box
- * animation: window wireframe, window opaque, and root. People who had
- * the shape extension theoretically had the choice of all three, and
- * people who didn't weren't given the choice of the wireframe option.
- * In practice, though, the opaque animation was never perfect, so it came
- * down to the wireframe option for those who had the extension and
- * the root option for those who didn't; there was actually no way of choosing
- * any other option anyway. Work on the opaque animation stopped in 2002;
- * anyone who wants something like that these days will be using the
- * compositor anyway.
- *
- * In svn r3769 this was made explicit.
- */
-
-/*
- * Copyright (C) 2001 Anders Carlsson, Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include "effects.h"
-#include "display-private.h"
-#include "ui.h"
-#include "window-private.h"
-#include "prefs.h"
-
-#ifdef HAVE_SHAPE
-#include <X11/extensions/shape.h>
-#endif
-
-#define META_MINIMIZE_ANIMATION_LENGTH 0.25
-#define META_SHADE_ANIMATION_LENGTH 0.2
-
-#include <string.h>
-
-typedef struct MetaEffect MetaEffect;
-typedef struct MetaEffectPriv MetaEffectPriv;
-
-typedef struct
-{
- MetaScreen *screen;
-
- double millisecs_duration;
- GTimeVal start_time;
-
-#ifdef HAVE_SHAPE
- /** For wireframe window */
- Window wireframe_xwindow;
-#else
- /** Rectangle to erase */
- MetaRectangle last_rect;
-
- /** First time we've plotted anything in this animation? */
- gboolean first_time;
-
- /** For wireframe drawn on root window */
- GC gc;
-#endif
-
- MetaRectangle start_rect;
- MetaRectangle end_rect;
-
-} BoxAnimationContext;
-
-/**
- * Information we need to know during a maximise or minimise effect.
- */
-typedef struct
-{
- /** This is the normal-size window. */
- MetaRectangle window_rect;
- /** This is the size of the window when it's an icon. */
- MetaRectangle icon_rect;
-} MetaMinimizeEffect, MetaUnminimizeEffect;
-
-struct MetaEffectPriv
-{
- MetaEffectFinished finished;
- gpointer finished_data;
-};
-
-struct MetaEffect
-{
- /** The window the effect is applied to. */
- MetaWindow *window;
- /** Which effect is happening here. */
- MetaEffectType type;
- /** The effect handler can hang data here. */
- gpointer info;
-
- union
- {
- MetaMinimizeEffect minimize;
- /* ... and theoretically anything else */
- } u;
-
- MetaEffectPriv *priv;
-};
-
-static void run_default_effect_handler (MetaEffect *effect);
-static void run_handler (MetaEffect *effect);
-static void effect_free (MetaEffect *effect);
-
-static MetaEffect *
-create_effect (MetaEffectType type,
- MetaWindow *window,
- MetaEffectFinished finished,
- gpointer finished_data);
-
-static void
-draw_box_animation (MetaScreen *screen,
- MetaRectangle *initial_rect,
- MetaRectangle *destination_rect,
- double seconds_duration);
-
-/**
- * Creates an effect.
- *
- */
-static MetaEffect*
-create_effect (MetaEffectType type,
- MetaWindow *window,
- MetaEffectFinished finished,
- gpointer finished_data)
-{
- MetaEffect *effect = g_new (MetaEffect, 1);
-
- effect->type = type;
- effect->window = window;
- effect->priv = g_new (MetaEffectPriv, 1);
- effect->priv->finished = finished;
- effect->priv->finished_data = finished_data;
-
- return effect;
-}
-
-/**
- * Destroys an effect. If the effect has a "finished" hook, it will be
- * called before cleanup.
- *
- * \param effect The effect.
- */
-static void
-effect_free (MetaEffect *effect)
-{
- if (effect->priv->finished)
- effect->priv->finished (effect->priv->finished_data);
-
- g_free (effect->priv);
- g_free (effect);
-}
-
-void
-meta_effect_run_focus (MetaWindow *window,
- MetaEffectFinished finished,
- gpointer data)
-{
- MetaEffect *effect;
-
- g_return_if_fail (window != NULL);
-
- effect = create_effect (META_EFFECT_FOCUS, window, finished, data);
-
- run_handler (effect);
-}
-
-void
-meta_effect_run_minimize (MetaWindow *window,
- MetaRectangle *window_rect,
- MetaRectangle *icon_rect,
- MetaEffectFinished finished,
- gpointer data)
-{
- MetaEffect *effect;
-
- g_return_if_fail (window != NULL);
- g_return_if_fail (icon_rect != NULL);
-
- effect = create_effect (META_EFFECT_MINIMIZE, window, finished, data);
-
- effect->u.minimize.window_rect = *window_rect;
- effect->u.minimize.icon_rect = *icon_rect;
-
- run_handler (effect);
-}
-
-void
-meta_effect_run_unminimize (MetaWindow *window,
- MetaRectangle *window_rect,
- MetaRectangle *icon_rect,
- MetaEffectFinished finished,
- gpointer data)
-{
- MetaEffect *effect;
-
- g_return_if_fail (window != NULL);
- g_return_if_fail (icon_rect != NULL);
-
- effect = create_effect (META_EFFECT_UNMINIMIZE, window, finished, data);
-
- effect->u.minimize.window_rect = *window_rect;
- effect->u.minimize.icon_rect = *icon_rect;
-
- run_handler (effect);
-}
-
-void
-meta_effect_run_close (MetaWindow *window,
- MetaEffectFinished finished,
- gpointer data)
-{
- MetaEffect *effect;
-
- g_return_if_fail (window != NULL);
-
- effect = create_effect (META_EFFECT_CLOSE, window,
- finished, data);
-
- run_handler (effect);
-}
-
-
-/* old ugly minimization effect */
-
-#ifdef HAVE_SHAPE
-static void
-update_wireframe_window (MetaDisplay *display,
- Window xwindow,
- const MetaRectangle *rect)
-{
- XMoveResizeWindow (display->xdisplay,
- xwindow,
- rect->x, rect->y,
- rect->width, rect->height);
-
-#define OUTLINE_WIDTH 3
-
- if (rect->width > OUTLINE_WIDTH * 2 &&
- rect->height > OUTLINE_WIDTH * 2)
- {
- XRectangle xrect;
- Region inner_xregion;
- Region outer_xregion;
-
- inner_xregion = XCreateRegion ();
- outer_xregion = XCreateRegion ();
-
- xrect.x = 0;
- xrect.y = 0;
- xrect.width = rect->width;
- xrect.height = rect->height;
-
- XUnionRectWithRegion (&xrect, outer_xregion, outer_xregion);
-
- xrect.x += OUTLINE_WIDTH;
- xrect.y += OUTLINE_WIDTH;
- xrect.width -= OUTLINE_WIDTH * 2;
- xrect.height -= OUTLINE_WIDTH * 2;
-
- XUnionRectWithRegion (&xrect, inner_xregion, inner_xregion);
-
- XSubtractRegion (outer_xregion, inner_xregion, outer_xregion);
-
- XShapeCombineRegion (display->xdisplay, xwindow,
- ShapeBounding, 0, 0, outer_xregion, ShapeSet);
-
- XDestroyRegion (outer_xregion);
- XDestroyRegion (inner_xregion);
- }
- else
- {
- /* Unset the shape */
- XShapeCombineMask (display->xdisplay, xwindow,
- ShapeBounding, 0, 0, None, ShapeSet);
- }
-}
-#endif
-
-/**
- * A hack to force the X server to synchronize with the
- * graphics hardware.
- */
-static void
-graphics_sync (BoxAnimationContext *context)
-{
- XImage *image;
-
- image = XGetImage (context->screen->display->xdisplay,
- context->screen->xroot,
- 0, 0, 1, 1,
- AllPlanes, ZPixmap);
-
- XDestroyImage (image);
-}
-
-static gboolean
-effects_draw_box_animation_timeout (BoxAnimationContext *context)
-{
- double elapsed;
- GTimeVal current_time;
- MetaRectangle draw_rect;
- double fraction;
-
-#ifndef HAVE_SHAPE
- if (!context->first_time)
- {
- /* Restore the previously drawn background */
- XDrawRectangle (context->screen->display->xdisplay,
- context->screen->xroot,
- context->gc,
- context->last_rect.x, context->last_rect.y,
- context->last_rect.width, context->last_rect.height);
- }
- else
- context->first_time = FALSE;
-
-#endif /* !HAVE_SHAPE */
-
- g_get_current_time (&current_time);
-
- /* We use milliseconds for all times */
- elapsed =
- ((((double)current_time.tv_sec - context->start_time.tv_sec) * G_USEC_PER_SEC +
- (current_time.tv_usec - context->start_time.tv_usec))) / 1000.0;
-
- if (elapsed < 0)
- {
- /* Probably the system clock was set backwards? */
- meta_warning ("System clock seemed to go backwards?\n");
- elapsed = G_MAXDOUBLE; /* definitely done. */
- }
-
- if (elapsed > context->millisecs_duration)
- {
- /* All done */
-#ifdef HAVE_SHAPE
- XDestroyWindow (context->screen->display->xdisplay,
- context->wireframe_xwindow);
-#else
- meta_display_ungrab (context->screen->display);
- meta_ui_pop_delay_exposes (context->screen->ui);
- XFreeGC (context->screen->display->xdisplay,
- context->gc);
-#endif /* !HAVE_SHAPE */
-
- graphics_sync (context);
-
- g_free (context);
- return FALSE;
- }
-
- g_assert (context->millisecs_duration > 0.0);
- fraction = elapsed / context->millisecs_duration;
-
- draw_rect = context->start_rect;
-
- /* Now add a delta proportional to elapsed time. */
- draw_rect.x += (context->end_rect.x - context->start_rect.x) * fraction;
- draw_rect.y += (context->end_rect.y - context->start_rect.y) * fraction;
- draw_rect.width += (context->end_rect.width - context->start_rect.width) * fraction;
- draw_rect.height += (context->end_rect.height - context->start_rect.height) * fraction;
-
- /* don't confuse X or gdk-pixbuf with bogus rectangles */
- if (draw_rect.width < 1)
- draw_rect.width = 1;
- if (draw_rect.height < 1)
- draw_rect.height = 1;
-
-#ifdef HAVE_SHAPE
- update_wireframe_window (context->screen->display,
- context->wireframe_xwindow,
- &draw_rect);
-#else
- context->last_rect = draw_rect;
-
- /* Draw the rectangle */
- XDrawRectangle (context->screen->display->xdisplay,
- context->screen->xroot,
- context->gc,
- draw_rect.x, draw_rect.y,
- draw_rect.width, draw_rect.height);
-
-#endif /* !HAVE_SHAPE */
-
- /* kick changes onto the server */
- graphics_sync (context);
-
- return TRUE;
-}
-
-void
-draw_box_animation (MetaScreen *screen,
- MetaRectangle *initial_rect,
- MetaRectangle *destination_rect,
- double seconds_duration)
-{
- BoxAnimationContext *context;
-
-#ifdef HAVE_SHAPE
- XSetWindowAttributes attrs;
-#else
- XGCValues gc_values;
-#endif
-
- g_return_if_fail (seconds_duration > 0.0);
-
- if (g_getenv ("METACITY_DEBUG_EFFECTS"))
- seconds_duration *= 10; /* slow things down */
-
- /* Create the animation context */
- context = g_new0 (BoxAnimationContext, 1);
-
- context->screen = screen;
-
- context->millisecs_duration = seconds_duration * 1000.0;
-
- context->start_rect = *initial_rect;
- context->end_rect = *destination_rect;
-
-#ifdef HAVE_SHAPE
-
- attrs.override_redirect = True;
- attrs.background_pixel = BlackPixel (screen->display->xdisplay,
- screen->number);
-
- context->wireframe_xwindow = XCreateWindow (screen->display->xdisplay,
- screen->xroot,
- initial_rect->x,
- initial_rect->y,
- initial_rect->width,
- initial_rect->height,
- 0,
- CopyFromParent,
- CopyFromParent,
- (Visual *)CopyFromParent,
- CWOverrideRedirect | CWBackPixel,
- &attrs);
-
- update_wireframe_window (screen->display,
- context->wireframe_xwindow,
- initial_rect);
-
- XMapWindow (screen->display->xdisplay,
- context->wireframe_xwindow);
-
-#else /* !HAVE_SHAPE */
-
- context->first_time = TRUE;
- gc_values.subwindow_mode = IncludeInferiors;
- gc_values.function = GXinvert;
-
- context->gc = XCreateGC (screen->display->xdisplay,
- screen->xroot,
- GCSubwindowMode | GCFunction,
- &gc_values);
-
- /* Grab the X server to avoid screen dirt */
- meta_display_grab (context->screen->display);
- meta_ui_push_delay_exposes (context->screen->ui);
-#endif
-
- /* Do this only after we get the pixbuf from the server,
- * so that the animation doesn't get truncated.
- */
- g_get_current_time (&context->start_time);
-
- /* Add the timeout - a short one, could even use an idle,
- * but this is maybe more CPU-friendly.
- */
- g_timeout_add (15,
- (GSourceFunc)effects_draw_box_animation_timeout,
- context);
-
- /* kick changes onto the server */
- XFlush (context->screen->display->xdisplay);
-}
-
-void
-meta_effects_begin_wireframe (MetaScreen *screen,
- const MetaRectangle *rect,
- int width,
- int height)
-{
- /* Grab the X server to avoid screen dirt */
- meta_display_grab (screen->display);
- meta_ui_push_delay_exposes (screen->ui);
-
- meta_effects_update_wireframe (screen,
- NULL, -1, -1,
- rect, width, height);
-}
-
-static void
-draw_xor_rect (MetaScreen *screen,
- const MetaRectangle *rect,
- int width,
- int height)
-{
- /* The lines in the center can't overlap the rectangle or each
- * other, or the XOR gets reversed. So we have to draw things
- * a bit oddly.
- */
- XSegment segments[8];
- MetaRectangle shrunk_rect;
- int i;
-
-#define LINE_WIDTH META_WIREFRAME_XOR_LINE_WIDTH
-
- /* We don't want the wireframe going outside the window area.
- * It makes it harder for the user to position windows and it exposes other
- * annoying bugs.
- */
- shrunk_rect = *rect;
-
- shrunk_rect.x += LINE_WIDTH / 2 + LINE_WIDTH % 2;
- shrunk_rect.y += LINE_WIDTH / 2 + LINE_WIDTH % 2;
- shrunk_rect.width -= LINE_WIDTH + 2 * (LINE_WIDTH % 2);
- shrunk_rect.height -= LINE_WIDTH + 2 * (LINE_WIDTH % 2);
-
- XDrawRectangle (screen->display->xdisplay,
- screen->xroot,
- screen->root_xor_gc,
- shrunk_rect.x, shrunk_rect.y,
- shrunk_rect.width, shrunk_rect.height);
-
- /* Don't put lines inside small rectangles where they won't fit */
- if (shrunk_rect.width < (LINE_WIDTH * 4) ||
- shrunk_rect.height < (LINE_WIDTH * 4))
- return;
-
- if ((width >= 0) && (height >= 0))
- {
- XGCValues gc_values = { 0 };
-
- if (XGetGCValues (screen->display->xdisplay,
- screen->root_xor_gc,
- GCFont, &gc_values))
- {
- char *text;
- int text_length;
-
- XFontStruct *font_struct;
- int text_width, text_height;
- int box_x, box_y;
- int box_width, box_height;
-
- font_struct = XQueryFont (screen->display->xdisplay,
- gc_values.font);
-
- if (font_struct != NULL)
- {
- text = g_strdup_printf ("%d x %d", width, height);
- text_length = strlen (text);
-
- text_width = text_length * font_struct->max_bounds.width;
- text_height = font_struct->max_bounds.descent +
- font_struct->max_bounds.ascent;
-
- box_width = text_width + 2 * LINE_WIDTH;
- box_height = text_height + 2 * LINE_WIDTH;
-
-
- box_x = shrunk_rect.x + (shrunk_rect.width - box_width) / 2;
- box_y = shrunk_rect.y + (shrunk_rect.height - box_height) / 2;
-
- if ((box_width < shrunk_rect.width) &&
- (box_height < shrunk_rect.height))
- {
- XFillRectangle (screen->display->xdisplay,
- screen->xroot,
- screen->root_xor_gc,
- box_x, box_y,
- box_width, box_height);
- XDrawString (screen->display->xdisplay,
- screen->xroot,
- screen->root_xor_gc,
- box_x + LINE_WIDTH,
- box_y + LINE_WIDTH + font_struct->max_bounds.ascent,
- text, text_length);
- }
-
- g_free (text);
-
- XFreeFontInfo (NULL, font_struct, 1);
-
- if ((box_width + LINE_WIDTH) >= (shrunk_rect.width / 3))
- return;
-
- if ((box_height + LINE_WIDTH) >= (shrunk_rect.height / 3))
- return;
- }
- }
- }
-
- /* Two vertical lines at 1/3 and 2/3 */
- segments[0].x1 = shrunk_rect.x + shrunk_rect.width / 3;
- segments[0].y1 = shrunk_rect.y + LINE_WIDTH / 2 + LINE_WIDTH % 2;
- segments[0].x2 = segments[0].x1;
- segments[0].y2 = shrunk_rect.y + shrunk_rect.height - LINE_WIDTH / 2;
-
- segments[1] = segments[0];
- segments[1].x1 = shrunk_rect.x + (shrunk_rect.width / 3) * 2;
- segments[1].x2 = segments[1].x1;
-
- /* Now make two horizontal lines at 1/3 and 2/3, but not
- * overlapping the verticals
- */
-
- segments[2].x1 = shrunk_rect.x + LINE_WIDTH / 2 + LINE_WIDTH % 2;
- segments[2].x2 = segments[0].x1 - LINE_WIDTH / 2;
- segments[2].y1 = shrunk_rect.y + shrunk_rect.height / 3;
- segments[2].y2 = segments[2].y1;
-
- segments[3] = segments[2];
- segments[3].x1 = segments[2].x2 + LINE_WIDTH;
- segments[3].x2 = segments[1].x1 - LINE_WIDTH / 2;
-
- segments[4] = segments[3];
- segments[4].x1 = segments[3].x2 + LINE_WIDTH;
- segments[4].x2 = shrunk_rect.x + shrunk_rect.width - LINE_WIDTH / 2;
-
- /* Second horizontal line is just like the first, but
- * shifted down
- */
- i = 5;
- while (i < 8)
- {
- segments[i] = segments[i - 3];
- segments[i].y1 = shrunk_rect.y + (shrunk_rect.height / 3) * 2;
- segments[i].y2 = segments[i].y1;
- ++i;
- }
-
- XDrawSegments (screen->display->xdisplay,
- screen->xroot,
- screen->root_xor_gc,
- segments,
- G_N_ELEMENTS (segments));
-}
-
-void
-meta_effects_update_wireframe (MetaScreen *screen,
- const MetaRectangle *old_rect,
- int old_width,
- int old_height,
- const MetaRectangle *new_rect,
- int new_width,
- int new_height)
-{
- if (old_rect)
- draw_xor_rect (screen, old_rect, old_width, old_height);
-
- if (new_rect)
- draw_xor_rect (screen, new_rect, new_width, new_height);
-
- XFlush (screen->display->xdisplay);
-}
-
-void
-meta_effects_end_wireframe (MetaScreen *screen,
- const MetaRectangle *old_rect,
- int old_width,
- int old_height)
-{
- meta_effects_update_wireframe (screen,
- old_rect, old_width, old_height,
- NULL, -1, -1);
-
- meta_display_ungrab (screen->display);
- meta_ui_pop_delay_exposes (screen->ui);
-}
-
-static void
-run_default_effect_handler (MetaEffect *effect)
-{
- switch (effect->type)
- {
- case META_EFFECT_MINIMIZE:
- draw_box_animation (effect->window->screen,
- &(effect->u.minimize.window_rect),
- &(effect->u.minimize.icon_rect),
- META_MINIMIZE_ANIMATION_LENGTH);
- break;
-
- default:
- break;
- }
-}
-
-static void
-run_handler (MetaEffect *effect)
-{
- if (meta_prefs_get_gnome_animations ())
- run_default_effect_handler (effect);
-
- effect_free (effect);
-}
diff --git a/src/core/effects.h b/src/core/effects.h
deleted file mode 100644
index 91d09e15..00000000
--- a/src/core/effects.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * \file effects.h "Special effects" other than compositor effects.
- *
- * Before we had a serious compositor, we supported swooping
- * rectangles for minimising and so on. These are still supported
- * today, even when the compositor is enabled. The file contains two
- * parts:
- *
- * 1) A set of functions, each of which implements a special effect.
- * (Only the minimize function does anything interesting; we should
- * probably get rid of the rest.)
- *
- * 2) A set of functions for moving a highlighted wireframe box around
- * the screen, optionally with height and width shown in the middle.
- * This is used for moving and resizing when reduced_resources is set.
- *
- * There was formerly a system which allowed callers to drop in their
- * own handlers for various things; it was never used (people who want
- * their own handlers can just modify this file, after all) and it added
- * a good deal of extra complexity, so it has been removed. If you want it,
- * it can be found in svn r3769.
- */
-
-/*
- * Copyright (C) 2001 Anders Carlsson, Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_EFFECTS_H
-#define META_EFFECTS_H
-
-#include "util.h"
-#include "screen-private.h"
-
-typedef enum
-{
- META_EFFECT_MINIMIZE,
- META_EFFECT_UNMINIMIZE,
- META_EFFECT_FOCUS,
- META_EFFECT_CLOSE,
- META_NUM_EFFECTS
-} MetaEffectType;
-
-/**
- * A callback which will be called when the effect has finished.
- */
-typedef void (* MetaEffectFinished) (gpointer data);
-
-/**
- * Performs the minimize effect.
- *
- * \param window The window we're moving
- * \param window_rect Its current state
- * \param target Where it should end up
- * \param finished Callback for when it's finished
- * \param data Data for callback
- */
-void meta_effect_run_minimize (MetaWindow *window,
- MetaRectangle *window_rect,
- MetaRectangle *target,
- MetaEffectFinished finished,
- gpointer data);
-
-/**
- * Performs the unminimize effect. There is no such effect.
- * FIXME: delete this.
- *
- * \param window The window we're moving
- * \param icon_rect Its current state
- * \param window_rect Where it should end up
- * \param finished Callback for when it's finished
- * \param data Data for callback
- */
-void meta_effect_run_unminimize (MetaWindow *window,
- MetaRectangle *window_rect,
- MetaRectangle *icon_rect,
- MetaEffectFinished finished,
- gpointer data);
-
-/**
- * Performs the close effect. There is no such effect.
- * FIXME: delete this.
- *
- * \param window The window we're moving
- * \param finished Callback for when it's finished
- * \param data Data for callback
- */
-void meta_effect_run_close (MetaWindow *window,
- MetaEffectFinished finished,
- gpointer data);
-
-/**
- * Performs the focus effect. There is no such effect.
- * FIXME: delete this.
- *
- * \param window The window we're moving
- * \param finished Callback for when it's finished
- * \param data Data for callback
- */
-void meta_effect_run_focus (MetaWindow *window,
- MetaEffectFinished finished,
- gpointer data);
-
-/**
- * Grabs the server and paints a wireframe rectangle on the screen.
- * Since this involves starting a grab, please be considerate of other
- * users and don't keep the grab for long. You may move the wireframe
- * around using meta_effects_update_wireframe() and remove it, and undo
- * the grab, using meta_effects_end_wireframe().
- *
- * \param screen The screen to draw the rectangle on.
- * \param rect The size of the rectangle to draw.
- * \param width The width to display in the middle (or 0 not to)
- * \param height The width to display in the middle (or 0 not to)
- */
-void meta_effects_begin_wireframe (MetaScreen *screen,
- const MetaRectangle *rect,
- int width,
- int height);
-
-/**
- * Moves a wireframe rectangle around after its creation by
- * meta_effects_begin_wireframe(). (Perhaps we ought to remember the old
- * positions and not require people to pass them in?)
- *
- * \param old_rect Where the rectangle is now
- * \param old_width The width that was displayed on it (or 0 if there wasn't)
- * \param old_height The height that was displayed on it (or 0 if there wasn't)
- * \param new_rect Where the rectangle is going
- * \param new_width The width that will be displayed on it (or 0 not to)
- * \param new_height The height that will be displayed on it (or 0 not to)
- */
-void meta_effects_update_wireframe (MetaScreen *screen,
- const MetaRectangle *old_rect,
- int old_width,
- int old_height,
- const MetaRectangle *new_rect,
- int new_width,
- int new_height);
-
-/**
- * Removes a wireframe rectangle from the screen and ends the grab started by
- * meta_effects_begin_wireframe().
- *
- * \param old_rect Where the rectangle is now
- * \param old_width The width that was displayed on it (or 0 if there wasn't)
- * \param old_height The height that was displayed on it (or 0 if there wasn't)
- */
-void meta_effects_end_wireframe (MetaScreen *screen,
- const MetaRectangle *old_rect,
- int width,
- int height);
-
-#endif /* META_EFFECTS_H */
diff --git a/src/core/errors.c b/src/core/errors.c
deleted file mode 100644
index 8de46080..00000000
--- a/src/core/errors.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity X error handling */
-
-/*
- * Copyright (C) 2001 Havoc Pennington, error trapping inspired by GDK
- * code copyrighted by the GTK team.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include "errors.h"
-#include "display-private.h"
-#include <errno.h>
-#include <stdlib.h>
-#include <gdk/gdk.h>
-
-static int x_error_handler (Display *display,
- XErrorEvent *error);
-static int x_io_error_handler (Display *display);
-
-void
-meta_errors_init (void)
-{
- XSetErrorHandler (x_error_handler);
- XSetIOErrorHandler (x_io_error_handler);
-}
-
-typedef struct ForeignDisplay ForeignDisplay;
-
-struct ForeignDisplay
-{
- Display *dpy;
- ErrorHandler handler;
- gpointer data;
- ForeignDisplay *next;
-};
-
-static ForeignDisplay *foreign_displays;
-
-void
-meta_errors_register_foreign_display (Display *foreign_dpy,
- ErrorHandler handler,
- gpointer data)
-{
- ForeignDisplay *info = g_new0 (ForeignDisplay, 1);
- info->dpy = foreign_dpy;
- info->handler = handler;
- info->data = data;
- info->next = foreign_displays;
- foreign_displays = info;
-}
-
-static void
-meta_error_trap_push_internal (MetaDisplay *display,
- gboolean need_sync)
-{
- /* GDK resets the error handler on each push */
- int (* old_error_handler) (Display *,
- XErrorEvent *);
-
- if (need_sync)
- {
- XSync (display->xdisplay, False);
- }
-
- gdk_error_trap_push ();
-
- /* old_error_handler will just be equal to x_error_handler
- * for nested traps
- */
- old_error_handler = XSetErrorHandler (x_error_handler);
-
- /* Replace GDK handler, but save it so we can chain up */
- if (display->error_trap_handler == NULL)
- {
- g_assert (display->error_traps == 0);
- display->error_trap_handler = old_error_handler;
- g_assert (display->error_trap_handler != x_error_handler);
- }
-
- display->error_traps += 1;
-
- meta_topic (META_DEBUG_ERRORS, "%d traps remain\n", display->error_traps);
-}
-
-static int
-meta_error_trap_pop_internal (MetaDisplay *display,
- gboolean need_sync)
-{
- int result;
-
- g_assert (display->error_traps > 0);
-
- if (need_sync)
- {
- XSync (display->xdisplay, False);
- }
-
- result = gdk_error_trap_pop ();
-
- display->error_traps -= 1;
-
- if (display->error_traps == 0)
- {
- /* check that GDK put our handler back; this
- * assumes that there are no pending GDK traps from GDK itself
- */
-
- int (* restored_error_handler) (Display *,
- XErrorEvent *);
-
- restored_error_handler = XSetErrorHandler (x_error_handler);
-
- /* remove this */
- display->error_trap_handler = NULL;
- }
-
- meta_topic (META_DEBUG_ERRORS, "%d traps\n", display->error_traps);
-
- return result;
-}
-
-void
-meta_error_trap_push (MetaDisplay *display)
-{
- meta_error_trap_push_internal (display, FALSE);
-}
-
-void
-meta_error_trap_pop (MetaDisplay *display,
- gboolean last_request_was_roundtrip)
-{
- gboolean need_sync;
-
- /* we only have to sync when popping the outermost trap */
- need_sync = (display->error_traps == 1 && !last_request_was_roundtrip);
-
- if (need_sync)
- meta_topic (META_DEBUG_SYNC, "Syncing on error_trap_pop, traps = %d, roundtrip = %d\n",
- display->error_traps, last_request_was_roundtrip);
-
- display->error_trap_synced_at_last_pop = need_sync || last_request_was_roundtrip;
-
- meta_error_trap_pop_internal (display, need_sync);
-}
-
-void
-meta_error_trap_push_with_return (MetaDisplay *display)
-{
- gboolean need_sync;
-
- /* We don't sync on push_with_return if there are no traps
- * currently, because we assume that any errors were either covered
- * by a previous pop, or were fatal.
- *
- * More generally, we don't sync if we were synchronized last time
- * we popped. This is known to be the case if there are no traps,
- * but we also keep a flag so we know whether it's the case otherwise.
- */
-
- if (!display->error_trap_synced_at_last_pop)
- need_sync = TRUE;
- else
- need_sync = FALSE;
-
- if (need_sync)
- meta_topic (META_DEBUG_SYNC, "Syncing on error_trap_push_with_return, traps = %d\n",
- display->error_traps);
-
- meta_error_trap_push_internal (display, FALSE);
-}
-
-int
-meta_error_trap_pop_with_return (MetaDisplay *display,
- gboolean last_request_was_roundtrip)
-{
- if (!last_request_was_roundtrip)
- meta_topic (META_DEBUG_SYNC, "Syncing on error_trap_pop_with_return, traps = %d, roundtrip = %d\n",
- display->error_traps, last_request_was_roundtrip);
-
- display->error_trap_synced_at_last_pop = TRUE;
-
- return meta_error_trap_pop_internal (display,
- !last_request_was_roundtrip);
-}
-
-static int
-x_error_handler (Display *xdisplay,
- XErrorEvent *error)
-{
- int retval;
- gchar buf[64];
- MetaDisplay *display;
- ForeignDisplay *foreign;
-
- for (foreign = foreign_displays; foreign != NULL; foreign = foreign->next)
- {
- if (foreign->dpy == xdisplay)
- {
- foreign->handler (xdisplay, error, foreign->data);
-
- return 0;
- }
- }
-
- XGetErrorText (xdisplay, error->error_code, buf, 63);
-
- display = meta_display_for_x_display (xdisplay);
-
- /* Display can be NULL here because the compositing manager
- * has its own Display, but Xlib only has one global error handler
- */
- if (display->error_traps > 0)
- {
- /* we're in an error trap, chain to the trap handler
- * saved from GDK
- */
- meta_verbose ("X error: %s serial %ld error_code %d request_code %d minor_code %d)\n",
- buf,
- error->serial,
- error->error_code,
- error->request_code,
- error->minor_code);
-
- g_assert (display->error_trap_handler != NULL);
- g_assert (display->error_trap_handler != x_error_handler);
-
- retval = (* display->error_trap_handler) (xdisplay, error);
- }
- else
- {
- meta_bug ("Unexpected X error: %s serial %ld error_code %d request_code %d minor_code %d)\n",
- buf,
- error->serial,
- error->error_code,
- error->request_code,
- error->minor_code);
-
- retval = 1; /* compiler warning */
- }
-
- return retval;
-}
-
-static int
-x_io_error_handler (Display *xdisplay)
-{
- MetaDisplay *display;
-
- display = meta_display_for_x_display (xdisplay);
-
- if (display == NULL)
- meta_bug ("IO error received for unknown display?\n");
-
- if (errno == EPIPE)
- {
- meta_warning (_("Lost connection to the display '%s';\n"
- "most likely the X server was shut down or you killed/destroyed\n"
- "the window manager.\n"),
- display->name);
- }
- else
- {
- meta_warning (_("Fatal IO error %d (%s) on display '%s'.\n"),
- errno, g_strerror (errno),
- display->name);
- }
-
- /* Xlib would force an exit anyhow */
- exit (1);
-
- return 0;
-}
diff --git a/src/core/eventqueue.c b/src/core/eventqueue.c
deleted file mode 100644
index 4ce3e46a..00000000
--- a/src/core/eventqueue.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity X event source for main loop */
-
-/*
- * Copyright (C) 2001 Havoc Pennington (based on GDK code (C) Owen
- * Taylor, Red Hat Inc.)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA. */
-
-#include "eventqueue.h"
-#include <X11/Xlib.h>
-
-static gboolean eq_prepare (GSource *source,
- gint *timeout);
-static gboolean eq_check (GSource *source);
-static gboolean eq_dispatch (GSource *source,
- GSourceFunc callback,
- gpointer user_data);
-static void eq_destroy (GSource *source);
-
-static GSourceFuncs eq_funcs = {
- eq_prepare,
- eq_check,
- eq_dispatch,
- eq_destroy
-};
-
-struct _MetaEventQueue
-{
- GSource source;
-
- Display *display;
- GPollFD poll_fd;
- int connection_fd;
- GQueue *events;
-};
-
-MetaEventQueue*
-meta_event_queue_new (Display *display, MetaEventQueueFunc func, gpointer data)
-{
- GSource *source;
- MetaEventQueue *eq;
-
- source = g_source_new (&eq_funcs, sizeof (MetaEventQueue));
- eq = (MetaEventQueue*) source;
-
- eq->connection_fd = ConnectionNumber (display);
- eq->poll_fd.fd = eq->connection_fd;
- eq->poll_fd.events = G_IO_IN;
-
- eq->events = g_queue_new ();
-
- eq->display = display;
-
- g_source_set_priority (source, G_PRIORITY_DEFAULT);
- g_source_add_poll (source, &eq->poll_fd);
- g_source_set_can_recurse (source, TRUE);
-
- g_source_set_callback (source, (GSourceFunc) func, data, NULL);
-
- g_source_attach (source, NULL);
- g_source_unref (source);
-
- return eq;
-}
-
-void
-meta_event_queue_free (MetaEventQueue *eq)
-{
- GSource *source;
-
- source = (GSource*) eq;
-
- g_source_destroy (source);
-}
-
-static gboolean
-eq_events_pending (MetaEventQueue *eq)
-{
- return eq->events->length > 0 || XPending (eq->display);
-}
-
-static void
-eq_queue_events (MetaEventQueue *eq)
-{
- XEvent xevent;
-
- while (XPending (eq->display))
- {
- XEvent *copy;
-
- XNextEvent (eq->display, &xevent);
-
- copy = g_new (XEvent, 1);
- *copy = xevent;
-
- g_queue_push_tail (eq->events, copy);
- }
-}
-
-static gboolean
-eq_prepare (GSource *source, gint *timeout)
-{
- MetaEventQueue *eq;
-
- eq = (MetaEventQueue*) source;
-
- *timeout = -1;
-
- return eq_events_pending (eq);
-}
-
-static gboolean
-eq_check (GSource *source)
-{
- MetaEventQueue *eq;
-
- eq = (MetaEventQueue*) source;
-
- if (eq->poll_fd.revents & G_IO_IN)
- return eq_events_pending (eq);
- else
- return FALSE;
-}
-
-static gboolean
-eq_dispatch (GSource *source, GSourceFunc callback, gpointer user_data)
-{
- MetaEventQueue *eq;
-
- eq = (MetaEventQueue*) source;
-
- eq_queue_events (eq);
-
- if (eq->events->length > 0)
- {
- XEvent *event;
- MetaEventQueueFunc func;
-
- event = g_queue_pop_head (eq->events);
- func = (MetaEventQueueFunc) callback;
-
- (* func) (event, user_data);
-
- g_free (event);
- }
-
- return TRUE;
-}
-
-static void
-eq_destroy (GSource *source)
-{
- MetaEventQueue *eq;
-
- eq = (MetaEventQueue*) source;
-
- while (eq->events->length > 0)
- {
- XEvent *event;
-
- event = g_queue_pop_head (eq->events);
-
- g_free (event);
- }
-
- g_queue_free (eq->events);
-
- /* source itself is freed by glib */
-}
diff --git a/src/core/eventqueue.h b/src/core/eventqueue.h
deleted file mode 100644
index cd115bdb..00000000
--- a/src/core/eventqueue.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity X event source for main loop */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_EVENT_QUEUE_H
-#define META_EVENT_QUEUE_H
-
-#include <glib.h>
-#include <X11/Xlib.h>
-
-typedef struct _MetaEventQueue MetaEventQueue;
-
-typedef void (* MetaEventQueueFunc) (XEvent *event,
- gpointer data);
-
-MetaEventQueue* meta_event_queue_new (Display *display,
- MetaEventQueueFunc func,
- gpointer data);
-void meta_event_queue_free (MetaEventQueue *eq);
-
-#endif
diff --git a/src/core/frame-private.h b/src/core/frame-private.h
deleted file mode 100644
index cba9b52a..00000000
--- a/src/core/frame-private.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity X window decorations */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_FRAME_PRIVATE_H
-#define META_FRAME_PRIVATE_H
-
-#include "frame.h"
-#include "window-private.h"
-
-typedef struct _MetaFrameGeometry MetaFrameGeometry;
-
-struct _MetaFrameGeometry
-{
- /* border sizes (space between frame and child) */
- int left_width;
- int right_width;
- int top_height;
- int bottom_height;
-};
-
-struct _MetaFrame
-{
- /* window we frame */
- MetaWindow *window;
-
- /* reparent window */
- Window xwindow;
-
- MetaCursor current_cursor;
-
- /* This rect is trusted info from where we put the
- * frame, not the result of ConfigureNotify
- */
- MetaRectangle rect;
-
- /* position of client, size of frame */
- int child_x;
- int child_y;
- int right_width;
- int bottom_height;
-
- guint mapped : 1;
- guint need_reapply_frame_shape : 1;
- guint is_flashing : 1; /* used by the visual bell flash */
-};
-
-void meta_window_ensure_frame (MetaWindow *window);
-void meta_window_destroy_frame (MetaWindow *window);
-void meta_frame_queue_draw (MetaFrame *frame);
-
-MetaFrameFlags meta_frame_get_flags (MetaFrame *frame);
-
-/* These should ONLY be called from meta_window_move_resize_internal */
-void meta_frame_calc_geometry (MetaFrame *frame,
- MetaFrameGeometry *geomp);
-void meta_frame_sync_to_window (MetaFrame *frame,
- int gravity,
- gboolean need_move,
- gboolean need_resize);
-
-void meta_frame_set_screen_cursor (MetaFrame *frame,
- MetaCursor cursor);
-
-#endif
-
-
-
-
diff --git a/src/core/frame.c b/src/core/frame.c
deleted file mode 100644
index d2bf62fc..00000000
--- a/src/core/frame.c
+++ /dev/null
@@ -1,420 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity X window decorations */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2003, 2004 Red Hat, Inc.
- * Copyright (C) 2005 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include "frame-private.h"
-#include "bell.h"
-#include "errors.h"
-#include "keybindings.h"
-
-#ifdef HAVE_RENDER
-#include <X11/extensions/Xrender.h>
-#endif
-
-#define EVENT_MASK (SubstructureRedirectMask | \
- StructureNotifyMask | SubstructureNotifyMask | \
- ExposureMask | \
- ButtonPressMask | ButtonReleaseMask | \
- PointerMotionMask | PointerMotionHintMask | \
- EnterWindowMask | LeaveWindowMask | \
- FocusChangeMask | \
- ColormapChangeMask)
-
-void
-meta_window_ensure_frame (MetaWindow *window)
-{
- MetaFrame *frame;
- XSetWindowAttributes attrs;
- Visual *visual;
-
- if (window->frame)
- return;
-
- /* See comment below for why this is required. */
- meta_display_grab (window->display);
-
- frame = g_new (MetaFrame, 1);
-
- frame->window = window;
- frame->xwindow = None;
-
- frame->rect = window->rect;
- frame->child_x = 0;
- frame->child_y = 0;
- frame->bottom_height = 0;
- frame->right_width = 0;
- frame->current_cursor = 0;
-
- frame->mapped = FALSE;
- frame->need_reapply_frame_shape = TRUE;
- frame->is_flashing = FALSE;
-
- meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n",
- window->desc,
- XVisualIDFromVisual (window->xvisual) ==
- XVisualIDFromVisual (window->screen->default_xvisual) ?
- "is" : "is not",
- window->depth, window->screen->default_depth);
- meta_verbose ("Frame geometry %d,%d %dx%d\n",
- frame->rect.x, frame->rect.y,
- frame->rect.width, frame->rect.height);
-
- /* Default depth/visual handles clients with weird visuals; they can
- * always be children of the root depth/visual obviously, but
- * e.g. DRI games can't be children of a parent that has the same
- * visual as the client. NULL means default visual.
- *
- * We look for an ARGB visual if we can find one, otherwise use
- * the default of NULL.
- */
-
- /* Special case for depth 32 windows (assumed to be ARGB),
- * we use the window's visual. Otherwise we just use the system visual.
- */
- if (window->depth == 32)
- visual = window->xvisual;
- else
- visual = NULL;
-
- frame->xwindow = meta_ui_create_frame_window (window->screen->ui,
- window->display->xdisplay,
- visual,
- frame->rect.x,
- frame->rect.y,
- frame->rect.width,
- frame->rect.height,
- frame->window->screen->number);
-
- meta_verbose ("Frame for %s is 0x%lx\n", frame->window->desc, frame->xwindow);
- attrs.event_mask = EVENT_MASK;
- XChangeWindowAttributes (window->display->xdisplay,
- frame->xwindow, CWEventMask, &attrs);
-
- meta_display_register_x_window (window->display, &frame->xwindow, window);
-
- /* Now that frame->xwindow is registered with window, we can set its
- * background.
- */
- meta_ui_reset_frame_bg (window->screen->ui, frame->xwindow);
-
- /* Reparent the client window; it may be destroyed,
- * thus the error trap. We'll get a destroy notify later
- * and free everything. Comment in FVWM source code says
- * we need a server grab or the child can get its MapNotify
- * before we've finished reparenting and getting the decoration
- * window onscreen, so ensure_frame must be called with
- * a grab.
- */
- meta_error_trap_push (window->display);
- if (window->mapped)
- {
- window->mapped = FALSE; /* the reparent will unmap the window,
- * we don't want to take that as a withdraw
- */
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Incrementing unmaps_pending on %s for reparent\n", window->desc);
- window->unmaps_pending += 1;
- }
- /* window was reparented to this position */
- window->rect.x = 0;
- window->rect.y = 0;
-
- XReparentWindow (window->display->xdisplay,
- window->xwindow,
- frame->xwindow,
- window->rect.x,
- window->rect.y);
- /* FIXME handle this error */
- meta_error_trap_pop (window->display, FALSE);
-
- /* stick frame to the window */
- window->frame = frame;
-
- if (window->title)
- meta_ui_set_frame_title (window->screen->ui,
- window->frame->xwindow,
- window->title);
-
- /* Move keybindings to frame instead of window */
- meta_window_grab_keys (window);
-
- /* Shape mask */
- meta_ui_apply_frame_shape (frame->window->screen->ui,
- frame->xwindow,
- frame->rect.width,
- frame->rect.height,
- frame->window->has_shape);
- frame->need_reapply_frame_shape = FALSE;
-
- meta_display_ungrab (window->display);
-}
-
-void
-meta_window_destroy_frame (MetaWindow *window)
-{
- MetaFrame *frame;
-
- if (window->frame == NULL)
- return;
-
- meta_verbose ("Unframing window %s\n", window->desc);
-
- frame = window->frame;
-
- meta_bell_notify_frame_destroy (frame);
-
- /* Unparent the client window; it may be destroyed,
- * thus the error trap.
- */
- meta_error_trap_push (window->display);
- if (window->mapped)
- {
- window->mapped = FALSE; /* Keep track of unmapping it, so we
- * can identify a withdraw initiated
- * by the client.
- */
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Incrementing unmaps_pending on %s for reparent back to root\n", window->desc);
- window->unmaps_pending += 1;
- }
- XReparentWindow (window->display->xdisplay,
- window->xwindow,
- window->screen->xroot,
- /* Using anything other than meta_window_get_position()
- * coordinates here means we'll need to ensure a configure
- * notify event is sent; see bug 399552.
- */
- window->frame->rect.x,
- window->frame->rect.y);
- meta_error_trap_pop (window->display, FALSE);
-
- meta_ui_destroy_frame_window (window->screen->ui, frame->xwindow);
-
- meta_display_unregister_x_window (window->display,
- frame->xwindow);
-
- window->frame = NULL;
-
- /* Move keybindings to window instead of frame */
- meta_window_grab_keys (window);
-
- g_free (frame);
-
- /* Put our state back where it should be */
- meta_window_queue (window, META_QUEUE_CALC_SHOWING);
-}
-
-
-MetaFrameFlags
-meta_frame_get_flags (MetaFrame *frame)
-{
- MetaFrameFlags flags;
-
- flags = 0;
-
- if (frame->window->border_only)
- {
- ; /* FIXME this may disable the _function_ as well as decor
- * in some cases, which is sort of wrong.
- */
- }
- else
- {
- flags |= META_FRAME_ALLOWS_MENU;
-
- if (frame->window->has_close_func)
- flags |= META_FRAME_ALLOWS_DELETE;
-
- if (frame->window->has_maximize_func)
- flags |= META_FRAME_ALLOWS_MAXIMIZE;
-
- if (frame->window->has_minimize_func)
- flags |= META_FRAME_ALLOWS_MINIMIZE;
-
- if (frame->window->has_shade_func)
- flags |= META_FRAME_ALLOWS_SHADE;
- }
-
- if (META_WINDOW_ALLOWS_MOVE (frame->window))
- flags |= META_FRAME_ALLOWS_MOVE;
-
- if (META_WINDOW_ALLOWS_HORIZONTAL_RESIZE (frame->window))
- flags |= META_FRAME_ALLOWS_HORIZONTAL_RESIZE;
-
- if (META_WINDOW_ALLOWS_VERTICAL_RESIZE (frame->window))
- flags |= META_FRAME_ALLOWS_VERTICAL_RESIZE;
-
- if (frame->window->has_focus)
- flags |= META_FRAME_HAS_FOCUS;
-
- if (frame->window->shaded)
- flags |= META_FRAME_SHADED;
-
- if (frame->window->on_all_workspaces)
- flags |= META_FRAME_STUCK;
-
- /* FIXME: Should we have some kind of UI for windows that are just vertically
- * maximized or just horizontally maximized?
- */
- if (META_WINDOW_MAXIMIZED (frame->window))
- flags |= META_FRAME_MAXIMIZED;
-
- if (frame->window->fullscreen)
- flags |= META_FRAME_FULLSCREEN;
-
- if (frame->is_flashing)
- flags |= META_FRAME_IS_FLASHING;
-
- if (frame->window->wm_state_above)
- flags |= META_FRAME_ABOVE;
-
- return flags;
-}
-
-void
-meta_frame_calc_geometry (MetaFrame *frame,
- MetaFrameGeometry *geomp)
-{
- MetaFrameGeometry geom;
- MetaWindow *window;
-
- window = frame->window;
-
- meta_ui_get_frame_geometry (window->screen->ui,
- frame->xwindow,
- &geom.top_height,
- &geom.bottom_height,
- &geom.left_width,
- &geom.right_width);
-
- *geomp = geom;
-}
-
-static void
-update_shape (MetaFrame *frame)
-{
- if (frame->need_reapply_frame_shape)
- {
- meta_ui_apply_frame_shape (frame->window->screen->ui,
- frame->xwindow,
- frame->rect.width,
- frame->rect.height,
- frame->window->has_shape);
- frame->need_reapply_frame_shape = FALSE;
- }
-}
-
-void
-meta_frame_sync_to_window (MetaFrame *frame,
- int resize_gravity,
- gboolean need_move,
- gboolean need_resize)
-{
- if (!(need_move || need_resize))
- {
- update_shape (frame);
- return;
- }
-
- meta_topic (META_DEBUG_GEOMETRY,
- "Syncing frame geometry %d,%d %dx%d (SE: %d,%d)\n",
- frame->rect.x, frame->rect.y,
- frame->rect.width, frame->rect.height,
- frame->rect.x + frame->rect.width,
- frame->rect.y + frame->rect.height);
-
- /* set bg to none to avoid flicker */
- if (need_resize)
- {
- meta_ui_unflicker_frame_bg (frame->window->screen->ui,
- frame->xwindow,
- frame->rect.width,
- frame->rect.height);
-
- /* we need new shape if we're resized */
- frame->need_reapply_frame_shape = TRUE;
- }
-
- /* Done before the window resize, because doing it before means
- * part of the window being resized becomes unshaped, which may
- * be sort of hard to see with bg = None. If we did it after
- * window resize, part of the window being resized would become
- * shaped, which might be more visible.
- */
- update_shape (frame);
-
- meta_ui_move_resize_frame (frame->window->screen->ui,
- frame->xwindow,
- frame->rect.x,
- frame->rect.y,
- frame->rect.width,
- frame->rect.height);
-
- if (need_resize)
- {
- meta_ui_reset_frame_bg (frame->window->screen->ui,
- frame->xwindow);
-
- /* If we're interactively resizing the frame, repaint
- * it immediately so we don't start to lag.
- */
- if (frame->window->display->grab_window ==
- frame->window)
- meta_ui_repaint_frame (frame->window->screen->ui,
- frame->xwindow);
- }
-}
-
-void
-meta_frame_queue_draw (MetaFrame *frame)
-{
- meta_ui_queue_frame_draw (frame->window->screen->ui,
- frame->xwindow);
-}
-
-void
-meta_frame_set_screen_cursor (MetaFrame *frame,
- MetaCursor cursor)
-{
- Cursor xcursor;
- if (cursor == frame->current_cursor)
- return;
- frame->current_cursor = cursor;
- if (cursor == META_CURSOR_DEFAULT)
- XUndefineCursor (frame->window->display->xdisplay, frame->xwindow);
- else
- {
- xcursor = meta_display_create_x_cursor (frame->window->display, cursor);
- XDefineCursor (frame->window->display->xdisplay, frame->xwindow, xcursor);
- XFlush (frame->window->display->xdisplay);
- XFreeCursor (frame->window->display->xdisplay, xcursor);
- }
-}
-
-Window
-meta_frame_get_xwindow (MetaFrame *frame)
-{
- return frame->xwindow;
-}
diff --git a/src/core/group-private.h b/src/core/group-private.h
deleted file mode 100644
index 25b05c77..00000000
--- a/src/core/group-private.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity window group private header */
-
-/*
- * Copyright (C) 2002 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_GROUP_PRIVATE_H
-#define META_GROUP_PRIVATE_H
-
-#include "group.h"
-
-struct _MetaGroup
-{
- int refcount;
- MetaDisplay *display;
- GSList *windows;
- Window group_leader;
- char *startup_id;
- char *wm_client_machine;
-};
-
-#endif
-
-
-
-
diff --git a/src/core/group-props.c b/src/core/group-props.c
deleted file mode 100644
index 05e82900..00000000
--- a/src/core/group-props.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* MetaGroup property handling */
-
-/*
- * Copyright (C) 2002 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include "group-props.h"
-#include "group-private.h"
-#include "xprops.h"
-#include <X11/Xatom.h>
-
-typedef void (* InitValueFunc) (MetaDisplay *display,
- Atom property,
- MetaPropValue *value);
-typedef void (* ReloadValueFunc) (MetaGroup *group,
- MetaPropValue *value);
-
-struct _MetaGroupPropHooks
-{
- Atom property;
- InitValueFunc init_func;
- ReloadValueFunc reload_func;
-};
-
-static void init_prop_value (MetaDisplay *display,
- Atom property,
- MetaPropValue *value);
-static void reload_prop_value (MetaGroup *group,
- MetaPropValue *value);
-static MetaGroupPropHooks* find_hooks (MetaDisplay *display,
- Atom property);
-
-
-
-void
-meta_group_reload_property (MetaGroup *group,
- Atom property)
-{
- meta_group_reload_properties (group, &property, 1);
-}
-
-void
-meta_group_reload_properties (MetaGroup *group,
- const Atom *properties,
- int n_properties)
-{
- int i;
- MetaPropValue *values;
-
- g_return_if_fail (properties != NULL);
- g_return_if_fail (n_properties > 0);
-
- values = g_new0 (MetaPropValue, n_properties);
-
- i = 0;
- while (i < n_properties)
- {
- init_prop_value (group->display, properties[i], &values[i]);
- ++i;
- }
-
- meta_prop_get_values (group->display, group->group_leader,
- values, n_properties);
-
- i = 0;
- while (i < n_properties)
- {
- reload_prop_value (group, &values[i]);
-
- ++i;
- }
-
- meta_prop_free_values (values, n_properties);
-
- g_free (values);
-}
-
-/* Fill in the MetaPropValue used to get the value of "property" */
-static void
-init_prop_value (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- MetaGroupPropHooks *hooks;
-
- value->type = META_PROP_VALUE_INVALID;
- value->atom = None;
-
- hooks = find_hooks (display, property);
- if (hooks && hooks->init_func != NULL)
- (* hooks->init_func) (display, property, value);
-}
-
-static void
-reload_prop_value (MetaGroup *group,
- MetaPropValue *value)
-{
- MetaGroupPropHooks *hooks;
-
- hooks = find_hooks (group->display, value->atom);
- if (hooks && hooks->reload_func != NULL)
- (* hooks->reload_func) (group, value);
-}
-
-static void
-init_wm_client_machine (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_STRING;
- value->atom = display->atom_WM_CLIENT_MACHINE;
-}
-
-static void
-reload_wm_client_machine (MetaGroup *group,
- MetaPropValue *value)
-{
- g_free (group->wm_client_machine);
- group->wm_client_machine = NULL;
-
- if (value->type != META_PROP_VALUE_INVALID)
- group->wm_client_machine = g_strdup (value->v.str);
-
- meta_verbose ("Group has client machine \"%s\"\n",
- group->wm_client_machine ? group->wm_client_machine : "unset");
-}
-
-static void
-init_net_startup_id (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_UTF8;
- value->atom = display->atom__NET_STARTUP_ID;
-}
-
-static void
-reload_net_startup_id (MetaGroup *group,
- MetaPropValue *value)
-{
- g_free (group->startup_id);
- group->startup_id = NULL;
-
- if (value->type != META_PROP_VALUE_INVALID)
- group->startup_id = g_strdup (value->v.str);
-
- meta_verbose ("Group has startup id \"%s\"\n",
- group->startup_id ? group->startup_id : "unset");
-}
-
-#define N_HOOKS 3
-
-void
-meta_display_init_group_prop_hooks (MetaDisplay *display)
-{
- int i;
- MetaGroupPropHooks *hooks;
-
- g_assert (display->group_prop_hooks == NULL);
-
- display->group_prop_hooks = g_new0 (MetaGroupPropHooks, N_HOOKS);
- hooks = display->group_prop_hooks;
-
- i = 0;
-
- hooks[i].property = display->atom_WM_CLIENT_MACHINE;
- hooks[i].init_func = init_wm_client_machine;
- hooks[i].reload_func = reload_wm_client_machine;
- ++i;
-
- hooks[i].property = display->atom__NET_WM_PID;
- hooks[i].init_func = NULL;
- hooks[i].reload_func = NULL;
- ++i;
-
- hooks[i].property = display->atom__NET_STARTUP_ID;
- hooks[i].init_func = init_net_startup_id;
- hooks[i].reload_func = reload_net_startup_id;
- ++i;
-
- if (i != N_HOOKS)
- {
- g_error ("Initialized %d group hooks should have been %d\n", i, N_HOOKS);
- }
-}
-
-void
-meta_display_free_group_prop_hooks (MetaDisplay *display)
-{
- g_assert (display->group_prop_hooks != NULL);
-
- g_free (display->group_prop_hooks);
- display->group_prop_hooks = NULL;
-}
-
-static MetaGroupPropHooks*
-find_hooks (MetaDisplay *display,
- Atom property)
-{
- int i;
-
- /* FIXME we could sort the array and do binary search or
- * something
- */
-
- i = 0;
- while (i < N_HOOKS)
- {
- if (display->group_prop_hooks[i].property == property)
- return &display->group_prop_hooks[i];
-
- ++i;
- }
-
- return NULL;
-}
diff --git a/src/core/group-props.h b/src/core/group-props.h
deleted file mode 100644
index ffde0901..00000000
--- a/src/core/group-props.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* MetaGroup property handling */
-
-/*
- * Copyright (C) 2002 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_GROUP_PROPS_H
-#define META_GROUP_PROPS_H
-
-#include "group.h"
-
-void meta_group_reload_property (MetaGroup *group,
- Atom property);
-void meta_group_reload_properties (MetaGroup *group,
- const Atom *properties,
- int n_properties);
-void meta_display_init_group_prop_hooks (MetaDisplay *display);
-void meta_display_free_group_prop_hooks (MetaDisplay *display);
-
-#endif /* META_GROUP_PROPS_H */
diff --git a/src/core/group.c b/src/core/group.c
deleted file mode 100644
index 69c879ee..00000000
--- a/src/core/group.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity window groups */
-
-/*
- * Copyright (C) 2002 Red Hat Inc.
- * Copyright (C) 2003 Rob Adams
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include "util.h"
-#include "group-private.h"
-#include "group-props.h"
-#include "window.h"
-
-static MetaGroup*
-meta_group_new (MetaDisplay *display,
- Window group_leader)
-{
- MetaGroup *group;
-#define N_INITIAL_PROPS 3
- Atom initial_props[N_INITIAL_PROPS];
- int i;
-
- g_assert (N_INITIAL_PROPS == (int) G_N_ELEMENTS (initial_props));
-
- group = g_new0 (MetaGroup, 1);
-
- group->display = display;
- group->windows = NULL;
- group->group_leader = group_leader;
- group->refcount = 1; /* owned by caller, hash table has only weak ref */
-
- if (display->groups_by_leader == NULL)
- display->groups_by_leader = g_hash_table_new (meta_unsigned_long_hash,
- meta_unsigned_long_equal);
-
- g_assert (g_hash_table_lookup (display->groups_by_leader, &group_leader) == NULL);
-
- g_hash_table_insert (display->groups_by_leader,
- &group->group_leader,
- group);
-
- /* Fill these in the order we want them to be gotten */
- i = 0;
- initial_props[i++] = display->atom_WM_CLIENT_MACHINE;
- initial_props[i++] = display->atom__NET_WM_PID;
- initial_props[i++] = display->atom__NET_STARTUP_ID;
- g_assert (N_INITIAL_PROPS == i);
-
- meta_group_reload_properties (group, initial_props, N_INITIAL_PROPS);
-
- meta_topic (META_DEBUG_GROUPS,
- "Created new group with leader 0x%lx\n",
- group->group_leader);
-
- return group;
-}
-
-static void
-meta_group_unref (MetaGroup *group)
-{
- g_return_if_fail (group->refcount > 0);
-
- group->refcount -= 1;
- if (group->refcount == 0)
- {
- meta_topic (META_DEBUG_GROUPS,
- "Destroying group with leader 0x%lx\n",
- group->group_leader);
-
- g_assert (group->display->groups_by_leader != NULL);
-
- g_hash_table_remove (group->display->groups_by_leader,
- &group->group_leader);
-
- /* mop up hash table, this is how it gets freed on display close */
- if (g_hash_table_size (group->display->groups_by_leader) == 0)
- {
- g_hash_table_destroy (group->display->groups_by_leader);
- group->display->groups_by_leader = NULL;
- }
-
- g_free (group->wm_client_machine);
- g_free (group->startup_id);
-
- g_free (group);
- }
-}
-
-MetaGroup*
-meta_window_get_group (MetaWindow *window)
-{
- if (window->unmanaging)
- return NULL;
-
- return window->group;
-}
-
-void
-meta_window_compute_group (MetaWindow* window)
-{
- MetaGroup *group;
- MetaWindow *ancestor;
-
- /* use window->xwindow if no window->xgroup_leader */
-
- group = NULL;
-
- /* Determine the ancestor of the window; its group setting will override the
- * normal grouping rules; see bug 328211.
- */
- ancestor = meta_window_find_root_ancestor (window);
-
- if (window->display->groups_by_leader)
- {
- if (ancestor != window)
- group = ancestor->group;
- else if (window->xgroup_leader != None)
- group = g_hash_table_lookup (window->display->groups_by_leader,
- &window->xgroup_leader);
- else
- group = g_hash_table_lookup (window->display->groups_by_leader,
- &window->xwindow);
- }
-
- if (group != NULL)
- {
- window->group = group;
- group->refcount += 1;
- }
- else
- {
- if (ancestor != window && ancestor->xgroup_leader != None)
- group = meta_group_new (window->display,
- ancestor->xgroup_leader);
- else if (window->xgroup_leader != None)
- group = meta_group_new (window->display,
- window->xgroup_leader);
- else
- group = meta_group_new (window->display,
- window->xwindow);
-
- window->group = group;
- }
-
- window->group->windows = g_slist_prepend (window->group->windows, window);
-
- meta_topic (META_DEBUG_GROUPS,
- "Adding %s to group with leader 0x%lx\n",
- window->desc, group->group_leader);
-
-}
-
-static void
-remove_window_from_group (MetaWindow *window)
-{
- if (window->group != NULL)
- {
- meta_topic (META_DEBUG_GROUPS,
- "Removing %s from group with leader 0x%lx\n",
- window->desc, window->group->group_leader);
-
- window->group->windows =
- g_slist_remove (window->group->windows,
- window);
- meta_group_unref (window->group);
- window->group = NULL;
- }
-}
-
-void
-meta_window_group_leader_changed (MetaWindow *window)
-{
- remove_window_from_group (window);
- meta_window_compute_group (window);
-}
-
-void
-meta_window_shutdown_group (MetaWindow *window)
-{
- remove_window_from_group (window);
-}
-
-MetaGroup*
-meta_display_lookup_group (MetaDisplay *display,
- Window group_leader)
-{
- MetaGroup *group;
-
- group = NULL;
-
- if (display->groups_by_leader)
- group = g_hash_table_lookup (display->groups_by_leader,
- &group_leader);
-
- return group;
-}
-
-GSList*
-meta_group_list_windows (MetaGroup *group)
-{
- return g_slist_copy (group->windows);
-}
-
-void
-meta_group_update_layers (MetaGroup *group)
-{
- GSList *tmp;
- GSList *frozen_stacks;
-
- if (group->windows == NULL)
- return;
-
- frozen_stacks = NULL;
- tmp = group->windows;
- while (tmp != NULL)
- {
- MetaWindow *window = tmp->data;
-
- /* we end up freezing the same stack a lot of times,
- * but doesn't hurt anything. have to handle
- * groups that span 2 screens.
- */
- meta_stack_freeze (window->screen->stack);
- frozen_stacks = g_slist_prepend (frozen_stacks, window->screen->stack);
-
- meta_stack_update_layer (window->screen->stack,
- window);
-
- tmp = tmp->next;
- }
-
- tmp = frozen_stacks;
- while (tmp != NULL)
- {
- meta_stack_thaw (tmp->data);
- tmp = tmp->next;
- }
-
- g_slist_free (frozen_stacks);
-}
-
-const char*
-meta_group_get_startup_id (MetaGroup *group)
-{
- return group->startup_id;
-}
-
-gboolean
-meta_group_property_notify (MetaGroup *group,
- XEvent *event)
-{
- meta_group_reload_property (group,
- event->xproperty.atom);
-
- return TRUE;
-
-}
diff --git a/src/core/group.h b/src/core/group.h
deleted file mode 100644
index 562ac59b..00000000
--- a/src/core/group.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity window groups */
-
-/*
- * Copyright (C) 2002 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_GROUP_H
-#define META_GROUP_H
-
-#include "window-private.h"
-
-/* note, can return NULL */
-MetaGroup* meta_window_get_group (MetaWindow *window);
-void meta_window_compute_group (MetaWindow* window);
-void meta_window_shutdown_group (MetaWindow *window);
-
-void meta_window_group_leader_changed (MetaWindow *window);
-
-/* note, can return NULL */
-MetaGroup* meta_display_lookup_group (MetaDisplay *display,
- Window group_leader);
-
-GSList* meta_group_list_windows (MetaGroup *group);
-
-void meta_group_update_layers (MetaGroup *group);
-
-const char* meta_group_get_startup_id (MetaGroup *group);
-
-gboolean meta_group_property_notify (MetaGroup *group,
- XEvent *event);
-
-#endif
-
-
-
-
diff --git a/src/core/iconcache.c b/src/core/iconcache.c
deleted file mode 100644
index 7fa21840..00000000
--- a/src/core/iconcache.c
+++ /dev/null
@@ -1,849 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity window icons */
-
-/*
- * Copyright (C) 2002 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include "iconcache.h"
-#include "ui.h"
-#include "errors.h"
-
-#include <X11/Xatom.h>
-
-/* The icon-reading code is also in libwnck, please sync bugfixes */
-
-static void
-get_fallback_icons (MetaScreen *screen,
- GdkPixbuf **iconp,
- int ideal_width,
- int ideal_height,
- GdkPixbuf **mini_iconp,
- int ideal_mini_width,
- int ideal_mini_height)
-{
- /* we don't scale, should be fixed if we ever un-hardcode the icon
- * size
- */
- *iconp = meta_ui_get_default_window_icon (screen->ui);
- *mini_iconp = meta_ui_get_default_mini_icon (screen->ui);
-}
-
-static gboolean
-find_largest_sizes (gulong *data,
- gulong nitems,
- int *width,
- int *height)
-{
- *width = 0;
- *height = 0;
-
- while (nitems > 0)
- {
- int w, h;
-
- if (nitems < 3)
- return FALSE; /* no space for w, h */
-
- w = data[0];
- h = data[1];
-
- if (nitems < ((gulong)(w * h) + 2))
- return FALSE; /* not enough data */
-
- *width = MAX (w, *width);
- *height = MAX (h, *height);
-
- data += (w * h) + 2;
- nitems -= (w * h) + 2;
- }
-
- return TRUE;
-}
-
-static gboolean
-find_best_size (gulong *data,
- gulong nitems,
- int ideal_width,
- int ideal_height,
- int *width,
- int *height,
- gulong **start)
-{
- int best_w;
- int best_h;
- gulong *best_start;
- int max_width, max_height;
-
- *width = 0;
- *height = 0;
- *start = NULL;
-
- if (!find_largest_sizes (data, nitems, &max_width, &max_height))
- return FALSE;
-
- if (ideal_width < 0)
- ideal_width = max_width;
- if (ideal_height < 0)
- ideal_height = max_height;
-
- best_w = 0;
- best_h = 0;
- best_start = NULL;
-
- while (nitems > 0)
- {
- int w, h;
- gboolean replace;
-
- replace = FALSE;
-
- if (nitems < 3)
- return FALSE; /* no space for w, h */
-
- w = data[0];
- h = data[1];
-
- if (nitems < ((gulong)(w * h) + 2))
- break; /* not enough data */
-
- if (best_start == NULL)
- {
- replace = TRUE;
- }
- else
- {
- /* work with averages */
- const int ideal_size = (ideal_width + ideal_height) / 2;
- int best_size = (best_w + best_h) / 2;
- int this_size = (w + h) / 2;
-
- /* larger than desired is always better than smaller */
- if (best_size < ideal_size &&
- this_size >= ideal_size)
- replace = TRUE;
- /* if we have too small, pick anything bigger */
- else if (best_size < ideal_size &&
- this_size > best_size)
- replace = TRUE;
- /* if we have too large, pick anything smaller
- * but still >= the ideal
- */
- else if (best_size > ideal_size &&
- this_size >= ideal_size &&
- this_size < best_size)
- replace = TRUE;
- }
-
- if (replace)
- {
- best_start = data + 2;
- best_w = w;
- best_h = h;
- }
-
- data += (w * h) + 2;
- nitems -= (w * h) + 2;
- }
-
- if (best_start)
- {
- *start = best_start;
- *width = best_w;
- *height = best_h;
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static void
-argbdata_to_pixdata (gulong *argb_data, int len, guchar **pixdata)
-{
- guchar *p;
- int i;
-
- *pixdata = g_new (guchar, len * 4);
- p = *pixdata;
-
- /* One could speed this up a lot. */
- i = 0;
- while (i < len)
- {
- guint argb;
- guint rgba;
-
- argb = argb_data[i];
- rgba = (argb << 8) | (argb >> 24);
-
- *p = rgba >> 24;
- ++p;
- *p = (rgba >> 16) & 0xff;
- ++p;
- *p = (rgba >> 8) & 0xff;
- ++p;
- *p = rgba & 0xff;
- ++p;
-
- ++i;
- }
-}
-
-static gboolean
-read_rgb_icon (MetaDisplay *display,
- Window xwindow,
- int ideal_width,
- int ideal_height,
- int ideal_mini_width,
- int ideal_mini_height,
- int *width,
- int *height,
- guchar **pixdata,
- int *mini_width,
- int *mini_height,
- guchar **mini_pixdata)
-{
- Atom type;
- int format;
- gulong nitems;
- gulong bytes_after;
- int result, err;
- guchar *data;
- gulong *best;
- int w, h;
- gulong *best_mini;
- int mini_w, mini_h;
- gulong *data_as_long;
-
- meta_error_trap_push_with_return (display);
- type = None;
- data = NULL;
- result = XGetWindowProperty (display->xdisplay,
- xwindow,
- display->atom__NET_WM_ICON,
- 0, G_MAXLONG,
- False, XA_CARDINAL, &type, &format, &nitems,
- &bytes_after, &data);
- err = meta_error_trap_pop_with_return (display, TRUE);
-
- if (err != Success ||
- result != Success)
- return FALSE;
-
- if (type != XA_CARDINAL)
- {
- XFree (data);
- return FALSE;
- }
-
- data_as_long = (gulong *)data;
-
- if (!find_best_size (data_as_long, nitems,
- ideal_width, ideal_height,
- &w, &h, &best))
- {
- XFree (data);
- return FALSE;
- }
-
- if (!find_best_size (data_as_long, nitems,
- ideal_mini_width, ideal_mini_height,
- &mini_w, &mini_h, &best_mini))
- {
- XFree (data);
- return FALSE;
- }
-
- *width = w;
- *height = h;
-
- *mini_width = mini_w;
- *mini_height = mini_h;
-
- argbdata_to_pixdata (best, w * h, pixdata);
- argbdata_to_pixdata (best_mini, mini_w * mini_h, mini_pixdata);
-
- XFree (data);
-
- return TRUE;
-}
-
-static void
-free_pixels (guchar *pixels, gpointer data)
-{
- g_free (pixels);
-}
-
-static void
-get_pixmap_geometry (MetaDisplay *display,
- Pixmap pixmap,
- int *w,
- int *h,
- int *d)
-{
- Window root_ignored;
- int x_ignored, y_ignored;
- guint width, height;
- guint border_width_ignored;
- guint depth;
-
- if (w)
- *w = 1;
- if (h)
- *h = 1;
- if (d)
- *d = 1;
-
- XGetGeometry (display->xdisplay,
- pixmap, &root_ignored, &x_ignored, &y_ignored,
- &width, &height, &border_width_ignored, &depth);
-
- if (w)
- *w = width;
- if (h)
- *h = height;
- if (d)
- *d = depth;
-}
-
-static GdkPixbuf*
-apply_mask (GdkPixbuf *pixbuf,
- GdkPixbuf *mask)
-{
- int w, h;
- int i, j;
- GdkPixbuf *with_alpha;
- guchar *src;
- guchar *dest;
- int src_stride;
- int dest_stride;
-
- w = MIN (gdk_pixbuf_get_width (mask), gdk_pixbuf_get_width (pixbuf));
- h = MIN (gdk_pixbuf_get_height (mask), gdk_pixbuf_get_height (pixbuf));
-
- with_alpha = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
-
- dest = gdk_pixbuf_get_pixels (with_alpha);
- src = gdk_pixbuf_get_pixels (mask);
-
- dest_stride = gdk_pixbuf_get_rowstride (with_alpha);
- src_stride = gdk_pixbuf_get_rowstride (mask);
-
- i = 0;
- while (i < h)
- {
- j = 0;
- while (j < w)
- {
- guchar *s = src + i * src_stride + j * 3;
- guchar *d = dest + i * dest_stride + j * 4;
-
- /* s[0] == s[1] == s[2], they are 255 if the bit was set, 0
- * otherwise
- */
- if (s[0] == 0)
- d[3] = 0; /* transparent */
- else
- d[3] = 255; /* opaque */
-
- ++j;
- }
-
- ++i;
- }
-
- return with_alpha;
-}
-
-static gboolean
-try_pixmap_and_mask (MetaDisplay *display,
- Pixmap src_pixmap,
- Pixmap src_mask,
- GdkPixbuf **iconp,
- int ideal_width,
- int ideal_height,
- GdkPixbuf **mini_iconp,
- int ideal_mini_width,
- int ideal_mini_height)
-{
- GdkPixbuf *unscaled = NULL;
- GdkPixbuf *mask = NULL;
- int w, h;
-
- if (src_pixmap == None)
- return FALSE;
-
- meta_error_trap_push (display);
-
- get_pixmap_geometry (display, src_pixmap, &w, &h, NULL);
-
- unscaled = meta_gdk_pixbuf_get_from_pixmap (NULL,
- src_pixmap,
- 0, 0, 0, 0,
- w, h);
-
- if (unscaled && src_mask != None)
- {
- get_pixmap_geometry (display, src_mask, &w, &h, NULL);
- mask = meta_gdk_pixbuf_get_from_pixmap (NULL,
- src_mask,
- 0, 0, 0, 0,
- w, h);
- }
-
- meta_error_trap_pop (display, FALSE);
-
- if (mask)
- {
- GdkPixbuf *masked;
-
- masked = apply_mask (unscaled, mask);
- g_object_unref (G_OBJECT (unscaled));
- unscaled = masked;
-
- g_object_unref (G_OBJECT (mask));
- mask = NULL;
- }
-
- if (unscaled)
- {
- *iconp =
- gdk_pixbuf_scale_simple (unscaled,
- ideal_width > 0 ? ideal_width :
- gdk_pixbuf_get_width (unscaled),
- ideal_height > 0 ? ideal_height :
- gdk_pixbuf_get_height (unscaled),
- GDK_INTERP_BILINEAR);
- *mini_iconp =
- gdk_pixbuf_scale_simple (unscaled,
- ideal_mini_width > 0 ? ideal_mini_width :
- gdk_pixbuf_get_width (unscaled),
- ideal_mini_height > 0 ? ideal_mini_height :
- gdk_pixbuf_get_height (unscaled),
- GDK_INTERP_BILINEAR);
-
- g_object_unref (G_OBJECT (unscaled));
-
- if (*iconp && *mini_iconp)
- return TRUE;
- else
- {
- if (*iconp)
- g_object_unref (G_OBJECT (*iconp));
- if (*mini_iconp)
- g_object_unref (G_OBJECT (*mini_iconp));
- return FALSE;
- }
- }
- else
- return FALSE;
-}
-
-static void
-get_kwm_win_icon (MetaDisplay *display,
- Window xwindow,
- Pixmap *pixmap,
- Pixmap *mask)
-{
- Atom type;
- int format;
- gulong nitems;
- gulong bytes_after;
- guchar *data;
- Pixmap *icons;
- int err, result;
-
- *pixmap = None;
- *mask = None;
-
- meta_error_trap_push_with_return (display);
- icons = NULL;
- result = XGetWindowProperty (display->xdisplay, xwindow,
- display->atom__KWM_WIN_ICON,
- 0, G_MAXLONG,
- False,
- display->atom__KWM_WIN_ICON,
- &type, &format, &nitems,
- &bytes_after, &data);
- icons = (Pixmap *)data;
-
- err = meta_error_trap_pop_with_return (display, TRUE);
- if (err != Success ||
- result != Success)
- return;
-
- if (type != display->atom__KWM_WIN_ICON)
- {
- XFree (icons);
- return;
- }
-
- *pixmap = icons[0];
- *mask = icons[1];
-
- XFree (icons);
-
- return;
-}
-
-void
-meta_icon_cache_init (MetaIconCache *icon_cache)
-{
- g_return_if_fail (icon_cache != NULL);
-
- icon_cache->origin = USING_NO_ICON;
- icon_cache->prev_pixmap = None;
- icon_cache->prev_mask = None;
-#if 0
- icon_cache->icon = NULL;
- icon_cache->mini_icon = NULL;
- icon_cache->ideal_width = -1; /* won't be a legit width */
- icon_cache->ideal_height = -1;
- icon_cache->ideal_mini_width = -1;
- icon_cache->ideal_mini_height = -1;
-#endif
- icon_cache->want_fallback = TRUE;
- icon_cache->wm_hints_dirty = TRUE;
- icon_cache->kwm_win_icon_dirty = TRUE;
- icon_cache->net_wm_icon_dirty = TRUE;
-}
-
-static void
-clear_icon_cache (MetaIconCache *icon_cache,
- gboolean dirty_all)
-{
-#if 0
- if (icon_cache->icon)
- g_object_unref (G_OBJECT (icon_cache->icon));
- icon_cache->icon = NULL;
-
- if (icon_cache->mini_icon)
- g_object_unref (G_OBJECT (icon_cache->mini_icon));
- icon_cache->mini_icon = NULL;
-#endif
-
- icon_cache->origin = USING_NO_ICON;
-
- if (dirty_all)
- {
- icon_cache->wm_hints_dirty = TRUE;
- icon_cache->kwm_win_icon_dirty = TRUE;
- icon_cache->net_wm_icon_dirty = TRUE;
- }
-}
-
-void
-meta_icon_cache_free (MetaIconCache *icon_cache)
-{
- clear_icon_cache (icon_cache, FALSE);
-}
-
-void
-meta_icon_cache_property_changed (MetaIconCache *icon_cache,
- MetaDisplay *display,
- Atom atom)
-{
- if (atom == display->atom__NET_WM_ICON)
- icon_cache->net_wm_icon_dirty = TRUE;
- else if (atom == display->atom__KWM_WIN_ICON)
- icon_cache->kwm_win_icon_dirty = TRUE;
- else if (atom == XA_WM_HINTS)
- icon_cache->wm_hints_dirty = TRUE;
-}
-
-gboolean
-meta_icon_cache_get_icon_invalidated (MetaIconCache *icon_cache)
-{
- if (icon_cache->origin <= USING_KWM_WIN_ICON &&
- icon_cache->kwm_win_icon_dirty)
- return TRUE;
- else if (icon_cache->origin <= USING_WM_HINTS &&
- icon_cache->wm_hints_dirty)
- return TRUE;
- else if (icon_cache->origin <= USING_NET_WM_ICON &&
- icon_cache->net_wm_icon_dirty)
- return TRUE;
- else if (icon_cache->origin < USING_FALLBACK_ICON &&
- icon_cache->want_fallback)
- return TRUE;
- else if (icon_cache->origin == USING_NO_ICON)
- return TRUE;
- else if (icon_cache->origin == USING_FALLBACK_ICON &&
- !icon_cache->want_fallback)
- return TRUE;
- else
- return FALSE;
-}
-
-static void
-replace_cache (MetaIconCache *icon_cache,
- IconOrigin origin,
- GdkPixbuf *new_icon,
- GdkPixbuf *new_mini_icon)
-{
- clear_icon_cache (icon_cache, FALSE);
-
- icon_cache->origin = origin;
-
-#if 0
- if (new_icon)
- g_object_ref (G_OBJECT (new_icon));
-
- icon_cache->icon = new_icon;
-
- if (new_mini_icon)
- g_object_ref (G_OBJECT (new_mini_icon));
-
- icon_cache->mini_icon = new_mini_icon;
-#endif
-}
-
-static GdkPixbuf*
-scaled_from_pixdata (guchar *pixdata,
- int w,
- int h,
- int new_w,
- int new_h)
-{
- GdkPixbuf *src;
- GdkPixbuf *dest;
-
- src = gdk_pixbuf_new_from_data (pixdata,
- GDK_COLORSPACE_RGB,
- TRUE,
- 8,
- w, h, w * 4,
- free_pixels,
- NULL);
-
- if (src == NULL)
- return NULL;
-
- if (w != h)
- {
- GdkPixbuf *tmp;
- int size;
-
- size = MAX (w, h);
-
- tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, size, size);
-
- if (tmp)
- {
- gdk_pixbuf_fill (tmp, 0);
- gdk_pixbuf_copy_area (src, 0, 0, w, h,
- tmp,
- (size - w) / 2, (size - h) / 2);
-
- g_object_unref (src);
- src = tmp;
- }
- }
-
- if (w != new_w || h != new_h)
- {
- dest = gdk_pixbuf_scale_simple (src, new_w, new_h, GDK_INTERP_BILINEAR);
-
- g_object_unref (G_OBJECT (src));
- }
- else
- {
- dest = src;
- }
-
- return dest;
-}
-
-gboolean
-meta_read_icons (MetaScreen *screen,
- Window xwindow,
- MetaIconCache *icon_cache,
- Pixmap wm_hints_pixmap,
- Pixmap wm_hints_mask,
- GdkPixbuf **iconp,
- int ideal_width,
- int ideal_height,
- GdkPixbuf **mini_iconp,
- int ideal_mini_width,
- int ideal_mini_height)
-{
- guchar *pixdata;
- int w, h;
- guchar *mini_pixdata;
- int mini_w, mini_h;
- Pixmap pixmap;
- Pixmap mask;
-
- /* Return value is whether the icon changed */
-
- g_return_val_if_fail (icon_cache != NULL, FALSE);
-
- *iconp = NULL;
- *mini_iconp = NULL;
-
-#if 0
- if (ideal_width != icon_cache->ideal_width ||
- ideal_height != icon_cache->ideal_height ||
- ideal_mini_width != icon_cache->ideal_mini_width ||
- ideal_mini_height != icon_cache->ideal_mini_height)
- clear_icon_cache (icon_cache, TRUE);
-
- icon_cache->ideal_width = ideal_width;
- icon_cache->ideal_height = ideal_height;
- icon_cache->ideal_mini_width = ideal_mini_width;
- icon_cache->ideal_mini_height = ideal_mini_height;
-#endif
-
- if (!meta_icon_cache_get_icon_invalidated (icon_cache))
- return FALSE; /* we have no new info to use */
-
- pixdata = NULL;
-
- /* Our algorithm here assumes that we can't have for example origin
- * < USING_NET_WM_ICON and icon_cache->net_wm_icon_dirty == FALSE
- * unless we have tried to read NET_WM_ICON.
- *
- * Put another way, if an icon origin is not dirty, then we have
- * tried to read it at the current size. If it is dirty, then
- * we haven't done that since the last change.
- */
-
- if (icon_cache->origin <= USING_NET_WM_ICON &&
- icon_cache->net_wm_icon_dirty)
-
- {
- icon_cache->net_wm_icon_dirty = FALSE;
-
- if (read_rgb_icon (screen->display, xwindow,
- ideal_width, ideal_height,
- ideal_mini_width, ideal_mini_height,
- &w, &h, &pixdata,
- &mini_w, &mini_h, &mini_pixdata))
- {
- *iconp = scaled_from_pixdata (pixdata, w, h,
- ideal_width, ideal_height);
-
- *mini_iconp = scaled_from_pixdata (mini_pixdata, mini_w, mini_h,
- ideal_mini_width, ideal_mini_height);
-
- if (*iconp && *mini_iconp)
- {
- replace_cache (icon_cache, USING_NET_WM_ICON,
- *iconp, *mini_iconp);
-
- return TRUE;
- }
- else
- {
- if (*iconp)
- g_object_unref (G_OBJECT (*iconp));
- if (*mini_iconp)
- g_object_unref (G_OBJECT (*mini_iconp));
- }
- }
- }
-
- if (icon_cache->origin <= USING_WM_HINTS &&
- icon_cache->wm_hints_dirty)
- {
- icon_cache->wm_hints_dirty = FALSE;
-
- pixmap = wm_hints_pixmap;
- mask = wm_hints_mask;
-
- /* We won't update if pixmap is unchanged;
- * avoids a get_from_drawable() on every geometry
- * hints change
- */
- if ((pixmap != icon_cache->prev_pixmap ||
- mask != icon_cache->prev_mask) &&
- pixmap != None)
- {
- if (try_pixmap_and_mask (screen->display,
- pixmap, mask,
- iconp, ideal_width, ideal_height,
- mini_iconp, ideal_mini_width, ideal_mini_height))
- {
- icon_cache->prev_pixmap = pixmap;
- icon_cache->prev_mask = mask;
-
- replace_cache (icon_cache, USING_WM_HINTS,
- *iconp, *mini_iconp);
-
- return TRUE;
- }
- }
- }
-
- if (icon_cache->origin <= USING_KWM_WIN_ICON &&
- icon_cache->kwm_win_icon_dirty)
- {
- icon_cache->kwm_win_icon_dirty = FALSE;
-
- get_kwm_win_icon (screen->display, xwindow, &pixmap, &mask);
-
- if ((pixmap != icon_cache->prev_pixmap ||
- mask != icon_cache->prev_mask) &&
- pixmap != None)
- {
- if (try_pixmap_and_mask (screen->display, pixmap, mask,
- iconp, ideal_width, ideal_height,
- mini_iconp, ideal_mini_width, ideal_mini_height))
- {
- icon_cache->prev_pixmap = pixmap;
- icon_cache->prev_mask = mask;
-
- replace_cache (icon_cache, USING_KWM_WIN_ICON,
- *iconp, *mini_iconp);
-
- return TRUE;
- }
- }
- }
-
- if (icon_cache->want_fallback &&
- icon_cache->origin < USING_FALLBACK_ICON)
- {
- get_fallback_icons (screen,
- iconp,
- ideal_width,
- ideal_height,
- mini_iconp,
- ideal_mini_width,
- ideal_mini_height);
-
- replace_cache (icon_cache, USING_FALLBACK_ICON,
- *iconp, *mini_iconp);
-
- return TRUE;
- }
-
- if (!icon_cache->want_fallback &&
- icon_cache->origin == USING_FALLBACK_ICON)
- {
- /* Get rid of current icon */
- clear_icon_cache (icon_cache, FALSE);
-
- return TRUE;
- }
-
- /* found nothing new */
- return FALSE;
-}
diff --git a/src/core/iconcache.h b/src/core/iconcache.h
deleted file mode 100644
index ac3e40ca..00000000
--- a/src/core/iconcache.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity window icons */
-
-/*
- * Copyright (C) 2002 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_ICON_CACHE_H
-#define META_ICON_CACHE_H
-
-#include "screen-private.h"
-
-typedef struct _MetaIconCache MetaIconCache;
-
-typedef enum
-{
- /* These MUST be in ascending order of preference;
- * i.e. if we get _NET_WM_ICON and already have
- * WM_HINTS, we prefer _NET_WM_ICON
- */
- USING_NO_ICON,
- USING_FALLBACK_ICON,
- USING_KWM_WIN_ICON,
- USING_WM_HINTS,
- USING_NET_WM_ICON
-} IconOrigin;
-
-struct _MetaIconCache
-{
- int origin;
- Pixmap prev_pixmap;
- Pixmap prev_mask;
- guint want_fallback : 1;
- /* TRUE if these props have changed */
- guint wm_hints_dirty : 1;
- guint kwm_win_icon_dirty : 1;
- guint net_wm_icon_dirty : 1;
-};
-
-void meta_icon_cache_init (MetaIconCache *icon_cache);
-void meta_icon_cache_free (MetaIconCache *icon_cache);
-void meta_icon_cache_property_changed (MetaIconCache *icon_cache,
- MetaDisplay *display,
- Atom atom);
-gboolean meta_icon_cache_get_icon_invalidated (MetaIconCache *icon_cache);
-
-gboolean meta_read_icons (MetaScreen *screen,
- Window xwindow,
- MetaIconCache *icon_cache,
- Pixmap wm_hints_pixmap,
- Pixmap wm_hints_mask,
- GdkPixbuf **iconp,
- int ideal_width,
- int ideal_height,
- GdkPixbuf **mini_iconp,
- int ideal_mini_width,
- int ideal_mini_height);
-
-#endif
-
-
-
-
diff --git a/src/core/keybindings.c b/src/core/keybindings.c
deleted file mode 100644
index 66b8294f..00000000
--- a/src/core/keybindings.c
+++ /dev/null
@@ -1,3350 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity Keybindings */
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2002 Red Hat Inc.
- * Copyright (C) 2003 Rob Adams
- * Copyright (C) 2004-2006 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#define _GNU_SOURCE
-#define _SVID_SOURCE /* for putenv() */
-
-#include <config.h>
-#include "keybindings.h"
-#include "workspace.h"
-#include "errors.h"
-#include "edge-resistance.h"
-#include "ui.h"
-#include "frame-private.h"
-#include "place.h"
-#include "prefs.h"
-#include "effects.h"
-#include "util.h"
-
-#include <X11/keysym.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#ifdef HAVE_XKB
-#include <X11/XKBlib.h>
-#endif
-
-static gboolean all_bindings_disabled = FALSE;
-
-typedef void (* MetaKeyHandlerFunc) (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding);
-
-/* Prototypes for handlers */
-#define keybind(name, handler, param, flags, stroke, description) \
-static void \
-handler (MetaDisplay *display,\
- MetaScreen *screen,\
- MetaWindow *window,\
- XEvent *event,\
- MetaKeyBinding *binding);
-#include "all-keybindings.h"
-#undef keybind
-
-/* These can't be bound to anything, but they are used to handle
- * various other events. TODO: Possibly we should include them as event
- * handler functions and have some kind of flag to say they're unbindable.
- */
-
-static void handle_workspace_switch (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding);
-
-static gboolean process_mouse_move_resize_grab (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- KeySym keysym);
-
-static gboolean process_keyboard_move_grab (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- KeySym keysym);
-
-static gboolean process_keyboard_resize_grab (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- KeySym keysym);
-
-static gboolean process_tab_grab (MetaDisplay *display,
- MetaScreen *screen,
- XEvent *event,
- KeySym keysym);
-
-static gboolean process_workspace_switch_grab (MetaDisplay *display,
- MetaScreen *screen,
- XEvent *event,
- KeySym keysym);
-
-static void regrab_key_bindings (MetaDisplay *display);
-
-typedef struct
-{
- const char *name;
- MetaKeyHandlerFunc func;
- gint data, flags;
-} MetaKeyHandler;
-
-struct _MetaKeyBinding
-{
- const char *name;
- KeySym keysym;
- KeyCode keycode;
- unsigned int mask;
- MetaVirtualModifier modifiers;
- const MetaKeyHandler *handler;
-};
-
-#define keybind(name, handler, param, flags, stroke, description) \
- { #name, handler, param, flags },
-static const MetaKeyHandler key_handlers[] = {
-#include "all-keybindings.h"
- { NULL, NULL, 0, 0 }
-};
-#undef keybind
-
-static void
-reload_keymap (MetaDisplay *display)
-{
- if (display->keymap)
- meta_XFree (display->keymap);
-
- display->keymap = XGetKeyboardMapping (display->xdisplay,
- display->min_keycode,
- display->max_keycode -
- display->min_keycode + 1,
- &display->keysyms_per_keycode);
-}
-
-static void
-reload_modmap (MetaDisplay *display)
-{
- XModifierKeymap *modmap;
- int map_size;
- int i;
-
- if (display->modmap)
- XFreeModifiermap (display->modmap);
-
- modmap = XGetModifierMapping (display->xdisplay);
- display->modmap = modmap;
-
- display->ignored_modifier_mask = 0;
-
- /* Multiple bits may get set in each of these */
- display->num_lock_mask = 0;
- display->scroll_lock_mask = 0;
- display->meta_mask = 0;
- display->hyper_mask = 0;
- display->super_mask = 0;
-
- /* there are 8 modifiers, and the first 3 are shift, shift lock,
- * and control
- */
- map_size = 8 * modmap->max_keypermod;
- i = 3 * modmap->max_keypermod;
- while (i < map_size)
- {
- /* get the key code at this point in the map,
- * see if its keysym is one we're interested in
- */
- int keycode = modmap->modifiermap[i];
-
- if (keycode >= display->min_keycode &&
- keycode <= display->max_keycode)
- {
- int j = 0;
- KeySym *syms = display->keymap +
- (keycode - display->min_keycode) * display->keysyms_per_keycode;
-
- while (j < display->keysyms_per_keycode)
- {
- if (syms[j] != 0)
- {
- const char *str;
-
- str = XKeysymToString (syms[j]);
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Keysym %s bound to modifier 0x%x\n",
- str ? str : "none",
- (1 << ( i / modmap->max_keypermod)));
- }
-
- if (syms[j] == XK_Num_Lock)
- {
- /* Mod1Mask is 1 << 3 for example, i.e. the
- * fourth modifier, i / keyspermod is the modifier
- * index
- */
-
- display->num_lock_mask |= (1 << ( i / modmap->max_keypermod));
- }
- else if (syms[j] == XK_Scroll_Lock)
- {
- display->scroll_lock_mask |= (1 << ( i / modmap->max_keypermod));
- }
- else if (syms[j] == XK_Super_L ||
- syms[j] == XK_Super_R)
- {
- display->super_mask |= (1 << ( i / modmap->max_keypermod));
- }
- else if (syms[j] == XK_Hyper_L ||
- syms[j] == XK_Hyper_R)
- {
- display->hyper_mask |= (1 << ( i / modmap->max_keypermod));
- }
- else if (syms[j] == XK_Meta_L ||
- syms[j] == XK_Meta_R)
- {
- display->meta_mask |= (1 << ( i / modmap->max_keypermod));
- }
-
- ++j;
- }
- }
-
- ++i;
- }
-
- display->ignored_modifier_mask = (display->num_lock_mask |
- display->scroll_lock_mask |
- LockMask);
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Ignoring modmask 0x%x num lock 0x%x scroll lock 0x%x hyper 0x%x super 0x%x meta 0x%x\n",
- display->ignored_modifier_mask,
- display->num_lock_mask,
- display->scroll_lock_mask,
- display->hyper_mask,
- display->super_mask,
- display->meta_mask);
-}
-
-static void
-reload_keycodes (MetaDisplay *display)
-{
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Reloading keycodes for binding tables\n");
-
- if (display->key_bindings)
- {
- int i;
-
- i = 0;
- while (i < display->n_key_bindings)
- {
- if (display->key_bindings[i].keycode == 0)
- display->key_bindings[i].keycode = XKeysymToKeycode (
- display->xdisplay, display->key_bindings[i].keysym);
-
- ++i;
- }
- }
-}
-
-static void
-reload_modifiers (MetaDisplay *display)
-{
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Reloading keycodes for binding tables\n");
-
- if (display->key_bindings)
- {
- int i;
-
- i = 0;
- while (i < display->n_key_bindings)
- {
- meta_display_devirtualize_modifiers (display,
- display->key_bindings[i].modifiers,
- &display->key_bindings[i].mask);
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- " Devirtualized mods 0x%x -> 0x%x (%s)\n",
- display->key_bindings[i].modifiers,
- display->key_bindings[i].mask,
- display->key_bindings[i].name);
-
- ++i;
- }
- }
-}
-
-
-static int
-count_bindings (const MetaKeyPref *prefs,
- int n_prefs)
-{
- int i;
- int count;
-
- count = 0;
- i = 0;
- while (i < n_prefs)
- {
- GSList *tmp = prefs[i].bindings;
-
- while (tmp)
- {
- MetaKeyCombo *combo = tmp->data;
-
- if (combo && (combo->keysym != None || combo->keycode != 0))
- {
- count += 1;
-
- if (prefs[i].add_shift &&
- (combo->modifiers & META_VIRTUAL_SHIFT_MASK) == 0)
- count += 1;
- }
-
- tmp = tmp->next;
- }
-
- ++i;
- }
-
- return count;
-}
-
-/* FIXME: replace this with a temporary hash */
-static const MetaKeyHandler*
-find_handler (const MetaKeyHandler *handlers,
- const char *name)
-{
- const MetaKeyHandler *iter;
-
- iter = handlers;
- while (iter->name)
- {
- if (strcmp (iter->name, name) == 0)
- return iter;
-
- ++iter;
- }
-
- return NULL;
-}
-
-static void
-rebuild_binding_table (MetaDisplay *display,
- MetaKeyBinding **bindings_p,
- int *n_bindings_p,
- const MetaKeyPref *prefs,
- int n_prefs)
-{
- int n_bindings;
- int src, dest;
-
- n_bindings = count_bindings (prefs, n_prefs);
- g_free (*bindings_p);
- *bindings_p = g_new0 (MetaKeyBinding, n_bindings);
-
- src = 0;
- dest = 0;
- while (src < n_prefs)
- {
- GSList *tmp = prefs[src].bindings;
-
- while (tmp)
- {
- MetaKeyCombo *combo = tmp->data;
-
- if (combo && (combo->keysym != None || combo->keycode != 0))
- {
- const MetaKeyHandler *handler = find_handler (key_handlers, prefs[src].name);
-
- (*bindings_p)[dest].name = prefs[src].name;
- (*bindings_p)[dest].handler = handler;
- (*bindings_p)[dest].keysym = combo->keysym;
- (*bindings_p)[dest].keycode = combo->keycode;
- (*bindings_p)[dest].modifiers = combo->modifiers;
- (*bindings_p)[dest].mask = 0;
-
- ++dest;
-
- if (prefs[src].add_shift &&
- (combo->modifiers & META_VIRTUAL_SHIFT_MASK) == 0)
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Binding %s also needs Shift grabbed\n",
- prefs[src].name);
-
- (*bindings_p)[dest].name = prefs[src].name;
- (*bindings_p)[dest].handler = handler;
- (*bindings_p)[dest].keysym = combo->keysym;
- (*bindings_p)[dest].keycode = combo->keycode;
- (*bindings_p)[dest].modifiers = combo->modifiers |
- META_VIRTUAL_SHIFT_MASK;
- (*bindings_p)[dest].mask = 0;
-
- ++dest;
- }
- }
-
- tmp = tmp->next;
- }
-
- ++src;
- }
-
- g_assert (dest == n_bindings);
-
- *n_bindings_p = dest;
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- " %d bindings in table\n",
- *n_bindings_p);
-}
-
-static void
-rebuild_key_binding_table (MetaDisplay *display)
-{
- const MetaKeyPref *prefs;
- int n_prefs;
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Rebuilding key binding table from preferences\n");
-
- meta_prefs_get_key_bindings (&prefs, &n_prefs);
- rebuild_binding_table (display,
- &display->key_bindings,
- &display->n_key_bindings,
- prefs, n_prefs);
-}
-
-static void
-regrab_key_bindings (MetaDisplay *display)
-{
- GSList *tmp;
- GSList *windows;
-
- meta_error_trap_push (display); /* for efficiency push outer trap */
-
- tmp = display->screens;
- while (tmp != NULL)
- {
- MetaScreen *screen = tmp->data;
-
- meta_screen_ungrab_keys (screen);
- meta_screen_grab_keys (screen);
-
- tmp = tmp->next;
- }
-
- windows = meta_display_list_windows (display);
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
-
- meta_window_ungrab_keys (w);
- meta_window_grab_keys (w);
-
- tmp = tmp->next;
- }
- meta_error_trap_pop (display, FALSE);
-
- g_slist_free (windows);
-}
-
-static MetaKeyBindingAction
-display_get_keybinding_action (MetaDisplay *display,
- unsigned int keysym,
- unsigned int keycode,
- unsigned long mask)
-{
- int i;
-
- i = display->n_key_bindings - 1;
- while (i >= 0)
- {
- if (display->key_bindings[i].keysym == keysym &&
- display->key_bindings[i].keycode == keycode &&
- display->key_bindings[i].mask == mask)
- {
- return meta_prefs_get_keybinding_action (display->key_bindings[i].name);
- }
-
- --i;
- }
-
- return META_KEYBINDING_ACTION_NONE;
-}
-
-void
-meta_display_process_mapping_event (MetaDisplay *display,
- XEvent *event)
-{
- if (event->xmapping.request == MappingModifier)
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Received MappingModifier event, will reload modmap and redo keybindings\n");
-
- reload_modmap (display);
-
- reload_modifiers (display);
-
- regrab_key_bindings (display);
- }
- else if (event->xmapping.request == MappingKeyboard)
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Received MappingKeyboard event, will reload keycodes and redo keybindings\n");
-
- reload_keymap (display);
- reload_modmap (display);
-
- reload_keycodes (display);
-
- regrab_key_bindings (display);
- }
-}
-
-static void
-bindings_changed_callback (MetaPreference pref,
- void *data)
-{
- MetaDisplay *display;
-
- display = data;
-
- switch (pref)
- {
- case META_PREF_KEYBINDINGS:
- rebuild_key_binding_table (display);
- reload_keycodes (display);
- reload_modifiers (display);
- regrab_key_bindings (display);
- break;
- default:
- break;
- }
-}
-
-
-void
-meta_display_init_keys (MetaDisplay *display)
-{
- /* Keybindings */
- display->keymap = NULL;
- display->keysyms_per_keycode = 0;
- display->modmap = NULL;
- display->min_keycode = 0;
- display->max_keycode = 0;
- display->ignored_modifier_mask = 0;
- display->num_lock_mask = 0;
- display->scroll_lock_mask = 0;
- display->hyper_mask = 0;
- display->super_mask = 0;
- display->meta_mask = 0;
- display->key_bindings = NULL;
- display->n_key_bindings = 0;
-
- XDisplayKeycodes (display->xdisplay,
- &display->min_keycode,
- &display->max_keycode);
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Display has keycode range %d to %d\n",
- display->min_keycode,
- display->max_keycode);
-
- reload_keymap (display);
- reload_modmap (display);
-
- rebuild_key_binding_table (display);
-
- reload_keycodes (display);
- reload_modifiers (display);
-
- /* Keys are actually grabbed in meta_screen_grab_keys() */
-
- meta_prefs_add_listener (bindings_changed_callback, display);
-}
-
-void
-meta_display_shutdown_keys (MetaDisplay *display)
-{
- /* Note that display->xdisplay is invalid in this function */
-
- meta_prefs_remove_listener (bindings_changed_callback, display);
-
- if (display->keymap)
- meta_XFree (display->keymap);
-
- if (display->modmap)
- XFreeModifiermap (display->modmap);
- g_free (display->key_bindings);
-}
-
-static const char*
-keysym_name (int keysym)
-{
- const char *name;
-
- name = XKeysymToString (keysym);
- if (name == NULL)
- name = "(unknown)";
-
- return name;
-}
-
-/* Grab/ungrab, ignoring all annoying modifiers like NumLock etc. */
-static void
-meta_change_keygrab (MetaDisplay *display,
- Window xwindow,
- gboolean grab,
- int keysym,
- unsigned int keycode,
- int modmask)
-{
- unsigned int ignored_mask;
-
- /* Grab keycode/modmask, together with
- * all combinations of ignored modifiers.
- * X provides no better way to do this.
- */
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "%s keybinding %s keycode %d mask 0x%x on 0x%lx\n",
- grab ? "Grabbing" : "Ungrabbing",
- keysym_name (keysym), keycode,
- modmask, xwindow);
-
- /* efficiency, avoid so many XSync() */
- meta_error_trap_push (display);
-
- ignored_mask = 0;
- while (ignored_mask <= display->ignored_modifier_mask)
- {
- if (ignored_mask & ~(display->ignored_modifier_mask))
- {
- /* Not a combination of ignored modifiers
- * (it contains some non-ignored modifiers)
- */
- ++ignored_mask;
- continue;
- }
-
- if (meta_is_debugging ())
- meta_error_trap_push_with_return (display);
- if (grab)
- XGrabKey (display->xdisplay, keycode,
- modmask | ignored_mask,
- xwindow,
- True,
- GrabModeAsync, GrabModeSync);
- else
- XUngrabKey (display->xdisplay, keycode,
- modmask | ignored_mask,
- xwindow);
-
- if (meta_is_debugging ())
- {
- int result;
-
- result = meta_error_trap_pop_with_return (display, FALSE);
-
- if (grab && result != Success)
- {
- if (result == BadAccess)
- meta_warning (_("Some other program is already using the key %s with modifiers %x as a binding\n"), keysym_name (keysym), modmask | ignored_mask);
- else
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Failed to grab key %s with modifiers %x\n",
- keysym_name (keysym), modmask | ignored_mask);
- }
- }
-
- ++ignored_mask;
- }
-
- meta_error_trap_pop (display, FALSE);
-}
-
-static void
-meta_grab_key (MetaDisplay *display,
- Window xwindow,
- int keysym,
- unsigned int keycode,
- int modmask)
-{
- meta_change_keygrab (display, xwindow, TRUE, keysym, keycode, modmask);
-}
-
-static void
-grab_keys (MetaKeyBinding *bindings,
- int n_bindings,
- MetaDisplay *display,
- Window xwindow,
- gboolean binding_per_window)
-{
- int i;
-
- g_assert (n_bindings == 0 || bindings != NULL);
-
- meta_error_trap_push (display);
-
- i = 0;
- while (i < n_bindings)
- {
- if (!!binding_per_window ==
- !!(bindings[i].handler->flags & BINDING_PER_WINDOW) &&
- bindings[i].keycode != 0)
- {
- meta_grab_key (display, xwindow,
- bindings[i].keysym,
- bindings[i].keycode,
- bindings[i].mask);
- }
-
- ++i;
- }
-
- meta_error_trap_pop (display, FALSE);
-}
-
-static void
-ungrab_all_keys (MetaDisplay *display,
- Window xwindow)
-{
- if (meta_is_debugging ())
- meta_error_trap_push_with_return (display);
- else
- meta_error_trap_push (display);
-
- XUngrabKey (display->xdisplay, AnyKey, AnyModifier,
- xwindow);
-
- if (meta_is_debugging ())
- {
- int result;
-
- result = meta_error_trap_pop_with_return (display, FALSE);
-
- if (result != Success)
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Ungrabbing all keys on 0x%lx failed\n", xwindow);
- }
- else
- meta_error_trap_pop (display, FALSE);
-}
-
-void
-meta_screen_grab_keys (MetaScreen *screen)
-{
- if (screen->all_keys_grabbed)
- return;
-
- if (screen->keys_grabbed)
- return;
-
- grab_keys (screen->display->key_bindings,
- screen->display->n_key_bindings,
- screen->display, screen->xroot,
- FALSE);
-
- screen->keys_grabbed = TRUE;
-}
-
-void
-meta_screen_ungrab_keys (MetaScreen *screen)
-{
- if (screen->keys_grabbed)
- {
- ungrab_all_keys (screen->display, screen->xroot);
- screen->keys_grabbed = FALSE;
- }
-}
-
-void
-meta_window_grab_keys (MetaWindow *window)
-{
- if (window->all_keys_grabbed)
- return;
-
- if (window->type == META_WINDOW_DOCK)
- {
- if (window->keys_grabbed)
- ungrab_all_keys (window->display, window->xwindow);
- window->keys_grabbed = FALSE;
- return;
- }
-
- if (window->keys_grabbed)
- {
- if (window->frame && !window->grab_on_frame)
- ungrab_all_keys (window->display, window->xwindow);
- else if (window->frame == NULL &&
- window->grab_on_frame)
- ; /* continue to regrab on client window */
- else
- return; /* already all good */
- }
-
- grab_keys (window->display->key_bindings,
- window->display->n_key_bindings,
- window->display,
- window->frame ? window->frame->xwindow : window->xwindow,
- TRUE);
-
- window->keys_grabbed = TRUE;
- window->grab_on_frame = window->frame != NULL;
-}
-
-void
-meta_window_ungrab_keys (MetaWindow *window)
-{
- if (window->keys_grabbed)
- {
- if (window->grab_on_frame &&
- window->frame != NULL)
- ungrab_all_keys (window->display,
- window->frame->xwindow);
- else if (!window->grab_on_frame)
- ungrab_all_keys (window->display,
- window->xwindow);
-
- window->keys_grabbed = FALSE;
- }
-}
-
-#ifdef WITH_VERBOSE_MODE
-static const char*
-grab_status_to_string (int status)
-{
- switch (status)
- {
- case AlreadyGrabbed:
- return "AlreadyGrabbed";
- case GrabSuccess:
- return "GrabSuccess";
- case GrabNotViewable:
- return "GrabNotViewable";
- case GrabFrozen:
- return "GrabFrozen";
- case GrabInvalidTime:
- return "GrabInvalidTime";
- default:
- return "(unknown)";
- }
-}
-#endif /* WITH_VERBOSE_MODE */
-
-static gboolean
-grab_keyboard (MetaDisplay *display,
- Window xwindow,
- guint32 timestamp)
-{
- int result;
- int grab_status;
-
- /* Grab the keyboard, so we get key releases and all key
- * presses
- */
- meta_error_trap_push_with_return (display);
-
- grab_status = XGrabKeyboard (display->xdisplay,
- xwindow, True,
- GrabModeAsync, GrabModeAsync,
- timestamp);
-
- if (grab_status != GrabSuccess)
- {
- meta_error_trap_pop_with_return (display, TRUE);
- meta_topic (META_DEBUG_KEYBINDINGS,
- "XGrabKeyboard() returned failure status %s time %u\n",
- grab_status_to_string (grab_status),
- timestamp);
- return FALSE;
- }
- else
- {
- result = meta_error_trap_pop_with_return (display, TRUE);
- if (result != Success)
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "XGrabKeyboard() resulted in an error\n");
- return FALSE;
- }
- }
-
- meta_topic (META_DEBUG_KEYBINDINGS, "Grabbed all keys\n");
-
- return TRUE;
-}
-
-static void
-ungrab_keyboard (MetaDisplay *display, guint32 timestamp)
-{
- meta_error_trap_push (display);
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Ungrabbing keyboard with timestamp %u\n",
- timestamp);
- XUngrabKeyboard (display->xdisplay, timestamp);
- meta_error_trap_pop (display, FALSE);
-}
-
-gboolean
-meta_screen_grab_all_keys (MetaScreen *screen, guint32 timestamp)
-{
- gboolean retval;
-
- if (screen->all_keys_grabbed)
- return FALSE;
-
- if (screen->keys_grabbed)
- meta_screen_ungrab_keys (screen);
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Grabbing all keys on RootWindow\n");
- retval = grab_keyboard (screen->display, screen->xroot, timestamp);
- if (retval)
- screen->all_keys_grabbed = TRUE;
- else
- meta_screen_grab_keys (screen);
-
- return retval;
-}
-
-void
-meta_screen_ungrab_all_keys (MetaScreen *screen, guint32 timestamp)
-{
- if (screen->all_keys_grabbed)
- {
- ungrab_keyboard (screen->display, timestamp);
-
- screen->all_keys_grabbed = FALSE;
- screen->keys_grabbed = FALSE;
-
- /* Re-establish our standard bindings */
- meta_screen_grab_keys (screen);
- }
-}
-
-gboolean
-meta_window_grab_all_keys (MetaWindow *window,
- guint32 timestamp)
-{
- Window grabwindow;
- gboolean retval;
-
- if (window->all_keys_grabbed)
- return FALSE;
-
- if (window->keys_grabbed)
- meta_window_ungrab_keys (window);
-
- /* Make sure the window is focused, otherwise the grab
- * won't do a lot of good.
- */
- meta_topic (META_DEBUG_FOCUS,
- "Focusing %s because we're grabbing all its keys\n",
- window->desc);
- meta_window_focus (window, timestamp);
-
- grabwindow = window->frame ? window->frame->xwindow : window->xwindow;
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Grabbing all keys on window %s\n", window->desc);
- retval = grab_keyboard (window->display, grabwindow, timestamp);
- if (retval)
- {
- window->keys_grabbed = FALSE;
- window->all_keys_grabbed = TRUE;
- window->grab_on_frame = window->frame != NULL;
- }
-
- return retval;
-}
-
-void
-meta_window_ungrab_all_keys (MetaWindow *window, guint32 timestamp)
-{
- if (window->all_keys_grabbed)
- {
- ungrab_keyboard (window->display, timestamp);
-
- window->grab_on_frame = FALSE;
- window->all_keys_grabbed = FALSE;
- window->keys_grabbed = FALSE;
-
- /* Re-establish our standard bindings */
- meta_window_grab_keys (window);
- }
-}
-
-static gboolean
-is_modifier (MetaDisplay *display,
- unsigned int keycode)
-{
- int i;
- int map_size;
- gboolean retval = FALSE;
-
- g_assert (display->modmap);
-
- map_size = 8 * display->modmap->max_keypermod;
- i = 0;
- while (i < map_size)
- {
- if (keycode == display->modmap->modifiermap[i])
- {
- retval = TRUE;
- break;
- }
- ++i;
- }
-
- return retval;
-}
-
-/* Indexes:
- * shift = 0
- * lock = 1
- * control = 2
- * mod1 = 3
- * mod2 = 4
- * mod3 = 5
- * mod4 = 6
- * mod5 = 7
- */
-
-static gboolean
-is_specific_modifier (MetaDisplay *display,
- unsigned int keycode,
- unsigned int mask)
-{
- int i;
- int end;
- gboolean retval = FALSE;
- int mod_index;
-
- g_assert (display->modmap);
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Checking whether code 0x%x is bound to modifier 0x%x\n",
- keycode, mask);
-
- mod_index = 0;
- mask = mask >> 1;
- while (mask != 0)
- {
- mod_index += 1;
- mask = mask >> 1;
- }
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Modifier has index %d\n", mod_index);
-
- end = (mod_index + 1) * display->modmap->max_keypermod;
- i = mod_index * display->modmap->max_keypermod;
- while (i < end)
- {
- if (keycode == display->modmap->modifiermap[i])
- {
- retval = TRUE;
- break;
- }
- ++i;
- }
-
- return retval;
-}
-
-static unsigned int
-get_primary_modifier (MetaDisplay *display,
- unsigned int entire_binding_mask)
-{
- /* The idea here is to see if the "main" modifier
- * for Alt+Tab has been pressed/released. So if the binding
- * is Alt+Shift+Tab then releasing Alt is the thing that
- * ends the operation. It's pretty random how we order
- * these.
- */
- unsigned int masks[] = { Mod5Mask, Mod4Mask, Mod3Mask,
- Mod2Mask, Mod1Mask, ControlMask,
- ShiftMask, LockMask };
-
- int i;
-
- i = 0;
- while (i < (int) G_N_ELEMENTS (masks))
- {
- if (entire_binding_mask & masks[i])
- return masks[i];
- ++i;
- }
-
- return 0;
-}
-
-static gboolean
-keycode_is_primary_modifier (MetaDisplay *display,
- unsigned int keycode,
- unsigned int entire_binding_mask)
-{
- unsigned int primary_modifier;
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Checking whether code 0x%x is the primary modifier of mask 0x%x\n",
- keycode, entire_binding_mask);
-
- primary_modifier = get_primary_modifier (display, entire_binding_mask);
- if (primary_modifier != 0)
- return is_specific_modifier (display, keycode, primary_modifier);
- else
- return FALSE;
-}
-
-static gboolean
-primary_modifier_still_pressed (MetaDisplay *display,
- unsigned int entire_binding_mask)
-{
- unsigned int primary_modifier;
- int x, y, root_x, root_y;
- Window root, child;
- guint mask;
- MetaScreen *random_screen;
- Window random_xwindow;
-
- primary_modifier = get_primary_modifier (display, entire_binding_mask);
-
- random_screen = display->screens->data;
- random_xwindow = random_screen->no_focus_window;
- XQueryPointer (display->xdisplay,
- random_xwindow, /* some random window */
- &root, &child,
- &root_x, &root_y,
- &x, &y,
- &mask);
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Primary modifier 0x%x full grab mask 0x%x current state 0x%x\n",
- primary_modifier, entire_binding_mask, mask);
-
- if ((mask & primary_modifier) == 0)
- return FALSE;
- else
- return TRUE;
-}
-
-/* now called from only one place, may be worth merging */
-static gboolean
-process_event (MetaKeyBinding *bindings,
- int n_bindings,
- MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- KeySym keysym,
- gboolean on_window)
-{
- int i;
-
- /* we used to have release-based bindings but no longer. */
- if (event->type == KeyRelease)
- return FALSE;
-
- /*
- * TODO: This would be better done with a hash table;
- * it doesn't suit to use O(n) for such a common operation.
- */
- for (i=0; i<n_bindings; i++)
- {
- const MetaKeyHandler *handler = bindings[i].handler;
-
- if ((!on_window && handler->flags & BINDING_PER_WINDOW) ||
- event->type != KeyPress ||
- bindings[i].keycode != event->xkey.keycode ||
- ((event->xkey.state & 0xff & ~(display->ignored_modifier_mask)) !=
- bindings[i].mask))
- continue;
-
- /*
- * window must be non-NULL for on_window to be true,
- * and so also window must be non-NULL if we get here and
- * this is a BINDING_PER_WINDOW binding.
- */
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Binding keycode 0x%x mask 0x%x matches event 0x%x state 0x%x\n",
- bindings[i].keycode, bindings[i].mask,
- event->xkey.keycode, event->xkey.state);
-
- if (handler == NULL)
- meta_bug ("Binding %s has no handler\n", bindings[i].name);
- else
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Running handler for %s\n",
- bindings[i].name);
-
- /* Global keybindings count as a let-the-terminal-lose-focus
- * due to new window mapping until the user starts
- * interacting with the terminal again.
- */
- display->allow_terminal_deactivation = TRUE;
-
- (* handler->func) (display, screen,
- bindings[i].handler->flags & BINDING_PER_WINDOW? window: NULL,
- event,
- &bindings[i]);
- return TRUE;
- }
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "No handler found for this event in this binding table\n");
- return FALSE;
-}
-
-/* Handle a key event. May be called recursively: some key events cause
- * grabs to be ended and then need to be processed again in their own
- * right. This cannot cause infinite recursion because we never call
- * ourselves when there wasn't a grab, and we always clear the grab
- * first; the invariant is enforced using an assertion. See #112560.
- * FIXME: We need to prove there are no race conditions here.
- * FIXME: Does it correctly handle alt-Tab being followed by another
- * grabbing keypress without letting go of alt?
- * FIXME: An iterative solution would probably be simpler to understand
- * (and help us solve the other fixmes).
- */
-void
-meta_display_process_key_event (MetaDisplay *display,
- MetaWindow *window,
- XEvent *event)
-{
- KeySym keysym;
- gboolean keep_grab;
- gboolean all_keys_grabbed;
- const char *str;
- MetaScreen *screen;
-
- XAllowEvents (display->xdisplay,
- all_bindings_disabled ? ReplayKeyboard : AsyncKeyboard,
- event->xkey.time);
- if (all_bindings_disabled)
- return;
-
- /* if key event was on root window, we have a shortcut */
- screen = meta_display_screen_for_root (display, event->xkey.window);
-
- /* else round-trip to server */
- if (screen == NULL)
- screen = meta_display_screen_for_xwindow (display,
- event->xany.window);
-
- if (screen == NULL)
- return; /* event window is destroyed */
-
- /* ignore key events on popup menus and such. */
- if (window == NULL &&
- meta_ui_window_is_widget (screen->ui, event->xany.window))
- return;
-
- /* window may be NULL */
-
- keysym = XKeycodeToKeysym (display->xdisplay, event->xkey.keycode, 0);
-
- str = XKeysymToString (keysym);
-
- /* was topic */
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Processing key %s event, keysym: %s state: 0x%x window: %s\n",
- event->type == KeyPress ? "press" : "release",
- str ? str : "none", event->xkey.state,
- window ? window->desc : "(no window)");
-
- keep_grab = TRUE;
- all_keys_grabbed = window ? window->all_keys_grabbed : screen->all_keys_grabbed;
- if (all_keys_grabbed)
- {
- if (display->grab_op == META_GRAB_OP_NONE)
- return;
- /* If we get here we have a global grab, because
- * we're in some special keyboard mode such as window move
- * mode.
- */
- if (window ? (window == display->grab_window) :
- (screen == display->grab_screen))
- {
- switch (display->grab_op)
- {
- case META_GRAB_OP_MOVING:
- case META_GRAB_OP_RESIZING_SE:
- case META_GRAB_OP_RESIZING_S:
- case META_GRAB_OP_RESIZING_SW:
- case META_GRAB_OP_RESIZING_N:
- case META_GRAB_OP_RESIZING_NE:
- case META_GRAB_OP_RESIZING_NW:
- case META_GRAB_OP_RESIZING_W:
- case META_GRAB_OP_RESIZING_E:
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Processing event for mouse-only move/resize\n");
- g_assert (window != NULL);
- keep_grab = process_mouse_move_resize_grab (display, screen,
- window, event, keysym);
- break;
-
- case META_GRAB_OP_KEYBOARD_MOVING:
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Processing event for keyboard move\n");
- g_assert (window != NULL);
- keep_grab = process_keyboard_move_grab (display, screen,
- window, event, keysym);
- break;
-
- case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
- case META_GRAB_OP_KEYBOARD_RESIZING_S:
- case META_GRAB_OP_KEYBOARD_RESIZING_N:
- case META_GRAB_OP_KEYBOARD_RESIZING_W:
- case META_GRAB_OP_KEYBOARD_RESIZING_E:
- case META_GRAB_OP_KEYBOARD_RESIZING_SE:
- case META_GRAB_OP_KEYBOARD_RESIZING_NE:
- case META_GRAB_OP_KEYBOARD_RESIZING_SW:
- case META_GRAB_OP_KEYBOARD_RESIZING_NW:
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Processing event for keyboard resize\n");
- g_assert (window != NULL);
- keep_grab = process_keyboard_resize_grab (display, screen,
- window, event, keysym);
- break;
-
- case META_GRAB_OP_KEYBOARD_TABBING_NORMAL:
- case META_GRAB_OP_KEYBOARD_TABBING_DOCK:
- case META_GRAB_OP_KEYBOARD_TABBING_GROUP:
- case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL:
- case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK:
- case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP:
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Processing event for keyboard tabbing/cycling\n");
- keep_grab = process_tab_grab (display, screen, event, keysym);
- break;
-
- case META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING:
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Processing event for keyboard workspace switching\n");
- keep_grab = process_workspace_switch_grab (display, screen, event, keysym);
- break;
-
- default:
- break;
- }
- }
- if (!keep_grab)
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Ending grab op %u on key event sym %s\n",
- display->grab_op, XKeysymToString (keysym));
- meta_display_end_grab_op (display, event->xkey.time);
- return;
- }
- }
- /* Do the normal keybindings */
- process_event (display->key_bindings,
- display->n_key_bindings,
- display, screen, window, event, keysym,
- !all_keys_grabbed && window);
-}
-
-static gboolean
-process_mouse_move_resize_grab (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- KeySym keysym)
-{
- /* don't care about releases, but eat them, don't end grab */
- if (event->type == KeyRelease)
- return TRUE;
-
- if (keysym == XK_Escape)
- {
- /* End move or resize and restore to original state. If the
- * window was a maximized window that had been "shaken loose" we
- * need to remaximize it. In normal cases, we need to do a
- * moveresize now to get the position back to the original. In
- * wireframe mode, we just need to set grab_was_cancelled to tru
- * to avoid avoid moveresizing to the position of the wireframe.
- */
- if (window->shaken_loose)
- meta_window_maximize (window,
- META_MAXIMIZE_HORIZONTAL |
- META_MAXIMIZE_VERTICAL);
- else if (!display->grab_wireframe_active)
- meta_window_move_resize (display->grab_window,
- TRUE,
- display->grab_initial_window_pos.x,
- display->grab_initial_window_pos.y,
- display->grab_initial_window_pos.width,
- display->grab_initial_window_pos.height);
- else
- display->grab_was_cancelled = TRUE;
-
- /* End grab */
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-process_keyboard_move_grab (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- KeySym keysym)
-{
- gboolean handled;
- int x, y;
- int incr;
- gboolean smart_snap;
-
- handled = FALSE;
-
- /* don't care about releases, but eat them, don't end grab */
- if (event->type == KeyRelease)
- return TRUE;
-
- /* don't end grab on modifier key presses */
- if (is_modifier (display, event->xkey.keycode))
- return TRUE;
-
- if (display->grab_wireframe_active)
- {
- x = display->grab_wireframe_rect.x;
- y = display->grab_wireframe_rect.y;
- }
- else
- {
- meta_window_get_position (window, &x, &y);
- }
-
- smart_snap = (event->xkey.state & ShiftMask) != 0;
-
-#define SMALL_INCREMENT 1
-#define NORMAL_INCREMENT 10
-
- if (smart_snap)
- incr = 1;
- else if (event->xkey.state & ControlMask)
- incr = SMALL_INCREMENT;
- else
- incr = NORMAL_INCREMENT;
-
- if (keysym == XK_Escape)
- {
- /* End move and restore to original state. If the window was a
- * maximized window that had been "shaken loose" we need to
- * remaximize it. In normal cases, we need to do a moveresize
- * now to get the position back to the original. In wireframe
- * mode, we just need to set grab_was_cancelled to tru to avoid
- * avoid moveresizing to the position of the wireframe.
- */
- if (window->shaken_loose)
- meta_window_maximize (window,
- META_MAXIMIZE_HORIZONTAL |
- META_MAXIMIZE_VERTICAL);
- else if (!display->grab_wireframe_active)
- meta_window_move_resize (display->grab_window,
- TRUE,
- display->grab_initial_window_pos.x,
- display->grab_initial_window_pos.y,
- display->grab_initial_window_pos.width,
- display->grab_initial_window_pos.height);
- else
- display->grab_was_cancelled = TRUE;
- }
-
- /* When moving by increments, we still snap to edges if the move
- * to the edge is smaller than the increment. This is because
- * Shift + arrow to snap is sort of a hidden feature. This way
- * people using just arrows shouldn't get too frustrated.
- */
- switch (keysym)
- {
- case XK_KP_Home:
- case XK_KP_Prior:
- case XK_Up:
- case XK_KP_Up:
- y -= incr;
- handled = TRUE;
- break;
- case XK_KP_End:
- case XK_KP_Next:
- case XK_Down:
- case XK_KP_Down:
- y += incr;
- handled = TRUE;
- break;
- }
-
- switch (keysym)
- {
- case XK_KP_Home:
- case XK_KP_End:
- case XK_Left:
- case XK_KP_Left:
- x -= incr;
- handled = TRUE;
- break;
- case XK_KP_Prior:
- case XK_KP_Next:
- case XK_Right:
- case XK_KP_Right:
- x += incr;
- handled = TRUE;
- break;
- }
-
- if (handled)
- {
- MetaRectangle old_rect;
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Computed new window location %d,%d due to keypress\n",
- x, y);
-
- if (display->grab_wireframe_active)
- old_rect = display->grab_wireframe_rect;
- else
- meta_window_get_client_root_coords (window, &old_rect);
-
- meta_window_edge_resistance_for_move (window,
- old_rect.x,
- old_rect.y,
- &x,
- &y,
- NULL,
- smart_snap,
- TRUE);
-
- if (display->grab_wireframe_active)
- {
- meta_window_update_wireframe (window, x, y,
- display->grab_wireframe_rect.width,
- display->grab_wireframe_rect.height);
- }
- else
- {
- meta_window_move (window, TRUE, x, y);
- }
-
- meta_window_update_keyboard_move (window);
- }
-
- return handled;
-}
-
-static gboolean
-process_keyboard_resize_grab_op_change (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- KeySym keysym)
-{
- gboolean handled;
-
- handled = FALSE;
- switch (display->grab_op)
- {
- case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
- switch (keysym)
- {
- case XK_Up:
- case XK_KP_Up:
- display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N;
- handled = TRUE;
- break;
- case XK_Down:
- case XK_KP_Down:
- display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S;
- handled = TRUE;
- break;
- case XK_Left:
- case XK_KP_Left:
- display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W;
- handled = TRUE;
- break;
- case XK_Right:
- case XK_KP_Right:
- display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E;
- handled = TRUE;
- break;
- }
- break;
-
- case META_GRAB_OP_KEYBOARD_RESIZING_S:
- switch (keysym)
- {
- case XK_Left:
- case XK_KP_Left:
- display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W;
- handled = TRUE;
- break;
- case XK_Right:
- case XK_KP_Right:
- display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E;
- handled = TRUE;
- break;
- }
- break;
-
- case META_GRAB_OP_KEYBOARD_RESIZING_N:
- switch (keysym)
- {
- case XK_Left:
- case XK_KP_Left:
- display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W;
- handled = TRUE;
- break;
- case XK_Right:
- case XK_KP_Right:
- display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E;
- handled = TRUE;
- break;
- }
- break;
-
- case META_GRAB_OP_KEYBOARD_RESIZING_W:
- switch (keysym)
- {
- case XK_Up:
- case XK_KP_Up:
- display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N;
- handled = TRUE;
- break;
- case XK_Down:
- case XK_KP_Down:
- display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S;
- handled = TRUE;
- break;
- }
- break;
-
- case META_GRAB_OP_KEYBOARD_RESIZING_E:
- switch (keysym)
- {
- case XK_Up:
- case XK_KP_Up:
- display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N;
- handled = TRUE;
- break;
- case XK_Down:
- case XK_KP_Down:
- display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S;
- handled = TRUE;
- break;
- }
- break;
-
- case META_GRAB_OP_KEYBOARD_RESIZING_SE:
- case META_GRAB_OP_KEYBOARD_RESIZING_NE:
- case META_GRAB_OP_KEYBOARD_RESIZING_SW:
- case META_GRAB_OP_KEYBOARD_RESIZING_NW:
- break;
-
- default:
- g_assert_not_reached ();
- break;
- }
-
- if (handled)
- {
- meta_window_update_keyboard_resize (window, TRUE);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-process_keyboard_resize_grab (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- KeySym keysym)
-{
- gboolean handled;
- int height_inc;
- int width_inc;
- int width, height;
- gboolean smart_snap;
- int gravity;
-
- handled = FALSE;
-
- /* don't care about releases, but eat them, don't end grab */
- if (event->type == KeyRelease)
- return TRUE;
-
- /* don't end grab on modifier key presses */
- if (is_modifier (display, event->xkey.keycode))
- return TRUE;
-
- if (keysym == XK_Escape)
- {
- /* End resize and restore to original state. If not in
- * wireframe mode, we need to do a moveresize now to get the
- * position back to the original. If we are in wireframe mode,
- * we need to avoid moveresizing to the position of the
- * wireframe.
- */
- if (!display->grab_wireframe_active)
- meta_window_move_resize (display->grab_window,
- TRUE,
- display->grab_initial_window_pos.x,
- display->grab_initial_window_pos.y,
- display->grab_initial_window_pos.width,
- display->grab_initial_window_pos.height);
- else
- display->grab_was_cancelled = TRUE;
-
- return FALSE;
- }
-
- if (process_keyboard_resize_grab_op_change (display, screen, window,
- event, keysym))
- return TRUE;
-
- if (display->grab_wireframe_active)
- {
- width = display->grab_wireframe_rect.width;
- height = display->grab_wireframe_rect.height;
- }
- else
- {
- width = window->rect.width;
- height = window->rect.height;
- }
-
- gravity = meta_resize_gravity_from_grab_op (display->grab_op);
-
- smart_snap = (event->xkey.state & ShiftMask) != 0;
-
-#define SMALL_INCREMENT 1
-#define NORMAL_INCREMENT 10
-
- if (smart_snap)
- {
- height_inc = 1;
- width_inc = 1;
- }
- else if (event->xkey.state & ControlMask)
- {
- width_inc = SMALL_INCREMENT;
- height_inc = SMALL_INCREMENT;
- }
- else
- {
- width_inc = NORMAL_INCREMENT;
- height_inc = NORMAL_INCREMENT;
- }
-
- /* If this is a resize increment window, make the amount we resize
- * the window by match that amount (well, unless snap resizing...)
- */
- if (window->size_hints.width_inc > 1)
- width_inc = window->size_hints.width_inc;
- if (window->size_hints.height_inc > 1)
- height_inc = window->size_hints.height_inc;
-
- switch (keysym)
- {
- case XK_Up:
- case XK_KP_Up:
- switch (gravity)
- {
- case NorthGravity:
- case NorthWestGravity:
- case NorthEastGravity:
- /* Move bottom edge up */
- height -= height_inc;
- break;
-
- case SouthGravity:
- case SouthWestGravity:
- case SouthEastGravity:
- /* Move top edge up */
- height += height_inc;
- break;
-
- case EastGravity:
- case WestGravity:
- case CenterGravity:
- g_assert_not_reached ();
- break;
- }
-
- handled = TRUE;
- break;
-
- case XK_Down:
- case XK_KP_Down:
- switch (gravity)
- {
- case NorthGravity:
- case NorthWestGravity:
- case NorthEastGravity:
- /* Move bottom edge down */
- height += height_inc;
- break;
-
- case SouthGravity:
- case SouthWestGravity:
- case SouthEastGravity:
- /* Move top edge down */
- height -= height_inc;
- break;
-
- case EastGravity:
- case WestGravity:
- case CenterGravity:
- g_assert_not_reached ();
- break;
- }
-
- handled = TRUE;
- break;
-
- case XK_Left:
- case XK_KP_Left:
- switch (gravity)
- {
- case EastGravity:
- case SouthEastGravity:
- case NorthEastGravity:
- /* Move left edge left */
- width += width_inc;
- break;
-
- case WestGravity:
- case SouthWestGravity:
- case NorthWestGravity:
- /* Move right edge left */
- width -= width_inc;
- break;
-
- case NorthGravity:
- case SouthGravity:
- case CenterGravity:
- g_assert_not_reached ();
- break;
- }
-
- handled = TRUE;
- break;
-
- case XK_Right:
- case XK_KP_Right:
- switch (gravity)
- {
- case EastGravity:
- case SouthEastGravity:
- case NorthEastGravity:
- /* Move left edge right */
- width -= width_inc;
- break;
-
- case WestGravity:
- case SouthWestGravity:
- case NorthWestGravity:
- /* Move right edge right */
- width += width_inc;
- break;
-
- case NorthGravity:
- case SouthGravity:
- case CenterGravity:
- g_assert_not_reached ();
- break;
- }
-
- handled = TRUE;
- break;
-
- default:
- break;
- }
-
- /* fixup hack (just paranoia, not sure it's required) */
- if (height < 1)
- height = 1;
- if (width < 1)
- width = 1;
-
- if (handled)
- {
- MetaRectangle old_rect;
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Computed new window size due to keypress: "
- "%dx%d, gravity %s\n",
- width, height, meta_gravity_to_string (gravity));
-
- if (display->grab_wireframe_active)
- old_rect = display->grab_wireframe_rect;
- else
- old_rect = window->rect; /* Don't actually care about x,y */
-
- /* Do any edge resistance/snapping */
- meta_window_edge_resistance_for_resize (window,
- old_rect.width,
- old_rect.height,
- &width,
- &height,
- gravity,
- NULL,
- smart_snap,
- TRUE);
-
- if (display->grab_wireframe_active)
- {
- MetaRectangle new_position;
- meta_rectangle_resize_with_gravity (&display->grab_wireframe_rect,
- &new_position,
- gravity,
- width,
- height);
- meta_window_update_wireframe (window,
- new_position.x,
- new_position.y,
- new_position.width,
- new_position.height);
- }
- else
- {
- /* We don't need to update unless the specified width and height
- * are actually different from what we had before.
- */
- if (window->rect.width != width || window->rect.height != height)
- meta_window_resize_with_gravity (window,
- TRUE,
- width,
- height,
- gravity);
- }
- meta_window_update_keyboard_resize (window, FALSE);
- }
-
- return handled;
-}
-
-static gboolean
-end_keyboard_grab (MetaDisplay *display,
- unsigned int keycode)
-{
-#ifdef HAVE_XKB
- if (display->xkb_base_event_type > 0)
- {
- unsigned int primary_modifier;
- XkbStateRec state;
-
- primary_modifier = get_primary_modifier (display, display->grab_mask);
-
- XkbGetState (display->xdisplay, XkbUseCoreKbd, &state);
-
- if (!(primary_modifier & state.mods))
- return TRUE;
- }
- else
-#endif
- {
- if (keycode_is_primary_modifier (display, keycode, display->grab_mask))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-process_tab_grab (MetaDisplay *display,
- MetaScreen *screen,
- XEvent *event,
- KeySym keysym)
-{
- MetaKeyBindingAction action;
- gboolean popup_not_showing;
- gboolean backward;
- gboolean key_used;
- Window prev_xwindow;
- MetaWindow *prev_window;
-
- if (screen != display->grab_screen)
- return FALSE;
-
- g_return_val_if_fail (screen->tab_popup != NULL, FALSE);
-
- if (event->type == KeyRelease &&
- end_keyboard_grab (display, event->xkey.keycode))
- {
- /* We're done, move to the new window. */
- Window target_xwindow;
- MetaWindow *target_window;
-
- target_xwindow =
- (Window) meta_ui_tab_popup_get_selected (screen->tab_popup);
- target_window =
- meta_display_lookup_x_window (display, target_xwindow);
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Ending tab operation, primary modifier released\n");
-
- if (target_window)
- {
- target_window->tab_unminimized = FALSE;
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Activating target window\n");
-
- meta_topic (META_DEBUG_FOCUS, "Activating %s due to tab popup "
- "selection and turning mouse_mode off\n",
- target_window->desc);
- display->mouse_mode = FALSE;
- meta_window_activate (target_window, event->xkey.time);
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Ending grab early so we can focus the target window\n");
- meta_display_end_grab_op (display, event->xkey.time);
-
- return TRUE; /* we already ended the grab */
- }
-
- return FALSE; /* end grab */
- }
-
- /* don't care about other releases, but eat them, don't end grab */
- if (event->type == KeyRelease)
- return TRUE;
-
- /* don't end grab on modifier key presses */
- if (is_modifier (display, event->xkey.keycode))
- return TRUE;
-
- prev_xwindow = (Window) meta_ui_tab_popup_get_selected (screen->tab_popup);
- prev_window = meta_display_lookup_x_window (display, prev_xwindow);
- action = display_get_keybinding_action (display,
- keysym,
- event->xkey.keycode,
- display->grab_mask);
-
- /* Cancel when alt-Escape is pressed during using alt-Tab, and vice
- * versa.
- */
- switch (action)
- {
- case META_KEYBINDING_ACTION_CYCLE_PANELS:
- case META_KEYBINDING_ACTION_CYCLE_WINDOWS:
- case META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD:
- case META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD:
- /* CYCLE_* are traditionally Escape-based actions,
- * and should cancel traditionally Tab-based ones.
- */
- switch (display->grab_op)
- {
- case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL:
- case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK:
- /* carry on */
- break;
- default:
- return FALSE;
- }
- break;
- case META_KEYBINDING_ACTION_SWITCH_PANELS:
- case META_KEYBINDING_ACTION_SWITCH_WINDOWS:
- case META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD:
- case META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD:
- /* SWITCH_* are traditionally Tab-based actions,
- * and should cancel traditionally Escape-based ones.
- */
- switch (display->grab_op)
- {
- case META_GRAB_OP_KEYBOARD_TABBING_NORMAL:
- case META_GRAB_OP_KEYBOARD_TABBING_DOCK:
- /* carry on */
- break;
- default:
- /* Also, we must re-lower and re-minimize whatever window
- * we'd previously raised and unminimized.
- */
- meta_stack_set_positions (screen->stack,
- screen->display->grab_old_window_stacking);
- if (prev_window && prev_window->tab_unminimized)
- {
- meta_window_minimize (prev_window);
- prev_window->tab_unminimized = FALSE;
- }
- return FALSE;
- }
- break;
- case META_KEYBINDING_ACTION_CYCLE_GROUP:
- case META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD:
- case META_KEYBINDING_ACTION_SWITCH_GROUP:
- case META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD:
- switch (display->grab_op)
- {
- case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP:
- case META_GRAB_OP_KEYBOARD_TABBING_GROUP:
- /* carry on */
- break;
- default:
- return FALSE;
- }
-
- break;
- default:
- break;
- }
-
- /* !! TO HERE !!
- * alt-f6 during alt-{Tab,Escape} does not end the grab
- * but does change the grab op (and redraws the window,
- * of course).
- * See _{SWITCH,CYCLE}_GROUP.@@@
- */
-
- popup_not_showing = FALSE;
- key_used = FALSE;
- backward = FALSE;
-
- switch (action)
- {
- case META_KEYBINDING_ACTION_CYCLE_PANELS:
- case META_KEYBINDING_ACTION_CYCLE_WINDOWS:
- case META_KEYBINDING_ACTION_CYCLE_GROUP:
- popup_not_showing = TRUE;
- key_used = TRUE;
- break;
- case META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD:
- case META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD:
- case META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD:
- popup_not_showing = TRUE;
- key_used = TRUE;
- backward = TRUE;
- break;
- case META_KEYBINDING_ACTION_SWITCH_PANELS:
- case META_KEYBINDING_ACTION_SWITCH_WINDOWS:
- case META_KEYBINDING_ACTION_SWITCH_GROUP:
- key_used = TRUE;
- break;
- case META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD:
- case META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD:
- case META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD:
- key_used = TRUE;
- backward = TRUE;
- break;
- default:
- break;
- }
-
- if (key_used)
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Key pressed, moving tab focus in popup\n");
-
- if (event->xkey.state & ShiftMask)
- backward = !backward;
-
- if (backward)
- meta_ui_tab_popup_backward (screen->tab_popup);
- else
- meta_ui_tab_popup_forward (screen->tab_popup);
-
- if (popup_not_showing)
- {
- /* We can't actually change window focus, due to the grab.
- * but raise the window.
- */
- Window target_xwindow;
- MetaWindow *target_window;
-
- meta_stack_set_positions (screen->stack,
- display->grab_old_window_stacking);
-
- target_xwindow =
- (Window) meta_ui_tab_popup_get_selected (screen->tab_popup);
- target_window =
- meta_display_lookup_x_window (display, target_xwindow);
-
- if (prev_window && prev_window->tab_unminimized)
- {
- prev_window->tab_unminimized = FALSE;
- meta_window_minimize (prev_window);
- }
-
- if (target_window)
- {
- meta_window_raise (target_window);
- target_window->tab_unminimized = target_window->minimized;
- meta_window_unminimize (target_window);
- }
- }
- }
- else
- {
- /* end grab */
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Ending tabbing/cycling, uninteresting key pressed\n");
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Syncing to old stack positions.\n");
- meta_stack_set_positions (screen->stack,
- screen->display->grab_old_window_stacking);
-
- if (prev_window && prev_window->tab_unminimized)
- {
- meta_window_minimize (prev_window);
- prev_window->tab_unminimized = FALSE;
- }
- }
-
- return key_used;
-}
-
-static void
-handle_switch_to_workspace (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *event_window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- gint which = binding->handler->data;
- MetaWorkspace *workspace;
-
- if (which < 0)
- {
- /* Negative workspace numbers are directions with respect to the
- * current workspace. While we could insta-switch here by setting
- * workspace to the result of meta_workspace_get_neighbor(), when
- * people request a workspace switch to the left or right via
- * the keyboard, they actually want a tab popup. So we should
- * go there instead.
- *
- * Note that we're the only caller of that function, so perhaps
- * we should merge with it.
- */
- handle_workspace_switch (display, screen, event_window, event, binding);
- return;
- }
-
- workspace = meta_screen_get_workspace_by_index (screen, which);
-
- if (workspace)
- {
- meta_workspace_activate (workspace, event->xkey.time);
- }
- else
- {
- /* We could offer to create it I suppose */
- }
-}
-
-static void
-error_on_command (int command_index,
- const char *command,
- const char *message,
- int screen_number,
- guint32 timestamp)
-{
- if (command_index < 0)
- meta_warning ("Error on terminal command \"%s\": %s\n", command, message);
- else
- meta_warning ("Error on command %d \"%s\": %s\n",
- command_index, command, message);
-
- /*
- metacity-dialog said:
-
- FIXME offer to change the value of the command's gconf key
- */
-
- if (command && strcmp(command, "")!=0)
- {
- char *text = g_strdup_printf (
- /* Displayed when a keybinding which is
- * supposed to launch a program fails.
- */
- _("There was an error running "
- "<tt>%s</tt>:\n\n%s"),
- command,
- message);
-
- meta_show_dialog ("--error",
- text,
- NULL,
- screen_number,
- NULL, NULL);
-
- g_free (text);
-
- }
- else
- {
- meta_show_dialog ("--error",
- message,
- NULL,
- screen_number,
- NULL, NULL);
- }
-}
-
-static void
-set_display_setup_func (void *data)
-{
- const char *screen_name = data;
- char *full;
-
- full = g_strdup_printf ("DISPLAY=%s", screen_name);
-
- putenv (full);
-
- /* do not free full, because putenv is lame */
-}
-
-static gboolean
-meta_spawn_command_line_async_on_screen (const gchar *command_line,
- MetaScreen *screen,
- GError **error)
-{
- gboolean retval;
- gchar **argv = NULL;
-
- g_return_val_if_fail (command_line != NULL, FALSE);
-
- if (!g_shell_parse_argv (command_line,
- NULL, &argv,
- error))
- return FALSE;
-
- retval = g_spawn_async (NULL,
- argv,
- NULL,
- G_SPAWN_SEARCH_PATH,
- set_display_setup_func,
- screen->screen_name,
- NULL,
- error);
- g_strfreev (argv);
-
- return retval;
-}
-
-
-static void
-handle_run_command (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- gint which = binding->handler->data;
- const char *command;
- GError *err;
-
- command = meta_prefs_get_command (which);
-
- if (command == NULL)
- {
- char *s;
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "No command %d to run in response to keybinding press\n",
- which);
-
- s = g_strdup_printf (_("No command %d has been defined.\n"),
- which + 1);
- error_on_command (which, NULL, s, screen->number, event->xkey.time);
- g_free (s);
-
- return;
- }
-
- err = NULL;
- if (!meta_spawn_command_line_async_on_screen (command, screen, &err))
- {
- error_on_command (which, command, err->message, screen->number, event->xkey.time);
-
- g_error_free (err);
- }
-}
-
-
-static void
-handle_maximize_vertically (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- if (window->has_resize_func)
- {
- if (window->maximized_vertically)
- meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL);
- else
- meta_window_maximize (window, META_MAXIMIZE_VERTICAL);
- }
-}
-
-static void
-handle_maximize_horizontally (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- if (window->has_resize_func)
- {
- if (window->maximized_horizontally)
- meta_window_unmaximize (window, META_MAXIMIZE_HORIZONTAL);
- else
- meta_window_maximize (window, META_MAXIMIZE_HORIZONTAL);
- }
-}
-
-/* Move a window to a corner; to_bottom/to_right are FALSE for the
- * top or left edge, or TRUE for the bottom/right edge. xchange/ychange
- * are FALSE if that dimension is not to be changed, TRUE otherwise.
- * Together they describe which of the four corners, or four sides,
- * is desired.
- */
-static void
-handle_move_to_corner_backend (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- gboolean xchange,
- gboolean ychange,
- gboolean to_right,
- gboolean to_bottom)
-{
- MetaRectangle work_area;
- MetaRectangle outer;
- int orig_x, orig_y;
- int new_x, new_y;
- int frame_width, frame_height;
-
- meta_window_get_work_area_all_xineramas (window, &work_area);
- meta_window_get_outer_rect (window, &outer);
- meta_window_get_position (window, &orig_x, &orig_y);
-
- frame_width = (window->frame ? window->frame->child_x : 0);
- frame_height = (window->frame ? window->frame->child_y : 0);
-
- if (xchange) {
- new_x = work_area.x + (to_right ?
- (work_area.width + frame_width) - outer.width :
- 0);
- } else {
- new_x = orig_x;
- }
-
- if (ychange) {
- new_y = work_area.y + (to_bottom ?
- (work_area.height + frame_height) - outer.height :
- 0);
- } else {
- new_y = orig_y;
- }
-
- meta_window_move_resize (window,
- FALSE,
- new_x,
- new_y,
- window->rect.width,
- window->rect.height);
-}
-
-static void
-handle_move_to_corner_nw (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, FALSE, FALSE);
-}
-
-static void
-handle_move_to_corner_ne (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, TRUE, FALSE);
-}
-
-static void
-handle_move_to_corner_sw (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, FALSE, TRUE);
-}
-
-static void
-handle_move_to_corner_se (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, TRUE, TRUE);
-}
-
-static void
-handle_move_to_side_n (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- handle_move_to_corner_backend (display, screen, window, FALSE, TRUE, FALSE, FALSE);
-}
-
-static void
-handle_move_to_side_s (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- handle_move_to_corner_backend (display, screen, window, FALSE, TRUE, FALSE, TRUE);
-}
-
-static void
-handle_move_to_side_e (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- handle_move_to_corner_backend (display, screen, window, TRUE, FALSE, TRUE, FALSE);
-}
-
-static void
-handle_move_to_side_w (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- handle_move_to_corner_backend (display, screen, window, TRUE, FALSE, FALSE, FALSE);
-}
-
-static void
-handle_move_to_center (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- MetaRectangle work_area;
- MetaRectangle outer;
- int orig_x, orig_y;
- int frame_width, frame_height;
-
- meta_window_get_work_area_all_xineramas (window, &work_area);
- meta_window_get_outer_rect (window, &outer);
- meta_window_get_position (window, &orig_x, &orig_y);
-
- frame_width = (window->frame ? window->frame->child_x : 0);
- frame_height = (window->frame ? window->frame->child_y : 0);
-
- meta_window_move_resize (window,
- TRUE,
- work_area.x + (work_area.width +frame_width -outer.width )/2,
- work_area.y + (work_area.height+frame_height-outer.height)/2,
- window->rect.width,
- window->rect.height);
-}
-
-static gboolean
-process_workspace_switch_grab (MetaDisplay *display,
- MetaScreen *screen,
- XEvent *event,
- KeySym keysym)
-{
- MetaWorkspace *workspace;
-
- if (screen != display->grab_screen)
- return FALSE;
-
- g_return_val_if_fail (screen->tab_popup != NULL, FALSE);
-
- if (event->type == KeyRelease &&
- end_keyboard_grab (display, event->xkey.keycode))
- {
- /* We're done, move to the new workspace. */
- MetaWorkspace *target_workspace;
-
- target_workspace =
- (MetaWorkspace *) meta_ui_tab_popup_get_selected (screen->tab_popup);
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Ending workspace tab operation, primary modifier released\n");
-
- if (target_workspace == screen->active_workspace)
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Ending grab so we can focus on the target workspace\n");
- meta_display_end_grab_op (display, event->xkey.time);
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Focusing default window on target workspace\n");
-
- meta_workspace_focus_default_window (target_workspace,
- NULL,
- event->xkey.time);
-
- return TRUE; /* we already ended the grab */
- }
-
- /* Workspace switching should have already occurred on KeyPress */
- meta_warning ("target_workspace != active_workspace. Some other event must have occurred.\n");
-
- return FALSE; /* end grab */
- }
-
- /* don't care about other releases, but eat them, don't end grab */
- if (event->type == KeyRelease)
- return TRUE;
-
- /* don't end grab on modifier key presses */
- if (is_modifier (display, event->xkey.keycode))
- return TRUE;
-
- /* select the next workspace in the tabpopup */
- workspace =
- (MetaWorkspace *) meta_ui_tab_popup_get_selected (screen->tab_popup);
-
- if (workspace)
- {
- MetaWorkspace *target_workspace;
- MetaKeyBindingAction action;
-
- action = display_get_keybinding_action (display,
- keysym,
- event->xkey.keycode,
- display->grab_mask);
-
- switch (action)
- {
- case META_KEYBINDING_ACTION_WORKSPACE_UP:
- target_workspace = meta_workspace_get_neighbor (workspace,
- META_MOTION_UP);
- break;
-
- case META_KEYBINDING_ACTION_WORKSPACE_DOWN:
- target_workspace = meta_workspace_get_neighbor (workspace,
- META_MOTION_DOWN);
- break;
-
- case META_KEYBINDING_ACTION_WORKSPACE_LEFT:
- target_workspace = meta_workspace_get_neighbor (workspace,
- META_MOTION_LEFT);
- break;
-
- case META_KEYBINDING_ACTION_WORKSPACE_RIGHT:
- target_workspace = meta_workspace_get_neighbor (workspace,
- META_MOTION_RIGHT);
- break;
-
- default:
- target_workspace = NULL;
- break;
- }
-
- if (target_workspace)
- {
- meta_ui_tab_popup_select (screen->tab_popup,
- (MetaTabEntryKey) target_workspace);
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Tab key pressed, moving tab focus in popup\n");
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Activating target workspace\n");
-
- meta_workspace_activate (target_workspace, event->xkey.time);
-
- return TRUE; /* we already ended the grab */
- }
- }
-
- /* end grab */
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Ending workspace tabbing & focusing default window; uninteresting key pressed\n");
- workspace =
- (MetaWorkspace *) meta_ui_tab_popup_get_selected (screen->tab_popup);
- meta_workspace_focus_default_window (workspace, NULL, event->xkey.time);
- return FALSE;
-}
-
-static void
-handle_show_desktop (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- if (screen->active_workspace->showing_desktop)
- {
- meta_screen_unshow_desktop (screen);
- meta_workspace_focus_default_window (screen->active_workspace,
- NULL,
- event->xkey.time);
- }
- else
- meta_screen_show_desktop (screen, event->xkey.time);
-}
-
-static void
-handle_panel (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- MetaKeyBindingAction action = binding->handler->data;
- Atom action_atom;
- XClientMessageEvent ev;
-
- action_atom = None;
- switch (action)
- {
- /* FIXME: The numbers are wrong */
- case META_KEYBINDING_ACTION_PANEL_MAIN_MENU:
- action_atom = display->atom__GNOME_PANEL_ACTION_MAIN_MENU;
- break;
- case META_KEYBINDING_ACTION_PANEL_RUN_DIALOG:
- action_atom = display->atom__GNOME_PANEL_ACTION_RUN_DIALOG;
- break;
- default:
- return;
- }
-
- ev.type = ClientMessage;
- ev.window = screen->xroot;
- ev.message_type = display->atom__GNOME_PANEL_ACTION;
- ev.format = 32;
- ev.data.l[0] = action_atom;
- ev.data.l[1] = event->xkey.time;
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Sending panel message with timestamp %lu, and turning mouse_mode "
- "off due to keybinding press\n", event->xkey.time);
- display->mouse_mode = FALSE;
-
- meta_error_trap_push (display);
-
- /* Release the grab for the panel before sending the event */
- XUngrabKeyboard (display->xdisplay, event->xkey.time);
-
- XSendEvent (display->xdisplay,
- screen->xroot,
- False,
- StructureNotifyMask,
- (XEvent*) &ev);
-
- meta_error_trap_pop (display, FALSE);
-}
-
-static void
-handle_activate_window_menu (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *event_window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- if (display->focus_window)
- {
- int x, y;
-
- meta_window_get_position (display->focus_window,
- &x, &y);
-
- if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
- x += display->focus_window->rect.width;
-
- meta_window_show_menu (display->focus_window,
- x, y,
- 0,
- event->xkey.time);
- }
-}
-
-static MetaGrabOp
-tab_op_from_tab_type (MetaTabList type)
-{
- switch (type)
- {
- case META_TAB_LIST_NORMAL:
- return META_GRAB_OP_KEYBOARD_TABBING_NORMAL;
- case META_TAB_LIST_DOCKS:
- return META_GRAB_OP_KEYBOARD_TABBING_DOCK;
- case META_TAB_LIST_GROUP:
- return META_GRAB_OP_KEYBOARD_TABBING_GROUP;
- }
-
- g_assert_not_reached ();
-
- return 0;
-}
-
-static MetaGrabOp
-cycle_op_from_tab_type (MetaTabList type)
-{
- switch (type)
- {
- case META_TAB_LIST_NORMAL:
- return META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL;
- case META_TAB_LIST_DOCKS:
- return META_GRAB_OP_KEYBOARD_ESCAPING_DOCK;
- case META_TAB_LIST_GROUP:
- return META_GRAB_OP_KEYBOARD_ESCAPING_GROUP;
- }
-
- g_assert_not_reached ();
-
- return 0;
-}
-
-static void
-do_choose_window (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *event_window,
- XEvent *event,
- MetaKeyBinding *binding,
- gboolean backward,
- gboolean show_popup)
-{
- MetaTabList type = binding->handler->data;
- MetaWindow *initial_selection;
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Tab list = %u show_popup = %d\n", type, show_popup);
-
- /* reverse direction if shift is down */
- if (event->xkey.state & ShiftMask)
- backward = !backward;
-
- initial_selection = meta_display_get_tab_next (display,
- type,
- screen,
- screen->active_workspace,
- NULL,
- backward);
-
- /* Note that focus_window may not be in the tab chain, but it's OK */
- if (initial_selection == NULL)
- initial_selection = meta_display_get_tab_current (display,
- type, screen,
- screen->active_workspace);
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Initially selecting window %s\n",
- initial_selection ? initial_selection->desc : "(none)");
-
- if (initial_selection != NULL)
- {
- if (binding->mask == 0)
- {
- /* If no modifiers, we can't do the "hold down modifier to keep
- * moving" thing, so we just instaswitch by one window.
- */
- meta_topic (META_DEBUG_FOCUS,
- "Activating %s and turning off mouse_mode due to "
- "switch/cycle windows with no modifiers\n",
- initial_selection->desc);
- display->mouse_mode = FALSE;
- meta_window_activate (initial_selection, event->xkey.time);
- }
- else if (meta_display_begin_grab_op (display,
- screen,
- NULL,
- show_popup ?
- tab_op_from_tab_type (type) :
- cycle_op_from_tab_type (type),
- FALSE,
- FALSE,
- 0,
- binding->mask,
- event->xkey.time,
- 0, 0))
- {
- if (!primary_modifier_still_pressed (display,
- binding->mask))
- {
- /* This handles a race where modifier might be released
- * before we establish the grab. must end grab
- * prior to trying to focus a window.
- */
- meta_topic (META_DEBUG_FOCUS,
- "Ending grab, activating %s, and turning off "
- "mouse_mode due to switch/cycle windows where "
- "modifier was released prior to grab\n",
- initial_selection->desc);
- meta_display_end_grab_op (display, event->xkey.time);
- display->mouse_mode = FALSE;
- meta_window_activate (initial_selection, event->xkey.time);
- }
- else
- {
- meta_ui_tab_popup_select (screen->tab_popup,
- (MetaTabEntryKey) initial_selection->xwindow);
-
- if (show_popup)
- meta_ui_tab_popup_set_showing (screen->tab_popup,
- TRUE);
- else
- {
- meta_window_raise (initial_selection);
- initial_selection->tab_unminimized =
- initial_selection->minimized;
- meta_window_unminimize (initial_selection);
- }
- }
- }
- }
-}
-
-static void
-handle_switch (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *event_window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- gint backwards = binding->handler->flags & BINDING_IS_REVERSED;
-
- do_choose_window (display, screen, event_window, event, binding,
- backwards, TRUE);
-}
-
-static void
-handle_cycle (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *event_window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- gint backwards = binding->handler->flags & BINDING_IS_REVERSED;
-
- do_choose_window (display, screen, event_window, event, binding,
- backwards, FALSE);
-}
-
-
-static void
-handle_toggle_fullscreen (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- if (window->fullscreen)
- meta_window_unmake_fullscreen (window);
- else if (window->has_fullscreen_func)
- meta_window_make_fullscreen (window);
-}
-
-static void
-handle_toggle_above (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- if (window->wm_state_above)
- meta_window_unmake_above (window);
- else
- meta_window_make_above (window);
-}
-
-static void
-handle_toggle_maximized (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- if (META_WINDOW_MAXIMIZED (window))
- meta_window_unmaximize (window,
- META_MAXIMIZE_HORIZONTAL |
- META_MAXIMIZE_VERTICAL);
- else if (window->has_maximize_func)
- meta_window_maximize (window,
- META_MAXIMIZE_HORIZONTAL |
- META_MAXIMIZE_VERTICAL);
-}
-
-static void
-handle_maximize (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- if (window->has_maximize_func)
- meta_window_maximize (window,
- META_MAXIMIZE_HORIZONTAL |
- META_MAXIMIZE_VERTICAL);
-}
-
-static void
-handle_unmaximize (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- if (window->maximized_vertically || window->maximized_horizontally)
- meta_window_unmaximize (window,
- META_MAXIMIZE_HORIZONTAL |
- META_MAXIMIZE_VERTICAL);
-}
-
-static void
-handle_toggle_shaded (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- if (window->shaded)
- meta_window_unshade (window, event->xkey.time);
- else if (window->has_shade_func)
- meta_window_shade (window, event->xkey.time);
-}
-
-static void
-handle_close (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- if (window->has_close_func)
- meta_window_delete (window, event->xkey.time);
-}
-
-static void
-handle_minimize (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- if (window->has_minimize_func)
- meta_window_minimize (window);
-}
-
-static void
-handle_begin_move (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- if (window->has_move_func)
- {
- meta_window_begin_grab_op (window,
- META_GRAB_OP_KEYBOARD_MOVING,
- FALSE,
- event->xkey.time);
- }
-}
-
-static void
-handle_begin_resize (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- if (window->has_resize_func)
- {
- meta_window_begin_grab_op (window,
- META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN,
- FALSE,
- event->xkey.time);
- }
-}
-
-static void
-handle_toggle_on_all_workspaces (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- if (window->on_all_workspaces)
- meta_window_unstick (window);
- else
- meta_window_stick (window);
-}
-
-static void
-handle_move_to_workspace (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- gint which = binding->handler->data;
- gboolean flip = (which < 0);
- MetaWorkspace *workspace;
-
- /* If which is zero or positive, it's a workspace number, and the window
- * should move to the workspace with that number.
- *
- * However, if it's negative, it's a direction with respect to the current
- * position; it's expressed as a member of the MetaMotionDirection enum,
- * all of whose members are negative. Such a change is called a flip.
- */
-
- if (window->always_sticky)
- return;
-
- workspace = NULL;
- if (flip)
- {
- workspace = meta_workspace_get_neighbor (screen->active_workspace,
- which);
- }
- else
- {
- workspace = meta_screen_get_workspace_by_index (screen, which);
- }
-
- if (workspace)
- {
- /* Activate second, so the window is never unmapped */
- meta_window_change_workspace (window, workspace);
- if (flip)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Resetting mouse_mode to FALSE due to "
- "handle_move_to_workspace() call with flip set.\n");
- workspace->screen->display->mouse_mode = FALSE;
- meta_workspace_activate_with_focus (workspace,
- window,
- event->xkey.time);
- }
- }
- else
- {
- /* We could offer to create it I suppose */
- }
-}
-
-static void
-handle_raise_or_lower (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- /* Get window at pointer */
-
- MetaWindow *above = NULL;
-
- /* Check if top */
- if (meta_stack_get_top (window->screen->stack) == window)
- {
- meta_window_lower (window);
- return;
- }
-
- /* else check if windows in same layer are intersecting it */
-
- above = meta_stack_get_above (window->screen->stack, window, TRUE);
-
- while (above)
- {
- MetaRectangle tmp, win_rect, above_rect;
-
- if (above->mapped)
- {
- meta_window_get_outer_rect (window, &win_rect);
- meta_window_get_outer_rect (above, &above_rect);
-
- /* Check if obscured */
- if (meta_rectangle_intersect (&win_rect, &above_rect, &tmp))
- {
- meta_window_raise (window);
- return;
- }
- }
-
- above = meta_stack_get_above (window->screen->stack, above, TRUE);
- }
-
- /* window is not obscured */
- meta_window_lower (window);
-}
-
-static void
-handle_raise (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- meta_window_raise (window);
-}
-
-static void
-handle_lower (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- meta_window_lower (window);
-}
-
-static void
-handle_workspace_switch (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- gint motion = binding->handler->data;
- unsigned int grab_mask;
-
- g_assert (motion < 0);
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Starting tab between workspaces, showing popup\n");
-
- /* FIXME should we use binding->mask ? */
- grab_mask = event->xkey.state & ~(display->ignored_modifier_mask);
-
- if (meta_display_begin_grab_op (display,
- screen,
- NULL,
- META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING,
- FALSE,
- FALSE,
- 0,
- grab_mask,
- event->xkey.time,
- 0, 0))
- {
- MetaWorkspace *next;
- gboolean grabbed_before_release;
-
- next = meta_workspace_get_neighbor (screen->active_workspace, motion);
- g_assert (next);
-
- grabbed_before_release = primary_modifier_still_pressed (display, grab_mask);
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Activating target workspace\n");
-
- if (!grabbed_before_release)
- {
- /* end the grab right away, modifier possibly released
- * before we could establish the grab and receive the
- * release event. Must end grab before we can switch
- * spaces.
- */
- meta_display_end_grab_op (display, event->xkey.time);
- }
-
- meta_workspace_activate (next, event->xkey.time);
-
- if (grabbed_before_release)
- {
- meta_ui_tab_popup_select (screen->tab_popup, (MetaTabEntryKey) next);
-
- /* only after selecting proper space */
- meta_ui_tab_popup_set_showing (screen->tab_popup, TRUE);
- }
- }
-}
-
-static void
-handle_set_spew_mark (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- meta_verbose ("-- MARK MARK MARK MARK --\n");
-}
-
-void
-meta_set_keybindings_disabled (gboolean setting)
-{
- all_bindings_disabled = setting;
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Keybindings %s\n", all_bindings_disabled ? "disabled" : "enabled");
-}
-
-static void
-handle_run_terminal (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding)
-{
- const char *command;
- GError *err;
-
- command = meta_prefs_get_terminal_command ();
-
- if (command == NULL)
- {
- char *s;
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "No terminal command to run in response to "
- "keybinding press\n");
-
- s = g_strdup_printf (_("No terminal command has been defined.\n"));
- error_on_command (-1, NULL, s, screen->number, event->xkey.time);
- g_free (s);
-
- return;
- }
-
- err = NULL;
- if (!meta_spawn_command_line_async_on_screen (command, screen, &err))
- {
- error_on_command (-1, command, err->message, screen->number,
- event->xkey.time);
-
- g_error_free (err);
- }
-}
diff --git a/src/core/keybindings.h b/src/core/keybindings.h
deleted file mode 100644
index 618520b4..00000000
--- a/src/core/keybindings.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * \file keybindings.h Grab and ungrab keys, and process the key events
- *
- * Performs global X grabs on the keys we need to be told about, like
- * the one to close a window. It also deals with incoming key events.
- */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_KEYBINDINGS_H
-#define META_KEYBINDINGS_H
-
-#include "display-private.h"
-#include "window.h"
-
-void meta_display_init_keys (MetaDisplay *display);
-void meta_display_shutdown_keys (MetaDisplay *display);
-void meta_screen_grab_keys (MetaScreen *screen);
-void meta_screen_ungrab_keys (MetaScreen *screen);
-gboolean meta_screen_grab_all_keys (MetaScreen *screen,
- guint32 timestamp);
-void meta_screen_ungrab_all_keys (MetaScreen *screen,
- guint32 timestamp);
-void meta_window_grab_keys (MetaWindow *window);
-void meta_window_ungrab_keys (MetaWindow *window);
-gboolean meta_window_grab_all_keys (MetaWindow *window,
- guint32 timestamp);
-void meta_window_ungrab_all_keys (MetaWindow *window,
- guint32 timestamp);
-void meta_display_process_key_event (MetaDisplay *display,
- MetaWindow *window,
- XEvent *event);
-void meta_set_keybindings_disabled (gboolean setting);
-void meta_display_process_mapping_event (MetaDisplay *display,
- XEvent *event);
-
-#endif
-
-
-
-
diff --git a/src/core/main.c b/src/core/main.c
deleted file mode 100644
index 19c2dd38..00000000
--- a/src/core/main.c
+++ /dev/null
@@ -1,620 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity main() */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2006 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-/**
- * \file
- * Program startup.
- * Functions which parse the command-line arguments, create the display,
- * kick everything off and then close down Metacity when it's time to go.
- */
-
-/**
- * \mainpage
- * Metacity - a boring window manager for the adult in you
- *
- * Many window managers are like Marshmallow Froot Loops; Metacity
- * is like Cheerios.
- *
- * The best way to get a handle on how the whole system fits together
- * is discussed in doc/code-overview.txt; if you're looking for functions
- * to investigate, read main(), meta_display_open(), and event_callback().
- */
-
-#define _GNU_SOURCE
-#define _SVID_SOURCE /* for putenv() and some signal-related functions */
-
-#include <config.h>
-#include "main.h"
-#include "util.h"
-#include "display-private.h"
-#include "errors.h"
-#include "ui.h"
-#include "session.h"
-#include "prefs.h"
-
-#include <glib-object.h>
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <signal.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <locale.h>
-#include <time.h>
-
-/**
- * The exit code we'll return to our parent process when we eventually die.
- */
-static MetaExitCode meta_exit_code = META_EXIT_SUCCESS;
-
-/**
- * Handle on the main loop, so that we have an easy way of shutting Metacity
- * down.
- */
-static GMainLoop *meta_main_loop = NULL;
-
-/**
- * If set, Metacity will spawn an identical copy of itself immediately
- * before quitting.
- */
-static gboolean meta_restart_after_quit = FALSE;
-
-static void prefs_changed_callback (MetaPreference pref,
- gpointer data);
-
-/**
- * Prints log messages. If Metacity was compiled with backtrace support,
- * also prints a backtrace (see meta_print_backtrace()).
- *
- * \param log_domain the domain the error occurred in (we ignore this)
- * \param log_level the log level so that we can filter out less
- * important messages
- * \param message the message to log
- * \param user_data arbitrary data (we ignore this)
- */
-static void
-log_handler (const gchar *log_domain,
- GLogLevelFlags log_level,
- const gchar *message,
- gpointer user_data)
-{
- meta_warning ("Log level %d: %s\n", log_level, message);
- meta_print_backtrace ();
-}
-
-/**
- * Prints the version notice. This is shown when Metacity is called
- * with the --version switch.
- */
-static void
-version (void)
-{
- g_print (_("metacity %s\n"
- "Copyright (C) 2001-2008 Havoc Pennington, Red Hat, Inc., and others\n"
- "This is free software; see the source for copying conditions.\n"
- "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"),
- VERSION);
- exit (0);
-}
-
-/**
- * Prints a list of which configure script options were used to
- * build this copy of Metacity. This is actually always called
- * on startup, but it's all no-op unless we're in verbose mode
- * (see meta_set_verbose).
- */
-static void
-meta_print_compilation_info (void)
-{
-#ifdef HAVE_SHAPE
- meta_verbose ("Compiled with shape extension\n");
-#else
- meta_verbose ("Compiled without shape extension\n");
-#endif
-#ifdef HAVE_XINERAMA
- meta_topic (META_DEBUG_XINERAMA, "Compiled with Xinerama extension\n");
-#else
- meta_topic (META_DEBUG_XINERAMA, "Compiled without Xinerama extension\n");
-#endif
-#ifdef HAVE_XFREE_XINERAMA
- meta_topic (META_DEBUG_XINERAMA, " (using XFree86 Xinerama)\n");
-#else
- meta_topic (META_DEBUG_XINERAMA, " (not using XFree86 Xinerama)\n");
-#endif
-#ifdef HAVE_SOLARIS_XINERAMA
- meta_topic (META_DEBUG_XINERAMA, " (using Solaris Xinerama)\n");
-#else
- meta_topic (META_DEBUG_XINERAMA, " (not using Solaris Xinerama)\n");
-#endif
-#ifdef HAVE_XSYNC
- meta_verbose ("Compiled with sync extension\n");
-#else
- meta_verbose ("Compiled without sync extension\n");
-#endif
-#ifdef HAVE_RANDR
- meta_verbose ("Compiled with randr extension\n");
-#else
- meta_verbose ("Compiled without randr extension\n");
-#endif
-#ifdef HAVE_STARTUP_NOTIFICATION
- meta_verbose ("Compiled with startup notification\n");
-#else
- meta_verbose ("Compiled without startup notification\n");
-#endif
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- meta_verbose ("Compiled with composite extensions\n");
-#else
- meta_verbose ("Compiled without composite extensions\n");
-#endif
-}
-
-/**
- * Prints the version number, the current timestamp (not the
- * build date), the locale, the character encoding, and a list
- * of configure script options that were used to build this
- * copy of Metacity. This is actually always called
- * on startup, but it's all no-op unless we're in verbose mode
- * (see meta_set_verbose).
- */
-static void
-meta_print_self_identity (void)
-{
- char buf[256];
- GDate d;
- const char *charset;
-
- /* Version and current date. */
- g_date_clear (&d, 1);
- g_date_set_time_t (&d, time (NULL));
- g_date_strftime (buf, sizeof (buf), "%x", &d);
- meta_verbose ("Metacity version %s running on %s\n",
- VERSION, buf);
-
- /* Locale and encoding. */
- g_get_charset (&charset);
- meta_verbose ("Running in locale \"%s\" with encoding \"%s\"\n",
- setlocale (LC_ALL, NULL), charset);
-
- /* Compilation settings. */
- meta_print_compilation_info ();
-}
-
-/**
- * The set of possible options that can be set on Metacity's
- * command line. This type exists so that meta_parse_options() can
- * write to an instance of it.
- */
-typedef struct
-{
- gchar *save_file;
- gchar *display_name;
- gchar *client_id;
- gboolean replace_wm;
- gboolean disable_sm;
- gboolean print_version;
- gboolean sync;
- gboolean composite;
- gboolean no_composite;
-} MetaArguments;
-
-#ifdef HAVE_COMPOSITE_EXTENSIONS
-#define COMPOSITE_OPTS_FLAGS 0
-#else /* HAVE_COMPOSITE_EXTENSIONS */
-/* No compositor, so don't show the arguments in --help */
-#define COMPOSITE_OPTS_FLAGS G_OPTION_FLAG_HIDDEN
-#endif /* HAVE_COMPOSITE_EXTENSIONS */
-
-/**
- * Parses argc and argv and returns the
- * arguments that Metacity understands in meta_args.
- *
- * The strange call signature has to be written like it is so
- * that g_option_context_parse() gets a chance to modify argc and
- * argv.
- *
- * \param argc Pointer to the number of arguments Metacity was given
- * \param argv Pointer to the array of arguments Metacity was given
- * \param meta_args The result of parsing the arguments.
- **/
-static void
-meta_parse_options (int *argc, char ***argv,
- MetaArguments *meta_args)
-{
- MetaArguments my_args = {NULL, NULL, NULL,
- FALSE, FALSE, FALSE, FALSE, FALSE};
- GOptionEntry options[] = {
- {
- "sm-disable", 0, 0, G_OPTION_ARG_NONE,
- &my_args.disable_sm,
- N_("Disable connection to session manager"),
- NULL
- },
- {
- "replace", 0, 0, G_OPTION_ARG_NONE,
- &my_args.replace_wm,
- N_("Replace the running window manager with Metacity"),
- NULL
- },
- {
- "sm-client-id", 0, 0, G_OPTION_ARG_STRING,
- &my_args.client_id,
- N_("Specify session management ID"),
- "ID"
- },
- {
- "display", 'd', 0, G_OPTION_ARG_STRING,
- &my_args.display_name, N_("X Display to use"),
- "DISPLAY"
- },
- {
- "sm-save-file", 0, 0, G_OPTION_ARG_FILENAME,
- &my_args.save_file,
- N_("Initialize session from savefile"),
- "FILE"
- },
- {
- "version", 0, 0, G_OPTION_ARG_NONE,
- &my_args.print_version,
- N_("Print version"),
- NULL
- },
- {
- "sync", 0, 0, G_OPTION_ARG_NONE,
- &my_args.sync,
- N_("Make X calls synchronous"),
- NULL
- },
- {
- "composite", 'c', COMPOSITE_OPTS_FLAGS, G_OPTION_ARG_NONE,
- &my_args.composite,
- N_("Turn compositing on"),
- NULL
- },
- {
- "no-composite", 0, COMPOSITE_OPTS_FLAGS, G_OPTION_ARG_NONE,
- &my_args.no_composite,
- N_("Turn compositing off"),
- NULL
- },
- {NULL}
- };
- GOptionContext *ctx;
- GError *error = NULL;
-
- ctx = g_option_context_new (NULL);
- g_option_context_add_main_entries (ctx, options, "metacity");
- if (!g_option_context_parse (ctx, argc, argv, &error))
- {
- g_print ("metacity: %s\n", error->message);
- exit(1);
- }
- g_option_context_free (ctx);
- /* Return the parsed options through the meta_args param. */
- *meta_args = my_args;
-}
-
-/**
- * Selects which display Metacity should use. It first tries to use
- * display_name as the display. If display_name is NULL then
- * try to use the environment variable METACITY_DISPLAY. If that
- * also is NULL, use the default - :0.0
- */
-static void
-meta_select_display (gchar *display_name)
-{
- gchar *envVar = "";
- if (display_name)
- envVar = g_strconcat ("DISPLAY=", display_name, NULL);
- else if (g_getenv ("METACITY_DISPLAY"))
- envVar = g_strconcat ("DISPLAY=",
- g_getenv ("METACITY_DISPLAY"), NULL);
- /* DO NOT FREE envVar, putenv() sucks */
- putenv (envVar);
-}
-
-static void
-meta_finalize (void)
-{
- meta_display_close (meta_get_display (),
- CurrentTime); /* I doubt correct timestamps matter here */
-
- meta_session_shutdown ();
-}
-
-static void
-sigterm_handler (int signum)
-{
- meta_finalize ();
-
- exit (meta_exit_code);
-}
-
-/**
- * This is where the story begins. It parses commandline options and
- * environment variables, sets up the screen, hands control off to
- * GTK, and cleans up afterwards.
- *
- * \param argc Number of arguments (as usual)
- * \param argv Array of arguments (as usual)
- *
- * \bug It's a bit long. It would be good to split it out into separate
- * functions.
- */
-int
-main (int argc, char **argv)
-{
- struct sigaction act;
- sigset_t empty_mask;
- MetaArguments meta_args;
- const gchar *log_domains[] = {
- NULL, G_LOG_DOMAIN, "Gtk", "Gdk", "GLib",
- "Pango", "GLib-GObject", "GThread"
- };
- guint i;
-
- if (!g_thread_supported ())
- g_thread_init (NULL);
-
- if (setlocale (LC_ALL, "") == NULL)
- meta_warning ("Locale not understood by C library, internationalization will not work\n");
-
- sigemptyset (&empty_mask);
- act.sa_handler = SIG_IGN;
- act.sa_mask = empty_mask;
- act.sa_flags = 0;
- if (sigaction (SIGPIPE, &act, NULL) < 0)
- g_printerr ("Failed to register SIGPIPE handler: %s\n",
- g_strerror (errno));
-#ifdef SIGXFSZ
- if (sigaction (SIGXFSZ, &act, NULL) < 0)
- g_printerr ("Failed to register SIGXFSZ handler: %s\n",
- g_strerror (errno));
-#endif
-
- act.sa_handler = &sigterm_handler;
- if (sigaction (SIGTERM, &act, NULL) < 0)
- g_printerr ("Failed to register SIGTERM handler: %s\n",
- g_strerror (errno));
-
- if (g_getenv ("METACITY_VERBOSE"))
- meta_set_verbose (TRUE);
- if (g_getenv ("METACITY_DEBUG"))
- meta_set_debugging (TRUE);
-
- if (g_get_home_dir ())
- if (chdir (g_get_home_dir ()) < 0)
- meta_warning ("Could not change to home directory %s.\n",
- g_get_home_dir ());
-
- meta_print_self_identity ();
-
- bindtextdomain (GETTEXT_PACKAGE, METACITY_LOCALEDIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
- textdomain (GETTEXT_PACKAGE);
-
- /* Parse command line arguments.*/
- meta_parse_options (&argc, &argv, &meta_args);
-
- meta_set_syncing (meta_args.sync || (g_getenv ("METACITY_SYNC") != NULL));
-
- if (meta_args.print_version)
- version ();
-
- meta_select_display (meta_args.display_name);
-
- if (meta_args.replace_wm)
- meta_set_replace_current_wm (TRUE);
-
- if (meta_args.save_file && meta_args.client_id)
- meta_fatal ("Can't specify both SM save file and SM client id\n");
-
- meta_main_loop = g_main_loop_new (NULL, FALSE);
-
- g_type_init ();
-
- meta_ui_init (&argc, &argv);
-
- /* must be after UI init so we can override GDK handlers */
- meta_errors_init ();
-
- /* Load prefs */
- meta_prefs_init ();
- meta_prefs_add_listener (prefs_changed_callback, NULL);
-
-
-#if 1
-
- for (i=0; i<G_N_ELEMENTS(log_domains); i++)
- g_log_set_handler (log_domains[i],
- G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
- log_handler, NULL);
-
-#endif
-
- if (g_getenv ("METACITY_G_FATAL_WARNINGS") != NULL)
- g_log_set_always_fatal (G_LOG_LEVEL_MASK);
-
- meta_ui_set_current_theme (meta_prefs_get_theme (), FALSE);
-
- /* Try to find some theme that'll work if the theme preference
- * doesn't exist. First try Simple (the default theme) then just
- * try anything in the themes directory.
- */
- if (!meta_ui_have_a_theme ())
- meta_ui_set_current_theme ("Simple", FALSE);
-
- if (!meta_ui_have_a_theme ())
- {
- const char *dir_entry = NULL;
- GError *err = NULL;
- GDir *themes_dir = NULL;
-
- if (!(themes_dir = g_dir_open (METACITY_DATADIR"/themes", 0, &err)))
- {
- meta_fatal (_("Failed to scan themes directory: %s\n"), err->message);
- g_error_free (err);
- }
- else
- {
- while (((dir_entry = g_dir_read_name (themes_dir)) != NULL) &&
- (!meta_ui_have_a_theme ()))
- {
- meta_ui_set_current_theme (dir_entry, FALSE);
- }
-
- g_dir_close (themes_dir);
- }
- }
-
- if (!meta_ui_have_a_theme ())
- meta_fatal (_("Could not find a theme! Be sure %s exists and contains the usual themes.\n"),
- METACITY_DATADIR"/themes");
-
- /* Connect to SM as late as possible - but before managing display,
- * or we might try to manage a window before we have the session
- * info
- */
- if (!meta_args.disable_sm)
- {
- if (meta_args.client_id == NULL)
- {
- const gchar *desktop_autostart_id;
-
- desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
-
- if (desktop_autostart_id != NULL)
- meta_args.client_id = g_strdup (desktop_autostart_id);
- }
-
- /* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to
- * use the same client id. */
- g_unsetenv ("DESKTOP_AUTOSTART_ID");
-
- meta_session_init (meta_args.client_id, meta_args.save_file);
- }
- /* Free memory possibly allocated by the argument parsing which are
- * no longer needed.
- */
- g_free (meta_args.save_file);
- g_free (meta_args.display_name);
- g_free (meta_args.client_id);
-
- if (meta_args.composite || meta_args.no_composite)
- meta_prefs_set_compositing_manager (meta_args.composite);
-
- if (!meta_display_open ())
- meta_exit (META_EXIT_ERROR);
-
- g_main_loop_run (meta_main_loop);
-
- meta_finalize ();
-
- if (meta_restart_after_quit)
- {
- GError *err;
-
- err = NULL;
- if (!g_spawn_async (NULL,
- argv,
- NULL,
- G_SPAWN_SEARCH_PATH,
- NULL,
- NULL,
- NULL,
- &err))
- {
- meta_fatal (_("Failed to restart: %s\n"),
- err->message);
- g_error_free (err); /* not reached anyhow */
- meta_exit_code = META_EXIT_ERROR;
- }
- }
-
- return meta_exit_code;
-}
-
-/**
- * Stops Metacity. This tells the event loop to stop processing; it is rather
- * dangerous to use this rather than meta_restart() because this will leave
- * the user with no window manager. We generally do this only if, for example,
- * the session manager asks us to; we assume the session manager knows what
- * it's talking about.
- *
- * \param code The success or failure code to return to the calling process.
- */
-void
-meta_quit (MetaExitCode code)
-{
- meta_exit_code = code;
-
- if (g_main_loop_is_running (meta_main_loop))
- g_main_loop_quit (meta_main_loop);
-}
-
-/**
- * Restarts Metacity. In practice, this tells the event loop to stop
- * processing, having first set the meta_restart_after_quit flag which
- * tells Metacity to spawn an identical copy of itself before quitting.
- * This happens on receipt of a _METACITY_RESTART_MESSAGE client event.
- */
-void
-meta_restart (void)
-{
- meta_restart_after_quit = TRUE;
- meta_quit (META_EXIT_SUCCESS);
-}
-
-/**
- * Called on pref changes. (One of several functions of its kind and purpose.)
- *
- * \bug Why are these particular prefs handled in main.c and not others?
- * Should they be?
- *
- * \param pref Which preference has changed
- * \param data Arbitrary data (which we ignore)
- */
-static void
-prefs_changed_callback (MetaPreference pref,
- gpointer data)
-{
- switch (pref)
- {
- case META_PREF_THEME:
- meta_ui_set_current_theme (meta_prefs_get_theme (), FALSE);
- meta_display_retheme_all ();
- break;
-
- case META_PREF_CURSOR_THEME:
- case META_PREF_CURSOR_SIZE:
- meta_display_set_cursor_theme (meta_prefs_get_cursor_theme (),
- meta_prefs_get_cursor_size ());
- break;
- default:
- /* handled elsewhere or otherwise */
- break;
- }
-}
diff --git a/src/core/metacity-Xatomtype.h b/src/core/metacity-Xatomtype.h
deleted file mode 100644
index d14d3ab7..00000000
--- a/src/core/metacity-Xatomtype.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * \file metacity-Xatomtype.h Types for communicating with X about properties
- *
- * This files defines crock C structures for calling XGetWindowProperty and
- * XChangeProperty. All fields must be longs as the semantics of property
- * routines will handle conversion to and from actual 32 bit objects. If your
- * compiler doesn't treat &structoflongs the same as &arrayoflongs[0], you
- * will have some work to do.
- */
-
-/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-#ifndef _XATOMTYPE_H_
-#define _XATOMTYPE_H_
-
-#define BOOL long
-#define SIGNEDINT long
-#define UNSIGNEDINT unsigned long
-#define RESOURCEID unsigned long
-
-
-/* this structure may be extended, but do not change the order */
-typedef struct {
- UNSIGNEDINT flags;
- SIGNEDINT x, y, width, height; /* need to cvt; only for pre-ICCCM */
- SIGNEDINT minWidth, minHeight; /* need to cvt */
- SIGNEDINT maxWidth, maxHeight; /* need to cvt */
- SIGNEDINT widthInc, heightInc; /* need to cvt */
- SIGNEDINT minAspectX, minAspectY; /* need to cvt */
- SIGNEDINT maxAspectX, maxAspectY; /* need to cvt */
- SIGNEDINT baseWidth,baseHeight; /* need to cvt; ICCCM version 1 */
- SIGNEDINT winGravity; /* need to cvt; ICCCM version 1 */
-} xPropSizeHints;
-#define OldNumPropSizeElements 15 /* pre-ICCCM */
-#define NumPropSizeElements 18 /* ICCCM version 1 */
-
-/* this structure may be extended, but do not change the order */
-/* RGB properties */
-typedef struct {
- RESOURCEID colormap;
- UNSIGNEDINT red_max;
- UNSIGNEDINT red_mult;
- UNSIGNEDINT green_max;
- UNSIGNEDINT green_mult;
- UNSIGNEDINT blue_max;
- UNSIGNEDINT blue_mult;
- UNSIGNEDINT base_pixel;
- RESOURCEID visualid; /* ICCCM version 1 */
- RESOURCEID killid; /* ICCCM version 1 */
-} xPropStandardColormap;
-#define OldNumPropStandardColormapElements 8 /* pre-ICCCM */
-#define NumPropStandardColormapElements 10 /* ICCCM version 1 */
-
-
-/* this structure may be extended, but do not change the order */
-typedef struct {
- UNSIGNEDINT flags;
- BOOL input; /* need to convert */
- SIGNEDINT initialState; /* need to cvt */
- RESOURCEID iconPixmap;
- RESOURCEID iconWindow;
- SIGNEDINT iconX; /* need to cvt */
- SIGNEDINT iconY; /* need to cvt */
- RESOURCEID iconMask;
- UNSIGNEDINT windowGroup;
- } xPropWMHints;
-#define NumPropWMHintsElements 9 /* number of elements in this structure */
-
-/* this structure defines the icon size hints information */
-typedef struct {
- SIGNEDINT minWidth, minHeight; /* need to cvt */
- SIGNEDINT maxWidth, maxHeight; /* need to cvt */
- SIGNEDINT widthInc, heightInc; /* need to cvt */
- } xPropIconSize;
-#define NumPropIconSizeElements 6 /* number of elements in this structure */
-
-/* this structure defines the window manager state information */
-typedef struct {
- SIGNEDINT state; /* need to cvt */
- RESOURCEID iconWindow;
-} xPropWMState;
-#define NumPropWMStateElements 2 /* number of elements in struct */
-
-#undef BOOL
-#undef SIGNEDINT
-#undef UNSIGNEDINT
-#undef RESOURCEID
-
-#endif /* _XATOMTYPE_H_ */
diff --git a/src/core/place.c b/src/core/place.c
deleted file mode 100644
index 901335c9..00000000
--- a/src/core/place.c
+++ /dev/null
@@ -1,932 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity window placement */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2002, 2003 Red Hat, Inc.
- * Copyright (C) 2003 Rob Adams
- * Copyright (C) 2005 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-
-#include "place.h"
-#include "workspace.h"
-#include "prefs.h"
-#include <gdk/gdk.h>
-#include <math.h>
-#include <stdlib.h>
-
-typedef enum
-{
- META_LEFT,
- META_RIGHT,
- META_TOP,
- META_BOTTOM
-} MetaWindowDirection;
-
-static gint
-northwestcmp (gconstpointer a, gconstpointer b)
-{
- MetaWindow *aw = (gpointer) a;
- MetaWindow *bw = (gpointer) b;
- int from_origin_a;
- int from_origin_b;
- int ax, ay, bx, by;
-
- /* we're interested in the frame position for cascading,
- * not meta_window_get_position()
- */
- if (aw->frame)
- {
- ax = aw->frame->rect.x;
- ay = aw->frame->rect.y;
- }
- else
- {
- ax = aw->rect.x;
- ay = aw->rect.y;
- }
-
- if (bw->frame)
- {
- bx = bw->frame->rect.x;
- by = bw->frame->rect.y;
- }
- else
- {
- bx = bw->rect.x;
- by = bw->rect.y;
- }
-
- /* probably there's a fast good-enough-guess we could use here. */
- from_origin_a = sqrt (ax * ax + ay * ay);
- from_origin_b = sqrt (bx * bx + by * by);
-
- if (from_origin_a < from_origin_b)
- return -1;
- else if (from_origin_a > from_origin_b)
- return 1;
- else
- return 0;
-}
-
-static void
-find_next_cascade (MetaWindow *window,
- MetaFrameGeometry *fgeom,
- /* visible windows on relevant workspaces */
- GList *windows,
- int x,
- int y,
- int *new_x,
- int *new_y)
-{
- GList *tmp;
- GList *sorted;
- int cascade_x, cascade_y;
- int x_threshold, y_threshold;
- int window_width, window_height;
- int cascade_stage;
- MetaRectangle work_area;
- const MetaXineramaScreenInfo* current;
-
- sorted = g_list_copy (windows);
- sorted = g_list_sort (sorted, northwestcmp);
-
- /* This is a "fuzzy" cascade algorithm.
- * For each window in the list, we find where we'd cascade a
- * new window after it. If a window is already nearly at that
- * position, we move on.
- */
-
- /* arbitrary-ish threshold, honors user attempts to
- * manually cascade.
- */
-#define CASCADE_FUZZ 15
- if (fgeom)
- {
- x_threshold = MAX (fgeom->left_width, CASCADE_FUZZ);
- y_threshold = MAX (fgeom->top_height, CASCADE_FUZZ);
- }
- else
- {
- x_threshold = CASCADE_FUZZ;
- y_threshold = CASCADE_FUZZ;
- }
-
- /* Find furthest-SE origin of all workspaces.
- * cascade_x, cascade_y are the target position
- * of NW corner of window frame.
- */
-
- current = meta_screen_get_current_xinerama (window->screen);
- meta_window_get_work_area_for_xinerama (window, current->number, &work_area);
-
- cascade_x = MAX (0, work_area.x);
- cascade_y = MAX (0, work_area.y);
-
- /* Find first cascade position that's not used. */
-
- window_width = window->frame ? window->frame->rect.width : window->rect.width;
- window_height = window->frame ? window->frame->rect.height : window->rect.height;
-
- cascade_stage = 0;
- tmp = sorted;
- while (tmp != NULL)
- {
- MetaWindow *w;
- int wx, wy;
-
- w = tmp->data;
-
- /* we want frame position, not window position */
- if (w->frame)
- {
- wx = w->frame->rect.x;
- wy = w->frame->rect.y;
- }
- else
- {
- wx = w->rect.x;
- wy = w->rect.y;
- }
-
- if (ABS (wx - cascade_x) < x_threshold &&
- ABS (wy - cascade_y) < y_threshold)
- {
- /* This window is "in the way", move to next cascade
- * point. The new window frame should go at the origin
- * of the client window we're stacking above.
- */
- meta_window_get_position (w, &wx, &wy);
- cascade_x = wx;
- cascade_y = wy;
-
- /* If we go off the screen, start over with a new cascade */
- if (((cascade_x + window_width) >
- (work_area.x + work_area.width)) ||
- ((cascade_y + window_height) >
- (work_area.y + work_area.height)))
- {
- cascade_x = MAX (0, work_area.x);
- cascade_y = MAX (0, work_area.y);
-
-#define CASCADE_INTERVAL 50 /* space between top-left corners of cascades */
- cascade_stage += 1;
- cascade_x += CASCADE_INTERVAL * cascade_stage;
-
- /* start over with a new cascade translated to the right, unless
- * we are out of space
- */
- if ((cascade_x + window_width) <
- (work_area.x + work_area.width))
- {
- tmp = sorted;
- continue;
- }
- else
- {
- /* All out of space, this cascade_x won't work */
- cascade_x = MAX (0, work_area.x);
- break;
- }
- }
- }
- else
- {
- /* Keep searching for a further-down-the-diagonal window. */
- }
-
- tmp = tmp->next;
- }
-
- /* cascade_x and cascade_y will match the last window in the list
- * that was "in the way" (in the approximate cascade diagonal)
- */
-
- g_list_free (sorted);
-
- /* Convert coords to position of window, not position of frame. */
- if (fgeom == NULL)
- {
- *new_x = cascade_x;
- *new_y = cascade_y;
- }
- else
- {
- *new_x = cascade_x + fgeom->left_width;
- *new_y = cascade_y + fgeom->top_height;
- }
-}
-
-static void
-find_most_freespace (MetaWindow *window,
- MetaFrameGeometry *fgeom,
- /* visible windows on relevant workspaces */
- MetaWindow *focus_window,
- int x,
- int y,
- int *new_x,
- int *new_y)
-{
- MetaWindowDirection side;
- int max_area;
- int max_width, max_height, left, right, top, bottom;
- int left_space, right_space, top_space, bottom_space;
- int frame_size_left, frame_size_top;
- MetaRectangle work_area;
- MetaRectangle avoid;
- MetaRectangle outer;
-
- frame_size_left = fgeom ? fgeom->left_width : 0;
- frame_size_top = fgeom ? fgeom->top_height : 0;
-
- meta_window_get_work_area_current_xinerama (focus_window, &work_area);
- meta_window_get_outer_rect (focus_window, &avoid);
- meta_window_get_outer_rect (window, &outer);
-
- /* Find the areas of choosing the various sides of the focus window */
- max_width = MIN (avoid.width, outer.width);
- max_height = MIN (avoid.height, outer.height);
- left_space = avoid.x - work_area.x;
- right_space = work_area.width - (avoid.x + avoid.width - work_area.x);
- top_space = avoid.y - work_area.y;
- bottom_space = work_area.height - (avoid.y + avoid.height - work_area.y);
- left = MIN (left_space, outer.width);
- right = MIN (right_space, outer.width);
- top = MIN (top_space, outer.height);
- bottom = MIN (bottom_space, outer.height);
-
- /* Find out which side of the focus_window can show the most of the window */
- side = META_LEFT;
- max_area = left*max_height;
- if (right*max_height > max_area)
- {
- side = META_RIGHT;
- max_area = right*max_height;
- }
- if (top*max_width > max_area)
- {
- side = META_TOP;
- max_area = top*max_width;
- }
- if (bottom*max_width > max_area)
- {
- side = META_BOTTOM;
- max_area = bottom*max_width;
- }
-
- /* Give up if there's no where to put it (i.e. focus window is maximized) */
- if (max_area == 0)
- return;
-
- /* Place the window on the relevant side; if the whole window fits,
- * make it adjacent to the focus window; if not, make sure the
- * window doesn't go off the edge of the screen.
- */
- switch (side)
- {
- case META_LEFT:
- *new_y = avoid.y + frame_size_top;
- if (left_space > outer.width)
- *new_x = avoid.x - outer.width + frame_size_left;
- else
- *new_x = work_area.x + frame_size_left;
- break;
- case META_RIGHT:
- *new_y = avoid.y + frame_size_top;
- if (right_space > outer.width)
- *new_x = avoid.x + avoid.width + frame_size_left;
- else
- *new_x = work_area.x + work_area.width - outer.width + frame_size_left;
- break;
- case META_TOP:
- *new_x = avoid.x + frame_size_left;
- if (top_space > outer.height)
- *new_y = avoid.y - outer.height + frame_size_top;
- else
- *new_y = work_area.y + frame_size_top;
- break;
- case META_BOTTOM:
- *new_x = avoid.x + frame_size_left;
- if (bottom_space > outer.height)
- *new_y = avoid.y + avoid.height + frame_size_top;
- else
- *new_y = work_area.y + work_area.height - outer.height + frame_size_top;
- break;
- }
-}
-
-static void
-avoid_being_obscured_as_second_modal_dialog (MetaWindow *window,
- MetaFrameGeometry *fgeom,
- int *x,
- int *y)
-{
- /* We can't center this dialog if it was denied focus and it
- * overlaps with the focus window and this dialog is modal and this
- * dialog is in the same app as the focus window (*phew*...please
- * don't make me say that ten times fast). See bug 307875 comment 11
- * and 12 for details, but basically it means this is probably a
- * second modal dialog for some app while the focus window is the
- * first modal dialog. We should probably make them simultaneously
- * visible in general, but it becomes mandatory to do so due to
- * buggy apps (e.g. those using gtk+ *sigh*) because in those cases
- * this second modal dialog also happens to be modal to the first
- * dialog in addition to the main window, while it has only let us
- * know about the modal-to-the-main-window part.
- */
-
- MetaWindow *focus_window;
- MetaRectangle overlap;
-
- focus_window = window->display->focus_window;
-
- if (window->denied_focus_and_not_transient &&
- window->wm_state_modal && /* FIXME: Maybe do this for all transients? */
- meta_window_same_application (window, focus_window) &&
- meta_rectangle_intersect (&window->rect,
- &focus_window->rect,
- &overlap))
- {
- find_most_freespace (window, fgeom, focus_window, *x, *y, x, y);
- meta_topic (META_DEBUG_PLACEMENT,
- "Dialog window %s was denied focus but may be modal "
- "to the focus window; had to move it to avoid the "
- "focus window\n",
- window->desc);
- }
-}
-
-static gboolean
-rectangle_overlaps_some_window (MetaRectangle *rect,
- GList *windows)
-{
- GList *tmp;
- MetaRectangle dest;
-
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *other = tmp->data;
- MetaRectangle other_rect;
-
- switch (other->type)
- {
- case META_WINDOW_DOCK:
- case META_WINDOW_SPLASHSCREEN:
- case META_WINDOW_DESKTOP:
- case META_WINDOW_DIALOG:
- case META_WINDOW_MODAL_DIALOG:
- break;
-
- case META_WINDOW_NORMAL:
- case META_WINDOW_UTILITY:
- case META_WINDOW_TOOLBAR:
- case META_WINDOW_MENU:
- meta_window_get_outer_rect (other, &other_rect);
-
- if (meta_rectangle_intersect (rect, &other_rect, &dest))
- return TRUE;
- break;
- }
-
- tmp = tmp->next;
- }
-
- return FALSE;
-}
-
-static gint
-leftmost_cmp (gconstpointer a, gconstpointer b)
-{
- MetaWindow *aw = (gpointer) a;
- MetaWindow *bw = (gpointer) b;
- int ax, bx;
-
- /* we're interested in the frame position for cascading,
- * not meta_window_get_position()
- */
- if (aw->frame)
- ax = aw->frame->rect.x;
- else
- ax = aw->rect.x;
-
- if (bw->frame)
- bx = bw->frame->rect.x;
- else
- bx = bw->rect.x;
-
- if (ax < bx)
- return -1;
- else if (ax > bx)
- return 1;
- else
- return 0;
-}
-
-static gint
-topmost_cmp (gconstpointer a, gconstpointer b)
-{
- MetaWindow *aw = (gpointer) a;
- MetaWindow *bw = (gpointer) b;
- int ay, by;
-
- /* we're interested in the frame position for cascading,
- * not meta_window_get_position()
- */
- if (aw->frame)
- ay = aw->frame->rect.y;
- else
- ay = aw->rect.y;
-
- if (bw->frame)
- by = bw->frame->rect.y;
- else
- by = bw->rect.y;
-
- if (ay < by)
- return -1;
- else if (ay > by)
- return 1;
- else
- return 0;
-}
-
-static void
-center_tile_rect_in_area (MetaRectangle *rect,
- MetaRectangle *work_area)
-{
- int fluff;
-
- /* The point here is to tile a window such that "extra"
- * space is equal on either side (i.e. so a full screen
- * of windows tiled this way would center the windows
- * as a group)
- */
-
- fluff = (work_area->width % (rect->width+1)) / 2;
- rect->x = work_area->x + fluff;
- fluff = (work_area->height % (rect->height+1)) / 3;
- rect->y = work_area->y + fluff;
-}
-
-/* Find the leftmost, then topmost, empty area on the workspace
- * that can contain the new window.
- *
- * Cool feature to have: if we can't fit the current window size,
- * try shrinking the window (within geometry constraints). But
- * beware windows such as Emacs with no sane minimum size, we
- * don't want to create a 1x1 Emacs.
- */
-static gboolean
-find_first_fit (MetaWindow *window,
- MetaFrameGeometry *fgeom,
- /* visible windows on relevant workspaces */
- GList *windows,
- int xinerama,
- int x,
- int y,
- int *new_x,
- int *new_y)
-{
- /* This algorithm is limited - it just brute-force tries
- * to fit the window in a small number of locations that are aligned
- * with existing windows. It tries to place the window on
- * the bottom of each existing window, and then to the right
- * of each existing window, aligned with the left/top of the
- * existing window in each of those cases.
- */
- int retval;
- GList *below_sorted;
- GList *right_sorted;
- GList *tmp;
- MetaRectangle rect;
- MetaRectangle work_area;
-
- retval = FALSE;
-
- /* Below each window */
- below_sorted = g_list_copy (windows);
- below_sorted = g_list_sort (below_sorted, leftmost_cmp);
- below_sorted = g_list_sort (below_sorted, topmost_cmp);
-
- /* To the right of each window */
- right_sorted = g_list_copy (windows);
- right_sorted = g_list_sort (right_sorted, topmost_cmp);
- right_sorted = g_list_sort (right_sorted, leftmost_cmp);
-
- rect.width = window->rect.width;
- rect.height = window->rect.height;
-
- if (fgeom)
- {
- rect.width += fgeom->left_width + fgeom->right_width;
- rect.height += fgeom->top_height + fgeom->bottom_height;
- }
-
-#ifdef WITH_VERBOSE_MODE
- {
- char xinerama_location_string[RECT_LENGTH];
- meta_rectangle_to_string (&window->screen->xinerama_infos[xinerama].rect,
- xinerama_location_string);
- meta_topic (META_DEBUG_XINERAMA,
- "Natural xinerama is %s\n",
- xinerama_location_string);
- }
-#endif
-
- meta_window_get_work_area_for_xinerama (window, xinerama, &work_area);
-
- center_tile_rect_in_area (&rect, &work_area);
-
- if (meta_rectangle_contains_rect (&work_area, &rect) &&
- !rectangle_overlaps_some_window (&rect, windows))
- {
- *new_x = rect.x;
- *new_y = rect.y;
- if (fgeom)
- {
- *new_x += fgeom->left_width;
- *new_y += fgeom->top_height;
- }
-
- retval = TRUE;
-
- goto out;
- }
-
- /* try below each window */
- tmp = below_sorted;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
- MetaRectangle outer_rect;
-
- meta_window_get_outer_rect (w, &outer_rect);
-
- rect.x = outer_rect.x;
- rect.y = outer_rect.y + outer_rect.height;
-
- if (meta_rectangle_contains_rect (&work_area, &rect) &&
- !rectangle_overlaps_some_window (&rect, below_sorted))
- {
- *new_x = rect.x;
- *new_y = rect.y;
- if (fgeom)
- {
- *new_x += fgeom->left_width;
- *new_y += fgeom->top_height;
- }
-
- retval = TRUE;
-
- goto out;
- }
-
- tmp = tmp->next;
- }
-
- /* try to the right of each window */
- tmp = right_sorted;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
- MetaRectangle outer_rect;
-
- meta_window_get_outer_rect (w, &outer_rect);
-
- rect.x = outer_rect.x + outer_rect.width;
- rect.y = outer_rect.y;
-
- if (meta_rectangle_contains_rect (&work_area, &rect) &&
- !rectangle_overlaps_some_window (&rect, right_sorted))
- {
- *new_x = rect.x;
- *new_y = rect.y;
- if (fgeom)
- {
- *new_x += fgeom->left_width;
- *new_y += fgeom->top_height;
- }
-
- retval = TRUE;
-
- goto out;
- }
-
- tmp = tmp->next;
- }
-
- out:
-
- g_list_free (below_sorted);
- g_list_free (right_sorted);
- return retval;
-}
-
-void
-meta_window_place (MetaWindow *window,
- MetaFrameGeometry *fgeom,
- int x,
- int y,
- int *new_x,
- int *new_y)
-{
- GList *windows;
- const MetaXineramaScreenInfo *xi;
-
- /* frame member variables should NEVER be used in here, only
- * MetaFrameGeometry. But remember fgeom == NULL
- * for undecorated windows. Also, this function should
- * NEVER have side effects other than computing the
- * placement coordinates.
- */
-
- meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc);
-
- windows = NULL;
-
- switch (window->type)
- {
- /* Run placement algorithm on these. */
- case META_WINDOW_NORMAL:
- case META_WINDOW_DIALOG:
- case META_WINDOW_MODAL_DIALOG:
- case META_WINDOW_SPLASHSCREEN:
- break;
-
- /* Assume the app knows best how to place these, no placement
- * algorithm ever (other than "leave them as-is")
- */
- case META_WINDOW_DESKTOP:
- case META_WINDOW_DOCK:
- case META_WINDOW_TOOLBAR:
- case META_WINDOW_MENU:
- case META_WINDOW_UTILITY:
- goto done_no_constraints;
- }
-
- if (meta_prefs_get_disable_workarounds ())
- {
- switch (window->type)
- {
- /* Only accept USPosition on normal windows because the app is full
- * of shit claiming the user set -geometry for a dialog or dock
- */
- case META_WINDOW_NORMAL:
- if (window->size_hints.flags & USPosition)
- {
- /* don't constrain with placement algorithm */
- meta_topic (META_DEBUG_PLACEMENT,
- "Honoring USPosition for %s instead of using placement algorithm\n", window->desc);
-
- goto done;
- }
- break;
-
- /* Ignore even USPosition on dialogs, splashscreen */
- case META_WINDOW_DIALOG:
- case META_WINDOW_MODAL_DIALOG:
- case META_WINDOW_SPLASHSCREEN:
- break;
-
- /* Assume the app knows best how to place these. */
- case META_WINDOW_DESKTOP:
- case META_WINDOW_DOCK:
- case META_WINDOW_TOOLBAR:
- case META_WINDOW_MENU:
- case META_WINDOW_UTILITY:
- if (window->size_hints.flags & PPosition)
- {
- meta_topic (META_DEBUG_PLACEMENT,
- "Not placing non-normal non-dialog window with PPosition set\n");
- goto done_no_constraints;
- }
- break;
- }
- }
- else
- {
- /* workarounds enabled */
-
- if ((window->size_hints.flags & PPosition) ||
- (window->size_hints.flags & USPosition))
- {
- meta_topic (META_DEBUG_PLACEMENT,
- "Not placing window with PPosition or USPosition set\n");
- avoid_being_obscured_as_second_modal_dialog (window, fgeom, &x, &y);
- goto done_no_constraints;
- }
- }
-
- if ((window->type == META_WINDOW_DIALOG ||
- window->type == META_WINDOW_MODAL_DIALOG) &&
- window->xtransient_for != None)
- {
- /* Center horizontally, at top of parent vertically */
-
- MetaWindow *parent;
-
- parent =
- meta_display_lookup_x_window (window->display,
- window->xtransient_for);
-
- if (parent)
- {
- int w;
-
- meta_window_get_position (parent, &x, &y);
- w = parent->rect.width;
-
- /* center of parent */
- x = x + w / 2;
- /* center of child over center of parent */
- x -= window->rect.width / 2;
-
- /* "visually" center window over parent, leaving twice as
- * much space below as on top.
- */
- y += (parent->rect.height - window->rect.height)/3;
-
- /* put top of child's frame, not top of child's client */
- if (fgeom)
- y += fgeom->top_height;
-
- meta_topic (META_DEBUG_PLACEMENT, "Centered window %s over transient parent\n",
- window->desc);
-
- avoid_being_obscured_as_second_modal_dialog (window, fgeom, &x, &y);
-
- goto done;
- }
- }
-
- /* FIXME UTILITY with transient set should be stacked up
- * on the sides of the parent window or something.
- */
-
- if (window->type == META_WINDOW_DIALOG ||
- window->type == META_WINDOW_MODAL_DIALOG ||
- window->type == META_WINDOW_SPLASHSCREEN)
- {
- /* Center on current xinerama (i.e. on current monitor) */
- int w, h;
-
- /* Warning, this function is a round trip! */
- xi = meta_screen_get_current_xinerama (window->screen);
-
- w = xi->rect.width;
- h = xi->rect.height;
-
- x = (w - window->rect.width) / 2;
- y = (h - window->rect.height) / 2;
-
- x += xi->rect.x;
- y += xi->rect.y;
-
- meta_topic (META_DEBUG_PLACEMENT, "Centered window %s on screen %d xinerama %d\n",
- window->desc, window->screen->number, xi->number);
-
- goto done_check_denied_focus;
- }
-
- /* Find windows that matter (not minimized, on same workspace
- * as placed window, may be shaded - if shaded we pretend it isn't
- * for placement purposes)
- */
- {
- GSList *all_windows;
- GSList *tmp;
-
- all_windows = meta_display_list_windows (window->display);
-
- tmp = all_windows;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
-
- if (meta_window_showing_on_its_workspace (w) &&
- w != window &&
- (window->workspace == w->workspace ||
- window->on_all_workspaces || w->on_all_workspaces))
- windows = g_list_prepend (windows, w);
-
- tmp = tmp->next;
- }
-
- g_slist_free (all_windows);
- }
-
- /* Warning, this is a round trip! */
- xi = meta_screen_get_current_xinerama (window->screen);
-
- /* "Origin" placement algorithm */
- x = xi->rect.x;
- y = xi->rect.y;
-
- if (find_first_fit (window, fgeom, windows,
- xi->number,
- x, y, &x, &y))
- goto done_check_denied_focus;
-
- /* Maximize windows if they are too big for their work area (bit of
- * a hack here). Assume undecorated windows probably don't intend to
- * be maximized.
- */
- if (window->has_maximize_func && window->decorated &&
- !window->fullscreen)
- {
- MetaRectangle workarea;
- MetaRectangle outer;
-
- meta_window_get_work_area_for_xinerama (window,
- xi->number,
- &workarea);
- meta_window_get_outer_rect (window, &outer);
-
- /* If the window is bigger than the screen, then automaximize. Do NOT
- * auto-maximize the directions independently. See #419810.
- */
- if (outer.width >= workarea.width && outer.height >= workarea.height)
- {
- window->maximize_horizontally_after_placement = TRUE;
- window->maximize_vertically_after_placement = TRUE;
- }
- }
-
- /* If no placement has been done, revert to cascade to avoid
- * fully overlapping window (e.g. starting multiple terminals)
- * */
- if (x == xi->rect.x && y == xi->rect.y)
- find_next_cascade (window, fgeom, windows, x, y, &x, &y);
-
- done_check_denied_focus:
- /* If the window is being denied focus and isn't a transient of the
- * focus window, we do NOT want it to overlap with the focus window
- * if at all possible. This is guaranteed to only be called if the
- * focus_window is non-NULL, and we try to avoid that window.
- */
- if (window->denied_focus_and_not_transient)
- {
- gboolean found_fit;
- MetaWindow *focus_window;
- MetaRectangle overlap;
-
- focus_window = window->display->focus_window;
- g_assert (focus_window != NULL);
-
- /* No need to do anything if the window doesn't overlap at all */
- found_fit = !meta_rectangle_intersect (&window->rect,
- &focus_window->rect,
- &overlap);
-
- /* Try to do a first fit again, this time only taking into account the
- * focus window.
- */
- if (!found_fit)
- {
- GList *focus_window_list;
- focus_window_list = g_list_prepend (NULL, focus_window);
-
- /* Reset x and y ("origin" placement algorithm) */
- x = xi->rect.x;
- y = xi->rect.y;
-
- found_fit = find_first_fit (window, fgeom, focus_window_list,
- xi->number,
- x, y, &x, &y);
- g_list_free (focus_window_list);
- }
-
- /* If that still didn't work, just place it where we can see as much
- * as possible.
- */
- if (!found_fit)
- find_most_freespace (window, fgeom, focus_window, x, y, &x, &y);
- }
-
- done:
- g_list_free (windows);
-
- done_no_constraints:
-
- *new_x = x;
- *new_y = y;
-}
diff --git a/src/core/place.h b/src/core/place.h
deleted file mode 100644
index 10bf4a1c..00000000
--- a/src/core/place.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity window placement */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_PLACE_H
-#define META_PLACE_H
-
-#include "window-private.h"
-#include "frame-private.h"
-
-void meta_window_place (MetaWindow *window,
- MetaFrameGeometry *fgeom,
- int x,
- int y,
- int *new_x,
- int *new_y);
-
-#endif
diff --git a/src/core/prefs.c b/src/core/prefs.c
deleted file mode 100644
index ca928e9e..00000000
--- a/src/core/prefs.c
+++ /dev/null
@@ -1,2776 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity preferences */
-
-/*
- * Copyright (C) 2001 Havoc Pennington, Copyright (C) 2002 Red Hat Inc.
- * Copyright (C) 2006 Elijah Newren
- * Copyright (C) 2008 Thomas Thurman
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include "prefs.h"
-#include "ui.h"
-#include "util.h"
-#ifdef HAVE_GCONF
-#include <gconf/gconf-client.h>
-#endif
-#include <string.h>
-#include <stdlib.h>
-
-#define MAX_REASONABLE_WORKSPACES 36
-
-#define MAX_COMMANDS (32 + NUM_EXTRA_COMMANDS)
-#define NUM_EXTRA_COMMANDS 2
-#define SCREENSHOT_COMMAND_IDX (MAX_COMMANDS - 2)
-#define WIN_SCREENSHOT_COMMAND_IDX (MAX_COMMANDS - 1)
-
-/* If you add a key, it needs updating in init() and in the gconf
- * notify listener and of course in the .schemas file.
- *
- * Keys which are handled by one of the unified handlers below are
- * not given a name here, because the purpose of the unified handlers
- * is that keys should be referred to exactly once.
- */
-#define KEY_TITLEBAR_FONT "/apps/metacity/general/titlebar_font"
-#define KEY_NUM_WORKSPACES "/apps/metacity/general/num_workspaces"
-#define KEY_COMPOSITOR "/apps/metacity/general/compositing_manager"
-#define KEY_GNOME_ACCESSIBILITY "/desktop/gnome/interface/accessibility"
-
-#define KEY_COMMAND_PREFIX "/apps/metacity/keybinding_commands/command_"
-
-#define KEY_TERMINAL_DIR "/desktop/gnome/applications/terminal"
-#define KEY_TERMINAL_COMMAND KEY_TERMINAL_DIR "/exec"
-
-#define KEY_SCREEN_BINDINGS_PREFIX "/apps/metacity/global_keybindings"
-#define KEY_WINDOW_BINDINGS_PREFIX "/apps/metacity/window_keybindings"
-#define KEY_LIST_BINDINGS_SUFFIX "_list"
-
-#define KEY_WORKSPACE_NAME_PREFIX "/apps/metacity/workspace_names/name_"
-
-
-#ifdef HAVE_GCONF
-static GConfClient *default_client = NULL;
-static GList *changes = NULL;
-static guint changed_idle;
-static GList *listeners = NULL;
-#endif
-
-static gboolean use_system_font = FALSE;
-static PangoFontDescription *titlebar_font = NULL;
-static MetaVirtualModifier mouse_button_mods = Mod1Mask;
-static MetaFocusMode focus_mode = META_FOCUS_MODE_CLICK;
-static MetaFocusNewWindows focus_new_windows = META_FOCUS_NEW_WINDOWS_SMART;
-static gboolean raise_on_click = TRUE;
-static char* current_theme = NULL;
-static int num_workspaces = 4;
-static MetaActionTitlebar action_double_click_titlebar = META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE;
-static MetaActionTitlebar action_middle_click_titlebar = META_ACTION_TITLEBAR_LOWER;
-static MetaActionTitlebar action_right_click_titlebar = META_ACTION_TITLEBAR_MENU;
-static gboolean application_based = FALSE;
-static gboolean disable_workarounds = FALSE;
-static gboolean auto_raise = FALSE;
-static gboolean auto_raise_delay = 500;
-static gboolean provide_visual_bell = FALSE;
-static gboolean bell_is_audible = TRUE;
-static gboolean reduced_resources = FALSE;
-static gboolean gnome_accessibility = FALSE;
-static gboolean gnome_animations = TRUE;
-static char *cursor_theme = NULL;
-static int cursor_size = 24;
-static gboolean compositing_manager = FALSE;
-
-static MetaVisualBellType visual_bell_type = META_VISUAL_BELL_FULLSCREEN_FLASH;
-static MetaButtonLayout button_layout;
-
-/* The screenshot commands are at the end */
-static char *commands[MAX_COMMANDS] = { NULL, };
-
-static char *terminal_command = NULL;
-
-static char *workspace_names[MAX_REASONABLE_WORKSPACES] = { NULL, };
-
-#ifdef HAVE_GCONF
-static gboolean handle_preference_update_enum (const gchar *key, GConfValue *value);
-
-static gboolean update_key_binding (const char *name,
- const char *value);
-static gboolean find_and_update_list_binding (MetaKeyPref *bindings,
- const char *name,
- GSList *value);
-static gboolean update_key_list_binding (const char *name,
- GSList *value);
-static gboolean update_command (const char *name,
- const char *value);
-static gboolean update_workspace_name (const char *name,
- const char *value);
-
-static void change_notify (GConfClient *client,
- guint cnxn_id,
- GConfEntry *entry,
- gpointer user_data);
-
-static char* gconf_key_for_workspace_name (int i);
-
-static void queue_changed (MetaPreference pref);
-
-typedef enum
- {
- META_LIST_OF_STRINGS,
- META_LIST_OF_GCONFVALUE_STRINGS
- } MetaStringListType;
-
-static gboolean update_list_binding (MetaKeyPref *binding,
- GSList *value,
- MetaStringListType type_of_value);
-
-static void cleanup_error (GError **error);
-static gboolean get_bool (const char *key, gboolean *val);
-static void maybe_give_disable_workarounds_warning (void);
-
-static void titlebar_handler (MetaPreference, const gchar*, gboolean*);
-static void theme_name_handler (MetaPreference, const gchar*, gboolean*);
-static void mouse_button_mods_handler (MetaPreference, const gchar*, gboolean*);
-static void button_layout_handler (MetaPreference, const gchar*, gboolean*);
-
-#endif /* HAVE_GCONF */
-
-static gboolean update_binding (MetaKeyPref *binding,
- const char *value);
-
-static void init_bindings (void);
-static void init_commands (void);
-static void init_workspace_names (void);
-
-#ifndef HAVE_GCONF
-static void init_button_layout (void);
-#endif /* !HAVE_GCONF */
-
-#ifdef HAVE_GCONF
-
-typedef struct
-{
- MetaPrefsChangedFunc func;
- gpointer data;
-} MetaPrefsListener;
-
-static GConfEnumStringPair symtab_focus_mode[] =
- {
- { META_FOCUS_MODE_CLICK, "click" },
- { META_FOCUS_MODE_SLOPPY, "sloppy" },
- { META_FOCUS_MODE_MOUSE, "mouse" },
- { 0, NULL },
- };
-
-static GConfEnumStringPair symtab_focus_new_windows[] =
- {
- { META_FOCUS_NEW_WINDOWS_SMART, "smart" },
- { META_FOCUS_NEW_WINDOWS_STRICT, "strict" },
- { 0, NULL },
- };
-
-static GConfEnumStringPair symtab_visual_bell_type[] =
- {
- /* Note to the reader: 0 is an invalid value; these start at 1. */
- { META_VISUAL_BELL_FULLSCREEN_FLASH, "fullscreen" },
- { META_VISUAL_BELL_FRAME_FLASH, "frame_flash" },
- { 0, NULL },
- };
-
-static GConfEnumStringPair symtab_titlebar_action[] =
- {
- { META_ACTION_TITLEBAR_TOGGLE_SHADE, "toggle_shade" },
- { META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE, "toggle_maximize" },
- { META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE_HORIZONTALLY,
- "toggle_maximize_horizontally" },
- { META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE_VERTICALLY,
- "toggle_maximize_vertically" },
- { META_ACTION_TITLEBAR_MINIMIZE, "minimize" },
- { META_ACTION_TITLEBAR_NONE, "none" },
- { META_ACTION_TITLEBAR_LOWER, "lower" },
- { META_ACTION_TITLEBAR_MENU, "menu" },
- { META_ACTION_TITLEBAR_TOGGLE_SHADE, "toggle_shade" },
- { 0, NULL },
- };
-
-/**
- * The details of one preference which is constrained to be
- * one of a small number of string values-- in other words,
- * an enumeration.
- *
- * We could have done this other ways. One particularly attractive
- * possibility would have been to represent the entire symbol table
- * as a space-separated string literal in the list of symtabs, so
- * the focus mode enums could have been represented simply by
- * "click sloppy mouse". However, the simplicity gained would have
- * been outweighed by the bugs caused when the ordering of the enum
- * strings got out of sync with the actual enum statement. Also,
- * there is existing library code to use this kind of symbol tables.
- *
- * Other things we might consider doing to clean this up in the
- * future include:
- *
- * - most of the keys begin with the same prefix, and perhaps we
- * could assume it if they don't start with a slash
- *
- * - there are several cases where a single identifier could be used
- * to generate an entire entry, and perhaps this could be done
- * with a macro. (This would reduce clarity, however, and is
- * probably a bad thing.)
- *
- * - these types all begin with a gchar* (and contain a MetaPreference)
- * and we can factor out the repeated code in the handlers by taking
- * advantage of this using some kind of union arrangement.
- */
-typedef struct
-{
- gchar *key;
- MetaPreference pref;
- GConfEnumStringPair *symtab;
- gpointer target;
-} MetaEnumPreference;
-
-typedef struct
-{
- gchar *key;
- MetaPreference pref;
- gboolean *target;
- gboolean becomes_true_on_destruction;
-} MetaBoolPreference;
-
-typedef struct
-{
- gchar *key;
- MetaPreference pref;
-
- /**
- * A handler. Many of the string preferences aren't stored as
- * strings and need parsing; others of them have default values
- * which can't be solved in the general case. If you include a
- * function pointer here, it will be called before the string
- * value is written out to the target variable.
- *
- * The function is passed two arguments: the preference, and
- * the new string as a gchar*. It returns a gboolean;
- * only if this is true, the listeners will be informed that
- * the preference has changed.
- *
- * This may be NULL. If it is, see "target", below.
- */
- void (*handler) (MetaPreference pref,
- const gchar *string_value,
- gboolean *inform_listeners);
-
- /**
- * Where to write the incoming string.
- *
- * This must be NULL if the handler is non-NULL.
- * If the incoming string is NULL, no change will be made.
- */
- gchar **target;
-
-} MetaStringPreference;
-
-#define METAINTPREFERENCE_NO_CHANGE_ON_DESTROY G_MININT
-
-typedef struct
-{
- gchar *key;
- MetaPreference pref;
- gint *target;
- /**
- * Minimum and maximum values of the integer.
- * If the new value is out of bounds, it will be discarded with a warning.
- */
- gint minimum, maximum;
- /**
- * Value to use if the key is destroyed.
- * If this is METAINTPREFERENCE_NO_CHANGE_ON_DESTROY, it will
- * not be changed when the key is destroyed.
- */
- gint value_if_destroyed;
-} MetaIntPreference;
-
-/* FIXMEs: */
-/* @@@ Don't use NULL lines at the end; glib can tell you how big it is */
-/* @@@ /apps/metacity/general should be assumed if first char is not / */
-/* @@@ Will it ever be possible to merge init and update? If not, why not? */
-
-static MetaEnumPreference preferences_enum[] =
- {
- { "/apps/metacity/general/focus_new_windows",
- META_PREF_FOCUS_NEW_WINDOWS,
- symtab_focus_new_windows,
- &focus_new_windows,
- },
- { "/apps/metacity/general/focus_mode",
- META_PREF_FOCUS_MODE,
- symtab_focus_mode,
- &focus_mode,
- },
- { "/apps/metacity/general/visual_bell_type",
- META_PREF_VISUAL_BELL_TYPE,
- symtab_visual_bell_type,
- &visual_bell_type,
- },
- { "/apps/metacity/general/action_double_click_titlebar",
- META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR,
- symtab_titlebar_action,
- &action_double_click_titlebar,
- },
- { "/apps/metacity/general/action_middle_click_titlebar",
- META_PREF_ACTION_MIDDLE_CLICK_TITLEBAR,
- symtab_titlebar_action,
- &action_middle_click_titlebar,
- },
- { "/apps/metacity/general/action_right_click_titlebar",
- META_PREF_ACTION_RIGHT_CLICK_TITLEBAR,
- symtab_titlebar_action,
- &action_right_click_titlebar,
- },
- { NULL, 0, NULL, NULL },
- };
-
-static MetaBoolPreference preferences_bool[] =
- {
- { "/apps/metacity/general/raise_on_click",
- META_PREF_RAISE_ON_CLICK,
- &raise_on_click,
- TRUE,
- },
- { "/apps/metacity/general/titlebar_uses_system_font",
- META_PREF_TITLEBAR_FONT, /* note! shares a pref */
- &use_system_font,
- TRUE,
- },
- { "/apps/metacity/general/application_based",
- META_PREF_APPLICATION_BASED,
- NULL, /* feature is known but disabled */
- FALSE,
- },
- { "/apps/metacity/general/disable_workarounds",
- META_PREF_DISABLE_WORKAROUNDS,
- &disable_workarounds,
- FALSE,
- },
- { "/apps/metacity/general/auto_raise",
- META_PREF_AUTO_RAISE,
- &auto_raise,
- FALSE,
- },
- { "/apps/metacity/general/visual_bell",
- META_PREF_VISUAL_BELL,
- &provide_visual_bell, /* FIXME: change the name: it's confusing */
- FALSE,
- },
- { "/apps/metacity/general/audible_bell",
- META_PREF_AUDIBLE_BELL,
- &bell_is_audible, /* FIXME: change the name: it's confusing */
- FALSE,
- },
- { "/apps/metacity/general/reduced_resources",
- META_PREF_REDUCED_RESOURCES,
- &reduced_resources,
- FALSE,
- },
- { "/desktop/gnome/interface/accessibility",
- META_PREF_GNOME_ACCESSIBILITY,
- &gnome_accessibility,
- FALSE,
- },
- { "/desktop/gnome/interface/enable_animations",
- META_PREF_GNOME_ANIMATIONS,
- &gnome_animations,
- TRUE,
- },
- { "/apps/metacity/general/compositing_manager",
- META_PREF_COMPOSITING_MANAGER,
- &compositing_manager,
- FALSE,
- },
- { NULL, 0, NULL, FALSE },
- };
-
-static MetaStringPreference preferences_string[] =
- {
- { "/apps/metacity/general/mouse_button_modifier",
- META_PREF_MOUSE_BUTTON_MODS,
- mouse_button_mods_handler,
- NULL,
- },
- { "/apps/metacity/general/theme",
- META_PREF_THEME,
- theme_name_handler,
- NULL,
- },
- { KEY_TITLEBAR_FONT,
- META_PREF_TITLEBAR_FONT,
- titlebar_handler,
- NULL,
- },
- { KEY_TERMINAL_COMMAND,
- META_PREF_TERMINAL_COMMAND,
- NULL,
- &terminal_command,
- },
- { "/apps/metacity/general/button_layout",
- META_PREF_BUTTON_LAYOUT,
- button_layout_handler,
- NULL,
- },
- { "/desktop/gnome/peripherals/mouse/cursor_theme",
- META_PREF_CURSOR_THEME,
- NULL,
- &cursor_theme,
- },
- { NULL, 0, NULL, NULL },
- };
-
-static MetaIntPreference preferences_int[] =
- {
- { "/apps/metacity/general/num_workspaces",
- META_PREF_NUM_WORKSPACES,
- &num_workspaces,
- /* I would actually recommend we change the destroy value to 4
- * and get rid of METAINTPREFERENCE_NO_CHANGE_ON_DESTROY entirely.
- * -- tthurman
- */
- 1, MAX_REASONABLE_WORKSPACES, METAINTPREFERENCE_NO_CHANGE_ON_DESTROY,
- },
- { "/apps/metacity/general/auto_raise_delay",
- META_PREF_AUTO_RAISE_DELAY,
- &auto_raise_delay,
- 0, 10000, 0,
- /* @@@ Get rid of MAX_REASONABLE_AUTO_RAISE_DELAY */
- },
- { "/desktop/gnome/peripherals/mouse/cursor_size",
- META_PREF_CURSOR_SIZE,
- &cursor_size,
- 1, 128, 24,
- },
- { NULL, 0, NULL, 0, 0, 0, },
- };
-
-static void
-handle_preference_init_enum (void)
-{
- MetaEnumPreference *cursor = preferences_enum;
-
- while (cursor->key!=NULL)
- {
- char *value;
- GError *error = NULL;
-
- if (cursor->target==NULL)
- {
- ++cursor;
- continue;
- }
-
- value = gconf_client_get_string (default_client,
- cursor->key,
- &error);
- cleanup_error (&error);
-
- if (value==NULL)
- {
- ++cursor;
- continue;
- }
-
- if (!gconf_string_to_enum (cursor->symtab,
- value,
- (gint *) cursor->target))
- meta_warning (_("GConf key '%s' is set to an invalid value\n"),
- cursor->key);
-
- g_free (value);
-
- ++cursor;
- }
-}
-
-static void
-handle_preference_init_bool (void)
-{
- MetaBoolPreference *cursor = preferences_bool;
-
- while (cursor->key!=NULL)
- {
- if (cursor->target!=NULL)
- get_bool (cursor->key, cursor->target);
-
- ++cursor;
- }
-
- maybe_give_disable_workarounds_warning ();
-}
-
-static void
-handle_preference_init_string (void)
-{
- MetaStringPreference *cursor = preferences_string;
-
- while (cursor->key!=NULL)
- {
- char *value;
- GError *error = NULL;
- gboolean dummy = TRUE;
-
- /* the string "value" will be newly allocated */
- value = gconf_client_get_string (default_client,
- cursor->key,
- &error);
- cleanup_error (&error);
-
- if (cursor->handler)
- {
- if (cursor->target)
- meta_bug ("%s has both a target and a handler\n", cursor->key);
-
- cursor->handler (cursor->pref, value, &dummy);
-
- g_free (value);
- }
- else if (cursor->target)
- {
- if (*(cursor->target))
- g_free (*(cursor->target));
-
- *(cursor->target) = value;
- }
-
- ++cursor;
- }
-}
-
-static void
-handle_preference_init_int (void)
-{
- MetaIntPreference *cursor = preferences_int;
-
-
- while (cursor->key!=NULL)
- {
- gint value;
- GError *error = NULL;
-
- value = gconf_client_get_int (default_client,
- cursor->key,
- &error);
- cleanup_error (&error);
-
- if (value < cursor->minimum || value > cursor->maximum)
- {
- meta_warning (_("%d stored in GConf key %s is out of range %d to %d\n"),
- value, cursor->key, cursor->minimum, cursor->maximum);
- /* Former behaviour for out-of-range values was:
- * - number of workspaces was clamped;
- * - auto raise delay was always reset to zero even if too high!;
- * - cursor size was ignored.
- *
- * These seem to be meaningless variations. If they did
- * have meaning we could have put them into MetaIntPreference.
- * The last of these is the closest to how we behave for
- * other types, so I think we should standardise on that.
- */
- }
- else if (cursor->target)
- *cursor->target = value;
-
- ++cursor;
- }
-}
-
-static gboolean
-handle_preference_update_enum (const gchar *key, GConfValue *value)
-{
- MetaEnumPreference *cursor = preferences_enum;
- gint old_value;
-
- while (cursor->key!=NULL && strcmp (key, cursor->key)!=0)
- ++cursor;
-
- if (cursor->key==NULL)
- /* Didn't recognise that key. */
- return FALSE;
-
- /* Setting it to null (that is, removing it) always means
- * "don't change".
- */
-
- if (value==NULL)
- return TRUE;
-
- /* Check the type. Enums are always strings. */
-
- if (value->type != GCONF_VALUE_STRING)
- {
- meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
- key);
- /* But we did recognise it. */
- return TRUE;
- }
-
- /* We need to know whether the value changes, so
- * store the current value away.
- */
-
- old_value = * ((gint *) cursor->target);
-
- /* Now look it up... */
-
- if (!gconf_string_to_enum (cursor->symtab,
- gconf_value_get_string (value),
- (gint *) cursor->target))
- {
- /*
- * We found it, but it was invalid. Complain.
- *
- * FIXME: This replicates the original behaviour, but in the future
- * we might consider reverting invalid keys to their original values.
- * (We know the old value, so we can look up a suitable string in
- * the symtab.)
- *
- * (Empty comment follows so the translators don't see this.)
- */
-
- /* */
- meta_warning (_("GConf key '%s' is set to an invalid value\n"),
- key);
- return TRUE;
- }
-
- /* Did it change? If so, tell the listeners about it. */
-
- if (old_value != *((gint *) cursor->target))
- queue_changed (cursor->pref);
-
- return TRUE;
-}
-
-static gboolean
-handle_preference_update_bool (const gchar *key, GConfValue *value)
-{
- MetaBoolPreference *cursor = preferences_bool;
- gboolean old_value;
-
- while (cursor->key!=NULL && strcmp (key, cursor->key)!=0)
- ++cursor;
-
- if (cursor->key==NULL)
- /* Didn't recognise that key. */
- return FALSE;
-
- if (cursor->target==NULL)
- /* No work for us to do. */
- return TRUE;
-
- if (value==NULL)
- {
- /* Value was destroyed; let's get out of here. */
-
- if (cursor->becomes_true_on_destruction)
- /* This preserves the behaviour of the old system, but
- * for all I know that might have been an oversight.
- */
- *((gboolean *)cursor->target) = TRUE;
-
- return TRUE;
- }
-
- /* Check the type. */
-
- if (value->type != GCONF_VALUE_BOOL)
- {
- meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
- key);
- /* But we did recognise it. */
- return TRUE;
- }
-
- /* We need to know whether the value changes, so
- * store the current value away.
- */
-
- old_value = * ((gboolean *) cursor->target);
-
- /* Now look it up... */
-
- *((gboolean *) cursor->target) = gconf_value_get_bool (value);
-
- /* Did it change? If so, tell the listeners about it. */
-
- if (old_value != *((gboolean *) cursor->target))
- queue_changed (cursor->pref);
-
- if (cursor->pref==META_PREF_DISABLE_WORKAROUNDS)
- maybe_give_disable_workarounds_warning ();
-
- return TRUE;
-}
-
-static gboolean
-handle_preference_update_string (const gchar *key, GConfValue *value)
-{
- MetaStringPreference *cursor = preferences_string;
- const gchar *value_as_string;
- gboolean inform_listeners = TRUE;
-
- while (cursor->key!=NULL && strcmp (key, cursor->key)!=0)
- ++cursor;
-
- if (cursor->key==NULL)
- /* Didn't recognise that key. */
- return FALSE;
-
- if (value==NULL)
- return TRUE;
-
- /* Check the type. */
-
- if (value->type != GCONF_VALUE_STRING)
- {
- meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
- key);
- /* But we did recognise it. */
- return TRUE;
- }
-
- /* Docs: "The returned string is not a copy, don't try to free it." */
- value_as_string = gconf_value_get_string (value);
-
- if (cursor->handler)
- cursor->handler (cursor->pref, value_as_string, &inform_listeners);
- else if (cursor->target)
- {
- if (*(cursor->target))
- g_free(*(cursor->target));
-
- if (value_as_string!=NULL)
- *(cursor->target) = g_strdup (value_as_string);
- else
- *(cursor->target) = NULL;
-
- inform_listeners =
- (value_as_string==NULL && *(cursor->target)==NULL) ||
- (value_as_string!=NULL && *(cursor->target)!=NULL &&
- strcmp (value_as_string, *(cursor->target))==0);
- }
-
- if (inform_listeners)
- queue_changed (cursor->pref);
-
- return TRUE;
-}
-
-static gboolean
-handle_preference_update_int (const gchar *key, GConfValue *value)
-{
- MetaIntPreference *cursor = preferences_int;
- gint new_value;
-
- while (cursor->key!=NULL && strcmp (key, cursor->key)!=0)
- ++cursor;
-
- if (cursor->key==NULL)
- /* Didn't recognise that key. */
- return FALSE;
-
- if (cursor->target==NULL)
- /* No work for us to do. */
- return TRUE;
-
- if (value==NULL)
- {
- /* Value was destroyed. */
-
- if (cursor->value_if_destroyed != METAINTPREFERENCE_NO_CHANGE_ON_DESTROY)
- *((gint *)cursor->target) = cursor->value_if_destroyed;
-
- return TRUE;
- }
-
- /* Check the type. */
-
- if (value->type != GCONF_VALUE_INT)
- {
- meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
- key);
- /* But we did recognise it. */
- return TRUE;
- }
-
- new_value = gconf_value_get_int (value);
-
- if (new_value < cursor->minimum || new_value > cursor->maximum)
- {
- meta_warning (_("%d stored in GConf key %s is out of range %d to %d\n"),
- new_value, cursor->key,
- cursor->minimum, cursor->maximum);
- return TRUE;
- }
-
- /* Did it change? If so, tell the listeners about it. */
-
- if (*cursor->target != new_value)
- {
- *cursor->target = new_value;
- queue_changed (cursor->pref);
- }
-
- return TRUE;
-
-}
-
-
-/****************************************************************************/
-/* Listeners. */
-/****************************************************************************/
-
-void
-meta_prefs_add_listener (MetaPrefsChangedFunc func,
- gpointer data)
-{
- MetaPrefsListener *l;
-
- l = g_new (MetaPrefsListener, 1);
- l->func = func;
- l->data = data;
-
- listeners = g_list_prepend (listeners, l);
-}
-
-void
-meta_prefs_remove_listener (MetaPrefsChangedFunc func,
- gpointer data)
-{
- GList *tmp;
-
- tmp = listeners;
- while (tmp != NULL)
- {
- MetaPrefsListener *l = tmp->data;
-
- if (l->func == func &&
- l->data == data)
- {
- g_free (l);
- listeners = g_list_delete_link (listeners, tmp);
-
- return;
- }
-
- tmp = tmp->next;
- }
-
- meta_bug ("Did not find listener to remove\n");
-}
-
-static void
-emit_changed (MetaPreference pref)
-{
- GList *tmp;
- GList *copy;
-
- meta_topic (META_DEBUG_PREFS, "Notifying listeners that pref %s changed\n",
- meta_preference_to_string (pref));
-
- copy = g_list_copy (listeners);
-
- tmp = copy;
-
- while (tmp != NULL)
- {
- MetaPrefsListener *l = tmp->data;
-
- (* l->func) (pref, l->data);
-
- tmp = tmp->next;
- }
-
- g_list_free (copy);
-}
-
-static gboolean
-changed_idle_handler (gpointer data)
-{
- GList *tmp;
- GList *copy;
-
- changed_idle = 0;
-
- copy = g_list_copy (changes); /* reentrancy paranoia */
-
- g_list_free (changes);
- changes = NULL;
-
- tmp = copy;
- while (tmp != NULL)
- {
- MetaPreference pref = GPOINTER_TO_INT (tmp->data);
-
- emit_changed (pref);
-
- tmp = tmp->next;
- }
-
- g_list_free (copy);
-
- return FALSE;
-}
-
-static void
-queue_changed (MetaPreference pref)
-{
- meta_topic (META_DEBUG_PREFS, "Queueing change of pref %s\n",
- meta_preference_to_string (pref));
-
- if (g_list_find (changes, GINT_TO_POINTER (pref)) == NULL)
- changes = g_list_prepend (changes, GINT_TO_POINTER (pref));
- else
- meta_topic (META_DEBUG_PREFS, "Change of pref %s was already pending\n",
- meta_preference_to_string (pref));
-
- /* add idle at priority below the gconf notify idle */
- if (changed_idle == 0)
- changed_idle = g_idle_add_full (META_PRIORITY_PREFS_NOTIFY,
- changed_idle_handler, NULL, NULL);
-}
-
-#else /* HAVE_GCONF */
-
-void
-meta_prefs_add_listener (MetaPrefsChangedFunc func,
- gpointer data)
-{
- /* Nothing, because they have gconf turned off */
-}
-
-void
-meta_prefs_remove_listener (MetaPrefsChangedFunc func,
- gpointer data)
-{
- /* Nothing, because they have gconf turned off */
-}
-
-#endif /* HAVE_GCONF */
-
-
-/****************************************************************************/
-/* Initialisation. */
-/****************************************************************************/
-
-#ifdef HAVE_GCONF
-/* @@@ again, use glib's ability to tell you the size of the array */
-static gchar *gconf_dirs_we_are_interested_in[] = {
- "/apps/metacity",
- KEY_TERMINAL_DIR,
- KEY_GNOME_ACCESSIBILITY,
- "/desktop/gnome/peripherals/mouse",
- "/desktop/gnome/interface",
- NULL,
-};
-#endif
-
-void
-meta_prefs_init (void)
-{
-#ifdef HAVE_GCONF
- GError *err = NULL;
- gchar **gconf_dir_cursor;
-
- if (default_client != NULL)
- return;
-
- /* returns a reference which we hold forever */
- default_client = gconf_client_get_default ();
-
- for (gconf_dir_cursor=gconf_dirs_we_are_interested_in;
- *gconf_dir_cursor!=NULL;
- gconf_dir_cursor++)
- {
- gconf_client_add_dir (default_client,
- *gconf_dir_cursor,
- GCONF_CLIENT_PRELOAD_RECURSIVE,
- &err);
- cleanup_error (&err);
- }
-
- /* Pick up initial values. */
-
- handle_preference_init_enum ();
- handle_preference_init_bool ();
- handle_preference_init_string ();
- handle_preference_init_int ();
-
- /* @@@ Is there any reason we don't do the add_dir here? */
- for (gconf_dir_cursor=gconf_dirs_we_are_interested_in;
- *gconf_dir_cursor!=NULL;
- gconf_dir_cursor++)
- {
- gconf_client_notify_add (default_client,
- *gconf_dir_cursor,
- change_notify,
- NULL,
- NULL,
- &err);
- cleanup_error (&err);
- }
-
-#else /* HAVE_GCONF */
-
- /* Set defaults for some values that can't be set at initialization time of
- * the static globals. In the case of the theme, note that there is code
- * elsewhere that will do everything possible to fallback to an existing theme
- * if the one here does not exist.
- */
- titlebar_font = pango_font_description_from_string ("Sans Bold 10");
- current_theme = g_strdup ("Atlanta");
-
- init_button_layout();
-#endif /* HAVE_GCONF */
-
- init_bindings ();
- init_commands ();
- init_workspace_names ();
-}
-
-
-/****************************************************************************/
-/* Updates. */
-/****************************************************************************/
-
-#ifdef HAVE_GCONF
-
-gboolean (*preference_update_handler[]) (const gchar*, GConfValue*) = {
- handle_preference_update_enum,
- handle_preference_update_bool,
- handle_preference_update_string,
- handle_preference_update_int,
- NULL
-};
-
-static void
-change_notify (GConfClient *client,
- guint cnxn_id,
- GConfEntry *entry,
- gpointer user_data)
-{
- const char *key;
- GConfValue *value;
- gint i=0;
-
- key = gconf_entry_get_key (entry);
- value = gconf_entry_get_value (entry);
-
- /* First, search for a handler that might know what to do. */
-
- /* FIXME: When this is all working, since the first item in every
- * array is the gchar* of the key, there's no reason we can't
- * find the correct record for that key here and save code duplication.
- */
-
- while (preference_update_handler[i]!=NULL)
- {
- if (preference_update_handler[i] (key, value))
- goto out; /* Get rid of this eventually */
-
- i++;
- }
-
- if (g_str_has_prefix (key, KEY_WINDOW_BINDINGS_PREFIX) ||
- g_str_has_prefix (key, KEY_SCREEN_BINDINGS_PREFIX))
- {
- if (g_str_has_suffix (key, KEY_LIST_BINDINGS_SUFFIX))
- {
- GSList *list;
-
- if (value && value->type != GCONF_VALUE_LIST)
- {
- meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
- key);
- goto out;
- }
-
- list = value ? gconf_value_get_list (value) : NULL;
-
- if (update_key_list_binding (key, list))
- queue_changed (META_PREF_KEYBINDINGS);
- }
- else
- {
- const char *str;
-
- if (value && value->type != GCONF_VALUE_STRING)
- {
- meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
- key);
- goto out;
- }
-
- str = value ? gconf_value_get_string (value) : NULL;
-
- if (update_key_binding (key, str))
- queue_changed (META_PREF_KEYBINDINGS);
- }
- }
- else if (g_str_has_prefix (key, KEY_COMMAND_PREFIX))
- {
- const char *str;
-
- if (value && value->type != GCONF_VALUE_STRING)
- {
- meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
- key);
- goto out;
- }
-
- str = value ? gconf_value_get_string (value) : NULL;
-
- if (update_command (key, str))
- queue_changed (META_PREF_COMMANDS);
- }
- else if (g_str_has_prefix (key, KEY_WORKSPACE_NAME_PREFIX))
- {
- const char *str;
-
- if (value && value->type != GCONF_VALUE_STRING)
- {
- meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
- key);
- goto out;
- }
-
- str = value ? gconf_value_get_string (value) : NULL;
-
- if (update_workspace_name (key, str))
- queue_changed (META_PREF_WORKSPACE_NAMES);
- }
- else
- {
- meta_topic (META_DEBUG_PREFS, "Key %s doesn't mean anything to Metacity\n",
- key);
- }
-
- out:
- /* nothing */
- return; /* AIX compiler wants something after a label like out: */
-}
-
-static void
-cleanup_error (GError **error)
-{
- if (*error)
- {
- meta_warning ("%s\n", (*error)->message);
-
- g_error_free (*error);
- *error = NULL;
- }
-}
-
-/* get_bool returns TRUE if *val is filled in, FALSE otherwise */
-/* @@@ probably worth moving this inline; only used once */
-static gboolean
-get_bool (const char *key, gboolean *val)
-{
- GError *err = NULL;
- GConfValue *value;
- gboolean filled_in = FALSE;
-
- value = gconf_client_get (default_client, key, &err);
- cleanup_error (&err);
- if (value)
- {
- if (value->type == GCONF_VALUE_BOOL)
- {
- *val = gconf_value_get_bool (value);
- filled_in = TRUE;
- }
- gconf_value_free (value);
- }
-
- return filled_in;
-}
-
-/**
- * Special case: give a warning the first time disable_workarounds
- * is turned on.
- */
-static void
-maybe_give_disable_workarounds_warning (void)
-{
- static gboolean first_disable = TRUE;
-
- if (first_disable && disable_workarounds)
- {
- first_disable = FALSE;
-
- meta_warning (_("Workarounds for broken applications disabled. "
- "Some applications may not behave properly.\n"));
- }
-}
-
-#endif /* HAVE_GCONF */
-
-MetaVirtualModifier
-meta_prefs_get_mouse_button_mods (void)
-{
- return mouse_button_mods;
-}
-
-MetaFocusMode
-meta_prefs_get_focus_mode (void)
-{
- return focus_mode;
-}
-
-MetaFocusNewWindows
-meta_prefs_get_focus_new_windows (void)
-{
- return focus_new_windows;
-}
-
-gboolean
-meta_prefs_get_raise_on_click (void)
-{
- /* Force raise_on_click on for click-to-focus, as requested by Havoc
- * in #326156.
- */
- return raise_on_click || focus_mode == META_FOCUS_MODE_CLICK;
-}
-
-const char*
-meta_prefs_get_theme (void)
-{
- return current_theme;
-}
-
-const char*
-meta_prefs_get_cursor_theme (void)
-{
- return cursor_theme;
-}
-
-int
-meta_prefs_get_cursor_size (void)
-{
- return cursor_size;
-}
-
-
-/****************************************************************************/
-/* Handlers for string preferences. */
-/****************************************************************************/
-
-#ifdef HAVE_GCONF
-
-static void
-titlebar_handler (MetaPreference pref,
- const gchar *string_value,
- gboolean *inform_listeners)
-{
- PangoFontDescription *new_desc = NULL;
-
- if (string_value)
- new_desc = pango_font_description_from_string (string_value);
-
- if (new_desc == NULL)
- {
- meta_warning (_("Could not parse font description "
- "\"%s\" from GConf key %s\n"),
- string_value ? string_value : "(null)",
- KEY_TITLEBAR_FONT);
-
- *inform_listeners = FALSE;
-
- return;
- }
-
- /* Is the new description the same as the old? */
-
- if (titlebar_font &&
- pango_font_description_equal (new_desc, titlebar_font))
- {
- pango_font_description_free (new_desc);
- *inform_listeners = FALSE;
- return;
- }
-
- /* No, so free the old one and put ours in instead. */
-
- if (titlebar_font)
- pango_font_description_free (titlebar_font);
-
- titlebar_font = new_desc;
-
-}
-
-static void
-theme_name_handler (MetaPreference pref,
- const gchar *string_value,
- gboolean *inform_listeners)
-{
- /* Fallback crackrock */
- if (string_value == NULL)
- current_theme = g_strdup ("Atlanta");
- else
- current_theme = g_strdup (string_value);
-}
-
-static void
-mouse_button_mods_handler (MetaPreference pref,
- const gchar *string_value,
- gboolean *inform_listeners)
-{
- MetaVirtualModifier mods;
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Mouse button modifier has new gconf value \"%s\"\n",
- string_value);
- if (string_value && meta_ui_parse_modifier (string_value, &mods))
- {
- mouse_button_mods = mods;
- }
- else
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Failed to parse new gconf value\n");
-
- meta_warning (_("\"%s\" found in configuration database is "
- "not a valid value for mouse button modifier\n"),
- string_value);
-
- *inform_listeners = FALSE;
- }
-}
-
-static gboolean
-button_layout_equal (const MetaButtonLayout *a,
- const MetaButtonLayout *b)
-{
- int i;
-
- i = 0;
- while (i < MAX_BUTTONS_PER_CORNER)
- {
- if (a->left_buttons[i] != b->left_buttons[i])
- return FALSE;
- if (a->right_buttons[i] != b->right_buttons[i])
- return FALSE;
- if (a->left_buttons_has_spacer[i] != b->left_buttons_has_spacer[i])
- return FALSE;
- if (a->right_buttons_has_spacer[i] != b->right_buttons_has_spacer[i])
- return FALSE;
- ++i;
- }
-
- return TRUE;
-}
-
-static MetaButtonFunction
-button_function_from_string (const char *str)
-{
- /* FIXME: gconf_string_to_enum is the obvious way to do this */
-
- if (strcmp (str, "menu") == 0)
- return META_BUTTON_FUNCTION_MENU;
- else if (strcmp (str, "minimize") == 0)
- return META_BUTTON_FUNCTION_MINIMIZE;
- else if (strcmp (str, "maximize") == 0)
- return META_BUTTON_FUNCTION_MAXIMIZE;
- else if (strcmp (str, "close") == 0)
- return META_BUTTON_FUNCTION_CLOSE;
- else if (strcmp (str, "shade") == 0)
- return META_BUTTON_FUNCTION_SHADE;
- else if (strcmp (str, "above") == 0)
- return META_BUTTON_FUNCTION_ABOVE;
- else if (strcmp (str, "stick") == 0)
- return META_BUTTON_FUNCTION_STICK;
- else
- /* don't know; give up */
- return META_BUTTON_FUNCTION_LAST;
-}
-
-static MetaButtonFunction
-button_opposite_function (MetaButtonFunction ofwhat)
-{
- switch (ofwhat)
- {
- case META_BUTTON_FUNCTION_SHADE:
- return META_BUTTON_FUNCTION_UNSHADE;
- case META_BUTTON_FUNCTION_UNSHADE:
- return META_BUTTON_FUNCTION_SHADE;
-
- case META_BUTTON_FUNCTION_ABOVE:
- return META_BUTTON_FUNCTION_UNABOVE;
- case META_BUTTON_FUNCTION_UNABOVE:
- return META_BUTTON_FUNCTION_ABOVE;
-
- case META_BUTTON_FUNCTION_STICK:
- return META_BUTTON_FUNCTION_UNSTICK;
- case META_BUTTON_FUNCTION_UNSTICK:
- return META_BUTTON_FUNCTION_STICK;
-
- default:
- return META_BUTTON_FUNCTION_LAST;
- }
-}
-
-static void
-button_layout_handler (MetaPreference pref,
- const gchar *string_value,
- gboolean *inform_listeners)
-{
- MetaButtonLayout new_layout;
- char **sides = NULL;
- int i;
-
- /* We need to ignore unknown button functions, for
- * compat with future versions
- */
-
- if (string_value)
- sides = g_strsplit (string_value, ":", 2);
-
- if (sides != NULL && sides[0] != NULL)
- {
- char **buttons;
- int b;
- gboolean used[META_BUTTON_FUNCTION_LAST];
-
- i = 0;
- while (i < META_BUTTON_FUNCTION_LAST)
- {
- used[i] = FALSE;
- new_layout.left_buttons_has_spacer[i] = FALSE;
- ++i;
- }
-
- buttons = g_strsplit (sides[0], ",", -1);
- i = 0;
- b = 0;
- while (buttons[b] != NULL)
- {
- MetaButtonFunction f = button_function_from_string (buttons[b]);
- if (i > 0 && strcmp("spacer", buttons[b]) == 0)
- {
- new_layout.left_buttons_has_spacer[i-1] = TRUE;
- f = button_opposite_function (f);
-
- if (f != META_BUTTON_FUNCTION_LAST)
- {
- new_layout.left_buttons_has_spacer[i-2] = TRUE;
- }
- }
- else
- {
- if (f != META_BUTTON_FUNCTION_LAST && !used[f])
- {
- new_layout.left_buttons[i] = f;
- used[f] = TRUE;
- ++i;
-
- f = button_opposite_function (f);
-
- if (f != META_BUTTON_FUNCTION_LAST)
- new_layout.left_buttons[i++] = f;
-
- }
- else
- {
- meta_topic (META_DEBUG_PREFS, "Ignoring unknown or already-used button name \"%s\"\n",
- buttons[b]);
- }
- }
-
- ++b;
- }
-
- new_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST;
- new_layout.left_buttons_has_spacer[i] = FALSE;
-
- g_strfreev (buttons);
- }
-
- if (sides != NULL && sides[0] != NULL && sides[1] != NULL)
- {
- char **buttons;
- int b;
- gboolean used[META_BUTTON_FUNCTION_LAST];
-
- i = 0;
- while (i < META_BUTTON_FUNCTION_LAST)
- {
- used[i] = FALSE;
- new_layout.right_buttons_has_spacer[i] = FALSE;
- ++i;
- }
-
- buttons = g_strsplit (sides[1], ",", -1);
- i = 0;
- b = 0;
- while (buttons[b] != NULL)
- {
- MetaButtonFunction f = button_function_from_string (buttons[b]);
- if (i > 0 && strcmp("spacer", buttons[b]) == 0)
- {
- new_layout.right_buttons_has_spacer[i-1] = TRUE;
- f = button_opposite_function (f);
- if (f != META_BUTTON_FUNCTION_LAST)
- {
- new_layout.right_buttons_has_spacer[i-2] = TRUE;
- }
- }
- else
- {
- if (f != META_BUTTON_FUNCTION_LAST && !used[f])
- {
- new_layout.right_buttons[i] = f;
- used[f] = TRUE;
- ++i;
-
- f = button_opposite_function (f);
-
- if (f != META_BUTTON_FUNCTION_LAST)
- new_layout.right_buttons[i++] = f;
-
- }
- else
- {
- meta_topic (META_DEBUG_PREFS, "Ignoring unknown or already-used button name \"%s\"\n",
- buttons[b]);
- }
- }
-
- ++b;
- }
-
- new_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
- new_layout.right_buttons_has_spacer[i] = FALSE;
-
- g_strfreev (buttons);
- }
-
- g_strfreev (sides);
-
- /* Invert the button layout for RTL languages */
- if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
- {
- MetaButtonLayout rtl_layout;
- int j;
-
- for (i = 0; new_layout.left_buttons[i] != META_BUTTON_FUNCTION_LAST; i++);
- for (j = 0; j < i; j++)
- {
- rtl_layout.right_buttons[j] = new_layout.left_buttons[i - j - 1];
- if (j == 0)
- rtl_layout.right_buttons_has_spacer[i - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
- else
- rtl_layout.right_buttons_has_spacer[j - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
- }
- rtl_layout.right_buttons[j] = META_BUTTON_FUNCTION_LAST;
- rtl_layout.right_buttons_has_spacer[j] = FALSE;
-
- for (i = 0; new_layout.right_buttons[i] != META_BUTTON_FUNCTION_LAST; i++);
- for (j = 0; j < i; j++)
- {
- rtl_layout.left_buttons[j] = new_layout.right_buttons[i - j - 1];
- if (j == 0)
- rtl_layout.left_buttons_has_spacer[i - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
- else
- rtl_layout.left_buttons_has_spacer[j - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
- }
- rtl_layout.left_buttons[j] = META_BUTTON_FUNCTION_LAST;
- rtl_layout.left_buttons_has_spacer[j] = FALSE;
-
- new_layout = rtl_layout;
- }
-
- if (button_layout_equal (&button_layout, &new_layout))
- {
- /* Same as before, so duck out */
- *inform_listeners = FALSE;
- }
- else
- {
- button_layout = new_layout;
- }
-}
-
-#endif /* HAVE_GCONF */
-
-const PangoFontDescription*
-meta_prefs_get_titlebar_font (void)
-{
- if (use_system_font)
- return NULL;
- else
- return titlebar_font;
-}
-
-int
-meta_prefs_get_num_workspaces (void)
-{
- return num_workspaces;
-}
-
-gboolean
-meta_prefs_get_application_based (void)
-{
- return FALSE; /* For now, we never want this to do anything */
-
- return application_based;
-}
-
-gboolean
-meta_prefs_get_disable_workarounds (void)
-{
- return disable_workarounds;
-}
-
-#ifdef HAVE_GCONF
-#define MAX_REASONABLE_AUTO_RAISE_DELAY 10000
-
-#endif /* HAVE_GCONF */
-
-#ifdef WITH_VERBOSE_MODE
-const char*
-meta_preference_to_string (MetaPreference pref)
-{
- /* FIXME: another case for gconf_string_to_enum */
- switch (pref)
- {
- case META_PREF_MOUSE_BUTTON_MODS:
- return "MOUSE_BUTTON_MODS";
-
- case META_PREF_FOCUS_MODE:
- return "FOCUS_MODE";
-
- case META_PREF_FOCUS_NEW_WINDOWS:
- return "FOCUS_NEW_WINDOWS";
-
- case META_PREF_RAISE_ON_CLICK:
- return "RAISE_ON_CLICK";
-
- case META_PREF_THEME:
- return "THEME";
-
- case META_PREF_TITLEBAR_FONT:
- return "TITLEBAR_FONT";
-
- case META_PREF_NUM_WORKSPACES:
- return "NUM_WORKSPACES";
-
- case META_PREF_APPLICATION_BASED:
- return "APPLICATION_BASED";
-
- case META_PREF_KEYBINDINGS:
- return "KEYBINDINGS";
-
- case META_PREF_DISABLE_WORKAROUNDS:
- return "DISABLE_WORKAROUNDS";
-
- case META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR:
- return "ACTION_DOUBLE_CLICK_TITLEBAR";
-
- case META_PREF_ACTION_MIDDLE_CLICK_TITLEBAR:
- return "ACTION_MIDDLE_CLICK_TITLEBAR";
-
- case META_PREF_ACTION_RIGHT_CLICK_TITLEBAR:
- return "ACTION_RIGHT_CLICK_TITLEBAR";
-
- case META_PREF_AUTO_RAISE:
- return "AUTO_RAISE";
-
- case META_PREF_AUTO_RAISE_DELAY:
- return "AUTO_RAISE_DELAY";
-
- case META_PREF_COMMANDS:
- return "COMMANDS";
-
- case META_PREF_TERMINAL_COMMAND:
- return "TERMINAL_COMMAND";
-
- case META_PREF_BUTTON_LAYOUT:
- return "BUTTON_LAYOUT";
-
- case META_PREF_WORKSPACE_NAMES:
- return "WORKSPACE_NAMES";
-
- case META_PREF_VISUAL_BELL:
- return "VISUAL_BELL";
-
- case META_PREF_AUDIBLE_BELL:
- return "AUDIBLE_BELL";
-
- case META_PREF_VISUAL_BELL_TYPE:
- return "VISUAL_BELL_TYPE";
-
- case META_PREF_REDUCED_RESOURCES:
- return "REDUCED_RESOURCES";
-
- case META_PREF_GNOME_ACCESSIBILITY:
- return "GNOME_ACCESSIBILTY";
-
- case META_PREF_GNOME_ANIMATIONS:
- return "GNOME_ANIMATIONS";
-
- case META_PREF_CURSOR_THEME:
- return "CURSOR_THEME";
-
- case META_PREF_CURSOR_SIZE:
- return "CURSOR_SIZE";
-
- case META_PREF_COMPOSITING_MANAGER:
- return "COMPOSITING_MANAGER";
- }
-
- return "(unknown)";
-}
-#endif /* WITH_VERBOSE_MODE */
-
-void
-meta_prefs_set_num_workspaces (int n_workspaces)
-{
-#ifdef HAVE_GCONF
- GError *err;
-
- if (default_client == NULL)
- return;
-
- if (n_workspaces < 1)
- n_workspaces = 1;
- if (n_workspaces > MAX_REASONABLE_WORKSPACES)
- n_workspaces = MAX_REASONABLE_WORKSPACES;
-
- err = NULL;
- gconf_client_set_int (default_client,
- KEY_NUM_WORKSPACES,
- n_workspaces,
- &err);
-
- if (err)
- {
- meta_warning (_("Error setting number of workspaces to %d: %s\n"),
- num_workspaces,
- err->message);
- g_error_free (err);
- }
-#endif /* HAVE_GCONF */
-}
-
-#define keybind(name, handler, param, flags, stroke, description) \
- { #name, NULL, !!(flags & BINDING_REVERSES), !!(flags & BINDING_PER_WINDOW) },
-static MetaKeyPref key_bindings[] = {
-#include "all-keybindings.h"
- { NULL, NULL, FALSE }
-};
-#undef keybind
-
-#ifndef HAVE_GCONF
-
-/**
- * A type to map names of keybindings (such as "switch_windows")
- * to the binding strings themselves (such as "<Alt>Tab").
- * It exists only when GConf is turned off in ./configure and
- * functions as a sort of ersatz GConf.
- */
-typedef struct
-{
- const char *name;
- const char *keybinding;
-} MetaSimpleKeyMapping;
-
-/* FIXME: This would be neater if the array only contained entries whose
- * default keystroke was non-null. You COULD do this by defining
- * ONLY_BOUND_BY_DEFAULT around various blocks at the cost of making
- * the bindings file way more complicated. However, we could stop this being
- * data and move it into code. Then the compiler would optimise away
- * the problem lines.
- */
-
-#define keybind(name, handler, param, flags, stroke, description) \
- { #name, stroke },
-
-static MetaSimpleKeyMapping key_string_bindings[] = {
-#include "all-keybindings.h"
- { NULL, NULL }
-};
-#undef keybind
-
-#endif /* NOT HAVE_GCONF */
-
-static void
-init_bindings (void)
-{
-#ifdef HAVE_GCONF
- int i = 0;
- GError *err;
-
- while (key_bindings[i].name)
- {
- GSList *list_val, *tmp;
- char *str_val;
- char *key;
-
- key = g_strconcat (key_bindings[i].per_window?
- KEY_WINDOW_BINDINGS_PREFIX:
- KEY_SCREEN_BINDINGS_PREFIX,
- "/",
- key_bindings[i].name, NULL);
-
- err = NULL;
- str_val = gconf_client_get_string (default_client, key, &err);
- cleanup_error (&err);
-
- update_binding (&key_bindings[i], str_val);
-
- g_free (str_val);
- g_free (key);
-
- key = g_strconcat (key_bindings[i].per_window?
- KEY_WINDOW_BINDINGS_PREFIX:
- KEY_SCREEN_BINDINGS_PREFIX,
- "/",
- key_bindings[i].name,
- KEY_LIST_BINDINGS_SUFFIX, NULL);
-
- err = NULL;
-
- list_val = gconf_client_get_list (default_client, key, GCONF_VALUE_STRING, &err);
- cleanup_error (&err);
-
- update_list_binding (&key_bindings[i], list_val, META_LIST_OF_STRINGS);
-
- tmp = list_val;
- while (tmp)
- {
- g_free (tmp->data);
- tmp = tmp->next;
- }
- g_slist_free (list_val);
- g_free (key);
-
- ++i;
- }
-#else /* HAVE_GCONF */
- int i = 0;
- int which = 0;
- while (key_string_bindings[i].name)
- {
- if (key_string_bindings[i].keybinding == NULL) {
- ++i;
- continue;
- }
-
- while (strcmp(key_bindings[which].name,
- key_string_bindings[i].name) != 0)
- which++;
-
- /* Set the binding */
- update_binding (&key_bindings[which],
- key_string_bindings[i].keybinding);
-
- ++i;
- }
-#endif /* HAVE_GCONF */
-}
-
-static void
-init_commands (void)
-{
-#ifdef HAVE_GCONF
- int i;
- GError *err;
-
- i = 0;
- while (i < MAX_COMMANDS)
- {
- char *str_val;
- char *key;
-
- key = meta_prefs_get_gconf_key_for_command (i);
-
- err = NULL;
- str_val = gconf_client_get_string (default_client, key, &err);
- cleanup_error (&err);
-
- update_command (key, str_val);
-
- g_free (str_val);
- g_free (key);
-
- ++i;
- }
-#else
- int i;
- for (i = 0; i < MAX_COMMANDS; i++)
- commands[i] = NULL;
-#endif /* HAVE_GCONF */
-}
-
-static void
-init_workspace_names (void)
-{
-#ifdef HAVE_GCONF
- int i;
- GError *err;
-
- i = 0;
- while (i < MAX_REASONABLE_WORKSPACES)
- {
- char *str_val;
- char *key;
-
- key = gconf_key_for_workspace_name (i);
-
- err = NULL;
- str_val = gconf_client_get_string (default_client, key, &err);
- cleanup_error (&err);
-
- update_workspace_name (key, str_val);
-
- g_assert (workspace_names[i] != NULL);
-
- g_free (str_val);
- g_free (key);
-
- ++i;
- }
-#else
- int i;
- for (i = 0; i < MAX_REASONABLE_WORKSPACES; i++)
- workspace_names[i] = g_strdup_printf (_("Workspace %d"), i + 1);
-
- meta_topic (META_DEBUG_PREFS,
- "Initialized workspace names\n");
-#endif /* HAVE_GCONF */
-}
-
-static gboolean
-update_binding (MetaKeyPref *binding,
- const char *value)
-{
- unsigned int keysym;
- unsigned int keycode;
- MetaVirtualModifier mods;
- MetaKeyCombo *combo;
- gboolean changed;
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Binding \"%s\" has new gconf value \"%s\"\n",
- binding->name, value ? value : "none");
-
- keysym = 0;
- keycode = 0;
- mods = 0;
- if (value)
- {
- if (!meta_ui_parse_accelerator (value, &keysym, &keycode, &mods))
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Failed to parse new gconf value\n");
- meta_warning (_("\"%s\" found in configuration database is not a valid value for keybinding \"%s\"\n"),
- value, binding->name);
-
- return FALSE;
- }
- }
-
- /* If there isn't already a first element, make one. */
- if (!binding->bindings)
- {
- MetaKeyCombo *blank = g_malloc0 (sizeof (MetaKeyCombo));
- binding->bindings = g_slist_alloc();
- binding->bindings->data = blank;
- }
-
- combo = binding->bindings->data;
-
-#ifdef HAVE_GCONF
- /* Bug 329676: Bindings which can be shifted must not have no modifiers,
- * nor only SHIFT as a modifier.
- */
-
- if (binding->add_shift &&
- 0 != keysym &&
- (META_VIRTUAL_SHIFT_MASK == mods || 0 == mods))
- {
- gchar *old_setting;
- gchar *key;
- GError *err = NULL;
-
- meta_warning ("Cannot bind \"%s\" to %s: it needs a modifier "
- "such as Ctrl or Alt.\n",
- binding->name,
- value);
-
- old_setting = meta_ui_accelerator_name (combo->keysym,
- combo->modifiers);
-
- if (!strcmp(old_setting, value))
- {
- /* We were about to set it to the same value
- * that it had originally! This must be caused
- * by getting an invalid string back from
- * meta_ui_accelerator_name. Bail out now
- * so we don't get into an infinite loop.
- */
- g_free (old_setting);
- return TRUE;
- }
-
- meta_warning ("Reverting \"%s\" to %s.\n",
- binding->name,
- old_setting);
-
- /* FIXME: add_shift is currently screen_bindings only, but
- * there's no really good reason it should always be.
- * So we shouldn't blindly add KEY_SCREEN_BINDINGS_PREFIX
- * onto here.
- */
- key = g_strconcat (KEY_SCREEN_BINDINGS_PREFIX, "/",
- binding->name, NULL);
-
- gconf_client_set_string (gconf_client_get_default (),
- key, old_setting, &err);
-
- if (err)
- {
- meta_warning ("Error while reverting keybinding: %s\n",
- err->message);
- g_error_free (err);
- err = NULL;
- }
-
- g_free (old_setting);
- g_free (key);
-
- /* The call to gconf_client_set_string() will cause this function
- * to be called again with the new value, so there's no need to
- * carry on.
- */
- return TRUE;
- }
-#endif
-
- changed = FALSE;
- if (keysym != combo->keysym ||
- keycode != combo->keycode ||
- mods != combo->modifiers)
- {
- changed = TRUE;
-
- combo->keysym = keysym;
- combo->keycode = keycode;
- combo->modifiers = mods;
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "New keybinding for \"%s\" is keysym = 0x%x keycode = 0x%x mods = 0x%x\n",
- binding->name, combo->keysym, combo->keycode,
- combo->modifiers);
- }
- else
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Keybinding for \"%s\" is unchanged\n", binding->name);
- }
-
- return changed;
-}
-
-#ifdef HAVE_GCONF
-static gboolean
-update_list_binding (MetaKeyPref *binding,
- GSList *value,
- MetaStringListType type_of_value)
-{
- unsigned int keysym;
- unsigned int keycode;
- MetaVirtualModifier mods;
- gboolean changed = FALSE;
- const gchar *pref_string;
- GSList *pref_iterator = value, *tmp;
- MetaKeyCombo *combo;
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Binding \"%s\" has new gconf value\n",
- binding->name);
-
- if (binding->bindings == NULL)
- {
- /* We need to insert a dummy element into the list, because the first
- * element is the one governed by update_binding. We only handle the
- * subsequent elements.
- */
- MetaKeyCombo *blank = g_malloc0 (sizeof (MetaKeyCombo));
- binding->bindings = g_slist_alloc();
- binding->bindings->data = blank;
- }
-
- /* Okay, so, we're about to provide a new list of key combos for this
- * action. Delete any pre-existing list.
- */
- tmp = binding->bindings->next;
- while (tmp)
- {
- g_free (tmp->data);
- tmp = tmp->next;
- }
- g_slist_free (binding->bindings->next);
- binding->bindings->next = NULL;
-
- while (pref_iterator)
- {
- keysym = 0;
- keycode = 0;
- mods = 0;
-
- if (!pref_iterator->data)
- {
- pref_iterator = pref_iterator->next;
- continue;
- }
-
- switch (type_of_value)
- {
- case META_LIST_OF_STRINGS:
- pref_string = pref_iterator->data;
- break;
- case META_LIST_OF_GCONFVALUE_STRINGS:
- pref_string = gconf_value_get_string (pref_iterator->data);
- break;
- default:
- g_assert_not_reached ();
- }
-
- if (!meta_ui_parse_accelerator (pref_string, &keysym, &keycode, &mods))
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Failed to parse new gconf value\n");
- meta_warning (_("\"%s\" found in configuration database is not a valid value for keybinding \"%s\"\n"),
- pref_string, binding->name);
-
- /* Should we remove this value from the list in gconf? */
- pref_iterator = pref_iterator->next;
- continue;
- }
-
- /* Bug 329676: Bindings which can be shifted must not have no modifiers,
- * nor only SHIFT as a modifier.
- */
-
- if (binding->add_shift &&
- 0 != keysym &&
- (META_VIRTUAL_SHIFT_MASK == mods || 0 == mods))
- {
- meta_warning ("Cannot bind \"%s\" to %s: it needs a modifier "
- "such as Ctrl or Alt.\n",
- binding->name,
- pref_string);
-
- /* Should we remove this value from the list in gconf? */
-
- pref_iterator = pref_iterator->next;
- continue;
- }
-
- changed = TRUE;
-
- combo = g_malloc0 (sizeof (MetaKeyCombo));
- combo->keysym = keysym;
- combo->keycode = keycode;
- combo->modifiers = mods;
- binding->bindings->next = g_slist_prepend (binding->bindings->next, combo);
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "New keybinding for \"%s\" is keysym = 0x%x keycode = 0x%x mods = 0x%x\n",
- binding->name, keysym, keycode, mods);
-
- pref_iterator = pref_iterator->next;
- }
- return changed;
-}
-
-static const gchar*
-relative_key (const gchar* key)
-{
- const gchar* end;
-
- end = strrchr (key, '/');
-
- ++end;
-
- return end;
-}
-
-/* Return value is TRUE if a preference changed and we need to
- * notify
- */
-static gboolean
-find_and_update_binding (MetaKeyPref *bindings,
- const char *name,
- const char *value)
-{
- const char *key;
- int i;
-
- if (*name == '/')
- key = relative_key (name);
- else
- key = name;
-
- i = 0;
- while (bindings[i].name &&
- strcmp (key, bindings[i].name) != 0)
- ++i;
-
- if (bindings[i].name)
- return update_binding (&bindings[i], value);
- else
- return FALSE;
-}
-
-static gboolean
-update_key_binding (const char *name,
- const char *value)
-{
- return find_and_update_binding (key_bindings, name, value);
-}
-
-static gboolean
-find_and_update_list_binding (MetaKeyPref *bindings,
- const char *name,
- GSList *value)
-{
- const char *key;
- int i;
- gchar *name_without_suffix = g_strdup(name);
-
- name_without_suffix[strlen(name_without_suffix) - strlen(KEY_LIST_BINDINGS_SUFFIX)] = 0;
-
- if (*name_without_suffix == '/')
- key = relative_key (name_without_suffix);
- else
- key = name_without_suffix;
-
- i = 0;
- while (bindings[i].name &&
- strcmp (key, bindings[i].name) != 0)
- ++i;
-
- g_free (name_without_suffix);
-
- if (bindings[i].name)
- return update_list_binding (&bindings[i], value, META_LIST_OF_GCONFVALUE_STRINGS);
- else
- return FALSE;
-}
-
-static gboolean
-update_key_list_binding (const char *name,
- GSList *value)
-{
- return find_and_update_list_binding (key_bindings, name, value);
-}
-
-static gboolean
-update_command (const char *name,
- const char *value)
-{
- char *p;
- int i;
-
- p = strrchr (name, '_');
- if (p == NULL)
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Command %s has no underscore?\n", name);
- return FALSE;
- }
-
- ++p;
-
- if (g_ascii_isdigit (*p))
- {
- i = atoi (p);
- i -= 1; /* count from 0 not 1 */
- }
- else
- {
- p = strrchr (name, '/');
- ++p;
-
- if (strcmp (p, "command_screenshot") == 0)
- {
- i = SCREENSHOT_COMMAND_IDX;
- }
- else if (strcmp (p, "command_window_screenshot") == 0)
- {
- i = WIN_SCREENSHOT_COMMAND_IDX;
- }
- else
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Command %s doesn't end in number?\n", name);
- return FALSE;
- }
- }
-
- if (i >= MAX_COMMANDS)
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Command %d is too highly numbered, ignoring\n", i);
- return FALSE;
- }
-
- if ((commands[i] == NULL && value == NULL) ||
- (commands[i] && value && strcmp (commands[i], value) == 0))
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Command %d is unchanged\n", i);
- return FALSE;
- }
-
- g_free (commands[i]);
- commands[i] = g_strdup (value);
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Updated command %d to \"%s\"\n",
- i, commands[i] ? commands[i] : "none");
-
- return TRUE;
-}
-
-#endif /* HAVE_GCONF */
-
-const char*
-meta_prefs_get_command (int i)
-{
- g_return_val_if_fail (i >= 0 && i < MAX_COMMANDS, NULL);
-
- return commands[i];
-}
-
-char*
-meta_prefs_get_gconf_key_for_command (int i)
-{
- char *key;
-
- switch (i)
- {
- case SCREENSHOT_COMMAND_IDX:
- key = g_strdup (KEY_COMMAND_PREFIX "screenshot");
- break;
- case WIN_SCREENSHOT_COMMAND_IDX:
- key = g_strdup (KEY_COMMAND_PREFIX "window_screenshot");
- break;
- default:
- key = g_strdup_printf (KEY_COMMAND_PREFIX"%d", i + 1);
- break;
- }
-
- return key;
-}
-
-const char*
-meta_prefs_get_terminal_command (void)
-{
- return terminal_command;
-}
-
-const char*
-meta_prefs_get_gconf_key_for_terminal_command (void)
-{
- return KEY_TERMINAL_COMMAND;
-}
-
-#ifdef HAVE_GCONF
-static gboolean
-update_workspace_name (const char *name,
- const char *value)
-{
- char *p;
- int i;
-
- p = strrchr (name, '_');
- if (p == NULL)
- {
- meta_topic (META_DEBUG_PREFS,
- "Workspace name %s has no underscore?\n", name);
- return FALSE;
- }
-
- ++p;
-
- if (!g_ascii_isdigit (*p))
- {
- meta_topic (META_DEBUG_PREFS,
- "Workspace name %s doesn't end in number?\n", name);
- return FALSE;
- }
-
- i = atoi (p);
- i -= 1; /* count from 0 not 1 */
-
- if (i >= MAX_REASONABLE_WORKSPACES)
- {
- meta_topic (META_DEBUG_PREFS,
- "Workspace name %d is too highly numbered, ignoring\n", i);
- return FALSE;
- }
-
- if (workspace_names[i] && value && strcmp (workspace_names[i], value) == 0)
- {
- meta_topic (META_DEBUG_PREFS,
- "Workspace name %d is unchanged\n", i);
- return FALSE;
- }
-
- /* This is a bad hack. We have to treat empty string as
- * "unset" because the root window property can't contain
- * null. So it gets empty string instead and we don't want
- * that to result in setting the empty string as a value that
- * overrides "unset".
- */
- if (value != NULL && *value != '\0')
- {
- g_free (workspace_names[i]);
- workspace_names[i] = g_strdup (value);
- }
- else
- {
- /* use a default name */
- char *d;
-
- d = g_strdup_printf (_("Workspace %d"), i + 1);
- if (workspace_names[i] && strcmp (workspace_names[i], d) == 0)
- {
- g_free (d);
- return FALSE;
- }
- else
- {
- g_free (workspace_names[i]);
- workspace_names[i] = d;
- }
- }
-
- meta_topic (META_DEBUG_PREFS,
- "Updated workspace name %d to \"%s\"\n",
- i, workspace_names[i] ? workspace_names[i] : "none");
-
- return TRUE;
-}
-#endif /* HAVE_GCONF */
-
-const char*
-meta_prefs_get_workspace_name (int i)
-{
- g_return_val_if_fail (i >= 0 && i < MAX_REASONABLE_WORKSPACES, NULL);
-
- g_assert (workspace_names[i] != NULL);
-
- meta_topic (META_DEBUG_PREFS,
- "Getting workspace name for %d: \"%s\"\n",
- i, workspace_names[i]);
-
- return workspace_names[i];
-}
-
-void
-meta_prefs_change_workspace_name (int i,
- const char *name)
-{
-#ifdef HAVE_GCONF
- char *key;
- GError *err;
-
- g_return_if_fail (i >= 0 && i < MAX_REASONABLE_WORKSPACES);
-
- meta_topic (META_DEBUG_PREFS,
- "Changing name of workspace %d to %s\n",
- i, name ? name : "none");
-
- /* This is a bad hack. We have to treat empty string as
- * "unset" because the root window property can't contain
- * null. So it gets empty string instead and we don't want
- * that to result in setting the empty string as a value that
- * overrides "unset".
- */
- if (name && *name == '\0')
- name = NULL;
-
- if ((name == NULL && workspace_names[i] == NULL) ||
- (name && workspace_names[i] && strcmp (name, workspace_names[i]) == 0))
- {
- meta_topic (META_DEBUG_PREFS,
- "Workspace %d already has name %s\n",
- i, name ? name : "none");
- return;
- }
-
- key = gconf_key_for_workspace_name (i);
-
- err = NULL;
- if (name != NULL)
- gconf_client_set_string (default_client,
- key, name,
- &err);
- else
- gconf_client_unset (default_client,
- key, &err);
-
-
- if (err)
- {
- meta_warning (_("Error setting name for workspace %d to \"%s\": %s\n"),
- i, name ? name : "none",
- err->message);
- g_error_free (err);
- }
-
- g_free (key);
-#else
- g_free (workspace_names[i]);
- workspace_names[i] = g_strdup (name);
-#endif /* HAVE_GCONF */
-}
-
-#ifdef HAVE_GCONF
-static char*
-gconf_key_for_workspace_name (int i)
-{
- char *key;
-
- key = g_strdup_printf (KEY_WORKSPACE_NAME_PREFIX"%d", i + 1);
-
- return key;
-}
-#endif /* HAVE_GCONF */
-
-void
-meta_prefs_get_button_layout (MetaButtonLayout *button_layout_p)
-{
- *button_layout_p = button_layout;
-}
-
-gboolean
-meta_prefs_get_visual_bell (void)
-{
- return provide_visual_bell;
-}
-
-gboolean
-meta_prefs_bell_is_audible (void)
-{
- return bell_is_audible;
-}
-
-MetaVisualBellType
-meta_prefs_get_visual_bell_type (void)
-{
- return visual_bell_type;
-}
-
-void
-meta_prefs_get_key_bindings (const MetaKeyPref **bindings,
- int *n_bindings)
-{
-
- *bindings = key_bindings;
- *n_bindings = (int) G_N_ELEMENTS (key_bindings) - 1;
-}
-
-MetaActionTitlebar
-meta_prefs_get_action_double_click_titlebar (void)
-{
- return action_double_click_titlebar;
-}
-
-MetaActionTitlebar
-meta_prefs_get_action_middle_click_titlebar (void)
-{
- return action_middle_click_titlebar;
-}
-
-MetaActionTitlebar
-meta_prefs_get_action_right_click_titlebar (void)
-{
- return action_right_click_titlebar;
-}
-
-gboolean
-meta_prefs_get_auto_raise (void)
-{
- return auto_raise;
-}
-
-int
-meta_prefs_get_auto_raise_delay (void)
-{
- return auto_raise_delay;
-}
-
-gboolean
-meta_prefs_get_reduced_resources (void)
-{
- return reduced_resources;
-}
-
-gboolean
-meta_prefs_get_gnome_accessibility ()
-{
- return gnome_accessibility;
-}
-
-gboolean
-meta_prefs_get_gnome_animations ()
-{
- return gnome_animations;
-}
-
-MetaKeyBindingAction
-meta_prefs_get_keybinding_action (const char *name)
-{
- int i;
-
- i = G_N_ELEMENTS (key_bindings) - 2; /* -2 for dummy entry at end */
- while (i >= 0)
- {
- if (strcmp (key_bindings[i].name, name) == 0)
- return (MetaKeyBindingAction) i;
-
- --i;
- }
-
- return META_KEYBINDING_ACTION_NONE;
-}
-
-/* This is used by the menu system to decide what key binding
- * to display next to an option. We return the first non-disabled
- * binding, if any.
- */
-void
-meta_prefs_get_window_binding (const char *name,
- unsigned int *keysym,
- MetaVirtualModifier *modifiers)
-{
- int i;
-
- i = G_N_ELEMENTS (key_bindings) - 2; /* -2 for dummy entry at end */
- while (i >= 0)
- {
- if (key_bindings[i].per_window &&
- strcmp (key_bindings[i].name, name) == 0)
- {
- GSList *s = key_bindings[i].bindings;
-
- while (s)
- {
- MetaKeyCombo *c = s->data;
-
- if (c->keysym!=0 || c->modifiers!=0)
- {
- *keysym = c->keysym;
- *modifiers = c->modifiers;
- return;
- }
-
- s = s->next;
- }
-
- /* Not found; return the disabled value */
- *keysym = *modifiers = 0;
- return;
- }
-
- --i;
- }
-
- g_assert_not_reached ();
-}
-
-gboolean
-meta_prefs_get_compositing_manager (void)
-{
- return compositing_manager;
-}
-
-void
-meta_prefs_set_compositing_manager (gboolean whether)
-{
-#ifdef HAVE_GCONF
- GError *err = NULL;
-
- gconf_client_set_bool (default_client,
- KEY_COMPOSITOR,
- whether,
- &err);
-
- if (err)
- {
- meta_warning (_("Error setting compositor status: %s\n"),
- err->message);
- g_error_free (err);
- }
-#else
- compositing_manager = whether;
-#endif
-}
-
-#ifndef HAVE_GCONF
-static void
-init_button_layout(void)
-{
- MetaButtonLayout button_layout_ltr = {
- {
- /* buttons in the group on the left side */
- META_BUTTON_FUNCTION_MENU,
- META_BUTTON_FUNCTION_LAST
- },
- {
- /* buttons in the group on the right side */
- META_BUTTON_FUNCTION_MINIMIZE,
- META_BUTTON_FUNCTION_MAXIMIZE,
- META_BUTTON_FUNCTION_CLOSE,
- META_BUTTON_FUNCTION_LAST
- }
- };
- MetaButtonLayout button_layout_rtl = {
- {
- /* buttons in the group on the left side */
- META_BUTTON_FUNCTION_CLOSE,
- META_BUTTON_FUNCTION_MAXIMIZE,
- META_BUTTON_FUNCTION_MINIMIZE,
- META_BUTTON_FUNCTION_LAST
- },
- {
- /* buttons in the group on the right side */
- META_BUTTON_FUNCTION_MENU,
- META_BUTTON_FUNCTION_LAST
- }
- };
-
- button_layout = meta_ui_get_direction() == META_UI_DIRECTION_LTR ?
- button_layout_ltr : button_layout_rtl;
-};
-
-#endif
diff --git a/src/core/schema-bindings.c b/src/core/schema-bindings.c
deleted file mode 100644
index 77a42899..00000000
--- a/src/core/schema-bindings.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2008 Thomas Thurman
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-/** \file Schema bindings generator.
- *
- * This program simply takes the items given in the binding list in
- * all-keybindings.h and turns them into a portion of
- * the GConf .schemas file.
- *
- * FIXME: also need to make 50-metacity-desktop-key.xml
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#include <glib.h>
-#include "config.h"
-
-#define _(x) x
-
-static void single_stanza (gboolean is_window, const char *name,
- const char *default_value,
- gboolean can_reverse,
- const char *description);
-
-char *about_keybindings, *about_reversible_keybindings;
-
-char *source_filename, *target_filename;
-FILE *source_file, *target_file;
-
-static void
-single_stanza (gboolean is_window, const char *name,
- const char *default_value,
- gboolean can_reverse,
- const char *description)
-{
- char *keybinding_type = is_window? "window": "global";
- char *escaped_default_value, *escaped_description;
-
- if (description==NULL)
- return; /* it must be undocumented, so it can't go in this table */
-
- escaped_description = g_markup_escape_text (description, -1);
- escaped_default_value = default_value==NULL? "disabled":
- g_markup_escape_text (default_value, -1);
-
- fprintf (target_file, " <schema>\n");
- fprintf (target_file, " <key>/schemas/apps/metacity/%s_keybindings/%s</key>\n",
- keybinding_type, name);
- fprintf (target_file, " <applyto>/apps/metacity/%s_keybindings/%s</applyto>\n",
- keybinding_type, name);
- fprintf (target_file, " <owner>metacity</owner>\n");
- fprintf (target_file, " <type>string</type>\n");
- fprintf (target_file, " <default>%s</default>\n", escaped_default_value);
-
- fprintf (target_file, " <locale name=\"C\">\n");
- fprintf (target_file, " <short>%s</short>\n", description);
- fprintf (target_file, " <long>%s</long>\n",
- can_reverse? about_reversible_keybindings:
- about_keybindings);
- fprintf (target_file, " </locale>\n");
- fprintf (target_file, " </schema>\n\n");
-
- g_free (escaped_description);
-
- if (default_value!=NULL)
- g_free (escaped_default_value);
-}
-
-static void produce_bindings ();
-
-static void
-produce_bindings ()
-{
- /* 10240 is ridiculous overkill; we're writing the input file and
- * the lines are always 80 chars or less.
- */
- char buffer[10240];
-
- source_file = fopen(source_filename, "r");
-
- if (!source_file)
- {
- g_error ("Cannot compile without %s: %s\n",
- source_filename, strerror (errno));
- }
-
- target_file = fopen(target_filename, "w");
-
- if (!target_file)
- {
- g_error ("Cannot create %s: %s\n",
- target_filename, strerror (errno));
- }
-
- while (fgets (buffer, sizeof (buffer), source_file))
- {
- if (strstr (buffer, "<!-- GENERATED -->"))
- break;
-
- fprintf (target_file, "%s", buffer);
- }
-
- if (!feof (source_file))
- {
-#define keybind(name, handler, param, flags, stroke, description) \
- single_stanza ( \
- flags & BINDING_PER_WINDOW, \
- #name, \
- stroke, \
- flags & BINDING_REVERSES, \
- description);
-#include "all-keybindings.h"
-#undef keybind
- }
-
- while (fgets (buffer, sizeof (buffer), source_file))
- fprintf (target_file, "%s", buffer);
-
- if (fclose (source_file)!=0)
- g_error ("Cannot close %s: %s\n",
- source_filename, strerror (errno));
-
- if (fclose (target_file)!=0)
- g_error ("Cannot close %s: %s\n",
- target_filename, strerror (errno));
-}
-
-int
-main (int argc, char **argv)
-{
- if (argc!=3)
- {
- g_error ("Syntax: %s <source.in.in> <target.in>\n", argv[0]);
- }
-
- source_filename = argv[1];
- target_filename = argv[2];
-
- /* Translators: Please don't translate "Control", "Shift", etc, since these
- * are hardcoded (in gtk/gtkaccelgroup.c; it's not metacity's fault).
- * "disabled" must also stay as it is.
- */
- about_keybindings = g_markup_escape_text(_( \
- "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n\n"\
- "The parser is fairly liberal and allows "\
- "lower or upper case, and also abbreviations such as \"<Ctl>\" and " \
- "\"<Ctrl>\". If you set the option to the special string " \
- "\"disabled\", then there will be no keybinding for this action."),
- -1);
-
- about_reversible_keybindings = g_markup_escape_text(_( \
- "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n\n"\
- "The parser is fairly liberal and allows "\
- "lower or upper case, and also abbreviations such as \"<Ctl>\" and " \
- "\"<Ctrl>\". If you set the option to the special string " \
- "\"disabled\", then there will be no keybinding for this action.\n\n"\
- "This keybinding may be reversed by holding down the \"shift\" key; "
- "therefore, \"shift\" cannot be one of the keys it uses."),
- -1);
-
- produce_bindings ();
-
- g_free (about_keybindings);
- g_free (about_reversible_keybindings);
-
- return 0;
-}
-
-/* eof schema-bindings.c */
-
diff --git a/src/core/screen-private.h b/src/core/screen-private.h
deleted file mode 100644
index d9de2f53..00000000
--- a/src/core/screen-private.h
+++ /dev/null
@@ -1,225 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * \file screen-private.h Screens which Metacity manages
- *
- * Managing X screens.
- * This file contains methods on this class which are available to
- * routines in core but not outside it. (See screen.h for the routines
- * which the rest of the world is allowed to use.)
- */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2003 Rob Adams
- * Copyright (C) 2004-2006 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_SCREEN_PRIVATE_H
-#define META_SCREEN_PRIVATE_H
-
-#include "display-private.h"
-#include "screen.h"
-#include <X11/Xutil.h>
-#include "ui.h"
-
-typedef struct _MetaXineramaScreenInfo MetaXineramaScreenInfo;
-
-struct _MetaXineramaScreenInfo
-{
- int number;
- MetaRectangle rect;
-};
-
-typedef void (* MetaScreenWindowFunc) (MetaScreen *screen, MetaWindow *window,
- gpointer user_data);
-
-typedef enum
-{
- META_SCREEN_TOPLEFT,
- META_SCREEN_TOPRIGHT,
- META_SCREEN_BOTTOMLEFT,
- META_SCREEN_BOTTOMRIGHT
-} MetaScreenCorner;
-
-typedef enum
-{
- META_SCREEN_UP,
- META_SCREEN_DOWN,
- META_SCREEN_LEFT,
- META_SCREEN_RIGHT
-} MetaScreenDirection;
-
-#define META_WIREFRAME_XOR_LINE_WIDTH 2
-
-struct _MetaScreen
-{
- MetaDisplay *display;
- int number;
- char *screen_name;
- Screen *xscreen;
- Window xroot;
- int default_depth;
- Visual *default_xvisual;
- MetaRectangle rect; /* Size of screen; rect.x & rect.y are always 0 */
- MetaUI *ui;
- MetaTabPopup *tab_popup;
-
- MetaWorkspace *active_workspace;
-
- /* This window holds the focus when we don't want to focus
- * any actual clients
- */
- Window no_focus_window;
-
- GList *workspaces;
-
- MetaStack *stack;
-
- MetaCursor current_cursor;
-
- Window flash_window;
-
- Window wm_sn_selection_window;
- Atom wm_sn_atom;
- guint32 wm_sn_timestamp;
-
- MetaXineramaScreenInfo *xinerama_infos;
- int n_xinerama_infos;
-
- /* Cache the current Xinerama */
- int last_xinerama_index;
-
-#ifdef HAVE_STARTUP_NOTIFICATION
- SnMonitorContext *sn_context;
- GSList *startup_sequences;
- guint startup_sequence_timeout;
-#endif
-
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- Window wm_cm_selection_window;
-#endif
-
- guint work_area_idle;
-
- int rows_of_workspaces;
- int columns_of_workspaces;
- MetaScreenCorner starting_corner;
- guint vertical_workspaces : 1;
-
- guint keys_grabbed : 1;
- guint all_keys_grabbed : 1;
-
- int closing;
-
- /* gc for XOR on root window */
- GC root_xor_gc;
-
- /* Managed by compositor.c */
- gpointer compositor_data;
-};
-
-MetaScreen* meta_screen_new (MetaDisplay *display,
- int number,
- guint32 timestamp);
-void meta_screen_free (MetaScreen *screen,
- guint32 timestamp);
-void meta_screen_manage_all_windows (MetaScreen *screen);
-void meta_screen_foreach_window (MetaScreen *screen,
- MetaScreenWindowFunc func,
- gpointer data);
-void meta_screen_queue_frame_redraws (MetaScreen *screen);
-void meta_screen_queue_window_resizes (MetaScreen *screen);
-
-int meta_screen_get_n_workspaces (MetaScreen *screen);
-
-MetaWorkspace* meta_screen_get_workspace_by_index (MetaScreen *screen,
- int index);
-
-void meta_screen_set_cursor (MetaScreen *screen,
- MetaCursor cursor);
-void meta_screen_update_cursor (MetaScreen *screen);
-
-void meta_screen_ensure_tab_popup (MetaScreen *screen,
- MetaTabList list_type,
- MetaTabShowType show_type);
-void meta_screen_ensure_workspace_popup (MetaScreen *screen);
-
-MetaWindow* meta_screen_get_mouse_window (MetaScreen *screen,
- MetaWindow *not_this_one);
-
-const MetaXineramaScreenInfo* meta_screen_get_current_xinerama (MetaScreen *screen);
-const MetaXineramaScreenInfo* meta_screen_get_xinerama_for_rect (MetaScreen *screen,
- MetaRectangle *rect);
-const MetaXineramaScreenInfo* meta_screen_get_xinerama_for_window (MetaScreen *screen,
- MetaWindow *window);
-
-
-const MetaXineramaScreenInfo* meta_screen_get_xinerama_neighbor (MetaScreen *screen,
- int which_xinerama,
- MetaScreenDirection dir);
-void meta_screen_get_natural_xinerama_list (MetaScreen *screen,
- int** xineramas_list,
- int* n_xineramas);
-
-void meta_screen_update_workspace_layout (MetaScreen *screen);
-void meta_screen_update_workspace_names (MetaScreen *screen);
-void meta_screen_queue_workarea_recalc (MetaScreen *screen);
-
-Window meta_create_offscreen_window (Display *xdisplay,
- Window parent,
- long valuemask);
-
-typedef struct MetaWorkspaceLayout MetaWorkspaceLayout;
-
-struct MetaWorkspaceLayout
-{
- int rows;
- int cols;
- int *grid;
- int grid_area;
- int current_row;
- int current_col;
-};
-
-void meta_screen_calc_workspace_layout (MetaScreen *screen,
- int num_workspaces,
- int current_space,
- MetaWorkspaceLayout *layout);
-void meta_screen_free_workspace_layout (MetaWorkspaceLayout *layout);
-
-void meta_screen_resize (MetaScreen *screen,
- int width,
- int height);
-
-void meta_screen_minimize_all_on_active_workspace_except (MetaScreen *screen,
- MetaWindow *keep);
-
-/* Show/hide the desktop (temporarily hide all windows) */
-void meta_screen_show_desktop (MetaScreen *screen,
- guint32 timestamp);
-void meta_screen_unshow_desktop (MetaScreen *screen);
-
-/* Update whether the destkop is being shown for the current active_workspace */
-void meta_screen_update_showing_desktop_hint (MetaScreen *screen);
-
-gboolean meta_screen_apply_startup_properties (MetaScreen *screen,
- MetaWindow *window);
-void meta_screen_composite_all_windows (MetaScreen *screen);
-
-#endif
diff --git a/src/core/screen.c b/src/core/screen.c
deleted file mode 100644
index e82dd932..00000000
--- a/src/core/screen.c
+++ /dev/null
@@ -1,2802 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity X screen handler */
-
-/*
- * Copyright (C) 2001, 2002 Havoc Pennington
- * Copyright (C) 2002, 2003 Red Hat Inc.
- * Some ICCCM manager selection code derived from fvwm2,
- * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team
- * Copyright (C) 2003 Rob Adams
- * Copyright (C) 2004-2006 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include "screen-private.h"
-#include "util.h"
-#include "errors.h"
-#include "window-private.h"
-#include "frame-private.h"
-#include "prefs.h"
-#include "workspace.h"
-#include "keybindings.h"
-#include "stack.h"
-#include "xprops.h"
-#include "compositor.h"
-
-#ifdef HAVE_SOLARIS_XINERAMA
-#include <X11/extensions/xinerama.h>
-#endif
-#ifdef HAVE_XFREE_XINERAMA
-#include <X11/extensions/Xinerama.h>
-#endif
-
-#include <X11/Xatom.h>
-#include <locale.h>
-#include <string.h>
-#include <stdio.h>
-
-static char* get_screen_name (MetaDisplay *display,
- int number);
-
-static void update_num_workspaces (MetaScreen *screen,
- guint32 timestamp);
-static void update_focus_mode (MetaScreen *screen);
-static void set_workspace_names (MetaScreen *screen);
-static void prefs_changed_callback (MetaPreference pref,
- gpointer data);
-
-static void set_desktop_geometry_hint (MetaScreen *screen);
-static void set_desktop_viewport_hint (MetaScreen *screen);
-
-#ifdef HAVE_STARTUP_NOTIFICATION
-static void meta_screen_sn_event (SnMonitorEvent *event,
- void *user_data);
-#endif
-
-static int
-set_wm_check_hint (MetaScreen *screen)
-{
- unsigned long data[1];
-
- g_return_val_if_fail (screen->display->leader_window != None, 0);
-
- data[0] = screen->display->leader_window;
-
- XChangeProperty (screen->display->xdisplay, screen->xroot,
- screen->display->atom__NET_SUPPORTING_WM_CHECK,
- XA_WINDOW,
- 32, PropModeReplace, (guchar*) data, 1);
-
- return Success;
-}
-
-static int
-set_supported_hint (MetaScreen *screen)
-{
- Atom atoms[] = {
-#define EWMH_ATOMS_ONLY
-#define item(x) screen->display->atom_##x,
-#include "atomnames.h"
-#undef item
-#undef EWMH_ATOMS_ONLY
- };
-
- XChangeProperty (screen->display->xdisplay, screen->xroot,
- screen->display->atom__NET_SUPPORTED,
- XA_ATOM,
- 32, PropModeReplace,
- (guchar*) atoms, G_N_ELEMENTS(atoms));
-
- return Success;
-}
-
-static int
-set_wm_icon_size_hint (MetaScreen *screen)
-{
-#define N_VALS 6
- gulong vals[N_VALS];
-
- /* min width, min height, max w, max h, width inc, height inc */
- vals[0] = META_ICON_WIDTH;
- vals[1] = META_ICON_HEIGHT;
- vals[2] = META_ICON_WIDTH;
- vals[3] = META_ICON_HEIGHT;
- vals[4] = 0;
- vals[5] = 0;
-
- XChangeProperty (screen->display->xdisplay, screen->xroot,
- screen->display->atom_WM_ICON_SIZE,
- XA_CARDINAL,
- 32, PropModeReplace, (guchar*) vals, N_VALS);
-
- return Success;
-#undef N_VALS
-}
-
-static void
-reload_xinerama_infos (MetaScreen *screen)
-{
- MetaDisplay *display;
-
- {
- GList *tmp;
-
- tmp = screen->workspaces;
- while (tmp != NULL)
- {
- MetaWorkspace *space = tmp->data;
-
- meta_workspace_invalidate_work_area (space);
-
- tmp = tmp->next;
- }
- }
-
- display = screen->display;
-
- if (screen->xinerama_infos)
- g_free (screen->xinerama_infos);
-
- screen->xinerama_infos = NULL;
- screen->n_xinerama_infos = 0;
- screen->last_xinerama_index = 0;
-
- screen->display->xinerama_cache_invalidated = TRUE;
-
-#ifdef HAVE_XFREE_XINERAMA
- if (XineramaIsActive (display->xdisplay))
- {
- XineramaScreenInfo *infos;
- int n_infos;
- int i;
-
- n_infos = 0;
- infos = XineramaQueryScreens (display->xdisplay, &n_infos);
-
- meta_topic (META_DEBUG_XINERAMA,
- "Found %d Xinerama screens on display %s\n",
- n_infos, display->name);
-
- if (n_infos > 0)
- {
- screen->xinerama_infos = g_new (MetaXineramaScreenInfo, n_infos);
- screen->n_xinerama_infos = n_infos;
-
- i = 0;
- while (i < n_infos)
- {
- screen->xinerama_infos[i].number = infos[i].screen_number;
- screen->xinerama_infos[i].rect.x = infos[i].x_org;
- screen->xinerama_infos[i].rect.y = infos[i].y_org;
- screen->xinerama_infos[i].rect.width = infos[i].width;
- screen->xinerama_infos[i].rect.height = infos[i].height;
-
- meta_topic (META_DEBUG_XINERAMA,
- "Xinerama %d is %d,%d %d x %d\n",
- screen->xinerama_infos[i].number,
- screen->xinerama_infos[i].rect.x,
- screen->xinerama_infos[i].rect.y,
- screen->xinerama_infos[i].rect.width,
- screen->xinerama_infos[i].rect.height);
-
- ++i;
- }
- }
-
- meta_XFree (infos);
- }
- else
- {
- meta_topic (META_DEBUG_XINERAMA,
- "No XFree86 Xinerama extension or XFree86 Xinerama inactive on display %s\n",
- display->name);
- }
-#else
- meta_topic (META_DEBUG_XINERAMA,
- "Metacity compiled without XFree86 Xinerama support\n");
-#endif /* HAVE_XFREE_XINERAMA */
-
-#ifdef HAVE_SOLARIS_XINERAMA
- /* This code from GDK, Copyright (C) 2002 Sun Microsystems */
- if (screen->n_xinerama_infos == 0 &&
- XineramaGetState (screen->display->xdisplay,
- screen->number))
- {
- XRectangle monitors[MAXFRAMEBUFFERS];
- unsigned char hints[16];
- int result;
- int n_monitors;
- int i;
-
- n_monitors = 0;
- result = XineramaGetInfo (screen->display->xdisplay,
- screen->number,
- monitors, hints,
- &n_monitors);
- /* Yes I know it should be Success but the current implementation
- * returns the num of monitor
- */
- if (result > 0)
- {
- g_assert (n_monitors > 0);
-
- screen->xinerama_infos = g_new (MetaXineramaScreenInfo, n_monitors);
- screen->n_xinerama_infos = n_monitors;
-
- i = 0;
- while (i < n_monitors)
- {
- screen->xinerama_infos[i].number = i;
- screen->xinerama_infos[i].rect.x = monitors[i].x;
- screen->xinerama_infos[i].rect.y = monitors[i].y;
- screen->xinerama_infos[i].rect.width = monitors[i].width;
- screen->xinerama_infos[i].rect.height = monitors[i].height;
-
- meta_topic (META_DEBUG_XINERAMA,
- "Xinerama %d is %d,%d %d x %d\n",
- screen->xinerama_infos[i].number,
- screen->xinerama_infos[i].rect.x,
- screen->xinerama_infos[i].rect.y,
- screen->xinerama_infos[i].rect.width,
- screen->xinerama_infos[i].rect.height);
-
- ++i;
- }
- }
- }
- else if (screen->n_xinerama_infos == 0)
- {
- meta_topic (META_DEBUG_XINERAMA,
- "No Solaris Xinerama extension or Solaris Xinerama inactive on display %s\n",
- display->name);
- }
-#else
- meta_topic (META_DEBUG_XINERAMA,
- "Metacity compiled without Solaris Xinerama support\n");
-#endif /* HAVE_SOLARIS_XINERAMA */
-
-
- /* If no Xinerama, fill in the single screen info so
- * we can use the field unconditionally
- */
- if (screen->n_xinerama_infos == 0)
- {
- if (g_getenv ("METACITY_DEBUG_XINERAMA"))
- {
- meta_topic (META_DEBUG_XINERAMA,
- "Pretending a single monitor has two Xinerama screens\n");
-
- screen->xinerama_infos = g_new (MetaXineramaScreenInfo, 2);
- screen->n_xinerama_infos = 2;
-
- screen->xinerama_infos[0].number = 0;
- screen->xinerama_infos[0].rect = screen->rect;
- screen->xinerama_infos[0].rect.width = screen->rect.width / 2;
-
- screen->xinerama_infos[1].number = 1;
- screen->xinerama_infos[1].rect = screen->rect;
- screen->xinerama_infos[1].rect.x = screen->rect.width / 2;
- screen->xinerama_infos[1].rect.width = screen->rect.width / 2;
- }
- else
- {
- meta_topic (META_DEBUG_XINERAMA,
- "No Xinerama screens, using default screen info\n");
-
- screen->xinerama_infos = g_new (MetaXineramaScreenInfo, 1);
- screen->n_xinerama_infos = 1;
-
- screen->xinerama_infos[0].number = 0;
- screen->xinerama_infos[0].rect = screen->rect;
- }
- }
-
- g_assert (screen->n_xinerama_infos > 0);
- g_assert (screen->xinerama_infos != NULL);
-}
-
-MetaScreen*
-meta_screen_new (MetaDisplay *display,
- int number,
- guint32 timestamp)
-{
- MetaScreen *screen;
- Window xroot;
- Display *xdisplay;
- XWindowAttributes attr;
- Window new_wm_sn_owner;
- Window current_wm_sn_owner;
- gboolean replace_current_wm;
- Atom wm_sn_atom;
- char buf[128];
- guint32 manager_timestamp;
- gulong current_workspace;
-
- replace_current_wm = meta_get_replace_current_wm ();
-
- /* Only display->name, display->xdisplay, and display->error_traps
- * can really be used in this function, since normally screens are
- * created from the MetaDisplay constructor
- */
-
- xdisplay = display->xdisplay;
-
- meta_verbose ("Trying screen %d on display '%s'\n",
- number, display->name);
-
- xroot = RootWindow (xdisplay, number);
-
- /* FVWM checks for None here, I don't know if this
- * ever actually happens
- */
- if (xroot == None)
- {
- meta_warning (_("Screen %d on display '%s' is invalid\n"),
- number, display->name);
- return NULL;
- }
-
- sprintf (buf, "WM_S%d", number);
- wm_sn_atom = XInternAtom (xdisplay, buf, False);
-
- current_wm_sn_owner = XGetSelectionOwner (xdisplay, wm_sn_atom);
-
- if (current_wm_sn_owner != None)
- {
- XSetWindowAttributes attrs;
-
- if (!replace_current_wm)
- {
- meta_warning (_("Screen %d on display \"%s\" already has a window manager; try using the --replace option to replace the current window manager.\n"),
- number, display->name);
-
- return NULL;
- }
-
- /* We want to find out when the current selection owner dies */
- meta_error_trap_push_with_return (display);
- attrs.event_mask = StructureNotifyMask;
- XChangeWindowAttributes (xdisplay,
- current_wm_sn_owner, CWEventMask, &attrs);
- if (meta_error_trap_pop_with_return (display, FALSE) != Success)
- current_wm_sn_owner = None; /* don't wait for it to die later on */
- }
-
- /* We need SelectionClear and SelectionRequest events on the new_wm_sn_owner,
- * but those cannot be masked, so we only need NoEventMask.
- */
- new_wm_sn_owner = meta_create_offscreen_window (xdisplay, xroot, NoEventMask);
-
- manager_timestamp = timestamp;
-
- XSetSelectionOwner (xdisplay, wm_sn_atom, new_wm_sn_owner,
- manager_timestamp);
-
- if (XGetSelectionOwner (xdisplay, wm_sn_atom) != new_wm_sn_owner)
- {
- meta_warning (_("Could not acquire window manager selection on screen %d display \"%s\"\n"),
- number, display->name);
-
- XDestroyWindow (xdisplay, new_wm_sn_owner);
-
- return NULL;
- }
-
- {
- /* Send client message indicating that we are now the WM */
- XClientMessageEvent ev;
-
- ev.type = ClientMessage;
- ev.window = xroot;
- ev.message_type = display->atom_MANAGER;
- ev.format = 32;
- ev.data.l[0] = manager_timestamp;
- ev.data.l[1] = wm_sn_atom;
-
- XSendEvent (xdisplay, xroot, False, StructureNotifyMask, (XEvent*)&ev);
- }
-
- /* Wait for old window manager to go away */
- if (current_wm_sn_owner != None)
- {
- XEvent event;
-
- /* We sort of block infinitely here which is probably lame. */
-
- meta_verbose ("Waiting for old window manager to exit\n");
- do
- {
- XWindowEvent (xdisplay, current_wm_sn_owner,
- StructureNotifyMask, &event);
- }
- while (event.type != DestroyNotify);
- }
-
- /* select our root window events */
- meta_error_trap_push_with_return (display);
-
- /* We need to or with the existing event mask since
- * gtk+ may be interested in other events.
- */
- XGetWindowAttributes (xdisplay, xroot, &attr);
- XSelectInput (xdisplay,
- xroot,
- SubstructureRedirectMask | SubstructureNotifyMask |
- ColormapChangeMask | PropertyChangeMask |
- LeaveWindowMask | EnterWindowMask |
- KeyPressMask | KeyReleaseMask |
- FocusChangeMask | StructureNotifyMask |
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- ExposureMask |
-#endif
- attr.your_event_mask);
- if (meta_error_trap_pop_with_return (display, FALSE) != Success)
- {
- meta_warning (_("Screen %d on display \"%s\" already has a window manager\n"),
- number, display->name);
-
- XDestroyWindow (xdisplay, new_wm_sn_owner);
-
- return NULL;
- }
-
- screen = g_new (MetaScreen, 1);
- screen->closing = 0;
-
- screen->display = display;
- screen->number = number;
- screen->screen_name = get_screen_name (display, number);
- screen->xscreen = ScreenOfDisplay (xdisplay, number);
- screen->xroot = xroot;
- screen->rect.x = screen->rect.y = 0;
- screen->rect.width = WidthOfScreen (screen->xscreen);
- screen->rect.height = HeightOfScreen (screen->xscreen);
- screen->current_cursor = -1; /* invalid/unset */
- screen->default_xvisual = DefaultVisualOfScreen (screen->xscreen);
- screen->default_depth = DefaultDepthOfScreen (screen->xscreen);
- screen->flash_window = None;
-
- screen->wm_sn_selection_window = new_wm_sn_owner;
- screen->wm_sn_atom = wm_sn_atom;
- screen->wm_sn_timestamp = manager_timestamp;
-
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- screen->wm_cm_selection_window = meta_create_offscreen_window (xdisplay,
- xroot,
- NoEventMask);
-#endif
- screen->work_area_idle = 0;
-
- screen->active_workspace = NULL;
- screen->workspaces = NULL;
- screen->rows_of_workspaces = 1;
- screen->columns_of_workspaces = -1;
- screen->vertical_workspaces = FALSE;
- screen->starting_corner = META_SCREEN_TOPLEFT;
- screen->compositor_data = NULL;
-
- {
- XFontStruct *font_info;
- XGCValues gc_values;
- gulong value_mask = 0;
-
- gc_values.subwindow_mode = IncludeInferiors;
- value_mask |= GCSubwindowMode;
- gc_values.function = GXinvert;
- value_mask |= GCFunction;
- gc_values.line_width = META_WIREFRAME_XOR_LINE_WIDTH;
- value_mask |= GCLineWidth;
-
- font_info = XLoadQueryFont (screen->display->xdisplay, "fixed");
-
- if (font_info != NULL)
- {
- gc_values.font = font_info->fid;
- value_mask |= GCFont;
- XFreeFontInfo (NULL, font_info, 1);
- }
- else
- meta_warning ("xserver doesn't have 'fixed' font.\n");
-
- screen->root_xor_gc = XCreateGC (screen->display->xdisplay,
- screen->xroot,
- value_mask,
- &gc_values);
- }
-
- screen->xinerama_infos = NULL;
- screen->n_xinerama_infos = 0;
- screen->last_xinerama_index = 0;
-
- reload_xinerama_infos (screen);
-
- meta_screen_set_cursor (screen, META_CURSOR_DEFAULT);
-
- /* Handle creating a no_focus_window for this screen */
- screen->no_focus_window =
- meta_create_offscreen_window (display->xdisplay,
- screen->xroot,
- FocusChangeMask|KeyPressMask|KeyReleaseMask);
- XMapWindow (display->xdisplay, screen->no_focus_window);
- /* Done with no_focus_window stuff */
-
- set_wm_icon_size_hint (screen);
-
- set_supported_hint (screen);
-
- set_wm_check_hint (screen);
-
- set_desktop_viewport_hint (screen);
-
- set_desktop_geometry_hint (screen);
-
- meta_screen_update_workspace_layout (screen);
-
- /* Get current workspace */
- current_workspace = 0;
- if (meta_prop_get_cardinal (screen->display,
- screen->xroot,
- screen->display->atom__NET_CURRENT_DESKTOP,
- &current_workspace))
- meta_verbose ("Read existing _NET_CURRENT_DESKTOP = %d\n",
- (int) current_workspace);
- else
- meta_verbose ("No _NET_CURRENT_DESKTOP present\n");
-
- /* Screens must have at least one workspace at all times,
- * so create that required workspace.
- */
- meta_workspace_activate (meta_workspace_new (screen), timestamp);
- update_num_workspaces (screen, timestamp);
-
- set_workspace_names (screen);
-
- screen->all_keys_grabbed = FALSE;
- screen->keys_grabbed = FALSE;
- meta_screen_grab_keys (screen);
-
- screen->ui = meta_ui_new (screen->display->xdisplay,
- screen->xscreen);
-
- screen->tab_popup = NULL;
-
- screen->stack = meta_stack_new (screen);
-
- meta_prefs_add_listener (prefs_changed_callback, screen);
-
-#ifdef HAVE_STARTUP_NOTIFICATION
- screen->sn_context =
- sn_monitor_context_new (screen->display->sn_display,
- screen->number,
- meta_screen_sn_event,
- screen,
- NULL);
- screen->startup_sequences = NULL;
- screen->startup_sequence_timeout = 0;
-#endif
-
- /* Switch to the _NET_CURRENT_DESKTOP workspace */
- {
- MetaWorkspace *space;
-
- space = meta_screen_get_workspace_by_index (screen,
- current_workspace);
-
- if (space != NULL)
- meta_workspace_activate (space, timestamp);
- }
-
- meta_verbose ("Added screen %d ('%s') root 0x%lx\n",
- screen->number, screen->screen_name, screen->xroot);
-
- return screen;
-}
-
-void
-meta_screen_free (MetaScreen *screen,
- guint32 timestamp)
-{
- MetaDisplay *display;
- XGCValues gc_values = { 0 };
-
- display = screen->display;
-
- screen->closing += 1;
-
- meta_display_grab (display);
-
- if (screen->display->compositor)
- {
- meta_compositor_unmanage_screen (screen->display->compositor,
- screen);
- }
-
- meta_display_unmanage_windows_for_screen (display, screen, timestamp);
-
- meta_prefs_remove_listener (prefs_changed_callback, screen);
-
- meta_screen_ungrab_keys (screen);
-
-#ifdef HAVE_STARTUP_NOTIFICATION
- g_slist_foreach (screen->startup_sequences,
- (GFunc) sn_startup_sequence_unref, NULL);
- g_slist_free (screen->startup_sequences);
- screen->startup_sequences = NULL;
-
- if (screen->startup_sequence_timeout != 0)
- {
- g_source_remove (screen->startup_sequence_timeout);
- screen->startup_sequence_timeout = 0;
- }
- if (screen->sn_context)
- {
- sn_monitor_context_unref (screen->sn_context);
- screen->sn_context = NULL;
- }
-#endif
-
- meta_ui_free (screen->ui);
-
- meta_stack_free (screen->stack);
-
- meta_error_trap_push_with_return (screen->display);
- XSelectInput (screen->display->xdisplay, screen->xroot, 0);
- if (meta_error_trap_pop_with_return (screen->display, FALSE) != Success)
- meta_warning (_("Could not release screen %d on display \"%s\"\n"),
- screen->number, screen->display->name);
-
- XDestroyWindow (screen->display->xdisplay,
- screen->wm_sn_selection_window);
-
- if (screen->work_area_idle != 0)
- g_source_remove (screen->work_area_idle);
-
-
- if (XGetGCValues (screen->display->xdisplay,
- screen->root_xor_gc,
- GCFont,
- &gc_values))
- {
- XUnloadFont (screen->display->xdisplay,
- gc_values.font);
- }
-
- XFreeGC (screen->display->xdisplay,
- screen->root_xor_gc);
-
- if (screen->xinerama_infos)
- g_free (screen->xinerama_infos);
-
- g_free (screen->screen_name);
- g_free (screen);
-
- XFlush (display->xdisplay);
- meta_display_ungrab (display);
-}
-
-typedef struct
-{
- Window xwindow;
- XWindowAttributes attrs;
-} WindowInfo;
-
-static GList *
-list_windows (MetaScreen *screen)
-{
- Window ignored1, ignored2;
- Window *children;
- guint n_children, i;
- GList *result;
-
- XQueryTree (screen->display->xdisplay,
- screen->xroot,
- &ignored1, &ignored2, &children, &n_children);
-
- result = NULL;
- for (i = 0; i < n_children; ++i)
- {
- WindowInfo *info = g_new0 (WindowInfo, 1);
-
- meta_error_trap_push_with_return (screen->display);
-
- XGetWindowAttributes (screen->display->xdisplay,
- children[i], &info->attrs);
-
- if (meta_error_trap_pop_with_return (screen->display, TRUE))
- {
- meta_verbose ("Failed to get attributes for window 0x%lx\n",
- children[i]);
- g_free (info);
- }
- else
- {
- info->xwindow = children[i];
- }
-
- result = g_list_prepend (result, info);
- }
-
- if (children)
- XFree (children);
-
- return g_list_reverse (result);
-}
-
-void
-meta_screen_manage_all_windows (MetaScreen *screen)
-{
- GList *windows;
- GList *list;
-
- meta_display_grab (screen->display);
-
- windows = list_windows (screen);
-
- meta_stack_freeze (screen->stack);
- for (list = windows; list != NULL; list = list->next)
- {
- WindowInfo *info = list->data;
- MetaWindow *window;
-
- window = meta_window_new_with_attrs (screen->display, info->xwindow, TRUE,
- &info->attrs);
- if (info->xwindow == screen->no_focus_window ||
- info->xwindow == screen->flash_window ||
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- info->xwindow == screen->wm_cm_selection_window ||
-#endif
- info->xwindow == screen->wm_sn_selection_window) {
- meta_verbose ("Not managing our own windows\n");
- continue;
- }
-
- if (screen->display->compositor)
- meta_compositor_add_window (screen->display->compositor, window,
- info->xwindow, &info->attrs);
- }
- meta_stack_thaw (screen->stack);
-
- g_list_foreach (windows, (GFunc)g_free, NULL);
- g_list_free (windows);
-
- meta_display_ungrab (screen->display);
-}
-
-void
-meta_screen_composite_all_windows (MetaScreen *screen)
-{
-#ifdef HAVE_COMPOSITE_EXTENSIONS
- MetaDisplay *display;
- GList *windows, *list;
-
- display = screen->display;
- if (!display->compositor)
- return;
-
- windows = list_windows (screen);
-
- meta_stack_freeze (screen->stack);
-
- for (list = windows; list != NULL; list = list->next)
- {
- WindowInfo *info = list->data;
-
- if (info->xwindow == screen->no_focus_window ||
- info->xwindow == screen->flash_window ||
- info->xwindow == screen->wm_sn_selection_window ||
- info->xwindow == screen->wm_cm_selection_window) {
- meta_verbose ("Not managing our own windows\n");
- continue;
- }
-
- meta_compositor_add_window (display->compositor,
- meta_display_lookup_x_window (display,
- info->xwindow),
- info->xwindow, &info->attrs);
- }
-
- meta_stack_thaw (screen->stack);
-
- g_list_foreach (windows, (GFunc)g_free, NULL);
- g_list_free (windows);
-#endif
-}
-
-MetaScreen*
-meta_screen_for_x_screen (Screen *xscreen)
-{
- MetaDisplay *display;
-
- display = meta_display_for_x_display (DisplayOfScreen (xscreen));
-
- if (display == NULL)
- return NULL;
-
- return meta_display_screen_for_x_screen (display, xscreen);
-}
-
-static void
-prefs_changed_callback (MetaPreference pref,
- gpointer data)
-{
- MetaScreen *screen = data;
-
- if (pref == META_PREF_NUM_WORKSPACES)
- {
- /* GConf doesn't provide timestamps, but luckily update_num_workspaces
- * often doesn't need it...
- */
- guint32 timestamp =
- meta_display_get_current_time_roundtrip (screen->display);
- update_num_workspaces (screen, timestamp);
- }
- else if (pref == META_PREF_FOCUS_MODE)
- {
- update_focus_mode (screen);
- }
- else if (pref == META_PREF_WORKSPACE_NAMES)
- {
- set_workspace_names (screen);
- }
-}
-
-
-static char*
-get_screen_name (MetaDisplay *display,
- int number)
-{
- char *p;
- char *dname;
- char *scr;
-
- /* DisplayString gives us a sort of canonical display,
- * vs. the user-entered name from XDisplayName()
- */
- dname = g_strdup (DisplayString (display->xdisplay));
-
- /* Change display name to specify this screen.
- */
- p = strrchr (dname, ':');
- if (p)
- {
- p = strchr (p, '.');
- if (p)
- *p = '\0';
- }
-
- scr = g_strdup_printf ("%s.%d", dname, number);
-
- g_free (dname);
-
- return scr;
-}
-
-static gint
-ptrcmp (gconstpointer a, gconstpointer b)
-{
- if (a < b)
- return -1;
- else if (a > b)
- return 1;
- else
- return 0;
-}
-
-static void
-listify_func (gpointer key, gpointer value, gpointer data)
-{
- GSList **listp;
-
- listp = data;
-
- *listp = g_slist_prepend (*listp, value);
-}
-
-void
-meta_screen_foreach_window (MetaScreen *screen,
- MetaScreenWindowFunc func,
- gpointer data)
-{
- GSList *winlist;
- GSList *tmp;
-
- /* If we end up doing this often, just keeping a list
- * of windows might be sensible.
- */
-
- winlist = NULL;
- g_hash_table_foreach (screen->display->window_ids,
- listify_func,
- &winlist);
-
- winlist = g_slist_sort (winlist, ptrcmp);
-
- tmp = winlist;
- while (tmp != NULL)
- {
- /* If the next node doesn't contain this window
- * a second time, delete the window.
- */
- if (tmp->next == NULL ||
- (tmp->next && tmp->next->data != tmp->data))
- {
- MetaWindow *window = tmp->data;
-
- if (window->screen == screen)
- (* func) (screen, window, data);
- }
-
- tmp = tmp->next;
- }
- g_slist_free (winlist);
-}
-
-static void
-queue_draw (MetaScreen *screen, MetaWindow *window, gpointer data)
-{
- if (window->frame)
- meta_frame_queue_draw (window->frame);
-}
-
-void
-meta_screen_queue_frame_redraws (MetaScreen *screen)
-{
- meta_screen_foreach_window (screen, queue_draw, NULL);
-}
-
-static void
-queue_resize (MetaScreen *screen, MetaWindow *window, gpointer data)
-{
- meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
-}
-
-void
-meta_screen_queue_window_resizes (MetaScreen *screen)
-{
- meta_screen_foreach_window (screen, queue_resize, NULL);
-}
-
-int
-meta_screen_get_n_workspaces (MetaScreen *screen)
-{
- return g_list_length (screen->workspaces);
-}
-
-MetaWorkspace*
-meta_screen_get_workspace_by_index (MetaScreen *screen,
- int idx)
-{
- GList *tmp;
- int i;
-
- /* should be robust, idx is maybe from an app */
- if (idx < 0)
- return NULL;
-
- i = 0;
- tmp = screen->workspaces;
- while (tmp != NULL)
- {
- MetaWorkspace *w = tmp->data;
-
- if (i == idx)
- return w;
-
- ++i;
- tmp = tmp->next;
- }
-
- return NULL;
-}
-
-static void
-set_number_of_spaces_hint (MetaScreen *screen,
- int n_spaces)
-{
- unsigned long data[1];
-
- if (screen->closing > 0)
- return;
-
- data[0] = n_spaces;
-
- meta_verbose ("Setting _NET_NUMBER_OF_DESKTOPS to %lu\n", data[0]);
-
- meta_error_trap_push (screen->display);
- XChangeProperty (screen->display->xdisplay, screen->xroot,
- screen->display->atom__NET_NUMBER_OF_DESKTOPS,
- XA_CARDINAL,
- 32, PropModeReplace, (guchar*) data, 1);
- meta_error_trap_pop (screen->display, FALSE);
-}
-
-static void
-set_desktop_geometry_hint (MetaScreen *screen)
-{
- unsigned long data[2];
-
- if (screen->closing > 0)
- return;
-
- data[0] = screen->rect.width;
- data[1] = screen->rect.height;
-
- meta_verbose ("Setting _NET_DESKTOP_GEOMETRY to %lu, %lu\n", data[0], data[1]);
-
- meta_error_trap_push (screen->display);
- XChangeProperty (screen->display->xdisplay, screen->xroot,
- screen->display->atom__NET_DESKTOP_GEOMETRY,
- XA_CARDINAL,
- 32, PropModeReplace, (guchar*) data, 2);
- meta_error_trap_pop (screen->display, FALSE);
-}
-
-static void
-set_desktop_viewport_hint (MetaScreen *screen)
-{
- unsigned long data[2];
-
- if (screen->closing > 0)
- return;
-
- /*
- * Metacity does not implement viewports, so this is a fixed 0,0
- */
- data[0] = 0;
- data[1] = 0;
-
- meta_verbose ("Setting _NET_DESKTOP_VIEWPORT to 0, 0\n");
-
- meta_error_trap_push (screen->display);
- XChangeProperty (screen->display->xdisplay, screen->xroot,
- screen->display->atom__NET_DESKTOP_VIEWPORT,
- XA_CARDINAL,
- 32, PropModeReplace, (guchar*) data, 2);
- meta_error_trap_pop (screen->display, FALSE);
-}
-
-static void
-update_num_workspaces (MetaScreen *screen,
- guint32 timestamp)
-{
- int new_num;
- GList *tmp;
- int i;
- GList *extras;
- MetaWorkspace *last_remaining;
- gboolean need_change_space;
-
- new_num = meta_prefs_get_num_workspaces ();
-
- g_assert (new_num > 0);
-
- last_remaining = NULL;
- extras = NULL;
- i = 0;
- tmp = screen->workspaces;
- while (tmp != NULL)
- {
- MetaWorkspace *w = tmp->data;
-
- if (i >= new_num)
- extras = g_list_prepend (extras, w);
- else
- last_remaining = w;
-
- ++i;
- tmp = tmp->next;
- }
-
- g_assert (last_remaining);
-
- /* Get rid of the extra workspaces by moving all their windows
- * to last_remaining, then activating last_remaining if
- * one of the removed workspaces was active. This will be a bit
- * wacky if the config tool for changing number of workspaces
- * is on a removed workspace ;-)
- */
- need_change_space = FALSE;
- tmp = extras;
- while (tmp != NULL)
- {
- MetaWorkspace *w = tmp->data;
-
- meta_workspace_relocate_windows (w, last_remaining);
-
- if (w == screen->active_workspace)
- need_change_space = TRUE;
-
- tmp = tmp->next;
- }
-
- if (need_change_space)
- meta_workspace_activate (last_remaining, timestamp);
-
- /* Should now be safe to free the workspaces */
- tmp = extras;
- while (tmp != NULL)
- {
- MetaWorkspace *w = tmp->data;
-
- g_assert (w->windows == NULL);
- meta_workspace_free (w);
-
- tmp = tmp->next;
- }
-
- g_list_free (extras);
-
- while (i < new_num)
- {
- meta_workspace_new (screen);
- ++i;
- }
-
- set_number_of_spaces_hint (screen, new_num);
-
- meta_screen_queue_workarea_recalc (screen);
-}
-
-static void
-update_focus_mode (MetaScreen *screen)
-{
- /* nothing to do anymore */ ;
-}
-
-void
-meta_screen_set_cursor (MetaScreen *screen,
- MetaCursor cursor)
-{
- Cursor xcursor;
-
- if (cursor == screen->current_cursor)
- return;
-
- screen->current_cursor = cursor;
-
- xcursor = meta_display_create_x_cursor (screen->display, cursor);
- XDefineCursor (screen->display->xdisplay, screen->xroot, xcursor);
- XFlush (screen->display->xdisplay);
- XFreeCursor (screen->display->xdisplay, xcursor);
-}
-
-void
-meta_screen_update_cursor (MetaScreen *screen)
-{
- Cursor xcursor;
-
- xcursor = meta_display_create_x_cursor (screen->display,
- screen->current_cursor);
- XDefineCursor (screen->display->xdisplay, screen->xroot, xcursor);
- XFlush (screen->display->xdisplay);
- XFreeCursor (screen->display->xdisplay, xcursor);
-}
-
-#define MAX_PREVIEW_SIZE 150.0
-
-static GdkPixbuf *
-get_window_pixbuf (MetaWindow *window,
- int *width,
- int *height)
-{
- Pixmap pmap;
- GdkPixbuf *pixbuf, *scaled;
- double ratio;
-
- pmap = meta_compositor_get_window_pixmap (window->display->compositor,
- window);
- if (pmap == None)
- return NULL;
-
- pixbuf = meta_ui_get_pixbuf_from_pixmap (pmap);
- if (pixbuf == NULL)
- return NULL;
-
- *width = gdk_pixbuf_get_width (pixbuf);
- *height = gdk_pixbuf_get_height (pixbuf);
-
- /* Scale pixbuf to max dimension MAX_PREVIEW_SIZE */
- if (*width > *height)
- {
- ratio = ((double) *width) / MAX_PREVIEW_SIZE;
- *width = (int) MAX_PREVIEW_SIZE;
- *height = (int) (((double) *height) / ratio);
- }
- else
- {
- ratio = ((double) *height) / MAX_PREVIEW_SIZE;
- *height = (int) MAX_PREVIEW_SIZE;
- *width = (int) (((double) *width) / ratio);
- }
-
- scaled = gdk_pixbuf_scale_simple (pixbuf, *width, *height,
- GDK_INTERP_BILINEAR);
- g_object_unref (pixbuf);
- return scaled;
-}
-
-void
-meta_screen_ensure_tab_popup (MetaScreen *screen,
- MetaTabList list_type,
- MetaTabShowType show_type)
-{
- MetaTabEntry *entries;
- GList *tab_list;
- GList *tmp;
- int len;
- int i;
-
- if (screen->tab_popup)
- return;
-
- tab_list = meta_display_get_tab_list (screen->display,
- list_type,
- screen,
- screen->active_workspace);
-
- len = g_list_length (tab_list);
-
- entries = g_new (MetaTabEntry, len + 1);
- entries[len].key = NULL;
- entries[len].title = NULL;
- entries[len].icon = NULL;
-
- i = 0;
- tmp = tab_list;
- while (i < len)
- {
- MetaWindow *window;
- MetaRectangle r;
- GdkPixbuf *win_pixbuf;
- int width, height;
-
- window = tmp->data;
-
- entries[i].key = (MetaTabEntryKey) window->xwindow;
- entries[i].title = window->title;
-
- win_pixbuf = get_window_pixbuf (window, &width, &height);
- if (win_pixbuf == NULL)
- entries[i].icon = g_object_ref (window->icon);
- else
- {
- int icon_width, icon_height, t_width, t_height;
-#define ICON_OFFSET 6
-
- icon_width = gdk_pixbuf_get_width (window->icon);
- icon_height = gdk_pixbuf_get_height (window->icon);
-
- t_width = width + ICON_OFFSET;
- t_height = height + ICON_OFFSET;
-
- entries[i].icon = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
- t_width, t_height);
- gdk_pixbuf_fill (entries[i].icon, 0x00000000);
- gdk_pixbuf_copy_area (win_pixbuf, 0, 0, width, height,
- entries[i].icon, 0, 0);
- g_object_unref (win_pixbuf);
- gdk_pixbuf_composite (window->icon, entries[i].icon,
- t_width - icon_width, t_height - icon_height,
- icon_width, icon_height,
- t_width - icon_width, t_height - icon_height,
- 1.0, 1.0, GDK_INTERP_BILINEAR, 255);
- }
-
- entries[i].blank = FALSE;
- entries[i].hidden = !meta_window_showing_on_its_workspace (window);
- entries[i].demands_attention = window->wm_state_demands_attention;
-
- if (show_type == META_TAB_SHOW_INSTANTLY ||
- !entries[i].hidden ||
- !meta_window_get_icon_geometry (window, &r))
- meta_window_get_outer_rect (window, &r);
-
- entries[i].rect = r;
-
- /* Find inside of highlight rectangle to be used when window is
- * outlined for tabbing. This should be the size of the
- * east/west frame, and the size of the south frame, on those
- * sides. On the top it should be the size of the south frame
- * edge.
- */
-#define OUTLINE_WIDTH 5
- /* Top side */
- if (!entries[i].hidden &&
- window->frame && window->frame->bottom_height > 0 &&
- window->frame->child_y >= window->frame->bottom_height)
- entries[i].inner_rect.y = window->frame->bottom_height;
- else
- entries[i].inner_rect.y = OUTLINE_WIDTH;
-
- /* Bottom side */
- if (!entries[i].hidden &&
- window->frame && window->frame->bottom_height != 0)
- entries[i].inner_rect.height = r.height
- - entries[i].inner_rect.y - window->frame->bottom_height;
- else
- entries[i].inner_rect.height = r.height
- - entries[i].inner_rect.y - OUTLINE_WIDTH;
-
- /* Left side */
- if (!entries[i].hidden && window->frame && window->frame->child_x != 0)
- entries[i].inner_rect.x = window->frame->child_x;
- else
- entries[i].inner_rect.x = OUTLINE_WIDTH;
-
- /* Right side */
- if (!entries[i].hidden &&
- window->frame && window->frame->right_width != 0)
- entries[i].inner_rect.width = r.width
- - entries[i].inner_rect.x - window->frame->right_width;
- else
- entries[i].inner_rect.width = r.width
- - entries[i].inner_rect.x - OUTLINE_WIDTH;
-
- ++i;
- tmp = tmp->next;
- }
-
- screen->tab_popup = meta_ui_tab_popup_new (entries,
- screen->number,
- len,
- 5, /* FIXME */
- TRUE);
-
- for (i = 0; i < len; i++)
- g_object_unref (entries[i].icon);
-
- g_free (entries);
-
- g_list_free (tab_list);
-
- /* don't show tab popup, since proper window isn't selected yet */
-}
-
-void
-meta_screen_ensure_workspace_popup (MetaScreen *screen)
-{
- MetaTabEntry *entries;
- int len;
- int i;
- MetaWorkspaceLayout layout;
- int n_workspaces;
- int current_workspace;
-
- if (screen->tab_popup)
- return;
-
- current_workspace = meta_workspace_index (screen->active_workspace);
- n_workspaces = meta_screen_get_n_workspaces (screen);
-
- meta_screen_calc_workspace_layout (screen, n_workspaces,
- current_workspace, &layout);
-
- len = layout.grid_area;
-
- entries = g_new (MetaTabEntry, len + 1);
- entries[len].key = NULL;
- entries[len].title = NULL;
- entries[len].icon = NULL;
-
- i = 0;
- while (i < len)
- {
- if (layout.grid[i] >= 0)
- {
- MetaWorkspace *workspace;
-
- workspace = meta_screen_get_workspace_by_index (screen,
- layout.grid[i]);
-
- entries[i].key = (MetaTabEntryKey) workspace;
- entries[i].title = meta_workspace_get_name (workspace);
- entries[i].icon = NULL;
- entries[i].blank = FALSE;
-
- g_assert (entries[i].title != NULL);
- }
- else
- {
- entries[i].key = NULL;
- entries[i].title = NULL;
- entries[i].icon = NULL;
- entries[i].blank = TRUE;
- }
- entries[i].hidden = FALSE;
- entries[i].demands_attention = FALSE;
-
- ++i;
- }
-
- screen->tab_popup = meta_ui_tab_popup_new (entries,
- screen->number,
- len,
- layout.cols,
- FALSE);
-
- g_free (entries);
- meta_screen_free_workspace_layout (&layout);
-
- /* don't show tab popup, since proper space isn't selected yet */
-}
-
-MetaWindow*
-meta_screen_get_mouse_window (MetaScreen *screen,
- MetaWindow *not_this_one)
-{
- MetaWindow *window;
- Window root_return, child_return;
- int root_x_return, root_y_return;
- int win_x_return, win_y_return;
- unsigned int mask_return;
-
- if (not_this_one)
- meta_topic (META_DEBUG_FOCUS,
- "Focusing mouse window excluding %s\n", not_this_one->desc);
-
- meta_error_trap_push (screen->display);
- XQueryPointer (screen->display->xdisplay,
- screen->xroot,
- &root_return,
- &child_return,
- &root_x_return,
- &root_y_return,
- &win_x_return,
- &win_y_return,
- &mask_return);
- meta_error_trap_pop (screen->display, TRUE);
-
- window = meta_stack_get_default_focus_window_at_point (screen->stack,
- screen->active_workspace,
- not_this_one,
- root_x_return,
- root_y_return);
-
- return window;
-}
-
-const MetaXineramaScreenInfo*
-meta_screen_get_xinerama_for_rect (MetaScreen *screen,
- MetaRectangle *rect)
-{
- int i;
- int best_xinerama, xinerama_score;
-
- if (screen->n_xinerama_infos == 1)
- return &screen->xinerama_infos[0];
-
- best_xinerama = 0;
- xinerama_score = 0;
-
- for (i = 0; i < screen->n_xinerama_infos; i++)
- {
- MetaRectangle dest;
- if (meta_rectangle_intersect (&screen->xinerama_infos[i].rect,
- rect,
- &dest))
- {
- int cur = meta_rectangle_area (&dest);
- if (cur > xinerama_score)
- {
- xinerama_score = cur;
- best_xinerama = i;
- }
- }
- }
-
- return &screen->xinerama_infos[best_xinerama];
-}
-
-const MetaXineramaScreenInfo*
-meta_screen_get_xinerama_for_window (MetaScreen *screen,
- MetaWindow *window)
-{
- MetaRectangle window_rect;
-
- meta_window_get_outer_rect (window, &window_rect);
-
- return meta_screen_get_xinerama_for_rect (screen, &window_rect);
-}
-
-const MetaXineramaScreenInfo*
-meta_screen_get_xinerama_neighbor (MetaScreen *screen,
- int which_xinerama,
- MetaScreenDirection direction)
-{
- MetaXineramaScreenInfo* input = screen->xinerama_infos + which_xinerama;
- MetaXineramaScreenInfo* current;
- int i;
-
- for (i = 0; i < screen->n_xinerama_infos; i++)
- {
- current = screen->xinerama_infos + i;
-
- if ((direction == META_SCREEN_RIGHT &&
- current->rect.x == input->rect.x + input->rect.width &&
- meta_rectangle_vert_overlap(&current->rect, &input->rect)) ||
- (direction == META_SCREEN_LEFT &&
- input->rect.x == current->rect.x + current->rect.width &&
- meta_rectangle_vert_overlap(&current->rect, &input->rect)) ||
- (direction == META_SCREEN_UP &&
- input->rect.y == current->rect.y + current->rect.height &&
- meta_rectangle_horiz_overlap(&current->rect, &input->rect)) ||
- (direction == META_SCREEN_DOWN &&
- current->rect.y == input->rect.y + input->rect.height &&
- meta_rectangle_horiz_overlap(&current->rect, &input->rect)))
- {
- return current;
- }
- }
-
- return NULL;
-}
-
-void
-meta_screen_get_natural_xinerama_list (MetaScreen *screen,
- int** xineramas_list,
- int* n_xineramas)
-{
- const MetaXineramaScreenInfo* current;
- const MetaXineramaScreenInfo* tmp;
- GQueue* xinerama_queue;
- int* visited;
- int cur = 0;
- int i;
-
- *n_xineramas = screen->n_xinerama_infos;
- *xineramas_list = g_new (int, screen->n_xinerama_infos);
-
- /* we calculate a natural ordering by which to choose xineramas for
- * window placement. We start at the current xinerama, and perform
- * a breadth-first search of the xineramas starting from that
- * xinerama. We choose preferentially left, then right, then down,
- * then up. The visitation order produced by this traversal is the
- * natural xinerama ordering.
- */
-
- visited = g_new (int, screen->n_xinerama_infos);
- for (i = 0; i < screen->n_xinerama_infos; i++)
- {
- visited[i] = FALSE;
- }
-
- current = meta_screen_get_current_xinerama (screen);
- xinerama_queue = g_queue_new ();
- g_queue_push_tail (xinerama_queue, (gpointer) current);
- visited[current->number] = TRUE;
-
- while (!g_queue_is_empty (xinerama_queue))
- {
- current = (const MetaXineramaScreenInfo*)
- g_queue_pop_head (xinerama_queue);
-
- (*xineramas_list)[cur++] = current->number;
-
- /* enqueue each of the directions */
- tmp = meta_screen_get_xinerama_neighbor (screen,
- current->number,
- META_SCREEN_LEFT);
- if (tmp && !visited[tmp->number])
- {
- g_queue_push_tail (xinerama_queue,
- (MetaXineramaScreenInfo*) tmp);
- visited[tmp->number] = TRUE;
- }
- tmp = meta_screen_get_xinerama_neighbor (screen,
- current->number,
- META_SCREEN_RIGHT);
- if (tmp && !visited[tmp->number])
- {
- g_queue_push_tail (xinerama_queue,
- (MetaXineramaScreenInfo*) tmp);
- visited[tmp->number] = TRUE;
- }
- tmp = meta_screen_get_xinerama_neighbor (screen,
- current->number,
- META_SCREEN_UP);
- if (tmp && !visited[tmp->number])
- {
- g_queue_push_tail (xinerama_queue,
- (MetaXineramaScreenInfo*) tmp);
- visited[tmp->number] = TRUE;
- }
- tmp = meta_screen_get_xinerama_neighbor (screen,
- current->number,
- META_SCREEN_DOWN);
- if (tmp && !visited[tmp->number])
- {
- g_queue_push_tail (xinerama_queue,
- (MetaXineramaScreenInfo*) tmp);
- visited[tmp->number] = TRUE;
- }
- }
-
- /* in case we somehow missed some set of xineramas, go through the
- * visited list and add in any xineramas that were missed
- */
- for (i = 0; i < screen->n_xinerama_infos; i++)
- {
- if (visited[i] == FALSE)
- {
- (*xineramas_list)[cur++] = i;
- }
- }
-
- g_free (visited);
- g_queue_free (xinerama_queue);
-}
-
-const MetaXineramaScreenInfo*
-meta_screen_get_current_xinerama (MetaScreen *screen)
-{
- if (screen->n_xinerama_infos == 1)
- return &screen->xinerama_infos[0];
-
- /* Sadly, we have to do it this way. Yuck.
- */
-
- if (screen->display->xinerama_cache_invalidated)
- {
- Window root_return, child_return;
- int win_x_return, win_y_return;
- unsigned int mask_return;
- int i;
- MetaRectangle pointer_position;
-
- screen->display->xinerama_cache_invalidated = FALSE;
-
- pointer_position.width = pointer_position.height = 1;
- XQueryPointer (screen->display->xdisplay,
- screen->xroot,
- &root_return,
- &child_return,
- &pointer_position.x,
- &pointer_position.y,
- &win_x_return,
- &win_y_return,
- &mask_return);
-
- screen->last_xinerama_index = 0;
- for (i = 0; i < screen->n_xinerama_infos; i++)
- {
- if (meta_rectangle_contains_rect (&screen->xinerama_infos[i].rect,
- &pointer_position))
- {
- screen->last_xinerama_index = i;
- break;
- }
- }
-
- meta_topic (META_DEBUG_XINERAMA,
- "Rechecked current Xinerama, now %d\n",
- screen->last_xinerama_index);
- }
-
- return &screen->xinerama_infos[screen->last_xinerama_index];
-}
-
-#define _NET_WM_ORIENTATION_HORZ 0
-#define _NET_WM_ORIENTATION_VERT 1
-
-#define _NET_WM_TOPLEFT 0
-#define _NET_WM_TOPRIGHT 1
-#define _NET_WM_BOTTOMRIGHT 2
-#define _NET_WM_BOTTOMLEFT 3
-
-void
-meta_screen_update_workspace_layout (MetaScreen *screen)
-{
- gulong *list;
- int n_items;
-
- list = NULL;
- n_items = 0;
-
- if (meta_prop_get_cardinal_list (screen->display,
- screen->xroot,
- screen->display->atom__NET_DESKTOP_LAYOUT,
- &list, &n_items))
- {
- if (n_items == 3 || n_items == 4)
- {
- int cols, rows;
-
- switch (list[0])
- {
- case _NET_WM_ORIENTATION_HORZ:
- screen->vertical_workspaces = FALSE;
- break;
- case _NET_WM_ORIENTATION_VERT:
- screen->vertical_workspaces = TRUE;
- break;
- default:
- meta_warning ("Someone set a weird orientation in _NET_DESKTOP_LAYOUT\n");
- break;
- }
-
- cols = list[1];
- rows = list[2];
-
- if (rows <= 0 && cols <= 0)
- {
- meta_warning ("Columns = %d rows = %d in _NET_DESKTOP_LAYOUT makes no sense\n", rows, cols);
- }
- else
- {
- if (rows > 0)
- screen->rows_of_workspaces = rows;
- else
- screen->rows_of_workspaces = -1;
-
- if (cols > 0)
- screen->columns_of_workspaces = cols;
- else
- screen->columns_of_workspaces = -1;
- }
-
- if (n_items == 4)
- {
- switch (list[3])
- {
- case _NET_WM_TOPLEFT:
- screen->starting_corner = META_SCREEN_TOPLEFT;
- break;
- case _NET_WM_TOPRIGHT:
- screen->starting_corner = META_SCREEN_TOPRIGHT;
- break;
- case _NET_WM_BOTTOMRIGHT:
- screen->starting_corner = META_SCREEN_BOTTOMRIGHT;
- break;
- case _NET_WM_BOTTOMLEFT:
- screen->starting_corner = META_SCREEN_BOTTOMLEFT;
- break;
- default:
- meta_warning ("Someone set a weird starting corner in _NET_DESKTOP_LAYOUT\n");
- break;
- }
- }
- else
- screen->starting_corner = META_SCREEN_TOPLEFT;
- }
- else
- {
- meta_warning ("Someone set _NET_DESKTOP_LAYOUT to %d integers instead of 4 "
- "(3 is accepted for backwards compat)\n", n_items);
- }
-
- meta_XFree (list);
- }
-
- meta_verbose ("Workspace layout rows = %d cols = %d orientation = %d starting corner = %u\n",
- screen->rows_of_workspaces,
- screen->columns_of_workspaces,
- screen->vertical_workspaces,
- screen->starting_corner);
-}
-
-static void
-set_workspace_names (MetaScreen *screen)
-{
- /* This updates names on root window when the pref changes,
- * note we only get prefs change notify if things have
- * really changed.
- */
- GString *flattened;
- int i;
- int n_spaces;
-
- /* flatten to nul-separated list */
- n_spaces = meta_screen_get_n_workspaces (screen);
- flattened = g_string_new ("");
- i = 0;
- while (i < n_spaces)
- {
- const char *name;
-
- name = meta_prefs_get_workspace_name (i);
-
- if (name)
- g_string_append_len (flattened, name,
- strlen (name) + 1);
- else
- g_string_append_len (flattened, "", 1);
-
- ++i;
- }
-
- meta_error_trap_push (screen->display);
- XChangeProperty (screen->display->xdisplay,
- screen->xroot,
- screen->display->atom__NET_DESKTOP_NAMES,
- screen->display->atom_UTF8_STRING,
- 8, PropModeReplace,
- (unsigned char *)flattened->str, flattened->len);
- meta_error_trap_pop (screen->display, FALSE);
-
- g_string_free (flattened, TRUE);
-}
-
-void
-meta_screen_update_workspace_names (MetaScreen *screen)
-{
- char **names;
- int n_names;
- int i;
-
- /* this updates names in prefs when the root window property changes,
- * iff the new property contents don't match what's already in prefs
- */
-
- names = NULL;
- n_names = 0;
- if (!meta_prop_get_utf8_list (screen->display,
- screen->xroot,
- screen->display->atom__NET_DESKTOP_NAMES,
- &names, &n_names))
- {
- meta_verbose ("Failed to get workspace names from root window %d\n",
- screen->number);
- return;
- }
-
- i = 0;
- while (i < n_names)
- {
- meta_topic (META_DEBUG_PREFS,
- "Setting workspace %d name to \"%s\" due to _NET_DESKTOP_NAMES change\n",
- i, names[i] ? names[i] : "null");
- meta_prefs_change_workspace_name (i, names[i]);
-
- ++i;
- }
-
- g_strfreev (names);
-}
-
-Window
-meta_create_offscreen_window (Display *xdisplay,
- Window parent,
- long valuemask)
-{
- XSetWindowAttributes attrs;
-
- /* we want to be override redirect because sometimes we
- * create a window on a screen we aren't managing.
- * (but on a display we are managing at least one screen for)
- */
- attrs.override_redirect = True;
- attrs.event_mask = valuemask;
-
- return XCreateWindow (xdisplay,
- parent,
- -100, -100, 1, 1,
- 0,
- CopyFromParent,
- CopyFromParent,
- (Visual *)CopyFromParent,
- CWOverrideRedirect | CWEventMask,
- &attrs);
-}
-
-static void
-set_work_area_hint (MetaScreen *screen)
-{
- int num_workspaces;
- GList *tmp_list;
- unsigned long *data, *tmp;
- MetaRectangle area;
-
- num_workspaces = meta_screen_get_n_workspaces (screen);
- data = g_new (unsigned long, num_workspaces * 4);
- tmp_list = screen->workspaces;
- tmp = data;
-
- while (tmp_list != NULL)
- {
- MetaWorkspace *workspace = tmp_list->data;
-
- if (workspace->screen == screen)
- {
- meta_workspace_get_work_area_all_xineramas (workspace, &area);
- tmp[0] = area.x;
- tmp[1] = area.y;
- tmp[2] = area.width;
- tmp[3] = area.height;
-
- tmp += 4;
- }
-
- tmp_list = tmp_list->next;
- }
-
- meta_error_trap_push (screen->display);
- XChangeProperty (screen->display->xdisplay, screen->xroot,
- screen->display->atom__NET_WORKAREA,
- XA_CARDINAL, 32, PropModeReplace,
- (guchar*) data, num_workspaces*4);
- g_free (data);
- meta_error_trap_pop (screen->display, FALSE);
-}
-
-static gboolean
-set_work_area_idle_func (MetaScreen *screen)
-{
- meta_topic (META_DEBUG_WORKAREA,
- "Running work area idle function\n");
-
- screen->work_area_idle = 0;
-
- set_work_area_hint (screen);
-
- return FALSE;
-}
-
-void
-meta_screen_queue_workarea_recalc (MetaScreen *screen)
-{
- /* Recompute work area in an idle */
- if (screen->work_area_idle == 0)
- {
- meta_topic (META_DEBUG_WORKAREA,
- "Adding work area hint idle function\n");
- screen->work_area_idle =
- g_idle_add_full (META_PRIORITY_WORK_AREA_HINT,
- (GSourceFunc) set_work_area_idle_func,
- screen,
- NULL);
- }
-}
-
-
-#ifdef WITH_VERBOSE_MODE
-static char *
-meta_screen_corner_to_string (MetaScreenCorner corner)
-{
- switch (corner)
- {
- case META_SCREEN_TOPLEFT:
- return "TopLeft";
- case META_SCREEN_TOPRIGHT:
- return "TopRight";
- case META_SCREEN_BOTTOMLEFT:
- return "BottomLeft";
- case META_SCREEN_BOTTOMRIGHT:
- return "BottomRight";
- }
-
- return "Unknown";
-}
-#endif /* WITH_VERBOSE_MODE */
-
-void
-meta_screen_calc_workspace_layout (MetaScreen *screen,
- int num_workspaces,
- int current_space,
- MetaWorkspaceLayout *layout)
-{
- int rows, cols;
- int grid_area;
- int *grid;
- int i, r, c;
- int current_row, current_col;
-
- rows = screen->rows_of_workspaces;
- cols = screen->columns_of_workspaces;
- if (rows <= 0 && cols <= 0)
- cols = num_workspaces;
-
- if (rows <= 0)
- rows = num_workspaces / cols + ((num_workspaces % cols) > 0 ? 1 : 0);
- if (cols <= 0)
- cols = num_workspaces / rows + ((num_workspaces % rows) > 0 ? 1 : 0);
-
- /* paranoia */
- if (rows < 1)
- rows = 1;
- if (cols < 1)
- cols = 1;
-
- g_assert (rows != 0 && cols != 0);
-
- grid_area = rows * cols;
-
- meta_verbose ("Getting layout rows = %d cols = %d current = %d "
- "num_spaces = %d vertical = %s corner = %s\n",
- rows, cols, current_space, num_workspaces,
- screen->vertical_workspaces ? "(true)" : "(false)",
- meta_screen_corner_to_string (screen->starting_corner));
-
- /* ok, we want to setup the distances in the workspace array to go
- * in each direction. Remember, there are many ways that a workspace
- * array can be setup.
- * see http://www.freedesktop.org/standards/wm-spec/1.2/html/x109.html
- * and look at the _NET_DESKTOP_LAYOUT section for details.
- * For instance:
- */
- /* starting_corner = META_SCREEN_TOPLEFT
- * vertical_workspaces = 0 vertical_workspaces=1
- * 1234 1357
- * 5678 2468
- *
- * starting_corner = META_SCREEN_TOPRIGHT
- * vertical_workspaces = 0 vertical_workspaces=1
- * 4321 7531
- * 8765 8642
- *
- * starting_corner = META_SCREEN_BOTTOMLEFT
- * vertical_workspaces = 0 vertical_workspaces=1
- * 5678 2468
- * 1234 1357
- *
- * starting_corner = META_SCREEN_BOTTOMRIGHT
- * vertical_workspaces = 0 vertical_workspaces=1
- * 8765 8642
- * 4321 7531
- *
- */
- /* keep in mind that we could have a ragged layout, e.g. the "8"
- * in the above grids could be missing
- */
-
-
- grid = g_new (int, grid_area);
-
- current_row = -1;
- current_col = -1;
- i = 0;
-
- switch (screen->starting_corner)
- {
- case META_SCREEN_TOPLEFT:
- if (screen->vertical_workspaces)
- {
- c = 0;
- while (c < cols)
- {
- r = 0;
- while (r < rows)
- {
- grid[r*cols+c] = i;
- ++i;
- ++r;
- }
- ++c;
- }
- }
- else
- {
- r = 0;
- while (r < rows)
- {
- c = 0;
- while (c < cols)
- {
- grid[r*cols+c] = i;
- ++i;
- ++c;
- }
- ++r;
- }
- }
- break;
- case META_SCREEN_TOPRIGHT:
- if (screen->vertical_workspaces)
- {
- c = cols - 1;
- while (c >= 0)
- {
- r = 0;
- while (r < rows)
- {
- grid[r*cols+c] = i;
- ++i;
- ++r;
- }
- --c;
- }
- }
- else
- {
- r = 0;
- while (r < rows)
- {
- c = cols - 1;
- while (c >= 0)
- {
- grid[r*cols+c] = i;
- ++i;
- --c;
- }
- ++r;
- }
- }
- break;
- case META_SCREEN_BOTTOMLEFT:
- if (screen->vertical_workspaces)
- {
- c = 0;
- while (c < cols)
- {
- r = rows - 1;
- while (r >= 0)
- {
- grid[r*cols+c] = i;
- ++i;
- --r;
- }
- ++c;
- }
- }
- else
- {
- r = rows - 1;
- while (r >= 0)
- {
- c = 0;
- while (c < cols)
- {
- grid[r*cols+c] = i;
- ++i;
- ++c;
- }
- --r;
- }
- }
- break;
- case META_SCREEN_BOTTOMRIGHT:
- if (screen->vertical_workspaces)
- {
- c = cols - 1;
- while (c >= 0)
- {
- r = rows - 1;
- while (r >= 0)
- {
- grid[r*cols+c] = i;
- ++i;
- --r;
- }
- --c;
- }
- }
- else
- {
- r = rows - 1;
- while (r >= 0)
- {
- c = cols - 1;
- while (c >= 0)
- {
- grid[r*cols+c] = i;
- ++i;
- --c;
- }
- --r;
- }
- }
- break;
- }
-
- if (i != grid_area)
- meta_bug ("did not fill in the whole workspace grid in %s (%d filled)\n",
- G_STRFUNC, i);
-
- current_row = 0;
- current_col = 0;
- r = 0;
- while (r < rows)
- {
- c = 0;
- while (c < cols)
- {
- if (grid[r*cols+c] == current_space)
- {
- current_row = r;
- current_col = c;
- }
- else if (grid[r*cols+c] >= num_workspaces)
- {
- /* flag nonexistent spaces with -1 */
- grid[r*cols+c] = -1;
- }
- ++c;
- }
- ++r;
- }
-
- layout->rows = rows;
- layout->cols = cols;
- layout->grid = grid;
- layout->grid_area = grid_area;
- layout->current_row = current_row;
- layout->current_col = current_col;
-
-#ifdef WITH_VERBOSE_MODE
- if (meta_is_verbose ())
- {
- r = 0;
- while (r < layout->rows)
- {
- meta_verbose (" ");
- meta_push_no_msg_prefix ();
- c = 0;
- while (c < layout->cols)
- {
- if (r == layout->current_row &&
- c == layout->current_col)
- meta_verbose ("*%2d ", layout->grid[r*layout->cols+c]);
- else
- meta_verbose ("%3d ", layout->grid[r*layout->cols+c]);
- ++c;
- }
- meta_verbose ("\n");
- meta_pop_no_msg_prefix ();
- ++r;
- }
- }
-#endif /* WITH_VERBOSE_MODE */
-}
-
-void
-meta_screen_free_workspace_layout (MetaWorkspaceLayout *layout)
-{
- g_free (layout->grid);
-}
-
-static void
-meta_screen_resize_func (MetaScreen *screen,
- MetaWindow *window,
- void *user_data)
-{
- if (window->struts)
- {
- meta_window_update_struts (window);
- }
- meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
-
- meta_window_recalc_features (window);
-}
-
-void
-meta_screen_resize (MetaScreen *screen,
- int width,
- int height)
-{
- screen->rect.width = width;
- screen->rect.height = height;
-
- reload_xinerama_infos (screen);
- set_desktop_geometry_hint (screen);
-
- /* Queue a resize on all the windows */
- meta_screen_foreach_window (screen, meta_screen_resize_func, 0);
-}
-
-void
-meta_screen_update_showing_desktop_hint (MetaScreen *screen)
-{
- unsigned long data[1];
-
- data[0] = screen->active_workspace->showing_desktop ? 1 : 0;
-
- meta_error_trap_push (screen->display);
- XChangeProperty (screen->display->xdisplay, screen->xroot,
- screen->display->atom__NET_SHOWING_DESKTOP,
- XA_CARDINAL,
- 32, PropModeReplace, (guchar*) data, 1);
- meta_error_trap_pop (screen->display, FALSE);
-}
-
-static void
-queue_windows_showing (MetaScreen *screen)
-{
- GSList *windows;
- GSList *tmp;
-
- /* Must operate on all windows on display instead of just on the
- * active_workspace's window list, because the active_workspace's
- * window list may not contain the on_all_workspace windows.
- */
- windows = meta_display_list_windows (screen->display);
-
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
-
- if (w->screen == screen)
- meta_window_queue (w, META_QUEUE_CALC_SHOWING);
-
- tmp = tmp->next;
- }
-
- g_slist_free (windows);
-}
-
-void
-meta_screen_minimize_all_on_active_workspace_except (MetaScreen *screen,
- MetaWindow *keep)
-{
- GList *windows;
- GList *tmp;
-
- windows = screen->active_workspace->windows;
-
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
-
- if (w->screen == screen &&
- w->has_minimize_func &&
- w != keep)
- meta_window_minimize (w);
-
- tmp = tmp->next;
- }
-}
-
-void
-meta_screen_show_desktop (MetaScreen *screen,
- guint32 timestamp)
-{
- GList *windows;
-
- if (screen->active_workspace->showing_desktop)
- return;
-
- screen->active_workspace->showing_desktop = TRUE;
-
- queue_windows_showing (screen);
-
- /* Focus the most recently used META_WINDOW_DESKTOP window, if there is one;
- * see bug 159257.
- */
- windows = screen->active_workspace->mru_list;
- while (windows != NULL)
- {
- MetaWindow *w = windows->data;
-
- if (w->screen == screen &&
- w->type == META_WINDOW_DESKTOP)
- {
- meta_window_focus (w, timestamp);
- break;
- }
-
- windows = windows->next;
- }
-
-
- meta_screen_update_showing_desktop_hint (screen);
-}
-
-void
-meta_screen_unshow_desktop (MetaScreen *screen)
-{
- if (!screen->active_workspace->showing_desktop)
- return;
-
- screen->active_workspace->showing_desktop = FALSE;
-
- queue_windows_showing (screen);
-
- meta_screen_update_showing_desktop_hint (screen);
-}
-
-
-#ifdef HAVE_STARTUP_NOTIFICATION
-static gboolean startup_sequence_timeout (void *data);
-
-static void
-update_startup_feedback (MetaScreen *screen)
-{
- if (screen->startup_sequences != NULL)
- {
- meta_topic (META_DEBUG_STARTUP,
- "Setting busy cursor\n");
- meta_screen_set_cursor (screen, META_CURSOR_BUSY);
- }
- else
- {
- meta_topic (META_DEBUG_STARTUP,
- "Setting default cursor\n");
- meta_screen_set_cursor (screen, META_CURSOR_DEFAULT);
- }
-}
-
-static void
-add_sequence (MetaScreen *screen,
- SnStartupSequence *sequence)
-{
- meta_topic (META_DEBUG_STARTUP,
- "Adding sequence %s\n",
- sn_startup_sequence_get_id (sequence));
- sn_startup_sequence_ref (sequence);
- screen->startup_sequences = g_slist_prepend (screen->startup_sequences,
- sequence);
-
- /* our timeout just polls every second, instead of bothering
- * to compute exactly when we may next time out
- */
- if (screen->startup_sequence_timeout == 0)
- screen->startup_sequence_timeout = g_timeout_add (1000,
- startup_sequence_timeout,
- screen);
-
- update_startup_feedback (screen);
-}
-
-static void
-remove_sequence (MetaScreen *screen,
- SnStartupSequence *sequence)
-{
- meta_topic (META_DEBUG_STARTUP,
- "Removing sequence %s\n",
- sn_startup_sequence_get_id (sequence));
-
- screen->startup_sequences = g_slist_remove (screen->startup_sequences,
- sequence);
- sn_startup_sequence_unref (sequence);
-
- if (screen->startup_sequences == NULL &&
- screen->startup_sequence_timeout != 0)
- {
- g_source_remove (screen->startup_sequence_timeout);
- screen->startup_sequence_timeout = 0;
- }
-
- update_startup_feedback (screen);
-}
-
-typedef struct
-{
- GSList *list;
- GTimeVal now;
-} CollectTimedOutData;
-
-/* This should be fairly long, as it should never be required unless
- * apps or .desktop files are buggy, and it's confusing if
- * OpenOffice or whatever seems to stop launching - people
- * might decide they need to launch it again.
- */
-#define STARTUP_TIMEOUT 15000
-
-static void
-collect_timed_out_foreach (void *element,
- void *data)
-{
- CollectTimedOutData *ctod = data;
- SnStartupSequence *sequence = element;
- long tv_sec, tv_usec;
- double elapsed;
-
- sn_startup_sequence_get_last_active_time (sequence, &tv_sec, &tv_usec);
-
- elapsed =
- ((((double)ctod->now.tv_sec - tv_sec) * G_USEC_PER_SEC +
- (ctod->now.tv_usec - tv_usec))) / 1000.0;
-
- meta_topic (META_DEBUG_STARTUP,
- "Sequence used %g seconds vs. %g max: %s\n",
- elapsed, (double) STARTUP_TIMEOUT,
- sn_startup_sequence_get_id (sequence));
-
- if (elapsed > STARTUP_TIMEOUT)
- ctod->list = g_slist_prepend (ctod->list, sequence);
-}
-
-static gboolean
-startup_sequence_timeout (void *data)
-{
- MetaScreen *screen = data;
- CollectTimedOutData ctod;
- GSList *tmp;
-
- ctod.list = NULL;
- g_get_current_time (&ctod.now);
- g_slist_foreach (screen->startup_sequences,
- collect_timed_out_foreach,
- &ctod);
-
- tmp = ctod.list;
- while (tmp != NULL)
- {
- SnStartupSequence *sequence = tmp->data;
-
- meta_topic (META_DEBUG_STARTUP,
- "Timed out sequence %s\n",
- sn_startup_sequence_get_id (sequence));
-
- sn_startup_sequence_complete (sequence);
-
- tmp = tmp->next;
- }
-
- g_slist_free (ctod.list);
-
- if (screen->startup_sequences != NULL)
- {
- return TRUE;
- }
- else
- {
- /* remove */
- screen->startup_sequence_timeout = 0;
- return FALSE;
- }
-}
-
-static void
-meta_screen_sn_event (SnMonitorEvent *event,
- void *user_data)
-{
- MetaScreen *screen;
- SnStartupSequence *sequence;
-
- screen = user_data;
-
- sequence = sn_monitor_event_get_startup_sequence (event);
-
- switch (sn_monitor_event_get_type (event))
- {
- case SN_MONITOR_EVENT_INITIATED:
- {
- const char *wmclass;
-
- wmclass = sn_startup_sequence_get_wmclass (sequence);
-
- meta_topic (META_DEBUG_STARTUP,
- "Received startup initiated for %s wmclass %s\n",
- sn_startup_sequence_get_id (sequence),
- wmclass ? wmclass : "(unset)");
- add_sequence (screen, sequence);
- }
- break;
-
- case SN_MONITOR_EVENT_COMPLETED:
- {
- meta_topic (META_DEBUG_STARTUP,
- "Received startup completed for %s\n",
- sn_startup_sequence_get_id (sequence));
- remove_sequence (screen,
- sn_monitor_event_get_startup_sequence (event));
- }
- break;
-
- case SN_MONITOR_EVENT_CHANGED:
- meta_topic (META_DEBUG_STARTUP,
- "Received startup changed for %s\n",
- sn_startup_sequence_get_id (sequence));
- break;
-
- case SN_MONITOR_EVENT_CANCELED:
- meta_topic (META_DEBUG_STARTUP,
- "Received startup canceled for %s\n",
- sn_startup_sequence_get_id (sequence));
- break;
- }
-}
-#endif
-
-/* Sets the initial_timestamp and initial_workspace properties
- * of a window according to information given us by the
- * startup-notification library.
- *
- * Returns TRUE if startup properties have been applied, and
- * FALSE if they have not (for example, if they had already
- * been applied.)
- */
-gboolean
-meta_screen_apply_startup_properties (MetaScreen *screen,
- MetaWindow *window)
-{
-#ifdef HAVE_STARTUP_NOTIFICATION
- const char *startup_id;
- GSList *tmp;
- SnStartupSequence *sequence;
-
- /* Does the window have a startup ID stored? */
- startup_id = meta_window_get_startup_id (window);
-
- meta_topic (META_DEBUG_STARTUP,
- "Applying startup props to %s id \"%s\"\n",
- window->desc,
- startup_id ? startup_id : "(none)");
-
- sequence = NULL;
- if (startup_id == NULL)
- {
- /* No startup ID stored for the window. Let's ask the
- * startup-notification library whether there's anything
- * stored for the resource name or resource class hints.
- */
- tmp = screen->startup_sequences;
- while (tmp != NULL)
- {
- const char *wmclass;
-
- wmclass = sn_startup_sequence_get_wmclass (tmp->data);
-
- if (wmclass != NULL &&
- ((window->res_class &&
- strcmp (wmclass, window->res_class) == 0) ||
- (window->res_name &&
- strcmp (wmclass, window->res_name) == 0)))
- {
- sequence = tmp->data;
-
- g_assert (window->startup_id == NULL);
- window->startup_id = g_strdup (sn_startup_sequence_get_id (sequence));
- startup_id = window->startup_id;
-
- meta_topic (META_DEBUG_STARTUP,
- "Ending legacy sequence %s due to window %s\n",
- sn_startup_sequence_get_id (sequence),
- window->desc);
-
- sn_startup_sequence_complete (sequence);
- break;
- }
-
- tmp = tmp->next;
- }
- }
-
- /* Still no startup ID? Bail. */
- if (startup_id == NULL)
- return FALSE;
-
- /* We might get this far and not know the sequence ID (if the window
- * already had a startup ID stored), so let's look for one if we don't
- * already know it.
- */
- if (sequence == NULL)
- {
- tmp = screen->startup_sequences;
- while (tmp != NULL)
- {
- const char *id;
-
- id = sn_startup_sequence_get_id (tmp->data);
-
- if (strcmp (id, startup_id) == 0)
- {
- sequence = tmp->data;
- break;
- }
-
- tmp = tmp->next;
- }
- }
-
- if (sequence != NULL)
- {
- gboolean changed_something = FALSE;
-
- meta_topic (META_DEBUG_STARTUP,
- "Found startup sequence for window %s ID \"%s\"\n",
- window->desc, startup_id);
-
- if (!window->initial_workspace_set)
- {
- int space = sn_startup_sequence_get_workspace (sequence);
- if (space >= 0)
- {
- meta_topic (META_DEBUG_STARTUP,
- "Setting initial window workspace to %d based on startup info\n",
- space);
-
- window->initial_workspace_set = TRUE;
- window->initial_workspace = space;
- changed_something = TRUE;
- }
- }
-
- if (!window->initial_timestamp_set)
- {
- guint32 timestamp = sn_startup_sequence_get_timestamp (sequence);
- meta_topic (META_DEBUG_STARTUP,
- "Setting initial window timestamp to %u based on startup info\n",
- timestamp);
-
- window->initial_timestamp_set = TRUE;
- window->initial_timestamp = timestamp;
- changed_something = TRUE;
- }
-
- return changed_something;
- }
- else
- {
- meta_topic (META_DEBUG_STARTUP,
- "Did not find startup sequence for window %s ID \"%s\"\n",
- window->desc, startup_id);
- }
-
-#endif /* HAVE_STARTUP_NOTIFICATION */
-
- return FALSE;
-}
-
-int
-meta_screen_get_screen_number (MetaScreen *screen)
-{
- return screen->number;
-}
-
-MetaDisplay *
-meta_screen_get_display (MetaScreen *screen)
-{
- return screen->display;
-}
-
-Window
-meta_screen_get_xroot (MetaScreen *screen)
-{
- return screen->xroot;
-}
-
-void
-meta_screen_get_size (MetaScreen *screen,
- int *width,
- int *height)
-{
- *width = screen->rect.width;
- *height = screen->rect.height;
-}
-
-gpointer
-meta_screen_get_compositor_data (MetaScreen *screen)
-{
- return screen->compositor_data;
-}
-
-void
-meta_screen_set_compositor_data (MetaScreen *screen,
- gpointer compositor)
-{
- screen->compositor_data = compositor;
-}
-
-#ifdef HAVE_COMPOSITE_EXTENSIONS
-void
-meta_screen_set_cm_selection (MetaScreen *screen)
-{
- char selection[32];
- Atom a;
-
- g_snprintf (selection, sizeof(selection), "_NET_WM_CM_S%d", screen->number);
- meta_verbose ("Setting selection: %s\n", selection);
- a = XInternAtom (screen->display->xdisplay, selection, FALSE);
- XSetSelectionOwner (screen->display->xdisplay, a,
- screen->wm_cm_selection_window, CurrentTime);
-}
-
-void
-meta_screen_unset_cm_selection (MetaScreen *screen)
-{
- char selection[32];
- Atom a;
-
- g_snprintf (selection, sizeof(selection), "_NET_WM_CM_S%d", screen->number);
- a = XInternAtom (screen->display->xdisplay, selection, FALSE);
- XSetSelectionOwner (screen->display->xdisplay, a, None, CurrentTime);
-}
-#endif /* HAVE_COMPOSITE_EXTENSIONS */
diff --git a/src/core/session.c b/src/core/session.c
deleted file mode 100644
index fc29e13d..00000000
--- a/src/core/session.c
+++ /dev/null
@@ -1,1900 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity Session Management */
-
-/*
- * Copyright (C) 2001 Havoc Pennington (some code in here from
- * libgnomeui, (C) Tom Tromey, Carsten Schaar)
- * Copyright (C) 2004, 2005 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-
-#include "session.h"
-#include <X11/Xatom.h>
-
-#include <time.h>
-
-#ifndef HAVE_SM
-void
-meta_session_init (const char *client_id,
- const char *save_file)
-{
- meta_topic (META_DEBUG_SM, "Compiled without session management support\n");
-}
-
-void
-meta_session_shutdown (void)
-{
- /* nothing */
-}
-
-const MetaWindowSessionInfo*
-meta_window_lookup_saved_state (MetaWindow *window)
-{
- return NULL;
-}
-
-void
-meta_window_release_saved_state (const MetaWindowSessionInfo *info)
-{
- ;
-}
-#else /* HAVE_SM */
-
-#include <X11/ICE/ICElib.h>
-#include <X11/SM/SMlib.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <glib.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "main.h"
-#include "util.h"
-#include "display-private.h"
-#include "workspace.h"
-
-static void ice_io_error_handler (IceConn connection);
-
-static void new_ice_connection (IceConn connection, IcePointer client_data,
- Bool opening, IcePointer *watch_data);
-
-static void save_state (void);
-static char* load_state (const char *previous_save_file);
-static void regenerate_save_file (void);
-static const char* full_save_file (void);
-static void warn_about_lame_clients_and_finish_interact (gboolean shutdown);
-
-/* This is called when data is available on an ICE connection. */
-static gboolean
-process_ice_messages (GIOChannel *channel,
- GIOCondition condition,
- gpointer client_data)
-{
- IceConn connection = (IceConn) client_data;
- IceProcessMessagesStatus status;
-
- /* This blocks infinitely sometimes. I don't know what
- * to do about it. Checking "condition" just breaks
- * session management.
- */
- status = IceProcessMessages (connection, NULL, NULL);
-
- if (status == IceProcessMessagesIOError)
- {
-#if 0
- IcePointer context = IceGetConnectionContext (connection);
-#endif
-
- /* We were disconnected */
- IceSetShutdownNegotiation (connection, False);
- IceCloseConnection (connection);
-
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* This is called when a new ICE connection is made. It arranges for
- the ICE connection to be handled via the event loop. */
-static void
-new_ice_connection (IceConn connection, IcePointer client_data, Bool opening,
- IcePointer *watch_data)
-{
- guint input_id;
-
- if (opening)
- {
- /* Make sure we don't pass on these file descriptors to any
- * exec'ed children
- */
- GIOChannel *channel;
-
- fcntl (IceConnectionNumber (connection), F_SETFD,
- fcntl (IceConnectionNumber (connection), F_GETFD, 0) | FD_CLOEXEC);
-
- channel = g_io_channel_unix_new (IceConnectionNumber (connection));
-
- input_id = g_io_add_watch (channel,
- G_IO_IN | G_IO_ERR,
- process_ice_messages,
- connection);
-
- g_io_channel_unref (channel);
-
- *watch_data = (IcePointer) GUINT_TO_POINTER (input_id);
- }
- else
- {
- input_id = GPOINTER_TO_UINT ((gpointer) *watch_data);
-
- g_source_remove (input_id);
- }
-}
-
-static IceIOErrorHandler ice_installed_handler;
-
-/* We call any handler installed before (or after) gnome_ice_init but
- avoid calling the default libICE handler which does an exit() */
-static void
-ice_io_error_handler (IceConn connection)
-{
- if (ice_installed_handler)
- (*ice_installed_handler) (connection);
-}
-
-static void
-ice_init (void)
-{
- static gboolean ice_initted = FALSE;
-
- if (! ice_initted)
- {
- IceIOErrorHandler default_handler;
-
- ice_installed_handler = IceSetIOErrorHandler (NULL);
- default_handler = IceSetIOErrorHandler (ice_io_error_handler);
-
- if (ice_installed_handler == default_handler)
- ice_installed_handler = NULL;
-
- IceAddConnectionWatch (new_ice_connection, NULL);
-
- ice_initted = TRUE;
- }
-}
-
-typedef enum
-{
- STATE_DISCONNECTED,
- STATE_IDLE,
- STATE_SAVING_PHASE_1,
- STATE_WAITING_FOR_PHASE_2,
- STATE_SAVING_PHASE_2,
- STATE_WAITING_FOR_INTERACT,
- STATE_DONE_WITH_INTERACT,
- STATE_SKIPPING_GLOBAL_SAVE,
- STATE_FROZEN,
- STATE_REGISTERING
-} ClientState;
-
-static void save_phase_2_callback (SmcConn smc_conn,
- SmPointer client_data);
-static void interact_callback (SmcConn smc_conn,
- SmPointer client_data);
-static void shutdown_cancelled_callback (SmcConn smc_conn,
- SmPointer client_data);
-static void save_complete_callback (SmcConn smc_conn,
- SmPointer client_data);
-static void die_callback (SmcConn smc_conn,
- SmPointer client_data);
-static void save_yourself_callback (SmcConn smc_conn,
- SmPointer client_data,
- int save_style,
- Bool shutdown,
- int interact_style,
- Bool fast);
-static void set_clone_restart_commands (void);
-
-static char *client_id = NULL;
-static gpointer session_connection = NULL;
-static ClientState current_state = STATE_DISCONNECTED;
-static gboolean interaction_allowed = FALSE;
-
-void
-meta_session_init (const char *previous_client_id,
- const char *previous_save_file)
-{
- /* Some code here from twm */
- char buf[256];
- unsigned long mask;
- SmcCallbacks callbacks;
- char *saved_client_id;
-
- meta_topic (META_DEBUG_SM, "Initializing session with save file '%s'\n",
- previous_save_file ? previous_save_file : "(none)");
-
- if (previous_save_file)
- {
- saved_client_id = load_state (previous_save_file);
- previous_client_id = saved_client_id;
- }
- else if (previous_client_id)
- {
- char *save_file = g_strconcat (previous_client_id, ".ms", NULL);
- saved_client_id = load_state (save_file);
- g_free (save_file);
- }
- else
- {
- saved_client_id = NULL;
- }
-
- ice_init ();
-
- mask = SmcSaveYourselfProcMask | SmcDieProcMask |
- SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask;
-
- callbacks.save_yourself.callback = save_yourself_callback;
- callbacks.save_yourself.client_data = NULL;
-
- callbacks.die.callback = die_callback;
- callbacks.die.client_data = NULL;
-
- callbacks.save_complete.callback = save_complete_callback;
- callbacks.save_complete.client_data = NULL;
-
- callbacks.shutdown_cancelled.callback = shutdown_cancelled_callback;
- callbacks.shutdown_cancelled.client_data = NULL;
-
- session_connection =
- SmcOpenConnection (NULL, /* use SESSION_MANAGER env */
- NULL, /* means use existing ICE connection */
- SmProtoMajor,
- SmProtoMinor,
- mask,
- &callbacks,
- (char*) previous_client_id,
- &client_id,
- 255, buf);
-
- if (session_connection == NULL)
- {
- meta_topic (META_DEBUG_SM,
- "Failed to a open connection to a session manager, so window positions will not be saved: %s\n",
- buf);
-
- goto out;
- }
- else
- {
- if (client_id == NULL)
- meta_bug ("Session manager gave us a NULL client ID?");
- meta_topic (META_DEBUG_SM, "Obtained session ID '%s'\n", client_id);
- }
-
- if (previous_client_id && strcmp (previous_client_id, client_id) == 0)
- current_state = STATE_IDLE;
- else
- current_state = STATE_REGISTERING;
-
- {
- SmProp prop1, prop2, prop3, prop4, prop5, prop6, *props[6];
- SmPropValue prop1val, prop2val, prop3val, prop4val, prop5val, prop6val;
- char pid[32];
- char hint = SmRestartImmediately;
- char priority = 20; /* low to run before other apps */
-
- prop1.name = SmProgram;
- prop1.type = SmARRAY8;
- prop1.num_vals = 1;
- prop1.vals = &prop1val;
- prop1val.value = "metacity";
- prop1val.length = strlen ("metacity");
-
- /* twm sets getuid() for this, but the SM spec plainly
- * says pw_name, twm is on crack
- */
- prop2.name = SmUserID;
- prop2.type = SmARRAY8;
- prop2.num_vals = 1;
- prop2.vals = &prop2val;
- prop2val.value = (char*) g_get_user_name ();
- prop2val.length = strlen (prop2val.value);
-
- prop3.name = SmRestartStyleHint;
- prop3.type = SmCARD8;
- prop3.num_vals = 1;
- prop3.vals = &prop3val;
- prop3val.value = &hint;
- prop3val.length = 1;
-
- sprintf (pid, "%d", getpid ());
- prop4.name = SmProcessID;
- prop4.type = SmARRAY8;
- prop4.num_vals = 1;
- prop4.vals = &prop4val;
- prop4val.value = pid;
- prop4val.length = strlen (prop4val.value);
-
- /* Always start in home directory */
- prop5.name = SmCurrentDirectory;
- prop5.type = SmARRAY8;
- prop5.num_vals = 1;
- prop5.vals = &prop5val;
- prop5val.value = (char*) g_get_home_dir ();
- prop5val.length = strlen (prop5val.value);
-
- prop6.name = "_GSM_Priority";
- prop6.type = SmCARD8;
- prop6.num_vals = 1;
- prop6.vals = &prop6val;
- prop6val.value = &priority;
- prop6val.length = 1;
-
- props[0] = &prop1;
- props[1] = &prop2;
- props[2] = &prop3;
- props[3] = &prop4;
- props[4] = &prop5;
- props[5] = &prop6;
-
- SmcSetProperties (session_connection, 6, props);
- }
-
- out:
- g_free (saved_client_id);
-}
-
-void
-meta_session_shutdown (void)
-{
- /* Change our restart mode to IfRunning */
-
- SmProp prop1;
- SmPropValue prop1val;
- SmProp *props[1];
- char hint = SmRestartIfRunning;
-
- if (session_connection == NULL)
- return;
-
- prop1.name = SmRestartStyleHint;
- prop1.type = SmCARD8;
- prop1.num_vals = 1;
- prop1.vals = &prop1val;
- prop1val.value = &hint;
- prop1val.length = 1;
-
- props[0] = &prop1;
-
- SmcSetProperties (session_connection, 1, props);
-}
-
-static void
-disconnect (void)
-{
- SmcCloseConnection (session_connection, 0, NULL);
- session_connection = NULL;
- current_state = STATE_DISCONNECTED;
-}
-
-static void
-save_yourself_possibly_done (gboolean shutdown,
- gboolean successful)
-{
- meta_topic (META_DEBUG_SM,
- "save possibly done shutdown = %d success = %d\n",
- shutdown, successful);
-
- if (current_state == STATE_SAVING_PHASE_1)
- {
- Status status;
-
- status = SmcRequestSaveYourselfPhase2 (session_connection,
- save_phase_2_callback,
- GINT_TO_POINTER (shutdown));
-
- if (status)
- current_state = STATE_WAITING_FOR_PHASE_2;
-
- meta_topic (META_DEBUG_SM,
- "Requested phase 2, status = %d\n", status);
- }
-
- if (current_state == STATE_SAVING_PHASE_2 &&
- interaction_allowed)
- {
- Status status;
-
- status = SmcInteractRequest (session_connection,
- /* ignore this feature of the protocol by always
- * claiming normal
- */
- SmDialogNormal,
- interact_callback,
- GINT_TO_POINTER (shutdown));
-
- if (status)
- current_state = STATE_WAITING_FOR_INTERACT;
-
- meta_topic (META_DEBUG_SM,
- "Requested interact, status = %d\n", status);
- }
-
- if (current_state == STATE_SAVING_PHASE_1 ||
- current_state == STATE_SAVING_PHASE_2 ||
- current_state == STATE_DONE_WITH_INTERACT ||
- current_state == STATE_SKIPPING_GLOBAL_SAVE)
- {
- meta_topic (META_DEBUG_SM, "Sending SaveYourselfDone\n");
-
- SmcSaveYourselfDone (session_connection,
- successful);
-
- if (shutdown)
- current_state = STATE_FROZEN;
- else
- current_state = STATE_IDLE;
- }
-}
-
-static void
-save_phase_2_callback (SmcConn smc_conn, SmPointer client_data)
-{
- gboolean shutdown;
-
- meta_topic (META_DEBUG_SM, "Phase 2 save");
-
- shutdown = GPOINTER_TO_INT (client_data);
-
- current_state = STATE_SAVING_PHASE_2;
-
- save_state ();
-
- save_yourself_possibly_done (shutdown, TRUE);
-}
-
-static void
-save_yourself_callback (SmcConn smc_conn,
- SmPointer client_data,
- int save_style,
- Bool shutdown,
- int interact_style,
- Bool fast)
-{
- gboolean successful;
-
- meta_topic (META_DEBUG_SM, "SaveYourself received");
-
- successful = TRUE;
-
- /* The first SaveYourself after registering for the first time
- * is a special case (SM specs 7.2).
- */
-
-#if 0 /* I think the GnomeClient rationale for this doesn't apply */
- if (current_state == STATE_REGISTERING)
- {
- current_state = STATE_IDLE;
- /* Double check that this is a section 7.2 SaveYourself: */
-
- if (save_style == SmSaveLocal &&
- interact_style == SmInteractStyleNone &&
- !shutdown && !fast)
- {
- /* The protocol requires this even if xsm ignores it. */
- SmcSaveYourselfDone (session_connection, successful);
- return;
- }
- }
-#endif
-
- /* ignore Global style saves
- *
- * This interpretaion of the Local/Global/Both styles
- * was discussed extensively on the xdg-list. See:
- *
- * https://listman.redhat.com/pipermail/xdg-list/2002-July/000615.html
- */
- if (save_style == SmSaveGlobal)
- {
- current_state = STATE_SKIPPING_GLOBAL_SAVE;
- save_yourself_possibly_done (shutdown, successful);
- return;
- }
-
- interaction_allowed = interact_style != SmInteractStyleNone;
-
- current_state = STATE_SAVING_PHASE_1;
-
- regenerate_save_file ();
-
- set_clone_restart_commands ();
-
- save_yourself_possibly_done (shutdown, successful);
-}
-
-
-static void
-die_callback (SmcConn smc_conn, SmPointer client_data)
-{
- meta_topic (META_DEBUG_SM, "Exiting at request of session manager\n");
- disconnect ();
- meta_quit (META_EXIT_SUCCESS);
-}
-
-static void
-save_complete_callback (SmcConn smc_conn, SmPointer client_data)
-{
- /* nothing */
- meta_topic (META_DEBUG_SM, "SaveComplete received\n");
-}
-
-static void
-shutdown_cancelled_callback (SmcConn smc_conn, SmPointer client_data)
-{
- meta_topic (META_DEBUG_SM, "Shutdown cancelled received\n");
-
- if (session_connection != NULL &&
- (current_state != STATE_IDLE && current_state != STATE_FROZEN))
- {
- SmcSaveYourselfDone (session_connection, True);
- current_state = STATE_IDLE;
- }
-}
-
-static void
-interact_callback (SmcConn smc_conn, SmPointer client_data)
-{
- /* nothing */
- gboolean shutdown;
-
- meta_topic (META_DEBUG_SM, "Interaction permission received\n");
-
- shutdown = GPOINTER_TO_INT (client_data);
-
- current_state = STATE_DONE_WITH_INTERACT;
-
- warn_about_lame_clients_and_finish_interact (shutdown);
-}
-
-static void
-set_clone_restart_commands (void)
-{
- char *restartv[10];
- char *clonev[10];
- char *discardv[10];
- int i;
- SmProp prop1, prop2, prop3, *props[3];
-
- /* Restart (use same client ID) */
-
- prop1.name = SmRestartCommand;
- prop1.type = SmLISTofARRAY8;
-
- g_return_if_fail (client_id);
-
- i = 0;
- restartv[i] = "metacity";
- ++i;
- restartv[i] = "--sm-client-id";
- ++i;
- restartv[i] = client_id;
- ++i;
- restartv[i] = NULL;
-
- prop1.vals = g_new (SmPropValue, i);
- i = 0;
- while (restartv[i])
- {
- prop1.vals[i].value = restartv[i];
- prop1.vals[i].length = strlen (restartv[i]);
- ++i;
- }
- prop1.num_vals = i;
-
- /* Clone (no client ID) */
-
- i = 0;
- clonev[i] = "metacity";
- ++i;
- clonev[i] = NULL;
-
- prop2.name = SmCloneCommand;
- prop2.type = SmLISTofARRAY8;
-
- prop2.vals = g_new (SmPropValue, i);
- i = 0;
- while (clonev[i])
- {
- prop2.vals[i].value = clonev[i];
- prop2.vals[i].length = strlen (clonev[i]);
- ++i;
- }
- prop2.num_vals = i;
-
- /* Discard */
-
- i = 0;
- discardv[i] = "rm";
- ++i;
- discardv[i] = "-f";
- ++i;
- discardv[i] = (char*) full_save_file ();
- ++i;
- discardv[i] = NULL;
-
- prop3.name = SmDiscardCommand;
- prop3.type = SmLISTofARRAY8;
-
- prop3.vals = g_new (SmPropValue, i);
- i = 0;
- while (discardv[i])
- {
- prop3.vals[i].value = discardv[i];
- prop3.vals[i].length = strlen (discardv[i]);
- ++i;
- }
- prop3.num_vals = i;
-
-
- props[0] = &prop1;
- props[1] = &prop2;
- props[2] = &prop3;
-
- SmcSetProperties (session_connection, 3, props);
-
- g_free (prop1.vals);
- g_free (prop2.vals);
- g_free (prop3.vals);
-}
-
-/* The remaining code in this file actually loads/saves the session,
- * while the code above this comment handles chatting with the
- * session manager.
- */
-
-static const char*
-window_type_to_string (MetaWindowType type)
-{
- switch (type)
- {
- case META_WINDOW_NORMAL:
- return "normal";
- case META_WINDOW_DESKTOP:
- return "desktop";
- case META_WINDOW_DOCK:
- return "dock";
- case META_WINDOW_DIALOG:
- return "dialog";
- case META_WINDOW_MODAL_DIALOG:
- return "modal_dialog";
- case META_WINDOW_TOOLBAR:
- return "toolbar";
- case META_WINDOW_MENU:
- return "menu";
- case META_WINDOW_SPLASHSCREEN:
- return "splashscreen";
- case META_WINDOW_UTILITY:
- return "utility";
- }
-
- return "";
-}
-
-static MetaWindowType
-window_type_from_string (const char *str)
-{
- if (strcmp (str, "normal") == 0)
- return META_WINDOW_NORMAL;
- else if (strcmp (str, "desktop") == 0)
- return META_WINDOW_DESKTOP;
- else if (strcmp (str, "dock") == 0)
- return META_WINDOW_DOCK;
- else if (strcmp (str, "dialog") == 0)
- return META_WINDOW_DIALOG;
- else if (strcmp (str, "modal_dialog") == 0)
- return META_WINDOW_MODAL_DIALOG;
- else if (strcmp (str, "toolbar") == 0)
- return META_WINDOW_TOOLBAR;
- else if (strcmp (str, "menu") == 0)
- return META_WINDOW_MENU;
- else if (strcmp (str, "utility") == 0)
- return META_WINDOW_UTILITY;
- else if (strcmp (str, "splashscreen") == 0)
- return META_WINDOW_SPLASHSCREEN;
- else
- return META_WINDOW_NORMAL;
-}
-
-static int
-window_gravity_from_string (const char *str)
-{
- if (strcmp (str, "NorthWestGravity") == 0)
- return NorthWestGravity;
- else if (strcmp (str, "NorthGravity") == 0)
- return NorthGravity;
- else if (strcmp (str, "NorthEastGravity") == 0)
- return NorthEastGravity;
- else if (strcmp (str, "WestGravity") == 0)
- return WestGravity;
- else if (strcmp (str, "CenterGravity") == 0)
- return CenterGravity;
- else if (strcmp (str, "EastGravity") == 0)
- return EastGravity;
- else if (strcmp (str, "SouthWestGravity") == 0)
- return SouthWestGravity;
- else if (strcmp (str, "SouthGravity") == 0)
- return SouthGravity;
- else if (strcmp (str, "SouthEastGravity") == 0)
- return SouthEastGravity;
- else if (strcmp (str, "StaticGravity") == 0)
- return StaticGravity;
- else
- return NorthWestGravity;
-}
-
-static char*
-encode_text_as_utf8_markup (const char *text)
-{
- /* text can be any encoding, and is nul-terminated.
- * we pretend it's Latin-1 and encode as UTF-8
- */
- GString *str;
- const char *p;
- char *escaped;
-
- str = g_string_new ("");
-
- p = text;
- while (*p)
- {
- g_string_append_unichar (str, *p);
- ++p;
- }
-
- escaped = g_markup_escape_text (str->str, str->len);
- g_string_free (str, TRUE);
-
- return escaped;
-}
-
-static char*
-decode_text_from_utf8 (const char *text)
-{
- /* Convert back from the encoded (but not escaped) UTF-8 */
- GString *str;
- const char *p;
-
- str = g_string_new ("");
-
- p = text;
- while (*p)
- {
- /* obviously this barfs if the UTF-8 contains chars > 255 */
- g_string_append_c (str, g_utf8_get_char (p));
-
- p = g_utf8_next_char (p);
- }
-
- return g_string_free (str, FALSE);
-}
-
-static void
-save_state (void)
-{
- char *metacity_dir;
- char *session_dir;
- FILE *outfile;
- GSList *windows;
- GSList *tmp;
- int stack_position;
-
- g_assert (client_id);
-
- outfile = NULL;
-
- /*
- * g_get_user_config_dir() is guaranteed to return an existing directory.
- * Eventually, if SM stays with the WM, I'd like to make this
- * something like <config>/window_placement in a standard format.
- * Future optimisers should note also that by the time we get here
- * we probably already have full_save_path figured out and therefore
- * can just use the directory name from that.
- */
- metacity_dir = g_strconcat (g_get_user_config_dir (),
- G_DIR_SEPARATOR_S "metacity",
- NULL);
-
- session_dir = g_strconcat (metacity_dir,
- G_DIR_SEPARATOR_S "sessions",
- NULL);
-
- if (mkdir (metacity_dir, 0700) < 0 &&
- errno != EEXIST)
- {
- meta_warning (_("Could not create directory '%s': %s\n"),
- metacity_dir, g_strerror (errno));
- }
-
- if (mkdir (session_dir, 0700) < 0 &&
- errno != EEXIST)
- {
- meta_warning (_("Could not create directory '%s': %s\n"),
- session_dir, g_strerror (errno));
- }
-
- meta_topic (META_DEBUG_SM, "Saving session to '%s'\n", full_save_file ());
-
- outfile = fopen (full_save_file (), "w");
-
- if (outfile == NULL)
- {
- meta_warning (_("Could not open session file '%s' for writing: %s\n"),
- full_save_file (), g_strerror (errno));
- goto out;
- }
-
- /* The file format is:
- * <metacity_session id="foo">
- * <window id="bar" class="XTerm" name="xterm" title="/foo/bar" role="blah" type="normal" stacking="5">
- * <workspace index="2"/>
- * <workspace index="4"/>
- * <sticky/> <minimized/> <maximized/>
- * <geometry x="100" y="100" width="200" height="200" gravity="northwest"/>
- * </window>
- * </metacity_session>
- *
- * Note that attributes on <window> are the match info we use to
- * see if the saved state applies to a restored window, and
- * child elements are the saved state to be applied.
- *
- */
-
- fprintf (outfile, "<metacity_session id=\"%s\">\n",
- client_id);
-
- windows = meta_display_list_windows (meta_get_display ());
- stack_position = 0;
-
- windows = g_slist_sort (windows, meta_display_stack_cmp);
- tmp = windows;
- stack_position = 0;
-
- while (tmp != NULL)
- {
- MetaWindow *window;
-
- window = tmp->data;
-
- if (window->sm_client_id)
- {
- char *sm_client_id;
- char *res_class;
- char *res_name;
- char *role;
- char *title;
-
- /* client id, class, name, role are not expected to be
- * in UTF-8 (I think they are in XPCS which is Latin-1?
- * in practice they are always ascii though.)
- */
-
- sm_client_id = encode_text_as_utf8_markup (window->sm_client_id);
- res_class = window->res_class ?
- encode_text_as_utf8_markup (window->res_class) : NULL;
- res_name = window->res_name ?
- encode_text_as_utf8_markup (window->res_name) : NULL;
- role = window->role ?
- encode_text_as_utf8_markup (window->role) : NULL;
- if (window->title)
- title = g_markup_escape_text (window->title, -1);
- else
- title = NULL;
-
- meta_topic (META_DEBUG_SM, "Saving session managed window %s, client ID '%s'\n",
- window->desc, window->sm_client_id);
-
- fprintf (outfile,
- " <window id=\"%s\" class=\"%s\" name=\"%s\" title=\"%s\" role=\"%s\" type=\"%s\" stacking=\"%d\">\n",
- sm_client_id,
- res_class ? res_class : "",
- res_name ? res_name : "",
- title ? title : "",
- role ? role : "",
- window_type_to_string (window->type),
- stack_position);
-
- g_free (sm_client_id);
- g_free (res_class);
- g_free (res_name);
- g_free (role);
- g_free (title);
-
- /* Sticky */
- if (window->on_all_workspaces)
- fputs (" <sticky/>\n", outfile);
-
- /* Minimized */
- if (window->minimized)
- fputs (" <minimized/>\n", outfile);
-
- /* Maximized */
- if (META_WINDOW_MAXIMIZED (window))
- {
- fprintf (outfile,
- " <maximized saved_x=\"%d\" saved_y=\"%d\" saved_width=\"%d\" saved_height=\"%d\"/>\n",
- window->saved_rect.x,
- window->saved_rect.y,
- window->saved_rect.width,
- window->saved_rect.height);
- }
-
- /* Workspaces we're on */
- {
- int n;
- n = meta_workspace_index (window->workspace);
- fprintf (outfile,
- " <workspace index=\"%d\"/>\n", n);
- }
-
- /* Gravity */
- {
- int x, y, w, h;
- meta_window_get_geometry (window, &x, &y, &w, &h);
-
- fprintf (outfile,
- " <geometry x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" gravity=\"%s\"/>\n",
- x, y, w, h,
- meta_gravity_to_string (window->size_hints.win_gravity));
- }
-
- fputs (" </window>\n", outfile);
- }
- else
- {
- meta_topic (META_DEBUG_SM, "Not saving window '%s', not session managed\n",
- window->desc);
- }
-
- tmp = tmp->next;
- ++stack_position;
- }
-
- g_slist_free (windows);
-
- fputs ("</metacity_session>\n", outfile);
-
- out:
- if (outfile)
- {
- /* FIXME need a dialog for this */
- if (ferror (outfile))
- {
- meta_warning (_("Error writing session file '%s': %s\n"),
- full_save_file (), g_strerror (errno));
- }
- if (fclose (outfile))
- {
- meta_warning (_("Error closing session file '%s': %s\n"),
- full_save_file (), g_strerror (errno));
- }
- }
-
- g_free (metacity_dir);
- g_free (session_dir);
-}
-
-typedef enum
-{
- WINDOW_TAG_NONE,
- WINDOW_TAG_DESKTOP,
- WINDOW_TAG_STICKY,
- WINDOW_TAG_MINIMIZED,
- WINDOW_TAG_MAXIMIZED,
- WINDOW_TAG_GEOMETRY
-} WindowTag;
-
-typedef struct
-{
- MetaWindowSessionInfo *info;
- char *previous_id;
-} ParseData;
-
-static void session_info_free (MetaWindowSessionInfo *info);
-static MetaWindowSessionInfo* session_info_new (void);
-
-static void start_element_handler (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- gpointer user_data,
- GError **error);
-static void end_element_handler (GMarkupParseContext *context,
- const gchar *element_name,
- gpointer user_data,
- GError **error);
-static void text_handler (GMarkupParseContext *context,
- const gchar *text,
- gsize text_len,
- gpointer user_data,
- GError **error);
-
-static GMarkupParser metacity_session_parser = {
- start_element_handler,
- end_element_handler,
- text_handler,
- NULL,
- NULL
-};
-
-static GSList *window_info_list = NULL;
-
-static char*
-load_state (const char *previous_save_file)
-{
- GMarkupParseContext *context;
- GError *error;
- ParseData parse_data;
- char *text;
- gsize length;
- char *session_file;
-
- session_file = g_strconcat (g_get_user_config_dir (),
- G_DIR_SEPARATOR_S "metacity"
- G_DIR_SEPARATOR_S "sessions" G_DIR_SEPARATOR_S,
- previous_save_file,
- NULL);
-
- error = NULL;
- if (!g_file_get_contents (session_file,
- &text,
- &length,
- &error))
- {
- char *canonical_session_file = session_file;
-
- /* Maybe they were doing it the old way, with ~/.metacity */
- session_file = g_strconcat (g_get_home_dir (),
- G_DIR_SEPARATOR_S ".metacity"
- G_DIR_SEPARATOR_S "sessions"
- G_DIR_SEPARATOR_S,
- previous_save_file,
- NULL);
-
- if (!g_file_get_contents (session_file,
- &text,
- &length,
- NULL))
- {
- /* oh, just give up */
-
- meta_warning (_("Failed to read saved session file %s: %s\n"),
- canonical_session_file, error->message);
- g_error_free (error);
- g_free (session_file);
- g_free (canonical_session_file);
- return NULL;
- }
-
- g_free (canonical_session_file);
- }
-
- meta_topic (META_DEBUG_SM, "Parsing saved session file %s\n", session_file);
- g_free (session_file);
- session_file = NULL;
-
- parse_data.info = NULL;
- parse_data.previous_id = NULL;
-
- context = g_markup_parse_context_new (&metacity_session_parser,
- 0, &parse_data, NULL);
-
- error = NULL;
- if (!g_markup_parse_context_parse (context,
- text,
- length,
- &error))
- goto error;
-
-
- error = NULL;
- if (!g_markup_parse_context_end_parse (context, &error))
- goto error;
-
- g_markup_parse_context_free (context);
-
- goto out;
-
- error:
-
- meta_warning (_("Failed to parse saved session file: %s\n"),
- error->message);
- g_error_free (error);
-
- if (parse_data.info)
- session_info_free (parse_data.info);
-
- g_free (parse_data.previous_id);
- parse_data.previous_id = NULL;
-
- out:
-
- g_free (text);
-
- return parse_data.previous_id;
-}
-
-/* FIXME this isn't very robust against bogus session files */
-static void
-start_element_handler (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- gpointer user_data,
- GError **error)
-{
- ParseData *pd;
-
- pd = user_data;
-
- if (strcmp (element_name, "metacity_session") == 0)
- {
- /* Get previous ID */
- int i;
-
- i = 0;
- while (attribute_names[i])
- {
- const char *name;
- const char *val;
-
- name = attribute_names[i];
- val = attribute_values[i];
-
- if (pd->previous_id)
- {
- g_set_error (error,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("<metacity_session> attribute seen but we already have the session ID"));
- return;
- }
-
- if (strcmp (name, "id") == 0)
- {
- pd->previous_id = decode_text_from_utf8 (val);
- }
- else
- {
- g_set_error (error,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
- _("Unknown attribute %s on <%s> element"),
- name, "metacity_session");
- return;
- }
-
- ++i;
- }
- }
- else if (strcmp (element_name, "window") == 0)
- {
- int i;
-
- if (pd->info)
- {
- g_set_error (error,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("nested <window> tag"));
- return;
- }
-
- pd->info = session_info_new ();
-
- i = 0;
- while (attribute_names[i])
- {
- const char *name;
- const char *val;
-
- name = attribute_names[i];
- val = attribute_values[i];
-
- if (strcmp (name, "id") == 0)
- {
- if (*val)
- pd->info->id = decode_text_from_utf8 (val);
- }
- else if (strcmp (name, "class") == 0)
- {
- if (*val)
- pd->info->res_class = decode_text_from_utf8 (val);
- }
- else if (strcmp (name, "name") == 0)
- {
- if (*val)
- pd->info->res_name = decode_text_from_utf8 (val);
- }
- else if (strcmp (name, "title") == 0)
- {
- if (*val)
- pd->info->title = g_strdup (val);
- }
- else if (strcmp (name, "role") == 0)
- {
- if (*val)
- pd->info->role = decode_text_from_utf8 (val);
- }
- else if (strcmp (name, "type") == 0)
- {
- if (*val)
- pd->info->type = window_type_from_string (val);
- }
- else if (strcmp (name, "stacking") == 0)
- {
- if (*val)
- {
- pd->info->stack_position = atoi (val);
- pd->info->stack_position_set = TRUE;
- }
- }
- else
- {
- g_set_error (error,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
- _("Unknown attribute %s on <%s> element"),
- name, "window");
- session_info_free (pd->info);
- pd->info = NULL;
- return;
- }
-
- ++i;
- }
- }
- else if (strcmp (element_name, "workspace") == 0)
- {
- int i;
-
- i = 0;
- while (attribute_names[i])
- {
- const char *name;
-
- name = attribute_names[i];
-
- if (strcmp (name, "index") == 0)
- {
- pd->info->workspace_indices =
- g_slist_prepend (pd->info->workspace_indices,
- GINT_TO_POINTER (atoi (attribute_values[i])));
- }
- else
- {
- g_set_error (error,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
- _("Unknown attribute %s on <%s> element"),
- name, "window");
- session_info_free (pd->info);
- pd->info = NULL;
- return;
- }
-
- ++i;
- }
- }
- else if (strcmp (element_name, "sticky") == 0)
- {
- pd->info->on_all_workspaces = TRUE;
- pd->info->on_all_workspaces_set = TRUE;
- }
- else if (strcmp (element_name, "minimized") == 0)
- {
- pd->info->minimized = TRUE;
- pd->info->minimized_set = TRUE;
- }
- else if (strcmp (element_name, "maximized") == 0)
- {
- int i;
-
- i = 0;
- pd->info->maximized = TRUE;
- pd->info->maximized_set = TRUE;
- while (attribute_names[i])
- {
- const char *name;
- const char *val;
-
- name = attribute_names[i];
- val = attribute_values[i];
-
- if (strcmp (name, "saved_x") == 0)
- {
- if (*val)
- {
- pd->info->saved_rect.x = atoi (val);
- pd->info->saved_rect_set = TRUE;
- }
- }
- else if (strcmp (name, "saved_y") == 0)
- {
- if (*val)
- {
- pd->info->saved_rect.y = atoi (val);
- pd->info->saved_rect_set = TRUE;
- }
- }
- else if (strcmp (name, "saved_width") == 0)
- {
- if (*val)
- {
- pd->info->saved_rect.width = atoi (val);
- pd->info->saved_rect_set = TRUE;
- }
- }
- else if (strcmp (name, "saved_height") == 0)
- {
- if (*val)
- {
- pd->info->saved_rect.height = atoi (val);
- pd->info->saved_rect_set = TRUE;
- }
- }
- else
- {
- g_set_error (error,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
- _("Unknown attribute %s on <%s> element"),
- name, "maximized");
- return;
- }
-
- ++i;
- }
-
- if (pd->info->saved_rect_set)
- meta_topic (META_DEBUG_SM, "Saved unmaximized size %d,%d %dx%d \n",
- pd->info->saved_rect.x,
- pd->info->saved_rect.y,
- pd->info->saved_rect.width,
- pd->info->saved_rect.height);
- }
- else if (strcmp (element_name, "geometry") == 0)
- {
- int i;
-
- pd->info->geometry_set = TRUE;
-
- i = 0;
- while (attribute_names[i])
- {
- const char *name;
- const char *val;
-
- name = attribute_names[i];
- val = attribute_values[i];
-
- if (strcmp (name, "x") == 0)
- {
- if (*val)
- pd->info->rect.x = atoi (val);
- }
- else if (strcmp (name, "y") == 0)
- {
- if (*val)
- pd->info->rect.y = atoi (val);
- }
- else if (strcmp (name, "width") == 0)
- {
- if (*val)
- pd->info->rect.width = atoi (val);
- }
- else if (strcmp (name, "height") == 0)
- {
- if (*val)
- pd->info->rect.height = atoi (val);
- }
- else if (strcmp (name, "gravity") == 0)
- {
- if (*val)
- pd->info->gravity = window_gravity_from_string (val);
- }
- else
- {
- g_set_error (error,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
- _("Unknown attribute %s on <%s> element"),
- name, "geometry");
- return;
- }
-
- ++i;
- }
-
- meta_topic (META_DEBUG_SM, "Loaded geometry %d,%d %dx%d gravity %s\n",
- pd->info->rect.x,
- pd->info->rect.y,
- pd->info->rect.width,
- pd->info->rect.height,
- meta_gravity_to_string (pd->info->gravity));
- }
- else
- {
- g_set_error (error,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_UNKNOWN_ELEMENT,
- _("Unknown element %s"),
- element_name);
- return;
- }
-}
-
-static void
-end_element_handler (GMarkupParseContext *context,
- const gchar *element_name,
- gpointer user_data,
- GError **error)
-{
- ParseData *pd;
-
- pd = user_data;
-
- if (strcmp (element_name, "window") == 0)
- {
- g_assert (pd->info);
-
- window_info_list = g_slist_prepend (window_info_list,
- pd->info);
-
- meta_topic (META_DEBUG_SM, "Loaded window info from session with class: %s name: %s role: %s\n",
- pd->info->res_class ? pd->info->res_class : "(none)",
- pd->info->res_name ? pd->info->res_name : "(none)",
- pd->info->role ? pd->info->role : "(none)");
-
- pd->info = NULL;
- }
-}
-
-static void
-text_handler (GMarkupParseContext *context,
- const gchar *text,
- gsize text_len,
- gpointer user_data,
- GError **error)
-{
- /* Right now we don't have any elements where we care about their
- * content
- */
-}
-
-static gboolean
-both_null_or_matching (const char *a,
- const char *b)
-{
- if (a == NULL && b == NULL)
- return TRUE;
- else if (a && b && strcmp (a, b) == 0)
- return TRUE;
- else
- return FALSE;
-}
-
-static GSList*
-get_possible_matches (MetaWindow *window)
-{
- /* Get all windows with this client ID */
- GSList *retval;
- GSList *tmp;
- gboolean ignore_client_id;
-
- retval = NULL;
-
- ignore_client_id = g_getenv ("METACITY_DEBUG_SM") != NULL;
-
- tmp = window_info_list;
- while (tmp != NULL)
- {
- MetaWindowSessionInfo *info;
-
- info = tmp->data;
-
- if ((ignore_client_id ||
- both_null_or_matching (info->id, window->sm_client_id)) &&
- both_null_or_matching (info->res_class, window->res_class) &&
- both_null_or_matching (info->res_name, window->res_name) &&
- both_null_or_matching (info->role, window->role))
- {
- meta_topic (META_DEBUG_SM, "Window %s may match saved window with class: %s name: %s role: %s\n",
- window->desc,
- info->res_class ? info->res_class : "(none)",
- info->res_name ? info->res_name : "(none)",
- info->role ? info->role : "(none)");
-
- retval = g_slist_prepend (retval, info);
- }
- else
- {
- if (meta_is_verbose ())
- {
- if (!both_null_or_matching (info->id, window->sm_client_id))
- meta_topic (META_DEBUG_SM, "Window %s has SM client ID %s, saved state has %s, no match\n",
- window->desc,
- window->sm_client_id ? window->sm_client_id : "(none)",
- info->id ? info->id : "(none)");
- else if (!both_null_or_matching (info->res_class, window->res_class))
- meta_topic (META_DEBUG_SM, "Window %s has class %s doesn't match saved class %s, no match\n",
- window->desc,
- window->res_class ? window->res_class : "(none)",
- info->res_class ? info->res_class : "(none)");
-
- else if (!both_null_or_matching (info->res_name, window->res_name))
- meta_topic (META_DEBUG_SM, "Window %s has name %s doesn't match saved name %s, no match\n",
- window->desc,
- window->res_name ? window->res_name : "(none)",
- info->res_name ? info->res_name : "(none)");
- else if (!both_null_or_matching (info->role, window->role))
- meta_topic (META_DEBUG_SM, "Window %s has role %s doesn't match saved role %s, no match\n",
- window->desc,
- window->role ? window->role : "(none)",
- info->role ? info->role : "(none)");
- else
- meta_topic (META_DEBUG_SM, "???? should not happen - window %s doesn't match saved state %s for no good reason\n",
- window->desc, info->id);
- }
- }
-
- tmp = tmp->next;
- }
-
- return retval;
-}
-
-static const MetaWindowSessionInfo*
-find_best_match (GSList *infos,
- MetaWindow *window)
-{
- GSList *tmp;
- const MetaWindowSessionInfo *matching_title;
- const MetaWindowSessionInfo *matching_type;
-
- matching_title = NULL;
- matching_type = NULL;
-
- tmp = infos;
- while (tmp != NULL)
- {
- MetaWindowSessionInfo *info;
-
- info = tmp->data;
-
- if (matching_title == NULL &&
- both_null_or_matching (info->title, window->title))
- matching_title = info;
-
- if (matching_type == NULL &&
- info->type == window->type)
- matching_type = info;
-
- tmp = tmp->next;
- }
-
- /* Prefer same title, then same type of window, then
- * just pick something. Eventually we could enhance this
- * to e.g. break ties by geometry hint similarity,
- * or other window features.
- */
-
- if (matching_title)
- return matching_title;
- else if (matching_type)
- return matching_type;
- else
- return infos->data;
-}
-
-const MetaWindowSessionInfo*
-meta_window_lookup_saved_state (MetaWindow *window)
-{
- GSList *possibles;
- const MetaWindowSessionInfo *info;
-
- /* Window is not session managed.
- * I haven't yet figured out how to deal with these
- * in a way that doesn't cause broken side effects in
- * situations other than on session restore.
- */
- if (window->sm_client_id == NULL)
- {
- meta_topic (META_DEBUG_SM,
- "Window %s is not session managed, not checking for saved state\n",
- window->desc);
- return NULL;
- }
-
- possibles = get_possible_matches (window);
-
- if (possibles == NULL)
- {
- meta_topic (META_DEBUG_SM, "Window %s has no possible matches in the list of saved window states\n",
- window->desc);
- return NULL;
- }
-
- info = find_best_match (possibles, window);
-
- g_slist_free (possibles);
-
- return info;
-}
-
-void
-meta_window_release_saved_state (const MetaWindowSessionInfo *info)
-{
- /* We don't want to use the same saved state again for another
- * window.
- */
- window_info_list = g_slist_remove (window_info_list, info);
-
- session_info_free ((MetaWindowSessionInfo*) info);
-}
-
-static void
-session_info_free (MetaWindowSessionInfo *info)
-{
- g_free (info->id);
- g_free (info->res_class);
- g_free (info->res_name);
- g_free (info->title);
- g_free (info->role);
-
- g_slist_free (info->workspace_indices);
-
- g_free (info);
-}
-
-static MetaWindowSessionInfo*
-session_info_new (void)
-{
- MetaWindowSessionInfo *info;
-
- info = g_new0 (MetaWindowSessionInfo, 1);
-
- info->type = META_WINDOW_NORMAL;
- info->gravity = NorthWestGravity;
-
- return info;
-}
-
-static char* full_save_path = NULL;
-
-static void
-regenerate_save_file (void)
-{
- g_free (full_save_path);
-
- if (client_id)
- full_save_path = g_strconcat (g_get_user_config_dir (),
- G_DIR_SEPARATOR_S "metacity"
- G_DIR_SEPARATOR_S "sessions" G_DIR_SEPARATOR_S,
- client_id,
- ".ms",
- NULL);
- else
- full_save_path = NULL;
-}
-
-static const char*
-full_save_file (void)
-{
- return full_save_path;
-}
-
-static int
-windows_cmp_by_title (MetaWindow *a,
- MetaWindow *b)
-{
- return g_utf8_collate (a->title, b->title);
-}
-
-typedef struct
-{
- int child_pid;
- int child_pipe;
- gboolean shutdown;
-} LameClientsDialogData;
-
-static void
-finish_interact (gboolean shutdown)
-{
- if (current_state == STATE_DONE_WITH_INTERACT) /* paranoia */
- {
- SmcInteractDone (session_connection, False /* don't cancel logout */);
-
- save_yourself_possibly_done (shutdown, TRUE);
- }
-}
-
-static gboolean
-io_from_warning_dialog (GIOChannel *channel,
- GIOCondition condition,
- gpointer data)
-{
- LameClientsDialogData *d;
-
- d = data;
-
- meta_topic (META_DEBUG_PING,
- "IO handler from lame clients dialog, condition = %x\n",
- condition);
-
- if (condition & (G_IO_HUP | G_IO_NVAL | G_IO_ERR))
- {
- finish_interact (d->shutdown);
-
- /* Remove the callback, freeing data */
- return FALSE;
- }
- else if (condition & G_IO_IN)
- {
- /* Check for EOF */
-
- char buf[16];
- int ret;
-
- ret = read (d->child_pipe, buf, sizeof (buf));
- if (ret == 0)
- {
- finish_interact (d->shutdown);
- return FALSE;
- }
- }
-
- /* Keep callback installed */
- return TRUE;
-}
-
-static void
-warn_about_lame_clients_and_finish_interact (gboolean shutdown)
-{
- GSList *lame;
- GSList *windows;
- char **argv;
- int i;
- GSList *tmp;
- int len;
- int child_pid;
- int child_pipe;
- GError *err;
- GIOChannel *channel;
- LameClientsDialogData *d;
- guint32 timestamp;
- char timestampbuf[32];
-
- lame = NULL;
- windows = meta_display_list_windows (meta_get_display ());
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *window;
-
- window = tmp->data;
-
- /* only complain about normal windows, the others
- * are kind of dumb to worry about
- */
- if (window->sm_client_id == NULL &&
- window->type == META_WINDOW_NORMAL)
- lame = g_slist_prepend (lame, window);
-
- tmp = tmp->next;
- }
-
- g_slist_free (windows);
-
- if (lame == NULL)
- {
- /* No lame apps. */
- finish_interact (shutdown);
- return;
- }
-
- lame = g_slist_sort (lame, (GCompareFunc) windows_cmp_by_title);
-
- timestamp = meta_display_get_current_time_roundtrip (meta_get_display ());
- sprintf (timestampbuf, "%u", timestamp);
-
- len = g_slist_length (lame);
- len *= 2; /* titles and also classes */
- len += 2; /* --timestamp flag and actual timestamp */
- len += 1; /* NULL term */
- len += 2; /* metacity-dialog command and option */
-
- argv = g_new0 (char*, len);
-
- i = 0;
-
- argv[i] = METACITY_LIBEXECDIR"/metacity-dialog";
- ++i;
- argv[i] = "--timestamp";
- ++i;
- argv[i] = timestampbuf;
- ++i;
- argv[i] = "--warn-about-no-sm-support";
- ++i;
-
- tmp = lame;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
-
- argv[i] = w->title;
- ++i;
- argv[i] = w->res_class ? w->res_class : "";
- ++i;
-
- tmp = tmp->next;
- }
-
- child_pipe = -1;
- child_pid = -1;
- err = NULL;
- if (!g_spawn_async_with_pipes ("/",
- argv,
- NULL,
- 0,
- NULL, NULL,
- &child_pid,
- NULL,
- &child_pipe,
- NULL,
- &err))
- {
- meta_warning (_("Error launching metacity-dialog to warn about apps that don't support session management: %s\n"),
- err->message);
- g_error_free (err);
- }
-
- g_free (argv);
- g_slist_free (lame);
-
- d = g_new0 (LameClientsDialogData, 1);
- d->child_pipe = child_pipe;
- d->child_pid = child_pid;
- d->shutdown = shutdown;
-
- channel = g_io_channel_unix_new (d->child_pipe);
- g_io_add_watch_full (channel, G_PRIORITY_DEFAULT,
- G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- io_from_warning_dialog,
- d, g_free);
- g_io_channel_unref (channel);
-}
-
-#endif /* HAVE_SM */
diff --git a/src/core/session.h b/src/core/session.h
deleted file mode 100644
index 62a9370d..00000000
--- a/src/core/session.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * \file session.h Session management
- *
- * Maps windows to information about their placing and state on startup.
- * This is window matching, which we have a policy of leaving in general
- * to programs such as Devil's Pie, but the session manager specification
- * requires us to do it here.
- */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_SESSION_H
-#define META_SESSION_H
-
-#include "window-private.h"
-
-typedef struct _MetaWindowSessionInfo MetaWindowSessionInfo;
-
-struct _MetaWindowSessionInfo
-{
- /* Fields we use to match against */
-
- char *id;
- char *res_class;
- char *res_name;
- char *title;
- char *role;
- MetaWindowType type;
-
- /* Information we restore */
-
- GSList *workspace_indices;
-
- int stack_position;
-
- /* width/height should be multiplied by resize inc and
- * added to base size; position should be interpreted in
- * light of gravity. This preserves semantics of the
- * window size/pos, even if fonts/themes change, etc.
- */
- int gravity;
- MetaRectangle rect;
- MetaRectangle saved_rect;
- guint on_all_workspaces : 1;
- guint minimized : 1;
- guint maximized : 1;
-
- guint stack_position_set : 1;
- guint geometry_set : 1;
- guint on_all_workspaces_set : 1;
- guint minimized_set : 1;
- guint maximized_set : 1;
- guint saved_rect_set : 1;
-};
-
-/* If lookup_saved_state returns something, it should be used,
- * and then released when you're done with it.
- */
-const MetaWindowSessionInfo* meta_window_lookup_saved_state (MetaWindow *window);
-void meta_window_release_saved_state (const MetaWindowSessionInfo *info);
-
-void meta_session_init (const char *client_id,
- const char *save_file);
-
-
-void meta_session_shutdown (void);
-
-#endif
-
-
-
-
diff --git a/src/core/stack.c b/src/core/stack.c
deleted file mode 100644
index cf770bca..00000000
--- a/src/core/stack.c
+++ /dev/null
@@ -1,1661 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * \file stack.c Which windows cover which other windows
- */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2002, 2003 Red Hat, Inc.
- * Copyright (C) 2004 Rob Adams
- * Copyright (C) 2004, 2005 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include "stack.h"
-#include "window-private.h"
-#include "errors.h"
-#include "frame-private.h"
-#include "group.h"
-#include "prefs.h"
-#include "workspace.h"
-
-#include <X11/Xatom.h>
-
-#define WINDOW_HAS_TRANSIENT_TYPE(w) \
- (w->type == META_WINDOW_DIALOG || \
- w->type == META_WINDOW_MODAL_DIALOG || \
- w->type == META_WINDOW_TOOLBAR || \
- w->type == META_WINDOW_MENU || \
- w->type == META_WINDOW_UTILITY)
-
-#define WINDOW_TRANSIENT_FOR_WHOLE_GROUP(w) \
- ((w->xtransient_for == None || \
- w->transient_parent_is_root_window) && \
- WINDOW_HAS_TRANSIENT_TYPE (w))
-
-#define WINDOW_IN_STACK(w) (w->stack_position >= 0)
-
-static void stack_sync_to_server (MetaStack *stack);
-static void meta_window_set_stack_position_no_sync (MetaWindow *window,
- int position);
-static void stack_do_window_deletions (MetaStack *stack);
-static void stack_do_window_additions (MetaStack *stack);
-static void stack_do_relayer (MetaStack *stack);
-static void stack_do_constrain (MetaStack *stack);
-static void stack_do_resort (MetaStack *stack);
-
-static void stack_ensure_sorted (MetaStack *stack);
-
-MetaStack*
-meta_stack_new (MetaScreen *screen)
-{
- MetaStack *stack;
-
- stack = g_new (MetaStack, 1);
-
- stack->screen = screen;
- stack->windows = g_array_new (FALSE, FALSE, sizeof (Window));
-
- stack->sorted = NULL;
- stack->added = NULL;
- stack->removed = NULL;
-
- stack->freeze_count = 0;
- stack->last_root_children_stacked = NULL;
-
- stack->n_positions = 0;
-
- stack->need_resort = FALSE;
- stack->need_relayer = FALSE;
- stack->need_constrain = FALSE;
-
- return stack;
-}
-
-void
-meta_stack_free (MetaStack *stack)
-{
- g_array_free (stack->windows, TRUE);
-
- g_list_free (stack->sorted);
- g_list_free (stack->added);
- g_list_free (stack->removed);
-
- if (stack->last_root_children_stacked)
- g_array_free (stack->last_root_children_stacked, TRUE);
-
- g_free (stack);
-}
-
-void
-meta_stack_add (MetaStack *stack,
- MetaWindow *window)
-{
- meta_topic (META_DEBUG_STACK, "Adding window %s to the stack\n", window->desc);
-
- if (window->stack_position >= 0)
- meta_bug ("Window %s had stack position already\n", window->desc);
-
- stack->added = g_list_prepend (stack->added, window);
-
- window->stack_position = stack->n_positions;
- stack->n_positions += 1;
- meta_topic (META_DEBUG_STACK,
- "Window %s has stack_position initialized to %d\n",
- window->desc, window->stack_position);
-
- stack_sync_to_server (stack);
-}
-
-void
-meta_stack_remove (MetaStack *stack,
- MetaWindow *window)
-{
- meta_topic (META_DEBUG_STACK, "Removing window %s from the stack\n", window->desc);
-
- if (window->stack_position < 0)
- meta_bug ("Window %s removed from stack but had no stack position\n",
- window->desc);
-
- /* Set window to top position, so removing it will not leave gaps
- * in the set of positions
- */
- meta_window_set_stack_position_no_sync (window,
- stack->n_positions - 1);
- window->stack_position = -1;
- stack->n_positions -= 1;
-
- /* We don't know if it's been moved from "added" to "stack" yet */
- stack->added = g_list_remove (stack->added, window);
- stack->sorted = g_list_remove (stack->sorted, window);
-
- /* Remember the window ID to remove it from the stack array.
- * The macro is safe to use: Window is guaranteed to be 32 bits, and
- * GUINT_TO_POINTER says it only works on 32 bits.
- */
- stack->removed = g_list_prepend (stack->removed,
- GUINT_TO_POINTER (window->xwindow));
- if (window->frame)
- stack->removed = g_list_prepend (stack->removed,
- GUINT_TO_POINTER (window->frame->xwindow));
-
- stack_sync_to_server (stack);
-}
-
-void
-meta_stack_update_layer (MetaStack *stack,
- MetaWindow *window)
-{
- stack->need_relayer = TRUE;
-
- stack_sync_to_server (stack);
-}
-
-void
-meta_stack_update_transient (MetaStack *stack,
- MetaWindow *window)
-{
- stack->need_constrain = TRUE;
-
- stack_sync_to_server (stack);
-}
-
-/* raise/lower within a layer */
-void
-meta_stack_raise (MetaStack *stack,
- MetaWindow *window)
-{
- meta_window_set_stack_position_no_sync (window,
- stack->n_positions - 1);
-
- stack_sync_to_server (stack);
-}
-
-void
-meta_stack_lower (MetaStack *stack,
- MetaWindow *window)
-{
- meta_window_set_stack_position_no_sync (window, 0);
-
- stack_sync_to_server (stack);
-}
-
-void
-meta_stack_freeze (MetaStack *stack)
-{
- stack->freeze_count += 1;
-}
-
-void
-meta_stack_thaw (MetaStack *stack)
-{
- g_return_if_fail (stack->freeze_count > 0);
-
- stack->freeze_count -= 1;
- stack_sync_to_server (stack);
-}
-
-static gboolean
-is_focused_foreach (MetaWindow *window,
- void *data)
-{
- if (window == window->display->expected_focus_window)
- {
- *((gboolean*) data) = TRUE;
- return FALSE;
- }
- return TRUE;
-}
-
-static gboolean
-windows_on_different_xinerama (MetaWindow *a,
- MetaWindow *b)
-{
- if (a->screen != b->screen)
- return TRUE;
-
- return meta_screen_get_xinerama_for_window (a->screen, a) !=
- meta_screen_get_xinerama_for_window (b->screen, b);
-}
-
-/* Get layer ignoring any transient or group relationships */
-static MetaStackLayer
-get_standalone_layer (MetaWindow *window)
-{
- MetaStackLayer layer;
- gboolean focused_transient = FALSE;
-
- switch (window->type)
- {
- case META_WINDOW_DESKTOP:
- layer = META_LAYER_DESKTOP;
- break;
-
- case META_WINDOW_DOCK:
- /* still experimenting here */
- if (window->wm_state_below)
- layer = META_LAYER_BOTTOM;
- else
- layer = META_LAYER_DOCK;
- break;
-
- default:
- meta_window_foreach_transient (window,
- is_focused_foreach,
- &focused_transient);
-
- if (window->wm_state_below)
- layer = META_LAYER_BOTTOM;
- else if (window->fullscreen &&
- (focused_transient ||
- window == window->display->expected_focus_window ||
- window->display->expected_focus_window == NULL ||
- (window->display->expected_focus_window != NULL &&
- windows_on_different_xinerama (window,
- window->display->expected_focus_window))))
- layer = META_LAYER_FULLSCREEN;
- else if (window->wm_state_above)
- layer = META_LAYER_TOP;
- else
- layer = META_LAYER_NORMAL;
- break;
- }
-
- return layer;
-}
-
-/* Note that this function can never use window->layer only
- * get_standalone_layer, or we'd have issues.
- */
-static MetaStackLayer
-get_maximum_layer_in_group (MetaWindow *window)
-{
- GSList *members;
- MetaGroup *group;
- GSList *tmp;
- MetaStackLayer max;
- MetaStackLayer layer;
-
- max = META_LAYER_DESKTOP;
-
- group = meta_window_get_group (window);
-
- if (group != NULL)
- members = meta_group_list_windows (group);
- else
- members = NULL;
-
- tmp = members;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
-
- layer = get_standalone_layer (w);
- if (layer > max)
- max = layer;
-
- tmp = tmp->next;
- }
-
- g_slist_free (members);
-
- return max;
-}
-
-static void
-compute_layer (MetaWindow *window)
-{
- window->layer = get_standalone_layer (window);
-
- /* We can only do promotion-due-to-group for dialogs and other
- * transients, or weird stuff happens like the desktop window and
- * nautilus windows getting in the same layer, or all gnome-terminal
- * windows getting in fullscreen layer if any terminal is
- * fullscreen.
- */
- if (WINDOW_HAS_TRANSIENT_TYPE(window) &&
- (window->xtransient_for == None ||
- window->transient_parent_is_root_window))
- {
- /* We only do the group thing if the dialog is NOT transient for
- * a particular window. Imagine a group with a normal window, a dock,
- * and a dialog transient for the normal window; you don't want the dialog
- * above the dock if it wouldn't normally be.
- */
-
- MetaStackLayer group_max;
-
- group_max = get_maximum_layer_in_group (window);
-
- if (group_max > window->layer)
- {
- meta_topic (META_DEBUG_STACK,
- "Promoting window %s from layer %u to %u due to group membership\n",
- window->desc, window->layer, group_max);
- window->layer = group_max;
- }
- }
-
- meta_topic (META_DEBUG_STACK, "Window %s on layer %u type = %u has_focus = %d\n",
- window->desc, window->layer,
- window->type, window->has_focus);
-}
-
-/* Front of the layer list is the topmost window,
- * so the lower stack position is later in the list
- */
-static int
-compare_window_position (void *a,
- void *b)
-{
- MetaWindow *window_a = a;
- MetaWindow *window_b = b;
-
- /* Go by layer, then stack_position */
- if (window_a->layer < window_b->layer)
- return 1; /* move window_a later in list */
- else if (window_a->layer > window_b->layer)
- return -1;
- else if (window_a->stack_position < window_b->stack_position)
- return 1; /* move window_a later in list */
- else if (window_a->stack_position > window_b->stack_position)
- return -1;
- else
- return 0; /* not reached */
-}
-
-/*
- * Stacking constraints
- *
- * Assume constraints of the form "AB" meaning "window A must be
- * below window B"
- *
- * If we have windows stacked from bottom to top
- * "ABC" then raise A we get "BCA". Say C is
- * transient for B is transient for A. So
- * we have constraints AB and BC.
- *
- * After raising A, we need to reapply the constraints.
- * If we do this by raising one window at a time -
- *
- * start: BCA
- * apply AB: CAB
- * apply BC: ABC
- *
- * but apply constraints in the wrong order and it breaks:
- *
- * start: BCA
- * apply BC: BCA
- * apply AB: CAB
- *
- * We make a directed graph of the constraints by linking
- * from "above windows" to "below windows as follows:
- *
- * AB -> BC -> CD
- * \
- * CE
- *
- * If we then walk that graph and apply the constraints in the order
- * that they appear, we will apply them correctly. Note that the
- * graph MAY have cycles, so we have to guard against that.
- *
- */
-
-typedef struct Constraint Constraint;
-
-struct Constraint
-{
- MetaWindow *above;
- MetaWindow *below;
-
- /* used to keep the constraint in the
- * list of constraints for window "below"
- */
- Constraint *next;
-
- /* used to create the graph. */
- GSList *next_nodes;
-
- /* constraint has been applied, used
- * to detect cycles.
- */
- unsigned int applied : 1;
-
- /* constraint has a previous node in the graph,
- * used to find places to start in the graph.
- * (I think this also has the side effect
- * of preventing cycles, since cycles will
- * have no starting point - so maybe
- * the "applied" flag isn't needed.)
- */
- unsigned int has_prev : 1;
-};
-
-/* We index the array of constraints by window
- * stack positions, just because the stack
- * positions are a convenient index.
- */
-static void
-add_constraint (Constraint **constraints,
- MetaWindow *above,
- MetaWindow *below)
-{
- Constraint *c;
-
- g_assert (above->screen == below->screen);
-
- /* check if constraint is a duplicate */
- c = constraints[below->stack_position];
- while (c != NULL)
- {
- if (c->above == above)
- return;
- c = c->next;
- }
-
- /* if not, add the constraint */
- c = g_new (Constraint, 1);
- c->above = above;
- c->below = below;
- c->next = constraints[below->stack_position];
- c->next_nodes = NULL;
- c->applied = FALSE;
- c->has_prev = FALSE;
-
- constraints[below->stack_position] = c;
-}
-
-static void
-create_constraints (Constraint **constraints,
- GList *windows)
-{
- GList *tmp;
-
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
-
- if (!WINDOW_IN_STACK (w))
- {
- meta_topic (META_DEBUG_STACK, "Window %s not in the stack, not constraining it\n",
- w->desc);
- tmp = tmp->next;
- continue;
- }
-
- if (WINDOW_TRANSIENT_FOR_WHOLE_GROUP (w))
- {
- GSList *group_windows;
- GSList *tmp2;
- MetaGroup *group;
-
- group = meta_window_get_group (w);
-
- if (group != NULL)
- group_windows = meta_group_list_windows (group);
- else
- group_windows = NULL;
-
- tmp2 = group_windows;
-
- while (tmp2 != NULL)
- {
- MetaWindow *group_window = tmp2->data;
-
- if (!WINDOW_IN_STACK (group_window) ||
- w->screen != group_window->screen)
- {
- tmp2 = tmp2->next;
- continue;
- }
-
-#if 0
- /* old way of doing it */
- if (!(meta_window_is_ancestor_of_transient (w, group_window)) &&
- !WINDOW_TRANSIENT_FOR_WHOLE_GROUP (group_window)) /* note */;/*note*/
-#else
- /* better way I think, so transient-for-group are constrained
- * only above non-transient-type windows in their group
- */
- if (!WINDOW_HAS_TRANSIENT_TYPE (group_window))
-#endif
- {
- meta_topic (META_DEBUG_STACK, "Constraining %s above %s as it's transient for its group\n",
- w->desc, group_window->desc);
- add_constraint (constraints, w, group_window);
- }
-
- tmp2 = tmp2->next;
- }
-
- g_slist_free (group_windows);
- }
- else if (w->xtransient_for != None &&
- !w->transient_parent_is_root_window)
- {
- MetaWindow *parent;
-
- parent =
- meta_display_lookup_x_window (w->display, w->xtransient_for);
-
- if (parent && WINDOW_IN_STACK (parent) &&
- parent->screen == w->screen)
- {
- meta_topic (META_DEBUG_STACK, "Constraining %s above %s due to transiency\n",
- w->desc, parent->desc);
- add_constraint (constraints, w, parent);
- }
- }
-
- tmp = tmp->next;
- }
-}
-
-static void
-graph_constraints (Constraint **constraints,
- int n_constraints)
-{
- int i;
-
- i = 0;
- while (i < n_constraints)
- {
- Constraint *c;
-
- /* If we have "A below B" and "B below C" then AB -> BC so we
- * add BC to next_nodes in AB.
- */
-
- c = constraints[i];
- while (c != NULL)
- {
- Constraint *n;
-
- g_assert (c->below->stack_position == i);
-
- /* Constraints where ->above is below are our
- * next_nodes and we are their previous
- */
- n = constraints[c->above->stack_position];
- while (n != NULL)
- {
- c->next_nodes = g_slist_prepend (c->next_nodes,
- n);
- /* c is a previous node of n */
- n->has_prev = TRUE;
-
- n = n->next;
- }
-
- c = c->next;
- }
-
- ++i;
- }
-}
-
-static void
-free_constraints (Constraint **constraints,
- int n_constraints)
-{
- int i;
-
- i = 0;
- while (i < n_constraints)
- {
- Constraint *c;
-
- c = constraints[i];
- while (c != NULL)
- {
- Constraint *next = c->next;
-
- g_slist_free (c->next_nodes);
-
- g_free (c);
-
- c = next;
- }
-
- ++i;
- }
-}
-
-static void
-ensure_above (MetaWindow *above,
- MetaWindow *below)
-{
- if (WINDOW_HAS_TRANSIENT_TYPE(above) &&
- above->layer < below->layer)
- {
- meta_topic (META_DEBUG_STACK,
- "Promoting window %s from layer %u to %u due to contraint\n",
- above->desc, above->layer, below->layer);
- above->layer = below->layer;
- }
-
- if (above->stack_position < below->stack_position)
- {
- /* move above to below->stack_position bumping below down the stack */
- meta_window_set_stack_position_no_sync (above, below->stack_position);
- g_assert (below->stack_position + 1 == above->stack_position);
- }
- meta_topic (META_DEBUG_STACK, "%s above at %d > %s below at %d\n",
- above->desc, above->stack_position,
- below->desc, below->stack_position);
-}
-
-static void
-traverse_constraint (Constraint *c)
-{
- GSList *tmp;
-
- if (c->applied)
- return;
-
- ensure_above (c->above, c->below);
- c->applied = TRUE;
-
- tmp = c->next_nodes;
- while (tmp != NULL)
- {
- traverse_constraint (tmp->data);
-
- tmp = tmp->next;
- }
-}
-
-static void
-apply_constraints (Constraint **constraints,
- int n_constraints)
-{
- GSList *heads;
- GSList *tmp;
- int i;
-
- /* List all heads in an ordered constraint chain */
- heads = NULL;
- i = 0;
- while (i < n_constraints)
- {
- Constraint *c;
-
- c = constraints[i];
- while (c != NULL)
- {
- if (!c->has_prev)
- heads = g_slist_prepend (heads, c);
-
- c = c->next;
- }
-
- ++i;
- }
-
- /* Now traverse the chain and apply constraints */
- tmp = heads;
- while (tmp != NULL)
- {
- Constraint *c = tmp->data;
-
- traverse_constraint (c);
-
- tmp = tmp->next;
- }
-
- g_slist_free (heads);
-}
-
-/**
- * Go through "deleted" and take the matching windows
- * out of "windows".
- */
-static void
-stack_do_window_deletions (MetaStack *stack)
-{
- /* Do removals before adds, with paranoid idea that we might re-add
- * the same window IDs.
- */
- GList *tmp;
- int i;
-
- tmp = stack->removed;
- while (tmp != NULL)
- {
- Window xwindow;
- xwindow = GPOINTER_TO_UINT (tmp->data);
-
- /* We go from the end figuring removals are more
- * likely to be recent.
- */
- i = stack->windows->len;
- while (i > 0)
- {
- --i;
-
- /* there's no guarantee we'll actually find windows to
- * remove, e.g. the same xwindow could have been
- * added/removed before we ever synced, and we put
- * both the window->xwindow and window->frame->xwindow
- * in the removal list.
- */
- if (xwindow == g_array_index (stack->windows, Window, i))
- {
- g_array_remove_index (stack->windows, i);
- goto next;
- }
- }
-
- next:
- tmp = tmp->next;
- }
-
- g_list_free (stack->removed);
- stack->removed = NULL;
-}
-
-static void
-stack_do_window_additions (MetaStack *stack)
-{
- GList *tmp;
- gint i, n_added;
-
- n_added = g_list_length (stack->added);
- if (n_added > 0)
- {
- Window *end;
- int old_size;
-
- meta_topic (META_DEBUG_STACK,
- "Adding %d windows to sorted list\n",
- n_added);
-
- old_size = stack->windows->len;
- g_array_set_size (stack->windows, old_size + n_added);
-
- end = &g_array_index (stack->windows, Window, old_size);
-
- /* stack->added has the most recent additions at the
- * front of the list, so we need to reverse it
- */
- stack->added = g_list_reverse (stack->added);
-
- i = 0;
- tmp = stack->added;
- while (tmp != NULL)
- {
- MetaWindow *w;
-
- w = tmp->data;
-
- end[i] = w->xwindow;
-
- /* add to the main list */
- stack->sorted = g_list_prepend (stack->sorted, w);
-
- ++i;
- tmp = tmp->next;
- }
-
- stack->need_resort = TRUE; /* may not be needed as we add to top */
- stack->need_constrain = TRUE;
- stack->need_relayer = TRUE;
- }
-
- g_list_free (stack->added);
- stack->added = NULL;
-}
-
-/**
- * Update the layers that windows are in
- */
-static void
-stack_do_relayer (MetaStack *stack)
-{
- GList *tmp;
-
- if (!stack->need_relayer)
- return;
-
- meta_topic (META_DEBUG_STACK,
- "Recomputing layers\n");
-
- tmp = stack->sorted;
-
- while (tmp != NULL)
- {
- MetaWindow *w;
- MetaStackLayer old_layer;
-
- w = tmp->data;
- old_layer = w->layer;
-
- compute_layer (w);
-
- if (w->layer != old_layer)
- {
- meta_topic (META_DEBUG_STACK,
- "Window %s moved from layer %u to %u\n",
- w->desc, old_layer, w->layer);
-
- stack->need_resort = TRUE;
- stack->need_constrain = TRUE;
- /* don't need to constrain as constraining
- * purely operates in terms of stack_position
- * not layer
- */
- }
-
- tmp = tmp->next;
- }
-
- stack->need_relayer = FALSE;
-}
-
-/**
- * Update stack_position and layer to reflect transiency
- * constraints
- */
-static void
-stack_do_constrain (MetaStack *stack)
-{
- Constraint **constraints;
-
- /* It'd be nice if this were all faster, probably */
-
- if (!stack->need_constrain)
- return;
-
- meta_topic (META_DEBUG_STACK,
- "Reapplying constraints\n");
-
- constraints = g_new0 (Constraint*,
- stack->n_positions);
-
- create_constraints (constraints, stack->sorted);
-
- graph_constraints (constraints, stack->n_positions);
-
- apply_constraints (constraints, stack->n_positions);
-
- free_constraints (constraints, stack->n_positions);
- g_free (constraints);
-
- stack->need_constrain = FALSE;
-}
-
-/**
- * Sort stack->sorted with layers having priority over stack_position.
- */
-static void
-stack_do_resort (MetaStack *stack)
-{
- if (!stack->need_resort)
- return;
-
- meta_topic (META_DEBUG_STACK,
- "Sorting stack list\n");
-
- stack->sorted = g_list_sort (stack->sorted,
- (GCompareFunc) compare_window_position);
-
- stack->need_resort = FALSE;
-}
-
-/**
- * Puts the stack into canonical form.
- *
- * Honour the removed and added lists of the stack, and then recalculate
- * all the layers (if the flag is set), re-run all the constraint calculations
- * (if the flag is set), and finally re-sort the stack (if the flag is set,
- * and if it wasn't already it might have become so during all the previous
- * activity).
- */
-static void
-stack_ensure_sorted (MetaStack *stack)
-{
- stack_do_window_deletions (stack);
- stack_do_window_additions (stack);
- stack_do_relayer (stack);
- stack_do_constrain (stack);
- stack_do_resort (stack);
-}
-
-/**
- * This function is used to avoid raising a window above popup
- * menus and other such things.
- *
- * FIXME This is sort of an expensive function, should probably
- * do something to avoid it. One approach would be to reverse
- * the stacking algorithm to work by placing each window above
- * the others, and start by lowering a window to the bottom
- * (instead of the current way, which works by placing each
- * window below another and starting with a raise)
- */
-static void
-raise_window_relative_to_managed_windows (MetaScreen *screen,
- Window xwindow)
-{
-
- Window ignored1, ignored2;
- Window *children;
- unsigned int n_children;
- int i;
-
- /* Normally XQueryTree() means "must grab server" but here
- * we don't, since we know we won't manage any new windows
- * or restack any windows before using the XQueryTree results.
- */
-
- meta_error_trap_push_with_return (screen->display);
-
- XQueryTree (screen->display->xdisplay,
- screen->xroot,
- &ignored1, &ignored2, &children, &n_children);
-
- if (meta_error_trap_pop_with_return (screen->display, TRUE) != Success)
- {
- meta_topic (META_DEBUG_STACK,
- "Error querying root children to raise window 0x%lx\n",
- xwindow);
- return;
- }
-
- /* Children are in order from bottom to top. We want to
- * find the topmost managed child, then configure
- * our window to be above it.
- */
- i = n_children - 1;
- while (i >= 0)
- {
- if (children[i] == xwindow)
- {
- /* Do nothing. This means we're already the topmost managed
- * window, but it DOES NOT mean we are already just above
- * the topmost managed window. This is important because if
- * an override redirect window is up, and we map a new
- * managed window, the new window is probably above the old
- * popup by default, and we want to push it below that
- * popup. So keep looking for a sibling managed window
- * to be moved below.
- */
- }
- else if (meta_display_lookup_x_window (screen->display,
- children[i]) != NULL)
- {
- XWindowChanges changes;
-
- /* children[i] is the topmost managed child */
- meta_topic (META_DEBUG_STACK,
- "Moving 0x%lx above topmost managed child window 0x%lx\n",
- xwindow, children[i]);
-
- changes.sibling = children[i];
- changes.stack_mode = Above;
-
- meta_error_trap_push (screen->display);
- XConfigureWindow (screen->display->xdisplay,
- xwindow,
- CWSibling | CWStackMode,
- &changes);
- meta_error_trap_pop (screen->display, FALSE);
-
- break;
- }
-
- --i;
- }
-
- if (i < 0)
- {
- /* No sibling to use, just lower ourselves to the bottom
- * to be sure we're below any override redirect windows.
- */
- meta_error_trap_push (screen->display);
- XLowerWindow (screen->display->xdisplay,
- xwindow);
- meta_error_trap_pop (screen->display, FALSE);
- }
-
- if (children)
- XFree (children);
-}
-
-/**
- * Order the windows on the X server to be the same as in our structure.
- * We do this using XRestackWindows if we don't know the previous order,
- * or XConfigureWindow on a few particular windows if we do and can figure
- * out the minimum set of changes. After that, we set __NET_CLIENT_LIST
- * and __NET_CLIENT_LIST_STACKING.
- */
-static void
-stack_sync_to_server (MetaStack *stack)
-{
- GArray *stacked;
- GArray *root_children_stacked;
- GList *tmp;
-
- /* Bail out if frozen */
- if (stack->freeze_count > 0)
- return;
-
- meta_topic (META_DEBUG_STACK, "Syncing window stack to server\n");
-
- stack_ensure_sorted (stack);
-
- /* Create stacked xwindow arrays.
- * Painfully, "stacked" is in bottom-to-top order for the
- * _NET hints, and "root_children_stacked" is in top-to-bottom
- * order for XRestackWindows()
- */
- stacked = g_array_new (FALSE, FALSE, sizeof (Window));
- root_children_stacked = g_array_new (FALSE, FALSE, sizeof (Window));
-
- meta_topic (META_DEBUG_STACK, "Top to bottom: ");
- meta_push_no_msg_prefix ();
-
- tmp = stack->sorted;
- while (tmp != NULL)
- {
- MetaWindow *w;
-
- w = tmp->data;
-
- /* remember, stacked is in reverse order (bottom to top) */
- g_array_prepend_val (stacked, w->xwindow);
-
- /* build XRestackWindows() array from top to bottom */
- if (w->frame)
- g_array_append_val (root_children_stacked, w->frame->xwindow);
- else
- g_array_append_val (root_children_stacked, w->xwindow);
-
- meta_topic (META_DEBUG_STACK, "%u:%d - %s ", w->layer, w->stack_position, w->desc);
-
- tmp = tmp->next;
- }
-
- meta_topic (META_DEBUG_STACK, "\n");
- meta_pop_no_msg_prefix ();
-
- /* All windows should be in some stacking order */
- if (stacked->len != stack->windows->len)
- meta_bug ("%u windows stacked, %u windows exist in stack\n",
- stacked->len, stack->windows->len);
-
- /* Sync to server */
-
- meta_topic (META_DEBUG_STACK, "Restacking %u windows\n",
- root_children_stacked->len);
-
- meta_error_trap_push (stack->screen->display);
-
- if (stack->last_root_children_stacked == NULL)
- {
- /* Just impose our stack, we don't know the previous state.
- * This involves a ton of circulate requests and may flicker.
- */
- meta_topic (META_DEBUG_STACK, "Don't know last stack state, restacking everything\n");
-
- if (root_children_stacked->len > 0)
- XRestackWindows (stack->screen->display->xdisplay,
- (Window *) root_children_stacked->data,
- root_children_stacked->len);
- }
- else if (root_children_stacked->len > 0)
- {
- /* Try to do minimal window moves to get the stack in order */
- /* A point of note: these arrays include frames not client windows,
- * so if a client window has changed frame since last_root_children_stacked
- * was saved, then we may have inefficiency, but I don't think things
- * break...
- */
- const Window *old_stack = (Window *) stack->last_root_children_stacked->data;
- const Window *new_stack = (Window *) root_children_stacked->data;
- const int old_len = stack->last_root_children_stacked->len;
- const int new_len = root_children_stacked->len;
- const Window *oldp = old_stack;
- const Window *newp = new_stack;
- const Window *old_end = old_stack + old_len;
- const Window *new_end = new_stack + new_len;
- Window last_window = None;
-
- while (oldp != old_end &&
- newp != new_end)
- {
- if (*oldp == *newp)
- {
- /* Stacks are the same here, move on */
- ++oldp;
- last_window = *newp;
- ++newp;
- }
- else if (meta_display_lookup_x_window (stack->screen->display,
- *oldp) == NULL)
- {
- /* *oldp is no longer known to us (probably destroyed),
- * so we can just skip it
- */
- ++oldp;
- }
- else
- {
- /* Move *newp below last_window */
- if (last_window == None)
- {
- meta_topic (META_DEBUG_STACK, "Using window 0x%lx as topmost (but leaving it in-place)\n", *newp);
-
- raise_window_relative_to_managed_windows (stack->screen,
- *newp);
- }
- else
- {
- /* This means that if last_window is dead, but not
- * *newp, then we fail to restack *newp; but on
- * unmanaging last_window, we'll fix it up.
- */
-
- XWindowChanges changes;
-
- changes.sibling = last_window;
- changes.stack_mode = Below;
-
- meta_topic (META_DEBUG_STACK, "Placing window 0x%lx below 0x%lx\n",
- *newp, last_window);
-
- XConfigureWindow (stack->screen->display->xdisplay,
- *newp,
- CWSibling | CWStackMode,
- &changes);
- }
-
- last_window = *newp;
- ++newp;
- }
- }
-
- if (newp != new_end)
- {
- /* Restack remaining windows */
- meta_topic (META_DEBUG_STACK, "Restacking remaining %d windows\n",
- (int) (new_end - newp));
- /* We need to include an already-stacked window
- * in the restack call, so we get in the proper position
- * with respect to it.
- */
- if (newp != new_stack)
- --newp;
- XRestackWindows (stack->screen->display->xdisplay,
- (Window *) newp, new_end - newp);
- }
- }
-
- meta_error_trap_pop (stack->screen->display, FALSE);
- /* on error, a window was destroyed; it should eventually
- * get removed from the stacking list when we unmanage it
- * and we'll fix stacking at that time.
- */
-
- /* Sync _NET_CLIENT_LIST and _NET_CLIENT_LIST_STACKING */
-
- XChangeProperty (stack->screen->display->xdisplay,
- stack->screen->xroot,
- stack->screen->display->atom__NET_CLIENT_LIST,
- XA_WINDOW,
- 32, PropModeReplace,
- (unsigned char *)stack->windows->data,
- stack->windows->len);
- XChangeProperty (stack->screen->display->xdisplay,
- stack->screen->xroot,
- stack->screen->display->atom__NET_CLIENT_LIST_STACKING,
- XA_WINDOW,
- 32, PropModeReplace,
- (unsigned char *)stacked->data,
- stacked->len);
-
- g_array_free (stacked, TRUE);
-
- if (stack->last_root_children_stacked)
- g_array_free (stack->last_root_children_stacked, TRUE);
- stack->last_root_children_stacked = root_children_stacked;
-
- /* That was scary... */
-}
-
-MetaWindow*
-meta_stack_get_top (MetaStack *stack)
-{
- stack_ensure_sorted (stack);
-
- if (stack->sorted)
- return stack->sorted->data;
- else
- return NULL;
-}
-
-MetaWindow*
-meta_stack_get_bottom (MetaStack *stack)
-{
- GList *link;
-
- stack_ensure_sorted (stack);
-
- link = g_list_last (stack->sorted);
- if (link != NULL)
- return link->data;
- else
- return NULL;
-}
-
-MetaWindow*
-meta_stack_get_above (MetaStack *stack,
- MetaWindow *window,
- gboolean only_within_layer)
-{
- GList *link;
- MetaWindow *above;
-
- stack_ensure_sorted (stack);
-
- link = g_list_find (stack->sorted, window);
- if (link == NULL)
- return NULL;
- if (link->prev == NULL)
- return NULL;
-
- above = link->prev->data;
-
- if (only_within_layer &&
- above->layer != window->layer)
- return NULL;
- else
- return above;
-}
-
-MetaWindow*
-meta_stack_get_below (MetaStack *stack,
- MetaWindow *window,
- gboolean only_within_layer)
-{
- GList *link;
- MetaWindow *below;
-
- stack_ensure_sorted (stack);
-
- link = g_list_find (stack->sorted, window);
-
- if (link == NULL)
- return NULL;
- if (link->next == NULL)
- return NULL;
-
- below = link->next->data;
-
- if (only_within_layer &&
- below->layer != window->layer)
- return NULL;
- else
- return below;
-}
-
-static gboolean
-window_contains_point (MetaWindow *window,
- int root_x,
- int root_y)
-{
- MetaRectangle rect;
-
- meta_window_get_outer_rect (window, &rect);
-
- return POINT_IN_RECT (root_x, root_y, rect);
-}
-
-static MetaWindow*
-get_default_focus_window (MetaStack *stack,
- MetaWorkspace *workspace,
- MetaWindow *not_this_one,
- gboolean must_be_at_point,
- int root_x,
- int root_y)
-{
- /* Find the topmost, focusable, mapped, window.
- * not_this_one is being unfocused or going away, so exclude it.
- * Also, prefer to focus transient parent of not_this_one,
- * or top window in same group as not_this_one.
- */
-
- MetaWindow *topmost_dock;
- MetaWindow *transient_parent;
- MetaWindow *topmost_in_group;
- MetaWindow *topmost_overall;
- MetaGroup *not_this_one_group;
- GList *link;
-
- topmost_dock = NULL;
- transient_parent = NULL;
- topmost_in_group = NULL;
- topmost_overall = NULL;
- if (not_this_one)
- not_this_one_group = meta_window_get_group (not_this_one);
- else
- not_this_one_group = NULL;
-
- stack_ensure_sorted (stack);
-
- /* top of this layer is at the front of the list */
- link = stack->sorted;
-
- while (link)
- {
- MetaWindow *window = link->data;
-
- if (window &&
- window != not_this_one &&
- (window->unmaps_pending == 0) &&
- !window->minimized &&
- (window->input || window->take_focus) &&
- (workspace == NULL ||
- meta_window_located_on_workspace (window, workspace)))
- {
- if (topmost_dock == NULL &&
- window->type == META_WINDOW_DOCK)
- topmost_dock = window;
-
- if (not_this_one != NULL)
- {
- if (transient_parent == NULL &&
- not_this_one->xtransient_for != None &&
- not_this_one->xtransient_for == window->xwindow &&
- (!must_be_at_point ||
- window_contains_point (window, root_x, root_y)))
- transient_parent = window;
-
- if (topmost_in_group == NULL &&
- not_this_one_group != NULL &&
- not_this_one_group == meta_window_get_group (window) &&
- (!must_be_at_point ||
- window_contains_point (window, root_x, root_y)))
- topmost_in_group = window;
- }
-
- /* Note that DESKTOP windows can be topmost_overall so
- * we prefer focusing desktop or other windows over
- * focusing dock, even though docks are stacked higher.
- */
- if (topmost_overall == NULL &&
- window->type != META_WINDOW_DOCK &&
- (!must_be_at_point ||
- window_contains_point (window, root_x, root_y)))
- topmost_overall = window;
-
- /* We could try to bail out early here for efficiency in
- * some cases, but it's just not worth the code.
- */
- }
-
- link = link->next;
- }
-
- if (transient_parent)
- return transient_parent;
- else if (topmost_in_group)
- return topmost_in_group;
- else if (topmost_overall)
- return topmost_overall;
- else
- return topmost_dock;
-}
-
-MetaWindow*
-meta_stack_get_default_focus_window_at_point (MetaStack *stack,
- MetaWorkspace *workspace,
- MetaWindow *not_this_one,
- int root_x,
- int root_y)
-{
- return get_default_focus_window (stack, workspace, not_this_one,
- TRUE, root_x, root_y);
-}
-
-MetaWindow*
-meta_stack_get_default_focus_window (MetaStack *stack,
- MetaWorkspace *workspace,
- MetaWindow *not_this_one)
-{
- return get_default_focus_window (stack, workspace, not_this_one,
- FALSE, 0, 0);
-}
-
-GList*
-meta_stack_list_windows (MetaStack *stack,
- MetaWorkspace *workspace)
-{
- GList *workspace_windows = NULL;
- GList *link;
-
- stack_ensure_sorted (stack); /* do adds/removes */
-
- link = stack->sorted;
-
- while (link)
- {
- MetaWindow *window = link->data;
-
- if (window &&
- (workspace == NULL || meta_window_located_on_workspace (window, workspace)))
- {
- workspace_windows = g_list_prepend (workspace_windows,
- window);
- }
-
- link = link->next;
- }
-
- return workspace_windows;
-}
-
-int
-meta_stack_windows_cmp (MetaStack *stack,
- MetaWindow *window_a,
- MetaWindow *window_b)
-{
- g_return_val_if_fail (window_a->screen == window_b->screen, 0);
-
- /* -1 means a below b */
-
- stack_ensure_sorted (stack); /* update constraints, layers */
-
- if (window_a->layer < window_b->layer)
- return -1;
- else if (window_a->layer > window_b->layer)
- return 1;
- else if (window_a->stack_position < window_b->stack_position)
- return -1;
- else if (window_a->stack_position > window_b->stack_position)
- return 1;
- else
- return 0; /* not reached */
-}
-
-static int
-compare_just_window_stack_position (void *a,
- void *b)
-{
- MetaWindow *window_a = a;
- MetaWindow *window_b = b;
-
- if (window_a->stack_position < window_b->stack_position)
- return -1; /* move window_a earlier in list */
- else if (window_a->stack_position > window_b->stack_position)
- return 1;
- else
- return 0; /* not reached */
-}
-
-GList*
-meta_stack_get_positions (MetaStack *stack)
-{
- GList *tmp;
-
- /* Make sure to handle any adds or removes */
- stack_ensure_sorted (stack);
-
- tmp = g_list_copy (stack->sorted);
- tmp = g_list_sort (tmp, (GCompareFunc) compare_just_window_stack_position);
-
- return tmp;
-}
-
-static gint
-compare_pointers (gconstpointer a,
- gconstpointer b)
-{
- if (a > b)
- return 1;
- else if (a < b)
- return -1;
- else
- return 0;
-}
-
-static gboolean
-lists_contain_same_windows (GList *a,
- GList *b)
-{
- GList *copy1, *copy2;
- GList *tmp1, *tmp2;
-
- if (g_list_length (a) != g_list_length (b))
- return FALSE;
-
- tmp1 = copy1 = g_list_sort (g_list_copy (a), compare_pointers);
- tmp2 = copy2 = g_list_sort (g_list_copy (b), compare_pointers);
-
- while (tmp1 && tmp1->data == tmp2->data) /* tmp2 is non-NULL if tmp1 is */
- {
- tmp1 = tmp1->next;
- tmp2 = tmp2->next;
- }
-
- g_list_free (copy1);
- g_list_free (copy2);
-
- return (tmp1 == NULL); /* tmp2 is non-NULL if tmp1 is */
-}
-
-void
-meta_stack_set_positions (MetaStack *stack,
- GList *windows)
-{
- int i;
- GList *tmp;
-
- /* Make sure any adds or removes aren't in limbo -- is this needed? */
- stack_ensure_sorted (stack);
-
- if (!lists_contain_same_windows (windows, stack->sorted))
- {
- meta_warning ("This list of windows has somehow changed; not resetting "
- "positions of the windows.\n");
- return;
- }
-
- g_list_free (stack->sorted);
- stack->sorted = g_list_copy (windows);
-
- stack->need_resort = TRUE;
- stack->need_constrain = TRUE;
-
- i = 0;
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
- w->stack_position = i++;
- tmp = tmp->next;
- }
-
- meta_topic (META_DEBUG_STACK,
- "Reset the stack positions of (nearly) all windows\n");
-
- stack_sync_to_server (stack);
-}
-
-void
-meta_window_set_stack_position_no_sync (MetaWindow *window,
- int position)
-{
- int low, high, delta;
- GList *tmp;
-
- g_return_if_fail (window->screen->stack != NULL);
- g_return_if_fail (window->stack_position >= 0);
- g_return_if_fail (position >= 0);
- g_return_if_fail (position < window->screen->stack->n_positions);
-
- if (position == window->stack_position)
- {
- meta_topic (META_DEBUG_STACK, "Window %s already has position %d\n",
- window->desc, position);
- return;
- }
-
- window->screen->stack->need_resort = TRUE;
- window->screen->stack->need_constrain = TRUE;
-
- if (position < window->stack_position)
- {
- low = position;
- high = window->stack_position - 1;
- delta = 1;
- }
- else
- {
- low = window->stack_position + 1;
- high = position;
- delta = -1;
- }
-
- tmp = window->screen->stack->sorted;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
-
- if (w->stack_position >= low &&
- w->stack_position <= high)
- w->stack_position += delta;
-
- tmp = tmp->next;
- }
-
- window->stack_position = position;
-
- meta_topic (META_DEBUG_STACK,
- "Window %s had stack_position set to %d\n",
- window->desc, window->stack_position);
-}
-
-void
-meta_window_set_stack_position (MetaWindow *window,
- int position)
-{
- meta_window_set_stack_position_no_sync (window, position);
- stack_sync_to_server (window->screen->stack);
-}
diff --git a/src/core/stack.h b/src/core/stack.h
deleted file mode 100644
index f9693897..00000000
--- a/src/core/stack.h
+++ /dev/null
@@ -1,402 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * \file stack.h Which windows cover which other windows
- *
- * There are two factors that determine window position.
- *
- * One is window->stack_position, which is a unique integer
- * indicating how windows are ordered with respect to one
- * another. The ordering here transcends layers; it isn't changed
- * as the window is moved among layers. This allows us to move several
- * windows from one layer to another, while preserving the relative
- * order of the moved windows. Also, it allows us to restore
- * the stacking order from a saved session.
- *
- * However when actually stacking windows on the screen, the
- * layer overrides the stack_position; windows are first sorted
- * by layer, then by stack_position within each layer.
- */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2005 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_STACK_H
-#define META_STACK_H
-
-#include "screen-private.h"
-
-/**
- * Layers a window can be in.
- * These MUST be in the order of stacking.
- */
-typedef enum
-{
- META_LAYER_DESKTOP = 0,
- META_LAYER_BOTTOM = 1,
- META_LAYER_NORMAL = 2,
- META_LAYER_TOP = 4, /* Same as DOCK; see EWMH and bug 330717 */
- META_LAYER_DOCK = 4,
- META_LAYER_FULLSCREEN = 5,
- META_LAYER_FOCUSED_WINDOW = 6,
- META_LAYER_LAST = 7
-} MetaStackLayer;
-
-/**
- * A sorted list of windows bearing some level of resemblance to the stack of
- * windows on the X server.
- *
- * (This is only used as a field within a MetaScreen; we treat it as a separate
- * class for simplicity.)
- */
-struct _MetaStack
-{
- /** The MetaScreen containing this stack. */
- MetaScreen *screen;
-
- /**
- * A sequence of all the Windows (X handles, not MetaWindows) of the windows
- * we manage, sorted in order. Suitable to be passed into _NET_CLIENT_LIST.
- */
- GArray *windows;
-
- /** The MetaWindows of the windows we manage, sorted in order. */
- GList *sorted;
-
- /**
- * MetaWindows waiting to be added to the "sorted" and "windows" list, after
- * being added by meta_stack_add() and before being assimilated by
- * stack_ensure_sorted().
- *
- * The order of the elements in this list is not important; what is important
- * is the stack_position element of each window.
- */
- GList *added;
-
- /**
- * Windows (X handles, not MetaWindows) waiting to be removed from the
- * "windows" list, after being removed by meta_stack_remove() and before
- * being assimilated by stack_ensure_sorted(). (We already removed them
- * from the "sorted" list.)
- *
- * The order of the elements in this list is not important.
- */
- GList *removed;
-
- /**
- * If this is zero, the local stack oughtn't to be brought up to date with
- * the X server's stack, because it is in the middle of being updated.
- * If it is positive, the local stack is said to be "frozen", and will need
- * to be thawed that many times before the stack can be brought up to date
- * again. You may freeze the stack with meta_stack_freeze() and thaw it
- * with meta_stack_thaw().
- */
- int freeze_count;
-
- /**
- * The last-known stack of all windows, bottom to top. We cache it here
- * so that subsequent times we'll be able to do incremental moves.
- */
- GArray *last_root_children_stacked;
-
- /**
- * Number of stack positions; same as the length of added, but
- * kept for quick reference.
- */
- gint n_positions;
-
- /** Is the stack in need of re-sorting? */
- unsigned int need_resort : 1;
-
- /**
- * Are the windows in the stack in need of having their
- * layers recalculated?
- */
- unsigned int need_relayer : 1;
-
- /**
- * Are the windows in the stack in need of having their positions
- * recalculated with respect to transiency (parent and child windows)?
- */
- unsigned int need_constrain : 1;
-};
-
-/**
- * Creates and initialises a MetaStack.
- *
- * \param screen The MetaScreen which will be the parent of this stack.
- * \return The new screen.
- */
-MetaStack *meta_stack_new (MetaScreen *screen);
-
-/**
- * Destroys and frees a MetaStack.
- *
- * \param stack The stack to destroy.
- */
-void meta_stack_free (MetaStack *stack);
-
-/**
- * Adds a window to the local stack. It is a fatal error to call this
- * function on a window which already exists on the stack of any screen.
- *
- * \param window The window to add
- * \param stack The stack to add it to
- */
-void meta_stack_add (MetaStack *stack,
- MetaWindow *window);
-
-/**
- * Removes a window from the local stack. It is a fatal error to call this
- * function on a window which exists on the stack of any screen.
- *
- * \param window The window to remove
- * \param stack The stack to remove it from
- */
-void meta_stack_remove (MetaStack *stack,
- MetaWindow *window);
-/**
- * Recalculates the correct layer for all windows in the stack,
- * and moves them about accordingly.
- *
- * \param window Dummy parameter
- * \param stack The stack to recalculate
- * \bug What's with the dummy parameter?
- */
-void meta_stack_update_layer (MetaStack *stack,
- MetaWindow *window);
-
-/**
- * Recalculates the correct stacking order for all windows in the stack
- * according to their transience, and moves them about accordingly.
- *
- * \param window Dummy parameter
- * \param stack The stack to recalculate
- * \bug What's with the dummy parameter?
- */
-void meta_stack_update_transient (MetaStack *stack,
- MetaWindow *window);
-
-/**
- * Move a window to the top of its layer.
- *
- * \param stack The stack to modify.
- * \param window The window that's making an ascension.
- * (Amulet of Yendor not required.)
- */
-void meta_stack_raise (MetaStack *stack,
- MetaWindow *window);
-/**
- * Move a window to the bottom of its layer.
- *
- * \param stack The stack to modify.
- * \param window The window that's on the way downwards.
- */
-void meta_stack_lower (MetaStack *stack,
- MetaWindow *window);
-
-/**
- * Prevent syncing to server until the next call of meta_stack_thaw(),
- * so that we can carry out multiple operations in one go without having
- * everything halfway reflected on the X server.
- *
- * (Calls to meta_stack_freeze() nest, so that multiple calls to
- * meta_stack_freeze will require multiple calls to meta_stack_thaw().)
- *
- * \param stack The stack to freeze.
- */
-void meta_stack_freeze (MetaStack *stack);
-
-/**
- * Undoes a meta_stack_freeze(), and processes anything which has become
- * necessary during the freeze. It is an error to call this function if
- * the stack has not been frozen.
- *
- * \param stack The stack to thaw.
- */
-void meta_stack_thaw (MetaStack *stack);
-
-/**
- * Finds the top window on the stack.
- *
- * \param stack The stack to examine.
- * \return The top window on the stack, or NULL in the vanishingly unlikely
- * event that you have no windows on your screen whatsoever.
- */
-MetaWindow* meta_stack_get_top (MetaStack *stack);
-
-/**
- * Finds the window at the bottom of the stack. Since that's pretty much
- * always the desktop, this isn't the most useful of functions, and nobody
- * actually calls it. We should probably get rid of it.
- *
- * \param stack The stack to search
- */
-MetaWindow* meta_stack_get_bottom (MetaStack *stack);
-
-/**
- * Finds the window above a given window in the stack.
- * It is not an error to pass in a window which does not exist in
- * the stack; the function will merely return NULL.
- *
- * \param stack The stack to search.
- * \param window The window to look above.
- * \param only_within_layer If true, will return NULL if "window" is the
- * top window in its layer.
- * \return NULL if there is no such window;
- * the window above "window" otherwise.
- */
-MetaWindow* meta_stack_get_above (MetaStack *stack,
- MetaWindow *window,
- gboolean only_within_layer);
-
-/**
- * Finds the window below a given window in the stack.
- * It is not an error to pass in a window which does not exist in
- * the stack; the function will merely return NULL.
- *
- * \param stack The stack to search.
- * \param window The window to look below.
- * \param only_within_layer If true, will return NULL if "window" is the
- * bottom window in its layer.
- * \return NULL if there is no such window;
- * the window below "window" otherwise.
- */
-MetaWindow* meta_stack_get_below (MetaStack *stack,
- MetaWindow *window,
- gboolean only_within_layer);
-
-/**
- * Find the topmost, focusable, mapped, window in a stack. If you supply
- * a window as "not_this_one", we won't return that one (presumably
- * because it's going to be going away). But if you do supply "not_this_one"
- * and we find its parent, we'll return that; and if "not_this_one" is in
- * a group, we'll return the top window of that group.
- *
- * Also, we are prejudiced against dock windows. Every kind of window, even
- * the desktop, will be returned in preference to a dock window.
- *
- * \param stack The stack to search.
- * \param workspace NULL to search all workspaces; otherwise only windows
- * from that workspace will be returned.
- * \param not_this_one Window to ignore because it's being unfocussed or
- * going away.
- * \return The window matching all these constraints or NULL if none does.
- *
- * \bug Never called!
- */
-MetaWindow* meta_stack_get_default_focus_window (MetaStack *stack,
- MetaWorkspace *workspace,
- MetaWindow *not_this_one);
-
-/**
- * Find the topmost, focusable, mapped, window in a stack. If you supply
- * a window as "not_this_one", we won't return that one (presumably
- * because it's going to be going away). But if you do supply "not_this_one"
- * and we find its parent, we'll return that; and if "not_this_one" is in
- * a group, we'll return the top window of that group.
- *
- * Also, we are prejudiced against dock windows. Every kind of window, even
- * the desktop, will be returned in preference to a dock window.
- *
- * \param stack The stack to search.
- * \param workspace NULL to search all workspaces; otherwise only windows
- * from that workspace will be returned.
- * \param not_this_one Window to ignore because it's being unfocussed or
- * going away.
- * \param root_x The returned window must contain this point,
- * unless it's a dock.
- * \param root_y See root_x.
- * \return The window matching all these constraints or NULL if none does.
- */
-MetaWindow* meta_stack_get_default_focus_window_at_point (MetaStack *stack,
- MetaWorkspace *workspace,
- MetaWindow *not_this_one,
- int root_x,
- int root_y);
-
-/**
- * Finds all the windows in the stack, in order.
- *
- * \param stack The stack to examine.
- * \param workspace If non-NULL, only windows on this workspace will be
- * returned; otherwise all windows in the stack will be
- * returned.
- * \return A list of windows, in stacking order, honouring layers.
- */
-GList* meta_stack_list_windows (MetaStack *stack,
- MetaWorkspace *workspace);
-
-/**
- * Comparison function for windows within a stack. This is not directly
- * suitable for use within a standard comparison routine, because it takes
- * an extra parameter; you will need to wrap it.
- *
- * (FIXME: We could remove the stack parameter and use the stack of
- * the screen of window A, and complain if the stack of the screen of
- * window B differed; then this would be a usable general comparison function.)
- *
- * (FIXME: Apparently identical to compare_window_position(). Merge them.)
- *
- * \param stack A stack containing both window_a and window_b
- * \param window_a A window
- * \param window_b Another window
- * \return -1 if window_a is below window_b, honouring layers; 1 if it's
- * above it; 0 if you passed in the same window twice!
- */
-int meta_stack_windows_cmp (MetaStack *stack,
- MetaWindow *window_a,
- MetaWindow *window_b);
-
-/**
- * Sets the position of a window within the stack. This will only move it
- * up or down within its layer. It is an error to attempt to move this
- * below position zero or above the last position in the stack (however, since
- * we don't provide a simple way to tell the number of windows in the stack,
- * this requirement may not be easy to fulfil).
- *
- * \param window The window which is moving.
- * \param position Where it should move to (0 is the bottom).
- */
-void meta_window_set_stack_position (MetaWindow *window,
- int position);
-
-/**
- * Returns the current stack state, allowing rudimentary transactions.
- *
- * \param stack The stack to examine.
- * \return An opaque GList representing the current stack sort order;
- * it is the caller's responsibility to free it.
- * Pass this to meta_stack_set_positions() later if you want to restore
- * the state to where it was when you called this function.
- */
-GList* meta_stack_get_positions (MetaStack *stack);
-
-/**
- * Rolls back a transaction, given the list returned from
- * meta_stack_get_positions().
- *
- * \param stack The stack to roll back.
- * \param windows The list returned from meta_stack_get_positions().
- */
-void meta_stack_set_positions (MetaStack *stack,
- GList *windows);
-
-#endif
diff --git a/src/core/testasyncgetprop.c b/src/core/testasyncgetprop.c
deleted file mode 100644
index 03182680..00000000
--- a/src/core/testasyncgetprop.c
+++ /dev/null
@@ -1,497 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2002 Havoc Pennington
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without
- * fee, provided that the above copyright notice appear in all copies
- * and that both that copyright notice and this permission notice
- * appear in supporting documentation.
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of The Open Group shall not be
- * used in advertising or otherwise to promote the sale, use or other dealings
- * in this Software without prior written authorization from The Open Group.
- */
-
-#include "async-getprop.h"
-
-#include <time.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <signal.h>
-#include <assert.h>
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef NULL
-#define NULL ((void*) 0)
-#endif
-
-#ifdef HAVE_BACKTRACE
-#include <execinfo.h>
-static void
-print_backtrace (void)
-{
- void *bt[500];
- int bt_size;
- int i;
- char **syms;
-
- bt_size = backtrace (bt, 500);
-
- syms = backtrace_symbols (bt, bt_size);
-
- i = 0;
- while (i < bt_size)
- {
- fprintf (stderr, " %s\n", syms[i]);
- ++i;
- }
-
- free (syms);
-}
-#else
-static void
-print_backtrace (void)
-{
- fprintf (stderr, "Not compiled with backtrace support\n");
-}
-#endif
-
-static int error_trap_depth = 0;
-
-static int
-x_error_handler (Display *xdisplay,
- XErrorEvent *error)
-{
- char buf[64];
-
- XGetErrorText (xdisplay, error->error_code, buf, 63);
-
- if (error_trap_depth == 0)
- {
- print_backtrace ();
-
- fprintf (stderr, "Unexpected X error: %s serial %ld error_code %d request_code %d minor_code %d)\n",
- buf,
- error->serial,
- error->error_code,
- error->request_code,
- error->minor_code);
-
- exit (1);
- }
-
- return 1; /* return value is meaningless */
-}
-
-static void
-error_trap_push (Display *xdisplay)
-{
- ++error_trap_depth;
-}
-
-static void
-error_trap_pop (Display *xdisplay)
-{
- if (error_trap_depth == 0)
- {
- fprintf (stderr, "Error trap underflow!\n");
- exit (1);
- }
-
- XSync (xdisplay, False); /* get all errors out of the queue */
- --error_trap_depth;
-}
-
-static char*
-my_strdup (const char *str)
-{
- char *s;
-
- s = malloc (strlen (str) + 1);
- if (s == NULL)
- {
- fprintf (stderr, "malloc failed\n");
- exit (1);
- }
- strcpy (s, str);
-
- return s;
-}
-
-static char*
-atom_name (Display *display,
- Atom atom)
-{
- if (atom == None)
- {
- return my_strdup ("None");
- }
- else
- {
- char *xname;
- char *ret;
-
- error_trap_push (display);
- xname = XGetAtomName (display, atom);
- error_trap_pop (display);
- if (xname == NULL)
- return my_strdup ("[unknown atom]");
-
- ret = my_strdup (xname);
- XFree (xname);
-
- return ret;
- }
-}
-
-
-#define ELAPSED(start_time, current_time) \
- (((((double)current_time.tv_sec - start_time.tv_sec) * 1000000 + \
- (current_time.tv_usec - start_time.tv_usec))) / 1000.0)
-
-static struct timeval program_start_time;
-
-static Bool
-try_get_reply (Display *xdisplay,
- AgGetPropertyTask *task)
-{
- if (ag_task_have_reply (task))
- {
- int result;
- Atom actual_type;
- int actual_format;
- unsigned long n_items;
- unsigned long bytes_after;
- unsigned char *data;
- char *name;
- struct timeval current_time;
-
- gettimeofday (&current_time, NULL);
-
- printf (" %gms (we have a reply for property %ld)\n",
- ELAPSED (program_start_time, current_time),
- ag_task_get_property (task));
-
- data = NULL;
-
- name = atom_name (xdisplay,
- ag_task_get_property (task));
- printf (" %s on 0x%lx:\n", name,
- ag_task_get_window (task));
- free (name);
-
- result = ag_task_get_reply_and_free (task,
- &actual_type,
- &actual_format,
- &n_items,
- &bytes_after,
- &data);
- task = NULL;
-
- if (result != Success)
- {
- fprintf (stderr, " error code %d getting reply\n", result);
- }
- else
- {
- name = atom_name (xdisplay, actual_type);
- printf (" actual_type = %s\n", name);
- free (name);
-
- printf (" actual_format = %d\n", actual_format);
-
- printf (" n_items = %lu\n", n_items);
- printf (" bytes_after = %lu\n", bytes_after);
-
- printf (" data = \"%s\"\n", data ? (char*) data : "NULL");
- }
-
- return True;
- }
-
- return False;
-}
-
-static void run_speed_comparison (Display *xdisplay,
- Window window);
-
-int
-main (int argc, char **argv)
-{
- Display *xdisplay;
- int i;
- int n_left;
- int n_props;
- Window window;
- const char *window_str;
- char *end;
- Atom *props;
- struct timeval current_time;
-
- if (argc < 2)
- {
- fprintf (stderr, "specify window ID\n");
- return 1;
- }
-
- window_str = argv[1];
-
- end = NULL;
- window = strtoul (window_str, &end, 0);
- if (end == NULL || *end != '\0')
- {
- fprintf (stderr, "\"%s\" does not parse as a window ID\n", window_str);
- return 1;
- }
-
- xdisplay = XOpenDisplay (NULL);
- if (xdisplay == NULL)
- {
- fprintf (stderr, "Could not open display\n");
- return 1;
- }
-
- if (getenv ("METACITY_SYNC") != NULL)
- XSynchronize (xdisplay, True);
-
- XSetErrorHandler (x_error_handler);
-
- n_props = 0;
- props = XListProperties (xdisplay, window, &n_props);
- if (n_props == 0 || props == NULL)
- {
- fprintf (stderr, "Window has no properties\n");
- return 1;
- }
-
- gettimeofday (&program_start_time, NULL);
-
- i = 0;
- while (i < n_props)
- {
- gettimeofday (&current_time, NULL);
- printf (" %gms (sending request for property %ld)\n",
- ELAPSED (program_start_time, current_time),
- props[i]);
- if (ag_task_create (xdisplay,
- window, props[i],
- 0, 0xffffffff,
- False,
- AnyPropertyType) == NULL)
- {
- fprintf (stderr, "Failed to send request\n");
- return 1;
- }
-
- ++i;
- }
-
- XFree (props);
- props = NULL;
-
- n_left = n_props;
-
- while (TRUE)
- {
- XEvent xevent;
- int connection;
- fd_set set;
- AgGetPropertyTask *task;
-
- /* Mop up event queue */
- while (XPending (xdisplay) > 0)
- {
- XNextEvent (xdisplay, &xevent);
- gettimeofday (&current_time, NULL);
- printf (" %gms (processing event type %d)\n",
- ELAPSED (program_start_time, current_time),
- xevent.xany.type);
- }
-
- while ((task = ag_get_next_completed_task (xdisplay)))
- {
- try_get_reply (xdisplay, task);
- n_left -= 1;
- }
-
- if (n_left == 0)
- {
- printf ("All %d replies received.\n", n_props);
- break;
- }
-
- /* Wake up if we may have a reply */
- connection = ConnectionNumber (xdisplay);
-
- FD_ZERO (&set);
- FD_SET (connection, &set);
-
- gettimeofday (&current_time, NULL);
- printf (" %gms (blocking for data %d left)\n",
- ELAPSED (program_start_time, current_time), n_left);
- select (connection + 1, &set, NULL, NULL, NULL);
- }
-
- run_speed_comparison (xdisplay, window);
-
- return 0;
-}
-
-/* This function doesn't have all the printf's
- * and other noise, it just compares async to sync
- */
-static void
-run_speed_comparison (Display *xdisplay,
- Window window)
-{
- int i;
- int n_props;
- struct timeval start, end;
- int n_left;
-
- /* We just use atom values (0 to n_props) % 200, many are probably
- * BadAtom, that's fine, but the %200 keeps most of them valid. The
- * async case is about twice as advantageous when using valid atoms
- * (or the issue may be that it's more advantageous when the
- * properties are present and data is transmitted).
- */
- n_props = 4000;
- printf ("Timing with %d property requests\n", n_props);
-
- gettimeofday (&start, NULL);
-
- i = 0;
- while (i < n_props)
- {
- if (ag_task_create (xdisplay,
- window, (Atom) i % 200,
- 0, 0xffffffff,
- False,
- AnyPropertyType) == NULL)
- {
- fprintf (stderr, "Failed to send request\n");
- exit (1);
- }
-
- ++i;
- }
-
- n_left = n_props;
-
- while (TRUE)
- {
- int connection;
- fd_set set;
- XEvent xevent;
- AgGetPropertyTask *task;
-
- /* Mop up event queue */
- while (XPending (xdisplay) > 0)
- XNextEvent (xdisplay, &xevent);
-
- while ((task = ag_get_next_completed_task (xdisplay)))
- {
- int result;
- Atom actual_type;
- int actual_format;
- unsigned long n_items;
- unsigned long bytes_after;
- unsigned char *data;
-
- assert (ag_task_have_reply (task));
-
- data = NULL;
- result = ag_task_get_reply_and_free (task,
- &actual_type,
- &actual_format,
- &n_items,
- &bytes_after,
- &data);
-
- if (data)
- XFree (data);
-
- n_left -= 1;
- }
-
- if (n_left == 0)
- break;
-
- /* Wake up if we may have a reply */
- connection = ConnectionNumber (xdisplay);
-
- FD_ZERO (&set);
- FD_SET (connection, &set);
-
- select (connection + 1, &set, NULL, NULL, NULL);
- }
-
- gettimeofday (&end, NULL);
-
- printf ("Async time: %gms\n",
- ELAPSED (start, end));
-
- gettimeofday (&start, NULL);
-
- error_trap_push (xdisplay);
-
- i = 0;
- while (i < n_props)
- {
- Atom actual_type;
- int actual_format;
- unsigned long n_items;
- unsigned long bytes_after;
- unsigned char *data;
-
- data = NULL;
- if (XGetWindowProperty (xdisplay, window,
- (Atom) i % 200,
- 0, 0xffffffff,
- False,
- AnyPropertyType,
- &actual_type,
- &actual_format,
- &n_items,
- &bytes_after,
- &data) == Success)
- {
- if (data)
- XFree (data);
- }
-
- ++i;
- }
-
- error_trap_pop (xdisplay);
-
- gettimeofday (&end, NULL);
-
- printf ("Sync time: %gms\n",
- ELAPSED (start, end));
-}
diff --git a/src/core/testboxes.c b/src/core/testboxes.c
deleted file mode 100644
index 91ac2f87..00000000
--- a/src/core/testboxes.c
+++ /dev/null
@@ -1,1416 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity box operation testing program */
-
-/*
- * Copyright (C) 2005 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "boxes.h"
-#include <glib.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <X11/Xutil.h> /* Just for the definition of the various gravities */
-#include <time.h> /* To initialize random seed */
-
-#define NUM_RANDOM_RUNS 10000
-
-static void
-init_random_ness ()
-{
- srand(time(NULL));
-}
-
-static void
-get_random_rect (MetaRectangle *rect)
-{
- rect->x = rand () % 1600;
- rect->y = rand () % 1200;
- rect->width = rand () % 1600 + 1;
- rect->height = rand () % 1200 + 1;
-}
-
-static MetaRectangle*
-new_meta_rect (int x, int y, int width, int height)
-{
- MetaRectangle* temporary;
- temporary = g_new (MetaRectangle, 1);
- temporary->x = x;
- temporary->y = y;
- temporary->width = width;
- temporary->height = height;
-
- return temporary;
-}
-
-static MetaStrut*
-new_meta_strut (int x, int y, int width, int height, int side)
-{
- MetaStrut* temporary;
- temporary = g_new (MetaStrut, 1);
- temporary->rect = meta_rect(x, y, width, height);
- temporary->side = side;
-
- return temporary;
-}
-
-static MetaEdge*
-new_screen_edge (int x, int y, int width, int height, int side_type)
-{
- MetaEdge* temporary;
- temporary = g_new (MetaEdge, 1);
- temporary->rect.x = x;
- temporary->rect.y = y;
- temporary->rect.width = width;
- temporary->rect.height = height;
- temporary->side_type = side_type;
- temporary->edge_type = META_EDGE_SCREEN;
-
- return temporary;
-}
-
-static MetaEdge*
-new_xinerama_edge (int x, int y, int width, int height, int side_type)
-{
- MetaEdge* temporary;
- temporary = g_new (MetaEdge, 1);
- temporary->rect.x = x;
- temporary->rect.y = y;
- temporary->rect.width = width;
- temporary->rect.height = height;
- temporary->side_type = side_type;
- temporary->edge_type = META_EDGE_XINERAMA;
-
- return temporary;
-}
-
-static void
-test_area ()
-{
- MetaRectangle temp;
- int i;
- for (i = 0; i < NUM_RANDOM_RUNS; i++)
- {
- get_random_rect (&temp);
- g_assert (meta_rectangle_area (&temp) == temp.width * temp.height);
- }
-
- temp = meta_rect (0, 0, 5, 7);
- g_assert (meta_rectangle_area (&temp) == 35);
-
- printf ("%s passed.\n", G_STRFUNC);
-}
-
-static void
-test_intersect ()
-{
- MetaRectangle a = {100, 200, 50, 40};
- MetaRectangle b = { 0, 50, 110, 152};
- MetaRectangle c = { 0, 0, 10, 10};
- MetaRectangle d = {100, 100, 50, 50};
- MetaRectangle b_intersect_d = {100, 100, 10, 50};
- MetaRectangle temp;
- MetaRectangle temp2;
-
- meta_rectangle_intersect (&a, &b, &temp);
- temp2 = meta_rect (100, 200, 10, 2);
- g_assert (meta_rectangle_equal (&temp, &temp2));
- g_assert (meta_rectangle_area (&temp) == 20);
-
- meta_rectangle_intersect (&a, &c, &temp);
- g_assert (meta_rectangle_area (&temp) == 0);
-
- meta_rectangle_intersect (&a, &d, &temp);
- g_assert (meta_rectangle_area (&temp) == 0);
-
- meta_rectangle_intersect (&b, &d, &b);
- g_assert (meta_rectangle_equal (&b, &b_intersect_d));
-
- printf ("%s passed.\n", G_STRFUNC);
-}
-
-static void
-test_equal ()
-{
- MetaRectangle a = {10, 12, 4, 18};
- MetaRectangle b = a;
- MetaRectangle c = {10, 12, 4, 19};
- MetaRectangle d = {10, 12, 7, 18};
- MetaRectangle e = {10, 62, 4, 18};
- MetaRectangle f = {27, 12, 4, 18};
-
- g_assert ( meta_rectangle_equal (&a, &b));
- g_assert (!meta_rectangle_equal (&a, &c));
- g_assert (!meta_rectangle_equal (&a, &d));
- g_assert (!meta_rectangle_equal (&a, &e));
- g_assert (!meta_rectangle_equal (&a, &f));
-
- printf ("%s passed.\n", G_STRFUNC);
-}
-
-static void
-test_overlap_funcs ()
-{
- MetaRectangle temp1, temp2;
- int i;
- for (i = 0; i < NUM_RANDOM_RUNS; i++)
- {
- get_random_rect (&temp1);
- get_random_rect (&temp2);
- g_assert (meta_rectangle_overlap (&temp1, &temp2) ==
- (meta_rectangle_horiz_overlap (&temp1, &temp2) &&
- meta_rectangle_vert_overlap (&temp1, &temp2)));
- }
-
- temp1 = meta_rect ( 0, 0, 10, 10);
- temp2 = meta_rect (20, 0, 10, 5);
- g_assert (!meta_rectangle_overlap (&temp1, &temp2));
- g_assert (!meta_rectangle_horiz_overlap (&temp1, &temp2));
- g_assert ( meta_rectangle_vert_overlap (&temp1, &temp2));
-
- printf ("%s passed.\n", G_STRFUNC);
-}
-
-static void
-test_basic_fitting ()
-{
- MetaRectangle temp1, temp2, temp3;
- int i;
- /* Four cases:
- * case temp1 fits temp2 temp1 could fit temp2
- * 1 Y Y
- * 2 N Y
- * 3 Y N
- * 4 N N
- * Of the four cases, case 3 is impossible. An alternate way of looking
- * at this table is that either the middle column must be no, or the last
- * column must be yes. So we test that. Also, we can repeat the test
- * reversing temp1 and temp2.
- */
- for (i = 0; i < NUM_RANDOM_RUNS; i++)
- {
- get_random_rect (&temp1);
- get_random_rect (&temp2);
- g_assert (meta_rectangle_contains_rect (&temp1, &temp2) == FALSE ||
- meta_rectangle_could_fit_rect (&temp1, &temp2) == TRUE);
- g_assert (meta_rectangle_contains_rect (&temp2, &temp1) == FALSE ||
- meta_rectangle_could_fit_rect (&temp2, &temp1) == TRUE);
- }
-
- temp1 = meta_rect ( 0, 0, 10, 10);
- temp2 = meta_rect ( 5, 5, 5, 5);
- temp3 = meta_rect ( 8, 2, 3, 7);
- g_assert ( meta_rectangle_contains_rect (&temp1, &temp2));
- g_assert (!meta_rectangle_contains_rect (&temp2, &temp1));
- g_assert (!meta_rectangle_contains_rect (&temp1, &temp3));
- g_assert ( meta_rectangle_could_fit_rect (&temp1, &temp3));
- g_assert (!meta_rectangle_could_fit_rect (&temp3, &temp2));
-
- printf ("%s passed.\n", G_STRFUNC);
-}
-
-static void
-free_strut_list (GSList *struts)
-{
- GSList *tmp = struts;
- while (tmp)
- {
- g_free (tmp->data);
- tmp = tmp->next;
- }
- g_slist_free (struts);
-}
-
-static GSList*
-get_strut_list (int which)
-{
- GSList *ans;
- MetaDirection wc = 0; /* wc == who cares? ;-) */
-
- ans = NULL;
-
- g_assert (which >=0 && which <= 6);
- switch (which)
- {
- case 0:
- break;
- case 1:
- ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 20, wc));
- ans = g_slist_prepend (ans, new_meta_strut ( 400, 1160, 1600, 40, wc));
- break;
- case 2:
- ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 20, wc));
- ans = g_slist_prepend (ans, new_meta_strut ( 800, 1100, 400, 100, wc));
- ans = g_slist_prepend (ans, new_meta_strut ( 300, 1150, 150, 50, wc));
- break;
- case 3:
- ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 20, wc));
- ans = g_slist_prepend (ans, new_meta_strut ( 800, 1100, 400, 100, wc));
- ans = g_slist_prepend (ans, new_meta_strut ( 300, 1150, 80, 50, wc));
- ans = g_slist_prepend (ans, new_meta_strut ( 700, 525, 200, 150, wc));
- break;
- case 4:
- ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 800, 1200, wc));
- ans = g_slist_prepend (ans, new_meta_strut ( 800, 0, 1600, 20, wc));
- break;
- case 5:
- ans = g_slist_prepend (ans, new_meta_strut ( 800, 0, 1600, 20, wc));
- ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 800, 1200, wc));
- ans = g_slist_prepend (ans, new_meta_strut ( 800, 10, 800, 1200, wc));
- break;
- case 6:
- ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 40, wc));
- ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 20, wc));
- break;
- }
-
- return ans;
-}
-
-static GList*
-get_screen_region (int which)
-{
- GList *ret;
- GSList *struts;
- MetaRectangle basic_rect;
-
- basic_rect = meta_rect (0, 0, 1600, 1200);
- ret = NULL;
-
- struts = get_strut_list (which);
- ret = meta_rectangle_get_minimal_spanning_set_for_region (&basic_rect, struts);
- free_strut_list (struts);
-
- return ret;
-}
-
-static GList*
-get_screen_edges (int which)
-{
- GList *ret;
- GSList *struts;
- MetaRectangle basic_rect;
-
- basic_rect = meta_rect (0, 0, 1600, 1200);
- ret = NULL;
-
- struts = get_strut_list (which);
- ret = meta_rectangle_find_onscreen_edges (&basic_rect, struts);
- free_strut_list (struts);
-
- return ret;
-}
-
-static GList*
-get_xinerama_edges (int which_xinerama_set, int which_strut_set)
-{
- GList *ret;
- GSList *struts;
- GList *xins;
-
- xins = NULL;
- g_assert (which_xinerama_set >=0 && which_xinerama_set <= 3);
- switch (which_xinerama_set)
- {
- case 0:
- xins = g_list_prepend (xins, new_meta_rect ( 0, 0, 1600, 1200));
- break;
- case 1:
- xins = g_list_prepend (xins, new_meta_rect ( 0, 0, 800, 1200));
- xins = g_list_prepend (xins, new_meta_rect (800, 0, 800, 1200));
- break;
- case 2:
- xins = g_list_prepend (xins, new_meta_rect ( 0, 0, 1600, 600));
- xins = g_list_prepend (xins, new_meta_rect ( 0, 600, 1600, 600));
- break;
- case 3:
- xins = g_list_prepend (xins, new_meta_rect ( 0, 0, 1600, 600));
- xins = g_list_prepend (xins, new_meta_rect ( 0, 600, 800, 600));
- xins = g_list_prepend (xins, new_meta_rect (800, 600, 800, 600));
- break;
- }
-
- ret = NULL;
-
- struts = get_strut_list (which_strut_set);
- ret = meta_rectangle_find_nonintersected_xinerama_edges (xins, struts);
-
- free_strut_list (struts);
- meta_rectangle_free_list_and_elements (xins);
-
- return ret;
-}
-
-#if 0
-static void
-test_merge_regions ()
-{
- /* logarithmically distributed random number of struts (range?)
- * logarithmically distributed random size of struts (up to screen size???)
- * uniformly distributed location of center of struts (within screen)
- * merge all regions that are possible
- * print stats on problem setup
- * number of (non-completely-occluded?) struts
- * percentage of screen covered
- * length of resulting non-minimal spanning set
- * length of resulting minimal spanning set
- * print stats on merged regions:
- * number boxes merged
- * number of those merges that were of the form A contains B
- * number of those merges that were of the form A partially contains B
- * number of those merges that were of the form A is adjacent to B
- */
-
- GList* region;
- GList* compare;
- int num_contains, num_merged, num_part_contains, num_adjacent;
-
- num_contains = num_merged = num_part_contains = num_adjacent = 0;
- compare = region = get_screen_region (2);
- g_assert (region);
-
- printf ("Merging stats:\n");
- printf (" Length of initial list: %d\n", g_list_length (region));
-#ifdef PRINT_DEBUG
- char rect1[RECT_LENGTH], rect2[RECT_LENGTH];
- char region_list[(RECT_LENGTH + 2) * g_list_length (region)];
- meta_rectangle_region_to_string (region, ", ", region_list);
- printf (" Initial rectangles: %s\n", region_list);
-#endif
-
- while (compare && compare->next)
- {
- MetaRectangle *a = compare->data;
- GList *other = compare->next;
-
- g_assert (a->width > 0 && a->height > 0);
-
- while (other)
- {
- MetaRectangle *b = other->data;
- GList *delete_me = NULL;
-
- g_assert (b->width > 0 && b->height > 0);
-
-#ifdef PRINT_DEBUG
- printf (" -- Comparing %s to %s --\n",
- meta_rectangle_to_string (a, rect1),
- meta_rectangle_to_string (b, rect2));
-#endif
-
- /* If a contains b, just remove b */
- if (meta_rectangle_contains_rect (a, b))
- {
- delete_me = other;
- num_contains++;
- num_merged++;
- }
- /* If b contains a, just remove a */
- else if (meta_rectangle_contains_rect (a, b))
- {
- delete_me = compare;
- num_contains++;
- num_merged++;
- }
- /* If a and b might be mergeable horizontally */
- else if (a->y == b->y && a->height == b->height)
- {
- /* If a and b overlap */
- if (meta_rectangle_overlap (a, b))
- {
- int new_x = MIN (a->x, b->x);
- a->width = MAX (a->x + a->width, b->x + b->width) - new_x;
- a->x = new_x;
- delete_me = other;
- num_part_contains++;
- num_merged++;
- }
- /* If a and b are adjacent */
- else if (a->x + a->width == b->x || a->x == b->x + b->width)
- {
- int new_x = MIN (a->x, b->x);
- a->width = MAX (a->x + a->width, b->x + b->width) - new_x;
- a->x = new_x;
- delete_me = other;
- num_adjacent++;
- num_merged++;
- }
- }
- /* If a and b might be mergeable vertically */
- else if (a->x == b->x && a->width == b->width)
- {
- /* If a and b overlap */
- if (meta_rectangle_overlap (a, b))
- {
- int new_y = MIN (a->y, b->y);
- a->height = MAX (a->y + a->height, b->y + b->height) - new_y;
- a->y = new_y;
- delete_me = other;
- num_part_contains++;
- num_merged++;
- }
- /* If a and b are adjacent */
- else if (a->y + a->height == b->y || a->y == b->y + b->height)
- {
- int new_y = MIN (a->y, b->y);
- a->height = MAX (a->y + a->height, b->y + b->height) - new_y;
- a->y = new_y;
- delete_me = other;
- num_adjacent++;
- num_merged++;
- }
- }
-
- other = other->next;
-
- /* Delete any rectangle in the list that is no longer wanted */
- if (delete_me != NULL)
- {
-#ifdef PRINT_DEBUG
- MetaRectangle *bla = delete_me->data;
- printf (" Deleting rect %s\n",
- meta_rectangle_to_string (bla, rect1));
-#endif
-
- /* Deleting the rect we're compare others to is a little tricker */
- if (compare == delete_me)
- {
- compare = compare->next;
- other = compare->next;
- a = compare->data;
- }
-
- /* Okay, we can free it now */
- g_free (delete_me->data);
- region = g_list_delete_link (region, delete_me);
- }
-
-#ifdef PRINT_DEBUG
- char region_list[(RECT_LENGTH + 2) * g_list_length (region)];
- meta_rectangle_region_to_string (region, ", ", region_list);
- printf (" After comparison, new list is: %s\n", region_list);
-#endif
- }
-
- compare = compare->next;
- }
-
- printf (" Num rectangles contained in others : %d\n",
- num_contains);
- printf (" Num rectangles partially contained in others: %d\n",
- num_part_contains);
- printf (" Num rectangles adjacent to others : %d\n",
- num_adjacent);
- printf (" Num rectangles merged with others : %d\n",
- num_merged);
-#ifdef PRINT_DEBUG
- char region_list2[(RECT_LENGTH + 2) * g_list_length (region)];
- meta_rectangle_region_to_string (region, ", ", region_list2);
- printf (" Final rectangles: %s\n", region_list2);
-#endif
-
- meta_rectangle_free_spanning_set (region);
- region = NULL;
-
- printf ("%s passed.\n", G_STRFUNC);
-}
-#endif
-
-static void
-verify_lists_are_equal (GList *code, GList *answer)
-{
- int which = 0;
-
- while (code && answer)
- {
- MetaRectangle *a = code->data;
- MetaRectangle *b = answer->data;
-
- if (a->x != b->x ||
- a->y != b->y ||
- a->width != b->width ||
- a->height != b->height)
- {
- g_error ("%dth item in code answer answer lists do not match; "
- "code rect: %d,%d + %d,%d; answer rect: %d,%d + %d,%d\n",
- which,
- a->x, a->y, a->width, a->height,
- b->x, b->y, b->width, b->height);
- }
-
- code = code->next;
- answer = answer->next;
-
- which++;
- }
-
- /* Ought to be at the end of both lists; check if we aren't */
- if (code)
- {
- MetaRectangle *tmp = code->data;
- g_error ("code list longer than answer list by %d items; "
- "first extra item: %d,%d +%d,%d\n",
- g_list_length (code),
- tmp->x, tmp->y, tmp->width, tmp->height);
- }
-
- if (answer)
- {
- MetaRectangle *tmp = answer->data;
- g_error ("answer list longer than code list by %d items; "
- "first extra item: %d,%d +%d,%d\n",
- g_list_length (answer),
- tmp->x, tmp->y, tmp->width, tmp->height);
- }
-}
-
-static void
-test_regions_okay ()
-{
- GList* region;
- GList* tmp;
-
- /*************************************************************/
- /* Make sure test region 0 has the right spanning rectangles */
- /*************************************************************/
- region = get_screen_region (0);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_meta_rect (0, 0, 1600, 1200));
- verify_lists_are_equal (region, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (region);
-
- /*************************************************************/
- /* Make sure test region 1 has the right spanning rectangles */
- /*************************************************************/
- region = get_screen_region (1);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_meta_rect (0, 20, 400, 1180));
- tmp = g_list_prepend (tmp, new_meta_rect (0, 20, 1600, 1140));
- verify_lists_are_equal (region, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (region);
-
- /*************************************************************/
- /* Make sure test region 2 has the right spanning rectangles */
- /*************************************************************/
- region = get_screen_region (2);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_meta_rect ( 0, 20, 300, 1180));
- tmp = g_list_prepend (tmp, new_meta_rect ( 450, 20, 350, 1180));
- tmp = g_list_prepend (tmp, new_meta_rect (1200, 20, 400, 1180));
- tmp = g_list_prepend (tmp, new_meta_rect ( 0, 20, 800, 1130));
- tmp = g_list_prepend (tmp, new_meta_rect ( 0, 20, 1600, 1080));
- verify_lists_are_equal (region, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (region);
-
- /*************************************************************/
- /* Make sure test region 3 has the right spanning rectangles */
- /*************************************************************/
- region = get_screen_region (3);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_meta_rect ( 380, 675, 420, 525)); /* 220500 */
- tmp = g_list_prepend (tmp, new_meta_rect ( 0, 20, 300, 1180)); /* 354000 */
- tmp = g_list_prepend (tmp, new_meta_rect ( 380, 20, 320, 1180)); /* 377600 */
- tmp = g_list_prepend (tmp, new_meta_rect ( 0, 675, 800, 475)); /* 380000 */
- tmp = g_list_prepend (tmp, new_meta_rect (1200, 20, 400, 1180)); /* 472000 */
- tmp = g_list_prepend (tmp, new_meta_rect ( 0, 675, 1600, 425)); /* 680000 */
- tmp = g_list_prepend (tmp, new_meta_rect ( 900, 20, 700, 1080)); /* 756000 */
- tmp = g_list_prepend (tmp, new_meta_rect ( 0, 20, 700, 1130)); /* 791000 */
- tmp = g_list_prepend (tmp, new_meta_rect ( 0, 20, 1600, 505)); /* 808000 */
-#if 0
- printf ("Got to here...\n");
- char region_list[(RECT_LENGTH+2) * g_list_length (region)];
- char tmp_list[ (RECT_LENGTH+2) * g_list_length (tmp)];
- meta_rectangle_region_to_string (region, ", ", region_list);
- meta_rectangle_region_to_string (region, ", ", tmp_list);
- printf ("%s vs. %s\n", region_list, tmp_list);
-#endif
- verify_lists_are_equal (region, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (region);
-
- /*************************************************************/
- /* Make sure test region 4 has the right spanning rectangles */
- /*************************************************************/
- region = get_screen_region (4);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_meta_rect ( 800, 20, 800, 1180));
- verify_lists_are_equal (region, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (region);
-
- /*************************************************************/
- /* Make sure test region 5 has the right spanning rectangles */
- /*************************************************************/
- printf ("The next test intentionally causes a warning, "
- "but it can be ignored.\n");
- region = get_screen_region (5);
- verify_lists_are_equal (region, NULL);
-
- /* FIXME: Still to do:
- * - Create random struts and check the regions somehow
- */
-
- printf ("%s passed.\n", G_STRFUNC);
-}
-
-static void
-test_region_fitting ()
-{
- GList* region;
- MetaRectangle rect;
-
- /* See test_basic_fitting() for how/why these automated random tests work */
- int i;
- region = get_screen_region (3);
- for (i = 0; i < NUM_RANDOM_RUNS; i++)
- {
- get_random_rect (&rect);
- g_assert (meta_rectangle_contained_in_region (region, &rect) == FALSE ||
- meta_rectangle_could_fit_in_region (region, &rect) == TRUE);
- }
- meta_rectangle_free_list_and_elements (region);
-
- /* Do some manual tests too */
- region = get_screen_region (1);
-
- rect = meta_rect (50, 50, 400, 400);
- g_assert (meta_rectangle_could_fit_in_region (region, &rect));
- g_assert (meta_rectangle_contained_in_region (region, &rect));
-
- rect = meta_rect (250, 0, 500, 1150);
- g_assert (!meta_rectangle_could_fit_in_region (region, &rect));
- g_assert (!meta_rectangle_contained_in_region (region, &rect));
-
- rect = meta_rect (250, 0, 400, 400);
- g_assert (meta_rectangle_could_fit_in_region (region, &rect));
- g_assert (!meta_rectangle_contained_in_region (region, &rect));
-
- meta_rectangle_free_list_and_elements (region);
-
- region = get_screen_region (2);
- rect = meta_rect (1000, 50, 600, 1100);
- g_assert (meta_rectangle_could_fit_in_region (region, &rect));
- g_assert (!meta_rectangle_contained_in_region (region, &rect));
-
- meta_rectangle_free_list_and_elements (region);
-
- printf ("%s passed.\n", G_STRFUNC);
-}
-
-static void
-test_clamping_to_region ()
-{
- GList* region;
- MetaRectangle rect;
- MetaRectangle min_size;
- FixedDirections fixed_directions;
- int i;
-
- min_size.height = min_size.width = 1;
- fixed_directions = 0;
-
- region = get_screen_region (3);
- for (i = 0; i < NUM_RANDOM_RUNS; i++)
- {
- MetaRectangle temp;
- get_random_rect (&rect);
- temp = rect;
- meta_rectangle_clamp_to_fit_into_region (region,
- fixed_directions,
- &rect,
- &min_size);
- g_assert (meta_rectangle_could_fit_in_region (region, &rect) == TRUE);
- g_assert (rect.x == temp.x && rect.y == temp.y);
- }
- meta_rectangle_free_list_and_elements (region);
-
- /* Do some manual tests too */
- region = get_screen_region (1);
-
- rect = meta_rect (50, 50, 10000, 10000);
- meta_rectangle_clamp_to_fit_into_region (region,
- fixed_directions,
- &rect,
- &min_size);
- g_assert (rect.width == 1600 && rect.height == 1140);
-
- rect = meta_rect (275, -50, 410, 10000);
- meta_rectangle_clamp_to_fit_into_region (region,
- fixed_directions,
- &rect,
- &min_size);
- g_assert (rect.width == 400 && rect.height == 1180);
-
- rect = meta_rect (50, 50, 10000, 10000);
- min_size.height = 1170;
- meta_rectangle_clamp_to_fit_into_region (region,
- fixed_directions,
- &rect,
- &min_size);
- g_assert (rect.width == 400 && rect.height == 1180);
-
- printf ("The next test intentionally causes a warning, "
- "but it can be ignored.\n");
- rect = meta_rect (50, 50, 10000, 10000);
- min_size.width = 600; min_size.height = 1170;
- meta_rectangle_clamp_to_fit_into_region (region,
- fixed_directions,
- &rect,
- &min_size);
- g_assert (rect.width == 600 && rect.height == 1170);
-
- rect = meta_rect (350, 50, 100, 1100);
- min_size.width = 1; min_size.height = 1;
- fixed_directions = FIXED_DIRECTION_X;
- meta_rectangle_clamp_to_fit_into_region (region,
- fixed_directions,
- &rect,
- &min_size);
- g_assert (rect.width == 100 && rect.height == 1100);
-
- rect = meta_rect (300, 70, 500, 1100);
- min_size.width = 1; min_size.height = 1;
- fixed_directions = FIXED_DIRECTION_Y;
- meta_rectangle_clamp_to_fit_into_region (region,
- fixed_directions,
- &rect,
- &min_size);
- g_assert (rect.width == 400 && rect.height == 1100);
-
- printf ("The next test intentionally causes a warning, "
- "but it can be ignored.\n");
- rect = meta_rect (300, 70, 999999, 999999);
- min_size.width = 100; min_size.height = 200;
- fixed_directions = FIXED_DIRECTION_Y;
- meta_rectangle_clamp_to_fit_into_region (region,
- fixed_directions,
- &rect,
- &min_size);
- g_assert (rect.width == 100 && rect.height == 999999);
-
- meta_rectangle_free_list_and_elements (region);
-
- printf ("%s passed.\n", G_STRFUNC);
-}
-
-static gboolean
-rect_overlaps_region (const GList *spanning_rects,
- const MetaRectangle *rect)
-{
- /* FIXME: Should I move this to boxes.[ch]? */
- const GList *temp;
- gboolean overlaps;
-
- temp = spanning_rects;
- overlaps = FALSE;
- while (!overlaps && temp != NULL)
- {
- overlaps = overlaps || meta_rectangle_overlap (temp->data, rect);
- temp = temp->next;
- }
-
- return overlaps;
-}
-
-gboolean time_to_print = FALSE;
-
-static void
-test_clipping_to_region ()
-{
- GList* region;
- MetaRectangle rect, temp;
- FixedDirections fixed_directions = 0;
- int i;
-
- region = get_screen_region (3);
- for (i = 0; i < NUM_RANDOM_RUNS; i++)
- {
- get_random_rect (&rect);
- if (rect_overlaps_region (region, &rect))
- {
- meta_rectangle_clip_to_region (region, 0, &rect);
- g_assert (meta_rectangle_contained_in_region (region, &rect) == TRUE);
- }
- }
- meta_rectangle_free_list_and_elements (region);
-
- /* Do some manual tests too */
- region = get_screen_region (2);
-
- rect = meta_rect (-50, -10, 10000, 10000);
- meta_rectangle_clip_to_region (region,
- fixed_directions,
- &rect);
- g_assert (meta_rectangle_equal (region->data, &rect));
-
- rect = meta_rect (300, 1000, 400, 200);
- temp = meta_rect (300, 1000, 400, 150);
- meta_rectangle_clip_to_region (region,
- fixed_directions,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect (400, 1000, 300, 200);
- temp = meta_rect (450, 1000, 250, 200);
- meta_rectangle_clip_to_region (region,
- fixed_directions,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect (400, 1000, 300, 200);
- temp = meta_rect (400, 1000, 300, 150);
- meta_rectangle_clip_to_region (region,
- FIXED_DIRECTION_X,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect (400, 1000, 300, 200);
- temp = meta_rect (400, 1000, 300, 150);
- meta_rectangle_clip_to_region (region,
- FIXED_DIRECTION_X,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- meta_rectangle_free_list_and_elements (region);
-
- printf ("%s passed.\n", G_STRFUNC);
-}
-
-static void
-test_shoving_into_region ()
-{
- GList* region;
- MetaRectangle rect, temp;
- FixedDirections fixed_directions = 0;
- int i;
-
- region = get_screen_region (3);
- for (i = 0; i < NUM_RANDOM_RUNS; i++)
- {
- get_random_rect (&rect);
- if (meta_rectangle_could_fit_in_region (region, &rect))
- {
- meta_rectangle_shove_into_region (region, 0, &rect);
- g_assert (meta_rectangle_contained_in_region (region, &rect));
- }
- }
- meta_rectangle_free_list_and_elements (region);
-
- /* Do some manual tests too */
- region = get_screen_region (2);
-
- rect = meta_rect (300, 1000, 400, 200);
- temp = meta_rect (300, 950, 400, 200);
- meta_rectangle_shove_into_region (region,
- fixed_directions,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect (425, 1000, 300, 200);
- temp = meta_rect (450, 1000, 300, 200);
- meta_rectangle_shove_into_region (region,
- fixed_directions,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect (425, 1000, 300, 200);
- temp = meta_rect (425, 950, 300, 200);
- meta_rectangle_shove_into_region (region,
- FIXED_DIRECTION_X,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect ( 300, 1000, 400, 200);
- temp = meta_rect (1200, 1000, 400, 200);
- meta_rectangle_shove_into_region (region,
- FIXED_DIRECTION_Y,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect ( 800, 1150, 400, 50); /* Completely "offscreen" :) */
- temp = meta_rect ( 800, 1050, 400, 50);
- meta_rectangle_shove_into_region (region,
- 0,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect (-1000, 0, 400, 150); /* Offscreen in 2 directions */
- temp = meta_rect ( 0, 20, 400, 150);
- meta_rectangle_shove_into_region (region,
- 0,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- meta_rectangle_free_list_and_elements (region);
-
- printf ("%s passed.\n", G_STRFUNC);
-}
-
-static void
-verify_edge_lists_are_equal (GList *code, GList *answer)
-{
- int which = 0;
-
- while (code && answer)
- {
- MetaEdge *a = code->data;
- MetaEdge *b = answer->data;
-
- if (!meta_rectangle_equal (&a->rect, &b->rect) ||
- a->side_type != b->side_type ||
- a->edge_type != b->edge_type)
- {
- g_error ("%dth item in code answer answer lists do not match; "
- "code rect: %d,%d + %d,%d; answer rect: %d,%d + %d,%d\n",
- which,
- a->rect.x, a->rect.y, a->rect.width, a->rect.height,
- b->rect.x, b->rect.y, b->rect.width, b->rect.height);
- }
-
- code = code->next;
- answer = answer->next;
-
- which++;
- }
-
- /* Ought to be at the end of both lists; check if we aren't */
- if (code)
- {
- MetaEdge *tmp = code->data;
- g_error ("code list longer than answer list by %d items; "
- "first extra item rect: %d,%d +%d,%d\n",
- g_list_length (code),
- tmp->rect.x, tmp->rect.y, tmp->rect.width, tmp->rect.height);
- }
-
- if (answer)
- {
- MetaEdge *tmp = answer->data;
- g_error ("answer list longer than code list by %d items; "
- "first extra item rect: %d,%d +%d,%d\n",
- g_list_length (answer),
- tmp->rect.x, tmp->rect.y, tmp->rect.width, tmp->rect.height);
- }
-}
-
-static void
-test_find_onscreen_edges ()
-{
- GList* edges;
- GList* tmp;
-
- int left = META_DIRECTION_LEFT;
- int right = META_DIRECTION_RIGHT;
- int top = META_DIRECTION_TOP;
- int bottom = META_DIRECTION_BOTTOM;
-
- /*************************************************/
- /* Make sure test region 0 has the correct edges */
- /*************************************************/
- edges = get_screen_edges (0);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 1200, 1600, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 0, 1600, 0, top));
- tmp = g_list_prepend (tmp, new_screen_edge (1600, 0, 0, 1200, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 0, 0, 1200, left));
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************/
- /* Make sure test region 1 has the correct edges */
- /*************************************************/
- edges = get_screen_edges (1);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 1200, 400, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 400, 1160, 1200, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 20, 1600, 0, top));
- tmp = g_list_prepend (tmp, new_screen_edge (1600, 20, 0, 1140, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 400, 1160, 0, 40, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 20, 0, 1180, left));
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************/
- /* Make sure test region 2 has the correct edges */
- /*************************************************/
- edges = get_screen_edges (2);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_screen_edge (1200, 1200, 400, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 450, 1200, 350, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 1200, 300, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 300, 1150, 150, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 800, 1100, 400, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 20, 1600, 0, top));
- tmp = g_list_prepend (tmp, new_screen_edge (1600, 20, 0, 1180, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 800, 1100, 0, 100, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 300, 1150, 0, 50, right));
- tmp = g_list_prepend (tmp, new_screen_edge (1200, 1100, 0, 100, left));
- tmp = g_list_prepend (tmp, new_screen_edge ( 450, 1150, 0, 50, left));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 20, 0, 1180, left));
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************/
- /* Make sure test region 3 has the correct edges */
- /*************************************************/
- edges = get_screen_edges (3);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_screen_edge (1200, 1200, 400, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 380, 1200, 420, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 1200, 300, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 300, 1150, 80, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 800, 1100, 400, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 700, 525, 200, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 700, 675, 200, 0, top));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 20, 1600, 0, top));
- tmp = g_list_prepend (tmp, new_screen_edge (1600, 20, 0, 1180, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 800, 1100, 0, 100, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 700, 525, 0, 150, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 300, 1150, 0, 50, right));
- tmp = g_list_prepend (tmp, new_screen_edge (1200, 1100, 0, 100, left));
- tmp = g_list_prepend (tmp, new_screen_edge ( 900, 525, 0, 150, left));
- tmp = g_list_prepend (tmp, new_screen_edge ( 380, 1150, 0, 50, left));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 20, 0, 1180, left));
-
-#if 0
- #define FUDGE 50 /* number of edges */
- char big_buffer1[(EDGE_LENGTH+2)*FUDGE], big_buffer2[(EDGE_LENGTH+2)*FUDGE];
- meta_rectangle_edge_list_to_string (edges, "\n ", big_buffer1);
- meta_rectangle_edge_list_to_string (tmp, "\n ", big_buffer2);
- printf("Generated edge list:\n %s\nComparison edges list:\n %s\n",
- big_buffer1, big_buffer2);
-#endif
-
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************/
- /* Make sure test region 4 has the correct edges */
- /*************************************************/
- edges = get_screen_edges (4);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_screen_edge ( 800, 1200, 800, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 800, 20, 800, 0, top));
- tmp = g_list_prepend (tmp, new_screen_edge (1600, 20, 0, 1180, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 800, 20, 0, 1180, left));
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************/
- /* Make sure test region 5 has the correct edges */
- /*************************************************/
- edges = get_screen_edges (5);
- tmp = NULL;
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************/
- /* Make sure test region 6 has the correct edges */
- /*************************************************/
- edges = get_screen_edges (6);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 1200, 1600, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 40, 1600, 0, top));
- tmp = g_list_prepend (tmp, new_screen_edge (1600, 40, 0, 1160, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 40, 0, 1160, left));
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- printf ("%s passed.\n", G_STRFUNC);
-}
-
-static void
-test_find_nonintersected_xinerama_edges ()
-{
- GList* edges;
- GList* tmp;
-
- int left = META_DIRECTION_LEFT;
- int right = META_DIRECTION_RIGHT;
- int top = META_DIRECTION_TOP;
- int bottom = META_DIRECTION_BOTTOM;
-
- /*************************************************************************/
- /* Make sure test xinerama set 0 for with region 0 has the correct edges */
- /*************************************************************************/
- edges = get_xinerama_edges (0, 0);
- tmp = NULL;
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************************************/
- /* Make sure test xinerama set 2 for with region 1 has the correct edges */
- /*************************************************************************/
- edges = get_xinerama_edges (2, 1);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_xinerama_edge ( 0, 600, 1600, 0, bottom));
- tmp = g_list_prepend (tmp, new_xinerama_edge ( 0, 600, 1600, 0, top));
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************************************/
- /* Make sure test xinerama set 1 for with region 2 has the correct edges */
- /*************************************************************************/
- edges = get_xinerama_edges (1, 2);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_xinerama_edge ( 800, 20, 0, 1080, right));
- tmp = g_list_prepend (tmp, new_xinerama_edge ( 800, 20, 0, 1180, left));
-#if 0
- #define FUDGE 50
- char big_buffer1[(EDGE_LENGTH+2)*FUDGE], big_buffer2[(EDGE_LENGTH+2)*FUDGE];
- meta_rectangle_edge_list_to_string (edges, "\n ", big_buffer1);
- meta_rectangle_edge_list_to_string (tmp, "\n ", big_buffer2);
- printf("Generated edge list:\n %s\nComparison edges list:\n %s\n",
- big_buffer1, big_buffer2);
-#endif
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************************************/
- /* Make sure test xinerama set 3 for with region 3 has the correct edges */
- /*************************************************************************/
- edges = get_xinerama_edges (3, 3);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_xinerama_edge ( 900, 600, 700, 0, bottom));
- tmp = g_list_prepend (tmp, new_xinerama_edge ( 0, 600, 700, 0, bottom));
- tmp = g_list_prepend (tmp, new_xinerama_edge ( 900, 600, 700, 0, top));
- tmp = g_list_prepend (tmp, new_xinerama_edge ( 0, 600, 700, 0, top));
- tmp = g_list_prepend (tmp, new_xinerama_edge ( 800, 675, 0, 425, right));
- tmp = g_list_prepend (tmp, new_xinerama_edge ( 800, 675, 0, 525, left));
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************************************/
- /* Make sure test xinerama set 3 for with region 4 has the correct edges */
- /*************************************************************************/
- edges = get_xinerama_edges (3, 4);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_xinerama_edge ( 800, 600, 800, 0, bottom));
- tmp = g_list_prepend (tmp, new_xinerama_edge ( 800, 600, 800, 0, top));
- tmp = g_list_prepend (tmp, new_xinerama_edge ( 800, 600, 0, 600, right));
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************************************/
- /* Make sure test xinerama set 3 for with region 5has the correct edges */
- /*************************************************************************/
- edges = get_xinerama_edges (3, 5);
- tmp = NULL;
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- printf ("%s passed.\n", G_STRFUNC);
-}
-
-static void
-test_gravity_resize ()
-{
- MetaRectangle oldrect, rect, temp;
-
- rect.x = -500; /* Some random amount not equal to oldrect.x to ensure that
- * the resize is done with respect to oldrect instead of rect
- */
- oldrect = meta_rect ( 50, 300, 250, 400);
- temp = meta_rect ( 50, 300, 20, 5);
- meta_rectangle_resize_with_gravity (&oldrect,
- &rect,
- NorthWestGravity,
- 20,
- 5);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect ( 50, 300, 250, 400);
- temp = meta_rect (165, 300, 20, 5);
- meta_rectangle_resize_with_gravity (&rect,
- &rect,
- NorthGravity,
- 20,
- 5);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect ( 50, 300, 250, 400);
- temp = meta_rect (280, 300, 20, 5);
- meta_rectangle_resize_with_gravity (&rect,
- &rect,
- NorthEastGravity,
- 20,
- 5);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect ( 50, 300, 250, 400);
- temp = meta_rect ( 50, 695, 50, 5);
- meta_rectangle_resize_with_gravity (&rect,
- &rect,
- SouthWestGravity,
- 50,
- 5);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect ( 50, 300, 250, 400);
- temp = meta_rect (150, 695, 50, 5);
- meta_rectangle_resize_with_gravity (&rect,
- &rect,
- SouthGravity,
- 50,
- 5);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect ( 50, 300, 250, 400);
- temp = meta_rect (250, 695, 50, 5);
- meta_rectangle_resize_with_gravity (&rect,
- &rect,
- SouthEastGravity,
- 50,
- 5);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect (167, 738, 237, 843);
- temp = meta_rect (167, 1113, 832, 93);
- meta_rectangle_resize_with_gravity (&rect,
- &rect,
- WestGravity,
- 832,
- 93);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect ( 167, 738, 237, 843);
- temp = meta_rect (-131, 1113, 833, 93);
- meta_rectangle_resize_with_gravity (&rect,
- &rect,
- CenterGravity,
- 832,
- 93);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect (300, 1000, 400, 200);
- temp = meta_rect (270, 994, 430, 212);
- meta_rectangle_resize_with_gravity (&rect,
- &rect,
- EastGravity,
- 430,
- 211);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect (300, 1000, 400, 200);
- temp = meta_rect (300, 1000, 430, 211);
- meta_rectangle_resize_with_gravity (&rect,
- &rect,
- StaticGravity,
- 430,
- 211);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- printf ("%s passed.\n", G_STRFUNC);
-}
-
-static void
-test_find_closest_point_to_line ()
-{
- double x1, y1, x2, y2, px, py, rx, ry;
- double answer_x, answer_y;
-
- x1 = 3.0; y1 = 49.0;
- x2 = 2.0; y2 = - 1.0;
- px = -2.6; py = 19.1;
- answer_x = 2.4; answer_y = 19;
- meta_rectangle_find_linepoint_closest_to_point (x1, y1,
- x2, y2,
- px, py,
- &rx, &ry);
- g_assert (rx == answer_x && ry == answer_y);
-
- /* Special test for x1 == x2, so that slop of line is infinite */
- x1 = 3.0; y1 = 49.0;
- x2 = 3.0; y2 = - 1.0;
- px = -2.6; py = 19.1;
- answer_x = 3.0; answer_y = 19.1;
- meta_rectangle_find_linepoint_closest_to_point (x1, y1,
- x2, y2,
- px, py,
- &rx, &ry);
- g_assert (rx == answer_x && ry == answer_y);
-
- /* Special test for y1 == y2, so perp line has slope of infinity */
- x1 = 3.14; y1 = 7.0;
- x2 = 2.718; y2 = 7.0;
- px = -2.6; py = 19.1;
- answer_x = -2.6; answer_y = 7;
- meta_rectangle_find_linepoint_closest_to_point (x1, y1,
- x2, y2,
- px, py,
- &rx, &ry);
- g_assert (rx == answer_x && ry == answer_y);
-
- /* Test when we the point we want to be closest to is actually on the line */
- x1 = 3.0; y1 = 49.0;
- x2 = 2.0; y2 = - 1.0;
- px = 2.4; py = 19.0;
- answer_x = 2.4; answer_y = 19;
- meta_rectangle_find_linepoint_closest_to_point (x1, y1,
- x2, y2,
- px, py,
- &rx, &ry);
- g_assert (rx == answer_x && ry == answer_y);
-
- printf ("%s passed.\n", G_STRFUNC);
-}
-
-int
-main()
-{
- init_random_ness ();
- test_area ();
- test_intersect ();
- test_equal ();
- test_overlap_funcs ();
- test_basic_fitting ();
-
- test_regions_okay ();
- test_region_fitting ();
-
- test_clamping_to_region ();
- test_clipping_to_region ();
- test_shoving_into_region ();
-
- /* And now the functions dealing with edges more than boxes */
- test_find_onscreen_edges ();
- test_find_nonintersected_xinerama_edges ();
-
- /* And now the misfit functions that don't quite fit in anywhere else... */
- test_gravity_resize ();
- test_find_closest_point_to_line ();
-
- printf ("All tests passed.\n");
- return 0;
-}
diff --git a/src/core/util.c b/src/core/util.c
deleted file mode 100644
index bcfcb7f4..00000000
--- a/src/core/util.c
+++ /dev/null
@@ -1,611 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity utilities */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2005 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#define _GNU_SOURCE
-#define _POSIX_C_SOURCE 200112L /* for fdopen() */
-
-#include <config.h>
-#include "util.h"
-#include "main.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <X11/Xlib.h> /* must explicitly be included for Solaris; #326746 */
-#include <X11/Xutil.h> /* Just for the definition of the various gravities */
-
-#ifdef HAVE_BACKTRACE
-#include <execinfo.h>
-void
-meta_print_backtrace (void)
-{
- void *bt[500];
- int bt_size;
- int i;
- char **syms;
-
- bt_size = backtrace (bt, 500);
-
- syms = backtrace_symbols (bt, bt_size);
-
- i = 0;
- while (i < bt_size)
- {
- meta_verbose (" %s\n", syms[i]);
- ++i;
- }
-
- free (syms);
-}
-#else
-void
-meta_print_backtrace (void)
-{
- meta_verbose ("Not compiled with backtrace support\n");
-}
-#endif
-
-static gboolean is_verbose = FALSE;
-static gboolean is_debugging = FALSE;
-static gboolean replace_current = FALSE;
-static int no_prefix = 0;
-
-#ifdef WITH_VERBOSE_MODE
-static FILE* logfile = NULL;
-
-static void
-ensure_logfile (void)
-{
- if (logfile == NULL && g_getenv ("METACITY_USE_LOGFILE"))
- {
- char *filename = NULL;
- char *tmpl;
- int fd;
- GError *err;
-
- tmpl = g_strdup_printf ("metacity-%d-debug-log-XXXXXX",
- (int) getpid ());
-
- err = NULL;
- fd = g_file_open_tmp (tmpl,
- &filename,
- &err);
-
- g_free (tmpl);
-
- if (err != NULL)
- {
- meta_warning (_("Failed to open debug log: %s\n"),
- err->message);
- g_error_free (err);
- return;
- }
-
- logfile = fdopen (fd, "w");
-
- if (logfile == NULL)
- {
- meta_warning (_("Failed to fdopen() log file %s: %s\n"),
- filename, strerror (errno));
- close (fd);
- }
- else
- {
- g_printerr (_("Opened log file %s\n"), filename);
- }
-
- g_free (filename);
- }
-}
-#endif
-
-gboolean
-meta_is_verbose (void)
-{
- return is_verbose;
-}
-
-void
-meta_set_verbose (gboolean setting)
-{
-#ifndef WITH_VERBOSE_MODE
- if (setting)
- meta_fatal (_("Metacity was compiled without support for verbose mode\n"));
-#else
- if (setting)
- ensure_logfile ();
-#endif
-
- is_verbose = setting;
-}
-
-gboolean
-meta_is_debugging (void)
-{
- return is_debugging;
-}
-
-void
-meta_set_debugging (gboolean setting)
-{
-#ifdef WITH_VERBOSE_MODE
- if (setting)
- ensure_logfile ();
-#endif
-
- is_debugging = setting;
-}
-
-gboolean
-meta_get_replace_current_wm (void)
-{
- return replace_current;
-}
-
-void
-meta_set_replace_current_wm (gboolean setting)
-{
- replace_current = setting;
-}
-
-char *
-meta_g_utf8_strndup (const gchar *src,
- gsize n)
-{
- const gchar *s = src;
- while (n && *s)
- {
- s = g_utf8_next_char (s);
- n--;
- }
-
- return g_strndup (src, s - src);
-}
-
-static int
-utf8_fputs (const char *str,
- FILE *f)
-{
- char *l;
- int retval;
-
- l = g_locale_from_utf8 (str, -1, NULL, NULL, NULL);
-
- if (l == NULL)
- retval = fputs (str, f); /* just print it anyway, better than nothing */
- else
- retval = fputs (l, f);
-
- g_free (l);
-
- return retval;
-}
-
-void
-meta_free_gslist_and_elements (GSList *list_to_deep_free)
-{
- g_slist_foreach (list_to_deep_free,
- (void (*)(gpointer,gpointer))&g_free, /* ew, for ugly */
- NULL);
- g_slist_free (list_to_deep_free);
-}
-
-#ifdef WITH_VERBOSE_MODE
-void
-meta_debug_spew_real (const char *format, ...)
-{
- va_list args;
- gchar *str;
- FILE *out;
-
- g_return_if_fail (format != NULL);
-
- if (!is_debugging)
- return;
-
- va_start (args, format);
- str = g_strdup_vprintf (format, args);
- va_end (args);
-
- out = logfile ? logfile : stderr;
-
- if (no_prefix == 0)
- utf8_fputs (_("Window manager: "), out);
- utf8_fputs (str, out);
-
- fflush (out);
-
- g_free (str);
-}
-#endif /* WITH_VERBOSE_MODE */
-
-#ifdef WITH_VERBOSE_MODE
-void
-meta_verbose_real (const char *format, ...)
-{
- va_list args;
- gchar *str;
- FILE *out;
-
- g_return_if_fail (format != NULL);
-
- if (!is_verbose)
- return;
-
- va_start (args, format);
- str = g_strdup_vprintf (format, args);
- va_end (args);
-
- out = logfile ? logfile : stderr;
-
- if (no_prefix == 0)
- utf8_fputs ("Window manager: ", out);
- utf8_fputs (str, out);
-
- fflush (out);
-
- g_free (str);
-}
-#endif /* WITH_VERBOSE_MODE */
-
-#ifdef WITH_VERBOSE_MODE
-static const char*
-topic_name (MetaDebugTopic topic)
-{
- switch (topic)
- {
- case META_DEBUG_FOCUS:
- return "FOCUS";
- case META_DEBUG_WORKAREA:
- return "WORKAREA";
- case META_DEBUG_STACK:
- return "STACK";
- case META_DEBUG_THEMES:
- return "THEMES";
- case META_DEBUG_SM:
- return "SM";
- case META_DEBUG_EVENTS:
- return "EVENTS";
- case META_DEBUG_WINDOW_STATE:
- return "WINDOW_STATE";
- case META_DEBUG_WINDOW_OPS:
- return "WINDOW_OPS";
- case META_DEBUG_PLACEMENT:
- return "PLACEMENT";
- case META_DEBUG_GEOMETRY:
- return "GEOMETRY";
- case META_DEBUG_PING:
- return "PING";
- case META_DEBUG_XINERAMA:
- return "XINERAMA";
- case META_DEBUG_KEYBINDINGS:
- return "KEYBINDINGS";
- case META_DEBUG_SYNC:
- return "SYNC";
- case META_DEBUG_ERRORS:
- return "ERRORS";
- case META_DEBUG_STARTUP:
- return "STARTUP";
- case META_DEBUG_PREFS:
- return "PREFS";
- case META_DEBUG_GROUPS:
- return "GROUPS";
- case META_DEBUG_RESIZING:
- return "RESIZING";
- case META_DEBUG_SHAPES:
- return "SHAPES";
- case META_DEBUG_COMPOSITOR:
- return "COMPOSITOR";
- case META_DEBUG_EDGE_RESISTANCE:
- return "EDGE_RESISTANCE";
- }
-
- return "WM";
-}
-
-static int sync_count = 0;
-
-void
-meta_topic_real (MetaDebugTopic topic,
- const char *format,
- ...)
-{
- va_list args;
- gchar *str;
- FILE *out;
-
- g_return_if_fail (format != NULL);
-
- if (!is_verbose)
- return;
-
- va_start (args, format);
- str = g_strdup_vprintf (format, args);
- va_end (args);
-
- out = logfile ? logfile : stderr;
-
- if (no_prefix == 0)
- fprintf (out, "%s: ", topic_name (topic));
-
- if (topic == META_DEBUG_SYNC)
- {
- ++sync_count;
- fprintf (out, "%d: ", sync_count);
- }
-
- utf8_fputs (str, out);
-
- fflush (out);
-
- g_free (str);
-}
-#endif /* WITH_VERBOSE_MODE */
-
-void
-meta_bug (const char *format, ...)
-{
- va_list args;
- gchar *str;
- FILE *out;
-
- g_return_if_fail (format != NULL);
-
- va_start (args, format);
- str = g_strdup_vprintf (format, args);
- va_end (args);
-
-#ifdef WITH_VERBOSE_MODE
- out = logfile ? logfile : stderr;
-#else
- out = stderr;
-#endif
-
- if (no_prefix == 0)
- utf8_fputs (_("Bug in window manager: "), out);
- utf8_fputs (str, out);
-
- fflush (out);
-
- g_free (str);
-
- meta_print_backtrace ();
-
- /* stop us in a debugger */
- abort ();
-}
-
-void
-meta_warning (const char *format, ...)
-{
- va_list args;
- gchar *str;
- FILE *out;
-
- g_return_if_fail (format != NULL);
-
- va_start (args, format);
- str = g_strdup_vprintf (format, args);
- va_end (args);
-
-#ifdef WITH_VERBOSE_MODE
- out = logfile ? logfile : stderr;
-#else
- out = stderr;
-#endif
-
- if (no_prefix == 0)
- utf8_fputs (_("Window manager warning: "), out);
- utf8_fputs (str, out);
-
- fflush (out);
-
- g_free (str);
-}
-
-void
-meta_fatal (const char *format, ...)
-{
- va_list args;
- gchar *str;
- FILE *out;
-
- g_return_if_fail (format != NULL);
-
- va_start (args, format);
- str = g_strdup_vprintf (format, args);
- va_end (args);
-
-#ifdef WITH_VERBOSE_MODE
- out = logfile ? logfile : stderr;
-#else
- out = stderr;
-#endif
-
- if (no_prefix == 0)
- utf8_fputs (_("Window manager error: "), out);
- utf8_fputs (str, out);
-
- fflush (out);
-
- g_free (str);
-
- meta_exit (META_EXIT_ERROR);
-}
-
-void
-meta_push_no_msg_prefix (void)
-{
- ++no_prefix;
-}
-
-void
-meta_pop_no_msg_prefix (void)
-{
- g_return_if_fail (no_prefix > 0);
-
- --no_prefix;
-}
-
-void
-meta_exit (MetaExitCode code)
-{
-
- exit (code);
-}
-
-gint
-meta_unsigned_long_equal (gconstpointer v1,
- gconstpointer v2)
-{
- return *((const gulong*) v1) == *((const gulong*) v2);
-}
-
-guint
-meta_unsigned_long_hash (gconstpointer v)
-{
- gulong val = * (const gulong *) v;
-
- /* I'm not sure this works so well. */
-#if GLIB_SIZEOF_LONG > 4
- return (guint) (val ^ (val >> 32));
-#else
- return val;
-#endif
-}
-
-const char*
-meta_gravity_to_string (int gravity)
-{
- switch (gravity)
- {
- case NorthWestGravity:
- return "NorthWestGravity";
- break;
- case NorthGravity:
- return "NorthGravity";
- break;
- case NorthEastGravity:
- return "NorthEastGravity";
- break;
- case WestGravity:
- return "WestGravity";
- break;
- case CenterGravity:
- return "CenterGravity";
- break;
- case EastGravity:
- return "EastGravity";
- break;
- case SouthWestGravity:
- return "SouthWestGravity";
- break;
- case SouthGravity:
- return "SouthGravity";
- break;
- case SouthEastGravity:
- return "SouthEastGravity";
- break;
- case StaticGravity:
- return "StaticGravity";
- break;
- default:
- return "NorthWestGravity";
- break;
- }
-}
-
-void
-meta_show_dialog (const char *type,
- const char *message,
- const char *timeout,
- const gint screen_number,
- const char **columns,
- const char **entries)
-{
- GError *error = NULL;
- char *screen_number_text = g_strdup_printf("%d", screen_number);
-
- /*
- We want:
-
-zenity --display X --screen S --title Metacity --error --text "There was an error running <tt>terminal</tt>:\n\nYour computer is on fire."
- ** with no pipes
-
-zenity --display X --screen S --title Metacity --question --text "<big><b><tt>%s</tt> is not responding.</b></big>\n\n<i>You may choose to wait a short while for it to continue or force the application to quit entirely.</i>"
-
-zenity --display X --screen S --title Metacity --list --timeout 240 --text "These windows do not support \"save current setup\" and will have to be restarted manually next time you log in." --column "Window" --column "Class" "Firefox" "foo" "Duke Nukem Forever" "bar"
- */
-
- const char **argvl;
- int i=0;
- GPid child_pid;
-
- argvl = g_malloc(sizeof (char*) *
- (9 + (timeout?2:0))
- );
-
- argvl[i++] = "zenity";
- argvl[i++] = type;
- argvl[i++] = "--screen";
- argvl[i++] = screen_number_text;
- argvl[i++] = "--title";
- /* Translators: This is the title used on dialog boxes */
- argvl[i++] = _("Metacity");
- argvl[i++] = "--text";
- argvl[i++] = message;
-
- if (timeout)
- {
- argvl[i++] = "--timeout";
- argvl[i++] = timeout;
- }
-
- argvl[i] = NULL;
-
- g_spawn_async_with_pipes (
- "/",
- (char**) argvl, /* ugh */
- NULL,
- G_SPAWN_SEARCH_PATH,
- NULL, NULL,
- &child_pid,
- NULL, NULL, NULL,
- &error
- );
-
- g_free (argvl);
- g_free (screen_number_text);
-
- if (error)
- {
- meta_warning ("%s\n", error->message);
- g_error_free (error);
- }
-}
-
-/* eof util.c */
-
diff --git a/src/core/window-private.h b/src/core/window-private.h
deleted file mode 100644
index f5547122..00000000
--- a/src/core/window-private.h
+++ /dev/null
@@ -1,632 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * \file window-private.h Windows which Metacity manages
- *
- * Managing X windows.
- * This file contains methods on this class which are available to
- * routines in core but not outside it. (See window.h for the routines
- * which the rest of the world is allowed to use.)
- */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2002 Red Hat, Inc.
- * Copyright (C) 2003, 2004 Rob Adams
- * Copyright (C) 2004-2006 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_WINDOW_PRIVATE_H
-#define META_WINDOW_PRIVATE_H
-
-#include <config.h>
-#include "window.h"
-#include "screen-private.h"
-#include "util.h"
-#include "stack.h"
-#include "iconcache.h"
-#include <X11/Xutil.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-
-typedef struct _MetaGroup MetaGroup;
-typedef struct _MetaWindowQueue MetaWindowQueue;
-
-typedef gboolean (*MetaWindowForeachFunc) (MetaWindow *window,
- void *data);
-
-typedef enum
-{
- META_WINDOW_NORMAL,
- META_WINDOW_DESKTOP,
- META_WINDOW_DOCK,
- META_WINDOW_DIALOG,
- META_WINDOW_MODAL_DIALOG,
- META_WINDOW_TOOLBAR,
- META_WINDOW_MENU,
- META_WINDOW_UTILITY,
- META_WINDOW_SPLASHSCREEN
-} MetaWindowType;
-
-typedef enum
-{
- META_MAXIMIZE_HORIZONTAL = 1 << 0,
- META_MAXIMIZE_VERTICAL = 1 << 1
-} MetaMaximizeFlags;
-
-typedef enum {
- META_CLIENT_TYPE_UNKNOWN = 0,
- META_CLIENT_TYPE_APPLICATION = 1,
- META_CLIENT_TYPE_PAGER = 2,
- META_CLIENT_TYPE_MAX_RECOGNIZED = 2
-} MetaClientType;
-
-typedef enum {
- META_QUEUE_CALC_SHOWING = 1 << 0,
- META_QUEUE_MOVE_RESIZE = 1 << 1,
- META_QUEUE_UPDATE_ICON = 1 << 2,
-} MetaQueueType;
-
-#define NUMBER_OF_QUEUES 3
-
-struct _MetaWindow
-{
- MetaDisplay *display;
- MetaScreen *screen;
- MetaWorkspace *workspace;
- Window xwindow;
- /* may be NULL! not all windows get decorated */
- MetaFrame *frame;
- int depth;
- Visual *xvisual;
- Colormap colormap;
- char *desc; /* used in debug spew */
- char *title;
-
- char *icon_name;
- GdkPixbuf *icon;
- GdkPixbuf *mini_icon;
- MetaIconCache icon_cache;
- Pixmap wm_hints_pixmap;
- Pixmap wm_hints_mask;
-
- MetaWindowType type;
- Atom type_atom;
-
- /* NOTE these five are not in UTF-8, we just treat them as random
- * binary data
- */
- char *res_class;
- char *res_name;
- char *role;
- char *sm_client_id;
- char *wm_client_machine;
- char *startup_id;
-
- int net_wm_pid;
-
- Window xtransient_for;
- Window xgroup_leader;
- Window xclient_leader;
-
- /* Initial workspace property */
- int initial_workspace;
-
- /* Initial timestamp property */
- guint32 initial_timestamp;
-
- /* Whether we're maximized */
- guint maximized_horizontally : 1;
- guint maximized_vertically : 1;
-
- /* Whether we have to maximize/minimize after placement */
- guint maximize_horizontally_after_placement : 1;
- guint maximize_vertically_after_placement : 1;
- guint minimize_after_placement : 1;
-
- /* Whether we're shaded */
- guint shaded : 1;
-
- /* Whether we're fullscreen */
- guint fullscreen : 1;
-
- /* Area to cover when in fullscreen mode. If _NET_WM_FULLSCREEN_MONITORS has
- * been overridden (via a client message), the window will cover the union of
- * these monitors. If not, this is the single monitor which the window's
- * origin is on. */
- long fullscreen_monitors[4];
-
- /* Whether we're trying to constrain the window to be fully onscreen */
- guint require_fully_onscreen : 1;
-
- /* Whether we're trying to constrain the window to be on a single xinerama */
- guint require_on_single_xinerama : 1;
-
- /* Whether we're trying to constrain the window's titlebar to be onscreen */
- guint require_titlebar_visible : 1;
-
- /* Whether we're sticky in the multi-workspace sense
- * (vs. the not-scroll-with-viewport sense, we don't
- * have no stupid viewports)
- */
- guint on_all_workspaces : 1;
-
- /* Minimize is the state controlled by the minimize button */
- guint minimized : 1;
- guint was_minimized : 1;
- guint tab_unminimized : 1;
-
- /* Whether the window is mapped; actual server-side state
- * see also unmaps_pending
- */
- guint mapped : 1;
-
- /* Iconic is the state in WM_STATE; happens for workspaces/shading
- * in addition to minimize
- */
- guint iconic : 1;
- /* initially_iconic is the WM_HINTS setting when we first manage
- * the window. It's taken to mean initially minimized.
- */
- guint initially_iconic : 1;
-
- /* whether an initial workspace was explicitly set */
- guint initial_workspace_set : 1;
-
- /* whether an initial timestamp was explicitly set */
- guint initial_timestamp_set : 1;
-
- /* whether net_wm_user_time has been set yet */
- guint net_wm_user_time_set : 1;
-
- /* These are the flags from WM_PROTOCOLS */
- guint take_focus : 1;
- guint delete_window : 1;
- guint net_wm_ping : 1;
- /* Globally active / No input */
- guint input : 1;
-
- /* MWM hints about features of window */
- guint mwm_decorated : 1;
- guint mwm_border_only : 1;
- guint mwm_has_close_func : 1;
- guint mwm_has_minimize_func : 1;
- guint mwm_has_maximize_func : 1;
- guint mwm_has_move_func : 1;
- guint mwm_has_resize_func : 1;
-
- /* Computed features of window */
- guint decorated : 1;
- guint border_only : 1;
- guint always_sticky : 1;
- guint has_close_func : 1;
- guint has_minimize_func : 1;
- guint has_maximize_func : 1;
- guint has_shade_func : 1;
- guint has_move_func : 1;
- guint has_resize_func : 1;
- guint has_fullscreen_func : 1;
-
- /* Weird "_NET_WM_STATE_MODAL" flag */
- guint wm_state_modal : 1;
-
- /* TRUE if the client forced these on */
- guint wm_state_skip_taskbar : 1;
- guint wm_state_skip_pager : 1;
-
- /* Computed whether to skip taskbar or not */
- guint skip_taskbar : 1;
- guint skip_pager : 1;
-
- /* TRUE if client set these */
- guint wm_state_above : 1;
- guint wm_state_below : 1;
-
- /* EWHH demands attention flag */
- guint wm_state_demands_attention : 1;
-
- /* this flag tracks receipt of focus_in focus_out and
- * determines whether we draw the focus
- */
- guint has_focus : 1;
-
- /* Have we placed this window? */
- guint placed : 1;
-
- /* Is this not a transient of the focus window which is being denied focus? */
- guint denied_focus_and_not_transient : 1;
-
- /* Has this window not ever been shown yet? */
- guint showing_for_first_time : 1;
-
- /* Are we in meta_window_free()? */
- guint unmanaging : 1;
-
- /* Are we in meta_window_new()? */
- guint constructing : 1;
-
- /* Are we in the various queues? (Bitfield: see META_WINDOW_IS_IN_QUEUE) */
- guint is_in_queues : NUMBER_OF_QUEUES;
-
- /* Used by keybindings.c */
- guint keys_grabbed : 1; /* normal keybindings grabbed */
- guint grab_on_frame : 1; /* grabs are on the frame */
- guint all_keys_grabbed : 1; /* AnyKey grabbed */
-
- /* Set if the reason for unmanaging the window is that
- * it was withdrawn
- */
- guint withdrawn : 1;
-
- /* TRUE if constrain_position should calc placement.
- * only relevant if !window->placed
- */
- guint calc_placement : 1;
-
- /* Transient parent is a root window */
- guint transient_parent_is_root_window : 1;
-
- /* Info on which props we got our attributes from */
- guint using_net_wm_name : 1; /* vs. plain wm_name */
- guint using_net_wm_visible_name : 1; /* tracked so we can clear it */
- guint using_net_wm_icon_name : 1; /* vs. plain wm_icon_name */
- guint using_net_wm_visible_icon_name : 1; /* tracked so we can clear it */
-
- /* has a shape mask */
- guint has_shape : 1;
-
- /* icon props have changed */
- guint need_reread_icon : 1;
-
- /* if TRUE, window was maximized at start of current grab op */
- guint shaken_loose : 1;
-
- /* if TRUE we have a grab on the focus click buttons */
- guint have_focus_click_grab : 1;
-
- /* if TRUE, application is buggy and SYNC resizing is turned off */
- guint disable_sync : 1;
-
- /* Note: can be NULL */
- GSList *struts;
-
-#ifdef HAVE_XSYNC
- /* XSync update counter */
- XSyncCounter sync_request_counter;
- guint sync_request_serial;
- GTimeVal sync_request_time;
-#endif
-
- /* Number of UnmapNotify that are caused by us, if
- * we get UnmapNotify with none pending then the client
- * is withdrawing the window.
- */
- int unmaps_pending;
-
- /* set to the most recent user-interaction event timestamp that we
- know about for this window */
- guint32 net_wm_user_time;
-
- /* window that gets updated net_wm_user_time values */
- Window user_time_window;
-
- /* The size we set the window to last (i.e. what we believe
- * to be its actual size on the server). The x, y are
- * the actual server-side x,y so are relative to the frame
- * (meaning that they just hold the frame width and height)
- * or the root window (meaning they specify the location
- * of the top left of the inner window) as appropriate.
- */
- MetaRectangle rect;
-
- /* The geometry to restore when we unmaximize. The position is in
- * root window coords, even if there's a frame, which contrasts with
- * window->rect above. Note that this gives the position and size
- * of the client window (i.e. ignoring the frame).
- */
- MetaRectangle saved_rect;
-
- /* This is the geometry the window had after the last user-initiated
- * move/resize operations. We use this whenever we are moving the
- * implicitly (for example, if we move to avoid a panel, we can snap
- * back to this position if the panel moves again). Note that this
- * gives the position and size of the client window (i.e. ignoring
- * the frame).
- *
- * Position valid if user_has_moved, size valid if user_has_resized
- *
- * Position always in root coords, unlike window->rect.
- */
- MetaRectangle user_rect;
-
- /* Requested geometry */
- int border_width;
- /* x/y/w/h here get filled with ConfigureRequest values */
- XSizeHints size_hints;
-
- /* Managed by stack.c */
- MetaStackLayer layer;
- int stack_position; /* see comment in stack.h */
-
- /* Current dialog open for this window */
- int dialog_pid;
- int dialog_pipe;
-
- /* maintained by group.c */
- MetaGroup *group;
-};
-
-/* These differ from window->has_foo_func in that they consider
- * the dynamic window state such as "maximized", not just the
- * window's type
- */
-#define META_WINDOW_MAXIMIZED(w) ((w)->maximized_horizontally && \
- (w)->maximized_vertically)
-#define META_WINDOW_MAXIMIZED_VERTICALLY(w) ((w)->maximized_vertically)
-#define META_WINDOW_MAXIMIZED_HORIZONTALLY(w) ((w)->maximized_horizontally)
-#define META_WINDOW_ALLOWS_MOVE(w) ((w)->has_move_func && !(w)->fullscreen)
-#define META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS(w) ((w)->has_resize_func && !META_WINDOW_MAXIMIZED (w) && !(w)->fullscreen && !(w)->shaded)
-#define META_WINDOW_ALLOWS_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && \
- (((w)->size_hints.min_width < (w)->size_hints.max_width) || \
- ((w)->size_hints.min_height < (w)->size_hints.max_height)))
-#define META_WINDOW_ALLOWS_HORIZONTAL_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && (w)->size_hints.min_width < (w)->size_hints.max_width)
-#define META_WINDOW_ALLOWS_VERTICAL_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && (w)->size_hints.min_height < (w)->size_hints.max_height)
-
-MetaWindow* meta_window_new (MetaDisplay *display,
- Window xwindow,
- gboolean must_be_viewable);
-MetaWindow* meta_window_new_with_attrs (MetaDisplay *display,
- Window xwindow,
- gboolean must_be_viewable,
- XWindowAttributes *attrs);
-void meta_window_free (MetaWindow *window,
- guint32 timestamp);
-void meta_window_calc_showing (MetaWindow *window);
-void meta_window_queue (MetaWindow *window,
- guint queuebits);
-void meta_window_minimize (MetaWindow *window);
-void meta_window_unminimize (MetaWindow *window);
-void meta_window_maximize (MetaWindow *window,
- MetaMaximizeFlags directions);
-void meta_window_maximize_internal (MetaWindow *window,
- MetaMaximizeFlags directions,
- MetaRectangle *saved_rect);
-void meta_window_unmaximize (MetaWindow *window,
- MetaMaximizeFlags directions);
-void meta_window_make_above (MetaWindow *window);
-void meta_window_unmake_above (MetaWindow *window);
-void meta_window_shade (MetaWindow *window,
- guint32 timestamp);
-void meta_window_unshade (MetaWindow *window,
- guint32 timestamp);
-void meta_window_change_workspace (MetaWindow *window,
- MetaWorkspace *workspace);
-void meta_window_stick (MetaWindow *window);
-void meta_window_unstick (MetaWindow *window);
-
-void meta_window_activate (MetaWindow *window,
- guint32 current_time);
-void meta_window_activate_with_workspace (MetaWindow *window,
- guint32 current_time,
- MetaWorkspace *workspace);
-void meta_window_make_fullscreen_internal (MetaWindow *window);
-void meta_window_make_fullscreen (MetaWindow *window);
-void meta_window_unmake_fullscreen (MetaWindow *window);
-void meta_window_update_fullscreen_monitors (MetaWindow *window,
- unsigned long top,
- unsigned long bottom,
- unsigned long left,
- unsigned long right);
-
-/* args to move are window pos, not frame pos */
-void meta_window_move (MetaWindow *window,
- gboolean user_op,
- int root_x_nw,
- int root_y_nw);
-void meta_window_resize (MetaWindow *window,
- gboolean user_op,
- int w,
- int h);
-void meta_window_move_resize (MetaWindow *window,
- gboolean user_op,
- int root_x_nw,
- int root_y_nw,
- int w,
- int h);
-void meta_window_resize_with_gravity (MetaWindow *window,
- gboolean user_op,
- int w,
- int h,
- int gravity);
-
-
-/* Return whether the window would be showing if we were on its workspace */
-gboolean meta_window_showing_on_its_workspace (MetaWindow *window);
-
-/* Return whether the window should be currently mapped */
-gboolean meta_window_should_be_showing (MetaWindow *window);
-
-/* See warning in window.c about this function */
-gboolean __window_is_terminal (MetaWindow *window);
-
-void meta_window_update_struts (MetaWindow *window);
-
-/* this gets root coords */
-void meta_window_get_position (MetaWindow *window,
- int *x,
- int *y);
-
-/* Gets root coords for x, y, width & height of client window; uses
- * meta_window_get_position for x & y.
- */
-void meta_window_get_client_root_coords (MetaWindow *window,
- MetaRectangle *rect);
-
-/* gets position we need to set to stay in current position,
- * assuming position will be gravity-compensated. i.e.
- * this is the position a client would send in a configure
- * request.
- */
-void meta_window_get_gravity_position (MetaWindow *window,
- int gravity,
- int *x,
- int *y);
-/* Get geometry for saving in the session; x/y are gravity
- * position, and w/h are in resize inc above the base size.
- */
-void meta_window_get_geometry (MetaWindow *window,
- int *x,
- int *y,
- int *width,
- int *height);
-void meta_window_get_outer_rect (const MetaWindow *window,
- MetaRectangle *rect);
-void meta_window_get_xor_rect (MetaWindow *window,
- const MetaRectangle *grab_wireframe_rect,
- MetaRectangle *xor_rect);
-void meta_window_begin_wireframe (MetaWindow *window);
-void meta_window_update_wireframe (MetaWindow *window,
- int x,
- int y,
- int width,
- int height);
-void meta_window_end_wireframe (MetaWindow *window);
-
-void meta_window_delete (MetaWindow *window,
- guint32 timestamp);
-void meta_window_kill (MetaWindow *window);
-void meta_window_focus (MetaWindow *window,
- guint32 timestamp);
-void meta_window_raise (MetaWindow *window);
-void meta_window_lower (MetaWindow *window);
-
-void meta_window_update_unfocused_button_grabs (MetaWindow *window);
-
-/* Sends a client message */
-void meta_window_send_icccm_message (MetaWindow *window,
- Atom atom,
- guint32 timestamp);
-
-
-void meta_window_move_resize_request(MetaWindow *window,
- guint value_mask,
- int gravity,
- int x,
- int y,
- int width,
- int height);
-gboolean meta_window_configure_request (MetaWindow *window,
- XEvent *event);
-gboolean meta_window_property_notify (MetaWindow *window,
- XEvent *event);
-gboolean meta_window_client_message (MetaWindow *window,
- XEvent *event);
-gboolean meta_window_notify_focus (MetaWindow *window,
- XEvent *event);
-
-void meta_window_set_current_workspace_hint (MetaWindow *window);
-
-unsigned long meta_window_get_net_wm_desktop (MetaWindow *window);
-
-void meta_window_show_menu (MetaWindow *window,
- int root_x,
- int root_y,
- int button,
- guint32 timestamp);
-
-gboolean meta_window_titlebar_is_onscreen (MetaWindow *window);
-void meta_window_shove_titlebar_onscreen (MetaWindow *window);
-
-void meta_window_set_gravity (MetaWindow *window,
- int gravity);
-
-void meta_window_handle_mouse_grab_op_event (MetaWindow *window,
- XEvent *event);
-
-GList* meta_window_get_workspaces (MetaWindow *window);
-
-gboolean meta_window_located_on_workspace (MetaWindow *window,
- MetaWorkspace *workspace);
-
-void meta_window_get_work_area_current_xinerama (MetaWindow *window,
- MetaRectangle *area);
-void meta_window_get_work_area_for_xinerama (MetaWindow *window,
- int which_xinerama,
- MetaRectangle *area);
-void meta_window_get_work_area_all_xineramas (MetaWindow *window,
- MetaRectangle *area);
-
-
-gboolean meta_window_same_application (MetaWindow *window,
- MetaWindow *other_window);
-
-#define META_WINDOW_IN_NORMAL_TAB_CHAIN_TYPE(w) \
- ((w)->type != META_WINDOW_DOCK && (w)->type != META_WINDOW_DESKTOP)
-#define META_WINDOW_IN_NORMAL_TAB_CHAIN(w) \
- (((w)->input || (w)->take_focus ) && META_WINDOW_IN_NORMAL_TAB_CHAIN_TYPE (w) && (!(w)->skip_taskbar))
-#define META_WINDOW_IN_DOCK_TAB_CHAIN(w) \
- (((w)->input || (w)->take_focus) && (! META_WINDOW_IN_NORMAL_TAB_CHAIN_TYPE (w) || (w)->skip_taskbar))
-#define META_WINDOW_IN_GROUP_TAB_CHAIN(w, g) \
- (((w)->input || (w)->take_focus) && (!g || meta_window_get_group(w)==g))
-
-void meta_window_refresh_resize_popup (MetaWindow *window);
-
-void meta_window_free_delete_dialog (MetaWindow *window);
-
-void meta_window_foreach_transient (MetaWindow *window,
- MetaWindowForeachFunc func,
- void *data);
-gboolean meta_window_is_ancestor_of_transient (MetaWindow *window,
- MetaWindow *transient);
-void meta_window_foreach_ancestor (MetaWindow *window,
- MetaWindowForeachFunc func,
- void *data);
-MetaWindow* meta_window_find_root_ancestor (MetaWindow *window);
-
-
-void meta_window_begin_grab_op (MetaWindow *window,
- MetaGrabOp op,
- gboolean frame_action,
- guint32 timestamp);
-
-void meta_window_update_keyboard_resize (MetaWindow *window,
- gboolean update_cursor);
-void meta_window_update_keyboard_move (MetaWindow *window);
-
-void meta_window_update_layer (MetaWindow *window);
-
-gboolean meta_window_get_icon_geometry (MetaWindow *window,
- MetaRectangle *rect);
-
-const char* meta_window_get_startup_id (MetaWindow *window);
-
-void meta_window_recalc_features (MetaWindow *window);
-void meta_window_recalc_window_type (MetaWindow *window);
-
-void meta_window_stack_just_below (MetaWindow *window,
- MetaWindow *below_this_one);
-
-void meta_window_set_user_time (MetaWindow *window,
- guint32 timestamp);
-
-void meta_window_set_demands_attention (MetaWindow *window);
-
-void meta_window_unset_demands_attention (MetaWindow *window);
-
-void meta_window_update_icon_now (MetaWindow *window);
-
-#endif
diff --git a/src/core/window-props.c b/src/core/window-props.c
deleted file mode 100644
index 59feadf7..00000000
--- a/src/core/window-props.c
+++ /dev/null
@@ -1,1636 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * \file window-props.c MetaWindow property handling
- *
- * A system which can inspect sets of properties of given windows
- * and take appropriate action given their values.
- *
- * Note that all the meta_window_reload_propert* functions require a
- * round trip to the server.
- *
- * \bug Not all the properties have moved over from their original
- * handler in window.c yet.
- */
-
-/*
- * Copyright (C) 2001, 2002, 2003 Red Hat, Inc.
- * Copyright (C) 2004, 2005 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#define _GNU_SOURCE
-#define _SVID_SOURCE /* for gethostname() */
-
-#include <config.h>
-#include "window-props.h"
-#include "errors.h"
-#include "xprops.h"
-#include "frame-private.h"
-#include "group.h"
-#include <X11/Xatom.h>
-#include <unistd.h>
-#include <string.h>
-#ifndef HOST_NAME_MAX
-/* Solaris headers apparently don't define this so do so manually; #326745 */
-#define HOST_NAME_MAX 255
-#endif
-
-typedef void (* InitValueFunc) (MetaDisplay *display,
- Atom property,
- MetaPropValue *value);
-typedef void (* ReloadValueFunc) (MetaWindow *window,
- MetaPropValue *value);
-
-struct _MetaWindowPropHooks
-{
- Atom property;
- InitValueFunc init_func;
- ReloadValueFunc reload_func;
-};
-
-static void init_prop_value (MetaDisplay *display,
- Atom property,
- MetaPropValue *value);
-static void reload_prop_value (MetaWindow *window,
- MetaPropValue *value);
-static MetaWindowPropHooks* find_hooks (MetaDisplay *display,
- Atom property);
-
-
-void
-meta_window_reload_property (MetaWindow *window,
- Atom property)
-{
- meta_window_reload_properties (window, &property, 1);
-}
-
-void
-meta_window_reload_properties (MetaWindow *window,
- const Atom *properties,
- int n_properties)
-{
- meta_window_reload_properties_from_xwindow (window,
- window->xwindow,
- properties,
- n_properties);
-}
-
-void
-meta_window_reload_property_from_xwindow (MetaWindow *window,
- Window xwindow,
- Atom property)
-{
- meta_window_reload_properties_from_xwindow (window, xwindow, &property, 1);
-}
-
-void
-meta_window_reload_properties_from_xwindow (MetaWindow *window,
- Window xwindow,
- const Atom *properties,
- int n_properties)
-{
- int i;
- MetaPropValue *values;
-
- g_return_if_fail (properties != NULL);
- g_return_if_fail (n_properties > 0);
-
- values = g_new0 (MetaPropValue, n_properties);
-
- i = 0;
- while (i < n_properties)
- {
- init_prop_value (window->display, properties[i], &values[i]);
- ++i;
- }
-
- meta_prop_get_values (window->display, xwindow,
- values, n_properties);
-
- i = 0;
- while (i < n_properties)
- {
- reload_prop_value (window, &values[i]);
-
- ++i;
- }
-
- meta_prop_free_values (values, n_properties);
-
- g_free (values);
-}
-
-/* Fill in the MetaPropValue used to get the value of "property" */
-static void
-init_prop_value (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- MetaWindowPropHooks *hooks;
-
- value->type = META_PROP_VALUE_INVALID;
- value->atom = None;
-
- hooks = find_hooks (display, property);
- if (hooks && hooks->init_func != NULL)
- (* hooks->init_func) (display, property, value);
-}
-
-static void
-reload_prop_value (MetaWindow *window,
- MetaPropValue *value)
-{
- MetaWindowPropHooks *hooks;
-
- hooks = find_hooks (window->display, value->atom);
- if (hooks && hooks->reload_func != NULL)
- (* hooks->reload_func) (window, value);
-}
-
-static void
-init_wm_client_machine (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_STRING;
- value->atom = display->atom_WM_CLIENT_MACHINE;
-}
-
-static void
-reload_wm_client_machine (MetaWindow *window,
- MetaPropValue *value)
-{
- g_free (window->wm_client_machine);
- window->wm_client_machine = NULL;
-
- if (value->type != META_PROP_VALUE_INVALID)
- window->wm_client_machine = g_strdup (value->v.str);
-
- meta_verbose ("Window has client machine \"%s\"\n",
- window->wm_client_machine ? window->wm_client_machine : "unset");
-}
-
-static void
-init_net_wm_pid (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_CARDINAL;
- value->atom = display->atom__NET_WM_PID;
-}
-
-static void
-reload_net_wm_pid (MetaWindow *window,
- MetaPropValue *value)
-{
- if (value->type != META_PROP_VALUE_INVALID)
- {
- gulong cardinal = (int) value->v.cardinal;
-
- if (cardinal <= 0)
- meta_warning (_("Application set a bogus _NET_WM_PID %lu\n"),
- cardinal);
- else
- {
- window->net_wm_pid = cardinal;
- meta_verbose ("Window has _NET_WM_PID %d\n",
- window->net_wm_pid);
- }
- }
-}
-
-static void
-init_net_wm_user_time (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_CARDINAL;
- value->atom = display->atom__NET_WM_USER_TIME;
-}
-
-static void
-reload_net_wm_user_time (MetaWindow *window,
- MetaPropValue *value)
-{
- if (value->type != META_PROP_VALUE_INVALID)
- {
- gulong cardinal = value->v.cardinal;
- meta_window_set_user_time (window, cardinal);
- }
-}
-
-static void
-init_net_wm_user_time_window (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_WINDOW;
- value->atom = display->atom__NET_WM_USER_TIME_WINDOW;
-}
-
-static void
-reload_net_wm_user_time_window (MetaWindow *window,
- MetaPropValue *value)
-{
- if (value->type != META_PROP_VALUE_INVALID)
- {
- /* Unregister old NET_WM_USER_TIME_WINDOW */
- if (window->user_time_window != None)
- {
- /* See the comment to the meta_display_register_x_window call below. */
- meta_display_unregister_x_window (window->display,
- window->user_time_window);
- /* Don't get events on not-managed windows */
- XSelectInput (window->display->xdisplay,
- window->user_time_window,
- NoEventMask);
- }
-
-
- /* Obtain the new NET_WM_USER_TIME_WINDOW and register it */
- window->user_time_window = value->v.xwindow;
- if (window->user_time_window != None)
- {
- /* Kind of a hack; display.c:event_callback() ignores events
- * for unknown windows. We make window->user_time_window
- * known by registering it with window (despite the fact
- * that window->xwindow is already registered with window).
- * This basically means that property notifies to either the
- * window->user_time_window or window->xwindow will be
- * treated identically and will result in functions for
- * window being called to update it. Maybe we should ignore
- * any property notifies to window->user_time_window other
- * than atom__NET_WM_USER_TIME ones, but I just don't care
- * and it's not specified in the spec anyway.
- */
- meta_display_register_x_window (window->display,
- &window->user_time_window,
- window);
- /* Just listen for property notify events */
- XSelectInput (window->display->xdisplay,
- window->user_time_window,
- PropertyChangeMask);
-
- /* Manually load the _NET_WM_USER_TIME field from the given window
- * at this time as well. If the user_time_window ever broadens in
- * scope, we'll probably want to load all relevant properties here.
- */
- meta_window_reload_property_from_xwindow (
- window,
- window->user_time_window,
- window->display->atom__NET_WM_USER_TIME);
- }
- }
-}
-
-#define MAX_TITLE_LENGTH 512
-
-/**
- * Called by set_window_title and set_icon_title to set the value of
- * *target to title. It required and atom is set, it will update the
- * appropriate property.
- *
- * Returns TRUE if a new title was set.
- */
-static gboolean
-set_title_text (MetaWindow *window,
- gboolean previous_was_modified,
- const char *title,
- Atom atom,
- char **target)
-{
- char hostname[HOST_NAME_MAX + 1];
- gboolean modified = FALSE;
-
- if (!target)
- return FALSE;
-
- g_free (*target);
-
- if (!title)
- *target = g_strdup ("");
- else if (g_utf8_strlen (title, MAX_TITLE_LENGTH + 1) > MAX_TITLE_LENGTH)
- {
- *target = meta_g_utf8_strndup (title, MAX_TITLE_LENGTH);
- modified = TRUE;
- }
- /* if WM_CLIENT_MACHINE indicates this machine is on a remote host
- * lets place that hostname in the title */
- else if (window->wm_client_machine &&
- !gethostname (hostname, HOST_NAME_MAX + 1) &&
- strcmp (hostname, window->wm_client_machine))
- {
- *target = g_strdup_printf (_("%s (on %s)"),
- title, window->wm_client_machine);
- modified = TRUE;
- }
- else
- *target = g_strdup (title);
-
- if (modified && atom != None)
- meta_prop_set_utf8_string_hint (window->display,
- window->xwindow,
- atom, *target);
-
- /* Bug 330671 -- Don't forget to clear _NET_WM_VISIBLE_(ICON_)NAME */
- if (!modified && previous_was_modified)
- {
- meta_error_trap_push (window->display);
- XDeleteProperty (window->display->xdisplay,
- window->xwindow,
- atom);
- meta_error_trap_pop (window->display, FALSE);
- }
-
- return modified;
-}
-
-static void
-set_window_title (MetaWindow *window,
- const char *title)
-{
- char *str;
-
- gboolean modified =
- set_title_text (window,
- window->using_net_wm_visible_name,
- title,
- window->display->atom__NET_WM_VISIBLE_NAME,
- &window->title);
- window->using_net_wm_visible_name = modified;
-
- /* strndup is a hack since GNU libc has broken %.10s */
- str = g_strndup (window->title, 10);
- g_free (window->desc);
- window->desc = g_strdup_printf ("0x%lx (%s)", window->xwindow, str);
- g_free (str);
-
- if (window->frame)
- meta_ui_set_frame_title (window->screen->ui,
- window->frame->xwindow,
- window->title);
-}
-
-static void
-init_net_wm_name (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_UTF8;
- value->atom = display->atom__NET_WM_NAME;
-}
-
-static void
-reload_net_wm_name (MetaWindow *window,
- MetaPropValue *value)
-{
- if (value->type != META_PROP_VALUE_INVALID)
- {
- set_window_title (window, value->v.str);
- window->using_net_wm_name = TRUE;
-
- meta_verbose ("Using _NET_WM_NAME for new title of %s: \"%s\"\n",
- window->desc, window->title);
- }
- else
- {
- set_window_title (window, NULL);
- window->using_net_wm_name = FALSE;
- }
-}
-
-
-static void
-init_wm_name (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_TEXT_PROPERTY;
- value->atom = XA_WM_NAME;
-}
-
-static void
-reload_wm_name (MetaWindow *window,
- MetaPropValue *value)
-{
- if (window->using_net_wm_name)
- {
- meta_verbose ("Ignoring WM_NAME \"%s\" as _NET_WM_NAME is set\n",
- value->v.str);
- return;
- }
-
- if (value->type != META_PROP_VALUE_INVALID)
- {
- set_window_title (window, value->v.str);
-
- meta_verbose ("Using WM_NAME for new title of %s: \"%s\"\n",
- window->desc, window->title);
- }
- else
- {
- set_window_title (window, NULL);
- }
-}
-
-static void
-set_icon_title (MetaWindow *window,
- const char *title)
-{
- gboolean modified =
- set_title_text (window,
- window->using_net_wm_visible_icon_name,
- title,
- window->display->atom__NET_WM_VISIBLE_ICON_NAME,
- &window->icon_name);
- window->using_net_wm_visible_icon_name = modified;
-}
-
-static void
-init_net_wm_icon_name (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_UTF8;
- value->atom = display->atom__NET_WM_ICON_NAME;
-}
-
-static void
-reload_net_wm_icon_name (MetaWindow *window,
- MetaPropValue *value)
-{
- if (value->type != META_PROP_VALUE_INVALID)
- {
- set_icon_title (window, value->v.str);
- window->using_net_wm_icon_name = TRUE;
-
- meta_verbose ("Using _NET_WM_ICON_NAME for new title of %s: \"%s\"\n",
- window->desc, window->title);
- }
- else
- {
- set_icon_title (window, NULL);
- window->using_net_wm_icon_name = FALSE;
- }
-}
-
-
-static void
-init_wm_icon_name (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_TEXT_PROPERTY;
- value->atom = XA_WM_ICON_NAME;
-}
-
-static void
-reload_wm_icon_name (MetaWindow *window,
- MetaPropValue *value)
-{
- if (window->using_net_wm_icon_name)
- {
- meta_verbose ("Ignoring WM_ICON_NAME \"%s\" as _NET_WM_ICON_NAME is set\n",
- value->v.str);
- return;
- }
-
- if (value->type != META_PROP_VALUE_INVALID)
- {
- set_icon_title (window, value->v.str);
-
- meta_verbose ("Using WM_ICON_NAME for new title of %s: \"%s\"\n",
- window->desc, window->title);
- }
- else
- {
- set_icon_title (window, NULL);
- }
-}
-
-static void
-init_net_wm_state (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_ATOM_LIST;
- value->atom = display->atom__NET_WM_STATE;
-}
-
-static void
-reload_net_wm_state (MetaWindow *window,
- MetaPropValue *value)
-{
- int i;
-
- /* We know this is only an initial window creation,
- * clients don't change the property.
- */
-
- window->shaded = FALSE;
- window->maximized_horizontally = FALSE;
- window->maximized_vertically = FALSE;
- window->wm_state_modal = FALSE;
- window->wm_state_skip_taskbar = FALSE;
- window->wm_state_skip_pager = FALSE;
- window->wm_state_above = FALSE;
- window->wm_state_below = FALSE;
- window->wm_state_demands_attention = FALSE;
-
- if (value->type == META_PROP_VALUE_INVALID)
- return;
-
- i = 0;
- while (i < value->v.atom_list.n_atoms)
- {
- if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SHADED)
- window->shaded = TRUE;
- else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_MAXIMIZED_HORZ)
- window->maximize_horizontally_after_placement = TRUE;
- else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_MAXIMIZED_VERT)
- window->maximize_vertically_after_placement = TRUE;
- else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_HIDDEN)
- window->minimize_after_placement = TRUE;
- else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_MODAL)
- window->wm_state_modal = TRUE;
- else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SKIP_TASKBAR)
- window->wm_state_skip_taskbar = TRUE;
- else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SKIP_PAGER)
- window->wm_state_skip_pager = TRUE;
- else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_FULLSCREEN)
- window->fullscreen = TRUE;
- else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_ABOVE)
- window->wm_state_above = TRUE;
- else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_BELOW)
- window->wm_state_below = TRUE;
- else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_DEMANDS_ATTENTION)
- window->wm_state_demands_attention = TRUE;
- else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_STICKY)
- window->on_all_workspaces = TRUE;
-
- ++i;
- }
-
- meta_verbose ("Reloaded _NET_WM_STATE for %s\n",
- window->desc);
-
- meta_window_recalc_window_type (window);
-}
-
-static void
-init_mwm_hints (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_MOTIF_HINTS;
- value->atom = display->atom__MOTIF_WM_HINTS;
-}
-
-static void
-reload_mwm_hints (MetaWindow *window,
- MetaPropValue *value)
-{
- MotifWmHints *hints;
-
- window->mwm_decorated = TRUE;
- window->mwm_border_only = FALSE;
- window->mwm_has_close_func = TRUE;
- window->mwm_has_minimize_func = TRUE;
- window->mwm_has_maximize_func = TRUE;
- window->mwm_has_move_func = TRUE;
- window->mwm_has_resize_func = TRUE;
-
- if (value->type == META_PROP_VALUE_INVALID)
- {
- meta_verbose ("Window %s has no MWM hints\n", window->desc);
- meta_window_recalc_features (window);
- return;
- }
-
- hints = value->v.motif_hints;
-
- /* We support those MWM hints deemed non-stupid */
-
- meta_verbose ("Window %s has MWM hints\n",
- window->desc);
-
- if (hints->flags & MWM_HINTS_DECORATIONS)
- {
- meta_verbose ("Window %s sets MWM_HINTS_DECORATIONS 0x%lx\n",
- window->desc, hints->decorations);
-
- if (hints->decorations == 0)
- window->mwm_decorated = FALSE;
- /* some input methods use this */
- else if (hints->decorations == MWM_DECOR_BORDER)
- window->mwm_border_only = TRUE;
- }
- else
- meta_verbose ("Decorations flag unset\n");
-
- if (hints->flags & MWM_HINTS_FUNCTIONS)
- {
- gboolean toggle_value;
-
- meta_verbose ("Window %s sets MWM_HINTS_FUNCTIONS 0x%lx\n",
- window->desc, hints->functions);
-
- /* If _ALL is specified, then other flags indicate what to turn off;
- * if ALL is not specified, flags are what to turn on.
- * at least, I think so
- */
-
- if ((hints->functions & MWM_FUNC_ALL) == 0)
- {
- toggle_value = TRUE;
-
- meta_verbose ("Window %s disables all funcs then reenables some\n",
- window->desc);
- window->mwm_has_close_func = FALSE;
- window->mwm_has_minimize_func = FALSE;
- window->mwm_has_maximize_func = FALSE;
- window->mwm_has_move_func = FALSE;
- window->mwm_has_resize_func = FALSE;
- }
- else
- {
- meta_verbose ("Window %s enables all funcs then disables some\n",
- window->desc);
- toggle_value = FALSE;
- }
-
- if ((hints->functions & MWM_FUNC_CLOSE) != 0)
- {
- meta_verbose ("Window %s toggles close via MWM hints\n",
- window->desc);
- window->mwm_has_close_func = toggle_value;
- }
- if ((hints->functions & MWM_FUNC_MINIMIZE) != 0)
- {
- meta_verbose ("Window %s toggles minimize via MWM hints\n",
- window->desc);
- window->mwm_has_minimize_func = toggle_value;
- }
- if ((hints->functions & MWM_FUNC_MAXIMIZE) != 0)
- {
- meta_verbose ("Window %s toggles maximize via MWM hints\n",
- window->desc);
- window->mwm_has_maximize_func = toggle_value;
- }
- if ((hints->functions & MWM_FUNC_MOVE) != 0)
- {
- meta_verbose ("Window %s toggles move via MWM hints\n",
- window->desc);
- window->mwm_has_move_func = toggle_value;
- }
- if ((hints->functions & MWM_FUNC_RESIZE) != 0)
- {
- meta_verbose ("Window %s toggles resize via MWM hints\n",
- window->desc);
- window->mwm_has_resize_func = toggle_value;
- }
- }
- else
- meta_verbose ("Functions flag unset\n");
-
- meta_window_recalc_features (window);
-
- /* We do all this anyhow at the end of meta_window_new() */
- if (!window->constructing)
- {
- if (window->decorated)
- meta_window_ensure_frame (window);
- else
- meta_window_destroy_frame (window);
-
- meta_window_queue (window,
- META_QUEUE_MOVE_RESIZE |
- /* because ensure/destroy frame may unmap: */
- META_QUEUE_CALC_SHOWING);
- }
-}
-
-static void
-init_wm_class (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_CLASS_HINT;
- value->atom = XA_WM_CLASS;
-}
-
-static void
-reload_wm_class (MetaWindow *window,
- MetaPropValue *value)
-{
- if (window->res_class)
- g_free (window->res_class);
- if (window->res_name)
- g_free (window->res_name);
-
- window->res_class = NULL;
- window->res_name = NULL;
-
- if (value->type != META_PROP_VALUE_INVALID)
- {
- if (value->v.class_hint.res_name)
- window->res_name = g_strdup (value->v.class_hint.res_name);
-
- if (value->v.class_hint.res_class)
- window->res_class = g_strdup (value->v.class_hint.res_class);
- }
-
- meta_verbose ("Window %s class: '%s' name: '%s'\n",
- window->desc,
- window->res_class ? window->res_class : "none",
- window->res_name ? window->res_name : "none");
-}
-
-static void
-init_net_wm_desktop (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_CARDINAL;
- value->atom = display->atom__NET_WM_DESKTOP;
-}
-
-static void
-reload_net_wm_desktop (MetaWindow *window,
- MetaPropValue *value)
-{
- if (value->type != META_PROP_VALUE_INVALID)
- {
- window->initial_workspace_set = TRUE;
- window->initial_workspace = value->v.cardinal;
- meta_topic (META_DEBUG_PLACEMENT,
- "Read initial workspace prop %d for %s\n",
- window->initial_workspace, window->desc);
- }
-}
-
-static void
-init_net_startup_id (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_UTF8;
- value->atom = display->atom__NET_STARTUP_ID;
-}
-
-static void
-reload_net_startup_id (MetaWindow *window,
- MetaPropValue *value)
-{
- guint32 timestamp = window->net_wm_user_time;
- MetaWorkspace *workspace = NULL;
-
- g_free (window->startup_id);
-
- if (value->type != META_PROP_VALUE_INVALID)
- window->startup_id = g_strdup (value->v.str);
- else
- window->startup_id = NULL;
-
- /* Update timestamp and workspace on a running window */
- if (!window->constructing)
- {
- window->initial_timestamp_set = 0;
- window->initial_workspace_set = 0;
-
- if (meta_screen_apply_startup_properties (window->screen, window))
- {
-
- if (window->initial_timestamp_set)
- timestamp = window->initial_timestamp;
- if (window->initial_workspace_set)
- workspace = meta_screen_get_workspace_by_index (window->screen, window->initial_workspace);
-
- meta_window_activate_with_workspace (window, timestamp, workspace);
- }
- }
-
- meta_verbose ("New _NET_STARTUP_ID \"%s\" for %s\n",
- window->startup_id ? window->startup_id : "unset",
- window->desc);
-}
-
-static void
-init_update_counter (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_SYNC_COUNTER;
- value->atom = display->atom__NET_WM_SYNC_REQUEST_COUNTER;
-}
-
-static void
-reload_update_counter (MetaWindow *window,
- MetaPropValue *value)
-{
- if (value->type != META_PROP_VALUE_INVALID)
- {
-#ifdef HAVE_XSYNC
- XSyncCounter counter = value->v.xcounter;
-
- window->sync_request_counter = counter;
- meta_verbose ("Window has _NET_WM_SYNC_REQUEST_COUNTER 0x%lx\n",
- window->sync_request_counter);
-#endif
- }
-}
-
-
-static void
-init_normal_hints (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_SIZE_HINTS;
- value->atom = XA_WM_NORMAL_HINTS;
-}
-
-
-#define FLAG_TOGGLED_ON(old,new,flag) \
- (((old)->flags & (flag)) == 0 && \
- ((new)->flags & (flag)) != 0)
-
-#define FLAG_TOGGLED_OFF(old,new,flag) \
- (((old)->flags & (flag)) != 0 && \
- ((new)->flags & (flag)) == 0)
-
-#define FLAG_CHANGED(old,new,flag) \
- (FLAG_TOGGLED_ON(old,new,flag) || FLAG_TOGGLED_OFF(old,new,flag))
-
-static void
-spew_size_hints_differences (const XSizeHints *old,
- const XSizeHints *new)
-{
- if (FLAG_CHANGED (old, new, USPosition))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: USPosition now %s\n",
- FLAG_TOGGLED_ON (old, new, USPosition) ? "set" : "unset");
- if (FLAG_CHANGED (old, new, USSize))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: USSize now %s\n",
- FLAG_TOGGLED_ON (old, new, USSize) ? "set" : "unset");
- if (FLAG_CHANGED (old, new, PPosition))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PPosition now %s\n",
- FLAG_TOGGLED_ON (old, new, PPosition) ? "set" : "unset");
- if (FLAG_CHANGED (old, new, PSize))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PSize now %s\n",
- FLAG_TOGGLED_ON (old, new, PSize) ? "set" : "unset");
- if (FLAG_CHANGED (old, new, PMinSize))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PMinSize now %s (%d x %d -> %d x %d)\n",
- FLAG_TOGGLED_ON (old, new, PMinSize) ? "set" : "unset",
- old->min_width, old->min_height,
- new->min_width, new->min_height);
- if (FLAG_CHANGED (old, new, PMaxSize))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PMaxSize now %s (%d x %d -> %d x %d)\n",
- FLAG_TOGGLED_ON (old, new, PMaxSize) ? "set" : "unset",
- old->max_width, old->max_height,
- new->max_width, new->max_height);
- if (FLAG_CHANGED (old, new, PResizeInc))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PResizeInc now %s (width_inc %d -> %d height_inc %d -> %d)\n",
- FLAG_TOGGLED_ON (old, new, PResizeInc) ? "set" : "unset",
- old->width_inc, new->width_inc,
- old->height_inc, new->height_inc);
- if (FLAG_CHANGED (old, new, PAspect))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PAspect now %s (min %d/%d -> %d/%d max %d/%d -> %d/%d)\n",
- FLAG_TOGGLED_ON (old, new, PAspect) ? "set" : "unset",
- old->min_aspect.x, old->min_aspect.y,
- new->min_aspect.x, new->min_aspect.y,
- old->max_aspect.x, old->max_aspect.y,
- new->max_aspect.x, new->max_aspect.y);
- if (FLAG_CHANGED (old, new, PBaseSize))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PBaseSize now %s (%d x %d -> %d x %d)\n",
- FLAG_TOGGLED_ON (old, new, PBaseSize) ? "set" : "unset",
- old->base_width, old->base_height,
- new->base_width, new->base_height);
- if (FLAG_CHANGED (old, new, PWinGravity))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PWinGravity now %s (%d -> %d)\n",
- FLAG_TOGGLED_ON (old, new, PWinGravity) ? "set" : "unset",
- old->win_gravity, new->win_gravity);
-}
-
-void
-meta_set_normal_hints (MetaWindow *window,
- XSizeHints *hints)
-{
- int x, y, w, h;
- double minr, maxr;
- /* Some convenience vars */
- int minw, minh, maxw, maxh; /* min/max width/height */
- int basew, baseh, winc, hinc; /* base width/height, width/height increment */
-
- /* Save the last ConfigureRequest, which we put here.
- * Values here set in the hints are supposed to
- * be ignored.
- */
- x = window->size_hints.x;
- y = window->size_hints.y;
- w = window->size_hints.width;
- h = window->size_hints.height;
-
- /* as far as I can tell, value->v.size_hints.flags is just to
- * check whether we had old-style normal hints without gravity,
- * base size as returned by XGetNormalHints(), so we don't
- * really use it as we fixup window->size_hints to have those
- * fields if they're missing.
- */
-
- /*
- * When the window is first created, NULL hints will
- * be passed in which will initialize all of the fields
- * as if flags were zero
- */
- if (hints)
- window->size_hints = *hints;
- else
- window->size_hints.flags = 0;
-
- /* Put back saved ConfigureRequest. */
- window->size_hints.x = x;
- window->size_hints.y = y;
- window->size_hints.width = w;
- window->size_hints.height = h;
-
- /* Get base size hints */
- if (window->size_hints.flags & PBaseSize)
- {
- meta_topic (META_DEBUG_GEOMETRY, "Window %s sets base size %d x %d\n",
- window->desc,
- window->size_hints.base_width,
- window->size_hints.base_height);
- }
- else if (window->size_hints.flags & PMinSize)
- {
- window->size_hints.base_width = window->size_hints.min_width;
- window->size_hints.base_height = window->size_hints.min_height;
- }
- else
- {
- window->size_hints.base_width = 0;
- window->size_hints.base_height = 0;
- }
- window->size_hints.flags |= PBaseSize;
-
- /* Get min size hints */
- if (window->size_hints.flags & PMinSize)
- {
- meta_topic (META_DEBUG_GEOMETRY, "Window %s sets min size %d x %d\n",
- window->desc,
- window->size_hints.min_width,
- window->size_hints.min_height);
- }
- else if (window->size_hints.flags & PBaseSize)
- {
- window->size_hints.min_width = window->size_hints.base_width;
- window->size_hints.min_height = window->size_hints.base_height;
- }
- else
- {
- window->size_hints.min_width = 0;
- window->size_hints.min_height = 0;
- }
- window->size_hints.flags |= PMinSize;
-
- /* Get max size hints */
- if (window->size_hints.flags & PMaxSize)
- {
- meta_topic (META_DEBUG_GEOMETRY, "Window %s sets max size %d x %d\n",
- window->desc,
- window->size_hints.max_width,
- window->size_hints.max_height);
- }
- else
- {
- window->size_hints.max_width = G_MAXINT;
- window->size_hints.max_height = G_MAXINT;
- window->size_hints.flags |= PMaxSize;
- }
-
- /* Get resize increment hints */
- if (window->size_hints.flags & PResizeInc)
- {
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s sets resize width inc: %d height inc: %d\n",
- window->desc,
- window->size_hints.width_inc,
- window->size_hints.height_inc);
- }
- else
- {
- window->size_hints.width_inc = 1;
- window->size_hints.height_inc = 1;
- window->size_hints.flags |= PResizeInc;
- }
-
- /* Get aspect ratio hints */
- if (window->size_hints.flags & PAspect)
- {
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s sets min_aspect: %d/%d max_aspect: %d/%d\n",
- window->desc,
- window->size_hints.min_aspect.x,
- window->size_hints.min_aspect.y,
- window->size_hints.max_aspect.x,
- window->size_hints.max_aspect.y);
- }
- else
- {
- window->size_hints.min_aspect.x = 1;
- window->size_hints.min_aspect.y = G_MAXINT;
- window->size_hints.max_aspect.x = G_MAXINT;
- window->size_hints.max_aspect.y = 1;
- window->size_hints.flags |= PAspect;
- }
-
- /* Get gravity hint */
- if (window->size_hints.flags & PWinGravity)
- {
- meta_topic (META_DEBUG_GEOMETRY, "Window %s sets gravity %d\n",
- window->desc,
- window->size_hints.win_gravity);
- }
- else
- {
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s doesn't set gravity, using NW\n",
- window->desc);
- window->size_hints.win_gravity = NorthWestGravity;
- window->size_hints.flags |= PWinGravity;
- }
-
- /*** Lots of sanity checking ***/
-
- /* Verify all min & max hints are at least 1 pixel */
- if (window->size_hints.min_width < 1)
- {
- /* someone is on crack */
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s sets min width to 0, which makes no sense\n",
- window->desc);
- window->size_hints.min_width = 1;
- }
- if (window->size_hints.max_width < 1)
- {
- /* another cracksmoker */
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s sets max width to 0, which makes no sense\n",
- window->desc);
- window->size_hints.max_width = 1;
- }
- if (window->size_hints.min_height < 1)
- {
- /* another cracksmoker */
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s sets min height to 0, which makes no sense\n",
- window->desc);
- window->size_hints.min_height = 1;
- }
- if (window->size_hints.max_height < 1)
- {
- /* another cracksmoker */
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s sets max height to 0, which makes no sense\n",
- window->desc);
- window->size_hints.max_height = 1;
- }
-
- /* Verify size increment hints are at least 1 pixel */
- if (window->size_hints.width_inc < 1)
- {
- /* app authors find so many ways to smoke crack */
- window->size_hints.width_inc = 1;
- meta_topic (META_DEBUG_GEOMETRY, "Corrected 0 width_inc to 1\n");
- }
- if (window->size_hints.height_inc < 1)
- {
- /* another cracksmoker */
- window->size_hints.height_inc = 1;
- meta_topic (META_DEBUG_GEOMETRY, "Corrected 0 height_inc to 1\n");
- }
- /* divide by 0 cracksmokers; note that x & y in (min|max)_aspect are
- * numerator & denominator
- */
- if (window->size_hints.min_aspect.y < 1)
- window->size_hints.min_aspect.y = 1;
- if (window->size_hints.max_aspect.y < 1)
- window->size_hints.max_aspect.y = 1;
-
- minw = window->size_hints.min_width; minh = window->size_hints.min_height;
- maxw = window->size_hints.max_width; maxh = window->size_hints.max_height;
- basew = window->size_hints.base_width; baseh = window->size_hints.base_height;
- winc = window->size_hints.width_inc; hinc = window->size_hints.height_inc;
-
- /* Make sure min and max size hints are consistent with the base + increment
- * size hints. If they're not, it's not a real big deal, but it means the
- * effective min and max size are more restrictive than the application
- * specified values.
- */
- if ((minw - basew) % winc != 0)
- {
- /* Take advantage of integer division throwing away the remainder... */
- window->size_hints.min_width = basew + ((minw - basew)/winc + 1)*winc;
-
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s has width_inc (%d) that does not evenly divide "
- "min_width - base_width (%d - %d); thus effective "
- "min_width is really %d\n",
- window->desc,
- winc, minw, basew, window->size_hints.min_width);
- minw = window->size_hints.min_width;
- }
- if (maxw != G_MAXINT && (maxw - basew) % winc != 0)
- {
- /* Take advantage of integer division throwing away the remainder... */
- window->size_hints.max_width = basew + ((maxw - basew)/winc)*winc;
-
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s has width_inc (%d) that does not evenly divide "
- "max_width - base_width (%d - %d); thus effective "
- "max_width is really %d\n",
- window->desc,
- winc, maxw, basew, window->size_hints.max_width);
- maxw = window->size_hints.max_width;
- }
- if ((minh - baseh) % hinc != 0)
- {
- /* Take advantage of integer division throwing away the remainder... */
- window->size_hints.min_height = baseh + ((minh - baseh)/hinc + 1)*hinc;
-
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s has height_inc (%d) that does not evenly divide "
- "min_height - base_height (%d - %d); thus effective "
- "min_height is really %d\n",
- window->desc,
- hinc, minh, baseh, window->size_hints.min_height);
- minh = window->size_hints.min_height;
- }
- if (maxh != G_MAXINT && (maxh - baseh) % hinc != 0)
- {
- /* Take advantage of integer division throwing away the remainder... */
- window->size_hints.max_height = baseh + ((maxh - baseh)/hinc)*hinc;
-
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s has height_inc (%d) that does not evenly divide "
- "max_height - base_height (%d - %d); thus effective "
- "max_height is really %d\n",
- window->desc,
- hinc, maxh, baseh, window->size_hints.max_height);
- maxh = window->size_hints.max_height;
- }
-
- /* make sure maximum size hints are compatible with minimum size hints; min
- * size hints take precedence.
- */
- if (window->size_hints.max_width < window->size_hints.min_width)
- {
- /* another cracksmoker */
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s sets max width %d less than min width %d, "
- "disabling resize\n",
- window->desc,
- window->size_hints.max_width,
- window->size_hints.min_width);
- maxw = window->size_hints.max_width = window->size_hints.min_width;
- }
- if (window->size_hints.max_height < window->size_hints.min_height)
- {
- /* another cracksmoker */
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s sets max height %d less than min height %d, "
- "disabling resize\n",
- window->desc,
- window->size_hints.max_height,
- window->size_hints.min_height);
- maxh = window->size_hints.max_height = window->size_hints.min_height;
- }
-
- /* Make sure the aspect ratio hints are sane. */
- minr = window->size_hints.min_aspect.x /
- (double)window->size_hints.min_aspect.y;
- maxr = window->size_hints.max_aspect.x /
- (double)window->size_hints.max_aspect.y;
- if (minr > maxr)
- {
- /* another cracksmoker; not even minimally (self) consistent */
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s sets min aspect ratio larger than max aspect "
- "ratio; disabling aspect ratio constraints.\n",
- window->desc);
- window->size_hints.min_aspect.x = 1;
- window->size_hints.min_aspect.y = G_MAXINT;
- window->size_hints.max_aspect.x = G_MAXINT;
- window->size_hints.max_aspect.y = 1;
- }
- else /* check consistency of aspect ratio hints with other hints */
- {
- if (minh > 0 && minr > (maxw / (double)minh))
- {
- /* another cracksmoker */
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s sets min aspect ratio larger than largest "
- "aspect ratio possible given min/max size constraints; "
- "disabling min aspect ratio constraint.\n",
- window->desc);
- window->size_hints.min_aspect.x = 1;
- window->size_hints.min_aspect.y = G_MAXINT;
- }
- if (maxr < (minw / (double)maxh))
- {
- /* another cracksmoker */
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s sets max aspect ratio smaller than smallest "
- "aspect ratio possible given min/max size constraints; "
- "disabling max aspect ratio constraint.\n",
- window->desc);
- window->size_hints.max_aspect.x = G_MAXINT;
- window->size_hints.max_aspect.y = 1;
- }
- /* FIXME: Would be nice to check that aspect ratios are
- * consistent with base and size increment constraints.
- */
- }
-}
-
-static void
-reload_normal_hints (MetaWindow *window,
- MetaPropValue *value)
-{
- if (value->type != META_PROP_VALUE_INVALID)
- {
- XSizeHints old_hints;
-
- meta_topic (META_DEBUG_GEOMETRY, "Updating WM_NORMAL_HINTS for %s\n", window->desc);
-
- old_hints = window->size_hints;
-
- meta_set_normal_hints (window, value->v.size_hints.hints);
-
- spew_size_hints_differences (&old_hints, &window->size_hints);
-
- meta_window_recalc_features (window);
- }
-}
-
-
-static void
-init_wm_protocols (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_ATOM_LIST;
- value->atom = display->atom_WM_PROTOCOLS;
-}
-
-static void
-reload_wm_protocols (MetaWindow *window,
- MetaPropValue *value)
-{
- int i;
-
- window->take_focus = FALSE;
- window->delete_window = FALSE;
- window->net_wm_ping = FALSE;
-
- if (value->type == META_PROP_VALUE_INVALID)
- return;
-
- i = 0;
- while (i < value->v.atom_list.n_atoms)
- {
- if (value->v.atom_list.atoms[i] ==
- window->display->atom_WM_TAKE_FOCUS)
- window->take_focus = TRUE;
- else if (value->v.atom_list.atoms[i] ==
- window->display->atom_WM_DELETE_WINDOW)
- window->delete_window = TRUE;
- else if (value->v.atom_list.atoms[i] ==
- window->display->atom__NET_WM_PING)
- window->net_wm_ping = TRUE;
- ++i;
- }
-
- meta_verbose ("New _NET_STARTUP_ID \"%s\" for %s\n",
- window->startup_id ? window->startup_id : "unset",
- window->desc);
-}
-
-static void
-init_wm_hints (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_WM_HINTS;
- value->atom = XA_WM_HINTS;
-}
-
-static void
-reload_wm_hints (MetaWindow *window,
- MetaPropValue *value)
-{
- Window old_group_leader;
-
- old_group_leader = window->xgroup_leader;
-
- /* Fill in defaults */
- window->input = TRUE;
- window->initially_iconic = FALSE;
- window->xgroup_leader = None;
- window->wm_hints_pixmap = None;
- window->wm_hints_mask = None;
-
- if (value->type != META_PROP_VALUE_INVALID)
- {
- const XWMHints *hints = value->v.wm_hints;
-
- if (hints->flags & InputHint)
- window->input = hints->input;
-
- if (hints->flags & StateHint)
- window->initially_iconic = (hints->initial_state == IconicState);
-
- if (hints->flags & WindowGroupHint)
- window->xgroup_leader = hints->window_group;
-
- if (hints->flags & IconPixmapHint)
- window->wm_hints_pixmap = hints->icon_pixmap;
-
- if (hints->flags & IconMaskHint)
- window->wm_hints_mask = hints->icon_mask;
-
- meta_verbose ("Read WM_HINTS input: %d iconic: %d group leader: 0x%lx pixmap: 0x%lx mask: 0x%lx\n",
- window->input, window->initially_iconic,
- window->xgroup_leader,
- window->wm_hints_pixmap,
- window->wm_hints_mask);
- }
-
- if (window->xgroup_leader != old_group_leader)
- {
- meta_verbose ("Window %s changed its group leader to 0x%lx\n",
- window->desc, window->xgroup_leader);
-
- meta_window_group_leader_changed (window);
- }
-
- meta_icon_cache_property_changed (&window->icon_cache,
- window->display,
- XA_WM_HINTS);
-
- meta_window_queue (window, META_QUEUE_UPDATE_ICON | META_QUEUE_MOVE_RESIZE);
-}
-
-static void
-init_transient_for (MetaDisplay *display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_WINDOW;
- value->atom = XA_WM_TRANSIENT_FOR;
-}
-
-static void
-reload_transient_for (MetaWindow *window,
- MetaPropValue *value)
-{
- window->xtransient_for = None;
-
- if (value->type != META_PROP_VALUE_INVALID)
- window->xtransient_for = value->v.xwindow;
-
- /* Make sure transient_for is valid */
- if (window->xtransient_for != None &&
- meta_display_lookup_x_window (window->display,
- window->xtransient_for) == NULL)
- {
- meta_warning (_("Invalid WM_TRANSIENT_FOR window 0x%lx specified "
- "for %s.\n"),
- window->xtransient_for, window->desc);
- window->xtransient_for = None;
- }
-
- window->transient_parent_is_root_window =
- window->xtransient_for == window->screen->xroot;
-
- if (window->xtransient_for != None)
- meta_verbose ("Window %s transient for 0x%lx (root = %d)\n", window->desc,
- window->xtransient_for, window->transient_parent_is_root_window);
- else
- meta_verbose ("Window %s is not transient\n", window->desc);
-
- /* may now be a dialog */
- meta_window_recalc_window_type (window);
-
- /* update stacking constraints */
- meta_stack_update_transient (window->screen->stack, window);
-
- /* possibly change its group. We treat being a window's transient as
- * equivalent to making it your group leader, to work around shortcomings
- * in programs such as xmms-- see #328211.
- */
- if (window->xtransient_for != None &&
- window->xgroup_leader != None &&
- window->xtransient_for != window->xgroup_leader)
- meta_window_group_leader_changed (window);
-
- if (!window->constructing)
- meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
-}
-
-#define N_HOOKS 26
-
-void
-meta_display_init_window_prop_hooks (MetaDisplay *display)
-{
- int i;
- MetaWindowPropHooks *hooks;
-
- g_assert (display->prop_hooks == NULL);
-
- display->prop_hooks = g_new0 (MetaWindowPropHooks, N_HOOKS);
- hooks = display->prop_hooks;
-
- i = 0;
-
- hooks[i].property = display->atom_WM_STATE;
- hooks[i].init_func = NULL;
- hooks[i].reload_func = NULL;
- ++i;
-
- hooks[i].property = display->atom_WM_CLIENT_MACHINE;
- hooks[i].init_func = init_wm_client_machine;
- hooks[i].reload_func = reload_wm_client_machine;
- ++i;
-
- hooks[i].property = display->atom__NET_WM_PID;
- hooks[i].init_func = init_net_wm_pid;
- hooks[i].reload_func = reload_net_wm_pid;
- ++i;
-
- hooks[i].property = display->atom__NET_WM_USER_TIME;
- hooks[i].init_func = init_net_wm_user_time;
- hooks[i].reload_func = reload_net_wm_user_time;
- ++i;
-
- hooks[i].property = display->atom__NET_WM_NAME;
- hooks[i].init_func = init_net_wm_name;
- hooks[i].reload_func = reload_net_wm_name;
- ++i;
-
- hooks[i].property = XA_WM_NAME;
- hooks[i].init_func = init_wm_name;
- hooks[i].reload_func = reload_wm_name;
- ++i;
-
- hooks[i].property = display->atom__NET_WM_ICON_NAME;
- hooks[i].init_func = init_net_wm_icon_name;
- hooks[i].reload_func = reload_net_wm_icon_name;
- ++i;
-
- hooks[i].property = XA_WM_ICON_NAME;
- hooks[i].init_func = init_wm_icon_name;
- hooks[i].reload_func = reload_wm_icon_name;
- ++i;
-
- hooks[i].property = display->atom__NET_WM_STATE;
- hooks[i].init_func = init_net_wm_state;
- hooks[i].reload_func = reload_net_wm_state;
- ++i;
-
- hooks[i].property = display->atom__MOTIF_WM_HINTS;
- hooks[i].init_func = init_mwm_hints;
- hooks[i].reload_func = reload_mwm_hints;
- ++i;
-
- hooks[i].property = display->atom__NET_WM_ICON_GEOMETRY;
- hooks[i].init_func = NULL;
- hooks[i].reload_func = NULL;
- ++i;
-
- hooks[i].property = XA_WM_CLASS;
- hooks[i].init_func = init_wm_class;
- hooks[i].reload_func = reload_wm_class;
- ++i;
-
- hooks[i].property = display->atom_WM_CLIENT_LEADER;
- hooks[i].init_func = NULL;
- hooks[i].reload_func = NULL;
- ++i;
-
- hooks[i].property = display->atom_SM_CLIENT_ID;
- hooks[i].init_func = NULL;
- hooks[i].reload_func = NULL;
- ++i;
-
- hooks[i].property = display->atom_WM_WINDOW_ROLE;
- hooks[i].init_func = NULL;
- hooks[i].reload_func = NULL;
- ++i;
-
- hooks[i].property = display->atom__NET_WM_WINDOW_TYPE;
- hooks[i].init_func = NULL;
- hooks[i].reload_func = NULL;
- ++i;
-
- hooks[i].property = display->atom__NET_WM_DESKTOP;
- hooks[i].init_func = init_net_wm_desktop;
- hooks[i].reload_func = reload_net_wm_desktop;
- ++i;
-
- hooks[i].property = display->atom__NET_WM_STRUT;
- hooks[i].init_func = NULL;
- hooks[i].reload_func = NULL;
- ++i;
-
- hooks[i].property = display->atom__NET_WM_STRUT_PARTIAL;
- hooks[i].init_func = NULL;
- hooks[i].reload_func = NULL;
- ++i;
-
- hooks[i].property = display->atom__NET_STARTUP_ID;
- hooks[i].init_func = init_net_startup_id;
- hooks[i].reload_func = reload_net_startup_id;
- ++i;
-
- hooks[i].property = display->atom__NET_WM_SYNC_REQUEST_COUNTER;
- hooks[i].init_func = init_update_counter;
- hooks[i].reload_func = reload_update_counter;
- ++i;
-
- hooks[i].property = XA_WM_NORMAL_HINTS;
- hooks[i].init_func = init_normal_hints;
- hooks[i].reload_func = reload_normal_hints;
- ++i;
-
- hooks[i].property = display->atom_WM_PROTOCOLS;
- hooks[i].init_func = init_wm_protocols;
- hooks[i].reload_func = reload_wm_protocols;
- ++i;
-
- hooks[i].property = XA_WM_HINTS;
- hooks[i].init_func = init_wm_hints;
- hooks[i].reload_func = reload_wm_hints;
- ++i;
-
- hooks[i].property = XA_WM_TRANSIENT_FOR;
- hooks[i].init_func = init_transient_for;
- hooks[i].reload_func = reload_transient_for;
- ++i;
-
- hooks[i].property = display->atom__NET_WM_USER_TIME_WINDOW;
- hooks[i].init_func = init_net_wm_user_time_window;
- hooks[i].reload_func = reload_net_wm_user_time_window;
- ++i;
-
- if (i != N_HOOKS)
- {
- g_error ("Initialized %d hooks should have been %d\n", i, N_HOOKS);
- }
-}
-
-void
-meta_display_free_window_prop_hooks (MetaDisplay *display)
-{
- g_assert (display->prop_hooks != NULL);
-
- g_free (display->prop_hooks);
- display->prop_hooks = NULL;
-}
-
-static MetaWindowPropHooks*
-find_hooks (MetaDisplay *display,
- Atom property)
-{
- int i;
-
- /* FIXME we could sort the array and do binary search or
- * something
- */
-
- i = 0;
- while (i < N_HOOKS)
- {
- if (display->prop_hooks[i].property == property)
- return &display->prop_hooks[i];
-
- ++i;
- }
-
- return NULL;
-}
diff --git a/src/core/window-props.h b/src/core/window-props.h
deleted file mode 100644
index 9ac3cf19..00000000
--- a/src/core/window-props.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * \file window-props.h MetaWindow property handling
- *
- * A system which can inspect sets of properties of given windows
- * and take appropriate action given their values.
- *
- * Note that all the meta_window_reload_propert* functions require a
- * round trip to the server.
- */
-
-/*
- * Copyright (C) 2001, 2002 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_WINDOW_PROPS_H
-#define META_WINDOW_PROPS_H
-
-#include "window-private.h"
-
-/**
- * Requests the current values of a single property for a given
- * window from the server, and deals with it appropriately.
- * Does not return it to the caller (it's been dealt with!)
- *
- * \param window The window.
- * \param property A single X atom.
- */
-void meta_window_reload_property (MetaWindow *window,
- Atom property);
-
-
-/**
- * Requests the current values of a set of properties for a given
- * window from the server, and deals with them appropriately.
- * Does not return them to the caller (they've been dealt with!)
- *
- * \param window The window.
- * \param properties A pointer to a list of X atoms, "n_properties" long.
- * \param n_properties The length of the properties list.
- */
-void meta_window_reload_properties (MetaWindow *window,
- const Atom *properties,
- int n_properties);
-
-/**
- * Requests the current values of a single property for a given
- * window from the server, and deals with it appropriately.
- * Does not return it to the caller (it's been dealt with!)
- *
- * \param window A window on the same display as the one we're
- * investigating (only used to find the display)
- * \param xwindow The X handle for the window.
- * \param property A single X atom.
- */
-void meta_window_reload_property_from_xwindow
- (MetaWindow *window,
- Window xwindow,
- Atom property);
-
-/**
- * Requests the current values of a set of properties for a given
- * window from the server, and deals with them appropriately.
- * Does not return them to the caller (they've been dealt with!)
- *
- * \param window A window on the same display as the one we're
- * investigating (only used to find the display)
- * \param xwindow The X handle for the window.
- * \param properties A pointer to a list of X atoms, "n_properties" long.
- * \param n_properties The length of the properties list.
- */
-void meta_window_reload_properties_from_xwindow
- (MetaWindow *window,
- Window xwindow,
- const Atom *properties,
- int n_properties);
-
-/**
- * Initialises the hooks used for the reload_propert* functions
- * on a particular display, and stores a pointer to them in the
- * display.
- *
- * \param display The display.
- */
-void meta_display_init_window_prop_hooks (MetaDisplay *display);
-
-/**
- * Frees the hooks used for the reload_propert* functions
- * for a particular display.
- *
- * \param display The display.
- */
-void meta_display_free_window_prop_hooks (MetaDisplay *display);
-
-/**
- * Sets the size hints for a window. This happens when a
- * WM_NORMAL_HINTS property is set on a window, but it is public
- * because the size hints are set to defaults when a window is
- * created. See
- * http://tronche.com/gui/x/icccm/sec-4.html#WM_NORMAL_HINTS
- * for the X details.
- *
- * \param window The window to set the size hints on.
- * \param hints Either some X size hints, or NULL for default.
- */
-void meta_set_normal_hints (MetaWindow *window,
- XSizeHints *hints);
-
-#endif /* META_WINDOW_PROPS_H */
diff --git a/src/core/window.c b/src/core/window.c
deleted file mode 100644
index 0f93c409..00000000
--- a/src/core/window.c
+++ /dev/null
@@ -1,8262 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity X managed windows */
-
-/*
- * Copyright (C) 2001 Havoc Pennington, Anders Carlsson
- * Copyright (C) 2002, 2003 Red Hat, Inc.
- * Copyright (C) 2003 Rob Adams
- * Copyright (C) 2004-2006 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include "window-private.h"
-#include "edge-resistance.h"
-#include "util.h"
-#include "frame-private.h"
-#include "errors.h"
-#include "workspace.h"
-#include "stack.h"
-#include "keybindings.h"
-#include "ui.h"
-#include "place.h"
-#include "session.h"
-#include "effects.h"
-#include "prefs.h"
-#include "resizepopup.h"
-#include "xprops.h"
-#include "group.h"
-#include "window-props.h"
-#include "constraints.h"
-#include "compositor.h"
-#include "effects.h"
-
-#include <X11/Xatom.h>
-#include <string.h>
-
-#ifdef HAVE_SHAPE
-#include <X11/extensions/shape.h>
-#endif
-
-static int destroying_windows_disallowed = 0;
-
-
-static void update_sm_hints (MetaWindow *window);
-static void update_role (MetaWindow *window);
-static void update_net_wm_type (MetaWindow *window);
-static void update_net_frame_extents (MetaWindow *window);
-static void recalc_window_type (MetaWindow *window);
-static void recalc_window_features (MetaWindow *window);
-static void invalidate_work_areas (MetaWindow *window);
-static void recalc_window_type (MetaWindow *window);
-static void set_wm_state (MetaWindow *window,
- int state);
-static void set_net_wm_state (MetaWindow *window);
-
-static void send_configure_notify (MetaWindow *window);
-static gboolean process_property_notify (MetaWindow *window,
- XPropertyEvent *event);
-static void meta_window_show (MetaWindow *window);
-static void meta_window_hide (MetaWindow *window);
-
-static void meta_window_save_rect (MetaWindow *window);
-static void save_user_window_placement (MetaWindow *window);
-static void force_save_user_window_placement (MetaWindow *window);
-
-static void meta_window_move_resize_internal (MetaWindow *window,
- MetaMoveResizeFlags flags,
- int resize_gravity,
- int root_x_nw,
- int root_y_nw,
- int w,
- int h);
-
-static void ensure_mru_position_after (MetaWindow *window,
- MetaWindow *after_this_one);
-
-
-static void meta_window_move_resize_now (MetaWindow *window);
-
-static void meta_window_unqueue (MetaWindow *window, guint queuebits);
-
-static void update_move (MetaWindow *window,
- gboolean snap,
- int x,
- int y);
-static gboolean update_move_timeout (gpointer data);
-static void update_resize (MetaWindow *window,
- gboolean snap,
- int x,
- int y,
- gboolean force);
-static gboolean update_resize_timeout (gpointer data);
-
-
-static void meta_window_flush_calc_showing (MetaWindow *window);
-
-static gboolean queue_calc_showing_func (MetaWindow *window,
- void *data);
-
-static void meta_window_apply_session_info (MetaWindow *window,
- const MetaWindowSessionInfo *info);
-
-static void unmaximize_window_before_freeing (MetaWindow *window);
-static void unminimize_window_and_all_transient_parents (MetaWindow *window);
-
-/* Idle handlers for the three queues. The "data" parameter in each case
- * will be a GINT_TO_POINTER of the index into the queue arrays to use.
- *
- * TODO: Possibly there is still some code duplication among these, which we
- * need to sort out at some point.
- */
-static gboolean idle_calc_showing (gpointer data);
-static gboolean idle_move_resize (gpointer data);
-static gboolean idle_update_icon (gpointer data);
-
-#ifdef WITH_VERBOSE_MODE
-static const char*
-wm_state_to_string (int state)
-{
- switch (state)
- {
- case NormalState:
- return "NormalState";
- case IconicState:
- return "IconicState";
- case WithdrawnState:
- return "WithdrawnState";
- }
-
- return "Unknown";
-}
-#endif
-
-static gboolean
-is_desktop_or_dock_foreach (MetaWindow *window,
- void *data)
-{
- gboolean *result = data;
-
- *result =
- window->type == META_WINDOW_DESKTOP ||
- window->type == META_WINDOW_DOCK;
- if (*result)
- return FALSE; /* stop as soon as we find one */
- else
- return TRUE;
-}
-
-/* window is the window that's newly mapped provoking
- * the possible change
- */
-static void
-maybe_leave_show_desktop_mode (MetaWindow *window)
-{
- gboolean is_desktop_or_dock;
-
- if (!window->screen->active_workspace->showing_desktop)
- return;
-
- /* If the window is a transient for the dock or desktop, don't
- * leave show desktop mode when the window opens. That's
- * so you can e.g. hide all windows, manipulate a file on
- * the desktop via a dialog, then unshow windows again.
- */
- is_desktop_or_dock = FALSE;
- is_desktop_or_dock_foreach (window,
- &is_desktop_or_dock);
-
- meta_window_foreach_ancestor (window, is_desktop_or_dock_foreach,
- &is_desktop_or_dock);
-
- if (!is_desktop_or_dock)
- {
- meta_screen_minimize_all_on_active_workspace_except (window->screen,
- window);
- meta_screen_unshow_desktop (window->screen);
- }
-}
-
-MetaWindow*
-meta_window_new (MetaDisplay *display,
- Window xwindow,
- gboolean must_be_viewable)
-{
- XWindowAttributes attrs;
- MetaWindow *window;
-
- meta_display_grab (display);
- meta_error_trap_push (display); /* Push a trap over all of window
- * creation, to reduce XSync() calls
- */
-
- meta_error_trap_push_with_return (display);
-
- if (XGetWindowAttributes (display->xdisplay,xwindow, &attrs))
- {
- if(meta_error_trap_pop_with_return (display, TRUE) != Success)
- {
- meta_verbose ("Failed to get attributes for window 0x%lx\n",
- xwindow);
- meta_error_trap_pop (display, TRUE);
- meta_display_ungrab (display);
- return NULL;
- }
- window = meta_window_new_with_attrs (display, xwindow,
- must_be_viewable, &attrs);
- }
- else
- {
- meta_error_trap_pop_with_return (display, TRUE);
- meta_verbose ("Failed to get attributes for window 0x%lx\n",
- xwindow);
- meta_error_trap_pop (display, TRUE);
- meta_display_ungrab (display);
- return NULL;
- }
-
-
- meta_error_trap_pop (display, FALSE);
- meta_display_ungrab (display);
-
- return window;
-}
-
-MetaWindow*
-meta_window_new_with_attrs (MetaDisplay *display,
- Window xwindow,
- gboolean must_be_viewable,
- XWindowAttributes *attrs)
-{
- MetaWindow *window;
- GSList *tmp;
- MetaWorkspace *space;
- gulong existing_wm_state;
- gulong event_mask;
- MetaMoveResizeFlags flags;
-#define N_INITIAL_PROPS 19
- Atom initial_props[N_INITIAL_PROPS];
- int i;
- gboolean has_shape;
-
- g_assert (attrs != NULL);
- g_assert (N_INITIAL_PROPS == (int) G_N_ELEMENTS (initial_props));
-
- meta_verbose ("Attempting to manage 0x%lx\n", xwindow);
-
- if (meta_display_xwindow_is_a_no_focus_window (display, xwindow))
- {
- meta_verbose ("Not managing no_focus_window 0x%lx\n",
- xwindow);
- return NULL;
- }
-
- if (attrs->override_redirect)
- {
- meta_verbose ("Deciding not to manage override_redirect window 0x%lx\n", xwindow);
- return NULL;
- }
-
- /* Grab server */
- meta_display_grab (display);
- meta_error_trap_push (display); /* Push a trap over all of window
- * creation, to reduce XSync() calls
- */
-
- meta_verbose ("must_be_viewable = %d attrs->map_state = %d (%s)\n",
- must_be_viewable,
- attrs->map_state,
- (attrs->map_state == IsUnmapped) ?
- "IsUnmapped" :
- (attrs->map_state == IsViewable) ?
- "IsViewable" :
- (attrs->map_state == IsUnviewable) ?
- "IsUnviewable" :
- "(unknown)");
-
- existing_wm_state = WithdrawnState;
- if (must_be_viewable && attrs->map_state != IsViewable)
- {
- /* Only manage if WM_STATE is IconicState or NormalState */
- gulong state;
-
- /* WM_STATE isn't a cardinal, it's type WM_STATE, but is an int */
- if (!(meta_prop_get_cardinal_with_atom_type (display, xwindow,
- display->atom_WM_STATE,
- display->atom_WM_STATE,
- &state) &&
- (state == IconicState || state == NormalState)))
- {
- meta_verbose ("Deciding not to manage unmapped or unviewable window 0x%lx\n", xwindow);
- meta_error_trap_pop (display, TRUE);
- meta_display_ungrab (display);
- return NULL;
- }
-
- existing_wm_state = state;
- meta_verbose ("WM_STATE of %lx = %s\n", xwindow,
- wm_state_to_string (existing_wm_state));
- }
-
- meta_error_trap_push_with_return (display);
-
- XAddToSaveSet (display->xdisplay, xwindow);
-
- event_mask =
- PropertyChangeMask | EnterWindowMask | LeaveWindowMask |
- FocusChangeMask | ColormapChangeMask;
-
- XSelectInput (display->xdisplay, xwindow, event_mask);
-
- has_shape = FALSE;
-#ifdef HAVE_SHAPE
- if (META_DISPLAY_HAS_SHAPE (display))
- {
- int x_bounding, y_bounding, x_clip, y_clip;
- unsigned w_bounding, h_bounding, w_clip, h_clip;
- int bounding_shaped, clip_shaped;
-
- XShapeSelectInput (display->xdisplay, xwindow, ShapeNotifyMask);
-
- XShapeQueryExtents (display->xdisplay, xwindow,
- &bounding_shaped, &x_bounding, &y_bounding,
- &w_bounding, &h_bounding,
- &clip_shaped, &x_clip, &y_clip,
- &w_clip, &h_clip);
-
- has_shape = bounding_shaped != FALSE;
-
- meta_topic (META_DEBUG_SHAPES,
- "Window has_shape = %d extents %d,%d %u x %u\n",
- has_shape, x_bounding, y_bounding,
- w_bounding, h_bounding);
- }
-#endif
-
- /* Get rid of any borders */
- if (attrs->border_width != 0)
- XSetWindowBorderWidth (display->xdisplay, xwindow, 0);
-
- /* Get rid of weird gravities */
- if (attrs->win_gravity != NorthWestGravity)
- {
- XSetWindowAttributes set_attrs;
-
- set_attrs.win_gravity = NorthWestGravity;
-
- XChangeWindowAttributes (display->xdisplay,
- xwindow,
- CWWinGravity,
- &set_attrs);
- }
-
- if (meta_error_trap_pop_with_return (display, FALSE) != Success)
- {
- meta_verbose ("Window 0x%lx disappeared just as we tried to manage it\n",
- xwindow);
- meta_error_trap_pop (display, FALSE);
- meta_display_ungrab (display);
- return NULL;
- }
-
- g_assert (!attrs->override_redirect);
-
- window = g_new (MetaWindow, 1);
-
- window->constructing = TRUE;
-
- window->dialog_pid = -1;
- window->dialog_pipe = -1;
-
- window->xwindow = xwindow;
-
- /* this is in window->screen->display, but that's too annoying to
- * type
- */
- window->display = display;
- window->workspace = NULL;
-
-#ifdef HAVE_XSYNC
- window->sync_request_counter = None;
- window->sync_request_serial = 0;
- window->sync_request_time.tv_sec = 0;
- window->sync_request_time.tv_usec = 0;
-#endif
-
- window->screen = NULL;
- tmp = display->screens;
- while (tmp != NULL)
- {
- MetaScreen *scr = tmp->data;
-
- if (scr->xroot == attrs->root)
- {
- window->screen = tmp->data;
- break;
- }
-
- tmp = tmp->next;
- }
-
- g_assert (window->screen);
-
- window->desc = g_strdup_printf ("0x%lx", window->xwindow);
-
- /* avoid tons of stack updates */
- meta_stack_freeze (window->screen->stack);
-
- window->has_shape = has_shape;
-
- window->rect.x = attrs->x;
- window->rect.y = attrs->y;
- window->rect.width = attrs->width;
- window->rect.height = attrs->height;
-
- /* And border width, size_hints are the "request" */
- window->border_width = attrs->border_width;
- window->size_hints.x = attrs->x;
- window->size_hints.y = attrs->y;
- window->size_hints.width = attrs->width;
- window->size_hints.height = attrs->height;
- /* initialize the remaining size_hints as if size_hints.flags were zero */
- meta_set_normal_hints (window, NULL);
-
- /* And this is our unmaximized size */
- window->saved_rect = window->rect;
- window->user_rect = window->rect;
-
- window->depth = attrs->depth;
- window->xvisual = attrs->visual;
- window->colormap = attrs->colormap;
-
- window->title = NULL;
- window->icon_name = NULL;
- window->icon = NULL;
- window->mini_icon = NULL;
- meta_icon_cache_init (&window->icon_cache);
- window->wm_hints_pixmap = None;
- window->wm_hints_mask = None;
-
- window->frame = NULL;
- window->has_focus = FALSE;
-
- window->maximized_horizontally = FALSE;
- window->maximized_vertically = FALSE;
- window->maximize_horizontally_after_placement = FALSE;
- window->maximize_vertically_after_placement = FALSE;
- window->minimize_after_placement = FALSE;
- window->fullscreen = FALSE;
- window->fullscreen_monitors[0] = -1;
- window->require_fully_onscreen = TRUE;
- window->require_on_single_xinerama = TRUE;
- window->require_titlebar_visible = TRUE;
- window->on_all_workspaces = FALSE;
- window->shaded = FALSE;
- window->initially_iconic = FALSE;
- window->minimized = FALSE;
- window->was_minimized = FALSE;
- window->tab_unminimized = FALSE;
- window->iconic = FALSE;
- window->mapped = attrs->map_state != IsUnmapped;
- /* if already mapped, no need to worry about focus-on-first-time-showing */
- window->showing_for_first_time = !window->mapped;
- /* if already mapped we don't want to do the placement thing */
- window->placed = window->mapped;
- if (window->placed)
- meta_topic (META_DEBUG_PLACEMENT,
- "Not placing window 0x%lx since it's already mapped\n",
- xwindow);
- window->denied_focus_and_not_transient = FALSE;
- window->unmanaging = FALSE;
- window->is_in_queues = 0;
- window->keys_grabbed = FALSE;
- window->grab_on_frame = FALSE;
- window->all_keys_grabbed = FALSE;
- window->withdrawn = FALSE;
- window->initial_workspace_set = FALSE;
- window->initial_timestamp_set = FALSE;
- window->net_wm_user_time_set = FALSE;
- window->user_time_window = None;
- window->calc_placement = FALSE;
- window->shaken_loose = FALSE;
- window->have_focus_click_grab = FALSE;
- window->disable_sync = FALSE;
-
- window->unmaps_pending = 0;
-
- window->mwm_decorated = TRUE;
- window->mwm_border_only = FALSE;
- window->mwm_has_close_func = TRUE;
- window->mwm_has_minimize_func = TRUE;
- window->mwm_has_maximize_func = TRUE;
- window->mwm_has_move_func = TRUE;
- window->mwm_has_resize_func = TRUE;
-
- window->decorated = TRUE;
- window->has_close_func = TRUE;
- window->has_minimize_func = TRUE;
- window->has_maximize_func = TRUE;
- window->has_move_func = TRUE;
- window->has_resize_func = TRUE;
-
- window->has_shade_func = TRUE;
-
- window->has_fullscreen_func = TRUE;
-
- window->always_sticky = FALSE;
-
- window->wm_state_modal = FALSE;
- window->skip_taskbar = FALSE;
- window->skip_pager = FALSE;
- window->wm_state_skip_taskbar = FALSE;
- window->wm_state_skip_pager = FALSE;
- window->wm_state_above = FALSE;
- window->wm_state_below = FALSE;
- window->wm_state_demands_attention = FALSE;
-
- window->res_class = NULL;
- window->res_name = NULL;
- window->role = NULL;
- window->sm_client_id = NULL;
- window->wm_client_machine = NULL;
- window->startup_id = NULL;
-
- window->net_wm_pid = -1;
-
- window->xtransient_for = None;
- window->xclient_leader = None;
- window->transient_parent_is_root_window = FALSE;
-
- window->type = META_WINDOW_NORMAL;
- window->type_atom = None;
-
- window->struts = NULL;
-
- window->using_net_wm_name = FALSE;
- window->using_net_wm_visible_name = FALSE;
- window->using_net_wm_icon_name = FALSE;
- window->using_net_wm_visible_icon_name = FALSE;
-
- window->need_reread_icon = TRUE;
-
- window->layer = META_LAYER_LAST; /* invalid value */
- window->stack_position = -1;
- window->initial_workspace = 0; /* not used */
- window->initial_timestamp = 0; /* not used */
-
- meta_display_register_x_window (display, &window->xwindow, window);
-
-
- /* assign the window to its group, or create a new group if needed
- */
- window->group = NULL;
- window->xgroup_leader = None;
- meta_window_compute_group (window);
-
- /* Fill these in the order we want them to be gotten. we want to
- * get window name and class first so we can use them in error
- * messages and such. However, name is modified depending on
- * wm_client_machine, so push it slightly sooner.
- */
- i = 0;
- initial_props[i++] = display->atom_WM_CLIENT_MACHINE;
- initial_props[i++] = display->atom__NET_WM_NAME;
- initial_props[i++] = XA_WM_CLASS;
- initial_props[i++] = display->atom__NET_WM_PID;
- initial_props[i++] = XA_WM_NAME;
- initial_props[i++] = display->atom__NET_WM_ICON_NAME;
- initial_props[i++] = XA_WM_ICON_NAME;
- initial_props[i++] = display->atom__NET_WM_DESKTOP;
- initial_props[i++] = display->atom__NET_STARTUP_ID;
- initial_props[i++] = display->atom__NET_WM_SYNC_REQUEST_COUNTER;
- initial_props[i++] = XA_WM_NORMAL_HINTS;
- initial_props[i++] = display->atom_WM_PROTOCOLS;
- initial_props[i++] = XA_WM_HINTS;
- initial_props[i++] = display->atom__NET_WM_USER_TIME;
- initial_props[i++] = display->atom__NET_WM_STATE;
- initial_props[i++] = display->atom__MOTIF_WM_HINTS;
- initial_props[i++] = XA_WM_TRANSIENT_FOR;
- initial_props[i++] = display->atom__NET_WM_USER_TIME_WINDOW;
- initial_props[i++] = display->atom__NET_WM_FULLSCREEN_MONITORS;
- g_assert (N_INITIAL_PROPS == i);
-
- meta_window_reload_properties (window, initial_props, N_INITIAL_PROPS);
-
- update_sm_hints (window); /* must come after transient_for */
- update_role (window);
- update_net_wm_type (window);
- meta_window_update_icon_now (window);
-
- if (window->initially_iconic)
- {
- /* WM_HINTS said minimized */
- window->minimized = TRUE;
- meta_verbose ("Window %s asked to start out minimized\n", window->desc);
- }
-
- if (existing_wm_state == IconicState)
- {
- /* WM_STATE said minimized */
- window->minimized = TRUE;
- meta_verbose ("Window %s had preexisting WM_STATE = IconicState, minimizing\n",
- window->desc);
-
- /* Assume window was previously placed, though perhaps it's
- * been iconic its whole life, we have no way of knowing.
- */
- window->placed = TRUE;
- }
-
- /* Apply any window attributes such as initial workspace
- * based on startup notification
- */
- meta_screen_apply_startup_properties (window->screen, window);
-
- /* Try to get a "launch timestamp" for the window. If the window is
- * a transient, we'd like to be able to get a last-usage timestamp
- * from the parent window. If the window has no parent, there isn't
- * much we can do...except record the current time so that any children
- * can use this time as a fallback.
- */
- if (!window->net_wm_user_time_set) {
- MetaWindow *parent = NULL;
- if (window->xtransient_for)
- parent = meta_display_lookup_x_window (window->display,
- window->xtransient_for);
-
- /* First, maybe the app was launched with startup notification using an
- * obsolete version of the spec; use that timestamp if it exists.
- */
- if (window->initial_timestamp_set)
- /* NOTE: Do NOT toggle net_wm_user_time_set to true; this is just
- * being recorded as a fallback for potential transients
- */
- window->net_wm_user_time = window->initial_timestamp;
- else if (parent != NULL)
- meta_window_set_user_time(window, parent->net_wm_user_time);
- else
- /* NOTE: Do NOT toggle net_wm_user_time_set to true; this is just
- * being recorded as a fallback for potential transients
- */
- window->net_wm_user_time =
- meta_display_get_current_time_roundtrip (window->display);
- }
-
- if (window->decorated)
- meta_window_ensure_frame (window);
-
- meta_window_grab_keys (window);
- if (window->type != META_WINDOW_DOCK)
- {
- meta_display_grab_window_buttons (window->display, window->xwindow);
- meta_display_grab_focus_window_button (window->display, window);
- }
-
- if (window->type == META_WINDOW_DESKTOP ||
- window->type == META_WINDOW_DOCK)
- {
- /* Change the default, but don't enforce this if the user
- * focuses the dock/desktop and unsticks it using key shortcuts.
- * Need to set this before adding to the workspaces so the MRU
- * lists will be updated.
- */
- window->on_all_workspaces = TRUE;
- }
-
- /* For the workspace, first honor hints,
- * if that fails put transients with parents,
- * otherwise put window on active space
- */
-
- if (window->initial_workspace_set)
- {
- if (window->initial_workspace == (int) 0xFFFFFFFF)
- {
- meta_topic (META_DEBUG_PLACEMENT,
- "Window %s is initially on all spaces\n",
- window->desc);
-
- /* need to set on_all_workspaces first so that it will be
- * added to all the MRU lists
- */
- window->on_all_workspaces = TRUE;
- meta_workspace_add_window (window->screen->active_workspace, window);
- }
- else
- {
- meta_topic (META_DEBUG_PLACEMENT,
- "Window %s is initially on space %d\n",
- window->desc, window->initial_workspace);
-
- space =
- meta_screen_get_workspace_by_index (window->screen,
- window->initial_workspace);
-
- if (space)
- meta_workspace_add_window (space, window);
- }
- }
-
- if (window->workspace == NULL &&
- window->xtransient_for != None)
- {
- /* Try putting dialog on parent's workspace */
- MetaWindow *parent;
-
- parent = meta_display_lookup_x_window (window->display,
- window->xtransient_for);
-
- if (parent && parent->workspace)
- {
- meta_topic (META_DEBUG_PLACEMENT,
- "Putting window %s on same workspace as parent %s\n",
- window->desc, parent->desc);
-
- if (parent->on_all_workspaces)
- window->on_all_workspaces = TRUE;
-
- /* this will implicitly add to the appropriate MRU lists
- */
- meta_workspace_add_window (parent->workspace, window);
- }
- }
-
- if (window->workspace == NULL)
- {
- meta_topic (META_DEBUG_PLACEMENT,
- "Putting window %s on active workspace\n",
- window->desc);
-
- space = window->screen->active_workspace;
-
- meta_workspace_add_window (space, window);
- }
-
- /* for the various on_all_workspaces = TRUE possible above */
- meta_window_set_current_workspace_hint (window);
-
- meta_window_update_struts (window);
-
- /* Must add window to stack before doing move/resize, since the
- * window might have fullscreen size (i.e. should have been
- * fullscreen'd; acrobat is one such braindead case; it withdraws
- * and remaps its window whenever trying to become fullscreen...)
- * and thus constraints may try to auto-fullscreen it which also
- * means restacking it.
- */
- meta_stack_add (window->screen->stack,
- window);
-
- /* Put our state back where it should be,
- * passing TRUE for is_configure_request, ICCCM says
- * initial map is handled same as configure request
- */
- flags =
- META_IS_CONFIGURE_REQUEST | META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
- meta_window_move_resize_internal (window,
- flags,
- window->size_hints.win_gravity,
- window->size_hints.x,
- window->size_hints.y,
- window->size_hints.width,
- window->size_hints.height);
-
- /* Now try applying saved stuff from the session */
- {
- const MetaWindowSessionInfo *info;
-
- info = meta_window_lookup_saved_state (window);
-
- if (info)
- {
- meta_window_apply_session_info (window, info);
- meta_window_release_saved_state (info);
- }
- }
-
- /* FIXME we have a tendency to set this then immediately
- * change it again.
- */
- set_wm_state (window, window->iconic ? IconicState : NormalState);
- set_net_wm_state (window);
-
- /* Sync stack changes */
- meta_stack_thaw (window->screen->stack);
-
- /* disable show desktop mode unless we're a desktop component */
- maybe_leave_show_desktop_mode (window);
-
- meta_window_queue (window, META_QUEUE_CALC_SHOWING);
- /* See bug 303284; a transient of the given window can already exist, in which
- * case we think it should probably be shown.
- */
- meta_window_foreach_transient (window,
- queue_calc_showing_func,
- NULL);
- /* See bug 334899; the window may have minimized ancestors
- * which need to be shown.
- *
- * However, we shouldn't unminimize windows here when opening
- * a new display because that breaks passing _NET_WM_STATE_HIDDEN
- * between window managers when replacing them; see bug 358042.
- *
- * And we shouldn't unminimize windows if they were initially
- * iconic.
- */
- if (!display->display_opening && !window->initially_iconic)
- unminimize_window_and_all_transient_parents (window);
-
- meta_error_trap_pop (display, FALSE); /* pop the XSync()-reducing trap */
- meta_display_ungrab (display);
-
- window->constructing = FALSE;
-
- return window;
-}
-
-/* This function should only be called from the end of meta_window_new_with_attrs () */
-static void
-meta_window_apply_session_info (MetaWindow *window,
- const MetaWindowSessionInfo *info)
-{
- if (info->stack_position_set)
- {
- meta_topic (META_DEBUG_SM,
- "Restoring stack position %d for window %s\n",
- info->stack_position, window->desc);
-
- /* FIXME well, I'm not sure how to do this. */
- }
-
- if (info->minimized_set)
- {
- meta_topic (META_DEBUG_SM,
- "Restoring minimized state %d for window %s\n",
- info->minimized, window->desc);
-
- if (window->has_minimize_func && info->minimized)
- meta_window_minimize (window);
- }
-
- if (info->maximized_set)
- {
- meta_topic (META_DEBUG_SM,
- "Restoring maximized state %d for window %s\n",
- info->maximized, window->desc);
-
- if (window->has_maximize_func && info->maximized)
- {
- meta_window_maximize (window,
- META_MAXIMIZE_HORIZONTAL |
- META_MAXIMIZE_VERTICAL);
-
- if (info->saved_rect_set)
- {
- meta_topic (META_DEBUG_SM,
- "Restoring saved rect %d,%d %dx%d for window %s\n",
- info->saved_rect.x,
- info->saved_rect.y,
- info->saved_rect.width,
- info->saved_rect.height,
- window->desc);
-
- window->saved_rect.x = info->saved_rect.x;
- window->saved_rect.y = info->saved_rect.y;
- window->saved_rect.width = info->saved_rect.width;
- window->saved_rect.height = info->saved_rect.height;
- }
- }
- }
-
- if (info->on_all_workspaces_set)
- {
- window->on_all_workspaces = info->on_all_workspaces;
- meta_topic (META_DEBUG_SM,
- "Restoring sticky state %d for window %s\n",
- window->on_all_workspaces, window->desc);
- }
-
- if (info->workspace_indices)
- {
- GSList *tmp;
- GSList *spaces;
-
- spaces = NULL;
-
- tmp = info->workspace_indices;
- while (tmp != NULL)
- {
- MetaWorkspace *space;
-
- space =
- meta_screen_get_workspace_by_index (window->screen,
- GPOINTER_TO_INT (tmp->data));
-
- if (space)
- spaces = g_slist_prepend (spaces, space);
-
- tmp = tmp->next;
- }
-
- if (spaces)
- {
- /* This briefly breaks the invariant that we are supposed
- * to always be on some workspace. But we paranoically
- * ensured that one of the workspaces from the session was
- * indeed valid, so we know we'll go right back to one.
- */
- if (window->workspace)
- meta_workspace_remove_window (window->workspace, window);
-
- /* Only restore to the first workspace if the window
- * happened to be on more than one, since we have replaces
- * window->workspaces with window->workspace
- */
- meta_workspace_add_window (spaces->data, window);
-
- meta_topic (META_DEBUG_SM,
- "Restoring saved window %s to workspace %d\n",
- window->desc,
- meta_workspace_index (spaces->data));
-
- g_slist_free (spaces);
- }
- }
-
- if (info->geometry_set)
- {
- int x, y, w, h;
- MetaMoveResizeFlags flags;
-
- window->placed = TRUE; /* don't do placement algorithms later */
-
- x = info->rect.x;
- y = info->rect.y;
-
- w = window->size_hints.base_width +
- info->rect.width * window->size_hints.width_inc;
- h = window->size_hints.base_height +
- info->rect.height * window->size_hints.height_inc;
-
- /* Force old gravity, ignoring anything now set */
- window->size_hints.win_gravity = info->gravity;
-
- meta_topic (META_DEBUG_SM,
- "Restoring pos %d,%d size %d x %d for %s\n",
- x, y, w, h, window->desc);
-
- flags = META_DO_GRAVITY_ADJUST | META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
- meta_window_move_resize_internal (window,
- flags,
- window->size_hints.win_gravity,
- x, y, w, h);
- }
-}
-
-void
-meta_window_free (MetaWindow *window,
- guint32 timestamp)
-{
- GList *tmp;
-
- meta_verbose ("Unmanaging 0x%lx\n", window->xwindow);
-
- if (window->display->compositor)
- meta_compositor_free_window (window->display->compositor, window);
-
- if (window->display->window_with_menu == window)
- {
- meta_ui_window_menu_free (window->display->window_menu);
- window->display->window_menu = NULL;
- window->display->window_with_menu = NULL;
- }
-
- if (destroying_windows_disallowed > 0)
- meta_bug ("Tried to destroy window %s while destruction was not allowed\n",
- window->desc);
-
- window->unmanaging = TRUE;
-
- if (window->fullscreen)
- {
- MetaGroup *group;
-
- /* If the window is fullscreen, it may be forcing
- * other windows in its group to a higher layer
- */
-
- meta_stack_freeze (window->screen->stack);
- group = meta_window_get_group (window);
- if (group)
- meta_group_update_layers (group);
- meta_stack_thaw (window->screen->stack);
- }
-
- meta_window_shutdown_group (window); /* safe to do this early as
- * group.c won't re-add to the
- * group if window->unmanaging
- */
-
- /* If we have the focus, focus some other window.
- * This is done first, so that if the unmap causes
- * an EnterNotify the EnterNotify will have final say
- * on what gets focused, maintaining sloppy focus
- * invariants.
- */
- if (window->has_focus)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Focusing default window since we're unmanaging %s\n",
- window->desc);
- meta_workspace_focus_default_window (window->screen->active_workspace,
- window,
- timestamp);
- }
- else if (window->display->expected_focus_window == window)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Focusing default window since expected focus window freed %s\n",
- window->desc);
- window->display->expected_focus_window = NULL;
- meta_workspace_focus_default_window (window->screen->active_workspace,
- window,
- timestamp);
- }
- else
- {
- meta_topic (META_DEBUG_FOCUS,
- "Unmanaging window %s which doesn't currently have focus\n",
- window->desc);
- }
-
- if (window->struts)
- {
- meta_free_gslist_and_elements (window->struts);
- window->struts = NULL;
-
- meta_topic (META_DEBUG_WORKAREA,
- "Unmanaging window %s which has struts, so invalidating work areas\n",
- window->desc);
- invalidate_work_areas (window);
- }
-
- if (window->display->grab_window == window)
- meta_display_end_grab_op (window->display, timestamp);
-
- g_assert (window->display->grab_window != window);
-
- if (window->display->focus_window == window)
- {
- window->display->focus_window = NULL;
- meta_compositor_set_active_window (window->display->compositor,
- window->screen, NULL);
- }
-
- if (window->maximized_horizontally || window->maximized_vertically)
- unmaximize_window_before_freeing (window);
-
- /* The XReparentWindow call in meta_window_destroy_frame() moves the
- * window so we need to send a configure notify; see bug 399552. (We
- * also do this just in case a window got unmaximized.)
- */
- send_configure_notify (window);
-
- meta_window_unqueue (window, META_QUEUE_CALC_SHOWING |
- META_QUEUE_MOVE_RESIZE |
- META_QUEUE_UPDATE_ICON);
- meta_window_free_delete_dialog (window);
-
- if (window->workspace)
- meta_workspace_remove_window (window->workspace, window);
-
- g_assert (window->workspace == NULL);
-
-#ifndef G_DISABLE_CHECKS
- tmp = window->screen->workspaces;
- while (tmp != NULL)
- {
- MetaWorkspace *workspace = tmp->data;
-
- g_assert (g_list_find (workspace->windows, window) == NULL);
- g_assert (g_list_find (workspace->mru_list, window) == NULL);
-
- tmp = tmp->next;
- }
-#endif
-
- meta_stack_remove (window->screen->stack, window);
-
- if (window->frame)
- meta_window_destroy_frame (window);
-
- if (window->withdrawn)
- {
- /* We need to clean off the window's state so it
- * won't be restored if the app maps it again.
- */
- meta_error_trap_push (window->display);
- meta_verbose ("Cleaning state from window %s\n", window->desc);
- XDeleteProperty (window->display->xdisplay,
- window->xwindow,
- window->display->atom__NET_WM_DESKTOP);
- XDeleteProperty (window->display->xdisplay,
- window->xwindow,
- window->display->atom__NET_WM_STATE);
- XDeleteProperty (window->display->xdisplay,
- window->xwindow,
- window->display->atom__NET_WM_FULLSCREEN_MONITORS);
- set_wm_state (window, WithdrawnState);
- meta_error_trap_pop (window->display, FALSE);
- }
- else
- {
- /* We need to put WM_STATE so that others will understand it on
- * restart.
- */
- if (!window->minimized)
- {
- meta_error_trap_push (window->display);
- set_wm_state (window, NormalState);
- meta_error_trap_pop (window->display, FALSE);
- }
-
- /* And we need to be sure the window is mapped so other WMs
- * know that it isn't Withdrawn
- */
- meta_error_trap_push (window->display);
- XMapWindow (window->display->xdisplay,
- window->xwindow);
- meta_error_trap_pop (window->display, FALSE);
- }
-
- meta_window_ungrab_keys (window);
- meta_display_ungrab_window_buttons (window->display, window->xwindow);
- meta_display_ungrab_focus_window_button (window->display, window);
-
- meta_display_unregister_x_window (window->display, window->xwindow);
-
-
- meta_error_trap_push (window->display);
-
- /* Put back anything we messed up */
- if (window->border_width != 0)
- XSetWindowBorderWidth (window->display->xdisplay,
- window->xwindow,
- window->border_width);
-
- /* No save set */
- XRemoveFromSaveSet (window->display->xdisplay,
- window->xwindow);
-
- /* Don't get events on not-managed windows */
- XSelectInput (window->display->xdisplay,
- window->xwindow,
- NoEventMask);
-
- /* Stop getting events for the window's _NET_WM_USER_TIME_WINDOW too */
- if (window->user_time_window != None)
- {
- meta_display_unregister_x_window (window->display,
- window->user_time_window);
- XSelectInput (window->display->xdisplay,
- window->user_time_window,
- NoEventMask);
- window->user_time_window = None;
- }
-
-#ifdef HAVE_SHAPE
- if (META_DISPLAY_HAS_SHAPE (window->display))
- XShapeSelectInput (window->display->xdisplay, window->xwindow, NoEventMask);
-#endif
-
- meta_error_trap_pop (window->display, FALSE);
-
- if (window->icon)
- g_object_unref (G_OBJECT (window->icon));
-
- if (window->mini_icon)
- g_object_unref (G_OBJECT (window->mini_icon));
-
- meta_icon_cache_free (&window->icon_cache);
-
- g_free (window->sm_client_id);
- g_free (window->wm_client_machine);
- g_free (window->startup_id);
- g_free (window->role);
- g_free (window->res_class);
- g_free (window->res_name);
- g_free (window->title);
- g_free (window->icon_name);
- g_free (window->desc);
- g_free (window);
-}
-
-static void
-set_wm_state (MetaWindow *window,
- int state)
-{
- unsigned long data[2];
-
- meta_verbose ("Setting wm state %s on %s\n",
- wm_state_to_string (state), window->desc);
-
- /* Metacity doesn't use icon windows, so data[1] should be None
- * according to the ICCCM 2.0 Section 4.1.3.1.
- */
- data[0] = state;
- data[1] = None;
-
- meta_error_trap_push (window->display);
- XChangeProperty (window->display->xdisplay, window->xwindow,
- window->display->atom_WM_STATE,
- window->display->atom_WM_STATE,
- 32, PropModeReplace, (guchar*) data, 2);
- meta_error_trap_pop (window->display, FALSE);
-}
-
-static void
-set_net_wm_state (MetaWindow *window)
-{
- int i;
- unsigned long data[12];
-
- i = 0;
- if (window->shaded)
- {
- data[i] = window->display->atom__NET_WM_STATE_SHADED;
- ++i;
- }
- if (window->wm_state_modal)
- {
- data[i] = window->display->atom__NET_WM_STATE_MODAL;
- ++i;
- }
- if (window->skip_pager)
- {
- data[i] = window->display->atom__NET_WM_STATE_SKIP_PAGER;
- ++i;
- }
- if (window->skip_taskbar)
- {
- data[i] = window->display->atom__NET_WM_STATE_SKIP_TASKBAR;
- ++i;
- }
- if (window->maximized_horizontally)
- {
- data[i] = window->display->atom__NET_WM_STATE_MAXIMIZED_HORZ;
- ++i;
- }
- if (window->maximized_vertically)
- {
- data[i] = window->display->atom__NET_WM_STATE_MAXIMIZED_VERT;
- ++i;
- }
- if (window->fullscreen)
- {
- data[i] = window->display->atom__NET_WM_STATE_FULLSCREEN;
- ++i;
- }
- if (!meta_window_showing_on_its_workspace (window) || window->shaded)
- {
- data[i] = window->display->atom__NET_WM_STATE_HIDDEN;
- ++i;
- }
- if (window->wm_state_above)
- {
- data[i] = window->display->atom__NET_WM_STATE_ABOVE;
- ++i;
- }
- if (window->wm_state_below)
- {
- data[i] = window->display->atom__NET_WM_STATE_BELOW;
- ++i;
- }
- if (window->wm_state_demands_attention)
- {
- data[i] = window->display->atom__NET_WM_STATE_DEMANDS_ATTENTION;
- ++i;
- }
- if (window->on_all_workspaces)
- {
- data[i] = window->display->atom__NET_WM_STATE_STICKY;
- ++i;
- }
-
- meta_verbose ("Setting _NET_WM_STATE with %d atoms\n", i);
-
- meta_error_trap_push (window->display);
- XChangeProperty (window->display->xdisplay, window->xwindow,
- window->display->atom__NET_WM_STATE,
- XA_ATOM,
- 32, PropModeReplace, (guchar*) data, i);
- meta_error_trap_pop (window->display, FALSE);
-
- if (window->fullscreen)
- {
- data[0] = window->fullscreen_monitors[0];
- data[1] = window->fullscreen_monitors[1];
- data[2] = window->fullscreen_monitors[2];
- data[3] = window->fullscreen_monitors[3];
-
- meta_verbose ("Setting _NET_WM_FULLSCREEN_MONITORS\n");
- meta_error_trap_push (window->display);
- XChangeProperty (window->display->xdisplay,
- window->xwindow,
- window->display->atom__NET_WM_FULLSCREEN_MONITORS,
- XA_CARDINAL, 32, PropModeReplace,
- (guchar*) data, 4);
- meta_error_trap_pop (window->display, FALSE);
- }
-}
-
-gboolean
-meta_window_located_on_workspace (MetaWindow *window,
- MetaWorkspace *workspace)
-{
- return (window->on_all_workspaces && window->screen == workspace->screen) ||
- (window->workspace == workspace);
-}
-
-static gboolean
-is_minimized_foreach (MetaWindow *window,
- void *data)
-{
- gboolean *result = data;
-
- *result = window->minimized;
- if (*result)
- return FALSE; /* stop as soon as we find one */
- else
- return TRUE;
-}
-
-static gboolean
-ancestor_is_minimized (MetaWindow *window)
-{
- gboolean is_minimized;
-
- is_minimized = FALSE;
-
- meta_window_foreach_ancestor (window, is_minimized_foreach, &is_minimized);
-
- return is_minimized;
-}
-
-gboolean
-meta_window_showing_on_its_workspace (MetaWindow *window)
-{
- gboolean showing;
- gboolean is_desktop_or_dock;
- MetaWorkspace* workspace_of_window;
-
- showing = TRUE;
-
- /* 1. See if we're minimized */
- if (window->minimized)
- showing = FALSE;
-
- /* 2. See if we're in "show desktop" mode */
- is_desktop_or_dock = FALSE;
- is_desktop_or_dock_foreach (window,
- &is_desktop_or_dock);
-
- meta_window_foreach_ancestor (window, is_desktop_or_dock_foreach,
- &is_desktop_or_dock);
-
- if (window->on_all_workspaces)
- workspace_of_window = window->screen->active_workspace;
- else if (window->workspace)
- workspace_of_window = window->workspace;
- else /* This only seems to be needed for startup */
- workspace_of_window = NULL;
-
- if (showing &&
- workspace_of_window && workspace_of_window->showing_desktop &&
- !is_desktop_or_dock)
- {
- meta_verbose ("We're showing the desktop on the workspace(s) that window %s is on\n",
- window->desc);
- showing = FALSE;
- }
-
- /* 3. See if an ancestor is minimized (note that
- * ancestor's "mapped" field may not be up to date
- * since it's being computed in this same idle queue)
- */
-
- if (showing)
- {
- if (ancestor_is_minimized (window))
- showing = FALSE;
- }
-
-#if 0
- /* 4. See if we're drawing wireframe
- */
- if (window->display->grab_window == window &&
- window->display->grab_wireframe_active)
- showing = FALSE;
-#endif
-
- return showing;
-}
-
-gboolean
-meta_window_should_be_showing (MetaWindow *window)
-{
- gboolean on_workspace;
-
- meta_verbose ("Should be showing for window %s\n", window->desc);
-
- /* See if we're on the workspace */
- on_workspace = meta_window_located_on_workspace (window,
- window->screen->active_workspace);
-
- if (!on_workspace)
- meta_verbose ("Window %s is not on workspace %d\n",
- window->desc,
- meta_workspace_index (window->screen->active_workspace));
- else
- meta_verbose ("Window %s is on the active workspace %d\n",
- window->desc,
- meta_workspace_index (window->screen->active_workspace));
-
- if (window->on_all_workspaces)
- meta_verbose ("Window %s is on all workspaces\n", window->desc);
-
- return on_workspace && meta_window_showing_on_its_workspace (window);
-}
-
-static void
-finish_minimize (gpointer data)
-{
- MetaWindow *window = data;
- /* FIXME: It really sucks to put timestamp pinging here; it'd
- * probably make more sense in implement_showing() so that it's at
- * least not duplicated in meta_window_show; but since
- * finish_minimize is a callback making things just slightly icky, I
- * haven't done that yet.
- */
- guint32 timestamp = meta_display_get_current_time_roundtrip (window->display);
-
- meta_window_hide (window);
- if (window->has_focus)
- {
- meta_workspace_focus_default_window (window->screen->active_workspace,
- window,
- timestamp);
- }
-}
-
-static void
-implement_showing (MetaWindow *window,
- gboolean showing)
-{
- /* Actually show/hide the window */
- meta_verbose ("Implement showing = %d for window %s\n",
- showing, window->desc);
-
- if (!showing)
- {
- gboolean on_workspace;
-
- on_workspace = meta_window_located_on_workspace (window,
- window->screen->active_workspace);
-
- /* Really this effects code should probably
- * be in meta_window_hide so the window->mapped
- * test isn't duplicated here. Anyhow, we animate
- * if we are mapped now, we are supposed to
- * be minimized, and we are on the current workspace.
- */
- if (on_workspace && window->minimized && window->mapped &&
- !meta_prefs_get_reduced_resources ())
- {
- MetaRectangle icon_rect, window_rect;
- gboolean result;
-
- /* Check if the window has an icon geometry */
- result = meta_window_get_icon_geometry (window, &icon_rect);
-
- if (!result)
- {
- /* just animate into the corner somehow - maybe
- * not a good idea...
- */
- icon_rect.x = window->screen->rect.width;
- icon_rect.y = window->screen->rect.height;
- icon_rect.width = 1;
- icon_rect.height = 1;
- }
-
- meta_window_get_outer_rect (window, &window_rect);
-
- meta_effect_run_minimize (window,
- &window_rect,
- &icon_rect,
- finish_minimize,
- window);
- }
- else
- {
- finish_minimize (window);
- }
- }
- else
- {
- meta_window_show (window);
- }
-}
-
-void
-meta_window_calc_showing (MetaWindow *window)
-{
- implement_showing (window, meta_window_should_be_showing (window));
-}
-
-static guint queue_idle[NUMBER_OF_QUEUES] = {0, 0, 0};
-static GSList *queue_pending[NUMBER_OF_QUEUES] = {NULL, NULL, NULL};
-
-static int
-stackcmp (gconstpointer a, gconstpointer b)
-{
- MetaWindow *aw = (gpointer) a;
- MetaWindow *bw = (gpointer) b;
-
- if (aw->screen != bw->screen)
- return 0; /* don't care how they sort with respect to each other */
- else
- return meta_stack_windows_cmp (aw->screen->stack,
- aw, bw);
-}
-
-static gboolean
-idle_calc_showing (gpointer data)
-{
- GSList *tmp;
- GSList *copy;
- GSList *should_show;
- GSList *should_hide;
- GSList *unplaced;
- GSList *displays;
- MetaWindow *first_window;
- guint queue_index = GPOINTER_TO_INT (data);
-
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Clearing the calc_showing queue\n");
-
- /* Work with a copy, for reentrancy. The allowed reentrancy isn't
- * complete; destroying a window while we're in here would result in
- * badness. But it's OK to queue/unqueue calc_showings.
- */
- copy = g_slist_copy (queue_pending[queue_index]);
- g_slist_free (queue_pending[queue_index]);
- queue_pending[queue_index] = NULL;
- queue_idle[queue_index] = 0;
-
- destroying_windows_disallowed += 1;
-
- /* We map windows from top to bottom and unmap from bottom to
- * top, to avoid extra expose events. The exception is
- * for unplaced windows, which have to be mapped from bottom to
- * top so placement works.
- */
- should_show = NULL;
- should_hide = NULL;
- unplaced = NULL;
- displays = NULL;
-
- tmp = copy;
- while (tmp != NULL)
- {
- MetaWindow *window;
-
- window = tmp->data;
-
- if (!window->placed)
- unplaced = g_slist_prepend (unplaced, window);
- else if (meta_window_should_be_showing (window))
- should_show = g_slist_prepend (should_show, window);
- else
- should_hide = g_slist_prepend (should_hide, window);
-
- tmp = tmp->next;
- }
-
- /* bottom to top */
- unplaced = g_slist_sort (unplaced, stackcmp);
- should_hide = g_slist_sort (should_hide, stackcmp);
- /* top to bottom */
- should_show = g_slist_sort (should_show, stackcmp);
- should_show = g_slist_reverse (should_show);
-
- first_window = copy->data;
-
- meta_display_grab (first_window->display);
-
- tmp = unplaced;
- while (tmp != NULL)
- {
- MetaWindow *window;
-
- window = tmp->data;
-
- meta_window_calc_showing (window);
-
- tmp = tmp->next;
- }
-
- tmp = should_show;
- while (tmp != NULL)
- {
- MetaWindow *window;
-
- window = tmp->data;
-
- implement_showing (window, TRUE);
-
- tmp = tmp->next;
- }
-
- tmp = should_hide;
- while (tmp != NULL)
- {
- MetaWindow *window;
-
- window = tmp->data;
-
- implement_showing (window, FALSE);
-
- tmp = tmp->next;
- }
-
- tmp = copy;
- while (tmp != NULL)
- {
- MetaWindow *window;
-
- window = tmp->data;
-
- /* important to set this here for reentrancy -
- * if we queue a window again while it's in "copy",
- * then queue_calc_showing will just return since
- * we are still in the calc_showing queue
- */
- window->is_in_queues &= ~META_QUEUE_CALC_SHOWING;
-
- tmp = tmp->next;
- }
-
- if (meta_prefs_get_focus_mode () != META_FOCUS_MODE_CLICK)
- {
- /* When display->mouse_mode is false, we want to ignore
- * EnterNotify events unless they come from mouse motion. To do
- * that, we set a sentinel property on the root window if we're
- * not in mouse_mode.
- */
- tmp = should_show;
- while (tmp != NULL)
- {
- MetaWindow *window = tmp->data;
-
- if (!window->display->mouse_mode)
- meta_display_increment_focus_sentinel (window->display);
-
- tmp = tmp->next;
- }
- }
-
- meta_display_ungrab (first_window->display);
-
- g_slist_free (copy);
-
- g_slist_free (unplaced);
- g_slist_free (should_show);
- g_slist_free (should_hide);
- g_slist_free (displays);
-
- destroying_windows_disallowed -= 1;
-
- return FALSE;
-}
-
-static const gchar* meta_window_queue_names[NUMBER_OF_QUEUES] =
- {"calc_showing", "move_resize", "update_icon"};
-
-static void
-meta_window_unqueue (MetaWindow *window, guint queuebits)
-{
- gint queuenum;
-
- for (queuenum=0; queuenum<NUMBER_OF_QUEUES; queuenum++)
- {
- if ((queuebits & 1<<queuenum) /* they have asked to unqueue */
- &&
- (window->is_in_queues & 1<<queuenum)) /* it's in the queue */
- {
-
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Removing %s from the %s queue\n",
- window->desc,
- meta_window_queue_names[queuenum]);
-
- /* Note that window may not actually be in the queue
- * because it may have been in "copy" inside the idle handler
- */
- queue_pending[queuenum] = g_slist_remove (queue_pending[queuenum], window);
- window->is_in_queues &= ~(1<<queuenum);
-
- /* Okay, so maybe we've used up all the entries in the queue.
- * In that case, we should kill the function that deals with
- * the queue, because there's nothing left for it to do.
- */
- if (queue_pending[queuenum] == NULL && queue_idle[queuenum] != 0)
- {
- g_source_remove (queue_idle[queuenum]);
- queue_idle[queuenum] = 0;
- }
- }
- }
-}
-
-static void
-meta_window_flush_calc_showing (MetaWindow *window)
-{
- if (window->is_in_queues & META_QUEUE_CALC_SHOWING)
- {
- meta_window_unqueue (window, META_QUEUE_CALC_SHOWING);
- meta_window_calc_showing (window);
- }
-}
-
-void
-meta_window_queue (MetaWindow *window, guint queuebits)
-{
- guint queuenum;
-
- for (queuenum=0; queuenum<NUMBER_OF_QUEUES; queuenum++)
- {
- if (queuebits & 1<<queuenum)
- {
- /* Data which varies between queues.
- * Yes, these do look a lot like associative arrays:
- * I seem to be turning into a Perl programmer.
- */
-
- const gint window_queue_idle_priority[NUMBER_OF_QUEUES] =
- {
- G_PRIORITY_DEFAULT_IDLE, /* CALC_SHOWING */
- META_PRIORITY_RESIZE, /* MOVE_RESIZE */
- G_PRIORITY_DEFAULT_IDLE /* UPDATE_ICON */
- };
-
- const GSourceFunc window_queue_idle_handler[NUMBER_OF_QUEUES] =
- {
- idle_calc_showing,
- idle_move_resize,
- idle_update_icon,
- };
-
- /* If we're about to drop the window, there's no point in putting
- * it on a queue.
- */
- if (window->unmanaging)
- break;
-
- /* If the window already claims to be in that queue, there's no
- * point putting it in the queue.
- */
- if (window->is_in_queues & 1<<queuenum)
- break;
-
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Putting %s in the %s queue\n",
- window->desc,
- meta_window_queue_names[queuenum]);
-
- /* So, mark it as being in this queue. */
- window->is_in_queues |= 1<<queuenum;
-
- /* There's not a lot of point putting things into a queue if
- * nobody's on the other end pulling them out. Therefore,
- * let's check to see whether an idle handler exists to do
- * that. If not, we'll create one.
- */
-
- if (queue_idle[queuenum] == 0)
- queue_idle[queuenum] = g_idle_add_full
- (
- window_queue_idle_priority[queuenum],
- window_queue_idle_handler[queuenum],
- GUINT_TO_POINTER(queuenum),
- NULL
- );
-
- /* And now we actually put it on the queue. */
- queue_pending[queuenum] = g_slist_prepend (queue_pending[queuenum],
- window);
- }
- }
-}
-
-static gboolean
-intervening_user_event_occurred (MetaWindow *window)
-{
- guint32 compare;
- MetaWindow *focus_window;
-
- focus_window = window->display->focus_window;
-
- meta_topic (META_DEBUG_STARTUP,
- "COMPARISON:\n"
- " net_wm_user_time_set : %d\n"
- " net_wm_user_time : %u\n"
- " initial_timestamp_set: %d\n"
- " initial_timestamp : %u\n",
- window->net_wm_user_time_set,
- window->net_wm_user_time,
- window->initial_timestamp_set,
- window->initial_timestamp);
- if (focus_window != NULL)
- {
- meta_topic (META_DEBUG_STARTUP,
- "COMPARISON (continued):\n"
- " focus_window : %s\n"
- " fw->net_wm_user_time_set : %d\n"
- " fw->net_wm_user_time : %u\n",
- focus_window->desc,
- focus_window->net_wm_user_time_set,
- focus_window->net_wm_user_time);
- }
-
- /* We expect the most common case for not focusing a new window
- * to be when a hint to not focus it has been set. Since we can
- * deal with that case rapidly, we use special case it--this is
- * merely a preliminary optimization. :)
- */
- if ( ((window->net_wm_user_time_set == TRUE) &&
- (window->net_wm_user_time == 0))
- ||
- ((window->initial_timestamp_set == TRUE) &&
- (window->initial_timestamp == 0)))
- {
- meta_topic (META_DEBUG_STARTUP,
- "window %s explicitly requested no focus\n",
- window->desc);
- return TRUE;
- }
-
- if (!(window->net_wm_user_time_set) && !(window->initial_timestamp_set))
- {
- meta_topic (META_DEBUG_STARTUP,
- "no information about window %s found\n",
- window->desc);
- return FALSE;
- }
-
- if (focus_window != NULL &&
- !focus_window->net_wm_user_time_set)
- {
- meta_topic (META_DEBUG_STARTUP,
- "focus window, %s, doesn't have a user time set yet!\n",
- window->desc);
- return FALSE;
- }
-
- /* To determine the "launch" time of an application,
- * startup-notification can set the TIMESTAMP and the
- * application (usually via its toolkit such as gtk or qt) can
- * set the _NET_WM_USER_TIME. If both are set, then it means
- * the user has interacted with the application since it
- * launched, and _NET_WM_USER_TIME is the value that should be
- * used in the comparison.
- */
- compare = window->initial_timestamp_set ? window->initial_timestamp : 0;
- compare = window->net_wm_user_time_set ? window->net_wm_user_time : compare;
-
- if ((focus_window != NULL) &&
- XSERVER_TIME_IS_BEFORE (compare, focus_window->net_wm_user_time))
- {
- meta_topic (META_DEBUG_STARTUP,
- "window %s focus prevented by other activity; %u < %u\n",
- window->desc,
- compare,
- focus_window->net_wm_user_time);
- return TRUE;
- }
- else
- {
- meta_topic (META_DEBUG_STARTUP,
- "new window %s with no intervening events\n",
- window->desc);
- return FALSE;
- }
-}
-
-/* This function is an ugly hack. It's experimental in nature and ought to be
- * replaced by a real hint from the app to the WM if we decide the experimental
- * behavior is worthwhile. The basic idea is to get more feedback about how
- * usage scenarios of "strict" focus users and what they expect. See #326159.
- */
-gboolean
-__window_is_terminal (MetaWindow *window)
-{
- if (window == NULL || window->res_class == NULL)
- return FALSE;
-
- /*
- * Compare res_class, which is not user-settable, and thus theoretically
- * a more-reliable indication of term-ness.
- */
-
- /* gnome-terminal -- if you couldn't guess */
- if (strcmp (window->res_class, "Gnome-terminal") == 0)
- return TRUE;
- /* xterm, rxvt, aterm */
- else if (strcmp (window->res_class, "XTerm") == 0)
- return TRUE;
- /* konsole, KDE's terminal program */
- else if (strcmp (window->res_class, "Konsole") == 0)
- return TRUE;
- /* rxvt-unicode */
- else if (strcmp (window->res_class, "URxvt") == 0)
- return TRUE;
- /* eterm */
- else if (strcmp (window->res_class, "Eterm") == 0)
- return TRUE;
- /* KTerm -- some terminal not KDE based; so not like Konsole */
- else if (strcmp (window->res_class, "KTerm") == 0)
- return TRUE;
- /* Multi-gnome-terminal */
- else if (strcmp (window->res_class, "Multi-gnome-terminal") == 0)
- return TRUE;
- /* mlterm ("multi lingual terminal emulator on X") */
- else if (strcmp (window->res_class, "mlterm") == 0)
- return TRUE;
-
- return FALSE;
-}
-
-/* This function determines what state the window should have assuming that it
- * and the focus_window have no relation
- */
-static void
-window_state_on_map (MetaWindow *window,
- gboolean *takes_focus,
- gboolean *places_on_top)
-{
- gboolean intervening_events;
-
- intervening_events = intervening_user_event_occurred (window);
-
- *takes_focus = !intervening_events;
- *places_on_top = *takes_focus;
-
- /* don't initially focus windows that are intended to not accept
- * focus
- */
- if (!(window->input || window->take_focus))
- {
- *takes_focus = FALSE;
- return;
- }
-
- /* Terminal usage may be different; some users intend to launch
- * many apps in quick succession or to just view things in the new
- * window while still interacting with the terminal. In that case,
- * apps launched from the terminal should not take focus. This
- * isn't quite the same as not allowing focus to transfer from
- * terminals due to new window map, but the latter is a much easier
- * approximation to enforce so we do that.
- */
- if (*takes_focus &&
- meta_prefs_get_focus_new_windows () == META_FOCUS_NEW_WINDOWS_STRICT &&
- !window->display->allow_terminal_deactivation &&
- __window_is_terminal (window->display->focus_window) &&
- !meta_window_is_ancestor_of_transient (window->display->focus_window,
- window))
- {
- meta_topic (META_DEBUG_FOCUS,
- "focus_window is terminal; not focusing new window.\n");
- *takes_focus = FALSE;
- *places_on_top = FALSE;
- }
-
- switch (window->type)
- {
- case META_WINDOW_UTILITY:
- case META_WINDOW_TOOLBAR:
- *takes_focus = FALSE;
- *places_on_top = FALSE;
- break;
- case META_WINDOW_DOCK:
- case META_WINDOW_DESKTOP:
- case META_WINDOW_SPLASHSCREEN:
- case META_WINDOW_MENU:
- /* don't focus any of these; places_on_top may be irrelevant for some of
- * these (e.g. dock)--but you never know--the focus window might also be
- * of the same type in some weird situation...
- */
- *takes_focus = FALSE;
- break;
- case META_WINDOW_NORMAL:
- case META_WINDOW_DIALOG:
- case META_WINDOW_MODAL_DIALOG:
- /* The default is correct for these */
- break;
- }
-}
-
-static gboolean
-windows_overlap (const MetaWindow *w1, const MetaWindow *w2)
-{
- MetaRectangle w1rect, w2rect;
- meta_window_get_outer_rect (w1, &w1rect);
- meta_window_get_outer_rect (w2, &w2rect);
- return meta_rectangle_overlap (&w1rect, &w2rect);
-}
-
-/* Returns whether a new window would be covered by any
- * existing window on the same workspace that is set
- * to be "above" ("always on top"). A window that is not
- * set "above" would be underneath the new window anyway.
- *
- * We take "covered" to mean even partially covered, but
- * some people might prefer entirely covered. I think it
- * is more useful to behave this way if any part of the
- * window is covered, because a partial coverage could be
- * (say) ninety per cent and almost indistinguishable from total.
- */
-static gboolean
-window_would_be_covered (const MetaWindow *newbie)
-{
- MetaWorkspace *workspace = newbie->workspace;
- GList *tmp, *windows;
-
- windows = meta_workspace_list_windows (workspace);
-
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
-
- if (w->wm_state_above && w != newbie)
- {
- /* We have found a window that is "above". Perhaps it overlaps. */
- if (windows_overlap (w, newbie))
- {
- g_list_free (windows); /* clean up... */
- return TRUE; /* yes, it does */
- }
- }
-
- tmp = tmp->next;
- }
-
- g_list_free (windows);
- return FALSE; /* none found */
-}
-
-/* XXX META_EFFECT_*_MAP */
-void
-meta_window_show (MetaWindow *window)
-{
- gboolean did_show;
- gboolean takes_focus_on_map;
- gboolean place_on_top_on_map;
- gboolean needs_stacking_adjustment;
- MetaWindow *focus_window;
- guint32 timestamp;
-
- /* FIXME: It really sucks to put timestamp pinging here; it'd
- * probably make more sense in implement_showing() so that it's at
- * least not duplicated in finish_minimize. *shrug*
- */
- timestamp = meta_display_get_current_time_roundtrip (window->display);
-
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Showing window %s, shaded: %d iconic: %d placed: %d\n",
- window->desc, window->shaded, window->iconic, window->placed);
-
- focus_window = window->display->focus_window; /* May be NULL! */
- did_show = FALSE;
- window_state_on_map (window, &takes_focus_on_map, &place_on_top_on_map);
- needs_stacking_adjustment = FALSE;
-
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Window %s %s focus on map, and %s place on top on map.\n",
- window->desc,
- takes_focus_on_map ? "does" : "does not",
- place_on_top_on_map ? "does" : "does not");
-
- /* Now, in some rare cases we should *not* put a new window on top.
- * These cases include certain types of windows showing for the first
- * time, and any window which would be covered because of another window
- * being set "above" ("always on top").
- *
- * FIXME: Although "place_on_top_on_map" and "takes_focus_on_map" are
- * generally based on the window type, there is a special case when the
- * focus window is a terminal for them both to be false; this should
- * probably rather be a term in the "if" condition below.
- */
-
- if ( focus_window != NULL && window->showing_for_first_time &&
- ( (!place_on_top_on_map && !takes_focus_on_map) ||
- window_would_be_covered (window) )
- ) {
- if (meta_window_is_ancestor_of_transient (focus_window, window))
- {
- /* This happens for error dialogs or alerts; these need to remain on
- * top, but it would be confusing to have its ancestor remain
- * focused.
- */
- meta_topic (META_DEBUG_STARTUP,
- "The focus window %s is an ancestor of the newly mapped "
- "window %s which isn't being focused. Unfocusing the "
- "ancestor.\n",
- focus_window->desc, window->desc);
-
- meta_display_focus_the_no_focus_window (window->display,
- window->screen,
- timestamp);
- }
- else
- {
- needs_stacking_adjustment = TRUE;
- if (!window->placed)
- window->denied_focus_and_not_transient = TRUE;
- }
- }
-
- if (!window->placed)
- {
- /* We have to recalc the placement here since other windows may
- * have been mapped/placed since we last did constrain_position
- */
-
- /* calc_placement is an efficiency hack to avoid
- * multiple placement calculations before we finally
- * show the window.
- */
- window->calc_placement = TRUE;
- meta_window_move_resize_now (window);
- window->calc_placement = FALSE;
-
- /* don't ever do the initial position constraint thing again.
- * This is toggled here so that initially-iconified windows
- * still get placed when they are ultimately shown.
- */
- window->placed = TRUE;
-
- /* Don't want to accidentally reuse the fact that we had been denied
- * focus in any future constraints unless we're denied focus again.
- */
- window->denied_focus_and_not_transient = FALSE;
- }
-
- if (needs_stacking_adjustment)
- {
- gboolean overlap;
-
- /* This window isn't getting focus on map. We may need to do some
- * special handing with it in regards to
- * - the stacking of the window
- * - the MRU position of the window
- * - the demands attention setting of the window
- *
- * Firstly, set the flag so we don't give the window focus anyway
- * and confuse people.
- */
-
- takes_focus_on_map = FALSE;
-
- overlap = windows_overlap (window, focus_window);
-
- /* We want alt tab to go to the denied-focus window */
- ensure_mru_position_after (window, focus_window);
-
- /* We don't want the denied-focus window to obscure the focus
- * window, and if we're in both click-to-focus mode and
- * raise-on-click mode then we want to maintain the invariant
- * that MRU order == stacking order. The need for this if
- * comes from the fact that in sloppy/mouse focus the focus
- * window may not overlap other windows and also can be
- * considered "below" them; this combination means that
- * placing the denied-focus window "below" the focus window
- * in the stack when it doesn't overlap it confusingly places
- * that new window below a lot of other windows.
- */
- if (overlap ||
- (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK &&
- meta_prefs_get_raise_on_click ()))
- meta_window_stack_just_below (window, focus_window);
-
- /* If the window will be obscured by the focus window, then the
- * user might not notice the window appearing so set the
- * demands attention hint.
- *
- * We set the hint ourselves rather than calling
- * meta_window_set_demands_attention() because that would cause
- * a recalculation of overlap, and a call to set_net_wm_state()
- * which we are going to call ourselves here a few lines down.
- */
- if (overlap)
- window->wm_state_demands_attention = TRUE;
- }
-
- /* Shaded means the frame is mapped but the window is not */
-
- if (window->frame && !window->frame->mapped)
- {
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Frame actually needs map\n");
- window->frame->mapped = TRUE;
- meta_ui_map_frame (window->screen->ui, window->frame->xwindow);
- did_show = TRUE;
- }
-
- if (window->shaded)
- {
- if (window->mapped)
- {
- meta_topic (META_DEBUG_WINDOW_STATE,
- "%s actually needs unmap (shaded)\n", window->desc);
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Incrementing unmaps_pending on %s for shade\n",
- window->desc);
- window->mapped = FALSE;
- window->unmaps_pending += 1;
- meta_error_trap_push (window->display);
- XUnmapWindow (window->display->xdisplay, window->xwindow);
- meta_error_trap_pop (window->display, FALSE);
- }
-
- if (!window->iconic)
- {
- window->iconic = TRUE;
- set_wm_state (window, IconicState);
- }
- }
- else
- {
- if (!window->mapped)
- {
- meta_topic (META_DEBUG_WINDOW_STATE,
- "%s actually needs map\n", window->desc);
- window->mapped = TRUE;
- meta_error_trap_push (window->display);
- XMapWindow (window->display->xdisplay, window->xwindow);
- meta_error_trap_pop (window->display, FALSE);
- did_show = TRUE;
-
- if (window->was_minimized)
- {
- MetaRectangle window_rect;
- MetaRectangle icon_rect;
-
- window->was_minimized = FALSE;
-
- if (meta_window_get_icon_geometry (window, &icon_rect))
- {
- meta_window_get_outer_rect (window, &window_rect);
-
- meta_effect_run_unminimize (window,
- &window_rect,
- &icon_rect,
- NULL, NULL);
- }
- }
- }
-
- if (window->iconic)
- {
- window->iconic = FALSE;
- set_wm_state (window, NormalState);
- }
- }
-
- /* We don't want to worry about all cases from inside
- * implement_showing(); we only want to worry about focus if this
- * window has not been shown before.
- */
- if (window->showing_for_first_time)
- {
- window->showing_for_first_time = FALSE;
- if (takes_focus_on_map)
- {
- meta_window_focus (window, timestamp);
- }
- else
- {
- /* Prevent EnterNotify events in sloppy/mouse focus from
- * erroneously focusing the window that had been denied
- * focus. FIXME: This introduces a race; I have a couple
- * ideas for a better way to accomplish the same thing, but
- * they're more involved so do it this way for now.
- */
- meta_display_increment_focus_sentinel (window->display);
- }
- }
-
- set_net_wm_state (window);
-
- if (did_show && window->struts)
- {
- meta_topic (META_DEBUG_WORKAREA,
- "Mapped window %s with struts, so invalidating work areas\n",
- window->desc);
- invalidate_work_areas (window);
- }
-}
-
-/* XXX META_EFFECT_*_UNMAP */
-static void
-meta_window_hide (MetaWindow *window)
-{
- gboolean did_hide;
-
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Hiding window %s\n", window->desc);
-
- did_hide = FALSE;
-
- if (window->frame && window->frame->mapped)
- {
- meta_topic (META_DEBUG_WINDOW_STATE, "Frame actually needs unmap\n");
- window->frame->mapped = FALSE;
- meta_ui_unmap_frame (window->screen->ui, window->frame->xwindow);
- did_hide = TRUE;
- }
-
- if (window->mapped)
- {
- meta_topic (META_DEBUG_WINDOW_STATE,
- "%s actually needs unmap\n", window->desc);
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Incrementing unmaps_pending on %s for hide\n",
- window->desc);
- window->mapped = FALSE;
- window->unmaps_pending += 1;
- meta_error_trap_push (window->display);
- XUnmapWindow (window->display->xdisplay, window->xwindow);
- meta_error_trap_pop (window->display, FALSE);
- did_hide = TRUE;
- }
-
- if (!window->iconic)
- {
- window->iconic = TRUE;
- set_wm_state (window, IconicState);
- }
-
- set_net_wm_state (window);
-
- if (did_hide && window->struts)
- {
- meta_topic (META_DEBUG_WORKAREA,
- "Unmapped window %s with struts, so invalidating work areas\n",
- window->desc);
- invalidate_work_areas (window);
- }
-}
-
-static gboolean
-queue_calc_showing_func (MetaWindow *window,
- void *data)
-{
- meta_window_queue(window, META_QUEUE_CALC_SHOWING);
- return TRUE;
-}
-
-void
-meta_window_minimize (MetaWindow *window)
-{
- if (!window->minimized)
- {
- window->minimized = TRUE;
- meta_window_queue(window, META_QUEUE_CALC_SHOWING);
-
- meta_window_foreach_transient (window,
- queue_calc_showing_func,
- NULL);
-
- if (window->has_focus)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Focusing default window due to minimization of focus window %s\n",
- window->desc);
- }
- else
- {
- meta_topic (META_DEBUG_FOCUS,
- "Minimizing window %s which doesn't have the focus\n",
- window->desc);
- }
- }
-}
-
-void
-meta_window_unminimize (MetaWindow *window)
-{
- if (window->minimized)
- {
- window->minimized = FALSE;
- window->was_minimized = TRUE;
- meta_window_queue(window, META_QUEUE_CALC_SHOWING);
-
- meta_window_foreach_transient (window,
- queue_calc_showing_func,
- NULL);
- }
-}
-
-static void
-ensure_size_hints_satisfied (MetaRectangle *rect,
- const XSizeHints *size_hints)
-{
- int minw, minh, maxw, maxh; /* min/max width/height */
- int basew, baseh, winc, hinc; /* base width/height, width/height increment */
- int extra_width, extra_height;
-
- minw = size_hints->min_width; minh = size_hints->min_height;
- maxw = size_hints->max_width; maxh = size_hints->max_height;
- basew = size_hints->base_width; baseh = size_hints->base_height;
- winc = size_hints->width_inc; hinc = size_hints->height_inc;
-
- /* First, enforce min/max size constraints */
- rect->width = CLAMP (rect->width, minw, maxw);
- rect->height = CLAMP (rect->height, minh, maxh);
-
- /* Now, verify size increment constraints are satisfied, or make them be */
- extra_width = (rect->width - basew) % winc;
- extra_height = (rect->height - baseh) % hinc;
-
- rect->width -= extra_width;
- rect->height -= extra_height;
-
- /* Adjusting width/height down, as done above, may violate minimum size
- * constraints, so one last fix.
- */
- if (rect->width < minw)
- rect->width += ((minw - rect->width)/winc + 1)*winc;
- if (rect->height < minh)
- rect->height += ((minh - rect->height)/hinc + 1)*hinc;
-}
-
-static void
-meta_window_save_rect (MetaWindow *window)
-{
- if (!(META_WINDOW_MAXIMIZED (window) || window->fullscreen))
- {
- /* save size/pos as appropriate args for move_resize */
- if (!window->maximized_horizontally)
- {
- window->saved_rect.x = window->rect.x;
- window->saved_rect.width = window->rect.width;
- if (window->frame)
- window->saved_rect.x += window->frame->rect.x;
- }
- if (!window->maximized_vertically)
- {
- window->saved_rect.y = window->rect.y;
- window->saved_rect.height = window->rect.height;
- if (window->frame)
- window->saved_rect.y += window->frame->rect.y;
- }
- }
-}
-
-/**
- * Save the user_rect regardless of whether the window is maximized or
- * fullscreen. See save_user_window_placement() for most uses.
- *
- * \param window Store current position of this window for future reference
- */
-static void
-force_save_user_window_placement (MetaWindow *window)
-{
- meta_window_get_client_root_coords (window, &window->user_rect);
-}
-
-/**
- * Save the user_rect, but only if the window is neither maximized nor
- * fullscreen, otherwise the window may snap back to those dimensions
- * (bug #461927).
- *
- * \param window Store current position of this window for future reference
- */
-static void
-save_user_window_placement (MetaWindow *window)
-{
- if (!(META_WINDOW_MAXIMIZED (window) || window->fullscreen))
- {
- MetaRectangle user_rect;
-
- meta_window_get_client_root_coords (window, &user_rect);
-
- if (!window->maximized_horizontally)
- {
- window->user_rect.x = user_rect.x;
- window->user_rect.width = user_rect.width;
- }
- if (!window->maximized_vertically)
- {
- window->user_rect.y = user_rect.y;
- window->user_rect.height = user_rect.height;
- }
- }
-}
-
-void
-meta_window_maximize_internal (MetaWindow *window,
- MetaMaximizeFlags directions,
- MetaRectangle *saved_rect)
-{
- /* At least one of the two directions ought to be set */
- gboolean maximize_horizontally, maximize_vertically;
- maximize_horizontally = directions & META_MAXIMIZE_HORIZONTAL;
- maximize_vertically = directions & META_MAXIMIZE_VERTICAL;
- g_assert (maximize_horizontally || maximize_vertically);
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Maximizing %s%s\n",
- window->desc,
- maximize_horizontally && maximize_vertically ? "" :
- maximize_horizontally ? " horizontally" :
- maximize_vertically ? " vertically" : "BUGGGGG");
-
- if (saved_rect != NULL)
- window->saved_rect = *saved_rect;
- else
- meta_window_save_rect (window);
-
- window->maximized_horizontally =
- window->maximized_horizontally || maximize_horizontally;
- window->maximized_vertically =
- window->maximized_vertically || maximize_vertically;
-
- /* Fix for #336850: If the frame shape isn't reapplied, it is
- * possible that the frame will retains its rounded corners. That
- * happens if the client's size when maximized equals the unmaximized
- * size.
- */
- if (window->frame)
- window->frame->need_reapply_frame_shape = TRUE;
-
- recalc_window_features (window);
- set_net_wm_state (window);
-}
-
-void
-meta_window_maximize (MetaWindow *window,
- MetaMaximizeFlags directions)
-{
- /* At least one of the two directions ought to be set */
- gboolean maximize_horizontally, maximize_vertically;
- maximize_horizontally = directions & META_MAXIMIZE_HORIZONTAL;
- maximize_vertically = directions & META_MAXIMIZE_VERTICAL;
- g_assert (maximize_horizontally || maximize_vertically);
-
- /* Only do something if the window isn't already maximized in the
- * given direction(s).
- */
- if ((maximize_horizontally && !window->maximized_horizontally) ||
- (maximize_vertically && !window->maximized_vertically))
- {
- if (window->shaded && maximize_vertically)
- {
- /* Shading sucks anyway; I'm not adding a timestamp argument
- * to this function just for this niche usage & corner case.
- */
- guint32 timestamp =
- meta_display_get_current_time_roundtrip (window->display);
- meta_window_unshade (window, timestamp);
- }
-
- /* if the window hasn't been placed yet, we'll maximize it then
- */
- if (!window->placed)
- {
- window->maximize_horizontally_after_placement =
- window->maximize_horizontally_after_placement ||
- maximize_horizontally;
- window->maximize_vertically_after_placement =
- window->maximize_vertically_after_placement ||
- maximize_vertically;
- return;
- }
-
- meta_window_maximize_internal (window,
- directions,
- NULL);
-
- /* move_resize with new maximization constraints
- */
- meta_window_queue(window, META_QUEUE_MOVE_RESIZE);
- }
-}
-
-static void
-unmaximize_window_before_freeing (MetaWindow *window)
-{
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Unmaximizing %s just before freeing\n",
- window->desc);
-
- window->maximized_horizontally = FALSE;
- window->maximized_vertically = FALSE;
-
- if (window->withdrawn) /* See bug #137185 */
- {
- window->rect = window->saved_rect;
- set_net_wm_state (window);
- }
- else if (window->screen->closing) /* See bug #358042 */
- {
- /* Do NOT update net_wm_state: this screen is closing,
- * it likely will be managed by another window manager
- * that will need the current _NET_WM_STATE atoms.
- * Moreover, it will need to know the unmaximized geometry,
- * therefore move_resize the window to saved_rect here
- * before closing it. */
- meta_window_move_resize (window,
- FALSE,
- window->saved_rect.x,
- window->saved_rect.y,
- window->saved_rect.width,
- window->saved_rect.height);
- }
-}
-
-void
-meta_window_unmaximize (MetaWindow *window,
- MetaMaximizeFlags directions)
-{
- /* At least one of the two directions ought to be set */
- gboolean unmaximize_horizontally, unmaximize_vertically;
- unmaximize_horizontally = directions & META_MAXIMIZE_HORIZONTAL;
- unmaximize_vertically = directions & META_MAXIMIZE_VERTICAL;
- g_assert (unmaximize_horizontally || unmaximize_vertically);
-
- /* Only do something if the window isn't already maximized in the
- * given direction(s).
- */
- if ((unmaximize_horizontally && window->maximized_horizontally) ||
- (unmaximize_vertically && window->maximized_vertically))
- {
- MetaRectangle target_rect;
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Unmaximizing %s%s\n",
- window->desc,
- unmaximize_horizontally && unmaximize_vertically ? "" :
- unmaximize_horizontally ? " horizontally" :
- unmaximize_vertically ? " vertically" : "BUGGGGG");
-
- window->maximized_horizontally =
- window->maximized_horizontally && !unmaximize_horizontally;
- window->maximized_vertically =
- window->maximized_vertically && !unmaximize_vertically;
-
- /* Unmaximize to the saved_rect position in the direction(s)
- * being unmaximized.
- */
- meta_window_get_client_root_coords (window, &target_rect);
- if (unmaximize_horizontally)
- {
- target_rect.x = window->saved_rect.x;
- target_rect.width = window->saved_rect.width;
- }
- if (unmaximize_vertically)
- {
- target_rect.y = window->saved_rect.y;
- target_rect.height = window->saved_rect.height;
- }
-
- /* Window's size hints may have changed while maximized, making
- * saved_rect invalid. #329152
- */
- ensure_size_hints_satisfied (&target_rect, &window->size_hints);
-
- /* When we unmaximize, if we're doing a mouse move also we could
- * get the window suddenly jumping to the upper left corner of
- * the workspace, since that's where it was when the grab op
- * started. So we need to update the grab state.
- */
- if (meta_grab_op_is_moving (window->display->grab_op) &&
- window->display->grab_window == window)
- {
- window->display->grab_anchor_window_pos = target_rect;
- }
-
- meta_window_move_resize (window,
- FALSE,
- target_rect.x,
- target_rect.y,
- target_rect.width,
- target_rect.height);
-
- if (window->display->grab_wireframe_active)
- {
- window->display->grab_wireframe_rect = target_rect;
- }
-
- recalc_window_features (window);
- set_net_wm_state (window);
- }
-}
-
-void
-meta_window_make_above (MetaWindow *window)
-{
- window->wm_state_above = TRUE;
- meta_window_update_layer (window);
- meta_window_raise (window);
- set_net_wm_state (window);
-}
-
-void
-meta_window_unmake_above (MetaWindow *window)
-{
- window->wm_state_above = FALSE;
- meta_window_raise (window);
- meta_window_update_layer (window);
- set_net_wm_state (window);
-}
-
-void
-meta_window_make_fullscreen_internal (MetaWindow *window)
-{
- if (!window->fullscreen)
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Fullscreening %s\n", window->desc);
-
- if (window->shaded)
- {
- /* Shading sucks anyway; I'm not adding a timestamp argument
- * to this function just for this niche usage & corner case.
- */
- guint32 timestamp =
- meta_display_get_current_time_roundtrip (window->display);
- meta_window_unshade (window, timestamp);
- }
-
- meta_window_save_rect (window);
-
- window->fullscreen = TRUE;
-
- meta_stack_freeze (window->screen->stack);
- meta_window_update_layer (window);
-
- meta_window_raise (window);
- meta_stack_thaw (window->screen->stack);
-
- recalc_window_features (window);
- set_net_wm_state (window);
- }
-}
-
-void
-meta_window_make_fullscreen (MetaWindow *window)
-{
- if (!window->fullscreen)
- {
- meta_window_make_fullscreen_internal (window);
- /* move_resize with new constraints
- */
- meta_window_queue(window, META_QUEUE_MOVE_RESIZE);
- }
-}
-
-void
-meta_window_unmake_fullscreen (MetaWindow *window)
-{
- if (window->fullscreen)
- {
- MetaRectangle target_rect;
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Unfullscreening %s\n", window->desc);
-
- window->fullscreen = FALSE;
- target_rect = window->saved_rect;
-
- /* Window's size hints may have changed while maximized, making
- * saved_rect invalid. #329152
- */
- ensure_size_hints_satisfied (&target_rect, &window->size_hints);
-
- meta_window_move_resize (window,
- FALSE,
- target_rect.x,
- target_rect.y,
- target_rect.width,
- target_rect.height);
-
- meta_window_update_layer (window);
-
- recalc_window_features (window);
- set_net_wm_state (window);
- }
-}
-
-void
-meta_window_update_fullscreen_monitors (MetaWindow *window,
- unsigned long top,
- unsigned long bottom,
- unsigned long left,
- unsigned long right)
-{
- if ((int)top < window->screen->n_xinerama_infos &&
- (int)bottom < window->screen->n_xinerama_infos &&
- (int)left < window->screen->n_xinerama_infos &&
- (int)right < window->screen->n_xinerama_infos)
- {
- window->fullscreen_monitors[0] = top;
- window->fullscreen_monitors[1] = bottom;
- window->fullscreen_monitors[2] = left;
- window->fullscreen_monitors[3] = right;
- }
- else
- {
- window->fullscreen_monitors[0] = -1;
- }
-
- if (window->fullscreen)
- {
- meta_window_queue(window, META_QUEUE_MOVE_RESIZE);
- }
-}
-
-void
-meta_window_shade (MetaWindow *window,
- guint32 timestamp)
-{
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Shading %s\n", window->desc);
- if (!window->shaded)
- {
- window->shaded = TRUE;
-
- meta_window_queue(window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING);
-
- /* After queuing the calc showing, since _focus flushes it,
- * and we need to focus the frame
- */
- meta_topic (META_DEBUG_FOCUS,
- "Re-focusing window %s after shading it\n",
- window->desc);
- meta_window_focus (window, timestamp);
-
- set_net_wm_state (window);
- }
-}
-
-void
-meta_window_unshade (MetaWindow *window,
- guint32 timestamp)
-{
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Unshading %s\n", window->desc);
- if (window->shaded)
- {
- window->shaded = FALSE;
- meta_window_queue(window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING);
-
- /* focus the window */
- meta_topic (META_DEBUG_FOCUS,
- "Focusing window %s after unshading it\n",
- window->desc);
- meta_window_focus (window, timestamp);
-
- set_net_wm_state (window);
- }
-}
-
-static gboolean
-unminimize_func (MetaWindow *window,
- void *data)
-{
- meta_window_unminimize (window);
- return TRUE;
-}
-
-static void
-unminimize_window_and_all_transient_parents (MetaWindow *window)
-{
- meta_window_unminimize (window);
- meta_window_foreach_ancestor (window, unminimize_func, NULL);
-}
-
-static void
-window_activate (MetaWindow *window,
- guint32 timestamp,
- MetaClientType source_indication,
- MetaWorkspace *workspace)
-{
- gboolean can_ignore_outdated_timestamps;
- meta_topic (META_DEBUG_FOCUS,
- "_NET_ACTIVE_WINDOW message sent for %s at time %u "
- "by client type %u.\n",
- window->desc, timestamp, source_indication);
-
- /* Older EWMH spec didn't specify a timestamp; we decide to honor these only
- * if the app specifies that it is a pager.
- *
- * Update: Unconditionally honor 0 timestamps for now; we'll fight
- * that battle later. Just remove the "FALSE &&" in order to only
- * honor 0 timestamps for pagers.
- */
- can_ignore_outdated_timestamps =
- (timestamp != 0 || (FALSE && source_indication != META_CLIENT_TYPE_PAGER));
- if (XSERVER_TIME_IS_BEFORE (timestamp, window->display->last_user_time) &&
- can_ignore_outdated_timestamps)
- {
- meta_topic (META_DEBUG_FOCUS,
- "last_user_time (%u) is more recent; ignoring "
- " _NET_ACTIVE_WINDOW message.\n",
- window->display->last_user_time);
- meta_window_set_demands_attention(window);
- return;
- }
-
- /* For those stupid pagers, get a valid timestamp and show a warning */
- if (timestamp == 0)
- {
- meta_warning ("meta_window_activate called by a pager with a 0 timestamp; "
- "the pager needs to be fixed.\n");
- timestamp = meta_display_get_current_time_roundtrip (window->display);
- }
-
- meta_window_set_user_time (window, timestamp);
-
- /* disable show desktop mode unless we're a desktop component */
- maybe_leave_show_desktop_mode (window);
-
- /* Get window on current or given workspace */
- if (workspace == NULL)
- workspace = window->screen->active_workspace;
-
- /* For non-transient windows, we just set up a pulsing indicator,
- rather than move windows or workspaces.
- See http://bugzilla.gnome.org/show_bug.cgi?id=482354 */
- if (window->xtransient_for == None &&
- !meta_window_located_on_workspace (window, workspace))
- {
- meta_window_set_demands_attention (window);
- /* We've marked it as demanding, don't need to do anything else. */
- return;
- }
- else if (window->xtransient_for != None)
- {
- /* Move transients to current workspace - preference dialogs should appear over
- the source window. */
- meta_window_change_workspace (window, workspace);
- }
-
- if (window->shaded)
- meta_window_unshade (window, timestamp);
-
- unminimize_window_and_all_transient_parents (window);
-
- if (meta_prefs_get_raise_on_click () ||
- source_indication == META_CLIENT_TYPE_PAGER)
- meta_window_raise (window);
-
- meta_topic (META_DEBUG_FOCUS,
- "Focusing window %s due to activation\n",
- window->desc);
- meta_window_focus (window, timestamp);
-}
-
-/* This function exists since most of the functionality in window_activate
- * is useful for Metacity, but Metacity shouldn't need to specify a client
- * type for itself. ;-)
- */
-void
-meta_window_activate (MetaWindow *window,
- guint32 timestamp)
-{
- /* We're not really a pager, but the behavior we want is the same as if
- * we were such. If we change the pager behavior later, we could revisit
- * this and just add extra flags to window_activate.
- */
- window_activate (window, timestamp, META_CLIENT_TYPE_PAGER, NULL);
-}
-
-void
-meta_window_activate_with_workspace (MetaWindow *window,
- guint32 timestamp,
- MetaWorkspace *workspace)
-{
- /* We're not really a pager, but the behavior we want is the same as if
- * we were such. If we change the pager behavior later, we could revisit
- * this and just add extra flags to window_activate.
- */
- window_activate (window, timestamp, META_CLIENT_TYPE_APPLICATION, workspace);
-}
-
-/* Manually fix all the weirdness explained in the big comment at the
- * beginning of meta_window_move_resize_internal() giving positions
- * expected by meta_window_constrain (i.e. positions & sizes of the
- * internal or client window).
- */
-static void
-adjust_for_gravity (MetaWindow *window,
- MetaFrameGeometry *fgeom,
- gboolean coords_assume_border,
- int gravity,
- MetaRectangle *rect)
-{
- int ref_x, ref_y;
- int bw;
- int child_x, child_y;
- int frame_width, frame_height;
-
- if (coords_assume_border)
- bw = window->border_width;
- else
- bw = 0;
-
- if (fgeom)
- {
- child_x = fgeom->left_width;
- child_y = fgeom->top_height;
- frame_width = child_x + rect->width + fgeom->right_width;
- frame_height = child_y + rect->height + fgeom->bottom_height;
- }
- else
- {
- child_x = 0;
- child_y = 0;
- frame_width = rect->width;
- frame_height = rect->height;
- }
-
- /* We're computing position to pass to window_move, which is
- * the position of the client window (StaticGravity basically)
- *
- * (see WM spec description of gravity computation, but note that
- * their formulas assume we're honoring the border width, rather
- * than compensating for having turned it off)
- */
- switch (gravity)
- {
- case NorthWestGravity:
- ref_x = rect->x;
- ref_y = rect->y;
- break;
- case NorthGravity:
- ref_x = rect->x + rect->width / 2 + bw;
- ref_y = rect->y;
- break;
- case NorthEastGravity:
- ref_x = rect->x + rect->width + bw * 2;
- ref_y = rect->y;
- break;
- case WestGravity:
- ref_x = rect->x;
- ref_y = rect->y + rect->height / 2 + bw;
- break;
- case CenterGravity:
- ref_x = rect->x + rect->width / 2 + bw;
- ref_y = rect->y + rect->height / 2 + bw;
- break;
- case EastGravity:
- ref_x = rect->x + rect->width + bw * 2;
- ref_y = rect->y + rect->height / 2 + bw;
- break;
- case SouthWestGravity:
- ref_x = rect->x;
- ref_y = rect->y + rect->height + bw * 2;
- break;
- case SouthGravity:
- ref_x = rect->x + rect->width / 2 + bw;
- ref_y = rect->y + rect->height + bw * 2;
- break;
- case SouthEastGravity:
- ref_x = rect->x + rect->width + bw * 2;
- ref_y = rect->y + rect->height + bw * 2;
- break;
- case StaticGravity:
- default:
- ref_x = rect->x;
- ref_y = rect->y;
- break;
- }
-
- switch (gravity)
- {
- case NorthWestGravity:
- rect->x = ref_x + child_x;
- rect->y = ref_y + child_y;
- break;
- case NorthGravity:
- rect->x = ref_x - frame_width / 2 + child_x;
- rect->y = ref_y + child_y;
- break;
- case NorthEastGravity:
- rect->x = ref_x - frame_width + child_x;
- rect->y = ref_y + child_y;
- break;
- case WestGravity:
- rect->x = ref_x + child_x;
- rect->y = ref_y - frame_height / 2 + child_y;
- break;
- case CenterGravity:
- rect->x = ref_x - frame_width / 2 + child_x;
- rect->y = ref_y - frame_height / 2 + child_y;
- break;
- case EastGravity:
- rect->x = ref_x - frame_width + child_x;
- rect->y = ref_y - frame_height / 2 + child_y;
- break;
- case SouthWestGravity:
- rect->x = ref_x + child_x;
- rect->y = ref_y - frame_height + child_y;
- break;
- case SouthGravity:
- rect->x = ref_x - frame_width / 2 + child_x;
- rect->y = ref_y - frame_height + child_y;
- break;
- case SouthEastGravity:
- rect->x = ref_x - frame_width + child_x;
- rect->y = ref_y - frame_height + child_y;
- break;
- case StaticGravity:
- default:
- rect->x = ref_x;
- rect->y = ref_y;
- break;
- }
-}
-
-static gboolean
-static_gravity_works (MetaDisplay *display)
-{
- return display->static_gravity_works;
-}
-
-#ifdef HAVE_XSYNC
-static void
-send_sync_request (MetaWindow *window)
-{
- XSyncValue value;
- XClientMessageEvent ev;
-
- window->sync_request_serial++;
-
- XSyncIntToValue (&value, window->sync_request_serial);
-
- ev.type = ClientMessage;
- ev.window = window->xwindow;
- ev.message_type = window->display->atom_WM_PROTOCOLS;
- ev.format = 32;
- ev.data.l[0] = window->display->atom__NET_WM_SYNC_REQUEST;
- /* FIXME: meta_display_get_current_time() is bad, but since calls
- * come from meta_window_move_resize_internal (which in turn come
- * from all over), I'm not sure what we can do to fix it. Do we
- * want to use _roundtrip, though?
- */
- ev.data.l[1] = meta_display_get_current_time (window->display);
- ev.data.l[2] = XSyncValueLow32 (value);
- ev.data.l[3] = XSyncValueHigh32 (value);
-
- /* We don't need to trap errors here as we are already
- * inside an error_trap_push()/pop() pair.
- */
- XSendEvent (window->display->xdisplay,
- window->xwindow, False, 0, (XEvent*) &ev);
-
- g_get_current_time (&window->sync_request_time);
-}
-#endif
-
-static void
-meta_window_move_resize_internal (MetaWindow *window,
- MetaMoveResizeFlags flags,
- int gravity,
- int root_x_nw,
- int root_y_nw,
- int w,
- int h)
-{
- /* meta_window_move_resize_internal gets called with very different
- * meanings for root_x_nw and root_y_nw. w & h are always the area
- * of the inner or client window (i.e. excluding the frame) and
- * gravity is the relevant gravity associated with the request (note
- * that gravity is ignored for move-only operations unless its
- * e.g. a configure request). The location is different for
- * different cases because of how this function gets called; note
- * that in all cases what we want to find out is the upper left
- * corner of the position of the inner window:
- *
- * Case | Called from (flags; gravity)
- * -----+-----------------------------------------------
- * 1 | A resize only ConfigureRequest
- * 1 | meta_window_resize
- * 1 | meta_window_resize_with_gravity
- * 2 | New window
- * 2 | Session restore
- * 2 | A not-resize-only ConfigureRequest/net_moveresize_window request
- * 3 | meta_window_move
- * 3 | meta_window_move_resize
- *
- * For each of the cases, root_x_nw and root_y_nw must be treated as follows:
- *
- * (1) They should be entirely ignored; instead the previous position
- * and size of the window should be resized according to the given
- * gravity in order to determine the new position of the window.
- * (2) Needs to be fixed up by adjust_for_gravity() as these
- * coordinates are relative to some corner or side of the outer
- * window (except for the case of StaticGravity) and we want to
- * know the location of the upper left corner of the inner window.
- * (3) These values are already the desired positon of the NW corner
- * of the inner window
- */
- XWindowChanges values;
- unsigned int mask;
- gboolean need_configure_notify;
- MetaFrameGeometry fgeom;
- gboolean need_move_client = FALSE;
- gboolean need_move_frame = FALSE;
- gboolean need_resize_client = FALSE;
- gboolean need_resize_frame = FALSE;
- int frame_size_dx;
- int frame_size_dy;
- int size_dx;
- int size_dy;
- gboolean is_configure_request;
- gboolean do_gravity_adjust;
- gboolean is_user_action;
- gboolean configure_frame_first;
- gboolean use_static_gravity;
- /* used for the configure request, but may not be final
- * destination due to StaticGravity etc.
- */
- int client_move_x;
- int client_move_y;
- MetaRectangle new_rect;
- MetaRectangle old_rect;
-
- is_configure_request = (flags & META_IS_CONFIGURE_REQUEST) != 0;
- do_gravity_adjust = (flags & META_DO_GRAVITY_ADJUST) != 0;
- is_user_action = (flags & META_IS_USER_ACTION) != 0;
-
- /* The action has to be a move or a resize or both... */
- g_assert (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION));
-
- /* We don't need it in the idle queue anymore. */
- meta_window_unqueue (window, META_QUEUE_MOVE_RESIZE);
-
- meta_window_get_client_root_coords (window, &old_rect);
-
- meta_topic (META_DEBUG_GEOMETRY,
- "Move/resize %s to %d,%d %dx%d%s%s from %d,%d %dx%d\n",
- window->desc, root_x_nw, root_y_nw, w, h,
- is_configure_request ? " (configure request)" : "",
- is_user_action ? " (user move/resize)" : "",
- old_rect.x, old_rect.y, old_rect.width, old_rect.height);
-
- if (window->frame)
- meta_frame_calc_geometry (window->frame,
- &fgeom);
-
- new_rect.x = root_x_nw;
- new_rect.y = root_y_nw;
- new_rect.width = w;
- new_rect.height = h;
-
- /* If this is a resize only, the position should be ignored and
- * instead obtained by resizing the old rectangle according to the
- * relevant gravity.
- */
- if ((flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION)) ==
- META_IS_RESIZE_ACTION)
- {
- meta_rectangle_resize_with_gravity (&old_rect,
- &new_rect,
- gravity,
- new_rect.width,
- new_rect.height);
-
- meta_topic (META_DEBUG_GEOMETRY,
- "Compensated for gravity in resize action; new pos %d,%d\n",
- new_rect.x, new_rect.y);
- }
- else if (is_configure_request || do_gravity_adjust)
- {
- adjust_for_gravity (window,
- window->frame ? &fgeom : NULL,
- /* configure request coords assume
- * the border width existed
- */
- is_configure_request,
- gravity,
- &new_rect);
-
- meta_topic (META_DEBUG_GEOMETRY,
- "Compensated for configure_request/do_gravity_adjust needing "
- "weird positioning; new pos %d,%d\n",
- new_rect.x, new_rect.y);
- }
-
- meta_window_constrain (window,
- window->frame ? &fgeom : NULL,
- flags,
- gravity,
- &old_rect,
- &new_rect);
-
- w = new_rect.width;
- h = new_rect.height;
- root_x_nw = new_rect.x;
- root_y_nw = new_rect.y;
-
- if (w != window->rect.width ||
- h != window->rect.height)
- need_resize_client = TRUE;
-
- window->rect.width = w;
- window->rect.height = h;
-
- if (window->frame)
- {
- int new_w, new_h;
-
- new_w = window->rect.width + fgeom.left_width + fgeom.right_width;
-
- if (window->shaded)
- new_h = fgeom.top_height;
- else
- new_h = window->rect.height + fgeom.top_height + fgeom.bottom_height;
-
- frame_size_dx = new_w - window->frame->rect.width;
- frame_size_dy = new_h - window->frame->rect.height;
-
- need_resize_frame = (frame_size_dx != 0 || frame_size_dy != 0);
-
- window->frame->rect.width = new_w;
- window->frame->rect.height = new_h;
-
- meta_topic (META_DEBUG_GEOMETRY,
- "Calculated frame size %dx%d\n",
- window->frame->rect.width,
- window->frame->rect.height);
- }
- else
- {
- frame_size_dx = 0;
- frame_size_dy = 0;
- }
-
- /* For nice effect, when growing the window we want to move/resize
- * the frame first, when shrinking the window we want to move/resize
- * the client first. If we grow one way and shrink the other,
- * see which way we're moving "more"
- *
- * Mail from Owen subject "Suggestion: Gravity and resizing from the left"
- * http://mail.gnome.org/archives/wm-spec-list/1999-November/msg00088.html
- *
- * An annoying fact you need to know in this code is that StaticGravity
- * does nothing if you _only_ resize or _only_ move the frame;
- * it must move _and_ resize, otherwise you get NorthWestGravity
- * behavior. The move and resize must actually occur, it is not
- * enough to set CWX | CWWidth but pass in the current size/pos.
- */
-
- if (window->frame)
- {
- int new_x, new_y;
- int frame_pos_dx, frame_pos_dy;
-
- /* Compute new frame coords */
- new_x = root_x_nw - fgeom.left_width;
- new_y = root_y_nw - fgeom.top_height;
-
- frame_pos_dx = new_x - window->frame->rect.x;
- frame_pos_dy = new_y - window->frame->rect.y;
-
- need_move_frame = (frame_pos_dx != 0 || frame_pos_dy != 0);
-
- window->frame->rect.x = new_x;
- window->frame->rect.y = new_y;
-
- /* If frame will both move and resize, then StaticGravity
- * on the child window will kick in and implicitly move
- * the child with respect to the frame. The implicit
- * move will keep the child in the same place with
- * respect to the root window. If frame only moves
- * or only resizes, then the child will just move along
- * with the frame.
- */
-
- /* window->rect.x, window->rect.y are relative to frame,
- * remember they are the server coords
- */
-
- new_x = fgeom.left_width;
- new_y = fgeom.top_height;
-
- if (need_resize_frame && need_move_frame &&
- static_gravity_works (window->display))
- {
- /* static gravity kicks in because frame
- * is both moved and resized
- */
- /* when we move the frame by frame_pos_dx, frame_pos_dy the
- * client will implicitly move relative to frame by the
- * inverse delta.
- *
- * When moving client then frame, we move the client by the
- * frame delta, to be canceled out by the implicit move by
- * the inverse frame delta, resulting in a client at new_x,
- * new_y.
- *
- * When moving frame then client, we move the client
- * by the same delta as the frame, because the client
- * was "left behind" by the frame - resulting in a client
- * at new_x, new_y.
- *
- * In both cases we need to move the client window
- * in all cases where we had to move the frame window.
- */
-
- client_move_x = new_x + frame_pos_dx;
- client_move_y = new_y + frame_pos_dy;
-
- if (need_move_frame)
- need_move_client = TRUE;
-
- use_static_gravity = TRUE;
- }
- else
- {
- client_move_x = new_x;
- client_move_y = new_y;
-
- if (client_move_x != window->rect.x ||
- client_move_y != window->rect.y)
- need_move_client = TRUE;
-
- use_static_gravity = FALSE;
- }
-
- /* This is the final target position, but not necessarily what
- * we pass to XConfigureWindow, due to StaticGravity implicit
- * movement.
- */
- window->rect.x = new_x;
- window->rect.y = new_y;
- }
- else
- {
- if (root_x_nw != window->rect.x ||
- root_y_nw != window->rect.y)
- need_move_client = TRUE;
-
- window->rect.x = root_x_nw;
- window->rect.y = root_y_nw;
-
- client_move_x = window->rect.x;
- client_move_y = window->rect.y;
-
- use_static_gravity = FALSE;
- }
-
- /* If frame extents have changed, fill in other frame fields and
- change frame's extents property. */
- if (window->frame &&
- (window->frame->child_x != fgeom.left_width ||
- window->frame->child_y != fgeom.top_height ||
- window->frame->right_width != fgeom.right_width ||
- window->frame->bottom_height != fgeom.bottom_height))
- {
- window->frame->child_x = fgeom.left_width;
- window->frame->child_y = fgeom.top_height;
- window->frame->right_width = fgeom.right_width;
- window->frame->bottom_height = fgeom.bottom_height;
-
- update_net_frame_extents (window);
- }
-
- /* See ICCCM 4.1.5 for when to send ConfigureNotify */
-
- need_configure_notify = FALSE;
-
- /* If this is a configure request and we change nothing, then we
- * must send configure notify.
- */
- if (is_configure_request &&
- !(need_move_client || need_move_frame ||
- need_resize_client || need_resize_frame ||
- window->border_width != 0))
- need_configure_notify = TRUE;
-
- /* We must send configure notify if we move but don't resize, since
- * the client window may not get a real event
- */
- if ((need_move_client || need_move_frame) &&
- !(need_resize_client || need_resize_frame))
- need_configure_notify = TRUE;
-
- /* MapRequest events with a PPosition or UPosition hint with a frame
- * are moved by metacity without resizing; send a configure notify
- * in such cases. See #322840. (Note that window->constructing is
- * only true iff this call is due to a MapRequest, and when
- * PPosition/UPosition hints aren't set, metacity seems to send a
- * ConfigureNotify anyway due to the above code.)
- */
- if (window->constructing && window->frame &&
- ((window->size_hints.flags & PPosition) ||
- (window->size_hints.flags & USPosition)))
- need_configure_notify = TRUE;
-
- /* The rest of this function syncs our new size/pos with X as
- * efficiently as possible
- */
-
- /* configure frame first if we grow more than we shrink
- */
- size_dx = w - window->rect.width;
- size_dy = h - window->rect.height;
-
- configure_frame_first = (size_dx + size_dy >= 0);
-
- if (use_static_gravity)
- meta_window_set_gravity (window, StaticGravity);
-
- if (configure_frame_first && window->frame)
- meta_frame_sync_to_window (window->frame,
- gravity,
- need_move_frame, need_resize_frame);
-
- values.border_width = 0;
- values.x = client_move_x;
- values.y = client_move_y;
- values.width = window->rect.width;
- values.height = window->rect.height;
-
- mask = 0;
- if (is_configure_request && window->border_width != 0)
- mask |= CWBorderWidth; /* must force to 0 */
- if (need_move_client)
- mask |= (CWX | CWY);
- if (need_resize_client)
- mask |= (CWWidth | CWHeight);
-
- if (mask != 0)
- {
- {
- int newx, newy;
- meta_window_get_position (window, &newx, &newy);
- meta_topic (META_DEBUG_GEOMETRY,
- "Syncing new client geometry %d,%d %dx%d, border: %s pos: %s size: %s\n",
- newx, newy,
- window->rect.width, window->rect.height,
- mask & CWBorderWidth ? "true" : "false",
- need_move_client ? "true" : "false",
- need_resize_client ? "true" : "false");
- }
-
- meta_error_trap_push (window->display);
-
-#ifdef HAVE_XSYNC
- if (window->sync_request_counter != None &&
- window->display->grab_sync_request_alarm != None &&
- window->sync_request_time.tv_usec == 0 &&
- window->sync_request_time.tv_sec == 0)
- {
- /* turn off updating */
- if (window->display->compositor)
- meta_compositor_set_updates (window->display->compositor, window, FALSE);
-
- send_sync_request (window);
- }
-#endif
-
- XConfigureWindow (window->display->xdisplay,
- window->xwindow,
- mask,
- &values);
-
- meta_error_trap_pop (window->display, FALSE);
- }
-
- if (!configure_frame_first && window->frame)
- meta_frame_sync_to_window (window->frame,
- gravity,
- need_move_frame, need_resize_frame);
-
- /* Put gravity back to be nice to lesser window managers */
- if (use_static_gravity)
- meta_window_set_gravity (window, NorthWestGravity);
-
- if (need_configure_notify)
- send_configure_notify (window);
-
- if (!window->placed)
- force_save_user_window_placement (window);
- else if (is_user_action)
- save_user_window_placement (window);
-
- if (need_move_frame || need_resize_frame ||
- need_move_client || need_resize_client)
- {
- int newx, newy;
- meta_window_get_position (window, &newx, &newy);
- meta_topic (META_DEBUG_GEOMETRY,
- "New size/position %d,%d %dx%d (user %d,%d %dx%d)\n",
- newx, newy, window->rect.width, window->rect.height,
- window->user_rect.x, window->user_rect.y,
- window->user_rect.width, window->user_rect.height);
- }
- else
- {
- meta_topic (META_DEBUG_GEOMETRY, "Size/position not modified\n");
- }
-
- if (window->display->grab_wireframe_active)
- meta_window_update_wireframe (window, root_x_nw, root_y_nw, w, h);
- else
- meta_window_refresh_resize_popup (window);
-
- /* Invariants leaving this function are:
- * a) window->rect and frame->rect reflect the actual
- * server-side size/pos of window->xwindow and frame->xwindow
- * b) all constraints are obeyed by window->rect and frame->rect
- */
-}
-
-void
-meta_window_resize (MetaWindow *window,
- gboolean user_op,
- int w,
- int h)
-{
- int x, y;
- MetaMoveResizeFlags flags;
-
- meta_window_get_position (window, &x, &y);
-
- flags = (user_op ? META_IS_USER_ACTION : 0) | META_IS_RESIZE_ACTION;
- meta_window_move_resize_internal (window,
- flags,
- NorthWestGravity,
- x, y, w, h);
-}
-
-void
-meta_window_move (MetaWindow *window,
- gboolean user_op,
- int root_x_nw,
- int root_y_nw)
-{
- MetaMoveResizeFlags flags =
- (user_op ? META_IS_USER_ACTION : 0) | META_IS_MOVE_ACTION;
- meta_window_move_resize_internal (window,
- flags,
- NorthWestGravity,
- root_x_nw, root_y_nw,
- window->rect.width,
- window->rect.height);
-}
-
-void
-meta_window_move_resize (MetaWindow *window,
- gboolean user_op,
- int root_x_nw,
- int root_y_nw,
- int w,
- int h)
-{
- MetaMoveResizeFlags flags =
- (user_op ? META_IS_USER_ACTION : 0) |
- META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
- meta_window_move_resize_internal (window,
- flags,
- NorthWestGravity,
- root_x_nw, root_y_nw,
- w, h);
-}
-
-void
-meta_window_resize_with_gravity (MetaWindow *window,
- gboolean user_op,
- int w,
- int h,
- int gravity)
-{
- int x, y;
- MetaMoveResizeFlags flags;
-
- meta_window_get_position (window, &x, &y);
-
- flags = (user_op ? META_IS_USER_ACTION : 0) | META_IS_RESIZE_ACTION;
- meta_window_move_resize_internal (window,
- flags,
- gravity,
- x, y, w, h);
-}
-
-static void
-meta_window_move_resize_now (MetaWindow *window)
-{
- /* If constraints have changed then we want to snap back to wherever
- * the user had the window. We use user_rect for this reason. See
- * also bug 426519 comment 3.
- */
- meta_window_move_resize (window, FALSE,
- window->user_rect.x,
- window->user_rect.y,
- window->user_rect.width,
- window->user_rect.height);
-}
-
-static gboolean
-idle_move_resize (gpointer data)
-{
- GSList *tmp;
- GSList *copy;
- guint queue_index = GPOINTER_TO_INT (data);
-
- meta_topic (META_DEBUG_GEOMETRY, "Clearing the move_resize queue\n");
-
- /* Work with a copy, for reentrancy. The allowed reentrancy isn't
- * complete; destroying a window while we're in here would result in
- * badness. But it's OK to queue/unqueue move_resizes.
- */
- copy = g_slist_copy (queue_pending[queue_index]);
- g_slist_free (queue_pending[queue_index]);
- queue_pending[queue_index] = NULL;
- queue_idle[queue_index] = 0;
-
- destroying_windows_disallowed += 1;
-
- tmp = copy;
- while (tmp != NULL)
- {
- MetaWindow *window;
-
- window = tmp->data;
-
- /* As a side effect, sets window->move_resize_queued = FALSE */
- meta_window_move_resize_now (window);
-
- tmp = tmp->next;
- }
-
- g_slist_free (copy);
-
- destroying_windows_disallowed -= 1;
-
- return FALSE;
-}
-
-void
-meta_window_get_position (MetaWindow *window,
- int *x,
- int *y)
-{
- if (window->frame)
- {
- if (x)
- *x = window->frame->rect.x + window->frame->child_x;
- if (y)
- *y = window->frame->rect.y + window->frame->child_y;
- }
- else
- {
- if (x)
- *x = window->rect.x;
- if (y)
- *y = window->rect.y;
- }
-}
-
-void
-meta_window_get_client_root_coords (MetaWindow *window,
- MetaRectangle *rect)
-{
- meta_window_get_position (window, &rect->x, &rect->y);
- rect->width = window->rect.width;
- rect->height = window->rect.height;
-}
-
-void
-meta_window_get_gravity_position (MetaWindow *window,
- int gravity,
- int *root_x,
- int *root_y)
-{
- MetaRectangle frame_extents;
- int w, h;
- int x, y;
-
- w = window->rect.width;
- h = window->rect.height;
-
- if (gravity == StaticGravity)
- {
- frame_extents = window->rect;
- if (window->frame)
- {
- frame_extents.x = window->frame->rect.x + window->frame->child_x;
- frame_extents.y = window->frame->rect.y + window->frame->child_y;
- }
- }
- else
- {
- if (window->frame == NULL)
- frame_extents = window->rect;
- else
- frame_extents = window->frame->rect;
- }
-
- x = frame_extents.x;
- y = frame_extents.y;
-
- switch (gravity)
- {
- case NorthGravity:
- case CenterGravity:
- case SouthGravity:
- /* Find center of frame. */
- x += frame_extents.width / 2;
- /* Center client window on that point. */
- x -= w / 2;
- break;
-
- case SouthEastGravity:
- case EastGravity:
- case NorthEastGravity:
- /* Find right edge of frame */
- x += frame_extents.width;
- /* Align left edge of client at that point. */
- x -= w;
- break;
- default:
- break;
- }
-
- switch (gravity)
- {
- case WestGravity:
- case CenterGravity:
- case EastGravity:
- /* Find center of frame. */
- y += frame_extents.height / 2;
- /* Center client window there. */
- y -= h / 2;
- break;
- case SouthWestGravity:
- case SouthGravity:
- case SouthEastGravity:
- /* Find south edge of frame */
- y += frame_extents.height;
- /* Place bottom edge of client there */
- y -= h;
- break;
- default:
- break;
- }
-
- if (root_x)
- *root_x = x;
- if (root_y)
- *root_y = y;
-}
-
-void
-meta_window_get_geometry (MetaWindow *window,
- int *x,
- int *y,
- int *width,
- int *height)
-{
- meta_window_get_gravity_position (window,
- window->size_hints.win_gravity,
- x, y);
-
- *width = (window->rect.width - window->size_hints.base_width) /
- window->size_hints.width_inc;
- *height = (window->rect.height - window->size_hints.base_height) /
- window->size_hints.height_inc;
-}
-
-void
-meta_window_get_outer_rect (const MetaWindow *window,
- MetaRectangle *rect)
-{
- if (window->frame)
- *rect = window->frame->rect;
- else
- *rect = window->rect;
-}
-
-void
-meta_window_get_xor_rect (MetaWindow *window,
- const MetaRectangle *grab_wireframe_rect,
- MetaRectangle *xor_rect)
-{
- if (window->frame)
- {
- xor_rect->x = grab_wireframe_rect->x - window->frame->child_x;
- xor_rect->y = grab_wireframe_rect->y - window->frame->child_y;
- xor_rect->width = grab_wireframe_rect->width + window->frame->child_x + window->frame->right_width;
-
- if (window->shaded)
- xor_rect->height = window->frame->child_y;
- else
- xor_rect->height = grab_wireframe_rect->height + window->frame->child_y + window->frame->bottom_height;
- }
- else
- *xor_rect = *grab_wireframe_rect;
-}
-
-/* Figure out the numbers that show up in the
- * resize popup when in reduced resources mode.
- */
-static void
-meta_window_get_wireframe_geometry (MetaWindow *window,
- int *width,
- int *height)
-{
- if (!window->display->grab_wireframe_active)
- return;
-
- if ((width == NULL) || (height == NULL))
- return;
-
- if ((window->display->grab_window->size_hints.width_inc <= 1) ||
- (window->display->grab_window->size_hints.height_inc <= 1))
- {
- *width = -1;
- *height = -1;
- return;
- }
-
- *width = window->display->grab_wireframe_rect.width -
- window->display->grab_window->size_hints.base_width;
- *width /= window->display->grab_window->size_hints.width_inc;
-
- *height = window->display->grab_wireframe_rect.height -
- window->display->grab_window->size_hints.base_height;
- *height /= window->display->grab_window->size_hints.height_inc;
-}
-
-/* XXX META_EFFECT_ALT_TAB, well, this and others */
-void
-meta_window_begin_wireframe (MetaWindow *window)
-{
-
- MetaRectangle new_xor;
- int display_width, display_height;
-
- meta_window_get_client_root_coords (window,
- &window->display->grab_wireframe_rect);
-
- meta_window_get_xor_rect (window, &window->display->grab_wireframe_rect,
- &new_xor);
- meta_window_get_wireframe_geometry (window, &display_width, &display_height);
-
- meta_effects_begin_wireframe (window->screen,
- &new_xor, display_width, display_height);
-
- window->display->grab_wireframe_last_xor_rect = new_xor;
- window->display->grab_wireframe_last_display_width = display_width;
- window->display->grab_wireframe_last_display_height = display_height;
-}
-
-void
-meta_window_update_wireframe (MetaWindow *window,
- int x,
- int y,
- int width,
- int height)
-{
-
- MetaRectangle new_xor;
- int display_width, display_height;
-
- window->display->grab_wireframe_rect.x = x;
- window->display->grab_wireframe_rect.y = y;
- window->display->grab_wireframe_rect.width = width;
- window->display->grab_wireframe_rect.height = height;
-
- meta_window_get_xor_rect (window, &window->display->grab_wireframe_rect,
- &new_xor);
- meta_window_get_wireframe_geometry (window, &display_width, &display_height);
-
- meta_effects_update_wireframe (window->screen,
- &window->display->grab_wireframe_last_xor_rect,
- window->display->grab_wireframe_last_display_width,
- window->display->grab_wireframe_last_display_height,
- &new_xor, display_width, display_height);
-
- window->display->grab_wireframe_last_xor_rect = new_xor;
- window->display->grab_wireframe_last_display_width = display_width;
- window->display->grab_wireframe_last_display_height = display_height;
-}
-
-void
-meta_window_end_wireframe (MetaWindow *window)
-{
- meta_effects_end_wireframe (window->display->grab_window->screen,
- &window->display->grab_wireframe_last_xor_rect,
- window->display->grab_wireframe_last_display_width,
- window->display->grab_wireframe_last_display_height);
-}
-
-const char*
-meta_window_get_startup_id (MetaWindow *window)
-{
- if (window->startup_id == NULL)
- {
- MetaGroup *group;
-
- group = meta_window_get_group (window);
-
- if (group != NULL)
- return meta_group_get_startup_id (group);
- }
-
- return window->startup_id;
-}
-
-static MetaWindow*
-get_modal_transient (MetaWindow *window)
-{
- GSList *windows;
- GSList *tmp;
- MetaWindow *modal_transient;
-
- /* A window can't be the transient of itself, but this is just for
- * convenience in the loop below; we manually fix things up at the
- * end if no real modal transient was found.
- */
- modal_transient = window;
-
- windows = meta_display_list_windows (window->display);
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *transient = tmp->data;
-
- if (transient->xtransient_for == modal_transient->xwindow &&
- transient->wm_state_modal)
- {
- modal_transient = transient;
- tmp = windows;
- continue;
- }
-
- tmp = tmp->next;
- }
-
- g_slist_free (windows);
-
- if (window == modal_transient)
- modal_transient = NULL;
-
- return modal_transient;
-}
-
-/* XXX META_EFFECT_FOCUS */
-void
-meta_window_focus (MetaWindow *window,
- guint32 timestamp)
-{
- MetaWindow *modal_transient;
-
- meta_topic (META_DEBUG_FOCUS,
- "Setting input focus to window %s, input: %d take_focus: %d\n",
- window->desc, window->input, window->take_focus);
-
- if (window->display->grab_window &&
- window->display->grab_window->all_keys_grabbed)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Current focus window %s has global keygrab, not focusing window %s after all\n",
- window->display->grab_window->desc, window->desc);
- return;
- }
-
- modal_transient = get_modal_transient (window);
- if (modal_transient != NULL &&
- !modal_transient->unmanaging)
- {
- meta_topic (META_DEBUG_FOCUS,
- "%s has %s as a modal transient, so focusing it instead.\n",
- window->desc, modal_transient->desc);
- if (!modal_transient->on_all_workspaces &&
- modal_transient->workspace != window->screen->active_workspace)
- meta_window_change_workspace (modal_transient,
- window->screen->active_workspace);
- window = modal_transient;
- }
-
- meta_window_flush_calc_showing (window);
-
- if (!window->mapped && !window->shaded)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Window %s is not showing, not focusing after all\n",
- window->desc);
- return;
- }
-
- /* For output-only or shaded windows, focus the frame.
- * This seems to result in the client window getting key events
- * though, so I don't know if it's icccm-compliant.
- *
- * Still, we have to do this or keynav breaks for these windows.
- */
- if (window->frame &&
- (window->shaded ||
- !(window->input || window->take_focus)))
- {
- if (window->frame)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Focusing frame of %s\n", window->desc);
- meta_display_set_input_focus_window (window->display,
- window,
- TRUE,
- timestamp);
- }
- }
- else
- {
- if (window->input)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Setting input focus on %s since input = true\n",
- window->desc);
- meta_display_set_input_focus_window (window->display,
- window,
- FALSE,
- timestamp);
- }
-
- if (window->take_focus)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Sending WM_TAKE_FOCUS to %s since take_focus = true\n",
- window->desc);
- meta_window_send_icccm_message (window,
- window->display->atom_WM_TAKE_FOCUS,
- timestamp);
- window->display->expected_focus_window = window;
- }
- }
-
- if (window->wm_state_demands_attention)
- meta_window_unset_demands_attention(window);
-
- meta_effect_run_focus(window, NULL, NULL);
-}
-
-static void
-meta_window_change_workspace_without_transients (MetaWindow *window,
- MetaWorkspace *workspace)
-{
- meta_verbose ("Changing window %s to workspace %d\n",
- window->desc, meta_workspace_index (workspace));
-
- /* unstick if stuck. meta_window_unstick would call
- * meta_window_change_workspace recursively if the window
- * is not in the active workspace.
- */
- if (window->on_all_workspaces)
- meta_window_unstick (window);
-
- /* See if we're already on this space. If not, make sure we are */
- if (window->workspace != workspace)
- {
- meta_workspace_remove_window (window->workspace, window);
- meta_workspace_add_window (workspace, window);
- }
-}
-
-static gboolean
-change_workspace_foreach (MetaWindow *window,
- void *data)
-{
- meta_window_change_workspace_without_transients (window, data);
- return TRUE;
-}
-
-void
-meta_window_change_workspace (MetaWindow *window,
- MetaWorkspace *workspace)
-{
- meta_window_change_workspace_without_transients (window, workspace);
-
- meta_window_foreach_transient (window, change_workspace_foreach,
- workspace);
- meta_window_foreach_ancestor (window, change_workspace_foreach,
- workspace);
-}
-
-static void
-window_stick_impl (MetaWindow *window)
-{
- GList *tmp;
- MetaWorkspace *workspace;
-
- meta_verbose ("Sticking window %s current on_all_workspaces = %d\n",
- window->desc, window->on_all_workspaces);
-
- if (window->on_all_workspaces)
- return;
-
- /* We don't change window->workspaces, because we revert
- * to that original workspace list if on_all_workspaces is
- * toggled back off.
- */
- window->on_all_workspaces = TRUE;
-
- /* We do, however, change the MRU lists of all the workspaces
- */
- tmp = window->screen->workspaces;
- while (tmp)
- {
- workspace = (MetaWorkspace *) tmp->data;
- if (!g_list_find (workspace->mru_list, window))
- workspace->mru_list = g_list_prepend (workspace->mru_list, window);
-
- tmp = tmp->next;
- }
-
- meta_window_set_current_workspace_hint (window);
-
- meta_window_queue(window, META_QUEUE_CALC_SHOWING);
-}
-
-static void
-window_unstick_impl (MetaWindow *window)
-{
- GList *tmp;
- MetaWorkspace *workspace;
-
- if (!window->on_all_workspaces)
- return;
-
- /* Revert to window->workspaces */
-
- window->on_all_workspaces = FALSE;
-
- /* Remove window from MRU lists that it doesn't belong in */
- tmp = window->screen->workspaces;
- while (tmp)
- {
- workspace = (MetaWorkspace *) tmp->data;
- if (window->workspace != workspace)
- workspace->mru_list = g_list_remove (workspace->mru_list, window);
- tmp = tmp->next;
- }
-
- /* We change ourselves to the active workspace, since otherwise you'd get
- * a weird window-vaporization effect. Once we have UI for being
- * on more than one workspace this should probably be add_workspace
- * not change_workspace.
- */
- if (window->screen->active_workspace != window->workspace)
- meta_window_change_workspace (window, window->screen->active_workspace);
-
- meta_window_set_current_workspace_hint (window);
-
- meta_window_queue(window, META_QUEUE_CALC_SHOWING);
-}
-
-static gboolean
-stick_foreach_func (MetaWindow *window,
- void *data)
-{
- gboolean stick;
-
- stick = *(gboolean*)data;
- if (stick)
- window_stick_impl (window);
- else
- window_unstick_impl (window);
- return TRUE;
-}
-
-void
-meta_window_stick (MetaWindow *window)
-{
- gboolean stick = TRUE;
- window_stick_impl (window);
- meta_window_foreach_transient (window,
- stick_foreach_func,
- &stick);
-}
-
-void
-meta_window_unstick (MetaWindow *window)
-{
- gboolean stick = FALSE;
- window_unstick_impl (window);
- meta_window_foreach_transient (window,
- stick_foreach_func,
- &stick);
-}
-
-unsigned long
-meta_window_get_net_wm_desktop (MetaWindow *window)
-{
- if (window->on_all_workspaces)
- return 0xFFFFFFFF;
- else
- return meta_workspace_index (window->workspace);
-}
-
-static void
-update_net_frame_extents (MetaWindow *window)
-{
- unsigned long data[4] = { 0, 0, 0, 0 };
-
- if (window->frame)
- {
- /* Left */
- data[0] = window->frame->child_x;
- /* Right */
- data[1] = window->frame->right_width;
- /* Top */
- data[2] = window->frame->child_y;
- /* Bottom */
- data[3] = window->frame->bottom_height;
- }
-
- meta_topic (META_DEBUG_GEOMETRY,
- "Setting _NET_FRAME_EXTENTS on managed window 0x%lx "
- "to left = %lu, right = %lu, top = %lu, bottom = %lu\n",
- window->xwindow, data[0], data[1], data[2], data[3]);
-
- meta_error_trap_push (window->display);
- XChangeProperty (window->display->xdisplay, window->xwindow,
- window->display->atom__NET_FRAME_EXTENTS,
- XA_CARDINAL,
- 32, PropModeReplace, (guchar*) data, 4);
- meta_error_trap_pop (window->display, FALSE);
-}
-
-void
-meta_window_set_current_workspace_hint (MetaWindow *window)
-{
- /* FIXME if on more than one workspace, we claim to be "sticky",
- * the WM spec doesn't say what to do here.
- */
- unsigned long data[1];
-
- if (window->workspace == NULL)
- {
- /* this happens when unmanaging windows */
- return;
- }
-
- data[0] = meta_window_get_net_wm_desktop (window);
-
- meta_verbose ("Setting _NET_WM_DESKTOP of %s to %lu\n",
- window->desc, data[0]);
-
- meta_error_trap_push (window->display);
- XChangeProperty (window->display->xdisplay, window->xwindow,
- window->display->atom__NET_WM_DESKTOP,
- XA_CARDINAL,
- 32, PropModeReplace, (guchar*) data, 1);
- meta_error_trap_pop (window->display, FALSE);
-}
-
-static gboolean
-find_root_ancestor (MetaWindow *window,
- void *data)
-{
- MetaWindow **ancestor = data;
-
- /* Overwrite the previously "most-root" ancestor with the new one found */
- *ancestor = window;
-
- /* We want this to continue until meta_window_foreach_ancestor quits because
- * there are no more valid ancestors.
- */
- return TRUE;
-}
-
-MetaWindow *
-meta_window_find_root_ancestor (MetaWindow *window)
-{
- MetaWindow *ancestor;
- ancestor = window;
- meta_window_foreach_ancestor (window, find_root_ancestor, &ancestor);
- return ancestor;
-}
-
-void
-meta_window_raise (MetaWindow *window)
-{
- MetaWindow *ancestor;
- ancestor = meta_window_find_root_ancestor (window);
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Raising window %s, ancestor of %s\n",
- ancestor->desc, window->desc);
-
- /* Raise the ancestor of the window (if the window has no ancestor,
- * then ancestor will be set to the window itself); do this because
- * it's weird to see windows from other apps stacked between a child
- * and parent window of the currently active app. The stacking
- * constraints in stack.c then magically take care of raising all
- * the child windows appropriately.
- */
- if (window->screen->stack == ancestor->screen->stack)
- meta_stack_raise (window->screen->stack, ancestor);
- else
- {
- meta_warning (
- "Either stacks aren't per screen or some window has a weird "
- "transient_for hint; window->screen->stack != "
- "ancestor->screen->stack. window = %s, ancestor = %s.\n",
- window->desc, ancestor->desc);
- /* We could raise the window here, but don't want to do that twice and
- * so we let the case below handle that.
- */
- }
-
- /* Okay, so stacking constraints misses one case: If a window has
- * two children and we want to raise one of those children, then
- * raising the ancestor isn't enough; we need to also raise the
- * correct child. See bug 307875.
- */
- if (window != ancestor)
- meta_stack_raise (window->screen->stack, window);
-}
-
-void
-meta_window_lower (MetaWindow *window)
-{
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Lowering window %s\n", window->desc);
-
- meta_stack_lower (window->screen->stack, window);
-}
-
-void
-meta_window_send_icccm_message (MetaWindow *window,
- Atom atom,
- guint32 timestamp)
-{
- /* This comment and code are from twm, copyright
- * Open Group, Evans & Sutherland, etc.
- */
-
- /*
- * ICCCM Client Messages - Section 4.2.8 of the ICCCM dictates that all
- * client messages will have the following form:
- *
- * event type ClientMessage
- * message type _XA_WM_PROTOCOLS
- * window tmp->w
- * format 32
- * data[0] message atom
- * data[1] time stamp
- */
-
- XClientMessageEvent ev;
-
- ev.type = ClientMessage;
- ev.window = window->xwindow;
- ev.message_type = window->display->atom_WM_PROTOCOLS;
- ev.format = 32;
- ev.data.l[0] = atom;
- ev.data.l[1] = timestamp;
-
- meta_error_trap_push (window->display);
- XSendEvent (window->display->xdisplay,
- window->xwindow, False, 0, (XEvent*) &ev);
- meta_error_trap_pop (window->display, FALSE);
-}
-
-void
-meta_window_move_resize_request (MetaWindow *window,
- guint value_mask,
- int gravity,
- int new_x,
- int new_y,
- int new_width,
- int new_height)
-{
- int x, y, width, height;
- gboolean allow_position_change;
- gboolean in_grab_op;
- MetaMoveResizeFlags flags;
-
- /* We ignore configure requests while the user is moving/resizing
- * the window, since these represent the app sucking and fighting
- * the user, most likely due to a bug in the app (e.g. pfaedit
- * seemed to do this)
- *
- * Still have to do the ConfigureNotify and all, but pretend the
- * app asked for the current size/position instead of the new one.
- */
- in_grab_op = FALSE;
- if (window->display->grab_op != META_GRAB_OP_NONE &&
- window == window->display->grab_window)
- {
- switch (window->display->grab_op)
- {
- case META_GRAB_OP_MOVING:
- case META_GRAB_OP_RESIZING_SE:
- case META_GRAB_OP_RESIZING_S:
- case META_GRAB_OP_RESIZING_SW:
- case META_GRAB_OP_RESIZING_N:
- case META_GRAB_OP_RESIZING_NE:
- case META_GRAB_OP_RESIZING_NW:
- case META_GRAB_OP_RESIZING_W:
- case META_GRAB_OP_RESIZING_E:
- in_grab_op = TRUE;
- break;
- default:
- break;
- }
- }
-
- /* it's essential to use only the explicitly-set fields,
- * and otherwise use our current up-to-date position.
- *
- * Otherwise you get spurious position changes when the app changes
- * size, for example, if window->rect is not in sync with the
- * server-side position in effect when the configure request was
- * generated.
- */
- meta_window_get_gravity_position (window,
- gravity,
- &x, &y);
-
- allow_position_change = FALSE;
-
- if (meta_prefs_get_disable_workarounds ())
- {
- if (window->type == META_WINDOW_DIALOG ||
- window->type == META_WINDOW_MODAL_DIALOG ||
- window->type == META_WINDOW_SPLASHSCREEN)
- ; /* No position change for these */
- else if ((window->size_hints.flags & PPosition) ||
- /* USPosition is just stale if window is placed;
- * no --geometry involved here.
- */
- ((window->size_hints.flags & USPosition) &&
- !window->placed))
- allow_position_change = TRUE;
- }
- else
- {
- allow_position_change = TRUE;
- }
-
- if (in_grab_op)
- allow_position_change = FALSE;
-
- if (allow_position_change)
- {
- if (value_mask & CWX)
- x = new_x;
- if (value_mask & CWY)
- y = new_y;
- if (value_mask & (CWX | CWY))
- {
- /* Once manually positioned, windows shouldn't be placed
- * by the window manager.
- */
- window->placed = TRUE;
- }
- }
- else
- {
- meta_topic (META_DEBUG_GEOMETRY,
- "Not allowing position change for window %s PPosition 0x%lx USPosition 0x%lx type %u\n",
- window->desc, window->size_hints.flags & PPosition,
- window->size_hints.flags & USPosition,
- window->type);
- }
-
- width = window->rect.width;
- height = window->rect.height;
- if (!in_grab_op)
- {
- if (value_mask & CWWidth)
- width = new_width;
-
- if (value_mask & CWHeight)
- height = new_height;
- }
-
- /* ICCCM 4.1.5 */
-
- /* We're ignoring the value_mask here, since sizes
- * not in the mask will be the current window geometry.
- */
- window->size_hints.x = x;
- window->size_hints.y = y;
- window->size_hints.width = width;
- window->size_hints.height = height;
-
- /* NOTE: We consider ConfigureRequests to be "user" actions in one
- * way, but not in another. Explanation of the two cases are in the
- * next two big comments.
- */
-
- /* The constraints code allows user actions to move windows
- * offscreen, etc., and configure request actions would often send
- * windows offscreen when users don't want it if not constrained
- * (e.g. hitting a dropdown triangle in a fileselector to show more
- * options, which makes the window bigger). Thus we do not set
- * META_IS_USER_ACTION in flags to the
- * meta_window_move_resize_internal() call.
- */
- flags = META_IS_CONFIGURE_REQUEST;
- if (value_mask & (CWX | CWY))
- flags |= META_IS_MOVE_ACTION;
- if (value_mask & (CWWidth | CWHeight))
- flags |= META_IS_RESIZE_ACTION;
-
- if (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION))
- meta_window_move_resize_internal (window,
- flags,
- gravity,
- x,
- y,
- width,
- height);
-
- /* window->user_rect exists to allow "snapping-back" the window if a
- * new strut is set (causing the window to move) and then the strut
- * is later removed without the user moving the window in the
- * interim. We'd like to "snap-back" to the position specified by
- * ConfigureRequest events (at least the constrained version of the
- * ConfigureRequest, since that is guaranteed to be onscreen) so we
- * set user_rect here.
- *
- * See also bug 426519.
- */
- save_user_window_placement (window);
-}
-
-gboolean
-meta_window_configure_request (MetaWindow *window,
- XEvent *event)
-{
- /* Note that x, y is the corner of the window border,
- * and width, height is the size of the window inside
- * its border, but that we always deny border requests
- * and give windows a border of 0. But we save the
- * requested border here.
- */
- if (event->xconfigurerequest.value_mask & CWBorderWidth)
- window->border_width = event->xconfigurerequest.border_width;
-
- meta_window_move_resize_request(window,
- event->xconfigurerequest.value_mask,
- window->size_hints.win_gravity,
- event->xconfigurerequest.x,
- event->xconfigurerequest.y,
- event->xconfigurerequest.width,
- event->xconfigurerequest.height);
-
- /* Handle stacking. We only handle raises/lowers, mostly because
- * stack.c really can't deal with anything else. I guess we'll fix
- * that if a client turns up that really requires it. Only a very
- * few clients even require the raise/lower (and in fact all client
- * attempts to deal with stacking order are essentially broken,
- * since they have no idea what other clients are involved or how
- * the stack looks).
- *
- * I'm pretty sure no interesting client uses TopIf, BottomIf, or
- * Opposite anyway, so the only possible missing thing is
- * Above/Below with a sibling set. For now we just pretend there's
- * never a sibling set and always do the full raise/lower instead of
- * the raise-just-above/below-sibling.
- */
- if (event->xconfigurerequest.value_mask & CWStackMode)
- {
- MetaWindow *active_window;
- active_window = window->display->expected_focus_window;
- if (meta_prefs_get_disable_workarounds () ||
- !meta_prefs_get_raise_on_click ())
- {
- meta_topic (META_DEBUG_STACK,
- "%s sent an xconfigure stacking request; this is "
- "broken behavior and the request is being ignored.\n",
- window->desc);
- }
- else if (active_window &&
- !meta_window_same_application (window, active_window) &&
- XSERVER_TIME_IS_BEFORE (window->net_wm_user_time,
- active_window->net_wm_user_time))
- {
- meta_topic (META_DEBUG_STACK,
- "Ignoring xconfigure stacking request from %s (with "
- "user_time %u); currently active application is %s (with "
- "user_time %u).\n",
- window->desc,
- window->net_wm_user_time,
- active_window->desc,
- active_window->net_wm_user_time);
- if (event->xconfigurerequest.detail == Above)
- meta_window_set_demands_attention(window);
- }
- else
- {
- switch (event->xconfigurerequest.detail)
- {
- case Above:
- meta_window_raise (window);
- break;
- case Below:
- meta_window_lower (window);
- break;
- case TopIf:
- case BottomIf:
- case Opposite:
- break;
- }
- }
- }
-
- return TRUE;
-}
-
-gboolean
-meta_window_property_notify (MetaWindow *window,
- XEvent *event)
-{
- return process_property_notify (window, &event->xproperty);
-}
-
-#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
-#define _NET_WM_MOVERESIZE_SIZE_TOP 1
-#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
-#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
-#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
-#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
-#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
-#define _NET_WM_MOVERESIZE_SIZE_LEFT 7
-#define _NET_WM_MOVERESIZE_MOVE 8
-#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD 9
-#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10
-
-gboolean
-meta_window_client_message (MetaWindow *window,
- XEvent *event)
-{
- MetaDisplay *display;
-
- display = window->display;
-
- if (event->xclient.message_type ==
- display->atom__NET_CLOSE_WINDOW)
- {
- guint32 timestamp;
-
- if (event->xclient.data.l[0] != 0)
- timestamp = event->xclient.data.l[0];
- else
- {
- meta_warning ("Receiving a NET_CLOSE_WINDOW message for %s without "
- "a timestamp! This means some buggy (outdated) "
- "application is on the loose!\n",
- window->desc);
- timestamp = meta_display_get_current_time (window->display);
- }
-
- meta_window_delete (window, timestamp);
-
- return TRUE;
- }
- else if (event->xclient.message_type ==
- display->atom__NET_WM_DESKTOP)
- {
- int space;
- MetaWorkspace *workspace;
-
- space = event->xclient.data.l[0];
-
- meta_verbose ("Request to move %s to workspace %d\n",
- window->desc, space);
-
- workspace =
- meta_screen_get_workspace_by_index (window->screen,
- space);
-
- if (workspace)
- {
- if (window->on_all_workspaces)
- meta_window_unstick (window);
- meta_window_change_workspace (window, workspace);
- }
- else if (space == (int) 0xFFFFFFFF)
- {
- meta_window_stick (window);
- }
- else
- {
- meta_verbose ("No such workspace %d for screen\n", space);
- }
-
- meta_verbose ("Window %s now on_all_workspaces = %d\n",
- window->desc, window->on_all_workspaces);
-
- return TRUE;
- }
- else if (event->xclient.message_type ==
- display->atom__NET_WM_STATE)
- {
- gulong action;
- Atom first;
- Atom second;
-
- action = event->xclient.data.l[0];
- first = event->xclient.data.l[1];
- second = event->xclient.data.l[2];
-
- if (meta_is_verbose ())
- {
- char *str1;
- char *str2;
-
- meta_error_trap_push_with_return (display);
- str1 = XGetAtomName (display->xdisplay, first);
- if (meta_error_trap_pop_with_return (display, TRUE) != Success)
- str1 = NULL;
-
- meta_error_trap_push_with_return (display);
- str2 = XGetAtomName (display->xdisplay, second);
- if (meta_error_trap_pop_with_return (display, TRUE) != Success)
- str2 = NULL;
-
- meta_verbose ("Request to change _NET_WM_STATE action %lu atom1: %s atom2: %s\n",
- action,
- str1 ? str1 : "(unknown)",
- str2 ? str2 : "(unknown)");
-
- meta_XFree (str1);
- meta_XFree (str2);
- }
-
- if (first == display->atom__NET_WM_STATE_SHADED ||
- second == display->atom__NET_WM_STATE_SHADED)
- {
- gboolean shade;
- guint32 timestamp;
-
- /* Stupid protocol has no timestamp; of course, shading
- * sucks anyway so who really cares that we're forced to do
- * a roundtrip here?
- */
- timestamp = meta_display_get_current_time_roundtrip (window->display);
-
- shade = (action == _NET_WM_STATE_ADD ||
- (action == _NET_WM_STATE_TOGGLE && !window->shaded));
- if (shade && window->has_shade_func)
- meta_window_shade (window, timestamp);
- else
- meta_window_unshade (window, timestamp);
- }
-
- if (first == display->atom__NET_WM_STATE_FULLSCREEN ||
- second == display->atom__NET_WM_STATE_FULLSCREEN)
- {
- gboolean make_fullscreen;
-
- make_fullscreen = (action == _NET_WM_STATE_ADD ||
- (action == _NET_WM_STATE_TOGGLE && !window->fullscreen));
- if (make_fullscreen && window->has_fullscreen_func)
- meta_window_make_fullscreen (window);
- else
- meta_window_unmake_fullscreen (window);
- }
-
- if (first == display->atom__NET_WM_STATE_MAXIMIZED_HORZ ||
- second == display->atom__NET_WM_STATE_MAXIMIZED_HORZ)
- {
- gboolean max;
-
- max = (action == _NET_WM_STATE_ADD ||
- (action == _NET_WM_STATE_TOGGLE &&
- !window->maximized_horizontally));
- if (max && window->has_maximize_func)
- {
- if (meta_prefs_get_raise_on_click ())
- meta_window_raise (window);
- meta_window_maximize (window, META_MAXIMIZE_HORIZONTAL);
- }
- else
- {
- if (meta_prefs_get_raise_on_click ())
- meta_window_raise (window);
- meta_window_unmaximize (window, META_MAXIMIZE_HORIZONTAL);
- }
- }
-
- if (first == display->atom__NET_WM_STATE_MAXIMIZED_VERT ||
- second == display->atom__NET_WM_STATE_MAXIMIZED_VERT)
- {
- gboolean max;
-
- max = (action == _NET_WM_STATE_ADD ||
- (action == _NET_WM_STATE_TOGGLE &&
- !window->maximized_vertically));
- if (max && window->has_maximize_func)
- {
- if (meta_prefs_get_raise_on_click ())
- meta_window_raise (window);
- meta_window_maximize (window, META_MAXIMIZE_VERTICAL);
- }
- else
- {
- if (meta_prefs_get_raise_on_click ())
- meta_window_raise (window);
- meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL);
- }
- }
-
- if (first == display->atom__NET_WM_STATE_MODAL ||
- second == display->atom__NET_WM_STATE_MODAL)
- {
- window->wm_state_modal =
- (action == _NET_WM_STATE_ADD) ||
- (action == _NET_WM_STATE_TOGGLE && !window->wm_state_modal);
-
- recalc_window_type (window);
- meta_window_queue(window, META_QUEUE_MOVE_RESIZE);
- }
-
- if (first == display->atom__NET_WM_STATE_SKIP_PAGER ||
- second == display->atom__NET_WM_STATE_SKIP_PAGER)
- {
- window->wm_state_skip_pager =
- (action == _NET_WM_STATE_ADD) ||
- (action == _NET_WM_STATE_TOGGLE && !window->skip_pager);
-
- recalc_window_features (window);
- set_net_wm_state (window);
- }
-
- if (first == display->atom__NET_WM_STATE_SKIP_TASKBAR ||
- second == display->atom__NET_WM_STATE_SKIP_TASKBAR)
- {
- window->wm_state_skip_taskbar =
- (action == _NET_WM_STATE_ADD) ||
- (action == _NET_WM_STATE_TOGGLE && !window->skip_taskbar);
-
- recalc_window_features (window);
- set_net_wm_state (window);
- }
-
- if (first == display->atom__NET_WM_STATE_ABOVE ||
- second == display->atom__NET_WM_STATE_ABOVE)
- {
- window->wm_state_above =
- (action == _NET_WM_STATE_ADD) ||
- (action == _NET_WM_STATE_TOGGLE && !window->wm_state_above);
-
- meta_window_update_layer (window);
- set_net_wm_state (window);
- }
-
- if (first == display->atom__NET_WM_STATE_BELOW ||
- second == display->atom__NET_WM_STATE_BELOW)
- {
- window->wm_state_below =
- (action == _NET_WM_STATE_ADD) ||
- (action == _NET_WM_STATE_TOGGLE && !window->wm_state_below);
-
- meta_window_update_layer (window);
- set_net_wm_state (window);
- }
-
- if (first == display->atom__NET_WM_STATE_DEMANDS_ATTENTION ||
- second == display->atom__NET_WM_STATE_DEMANDS_ATTENTION)
- {
- if ((action == _NET_WM_STATE_ADD) ||
- (action == _NET_WM_STATE_TOGGLE && !window->wm_state_demands_attention))
- meta_window_set_demands_attention (window);
- else
- meta_window_unset_demands_attention (window);
- }
-
- if (first == display->atom__NET_WM_STATE_STICKY ||
- second == display->atom__NET_WM_STATE_STICKY)
- {
- if ((action == _NET_WM_STATE_ADD) ||
- (action == _NET_WM_STATE_TOGGLE && !window->on_all_workspaces))
- meta_window_stick (window);
- else
- meta_window_unstick (window);
- }
-
- return TRUE;
- }
- else if (event->xclient.message_type ==
- display->atom_WM_CHANGE_STATE)
- {
- meta_verbose ("WM_CHANGE_STATE client message, state: %ld\n",
- event->xclient.data.l[0]);
- if (event->xclient.data.l[0] == IconicState &&
- window->has_minimize_func)
- meta_window_minimize (window);
-
- return TRUE;
- }
- else if (event->xclient.message_type ==
- display->atom__NET_WM_MOVERESIZE)
- {
- int x_root;
- int y_root;
- int action;
- MetaGrabOp op;
- int button;
- guint32 timestamp;
-
- /* _NET_WM_MOVERESIZE messages are almost certainly going to come from
- * clients when users click on the fake "frame" that the client has,
- * thus we should also treat such messages as though it were a
- * "frame action".
- */
- gboolean const frame_action = TRUE;
-
- x_root = event->xclient.data.l[0];
- y_root = event->xclient.data.l[1];
- action = event->xclient.data.l[2];
- button = event->xclient.data.l[3];
-
- /* FIXME: What a braindead protocol; no timestamp?!? */
- timestamp = meta_display_get_current_time_roundtrip (display);
- meta_warning ("Received a _NET_WM_MOVERESIZE message for %s; these "
- "messages lack timestamps and therefore suck.\n",
- window->desc);
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Received _NET_WM_MOVERESIZE message on %s, %d,%d action = %d, button %d\n",
- window->desc,
- x_root, y_root, action, button);
-
- op = META_GRAB_OP_NONE;
- switch (action)
- {
- case _NET_WM_MOVERESIZE_SIZE_TOPLEFT:
- op = META_GRAB_OP_RESIZING_NW;
- break;
- case _NET_WM_MOVERESIZE_SIZE_TOP:
- op = META_GRAB_OP_RESIZING_N;
- break;
- case _NET_WM_MOVERESIZE_SIZE_TOPRIGHT:
- op = META_GRAB_OP_RESIZING_NE;
- break;
- case _NET_WM_MOVERESIZE_SIZE_RIGHT:
- op = META_GRAB_OP_RESIZING_E;
- break;
- case _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT:
- op = META_GRAB_OP_RESIZING_SE;
- break;
- case _NET_WM_MOVERESIZE_SIZE_BOTTOM:
- op = META_GRAB_OP_RESIZING_S;
- break;
- case _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT:
- op = META_GRAB_OP_RESIZING_SW;
- break;
- case _NET_WM_MOVERESIZE_SIZE_LEFT:
- op = META_GRAB_OP_RESIZING_W;
- break;
- case _NET_WM_MOVERESIZE_MOVE:
- op = META_GRAB_OP_MOVING;
- break;
- case _NET_WM_MOVERESIZE_SIZE_KEYBOARD:
- op = META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN;
- break;
- case _NET_WM_MOVERESIZE_MOVE_KEYBOARD:
- op = META_GRAB_OP_KEYBOARD_MOVING;
- break;
- default:
- break;
- }
-
- if (op != META_GRAB_OP_NONE &&
- ((window->has_move_func && op == META_GRAB_OP_KEYBOARD_MOVING) ||
- (window->has_resize_func && op == META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN)))
- {
- meta_window_begin_grab_op (window, op, frame_action, timestamp);
- }
- else if (op != META_GRAB_OP_NONE &&
- ((window->has_move_func && op == META_GRAB_OP_MOVING) ||
- (window->has_resize_func &&
- (op != META_GRAB_OP_MOVING &&
- op != META_GRAB_OP_KEYBOARD_MOVING))))
- {
- /*
- * the button SHOULD already be included in the message
- */
- if (button == 0)
- {
- int x, y, query_root_x, query_root_y;
- Window root, child;
- guint mask;
-
- /* The race conditions in this _NET_WM_MOVERESIZE thing
- * are mind-boggling
- */
- mask = 0;
- meta_error_trap_push (window->display);
- XQueryPointer (window->display->xdisplay,
- window->xwindow,
- &root, &child,
- &query_root_x, &query_root_y,
- &x, &y,
- &mask);
- meta_error_trap_pop (window->display, TRUE);
-
- if (mask & Button1Mask)
- button = 1;
- else if (mask & Button2Mask)
- button = 2;
- else if (mask & Button3Mask)
- button = 3;
- else
- button = 0;
- }
-
- if (button != 0)
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Beginning move/resize with button = %d\n", button);
- meta_display_begin_grab_op (window->display,
- window->screen,
- window,
- op,
- FALSE,
- frame_action,
- button, 0,
- timestamp,
- x_root,
- y_root);
- }
- }
-
- return TRUE;
- }
- else if (event->xclient.message_type ==
- display->atom__NET_MOVERESIZE_WINDOW)
- {
- int gravity, source;
- guint value_mask;
-
- gravity = (event->xclient.data.l[0] & 0xff);
- value_mask = (event->xclient.data.l[0] & 0xf00) >> 8;
- source = (event->xclient.data.l[0] & 0xf000) >> 12;
-
- if (gravity == 0)
- gravity = window->size_hints.win_gravity;
-
- meta_window_move_resize_request(window,
- value_mask,
- gravity,
- event->xclient.data.l[1], /* x */
- event->xclient.data.l[2], /* y */
- event->xclient.data.l[3], /* width */
- event->xclient.data.l[4]); /* height */
- }
- else if (event->xclient.message_type ==
- display->atom__NET_ACTIVE_WINDOW)
- {
- MetaClientType source_indication;
- guint32 timestamp;
-
- meta_verbose ("_NET_ACTIVE_WINDOW request for window '%s', activating\n",
- window->desc);
-
- source_indication = event->xclient.data.l[0];
- timestamp = event->xclient.data.l[1];
-
- if (source_indication > META_CLIENT_TYPE_MAX_RECOGNIZED)
- source_indication = META_CLIENT_TYPE_UNKNOWN;
-
- if (timestamp == 0)
- {
- /* Client using older EWMH _NET_ACTIVE_WINDOW without a timestamp */
- meta_warning ("Buggy client sent a _NET_ACTIVE_WINDOW message with a "
- "timestamp of 0 for %s\n",
- window->desc);
- timestamp = meta_display_get_current_time (display);
- }
-
- window_activate (window, timestamp, source_indication, NULL);
- return TRUE;
- }
- else if (event->xclient.message_type ==
- display->atom__NET_WM_FULLSCREEN_MONITORS)
- {
- MetaClientType source_indication;
- gulong top, bottom, left, right;
-
- meta_verbose ("_NET_WM_FULLSCREEN_MONITORS request for window '%s'\n",
- window->desc);
-
- top = event->xclient.data.l[0];
- bottom = event->xclient.data.l[1];
- left = event->xclient.data.l[2];
- right = event->xclient.data.l[3];
- source_indication = event->xclient.data.l[4];
-
- meta_window_update_fullscreen_monitors (window, top, bottom, left, right);
- }
-
- return FALSE;
-}
-
-gboolean
-meta_window_notify_focus (MetaWindow *window,
- XEvent *event)
-{
- /* note the event can be on either the window or the frame,
- * we focus the frame for shaded windows
- */
-
- /* The event can be FocusIn, FocusOut, or UnmapNotify.
- * On UnmapNotify we have to pretend it's focus out,
- * because we won't get a focus out if it occurs, apparently.
- */
-
- /* We ignore grabs, though this is questionable.
- * It may be better to increase the intelligence of
- * the focus window tracking.
- *
- * The problem is that keybindings for windows are done with
- * XGrabKey, which means focus_window disappears and the front of
- * the MRU list gets confused from what the user expects once a
- * keybinding is used.
- */
- meta_topic (META_DEBUG_FOCUS,
- "Focus %s event received on %s 0x%lx (%s) "
- "mode %s detail %s\n",
- event->type == FocusIn ? "in" :
- event->type == FocusOut ? "out" :
- event->type == UnmapNotify ? "unmap" :
- "???",
- window->desc, event->xany.window,
- event->xany.window == window->xwindow ?
- "client window" :
- (window->frame && event->xany.window == window->frame->xwindow) ?
- "frame window" :
- "unknown window",
- event->type != UnmapNotify ?
- meta_event_mode_to_string (event->xfocus.mode) : "n/a",
- event->type != UnmapNotify ?
- meta_event_detail_to_string (event->xfocus.detail) : "n/a");
-
- /* FIXME our pointer tracking is broken; see how
- * gtk+/gdk/x11/gdkevents-x11.c or XFree86/xc/programs/xterm/misc.c
- * handle it for the correct way. In brief you need to track
- * pointer focus and regular focus, and handle EnterNotify in
- * PointerRoot mode with no window manager. However as noted above,
- * accurate focus tracking will break things because we want to keep
- * windows "focused" when using keybindings on them, and also we
- * sometimes "focus" a window by focusing its frame or
- * no_focus_window; so this all needs rethinking massively.
- *
- * My suggestion is to change it so that we clearly separate
- * actual keyboard focus tracking using the xterm algorithm,
- * and metacity's "pretend" focus window, and go through all
- * the code and decide which one should be used in each place;
- * a hard bit is deciding on a policy for that.
- *
- * http://bugzilla.gnome.org/show_bug.cgi?id=90382
- */
-
- if ((event->type == FocusIn ||
- event->type == FocusOut) &&
- (event->xfocus.mode == NotifyGrab ||
- event->xfocus.mode == NotifyUngrab ||
- /* From WindowMaker, ignore all funky pointer root events */
- event->xfocus.detail > NotifyNonlinearVirtual))
- {
- meta_topic (META_DEBUG_FOCUS,
- "Ignoring focus event generated by a grab or other weirdness\n");
- return TRUE;
- }
-
- if (event->type == FocusIn)
- {
- if (window != window->display->focus_window)
- {
- meta_topic (META_DEBUG_FOCUS,
- "* Focus --> %s\n", window->desc);
- window->display->focus_window = window;
- window->has_focus = TRUE;
- meta_compositor_set_active_window (window->display->compositor,
- window->screen, window);
-
- /* Move to the front of the focusing workspace's MRU list.
- * We should only be "removing" it from the MRU list if it's
- * not already there. Note that it's possible that we might
- * be processing this FocusIn after we've changed to a
- * different workspace; we should therefore update the MRU
- * list only if the window is actually on the active
- * workspace.
- */
- if (window->screen->active_workspace &&
- meta_window_located_on_workspace (window,
- window->screen->active_workspace))
- {
- GList* link;
- link = g_list_find (window->screen->active_workspace->mru_list,
- window);
- g_assert (link);
-
- window->screen->active_workspace->mru_list =
- g_list_remove_link (window->screen->active_workspace->mru_list,
- link);
- g_list_free (link);
-
- window->screen->active_workspace->mru_list =
- g_list_prepend (window->screen->active_workspace->mru_list,
- window);
- }
-
- if (window->frame)
- meta_frame_queue_draw (window->frame);
-
- meta_error_trap_push (window->display);
- XInstallColormap (window->display->xdisplay,
- window->colormap);
- meta_error_trap_pop (window->display, FALSE);
-
- /* move into FOCUSED_WINDOW layer */
- meta_window_update_layer (window);
-
- /* Ungrab click to focus button since the sync grab can interfere
- * with some things you might do inside the focused window, by
- * causing the client to get funky enter/leave events.
- *
- * The reason we usually have a passive grab on the window is
- * so that we can intercept clicks and raise the window in
- * response. For click-to-focus we don't need that since the
- * focused window is already raised. When raise_on_click is
- * FALSE we also don't need that since we don't do anything
- * when the window is clicked.
- *
- * There is dicussion in bugs 102209, 115072, and 461577
- */
- if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK ||
- !meta_prefs_get_raise_on_click())
- meta_display_ungrab_focus_window_button (window->display, window);
- }
- }
- else if (event->type == FocusOut ||
- event->type == UnmapNotify)
- {
- if (event->type == FocusOut &&
- event->xfocus.detail == NotifyInferior)
- {
- /* This event means the client moved focus to a subwindow */
- meta_topic (META_DEBUG_FOCUS,
- "Ignoring focus out on %s with NotifyInferior\n",
- window->desc);
- return TRUE;
- }
-
- if (window == window->display->focus_window)
- {
- meta_topic (META_DEBUG_FOCUS,
- "%s is now the previous focus window due to being focused out or unmapped\n",
- window->desc);
-
- meta_topic (META_DEBUG_FOCUS,
- "* Focus --> NULL (was %s)\n", window->desc);
-
- window->display->focus_window = NULL;
- window->has_focus = FALSE;
- if (window->frame)
- meta_frame_queue_draw (window->frame);
-
- meta_compositor_set_active_window (window->display->compositor,
- window->screen, NULL);
-
- meta_error_trap_push (window->display);
- XUninstallColormap (window->display->xdisplay,
- window->colormap);
- meta_error_trap_pop (window->display, FALSE);
-
- /* move out of FOCUSED_WINDOW layer */
- meta_window_update_layer (window);
-
- /* Re-grab for click to focus and raise-on-click, if necessary */
- if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK ||
- !meta_prefs_get_raise_on_click ())
- meta_display_grab_focus_window_button (window->display, window);
- }
- }
-
- /* Now set _NET_ACTIVE_WINDOW hint */
- meta_display_update_active_window_hint (window->display);
-
- return FALSE;
-}
-
-static gboolean
-process_property_notify (MetaWindow *window,
- XPropertyEvent *event)
-{
- /* First, property notifies to ignore because we shouldn't honor
- * new values
- */
- if (event->atom == window->display->atom__NET_WM_STATE)
- {
- meta_verbose ("Property notify on %s for _NET_WM_STATE, ignoring (we should be the one who set the property in the first place)\n",
- window->desc);
- return TRUE;
- }
-
- /* Second, property notifies we want to use.
- * FIXME once we move entirely to the window-props.h framework, we
- * can just call reload on the property in the event and get rid of
- * this if-else chain.
- */
-
- if (meta_is_verbose ()) /* avoid looking up the name if we don't have to */
- {
- char *property_name = XGetAtomName (window->display->xdisplay,
- event->atom);
-
- meta_verbose ("Property notify on %s for %s\n",
- window->desc, property_name);
- XFree (property_name);
- }
-
- if (event->atom == XA_WM_NAME)
- {
- /* don't bother reloading WM_NAME if using _NET_WM_NAME already */
- if (!window->using_net_wm_name)
- meta_window_reload_property (window, XA_WM_NAME);
- }
- else if (event->atom == window->display->atom__NET_WM_NAME)
- {
- meta_window_reload_property (window, window->display->atom__NET_WM_NAME);
-
- /* if _NET_WM_NAME was unset, reload WM_NAME */
- if (!window->using_net_wm_name)
- meta_window_reload_property (window, XA_WM_NAME);
- }
- else if (event->atom == XA_WM_ICON_NAME)
- {
- /* don't bother reloading WM_ICON_NAME if using _NET_WM_ICON_NAME already */
- if (!window->using_net_wm_icon_name)
- meta_window_reload_property (window, XA_WM_ICON_NAME);
- }
- else if (event->atom == window->display->atom__NET_WM_ICON_NAME)
- {
- meta_window_reload_property (window, window->display->atom__NET_WM_ICON_NAME);
-
- /* if _NET_WM_ICON_NAME was unset, reload WM_ICON_NAME */
- if (!window->using_net_wm_icon_name)
- meta_window_reload_property (window, XA_WM_ICON_NAME);
- }
- else if (event->atom == XA_WM_NORMAL_HINTS)
- {
- meta_window_reload_property (window, XA_WM_NORMAL_HINTS);
-
- /* See if we need to constrain current size */
- meta_window_queue(window, META_QUEUE_MOVE_RESIZE);
- }
- else if (event->atom == window->display->atom_WM_PROTOCOLS)
- {
- meta_window_reload_property (window, window->display->atom_WM_PROTOCOLS);
- }
- else if (event->atom == XA_WM_HINTS)
- {
- meta_window_reload_property (window, XA_WM_HINTS);
- }
- else if (event->atom == window->display->atom__MOTIF_WM_HINTS)
- {
- meta_window_reload_property (window,
- window->display->atom__MOTIF_WM_HINTS);
- }
- else if (event->atom == XA_WM_CLASS)
- {
- meta_window_reload_property (window, XA_WM_CLASS);
- }
- else if (event->atom == XA_WM_TRANSIENT_FOR)
- {
- meta_window_reload_property (window, XA_WM_TRANSIENT_FOR);
- }
- else if (event->atom ==
- window->display->atom_WM_WINDOW_ROLE)
- {
- update_role (window);
- }
- else if (event->atom ==
- window->display->atom_WM_CLIENT_LEADER ||
- event->atom ==
- window->display->atom_SM_CLIENT_ID)
- {
- meta_warning ("Broken client! Window %s changed client leader window or SM client ID\n", window->desc);
- }
- else if (event->atom ==
- window->display->atom__NET_WM_WINDOW_TYPE)
- {
- update_net_wm_type (window);
- }
- else if (event->atom == window->display->atom__NET_WM_ICON)
- {
- meta_icon_cache_property_changed (&window->icon_cache,
- window->display,
- event->atom);
- meta_window_queue(window, META_QUEUE_UPDATE_ICON);
- }
- else if (event->atom == window->display->atom__KWM_WIN_ICON)
- {
- meta_icon_cache_property_changed (&window->icon_cache,
- window->display,
- event->atom);
- meta_window_queue(window, META_QUEUE_UPDATE_ICON);
- }
- else if ((event->atom == window->display->atom__NET_WM_STRUT) ||
- (event->atom == window->display->atom__NET_WM_STRUT_PARTIAL))
- {
- meta_window_update_struts (window);
- }
- else if (event->atom == window->display->atom__NET_STARTUP_ID)
- {
- meta_window_reload_property (window,
- window->display->atom__NET_STARTUP_ID);
- }
- else if (event->atom == window->display->atom__NET_WM_SYNC_REQUEST_COUNTER)
- {
- meta_window_reload_property (window,
- window->display->atom__NET_WM_SYNC_REQUEST_COUNTER);
- }
- else if (event->atom == window->display->atom__NET_WM_USER_TIME)
- {
- Window xid;
- Atom atom__NET_WM_USER_TIME;
-
- atom__NET_WM_USER_TIME = window->display->atom__NET_WM_USER_TIME;
- if (window->user_time_window)
- xid = window->user_time_window;
- else
- xid = window->xwindow;
- meta_window_reload_property_from_xwindow (window,
- xid,
- atom__NET_WM_USER_TIME);
- }
-
- return TRUE;
-}
-
-static void
-send_configure_notify (MetaWindow *window)
-{
- XEvent event;
-
- /* from twm */
-
- event.type = ConfigureNotify;
- event.xconfigure.display = window->display->xdisplay;
- event.xconfigure.event = window->xwindow;
- event.xconfigure.window = window->xwindow;
- event.xconfigure.x = window->rect.x - window->border_width;
- event.xconfigure.y = window->rect.y - window->border_width;
- if (window->frame)
- {
- if (window->withdrawn)
- {
- /* WARNING: x & y need to be set to whatever the XReparentWindow
- * call in meta_window_destroy_frame will use so that the window
- * has the right coordinates. Currently, that means no change to
- * x & y.
- */
- }
- else
- {
- /* Need to be in root window coordinates */
- event.xconfigure.x += window->frame->rect.x;
- event.xconfigure.y += window->frame->rect.y;
- }
- }
- event.xconfigure.width = window->rect.width;
- event.xconfigure.height = window->rect.height;
- event.xconfigure.border_width = window->border_width; /* requested not actual */
- event.xconfigure.above = None; /* FIXME */
- event.xconfigure.override_redirect = False;
-
- meta_topic (META_DEBUG_GEOMETRY,
- "Sending synthetic configure notify to %s with x: %d y: %d w: %d h: %d\n",
- window->desc,
- event.xconfigure.x, event.xconfigure.y,
- event.xconfigure.width, event.xconfigure.height);
-
- meta_error_trap_push (window->display);
- XSendEvent (window->display->xdisplay,
- window->xwindow,
- False, StructureNotifyMask, &event);
- meta_error_trap_pop (window->display, FALSE);
-}
-
-gboolean
-meta_window_get_icon_geometry (MetaWindow *window,
- MetaRectangle *rect)
-{
- gulong *geometry = NULL;
- int nitems;
-
- if (meta_prop_get_cardinal_list (window->display,
- window->xwindow,
- window->display->atom__NET_WM_ICON_GEOMETRY,
- &geometry, &nitems))
- {
- if (nitems != 4)
- {
- meta_verbose ("_NET_WM_ICON_GEOMETRY on %s has %d values instead of 4\n",
- window->desc, nitems);
- meta_XFree (geometry);
- return FALSE;
- }
-
- if (rect)
- {
- rect->x = geometry[0];
- rect->y = geometry[1];
- rect->width = geometry[2];
- rect->height = geometry[3];
- }
-
- meta_XFree (geometry);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-static Window
-read_client_leader (MetaDisplay *display,
- Window xwindow)
-{
- Window retval = None;
-
- meta_prop_get_window (display, xwindow,
- display->atom_WM_CLIENT_LEADER,
- &retval);
-
- return retval;
-}
-
-typedef struct
-{
- Window leader;
-} ClientLeaderData;
-
-static gboolean
-find_client_leader_func (MetaWindow *ancestor,
- void *data)
-{
- ClientLeaderData *d;
-
- d = data;
-
- d->leader = read_client_leader (ancestor->display,
- ancestor->xwindow);
-
- /* keep going if no client leader found */
- return d->leader == None;
-}
-
-static void
-update_sm_hints (MetaWindow *window)
-{
- Window leader;
-
- window->xclient_leader = None;
- window->sm_client_id = NULL;
-
- /* If not on the current window, we can get the client
- * leader from transient parents. If we find a client
- * leader, we read the SM_CLIENT_ID from it.
- */
- leader = read_client_leader (window->display, window->xwindow);
- if (leader == None)
- {
- ClientLeaderData d;
- d.leader = None;
- meta_window_foreach_ancestor (window, find_client_leader_func,
- &d);
- leader = d.leader;
- }
-
- if (leader != None)
- {
- char *str;
-
- window->xclient_leader = leader;
-
- if (meta_prop_get_latin1_string (window->display, leader,
- window->display->atom_SM_CLIENT_ID,
- &str))
- {
- window->sm_client_id = g_strdup (str);
- meta_XFree (str);
- }
- }
- else
- {
- meta_verbose ("Didn't find a client leader for %s\n", window->desc);
-
- if (!meta_prefs_get_disable_workarounds ())
- {
- /* Some broken apps (kdelibs fault?) set SM_CLIENT_ID on the app
- * instead of the client leader
- */
- char *str;
-
- str = NULL;
- if (meta_prop_get_latin1_string (window->display, window->xwindow,
- window->display->atom_SM_CLIENT_ID,
- &str))
- {
- if (window->sm_client_id == NULL) /* first time through */
- meta_warning (_("Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER window as specified in the ICCCM.\n"),
- window->desc);
-
- window->sm_client_id = g_strdup (str);
- meta_XFree (str);
- }
- }
- }
-
- meta_verbose ("Window %s client leader: 0x%lx SM_CLIENT_ID: '%s'\n",
- window->desc, window->xclient_leader,
- window->sm_client_id ? window->sm_client_id : "none");
-}
-
-static void
-update_role (MetaWindow *window)
-{
- char *str;
-
- if (window->role)
- g_free (window->role);
- window->role = NULL;
-
- if (meta_prop_get_latin1_string (window->display, window->xwindow,
- window->display->atom_WM_WINDOW_ROLE,
- &str))
- {
- window->role = g_strdup (str);
- meta_XFree (str);
- }
-
- meta_verbose ("Updated role of %s to '%s'\n",
- window->desc, window->role ? window->role : "null");
-}
-
-static void
-update_net_wm_type (MetaWindow *window)
-{
- int n_atoms;
- Atom *atoms;
- int i;
-
- window->type_atom = None;
- n_atoms = 0;
- atoms = NULL;
-
- meta_prop_get_atom_list (window->display, window->xwindow,
- window->display->atom__NET_WM_WINDOW_TYPE,
- &atoms, &n_atoms);
-
- i = 0;
- while (i < n_atoms)
- {
- /* We break as soon as we find one we recognize,
- * supposed to prefer those near the front of the list
- */
- if (atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP ||
- atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DOCK ||
- atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR ||
- atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_MENU ||
- atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG ||
- atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL ||
- atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY ||
- atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH)
- {
- window->type_atom = atoms[i];
- break;
- }
-
- ++i;
- }
-
- meta_XFree (atoms);
-
- if (meta_is_verbose ())
- {
- char *str;
-
- str = NULL;
- if (window->type_atom != None)
- {
- meta_error_trap_push (window->display);
- str = XGetAtomName (window->display->xdisplay, window->type_atom);
- meta_error_trap_pop (window->display, TRUE);
- }
-
- meta_verbose ("Window %s type atom %s\n", window->desc,
- str ? str : "(none)");
-
- if (str)
- meta_XFree (str);
- }
-
- recalc_window_type (window);
-}
-
-static void
-redraw_icon (MetaWindow *window)
-{
- /* We could probably be smart and just redraw the icon here,
- * instead of the whole frame.
- */
- if (window->frame && (window->mapped || window->frame->mapped))
- meta_ui_queue_frame_draw (window->screen->ui, window->frame->xwindow);
-}
-
-void
-meta_window_update_icon_now (MetaWindow *window)
-{
- GdkPixbuf *icon;
- GdkPixbuf *mini_icon;
-
- icon = NULL;
- mini_icon = NULL;
-
- if (meta_read_icons (window->screen,
- window->xwindow,
- &window->icon_cache,
- window->wm_hints_pixmap,
- window->wm_hints_mask,
- &icon,
- META_ICON_WIDTH, META_ICON_HEIGHT,
- &mini_icon,
- META_MINI_ICON_WIDTH,
- META_MINI_ICON_HEIGHT))
- {
- if (window->icon)
- g_object_unref (G_OBJECT (window->icon));
-
- if (window->mini_icon)
- g_object_unref (G_OBJECT (window->mini_icon));
-
- window->icon = icon;
- window->mini_icon = mini_icon;
-
- redraw_icon (window);
- }
-
- g_assert (window->icon);
- g_assert (window->mini_icon);
-}
-
-static gboolean
-idle_update_icon (gpointer data)
-{
- GSList *tmp;
- GSList *copy;
- guint queue_index = GPOINTER_TO_INT (data);
-
- meta_topic (META_DEBUG_GEOMETRY, "Clearing the update_icon queue\n");
-
- /* Work with a copy, for reentrancy. The allowed reentrancy isn't
- * complete; destroying a window while we're in here would result in
- * badness. But it's OK to queue/unqueue update_icons.
- */
- copy = g_slist_copy (queue_pending[queue_index]);
- g_slist_free (queue_pending[queue_index]);
- queue_pending[queue_index] = NULL;
- queue_idle[queue_index] = 0;
-
- destroying_windows_disallowed += 1;
-
- tmp = copy;
- while (tmp != NULL)
- {
- MetaWindow *window;
-
- window = tmp->data;
-
- meta_window_update_icon_now (window);
- window->is_in_queues &= ~META_QUEUE_UPDATE_ICON;
-
- tmp = tmp->next;
- }
-
- g_slist_free (copy);
-
- destroying_windows_disallowed -= 1;
-
- return FALSE;
-}
-
-GList*
-meta_window_get_workspaces (MetaWindow *window)
-{
- if (window->on_all_workspaces)
- return window->screen->workspaces;
- else
- return window->workspace->list_containing_self;
-}
-
-static void
-invalidate_work_areas (MetaWindow *window)
-{
- GList *tmp;
-
- tmp = meta_window_get_workspaces (window);
-
- while (tmp != NULL)
- {
- meta_workspace_invalidate_work_area (tmp->data);
- tmp = tmp->next;
- }
-}
-
-void
-meta_window_update_struts (MetaWindow *window)
-{
- GSList *old_struts;
- GSList *new_struts;
- GSList *old_iter, *new_iter;
- gulong *struts = NULL;
- int nitems;
- gboolean changed;
-
- meta_verbose ("Updating struts for %s\n", window->desc);
-
- old_struts = window->struts;
- new_struts = NULL;
-
- if (meta_prop_get_cardinal_list (window->display,
- window->xwindow,
- window->display->atom__NET_WM_STRUT_PARTIAL,
- &struts, &nitems))
- {
- if (nitems != 12)
- meta_verbose ("_NET_WM_STRUT_PARTIAL on %s has %d values instead "
- "of 12\n",
- window->desc, nitems);
- else
- {
- /* Pull out the strut info for each side in the hint */
- int i;
- for (i=0; i<4; i++)
- {
- MetaStrut *temp;
- int thickness, strut_begin, strut_end;
-
- thickness = struts[i];
- if (thickness == 0)
- continue;
- strut_begin = struts[4+(i*2)];
- strut_end = struts[4+(i*2)+1];
-
- temp = g_new (MetaStrut, 1);
- temp->side = 1 << i; /* See MetaDirection def. Matches nicely, eh? */
- temp->rect = window->screen->rect;
- switch (temp->side)
- {
- case META_SIDE_RIGHT:
- temp->rect.x = BOX_RIGHT(temp->rect) - thickness;
- /* Intentionally fall through without breaking */
- case META_SIDE_LEFT:
- temp->rect.width = thickness;
- temp->rect.y = strut_begin;
- temp->rect.height = strut_end - strut_begin + 1;
- break;
- case META_SIDE_BOTTOM:
- temp->rect.y = BOX_BOTTOM(temp->rect) - thickness;
- /* Intentionally fall through without breaking */
- case META_SIDE_TOP:
- temp->rect.height = thickness;
- temp->rect.x = strut_begin;
- temp->rect.width = strut_end - strut_begin + 1;
- break;
- default:
- g_assert_not_reached ();
- }
-
- new_struts = g_slist_prepend (new_struts, temp);
- }
-
- meta_verbose ("_NET_WM_STRUT_PARTIAL struts %lu %lu %lu %lu for "
- "window %s\n",
- struts[0], struts[1], struts[2], struts[3],
- window->desc);
- }
- meta_XFree (struts);
- }
- else
- {
- meta_verbose ("No _NET_WM_STRUT property for %s\n",
- window->desc);
- }
-
- if (!new_struts &&
- meta_prop_get_cardinal_list (window->display,
- window->xwindow,
- window->display->atom__NET_WM_STRUT,
- &struts, &nitems))
- {
- if (nitems != 4)
- meta_verbose ("_NET_WM_STRUT on %s has %d values instead of 4\n",
- window->desc, nitems);
- else
- {
- /* Pull out the strut info for each side in the hint */
- int i;
- for (i=0; i<4; i++)
- {
- MetaStrut *temp;
- int thickness;
-
- thickness = struts[i];
- if (thickness == 0)
- continue;
-
- temp = g_new (MetaStrut, 1);
- temp->side = 1 << i;
- temp->rect = window->screen->rect;
- switch (temp->side)
- {
- case META_SIDE_RIGHT:
- temp->rect.x = BOX_RIGHT(temp->rect) - thickness;
- /* Intentionally fall through without breaking */
- case META_SIDE_LEFT:
- temp->rect.width = thickness;
- break;
- case META_SIDE_BOTTOM:
- temp->rect.y = BOX_BOTTOM(temp->rect) - thickness;
- /* Intentionally fall through without breaking */
- case META_SIDE_TOP:
- temp->rect.height = thickness;
- break;
- default:
- g_assert_not_reached ();
- }
-
- new_struts = g_slist_prepend (new_struts, temp);
- }
-
- meta_verbose ("_NET_WM_STRUT struts %lu %lu %lu %lu for window %s\n",
- struts[0], struts[1], struts[2], struts[3],
- window->desc);
- }
- meta_XFree (struts);
- }
- else if (!new_struts)
- {
- meta_verbose ("No _NET_WM_STRUT property for %s\n",
- window->desc);
- }
-
- /* Determine whether old_struts and new_struts are the same */
- old_iter = old_struts;
- new_iter = new_struts;
- while (old_iter && new_iter)
- {
- MetaStrut *old_strut = (MetaStrut*) old_iter->data;
- MetaStrut *new_strut = (MetaStrut*) new_iter->data;
-
- if (old_strut->side != new_strut->side ||
- !meta_rectangle_equal (&old_strut->rect, &new_strut->rect))
- break;
-
- old_iter = old_iter->next;
- new_iter = new_iter->next;
- }
- changed = (old_iter != NULL || new_iter != NULL);
-
- /* Update appropriately */
- meta_free_gslist_and_elements (old_struts);
- window->struts = new_struts;
- if (changed)
- {
- meta_topic (META_DEBUG_WORKAREA,
- "Invalidating work areas of window %s due to struts update\n",
- window->desc);
- invalidate_work_areas (window);
- }
- else
- {
- meta_topic (META_DEBUG_WORKAREA,
- "Struts on %s were unchanged\n", window->desc);
- }
-}
-
-void
-meta_window_recalc_window_type (MetaWindow *window)
-{
- recalc_window_type (window);
-}
-
-static void
-recalc_window_type (MetaWindow *window)
-{
- MetaWindowType old_type;
-
- old_type = window->type;
-
- if (window->type_atom != None)
- {
- if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP)
- window->type = META_WINDOW_DESKTOP;
- else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DOCK)
- window->type = META_WINDOW_DOCK;
- else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR)
- window->type = META_WINDOW_TOOLBAR;
- else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_MENU)
- window->type = META_WINDOW_MENU;
- else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG)
- window->type = META_WINDOW_DIALOG;
- else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL)
- window->type = META_WINDOW_NORMAL;
- else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY)
- window->type = META_WINDOW_UTILITY;
- else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH)
- window->type = META_WINDOW_SPLASHSCREEN;
- else
- meta_bug ("Set a type atom for %s that wasn't handled in recalc_window_type\n",
- window->desc);
- }
- else if (window->xtransient_for != None)
- {
- window->type = META_WINDOW_DIALOG;
- }
- else
- {
- window->type = META_WINDOW_NORMAL;
- }
-
- if (window->type == META_WINDOW_DIALOG &&
- window->wm_state_modal)
- window->type = META_WINDOW_MODAL_DIALOG;
-
- meta_verbose ("Calculated type %u for %s, old type %u\n",
- window->type, window->desc, old_type);
-
- if (old_type != window->type)
- {
- recalc_window_features (window);
-
- set_net_wm_state (window);
-
- /* Update frame */
- if (window->decorated)
- meta_window_ensure_frame (window);
- else
- meta_window_destroy_frame (window);
-
- /* update stacking constraints */
- meta_window_update_layer (window);
-
- meta_window_grab_keys (window);
- }
-}
-
-static void
-set_allowed_actions_hint (MetaWindow *window)
-{
-#define MAX_N_ACTIONS 12
- unsigned long data[MAX_N_ACTIONS];
- int i;
-
- i = 0;
- if (window->has_move_func)
- {
- data[i] = window->display->atom__NET_WM_ACTION_MOVE;
- ++i;
- }
- if (window->has_resize_func)
- {
- data[i] = window->display->atom__NET_WM_ACTION_RESIZE;
- ++i;
- }
- if (window->has_fullscreen_func)
- {
- data[i] = window->display->atom__NET_WM_ACTION_FULLSCREEN;
- ++i;
- }
- if (window->has_minimize_func)
- {
- data[i] = window->display->atom__NET_WM_ACTION_MINIMIZE;
- ++i;
- }
- if (window->has_shade_func)
- {
- data[i] = window->display->atom__NET_WM_ACTION_SHADE;
- ++i;
- }
- /* sticky according to EWMH is different from metacity's sticky;
- * metacity doesn't support EWMH sticky
- */
- if (window->has_maximize_func)
- {
- data[i] = window->display->atom__NET_WM_ACTION_MAXIMIZE_HORZ;
- ++i;
- data[i] = window->display->atom__NET_WM_ACTION_MAXIMIZE_VERT;
- ++i;
- }
- /* We always allow this */
- data[i] = window->display->atom__NET_WM_ACTION_CHANGE_DESKTOP;
- ++i;
- if (window->has_close_func)
- {
- data[i] = window->display->atom__NET_WM_ACTION_CLOSE;
- ++i;
- }
-
- /* I guess we always allow above/below operations */
- data[i] = window->display->atom__NET_WM_ACTION_ABOVE;
- ++i;
- data[i] = window->display->atom__NET_WM_ACTION_BELOW;
- ++i;
-
- g_assert (i <= MAX_N_ACTIONS);
-
- meta_verbose ("Setting _NET_WM_ALLOWED_ACTIONS with %d atoms\n", i);
-
- meta_error_trap_push (window->display);
- XChangeProperty (window->display->xdisplay, window->xwindow,
- window->display->atom__NET_WM_ALLOWED_ACTIONS,
- XA_ATOM,
- 32, PropModeReplace, (guchar*) data, i);
- meta_error_trap_pop (window->display, FALSE);
-#undef MAX_N_ACTIONS
-}
-
-void
-meta_window_recalc_features (MetaWindow *window)
-{
- recalc_window_features (window);
-}
-
-static void
-recalc_window_features (MetaWindow *window)
-{
- gboolean old_has_close_func;
- gboolean old_has_minimize_func;
- gboolean old_has_move_func;
- gboolean old_has_resize_func;
- gboolean old_has_shade_func;
- gboolean old_always_sticky;
-
- old_has_close_func = window->has_close_func;
- old_has_minimize_func = window->has_minimize_func;
- old_has_move_func = window->has_move_func;
- old_has_resize_func = window->has_resize_func;
- old_has_shade_func = window->has_shade_func;
- old_always_sticky = window->always_sticky;
-
- /* Use MWM hints initially */
- window->decorated = window->mwm_decorated;
- window->border_only = window->mwm_border_only;
- window->has_close_func = window->mwm_has_close_func;
- window->has_minimize_func = window->mwm_has_minimize_func;
- window->has_maximize_func = window->mwm_has_maximize_func;
- window->has_move_func = window->mwm_has_move_func;
-
- window->has_resize_func = TRUE;
-
- /* If min_size == max_size, then don't allow resize */
- if (window->size_hints.min_width == window->size_hints.max_width &&
- window->size_hints.min_height == window->size_hints.max_height)
- window->has_resize_func = FALSE;
- else if (!window->mwm_has_resize_func)
- {
- /* We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the
- * authoritative source for that info. Some apps such as mplayer or
- * xine disable resize via MWM but not WM_NORMAL_HINTS, but that
- * leads to e.g. us not fullscreening their windows. Apps that set
- * MWM but not WM_NORMAL_HINTS are basically broken. We complain
- * about these apps but make them work.
- */
-
- meta_warning (_("Window %s sets an MWM hint indicating it isn't resizable, but sets min size %d x %d and max size %d x %d; this doesn't make much sense.\n"),
- window->desc,
- window->size_hints.min_width,
- window->size_hints.min_height,
- window->size_hints.max_width,
- window->size_hints.max_height);
- }
-
- window->has_shade_func = TRUE;
- window->has_fullscreen_func = TRUE;
-
- window->always_sticky = FALSE;
-
- /* Semantic category overrides the MWM hints */
- if (window->type == META_WINDOW_TOOLBAR)
- window->decorated = FALSE;
-
- if (window->type == META_WINDOW_DESKTOP ||
- window->type == META_WINDOW_DOCK)
- window->always_sticky = TRUE;
-
- if (window->type == META_WINDOW_DESKTOP ||
- window->type == META_WINDOW_DOCK ||
- window->type == META_WINDOW_SPLASHSCREEN)
- {
- window->decorated = FALSE;
- window->has_close_func = FALSE;
- window->has_shade_func = FALSE;
-
- /* FIXME this keeps panels and things from using
- * NET_WM_MOVERESIZE; the problem is that some
- * panels (edge panels) have fixed possible locations,
- * and others ("floating panels") do not.
- *
- * Perhaps we should require edge panels to explicitly
- * disable movement?
- */
- window->has_move_func = FALSE;
- window->has_resize_func = FALSE;
- }
-
- if (window->type != META_WINDOW_NORMAL)
- {
- window->has_minimize_func = FALSE;
- window->has_maximize_func = FALSE;
- window->has_fullscreen_func = FALSE;
- }
-
- if (!window->has_resize_func)
- {
- window->has_maximize_func = FALSE;
-
- /* don't allow fullscreen if we can't resize, unless the size
- * is entire screen size (kind of broken, because we
- * actually fullscreen to xinerama head size not screen size)
- */
- if (window->size_hints.min_width == window->screen->rect.width &&
- window->size_hints.min_height == window->screen->rect.height)
- ; /* leave fullscreen available */
- else
- window->has_fullscreen_func = FALSE;
- }
-
- /* We leave fullscreen windows decorated, just push the frame outside
- * the screen. This avoids flickering to unparent them.
- *
- * Note that setting has_resize_func = FALSE here must come after the
- * above code that may disable fullscreen, because if the window
- * is not resizable purely due to fullscreen, we don't want to
- * disable fullscreen mode.
- */
- if (window->fullscreen)
- {
- window->has_shade_func = FALSE;
- window->has_move_func = FALSE;
- window->has_resize_func = FALSE;
- window->has_maximize_func = FALSE;
- }
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Window %s fullscreen = %d not resizable, maximizable = %d fullscreenable = %d min size %dx%d max size %dx%d\n",
- window->desc,
- window->fullscreen,
- window->has_maximize_func, window->has_fullscreen_func,
- window->size_hints.min_width,
- window->size_hints.min_height,
- window->size_hints.max_width,
- window->size_hints.max_height);
-
- /* no shading if not decorated */
- if (!window->decorated || window->border_only)
- window->has_shade_func = FALSE;
-
- window->skip_taskbar = FALSE;
- window->skip_pager = FALSE;
-
- if (window->wm_state_skip_taskbar)
- window->skip_taskbar = TRUE;
-
- if (window->wm_state_skip_pager)
- window->skip_pager = TRUE;
-
- switch (window->type)
- {
- /* Force skip taskbar/pager on these window types */
- case META_WINDOW_DESKTOP:
- case META_WINDOW_DOCK:
- case META_WINDOW_TOOLBAR:
- case META_WINDOW_MENU:
- case META_WINDOW_UTILITY:
- case META_WINDOW_SPLASHSCREEN:
- window->skip_taskbar = TRUE;
- window->skip_pager = TRUE;
- break;
-
- case META_WINDOW_DIALOG:
- case META_WINDOW_MODAL_DIALOG:
- /* only skip taskbar if we have a real transient parent */
- if (window->xtransient_for != None &&
- window->xtransient_for != window->screen->xroot)
- window->skip_taskbar = TRUE;
- break;
-
- case META_WINDOW_NORMAL:
- break;
- }
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Window %s decorated = %d border_only = %d has_close = %d has_minimize = %d has_maximize = %d has_move = %d has_shade = %d skip_taskbar = %d skip_pager = %d\n",
- window->desc,
- window->decorated,
- window->border_only,
- window->has_close_func,
- window->has_minimize_func,
- window->has_maximize_func,
- window->has_move_func,
- window->has_shade_func,
- window->skip_taskbar,
- window->skip_pager);
-
- /* FIXME:
- * Lame workaround for recalc_window_features
- * being used overzealously. The fix is to
- * only recalc_window_features when something
- * has actually changed.
- */
- if (window->constructing ||
- old_has_close_func != window->has_close_func ||
- old_has_minimize_func != window->has_minimize_func ||
- old_has_move_func != window->has_move_func ||
- old_has_resize_func != window->has_resize_func ||
- old_has_shade_func != window->has_shade_func ||
- old_always_sticky != window->always_sticky)
- set_allowed_actions_hint (window);
-
- /* FIXME perhaps should ensure if we don't have a shade func,
- * we aren't shaded, etc.
- */
-}
-
-static void
-menu_callback (MetaWindowMenu *menu,
- Display *xdisplay,
- Window client_xwindow,
- guint32 timestamp,
- MetaMenuOp op,
- int workspace_index,
- gpointer data)
-{
- MetaDisplay *display;
- MetaWindow *window;
- MetaWorkspace *workspace;
-
- display = meta_display_for_x_display (xdisplay);
- window = meta_display_lookup_x_window (display, client_xwindow);
- workspace = NULL;
-
- if (window != NULL) /* window can be NULL */
- {
- meta_verbose ("Menu op %u on %s\n", op, window->desc);
-
- /* op can be 0 for none */
- switch (op)
- {
- case META_MENU_OP_DELETE:
- meta_window_delete (window, timestamp);
- break;
-
- case META_MENU_OP_MINIMIZE:
- meta_window_minimize (window);
- break;
-
- case META_MENU_OP_UNMAXIMIZE:
- meta_window_unmaximize (window,
- META_MAXIMIZE_HORIZONTAL |
- META_MAXIMIZE_VERTICAL);
- break;
-
- case META_MENU_OP_MAXIMIZE:
- meta_window_maximize (window,
- META_MAXIMIZE_HORIZONTAL |
- META_MAXIMIZE_VERTICAL);
- break;
-
- case META_MENU_OP_UNSHADE:
- meta_window_unshade (window, timestamp);
- break;
-
- case META_MENU_OP_SHADE:
- meta_window_shade (window, timestamp);
- break;
-
- case META_MENU_OP_MOVE_LEFT:
- workspace = meta_workspace_get_neighbor (window->screen->active_workspace,
- META_MOTION_LEFT);
- break;
-
- case META_MENU_OP_MOVE_RIGHT:
- workspace = meta_workspace_get_neighbor (window->screen->active_workspace,
- META_MOTION_RIGHT);
- break;
-
- case META_MENU_OP_MOVE_UP:
- workspace = meta_workspace_get_neighbor (window->screen->active_workspace,
- META_MOTION_UP);
- break;
-
- case META_MENU_OP_MOVE_DOWN:
- workspace = meta_workspace_get_neighbor (window->screen->active_workspace,
- META_MOTION_DOWN);
- break;
-
- case META_MENU_OP_WORKSPACES:
- workspace = meta_screen_get_workspace_by_index (window->screen,
- workspace_index);
- break;
-
- case META_MENU_OP_STICK:
- meta_window_stick (window);
- break;
-
- case META_MENU_OP_UNSTICK:
- meta_window_unstick (window);
- break;
-
- case META_MENU_OP_ABOVE:
- case META_MENU_OP_UNABOVE:
- if (window->wm_state_above == FALSE)
- meta_window_make_above (window);
- else
- meta_window_unmake_above (window);
- break;
-
- case META_MENU_OP_MOVE:
- meta_window_begin_grab_op (window,
- META_GRAB_OP_KEYBOARD_MOVING,
- TRUE,
- timestamp);
- break;
-
- case META_MENU_OP_RESIZE:
- meta_window_begin_grab_op (window,
- META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN,
- TRUE,
- timestamp);
- break;
-
- case META_MENU_OP_RECOVER:
- meta_window_shove_titlebar_onscreen (window);
- break;
-
- case 0:
- /* nothing */
- break;
-
- default:
- meta_warning (G_STRLOC": Unknown window op\n");
- break;
- }
-
- if (workspace)
- {
- meta_window_change_workspace (window,
- workspace);
-#if 0
- meta_workspace_activate (workspace);
- meta_window_raise (window);
-#endif
- }
- }
- else
- {
- meta_verbose ("Menu callback on nonexistent window\n");
- }
-
- if (display->window_menu == menu)
- {
- display->window_menu = NULL;
- display->window_with_menu = NULL;
- }
-
- meta_ui_window_menu_free (menu);
-}
-
-void
-meta_window_show_menu (MetaWindow *window,
- int root_x,
- int root_y,
- int button,
- guint32 timestamp)
-{
- MetaMenuOp ops;
- MetaMenuOp insensitive;
- MetaWindowMenu *menu;
- MetaWorkspaceLayout layout;
- int n_workspaces;
- gboolean ltr;
-
- if (window->display->window_menu)
- {
- meta_ui_window_menu_free (window->display->window_menu);
- window->display->window_menu = NULL;
- window->display->window_with_menu = NULL;
- }
-
- ops = 0;
- insensitive = 0;
-
- ops |= (META_MENU_OP_DELETE | META_MENU_OP_MINIMIZE | META_MENU_OP_MOVE | META_MENU_OP_RESIZE);
-
- if (!meta_window_titlebar_is_onscreen (window) &&
- window->type != META_WINDOW_DOCK &&
- window->type != META_WINDOW_DESKTOP)
- ops |= META_MENU_OP_RECOVER;
-
- n_workspaces = meta_screen_get_n_workspaces (window->screen);
-
- if (n_workspaces > 1)
- ops |= META_MENU_OP_WORKSPACES;
-
- meta_screen_calc_workspace_layout (window->screen,
- n_workspaces,
- meta_workspace_index ( window->screen->active_workspace),
- &layout);
-
- if (!window->on_all_workspaces)
- {
- ltr = meta_ui_get_direction() == META_UI_DIRECTION_LTR;
-
- if (layout.current_col > 0)
- ops |= ltr ? META_MENU_OP_MOVE_LEFT : META_MENU_OP_MOVE_RIGHT;
- if ((layout.current_col < layout.cols - 1) &&
- (layout.current_row * layout.cols + (layout.current_col + 1) < n_workspaces))
- ops |= ltr ? META_MENU_OP_MOVE_RIGHT : META_MENU_OP_MOVE_LEFT;
- if (layout.current_row > 0)
- ops |= META_MENU_OP_MOVE_UP;
- if ((layout.current_row < layout.rows - 1) &&
- ((layout.current_row + 1) * layout.cols + layout.current_col < n_workspaces))
- ops |= META_MENU_OP_MOVE_DOWN;
- }
-
- meta_screen_free_workspace_layout (&layout);
-
- if (META_WINDOW_MAXIMIZED (window))
- ops |= META_MENU_OP_UNMAXIMIZE;
- else
- ops |= META_MENU_OP_MAXIMIZE;
-
-#if 0
- if (window->shaded)
- ops |= META_MENU_OP_UNSHADE;
- else
- ops |= META_MENU_OP_SHADE;
-#endif
-
- ops |= META_MENU_OP_UNSTICK;
- ops |= META_MENU_OP_STICK;
-
- if (window->wm_state_above)
- ops |= META_MENU_OP_UNABOVE;
- else
- ops |= META_MENU_OP_ABOVE;
-
- if (!window->has_maximize_func)
- insensitive |= META_MENU_OP_UNMAXIMIZE | META_MENU_OP_MAXIMIZE;
-
- if (!window->has_minimize_func)
- insensitive |= META_MENU_OP_MINIMIZE;
-
- if (!window->has_close_func)
- insensitive |= META_MENU_OP_DELETE;
-
- if (!window->has_shade_func)
- insensitive |= META_MENU_OP_SHADE | META_MENU_OP_UNSHADE;
-
- if (!META_WINDOW_ALLOWS_MOVE (window))
- insensitive |= META_MENU_OP_MOVE;
-
- if (!META_WINDOW_ALLOWS_RESIZE (window))
- insensitive |= META_MENU_OP_RESIZE;
-
- if (window->always_sticky)
- insensitive |= META_MENU_OP_STICK | META_MENU_OP_UNSTICK | META_MENU_OP_WORKSPACES;
-
- if ((window->type == META_WINDOW_DESKTOP) ||
- (window->type == META_WINDOW_DOCK) ||
- (window->type == META_WINDOW_SPLASHSCREEN))
- insensitive |= META_MENU_OP_ABOVE | META_MENU_OP_UNABOVE;
-
- /* If all operations are disabled, just quit without showing the menu.
- * This is the case, for example, with META_WINDOW_DESKTOP windows.
- */
- if ((ops & ~insensitive) == 0)
- return;
-
- menu =
- meta_ui_window_menu_new (window->screen->ui,
- window->xwindow,
- ops,
- insensitive,
- meta_window_get_net_wm_desktop (window),
- meta_screen_get_n_workspaces (window->screen),
- menu_callback,
- NULL);
-
- window->display->window_menu = menu;
- window->display->window_with_menu = window;
-
- meta_verbose ("Popping up window menu for %s\n", window->desc);
-
- meta_ui_window_menu_popup (menu, root_x, root_y, button, timestamp);
-}
-
-void
-meta_window_shove_titlebar_onscreen (MetaWindow *window)
-{
- MetaRectangle outer_rect;
- GList *onscreen_region;
- int horiz_amount, vert_amount;
- int newx, newy;
-
- /* If there's no titlebar, don't bother */
- if (!window->frame)
- return;
-
- /* Get the basic info we need */
- meta_window_get_outer_rect (window, &outer_rect);
- onscreen_region = window->screen->active_workspace->screen_region;
-
- /* Extend the region (just in case the window is too big to fit on the
- * screen), then shove the window on screen, then return the region to
- * normal.
- */
- horiz_amount = outer_rect.width;
- vert_amount = outer_rect.height;
- meta_rectangle_expand_region (onscreen_region,
- horiz_amount,
- horiz_amount,
- 0,
- vert_amount);
- meta_rectangle_shove_into_region(onscreen_region,
- FIXED_DIRECTION_X,
- &outer_rect);
- meta_rectangle_expand_region (onscreen_region,
- -horiz_amount,
- -horiz_amount,
- 0,
- -vert_amount);
-
- newx = outer_rect.x + window->frame->child_x;
- newy = outer_rect.y + window->frame->child_y;
- meta_window_move_resize (window,
- FALSE,
- newx,
- newy,
- window->rect.width,
- window->rect.height);
-}
-
-gboolean
-meta_window_titlebar_is_onscreen (MetaWindow *window)
-{
- MetaRectangle titlebar_rect;
- GList *onscreen_region;
- int titlebar_size;
- gboolean is_onscreen;
-
- const int min_height_needed = 8;
- const int min_width_percent = 0.5;
- const int min_width_absolute = 50;
-
- /* Titlebar can't be offscreen if there is no titlebar... */
- if (!window->frame)
- return FALSE;
-
- /* Get the rectangle corresponding to the titlebar */
- meta_window_get_outer_rect (window, &titlebar_rect);
- titlebar_rect.height = window->frame->child_y;
- titlebar_size = meta_rectangle_area (&titlebar_rect);
-
- /* Run through the spanning rectangles for the screen and see if one of
- * them overlaps with the titlebar sufficiently to consider it onscreen.
- */
- is_onscreen = FALSE;
- onscreen_region = window->screen->active_workspace->screen_region;
- while (onscreen_region)
- {
- MetaRectangle *spanning_rect = onscreen_region->data;
- MetaRectangle overlap;
-
- meta_rectangle_intersect (&titlebar_rect, spanning_rect, &overlap);
- if (overlap.height > MIN (titlebar_rect.height, min_height_needed) &&
- overlap.width > MIN (titlebar_rect.width * min_width_percent,
- min_width_absolute))
- {
- is_onscreen = TRUE;
- break;
- }
-
- onscreen_region = onscreen_region->next;
- }
-
- return is_onscreen;
-}
-
-static double
-timeval_to_ms (const GTimeVal *timeval)
-{
- return (timeval->tv_sec * G_USEC_PER_SEC + timeval->tv_usec) / 1000.0;
-}
-
-static double
-time_diff (const GTimeVal *first,
- const GTimeVal *second)
-{
- double first_ms = timeval_to_ms (first);
- double second_ms = timeval_to_ms (second);
-
- return first_ms - second_ms;
-}
-
-static gboolean
-check_moveresize_frequency (MetaWindow *window,
- gdouble *remaining)
-{
- GTimeVal current_time;
-
- g_get_current_time (&current_time);
-
-#ifdef HAVE_XSYNC
- if (!window->disable_sync &&
- window->display->grab_sync_request_alarm != None)
- {
- if (window->sync_request_time.tv_sec != 0 ||
- window->sync_request_time.tv_usec != 0)
- {
- double elapsed =
- time_diff (&current_time, &window->sync_request_time);
-
- if (elapsed < 1000.0)
- {
- /* We want to be sure that the timeout happens at
- * a time where elapsed will definitely be
- * greater than 1000, so we can disable sync
- */
- if (remaining)
- *remaining = 1000.0 - elapsed + 100;
-
- return FALSE;
- }
- else
- {
- /* We have now waited for more than a second for the
- * application to respond to the sync request
- */
- window->disable_sync = TRUE;
- return TRUE;
- }
- }
- else
- {
- /* No outstanding sync requests. Go ahead and resize
- */
- return TRUE;
- }
- }
- else
-#endif /* HAVE_XSYNC */
- {
- const double max_resizes_per_second = 25.0;
- const double ms_between_resizes = 1000.0 / max_resizes_per_second;
- double elapsed;
-
- elapsed = time_diff (&current_time, &window->display->grab_last_moveresize_time);
-
- if (elapsed >= 0.0 && elapsed < ms_between_resizes)
- {
- meta_topic (META_DEBUG_RESIZING,
- "Delaying move/resize as only %g of %g ms elapsed\n",
- elapsed, ms_between_resizes);
-
- if (remaining)
- *remaining = (ms_between_resizes - elapsed);
-
- return FALSE;
- }
-
- meta_topic (META_DEBUG_RESIZING,
- " Checked moveresize freq, allowing move/resize now (%g of %g seconds elapsed)\n",
- elapsed / 1000.0, 1.0 / max_resizes_per_second);
-
- return TRUE;
- }
-}
-
-static gboolean
-update_move_timeout (gpointer data)
-{
- MetaWindow *window = data;
-
- update_move (window,
- window->display->grab_last_user_action_was_snap,
- window->display->grab_latest_motion_x,
- window->display->grab_latest_motion_y);
-
- return FALSE;
-}
-
-static void
-update_move (MetaWindow *window,
- gboolean snap,
- int x,
- int y)
-{
- int dx, dy;
- int new_x, new_y;
- MetaRectangle old;
- int shake_threshold;
- MetaDisplay *display = window->display;
-
- display->grab_latest_motion_x = x;
- display->grab_latest_motion_y = y;
-
- dx = x - display->grab_anchor_root_x;
- dy = y - display->grab_anchor_root_y;
-
- new_x = display->grab_anchor_window_pos.x + dx;
- new_y = display->grab_anchor_window_pos.y + dy;
-
- meta_verbose ("x,y = %d,%d anchor ptr %d,%d anchor pos %d,%d dx,dy %d,%d\n",
- x, y,
- display->grab_anchor_root_x,
- display->grab_anchor_root_y,
- display->grab_anchor_window_pos.x,
- display->grab_anchor_window_pos.y,
- dx, dy);
-
- /* Don't bother doing anything if no move has been specified. (This
- * happens often, even in keyboard moving, due to the warping of the
- * pointer.
- */
- if (dx == 0 && dy == 0)
- return;
-
- /* shake loose (unmaximize) maximized window if dragged beyond the threshold
- * in the Y direction. You can't pull a window loose via X motion.
- */
-
-#define DRAG_THRESHOLD_TO_SHAKE_THRESHOLD_FACTOR 6
- shake_threshold = meta_ui_get_drag_threshold (window->screen->ui) *
- DRAG_THRESHOLD_TO_SHAKE_THRESHOLD_FACTOR;
-
- if (META_WINDOW_MAXIMIZED (window) && ABS (dy) >= shake_threshold)
- {
- double prop;
-
- /* Shake loose */
- window->shaken_loose = TRUE;
-
- /* move the unmaximized window to the cursor */
- prop =
- ((double)(x - display->grab_initial_window_pos.x)) /
- ((double)display->grab_initial_window_pos.width);
-
- display->grab_initial_window_pos.x =
- x - window->saved_rect.width * prop;
- display->grab_initial_window_pos.y = y;
-
- if (window->frame)
- {
- display->grab_initial_window_pos.y += window->frame->child_y / 2;
- }
-
- window->saved_rect.x = display->grab_initial_window_pos.x;
- window->saved_rect.y = display->grab_initial_window_pos.y;
- display->grab_anchor_root_x = x;
- display->grab_anchor_root_y = y;
-
- meta_window_unmaximize (window,
- META_MAXIMIZE_HORIZONTAL |
- META_MAXIMIZE_VERTICAL);
-
- return;
- }
- /* remaximize window on an other xinerama monitor if window has
- * been shaken loose or it is still maximized (then move straight)
- */
- else if (window->shaken_loose || META_WINDOW_MAXIMIZED (window))
- {
- const MetaXineramaScreenInfo *wxinerama;
- MetaRectangle work_area;
- int monitor;
-
- wxinerama = meta_screen_get_xinerama_for_window (window->screen, window);
-
- for (monitor = 0; monitor < window->screen->n_xinerama_infos; monitor++)
- {
- meta_window_get_work_area_for_xinerama (window, monitor, &work_area);
-
- /* check if cursor is near the top of a xinerama work area */
- if (x >= work_area.x &&
- x < (work_area.x + work_area.width) &&
- y >= work_area.y &&
- y < (work_area.y + shake_threshold))
- {
- /* move the saved rect if window will become maximized on an
- * other monitor so user isn't surprised on a later unmaximize
- */
- if (wxinerama->number != monitor)
- {
- window->saved_rect.x = work_area.x;
- window->saved_rect.y = work_area.y;
-
- if (window->frame)
- {
- window->saved_rect.x += window->frame->child_x;
- window->saved_rect.y += window->frame->child_y;
- }
-
- window->user_rect.x = window->saved_rect.x;
- window->user_rect.y = window->saved_rect.y;
-
- meta_window_unmaximize (window,
- META_MAXIMIZE_HORIZONTAL |
- META_MAXIMIZE_VERTICAL);
- }
-
- display->grab_initial_window_pos = work_area;
- display->grab_anchor_root_x = x;
- display->grab_anchor_root_y = y;
- window->shaken_loose = FALSE;
-
- meta_window_maximize (window,
- META_MAXIMIZE_HORIZONTAL |
- META_MAXIMIZE_VERTICAL);
-
- return;
- }
- }
- }
-
- if (display->grab_wireframe_active)
- old = display->grab_wireframe_rect;
- else
- meta_window_get_client_root_coords (window, &old);
-
- /* Don't allow movement in the maximized directions */
- if (window->maximized_horizontally)
- new_x = old.x;
- if (window->maximized_vertically)
- new_y = old.y;
-
- /* Do any edge resistance/snapping */
- meta_window_edge_resistance_for_move (window,
- old.x,
- old.y,
- &new_x,
- &new_y,
- update_move_timeout,
- snap,
- FALSE);
-
- if (display->compositor)
- {
- int root_x = new_x - display->grab_anchor_window_pos.x + display->grab_anchor_root_x;
- int root_y = new_y - display->grab_anchor_window_pos.y + display->grab_anchor_root_y;
-
- meta_compositor_update_move (display->compositor,
- window, root_x, root_y);
- }
-
- if (display->grab_wireframe_active)
- meta_window_update_wireframe (window, new_x, new_y,
- display->grab_wireframe_rect.width,
- display->grab_wireframe_rect.height);
- else
- meta_window_move (window, TRUE, new_x, new_y);
-}
-
-static gboolean
-update_resize_timeout (gpointer data)
-{
- MetaWindow *window = data;
-
- update_resize (window,
- window->display->grab_last_user_action_was_snap,
- window->display->grab_latest_motion_x,
- window->display->grab_latest_motion_y,
- TRUE);
- return FALSE;
-}
-
-static void
-update_resize (MetaWindow *window,
- gboolean snap,
- int x, int y,
- gboolean force)
-{
- int dx, dy;
- int new_w, new_h;
- int gravity;
- MetaRectangle old;
- int new_x, new_y;
- double remaining;
-
- window->display->grab_latest_motion_x = x;
- window->display->grab_latest_motion_y = y;
-
- dx = x - window->display->grab_anchor_root_x;
- dy = y - window->display->grab_anchor_root_y;
-
- new_w = window->display->grab_anchor_window_pos.width;
- new_h = window->display->grab_anchor_window_pos.height;
-
- /* Don't bother doing anything if no move has been specified. (This
- * happens often, even in keyboard resizing, due to the warping of the
- * pointer.
- */
- if (dx == 0 && dy == 0)
- return;
-
- /* FIXME this is only used in wireframe mode */
- new_x = window->display->grab_anchor_window_pos.x;
- new_y = window->display->grab_anchor_window_pos.y;
-
- if (window->display->grab_op == META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN)
- {
- if ((dx > 0) && (dy > 0))
- {
- window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_SE;
- meta_window_update_keyboard_resize (window, TRUE);
- }
- else if ((dx < 0) && (dy > 0))
- {
- window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_SW;
- meta_window_update_keyboard_resize (window, TRUE);
- }
- else if ((dx > 0) && (dy < 0))
- {
- window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_NE;
- meta_window_update_keyboard_resize (window, TRUE);
- }
- else if ((dx < 0) && (dy < 0))
- {
- window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_NW;
- meta_window_update_keyboard_resize (window, TRUE);
- }
- else if (dx < 0)
- {
- window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W;
- meta_window_update_keyboard_resize (window, TRUE);
- }
- else if (dx > 0)
- {
- window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E;
- meta_window_update_keyboard_resize (window, TRUE);
- }
- else if (dy > 0)
- {
- window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S;
- meta_window_update_keyboard_resize (window, TRUE);
- }
- else if (dy < 0)
- {
- window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N;
- meta_window_update_keyboard_resize (window, TRUE);
- }
- }
-
- /* FIXME: This stupidity only needed because of wireframe mode and
- * the fact that wireframe isn't making use of
- * meta_rectangle_resize_with_gravity(). If we were to use that, we
- * could just increment new_w and new_h by dx and dy in all cases.
- */
- switch (window->display->grab_op)
- {
- case META_GRAB_OP_RESIZING_SE:
- case META_GRAB_OP_RESIZING_NE:
- case META_GRAB_OP_RESIZING_E:
- case META_GRAB_OP_KEYBOARD_RESIZING_SE:
- case META_GRAB_OP_KEYBOARD_RESIZING_NE:
- case META_GRAB_OP_KEYBOARD_RESIZING_E:
- new_w += dx;
- break;
-
- case META_GRAB_OP_RESIZING_NW:
- case META_GRAB_OP_RESIZING_SW:
- case META_GRAB_OP_RESIZING_W:
- case META_GRAB_OP_KEYBOARD_RESIZING_NW:
- case META_GRAB_OP_KEYBOARD_RESIZING_SW:
- case META_GRAB_OP_KEYBOARD_RESIZING_W:
- new_w -= dx;
- new_x += dx;
- break;
-
- default:
- break;
- }
-
- switch (window->display->grab_op)
- {
- case META_GRAB_OP_RESIZING_SE:
- case META_GRAB_OP_RESIZING_S:
- case META_GRAB_OP_RESIZING_SW:
- case META_GRAB_OP_KEYBOARD_RESIZING_SE:
- case META_GRAB_OP_KEYBOARD_RESIZING_S:
- case META_GRAB_OP_KEYBOARD_RESIZING_SW:
- new_h += dy;
- break;
-
- case META_GRAB_OP_RESIZING_N:
- case META_GRAB_OP_RESIZING_NE:
- case META_GRAB_OP_RESIZING_NW:
- case META_GRAB_OP_KEYBOARD_RESIZING_N:
- case META_GRAB_OP_KEYBOARD_RESIZING_NE:
- case META_GRAB_OP_KEYBOARD_RESIZING_NW:
- new_h -= dy;
- new_y += dy;
- break;
- default:
- break;
- }
-
- if (!check_moveresize_frequency (window, &remaining) && !force)
- {
- /* we are ignoring an event here, so we schedule a
- * compensation event when we would otherwise not ignore
- * an event. Otherwise we can become stuck if the user never
- * generates another event.
- */
- if (!window->display->grab_resize_timeout_id)
- {
- window->display->grab_resize_timeout_id =
- g_timeout_add ((int)remaining, update_resize_timeout, window);
- }
-
- return;
- }
-
- /* If we get here, it means the client should have redrawn itself */
- if (window->display->compositor)
- meta_compositor_set_updates (window->display->compositor, window, TRUE);
-
- /* Remove any scheduled compensation events */
- if (window->display->grab_resize_timeout_id)
- {
- g_source_remove (window->display->grab_resize_timeout_id);
- window->display->grab_resize_timeout_id = 0;
- }
-
- if (window->display->grab_wireframe_active)
- old = window->display->grab_wireframe_rect;
- else
- old = window->rect; /* Don't actually care about x,y */
-
- /* One sided resizing ought to actually be one-sided, despite the fact that
- * aspect ratio windows don't interact nicely with the above stuff. So,
- * to avoid some nasty flicker, we enforce that.
- */
- switch (window->display->grab_op)
- {
- case META_GRAB_OP_RESIZING_S:
- case META_GRAB_OP_RESIZING_N:
- new_w = old.width;
- break;
-
- case META_GRAB_OP_RESIZING_E:
- case META_GRAB_OP_RESIZING_W:
- new_h = old.height;
- break;
-
- default:
- break;
- }
-
- /* compute gravity of client during operation */
- gravity = meta_resize_gravity_from_grab_op (window->display->grab_op);
- g_assert (gravity >= 0);
-
- /* Do any edge resistance/snapping */
- meta_window_edge_resistance_for_resize (window,
- old.width,
- old.height,
- &new_w,
- &new_h,
- gravity,
- update_resize_timeout,
- snap,
- FALSE);
-
- if (window->display->grab_wireframe_active)
- {
- if ((new_x + new_w <= new_x) || (new_y + new_h <= new_y))
- return;
-
- /* FIXME This is crap. For example, the wireframe isn't
- * constrained in the way that a real resize would be. An
- * obvious elegant solution is to unmap the window during
- * wireframe, but still resize it; however, that probably
- * confuses broken clients that have problems with opaque
- * resize, they probably don't track their visibility.
- */
- meta_window_update_wireframe (window, new_x, new_y, new_w, new_h);
- }
- else
- {
- /* We don't need to update unless the specified width and height
- * are actually different from what we had before.
- */
- if (old.width != new_w || old.height != new_h)
- meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity);
- }
-
- /* Store the latest resize time, if we actually resized. */
- if (window->rect.width != old.width || window->rect.height != old.height)
- g_get_current_time (&window->display->grab_last_moveresize_time);
-}
-
-typedef struct
-{
- const XEvent *current_event;
- int count;
- guint32 last_time;
-} EventScannerData;
-
-static Bool
-find_last_time_predicate (Display *display,
- XEvent *xevent,
- XPointer arg)
-{
- EventScannerData *esd = (void*) arg;
-
- if (esd->current_event->type == xevent->type &&
- esd->current_event->xany.window == xevent->xany.window)
- {
- esd->count += 1;
- esd->last_time = xevent->xmotion.time;
- }
-
- return False;
-}
-
-static gboolean
-check_use_this_motion_notify (MetaWindow *window,
- XEvent *event)
-{
- EventScannerData esd;
- XEvent useless;
-
- /* This code is copied from Owen's GDK code. */
-
- if (window->display->grab_motion_notify_time != 0)
- {
- /* == is really the right test, but I'm all for paranoia */
- if (window->display->grab_motion_notify_time <=
- event->xmotion.time)
- {
- meta_topic (META_DEBUG_RESIZING,
- "Arrived at event with time %u (waiting for %u), using it\n",
- (unsigned int)event->xmotion.time,
- window->display->grab_motion_notify_time);
- window->display->grab_motion_notify_time = 0;
- return TRUE;
- }
- else
- return FALSE; /* haven't reached the saved timestamp yet */
- }
-
- esd.current_event = event;
- esd.count = 0;
- esd.last_time = 0;
-
- /* "useless" isn't filled in because the predicate never returns True */
- XCheckIfEvent (window->display->xdisplay,
- &useless,
- find_last_time_predicate,
- (XPointer) &esd);
-
- if (esd.count > 0)
- meta_topic (META_DEBUG_RESIZING,
- "Will skip %d motion events and use the event with time %u\n",
- esd.count, (unsigned int) esd.last_time);
-
- if (esd.last_time == 0)
- return TRUE;
- else
- {
- /* Save this timestamp, and ignore all motion notify
- * until we get to the one with this stamp.
- */
- window->display->grab_motion_notify_time = esd.last_time;
- return FALSE;
- }
-}
-
-void
-meta_window_handle_mouse_grab_op_event (MetaWindow *window,
- XEvent *event)
-{
-#ifdef HAVE_XSYNC
- if (event->type == (window->display->xsync_event_base + XSyncAlarmNotify))
- {
- meta_topic (META_DEBUG_RESIZING,
- "Alarm event received last motion x = %d y = %d\n",
- window->display->grab_latest_motion_x,
- window->display->grab_latest_motion_y);
-
- /* If sync was previously disabled, turn it back on and hope
- * the application has come to its senses (maybe it was just
- * busy with a pagefault or a long computation).
- */
- window->disable_sync = FALSE;
- window->sync_request_time.tv_sec = 0;
- window->sync_request_time.tv_usec = 0;
-
- /* This means we are ready for another configure. */
- switch (window->display->grab_op)
- {
- case META_GRAB_OP_RESIZING_E:
- case META_GRAB_OP_RESIZING_W:
- case META_GRAB_OP_RESIZING_S:
- case META_GRAB_OP_RESIZING_N:
- case META_GRAB_OP_RESIZING_SE:
- case META_GRAB_OP_RESIZING_SW:
- case META_GRAB_OP_RESIZING_NE:
- case META_GRAB_OP_RESIZING_NW:
- case META_GRAB_OP_KEYBOARD_RESIZING_S:
- case META_GRAB_OP_KEYBOARD_RESIZING_N:
- case META_GRAB_OP_KEYBOARD_RESIZING_W:
- case META_GRAB_OP_KEYBOARD_RESIZING_E:
- case META_GRAB_OP_KEYBOARD_RESIZING_SE:
- case META_GRAB_OP_KEYBOARD_RESIZING_NE:
- case META_GRAB_OP_KEYBOARD_RESIZING_SW:
- case META_GRAB_OP_KEYBOARD_RESIZING_NW:
- /* no pointer round trip here, to keep in sync */
- update_resize (window,
- window->display->grab_last_user_action_was_snap,
- window->display->grab_latest_motion_x,
- window->display->grab_latest_motion_y,
- TRUE);
- break;
-
- default:
- break;
- }
- }
-#endif /* HAVE_XSYNC */
-
- switch (event->type)
- {
- case ButtonRelease:
- meta_display_check_threshold_reached (window->display,
- event->xbutton.x_root,
- event->xbutton.y_root);
- /* If the user was snap moving then ignore the button release
- * because they may have let go of shift before releasing the
- * mouse button and they almost certainly do not want a
- * non-snapped movement to occur from the button release.
- */
- if (!window->display->grab_last_user_action_was_snap)
- {
- if (meta_grab_op_is_moving (window->display->grab_op))
- {
- if (event->xbutton.root == window->screen->xroot)
- update_move (window, event->xbutton.state & ShiftMask,
- event->xbutton.x_root, event->xbutton.y_root);
- }
- else if (meta_grab_op_is_resizing (window->display->grab_op))
- {
- if (event->xbutton.root == window->screen->xroot)
- update_resize (window,
- event->xbutton.state & ShiftMask,
- event->xbutton.x_root,
- event->xbutton.y_root,
- TRUE);
- if (window->display->compositor)
- meta_compositor_set_updates (window->display->compositor, window, TRUE);
- }
- }
-
- meta_display_end_grab_op (window->display, event->xbutton.time);
- break;
-
- case MotionNotify:
- meta_display_check_threshold_reached (window->display,
- event->xmotion.x_root,
- event->xmotion.y_root);
- if (meta_grab_op_is_moving (window->display->grab_op))
- {
- if (event->xmotion.root == window->screen->xroot)
- {
- if (check_use_this_motion_notify (window,
- event))
- update_move (window,
- event->xmotion.state & ShiftMask,
- event->xmotion.x_root,
- event->xmotion.y_root);
- }
- }
- else if (meta_grab_op_is_resizing (window->display->grab_op))
- {
- if (event->xmotion.root == window->screen->xroot)
- {
- if (check_use_this_motion_notify (window,
- event))
- update_resize (window,
- event->xmotion.state & ShiftMask,
- event->xmotion.x_root,
- event->xmotion.y_root,
- FALSE);
- }
- }
- break;
-
- default:
- break;
- }
-}
-
-void
-meta_window_set_gravity (MetaWindow *window,
- int gravity)
-{
- XSetWindowAttributes attrs;
-
- meta_verbose ("Setting gravity of %s to %d\n", window->desc, gravity);
-
- attrs.win_gravity = gravity;
-
- meta_error_trap_push (window->display);
-
- XChangeWindowAttributes (window->display->xdisplay,
- window->xwindow,
- CWWinGravity,
- &attrs);
-
- meta_error_trap_pop (window->display, FALSE);
-}
-
-static void
-get_work_area_xinerama (MetaWindow *window,
- MetaRectangle *area,
- int which_xinerama)
-{
- GList *tmp;
-
- g_assert (which_xinerama >= 0);
-
- /* Initialize to the whole xinerama */
- *area = window->screen->xinerama_infos[which_xinerama].rect;
-
- tmp = meta_window_get_workspaces (window);
- while (tmp != NULL)
- {
- MetaRectangle workspace_work_area;
- meta_workspace_get_work_area_for_xinerama (tmp->data,
- which_xinerama,
- &workspace_work_area);
- meta_rectangle_intersect (area,
- &workspace_work_area,
- area);
- tmp = tmp->next;
- }
-
- meta_topic (META_DEBUG_WORKAREA,
- "Window %s xinerama %d has work area %d,%d %d x %d\n",
- window->desc, which_xinerama,
- area->x, area->y, area->width, area->height);
-}
-
-void
-meta_window_get_work_area_current_xinerama (MetaWindow *window,
- MetaRectangle *area)
-{
- const MetaXineramaScreenInfo *xinerama = NULL;
- xinerama = meta_screen_get_xinerama_for_window (window->screen,
- window);
-
- meta_window_get_work_area_for_xinerama (window,
- xinerama->number,
- area);
-}
-
-void
-meta_window_get_work_area_for_xinerama (MetaWindow *window,
- int which_xinerama,
- MetaRectangle *area)
-{
- g_return_if_fail (which_xinerama >= 0);
-
- get_work_area_xinerama (window,
- area,
- which_xinerama);
-}
-
-void
-meta_window_get_work_area_all_xineramas (MetaWindow *window,
- MetaRectangle *area)
-{
- GList *tmp;
-
- /* Initialize to the whole screen */
- *area = window->screen->rect;
-
- tmp = meta_window_get_workspaces (window);
- while (tmp != NULL)
- {
- MetaRectangle workspace_work_area;
- meta_workspace_get_work_area_all_xineramas (tmp->data,
- &workspace_work_area);
- meta_rectangle_intersect (area,
- &workspace_work_area,
- area);
- tmp = tmp->next;
- }
-
- meta_topic (META_DEBUG_WORKAREA,
- "Window %s has whole-screen work area %d,%d %d x %d\n",
- window->desc, area->x, area->y, area->width, area->height);
-}
-
-
-gboolean
-meta_window_same_application (MetaWindow *window,
- MetaWindow *other_window)
-{
- MetaGroup *group = meta_window_get_group (window);
- MetaGroup *other_group = meta_window_get_group (other_window);
-
- return
- group!=NULL &&
- other_group!=NULL &&
- group==other_group;
-}
-
-void
-meta_window_refresh_resize_popup (MetaWindow *window)
-{
- if (window->display->grab_op == META_GRAB_OP_NONE)
- return;
-
- if (window->display->grab_window != window)
- return;
-
- /* We shouldn't ever get called when the wireframe is active
- * because that's handled by a different code path in effects.c
- */
- if (window->display->grab_wireframe_active)
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "refresh_resize_popup called when wireframe active\n");
- return;
- }
-
- switch (window->display->grab_op)
- {
- case META_GRAB_OP_RESIZING_SE:
- case META_GRAB_OP_RESIZING_S:
- case META_GRAB_OP_RESIZING_SW:
- case META_GRAB_OP_RESIZING_N:
- case META_GRAB_OP_RESIZING_NE:
- case META_GRAB_OP_RESIZING_NW:
- case META_GRAB_OP_RESIZING_W:
- case META_GRAB_OP_RESIZING_E:
- case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
- case META_GRAB_OP_KEYBOARD_RESIZING_S:
- case META_GRAB_OP_KEYBOARD_RESIZING_N:
- case META_GRAB_OP_KEYBOARD_RESIZING_W:
- case META_GRAB_OP_KEYBOARD_RESIZING_E:
- case META_GRAB_OP_KEYBOARD_RESIZING_SE:
- case META_GRAB_OP_KEYBOARD_RESIZING_NE:
- case META_GRAB_OP_KEYBOARD_RESIZING_SW:
- case META_GRAB_OP_KEYBOARD_RESIZING_NW:
- break;
-
- default:
- /* Not resizing */
- return;
- }
-
- if (window->display->grab_resize_popup == NULL)
- {
- if (window->size_hints.width_inc > 1 ||
- window->size_hints.height_inc > 1)
- window->display->grab_resize_popup =
- meta_ui_resize_popup_new (window->display->xdisplay,
- window->screen->number);
- }
-
- if (window->display->grab_resize_popup != NULL)
- {
- MetaRectangle rect;
-
- if (window->display->grab_wireframe_active)
- rect = window->display->grab_wireframe_rect;
- else
- meta_window_get_client_root_coords (window, &rect);
-
- meta_ui_resize_popup_set (window->display->grab_resize_popup,
- rect,
- window->size_hints.base_width,
- window->size_hints.base_height,
- window->size_hints.width_inc,
- window->size_hints.height_inc);
-
- meta_ui_resize_popup_set_showing (window->display->grab_resize_popup,
- TRUE);
- }
-}
-
-void
-meta_window_foreach_transient (MetaWindow *window,
- MetaWindowForeachFunc func,
- void *data)
-{
- GSList *windows;
- GSList *tmp;
-
- windows = meta_display_list_windows (window->display);
-
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *transient = tmp->data;
-
- if (meta_window_is_ancestor_of_transient (window, transient))
- {
- if (!(* func) (transient, data))
- break;
- }
-
- tmp = tmp->next;
- }
-
- g_slist_free (windows);
-}
-
-void
-meta_window_foreach_ancestor (MetaWindow *window,
- MetaWindowForeachFunc func,
- void *data)
-{
- MetaWindow *w;
- MetaWindow *tortoise;
-
- w = window;
- tortoise = window;
- while (TRUE)
- {
- if (w->xtransient_for == None ||
- w->transient_parent_is_root_window)
- break;
-
- w = meta_display_lookup_x_window (w->display, w->xtransient_for);
-
- if (w == NULL || w == tortoise)
- break;
-
- if (!(* func) (w, data))
- break;
-
- if (w->xtransient_for == None ||
- w->transient_parent_is_root_window)
- break;
-
- w = meta_display_lookup_x_window (w->display, w->xtransient_for);
-
- if (w == NULL || w == tortoise)
- break;
-
- if (!(* func) (w, data))
- break;
-
- tortoise = meta_display_lookup_x_window (tortoise->display,
- tortoise->xtransient_for);
-
- /* "w" should have already covered all ground covered by the
- * tortoise, so the following must hold.
- */
- g_assert (tortoise != NULL);
- g_assert (tortoise->xtransient_for != None);
- g_assert (!tortoise->transient_parent_is_root_window);
- }
-}
-
-typedef struct
-{
- MetaWindow *ancestor;
- gboolean found;
-} FindAncestorData;
-
-static gboolean
-find_ancestor_func (MetaWindow *window,
- void *data)
-{
- FindAncestorData *d = data;
-
- if (window == d->ancestor)
- {
- d->found = TRUE;
- return FALSE;
- }
-
- return TRUE;
-}
-
-gboolean
-meta_window_is_ancestor_of_transient (MetaWindow *window,
- MetaWindow *transient)
-{
- FindAncestorData d;
-
- d.ancestor = window;
- d.found = FALSE;
-
- meta_window_foreach_ancestor (transient, find_ancestor_func, &d);
-
- return d.found;
-}
-
-/* Warp pointer to location appropriate for grab,
- * return root coordinates where pointer ended up.
- */
-static gboolean
-warp_grab_pointer (MetaWindow *window,
- MetaGrabOp grab_op,
- int *x,
- int *y)
-{
- MetaRectangle rect;
- MetaDisplay *display;
-
- display = window->display;
-
- /* We may not have done begin_grab_op yet, i.e. may not be in a grab
- */
-
- if (window == display->grab_window && display->grab_wireframe_active)
- {
- meta_window_get_xor_rect (window, &display->grab_wireframe_rect, &rect);
- }
- else
- {
- meta_window_get_outer_rect (window, &rect);
- }
-
- switch (grab_op)
- {
- case META_GRAB_OP_KEYBOARD_MOVING:
- case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
- *x = rect.width / 2;
- *y = rect.height / 2;
- break;
-
- case META_GRAB_OP_KEYBOARD_RESIZING_S:
- *x = rect.width / 2;
- *y = rect.height - 1;
- break;
-
- case META_GRAB_OP_KEYBOARD_RESIZING_N:
- *x = rect.width / 2;
- *y = 0;
- break;
-
- case META_GRAB_OP_KEYBOARD_RESIZING_W:
- *x = 0;
- *y = rect.height / 2;
- break;
-
- case META_GRAB_OP_KEYBOARD_RESIZING_E:
- *x = rect.width - 1;
- *y = rect.height / 2;
- break;
-
- case META_GRAB_OP_KEYBOARD_RESIZING_SE:
- *x = rect.width - 1;
- *y = rect.height - 1;
- break;
-
- case META_GRAB_OP_KEYBOARD_RESIZING_NE:
- *x = rect.width - 1;
- *y = 0;
- break;
-
- case META_GRAB_OP_KEYBOARD_RESIZING_SW:
- *x = 0;
- *y = rect.height - 1;
- break;
-
- case META_GRAB_OP_KEYBOARD_RESIZING_NW:
- *x = 0;
- *y = 0;
- break;
-
- default:
- return FALSE;
- }
-
- *x += rect.x;
- *y += rect.y;
-
- /* Avoid weird bouncing at the screen edge; see bug 154706 */
- *x = CLAMP (*x, 0, window->screen->rect.width-1);
- *y = CLAMP (*y, 0, window->screen->rect.height-1);
-
- meta_error_trap_push_with_return (display);
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Warping pointer to %d,%d with window at %d,%d\n",
- *x, *y, rect.x, rect.y);
-
- /* Need to update the grab positions so that the MotionNotify and other
- * events generated by the XWarpPointer() call below don't cause complete
- * funkiness. See bug 124582 and bug 122670.
- */
- display->grab_anchor_root_x = *x;
- display->grab_anchor_root_y = *y;
- display->grab_latest_motion_x = *x;
- display->grab_latest_motion_y = *y;
- if (display->grab_wireframe_active)
- display->grab_anchor_window_pos = display->grab_wireframe_rect;
- else
- meta_window_get_client_root_coords (window,
- &display->grab_anchor_window_pos);
-
- XWarpPointer (display->xdisplay,
- None,
- window->screen->xroot,
- 0, 0, 0, 0,
- *x, *y);
-
- if (meta_error_trap_pop_with_return (display, FALSE) != Success)
- {
- meta_verbose ("Failed to warp pointer for window %s\n",
- window->desc);
- return FALSE;
- }
-
- return TRUE;
-}
-
-void
-meta_window_begin_grab_op (MetaWindow *window,
- MetaGrabOp op,
- gboolean frame_action,
- guint32 timestamp)
-{
- int x, y;
-
- warp_grab_pointer (window,
- op, &x, &y);
-
- meta_display_begin_grab_op (window->display,
- window->screen,
- window,
- op,
- FALSE,
- frame_action,
- 0 /* button */,
- 0,
- timestamp,
- x, y);
-}
-
-void
-meta_window_update_keyboard_resize (MetaWindow *window,
- gboolean update_cursor)
-{
- int x, y;
-
- warp_grab_pointer (window,
- window->display->grab_op,
- &x, &y);
-
- if (update_cursor)
- {
- guint32 timestamp;
- /* FIXME: Using CurrentTime is really bad mojo */
- timestamp = CurrentTime;
- meta_display_set_grab_op_cursor (window->display,
- NULL,
- window->display->grab_op,
- TRUE,
- window->display->grab_xwindow,
- timestamp);
- }
-}
-
-void
-meta_window_update_keyboard_move (MetaWindow *window)
-{
- int x, y;
-
- warp_grab_pointer (window,
- window->display->grab_op,
- &x, &y);
-}
-
-void
-meta_window_update_layer (MetaWindow *window)
-{
- MetaGroup *group;
-
- meta_stack_freeze (window->screen->stack);
- group = meta_window_get_group (window);
- if (group)
- meta_group_update_layers (group);
- else
- meta_stack_update_layer (window->screen->stack, window);
- meta_stack_thaw (window->screen->stack);
-}
-
-/* ensure_mru_position_after ensures that window appears after
- * below_this_one in the active_workspace's mru_list (i.e. it treats
- * window as having been less recently used than below_this_one)
- */
-static void
-ensure_mru_position_after (MetaWindow *window,
- MetaWindow *after_this_one)
-{
- /* This is sort of slow since it runs through the entire list more
- * than once (especially considering the fact that we expect the
- * windows of interest to be the first two elements in the list),
- * but it doesn't matter while we're only using it on new window
- * map.
- */
-
- GList* active_mru_list;
- GList* window_position;
- GList* after_this_one_position;
-
- active_mru_list = window->screen->active_workspace->mru_list;
- window_position = g_list_find (active_mru_list, window);
- after_this_one_position = g_list_find (active_mru_list, after_this_one);
-
- /* after_this_one_position is NULL when we switch workspaces, but in
- * that case we don't need to do any MRU shuffling so we can simply
- * return.
- */
- if (after_this_one_position == NULL)
- return;
-
- if (g_list_length (window_position) > g_list_length (after_this_one_position))
- {
- window->screen->active_workspace->mru_list =
- g_list_delete_link (window->screen->active_workspace->mru_list,
- window_position);
-
- window->screen->active_workspace->mru_list =
- g_list_insert_before (window->screen->active_workspace->mru_list,
- after_this_one_position->next,
- window);
- }
-}
-
-void
-meta_window_stack_just_below (MetaWindow *window,
- MetaWindow *below_this_one)
-{
- g_return_if_fail (window != NULL);
- g_return_if_fail (below_this_one != NULL);
-
- if (window->stack_position > below_this_one->stack_position)
- {
- meta_topic (META_DEBUG_STACK,
- "Setting stack position of window %s to %d (making it below window %s).\n",
- window->desc,
- below_this_one->stack_position,
- below_this_one->desc);
- meta_window_set_stack_position (window, below_this_one->stack_position);
- }
- else
- {
- meta_topic (META_DEBUG_STACK,
- "Window %s was already below window %s.\n",
- window->desc, below_this_one->desc);
- }
-}
-
-void
-meta_window_set_user_time (MetaWindow *window,
- guint32 timestamp)
-{
- /* FIXME: If Soeren's suggestion in bug 151984 is implemented, it will allow
- * us to sanity check the timestamp here and ensure it doesn't correspond to
- * a future time.
- */
-
- /* Only update the time if this timestamp is newer... */
- if (window->net_wm_user_time_set &&
- XSERVER_TIME_IS_BEFORE (timestamp, window->net_wm_user_time))
- {
- meta_topic (META_DEBUG_STARTUP,
- "Window %s _NET_WM_USER_TIME not updated to %u, because it "
- "is less than %u\n",
- window->desc, timestamp, window->net_wm_user_time);
- }
- else
- {
- meta_topic (META_DEBUG_STARTUP,
- "Window %s has _NET_WM_USER_TIME of %u\n",
- window->desc, timestamp);
- window->net_wm_user_time_set = TRUE;
- window->net_wm_user_time = timestamp;
- if (XSERVER_TIME_IS_BEFORE (window->display->last_user_time, timestamp))
- window->display->last_user_time = timestamp;
-
- /* If this is a terminal, user interaction with it means the user likely
- * doesn't want to have focus transferred for now due to new windows.
- */
- if (meta_prefs_get_focus_new_windows () ==
- META_FOCUS_NEW_WINDOWS_STRICT &&
- __window_is_terminal (window))
- window->display->allow_terminal_deactivation = FALSE;
- }
-}
-
-/* Sets the demands_attention hint on a window, but only
- * if it's at least partially obscured (see #305882).
- */
-void
-meta_window_set_demands_attention (MetaWindow *window)
-{
- MetaRectangle candidate_rect, other_rect;
- GList *stack = window->screen->stack->sorted;
- MetaWindow *other_window;
- gboolean obscured = FALSE;
-
- MetaWorkspace *workspace = window->screen->active_workspace;
- if (workspace!=window->workspace)
- {
- /* windows on other workspaces are necessarily obscured */
- obscured = TRUE;
- }
- else if (window->minimized)
- {
- obscured = TRUE;
- }
- else
- {
- meta_window_get_outer_rect (window, &candidate_rect);
-
- /* The stack is sorted with the top windows first. */
-
- while (stack != NULL && stack->data != window)
- {
- other_window = stack->data;
- stack = stack->next;
-
- if (other_window->on_all_workspaces ||
- window->on_all_workspaces ||
- other_window->workspace == window->workspace)
- {
- meta_window_get_outer_rect (other_window, &other_rect);
-
- if (meta_rectangle_overlap (&candidate_rect, &other_rect))
- {
- obscured = TRUE;
- break;
- }
- }
- }
- }
-
- if (obscured)
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Marking %s as needing attention\n",
- window->desc);
-
- window->wm_state_demands_attention = TRUE;
- set_net_wm_state (window);
- }
- else
- {
- /* If the window's in full view, there's no point setting the flag. */
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Not marking %s as needing attention because "
- "it's in full view\n",
- window->desc);
- }
-}
-
-void
-meta_window_unset_demands_attention (MetaWindow *window)
-{
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Marking %s as not needing attention\n", window->desc);
-
- window->wm_state_demands_attention = FALSE;
- set_net_wm_state (window);
-}
-
-MetaFrame *
-meta_window_get_frame (MetaWindow *window)
-{
- return window->frame;
-}
-
-gboolean
-meta_window_has_focus (MetaWindow *window)
-{
- return window->has_focus;
-}
-
-gboolean
-meta_window_is_shaded (MetaWindow *window)
-{
- return window->shaded;
-}
-
-MetaRectangle *
-meta_window_get_rect (MetaWindow *window)
-{
- return &window->rect;
-}
-
-MetaScreen *
-meta_window_get_screen (MetaWindow *window)
-{
- return window->screen;
-}
-
-MetaDisplay *
-meta_window_get_display (MetaWindow *window)
-{
- return window->display;
-}
-
-Window
-meta_window_get_xwindow (MetaWindow *window)
-{
- return window->xwindow;
-}
diff --git a/src/core/workspace.c b/src/core/workspace.c
deleted file mode 100644
index ddb2541f..00000000
--- a/src/core/workspace.c
+++ /dev/null
@@ -1,976 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity Workspaces */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2003 Rob Adams
- * Copyright (C) 2004, 2005 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include "workspace.h"
-#include "errors.h"
-#include "prefs.h"
-#include <X11/Xatom.h>
-#include <string.h>
-
-void meta_workspace_queue_calc_showing (MetaWorkspace *workspace);
-static void set_active_space_hint (MetaScreen *screen);
-static void focus_ancestor_or_mru_window (MetaWorkspace *workspace,
- MetaWindow *not_this_one,
- guint32 timestamp);
-static void free_this (gpointer candidate,
- gpointer dummy);
-static void workspace_free_struts (MetaWorkspace *workspace);
-
-static void
-maybe_add_to_list (MetaScreen *screen, MetaWindow *window, gpointer data)
-{
- GList **mru_list = data;
-
- if (window->on_all_workspaces)
- *mru_list = g_list_prepend (*mru_list, window);
-}
-
-MetaWorkspace*
-meta_workspace_new (MetaScreen *screen)
-{
- MetaWorkspace *workspace;
-
- workspace = g_new (MetaWorkspace, 1);
-
- workspace->screen = screen;
- workspace->screen->workspaces =
- g_list_append (workspace->screen->workspaces, workspace);
- workspace->windows = NULL;
- workspace->mru_list = NULL;
- meta_screen_foreach_window (screen, maybe_add_to_list, &workspace->mru_list);
-
- workspace->work_areas_invalid = TRUE;
- workspace->work_area_xinerama = NULL;
- workspace->work_area_screen.x = 0;
- workspace->work_area_screen.y = 0;
- workspace->work_area_screen.width = 0;
- workspace->work_area_screen.height = 0;
-
- workspace->screen_region = NULL;
- workspace->xinerama_region = NULL;
- workspace->screen_edges = NULL;
- workspace->xinerama_edges = NULL;
- workspace->list_containing_self = g_list_prepend (NULL, workspace);
-
- workspace->all_struts = NULL;
-
- workspace->showing_desktop = FALSE;
-
- return workspace;
-}
-
-/** Foreach function for workspace_free_struts() */
-static void
-free_this (gpointer candidate, gpointer dummy)
-{
- g_free (candidate);
-}
-
-/**
- * Frees the struts list of a workspace.
- *
- * \param workspace The workspace.
- */
-static void
-workspace_free_struts (MetaWorkspace *workspace)
-{
- if (workspace->all_struts == NULL)
- return;
-
- g_slist_foreach (workspace->all_struts, free_this, NULL);
- g_slist_free (workspace->all_struts);
- workspace->all_struts = NULL;
-}
-
-void
-meta_workspace_free (MetaWorkspace *workspace)
-{
- GList *tmp;
- MetaScreen *screen;
- int i;
-
- g_return_if_fail (workspace != workspace->screen->active_workspace);
-
- /* Here we assume all the windows are already on another workspace
- * as well, so they won't be "orphaned"
- */
-
- tmp = workspace->windows;
- while (tmp != NULL)
- {
- GList *next;
- MetaWindow *window = tmp->data;
- next = tmp->next;
-
- /* pop front of list we're iterating over */
- meta_workspace_remove_window (workspace, window);
- g_assert (window->workspace != NULL);
-
- tmp = next;
- }
-
- g_assert (workspace->windows == NULL);
-
- screen = workspace->screen;
-
- workspace->screen->workspaces =
- g_list_remove (workspace->screen->workspaces, workspace);
-
- g_free (workspace->work_area_xinerama);
-
- g_list_free (workspace->mru_list);
- g_list_free (workspace->list_containing_self);
-
- /* screen.c:update_num_workspaces(), which calls us, removes windows from
- * workspaces first, which can cause the workareas on the workspace to be
- * invalidated (and hence for struts/regions/edges to be freed).
- * So, no point trying to double free it; that causes a crash
- * anyway. #361804.
- */
-
- if (!workspace->work_areas_invalid)
- {
- workspace_free_struts (workspace);
- for (i = 0; i < screen->n_xinerama_infos; i++)
- meta_rectangle_free_list_and_elements (workspace->xinerama_region[i]);
- g_free (workspace->xinerama_region);
- meta_rectangle_free_list_and_elements (workspace->screen_region);
- meta_rectangle_free_list_and_elements (workspace->screen_edges);
- meta_rectangle_free_list_and_elements (workspace->xinerama_edges);
- }
-
- g_free (workspace);
-
- /* don't bother to reset names, pagers can just ignore
- * extra ones
- */
-}
-
-void
-meta_workspace_add_window (MetaWorkspace *workspace,
- MetaWindow *window)
-{
- g_return_if_fail (window->workspace == NULL);
-
- /* If the window is on all workspaces, we want to add it to all mru
- * lists, otherwise just add it to this workspaces mru list
- */
- if (window->on_all_workspaces)
- {
- if (window->workspace == NULL)
- {
- GList* tmp = window->screen->workspaces;
- while (tmp)
- {
- MetaWorkspace* work = (MetaWorkspace*) tmp->data;
- if (!g_list_find (work->mru_list, window))
- work->mru_list = g_list_prepend (work->mru_list, window);
-
- tmp = tmp->next;
- }
- }
- }
- else
- {
- g_assert (g_list_find (workspace->mru_list, window) == NULL);
- workspace->mru_list = g_list_prepend (workspace->mru_list, window);
- }
-
- workspace->windows = g_list_prepend (workspace->windows, window);
- window->workspace = workspace;
-
- meta_window_set_current_workspace_hint (window);
-
- if (window->struts)
- {
- meta_topic (META_DEBUG_WORKAREA,
- "Invalidating work area of workspace %d since we're adding window %s to it\n",
- meta_workspace_index (workspace), window->desc);
- meta_workspace_invalidate_work_area (workspace);
- }
-
- /* queue a move_resize since changing workspaces may change
- * the relevant struts
- */
- meta_window_queue (window, META_QUEUE_CALC_SHOWING|META_QUEUE_MOVE_RESIZE);
-}
-
-void
-meta_workspace_remove_window (MetaWorkspace *workspace,
- MetaWindow *window)
-{
- g_return_if_fail (window->workspace == workspace);
-
- workspace->windows = g_list_remove (workspace->windows, window);
- window->workspace = NULL;
-
- /* If the window is on all workspaces, we don't want to remove it
- * from the MRU list unless this causes it to be removed from all
- * workspaces
- */
- if (window->on_all_workspaces)
- {
- GList* tmp = window->screen->workspaces;
- while (tmp)
- {
- MetaWorkspace* work = (MetaWorkspace*) tmp->data;
- work->mru_list = g_list_remove (work->mru_list, window);
-
- tmp = tmp->next;
- }
- }
- else
- {
- workspace->mru_list = g_list_remove (workspace->mru_list, window);
- g_assert (g_list_find (workspace->mru_list, window) == NULL);
- }
-
- meta_window_set_current_workspace_hint (window);
-
- if (window->struts)
- {
- meta_topic (META_DEBUG_WORKAREA,
- "Invalidating work area of workspace %d since we're removing window %s from it\n",
- meta_workspace_index (workspace), window->desc);
- meta_workspace_invalidate_work_area (workspace);
- }
-
- /* queue a move_resize since changing workspaces may change
- * the relevant struts
- */
- meta_window_queue (window, META_QUEUE_CALC_SHOWING|META_QUEUE_MOVE_RESIZE);
-}
-
-void
-meta_workspace_relocate_windows (MetaWorkspace *workspace,
- MetaWorkspace *new_home)
-{
- GList *tmp;
- GList *copy;
-
- g_return_if_fail (workspace != new_home);
-
- /* can't modify list we're iterating over */
- copy = g_list_copy (workspace->windows);
-
- tmp = copy;
- while (tmp != NULL)
- {
- MetaWindow *window = tmp->data;
-
- meta_workspace_remove_window (workspace, window);
- meta_workspace_add_window (new_home, window);
-
- tmp = tmp->next;
- }
-
- g_list_free (copy);
-
- g_assert (workspace->windows == NULL);
-}
-
-void
-meta_workspace_queue_calc_showing (MetaWorkspace *workspace)
-{
- GList *tmp;
-
- tmp = workspace->windows;
- while (tmp != NULL)
- {
- meta_window_queue (tmp->data, META_QUEUE_CALC_SHOWING);
-
- tmp = tmp->next;
- }
-}
-
-void
-meta_workspace_activate_with_focus (MetaWorkspace *workspace,
- MetaWindow *focus_this,
- guint32 timestamp)
-{
- MetaWorkspace *old;
- MetaWindow *move_window;
-
- meta_verbose ("Activating workspace %d\n",
- meta_workspace_index (workspace));
-
- if (workspace->screen->active_workspace == workspace)
- return;
-
- /* Note that old can be NULL; e.g. when starting up */
- old = workspace->screen->active_workspace;
-
- workspace->screen->active_workspace = workspace;
-
- set_active_space_hint (workspace->screen);
-
- /* If the "show desktop" mode is active for either the old workspace
- * or the new one *but not both*, then update the
- * _net_showing_desktop hint
- */
- if (old && (old->showing_desktop ^ workspace->showing_desktop))
- meta_screen_update_showing_desktop_hint (workspace->screen);
-
- if (old == NULL)
- return;
-
- move_window = NULL;
- if (workspace->screen->display->grab_op == META_GRAB_OP_MOVING ||
- workspace->screen->display->grab_op == META_GRAB_OP_KEYBOARD_MOVING)
- move_window = workspace->screen->display->grab_window;
-
- if (move_window != NULL)
- {
- if (move_window->on_all_workspaces)
- move_window = NULL; /* don't move it after all */
-
- /* We put the window on the new workspace, flip spaces,
- * then remove from old workspace, so the window
- * never gets unmapped and we maintain the button grab
- * on it.
- *
- * \bug This comment appears to be the reverse of what happens
- */
- if (move_window && (move_window->workspace != workspace))
- {
- meta_workspace_remove_window (old, move_window);
- meta_workspace_add_window (workspace, move_window);
- }
- }
-
- meta_workspace_queue_calc_showing (old);
- meta_workspace_queue_calc_showing (workspace);
-
- /* FIXME: Why do we need this?!? Isn't it handled in the lines above? */
- if (move_window)
- /* Removes window from other spaces */
- meta_window_change_workspace (move_window, workspace);
-
- if (focus_this)
- {
- meta_window_focus (focus_this, timestamp);
- meta_window_raise (focus_this);
- }
- else if (move_window)
- {
- meta_window_raise (move_window);
- }
- else
- {
- meta_topic (META_DEBUG_FOCUS, "Focusing default window on new workspace\n");
- meta_workspace_focus_default_window (workspace, NULL, timestamp);
- }
-}
-
-void
-meta_workspace_activate (MetaWorkspace *workspace,
- guint32 timestamp)
-{
- meta_workspace_activate_with_focus (workspace, NULL, timestamp);
-}
-
-int
-meta_workspace_index (MetaWorkspace *workspace)
-{
- int ret;
-
- ret = g_list_index (workspace->screen->workspaces, workspace);
-
- if (ret < 0)
- meta_bug ("Workspace does not exist to index!\n");
-
- return ret;
-}
-
-/* get windows contained on workspace, including workspace->windows
- * and also sticky windows.
- */
-GList*
-meta_workspace_list_windows (MetaWorkspace *workspace)
-{
- GSList *display_windows;
- GSList *tmp;
- GList *workspace_windows;
-
- display_windows = meta_display_list_windows (workspace->screen->display);
-
- workspace_windows = NULL;
- tmp = display_windows;
- while (tmp != NULL)
- {
- MetaWindow *window = tmp->data;
-
- if (meta_window_located_on_workspace (window, workspace))
- workspace_windows = g_list_prepend (workspace_windows,
- window);
-
- tmp = tmp->next;
- }
-
- g_slist_free (display_windows);
-
- return workspace_windows;
-}
-
-static void
-set_active_space_hint (MetaScreen *screen)
-{
- unsigned long data[1];
-
- /* this is because we destroy the spaces in order,
- * so we always end up setting a current desktop of
- * 0 when closing a screen, so lose the current desktop
- * on restart. By doing this we keep the current
- * desktop on restart.
- */
- if (screen->closing > 0)
- return;
-
- data[0] = meta_workspace_index (screen->active_workspace);
-
- meta_verbose ("Setting _NET_CURRENT_DESKTOP to %lu\n", data[0]);
-
- meta_error_trap_push (screen->display);
- XChangeProperty (screen->display->xdisplay, screen->xroot,
- screen->display->atom__NET_CURRENT_DESKTOP,
- XA_CARDINAL,
- 32, PropModeReplace, (guchar*) data, 1);
- meta_error_trap_pop (screen->display, FALSE);
-}
-
-void
-meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
-{
- GList *tmp;
- GList *windows;
- int i;
-
- if (workspace->work_areas_invalid)
- {
- meta_topic (META_DEBUG_WORKAREA,
- "Work area for workspace %d is already invalid\n",
- meta_workspace_index (workspace));
- return;
- }
-
- meta_topic (META_DEBUG_WORKAREA,
- "Invalidating work area for workspace %d\n",
- meta_workspace_index (workspace));
-
- g_free (workspace->work_area_xinerama);
- workspace->work_area_xinerama = NULL;
-
- workspace_free_struts (workspace);
-
- for (i = 0; i < workspace->screen->n_xinerama_infos; i++)
- meta_rectangle_free_list_and_elements (workspace->xinerama_region[i]);
- g_free (workspace->xinerama_region);
- meta_rectangle_free_list_and_elements (workspace->screen_region);
- meta_rectangle_free_list_and_elements (workspace->screen_edges);
- meta_rectangle_free_list_and_elements (workspace->xinerama_edges);
- workspace->xinerama_region = NULL;
- workspace->screen_region = NULL;
- workspace->screen_edges = NULL;
- workspace->xinerama_edges = NULL;
-
- workspace->work_areas_invalid = TRUE;
-
- /* redo the size/position constraints on all windows */
- windows = meta_workspace_list_windows (workspace);
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
-
- meta_window_queue (w, META_QUEUE_MOVE_RESIZE);
-
- tmp = tmp->next;
- }
-
- g_list_free (windows);
-
- meta_screen_queue_workarea_recalc (workspace->screen);
-}
-
-static void
-ensure_work_areas_validated (MetaWorkspace *workspace)
-{
- GList *windows;
- GList *tmp;
- MetaRectangle work_area;
- int i; /* C89 absolutely sucks... */
-
- if (!workspace->work_areas_invalid)
- return;
-
- g_assert (workspace->all_struts == NULL);
- g_assert (workspace->xinerama_region == NULL);
- g_assert (workspace->screen_region == NULL);
- g_assert (workspace->screen_edges == NULL);
- g_assert (workspace->xinerama_edges == NULL);
-
- /* STEP 1: Get the list of struts */
- windows = meta_workspace_list_windows (workspace);
- for (tmp = windows; tmp != NULL; tmp = tmp->next)
- {
- MetaWindow *win = tmp->data;
- GSList *s_iter;
-
- for (s_iter = win->struts; s_iter != NULL; s_iter = s_iter->next) {
- MetaStrut *cpy = g_new (MetaStrut, 1);
- *cpy = *((MetaStrut *)s_iter->data);
- workspace->all_struts = g_slist_prepend (workspace->all_struts,
- cpy);
- }
- }
- g_list_free (windows);
-
- /* STEP 2: Get the maximal/spanning rects for the onscreen and
- * on-single-xinerama regions
- */
- g_assert (workspace->xinerama_region == NULL);
- g_assert (workspace->screen_region == NULL);
-
- workspace->xinerama_region = g_new (GList*,
- workspace->screen->n_xinerama_infos);
- for (i = 0; i < workspace->screen->n_xinerama_infos; i++)
- {
- workspace->xinerama_region[i] =
- meta_rectangle_get_minimal_spanning_set_for_region (
- &workspace->screen->xinerama_infos[i].rect,
- workspace->all_struts);
- }
- workspace->screen_region =
- meta_rectangle_get_minimal_spanning_set_for_region (
- &workspace->screen->rect,
- workspace->all_struts);
-
- /* STEP 3: Get the work areas (region-to-maximize-to) for the screen and
- * xineramas.
- */
- work_area = workspace->screen->rect; /* start with the screen */
- if (workspace->screen_region == NULL)
- work_area = meta_rect (0, 0, -1, -1);
- else
- meta_rectangle_clip_to_region (workspace->screen_region,
- FIXED_DIRECTION_NONE,
- &work_area);
-
- /* Lots of paranoia checks, forcing work_area_screen to be sane */
-#define MIN_SANE_AREA 100
- if (work_area.width < MIN_SANE_AREA)
- {
- meta_warning ("struts occupy an unusually large percentage of the screen; "
- "available remaining width = %d < %d",
- work_area.width, MIN_SANE_AREA);
- if (work_area.width < 1)
- {
- work_area.x = (workspace->screen->rect.width - MIN_SANE_AREA)/2;
- work_area.width = MIN_SANE_AREA;
- }
- else
- {
- int amount = (MIN_SANE_AREA - work_area.width)/2;
- work_area.x -= amount;
- work_area.width += 2*amount;
- }
- }
- if (work_area.height < MIN_SANE_AREA)
- {
- meta_warning ("struts occupy an unusually large percentage of the screen; "
- "available remaining height = %d < %d",
- work_area.height, MIN_SANE_AREA);
- if (work_area.height < 1)
- {
- work_area.y = (workspace->screen->rect.height - MIN_SANE_AREA)/2;
- work_area.height = MIN_SANE_AREA;
- }
- else
- {
- int amount = (MIN_SANE_AREA - work_area.height)/2;
- work_area.y -= amount;
- work_area.height += 2*amount;
- }
- }
- workspace->work_area_screen = work_area;
- meta_topic (META_DEBUG_WORKAREA,
- "Computed work area for workspace %d: %d,%d %d x %d\n",
- meta_workspace_index (workspace),
- workspace->work_area_screen.x,
- workspace->work_area_screen.y,
- workspace->work_area_screen.width,
- workspace->work_area_screen.height);
-
- /* Now find the work areas for each xinerama */
- g_free (workspace->work_area_xinerama);
- workspace->work_area_xinerama = g_new (MetaRectangle,
- workspace->screen->n_xinerama_infos);
-
- for (i = 0; i < workspace->screen->n_xinerama_infos; i++)
- {
- work_area = workspace->screen->xinerama_infos[i].rect;
-
- if (workspace->xinerama_region[i] == NULL)
- /* FIXME: constraints.c untested with this, but it might be nice for
- * a screen reader or magnifier.
- */
- work_area = meta_rect (work_area.x, work_area.y, -1, -1);
- else
- meta_rectangle_clip_to_region (workspace->xinerama_region[i],
- FIXED_DIRECTION_NONE,
- &work_area);
-
- workspace->work_area_xinerama[i] = work_area;
- meta_topic (META_DEBUG_WORKAREA,
- "Computed work area for workspace %d "
- "xinerama %d: %d,%d %d x %d\n",
- meta_workspace_index (workspace),
- i,
- workspace->work_area_xinerama[i].x,
- workspace->work_area_xinerama[i].y,
- workspace->work_area_xinerama[i].width,
- workspace->work_area_xinerama[i].height);
- }
-
- /* STEP 4: Make sure the screen_region is nonempty (separate from step 2
- * since it relies on step 3).
- */
- if (workspace->screen_region == NULL)
- {
- MetaRectangle *nonempty_region;
- nonempty_region = g_new (MetaRectangle, 1);
- *nonempty_region = workspace->work_area_screen;
- workspace->screen_region = g_list_prepend (NULL, nonempty_region);
- }
-
- /* STEP 5: Cache screen and xinerama edges for edge resistance and snapping */
- g_assert (workspace->screen_edges == NULL);
- g_assert (workspace->xinerama_edges == NULL);
- workspace->screen_edges =
- meta_rectangle_find_onscreen_edges (&workspace->screen->rect,
- workspace->all_struts);
- tmp = NULL;
- for (i = 0; i < workspace->screen->n_xinerama_infos; i++)
- tmp = g_list_prepend (tmp, &workspace->screen->xinerama_infos[i].rect);
- workspace->xinerama_edges =
- meta_rectangle_find_nonintersected_xinerama_edges (tmp,
- workspace->all_struts);
- g_list_free (tmp);
-
- /* We're all done, YAAY! Record that everything has been validated. */
- workspace->work_areas_invalid = FALSE;
-}
-
-void
-meta_workspace_get_work_area_for_xinerama (MetaWorkspace *workspace,
- int which_xinerama,
- MetaRectangle *area)
-{
- g_assert (which_xinerama >= 0);
-
- ensure_work_areas_validated (workspace);
- g_assert (which_xinerama < workspace->screen->n_xinerama_infos);
-
- *area = workspace->work_area_xinerama[which_xinerama];
-}
-
-void
-meta_workspace_get_work_area_all_xineramas (MetaWorkspace *workspace,
- MetaRectangle *area)
-{
- ensure_work_areas_validated (workspace);
-
- *area = workspace->work_area_screen;
-}
-
-GList*
-meta_workspace_get_onscreen_region (MetaWorkspace *workspace)
-{
- ensure_work_areas_validated (workspace);
-
- return workspace->screen_region;
-}
-
-GList*
-meta_workspace_get_onxinerama_region (MetaWorkspace *workspace,
- int which_xinerama)
-{
- ensure_work_areas_validated (workspace);
-
- return workspace->xinerama_region[which_xinerama];
-}
-
-#ifdef WITH_VERBOSE_MODE
-static char *
-meta_motion_direction_to_string (MetaMotionDirection direction)
-{
- switch (direction)
- {
- case META_MOTION_UP:
- return "Up";
- case META_MOTION_DOWN:
- return "Down";
- case META_MOTION_LEFT:
- return "Left";
- case META_MOTION_RIGHT:
- return "Right";
- }
-
- return "Unknown";
-}
-#endif /* WITH_VERBOSE_MODE */
-
-MetaWorkspace*
-meta_workspace_get_neighbor (MetaWorkspace *workspace,
- MetaMotionDirection direction)
-{
- MetaWorkspaceLayout layout;
- int i, current_space, num_workspaces;
- gboolean ltr;
-
- current_space = meta_workspace_index (workspace);
- num_workspaces = meta_screen_get_n_workspaces (workspace->screen);
- meta_screen_calc_workspace_layout (workspace->screen, num_workspaces,
- current_space, &layout);
-
- meta_verbose ("Getting neighbor of %d in direction %s\n",
- current_space, meta_motion_direction_to_string (direction));
-
- ltr = meta_ui_get_direction() == META_UI_DIRECTION_LTR;
-
- switch (direction)
- {
- case META_MOTION_LEFT:
- layout.current_col -= ltr ? 1 : -1;
- break;
- case META_MOTION_RIGHT:
- layout.current_col += ltr ? 1 : -1;
- break;
- case META_MOTION_UP:
- layout.current_row -= 1;
- break;
- case META_MOTION_DOWN:
- layout.current_row += 1;
- break;
- }
-
- if (layout.current_col < 0)
- layout.current_col = 0;
- if (layout.current_col >= layout.cols)
- layout.current_col = layout.cols - 1;
- if (layout.current_row < 0)
- layout.current_row = 0;
- if (layout.current_row >= layout.rows)
- layout.current_row = layout.rows - 1;
-
- i = layout.grid[layout.current_row * layout.cols + layout.current_col];
-
- if (i < 0)
- i = current_space;
-
- if (i >= num_workspaces)
- meta_bug ("calc_workspace_layout left an invalid (too-high) workspace number %d in the grid\n",
- i);
-
- meta_verbose ("Neighbor workspace is %d at row %d col %d\n",
- i, layout.current_row, layout.current_col);
-
- meta_screen_free_workspace_layout (&layout);
-
- return meta_screen_get_workspace_by_index (workspace->screen, i);
-}
-
-const char*
-meta_workspace_get_name (MetaWorkspace *workspace)
-{
- return meta_prefs_get_workspace_name (meta_workspace_index (workspace));
-}
-
-void
-meta_workspace_focus_default_window (MetaWorkspace *workspace,
- MetaWindow *not_this_one,
- guint32 timestamp)
-{
- if (timestamp == CurrentTime)
- {
- meta_warning ("CurrentTime used to choose focus window; "
- "focus window may not be correct.\n");
- }
-
-
- if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK ||
- !workspace->screen->display->mouse_mode)
- focus_ancestor_or_mru_window (workspace, not_this_one, timestamp);
- else
- {
- MetaWindow * window;
- window = meta_screen_get_mouse_window (workspace->screen, not_this_one);
- if (window &&
- window->type != META_WINDOW_DOCK &&
- window->type != META_WINDOW_DESKTOP)
- {
- if (timestamp == CurrentTime)
- {
-
- /* We would like for this to never happen. However, if
- * it does happen then we kludge since using CurrentTime
- * can mean ugly race conditions--and we can avoid these
- * by allowing EnterNotify events (which come with
- * timestamps) to handle focus.
- */
-
- meta_topic (META_DEBUG_FOCUS,
- "Not focusing mouse window %s because EnterNotify events should handle that\n", window->desc);
- }
- else
- {
- meta_topic (META_DEBUG_FOCUS,
- "Focusing mouse window %s\n", window->desc);
- meta_window_focus (window, timestamp);
- }
-
- if (workspace->screen->display->autoraise_window != window &&
- meta_prefs_get_auto_raise ())
- {
- meta_display_queue_autoraise_callback (workspace->screen->display,
- window);
- }
- }
- else if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_SLOPPY)
- focus_ancestor_or_mru_window (workspace, not_this_one, timestamp);
- else if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_MOUSE)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Setting focus to no_focus_window, since no valid "
- "window to focus found.\n");
- meta_display_focus_the_no_focus_window (workspace->screen->display,
- workspace->screen,
- timestamp);
- }
- }
-}
-
-static gboolean
-record_ancestor (MetaWindow *window,
- void *data)
-{
- MetaWindow **result = data;
-
- *result = window;
- return FALSE; /* quit with the first ancestor we find */
-}
-
-/* Focus ancestor of not_this_one if there is one, otherwise focus the MRU
- * window on active workspace
- */
-static void
-focus_ancestor_or_mru_window (MetaWorkspace *workspace,
- MetaWindow *not_this_one,
- guint32 timestamp)
-{
- MetaWindow *window = NULL;
- MetaWindow *desktop_window = NULL;
- GList *tmp;
-
- if (not_this_one)
- meta_topic (META_DEBUG_FOCUS,
- "Focusing MRU window excluding %s\n", not_this_one->desc);
- else
- meta_topic (META_DEBUG_FOCUS,
- "Focusing MRU window\n");
-
- /* First, check to see if we need to focus an ancestor of a window */
- if (not_this_one)
- {
- MetaWindow *ancestor;
- ancestor = NULL;
- meta_window_foreach_ancestor (not_this_one, record_ancestor, &ancestor);
- if (ancestor != NULL)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Focusing %s, ancestor of %s\n",
- ancestor->desc, not_this_one->desc);
-
- meta_window_focus (ancestor, timestamp);
-
- /* Also raise the window if in click-to-focus */
- if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
- meta_window_raise (ancestor);
-
- return;
- }
- }
-
- /* No ancestor, look for the MRU window */
- tmp = workspace->mru_list;
-
- while (tmp)
- {
- MetaWindow* tmp_window;
- tmp_window = ((MetaWindow*) tmp->data);
- if (tmp_window != not_this_one &&
- meta_window_showing_on_its_workspace (tmp_window) &&
- tmp_window->type != META_WINDOW_DOCK &&
- tmp_window->type != META_WINDOW_DESKTOP)
- {
- window = tmp->data;
- break;
- }
- else if (tmp_window != not_this_one &&
- desktop_window == NULL &&
- meta_window_showing_on_its_workspace (tmp_window) &&
- tmp_window->type == META_WINDOW_DESKTOP)
- {
- /* Found the most recently used desktop window */
- desktop_window = tmp_window;
- }
-
- tmp = tmp->next;
- }
-
- /* If no window was found, default to the MRU desktop-window */
- if (window == NULL)
- window = desktop_window;
-
- if (window)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Focusing workspace MRU window %s\n", window->desc);
-
- meta_window_focus (window, timestamp);
-
- /* Also raise the window if in click-to-focus */
- if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
- meta_window_raise (window);
- }
- else
- {
- meta_topic (META_DEBUG_FOCUS, "No MRU window to focus found; focusing no_focus_window.\n");
- meta_display_focus_the_no_focus_window (workspace->screen->display,
- workspace->screen,
- timestamp);
- }
-}
diff --git a/src/core/workspace.h b/src/core/workspace.h
deleted file mode 100644
index f4079ebb..00000000
--- a/src/core/workspace.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * \file workspace.h Workspaces
- *
- * A workspace is a set of windows which all live on the same
- * screen. (You may also see the name "desktop" around the place,
- * which is the EWMH's name for the same thing.) Only one workspace
- * of a screen may be active at once; all windows on all other workspaces
- * are unmapped.
- */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2004, 2005 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_WORKSPACE_H
-#define META_WORKSPACE_H
-
-#include "window-private.h"
-
-/* Negative to avoid conflicting with real workspace
- * numbers
- */
-typedef enum
-{
- META_MOTION_UP = -1,
- META_MOTION_DOWN = -2,
- META_MOTION_LEFT = -3,
- META_MOTION_RIGHT = -4
-} MetaMotionDirection;
-
-struct _MetaWorkspace
-{
- MetaScreen *screen;
-
- GList *windows;
- GList *mru_list;
-
- GList *list_containing_self;
-
- MetaRectangle work_area_screen;
- MetaRectangle *work_area_xinerama;
- GList *screen_region;
- GList **xinerama_region;
- GList *screen_edges;
- GList *xinerama_edges;
- GSList *all_struts;
- guint work_areas_invalid : 1;
-
- guint showing_desktop : 1;
-};
-
-MetaWorkspace* meta_workspace_new (MetaScreen *screen);
-void meta_workspace_free (MetaWorkspace *workspace);
-void meta_workspace_add_window (MetaWorkspace *workspace,
- MetaWindow *window);
-void meta_workspace_remove_window (MetaWorkspace *workspace,
- MetaWindow *window);
-void meta_workspace_relocate_windows (MetaWorkspace *workspace,
- MetaWorkspace *new_home);
-void meta_workspace_activate_with_focus (MetaWorkspace *workspace,
- MetaWindow *focus_this,
- guint32 timestamp);
-void meta_workspace_activate (MetaWorkspace *workspace,
- guint32 timestamp);
-int meta_workspace_index (MetaWorkspace *workspace);
-GList* meta_workspace_list_windows (MetaWorkspace *workspace);
-
-void meta_workspace_invalidate_work_area (MetaWorkspace *workspace);
-
-
-void meta_workspace_get_work_area_for_xinerama (MetaWorkspace *workspace,
- int which_xinerama,
- MetaRectangle *area);
-void meta_workspace_get_work_area_all_xineramas (MetaWorkspace *workspace,
- MetaRectangle *area);
-GList* meta_workspace_get_onscreen_region (MetaWorkspace *workspace);
-GList* meta_workspace_get_onxinerama_region (MetaWorkspace *workspace,
- int which_xinerama);
-void meta_workspace_get_work_area_all_xineramas (MetaWorkspace *workspace,
- MetaRectangle *area);
-
-void meta_workspace_focus_default_window (MetaWorkspace *workspace,
- MetaWindow *not_this_one,
- guint32 timestamp);
-
-MetaWorkspace* meta_workspace_get_neighbor (MetaWorkspace *workspace,
- MetaMotionDirection direction);
-
-const char* meta_workspace_get_name (MetaWorkspace *workspace);
-
-#endif
-
-
-
-
diff --git a/src/core/xprops.c b/src/core/xprops.c
deleted file mode 100644
index a39c7b4f..00000000
--- a/src/core/xprops.c
+++ /dev/null
@@ -1,1238 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity X property convenience routines */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2002 Red Hat Inc.
- *
- * Some trivial property-unpacking code from Xlib:
- * Copyright 1987, 1988, 1998 The Open Group
- * Copyright 1988 by Wyse Technology, Inc., San Jose, Ca,
- * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-/***********************************************************
-Copyright 1988 by Wyse Technology, Inc., San Jose, Ca,
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL AND WYSE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-EVENT SHALL DIGITAL OR WYSE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
-USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
-******************************************************************/
-
-/*
-
-Copyright 1987, 1988, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-*/
-
-
-#include <config.h>
-#include "xprops.h"
-#include "errors.h"
-#include "util.h"
-#include "async-getprop.h"
-#include "ui.h"
-#include "metacity-Xatomtype.h"
-#include <X11/Xatom.h>
-#include <string.h>
-#include "window-private.h"
-
-typedef struct
-{
- MetaDisplay *display;
- Window xwindow;
- Atom xatom;
- Atom type;
- int format;
- unsigned long n_items;
- unsigned long bytes_after;
- unsigned char *prop;
-} GetPropertyResults;
-
-static gboolean
-validate_or_free_results (GetPropertyResults *results,
- int expected_format,
- Atom expected_type,
- gboolean must_have_items)
-{
- char *type_name;
- char *expected_name;
- char *prop_name;
- const char *title;
- const char *res_class;
- const char *res_name;
- MetaWindow *w;
-
- if (expected_format == results->format &&
- expected_type == results->type &&
- (!must_have_items || results->n_items > 0))
- return TRUE;
-
- meta_error_trap_push (results->display);
- type_name = XGetAtomName (results->display->xdisplay, results->type);
- expected_name = XGetAtomName (results->display->xdisplay, expected_type);
- prop_name = XGetAtomName (results->display->xdisplay, results->xatom);
- meta_error_trap_pop (results->display, TRUE);
-
- w = meta_display_lookup_x_window (results->display, results->xwindow);
-
- if (w != NULL)
- {
- title = w->title;
- res_class = w->res_class;
- res_name = w->res_name;
- }
- else
- {
- title = NULL;
- res_class = NULL;
- res_name = NULL;
- }
-
- if (title == NULL)
- title = "unknown";
-
- if (res_class == NULL)
- res_class = "unknown";
-
- if (res_name == NULL)
- res_name = "unknown";
-
- meta_warning (_("Window 0x%lx has property %s\nthat was expected to have type %s format %d\nand actually has type %s format %d n_items %d.\nThis is most likely an application bug, not a window manager bug.\nThe window has title=\"%s\" class=\"%s\" name=\"%s\"\n"),
- results->xwindow,
- prop_name ? prop_name : "(bad atom)",
- expected_name ? expected_name : "(bad atom)",
- expected_format,
- type_name ? type_name : "(bad atom)",
- results->format, (int) results->n_items,
- title, res_class, res_name);
-
- if (type_name)
- XFree (type_name);
- if (expected_name)
- XFree (expected_name);
- if (prop_name)
- XFree (prop_name);
-
- if (results->prop)
- {
- XFree (results->prop);
- results->prop = NULL;
- }
-
- return FALSE;
-}
-
-static gboolean
-get_property (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- Atom req_type,
- GetPropertyResults *results)
-{
- results->display = display;
- results->xwindow = xwindow;
- results->xatom = xatom;
- results->prop = NULL;
- results->n_items = 0;
- results->type = None;
- results->bytes_after = 0;
- results->format = 0;
-
- meta_error_trap_push_with_return (display);
- if (XGetWindowProperty (display->xdisplay, xwindow, xatom,
- 0, G_MAXLONG,
- False, req_type, &results->type, &results->format,
- &results->n_items,
- &results->bytes_after,
- &results->prop) != Success ||
- results->type == None)
- {
- if (results->prop)
- XFree (results->prop);
- meta_error_trap_pop_with_return (display, TRUE);
- return FALSE;
- }
-
- if (meta_error_trap_pop_with_return (display, TRUE) != Success)
- {
- if (results->prop)
- XFree (results->prop);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-atom_list_from_results (GetPropertyResults *results,
- Atom **atoms_p,
- int *n_atoms_p)
-{
- if (!validate_or_free_results (results, 32, XA_ATOM, FALSE))
- return FALSE;
-
- *atoms_p = (Atom*) results->prop;
- *n_atoms_p = results->n_items;
- results->prop = NULL;
-
- return TRUE;
-}
-
-gboolean
-meta_prop_get_atom_list (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- Atom **atoms_p,
- int *n_atoms_p)
-{
- GetPropertyResults results;
-
- *atoms_p = NULL;
- *n_atoms_p = 0;
-
- if (!get_property (display, xwindow, xatom, XA_ATOM,
- &results))
- return FALSE;
-
- return atom_list_from_results (&results, atoms_p, n_atoms_p);
-}
-
-static gboolean
-cardinal_list_from_results (GetPropertyResults *results,
- gulong **cardinals_p,
- int *n_cardinals_p)
-{
- if (!validate_or_free_results (results, 32, XA_CARDINAL, FALSE))
- return FALSE;
-
- *cardinals_p = (gulong*) results->prop;
- *n_cardinals_p = results->n_items;
- results->prop = NULL;
-
- return TRUE;
-}
-
-gboolean
-meta_prop_get_cardinal_list (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- gulong **cardinals_p,
- int *n_cardinals_p)
-{
- GetPropertyResults results;
-
- *cardinals_p = NULL;
- *n_cardinals_p = 0;
-
- if (!get_property (display, xwindow, xatom, XA_CARDINAL,
- &results))
- return FALSE;
-
- return cardinal_list_from_results (&results, cardinals_p, n_cardinals_p);
-}
-
-static gboolean
-motif_hints_from_results (GetPropertyResults *results,
- MotifWmHints **hints_p)
-{
- int real_size, max_size;
-#define MAX_ITEMS sizeof (MotifWmHints)/sizeof (gulong)
-
- *hints_p = NULL;
-
- if (results->type == None || results->n_items <= 0)
- {
- meta_verbose ("Motif hints had unexpected type or n_items\n");
- if (results->prop)
- {
- XFree (results->prop);
- results->prop = NULL;
- }
- return FALSE;
- }
-
- /* The issue here is that some old crufty code will set a smaller
- * MotifWmHints than the one we expect, apparently. I'm not sure of
- * the history behind it. See bug #89841 for example.
- */
- *hints_p = ag_Xmalloc (sizeof (MotifWmHints));
- if (*hints_p == NULL)
- {
- if (results->prop)
- {
- XFree (results->prop);
- results->prop = NULL;
- }
- return FALSE;
- }
- real_size = results->n_items * sizeof (gulong);
- max_size = MAX_ITEMS * sizeof (gulong);
- memcpy (*hints_p, results->prop, MIN (real_size, max_size));
-
- if (results->prop)
- {
- XFree (results->prop);
- results->prop = NULL;
- }
-
- return TRUE;
-}
-
-gboolean
-meta_prop_get_motif_hints (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- MotifWmHints **hints_p)
-{
- GetPropertyResults results;
-
- *hints_p = NULL;
-
- if (!get_property (display, xwindow, xatom, AnyPropertyType,
- &results))
- return FALSE;
-
- return motif_hints_from_results (&results, hints_p);
-}
-
-static gboolean
-latin1_string_from_results (GetPropertyResults *results,
- char **str_p)
-{
- *str_p = NULL;
-
- if (!validate_or_free_results (results, 8, XA_STRING, FALSE))
- return FALSE;
-
- *str_p = (char*) results->prop;
- results->prop = NULL;
-
- return TRUE;
-}
-
-gboolean
-meta_prop_get_latin1_string (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- char **str_p)
-{
- GetPropertyResults results;
-
- *str_p = NULL;
-
- if (!get_property (display, xwindow, xatom, XA_STRING,
- &results))
- return FALSE;
-
- return latin1_string_from_results (&results, str_p);
-}
-
-static gboolean
-utf8_string_from_results (GetPropertyResults *results,
- char **str_p)
-{
- *str_p = NULL;
-
- if (!validate_or_free_results (results, 8,
- results->display->atom_UTF8_STRING, FALSE))
- return FALSE;
-
- if (results->n_items > 0 &&
- !g_utf8_validate ((gchar *)results->prop, results->n_items, NULL))
- {
- char *name;
-
- name = XGetAtomName (results->display->xdisplay, results->xatom);
- meta_warning (_("Property %s on window 0x%lx contained invalid UTF-8\n"),
- name, results->xwindow);
- meta_XFree (name);
- XFree (results->prop);
- results->prop = NULL;
-
- return FALSE;
- }
-
- *str_p = (char*) results->prop;
- results->prop = NULL;
-
- return TRUE;
-}
-
-gboolean
-meta_prop_get_utf8_string (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- char **str_p)
-{
- GetPropertyResults results;
-
- *str_p = NULL;
-
- if (!get_property (display, xwindow, xatom,
- display->atom_UTF8_STRING,
- &results))
- return FALSE;
-
- return utf8_string_from_results (&results, str_p);
-}
-
-/* this one freakishly returns g_malloc memory */
-static gboolean
-utf8_list_from_results (GetPropertyResults *results,
- char ***str_p,
- int *n_str_p)
-{
- int i;
- int n_strings;
- char **retval;
- const char *p;
-
- *str_p = NULL;
- *n_str_p = 0;
-
- if (!validate_or_free_results (results, 8,
- results->display->atom_UTF8_STRING, FALSE))
- return FALSE;
-
- /* I'm not sure this is right, but I'm guessing the
- * property is nul-separated
- */
- i = 0;
- n_strings = 0;
- while (i < (int) results->n_items)
- {
- if (results->prop[i] == '\0')
- ++n_strings;
- ++i;
- }
-
- if (results->prop[results->n_items - 1] != '\0')
- ++n_strings;
-
- /* we're guaranteed that results->prop has a nul on the end
- * by XGetWindowProperty
- */
-
- retval = g_new0 (char*, n_strings + 1);
-
- p = (char *)results->prop;
- i = 0;
- while (i < n_strings)
- {
- if (!g_utf8_validate (p, -1, NULL))
- {
- char *name;
-
- meta_error_trap_push (results->display);
- name = XGetAtomName (results->display->xdisplay, results->xatom);
- meta_error_trap_pop (results->display, TRUE);
- meta_warning (_("Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n"),
- name, results->xwindow, i);
- meta_XFree (name);
- meta_XFree (results->prop);
- results->prop = NULL;
-
- g_strfreev (retval);
- return FALSE;
- }
-
- retval[i] = g_strdup (p);
-
- p = p + strlen (p) + 1;
- ++i;
- }
-
- *str_p = retval;
- *n_str_p = i;
-
- meta_XFree (results->prop);
- results->prop = NULL;
-
- return TRUE;
-}
-
-/* returns g_malloc not Xmalloc memory */
-gboolean
-meta_prop_get_utf8_list (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- char ***str_p,
- int *n_str_p)
-{
- GetPropertyResults results;
-
- *str_p = NULL;
-
- if (!get_property (display, xwindow, xatom,
- display->atom_UTF8_STRING,
- &results))
- return FALSE;
-
- return utf8_list_from_results (&results, str_p, n_str_p);
-}
-
-void
-meta_prop_set_utf8_string_hint (MetaDisplay *display,
- Window xwindow,
- Atom atom,
- const char *val)
-{
- meta_error_trap_push (display);
- XChangeProperty (display->xdisplay,
- xwindow, atom,
- display->atom_UTF8_STRING,
- 8, PropModeReplace, (guchar*) val, strlen (val));
- meta_error_trap_pop (display, FALSE);
-}
-
-static gboolean
-window_from_results (GetPropertyResults *results,
- Window *window_p)
-{
- if (!validate_or_free_results (results, 32, XA_WINDOW, TRUE))
- return FALSE;
-
- *window_p = *(Window*) results->prop;
- XFree (results->prop);
- results->prop = NULL;
-
- return TRUE;
-}
-
-#ifdef HAVE_XSYNC
-static gboolean
-counter_from_results (GetPropertyResults *results,
- XSyncCounter *counter_p)
-{
- if (!validate_or_free_results (results, 32,
- XA_CARDINAL,
- TRUE))
- return FALSE;
-
- *counter_p = *(XSyncCounter*) results->prop;
- XFree (results->prop);
- results->prop = NULL;
-
- return TRUE;
-}
-#endif
-
-gboolean
-meta_prop_get_window (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- Window *window_p)
-{
- GetPropertyResults results;
-
- *window_p = None;
-
- if (!get_property (display, xwindow, xatom, XA_WINDOW,
- &results))
- return FALSE;
-
- return window_from_results (&results, window_p);
-}
-
-gboolean
-meta_prop_get_cardinal (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- gulong *cardinal_p)
-{
- return meta_prop_get_cardinal_with_atom_type (display, xwindow, xatom,
- XA_CARDINAL, cardinal_p);
-}
-
-static gboolean
-cardinal_with_atom_type_from_results (GetPropertyResults *results,
- Atom prop_type,
- gulong *cardinal_p)
-{
- if (!validate_or_free_results (results, 32, prop_type, TRUE))
- return FALSE;
-
- *cardinal_p = *(gulong*) results->prop;
- XFree (results->prop);
- results->prop = NULL;
-
- return TRUE;
-}
-
-gboolean
-meta_prop_get_cardinal_with_atom_type (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- Atom prop_type,
- gulong *cardinal_p)
-{
- GetPropertyResults results;
-
- *cardinal_p = 0;
-
- if (!get_property (display, xwindow, xatom, prop_type,
- &results))
- return FALSE;
-
- return cardinal_with_atom_type_from_results (&results, prop_type, cardinal_p);
-}
-
-static gboolean
-text_property_from_results (GetPropertyResults *results,
- char **utf8_str_p)
-{
- XTextProperty tp;
-
- *utf8_str_p = NULL;
-
- tp.value = results->prop;
- results->prop = NULL;
- tp.encoding = results->type;
- tp.format = results->format;
- tp.nitems = results->n_items;
-
- *utf8_str_p = meta_text_property_to_utf8 (results->display->xdisplay,
- &tp);
-
- if (tp.value != NULL)
- XFree (tp.value);
-
- return *utf8_str_p != NULL;
-}
-
-gboolean
-meta_prop_get_text_property (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- char **utf8_str_p)
-{
- GetPropertyResults results;
-
- if (!get_property (display, xwindow, xatom, AnyPropertyType,
- &results))
- return FALSE;
-
- return text_property_from_results (&results, utf8_str_p);
-}
-
-/* From Xmd.h */
-#ifndef cvtINT32toInt
-#if SIZEOF_VOID_P == 8
-#define cvtINT8toInt(val) ((((unsigned int)val) & 0x00000080) ? (((unsigned int)val) | 0xffffffffffffff00) : ((unsigned int)val))
-#define cvtINT16toInt(val) ((((unsigned int)val) & 0x00008000) ? (((unsigned int)val) | 0xffffffffffff0000) : ((unsigned int)val))
-#define cvtINT32toInt(val) ((((unsigned int)val) & 0x80000000) ? (((unsigned int)val) | 0xffffffff00000000) : ((unsigned int)val))
-#define cvtINT8toShort(val) cvtINT8toInt(val)
-#define cvtINT16toShort(val) cvtINT16toInt(val)
-#define cvtINT32toShort(val) cvtINT32toInt(val)
-#define cvtINT8toLong(val) cvtINT8toInt(val)
-#define cvtINT16toLong(val) cvtINT16toInt(val)
-#define cvtINT32toLong(val) cvtINT32toInt(val)
-#else
-#define cvtINT8toInt(val) (val)
-#define cvtINT16toInt(val) (val)
-#define cvtINT32toInt(val) (val)
-#define cvtINT8toShort(val) (val)
-#define cvtINT16toShort(val) (val)
-#define cvtINT32toShort(val) (val)
-#define cvtINT8toLong(val) (val)
-#define cvtINT16toLong(val) (val)
-#define cvtINT32toLong(val) (val)
-#endif /* SIZEOF_VOID_P == 8 */
-#endif /* cvtINT32toInt() */
-
-static gboolean
-wm_hints_from_results (GetPropertyResults *results,
- XWMHints **hints_p)
-{
- XWMHints *hints;
- xPropWMHints *raw;
-
- *hints_p = NULL;
-
- if (!validate_or_free_results (results, 32, XA_WM_HINTS, TRUE))
- return FALSE;
-
- /* pre-R3 bogusly truncated window_group, don't fail on them */
- if (results->n_items < (NumPropWMHintsElements - 1))
- {
- meta_verbose ("WM_HINTS property too short: %d should be %d\n",
- (int) results->n_items, NumPropWMHintsElements - 1);
- if (results->prop)
- {
- XFree (results->prop);
- results->prop = NULL;
- }
- return FALSE;
- }
-
- hints = ag_Xmalloc0 (sizeof (XWMHints));
-
- raw = (xPropWMHints*) results->prop;
-
- hints->flags = raw->flags;
- hints->input = (raw->input ? True : False);
- hints->initial_state = cvtINT32toInt (raw->initialState);
- hints->icon_pixmap = raw->iconPixmap;
- hints->icon_window = raw->iconWindow;
- hints->icon_x = cvtINT32toInt (raw->iconX);
- hints->icon_y = cvtINT32toInt (raw->iconY);
- hints->icon_mask = raw->iconMask;
- if (results->n_items >= NumPropWMHintsElements)
- hints->window_group = raw->windowGroup;
- else
- hints->window_group = 0;
-
- if (results->prop)
- {
- XFree (results->prop);
- results->prop = NULL;
- }
-
- *hints_p = hints;
-
- return TRUE;
-}
-
-gboolean
-meta_prop_get_wm_hints (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- XWMHints **hints_p)
-{
- GetPropertyResults results;
-
- *hints_p = NULL;
-
- if (!get_property (display, xwindow, xatom, XA_WM_HINTS,
- &results))
- return FALSE;
-
- return wm_hints_from_results (&results, hints_p);
-}
-
-static gboolean
-class_hint_from_results (GetPropertyResults *results,
- XClassHint *class_hint)
-{
- int len_name, len_class;
-
- class_hint->res_class = NULL;
- class_hint->res_name = NULL;
-
- if (!validate_or_free_results (results, 8, XA_STRING, FALSE))
- return FALSE;
-
- len_name = strlen ((char *) results->prop);
- if (! (class_hint->res_name = ag_Xmalloc (len_name+1)))
- {
- XFree (results->prop);
- results->prop = NULL;
- return FALSE;
- }
-
- strcpy (class_hint->res_name, (char *)results->prop);
-
- if (len_name == (int) results->n_items)
- len_name--;
-
- len_class = strlen ((char *)results->prop + len_name + 1);
-
- if (! (class_hint->res_class = ag_Xmalloc(len_class+1)))
- {
- XFree(class_hint->res_name);
- class_hint->res_name = NULL;
- XFree (results->prop);
- results->prop = NULL;
- return FALSE;
- }
-
- strcpy (class_hint->res_class, (char *)results->prop + len_name + 1);
-
- XFree (results->prop);
- results->prop = NULL;
-
- return TRUE;
-}
-
-gboolean
-meta_prop_get_class_hint (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- XClassHint *class_hint)
-{
- GetPropertyResults results;
-
- class_hint->res_class = NULL;
- class_hint->res_name = NULL;
-
- if (!get_property (display, xwindow, xatom, XA_STRING,
- &results))
- return FALSE;
-
- return class_hint_from_results (&results, class_hint);
-}
-
-static gboolean
-size_hints_from_results (GetPropertyResults *results,
- XSizeHints **hints_p,
- gulong *flags_p)
-{
- xPropSizeHints *raw;
- XSizeHints *hints;
-
- *hints_p = NULL;
- *flags_p = 0;
-
- if (!validate_or_free_results (results, 32, XA_WM_SIZE_HINTS, FALSE))
- return FALSE;
-
- if (results->n_items < OldNumPropSizeElements)
- return FALSE;
-
- raw = (xPropSizeHints*) results->prop;
-
- hints = ag_Xmalloc (sizeof (XSizeHints));
-
- /* XSizeHints misdeclares these as int instead of long */
- hints->flags = raw->flags;
- hints->x = cvtINT32toInt (raw->x);
- hints->y = cvtINT32toInt (raw->y);
- hints->width = cvtINT32toInt (raw->width);
- hints->height = cvtINT32toInt (raw->height);
- hints->min_width = cvtINT32toInt (raw->minWidth);
- hints->min_height = cvtINT32toInt (raw->minHeight);
- hints->max_width = cvtINT32toInt (raw->maxWidth);
- hints->max_height = cvtINT32toInt (raw->maxHeight);
- hints->width_inc = cvtINT32toInt (raw->widthInc);
- hints->height_inc = cvtINT32toInt (raw->heightInc);
- hints->min_aspect.x = cvtINT32toInt (raw->minAspectX);
- hints->min_aspect.y = cvtINT32toInt (raw->minAspectY);
- hints->max_aspect.x = cvtINT32toInt (raw->maxAspectX);
- hints->max_aspect.y = cvtINT32toInt (raw->maxAspectY);
-
- *flags_p = (USPosition | USSize | PAllHints);
- if (results->n_items >= NumPropSizeElements)
- {
- hints->base_width= cvtINT32toInt (raw->baseWidth);
- hints->base_height= cvtINT32toInt (raw->baseHeight);
- hints->win_gravity= cvtINT32toInt (raw->winGravity);
- *flags_p |= (PBaseSize | PWinGravity);
- }
-
- hints->flags &= (*flags_p); /* get rid of unwanted bits */
-
- XFree (results->prop);
- results->prop = NULL;
-
- *hints_p = hints;
-
- return TRUE;
-}
-
-gboolean
-meta_prop_get_size_hints (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- XSizeHints **hints_p,
- gulong *flags_p)
-{
- GetPropertyResults results;
-
- *hints_p = NULL;
- *flags_p = 0;
-
- if (!get_property (display, xwindow, xatom, XA_WM_SIZE_HINTS,
- &results))
- return FALSE;
-
- return size_hints_from_results (&results, hints_p, flags_p);
-}
-
-static AgGetPropertyTask*
-get_task (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- Atom req_type)
-{
- return ag_task_create (display->xdisplay,
- xwindow,
- xatom, 0, G_MAXLONG,
- False, req_type);
-}
-
-static char*
-latin1_to_utf8 (const char *text)
-{
- GString *str;
- const char *p;
-
- str = g_string_new ("");
-
- p = text;
- while (*p)
- {
- g_string_append_unichar (str, *p);
- ++p;
- }
-
- return g_string_free (str, FALSE);
-}
-
-void
-meta_prop_get_values (MetaDisplay *display,
- Window xwindow,
- MetaPropValue *values,
- int n_values)
-{
- int i;
- AgGetPropertyTask **tasks;
-
- meta_verbose ("Requesting %d properties of 0x%lx at once\n",
- n_values, xwindow);
-
- if (n_values == 0)
- return;
-
- tasks = g_new0 (AgGetPropertyTask*, n_values);
-
- /* Start up tasks. The "values" array can have values
- * with atom == None, which means to ignore that element.
- */
- i = 0;
- while (i < n_values)
- {
- if (values[i].required_type == None)
- {
- switch (values[i].type)
- {
- case META_PROP_VALUE_INVALID:
- /* This means we don't really want a value, e.g. got
- * property notify on an atom we don't care about.
- */
- if (values[i].atom != None)
- meta_bug ("META_PROP_VALUE_INVALID requested in %s\n", G_STRFUNC);
- break;
- case META_PROP_VALUE_UTF8_LIST:
- case META_PROP_VALUE_UTF8:
- values[i].required_type = display->atom_UTF8_STRING;
- break;
- case META_PROP_VALUE_STRING:
- case META_PROP_VALUE_STRING_AS_UTF8:
- values[i].required_type = XA_STRING;
- break;
- case META_PROP_VALUE_MOTIF_HINTS:
- values[i].required_type = AnyPropertyType;
- break;
- case META_PROP_VALUE_CARDINAL_LIST:
- case META_PROP_VALUE_CARDINAL:
- values[i].required_type = XA_CARDINAL;
- break;
- case META_PROP_VALUE_WINDOW:
- values[i].required_type = XA_WINDOW;
- break;
- case META_PROP_VALUE_ATOM_LIST:
- values[i].required_type = XA_ATOM;
- break;
- case META_PROP_VALUE_TEXT_PROPERTY:
- values[i].required_type = AnyPropertyType;
- break;
- case META_PROP_VALUE_WM_HINTS:
- values[i].required_type = XA_WM_HINTS;
- break;
- case META_PROP_VALUE_CLASS_HINT:
- values[i].required_type = XA_STRING;
- break;
- case META_PROP_VALUE_SIZE_HINTS:
- values[i].required_type = XA_WM_SIZE_HINTS;
- break;
- case META_PROP_VALUE_SYNC_COUNTER:
- values[i].required_type = XA_CARDINAL;
- break;
- }
- }
-
- if (values[i].atom != None)
- tasks[i] = get_task (display, xwindow,
- values[i].atom, values[i].required_type);
-
- ++i;
- }
-
- /* Get replies for all our tasks */
- meta_topic (META_DEBUG_SYNC, "Syncing to get %d GetProperty replies in %s\n",
- n_values, G_STRFUNC);
- XSync (display->xdisplay, False);
-
- /* Collect results, should arrive in order requested */
- i = 0;
- while (i < n_values)
- {
- AgGetPropertyTask *task;
- GetPropertyResults results;
-
- if (tasks[i] == NULL)
- {
- /* Probably values[i].type was None, or ag_task_create()
- * returned NULL.
- */
- values[i].type = META_PROP_VALUE_INVALID;
- goto next;
- }
-
- task = ag_get_next_completed_task (display->xdisplay);
- g_assert (task != NULL);
- g_assert (ag_task_have_reply (task));
-
- results.display = display;
- results.xwindow = xwindow;
- results.xatom = values[i].atom;
- results.prop = NULL;
- results.n_items = 0;
- results.type = None;
- results.bytes_after = 0;
- results.format = 0;
-
- if (ag_task_get_reply_and_free (task,
- &results.type, &results.format,
- &results.n_items,
- &results.bytes_after,
- &results.prop) != Success ||
- results.type == None)
- {
- values[i].type = META_PROP_VALUE_INVALID;
- if (results.prop)
- {
- XFree (results.prop);
- results.prop = NULL;
- }
- goto next;
- }
-
- switch (values[i].type)
- {
- case META_PROP_VALUE_INVALID:
- g_assert_not_reached ();
- break;
- case META_PROP_VALUE_UTF8_LIST:
- if (!utf8_list_from_results (&results,
- &values[i].v.string_list.strings,
- &values[i].v.string_list.n_strings))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_UTF8:
- if (!utf8_string_from_results (&results,
- &values[i].v.str))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_STRING:
- if (!latin1_string_from_results (&results,
- &values[i].v.str))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_STRING_AS_UTF8:
- if (!latin1_string_from_results (&results,
- &values[i].v.str))
- values[i].type = META_PROP_VALUE_INVALID;
- else
- {
- char *new_str;
- char *xmalloc_new_str;
-
- new_str = latin1_to_utf8 (values[i].v.str);
- xmalloc_new_str = ag_Xmalloc (strlen (new_str) + 1);
- if (xmalloc_new_str != NULL)
- {
- strcpy (xmalloc_new_str, new_str);
- meta_XFree (values[i].v.str);
- values[i].v.str = xmalloc_new_str;
- }
-
- g_free (new_str);
- }
- break;
- case META_PROP_VALUE_MOTIF_HINTS:
- if (!motif_hints_from_results (&results,
- &values[i].v.motif_hints))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_CARDINAL_LIST:
- if (!cardinal_list_from_results (&results,
- &values[i].v.cardinal_list.cardinals,
- &values[i].v.cardinal_list.n_cardinals))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_CARDINAL:
- if (!cardinal_with_atom_type_from_results (&results,
- values[i].required_type,
- &values[i].v.cardinal))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_WINDOW:
- if (!window_from_results (&results,
- &values[i].v.xwindow))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_ATOM_LIST:
- if (!atom_list_from_results (&results,
- &values[i].v.atom_list.atoms,
- &values[i].v.atom_list.n_atoms))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_TEXT_PROPERTY:
- if (!text_property_from_results (&results, &values[i].v.str))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_WM_HINTS:
- if (!wm_hints_from_results (&results, &values[i].v.wm_hints))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_CLASS_HINT:
- if (!class_hint_from_results (&results, &values[i].v.class_hint))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_SIZE_HINTS:
- if (!size_hints_from_results (&results,
- &values[i].v.size_hints.hints,
- &values[i].v.size_hints.flags))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_SYNC_COUNTER:
-#ifdef HAVE_XSYNC
- if (!counter_from_results (&results,
- &values[i].v.xcounter))
- values[i].type = META_PROP_VALUE_INVALID;
-#else
- values[i].type = META_PROP_VALUE_INVALID;
- if (results.prop)
- {
- XFree (results.prop);
- results.prop = NULL;
- }
-#endif
- break;
- }
-
- next:
- ++i;
- }
-
- g_free (tasks);
-}
-
-static void
-free_value (MetaPropValue *value)
-{
- switch (value->type)
- {
- case META_PROP_VALUE_INVALID:
- break;
- case META_PROP_VALUE_UTF8:
- case META_PROP_VALUE_STRING:
- case META_PROP_VALUE_STRING_AS_UTF8:
- meta_XFree (value->v.str);
- break;
- case META_PROP_VALUE_MOTIF_HINTS:
- meta_XFree (value->v.motif_hints);
- break;
- case META_PROP_VALUE_CARDINAL:
- break;
- case META_PROP_VALUE_WINDOW:
- break;
- case META_PROP_VALUE_ATOM_LIST:
- meta_XFree (value->v.atom_list.atoms);
- break;
- case META_PROP_VALUE_TEXT_PROPERTY:
- meta_XFree (value->v.str);
- break;
- case META_PROP_VALUE_WM_HINTS:
- meta_XFree (value->v.wm_hints);
- break;
- case META_PROP_VALUE_CLASS_HINT:
- meta_XFree (value->v.class_hint.res_class);
- meta_XFree (value->v.class_hint.res_name);
- break;
- case META_PROP_VALUE_SIZE_HINTS:
- meta_XFree (value->v.size_hints.hints);
- break;
- case META_PROP_VALUE_UTF8_LIST:
- g_strfreev (value->v.string_list.strings);
- break;
- case META_PROP_VALUE_CARDINAL_LIST:
- meta_XFree (value->v.cardinal_list.cardinals);
- break;
- case META_PROP_VALUE_SYNC_COUNTER:
- break;
- }
-}
-
-void
-meta_prop_free_values (MetaPropValue *values,
- int n_values)
-{
- int i;
-
- i = 0;
- while (i < n_values)
- {
- free_value (&values[i]);
- ++i;
- }
-
- /* Zero the whole thing to quickly detect breakage */
- memset (values, '\0', sizeof (MetaPropValue) * n_values);
-}
diff --git a/src/default_icon.png b/src/default_icon.png
deleted file mode 100644
index 5aad8798..00000000
--- a/src/default_icon.png
+++ /dev/null
Binary files differ
diff --git a/src/include/all-keybindings.h b/src/include/all-keybindings.h
deleted file mode 100644
index aa509576..00000000
--- a/src/include/all-keybindings.h
+++ /dev/null
@@ -1,386 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2008 Thomas Thurman
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-/**
- * A list of screen keybinding information.
- *
- * Each action which can have a keystroke bound to it is listed below.
- * To use this file, define keybind() to be a seven-argument macro (you can
- * throw any of the arguments you please away), include this file,
- * and then undefine the macro again.
- *
- * (If you aren't familiar with this technique, sometimes called "x-macros",
- * see DDJ of May 2001: <http://www.ddj.com/cpp/184401387>.)
- *
- * This makes it possible to keep all information about all the keybindings
- * in the same place. The only exception is the code to run when an action
- * is actually invoked; while we *could* have put that in this file, it would
- * have made debugging ridiculously difficult. Instead, each action should
- * have a corresponding static function named handle_<name>() in
- * keybindings.c.
- *
- * The arguments to keybind() are:
- * 1) the name of the binding; a bareword identifier
- * (it's fine if it happens to clash with a C reserved word)
- * 2) the name of the function which implements it.
- * Clearly we could have guessed this from the binding very often,
- * but we choose to write it in full for the benefit of grep.
- * 3) an integer parameter to pass to the handler
- * 4) a set of boolean flags, ORed together:
- * BINDING_PER_WINDOW - this is a window-based binding.
- * It is only valid if there is a
- * current window, and will operate in
- * some way on that window.
- * BINDING_REVERSES - the binding can reverse if you hold down Shift
- * BINDING_IS_REVERSED - the same, but the senses are reversed from the
- * handler's point of view (let me know if I should
- * explain this better)
- * or 0 if no flag applies.
- *
- * 5) a string representing the default binding.
- * If this is NULL, the action is unbound by default.
- * Please use NULL and not "disabled".
- * 6) a short description.
- * It must be marked translatable (i.e. inside "_(...)").
- *
- * Don't try to do XML entity escaping anywhere in the strings.
- */
-
-#ifndef keybind
-#error "keybind () must be defined when you include screen-bindings.h"
-#endif
-
-/***********************************/
-
-#ifndef _BINDINGS_DEFINED_CONSTANTS
-#define _BINDINGS_DEFINED_CONSTANTS 1
-
-#define BINDING_PER_WINDOW 0x01
-#define BINDING_REVERSES 0x02
-#define BINDING_IS_REVERSED 0x04
-
-#endif /* _BINDINGS_DEFINED_CONSTANTS */
-
-/***********************************/
-
-/* convenience, since in this file they must always be set together */
-#define REVERSES_AND_REVERSED (BINDING_REVERSES | BINDING_IS_REVERSED)
-
-keybind (switch_to_workspace_1, handle_switch_to_workspace, 0, 0, NULL,
- _("Switch to workspace 1"))
-keybind (switch_to_workspace_2, handle_switch_to_workspace, 1, 0, NULL,
- _("Switch to workspace 2"))
-keybind (switch_to_workspace_3, handle_switch_to_workspace, 2, 0, NULL,
- _("Switch to workspace 3"))
-keybind (switch_to_workspace_4, handle_switch_to_workspace, 3, 0, NULL,
- _("Switch to workspace 4"))
-keybind (switch_to_workspace_5, handle_switch_to_workspace, 4, 0, NULL,
- _("Switch to workspace 5"))
-keybind (switch_to_workspace_6, handle_switch_to_workspace, 5, 0, NULL,
- _("Switch to workspace 6"))
-keybind (switch_to_workspace_7, handle_switch_to_workspace, 6, 0, NULL,
- _("Switch to workspace 7"))
-keybind (switch_to_workspace_8, handle_switch_to_workspace, 7, 0, NULL,
- _("Switch to workspace 8"))
-keybind (switch_to_workspace_9, handle_switch_to_workspace, 8, 0, NULL,
- _("Switch to workspace 9"))
-keybind (switch_to_workspace_10, handle_switch_to_workspace, 9, 0, NULL,
- _("Switch to workspace 10"))
-keybind (switch_to_workspace_11, handle_switch_to_workspace, 10, 0, NULL,
- _("Switch to workspace 11"))
-keybind (switch_to_workspace_12, handle_switch_to_workspace, 11, 0, NULL,
- _("Switch to workspace 12"))
-
-/* META_MOTION_* are negative, and so distinct from workspace numbers,
- * which are always zero or positive.
- * If you make use of these constants, you will need to include workspace.h
- * (which you're probably using already for other reasons anyway).
- * If your definition of keybind() throws them away, you don't need to include
- * workspace.h, of course.
- */
-
-keybind (switch_to_workspace_left, handle_switch_to_workspace,
- META_MOTION_LEFT, 0, "<Control><Alt>Left",
- _("Switch to workspace on the left of the current workspace"))
-
-keybind (switch_to_workspace_right, handle_switch_to_workspace,
- META_MOTION_RIGHT, 0, "<Control><Alt>Right",
- _("Switch to workspace on the right of the current workspace"))
-
-keybind (switch_to_workspace_up, handle_switch_to_workspace,
- META_MOTION_UP, 0, "<Control><Alt>Up",
- _("Switch to workspace above the current workspace"))
-
-keybind (switch_to_workspace_down, handle_switch_to_workspace,
- META_MOTION_DOWN, 0, "<Control><Alt>Down",
- _("Switch to workspace below the current workspace"))
-
-/***********************************/
-
-/* The ones which have inverses. These can't be bound to any keystroke
- * containing Shift because Shift will invert their "backward" state.
- *
- * TODO: "NORMAL" and "DOCKS" should be renamed to the same name as their
- * action, for obviousness.
- *
- * TODO: handle_switch and handle_cycle should probably really be the
- * same function checking a bit in the parameter for difference.
- */
-
-keybind (switch_group, handle_switch, META_TAB_LIST_GROUP,
- BINDING_REVERSES, NULL,
- _("Move between windows of an application, using a popup window"))
-keybind (switch_group_backward, handle_switch, META_TAB_LIST_GROUP,
- REVERSES_AND_REVERSED, NULL,
- _("Move backward between windows of an application, "
- "using a popup window"))
-keybind (switch_windows, handle_switch, META_TAB_LIST_NORMAL,
- BINDING_REVERSES, "<Alt>Tab",
- _("Move between windows, using a popup window"))
-keybind (switch_windows_backward, handle_switch, META_TAB_LIST_NORMAL,
- REVERSES_AND_REVERSED, NULL,
- _("Move backward between windows, using a popup window"))
-keybind (switch_panels, handle_switch, META_TAB_LIST_DOCKS,
- BINDING_REVERSES, "<Control><Alt>Tab",
- _("Move between panels and the desktop, using a popup window"))
-keybind (switch_panels_backward, handle_switch, META_TAB_LIST_DOCKS,
- REVERSES_AND_REVERSED, NULL,
- _("Move backward between panels and the desktop, "
- "using a popup window"))
-
-keybind (cycle_group, handle_cycle, META_TAB_LIST_GROUP,
- BINDING_REVERSES, "<Alt>F6",
- _("Move between windows of an application immediately"))
-keybind (cycle_group_backward, handle_cycle, META_TAB_LIST_GROUP,
- REVERSES_AND_REVERSED, NULL,
- _("Move backward between windows of an application immediately"))
-keybind (cycle_windows, handle_cycle, META_TAB_LIST_NORMAL,
- BINDING_REVERSES, "<Alt>Escape",
- _("Move between windows immediately"))
-keybind (cycle_windows_backward, handle_cycle, META_TAB_LIST_NORMAL,
- REVERSES_AND_REVERSED, NULL,
- _("Move backward between windows immediately"))
-keybind (cycle_panels, handle_cycle, META_TAB_LIST_DOCKS,
- BINDING_REVERSES, "<Control><Alt>Escape",
- _("Move between panels and the desktop immediately"))
-keybind (cycle_panels_backward, handle_cycle, META_TAB_LIST_DOCKS,
- REVERSES_AND_REVERSED, NULL,
- _("Move backward between panels and the desktop immediately"))
-
-/***********************************/
-
-keybind (show_desktop, handle_show_desktop, 0, 0, "<Control><Alt>d",
- _("Hide all normal windows and set focus to the desktop background"))
-keybind (panel_main_menu, handle_panel,
- META_KEYBINDING_ACTION_PANEL_MAIN_MENU, 0, "<Alt>F1",
- _("Show the panel's main menu"))
-keybind (panel_run_dialog, handle_panel,
- META_KEYBINDING_ACTION_PANEL_RUN_DIALOG, 0, "<Alt>F2",
- _("Show the panel's \"Run Application\" dialog box"))
-
-/* Yes, the param is offset by one. Historical reasons. (Maybe worth fixing
- * at some point.) The description is NULL here because the stanza is
- * irregularly shaped in metacity.schemas.in. This will probably be fixed
- * as well.
- */
-keybind (run_command_1, handle_run_command, 0, 0, NULL, NULL)
-keybind (run_command_2, handle_run_command, 1, 0, NULL, NULL)
-keybind (run_command_3, handle_run_command, 2, 0, NULL, NULL)
-keybind (run_command_4, handle_run_command, 3, 0, NULL, NULL)
-keybind (run_command_5, handle_run_command, 4, 0, NULL, NULL)
-keybind (run_command_6, handle_run_command, 5, 0, NULL, NULL)
-keybind (run_command_7, handle_run_command, 6, 0, NULL, NULL)
-keybind (run_command_8, handle_run_command, 7, 0, NULL, NULL)
-keybind (run_command_9, handle_run_command, 8, 0, NULL, NULL)
-keybind (run_command_10, handle_run_command, 9, 0, NULL, NULL)
-keybind (run_command_11, handle_run_command, 10, 0, NULL, NULL)
-keybind (run_command_12, handle_run_command, 11, 0, NULL, NULL)
-keybind (run_command_13, handle_run_command, 12, 0, NULL, NULL)
-keybind (run_command_14, handle_run_command, 13, 0, NULL, NULL)
-keybind (run_command_15, handle_run_command, 14, 0, NULL, NULL)
-keybind (run_command_16, handle_run_command, 15, 0, NULL, NULL)
-keybind (run_command_17, handle_run_command, 16, 0, NULL, NULL)
-keybind (run_command_18, handle_run_command, 17, 0, NULL, NULL)
-keybind (run_command_19, handle_run_command, 18, 0, NULL, NULL)
-keybind (run_command_20, handle_run_command, 19, 0, NULL, NULL)
-keybind (run_command_21, handle_run_command, 20, 0, NULL, NULL)
-keybind (run_command_22, handle_run_command, 21, 0, NULL, NULL)
-keybind (run_command_23, handle_run_command, 22, 0, NULL, NULL)
-keybind (run_command_24, handle_run_command, 23, 0, NULL, NULL)
-keybind (run_command_25, handle_run_command, 24, 0, NULL, NULL)
-keybind (run_command_26, handle_run_command, 25, 0, NULL, NULL)
-keybind (run_command_27, handle_run_command, 26, 0, NULL, NULL)
-keybind (run_command_28, handle_run_command, 27, 0, NULL, NULL)
-keybind (run_command_29, handle_run_command, 28, 0, NULL, NULL)
-keybind (run_command_30, handle_run_command, 29, 0, NULL, NULL)
-keybind (run_command_31, handle_run_command, 30, 0, NULL, NULL)
-keybind (run_command_32, handle_run_command, 31, 0, NULL, NULL)
-
-keybind (run_command_screenshot, handle_run_command, 32, 0, "Print",
- _("Take a screenshot"))
-keybind (run_command_window_screenshot, handle_run_command, 33, 0,"<Alt>Print",
- _("Take a screenshot of a window"))
-
-keybind (run_command_terminal, handle_run_terminal, 0, 0, NULL, _("Run a terminal"))
-
-/* No description because this is undocumented */
-keybind (set_spew_mark, handle_set_spew_mark, 0, 0, NULL, NULL)
-
-#undef REVERSES_AND_REVERSED
-
-/************************ PER WINDOW BINDINGS ************************/
-
-/* These take a window as an extra parameter; they have no effect
- * if no window is active.
- */
-
-keybind (activate_window_menu, handle_activate_window_menu, 0,
- BINDING_PER_WINDOW, "<Alt>space",
- _("Activate the window menu"))
-keybind (toggle_fullscreen, handle_toggle_fullscreen, 0, BINDING_PER_WINDOW,
- NULL,
- _("Toggle fullscreen mode"))
-keybind (toggle_maximized, handle_toggle_maximized, 0, BINDING_PER_WINDOW, "<Alt>F10",
- _("Toggle maximization state"))
-keybind (toggle_above, handle_toggle_above, 0, BINDING_PER_WINDOW, NULL,
- _("Toggle whether a window will always be visible over other windows"))
-keybind (maximize, handle_maximize, 0, BINDING_PER_WINDOW, NULL,
- _("Maximize window"))
-keybind (unmaximize, handle_unmaximize, 0, BINDING_PER_WINDOW, "<Alt>F5",
- _("Restore window"))
-keybind (toggle_shaded, handle_toggle_shaded, 0, BINDING_PER_WINDOW, NULL,
- _("Toggle shaded state"))
-keybind (minimize, handle_minimize, 0, BINDING_PER_WINDOW, "<Alt>F9",
- _("Minimize window"))
-keybind (close, handle_close, 0, BINDING_PER_WINDOW, "<Alt>F4",
- _("Close window"))
-keybind (begin_move, handle_begin_move, 0, BINDING_PER_WINDOW, "<Alt>F7",
- _("Move window"))
-keybind (begin_resize, handle_begin_resize, 0, BINDING_PER_WINDOW, "<Alt>F8",
- _("Resize window"))
-keybind (toggle_on_all_workspaces, handle_toggle_on_all_workspaces, 0,
- BINDING_PER_WINDOW, NULL,
- _("Toggle whether window is on all workspaces or just one"))
-
-keybind (move_to_workspace_1, handle_move_to_workspace, 0, BINDING_PER_WINDOW,
- NULL,
- _("Move window to workspace 1"))
-keybind (move_to_workspace_2, handle_move_to_workspace, 1, BINDING_PER_WINDOW,
- NULL,
- _("Move window to workspace 2"))
-keybind (move_to_workspace_3, handle_move_to_workspace, 2, BINDING_PER_WINDOW,
- NULL,
- _("Move window to workspace 3"))
-keybind (move_to_workspace_4, handle_move_to_workspace, 3, BINDING_PER_WINDOW,
- NULL,
- _("Move window to workspace 4"))
-keybind (move_to_workspace_5, handle_move_to_workspace, 4, BINDING_PER_WINDOW,
- NULL,
- _("Move window to workspace 5"))
-keybind (move_to_workspace_6, handle_move_to_workspace, 5, BINDING_PER_WINDOW,
- NULL,
- _("Move window to workspace 6"))
-keybind (move_to_workspace_7, handle_move_to_workspace, 6, BINDING_PER_WINDOW,
- NULL,
- _("Move window to workspace 7"))
-keybind (move_to_workspace_8, handle_move_to_workspace, 7, BINDING_PER_WINDOW,
- NULL,
- _("Move window to workspace 8"))
-keybind (move_to_workspace_9, handle_move_to_workspace, 8, BINDING_PER_WINDOW,
- NULL,
- _("Move window to workspace 9"))
-keybind (move_to_workspace_10, handle_move_to_workspace, 9, BINDING_PER_WINDOW,
- NULL,
- _("Move window to workspace 10"))
-keybind (move_to_workspace_11, handle_move_to_workspace, 10, BINDING_PER_WINDOW,
- NULL,
- _("Move window to workspace 11"))
-keybind (move_to_workspace_12, handle_move_to_workspace, 11, BINDING_PER_WINDOW,
- NULL,
- _("Move window to workspace 12"))
-
-/* META_MOTION_* are negative, and so distinct from workspace numbers,
- * which are always zero or positive.
- * If you make use of these constants, you will need to include workspace.h
- * (which you're probably using already for other reasons anyway).
- * If your definition of keybind() throws them away, you don't need to include
- * workspace.h, of course.
- */
-
-keybind (move_to_workspace_left, handle_move_to_workspace,
- META_MOTION_LEFT, BINDING_PER_WINDOW, "<Control><Shift><Alt>Left",
- _("Move window one workspace to the left"))
-keybind (move_to_workspace_right, handle_move_to_workspace,
- META_MOTION_RIGHT, BINDING_PER_WINDOW, "<Control><Shift><Alt>Right",
- _("Move window one workspace to the right"))
-keybind (move_to_workspace_up, handle_move_to_workspace,
- META_MOTION_UP, BINDING_PER_WINDOW, "<Control><Shift><Alt>Up",
- _("Move window one workspace up"))
-keybind (move_to_workspace_down, handle_move_to_workspace,
- META_MOTION_DOWN, BINDING_PER_WINDOW, "<Control><Shift><Alt>Down",
- _("Move window one workspace down"))
-
-keybind (raise_or_lower, handle_raise_or_lower, 0, BINDING_PER_WINDOW, NULL,
- _("Raise window if it's covered by another window, otherwise lower it"))
-keybind (raise, handle_raise, 0, BINDING_PER_WINDOW, NULL,
- _("Raise window above other windows"))
-keybind (lower, handle_lower, 0, BINDING_PER_WINDOW, NULL,
- _("Lower window below other windows"))
-
-keybind (maximize_vertically, handle_maximize_vertically, 0,
- BINDING_PER_WINDOW, NULL,
- _("Maximize window vertically"))
-
-keybind (maximize_horizontally, handle_maximize_horizontally, 0,
- BINDING_PER_WINDOW, NULL,
- _("Maximize window horizontally"))
-
-keybind (move_to_corner_nw, handle_move_to_corner_nw, 0,
- BINDING_PER_WINDOW, NULL,
- _("Move window to north-west (top left) corner"))
-keybind (move_to_corner_ne, handle_move_to_corner_ne, 0,
- BINDING_PER_WINDOW, NULL,
- _("Move window to north-east (top right) corner"))
-keybind (move_to_corner_sw, handle_move_to_corner_sw, 0,
- BINDING_PER_WINDOW, NULL,
- _("Move window to south-west (bottom left) corner"))
-keybind (move_to_corner_se, handle_move_to_corner_se, 0,
- BINDING_PER_WINDOW, NULL,
- _("Move window to south-east (bottom right) corner"))
-
-keybind (move_to_side_n, handle_move_to_side_n, 0,
- BINDING_PER_WINDOW, NULL,
- _("Move window to north (top) side of screen"))
-keybind (move_to_side_s, handle_move_to_side_s, 0,
- BINDING_PER_WINDOW, NULL,
- _("Move window to south (bottom) side of screen"))
-keybind (move_to_side_e, handle_move_to_side_e, 0,
- BINDING_PER_WINDOW, NULL,
- _("Move window to east (right) side of screen"))
-keybind (move_to_side_w, handle_move_to_side_w, 0,
- BINDING_PER_WINDOW, NULL,
- _("Move window to west (left) side of screen"))
-keybind (move_to_center, handle_move_to_center, 0,
- BINDING_PER_WINDOW, NULL,
- _("Move window to center of screen"))
-
-/* eof all-keybindings.h */
-
diff --git a/src/include/boxes.h b/src/include/boxes.h
deleted file mode 100644
index 54b94ea9..00000000
--- a/src/include/boxes.h
+++ /dev/null
@@ -1,290 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Simple box operations */
-
-/*
- * Copyright (C) 2005, 2006 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_BOXES_H
-#define META_BOXES_H
-
-#include <glib.h>
-#include "common.h"
-
-typedef struct _MetaRectangle MetaRectangle;
-struct _MetaRectangle
-{
- int x;
- int y;
- int width;
- int height;
-};
-
-typedef struct _MetaStrut MetaStrut;
-struct _MetaStrut
-{
- MetaRectangle rect;
- MetaDirection side;
-};
-
-#define BOX_LEFT(box) ((box).x) /* Leftmost pixel of rect */
-#define BOX_RIGHT(box) ((box).x + (box).width) /* One pixel past right */
-#define BOX_TOP(box) ((box).y) /* Topmost pixel of rect */
-#define BOX_BOTTOM(box) ((box).y + (box).height) /* One pixel past bottom */
-
-typedef enum
-{
- FIXED_DIRECTION_NONE = 0,
- FIXED_DIRECTION_X = 1 << 0,
- FIXED_DIRECTION_Y = 1 << 1,
-} FixedDirections;
-
-typedef enum
-{
- META_EDGE_WINDOW,
- META_EDGE_XINERAMA,
- META_EDGE_SCREEN
-} MetaEdgeType;
-
-typedef struct _MetaEdge MetaEdge;
-struct _MetaEdge
-{
- MetaRectangle rect; /* width or height should be 1 */
- MetaDirection side_type; /* should only have 1 of the 4 directions set */
- MetaEdgeType edge_type;
-};
-
-/* Output functions -- note that the output buffer had better be big enough:
- * rect_to_string: RECT_LENGTH
- * region_to_string: (RECT_LENGTH+strlen(separator_string)) *
- * g_list_length (region)
- * edge_to_string: EDGE_LENGTH
- * edge_list_to_...: (EDGE_LENGTH+strlen(separator_string)) *
- * g_list_length (edge_list)
- */
-#define RECT_LENGTH 27
-#define EDGE_LENGTH 37
-char* meta_rectangle_to_string (const MetaRectangle *rect,
- char *output);
-char* meta_rectangle_region_to_string (GList *region,
- const char *separator_string,
- char *output);
-char* meta_rectangle_edge_to_string (const MetaEdge *edge,
- char *output);
-char* meta_rectangle_edge_list_to_string (
- GList *edge_list,
- const char *separator_string,
- char *output);
-
-/* Function to make initializing a rect with a single line of code easy */
-MetaRectangle meta_rect (int x, int y, int width, int height);
-
-/* Basic comparison functions */
-int meta_rectangle_area (const MetaRectangle *rect);
-gboolean meta_rectangle_intersect (const MetaRectangle *src1,
- const MetaRectangle *src2,
- MetaRectangle *dest);
-gboolean meta_rectangle_equal (const MetaRectangle *src1,
- const MetaRectangle *src2);
-
-/* Find the bounding box of the union of two rectangles */
-void meta_rectangle_union (const MetaRectangle *rect1,
- const MetaRectangle *rect2,
- MetaRectangle *dest);
-
-/* overlap is similar to intersect but doesn't provide location of
- * intersection information.
- */
-gboolean meta_rectangle_overlap (const MetaRectangle *rect1,
- const MetaRectangle *rect2);
-
-/* vert_overlap means ignore the horizontal location and ask if the
- * vertical parts overlap. An alternate way to think of it is "Does there
- * exist a way to shift either rect horizontally so that the two rects
- * overlap?" horiz_overlap is similar.
- */
-gboolean meta_rectangle_vert_overlap (const MetaRectangle *rect1,
- const MetaRectangle *rect2);
-gboolean meta_rectangle_horiz_overlap (const MetaRectangle *rect1,
- const MetaRectangle *rect2);
-
-/* could_fit_rect determines whether "outer_rect" is big enough to contain
- * inner_rect. contains_rect checks whether it actually contains it.
- */
-gboolean meta_rectangle_could_fit_rect (const MetaRectangle *outer_rect,
- const MetaRectangle *inner_rect);
-gboolean meta_rectangle_contains_rect (const MetaRectangle *outer_rect,
- const MetaRectangle *inner_rect);
-
-/* Resize old_rect to the given new_width and new_height, but store the
- * result in rect. NOTE THAT THIS IS RESIZE ONLY SO IT CANNOT BE USED FOR
- * A MOVERESIZE OPERATION (that simplies the routine a little bit as it
- * means there's no difference between NorthWestGravity and StaticGravity.
- * Also, I lied a little bit--technically, you could use it in a MoveResize
- * operation if you muck with old_rect just right).
- */
-void meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect,
- MetaRectangle *rect,
- int gravity,
- int new_width,
- int new_height);
-
-/* find a list of rectangles with the property that a window is contained
- * in the given region if and only if it is contained in one of the
- * rectangles in the list.
- *
- * In this case, the region is given by taking basic_rect, removing from
- * it the intersections with all the rectangles in the all_struts list,
- * then expanding all the rectangles in the resulting list by the given
- * amounts on each side.
- *
- * See boxes.c for more details.
- */
-GList* meta_rectangle_get_minimal_spanning_set_for_region (
- const MetaRectangle *basic_rect,
- const GSList *all_struts);
-
-/* Expand all rectangles in region by the given amount on each side */
-GList* meta_rectangle_expand_region (GList *region,
- const int left_expand,
- const int right_expand,
- const int top_expand,
- const int bottom_expand);
-/* Same as for meta_rectangle_expand_region except that rectangles not at
- * least min_x or min_y in size are not expanded in that direction
- */
-GList* meta_rectangle_expand_region_conditionally (
- GList *region,
- const int left_expand,
- const int right_expand,
- const int top_expand,
- const int bottom_expand,
- const int min_x,
- const int min_y);
-
-/* Expand rect in direction to the size of expand_to, and then clip out any
- * overlapping struts oriented orthognal to the expansion direction. (Think
- * horizontal or vertical maximization)
- */
-void meta_rectangle_expand_to_avoiding_struts (
- MetaRectangle *rect,
- const MetaRectangle *expand_to,
- const MetaDirection direction,
- const GSList *all_struts);
-
-/* Free the list created by
- * meta_rectangle_get_minimal_spanning_set_for_region()
- * or
- * meta_rectangle_find_onscreen_edges ()
- * or
- * meta_rectangle_find_nonintersected_xinerama_edges()
- */
-void meta_rectangle_free_list_and_elements (GList *filled_list);
-
-/* could_fit_in_region determines whether one of the spanning_rects is
- * big enough to contain rect. contained_in_region checks whether one
- * actually contains it.
- */
-gboolean meta_rectangle_could_fit_in_region (
- const GList *spanning_rects,
- const MetaRectangle *rect);
-gboolean meta_rectangle_contained_in_region (
- const GList *spanning_rects,
- const MetaRectangle *rect);
-gboolean meta_rectangle_overlaps_with_region (
- const GList *spanning_rects,
- const MetaRectangle *rect);
-
-/* Make the rectangle small enough to fit into one of the spanning_rects,
- * but make it no smaller than min_size.
- */
-void meta_rectangle_clamp_to_fit_into_region (
- const GList *spanning_rects,
- FixedDirections fixed_directions,
- MetaRectangle *rect,
- const MetaRectangle *min_size);
-
-/* Clip the rectangle so that it fits into one of the spanning_rects, assuming
- * it overlaps with at least one of them
- */
-void meta_rectangle_clip_to_region (const GList *spanning_rects,
- FixedDirections fixed_directions,
- MetaRectangle *rect);
-
-/* Shove the rectangle into one of the spanning_rects, assuming it fits in
- * one of them.
- */
-void meta_rectangle_shove_into_region(
- const GList *spanning_rects,
- FixedDirections fixed_directions,
- MetaRectangle *rect);
-
-/* Finds the point on the line connecting (x1,y1) to (x2,y2) which is closest
- * to (px, py). Useful for finding an optimal rectangle size when given a
- * range between two sizes that are all candidates.
- */
-void meta_rectangle_find_linepoint_closest_to_point (double x1, double y1,
- double x2, double y2,
- double px, double py,
- double *valx, double *valy);
-
-/***************************************************************************/
-/* */
-/* Switching gears to code for edges instead of just rectangles */
-/* */
-/***************************************************************************/
-
-/* Return whether an edge overlaps or is adjacent to the rectangle in the
- * nonzero-width dimension of the edge.
- */
-gboolean meta_rectangle_edge_aligns (const MetaRectangle *rect,
- const MetaEdge *edge);
-
-/* Compare two edges, so that sorting functions can put a list of edges in
- * canonical order.
- */
-gint meta_rectangle_edge_cmp (gconstpointer a, gconstpointer b);
-
-/* Compare two edges, so that sorting functions can put a list of edges in
- * order. This function doesn't separate left edges first, then right edges,
- * etc., but rather compares only upon location.
- */
-gint meta_rectangle_edge_cmp_ignore_type (gconstpointer a, gconstpointer b);
-
-/* Removes an parts of edges in the given list that intersect any box in the
- * given rectangle list. Returns the result.
- */
-GList* meta_rectangle_remove_intersections_with_boxes_from_edges (
- GList *edges,
- const GSList *rectangles);
-
-/* Finds all the edges of an onscreen region, returning a GList* of
- * MetaEdgeRect's.
- */
-GList* meta_rectangle_find_onscreen_edges (const MetaRectangle *basic_rect,
- const GSList *all_struts);
-
-/* Finds edges between adjacent xineramas which are not covered by the given
- * struts.
- */
-GList* meta_rectangle_find_nonintersected_xinerama_edges (
- const GList *xinerama_rects,
- const GSList *all_struts);
-
-#endif /* META_BOXES_H */
diff --git a/src/include/common.h b/src/include/common.h
deleted file mode 100644
index 9d6a98c5..00000000
--- a/src/include/common.h
+++ /dev/null
@@ -1,292 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity common types shared by core.h and ui.h */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2005 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_COMMON_H
-#define META_COMMON_H
-
-/* Don't include GTK or core headers here */
-#include <X11/Xlib.h>
-#include <glib.h>
-
-typedef struct _MetaResizePopup MetaResizePopup;
-
-typedef enum
-{
- META_FRAME_ALLOWS_DELETE = 1 << 0,
- META_FRAME_ALLOWS_MENU = 1 << 1,
- META_FRAME_ALLOWS_MINIMIZE = 1 << 2,
- META_FRAME_ALLOWS_MAXIMIZE = 1 << 3,
- META_FRAME_ALLOWS_VERTICAL_RESIZE = 1 << 4,
- META_FRAME_ALLOWS_HORIZONTAL_RESIZE = 1 << 5,
- META_FRAME_HAS_FOCUS = 1 << 6,
- META_FRAME_SHADED = 1 << 7,
- META_FRAME_STUCK = 1 << 8,
- META_FRAME_MAXIMIZED = 1 << 9,
- META_FRAME_ALLOWS_SHADE = 1 << 10,
- META_FRAME_ALLOWS_MOVE = 1 << 11,
- META_FRAME_FULLSCREEN = 1 << 12,
- META_FRAME_IS_FLASHING = 1 << 13,
- META_FRAME_ABOVE = 1 << 14
-} MetaFrameFlags;
-
-typedef enum
-{
- META_MENU_OP_DELETE = 1 << 0,
- META_MENU_OP_MINIMIZE = 1 << 1,
- META_MENU_OP_UNMAXIMIZE = 1 << 2,
- META_MENU_OP_MAXIMIZE = 1 << 3,
- META_MENU_OP_UNSHADE = 1 << 4,
- META_MENU_OP_SHADE = 1 << 5,
- META_MENU_OP_UNSTICK = 1 << 6,
- META_MENU_OP_STICK = 1 << 7,
- META_MENU_OP_WORKSPACES = 1 << 8,
- META_MENU_OP_MOVE = 1 << 9,
- META_MENU_OP_RESIZE = 1 << 10,
- META_MENU_OP_ABOVE = 1 << 11,
- META_MENU_OP_UNABOVE = 1 << 12,
- META_MENU_OP_MOVE_LEFT = 1 << 13,
- META_MENU_OP_MOVE_RIGHT = 1 << 14,
- META_MENU_OP_MOVE_UP = 1 << 15,
- META_MENU_OP_MOVE_DOWN = 1 << 16,
- META_MENU_OP_RECOVER = 1 << 17
-} MetaMenuOp;
-
-typedef struct _MetaWindowMenu MetaWindowMenu;
-
-typedef void (* MetaWindowMenuFunc) (MetaWindowMenu *menu,
- Display *xdisplay,
- Window client_xwindow,
- guint32 timestamp,
- MetaMenuOp op,
- int workspace,
- gpointer data);
-
-/* when changing this enum, there are various switch statements
- * you have to update
- */
-typedef enum
-{
- META_GRAB_OP_NONE,
-
- /* Mouse ops */
- META_GRAB_OP_MOVING,
- META_GRAB_OP_RESIZING_SE,
- META_GRAB_OP_RESIZING_S,
- META_GRAB_OP_RESIZING_SW,
- META_GRAB_OP_RESIZING_N,
- META_GRAB_OP_RESIZING_NE,
- META_GRAB_OP_RESIZING_NW,
- META_GRAB_OP_RESIZING_W,
- META_GRAB_OP_RESIZING_E,
-
- /* Keyboard ops */
- META_GRAB_OP_KEYBOARD_MOVING,
- META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN,
- META_GRAB_OP_KEYBOARD_RESIZING_S,
- META_GRAB_OP_KEYBOARD_RESIZING_N,
- META_GRAB_OP_KEYBOARD_RESIZING_W,
- META_GRAB_OP_KEYBOARD_RESIZING_E,
- META_GRAB_OP_KEYBOARD_RESIZING_SE,
- META_GRAB_OP_KEYBOARD_RESIZING_NE,
- META_GRAB_OP_KEYBOARD_RESIZING_SW,
- META_GRAB_OP_KEYBOARD_RESIZING_NW,
-
- /* Alt+Tab */
- META_GRAB_OP_KEYBOARD_TABBING_NORMAL,
- META_GRAB_OP_KEYBOARD_TABBING_DOCK,
-
- /* Alt+Esc */
- META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL,
- META_GRAB_OP_KEYBOARD_ESCAPING_DOCK,
-
- META_GRAB_OP_KEYBOARD_ESCAPING_GROUP,
-
- /* Alt+F6 */
- META_GRAB_OP_KEYBOARD_TABBING_GROUP,
-
- META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING,
-
- /* Frame button ops */
- META_GRAB_OP_CLICKING_MINIMIZE,
- META_GRAB_OP_CLICKING_MAXIMIZE,
- META_GRAB_OP_CLICKING_UNMAXIMIZE,
- META_GRAB_OP_CLICKING_DELETE,
- META_GRAB_OP_CLICKING_MENU,
- META_GRAB_OP_CLICKING_SHADE,
- META_GRAB_OP_CLICKING_UNSHADE,
- META_GRAB_OP_CLICKING_ABOVE,
- META_GRAB_OP_CLICKING_UNABOVE,
- META_GRAB_OP_CLICKING_STICK,
- META_GRAB_OP_CLICKING_UNSTICK
-} MetaGrabOp;
-
-typedef enum
-{
- META_CURSOR_DEFAULT,
- META_CURSOR_NORTH_RESIZE,
- META_CURSOR_SOUTH_RESIZE,
- META_CURSOR_WEST_RESIZE,
- META_CURSOR_EAST_RESIZE,
- META_CURSOR_SE_RESIZE,
- META_CURSOR_SW_RESIZE,
- META_CURSOR_NE_RESIZE,
- META_CURSOR_NW_RESIZE,
- META_CURSOR_MOVE_OR_RESIZE_WINDOW,
- META_CURSOR_BUSY
-
-} MetaCursor;
-
-typedef enum
-{
- META_FOCUS_MODE_CLICK,
- META_FOCUS_MODE_SLOPPY,
- META_FOCUS_MODE_MOUSE
-} MetaFocusMode;
-
-typedef enum
-{
- META_FOCUS_NEW_WINDOWS_SMART,
- META_FOCUS_NEW_WINDOWS_STRICT
-} MetaFocusNewWindows;
-
-typedef enum
-{
- META_ACTION_TITLEBAR_TOGGLE_SHADE,
- META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE,
- META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE_HORIZONTALLY,
- META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE_VERTICALLY,
- META_ACTION_TITLEBAR_MINIMIZE,
- META_ACTION_TITLEBAR_NONE,
- META_ACTION_TITLEBAR_LOWER,
- META_ACTION_TITLEBAR_MENU,
- META_ACTION_TITLEBAR_LAST
-} MetaActionTitlebar;
-
-typedef enum
-{
- META_FRAME_TYPE_NORMAL,
- META_FRAME_TYPE_DIALOG,
- META_FRAME_TYPE_MODAL_DIALOG,
- META_FRAME_TYPE_UTILITY,
- META_FRAME_TYPE_MENU,
- META_FRAME_TYPE_BORDER,
- META_FRAME_TYPE_LAST
-} MetaFrameType;
-
-typedef enum
-{
- /* Create gratuitous divergence from regular
- * X mod bits, to be sure we find bugs
- */
- META_VIRTUAL_SHIFT_MASK = 1 << 5,
- META_VIRTUAL_CONTROL_MASK = 1 << 6,
- META_VIRTUAL_ALT_MASK = 1 << 7,
- META_VIRTUAL_META_MASK = 1 << 8,
- META_VIRTUAL_SUPER_MASK = 1 << 9,
- META_VIRTUAL_HYPER_MASK = 1 << 10,
- META_VIRTUAL_MOD2_MASK = 1 << 11,
- META_VIRTUAL_MOD3_MASK = 1 << 12,
- META_VIRTUAL_MOD4_MASK = 1 << 13,
- META_VIRTUAL_MOD5_MASK = 1 << 14
-} MetaVirtualModifier;
-
-/* Relative directions or sides seem to come up all over the place... */
-/* FIXME: Replace
- * screen.[ch]:MetaScreenDirection,
- * workspace.[ch]:MetaMotionDirection,
- * with the use of MetaDirection.
- */
-typedef enum
-{
- META_DIRECTION_LEFT = 1 << 0,
- META_DIRECTION_RIGHT = 1 << 1,
- META_DIRECTION_TOP = 1 << 2,
- META_DIRECTION_BOTTOM = 1 << 3,
-
- /* Some aliases for making code more readable for various circumstances. */
- META_DIRECTION_UP = META_DIRECTION_TOP,
- META_DIRECTION_DOWN = META_DIRECTION_BOTTOM,
-
- /* A few more definitions using aliases */
- META_DIRECTION_HORIZONTAL = META_DIRECTION_LEFT | META_DIRECTION_RIGHT,
- META_DIRECTION_VERTICAL = META_DIRECTION_UP | META_DIRECTION_DOWN,
-
- /* And a few more aliases */
- META_SIDE_LEFT = META_DIRECTION_LEFT,
- META_SIDE_RIGHT = META_DIRECTION_RIGHT,
- META_SIDE_TOP = META_DIRECTION_TOP,
- META_SIDE_BOTTOM = META_DIRECTION_BOTTOM
-} MetaDirection;
-
-/* Function a window button can have. Note, you can't add stuff here
- * without extending the theme format to draw a new function and
- * breaking all existing themes.
- */
-typedef enum
-{
- META_BUTTON_FUNCTION_MENU,
- META_BUTTON_FUNCTION_MINIMIZE,
- META_BUTTON_FUNCTION_MAXIMIZE,
- META_BUTTON_FUNCTION_CLOSE,
- META_BUTTON_FUNCTION_SHADE,
- META_BUTTON_FUNCTION_ABOVE,
- META_BUTTON_FUNCTION_STICK,
- META_BUTTON_FUNCTION_UNSHADE,
- META_BUTTON_FUNCTION_UNABOVE,
- META_BUTTON_FUNCTION_UNSTICK,
- META_BUTTON_FUNCTION_LAST
-} MetaButtonFunction;
-
-#define MAX_BUTTONS_PER_CORNER META_BUTTON_FUNCTION_LAST
-
-typedef struct _MetaButtonLayout MetaButtonLayout;
-struct _MetaButtonLayout
-{
- /* buttons in the group on the left side */
- MetaButtonFunction left_buttons[MAX_BUTTONS_PER_CORNER];
- gboolean left_buttons_has_spacer[MAX_BUTTONS_PER_CORNER];
-
- /* buttons in the group on the right side */
- MetaButtonFunction right_buttons[MAX_BUTTONS_PER_CORNER];
- gboolean right_buttons_has_spacer[MAX_BUTTONS_PER_CORNER];
-};
-
-/* should investigate changing these to whatever most apps use */
-#define META_ICON_WIDTH 32
-#define META_ICON_HEIGHT 32
-#define META_MINI_ICON_WIDTH 16
-#define META_MINI_ICON_HEIGHT 16
-
-#define META_DEFAULT_ICON_NAME "window"
-
-#define META_PRIORITY_PREFS_NOTIFY (G_PRIORITY_DEFAULT_IDLE + 10)
-#define META_PRIORITY_WORK_AREA_HINT (G_PRIORITY_DEFAULT_IDLE + 15)
-
-#define POINT_IN_RECT(xcoord, ycoord, rect) \
- ((xcoord) >= (rect).x && \
- (xcoord) < ((rect).x + (rect).width) && \
- (ycoord) >= (rect).y && \
- (ycoord) < ((rect).y + (rect).height))
-
-#endif
diff --git a/src/include/compositor.h b/src/include/compositor.h
deleted file mode 100644
index a7f9bf1f..00000000
--- a/src/include/compositor.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2008 Iain Holmes
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_COMPOSITOR_H
-#define META_COMPOSITOR_H
-
-#include <glib.h>
-#include <X11/Xlib.h>
-
-#include "types.h"
-#include "boxes.h"
-
-MetaCompositor *meta_compositor_new (MetaDisplay *display);
-void meta_compositor_destroy (MetaCompositor *compositor);
-
-void meta_compositor_manage_screen (MetaCompositor *compositor,
- MetaScreen *screen);
-void meta_compositor_unmanage_screen (MetaCompositor *compositor,
- MetaScreen *screen);
-
-void meta_compositor_add_window (MetaCompositor *compositor,
- MetaWindow *window,
- Window xwindow,
- XWindowAttributes *attrs);
-void meta_compositor_remove_window (MetaCompositor *compositor,
- Window xwindow);
-
-void meta_compositor_set_updates (MetaCompositor *compositor,
- MetaWindow *window,
- gboolean updates);
-
-void meta_compositor_process_event (MetaCompositor *compositor,
- XEvent *event,
- MetaWindow *window);
-Pixmap meta_compositor_get_window_pixmap (MetaCompositor *compositor,
- MetaWindow *window);
-void meta_compositor_set_active_window (MetaCompositor *compositor,
- MetaScreen *screen,
- MetaWindow *window);
-
-void meta_compositor_begin_move (MetaCompositor *compositor,
- MetaWindow *window,
- MetaRectangle *initial,
- int grab_x, int grab_y);
-void meta_compositor_update_move (MetaCompositor *compositor,
- MetaWindow *window,
- int x, int y);
-void meta_compositor_end_move (MetaCompositor *compositor,
- MetaWindow *window);
-void meta_compositor_free_window (MetaCompositor *compositor,
- MetaWindow *window);
-
-#endif
-
-
-
-
-
diff --git a/src/include/core.h b/src/include/core.h
deleted file mode 100644
index 0c518e74..00000000
--- a/src/include/core.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity interface used by GTK+ UI to talk to core */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2005 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_CORE_H
-#define META_CORE_H
-
-/* Don't include core headers here */
-#include <gdk/gdkx.h>
-#include "common.h"
-
-typedef enum
-{
- META_CORE_GET_END = 0,
- META_CORE_WINDOW_HAS_FRAME,
- META_CORE_GET_CLIENT_WIDTH,
- META_CORE_GET_CLIENT_HEIGHT,
- META_CORE_IS_TITLEBAR_ONSCREEN,
- META_CORE_GET_CLIENT_XWINDOW,
- META_CORE_GET_FRAME_FLAGS,
- META_CORE_GET_FRAME_TYPE,
- META_CORE_GET_MINI_ICON,
- META_CORE_GET_ICON,
- META_CORE_GET_X,
- META_CORE_GET_Y,
- META_CORE_GET_FRAME_WORKSPACE,
- META_CORE_GET_FRAME_X,
- META_CORE_GET_FRAME_Y,
- META_CORE_GET_FRAME_WIDTH,
- META_CORE_GET_FRAME_HEIGHT,
- META_CORE_GET_SCREEN_WIDTH,
- META_CORE_GET_SCREEN_HEIGHT,
-} MetaCoreGetType;
-
-/* General information function about the given window. Pass in a sequence of
- * pairs of MetaCoreGetTypes and pointers to variables; the variables will be
- * filled with the requested values. End the list with META_CORE_GET_END.
- * For example:
- *
- * meta_core_get (my_display, my_window,
- * META_CORE_GET_X, &x,
- * META_CORE_GET_Y, &y,
- * META_CORE_GET_END);
- *
- * If the window doesn't have a frame, this will raise a meta_bug. To suppress
- * this behaviour, ask META_CORE_WINDOW_HAS_FRAME as the *first* question in
- * the list. If the window has no frame, the answer to this question will be
- * False, and anything else you asked will be undefined. Otherwise, the answer
- * will be True. The answer will necessarily be True if you ask the question
- * in any other position. The positions of all other questions don't matter.
- *
- * The reason for this function is that some parts of the program don't know
- * about MetaWindows. But they *can* see core.h. So we used to have a whole
- * load of functions which took a display and an X window, looked up the
- * relevant MetaWindow, and returned information about it. The trouble with
- * that is that looking up the MetaWindow is a nontrivial operation, and
- * consolidating the calls in this way makes (for example) frame exposes
- * 33% faster, according to valgrind.
- *
- * This function would perhaps be slightly better if the questions were
- * represented by pointers, perhaps gchar*s, because then we could take
- * advantage of gcc's automatic sentinel checking. On the other hand, this
- * immediately suggests string comparison, and that's slow.
- *
- * Another possible improvement is that core.h still has a bunch of
- * functions which can't be described by the formula "give a display and
- * an X window, get a single value" (meta_core_user_move, for example), but
- * which could theoretically be handled by this function if we relaxed the
- * requirement that all questions should have exactly one argument.
- */
-void meta_core_get (Display *xdisplay,
- Window window,
- ...);
-
-void meta_core_queue_frame_resize (Display *xdisplay,
- Window frame_xwindow);
-
-/* Move as a result of user operation */
-void meta_core_user_move (Display *xdisplay,
- Window frame_xwindow,
- int x,
- int y);
-void meta_core_user_resize (Display *xdisplay,
- Window frame_xwindow,
- int gravity,
- int width,
- int height);
-
-void meta_core_user_raise (Display *xdisplay,
- Window frame_xwindow);
-void meta_core_user_lower_and_unfocus (Display *xdisplay,
- Window frame_xwindow,
- guint32 timestamp);
-
-void meta_core_user_focus (Display *xdisplay,
- Window frame_xwindow,
- guint32 timestamp);
-
-void meta_core_minimize (Display *xdisplay,
- Window frame_xwindow);
-void meta_core_toggle_maximize (Display *xdisplay,
- Window frame_xwindow);
-void meta_core_toggle_maximize_horizontally (Display *xdisplay,
- Window frame_xwindow);
-void meta_core_toggle_maximize_vertically (Display *xdisplay,
- Window frame_xwindow);
-void meta_core_unmaximize (Display *xdisplay,
- Window frame_xwindow);
-void meta_core_maximize (Display *xdisplay,
- Window frame_xwindow);
-void meta_core_delete (Display *xdisplay,
- Window frame_xwindow,
- guint32 timestamp);
-void meta_core_unshade (Display *xdisplay,
- Window frame_xwindow,
- guint32 timestamp);
-void meta_core_shade (Display *xdisplay,
- Window frame_xwindow,
- guint32 timestamp);
-void meta_core_unstick (Display *xdisplay,
- Window frame_xwindow);
-void meta_core_stick (Display *xdisplay,
- Window frame_xwindow);
-void meta_core_unmake_above (Display *xdisplay,
- Window frame_xwindow);
-void meta_core_make_above (Display *xdisplay,
- Window frame_xwindow);
-void meta_core_change_workspace (Display *xdisplay,
- Window frame_xwindow,
- int new_workspace);
-
-int meta_core_get_num_workspaces (Screen *xscreen);
-int meta_core_get_active_workspace (Screen *xscreen);
-int meta_core_get_frame_workspace (Display *xdisplay,
- Window frame_xwindow);
-const char* meta_core_get_workspace_name_with_index (Display *xdisplay,
- Window xroot,
- int index);
-
-void meta_core_show_window_menu (Display *xdisplay,
- Window frame_xwindow,
- int root_x,
- int root_y,
- int button,
- guint32 timestamp);
-
-void meta_core_get_menu_accelerator (MetaMenuOp menu_op,
- int workspace,
- unsigned int *keysym,
- MetaVirtualModifier *modifiers);
-
-gboolean meta_core_begin_grab_op (Display *xdisplay,
- Window frame_xwindow,
- MetaGrabOp op,
- gboolean pointer_already_grabbed,
- gboolean frame_action,
- int button,
- gulong modmask,
- guint32 timestamp,
- int root_x,
- int root_y);
-void meta_core_end_grab_op (Display *xdisplay,
- guint32 timestamp);
-MetaGrabOp meta_core_get_grab_op (Display *xdisplay);
-Window meta_core_get_grab_frame (Display *xdisplay);
-int meta_core_get_grab_button (Display *xdisplay);
-
-
-void meta_core_grab_buttons (Display *xdisplay,
- Window frame_xwindow);
-
-void meta_core_set_screen_cursor (Display *xdisplay,
- Window frame_on_screen,
- MetaCursor cursor);
-
-/* Used because we ignore EnterNotify when a window is unmapped that
- * really shouldn't cause focus changes, by comparing the event serial
- * of the EnterNotify and the UnmapNotify.
- */
-void meta_core_increment_event_serial (Display *display);
-
-void meta_invalidate_default_icons (void);
-
-#endif
-
-
-
-
diff --git a/src/include/display.h b/src/include/display.h
deleted file mode 100644
index 53dd9d75..00000000
--- a/src/include/display.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2008 Iain Holmes
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_DISPLAY_H
-#define META_DISPLAY_H
-
-#include <glib.h>
-#include <X11/Xlib.h>
-
-#include "types.h"
-
-#define meta_XFree(p) do { if ((p)) XFree ((p)); } while (0)
-
-void meta_display_get_compositor_version (MetaDisplay *display,
- int *major,
- int *minor);
-Display *meta_display_get_xdisplay (MetaDisplay *display);
-MetaCompositor *meta_display_get_compositor (MetaDisplay *display);
-GSList *meta_display_get_screens (MetaDisplay *display);
-
-gboolean meta_display_has_shape (MetaDisplay *display);
-
-MetaScreen *meta_display_screen_for_root (MetaDisplay *display,
- Window xroot);
-MetaWindow *meta_display_get_focus_window (MetaDisplay *display);
-
-int meta_display_get_damage_event_base (MetaDisplay *display);
-int meta_display_get_shape_event_base (MetaDisplay *display);
-
-#endif
diff --git a/src/include/errors.h b/src/include/errors.h
deleted file mode 100644
index 8278948a..00000000
--- a/src/include/errors.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity X error handling */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_ERRORS_H
-#define META_ERRORS_H
-
-#include <X11/Xlib.h>
-
-#include "util.h"
-#include "display.h"
-
-typedef void (* ErrorHandler) (Display *dpy,
- XErrorEvent *error,
- gpointer data);
-
-void meta_errors_init (void);
-void meta_errors_register_foreign_display (Display *foreign_dpy,
- ErrorHandler handler,
- gpointer data);
-
-void meta_error_trap_push (MetaDisplay *display);
-void meta_error_trap_pop (MetaDisplay *display,
- gboolean last_request_was_roundtrip);
-
-void meta_error_trap_push_with_return (MetaDisplay *display);
-/* returns X error code, or 0 for no error */
-int meta_error_trap_pop_with_return (MetaDisplay *display,
- gboolean last_request_was_roundtrip);
-
-
-#endif
diff --git a/src/include/frame.h b/src/include/frame.h
deleted file mode 100644
index eeb57263..00000000
--- a/src/include/frame.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2008 Iain Holmes
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_FRAME_H
-#define META_FRAME_H
-
-#include <X11/Xlib.h>
-
-#include "types.h"
-
-Window meta_frame_get_xwindow (MetaFrame *frame);
-
-#endif
diff --git a/src/include/main.h b/src/include/main.h
deleted file mode 100644
index 62106e16..00000000
--- a/src/include/main.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity main */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_MAIN_H
-#define META_MAIN_H
-
-#include <glib.h>
-
-typedef enum
-{
- META_EXIT_SUCCESS,
- META_EXIT_ERROR
-} MetaExitCode;
-
-/* exit immediately */
-void meta_exit (MetaExitCode code);
-
-/* g_main_loop_quit() then fall out of main() */
-void meta_quit (MetaExitCode code);
-
-void meta_restart (void);
-
-#endif
diff --git a/src/include/prefs.h b/src/include/prefs.h
deleted file mode 100644
index 5acad233..00000000
--- a/src/include/prefs.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity preferences */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2006 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_PREFS_H
-#define META_PREFS_H
-
-/* This header is a "common" one between the UI and core side */
-#include "common.h"
-#include <pango/pango-font.h>
-
-typedef enum
-{
- META_PREF_MOUSE_BUTTON_MODS,
- META_PREF_FOCUS_MODE,
- META_PREF_FOCUS_NEW_WINDOWS,
- META_PREF_RAISE_ON_CLICK,
- META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR,
- META_PREF_ACTION_MIDDLE_CLICK_TITLEBAR,
- META_PREF_ACTION_RIGHT_CLICK_TITLEBAR,
- META_PREF_AUTO_RAISE,
- META_PREF_AUTO_RAISE_DELAY,
- META_PREF_THEME,
- META_PREF_TITLEBAR_FONT,
- META_PREF_NUM_WORKSPACES,
- META_PREF_APPLICATION_BASED,
- META_PREF_KEYBINDINGS,
- META_PREF_DISABLE_WORKAROUNDS,
- META_PREF_COMMANDS,
- META_PREF_TERMINAL_COMMAND,
- META_PREF_BUTTON_LAYOUT,
- META_PREF_WORKSPACE_NAMES,
- META_PREF_VISUAL_BELL,
- META_PREF_AUDIBLE_BELL,
- META_PREF_VISUAL_BELL_TYPE,
- META_PREF_REDUCED_RESOURCES,
- META_PREF_GNOME_ACCESSIBILITY,
- META_PREF_GNOME_ANIMATIONS,
- META_PREF_CURSOR_THEME,
- META_PREF_CURSOR_SIZE,
- META_PREF_COMPOSITING_MANAGER
-} MetaPreference;
-
-typedef void (* MetaPrefsChangedFunc) (MetaPreference pref,
- gpointer data);
-
-void meta_prefs_add_listener (MetaPrefsChangedFunc func,
- gpointer data);
-void meta_prefs_remove_listener (MetaPrefsChangedFunc func,
- gpointer data);
-
-void meta_prefs_init (void);
-const char* meta_preference_to_string (MetaPreference pref);
-
-MetaVirtualModifier meta_prefs_get_mouse_button_mods (void);
-MetaFocusMode meta_prefs_get_focus_mode (void);
-MetaFocusNewWindows meta_prefs_get_focus_new_windows (void);
-gboolean meta_prefs_get_raise_on_click (void);
-const char* meta_prefs_get_theme (void);
-/* returns NULL if GTK default should be used */
-const PangoFontDescription* meta_prefs_get_titlebar_font (void);
-int meta_prefs_get_num_workspaces (void);
-gboolean meta_prefs_get_application_based (void);
-gboolean meta_prefs_get_disable_workarounds (void);
-gboolean meta_prefs_get_auto_raise (void);
-int meta_prefs_get_auto_raise_delay (void);
-gboolean meta_prefs_get_reduced_resources (void);
-gboolean meta_prefs_get_gnome_accessibility (void);
-gboolean meta_prefs_get_gnome_animations (void);
-
-const char* meta_prefs_get_command (int i);
-
-char* meta_prefs_get_gconf_key_for_command (int i);
-
-const char* meta_prefs_get_terminal_command (void);
-const char* meta_prefs_get_gconf_key_for_terminal_command (void);
-
-void meta_prefs_get_button_layout (MetaButtonLayout *button_layout);
-
-/* Double, right, middle click can be configured to any titlebar meta-action */
-MetaActionTitlebar meta_prefs_get_action_double_click_titlebar (void);
-MetaActionTitlebar meta_prefs_get_action_middle_click_titlebar (void);
-MetaActionTitlebar meta_prefs_get_action_right_click_titlebar (void);
-
-void meta_prefs_set_num_workspaces (int n_workspaces);
-
-const char* meta_prefs_get_workspace_name (int i);
-void meta_prefs_change_workspace_name (int i,
- const char *name);
-
-const char* meta_prefs_get_cursor_theme (void);
-int meta_prefs_get_cursor_size (void);
-gboolean meta_prefs_get_compositing_manager (void);
-
-/**
- * Sets whether the compositor is turned on.
- *
- * \param whether TRUE to turn on, FALSE to turn off
- */
-void meta_prefs_set_compositing_manager (gboolean whether);
-
-/* XXX FIXME This should be x-macroed, but isn't yet because it would be
- * difficult (or perhaps impossible) to add the suffixes using the current
- * system. It needs some more thought, perhaps after the current system
- * evolves a little.
- */
-typedef enum _MetaKeyBindingAction
-{
- META_KEYBINDING_ACTION_NONE = -1,
- META_KEYBINDING_ACTION_WORKSPACE_1,
- META_KEYBINDING_ACTION_WORKSPACE_2,
- META_KEYBINDING_ACTION_WORKSPACE_3,
- META_KEYBINDING_ACTION_WORKSPACE_4,
- META_KEYBINDING_ACTION_WORKSPACE_5,
- META_KEYBINDING_ACTION_WORKSPACE_6,
- META_KEYBINDING_ACTION_WORKSPACE_7,
- META_KEYBINDING_ACTION_WORKSPACE_8,
- META_KEYBINDING_ACTION_WORKSPACE_9,
- META_KEYBINDING_ACTION_WORKSPACE_10,
- META_KEYBINDING_ACTION_WORKSPACE_11,
- META_KEYBINDING_ACTION_WORKSPACE_12,
- META_KEYBINDING_ACTION_WORKSPACE_LEFT,
- META_KEYBINDING_ACTION_WORKSPACE_RIGHT,
- META_KEYBINDING_ACTION_WORKSPACE_UP,
- META_KEYBINDING_ACTION_WORKSPACE_DOWN,
- META_KEYBINDING_ACTION_SWITCH_GROUP,
- META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD,
- META_KEYBINDING_ACTION_SWITCH_WINDOWS,
- META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD,
- META_KEYBINDING_ACTION_SWITCH_PANELS,
- META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD,
- META_KEYBINDING_ACTION_CYCLE_GROUP,
- META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD,
- META_KEYBINDING_ACTION_CYCLE_WINDOWS,
- META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD,
- META_KEYBINDING_ACTION_CYCLE_PANELS,
- META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD,
- META_KEYBINDING_ACTION_SHOW_DESKTOP,
- META_KEYBINDING_ACTION_PANEL_MAIN_MENU,
- META_KEYBINDING_ACTION_PANEL_RUN_DIALOG,
- META_KEYBINDING_ACTION_COMMAND_1,
- META_KEYBINDING_ACTION_COMMAND_2,
- META_KEYBINDING_ACTION_COMMAND_3,
- META_KEYBINDING_ACTION_COMMAND_4,
- META_KEYBINDING_ACTION_COMMAND_5,
- META_KEYBINDING_ACTION_COMMAND_6,
- META_KEYBINDING_ACTION_COMMAND_7,
- META_KEYBINDING_ACTION_COMMAND_8,
- META_KEYBINDING_ACTION_COMMAND_9,
- META_KEYBINDING_ACTION_COMMAND_10,
- META_KEYBINDING_ACTION_COMMAND_11,
- META_KEYBINDING_ACTION_COMMAND_12
-} MetaKeyBindingAction;
-
-typedef struct
-{
- unsigned int keysym;
- unsigned int keycode;
- MetaVirtualModifier modifiers;
-} MetaKeyCombo;
-
-typedef struct
-{
- const char *name;
- /**
- * A list of MetaKeyCombos. Each of them is bound to
- * this keypref. If one has keysym==modifiers==0, it is
- * ignored. For historical reasons, the first entry is
- * governed by the pref FOO and the remainder are
- * governed by the pref FOO_list.
- */
- GSList *bindings;
-
- /** for keybindings that can have shift or not like Alt+Tab */
- gboolean add_shift:1;
-
- /** for keybindings that apply only to a window */
- gboolean per_window:1;
-} MetaKeyPref;
-
-void meta_prefs_get_key_bindings (const MetaKeyPref **bindings,
- int *n_bindings);
-
-MetaKeyBindingAction meta_prefs_get_keybinding_action (const char *name);
-
-void meta_prefs_get_window_binding (const char *name,
- unsigned int *keysym,
- MetaVirtualModifier *modifiers);
-
-typedef enum
-{
- META_VISUAL_BELL_INVALID = 0,
- META_VISUAL_BELL_FULLSCREEN_FLASH,
- META_VISUAL_BELL_FRAME_FLASH
-
-} MetaVisualBellType;
-
-gboolean meta_prefs_get_visual_bell (void);
-gboolean meta_prefs_bell_is_audible (void);
-MetaVisualBellType meta_prefs_get_visual_bell_type (void);
-
-#endif
-
-
-
-
diff --git a/src/include/resizepopup.h b/src/include/resizepopup.h
deleted file mode 100644
index a861ff38..00000000
--- a/src/include/resizepopup.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity resizing-terminal-window feedback */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_RESIZEPOPUP_H
-#define META_RESIZEPOPUP_H
-
-/* Don't include gtk.h or gdk.h here */
-#include "boxes.h"
-#include "common.h"
-#include <X11/Xlib.h>
-#include <glib.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-
-MetaResizePopup* meta_ui_resize_popup_new (Display *display,
- int screen_number);
-void meta_ui_resize_popup_free (MetaResizePopup *popup);
-void meta_ui_resize_popup_set (MetaResizePopup *popup,
- MetaRectangle rect,
- int base_width,
- int base_height,
- int width_inc,
- int height_inc);
-void meta_ui_resize_popup_set_showing (MetaResizePopup *popup,
- gboolean showing);
-
-#endif
-
diff --git a/src/include/screen.h b/src/include/screen.h
deleted file mode 100644
index 9f842317..00000000
--- a/src/include/screen.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2008 Iain Holmes
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_SCREEN_H
-#define META_SCREEN_H
-
-#include <X11/Xlib.h>
-#include <glib.h>
-#include "types.h"
-
-int meta_screen_get_screen_number (MetaScreen *screen);
-MetaDisplay *meta_screen_get_display (MetaScreen *screen);
-
-Window meta_screen_get_xroot (MetaScreen *screen);
-void meta_screen_get_size (MetaScreen *screen,
- int *width,
- int *height);
-
-gpointer meta_screen_get_compositor_data (MetaScreen *screen);
-void meta_screen_set_compositor_data (MetaScreen *screen,
- gpointer info);
-
-MetaScreen *meta_screen_for_x_screen (Screen *xscreen);
-
-#ifdef HAVE_COMPOSITE_EXTENSIONS
-void meta_screen_set_cm_selection (MetaScreen *screen);
-void meta_screen_unset_cm_selection (MetaScreen *screen);
-#endif
-
-#endif
diff --git a/src/include/tabpopup.h b/src/include/tabpopup.h
deleted file mode 100644
index c210a191..00000000
--- a/src/include/tabpopup.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity tab popup window */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2005 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_TABPOPUP_H
-#define META_TABPOPUP_H
-
-/* Don't include gtk.h or gdk.h here */
-#include "common.h"
-#include "boxes.h"
-#include <X11/Xlib.h>
-#include <glib.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-
-typedef struct _MetaTabEntry MetaTabEntry;
-typedef struct _MetaTabPopup MetaTabPopup;
-typedef void *MetaTabEntryKey;
-
-struct _MetaTabEntry
-{
- MetaTabEntryKey key;
- const char *title;
- GdkPixbuf *icon;
- MetaRectangle rect;
- MetaRectangle inner_rect;
- guint blank : 1;
- guint hidden : 1;
- guint demands_attention : 1;
-};
-
-MetaTabPopup* meta_ui_tab_popup_new (const MetaTabEntry *entries,
- int screen_number,
- int entry_count,
- int width,
- gboolean outline);
-void meta_ui_tab_popup_free (MetaTabPopup *popup);
-void meta_ui_tab_popup_set_showing (MetaTabPopup *popup,
- gboolean showing);
-void meta_ui_tab_popup_forward (MetaTabPopup *popup);
-void meta_ui_tab_popup_backward (MetaTabPopup *popup);
-MetaTabEntryKey meta_ui_tab_popup_get_selected (MetaTabPopup *popup);
-void meta_ui_tab_popup_select (MetaTabPopup *popup,
- MetaTabEntryKey key);
-
-
-#endif
-
diff --git a/src/include/types.h b/src/include/types.h
deleted file mode 100644
index 045b102f..00000000
--- a/src/include/types.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2008 Iain Holmes
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_TYPES_H
-#define META_TYPES_H
-
-typedef struct _MetaCompositor MetaCompositor;
-typedef struct _MetaDisplay MetaDisplay;
-typedef struct _MetaFrame MetaFrame;
-typedef struct _MetaScreen MetaScreen;
-typedef struct _MetaWindow MetaWindow;
-
-#endif
diff --git a/src/include/ui.h b/src/include/ui.h
deleted file mode 100644
index a4d7fea7..00000000
--- a/src/include/ui.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity interface for talking to GTK+ UI module */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_UI_H
-#define META_UI_H
-
-/* Don't include gtk.h or gdk.h here */
-#include "common.h"
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <glib.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-
-/* This is between GTK_PRIORITY_RESIZE (+10) and GTK_PRIORITY_REDRAW (+20) */
-#define META_PRIORITY_RESIZE (G_PRIORITY_HIGH_IDLE + 15)
-
-typedef struct _MetaUI MetaUI;
-
-typedef struct _MetaImageWindow MetaImageWindow;
-
-typedef gboolean (* MetaEventFunc) (XEvent *xevent, gpointer data);
-
-typedef enum
-{
- META_UI_DIRECTION_LTR,
- META_UI_DIRECTION_RTL
-} MetaUIDirection;
-
-void meta_ui_init (int *argc, char ***argv);
-
-Display* meta_ui_get_display (void);
-
-void meta_ui_add_event_func (Display *xdisplay,
- MetaEventFunc func,
- gpointer data);
-void meta_ui_remove_event_func (Display *xdisplay,
- MetaEventFunc func,
- gpointer data);
-
-MetaUI* meta_ui_new (Display *xdisplay,
- Screen *screen);
-void meta_ui_free (MetaUI *ui);
-
-void meta_ui_theme_get_frame_borders (MetaUI *ui,
- MetaFrameType type,
- MetaFrameFlags flags,
- int *top_height,
- int *bottom_height,
- int *left_width,
- int *right_width);
-void meta_ui_get_frame_geometry (MetaUI *ui,
- Window frame_xwindow,
- int *top_height, int *bottom_height,
- int *left_width, int *right_width);
-Window meta_ui_create_frame_window (MetaUI *ui,
- Display *xdisplay,
- Visual *xvisual,
- gint x,
- gint y,
- gint width,
- gint height,
- gint screen_no);
-void meta_ui_destroy_frame_window (MetaUI *ui,
- Window xwindow);
-void meta_ui_move_resize_frame (MetaUI *ui,
- Window frame,
- int x,
- int y,
- int width,
- int height);
-
-/* GDK insists on tracking map/unmap */
-void meta_ui_map_frame (MetaUI *ui,
- Window xwindow);
-void meta_ui_unmap_frame (MetaUI *ui,
- Window xwindow);
-
-void meta_ui_unflicker_frame_bg (MetaUI *ui,
- Window xwindow,
- int target_width,
- int target_height);
-void meta_ui_reset_frame_bg (MetaUI *ui,
- Window xwindow);
-
-void meta_ui_apply_frame_shape (MetaUI *ui,
- Window xwindow,
- int new_window_width,
- int new_window_height,
- gboolean window_has_shape);
-
-void meta_ui_queue_frame_draw (MetaUI *ui,
- Window xwindow);
-
-void meta_ui_set_frame_title (MetaUI *ui,
- Window xwindow,
- const char *title);
-
-void meta_ui_repaint_frame (MetaUI *ui,
- Window xwindow);
-
-MetaWindowMenu* meta_ui_window_menu_new (MetaUI *ui,
- Window client_xwindow,
- MetaMenuOp ops,
- MetaMenuOp insensitive,
- unsigned long active_workspace,
- int n_workspaces,
- MetaWindowMenuFunc func,
- gpointer data);
-void meta_ui_window_menu_popup (MetaWindowMenu *menu,
- int root_x,
- int root_y,
- int button,
- guint32 timestamp);
-void meta_ui_window_menu_free (MetaWindowMenu *menu);
-
-
-MetaImageWindow* meta_image_window_new (Display *xdisplay,
- int screen_number,
- int max_width,
- int max_height);
-void meta_image_window_free (MetaImageWindow *iw);
-void meta_image_window_set_showing (MetaImageWindow *iw,
- gboolean showing);
-void meta_image_window_set (MetaImageWindow *iw,
- GdkPixbuf *pixbuf,
- int x,
- int y);
-
-/* FIXME these lack a display arg */
-GdkPixbuf* meta_gdk_pixbuf_get_from_window (GdkPixbuf *dest,
- Window xwindow,
- int src_x,
- int src_y,
- int dest_x,
- int dest_y,
- int width,
- int height);
-
-GdkPixbuf* meta_gdk_pixbuf_get_from_pixmap (GdkPixbuf *dest,
- Pixmap xpixmap,
- int src_x,
- int src_y,
- int dest_x,
- int dest_y,
- int width,
- int height);
-
-/* Used when we have a server grab and draw all over everything,
- * then we need to handle exposes after doing that, instead of
- * during it
- */
-void meta_ui_push_delay_exposes (MetaUI *ui);
-void meta_ui_pop_delay_exposes (MetaUI *ui);
-
-GdkPixbuf* meta_ui_get_default_window_icon (MetaUI *ui);
-GdkPixbuf* meta_ui_get_default_mini_icon (MetaUI *ui);
-
-gboolean meta_ui_window_should_not_cause_focus (Display *xdisplay,
- Window xwindow);
-
-char* meta_text_property_to_utf8 (Display *xdisplay,
- const XTextProperty *prop);
-
-void meta_ui_set_current_theme (const char *name,
- gboolean force_reload);
-gboolean meta_ui_have_a_theme (void);
-
-gboolean meta_ui_parse_accelerator (const char *accel,
- unsigned int *keysym,
- unsigned int *keycode,
- MetaVirtualModifier *mask);
-gboolean meta_ui_parse_modifier (const char *accel,
- MetaVirtualModifier *mask);
-
-/* Caller responsible for freeing return string of meta_ui_accelerator_name! */
-gchar* meta_ui_accelerator_name (unsigned int keysym,
- MetaVirtualModifier mask);
-gboolean meta_ui_window_is_widget (MetaUI *ui,
- Window xwindow);
-
-int meta_ui_get_drag_threshold (MetaUI *ui);
-
-MetaUIDirection meta_ui_get_direction (void);
-
-GdkPixbuf *meta_ui_get_pixbuf_from_pixmap (Pixmap pmap);
-
-#include "tabpopup.h"
-
-#endif
diff --git a/src/include/util.h b/src/include/util.h
deleted file mode 100644
index 5041f5ec..00000000
--- a/src/include/util.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity utilities */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2005 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_UTIL_H
-#define META_UTIL_H
-
-#include <glib.h>
-
-gboolean meta_is_verbose (void);
-void meta_set_verbose (gboolean setting);
-gboolean meta_is_debugging (void);
-void meta_set_debugging (gboolean setting);
-gboolean meta_is_syncing (void);
-void meta_set_syncing (gboolean setting);
-gboolean meta_get_replace_current_wm (void);
-void meta_set_replace_current_wm (gboolean setting);
-
-void meta_debug_spew_real (const char *format,
- ...) G_GNUC_PRINTF (1, 2);
-void meta_verbose_real (const char *format,
- ...) G_GNUC_PRINTF (1, 2);
-
-void meta_bug (const char *format,
- ...) G_GNUC_PRINTF (1, 2);
-void meta_warning (const char *format,
- ...) G_GNUC_PRINTF (1, 2);
-void meta_fatal (const char *format,
- ...) G_GNUC_PRINTF (1, 2);
-
-typedef enum
-{
- META_DEBUG_FOCUS = 1 << 0,
- META_DEBUG_WORKAREA = 1 << 1,
- META_DEBUG_STACK = 1 << 2,
- META_DEBUG_THEMES = 1 << 3,
- META_DEBUG_SM = 1 << 4,
- META_DEBUG_EVENTS = 1 << 5,
- META_DEBUG_WINDOW_STATE = 1 << 6,
- META_DEBUG_WINDOW_OPS = 1 << 7,
- META_DEBUG_GEOMETRY = 1 << 8,
- META_DEBUG_PLACEMENT = 1 << 9,
- META_DEBUG_PING = 1 << 10,
- META_DEBUG_XINERAMA = 1 << 11,
- META_DEBUG_KEYBINDINGS = 1 << 12,
- META_DEBUG_SYNC = 1 << 13,
- META_DEBUG_ERRORS = 1 << 14,
- META_DEBUG_STARTUP = 1 << 15,
- META_DEBUG_PREFS = 1 << 16,
- META_DEBUG_GROUPS = 1 << 17,
- META_DEBUG_RESIZING = 1 << 18,
- META_DEBUG_SHAPES = 1 << 19,
- META_DEBUG_COMPOSITOR = 1 << 20,
- META_DEBUG_EDGE_RESISTANCE = 1 << 21
-} MetaDebugTopic;
-
-void meta_topic_real (MetaDebugTopic topic,
- const char *format,
- ...) G_GNUC_PRINTF (2, 3);
-
-void meta_push_no_msg_prefix (void);
-void meta_pop_no_msg_prefix (void);
-
-gint meta_unsigned_long_equal (gconstpointer v1,
- gconstpointer v2);
-guint meta_unsigned_long_hash (gconstpointer v);
-
-void meta_print_backtrace (void);
-
-const char* meta_gravity_to_string (int gravity);
-
-#include <libintl.h>
-#define _(x) dgettext (GETTEXT_PACKAGE, x)
-#define N_(x) x
-
-char* meta_g_utf8_strndup (const gchar *src, gsize n);
-
-void meta_free_gslist_and_elements (GSList *list_to_deep_free);
-
-void meta_show_dialog (const char *type,
- const char *title,
- const char *message,
- gint timeout,
- const char **columns,
- const char **entries);
-
-/* To disable verbose mode, we make these functions into no-ops */
-#ifdef WITH_VERBOSE_MODE
-
-#define meta_debug_spew meta_debug_spew_real
-#define meta_verbose meta_verbose_real
-#define meta_topic meta_topic_real
-
-#else
-
-# ifdef G_HAVE_ISO_VARARGS
-# define meta_debug_spew(...)
-# define meta_verbose(...)
-# define meta_topic(...)
-# elif defined(G_HAVE_GNUC_VARARGS)
-# define meta_debug_spew(format...)
-# define meta_verbose(format...)
-# define meta_topic(format...)
-# else
-# error "This compiler does not support varargs macros and thus verbose mode can't be disabled meaningfully"
-# endif
-
-#endif /* !WITH_VERBOSE_MODE */
-
-#endif /* META_UTIL_H */
-
-
diff --git a/src/include/window.h b/src/include/window.h
deleted file mode 100644
index 8a338660..00000000
--- a/src/include/window.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2008 Iain Holmes
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_WINDOW_H
-#define META_WINDOW_H
-
-#include <glib.h>
-#include <X11/Xlib.h>
-
-#include "boxes.h"
-#include "types.h"
-
-MetaFrame *meta_window_get_frame (MetaWindow *window);
-gboolean meta_window_has_focus (MetaWindow *window);
-gboolean meta_window_is_shaded (MetaWindow *window);
-MetaRectangle *meta_window_get_rect (MetaWindow *window);
-MetaScreen *meta_window_get_screen (MetaWindow *window);
-MetaDisplay *meta_window_get_display (MetaWindow *window);
-Window meta_window_get_xwindow (MetaWindow *window);
-
-#endif
diff --git a/src/include/xprops.h b/src/include/xprops.h
deleted file mode 100644
index f5ecb6ac..00000000
--- a/src/include/xprops.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity X property convenience routines */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_XPROPS_H
-#define META_XPROPS_H
-
-#include <config.h>
-
-#include "display.h"
-#include <X11/Xutil.h>
-
-#ifdef HAVE_XSYNC
-#include <X11/extensions/sync.h>
-#endif
-
-/* Copied from Lesstif by way of GTK. Rudimentary docs can be
- * found in some Motif reference guides online.
- */
-typedef struct {
- unsigned long flags;
- unsigned long functions;
- unsigned long decorations;
- long input_mode;
- unsigned long status;
-} MotifWmHints, MwmHints;
-
-#define MWM_HINTS_FUNCTIONS (1L << 0)
-#define MWM_HINTS_DECORATIONS (1L << 1)
-#define MWM_HINTS_INPUT_MODE (1L << 2)
-#define MWM_HINTS_STATUS (1L << 3)
-
-#define MWM_FUNC_ALL (1L << 0)
-#define MWM_FUNC_RESIZE (1L << 1)
-#define MWM_FUNC_MOVE (1L << 2)
-#define MWM_FUNC_MINIMIZE (1L << 3)
-#define MWM_FUNC_MAXIMIZE (1L << 4)
-#define MWM_FUNC_CLOSE (1L << 5)
-
-#define MWM_DECOR_ALL (1L << 0)
-#define MWM_DECOR_BORDER (1L << 1)
-#define MWM_DECOR_RESIZEH (1L << 2)
-#define MWM_DECOR_TITLE (1L << 3)
-#define MWM_DECOR_MENU (1L << 4)
-#define MWM_DECOR_MINIMIZE (1L << 5)
-#define MWM_DECOR_MAXIMIZE (1L << 6)
-
-#define MWM_INPUT_MODELESS 0
-#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
-#define MWM_INPUT_SYSTEM_MODAL 2
-#define MWM_INPUT_FULL_APPLICATION_MODAL 3
-#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL
-
-#define MWM_TEAROFF_WINDOW (1L<<0)
-
-/* These all return the memory from Xlib, so require an XFree()
- * when they return TRUE. They return TRUE on success.
- */
-gboolean meta_prop_get_atom_list (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- Atom **atoms_p,
- int *n_atoms_p);
-gboolean meta_prop_get_motif_hints (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- MotifWmHints **hints_p);
-gboolean meta_prop_get_cardinal_list (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- gulong **cardinals_p,
- int *n_cardinals_p);
-gboolean meta_prop_get_latin1_string (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- char **str_p);
-gboolean meta_prop_get_utf8_string (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- char **str_p);
-gboolean meta_prop_get_utf8_list (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- char ***str_p,
- int *n_str_p);
-void meta_prop_set_utf8_string_hint
- (MetaDisplay *display,
- Window xwindow,
- Atom atom,
- const char *val);
-gboolean meta_prop_get_window (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- Window *window_p);
-gboolean meta_prop_get_cardinal (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- gulong *cardinal_p);
-gboolean meta_prop_get_cardinal_with_atom_type (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- Atom prop_type,
- gulong *cardinal_p);
-gboolean meta_prop_get_text_property (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- char **utf8_str_p);
-
-gboolean meta_prop_get_wm_hints (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- XWMHints **hints_p);
-
-gboolean meta_prop_get_class_hint (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- XClassHint *class_hint);
-
-gboolean meta_prop_get_size_hints (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- XSizeHints **hints_p,
- gulong *flags_p);
-
-typedef enum
-{
- META_PROP_VALUE_INVALID,
- META_PROP_VALUE_UTF8,
- META_PROP_VALUE_STRING,
- META_PROP_VALUE_STRING_AS_UTF8,
- META_PROP_VALUE_MOTIF_HINTS,
- META_PROP_VALUE_CARDINAL,
- META_PROP_VALUE_WINDOW,
- META_PROP_VALUE_CARDINAL_LIST,
- META_PROP_VALUE_UTF8_LIST,
- META_PROP_VALUE_ATOM_LIST,
- META_PROP_VALUE_TEXT_PROPERTY, /* comes back as UTF-8 string */
- META_PROP_VALUE_WM_HINTS,
- META_PROP_VALUE_CLASS_HINT,
- META_PROP_VALUE_SIZE_HINTS,
- META_PROP_VALUE_SYNC_COUNTER /* comes back as CARDINAL */
-} MetaPropValueType;
-
-/* used to request/return/store property values */
-typedef struct
-{
- MetaPropValueType type;
- Atom atom;
- Atom required_type; /* autofilled if None */
-
- union
- {
- char *str;
- MotifWmHints *motif_hints;
- Window xwindow;
- gulong cardinal;
- XWMHints *wm_hints;
- XClassHint class_hint;
-#ifdef HAVE_XSYNC
- XSyncCounter xcounter;
-#endif
-
- struct
- {
- XSizeHints *hints;
- unsigned long flags;
- } size_hints;
-
- struct
- {
- gulong *cardinals;
- int n_cardinals;
- } cardinal_list;
-
- struct
- {
- char **strings;
- int n_strings;
- } string_list;
-
- struct
- {
- Atom *atoms;
- int n_atoms;
- } atom_list;
-
- } v;
-
-} MetaPropValue;
-
-/* Each value has type and atom initialized. If there's an error,
- * or property is unset, type comes back as INVALID;
- * else type comes back as it originated, and the data
- * is filled in.
- */
-void meta_prop_get_values (MetaDisplay *display,
- Window xwindow,
- MetaPropValue *values,
- int n_values);
-
-void meta_prop_free_values (MetaPropValue *values,
- int n_values);
-
-#endif
-
-
-
-
diff --git a/src/libmetacity-private.pc.in b/src/libmetacity-private.pc.in
deleted file mode 100644
index 3f034b62..00000000
--- a/src/libmetacity-private.pc.in
+++ /dev/null
@@ -1,12 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-libgnome_serverdir=@libexecdir@
-
-Name: libmetacity-private
-Description: Metacity internals shared
-Requires: gtk+-2.0
-Version: @VERSION@
-Libs: -L${libdir} -lmetacity-private
-Cflags: -I${includedir}/metacity-1
diff --git a/src/metacity-wm.desktop.in b/src/metacity-wm.desktop.in
deleted file mode 100644
index 91b81246..00000000
--- a/src/metacity-wm.desktop.in
+++ /dev/null
@@ -1,21 +0,0 @@
-[Desktop Entry]
-Type=Application
-Encoding=UTF-8
-_Name=Metacity
-Exec=metacity
-# name of loadable control center module
-X-GNOME-WMSettingsModule=metacity
-# name we put on the WM spec check window
-X-GNOME-WMName=Metacity
-# back compat only
-X-GnomeWMSettingsLibrary=metacity
-X-GNOME-Bugzilla-Bugzilla=GNOME
-X-GNOME-Bugzilla-Product=metacity
-X-GNOME-Bugzilla-Component=general
-X-GNOME-Autostart-Phase=WindowManager
-X-GNOME-Provides=windowmanager
-X-GNOME-Autostart-Notify=true
-
-[Window Manager]
-SessionManaged=true
-
diff --git a/src/metacity.desktop.in b/src/metacity.desktop.in
deleted file mode 100644
index e6b5d475..00000000
--- a/src/metacity.desktop.in
+++ /dev/null
@@ -1,18 +0,0 @@
-[Desktop Entry]
-Type=Application
-Encoding=UTF-8
-_Name=Metacity
-Exec=metacity
-NoDisplay=true
-# name of loadable control center module
-X-GNOME-WMSettingsModule=metacity
-# name we put on the WM spec check window
-X-GNOME-WMName=Metacity
-# back compat only
-X-GnomeWMSettingsLibrary=metacity
-X-GNOME-Bugzilla-Bugzilla=GNOME
-X-GNOME-Bugzilla-Product=metacity
-X-GNOME-Bugzilla-Component=general
-X-GNOME-Autostart-Phase=WindowManager
-X-GNOME-Provides=windowmanager
-X-GNOME-Autostart-Notify=true
diff --git a/src/metacity.schemas.in.in b/src/metacity.schemas.in.in
deleted file mode 100644
index 41b7c267..00000000
--- a/src/metacity.schemas.in.in
+++ /dev/null
@@ -1,554 +0,0 @@
-<gconfschemafile>
- <schemalist>
-
- <!-- General preferences -->
-
- <schema>
- <key>/schemas/apps/metacity/general/mouse_button_modifier</key>
- <applyto>/apps/metacity/general/mouse_button_modifier</applyto>
- <owner>metacity</owner>
- <type>string</type>
- <default>&lt;Alt&gt;</default>
- <locale name="C">
- <short>Modifier to use for modified window click actions</short>
- <long>
- Clicking a window while holding down this modifier key
- will move the window (left click), resize the window
- (middle click), or show the window menu (right click).
- Modifier is expressed as "&lt;Alt&gt;" or "&lt;Super&gt;"
- for example.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/general/button_layout</key>
- <applyto>/apps/metacity/general/button_layout</applyto>
- <owner>metacity</owner>
- <type>string</type>
- <default>menu:minimize,maximize,close</default>
- <locale name="C">
- <short>Arrangement of buttons on the titlebar</short>
- <long>
- Arrangement of buttons on the titlebar. The
- value should be a string, such as
- "menu:minimize,maximize,spacer,close"; the colon separates the
- left corner of the window from the right corner, and
- the button names are comma-separated. Duplicate buttons
- are not allowed. Unknown button names are silently ignored
- so that buttons can be added in future metacity versions
- without breaking older versions.
- A special spacer tag can be used to insert some space between
- two adjacent buttons.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/general/focus_mode</key>
- <applyto>/apps/metacity/general/focus_mode</applyto>
- <owner>metacity</owner>
- <type>string</type>
- <default>click</default>
- <locale name="C">
- <short>Window focus mode</short>
- <long>
- The window focus mode indicates how windows are activated.
- It has three possible values; "click" means windows must
- be clicked in order to focus them, "sloppy" means windows
- are focused when the mouse enters the window, and "mouse" means
- windows are focused when the mouse enters the window and
- unfocused when the mouse leaves the window.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/general/focus_new_windows</key>
- <applyto>/apps/metacity/general/focus_new_windows</applyto>
- <owner>metacity</owner>
- <type>string</type>
- <default>smart</default>
- <locale name="C">
- <short>Control how new windows get focus</short>
- <long>
- This option provides additional control over how newly created
- windows get focus. It has two possible values; "smart" applies
- the user's normal focus mode, and "strict" results in windows
- started from a terminal not being given focus.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/general/raise_on_click</key>
- <applyto>/apps/metacity/general/raise_on_click</applyto>
- <owner>metacity</owner>
- <type>bool</type>
- <default>true</default>
- <locale name="C">
- <short>Whether raising should be a side-effect of other user
- interactions</short>
- <long>
- Setting this option to false can lead to buggy behavior, so
- users are strongly discouraged from changing it from the default
- of true.
-
- Many actions (e.g. clicking in the client area, moving or resizing the window)
- normally raise the window as a side-effect. Setting this option to false, which
- is strongly discouraged, will decouple raising from other user actions, and
- ignore raise requests generated by applications. See
- http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6.
- Even when this option is false, windows can
- still be raised by an alt-left-click anywhere on the window, a
- normal click on the window decorations, or by special messages
- from pagers, such as activation requests from tasklist applets.
- This option is currently disabled in click-to-focus mode.
-
- Note that the list of ways to raise windows when raise_on_click
- is false does not include programmatic requests from
- applications to raise windows; such requests will be ignored
- regardless of the reason for the request. If you are an
- application developer and have a user complaining that your
- application does not work with this setting disabled, tell them
- it is _their_ fault for breaking their window manager and that
- they need to change this option back to true or live with the
- "bug" they requested.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/general/action_double_click_titlebar</key>
- <applyto>/apps/metacity/general/action_double_click_titlebar</applyto>
- <owner>metacity</owner>
- <type>string</type>
- <default>toggle_maximize</default>
- <locale name="C">
- <short>Action on title bar double-click</short>
- <long>
- This option determines the effects of double-clicking on the
- title bar. Current valid options are
- 'toggle_shade', which will shade/unshade the window,
- 'toggle_maximize' which will maximize/unmaximize the window,
- 'toggle_maximize_horizontally' and 'toggle_maximize_vertically'
- which will maximize/unmaximize the window in that direction only,
- 'minimize' which will minimize the window,
- 'shade' which will roll the window up,
- 'menu' which will display the window menu,
- 'lower' which will put the window behind all the others,
- and 'none' which will not do anything.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/general/action_middle_click_titlebar</key>
- <applyto>/apps/metacity/general/action_middle_click_titlebar</applyto>
- <owner>metacity</owner>
- <type>string</type>
- <default>lower</default>
- <locale name="C">
- <short>Action on title bar middle-click</short>
- <long>
- This option determines the effects of middle-clicking on the
- title bar. Current valid options are
- 'toggle_shade', which will shade/unshade the window,
- 'toggle_maximize' which will maximize/unmaximize the window,
- 'toggle_maximize_horizontally' and 'toggle_maximize_vertically'
- which will maximize/unmaximize the window in that direction only,
- 'minimize' which will minimize the window,
- 'shade' which will roll the window up,
- 'menu' which will display the window menu,
- 'lower' which will put the window behind all the others,
- and 'none' which will not do anything.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/general/action_right_click_titlebar</key>
- <applyto>/apps/metacity/general/action_right_click_titlebar</applyto>
- <owner>metacity</owner>
- <type>string</type>
- <default>menu</default>
- <locale name="C">
- <short>Action on title bar right-click</short>
- <long>
- This option determines the effects of right-clicking on the
- title bar. Current valid options are
- 'toggle_shade', which will shade/unshade the window,
- 'toggle_maximize' which will maximize/unmaximize the window,
- 'toggle_maximize_horizontally' and 'toggle_maximize_vertically'
- which will maximize/unmaximize the window in that direction only,
- 'minimize' which will minimize the window,
- 'shade' which will roll the window up,
- 'menu' which will display the window menu,
- 'lower' which will put the window behind all the others,
- and 'none' which will not do anything.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/general/auto_raise</key>
- <applyto>/apps/metacity/general/auto_raise</applyto>
- <owner>metacity</owner>
- <type>bool</type>
- <default>false</default>
- <locale name="C">
- <short>Automatically raises the focused window</short>
- <long>
- If set to true, and the focus mode is either "sloppy" or "mouse"
- then the focused window will be automatically raised after a
- delay specified by the auto_raise_delay key. This is not related
- to clicking on a window to raise it, nor to entering a window
- during drag-and-drop.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/general/auto_raise_delay</key>
- <applyto>/apps/metacity/general/auto_raise_delay</applyto>
- <owner>metacity</owner>
- <type>int</type>
- <default>500</default>
- <locale name="C">
- <short>Delay in milliseconds for the auto raise option</short>
- <long>
- The time delay before raising a window if auto_raise is set to
- true. The delay is given in thousandths of a second.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/general/theme</key>
- <applyto>/apps/metacity/general/theme</applyto>
- <owner>metacity</owner>
- <type>string</type>
- <default>Clearlooks</default>
- <locale name="C">
- <short>Current theme</short>
- <long>
- The theme determines the appearance of window borders,
- titlebar, and so forth.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/general/titlebar_uses_system_font</key>
- <applyto>/apps/metacity/general/titlebar_uses_system_font</applyto>
- <owner>metacity</owner>
- <type>bool</type>
- <default>false</default>
- <locale name="C">
- <short>Use standard system font in window titles</short>
- <long>
- If true, ignore the titlebar_font
- option, and use the standard application font for window
- titles.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/general/titlebar_font</key>
- <applyto>/apps/metacity/general/titlebar_font</applyto>
- <owner>metacity</owner>
- <type>string</type>
- <default>Sans Bold 10</default>
- <locale name="C">
- <short>Window title font</short>
- <long>
- A font description string describing a font for window
- titlebars. The size from the description will only be used if the
- titlebar_font_size option is set to 0. Also, this option is
- disabled if the titlebar_uses_desktop_font option is set to true.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/general/num_workspaces</key>
- <applyto>/apps/metacity/general/num_workspaces</applyto>
- <owner>metacity</owner>
- <type>int</type>
- <default>4</default>
- <locale name="C">
- <short>Number of workspaces</short>
- <long>
- Number of workspaces. Must be more than zero, and has a fixed
- maximum to prevent making the desktop unusable by accidentally
- asking for too many workspaces.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/general/visual_bell</key>
- <applyto>/apps/metacity/general/visual_bell</applyto>
- <owner>metacity</owner>
- <type>bool</type>
- <default>false</default>
- <locale name="C">
- <short>Enable Visual Bell</short>
- <long>
- Turns on a visual indication when an application or the system
- issues a 'bell' or 'beep'; useful for the hard-of-hearing and for
- use in noisy environments.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/general/audible_bell</key>
- <applyto>/apps/metacity/general/audible_bell</applyto>
- <owner>metacity</owner>
- <type>bool</type>
- <default>true</default>
- <locale name="C">
- <short>System Bell is Audible</short>
- <long>
- Determines whether applications or the system can generate
- audible 'beeps'; may be used in conjunction with 'visual bell' to
- allow silent 'beeps'.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/general/visual_bell_type</key>
- <applyto>/apps/metacity/general/visual_bell_type</applyto>
- <owner>metacity</owner>
- <type>string</type>
- <default>fullscreen</default>
- <locale name="C">
- <short>Visual Bell Type</short>
- <long>
- Tells Metacity how to implement the visual indication that the
- system bell or another application 'bell' indicator has been
- rung. Currently there are two valid values, "fullscreen", which
- causes a fullscreen white-black flash, and "frame_flash" which
- causes the titlebar of the application which sent the bell signal
- to flash. If the application which sent the bell is unknown (as
- is usually the case for the default "system beep"), the currently
- focused window's titlebar is flashed.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/general/compositing_manager</key>
- <applyto>/apps/metacity/general/compositing_manager</applyto>
- <owner>metacity</owner>
- <type>bool</type>
- <default>false</default>
- <locale name="C">
- <short>Compositing Manager</short>
- <long>
- Determines whether Metacity is a compositing manager.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/workspace_names/name</key>
- <applyto>/apps/metacity/workspace_names/name_1</applyto>
- <applyto>/apps/metacity/workspace_names/name_2</applyto>
- <applyto>/apps/metacity/workspace_names/name_3</applyto>
- <applyto>/apps/metacity/workspace_names/name_4</applyto>
- <applyto>/apps/metacity/workspace_names/name_5</applyto>
- <applyto>/apps/metacity/workspace_names/name_6</applyto>
- <applyto>/apps/metacity/workspace_names/name_7</applyto>
- <applyto>/apps/metacity/workspace_names/name_8</applyto>
- <applyto>/apps/metacity/workspace_names/name_9</applyto>
- <applyto>/apps/metacity/workspace_names/name_10</applyto>
- <applyto>/apps/metacity/workspace_names/name_11</applyto>
- <applyto>/apps/metacity/workspace_names/name_12</applyto>
- <applyto>/apps/metacity/workspace_names/name_13</applyto>
- <applyto>/apps/metacity/workspace_names/name_14</applyto>
- <applyto>/apps/metacity/workspace_names/name_15</applyto>
- <applyto>/apps/metacity/workspace_names/name_16</applyto>
- <owner>metacity</owner>
- <type>string</type>
- <default></default>
- <locale name="C">
- <short>Name of workspace</short>
- <long>
- The name of a workspace.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/general/reduced_resources</key>
- <applyto>/apps/metacity/general/reduced_resources</applyto>
- <owner>metacity</owner>
- <type>bool</type>
- <default>false</default>
- <locale name="C">
- <short>If true, trade off usability for less resource usage</short>
- <long>
- If true, metacity will give the user less feedback by using
- wireframes, avoiding animations, or other means. This is a
- significant reduction in usability for many users, but may allow
- legacy applications to continue working, and may also be a
- useful tradeoff for terminal servers. However, the wireframe
- feature is disabled when accessibility is on.
- </long>
- </locale>
- </schema>
-
- <!-- Keybindings -->
-
- <schema>
- <key>/schemas/apps/metacity/global_keybindings/run_command</key>
- <applyto>/apps/metacity/global_keybindings/run_command_1</applyto>
- <applyto>/apps/metacity/global_keybindings/run_command_2</applyto>
- <applyto>/apps/metacity/global_keybindings/run_command_3</applyto>
- <applyto>/apps/metacity/global_keybindings/run_command_4</applyto>
- <applyto>/apps/metacity/global_keybindings/run_command_5</applyto>
- <applyto>/apps/metacity/global_keybindings/run_command_6</applyto>
- <applyto>/apps/metacity/global_keybindings/run_command_7</applyto>
- <applyto>/apps/metacity/global_keybindings/run_command_8</applyto>
- <applyto>/apps/metacity/global_keybindings/run_command_9</applyto>
- <applyto>/apps/metacity/global_keybindings/run_command_10</applyto>
- <applyto>/apps/metacity/global_keybindings/run_command_11</applyto>
- <applyto>/apps/metacity/global_keybindings/run_command_12</applyto>
- <owner>metacity</owner>
- <type>string</type>
- <default>disabled</default>
- <locale name="C">
- <short>Run a defined command</short>
- <long>
- The keybinding that runs the correspondingly-numbered
- command in /apps/metacity/keybinding_commands
-
- The format looks like "&lt;Control&gt;a" or
- "&lt;Shift&gt;&lt;Alt&gt;F1".
-
- The parser is fairly liberal and allows lower or upper case,
- and also abbreviations such as "&lt;Ctl&gt;" and
- "&lt;Ctrl&gt;". If you set the option to the special string
- "disabled", then there will be no keybinding for this
- action.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/keybinding_commands/command</key>
- <applyto>/apps/metacity/keybinding_commands/command_1</applyto>
- <applyto>/apps/metacity/keybinding_commands/command_2</applyto>
- <applyto>/apps/metacity/keybinding_commands/command_3</applyto>
- <applyto>/apps/metacity/keybinding_commands/command_4</applyto>
- <applyto>/apps/metacity/keybinding_commands/command_5</applyto>
- <applyto>/apps/metacity/keybinding_commands/command_6</applyto>
- <applyto>/apps/metacity/keybinding_commands/command_7</applyto>
- <applyto>/apps/metacity/keybinding_commands/command_8</applyto>
- <applyto>/apps/metacity/keybinding_commands/command_9</applyto>
- <applyto>/apps/metacity/keybinding_commands/command_10</applyto>
- <applyto>/apps/metacity/keybinding_commands/command_11</applyto>
- <applyto>/apps/metacity/keybinding_commands/command_12</applyto>
- <owner>metacity</owner>
- <type>string</type>
- <default> </default>
- <locale name="C">
- <short>Commands to run in response to keybindings</short>
- <long>
- The /apps/metacity/global_keybindings/run_command_N
- keys define keybindings that correspond to these commands.
- Pressing the keybinding for run_command_N will
- execute command_N.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/keybinding_commands/command_screenshot</key>
- <applyto>/apps/metacity/keybinding_commands/command_screenshot</applyto>
- <owner>metacity</owner>
- <type>string</type>
- <default>gnome-screenshot</default>
- <locale name="C">
- <short>The screenshot command</short>
- <long>
- The /apps/metacity/global_keybindings/run_command_screenshot
- key defines a keybinding which causes the command specified
- by this setting to be invoked.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/keybinding_commands/command_window_screenshot</key>
- <applyto>/apps/metacity/keybinding_commands/command_window_screenshot</applyto>
- <owner>metacity</owner>
- <type>string</type>
- <default>gnome-screenshot --window</default>
- <locale name="C">
- <short>The window screenshot command</short>
- <long>
- The /apps/metacity/global_keybindings/run_command_window_screenshot
- key defines a keybinding which causes the command specified
- by this setting to be invoked.
- </long>
- </locale>
- </schema>
-
- <!-- Schemas below are generated by schema-bindings.c when this file
- becomes metacity.schemas.in
- -->
- <!-- GENERATED -->
-
- <!-- Not used and/or crackrock -->
-
- <schema>
- <key>/schemas/apps/metacity/general/application_based</key>
- <applyto>/apps/metacity/general/application_based</applyto>
- <owner>metacity</owner>
- <type>bool</type>
- <default>false</default>
- <locale name="C">
- <short>(Not implemented) Navigation works in terms of applications not windows</short>
- <long>
- If true, then Metacity works in terms of applications rather than
- windows. The concept is a bit abstract, but in general an
- application-based setup is more like the Mac and less like
- Windows. When you focus a window in application-based mode, all
- the windows in the application will be raised. Also, in
- application-based mode, focus clicks are not passed through to
- windows in other applications. Application-based mode is,
- however, largely unimplemented at the moment.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/metacity/general/disable_workarounds</key>
- <applyto>/apps/metacity/general/disable_workarounds</applyto>
- <owner>metacity</owner>
- <type>bool</type>
- <default>false</default>
- <locale name="C">
- <short>Disable misfeatures that are required by old or broken
- applications</short>
- <long>
- Some applications disregard specifications in ways that result in
- window manager misfeatures. This option puts Metacity in a
- rigorously correct mode, which gives a more consistent user
- interface, provided one does not need to run any misbehaving
- applications.
- </long>
- </locale>
- </schema>
-
- </schemalist>
-</gconfschemafile>
-
-
-
-
diff --git a/src/run-metacity.sh b/src/run-metacity.sh
deleted file mode 100755
index e0d9265a..00000000
--- a/src/run-metacity.sh
+++ /dev/null
@@ -1,109 +0,0 @@
-#! /bin/bash
-
-if test -z "$XNEST_DISPLAY"; then
- XNEST_DISPLAY=:8
-fi
-
-if test -z "$CLIENT_DISPLAY"; then
- CLIENT_DISPLAY=:8
-fi
-
-if test -z "$METACITY_DISPLAY"; then
- export METACITY_DISPLAY=$CLIENT_DISPLAY
-fi
-
-if test -z "$SCREENS"; then
- SCREENS=1
-fi
-
-MAX_SCREEN=`echo $SCREENS-1 | bc`
-
-if test "$DEBUG" = none; then
- DEBUG=
-elif test -z "$DEBUG"; then
- DEBUG=
-fi
-
-if test -z "$CLIENTS"; then
- CLIENTS=0
-fi
-
-if test -z "$SM_CLIENTS"; then
- SM_CLIENTS=0
-fi
-
-if test -n "$EVIL_TEST"; then
- TEST_CLIENT='./wm-tester/wm-tester --evil'
-fi
-
-if test -n "$ICON_TEST"; then
- TEST_CLIENT='./wm-tester/wm-tester --icon-windows'
-fi
-
-if test -n "$DEMO_TEST"; then
- TEST_CLIENT='./tools/metacity-window-demo'
-fi
-
-if test -n "$XINERAMA"; then
- XINERAMA_FLAGS='+xinerama'
-fi
-
-export EF_ALLOW_MALLOC_0=1
-
-if test -z "$ONLY_WM"; then
- echo "Launching Xnest"
- Xnest -ac $XNEST_DISPLAY -scrns $SCREENS -geometry 640x480 -bw 15 $XINERAMA_FLAGS &
- ## usleep 800000
- sleep 1
-
- if test -n "$XMON_DIR"; then
- echo "Launching xmond"
- $XMON_DIR/xmonui | $XMON_DIR/xmond -server localhost:$XNEST_DISPLAY &
- sleep 1
- fi
-
- if test -n "$XSCOPE_DIR"; then
- ## xscope doesn't like to die when it should, it backgrounds itself
- killall -9 xscope
- killall -9 xscope
- echo "Launching xscope"
- DISPLAY= $XSCOPE_DIR/xscope -o1 -i28 > xscoped-replies.txt &
- export METACITY_DISPLAY=localhost:28
- sleep 1
- fi
-
- echo "Launching clients"
- if test -n "$TEST_CLIENT"; then
- for I in `seq 0 $MAX_SCREEN`; do
- DISPLAY=$CLIENT_DISPLAY.$I $TEST_CLIENT &
- done
- fi
-
- if test $CLIENTS != 0; then
- for I in `seq 1 $CLIENTS`; do
- echo "Launching xterm $I"
- DISPLAY=$CLIENT_DISPLAY xterm -geometry 25x15 &
- done
- fi
-
- if test $SM_CLIENTS != 0; then
- for I in `seq 1 $SM_CLIENTS`; do
- echo "Launching gnome-terminal $I"
- DISPLAY=$CLIENT_DISPLAY gnome-terminal --geometry 25x15 &
- done
- fi
-
- if test -e ~/.Xmodmap; then
- DISPLAY=$CLIENT_DISPLAY xmodmap ~/.Xmodmap
- fi
-
- usleep 50000
-
- for I in `seq 0 $MAX_SCREEN`; do
- DISPLAY=$CLIENT_DISPLAY.$I xsetroot -solid royalblue3
- done
-fi
-
-if test -z "$ONLY_SETUP"; then
- METACITY_VERBOSE=1 METACITY_USE_LOGFILE=1 METACITY_DEBUG_BUTTON_GRABS=1 exec $DEBUG ./metacity $OPTIONS
-fi
diff --git a/src/stock_delete.png b/src/stock_delete.png
deleted file mode 100644
index 429401cb..00000000
--- a/src/stock_delete.png
+++ /dev/null
Binary files differ
diff --git a/src/stock_maximize.png b/src/stock_maximize.png
deleted file mode 100644
index 6f108405..00000000
--- a/src/stock_maximize.png
+++ /dev/null
Binary files differ
diff --git a/src/stock_minimize.png b/src/stock_minimize.png
deleted file mode 100644
index a22e3c45..00000000
--- a/src/stock_minimize.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/.cvsignore b/src/themes/.cvsignore
deleted file mode 100644
index 282522db..00000000
--- a/src/themes/.cvsignore
+++ /dev/null
@@ -1,2 +0,0 @@
-Makefile
-Makefile.in
diff --git a/src/themes/AgingGorilla/README b/src/themes/AgingGorilla/README
deleted file mode 100644
index c275e5ee..00000000
--- a/src/themes/AgingGorilla/README
+++ /dev/null
@@ -1,7 +0,0 @@
-* Gorilla *
-
-A metacity theme to accompany Scalable and Unscalable Gorilla nautilus
-themes.
-
-(c) 2001 Jakub 'jimmac' Steiner
-Ported by Kenneth Christiansen
diff --git a/src/themes/AgingGorilla/active-button.png b/src/themes/AgingGorilla/active-button.png
deleted file mode 100644
index 64455b33..00000000
--- a/src/themes/AgingGorilla/active-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/AgingGorilla/active-close-button.png b/src/themes/AgingGorilla/active-close-button.png
deleted file mode 100644
index 1d292165..00000000
--- a/src/themes/AgingGorilla/active-close-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/AgingGorilla/active-close-menu-icon.png b/src/themes/AgingGorilla/active-close-menu-icon.png
deleted file mode 100644
index b77f77ae..00000000
--- a/src/themes/AgingGorilla/active-close-menu-icon.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/AgingGorilla/active-maximize-button.png b/src/themes/AgingGorilla/active-maximize-button.png
deleted file mode 100644
index a982e5cb..00000000
--- a/src/themes/AgingGorilla/active-maximize-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/AgingGorilla/active-maximize-menu-icon.png b/src/themes/AgingGorilla/active-maximize-menu-icon.png
deleted file mode 100644
index 02ccc37a..00000000
--- a/src/themes/AgingGorilla/active-maximize-menu-icon.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/AgingGorilla/active-menu-button.png b/src/themes/AgingGorilla/active-menu-button.png
deleted file mode 100644
index b55d7078..00000000
--- a/src/themes/AgingGorilla/active-menu-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/AgingGorilla/active-minimize-button.png b/src/themes/AgingGorilla/active-minimize-button.png
deleted file mode 100644
index 4205f4e8..00000000
--- a/src/themes/AgingGorilla/active-minimize-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/AgingGorilla/active-minimize-menu-icon.png b/src/themes/AgingGorilla/active-minimize-menu-icon.png
deleted file mode 100644
index 29276929..00000000
--- a/src/themes/AgingGorilla/active-minimize-menu-icon.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/AgingGorilla/gorilla.xcf.bz2 b/src/themes/AgingGorilla/gorilla.xcf.bz2
deleted file mode 100644
index 89b85651..00000000
--- a/src/themes/AgingGorilla/gorilla.xcf.bz2
+++ /dev/null
Binary files differ
diff --git a/src/themes/AgingGorilla/inactive-close-button.png b/src/themes/AgingGorilla/inactive-close-button.png
deleted file mode 100644
index c566b12f..00000000
--- a/src/themes/AgingGorilla/inactive-close-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/AgingGorilla/inactive-maximize-button.png b/src/themes/AgingGorilla/inactive-maximize-button.png
deleted file mode 100644
index 9c838823..00000000
--- a/src/themes/AgingGorilla/inactive-maximize-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/AgingGorilla/inactive-menu-button.png b/src/themes/AgingGorilla/inactive-menu-button.png
deleted file mode 100644
index b000a378..00000000
--- a/src/themes/AgingGorilla/inactive-menu-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/AgingGorilla/inactive-minimize-button.png b/src/themes/AgingGorilla/inactive-minimize-button.png
deleted file mode 100644
index 4459af4e..00000000
--- a/src/themes/AgingGorilla/inactive-minimize-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/AgingGorilla/metacity-theme-1.xml b/src/themes/AgingGorilla/metacity-theme-1.xml
deleted file mode 100644
index f4f75eb7..00000000
--- a/src/themes/AgingGorilla/metacity-theme-1.xml
+++ /dev/null
@@ -1,291 +0,0 @@
-<?xml version="1.0"?>
-<metacity_theme>
-<info>
- <name>Gorilla</name>
- <author>Kenneth Christiansen &lt;kenneth@gnu.org&gt; Anders Carlsson &lt;andersca@gnu.org&gt;</author>
- <copyright>&#194; Ximian, Inc, 2001</copyright>
- <date>February 8, 2002</date>
- <description>A port of the Gorilla theme by Jacub Steiner</description>
-</info>
-
-<!-- define constants -->
-<constant name="IconTitleSpacing" value="2"/> <!-- Space between menu button and title -->
-<constant name="ButtonWidth" value="18"/> <!-- Button width -->
-
-<frame_geometry name="normal">
- <distance name="left_width" value="6"/>
- <distance name="right_width" value="6"/>
- <distance name="bottom_height" value="6"/>
- <distance name="left_titlebar_edge" value="8"/>
- <distance name="right_titlebar_edge" value="8"/>
- <aspect_ratio name="button" value="1.0"/>
- <distance name="title_vertical_pad" value="0"/>
- <border name="title_border" left="0" right="0" top="7" bottom="4"/>
- <border name="button_border" left="0" right="0" top="9" bottom="0"/>
-</frame_geometry>
-
-<frame_geometry name="border" has_title="false">
- <distance name="left_width" value="4"/>
- <distance name="right_width" value="4"/>
- <distance name="bottom_height" value="4"/>
- <distance name="left_titlebar_edge" value="0"/>
- <distance name="right_titlebar_edge" value="0"/>
- <distance name="button_width" value="0"/>
- <distance name="button_height" value="0"/>
- <distance name="title_vertical_pad" value="4"/>
- <border name="title_border" left="0" right="0" top="0" bottom="0"/>
- <border name="button_border" left="0" right="0" top="0" bottom="0"/>
-</frame_geometry>
-
-<!-- Buttons -->
-
-<draw_ops name="title_tile">
- <line color="#494d59" x1="0" y1="0" x2="width" y2="0"/>
- <line color="#515961" x1="0" y1="1" x2="width" y2="1"/>
-</draw_ops>
-
-<!-- Inactive style -->
-<frame_style name="normal" geometry="normal">
- <piece position="entire_background">
- <draw_ops>
- <rectangle color="black" x="1" y="1" width="width - 2" height="height - 2" filled="true"/>
- <rectangle color="dark gray" x="3" y="3" width="width - 8" height="height - 7" filled="false"/>
- <rectangle color="light gray" x="4" y="4" width="width - 9" height="height - 8" filled="false"/>
- <rectangle color="light gray" x="5" y="5" width="width - 11" height="height - 10" filled="false"/>
- <rectangle color="white" x="6" y="6" width="width - 13" height="height - 12" filled="false"/>
- <rectangle color="gtk:bg[INSENSITIVE]" x="6" y="6" width="width - 12" height="height - 12" filled="true"/>
-
- <line color="gtk:bg[INSENSITIVE]" x1="1" y1="1" x2="2" y2="2"/>
- <line color="gtk:bg[INSENSITIVE]" x1="1" y1="height - 2" x2="1" y2="height"/>
- <line color="gtk:bg[INSENSITIVE]" x1="width - 2" y1="1" x2="width - 1" y2="2"/>
- <line color="gtk:bg[INSENSITIVE]" x1="width - 1" y1="height - 1" x2="width - 2" y2="height - 2"/>
- </draw_ops>
- </piece>
-
- <piece position="title">
- <draw_ops>
- <title color="gray" x="IconTitleSpacing" y="0"/>
- </draw_ops>
- </piece>
-
- <piece position="titlebar">
- <draw_ops>
- <rectangle color="black" x="6" y="6" width="width - 12" height="height - 10" filled="true"/>
- <tile name="title_tile" tile_width="width" tile_height="2" x="8" y="8" width="width - 16" height="height - 14"/>
- </draw_ops>
- </piece>
-
- <button function="close" state="normal">
- <draw_ops>
- <image filename="inactive-close-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="close" state="pressed">
- <draw_ops>
- <image filename="inactive-close-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="normal">
- <draw_ops>
- <image filename="inactive-minimize-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="pressed">
- <draw_ops>
- <image filename="inactive-minimize-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="normal">
- <draw_ops>
- <image filename="inactive-maximize-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="pressed">
- <draw_ops>
- <image filename="inactive-maximize-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="menu" state="normal">
- <draw_ops>
- <image filename="inactive-menu-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="menu" state="pressed">
- <draw_ops>
- <image filename="inactive-menu-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
-
-</frame_style>
-
-
-<!-- Active (focused) shaded style -->
-<frame_style name="normal_shaded" geometry="normal" parent="normal">
-
-</frame_style>
-
-<!-- Active (focused) style -->
-<frame_style name="focused" geometry="normal">
- <piece position="entire_background">
- <draw_ops>
- <rectangle color="black" x="0" y="0" width="width" height="height" filled="true"/>
- <rectangle color="dark gray" x="3" y="3" width="width - 8" height="height - 7" filled="false"/>
- <rectangle color="light gray" x="4" y="4" width="width - 9" height="height - 8" filled="false"/>
- <rectangle color="light gray" x="5" y="5" width="width - 11" height="height - 10" filled="false"/>
- <rectangle color="white" x="6" y="6" width="width - 13" height="height - 12" filled="false"/>
- <rectangle color="gtk:bg[NORMAL]" x="6" y="6" width="width - 12" height="height - 12" filled="true"/>
-
- <line color="gtk:bg[NORMAL]" x1="0" y1="0" x2="1" y2="1"/>
- <line color="gtk:bg[NORMAL]" x1="0" y1="height - 1" x2="1" y2="height"/>
- <line color="gtk:bg[NORMAL]" x1="width - 1" y1="0" x2="width" y2="1"/>
- <line color="gtk:bg[NORMAL]" x1="width" y1="height" x2="width - 1" y2="height - 1"/>
- </draw_ops>
- </piece>
-
- <piece position="title">
- <draw_ops>
- <title color="white" x="IconTitleSpacing" y="0"/>
- </draw_ops>
- </piece>
-
- <piece position="titlebar">
- <draw_ops>
- <rectangle color="black" x="6" y="6" width="width - 12" height="height - 10" filled="true"/>
- <tile name="title_tile" tile_width="width" tile_height="2" x="8" y="8" width="width - 16" height="height - 14"/>
- </draw_ops>
- </piece>
-
- <button function="close" state="normal">
- <draw_ops>
- <image filename="active-close-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="close" state="pressed">
- <draw_ops>
- <image filename="active-close-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="normal">
- <draw_ops>
- <image filename="active-minimize-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="pressed">
- <draw_ops>
- <image filename="active-minimize-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="normal">
- <draw_ops>
- <image filename="active-maximize-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="pressed">
- <draw_ops>
- <image filename="active-maximize-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="menu" state="normal">
- <draw_ops>
- <image filename="active-menu-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="menu" state="pressed">
- <draw_ops>
- <image filename="active-menu-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
-</frame_style>
-
-<!-- Active (focused) shaded style -->
-<frame_style name="focused_shaded" geometry="normal" parent="focused">
-
-</frame_style>
-
-<frame_style_set name="normal">
-<frame focus="yes" state="shaded" style="focused_shaded"/>
-<frame focus="yes" state="normal" resize="both" style="focused"/>
-<frame focus="yes" state="maximized" style="focused"/>
-<frame focus="yes" state="maximized_and_shaded" style="focused_shaded"/>
-<frame focus="no" state="normal" resize="both" style="normal"/>
-<frame focus="no" state="shaded" style="normal_shaded"/>
-<frame focus="no" state="maximized" style="normal"/>
-<frame focus="no" state="maximized_and_shaded" style="normal_shaded"/>
-</frame_style_set>
-
-<draw_ops name="blank">
-<!-- nothing -->
-</draw_ops>
-
-<frame_style name="border" geometry="border" parent="normal">
- <piece position="title" draw_ops="blank"/>
-</frame_style>
-
-<frame_style_set name="border">
-<frame focus="yes" state="normal" resize="both" style="border"/>
-<frame focus="no" state="normal" resize="both" style="border"/>
-<frame focus="yes" state="maximized" style="border"/>
-<frame focus="no" state="maximized" style="border"/>
-<frame focus="yes" state="shaded" style="border"/>
-<frame focus="no" state="shaded" style="border"/>
-<frame focus="yes" state="maximized_and_shaded" style="border"/>
-<frame focus="no" state="maximized_and_shaded" style="border"/>
-</frame_style_set>
-
-<window type="normal" style_set="normal"/>
-<window type="dialog" style_set="normal"/>
-<window type="modal_dialog" style_set="normal"/>
-<window type="menu" style_set="normal"/>
-<window type="utility" style_set="normal"/>
-<window type="border" style_set="border"/>
-
-<menu_icon function="maximize" state="normal">
- <draw_ops>
- <image filename="active-maximize-menu-icon.png"
- x="(width - object_width) / 2"
- y="(height - object_height) / 2"
- width="object_width" height="object_height"/>
- </draw_ops>
-</menu_icon>
-
-
-<menu_icon function="close" state="normal">
- <draw_ops>
- <image filename="active-close-menu-icon.png"
- x="(width - object_width) / 2"
- y="(height - object_height) / 2"
- width="object_width" height="object_height"/>
- </draw_ops>
-</menu_icon>
-
-<menu_icon function="minimize" state="normal">
- <draw_ops>
- <image filename="active-minimize-menu-icon.png"
- x="(width - object_width) / 2"
- y="(height - object_height) / 2"
- width="object_width" height="object_height"/>
- </draw_ops>
-</menu_icon>
-
-<menu_icon function="unmaximize" state="normal">
- <draw_ops>
- </draw_ops>
-</menu_icon>
-
-</metacity_theme>
diff --git a/src/themes/Atlanta/metacity-theme-1.xml b/src/themes/Atlanta/metacity-theme-1.xml
deleted file mode 100644
index 8355f4c3..00000000
--- a/src/themes/Atlanta/metacity-theme-1.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0"?>
-<metacity_theme>
-<info>
- <name>Default</name>
- <author>Havoc Pennington &lt;hp@redhat.com&gt;</author>
- <copyright>&#194; Havoc Pennington, 2002</copyright>
- <date>February 3, 2002</date>
- <description>Simple low-overhead default theme that comes with Metacity.</description>
-</info>
-
-<frame_geometry name="normal">
- <distance name="left_width" value="6"/>
- <distance name="right_width" value="6"/>
- <distance name="bottom_height" value="7"/>
- <distance name="left_titlebar_edge" value="6"/>
- <distance name="right_titlebar_edge" value="6"/>
- <aspect_ratio name="button" value="1.0"/>
- <distance name="title_vertical_pad" value="3"/>
- <border name="title_border" left="3" right="4" top="4" bottom="3"/>
- <border name="button_border" left="0" right="0" top="1" bottom="1"/>
-</frame_geometry>
-
-<!-- strip borders off the normal geometry -->
-<frame_geometry name="normal_small_borders" parent="normal">
- <distance name="left_width" value="0"/>
- <distance name="right_width" value="0"/>
- <distance name="bottom_height" value="0"/>
- <distance name="left_titlebar_edge" value="0"/>
- <distance name="right_titlebar_edge" value="0"/>
-</frame_geometry>
-
-<frame_geometry name="utility" title_scale="xx-small">
- <distance name="left_width" value="3"/>
- <distance name="right_width" value="3"/>
- <distance name="bottom_height" value="4"/>
- <distance name="left_titlebar_edge" value="3"/>
- <distance name="right_titlebar_edge" value="3"/>
- <distance name="button_width" value="11"/>
- <distance name="button_height" value="11"/>
- <distance name="title_vertical_pad" value="1"/>
- <border name="title_border" left="3" right="4" top="3" bottom="3"/>
- <border name="button_border" left="0" right="0" top="1" bottom="1"/>
-</frame_geometry>
-
-<frame_geometry name="border" has_title="false">
- <distance name="left_width" value="4"/>
- <distance name="right_width" value="4"/>
- <distance name="bottom_height" value="4"/>
- <distance name="left_titlebar_edge" value="0"/>
- <distance name="right_titlebar_edge" value="0"/>
- <distance name="button_width" value="0"/>
- <distance name="button_height" value="0"/>
- <distance name="title_vertical_pad" value="4"/>
- <border name="title_border" left="0" right="0" top="0" bottom="0"/>
- <border name="button_border" left="0" right="0" top="0" bottom="0"/>
-</frame_geometry>
-
-<!-- define constants -->
-<constant name="ArrowSpacer" value="8"/>
-<constant name="MinArrowSize" value="7"/>
-<constant name="ButtonIPad" value="6"/>
-<constant name="ThickLineWidth" value="3"/>
-<constant name="IconTitleSpacing" value="2"/>
-<constant name="SpacerWidth" value="6"/>
-<constant name="SpacerHeight" value="9"/>
-<constant name="SpacerOffset" value="4"/>
-
-<!-- Buttons -->
-
-<draw_ops name="button_pressed_bg">
- <gtk_box state="active" shadow="in" x="0" y="0" width="width" height="height"/>
-</draw_ops>
-
-<draw_ops name="menu_button">
- <gtk_arrow state="normal" shadow="out" arrow="down"
- x="ArrowSpacer `min` (width-MinArrowSize)/2"
- y="ArrowSpacer `min` (height-MinArrowSize)/2"
- width="(width-(ArrowSpacer*2)) `max` MinArrowSize"
- height="(height-(ArrowSpacer*2)) `max` MinArrowSize"/>
-</draw_ops>
-
-<draw_ops name="menu_button_pressed">
- <include name="menu_button"/>
-</draw_ops>
-
-<draw_ops name="minimize_button">
- <line color="gtk:fg[NORMAL]"
- x1="ButtonIPad"
- y1="height - ButtonIPad - ThickLineWidth + 1"
- x2="width - ButtonIPad"
- y2="height - ButtonIPad - ThickLineWidth + 1"
- width="3"/> <!-- FIXME allow a constant here -->
-</draw_ops>
-
-<draw_ops name="minimize_button_pressed">
- <include name="minimize_button"/>
-</draw_ops>
-
-<draw_ops name="maximize_button">
- <rectangle color="gtk:fg[NORMAL]" filled="false"
- x="ButtonIPad" y="ButtonIPad" width="width-ButtonIPad*2-1" height="height-ButtonIPad*2-1"/>
- <line color="gtk:fg[NORMAL]" width="3"
- x1="ButtonIPad" y1="ButtonIPad+1" x2="width-ButtonIPad" y2="ButtonIPad+1"/>
-</draw_ops>
-
-<draw_ops name="maximize_button_pressed">
- <include name="maximize_button"/>
-</draw_ops>
-
-<draw_ops name="mini_window_icon">
- <rectangle color="gtk:bg[NORMAL]" filled="true"
- x="0" y="0" width="width-1" height="height-1"/>
- <rectangle color="gtk:fg[NORMAL]" filled="false"
- x="0" y="0" width="width-1" height="height-1"/>
- <line color="gtk:fg[NORMAL]" width="2"
- x1="0" y1="1" x2="width" y2="1"/>
-</draw_ops>
-
-<draw_ops name="restore_button">
- <include name="mini_window_icon"
- x="ButtonIPad" y="ButtonIPad"
- width="width - 5 - ButtonIPad"
- height="height - 5 - ButtonIPad"/>
- <include name="mini_window_icon"
- x="3 + ButtonIPad" y="3 + ButtonIPad"
- width="width - 5 - ButtonIPad"
- height="height - 5 - ButtonIPad"/>
-</draw_ops>
-
-<draw_ops name="restore_button_pressed">
- <include name="restore_button"/>
-</draw_ops>
-
-<draw_ops name="close_button">
- <line color="gtk:fg[NORMAL]"
- x1="ButtonIPad" y1="ButtonIPad"
- x2="width - ButtonIPad - 1" y2="height - ButtonIPad - 1"
- width="1"/>
- <line color="gtk:fg[NORMAL]"
- x1="ButtonIPad" y1="height - ButtonIPad - 1"
- x2="width - ButtonIPad - 1" y2="ButtonIPad"
- width="1"/>
-</draw_ops>
-
-<draw_ops name="close_button_pressed">
- <include name="close_button"/>
-</draw_ops>
-
-<draw_ops name="outer_bevel">
- <rectangle color="gtk:fg[NORMAL]"
- x="0" y="0" width="width-1" height="height-1"/>
- <line color="gtk:light[NORMAL]"
- x1="1" y1="1" x2="1" y2="height-2"/>
- <line color="gtk:light[NORMAL]"
- x1="1" y1="1" x2="width-2" y2="1"/>
- <line color="gtk:dark[NORMAL]"
- x1="width-2" y1="1" x2="width-2" y2="height-2"/>
- <line color="gtk:dark[NORMAL]"
- x1="1" y1="height-2" x2="width-2" y2="height-2"/>
-</draw_ops>
-
-<draw_ops name="blank">
-<!-- nothing -->
-</draw_ops>
-
-<draw_ops name="focus_outline">
- <rectangle color="gtk:fg[NORMAL]"
- x="left_width-1" y="top_height-1"
- width="width-left_width-right_width+1"
- height="height-top_height-bottom_height+1"/>
-</draw_ops>
-
-<draw_ops name="focus_background">
- <include name="outer_bevel"/>
- <include name="focus_outline"/>
-</draw_ops>
-
-<draw_ops name="background_unfocused">
- <include name="outer_bevel"/>
- <include name="focus_outline"/>
-</draw_ops>
-
-<draw_ops name="title_gradient">
- <gradient type="diagonal" x="0" y="0" width="width-SpacerWidth" height="height">
- <color value="blend/gtk:bg[NORMAL]/gtk:bg[SELECTED]/0.6"/>
- <color value="gtk:bg[SELECTED]"/>
- </gradient>
-</draw_ops>
-
-<draw_ops name="title_spacer">
- <gtk_vline state="normal" x="width+1-SpacerWidth/2"
- y1="SpacerOffset"
- y2="height - SpacerOffset"/>
-</draw_ops>
-
-<draw_ops name="title_text_focused_with_icon">
- <clip x="0" y="0" width="width-SpacerWidth" height="height"/>
- <title color="gtk:fg[SELECTED]"
- x="(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2 + mini_icon_width + IconTitleSpacing"
- y="((height - title_height) / 2) `max` 0"/>
- <icon x="(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2"
- y="(height-mini_icon_height) / 2"
- width="mini_icon_width" height="mini_icon_height"/>
-</draw_ops>
-
-<draw_ops name="title_text_focused_no_icon">
- <clip x="0" y="0" width="width-SpacerWidth" height="height"/>
- <title color="gtk:fg[SELECTED]"
- x="(0 `max` (width-title_width)) / 2"
- y="((height - title_height) / 2) `max` 0"/>
-</draw_ops>
-
-<draw_ops name="title_text_with_icon">
- <clip x="0" y="0" width="width-SpacerWidth" height="height"/>
- <title color="gtk:fg[NORMAL]"
- x="(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2 + mini_icon_width + IconTitleSpacing"
- y="((height - title_height) / 2) `max` 0"/>
- <icon x="(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2"
- y="(height-mini_icon_height) / 2"
- width="mini_icon_width" height="mini_icon_height"/>
-</draw_ops>
-
-<draw_ops name="title_text_no_icon">
- <clip x="0" y="0" width="width-SpacerWidth" height="height"/>
- <title color="gtk:fg[NORMAL]"
- x="(0 `max` (width-title_width)) / 2"
- y="((height - title_height) / 2) `max` 0"/>
-</draw_ops>
-
-<draw_ops name="title_normal">
- <include name="title_spacer"/>
- <include name="title_text_with_icon"/>
-</draw_ops>
-
-<draw_ops name="title_focused">
- <include name="title_gradient"/>
- <include name="title_spacer"/>
- <include name="title_text_focused_with_icon"/>
-</draw_ops>
-
-<draw_ops name="title_utility">
- <include name="title_spacer"/>
- <include name="title_text_no_icon"/>
-</draw_ops>
-
-<draw_ops name="title_utility_focused">
- <include name="title_gradient"/>
- <include name="title_spacer"/>
- <include name="title_text_focused_no_icon"/>
-</draw_ops>
-
-<frame_style name="normal_unfocused" geometry="normal">
- <piece position="entire_background" draw_ops="background_unfocused"/>
- <piece position="title" draw_ops="title_normal"/>
-
- <!-- we don't specify for prelight, so normal is used -->
- <button function="left_left_background" state="pressed" draw_ops="button_pressed_bg"/>
- <button function="left_middle_background" state="pressed" draw_ops="button_pressed_bg"/>
- <button function="left_right_background" state="pressed" draw_ops="button_pressed_bg"/>
- <button function="right_left_background" state="pressed" draw_ops="button_pressed_bg"/>
- <button function="right_middle_background" state="pressed" draw_ops="button_pressed_bg"/>
- <button function="right_right_background" state="pressed" draw_ops="button_pressed_bg"/>
-
- <button function="close" state="normal" draw_ops="close_button"/>
- <button function="close" state="pressed" draw_ops="close_button_pressed"/>
- <button function="minimize" state="normal" draw_ops="minimize_button"/>
- <button function="minimize" state="pressed" draw_ops="minimize_button_pressed"/>
- <button function="maximize" state="normal" draw_ops="maximize_button"/>
- <button function="maximize" state="pressed" draw_ops="maximize_button_pressed"/>
- <button function="menu" state="normal" draw_ops="menu_button"/>
- <button function="menu" state="pressed" draw_ops="menu_button_pressed"/>
-</frame_style>
-
-<frame_style name="normal_focused" geometry="normal" parent="normal_unfocused">
- <piece position="entire_background" draw_ops="focus_background"/>
- <piece position="title" draw_ops="title_focused"/>
-</frame_style>
-
-<frame_style name="maximized_unfocused" geometry="normal_small_borders" parent="normal_unfocused">
- <piece position="entire_background" draw_ops="blank"/>
- <button function="maximize" state="normal" draw_ops="restore_button"/>
- <button function="maximize" state="pressed" draw_ops="restore_button_pressed"/>
-</frame_style>
-
-<frame_style name="maximized_focused" geometry="normal_small_borders" parent="normal_focused">
- <piece position="entire_background" draw_ops="focus_outline"/>
- <button function="maximize" state="normal" draw_ops="restore_button"/>
- <button function="maximize" state="pressed" draw_ops="restore_button_pressed"/>
-</frame_style>
-
-<frame_style name="utility_unfocused" geometry="utility" parent="normal_unfocused">
- <piece position="title" draw_ops="title_utility"/>
-</frame_style>
-
-<frame_style name="utility_focused" geometry="utility" parent="normal_focused">
- <piece position="title" draw_ops="title_utility_focused"/>
-</frame_style>
-
-<frame_style name="border" geometry="border" parent="normal_unfocused">
- <piece position="entire_background" draw_ops="outer_bevel"/>
- <piece position="title" draw_ops="blank"/>
-</frame_style>
-
-<frame_style_set name="normal">
-<frame focus="yes" state="normal" resize="both" style="normal_focused"/>
-<frame focus="no" state="normal" resize="both" style="normal_unfocused"/>
-<frame focus="yes" state="maximized" style="maximized_focused"/>
-<frame focus="no" state="maximized" style="maximized_unfocused"/>
-<frame focus="yes" state="shaded" style="normal_focused"/>
-<frame focus="no" state="shaded" style="normal_unfocused"/>
-<frame focus="yes" state="maximized_and_shaded" style="maximized_focused"/>
-<frame focus="no" state="maximized_and_shaded" style="maximized_unfocused"/>
-</frame_style_set>
-
-<frame_style_set name="utility" parent="normal">
-<frame focus="yes" state="normal" resize="both" style="utility_focused"/>
-<frame focus="no" state="normal" resize="both" style="utility_unfocused"/>
-<!-- this is a bunch of crack since utility windows shouldn't be maximized -->
-<frame focus="yes" state="maximized" style="utility_focused"/>
-<frame focus="no" state="maximized" style="utility_unfocused"/>
-<frame focus="yes" state="shaded" style="utility_focused"/>
-<frame focus="no" state="shaded" style="utility_unfocused"/>
-<frame focus="yes" state="maximized_and_shaded" style="utility_focused"/>
-<frame focus="no" state="maximized_and_shaded" style="utility_unfocused"/>
-</frame_style_set>
-
-<frame_style_set name="border">
-<frame focus="yes" state="normal" resize="both" style="border"/>
-<frame focus="no" state="normal" resize="both" style="border"/>
-<frame focus="yes" state="maximized" style="border"/>
-<frame focus="no" state="maximized" style="border"/>
-<frame focus="yes" state="shaded" style="border"/>
-<frame focus="no" state="shaded" style="border"/>
-<frame focus="yes" state="maximized_and_shaded" style="border"/>
-<frame focus="no" state="maximized_and_shaded" style="border"/>
-</frame_style_set>
-
-<window type="normal" style_set="normal"/>
-<window type="dialog" style_set="normal"/>
-<window type="modal_dialog" style_set="normal"/>
-<window type="menu" style_set="normal"/>
-<window type="utility" style_set="utility"/>
-<window type="border" style_set="border"/>
-
-<menu_icon function="close" state="normal" draw_ops="close_button"/>
-<menu_icon function="maximize" state="normal" draw_ops="maximize_button"/>
-<menu_icon function="unmaximize" state="normal" draw_ops="restore_button"/>
-<menu_icon function="minimize" state="normal" draw_ops="minimize_button"/>
-
-</metacity_theme>
diff --git a/src/themes/Bright/metacity-theme-1.xml b/src/themes/Bright/metacity-theme-1.xml
deleted file mode 100644
index a55f4462..00000000
--- a/src/themes/Bright/metacity-theme-1.xml
+++ /dev/null
@@ -1,376 +0,0 @@
-<?xml version="1.0"?>
-<metacity_theme>
-<info>
- <name>Bright</name>
- <author>Gaute Lindkvist &lt;lindkvis@linpro.no&gt;</author>
- <copyright>&#194; Havoc Pennington, 2002 for Atlanta. &#194; Gaute Lindkvist, 2002 for modifications</copyright>
- <date>February 3, 2002</date>
- <description>Simple theme based on Havoc Pennington's Atlanta</description>
-</info>
-
-<frame_geometry name="normal">
- <distance name="left_width" value="6"/>
- <distance name="right_width" value="6"/>
- <distance name="bottom_height" value="7"/>
- <distance name="left_titlebar_edge" value="6"/>
- <distance name="right_titlebar_edge" value="6"/>
- <distance name="button_width" value="15"/>
- <distance name="button_height" value="15"/>
- <distance name="title_vertical_pad" value="4"/>
- <border name="title_border" left="3" right="4" top="4" bottom="3"/>
- <border name="button_border" left="1" right="2" top="2" bottom="1"/>
-</frame_geometry>
-
-<!-- strip borders off the normal geometry -->
-<frame_geometry name="normal_small_borders" parent="normal">
- <distance name="left_width" value="4"/>
- <distance name="right_width" value="4"/>
- <distance name="bottom_height" value="5"/>
- <distance name="left_titlebar_edge" value="4"/>
- <distance name="right_titlebar_edge" value="4"/>
-</frame_geometry>
-
-<frame_geometry name="utility" title_scale="xx-small">
- <distance name="left_width" value="3"/>
- <distance name="right_width" value="3"/>
- <distance name="bottom_height" value="4"/>
- <distance name="left_titlebar_edge" value="3"/>
- <distance name="right_titlebar_edge" value="3"/>
- <distance name="button_width" value="11"/>
- <distance name="button_height" value="11"/>
- <distance name="title_vertical_pad" value="1"/>
- <border name="title_border" left="3" right="4" top="3" bottom="3"/>
- <border name="button_border" left="0" right="0" top="1" bottom="1"/>
-</frame_geometry>
-
-<frame_geometry name="border" has_title="false">
- <distance name="left_width" value="4"/>
- <distance name="right_width" value="4"/>
- <distance name="bottom_height" value="4"/>
- <distance name="left_titlebar_edge" value="0"/>
- <distance name="right_titlebar_edge" value="0"/>
- <distance name="button_width" value="0"/>
- <distance name="button_height" value="0"/>
- <distance name="title_vertical_pad" value="4"/>
- <border name="title_border" left="0" right="0" top="0" bottom="0"/>
- <border name="button_border" left="0" right="0" top="0" bottom="0"/>
-</frame_geometry>
-
-<!-- define constants -->
-<constant name="ArrowWidth" value="7"/>
-<constant name="ArrowHeight" value="5"/>
-<constant name="ButtonIPad" value="3"/>
-<constant name="ThickLineWidth" value="3"/>
-<constant name="IconTitleSpacing" value="2"/>
-<constant name="SpacerWidth" value="7"/>
-<constant name="SpacerHeight" value="11"/>
-
-<!-- Buttons -->
-
-<draw_ops name="button_normal_bg">
-<rectangle color="gtk:fg[NORMAL]" filled="false"
- x="0" y="0" width="width-2" height="height-2"/>
-<line color="#BBBBBB"
- x1="1"
- y1="height-1"
- x2="width"
- y2="height-1"
- width="1"/>
-<line color="#BBBBBB"
- x1="width-1"
- y1="1"
- x2="width-1"
- y2="height-1"
- width="1"/>
-<rectangle color="gtk:base[NORMAL]" filled="true"
- x="1" y="1" width="width-3" height="height-3"/>
-</draw_ops>
-
-<draw_ops name="button_pressed_bg">
- <gtk_box state="active" shadow="in" x="0" y="0" width="width" height="height"/>
-</draw_ops>
-
-<draw_ops name="menu_button">
- <clip x="0" y="0" width="width" height="height"/>
-<icon x="(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2"
- y="(height-mini_icon_height) / 2"
- width="mini_icon_width-1" height="mini_icon_height-1"/>
-</draw_ops>
-
-<draw_ops name="menu_button_normal">
- <include name="menu_button"/>
-</draw_ops>
-<draw_ops name="menu_button_pressed">
- <include name="menu_button"/>
-</draw_ops>
-
-<draw_ops name="minimize_button">
- <line color="gtk:fg[NORMAL]"
- x1="ButtonIPad"
- y1="height - ButtonIPad - ThickLineWidth + 1"
- x2="width - ButtonIPad-1"
- y2="height - ButtonIPad - ThickLineWidth + 1"
- width="2"/> <!-- FIXME allow a constant here -->
-</draw_ops>
-
-<draw_ops name="minimize_button_normal">
- <include name="button_normal_bg"/>
- <include name="minimize_button"/>
-</draw_ops>
-
-<draw_ops name="minimize_button_pressed">
- <include name="button_pressed_bg"/>
- <include name="minimize_button"/>
-</draw_ops>
-
-<draw_ops name="maximize_button">
- <rectangle color="gtk:fg[NORMAL]" filled="false"
- x="ButtonIPad" y="ButtonIPad" width="width-ButtonIPad*2-2" height="height-ButtonIPad*2-2"/>
- <line color="gtk:fg[NORMAL]" width="2"
- x1="ButtonIPad" y1="ButtonIPad+1" x2="width-ButtonIPad-1" y2="ButtonIPad+1"/>
-</draw_ops>
-
-<draw_ops name="maximize_button_normal">
- <include name="button_normal_bg"/>
- <include name="maximize_button"/>
-</draw_ops>
-
-<draw_ops name="maximize_button_pressed">
- <include name="button_pressed_bg"/>
- <include name="maximize_button"/>
-</draw_ops>
-
-<draw_ops name="mini_window_icon">
- <rectangle color="gtk:fg[NORMAL]" filled="false"
- x="0" y="0" width="width-3" height="height-3"/>
- <rectangle color="gtk:fg[NORMAL]" filled="false"
- x="0" y="0" width="width-3" height="height-3"/>
- <line color="gtk:fg[NORMAL]" width="1"
- x1="0" y1="1" x2="width-1" y2="1"/>
-</draw_ops>
-
-<draw_ops name="restore_button">
- <include name="mini_window_icon"
- x="ButtonIPad" y="ButtonIPad"
- width="width - 5 - ButtonIPad"
- height="height - 5 - ButtonIPad"/>
- <include name="mini_window_icon"
- x="3 + ButtonIPad" y="3 + ButtonIPad"
- width="width - 5 - ButtonIPad"
- height="height - 5 - ButtonIPad"/>
-</draw_ops>
-
-<draw_ops name="restore_button_normal">
- <include name="button_normal_bg"/>
- <include name="restore_button"/>
-</draw_ops>
-
-<draw_ops name="restore_button_pressed">
- <include name="button_pressed_bg"/>
- <include name="restore_button"/>
-</draw_ops>
-
-<draw_ops name="close_button">
- <line color="gtk:fg[NORMAL]"
- x1="ButtonIPad" y1="ButtonIPad"
- x2="width - ButtonIPad - 2" y2="height - ButtonIPad - 2"/>
- <line color="gtk:fg[NORMAL]"
- x1="ButtonIPad" y1="height - ButtonIPad - 2"
- x2="width - ButtonIPad - 2" y2="ButtonIPad"/>
-</draw_ops>
-
-<draw_ops name="close_button_normal">
- <include name="button_normal_bg"/>
- <include name="close_button"/>
-</draw_ops>
-
-<draw_ops name="close_button_pressed">
- <include name="button_pressed_bg"/>
- <include name="close_button"/>
-</draw_ops>
-
-<draw_ops name="outer_bevel">
- <rectangle color="gtk:fg[NORMAL]"
- x="0" y="0" width="width-1" height="height-1"/>
- <line color="gtk:light[NORMAL]"
- x1="1" y1="1" x2="1" y2="height-2"/>
- <line color="gtk:light[NORMAL]"
- x1="1" y1="1" x2="width-2" y2="1"/>
- <line color="gtk:dark[NORMAL]"
- x1="width-2" y1="1" x2="width-2" y2="height-2"/>
- <line color="gtk:dark[NORMAL]"
- x1="1" y1="height-2" x2="width-2" y2="height-2"/>
-</draw_ops>
-
-<draw_ops name="blank">
-<!-- nothing -->
-</draw_ops>
-
-<draw_ops name="focus_outline">
- <rectangle color="gtk:fg[NORMAL]"
- x="left_width-1" y="top_height-1"
- width="width-left_width-right_width+1"
- height="height-top_height-bottom_height+1"/>
-</draw_ops>
-
-<draw_ops name="focus_background">
- <include name="outer_bevel"/>
- <include name="focus_outline"/>
-</draw_ops>
-
-<draw_ops name="background_unfocused">
- <include name="outer_bevel"/>
- <include name="focus_outline"/>
-</draw_ops>
-
-<draw_ops name="title_box">
-<rectangle color="gtk:fg[NORMAL]" filled="false"
- x="0" y="1" width="width-SpacerWidth+3" height="height-2"/>
-<line color="#BBBBBB"
- x1="2"
- y1="height-2"
- x2="width-SpacerWidth+2"
- y2="height-2"
- width="1"/>
-<line color="#BBBBBB"
- x1="width-5"
- y1="2"
- x2="width-SpacerWidth+2"
- y2="height-2"
- width="1"/>
-<rectangle color="gtk:bg[SELECTED]" filled="true"
- x="1" y="2" width="width-5" height="height-3"/>
-</draw_ops>
-
-<draw_ops name="title_spacer">
- <gtk_vline state="normal" x="width+1-SpacerWidth/2"
- y1="(height-SpacerHeight)/2"
- y2="height - (height-SpacerHeight)/2"/>
-</draw_ops>
-
-<draw_ops name="title_text_focused_no_icon">
- <clip x="3" y="2" width="width-SpacerWidth-2" height="height-4"/>
- <title color="gtk:fg[SELECTED]"
- x="(3 `max` (width-title_width)) / 2+2"
- y="((height - title_height) / 2) `max` 0"/>
-</draw_ops>
-
-<draw_ops name="title_text_no_icon">
- <clip x="3" y="2" width="width-SpacerWidth-2" height="height-4"/>
- <title color="gtk:fg[NORMAL]"
- x="(3 `max` (width-title_width)) / 2+2"
- y="((height - title_height) / 2) `max` 0"/>
-</draw_ops>
-
-<draw_ops name="title_normal">
- <include name="title_text_no_icon"/>
-</draw_ops>
-
-<draw_ops name="title_focused">
- <include name="title_box"/>
- <include name="title_text_focused_no_icon"/>
-</draw_ops>
-
-<draw_ops name="title_utility">
- <include name="title_spacer"/>
- <include name="title_text_no_icon"/>
-</draw_ops>
-
-<draw_ops name="title_utility_focused">
- <include name="title_box"/>
- <include name="title_spacer"/>
- <include name="title_text_focused_no_icon"/>
-</draw_ops>
-
-<frame_style name="normal_unfocused" geometry="normal">
- <piece position="entire_background" draw_ops="background_unfocused"/>
- <piece position="title" draw_ops="title_normal"/>
-
- <!-- we don't specify for prelight, so normal is used -->
- <button function="close" state="normal" draw_ops="close_button_normal"/>
- <button function="close" state="pressed" draw_ops="close_button_pressed"/>
- <button function="minimize" state="normal" draw_ops="minimize_button_normal"/>
- <button function="minimize" state="pressed" draw_ops="minimize_button_pressed"/>
- <button function="maximize" state="normal" draw_ops="maximize_button_normal"/>
- <button function="maximize" state="pressed" draw_ops="maximize_button_pressed"/>
- <button function="menu" state="normal" draw_ops="menu_button_normal"/>
- <button function="menu" state="pressed" draw_ops="menu_button_pressed"/>
-</frame_style>
-
-<frame_style name="normal_focused" geometry="normal" parent="normal_unfocused">
- <piece position="entire_background" draw_ops="focus_background"/>
- <piece position="title" draw_ops="title_focused"/>
-</frame_style>
-
-<frame_style name="maximized_unfocused" geometry="normal_small_borders" parent="normal_unfocused">
- <piece position="entire_background" draw_ops="blank"/>
- <button function="maximize" state="normal" draw_ops="restore_button_normal"/>
- <button function="maximize" state="pressed" draw_ops="restore_button_pressed"/>
-</frame_style>
-
-<frame_style name="maximized_focused" geometry="normal_small_borders" parent="normal_focused">
- <piece position="entire_background" draw_ops="focus_outline"/>
- <button function="maximize" state="normal" draw_ops="restore_button_normal"/>
- <button function="maximize" state="pressed" draw_ops="restore_button_pressed"/>
-</frame_style>
-
-<frame_style name="utility_unfocused" geometry="utility" parent="normal_unfocused">
- <piece position="title" draw_ops="title_utility"/>
-</frame_style>
-
-<frame_style name="utility_focused" geometry="utility" parent="normal_focused">
- <piece position="title" draw_ops="title_utility_focused"/>
-</frame_style>
-
-<frame_style name="border" geometry="border" parent="normal_unfocused">
- <piece position="entire_background" draw_ops="outer_bevel"/>
- <piece position="title" draw_ops="blank"/>
-</frame_style>
-
-<frame_style_set name="normal">
-<frame focus="yes" state="normal" resize="both" style="normal_focused"/>
-<frame focus="no" state="normal" resize="both" style="normal_unfocused"/>
-<frame focus="yes" state="maximized" style="maximized_focused"/>
-<frame focus="no" state="maximized" style="maximized_unfocused"/>
-<frame focus="yes" state="shaded" style="normal_focused"/>
-<frame focus="no" state="shaded" style="normal_unfocused"/>
-<frame focus="yes" state="maximized_and_shaded" style="maximized_focused"/>
-<frame focus="no" state="maximized_and_shaded" style="maximized_unfocused"/>
-</frame_style_set>
-
-<frame_style_set name="utility" parent="normal">
-<frame focus="yes" state="normal" resize="both" style="utility_focused"/>
-<frame focus="no" state="normal" resize="both" style="utility_unfocused"/>
-<!-- this is a bunch of crack since utility windows shouldn't be maximized -->
-<frame focus="yes" state="maximized" style="utility_focused"/>
-<frame focus="no" state="maximized" style="utility_unfocused"/>
-<frame focus="yes" state="shaded" style="utility_focused"/>
-<frame focus="no" state="shaded" style="utility_unfocused"/>
-<frame focus="yes" state="maximized_and_shaded" style="utility_focused"/>
-<frame focus="no" state="maximized_and_shaded" style="utility_unfocused"/>
-</frame_style_set>
-
-<frame_style_set name="border">
-<frame focus="yes" state="normal" resize="both" style="border"/>
-<frame focus="no" state="normal" resize="both" style="border"/>
-<frame focus="yes" state="maximized" style="border"/>
-<frame focus="no" state="maximized" style="border"/>
-<frame focus="yes" state="shaded" style="border"/>
-<frame focus="no" state="shaded" style="border"/>
-<frame focus="yes" state="maximized_and_shaded" style="border"/>
-<frame focus="no" state="maximized_and_shaded" style="border"/>
-</frame_style_set>
-
-<window type="normal" style_set="normal"/>
-<window type="dialog" style_set="normal"/>
-<window type="modal_dialog" style_set="normal"/>
-<window type="menu" style_set="normal"/>
-<window type="utility" style_set="utility"/>
-<window type="border" style_set="border"/>
-
-<menu_icon function="close" state="normal" draw_ops="close_button_normal"/>
-<menu_icon function="maximize" state="normal" draw_ops="maximize_button_normal"/>
-<menu_icon function="unmaximize" state="normal" draw_ops="restore_button_normal"/>
-<menu_icon function="minimize" state="normal" draw_ops="minimize_button_normal"/>
-
-</metacity_theme>
diff --git a/src/themes/Bright/metacity-theme-2.xml b/src/themes/Bright/metacity-theme-2.xml
deleted file mode 100644
index 1a43fe16..00000000
--- a/src/themes/Bright/metacity-theme-2.xml
+++ /dev/null
@@ -1,546 +0,0 @@
-<?xml version="1.0"?>
-<metacity_theme>
-<info>
- <name>Bright</name>
- <author>Gaute Lindkvist &lt;lindkvis@linpro.no&gt;</author>
- <copyright>&#194; Havoc Pennington, 2002 for Atlanta. &#194; Gaute Lindkvist, 2002 for modifications</copyright>
- <date>February 3, 2002</date>
- <description>Simple theme based on Havoc Pennington's Atlanta</description>
-</info>
-
-<frame_geometry name="normal">
- <distance name="left_width" value="6"/>
- <distance name="right_width" value="6"/>
- <distance name="bottom_height" value="7"/>
- <distance name="left_titlebar_edge" value="6"/>
- <distance name="right_titlebar_edge" value="6"/>
- <distance name="button_width" value="15"/>
- <distance name="button_height" value="15"/>
- <distance name="title_vertical_pad" value="4"/>
- <border name="title_border" left="3" right="4" top="4" bottom="3"/>
- <border name="button_border" left="1" right="2" top="2" bottom="1"/>
-</frame_geometry>
-
-<!-- strip borders off the normal geometry -->
-<frame_geometry name="normal_small_borders" parent="normal">
- <distance name="left_width" value="4"/>
- <distance name="right_width" value="4"/>
- <distance name="bottom_height" value="5"/>
- <distance name="left_titlebar_edge" value="4"/>
- <distance name="right_titlebar_edge" value="4"/>
-</frame_geometry>
-
-<frame_geometry name="utility" title_scale="xx-small">
- <distance name="left_width" value="3"/>
- <distance name="right_width" value="3"/>
- <distance name="bottom_height" value="4"/>
- <distance name="left_titlebar_edge" value="3"/>
- <distance name="right_titlebar_edge" value="3"/>
- <distance name="button_width" value="11"/>
- <distance name="button_height" value="11"/>
- <distance name="title_vertical_pad" value="1"/>
- <border name="title_border" left="3" right="4" top="3" bottom="3"/>
- <border name="button_border" left="0" right="0" top="1" bottom="1"/>
-</frame_geometry>
-
-<frame_geometry name="border" has_title="false">
- <distance name="left_width" value="4"/>
- <distance name="right_width" value="4"/>
- <distance name="bottom_height" value="4"/>
- <distance name="left_titlebar_edge" value="0"/>
- <distance name="right_titlebar_edge" value="0"/>
- <distance name="button_width" value="0"/>
- <distance name="button_height" value="0"/>
- <distance name="title_vertical_pad" value="4"/>
- <border name="title_border" left="0" right="0" top="0" bottom="0"/>
- <border name="button_border" left="0" right="0" top="0" bottom="0"/>
-</frame_geometry>
-
-<!-- define constants -->
-<constant name="ArrowWidth" value="7"/>
-<constant name="ArrowHeight" value="5"/>
-<constant name="ButtonIPad" value="3"/>
-<constant name="ThickLineWidth" value="3"/>
-<constant name="IconTitleSpacing" value="2"/>
-<constant name="SpacerWidth" value="7"/>
-<constant name="SpacerHeight" value="11"/>
-
-<!-- Buttons -->
-
-<draw_ops name="button_normal_bg">
-<rectangle color="gtk:fg[NORMAL]" filled="false"
- x="0" y="0" width="width-2" height="height-2"/>
-<line color="#BBBBBB"
- x1="1"
- y1="height-1"
- x2="width"
- y2="height-1"
- width="1"/>
-<line color="#BBBBBB"
- x1="width-1"
- y1="1"
- x2="width-1"
- y2="height-1"
- width="1"/>
-<rectangle color="gtk:base[NORMAL]" filled="true"
- x="1" y="1" width="width-3" height="height-3"/>
-</draw_ops>
-
-<draw_ops name="button_pressed_bg">
- <gtk_box state="active" shadow="in" x="0" y="0" width="width" height="height"/>
-</draw_ops>
-
-<draw_ops name="menu_button">
- <clip x="0" y="0" width="width" height="height"/>
-<icon x="(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2"
- y="(height-mini_icon_height) / 2"
- width="mini_icon_width-1" height="mini_icon_height-1"/>
-</draw_ops>
-
-<draw_ops name="menu_button_normal">
- <include name="menu_button"/>
-</draw_ops>
-<draw_ops name="menu_button_pressed">
- <include name="menu_button"/>
-</draw_ops>
-
-<draw_ops name="minimize_button">
- <line color="gtk:fg[NORMAL]"
- x1="ButtonIPad"
- y1="height - ButtonIPad - ThickLineWidth + 1"
- x2="width - ButtonIPad-1"
- y2="height - ButtonIPad - ThickLineWidth + 1"
- width="ThickLineWidth"/>
-</draw_ops>
-
-<draw_ops name="minimize_button_normal">
- <include name="button_normal_bg"/>
- <include name="minimize_button"/>
-</draw_ops>
-
-<draw_ops name="minimize_button_pressed">
- <include name="button_pressed_bg"/>
- <include name="minimize_button"/>
-</draw_ops>
-
-<draw_ops name="maximize_button">
- <rectangle color="gtk:fg[NORMAL]" filled="false"
- x="ButtonIPad" y="ButtonIPad" width="width-ButtonIPad*2-2" height="height-ButtonIPad*2-2"/>
- <line color="gtk:fg[NORMAL]" width="2"
- x1="ButtonIPad" y1="ButtonIPad+1" x2="width-ButtonIPad-1" y2="ButtonIPad+1"/>
-</draw_ops>
-
-<draw_ops name="maximize_button_normal">
- <include name="button_normal_bg"/>
- <include name="maximize_button"/>
-</draw_ops>
-
-<draw_ops name="maximize_button_pressed">
- <include name="button_pressed_bg"/>
- <include name="maximize_button"/>
-</draw_ops>
-
-<draw_ops name="mini_window_icon">
- <rectangle color="gtk:fg[NORMAL]" filled="false"
- x="0" y="0" width="width-3" height="height-3"/>
- <rectangle color="gtk:fg[NORMAL]" filled="false"
- x="0" y="0" width="width-3" height="height-3"/>
- <line color="gtk:fg[NORMAL]" width="1"
- x1="0" y1="1" x2="width-1" y2="1"/>
-</draw_ops>
-
-<draw_ops name="restore_button">
- <include name="mini_window_icon"
- x="ButtonIPad" y="ButtonIPad"
- width="width - 5 - ButtonIPad"
- height="height - 5 - ButtonIPad"/>
- <include name="mini_window_icon"
- x="3 + ButtonIPad" y="3 + ButtonIPad"
- width="width - 5 - ButtonIPad"
- height="height - 5 - ButtonIPad"/>
-</draw_ops>
-
-<draw_ops name="restore_button_normal">
- <include name="button_normal_bg"/>
- <include name="restore_button"/>
-</draw_ops>
-
-<draw_ops name="restore_button_pressed">
- <include name="button_pressed_bg"/>
- <include name="restore_button"/>
-</draw_ops>
-
-<draw_ops name="close_button">
- <line color="gtk:fg[NORMAL]"
- x1="ButtonIPad" y1="ButtonIPad"
- x2="width - ButtonIPad - 2" y2="height - ButtonIPad - 2"/>
- <line color="gtk:fg[NORMAL]"
- x1="ButtonIPad" y1="height - ButtonIPad - 2"
- x2="width - ButtonIPad - 2" y2="ButtonIPad"/>
-</draw_ops>
-
-<draw_ops name="shade_button">
- <line color="gtk:fg[NORMAL]"
- x1="ButtonIPad"
- y1="ButtonIPad"
- x2="width - ButtonIPad-1"
- y2="ButtonIPad"
- width="ThickLineWidth"/>
-</draw_ops>
-
-<draw_ops name="unshade_button">
- <line color="gtk:fg[NORMAL]"
- x1="ButtonIPad"
- y1="ButtonIPad"
- x2="width - ButtonIPad-1"
- y2="ButtonIPad"
- width="ThickLineWidth"/>
- <rectangle color="gtk:fg[NORMAL]" filled="false"
- x="ButtonIPad"
- y="ButtonIPad*2"
- width="width - ButtonIPad*2-1"
- height="height - ButtonIPad*3-1"/>
-</draw_ops>
-
-<draw_ops name="above_button">
- <line color="gtk:fg[NORMAL]"
- x1="ButtonIPad"
- y1="height/2"
- x2="ButtonIPad + 2"
- y2="height/2"
- width="ThickLineWidth"/>
- <line color="gtk:fg[NORMAL]"
- x1="width - ButtonIPad-1"
- y1="height/2"
- x2="width - ButtonIPad-3"
- y2="height/2"
- width="ThickLineWidth"/>
- <line color="gtk:fg[NORMAL]"
- x1="width/2-1"
- y1="height - ButtonIPad - 2"
- x2="width/2+1"
- y2="height - ButtonIPad - 2"
- width="ThickLineWidth"/>
- <line color="gtk:fg[NORMAL]"
- x1="ButtonIPad"
- y1="ButtonIPad"
- x2="width - ButtonIPad-1"
- y2="ButtonIPad"
- width="ThickLineWidth"/>
-</draw_ops>
-
-<draw_ops name="unabove_button">
- <line color="gtk:fg[NORMAL]"
- x1="ButtonIPad"
- y1="height/2"
- x2="ButtonIPad + 2"
- y2="height/2"
- width="ThickLineWidth"/>
- <line color="gtk:fg[NORMAL]"
- x1="width - ButtonIPad-1"
- y1="height/2"
- x2="width - ButtonIPad-3"
- y2="height/2"
- width="ThickLineWidth"/>
- <line color="gtk:fg[NORMAL]"
- x1="width/2-1"
- y1="height - ButtonIPad - 2"
- x2="width/2+1"
- y2="height - ButtonIPad - 2"
- width="ThickLineWidth"/>
- <line color="gtk:fg[NORMAL]"
- x1="width/2-1"
- y1="ButtonIPad"
- x2="width/2+1"
- y2="ButtonIPad"
- width="ThickLineWidth"/>
-</draw_ops>
-
-<draw_ops name="stick_button">
- <line color="gtk:fg[NORMAL]"
- x1="ButtonIPad" y1="ButtonIPad"
- x2="ButtonIPad" y2="height - ButtonIPad - 2"/>
- <line color="gtk:fg[NORMAL]"
- x1="ButtonIPad" y1="height/2-1"
- x2="width - ButtonIPad - 2" y2="height/2-1"/>
-</draw_ops>
-
-<draw_ops name="unstick_button">
- <line color="gtk:fg[NORMAL]"
- x1="width/2" y1="ButtonIPad"
- x2="width/2" y2="height - ButtonIPad - 2"/>
- <line color="gtk:fg[NORMAL]"
- x1="width/2" y1="height/2-1"
- x2="width - ButtonIPad - 2" y2="height/2-1"/>
- <line color="gtk:fg[NORMAL]"
- x1="width-ButtonIPad-2" y1="height/2-3"
- x2="width-ButtonIPad-2" y2="height/2+2"/>
-</draw_ops>
-
-<draw_ops name="close_button_normal">
- <include name="button_normal_bg"/>
- <include name="close_button"/>
-</draw_ops>
-
-<draw_ops name="close_button_pressed">
- <include name="button_pressed_bg"/>
- <include name="close_button"/>
-</draw_ops>
-
-<draw_ops name="shade_button_normal">
- <include name="button_normal_bg"/>
- <include name="shade_button"/>
-</draw_ops>
-
-<draw_ops name="shade_button_pressed">
- <include name="button_pressed_bg"/>
- <include name="shade_button"/>
-</draw_ops>
-
-<draw_ops name="unshade_button_normal">
- <include name="button_normal_bg"/>
- <include name="unshade_button"/>
-</draw_ops>
-
-<draw_ops name="unshade_button_pressed">
- <include name="button_pressed_bg"/>
- <include name="unshade_button"/>
-</draw_ops>
-
-<draw_ops name="above_button_normal">
- <include name="button_normal_bg"/>
- <include name="above_button"/>
-</draw_ops>
-
-<draw_ops name="above_button_pressed">
- <include name="button_pressed_bg"/>
- <include name="above_button"/>
-</draw_ops>
-
-<draw_ops name="unabove_button_normal">
- <include name="button_normal_bg"/>
- <include name="unabove_button"/>
-</draw_ops>
-
-<draw_ops name="unabove_button_pressed">
- <include name="button_pressed_bg"/>
- <include name="unabove_button"/>
-</draw_ops>
-
-<draw_ops name="stick_button_normal">
- <include name="button_normal_bg"/>
- <include name="stick_button"/>
-</draw_ops>
-
-<draw_ops name="stick_button_pressed">
- <include name="button_pressed_bg"/>
- <include name="stick_button"/>
-</draw_ops>
-
-<draw_ops name="unstick_button_normal">
- <include name="button_normal_bg"/>
- <include name="unstick_button"/>
-</draw_ops>
-
-<draw_ops name="unstick_button_pressed">
- <include name="button_pressed_bg"/>
- <include name="unstick_button"/>
-</draw_ops>
-
-<draw_ops name="outer_bevel">
- <rectangle color="gtk:fg[NORMAL]"
- x="0" y="0" width="width-1" height="height-1"/>
- <line color="gtk:light[NORMAL]"
- x1="1" y1="1" x2="1" y2="height-2"/>
- <line color="gtk:light[NORMAL]"
- x1="1" y1="1" x2="width-2" y2="1"/>
- <line color="gtk:dark[NORMAL]"
- x1="width-2" y1="1" x2="width-2" y2="height-2"/>
- <line color="gtk:dark[NORMAL]"
- x1="1" y1="height-2" x2="width-2" y2="height-2"/>
-</draw_ops>
-
-<draw_ops name="blank">
-<!-- nothing -->
-</draw_ops>
-
-<draw_ops name="focus_outline">
- <rectangle color="gtk:fg[NORMAL]"
- x="left_width-1" y="top_height-1"
- width="width-left_width-right_width+1"
- height="height-top_height-bottom_height+1"/>
-</draw_ops>
-
-<draw_ops name="focus_background">
- <include name="outer_bevel"/>
- <include name="focus_outline"/>
-</draw_ops>
-
-<draw_ops name="background_unfocused">
- <include name="outer_bevel"/>
- <include name="focus_outline"/>
-</draw_ops>
-
-<draw_ops name="title_box">
-<rectangle color="gtk:fg[NORMAL]" filled="false"
- x="0" y="1" width="width-SpacerWidth+3" height="height-2"/>
-<line color="#BBBBBB"
- x1="2"
- y1="height-2"
- x2="width-SpacerWidth+2"
- y2="height-2"
- width="1"/>
-<line color="#BBBBBB"
- x1="width-5"
- y1="2"
- x2="width-SpacerWidth+2"
- y2="height-2"
- width="1"/>
-<rectangle color="gtk:bg[SELECTED]" filled="true"
- x="1" y="2" width="width-5" height="height-3"/>
-</draw_ops>
-
-<draw_ops name="title_spacer">
- <gtk_vline state="normal" x="width+1-SpacerWidth/2"
- y1="(height-SpacerHeight)/2"
- y2="height - (height-SpacerHeight)/2"/>
-</draw_ops>
-
-<draw_ops name="title_text_focused_no_icon">
- <clip x="3" y="2" width="width-SpacerWidth-2" height="height-4"/>
- <title color="gtk:fg[SELECTED]"
- x="(3 `max` (width-title_width)) / 2+2"
- y="((height - title_height) / 2) `max` 0"/>
-</draw_ops>
-
-<draw_ops name="title_text_no_icon">
- <clip x="3" y="2" width="width-SpacerWidth-2" height="height-4"/>
- <title color="gtk:fg[NORMAL]"
- x="(3 `max` (width-title_width)) / 2+2"
- y="((height - title_height) / 2) `max` 0"/>
-</draw_ops>
-
-<draw_ops name="title_normal">
- <include name="title_text_no_icon"/>
-</draw_ops>
-
-<draw_ops name="title_focused">
- <include name="title_box"/>
- <include name="title_text_focused_no_icon"/>
-</draw_ops>
-
-<draw_ops name="title_utility">
- <include name="title_spacer"/>
- <include name="title_text_no_icon"/>
-</draw_ops>
-
-<draw_ops name="title_utility_focused">
- <include name="title_box"/>
- <include name="title_spacer"/>
- <include name="title_text_focused_no_icon"/>
-</draw_ops>
-
-<frame_style name="normal_unfocused" geometry="normal">
- <piece position="entire_background" draw_ops="background_unfocused"/>
- <piece position="title" draw_ops="title_normal"/>
-
- <!-- we don't specify for prelight, so normal is used -->
- <button function="close" state="normal" draw_ops="close_button_normal"/>
- <button function="close" state="pressed" draw_ops="close_button_pressed"/>
- <button function="minimize" state="normal" draw_ops="minimize_button_normal"/>
- <button function="minimize" state="pressed" draw_ops="minimize_button_pressed"/>
- <button function="maximize" state="normal" draw_ops="maximize_button_normal"/>
- <button function="maximize" state="pressed" draw_ops="maximize_button_pressed"/>
- <button function="menu" state="normal" draw_ops="menu_button_normal"/>
- <button function="menu" state="pressed" draw_ops="menu_button_pressed"/>
- <button function="shade" state="normal" draw_ops="shade_button_normal"/>
- <button function="shade" state="pressed" draw_ops="shade_button_pressed"/>
- <button function="unshade" state="normal" draw_ops="unshade_button_normal"/>
- <button function="unshade" state="pressed" draw_ops="unshade_button_pressed"/>
- <button function="above" state="normal" draw_ops="above_button_normal"/>
- <button function="above" state="pressed" draw_ops="above_button_pressed"/>
- <button function="unabove" state="normal" draw_ops="unabove_button_normal"/>
- <button function="unabove" state="pressed" draw_ops="unabove_button_pressed"/>
- <button function="stick" state="normal" draw_ops="stick_button_normal"/>
- <button function="stick" state="pressed" draw_ops="stick_button_pressed"/>
- <button function="unstick" state="normal" draw_ops="unstick_button_normal"/>
- <button function="unstick" state="pressed" draw_ops="unstick_button_pressed"/>
-</frame_style>
-
-<frame_style name="normal_focused" geometry="normal" parent="normal_unfocused">
- <piece position="entire_background" draw_ops="focus_background"/>
- <piece position="title" draw_ops="title_focused"/>
-</frame_style>
-
-<frame_style name="maximized_unfocused" geometry="normal_small_borders" parent="normal_unfocused">
- <piece position="entire_background" draw_ops="blank"/>
- <button function="maximize" state="normal" draw_ops="restore_button_normal"/>
- <button function="maximize" state="pressed" draw_ops="restore_button_pressed"/>
-</frame_style>
-
-<frame_style name="maximized_focused" geometry="normal_small_borders" parent="normal_focused">
- <piece position="entire_background" draw_ops="focus_outline"/>
- <button function="maximize" state="normal" draw_ops="restore_button_normal"/>
- <button function="maximize" state="pressed" draw_ops="restore_button_pressed"/>
-</frame_style>
-
-<frame_style name="utility_unfocused" geometry="utility" parent="normal_unfocused">
- <piece position="title" draw_ops="title_utility"/>
-</frame_style>
-
-<frame_style name="utility_focused" geometry="utility" parent="normal_focused">
- <piece position="title" draw_ops="title_utility_focused"/>
-</frame_style>
-
-<frame_style name="border" geometry="border" parent="normal_unfocused">
- <piece position="entire_background" draw_ops="outer_bevel"/>
- <piece position="title" draw_ops="blank"/>
-</frame_style>
-
-<frame_style_set name="normal">
-<frame focus="yes" state="normal" resize="both" style="normal_focused"/>
-<frame focus="no" state="normal" resize="both" style="normal_unfocused"/>
-<frame focus="yes" state="maximized" style="maximized_focused"/>
-<frame focus="no" state="maximized" style="maximized_unfocused"/>
-<frame focus="yes" state="shaded" style="normal_focused"/>
-<frame focus="no" state="shaded" style="normal_unfocused"/>
-<frame focus="yes" state="maximized_and_shaded" style="maximized_focused"/>
-<frame focus="no" state="maximized_and_shaded" style="maximized_unfocused"/>
-</frame_style_set>
-
-<frame_style_set name="utility" parent="normal">
-<frame focus="yes" state="normal" resize="both" style="utility_focused"/>
-<frame focus="no" state="normal" resize="both" style="utility_unfocused"/>
-<!-- this is a bunch of crack since utility windows shouldn't be maximized -->
-<frame focus="yes" state="maximized" style="utility_focused"/>
-<frame focus="no" state="maximized" style="utility_unfocused"/>
-<frame focus="yes" state="shaded" style="utility_focused"/>
-<frame focus="no" state="shaded" style="utility_unfocused"/>
-<frame focus="yes" state="maximized_and_shaded" style="utility_focused"/>
-<frame focus="no" state="maximized_and_shaded" style="utility_unfocused"/>
-</frame_style_set>
-
-<frame_style_set name="border">
-<frame focus="yes" state="normal" resize="both" style="border"/>
-<frame focus="no" state="normal" resize="both" style="border"/>
-<frame focus="yes" state="maximized" style="border"/>
-<frame focus="no" state="maximized" style="border"/>
-<frame focus="yes" state="shaded" style="border"/>
-<frame focus="no" state="shaded" style="border"/>
-<frame focus="yes" state="maximized_and_shaded" style="border"/>
-<frame focus="no" state="maximized_and_shaded" style="border"/>
-</frame_style_set>
-
-<window type="normal" style_set="normal"/>
-<window type="dialog" style_set="normal"/>
-<window type="modal_dialog" style_set="normal"/>
-<window type="menu" style_set="normal"/>
-<window type="utility" style_set="utility"/>
-<window type="border" style_set="border"/>
-
-<menu_icon function="close" state="normal" draw_ops="close_button_normal"/>
-<menu_icon function="maximize" state="normal" draw_ops="maximize_button_normal"/>
-<menu_icon function="unmaximize" state="normal" draw_ops="restore_button_normal"/>
-<menu_icon function="minimize" state="normal" draw_ops="minimize_button_normal"/>
-
-</metacity_theme>
diff --git a/src/themes/Crux/active-above-button.png b/src/themes/Crux/active-above-button.png
deleted file mode 100644
index 0eec82b8..00000000
--- a/src/themes/Crux/active-above-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-border-top-left-border.png b/src/themes/Crux/active-border-top-left-border.png
deleted file mode 100644
index 2d61acf5..00000000
--- a/src/themes/Crux/active-border-top-left-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-border-top-right-border.png b/src/themes/Crux/active-border-top-right-border.png
deleted file mode 100644
index 9797c0fc..00000000
--- a/src/themes/Crux/active-border-top-right-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-bottom-left-border.png b/src/themes/Crux/active-bottom-left-border.png
deleted file mode 100644
index f22ea1a3..00000000
--- a/src/themes/Crux/active-bottom-left-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-bottom-left-corner.png b/src/themes/Crux/active-bottom-left-corner.png
deleted file mode 100644
index de8fe868..00000000
--- a/src/themes/Crux/active-bottom-left-corner.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-bottom-mid-left-border.png b/src/themes/Crux/active-bottom-mid-left-border.png
deleted file mode 100644
index 7eec69f5..00000000
--- a/src/themes/Crux/active-bottom-mid-left-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-bottom-mid-right-border.png b/src/themes/Crux/active-bottom-mid-right-border.png
deleted file mode 100644
index 63da8e9d..00000000
--- a/src/themes/Crux/active-bottom-mid-right-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-bottom-right-border.png b/src/themes/Crux/active-bottom-right-border.png
deleted file mode 100644
index 61a4f560..00000000
--- a/src/themes/Crux/active-bottom-right-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-bottom-right-corner.png b/src/themes/Crux/active-bottom-right-corner.png
deleted file mode 100644
index 57594466..00000000
--- a/src/themes/Crux/active-bottom-right-corner.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-button-prelight.png b/src/themes/Crux/active-button-prelight.png
deleted file mode 100644
index 6da2ae25..00000000
--- a/src/themes/Crux/active-button-prelight.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-button-pressed.png b/src/themes/Crux/active-button-pressed.png
deleted file mode 100644
index 4fb94aa4..00000000
--- a/src/themes/Crux/active-button-pressed.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-button.png b/src/themes/Crux/active-button.png
deleted file mode 100644
index cd93b8c5..00000000
--- a/src/themes/Crux/active-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-close-button.png b/src/themes/Crux/active-close-button.png
deleted file mode 100644
index bfbfd142..00000000
--- a/src/themes/Crux/active-close-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-left-border.png b/src/themes/Crux/active-left-border.png
deleted file mode 100644
index 89b47f42..00000000
--- a/src/themes/Crux/active-left-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-left-top-border-shaded.png b/src/themes/Crux/active-left-top-border-shaded.png
deleted file mode 100644
index a9e775ac..00000000
--- a/src/themes/Crux/active-left-top-border-shaded.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-left-top-border.png b/src/themes/Crux/active-left-top-border.png
deleted file mode 100644
index 24a13ea9..00000000
--- a/src/themes/Crux/active-left-top-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-maximize-button.png b/src/themes/Crux/active-maximize-button.png
deleted file mode 100644
index 870e2cb6..00000000
--- a/src/themes/Crux/active-maximize-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-menu-button-prelight.png b/src/themes/Crux/active-menu-button-prelight.png
deleted file mode 100644
index db0a88c8..00000000
--- a/src/themes/Crux/active-menu-button-prelight.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-menu-button-pressed.png b/src/themes/Crux/active-menu-button-pressed.png
deleted file mode 100644
index 8ac8201d..00000000
--- a/src/themes/Crux/active-menu-button-pressed.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-menu-button.png b/src/themes/Crux/active-menu-button.png
deleted file mode 100644
index de8e1a7b..00000000
--- a/src/themes/Crux/active-menu-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-minimize-button.png b/src/themes/Crux/active-minimize-button.png
deleted file mode 100644
index ea740ffb..00000000
--- a/src/themes/Crux/active-minimize-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-restore-button.png b/src/themes/Crux/active-restore-button.png
deleted file mode 100644
index ec7259e3..00000000
--- a/src/themes/Crux/active-restore-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-right-border.png b/src/themes/Crux/active-right-border.png
deleted file mode 100644
index 2dea03e3..00000000
--- a/src/themes/Crux/active-right-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-right-top-border-shaded.png b/src/themes/Crux/active-right-top-border-shaded.png
deleted file mode 100644
index cf7ac2ec..00000000
--- a/src/themes/Crux/active-right-top-border-shaded.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-right-top-border.png b/src/themes/Crux/active-right-top-border.png
deleted file mode 100644
index eab9cae0..00000000
--- a/src/themes/Crux/active-right-top-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-shade-button.png b/src/themes/Crux/active-shade-button.png
deleted file mode 100644
index 2c86470e..00000000
--- a/src/themes/Crux/active-shade-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-stick-button.png b/src/themes/Crux/active-stick-button.png
deleted file mode 100644
index 2bb224c5..00000000
--- a/src/themes/Crux/active-stick-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-top-center-left.png b/src/themes/Crux/active-top-center-left.png
deleted file mode 100644
index 9d43fc2f..00000000
--- a/src/themes/Crux/active-top-center-left.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-top-center-mid-left.png b/src/themes/Crux/active-top-center-mid-left.png
deleted file mode 100644
index 927d50e9..00000000
--- a/src/themes/Crux/active-top-center-mid-left.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-top-center-mid-right.png b/src/themes/Crux/active-top-center-mid-right.png
deleted file mode 100644
index 8cea6f6f..00000000
--- a/src/themes/Crux/active-top-center-mid-right.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-top-center-right.png b/src/themes/Crux/active-top-center-right.png
deleted file mode 100644
index e471c363..00000000
--- a/src/themes/Crux/active-top-center-right.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-top-left-border.png b/src/themes/Crux/active-top-left-border.png
deleted file mode 100644
index fa4a6f54..00000000
--- a/src/themes/Crux/active-top-left-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-top-left-corner.png b/src/themes/Crux/active-top-left-corner.png
deleted file mode 100644
index 477e46a9..00000000
--- a/src/themes/Crux/active-top-left-corner.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-top-mid-left-border.png b/src/themes/Crux/active-top-mid-left-border.png
deleted file mode 100644
index 35a42feb..00000000
--- a/src/themes/Crux/active-top-mid-left-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-top-mid-right-border.png b/src/themes/Crux/active-top-mid-right-border.png
deleted file mode 100644
index 1fa16504..00000000
--- a/src/themes/Crux/active-top-mid-right-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-top-right-border.png b/src/themes/Crux/active-top-right-border.png
deleted file mode 100644
index b3f07f2f..00000000
--- a/src/themes/Crux/active-top-right-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-top-right-corner.png b/src/themes/Crux/active-top-right-corner.png
deleted file mode 100644
index 199a3780..00000000
--- a/src/themes/Crux/active-top-right-corner.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-unabove-button.png b/src/themes/Crux/active-unabove-button.png
deleted file mode 100644
index af1104ce..00000000
--- a/src/themes/Crux/active-unabove-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-unshade-button.png b/src/themes/Crux/active-unshade-button.png
deleted file mode 100644
index ddaf11f5..00000000
--- a/src/themes/Crux/active-unshade-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/active-unstick-button.png b/src/themes/Crux/active-unstick-button.png
deleted file mode 100644
index 2936b166..00000000
--- a/src/themes/Crux/active-unstick-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-above-button.png b/src/themes/Crux/inactive-above-button.png
deleted file mode 100644
index dd6de031..00000000
--- a/src/themes/Crux/inactive-above-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-border-top-left-border.png b/src/themes/Crux/inactive-border-top-left-border.png
deleted file mode 100644
index 0f6a1b88..00000000
--- a/src/themes/Crux/inactive-border-top-left-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-border-top-right-border.png b/src/themes/Crux/inactive-border-top-right-border.png
deleted file mode 100644
index 0e37f50b..00000000
--- a/src/themes/Crux/inactive-border-top-right-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-bottom-left-border.png b/src/themes/Crux/inactive-bottom-left-border.png
deleted file mode 100644
index ea174d65..00000000
--- a/src/themes/Crux/inactive-bottom-left-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-bottom-left-corner.png b/src/themes/Crux/inactive-bottom-left-corner.png
deleted file mode 100644
index f6f43632..00000000
--- a/src/themes/Crux/inactive-bottom-left-corner.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-bottom-mid-border.png b/src/themes/Crux/inactive-bottom-mid-border.png
deleted file mode 100644
index b24ea233..00000000
--- a/src/themes/Crux/inactive-bottom-mid-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-bottom-right-border.png b/src/themes/Crux/inactive-bottom-right-border.png
deleted file mode 100644
index 3302e015..00000000
--- a/src/themes/Crux/inactive-bottom-right-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-bottom-right-corner.png b/src/themes/Crux/inactive-bottom-right-corner.png
deleted file mode 100644
index 0fddaac5..00000000
--- a/src/themes/Crux/inactive-bottom-right-corner.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-button-prelight.png b/src/themes/Crux/inactive-button-prelight.png
deleted file mode 100644
index 070a164e..00000000
--- a/src/themes/Crux/inactive-button-prelight.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-button-pressed.png b/src/themes/Crux/inactive-button-pressed.png
deleted file mode 100644
index 88f3f8a0..00000000
--- a/src/themes/Crux/inactive-button-pressed.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-button.png b/src/themes/Crux/inactive-button.png
deleted file mode 100644
index e74564d2..00000000
--- a/src/themes/Crux/inactive-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-close-button.png b/src/themes/Crux/inactive-close-button.png
deleted file mode 100644
index 2f9d0a57..00000000
--- a/src/themes/Crux/inactive-close-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-left-border.png b/src/themes/Crux/inactive-left-border.png
deleted file mode 100644
index 3f7ad16e..00000000
--- a/src/themes/Crux/inactive-left-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-left-top-border-shaded.png b/src/themes/Crux/inactive-left-top-border-shaded.png
deleted file mode 100644
index 177fa41f..00000000
--- a/src/themes/Crux/inactive-left-top-border-shaded.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-left-top-border.png b/src/themes/Crux/inactive-left-top-border.png
deleted file mode 100644
index 74fa074e..00000000
--- a/src/themes/Crux/inactive-left-top-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-maximize-button.png b/src/themes/Crux/inactive-maximize-button.png
deleted file mode 100644
index 73244678..00000000
--- a/src/themes/Crux/inactive-maximize-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-menu-button-prelight.png b/src/themes/Crux/inactive-menu-button-prelight.png
deleted file mode 100644
index 8c45a1bb..00000000
--- a/src/themes/Crux/inactive-menu-button-prelight.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-menu-button-pressed.png b/src/themes/Crux/inactive-menu-button-pressed.png
deleted file mode 100644
index 757ff7c2..00000000
--- a/src/themes/Crux/inactive-menu-button-pressed.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-menu-button.png b/src/themes/Crux/inactive-menu-button.png
deleted file mode 100644
index 89b2a442..00000000
--- a/src/themes/Crux/inactive-menu-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-minimize-button.png b/src/themes/Crux/inactive-minimize-button.png
deleted file mode 100644
index 6cdac563..00000000
--- a/src/themes/Crux/inactive-minimize-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-restore-button.png b/src/themes/Crux/inactive-restore-button.png
deleted file mode 100644
index bafa2967..00000000
--- a/src/themes/Crux/inactive-restore-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-right-border.png b/src/themes/Crux/inactive-right-border.png
deleted file mode 100644
index 0404cc48..00000000
--- a/src/themes/Crux/inactive-right-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-right-top-border-shaded.png b/src/themes/Crux/inactive-right-top-border-shaded.png
deleted file mode 100644
index 92955273..00000000
--- a/src/themes/Crux/inactive-right-top-border-shaded.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-right-top-border.png b/src/themes/Crux/inactive-right-top-border.png
deleted file mode 100644
index c1882e96..00000000
--- a/src/themes/Crux/inactive-right-top-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-shade-button.png b/src/themes/Crux/inactive-shade-button.png
deleted file mode 100644
index 93ff14b2..00000000
--- a/src/themes/Crux/inactive-shade-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-stick-button.png b/src/themes/Crux/inactive-stick-button.png
deleted file mode 100644
index 14ffd9ed..00000000
--- a/src/themes/Crux/inactive-stick-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-top-center-left.png b/src/themes/Crux/inactive-top-center-left.png
deleted file mode 100644
index eaba4798..00000000
--- a/src/themes/Crux/inactive-top-center-left.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-top-center-mid.png b/src/themes/Crux/inactive-top-center-mid.png
deleted file mode 100644
index 7346fbc4..00000000
--- a/src/themes/Crux/inactive-top-center-mid.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-top-center-right.png b/src/themes/Crux/inactive-top-center-right.png
deleted file mode 100644
index 3a2e3a0a..00000000
--- a/src/themes/Crux/inactive-top-center-right.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-top-left-border.png b/src/themes/Crux/inactive-top-left-border.png
deleted file mode 100644
index 8ebbdca9..00000000
--- a/src/themes/Crux/inactive-top-left-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-top-left-corner.png b/src/themes/Crux/inactive-top-left-corner.png
deleted file mode 100644
index 1db17706..00000000
--- a/src/themes/Crux/inactive-top-left-corner.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-top-mid-border.png b/src/themes/Crux/inactive-top-mid-border.png
deleted file mode 100644
index 0ec3b26a..00000000
--- a/src/themes/Crux/inactive-top-mid-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-top-right-border.png b/src/themes/Crux/inactive-top-right-border.png
deleted file mode 100644
index e86fddc7..00000000
--- a/src/themes/Crux/inactive-top-right-border.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-top-right-corner.png b/src/themes/Crux/inactive-top-right-corner.png
deleted file mode 100644
index 7b13da35..00000000
--- a/src/themes/Crux/inactive-top-right-corner.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-unabove-button.png b/src/themes/Crux/inactive-unabove-button.png
deleted file mode 100644
index bc1052d9..00000000
--- a/src/themes/Crux/inactive-unabove-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-unshade-button.png b/src/themes/Crux/inactive-unshade-button.png
deleted file mode 100644
index 982abeac..00000000
--- a/src/themes/Crux/inactive-unshade-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/inactive-unstick-button.png b/src/themes/Crux/inactive-unstick-button.png
deleted file mode 100644
index e4822729..00000000
--- a/src/themes/Crux/inactive-unstick-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Crux/metacity-theme-1.xml b/src/themes/Crux/metacity-theme-1.xml
deleted file mode 100644
index a6994561..00000000
--- a/src/themes/Crux/metacity-theme-1.xml
+++ /dev/null
@@ -1,579 +0,0 @@
-<?xml version="1.0"?>
-<metacity_theme>
-<info>
- <name>Crux</name>
- <author>Anders Carlsson &lt;andersca@gnu.org&gt;</author>
- <copyright>&#194; Eazel Inc, 2000</copyright>
- <date>February 6, 2002</date>
- <description>A port of the Crux theme by Arlo Rose and John Harper</description>
-</info>
-
-<!-- define constants -->
-<constant name="IconTitleSpacing" value="2"/> <!-- Space between menu button and title -->
-<constant name="CenterTitlePieceWidth" value="48"/> <!-- Width of center title piece -->
-<constant name="ButtonWidth" value="16"/> <!-- Button width -->
-
-<frame_geometry name="normal">
- <distance name="left_width" value="5"/>
- <distance name="right_width" value="6"/>
- <distance name="bottom_height" value="6"/>
- <distance name="left_titlebar_edge" value="5"/>
- <distance name="right_titlebar_edge" value="6"/>
- <aspect_ratio name="button" value="1.0"/>
- <distance name="title_vertical_pad" value="0"/>
- <border name="title_border" left="0" right="0" top="3" bottom="3"/>
- <border name="button_border" left="0" right="0" top="3" bottom="3"/>
-</frame_geometry>
-
-<frame_geometry name="border" has_title="false">
- <distance name="left_width" value="5"/>
- <distance name="right_width" value="6"/>
- <distance name="bottom_height" value="6"/>
- <distance name="left_titlebar_edge" value="0"/>
- <distance name="right_titlebar_edge" value="0"/>
- <distance name="button_width" value="0"/>
- <distance name="button_height" value="0"/>
- <distance name="title_vertical_pad" value="5"/>
- <border name="title_border" left="0" right="0" top="0" bottom="0"/>
- <border name="button_border" left="0" right="0" top="0" bottom="0"/>
-</frame_geometry>
-
-<!-- Buttons -->
-
-<draw_ops name="active_button">
- <image filename="active-button.png" x="0" y="0" width="width" height="height"/>
-</draw_ops>
-
-<draw_ops name="active_button_pressed">
- <image filename="active-button-pressed.png" x="0" y="0" width="width" height="height"/>
-</draw_ops>
-
-<draw_ops name="active_button_prelight">
- <image filename="active-button-prelight.png" x="0" y="0" width="width" height="height"/>
-</draw_ops>
-
-<draw_ops name="inactive_button">
- <image filename="inactive-button.png" x="0" y="0" width="width" height="height"/>
-</draw_ops>
-
-<draw_ops name="inactive_button_pressed">
- <image filename="inactive-button-pressed.png" x="0" y="0" width="width" height="height"/>
-</draw_ops>
-
-<draw_ops name="inactive_button_prelight">
- <image filename="inactive-button-prelight.png" x="0" y="0" width="width" height="height"/>
-</draw_ops>
-
-<!-- Inactive style -->
-<frame_style name="normal" geometry="normal">
- <piece position="left_edge">
- <draw_ops>
- <image filename="inactive-left-border.png" x="0" y="0" width="object_width" height="height"/>
- </draw_ops>
- </piece>
-
- <piece position="right_edge">
- <draw_ops>
- <image filename="inactive-right-border.png" x="0" y="0" width="object_width" height="height"/>
- </draw_ops>
- </piece>
-
- <piece position="title">
- <draw_ops>
- <title color="gtk:fg[SELECTED]" x="IconTitleSpacing" y="0"/>
- </draw_ops>
- </piece>
-
- <piece position="titlebar">
- <draw_ops>
-
- <image filename="inactive-left-top-border.png"
- x="0" y="0" width="object_width" height="height"/>
- <image filename="inactive-right-top-border.png"
- x="width - object_width" y="0" width="object_width" height="height"/>
-
- <image filename="inactive-top-center-left.png"
- x="4" y="0"
- width="(left_width + ButtonWidth + IconTitleSpacing + title_width) `min`
- (width - right_width - 3 * ButtonWidth - CenterTitlePieceWidth * height / 22 - 3)"
- height="height"/>
-
- <image filename="inactive-top-center-mid.png"
- x="((left_width + ButtonWidth + IconTitleSpacing + title_width) `min` (width - object_width * height / 22 - right_width - 3 * ButtonWidth)) + 1"
- y="0" width="object_width * height / 22" height="height"/>
-
- <image filename="inactive-top-center-right.png"
- x="((left_width + ButtonWidth + IconTitleSpacing + title_width + CenterTitlePieceWidth * height / 22) `min` (width - 3 * ButtonWidth - right_width)) + 1"
- y="0"
- width="(width - title_width - left_width - ButtonWidth - IconTitleSpacing - CenterTitlePieceWidth * height / 22 - right_width) `max` (3 * ButtonWidth)"
- height="height"/>
-
- </draw_ops>
- </piece>
-
- <!-- We have to draw the bottom edge in the background piece
- because that's the only way we can get the correct window height -->
- <piece position="overlay">
- <draw_ops>
- <image filename="inactive-bottom-left-corner.png"
- x="0" y="height - object_height" width="object_width" height="object_height"/>
- <image filename="inactive-bottom-left-border.png" x="5" y="height - object_height"
- width="((title_width + height / 2 - 4) `min` (width - object_width - 26))"
- height="object_height"/>
- <image filename="inactive-bottom-mid-border.png"
- x="((title_width + height / 2) `min` (width - object_width - 6)) + 1"
- y="height - object_height" width="object_width" height="object_height"/>
-
- <image filename="inactive-bottom-right-border.png"
- x="((title_width + height / 2 + 32)) + 1"
- y="height - object_height"
- width="(width - title_width - height / 2 - 32 - 7) `max` 0"
- height="object_height"/>
-
- <image filename="inactive-bottom-right-corner.png"
- x="width - object_width" y="height - object_height" width="object_height" height="object_height"/>
-
- </draw_ops>
- </piece>
-
- <button function="close" state="normal">
- <draw_ops>
- <include name="inactive_button"/>
- <image filename="inactive-close-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="close" state="pressed">
- <draw_ops>
- <include name="inactive_button_pressed"/>
- <image filename="inactive-close-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="close" state="prelight">
- <draw_ops>
- <include name="inactive_button_prelight"/>
- <image filename="inactive-close-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="normal">
- <draw_ops>
- <include name="inactive_button"/>
- <image filename="inactive-minimize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="pressed">
- <draw_ops>
- <include name="inactive_button_pressed"/>
- <image filename="inactive-minimize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="prelight">
- <draw_ops>
- <include name="inactive_button_prelight"/>
- <image filename="inactive-minimize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="normal">
- <draw_ops>
- <include name="inactive_button"/>
- <image filename="inactive-maximize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="pressed">
- <draw_ops>
- <include name="inactive_button_pressed"/>
- <image filename="inactive-maximize-button.png" x="2" y="2" width="width - 4" height="height - 4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="prelight">
- <draw_ops>
- <include name="inactive_button_prelight"/>
- <image filename="inactive-maximize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="menu" state="normal">
- <draw_ops>
- <image filename="inactive-menu-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="menu" state="pressed">
- <draw_ops>
- <image filename="inactive-menu-button-pressed.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
- <button function="menu" state="prelight">
- <draw_ops>
- <image filename="inactive-menu-button-prelight.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-</frame_style>
-
-<frame_style name="normal_maximized" parent="normal">
- <button function="maximize" state="normal">
- <draw_ops>
- <include name="inactive_button"/>
- <image filename="inactive-restore-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="pressed">
- <draw_ops>
- <include name="inactive_button_pressed"/>
- <image filename="inactive-restore-button.png" x="2" y="2" width="width - 4" height="height - 4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="prelight">
- <draw_ops>
- <include name="inactive_button_prelight"/>
- <image filename="inactive-restore-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
-</frame_style>
-
-<!-- Active (focused) shaded style -->
- <frame_style name="normal_shaded" geometry="normal" parent="normal">
- <piece position="left_titlebar_edge">
- <draw_ops>
- <image filename="inactive-left-top-border-shaded.png" x="0" y="3" width="object_width" height="object_height"/>
- </draw_ops>
- </piece>
- <piece position="right_titlebar_edge">
- <draw_ops>
- <image filename="inactive-right-top-border-shaded.png" x="width - object_width" y="3" width="object_width" height="object_height"/>
- </draw_ops>
- </piece>
- </frame_style>
-
-
-<!-- Active (focused) style -->
-<frame_style name="focused" geometry="normal">
- <piece position="left_edge">
- <draw_ops>
- <image colorize="gtk:bg[SELECTED]" filename="active-left-border.png" x="0" y="0" width="object_width" height="height"/>
- </draw_ops>
- </piece>
-
- <piece position="right_edge">
- <draw_ops>
- <image filename="active-right-border.png" x="0" y="0" width="object_width" height="height"/>
- </draw_ops>
- </piece>
-
- <piece position="title">
- <draw_ops>
- <title color="gtk:fg[SELECTED]" x="IconTitleSpacing" y="((height - title_height) / 2) `max` 0"/>
- </draw_ops>
- </piece>
-
- <piece position="titlebar">
- <draw_ops>
-
- <image filename="active-left-top-border.png"
- colorize="gtk:bg[SELECTED]"
- x="0" y="0" width="object_width" height="height"/>
-
- <image filename="active-right-top-border.png"
- x="width - object_width" y="0" width="object_width" height="height"/>
-
- <image filename="active-top-center-left.png"
- colorize="gtk:bg[SELECTED]"
- x="4" y="0"
- width="(left_width + ButtonWidth + IconTitleSpacing + title_width) `min`
- (width - right_width - 3 * ButtonWidth - CenterTitlePieceWidth * height / 22 - 3)"
- height="height"/>
-
- <image filename="active-top-center-mid-left.png"
- colorize="gtk:bg[SELECTED]"
- x="((left_width + ButtonWidth + IconTitleSpacing + title_width) `min` (width - object_width * height / 22 - right_width - 3 * ButtonWidth)) + 1"
- y="0" width="object_width * height / 22" height="height"/>
-
- <image filename="active-top-center-mid-right.png"
- x="((left_width + ButtonWidth + IconTitleSpacing + title_width) `min` (width - object_width * height / 22 - right_width - 3 * ButtonWidth)) + 1"
- y="0" width="object_width * height / 22" height="height"/>
-
- <image filename="active-top-center-right.png"
- x="((left_width + ButtonWidth + IconTitleSpacing + title_width + CenterTitlePieceWidth * height / 22) `min` (width - 3 * ButtonWidth - right_width)) + 1"
- y="0"
- width="(width - title_width - left_width - ButtonWidth - IconTitleSpacing - CenterTitlePieceWidth * height / 22 - right_width) `max` (3 * ButtonWidth)"
- height="height"/>
-
- </draw_ops>
- </piece>
-
- <!-- We have to draw the bottom edge in the background piece
- because that's the only way we can get the correct window height -->
- <piece position="overlay">
- <draw_ops>
- <image filename="active-bottom-left-corner.png"
- colorize="gtk:bg[SELECTED]"
- x="0" y="height - object_height" width="object_width" height="object_height"/>
- <image filename="active-bottom-left-border.png" x="5" y="height - object_height"
- colorize="gtk:bg[SELECTED]"
- width="((title_width + height / 2 - 4) `min` (width - object_width - 26))"
- height="object_height"/>
- <image filename="active-bottom-mid-left-border.png"
- colorize="gtk:bg[SELECTED]"
- x="((title_width + height / 2) `min` (width - object_width - 6)) + 1"
- y="height - object_height" width="object_width" height="object_height"/>
- <image filename="active-bottom-mid-right-border.png"
- x="((title_width + height / 2) `min` (width - object_width - 6)) + 1"
- y="height - object_height" width="object_width" height="object_height"/>
-
- <image filename="active-bottom-right-border.png"
- x="((title_width + height / 2 + 32)) + 1"
- y="height - object_height"
- width="(width - title_width - height / 2 - 32 - 7) `max` 0"
- height="object_height"/>
-
- <image filename="active-bottom-right-corner.png"
- x="width - object_width" y="height - object_height" width="object_height" height="object_height"/>
-
- </draw_ops>
- </piece>
-
- <button function="close" state="normal">
- <draw_ops>
- <include name="active_button"/>
- <image filename="active-close-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="close" state="pressed">
- <draw_ops>
- <include name="active_button_pressed"/>
- <image filename="active-close-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="close" state="prelight">
- <draw_ops>
- <include name="active_button_prelight"/>
- <image filename="active-close-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="normal">
- <draw_ops>
- <include name="active_button"/>
- <image filename="active-minimize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="pressed">
- <draw_ops>
- <include name="active_button_pressed"/>
- <image filename="active-minimize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="prelight">
- <draw_ops>
- <include name="active_button_prelight"/>
- <image filename="active-minimize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="normal">
- <draw_ops>
- <include name="active_button"/>
- <image filename="active-maximize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="pressed">
- <draw_ops>
- <include name="active_button_pressed"/>
- <image filename="active-maximize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="prelight">
- <draw_ops>
- <include name="active_button_prelight"/>
- <image filename="active-maximize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="menu" state="normal">
- <draw_ops>
- <image colorize="gtk:bg[SELECTED]" filename="active-menu-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="menu" state="pressed">
- <draw_ops>
- <image colorize="gtk:bg[SELECTED]" filename="active-menu-button-pressed.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
- <button function="menu" state="prelight">
- <draw_ops>
- <image colorize="gtk:bg[SELECTED]" filename="active-menu-button-prelight.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-</frame_style>
-
-<frame_style name="focused_maximized" geometry="normal" parent="focused">
- <button function="maximize" state="normal">
- <draw_ops>
- <include name="active_button"/>
- <image filename="active-restore-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="pressed">
- <draw_ops>
- <include name="active_button_pressed"/>
- <image filename="active-restore-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="prelight">
- <draw_ops>
- <include name="active_button_prelight"/>
- <image filename="active-restore-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
-</frame_style>
-
-<!-- Active (focused) shaded style -->
-<frame_style name="focused_shaded" geometry="normal" parent="focused">
- <piece position="left_titlebar_edge">
- <draw_ops>
- <image colorize="gtk:bg[SELECTED]" filename="active-left-top-border-shaded.png" x="0" y="3" width="object_width" height="object_height"/>
- </draw_ops>
- </piece>
- <piece position="right_titlebar_edge">
- <draw_ops>
- <image filename="active-right-top-border-shaded.png" x="width - object_width" y="3" width="object_width" height="object_height"/>
- </draw_ops>
- </piece>
-</frame_style>
-
-<!-- Inactive border style -->
-<frame_style name="border_unfocused" geometry="border" parent="normal">
- <piece position="title"><draw_ops/></piece>
- <piece position="titlebar">
- <draw_ops>
- <image filename="inactive-top-left-corner.png"
- x="0" y="0" width="object_width" height="object_height"/>
- <image filename="inactive-border-top-left-border.png" x="5" y="0"
- width="((title_width + height / 2 - 4) `min` (width - object_width - 26))"
- height="object_height"/>
- <image filename="inactive-top-mid-border.png"
- x="((title_width + height / 2) `min` (width - object_width - 6)) + 1"
- y="0" width="object_width" height="object_height"/>
- <image filename="inactive-border-top-right-border.png"
- x="((title_width + height / 2 + 32)) + 1"
- y="0"
- width="(width - title_width - height / 2 - 32 - 7) `max` 0"
- height="object_height"/>
- <image filename="inactive-top-right-corner.png"
- x="width - object_width" y="0" width="object_height" height="object_height"/>
- </draw_ops>
- </piece>
-</frame_style>
-
-<!-- Active (focused) border style -->
-<frame_style name="border_focused" geometry="border" parent="focused">
- <piece position="title"><draw_ops/></piece>
- <piece position="titlebar">
- <draw_ops>
- <image filename="active-top-left-corner.png"
- colorize="gtk:bg[SELECTED]"
- x="0" y="0" width="object_width" height="object_height"/>
- <image filename="active-border-top-left-border.png"
- colorize="gtk:bg[SELECTED]" x="5" y="0"
- width="((title_width + height / 2 - 4) `min` (width - object_width - 26))"
- height="object_height"/>
- <image filename="active-top-mid-left-border.png"
- colorize="gtk:bg[SELECTED]"
- x="((title_width + height / 2) `min` (width - object_width - 6)) + 1"
- y="0" width="object_width" height="object_height"/>
- <image filename="active-top-mid-right-border.png"
- x="((title_width + height / 2) `min` (width - object_width - 6)) + 1"
- y="0" width="object_width" height="object_height"/>
- <image filename="active-border-top-right-border.png"
- x="((title_width + height / 2 + 32)) + 1" y="0"
- width="(width - title_width - height / 2 - 32 - 7) `max` 0"
- height="object_height"/>
- <image filename="active-top-right-corner.png"
- x="width - object_width" y="0" width="object_height" height="object_height"/>
- </draw_ops>
- </piece>
-</frame_style>
-
-<frame_style_set name="normal">
-<frame focus="yes" state="shaded" style="focused_shaded"/>
-<frame focus="yes" state="normal" resize="both" style="focused"/>
-<frame focus="yes" state="maximized" style="focused_maximized"/>
-<frame focus="yes" state="maximized_and_shaded" style="focused_maximized"/>
-<frame focus="no" state="normal" resize="both" style="normal"/>
-<frame focus="no" state="shaded" style="normal_shaded"/>
-<frame focus="no" state="maximized" style="normal_maximized"/>
-<frame focus="no" state="maximized_and_shaded" style="normal_maximized"/>
-</frame_style_set>
-
-<frame_style_set name="border">
-<frame focus="yes" state="normal" resize="both" style="border_focused"/>
-<frame focus="yes" state="maximized" style="border_focused"/>
-<frame focus="yes" state="shaded" style="border_focused"/>
-<frame focus="yes" state="maximized_and_shaded" style="border_focused"/>
-<frame focus="no" state="normal" resize="both" style="border_unfocused"/>
-<frame focus="no" state="maximized" style="border_unfocused"/>
-<frame focus="no" state="shaded" style="border_unfocused"/>
-<frame focus="no" state="maximized_and_shaded" style="border_unfocused"/>
-</frame_style_set>
-
-<window type="normal" style_set="normal"/>
-<window type="dialog" style_set="normal"/>
-<window type="modal_dialog" style_set="normal"/>
-<window type="menu" style_set="normal"/>
-<window type="utility" style_set="normal"/>
-<window type="border" style_set="border"/>
-
-<menu_icon function="close" state="normal">
- <draw_ops>
- <image filename="active-close-button.png"
- x="(width - object_width) / 2"
- y="(height - object_height) / 2"
- width="object_width" height="object_height"/>
- </draw_ops>
-</menu_icon>
-
-<menu_icon function="maximize" state="normal">
- <draw_ops>
- <image filename="active-maximize-button.png"
- x="(width - object_width) / 2"
- y="(height - object_height) / 2"
- width="object_width" height="object_height"/>
- </draw_ops>
-</menu_icon>
-
-
-<menu_icon function="minimize" state="normal">
- <draw_ops>
- <image filename="active-minimize-button.png"
- x="(width - object_width) / 2"
- y="(height - object_height) / 2"
- width="object_width" height="object_height"/>
- </draw_ops>
-</menu_icon>
-
-<menu_icon function="unmaximize" state="normal">
- <draw_ops>
- </draw_ops>
-</menu_icon>
-
-</metacity_theme>
diff --git a/src/themes/Crux/metacity-theme-2.xml b/src/themes/Crux/metacity-theme-2.xml
deleted file mode 100644
index 11820d3f..00000000
--- a/src/themes/Crux/metacity-theme-2.xml
+++ /dev/null
@@ -1,832 +0,0 @@
-<?xml version="1.0"?>
-<metacity_theme>
-<info>
- <name>Crux</name>
- <author>Anders Carlsson &lt;andersca@gnu.org&gt;</author>
- <copyright>&#194; Eazel Inc, 2000</copyright>
- <date>February 6, 2002</date>
- <description>A port of the Crux theme by Arlo Rose and John Harper</description>
-</info>
-
-<!-- define constants -->
-<constant name="IconTitleSpacing" value="2"/> <!-- Space between menu button and title -->
-<constant name="CenterTitlePieceWidth" value="48"/> <!-- Width of center title piece -->
-<constant name="ButtonWidth" value="16"/> <!-- Button width -->
-
-<frame_geometry name="normal">
- <distance name="left_width" value="5"/>
- <distance name="right_width" value="6"/>
- <distance name="bottom_height" value="6"/>
- <distance name="left_titlebar_edge" value="5"/>
- <distance name="right_titlebar_edge" value="6"/>
- <aspect_ratio name="button" value="1.0"/>
- <distance name="title_vertical_pad" value="0"/>
- <border name="title_border" left="0" right="0" top="3" bottom="3"/>
- <border name="button_border" left="0" right="0" top="3" bottom="3"/>
-</frame_geometry>
-
-<frame_geometry name="border" has_title="false">
- <distance name="left_width" value="5"/>
- <distance name="right_width" value="6"/>
- <distance name="bottom_height" value="6"/>
- <distance name="left_titlebar_edge" value="0"/>
- <distance name="right_titlebar_edge" value="0"/>
- <distance name="button_width" value="0"/>
- <distance name="button_height" value="0"/>
- <distance name="title_vertical_pad" value="5"/>
- <border name="title_border" left="0" right="0" top="0" bottom="0"/>
- <border name="button_border" left="0" right="0" top="0" bottom="0"/>
-</frame_geometry>
-
-<!-- Buttons -->
-
-<draw_ops name="active_button">
- <image filename="active-button.png" x="0" y="0" width="width" height="height"/>
-</draw_ops>
-
-<draw_ops name="active_button_pressed">
- <image filename="active-button-pressed.png" x="0" y="0" width="width" height="height"/>
-</draw_ops>
-
-<draw_ops name="active_button_prelight">
- <image filename="active-button-prelight.png" x="0" y="0" width="width" height="height"/>
-</draw_ops>
-
-<draw_ops name="inactive_button">
- <image filename="inactive-button.png" x="0" y="0" width="width" height="height"/>
-</draw_ops>
-
-<draw_ops name="inactive_button_pressed">
- <image filename="inactive-button-pressed.png" x="0" y="0" width="width" height="height"/>
-</draw_ops>
-
-<draw_ops name="inactive_button_prelight">
- <image filename="inactive-button-prelight.png" x="0" y="0" width="width" height="height"/>
-</draw_ops>
-
-<!-- Inactive style -->
-<frame_style name="normal" geometry="normal">
- <piece position="left_edge">
- <draw_ops>
- <image filename="inactive-left-border.png" x="0" y="0" width="object_width" height="height"/>
- </draw_ops>
- </piece>
-
- <piece position="right_edge">
- <draw_ops>
- <image filename="inactive-right-border.png" x="0" y="0" width="object_width" height="height"/>
- </draw_ops>
- </piece>
-
- <piece position="title">
- <draw_ops>
- <title color="gtk:fg[SELECTED]" x="IconTitleSpacing" y="0"/>
- </draw_ops>
- </piece>
-
- <piece position="titlebar">
- <draw_ops>
-
- <image filename="inactive-left-top-border.png"
- x="0" y="0" width="object_width" height="height"/>
- <image filename="inactive-right-top-border.png"
- x="width - object_width" y="0" width="object_width" height="height"/>
-
- <image filename="inactive-top-center-left.png"
- x="4" y="0"
- width="(left_width + ButtonWidth + IconTitleSpacing + title_width) `min`
- (width - right_width - 3 * ButtonWidth - CenterTitlePieceWidth * height / 22 - 3)"
- height="height"/>
-
- <image filename="inactive-top-center-mid.png"
- x="((left_width + ButtonWidth + IconTitleSpacing + title_width) `min` (width - object_width * height / 22 - right_width - 3 * ButtonWidth)) + 1"
- y="0" width="object_width * height / 22" height="height"/>
-
- <image filename="inactive-top-center-right.png"
- x="((left_width + ButtonWidth + IconTitleSpacing + title_width + CenterTitlePieceWidth * height / 22) `min` (width - 3 * ButtonWidth - right_width)) + 1"
- y="0"
- width="(width - title_width - left_width - ButtonWidth - IconTitleSpacing - CenterTitlePieceWidth * height / 22 - right_width) `max` (3 * ButtonWidth)"
- height="height"/>
-
- </draw_ops>
- </piece>
-
- <!-- We have to draw the bottom edge in the background piece
- because that's the only way we can get the correct window height -->
- <piece position="overlay">
- <draw_ops>
- <image filename="inactive-bottom-left-corner.png"
- x="0" y="height - object_height" width="object_width" height="object_height"/>
- <image filename="inactive-bottom-left-border.png" x="5" y="height - object_height"
- width="((title_width + height / 2 - 4) `min` (width - object_width - 26))"
- height="object_height"/>
- <image filename="inactive-bottom-mid-border.png"
- x="((title_width + height / 2) `min` (width - object_width - 6)) + 1"
- y="height - object_height" width="object_width" height="object_height"/>
-
- <image filename="inactive-bottom-right-border.png"
- x="((title_width + height / 2 + 32)) + 1"
- y="height - object_height"
- width="(width - title_width - height / 2 - 32 - 7) `max` 0"
- height="object_height"/>
-
- <image filename="inactive-bottom-right-corner.png"
- x="width - object_width" y="height - object_height" width="object_height" height="object_height"/>
-
- </draw_ops>
- </piece>
-
- <button function="close" state="normal">
- <draw_ops>
- <include name="inactive_button"/>
- <image filename="inactive-close-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="close" state="pressed">
- <draw_ops>
- <include name="inactive_button_pressed"/>
- <image filename="inactive-close-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="close" state="prelight">
- <draw_ops>
- <include name="inactive_button_prelight"/>
- <image filename="inactive-close-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="normal">
- <draw_ops>
- <include name="inactive_button"/>
- <image filename="inactive-minimize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="pressed">
- <draw_ops>
- <include name="inactive_button_pressed"/>
- <image filename="inactive-minimize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="prelight">
- <draw_ops>
- <include name="inactive_button_prelight"/>
- <image filename="inactive-minimize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="normal">
- <draw_ops>
- <include name="inactive_button"/>
- <image filename="inactive-maximize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="pressed">
- <draw_ops>
- <include name="inactive_button_pressed"/>
- <image filename="inactive-maximize-button.png" x="2" y="2" width="width - 4" height="height - 4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="prelight">
- <draw_ops>
- <include name="inactive_button_prelight"/>
- <image filename="inactive-maximize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="unshade" state="normal">
- <draw_ops>
- <include name="inactive_button"/>
- <image filename="inactive-unshade-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="unshade" state="pressed">
- <draw_ops>
- <include name="inactive_button_pressed"/>
- <image filename="inactive-unshade-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="unshade" state="prelight">
- <draw_ops>
- <include name="inactive_button_prelight"/>
- <image filename="inactive-unshade-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="shade" state="normal">
- <draw_ops>
- <include name="inactive_button"/>
- <image filename="inactive-shade-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="shade" state="pressed">
- <draw_ops>
- <include name="inactive_button_pressed"/>
- <image filename="inactive-shade-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="shade" state="prelight">
- <draw_ops>
- <include name="inactive_button_prelight"/>
- <image filename="inactive-shade-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="unabove" state="normal">
- <draw_ops>
- <include name="inactive_button"/>
- <image filename="inactive-unabove-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="unabove" state="pressed">
- <draw_ops>
- <include name="inactive_button_pressed"/>
- <image filename="inactive-unabove-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="unabove" state="prelight">
- <draw_ops>
- <include name="inactive_button_prelight"/>
- <image filename="inactive-unabove-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="above" state="normal">
- <draw_ops>
- <include name="inactive_button"/>
- <image filename="inactive-above-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="above" state="pressed">
- <draw_ops>
- <include name="inactive_button_pressed"/>
- <image filename="inactive-above-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="above" state="prelight">
- <draw_ops>
- <include name="inactive_button_prelight"/>
- <image filename="inactive-above-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="stick" state="normal">
- <draw_ops>
- <include name="inactive_button"/>
- <image filename="inactive-stick-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="stick" state="pressed">
- <draw_ops>
- <include name="inactive_button_pressed"/>
- <image filename="inactive-stick-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="stick" state="prelight">
- <draw_ops>
- <include name="inactive_button_prelight"/>
- <image filename="inactive-stick-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="unstick" state="normal">
- <draw_ops>
- <include name="inactive_button"/>
- <image filename="inactive-unstick-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="unstick" state="pressed">
- <draw_ops>
- <include name="inactive_button_pressed"/>
- <image filename="inactive-unstick-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="unstick" state="prelight">
- <draw_ops>
- <include name="inactive_button_prelight"/>
- <image filename="inactive-unstick-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="menu" state="normal">
- <draw_ops>
- <image filename="inactive-menu-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="menu" state="pressed">
- <draw_ops>
- <image filename="inactive-menu-button-pressed.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="menu" state="prelight">
- <draw_ops>
- <image filename="inactive-menu-button-prelight.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-</frame_style>
-
-<frame_style name="normal_maximized" parent="normal">
- <button function="maximize" state="normal">
- <draw_ops>
- <include name="inactive_button"/>
- <image filename="inactive-restore-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="pressed">
- <draw_ops>
- <include name="inactive_button_pressed"/>
- <image filename="inactive-restore-button.png" x="2" y="2" width="width - 4" height="height - 4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="prelight">
- <draw_ops>
- <include name="inactive_button_prelight"/>
- <image filename="inactive-restore-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
-</frame_style>
-
-<!-- Active (focused) shaded style -->
- <frame_style name="normal_shaded" geometry="normal" parent="normal">
- <piece position="left_titlebar_edge">
- <draw_ops>
- <image filename="inactive-left-top-border-shaded.png" x="0" y="3" width="object_width" height="object_height"/>
- </draw_ops>
- </piece>
- <piece position="right_titlebar_edge">
- <draw_ops>
- <image filename="inactive-right-top-border-shaded.png" x="width - object_width" y="3" width="object_width" height="object_height"/>
- </draw_ops>
- </piece>
- </frame_style>
-
-
-<!-- Active (focused) style -->
-<frame_style name="focused" geometry="normal">
- <piece position="left_edge">
- <draw_ops>
- <image colorize="gtk:bg[SELECTED]" filename="active-left-border.png" x="0" y="0" width="object_width" height="height"/>
- </draw_ops>
- </piece>
-
- <piece position="right_edge">
- <draw_ops>
- <image filename="active-right-border.png" x="0" y="0" width="object_width" height="height"/>
- </draw_ops>
- </piece>
-
- <piece position="title">
- <draw_ops>
- <title color="gtk:fg[SELECTED]" x="IconTitleSpacing" y="((height - title_height) / 2) `max` 0"/>
- </draw_ops>
- </piece>
-
- <piece position="titlebar">
- <draw_ops>
-
- <image filename="active-left-top-border.png"
- colorize="gtk:bg[SELECTED]"
- x="0" y="0" width="object_width" height="height"/>
-
- <image filename="active-right-top-border.png"
- x="width - object_width" y="0" width="object_width" height="height"/>
-
- <image filename="active-top-center-left.png"
- colorize="gtk:bg[SELECTED]"
- x="4" y="0"
- width="(left_width + ButtonWidth + IconTitleSpacing + title_width) `min`
- (width - right_width - 3 * ButtonWidth - CenterTitlePieceWidth * height / 22 - 3)"
- height="height"/>
-
- <image filename="active-top-center-mid-left.png"
- colorize="gtk:bg[SELECTED]"
- x="((left_width + ButtonWidth + IconTitleSpacing + title_width) `min` (width - object_width * height / 22 - right_width - 3 * ButtonWidth)) + 1"
- y="0" width="object_width * height / 22" height="height"/>
-
- <image filename="active-top-center-mid-right.png"
- x="((left_width + ButtonWidth + IconTitleSpacing + title_width) `min` (width - object_width * height / 22 - right_width - 3 * ButtonWidth)) + 1"
- y="0" width="object_width * height / 22" height="height"/>
-
- <image filename="active-top-center-right.png"
- x="((left_width + ButtonWidth + IconTitleSpacing + title_width + CenterTitlePieceWidth * height / 22) `min` (width - 3 * ButtonWidth - right_width)) + 1"
- y="0"
- width="(width - title_width - left_width - ButtonWidth - IconTitleSpacing - CenterTitlePieceWidth * height / 22 - right_width) `max` (3 * ButtonWidth)"
- height="height"/>
-
- </draw_ops>
- </piece>
-
- <!-- We have to draw the bottom edge in the background piece
- because that's the only way we can get the correct window height -->
- <piece position="overlay">
- <draw_ops>
- <image filename="active-bottom-left-corner.png"
- colorize="gtk:bg[SELECTED]"
- x="0" y="height - object_height" width="object_width" height="object_height"/>
- <image filename="active-bottom-left-border.png" x="5" y="height - object_height"
- colorize="gtk:bg[SELECTED]"
- width="((title_width + height / 2 - 4) `min` (width - object_width - 26))"
- height="object_height"/>
- <image filename="active-bottom-mid-left-border.png"
- colorize="gtk:bg[SELECTED]"
- x="((title_width + height / 2) `min` (width - object_width - 6)) + 1"
- y="height - object_height" width="object_width" height="object_height"/>
- <image filename="active-bottom-mid-right-border.png"
- x="((title_width + height / 2) `min` (width - object_width - 6)) + 1"
- y="height - object_height" width="object_width" height="object_height"/>
-
- <image filename="active-bottom-right-border.png"
- x="((title_width + height / 2 + 32)) + 1"
- y="height - object_height"
- width="(width - title_width - height / 2 - 32 - 7) `max` 0"
- height="object_height"/>
-
- <image filename="active-bottom-right-corner.png"
- x="width - object_width" y="height - object_height" width="object_height" height="object_height"/>
-
- </draw_ops>
- </piece>
-
- <button function="close" state="normal">
- <draw_ops>
- <include name="active_button"/>
- <image filename="active-close-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="close" state="pressed">
- <draw_ops>
- <include name="active_button_pressed"/>
- <image filename="active-close-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="close" state="prelight">
- <draw_ops>
- <include name="active_button_prelight"/>
- <image filename="active-close-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="normal">
- <draw_ops>
- <include name="active_button"/>
- <image filename="active-minimize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="pressed">
- <draw_ops>
- <include name="active_button_pressed"/>
- <image filename="active-minimize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="prelight">
- <draw_ops>
- <include name="active_button_prelight"/>
- <image filename="active-minimize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="normal">
- <draw_ops>
- <include name="active_button"/>
- <image filename="active-maximize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="pressed">
- <draw_ops>
- <include name="active_button_pressed"/>
- <image filename="active-maximize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="prelight">
- <draw_ops>
- <include name="active_button_prelight"/>
- <image filename="active-maximize-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="shade" state="normal">
- <draw_ops>
- <include name="active_button"/>
- <image filename="active-shade-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="shade" state="pressed">
- <draw_ops>
- <include name="active_button_pressed"/>
- <image filename="active-shade-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="shade" state="prelight">
- <draw_ops>
- <include name="active_button_prelight"/>
- <image filename="active-shade-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="unshade" state="normal">
- <draw_ops>
- <include name="active_button"/>
- <image filename="active-unshade-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="unshade" state="pressed">
- <draw_ops>
- <include name="active_button_pressed"/>
- <image filename="active-unshade-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="unshade" state="prelight">
- <draw_ops>
- <include name="active_button_prelight"/>
- <image filename="active-unshade-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="above" state="normal">
- <draw_ops>
- <include name="active_button"/>
- <image filename="active-above-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="above" state="pressed">
- <draw_ops>
- <include name="active_button_pressed"/>
- <image filename="active-above-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="above" state="prelight">
- <draw_ops>
- <include name="active_button_prelight"/>
- <image filename="active-above-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="unabove" state="normal">
- <draw_ops>
- <include name="active_button"/>
- <image filename="active-unabove-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="unabove" state="pressed">
- <draw_ops>
- <include name="active_button_pressed"/>
- <image filename="active-unabove-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="unabove" state="prelight">
- <draw_ops>
- <include name="active_button_prelight"/>
- <image filename="active-unabove-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="stick" state="normal">
- <draw_ops>
- <include name="active_button"/>
- <image filename="active-stick-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="stick" state="pressed">
- <draw_ops>
- <include name="active_button_pressed"/>
- <image filename="active-stick-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="stick" state="prelight">
- <draw_ops>
- <include name="active_button_prelight"/>
- <image filename="active-stick-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="unstick" state="normal">
- <draw_ops>
- <include name="active_button"/>
- <image filename="active-unstick-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="unstick" state="pressed">
- <draw_ops>
- <include name="active_button_pressed"/>
- <image filename="active-unstick-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="unstick" state="prelight">
- <draw_ops>
- <include name="active_button_prelight"/>
- <image filename="active-unstick-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="menu" state="normal">
- <draw_ops>
- <image colorize="gtk:bg[SELECTED]" filename="active-menu-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="menu" state="pressed">
- <draw_ops>
- <image colorize="gtk:bg[SELECTED]" filename="active-menu-button-pressed.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
- <button function="menu" state="prelight">
- <draw_ops>
- <image colorize="gtk:bg[SELECTED]" filename="active-menu-button-prelight.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-</frame_style>
-
-<frame_style name="focused_maximized" geometry="normal" parent="focused">
- <button function="maximize" state="normal">
- <draw_ops>
- <include name="active_button"/>
- <image filename="active-restore-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="pressed">
- <draw_ops>
- <include name="active_button_pressed"/>
- <image filename="active-restore-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="prelight">
- <draw_ops>
- <include name="active_button_prelight"/>
- <image filename="active-restore-button.png" x="2" y="2" width="width-4" height="height-4"/>
- </draw_ops>
- </button>
-
-</frame_style>
-
-<!-- Active (focused) shaded style -->
-<frame_style name="focused_shaded" geometry="normal" parent="focused">
- <piece position="left_titlebar_edge">
- <draw_ops>
- <image colorize="gtk:bg[SELECTED]" filename="active-left-top-border-shaded.png" x="0" y="3" width="object_width" height="object_height"/>
- </draw_ops>
- </piece>
- <piece position="right_titlebar_edge">
- <draw_ops>
- <image filename="active-right-top-border-shaded.png" x="width - object_width" y="3" width="object_width" height="object_height"/>
- </draw_ops>
- </piece>
-</frame_style>
-
-<!-- Inactive border style -->
-<frame_style name="border_unfocused" geometry="border" parent="normal">
- <piece position="title"><draw_ops/></piece>
- <piece position="titlebar">
- <draw_ops>
- <image filename="inactive-top-left-corner.png"
- x="0" y="0" width="object_width" height="object_height"/>
- <image filename="inactive-border-top-left-border.png" x="5" y="0"
- width="((title_width + height / 2 - 4) `min` (width - object_width - 26))"
- height="object_height"/>
- <image filename="inactive-top-mid-border.png"
- x="((title_width + height / 2) `min` (width - object_width - 6)) + 1"
- y="0" width="object_width" height="object_height"/>
- <image filename="inactive-border-top-right-border.png"
- x="((title_width + height / 2 + 32)) + 1"
- y="0"
- width="(width - title_width - height / 2 - 32 - 7) `max` 0"
- height="object_height"/>
- <image filename="inactive-top-right-corner.png"
- x="width - object_width" y="0" width="object_height" height="object_height"/>
- </draw_ops>
- </piece>
-</frame_style>
-
-<!-- Active (focused) border style -->
-<frame_style name="border_focused" geometry="border" parent="focused">
- <piece position="title"><draw_ops/></piece>
- <piece position="titlebar">
- <draw_ops>
- <image filename="active-top-left-corner.png"
- colorize="gtk:bg[SELECTED]"
- x="0" y="0" width="object_width" height="object_height"/>
- <image filename="active-border-top-left-border.png"
- colorize="gtk:bg[SELECTED]" x="5" y="0"
- width="((title_width + height / 2 - 4) `min` (width - object_width - 26))"
- height="object_height"/>
- <image filename="active-top-mid-left-border.png"
- colorize="gtk:bg[SELECTED]"
- x="((title_width + height / 2) `min` (width - object_width - 6)) + 1"
- y="0" width="object_width" height="object_height"/>
- <image filename="active-top-mid-right-border.png"
- x="((title_width + height / 2) `min` (width - object_width - 6)) + 1"
- y="0" width="object_width" height="object_height"/>
- <image filename="active-border-top-right-border.png"
- x="((title_width + height / 2 + 32)) + 1" y="0"
- width="(width - title_width - height / 2 - 32 - 7) `max` 0"
- height="object_height"/>
- <image filename="active-top-right-corner.png"
- x="width - object_width" y="0" width="object_height" height="object_height"/>
- </draw_ops>
- </piece>
-</frame_style>
-
-<frame_style_set name="normal">
-<frame focus="yes" state="shaded" resize="both" style="focused_shaded"/>
-<frame focus="yes" state="normal" resize="both" style="focused"/>
-<frame focus="yes" state="maximized" style="focused_maximized"/>
-<frame focus="yes" state="maximized_and_shaded" style="focused_maximized"/>
-<frame focus="no" state="normal" resize="both" style="normal"/>
-<frame focus="no" state="shaded" resize="both" style="normal_shaded"/>
-<frame focus="no" state="maximized" style="normal_maximized"/>
-<frame focus="no" state="maximized_and_shaded" style="normal_maximized"/>
-</frame_style_set>
-
-<frame_style_set name="border">
-<frame focus="yes" state="normal" resize="both" style="border_focused"/>
-<frame focus="yes" state="maximized" style="border_focused"/>
-<frame focus="yes" state="shaded" resize="both" style="border_focused"/>
-<frame focus="yes" state="maximized_and_shaded" style="border_focused"/>
-<frame focus="no" state="normal" resize="both" style="border_unfocused"/>
-<frame focus="no" state="maximized" style="border_unfocused"/>
-<frame focus="no" state="shaded" resize="both" style="border_unfocused"/>
-<frame focus="no" state="maximized_and_shaded" style="border_unfocused"/>
-</frame_style_set>
-
-<window type="normal" style_set="normal"/>
-<window type="dialog" style_set="normal"/>
-<window type="modal_dialog" style_set="normal"/>
-<window type="menu" style_set="normal"/>
-<window type="utility" style_set="normal"/>
-<window type="border" style_set="border"/>
-
-<menu_icon function="close" state="normal">
- <draw_ops>
- <image filename="active-close-button.png"
- x="(width - object_width) / 2"
- y="(height - object_height) / 2"
- width="object_width" height="object_height"/>
- </draw_ops>
-</menu_icon>
-
-<menu_icon function="maximize" state="normal">
- <draw_ops>
- <image filename="active-maximize-button.png"
- x="(width - object_width) / 2"
- y="(height - object_height) / 2"
- width="object_width" height="object_height"/>
- </draw_ops>
-</menu_icon>
-
-
-<menu_icon function="minimize" state="normal">
- <draw_ops>
- <image filename="active-minimize-button.png"
- x="(width - object_width) / 2"
- y="(height - object_height) / 2"
- width="object_width" height="object_height"/>
- </draw_ops>
-</menu_icon>
-
-<menu_icon function="unmaximize" state="normal">
- <draw_ops>
- </draw_ops>
-</menu_icon>
-
-</metacity_theme>
diff --git a/src/themes/Esco/metacity-theme-1.xml b/src/themes/Esco/metacity-theme-1.xml
deleted file mode 100644
index 9a9061ba..00000000
--- a/src/themes/Esco/metacity-theme-1.xml
+++ /dev/null
@@ -1,990 +0,0 @@
-<?xml version="1.0"?>
-<metacity_theme>
-
-<info>
- <name>Esco</name>
- <author>James M. Cape &lt;jcape@ignore-your.tv&gt;</author>
- <copyright>&#194; Havoc Pennington, 2002 for Atlanta. &#194; Gaute Lindkvist, 2002 for Bright. &#194; James M. Cape 2002 for modifications</copyright>
- <date>February 3, 2002</date>
- <description>Simple theme designed to look really good &amp; match GTK+ well.</description>
-</info>
-
-<frame_geometry name="normal">
- <distance name="left_width" value="5"/>
- <distance name="right_width" value="5"/>
- <distance name="bottom_height" value="5"/>
- <distance name="left_titlebar_edge" value="5"/>
- <distance name="right_titlebar_edge" value="5"/>
- <aspect_ratio name="button" value="1.0"/>
- <distance name="title_vertical_pad" value="1"/>
- <border name="title_border" left="5" right="5" top="3" bottom="2"/>
- <border name="button_border" left="0" right="0" top="3" bottom="2"/>
-</frame_geometry>
-
-<!-- strip borders off the normal geometry -->
-<frame_geometry name="normal_small_borders" parent="normal">
- <distance name="left_width" value="0"/>
- <distance name="right_width" value="0"/>
- <distance name="bottom_height" value="0"/>
- <distance name="left_titlebar_edge" value="0"/>
- <distance name="right_titlebar_edge" value="0"/>
- <distance name="title_vertical_pad" value="2"/>
- <border name="title_border" left="5" right="5" top="0" bottom="0"/>
- <border name="button_border" left="0" right="0" top="0" bottom="0"/>
-</frame_geometry>
-
-<frame_geometry name="utility" title_scale="small">
- <distance name="left_width" value="1"/>
- <distance name="right_width" value="1"/>
- <distance name="bottom_height" value="5"/>
- <distance name="left_titlebar_edge" value="2"/>
- <distance name="right_titlebar_edge" value="2"/>
- <aspect_ratio name="button" value="1.0"/>
- <distance name="title_vertical_pad" value="3"/>
- <border name="title_border" left="2" right="2" top="0" bottom="0"/>
- <border name="button_border" left="0" right="0" top="2" bottom="0"/>
-</frame_geometry>
-
-<frame_geometry name="border" has_title="false">
- <distance name="left_width" value="5"/>
- <distance name="right_width" value="5"/>
- <distance name="bottom_height" value="5"/>
- <distance name="left_titlebar_edge" value="0"/>
- <distance name="right_titlebar_edge" value="0"/>
- <distance name="button_width" value="0"/>
- <distance name="button_height" value="0"/>
- <distance name="title_vertical_pad" value="5"/>
- <border name="title_border" left="0" right="0" top="0" bottom="0"/>
- <border name="button_border" left="0" right="0" top="0" bottom="0"/>
-</frame_geometry>
-
-<!-- define constants -->
-<constant name="ButtonIPad" value="3"/>
-<constant name="IconTitleSpacing" value="8"/>
-
-<!-- Button Outlines -->
-<draw_ops name="button_prelight_bg">
- <gtk_box state="prelight" shadow="out" x="0" y="0" width="width"
- height="height"/>
-</draw_ops>
-
-<draw_ops name="button_pressed_bg">
- <gtk_box state="active" shadow="in" x="0" y="0" width="width"
- height="height"/>
-</draw_ops>
-
-<draw_ops name="right_button_normal_bg">
- <rectangle color="#ffffff" filled="true" x="0" y="0" width="width" height="height"/>
-</draw_ops>
-
-<!-- Button Icons -->
-
-<!-- Minimize Button -->
-<draw_ops name="minimize_button">
- <rectangle color="gtk:dark[NORMAL]" filled="true"
- x="ButtonIPad"
- y="height - ButtonIPad - ((height - (ButtonIPad + 1) * 2) * 0.4) - 1"
- width="width - (ButtonIPad + 1) * 2"
- height="(height - (ButtonIPad + 1) * 2) * 0.4"/>
-</draw_ops>
-<draw_ops name="minimize_button_focused">
- <rectangle color="gtk:fg[SELECTED]" filled="true"
- x="ButtonIPad"
- y="height - ButtonIPad - ((height - (ButtonIPad + 1) * 2) * 0.4) - 1"
- width="width - (ButtonIPad + 1) * 2"
- height="(height - (ButtonIPad + 1) * 2) * 0.4"/>
-</draw_ops>
-<draw_ops name="minimize_button_prelight">
- <include name="button_prelight_bg"/>
- <rectangle color="gtk:dark[PRELIGHT]" filled="true"
- x="ButtonIPad + 1"
- y="height - ButtonIPad - ((height - (ButtonIPad + 1) * 2) * 0.4)"
- width="width - (ButtonIPad + 1) * 2"
- height="(height - (ButtonIPad + 1) * 2) * 0.4 + 1"/>
- <rectangle color="gtk:fg[PRELIGHT]" filled="false"
- x="ButtonIPad"
- y="height - ButtonIPad - ((height - (ButtonIPad + 1) * 2) * 0.4) - 1"
- width="width - (ButtonIPad + 1) * 2"
- height="(height - (ButtonIPad + 1) * 2) * 0.4"/>
-</draw_ops>
-<draw_ops name="minimize_button_pressed">
- <include name="button_pressed_bg"/>
- <rectangle color="gtk:dark[ACTIVE]" filled="true"
- x="ButtonIPad + 1"
- y="height - ButtonIPad - ((height - (ButtonIPad + 1) * 2) * 0.4)"
- width="width - (ButtonIPad + 1) * 2"
- height="(height - (ButtonIPad + 1) * 2) * 0.4 + 1"/>
- <rectangle color="gtk:fg[ACTIVE]" filled="false"
- x="ButtonIPad"
- y="height - ButtonIPad - ((height - (ButtonIPad + 1) * 2) * 0.4) - 1"
- width="width - (ButtonIPad + 1) * 2"
- height="(height - (ButtonIPad + 1) * 2) * 0.4"/>
-</draw_ops>
-
-<!-- Maximize Button -->
-<draw_ops name="maximize_button">
- <rectangle color="gtk:dark[NORMAL]" filled="false"
- x="ButtonIPad"
- y="ButtonIPad"
- width="width - (ButtonIPad + 1) * 2"
- height="height - (ButtonIPad + 1) * 2"/>
- <rectangle color="gtk:dark[NORMAL]" filled="true"
- x="ButtonIPad"
- y="ButtonIPad"
- width="width - (ButtonIPad + 1) * 2"
- height="(height - (ButtonIPad + 1) * 2) * 0.4"/>
-</draw_ops>
-<draw_ops name="maximize_button_focused">
- <rectangle color="gtk:fg[SELECTED]" filled="false"
- x="ButtonIPad"
- y="ButtonIPad"
- width="width - (ButtonIPad + 1) * 2"
- height="height - (ButtonIPad + 1) * 2"/>
- <rectangle color="gtk:fg[SELECTED]" filled="true"
- x="ButtonIPad"
- y="ButtonIPad"
- width="width - (ButtonIPad + 1) * 2"
- height="(height - (ButtonIPad + 1) * 2) * 0.4"/>
-</draw_ops>
-<draw_ops name="maximize_button_prelight">
- <include name="button_prelight_bg"/>
- <rectangle color="gtk:dark[PRELIGHT]" filled="false"
- x="ButtonIPad + 1"
- y="ButtonIPad + 1"
- width="width - (ButtonIPad + 1) * 2"
- height="height - (ButtonIPad + 1) * 2"/>
- <rectangle color="gtk:dark[PRELIGHT]" filled="true"
- x="ButtonIPad + 1"
- y="ButtonIPad + 1"
- width="width - (ButtonIPad + 1) * 2"
- height="(height - (ButtonIPad + 1) * 2) * 0.4 + 1"/>
- <rectangle color="gtk:fg[PRELIGHT]" filled="false"
- x="ButtonIPad"
- y="ButtonIPad"
- width="width - (ButtonIPad + 1) * 2"
- height="height - (ButtonIPad + 1) * 2"/>
- <rectangle color="gtk:fg[PRELIGHT]" filled="false"
- x="ButtonIPad"
- y="ButtonIPad"
- width="width - (ButtonIPad + 1) * 2"
- height="(height - (ButtonIPad + 1) * 2) * 0.4"/>
-</draw_ops>
-<draw_ops name="maximize_button_pressed">
- <include name="button_pressed_bg"/>
- <rectangle color="gtk:dark[ACTIVE]" filled="false"
- x="ButtonIPad + 1"
- y="ButtonIPad + 1"
- width="width - (ButtonIPad + 1) * 2"
- height="height - (ButtonIPad + 1) * 2"/>
- <rectangle color="gtk:dark[ACTIVE]" filled="true"
- x="ButtonIPad + 1"
- y="ButtonIPad + 1"
- width="width - (ButtonIPad + 1) * 2"
- height="(height - (ButtonIPad + 1) * 2) * 0.4 + 1"/>
- <rectangle color="gtk:fg[ACTIVE]" filled="false"
- x="ButtonIPad"
- y="ButtonIPad"
- width="width - (ButtonIPad + 1) * 2"
- height="height - (ButtonIPad + 1) * 2"/>
- <rectangle color="gtk:fg[ACTIVE]" filled="false"
- x="ButtonIPad"
- y="ButtonIPad"
- width="width - (ButtonIPad + 1) * 2"
- height="(height - (ButtonIPad + 1) * 2) * 0.4"/>
-</draw_ops>
-
-<!-- UnMaximize Button -->
-<draw_ops name="restore_button">
- <rectangle color="gtk:dark[NORMAL]" filled="false"
- x="ButtonIPad"
- y="ButtonIPad"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="(height - (ButtonIPad + 1) * 2) * 0.67"/>
- <rectangle color="gtk:dark[NORMAL]" filled="true"
- x="ButtonIPad"
- y="ButtonIPad"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="((height - (ButtonIPad + 1) * 2) * 0.4) * 0.67"/>
- <rectangle color="gtk:dark[NORMAL]" filled="false"
- x="ButtonIPad + (width - (ButtonIPad + 1) * 2) * 0.33"
- y="ButtonIPad + (height - (ButtonIPad + 1) * 2) * 0.33"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="(height - (ButtonIPad + 1) * 2) * 0.67"/>
- <rectangle color="gtk:dark[NORMAL]" filled="true"
- x="ButtonIPad + (width - (ButtonIPad + 1) * 2) * 0.33"
- y="ButtonIPad + (height - (ButtonIPad + 1) * 2) * 0.33"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="((height - (ButtonIPad + 1) * 2) * 0.4) * 0.67"/>
-</draw_ops>
-<draw_ops name="restore_button_focused">
- <rectangle color="gtk:fg[SELECTED]" filled="false"
- x="ButtonIPad"
- y="ButtonIPad"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="(height - (ButtonIPad + 1) * 2) * 0.67"/>
- <rectangle color="gtk:fg[SELECTED]" filled="true"
- x="ButtonIPad"
- y="ButtonIPad"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="((height - (ButtonIPad + 1) * 2) * 0.4) * 0.67"/>
- <rectangle color="gtk:fg[SELECTED]" filled="false"
- x="ButtonIPad + (width - (ButtonIPad + 1) * 2) * 0.33"
- y="ButtonIPad + (height - (ButtonIPad + 1) * 2) * 0.33"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="(height - (ButtonIPad + 1) * 2) * 0.67"/>
- <rectangle color="gtk:fg[SELECTED]" filled="true"
- x="ButtonIPad + (width - (ButtonIPad + 1) * 2) * 0.33"
- y="ButtonIPad + (height - (ButtonIPad + 1) * 2) * 0.33"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="((height - (ButtonIPad + 1) * 2) * 0.4) * 0.67"/>
-</draw_ops>
-<draw_ops name="restore_button_prelight">
- <include name="button_prelight_bg"/>
- <rectangle color="gtk:dark[PRELIGHT]" filled="false"
- x="ButtonIPad + 1"
- y="ButtonIPad + 1"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="(height - (ButtonIPad + 1) * 2) * 0.67"/>
- <rectangle color="gtk:dark[PRELIGHT]" filled="true"
- x="ButtonIPad + 1"
- y="ButtonIPad + 1"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="((height - (ButtonIPad + 1) * 2) * 0.4) * 0.67"/>
- <rectangle color="gtk:dark[PRELIGHT]" filled="false"
- x="ButtonIPad + (width - (ButtonIPad + 1) * 2) * 0.33 + 1"
- y="ButtonIPad + (height - (ButtonIPad + 1) * 2) * 0.33 + 1"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="(height - (ButtonIPad + 1) * 2) * 0.67"/>
- <rectangle color="gtk:dark[PRELIGHT]" filled="true"
- x="ButtonIPad + (width - (ButtonIPad + 1) * 2) * 0.33 + 1"
- y="ButtonIPad + (height - (ButtonIPad + 1) * 2) * 0.33 + 1"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="((height - (ButtonIPad + 1) * 2) * 0.4) * 0.67"/>
- <rectangle color="gtk:fg[PRELIGHT]" filled="false"
- x="ButtonIPad"
- y="ButtonIPad"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="(height - (ButtonIPad + 1) * 2) * 0.67"/>
- <rectangle color="gtk:fg[PRELIGHT]" filled="true"
- x="ButtonIPad"
- y="ButtonIPad"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="((height - (ButtonIPad + 1) * 2) * 0.4) * 0.67"/>
- <rectangle color="gtk:fg[PRELIGHT]" filled="false"
- x="ButtonIPad + (width - (ButtonIPad + 1) * 2) * 0.33"
- y="ButtonIPad + (height - (ButtonIPad + 1) * 2) * 0.33"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="(height - (ButtonIPad + 1) * 2) * 0.67"/>
- <rectangle color="gtk:fg[PRELIGHT]" filled="true"
- x="ButtonIPad + (width - (ButtonIPad + 1) * 2) * 0.33"
- y="ButtonIPad + (height - (ButtonIPad + 1) * 2) * 0.33"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="((height - (ButtonIPad + 1) * 2) * 0.4) * 0.67"/>
-</draw_ops>
-<draw_ops name="restore_button_pressed">
- <include name="button_pressed_bg"/>
- <rectangle color="gtk:dark[ACTIVE]" filled="false"
- x="ButtonIPad + 1"
- y="ButtonIPad + 1"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="(height - (ButtonIPad + 1) * 2) * 0.67"/>
- <rectangle color="gtk:dark[ACTIVE]" filled="true"
- x="ButtonIPad + 1"
- y="ButtonIPad + 1"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="((height - (ButtonIPad + 1) * 2) * 0.4) * 0.67"/>
- <rectangle color="gtk:dark[ACTIVE]" filled="false"
- x="ButtonIPad + (width - (ButtonIPad + 1) * 2) * 0.33 + 1"
- y="ButtonIPad + (height - (ButtonIPad + 1) * 2) * 0.33 + 1"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="(height - (ButtonIPad + 1) * 2) * 0.67"/>
- <rectangle color="gtk:dark[ACTIVE]" filled="true"
- x="ButtonIPad + (width - (ButtonIPad + 1) * 2) * 0.33 + 1"
- y="ButtonIPad + (height - (ButtonIPad + 1) * 2) * 0.33 + 1"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="((height - (ButtonIPad + 1) * 2) * 0.4) * 0.67"/>
- <rectangle color="gtk:fg[ACTIVE]" filled="false"
- x="ButtonIPad"
- y="ButtonIPad"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="(height - (ButtonIPad + 1) * 2) * 0.67"/>
- <rectangle color="gtk:fg[ACTIVE]" filled="true"
- x="ButtonIPad"
- y="ButtonIPad"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="((height - (ButtonIPad + 1) * 2) * 0.4) * 0.67"/>
- <rectangle color="gtk:fg[ACTIVE]" filled="false"
- x="ButtonIPad + (width - (ButtonIPad + 1) * 2) * 0.33"
- y="ButtonIPad + (height - (ButtonIPad + 1) * 2) * 0.33"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="(height - (ButtonIPad + 1) * 2) * 0.67"/>
- <rectangle color="gtk:fg[ACTIVE]" filled="true"
- x="ButtonIPad + (width - (ButtonIPad + 1) * 2) * 0.33"
- y="ButtonIPad + (height - (ButtonIPad + 1) * 2) * 0.33"
- width="(width - (ButtonIPad + 1) * 2) * 0.67"
- height="((height - (ButtonIPad + 1) * 2) * 0.4) * 0.67"/>
-</draw_ops>
-
-<!-- Menu Button -->
-<draw_ops name="menu_button">
- <line color="gtk:dark[NORMAL]" width="3"
- x1="ButtonIPad + 1"
- y1="ButtonIPad"
- x2="ButtonIPad + 1"
- y2="height - ButtonIPad - 3"/>
- <line color="gtk:dark[NORMAL]" width="3"
- x1="ButtonIPad"
- y1="height - ButtonIPad - 5"
- x2="width - ButtonIPad - 2"
- y2="height - ButtonIPad - 5"/>
- <line color="gtk:dark[NORMAL]" width="1"
- x1="ButtonIPad"
- y1="height - ButtonIPad - 5"
- x2="width - ButtonIPad - 1"
- y2="height - ButtonIPad - 5"/>
- <line color="gtk:dark[NORMAL]" width="1"
- x1="width - ButtonIPad - 4"
- y1="height - ButtonIPad - 3 - 4"
- x2="width - ButtonIPad - 4"
- y2="height - ButtonIPad - 2"/>
- <line color="gtk:dark[NORMAL]" width="1"
- x1="width - ButtonIPad - 5"
- y1="height - ButtonIPad - 3 - 5"
- x2="width - ButtonIPad - 5"
- y2="height - ButtonIPad - 1"/>
-</draw_ops>
-<draw_ops name="menu_button_focused">
- <line color="gtk:fg[SELECTED]" width="3"
- x1="ButtonIPad + 1"
- y1="ButtonIPad"
- x2="ButtonIPad + 1"
- y2="height - ButtonIPad - 3"/>
- <line color="gtk:fg[SELECTED]" width="3"
- x1="ButtonIPad"
- y1="height - ButtonIPad - 5"
- x2="width - ButtonIPad - 2"
- y2="height - ButtonIPad - 5"/>
- <line color="gtk:fg[SELECTED]" width="1"
- x1="ButtonIPad"
- y1="height - ButtonIPad - 5"
- x2="width - ButtonIPad - 1"
- y2="height - ButtonIPad - 5"/>
- <line color="gtk:fg[SELECTED]" width="1"
- x1="width - ButtonIPad - 4"
- y1="height - ButtonIPad - 3 - 4"
- x2="width - ButtonIPad - 4"
- y2="height - ButtonIPad - 2"/>
- <line color="gtk:fg[SELECTED]" width="1"
- x1="width - ButtonIPad - 5"
- y1="height - ButtonIPad - 3 - 5"
- x2="width - ButtonIPad - 5"
- y2="height - ButtonIPad - 1"/>
-</draw_ops>
-<draw_ops name="menu_button_prelight">
- <include name="button_prelight_bg"/>
- <line color="gtk:dark[PRELIGHT]" width="3"
- x1="ButtonIPad + 1 + 1"
- y1="ButtonIPad + 1"
- x2="ButtonIPad + 1 + 1"
- y2="height - ButtonIPad - 3 + 1"/>
- <line color="gtk:dark[PRELIGHT]" width="3"
- x1="ButtonIPad + 1"
- y1="height - ButtonIPad - 5 + 1"
- x2="width - ButtonIPad - 2 + 1"
- y2="height - ButtonIPad - 5 + 1"/>
- <line color="gtk:dark[PRELIGHT]" width="1"
- x1="ButtonIPad + 1"
- y1="height - ButtonIPad - 5 + 1"
- x2="width - ButtonIPad - 1 + 1"
- y2="height - ButtonIPad - 5 + 1"/>
- <line color="gtk:dark[PRELIGHT]" width="1"
- x1="width - ButtonIPad - 4 + 1"
- y1="height - ButtonIPad - 3 - 4 + 1"
- x2="width - ButtonIPad - 4 + 1"
- y2="height - ButtonIPad - 2 + 1"/>
- <line color="gtk:dark[PRELIGHT]" width="1"
- x1="width - ButtonIPad - 5 + 1"
- y1="height - ButtonIPad - 3 - 5 + 1"
- x2="width - ButtonIPad - 5 + 1"
- y2="height - ButtonIPad - 1 + 1"/>
- <line color="gtk:fg[PRELIGHT]" width="3"
- x1="ButtonIPad + 1"
- y1="ButtonIPad"
- x2="ButtonIPad + 1"
- y2="height - ButtonIPad - 3"/>
- <line color="gtk:fg[PRELIGHT]" width="3"
- x1="ButtonIPad"
- y1="height - ButtonIPad - 5"
- x2="width - ButtonIPad - 2"
- y2="height - ButtonIPad - 5"/>
- <line color="gtk:fg[PRELIGHT]" width="1"
- x1="ButtonIPad"
- y1="height - ButtonIPad - 5"
- x2="width - ButtonIPad - 1"
- y2="height - ButtonIPad - 5"/>
- <line color="gtk:fg[PRELIGHT]" width="1"
- x1="width - ButtonIPad - 4"
- y1="height - ButtonIPad - 3 - 4"
- x2="width - ButtonIPad - 4"
- y2="height - ButtonIPad - 2"/>
- <line color="gtk:fg[PRELIGHT]" width="1"
- x1="width - ButtonIPad - 5"
- y1="height - ButtonIPad - 3 - 5"
- x2="width - ButtonIPad - 5"
- y2="height - ButtonIPad - 1"/>
-</draw_ops>
-<draw_ops name="menu_button_pressed">
- <include name="button_pressed_bg"/>
- <line color="gtk:dark[ACTIVE]" width="3"
- x1="ButtonIPad + 1 + 1"
- y1="ButtonIPad + 1"
- x2="ButtonIPad + 1 + 1"
- y2="height - ButtonIPad - 3 + 1"/>
- <line color="gtk:dark[ACTIVE]" width="3"
- x1="ButtonIPad + 1"
- y1="height - ButtonIPad - 5 + 1"
- x2="width - ButtonIPad - 2 + 1"
- y2="height - ButtonIPad - 5 + 1"/>
- <line color="gtk:dark[ACTIVE]" width="1"
- x1="ButtonIPad + 1"
- y1="height - ButtonIPad - 5 + 1"
- x2="width - ButtonIPad - 1 + 1"
- y2="height - ButtonIPad - 5 + 1"/>
- <line color="gtk:dark[ACTIVE]" width="1"
- x1="width - ButtonIPad - 4 + 1"
- y1="height - ButtonIPad - 3 - 4 + 1"
- x2="width - ButtonIPad - 4 + 1"
- y2="height - ButtonIPad - 2 + 1"/>
- <line color="gtk:dark[ACTIVE]" width="1"
- x1="width - ButtonIPad - 5 + 1"
- y1="height - ButtonIPad - 3 - 5 + 1"
- x2="width - ButtonIPad - 5 + 1"
- y2="height - ButtonIPad - 1 + 1"/>
- <line color="gtk:fg[ACTIVE]" width="3"
- x1="ButtonIPad + 1"
- y1="ButtonIPad"
- x2="ButtonIPad + 1"
- y2="height - ButtonIPad - 3"/>
- <line color="gtk:fg[ACTIVE]" width="3"
- x1="ButtonIPad"
- y1="height - ButtonIPad - 5"
- x2="width - ButtonIPad - 2"
- y2="height - ButtonIPad - 5"/>
- <line color="gtk:fg[ACTIVE]" width="1"
- x1="ButtonIPad"
- y1="height - ButtonIPad - 5"
- x2="width - ButtonIPad - 1"
- y2="height - ButtonIPad - 5"/>
- <line color="gtk:fg[ACTIVE]" width="1"
- x1="width - ButtonIPad - 4"
- y1="height - ButtonIPad - 3 - 4"
- x2="width - ButtonIPad - 4"
- y2="height - ButtonIPad - 2"/>
- <line color="gtk:fg[ACTIVE]" width="1"
- x1="width - ButtonIPad - 5"
- y1="height - ButtonIPad - 3 - 5"
- x2="width - ButtonIPad - 5"
- y2="height - ButtonIPad - 1"/>
-</draw_ops>
-
-<!-- Close Button -->
-<draw_ops name="close_button">
- <line color="gtk:dark[NORMAL]" width="1"
- x1="ButtonIPad"
- y1="ButtonIPad"
- x2="width - ButtonIPad - 1"
- y2="height - ButtonIPad - 1"/>
- <line color="gtk:dark[NORMAL]" width="1"
- x1="ButtonIPad + 1"
- y1="ButtonIPad"
- x2="width - ButtonIPad - 1"
- y2="height - ButtonIPad - 1 - 1"/>
- <line color="gtk:dark[NORMAL]" width="1"
- x1="ButtonIPad"
- y1="ButtonIPad + 1"
- x2="width - ButtonIPad - 1 - 1"
- y2="height - ButtonIPad - 1"/>
-
- <line color="gtk:dark[NORMAL]" width="1"
- x1="ButtonIPad"
- y1="height - 1 - ButtonIPad - 1"
- x2="width - 1 - ButtonIPad"
- y2="ButtonIPad - 1"/>
- <line color="gtk:dark[NORMAL]" width="1"
- x1="ButtonIPad + 1"
- y1="height - 1 - ButtonIPad - 1"
- x2="width - 1 - ButtonIPad"
- y2="ButtonIPad"/>
- <line color="gtk:dark[NORMAL]" width="1"
- x1="ButtonIPad"
- y1="height - 1 - ButtonIPad - 1 - 1"
- x2="width - 1 - ButtonIPad - 1"
- y2="ButtonIPad - 1"/>
-</draw_ops>
-<draw_ops name="close_button_focused">
- <line color="gtk:fg[SELECTED]" width="1"
- x1="ButtonIPad"
- y1="ButtonIPad"
- x2="width - ButtonIPad - 1"
- y2="height - ButtonIPad - 1"/>
- <line color="gtk:fg[SELECTED]" width="1"
- x1="ButtonIPad + 1"
- y1="ButtonIPad"
- x2="width - ButtonIPad - 1"
- y2="height - ButtonIPad - 1 - 1"/>
- <line color="gtk:fg[SELECTED]" width="1"
- x1="ButtonIPad"
- y1="ButtonIPad + 1"
- x2="width - ButtonIPad - 1 - 1"
- y2="height - ButtonIPad - 1"/>
-
- <line color="gtk:fg[SELECTED]" width="1"
- x1="ButtonIPad"
- y1="height - 1 - ButtonIPad - 1"
- x2="width - 1 - ButtonIPad"
- y2="ButtonIPad - 1"/>
- <line color="gtk:fg[SELECTED]" width="1"
- x1="ButtonIPad + 1"
- y1="height - 1 - ButtonIPad - 1"
- x2="width - 1 - ButtonIPad"
- y2="ButtonIPad"/>
- <line color="gtk:fg[SELECTED]" width="1"
- x1="ButtonIPad"
- y1="height - 1 - ButtonIPad - 1 - 1"
- x2="width - 1 - ButtonIPad - 1"
- y2="ButtonIPad - 1"/>
-</draw_ops>
-<draw_ops name="close_button_prelight">
- <include name="button_prelight_bg"/>
- <line color="gtk:dark[PRELIGHT]" width="1"
- x1="ButtonIPad + 1"
- y1="ButtonIPad + 1"
- x2="width - ButtonIPad - 1 + 1"
- y2="height - ButtonIPad - 1 + 1"/>
- <line color="gtk:dark[PRELIGHT]" width="1"
- x1="ButtonIPad + 1 + 1"
- y1="ButtonIPad + 1"
- x2="width - ButtonIPad - 1 + 1"
- y2="height - ButtonIPad - 1 - 1 + 1"/>
- <line color="gtk:dark[PRELIGHT]" width="1"
- x1="ButtonIPad + 1"
- y1="ButtonIPad + 1 + 1"
- x2="width - ButtonIPad - 1 - 1 + 1"
- y2="height - ButtonIPad - 1 + 1"/>
-
- <line color="gtk:dark[PRELIGHT]" width="1"
- x1="ButtonIPad + 1"
- y1="height - 1 - ButtonIPad - 1 + 1"
- x2="width - 1 - ButtonIPad + 1"
- y2="ButtonIPad - 1 + 1"/>
- <line color="gtk:dark[PRELIGHT]" width="1"
- x1="ButtonIPad + 1 + 1"
- y1="height - 1 - ButtonIPad - 1 + 1"
- x2="width - 1 - ButtonIPad + 1"
- y2="ButtonIPad + 1"/>
- <line color="gtk:dark[PRELIGHT]" width="1"
- x1="ButtonIPad + 1"
- y1="height - 1 - ButtonIPad - 1 - 1 + 1"
- x2="width - 1 - ButtonIPad - 1 + 1"
- y2="ButtonIPad - 1 + 1"/>
-
- <line color="gtk:fg[PRELIGHT]" width="1"
- x1="ButtonIPad"
- y1="ButtonIPad"
- x2="width - ButtonIPad - 1"
- y2="height - ButtonIPad - 1"/>
- <line color="gtk:fg[PRELIGHT]" width="1"
- x1="ButtonIPad + 1"
- y1="ButtonIPad"
- x2="width - ButtonIPad - 1"
- y2="height - ButtonIPad - 1 - 1"/>
- <line color="gtk:fg[PRELIGHT]" width="1"
- x1="ButtonIPad"
- y1="ButtonIPad + 1"
- x2="width - ButtonIPad - 1 - 1"
- y2="height - ButtonIPad - 1"/>
-
- <line color="gtk:fg[PRELIGHT]" width="1"
- x1="ButtonIPad"
- y1="height - 1 - ButtonIPad - 1"
- x2="width - 1 - ButtonIPad"
- y2="ButtonIPad - 1"/>
- <line color="gtk:fg[PRELIGHT]" width="1"
- x1="ButtonIPad + 1"
- y1="height - 1 - ButtonIPad - 1"
- x2="width - 1 - ButtonIPad"
- y2="ButtonIPad"/>
- <line color="gtk:fg[PRELIGHT]" width="1"
- x1="ButtonIPad"
- y1="height - 1 - ButtonIPad - 1 - 1"
- x2="width - 1 - ButtonIPad - 1"
- y2="ButtonIPad - 1"/>
-</draw_ops>
-<draw_ops name="close_button_pressed">
- <include name="button_pressed_bg"/>
- <line color="gtk:dark[ACTIVE]" width="1"
- x1="ButtonIPad + 1"
- y1="ButtonIPad + 1"
- x2="width - ButtonIPad - 1 + 1"
- y2="height - ButtonIPad - 1 + 1"/>
- <line color="gtk:dark[ACTIVE]" width="1"
- x1="ButtonIPad + 1 + 1"
- y1="ButtonIPad + 1"
- x2="width - ButtonIPad - 1 + 1"
- y2="height - ButtonIPad - 1 - 1 + 1"/>
- <line color="gtk:dark[ACTIVE]" width="1"
- x1="ButtonIPad + 1"
- y1="ButtonIPad + 1 + 1"
- x2="width - ButtonIPad - 1 - 1 + 1"
- y2="height - ButtonIPad - 1 + 1"/>
-
- <line color="gtk:dark[ACTIVE]" width="1"
- x1="ButtonIPad + 1"
- y1="height - 1 - ButtonIPad - 1 + 1"
- x2="width - 1 - ButtonIPad + 1"
- y2="ButtonIPad - 1 + 1"/>
- <line color="gtk:dark[ACTIVE]" width="1"
- x1="ButtonIPad + 1 + 1"
- y1="height - 1 - ButtonIPad - 1 + 1"
- x2="width - 1 - ButtonIPad + 1"
- y2="ButtonIPad + 1"/>
- <line color="gtk:dark[ACTIVE]" width="1"
- x1="ButtonIPad + 1"
- y1="height - 1 - ButtonIPad - 1 - 1 + 1"
- x2="width - 1 - ButtonIPad - 1 + 1"
- y2="ButtonIPad - 1 + 1"/>
-
- <line color="gtk:fg[ACTIVE]" width="1"
- x1="ButtonIPad"
- y1="ButtonIPad"
- x2="width - ButtonIPad - 1"
- y2="height - ButtonIPad - 1"/>
- <line color="gtk:fg[ACTIVE]" width="1"
- x1="ButtonIPad + 1"
- y1="ButtonIPad"
- x2="width - ButtonIPad - 1"
- y2="height - ButtonIPad - 1 - 1"/>
- <line color="gtk:fg[ACTIVE]" width="1"
- x1="ButtonIPad"
- y1="ButtonIPad + 1"
- x2="width - ButtonIPad - 1 - 1"
- y2="height - ButtonIPad - 1"/>
-
- <line color="gtk:fg[ACTIVE]" width="1"
- x1="ButtonIPad"
- y1="height - 1 - ButtonIPad - 1"
- x2="width - 1 - ButtonIPad"
- y2="ButtonIPad - 1"/>
- <line color="gtk:fg[ACTIVE]" width="1"
- x1="ButtonIPad + 1"
- y1="height - 1 - ButtonIPad - 1"
- x2="width - 1 - ButtonIPad"
- y2="ButtonIPad"/>
- <line color="gtk:fg[ACTIVE]" width="1"
- x1="ButtonIPad"
- y1="height - 1 - ButtonIPad - 1 - 1"
- x2="width - 1 - ButtonIPad - 1"
- y2="ButtonIPad - 1"/>
-</draw_ops>
-<!-- End Buttons Icons -->
-
-<!-- Outer Bevel -->
-<draw_ops name="outer_bevel">
- <rectangle color="gtk:dark[NORMAL]"
- x="0" y="0" width="width - 1" height="height - 1"/>
- <rectangle color="gtk:bg[NORMAL]" filled="true"
- x="1" y="1" width="width - 2" height="height - 2"/>
-</draw_ops>
-
-<draw_ops name="gradient_background">
- <gradient type="vertical" x="0" y="0" width="width" height="top_height">
- <color value="gtk:light[SELECTED]"/>
- <color value="gtk:dark[SELECTED]"/>
- </gradient>
-</draw_ops>
-
-<draw_ops name="outer_bevel_focused">
- <gtk_box state="selected" shadow="out" x="2" y="2" width="width - 2"
- height="height - 2"/>
- <rectangle color="gtk:bg[NORMAL]" filled="true"
- x="left_width" y="top_height"
- width="width - left_width - right_width - 1"
- height="height - top_height - bottom_height - 1"/>
- <rectangle color="gtk:fg[NORMAL]"
- x="0" y="0" width="width - 1" height="height - 1"/>
- <include name="gradient_background"
- x="3" y="3" width="width - 7" height="height - 7"/>
-</draw_ops>
-
-<draw_ops name="blank">
-<!-- nothing -->
-</draw_ops>
-
-<draw_ops name="outline_focused">
- <rectangle color="gtk:fg[NORMAL]"
- x="left_width - 1" y="top_height - 1"
- width="width - left_width - right_width + 1"
- height="height - top_height - bottom_height + 1"/>
-</draw_ops>
-
-<draw_ops name="background">
- <include name="outer_bevel"/>
-</draw_ops>
-
-<draw_ops name="background_focused">
- <include name="outer_bevel_focused"/>
- <include name="outline_focused"/>
-</draw_ops>
-
-<draw_ops name="title_background">
- <line color="#000000" width="50"
- x1="width - title_width - IconTitleSpacing + 25 - 1 + 3"
- y1="0 - 25"
- x2="width - title_width - IconTitleSpacing - height - 25 - 1 + 3"
- y2="height + 25"/>
- <line color="#ffffff" width="50"
- x1="width - title_width - IconTitleSpacing + 25 + 3"
- y1="0 - 25"
- x2="width - title_width - IconTitleSpacing - height - 25 + 3"
- y2="height + 25"/>
- <line color="#000000" width="1"
- x1="width - 1"
- y1="0"
- x2="width - 1"
- y2="height"/>
- <rectangle color="#ffffff" filled="true"
- x="width - title_width - mini_icon_width - IconTitleSpacing * 3"
- y="0"
- width="title_width + mini_icon_width + IconTitleSpacing * 3 - 1"
- height="height"/>
-</draw_ops>
-
-<draw_ops name="title_text_focused_with_icon">
- <title color="#000000"
- x="width - title_width - IconTitleSpacing"
- y="(height / 2) - (title_height / 2) - 1"/>
- <icon
- x="width - title_width - mini_icon_width - (IconTitleSpacing * 2)"
- y="(height / 2) - (mini_icon_height / 2)"
- width="mini_icon_width"
- height="mini_icon_height"/>
-</draw_ops>
-
-<draw_ops name="title_text_focused_no_icon">
- <title color="gtk:fg[INSENSITIVE]"
- x="width - title_width - IconTitleSpacing"
- y="(height / 2) - (title_height / 2)"/>
- <icon
- x="width - title_width - height - (IconTitleSpacing * 2)"
- y="1"
- width="height - 2"
- height="height - 2"/>
-</draw_ops>
-
-<draw_ops name="title_text_with_icon">
- <title color="gtk:dark[NORMAL]"
- x="width - title_width - IconTitleSpacing"
- y="(height / 2) - (title_height / 2) - 2"/>
- <icon alpha="0.33"
- x="width - title_width - mini_icon_width - (IconTitleSpacing * 2)"
- y="(height / 2) - (mini_icon_height / 2) - 2"
- width="mini_icon_width"
- height="mini_icon_height"/>
-</draw_ops>
-
-<draw_ops name="title_text_no_icon">
- <title color="gtk:dark[NORMAL]"
- x="width - title_width - IconTitleSpacing"
- y="(height / 2) - (title_height / 2)"/>
- <icon alpha="0.33"
- x="width - title_width - height - (IconTitleSpacing * 2)"
- y="1"
- width="height - 2"
- height="height - 2"/>
-</draw_ops>
-
-<draw_ops name="title_normal">
- <include name="title_text_with_icon" x="0" y="3" width="width" height="height - 3"/>
-</draw_ops>
-
-<draw_ops name="title_focused">
- <include name="title_background"/>
- <line color="#000000" width="1"
- x1="width - title_width - mini_icon_width - IconTitleSpacing * 3"
- y1="0"
- x2="width"
- y2="0"/>
- <line color="#000000" width="1"
- x1="width - title_width - mini_icon_width - IconTitleSpacing * 3 - 18"
- y1="height - 1"
- x2="width"
- y2="height - 1"/>
- <include name="title_text_focused_with_icon" x="0" y="2" width="width" height="height - 3"/>
-</draw_ops>
-
-<draw_ops name="title_maximized">
- <include name="title_text_with_icon"/>
-</draw_ops>
-
-<draw_ops name="title_maximized_focused">
- <include name="title_background"/>
- <include name="title_text_focused_with_icon"/>
-</draw_ops>
-
-<draw_ops name="title_utility">
- <include name="title_text_no_icon"/>
-</draw_ops>
-
-<draw_ops name="title_utility_focused">
- <include name="title_background"
- x="mini_icon_width + IconTitleSpacing"
- y="0"
- width="width - mini_icon_width - IconTitleSpacing"
- height="height"/>
- <line color="#000000" width="1"
- x1="width - title_width - mini_icon_width - IconTitleSpacing * 3"
- y1="0"
- x2="width"
- y2="0"/>
- <include name="title_text_focused_no_icon"/>
-</draw_ops>
-
-<frame_style name="normal_unfocused" geometry="normal">
- <piece position="entire_background" draw_ops="background"/>
-
- <piece position="title" draw_ops="title_normal"/>
-
- <button function="menu" state="normal"
- draw_ops="menu_button"/>
- <button function="menu" state="pressed"
- draw_ops="menu_button_pressed"/>
-
- <button function="minimize" state="normal"
- draw_ops="minimize_button"/>
- <button function="minimize" state="pressed"
- draw_ops="minimize_button_pressed"/>
-
- <button function="maximize" state="normal"
- draw_ops="maximize_button"/>
- <button function="maximize" state="pressed"
- draw_ops="maximize_button_pressed"/>
-
- <button function="close" state="normal" draw_ops="close_button"/>
- <button function="close" state="pressed" draw_ops="close_button_pressed"/>
-</frame_style>
-
-<frame_style name="normal_focused" geometry="normal" parent="normal_unfocused">
- <piece position="entire_background" draw_ops="background_focused"/>
- <piece position="title" draw_ops="title_focused"/>
-
- <button function="close" state="normal"
- draw_ops="close_button_focused"/>
- <button function="close" state="prelight"
- draw_ops="close_button_prelight"/>
-
- <button function="menu" state="normal"
- draw_ops="menu_button_focused"/>
- <button function="menu" state="prelight"
- draw_ops="menu_button_prelight"/>
-
- <button function="maximize" state="normal"
- draw_ops="maximize_button_focused"/>
- <button function="maximize" state="prelight"
- draw_ops="maximize_button_prelight"/>
-
- <button function="minimize" state="normal"
- draw_ops="minimize_button_focused"/>
- <button function="minimize" state="prelight"
- draw_ops="minimize_button_prelight"/>
-</frame_style>
-
-<frame_style name="maximized_unfocused" geometry="normal_small_borders"
- parent="normal_unfocused">
- <piece position="entire_background" draw_ops="blank"/>
-
- <piece position="title" draw_ops="title_maximized"/>
-
- <button function="maximize" state="normal"
- draw_ops="restore_button"/>
- <button function="maximize" state="pressed"
- draw_ops="restore_button_pressed"/>
-</frame_style>
-
-<frame_style name="maximized_focused" geometry="normal_small_borders"
- parent="normal_focused">
- <piece position="entire_background" draw_ops="gradient_background"/>
- <piece position="title" draw_ops="title_maximized_focused"/>
-
- <button function="maximize" state="normal"
- draw_ops="restore_button_focused"/>
- <button function="maximize" state="pressed"
- draw_ops="restore_button_pressed"/>
- <button function="maximize" state="prelight"
- draw_ops="restore_button_prelight"/>
-</frame_style>
-
-<frame_style name="utility_unfocused" geometry="utility"
- parent="normal_unfocused">
- <piece position="title" draw_ops="title_utility"/>
-</frame_style>
-
-<frame_style name="utility_focused" geometry="utility" parent="normal_focused">
- <piece position="title" draw_ops="title_utility_focused"/>
-</frame_style>
-
-<frame_style name="border" geometry="border" parent="normal_unfocused">
- <piece position="entire_background" draw_ops="outer_bevel"/>
- <piece position="title" draw_ops="blank"/>
-</frame_style>
-
-<frame_style_set name="normal">
- <frame focus="yes" state="normal" resize="both" style="normal_focused"/>
- <frame focus="no" state="normal" resize="both" style="normal_unfocused"/>
- <frame focus="yes" state="maximized" style="maximized_focused"/>
- <frame focus="no" state="maximized" style="maximized_unfocused"/>
- <frame focus="yes" state="shaded" style="normal_focused"/>
- <frame focus="no" state="shaded" style="normal_unfocused"/>
- <frame focus="yes" state="maximized_and_shaded" style="maximized_focused"/>
- <frame focus="no" state="maximized_and_shaded" style="maximized_unfocused"/>
-</frame_style_set>
-
-<frame_style_set name="utility" parent="normal">
- <frame focus="yes" state="normal" resize="both" style="utility_focused"/>
- <frame focus="no" state="normal" resize="both" style="utility_unfocused"/>
-<!-- this is a bunch of crack since utility windows shouldn't be maximized -->
- <frame focus="yes" state="maximized" style="utility_focused"/>
- <frame focus="no" state="maximized" style="utility_unfocused"/>
- <frame focus="yes" state="shaded" style="utility_focused"/>
- <frame focus="no" state="shaded" style="utility_unfocused"/>
- <frame focus="yes" state="maximized_and_shaded" style="utility_focused"/>
- <frame focus="no" state="maximized_and_shaded" style="utility_unfocused"/>
-</frame_style_set>
-
-<frame_style_set name="border">
- <frame focus="yes" state="normal" resize="both" style="border"/>
- <frame focus="no" state="normal" resize="both" style="border"/>
- <frame focus="yes" state="maximized" style="border"/>
- <frame focus="no" state="maximized" style="border"/>
- <frame focus="yes" state="shaded" style="border"/>
- <frame focus="no" state="shaded" style="border"/>
- <frame focus="yes" state="maximized_and_shaded" style="border"/>
- <frame focus="no" state="maximized_and_shaded" style="border"/>
-</frame_style_set>
-
-<window type="normal" style_set="normal"/>
-<window type="dialog" style_set="utility"/>
-<window type="modal_dialog" style_set="utility"/>
-<window type="menu" style_set="utility"/>
-<window type="utility" style_set="utility"/>
-<window type="border" style_set="border"/>
-
-<menu_icon function="close" state="normal"
- draw_ops="close_button_focused"/>
-<menu_icon function="maximize" state="normal"
- draw_ops="maximize_button_focused"/>
-<menu_icon function="unmaximize" state="normal"
- draw_ops="restore_button_focused"/>
-<menu_icon function="minimize" state="normal"
- draw_ops="minimize_button_focused"/>
-
-</metacity_theme>
diff --git a/src/themes/Gorilla/README b/src/themes/Gorilla/README
deleted file mode 100644
index c275e5ee..00000000
--- a/src/themes/Gorilla/README
+++ /dev/null
@@ -1,7 +0,0 @@
-* Gorilla *
-
-A metacity theme to accompany Scalable and Unscalable Gorilla nautilus
-themes.
-
-(c) 2001 Jakub 'jimmac' Steiner
-Ported by Kenneth Christiansen
diff --git a/src/themes/Gorilla/active-button.png b/src/themes/Gorilla/active-button.png
deleted file mode 100644
index 64455b33..00000000
--- a/src/themes/Gorilla/active-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Gorilla/active-close-button.png b/src/themes/Gorilla/active-close-button.png
deleted file mode 100644
index 1d292165..00000000
--- a/src/themes/Gorilla/active-close-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Gorilla/active-close-menu-icon.png b/src/themes/Gorilla/active-close-menu-icon.png
deleted file mode 100644
index b77f77ae..00000000
--- a/src/themes/Gorilla/active-close-menu-icon.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Gorilla/active-maximize-button.png b/src/themes/Gorilla/active-maximize-button.png
deleted file mode 100644
index a982e5cb..00000000
--- a/src/themes/Gorilla/active-maximize-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Gorilla/active-maximize-menu-icon.png b/src/themes/Gorilla/active-maximize-menu-icon.png
deleted file mode 100644
index 02ccc37a..00000000
--- a/src/themes/Gorilla/active-maximize-menu-icon.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Gorilla/active-menu-button.png b/src/themes/Gorilla/active-menu-button.png
deleted file mode 100644
index b55d7078..00000000
--- a/src/themes/Gorilla/active-menu-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Gorilla/active-minimize-button.png b/src/themes/Gorilla/active-minimize-button.png
deleted file mode 100644
index 4205f4e8..00000000
--- a/src/themes/Gorilla/active-minimize-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Gorilla/active-minimize-menu-icon.png b/src/themes/Gorilla/active-minimize-menu-icon.png
deleted file mode 100644
index 29276929..00000000
--- a/src/themes/Gorilla/active-minimize-menu-icon.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Gorilla/gorilla.xcf.bz2 b/src/themes/Gorilla/gorilla.xcf.bz2
deleted file mode 100644
index 89b85651..00000000
--- a/src/themes/Gorilla/gorilla.xcf.bz2
+++ /dev/null
Binary files differ
diff --git a/src/themes/Gorilla/inactive-close-button.png b/src/themes/Gorilla/inactive-close-button.png
deleted file mode 100644
index c566b12f..00000000
--- a/src/themes/Gorilla/inactive-close-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Gorilla/inactive-maximize-button.png b/src/themes/Gorilla/inactive-maximize-button.png
deleted file mode 100644
index 9c838823..00000000
--- a/src/themes/Gorilla/inactive-maximize-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Gorilla/inactive-menu-button.png b/src/themes/Gorilla/inactive-menu-button.png
deleted file mode 100644
index b000a378..00000000
--- a/src/themes/Gorilla/inactive-menu-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Gorilla/inactive-minimize-button.png b/src/themes/Gorilla/inactive-minimize-button.png
deleted file mode 100644
index 4459af4e..00000000
--- a/src/themes/Gorilla/inactive-minimize-button.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Gorilla/metacity-theme-1.xml b/src/themes/Gorilla/metacity-theme-1.xml
deleted file mode 100644
index 7dde366a..00000000
--- a/src/themes/Gorilla/metacity-theme-1.xml
+++ /dev/null
@@ -1,260 +0,0 @@
-<?xml version="1.0"?>
-<metacity_theme>
-<info>
- <name>Gorilla</name>
- <author>Kenneth Christiansen &lt;kenneth@gnu.org&gt; Anders Carlsson &lt;andersca@gnu.org&gt;</author>
- <copyright>&#194; Ximian, Inc, 2001</copyright>
- <date>February 8, 2002</date>
- <description>A port of the Gorilla theme by Jacub Steiner</description>
-</info>
-
-<!-- define constants -->
-<constant name="IconTitleSpacing" value="2"/> <!-- Space between menu button and title -->
-<constant name="ButtonWidth" value="18"/> <!-- Button width -->
-
-<frame_geometry name="normal">
- <distance name="left_width" value="6"/>
- <distance name="right_width" value="6"/>
- <distance name="bottom_height" value="6"/>
- <distance name="left_titlebar_edge" value="8"/>
- <distance name="right_titlebar_edge" value="8"/>
- <aspect_ratio name="button" value="1.0"/>
- <distance name="title_vertical_pad" value="0"/>
- <border name="title_border" left="0" right="0" top="7" bottom="4"/>
- <border name="button_border" left="0" right="0" top="9" bottom="0"/>
-</frame_geometry>
-
-
-<!-- Buttons -->
-
-<draw_ops name="title_tile">
- <line color="#494d59" x1="0" y1="0" x2="width" y2="0"/>
- <line color="#515961" x1="0" y1="1" x2="width" y2="1"/>
-</draw_ops>
-
-<!-- Inactive style -->
-<frame_style name="normal" geometry="normal">
- <piece position="entire_background">
- <draw_ops>
- <rectangle color="black" x="1" y="1" width="width - 2" height="height - 2" filled="true"/>
- <rectangle color="dark gray" x="3" y="3" width="width - 8" height="height - 7" filled="false"/>
- <rectangle color="light gray" x="4" y="4" width="width - 9" height="height - 8" filled="false"/>
- <rectangle color="light gray" x="5" y="5" width="width - 11" height="height - 10" filled="false"/>
- <rectangle color="white" x="6" y="6" width="width - 13" height="height - 12" filled="false"/>
- <rectangle color="gtk:bg[INSENSITIVE]" x="6" y="6" width="width - 12" height="height - 12" filled="true"/>
-
- <line color="gtk:bg[INSENSITIVE]" x1="1" y1="1" x2="2" y2="2"/>
- <line color="gtk:bg[INSENSITIVE]" x1="1" y1="height - 2" x2="1" y2="height"/>
- <line color="gtk:bg[INSENSITIVE]" x1="width - 2" y1="1" x2="width - 1" y2="2"/>
- <line color="gtk:bg[INSENSITIVE]" x1="width - 1" y1="height - 1" x2="width - 2" y2="height - 2"/>
- </draw_ops>
- </piece>
-
- <piece position="title">
- <draw_ops>
- <title color="gray" x="IconTitleSpacing" y="0"/>
- </draw_ops>
- </piece>
-
- <piece position="titlebar">
- <draw_ops>
- <rectangle color="black" x="6" y="6" width="width - 12" height="height - 10" filled="true"/>
- <tile name="title_tile" tile_width="width" tile_height="2" x="8" y="8" width="width - 16" height="height - 14"/>
- </draw_ops>
- </piece>
-
- <button function="close" state="normal">
- <draw_ops>
- <image filename="inactive-close-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="close" state="pressed">
- <draw_ops>
- <image filename="inactive-close-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="normal">
- <draw_ops>
- <image filename="inactive-minimize-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="pressed">
- <draw_ops>
- <image filename="inactive-minimize-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="normal">
- <draw_ops>
- <image filename="inactive-maximize-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="pressed">
- <draw_ops>
- <image filename="inactive-maximize-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="menu" state="normal">
- <draw_ops>
- <image filename="inactive-menu-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="menu" state="pressed">
- <draw_ops>
- <image filename="inactive-menu-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
-
-</frame_style>
-
-
-<!-- Active (focused) shaded style -->
-<frame_style name="normal_shaded" geometry="normal" parent="normal">
-
-</frame_style>
-
-<!-- Active (focused) style -->
-<frame_style name="focused" geometry="normal">
- <piece position="entire_background">
- <draw_ops>
- <rectangle color="black" x="0" y="0" width="width" height="height" filled="true"/>
- <rectangle color="dark gray" x="3" y="3" width="width - 8" height="height - 7" filled="false"/>
- <rectangle color="light gray" x="4" y="4" width="width - 9" height="height - 8" filled="false"/>
- <rectangle color="light gray" x="5" y="5" width="width - 11" height="height - 10" filled="false"/>
- <rectangle color="white" x="6" y="6" width="width - 13" height="height - 12" filled="false"/>
- <rectangle color="gtk:bg[NORMAL]" x="6" y="6" width="width - 12" height="height - 12" filled="true"/>
-
- <line color="gtk:bg[NORMAL]" x1="0" y1="0" x2="1" y2="1"/>
- <line color="gtk:bg[NORMAL]" x1="0" y1="height - 1" x2="1" y2="height"/>
- <line color="gtk:bg[NORMAL]" x1="width - 1" y1="0" x2="width" y2="1"/>
- <line color="gtk:bg[NORMAL]" x1="width" y1="height" x2="width - 1" y2="height - 1"/>
- </draw_ops>
- </piece>
-
- <piece position="title">
- <draw_ops>
- <title color="white" x="IconTitleSpacing" y="0"/>
- </draw_ops>
- </piece>
-
- <piece position="titlebar">
- <draw_ops>
- <rectangle color="black" x="6" y="6" width="width - 12" height="height - 10" filled="true"/>
- <tile name="title_tile" tile_width="width" tile_height="2" x="8" y="8" width="width - 16" height="height - 14"/>
- </draw_ops>
- </piece>
-
- <button function="close" state="normal">
- <draw_ops>
- <image filename="active-close-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="close" state="pressed">
- <draw_ops>
- <image filename="active-close-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="normal">
- <draw_ops>
- <image filename="active-minimize-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="minimize" state="pressed">
- <draw_ops>
- <image filename="active-minimize-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="normal">
- <draw_ops>
- <image filename="active-maximize-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="maximize" state="pressed">
- <draw_ops>
- <image filename="active-maximize-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="menu" state="normal">
- <draw_ops>
- <image filename="active-menu-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
- <button function="menu" state="pressed">
- <draw_ops>
- <image filename="active-menu-button.png" x="0" y="0" width="width" height="height"/>
- </draw_ops>
- </button>
-
-</frame_style>
-
-<!-- Active (focused) shaded style -->
-<frame_style name="focused_shaded" geometry="normal" parent="focused">
-
-</frame_style>
-
-<frame_style_set name="normal">
-<frame focus="yes" state="shaded" style="focused_shaded"/>
-<frame focus="yes" state="normal" resize="both" style="focused"/>
-<frame focus="yes" state="maximized" style="focused"/>
-<frame focus="yes" state="maximized_and_shaded" style="focused_shaded"/>
-<frame focus="no" state="normal" resize="both" style="normal"/>
-<frame focus="no" state="shaded" style="normal_shaded"/>
-<frame focus="no" state="maximized" style="normal"/>
-<frame focus="no" state="maximized_and_shaded" style="normal_shaded"/>
-</frame_style_set>
-
-<window type="normal" style_set="normal"/>
-<window type="dialog" style_set="normal"/>
-<window type="modal_dialog" style_set="normal"/>
-<window type="menu" style_set="normal"/>
-<window type="utility" style_set="normal"/>
-<window type="border" style_set="normal"/>
-
-<menu_icon function="maximize" state="normal">
- <draw_ops>
- <image filename="active-maximize-menu-icon.png"
- x="(width - object_width) / 2"
- y="(height - object_height) / 2"
- width="object_width" height="object_height"/>
- </draw_ops>
-</menu_icon>
-
-
-<menu_icon function="close" state="normal">
- <draw_ops>
- <image filename="active-close-menu-icon.png"
- x="(width - object_width) / 2"
- y="(height - object_height) / 2"
- width="object_width" height="object_height"/>
- </draw_ops>
-</menu_icon>
-
-<menu_icon function="minimize" state="normal">
- <draw_ops>
- <image filename="active-minimize-menu-icon.png"
- x="(width - object_width) / 2"
- y="(height - object_height) / 2"
- width="object_width" height="object_height"/>
- </draw_ops>
-</menu_icon>
-
-<menu_icon function="unmaximize" state="normal">
- <draw_ops>
- </draw_ops>
-</menu_icon>
-
-</metacity_theme>
diff --git a/src/themes/Makefile.am b/src/themes/Makefile.am
deleted file mode 100644
index 82c504e8..00000000
--- a/src/themes/Makefile.am
+++ /dev/null
@@ -1,50 +0,0 @@
-THEMES= \
- Atlanta \
- Bright \
- Crux \
- Esco \
- AgingGorilla \
- Metabox \
- Simple
-
-THEME_DIR=$(datadir)/themes
-THEME_SUBDIR=metacity-1
-
-install-data-local:
- $(mkinstalldirs) $(DESTDIR)$(THEME_DIR); \
- for THEME in $(THEMES); do \
- echo '-- Installing theme '$$THEME; \
- $(mkinstalldirs) $(DESTDIR)$(THEME_DIR)/$$THEME; \
- $(mkinstalldirs) $(DESTDIR)$(THEME_DIR)/$$THEME/$(THEME_SUBDIR); \
- (installfiles=`find $(srcdir)/$$THEME -name "*.png" -o -name "*.xml"`; \
- for i in $$installfiles; do \
- echo '-- Installing '$$i ; \
- $(INSTALL_DATA) $$i $(DESTDIR)$(THEME_DIR)/$$THEME/$(THEME_SUBDIR) ; \
- done) \
- done
-
-uninstall-local:
- for THEME in $(THEMES); do \
- echo '-- Uninstalling theme '$$THEME; \
- (uninstallfiles=`find $(srcdir)/$$THEME -name "*.png" -o -name "*.xml"`; \
- for i in $$uninstallfiles; do \
- i=`basename $$i`; \
- echo '-- Removing '$$i ; \
- rm -f $(DESTDIR)$(THEME_DIR)/$$THEME/$(THEME_SUBDIR)/$$i ; \
- done); \
- rmdir $(DESTDIR)$(THEME_DIR)/$$THEME/$(THEME_SUBDIR) || :; \
- rmdir $(DESTDIR)$(THEME_DIR)/$$THEME || :; \
- done
- -rmdir $(DESTDIR)$(THEME_DIR)
-
-dist-hook:
- mkdir $(distdir)/themes; \
- for THEME in $(THEMES); do \
- echo '-- Disting theme '$$THEME; \
- mkdir $(distdir)/$$THEME; \
- (installfiles=`find $(srcdir)/$$THEME -name "*.png" -o -name "*.xml"`; \
- for i in $$installfiles; do \
- echo '-- Disting '$$i ; \
- cp $$i $(distdir)/$$THEME; \
- done) \
- done
diff --git a/src/themes/Metabox/metacity-theme-1.xml b/src/themes/Metabox/metacity-theme-1.xml
deleted file mode 100644
index ac90a3f9..00000000
--- a/src/themes/Metabox/metacity-theme-1.xml
+++ /dev/null
@@ -1,479 +0,0 @@
-<?xml version="1.0"?>
-<metacity_theme>
- <info>
- <name>Metabox</name>
- <author>Garrett LeSage &lt;garrett@redhat.com&gt; based on Havoc Pennington &lt;hp@redhat.com&gt;'s Atlanta theme</author>
- <copyright>&#194; Garrett LeSage, Havoc Pennington, 2002</copyright>
- <date>Jun 12, 2002</date>
- <description>Looks a little like BlackBox.</description>
- </info>
-
- <frame_geometry name="normal">
- <distance name="left_width" value="1"/>
- <distance name="right_width" value="1"/>
- <distance name="bottom_height" value="6"/>
- <distance name="left_titlebar_edge" value="1"/>
- <distance name="right_titlebar_edge" value="1"/>
- <distance name="title_vertical_pad" value="3"/>
- <border name="title_border" left="0" right="0" top="1" bottom="1"/>
- <border name="button_border" left="0" right="0" top="1" bottom="1"/>
- <aspect_ratio name="button" value="1.0"/>
- </frame_geometry>
-
- <!-- strip borders off the normal geometry -->
- <frame_geometry name="normal_small_borders" parent="normal">
- <distance name="left_width" value="0"/>
- <distance name="right_width" value="0"/>
- <distance name="bottom_height" value="0"/>
- <distance name="left_titlebar_edge" value="0"/>
- <distance name="right_titlebar_edge" value="0"/>
- </frame_geometry>
-
- <frame_geometry name="utility" title_scale="small">
- <distance name="left_width" value="1"/>
- <distance name="right_width" value="1"/>
- <distance name="bottom_height" value="4"/>
- <distance name="left_titlebar_edge" value="1"/>
- <distance name="right_titlebar_edge" value="1"/>
- <distance name="title_vertical_pad" value="1"/>
- <border name="title_border" left="0" right="0" top="1" bottom="1"/>
- <border name="button_border" left="0" right="0" top="1" bottom="1"/>
- <aspect_ratio name="button" value="1.0"/>
- </frame_geometry>
-
- <frame_geometry name="border" has_title="false">
- <distance name="left_width" value="4"/>
- <distance name="right_width" value="4"/>
- <distance name="bottom_height" value="4"/>
- <distance name="left_titlebar_edge" value="0"/>
- <distance name="right_titlebar_edge" value="0"/>
- <distance name="button_width" value="0"/>
- <distance name="button_height" value="0"/>
- <distance name="title_vertical_pad" value="4"/>
- <border name="title_border" left="0" right="0" top="0" bottom="0"/>
- <border name="button_border" left="0" right="0" top="0" bottom="0"/>
- </frame_geometry>
-
- <!-- define constants -->
- <constant name="ArrowWidth" value="7"/>
- <constant name="ArrowHeight" value="5"/>
- <constant name="ButtonIPad" value="4"/>
- <constant name="ThickLineWidth" value="3"/>
- <constant name="IconTitleSpacing" value="2"/>
- <constant name="SpacerWidth" value="8"/>
- <constant name="SpacerHeight" value="11"/>
-
- <!-- Backgrounds -->
-
- <draw_ops name="bg_active">
- <gradient type="vertical" x="0" y="0" width="width" height="height">
- <color value="shade/gtk:bg[SELECTED]/1.25"/>
- <color value="shade/gtk:bg[SELECTED]/0.85"/>
- </gradient>
- </draw_ops>
-
- <draw_ops name="bg_inactive">
- <gradient type="vertical" x="0" y="0" width="width" height="height">
- <color value="shade/gtk:bg[INSENSITIVE]/1.1"/>
- <color value="shade/gtk:bg[INSENSITIVE]/0.9"/>
- </gradient>
- </draw_ops>
-
- <draw_ops name="bg_button_active">
- <include name="bg_active"/>
- </draw_ops>
-
- <draw_ops name="bg_button_inactive">
- <include name="bg_inactive"/>
- </draw_ops>
-
- <draw_ops name="bg_title_active">
- <include name="bg_active"/>
- </draw_ops>
-
- <draw_ops name="bg_title_inactive">
- <include name="bg_inactive"/>
- </draw_ops>
-
- <!-- Buttons -->
-
- <draw_ops name="button_pressed_bg">
- <gradient type="vertical" x="0" y="0" width="width" height="height" alpha="0.25">
- <color value="shade/gtk:bg[SELECTED]/0.75"/>
- <color value="shade/gtk:bg[SELECTED]/0.5"/>
- </gradient>
- </draw_ops>
-
- <draw_ops name="button_prelight_bg">
- <gradient type="vertical" x="0" y="0" width="width" height="height" alpha="0.25">
- <color value="shade/gtk:bg[SELECTED]/2.0"/>
- <color value="shade/gtk:bg[SELECTED]/1.5"/>
- </gradient>
- </draw_ops>
-
- <draw_ops name="menu_button">
- <include name="bg_button_active"/>
- <line color="blend/gtk:bg[SELECTED]/gtk:fg[SELECTED]/0.75" width="2" x1="ButtonIPad+1" y1="width/2+2" x2="(width-ButtonIPad)/2+1" y2="width/2+2"/>
- <line color="blend/gtk:bg[SELECTED]/gtk:fg[SELECTED]/0.75" width="2" x1="ButtonIPad+1" y1="width/2-2" x2="(width-ButtonIPad)/2+1" y2="width/2-2"/>
- <line color="blend/gtk:bg[SELECTED]/gtk:fg[SELECTED]/0.75" width="2" x1="width-ButtonIPad-1" y1="width/2+2" x2="width-(width-ButtonIPad)/2-1" y2="width/2+2"/>
- <line color="blend/gtk:bg[SELECTED]/gtk:fg[SELECTED]/0.75" width="2" x1="width-ButtonIPad-1" y1="width/2-2" x2="width-(width-ButtonIPad)/2-1" y2="width/2-2"/>
- </draw_ops>
-
- <draw_ops name="menu_button_pressed">
- <include name="menu_button"/>
- <include name="button_pressed_bg"/>
- </draw_ops>
-
- <draw_ops name="menu_button_prelight">
- <include name="menu_button"/>
- <include name="button_prelight_bg"/>
- </draw_ops>
-
- <draw_ops name="menu_button_unfocused">
- <include name="bg_button_inactive"/>
- <line color="blend/gtk:fg[INSENSITIVE]/gtk:bg[INSENSITIVE]/0.35" width="2" x1="ButtonIPad+1" y1="width/2+2" x2="(width-ButtonIPad)/2+1" y2="width/2+2"/>
- <line color="blend/gtk:fg[INSENSITIVE]/gtk:bg[INSENSITIVE]/0.35" width="2" x1="ButtonIPad+1" y1="width/2-2" x2="(width-ButtonIPad)/2+1" y2="width/2-2"/>
- <line color="blend/gtk:fg[INSENSITIVE]/gtk:bg[INSENSITIVE]/0.35" width="2" x1="width-ButtonIPad-1" y1="width/2+2" x2="width-(width-ButtonIPad)/2-1" y2="width/2+2"/>
- <line color="blend/gtk:fg[INSENSITIVE]/gtk:bg[INSENSITIVE]/0.35" width="2" x1="width-ButtonIPad-1" y1="width/2-2" x2="width-(width-ButtonIPad)/2-1" y2="width/2-2"/>
- </draw_ops>
-
- <draw_ops name="minimize_button">
- <include name="bg_button_active"/>
- <line color="blend/gtk:bg[SELECTED]/gtk:fg[SELECTED]/0.75"
- x1="ButtonIPad"
- y1="height - ButtonIPad - ThickLineWidth + 1"
- x2="width - ButtonIPad"
- y2="height - ButtonIPad - ThickLineWidth + 1"
- width="3"/> <!-- FIXME allow a constant here -->
- </draw_ops>
-
- <draw_ops name="minimize_button_pressed">
- <include name="minimize_button"/>
- <include name="button_pressed_bg"/>
- </draw_ops>
-
- <draw_ops name="minimize_button_prelight">
- <include name="minimize_button"/>
- <include name="button_prelight_bg"/>
- </draw_ops>
-
- <draw_ops name="minimize_button_unfocused">
- <include name="bg_button_inactive"/>
- <line color="blend/gtk:fg[INSENSITIVE]/gtk:bg[INSENSITIVE]/0.35"
- x1="ButtonIPad"
- y1="height - ButtonIPad - ThickLineWidth + 1"
- x2="width - ButtonIPad"
- y2="height - ButtonIPad - ThickLineWidth + 1"
- width="3"/> <!-- FIXME allow a constant here -->
- </draw_ops>
-
- <draw_ops name="maximize_button">
- <include name="bg_button_active"/>
- <rectangle color="blend/gtk:bg[SELECTED]/gtk:fg[SELECTED]/0.75" filled="false"
- x="ButtonIPad" y="ButtonIPad" width="width-ButtonIPad*2-1" height="height-ButtonIPad*2-1"/>
- <line color="blend/gtk:bg[SELECTED]/gtk:fg[SELECTED]/0.75" width="3"
- x1="ButtonIPad" y1="ButtonIPad+1" x2="width-ButtonIPad" y2="ButtonIPad+1"/>
- </draw_ops>
-
- <draw_ops name="maximize_button_pressed">
- <include name="maximize_button"/>
- <include name="button_pressed_bg"/>
- </draw_ops>
-
- <draw_ops name="maximize_button_prelight">
- <include name="maximize_button"/>
- <include name="button_prelight_bg"/>
- </draw_ops>
-
- <draw_ops name="maximize_button_unfocused">
- <include name="bg_button_inactive"/>
- <rectangle color="blend/gtk:fg[INSENSITIVE]/gtk:bg[INSENSITIVE]/0.35" filled="false"
- x="ButtonIPad" y="ButtonIPad" width="width-ButtonIPad*2-1" height="height-ButtonIPad*2-1"/>
- <line color="blend/gtk:fg[INSENSITIVE]/gtk:bg[INSENSITIVE]/0.35" width="3"
- x1="ButtonIPad" y1="ButtonIPad+1" x2="width-ButtonIPad" y2="ButtonIPad+1"/>
- </draw_ops>
-
- <draw_ops name="mini_window_icon">
- <rectangle color="gtk:bg[SELECTED]" filled="true"
- x="0" y="0" width="width-1" height="height-1"/>
- <rectangle color="blend/gtk:bg[SELECTED]/gtk:fg[SELECTED]/0.75" filled="false"
- x="0" y="0" width="width-1" height="height-1"/>
- <line color="blend/gtk:bg[SELECTED]/gtk:fg[SELECTED]/0.75" width="2"
- x1="0" y1="1" x2="width" y2="1"/>
- </draw_ops>
-
- <draw_ops name="mini_window_icon_unfocused">
- <rectangle color="gtk:bg[NORMAL]" filled="true"
- x="0" y="0" width="width-1" height="height-1"/>
- <rectangle color="blend/gtk:fg[INSENSITIVE]/gtk:bg[INSENSITIVE]/0.35" filled="false"
- x="0" y="0" width="width-1" height="height-1"/>
- <line color="blend/gtk:fg[INSENSITIVE]/gtk:bg[INSENSITIVE]/0.35" width="2"
- x1="0" y1="1" x2="width" y2="1"/>
- </draw_ops>
-
- <draw_ops name="restore_button">
- <include name="bg_button_active"/>
- <include name="mini_window_icon"
- x="3 + ButtonIPad" y="ButtonIPad"
- width="width - 7 - ButtonIPad"
- height="height - 7 - ButtonIPad"/>
- <include name="mini_window_icon"
- x="ButtonIPad" y="3 + ButtonIPad"
- width="width - 7 - ButtonIPad"
- height="height - 7 - ButtonIPad"/>
- </draw_ops>
-
- <draw_ops name="restore_button_pressed">
- <include name="restore_button"/>
- <include name="button_pressed_bg"/>
- </draw_ops>
-
- <draw_ops name="restore_button_prelight">
- <include name="restore_button"/>
- <include name="button_prelight_bg"/>
- </draw_ops>
-
- <draw_ops name="restore_button_unfocused">
- <include name="bg_button_inactive"/>
- <include name="mini_window_icon_unfocused"
- x="3 + ButtonIPad" y="ButtonIPad"
- width="width - 7 - ButtonIPad"
- height="height - 7 - ButtonIPad"/>
- <include name="mini_window_icon_unfocused"
- x="ButtonIPad" y="3 + ButtonIPad"
- width="width - 7 - ButtonIPad"
- height="height - 7 - ButtonIPad"/>
- </draw_ops>
-
- <draw_ops name="close_button">
- <include name="bg_button_active"/>
- <!-- draw longer lines and clip for 'x' with symmetrical endpoints &lt;joefefifo@yahoo.com&gt; -->
- <clip x="ButtonIPad" y="ButtonIPad"
- width="width - ButtonIPad - 4"
- height="height - ButtonIPad - 4"/>
- <line color="blend/gtk:bg[SELECTED]/gtk:fg[SELECTED]/0.75"
- width="2"
- x1="ButtonIPad" y1="ButtonIPad"
- x2="width - ButtonIPad" y2="height - ButtonIPad"/>
-
- <line color="blend/gtk:bg[SELECTED]/gtk:fg[SELECTED]/0.75"
- width="2"
- x1="ButtonIPad" y1="height - ButtonIPad - 1"
- x2="width - ButtonIPad" y2="ButtonIPad - 1"/>
- </draw_ops>
-
- <draw_ops name="close_button_pressed">
- <include name="close_button"/>
- <include name="button_pressed_bg"/>
- </draw_ops>
-
- <draw_ops name="close_button_prelight">
- <include name="close_button"/>
- <include name="button_prelight_bg"/>
- </draw_ops>
-
- <draw_ops name="close_button_unfocused">
- <include name="bg_button_inactive"/>
- <!-- draw longer lines and clip for 'x' with symmetrical endpoints &lt;joefefifo@yahoo.com&gt; -->
- <clip x="ButtonIPad" y="ButtonIPad"
- width="width - ButtonIPad - 4"
- height="height - ButtonIPad - 4"/>
- <line color="blend/gtk:fg[INSENSITIVE]/gtk:bg[INSENSITIVE]/0.35"
- width="2"
- x1="ButtonIPad" y1="ButtonIPad"
- x2="width - ButtonIPad" y2="height - ButtonIPad"/>
- <line color="blend/gtk:fg[INSENSITIVE]/gtk:bg[INSENSITIVE]/0.35"
- width="2"
- x1="ButtonIPad" y1="height - ButtonIPad - 1"
- x2="width - ButtonIPad" y2="ButtonIPad - 1"/>
- </draw_ops>
-
- <draw_ops name="outer_bevel">
- <rectangle color="#000000"
- x="0" y="0" width="width-1" height="height-1"/>
- <line color="gtk:light[NORMAL]"
- x1="1" y1="1" x2="1" y2="height-2"/>
- <line color="gtk:light[NORMAL]"
- x1="1" y1="1" x2="width-2" y2="1"/>
- <line color="gtk:dark[NORMAL]"
- x1="width-2" y1="1" x2="width-2" y2="height-2"/>
- <line color="gtk:dark[NORMAL]"
- x1="1" y1="height-2" x2="width-2" y2="height-2"/>
- </draw_ops>
-
- <draw_ops name="blank">
- <!-- nothing -->
- </draw_ops>
-
- <draw_ops name="focus_outline">
- <rectangle color="#000000"
- x="left_width-1" y="top_height-1"
- width="width-left_width-right_width+1"
- height="height-top_height-bottom_height+1"/>
- </draw_ops>
-
- <draw_ops name="focus_background">
- <include name="outer_bevel"/>
- <include name="focus_outline"/>
- </draw_ops>
-
- <draw_ops name="title_text_focused_with_icon">
- <clip x="0" y="0" width="width" height="height"/>
- <title color="gtk:fg[SELECTED]"
- x="(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2 + mini_icon_width + IconTitleSpacing"
- y="((height - title_height) / 2) `max` 0"/>
- <icon x="(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2"
- y="(height-mini_icon_height) / 2"
- width="mini_icon_width" height="mini_icon_height"/>
- </draw_ops>
-
- <draw_ops name="title_text_focused_no_icon">
- <clip x="0" y="0" width="width" height="height"/>
- <title color="gtk:fg[SELECTED]"
- x="(0 `max` (width-title_width)) / 2"
- y="((height - title_height) / 2) `max` 0"/>
- </draw_ops>
-
- <draw_ops name="title_text_with_icon">
- <clip x="0" y="0" width="width" height="height"/>
- <title color="gtk:fg[INSENSITIVE]"
- x="(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2 + mini_icon_width + IconTitleSpacing"
- y="((height - title_height) / 2) `max` 0"/>
- <icon x="(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2"
- y="(height-mini_icon_height) / 2"
- width="mini_icon_width" height="mini_icon_height"/>
- </draw_ops>
-
- <draw_ops name="title_text_no_icon">
- <clip x="0" y="0" width="width" height="height"/>
- <title color="blend/gtk:fg[INSENSITIVE]/gtk:bg[INSENSITIVE]/0.35"
- x="(0 `max` (width-title_width)) / 2"
- y="((height - title_height) / 2) `max` 0"/>
- </draw_ops>
-
- <draw_ops name="title_normal">
- <include name="bg_title_inactive"/>
- <include name="title_text_no_icon"/>
- </draw_ops>
-
- <draw_ops name="title_focused">
- <include name="bg_title_active"/>
- <include name="title_text_focused_no_icon"/>
- </draw_ops>
-
- <draw_ops name="title_utility">
- <include name="title_text_no_icon"/>
- </draw_ops>
-
- <draw_ops name="title_utility_focused">
- <include name="bg_title_active"/>
- <include name="title_text_focused_no_icon"/>
- </draw_ops>
-
- <frame_style name="normal_unfocused" geometry="normal">
- <piece position="entire_background" draw_ops="focus_background"/>
- <piece position="title" draw_ops="title_normal"/>
-
- <!-- we don't specify for prelight, so normal is used -->
- <button function="close" state="normal" draw_ops="close_button_unfocused"/>
- <button function="close" state="pressed" draw_ops="close_button_pressed"/>
- <button function="minimize" state="normal" draw_ops="minimize_button_unfocused"/>
- <button function="minimize" state="pressed" draw_ops="minimize_button_pressed"/>
- <button function="maximize" state="normal" draw_ops="maximize_button_unfocused"/>
- <button function="maximize" state="pressed" draw_ops="maximize_button_pressed"/>
- <button function="menu" state="normal" draw_ops="menu_button_unfocused"/>
- <button function="menu" state="pressed" draw_ops="menu_button_pressed"/>
- </frame_style>
-
- <frame_style name="normal_focused" geometry="normal">
- <piece position="entire_background" draw_ops="focus_background"/>
- <piece position="title" draw_ops="title_focused"/>
-
- <!-- we don't specify for prelight, so normal is used -->
- <button function="close" state="normal" draw_ops="close_button"/>
- <button function="close" state="pressed" draw_ops="close_button_pressed"/>
- <button function="close" state="prelight" draw_ops="close_button_prelight"/>
- <button function="minimize" state="normal" draw_ops="minimize_button"/>
- <button function="minimize" state="pressed" draw_ops="minimize_button_pressed"/>
- <button function="minimize" state="prelight" draw_ops="minimize_button_prelight"/>
- <button function="maximize" state="normal" draw_ops="maximize_button"/>
- <button function="maximize" state="pressed" draw_ops="maximize_button_pressed"/>
- <button function="maximize" state="prelight" draw_ops="maximize_button_prelight"/>
- <button function="menu" state="normal" draw_ops="menu_button"/>
- <button function="menu" state="pressed" draw_ops="menu_button_pressed"/>
- <button function="menu" state="prelight" draw_ops="menu_button_prelight"/>
- </frame_style>
-
- <frame_style name="maximized_unfocused" geometry="normal_small_borders" parent="normal_unfocused">
- <piece position="entire_background" draw_ops="blank"/>
- <button function="maximize" state="normal" draw_ops="restore_button_unfocused"/>
- <button function="maximize" state="pressed" draw_ops="restore_button_pressed"/>
- </frame_style>
-
- <frame_style name="maximized_focused" geometry="normal_small_borders" parent="normal_focused">
- <piece position="entire_background" draw_ops="focus_outline"/>
- <button function="maximize" state="normal" draw_ops="restore_button"/>
- <button function="maximize" state="pressed" draw_ops="restore_button_pressed"/>
- <button function="maximize" state="prelight" draw_ops="restore_button_prelight"/>
- </frame_style>
-
- <frame_style name="utility_unfocused" geometry="utility" parent="normal_unfocused">
- <piece position="title" draw_ops="title_utility"/>
- </frame_style>
-
- <frame_style name="utility_focused" geometry="utility" parent="normal_focused">
- <piece position="title" draw_ops="title_utility_focused"/>
- </frame_style>
-
- <frame_style name="border" geometry="border" parent="normal_unfocused">
- <piece position="entire_background" draw_ops="outer_bevel"/>
- <piece position="title" draw_ops="blank"/>
- </frame_style>
-
- <frame_style_set name="normal">
- <frame focus="yes" state="normal" resize="both" style="normal_focused"/>
- <frame focus="no" state="normal" resize="both" style="normal_unfocused"/>
- <frame focus="yes" state="maximized" style="maximized_focused"/>
- <frame focus="no" state="maximized" style="maximized_unfocused"/>
- <frame focus="yes" state="shaded" style="normal_focused"/>
- <frame focus="no" state="shaded" style="normal_unfocused"/>
- <frame focus="yes" state="maximized_and_shaded" style="maximized_focused"/>
- <frame focus="no" state="maximized_and_shaded" style="maximized_unfocused"/>
- </frame_style_set>
-
- <frame_style_set name="utility" parent="normal">
- <frame focus="yes" state="normal" resize="both" style="utility_focused"/>
- <frame focus="no" state="normal" resize="both" style="utility_unfocused"/>
- <!-- this is a bunch of crack since utility windows shouldn't be maximized -->
- <frame focus="yes" state="maximized" style="utility_focused"/>
- <frame focus="no" state="maximized" style="utility_unfocused"/>
- <frame focus="yes" state="shaded" style="utility_focused"/>
- <frame focus="no" state="shaded" style="utility_unfocused"/>
- <frame focus="yes" state="maximized_and_shaded" style="utility_focused"/>
- <frame focus="no" state="maximized_and_shaded" style="utility_unfocused"/>
- </frame_style_set>
-
- <frame_style_set name="border">
- <frame focus="yes" state="normal" resize="both" style="border"/>
- <frame focus="no" state="normal" resize="both" style="border"/>
- <frame focus="yes" state="maximized" style="border"/>
- <frame focus="no" state="maximized" style="border"/>
- <frame focus="yes" state="shaded" style="border"/>
- <frame focus="no" state="shaded" style="border"/>
- <frame focus="yes" state="maximized_and_shaded" style="border"/>
- <frame focus="no" state="maximized_and_shaded" style="border"/>
- </frame_style_set>
-
- <window type="normal" style_set="normal"/>
- <window type="dialog" style_set="normal"/>
- <window type="modal_dialog" style_set="normal"/>
- <window type="menu" style_set="normal"/>
- <window type="utility" style_set="utility"/>
- <window type="border" style_set="border"/>
-
- <menu_icon function="close" state="normal" draw_ops="close_button"/>
- <menu_icon function="maximize" state="normal" draw_ops="maximize_button"/>
- <menu_icon function="unmaximize" state="normal" draw_ops="restore_button"/>
- <menu_icon function="minimize" state="normal" draw_ops="minimize_button"/>
-
-</metacity_theme>
diff --git a/src/themes/Simple/close.png b/src/themes/Simple/close.png
deleted file mode 100644
index 3c29292d..00000000
--- a/src/themes/Simple/close.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Simple/maximize.png b/src/themes/Simple/maximize.png
deleted file mode 100644
index e487352b..00000000
--- a/src/themes/Simple/maximize.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Simple/maximized.png b/src/themes/Simple/maximized.png
deleted file mode 100644
index 5e3ad4c5..00000000
--- a/src/themes/Simple/maximized.png
+++ /dev/null
Binary files differ
diff --git a/src/themes/Simple/metacity-theme-1.xml b/src/themes/Simple/metacity-theme-1.xml
deleted file mode 100644
index ec97ce86..00000000
--- a/src/themes/Simple/metacity-theme-1.xml
+++ /dev/null
@@ -1,346 +0,0 @@
-<?xml version="1.0"?>
-<metacity_theme>
-<info>
- <name>Simple</name>
- <author>Tuomas Kuosmanen &lt;tigert@ximian.com&gt;</author>
- <copyright>&#194; Tuomas Kuosmanen, 2002, based on Atlanta theme by Havoc.</copyright>
- <date>April, 2002</date>
- <description>Default GNOME window theme</description>
-</info>
-
-<frame_geometry name="normal">
- <distance name="left_width" value="4"/>
- <distance name="right_width" value="4"/>
- <distance name="bottom_height" value="4"/>
- <distance name="left_titlebar_edge" value="2"/>
- <distance name="right_titlebar_edge" value="2"/>
- <distance name="button_width" value="16"/>
- <distance name="button_height" value="16"/>
- <distance name="title_vertical_pad" value="0"/>
- <border name="title_border" left="1" right="1" top="2" bottom="2"/>
- <border name="button_border" left="1" right="1" top="0" bottom="0"/>
-</frame_geometry>
-
-<!-- strip borders off the normal geometry -->
-<frame_geometry name="normal_small_borders" parent="normal">
- <distance name="left_width" value="0"/>
- <distance name="right_width" value="0"/>
- <distance name="bottom_height" value="0"/>
- <distance name="left_titlebar_edge" value="0"/>
- <distance name="right_titlebar_edge" value="0"/>
-</frame_geometry>
-
-<frame_geometry name="utility" title_scale="xx-small">
- <distance name="left_width" value="3"/>
- <distance name="right_width" value="3"/>
- <distance name="bottom_height" value="4"/>
- <distance name="left_titlebar_edge" value="3"/>
- <distance name="right_titlebar_edge" value="3"/>
- <distance name="button_width" value="16"/>
- <distance name="button_height" value="16"/>
- <distance name="title_vertical_pad" value="1"/>
- <border name="title_border" left="3" right="4" top="3" bottom="3"/>
- <border name="button_border" left="0" right="0" top="0" bottom="0"/>
-</frame_geometry>
-
-<frame_geometry name="border" has_title="false">
- <distance name="left_width" value="4"/>
- <distance name="right_width" value="4"/>
- <distance name="bottom_height" value="4"/>
- <distance name="left_titlebar_edge" value="0"/>
- <distance name="right_titlebar_edge" value="0"/>
- <distance name="button_width" value="0"/>
- <distance name="button_height" value="0"/>
- <distance name="title_vertical_pad" value="4"/>
- <border name="title_border" left="0" right="0" top="0" bottom="0"/>
- <border name="button_border" left="0" right="0" top="0" bottom="0"/>
-</frame_geometry>
-
-<!-- define constants -->
-<constant name="ArrowWidth" value="8"/>
-<constant name="ArrowHeight" value="4"/>
-<constant name="ButtonIPad" value="4"/>
-<constant name="ThickLineWidth" value="3"/>
-<constant name="IconTitleSpacing" value="6"/>
-<constant name="SpacerWidth" value="2"/>
-<constant name="SpacerHeight" value="10"/>
-
-<!-- Buttons -->
-
-<draw_ops name="button_pressed_bg">
- <rectangle color="gtk:light[NORMAL]" filled="true"
- x="1" y="1" width="width" height="height"/>
- <rectangle color="gtk:dark[NORMAL]" filled="true"
- x="0" y="0" width="width - 1" height="height - 1"/>
- <rectangle color="blend/#000000/gtk:bg[NORMAL]/0.9" filled="true"
- x="1" y="1" width="width - 2" height="height - 2"/>
- <!-- gtk_box state="active" shadow="out" x="0" y="0" width="width" height="height"/ -->
-</draw_ops>
-
-<draw_ops name="menu_button">
- <icon x="1"
- y="1"
- width="width-2" height="height-2"/>
-</draw_ops>
-
-<draw_ops name="menu_button_pressed">
- <include name="menu_button"/>
-</draw_ops>
-
-<draw_ops name="minimize_button">
- <line color="gtk:fg[NORMAL]"
- x1="ButtonIPad"
- y1="height - ButtonIPad - ThickLineWidth + 3"
- x2="width"
- y2="height - ButtonIPad - ThickLineWidth + 3"
- width="2"/>
-</draw_ops>
-
-<draw_ops name="minimize_button_pressed">
- <include name="button_pressed_bg"/>
- <include name="minimize_button"/>
-</draw_ops>
-
-<draw_ops name="maximize_button">
- <rectangle color="gtk:fg[NORMAL]" filled="false"
- x="ButtonIPad" y="ButtonIPad" width="width-ButtonIPad*2 + 2"
- height="height-ButtonIPad*2 + 1"/>
- <line color="gtk:fg[NORMAL]" width="2"
- x1="ButtonIPad" y1="ButtonIPad+1" x2="width-ButtonIPad + 2"
- y2="ButtonIPad+2"/>
-</draw_ops>
-
-<draw_ops name="maximize_button_pressed">
- <include name="button_pressed_bg"/>
- <include name="maximize_button"/>
-</draw_ops>
-
-<draw_ops name="mini_window_icon">
- <rectangle color="gtk:bg[NORMAL]" filled="true"
- x="0" y="0" width="width-1" height="height-1"/>
- <rectangle color="gtk:fg[NORMAL]" filled="false"
- x="0" y="0" width="width-1" height="height-1"/>
- <line color="gtk:fg[NORMAL]" width="2" x1="0" y1="1" x2="width" y2="1"/>
-</draw_ops>
-
-<draw_ops name="restore_button">
- <include name="mini_window_icon"
- x="3 + ButtonIPad" y="3 + ButtonIPad"
- width="width - 5 - ButtonIPad"
- height="height - 5 - ButtonIPad"/>
- <include name="mini_window_icon"
- x="ButtonIPad" y="ButtonIPad"
- width="width - 5 - ButtonIPad"
- height="height - 5 - ButtonIPad"/>
-</draw_ops>
-
-<draw_ops name="restore_button_pressed">
- <include name="button_pressed_bg"/>
- <include name="restore_button"/>
-</draw_ops>
-
-<draw_ops name="close_button">
- <line color="gtk:fg[NORMAL]"
- x1="ButtonIPad" y1="ButtonIPad"
- x2="width - ButtonIPad + 1" y2="height - ButtonIPad + 1" width="3"/>
- <line color="gtk:fg[NORMAL]"
- x1="ButtonIPad - 1" y1="height - ButtonIPad"
- x2="width - ButtonIPad + 1" y2="ButtonIPad" width="3"/>
-</draw_ops>
-
-<draw_ops name="close_button_pressed">
- <include name="button_pressed_bg"/>
- <include name="close_button"/>
-</draw_ops>
-
-<draw_ops name="outer_bevel">
- <rectangle color="gtk:fg[NORMAL]"
- x="0" y="0" width="width" height="height" filled="true"/>
- <rectangle color="gtk:bg[NORMAL]"
- x="1" y="1" width="width-2" height="height-2" filled="true"/>
- <line color="gtk:light[NORMAL]"
- x1="1" y1="1" x2="1" y2="height-3"/>
- <line color="gtk:light[NORMAL]"
- x1="1" y1="1" x2="width-3" y2="1"/>
- <line color="gtk:dark[NORMAL]"
- x1="width-2" y1="2" x2="width-2" y2="height-2"/>
- <line color="gtk:dark[NORMAL]"
- x1="2" y1="height-2" x2="width-3" y2="height-2"/>
-</draw_ops>
-
-<draw_ops name="blank">
-<!-- nothing -->
-</draw_ops>
-
-<draw_ops name="focus_outline">
- <rectangle color="gtk:dark[NORMAL]"
- x="left_width-1" y="top_height-1"
- width="width-left_width-right_width+1"
- height="height-top_height-bottom_height+1"/>
-</draw_ops>
-
-<draw_ops name="focus_background">
- <include name="outer_bevel"/>
-</draw_ops>
-
-<draw_ops name="title_tile">
- <line color="gtk:bg[SELECTED]" x1="0" y1="0" x2="width" y2="0"/>
- <line color="blend/gtk:bg[SELECTED]/#000000/0.1" x1="0" y1="1" x2="width" y2="1"/>
-</draw_ops>
-
-<draw_ops name="title_tile_unfocused">
- <line color="blend/gtk:bg[NORMAL]/#000000/0.1" x1="0" y1="0" x2="width" y2="0"/>
- <line color="blend/gtk:bg[NORMAL]/#ffffff/0.2" x1="0" y1="1" x2="width" y2="1"/>
-</draw_ops>
-
-<draw_ops name="title_bg">
- <tile name="title_tile" tile_width="width" tile_height="2" x="0" y="0" width="width" height="height"/>
- <rectangle color="blend/gtk:bg[SELECTED]/#000000/0.6" filled="false" x="0" y="0" width="width-1" height="height-1"/>
- <rectangle color="blend/#000000/gtk:bg[NORMAL]/0.5" filled="true" x="0" y="0" width="1" height="1"/>
- <rectangle color="blend/#000000/gtk:bg[NORMAL]/0.5" filled="true" x="width-1" y="0" width="1" height="1"/>
- <rectangle color="blend/#000000/gtk:bg[NORMAL]/0.5" filled="true" x="0" y="height-1" width="1" height="1"/>
- <rectangle color="blend/#000000/gtk:bg[NORMAL]/0.5" filled="true" x="width-1" y="height-1" width="1" height="1"/>
-</draw_ops>
-
-<draw_ops name="title_bg_unfocused">
- <tile name="title_tile_unfocused" tile_width="width" tile_height="2" x="0" y="0" width="width-1" height="height-1"/>
- <rectangle color="blend/#000000/gtk:fg[NORMAL]/0.7" filled="false" x="0" y="0" width="width-1" height="height-1"/>
- <rectangle color="blend/#000000/gtk:bg[NORMAL]/0.8" filled="true" x="0" y="0" width="1" height="1"/>
- <rectangle color="blend/#000000/gtk:bg[NORMAL]/0.8" filled="true" x="width-1" y="0" width="1" height="1"/>
- <rectangle color="blend/#000000/gtk:bg[NORMAL]/0.8" filled="true" x="0" y="height-1" width="1" height="1"/>
- <rectangle color="blend/#000000/gtk:bg[NORMAL]/0.8" filled="true" x="width-1" y="height-1" width="1" height="1"/>
-</draw_ops>
-
-<draw_ops name="title_text_focused">
- <clip x="0" y="0" width="width-SpacerWidth" height="height"/>
- <title color="blend/gtk:fg[SELECTED]/#000000/0.7"
- x="(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2 + mini_icon_width + IconTitleSpacing + 1"
- y="((height - title_height) / 2) `max` 0 + 1"/>
- <title color="gtk:fg[SELECTED]"
- x="(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2 + mini_icon_width + IconTitleSpacing"
- y="((height - title_height) / 2) `max` 0"/>
-</draw_ops>
-
-<draw_ops name="title_text">
- <clip x="0" y="0" width="width-SpacerWidth" height="height"/>
- <title color="gtk:fg[NORMAL]"
- x="(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2 + mini_icon_width + IconTitleSpacing"
- y="((height - title_height) / 2) `max` 0"/>
-</draw_ops>
-
-<draw_ops name="title_normal">
- <include name="title_bg_unfocused"/>
- <include name="title_text"/>
-</draw_ops>
-
-<draw_ops name="title_focused">
- <include name="title_bg"/>
- <include name="title_text_focused"/>
-</draw_ops>
-
-<draw_ops name="title_utility">
- <include name="title_text"/>
-</draw_ops>
-
-<draw_ops name="title_utility_focused">
- <include name="title_bg"/>
- <include name="title_text_focused"/>
-</draw_ops>
-
-<frame_style name="normal_unfocused" geometry="normal">
- <piece position="entire_background" draw_ops="outer_bevel"/>
- <piece position="title" draw_ops="title_normal"/>
-
- <!-- we don't specify for prelight, so normal is used -->
- <button function="close" state="normal" draw_ops="close_button"/>
- <button function="close" state="pressed" draw_ops="close_button_pressed"/>
- <button function="minimize" state="normal" draw_ops="minimize_button"/>
- <button function="minimize" state="pressed" draw_ops="minimize_button_pressed"/>
- <button function="maximize" state="normal" draw_ops="maximize_button"/>
- <button function="maximize" state="pressed" draw_ops="maximize_button_pressed"/>
- <button function="menu" state="normal" draw_ops="menu_button"/>
- <button function="menu" state="pressed" draw_ops="menu_button_pressed"/>
-</frame_style>
-
-<frame_style name="normal_focused" geometry="normal" parent="normal_unfocused">
- <piece position="entire_background" draw_ops="focus_background"/>
- <piece position="title" draw_ops="title_focused"/>
-</frame_style>
-
-<frame_style name="shaded_focused" geometry="normal" parent="normal_unfocused">
- <piece position="title" draw_ops="title_focused"/>
-</frame_style>
-
-<frame_style name="maximized_unfocused" geometry="normal_small_borders" parent="normal_unfocused">
- <piece position="entire_background" draw_ops="blank"/>
- <button function="maximize" state="normal" draw_ops="restore_button"/>
- <button function="maximize" state="pressed" draw_ops="restore_button_pressed"/>
-</frame_style>
-
-<frame_style name="maximized_focused" geometry="normal_small_borders" parent="normal_focused">
- <piece position="entire_background" draw_ops="focus_outline"/>
- <button function="maximize" state="normal" draw_ops="restore_button"/>
- <button function="maximize" state="pressed" draw_ops="restore_button_pressed"/>
-</frame_style>
-
-<frame_style name="utility_unfocused" geometry="utility" parent="normal_unfocused">
- <piece position="title" draw_ops="title_utility"/>
-</frame_style>
-
-<frame_style name="utility_focused" geometry="utility" parent="normal_focused">
- <piece position="title" draw_ops="title_utility_focused"/>
-</frame_style>
-
-<frame_style name="border" geometry="border" parent="normal_unfocused">
- <piece position="entire_background" draw_ops="outer_bevel"/>
- <piece position="title" draw_ops="blank"/>
-</frame_style>
-
-<frame_style_set name="normal">
-<frame focus="yes" state="normal" resize="both" style="normal_focused"/>
-<frame focus="no" state="normal" resize="both" style="normal_unfocused"/>
-<frame focus="yes" state="maximized" style="maximized_focused"/>
-<frame focus="no" state="maximized" style="maximized_unfocused"/>
-<frame focus="yes" state="shaded" style="shaded_focused"/>
-<frame focus="no" state="shaded" style="normal_unfocused"/>
-<frame focus="yes" state="maximized_and_shaded" style="maximized_focused"/>
-<frame focus="no" state="maximized_and_shaded" style="maximized_unfocused"/>
-</frame_style_set>
-
-<frame_style_set name="utility" parent="normal">
-<frame focus="yes" state="normal" resize="both" style="utility_focused"/>
-<frame focus="no" state="normal" resize="both" style="utility_unfocused"/>
-<!-- this is a bunch of crack since utility windows shouldn't be maximized -->
-<frame focus="yes" state="maximized" style="utility_focused"/>
-<frame focus="no" state="maximized" style="utility_unfocused"/>
-<frame focus="yes" state="shaded" style="utility_focused"/>
-<frame focus="no" state="shaded" style="utility_unfocused"/>
-<frame focus="yes" state="maximized_and_shaded" style="utility_focused"/>
-<frame focus="no" state="maximized_and_shaded" style="utility_unfocused"/>
-</frame_style_set>
-
-<frame_style_set name="border" parent="normal">
-<frame focus="yes" state="normal" resize="both" style="border"/>
-<frame focus="no" state="normal" resize="both" style="border"/>
-<!-- this is a bunch of crack since utility windows shouldn't be maximized -->
-<frame focus="yes" state="maximized" style="utility_focused"/>
-<frame focus="no" state="maximized" style="utility_unfocused"/>
-<frame focus="yes" state="shaded" style="utility_focused"/>
-<frame focus="no" state="shaded" style="utility_unfocused"/>
-<frame focus="yes" state="maximized_and_shaded" style="utility_focused"/>
-<frame focus="no" state="maximized_and_shaded" style="utility_unfocused"/>
-</frame_style_set>
-
-<window type="normal" style_set="normal"/>
-<window type="dialog" style_set="normal"/>
-<window type="modal_dialog" style_set="normal"/>
-<window type="menu" style_set="normal"/>
-<window type="utility" style_set="utility"/>
-<window type="border" style_set="border"/>
-
-<menu_icon function="close" state="normal" draw_ops="close_button"/>
-<menu_icon function="maximize" state="normal" draw_ops="maximize_button"/>
-<menu_icon function="unmaximize" state="normal" draw_ops="restore_button"/>
-<menu_icon function="minimize" state="normal" draw_ops="minimize_button"/>
-
-</metacity_theme>
diff --git a/src/themes/Simple/minimize.png b/src/themes/Simple/minimize.png
deleted file mode 100644
index 608a633d..00000000
--- a/src/themes/Simple/minimize.png
+++ /dev/null
Binary files differ
diff --git a/src/tools/.cvsignore b/src/tools/.cvsignore
deleted file mode 100644
index 8ecc6b5e..00000000
--- a/src/tools/.cvsignore
+++ /dev/null
@@ -1,8 +0,0 @@
-Makefile
-Makefile.in
-metacity-grayscale
-metacity-message
-metacity-mag
-metacity-properties
-metacity-properties.desktop
-metacity-window-demo
diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am
deleted file mode 100644
index fe02c2ca..00000000
--- a/src/tools/Makefile.am
+++ /dev/null
@@ -1,33 +0,0 @@
-@INTLTOOL_DESKTOP_RULE@
-
-icondir=$(pkgdatadir)/icons
-icon_DATA=metacity-window-demo.png
-
-INCLUDES=@METACITY_WINDOW_DEMO_CFLAGS@ @METACITY_MESSAGE_CFLAGS@ \
- -DMETACITY_ICON_DIR=\"$(pkgdatadir)/icons\" \
- -DMETACITY_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\"
-
-metacity_message_SOURCES= \
- metacity-message.c
-
-metacity_window_demo_SOURCES= \
- metacity-window-demo.c
-
-metacity_mag_SOURCES= \
- metacity-mag.c
-
-metacity_grayscale_SOURCES= \
- metacity-grayscale.c
-
-bin_PROGRAMS=metacity-message metacity-window-demo
-
-## cheesy hacks I use, don't really have any business existing. ;-)
-noinst_PROGRAMS=metacity-mag metacity-grayscale
-
-metacity_message_LDADD= @METACITY_MESSAGE_LIBS@
-metacity_window_demo_LDADD= @METACITY_WINDOW_DEMO_LIBS@
-metacity_mag_LDADD= @METACITY_WINDOW_DEMO_LIBS@
-metacity_grayscale_LDADD = @METACITY_WINDOW_DEMO_LIBS@
-
-EXTRA_DIST=$(icon_DATA)
-
diff --git a/src/tools/metacity-grayscale.c b/src/tools/metacity-grayscale.c
deleted file mode 100644
index 8d0cd68c..00000000
--- a/src/tools/metacity-grayscale.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/* Hack for grayscaling an image */
-
-/*
- * Copyright (C) 2002 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <math.h>
-
-#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
-
-static GdkPixbuf*
-grayscale_pixbuf (GdkPixbuf *pixbuf)
-{
- GdkPixbuf *gray;
- guchar *pixels;
- int rowstride;
- int pixstride;
- int row;
- int n_rows;
- int width;
-
- gray = gdk_pixbuf_copy (pixbuf);
- rowstride = gdk_pixbuf_get_rowstride (gray);
- pixstride = gdk_pixbuf_get_has_alpha (gray) ? 4 : 3;
-
- pixels = gdk_pixbuf_get_pixels (gray);
- n_rows = gdk_pixbuf_get_height (gray);
- width = gdk_pixbuf_get_width (gray);
-
- row = 0;
- while (row < n_rows)
- {
- guchar *p = pixels + row * rowstride;
- guchar *end = p + (pixstride * width);
-
- while (p != end)
- {
- double v = INTENSITY (p[0], p[1], p[2]);
-
- p[0] = (guchar) v;
- p[1] = (guchar) v;
- p[2] = (guchar) v;
-
- p += pixstride;
- }
-
- ++row;
- }
-
- return gray;
-}
-
-int
-main (int argc, char **argv)
-{
- GdkPixbuf *pixbuf;
- GdkPixbuf *gray;
- GError *err;
-
- if (argc != 2)
- {
- g_printerr ("specify a single image on the command line\n");
- return 1;
- }
-
- g_type_init ();
-
- err = NULL;
- pixbuf = gdk_pixbuf_new_from_file (argv[1], &err);
- if (err != NULL)
- {
- g_printerr ("failed to load image: %s\n", err->message);
- g_error_free (err);
- return 1;
- }
-
- gray = grayscale_pixbuf (pixbuf);
-
- err = NULL;
- gdk_pixbuf_save (gray, "grayscale.png", "png", &err, NULL);
- if (err != NULL)
- {
- g_printerr ("failed to save image: %s\n", err->message);
- g_error_free (err);
- return 1;
- }
-
- g_print ("wrote grayscale.png\n");
-
- return 0;
-}
diff --git a/src/tools/metacity-mag.c b/src/tools/metacity-mag.c
deleted file mode 100644
index a5f1b1b2..00000000
--- a/src/tools/metacity-mag.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/* Hack for use instead of xmag */
-
-/*
- * Copyright (C) 2002 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#define _GNU_SOURCE
-#define _XOPEN_SOURCE 600 /* C99 -- for rint() */
-
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
-#include <gdk/gdkkeysyms.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <math.h>
-
-static GtkWidget *grab_widget = NULL;
-static GtkWidget *display_window = NULL;
-static int last_grab_x = 0;
-static int last_grab_y = 0;
-static int last_grab_width = 150;
-static int last_grab_height = 150;
-static GtkAllocation last_grab_allocation;
-static double width_factor = 4.0;
-static double height_factor = 4.0;
-static GdkInterpType interp_mode = GDK_INTERP_NEAREST;
-static guint regrab_idle_id = 0;
-
-static GdkPixbuf*
-get_pixbuf (void)
-{
- GdkPixbuf *screenshot;
- GdkPixbuf *magnified;
-
-#if 0
- g_print ("Size %d x %d\n",
- last_grab_width, last_grab_height);
-#endif
-
- screenshot = gdk_pixbuf_get_from_drawable (NULL, gdk_get_default_root_window (),
- NULL,
- last_grab_x, last_grab_y, 0, 0,
- last_grab_width, last_grab_height);
-
- if (screenshot == NULL)
- {
- g_printerr ("Screenshot failed\n");
- exit (1);
- }
-
- magnified = gdk_pixbuf_scale_simple (screenshot, last_grab_width * width_factor,
- last_grab_height * height_factor,
- interp_mode);
-
-
- g_object_unref (G_OBJECT (screenshot));
-
- return magnified;
-}
-
-static gboolean
-regrab_idle (GtkWidget *image)
-{
- GdkPixbuf *magnified;
-
- if (image->allocation.width != last_grab_allocation.width ||
- image->allocation.height != last_grab_allocation.height)
- {
- last_grab_width = rint (image->allocation.width / width_factor);
- last_grab_height = rint (image->allocation.height / height_factor);
- last_grab_allocation = image->allocation;
-
- magnified = get_pixbuf ();
-
- gtk_image_set_from_pixbuf (GTK_IMAGE (image), magnified);
-
- g_object_unref (G_OBJECT (magnified));
- }
-
- regrab_idle_id = 0;
-
- return FALSE;
-}
-
-static void
-image_resized (GtkWidget *image)
-{
- if (regrab_idle_id == 0)
- regrab_idle_id = g_idle_add_full (G_PRIORITY_LOW + 100, (GSourceFunc) regrab_idle,
- image, NULL);
-}
-
-static void
-grab_area_at_mouse (GtkWidget *invisible,
- int x_root,
- int y_root)
-{
- GdkPixbuf *magnified;
- int width, height;
- GtkWidget *widget;
-
- width = last_grab_width;
- height = last_grab_height;
-
- last_grab_x = x_root;
- last_grab_y = y_root;
- last_grab_width = width;
- last_grab_height = height;
-
- magnified = get_pixbuf ();
-
- display_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_default_size (GTK_WINDOW (display_window),
- last_grab_width, last_grab_height);
- widget = gtk_image_new_from_pixbuf (magnified);
- gtk_widget_set_size_request (widget, 40, 40);
- gtk_container_add (GTK_CONTAINER (display_window), widget);
- g_object_unref (G_OBJECT (magnified));
-
- g_object_add_weak_pointer (G_OBJECT (display_window),
- (gpointer) &display_window);
-
- g_signal_connect (G_OBJECT (display_window), "destroy",
- G_CALLBACK (gtk_main_quit), NULL);
-
- g_signal_connect_after (G_OBJECT (widget), "size_allocate", G_CALLBACK (image_resized), NULL);
-
- gtk_widget_show_all (display_window);
-}
-
-static void
-shutdown_grab (void)
-{
- gdk_keyboard_ungrab (gtk_get_current_event_time ());
- gdk_pointer_ungrab (gtk_get_current_event_time ());
- gtk_grab_remove (grab_widget);
-}
-
-static void
-mouse_motion (GtkWidget *invisible,
- GdkEventMotion *event,
- gpointer data)
-{
-
-}
-
-static gboolean
-mouse_release (GtkWidget *invisible,
- GdkEventButton *event,
- gpointer data)
-{
- if (event->button != 1)
- return FALSE;
-
- grab_area_at_mouse (invisible, event->x_root, event->y_root);
-
- shutdown_grab ();
-
- gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
- GTK_SIGNAL_FUNC (mouse_motion), NULL);
- gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
- GTK_SIGNAL_FUNC (mouse_release), NULL);
-
- return TRUE;
-}
-
-/* Helper Functions */
-
-static gboolean mouse_press (GtkWidget *invisible,
- GdkEventButton *event,
- gpointer data);
-
-static gboolean
-key_press (GtkWidget *invisible,
- GdkEventKey *event,
- gpointer data)
-{
- if (event->keyval == GDK_Escape)
- {
- shutdown_grab ();
-
- gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
- GTK_SIGNAL_FUNC (mouse_press),
- NULL);
- gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
- GTK_SIGNAL_FUNC (key_press),
- NULL);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-mouse_press (GtkWidget *invisible,
- GdkEventButton *event,
- gpointer data)
-{
- if (event->type == GDK_BUTTON_PRESS &&
- event->button == 1)
- {
- g_signal_connect (invisible, "motion_notify_event",
- G_CALLBACK (mouse_motion), NULL);
- g_signal_connect (invisible, "button_release_event",
- G_CALLBACK (mouse_release), NULL);
- gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
- GTK_SIGNAL_FUNC (mouse_press),
- NULL);
- gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
- GTK_SIGNAL_FUNC (key_press),
- NULL);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-begin_area_grab (void)
-{
- if (grab_widget == NULL)
- {
- grab_widget = gtk_invisible_new ();
-
- gtk_widget_add_events (grab_widget,
- GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);
-
- gtk_widget_show (grab_widget);
- }
-
- if (gdk_keyboard_grab (grab_widget->window,
- FALSE,
- gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS)
- {
- g_warning ("Failed to grab keyboard to do eyedropper");
- return;
- }
-
- if (gdk_pointer_grab (grab_widget->window,
- FALSE,
- GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK,
- NULL,
- NULL,
- gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS)
- {
- gdk_keyboard_ungrab (GDK_CURRENT_TIME);
- g_warning ("Failed to grab pointer to do eyedropper");
- return;
- }
-
- gtk_grab_add (grab_widget);
-
- g_signal_connect (grab_widget, "button_press_event",
- G_CALLBACK (mouse_press), NULL);
- g_signal_connect (grab_widget, "key_press_event",
- G_CALLBACK (key_press), NULL);
-}
-
-int
-main (int argc, char **argv)
-{
- gtk_init (&argc, &argv);
-
- begin_area_grab ();
-
- gtk_main ();
-
- return 0;
-}
diff --git a/src/tools/metacity-message.c b/src/tools/metacity-message.c
deleted file mode 100644
index 0df89912..00000000
--- a/src/tools/metacity-message.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/* Metacity send-magic-messages app */
-
-/*
- * Copyright (C) 2002 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <libintl.h>
-#define _(x) dgettext (GETTEXT_PACKAGE, x)
-#define N_(x) x
-
-
-static void
-send_restart (void)
-{
- XEvent xev;
-
- xev.xclient.type = ClientMessage;
- xev.xclient.serial = 0;
- xev.xclient.send_event = True;
- xev.xclient.display = gdk_display;
- xev.xclient.window = gdk_x11_get_default_root_xwindow ();
- xev.xclient.message_type = XInternAtom (gdk_display,
- "_METACITY_RESTART_MESSAGE",
- False);
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = 0;
- xev.xclient.data.l[1] = 0;
- xev.xclient.data.l[2] = 0;
-
- XSendEvent (gdk_display,
- gdk_x11_get_default_root_xwindow (),
- False,
- SubstructureRedirectMask | SubstructureNotifyMask,
- &xev);
-
- XFlush (gdk_display);
- XSync (gdk_display, False);
-}
-
-static void
-send_reload_theme (void)
-{
- XEvent xev;
-
- xev.xclient.type = ClientMessage;
- xev.xclient.serial = 0;
- xev.xclient.send_event = True;
- xev.xclient.display = gdk_display;
- xev.xclient.window = gdk_x11_get_default_root_xwindow ();
- xev.xclient.message_type = XInternAtom (gdk_display,
- "_METACITY_RELOAD_THEME_MESSAGE",
- False);
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = 0;
- xev.xclient.data.l[1] = 0;
- xev.xclient.data.l[2] = 0;
-
- XSendEvent (gdk_display,
- gdk_x11_get_default_root_xwindow (),
- False,
- SubstructureRedirectMask | SubstructureNotifyMask,
- &xev);
-
- XFlush (gdk_display);
- XSync (gdk_display, False);
-}
-
-static void
-send_set_keybindings (gboolean enabled)
-{
- XEvent xev;
-
- xev.xclient.type = ClientMessage;
- xev.xclient.serial = 0;
- xev.xclient.send_event = True;
- xev.xclient.display = gdk_display;
- xev.xclient.window = gdk_x11_get_default_root_xwindow ();
- xev.xclient.message_type = XInternAtom (gdk_display,
- "_METACITY_SET_KEYBINDINGS_MESSAGE",
- False);
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = enabled;
- xev.xclient.data.l[1] = 0;
- xev.xclient.data.l[2] = 0;
-
- XSendEvent (gdk_display,
- gdk_x11_get_default_root_xwindow (),
- False,
- SubstructureRedirectMask | SubstructureNotifyMask,
- &xev);
-
- XFlush (gdk_display);
- XSync (gdk_display, False);
-}
-
-#ifdef WITH_VERBOSE_MODE
-static void
-send_toggle_verbose (void)
-{
- XEvent xev;
-
- xev.xclient.type = ClientMessage;
- xev.xclient.serial = 0;
- xev.xclient.send_event = True;
- xev.xclient.display = gdk_display;
- xev.xclient.window = gdk_x11_get_default_root_xwindow ();
- xev.xclient.message_type = XInternAtom (gdk_display,
- "_METACITY_TOGGLE_VERBOSE",
- False);
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = 0;
- xev.xclient.data.l[1] = 0;
- xev.xclient.data.l[2] = 0;
-
- XSendEvent (gdk_display,
- gdk_x11_get_default_root_xwindow (),
- False,
- SubstructureRedirectMask | SubstructureNotifyMask,
- &xev);
-
- XFlush (gdk_display);
- XSync (gdk_display, False);
-}
-#endif
-
-static void
-usage (void)
-{
- g_printerr (_("Usage: %s\n"),
- "metacity-message (restart|reload-theme|enable-keybindings|disable-keybindings|toggle-verbose)");
- exit (1);
-}
-
-int
-main (int argc, char **argv)
-{
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-
- gtk_init (&argc, &argv);
-
- if (argc < 2)
- usage ();
-
- if (strcmp (argv[1], "restart") == 0)
- send_restart ();
- else if (strcmp (argv[1], "reload-theme") == 0)
- send_reload_theme ();
- else if (strcmp (argv[1], "enable-keybindings") == 0)
- send_set_keybindings (TRUE);
- else if (strcmp (argv[1], "disable-keybindings") == 0)
- send_set_keybindings (FALSE);
- else if (strcmp (argv[1], "toggle-verbose") == 0)
- {
-#ifndef WITH_VERBOSE_MODE
- g_printerr (_("Metacity was compiled without support for verbose mode\n"));
- return 1;
-#else
- send_toggle_verbose ();
-#endif
- }
- else
- usage ();
-
- return 0;
-}
-
diff --git a/src/tools/metacity-window-demo.c b/src/tools/metacity-window-demo.c
deleted file mode 100644
index 0685b1f3..00000000
--- a/src/tools/metacity-window-demo.c
+++ /dev/null
@@ -1,997 +0,0 @@
-/* Metacity window types/properties demo app */
-
-/*
- * Copyright (C) 2002 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
-#include <X11/Xatom.h>
-#include <unistd.h>
-
-static GtkWidget* do_appwindow (void);
-
-static gboolean aspect_on;
-
-static void
-set_gdk_window_struts (GdkWindow *window,
- int left,
- int right,
- int top,
- int bottom)
-{
- long vals[12];
-
- vals[0] = left;
- vals[1] = right;
- vals[2] = top;
- vals[3] = bottom;
- vals[4] = 000;
- vals[5] = 400;
- vals[6] = 200;
- vals[7] = 600;
- vals[8] = 76;
- vals[9] = 676;
- vals[10] = 200;
- vals[11] = 800;
-
- XChangeProperty (GDK_WINDOW_XDISPLAY (window),
- GDK_WINDOW_XWINDOW (window),
- XInternAtom (GDK_WINDOW_XDISPLAY (window),
- "_NET_WM_STRUT_PARTIAL", False),
- XA_CARDINAL, 32, PropModeReplace,
- (guchar *)vals, 12);
-}
-
-static void
-on_realize_set_struts (GtkWindow *window,
- gpointer data)
-{
- int left;
- int right;
- int top;
- int bottom;
-
- g_return_if_fail (GTK_WIDGET_REALIZED (window));
-
- left = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "meta-strut-left"));
- right = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "meta-strut-right"));
- top = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "meta-strut-top"));
- bottom = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "meta-strut-bottom"));
-
- set_gdk_window_struts (GTK_WIDGET (window)->window,
- left, right, top, bottom);
-}
-
-static void
-set_gtk_window_struts (GtkWidget *window,
- int left,
- int right,
- int top,
- int bottom)
-{
- g_object_set_data (G_OBJECT (window), "meta-strut-left",
- GINT_TO_POINTER (left));
- g_object_set_data (G_OBJECT (window), "meta-strut-right",
- GINT_TO_POINTER (right));
- g_object_set_data (G_OBJECT (window), "meta-strut-top",
- GINT_TO_POINTER (top));
- g_object_set_data (G_OBJECT (window), "meta-strut-bottom",
- GINT_TO_POINTER (bottom));
-
- g_signal_handlers_disconnect_by_func (G_OBJECT (window),
- on_realize_set_struts,
- NULL);
-
- g_signal_connect_after (G_OBJECT (window),
- "realize",
- G_CALLBACK (on_realize_set_struts),
- NULL);
-
- if (GTK_WIDGET_REALIZED (window))
- set_gdk_window_struts (GTK_WIDGET (window)->window,
- left, right, top, bottom);
-}
-
-static void
-set_gdk_window_type (GdkWindow *window,
- const char *type)
-{
- Atom atoms[2] = { None, None };
-
- atoms[0] = XInternAtom (GDK_WINDOW_XDISPLAY (window),
- type, False);
-
- XChangeProperty (GDK_WINDOW_XDISPLAY (window),
- GDK_WINDOW_XWINDOW (window),
- XInternAtom (GDK_WINDOW_XDISPLAY (window), "_NET_WM_WINDOW_TYPE", False),
- XA_ATOM, 32, PropModeReplace,
- (guchar *)atoms,
- 1);
-}
-
-static void
-on_realize_set_type (GtkWindow *window,
- gpointer data)
-{
- const char *type;
-
- g_return_if_fail (GTK_WIDGET_REALIZED (window));
-
- type = g_object_get_data (G_OBJECT (window), "meta-window-type");
-
- g_return_if_fail (type != NULL);
-
- set_gdk_window_type (GTK_WIDGET (window)->window,
- type);
-}
-
-static void
-set_gtk_window_type (GtkWindow *window,
- const char *type)
-{
- g_object_set_data (G_OBJECT (window), "meta-window-type", (char*) type);
-
- g_signal_handlers_disconnect_by_func (G_OBJECT (window),
- on_realize_set_type,
- NULL);
-
- g_signal_connect_after (G_OBJECT (window),
- "realize",
- G_CALLBACK (on_realize_set_type),
- NULL);
-
- if (GTK_WIDGET_REALIZED (window))
- set_gdk_window_type (GTK_WIDGET (window)->window,
- type);
-}
-
-static void
-set_gdk_window_border_only (GdkWindow *window)
-{
- gdk_window_set_decorations (window, GDK_DECOR_BORDER);
-}
-
-static void
-on_realize_set_border_only (GtkWindow *window,
- gpointer data)
-{
- g_return_if_fail (GTK_WIDGET_REALIZED (window));
-
- set_gdk_window_border_only (GTK_WIDGET (window)->window);
-}
-
-static void
-set_gtk_window_border_only (GtkWindow *window)
-{
- g_signal_handlers_disconnect_by_func (G_OBJECT (window),
- on_realize_set_border_only,
- NULL);
-
- g_signal_connect_after (G_OBJECT (window),
- "realize",
- G_CALLBACK (on_realize_set_border_only),
- NULL);
-
- if (GTK_WIDGET_REALIZED (window))
- set_gdk_window_border_only (GTK_WIDGET (window)->window);
-}
-
-int
-main (int argc, char **argv)
-{
- GList *list;
- GdkPixbuf *pixbuf;
- GError *err;
-
- gtk_init (&argc, &argv);
-
- err = NULL;
- pixbuf = gdk_pixbuf_new_from_file (METACITY_ICON_DIR"/metacity-window-demo.png",
- &err);
- if (pixbuf)
- {
- list = g_list_prepend (NULL, pixbuf);
-
- gtk_window_set_default_icon_list (list);
- g_list_free (list);
- g_object_unref (G_OBJECT (pixbuf));
- }
- else
- {
- g_printerr ("Could not load icon: %s\n", err->message);
- g_error_free (err);
- }
-
- do_appwindow ();
-
- gtk_main ();
-
- return 0;
-}
-
-static void
-response_cb (GtkDialog *dialog,
- int response_id,
- void *data);
-
-static void
-make_dialog (GtkWidget *parent,
- int depth)
-{
- GtkWidget *dialog;
- char *str;
-
- dialog = gtk_message_dialog_new (parent ? GTK_WINDOW (parent) : NULL,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_INFO,
- GTK_BUTTONS_CLOSE,
- parent ? "Here is a dialog %d" :
- "Here is a dialog %d with no transient parent",
- depth);
-
- str = g_strdup_printf ("%d dialog", depth);
- gtk_window_set_title (GTK_WINDOW (dialog), str);
- g_free (str);
-
- gtk_dialog_add_button (GTK_DIALOG (dialog),
- "Open child dialog",
- GTK_RESPONSE_ACCEPT);
-
- /* Close dialog on user response */
- g_signal_connect (G_OBJECT (dialog),
- "response",
- G_CALLBACK (response_cb),
- NULL);
-
- g_object_set_data (G_OBJECT (dialog), "depth",
- GINT_TO_POINTER (depth));
-
- gtk_widget_show (dialog);
-}
-
-static void
-response_cb (GtkDialog *dialog,
- int response_id,
- void *data)
-{
- switch (response_id)
- {
- case GTK_RESPONSE_ACCEPT:
- make_dialog (GTK_WIDGET (dialog),
- GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dialog),
- "depth")) + 1);
- break;
-
- default:
- gtk_widget_destroy (GTK_WIDGET (dialog));
- break;
- }
-}
-
-static void
-dialog_cb (gpointer callback_data,
- guint callback_action,
- GtkWidget *widget)
-{
- make_dialog (GTK_WIDGET (callback_data), 1);
-}
-
-static void
-modal_dialog_cb (gpointer callback_data,
- guint callback_action,
- GtkWidget *widget)
-{
- GtkWidget *dialog;
-
- dialog = gtk_message_dialog_new (GTK_WINDOW (callback_data),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_INFO,
- GTK_BUTTONS_CLOSE,
- "Here is a MODAL dialog");
-
- set_gtk_window_type (GTK_WINDOW (dialog), "_NET_WM_WINDOW_TYPE_MODAL_DIALOG");
-
- gtk_dialog_run (GTK_DIALOG (dialog));
-
- gtk_widget_destroy (dialog);
-}
-
-static void
-no_parent_dialog_cb (gpointer callback_data,
- guint callback_action,
- GtkWidget *widget)
-{
- make_dialog (NULL, 1);
-}
-
-static void
-utility_cb (gpointer callback_data,
- guint callback_action,
- GtkWidget *widget)
-{
- GtkWidget *window;
- GtkWidget *vbox;
- GtkWidget *button;
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_UTILITY");
- gtk_window_set_title (GTK_WINDOW (window), "Utility");
-
- gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (callback_data));
-
- vbox = gtk_vbox_new (FALSE, 0);
-
- gtk_container_add (GTK_CONTAINER (window), vbox);
-
- button = gtk_button_new_with_mnemonic ("_A button");
- gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-
- button = gtk_button_new_with_mnemonic ("_B button");
- gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-
- button = gtk_button_new_with_mnemonic ("_C button");
- gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-
- button = gtk_button_new_with_mnemonic ("_D button");
- gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-
- gtk_widget_show_all (window);
-}
-
-static void
-toolbar_cb (gpointer callback_data,
- guint callback_action,
- GtkWidget *widget)
-{
- GtkWidget *window;
- GtkWidget *vbox;
- GtkWidget *label;
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_TOOLBAR");
- gtk_window_set_title (GTK_WINDOW (window), "Toolbar");
-
- gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (callback_data));
-
- vbox = gtk_vbox_new (FALSE, 0);
-
- gtk_container_add (GTK_CONTAINER (window), vbox);
-
- label = gtk_label_new ("FIXME this needs a resize grip, etc.");
- gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
-
- gtk_widget_show_all (window);
-}
-
-static void
-menu_cb (gpointer callback_data,
- guint callback_action,
- GtkWidget *widget)
-{
- GtkWidget *window;
- GtkWidget *vbox;
- GtkWidget *label;
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_MENU");
- gtk_window_set_title (GTK_WINDOW (window), "Menu");
-
- gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (callback_data));
-
- vbox = gtk_vbox_new (FALSE, 0);
-
- gtk_container_add (GTK_CONTAINER (window), vbox);
-
- label = gtk_label_new ("FIXME this isn't a menu.");
- gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
-
- gtk_widget_show_all (window);
-}
-
-static void
-override_redirect_cb (gpointer callback_data,
- guint callback_action,
- GtkWidget *widget)
-{
- GtkWidget *window;
- GtkWidget *vbox;
- GtkWidget *label;
-
- window = gtk_window_new (GTK_WINDOW_POPUP);
- gtk_window_set_title (GTK_WINDOW (window), "Override Redirect");
-
- vbox = gtk_vbox_new (FALSE, 0);
-
- gtk_container_add (GTK_CONTAINER (window), vbox);
-
- label = gtk_label_new ("This is an override\nredirect window\nand should not be managed");
- gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
-
- gtk_widget_show_all (window);
-}
-
-static void
-border_only_cb (gpointer callback_data,
- guint callback_action,
- GtkWidget *widget)
-{
- GtkWidget *window;
- GtkWidget *vbox;
- GtkWidget *label;
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- set_gtk_window_border_only (GTK_WINDOW (window));
- gtk_window_set_title (GTK_WINDOW (window), "Border only");
-
- gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (callback_data));
-
- vbox = gtk_vbox_new (FALSE, 0);
-
- gtk_container_add (GTK_CONTAINER (window), vbox);
-
- label = gtk_label_new ("This window is supposed to have a border but no titlebar.");
- gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
-
- gtk_widget_show_all (window);
-}
-
-#if 0
-static void
-changing_icon_cb (gpointer callback_data,
- guint callback_action,
- GtkWidget *widget)
-{
- GtkWidget *window;
- GtkWidget *vbox;
- GtkWidget *label;
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title (GTK_WINDOW (window), "Changing Icon");
-
- vbox = gtk_vbox_new (FALSE, 0);
-
- gtk_container_add (GTK_CONTAINER (window), vbox);
-
- label = gtk_label_new ("This window has an icon that changes over time");
- gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
-
- gtk_widget_show_all (window);
-}
-#endif
-
-static gboolean
-focus_in_event_cb (GtkWidget *window,
- GdkEvent *event,
- gpointer data)
-{
- GtkWidget *widget;
-
- widget = GTK_WIDGET (data);
-
- gtk_label_set_text (GTK_LABEL (widget), "Has focus");
-
- return TRUE;
-}
-
-
-static gboolean
-focus_out_event_cb (GtkWidget *window,
- GdkEvent *event,
- gpointer data)
-{
- GtkWidget *widget;
-
- widget = GTK_WIDGET (data);
-
- gtk_label_set_text (GTK_LABEL (widget), "Not focused");
-
- return TRUE;
-}
-
-static GtkWidget*
-focus_label (GtkWidget *window)
-{
- GtkWidget *label;
-
- label = gtk_label_new ("Not focused");
-
- g_signal_connect (G_OBJECT (window), "focus_in_event",
- G_CALLBACK (focus_in_event_cb), label);
-
- g_signal_connect (G_OBJECT (window), "focus_out_event",
- G_CALLBACK (focus_out_event_cb), label);
-
- return label;
-}
-
-static void
-splashscreen_cb (gpointer callback_data,
- guint callback_action,
- GtkWidget *widget)
-{
- GtkWidget *window;
- GtkWidget *image;
- GtkWidget *vbox;
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_SPLASHSCREEN");
- gtk_window_set_title (GTK_WINDOW (window), "Splashscreen");
-
- vbox = gtk_vbox_new (FALSE, 0);
-
- image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
- gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0);
-
- gtk_box_pack_start (GTK_BOX (vbox), focus_label (window), FALSE, FALSE, 0);
-
- gtk_container_add (GTK_CONTAINER (window), vbox);
-
- gtk_widget_show_all (window);
-}
-
-enum
-{
- DOCK_TOP = 1,
- DOCK_BOTTOM = 2,
- DOCK_LEFT = 3,
- DOCK_RIGHT = 4,
- DOCK_ALL = 5
-};
-
-static void
-make_dock (int type)
-{
- GtkWidget *window;
- GtkWidget *image;
- GtkWidget *box;
- GtkWidget *button;
-
- g_return_if_fail (type != DOCK_ALL);
-
- box = NULL;
- switch (type)
- {
- case DOCK_LEFT:
- case DOCK_RIGHT:
- box = gtk_vbox_new (FALSE, 0);
- break;
- case DOCK_TOP:
- case DOCK_BOTTOM:
- box = gtk_hbox_new (FALSE, 0);
- break;
- case DOCK_ALL:
- break;
- }
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_DOCK");
-
- image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
- gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 0);
-
- gtk_box_pack_start (GTK_BOX (box), focus_label (window), FALSE, FALSE, 0);
-
- button = gtk_button_new_with_label ("Close");
- gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
-
- g_signal_connect_swapped (G_OBJECT (button), "clicked",
- G_CALLBACK (gtk_widget_destroy), window);
-
- gtk_container_add (GTK_CONTAINER (window), box);
-
-#define DOCK_SIZE 48
- switch (type)
- {
- case DOCK_LEFT:
- gtk_widget_set_size_request (window, DOCK_SIZE, 400);
- gtk_window_move (GTK_WINDOW (window), 0, 000);
- set_gtk_window_struts (window, DOCK_SIZE, 0, 0, 0);
- gtk_window_set_title (GTK_WINDOW (window), "LeftDock");
- break;
- case DOCK_RIGHT:
- gtk_widget_set_size_request (window, DOCK_SIZE, 400);
- gtk_window_move (GTK_WINDOW (window), gdk_screen_width () - DOCK_SIZE, 200);
- set_gtk_window_struts (window, 0, DOCK_SIZE, 0, 0);
- gtk_window_set_title (GTK_WINDOW (window), "RightDock");
- break;
- case DOCK_TOP:
- gtk_widget_set_size_request (window, 600, DOCK_SIZE);
- gtk_window_move (GTK_WINDOW (window), 76, 0);
- set_gtk_window_struts (window, 0, 0, DOCK_SIZE, 0);
- gtk_window_set_title (GTK_WINDOW (window), "TopDock");
- break;
- case DOCK_BOTTOM:
- gtk_widget_set_size_request (window, 600, DOCK_SIZE);
- gtk_window_move (GTK_WINDOW (window), 200, gdk_screen_height () - DOCK_SIZE);
- set_gtk_window_struts (window, 0, 0, 0, DOCK_SIZE);
- gtk_window_set_title (GTK_WINDOW (window), "BottomDock");
- break;
- case DOCK_ALL:
- break;
- }
-
- gtk_widget_show_all (window);
-}
-
-static void
-dock_cb (gpointer callback_data,
- guint callback_action,
- GtkWidget *widget)
-{
- if (callback_action == DOCK_ALL)
- {
- make_dock (DOCK_TOP);
- make_dock (DOCK_BOTTOM);
- make_dock (DOCK_LEFT);
- make_dock (DOCK_RIGHT);
- }
- else
- {
- make_dock (callback_action);
- }
-}
-
-static void
-desktop_cb (gpointer callback_data,
- guint callback_action,
- GtkWidget *widget)
-{
- GtkWidget *window;
- GtkWidget *label;
- GdkColor desktop_color;
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_DESKTOP");
- gtk_window_set_title (GTK_WINDOW (window), "Desktop");
- gtk_widget_set_size_request (window,
- gdk_screen_width (), gdk_screen_height ());
- gtk_window_move (GTK_WINDOW (window), 0, 0);
-
- desktop_color.red = 0x5144;
- desktop_color.green = 0x75D6;
- desktop_color.blue = 0xA699;
-
- gtk_widget_modify_bg (window, GTK_STATE_NORMAL, &desktop_color);
-
- label = focus_label (window);
-
- gtk_container_add (GTK_CONTAINER (window), label);
-
- gtk_widget_show_all (window);
-}
-
-static GtkItemFactoryEntry menu_items[] =
-{
- { "/_Windows", NULL, NULL, 0, "<Branch>" },
- { "/Windows/tearoff", NULL, NULL, 0, "<Tearoff>" },
- { "/Windows/_Dialog", "<control>d", dialog_cb, 0, NULL },
- { "/Windows/_Modal dialog", NULL, modal_dialog_cb, 0, NULL },
- { "/Windows/_Parentless dialog", NULL, no_parent_dialog_cb, 0, NULL },
- { "/Windows/_Utility", "<control>u", utility_cb, 0, NULL },
- { "/Windows/_Splashscreen", "<control>s", splashscreen_cb, 0, NULL },
- { "/Windows/_Top dock", NULL, dock_cb, DOCK_TOP, NULL },
- { "/Windows/_Bottom dock", NULL, dock_cb, DOCK_BOTTOM, NULL },
- { "/Windows/_Left dock", NULL, dock_cb, DOCK_LEFT, NULL },
- { "/Windows/_Right dock", NULL, dock_cb, DOCK_RIGHT, NULL },
- { "/Windows/_All docks", NULL, dock_cb, DOCK_ALL, NULL },
- { "/Windows/Des_ktop", NULL, desktop_cb, 0, NULL },
- { "/Windows/Me_nu", NULL, menu_cb, 0, NULL },
- { "/Windows/Tool_bar", NULL, toolbar_cb, 0, NULL },
- { "/Windows/Override Redirect", NULL, override_redirect_cb, 0, NULL },
- { "/Windows/Border Only", NULL, border_only_cb, 0, NULL }
-};
-
-static void
-sleep_cb (GtkWidget *button,
- gpointer data)
-{
- sleep (1000);
-}
-
-static void
-toggle_aspect_ratio (GtkWidget *button,
- gpointer data)
-{
- GtkWidget *window;
- GdkGeometry geom;
-
- if (aspect_on)
- {
- geom.min_aspect = 0;
- geom.max_aspect = 65535;
- }
- else
- {
- geom.min_aspect = 1.777778;
- geom.max_aspect = 1.777778;
- }
-
- aspect_on = !aspect_on;
-
- window = gtk_widget_get_ancestor (button, GTK_TYPE_WINDOW);
- if (window)
- gtk_window_set_geometry_hints (GTK_WINDOW (window),
- GTK_WIDGET (data),
- &geom,
- GDK_HINT_ASPECT);
-
-}
-
-static void
-toggle_decorated_cb (GtkWidget *button,
- gpointer data)
-{
- GtkWidget *window;
- window = gtk_widget_get_ancestor (button, GTK_TYPE_WINDOW);
- if (window)
- gtk_window_set_decorated (GTK_WINDOW (window),
- !gtk_window_get_decorated (GTK_WINDOW (window)));
-}
-
-static void
-clicked_toolbar_cb (GtkWidget *button,
- gpointer data)
-{
- GtkWidget *dialog;
-
- dialog = gtk_message_dialog_new (GTK_WINDOW (data),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_INFO,
- GTK_BUTTONS_CLOSE,
- "Clicking the toolbar buttons doesn't do anything");
-
- /* Close dialog on user response */
- g_signal_connect (G_OBJECT (dialog),
- "response",
- G_CALLBACK (gtk_widget_destroy),
- NULL);
-
- gtk_widget_show (dialog);
-}
-
-static void
-update_statusbar (GtkTextBuffer *buffer,
- GtkStatusbar *statusbar)
-{
- gchar *msg;
- gint row, col;
- gint count;
- GtkTextIter iter;
-
- gtk_statusbar_pop (statusbar, 0); /* clear any previous message, underflow is allowed */
-
- count = gtk_text_buffer_get_char_count (buffer);
-
- gtk_text_buffer_get_iter_at_mark (buffer,
- &iter,
- gtk_text_buffer_get_insert (buffer));
-
- row = gtk_text_iter_get_line (&iter);
- col = gtk_text_iter_get_line_offset (&iter);
-
- msg = g_strdup_printf ("Cursor at row %d column %d - %d chars in document",
- row, col, count);
-
- gtk_statusbar_push (statusbar, 0, msg);
-
- g_free (msg);
-}
-
-static void
-mark_set_callback (GtkTextBuffer *buffer,
- const GtkTextIter *new_location,
- GtkTextMark *mark,
- gpointer data)
-{
- update_statusbar (buffer, GTK_STATUSBAR (data));
-}
-
-static int window_count = 0;
-
-static void
-destroy_cb (GtkWidget *w, gpointer data)
-{
- --window_count;
- if (window_count == 0)
- gtk_main_quit ();
-}
-
-static GtkWidget *
-do_appwindow (void)
-{
- GtkWidget *window;
- GtkWidget *table;
- GtkWidget *toolbar;
- GtkWidget *handlebox;
- GtkWidget *statusbar;
- GtkWidget *contents;
- GtkWidget *sw;
- GtkTextBuffer *buffer;
- GtkAccelGroup *accel_group;
- GtkItemFactory *item_factory;
-
- /* Create the toplevel window
- */
-
- ++window_count;
-
- aspect_on = FALSE;
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title (GTK_WINDOW (window), "Application Window");
-
- g_signal_connect (G_OBJECT (window), "destroy",
- G_CALLBACK (destroy_cb), NULL);
-
- table = gtk_table_new (1, 4, FALSE);
-
- gtk_container_add (GTK_CONTAINER (window), table);
-
- /* Create the menubar
- */
-
- accel_group = gtk_accel_group_new ();
- gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
- g_object_unref (accel_group);
-
- item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", accel_group);
-
- /* Set up item factory to go away with the window */
- g_object_ref (item_factory);
- gtk_object_sink (GTK_OBJECT (item_factory));
- g_object_set_data_full (G_OBJECT (window),
- "<main>",
- item_factory,
- (GDestroyNotify) g_object_unref);
-
- /* create menu items */
- gtk_item_factory_create_items (item_factory, G_N_ELEMENTS (menu_items),
- menu_items, window);
-
- gtk_table_attach (GTK_TABLE (table),
- gtk_item_factory_get_widget (item_factory, "<main>"),
- /* X direction */ /* Y direction */
- 0, 1, 0, 1,
- GTK_EXPAND | GTK_FILL, 0,
- 0, 0);
-
- /* Create document
- */
-
- sw = gtk_scrolled_window_new (NULL, NULL);
-
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
-
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
- GTK_SHADOW_IN);
-
- gtk_table_attach (GTK_TABLE (table),
- sw,
- /* X direction */ /* Y direction */
- 0, 1, 2, 3,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
- 0, 0);
-
- gtk_window_set_default_size (GTK_WINDOW (window),
- 200, 200);
-
- contents = gtk_text_view_new ();
- gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (contents),
- PANGO_WRAP_WORD);
-
- gtk_container_add (GTK_CONTAINER (sw),
- contents);
-
- /* Create the toolbar
- */
- toolbar = gtk_toolbar_new ();
-
- gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
- GTK_STOCK_NEW,
- "Open another one of these windows",
- NULL,
- G_CALLBACK (do_appwindow),
- window, /* user data for callback */
- -1); /* -1 means "append" */
-
- gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
- GTK_STOCK_OPEN,
- "This is a demo button that locks up the demo",
- NULL,
- G_CALLBACK (sleep_cb),
- window, /* user data for callback */
- -1); /* -1 means "append" */
-
- gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
- GTK_STOCK_OPEN,
- "This is a demo button that toggles window decorations",
- NULL,
- G_CALLBACK (toggle_decorated_cb),
- window, /* user data for callback */
- -1); /* -1 means "append" */
-
- gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
- GTK_STOCK_OPEN,
- "This is a demo button that locks the aspect ratio using a hint",
- NULL,
- G_CALLBACK (toggle_aspect_ratio),
- contents, /* user data for callback */
- -1); /* -1 means "append" */
-
- gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
- GTK_STOCK_QUIT,
- "This is a demo button with a 'quit' icon",
- NULL,
- G_CALLBACK (clicked_toolbar_cb),
- window, /* user data for callback */
- -1); /* -1 means "append" */
-
- handlebox = gtk_handle_box_new ();
-
- gtk_container_add (GTK_CONTAINER (handlebox), toolbar);
-
- gtk_table_attach (GTK_TABLE (table),
- handlebox,
- /* X direction */ /* Y direction */
- 0, 1, 1, 2,
- GTK_EXPAND | GTK_FILL, 0,
- 0, 0);
-
- /* Create statusbar */
-
- statusbar = gtk_statusbar_new ();
- gtk_table_attach (GTK_TABLE (table),
- statusbar,
- /* X direction */ /* Y direction */
- 0, 1, 3, 4,
- GTK_EXPAND | GTK_FILL, 0,
- 0, 0);
-
- /* Show text widget info in the statusbar */
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (contents));
-
- gtk_text_buffer_set_text (buffer,
- "This demo demonstrates various kinds of windows that "
- "window managers and window manager themes should handle. "
- "Be sure to tear off the menu and toolbar, those are also "
- "a special kind of window.",
- -1);
-
- g_signal_connect_object (buffer,
- "changed",
- G_CALLBACK (update_statusbar),
- statusbar,
- 0);
-
- g_signal_connect_object (buffer,
- "mark_set", /* cursor moved */
- G_CALLBACK (mark_set_callback),
- statusbar,
- 0);
-
- update_statusbar (buffer, GTK_STATUSBAR (statusbar));
-
- gtk_widget_show_all (window);
-
- return window;
-}
-
-
diff --git a/src/tools/metacity-window-demo.png b/src/tools/metacity-window-demo.png
deleted file mode 100644
index d87f8296..00000000
--- a/src/tools/metacity-window-demo.png
+++ /dev/null
Binary files differ
diff --git a/src/ui/draw-workspace.c b/src/ui/draw-workspace.c
deleted file mode 100644
index f7c98b68..00000000
--- a/src/ui/draw-workspace.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Draw a workspace */
-
-/* This file should not be modified to depend on other files in
- * libwnck or metacity, since it's used in both of them
- */
-
-/*
- * Copyright (C) 2002 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "draw-workspace.h"
-
-
-static void
-get_window_rect (const WnckWindowDisplayInfo *win,
- int screen_width,
- int screen_height,
- const GdkRectangle *workspace_rect,
- GdkRectangle *rect)
-{
- double width_ratio, height_ratio;
- int x, y, width, height;
-
- width_ratio = (double) workspace_rect->width / (double) screen_width;
- height_ratio = (double) workspace_rect->height / (double) screen_height;
-
- x = win->x;
- y = win->y;
- width = win->width;
- height = win->height;
-
- x *= width_ratio;
- y *= height_ratio;
- width *= width_ratio;
- height *= height_ratio;
-
- x += workspace_rect->x;
- y += workspace_rect->y;
-
- if (width < 3)
- width = 3;
- if (height < 3)
- height = 3;
-
- rect->x = x;
- rect->y = y;
- rect->width = width;
- rect->height = height;
-}
-
-static void
-draw_window (GtkWidget *widget,
- GdkDrawable *drawable,
- const WnckWindowDisplayInfo *win,
- const GdkRectangle *winrect,
- GtkStateType state)
-{
- cairo_t *cr;
- GdkPixbuf *icon;
- int icon_x, icon_y, icon_w, icon_h;
- gboolean is_active;
- GdkColor *color;
-
- is_active = win->is_active;
-
- cr = gdk_cairo_create (drawable);
- cairo_rectangle (cr, winrect->x, winrect->y, winrect->width, winrect->height);
- cairo_clip (cr);
-
- if (is_active)
- color = &widget->style->light[state];
- else
- color = &widget->style->bg[state];
- cairo_set_source_rgb (cr,
- color->red / 65535.,
- color->green / 65535.,
- color->blue / 65535.);
-
- cairo_rectangle (cr,
- winrect->x + 1, winrect->y + 1,
- MAX (0, winrect->width - 2), MAX (0, winrect->height - 2));
- cairo_fill (cr);
-
-
- icon = win->icon;
-
- icon_w = icon_h = 0;
-
- if (icon)
- {
- icon_w = gdk_pixbuf_get_width (icon);
- icon_h = gdk_pixbuf_get_height (icon);
-
- /* If the icon is too big, fall back to mini icon.
- * We don't arbitrarily scale the icon, because it's
- * just too slow on my Athlon 850.
- */
- if (icon_w > (winrect->width - 2) ||
- icon_h > (winrect->height - 2))
- {
- icon = win->mini_icon;
- if (icon)
- {
- icon_w = gdk_pixbuf_get_width (icon);
- icon_h = gdk_pixbuf_get_height (icon);
-
- /* Give up. */
- if (icon_w > (winrect->width - 2) ||
- icon_h > (winrect->height - 2))
- icon = NULL;
- }
- }
- }
-
- if (icon)
- {
- icon_x = winrect->x + (winrect->width - icon_w) / 2;
- icon_y = winrect->y + (winrect->height - icon_h) / 2;
-
- cairo_save (cr);
- gdk_cairo_set_source_pixbuf (cr, icon, icon_x, icon_y);
- cairo_rectangle (cr, icon_x, icon_y, icon_w, icon_h);
- cairo_clip (cr);
- cairo_paint (cr);
- cairo_restore (cr);
- }
-
- if (is_active)
- color = &widget->style->fg[state];
- else
- color = &widget->style->fg[state];
-
- cairo_set_source_rgb (cr,
- color->red / 65535.,
- color->green / 65535.,
- color->blue / 65535.);
- cairo_set_line_width (cr, 1.0);
- cairo_rectangle (cr,
- winrect->x + 0.5, winrect->y + 0.5,
- MAX (0, winrect->width - 1), MAX (0, winrect->height - 1));
- cairo_stroke (cr);
-
- cairo_destroy (cr);
-}
-
-void
-wnck_draw_workspace (GtkWidget *widget,
- GdkDrawable *drawable,
- int x,
- int y,
- int width,
- int height,
- int screen_width,
- int screen_height,
- GdkPixbuf *workspace_background,
- gboolean is_active,
- const WnckWindowDisplayInfo *windows,
- int n_windows)
-{
- int i;
- GdkRectangle workspace_rect;
- GtkStateType state;
-
- workspace_rect.x = x;
- workspace_rect.y = y;
- workspace_rect.width = width;
- workspace_rect.height = height;
-
- if (is_active)
- state = GTK_STATE_SELECTED;
- else if (workspace_background)
- state = GTK_STATE_PRELIGHT;
- else
- state = GTK_STATE_NORMAL;
-
- if (workspace_background)
- {
- gdk_draw_pixbuf (drawable,
- GTK_WIDGET (widget)->style->dark_gc[state],
- workspace_background,
- 0, 0,
- x, y,
- -1, -1,
- GDK_RGB_DITHER_MAX,
- 0, 0);
- }
- else
- {
- cairo_t *cr;
-
- cr = gdk_cairo_create (widget->window);
- gdk_cairo_set_source_color (cr, &widget->style->dark[state]);
- cairo_rectangle (cr, x, y, width, height);
- cairo_fill (cr);
- cairo_destroy (cr);
- }
-
- i = 0;
- while (i < n_windows)
- {
- const WnckWindowDisplayInfo *win = &windows[i];
- GdkRectangle winrect;
-
- get_window_rect (win, screen_width,
- screen_height, &workspace_rect, &winrect);
-
- draw_window (widget,
- drawable,
- win,
- &winrect,
- state);
-
- ++i;
- }
-}
diff --git a/src/ui/draw-workspace.h b/src/ui/draw-workspace.h
deleted file mode 100644
index 10018aa8..00000000
--- a/src/ui/draw-workspace.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Draw a workspace */
-
-/* This file should not be modified to depend on other files in
- * libwnck or metacity, since it's used in both of them
- */
-
-/*
- * Copyright (C) 2002 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef WNCK_DRAW_WORKSPACE_H
-#define WNCK_DRAW_WORKSPACE_H
-
-#include <gdk/gdk.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <gtk/gtk.h>
-
-typedef struct
-{
- GdkPixbuf *icon;
- GdkPixbuf *mini_icon;
- int x;
- int y;
- int width;
- int height;
-
- guint is_active : 1;
-
-} WnckWindowDisplayInfo;
-
-void wnck_draw_workspace (GtkWidget *widget,
- GdkDrawable *drawable,
- int x,
- int y,
- int width,
- int height,
- int screen_width,
- int screen_height,
- GdkPixbuf *workspace_background,
- gboolean is_active,
- const WnckWindowDisplayInfo *windows,
- int n_windows);
-
-#endif
diff --git a/src/ui/fixedtip.c b/src/ui/fixedtip.c
deleted file mode 100644
index b4c5203c..00000000
--- a/src/ui/fixedtip.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity fixed tooltip routine */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include "fixedtip.h"
-#include "ui.h"
-
-/**
- * The floating rectangle. This is a GtkWindow, and it contains
- * the "label" widget, below.
- */
-static GtkWidget *tip = NULL;
-
-/**
- * The actual text that gets displayed.
- */
-static GtkWidget *label = NULL;
-/*
- * X coordinate of the right-hand edge of the screen.
- *
- * \bug This appears to be a bug; screen_right_edge is calculated only when
- * the window is redrawn. Actually we should never cache it because
- * different windows are different sizes.
- */
-static int screen_right_edge = 0;
-/*
- * Y coordinate of the bottom edge of the screen.
- *
- * \bug As with screen_right_edge.
- */
-static int screen_bottom_edge = 0;
-
-static gint
-expose_handler (GtkTooltips *tooltips)
-{
- gtk_paint_flat_box (tip->style, tip->window,
- GTK_STATE_NORMAL, GTK_SHADOW_OUT,
- NULL, tip, "tooltip",
- 0, 0, -1, -1);
-
- return FALSE;
-}
-
-void
-meta_fixed_tip_show (Display *xdisplay, int screen_number,
- int root_x, int root_y,
- const char *markup_text)
-{
- int w, h;
-
- if (tip == NULL)
- {
- tip = gtk_window_new (GTK_WINDOW_POPUP);
- {
- GdkScreen *gdk_screen;
- GdkRectangle monitor;
- gint mon_num;
-
- gdk_screen = gdk_display_get_screen (gdk_display_get_default (),
- screen_number);
- gtk_window_set_screen (GTK_WINDOW (tip),
- gdk_screen);
- mon_num = gdk_screen_get_monitor_at_point (gdk_screen, root_x, root_y);
- gdk_screen_get_monitor_geometry (gdk_screen, mon_num, &monitor);
- screen_right_edge = monitor.x + monitor.width;
- screen_bottom_edge = monitor.y + monitor.height;
- }
-
- gtk_widget_set_app_paintable (tip, TRUE);
- gtk_window_set_policy (GTK_WINDOW (tip), FALSE, FALSE, TRUE);
- gtk_widget_set_name (tip, "gtk-tooltips");
- gtk_container_set_border_width (GTK_CONTAINER (tip), 4);
-
- g_signal_connect_swapped (tip, "expose_event",
- G_CALLBACK (expose_handler), NULL);
-
- label = gtk_label_new (NULL);
- gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
- gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5);
- gtk_widget_show (label);
-
- gtk_container_add (GTK_CONTAINER (tip), label);
-
- g_signal_connect (tip, "destroy",
- G_CALLBACK (gtk_widget_destroyed), &tip);
- }
-
- gtk_label_set_markup (GTK_LABEL (label), markup_text);
-
- gtk_window_get_size (GTK_WINDOW (tip), &w, &h);
-
- if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
- root_x = MAX(0, root_x - w);
-
- if ((root_x + w) > screen_right_edge)
- root_x -= (root_x + w) - screen_right_edge;
-
- gtk_window_move (GTK_WINDOW (tip), root_x, root_y);
-
- gtk_widget_show (tip);
-}
-
-void
-meta_fixed_tip_hide (void)
-{
- if (tip)
- {
- gtk_widget_destroy (tip);
- tip = NULL;
- }
-}
diff --git a/src/ui/fixedtip.h b/src/ui/fixedtip.h
deleted file mode 100644
index c196389d..00000000
--- a/src/ui/fixedtip.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-/**
- * \file fixedtip.h Metacity fixed tooltip routine
- *
- * Sometimes we want to display a small floating rectangle with helpful
- * text near the pointer. For example, if the user holds the mouse over
- * the maximise button, we can display a tooltip saying "Maximize".
- * The text is localised, of course.
- *
- * This file contains the functions to create and delete these tooltips.
- *
- * \todo Since we now consider MetaDisplay a singleton, there can be
- * only one tooltip per display; this might quite simply live in
- * display.c. Alternatively, it could move to frames.c, which
- * is the only place this business is called anyway.
- *
- * \todo Apparently some UI needs changing (check bugzilla)
- */
-
-#ifndef META_FIXED_TIP_H
-#define META_FIXED_TIP_H
-
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
-
-/**
- * Displays a tooltip. There can be only one across the entire system.
- * This function behaves identically whether or not a tooltip is already
- * displayed, but if it is the window will be reused rather than destroyed
- * and recreated.
- *
- * \param xdisplay An X display.
- * \param screen_number The number of the screen.
- * \param root_x The X coordinate where the tooltip should appear
- * \param root_y The Y coordinate where the tooltip should appear
- * \param markup_text Text to display in the tooltip; can contain markup
- */
-void meta_fixed_tip_show (Display *xdisplay, int screen_number,
- int root_x, int root_y,
- const char *markup_text);
-
-/**
- * Removes the tooltip that was created by meta_fixed_tip_show(). If there
- * is no tooltip currently visible, this is a no-op.
- */
-void meta_fixed_tip_hide (void);
-
-
-#endif
diff --git a/src/ui/frames.c b/src/ui/frames.c
deleted file mode 100644
index f4761d2a..00000000
--- a/src/ui/frames.c
+++ /dev/null
@@ -1,2848 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity window frame manager widget */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2003 Red Hat, Inc.
- * Copyright (C) 2005, 2006 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include <math.h>
-#include "boxes.h"
-#include "frames.h"
-#include "util.h"
-#include "core.h"
-#include "menu.h"
-#include "fixedtip.h"
-#include "theme.h"
-#include "prefs.h"
-#include "ui.h"
-
-#ifdef HAVE_SHAPE
-#include <X11/extensions/shape.h>
-#endif
-
-#define DEFAULT_INNER_BUTTON_BORDER 3
-
-static void meta_frames_class_init (MetaFramesClass *klass);
-static void meta_frames_init (MetaFrames *frames);
-static void meta_frames_destroy (GtkObject *object);
-static void meta_frames_finalize (GObject *object);
-static void meta_frames_style_set (GtkWidget *widget,
- GtkStyle *prev_style);
-static void meta_frames_realize (GtkWidget *widget);
-static void meta_frames_unrealize (GtkWidget *widget);
-
-static void meta_frames_update_prelit_control (MetaFrames *frames,
- MetaUIFrame *frame,
- MetaFrameControl control);
-static gboolean meta_frames_button_press_event (GtkWidget *widget,
- GdkEventButton *event);
-static gboolean meta_frames_button_release_event (GtkWidget *widget,
- GdkEventButton *event);
-static gboolean meta_frames_motion_notify_event (GtkWidget *widget,
- GdkEventMotion *event);
-static gboolean meta_frames_destroy_event (GtkWidget *widget,
- GdkEventAny *event);
-static gboolean meta_frames_expose_event (GtkWidget *widget,
- GdkEventExpose *event);
-static gboolean meta_frames_enter_notify_event (GtkWidget *widget,
- GdkEventCrossing *event);
-static gboolean meta_frames_leave_notify_event (GtkWidget *widget,
- GdkEventCrossing *event);
-
-static void meta_frames_paint_to_drawable (MetaFrames *frames,
- MetaUIFrame *frame,
- GdkDrawable *drawable,
- GdkRegion *region,
- int x_offset,
- int y_offset);
-
-static void meta_frames_set_window_background (MetaFrames *frames,
- MetaUIFrame *frame);
-
-static void meta_frames_calc_geometry (MetaFrames *frames,
- MetaUIFrame *frame,
- MetaFrameGeometry *fgeom);
-
-static void meta_frames_ensure_layout (MetaFrames *frames,
- MetaUIFrame *frame);
-
-static MetaUIFrame* meta_frames_lookup_window (MetaFrames *frames,
- Window xwindow);
-
-static void meta_frames_font_changed (MetaFrames *frames);
-static void meta_frames_button_layout_changed (MetaFrames *frames);
-
-
-static GdkRectangle* control_rect (MetaFrameControl control,
- MetaFrameGeometry *fgeom);
-static MetaFrameControl get_control (MetaFrames *frames,
- MetaUIFrame *frame,
- int x,
- int y);
-static void clear_tip (MetaFrames *frames);
-static void invalidate_all_caches (MetaFrames *frames);
-static void invalidate_whole_window (MetaFrames *frames,
- MetaUIFrame *frame);
-
-static GtkWidgetClass *parent_class = NULL;
-
-GtkType
-meta_frames_get_type (void)
-{
- static GtkType frames_type = 0;
-
- if (!frames_type)
- {
- static const GtkTypeInfo frames_info =
- {
- "MetaFrames",
- sizeof (MetaFrames),
- sizeof (MetaFramesClass),
- (GtkClassInitFunc) meta_frames_class_init,
- (GtkObjectInitFunc) meta_frames_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- frames_type = gtk_type_unique (GTK_TYPE_WINDOW, &frames_info);
- }
-
- return frames_type;
-}
-
-static void
-meta_frames_class_init (MetaFramesClass *class)
-{
- GObjectClass *gobject_class;
- GtkObjectClass *object_class;
- GtkWidgetClass *widget_class;
-
- gobject_class = G_OBJECT_CLASS (class);
- object_class = (GtkObjectClass*) class;
- widget_class = (GtkWidgetClass*) class;
-
- parent_class = g_type_class_peek_parent (class);
-
- gobject_class->finalize = meta_frames_finalize;
- object_class->destroy = meta_frames_destroy;
-
- widget_class->style_set = meta_frames_style_set;
-
- widget_class->realize = meta_frames_realize;
- widget_class->unrealize = meta_frames_unrealize;
-
- widget_class->expose_event = meta_frames_expose_event;
- widget_class->destroy_event = meta_frames_destroy_event;
- widget_class->button_press_event = meta_frames_button_press_event;
- widget_class->button_release_event = meta_frames_button_release_event;
- widget_class->motion_notify_event = meta_frames_motion_notify_event;
- widget_class->enter_notify_event = meta_frames_enter_notify_event;
- widget_class->leave_notify_event = meta_frames_leave_notify_event;
-}
-
-static gint
-unsigned_long_equal (gconstpointer v1,
- gconstpointer v2)
-{
- return *((const gulong*) v1) == *((const gulong*) v2);
-}
-
-static guint
-unsigned_long_hash (gconstpointer v)
-{
- gulong val = * (const gulong *) v;
-
- /* I'm not sure this works so well. */
-#if GLIB_SIZEOF_LONG > 4
- return (guint) (val ^ (val >> 32));
-#else
- return val;
-#endif
-}
-
-static void
-prefs_changed_callback (MetaPreference pref,
- void *data)
-{
- switch (pref)
- {
- case META_PREF_TITLEBAR_FONT:
- meta_frames_font_changed (META_FRAMES (data));
- break;
- case META_PREF_BUTTON_LAYOUT:
- meta_frames_button_layout_changed (META_FRAMES (data));
- break;
- default:
- break;
- }
-}
-
-static void
-meta_frames_init (MetaFrames *frames)
-{
- GTK_WINDOW (frames)->type = GTK_WINDOW_POPUP;
-
- frames->text_heights = g_hash_table_new (NULL, NULL);
-
- frames->frames = g_hash_table_new (unsigned_long_hash, unsigned_long_equal);
-
- frames->tooltip_timeout = 0;
-
- frames->expose_delay_count = 0;
-
- frames->invalidate_cache_timeout_id = 0;
- frames->invalidate_frames = NULL;
- frames->cache = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- gtk_widget_set_double_buffered (GTK_WIDGET (frames), FALSE);
-
- meta_prefs_add_listener (prefs_changed_callback, frames);
-}
-
-static void
-listify_func (gpointer key, gpointer value, gpointer data)
-{
- GSList **listp;
-
- listp = data;
- *listp = g_slist_prepend (*listp, value);
-}
-
-static void
-meta_frames_destroy (GtkObject *object)
-{
- GSList *winlist;
- GSList *tmp;
- MetaFrames *frames;
-
- frames = META_FRAMES (object);
-
- clear_tip (frames);
-
- winlist = NULL;
- g_hash_table_foreach (frames->frames, listify_func, &winlist);
-
- /* Unmanage all frames */
- for (tmp = winlist; tmp != NULL; tmp = tmp->next)
- {
- MetaUIFrame *frame;
-
- frame = tmp->data;
-
- meta_frames_unmanage_window (frames, frame->xwindow);
- }
- g_slist_free (winlist);
-
- GTK_OBJECT_CLASS (parent_class)->destroy (object);
-}
-
-static void
-meta_frames_finalize (GObject *object)
-{
- MetaFrames *frames;
-
- frames = META_FRAMES (object);
-
- meta_prefs_remove_listener (prefs_changed_callback, frames);
-
- g_hash_table_destroy (frames->text_heights);
-
- invalidate_all_caches (frames);
- if (frames->invalidate_cache_timeout_id)
- g_source_remove (frames->invalidate_cache_timeout_id);
-
- g_assert (g_hash_table_size (frames->frames) == 0);
- g_hash_table_destroy (frames->frames);
- g_hash_table_destroy (frames->cache);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-typedef struct
-{
- MetaRectangle rect;
- GdkPixmap *pixmap;
-} CachedFramePiece;
-
-typedef struct
-{
- /* Caches of the four rendered sides in a MetaFrame.
- * Order: top (titlebar), left, right, bottom.
- */
- CachedFramePiece piece[4];
-} CachedPixels;
-
-static CachedPixels *
-get_cache (MetaFrames *frames,
- MetaUIFrame *frame)
-{
- CachedPixels *pixels;
-
- pixels = g_hash_table_lookup (frames->cache, frame);
-
- if (!pixels)
- {
- pixels = g_new0 (CachedPixels, 1);
- g_hash_table_insert (frames->cache, frame, pixels);
- }
-
- return pixels;
-}
-
-static void
-invalidate_cache (MetaFrames *frames,
- MetaUIFrame *frame)
-{
- CachedPixels *pixels = get_cache (frames, frame);
- int i;
-
- for (i = 0; i < 4; i++)
- if (pixels->piece[i].pixmap)
- g_object_unref (pixels->piece[i].pixmap);
-
- g_free (pixels);
- g_hash_table_remove (frames->cache, frame);
-}
-
-static void
-invalidate_all_caches (MetaFrames *frames)
-{
- GList *l;
-
- for (l = frames->invalidate_frames; l; l = l->next)
- {
- MetaUIFrame *frame = l->data;
-
- invalidate_cache (frames, frame);
- }
-
- g_list_free (frames->invalidate_frames);
- frames->invalidate_frames = NULL;
-}
-
-static gboolean
-invalidate_cache_timeout (gpointer data)
-{
- MetaFrames *frames = data;
-
- invalidate_all_caches (frames);
- frames->invalidate_cache_timeout_id = 0;
- return FALSE;
-}
-
-static void
-queue_recalc_func (gpointer key, gpointer value, gpointer data)
-{
- MetaUIFrame *frame;
- MetaFrames *frames;
-
- frames = META_FRAMES (data);
- frame = value;
-
- /* If a resize occurs it will cause a redraw, but the
- * resize may not actually be needed so we always redraw
- * in case of color change.
- */
- meta_frames_set_window_background (frames, frame);
-
- invalidate_whole_window (frames, frame);
- meta_core_queue_frame_resize (gdk_display,
- frame->xwindow);
- if (frame->layout)
- {
- /* save title to recreate layout */
- g_free (frame->title);
-
- frame->title = g_strdup (pango_layout_get_text (frame->layout));
-
- g_object_unref (G_OBJECT (frame->layout));
- frame->layout = NULL;
- }
-}
-
-static void
-meta_frames_font_changed (MetaFrames *frames)
-{
- if (g_hash_table_size (frames->text_heights) > 0)
- {
- g_hash_table_destroy (frames->text_heights);
- frames->text_heights = g_hash_table_new (NULL, NULL);
- }
-
- /* Queue a draw/resize on all frames */
- g_hash_table_foreach (frames->frames,
- queue_recalc_func, frames);
-
-}
-
-static void
-queue_draw_func (gpointer key, gpointer value, gpointer data)
-{
- MetaUIFrame *frame;
- MetaFrames *frames;
-
- frames = META_FRAMES (data);
- frame = value;
-
- /* If a resize occurs it will cause a redraw, but the
- * resize may not actually be needed so we always redraw
- * in case of color change.
- */
- meta_frames_set_window_background (frames, frame);
-
- invalidate_whole_window (frames, frame);
-}
-
-static void
-meta_frames_button_layout_changed (MetaFrames *frames)
-{
- g_hash_table_foreach (frames->frames,
- queue_draw_func, frames);
-}
-
-static void
-meta_frames_style_set (GtkWidget *widget,
- GtkStyle *prev_style)
-{
- MetaFrames *frames;
-
- frames = META_FRAMES (widget);
-
- meta_frames_font_changed (frames);
-
- GTK_WIDGET_CLASS (parent_class)->style_set (widget, prev_style);
-}
-
-static void
-meta_frames_ensure_layout (MetaFrames *frames,
- MetaUIFrame *frame)
-{
- GtkWidget *widget;
- MetaFrameFlags flags;
- MetaFrameType type;
- MetaFrameStyle *style;
-
- g_return_if_fail (GTK_WIDGET_REALIZED (frames));
-
- widget = GTK_WIDGET (frames);
-
- meta_core_get (gdk_display, frame->xwindow,
- META_CORE_GET_FRAME_FLAGS, &flags,
- META_CORE_GET_FRAME_TYPE, &type,
- META_CORE_GET_END);
-
- style = meta_theme_get_frame_style (meta_theme_get_current (),
- type, flags);
-
- if (style != frame->cache_style)
- {
- if (frame->layout)
- {
- /* save title to recreate layout */
- g_free (frame->title);
-
- frame->title = g_strdup (pango_layout_get_text (frame->layout));
-
- g_object_unref (G_OBJECT (frame->layout));
- frame->layout = NULL;
- }
- }
-
- frame->cache_style = style;
-
- if (frame->layout == NULL)
- {
- gpointer key, value;
- PangoFontDescription *font_desc;
- double scale;
- int size;
-
- scale = meta_theme_get_title_scale (meta_theme_get_current (),
- type,
- flags);
-
- frame->layout = gtk_widget_create_pango_layout (widget, frame->title);
-
- pango_layout_set_auto_dir (frame->layout, FALSE);
-
- font_desc = meta_gtk_widget_get_font_desc (widget, scale,
- meta_prefs_get_titlebar_font ());
-
- size = pango_font_description_get_size (font_desc);
-
- if (g_hash_table_lookup_extended (frames->text_heights,
- GINT_TO_POINTER (size),
- &key, &value))
- {
- frame->text_height = GPOINTER_TO_INT (value);
- }
- else
- {
- frame->text_height =
- meta_pango_font_desc_get_text_height (font_desc,
- gtk_widget_get_pango_context (widget));
-
- g_hash_table_replace (frames->text_heights,
- GINT_TO_POINTER (size),
- GINT_TO_POINTER (frame->text_height));
- }
-
- pango_layout_set_font_description (frame->layout,
- font_desc);
-
- pango_font_description_free (font_desc);
-
- /* Save some RAM */
- g_free (frame->title);
- frame->title = NULL;
- }
-}
-
-static void
-meta_frames_calc_geometry (MetaFrames *frames,
- MetaUIFrame *frame,
- MetaFrameGeometry *fgeom)
-{
- int width, height;
- MetaFrameFlags flags;
- MetaFrameType type;
- MetaButtonLayout button_layout;
-
- meta_core_get (gdk_display, frame->xwindow,
- META_CORE_GET_CLIENT_WIDTH, &width,
- META_CORE_GET_CLIENT_HEIGHT, &height,
- META_CORE_GET_FRAME_FLAGS, &flags,
- META_CORE_GET_FRAME_TYPE, &type,
- META_CORE_GET_END);
-
- meta_frames_ensure_layout (frames, frame);
-
- meta_prefs_get_button_layout (&button_layout);
-
- meta_theme_calc_geometry (meta_theme_get_current (),
- type,
- frame->text_height,
- flags,
- width, height,
- &button_layout,
- fgeom);
-}
-
-MetaFrames*
-meta_frames_new (int screen_number)
-{
- GdkScreen *screen;
-
- screen = gdk_display_get_screen (gdk_display_get_default (),
- screen_number);
-
- return g_object_new (META_TYPE_FRAMES,
- "screen", screen,
- NULL);
-}
-
-void
-meta_frames_manage_window (MetaFrames *frames,
- Window xwindow,
- GdkWindow *window)
-{
- MetaUIFrame *frame;
-
- g_assert (window);
-
- frame = g_new (MetaUIFrame, 1);
-
- frame->window = window;
-
- gdk_window_set_user_data (frame->window, frames);
-
- /* Don't set event mask here, it's in frame.c */
-
- frame->xwindow = xwindow;
- frame->cache_style = NULL;
- frame->layout = NULL;
- frame->text_height = -1;
- frame->title = NULL;
- frame->expose_delayed = FALSE;
- frame->shape_applied = FALSE;
- frame->prelit_control = META_FRAME_CONTROL_NONE;
-
- /* Don't set the window background yet; we need frame->xwindow to be
- * registered with its MetaWindow, which happens after this function
- * and meta_ui_create_frame_window() return to meta_window_ensure_frame().
- */
-
- meta_core_grab_buttons (gdk_display, frame->xwindow);
-
- g_hash_table_replace (frames->frames, &frame->xwindow, frame);
-}
-
-void
-meta_frames_unmanage_window (MetaFrames *frames,
- Window xwindow)
-{
- MetaUIFrame *frame;
-
- clear_tip (frames);
-
- frame = g_hash_table_lookup (frames->frames, &xwindow);
-
- if (frame)
- {
- /* invalidating all caches ensures the frame
- * is not actually referenced anymore
- */
- invalidate_all_caches (frames);
-
- /* restore the cursor */
- meta_core_set_screen_cursor (gdk_display,
- frame->xwindow,
- META_CURSOR_DEFAULT);
-
- gdk_window_set_user_data (frame->window, NULL);
-
- if (frames->last_motion_frame == frame)
- frames->last_motion_frame = NULL;
-
- g_hash_table_remove (frames->frames, &frame->xwindow);
-
- gdk_window_destroy (frame->window);
-
- if (frame->layout)
- g_object_unref (G_OBJECT (frame->layout));
-
- if (frame->title)
- g_free (frame->title);
-
- g_free (frame);
- }
- else
- meta_warning ("Frame 0x%lx not managed, can't unmanage\n", xwindow);
-}
-
-static void
-meta_frames_realize (GtkWidget *widget)
-{
- if (GTK_WIDGET_CLASS (parent_class)->realize)
- GTK_WIDGET_CLASS (parent_class)->realize (widget);
-}
-
-static void
-meta_frames_unrealize (GtkWidget *widget)
-{
- if (GTK_WIDGET_CLASS (parent_class)->unrealize)
- GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
-}
-
-static MetaUIFrame*
-meta_frames_lookup_window (MetaFrames *frames,
- Window xwindow)
-{
- MetaUIFrame *frame;
-
- frame = g_hash_table_lookup (frames->frames, &xwindow);
-
- return frame;
-}
-
-void
-meta_frames_get_geometry (MetaFrames *frames,
- Window xwindow,
- int *top_height, int *bottom_height,
- int *left_width, int *right_width)
-{
- MetaFrameFlags flags;
- MetaUIFrame *frame;
- MetaFrameType type;
-
- frame = meta_frames_lookup_window (frames, xwindow);
-
- if (frame == NULL)
- meta_bug ("No such frame 0x%lx\n", xwindow);
-
- meta_core_get (gdk_display, frame->xwindow,
- META_CORE_GET_FRAME_FLAGS, &flags,
- META_CORE_GET_FRAME_TYPE, &type,
- META_CORE_GET_END);
-
- g_return_if_fail (type < META_FRAME_TYPE_LAST);
-
- meta_frames_ensure_layout (frames, frame);
-
- /* We can't get the full geometry, because that depends on
- * the client window size and probably we're being called
- * by the core move/resize code to decide on the client
- * window size
- */
- meta_theme_get_frame_borders (meta_theme_get_current (),
- type,
- frame->text_height,
- flags,
- top_height, bottom_height,
- left_width, right_width);
-}
-
-void
-meta_frames_reset_bg (MetaFrames *frames,
- Window xwindow)
-{
- MetaUIFrame *frame;
-
- frame = meta_frames_lookup_window (frames, xwindow);
-
- meta_frames_set_window_background (frames, frame);
-}
-
-static void
-set_background_none (Display *xdisplay,
- Window xwindow)
-{
- XSetWindowAttributes attrs;
-
- attrs.background_pixmap = None;
- XChangeWindowAttributes (xdisplay, xwindow,
- CWBackPixmap, &attrs);
-}
-
-void
-meta_frames_unflicker_bg (MetaFrames *frames,
- Window xwindow,
- int target_width,
- int target_height)
-{
- MetaUIFrame *frame;
-
- frame = meta_frames_lookup_window (frames, xwindow);
- g_return_if_fail (frame != NULL);
-
-#if 0
- pixmap = gdk_pixmap_new (frame->window,
- width, height,
- -1);
-
- /* Oops, no way to get the background here */
-
- meta_frames_paint_to_drawable (frames, frame, pixmap);
-#endif
-
- set_background_none (gdk_display, frame->xwindow);
-}
-
-void
-meta_frames_apply_shapes (MetaFrames *frames,
- Window xwindow,
- int new_window_width,
- int new_window_height,
- gboolean window_has_shape)
-{
-#ifdef HAVE_SHAPE
- /* Apply shapes as if window had new_window_width, new_window_height */
- MetaUIFrame *frame;
- MetaFrameGeometry fgeom;
- XRectangle xrect;
- Region corners_xregion;
- Region window_xregion;
-
- frame = meta_frames_lookup_window (frames, xwindow);
- g_return_if_fail (frame != NULL);
-
- meta_frames_calc_geometry (frames, frame, &fgeom);
-
- if (!(fgeom.top_left_corner_rounded_radius != 0 ||
- fgeom.top_right_corner_rounded_radius != 0 ||
- fgeom.bottom_left_corner_rounded_radius != 0 ||
- fgeom.bottom_right_corner_rounded_radius != 0 ||
- window_has_shape))
- {
- if (frame->shape_applied)
- {
- meta_topic (META_DEBUG_SHAPES,
- "Unsetting shape mask on frame 0x%lx\n",
- frame->xwindow);
-
- XShapeCombineMask (gdk_display, frame->xwindow,
- ShapeBounding, 0, 0, None, ShapeSet);
- frame->shape_applied = FALSE;
- }
- else
- {
- meta_topic (META_DEBUG_SHAPES,
- "Frame 0x%lx still doesn't need a shape mask\n",
- frame->xwindow);
- }
-
- return; /* nothing to do */
- }
-
- corners_xregion = XCreateRegion ();
-
- if (fgeom.top_left_corner_rounded_radius != 0)
- {
- const int corner = fgeom.top_left_corner_rounded_radius;
- const float radius = sqrt(corner) + corner;
- int i;
-
- for (i=0; i<corner; i++)
- {
- const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
- xrect.x = 0;
- xrect.y = i;
- xrect.width = width;
- xrect.height = 1;
-
- XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
- }
- }
-
- if (fgeom.top_right_corner_rounded_radius != 0)
- {
- const int corner = fgeom.top_right_corner_rounded_radius;
- const float radius = sqrt(corner) + corner;
- int i;
-
- for (i=0; i<corner; i++)
- {
- const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
- xrect.x = new_window_width - width;
- xrect.y = i;
- xrect.width = width;
- xrect.height = 1;
-
- XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
- }
- }
-
- if (fgeom.bottom_left_corner_rounded_radius != 0)
- {
- const int corner = fgeom.bottom_left_corner_rounded_radius;
- const float radius = sqrt(corner) + corner;
- int i;
-
- for (i=0; i<corner; i++)
- {
- const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
- xrect.x = 0;
- xrect.y = new_window_height - i - 1;
- xrect.width = width;
- xrect.height = 1;
-
- XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
- }
- }
-
- if (fgeom.bottom_right_corner_rounded_radius != 0)
- {
- const int corner = fgeom.bottom_right_corner_rounded_radius;
- const float radius = sqrt(corner) + corner;
- int i;
-
- for (i=0; i<corner; i++)
- {
- const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
- xrect.x = new_window_width - width;
- xrect.y = new_window_height - i - 1;
- xrect.width = width;
- xrect.height = 1;
-
- XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
- }
- }
-
- window_xregion = XCreateRegion ();
-
- xrect.x = 0;
- xrect.y = 0;
- xrect.width = new_window_width;
- xrect.height = new_window_height;
-
- XUnionRectWithRegion (&xrect, window_xregion, window_xregion);
-
- XSubtractRegion (window_xregion, corners_xregion, window_xregion);
-
- XDestroyRegion (corners_xregion);
-
- if (window_has_shape)
- {
- /* The client window is oclock or something and has a shape
- * mask. To avoid a round trip to get its shape region, we
- * create a fake window that's never mapped, build up our shape
- * on that, then combine. Wasting the window is assumed cheaper
- * than a round trip, but who really knows for sure.
- */
- XSetWindowAttributes attrs;
- Window shape_window;
- Window client_window;
- Region client_xregion;
- GdkScreen *screen;
- int screen_number;
-
- meta_topic (META_DEBUG_SHAPES,
- "Frame 0x%lx needs to incorporate client shape\n",
- frame->xwindow);
-
- screen = gtk_widget_get_screen (GTK_WIDGET (frames));
- screen_number = gdk_x11_screen_get_screen_number (screen);
-
- attrs.override_redirect = True;
-
- shape_window = XCreateWindow (gdk_display,
- RootWindow (gdk_display, screen_number),
- -5000, -5000,
- new_window_width,
- new_window_height,
- 0,
- CopyFromParent,
- CopyFromParent,
- (Visual *)CopyFromParent,
- CWOverrideRedirect,
- &attrs);
-
- /* Copy the client's shape to the temporary shape_window */
- meta_core_get (gdk_display, frame->xwindow,
- META_CORE_GET_CLIENT_XWINDOW, &client_window,
- META_CORE_GET_END);
-
- XShapeCombineShape (gdk_display, shape_window, ShapeBounding,
- fgeom.left_width,
- fgeom.top_height,
- client_window,
- ShapeBounding,
- ShapeSet);
-
- /* Punch the client area out of the normal frame shape,
- * then union it with the shape_window's existing shape
- */
- client_xregion = XCreateRegion ();
-
- xrect.x = fgeom.left_width;
- xrect.y = fgeom.top_height;
- xrect.width = new_window_width - fgeom.right_width - xrect.x;
- xrect.height = new_window_height - fgeom.bottom_height - xrect.y;
-
- XUnionRectWithRegion (&xrect, client_xregion, client_xregion);
-
- XSubtractRegion (window_xregion, client_xregion, window_xregion);
-
- XDestroyRegion (client_xregion);
-
- XShapeCombineRegion (gdk_display, shape_window,
- ShapeBounding, 0, 0, window_xregion, ShapeUnion);
-
- /* Now copy shape_window shape to the real frame */
- XShapeCombineShape (gdk_display, frame->xwindow, ShapeBounding,
- 0, 0,
- shape_window,
- ShapeBounding,
- ShapeSet);
-
- XDestroyWindow (gdk_display, shape_window);
- }
- else
- {
- /* No shape on the client, so just do simple stuff */
-
- meta_topic (META_DEBUG_SHAPES,
- "Frame 0x%lx has shaped corners\n",
- frame->xwindow);
-
- XShapeCombineRegion (gdk_display, frame->xwindow,
- ShapeBounding, 0, 0, window_xregion, ShapeSet);
- }
-
- frame->shape_applied = TRUE;
-
- XDestroyRegion (window_xregion);
-#endif /* HAVE_SHAPE */
-}
-
-void
-meta_frames_move_resize_frame (MetaFrames *frames,
- Window xwindow,
- int x,
- int y,
- int width,
- int height)
-{
- MetaUIFrame *frame = meta_frames_lookup_window (frames, xwindow);
- int old_x, old_y, old_width, old_height;
-
- gdk_drawable_get_size (frame->window, &old_width, &old_height);
- gdk_window_get_position (frame->window, &old_x, &old_y);
-
- gdk_window_move_resize (frame->window, x, y, width, height);
-
- if (old_width != width || old_height != height)
- invalidate_whole_window (frames, frame);
-}
-
-void
-meta_frames_queue_draw (MetaFrames *frames,
- Window xwindow)
-{
- MetaUIFrame *frame;
-
- frame = meta_frames_lookup_window (frames, xwindow);
-
- invalidate_whole_window (frames, frame);
-}
-
-void
-meta_frames_set_title (MetaFrames *frames,
- Window xwindow,
- const char *title)
-{
- MetaUIFrame *frame;
-
- frame = meta_frames_lookup_window (frames, xwindow);
-
- g_assert (frame);
-
- g_free (frame->title);
- frame->title = g_strdup (title);
-
- if (frame->layout)
- {
- g_object_unref (frame->layout);
- frame->layout = NULL;
- }
-
- invalidate_whole_window (frames, frame);
-}
-
-void
-meta_frames_repaint_frame (MetaFrames *frames,
- Window xwindow)
-{
- MetaUIFrame *frame;
-
- frame = meta_frames_lookup_window (frames, xwindow);
-
- g_assert (frame);
-
- /* repaint everything, so the other frame don't
- * lag behind if they are exposed
- */
- gdk_window_process_all_updates ();
-}
-
-static void
-show_tip_now (MetaFrames *frames)
-{
- const char *tiptext;
- MetaUIFrame *frame;
- int x, y, root_x, root_y;
- Window root, child;
- guint mask;
- MetaFrameControl control;
-
- frame = frames->last_motion_frame;
- if (frame == NULL)
- return;
-
- XQueryPointer (gdk_display,
- frame->xwindow,
- &root, &child,
- &root_x, &root_y,
- &x, &y,
- &mask);
-
- control = get_control (frames, frame, x, y);
-
- tiptext = NULL;
- switch (control)
- {
- case META_FRAME_CONTROL_TITLE:
- break;
- case META_FRAME_CONTROL_DELETE:
- tiptext = _("Close Window");
- break;
- case META_FRAME_CONTROL_MENU:
- tiptext = _("Window Menu");
- break;
- case META_FRAME_CONTROL_MINIMIZE:
- tiptext = _("Minimize Window");
- break;
- case META_FRAME_CONTROL_MAXIMIZE:
- tiptext = _("Maximize Window");
- break;
- case META_FRAME_CONTROL_UNMAXIMIZE:
- tiptext = _("Restore Window");
- break;
- case META_FRAME_CONTROL_SHADE:
- tiptext = _("Roll Up Window");
- break;
- case META_FRAME_CONTROL_UNSHADE:
- tiptext = _("Unroll Window");
- break;
- case META_FRAME_CONTROL_ABOVE:
- tiptext = _("Keep Window On Top");
- break;
- case META_FRAME_CONTROL_UNABOVE:
- tiptext = _("Remove Window From Top");
- break;
- case META_FRAME_CONTROL_STICK:
- tiptext = _("Always On Visible Workspace");
- break;
- case META_FRAME_CONTROL_UNSTICK:
- tiptext = _("Put Window On Only One Workspace");
- break;
- case META_FRAME_CONTROL_RESIZE_SE:
- break;
- case META_FRAME_CONTROL_RESIZE_S:
- break;
- case META_FRAME_CONTROL_RESIZE_SW:
- break;
- case META_FRAME_CONTROL_RESIZE_N:
- break;
- case META_FRAME_CONTROL_RESIZE_NE:
- break;
- case META_FRAME_CONTROL_RESIZE_NW:
- break;
- case META_FRAME_CONTROL_RESIZE_W:
- break;
- case META_FRAME_CONTROL_RESIZE_E:
- break;
- case META_FRAME_CONTROL_NONE:
- break;
- case META_FRAME_CONTROL_CLIENT_AREA:
- break;
- }
-
- if (tiptext)
- {
- MetaFrameGeometry fgeom;
- GdkRectangle *rect;
- int dx, dy;
- int screen_number;
-
- meta_frames_calc_geometry (frames, frame, &fgeom);
-
- rect = control_rect (control, &fgeom);
-
- /* get conversion delta for root-to-frame coords */
- dx = root_x - x;
- dy = root_y - y;
-
- /* Align the tooltip to the button right end if RTL */
- if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
- dx += rect->width;
-
- screen_number = gdk_screen_get_number (gtk_widget_get_screen (GTK_WIDGET (frames)));
-
- meta_fixed_tip_show (gdk_display,
- screen_number,
- rect->x + dx,
- rect->y + rect->height + 2 + dy,
- tiptext);
- }
-}
-
-static gboolean
-tip_timeout_func (gpointer data)
-{
- MetaFrames *frames;
-
- frames = data;
-
- show_tip_now (frames);
-
- return FALSE;
-}
-
-#define TIP_DELAY 450
-static void
-queue_tip (MetaFrames *frames)
-{
- clear_tip (frames);
-
- frames->tooltip_timeout = g_timeout_add (TIP_DELAY,
- tip_timeout_func,
- frames);
-}
-
-static void
-clear_tip (MetaFrames *frames)
-{
- if (frames->tooltip_timeout)
- {
- g_source_remove (frames->tooltip_timeout);
- frames->tooltip_timeout = 0;
- }
- meta_fixed_tip_hide ();
-}
-
-static void
-redraw_control (MetaFrames *frames,
- MetaUIFrame *frame,
- MetaFrameControl control)
-{
- MetaFrameGeometry fgeom;
- GdkRectangle *rect;
-
- meta_frames_calc_geometry (frames, frame, &fgeom);
-
- rect = control_rect (control, &fgeom);
-
- gdk_window_invalidate_rect (frame->window, rect, FALSE);
- invalidate_cache (frames, frame);
-}
-
-static gboolean
-meta_frame_titlebar_event (MetaUIFrame *frame,
- GdkEventButton *event,
- int action)
-{
- MetaFrameFlags flags;
-
- switch (action)
- {
- case META_ACTION_TITLEBAR_TOGGLE_SHADE:
- {
- meta_core_get (gdk_display, frame->xwindow,
- META_CORE_GET_FRAME_FLAGS, &flags,
- META_CORE_GET_END);
-
- if (flags & META_FRAME_ALLOWS_SHADE)
- {
- if (flags & META_FRAME_SHADED)
- meta_core_unshade (gdk_display,
- frame->xwindow,
- event->time);
- else
- meta_core_shade (gdk_display,
- frame->xwindow,
- event->time);
- }
- }
- break;
-
- case META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE:
- {
- meta_core_get (gdk_display, frame->xwindow,
- META_CORE_GET_FRAME_FLAGS, &flags,
- META_CORE_GET_END);
-
- if (flags & META_FRAME_ALLOWS_MAXIMIZE)
- {
- meta_core_toggle_maximize (gdk_display, frame->xwindow);
- }
- }
- break;
-
- case META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE_HORIZONTALLY:
- {
- meta_core_get (gdk_display, frame->xwindow,
- META_CORE_GET_FRAME_FLAGS, &flags,
- META_CORE_GET_END);
-
- if (flags & META_FRAME_ALLOWS_MAXIMIZE)
- {
- meta_core_toggle_maximize_horizontally (gdk_display, frame->xwindow);
- }
- }
- break;
-
- case META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE_VERTICALLY:
- {
- meta_core_get (gdk_display, frame->xwindow,
- META_CORE_GET_FRAME_FLAGS, &flags,
- META_CORE_GET_END);
-
- if (flags & META_FRAME_ALLOWS_MAXIMIZE)
- {
- meta_core_toggle_maximize_vertically (gdk_display, frame->xwindow);
- }
- }
- break;
-
- case META_ACTION_TITLEBAR_MINIMIZE:
- {
- meta_core_get (gdk_display, frame->xwindow,
- META_CORE_GET_FRAME_FLAGS, &flags,
- META_CORE_GET_END);
-
- if (flags & META_FRAME_ALLOWS_MINIMIZE)
- {
- meta_core_minimize (gdk_display, frame->xwindow);
- }
- }
- break;
-
- case META_ACTION_TITLEBAR_NONE:
- /* Yaay, a sane user that doesn't use that other weird crap! */
- break;
-
- case META_ACTION_TITLEBAR_LOWER:
- meta_core_user_lower_and_unfocus (gdk_display,
- frame->xwindow,
- event->time);
- break;
-
- case META_ACTION_TITLEBAR_MENU:
- meta_core_show_window_menu (gdk_display,
- frame->xwindow,
- event->x_root,
- event->y_root,
- event->button,
- event->time);
- break;
-
- case META_ACTION_TITLEBAR_LAST:
- break;
- }
-
- return TRUE;
-}
-
-static gboolean
-meta_frame_double_click_event (MetaUIFrame *frame,
- GdkEventButton *event)
-{
- int action = meta_prefs_get_action_double_click_titlebar ();
-
- return meta_frame_titlebar_event (frame, event, action);
-}
-
-static gboolean
-meta_frame_middle_click_event (MetaUIFrame *frame,
- GdkEventButton *event)
-{
- int action = meta_prefs_get_action_middle_click_titlebar();
-
- return meta_frame_titlebar_event (frame, event, action);
-}
-
-static gboolean
-meta_frame_right_click_event(MetaUIFrame *frame,
- GdkEventButton *event)
-{
- int action = meta_prefs_get_action_right_click_titlebar();
-
- return meta_frame_titlebar_event (frame, event, action);
-}
-
-static gboolean
-meta_frames_button_press_event (GtkWidget *widget,
- GdkEventButton *event)
-{
- MetaUIFrame *frame;
- MetaFrames *frames;
- MetaFrameControl control;
-
- frames = META_FRAMES (widget);
-
- /* Remember that the display may have already done something with this event.
- * If so there's probably a GrabOp in effect.
- */
-
- frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
- if (frame == NULL)
- return FALSE;
-
- clear_tip (frames);
-
- control = get_control (frames, frame, event->x, event->y);
-
- /* focus on click, even if click was on client area */
- if (event->button == 1 &&
- !(control == META_FRAME_CONTROL_MINIMIZE ||
- control == META_FRAME_CONTROL_DELETE ||
- control == META_FRAME_CONTROL_MAXIMIZE))
- {
- meta_topic (META_DEBUG_FOCUS,
- "Focusing window with frame 0x%lx due to button 1 press\n",
- frame->xwindow);
- meta_core_user_focus (gdk_display,
- frame->xwindow,
- event->time);
- }
-
- /* don't do the rest of this if on client area */
- if (control == META_FRAME_CONTROL_CLIENT_AREA)
- return FALSE; /* not on the frame, just passed through from client */
-
- /* We want to shade even if we have a GrabOp, since we'll have a move grab
- * if we double click the titlebar.
- */
- if (control == META_FRAME_CONTROL_TITLE &&
- event->button == 1 &&
- event->type == GDK_2BUTTON_PRESS)
- {
- meta_core_end_grab_op (gdk_display, event->time);
- return meta_frame_double_click_event (frame, event);
- }
-
- if (meta_core_get_grab_op (gdk_display) !=
- META_GRAB_OP_NONE)
- return FALSE; /* already up to something */
-
- if (event->button == 1 &&
- (control == META_FRAME_CONTROL_MAXIMIZE ||
- control == META_FRAME_CONTROL_UNMAXIMIZE ||
- control == META_FRAME_CONTROL_MINIMIZE ||
- control == META_FRAME_CONTROL_DELETE ||
- control == META_FRAME_CONTROL_SHADE ||
- control == META_FRAME_CONTROL_UNSHADE ||
- control == META_FRAME_CONTROL_ABOVE ||
- control == META_FRAME_CONTROL_UNABOVE ||
- control == META_FRAME_CONTROL_STICK ||
- control == META_FRAME_CONTROL_UNSTICK ||
- control == META_FRAME_CONTROL_MENU))
- {
- MetaGrabOp op = META_GRAB_OP_NONE;
-
- switch (control)
- {
- case META_FRAME_CONTROL_MINIMIZE:
- op = META_GRAB_OP_CLICKING_MINIMIZE;
- break;
- case META_FRAME_CONTROL_MAXIMIZE:
- op = META_GRAB_OP_CLICKING_MAXIMIZE;
- break;
- case META_FRAME_CONTROL_UNMAXIMIZE:
- op = META_GRAB_OP_CLICKING_UNMAXIMIZE;
- break;
- case META_FRAME_CONTROL_DELETE:
- op = META_GRAB_OP_CLICKING_DELETE;
- break;
- case META_FRAME_CONTROL_MENU:
- op = META_GRAB_OP_CLICKING_MENU;
- break;
- case META_FRAME_CONTROL_SHADE:
- op = META_GRAB_OP_CLICKING_SHADE;
- break;
- case META_FRAME_CONTROL_UNSHADE:
- op = META_GRAB_OP_CLICKING_UNSHADE;
- break;
- case META_FRAME_CONTROL_ABOVE:
- op = META_GRAB_OP_CLICKING_ABOVE;
- break;
- case META_FRAME_CONTROL_UNABOVE:
- op = META_GRAB_OP_CLICKING_UNABOVE;
- break;
- case META_FRAME_CONTROL_STICK:
- op = META_GRAB_OP_CLICKING_STICK;
- break;
- case META_FRAME_CONTROL_UNSTICK:
- op = META_GRAB_OP_CLICKING_UNSTICK;
- break;
- default:
- g_assert_not_reached ();
- break;
- }
-
- meta_core_begin_grab_op (gdk_display,
- frame->xwindow,
- op,
- TRUE,
- TRUE,
- event->button,
- 0,
- event->time,
- event->x_root,
- event->y_root);
-
- frame->prelit_control = control;
- redraw_control (frames, frame, control);
-
- if (op == META_GRAB_OP_CLICKING_MENU)
- {
- MetaFrameGeometry fgeom;
- GdkRectangle *rect;
- int dx, dy;
-
- meta_frames_calc_geometry (frames, frame, &fgeom);
-
- rect = control_rect (META_FRAME_CONTROL_MENU, &fgeom);
-
- /* get delta to convert to root coords */
- dx = event->x_root - event->x;
- dy = event->y_root - event->y;
-
- /* Align to the right end of the menu rectangle if RTL */
- if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
- dx += rect->width;
-
- meta_core_show_window_menu (gdk_display,
- frame->xwindow,
- rect->x + dx,
- rect->y + rect->height + dy,
- event->button,
- event->time);
- }
- }
- else if (event->button == 1 &&
- (control == META_FRAME_CONTROL_RESIZE_SE ||
- control == META_FRAME_CONTROL_RESIZE_S ||
- control == META_FRAME_CONTROL_RESIZE_SW ||
- control == META_FRAME_CONTROL_RESIZE_NE ||
- control == META_FRAME_CONTROL_RESIZE_N ||
- control == META_FRAME_CONTROL_RESIZE_NW ||
- control == META_FRAME_CONTROL_RESIZE_E ||
- control == META_FRAME_CONTROL_RESIZE_W))
- {
- MetaGrabOp op;
- gboolean titlebar_is_onscreen;
-
- op = META_GRAB_OP_NONE;
-
- switch (control)
- {
- case META_FRAME_CONTROL_RESIZE_SE:
- op = META_GRAB_OP_RESIZING_SE;
- break;
- case META_FRAME_CONTROL_RESIZE_S:
- op = META_GRAB_OP_RESIZING_S;
- break;
- case META_FRAME_CONTROL_RESIZE_SW:
- op = META_GRAB_OP_RESIZING_SW;
- break;
- case META_FRAME_CONTROL_RESIZE_NE:
- op = META_GRAB_OP_RESIZING_NE;
- break;
- case META_FRAME_CONTROL_RESIZE_N:
- op = META_GRAB_OP_RESIZING_N;
- break;
- case META_FRAME_CONTROL_RESIZE_NW:
- op = META_GRAB_OP_RESIZING_NW;
- break;
- case META_FRAME_CONTROL_RESIZE_E:
- op = META_GRAB_OP_RESIZING_E;
- break;
- case META_FRAME_CONTROL_RESIZE_W:
- op = META_GRAB_OP_RESIZING_W;
- break;
- default:
- g_assert_not_reached ();
- break;
- }
-
- meta_core_get (gdk_display, frame->xwindow,
- META_CORE_IS_TITLEBAR_ONSCREEN, &titlebar_is_onscreen,
- META_CORE_GET_END);
-
- if (!titlebar_is_onscreen)
- meta_core_show_window_menu (gdk_display,
- frame->xwindow,
- event->x_root,
- event->y_root,
- event->button,
- event->time);
- else
- meta_core_begin_grab_op (gdk_display,
- frame->xwindow,
- op,
- TRUE,
- TRUE,
- event->button,
- 0,
- event->time,
- event->x_root,
- event->y_root);
- }
- else if (control == META_FRAME_CONTROL_TITLE &&
- event->button == 1)
- {
- MetaFrameFlags flags;
-
- meta_core_get (gdk_display, frame->xwindow,
- META_CORE_GET_FRAME_FLAGS, &flags,
- META_CORE_GET_END);
-
- if (flags & META_FRAME_ALLOWS_MOVE)
- {
- meta_core_begin_grab_op (gdk_display,
- frame->xwindow,
- META_GRAB_OP_MOVING,
- TRUE,
- TRUE,
- event->button,
- 0,
- event->time,
- event->x_root,
- event->y_root);
- }
- }
- else if (event->button == 2)
- {
- return meta_frame_middle_click_event (frame, event);
- }
- else if (event->button == 3)
- {
- return meta_frame_right_click_event (frame, event);
- }
-
- return TRUE;
-}
-
-void
-meta_frames_notify_menu_hide (MetaFrames *frames)
-{
- if (meta_core_get_grab_op (gdk_display) ==
- META_GRAB_OP_CLICKING_MENU)
- {
- Window grab_frame;
-
- grab_frame = meta_core_get_grab_frame (gdk_display);
-
- if (grab_frame != None)
- {
- MetaUIFrame *frame;
-
- frame = meta_frames_lookup_window (frames, grab_frame);
-
- if (frame)
- {
- redraw_control (frames, frame,
- META_FRAME_CONTROL_MENU);
- meta_core_end_grab_op (gdk_display, CurrentTime);
- }
- }
- }
-}
-
-static gboolean
-meta_frames_button_release_event (GtkWidget *widget,
- GdkEventButton *event)
-{
- MetaUIFrame *frame;
- MetaFrames *frames;
- MetaGrabOp op;
-
- frames = META_FRAMES (widget);
-
- frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
- if (frame == NULL)
- return FALSE;
-
- clear_tip (frames);
-
- op = meta_core_get_grab_op (gdk_display);
-
- if (op == META_GRAB_OP_NONE)
- return FALSE;
-
- /* We only handle the releases we handled the presses for (things
- * involving frame controls). Window ops that don't require a
- * frame are handled in the Xlib part of the code, display.c/window.c
- */
- if (frame->xwindow == meta_core_get_grab_frame (gdk_display) &&
- ((int) event->button) == meta_core_get_grab_button (gdk_display))
- {
- MetaFrameControl control;
-
- control = get_control (frames, frame, event->x, event->y);
-
- switch (op)
- {
- case META_GRAB_OP_CLICKING_MINIMIZE:
- if (control == META_FRAME_CONTROL_MINIMIZE)
- meta_core_minimize (gdk_display, frame->xwindow);
-
- meta_core_end_grab_op (gdk_display, event->time);
- break;
-
- case META_GRAB_OP_CLICKING_MAXIMIZE:
- if (control == META_FRAME_CONTROL_MAXIMIZE)
- {
- /* Focus the window on the maximize */
- meta_core_user_focus (gdk_display,
- frame->xwindow,
- event->time);
- meta_core_maximize (gdk_display, frame->xwindow);
- }
- meta_core_end_grab_op (gdk_display, event->time);
- break;
-
- case META_GRAB_OP_CLICKING_UNMAXIMIZE:
- if (control == META_FRAME_CONTROL_UNMAXIMIZE)
- meta_core_unmaximize (gdk_display, frame->xwindow);
-
- meta_core_end_grab_op (gdk_display, event->time);
- break;
-
- case META_GRAB_OP_CLICKING_DELETE:
- if (control == META_FRAME_CONTROL_DELETE)
- meta_core_delete (gdk_display, frame->xwindow, event->time);
-
- meta_core_end_grab_op (gdk_display, event->time);
- break;
-
- case META_GRAB_OP_CLICKING_MENU:
- meta_core_end_grab_op (gdk_display, event->time);
- break;
-
- case META_GRAB_OP_CLICKING_SHADE:
- if (control == META_FRAME_CONTROL_SHADE)
- meta_core_shade (gdk_display, frame->xwindow, event->time);
-
- meta_core_end_grab_op (gdk_display, event->time);
- break;
-
- case META_GRAB_OP_CLICKING_UNSHADE:
- if (control == META_FRAME_CONTROL_UNSHADE)
- meta_core_unshade (gdk_display, frame->xwindow, event->time);
-
- meta_core_end_grab_op (gdk_display, event->time);
- break;
-
- case META_GRAB_OP_CLICKING_ABOVE:
- if (control == META_FRAME_CONTROL_ABOVE)
- meta_core_make_above (gdk_display, frame->xwindow);
-
- meta_core_end_grab_op (gdk_display, event->time);
- break;
-
- case META_GRAB_OP_CLICKING_UNABOVE:
- if (control == META_FRAME_CONTROL_UNABOVE)
- meta_core_unmake_above (gdk_display, frame->xwindow);
-
- meta_core_end_grab_op (gdk_display, event->time);
- break;
-
- case META_GRAB_OP_CLICKING_STICK:
- if (control == META_FRAME_CONTROL_STICK)
- meta_core_stick (gdk_display, frame->xwindow);
-
- meta_core_end_grab_op (gdk_display, event->time);
- break;
-
- case META_GRAB_OP_CLICKING_UNSTICK:
- if (control == META_FRAME_CONTROL_UNSTICK)
- meta_core_unstick (gdk_display, frame->xwindow);
-
- meta_core_end_grab_op (gdk_display, event->time);
- break;
-
- default:
- break;
- }
-
- /* Update the prelit control regardless of what button the mouse
- * was released over; needed so that the new button can become
- * prelit so to let the user know that it can now be pressed.
- * :)
- */
- meta_frames_update_prelit_control (frames, frame, control);
- }
-
- return TRUE;
-}
-
-static void
-meta_frames_update_prelit_control (MetaFrames *frames,
- MetaUIFrame *frame,
- MetaFrameControl control)
-{
- MetaFrameControl old_control;
- MetaCursor cursor;
-
-
- meta_verbose ("Updating prelit control from %u to %u\n",
- frame->prelit_control, control);
-
- cursor = META_CURSOR_DEFAULT;
-
- switch (control)
- {
- case META_FRAME_CONTROL_CLIENT_AREA:
- break;
- case META_FRAME_CONTROL_NONE:
- break;
- case META_FRAME_CONTROL_TITLE:
- break;
- case META_FRAME_CONTROL_DELETE:
- break;
- case META_FRAME_CONTROL_MENU:
- break;
- case META_FRAME_CONTROL_MINIMIZE:
- break;
- case META_FRAME_CONTROL_MAXIMIZE:
- break;
- case META_FRAME_CONTROL_UNMAXIMIZE:
- break;
- case META_FRAME_CONTROL_SHADE:
- break;
- case META_FRAME_CONTROL_UNSHADE:
- break;
- case META_FRAME_CONTROL_ABOVE:
- break;
- case META_FRAME_CONTROL_UNABOVE:
- break;
- case META_FRAME_CONTROL_STICK:
- break;
- case META_FRAME_CONTROL_UNSTICK:
- break;
- case META_FRAME_CONTROL_RESIZE_SE:
- cursor = META_CURSOR_SE_RESIZE;
- break;
- case META_FRAME_CONTROL_RESIZE_S:
- cursor = META_CURSOR_SOUTH_RESIZE;
- break;
- case META_FRAME_CONTROL_RESIZE_SW:
- cursor = META_CURSOR_SW_RESIZE;
- break;
- case META_FRAME_CONTROL_RESIZE_N:
- cursor = META_CURSOR_NORTH_RESIZE;
- break;
- case META_FRAME_CONTROL_RESIZE_NE:
- cursor = META_CURSOR_NE_RESIZE;
- break;
- case META_FRAME_CONTROL_RESIZE_NW:
- cursor = META_CURSOR_NW_RESIZE;
- break;
- case META_FRAME_CONTROL_RESIZE_W:
- cursor = META_CURSOR_WEST_RESIZE;
- break;
- case META_FRAME_CONTROL_RESIZE_E:
- cursor = META_CURSOR_EAST_RESIZE;
- break;
- }
-
- /* set/unset the prelight cursor */
- meta_core_set_screen_cursor (gdk_display,
- frame->xwindow,
- cursor);
-
- switch (control)
- {
- case META_FRAME_CONTROL_MENU:
- case META_FRAME_CONTROL_MINIMIZE:
- case META_FRAME_CONTROL_MAXIMIZE:
- case META_FRAME_CONTROL_DELETE:
- case META_FRAME_CONTROL_SHADE:
- case META_FRAME_CONTROL_UNSHADE:
- case META_FRAME_CONTROL_ABOVE:
- case META_FRAME_CONTROL_UNABOVE:
- case META_FRAME_CONTROL_STICK:
- case META_FRAME_CONTROL_UNSTICK:
- case META_FRAME_CONTROL_UNMAXIMIZE:
- /* leave control set */
- break;
- default:
- /* Only prelight buttons */
- control = META_FRAME_CONTROL_NONE;
- break;
- }
-
- if (control == frame->prelit_control)
- return;
-
- /* Save the old control so we can unprelight it */
- old_control = frame->prelit_control;
-
- frame->prelit_control = control;
-
- redraw_control (frames, frame, old_control);
- redraw_control (frames, frame, control);
-}
-
-static gboolean
-meta_frames_motion_notify_event (GtkWidget *widget,
- GdkEventMotion *event)
-{
- MetaUIFrame *frame;
- MetaFrames *frames;
- MetaGrabOp grab_op;
-
- frames = META_FRAMES (widget);
-
- frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
- if (frame == NULL)
- return FALSE;
-
- clear_tip (frames);
-
- frames->last_motion_frame = frame;
-
- grab_op = meta_core_get_grab_op (gdk_display);
-
- switch (grab_op)
- {
- case META_GRAB_OP_CLICKING_MENU:
- case META_GRAB_OP_CLICKING_DELETE:
- case META_GRAB_OP_CLICKING_MINIMIZE:
- case META_GRAB_OP_CLICKING_MAXIMIZE:
- case META_GRAB_OP_CLICKING_UNMAXIMIZE:
- case META_GRAB_OP_CLICKING_SHADE:
- case META_GRAB_OP_CLICKING_UNSHADE:
- case META_GRAB_OP_CLICKING_ABOVE:
- case META_GRAB_OP_CLICKING_UNABOVE:
- case META_GRAB_OP_CLICKING_STICK:
- case META_GRAB_OP_CLICKING_UNSTICK:
- {
- MetaFrameControl control;
- int x, y;
-
- gdk_window_get_pointer (frame->window, &x, &y, NULL);
-
- /* Control is set to none unless it matches
- * the current grab
- */
- control = get_control (frames, frame, x, y);
- if (! ((control == META_FRAME_CONTROL_MENU &&
- grab_op == META_GRAB_OP_CLICKING_MENU) ||
- (control == META_FRAME_CONTROL_DELETE &&
- grab_op == META_GRAB_OP_CLICKING_DELETE) ||
- (control == META_FRAME_CONTROL_MINIMIZE &&
- grab_op == META_GRAB_OP_CLICKING_MINIMIZE) ||
- ((control == META_FRAME_CONTROL_MAXIMIZE ||
- control == META_FRAME_CONTROL_UNMAXIMIZE) &&
- (grab_op == META_GRAB_OP_CLICKING_MAXIMIZE ||
- grab_op == META_GRAB_OP_CLICKING_UNMAXIMIZE)) ||
- (control == META_FRAME_CONTROL_SHADE &&
- grab_op == META_GRAB_OP_CLICKING_SHADE) ||
- (control == META_FRAME_CONTROL_UNSHADE &&
- grab_op == META_GRAB_OP_CLICKING_UNSHADE) ||
- (control == META_FRAME_CONTROL_ABOVE &&
- grab_op == META_GRAB_OP_CLICKING_ABOVE) ||
- (control == META_FRAME_CONTROL_UNABOVE &&
- grab_op == META_GRAB_OP_CLICKING_UNABOVE) ||
- (control == META_FRAME_CONTROL_STICK &&
- grab_op == META_GRAB_OP_CLICKING_STICK) ||
- (control == META_FRAME_CONTROL_UNSTICK &&
- grab_op == META_GRAB_OP_CLICKING_UNSTICK)))
- control = META_FRAME_CONTROL_NONE;
-
- /* Update prelit control and cursor */
- meta_frames_update_prelit_control (frames, frame, control);
-
- /* No tooltip while in the process of clicking */
- }
- break;
- case META_GRAB_OP_NONE:
- {
- MetaFrameControl control;
- int x, y;
-
- gdk_window_get_pointer (frame->window, &x, &y, NULL);
-
- control = get_control (frames, frame, x, y);
-
- /* Update prelit control and cursor */
- meta_frames_update_prelit_control (frames, frame, control);
-
- queue_tip (frames);
- }
- break;
-
- default:
- break;
- }
-
- return TRUE;
-}
-
-static gboolean
-meta_frames_destroy_event (GtkWidget *widget,
- GdkEventAny *event)
-{
- MetaUIFrame *frame;
- MetaFrames *frames;
-
- frames = META_FRAMES (widget);
-
- frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
- if (frame == NULL)
- return FALSE;
-
- return TRUE;
-}
-
-/* Cut and paste from GDK */
-static GdkGC *
-get_bg_gc (GdkWindow *window, int x_offset, int y_offset)
-{
- GdkWindowObject *private = (GdkWindowObject *)window;
- guint gc_mask = 0;
- GdkGCValues gc_values;
-
- if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG && private->parent)
- {
- return get_bg_gc (GDK_WINDOW (private->parent),
- x_offset + private->x,
- y_offset + private->y);
- }
- else if (private->bg_pixmap &&
- private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
- private->bg_pixmap != GDK_NO_BG)
- {
- gc_values.fill = GDK_TILED;
- gc_values.tile = private->bg_pixmap;
- gc_values.ts_x_origin = x_offset;
- gc_values.ts_y_origin = y_offset;
-
- gc_mask = GDK_GC_FILL | GDK_GC_TILE | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN;
-
- return gdk_gc_new_with_values (window, &gc_values, gc_mask);
- }
- else
- {
- GdkGC *gc = gdk_gc_new (window);
-
- gdk_gc_set_foreground (gc, &(private->bg_color));
-
- return gc;
- }
-}
-
-static void
-clear_backing (GdkPixmap *pixmap,
- GdkWindow *window,
- int xoffset, int yoffset)
-{
- GdkGC *tmp_gc = get_bg_gc (window, xoffset, yoffset);
-
- gdk_draw_rectangle (pixmap, tmp_gc, TRUE,
- 0, 0, -1, -1);
-
- g_object_unref (tmp_gc);
-}
-
-/* Returns a pixmap with a piece of the windows frame painted on it.
-*/
-
-static GdkPixmap *
-generate_pixmap (MetaFrames *frames,
- MetaUIFrame *frame,
- MetaRectangle rect)
-{
- GdkRectangle rectangle;
- GdkRegion *region;
- GdkPixmap *result;
-
- rectangle.x = rect.x;
- rectangle.y = rect.y;
- rectangle.width = MAX (rect.width, 1);
- rectangle.height = MAX (rect.height, 1);
-
- result = gdk_pixmap_new (frame->window,
- rectangle.width, rectangle.height, -1);
-
- clear_backing (result, frame->window, rectangle.x, rectangle.y);
-
- region = gdk_region_rectangle (&rectangle);
-
- meta_frames_paint_to_drawable (frames, frame, result, region,
- -rectangle.x, -rectangle.y);
-
- gdk_region_destroy (region);
-
- return result;
-}
-
-
-static void
-populate_cache (MetaFrames *frames,
- MetaUIFrame *frame)
-{
- int top, bottom, left, right;
- int width, height;
- int frame_width, frame_height, screen_width, screen_height;
- CachedPixels *pixels;
- MetaFrameType frame_type;
- MetaFrameFlags frame_flags;
- int i;
-
- meta_core_get (gdk_display, frame->xwindow,
- META_CORE_GET_FRAME_WIDTH, &frame_width,
- META_CORE_GET_FRAME_HEIGHT, &frame_height,
- META_CORE_GET_SCREEN_WIDTH, &screen_width,
- META_CORE_GET_SCREEN_HEIGHT, &screen_height,
- META_CORE_GET_CLIENT_WIDTH, &width,
- META_CORE_GET_CLIENT_HEIGHT, &height,
- META_CORE_GET_FRAME_TYPE, &frame_type,
- META_CORE_GET_FRAME_FLAGS, &frame_flags,
- META_CORE_GET_END);
-
- /* don't cache extremely large windows */
- if (frame_width > 2 * screen_width ||
- frame_height > 2 * screen_height)
- {
- return;
- }
-
- meta_theme_get_frame_borders (meta_theme_get_current (),
- frame_type,
- frame->text_height,
- frame_flags,
- &top, &bottom, &left, &right);
-
- pixels = get_cache (frames, frame);
-
- /* Setup the rectangles for the four frame borders. First top, then
- left, right and bottom. */
- pixels->piece[0].rect.x = 0;
- pixels->piece[0].rect.y = 0;
- pixels->piece[0].rect.width = left + width + right;
- pixels->piece[0].rect.height = top;
-
- pixels->piece[1].rect.x = 0;
- pixels->piece[1].rect.y = top;
- pixels->piece[1].rect.width = left;
- pixels->piece[1].rect.height = height;
-
- pixels->piece[2].rect.x = left + width;
- pixels->piece[2].rect.y = top;
- pixels->piece[2].rect.width = right;
- pixels->piece[2].rect.height = height;
-
- pixels->piece[3].rect.x = 0;
- pixels->piece[3].rect.y = top + height;
- pixels->piece[3].rect.width = left + width + right;
- pixels->piece[3].rect.height = bottom;
-
- for (i = 0; i < 4; i++)
- {
- CachedFramePiece *piece = &pixels->piece[i];
- if (!piece->pixmap)
- piece->pixmap = generate_pixmap (frames, frame, piece->rect);
- }
-
- if (frames->invalidate_cache_timeout_id)
- g_source_remove (frames->invalidate_cache_timeout_id);
-
- frames->invalidate_cache_timeout_id = g_timeout_add (1000, invalidate_cache_timeout, frames);
-
- if (!g_list_find (frames->invalidate_frames, frame))
- frames->invalidate_frames =
- g_list_prepend (frames->invalidate_frames, frame);
-}
-
-static void
-clip_to_screen (GdkRegion *region, MetaUIFrame *frame)
-{
- GdkRectangle frame_area;
- GdkRectangle screen_area = { 0, 0, 0, 0 };
- GdkRegion *tmp_region;
-
- /* Chop off stuff outside the screen; this optimization
- * is crucial to handle huge client windows,
- * like "xterm -geometry 1000x1000"
- */
- meta_core_get (gdk_display, frame->xwindow,
- META_CORE_GET_FRAME_X, &frame_area.x,
- META_CORE_GET_FRAME_Y, &frame_area.y,
- META_CORE_GET_FRAME_WIDTH, &frame_area.width,
- META_CORE_GET_FRAME_HEIGHT, &frame_area.height,
- META_CORE_GET_SCREEN_WIDTH, &screen_area.height,
- META_CORE_GET_SCREEN_HEIGHT, &screen_area.height,
- META_CORE_GET_END);
-
- gdk_region_offset (region, frame_area.x, frame_area.y);
-
- tmp_region = gdk_region_rectangle (&frame_area);
- gdk_region_intersect (region, tmp_region);
- gdk_region_destroy (tmp_region);
-
- gdk_region_offset (region, - frame_area.x, - frame_area.y);
-}
-
-static void
-subtract_from_region (GdkRegion *region, GdkDrawable *drawable,
- gint x, gint y)
-{
- GdkRectangle rect;
- GdkRegion *reg_rect;
-
- gdk_drawable_get_size (drawable, &rect.width, &rect.height);
- rect.x = x;
- rect.y = y;
-
- reg_rect = gdk_region_rectangle (&rect);
- gdk_region_subtract (region, reg_rect);
- gdk_region_destroy (reg_rect);
-}
-
-static void
-cached_pixels_draw (CachedPixels *pixels,
- GdkWindow *window,
- GdkRegion *region)
-{
- GdkGC *gc;
- int i;
-
- gc = gdk_gc_new (window);
-
- for (i = 0; i < 4; i++)
- {
- CachedFramePiece *piece;
- piece = &pixels->piece[i];
-
- if (piece->pixmap)
- {
- gdk_draw_drawable (window, gc, piece->pixmap,
- 0, 0,
- piece->rect.x, piece->rect.y,
- -1, -1);
- subtract_from_region (region, piece->pixmap,
- piece->rect.x, piece->rect.y);
- }
- }
-
- g_object_unref (gc);
-}
-
-static gboolean
-meta_frames_expose_event (GtkWidget *widget,
- GdkEventExpose *event)
-{
- MetaUIFrame *frame;
- MetaFrames *frames;
- GdkRegion *region;
- CachedPixels *pixels;
-
- frames = META_FRAMES (widget);
-
- frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
- if (frame == NULL)
- return FALSE;
-
- if (frames->expose_delay_count > 0)
- {
- /* Redraw this entire frame later */
- frame->expose_delayed = TRUE;
- return TRUE;
- }
-
- populate_cache (frames, frame);
-
- region = gdk_region_copy (event->region);
-
- pixels = get_cache (frames, frame);
-
- cached_pixels_draw (pixels, frame->window, region);
-
- clip_to_screen (region, frame);
- meta_frames_paint_to_drawable (frames, frame, frame->window, region, 0, 0);
-
- gdk_region_destroy (region);
-
- return TRUE;
-}
-
-/* How far off the screen edge the window decorations should
- * be drawn. Used only in meta_frames_paint_to_drawable, below.
- */
-#define DECORATING_BORDER 100
-
-static void
-meta_frames_paint_to_drawable (MetaFrames *frames,
- MetaUIFrame *frame,
- GdkDrawable *drawable,
- GdkRegion *region,
- int x_offset,
- int y_offset)
-{
- GtkWidget *widget;
- MetaFrameFlags flags;
- MetaFrameType type;
- GdkPixbuf *mini_icon;
- GdkPixbuf *icon;
- int w, h;
- MetaButtonState button_states[META_BUTTON_TYPE_LAST];
- Window grab_frame;
- int i;
- MetaButtonLayout button_layout;
- MetaGrabOp grab_op;
-
- widget = GTK_WIDGET (frames);
-
- for (i = 0; i < META_BUTTON_TYPE_LAST; i++)
- button_states[i] = META_BUTTON_STATE_NORMAL;
-
- grab_frame = meta_core_get_grab_frame (gdk_display);
- grab_op = meta_core_get_grab_op (gdk_display);
- if (grab_frame != frame->xwindow)
- grab_op = META_GRAB_OP_NONE;
-
- /* Set prelight state */
- switch (frame->prelit_control)
- {
- case META_FRAME_CONTROL_MENU:
- if (grab_op == META_GRAB_OP_CLICKING_MENU)
- button_states[META_BUTTON_TYPE_MENU] = META_BUTTON_STATE_PRESSED;
- else
- button_states[META_BUTTON_TYPE_MENU] = META_BUTTON_STATE_PRELIGHT;
- break;
- case META_FRAME_CONTROL_MINIMIZE:
- if (grab_op == META_GRAB_OP_CLICKING_MINIMIZE)
- button_states[META_BUTTON_TYPE_MINIMIZE] = META_BUTTON_STATE_PRESSED;
- else
- button_states[META_BUTTON_TYPE_MINIMIZE] = META_BUTTON_STATE_PRELIGHT;
- break;
- case META_FRAME_CONTROL_MAXIMIZE:
- if (grab_op == META_GRAB_OP_CLICKING_MAXIMIZE)
- button_states[META_BUTTON_TYPE_MAXIMIZE] = META_BUTTON_STATE_PRESSED;
- else
- button_states[META_BUTTON_TYPE_MAXIMIZE] = META_BUTTON_STATE_PRELIGHT;
- break;
- case META_FRAME_CONTROL_UNMAXIMIZE:
- if (grab_op == META_GRAB_OP_CLICKING_UNMAXIMIZE)
- button_states[META_BUTTON_TYPE_MAXIMIZE] = META_BUTTON_STATE_PRESSED;
- else
- button_states[META_BUTTON_TYPE_MAXIMIZE] = META_BUTTON_STATE_PRELIGHT;
- break;
- case META_FRAME_CONTROL_SHADE:
- if (grab_op == META_GRAB_OP_CLICKING_SHADE)
- button_states[META_BUTTON_TYPE_SHADE] = META_BUTTON_STATE_PRESSED;
- else
- button_states[META_BUTTON_TYPE_SHADE] = META_BUTTON_STATE_PRELIGHT;
- break;
- case META_FRAME_CONTROL_UNSHADE:
- if (grab_op == META_GRAB_OP_CLICKING_UNSHADE)
- button_states[META_BUTTON_TYPE_UNSHADE] = META_BUTTON_STATE_PRESSED;
- else
- button_states[META_BUTTON_TYPE_UNSHADE] = META_BUTTON_STATE_PRELIGHT;
- break;
- case META_FRAME_CONTROL_ABOVE:
- if (grab_op == META_GRAB_OP_CLICKING_ABOVE)
- button_states[META_BUTTON_TYPE_ABOVE] = META_BUTTON_STATE_PRESSED;
- else
- button_states[META_BUTTON_TYPE_ABOVE] = META_BUTTON_STATE_PRELIGHT;
- break;
- case META_FRAME_CONTROL_UNABOVE:
- if (grab_op == META_GRAB_OP_CLICKING_UNABOVE)
- button_states[META_BUTTON_TYPE_UNABOVE] = META_BUTTON_STATE_PRESSED;
- else
- button_states[META_BUTTON_TYPE_UNABOVE] = META_BUTTON_STATE_PRELIGHT;
- break;
- case META_FRAME_CONTROL_STICK:
- if (grab_op == META_GRAB_OP_CLICKING_STICK)
- button_states[META_BUTTON_TYPE_STICK] = META_BUTTON_STATE_PRESSED;
- else
- button_states[META_BUTTON_TYPE_STICK] = META_BUTTON_STATE_PRELIGHT;
- break;
- case META_FRAME_CONTROL_UNSTICK:
- if (grab_op == META_GRAB_OP_CLICKING_UNSTICK)
- button_states[META_BUTTON_TYPE_UNSTICK] = META_BUTTON_STATE_PRESSED;
- else
- button_states[META_BUTTON_TYPE_UNSTICK] = META_BUTTON_STATE_PRELIGHT;
- break;
- case META_FRAME_CONTROL_DELETE:
- if (grab_op == META_GRAB_OP_CLICKING_DELETE)
- button_states[META_BUTTON_TYPE_CLOSE] = META_BUTTON_STATE_PRESSED;
- else
- button_states[META_BUTTON_TYPE_CLOSE] = META_BUTTON_STATE_PRELIGHT;
- break;
- default:
- break;
- }
-
- /* Map button function states to button position states */
- button_states[META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND] =
- button_states[META_BUTTON_TYPE_MENU];
- button_states[META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND] =
- META_BUTTON_STATE_NORMAL;
- button_states[META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND] =
- META_BUTTON_STATE_NORMAL;
- button_states[META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND] =
- button_states[META_BUTTON_TYPE_MINIMIZE];
- button_states[META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND] =
- button_states[META_BUTTON_TYPE_MAXIMIZE];
- button_states[META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND] =
- button_states[META_BUTTON_TYPE_CLOSE];
-
- meta_core_get (gdk_display, frame->xwindow,
- META_CORE_GET_FRAME_FLAGS, &flags,
- META_CORE_GET_FRAME_TYPE, &type,
- META_CORE_GET_MINI_ICON, &mini_icon,
- META_CORE_GET_ICON, &icon,
- META_CORE_GET_CLIENT_WIDTH, &w,
- META_CORE_GET_CLIENT_HEIGHT, &h,
- META_CORE_GET_END);
-
- meta_frames_ensure_layout (frames, frame);
-
- meta_prefs_get_button_layout (&button_layout);
-
- if (G_LIKELY (GDK_IS_WINDOW (drawable)))
- {
- /* A window; happens about 2/3 of the time */
-
- GdkRectangle area, *areas;
- int n_areas;
- int screen_width, screen_height;
- GdkRegion *edges, *tmp_region;
- int top, bottom, left, right;
-
- /* Repaint each side of the frame */
-
- meta_theme_get_frame_borders (meta_theme_get_current (),
- type, frame->text_height, flags,
- &top, &bottom, &left, &right);
-
- meta_core_get (gdk_display, frame->xwindow,
- META_CORE_GET_SCREEN_WIDTH, &screen_width,
- META_CORE_GET_SCREEN_HEIGHT, &screen_height,
- META_CORE_GET_END);
-
- edges = gdk_region_copy (region);
-
- /* Punch out the client area */
-
- area.x = left;
- area.y = top;
- area.width = w;
- area.height = h;
- tmp_region = gdk_region_rectangle (&area);
- gdk_region_subtract (edges, tmp_region);
- gdk_region_destroy (tmp_region);
-
- /* Now draw remaining portion of region */
-
- gdk_region_get_rectangles (edges, &areas, &n_areas);
-
- for (i = 0; i < n_areas; i++)
- {
- /* Bug 399529: clamp areas[i] so that it doesn't go too far
- * off the edge of the screen. This works around a GDK bug
- * which makes gdk_window_begin_paint_rect cause an X error
- * if the window is insanely huge. If the client is a GDK program
- * and does this, it will still probably cause an X error in that
- * program, but the last thing we want is for Metacity to crash
- * because it attempted to decorate the silly window.
- */
-
- areas[i].x = MAX (areas[i].x, -DECORATING_BORDER);
- areas[i].y = MAX (areas[i].y, -DECORATING_BORDER);
- if (areas[i].x+areas[i].width > screen_width + DECORATING_BORDER)
- areas[i].width = MIN (0, screen_width - areas[i].x);
- if (areas[i].y+areas[i].height > screen_height + DECORATING_BORDER)
- areas[i].height = MIN (0, screen_height - areas[i].y);
-
- /* Okay, so let's start painting. */
-
- gdk_window_begin_paint_rect (drawable, &areas[i]);
-
- meta_theme_draw_frame (meta_theme_get_current (),
- widget,
- drawable,
- NULL, /* &areas[i], */
- x_offset, y_offset,
- type,
- flags,
- w, h,
- frame->layout,
- frame->text_height,
- &button_layout,
- button_states,
- mini_icon, icon);
-
- gdk_window_end_paint (drawable);
- }
-
- g_free (areas);
- gdk_region_destroy (edges);
-
- }
- else
- {
- /* Not a window; happens about 1/3 of the time */
-
- meta_theme_draw_frame (meta_theme_get_current (),
- widget,
- drawable,
- NULL,
- x_offset, y_offset,
- type,
- flags,
- w, h,
- frame->layout,
- frame->text_height,
- &button_layout,
- button_states,
- mini_icon, icon);
- }
-
-}
-
-static void
-meta_frames_set_window_background (MetaFrames *frames,
- MetaUIFrame *frame)
-{
- MetaFrameFlags flags;
- MetaFrameType type;
- MetaFrameStyle *style;
- gboolean frame_exists;
-
- meta_core_get (gdk_display, frame->xwindow,
- META_CORE_WINDOW_HAS_FRAME, &frame_exists,
- META_CORE_GET_FRAME_FLAGS, &flags,
- META_CORE_GET_FRAME_TYPE, &type,
- META_CORE_GET_END);
-
- if (frame_exists)
- {
- style = meta_theme_get_frame_style (meta_theme_get_current (),
- type, flags);
- }
-
- if (frame_exists && style->window_background_color != NULL)
- {
- GdkColor color;
- GdkVisual *visual;
-
- meta_color_spec_render (style->window_background_color,
- GTK_WIDGET (frames),
- &color);
-
- /* Fill in color.pixel */
-
- gdk_rgb_find_color (gtk_widget_get_colormap (GTK_WIDGET (frames)),
- &color);
-
- /* Set A in ARGB to window_background_alpha, if we have ARGB */
-
- visual = gtk_widget_get_visual (GTK_WIDGET (frames));
- if (visual->depth == 32) /* we have ARGB */
- {
- color.pixel = (color.pixel & 0xffffff) &
- style->window_background_alpha << 24;
- }
-
- gdk_window_set_background (frame->window, &color);
- }
- else
- {
- gtk_style_set_background (GTK_WIDGET (frames)->style,
- frame->window, GTK_STATE_NORMAL);
- }
- }
-
-static gboolean
-meta_frames_enter_notify_event (GtkWidget *widget,
- GdkEventCrossing *event)
-{
- MetaUIFrame *frame;
- MetaFrames *frames;
- MetaFrameControl control;
-
- frames = META_FRAMES (widget);
-
- frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
- if (frame == NULL)
- return FALSE;
-
- control = get_control (frames, frame, event->x, event->y);
- meta_frames_update_prelit_control (frames, frame, control);
-
- return TRUE;
-}
-
-static gboolean
-meta_frames_leave_notify_event (GtkWidget *widget,
- GdkEventCrossing *event)
-{
- MetaUIFrame *frame;
- MetaFrames *frames;
-
- frames = META_FRAMES (widget);
-
- frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
- if (frame == NULL)
- return FALSE;
-
- meta_frames_update_prelit_control (frames, frame, META_FRAME_CONTROL_NONE);
-
- clear_tip (frames);
-
- return TRUE;
-}
-
-static GdkRectangle*
-control_rect (MetaFrameControl control,
- MetaFrameGeometry *fgeom)
-{
- GdkRectangle *rect;
-
- rect = NULL;
- switch (control)
- {
- case META_FRAME_CONTROL_TITLE:
- rect = &fgeom->title_rect;
- break;
- case META_FRAME_CONTROL_DELETE:
- rect = &fgeom->close_rect.visible;
- break;
- case META_FRAME_CONTROL_MENU:
- rect = &fgeom->menu_rect.visible;
- break;
- case META_FRAME_CONTROL_MINIMIZE:
- rect = &fgeom->min_rect.visible;
- break;
- case META_FRAME_CONTROL_MAXIMIZE:
- case META_FRAME_CONTROL_UNMAXIMIZE:
- rect = &fgeom->max_rect.visible;
- break;
- case META_FRAME_CONTROL_SHADE:
- rect = &fgeom->shade_rect.visible;
- break;
- case META_FRAME_CONTROL_UNSHADE:
- rect = &fgeom->unshade_rect.visible;
- break;
- case META_FRAME_CONTROL_ABOVE:
- rect = &fgeom->above_rect.visible;
- break;
- case META_FRAME_CONTROL_UNABOVE:
- rect = &fgeom->unabove_rect.visible;
- break;
- case META_FRAME_CONTROL_STICK:
- rect = &fgeom->stick_rect.visible;
- break;
- case META_FRAME_CONTROL_UNSTICK:
- rect = &fgeom->unstick_rect.visible;
- break;
- case META_FRAME_CONTROL_RESIZE_SE:
- break;
- case META_FRAME_CONTROL_RESIZE_S:
- break;
- case META_FRAME_CONTROL_RESIZE_SW:
- break;
- case META_FRAME_CONTROL_RESIZE_N:
- break;
- case META_FRAME_CONTROL_RESIZE_NE:
- break;
- case META_FRAME_CONTROL_RESIZE_NW:
- break;
- case META_FRAME_CONTROL_RESIZE_W:
- break;
- case META_FRAME_CONTROL_RESIZE_E:
- break;
- case META_FRAME_CONTROL_NONE:
- break;
- case META_FRAME_CONTROL_CLIENT_AREA:
- break;
- }
-
- return rect;
-}
-
-#define RESIZE_EXTENDS 15
-#define TOP_RESIZE_HEIGHT 2
-static MetaFrameControl
-get_control (MetaFrames *frames,
- MetaUIFrame *frame,
- int x, int y)
-{
- MetaFrameGeometry fgeom;
- MetaFrameFlags flags;
- gboolean has_vert, has_horiz;
- GdkRectangle client;
-
- meta_frames_calc_geometry (frames, frame, &fgeom);
-
- client.x = fgeom.left_width;
- client.y = fgeom.top_height;
- client.width = fgeom.width - fgeom.left_width - fgeom.right_width;
- client.height = fgeom.height - fgeom.top_height - fgeom.bottom_height;
-
- if (POINT_IN_RECT (x, y, client))
- return META_FRAME_CONTROL_CLIENT_AREA;
-
- if (POINT_IN_RECT (x, y, fgeom.close_rect.clickable))
- return META_FRAME_CONTROL_DELETE;
-
- if (POINT_IN_RECT (x, y, fgeom.min_rect.clickable))
- return META_FRAME_CONTROL_MINIMIZE;
-
- if (POINT_IN_RECT (x, y, fgeom.menu_rect.clickable))
- return META_FRAME_CONTROL_MENU;
-
- meta_core_get (gdk_display, frame->xwindow,
- META_CORE_GET_FRAME_FLAGS, &flags,
- META_CORE_GET_END);
-
- has_vert = (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE) != 0;
- has_horiz = (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE) != 0;
-
- if (POINT_IN_RECT (x, y, fgeom.title_rect))
- {
- if (has_vert && y <= TOP_RESIZE_HEIGHT)
- return META_FRAME_CONTROL_RESIZE_N;
- else
- return META_FRAME_CONTROL_TITLE;
- }
-
- if (POINT_IN_RECT (x, y, fgeom.max_rect.clickable))
- {
- if (flags & META_FRAME_MAXIMIZED)
- return META_FRAME_CONTROL_UNMAXIMIZE;
- else
- return META_FRAME_CONTROL_MAXIMIZE;
- }
-
- if (POINT_IN_RECT (x, y, fgeom.shade_rect.clickable))
- {
- return META_FRAME_CONTROL_SHADE;
- }
-
- if (POINT_IN_RECT (x, y, fgeom.unshade_rect.clickable))
- {
- return META_FRAME_CONTROL_UNSHADE;
- }
-
- if (POINT_IN_RECT (x, y, fgeom.above_rect.clickable))
- {
- return META_FRAME_CONTROL_ABOVE;
- }
-
- if (POINT_IN_RECT (x, y, fgeom.unabove_rect.clickable))
- {
- return META_FRAME_CONTROL_UNABOVE;
- }
-
- if (POINT_IN_RECT (x, y, fgeom.stick_rect.clickable))
- {
- return META_FRAME_CONTROL_STICK;
- }
-
- if (POINT_IN_RECT (x, y, fgeom.unstick_rect.clickable))
- {
- return META_FRAME_CONTROL_UNSTICK;
- }
-
- /* South resize always has priority over north resize,
- * in case of overlap.
- */
-
- if (y >= (fgeom.height - fgeom.bottom_height - RESIZE_EXTENDS) &&
- x >= (fgeom.width - fgeom.right_width - RESIZE_EXTENDS))
- {
- if (has_vert && has_horiz)
- return META_FRAME_CONTROL_RESIZE_SE;
- else if (has_vert)
- return META_FRAME_CONTROL_RESIZE_S;
- else if (has_horiz)
- return META_FRAME_CONTROL_RESIZE_E;
- }
- else if (y >= (fgeom.height - fgeom.bottom_height - RESIZE_EXTENDS) &&
- x <= (fgeom.left_width + RESIZE_EXTENDS))
- {
- if (has_vert && has_horiz)
- return META_FRAME_CONTROL_RESIZE_SW;
- else if (has_vert)
- return META_FRAME_CONTROL_RESIZE_S;
- else if (has_horiz)
- return META_FRAME_CONTROL_RESIZE_W;
- }
- else if (y < (fgeom.top_height + RESIZE_EXTENDS) &&
- x < RESIZE_EXTENDS)
- {
- if (has_vert && has_horiz)
- return META_FRAME_CONTROL_RESIZE_NW;
- else if (has_vert)
- return META_FRAME_CONTROL_RESIZE_N;
- else if (has_horiz)
- return META_FRAME_CONTROL_RESIZE_W;
- }
- else if (y < (fgeom.top_height + RESIZE_EXTENDS) &&
- x >= (fgeom.width - RESIZE_EXTENDS))
- {
- if (has_vert && has_horiz)
- return META_FRAME_CONTROL_RESIZE_NE;
- else if (has_vert)
- return META_FRAME_CONTROL_RESIZE_N;
- else if (has_horiz)
- return META_FRAME_CONTROL_RESIZE_E;
- }
- else if (y >= (fgeom.height - fgeom.bottom_height - RESIZE_EXTENDS))
- {
- if (has_vert)
- return META_FRAME_CONTROL_RESIZE_S;
- }
- else if (y <= TOP_RESIZE_HEIGHT)
- {
- if (has_vert)
- return META_FRAME_CONTROL_RESIZE_N;
- else if (has_horiz)
- return META_FRAME_CONTROL_TITLE;
- }
- else if (x <= fgeom.left_width)
- {
- if (has_horiz)
- return META_FRAME_CONTROL_RESIZE_W;
- }
- else if (x >= (fgeom.width - fgeom.right_width))
- {
- if (has_horiz)
- return META_FRAME_CONTROL_RESIZE_E;
- }
-
- if (y >= fgeom.top_height)
- return META_FRAME_CONTROL_NONE;
- else
- return META_FRAME_CONTROL_TITLE;
-}
-
-void
-meta_frames_push_delay_exposes (MetaFrames *frames)
-{
- if (frames->expose_delay_count == 0)
- {
- /* Make sure we've repainted things */
- gdk_window_process_all_updates ();
- XFlush (gdk_display);
- }
-
- frames->expose_delay_count += 1;
-}
-
-static void
-queue_pending_exposes_func (gpointer key, gpointer value, gpointer data)
-{
- MetaUIFrame *frame;
- MetaFrames *frames;
-
- frames = META_FRAMES (data);
- frame = value;
-
- if (frame->expose_delayed)
- {
- invalidate_whole_window (frames, frame);
- frame->expose_delayed = FALSE;
- }
-}
-
-void
-meta_frames_pop_delay_exposes (MetaFrames *frames)
-{
- g_return_if_fail (frames->expose_delay_count > 0);
-
- frames->expose_delay_count -= 1;
-
- if (frames->expose_delay_count == 0)
- {
- g_hash_table_foreach (frames->frames,
- queue_pending_exposes_func,
- frames);
- }
-}
-
-static void
-invalidate_whole_window (MetaFrames *frames,
- MetaUIFrame *frame)
-{
- gdk_window_invalidate_rect (frame->window, NULL, FALSE);
- invalidate_cache (frames, frame);
-}
diff --git a/src/ui/frames.h b/src/ui/frames.h
deleted file mode 100644
index c4ad8bfb..00000000
--- a/src/ui/frames.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity window frame manager widget */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_FRAMES_H
-#define META_FRAMES_H
-
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
-#include "common.h"
-#include "theme.h"
-
-typedef enum
-{
- META_FRAME_CONTROL_NONE,
- META_FRAME_CONTROL_TITLE,
- META_FRAME_CONTROL_DELETE,
- META_FRAME_CONTROL_MENU,
- META_FRAME_CONTROL_MINIMIZE,
- META_FRAME_CONTROL_MAXIMIZE,
- META_FRAME_CONTROL_UNMAXIMIZE,
- META_FRAME_CONTROL_SHADE,
- META_FRAME_CONTROL_UNSHADE,
- META_FRAME_CONTROL_ABOVE,
- META_FRAME_CONTROL_UNABOVE,
- META_FRAME_CONTROL_STICK,
- META_FRAME_CONTROL_UNSTICK,
- META_FRAME_CONTROL_RESIZE_SE,
- META_FRAME_CONTROL_RESIZE_S,
- META_FRAME_CONTROL_RESIZE_SW,
- META_FRAME_CONTROL_RESIZE_N,
- META_FRAME_CONTROL_RESIZE_NE,
- META_FRAME_CONTROL_RESIZE_NW,
- META_FRAME_CONTROL_RESIZE_W,
- META_FRAME_CONTROL_RESIZE_E,
- META_FRAME_CONTROL_CLIENT_AREA
-} MetaFrameControl;
-
-/* This is one widget that manages all the window frames
- * as subwindows.
- */
-
-#define META_TYPE_FRAMES (meta_frames_get_type ())
-#define META_FRAMES(obj) (GTK_CHECK_CAST ((obj), META_TYPE_FRAMES, MetaFrames))
-#define META_FRAMES_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), META_TYPE_FRAMES, MetaFramesClass))
-#define META_IS_FRAMES(obj) (GTK_CHECK_TYPE ((obj), META_TYPE_FRAMES))
-#define META_IS_FRAMES_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), META_TYPE_FRAMES))
-#define META_FRAMES_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), META_TYPE_FRAMES, MetaFramesClass))
-
-typedef struct _MetaFrames MetaFrames;
-typedef struct _MetaFramesClass MetaFramesClass;
-
-typedef struct _MetaUIFrame MetaUIFrame;
-
-struct _MetaUIFrame
-{
- Window xwindow;
- GdkWindow *window;
- MetaFrameStyle *cache_style;
- PangoLayout *layout;
- int text_height;
- char *title; /* NULL once we have a layout */
- guint expose_delayed : 1;
- guint shape_applied : 1;
-
- /* FIXME get rid of this, it can just be in the MetaFrames struct */
- MetaFrameControl prelit_control;
-};
-
-struct _MetaFrames
-{
- GtkWindow parent_instance;
-
- GHashTable *text_heights;
-
- GHashTable *frames;
-
- guint tooltip_timeout;
- MetaUIFrame *last_motion_frame;
-
- int expose_delay_count;
-
- int invalidate_cache_timeout_id;
- GList *invalidate_frames;
- GHashTable *cache;
-};
-
-struct _MetaFramesClass
-{
- GtkWindowClass parent_class;
-
-};
-
-GType meta_frames_get_type (void) G_GNUC_CONST;
-
-MetaFrames *meta_frames_new (int screen_number);
-
-void meta_frames_manage_window (MetaFrames *frames,
- Window xwindow,
- GdkWindow *window);
-void meta_frames_unmanage_window (MetaFrames *frames,
- Window xwindow);
-void meta_frames_set_title (MetaFrames *frames,
- Window xwindow,
- const char *title);
-
-void meta_frames_repaint_frame (MetaFrames *frames,
- Window xwindow);
-
-void meta_frames_get_geometry (MetaFrames *frames,
- Window xwindow,
- int *top_height, int *bottom_height,
- int *left_width, int *right_width);
-
-void meta_frames_reset_bg (MetaFrames *frames,
- Window xwindow);
-void meta_frames_unflicker_bg (MetaFrames *frames,
- Window xwindow,
- int target_width,
- int target_height);
-
-void meta_frames_apply_shapes (MetaFrames *frames,
- Window xwindow,
- int new_window_width,
- int new_window_height,
- gboolean window_has_shape);
-void meta_frames_move_resize_frame (MetaFrames *frames,
- Window xwindow,
- int x,
- int y,
- int width,
- int height);
-void meta_frames_queue_draw (MetaFrames *frames,
- Window xwindow);
-
-void meta_frames_notify_menu_hide (MetaFrames *frames);
-
-Window meta_frames_get_moving_frame (MetaFrames *frames);
-
-void meta_frames_push_delay_exposes (MetaFrames *frames);
-void meta_frames_pop_delay_exposes (MetaFrames *frames);
-
-#endif
diff --git a/src/ui/gradient.c b/src/ui/gradient.c
deleted file mode 100644
index 67906231..00000000
--- a/src/ui/gradient.c
+++ /dev/null
@@ -1,842 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity gradient rendering */
-
-/*
- * Copyright (C) 2001 Havoc Pennington, 99% copied from wrlib in
- * WindowMaker, Copyright (C) 1997-2000 Dan Pascu and Alfredo Kojima
- * Copyright (C) 2005 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA. */
-
-#include "gradient.h"
-#include "util.h"
-#include <string.h>
-
-/* This is all Alfredo's and Dan's usual very nice WindowMaker code,
- * slightly GTK-ized
- */
-static GdkPixbuf* meta_gradient_create_horizontal (int width,
- int height,
- const GdkColor *from,
- const GdkColor *to);
-static GdkPixbuf* meta_gradient_create_vertical (int width,
- int height,
- const GdkColor *from,
- const GdkColor *to);
-static GdkPixbuf* meta_gradient_create_diagonal (int width,
- int height,
- const GdkColor *from,
- const GdkColor *to);
-static GdkPixbuf* meta_gradient_create_multi_horizontal (int width,
- int height,
- const GdkColor *colors,
- int count);
-static GdkPixbuf* meta_gradient_create_multi_vertical (int width,
- int height,
- const GdkColor *colors,
- int count);
-static GdkPixbuf* meta_gradient_create_multi_diagonal (int width,
- int height,
- const GdkColor *colors,
- int count);
-
-
-/* Used as the destroy notification function for gdk_pixbuf_new() */
-static void
-free_buffer (guchar *pixels, gpointer data)
-{
- g_free (pixels);
-}
-
-static GdkPixbuf*
-blank_pixbuf (int width, int height, gboolean no_padding)
-{
- guchar *buf;
- int rowstride;
-
- g_return_val_if_fail (width > 0, NULL);
- g_return_val_if_fail (height > 0, NULL);
-
- if (no_padding)
- rowstride = width * 3;
- else
- /* Always align rows to 32-bit boundaries */
- rowstride = 4 * ((3 * width + 3) / 4);
-
- buf = g_try_malloc (height * rowstride);
- if (!buf)
- return NULL;
-
- return gdk_pixbuf_new_from_data (buf, GDK_COLORSPACE_RGB,
- FALSE, 8,
- width, height, rowstride,
- free_buffer, NULL);
-}
-
-GdkPixbuf*
-meta_gradient_create_simple (int width,
- int height,
- const GdkColor *from,
- const GdkColor *to,
- MetaGradientType style)
-{
- switch (style)
- {
- case META_GRADIENT_HORIZONTAL:
- return meta_gradient_create_horizontal (width, height,
- from, to);
- case META_GRADIENT_VERTICAL:
- return meta_gradient_create_vertical (width, height,
- from, to);
-
- case META_GRADIENT_DIAGONAL:
- return meta_gradient_create_diagonal (width, height,
- from, to);
- case META_GRADIENT_LAST:
- break;
- }
- g_assert_not_reached ();
- return NULL;
-}
-
-GdkPixbuf*
-meta_gradient_create_multi (int width,
- int height,
- const GdkColor *colors,
- int n_colors,
- MetaGradientType style)
-{
-
- if (n_colors > 2)
- {
- switch (style)
- {
- case META_GRADIENT_HORIZONTAL:
- return meta_gradient_create_multi_horizontal (width, height, colors, n_colors);
- case META_GRADIENT_VERTICAL:
- return meta_gradient_create_multi_vertical (width, height, colors, n_colors);
- case META_GRADIENT_DIAGONAL:
- return meta_gradient_create_multi_diagonal (width, height, colors, n_colors);
- case META_GRADIENT_LAST:
- g_assert_not_reached ();
- break;
- }
- }
- else if (n_colors > 1)
- {
- return meta_gradient_create_simple (width, height, &colors[0], &colors[1],
- style);
- }
- else if (n_colors > 0)
- {
- return meta_gradient_create_simple (width, height, &colors[0], &colors[0],
- style);
- }
- g_assert_not_reached ();
- return NULL;
-}
-
-/* Interwoven essentially means we have two vertical gradients,
- * cut into horizontal strips of the given thickness, and then the strips
- * are alternated. I'm not sure what it's good for, just copied since
- * WindowMaker had it.
- */
-GdkPixbuf*
-meta_gradient_create_interwoven (int width,
- int height,
- const GdkColor colors1[2],
- int thickness1,
- const GdkColor colors2[2],
- int thickness2)
-{
-
- int i, j, k, l, ll;
- long r1, g1, b1, dr1, dg1, db1;
- long r2, g2, b2, dr2, dg2, db2;
- GdkPixbuf *pixbuf;
- unsigned char *ptr;
- unsigned char *pixels;
- int rowstride;
-
- pixbuf = blank_pixbuf (width, height, FALSE);
- if (pixbuf == NULL)
- return NULL;
-
- pixels = gdk_pixbuf_get_pixels (pixbuf);
- rowstride = gdk_pixbuf_get_rowstride (pixbuf);
-
- r1 = colors1[0].red<<8;
- g1 = colors1[0].green<<8;
- b1 = colors1[0].blue<<8;
-
- r2 = colors2[0].red<<8;
- g2 = colors2[0].green<<8;
- b2 = colors2[0].blue<<8;
-
- dr1 = ((colors1[1].red-colors1[0].red)<<8)/(int)height;
- dg1 = ((colors1[1].green-colors1[0].green)<<8)/(int)height;
- db1 = ((colors1[1].blue-colors1[0].blue)<<8)/(int)height;
-
- dr2 = ((colors2[1].red-colors2[0].red)<<8)/(int)height;
- dg2 = ((colors2[1].green-colors2[0].green)<<8)/(int)height;
- db2 = ((colors2[1].blue-colors2[0].blue)<<8)/(int)height;
-
- for (i=0,k=0,l=0,ll=thickness1; i<height; i++)
- {
- ptr = pixels + i * rowstride;
-
- if (k == 0)
- {
- ptr[0] = (unsigned char) (r1>>16);
- ptr[1] = (unsigned char) (g1>>16);
- ptr[2] = (unsigned char) (b1>>16);
- }
- else
- {
- ptr[0] = (unsigned char) (r2>>16);
- ptr[1] = (unsigned char) (g2>>16);
- ptr[2] = (unsigned char) (b2>>16);
- }
-
- for (j=1; j <= width/2; j *= 2)
- memcpy (&(ptr[j*3]), ptr, j*3);
- memcpy (&(ptr[j*3]), ptr, (width - j)*3);
-
- if (++l == ll)
- {
- if (k == 0)
- {
- k = 1;
- ll = thickness2;
- }
- else
- {
- k = 0;
- ll = thickness1;
- }
- l = 0;
- }
- r1+=dr1;
- g1+=dg1;
- b1+=db1;
-
- r2+=dr2;
- g2+=dg2;
- b2+=db2;
- }
-
- return pixbuf;
-}
-
-/*
- *----------------------------------------------------------------------
- * meta_gradient_create_horizontal--
- * Renders a horizontal linear gradient of the specified size in the
- * GdkPixbuf format with a border of the specified type.
- *
- * Returns:
- * A 24bit GdkPixbuf with the gradient (no alpha channel).
- *
- * Side effects:
- * None
- *----------------------------------------------------------------------
- */
-static GdkPixbuf*
-meta_gradient_create_horizontal (int width, int height,
- const GdkColor *from,
- const GdkColor *to)
-{
- int i;
- long r, g, b, dr, dg, db;
- GdkPixbuf *pixbuf;
- unsigned char *ptr;
- unsigned char *pixels;
- int r0, g0, b0;
- int rf, gf, bf;
- int rowstride;
-
- pixbuf = blank_pixbuf (width, height, FALSE);
- if (pixbuf == NULL)
- return NULL;
-
- pixels = gdk_pixbuf_get_pixels (pixbuf);
- ptr = pixels;
- rowstride = gdk_pixbuf_get_rowstride (pixbuf);
-
- r0 = (guchar) (from->red / 256.0);
- g0 = (guchar) (from->green / 256.0);
- b0 = (guchar) (from->blue / 256.0);
- rf = (guchar) (to->red / 256.0);
- gf = (guchar) (to->green / 256.0);
- bf = (guchar) (to->blue / 256.0);
-
- r = r0 << 16;
- g = g0 << 16;
- b = b0 << 16;
-
- dr = ((rf-r0)<<16)/(int)width;
- dg = ((gf-g0)<<16)/(int)width;
- db = ((bf-b0)<<16)/(int)width;
- /* render the first line */
- for (i=0; i<width; i++)
- {
- *(ptr++) = (unsigned char)(r>>16);
- *(ptr++) = (unsigned char)(g>>16);
- *(ptr++) = (unsigned char)(b>>16);
- r += dr;
- g += dg;
- b += db;
- }
-
- /* copy the first line to the other lines */
- for (i=1; i<height; i++)
- {
- memcpy (&(pixels[i*rowstride]), pixels, rowstride);
- }
- return pixbuf;
-}
-
-/*
- *----------------------------------------------------------------------
- * meta_gradient_create_vertical--
- * Renders a vertical linear gradient of the specified size in the
- * GdkPixbuf format with a border of the specified type.
- *
- * Returns:
- * A 24bit GdkPixbuf with the gradient (no alpha channel).
- *
- * Side effects:
- * None
- *----------------------------------------------------------------------
- */
-static GdkPixbuf*
-meta_gradient_create_vertical (int width, int height,
- const GdkColor *from,
- const GdkColor *to)
-{
- int i, j;
- long r, g, b, dr, dg, db;
- GdkPixbuf *pixbuf;
- unsigned char *ptr;
- int r0, g0, b0;
- int rf, gf, bf;
- int rowstride;
- unsigned char *pixels;
-
- pixbuf = blank_pixbuf (width, height, FALSE);
- if (pixbuf == NULL)
- return NULL;
-
- pixels = gdk_pixbuf_get_pixels (pixbuf);
- rowstride = gdk_pixbuf_get_rowstride (pixbuf);
-
- r0 = (guchar) (from->red / 256.0);
- g0 = (guchar) (from->green / 256.0);
- b0 = (guchar) (from->blue / 256.0);
- rf = (guchar) (to->red / 256.0);
- gf = (guchar) (to->green / 256.0);
- bf = (guchar) (to->blue / 256.0);
-
- r = r0<<16;
- g = g0<<16;
- b = b0<<16;
-
- dr = ((rf-r0)<<16)/(int)height;
- dg = ((gf-g0)<<16)/(int)height;
- db = ((bf-b0)<<16)/(int)height;
-
- for (i=0; i<height; i++)
- {
- ptr = pixels + i * rowstride;
-
- ptr[0] = (unsigned char)(r>>16);
- ptr[1] = (unsigned char)(g>>16);
- ptr[2] = (unsigned char)(b>>16);
-
- for (j=1; j <= width/2; j *= 2)
- memcpy (&(ptr[j*3]), ptr, j*3);
- memcpy (&(ptr[j*3]), ptr, (width - j)*3);
-
- r+=dr;
- g+=dg;
- b+=db;
- }
- return pixbuf;
-}
-
-
-/*
- *----------------------------------------------------------------------
- * meta_gradient_create_diagonal--
- * Renders a diagonal linear gradient of the specified size in the
- * GdkPixbuf format with a border of the specified type.
- *
- * Returns:
- * A 24bit GdkPixbuf with the gradient (no alpha channel).
- *
- * Side effects:
- * None
- *----------------------------------------------------------------------
- */
-
-
-static GdkPixbuf*
-meta_gradient_create_diagonal (int width, int height,
- const GdkColor *from,
- const GdkColor *to)
-{
- GdkPixbuf *pixbuf, *tmp;
- int j;
- float a, offset;
- unsigned char *ptr;
- unsigned char *pixels;
- int rowstride;
-
- if (width == 1)
- return meta_gradient_create_vertical (width, height, from, to);
- else if (height == 1)
- return meta_gradient_create_horizontal (width, height, from, to);
-
- pixbuf = blank_pixbuf (width, height, FALSE);
- if (pixbuf == NULL)
- return NULL;
-
- pixels = gdk_pixbuf_get_pixels (pixbuf);
- rowstride = gdk_pixbuf_get_rowstride (pixbuf);
-
- tmp = meta_gradient_create_horizontal (2*width-1, 1, from, to);
- if (!tmp)
- {
- g_object_unref (G_OBJECT (pixbuf));
- return NULL;
- }
-
- ptr = gdk_pixbuf_get_pixels (tmp);
-
- a = ((float)(width - 1))/((float)(height - 1));
- width = width * 3;
-
- /* copy the first line to the other lines with corresponding offset */
- for (j=0, offset=0.0; j<rowstride*height; j += rowstride)
- {
- memcpy (&(pixels[j]), &ptr[3*(int)offset], width);
- offset += a;
- }
-
- g_object_unref (G_OBJECT (tmp));
- return pixbuf;
-}
-
-
-static GdkPixbuf*
-meta_gradient_create_multi_horizontal (int width, int height,
- const GdkColor *colors,
- int count)
-{
- int i, j, k;
- long r, g, b, dr, dg, db;
- GdkPixbuf *pixbuf;
- unsigned char *ptr;
- unsigned char *pixels;
- int width2;
- int rowstride;
-
- g_return_val_if_fail (count > 2, NULL);
-
- pixbuf = blank_pixbuf (width, height, FALSE);
- if (pixbuf == NULL)
- return NULL;
-
- pixels = gdk_pixbuf_get_pixels (pixbuf);
- rowstride = gdk_pixbuf_get_rowstride (pixbuf);
- ptr = pixels;
-
- if (count > width)
- count = width;
-
- if (count > 1)
- width2 = width/(count-1);
- else
- width2 = width;
-
- k = 0;
-
- r = colors[0].red << 8;
- g = colors[0].green << 8;
- b = colors[0].blue << 8;
-
- /* render the first line */
- for (i=1; i<count; i++)
- {
- dr = ((int)(colors[i].red - colors[i-1].red) <<8)/(int)width2;
- dg = ((int)(colors[i].green - colors[i-1].green)<<8)/(int)width2;
- db = ((int)(colors[i].blue - colors[i-1].blue) <<8)/(int)width2;
- for (j=0; j<width2; j++)
- {
- *ptr++ = (unsigned char)(r>>16);
- *ptr++ = (unsigned char)(g>>16);
- *ptr++ = (unsigned char)(b>>16);
- r += dr;
- g += dg;
- b += db;
- k++;
- }
- r = colors[i].red << 8;
- g = colors[i].green << 8;
- b = colors[i].blue << 8;
- }
- for (j=k; j<width; j++)
- {
- *ptr++ = (unsigned char)(r>>16);
- *ptr++ = (unsigned char)(g>>16);
- *ptr++ = (unsigned char)(b>>16);
- }
-
- /* copy the first line to the other lines */
- for (i=1; i<height; i++)
- {
- memcpy (&(pixels[i*rowstride]), pixels, rowstride);
- }
- return pixbuf;
-}
-
-static GdkPixbuf*
-meta_gradient_create_multi_vertical (int width, int height,
- const GdkColor *colors,
- int count)
-{
- int i, j, k;
- long r, g, b, dr, dg, db;
- GdkPixbuf *pixbuf;
- unsigned char *ptr, *tmp, *pixels;
- int height2;
- int x;
- int rowstride;
-
- g_return_val_if_fail (count > 2, NULL);
-
- pixbuf = blank_pixbuf (width, height, FALSE);
- if (pixbuf == NULL)
- return NULL;
-
- pixels = gdk_pixbuf_get_pixels (pixbuf);
- rowstride = gdk_pixbuf_get_rowstride (pixbuf);
- ptr = pixels;
-
- if (count > height)
- count = height;
-
- if (count > 1)
- height2 = height/(count-1);
- else
- height2 = height;
-
- k = 0;
-
- r = colors[0].red << 8;
- g = colors[0].green << 8;
- b = colors[0].blue << 8;
-
- for (i=1; i<count; i++)
- {
- dr = ((int)(colors[i].red - colors[i-1].red) <<8)/(int)height2;
- dg = ((int)(colors[i].green - colors[i-1].green)<<8)/(int)height2;
- db = ((int)(colors[i].blue - colors[i-1].blue) <<8)/(int)height2;
-
- for (j=0; j<height2; j++)
- {
- ptr[0] = (unsigned char)(r>>16);
- ptr[1] = (unsigned char)(g>>16);
- ptr[2] = (unsigned char)(b>>16);
-
- for (x=1; x <= width/2; x *= 2)
- memcpy (&(ptr[x*3]), ptr, x*3);
- memcpy (&(ptr[x*3]), ptr, (width - x)*3);
-
- ptr += rowstride;
-
- r += dr;
- g += dg;
- b += db;
- k++;
- }
- r = colors[i].red << 8;
- g = colors[i].green << 8;
- b = colors[i].blue << 8;
- }
-
- if (k<height)
- {
- tmp = ptr;
-
- ptr[0] = (unsigned char) (r>>16);
- ptr[1] = (unsigned char) (g>>16);
- ptr[2] = (unsigned char) (b>>16);
-
- for (x=1; x <= width/2; x *= 2)
- memcpy (&(ptr[x*3]), ptr, x*3);
- memcpy (&(ptr[x*3]), ptr, (width - x)*3);
-
- ptr += rowstride;
-
- for (j=k+1; j<height; j++)
- {
- memcpy (ptr, tmp, rowstride);
- ptr += rowstride;
- }
- }
-
- return pixbuf;
-}
-
-
-static GdkPixbuf*
-meta_gradient_create_multi_diagonal (int width, int height,
- const GdkColor *colors,
- int count)
-{
- GdkPixbuf *pixbuf, *tmp;
- float a, offset;
- int j;
- unsigned char *ptr;
- unsigned char *pixels;
- int rowstride;
-
- g_return_val_if_fail (count > 2, NULL);
-
- if (width == 1)
- return meta_gradient_create_multi_vertical (width, height, colors, count);
- else if (height == 1)
- return meta_gradient_create_multi_horizontal (width, height, colors, count);
-
- pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8,
- width, height);
- if (pixbuf == NULL)
- return NULL;
-
- pixels = gdk_pixbuf_get_pixels (pixbuf);
- rowstride = gdk_pixbuf_get_rowstride (pixbuf);
-
- if (count > width)
- count = width;
- if (count > height)
- count = height;
-
- if (count > 2)
- tmp = meta_gradient_create_multi_horizontal (2*width-1, 1, colors, count);
- else
- /* wrlib multiplies these colors by 256 before passing them in, but
- * I think it's a bug in wrlib, so changed here. I could be wrong
- * though, if we notice two-color multi diagonals not working.
- */
- tmp = meta_gradient_create_horizontal (2*width-1, 1,
- &colors[0], &colors[1]);
-
- if (!tmp)
- {
- g_object_unref (G_OBJECT (pixbuf));
- return NULL;
- }
- ptr = gdk_pixbuf_get_pixels (tmp);
-
- a = ((float)(width - 1))/((float)(height - 1));
- width = width * 3;
-
- /* copy the first line to the other lines with corresponding offset */
- for (j=0, offset=0; j<rowstride*height; j += rowstride)
- {
- memcpy (&(pixels[j]), &ptr[3*(int)offset], width);
- offset += a;
- }
-
- g_object_unref (G_OBJECT (tmp));
- return pixbuf;
-}
-
-static void
-simple_multiply_alpha (GdkPixbuf *pixbuf,
- guchar alpha)
-{
- guchar *pixels;
- int rowstride;
- int height;
- int row;
-
- g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
-
- if (alpha == 255)
- return;
-
- g_assert (gdk_pixbuf_get_has_alpha (pixbuf));
-
- pixels = gdk_pixbuf_get_pixels (pixbuf);
- rowstride = gdk_pixbuf_get_rowstride (pixbuf);
- height = gdk_pixbuf_get_height (pixbuf);
-
- row = 0;
- while (row < height)
- {
- guchar *p;
- guchar *end;
-
- p = pixels + row * rowstride;
- end = p + rowstride;
-
- while (p != end)
- {
- p += 3; /* skip RGB */
-
- /* multiply the two alpha channels. not sure this is right.
- * but some end cases are that if the pixbuf contains 255,
- * then it should be modified to contain "alpha"; if the
- * pixbuf contains 0, it should remain 0.
- */
- /* ((*p / 255.0) * (alpha / 255.0)) * 255; */
- *p = (guchar) (((int) *p * (int) alpha) / (int) 255);
-
- ++p; /* skip A */
- }
-
- ++row;
- }
-}
-
-static void
-meta_gradient_add_alpha_horizontal (GdkPixbuf *pixbuf,
- const unsigned char *alphas,
- int n_alphas)
-{
- int i, j;
- long a, da;
- unsigned char *p;
- unsigned char *pixels;
- int width2;
- int rowstride;
- int width, height;
- unsigned char *gradient;
- unsigned char *gradient_p;
- unsigned char *gradient_end;
-
- g_return_if_fail (n_alphas > 0);
-
- if (n_alphas == 1)
- {
- /* Optimize this */
- simple_multiply_alpha (pixbuf, alphas[0]);
- return;
- }
-
- width = gdk_pixbuf_get_width (pixbuf);
- height = gdk_pixbuf_get_height (pixbuf);
-
- gradient = g_new (unsigned char, width);
- gradient_end = gradient + width;
-
- if (n_alphas > width)
- n_alphas = width;
-
- if (n_alphas > 1)
- width2 = width / (n_alphas - 1);
- else
- width2 = width;
-
- a = alphas[0] << 8;
- gradient_p = gradient;
-
- /* render the gradient into an array */
- for (i = 1; i < n_alphas; i++)
- {
- da = (((int)(alphas[i] - (int) alphas[i-1])) << 8) / (int) width2;
-
- for (j = 0; j < width2; j++)
- {
- *gradient_p++ = (a >> 8);
-
- a += da;
- }
-
- a = alphas[i] << 8;
- }
-
- /* get leftover pixels */
- while (gradient_p != gradient_end)
- {
- *gradient_p++ = a >> 8;
- }
-
- /* Now for each line of the pixbuf, fill in with the gradient */
- pixels = gdk_pixbuf_get_pixels (pixbuf);
- rowstride = gdk_pixbuf_get_rowstride (pixbuf);
-
- p = pixels;
- i = 0;
- while (i < height)
- {
- unsigned char *row_end = p + rowstride;
- gradient_p = gradient;
-
- p += 3;
- while (gradient_p != gradient_end)
- {
- /* multiply the two alpha channels. not sure this is right.
- * but some end cases are that if the pixbuf contains 255,
- * then it should be modified to contain "alpha"; if the
- * pixbuf contains 0, it should remain 0.
- */
- /* ((*p / 255.0) * (alpha / 255.0)) * 255; */
- *p = (guchar) (((int) *p * (int) *gradient_p) / (int) 255);
-
- p += 4;
- ++gradient_p;
- }
-
- p = row_end;
- ++i;
- }
-
- g_free (gradient);
-}
-
-void
-meta_gradient_add_alpha (GdkPixbuf *pixbuf,
- const guchar *alphas,
- int n_alphas,
- MetaGradientType type)
-{
- g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
- g_return_if_fail (gdk_pixbuf_get_has_alpha (pixbuf));
- g_return_if_fail (n_alphas > 0);
-
- switch (type)
- {
- case META_GRADIENT_HORIZONTAL:
- meta_gradient_add_alpha_horizontal (pixbuf, alphas, n_alphas);
- break;
-
- case META_GRADIENT_VERTICAL:
- g_printerr ("metacity: vertical alpha channel gradient not implemented yet\n");
- break;
-
- case META_GRADIENT_DIAGONAL:
- g_printerr ("metacity: diagonal alpha channel gradient not implemented yet\n");
- break;
-
- case META_GRADIENT_LAST:
- g_assert_not_reached ();
- break;
- }
-}
diff --git a/src/ui/gradient.h b/src/ui/gradient.h
deleted file mode 100644
index 16b3985d..00000000
--- a/src/ui/gradient.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity gradient rendering */
-
-/*
- * Copyright (C) 2001 Havoc Pennington, 99% copied from wrlib in
- * WindowMaker, Copyright (C) 1997-2000 Dan Pascu and Alfredo Kojima
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA. */
-
-#ifndef META_GRADIENT_H
-#define META_GRADIENT_H
-
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <gdk/gdk.h>
-
-typedef enum
-{
- META_GRADIENT_VERTICAL,
- META_GRADIENT_HORIZONTAL,
- META_GRADIENT_DIAGONAL,
- META_GRADIENT_LAST
-} MetaGradientType;
-
-GdkPixbuf* meta_gradient_create_simple (int width,
- int height,
- const GdkColor *from,
- const GdkColor *to,
- MetaGradientType style);
-GdkPixbuf* meta_gradient_create_multi (int width,
- int height,
- const GdkColor *colors,
- int n_colors,
- MetaGradientType style);
-GdkPixbuf* meta_gradient_create_interwoven (int width,
- int height,
- const GdkColor colors1[2],
- int thickness1,
- const GdkColor colors2[2],
- int thickness2);
-
-
-/* Generate an alpha gradient and multiply it with the existing alpha
- * channel of the given pixbuf
- */
-void meta_gradient_add_alpha (GdkPixbuf *pixbuf,
- const guchar *alphas,
- int n_alphas,
- MetaGradientType type);
-
-
-#endif
diff --git a/src/ui/menu.c b/src/ui/menu.c
deleted file mode 100644
index 83198979..00000000
--- a/src/ui/menu.c
+++ /dev/null
@@ -1,532 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity window menu */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2004 Rob Adams
- * Copyright (C) 2005 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <string.h>
-#include "menu.h"
-#include "main.h"
-#include "util.h"
-#include "core.h"
-#include "themewidget.h"
-#include "metaaccellabel.h"
-#include "ui.h"
-
-typedef struct _MenuItem MenuItem;
-typedef struct _MenuData MenuData;
-
-typedef enum
-{
- MENU_ITEM_SEPARATOR = 0,
- MENU_ITEM_NORMAL,
- MENU_ITEM_IMAGE,
- MENU_ITEM_CHECKBOX,
- MENU_ITEM_RADIOBUTTON,
- MENU_ITEM_WORKSPACE_LIST,
-} MetaMenuItemType;
-
-struct _MenuItem
-{
- MetaMenuOp op;
- MetaMenuItemType type;
- const char *stock_id;
- const gboolean checked;
- const char *label;
-};
-
-
-struct _MenuData
-{
- MetaWindowMenu *menu;
- MetaMenuOp op;
-};
-
-static void activate_cb (GtkWidget *menuitem, gpointer data);
-
-static MenuItem menuitems[] = {
- /* Translators: Translate this string the same way as you do in libwnck! */
- { META_MENU_OP_MINIMIZE, MENU_ITEM_IMAGE, METACITY_STOCK_MINIMIZE, FALSE, N_("Mi_nimize") },
- /* Translators: Translate this string the same way as you do in libwnck! */
- { META_MENU_OP_MAXIMIZE, MENU_ITEM_IMAGE, METACITY_STOCK_MAXIMIZE, FALSE, N_("Ma_ximize") },
- /* Translators: Translate this string the same way as you do in libwnck! */
- { META_MENU_OP_UNMAXIMIZE, MENU_ITEM_NORMAL, NULL, FALSE, N_("Unma_ximize") },
- /* Translators: Translate this string the same way as you do in libwnck! */
- { META_MENU_OP_SHADE, MENU_ITEM_NORMAL, NULL, FALSE, N_("Roll _Up") },
- /* Translators: Translate this string the same way as you do in libwnck! */
- { META_MENU_OP_UNSHADE, MENU_ITEM_NORMAL, NULL, FALSE, N_("_Unroll") },
- /* Translators: Translate this string the same way as you do in libwnck! */
- { META_MENU_OP_MOVE, MENU_ITEM_NORMAL, NULL, FALSE, N_("_Move") },
- /* Translators: Translate this string the same way as you do in libwnck! */
- { META_MENU_OP_RESIZE, MENU_ITEM_NORMAL, NULL, FALSE, N_("_Resize") },
- /* Translators: Translate this string the same way as you do in libwnck! */
- { META_MENU_OP_RECOVER, MENU_ITEM_NORMAL, NULL, FALSE, N_("Move Titlebar On_screen") },
- { META_MENU_OP_WORKSPACES, MENU_ITEM_SEPARATOR, NULL, FALSE, NULL }, /* separator */
- /* Translators: Translate this string the same way as you do in libwnck! */
- { META_MENU_OP_ABOVE, MENU_ITEM_CHECKBOX, NULL, FALSE, N_("Always on _Top") },
- /* Translators: Translate this string the same way as you do in libwnck! */
- { META_MENU_OP_UNABOVE, MENU_ITEM_CHECKBOX, NULL, TRUE, N_("Always on _Top") },
- /* Translators: Translate this string the same way as you do in libwnck! */
- { META_MENU_OP_STICK, MENU_ITEM_RADIOBUTTON, NULL, FALSE, N_("_Always on Visible Workspace") },
- /* Translators: Translate this string the same way as you do in libwnck! */
- { META_MENU_OP_UNSTICK, MENU_ITEM_RADIOBUTTON, NULL, FALSE, N_("_Only on This Workspace") },
- /* Translators: Translate this string the same way as you do in libwnck! */
- { META_MENU_OP_MOVE_LEFT, MENU_ITEM_NORMAL, NULL, FALSE, N_("Move to Workspace _Left") },
- /* Translators: Translate this string the same way as you do in libwnck! */
- { META_MENU_OP_MOVE_RIGHT, MENU_ITEM_NORMAL, NULL, FALSE, N_("Move to Workspace R_ight") },
- /* Translators: Translate this string the same way as you do in libwnck! */
- { META_MENU_OP_MOVE_UP, MENU_ITEM_NORMAL, NULL, FALSE, N_("Move to Workspace _Up") },
- /* Translators: Translate this string the same way as you do in libwnck! */
- { META_MENU_OP_MOVE_DOWN, MENU_ITEM_NORMAL, NULL, FALSE, N_("Move to Workspace _Down") },
- { 0, MENU_ITEM_WORKSPACE_LIST, NULL, FALSE, NULL },
- { 0, MENU_ITEM_SEPARATOR, NULL, FALSE, NULL }, /* separator */
- /* Translators: Translate this string the same way as you do in libwnck! */
- { META_MENU_OP_DELETE, MENU_ITEM_IMAGE, METACITY_STOCK_DELETE, FALSE, N_("_Close") }
-};
-
-static void
-popup_position_func (GtkMenu *menu,
- gint *x,
- gint *y,
- gboolean *push_in,
- gpointer user_data)
-{
- GtkRequisition req;
- GdkPoint *pos;
-
- pos = user_data;
-
- gtk_widget_size_request (GTK_WIDGET (menu), &req);
-
- *x = pos->x;
- *y = pos->y;
-
- if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
- *x = MAX (0, *x - req.width);
-
- /* Ensure onscreen */
- *x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width));
- *y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height));
-}
-
-static void
-menu_closed (GtkMenu *widget,
- gpointer data)
-{
- MetaWindowMenu *menu;
-
- menu = data;
-
- meta_frames_notify_menu_hide (menu->frames);
- (* menu->func) (menu, gdk_display,
- menu->client_xwindow,
- gtk_get_current_event_time (),
- 0, 0,
- menu->data);
-
- /* menu may now be freed */
-}
-
-static void
-activate_cb (GtkWidget *menuitem, gpointer data)
-{
- MenuData *md;
-
- g_return_if_fail (GTK_IS_WIDGET (menuitem));
-
- md = data;
-
- meta_frames_notify_menu_hide (md->menu->frames);
- (* md->menu->func) (md->menu, gdk_display,
- md->menu->client_xwindow,
- gtk_get_current_event_time (),
- md->op,
- GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem),
- "workspace")),
- md->menu->data);
-
- /* menu may now be freed */
-}
-
-/*
- * Given a Display and an index, get the workspace name and add any
- * accelerators. At the moment this means adding a _ if the name is of
- * the form "Workspace n" where n is less than 10, and escaping any
- * other '_'s so they do not create inadvertant accelerators.
- *
- * The calling code owns the string, and is reponsible to free the
- * memory after use.
- *
- * See also http://mail.gnome.org/archives/gnome-i18n/2008-March/msg00380.html
- * which discusses possible i18n concerns.
- */
-static char*
-get_workspace_name_with_accel (Display *display,
- Window xroot,
- int index)
-{
- const char *name;
- int number;
- int charcount=0;
-
- name = meta_core_get_workspace_name_with_index (display, xroot, index);
-
- g_assert (name != NULL);
-
- /*
- * If the name is of the form "Workspace x" where x is an unsigned
- * integer, insert a '_' before the number if it is less than 10 and
- * return it
- */
- number = 0;
- if (sscanf (name, _("Workspace %d%n"), &number, &charcount) != 0 &&
- *(name + charcount)=='\0')
- {
- char *new_name;
-
- /*
- * Above name is a pointer into the Workspace struct. Here we make
- * a copy copy so we can have our wicked way with it.
- */
- if (number == 10)
- new_name = g_strdup_printf (_("Workspace 1_0"));
- else
- new_name = g_strdup_printf (_("Workspace %s%d"),
- number < 10 ? "_" : "",
- number);
- return new_name;
- }
- else
- {
- /*
- * Otherwise this is just a normal name. Escape any _ characters so that
- * the user's workspace names do not get mangled. If the number is less
- * than 10 we provide an accelerator.
- */
- char *new_name;
- const char *source;
- char *dest;
-
- /*
- * Assume the worst case, that every character is a _. We also
- * provide memory for " (_#)"
- */
- new_name = g_malloc0 (strlen (name) * 2 + 6 + 1);
-
- /*
- * Now iterate down the strings, adding '_' to escape as we go
- */
- dest = new_name;
- source = name;
- while (*source != '\0')
- {
- if (*source == '_')
- *dest++ = '_';
- *dest++ = *source++;
- }
-
- /* People don't start at workspace 0, but workspace 1 */
- if (index < 9)
- {
- g_snprintf (dest, 6, " (_%d)", index + 1);
- }
- else if (index == 9)
- {
- g_snprintf (dest, 6, " (_0)");
- }
-
- return new_name;
- }
-}
-
-static GtkWidget *
-menu_item_new (MenuItem *menuitem, int workspace_id)
-{
- unsigned int key;
- MetaVirtualModifier mods;
- const char *i18n_label;
- GtkWidget *mi;
- GtkWidget *accel_label;
-
- if (menuitem->type == MENU_ITEM_NORMAL)
- {
- mi = gtk_menu_item_new ();
- }
- else if (menuitem->type == MENU_ITEM_IMAGE)
- {
- GtkWidget *image;
-
- image = gtk_image_new_from_stock (menuitem->stock_id, GTK_ICON_SIZE_MENU);
- mi = gtk_image_menu_item_new ();
-
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), image);
- gtk_widget_show (image);
- }
- else if (menuitem->type == MENU_ITEM_CHECKBOX)
- {
- mi = gtk_check_menu_item_new ();
-
- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
- menuitem->checked);
- }
- else if (menuitem->type == MENU_ITEM_RADIOBUTTON)
- {
- mi = gtk_check_menu_item_new ();
-
- gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (mi),
- TRUE);
- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
- menuitem->checked);
- }
- else if (menuitem->type == MENU_ITEM_WORKSPACE_LIST)
- return NULL;
- else
- return gtk_separator_menu_item_new ();
-
- i18n_label = _(menuitem->label);
- meta_core_get_menu_accelerator (menuitem->op, workspace_id, &key, &mods);
-
- accel_label = meta_accel_label_new_with_mnemonic (i18n_label);
- gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5);
-
- gtk_container_add (GTK_CONTAINER (mi), accel_label);
- gtk_widget_show (accel_label);
-
- meta_accel_label_set_accelerator (META_ACCEL_LABEL (accel_label),
- key, mods);
-
- return mi;
-}
-
-MetaWindowMenu*
-meta_window_menu_new (MetaFrames *frames,
- MetaMenuOp ops,
- MetaMenuOp insensitive,
- Window client_xwindow,
- unsigned long active_workspace,
- int n_workspaces,
- MetaWindowMenuFunc func,
- gpointer data)
-{
- int i;
- MetaWindowMenu *menu;
-
- /* FIXME: Modifications to 'ops' should happen in meta_window_show_menu */
- if (n_workspaces < 2)
- ops &= ~(META_MENU_OP_STICK | META_MENU_OP_UNSTICK | META_MENU_OP_WORKSPACES);
- else if (n_workspaces == 2)
- /* #151183: If we only have two workspaces, disable the menu listing them. */
- ops &= ~(META_MENU_OP_WORKSPACES);
-
- menu = g_new (MetaWindowMenu, 1);
- menu->frames = frames;
- menu->client_xwindow = client_xwindow;
- menu->func = func;
- menu->data = data;
- menu->ops = ops;
- menu->insensitive = insensitive;
-
- menu->menu = gtk_menu_new ();
-
- gtk_menu_set_screen (GTK_MENU (menu->menu),
- gtk_widget_get_screen (GTK_WIDGET (frames)));
-
- for (i = 0; i < (int) G_N_ELEMENTS (menuitems); i++)
- {
- MenuItem menuitem = menuitems[i];
- if (ops & menuitem.op || menuitem.op == 0)
- {
- GtkWidget *mi;
- MenuData *md;
- unsigned int key;
- MetaVirtualModifier mods;
-
- mi = menu_item_new (&menuitem, -1);
-
- /* Set the activeness of radiobuttons. */
- switch (menuitem.op)
- {
- case META_MENU_OP_STICK:
- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
- active_workspace == 0xFFFFFFFF);
- break;
- case META_MENU_OP_UNSTICK:
- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
- active_workspace != 0xFFFFFFFF);
- break;
- default:
- break;
- }
-
- if (menuitem.type == MENU_ITEM_WORKSPACE_LIST)
- {
- if (ops & META_MENU_OP_WORKSPACES)
- {
- Display *display;
- Window xroot;
- GdkScreen *screen;
- GtkWidget *submenu;
- int j;
-
- MenuItem to_another_workspace = {
- 0, MENU_ITEM_NORMAL,
- NULL, FALSE,
- N_("Move to Another _Workspace")
- };
-
- meta_verbose ("Creating %d-workspace menu current space %lu\n",
- n_workspaces, active_workspace);
-
- display = gdk_x11_drawable_get_xdisplay (GTK_WIDGET (frames)->window);
-
- screen = gdk_drawable_get_screen (GTK_WIDGET (frames)->window);
- xroot = GDK_DRAWABLE_XID (gdk_screen_get_root_window (screen));
-
- submenu = gtk_menu_new ();
-
- g_assert (mi==NULL);
- mi = menu_item_new (&to_another_workspace, -1);
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), submenu);
-
- for (j = 0; j < n_workspaces; j++)
- {
- char *label;
- MenuData *md;
- unsigned int key;
- MetaVirtualModifier mods;
- MenuItem moveitem;
- GtkWidget *submi;
-
- meta_core_get_menu_accelerator (META_MENU_OP_WORKSPACES,
- j + 1,
- &key, &mods);
-
- label = get_workspace_name_with_accel (display, xroot, j);
-
- moveitem.type = MENU_ITEM_NORMAL;
- moveitem.op = META_MENU_OP_WORKSPACES;
- moveitem.label = label;
- submi = menu_item_new (&moveitem, j + 1);
-
- g_free (label);
-
- if ((active_workspace == (unsigned)j) && (ops & META_MENU_OP_UNSTICK))
- gtk_widget_set_sensitive (submi, FALSE);
-
- md = g_new (MenuData, 1);
-
- md->menu = menu;
- md->op = META_MENU_OP_WORKSPACES;
-
- g_object_set_data (G_OBJECT (submi),
- "workspace",
- GINT_TO_POINTER (j));
-
- gtk_signal_connect_full (GTK_OBJECT (submi),
- "activate",
- GTK_SIGNAL_FUNC (activate_cb),
- NULL,
- md,
- g_free, FALSE, FALSE);
-
- gtk_menu_shell_append (GTK_MENU_SHELL (submenu), submi);
-
- gtk_widget_show (submi);
- }
- }
- else
- meta_verbose ("not creating workspace menu\n");
- }
- else if (menuitem.type != MENU_ITEM_SEPARATOR)
- {
- meta_core_get_menu_accelerator (menuitems[i].op, -1,
- &key, &mods);
-
- if (insensitive & menuitem.op)
- gtk_widget_set_sensitive (mi, FALSE);
-
- md = g_new (MenuData, 1);
-
- md->menu = menu;
- md->op = menuitem.op;
-
- gtk_signal_connect_full (GTK_OBJECT (mi),
- "activate",
- GTK_SIGNAL_FUNC (activate_cb),
- NULL,
- md,
- g_free, FALSE, FALSE);
- }
-
- if (mi)
- {
- gtk_menu_shell_append (GTK_MENU_SHELL (menu->menu), mi);
-
- gtk_widget_show (mi);
- }
- }
- }
-
-
- g_signal_connect (menu->menu, "selection_done",
- G_CALLBACK (menu_closed), menu);
-
- return menu;
-}
-
-void
-meta_window_menu_popup (MetaWindowMenu *menu,
- int root_x,
- int root_y,
- int button,
- guint32 timestamp)
-{
- GdkPoint *pt;
-
- pt = g_new (GdkPoint, 1);
-
- g_object_set_data_full (G_OBJECT (menu->menu),
- "destroy-point",
- pt,
- g_free);
-
- pt->x = root_x;
- pt->y = root_y;
-
- gtk_menu_popup (GTK_MENU (menu->menu),
- NULL, NULL,
- popup_position_func, pt,
- button,
- timestamp);
-
- if (!GTK_MENU_SHELL (menu->menu)->have_xgrab)
- meta_warning ("GtkMenu failed to grab the pointer\n");
-}
-
-void
-meta_window_menu_free (MetaWindowMenu *menu)
-{
- gtk_widget_destroy (menu->menu);
- g_free (menu);
-}
diff --git a/src/ui/menu.h b/src/ui/menu.h
deleted file mode 100644
index 39bb7fa3..00000000
--- a/src/ui/menu.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity window menu */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_MENU_H
-#define META_MENU_H
-
-#include <gtk/gtk.h>
-#include "frames.h"
-
-/* Stock icons */
-#define METACITY_STOCK_DELETE "metacity-delete"
-#define METACITY_STOCK_MINIMIZE "metacity-minimize"
-#define METACITY_STOCK_MAXIMIZE "metacity-maximize"
-
-struct _MetaWindowMenu
-{
- MetaFrames *frames;
- Window client_xwindow;
- GtkWidget *menu;
- MetaWindowMenuFunc func;
- gpointer data;
- MetaMenuOp ops;
- MetaMenuOp insensitive;
-};
-
-MetaWindowMenu* meta_window_menu_new (MetaFrames *frames,
- MetaMenuOp ops,
- MetaMenuOp insensitive,
- Window client_xwindow,
- unsigned long active_workspace,
- int n_workspaces,
- MetaWindowMenuFunc func,
- gpointer data);
-void meta_window_menu_popup (MetaWindowMenu *menu,
- int root_x,
- int root_y,
- int button,
- guint32 timestamp);
-void meta_window_menu_free (MetaWindowMenu *menu);
-
-
-#endif
diff --git a/src/ui/metaaccellabel.c b/src/ui/metaaccellabel.c
deleted file mode 100644
index d5233042..00000000
--- a/src/ui/metaaccellabel.c
+++ /dev/null
@@ -1,456 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity hacked-up GtkAccelLabel */
-/* Copyright (C) 2002 Red Hat, Inc. */
-/* GTK - The GIMP Toolkit
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * MetaAccelLabel: GtkLabel with accelerator monitoring facilities.
- * Copyright (C) 1998 Tim Janik
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/*
- * Modified by the GTK+ Team and others 1997-2001. See the AUTHORS
- * file for a list of people on the GTK+ Team. See the ChangeLog
- * files for a list of changes. These files are distributed with
- * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
- */
-
-#include <config.h>
-#include "metaaccellabel.h"
-#include <gtk/gtk.h>
-#include <string.h>
-#include "util.h"
-
-static void meta_accel_label_class_init (MetaAccelLabelClass *klass);
-static void meta_accel_label_init (MetaAccelLabel *accel_label);
-static void meta_accel_label_destroy (GtkObject *object);
-static void meta_accel_label_finalize (GObject *object);
-static void meta_accel_label_size_request (GtkWidget *widget,
- GtkRequisition *requisition);
-static gboolean meta_accel_label_expose_event (GtkWidget *widget,
- GdkEventExpose *event);
-
-static void meta_accel_label_update (MetaAccelLabel *accel_label);
-static int meta_accel_label_get_accel_width (MetaAccelLabel *accel_label);
-
-
-static GtkLabelClass *parent_class = NULL;
-
-
-GtkType
-meta_accel_label_get_type (void)
-{
- static GtkType accel_label_type = 0;
-
- if (!accel_label_type)
- {
- static const GtkTypeInfo accel_label_info =
- {
- "MetaAccelLabel",
- sizeof (MetaAccelLabel),
- sizeof (MetaAccelLabelClass),
- (GtkClassInitFunc) meta_accel_label_class_init,
- (GtkObjectInitFunc) meta_accel_label_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- accel_label_type = gtk_type_unique (GTK_TYPE_LABEL, &accel_label_info);
- }
-
- return accel_label_type;
-}
-
-static void
-meta_accel_label_class_init (MetaAccelLabelClass *class)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (class);
- GtkObjectClass *object_class = GTK_OBJECT_CLASS (class);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
-
- parent_class = g_type_class_peek_parent (class);
-
- gobject_class->finalize = meta_accel_label_finalize;
-
- object_class->destroy = meta_accel_label_destroy;
-
- widget_class->size_request = meta_accel_label_size_request;
- widget_class->expose_event = meta_accel_label_expose_event;
-
- class->signal_quote1 = g_strdup ("<:");
- class->signal_quote2 = g_strdup (":>");
- /* This is the text that should appear next to menu accelerators
- * that use the shift key. If the text on this key isn't typically
- * translated on keyboards used for your language, don't translate
- * this.
- */
- class->mod_name_shift = g_strdup (_("Shift"));
- /* This is the text that should appear next to menu accelerators
- * that use the control key. If the text on this key isn't typically
- * translated on keyboards used for your language, don't translate
- * this.
- */
- class->mod_name_control = g_strdup (_("Ctrl"));
- /* This is the text that should appear next to menu accelerators
- * that use the alt key. If the text on this key isn't typically
- * translated on keyboards used for your language, don't translate
- * this.
- */
- class->mod_name_alt = g_strdup (_("Alt"));
- /* This is the text that should appear next to menu accelerators
- * that use the meta key. If the text on this key isn't typically
- * translated on keyboards used for your language, don't translate
- * this.
- */
- class->mod_name_meta = g_strdup (_("Meta"));
- /* This is the text that should appear next to menu accelerators
- * that use the super key. If the text on this key isn't typically
- * translated on keyboards used for your language, don't translate
- * this.
- */
- class->mod_name_super = g_strdup (_("Super"));
- /* This is the text that should appear next to menu accelerators
- * that use the hyper key. If the text on this key isn't typically
- * translated on keyboards used for your language, don't translate
- * this.
- */
- class->mod_name_hyper = g_strdup (_("Hyper"));
- /* This is the text that should appear next to menu accelerators
- * that use the mod2 key. If the text on this key isn't typically
- * translated on keyboards used for your language, don't translate
- * this.
- */
- class->mod_name_mod2 = g_strdup (_("Mod2"));
- /* This is the text that should appear next to menu accelerators
- * that use the mod3 key. If the text on this key isn't typically
- * translated on keyboards used for your language, don't translate
- * this.
- */
- class->mod_name_mod3 = g_strdup (_("Mod3"));
- /* This is the text that should appear next to menu accelerators
- * that use the mod4 key. If the text on this key isn't typically
- * translated on keyboards used for your language, don't translate
- * this.
- */
- class->mod_name_mod4 = g_strdup (_("Mod4"));
- /* This is the text that should appear next to menu accelerators
- * that use the mod5 key. If the text on this key isn't typically
- * translated on keyboards used for your language, don't translate
- * this.
- */
- class->mod_name_mod5 = g_strdup (_("Mod5"));
-
- class->mod_separator = g_strdup ("+");
- class->accel_seperator = g_strdup (" / ");
- class->latin1_to_char = TRUE;
-}
-
-static void
-meta_accel_label_init (MetaAccelLabel *accel_label)
-{
- accel_label->accel_padding = 3;
- accel_label->accel_string = NULL;
-
- meta_accel_label_update (accel_label);
-}
-
-GtkWidget*
-meta_accel_label_new_with_mnemonic (const gchar *string)
-{
- MetaAccelLabel *accel_label;
-
- g_return_val_if_fail (string != NULL, NULL);
-
- accel_label = g_object_new (META_TYPE_ACCEL_LABEL, NULL);
-
- gtk_label_set_text_with_mnemonic (GTK_LABEL (accel_label), string);
-
- return GTK_WIDGET (accel_label);
-}
-
-static void
-meta_accel_label_destroy (GtkObject *object)
-{
- MetaAccelLabel *accel_label = META_ACCEL_LABEL (object);
-
-
- g_free (accel_label->accel_string);
- accel_label->accel_string = NULL;
-
- accel_label->accel_mods = 0;
- accel_label->accel_key = 0;
-
- GTK_OBJECT_CLASS (parent_class)->destroy (object);
-}
-
-static void
-meta_accel_label_finalize (GObject *object)
-{
- MetaAccelLabel *accel_label = META_ACCEL_LABEL (object);
-
- g_free (accel_label->accel_string);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-void
-meta_accel_label_set_accelerator (MetaAccelLabel *accel_label,
- guint accelerator_key,
- MetaVirtualModifier accelerator_mods)
-{
- g_return_if_fail (META_IS_ACCEL_LABEL (accel_label));
-
- if (accelerator_key != accel_label->accel_key ||
- accelerator_mods != accel_label->accel_mods)
- {
- accel_label->accel_mods = accelerator_mods;
- accel_label->accel_key = accelerator_key;
-
- meta_accel_label_update (accel_label);
- }
-}
-
-static int
-meta_accel_label_get_accel_width (MetaAccelLabel *accel_label)
-{
- g_return_val_if_fail (META_IS_ACCEL_LABEL (accel_label), 0);
-
- return (accel_label->accel_string_width +
- (accel_label->accel_string_width ? accel_label->accel_padding : 0));
-}
-
-static void
-meta_accel_label_size_request (GtkWidget *widget,
- GtkRequisition *requisition)
-{
- MetaAccelLabel *accel_label = META_ACCEL_LABEL (widget);
- PangoLayout *layout;
- gint width;
-
- if (GTK_WIDGET_CLASS (parent_class)->size_request)
- GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition);
-
- layout = gtk_widget_create_pango_layout (widget, accel_label->accel_string);
- pango_layout_get_pixel_size (layout, &width, NULL);
- accel_label->accel_string_width = width;
-
- g_object_unref (G_OBJECT (layout));
-}
-
-static gboolean
-meta_accel_label_expose_event (GtkWidget *widget,
- GdkEventExpose *event)
-{
- MetaAccelLabel *accel_label = META_ACCEL_LABEL (widget);
- GtkMisc *misc = GTK_MISC (accel_label);
- PangoLayout *layout;
-
- if (GTK_WIDGET_DRAWABLE (accel_label))
- {
- int ac_width;
-
- ac_width = meta_accel_label_get_accel_width (accel_label);
-
- if (widget->allocation.width >= widget->requisition.width + ac_width)
- {
- GtkTextDirection direction = gtk_widget_get_direction (widget);
- gint x;
- gint y;
-
- if (direction == GTK_TEXT_DIR_RTL)
- {
- widget->allocation.x += ac_width;
- }
- widget->allocation.width -= ac_width;
-
- if (GTK_WIDGET_CLASS (parent_class)->expose_event)
- GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
-
- if (direction == GTK_TEXT_DIR_RTL)
- {
- widget->allocation.x -= ac_width;
- }
- widget->allocation.width += ac_width;
-
- if (direction == GTK_TEXT_DIR_RTL)
- {
- x = widget->allocation.x + misc->xpad;
- }
- else
- {
- x = widget->allocation.x + widget->allocation.width - misc->xpad - ac_width;
- }
-
- y = (widget->allocation.y * (1.0 - misc->yalign) +
- (widget->allocation.y + widget->allocation.height -
- (widget->requisition.height - misc->ypad * 2)) *
- misc->yalign) + 1.5;
-
- layout = gtk_widget_create_pango_layout (widget, accel_label->accel_string);
-
- gtk_paint_layout (widget->style,
- widget->window,
- GTK_WIDGET_STATE (widget),
- FALSE,
- &event->area,
- widget,
- "accellabel",
- x, y,
- layout);
-
- g_object_unref (G_OBJECT (layout));
- }
- else
- {
- if (GTK_WIDGET_CLASS (parent_class)->expose_event)
- GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
- }
- }
-
- return FALSE;
-}
-
-static void
-meta_accel_label_update (MetaAccelLabel *accel_label)
-{
- MetaAccelLabelClass *class;
- GString *gstring;
- gboolean seen_mod = FALSE;
- gunichar ch;
-
- g_return_if_fail (META_IS_ACCEL_LABEL (accel_label));
-
- class = META_ACCEL_LABEL_GET_CLASS (accel_label);
-
- g_free (accel_label->accel_string);
- accel_label->accel_string = NULL;
-
- gstring = g_string_new (accel_label->accel_string);
- g_string_append (gstring, gstring->len ? class->accel_seperator : " ");
-
- if (accel_label->accel_mods & META_VIRTUAL_SHIFT_MASK)
- {
- g_string_append (gstring, class->mod_name_shift);
- seen_mod = TRUE;
- }
- if (accel_label->accel_mods & META_VIRTUAL_CONTROL_MASK)
- {
- if (seen_mod)
- g_string_append (gstring, class->mod_separator);
- g_string_append (gstring, class->mod_name_control);
- seen_mod = TRUE;
- }
- if (accel_label->accel_mods & META_VIRTUAL_ALT_MASK)
- {
- if (seen_mod)
- g_string_append (gstring, class->mod_separator);
- g_string_append (gstring, class->mod_name_alt);
- seen_mod = TRUE;
- }
- if (accel_label->accel_mods & META_VIRTUAL_META_MASK)
- {
- if (seen_mod)
- g_string_append (gstring, class->mod_separator);
- g_string_append (gstring, class->mod_name_meta);
- seen_mod = TRUE;
- }
- if (accel_label->accel_mods & META_VIRTUAL_SUPER_MASK)
- {
- if (seen_mod)
- g_string_append (gstring, class->mod_separator);
- g_string_append (gstring, class->mod_name_super);
- seen_mod = TRUE;
- }
- if (accel_label->accel_mods & META_VIRTUAL_HYPER_MASK)
- {
- if (seen_mod)
- g_string_append (gstring, class->mod_separator);
- g_string_append (gstring, class->mod_name_hyper);
- seen_mod = TRUE;
- }
- if (accel_label->accel_mods & META_VIRTUAL_MOD2_MASK)
- {
- if (seen_mod)
- g_string_append (gstring, class->mod_separator);
- g_string_append (gstring, class->mod_name_mod2);
- seen_mod = TRUE;
- }
- if (accel_label->accel_mods & META_VIRTUAL_MOD3_MASK)
- {
- if (seen_mod)
- g_string_append (gstring, class->mod_separator);
- g_string_append (gstring, class->mod_name_mod3);
- seen_mod = TRUE;
- }
- if (accel_label->accel_mods & META_VIRTUAL_MOD4_MASK)
- {
- if (seen_mod)
- g_string_append (gstring, class->mod_separator);
- g_string_append (gstring, class->mod_name_mod4);
- seen_mod = TRUE;
- }
- if (accel_label->accel_mods & META_VIRTUAL_MOD5_MASK)
- {
- if (seen_mod)
- g_string_append (gstring, class->mod_separator);
- g_string_append (gstring, class->mod_name_mod5);
- seen_mod = TRUE;
- }
-
- if (seen_mod)
- g_string_append (gstring, class->mod_separator);
-
- ch = gdk_keyval_to_unicode (accel_label->accel_key);
- if (ch && (g_unichar_isgraph (ch) || ch == ' ') &&
- (ch < 0x80 || class->latin1_to_char))
- {
- switch (ch)
- {
- case ' ':
- g_string_append (gstring, "Space");
- break;
- case '\\':
- g_string_append (gstring, "Backslash");
- break;
- default:
- g_string_append_unichar (gstring, g_unichar_toupper (ch));
- break;
- }
- }
- else
- {
- gchar *tmp;
-
- tmp = gtk_accelerator_name (accel_label->accel_key, 0);
- if (tmp[0] != 0 && tmp[1] == 0)
- tmp[0] = g_ascii_toupper (tmp[0]);
- g_string_append (gstring, tmp);
- g_free (tmp);
- }
-
- g_free (accel_label->accel_string);
- accel_label->accel_string = gstring->str;
- g_string_free (gstring, FALSE);
-
- g_assert (accel_label->accel_string);
- /* accel_label->accel_string = g_strdup ("-/-"); */
-
- gtk_widget_queue_resize (GTK_WIDGET (accel_label));
-}
diff --git a/src/ui/metaaccellabel.h b/src/ui/metaaccellabel.h
deleted file mode 100644
index 4fb8ed5d..00000000
--- a/src/ui/metaaccellabel.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity hacked-up GtkAccelLabel */
-/* Copyright (C) 2002 Red Hat, Inc. */
-/* GTK - The GIMP Toolkit
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * MetaAccelLabel: GtkLabel with accelerator monitoring facilities.
- * Copyright (C) 1998 Tim Janik
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/*
- * Modified by the GTK+ Team and others 1997-2001. See the AUTHORS
- * file for a list of people on the GTK+ Team. See the ChangeLog
- * files for a list of changes. These files are distributed with
- * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
- */
-
-#ifndef __META_ACCEL_LABEL_H__
-#define __META_ACCEL_LABEL_H__
-
-#include <gtk/gtk.h>
-#include "common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-#define META_TYPE_ACCEL_LABEL (meta_accel_label_get_type ())
-#define META_ACCEL_LABEL(obj) (GTK_CHECK_CAST ((obj), META_TYPE_ACCEL_LABEL, MetaAccelLabel))
-#define META_ACCEL_LABEL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), META_TYPE_ACCEL_LABEL, MetaAccelLabelClass))
-#define META_IS_ACCEL_LABEL(obj) (GTK_CHECK_TYPE ((obj), META_TYPE_ACCEL_LABEL))
-#define META_IS_ACCEL_LABEL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), META_TYPE_ACCEL_LABEL))
-#define META_ACCEL_LABEL_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), META_TYPE_ACCEL_LABEL, MetaAccelLabelClass))
-
-
-typedef struct _MetaAccelLabel MetaAccelLabel;
-typedef struct _MetaAccelLabelClass MetaAccelLabelClass;
-
-struct _MetaAccelLabel
-{
- GtkLabel label;
-
- MetaVirtualModifier accel_mods;
- guint accel_key;
- guint accel_padding;
- gchar *accel_string;
- guint16 accel_string_width;
-};
-
-struct _MetaAccelLabelClass
-{
- GtkLabelClass parent_class;
-
- gchar *signal_quote1;
- gchar *signal_quote2;
- gchar *mod_name_shift;
- gchar *mod_name_control;
- gchar *mod_name_alt;
- gchar *mod_name_meta;
- gchar *mod_name_super;
- gchar *mod_name_hyper;
- gchar *mod_name_mod2;
- gchar *mod_name_mod3;
- gchar *mod_name_mod4;
- gchar *mod_name_mod5;
- gchar *mod_separator;
- gchar *accel_seperator;
- guint latin1_to_char : 1;
-
- /* Padding for future expansion */
- void (*_gtk_reserved1) (void);
- void (*_gtk_reserved2) (void);
- void (*_gtk_reserved3) (void);
- void (*_gtk_reserved4) (void);
-};
-
-GtkType meta_accel_label_get_type (void) G_GNUC_CONST;
-GtkWidget* meta_accel_label_new_with_mnemonic (const gchar *string);
-void meta_accel_label_set_accelerator (MetaAccelLabel *accel_label,
- guint accelerator_key,
- MetaVirtualModifier accelerator_mods);
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* __META_ACCEL_LABEL_H__ */
diff --git a/src/ui/metacity-dialog.c b/src/ui/metacity-dialog.c
deleted file mode 100644
index d47a9b3e..00000000
--- a/src/ui/metacity-dialog.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity dialog process */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2004 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include <gtk/gtk.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <libintl.h>
-#define _(x) dgettext (GETTEXT_PACKAGE, x)
-#define N_(x) x
-
-#include <gdk/gdkx.h>
-#include <X11/Xatom.h>
-
-static Window
-window_from_string (const char *str)
-{
- char *end;
- unsigned long l;
-
- end = NULL;
-
- l = strtoul (str, &end, 16);
-
- if (end == NULL || end == str)
- {
- g_printerr (_("Could not parse \"%s\" as an integer"),
- str);
- return None;
- }
-
- if (*end != '\0')
- {
- g_printerr (_("Did not understand trailing characters \"%s\" in string \"%s\""),
- end, str);
- return None;
- }
-
- return l;
-}
-
-static void
-on_realize (GtkWidget *dialog,
- void *data)
-{
- const char *parent_str = data;
- Window xwindow;
-
- xwindow = window_from_string (parent_str);
-
- gdk_error_trap_push ();
- XSetTransientForHint (gdk_display, GDK_WINDOW_XID (dialog->window),
- xwindow);
- XSync (gdk_display, False);
- gdk_error_trap_pop ();
-}
-
-static int
-kill_window_question (const char *window_name,
- const char *parent_str,
- guint32 timestamp)
-{
- GtkWidget *dialog;
- char *str, *tmp;
-
- tmp = g_markup_escape_text (window_name, -1);
- str = g_strdup_printf (_("\"%s\" is not responding."), tmp);
- g_free (tmp);
- dialog = gtk_message_dialog_new (NULL, 0,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_NONE,
- "<big><b>%s</b></big>\n\n<i>%s</i>",
- str,
- _("You may choose to wait a short while "
- "for it to continue or force the application "
- "to quit entirely."));
- g_free (str);
- gtk_window_set_icon_name (GTK_WINDOW (dialog), "stock_dialog-warning");
-
- gtk_label_set_use_markup (GTK_LABEL (GTK_MESSAGE_DIALOG (dialog)->label), TRUE);
- gtk_label_set_line_wrap (GTK_LABEL (GTK_MESSAGE_DIALOG (dialog)->label), TRUE);
-
- gtk_dialog_add_buttons (GTK_DIALOG (dialog),
- _("_Wait"),
- GTK_RESPONSE_REJECT,
- _("_Force Quit"),
- GTK_RESPONSE_ACCEPT,
- NULL);
-
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_REJECT);
-
- g_signal_connect (G_OBJECT (dialog), "realize",
- G_CALLBACK (on_realize), (char*) parent_str);
-
- gtk_widget_realize (dialog);
- gdk_x11_window_set_user_time (dialog->window, timestamp);
-
- /* return our PID, then window ID that should be killed */
- if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
- g_print ("%d\n%s\n", (int) getpid (), parent_str);
- else
- g_print ("%d\n0x0\n", (int) getpid ());
-
- return 0;
-}
-
-static char*
-latin1_to_utf8 (const char *text)
-{
- GString *str;
- const char *p;
-
- str = g_string_new ("");
-
- p = text;
- while (*p)
- {
- g_string_append_unichar (str, *p);
- ++p;
- }
-
- return g_string_free (str, FALSE);
-}
-
-enum
-{
- COLUMN_TITLE,
- COLUMN_CLASS,
- COLUMN_LAST
-};
-
-static GtkWidget*
-create_lame_apps_list (char **lame_apps)
-{
- GtkTreeSelection *selection;
- GtkCellRenderer *cell;
- GtkWidget *tree_view;
- GtkTreeViewColumn *column;
- GtkListStore *model;
- GtkTreeIter iter;
- int i;
-
- model = gtk_list_store_new (COLUMN_LAST,
- G_TYPE_STRING,
- G_TYPE_STRING);
-
- tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
-
- g_object_unref (G_OBJECT (model));
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
-
- gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection),
- GTK_SELECTION_NONE);
-
- i = 0;
- while (lame_apps[i])
- {
- char *s;
-
- gtk_list_store_append (model, &iter);
-
- /* window class is latin-1 */
- s = latin1_to_utf8 (lame_apps[i+1]);
-
- gtk_list_store_set (model,
- &iter,
- COLUMN_TITLE, lame_apps[i],
- COLUMN_CLASS, s,
- -1);
-
- g_free (s);
-
- i += 2;
- }
-
- cell = gtk_cell_renderer_text_new ();
-
- g_object_set (G_OBJECT (cell),
- "xpad", 2,
- NULL);
-
- column = gtk_tree_view_column_new_with_attributes (_("Title"),
- cell,
- "text", COLUMN_TITLE,
- NULL);
-
- gtk_tree_view_column_set_sort_column_id (column, COLUMN_TITLE);
-
- gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view),
- GTK_TREE_VIEW_COLUMN (column));
-
- cell = gtk_cell_renderer_text_new ();
-
- column = gtk_tree_view_column_new_with_attributes (_("Class"),
- cell,
- "text", COLUMN_CLASS,
- NULL);
-
- gtk_tree_view_column_set_sort_column_id (column, COLUMN_CLASS);
-
- gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view),
- GTK_TREE_VIEW_COLUMN (column));
-
- return tree_view;
-}
-
-static int
-warn_about_no_sm_support (char **lame_apps,
- guint32 timestamp)
-{
- GtkWidget *dialog;
- GtkWidget *list;
- GtkWidget *sw;
- GtkWidget *button;
-
- dialog = gtk_message_dialog_new (NULL,
- 0,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_NONE,
- _("These windows do not support \"save current setup\" and will have to be restarted manually next time you log in."));
- gtk_window_set_icon_name (GTK_WINDOW (dialog), "stock_dialog-warning");
-
- g_signal_connect (G_OBJECT (dialog),
- "response",
- G_CALLBACK (gtk_main_quit),
- NULL);
-
- /* Wait 4 minutes then force quit, so we don't wait around all night */
- g_timeout_add (4 * 60 * 1000, (GSourceFunc) gtk_main_quit, NULL);
-
- button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
- gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE);
- list = create_lame_apps_list (lame_apps);
-
- sw = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- gtk_container_set_border_width (GTK_CONTAINER (sw), 3);
-
- gtk_container_add (GTK_CONTAINER (sw), list);
-
- /* sw as geometry widget */
- gtk_window_set_geometry_hints (GTK_WINDOW (dialog),
- sw, NULL, 0);
-
- gtk_window_set_resizable (GTK_WINDOW(dialog), TRUE);
-
- /* applies to geometry widget; try to avoid scrollbars,
- * but don't make the window huge
- */
- gtk_window_set_default_size (GTK_WINDOW (dialog),
- 400, 225);
-
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
- sw,
- TRUE, TRUE, 0);
-
- gtk_window_stick (GTK_WINDOW (dialog));
-
- gtk_widget_realize (dialog);
- gdk_x11_window_set_user_time (dialog->window, timestamp);
-
- gtk_widget_grab_focus (button);
- gtk_widget_show_all (dialog);
-
- gtk_main ();
-
- return 0;
-}
-
-static int
-error_about_command (const char *gconf_key,
- const char *command,
- const char *error,
- guint32 timestamp)
-{
- GtkWidget *dialog;
-
- /* FIXME offer to change the value of the command's gconf key */
-
- if (*command != '\0')
- dialog = gtk_message_dialog_new (NULL, 0,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- _("There was an error running \"%s\":\n"
- "%s."),
- command, error);
- else
- dialog = gtk_message_dialog_new (NULL, 0,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "%s", error);
- gtk_window_set_icon_name (GTK_WINDOW (dialog), "stock_dialog-error");
-
- gtk_widget_realize (dialog);
- gdk_x11_window_set_user_time (dialog->window, timestamp);
-
- gtk_dialog_run (GTK_DIALOG (dialog));
-
- gtk_widget_destroy (dialog);
-
- return 0;
-}
-
-static gchar *screen = NULL;
-static gchar *timestamp_string = NULL;
-static gboolean isset_kill_window_question = FALSE;
-static gboolean isset_warn_about_no_sm_support = FALSE;
-static gboolean isset_command_failed_error = FALSE;
-static gchar **remaining_args;
-
-static const GOptionEntry options[] = {
- { "screen", 0, 0, G_OPTION_ARG_STRING, &screen, NULL, NULL},
- { "timestamp", 0, 0, G_OPTION_ARG_STRING, &timestamp_string, NULL, NULL},
- { "kill-window-question", 'k', 0, G_OPTION_ARG_NONE,
- &isset_kill_window_question, NULL, NULL},
- { "warn-about-no-sm-support", 'w', 0, G_OPTION_ARG_NONE,
- &isset_warn_about_no_sm_support, NULL, NULL},
- { "command-failed-error", 'c', 0, G_OPTION_ARG_NONE,
- &isset_command_failed_error, NULL, NULL},
- { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY,
- &remaining_args, NULL, NULL},
- { NULL}
-};
-
-int
-main (int argc, char **argv)
-{
- GOptionContext *ctx;
- guint32 timestamp = 0;
- gint num_args = 0;
-
- bindtextdomain (GETTEXT_PACKAGE, METACITY_LOCALEDIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
- textdomain (GETTEXT_PACKAGE);
-
- gtk_init (&argc, &argv);
-
- ctx = g_option_context_new ("- Dialogs for metacity. "
- "This program is intented for use by metacity only.");
- g_option_context_add_main_entries (ctx, options, GETTEXT_PACKAGE);
- g_option_context_parse (ctx, &argc, &argv, NULL);
- g_option_context_free (ctx);
-
- if (timestamp_string != NULL)
- {
- timestamp = strtoul (timestamp_string, NULL, 10);
- }
-
- if (remaining_args != NULL)
- {
- num_args = g_strv_length (remaining_args);
- }
-
- if ((isset_kill_window_question && isset_warn_about_no_sm_support) ||
- (isset_kill_window_question && isset_command_failed_error) ||
- (isset_warn_about_no_sm_support && isset_command_failed_error) ||
- timestamp == 0)
- {
- g_printerr ("bad args to metacity-dialog\n");
- return 1;
- }
-
- else if (isset_kill_window_question)
- {
- if (num_args < 2)
- {
- g_printerr ("bad args to metacity-dialog\n");
- return 1;
- }
- else
- {
- return kill_window_question (remaining_args[0],
- remaining_args[1], timestamp);
- }
- }
-
- else if (isset_warn_about_no_sm_support)
- {
- /* argc must be even because we want title-class pairs */
- if (num_args == 0 || (num_args % 2) != 0)
- {
- g_printerr ("bad args to metacity-dialog\n");
- return 1;
- }
- else
- {
- return warn_about_no_sm_support (&remaining_args[0], timestamp);
- }
- }
-
- else if (isset_command_failed_error)
- {
- /* the args are the gconf key of the failed command, the text of
- * the command, and the error message
- */
- if (num_args != 3)
- {
- g_printerr ("bad args to metacity-dialog\n");
- return 1;
- }
- else
- {
- return error_about_command (remaining_args[0],
- remaining_args[1], remaining_args[2], timestamp);
- }
- }
- else
- {
- g_printerr ("bad args to metacity-dialog\n");
- return 1;
- }
-}
diff --git a/src/ui/preview-widget.c b/src/ui/preview-widget.c
deleted file mode 100644
index e098baac..00000000
--- a/src/ui/preview-widget.c
+++ /dev/null
@@ -1,593 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity theme preview widget */
-
-/*
- * Copyright (C) 2002 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#define _GNU_SOURCE
-#define _XOPEN_SOURCE 600 /* for the maths routines over floats */
-
-#include <math.h>
-#include <gtk/gtk.h>
-#include "preview-widget.h"
-
-static void meta_preview_class_init (MetaPreviewClass *klass);
-static void meta_preview_init (MetaPreview *preview);
-static void meta_preview_size_request (GtkWidget *widget,
- GtkRequisition *req);
-static void meta_preview_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
-static gboolean meta_preview_expose (GtkWidget *widget,
- GdkEventExpose *event);
-static void meta_preview_finalize (GObject *object);
-
-static GtkWidgetClass *parent_class;
-
-GtkType
-meta_preview_get_type (void)
-{
- static GtkType preview_type = 0;
-
- if (!preview_type)
- {
- static const GtkTypeInfo preview_info =
- {
- "MetaPreview",
- sizeof (MetaPreview),
- sizeof (MetaPreviewClass),
- (GtkClassInitFunc) meta_preview_class_init,
- (GtkObjectInitFunc) meta_preview_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- preview_type = gtk_type_unique (GTK_TYPE_BIN, &preview_info);
- }
-
- return preview_type;
-}
-
-static void
-meta_preview_class_init (MetaPreviewClass *class)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (class);
- GtkWidgetClass *widget_class;
-
- widget_class = (GtkWidgetClass*) class;
- parent_class = gtk_type_class (GTK_TYPE_BIN);
-
- gobject_class->finalize = meta_preview_finalize;
-
- widget_class->expose_event = meta_preview_expose;
- widget_class->size_request = meta_preview_size_request;
- widget_class->size_allocate = meta_preview_size_allocate;
-}
-
-static void
-meta_preview_init (MetaPreview *preview)
-{
- int i;
-
- GTK_WIDGET_SET_FLAGS (preview, GTK_NO_WINDOW);
-
- i = 0;
- while (i < MAX_BUTTONS_PER_CORNER)
- {
- preview->button_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST;
- preview->button_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
- ++i;
- }
-
- preview->button_layout.left_buttons[0] = META_BUTTON_FUNCTION_MENU;
-
- preview->button_layout.right_buttons[0] = META_BUTTON_FUNCTION_MINIMIZE;
- preview->button_layout.right_buttons[1] = META_BUTTON_FUNCTION_MAXIMIZE;
- preview->button_layout.right_buttons[2] = META_BUTTON_FUNCTION_CLOSE;
-
- preview->type = META_FRAME_TYPE_NORMAL;
- preview->flags =
- META_FRAME_ALLOWS_DELETE |
- META_FRAME_ALLOWS_MENU |
- META_FRAME_ALLOWS_MINIMIZE |
- META_FRAME_ALLOWS_MAXIMIZE |
- META_FRAME_ALLOWS_VERTICAL_RESIZE |
- META_FRAME_ALLOWS_HORIZONTAL_RESIZE |
- META_FRAME_HAS_FOCUS |
- META_FRAME_ALLOWS_SHADE |
- META_FRAME_ALLOWS_MOVE;
-
- preview->left_width = -1;
- preview->right_width = -1;
- preview->top_height = -1;
- preview->bottom_height = -1;
-}
-
-GtkWidget*
-meta_preview_new (void)
-{
- MetaPreview *preview;
-
- preview = gtk_type_new (META_TYPE_PREVIEW);
-
- return GTK_WIDGET (preview);
-}
-
-static void
-meta_preview_finalize (GObject *object)
-{
- MetaPreview *preview;
-
- preview = META_PREVIEW (object);
-
- g_free (preview->title);
- preview->title = NULL;
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-ensure_info (MetaPreview *preview)
-{
- GtkWidget *widget;
-
- widget = GTK_WIDGET (preview);
-
- if (preview->layout == NULL)
- {
- PangoFontDescription *font_desc;
- double scale;
- PangoAttrList *attrs;
- PangoAttribute *attr;
-
- if (preview->theme)
- scale = meta_theme_get_title_scale (preview->theme,
- preview->type,
- preview->flags);
- else
- scale = 1.0;
-
- preview->layout = gtk_widget_create_pango_layout (widget,
- preview->title);
-
- font_desc = meta_gtk_widget_get_font_desc (widget, scale, NULL);
-
- preview->text_height =
- meta_pango_font_desc_get_text_height (font_desc,
- gtk_widget_get_pango_context (widget));
-
- attrs = pango_attr_list_new ();
-
- attr = pango_attr_size_new (pango_font_description_get_size (font_desc));
- attr->start_index = 0;
- attr->end_index = G_MAXINT;
-
- pango_attr_list_insert (attrs, attr);
-
- pango_layout_set_attributes (preview->layout, attrs);
-
- pango_attr_list_unref (attrs);
-
- pango_font_description_free (font_desc);
- }
-
- if (preview->top_height < 0)
- {
- if (preview->theme)
- {
- meta_theme_get_frame_borders (preview->theme,
- preview->type,
- preview->text_height,
- preview->flags,
- &preview->top_height,
- &preview->bottom_height,
- &preview->left_width,
- &preview->right_width);
- }
- else
- {
- preview->top_height = 0;
- preview->bottom_height = 0;
- preview->left_width = 0;
- preview->right_width = 0;
- }
- }
-}
-
-static gboolean
-meta_preview_expose (GtkWidget *widget,
- GdkEventExpose *event)
-{
- MetaPreview *preview;
- int border_width;
- int client_width;
- int client_height;
- MetaButtonState button_states[META_BUTTON_TYPE_LAST] =
- {
- META_BUTTON_STATE_NORMAL,
- META_BUTTON_STATE_NORMAL,
- META_BUTTON_STATE_NORMAL,
- META_BUTTON_STATE_NORMAL
- };
-
- g_return_val_if_fail (META_IS_PREVIEW (widget), FALSE);
- g_return_val_if_fail (event != NULL, FALSE);
-
- preview = META_PREVIEW (widget);
-
- ensure_info (preview);
-
- border_width = GTK_CONTAINER (widget)->border_width;
-
- client_width = widget->allocation.width - preview->left_width - preview->right_width - border_width * 2;
- client_height = widget->allocation.height - preview->top_height - preview->bottom_height - border_width * 2;
-
- if (client_width < 0)
- client_width = 1;
- if (client_height < 0)
- client_height = 1;
-
- if (preview->theme)
- {
- border_width = GTK_CONTAINER (widget)->border_width;
-
- meta_theme_draw_frame (preview->theme,
- widget,
- widget->window,
- &event->area,
- widget->allocation.x + border_width,
- widget->allocation.y + border_width,
- preview->type,
- preview->flags,
- client_width, client_height,
- preview->layout,
- preview->text_height,
- &preview->button_layout,
- button_states,
- meta_preview_get_mini_icon (),
- meta_preview_get_icon ());
- }
-
- /* draw child */
- return GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
-}
-
-static void
-meta_preview_size_request (GtkWidget *widget,
- GtkRequisition *req)
-{
- MetaPreview *preview;
-
- preview = META_PREVIEW (widget);
-
- ensure_info (preview);
-
- req->width = preview->left_width + preview->right_width;
- req->height = preview->top_height + preview->bottom_height;
-
- if (GTK_BIN (preview)->child &&
- GTK_WIDGET_VISIBLE (GTK_BIN (preview)->child))
- {
- GtkRequisition child_requisition;
-
- gtk_widget_size_request (GTK_BIN (preview)->child, &child_requisition);
-
- req->width += child_requisition.width;
- req->height += child_requisition.height;
- }
- else
- {
-#define NO_CHILD_WIDTH 80
-#define NO_CHILD_HEIGHT 20
- req->width += NO_CHILD_WIDTH;
- req->height += NO_CHILD_HEIGHT;
- }
-
- req->width += GTK_CONTAINER (widget)->border_width * 2;
- req->height += GTK_CONTAINER (widget)->border_width * 2;
-}
-
-static void
-meta_preview_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- MetaPreview *preview;
- int border_width;
- GtkAllocation child_allocation;
-
- preview = META_PREVIEW (widget);
-
- ensure_info (preview);
-
- widget->allocation = *allocation;
-
- border_width = GTK_CONTAINER (widget)->border_width;
-
- if (GTK_BIN (widget)->child &&
- GTK_WIDGET_VISIBLE (GTK_BIN (widget)->child))
- {
- child_allocation.x = widget->allocation.x + border_width + preview->left_width;
- child_allocation.y = widget->allocation.y + border_width + preview->top_height;
-
- child_allocation.width = MAX (1, widget->allocation.width - border_width * 2 - preview->left_width - preview->right_width);
- child_allocation.height = MAX (1, widget->allocation.height - border_width * 2 - preview->top_height - preview->bottom_height);
-
- gtk_widget_size_allocate (GTK_BIN (widget)->child, &child_allocation);
- }
-}
-
-static void
-clear_cache (MetaPreview *preview)
-{
- if (preview->layout)
- {
- g_object_unref (G_OBJECT (preview->layout));
- preview->layout = NULL;
- }
-
- preview->left_width = -1;
- preview->right_width = -1;
- preview->top_height = -1;
- preview->bottom_height = -1;
-}
-
-void
-meta_preview_set_theme (MetaPreview *preview,
- MetaTheme *theme)
-{
- g_return_if_fail (META_IS_PREVIEW (preview));
-
- preview->theme = theme;
-
- clear_cache (preview);
-
- gtk_widget_queue_resize (GTK_WIDGET (preview));
-}
-
-void
-meta_preview_set_title (MetaPreview *preview,
- const char *title)
-{
- g_return_if_fail (META_IS_PREVIEW (preview));
-
- g_free (preview->title);
- preview->title = g_strdup (title);
-
- clear_cache (preview);
-
- gtk_widget_queue_resize (GTK_WIDGET (preview));
-}
-
-void
-meta_preview_set_frame_type (MetaPreview *preview,
- MetaFrameType type)
-{
- g_return_if_fail (META_IS_PREVIEW (preview));
-
- preview->type = type;
-
- clear_cache (preview);
-
- gtk_widget_queue_resize (GTK_WIDGET (preview));
-}
-
-void
-meta_preview_set_frame_flags (MetaPreview *preview,
- MetaFrameFlags flags)
-{
- g_return_if_fail (META_IS_PREVIEW (preview));
-
- preview->flags = flags;
-
- clear_cache (preview);
-
- gtk_widget_queue_resize (GTK_WIDGET (preview));
-}
-
-void
-meta_preview_set_button_layout (MetaPreview *preview,
- const MetaButtonLayout *button_layout)
-{
- g_return_if_fail (META_IS_PREVIEW (preview));
-
- preview->button_layout = *button_layout;
-
- gtk_widget_queue_draw (GTK_WIDGET (preview));
-}
-
-GdkPixbuf*
-meta_preview_get_icon (void)
-{
- static GdkPixbuf *default_icon = NULL;
-
- if (default_icon == NULL)
- {
- GtkIconTheme *theme;
- gboolean icon_exists;
-
- theme = gtk_icon_theme_get_default ();
-
- icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME);
-
- if (icon_exists)
- default_icon = gtk_icon_theme_load_icon (theme,
- META_DEFAULT_ICON_NAME,
- META_ICON_WIDTH,
- 0,
- NULL);
- else
- default_icon = gtk_icon_theme_load_icon (theme,
- "gtk-missing-image",
- META_ICON_WIDTH,
- 0,
- NULL);
-
- g_assert (default_icon);
- }
-
- return default_icon;
-}
-
-GdkPixbuf*
-meta_preview_get_mini_icon (void)
-{
- static GdkPixbuf *default_icon = NULL;
-
- if (default_icon == NULL)
- {
- GtkIconTheme *theme;
- gboolean icon_exists;
-
- theme = gtk_icon_theme_get_default ();
-
- icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME);
-
- if (icon_exists)
- default_icon = gtk_icon_theme_load_icon (theme,
- META_DEFAULT_ICON_NAME,
- META_MINI_ICON_WIDTH,
- 0,
- NULL);
- else
- default_icon = gtk_icon_theme_load_icon (theme,
- "gtk-missing-image",
- META_MINI_ICON_WIDTH,
- 0,
- NULL);
-
- g_assert (default_icon);
- }
-
- return default_icon;
-}
-
-GdkRegion *
-meta_preview_get_clip_region (MetaPreview *preview, gint new_window_width, gint new_window_height)
-{
- GdkRectangle xrect;
- GdkRegion *corners_xregion, *window_xregion;
- gint flags;
- MetaFrameLayout *fgeom;
- MetaFrameStyle *frame_style;
-
- g_return_val_if_fail (META_IS_PREVIEW (preview), NULL);
-
- flags = (META_PREVIEW (preview)->flags);
-
- window_xregion = gdk_region_new ();
-
- xrect.x = 0;
- xrect.y = 0;
- xrect.width = new_window_width;
- xrect.height = new_window_height;
-
- gdk_region_union_with_rect (window_xregion, &xrect);
-
- if (preview->theme == NULL)
- return window_xregion;
-
- /* Otherwise, we do have a theme, so calculate the corners */
- frame_style = meta_theme_get_frame_style (preview->theme,
- META_FRAME_TYPE_NORMAL, flags);
-
- fgeom = frame_style->layout;
-
- corners_xregion = gdk_region_new ();
-
- if (fgeom->top_left_corner_rounded_radius != 0)
- {
- const int corner = fgeom->top_left_corner_rounded_radius;
- const float radius = sqrt(corner) + corner;
- int i;
-
- for (i=0; i<corner; i++)
- {
-
- const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
- xrect.x = 0;
- xrect.y = i;
- xrect.width = width;
- xrect.height = 1;
-
- gdk_region_union_with_rect (corners_xregion, &xrect);
- }
- }
-
- if (fgeom->top_right_corner_rounded_radius != 0)
- {
- const int corner = fgeom->top_right_corner_rounded_radius;
- const float radius = sqrt(corner) + corner;
- int i;
-
- for (i=0; i<corner; i++)
- {
- const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
- xrect.x = new_window_width - width;
- xrect.y = i;
- xrect.width = width;
- xrect.height = 1;
-
- gdk_region_union_with_rect (corners_xregion, &xrect);
- }
- }
-
- if (fgeom->bottom_left_corner_rounded_radius != 0)
- {
- const int corner = fgeom->bottom_left_corner_rounded_radius;
- const float radius = sqrt(corner) + corner;
- int i;
-
- for (i=0; i<corner; i++)
- {
- const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
- xrect.x = 0;
- xrect.y = new_window_height - i - 1;
- xrect.width = width;
- xrect.height = 1;
-
- gdk_region_union_with_rect (corners_xregion, &xrect);
- }
- }
-
- if (fgeom->bottom_right_corner_rounded_radius != 0)
- {
- const int corner = fgeom->bottom_right_corner_rounded_radius;
- const float radius = sqrt(corner) + corner;
- int i;
-
- for (i=0; i<corner; i++)
- {
- const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
- xrect.x = new_window_width - width;
- xrect.y = new_window_height - i - 1;
- xrect.width = width;
- xrect.height = 1;
-
- gdk_region_union_with_rect (corners_xregion, &xrect);
- }
- }
-
- gdk_region_subtract (window_xregion, corners_xregion);
- gdk_region_destroy (corners_xregion);
-
- return window_xregion;
-}
-
-
diff --git a/src/ui/preview-widget.h b/src/ui/preview-widget.h
deleted file mode 100644
index ab6a8f9e..00000000
--- a/src/ui/preview-widget.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity theme preview widget */
-
-/*
- * Copyright (C) 2002 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "theme.h"
-#include <gtk/gtk.h>
-
-#ifndef META_PREVIEW_WIDGET_H
-#define META_PREVIEW_WIDGET_H
-
-#define META_TYPE_PREVIEW (meta_preview_get_type ())
-#define META_PREVIEW(obj) (GTK_CHECK_CAST ((obj), META_TYPE_PREVIEW, MetaPreview))
-#define META_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), META_TYPE_PREVIEW, MetaPreviewClass))
-#define META_IS_PREVIEW(obj) (GTK_CHECK_TYPE ((obj), META_TYPE_PREVIEW))
-#define META_IS_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), META_TYPE_PREVIEW))
-#define META_PREVIEW_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), META_TYPE_PREVIEW, MetaPreviewClass))
-
-typedef struct _MetaPreview MetaPreview;
-typedef struct _MetaPreviewClass MetaPreviewClass;
-
-struct _MetaPreview
-{
- GtkBin bin;
-
- MetaTheme *theme;
- char *title;
- MetaFrameType type;
- MetaFrameFlags flags;
-
- PangoLayout *layout;
- int text_height;
-
- int left_width;
- int right_width;
- int top_height;
- int bottom_height;
-
- MetaButtonLayout button_layout;
-};
-
-struct _MetaPreviewClass
-{
- GtkBinClass parent_class;
-};
-
-
-GtkType meta_preview_get_type (void) G_GNUC_CONST;
-GtkWidget* meta_preview_new (void);
-
-void meta_preview_set_theme (MetaPreview *preview,
- MetaTheme *theme);
-void meta_preview_set_title (MetaPreview *preview,
- const char *title);
-void meta_preview_set_frame_type (MetaPreview *preview,
- MetaFrameType type);
-void meta_preview_set_frame_flags (MetaPreview *preview,
- MetaFrameFlags flags);
-void meta_preview_set_button_layout (MetaPreview *preview,
- const MetaButtonLayout *button_layout);
-
-GdkRegion * meta_preview_get_clip_region (MetaPreview *preview,
- gint new_window_width,
- gint new_window_height);
-
-GdkPixbuf* meta_preview_get_icon (void);
-GdkPixbuf* meta_preview_get_mini_icon (void);
-
-#endif
diff --git a/src/ui/resizepopup.c b/src/ui/resizepopup.c
deleted file mode 100644
index 11698e84..00000000
--- a/src/ui/resizepopup.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity resizing-terminal-window feedback */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include "resizepopup.h"
-#include "util.h"
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
-
-struct _MetaResizePopup
-{
- GtkWidget *size_window;
- GtkWidget *size_label;
- Display *display;
- int screen_number;
-
- int vertical_size;
- int horizontal_size;
-
- gboolean showing;
-
- MetaRectangle rect;
-};
-
-MetaResizePopup*
-meta_ui_resize_popup_new (Display *display,
- int screen_number)
-{
- MetaResizePopup *popup;
-
- popup = g_new0 (MetaResizePopup, 1);
-
- popup->display = display;
- popup->screen_number = screen_number;
-
- return popup;
-}
-
-void
-meta_ui_resize_popup_free (MetaResizePopup *popup)
-{
- g_return_if_fail (popup != NULL);
-
- if (popup->size_window)
- gtk_widget_destroy (popup->size_window);
-
- g_free (popup);
-}
-
-static void
-ensure_size_window (MetaResizePopup *popup)
-{
- GtkWidget *frame;
-
- if (popup->size_window)
- return;
-
- popup->size_window = gtk_window_new (GTK_WINDOW_POPUP);
-
- gtk_window_set_screen (GTK_WINDOW (popup->size_window),
- gdk_display_get_screen (gdk_x11_lookup_xdisplay (popup->display),
- popup->screen_number));
-
- /* never shrink the size window */
- gtk_window_set_resizable (GTK_WINDOW (popup->size_window),
- TRUE);
-
- frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
-
- gtk_container_add (GTK_CONTAINER (popup->size_window), frame);
-
- popup->size_label = gtk_label_new ("");
- gtk_misc_set_padding (GTK_MISC (popup->size_label), 3, 3);
-
- gtk_container_add (GTK_CONTAINER (frame), popup->size_label);
-
- gtk_widget_show_all (frame);
-}
-
-static void
-update_size_window (MetaResizePopup *popup)
-{
- char *str;
- int x, y;
- int width, height;
-
- g_return_if_fail (popup->size_window != NULL);
-
- /* Translators: This represents the size of a window. The first number is
- * the width of the window and the second is the height.
- */
- str = g_strdup_printf (_("%d x %d"),
- popup->horizontal_size,
- popup->vertical_size);
-
- gtk_label_set_text (GTK_LABEL (popup->size_label), str);
-
- g_free (str);
-
- gtk_window_get_size (GTK_WINDOW (popup->size_window), &width, &height);
-
- x = popup->rect.x + (popup->rect.width - width) / 2;
- y = popup->rect.y + (popup->rect.height - height) / 2;
-
- if (GTK_WIDGET_REALIZED (popup->size_window))
- {
- /* using move_resize to avoid jumpiness */
- gdk_window_move_resize (popup->size_window->window,
- x, y,
- width, height);
- }
- else
- {
- gtk_window_move (GTK_WINDOW (popup->size_window),
- x, y);
- }
-}
-
-static void
-sync_showing (MetaResizePopup *popup)
-{
- if (popup->showing)
- {
- if (popup->size_window)
- gtk_widget_show (popup->size_window);
-
- if (popup->size_window && GTK_WIDGET_REALIZED (popup->size_window))
- gdk_window_raise (popup->size_window->window);
- }
- else
- {
- if (popup->size_window)
- gtk_widget_hide (popup->size_window);
- }
-}
-
-void
-meta_ui_resize_popup_set (MetaResizePopup *popup,
- MetaRectangle rect,
- int base_width,
- int base_height,
- int width_inc,
- int height_inc)
-{
- gboolean need_update_size;
- int display_w, display_h;
-
- g_return_if_fail (popup != NULL);
-
- need_update_size = FALSE;
-
- display_w = rect.width - base_width;
- if (width_inc > 0)
- display_w /= width_inc;
-
- display_h = rect.height - base_height;
- if (height_inc > 0)
- display_h /= height_inc;
-
- if (!meta_rectangle_equal(&popup->rect, &rect) ||
- display_w != popup->horizontal_size ||
- display_h != popup->vertical_size)
- need_update_size = TRUE;
-
- popup->rect = rect;
- popup->vertical_size = display_h;
- popup->horizontal_size = display_w;
-
- if (need_update_size)
- {
- ensure_size_window (popup);
- update_size_window (popup);
- }
-
- sync_showing (popup);
-}
-
-void
-meta_ui_resize_popup_set_showing (MetaResizePopup *popup,
- gboolean showing)
-{
- g_return_if_fail (popup != NULL);
-
- if (showing == popup->showing)
- return;
-
- popup->showing = !!showing;
-
- if (popup->showing)
- {
- ensure_size_window (popup);
- update_size_window (popup);
- }
-
- sync_showing (popup);
-}
diff --git a/src/ui/tabpopup.c b/src/ui/tabpopup.c
deleted file mode 100644
index f38bb174..00000000
--- a/src/ui/tabpopup.c
+++ /dev/null
@@ -1,948 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity popup window thing showing windows you can tab to */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2002 Red Hat, Inc.
- * Copyright (C) 2005 Elijah Newren
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-
-#include "util.h"
-#include "core.h"
-#include "tabpopup.h"
-/* FIXME these two includes are 100% broken ...
- */
-#include "../core/workspace.h"
-#include "../core/frame-private.h"
-#include "draw-workspace.h"
-#include <gtk/gtk.h>
-#include <math.h>
-
-#define OUTSIDE_SELECT_RECT 2
-#define INSIDE_SELECT_RECT 2
-
-typedef struct _TabEntry TabEntry;
-
-struct _TabEntry
-{
- MetaTabEntryKey key;
- char *title;
- GdkPixbuf *icon, *dimmed_icon;
- GtkWidget *widget;
- GdkRectangle rect;
- GdkRectangle inner_rect;
- guint blank : 1;
-};
-
-struct _MetaTabPopup
-{
- GtkWidget *window;
- GtkWidget *label;
- GList *current;
- GList *entries;
- TabEntry *current_selected_entry;
- GtkWidget *outline_window;
- gboolean outline;
-};
-
-static GtkWidget* selectable_image_new (GdkPixbuf *pixbuf);
-static void select_image (GtkWidget *widget);
-static void unselect_image (GtkWidget *widget);
-
-static GtkWidget* selectable_workspace_new (MetaWorkspace *workspace);
-static void select_workspace (GtkWidget *widget);
-static void unselect_workspace (GtkWidget *widget);
-
-static gboolean
-outline_window_expose (GtkWidget *widget,
- GdkEventExpose *event,
- gpointer data)
-{
- MetaTabPopup *popup;
- TabEntry *te;
-
- popup = data;
-
- if (!popup->outline || popup->current_selected_entry == NULL)
- return FALSE;
-
- te = popup->current_selected_entry;
-
- gdk_draw_rectangle (widget->window,
- widget->style->white_gc,
- FALSE,
- 0, 0,
- te->rect.width - 1,
- te->rect.height - 1);
-
- gdk_draw_rectangle (widget->window,
- widget->style->white_gc,
- FALSE,
- te->inner_rect.x - 1, te->inner_rect.y - 1,
- te->inner_rect.width + 1,
- te->inner_rect.height + 1);
-
- return FALSE;
-}
-
-static GdkPixbuf*
-dimm_icon (GdkPixbuf *pixbuf)
-{
- int x, y, pixel_stride, row_stride;
- guchar *row, *pixels;
- int w, h;
- GdkPixbuf *dimmed_pixbuf;
-
- if (gdk_pixbuf_get_has_alpha (pixbuf))
- {
- dimmed_pixbuf = gdk_pixbuf_copy (pixbuf);
- }
- else
- {
- dimmed_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
- }
-
- w = gdk_pixbuf_get_width (dimmed_pixbuf);
- h = gdk_pixbuf_get_height (dimmed_pixbuf);
-
- pixel_stride = 4;
-
- row = gdk_pixbuf_get_pixels (dimmed_pixbuf);
- row_stride = gdk_pixbuf_get_rowstride (dimmed_pixbuf);
-
- for (y = 0; y < h; y++)
- {
- pixels = row;
- for (x = 0; x < w; x++)
- {
- pixels[3] /= 2;
- pixels += pixel_stride;
- }
- row += row_stride;
- }
- return dimmed_pixbuf;
-}
-
-static TabEntry*
-tab_entry_new (const MetaTabEntry *entry,
- gint screen_width,
- gboolean outline)
-{
- TabEntry *te;
-
- te = g_new (TabEntry, 1);
- te->key = entry->key;
- te->title = NULL;
- if (entry->title)
- {
- gchar *str;
- gchar *tmp;
- gchar *formatter = "%s";
-
- str = meta_g_utf8_strndup (entry->title, 4096);
-
- if (entry->hidden)
- {
- formatter = "[%s]";
- }
-
- tmp = g_markup_printf_escaped (formatter, str);
- g_free (str);
- str = tmp;
-
- if (entry->demands_attention)
- {
- /* Escape the whole line of text then markup the text and
- * copy it back into the original buffer.
- */
- tmp = g_strdup_printf ("<b>%s</b>", str);
- g_free (str);
- str = tmp;
- }
-
- te->title=g_strdup(str);
-
- g_free (str);
- }
- te->widget = NULL;
- te->icon = entry->icon;
- te->blank = entry->blank;
- te->dimmed_icon = NULL;
- if (te->icon)
- {
- g_object_ref (G_OBJECT (te->icon));
- if (entry->hidden)
- te->dimmed_icon = dimm_icon (entry->icon);
- }
-
- if (outline)
- {
- te->rect.x = entry->rect.x;
- te->rect.y = entry->rect.y;
- te->rect.width = entry->rect.width;
- te->rect.height = entry->rect.height;
-
- te->inner_rect.x = entry->inner_rect.x;
- te->inner_rect.y = entry->inner_rect.y;
- te->inner_rect.width = entry->inner_rect.width;
- te->inner_rect.height = entry->inner_rect.height;
- }
- return te;
-}
-
-MetaTabPopup*
-meta_ui_tab_popup_new (const MetaTabEntry *entries,
- int screen_number,
- int entry_count,
- int width,
- gboolean outline)
-{
- MetaTabPopup *popup;
- int i, left, right, top, bottom;
- int height;
- GtkWidget *table;
- GtkWidget *vbox;
- GtkWidget *align;
- GList *tmp;
- GtkWidget *frame;
- int max_label_width; /* the actual max width of the labels we create */
- AtkObject *obj;
- GdkScreen *screen;
- int screen_width;
-
- popup = g_new (MetaTabPopup, 1);
-
- popup->outline_window = gtk_window_new (GTK_WINDOW_POPUP);
-
- screen = gdk_display_get_screen (gdk_display_get_default (),
- screen_number);
- gtk_window_set_screen (GTK_WINDOW (popup->outline_window),
- screen);
-
- gtk_widget_set_app_paintable (popup->outline_window, TRUE);
- gtk_widget_realize (popup->outline_window);
-
- g_signal_connect (G_OBJECT (popup->outline_window), "expose_event",
- G_CALLBACK (outline_window_expose), popup);
-
- popup->window = gtk_window_new (GTK_WINDOW_POPUP);
-
- gtk_window_set_screen (GTK_WINDOW (popup->window),
- screen);
-
- gtk_window_set_position (GTK_WINDOW (popup->window),
- GTK_WIN_POS_CENTER_ALWAYS);
- /* enable resizing, to get never-shrink behavior */
- gtk_window_set_resizable (GTK_WINDOW (popup->window),
- TRUE);
- popup->current = NULL;
- popup->entries = NULL;
- popup->current_selected_entry = NULL;
- popup->outline = outline;
-
- screen_width = gdk_screen_get_width (screen);
- for (i = 0; i < entry_count; ++i)
- {
- TabEntry* new_entry = tab_entry_new (&entries[i], screen_width, outline);
- popup->entries = g_list_prepend (popup->entries, new_entry);
- }
-
- popup->entries = g_list_reverse (popup->entries);
-
- g_assert (width > 0);
- height = i / width;
- if (i % width)
- height += 1;
-
- table = gtk_table_new (height, width, FALSE);
- vbox = gtk_vbox_new (FALSE, 0);
-
- frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
- gtk_container_set_border_width (GTK_CONTAINER (table), 1);
- gtk_container_add (GTK_CONTAINER (popup->window),
- frame);
- gtk_container_add (GTK_CONTAINER (frame),
- vbox);
-
- align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
-
- gtk_box_pack_start (GTK_BOX (vbox), align, TRUE, TRUE, 0);
-
- gtk_container_add (GTK_CONTAINER (align),
- table);
-
- popup->label = gtk_label_new ("");
-
- /* Set the accessible role of the label to a status bar so it
- * will emit name changed events that can be used by screen
- * readers.
- */
- obj = gtk_widget_get_accessible (popup->label);
- atk_object_set_role (obj, ATK_ROLE_STATUSBAR);
-
- gtk_misc_set_padding (GTK_MISC (popup->label), 3, 3);
-
- gtk_box_pack_end (GTK_BOX (vbox), popup->label, FALSE, FALSE, 0);
-
- max_label_width = 0;
- top = 0;
- bottom = 1;
- tmp = popup->entries;
-
- while (tmp && top < height)
- {
- left = 0;
- right = 1;
-
- while (tmp && left < width)
- {
- GtkWidget *image;
- GtkRequisition req;
-
- TabEntry *te;
-
- te = tmp->data;
-
- if (te->blank)
- {
- /* just stick a widget here to avoid special cases */
- image = gtk_alignment_new (0.0, 0.0, 0.0, 0.0);
- }
- else if (outline)
- {
- if (te->dimmed_icon)
- {
- image = selectable_image_new (te->dimmed_icon);
- }
- else
- {
- image = selectable_image_new (te->icon);
- }
-
- gtk_misc_set_padding (GTK_MISC (image),
- INSIDE_SELECT_RECT + OUTSIDE_SELECT_RECT + 1,
- INSIDE_SELECT_RECT + OUTSIDE_SELECT_RECT + 1);
- gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.5);
- }
- else
- {
- image = selectable_workspace_new ((MetaWorkspace *) te->key);
- }
-
- te->widget = image;
-
- gtk_table_attach (GTK_TABLE (table),
- te->widget,
- left, right, top, bottom,
- 0, 0,
- 0, 0);
-
- /* Efficiency rules! */
- gtk_label_set_markup (GTK_LABEL (popup->label),
- te->title);
- gtk_widget_size_request (popup->label, &req);
- max_label_width = MAX (max_label_width, req.width);
-
- tmp = tmp->next;
-
- ++left;
- ++right;
- }
-
- ++top;
- ++bottom;
- }
-
- /* remove all the temporary text */
- gtk_label_set_text (GTK_LABEL (popup->label), "");
- /* Make it so that we ellipsize if the text is too long */
- gtk_label_set_ellipsize (GTK_LABEL (popup->label), PANGO_ELLIPSIZE_END);
-
- /* Limit the window size to no bigger than screen_width/4 */
- if (max_label_width>(screen_width/4))
- {
- max_label_width = screen_width/4;
- }
-
- max_label_width += 20; /* add random padding */
-
- gtk_window_set_default_size (GTK_WINDOW (popup->window),
- max_label_width,
- -1);
-
- return popup;
-}
-
-static void
-free_tab_entry (gpointer data, gpointer user_data)
-{
- TabEntry *te;
-
- te = data;
-
- g_free (te->title);
- if (te->icon)
- g_object_unref (G_OBJECT (te->icon));
- if (te->dimmed_icon)
- g_object_unref (G_OBJECT (te->dimmed_icon));
-
- g_free (te);
-}
-
-void
-meta_ui_tab_popup_free (MetaTabPopup *popup)
-{
- meta_verbose ("Destroying tab popup window\n");
-
- gtk_widget_destroy (popup->outline_window);
- gtk_widget_destroy (popup->window);
-
- g_list_foreach (popup->entries, free_tab_entry, NULL);
-
- g_list_free (popup->entries);
-
- g_free (popup);
-}
-
-void
-meta_ui_tab_popup_set_showing (MetaTabPopup *popup,
- gboolean showing)
-{
- if (showing)
- {
- gtk_widget_show_all (popup->window);
- }
- else
- {
- if (GTK_WIDGET_VISIBLE (popup->window))
- {
- meta_verbose ("Hiding tab popup window\n");
- gtk_widget_hide (popup->window);
- meta_core_increment_event_serial (gdk_display);
- }
- }
-}
-
-static void
-display_entry (MetaTabPopup *popup,
- TabEntry *te)
-{
- GdkRectangle rect;
- GdkRegion *region;
- GdkRegion *inner_region;
-
-
- if (popup->current_selected_entry)
- {
- if (popup->outline)
- unselect_image (popup->current_selected_entry->widget);
- else
- unselect_workspace (popup->current_selected_entry->widget);
- }
-
- gtk_label_set_markup (GTK_LABEL (popup->label), te->title);
-
- if (popup->outline)
- select_image (te->widget);
- else
- select_workspace (te->widget);
-
- if (popup->outline)
- {
- /* Do stuff behind gtk's back */
- gdk_window_hide (popup->outline_window->window);
- meta_core_increment_event_serial (gdk_display);
-
- rect = te->rect;
- rect.x = 0;
- rect.y = 0;
-
- gdk_window_move_resize (popup->outline_window->window,
- te->rect.x, te->rect.y,
- te->rect.width, te->rect.height);
-
- gdk_window_set_background (popup->outline_window->window,
- &popup->outline_window->style->black);
-
- region = gdk_region_rectangle (&rect);
- inner_region = gdk_region_rectangle (&te->inner_rect);
- gdk_region_subtract (region, inner_region);
- gdk_region_destroy (inner_region);
-
- gdk_window_shape_combine_region (popup->outline_window->window,
- region,
- 0, 0);
-
- gdk_region_destroy (region);
-
- /* This should piss off gtk a bit, but we don't want to raise
- * above the tab popup. So, instead of calling gtk_widget_show,
- * we manually set the window as mapped and then manually map it
- * with gdk functions.
- */
- GTK_WIDGET_SET_FLAGS (popup->outline_window, GTK_MAPPED);
- gdk_window_show_unraised (popup->outline_window->window);
- }
-
- /* Must be before we handle an expose for the outline window */
- popup->current_selected_entry = te;
-}
-
-void
-meta_ui_tab_popup_forward (MetaTabPopup *popup)
-{
- if (popup->current != NULL)
- popup->current = popup->current->next;
-
- if (popup->current == NULL)
- popup->current = popup->entries;
-
- if (popup->current != NULL)
- {
- TabEntry *te;
-
- te = popup->current->data;
-
- display_entry (popup, te);
- }
-}
-
-void
-meta_ui_tab_popup_backward (MetaTabPopup *popup)
-{
- if (popup->current != NULL)
- popup->current = popup->current->prev;
-
- if (popup->current == NULL)
- popup->current = g_list_last (popup->entries);
-
- if (popup->current != NULL)
- {
- TabEntry *te;
-
- te = popup->current->data;
-
- display_entry (popup, te);
- }
-}
-
-MetaTabEntryKey
-meta_ui_tab_popup_get_selected (MetaTabPopup *popup)
-{
- if (popup->current)
- {
- TabEntry *te;
-
- te = popup->current->data;
-
- return te->key;
- }
- else
- return (MetaTabEntryKey)None;
-}
-
-void
-meta_ui_tab_popup_select (MetaTabPopup *popup,
- MetaTabEntryKey key)
-{
- GList *tmp;
-
- /* Note, "key" may not be in the list of entries; other code assumes
- * it's OK to pass in a key that isn't.
- */
-
- tmp = popup->entries;
- while (tmp != NULL)
- {
- TabEntry *te;
-
- te = tmp->data;
-
- if (te->key == key)
- {
- popup->current = tmp;
-
- display_entry (popup, te);
-
- return;
- }
-
- tmp = tmp->next;
- }
-}
-
-#define META_TYPE_SELECT_IMAGE (meta_select_image_get_type ())
-#define META_SELECT_IMAGE(obj) (GTK_CHECK_CAST ((obj), META_TYPE_SELECT_IMAGE, MetaSelectImage))
-
-typedef struct _MetaSelectImage MetaSelectImage;
-typedef struct _MetaSelectImageClass MetaSelectImageClass;
-
-struct _MetaSelectImage
-{
- GtkImage parent_instance;
- guint selected : 1;
-};
-
-struct _MetaSelectImageClass
-{
- GtkImageClass parent_class;
-};
-
-
-static GType meta_select_image_get_type (void) G_GNUC_CONST;
-
-static GtkWidget*
-selectable_image_new (GdkPixbuf *pixbuf)
-{
- GtkWidget *w;
-
- w = g_object_new (meta_select_image_get_type (), NULL);
- gtk_image_set_from_pixbuf (GTK_IMAGE (w), pixbuf);
-
- return w;
-}
-
-static void
-select_image (GtkWidget *widget)
-{
- META_SELECT_IMAGE (widget)->selected = TRUE;
- gtk_widget_queue_draw (widget);
-}
-
-static void
-unselect_image (GtkWidget *widget)
-{
- META_SELECT_IMAGE (widget)->selected = FALSE;
- gtk_widget_queue_draw (widget);
-}
-
-static void meta_select_image_class_init (MetaSelectImageClass *klass);
-static gboolean meta_select_image_expose_event (GtkWidget *widget,
- GdkEventExpose *event);
-
-static GtkImageClass *parent_class;
-
-GType
-meta_select_image_get_type (void)
-{
- static GtkType image_type = 0;
-
- if (!image_type)
- {
- static const GTypeInfo image_info =
- {
- sizeof (MetaSelectImageClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) meta_select_image_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (MetaSelectImage),
- 16, /* n_preallocs */
- (GInstanceInitFunc) NULL,
- };
-
- image_type = g_type_register_static (GTK_TYPE_IMAGE, "MetaSelectImage", &image_info, 0);
- }
-
- return image_type;
-}
-
-static void
-meta_select_image_class_init (MetaSelectImageClass *klass)
-{
- GtkWidgetClass *widget_class;
-
- parent_class = gtk_type_class (gtk_image_get_type ());
-
- widget_class = GTK_WIDGET_CLASS (klass);
-
- widget_class->expose_event = meta_select_image_expose_event;
-}
-
-static gboolean
-meta_select_image_expose_event (GtkWidget *widget,
- GdkEventExpose *event)
-{
- if (META_SELECT_IMAGE (widget)->selected)
- {
- int x, y, w, h;
- GtkMisc *misc;
-
- misc = GTK_MISC (widget);
-
- x = (widget->allocation.x * (1.0 - misc->xalign) +
- (widget->allocation.x + widget->allocation.width
- - (widget->requisition.width - misc->xpad * 2)) *
- misc->xalign) + 0.5;
- y = (widget->allocation.y * (1.0 - misc->yalign) +
- (widget->allocation.y + widget->allocation.height
- - (widget->requisition.height - misc->ypad * 2)) *
- misc->yalign) + 0.5;
-
- x -= INSIDE_SELECT_RECT + 1;
- y -= INSIDE_SELECT_RECT + 1;
-
- w = widget->requisition.width - OUTSIDE_SELECT_RECT * 2 - 1;
- h = widget->requisition.height - OUTSIDE_SELECT_RECT * 2 - 1;
-
- gdk_draw_rectangle (widget->window,
- widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- FALSE,
- x, y, w, h);
- gdk_draw_rectangle (widget->window,
- widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- FALSE,
- x - 1, y - 1, w + 2, h + 2);
-
-#if 0
- gdk_draw_rectangle (widget->window,
- widget->style->bg_gc[GTK_STATE_SELECTED],
- TRUE,
- x, y, w, h);
-#endif
-#if 0
- gtk_paint_focus (widget->style, widget->window,
- &event->area, widget, "meta-tab-image",
- x, y, w, h);
-#endif
- }
-
- return GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
-}
-
-#define META_TYPE_SELECT_WORKSPACE (meta_select_workspace_get_type ())
-#define META_SELECT_WORKSPACE(obj) (GTK_CHECK_CAST ((obj), META_TYPE_SELECT_WORKSPACE, MetaSelectWorkspace))
-
-typedef struct _MetaSelectWorkspace MetaSelectWorkspace;
-typedef struct _MetaSelectWorkspaceClass MetaSelectWorkspaceClass;
-
-struct _MetaSelectWorkspace
-{
- GtkDrawingArea parent_instance;
- MetaWorkspace *workspace;
- guint selected : 1;
-};
-
-struct _MetaSelectWorkspaceClass
-{
- GtkDrawingAreaClass parent_class;
-};
-
-
-static GType meta_select_workspace_get_type (void) G_GNUC_CONST;
-
-#define SELECT_OUTLINE_WIDTH 2
-#define MINI_WORKSPACE_WIDTH 48
-
-static GtkWidget*
-selectable_workspace_new (MetaWorkspace *workspace)
-{
- GtkWidget *widget;
- double screen_aspect;
-
- widget = g_object_new (meta_select_workspace_get_type (), NULL);
-
- screen_aspect = (double) workspace->screen->rect.height /
- (double) workspace->screen->rect.width;
-
- /* account for select rect */
- gtk_widget_set_size_request (widget,
- MINI_WORKSPACE_WIDTH + SELECT_OUTLINE_WIDTH * 2,
- MINI_WORKSPACE_WIDTH * screen_aspect + SELECT_OUTLINE_WIDTH * 2);
-
- META_SELECT_WORKSPACE (widget)->workspace = workspace;
-
- return widget;
-}
-
-static void
-select_workspace (GtkWidget *widget)
-{
- META_SELECT_WORKSPACE(widget)->selected = TRUE;
- gtk_widget_queue_draw (widget);
-}
-
-static void
-unselect_workspace (GtkWidget *widget)
-{
- META_SELECT_WORKSPACE (widget)->selected = FALSE;
- gtk_widget_queue_draw (widget);
-}
-
-static void meta_select_workspace_class_init (MetaSelectWorkspaceClass *klass);
-
-static gboolean meta_select_workspace_expose_event (GtkWidget *widget,
- GdkEventExpose *event);
-
-GType
-meta_select_workspace_get_type (void)
-{
- static GtkType workspace_type = 0;
-
- if (!workspace_type)
- {
- static const GTypeInfo workspace_info =
- {
- sizeof (MetaSelectWorkspaceClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) meta_select_workspace_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (MetaSelectWorkspace),
- 16, /* n_preallocs */
- (GInstanceInitFunc) NULL,
- };
-
- workspace_type = g_type_register_static (GTK_TYPE_DRAWING_AREA,
- "MetaSelectWorkspace",
- &workspace_info,
- 0);
- }
-
- return workspace_type;
-}
-
-static void
-meta_select_workspace_class_init (MetaSelectWorkspaceClass *klass)
-{
- GtkWidgetClass *widget_class;
-
- widget_class = GTK_WIDGET_CLASS (klass);
-
- widget_class->expose_event = meta_select_workspace_expose_event;
-}
-
-/**
- * meta_convert_meta_to_wnck() converts a MetaWindow to a
- * WnckWindowDisplayInfo window that is used to build a thumbnail of a
- * workspace.
- **/
-static WnckWindowDisplayInfo
-meta_convert_meta_to_wnck (MetaWindow *window, MetaScreen *screen)
-{
- WnckWindowDisplayInfo wnck_window;
- wnck_window.icon = window->icon;
- wnck_window.mini_icon = window->mini_icon;
-
- wnck_window.is_active = FALSE;
- if (window == window->display->expected_focus_window)
- wnck_window.is_active = TRUE;
-
- if (window->frame)
- {
- wnck_window.x = window->frame->rect.x;
- wnck_window.y = window->frame->rect.y;
- wnck_window.width = window->frame->rect.width;
- wnck_window.height = window->frame->rect.height;
- }
- else
- {
- wnck_window.x = window->rect.x;
- wnck_window.y = window->rect.y;
- wnck_window.width = window->rect.width;
- wnck_window.height = window->rect.height;
- }
- return wnck_window;
-}
-
-
-static gboolean
-meta_select_workspace_expose_event (GtkWidget *widget,
- GdkEventExpose *event)
-{
- MetaWorkspace *workspace;
- WnckWindowDisplayInfo *windows;
- int i, n_windows;
- GList *tmp, *list;
-
- workspace = META_SELECT_WORKSPACE (widget)->workspace;
-
- list = meta_stack_list_windows (workspace->screen->stack, workspace);
- n_windows = g_list_length (list);
- windows = g_new (WnckWindowDisplayInfo, n_windows);
-
- tmp = list;
- i = 0;
- while (tmp != NULL)
- {
- MetaWindow *window;
- gboolean ignoreable_sticky;
-
- window = tmp->data;
-
- ignoreable_sticky = window->on_all_workspaces &&
- workspace != workspace->screen->active_workspace;
-
- if (window->skip_pager ||
- !meta_window_showing_on_its_workspace (window) ||
- window->unmaps_pending ||
- ignoreable_sticky)
- {
- --n_windows;
- }
- else
- {
- windows[i] = meta_convert_meta_to_wnck (window, workspace->screen);
- i++;
- }
- tmp = tmp->next;
- }
-
- g_list_free (list);
-
- wnck_draw_workspace (widget,
- widget->window,
- SELECT_OUTLINE_WIDTH,
- SELECT_OUTLINE_WIDTH,
- widget->allocation.width - SELECT_OUTLINE_WIDTH * 2,
- widget->allocation.height - SELECT_OUTLINE_WIDTH * 2,
- workspace->screen->rect.width,
- workspace->screen->rect.height,
- NULL,
- (workspace->screen->active_workspace == workspace),
- windows,
- n_windows);
-
- g_free (windows);
-
- if (META_SELECT_WORKSPACE (widget)->selected)
- {
- i = SELECT_OUTLINE_WIDTH - 1;
- while (i >= 0)
- {
- gdk_draw_rectangle (widget->window,
- widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- FALSE,
- i,
- i,
- widget->allocation.width - i * 2 - 1,
- widget->allocation.height - i * 2 - 1);
-
- --i;
- }
- }
-
- return TRUE;
-}
-
diff --git a/src/ui/testgradient.c b/src/ui/testgradient.c
deleted file mode 100644
index 28de317d..00000000
--- a/src/ui/testgradient.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity gradient test program */
-
-/*
- * Copyright (C) 2002 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA. */
-
-#include "gradient.h"
-#include <gtk/gtk.h>
-
-typedef void (* RenderGradientFunc) (GdkDrawable *drawable,
- GdkGC *gc,
- int width,
- int height);
-
-static void
-draw_checkerboard (GdkDrawable *drawable,
- int width,
- int height)
-{
- gint i, j, xcount, ycount;
- GdkGC *gc1, *gc2;
- GdkColor color;
-
-#define CHECK_SIZE 10
-#define SPACING 2
-
- /* It would be a bit more efficient to keep these
- * GC's around instead of recreating on each expose, but
- * this is the lazy/slow way.
- */
- gc1 = gdk_gc_new (drawable);
- color.red = 30000;
- color.green = 30000;
- color.blue = 30000;
- gdk_gc_set_rgb_fg_color (gc1, &color);
-
- gc2 = gdk_gc_new (drawable);
- color.red = 50000;
- color.green = 50000;
- color.blue = 50000;
- gdk_gc_set_rgb_fg_color (gc2, &color);
-
- xcount = 0;
- i = SPACING;
- while (i < width)
- {
- j = SPACING;
- ycount = xcount % 2; /* start with even/odd depending on row */
- while (j < height)
- {
- GdkGC *gc;
-
- if (ycount % 2)
- gc = gc1;
- else
- gc = gc2;
-
- /* If we're outside event->area, this will do nothing.
- * It might be mildly more efficient if we handled
- * the clipping ourselves, but again we're feeling lazy.
- */
- gdk_draw_rectangle (drawable,
- gc,
- TRUE,
- i, j,
- CHECK_SIZE,
- CHECK_SIZE);
-
- j += CHECK_SIZE + SPACING;
- ++ycount;
- }
-
- i += CHECK_SIZE + SPACING;
- ++xcount;
- }
-
- g_object_unref (G_OBJECT (gc1));
- g_object_unref (G_OBJECT (gc2));
-}
-
-static void
-render_simple (GdkDrawable *drawable,
- GdkGC *gc,
- int width, int height,
- MetaGradientType type,
- gboolean with_alpha)
-{
- GdkPixbuf *pixbuf;
- GdkColor from, to;
-
- gdk_color_parse ("blue", &from);
- gdk_color_parse ("green", &to);
-
- pixbuf = meta_gradient_create_simple (width, height,
- &from, &to,
- type);
-
- if (with_alpha)
- {
- const unsigned char alphas[] = { 0xff, 0xaa, 0x2f, 0x0, 0xcc, 0xff, 0xff };
-
- if (!gdk_pixbuf_get_has_alpha (pixbuf))
- {
- GdkPixbuf *new_pixbuf;
-
- new_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
- g_object_unref (G_OBJECT (pixbuf));
- pixbuf = new_pixbuf;
- }
-
- meta_gradient_add_alpha (pixbuf,
- alphas, G_N_ELEMENTS (alphas),
- META_GRADIENT_HORIZONTAL);
-
- draw_checkerboard (drawable, width, height);
- }
-
- gdk_draw_pixbuf (drawable,
- gc,
- pixbuf,
- 0, 0,
- 0, 0, width, height,
- GDK_RGB_DITHER_MAX,
- 0, 0);
-
- g_object_unref (G_OBJECT (pixbuf));
-}
-
-static void
-render_vertical_func (GdkDrawable *drawable,
- GdkGC *gc,
- int width, int height)
-{
- render_simple (drawable, gc, width, height, META_GRADIENT_VERTICAL, FALSE);
-}
-
-static void
-render_horizontal_func (GdkDrawable *drawable,
- GdkGC *gc,
- int width, int height)
-{
- render_simple (drawable, gc, width, height, META_GRADIENT_HORIZONTAL, FALSE);
-}
-
-static void
-render_diagonal_func (GdkDrawable *drawable,
- GdkGC *gc,
- int width, int height)
-{
- render_simple (drawable, gc, width, height, META_GRADIENT_DIAGONAL, FALSE);
-}
-
-static void
-render_diagonal_alpha_func (GdkDrawable *drawable,
- GdkGC *gc,
- int width, int height)
-{
- render_simple (drawable, gc, width, height, META_GRADIENT_DIAGONAL, TRUE);
-}
-
-static void
-render_multi (GdkDrawable *drawable,
- GdkGC *gc,
- int width, int height,
- MetaGradientType type)
-{
- GdkPixbuf *pixbuf;
-#define N_COLORS 5
- GdkColor colors[N_COLORS];
-
- gdk_color_parse ("red", &colors[0]);
- gdk_color_parse ("blue", &colors[1]);
- gdk_color_parse ("orange", &colors[2]);
- gdk_color_parse ("pink", &colors[3]);
- gdk_color_parse ("green", &colors[4]);
-
- pixbuf = meta_gradient_create_multi (width, height,
- colors, N_COLORS,
- type);
-
- gdk_pixbuf_render_to_drawable (pixbuf,
- drawable,
- gc,
- 0, 0,
- 0, 0, width, height,
- GDK_RGB_DITHER_NORMAL,
- 0, 0);
-
- g_object_unref (G_OBJECT (pixbuf));
-#undef N_COLORS
-}
-
-static void
-render_vertical_multi_func (GdkDrawable *drawable,
- GdkGC *gc,
- int width, int height)
-{
- render_multi (drawable, gc, width, height, META_GRADIENT_VERTICAL);
-}
-
-static void
-render_horizontal_multi_func (GdkDrawable *drawable,
- GdkGC *gc,
- int width, int height)
-{
- render_multi (drawable, gc, width, height, META_GRADIENT_HORIZONTAL);
-}
-
-static void
-render_diagonal_multi_func (GdkDrawable *drawable,
- GdkGC *gc,
- int width, int height)
-{
- render_multi (drawable, gc, width, height, META_GRADIENT_DIAGONAL);
-}
-
-static void
-render_interwoven_func (GdkDrawable *drawable,
- GdkGC *gc,
- int width, int height)
-{
- GdkPixbuf *pixbuf;
-#define N_COLORS 4
- GdkColor colors[N_COLORS];
-
- gdk_color_parse ("red", &colors[0]);
- gdk_color_parse ("blue", &colors[1]);
- gdk_color_parse ("pink", &colors[2]);
- gdk_color_parse ("green", &colors[3]);
-
- pixbuf = meta_gradient_create_interwoven (width, height,
- colors, height / 10,
- colors + 2, height / 14);
-
- gdk_pixbuf_render_to_drawable (pixbuf,
- drawable,
- gc,
- 0, 0,
- 0, 0, width, height,
- GDK_RGB_DITHER_NORMAL,
- 0, 0);
-
- g_object_unref (G_OBJECT (pixbuf));
-}
-
-static gboolean
-expose_callback (GtkWidget *widget,
- GdkEventExpose *event,
- gpointer data)
-{
- RenderGradientFunc func = data;
-
- (* func) (widget->window,
- widget->style->fg_gc[widget->state],
- widget->allocation.width,
- widget->allocation.height);
-
- return TRUE;
-}
-
-static GtkWidget*
-create_gradient_window (const char *title,
- RenderGradientFunc func)
-{
- GtkWidget *window;
- GtkWidget *drawing_area;
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-
- gtk_window_set_title (GTK_WINDOW (window), title);
-
- drawing_area = gtk_drawing_area_new ();
-
- gtk_widget_set_size_request (drawing_area, 1, 1);
-
- gtk_window_set_default_size (GTK_WINDOW (window), 175, 175);
-
- g_signal_connect (G_OBJECT (drawing_area),
- "expose_event",
- G_CALLBACK (expose_callback),
- func);
-
- gtk_container_add (GTK_CONTAINER (window), drawing_area);
-
- gtk_widget_show_all (window);
-
- return window;
-}
-
-static void
-meta_gradient_test (void)
-{
- GtkWidget *window;
-
- window = create_gradient_window ("Simple vertical",
- render_vertical_func);
-
- window = create_gradient_window ("Simple horizontal",
- render_horizontal_func);
-
- window = create_gradient_window ("Simple diagonal",
- render_diagonal_func);
-
- window = create_gradient_window ("Multi vertical",
- render_vertical_multi_func);
-
- window = create_gradient_window ("Multi horizontal",
- render_horizontal_multi_func);
-
- window = create_gradient_window ("Multi diagonal",
- render_diagonal_multi_func);
-
- window = create_gradient_window ("Interwoven",
- render_interwoven_func);
-
- window = create_gradient_window ("Simple diagonal with horizontal multi alpha",
- render_diagonal_alpha_func);
-
-}
-
-int
-main (int argc, char **argv)
-{
- gtk_init (&argc, &argv);
-
- meta_gradient_test ();
-
- gtk_main ();
-
- return 0;
-}
-
diff --git a/src/ui/theme-parser.c b/src/ui/theme-parser.c
deleted file mode 100644
index 98dc1662..00000000
--- a/src/ui/theme-parser.c
+++ /dev/null
@@ -1,4090 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity theme parsing */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include "theme-parser.h"
-#include "util.h"
-#include <string.h>
-#include <stdlib.h>
-
-typedef enum
-{
- STATE_START,
- STATE_THEME,
- /* info section */
- STATE_INFO,
- STATE_NAME,
- STATE_AUTHOR,
- STATE_COPYRIGHT,
- STATE_DATE,
- STATE_DESCRIPTION,
- /* constants */
- STATE_CONSTANT,
- /* geometry */
- STATE_FRAME_GEOMETRY,
- STATE_DISTANCE,
- STATE_BORDER,
- STATE_ASPECT_RATIO,
- /* draw ops */
- STATE_DRAW_OPS,
- STATE_LINE,
- STATE_RECTANGLE,
- STATE_ARC,
- STATE_CLIP,
- STATE_TINT,
- STATE_GRADIENT,
- STATE_IMAGE,
- STATE_GTK_ARROW,
- STATE_GTK_BOX,
- STATE_GTK_VLINE,
- STATE_ICON,
- STATE_TITLE,
- STATE_INCLUDE, /* include another draw op list */
- STATE_TILE, /* tile another draw op list */
- /* sub-parts of gradient */
- STATE_COLOR,
- /* frame style */
- STATE_FRAME_STYLE,
- STATE_PIECE,
- STATE_BUTTON,
- /* style set */
- STATE_FRAME_STYLE_SET,
- STATE_FRAME,
- /* assigning style sets to windows */
- STATE_WINDOW,
- /* things we don't use any more but we can still parse: */
- STATE_MENU_ICON,
- STATE_FALLBACK
-} ParseState;
-
-typedef struct
-{
- GSList *states;
-
- const char *theme_name; /* name of theme (directory it's in) */
- char *theme_file; /* theme filename */
- char *theme_dir; /* dir the theme is inside */
- MetaTheme *theme; /* theme being parsed */
- guint format_version; /* version of format of theme file */
- char *name; /* name of named thing being parsed */
- MetaFrameLayout *layout; /* layout being parsed if any */
- MetaDrawOpList *op_list; /* op list being parsed if any */
- MetaDrawOp *op; /* op being parsed if any */
- MetaFrameStyle *style; /* frame style being parsed if any */
- MetaFrameStyleSet *style_set; /* frame style set being parsed if any */
- MetaFramePiece piece; /* position of piece being parsed */
- MetaButtonType button_type; /* type of button/menuitem being parsed */
- MetaButtonState button_state; /* state of button being parsed */
-} ParseInfo;
-
-static void set_error (GError **err,
- GMarkupParseContext *context,
- int error_domain,
- int error_code,
- const char *format,
- ...) G_GNUC_PRINTF (5, 6);
-
-static void add_context_to_error (GError **err,
- GMarkupParseContext *context);
-
-static void parse_info_init (ParseInfo *info);
-static void parse_info_free (ParseInfo *info);
-
-static void push_state (ParseInfo *info,
- ParseState state);
-static void pop_state (ParseInfo *info);
-static ParseState peek_state (ParseInfo *info);
-
-
-static void parse_toplevel_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error);
-static void parse_info_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error);
-static void parse_geometry_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error);
-static void parse_draw_op_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error);
-static void parse_gradient_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error);
-static void parse_style_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error);
-static void parse_style_set_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error);
-
-static void parse_piece_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error);
-
-static void parse_button_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error);
-
-static void parse_menu_icon_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error);
-
-static void start_element_handler (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- gpointer user_data,
- GError **error);
-static void end_element_handler (GMarkupParseContext *context,
- const gchar *element_name,
- gpointer user_data,
- GError **error);
-static void text_handler (GMarkupParseContext *context,
- const gchar *text,
- gsize text_len,
- gpointer user_data,
- GError **error);
-
-/* Translators: This means that an attribute which should have been found
- * on an XML element was not in fact found.
- */
-#define ATTRIBUTE_NOT_FOUND _("No \"%s\" attribute on element <%s>")
-
-static GMarkupParser metacity_theme_parser = {
- start_element_handler,
- end_element_handler,
- text_handler,
- NULL,
- NULL
-};
-
-static void
-set_error (GError **err,
- GMarkupParseContext *context,
- int error_domain,
- int error_code,
- const char *format,
- ...)
-{
- int line, ch;
- va_list args;
- char *str;
-
- g_markup_parse_context_get_position (context, &line, &ch);
-
- va_start (args, format);
- str = g_strdup_vprintf (format, args);
- va_end (args);
-
- g_set_error (err, error_domain, error_code,
- _("Line %d character %d: %s"),
- line, ch, str);
-
- g_free (str);
-}
-
-static void
-add_context_to_error (GError **err,
- GMarkupParseContext *context)
-{
- int line, ch;
- char *str;
-
- if (err == NULL || *err == NULL)
- return;
-
- g_markup_parse_context_get_position (context, &line, &ch);
-
- str = g_strdup_printf (_("Line %d character %d: %s"),
- line, ch, (*err)->message);
- g_free ((*err)->message);
- (*err)->message = str;
-}
-
-static void
-parse_info_init (ParseInfo *info)
-{
- info->theme_file = NULL;
- info->states = g_slist_prepend (NULL, GINT_TO_POINTER (STATE_START));
- info->theme = NULL;
- info->name = NULL;
- info->layout = NULL;
- info->op_list = NULL;
- info->op = NULL;
- info->style = NULL;
- info->style_set = NULL;
- info->piece = META_FRAME_PIECE_LAST;
- info->button_type = META_BUTTON_TYPE_LAST;
- info->button_state = META_BUTTON_STATE_LAST;
-}
-
-static void
-parse_info_free (ParseInfo *info)
-{
- g_free (info->theme_file);
- g_free (info->theme_dir);
-
- g_slist_free (info->states);
-
- if (info->theme)
- meta_theme_free (info->theme);
-
- if (info->layout)
- meta_frame_layout_unref (info->layout);
-
- if (info->op_list)
- meta_draw_op_list_unref (info->op_list);
-
- if (info->op)
- meta_draw_op_free (info->op);
-
- if (info->style)
- meta_frame_style_unref (info->style);
-
- if (info->style_set)
- meta_frame_style_set_unref (info->style_set);
-}
-
-static void
-push_state (ParseInfo *info,
- ParseState state)
-{
- info->states = g_slist_prepend (info->states, GINT_TO_POINTER (state));
-}
-
-static void
-pop_state (ParseInfo *info)
-{
- g_return_if_fail (info->states != NULL);
-
- info->states = g_slist_remove (info->states, info->states->data);
-}
-
-static ParseState
-peek_state (ParseInfo *info)
-{
- g_return_val_if_fail (info->states != NULL, STATE_START);
-
- return GPOINTER_TO_INT (info->states->data);
-}
-
-#define ELEMENT_IS(name) (strcmp (element_name, (name)) == 0)
-
-typedef struct
-{
- const char *name;
- const char **retloc;
- gboolean required;
-} LocateAttr;
-
-/* Attribute names can have a leading '!' to indicate that they are
- * required.
- */
-static gboolean
-locate_attributes (GMarkupParseContext *context,
- const char *element_name,
- const char **attribute_names,
- const char **attribute_values,
- GError **error,
- const char *first_attribute_name,
- const char **first_attribute_retloc,
- ...)
-{
- va_list args;
- const char *name;
- const char **retloc;
- int n_attrs;
-#define MAX_ATTRS 24
- LocateAttr attrs[MAX_ATTRS];
- gboolean retval;
- int i;
-
- g_return_val_if_fail (first_attribute_name != NULL, FALSE);
- g_return_val_if_fail (first_attribute_retloc != NULL, FALSE);
-
- retval = TRUE;
-
- /* FIXME: duplicated code; refactor loop */
- n_attrs = 1;
- attrs[0].name = first_attribute_name;
- attrs[0].retloc = first_attribute_retloc;
- attrs[0].required = attrs[0].name[0]=='!';
- if (attrs[0].required)
- attrs[0].name++; /* skip past it */
- *first_attribute_retloc = NULL;
-
- va_start (args, first_attribute_retloc);
-
- name = va_arg (args, const char*);
- retloc = va_arg (args, const char**);
-
- while (name != NULL)
- {
- g_return_val_if_fail (retloc != NULL, FALSE);
-
- g_assert (n_attrs < MAX_ATTRS);
-
- attrs[n_attrs].name = name;
- attrs[n_attrs].retloc = retloc;
- attrs[n_attrs].required = attrs[n_attrs].name[0]=='!';
- if (attrs[n_attrs].required)
- attrs[n_attrs].name++; /* skip past it */
-
- n_attrs += 1;
- *retloc = NULL;
-
- name = va_arg (args, const char*);
- retloc = va_arg (args, const char**);
- }
-
- va_end (args);
-
- i = 0;
- while (attribute_names[i])
- {
- int j;
- gboolean found;
-
- found = FALSE;
- j = 0;
- while (j < n_attrs)
- {
- if (strcmp (attrs[j].name, attribute_names[i]) == 0)
- {
- retloc = attrs[j].retloc;
-
- if (*retloc != NULL)
- {
-
- set_error (error, context,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Attribute \"%s\" repeated twice on the same <%s> element"),
- attrs[j].name, element_name);
- retval = FALSE;
- goto out;
- }
-
- *retloc = attribute_values[i];
- found = TRUE;
- }
-
- ++j;
- }
-
- if (!found)
- {
- j = 0;
- while (j < n_attrs)
- {
- g_warning ("It could have been %s.\n", attrs[j++].name);
- }
-
- set_error (error, context,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Attribute \"%s\" is invalid on <%s> element in this context"),
- attribute_names[i], element_name);
- retval = FALSE;
- goto out;
- }
-
- ++i;
- }
-
- /* Did we catch them all? */
- i = 0;
- while (i < n_attrs)
- {
- if (attrs[i].required && *(attrs[i].retloc)==NULL)
- {
- set_error (error, context,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- ATTRIBUTE_NOT_FOUND,
- attrs[i].name, element_name);
- retval = FALSE;
- goto out;
- }
-
- ++i;
- }
-
- out:
- return retval;
-}
-
-static gboolean
-check_no_attributes (GMarkupParseContext *context,
- const char *element_name,
- const char **attribute_names,
- const char **attribute_values,
- GError **error)
-{
- if (attribute_names[0] != NULL)
- {
- set_error (error, context,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Attribute \"%s\" is invalid on <%s> element in this context"),
- attribute_names[0], element_name);
- return FALSE;
- }
-
- return TRUE;
-}
-
-#define MAX_REASONABLE 4096
-static gboolean
-parse_positive_integer (const char *str,
- int *val,
- GMarkupParseContext *context,
- MetaTheme *theme,
- GError **error)
-{
- char *end;
- long l;
- int j;
-
- *val = 0;
-
- end = NULL;
-
- /* Is str a constant? */
-
- if (META_THEME_ALLOWS (theme, META_THEME_UBIQUITOUS_CONSTANTS) &&
- meta_theme_lookup_int_constant (theme, str, &j))
- {
- /* Yes. */
- l = j;
- }
- else
- {
- /* No. Let's try parsing it instead. */
-
- l = strtol (str, &end, 10);
-
- if (end == NULL || end == str)
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Could not parse \"%s\" as an integer"),
- str);
- return FALSE;
- }
-
- if (*end != '\0')
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Did not understand trailing characters \"%s\" in string \"%s\""),
- end, str);
- return FALSE;
- }
- }
-
- if (l < 0)
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Integer %ld must be positive"), l);
- return FALSE;
- }
-
- if (l > MAX_REASONABLE)
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Integer %ld is too large, current max is %d"),
- l, MAX_REASONABLE);
- return FALSE;
- }
-
- *val = (int) l;
-
- return TRUE;
-}
-
-static gboolean
-parse_double (const char *str,
- double *val,
- GMarkupParseContext *context,
- GError **error)
-{
- char *end;
-
- *val = 0;
-
- end = NULL;
-
- *val = g_ascii_strtod (str, &end);
-
- if (end == NULL || end == str)
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Could not parse \"%s\" as a floating point number"),
- str);
- return FALSE;
- }
-
- if (*end != '\0')
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Did not understand trailing characters \"%s\" in string \"%s\""),
- end, str);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-parse_boolean (const char *str,
- gboolean *val,
- GMarkupParseContext *context,
- GError **error)
-{
- if (strcmp ("true", str) == 0)
- *val = TRUE;
- else if (strcmp ("false", str) == 0)
- *val = FALSE;
- else
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Boolean values must be \"true\" or \"false\" not \"%s\""),
- str);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-parse_rounding (const char *str,
- guint *val,
- GMarkupParseContext *context,
- MetaTheme *theme,
- GError **error)
-{
- if (strcmp ("true", str) == 0)
- *val = 5; /* historical "true" value */
- else if (strcmp ("false", str) == 0)
- *val = 0;
- else
- {
- int tmp;
- gboolean result;
- if (!META_THEME_ALLOWS (theme, META_THEME_VARIED_ROUND_CORNERS))
- {
- /* Not known in this version, so bail. */
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Boolean values must be \"true\" or \"false\" not \"%s\""),
- str);
- return FALSE;
- }
-
- result = parse_positive_integer (str, &tmp, context, theme, error);
-
- *val = tmp;
-
- return result;
- }
-
- return TRUE;
-}
-
-static gboolean
-parse_angle (const char *str,
- double *val,
- GMarkupParseContext *context,
- GError **error)
-{
- if (!parse_double (str, val, context, error))
- return FALSE;
-
- if (*val < (0.0 - 1e6) || *val > (360.0 + 1e6))
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Angle must be between 0.0 and 360.0, was %g\n"),
- *val);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-parse_alpha (const char *str,
- MetaAlphaGradientSpec **spec_ret,
- GMarkupParseContext *context,
- GError **error)
-{
- char **split;
- int i;
- int n_alphas;
- MetaAlphaGradientSpec *spec;
-
- *spec_ret = NULL;
-
- split = g_strsplit (str, ":", -1);
-
- i = 0;
- while (split[i])
- ++i;
-
- if (i == 0)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Could not parse \"%s\" as a floating point number"),
- str);
-
- g_strfreev (split);
-
- return FALSE;
- }
-
- n_alphas = i;
-
- /* FIXME allow specifying horizontal/vertical/diagonal in theme format,
- * once we implement vertical/diagonal in gradient.c
- */
- spec = meta_alpha_gradient_spec_new (META_GRADIENT_HORIZONTAL,
- n_alphas);
-
- i = 0;
- while (i < n_alphas)
- {
- double v;
-
- if (!parse_double (split[i], &v, context, error))
- {
- /* clear up, but don't set error: it was set by parse_double */
- g_strfreev (split);
- meta_alpha_gradient_spec_free (spec);
-
- return FALSE;
- }
-
- if (v < (0.0 - 1e-6) || v > (1.0 + 1e-6))
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n"),
- v);
-
- g_strfreev (split);
- meta_alpha_gradient_spec_free (spec);
-
- return FALSE;
- }
-
- spec->alphas[i] = (unsigned char) (v * 255);
-
- ++i;
- }
-
- g_strfreev (split);
-
- *spec_ret = spec;
-
- return TRUE;
-}
-
-static MetaColorSpec*
-parse_color (MetaTheme *theme,
- const char *str,
- GError **err)
-{
- char* referent;
-
- if (META_THEME_ALLOWS (theme, META_THEME_COLOR_CONSTANTS) &&
- meta_theme_lookup_color_constant (theme, str, &referent))
- {
- if (referent)
- return meta_color_spec_new_from_string (referent, err);
-
- /* no need to free referent: it's a pointer into the actual hash table */
- }
-
- return meta_color_spec_new_from_string (str, err);
-}
-
-static gboolean
-parse_title_scale (const char *str,
- double *val,
- GMarkupParseContext *context,
- GError **error)
-{
- double factor;
-
- if (strcmp (str, "xx-small") == 0)
- factor = PANGO_SCALE_XX_SMALL;
- else if (strcmp (str, "x-small") == 0)
- factor = PANGO_SCALE_X_SMALL;
- else if (strcmp (str, "small") == 0)
- factor = PANGO_SCALE_SMALL;
- else if (strcmp (str, "medium") == 0)
- factor = PANGO_SCALE_MEDIUM;
- else if (strcmp (str, "large") == 0)
- factor = PANGO_SCALE_LARGE;
- else if (strcmp (str, "x-large") == 0)
- factor = PANGO_SCALE_X_LARGE;
- else if (strcmp (str, "xx-large") == 0)
- factor = PANGO_SCALE_XX_LARGE;
- else
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,large,x-large,xx-large)\n"),
- str);
- return FALSE;
- }
-
- *val = factor;
-
- return TRUE;
-}
-
-static void
-parse_toplevel_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error)
-{
- g_return_if_fail (peek_state (info) == STATE_THEME);
-
- if (ELEMENT_IS ("info"))
- {
- if (!check_no_attributes (context, element_name,
- attribute_names, attribute_values,
- error))
- return;
-
- push_state (info, STATE_INFO);
- }
- else if (ELEMENT_IS ("constant"))
- {
- const char *name;
- const char *value;
- int ival = 0;
- double dval = 0.0;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!name", &name, "!value", &value,
- NULL))
- return;
-
- if (strchr (value, '.') && parse_double (value, &dval, context, error))
- {
- g_clear_error (error);
-
- if (!meta_theme_define_float_constant (info->theme,
- name,
- dval,
- error))
- {
- add_context_to_error (error, context);
- return;
- }
- }
- else if (parse_positive_integer (value, &ival, context, info->theme, error))
- {
- g_clear_error (error);
-
- if (!meta_theme_define_int_constant (info->theme,
- name,
- ival,
- error))
- {
- add_context_to_error (error, context);
- return;
- }
- }
- else
- {
- g_clear_error (error);
-
- if (!meta_theme_define_color_constant (info->theme,
- name,
- value,
- error))
- {
- add_context_to_error (error, context);
- return;
- }
- }
-
- push_state (info, STATE_CONSTANT);
- }
- else if (ELEMENT_IS ("frame_geometry"))
- {
- const char *name = NULL;
- const char *parent = NULL;
- const char *has_title = NULL;
- const char *title_scale = NULL;
- const char *rounded_top_left = NULL;
- const char *rounded_top_right = NULL;
- const char *rounded_bottom_left = NULL;
- const char *rounded_bottom_right = NULL;
- const char *hide_buttons = NULL;
- gboolean has_title_val;
- guint rounded_top_left_val;
- guint rounded_top_right_val;
- guint rounded_bottom_left_val;
- guint rounded_bottom_right_val;
- gboolean hide_buttons_val;
- double title_scale_val;
- MetaFrameLayout *parent_layout;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!name", &name, "parent", &parent,
- "has_title", &has_title, "title_scale", &title_scale,
- "rounded_top_left", &rounded_top_left,
- "rounded_top_right", &rounded_top_right,
- "rounded_bottom_left", &rounded_bottom_left,
- "rounded_bottom_right", &rounded_bottom_right,
- "hide_buttons", &hide_buttons,
- NULL))
- return;
-
- has_title_val = TRUE;
- if (has_title && !parse_boolean (has_title, &has_title_val, context, error))
- return;
-
- hide_buttons_val = FALSE;
- if (hide_buttons && !parse_boolean (hide_buttons, &hide_buttons_val, context, error))
- return;
-
- rounded_top_left_val = 0;
- rounded_top_right_val = 0;
- rounded_bottom_left_val = 0;
- rounded_bottom_right_val = 0;
-
- if (rounded_top_left && !parse_rounding (rounded_top_left, &rounded_top_left_val, context, info->theme, error))
- return;
- if (rounded_top_right && !parse_rounding (rounded_top_right, &rounded_top_right_val, context, info->theme, error))
- return;
- if (rounded_bottom_left && !parse_rounding (rounded_bottom_left, &rounded_bottom_left_val, context, info->theme, error))
- return;
- if (rounded_bottom_right && !parse_rounding (rounded_bottom_right, &rounded_bottom_right_val, context, info->theme, error))
- return;
-
- title_scale_val = 1.0;
- if (title_scale && !parse_title_scale (title_scale, &title_scale_val, context, error))
- return;
-
- if (meta_theme_lookup_layout (info->theme, name))
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("<%s> name \"%s\" used a second time"),
- element_name, name);
- return;
- }
-
- parent_layout = NULL;
- if (parent)
- {
- parent_layout = meta_theme_lookup_layout (info->theme, parent);
- if (parent_layout == NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("<%s> parent \"%s\" has not been defined"),
- element_name, parent);
- return;
- }
- }
-
- g_assert (info->layout == NULL);
-
- if (parent_layout)
- info->layout = meta_frame_layout_copy (parent_layout);
- else
- info->layout = meta_frame_layout_new ();
-
- if (has_title) /* only if explicit, otherwise inherit */
- info->layout->has_title = has_title_val;
-
- if (META_THEME_ALLOWS (info->theme, META_THEME_HIDDEN_BUTTONS) && hide_buttons_val)
- info->layout->hide_buttons = hide_buttons_val;
-
- if (title_scale)
- info->layout->title_scale = title_scale_val;
-
- if (rounded_top_left)
- info->layout->top_left_corner_rounded_radius = rounded_top_left_val;
-
- if (rounded_top_right)
- info->layout->top_right_corner_rounded_radius = rounded_top_right_val;
-
- if (rounded_bottom_left)
- info->layout->bottom_left_corner_rounded_radius = rounded_bottom_left_val;
-
- if (rounded_bottom_right)
- info->layout->bottom_right_corner_rounded_radius = rounded_bottom_right_val;
-
- meta_theme_insert_layout (info->theme, name, info->layout);
-
- push_state (info, STATE_FRAME_GEOMETRY);
- }
- else if (ELEMENT_IS ("draw_ops"))
- {
- const char *name = NULL;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!name", &name,
- NULL))
- return;
-
- if (meta_theme_lookup_draw_op_list (info->theme, name))
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("<%s> name \"%s\" used a second time"),
- element_name, name);
- return;
- }
-
- g_assert (info->op_list == NULL);
- info->op_list = meta_draw_op_list_new (2);
-
- meta_theme_insert_draw_op_list (info->theme, name, info->op_list);
-
- push_state (info, STATE_DRAW_OPS);
- }
- else if (ELEMENT_IS ("frame_style"))
- {
- const char *name = NULL;
- const char *parent = NULL;
- const char *geometry = NULL;
- const char *background = NULL;
- const char *alpha = NULL;
- MetaFrameStyle *parent_style;
- MetaFrameLayout *layout;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!name", &name, "parent", &parent,
- "geometry", &geometry,
- "background", &background,
- "alpha", &alpha,
- NULL))
- return;
-
- if (meta_theme_lookup_style (info->theme, name))
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("<%s> name \"%s\" used a second time"),
- element_name, name);
- return;
- }
-
- parent_style = NULL;
- if (parent)
- {
- parent_style = meta_theme_lookup_style (info->theme, parent);
- if (parent_style == NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("<%s> parent \"%s\" has not been defined"),
- element_name, parent);
- return;
- }
- }
-
- layout = NULL;
- if (geometry)
- {
- layout = meta_theme_lookup_layout (info->theme, geometry);
- if (layout == NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("<%s> geometry \"%s\" has not been defined"),
- element_name, geometry);
- return;
- }
- }
- else if (parent_style)
- {
- layout = parent_style->layout;
- }
-
- if (layout == NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("<%s> must specify either a geometry or a parent that has a geometry"),
- element_name);
- return;
- }
-
- g_assert (info->style == NULL);
-
- info->style = meta_frame_style_new (parent_style);
- g_assert (info->style->layout == NULL);
- meta_frame_layout_ref (layout);
- info->style->layout = layout;
-
- if (background != NULL && META_THEME_ALLOWS (info->theme, META_THEME_FRAME_BACKGROUNDS))
- {
- info->style->window_background_color = meta_color_spec_new_from_string (background, error);
- if (!info->style->window_background_color)
- return;
-
- if (alpha != NULL)
- {
-
- gboolean success;
- MetaAlphaGradientSpec *alpha_vector;
-
- g_clear_error (error);
- /* fortunately, we already have a routine to parse alpha values,
- * though it produces a vector of them, which is a superset of
- * what we want.
- */
- success = parse_alpha (alpha, &alpha_vector, context, error);
- if (!success)
- return;
-
- /* alpha_vector->alphas must contain at least one element */
- info->style->window_background_alpha = alpha_vector->alphas[0];
-
- meta_alpha_gradient_spec_free (alpha_vector);
- }
- }
- else if (alpha != NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("You must specify a background for an alpha value to be meaningful"));
- return;
- }
-
- meta_theme_insert_style (info->theme, name, info->style);
-
- push_state (info, STATE_FRAME_STYLE);
- }
- else if (ELEMENT_IS ("frame_style_set"))
- {
- const char *name = NULL;
- const char *parent = NULL;
- MetaFrameStyleSet *parent_set;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!name", &name, "parent", &parent,
- NULL))
- return;
-
- if (meta_theme_lookup_style_set (info->theme, name))
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("<%s> name \"%s\" used a second time"),
- element_name, name);
- return;
- }
-
- parent_set = NULL;
- if (parent)
- {
- parent_set = meta_theme_lookup_style_set (info->theme, parent);
- if (parent_set == NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("<%s> parent \"%s\" has not been defined"),
- element_name, parent);
- return;
- }
- }
-
- g_assert (info->style_set == NULL);
-
- info->style_set = meta_frame_style_set_new (parent_set);
-
- meta_theme_insert_style_set (info->theme, name, info->style_set);
-
- push_state (info, STATE_FRAME_STYLE_SET);
- }
- else if (ELEMENT_IS ("window"))
- {
- const char *type_name = NULL;
- const char *style_set_name = NULL;
- MetaFrameStyleSet *style_set;
- MetaFrameType type;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!type", &type_name, "!style_set", &style_set_name,
- NULL))
- return;
-
- type = meta_frame_type_from_string (type_name);
-
- if (type == META_FRAME_TYPE_LAST)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Unknown type \"%s\" on <%s> element"),
- type_name, element_name);
- return;
- }
-
- style_set = meta_theme_lookup_style_set (info->theme,
- style_set_name);
-
- if (style_set == NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Unknown style_set \"%s\" on <%s> element"),
- style_set_name, element_name);
- return;
- }
-
- if (info->theme->style_sets_by_type[type] != NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Window type \"%s\" has already been assigned a style set"),
- type_name);
- return;
- }
-
- meta_frame_style_set_ref (style_set);
- info->theme->style_sets_by_type[type] = style_set;
-
- push_state (info, STATE_WINDOW);
- }
- else if (ELEMENT_IS ("menu_icon"))
- {
- /* Not supported any more, but we have to parse it if they include it,
- * for backwards compatibility.
- */
- g_assert (info->op_list == NULL);
-
- push_state (info, STATE_MENU_ICON);
- }
- else if (ELEMENT_IS ("fallback"))
- {
- /* Not supported any more, but we have to parse it if they include it,
- * for backwards compatibility.
- */
- push_state (info, STATE_FALLBACK);
- }
- else
- {
- set_error (error, context,
- G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Element <%s> is not allowed below <%s>"),
- element_name, "metacity_theme");
- }
-}
-
-static void
-parse_info_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error)
-{
- g_return_if_fail (peek_state (info) == STATE_INFO);
-
- if (ELEMENT_IS ("name"))
- {
- if (!check_no_attributes (context, element_name,
- attribute_names, attribute_values,
- error))
- return;
-
- push_state (info, STATE_NAME);
- }
- else if (ELEMENT_IS ("author"))
- {
- if (!check_no_attributes (context, element_name,
- attribute_names, attribute_values,
- error))
- return;
-
- push_state (info, STATE_AUTHOR);
- }
- else if (ELEMENT_IS ("copyright"))
- {
- if (!check_no_attributes (context, element_name,
- attribute_names, attribute_values,
- error))
- return;
-
- push_state (info, STATE_COPYRIGHT);
- }
- else if (ELEMENT_IS ("description"))
- {
- if (!check_no_attributes (context, element_name,
- attribute_names, attribute_values,
- error))
- return;
-
- push_state (info, STATE_DESCRIPTION);
- }
- else if (ELEMENT_IS ("date"))
- {
- if (!check_no_attributes (context, element_name,
- attribute_names, attribute_values,
- error))
- return;
-
- push_state (info, STATE_DATE);
- }
- else
- {
- set_error (error, context,
- G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Element <%s> is not allowed below <%s>"),
- element_name, "info");
- }
-}
-
-static void
-parse_distance (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error)
-{
- const char *name;
- const char *value;
- int val;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!name", &name, "!value", &value,
- NULL))
- return;
-
- val = 0;
- if (!parse_positive_integer (value, &val, context, info->theme, error))
- return;
-
- g_assert (val >= 0); /* yeah, "non-negative" not "positive" get over it */
- g_assert (info->layout);
-
- if (strcmp (name, "left_width") == 0)
- info->layout->left_width = val;
- else if (strcmp (name, "right_width") == 0)
- info->layout->right_width = val;
- else if (strcmp (name, "bottom_height") == 0)
- info->layout->bottom_height = val;
- else if (strcmp (name, "title_vertical_pad") == 0)
- info->layout->title_vertical_pad = val;
- else if (strcmp (name, "right_titlebar_edge") == 0)
- info->layout->right_titlebar_edge = val;
- else if (strcmp (name, "left_titlebar_edge") == 0)
- info->layout->left_titlebar_edge = val;
- else if (strcmp (name, "button_width") == 0)
- {
- info->layout->button_width = val;
-
- if (!(info->layout->button_sizing == META_BUTTON_SIZING_LAST ||
- info->layout->button_sizing == META_BUTTON_SIZING_FIXED))
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" for buttons"));
- return;
- }
-
- info->layout->button_sizing = META_BUTTON_SIZING_FIXED;
- }
- else if (strcmp (name, "button_height") == 0)
- {
- info->layout->button_height = val;
-
- if (!(info->layout->button_sizing == META_BUTTON_SIZING_LAST ||
- info->layout->button_sizing == META_BUTTON_SIZING_FIXED))
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" for buttons"));
- return;
- }
-
- info->layout->button_sizing = META_BUTTON_SIZING_FIXED;
- }
- else
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Distance \"%s\" is unknown"), name);
- return;
- }
-}
-
-static void
-parse_aspect_ratio (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error)
-{
- const char *name;
- const char *value;
- double val;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!name", &name, "!value", &value,
- NULL))
- return;
-
- val = 0;
- if (!parse_double (value, &val, context, error))
- return;
-
- g_assert (info->layout);
-
- if (strcmp (name, "button") == 0)
- {
- info->layout->button_aspect = val;
-
- if (info->layout->button_sizing != META_BUTTON_SIZING_LAST)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" for buttons"));
- return;
- }
-
- info->layout->button_sizing = META_BUTTON_SIZING_ASPECT;
- }
- else
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Aspect ratio \"%s\" is unknown"), name);
- return;
- }
-}
-
-static void
-parse_border (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error)
-{
- const char *name;
- const char *top;
- const char *bottom;
- const char *left;
- const char *right;
- int top_val;
- int bottom_val;
- int left_val;
- int right_val;
- GtkBorder *border;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!name", &name,
- "!top", &top,
- "!bottom", &bottom,
- "!left", &left,
- "!right", &right,
- NULL))
- return;
-
- top_val = 0;
- if (!parse_positive_integer (top, &top_val, context, info->theme, error))
- return;
-
- bottom_val = 0;
- if (!parse_positive_integer (bottom, &bottom_val, context, info->theme, error))
- return;
-
- left_val = 0;
- if (!parse_positive_integer (left, &left_val, context, info->theme, error))
- return;
-
- right_val = 0;
- if (!parse_positive_integer (right, &right_val, context, info->theme, error))
- return;
-
- g_assert (info->layout);
-
- border = NULL;
-
- if (strcmp (name, "title_border") == 0)
- border = &info->layout->title_border;
- else if (strcmp (name, "button_border") == 0)
- border = &info->layout->button_border;
-
- if (border == NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Border \"%s\" is unknown"), name);
- return;
- }
-
- border->top = top_val;
- border->bottom = bottom_val;
- border->left = left_val;
- border->right = right_val;
-}
-
-static void
-parse_geometry_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error)
-{
- g_return_if_fail (peek_state (info) == STATE_FRAME_GEOMETRY);
-
- if (ELEMENT_IS ("distance"))
- {
- parse_distance (context, element_name,
- attribute_names, attribute_values,
- info, error);
- push_state (info, STATE_DISTANCE);
- }
- else if (ELEMENT_IS ("border"))
- {
- parse_border (context, element_name,
- attribute_names, attribute_values,
- info, error);
- push_state (info, STATE_BORDER);
- }
- else if (ELEMENT_IS ("aspect_ratio"))
- {
- parse_aspect_ratio (context, element_name,
- attribute_names, attribute_values,
- info, error);
-
- push_state (info, STATE_ASPECT_RATIO);
- }
- else
- {
- set_error (error, context,
- G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Element <%s> is not allowed below <%s>"),
- element_name, "frame_geometry");
- }
-}
-
-#if 0
-static gboolean
-check_expression (PosToken *tokens,
- int n_tokens,
- gboolean has_object,
- MetaTheme *theme,
- GMarkupParseContext *context,
- GError **error)
-{
- MetaPositionExprEnv env;
- int x, y;
-
- /* We set it all to 0 to try and catch divide-by-zero screwups.
- * it's possible we should instead guarantee that widths and heights
- * are at least 1.
- */
-
- env.rect = meta_rect (0, 0, 0, 0);
- if (has_object)
- {
- env.object_width = 0;
- env.object_height = 0;
- }
- else
- {
- env.object_width = -1;
- env.object_height = -1;
- }
-
- env.left_width = 0;
- env.right_width = 0;
- env.top_height = 0;
- env.bottom_height = 0;
- env.title_width = 0;
- env.title_height = 0;
-
- env.icon_width = 0;
- env.icon_height = 0;
- env.mini_icon_width = 0;
- env.mini_icon_height = 0;
- env.theme = theme;
-
- if (!meta_parse_position_expression (tokens, n_tokens,
- &env,
- &x, &y,
- error))
- {
- add_context_to_error (error, context);
- return FALSE;
- }
-
- return TRUE;
-}
-#endif
-
-static void
-parse_draw_op_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error)
-{
- g_return_if_fail (peek_state (info) == STATE_DRAW_OPS);
-
- if (ELEMENT_IS ("line"))
- {
- MetaDrawOp *op;
- const char *color;
- const char *x1;
- const char *y1;
- const char *x2;
- const char *y2;
- const char *dash_on_length;
- const char *dash_off_length;
- const char *width;
- MetaColorSpec *color_spec;
- int dash_on_val;
- int dash_off_val;
- int width_val;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!color", &color,
- "!x1", &x1, "!y1", &y1,
- "!x2", &x2, "!y2", &y2,
- "dash_on_length", &dash_on_length,
- "dash_off_length", &dash_off_length,
- "width", &width,
- NULL))
- return;
-
-#if 0
- if (!check_expression (x1, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (y1, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (x2, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (y2, FALSE, info->theme, context, error))
- return;
-#endif
-
- dash_on_val = 0;
- if (dash_on_length &&
- !parse_positive_integer (dash_on_length, &dash_on_val, context, info->theme, error))
- return;
-
- dash_off_val = 0;
- if (dash_off_length &&
- !parse_positive_integer (dash_off_length, &dash_off_val, context, info->theme, error))
- return;
-
- width_val = 0;
- if (width &&
- !parse_positive_integer (width, &width_val, context, info->theme, error))
- return;
-
- /* Check last so we don't have to free it when other
- * stuff fails
- */
- color_spec = parse_color (info->theme, color, error);
- if (color_spec == NULL)
- {
- add_context_to_error (error, context);
- return;
- }
-
- op = meta_draw_op_new (META_DRAW_LINE);
-
- op->data.line.color_spec = color_spec;
-
- op->data.line.x1 = meta_draw_spec_new (info->theme, x1, NULL);
- op->data.line.y1 = meta_draw_spec_new (info->theme, y1, NULL);
- op->data.line.x2 = meta_draw_spec_new (info->theme, x2, NULL);
- op->data.line.y2 = meta_draw_spec_new (info->theme, y2, NULL);
-
- op->data.line.width = width_val;
- op->data.line.dash_on_length = dash_on_val;
- op->data.line.dash_off_length = dash_off_val;
-
- g_assert (info->op_list);
-
- meta_draw_op_list_append (info->op_list, op);
-
- push_state (info, STATE_LINE);
- }
- else if (ELEMENT_IS ("rectangle"))
- {
- MetaDrawOp *op;
- const char *color;
- const char *x;
- const char *y;
- const char *width;
- const char *height;
- const char *filled;
- gboolean filled_val;
- MetaColorSpec *color_spec;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!color", &color,
- "!x", &x, "!y", &y,
- "!width", &width, "!height", &height,
- "filled", &filled,
- NULL))
- return;
-
-#if 0
- if (!check_expression (x, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (y, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (width, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (height, FALSE, info->theme, context, error))
- return;
-#endif
-
- filled_val = FALSE;
- if (filled && !parse_boolean (filled, &filled_val, context, error))
- return;
-
- /* Check last so we don't have to free it when other
- * stuff fails
- */
- color_spec = parse_color (info->theme, color, error);
- if (color_spec == NULL)
- {
- add_context_to_error (error, context);
- return;
- }
-
- op = meta_draw_op_new (META_DRAW_RECTANGLE);
-
- op->data.rectangle.color_spec = color_spec;
- op->data.rectangle.x = meta_draw_spec_new (info->theme, x, NULL);
- op->data.rectangle.y = meta_draw_spec_new (info->theme, y, NULL);
- op->data.rectangle.width = meta_draw_spec_new (info->theme, width, NULL);
- op->data.rectangle.height = meta_draw_spec_new (info->theme,
- height, NULL);
-
- op->data.rectangle.filled = filled_val;
-
- g_assert (info->op_list);
-
- meta_draw_op_list_append (info->op_list, op);
-
- push_state (info, STATE_RECTANGLE);
- }
- else if (ELEMENT_IS ("arc"))
- {
- MetaDrawOp *op;
- const char *color;
- const char *x;
- const char *y;
- const char *width;
- const char *height;
- const char *filled;
- const char *start_angle;
- const char *extent_angle;
- const char *from;
- const char *to;
- gboolean filled_val;
- double start_angle_val;
- double extent_angle_val;
- MetaColorSpec *color_spec;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!color", &color,
- "!x", &x, "!y", &y,
- "!width", &width, "!height", &height,
- "filled", &filled,
- "start_angle", &start_angle,
- "extent_angle", &extent_angle,
- "from", &from,
- "to", &to,
- NULL))
- return;
-
- if (META_THEME_ALLOWS (info->theme, META_THEME_DEGREES_IN_ARCS) )
- {
- if (start_angle == NULL && from == NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("No \"start_angle\" or \"from\" attribute on element <%s>"), element_name);
- return;
- }
-
- if (extent_angle == NULL && to == NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("No \"extent_angle\" or \"to\" attribute on element <%s>"), element_name);
- return;
- }
- }
- else
- {
- if (start_angle == NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- ATTRIBUTE_NOT_FOUND, "start_angle", element_name);
- return;
- }
-
- if (extent_angle == NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- ATTRIBUTE_NOT_FOUND, "extent_angle", element_name);
- return;
- }
- }
-
-#if 0
- if (!check_expression (x, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (y, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (width, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (height, FALSE, info->theme, context, error))
- return;
-#endif
-
- if (start_angle == NULL)
- {
- if (!parse_angle (from, &start_angle_val, context, error))
- return;
-
- start_angle_val = (180-start_angle_val)/360.0;
- }
- else
- {
- if (!parse_angle (start_angle, &start_angle_val, context, error))
- return;
- }
-
- if (extent_angle == NULL)
- {
- if (!parse_angle (to, &extent_angle_val, context, error))
- return;
-
- extent_angle_val = ((180-extent_angle_val)/360.0) - start_angle_val;
- }
- else
- {
- if (!parse_angle (extent_angle, &extent_angle_val, context, error))
- return;
- }
-
- filled_val = FALSE;
- if (filled && !parse_boolean (filled, &filled_val, context, error))
- return;
-
- /* Check last so we don't have to free it when other
- * stuff fails
- */
- color_spec = parse_color (info->theme, color, error);
- if (color_spec == NULL)
- {
- add_context_to_error (error, context);
- return;
- }
-
- op = meta_draw_op_new (META_DRAW_ARC);
-
- op->data.arc.color_spec = color_spec;
-
- op->data.arc.x = meta_draw_spec_new (info->theme, x, NULL);
- op->data.arc.y = meta_draw_spec_new (info->theme, y, NULL);
- op->data.arc.width = meta_draw_spec_new (info->theme, width, NULL);
- op->data.arc.height = meta_draw_spec_new (info->theme, height, NULL);
-
- op->data.arc.filled = filled_val;
- op->data.arc.start_angle = start_angle_val;
- op->data.arc.extent_angle = extent_angle_val;
-
- g_assert (info->op_list);
-
- meta_draw_op_list_append (info->op_list, op);
-
- push_state (info, STATE_ARC);
- }
- else if (ELEMENT_IS ("clip"))
- {
- MetaDrawOp *op;
- const char *x;
- const char *y;
- const char *width;
- const char *height;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!x", &x, "!y", &y,
- "!width", &width, "!height", &height,
- NULL))
- return;
-
-#if 0
- if (!check_expression (x, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (y, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (width, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (height, FALSE, info->theme, context, error))
- return;
-#endif
- op = meta_draw_op_new (META_DRAW_CLIP);
-
- op->data.clip.x = meta_draw_spec_new (info->theme, x, NULL);
- op->data.clip.y = meta_draw_spec_new (info->theme, y, NULL);
- op->data.clip.width = meta_draw_spec_new (info->theme, width, NULL);
- op->data.clip.height = meta_draw_spec_new (info->theme, height, NULL);
-
- g_assert (info->op_list);
-
- meta_draw_op_list_append (info->op_list, op);
-
- push_state (info, STATE_CLIP);
- }
- else if (ELEMENT_IS ("tint"))
- {
- MetaDrawOp *op;
- const char *color;
- const char *x;
- const char *y;
- const char *width;
- const char *height;
- const char *alpha;
- MetaAlphaGradientSpec *alpha_spec;
- MetaColorSpec *color_spec;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!color", &color,
- "!x", &x, "!y", &y,
- "!width", &width, "!height", &height,
- "!alpha", &alpha,
- NULL))
- return;
-
-#if 0
- if (!check_expression (x, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (y, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (width, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (height, FALSE, info->theme, context, error))
- return;
-#endif
- alpha_spec = NULL;
- if (!parse_alpha (alpha, &alpha_spec, context, error))
- return;
-
- /* Check last so we don't have to free it when other
- * stuff fails
- */
- color_spec = parse_color (info->theme, color, error);
- if (color_spec == NULL)
- {
- if (alpha_spec)
- meta_alpha_gradient_spec_free (alpha_spec);
-
- add_context_to_error (error, context);
- return;
- }
-
- op = meta_draw_op_new (META_DRAW_TINT);
-
- op->data.tint.color_spec = color_spec;
- op->data.tint.alpha_spec = alpha_spec;
-
- op->data.tint.x = meta_draw_spec_new (info->theme, x, NULL);
- op->data.tint.y = meta_draw_spec_new (info->theme, y, NULL);
- op->data.tint.width = meta_draw_spec_new (info->theme, width, NULL);
- op->data.tint.height = meta_draw_spec_new (info->theme, height, NULL);
-
- g_assert (info->op_list);
-
- meta_draw_op_list_append (info->op_list, op);
-
- push_state (info, STATE_TINT);
- }
- else if (ELEMENT_IS ("gradient"))
- {
- const char *x;
- const char *y;
- const char *width;
- const char *height;
- const char *type;
- const char *alpha;
- MetaAlphaGradientSpec *alpha_spec;
- MetaGradientType type_val;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!type", &type,
- "!x", &x, "!y", &y,
- "!width", &width, "!height", &height,
- "alpha", &alpha,
- NULL))
- return;
-
-#if 0
- if (!check_expression (x, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (y, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (width, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (height, FALSE, info->theme, context, error))
- return;
-#endif
-
- type_val = meta_gradient_type_from_string (type);
- if (type_val == META_GRADIENT_LAST)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Did not understand value \"%s\" for type of gradient"),
- type);
- return;
- }
-
- alpha_spec = NULL;
- if (alpha && !parse_alpha (alpha, &alpha_spec, context, error))
- return;
-
- g_assert (info->op == NULL);
- info->op = meta_draw_op_new (META_DRAW_GRADIENT);
-
- info->op->data.gradient.x = meta_draw_spec_new (info->theme, x, NULL);
- info->op->data.gradient.y = meta_draw_spec_new (info->theme, y, NULL);
- info->op->data.gradient.width = meta_draw_spec_new (info->theme,
- width, NULL);
- info->op->data.gradient.height = meta_draw_spec_new (info->theme,
- height, NULL);
-
- info->op->data.gradient.gradient_spec = meta_gradient_spec_new (type_val);
-
- info->op->data.gradient.alpha_spec = alpha_spec;
-
- push_state (info, STATE_GRADIENT);
-
- /* op gets appended on close tag */
- }
- else if (ELEMENT_IS ("image"))
- {
- MetaDrawOp *op;
- const char *filename;
- const char *x;
- const char *y;
- const char *width;
- const char *height;
- const char *alpha;
- const char *colorize;
- const char *fill_type;
- MetaAlphaGradientSpec *alpha_spec;
- GdkPixbuf *pixbuf;
- MetaColorSpec *colorize_spec = NULL;
- MetaImageFillType fill_type_val;
- int h, w, c;
- int pixbuf_width, pixbuf_height, pixbuf_n_channels, pixbuf_rowstride;
- guchar *pixbuf_pixels;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!x", &x, "!y", &y,
- "!width", &width, "!height", &height,
- "alpha", &alpha, "!filename", &filename,
- "colorize", &colorize,
- "fill_type", &fill_type,
- NULL))
- return;
-
-#if 0
- if (!check_expression (x, TRUE, info->theme, context, error))
- return;
-
- if (!check_expression (y, TRUE, info->theme, context, error))
- return;
-
- if (!check_expression (width, TRUE, info->theme, context, error))
- return;
-
- if (!check_expression (height, TRUE, info->theme, context, error))
- return;
-#endif
- fill_type_val = META_IMAGE_FILL_SCALE;
- if (fill_type)
- {
- fill_type_val = meta_image_fill_type_from_string (fill_type);
-
- if (((int) fill_type_val) == -1)
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Did not understand fill type \"%s\" for <%s> element"),
- fill_type, element_name);
- }
- }
-
- /* Check last so we don't have to free it when other
- * stuff fails.
- *
- * If it's a theme image, ask for it at 64px, which is
- * the largest possible. We scale it anyway.
- */
- pixbuf = meta_theme_load_image (info->theme, filename, 64, error);
-
- if (pixbuf == NULL)
- {
- add_context_to_error (error, context);
- return;
- }
-
- if (colorize)
- {
- colorize_spec = parse_color (info->theme, colorize, error);
-
- if (colorize_spec == NULL)
- {
- add_context_to_error (error, context);
- g_object_unref (G_OBJECT (pixbuf));
- return;
- }
- }
-
- alpha_spec = NULL;
- if (alpha && !parse_alpha (alpha, &alpha_spec, context, error))
- {
- g_object_unref (G_OBJECT (pixbuf));
- return;
- }
-
- op = meta_draw_op_new (META_DRAW_IMAGE);
-
- op->data.image.pixbuf = pixbuf;
- op->data.image.colorize_spec = colorize_spec;
-
- op->data.image.x = meta_draw_spec_new (info->theme, x, NULL);
- op->data.image.y = meta_draw_spec_new (info->theme, y, NULL);
- op->data.image.width = meta_draw_spec_new (info->theme, width, NULL);
- op->data.image.height = meta_draw_spec_new (info->theme, height, NULL);
-
- op->data.image.alpha_spec = alpha_spec;
- op->data.image.fill_type = fill_type_val;
-
- /* Check for vertical & horizontal stripes */
- pixbuf_n_channels = gdk_pixbuf_get_n_channels(pixbuf);
- pixbuf_width = gdk_pixbuf_get_width(pixbuf);
- pixbuf_height = gdk_pixbuf_get_height(pixbuf);
- pixbuf_rowstride = gdk_pixbuf_get_rowstride(pixbuf);
- pixbuf_pixels = gdk_pixbuf_get_pixels(pixbuf);
-
- /* Check for horizontal stripes */
- for (h = 0; h < pixbuf_height; h++)
- {
- for (w = 1; w < pixbuf_width; w++)
- {
- for (c = 0; c < pixbuf_n_channels; c++)
- {
- if (pixbuf_pixels[(h * pixbuf_rowstride) + c] !=
- pixbuf_pixels[(h * pixbuf_rowstride) + w + c])
- break;
- }
- if (c < pixbuf_n_channels)
- break;
- }
- if (w < pixbuf_width)
- break;
- }
-
- if (h >= pixbuf_height)
- {
- op->data.image.horizontal_stripes = TRUE;
- }
- else
- {
- op->data.image.horizontal_stripes = FALSE;
- }
-
- /* Check for vertical stripes */
- for (w = 0; w < pixbuf_width; w++)
- {
- for (h = 1; h < pixbuf_height; h++)
- {
- for (c = 0; c < pixbuf_n_channels; c++)
- {
- if (pixbuf_pixels[w + c] !=
- pixbuf_pixels[(h * pixbuf_rowstride) + w + c])
- break;
- }
- if (c < pixbuf_n_channels)
- break;
- }
- if (h < pixbuf_height)
- break;
- }
-
- if (w >= pixbuf_width)
- {
- op->data.image.vertical_stripes = TRUE;
- }
- else
- {
- op->data.image.vertical_stripes = FALSE;
- }
-
- g_assert (info->op_list);
-
- meta_draw_op_list_append (info->op_list, op);
-
- push_state (info, STATE_IMAGE);
- }
- else if (ELEMENT_IS ("gtk_arrow"))
- {
- MetaDrawOp *op;
- const char *state;
- const char *shadow;
- const char *arrow;
- const char *x;
- const char *y;
- const char *width;
- const char *height;
- const char *filled;
- gboolean filled_val;
- GtkStateType state_val;
- GtkShadowType shadow_val;
- GtkArrowType arrow_val;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!state", &state,
- "!shadow", &shadow,
- "!arrow", &arrow,
- "!x", &x, "!y", &y,
- "!width", &width, "!height", &height,
- "filled", &filled,
- NULL))
- return;
-
-#if 0
- if (!check_expression (x, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (y, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (width, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (height, FALSE, info->theme, context, error))
- return;
-#endif
- filled_val = TRUE;
- if (filled && !parse_boolean (filled, &filled_val, context, error))
- return;
-
- state_val = meta_gtk_state_from_string (state);
- if (((int) state_val) == -1)
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Did not understand state \"%s\" for <%s> element"),
- state, element_name);
- return;
- }
-
- shadow_val = meta_gtk_shadow_from_string (shadow);
- if (((int) shadow_val) == -1)
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Did not understand shadow \"%s\" for <%s> element"),
- shadow, element_name);
- return;
- }
-
- arrow_val = meta_gtk_arrow_from_string (arrow);
- if (((int) arrow_val) == -1)
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Did not understand arrow \"%s\" for <%s> element"),
- arrow, element_name);
- return;
- }
-
- op = meta_draw_op_new (META_DRAW_GTK_ARROW);
-
- op->data.gtk_arrow.x = meta_draw_spec_new (info->theme, x, NULL);
- op->data.gtk_arrow.y = meta_draw_spec_new (info->theme, y, NULL);
- op->data.gtk_arrow.width = meta_draw_spec_new (info->theme, width, NULL);
- op->data.gtk_arrow.height = meta_draw_spec_new (info->theme,
- height, NULL);
-
- op->data.gtk_arrow.filled = filled_val;
- op->data.gtk_arrow.state = state_val;
- op->data.gtk_arrow.shadow = shadow_val;
- op->data.gtk_arrow.arrow = arrow_val;
-
- g_assert (info->op_list);
-
- meta_draw_op_list_append (info->op_list, op);
-
- push_state (info, STATE_GTK_ARROW);
- }
- else if (ELEMENT_IS ("gtk_box"))
- {
- MetaDrawOp *op;
- const char *state;
- const char *shadow;
- const char *x;
- const char *y;
- const char *width;
- const char *height;
- GtkStateType state_val;
- GtkShadowType shadow_val;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!state", &state,
- "!shadow", &shadow,
- "!x", &x, "!y", &y,
- "!width", &width, "!height", &height,
- NULL))
- return;
-
-#if 0
- if (!check_expression (x, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (y, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (width, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (height, FALSE, info->theme, context, error))
- return;
-#endif
- state_val = meta_gtk_state_from_string (state);
- if (((int) state_val) == -1)
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Did not understand state \"%s\" for <%s> element"),
- state, element_name);
- return;
- }
-
- shadow_val = meta_gtk_shadow_from_string (shadow);
- if (((int) shadow_val) == -1)
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Did not understand shadow \"%s\" for <%s> element"),
- shadow, element_name);
- return;
- }
-
- op = meta_draw_op_new (META_DRAW_GTK_BOX);
-
- op->data.gtk_box.x = meta_draw_spec_new (info->theme, x, NULL);
- op->data.gtk_box.y = meta_draw_spec_new (info->theme, y, NULL);
- op->data.gtk_box.width = meta_draw_spec_new (info->theme, width, NULL);
- op->data.gtk_box.height = meta_draw_spec_new (info->theme, height, NULL);
-
- op->data.gtk_box.state = state_val;
- op->data.gtk_box.shadow = shadow_val;
-
- g_assert (info->op_list);
-
- meta_draw_op_list_append (info->op_list, op);
-
- push_state (info, STATE_GTK_BOX);
- }
- else if (ELEMENT_IS ("gtk_vline"))
- {
- MetaDrawOp *op;
- const char *state;
- const char *x;
- const char *y1;
- const char *y2;
- GtkStateType state_val;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!state", &state,
- "!x", &x, "!y1", &y1, "!y2", &y2,
- NULL))
- return;
-
-#if 0
- if (!check_expression (x, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (y1, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (y2, FALSE, info->theme, context, error))
- return;
-#endif
-
- state_val = meta_gtk_state_from_string (state);
- if (((int) state_val) == -1)
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Did not understand state \"%s\" for <%s> element"),
- state, element_name);
- return;
- }
-
- op = meta_draw_op_new (META_DRAW_GTK_VLINE);
-
- op->data.gtk_vline.x = meta_draw_spec_new (info->theme, x, NULL);
- op->data.gtk_vline.y1 = meta_draw_spec_new (info->theme, y1, NULL);
- op->data.gtk_vline.y2 = meta_draw_spec_new (info->theme, y2, NULL);
-
- op->data.gtk_vline.state = state_val;
-
- g_assert (info->op_list);
-
- meta_draw_op_list_append (info->op_list, op);
-
- push_state (info, STATE_GTK_VLINE);
- }
- else if (ELEMENT_IS ("icon"))
- {
- MetaDrawOp *op;
- const char *x;
- const char *y;
- const char *width;
- const char *height;
- const char *alpha;
- const char *fill_type;
- MetaAlphaGradientSpec *alpha_spec;
- MetaImageFillType fill_type_val;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!x", &x, "!y", &y,
- "!width", &width, "!height", &height,
- "alpha", &alpha,
- "fill_type", &fill_type,
- NULL))
- return;
-
-#if 0
- if (!check_expression (x, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (y, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (width, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (height, FALSE, info->theme, context, error))
- return;
-#endif
- fill_type_val = META_IMAGE_FILL_SCALE;
- if (fill_type)
- {
- fill_type_val = meta_image_fill_type_from_string (fill_type);
-
- if (((int) fill_type_val) == -1)
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Did not understand fill type \"%s\" for <%s> element"),
- fill_type, element_name);
- }
- }
-
- alpha_spec = NULL;
- if (alpha && !parse_alpha (alpha, &alpha_spec, context, error))
- return;
-
- op = meta_draw_op_new (META_DRAW_ICON);
-
- op->data.icon.x = meta_draw_spec_new (info->theme, x, NULL);
- op->data.icon.y = meta_draw_spec_new (info->theme, y, NULL);
- op->data.icon.width = meta_draw_spec_new (info->theme, width, NULL);
- op->data.icon.height = meta_draw_spec_new (info->theme, height, NULL);
-
- op->data.icon.alpha_spec = alpha_spec;
- op->data.icon.fill_type = fill_type_val;
-
- g_assert (info->op_list);
-
- meta_draw_op_list_append (info->op_list, op);
-
- push_state (info, STATE_ICON);
- }
- else if (ELEMENT_IS ("title"))
- {
- MetaDrawOp *op;
- const char *color;
- const char *x;
- const char *y;
- MetaColorSpec *color_spec;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!color", &color,
- "!x", &x, "!y", &y,
- NULL))
- return;
-
-#if 0
- if (!check_expression (x, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (y, FALSE, info->theme, context, error))
- return;
-#endif
-
- /* Check last so we don't have to free it when other
- * stuff fails
- */
- color_spec = parse_color (info->theme, color, error);
- if (color_spec == NULL)
- {
- add_context_to_error (error, context);
- return;
- }
-
- op = meta_draw_op_new (META_DRAW_TITLE);
-
- op->data.title.color_spec = color_spec;
-
- op->data.title.x = meta_draw_spec_new (info->theme, x, NULL);
- op->data.title.y = meta_draw_spec_new (info->theme, y, NULL);
-
- g_assert (info->op_list);
-
- meta_draw_op_list_append (info->op_list, op);
-
- push_state (info, STATE_TITLE);
- }
- else if (ELEMENT_IS ("include"))
- {
- MetaDrawOp *op;
- const char *name;
- const char *x;
- const char *y;
- const char *width;
- const char *height;
- MetaDrawOpList *op_list;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "x", &x, "y", &y,
- "width", &width, "height", &height,
- "!name", &name,
- NULL))
- return;
-
- /* x/y/width/height default to 0,0,width,height - should
- * probably do this for all the draw ops
- */
-#if 0
- if (x && !check_expression (x, FALSE, info->theme, context, error))
- return;
-
- if (y && !check_expression (y, FALSE, info->theme, context, error))
- return;
-
- if (width && !check_expression (width, FALSE, info->theme, context, error))
- return;
-
- if (height && !check_expression (height, FALSE, info->theme, context, error))
- return;
-#endif
-
- op_list = meta_theme_lookup_draw_op_list (info->theme,
- name);
- if (op_list == NULL)
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("No <draw_ops> called \"%s\" has been defined"),
- name);
- return;
- }
-
- g_assert (info->op_list);
-
- if (op_list == info->op_list ||
- meta_draw_op_list_contains (op_list, info->op_list))
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Including draw_ops \"%s\" here would create a circular reference"),
- name);
- return;
- }
-
- op = meta_draw_op_new (META_DRAW_OP_LIST);
-
- meta_draw_op_list_ref (op_list);
- op->data.op_list.op_list = op_list;
-
- op->data.op_list.x = meta_draw_spec_new (info->theme, x ? x : "0", NULL);
- op->data.op_list.y = meta_draw_spec_new (info->theme, y ? y : "0", NULL);
- op->data.op_list.width = meta_draw_spec_new (info->theme,
- width ? width : "width",
- NULL);
- op->data.op_list.height = meta_draw_spec_new (info->theme,
- height ? height : "height",
- NULL);
-
- meta_draw_op_list_append (info->op_list, op);
-
- push_state (info, STATE_INCLUDE);
- }
- else if (ELEMENT_IS ("tile"))
- {
- MetaDrawOp *op;
- const char *name;
- const char *x;
- const char *y;
- const char *width;
- const char *height;
- const char *tile_xoffset;
- const char *tile_yoffset;
- const char *tile_width;
- const char *tile_height;
- MetaDrawOpList *op_list;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "x", &x, "y", &y,
- "width", &width, "height", &height,
- "!name", &name,
- "tile_xoffset", &tile_xoffset,
- "tile_yoffset", &tile_yoffset,
- "!tile_width", &tile_width,
- "!tile_height", &tile_height,
- NULL))
- return;
-
- /* These default to 0 */
-#if 0
- if (tile_xoffset && !check_expression (tile_xoffset, FALSE, info->theme, context, error))
- return;
-
- if (tile_yoffset && !check_expression (tile_yoffset, FALSE, info->theme, context, error))
- return;
-
- /* x/y/width/height default to 0,0,width,height - should
- * probably do this for all the draw ops
- */
- if (x && !check_expression (x, FALSE, info->theme, context, error))
- return;
-
- if (y && !check_expression (y, FALSE, info->theme, context, error))
- return;
-
- if (width && !check_expression (width, FALSE, info->theme, context, error))
- return;
-
- if (height && !check_expression (height, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (tile_width, FALSE, info->theme, context, error))
- return;
-
- if (!check_expression (tile_height, FALSE, info->theme, context, error))
- return;
-#endif
- op_list = meta_theme_lookup_draw_op_list (info->theme,
- name);
- if (op_list == NULL)
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("No <draw_ops> called \"%s\" has been defined"),
- name);
- return;
- }
-
- g_assert (info->op_list);
-
- if (op_list == info->op_list ||
- meta_draw_op_list_contains (op_list, info->op_list))
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("Including draw_ops \"%s\" here would create a circular reference"),
- name);
- return;
- }
-
- op = meta_draw_op_new (META_DRAW_TILE);
-
- meta_draw_op_list_ref (op_list);
-
- op->data.tile.x = meta_draw_spec_new (info->theme, x ? x : "0", NULL);
- op->data.tile.y = meta_draw_spec_new (info->theme, y ? y : "0", NULL);
- op->data.tile.width = meta_draw_spec_new (info->theme,
- width ? width : "width",
- NULL);
- op->data.tile.height = meta_draw_spec_new (info->theme,
- height ? height : "height",
- NULL);
- op->data.tile.tile_xoffset = meta_draw_spec_new (info->theme,
- tile_xoffset ? tile_xoffset : "0",
- NULL);
- op->data.tile.tile_yoffset = meta_draw_spec_new (info->theme,
- tile_yoffset ? tile_yoffset : "0",
- NULL);
- op->data.tile.tile_width = meta_draw_spec_new (info->theme, tile_width, NULL);
- op->data.tile.tile_height = meta_draw_spec_new (info->theme, tile_height, NULL);
-
- op->data.tile.op_list = op_list;
-
- meta_draw_op_list_append (info->op_list, op);
-
- push_state (info, STATE_TILE);
- }
- else
- {
- set_error (error, context,
- G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Element <%s> is not allowed below <%s>"),
- element_name, "draw_ops");
- }
-}
-
-static void
-parse_gradient_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error)
-{
- g_return_if_fail (peek_state (info) == STATE_GRADIENT);
-
- if (ELEMENT_IS ("color"))
- {
- const char *value = NULL;
- MetaColorSpec *color_spec;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!value", &value,
- NULL))
- return;
-
- color_spec = parse_color (info->theme, value, error);
- if (color_spec == NULL)
- {
- add_context_to_error (error, context);
- return;
- }
-
- g_assert (info->op);
- g_assert (info->op->type == META_DRAW_GRADIENT);
- g_assert (info->op->data.gradient.gradient_spec != NULL);
- info->op->data.gradient.gradient_spec->color_specs =
- g_slist_append (info->op->data.gradient.gradient_spec->color_specs,
- color_spec);
-
- push_state (info, STATE_COLOR);
- }
- else
- {
- set_error (error, context,
- G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Element <%s> is not allowed below <%s>"),
- element_name, "gradient");
- }
-}
-
-static void
-parse_style_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error)
-{
- g_return_if_fail (peek_state (info) == STATE_FRAME_STYLE);
-
- g_assert (info->style);
-
- if (ELEMENT_IS ("piece"))
- {
- const char *position = NULL;
- const char *draw_ops = NULL;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!position", &position,
- "draw_ops", &draw_ops,
- NULL))
- return;
-
- info->piece = meta_frame_piece_from_string (position);
- if (info->piece == META_FRAME_PIECE_LAST)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Unknown position \"%s\" for frame piece"),
- position);
- return;
- }
-
- if (info->style->pieces[info->piece] != NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Frame style already has a piece at position %s"),
- position);
- return;
- }
-
- g_assert (info->op_list == NULL);
-
- if (draw_ops)
- {
- MetaDrawOpList *op_list;
-
- op_list = meta_theme_lookup_draw_op_list (info->theme,
- draw_ops);
-
- if (op_list == NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("No <draw_ops> with the name \"%s\" has been defined"),
- draw_ops);
- return;
- }
-
- meta_draw_op_list_ref (op_list);
- info->op_list = op_list;
- }
-
- push_state (info, STATE_PIECE);
- }
- else if (ELEMENT_IS ("button"))
- {
- const char *function = NULL;
- const char *state = NULL;
- const char *draw_ops = NULL;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!function", &function,
- "!state", &state,
- "draw_ops", &draw_ops,
- NULL))
- return;
-
- info->button_type = meta_button_type_from_string (function, info->theme);
- if (info->button_type == META_BUTTON_TYPE_LAST)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Unknown function \"%s\" for button"),
- function);
- return;
- }
-
- if (meta_theme_earliest_version_with_button (info->button_type) >
- info->theme->format_version)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Button function \"%s\" does not exist in this version (%d, need %d)"),
- function,
- info->theme->format_version,
- meta_theme_earliest_version_with_button (info->button_type)
- );
- return;
- }
-
- info->button_state = meta_button_state_from_string (state);
- if (info->button_state == META_BUTTON_STATE_LAST)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Unknown state \"%s\" for button"),
- state);
- return;
- }
-
- if (info->style->buttons[info->button_type][info->button_state] != NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Frame style already has a button for function %s state %s"),
- function, state);
- return;
- }
-
- g_assert (info->op_list == NULL);
-
- if (draw_ops)
- {
- MetaDrawOpList *op_list;
-
- op_list = meta_theme_lookup_draw_op_list (info->theme,
- draw_ops);
-
- if (op_list == NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("No <draw_ops> with the name \"%s\" has been defined"),
- draw_ops);
- return;
- }
-
- meta_draw_op_list_ref (op_list);
- info->op_list = op_list;
- }
-
- push_state (info, STATE_BUTTON);
- }
- else
- {
- set_error (error, context,
- G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Element <%s> is not allowed below <%s>"),
- element_name, "frame_style");
- }
-}
-
-static void
-parse_style_set_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error)
-{
- g_return_if_fail (peek_state (info) == STATE_FRAME_STYLE_SET);
-
- if (ELEMENT_IS ("frame"))
- {
- const char *focus = NULL;
- const char *state = NULL;
- const char *resize = NULL;
- const char *style = NULL;
- MetaFrameFocus frame_focus;
- MetaFrameState frame_state;
- MetaFrameResize frame_resize;
- MetaFrameStyle *frame_style;
-
- if (!locate_attributes (context, element_name, attribute_names, attribute_values,
- error,
- "!focus", &focus,
- "!state", &state,
- "resize", &resize,
- "!style", &style,
- NULL))
- return;
-
- frame_focus = meta_frame_focus_from_string (focus);
- if (frame_focus == META_FRAME_FOCUS_LAST)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("\"%s\" is not a valid value for focus attribute"),
- focus);
- return;
- }
-
- frame_state = meta_frame_state_from_string (state);
- if (frame_state == META_FRAME_STATE_LAST)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("\"%s\" is not a valid value for state attribute"),
- focus);
- return;
- }
-
- frame_style = meta_theme_lookup_style (info->theme, style);
-
- if (frame_style == NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("A style called \"%s\" has not been defined"),
- style);
- return;
- }
-
- switch (frame_state)
- {
- case META_FRAME_STATE_NORMAL:
- if (resize == NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- ATTRIBUTE_NOT_FOUND,
- "resize", element_name);
- return;
- }
-
-
- frame_resize = meta_frame_resize_from_string (resize);
- if (frame_resize == META_FRAME_RESIZE_LAST)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("\"%s\" is not a valid value for resize attribute"),
- focus);
- return;
- }
-
- break;
-
- case META_FRAME_STATE_SHADED:
- if (META_THEME_ALLOWS (info->theme, META_THEME_UNRESIZABLE_SHADED_STYLES))
- {
- if (resize == NULL)
- /* In state="normal" we would complain here. But instead we accept
- * not having a resize attribute and default to resize="both", since
- * that most closely mimics what we did in v1, and thus people can
- * upgrade a theme to v2 without as much hassle.
- */
- frame_resize = META_FRAME_RESIZE_BOTH;
- else
- {
- frame_resize = meta_frame_resize_from_string (resize);
- if (frame_resize == META_FRAME_RESIZE_LAST)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("\"%s\" is not a valid value for resize attribute"),
- focus);
- return;
- }
- }
- }
- else /* v1 theme */
- {
- if (resize != NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Should not have \"resize\" attribute on <%s> element for maximized/shaded states"),
- element_name);
- return;
- }
-
- /* resize="both" is equivalent to the old behaviour */
- frame_resize = META_FRAME_RESIZE_BOTH;
- }
- break;
-
- default:
- if (resize != NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Should not have \"resize\" attribute on <%s> element for maximized states"),
- element_name);
- return;
- }
-
- frame_resize = META_FRAME_RESIZE_LAST;
- }
-
- switch (frame_state)
- {
- case META_FRAME_STATE_NORMAL:
- if (info->style_set->normal_styles[frame_resize][frame_focus])
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Style has already been specified for state %s resize %s focus %s"),
- state, resize, focus);
- return;
- }
- meta_frame_style_ref (frame_style);
- info->style_set->normal_styles[frame_resize][frame_focus] = frame_style;
- break;
- case META_FRAME_STATE_MAXIMIZED:
- if (info->style_set->maximized_styles[frame_focus])
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Style has already been specified for state %s focus %s"),
- state, focus);
- return;
- }
- meta_frame_style_ref (frame_style);
- info->style_set->maximized_styles[frame_focus] = frame_style;
- break;
- case META_FRAME_STATE_SHADED:
- if (info->style_set->shaded_styles[frame_resize][frame_focus])
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Style has already been specified for state %s resize %s focus %s"),
- state, resize, focus);
- return;
- }
- meta_frame_style_ref (frame_style);
- info->style_set->shaded_styles[frame_resize][frame_focus] = frame_style;
- break;
- case META_FRAME_STATE_MAXIMIZED_AND_SHADED:
- if (info->style_set->maximized_and_shaded_styles[frame_focus])
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Style has already been specified for state %s focus %s"),
- state, focus);
- return;
- }
- meta_frame_style_ref (frame_style);
- info->style_set->maximized_and_shaded_styles[frame_focus] = frame_style;
- break;
- case META_FRAME_STATE_LAST:
- g_assert_not_reached ();
- break;
- }
-
- push_state (info, STATE_FRAME);
- }
- else
- {
- set_error (error, context,
- G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Element <%s> is not allowed below <%s>"),
- element_name, "frame_style_set");
- }
-}
-
-static void
-parse_piece_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error)
-{
- g_return_if_fail (peek_state (info) == STATE_PIECE);
-
- if (ELEMENT_IS ("draw_ops"))
- {
- if (info->op_list)
- {
- set_error (error, context,
- G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Can't have a two draw_ops for a <piece> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)"));
- return;
- }
-
- if (!check_no_attributes (context, element_name, attribute_names, attribute_values,
- error))
- return;
-
- g_assert (info->op_list == NULL);
- info->op_list = meta_draw_op_list_new (2);
-
- push_state (info, STATE_DRAW_OPS);
- }
- else
- {
- set_error (error, context,
- G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Element <%s> is not allowed below <%s>"),
- element_name, "piece");
- }
-}
-
-static void
-parse_button_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error)
-{
- g_return_if_fail (peek_state (info) == STATE_BUTTON);
-
- if (ELEMENT_IS ("draw_ops"))
- {
- if (info->op_list)
- {
- set_error (error, context,
- G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Can't have a two draw_ops for a <button> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)"));
- return;
- }
-
- if (!check_no_attributes (context, element_name, attribute_names, attribute_values,
- error))
- return;
-
- g_assert (info->op_list == NULL);
- info->op_list = meta_draw_op_list_new (2);
-
- push_state (info, STATE_DRAW_OPS);
- }
- else
- {
- set_error (error, context,
- G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Element <%s> is not allowed below <%s>"),
- element_name, "button");
- }
-}
-
-static void
-parse_menu_icon_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- ParseInfo *info,
- GError **error)
-{
- g_return_if_fail (peek_state (info) == STATE_MENU_ICON);
-
- if (ELEMENT_IS ("draw_ops"))
- {
- if (info->op_list)
- {
- set_error (error, context,
- G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Can't have a two draw_ops for a <menu_icon> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)"));
- return;
- }
-
- if (!check_no_attributes (context, element_name, attribute_names, attribute_values,
- error))
- return;
-
- g_assert (info->op_list == NULL);
- info->op_list = meta_draw_op_list_new (2);
-
- push_state (info, STATE_DRAW_OPS);
- }
- else
- {
- set_error (error, context,
- G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Element <%s> is not allowed below <%s>"),
- element_name, "menu_icon");
- }
-}
-
-
-static void
-start_element_handler (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- gpointer user_data,
- GError **error)
-{
- ParseInfo *info = user_data;
-
- switch (peek_state (info))
- {
- case STATE_START:
- if (strcmp (element_name, "metacity_theme") == 0)
- {
- info->theme = meta_theme_new ();
- info->theme->name = g_strdup (info->theme_name);
- info->theme->filename = g_strdup (info->theme_file);
- info->theme->dirname = g_strdup (info->theme_dir);
- info->theme->format_version = info->format_version;
-
- push_state (info, STATE_THEME);
- }
- else
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Outermost element in theme must be <metacity_theme> not <%s>"),
- element_name);
- break;
-
- case STATE_THEME:
- parse_toplevel_element (context, element_name,
- attribute_names, attribute_values,
- info, error);
- break;
- case STATE_INFO:
- parse_info_element (context, element_name,
- attribute_names, attribute_values,
- info, error);
- break;
- case STATE_NAME:
- case STATE_AUTHOR:
- case STATE_COPYRIGHT:
- case STATE_DATE:
- case STATE_DESCRIPTION:
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Element <%s> is not allowed inside a name/author/date/description element"),
- element_name);
- break;
- case STATE_CONSTANT:
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Element <%s> is not allowed inside a <constant> element"),
- element_name);
- break;
- case STATE_FRAME_GEOMETRY:
- parse_geometry_element (context, element_name,
- attribute_names, attribute_values,
- info, error);
- break;
- case STATE_DISTANCE:
- case STATE_BORDER:
- case STATE_ASPECT_RATIO:
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Element <%s> is not allowed inside a distance/border/aspect_ratio element"),
- element_name);
- break;
- case STATE_DRAW_OPS:
- parse_draw_op_element (context, element_name,
- attribute_names, attribute_values,
- info, error);
- break;
- case STATE_LINE:
- case STATE_RECTANGLE:
- case STATE_ARC:
- case STATE_CLIP:
- case STATE_TINT:
- case STATE_IMAGE:
- case STATE_GTK_ARROW:
- case STATE_GTK_BOX:
- case STATE_GTK_VLINE:
- case STATE_ICON:
- case STATE_TITLE:
- case STATE_INCLUDE:
- case STATE_TILE:
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Element <%s> is not allowed inside a draw operation element"),
- element_name);
- break;
- case STATE_GRADIENT:
- parse_gradient_element (context, element_name,
- attribute_names, attribute_values,
- info, error);
- break;
- case STATE_COLOR:
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Element <%s> is not allowed inside a <%s> element"),
- element_name, "color");
- break;
- case STATE_FRAME_STYLE:
- parse_style_element (context, element_name,
- attribute_names, attribute_values,
- info, error);
- break;
- case STATE_PIECE:
- parse_piece_element (context, element_name,
- attribute_names, attribute_values,
- info, error);
- break;
- case STATE_BUTTON:
- parse_button_element (context, element_name,
- attribute_names, attribute_values,
- info, error);
- break;
- case STATE_MENU_ICON:
- parse_menu_icon_element (context, element_name,
- attribute_names, attribute_values,
- info, error);
- break;
- case STATE_FRAME_STYLE_SET:
- parse_style_set_element (context, element_name,
- attribute_names, attribute_values,
- info, error);
- break;
- case STATE_FRAME:
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Element <%s> is not allowed inside a <%s> element"),
- element_name, "frame");
- break;
- case STATE_WINDOW:
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Element <%s> is not allowed inside a <%s> element"),
- element_name, "window");
- break;
- case STATE_FALLBACK:
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Element <%s> is not allowed inside a <%s> element"),
- element_name, "fallback");
- break;
- }
-}
-
-static void
-end_element_handler (GMarkupParseContext *context,
- const gchar *element_name,
- gpointer user_data,
- GError **error)
-{
- ParseInfo *info = user_data;
-
- switch (peek_state (info))
- {
- case STATE_START:
- break;
- case STATE_THEME:
- g_assert (info->theme);
-
- if (!meta_theme_validate (info->theme, error))
- {
- add_context_to_error (error, context);
- meta_theme_free (info->theme);
- info->theme = NULL;
- }
-
- pop_state (info);
- g_assert (peek_state (info) == STATE_START);
- break;
- case STATE_INFO:
- pop_state (info);
- g_assert (peek_state (info) == STATE_THEME);
- break;
- case STATE_NAME:
- pop_state (info);
- g_assert (peek_state (info) == STATE_INFO);
- break;
- case STATE_AUTHOR:
- pop_state (info);
- g_assert (peek_state (info) == STATE_INFO);
- break;
- case STATE_COPYRIGHT:
- pop_state (info);
- g_assert (peek_state (info) == STATE_INFO);
- break;
- case STATE_DATE:
- pop_state (info);
- g_assert (peek_state (info) == STATE_INFO);
- break;
- case STATE_DESCRIPTION:
- pop_state (info);
- g_assert (peek_state (info) == STATE_INFO);
- break;
- case STATE_CONSTANT:
- pop_state (info);
- g_assert (peek_state (info) == STATE_THEME);
- break;
- case STATE_FRAME_GEOMETRY:
- g_assert (info->layout);
-
- if (!meta_frame_layout_validate (info->layout,
- error))
- {
- add_context_to_error (error, context);
- }
-
- /* layout will already be stored in the theme under
- * its name
- */
- meta_frame_layout_unref (info->layout);
- info->layout = NULL;
- pop_state (info);
- g_assert (peek_state (info) == STATE_THEME);
- break;
- case STATE_DISTANCE:
- pop_state (info);
- g_assert (peek_state (info) == STATE_FRAME_GEOMETRY);
- break;
- case STATE_BORDER:
- pop_state (info);
- g_assert (peek_state (info) == STATE_FRAME_GEOMETRY);
- break;
- case STATE_ASPECT_RATIO:
- pop_state (info);
- g_assert (peek_state (info) == STATE_FRAME_GEOMETRY);
- break;
- case STATE_DRAW_OPS:
- {
- g_assert (info->op_list);
-
- if (!meta_draw_op_list_validate (info->op_list,
- error))
- {
- add_context_to_error (error, context);
- meta_draw_op_list_unref (info->op_list);
- info->op_list = NULL;
- }
-
- pop_state (info);
-
- switch (peek_state (info))
- {
- case STATE_BUTTON:
- case STATE_PIECE:
- case STATE_MENU_ICON:
- /* Leave info->op_list to be picked up
- * when these elements are closed
- */
- g_assert (info->op_list);
- break;
- case STATE_THEME:
- g_assert (info->op_list);
- meta_draw_op_list_unref (info->op_list);
- info->op_list = NULL;
- break;
- default:
- /* Op list can't occur in other contexts */
- g_assert_not_reached ();
- break;
- }
- }
- break;
- case STATE_LINE:
- pop_state (info);
- g_assert (peek_state (info) == STATE_DRAW_OPS);
- break;
- case STATE_RECTANGLE:
- pop_state (info);
- g_assert (peek_state (info) == STATE_DRAW_OPS);
- break;
- case STATE_ARC:
- pop_state (info);
- g_assert (peek_state (info) == STATE_DRAW_OPS);
- break;
- case STATE_CLIP:
- pop_state (info);
- g_assert (peek_state (info) == STATE_DRAW_OPS);
- break;
- case STATE_TINT:
- pop_state (info);
- g_assert (peek_state (info) == STATE_DRAW_OPS);
- break;
- case STATE_GRADIENT:
- g_assert (info->op);
- g_assert (info->op->type == META_DRAW_GRADIENT);
- if (!meta_gradient_spec_validate (info->op->data.gradient.gradient_spec,
- error))
- {
- add_context_to_error (error, context);
- meta_draw_op_free (info->op);
- info->op = NULL;
- }
- else
- {
- g_assert (info->op_list);
- meta_draw_op_list_append (info->op_list, info->op);
- info->op = NULL;
- }
- pop_state (info);
- g_assert (peek_state (info) == STATE_DRAW_OPS);
- break;
- case STATE_IMAGE:
- pop_state (info);
- g_assert (peek_state (info) == STATE_DRAW_OPS);
- break;
- case STATE_GTK_ARROW:
- pop_state (info);
- g_assert (peek_state (info) == STATE_DRAW_OPS);
- break;
- case STATE_GTK_BOX:
- pop_state (info);
- g_assert (peek_state (info) == STATE_DRAW_OPS);
- break;
- case STATE_GTK_VLINE:
- pop_state (info);
- g_assert (peek_state (info) == STATE_DRAW_OPS);
- break;
- case STATE_ICON:
- pop_state (info);
- g_assert (peek_state (info) == STATE_DRAW_OPS);
- break;
- case STATE_TITLE:
- pop_state (info);
- g_assert (peek_state (info) == STATE_DRAW_OPS);
- break;
- case STATE_INCLUDE:
- pop_state (info);
- g_assert (peek_state (info) == STATE_DRAW_OPS);
- break;
- case STATE_TILE:
- pop_state (info);
- g_assert (peek_state (info) == STATE_DRAW_OPS);
- break;
- case STATE_COLOR:
- pop_state (info);
- g_assert (peek_state (info) == STATE_GRADIENT);
- break;
- case STATE_FRAME_STYLE:
- g_assert (info->style);
-
- if (!meta_frame_style_validate (info->style,
- info->theme->format_version,
- error))
- {
- add_context_to_error (error, context);
- }
-
- /* Frame style is in the theme hash table and a ref
- * is held there
- */
- meta_frame_style_unref (info->style);
- info->style = NULL;
- pop_state (info);
- g_assert (peek_state (info) == STATE_THEME);
- break;
- case STATE_PIECE:
- g_assert (info->style);
- if (info->op_list == NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("No draw_ops provided for frame piece"));
- }
- else
- {
- info->style->pieces[info->piece] = info->op_list;
- info->op_list = NULL;
- }
- pop_state (info);
- g_assert (peek_state (info) == STATE_FRAME_STYLE);
- break;
- case STATE_BUTTON:
- g_assert (info->style);
- if (info->op_list == NULL)
- {
- set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("No draw_ops provided for button"));
- }
- else
- {
- info->style->buttons[info->button_type][info->button_state] =
- info->op_list;
- info->op_list = NULL;
- }
- pop_state (info);
- break;
- case STATE_MENU_ICON:
- g_assert (info->theme);
- if (info->op_list != NULL)
- {
- meta_draw_op_list_unref (info->op_list);
- info->op_list = NULL;
- }
- pop_state (info);
- g_assert (peek_state (info) == STATE_THEME);
- break;
- case STATE_FRAME_STYLE_SET:
- g_assert (info->style_set);
-
- if (!meta_frame_style_set_validate (info->style_set,
- error))
- {
- add_context_to_error (error, context);
- }
-
- /* Style set is in the theme hash table and a reference
- * is held there.
- */
- meta_frame_style_set_unref (info->style_set);
- info->style_set = NULL;
- pop_state (info);
- g_assert (peek_state (info) == STATE_THEME);
- break;
- case STATE_FRAME:
- pop_state (info);
- g_assert (peek_state (info) == STATE_FRAME_STYLE_SET);
- break;
- case STATE_WINDOW:
- pop_state (info);
- g_assert (peek_state (info) == STATE_THEME);
- break;
- case STATE_FALLBACK:
- pop_state (info);
- g_assert (peek_state (info) == STATE_THEME);
- break;
- }
-}
-
-#define NO_TEXT(element_name) set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, _("No text is allowed inside element <%s>"), element_name)
-
-static gboolean
-all_whitespace (const char *text,
- int text_len)
-{
- const char *p;
- const char *end;
-
- p = text;
- end = text + text_len;
-
- while (p != end)
- {
- if (!g_ascii_isspace (*p))
- return FALSE;
-
- p = g_utf8_next_char (p);
- }
-
- return TRUE;
-}
-
-static void
-text_handler (GMarkupParseContext *context,
- const gchar *text,
- gsize text_len,
- gpointer user_data,
- GError **error)
-{
- ParseInfo *info = user_data;
-
- if (all_whitespace (text, text_len))
- return;
-
- /* FIXME http://bugzilla.gnome.org/show_bug.cgi?id=70448 would
- * allow a nice cleanup here.
- */
-
- switch (peek_state (info))
- {
- case STATE_START:
- g_assert_not_reached (); /* gmarkup shouldn't do this */
- break;
- case STATE_THEME:
- NO_TEXT ("metacity_theme");
- break;
- case STATE_INFO:
- NO_TEXT ("info");
- break;
- case STATE_NAME:
- if (info->theme->readable_name != NULL)
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("<name> specified twice for this theme"));
- return;
- }
-
- info->theme->readable_name = g_strndup (text, text_len);
- break;
- case STATE_AUTHOR:
- if (info->theme->author != NULL)
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("<author> specified twice for this theme"));
- return;
- }
-
- info->theme->author = g_strndup (text, text_len);
- break;
- case STATE_COPYRIGHT:
- if (info->theme->copyright != NULL)
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("<copyright> specified twice for this theme"));
- return;
- }
-
- info->theme->copyright = g_strndup (text, text_len);
- break;
- case STATE_DATE:
- if (info->theme->date != NULL)
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("<date> specified twice for this theme"));
- return;
- }
-
- info->theme->date = g_strndup (text, text_len);
- break;
- case STATE_DESCRIPTION:
- if (info->theme->description != NULL)
- {
- set_error (error, context, G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- _("<description> specified twice for this theme"));
- return;
- }
-
- info->theme->description = g_strndup (text, text_len);
- break;
- case STATE_CONSTANT:
- NO_TEXT ("constant");
- break;
- case STATE_FRAME_GEOMETRY:
- NO_TEXT ("frame_geometry");
- break;
- case STATE_DISTANCE:
- NO_TEXT ("distance");
- break;
- case STATE_BORDER:
- NO_TEXT ("border");
- break;
- case STATE_ASPECT_RATIO:
- NO_TEXT ("aspect_ratio");
- break;
- case STATE_DRAW_OPS:
- NO_TEXT ("draw_ops");
- break;
- case STATE_LINE:
- NO_TEXT ("line");
- break;
- case STATE_RECTANGLE:
- NO_TEXT ("rectangle");
- break;
- case STATE_ARC:
- NO_TEXT ("arc");
- break;
- case STATE_CLIP:
- NO_TEXT ("clip");
- break;
- case STATE_TINT:
- NO_TEXT ("tint");
- break;
- case STATE_GRADIENT:
- NO_TEXT ("gradient");
- break;
- case STATE_IMAGE:
- NO_TEXT ("image");
- break;
- case STATE_GTK_ARROW:
- NO_TEXT ("gtk_arrow");
- break;
- case STATE_GTK_BOX:
- NO_TEXT ("gtk_box");
- break;
- case STATE_GTK_VLINE:
- NO_TEXT ("gtk_vline");
- break;
- case STATE_ICON:
- NO_TEXT ("icon");
- break;
- case STATE_TITLE:
- NO_TEXT ("title");
- break;
- case STATE_INCLUDE:
- NO_TEXT ("include");
- break;
- case STATE_TILE:
- NO_TEXT ("tile");
- break;
- case STATE_COLOR:
- NO_TEXT ("color");
- break;
- case STATE_FRAME_STYLE:
- NO_TEXT ("frame_style");
- break;
- case STATE_PIECE:
- NO_TEXT ("piece");
- break;
- case STATE_BUTTON:
- NO_TEXT ("button");
- break;
- case STATE_MENU_ICON:
- NO_TEXT ("menu_icon");
- break;
- case STATE_FRAME_STYLE_SET:
- NO_TEXT ("frame_style_set");
- break;
- case STATE_FRAME:
- NO_TEXT ("frame");
- break;
- case STATE_WINDOW:
- NO_TEXT ("window");
- break;
- case STATE_FALLBACK:
- NO_TEXT ("fallback");
- break;
- }
-}
-
-/* We were intending to put the version number
- * in the subdirectory name, but we ended up
- * using the filename instead. The "-1" survives
- * as a fossil.
- */
-#define THEME_SUBDIR "metacity-1"
-
-/* Highest version of the theme format to
- * look out for.
- */
-#define THEME_VERSION 2
-
-#define METACITY_THEME_FILENAME_FORMAT "metacity-theme-%d.xml"
-
-MetaTheme*
-meta_theme_load (const char *theme_name,
- GError **err)
-{
- GMarkupParseContext *context;
- GError *error;
- ParseInfo info;
- char *text;
- gsize length;
- char *theme_file;
- char *theme_dir;
- MetaTheme *retval;
- guint version;
- const gchar* const* xdg_data_dirs;
- int i;
-
- text = NULL;
- length = 0;
- retval = NULL;
- context = NULL;
-
- theme_dir = NULL;
- theme_file = NULL;
-
- if (meta_is_debugging ())
- {
- gchar *theme_filename = g_strdup_printf (METACITY_THEME_FILENAME_FORMAT,
- THEME_VERSION);
-
- /* Try in themes in our source tree */
- theme_dir = g_build_filename ("./themes", theme_name, NULL);
-
- theme_file = g_build_filename (theme_dir,
- theme_filename,
- NULL);
-
- error = NULL;
- if (!g_file_get_contents (theme_file,
- &text,
- &length,
- &error))
- {
- meta_topic (META_DEBUG_THEMES, "Failed to read theme from file %s: %s\n",
- theme_file, error->message);
- g_error_free (error);
- g_free (theme_dir);
- g_free (theme_file);
- theme_file = NULL;
- }
- version = THEME_VERSION;
-
- g_free (theme_filename);
- }
-
- /* We try all supported versions from current to oldest */
- for (version = THEME_VERSION; (version > 0) && (text == NULL); version--)
- {
- gchar *theme_filename = g_strdup_printf (METACITY_THEME_FILENAME_FORMAT,
- version);
-
- /* We try first in home dir, XDG_DATA_DIRS, then system dir for themes */
-
- /* Try home dir for themes */
- theme_dir = g_build_filename (g_get_home_dir (),
- ".themes",
- theme_name,
- THEME_SUBDIR,
- NULL);
-
- theme_file = g_build_filename (theme_dir,
- theme_filename,
- NULL);
-
- error = NULL;
- if (!g_file_get_contents (theme_file,
- &text,
- &length,
- &error))
- {
- meta_topic (META_DEBUG_THEMES, "Failed to read theme from file %s: %s\n",
- theme_file, error->message);
- g_error_free (error);
- g_free (theme_dir);
- g_free (theme_file);
- theme_file = NULL;
- }
-
- /* Try each XDG_DATA_DIRS for theme */
- xdg_data_dirs = g_get_system_data_dirs();
- for(i = 0; xdg_data_dirs[i] != NULL; i++)
- {
- if (text == NULL)
- {
- theme_dir = g_build_filename (xdg_data_dirs[i],
- "themes",
- theme_name,
- THEME_SUBDIR,
- NULL);
-
- theme_file = g_build_filename (theme_dir,
- theme_filename,
- NULL);
-
- error = NULL;
- if (!g_file_get_contents (theme_file,
- &text,
- &length,
- &error))
- {
- meta_topic (META_DEBUG_THEMES, "Failed to read theme from file %s: %s\n",
- theme_file, error->message);
- g_error_free (error);
- g_free (theme_dir);
- g_free (theme_file);
- theme_file = NULL;
- }
- else
- {
- break;
- }
- }
- }
-
- /* Look for themes in METACITY_DATADIR */
- if (text == NULL)
- {
- theme_dir = g_build_filename (METACITY_DATADIR,
- "themes",
- theme_name,
- THEME_SUBDIR,
- NULL);
-
- theme_file = g_build_filename (theme_dir,
- theme_filename,
- NULL);
-
- error = NULL;
- if (!g_file_get_contents (theme_file,
- &text,
- &length,
- &error))
- {
- meta_topic (META_DEBUG_THEMES, "Failed to read theme from file %s: %s\n",
- theme_file, error->message);
- g_error_free (error);
- g_free (theme_dir);
- g_free (theme_file);
- theme_file = NULL;
- }
- }
-
- g_free (theme_filename);
- }
-
- if (text == NULL)
- {
- g_set_error (err, META_THEME_ERROR, META_THEME_ERROR_FAILED,
- _("Failed to find a valid file for theme %s\n"),
- theme_name);
-
- return NULL; /* all fallbacks failed */
- }
-
- meta_topic (META_DEBUG_THEMES, "Parsing theme file %s\n", theme_file);
-
-
- parse_info_init (&info);
- info.theme_name = theme_name;
-
- /* pass ownership to info so we free it with the info */
- info.theme_file = theme_file;
- info.theme_dir = theme_dir;
-
- info.format_version = version + 1;
-
- context = g_markup_parse_context_new (&metacity_theme_parser,
- 0, &info, NULL);
-
- error = NULL;
- if (!g_markup_parse_context_parse (context,
- text,
- length,
- &error))
- goto out;
-
- error = NULL;
- if (!g_markup_parse_context_end_parse (context, &error))
- goto out;
-
- goto out;
-
- out:
-
- if (context)
- g_markup_parse_context_free (context);
- g_free (text);
-
- if (info.theme)
- info.theme->format_version = info.format_version;
-
- if (error)
- {
- g_propagate_error (err, error);
- }
- else if (info.theme)
- {
- /* Steal theme from info */
- retval = info.theme;
- info.theme = NULL;
- }
- else
- {
- g_set_error (err, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("Theme file %s did not contain a root <metacity_theme> element"),
- info.theme_file);
- }
-
- parse_info_free (&info);
-
- return retval;
-}
diff --git a/src/ui/theme-parser.h b/src/ui/theme-parser.h
deleted file mode 100644
index 035d7005..00000000
--- a/src/ui/theme-parser.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity theme parsing */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "theme.h"
-
-#ifndef META_THEME_PARSER_H
-#define META_THEME_PARSER_H
-
-MetaTheme* meta_theme_load (const char *theme_name,
- GError **err);
-
-#endif
diff --git a/src/ui/theme-viewer.c b/src/ui/theme-viewer.c
deleted file mode 100644
index 5787ad4b..00000000
--- a/src/ui/theme-viewer.c
+++ /dev/null
@@ -1,1336 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity theme viewer and test app main() */
-
-/*
- * Copyright (C) 2002 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-#include "util.h"
-#include "theme.h"
-#include "theme-parser.h"
-#include "preview-widget.h"
-#include <gtk/gtk.h>
-#include <time.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <libintl.h>
-#define _(x) dgettext (GETTEXT_PACKAGE, x)
-#define N_(x) x
-
-/* We need to compute all different button arrangements
- * in terms of button location. We don't care about
- * different arrangements in terms of button function.
- *
- * So if dups are allowed, from 0-4 buttons on the left, from 0-4 on
- * the right, 5x5=25 combinations.
- *
- * If no dups, 0-4 on left determines the number on the right plus
- * we have a special case for the "no buttons on either side" case.
- */
-#ifndef ALLOW_DUPLICATE_BUTTONS
-#define BUTTON_LAYOUT_COMBINATIONS (MAX_BUTTONS_PER_CORNER + 1 + 1)
-#else
-#define BUTTON_LAYOUT_COMBINATIONS ((MAX_BUTTONS_PER_CORNER+1)*(MAX_BUTTONS_PER_CORNER+1))
-#endif
-
-enum
-{
- FONT_SIZE_SMALL,
- FONT_SIZE_NORMAL,
- FONT_SIZE_LARGE,
- FONT_SIZE_LAST
-};
-
-static MetaTheme *global_theme = NULL;
-static GtkWidget *previews[META_FRAME_TYPE_LAST*FONT_SIZE_LAST + BUTTON_LAYOUT_COMBINATIONS] = { NULL, };
-static double milliseconds_to_draw_frame = 0.0;
-
-static void run_position_expression_tests (void);
-#if 0
-static void run_position_expression_timings (void);
-#endif
-static void run_theme_benchmark (void);
-
-
-static GtkItemFactoryEntry menu_items[] =
-{
- { N_("/_Windows"), NULL, NULL, 0, "<Branch>" },
- { N_("/Windows/tearoff"), NULL, NULL, 0, "<Tearoff>" },
- { N_("/Windows/_Dialog"), "<control>d", NULL, 0, NULL },
- { N_("/Windows/_Modal dialog"), NULL, NULL, 0, NULL },
- { N_("/Windows/_Utility"), "<control>u", NULL, 0, NULL },
- { N_("/Windows/_Splashscreen"), "<control>s", NULL, 0, NULL },
- { N_("/Windows/_Top dock"), NULL, NULL, 0, NULL },
- { N_("/Windows/_Bottom dock"), NULL, NULL, 0, NULL },
- { N_("/Windows/_Left dock"), NULL, NULL, 0, NULL },
- { N_("/Windows/_Right dock"), NULL, NULL, 0, NULL },
- { N_("/Windows/_All docks"), NULL, NULL, 0, NULL },
- { N_("/Windows/Des_ktop"), NULL, NULL, 0, NULL }
-};
-
-static GtkWidget *
-normal_contents (void)
-{
- GtkWidget *table;
- GtkWidget *toolbar;
- GtkWidget *handlebox;
- GtkWidget *statusbar;
- GtkWidget *contents;
- GtkWidget *sw;
- GtkItemFactory *item_factory;
-
- table = gtk_table_new (1, 4, FALSE);
-
- /* Create the menubar
- */
-
- item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", NULL);
-
- gtk_item_factory_set_translate_func(item_factory,
- (GtkTranslateFunc)gettext, NULL, NULL);
-
- /* Set up item factory to go away */
- g_object_ref (item_factory);
- gtk_object_sink (GTK_OBJECT (item_factory));
- g_object_set_data_full (G_OBJECT (table),
- "<main>",
- item_factory,
- (GDestroyNotify) g_object_unref);
-
- /* create menu items */
- gtk_item_factory_create_items (item_factory, G_N_ELEMENTS (menu_items),
- menu_items, NULL);
-
- gtk_table_attach (GTK_TABLE (table),
- gtk_item_factory_get_widget (item_factory, "<main>"),
- /* X direction */ /* Y direction */
- 0, 1, 0, 1,
- GTK_EXPAND | GTK_FILL, 0,
- 0, 0);
-
- /* Create the toolbar
- */
- toolbar = gtk_toolbar_new ();
-
- gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
- GTK_STOCK_NEW,
- _("Open another one of these windows"),
- NULL,
- NULL, NULL,
- -1); /* -1 means "append" */
-
- gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
- GTK_STOCK_OPEN,
- _("This is a demo button with an 'open' icon"),
- NULL,
- NULL, NULL,
- -1); /* -1 means "append" */
-
- gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
- GTK_STOCK_QUIT,
- _("This is a demo button with a 'quit' icon"),
- NULL,
- NULL, NULL,
- -1); /* -1 means "append" */
-
- handlebox = gtk_handle_box_new ();
-
- gtk_container_add (GTK_CONTAINER (handlebox), toolbar);
-
- gtk_table_attach (GTK_TABLE (table),
- handlebox,
- /* X direction */ /* Y direction */
- 0, 1, 1, 2,
- GTK_EXPAND | GTK_FILL, 0,
- 0, 0);
-
- /* Create document
- */
-
- sw = gtk_scrolled_window_new (NULL, NULL);
-
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
-
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
- GTK_SHADOW_IN);
-
- gtk_table_attach (GTK_TABLE (table),
- sw,
- /* X direction */ /* Y direction */
- 0, 1, 2, 3,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
- 0, 0);
-
- contents = gtk_text_view_new ();
- gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (contents),
- PANGO_WRAP_WORD);
-
- gtk_container_add (GTK_CONTAINER (sw),
- contents);
-
- /* Create statusbar */
-
- statusbar = gtk_statusbar_new ();
- gtk_table_attach (GTK_TABLE (table),
- statusbar,
- /* X direction */ /* Y direction */
- 0, 1, 3, 4,
- GTK_EXPAND | GTK_FILL, 0,
- 0, 0);
-
- gtk_widget_show_all (table);
-
- return table;
-}
-
-static void
-update_spacings (GtkWidget *vbox,
- GtkWidget *action_area)
-{
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
- gtk_box_set_spacing (GTK_BOX (action_area), 10);
- gtk_container_set_border_width (GTK_CONTAINER (action_area), 5);
-}
-
-static GtkWidget*
-dialog_contents (void)
-{
- GtkWidget *vbox;
- GtkWidget *hbox;
- GtkWidget *action_area;
- GtkWidget *label;
- GtkWidget *image;
- GtkWidget *button;
-
- vbox = gtk_vbox_new (FALSE, 0);
-
- action_area = gtk_hbutton_box_new ();
-
- gtk_button_box_set_layout (GTK_BUTTON_BOX (action_area),
- GTK_BUTTONBOX_END);
-
- button = gtk_button_new_from_stock (GTK_STOCK_OK);
- gtk_box_pack_end (GTK_BOX (action_area),
- button,
- FALSE, TRUE, 0);
-
- gtk_box_pack_end (GTK_BOX (vbox), action_area,
- FALSE, TRUE, 0);
-
- update_spacings (vbox, action_area);
-
- label = gtk_label_new (_("This is a sample message in a sample dialog"));
- image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO,
- GTK_ICON_SIZE_DIALOG);
- gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
-
- gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
- gtk_label_set_selectable (GTK_LABEL (label), TRUE);
-
- hbox = gtk_hbox_new (FALSE, 6);
-
- gtk_box_pack_start (GTK_BOX (hbox), image,
- FALSE, FALSE, 0);
-
- gtk_box_pack_start (GTK_BOX (hbox), label,
- TRUE, TRUE, 0);
-
- gtk_box_pack_start (GTK_BOX (vbox),
- hbox,
- FALSE, FALSE, 0);
-
- gtk_widget_show_all (vbox);
-
- return vbox;
-}
-
-static GtkWidget*
-utility_contents (void)
-{
- GtkWidget *table;
- GtkWidget *button;
- int i, j;
-
- table = gtk_table_new (3, 4, FALSE);
-
- i = 0;
- while (i < 3)
- {
- j = 0;
- while (j < 4)
- {
- char *str;
-
- str = g_strdup_printf ("_%c", (char) ('A' + 4*i + j));
-
- button = gtk_button_new_with_mnemonic (str);
-
- g_free (str);
-
- gtk_table_attach (GTK_TABLE (table),
- button,
- /* X direction */ /* Y direction */
- i, i+1, j, j+1,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
- 0, 0);
-
- ++j;
- }
-
- ++i;
- }
-
- gtk_widget_show_all (table);
-
- return table;
-}
-
-static GtkWidget*
-menu_contents (void)
-{
- GtkWidget *vbox;
- GtkWidget *mi;
- int i;
- GtkWidget *frame;
-
- frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type (GTK_FRAME (frame),
- GTK_SHADOW_OUT);
-
- vbox = gtk_vbox_new (FALSE, 0);
-
- i = 0;
- while (i < 10)
- {
- char *str = g_strdup_printf (_("Fake menu item %d\n"), i + 1);
- mi = gtk_label_new (str);
- gtk_misc_set_alignment (GTK_MISC (mi), 0.0, 0.5);
- g_free (str);
- gtk_box_pack_start (GTK_BOX (vbox), mi, FALSE, FALSE, 0);
-
- ++i;
- }
-
- gtk_container_add (GTK_CONTAINER (frame), vbox);
-
- gtk_widget_show_all (frame);
-
- return frame;
-}
-
-static GtkWidget*
-border_only_contents (void)
-{
- GtkWidget *event_box;
- GtkWidget *vbox;
- GtkWidget *w;
- GdkColor color;
-
- event_box = gtk_event_box_new ();
-
- color.red = 40000;
- color.green = 0;
- color.blue = 40000;
- gtk_widget_modify_bg (event_box, GTK_STATE_NORMAL, &color);
-
- vbox = gtk_vbox_new (FALSE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 3);
-
- w = gtk_label_new (_("Border-only window"));
- gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
- w = gtk_button_new_with_label (_("Bar"));
- gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
-
- gtk_container_add (GTK_CONTAINER (event_box), vbox);
-
- gtk_widget_show_all (event_box);
-
- return event_box;
-}
-
-static GtkWidget*
-get_window_contents (MetaFrameType type,
- const char **title)
-{
- switch (type)
- {
- case META_FRAME_TYPE_NORMAL:
- *title = _("Normal Application Window");
- return normal_contents ();
-
- case META_FRAME_TYPE_DIALOG:
- *title = _("Dialog Box");
- return dialog_contents ();
-
- case META_FRAME_TYPE_MODAL_DIALOG:
- *title = _("Modal Dialog Box");
- return dialog_contents ();
-
- case META_FRAME_TYPE_UTILITY:
- *title = _("Utility Palette");
- return utility_contents ();
-
- case META_FRAME_TYPE_MENU:
- *title = _("Torn-off Menu");
- return menu_contents ();
-
- case META_FRAME_TYPE_BORDER:
- *title = _("Border");
- return border_only_contents ();
-
- case META_FRAME_TYPE_LAST:
- g_assert_not_reached ();
- break;
- }
-
- return NULL;
-}
-
-static MetaFrameFlags
-get_window_flags (MetaFrameType type)
-{
- MetaFrameFlags flags;
-
- flags = META_FRAME_ALLOWS_DELETE |
- META_FRAME_ALLOWS_MENU |
- META_FRAME_ALLOWS_MINIMIZE |
- META_FRAME_ALLOWS_MAXIMIZE |
- META_FRAME_ALLOWS_VERTICAL_RESIZE |
- META_FRAME_ALLOWS_HORIZONTAL_RESIZE |
- META_FRAME_HAS_FOCUS |
- META_FRAME_ALLOWS_SHADE |
- META_FRAME_ALLOWS_MOVE;
-
- switch (type)
- {
- case META_FRAME_TYPE_NORMAL:
- break;
-
- case META_FRAME_TYPE_DIALOG:
- case META_FRAME_TYPE_MODAL_DIALOG:
- flags &= ~(META_FRAME_ALLOWS_MINIMIZE |
- META_FRAME_ALLOWS_MAXIMIZE);
- break;
-
- case META_FRAME_TYPE_UTILITY:
- flags &= ~(META_FRAME_ALLOWS_MINIMIZE |
- META_FRAME_ALLOWS_MAXIMIZE);
- break;
-
- case META_FRAME_TYPE_MENU:
- flags &= ~(META_FRAME_ALLOWS_MINIMIZE |
- META_FRAME_ALLOWS_MAXIMIZE);
- break;
-
- case META_FRAME_TYPE_BORDER:
- break;
-
- case META_FRAME_TYPE_LAST:
- g_assert_not_reached ();
- break;
- }
-
- return flags;
-}
-
-static GtkWidget*
-preview_collection (int font_size,
- PangoFontDescription *base_desc)
-{
- GtkWidget *box;
- GtkWidget *sw;
- GdkColor desktop_color;
- int i;
- GtkWidget *eventbox;
-
- sw = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
-
- box = gtk_vbox_new (FALSE, 0);
- gtk_box_set_spacing (GTK_BOX (box), 20);
- gtk_container_set_border_width (GTK_CONTAINER (box), 20);
-
- eventbox = gtk_event_box_new ();
- gtk_container_add (GTK_CONTAINER (eventbox), box);
-
- gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw), eventbox);
-
- desktop_color.red = 0x5144;
- desktop_color.green = 0x75D6;
- desktop_color.blue = 0xA699;
-
- gtk_widget_modify_bg (eventbox, GTK_STATE_NORMAL, &desktop_color);
-
- i = 0;
- while (i < META_FRAME_TYPE_LAST)
- {
- const char *title = NULL;
- GtkWidget *contents;
- GtkWidget *align;
- double xalign, yalign;
- GtkWidget *eventbox2;
- GtkWidget *preview;
- PangoFontDescription *font_desc;
- double scale;
-
- eventbox2 = gtk_event_box_new ();
-
- preview = meta_preview_new ();
-
- gtk_container_add (GTK_CONTAINER (eventbox2), preview);
-
- meta_preview_set_frame_type (META_PREVIEW (preview), i);
- meta_preview_set_frame_flags (META_PREVIEW (preview),
- get_window_flags (i));
-
- meta_preview_set_theme (META_PREVIEW (preview), global_theme);
-
- contents = get_window_contents (i, &title);
-
- meta_preview_set_title (META_PREVIEW (preview), title);
-
- gtk_container_add (GTK_CONTAINER (preview), contents);
-
- if (i == META_FRAME_TYPE_MENU)
- {
- xalign = 0.0;
- yalign = 0.0;
- }
- else
- {
- xalign = 0.5;
- yalign = 0.5;
- }
-
- align = gtk_alignment_new (0.0, 0.0, xalign, yalign);
- gtk_container_add (GTK_CONTAINER (align), eventbox2);
-
- gtk_box_pack_start (GTK_BOX (box), align, TRUE, TRUE, 0);
-
- switch (font_size)
- {
- case FONT_SIZE_SMALL:
- scale = PANGO_SCALE_XX_SMALL;
- break;
- case FONT_SIZE_LARGE:
- scale = PANGO_SCALE_XX_LARGE;
- break;
- default:
- scale = 1.0;
- break;
- }
-
- if (scale != 1.0)
- {
- font_desc = pango_font_description_new ();
-
- pango_font_description_set_size (font_desc,
- MAX (pango_font_description_get_size (base_desc) * scale, 1));
-
- gtk_widget_modify_font (preview, font_desc);
-
- pango_font_description_free (font_desc);
- }
-
- previews[font_size*META_FRAME_TYPE_LAST + i] = preview;
-
- ++i;
- }
-
- return sw;
-}
-
-static MetaButtonLayout different_layouts[BUTTON_LAYOUT_COMBINATIONS];
-
-static void
-init_layouts (void)
-{
- int i;
-
- /* Blank out all the layouts */
- i = 0;
- while (i < (int) G_N_ELEMENTS (different_layouts))
- {
- int j;
-
- j = 0;
- while (j < MAX_BUTTONS_PER_CORNER)
- {
- different_layouts[i].left_buttons[j] = META_BUTTON_FUNCTION_LAST;
- different_layouts[i].right_buttons[j] = META_BUTTON_FUNCTION_LAST;
- ++j;
- }
- ++i;
- }
-
-#ifndef ALLOW_DUPLICATE_BUTTONS
- i = 0;
- while (i <= MAX_BUTTONS_PER_CORNER)
- {
- int j;
-
- j = 0;
- while (j < i)
- {
- different_layouts[i].right_buttons[j] = (MetaButtonFunction) j;
- ++j;
- }
- while (j < MAX_BUTTONS_PER_CORNER)
- {
- different_layouts[i].left_buttons[j-i] = (MetaButtonFunction) j;
- ++j;
- }
-
- ++i;
- }
-
- /* Special extra case for no buttons on either side */
- different_layouts[i].left_buttons[0] = META_BUTTON_FUNCTION_LAST;
- different_layouts[i].right_buttons[0] = META_BUTTON_FUNCTION_LAST;
-
-#else
- /* FIXME this code is if we allow duplicate buttons,
- * which we currently do not
- */
- int left;
- int i;
-
- left = 0;
- i = 0;
-
- while (left < MAX_BUTTONS_PER_CORNER)
- {
- int right;
-
- right = 0;
-
- while (right < MAX_BUTTONS_PER_CORNER)
- {
- int j;
-
- static MetaButtonFunction left_functions[MAX_BUTTONS_PER_CORNER] = {
- META_BUTTON_FUNCTION_MENU,
- META_BUTTON_FUNCTION_MINIMIZE,
- META_BUTTON_FUNCTION_MAXIMIZE,
- META_BUTTON_FUNCTION_CLOSE
- };
- static MetaButtonFunction right_functions[MAX_BUTTONS_PER_CORNER] = {
- META_BUTTON_FUNCTION_MINIMIZE,
- META_BUTTON_FUNCTION_MAXIMIZE,
- META_BUTTON_FUNCTION_CLOSE,
- META_BUTTON_FUNCTION_MENU
- };
-
- g_assert (i < BUTTON_LAYOUT_COMBINATIONS);
-
- j = 0;
- while (j <= left)
- {
- different_layouts[i].left_buttons[j] = left_functions[j];
- ++j;
- }
-
- j = 0;
- while (j <= right)
- {
- different_layouts[i].right_buttons[j] = right_functions[j];
- ++j;
- }
-
- ++i;
-
- ++right;
- }
-
- ++left;
- }
-#endif
-}
-
-
-static GtkWidget*
-previews_of_button_layouts (void)
-{
- static gboolean initted = FALSE;
- GtkWidget *box;
- GtkWidget *sw;
- GdkColor desktop_color;
- int i;
- GtkWidget *eventbox;
-
- if (!initted)
- {
- init_layouts ();
- initted = TRUE;
- }
-
- sw = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
-
- box = gtk_vbox_new (FALSE, 0);
- gtk_box_set_spacing (GTK_BOX (box), 20);
- gtk_container_set_border_width (GTK_CONTAINER (box), 20);
-
- eventbox = gtk_event_box_new ();
- gtk_container_add (GTK_CONTAINER (eventbox), box);
-
- gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw), eventbox);
-
- desktop_color.red = 0x5144;
- desktop_color.green = 0x75D6;
- desktop_color.blue = 0xA699;
-
- gtk_widget_modify_bg (eventbox, GTK_STATE_NORMAL, &desktop_color);
-
- i = 0;
- while (i < BUTTON_LAYOUT_COMBINATIONS)
- {
- GtkWidget *align;
- double xalign, yalign;
- GtkWidget *eventbox2;
- GtkWidget *preview;
- char *title;
-
- eventbox2 = gtk_event_box_new ();
-
- preview = meta_preview_new ();
-
- gtk_container_add (GTK_CONTAINER (eventbox2), preview);
-
- meta_preview_set_theme (META_PREVIEW (preview), global_theme);
-
- title = g_strdup_printf (_("Button layout test %d"), i+1);
- meta_preview_set_title (META_PREVIEW (preview), title);
- g_free (title);
-
- meta_preview_set_button_layout (META_PREVIEW (preview),
- &different_layouts[i]);
-
- xalign = 0.5;
- yalign = 0.5;
-
- align = gtk_alignment_new (0.0, 0.0, xalign, yalign);
- gtk_container_add (GTK_CONTAINER (align), eventbox2);
-
- gtk_box_pack_start (GTK_BOX (box), align, TRUE, TRUE, 0);
-
- previews[META_FRAME_TYPE_LAST*FONT_SIZE_LAST + i] = preview;
-
- ++i;
- }
-
- return sw;
-}
-
-static GtkWidget*
-benchmark_summary (void)
-{
- char *msg;
- GtkWidget *label;
-
- msg = g_strdup_printf (_("%g milliseconds to draw one window frame"),
- milliseconds_to_draw_frame);
- label = gtk_label_new (msg);
- g_free (msg);
-
- return label;
-}
-
-int
-main (int argc, char **argv)
-{
- GtkWidget *window;
- GtkWidget *collection;
- GError *err;
- clock_t start, end;
- GtkWidget *notebook;
- int i;
-
- bindtextdomain (GETTEXT_PACKAGE, METACITY_LOCALEDIR);
- textdomain(GETTEXT_PACKAGE);
- bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
-
- run_position_expression_tests ();
-#if 0
- run_position_expression_timings ();
-#endif
-
- gtk_init (&argc, &argv);
-
- if (g_getenv ("METACITY_DEBUG") != NULL)
- {
- meta_set_debugging (TRUE);
- meta_set_verbose (TRUE);
- }
-
- start = clock ();
- err = NULL;
- if (argc == 1)
- global_theme = meta_theme_load ("Atlanta", &err);
- else if (argc == 2)
- global_theme = meta_theme_load (argv[1], &err);
- else
- {
- g_printerr (_("Usage: metacity-theme-viewer [THEMENAME]\n"));
- exit (1);
- }
- end = clock ();
-
- if (global_theme == NULL)
- {
- g_printerr (_("Error loading theme: %s\n"),
- err->message);
- g_error_free (err);
- exit (1);
- }
-
- g_print (_("Loaded theme \"%s\" in %g seconds\n"),
- global_theme->name,
- (end - start) / (double) CLOCKS_PER_SEC);
-
- run_theme_benchmark ();
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_default_size (GTK_WINDOW (window), 350, 350);
-
- if (strcmp (global_theme->name, global_theme->readable_name)==0)
- gtk_window_set_title (GTK_WINDOW (window),
- global_theme->readable_name);
- else
- {
- /* The theme directory name is different from the name the theme
- * gives itself within its file. Display both, directory name first.
- */
- gchar *title = g_strconcat (global_theme->name, " - ",
- global_theme->readable_name,
- NULL);
-
- gtk_window_set_title (GTK_WINDOW (window),
- title);
-
- g_free (title);
- }
-
- g_signal_connect (G_OBJECT (window), "destroy",
- G_CALLBACK (gtk_main_quit), NULL);
-
- gtk_widget_realize (window);
- g_assert (window->style);
- g_assert (window->style->font_desc);
-
- notebook = gtk_notebook_new ();
- gtk_container_add (GTK_CONTAINER (window), notebook);
-
- collection = preview_collection (FONT_SIZE_NORMAL,
- window->style->font_desc);
- gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
- collection,
- gtk_label_new (_("Normal Title Font")));
-
- collection = preview_collection (FONT_SIZE_SMALL,
- window->style->font_desc);
- gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
- collection,
- gtk_label_new (_("Small Title Font")));
-
- collection = preview_collection (FONT_SIZE_LARGE,
- window->style->font_desc);
- gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
- collection,
- gtk_label_new (_("Large Title Font")));
-
- collection = previews_of_button_layouts ();
- gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
- collection,
- gtk_label_new (_("Button Layouts")));
-
- collection = benchmark_summary ();
- gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
- collection,
- gtk_label_new (_("Benchmark")));
-
- i = 0;
- while (i < (int) G_N_ELEMENTS (previews))
- {
- /* preview widget likes to be realized before its size request.
- * it's lame that way.
- */
- gtk_widget_realize (previews[i]);
-
- ++i;
- }
-
- gtk_widget_show_all (window);
-
- gtk_main ();
-
- return 0;
-}
-
-
-static MetaFrameFlags
-get_flags (GtkWidget *widget)
-{
- return META_FRAME_ALLOWS_DELETE |
- META_FRAME_ALLOWS_MENU |
- META_FRAME_ALLOWS_MINIMIZE |
- META_FRAME_ALLOWS_MAXIMIZE |
- META_FRAME_ALLOWS_VERTICAL_RESIZE |
- META_FRAME_ALLOWS_HORIZONTAL_RESIZE |
- META_FRAME_HAS_FOCUS |
- META_FRAME_ALLOWS_SHADE |
- META_FRAME_ALLOWS_MOVE;
-}
-
-static int
-get_text_height (GtkWidget *widget)
-{
- return meta_pango_font_desc_get_text_height (widget->style->font_desc,
- gtk_widget_get_pango_context (widget));
-}
-
-static PangoLayout*
-create_title_layout (GtkWidget *widget)
-{
- PangoLayout *layout;
-
- layout = gtk_widget_create_pango_layout (widget, _("Window Title Goes Here"));
-
- return layout;
-}
-
-static void
-run_theme_benchmark (void)
-{
- GtkWidget* widget;
- GdkPixmap *pixmap;
- int top_height, bottom_height, left_width, right_width;
- MetaButtonState button_states[META_BUTTON_TYPE_LAST] =
- {
- META_BUTTON_STATE_NORMAL,
- META_BUTTON_STATE_NORMAL,
- META_BUTTON_STATE_NORMAL,
- META_BUTTON_STATE_NORMAL
- };
- PangoLayout *layout;
- clock_t start;
- clock_t end;
- GTimer *timer;
- int i;
- MetaButtonLayout button_layout;
-#define ITERATIONS 100
- int client_width;
- int client_height;
- int inc;
-
- widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_widget_realize (widget);
-
- meta_theme_get_frame_borders (global_theme,
- META_FRAME_TYPE_NORMAL,
- get_text_height (widget),
- get_flags (widget),
- &top_height,
- &bottom_height,
- &left_width,
- &right_width);
-
- layout = create_title_layout (widget);
-
- i = 0;
- while (i < MAX_BUTTONS_PER_CORNER)
- {
- button_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST;
- button_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
- ++i;
- }
-
- button_layout.left_buttons[0] = META_BUTTON_FUNCTION_MENU;
-
- button_layout.right_buttons[0] = META_BUTTON_FUNCTION_MINIMIZE;
- button_layout.right_buttons[1] = META_BUTTON_FUNCTION_MAXIMIZE;
- button_layout.right_buttons[2] = META_BUTTON_FUNCTION_CLOSE;
-
- timer = g_timer_new ();
- start = clock ();
-
- client_width = 50;
- client_height = 50;
- inc = 1000 / ITERATIONS; /* Increment to grow width/height,
- * eliminates caching effects.
- */
-
- i = 0;
- while (i < ITERATIONS)
- {
- /* Creating the pixmap in the loop is right, since
- * GDK does the same with its double buffering.
- */
- pixmap = gdk_pixmap_new (widget->window,
- client_width + left_width + right_width,
- client_height + top_height + bottom_height,
- -1);
-
- meta_theme_draw_frame (global_theme,
- widget,
- pixmap,
- NULL,
- 0, 0,
- META_FRAME_TYPE_NORMAL,
- get_flags (widget),
- client_width, client_height,
- layout,
- get_text_height (widget),
- &button_layout,
- button_states,
- meta_preview_get_mini_icon (),
- meta_preview_get_icon ());
-
- g_object_unref (G_OBJECT (pixmap));
-
- ++i;
- client_width += inc;
- client_height += inc;
- }
-
- end = clock ();
- g_timer_stop (timer);
-
- milliseconds_to_draw_frame = (g_timer_elapsed (timer, NULL) / (double) ITERATIONS) * 1000;
-
- g_print (_("Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g seconds wall clock time including X server resources (%g milliseconds per frame)\n"),
- ITERATIONS,
- ((double)end - (double)start) / CLOCKS_PER_SEC,
- (((double)end - (double)start) / CLOCKS_PER_SEC / (double) ITERATIONS) * 1000,
- g_timer_elapsed (timer, NULL),
- milliseconds_to_draw_frame);
-
- g_timer_destroy (timer);
- g_object_unref (G_OBJECT (layout));
- gtk_widget_destroy (widget);
-
-#undef ITERATIONS
-}
-
-typedef struct
-{
- GdkRectangle rect;
- const char *expr;
- int expected_x;
- int expected_y;
- MetaThemeError expected_error;
-} PositionExpressionTest;
-
-#define NO_ERROR -1
-
-static const PositionExpressionTest position_expression_tests[] = {
- /* Just numbers */
- { { 10, 20, 40, 50 },
- "10", 20, 30, NO_ERROR },
- { { 10, 20, 40, 50 },
- "14.37", 24, 34, NO_ERROR },
- /* Binary expressions with 2 ints */
- { { 10, 20, 40, 50 },
- "14 * 10", 150, 160, NO_ERROR },
- { { 10, 20, 40, 50 },
- "14 + 10", 34, 44, NO_ERROR },
- { { 10, 20, 40, 50 },
- "14 - 10", 14, 24, NO_ERROR },
- { { 10, 20, 40, 50 },
- "8 / 2", 14, 24, NO_ERROR },
- { { 10, 20, 40, 50 },
- "8 % 3", 12, 22, NO_ERROR },
- /* Binary expressions with floats and mixed float/ints */
- { { 10, 20, 40, 50 },
- "7.0 / 3.5", 12, 22, NO_ERROR },
- { { 10, 20, 40, 50 },
- "12.1 / 3", 14, 24, NO_ERROR },
- { { 10, 20, 40, 50 },
- "12 / 2.95", 14, 24, NO_ERROR },
- /* Binary expressions without whitespace after first number */
- { { 10, 20, 40, 50 },
- "14* 10", 150, 160, NO_ERROR },
- { { 10, 20, 40, 50 },
- "14+ 10", 34, 44, NO_ERROR },
- { { 10, 20, 40, 50 },
- "14- 10", 14, 24, NO_ERROR },
- { { 10, 20, 40, 50 },
- "8/ 2", 14, 24, NO_ERROR },
- { { 10, 20, 40, 50 },
- "7.0/ 3.5", 12, 22, NO_ERROR },
- { { 10, 20, 40, 50 },
- "12.1/ 3", 14, 24, NO_ERROR },
- { { 10, 20, 40, 50 },
- "12/ 2.95", 14, 24, NO_ERROR },
- /* Binary expressions without whitespace before second number */
- { { 10, 20, 40, 50 },
- "14 *10", 150, 160, NO_ERROR },
- { { 10, 20, 40, 50 },
- "14 +10", 34, 44, NO_ERROR },
- { { 10, 20, 40, 50 },
- "14 -10", 14, 24, NO_ERROR },
- { { 10, 20, 40, 50 },
- "8 /2", 14, 24, NO_ERROR },
- { { 10, 20, 40, 50 },
- "7.0 /3.5", 12, 22, NO_ERROR },
- { { 10, 20, 40, 50 },
- "12.1 /3", 14, 24, NO_ERROR },
- { { 10, 20, 40, 50 },
- "12 /2.95", 14, 24, NO_ERROR },
- /* Binary expressions without any whitespace */
- { { 10, 20, 40, 50 },
- "14*10", 150, 160, NO_ERROR },
- { { 10, 20, 40, 50 },
- "14+10", 34, 44, NO_ERROR },
- { { 10, 20, 40, 50 },
- "14-10", 14, 24, NO_ERROR },
- { { 10, 20, 40, 50 },
- "8/2", 14, 24, NO_ERROR },
- { { 10, 20, 40, 50 },
- "7.0/3.5", 12, 22, NO_ERROR },
- { { 10, 20, 40, 50 },
- "12.1/3", 14, 24, NO_ERROR },
- { { 10, 20, 40, 50 },
- "12/2.95", 14, 24, NO_ERROR },
- /* Binary expressions with parentheses */
- { { 10, 20, 40, 50 },
- "(14) * (10)", 150, 160, NO_ERROR },
- { { 10, 20, 40, 50 },
- "(14) + (10)", 34, 44, NO_ERROR },
- { { 10, 20, 40, 50 },
- "(14) - (10)", 14, 24, NO_ERROR },
- { { 10, 20, 40, 50 },
- "(8) / (2)", 14, 24, NO_ERROR },
- { { 10, 20, 40, 50 },
- "(7.0) / (3.5)", 12, 22, NO_ERROR },
- { { 10, 20, 40, 50 },
- "(12.1) / (3)", 14, 24, NO_ERROR },
- { { 10, 20, 40, 50 },
- "(12) / (2.95)", 14, 24, NO_ERROR },
- /* Lots of extra parentheses */
- { { 10, 20, 40, 50 },
- "(((14)) * ((10)))", 150, 160, NO_ERROR },
- { { 10, 20, 40, 50 },
- "((((14)))) + ((((((((10))))))))", 34, 44, NO_ERROR },
- { { 10, 20, 40, 50 },
- "((((((((((14 - 10))))))))))", 14, 24, NO_ERROR },
- /* Binary expressions with variables */
- { { 10, 20, 40, 50 },
- "2 * width", 90, 100, NO_ERROR },
- { { 10, 20, 40, 50 },
- "2 * height", 110, 120, NO_ERROR },
- { { 10, 20, 40, 50 },
- "width - 10", 40, 50, NO_ERROR },
- { { 10, 20, 40, 50 },
- "height / 2", 35, 45, NO_ERROR },
- /* More than two operands */
- { { 10, 20, 40, 50 },
- "8 / 2 + 5", 19, 29, NO_ERROR },
- { { 10, 20, 40, 50 },
- "8 * 2 + 5", 31, 41, NO_ERROR },
- { { 10, 20, 40, 50 },
- "8 + 2 * 5", 28, 38, NO_ERROR },
- { { 10, 20, 40, 50 },
- "8 + 8 / 2", 22, 32, NO_ERROR },
- { { 10, 20, 40, 50 },
- "14 / (2 + 5)", 12, 22, NO_ERROR },
- { { 10, 20, 40, 50 },
- "8 * (2 + 5)", 66, 76, NO_ERROR },
- { { 10, 20, 40, 50 },
- "(8 + 2) * 5", 60, 70, NO_ERROR },
- { { 10, 20, 40, 50 },
- "(8 + 8) / 2", 18, 28, NO_ERROR },
- /* Errors */
- { { 10, 20, 40, 50 },
- "2 * foo", 0, 0, META_THEME_ERROR_UNKNOWN_VARIABLE },
- { { 10, 20, 40, 50 },
- "2 *", 0, 0, META_THEME_ERROR_FAILED },
- { { 10, 20, 40, 50 },
- "- width", 0, 0, META_THEME_ERROR_FAILED },
- { { 10, 20, 40, 50 },
- "5 % 1.0", 0, 0, META_THEME_ERROR_MOD_ON_FLOAT },
- { { 10, 20, 40, 50 },
- "1.0 % 5", 0, 0, META_THEME_ERROR_MOD_ON_FLOAT },
- { { 10, 20, 40, 50 },
- "! * 2", 0, 0, META_THEME_ERROR_BAD_CHARACTER },
- { { 10, 20, 40, 50 },
- " ", 0, 0, META_THEME_ERROR_FAILED },
- { { 10, 20, 40, 50 },
- "() () (( ) ()) ((()))", 0, 0, META_THEME_ERROR_FAILED },
- { { 10, 20, 40, 50 },
- "(*) () ((/) ()) ((()))", 0, 0, META_THEME_ERROR_FAILED },
- { { 10, 20, 40, 50 },
- "2 * 5 /", 0, 0, META_THEME_ERROR_FAILED },
- { { 10, 20, 40, 50 },
- "+ 2 * 5", 0, 0, META_THEME_ERROR_FAILED },
- { { 10, 20, 40, 50 },
- "+ 2 * 5", 0, 0, META_THEME_ERROR_FAILED }
-};
-
-static void
-run_position_expression_tests (void)
-{
-#if 0
- int i;
- MetaPositionExprEnv env;
-
- i = 0;
- while (i < (int) G_N_ELEMENTS (position_expression_tests))
- {
- GError *err;
- gboolean retval;
- const PositionExpressionTest *test;
- PosToken *tokens;
- int n_tokens;
- int x, y;
-
- test = &position_expression_tests[i];
-
- if (g_getenv ("META_PRINT_TESTS") != NULL)
- g_print ("Test expression: \"%s\" expecting x = %d y = %d",
- test->expr, test->expected_x, test->expected_y);
-
- err = NULL;
-
- env.rect = meta_rect (test->rect.x, test->rect.y,
- test->rect.width, test->rect.height);
- env.object_width = -1;
- env.object_height = -1;
- env.left_width = 0;
- env.right_width = 0;
- env.top_height = 0;
- env.bottom_height = 0;
- env.title_width = 5;
- env.title_height = 5;
- env.icon_width = 32;
- env.icon_height = 32;
- env.mini_icon_width = 16;
- env.mini_icon_height = 16;
- env.theme = NULL;
-
- if (err == NULL)
- {
- retval = meta_parse_position_expression (tokens, n_tokens,
- &env,
- &x, &y,
- &err);
- }
-
- if (retval && err)
- g_error (_("position expression test returned TRUE but set error"));
- if (!retval && err == NULL)
- g_error (_("position expression test returned FALSE but didn't set error"));
- if (((int) test->expected_error) != NO_ERROR)
- {
- if (err == NULL)
- g_error (_("Error was expected but none given"));
- if (err->code != (int) test->expected_error)
- g_error (_("Error %d was expected but %d given"),
- test->expected_error, err->code);
- }
- else
- {
- if (err)
- g_error (_("Error not expected but one was returned: %s"),
- err->message);
-
- if (x != test->expected_x)
- g_error (_("x value was %d, %d was expected"), x, test->expected_x);
-
- if (y != test->expected_y)
- g_error (_("y value was %d, %d was expected"), y, test->expected_y);
- }
-
- if (err)
- g_error_free (err);
-
- meta_pos_tokens_free (tokens, n_tokens);
- ++i;
- }
-#endif
-}
-
-#if 0
-static void
-run_position_expression_timings (void)
-{
- int i;
- int iters;
- clock_t start;
- clock_t end;
- MetaPositionExprEnv env;
-
-#define ITERATIONS 100000
-
- start = clock ();
-
- iters = 0;
- i = 0;
- while (iters < ITERATIONS)
- {
- const PositionExpressionTest *test;
- int x, y;
-
- test = &position_expression_tests[i];
-
- env.x = test->rect.x;
- env.y = test->rect.y;
- env.width = test->rect.width;
- env.height = test->rect.height;
- env.object_width = -1;
- env.object_height = -1;
- env.left_width = 0;
- env.right_width = 0;
- env.top_height = 0;
- env.bottom_height = 0;
- env.title_width = 5;
- env.title_height = 5;
- env.icon_width = 32;
- env.icon_height = 32;
- env.mini_icon_width = 16;
- env.mini_icon_height = 16;
- env.theme = NULL;
-
- meta_parse_position_expression (test->expr,
- &env,
- &x, &y, NULL);
-
- ++iters;
- ++i;
- if (i == G_N_ELEMENTS (position_expression_tests))
- i = 0;
- }
-
- end = clock ();
-
- g_print (_("%d coordinate expressions parsed in %g seconds (%g seconds average)\n"),
- ITERATIONS,
- ((double)end - (double)start) / CLOCKS_PER_SEC,
- ((double)end - (double)start) / CLOCKS_PER_SEC / (double) ITERATIONS);
-
-}
-#endif
diff --git a/src/ui/theme.c b/src/ui/theme.c
deleted file mode 100644
index 1d822c82..00000000
--- a/src/ui/theme.c
+++ /dev/null
@@ -1,6480 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity Theme Rendering */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-/**
- * \file theme.c Making Metacity look pretty
- *
- * The window decorations drawn by Metacity are described by files on disk
- * known internally as "themes" (externally as "window border themes" on
- * http://art.gnome.org/themes/metacity/ or "Metacity themes"). This file
- * contains most of the code necessary to support themes; it does not
- * contain the XML parser, which is in theme-parser.c.
- *
- * \bug This is a big file with lots of different subsystems, which might
- * be better split out into separate files.
- */
-
-/**
- * \defgroup tokenizer The theme expression tokenizer
- *
- * Themes can use a simple expression language to represent the values of
- * things. This is the tokeniser used for that language.
- *
- * \bug We could remove almost all this code by using GScanner instead,
- * but we would also have to find every expression in every existing theme
- * we could and make sure the parse trees were the same.
- */
-
-/**
- * \defgroup parser The theme expression parser
- *
- * Themes can use a simple expression language to represent the values of
- * things. This is the parser used for that language.
- */
-
-#include <config.h>
-#include "theme.h"
-#include "theme-parser.h"
-#include "util.h"
-#include "gradient.h"
-#include <gtk/gtk.h>
-#include <string.h>
-#include <stdlib.h>
-#include <math.h>
-
-#define GDK_COLOR_RGBA(color) \
- ((guint32) (0xff | \
- (((color).red / 256) << 24) | \
- (((color).green / 256) << 16) | \
- (((color).blue / 256) << 8)))
-
-#define GDK_COLOR_RGB(color) \
- ((guint32) ((((color).red / 256) << 16) | \
- (((color).green / 256) << 8) | \
- (((color).blue / 256))))
-
-#define ALPHA_TO_UCHAR(d) ((unsigned char) ((d) * 255))
-
-#define DEBUG_FILL_STRUCT(s) memset ((s), 0xef, sizeof (*(s)))
-#define CLAMP_UCHAR(v) ((guchar) (CLAMP (((int)v), (int)0, (int)255)))
-#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
-
-static void gtk_style_shade (GdkColor *a,
- GdkColor *b,
- gdouble k);
-static void rgb_to_hls (gdouble *r,
- gdouble *g,
- gdouble *b);
-static void hls_to_rgb (gdouble *h,
- gdouble *l,
- gdouble *s);
-
-/**
- * The current theme. (Themes are singleton.)
- */
-static MetaTheme *meta_current_theme = NULL;
-
-static GdkPixbuf *
-colorize_pixbuf (GdkPixbuf *orig,
- GdkColor *new_color)
-{
- GdkPixbuf *pixbuf;
- double intensity;
- int x, y;
- const guchar *src;
- guchar *dest;
- int orig_rowstride;
- int dest_rowstride;
- int width, height;
- gboolean has_alpha;
- const guchar *src_pixels;
- guchar *dest_pixels;
-
- pixbuf = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (orig), gdk_pixbuf_get_has_alpha (orig),
- gdk_pixbuf_get_bits_per_sample (orig),
- gdk_pixbuf_get_width (orig), gdk_pixbuf_get_height (orig));
-
- if (pixbuf == NULL)
- return NULL;
-
- orig_rowstride = gdk_pixbuf_get_rowstride (orig);
- dest_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
- width = gdk_pixbuf_get_width (pixbuf);
- height = gdk_pixbuf_get_height (pixbuf);
- has_alpha = gdk_pixbuf_get_has_alpha (orig);
- src_pixels = gdk_pixbuf_get_pixels (orig);
- dest_pixels = gdk_pixbuf_get_pixels (pixbuf);
-
- for (y = 0; y < height; y++)
- {
- src = src_pixels + y * orig_rowstride;
- dest = dest_pixels + y * dest_rowstride;
-
- for (x = 0; x < width; x++)
- {
- double dr, dg, db;
-
- intensity = INTENSITY (src[0], src[1], src[2]) / 255.0;
-
- if (intensity <= 0.5)
- {
- /* Go from black at intensity = 0.0 to new_color at intensity = 0.5 */
- dr = (new_color->red * intensity * 2.0) / 65535.0;
- dg = (new_color->green * intensity * 2.0) / 65535.0;
- db = (new_color->blue * intensity * 2.0) / 65535.0;
- }
- else
- {
- /* Go from new_color at intensity = 0.5 to white at intensity = 1.0 */
- dr = (new_color->red + (65535 - new_color->red) * (intensity - 0.5) * 2.0) / 65535.0;
- dg = (new_color->green + (65535 - new_color->green) * (intensity - 0.5) * 2.0) / 65535.0;
- db = (new_color->blue + (65535 - new_color->blue) * (intensity - 0.5) * 2.0) / 65535.0;
- }
-
- dest[0] = CLAMP_UCHAR (255 * dr);
- dest[1] = CLAMP_UCHAR (255 * dg);
- dest[2] = CLAMP_UCHAR (255 * db);
-
- if (has_alpha)
- {
- dest[3] = src[3];
- src += 4;
- dest += 4;
- }
- else
- {
- src += 3;
- dest += 3;
- }
- }
- }
-
- return pixbuf;
-}
-
-static void
-color_composite (const GdkColor *bg,
- const GdkColor *fg,
- double alpha_d,
- GdkColor *color)
-{
- guint16 alpha;
-
- *color = *bg;
- alpha = alpha_d * 0xffff;
- color->red = color->red + (((fg->red - color->red) * alpha + 0x8000) >> 16);
- color->green = color->green + (((fg->green - color->green) * alpha + 0x8000) >> 16);
- color->blue = color->blue + (((fg->blue - color->blue) * alpha + 0x8000) >> 16);
-}
-
-/**
- * Sets all the fields of a border to dummy values.
- *
- * \param border The border whose fields should be reset.
- */
-static void
-init_border (GtkBorder *border)
-{
- border->top = -1;
- border->bottom = -1;
- border->left = -1;
- border->right = -1;
-}
-
-/**
- * Creates a new, empty MetaFrameLayout. The fields will be set to dummy
- * values.
- *
- * \return The newly created MetaFrameLayout.
- */
-MetaFrameLayout*
-meta_frame_layout_new (void)
-{
- MetaFrameLayout *layout;
-
- layout = g_new0 (MetaFrameLayout, 1);
-
- layout->refcount = 1;
-
- /* Fill with -1 values to detect invalid themes */
- layout->left_width = -1;
- layout->right_width = -1;
- layout->bottom_height = -1;
-
- init_border (&layout->title_border);
-
- layout->title_vertical_pad = -1;
-
- layout->right_titlebar_edge = -1;
- layout->left_titlebar_edge = -1;
-
- layout->button_sizing = META_BUTTON_SIZING_LAST;
- layout->button_aspect = 1.0;
- layout->button_width = -1;
- layout->button_height = -1;
-
- layout->has_title = TRUE;
- layout->title_scale = 1.0;
-
- init_border (&layout->button_border);
-
- return layout;
-}
-
-/**
- *
- */
-static gboolean
-validate_border (const GtkBorder *border,
- const char **bad)
-{
- *bad = NULL;
-
- if (border->top < 0)
- *bad = _("top");
- else if (border->bottom < 0)
- *bad = _("bottom");
- else if (border->left < 0)
- *bad = _("left");
- else if (border->right < 0)
- *bad = _("right");
-
- return *bad == NULL;
-}
-
-/**
- * Ensures that the theme supplied a particular dimension. When a
- * MetaFrameLayout is created, all its integer fields are set to -1
- * by meta_frame_layout_new(). After an instance of this type
- * should have been initialised, this function checks that
- * a given field is not still at -1. It is never called directly, but
- * rather via the CHECK_GEOMETRY_VALUE and CHECK_GEOMETRY_BORDER
- * macros.
- *
- * \param val The value to check
- * \param name The name to use in the error message
- * \param[out] error Set to an error if val was not initialised
- */
-static gboolean
-validate_geometry_value (int val,
- const char *name,
- GError **error)
-{
- if (val < 0)
- {
- g_set_error (error, META_THEME_ERROR,
- META_THEME_ERROR_FRAME_GEOMETRY,
- _("frame geometry does not specify \"%s\" dimension"),
- name);
- return FALSE;
- }
- else
- return TRUE;
-}
-
-static gboolean
-validate_geometry_border (const GtkBorder *border,
- const char *name,
- GError **error)
-{
- const char *bad;
-
- if (!validate_border (border, &bad))
- {
- g_set_error (error, META_THEME_ERROR,
- META_THEME_ERROR_FRAME_GEOMETRY,
- _("frame geometry does not specify dimension \"%s\" for border \"%s\""),
- bad, name);
- return FALSE;
- }
- else
- return TRUE;
-}
-
-gboolean
-meta_frame_layout_validate (const MetaFrameLayout *layout,
- GError **error)
-{
- g_return_val_if_fail (layout != NULL, FALSE);
-
-#define CHECK_GEOMETRY_VALUE(vname) if (!validate_geometry_value (layout->vname, #vname, error)) return FALSE
-
-#define CHECK_GEOMETRY_BORDER(bname) if (!validate_geometry_border (&layout->bname, #bname, error)) return FALSE
-
- CHECK_GEOMETRY_VALUE (left_width);
- CHECK_GEOMETRY_VALUE (right_width);
- CHECK_GEOMETRY_VALUE (bottom_height);
-
- CHECK_GEOMETRY_BORDER (title_border);
-
- CHECK_GEOMETRY_VALUE (title_vertical_pad);
-
- CHECK_GEOMETRY_VALUE (right_titlebar_edge);
- CHECK_GEOMETRY_VALUE (left_titlebar_edge);
-
- switch (layout->button_sizing)
- {
- case META_BUTTON_SIZING_ASPECT:
- if (layout->button_aspect < (0.1) ||
- layout->button_aspect > (15.0))
- {
- g_set_error (error, META_THEME_ERROR,
- META_THEME_ERROR_FRAME_GEOMETRY,
- _("Button aspect ratio %g is not reasonable"),
- layout->button_aspect);
- return FALSE;
- }
- break;
- case META_BUTTON_SIZING_FIXED:
- CHECK_GEOMETRY_VALUE (button_width);
- CHECK_GEOMETRY_VALUE (button_height);
- break;
- case META_BUTTON_SIZING_LAST:
- g_set_error (error, META_THEME_ERROR,
- META_THEME_ERROR_FRAME_GEOMETRY,
- _("Frame geometry does not specify size of buttons"));
- return FALSE;
- }
-
- CHECK_GEOMETRY_BORDER (button_border);
-
- return TRUE;
-}
-
-MetaFrameLayout*
-meta_frame_layout_copy (const MetaFrameLayout *src)
-{
- MetaFrameLayout *layout;
-
- layout = g_new0 (MetaFrameLayout, 1);
-
- *layout = *src;
-
- layout->refcount = 1;
-
- return layout;
-}
-
-void
-meta_frame_layout_ref (MetaFrameLayout *layout)
-{
- g_return_if_fail (layout != NULL);
-
- layout->refcount += 1;
-}
-
-void
-meta_frame_layout_unref (MetaFrameLayout *layout)
-{
- g_return_if_fail (layout != NULL);
- g_return_if_fail (layout->refcount > 0);
-
- layout->refcount -= 1;
-
- if (layout->refcount == 0)
- {
- DEBUG_FILL_STRUCT (layout);
- g_free (layout);
- }
-}
-
-void
-meta_frame_layout_get_borders (const MetaFrameLayout *layout,
- int text_height,
- MetaFrameFlags flags,
- int *top_height,
- int *bottom_height,
- int *left_width,
- int *right_width)
-{
- int buttons_height, title_height;
-
- g_return_if_fail (top_height != NULL);
- g_return_if_fail (bottom_height != NULL);
- g_return_if_fail (left_width != NULL);
- g_return_if_fail (right_width != NULL);
-
- if (!layout->has_title)
- text_height = 0;
-
- buttons_height = layout->button_height +
- layout->button_border.top + layout->button_border.bottom;
- title_height = text_height +
- layout->title_vertical_pad +
- layout->title_border.top + layout->title_border.bottom;
-
- if (top_height)
- {
- *top_height = MAX (buttons_height, title_height);
- }
-
- if (left_width)
- *left_width = layout->left_width;
- if (right_width)
- *right_width = layout->right_width;
-
- if (bottom_height)
- {
- if (flags & META_FRAME_SHADED)
- *bottom_height = 0;
- else
- *bottom_height = layout->bottom_height;
- }
-
- if (flags & META_FRAME_FULLSCREEN)
- {
- if (top_height)
- *top_height = 0;
- if (bottom_height)
- *bottom_height = 0;
- if (left_width)
- *left_width = 0;
- if (right_width)
- *right_width = 0;
- }
-}
-
-static MetaButtonSpace*
-rect_for_function (MetaFrameGeometry *fgeom,
- MetaFrameFlags flags,
- MetaButtonFunction function,
- MetaTheme *theme)
-{
-
- /* Firstly, check version-specific things. */
-
- if (META_THEME_ALLOWS(theme, META_THEME_SHADE_STICK_ABOVE_BUTTONS))
- {
- switch (function)
- {
- case META_BUTTON_FUNCTION_SHADE:
- if ((flags & META_FRAME_ALLOWS_SHADE) && !(flags & META_FRAME_SHADED))
- return &fgeom->shade_rect;
- else
- return NULL;
- case META_BUTTON_FUNCTION_ABOVE:
- if (!(flags & META_FRAME_ABOVE))
- return &fgeom->above_rect;
- else
- return NULL;
- case META_BUTTON_FUNCTION_STICK:
- if (!(flags & META_FRAME_STUCK))
- return &fgeom->stick_rect;
- else
- return NULL;
- case META_BUTTON_FUNCTION_UNSHADE:
- if ((flags & META_FRAME_ALLOWS_SHADE) && (flags & META_FRAME_SHADED))
- return &fgeom->unshade_rect;
- else
- return NULL;
- case META_BUTTON_FUNCTION_UNABOVE:
- if (flags & META_FRAME_ABOVE)
- return &fgeom->unabove_rect;
- else
- return NULL;
- case META_BUTTON_FUNCTION_UNSTICK:
- if (flags & META_FRAME_STUCK)
- return &fgeom->unstick_rect;
- default:
- /* just go on to the next switch block */;
- }
- }
-
- /* now consider the buttons which exist in all versions */
-
- switch (function)
- {
- case META_BUTTON_FUNCTION_MENU:
- if (flags & META_FRAME_ALLOWS_MENU)
- return &fgeom->menu_rect;
- else
- return NULL;
- case META_BUTTON_FUNCTION_MINIMIZE:
- if (flags & META_FRAME_ALLOWS_MINIMIZE)
- return &fgeom->min_rect;
- else
- return NULL;
- case META_BUTTON_FUNCTION_MAXIMIZE:
- if (flags & META_FRAME_ALLOWS_MAXIMIZE)
- return &fgeom->max_rect;
- else
- return NULL;
- case META_BUTTON_FUNCTION_CLOSE:
- if (flags & META_FRAME_ALLOWS_DELETE)
- return &fgeom->close_rect;
- else
- return NULL;
- case META_BUTTON_FUNCTION_STICK:
- case META_BUTTON_FUNCTION_SHADE:
- case META_BUTTON_FUNCTION_ABOVE:
- case META_BUTTON_FUNCTION_UNSTICK:
- case META_BUTTON_FUNCTION_UNSHADE:
- case META_BUTTON_FUNCTION_UNABOVE:
- /* we are being asked for a >v1 button which hasn't been handled yet,
- * so obviously we're not in a theme which supports that version.
- * therefore, we don't show the button. return NULL and all will
- * be well.
- */
- return NULL;
-
- case META_BUTTON_FUNCTION_LAST:
- return NULL;
- }
-
- return NULL;
-}
-
-static gboolean
-strip_button (MetaButtonSpace *func_rects[MAX_BUTTONS_PER_CORNER],
- GdkRectangle *bg_rects[MAX_BUTTONS_PER_CORNER],
- int *n_rects,
- MetaButtonSpace *to_strip)
-{
- int i;
-
- i = 0;
- while (i < *n_rects)
- {
- if (func_rects[i] == to_strip)
- {
- *n_rects -= 1;
-
- /* shift the other rects back in the array */
- while (i < *n_rects)
- {
- func_rects[i] = func_rects[i+1];
- bg_rects[i] = bg_rects[i+1];
-
- ++i;
- }
-
- func_rects[i] = NULL;
- bg_rects[i] = NULL;
-
- return TRUE;
- }
-
- ++i;
- }
-
- return FALSE; /* did not strip anything */
-}
-
-void
-meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
- int text_height,
- MetaFrameFlags flags,
- int client_width,
- int client_height,
- const MetaButtonLayout *button_layout,
- MetaFrameGeometry *fgeom,
- MetaTheme *theme)
-{
- int i, n_left, n_right, n_left_spacers, n_right_spacers;
- int x;
- int button_y;
- int title_right_edge;
- int width, height;
- int button_width, button_height;
- int min_size_for_rounding;
-
- /* the left/right rects in order; the max # of rects
- * is the number of button functions
- */
- MetaButtonSpace *left_func_rects[MAX_BUTTONS_PER_CORNER];
- MetaButtonSpace *right_func_rects[MAX_BUTTONS_PER_CORNER];
- GdkRectangle *left_bg_rects[MAX_BUTTONS_PER_CORNER];
- gboolean left_buttons_has_spacer[MAX_BUTTONS_PER_CORNER];
- GdkRectangle *right_bg_rects[MAX_BUTTONS_PER_CORNER];
- gboolean right_buttons_has_spacer[MAX_BUTTONS_PER_CORNER];
-
- meta_frame_layout_get_borders (layout, text_height,
- flags,
- &fgeom->top_height,
- &fgeom->bottom_height,
- &fgeom->left_width,
- &fgeom->right_width);
-
- width = client_width + fgeom->left_width + fgeom->right_width;
-
- height = ((flags & META_FRAME_SHADED) ? 0: client_height) +
- fgeom->top_height + fgeom->bottom_height;
-
- fgeom->width = width;
- fgeom->height = height;
-
- fgeom->top_titlebar_edge = layout->title_border.top;
- fgeom->bottom_titlebar_edge = layout->title_border.bottom;
- fgeom->left_titlebar_edge = layout->left_titlebar_edge;
- fgeom->right_titlebar_edge = layout->right_titlebar_edge;
-
- /* gcc warnings */
- button_width = -1;
- button_height = -1;
-
- switch (layout->button_sizing)
- {
- case META_BUTTON_SIZING_ASPECT:
- button_height = fgeom->top_height - layout->button_border.top - layout->button_border.bottom;
- button_width = button_height / layout->button_aspect;
- break;
- case META_BUTTON_SIZING_FIXED:
- button_width = layout->button_width;
- button_height = layout->button_height;
- break;
- case META_BUTTON_SIZING_LAST:
- g_assert_not_reached ();
- break;
- }
-
- /* FIXME all this code sort of pretends that duplicate buttons
- * with the same function are allowed, but that breaks the
- * code in frames.c, so isn't really allowed right now.
- * Would need left_close_rect, right_close_rect, etc.
- */
-
- /* Init all button rects to 0, lame hack */
- memset (ADDRESS_OF_BUTTON_RECTS (fgeom), '\0',
- LENGTH_OF_BUTTON_RECTS);
-
- n_left = 0;
- n_right = 0;
- n_left_spacers = 0;
- n_right_spacers = 0;
-
- if (!layout->hide_buttons)
- {
- /* Try to fill in rects */
- for (i = 0; i < MAX_BUTTONS_PER_CORNER && button_layout->left_buttons[i] != META_BUTTON_FUNCTION_LAST; i++)
- {
- left_func_rects[n_left] = rect_for_function (fgeom, flags,
- button_layout->left_buttons[i],
- theme);
- if (left_func_rects[n_left] != NULL)
- {
- left_buttons_has_spacer[n_left] = button_layout->left_buttons_has_spacer[i];
- if (button_layout->left_buttons_has_spacer[i])
- ++n_left_spacers;
-
- ++n_left;
- }
- }
-
- for (i = 0; i < MAX_BUTTONS_PER_CORNER && button_layout->right_buttons[i] != META_BUTTON_FUNCTION_LAST; i++)
- {
- right_func_rects[n_right] = rect_for_function (fgeom, flags,
- button_layout->right_buttons[i],
- theme);
- if (right_func_rects[n_right] != NULL)
- {
- right_buttons_has_spacer[n_right] = button_layout->right_buttons_has_spacer[i];
- if (button_layout->right_buttons_has_spacer[i])
- ++n_right_spacers;
-
- ++n_right;
- }
- }
- }
-
- for (i = 0; i < MAX_BUTTONS_PER_CORNER; i++)
- {
- left_bg_rects[i] = NULL;
- right_bg_rects[i] = NULL;
- }
-
- for (i = 0; i < n_left; i++)
- {
- if (i == 0) /* prefer left background if only one button */
- left_bg_rects[i] = &fgeom->left_left_background;
- else if (i == (n_left - 1))
- left_bg_rects[i] = &fgeom->left_right_background;
- else
- left_bg_rects[i] = &fgeom->left_middle_backgrounds[i - 1];
- }
-
- for (i = 0; i < n_right; i++)
- {
- /* prefer right background if only one button */
- if (i == (n_right - 1))
- right_bg_rects[i] = &fgeom->right_right_background;
- else if (i == 0)
- right_bg_rects[i] = &fgeom->right_left_background;
- else
- right_bg_rects[i] = &fgeom->right_middle_backgrounds[i - 1];
- }
-
- /* Be sure buttons fit */
- while (n_left > 0 || n_right > 0)
- {
- int space_used_by_buttons;
- int space_available;
-
- space_available = fgeom->width - layout->left_titlebar_edge - layout->right_titlebar_edge;
-
- space_used_by_buttons = 0;
-
- space_used_by_buttons += button_width * n_left;
- space_used_by_buttons += (button_width * 0.75) * n_left_spacers;
- space_used_by_buttons += layout->button_border.left * n_left;
- space_used_by_buttons += layout->button_border.right * n_left;
-
- space_used_by_buttons += button_width * n_right;
- space_used_by_buttons += (button_width * 0.75) * n_right_spacers;
- space_used_by_buttons += layout->button_border.left * n_right;
- space_used_by_buttons += layout->button_border.right * n_right;
-
- if (space_used_by_buttons <= space_available)
- break; /* Everything fits, bail out */
-
- /* First try to remove separators */
- if (n_left_spacers > 0)
- {
- left_buttons_has_spacer[--n_left_spacers] = FALSE;
- continue;
- }
- else if (n_right_spacers > 0)
- {
- right_buttons_has_spacer[--n_right_spacers] = FALSE;
- continue;
- }
-
- /* Otherwise we need to shave out a button. Shave
- * above, stick, shade, min, max, close, then menu (menu is most useful);
- * prefer the default button locations.
- */
- if (strip_button (left_func_rects, left_bg_rects,
- &n_left, &fgeom->above_rect))
- continue;
- else if (strip_button (right_func_rects, right_bg_rects,
- &n_right, &fgeom->above_rect))
- continue;
- else if (strip_button (left_func_rects, left_bg_rects,
- &n_left, &fgeom->stick_rect))
- continue;
- else if (strip_button (right_func_rects, right_bg_rects,
- &n_right, &fgeom->stick_rect))
- continue;
- else if (strip_button (left_func_rects, left_bg_rects,
- &n_left, &fgeom->shade_rect))
- continue;
- else if (strip_button (right_func_rects, right_bg_rects,
- &n_right, &fgeom->shade_rect))
- continue;
- else if (strip_button (left_func_rects, left_bg_rects,
- &n_left, &fgeom->min_rect))
- continue;
- else if (strip_button (right_func_rects, right_bg_rects,
- &n_right, &fgeom->min_rect))
- continue;
- else if (strip_button (left_func_rects, left_bg_rects,
- &n_left, &fgeom->max_rect))
- continue;
- else if (strip_button (right_func_rects, right_bg_rects,
- &n_right, &fgeom->max_rect))
- continue;
- else if (strip_button (left_func_rects, left_bg_rects,
- &n_left, &fgeom->close_rect))
- continue;
- else if (strip_button (right_func_rects, right_bg_rects,
- &n_right, &fgeom->close_rect))
- continue;
- else if (strip_button (right_func_rects, right_bg_rects,
- &n_right, &fgeom->menu_rect))
- continue;
- else if (strip_button (left_func_rects, left_bg_rects,
- &n_left, &fgeom->menu_rect))
- continue;
- else
- {
- meta_bug ("Could not find a button to strip. n_left = %d n_right = %d\n",
- n_left, n_right);
- }
- }
-
- /* center buttons vertically */
- button_y = (fgeom->top_height -
- (button_height + layout->button_border.top + layout->button_border.bottom)) / 2 + layout->button_border.top;
-
- /* right edge of farthest-right button */
- x = width - layout->right_titlebar_edge;
-
- i = n_right - 1;
- while (i >= 0)
- {
- MetaButtonSpace *rect;
-
- if (x < 0) /* if we go negative, leave the buttons we don't get to as 0-width */
- break;
-
- rect = right_func_rects[i];
- rect->visible.x = x - layout->button_border.right - button_width;
- if (right_buttons_has_spacer[i])
- rect->visible.x -= (button_width * 0.75);
-
- rect->visible.y = button_y;
- rect->visible.width = button_width;
- rect->visible.height = button_height;
-
- if (flags & META_FRAME_MAXIMIZED)
- {
- rect->clickable.x = rect->visible.x;
- rect->clickable.y = 0;
- rect->clickable.width = rect->visible.width;
- rect->clickable.height = button_height + button_y;
-
- if (i == n_right - 1)
- rect->clickable.width += layout->right_titlebar_edge + layout->right_width + layout->button_border.right;
-
- }
- else
- g_memmove (&(rect->clickable), &(rect->visible), sizeof(rect->clickable));
-
- *(right_bg_rects[i]) = rect->visible;
-
- x = rect->visible.x - layout->button_border.left;
-
- --i;
- }
-
- /* save right edge of titlebar for later use */
- title_right_edge = x - layout->title_border.right;
-
- /* Now x changes to be position from the left and we go through
- * the left-side buttons
- */
- x = layout->left_titlebar_edge;
- for (i = 0; i < n_left; i++)
- {
- MetaButtonSpace *rect;
-
- rect = left_func_rects[i];
-
- rect->visible.x = x + layout->button_border.left;
- rect->visible.y = button_y;
- rect->visible.width = button_width;
- rect->visible.height = button_height;
-
- if (flags & META_FRAME_MAXIMIZED)
- {
- if (i==0)
- {
- rect->clickable.x = 0;
- rect->clickable.width = button_width + x;
- }
- else
- {
- rect->clickable.x = rect->visible.x;
- rect->clickable.width = button_width;
- }
-
- rect->clickable.y = 0;
- rect->clickable.height = button_height + button_y;
- }
- else
- g_memmove (&(rect->clickable), &(rect->visible), sizeof(rect->clickable));
-
-
- x = rect->visible.x + rect->visible.width + layout->button_border.right;
- if (left_buttons_has_spacer[i])
- x += (button_width * 0.75);
-
- *(left_bg_rects[i]) = rect->visible;
- }
-
- /* We always fill as much vertical space as possible with title rect,
- * rather than centering it like the buttons
- */
- fgeom->title_rect.x = x + layout->title_border.left;
- fgeom->title_rect.y = layout->title_border.top;
- fgeom->title_rect.width = title_right_edge - fgeom->title_rect.x;
- fgeom->title_rect.height = fgeom->top_height - layout->title_border.top - layout->title_border.bottom;
-
- /* Nuke title if it won't fit */
- if (fgeom->title_rect.width < 0 ||
- fgeom->title_rect.height < 0)
- {
- fgeom->title_rect.width = 0;
- fgeom->title_rect.height = 0;
- }
-
- if (flags & META_FRAME_SHADED)
- min_size_for_rounding = 0;
- else
- min_size_for_rounding = 5;
-
- fgeom->top_left_corner_rounded_radius = 0;
- fgeom->top_right_corner_rounded_radius = 0;
- fgeom->bottom_left_corner_rounded_radius = 0;
- fgeom->bottom_right_corner_rounded_radius = 0;
-
- if (fgeom->top_height + fgeom->left_width >= min_size_for_rounding)
- fgeom->top_left_corner_rounded_radius = layout->top_left_corner_rounded_radius;
- if (fgeom->top_height + fgeom->right_width >= min_size_for_rounding)
- fgeom->top_right_corner_rounded_radius = layout->top_right_corner_rounded_radius;
-
- if (fgeom->bottom_height + fgeom->left_width >= min_size_for_rounding)
- fgeom->bottom_left_corner_rounded_radius = layout->bottom_left_corner_rounded_radius;
- if (fgeom->bottom_height + fgeom->right_width >= min_size_for_rounding)
- fgeom->bottom_right_corner_rounded_radius = layout->bottom_right_corner_rounded_radius;
-}
-
-MetaGradientSpec*
-meta_gradient_spec_new (MetaGradientType type)
-{
- MetaGradientSpec *spec;
-
- spec = g_new (MetaGradientSpec, 1);
-
- spec->type = type;
- spec->color_specs = NULL;
-
- return spec;
-}
-
-static void
-free_color_spec (gpointer spec, gpointer user_data)
-{
- meta_color_spec_free (spec);
-}
-
-void
-meta_gradient_spec_free (MetaGradientSpec *spec)
-{
- g_return_if_fail (spec != NULL);
-
- g_slist_foreach (spec->color_specs, free_color_spec, NULL);
- g_slist_free (spec->color_specs);
-
- DEBUG_FILL_STRUCT (spec);
- g_free (spec);
-}
-
-GdkPixbuf*
-meta_gradient_spec_render (const MetaGradientSpec *spec,
- GtkWidget *widget,
- int width,
- int height)
-{
- int n_colors;
- GdkColor *colors;
- GSList *tmp;
- int i;
- GdkPixbuf *pixbuf;
-
- n_colors = g_slist_length (spec->color_specs);
-
- if (n_colors == 0)
- return NULL;
-
- colors = g_new (GdkColor, n_colors);
-
- i = 0;
- tmp = spec->color_specs;
- while (tmp != NULL)
- {
- meta_color_spec_render (tmp->data, widget, &colors[i]);
-
- tmp = tmp->next;
- ++i;
- }
-
- pixbuf = meta_gradient_create_multi (width, height,
- colors, n_colors,
- spec->type);
-
- g_free (colors);
-
- return pixbuf;
-}
-
-gboolean
-meta_gradient_spec_validate (MetaGradientSpec *spec,
- GError **error)
-{
- g_return_val_if_fail (spec != NULL, FALSE);
-
- if (g_slist_length (spec->color_specs) < 2)
- {
- g_set_error (error, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Gradients should have at least two colors"));
- return FALSE;
- }
-
- return TRUE;
-}
-
-MetaAlphaGradientSpec*
-meta_alpha_gradient_spec_new (MetaGradientType type,
- int n_alphas)
-{
- MetaAlphaGradientSpec *spec;
-
- g_return_val_if_fail (n_alphas > 0, NULL);
-
- spec = g_new0 (MetaAlphaGradientSpec, 1);
-
- spec->type = type;
- spec->alphas = g_new0 (unsigned char, n_alphas);
- spec->n_alphas = n_alphas;
-
- return spec;
-}
-
-void
-meta_alpha_gradient_spec_free (MetaAlphaGradientSpec *spec)
-{
- g_return_if_fail (spec != NULL);
-
- g_free (spec->alphas);
- g_free (spec);
-}
-
-MetaColorSpec*
-meta_color_spec_new (MetaColorSpecType type)
-{
- MetaColorSpec *spec;
- MetaColorSpec dummy;
- int size;
-
- size = G_STRUCT_OFFSET (MetaColorSpec, data);
-
- switch (type)
- {
- case META_COLOR_SPEC_BASIC:
- size += sizeof (dummy.data.basic);
- break;
-
- case META_COLOR_SPEC_GTK:
- size += sizeof (dummy.data.gtk);
- break;
-
- case META_COLOR_SPEC_BLEND:
- size += sizeof (dummy.data.blend);
- break;
-
- case META_COLOR_SPEC_SHADE:
- size += sizeof (dummy.data.shade);
- break;
- }
-
- spec = g_malloc0 (size);
-
- spec->type = type;
-
- return spec;
-}
-
-void
-meta_color_spec_free (MetaColorSpec *spec)
-{
- g_return_if_fail (spec != NULL);
-
- switch (spec->type)
- {
- case META_COLOR_SPEC_BASIC:
- DEBUG_FILL_STRUCT (&spec->data.basic);
- break;
-
- case META_COLOR_SPEC_GTK:
- DEBUG_FILL_STRUCT (&spec->data.gtk);
- break;
-
- case META_COLOR_SPEC_BLEND:
- if (spec->data.blend.foreground)
- meta_color_spec_free (spec->data.blend.foreground);
- if (spec->data.blend.background)
- meta_color_spec_free (spec->data.blend.background);
- DEBUG_FILL_STRUCT (&spec->data.blend);
- break;
-
- case META_COLOR_SPEC_SHADE:
- if (spec->data.shade.base)
- meta_color_spec_free (spec->data.shade.base);
- DEBUG_FILL_STRUCT (&spec->data.shade);
- break;
- }
-
- g_free (spec);
-}
-
-MetaColorSpec*
-meta_color_spec_new_from_string (const char *str,
- GError **err)
-{
- MetaColorSpec *spec;
-
- spec = NULL;
-
- if (str[0] == 'g' && str[1] == 't' && str[2] == 'k' && str[3] == ':')
- {
- /* GTK color */
- const char *bracket;
- const char *end_bracket;
- char *tmp;
- GtkStateType state;
- MetaGtkColorComponent component;
-
- bracket = str;
- while (*bracket && *bracket != '[')
- ++bracket;
-
- if (*bracket == '\0')
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\""),
- str);
- return NULL;
- }
-
- end_bracket = bracket;
- ++end_bracket;
- while (*end_bracket && *end_bracket != ']')
- ++end_bracket;
-
- if (*end_bracket == '\0')
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("GTK color specification must have a close bracket after the state, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\""),
- str);
- return NULL;
- }
-
- tmp = g_strndup (bracket + 1, end_bracket - bracket - 1);
- state = meta_gtk_state_from_string (tmp);
- if (((int) state) == -1)
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Did not understand state \"%s\" in color specification"),
- tmp);
- g_free (tmp);
- return NULL;
- }
- g_free (tmp);
-
- tmp = g_strndup (str + 4, bracket - str - 4);
- component = meta_color_component_from_string (tmp);
- if (component == META_GTK_COLOR_LAST)
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Did not understand color component \"%s\" in color specification"),
- tmp);
- g_free (tmp);
- return NULL;
- }
- g_free (tmp);
-
- spec = meta_color_spec_new (META_COLOR_SPEC_GTK);
- spec->data.gtk.state = state;
- spec->data.gtk.component = component;
- g_assert (spec->data.gtk.state < N_GTK_STATES);
- g_assert (spec->data.gtk.component < META_GTK_COLOR_LAST);
- }
- else if (str[0] == 'b' && str[1] == 'l' && str[2] == 'e' && str[3] == 'n' &&
- str[4] == 'd' && str[5] == '/')
- {
- /* blend */
- char **split;
- double alpha;
- char *end;
- MetaColorSpec *fg;
- MetaColorSpec *bg;
-
- split = g_strsplit (str, "/", 4);
-
- if (split[0] == NULL || split[1] == NULL ||
- split[2] == NULL || split[3] == NULL)
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the format"),
- str);
- g_strfreev (split);
- return NULL;
- }
-
- alpha = g_ascii_strtod (split[3], &end);
- if (end == split[3])
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Could not parse alpha value \"%s\" in blended color"),
- split[3]);
- g_strfreev (split);
- return NULL;
- }
-
- if (alpha < (0.0 - 1e6) || alpha > (1.0 + 1e6))
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Alpha value \"%s\" in blended color is not between 0.0 and 1.0"),
- split[3]);
- g_strfreev (split);
- return NULL;
- }
-
- fg = NULL;
- bg = NULL;
-
- bg = meta_color_spec_new_from_string (split[1], err);
- if (bg == NULL)
- {
- g_strfreev (split);
- return NULL;
- }
-
- fg = meta_color_spec_new_from_string (split[2], err);
- if (fg == NULL)
- {
- meta_color_spec_free (bg);
- g_strfreev (split);
- return NULL;
- }
-
- g_strfreev (split);
-
- spec = meta_color_spec_new (META_COLOR_SPEC_BLEND);
- spec->data.blend.alpha = alpha;
- spec->data.blend.background = bg;
- spec->data.blend.foreground = fg;
- }
- else if (str[0] == 's' && str[1] == 'h' && str[2] == 'a' && str[3] == 'd' &&
- str[4] == 'e' && str[5] == '/')
- {
- /* shade */
- char **split;
- double factor;
- char *end;
- MetaColorSpec *base;
-
- split = g_strsplit (str, "/", 3);
-
- if (split[0] == NULL || split[1] == NULL ||
- split[2] == NULL)
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format"),
- str);
- g_strfreev (split);
- return NULL;
- }
-
- factor = g_ascii_strtod (split[2], &end);
- if (end == split[2])
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Could not parse shade factor \"%s\" in shaded color"),
- split[2]);
- g_strfreev (split);
- return NULL;
- }
-
- if (factor < (0.0 - 1e6))
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Shade factor \"%s\" in shaded color is negative"),
- split[2]);
- g_strfreev (split);
- return NULL;
- }
-
- base = NULL;
-
- base = meta_color_spec_new_from_string (split[1], err);
- if (base == NULL)
- {
- g_strfreev (split);
- return NULL;
- }
-
- g_strfreev (split);
-
- spec = meta_color_spec_new (META_COLOR_SPEC_SHADE);
- spec->data.shade.factor = factor;
- spec->data.shade.base = base;
- }
- else
- {
- spec = meta_color_spec_new (META_COLOR_SPEC_BASIC);
-
- if (!gdk_color_parse (str, &spec->data.basic.color))
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Could not parse color \"%s\""),
- str);
- meta_color_spec_free (spec);
- return NULL;
- }
- }
-
- g_assert (spec);
-
- return spec;
-}
-
-MetaColorSpec*
-meta_color_spec_new_gtk (MetaGtkColorComponent component,
- GtkStateType state)
-{
- MetaColorSpec *spec;
-
- spec = meta_color_spec_new (META_COLOR_SPEC_GTK);
-
- spec->data.gtk.component = component;
- spec->data.gtk.state = state;
-
- return spec;
-}
-
-void
-meta_color_spec_render (MetaColorSpec *spec,
- GtkWidget *widget,
- GdkColor *color)
-{
- g_return_if_fail (spec != NULL);
- g_return_if_fail (GTK_IS_WIDGET (widget));
- g_return_if_fail (widget->style != NULL);
-
- switch (spec->type)
- {
- case META_COLOR_SPEC_BASIC:
- *color = spec->data.basic.color;
- break;
-
- case META_COLOR_SPEC_GTK:
- switch (spec->data.gtk.component)
- {
- case META_GTK_COLOR_BG:
- *color = widget->style->bg[spec->data.gtk.state];
- break;
- case META_GTK_COLOR_FG:
- *color = widget->style->fg[spec->data.gtk.state];
- break;
- case META_GTK_COLOR_BASE:
- *color = widget->style->base[spec->data.gtk.state];
- break;
- case META_GTK_COLOR_TEXT:
- *color = widget->style->text[spec->data.gtk.state];
- break;
- case META_GTK_COLOR_LIGHT:
- *color = widget->style->light[spec->data.gtk.state];
- break;
- case META_GTK_COLOR_DARK:
- *color = widget->style->dark[spec->data.gtk.state];
- break;
- case META_GTK_COLOR_MID:
- *color = widget->style->mid[spec->data.gtk.state];
- break;
- case META_GTK_COLOR_TEXT_AA:
- *color = widget->style->text_aa[spec->data.gtk.state];
- break;
- case META_GTK_COLOR_LAST:
- g_assert_not_reached ();
- break;
- }
- break;
-
- case META_COLOR_SPEC_BLEND:
- {
- GdkColor bg, fg;
-
- meta_color_spec_render (spec->data.blend.background, widget, &bg);
- meta_color_spec_render (spec->data.blend.foreground, widget, &fg);
-
- color_composite (&bg, &fg, spec->data.blend.alpha,
- &spec->data.blend.color);
-
- *color = spec->data.blend.color;
- }
- break;
-
- case META_COLOR_SPEC_SHADE:
- {
- meta_color_spec_render (spec->data.shade.base, widget,
- &spec->data.shade.color);
-
- gtk_style_shade (&spec->data.shade.color,
- &spec->data.shade.color, spec->data.shade.factor);
-
- *color = spec->data.shade.color;
- }
- break;
- }
-}
-
-/**
- * Represents an operation as a string.
- *
- * \param type an operation, such as addition
- * \return a string, such as "+"
- */
-static const char*
-op_name (PosOperatorType type)
-{
- switch (type)
- {
- case POS_OP_ADD:
- return "+";
- case POS_OP_SUBTRACT:
- return "-";
- case POS_OP_MULTIPLY:
- return "*";
- case POS_OP_DIVIDE:
- return "/";
- case POS_OP_MOD:
- return "%";
- case POS_OP_MAX:
- return "`max`";
- case POS_OP_MIN:
- return "`min`";
- case POS_OP_NONE:
- break;
- }
-
- return "<unknown>";
-}
-
-/**
- * Parses a string and returns an operation.
- *
- * \param p a pointer into a string representing an operation; part of an
- * expression somewhere, so not null-terminated
- * \param len set to the length of the string found. Set to 0 if none is.
- * \return the operation found. If none was, returns POS_OP_NONE.
- */
-static PosOperatorType
-op_from_string (const char *p,
- int *len)
-{
- *len = 0;
-
- switch (*p)
- {
- case '+':
- *len = 1;
- return POS_OP_ADD;
- case '-':
- *len = 1;
- return POS_OP_SUBTRACT;
- case '*':
- *len = 1;
- return POS_OP_MULTIPLY;
- case '/':
- *len = 1;
- return POS_OP_DIVIDE;
- case '%':
- *len = 1;
- return POS_OP_MOD;
-
- case '`':
- if (p[0] == '`' &&
- p[1] == 'm' &&
- p[2] == 'a' &&
- p[3] == 'x' &&
- p[4] == '`')
- {
- *len = 5;
- return POS_OP_MAX;
- }
- else if (p[0] == '`' &&
- p[1] == 'm' &&
- p[2] == 'i' &&
- p[3] == 'n' &&
- p[4] == '`')
- {
- *len = 5;
- return POS_OP_MIN;
- }
- }
-
- return POS_OP_NONE;
-}
-
-/**
- * Frees an array of tokens. All the tokens and their associated memory
- * will be freed.
- *
- * \param tokens an array of tokens to be freed
- * \param n_tokens how many tokens are in the array.
- */
-static void
-free_tokens (PosToken *tokens,
- int n_tokens)
-{
- int i;
-
- /* n_tokens can be 0 since tokens may have been allocated more than
- * it was initialized
- */
-
- for (i = 0; i < n_tokens; i++)
- if (tokens[i].type == POS_TOKEN_VARIABLE)
- g_free (tokens[i].d.v.name);
-
- g_free (tokens);
-}
-
-/**
- * Tokenises a number in an expression.
- *
- * \param p a pointer into a string representing an operation; part of an
- * expression somewhere, so not null-terminated
- * \param end_return set to a pointer to the end of the number found; but
- * not updated if no number was found at all
- * \param next set to either an integer or a float token
- * \param[out] err set to the problem if there was a problem
- * \return TRUE if a valid number was found, FALSE otherwise (and "err" will
- * have been set)
- *
- * \bug The "while (*start)..." part: what's wrong with strchr-ish things?
- * \bug The name is wrong: it doesn't parse anything.
- * \ingroup tokenizer
- */
-static gboolean
-parse_number (const char *p,
- const char **end_return,
- PosToken *next,
- GError **err)
-{
- const char *start = p;
- char *end;
- gboolean is_float;
- char *num_str;
-
- while (*p && (*p == '.' || g_ascii_isdigit (*p)))
- ++p;
-
- if (p == start)
- {
- char buf[7] = { '\0' };
- buf[g_unichar_to_utf8 (g_utf8_get_char (p), buf)] = '\0';
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_BAD_CHARACTER,
- _("Coordinate expression contains character '%s' which is not allowed"),
- buf);
- return FALSE;
- }
-
- *end_return = p;
-
- /* we need this to exclude floats like "1e6" */
- num_str = g_strndup (start, p - start);
- start = num_str;
- is_float = FALSE;
- while (*start)
- {
- if (*start == '.')
- is_float = TRUE;
- ++start;
- }
-
- if (is_float)
- {
- next->type = POS_TOKEN_DOUBLE;
- next->d.d.val = g_ascii_strtod (num_str, &end);
-
- if (end == num_str)
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Coordinate expression contains floating point number '%s' which could not be parsed"),
- num_str);
- g_free (num_str);
- return FALSE;
- }
- }
- else
- {
- next->type = POS_TOKEN_INT;
- next->d.i.val = strtol (num_str, &end, 10);
- if (end == num_str)
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Coordinate expression contains integer '%s' which could not be parsed"),
- num_str);
- g_free (num_str);
- return FALSE;
- }
- }
-
- g_free (num_str);
-
- g_assert (next->type == POS_TOKEN_INT || next->type == POS_TOKEN_DOUBLE);
-
- return TRUE;
-}
-
-/**
- * Whether a variable can validly appear as part of the name of a variable.
- */
-#define IS_VARIABLE_CHAR(c) (g_ascii_isalpha ((c)) || (c) == '_')
-
-#if 0
-static void
-debug_print_tokens (PosToken *tokens,
- int n_tokens)
-{
- int i;
-
- for (i = 0; i < n_tokens; i++)
- {
- PosToken *t = &tokens[i];
-
- g_print (" ");
-
- switch (t->type)
- {
- case POS_TOKEN_INT:
- g_print ("\"%d\"", t->d.i.val);
- break;
- case POS_TOKEN_DOUBLE:
- g_print ("\"%g\"", t->d.d.val);
- break;
- case POS_TOKEN_OPEN_PAREN:
- g_print ("\"(\"");
- break;
- case POS_TOKEN_CLOSE_PAREN:
- g_print ("\")\"");
- break;
- case POS_TOKEN_VARIABLE:
- g_print ("\"%s\"", t->d.v.name);
- break;
- case POS_TOKEN_OPERATOR:
- g_print ("\"%s\"", op_name (t->d.o.op));
- break;
- }
- }
-
- g_print ("\n");
-}
-#endif
-
-/**
- * Tokenises an expression.
- *
- * \param expr The expression
- * \param[out] tokens_p The resulting tokens
- * \param[out] n_tokens_p The number of resulting tokens
- * \param[out] err set to the problem if there was a problem
- *
- * \return True if the expression was successfully tokenised; false otherwise.
- *
- * \ingroup tokenizer
- */
-static gboolean
-pos_tokenize (const char *expr,
- PosToken **tokens_p,
- int *n_tokens_p,
- GError **err)
-{
- PosToken *tokens;
- int n_tokens;
- int allocated;
- const char *p;
-
- *tokens_p = NULL;
- *n_tokens_p = 0;
-
- allocated = 3;
- n_tokens = 0;
- tokens = g_new (PosToken, allocated);
-
- p = expr;
- while (*p)
- {
- PosToken *next;
- int len;
-
- if (n_tokens == allocated)
- {
- allocated *= 2;
- tokens = g_renew (PosToken, tokens, allocated);
- }
-
- next = &tokens[n_tokens];
-
- switch (*p)
- {
- case '*':
- case '/':
- case '+':
- case '-': /* negative numbers aren't allowed so this is easy */
- case '%':
- case '`':
- next->type = POS_TOKEN_OPERATOR;
- next->d.o.op = op_from_string (p, &len);
- if (next->d.o.op != POS_OP_NONE)
- {
- ++n_tokens;
- p = p + (len - 1); /* -1 since we ++p later */
- }
- else
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Coordinate expression contained unknown operator at the start of this text: \"%s\""),
- p);
-
- goto error;
- }
- break;
-
- case '(':
- next->type = POS_TOKEN_OPEN_PAREN;
- ++n_tokens;
- break;
-
- case ')':
- next->type = POS_TOKEN_CLOSE_PAREN;
- ++n_tokens;
- break;
-
- case ' ':
- case '\t':
- case '\n':
- break;
-
- default:
- if (IS_VARIABLE_CHAR (*p))
- {
- /* Assume variable */
- const char *start = p;
- while (*p && IS_VARIABLE_CHAR (*p))
- ++p;
- g_assert (p != start);
- next->type = POS_TOKEN_VARIABLE;
- next->d.v.name = g_strndup (start, p - start);
- ++n_tokens;
- --p; /* since we ++p again at the end of while loop */
- }
- else
- {
- /* Assume number */
- const char *end;
-
- if (!parse_number (p, &end, next, err))
- goto error;
-
- ++n_tokens;
- p = end - 1; /* -1 since we ++p again at the end of while loop */
- }
-
- break;
- }
-
- ++p;
- }
-
- if (n_tokens == 0)
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Coordinate expression was empty or not understood"));
-
- goto error;
- }
-
- *tokens_p = tokens;
- *n_tokens_p = n_tokens;
-
- return TRUE;
-
- error:
- g_assert (err == NULL || *err != NULL);
-
- free_tokens (tokens, n_tokens);
- return FALSE;
-}
-
-/**
- * The type of a PosExpr: either integer, double, or an operation.
- * \ingroup parser
- */
-typedef enum
-{
- POS_EXPR_INT,
- POS_EXPR_DOUBLE,
- POS_EXPR_OPERATOR
-} PosExprType;
-
-/**
- * Type and value of an expression in a parsed sequence. We don't
- * keep expressions in a tree; if this is of type POS_EXPR_OPERATOR,
- * the arguments of the operator will be in the array positions
- * immediately preceding and following this operator; they cannot
- * themselves be operators.
- *
- * \bug operator is char; it should really be of PosOperatorType.
- * \ingroup parser
- */
-typedef struct
-{
- PosExprType type;
- union
- {
- double double_val;
- int int_val;
- char operator;
- } d;
-} PosExpr;
-
-#if 0
-static void
-debug_print_exprs (PosExpr *exprs,
- int n_exprs)
-{
- int i;
-
- for (i = 0; i < n_exprs; i++)
- {
- switch (exprs[i].type)
- {
- case POS_EXPR_INT:
- g_print (" %d", exprs[i].d.int_val);
- break;
- case POS_EXPR_DOUBLE:
- g_print (" %g", exprs[i].d.double_val);
- break;
- case POS_EXPR_OPERATOR:
- g_print (" %s", op_name (exprs[i].d.operator));
- break;
- }
- }
- g_print ("\n");
-}
-#endif
-
-static gboolean
-do_operation (PosExpr *a,
- PosExpr *b,
- PosOperatorType op,
- GError **err)
-{
- /* Promote types to double if required */
- if (a->type == POS_EXPR_DOUBLE ||
- b->type == POS_EXPR_DOUBLE)
- {
- if (a->type != POS_EXPR_DOUBLE)
- {
- a->type = POS_EXPR_DOUBLE;
- a->d.double_val = a->d.int_val;
- }
- if (b->type != POS_EXPR_DOUBLE)
- {
- b->type = POS_EXPR_DOUBLE;
- b->d.double_val = b->d.int_val;
- }
- }
-
- g_assert (a->type == b->type);
-
- if (a->type == POS_EXPR_INT)
- {
- switch (op)
- {
- case POS_OP_MULTIPLY:
- a->d.int_val = a->d.int_val * b->d.int_val;
- break;
- case POS_OP_DIVIDE:
- if (b->d.int_val == 0)
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_DIVIDE_BY_ZERO,
- _("Coordinate expression results in division by zero"));
- return FALSE;
- }
- a->d.int_val = a->d.int_val / b->d.int_val;
- break;
- case POS_OP_MOD:
- if (b->d.int_val == 0)
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_DIVIDE_BY_ZERO,
- _("Coordinate expression results in division by zero"));
- return FALSE;
- }
- a->d.int_val = a->d.int_val % b->d.int_val;
- break;
- case POS_OP_ADD:
- a->d.int_val = a->d.int_val + b->d.int_val;
- break;
- case POS_OP_SUBTRACT:
- a->d.int_val = a->d.int_val - b->d.int_val;
- break;
- case POS_OP_MAX:
- a->d.int_val = MAX (a->d.int_val, b->d.int_val);
- break;
- case POS_OP_MIN:
- a->d.int_val = MIN (a->d.int_val, b->d.int_val);
- break;
- case POS_OP_NONE:
- g_assert_not_reached ();
- break;
- }
- }
- else if (a->type == POS_EXPR_DOUBLE)
- {
- switch (op)
- {
- case POS_OP_MULTIPLY:
- a->d.double_val = a->d.double_val * b->d.double_val;
- break;
- case POS_OP_DIVIDE:
- if (b->d.double_val == 0.0)
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_DIVIDE_BY_ZERO,
- _("Coordinate expression results in division by zero"));
- return FALSE;
- }
- a->d.double_val = a->d.double_val / b->d.double_val;
- break;
- case POS_OP_MOD:
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_MOD_ON_FLOAT,
- _("Coordinate expression tries to use mod operator on a floating-point number"));
- return FALSE;
- case POS_OP_ADD:
- a->d.double_val = a->d.double_val + b->d.double_val;
- break;
- case POS_OP_SUBTRACT:
- a->d.double_val = a->d.double_val - b->d.double_val;
- break;
- case POS_OP_MAX:
- a->d.double_val = MAX (a->d.double_val, b->d.double_val);
- break;
- case POS_OP_MIN:
- a->d.double_val = MIN (a->d.double_val, b->d.double_val);
- break;
- case POS_OP_NONE:
- g_assert_not_reached ();
- break;
- }
- }
- else
- g_assert_not_reached ();
-
- return TRUE;
-}
-
-static gboolean
-do_operations (PosExpr *exprs,
- int *n_exprs,
- int precedence,
- GError **err)
-{
- int i;
-
-#if 0
- g_print ("Doing prec %d ops on %d exprs\n", precedence, *n_exprs);
- debug_print_exprs (exprs, *n_exprs);
-#endif
-
- i = 1;
- while (i < *n_exprs)
- {
- gboolean compress;
-
- /* exprs[i-1] first operand
- * exprs[i] operator
- * exprs[i+1] second operand
- *
- * we replace first operand with result of mul/div/mod,
- * or skip over operator and second operand if we have
- * an add/subtract
- */
-
- if (exprs[i-1].type == POS_EXPR_OPERATOR)
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Coordinate expression has an operator \"%s\" where an operand was expected"),
- op_name (exprs[i-1].d.operator));
- return FALSE;
- }
-
- if (exprs[i].type != POS_EXPR_OPERATOR)
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Coordinate expression had an operand where an operator was expected"));
- return FALSE;
- }
-
- if (i == (*n_exprs - 1))
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Coordinate expression ended with an operator instead of an operand"));
- return FALSE;
- }
-
- g_assert ((i+1) < *n_exprs);
-
- if (exprs[i+1].type == POS_EXPR_OPERATOR)
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Coordinate expression has operator \"%c\" following operator \"%c\" with no operand in between"),
- exprs[i+1].d.operator,
- exprs[i].d.operator);
- return FALSE;
- }
-
- compress = FALSE;
-
- switch (precedence)
- {
- case 2:
- switch (exprs[i].d.operator)
- {
- case POS_OP_DIVIDE:
- case POS_OP_MOD:
- case POS_OP_MULTIPLY:
- compress = TRUE;
- if (!do_operation (&exprs[i-1], &exprs[i+1],
- exprs[i].d.operator,
- err))
- return FALSE;
- break;
- }
- break;
- case 1:
- switch (exprs[i].d.operator)
- {
- case POS_OP_ADD:
- case POS_OP_SUBTRACT:
- compress = TRUE;
- if (!do_operation (&exprs[i-1], &exprs[i+1],
- exprs[i].d.operator,
- err))
- return FALSE;
- break;
- }
- break;
- /* I have no rationale at all for making these low-precedence */
- case 0:
- switch (exprs[i].d.operator)
- {
- case POS_OP_MAX:
- case POS_OP_MIN:
- compress = TRUE;
- if (!do_operation (&exprs[i-1], &exprs[i+1],
- exprs[i].d.operator,
- err))
- return FALSE;
- break;
- }
- break;
- }
-
- if (compress)
- {
- /* exprs[i-1] first operand (now result)
- * exprs[i] operator
- * exprs[i+1] second operand
- * exprs[i+2] new operator
- *
- * we move new operator just after first operand
- */
- if ((i+2) < *n_exprs)
- {
- g_memmove (&exprs[i], &exprs[i+2],
- sizeof (PosExpr) * (*n_exprs - i - 2));
- }
-
- *n_exprs -= 2;
- }
- else
- {
- /* Skip operator and next operand */
- i += 2;
- }
- }
-
- return TRUE;
-}
-
-/**
- * There is a predefined set of variables which can appear in an expression.
- * Here we take a token representing a variable, and return the current value
- * of that variable in a particular environment.
- * (The value is always an integer.)
- *
- * There are supposedly some circumstances in which this function can be
- * called from outside Metacity, in which case env->theme will be NULL, and
- * therefore we can't use it to find out quark values, so we do the comparison
- * using strcmp, which is slower.
- *
- * \param t The token representing a variable
- * \param[out] result The value of that variable; not set if the token did
- * not represent a known variable
- * \param env The environment within which t should be evaluated
- * \param[out] err set to the problem if there was a problem
- *
- * \return true if we found the variable asked for, false if we didn't
- *
- * \bug shouldn't t be const?
- * \bug we should perhaps consider some sort of lookup arrangement into an
- * array; also, the duplication of code is unlovely; perhaps using glib
- * string hashes instead of quarks would fix both problems?
- * \ingroup parser
- */
-static gboolean
-pos_eval_get_variable (PosToken *t,
- int *result,
- const MetaPositionExprEnv *env,
- GError **err)
-{
- if (env->theme)
- {
- if (t->d.v.name_quark == env->theme->quark_width)
- *result = env->rect.width;
- else if (t->d.v.name_quark == env->theme->quark_height)
- *result = env->rect.height;
- else if (env->object_width >= 0 &&
- t->d.v.name_quark == env->theme->quark_object_width)
- *result = env->object_width;
- else if (env->object_height >= 0 &&
- t->d.v.name_quark == env->theme->quark_object_height)
- *result = env->object_height;
- else if (t->d.v.name_quark == env->theme->quark_left_width)
- *result = env->left_width;
- else if (t->d.v.name_quark == env->theme->quark_right_width)
- *result = env->right_width;
- else if (t->d.v.name_quark == env->theme->quark_top_height)
- *result = env->top_height;
- else if (t->d.v.name_quark == env->theme->quark_bottom_height)
- *result = env->bottom_height;
- else if (t->d.v.name_quark == env->theme->quark_mini_icon_width)
- *result = env->mini_icon_width;
- else if (t->d.v.name_quark == env->theme->quark_mini_icon_height)
- *result = env->mini_icon_height;
- else if (t->d.v.name_quark == env->theme->quark_icon_width)
- *result = env->icon_width;
- else if (t->d.v.name_quark == env->theme->quark_icon_height)
- *result = env->icon_height;
- else if (t->d.v.name_quark == env->theme->quark_title_width)
- *result = env->title_width;
- else if (t->d.v.name_quark == env->theme->quark_title_height)
- *result = env->title_height;
- else
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_UNKNOWN_VARIABLE,
- _("Coordinate expression had unknown variable or constant \"%s\""),
- t->d.v.name);
- return FALSE;
- }
- }
- else
- {
- if (strcmp (t->d.v.name, "width") == 0)
- *result = env->rect.width;
- else if (strcmp (t->d.v.name, "height") == 0)
- *result = env->rect.height;
- else if (env->object_width >= 0 &&
- strcmp (t->d.v.name, "object_width") == 0)
- *result = env->object_width;
- else if (env->object_height >= 0 &&
- strcmp (t->d.v.name, "object_height") == 0)
- *result = env->object_height;
- else if (strcmp (t->d.v.name, "left_width") == 0)
- *result = env->left_width;
- else if (strcmp (t->d.v.name, "right_width") == 0)
- *result = env->right_width;
- else if (strcmp (t->d.v.name, "top_height") == 0)
- *result = env->top_height;
- else if (strcmp (t->d.v.name, "bottom_height") == 0)
- *result = env->bottom_height;
- else if (strcmp (t->d.v.name, "mini_icon_width") == 0)
- *result = env->mini_icon_width;
- else if (strcmp (t->d.v.name, "mini_icon_height") == 0)
- *result = env->mini_icon_height;
- else if (strcmp (t->d.v.name, "icon_width") == 0)
- *result = env->icon_width;
- else if (strcmp (t->d.v.name, "icon_height") == 0)
- *result = env->icon_height;
- else if (strcmp (t->d.v.name, "title_width") == 0)
- *result = env->title_width;
- else if (strcmp (t->d.v.name, "title_height") == 0)
- *result = env->title_height;
- else
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_UNKNOWN_VARIABLE,
- _("Coordinate expression had unknown variable or constant \"%s\""),
- t->d.v.name);
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-/**
- * Evaluates a sequence of tokens within a particular environment context,
- * and returns the current value. May recur if parantheses are found.
- *
- * \param tokens A list of tokens to evaluate.
- * \param n_tokens How many tokens are in the list.
- * \param env The environment context in which to evaluate the expression.
- * \param[out] result The current value of the expression
- *
- * \bug Yes, we really do reparse the expression every time it's evaluated.
- * We should keep the parse tree around all the time and just
- * run the new values through it.
- * \ingroup parser
- */
-static gboolean
-pos_eval_helper (PosToken *tokens,
- int n_tokens,
- const MetaPositionExprEnv *env,
- PosExpr *result,
- GError **err)
-{
- /* Lazy-ass hardcoded limit on number of terms in expression */
-#define MAX_EXPRS 32
- int paren_level;
- int first_paren;
- int i;
- PosExpr exprs[MAX_EXPRS];
- int n_exprs;
- int precedence;
-
- /* Our first goal is to get a list of PosExpr, essentially
- * substituting variables and handling parentheses.
- */
-
- first_paren = 0;
- paren_level = 0;
- n_exprs = 0;
- for (i = 0; i < n_tokens; i++)
- {
- PosToken *t = &tokens[i];
-
- if (n_exprs >= MAX_EXPRS)
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Coordinate expression parser overflowed its buffer."));
- return FALSE;
- }
-
- if (paren_level == 0)
- {
- switch (t->type)
- {
- case POS_TOKEN_INT:
- exprs[n_exprs].type = POS_EXPR_INT;
- exprs[n_exprs].d.int_val = t->d.i.val;
- ++n_exprs;
- break;
-
- case POS_TOKEN_DOUBLE:
- exprs[n_exprs].type = POS_EXPR_DOUBLE;
- exprs[n_exprs].d.double_val = t->d.d.val;
- ++n_exprs;
- break;
-
- case POS_TOKEN_OPEN_PAREN:
- ++paren_level;
- if (paren_level == 1)
- first_paren = i;
- break;
-
- case POS_TOKEN_CLOSE_PAREN:
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_BAD_PARENS,
- _("Coordinate expression had a close parenthesis with no open parenthesis"));
- return FALSE;
-
- case POS_TOKEN_VARIABLE:
- exprs[n_exprs].type = POS_EXPR_INT;
-
- /* FIXME we should just dump all this crap
- * in a hash, maybe keep width/height out
- * for optimization purposes
- */
- if (!pos_eval_get_variable (t, &exprs[n_exprs].d.int_val, env, err))
- return FALSE;
-
- ++n_exprs;
- break;
-
- case POS_TOKEN_OPERATOR:
- exprs[n_exprs].type = POS_EXPR_OPERATOR;
- exprs[n_exprs].d.operator = t->d.o.op;
- ++n_exprs;
- break;
- }
- }
- else
- {
- g_assert (paren_level > 0);
-
- switch (t->type)
- {
- case POS_TOKEN_INT:
- case POS_TOKEN_DOUBLE:
- case POS_TOKEN_VARIABLE:
- case POS_TOKEN_OPERATOR:
- break;
-
- case POS_TOKEN_OPEN_PAREN:
- ++paren_level;
- break;
-
- case POS_TOKEN_CLOSE_PAREN:
- if (paren_level == 1)
- {
- /* We closed a toplevel paren group, so recurse */
- if (!pos_eval_helper (&tokens[first_paren+1],
- i - first_paren - 1,
- env,
- &exprs[n_exprs],
- err))
- return FALSE;
-
- ++n_exprs;
- }
-
- --paren_level;
- break;
-
- }
- }
- }
-
- if (paren_level > 0)
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_BAD_PARENS,
- _("Coordinate expression had an open parenthesis with no close parenthesis"));
- return FALSE;
- }
-
- /* Now we have no parens and no vars; so we just do all the multiplies
- * and divides, then all the add and subtract.
- */
- if (n_exprs == 0)
- {
- g_set_error (err, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Coordinate expression doesn't seem to have any operators or operands"));
- return FALSE;
- }
-
- /* precedence 1 ops */
- precedence = 2;
- while (precedence >= 0)
- {
- if (!do_operations (exprs, &n_exprs, precedence, err))
- return FALSE;
- --precedence;
- }
-
- g_assert (n_exprs == 1);
-
- *result = *exprs;
-
- return TRUE;
-}
-
-/*
- * expr = int | double | expr * expr | expr / expr |
- * expr + expr | expr - expr | (expr)
- *
- * so very not worth fooling with bison, yet so very painful by hand.
- */
-/**
- * Evaluates an expression.
- *
- * \param spec The expression to evaluate.
- * \param env The environment context to evaluate the expression in.
- * \param[out] val_p The integer value of the expression; if the expression
- * is of type float, this will be rounded. If we return
- * FALSE because the expression is invalid, this will be
- * zero.
- * \param[out] err The error, if anything went wrong.
- *
- * \return True if we evaluated the expression successfully; false otherwise.
- *
- * \bug Shouldn't spec be const?
- * \ingroup parser
- */
-static gboolean
-pos_eval (MetaDrawSpec *spec,
- const MetaPositionExprEnv *env,
- int *val_p,
- GError **err)
-{
- PosExpr expr;
-
- *val_p = 0;
-
- if (pos_eval_helper (spec->tokens, spec->n_tokens, env, &expr, err))
- {
- switch (expr.type)
- {
- case POS_EXPR_INT:
- *val_p = expr.d.int_val;
- break;
- case POS_EXPR_DOUBLE:
- *val_p = expr.d.double_val;
- break;
- case POS_EXPR_OPERATOR:
- g_assert_not_reached ();
- break;
- }
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-/* We always return both X and Y, but only one will be meaningful in
- * most contexts.
- */
-
-gboolean
-meta_parse_position_expression (MetaDrawSpec *spec,
- const MetaPositionExprEnv *env,
- int *x_return,
- int *y_return,
- GError **err)
-{
- /* All positions are in a coordinate system with x, y at the origin.
- * The expression can have -, +, *, / as operators, floating point
- * or integer constants, and the variables "width" and "height" and
- * optionally "object_width" and object_height". Negative numbers
- * aren't allowed.
- */
- int val;
-
- if (spec->constant)
- val = spec->value;
- else
- {
- if (pos_eval (spec, env, &spec->value, err) == FALSE)
- {
- g_assert (err == NULL || *err != NULL);
- return FALSE;
- }
-
- val = spec->value;
- }
-
- if (x_return)
- *x_return = env->rect.x + val;
- if (y_return)
- *y_return = env->rect.y + val;
-
- return TRUE;
-}
-
-
-gboolean
-meta_parse_size_expression (MetaDrawSpec *spec,
- const MetaPositionExprEnv *env,
- int *val_return,
- GError **err)
-{
- int val;
-
- if (spec->constant)
- val = spec->value;
- else
- {
- if (pos_eval (spec, env, &spec->value, err) == FALSE)
- {
- g_assert (err == NULL || *err != NULL);
- return FALSE;
- }
-
- val = spec->value;
- }
-
- if (val_return)
- *val_return = MAX (val, 1); /* require that sizes be at least 1x1 */
-
- return TRUE;
-}
-
-/* To do this we tokenize, replace variable tokens
- * that are constants, then reassemble. The purpose
- * here is to optimize expressions so we don't do hash
- * lookups to eval them. Obviously it's a tradeoff that
- * slows down theme load times.
- */
-gboolean
-meta_theme_replace_constants (MetaTheme *theme,
- PosToken *tokens,
- int n_tokens,
- GError **err)
-{
- int i;
- double dval;
- int ival;
- gboolean is_constant = TRUE;
-
- /* Loop through tokenized string looking for variables to replace */
- for (i = 0; i < n_tokens; i++)
- {
- PosToken *t = &tokens[i];
-
- if (t->type == POS_TOKEN_VARIABLE)
- {
- if (meta_theme_lookup_int_constant (theme, t->d.v.name, &ival))
- {
- t->type = POS_TOKEN_INT;
- t->d.i.val = ival;
- }
- else if (meta_theme_lookup_float_constant (theme, t->d.v.name, &dval))
- {
- t->type = POS_TOKEN_DOUBLE;
- t->d.d.val = dval;
- }
- else
- {
- /* If we've found a variable that cannot be replaced then the
- expression is not a constant expression and we want to
- replace it with a GQuark */
-
- t->d.v.name_quark = g_quark_from_string (t->d.v.name);
- is_constant = FALSE;
- }
- }
- }
-
- return is_constant;
-}
-
-static int
-parse_x_position_unchecked (MetaDrawSpec *spec,
- const MetaPositionExprEnv *env)
-{
- int retval;
- GError *error;
-
- retval = 0;
- error = NULL;
- if (!meta_parse_position_expression (spec, env, &retval, NULL, &error))
- {
- meta_warning (_("Theme contained an expression that resulted in an error: %s\n"),
- error->message);
-
- g_error_free (error);
- }
-
- return retval;
-}
-
-static int
-parse_y_position_unchecked (MetaDrawSpec *spec,
- const MetaPositionExprEnv *env)
-{
- int retval;
- GError *error;
-
- retval = 0;
- error = NULL;
- if (!meta_parse_position_expression (spec, env, NULL, &retval, &error))
- {
- meta_warning (_("Theme contained an expression that resulted in an error: %s\n"),
- error->message);
-
- g_error_free (error);
- }
-
- return retval;
-}
-
-static int
-parse_size_unchecked (MetaDrawSpec *spec,
- MetaPositionExprEnv *env)
-{
- int retval;
- GError *error;
-
- retval = 0;
- error = NULL;
- if (!meta_parse_size_expression (spec, env, &retval, &error))
- {
- meta_warning (_("Theme contained an expression that resulted in an error: %s\n"),
- error->message);
-
- g_error_free (error);
- }
-
- return retval;
-}
-
-void
-meta_draw_spec_free (MetaDrawSpec *spec)
-{
- free_tokens (spec->tokens, spec->n_tokens);
- g_slice_free (MetaDrawSpec, spec);
-}
-
-MetaDrawSpec *
-meta_draw_spec_new (MetaTheme *theme,
- const char *expr,
- GError **error)
-{
- MetaDrawSpec *spec;
-
- spec = g_slice_new0 (MetaDrawSpec);
-
- pos_tokenize (expr, &spec->tokens, &spec->n_tokens, NULL);
-
- spec->constant = meta_theme_replace_constants (theme, spec->tokens,
- spec->n_tokens, NULL);
- if (spec->constant)
- {
- gboolean result;
-
- result = pos_eval (spec, NULL, &spec->value, error);
- if (result == FALSE)
- {
- meta_draw_spec_free (spec);
- return NULL;
- }
- }
-
- return spec;
-}
-
-MetaDrawOp*
-meta_draw_op_new (MetaDrawType type)
-{
- MetaDrawOp *op;
- MetaDrawOp dummy;
- int size;
-
- size = G_STRUCT_OFFSET (MetaDrawOp, data);
-
- switch (type)
- {
- case META_DRAW_LINE:
- size += sizeof (dummy.data.line);
- break;
-
- case META_DRAW_RECTANGLE:
- size += sizeof (dummy.data.rectangle);
- break;
-
- case META_DRAW_ARC:
- size += sizeof (dummy.data.arc);
- break;
-
- case META_DRAW_CLIP:
- size += sizeof (dummy.data.clip);
- break;
-
- case META_DRAW_TINT:
- size += sizeof (dummy.data.tint);
- break;
-
- case META_DRAW_GRADIENT:
- size += sizeof (dummy.data.gradient);
- break;
-
- case META_DRAW_IMAGE:
- size += sizeof (dummy.data.image);
- break;
-
- case META_DRAW_GTK_ARROW:
- size += sizeof (dummy.data.gtk_arrow);
- break;
-
- case META_DRAW_GTK_BOX:
- size += sizeof (dummy.data.gtk_box);
- break;
-
- case META_DRAW_GTK_VLINE:
- size += sizeof (dummy.data.gtk_vline);
- break;
-
- case META_DRAW_ICON:
- size += sizeof (dummy.data.icon);
- break;
-
- case META_DRAW_TITLE:
- size += sizeof (dummy.data.title);
- break;
- case META_DRAW_OP_LIST:
- size += sizeof (dummy.data.op_list);
- break;
- case META_DRAW_TILE:
- size += sizeof (dummy.data.tile);
- break;
- }
-
- op = g_malloc0 (size);
-
- op->type = type;
-
- return op;
-}
-
-void
-meta_draw_op_free (MetaDrawOp *op)
-{
- g_return_if_fail (op != NULL);
-
- switch (op->type)
- {
- case META_DRAW_LINE:
- if (op->data.line.color_spec)
- meta_color_spec_free (op->data.line.color_spec);
-
- meta_draw_spec_free (op->data.line.x1);
- meta_draw_spec_free (op->data.line.y1);
- meta_draw_spec_free (op->data.line.x2);
- meta_draw_spec_free (op->data.line.y2);
- break;
-
- case META_DRAW_RECTANGLE:
- if (op->data.rectangle.color_spec)
- g_free (op->data.rectangle.color_spec);
-
- meta_draw_spec_free (op->data.rectangle.x);
- meta_draw_spec_free (op->data.rectangle.y);
- meta_draw_spec_free (op->data.rectangle.width);
- meta_draw_spec_free (op->data.rectangle.height);
- break;
-
- case META_DRAW_ARC:
- if (op->data.arc.color_spec)
- g_free (op->data.arc.color_spec);
-
- meta_draw_spec_free (op->data.arc.x);
- meta_draw_spec_free (op->data.arc.y);
- meta_draw_spec_free (op->data.arc.width);
- meta_draw_spec_free (op->data.arc.height);
- break;
-
- case META_DRAW_CLIP:
- meta_draw_spec_free (op->data.clip.x);
- meta_draw_spec_free (op->data.clip.y);
- meta_draw_spec_free (op->data.clip.width);
- meta_draw_spec_free (op->data.clip.height);
- break;
-
- case META_DRAW_TINT:
- if (op->data.tint.color_spec)
- meta_color_spec_free (op->data.tint.color_spec);
-
- if (op->data.tint.alpha_spec)
- meta_alpha_gradient_spec_free (op->data.tint.alpha_spec);
-
- meta_draw_spec_free (op->data.tint.x);
- meta_draw_spec_free (op->data.tint.y);
- meta_draw_spec_free (op->data.tint.width);
- meta_draw_spec_free (op->data.tint.height);
- break;
-
- case META_DRAW_GRADIENT:
- if (op->data.gradient.gradient_spec)
- meta_gradient_spec_free (op->data.gradient.gradient_spec);
-
- if (op->data.gradient.alpha_spec)
- meta_alpha_gradient_spec_free (op->data.gradient.alpha_spec);
-
- meta_draw_spec_free (op->data.gradient.x);
- meta_draw_spec_free (op->data.gradient.y);
- meta_draw_spec_free (op->data.gradient.width);
- meta_draw_spec_free (op->data.gradient.height);
- break;
-
- case META_DRAW_IMAGE:
- if (op->data.image.alpha_spec)
- meta_alpha_gradient_spec_free (op->data.image.alpha_spec);
-
- if (op->data.image.pixbuf)
- g_object_unref (G_OBJECT (op->data.image.pixbuf));
-
- if (op->data.image.colorize_spec)
- meta_color_spec_free (op->data.image.colorize_spec);
-
- if (op->data.image.colorize_cache_pixbuf)
- g_object_unref (G_OBJECT (op->data.image.colorize_cache_pixbuf));
-
- meta_draw_spec_free (op->data.image.x);
- meta_draw_spec_free (op->data.image.y);
- meta_draw_spec_free (op->data.image.width);
- meta_draw_spec_free (op->data.image.height);
- break;
-
- case META_DRAW_GTK_ARROW:
- meta_draw_spec_free (op->data.gtk_arrow.x);
- meta_draw_spec_free (op->data.gtk_arrow.y);
- meta_draw_spec_free (op->data.gtk_arrow.width);
- meta_draw_spec_free (op->data.gtk_arrow.height);
- break;
-
- case META_DRAW_GTK_BOX:
- meta_draw_spec_free (op->data.gtk_box.x);
- meta_draw_spec_free (op->data.gtk_box.y);
- meta_draw_spec_free (op->data.gtk_box.width);
- meta_draw_spec_free (op->data.gtk_box.height);
- break;
-
- case META_DRAW_GTK_VLINE:
- meta_draw_spec_free (op->data.gtk_vline.x);
- meta_draw_spec_free (op->data.gtk_vline.y1);
- meta_draw_spec_free (op->data.gtk_vline.y2);
- break;
-
- case META_DRAW_ICON:
- if (op->data.icon.alpha_spec)
- meta_alpha_gradient_spec_free (op->data.icon.alpha_spec);
-
- meta_draw_spec_free (op->data.icon.x);
- meta_draw_spec_free (op->data.icon.y);
- meta_draw_spec_free (op->data.icon.width);
- meta_draw_spec_free (op->data.icon.height);
- break;
-
- case META_DRAW_TITLE:
- if (op->data.title.color_spec)
- meta_color_spec_free (op->data.title.color_spec);
-
- meta_draw_spec_free (op->data.title.x);
- meta_draw_spec_free (op->data.title.y);
- break;
-
- case META_DRAW_OP_LIST:
- if (op->data.op_list.op_list)
- meta_draw_op_list_unref (op->data.op_list.op_list);
-
- meta_draw_spec_free (op->data.op_list.x);
- meta_draw_spec_free (op->data.op_list.y);
- meta_draw_spec_free (op->data.op_list.width);
- meta_draw_spec_free (op->data.op_list.height);
- break;
-
- case META_DRAW_TILE:
- if (op->data.tile.op_list)
- meta_draw_op_list_unref (op->data.tile.op_list);
-
- meta_draw_spec_free (op->data.tile.x);
- meta_draw_spec_free (op->data.tile.y);
- meta_draw_spec_free (op->data.tile.width);
- meta_draw_spec_free (op->data.tile.height);
- meta_draw_spec_free (op->data.tile.tile_xoffset);
- meta_draw_spec_free (op->data.tile.tile_yoffset);
- meta_draw_spec_free (op->data.tile.tile_width);
- meta_draw_spec_free (op->data.tile.tile_height);
- break;
- }
-
- g_free (op);
-}
-
-static GdkGC*
-get_gc_for_primitive (GtkWidget *widget,
- GdkDrawable *drawable,
- MetaColorSpec *color_spec,
- const GdkRectangle *clip,
- int line_width)
-{
- GdkGC *gc;
- GdkGCValues values;
- GdkColor color;
-
- meta_color_spec_render (color_spec, widget, &color);
-
- values.foreground = color;
-
- gdk_rgb_find_color (gdk_drawable_get_colormap (drawable),
- &values.foreground);
-
- values.line_width = line_width;
-
- gc = gdk_gc_new_with_values (drawable, &values,
- GDK_GC_FOREGROUND | GDK_GC_LINE_WIDTH);
-
- if (clip)
- gdk_gc_set_clip_rectangle (gc,
- (GdkRectangle*) clip); /* const cast */
-
- return gc;
-}
-
-static GdkPixbuf*
-apply_alpha (GdkPixbuf *pixbuf,
- MetaAlphaGradientSpec *spec,
- gboolean force_copy)
-{
- GdkPixbuf *new_pixbuf;
- gboolean needs_alpha;
-
- g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
-
- needs_alpha = spec && (spec->n_alphas > 1 ||
- spec->alphas[0] != 0xff);
-
- if (!needs_alpha)
- return pixbuf;
-
- if (!gdk_pixbuf_get_has_alpha (pixbuf))
- {
- new_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
- g_object_unref (G_OBJECT (pixbuf));
- pixbuf = new_pixbuf;
- }
- else if (force_copy)
- {
- new_pixbuf = gdk_pixbuf_copy (pixbuf);
- g_object_unref (G_OBJECT (pixbuf));
- pixbuf = new_pixbuf;
- }
-
- g_assert (gdk_pixbuf_get_has_alpha (pixbuf));
-
- meta_gradient_add_alpha (pixbuf, spec->alphas, spec->n_alphas, spec->type);
-
- return pixbuf;
-}
-
-static void
-render_pixbuf (GdkDrawable *drawable,
- const GdkRectangle *clip,
- GdkPixbuf *pixbuf,
- int x,
- int y)
-{
- /* grumble, render_to_drawable_alpha does not accept a clip
- * mask, so we have to go through some BS
- */
- /* FIXME once GTK 1.3.13 has been out a while we can use
- * render_to_drawable() which now does alpha with clip.
- *
- * Though the gdk_rectangle_intersect() check may be a useful
- * optimization anyway.
- */
- GdkRectangle pixbuf_rect;
- GdkRectangle draw_rect;
-
- pixbuf_rect.x = x;
- pixbuf_rect.y = y;
- pixbuf_rect.width = gdk_pixbuf_get_width (pixbuf);
- pixbuf_rect.height = gdk_pixbuf_get_height (pixbuf);
-
- if (clip)
- {
- if (!gdk_rectangle_intersect ((GdkRectangle*)clip,
- &pixbuf_rect, &draw_rect))
- return;
- }
- else
- {
- draw_rect = pixbuf_rect;
- }
-
- gdk_draw_pixbuf (drawable,
- NULL,
- pixbuf,
- draw_rect.x - pixbuf_rect.x,
- draw_rect.y - pixbuf_rect.y,
- draw_rect.x, draw_rect.y,
- draw_rect.width,
- draw_rect.height,
- GDK_RGB_DITHER_NORMAL,
- draw_rect.x - pixbuf_rect.x,
- draw_rect.y - pixbuf_rect.y);
-}
-
-static GdkPixbuf*
-pixbuf_tile (GdkPixbuf *tile,
- int width,
- int height)
-{
- GdkPixbuf *pixbuf;
- int tile_width;
- int tile_height;
- int i, j;
-
- tile_width = gdk_pixbuf_get_width (tile);
- tile_height = gdk_pixbuf_get_height (tile);
-
- pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
- gdk_pixbuf_get_has_alpha (tile),
- 8, width, height);
-
- i = 0;
- while (i < width)
- {
- j = 0;
- while (j < height)
- {
- int w, h;
-
- w = MIN (tile_width, width - i);
- h = MIN (tile_height, height - j);
-
- gdk_pixbuf_copy_area (tile,
- 0, 0,
- w, h,
- pixbuf,
- i, j);
-
- j += tile_height;
- }
-
- i += tile_width;
- }
-
- return pixbuf;
-}
-
-static GdkPixbuf *
-replicate_rows (GdkPixbuf *src,
- int src_x,
- int src_y,
- int width,
- int height)
-{
- unsigned int n_channels = gdk_pixbuf_get_n_channels (src);
- unsigned int src_rowstride = gdk_pixbuf_get_rowstride (src);
- unsigned char *pixels = (gdk_pixbuf_get_pixels (src) + src_y * src_rowstride + src_x
- * n_channels);
- unsigned char *dest_pixels;
- GdkPixbuf *result;
- unsigned int dest_rowstride;
- int i;
-
- result = gdk_pixbuf_new (GDK_COLORSPACE_RGB, n_channels == 4, 8,
- width, height);
- dest_rowstride = gdk_pixbuf_get_rowstride (result);
- dest_pixels = gdk_pixbuf_get_pixels (result);
-
- for (i = 0; i < height; i++)
- memcpy (dest_pixels + dest_rowstride * i, pixels, n_channels * width);
-
- return result;
-}
-
-static GdkPixbuf *
-replicate_cols (GdkPixbuf *src,
- int src_x,
- int src_y,
- int width,
- int height)
-{
- unsigned int n_channels = gdk_pixbuf_get_n_channels (src);
- unsigned int src_rowstride = gdk_pixbuf_get_rowstride (src);
- unsigned char *pixels = (gdk_pixbuf_get_pixels (src) + src_y * src_rowstride + src_x
- * n_channels);
- unsigned char *dest_pixels;
- GdkPixbuf *result;
- unsigned int dest_rowstride;
- int i, j;
-
- result = gdk_pixbuf_new (GDK_COLORSPACE_RGB, n_channels == 4, 8,
- width, height);
- dest_rowstride = gdk_pixbuf_get_rowstride (result);
- dest_pixels = gdk_pixbuf_get_pixels (result);
-
- for (i = 0; i < height; i++)
- {
- unsigned char *p = dest_pixels + dest_rowstride * i;
- unsigned char *q = pixels + src_rowstride * i;
-
- unsigned char r = *(q++);
- unsigned char g = *(q++);
- unsigned char b = *(q++);
-
- if (n_channels == 4)
- {
- unsigned char a;
-
- a = *(q++);
-
- for (j = 0; j < width; j++)
- {
- *(p++) = r;
- *(p++) = g;
- *(p++) = b;
- *(p++) = a;
- }
- }
- else
- {
- for (j = 0; j < width; j++)
- {
- *(p++) = r;
- *(p++) = g;
- *(p++) = b;
- }
- }
- }
-
- return result;
-}
-
-static GdkPixbuf*
-scale_and_alpha_pixbuf (GdkPixbuf *src,
- MetaAlphaGradientSpec *alpha_spec,
- MetaImageFillType fill_type,
- int width,
- int height,
- gboolean vertical_stripes,
- gboolean horizontal_stripes)
-{
- GdkPixbuf *pixbuf;
- GdkPixbuf *temp_pixbuf;
-
- pixbuf = NULL;
-
- pixbuf = src;
-
- if (gdk_pixbuf_get_width (pixbuf) == width &&
- gdk_pixbuf_get_height (pixbuf) == height)
- {
- g_object_ref (G_OBJECT (pixbuf));
- }
- else
- {
- if (fill_type == META_IMAGE_FILL_TILE)
- {
- pixbuf = pixbuf_tile (pixbuf, width, height);
- }
- else
- {
- int src_h, src_w, dest_h, dest_w;
- src_h = gdk_pixbuf_get_height (src);
- src_w = gdk_pixbuf_get_width (src);
-
- /* prefer to replicate_cols if possible, as that
- * is faster (no memory reads)
- */
- if (horizontal_stripes)
- {
- dest_w = gdk_pixbuf_get_width (src);
- dest_h = height;
- }
- else if (vertical_stripes)
- {
- dest_w = width;
- dest_h = gdk_pixbuf_get_height (src);
- }
-
- else
- {
- dest_w = width;
- dest_h = height;
- }
-
- if (dest_w == src_w && dest_h == src_h)
- {
- temp_pixbuf = src;
- g_object_ref (G_OBJECT (temp_pixbuf));
- }
- else
- {
- temp_pixbuf = gdk_pixbuf_scale_simple (src,
- dest_w, dest_h,
- GDK_INTERP_BILINEAR);
- }
-
- /* prefer to replicate_cols if possible, as that
- * is faster (no memory reads)
- */
- if (horizontal_stripes)
- {
- pixbuf = replicate_cols (temp_pixbuf, 0, 0, width, height);
- g_object_unref (G_OBJECT (temp_pixbuf));
- }
- else if (vertical_stripes)
- {
- pixbuf = replicate_rows (temp_pixbuf, 0, 0, width, height);
- g_object_unref (G_OBJECT (temp_pixbuf));
- }
- else
- {
- pixbuf = temp_pixbuf;
- }
- }
- }
-
- if (pixbuf)
- pixbuf = apply_alpha (pixbuf, alpha_spec, pixbuf == src);
-
- return pixbuf;
-}
-
-static GdkPixbuf*
-draw_op_as_pixbuf (const MetaDrawOp *op,
- GtkWidget *widget,
- const MetaDrawInfo *info,
- int width,
- int height)
-{
- /* Try to get the op as a pixbuf, assuming w/h in the op
- * matches the width/height passed in. return NULL
- * if the op can't be converted to an equivalent pixbuf.
- */
- GdkPixbuf *pixbuf;
-
- pixbuf = NULL;
-
- switch (op->type)
- {
- case META_DRAW_LINE:
- break;
-
- case META_DRAW_RECTANGLE:
- if (op->data.rectangle.filled)
- {
- GdkColor color;
-
- meta_color_spec_render (op->data.rectangle.color_spec,
- widget,
- &color);
-
- pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
- FALSE,
- 8, width, height);
-
- gdk_pixbuf_fill (pixbuf, GDK_COLOR_RGBA (color));
- }
- break;
-
- case META_DRAW_ARC:
- break;
-
- case META_DRAW_CLIP:
- break;
-
- case META_DRAW_TINT:
- {
- GdkColor color;
- guint32 rgba;
- gboolean has_alpha;
-
- meta_color_spec_render (op->data.rectangle.color_spec,
- widget,
- &color);
-
- has_alpha =
- op->data.tint.alpha_spec &&
- (op->data.tint.alpha_spec->n_alphas > 1 ||
- op->data.tint.alpha_spec->alphas[0] != 0xff);
-
- pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
- has_alpha,
- 8, width, height);
-
- if (!has_alpha)
- {
- rgba = GDK_COLOR_RGBA (color);
-
- gdk_pixbuf_fill (pixbuf, rgba);
- }
- else if (op->data.tint.alpha_spec->n_alphas == 1)
- {
- rgba = GDK_COLOR_RGBA (color);
- rgba &= ~0xff;
- rgba |= op->data.tint.alpha_spec->alphas[0];
-
- gdk_pixbuf_fill (pixbuf, rgba);
- }
- else
- {
- rgba = GDK_COLOR_RGBA (color);
-
- gdk_pixbuf_fill (pixbuf, rgba);
-
- meta_gradient_add_alpha (pixbuf,
- op->data.tint.alpha_spec->alphas,
- op->data.tint.alpha_spec->n_alphas,
- op->data.tint.alpha_spec->type);
- }
- }
- break;
-
- case META_DRAW_GRADIENT:
- {
- pixbuf = meta_gradient_spec_render (op->data.gradient.gradient_spec,
- widget, width, height);
-
- pixbuf = apply_alpha (pixbuf,
- op->data.gradient.alpha_spec,
- FALSE);
- }
- break;
-
-
- case META_DRAW_IMAGE:
- {
- if (op->data.image.colorize_spec)
- {
- GdkColor color;
-
- meta_color_spec_render (op->data.image.colorize_spec,
- widget, &color);
-
- if (op->data.image.colorize_cache_pixbuf == NULL ||
- op->data.image.colorize_cache_pixel != GDK_COLOR_RGB (color))
- {
- if (op->data.image.colorize_cache_pixbuf)
- g_object_unref (G_OBJECT (op->data.image.colorize_cache_pixbuf));
-
- /* const cast here */
- ((MetaDrawOp*)op)->data.image.colorize_cache_pixbuf =
- colorize_pixbuf (op->data.image.pixbuf,
- &color);
- ((MetaDrawOp*)op)->data.image.colorize_cache_pixel =
- GDK_COLOR_RGB (color);
- }
-
- if (op->data.image.colorize_cache_pixbuf)
- {
- pixbuf = scale_and_alpha_pixbuf (op->data.image.colorize_cache_pixbuf,
- op->data.image.alpha_spec,
- op->data.image.fill_type,
- width, height,
- op->data.image.vertical_stripes,
- op->data.image.horizontal_stripes);
- }
- }
- else
- {
- pixbuf = scale_and_alpha_pixbuf (op->data.image.pixbuf,
- op->data.image.alpha_spec,
- op->data.image.fill_type,
- width, height,
- op->data.image.vertical_stripes,
- op->data.image.horizontal_stripes);
- }
- break;
- }
-
- case META_DRAW_GTK_ARROW:
- case META_DRAW_GTK_BOX:
- case META_DRAW_GTK_VLINE:
- break;
-
- case META_DRAW_ICON:
- if (info->mini_icon &&
- width <= gdk_pixbuf_get_width (info->mini_icon) &&
- height <= gdk_pixbuf_get_height (info->mini_icon))
- pixbuf = scale_and_alpha_pixbuf (info->mini_icon,
- op->data.icon.alpha_spec,
- op->data.icon.fill_type,
- width, height,
- FALSE, FALSE);
- else if (info->icon)
- pixbuf = scale_and_alpha_pixbuf (info->icon,
- op->data.icon.alpha_spec,
- op->data.icon.fill_type,
- width, height,
- FALSE, FALSE);
- break;
-
- case META_DRAW_TITLE:
- break;
-
- case META_DRAW_OP_LIST:
- break;
-
- case META_DRAW_TILE:
- break;
- }
-
- return pixbuf;
-}
-
-static void
-fill_env (MetaPositionExprEnv *env,
- const MetaDrawInfo *info,
- MetaRectangle logical_region)
-{
- /* FIXME this stuff could be raised into draw_op_list_draw() probably
- */
- env->rect = logical_region;
- env->object_width = -1;
- env->object_height = -1;
- if (info->fgeom)
- {
- env->left_width = info->fgeom->left_width;
- env->right_width = info->fgeom->right_width;
- env->top_height = info->fgeom->top_height;
- env->bottom_height = info->fgeom->bottom_height;
- }
- else
- {
- env->left_width = 0;
- env->right_width = 0;
- env->top_height = 0;
- env->bottom_height = 0;
- }
-
- env->mini_icon_width = info->mini_icon ? gdk_pixbuf_get_width (info->mini_icon) : 0;
- env->mini_icon_height = info->mini_icon ? gdk_pixbuf_get_height (info->mini_icon) : 0;
- env->icon_width = info->icon ? gdk_pixbuf_get_width (info->icon) : 0;
- env->icon_height = info->icon ? gdk_pixbuf_get_height (info->icon) : 0;
-
- env->title_width = info->title_layout_width;
- env->title_height = info->title_layout_height;
- env->theme = meta_current_theme;
-}
-
-static void
-meta_draw_op_draw_with_env (const MetaDrawOp *op,
- GtkWidget *widget,
- GdkDrawable *drawable,
- const GdkRectangle *clip,
- const MetaDrawInfo *info,
- MetaRectangle rect,
- MetaPositionExprEnv *env)
-{
- GdkGC *gc;
-
- switch (op->type)
- {
- case META_DRAW_LINE:
- {
- int x1, x2, y1, y2;
-
- gc = get_gc_for_primitive (widget, drawable,
- op->data.line.color_spec,
- clip,
- op->data.line.width);
-
- if (op->data.line.dash_on_length > 0 &&
- op->data.line.dash_off_length > 0)
- {
- gint8 dash_list[2];
- dash_list[0] = op->data.line.dash_on_length;
- dash_list[1] = op->data.line.dash_off_length;
- gdk_gc_set_dashes (gc, 0, dash_list, 2);
- }
-
- x1 = parse_x_position_unchecked (op->data.line.x1, env);
- y1 = parse_y_position_unchecked (op->data.line.y1, env);
- x2 = parse_x_position_unchecked (op->data.line.x2, env);
- y2 = parse_y_position_unchecked (op->data.line.y2, env);
-
- gdk_draw_line (drawable, gc, x1, y1, x2, y2);
-
- g_object_unref (G_OBJECT (gc));
- }
- break;
-
- case META_DRAW_RECTANGLE:
- {
- int rx, ry, rwidth, rheight;
-
- gc = get_gc_for_primitive (widget, drawable,
- op->data.rectangle.color_spec,
- clip, 0);
-
- rx = parse_x_position_unchecked (op->data.rectangle.x, env);
- ry = parse_y_position_unchecked (op->data.rectangle.y, env);
- rwidth = parse_size_unchecked (op->data.rectangle.width, env);
- rheight = parse_size_unchecked (op->data.rectangle.height, env);
-
- gdk_draw_rectangle (drawable, gc,
- op->data.rectangle.filled,
- rx, ry, rwidth, rheight);
-
- g_object_unref (G_OBJECT (gc));
- }
- break;
-
- case META_DRAW_ARC:
- {
- int rx, ry, rwidth, rheight;
-
- gc = get_gc_for_primitive (widget, drawable,
- op->data.arc.color_spec,
- clip, 0);
-
- rx = parse_x_position_unchecked (op->data.arc.x, env);
- ry = parse_y_position_unchecked (op->data.arc.y, env);
- rwidth = parse_size_unchecked (op->data.arc.width, env);
- rheight = parse_size_unchecked (op->data.arc.height, env);
-
- gdk_draw_arc (drawable,
- gc,
- op->data.arc.filled,
- rx, ry, rwidth, rheight,
- op->data.arc.start_angle * (360.0 * 64.0) -
- (90.0 * 64.0), /* start at 12 instead of 3 oclock */
- op->data.arc.extent_angle * (360.0 * 64.0));
-
- g_object_unref (G_OBJECT (gc));
- }
- break;
-
- case META_DRAW_CLIP:
- break;
-
- case META_DRAW_TINT:
- {
- int rx, ry, rwidth, rheight;
- gboolean needs_alpha;
-
- needs_alpha = op->data.tint.alpha_spec &&
- (op->data.tint.alpha_spec->n_alphas > 1 ||
- op->data.tint.alpha_spec->alphas[0] != 0xff);
-
- rx = parse_x_position_unchecked (op->data.tint.x, env);
- ry = parse_y_position_unchecked (op->data.tint.y, env);
- rwidth = parse_size_unchecked (op->data.tint.width, env);
- rheight = parse_size_unchecked (op->data.tint.height, env);
-
- if (!needs_alpha)
- {
- gc = get_gc_for_primitive (widget, drawable,
- op->data.tint.color_spec,
- clip, 0);
-
- gdk_draw_rectangle (drawable, gc,
- TRUE,
- rx, ry, rwidth, rheight);
-
- g_object_unref (G_OBJECT (gc));
- }
- else
- {
- GdkPixbuf *pixbuf;
-
- pixbuf = draw_op_as_pixbuf (op, widget, info,
- rwidth, rheight);
-
- if (pixbuf)
- {
- render_pixbuf (drawable, clip, pixbuf, rx, ry);
-
- g_object_unref (G_OBJECT (pixbuf));
- }
- }
- }
- break;
-
- case META_DRAW_GRADIENT:
- {
- int rx, ry, rwidth, rheight;
- GdkPixbuf *pixbuf;
-
- rx = parse_x_position_unchecked (op->data.gradient.x, env);
- ry = parse_y_position_unchecked (op->data.gradient.y, env);
- rwidth = parse_size_unchecked (op->data.gradient.width, env);
- rheight = parse_size_unchecked (op->data.gradient.height, env);
-
- pixbuf = draw_op_as_pixbuf (op, widget, info,
- rwidth, rheight);
-
- if (pixbuf)
- {
- render_pixbuf (drawable, clip, pixbuf, rx, ry);
-
- g_object_unref (G_OBJECT (pixbuf));
- }
- }
- break;
-
- case META_DRAW_IMAGE:
- {
- int rx, ry, rwidth, rheight;
- GdkPixbuf *pixbuf;
-
- if (op->data.image.pixbuf)
- {
- env->object_width = gdk_pixbuf_get_width (op->data.image.pixbuf);
- env->object_height = gdk_pixbuf_get_height (op->data.image.pixbuf);
- }
-
- rwidth = parse_size_unchecked (op->data.image.width, env);
- rheight = parse_size_unchecked (op->data.image.height, env);
-
- pixbuf = draw_op_as_pixbuf (op, widget, info,
- rwidth, rheight);
-
- if (pixbuf)
- {
- rx = parse_x_position_unchecked (op->data.image.x, env);
- ry = parse_y_position_unchecked (op->data.image.y, env);
-
- render_pixbuf (drawable, clip, pixbuf, rx, ry);
-
- g_object_unref (G_OBJECT (pixbuf));
- }
- }
- break;
-
- case META_DRAW_GTK_ARROW:
- {
- int rx, ry, rwidth, rheight;
-
- rx = parse_x_position_unchecked (op->data.gtk_arrow.x, env);
- ry = parse_y_position_unchecked (op->data.gtk_arrow.y, env);
- rwidth = parse_size_unchecked (op->data.gtk_arrow.width, env);
- rheight = parse_size_unchecked (op->data.gtk_arrow.height, env);
-
- gtk_paint_arrow (widget->style,
- drawable,
- op->data.gtk_arrow.state,
- op->data.gtk_arrow.shadow,
- (GdkRectangle*) clip,
- widget,
- "metacity",
- op->data.gtk_arrow.arrow,
- op->data.gtk_arrow.filled,
- rx, ry, rwidth, rheight);
- }
- break;
-
- case META_DRAW_GTK_BOX:
- {
- int rx, ry, rwidth, rheight;
-
- rx = parse_x_position_unchecked (op->data.gtk_box.x, env);
- ry = parse_y_position_unchecked (op->data.gtk_box.y, env);
- rwidth = parse_size_unchecked (op->data.gtk_box.width, env);
- rheight = parse_size_unchecked (op->data.gtk_box.height, env);
-
- gtk_paint_box (widget->style,
- drawable,
- op->data.gtk_box.state,
- op->data.gtk_box.shadow,
- (GdkRectangle*) clip,
- widget,
- "metacity",
- rx, ry, rwidth, rheight);
- }
- break;
-
- case META_DRAW_GTK_VLINE:
- {
- int rx, ry1, ry2;
-
- rx = parse_x_position_unchecked (op->data.gtk_vline.x, env);
- ry1 = parse_y_position_unchecked (op->data.gtk_vline.y1, env);
- ry2 = parse_y_position_unchecked (op->data.gtk_vline.y2, env);
-
- gtk_paint_vline (widget->style,
- drawable,
- op->data.gtk_vline.state,
- (GdkRectangle*) clip,
- widget,
- "metacity",
- ry1, ry2, rx);
- }
- break;
-
- case META_DRAW_ICON:
- {
- int rx, ry, rwidth, rheight;
- GdkPixbuf *pixbuf;
-
- rwidth = parse_size_unchecked (op->data.icon.width, env);
- rheight = parse_size_unchecked (op->data.icon.height, env);
-
- pixbuf = draw_op_as_pixbuf (op, widget, info,
- rwidth, rheight);
-
- if (pixbuf)
- {
- rx = parse_x_position_unchecked (op->data.icon.x, env);
- ry = parse_y_position_unchecked (op->data.icon.y, env);
-
- render_pixbuf (drawable, clip, pixbuf, rx, ry);
-
- g_object_unref (G_OBJECT (pixbuf));
- }
- }
- break;
-
- case META_DRAW_TITLE:
- if (info->title_layout)
- {
- int rx, ry;
-
- gc = get_gc_for_primitive (widget, drawable,
- op->data.title.color_spec,
- clip, 0);
-
- rx = parse_x_position_unchecked (op->data.title.x, env);
- ry = parse_y_position_unchecked (op->data.title.y, env);
-
- gdk_draw_layout (drawable, gc,
- rx, ry,
- info->title_layout);
-
- g_object_unref (G_OBJECT (gc));
- }
- break;
-
- case META_DRAW_OP_LIST:
- {
- MetaRectangle d_rect;
-
- d_rect.x = parse_x_position_unchecked (op->data.op_list.x, env);
- d_rect.y = parse_y_position_unchecked (op->data.op_list.y, env);
- d_rect.width = parse_size_unchecked (op->data.op_list.width, env);
- d_rect.height = parse_size_unchecked (op->data.op_list.height, env);
-
- meta_draw_op_list_draw (op->data.op_list.op_list,
- widget, drawable, clip, info,
- d_rect);
- }
- break;
-
- case META_DRAW_TILE:
- {
- int rx, ry, rwidth, rheight;
- int tile_xoffset, tile_yoffset;
- GdkRectangle new_clip;
- MetaRectangle tile;
-
- rx = parse_x_position_unchecked (op->data.tile.x, env);
- ry = parse_y_position_unchecked (op->data.tile.y, env);
- rwidth = parse_size_unchecked (op->data.tile.width, env);
- rheight = parse_size_unchecked (op->data.tile.height, env);
-
- new_clip.x = rx;
- new_clip.y = ry;
- new_clip.width = rwidth;
- new_clip.height = rheight;
-
- if (clip == NULL || gdk_rectangle_intersect ((GdkRectangle*)clip, &new_clip,
- &new_clip))
- {
- tile_xoffset = parse_x_position_unchecked (op->data.tile.tile_xoffset, env);
- tile_yoffset = parse_y_position_unchecked (op->data.tile.tile_yoffset, env);
- /* tile offset should not include x/y */
- tile_xoffset -= rect.x;
- tile_yoffset -= rect.y;
-
- tile.width = parse_size_unchecked (op->data.tile.tile_width, env);
- tile.height = parse_size_unchecked (op->data.tile.tile_height, env);
-
- tile.x = rx - tile_xoffset;
-
- while (tile.x < (rx + rwidth))
- {
- tile.y = ry - tile_yoffset;
- while (tile.y < (ry + rheight))
- {
- meta_draw_op_list_draw (op->data.tile.op_list,
- widget, drawable, &new_clip, info,
- tile);
-
- tile.y += tile.height;
- }
-
- tile.x += tile.width;
- }
- }
- }
- break;
- }
-}
-
-void
-meta_draw_op_draw (const MetaDrawOp *op,
- GtkWidget *widget,
- GdkDrawable *drawable,
- const GdkRectangle *clip,
- const MetaDrawInfo *info,
- MetaRectangle logical_region)
-{
- MetaPositionExprEnv env;
-
- fill_env (&env, info, logical_region);
-
- meta_draw_op_draw_with_env (op, widget, drawable, clip,
- info, logical_region,
- &env);
-
-}
-
-MetaDrawOpList*
-meta_draw_op_list_new (int n_preallocs)
-{
- MetaDrawOpList *op_list;
-
- g_return_val_if_fail (n_preallocs >= 0, NULL);
-
- op_list = g_new (MetaDrawOpList, 1);
-
- op_list->refcount = 1;
- op_list->n_allocated = n_preallocs;
- op_list->ops = g_new (MetaDrawOp*, op_list->n_allocated);
- op_list->n_ops = 0;
-
- return op_list;
-}
-
-void
-meta_draw_op_list_ref (MetaDrawOpList *op_list)
-{
- g_return_if_fail (op_list != NULL);
-
- op_list->refcount += 1;
-}
-
-void
-meta_draw_op_list_unref (MetaDrawOpList *op_list)
-{
- g_return_if_fail (op_list != NULL);
- g_return_if_fail (op_list->refcount > 0);
-
- op_list->refcount -= 1;
-
- if (op_list->refcount == 0)
- {
- int i;
-
- for (i = 0; i < op_list->n_ops; i++)
- meta_draw_op_free (op_list->ops[i]);
-
- g_free (op_list->ops);
-
- DEBUG_FILL_STRUCT (op_list);
- g_free (op_list);
- }
-}
-
-void
-meta_draw_op_list_draw (const MetaDrawOpList *op_list,
- GtkWidget *widget,
- GdkDrawable *drawable,
- const GdkRectangle *clip,
- const MetaDrawInfo *info,
- MetaRectangle rect)
-{
- int i;
- GdkRectangle active_clip;
- GdkRectangle orig_clip;
- MetaPositionExprEnv env;
-
- if (op_list->n_ops == 0)
- return;
-
- fill_env (&env, info, rect);
-
- /* FIXME this can be optimized, potentially a lot, by
- * compressing multiple ops when possible. For example,
- * anything convertible to a pixbuf can be composited
- * client-side, and putting a color tint over a pixbuf
- * can be done without creating the solid-color pixbuf.
- *
- * To implement this my plan is to have the idea of a
- * compiled draw op (with the string expressions already
- * evaluated), we make an array of those, and then fold
- * adjacent items when possible.
- */
- if (clip)
- {
- orig_clip = *clip;
- }
- else
- {
- orig_clip.x = rect.x;
- orig_clip.y = rect.y;
- orig_clip.width = rect.width;
- orig_clip.height = rect.height;
- }
-
- active_clip = orig_clip;
-
- for (i = 0; i < op_list->n_ops; i++)
- {
- MetaDrawOp *op = op_list->ops[i];
-
- if (op->type == META_DRAW_CLIP)
- {
- active_clip.x = parse_x_position_unchecked (op->data.clip.x, &env);
- active_clip.y = parse_y_position_unchecked (op->data.clip.y, &env);
- active_clip.width = parse_size_unchecked (op->data.clip.width, &env);
- active_clip.height = parse_size_unchecked (op->data.clip.height, &env);
-
- gdk_rectangle_intersect (&orig_clip, &active_clip, &active_clip);
- }
- else if (active_clip.width > 0 &&
- active_clip.height > 0)
- {
- meta_draw_op_draw_with_env (op,
- widget, drawable, &active_clip, info,
- rect,
- &env);
- }
- }
-}
-
-void
-meta_draw_op_list_append (MetaDrawOpList *op_list,
- MetaDrawOp *op)
-{
- if (op_list->n_ops == op_list->n_allocated)
- {
- op_list->n_allocated *= 2;
- op_list->ops = g_renew (MetaDrawOp*, op_list->ops, op_list->n_allocated);
- }
-
- op_list->ops[op_list->n_ops] = op;
- op_list->n_ops += 1;
-}
-
-gboolean
-meta_draw_op_list_validate (MetaDrawOpList *op_list,
- GError **error)
-{
- g_return_val_if_fail (op_list != NULL, FALSE);
-
- /* empty lists are OK, nothing else to check really */
-
- return TRUE;
-}
-
-/* This is not done in validate, since we wouldn't know the name
- * of the list to report the error. It might be nice to
- * store names inside the list sometime.
- */
-gboolean
-meta_draw_op_list_contains (MetaDrawOpList *op_list,
- MetaDrawOpList *child)
-{
- int i;
-
- /* mmm, huge tree recursion */
-
- for (i = 0; i < op_list->n_ops; i++)
- {
- if (op_list->ops[i]->type == META_DRAW_OP_LIST)
- {
- if (op_list->ops[i]->data.op_list.op_list == child)
- return TRUE;
-
- if (meta_draw_op_list_contains (op_list->ops[i]->data.op_list.op_list,
- child))
- return TRUE;
- }
- else if (op_list->ops[i]->type == META_DRAW_TILE)
- {
- if (op_list->ops[i]->data.tile.op_list == child)
- return TRUE;
-
- if (meta_draw_op_list_contains (op_list->ops[i]->data.tile.op_list,
- child))
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/**
- * Constructor for a MetaFrameStyle.
- *
- * \param parent The parent style. Data not filled in here will be
- * looked for in the parent style, and in its parent
- * style, and so on.
- *
- * \return The newly-constructed style.
- */
-MetaFrameStyle*
-meta_frame_style_new (MetaFrameStyle *parent)
-{
- MetaFrameStyle *style;
-
- style = g_new0 (MetaFrameStyle, 1);
-
- style->refcount = 1;
-
- /* Default alpha is fully opaque */
- style->window_background_alpha = 255;
-
- style->parent = parent;
- if (parent)
- meta_frame_style_ref (parent);
-
- return style;
-}
-
-/**
- * Increases the reference count of a frame style.
- * If the style is NULL, this is a no-op.
- *
- * \param style The style.
- */
-void
-meta_frame_style_ref (MetaFrameStyle *style)
-{
- g_return_if_fail (style != NULL);
-
- style->refcount += 1;
-}
-
-static void
-free_button_ops (MetaDrawOpList *op_lists[META_BUTTON_TYPE_LAST][META_BUTTON_STATE_LAST])
-{
- int i, j;
-
- for (i = 0; i < META_BUTTON_TYPE_LAST; i++)
- for (j = 0; j < META_BUTTON_STATE_LAST; j++)
- if (op_lists[i][j])
- meta_draw_op_list_unref (op_lists[i][j]);
-}
-
-void
-meta_frame_style_unref (MetaFrameStyle *style)
-{
- g_return_if_fail (style != NULL);
- g_return_if_fail (style->refcount > 0);
-
- style->refcount -= 1;
-
- if (style->refcount == 0)
- {
- int i;
-
- free_button_ops (style->buttons);
-
- for (i = 0; i < META_FRAME_PIECE_LAST; i++)
- if (style->pieces[i])
- meta_draw_op_list_unref (style->pieces[i]);
-
- if (style->layout)
- meta_frame_layout_unref (style->layout);
-
- if (style->window_background_color)
- meta_color_spec_free (style->window_background_color);
-
- /* we hold a reference to any parent style */
- if (style->parent)
- meta_frame_style_unref (style->parent);
-
- DEBUG_FILL_STRUCT (style);
- g_free (style);
- }
-}
-
-static MetaDrawOpList*
-get_button (MetaFrameStyle *style,
- MetaButtonType type,
- MetaButtonState state)
-{
- MetaDrawOpList *op_list;
- MetaFrameStyle *parent;
-
- parent = style;
- op_list = NULL;
- while (parent && op_list == NULL)
- {
- op_list = parent->buttons[type][state];
- parent = parent->parent;
- }
-
- /* We fall back to middle button backgrounds if we don't
- * have the ones on the sides
- */
-
- if (op_list == NULL &&
- (type == META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND ||
- type == META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND))
- return get_button (style, META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND,
- state);
-
- if (op_list == NULL &&
- (type == META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND ||
- type == META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND))
- return get_button (style, META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND,
- state);
-
- /* We fall back to normal if no prelight */
- if (op_list == NULL &&
- state == META_BUTTON_STATE_PRELIGHT)
- return get_button (style, type, META_BUTTON_STATE_NORMAL);
-
- return op_list;
-}
-
-gboolean
-meta_frame_style_validate (MetaFrameStyle *style,
- guint current_theme_version,
- GError **error)
-{
- int i, j;
-
- g_return_val_if_fail (style != NULL, FALSE);
- g_return_val_if_fail (style->layout != NULL, FALSE);
-
- for (i = 0; i < META_BUTTON_TYPE_LAST; i++)
- {
- /* for now the "positional" buttons are optional */
- if (i >= META_BUTTON_TYPE_CLOSE)
- {
- for (j = 0; j < META_BUTTON_STATE_LAST; j++)
- {
- if (get_button (style, i, j) == NULL &&
- meta_theme_earliest_version_with_button (i) <= current_theme_version
- )
- {
- g_set_error (error, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be specified for this frame style"),
- meta_button_type_to_string (i),
- meta_button_state_to_string (j));
- return FALSE;
- }
- }
- }
- }
-
- return TRUE;
-}
-
-static void
-button_rect (MetaButtonType type,
- const MetaFrameGeometry *fgeom,
- int middle_background_offset,
- GdkRectangle *rect)
-{
- switch (type)
- {
- case META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND:
- *rect = fgeom->left_left_background;
- break;
-
- case META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND:
- *rect = fgeom->left_middle_backgrounds[middle_background_offset];
- break;
-
- case META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND:
- *rect = fgeom->left_right_background;
- break;
-
- case META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND:
- *rect = fgeom->right_left_background;
- break;
-
- case META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND:
- *rect = fgeom->right_middle_backgrounds[middle_background_offset];
- break;
-
- case META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND:
- *rect = fgeom->right_right_background;
- break;
-
- case META_BUTTON_TYPE_CLOSE:
- *rect = fgeom->close_rect.visible;
- break;
-
- case META_BUTTON_TYPE_SHADE:
- *rect = fgeom->shade_rect.visible;
- break;
-
- case META_BUTTON_TYPE_UNSHADE:
- *rect = fgeom->unshade_rect.visible;
- break;
-
- case META_BUTTON_TYPE_ABOVE:
- *rect = fgeom->above_rect.visible;
- break;
-
- case META_BUTTON_TYPE_UNABOVE:
- *rect = fgeom->unabove_rect.visible;
- break;
-
- case META_BUTTON_TYPE_STICK:
- *rect = fgeom->stick_rect.visible;
- break;
-
- case META_BUTTON_TYPE_UNSTICK:
- *rect = fgeom->unstick_rect.visible;
- break;
-
- case META_BUTTON_TYPE_MAXIMIZE:
- *rect = fgeom->max_rect.visible;
- break;
-
- case META_BUTTON_TYPE_MINIMIZE:
- *rect = fgeom->min_rect.visible;
- break;
-
- case META_BUTTON_TYPE_MENU:
- *rect = fgeom->menu_rect.visible;
- break;
-
- case META_BUTTON_TYPE_LAST:
- g_assert_not_reached ();
- break;
- }
-}
-
-void
-meta_frame_style_draw (MetaFrameStyle *style,
- GtkWidget *widget,
- GdkDrawable *drawable,
- int x_offset,
- int y_offset,
- const GdkRectangle *clip,
- const MetaFrameGeometry *fgeom,
- int client_width,
- int client_height,
- PangoLayout *title_layout,
- int text_height,
- MetaButtonState button_states[META_BUTTON_TYPE_LAST],
- GdkPixbuf *mini_icon,
- GdkPixbuf *icon)
-{
- int i, j;
- GdkRectangle titlebar_rect;
- GdkRectangle left_titlebar_edge;
- GdkRectangle right_titlebar_edge;
- GdkRectangle bottom_titlebar_edge;
- GdkRectangle top_titlebar_edge;
- GdkRectangle left_edge, right_edge, bottom_edge;
- PangoRectangle extents;
- MetaDrawInfo draw_info;
-
- titlebar_rect.x = 0;
- titlebar_rect.y = 0;
- titlebar_rect.width = fgeom->width;
- titlebar_rect.height = fgeom->top_height;
-
- left_titlebar_edge.x = titlebar_rect.x;
- left_titlebar_edge.y = titlebar_rect.y + fgeom->top_titlebar_edge;
- left_titlebar_edge.width = fgeom->left_titlebar_edge;
- left_titlebar_edge.height = titlebar_rect.height - fgeom->top_titlebar_edge - fgeom->bottom_titlebar_edge;
-
- right_titlebar_edge.y = left_titlebar_edge.y;
- right_titlebar_edge.height = left_titlebar_edge.height;
- right_titlebar_edge.width = fgeom->right_titlebar_edge;
- right_titlebar_edge.x = titlebar_rect.x + titlebar_rect.width - right_titlebar_edge.width;
-
- top_titlebar_edge.x = titlebar_rect.x;
- top_titlebar_edge.y = titlebar_rect.y;
- top_titlebar_edge.width = titlebar_rect.width;
- top_titlebar_edge.height = fgeom->top_titlebar_edge;
-
- bottom_titlebar_edge.x = titlebar_rect.x;
- bottom_titlebar_edge.width = titlebar_rect.width;
- bottom_titlebar_edge.height = fgeom->bottom_titlebar_edge;
- bottom_titlebar_edge.y = titlebar_rect.y + titlebar_rect.height - bottom_titlebar_edge.height;
-
- left_edge.x = 0;
- left_edge.y = fgeom->top_height;
- left_edge.width = fgeom->left_width;
- left_edge.height = fgeom->height - fgeom->top_height - fgeom->bottom_height;
-
- right_edge.x = fgeom->width - fgeom->right_width;
- right_edge.y = fgeom->top_height;
- right_edge.width = fgeom->right_width;
- right_edge.height = fgeom->height - fgeom->top_height - fgeom->bottom_height;
-
- bottom_edge.x = 0;
- bottom_edge.y = fgeom->height - fgeom->bottom_height;
- bottom_edge.width = fgeom->width;
- bottom_edge.height = fgeom->bottom_height;
-
- if (title_layout)
- pango_layout_get_pixel_extents (title_layout,
- NULL, &extents);
-
- draw_info.mini_icon = mini_icon;
- draw_info.icon = icon;
- draw_info.title_layout = title_layout;
- draw_info.title_layout_width = title_layout ? extents.width : 0;
- draw_info.title_layout_height = title_layout ? extents.height : 0;
- draw_info.fgeom = fgeom;
-
- /* The enum is in the order the pieces should be rendered. */
- i = 0;
- while (i < META_FRAME_PIECE_LAST)
- {
- GdkRectangle rect;
- GdkRectangle combined_clip;
-
- switch ((MetaFramePiece) i)
- {
- case META_FRAME_PIECE_ENTIRE_BACKGROUND:
- rect.x = 0;
- rect.y = 0;
- rect.width = fgeom->width;
- rect.height = fgeom->height;
- break;
-
- case META_FRAME_PIECE_TITLEBAR:
- rect = titlebar_rect;
- break;
-
- case META_FRAME_PIECE_LEFT_TITLEBAR_EDGE:
- rect = left_titlebar_edge;
- break;
-
- case META_FRAME_PIECE_RIGHT_TITLEBAR_EDGE:
- rect = right_titlebar_edge;
- break;
-
- case META_FRAME_PIECE_TOP_TITLEBAR_EDGE:
- rect = top_titlebar_edge;
- break;
-
- case META_FRAME_PIECE_BOTTOM_TITLEBAR_EDGE:
- rect = bottom_titlebar_edge;
- break;
-
- case META_FRAME_PIECE_TITLEBAR_MIDDLE:
- rect.x = left_titlebar_edge.x + left_titlebar_edge.width;
- rect.y = top_titlebar_edge.y + top_titlebar_edge.height;
- rect.width = titlebar_rect.width - left_titlebar_edge.width -
- right_titlebar_edge.width;
- rect.height = titlebar_rect.height - top_titlebar_edge.height - bottom_titlebar_edge.height;
- break;
-
- case META_FRAME_PIECE_TITLE:
- rect = fgeom->title_rect;
- break;
-
- case META_FRAME_PIECE_LEFT_EDGE:
- rect = left_edge;
- break;
-
- case META_FRAME_PIECE_RIGHT_EDGE:
- rect = right_edge;
- break;
-
- case META_FRAME_PIECE_BOTTOM_EDGE:
- rect = bottom_edge;
- break;
-
- case META_FRAME_PIECE_OVERLAY:
- rect.x = 0;
- rect.y = 0;
- rect.width = fgeom->width;
- rect.height = fgeom->height;
- break;
-
- case META_FRAME_PIECE_LAST:
- g_assert_not_reached ();
- break;
- }
-
- rect.x += x_offset;
- rect.y += y_offset;
-
- if (clip == NULL)
- combined_clip = rect;
- else
- gdk_rectangle_intersect ((GdkRectangle*) clip, /* const cast */
- &rect,
- &combined_clip);
-
- if (combined_clip.width > 0 && combined_clip.height > 0)
- {
- MetaDrawOpList *op_list;
- MetaFrameStyle *parent;
-
- parent = style;
- op_list = NULL;
- while (parent && op_list == NULL)
- {
- op_list = parent->pieces[i];
- parent = parent->parent;
- }
-
- if (op_list)
- {
- MetaRectangle m_rect;
- m_rect = meta_rect (rect.x, rect.y, rect.width, rect.height);
- meta_draw_op_list_draw (op_list,
- widget,
- drawable,
- &combined_clip,
- &draw_info,
- m_rect);
- }
- }
-
-
- /* Draw buttons just before overlay */
- if ((i + 1) == META_FRAME_PIECE_OVERLAY)
- {
- int middle_bg_offset;
-
- middle_bg_offset = 0;
- j = 0;
- while (j < META_BUTTON_TYPE_LAST)
- {
- button_rect (j, fgeom, middle_bg_offset, &rect);
-
- rect.x += x_offset;
- rect.y += y_offset;
-
- if (clip == NULL)
- combined_clip = rect;
- else
- gdk_rectangle_intersect ((GdkRectangle*) clip, /* const cast */
- &rect,
- &combined_clip);
-
- if (combined_clip.width > 0 && combined_clip.height > 0)
- {
- MetaDrawOpList *op_list;
-
- op_list = get_button (style, j, button_states[j]);
-
- if (op_list)
- {
- MetaRectangle m_rect;
- m_rect = meta_rect (rect.x, rect.y,
- rect.width, rect.height);
- meta_draw_op_list_draw (op_list,
- widget,
- drawable,
- &combined_clip,
- &draw_info,
- m_rect);
- }
- }
-
- /* MIDDLE_BACKGROUND type may get drawn more than once */
- if ((j == META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND ||
- j == META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND) &&
- middle_bg_offset < MAX_MIDDLE_BACKGROUNDS)
- {
- ++middle_bg_offset;
- }
- else
- {
- middle_bg_offset = 0;
- ++j;
- }
- }
- }
-
- ++i;
- }
-}
-
-MetaFrameStyleSet*
-meta_frame_style_set_new (MetaFrameStyleSet *parent)
-{
- MetaFrameStyleSet *style_set;
-
- style_set = g_new0 (MetaFrameStyleSet, 1);
-
- style_set->parent = parent;
- if (parent)
- meta_frame_style_set_ref (parent);
-
- style_set->refcount = 1;
-
- return style_set;
-}
-
-static void
-free_focus_styles (MetaFrameStyle *focus_styles[META_FRAME_FOCUS_LAST])
-{
- int i;
-
- for (i = 0; i < META_FRAME_FOCUS_LAST; i++)
- if (focus_styles[i])
- meta_frame_style_unref (focus_styles[i]);
-}
-
-void
-meta_frame_style_set_ref (MetaFrameStyleSet *style_set)
-{
- g_return_if_fail (style_set != NULL);
-
- style_set->refcount += 1;
-}
-
-void
-meta_frame_style_set_unref (MetaFrameStyleSet *style_set)
-{
- g_return_if_fail (style_set != NULL);
- g_return_if_fail (style_set->refcount > 0);
-
- style_set->refcount -= 1;
-
- if (style_set->refcount == 0)
- {
- int i;
-
- for (i = 0; i < META_FRAME_RESIZE_LAST; i++)
- {
- free_focus_styles (style_set->normal_styles[i]);
- free_focus_styles (style_set->shaded_styles[i]);
- }
-
- free_focus_styles (style_set->maximized_styles);
- free_focus_styles (style_set->maximized_and_shaded_styles);
-
- if (style_set->parent)
- meta_frame_style_set_unref (style_set->parent);
-
- DEBUG_FILL_STRUCT (style_set);
- g_free (style_set);
- }
-}
-
-
-static MetaFrameStyle*
-get_style (MetaFrameStyleSet *style_set,
- MetaFrameState state,
- MetaFrameResize resize,
- MetaFrameFocus focus)
-{
- MetaFrameStyle *style;
-
- style = NULL;
-
- switch (state)
- {
- case META_FRAME_STATE_NORMAL:
- case META_FRAME_STATE_SHADED:
- {
- if (state == META_FRAME_STATE_SHADED)
- style = style_set->shaded_styles[resize][focus];
- else
- style = style_set->normal_styles[resize][focus];
-
- /* Try parent if we failed here */
- if (style == NULL && style_set->parent)
- style = get_style (style_set->parent, state, resize, focus);
-
- /* Allow people to omit the vert/horz/none resize modes */
- if (style == NULL &&
- resize != META_FRAME_RESIZE_BOTH)
- style = get_style (style_set, state, META_FRAME_RESIZE_BOTH, focus);
- }
- break;
- default:
- {
- MetaFrameStyle **styles;
-
- styles = NULL;
-
- switch (state)
- {
- case META_FRAME_STATE_MAXIMIZED:
- styles = style_set->maximized_styles;
- break;
- case META_FRAME_STATE_MAXIMIZED_AND_SHADED:
- styles = style_set->maximized_and_shaded_styles;
- break;
- case META_FRAME_STATE_NORMAL:
- case META_FRAME_STATE_SHADED:
- case META_FRAME_STATE_LAST:
- g_assert_not_reached ();
- break;
- }
-
- style = styles[focus];
-
- /* Try parent if we failed here */
- if (style == NULL && style_set->parent)
- style = get_style (style_set->parent, state, resize, focus);
- }
- }
-
- return style;
-}
-
-static gboolean
-check_state (MetaFrameStyleSet *style_set,
- MetaFrameState state,
- GError **error)
-{
- int i;
-
- for (i = 0; i < META_FRAME_FOCUS_LAST; i++)
- {
- if (get_style (style_set, state,
- META_FRAME_RESIZE_NONE, i) == NULL)
- {
- /* Translators: This error occurs when a <frame> tag is missing
- * in theme XML. The "<frame ...>" is intended as a noun phrase,
- * and the "missing" qualifies it. You should translate "whatever".
- */
- g_set_error (error, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"),
- meta_frame_state_to_string (state),
- meta_frame_resize_to_string (META_FRAME_RESIZE_NONE),
- meta_frame_focus_to_string (i));
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-gboolean
-meta_frame_style_set_validate (MetaFrameStyleSet *style_set,
- GError **error)
-{
- int i, j;
-
- g_return_val_if_fail (style_set != NULL, FALSE);
-
- for (i = 0; i < META_FRAME_RESIZE_LAST; i++)
- for (j = 0; j < META_FRAME_FOCUS_LAST; j++)
- if (get_style (style_set, META_FRAME_STATE_NORMAL, i, j) == NULL)
- {
- g_set_error (error, META_THEME_ERROR,
- META_THEME_ERROR_FAILED,
- _("Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"),
- meta_frame_state_to_string (META_FRAME_STATE_NORMAL),
- meta_frame_resize_to_string (i),
- meta_frame_focus_to_string (j));
- return FALSE;
- }
-
- if (!check_state (style_set, META_FRAME_STATE_SHADED, error))
- return FALSE;
-
- if (!check_state (style_set, META_FRAME_STATE_MAXIMIZED, error))
- return FALSE;
-
- if (!check_state (style_set, META_FRAME_STATE_MAXIMIZED_AND_SHADED, error))
- return FALSE;
-
- return TRUE;
-}
-
-MetaTheme*
-meta_theme_get_current (void)
-{
- return meta_current_theme;
-}
-
-void
-meta_theme_set_current (const char *name,
- gboolean force_reload)
-{
- MetaTheme *new_theme;
- GError *err;
-
- meta_topic (META_DEBUG_THEMES, "Setting current theme to \"%s\"\n", name);
-
- if (!force_reload &&
- meta_current_theme &&
- strcmp (name, meta_current_theme->name) == 0)
- return;
-
- err = NULL;
- new_theme = meta_theme_load (name, &err);
-
- if (new_theme == NULL)
- {
- meta_warning (_("Failed to load theme \"%s\": %s\n"),
- name, err->message);
- g_error_free (err);
- }
- else
- {
- if (meta_current_theme)
- meta_theme_free (meta_current_theme);
-
- meta_current_theme = new_theme;
-
- meta_topic (META_DEBUG_THEMES, "New theme is \"%s\"\n", meta_current_theme->name);
- }
-}
-
-MetaTheme*
-meta_theme_new (void)
-{
- MetaTheme *theme;
-
- theme = g_new0 (MetaTheme, 1);
-
- theme->images_by_filename =
- g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- (GDestroyNotify) g_object_unref);
-
- theme->layouts_by_name =
- g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- (GDestroyNotify) meta_frame_layout_unref);
-
- theme->draw_op_lists_by_name =
- g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- (GDestroyNotify) meta_draw_op_list_unref);
-
- theme->styles_by_name =
- g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- (GDestroyNotify) meta_frame_style_unref);
-
- theme->style_sets_by_name =
- g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- (GDestroyNotify) meta_frame_style_set_unref);
-
- /* Create our variable quarks so we can look up variables without
- having to strcmp for the names */
- theme->quark_width = g_quark_from_static_string ("width");
- theme->quark_height = g_quark_from_static_string ("height");
- theme->quark_object_width = g_quark_from_static_string ("object_width");
- theme->quark_object_height = g_quark_from_static_string ("object_height");
- theme->quark_left_width = g_quark_from_static_string ("left_width");
- theme->quark_right_width = g_quark_from_static_string ("right_width");
- theme->quark_top_height = g_quark_from_static_string ("top_height");
- theme->quark_bottom_height = g_quark_from_static_string ("bottom_height");
- theme->quark_mini_icon_width = g_quark_from_static_string ("mini_icon_width");
- theme->quark_mini_icon_height = g_quark_from_static_string ("mini_icon_height");
- theme->quark_icon_width = g_quark_from_static_string ("icon_width");
- theme->quark_icon_height = g_quark_from_static_string ("icon_height");
- theme->quark_title_width = g_quark_from_static_string ("title_width");
- theme->quark_title_height = g_quark_from_static_string ("title_height");
- return theme;
-}
-
-
-void
-meta_theme_free (MetaTheme *theme)
-{
- int i;
-
- g_return_if_fail (theme != NULL);
-
- g_free (theme->name);
- g_free (theme->dirname);
- g_free (theme->filename);
- g_free (theme->readable_name);
- g_free (theme->date);
- g_free (theme->description);
- g_free (theme->author);
- g_free (theme->copyright);
-
- /* be more careful when destroying the theme hash tables,
- since they are only constructed as needed, and may be NULL. */
- if (theme->integer_constants)
- g_hash_table_destroy (theme->integer_constants);
- if (theme->images_by_filename)
- g_hash_table_destroy (theme->images_by_filename);
- if (theme->layouts_by_name)
- g_hash_table_destroy (theme->layouts_by_name);
- if (theme->draw_op_lists_by_name)
- g_hash_table_destroy (theme->draw_op_lists_by_name);
- if (theme->styles_by_name)
- g_hash_table_destroy (theme->styles_by_name);
- if (theme->style_sets_by_name)
- g_hash_table_destroy (theme->style_sets_by_name);
-
- for (i = 0; i < META_FRAME_TYPE_LAST; i++)
- if (theme->style_sets_by_type[i])
- meta_frame_style_set_unref (theme->style_sets_by_type[i]);
-
- DEBUG_FILL_STRUCT (theme);
- g_free (theme);
-}
-
-gboolean
-meta_theme_validate (MetaTheme *theme,
- GError **error)
-{
- int i;
-
- g_return_val_if_fail (theme != NULL, FALSE);
-
- /* FIXME what else should be checked? */
-
- g_assert (theme->name);
-
- if (theme->readable_name == NULL)
- {
- /* Translators: This error means that a necessary XML tag (whose name
- * is given in angle brackets) was not found in a given theme (whose
- * name is given second, in quotation marks).
- */
- g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
- _("No <%s> set for theme \"%s\""), "name", theme->name);
- return FALSE;
- }
-
- if (theme->author == NULL)
- {
- g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
- _("No <%s> set for theme \"%s\""), "author", theme->name);
- return FALSE;
- }
-
- if (theme->date == NULL)
- {
- g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
- _("No <%s> set for theme \"%s\""), "date", theme->name);
- return FALSE;
- }
-
- if (theme->description == NULL)
- {
- g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
- _("No <%s> set for theme \"%s\""), "description", theme->name);
- return FALSE;
- }
-
- if (theme->copyright == NULL)
- {
- g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
- _("No <%s> set for theme \"%s\""), "copyright", theme->name);
- return FALSE;
- }
-
- for (i = 0; i < (int)META_FRAME_TYPE_LAST; i++)
- if (theme->style_sets_by_type[i] == NULL)
- {
- g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
- _("No frame style set for window type \"%s\" in theme \"%s\", add a <window type=\"%s\" style_set=\"whatever\"/> element"),
- meta_frame_type_to_string (i),
- theme->name,
- meta_frame_type_to_string (i));
-
- return FALSE;
- }
-
- return TRUE;
-}
-
-GdkPixbuf*
-meta_theme_load_image (MetaTheme *theme,
- const char *filename,
- guint size_of_theme_icons,
- GError **error)
-{
- GdkPixbuf *pixbuf;
-
- pixbuf = g_hash_table_lookup (theme->images_by_filename,
- filename);
-
- if (pixbuf == NULL)
- {
-
- if (g_str_has_prefix (filename, "theme:") &&
- META_THEME_ALLOWS (theme, META_THEME_IMAGES_FROM_ICON_THEMES))
- {
- pixbuf = gtk_icon_theme_load_icon (
- gtk_icon_theme_get_default (),
- filename+6,
- size_of_theme_icons,
- 0,
- error);
- if (pixbuf == NULL) return NULL;
- }
- else
- {
- char *full_path;
- full_path = g_build_filename (theme->dirname, filename, NULL);
-
- pixbuf = gdk_pixbuf_new_from_file (full_path, error);
- if (pixbuf == NULL)
- {
- g_free (full_path);
- return NULL;
- }
-
- g_free (full_path);
- }
- g_hash_table_replace (theme->images_by_filename,
- g_strdup (filename),
- pixbuf);
- }
-
- g_assert (pixbuf);
-
- g_object_ref (G_OBJECT (pixbuf));
-
- return pixbuf;
-}
-
-static MetaFrameStyle*
-theme_get_style (MetaTheme *theme,
- MetaFrameType type,
- MetaFrameFlags flags)
-{
- MetaFrameState state;
- MetaFrameResize resize;
- MetaFrameFocus focus;
- MetaFrameStyle *style;
- MetaFrameStyleSet *style_set;
-
- style_set = theme->style_sets_by_type[type];
-
- /* Right now the parser forces a style set for all types,
- * but this fallback code is here in case I take that out.
- */
- if (style_set == NULL)
- style_set = theme->style_sets_by_type[META_FRAME_TYPE_NORMAL];
- if (style_set == NULL)
- return NULL;
-
- switch (flags & (META_FRAME_MAXIMIZED | META_FRAME_SHADED))
- {
- case 0:
- state = META_FRAME_STATE_NORMAL;
- break;
- case META_FRAME_MAXIMIZED:
- state = META_FRAME_STATE_MAXIMIZED;
- break;
- case META_FRAME_SHADED:
- state = META_FRAME_STATE_SHADED;
- break;
- case (META_FRAME_MAXIMIZED | META_FRAME_SHADED):
- state = META_FRAME_STATE_MAXIMIZED_AND_SHADED;
- break;
- default:
- g_assert_not_reached ();
- state = META_FRAME_STATE_LAST; /* compiler */
- break;
- }
-
- switch (flags & (META_FRAME_ALLOWS_VERTICAL_RESIZE | META_FRAME_ALLOWS_HORIZONTAL_RESIZE))
- {
- case 0:
- resize = META_FRAME_RESIZE_NONE;
- break;
- case META_FRAME_ALLOWS_VERTICAL_RESIZE:
- resize = META_FRAME_RESIZE_VERTICAL;
- break;
- case META_FRAME_ALLOWS_HORIZONTAL_RESIZE:
- resize = META_FRAME_RESIZE_HORIZONTAL;
- break;
- case (META_FRAME_ALLOWS_VERTICAL_RESIZE | META_FRAME_ALLOWS_HORIZONTAL_RESIZE):
- resize = META_FRAME_RESIZE_BOTH;
- break;
- default:
- g_assert_not_reached ();
- resize = META_FRAME_RESIZE_LAST; /* compiler */
- break;
- }
-
- /* re invert the styles used for focus/unfocussed while flashing a frame */
- if (((flags & META_FRAME_HAS_FOCUS) && !(flags & META_FRAME_IS_FLASHING))
- || (!(flags & META_FRAME_HAS_FOCUS) && (flags & META_FRAME_IS_FLASHING)))
- focus = META_FRAME_FOCUS_YES;
- else
- focus = META_FRAME_FOCUS_NO;
-
- style = get_style (style_set, state, resize, focus);
-
- return style;
-}
-
-MetaFrameStyle*
-meta_theme_get_frame_style (MetaTheme *theme,
- MetaFrameType type,
- MetaFrameFlags flags)
-{
- MetaFrameStyle *style;
-
- g_return_val_if_fail (type < META_FRAME_TYPE_LAST, NULL);
-
- style = theme_get_style (theme, type, flags);
-
- return style;
-}
-
-double
-meta_theme_get_title_scale (MetaTheme *theme,
- MetaFrameType type,
- MetaFrameFlags flags)
-{
- MetaFrameStyle *style;
-
- g_return_val_if_fail (type < META_FRAME_TYPE_LAST, 1.0);
-
- style = theme_get_style (theme, type, flags);
-
- /* Parser is not supposed to allow this currently */
- if (style == NULL)
- return 1.0;
-
- return style->layout->title_scale;
-}
-
-void
-meta_theme_draw_frame (MetaTheme *theme,
- GtkWidget *widget,
- GdkDrawable *drawable,
- const GdkRectangle *clip,
- int x_offset,
- int y_offset,
- MetaFrameType type,
- MetaFrameFlags flags,
- int client_width,
- int client_height,
- PangoLayout *title_layout,
- int text_height,
- const MetaButtonLayout *button_layout,
- MetaButtonState button_states[META_BUTTON_TYPE_LAST],
- GdkPixbuf *mini_icon,
- GdkPixbuf *icon)
-{
- MetaFrameGeometry fgeom;
- MetaFrameStyle *style;
-
- g_return_if_fail (type < META_FRAME_TYPE_LAST);
-
- style = theme_get_style (theme, type, flags);
-
- /* Parser is not supposed to allow this currently */
- if (style == NULL)
- return;
-
- meta_frame_layout_calc_geometry (style->layout,
- text_height,
- flags,
- client_width, client_height,
- button_layout,
- &fgeom,
- theme);
-
- meta_frame_style_draw (style,
- widget,
- drawable,
- x_offset, y_offset,
- clip,
- &fgeom,
- client_width, client_height,
- title_layout,
- text_height,
- button_states,
- mini_icon, icon);
-}
-
-void
-meta_theme_draw_frame_by_name (MetaTheme *theme,
- GtkWidget *widget,
- GdkDrawable *drawable,
- const GdkRectangle *clip,
- int x_offset,
- int y_offset,
- const gchar *style_name,
- MetaFrameFlags flags,
- int client_width,
- int client_height,
- PangoLayout *title_layout,
- int text_height,
- const MetaButtonLayout *button_layout,
- MetaButtonState button_states[META_BUTTON_TYPE_LAST],
- GdkPixbuf *mini_icon,
- GdkPixbuf *icon)
-{
- MetaFrameGeometry fgeom;
- MetaFrameStyle *style;
-
- style = meta_theme_lookup_style (theme, style_name);
-
- /* Parser is not supposed to allow this currently */
- if (style == NULL)
- return;
-
- meta_frame_layout_calc_geometry (style->layout,
- text_height,
- flags,
- client_width, client_height,
- button_layout,
- &fgeom,
- theme);
-
- meta_frame_style_draw (style,
- widget,
- drawable,
- x_offset, y_offset,
- clip,
- &fgeom,
- client_width, client_height,
- title_layout,
- text_height,
- button_states,
- mini_icon, icon);
-}
-
-
-
-
-
-
-
-
-
-
-
-void
-meta_theme_get_frame_borders (MetaTheme *theme,
- MetaFrameType type,
- int text_height,
- MetaFrameFlags flags,
- int *top_height,
- int *bottom_height,
- int *left_width,
- int *right_width)
-{
- MetaFrameStyle *style;
-
- g_return_if_fail (type < META_FRAME_TYPE_LAST);
-
- if (top_height)
- *top_height = 0;
- if (bottom_height)
- *bottom_height = 0;
- if (left_width)
- *left_width = 0;
- if (right_width)
- *right_width = 0;
-
- style = theme_get_style (theme, type, flags);
-
- /* Parser is not supposed to allow this currently */
- if (style == NULL)
- return;
-
- meta_frame_layout_get_borders (style->layout,
- text_height,
- flags,
- top_height, bottom_height,
- left_width, right_width);
-}
-
-void
-meta_theme_calc_geometry (MetaTheme *theme,
- MetaFrameType type,
- int text_height,
- MetaFrameFlags flags,
- int client_width,
- int client_height,
- const MetaButtonLayout *button_layout,
- MetaFrameGeometry *fgeom)
-{
- MetaFrameStyle *style;
-
- g_return_if_fail (type < META_FRAME_TYPE_LAST);
-
- style = theme_get_style (theme, type, flags);
-
- /* Parser is not supposed to allow this currently */
- if (style == NULL)
- return;
-
- meta_frame_layout_calc_geometry (style->layout,
- text_height,
- flags,
- client_width, client_height,
- button_layout,
- fgeom,
- theme);
-}
-
-MetaFrameLayout*
-meta_theme_lookup_layout (MetaTheme *theme,
- const char *name)
-{
- return g_hash_table_lookup (theme->layouts_by_name, name);
-}
-
-void
-meta_theme_insert_layout (MetaTheme *theme,
- const char *name,
- MetaFrameLayout *layout)
-{
- meta_frame_layout_ref (layout);
- g_hash_table_replace (theme->layouts_by_name, g_strdup (name), layout);
-}
-
-MetaDrawOpList*
-meta_theme_lookup_draw_op_list (MetaTheme *theme,
- const char *name)
-{
- return g_hash_table_lookup (theme->draw_op_lists_by_name, name);
-}
-
-void
-meta_theme_insert_draw_op_list (MetaTheme *theme,
- const char *name,
- MetaDrawOpList *op_list)
-{
- meta_draw_op_list_ref (op_list);
- g_hash_table_replace (theme->draw_op_lists_by_name, g_strdup (name), op_list);
-}
-
-MetaFrameStyle*
-meta_theme_lookup_style (MetaTheme *theme,
- const char *name)
-{
- return g_hash_table_lookup (theme->styles_by_name, name);
-}
-
-void
-meta_theme_insert_style (MetaTheme *theme,
- const char *name,
- MetaFrameStyle *style)
-{
- meta_frame_style_ref (style);
- g_hash_table_replace (theme->styles_by_name, g_strdup (name), style);
-}
-
-MetaFrameStyleSet*
-meta_theme_lookup_style_set (MetaTheme *theme,
- const char *name)
-{
- return g_hash_table_lookup (theme->style_sets_by_name, name);
-}
-
-void
-meta_theme_insert_style_set (MetaTheme *theme,
- const char *name,
- MetaFrameStyleSet *style_set)
-{
- meta_frame_style_set_ref (style_set);
- g_hash_table_replace (theme->style_sets_by_name, g_strdup (name), style_set);
-}
-
-static gboolean
-first_uppercase (const char *str)
-{
- return g_ascii_isupper (*str);
-}
-
-gboolean
-meta_theme_define_int_constant (MetaTheme *theme,
- const char *name,
- int value,
- GError **error)
-{
- if (theme->integer_constants == NULL)
- theme->integer_constants = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- NULL);
-
- if (!first_uppercase (name))
- {
- g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
- _("User-defined constants must begin with a capital letter; \"%s\" does not"),
- name);
- return FALSE;
- }
-
- if (g_hash_table_lookup_extended (theme->integer_constants, name, NULL, NULL))
- {
- g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
- _("Constant \"%s\" has already been defined"),
- name);
-
- return FALSE;
- }
-
- g_hash_table_insert (theme->integer_constants,
- g_strdup (name),
- GINT_TO_POINTER (value));
-
- return TRUE;
-}
-
-gboolean
-meta_theme_lookup_int_constant (MetaTheme *theme,
- const char *name,
- int *value)
-{
- gpointer old_value;
-
- *value = 0;
-
- if (theme->integer_constants == NULL)
- return FALSE;
-
- if (g_hash_table_lookup_extended (theme->integer_constants,
- name, NULL, &old_value))
- {
- *value = GPOINTER_TO_INT (old_value);
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-gboolean
-meta_theme_define_float_constant (MetaTheme *theme,
- const char *name,
- double value,
- GError **error)
-{
- double *d;
-
- if (theme->float_constants == NULL)
- theme->float_constants = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- g_free);
-
- if (!first_uppercase (name))
- {
- g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
- _("User-defined constants must begin with a capital letter; \"%s\" does not"),
- name);
- return FALSE;
- }
-
- if (g_hash_table_lookup_extended (theme->float_constants, name, NULL, NULL))
- {
- g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
- _("Constant \"%s\" has already been defined"),
- name);
-
- return FALSE;
- }
-
- d = g_new (double, 1);
- *d = value;
-
- g_hash_table_insert (theme->float_constants,
- g_strdup (name), d);
-
- return TRUE;
-}
-
-gboolean
-meta_theme_lookup_float_constant (MetaTheme *theme,
- const char *name,
- double *value)
-{
- double *d;
-
- *value = 0.0;
-
- if (theme->float_constants == NULL)
- return FALSE;
-
- d = g_hash_table_lookup (theme->float_constants, name);
-
- if (d)
- {
- *value = *d;
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-gboolean
-meta_theme_define_color_constant (MetaTheme *theme,
- const char *name,
- const char *value,
- GError **error)
-{
- if (theme->color_constants == NULL)
- theme->color_constants = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- NULL);
-
- if (!first_uppercase (name))
- {
- g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
- _("User-defined constants must begin with a capital letter; \"%s\" does not"),
- name);
- return FALSE;
- }
-
- if (g_hash_table_lookup_extended (theme->color_constants, name, NULL, NULL))
- {
- g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
- _("Constant \"%s\" has already been defined"),
- name);
-
- return FALSE;
- }
-
- g_hash_table_insert (theme->color_constants,
- g_strdup (name),
- g_strdup (value));
-
- return TRUE;
-}
-
-gboolean
-meta_theme_lookup_color_constant (MetaTheme *theme,
- const char *name,
- char **value)
-{
- char *result;
-
- *value = NULL;
-
- if (theme->color_constants == NULL)
- return FALSE;
-
- result = g_hash_table_lookup (theme->color_constants, name);
-
- if (result)
- {
- *value = result;
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-
-PangoFontDescription*
-meta_gtk_widget_get_font_desc (GtkWidget *widget,
- double scale,
- const PangoFontDescription *override)
-{
- PangoFontDescription *font_desc;
-
- g_return_val_if_fail (GTK_WIDGET_REALIZED (widget), NULL);
-
- font_desc = pango_font_description_copy (widget->style->font_desc);
-
- if (override)
- pango_font_description_merge (font_desc, override, TRUE);
-
- pango_font_description_set_size (font_desc,
- MAX (pango_font_description_get_size (font_desc) * scale, 1));
-
- return font_desc;
-}
-
-int
-meta_pango_font_desc_get_text_height (const PangoFontDescription *font_desc,
- PangoContext *context)
-{
- PangoFontMetrics *metrics;
- PangoLanguage *lang;
- int retval;
-
- lang = pango_context_get_language (context);
- metrics = pango_context_get_metrics (context, font_desc, lang);
-
- retval = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) +
- pango_font_metrics_get_descent (metrics));
-
- pango_font_metrics_unref (metrics);
-
- return retval;
-}
-
-MetaGtkColorComponent
-meta_color_component_from_string (const char *str)
-{
- if (strcmp ("fg", str) == 0)
- return META_GTK_COLOR_FG;
- else if (strcmp ("bg", str) == 0)
- return META_GTK_COLOR_BG;
- else if (strcmp ("light", str) == 0)
- return META_GTK_COLOR_LIGHT;
- else if (strcmp ("dark", str) == 0)
- return META_GTK_COLOR_DARK;
- else if (strcmp ("mid", str) == 0)
- return META_GTK_COLOR_MID;
- else if (strcmp ("text", str) == 0)
- return META_GTK_COLOR_TEXT;
- else if (strcmp ("base", str) == 0)
- return META_GTK_COLOR_BASE;
- else if (strcmp ("text_aa", str) == 0)
- return META_GTK_COLOR_TEXT_AA;
- else
- return META_GTK_COLOR_LAST;
-}
-
-const char*
-meta_color_component_to_string (MetaGtkColorComponent component)
-{
- switch (component)
- {
- case META_GTK_COLOR_FG:
- return "fg";
- case META_GTK_COLOR_BG:
- return "bg";
- case META_GTK_COLOR_LIGHT:
- return "light";
- case META_GTK_COLOR_DARK:
- return "dark";
- case META_GTK_COLOR_MID:
- return "mid";
- case META_GTK_COLOR_TEXT:
- return "text";
- case META_GTK_COLOR_BASE:
- return "base";
- case META_GTK_COLOR_TEXT_AA:
- return "text_aa";
- case META_GTK_COLOR_LAST:
- break;
- }
-
- return "<unknown>";
-}
-
-MetaButtonState
-meta_button_state_from_string (const char *str)
-{
- if (strcmp ("normal", str) == 0)
- return META_BUTTON_STATE_NORMAL;
- else if (strcmp ("pressed", str) == 0)
- return META_BUTTON_STATE_PRESSED;
- else if (strcmp ("prelight", str) == 0)
- return META_BUTTON_STATE_PRELIGHT;
- else
- return META_BUTTON_STATE_LAST;
-}
-
-const char*
-meta_button_state_to_string (MetaButtonState state)
-{
- switch (state)
- {
- case META_BUTTON_STATE_NORMAL:
- return "normal";
- case META_BUTTON_STATE_PRESSED:
- return "pressed";
- case META_BUTTON_STATE_PRELIGHT:
- return "prelight";
- case META_BUTTON_STATE_LAST:
- break;
- }
-
- return "<unknown>";
-}
-
-MetaButtonType
-meta_button_type_from_string (const char *str, MetaTheme *theme)
-{
- if (META_THEME_ALLOWS(theme, META_THEME_SHADE_STICK_ABOVE_BUTTONS))
- {
- if (strcmp ("shade", str) == 0)
- return META_BUTTON_TYPE_SHADE;
- else if (strcmp ("above", str) == 0)
- return META_BUTTON_TYPE_ABOVE;
- else if (strcmp ("stick", str) == 0)
- return META_BUTTON_TYPE_STICK;
- else if (strcmp ("unshade", str) == 0)
- return META_BUTTON_TYPE_UNSHADE;
- else if (strcmp ("unabove", str) == 0)
- return META_BUTTON_TYPE_UNABOVE;
- else if (strcmp ("unstick", str) == 0)
- return META_BUTTON_TYPE_UNSTICK;
- }
-
- if (strcmp ("close", str) == 0)
- return META_BUTTON_TYPE_CLOSE;
- else if (strcmp ("maximize", str) == 0)
- return META_BUTTON_TYPE_MAXIMIZE;
- else if (strcmp ("minimize", str) == 0)
- return META_BUTTON_TYPE_MINIMIZE;
- else if (strcmp ("menu", str) == 0)
- return META_BUTTON_TYPE_MENU;
- else if (strcmp ("left_left_background", str) == 0)
- return META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND;
- else if (strcmp ("left_middle_background", str) == 0)
- return META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND;
- else if (strcmp ("left_right_background", str) == 0)
- return META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND;
- else if (strcmp ("right_left_background", str) == 0)
- return META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND;
- else if (strcmp ("right_middle_background", str) == 0)
- return META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND;
- else if (strcmp ("right_right_background", str) == 0)
- return META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND;
- else
- return META_BUTTON_TYPE_LAST;
-}
-
-const char*
-meta_button_type_to_string (MetaButtonType type)
-{
- switch (type)
- {
- case META_BUTTON_TYPE_CLOSE:
- return "close";
- case META_BUTTON_TYPE_MAXIMIZE:
- return "maximize";
- case META_BUTTON_TYPE_MINIMIZE:
- return "minimize";
- case META_BUTTON_TYPE_SHADE:
- return "shade";
- case META_BUTTON_TYPE_ABOVE:
- return "above";
- case META_BUTTON_TYPE_STICK:
- return "stick";
- case META_BUTTON_TYPE_UNSHADE:
- return "unshade";
- case META_BUTTON_TYPE_UNABOVE:
- return "unabove";
- case META_BUTTON_TYPE_UNSTICK:
- return "unstick";
- case META_BUTTON_TYPE_MENU:
- return "menu";
- case META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND:
- return "left_left_background";
- case META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND:
- return "left_middle_background";
- case META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND:
- return "left_right_background";
- case META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND:
- return "right_left_background";
- case META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND:
- return "right_middle_background";
- case META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND:
- return "right_right_background";
- case META_BUTTON_TYPE_LAST:
- break;
- }
-
- return "<unknown>";
-}
-
-MetaFramePiece
-meta_frame_piece_from_string (const char *str)
-{
- if (strcmp ("entire_background", str) == 0)
- return META_FRAME_PIECE_ENTIRE_BACKGROUND;
- else if (strcmp ("titlebar", str) == 0)
- return META_FRAME_PIECE_TITLEBAR;
- else if (strcmp ("titlebar_middle", str) == 0)
- return META_FRAME_PIECE_TITLEBAR_MIDDLE;
- else if (strcmp ("left_titlebar_edge", str) == 0)
- return META_FRAME_PIECE_LEFT_TITLEBAR_EDGE;
- else if (strcmp ("right_titlebar_edge", str) == 0)
- return META_FRAME_PIECE_RIGHT_TITLEBAR_EDGE;
- else if (strcmp ("top_titlebar_edge", str) == 0)
- return META_FRAME_PIECE_TOP_TITLEBAR_EDGE;
- else if (strcmp ("bottom_titlebar_edge", str) == 0)
- return META_FRAME_PIECE_BOTTOM_TITLEBAR_EDGE;
- else if (strcmp ("title", str) == 0)
- return META_FRAME_PIECE_TITLE;
- else if (strcmp ("left_edge", str) == 0)
- return META_FRAME_PIECE_LEFT_EDGE;
- else if (strcmp ("right_edge", str) == 0)
- return META_FRAME_PIECE_RIGHT_EDGE;
- else if (strcmp ("bottom_edge", str) == 0)
- return META_FRAME_PIECE_BOTTOM_EDGE;
- else if (strcmp ("overlay", str) == 0)
- return META_FRAME_PIECE_OVERLAY;
- else
- return META_FRAME_PIECE_LAST;
-}
-
-const char*
-meta_frame_piece_to_string (MetaFramePiece piece)
-{
- switch (piece)
- {
- case META_FRAME_PIECE_ENTIRE_BACKGROUND:
- return "entire_background";
- case META_FRAME_PIECE_TITLEBAR:
- return "titlebar";
- case META_FRAME_PIECE_TITLEBAR_MIDDLE:
- return "titlebar_middle";
- case META_FRAME_PIECE_LEFT_TITLEBAR_EDGE:
- return "left_titlebar_edge";
- case META_FRAME_PIECE_RIGHT_TITLEBAR_EDGE:
- return "right_titlebar_edge";
- case META_FRAME_PIECE_TOP_TITLEBAR_EDGE:
- return "top_titlebar_edge";
- case META_FRAME_PIECE_BOTTOM_TITLEBAR_EDGE:
- return "bottom_titlebar_edge";
- case META_FRAME_PIECE_TITLE:
- return "title";
- case META_FRAME_PIECE_LEFT_EDGE:
- return "left_edge";
- case META_FRAME_PIECE_RIGHT_EDGE:
- return "right_edge";
- case META_FRAME_PIECE_BOTTOM_EDGE:
- return "bottom_edge";
- case META_FRAME_PIECE_OVERLAY:
- return "overlay";
- case META_FRAME_PIECE_LAST:
- break;
- }
-
- return "<unknown>";
-}
-
-MetaFrameState
-meta_frame_state_from_string (const char *str)
-{
- if (strcmp ("normal", str) == 0)
- return META_FRAME_STATE_NORMAL;
- else if (strcmp ("maximized", str) == 0)
- return META_FRAME_STATE_MAXIMIZED;
- else if (strcmp ("shaded", str) == 0)
- return META_FRAME_STATE_SHADED;
- else if (strcmp ("maximized_and_shaded", str) == 0)
- return META_FRAME_STATE_MAXIMIZED_AND_SHADED;
- else
- return META_FRAME_STATE_LAST;
-}
-
-const char*
-meta_frame_state_to_string (MetaFrameState state)
-{
- switch (state)
- {
- case META_FRAME_STATE_NORMAL:
- return "normal";
- case META_FRAME_STATE_MAXIMIZED:
- return "maximized";
- case META_FRAME_STATE_SHADED:
- return "shaded";
- case META_FRAME_STATE_MAXIMIZED_AND_SHADED:
- return "maximized_and_shaded";
- case META_FRAME_STATE_LAST:
- break;
- }
-
- return "<unknown>";
-}
-
-MetaFrameResize
-meta_frame_resize_from_string (const char *str)
-{
- if (strcmp ("none", str) == 0)
- return META_FRAME_RESIZE_NONE;
- else if (strcmp ("vertical", str) == 0)
- return META_FRAME_RESIZE_VERTICAL;
- else if (strcmp ("horizontal", str) == 0)
- return META_FRAME_RESIZE_HORIZONTAL;
- else if (strcmp ("both", str) == 0)
- return META_FRAME_RESIZE_BOTH;
- else
- return META_FRAME_RESIZE_LAST;
-}
-
-const char*
-meta_frame_resize_to_string (MetaFrameResize resize)
-{
- switch (resize)
- {
- case META_FRAME_RESIZE_NONE:
- return "none";
- case META_FRAME_RESIZE_VERTICAL:
- return "vertical";
- case META_FRAME_RESIZE_HORIZONTAL:
- return "horizontal";
- case META_FRAME_RESIZE_BOTH:
- return "both";
- case META_FRAME_RESIZE_LAST:
- break;
- }
-
- return "<unknown>";
-}
-
-MetaFrameFocus
-meta_frame_focus_from_string (const char *str)
-{
- if (strcmp ("no", str) == 0)
- return META_FRAME_FOCUS_NO;
- else if (strcmp ("yes", str) == 0)
- return META_FRAME_FOCUS_YES;
- else
- return META_FRAME_FOCUS_LAST;
-}
-
-const char*
-meta_frame_focus_to_string (MetaFrameFocus focus)
-{
- switch (focus)
- {
- case META_FRAME_FOCUS_NO:
- return "no";
- case META_FRAME_FOCUS_YES:
- return "yes";
- case META_FRAME_FOCUS_LAST:
- break;
- }
-
- return "<unknown>";
-}
-
-MetaFrameType
-meta_frame_type_from_string (const char *str)
-{
- if (strcmp ("normal", str) == 0)
- return META_FRAME_TYPE_NORMAL;
- else if (strcmp ("dialog", str) == 0)
- return META_FRAME_TYPE_DIALOG;
- else if (strcmp ("modal_dialog", str) == 0)
- return META_FRAME_TYPE_MODAL_DIALOG;
- else if (strcmp ("utility", str) == 0)
- return META_FRAME_TYPE_UTILITY;
- else if (strcmp ("menu", str) == 0)
- return META_FRAME_TYPE_MENU;
- else if (strcmp ("border", str) == 0)
- return META_FRAME_TYPE_BORDER;
-#if 0
- else if (strcmp ("toolbar", str) == 0)
- return META_FRAME_TYPE_TOOLBAR;
-#endif
- else
- return META_FRAME_TYPE_LAST;
-}
-
-const char*
-meta_frame_type_to_string (MetaFrameType type)
-{
- switch (type)
- {
- case META_FRAME_TYPE_NORMAL:
- return "normal";
- case META_FRAME_TYPE_DIALOG:
- return "dialog";
- case META_FRAME_TYPE_MODAL_DIALOG:
- return "modal_dialog";
- case META_FRAME_TYPE_UTILITY:
- return "utility";
- case META_FRAME_TYPE_MENU:
- return "menu";
- case META_FRAME_TYPE_BORDER:
- return "border";
-#if 0
- case META_FRAME_TYPE_TOOLBAR:
- return "toolbar";
-#endif
- case META_FRAME_TYPE_LAST:
- break;
- }
-
- return "<unknown>";
-}
-
-MetaGradientType
-meta_gradient_type_from_string (const char *str)
-{
- if (strcmp ("vertical", str) == 0)
- return META_GRADIENT_VERTICAL;
- else if (strcmp ("horizontal", str) == 0)
- return META_GRADIENT_HORIZONTAL;
- else if (strcmp ("diagonal", str) == 0)
- return META_GRADIENT_DIAGONAL;
- else
- return META_GRADIENT_LAST;
-}
-
-const char*
-meta_gradient_type_to_string (MetaGradientType type)
-{
- switch (type)
- {
- case META_GRADIENT_VERTICAL:
- return "vertical";
- case META_GRADIENT_HORIZONTAL:
- return "horizontal";
- case META_GRADIENT_DIAGONAL:
- return "diagonal";
- case META_GRADIENT_LAST:
- break;
- }
-
- return "<unknown>";
-}
-
-GtkStateType
-meta_gtk_state_from_string (const char *str)
-{
- if (strcmp ("normal", str) == 0 || strcmp ("NORMAL", str) == 0)
- return GTK_STATE_NORMAL;
- else if (strcmp ("prelight", str) == 0 || strcmp ("PRELIGHT", str) == 0)
- return GTK_STATE_PRELIGHT;
- else if (strcmp ("active", str) == 0 || strcmp ("ACTIVE", str) == 0)
- return GTK_STATE_ACTIVE;
- else if (strcmp ("selected", str) == 0 || strcmp ("SELECTED", str) == 0)
- return GTK_STATE_SELECTED;
- else if (strcmp ("insensitive", str) == 0 || strcmp ("INSENSITIVE", str) == 0)
- return GTK_STATE_INSENSITIVE;
- else
- return -1; /* hack */
-}
-
-const char*
-meta_gtk_state_to_string (GtkStateType state)
-{
- switch (state)
- {
- case GTK_STATE_NORMAL:
- return "NORMAL";
- case GTK_STATE_PRELIGHT:
- return "PRELIGHT";
- case GTK_STATE_ACTIVE:
- return "ACTIVE";
- case GTK_STATE_SELECTED:
- return "SELECTED";
- case GTK_STATE_INSENSITIVE:
- return "INSENSITIVE";
- }
-
- return "<unknown>";
-}
-
-GtkShadowType
-meta_gtk_shadow_from_string (const char *str)
-{
- if (strcmp ("none", str) == 0)
- return GTK_SHADOW_NONE;
- else if (strcmp ("in", str) == 0)
- return GTK_SHADOW_IN;
- else if (strcmp ("out", str) == 0)
- return GTK_SHADOW_OUT;
- else if (strcmp ("etched_in", str) == 0)
- return GTK_SHADOW_ETCHED_IN;
- else if (strcmp ("etched_out", str) == 0)
- return GTK_SHADOW_ETCHED_OUT;
- else
- return -1;
-}
-
-const char*
-meta_gtk_shadow_to_string (GtkShadowType shadow)
-{
- switch (shadow)
- {
- case GTK_SHADOW_NONE:
- return "none";
- case GTK_SHADOW_IN:
- return "in";
- case GTK_SHADOW_OUT:
- return "out";
- case GTK_SHADOW_ETCHED_IN:
- return "etched_in";
- case GTK_SHADOW_ETCHED_OUT:
- return "etched_out";
- }
-
- return "<unknown>";
-}
-
-GtkArrowType
-meta_gtk_arrow_from_string (const char *str)
-{
- if (strcmp ("up", str) == 0)
- return GTK_ARROW_UP;
- else if (strcmp ("down", str) == 0)
- return GTK_ARROW_DOWN;
- else if (strcmp ("left", str) == 0)
- return GTK_ARROW_LEFT;
- else if (strcmp ("right", str) == 0)
- return GTK_ARROW_RIGHT;
- else if (strcmp ("none", str) == 0)
- return GTK_ARROW_NONE;
- else
- return -1;
-}
-
-const char*
-meta_gtk_arrow_to_string (GtkArrowType arrow)
-{
- switch (arrow)
- {
- case GTK_ARROW_UP:
- return "up";
- case GTK_ARROW_DOWN:
- return "down";
- case GTK_ARROW_LEFT:
- return "left";
- case GTK_ARROW_RIGHT:
- return "right";
- case GTK_ARROW_NONE:
- return "none";
- }
-
- return "<unknown>";
-}
-
-MetaImageFillType
-meta_image_fill_type_from_string (const char *str)
-{
- if (strcmp ("tile", str) == 0)
- return META_IMAGE_FILL_TILE;
- else if (strcmp ("scale", str) == 0)
- return META_IMAGE_FILL_SCALE;
- else
- return -1;
-}
-
-const char*
-meta_image_fill_type_to_string (MetaImageFillType fill_type)
-{
- switch (fill_type)
- {
- case META_IMAGE_FILL_TILE:
- return "tile";
- case META_IMAGE_FILL_SCALE:
- return "scale";
- }
-
- return "<unknown>";
-}
-
-/* gtkstyle.c cut-and-pastage */
-static void
-gtk_style_shade (GdkColor *a,
- GdkColor *b,
- gdouble k)
-{
- gdouble red;
- gdouble green;
- gdouble blue;
-
- red = (gdouble) a->red / 65535.0;
- green = (gdouble) a->green / 65535.0;
- blue = (gdouble) a->blue / 65535.0;
-
- rgb_to_hls (&red, &green, &blue);
-
- green *= k;
- if (green > 1.0)
- green = 1.0;
- else if (green < 0.0)
- green = 0.0;
-
- blue *= k;
- if (blue > 1.0)
- blue = 1.0;
- else if (blue < 0.0)
- blue = 0.0;
-
- hls_to_rgb (&red, &green, &blue);
-
- b->red = red * 65535.0;
- b->green = green * 65535.0;
- b->blue = blue * 65535.0;
-}
-
-static void
-rgb_to_hls (gdouble *r,
- gdouble *g,
- gdouble *b)
-{
- gdouble min;
- gdouble max;
- gdouble red;
- gdouble green;
- gdouble blue;
- gdouble h, l, s;
- gdouble delta;
-
- red = *r;
- green = *g;
- blue = *b;
-
- if (red > green)
- {
- if (red > blue)
- max = red;
- else
- max = blue;
-
- if (green < blue)
- min = green;
- else
- min = blue;
- }
- else
- {
- if (green > blue)
- max = green;
- else
- max = blue;
-
- if (red < blue)
- min = red;
- else
- min = blue;
- }
-
- l = (max + min) / 2;
- s = 0;
- h = 0;
-
- if (max != min)
- {
- if (l <= 0.5)
- s = (max - min) / (max + min);
- else
- s = (max - min) / (2 - max - min);
-
- delta = max -min;
- if (red == max)
- h = (green - blue) / delta;
- else if (green == max)
- h = 2 + (blue - red) / delta;
- else if (blue == max)
- h = 4 + (red - green) / delta;
-
- h *= 60;
- if (h < 0.0)
- h += 360;
- }
-
- *r = h;
- *g = l;
- *b = s;
-}
-
-static void
-hls_to_rgb (gdouble *h,
- gdouble *l,
- gdouble *s)
-{
- gdouble hue;
- gdouble lightness;
- gdouble saturation;
- gdouble m1, m2;
- gdouble r, g, b;
-
- lightness = *l;
- saturation = *s;
-
- if (lightness <= 0.5)
- m2 = lightness * (1 + saturation);
- else
- m2 = lightness + saturation - lightness * saturation;
- m1 = 2 * lightness - m2;
-
- if (saturation == 0)
- {
- *h = lightness;
- *l = lightness;
- *s = lightness;
- }
- else
- {
- hue = *h + 120;
- while (hue > 360)
- hue -= 360;
- while (hue < 0)
- hue += 360;
-
- if (hue < 60)
- r = m1 + (m2 - m1) * hue / 60;
- else if (hue < 180)
- r = m2;
- else if (hue < 240)
- r = m1 + (m2 - m1) * (240 - hue) / 60;
- else
- r = m1;
-
- hue = *h;
- while (hue > 360)
- hue -= 360;
- while (hue < 0)
- hue += 360;
-
- if (hue < 60)
- g = m1 + (m2 - m1) * hue / 60;
- else if (hue < 180)
- g = m2;
- else if (hue < 240)
- g = m1 + (m2 - m1) * (240 - hue) / 60;
- else
- g = m1;
-
- hue = *h - 120;
- while (hue > 360)
- hue -= 360;
- while (hue < 0)
- hue += 360;
-
- if (hue < 60)
- b = m1 + (m2 - m1) * hue / 60;
- else if (hue < 180)
- b = m2;
- else if (hue < 240)
- b = m1 + (m2 - m1) * (240 - hue) / 60;
- else
- b = m1;
-
- *h = r;
- *l = g;
- *s = b;
- }
-}
-
-#if 0
-/* These are some functions I'm saving to use in optimizing
- * MetaDrawOpList, namely to pre-composite pixbufs on client side
- * prior to rendering to the server
- */
-static void
-draw_bg_solid_composite (const MetaTextureSpec *bg,
- const MetaTextureSpec *fg,
- double alpha,
- GtkWidget *widget,
- GdkDrawable *drawable,
- const GdkRectangle *clip,
- MetaTextureDrawMode mode,
- double xalign,
- double yalign,
- int x,
- int y,
- int width,
- int height)
-{
- GdkColor bg_color;
-
- g_assert (bg->type == META_TEXTURE_SOLID);
- g_assert (fg->type != META_TEXTURE_COMPOSITE);
- g_assert (fg->type != META_TEXTURE_SHAPE_LIST);
-
- meta_color_spec_render (bg->data.solid.color_spec,
- widget,
- &bg_color);
-
- switch (fg->type)
- {
- case META_TEXTURE_SOLID:
- {
- GdkColor fg_color;
-
- meta_color_spec_render (fg->data.solid.color_spec,
- widget,
- &fg_color);
-
- color_composite (&bg_color, &fg_color,
- alpha, &fg_color);
-
- draw_color_rectangle (widget, drawable, &fg_color, clip,
- x, y, width, height);
- }
- break;
-
- case META_TEXTURE_GRADIENT:
- /* FIXME I think we could just composite all the colors in
- * the gradient prior to generating the gradient?
- */
- /* FALL THRU */
- case META_TEXTURE_IMAGE:
- {
- GdkPixbuf *pixbuf;
- GdkPixbuf *composited;
-
- pixbuf = meta_texture_spec_render (fg, widget, mode, 255,
- width, height);
-
- if (pixbuf == NULL)
- return;
-
- composited = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
- gdk_pixbuf_get_has_alpha (pixbuf), 8,
- gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf));
-
- if (composited == NULL)
- {
- g_object_unref (G_OBJECT (pixbuf));
- return;
- }
-
- gdk_pixbuf_composite_color (pixbuf,
- composited,
- 0, 0,
- gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf),
- 0.0, 0.0, /* offsets */
- 1.0, 1.0, /* scale */
- GDK_INTERP_BILINEAR,
- 255 * alpha,
- 0, 0, /* check offsets */
- 0, /* check size */
- GDK_COLOR_RGB (bg_color),
- GDK_COLOR_RGB (bg_color));
-
- /* Need to draw background since pixbuf is not
- * necessarily covering the whole thing
- */
- draw_color_rectangle (widget, drawable, &bg_color, clip,
- x, y, width, height);
-
- render_pixbuf_aligned (drawable, clip, composited,
- xalign, yalign,
- x, y, width, height);
-
- g_object_unref (G_OBJECT (pixbuf));
- g_object_unref (G_OBJECT (composited));
- }
- break;
-
- case META_TEXTURE_BLANK:
- case META_TEXTURE_COMPOSITE:
- case META_TEXTURE_SHAPE_LIST:
- g_assert_not_reached ();
- break;
- }
-}
-
-static void
-draw_bg_gradient_composite (const MetaTextureSpec *bg,
- const MetaTextureSpec *fg,
- double alpha,
- GtkWidget *widget,
- GdkDrawable *drawable,
- const GdkRectangle *clip,
- MetaTextureDrawMode mode,
- double xalign,
- double yalign,
- int x,
- int y,
- int width,
- int height)
-{
- g_assert (bg->type == META_TEXTURE_GRADIENT);
- g_assert (fg->type != META_TEXTURE_COMPOSITE);
- g_assert (fg->type != META_TEXTURE_SHAPE_LIST);
-
- switch (fg->type)
- {
- case META_TEXTURE_SOLID:
- case META_TEXTURE_GRADIENT:
- case META_TEXTURE_IMAGE:
- {
- GdkPixbuf *bg_pixbuf;
- GdkPixbuf *fg_pixbuf;
- GdkPixbuf *composited;
- int fg_width, fg_height;
-
- bg_pixbuf = meta_texture_spec_render (bg, widget, mode, 255,
- width, height);
-
- if (bg_pixbuf == NULL)
- return;
-
- fg_pixbuf = meta_texture_spec_render (fg, widget, mode, 255,
- width, height);
-
- if (fg_pixbuf == NULL)
- {
- g_object_unref (G_OBJECT (bg_pixbuf));
- return;
- }
-
- /* gradients always fill the entire target area */
- g_assert (gdk_pixbuf_get_width (bg_pixbuf) == width);
- g_assert (gdk_pixbuf_get_height (bg_pixbuf) == height);
-
- composited = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
- gdk_pixbuf_get_has_alpha (bg_pixbuf), 8,
- gdk_pixbuf_get_width (bg_pixbuf),
- gdk_pixbuf_get_height (bg_pixbuf));
-
- if (composited == NULL)
- {
- g_object_unref (G_OBJECT (bg_pixbuf));
- g_object_unref (G_OBJECT (fg_pixbuf));
- return;
- }
-
- fg_width = gdk_pixbuf_get_width (fg_pixbuf);
- fg_height = gdk_pixbuf_get_height (fg_pixbuf);
-
- /* If we wanted to be all cool we could deal with the
- * offsets and try to composite only in the clip rectangle,
- * but I just don't care enough to figure it out.
- */
-
- gdk_pixbuf_composite (fg_pixbuf,
- composited,
- x + (width - fg_width) * xalign,
- y + (height - fg_height) * yalign,
- gdk_pixbuf_get_width (fg_pixbuf),
- gdk_pixbuf_get_height (fg_pixbuf),
- 0.0, 0.0, /* offsets */
- 1.0, 1.0, /* scale */
- GDK_INTERP_BILINEAR,
- 255 * alpha);
-
- render_pixbuf (drawable, clip, composited, x, y);
-
- g_object_unref (G_OBJECT (bg_pixbuf));
- g_object_unref (G_OBJECT (fg_pixbuf));
- g_object_unref (G_OBJECT (composited));
- }
- break;
-
- case META_TEXTURE_BLANK:
- case META_TEXTURE_SHAPE_LIST:
- case META_TEXTURE_COMPOSITE:
- g_assert_not_reached ();
- break;
- }
-}
-#endif
-
-guint
-meta_theme_earliest_version_with_button (MetaButtonType type)
-{
- switch (type)
- {
- case META_BUTTON_TYPE_CLOSE:
- case META_BUTTON_TYPE_MAXIMIZE:
- case META_BUTTON_TYPE_MINIMIZE:
- case META_BUTTON_TYPE_MENU:
- case META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND:
- case META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND:
- case META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND:
- case META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND:
- case META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND:
- case META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND:
- return 1;
-
- case META_BUTTON_TYPE_SHADE:
- case META_BUTTON_TYPE_ABOVE:
- case META_BUTTON_TYPE_STICK:
- case META_BUTTON_TYPE_UNSHADE:
- case META_BUTTON_TYPE_UNABOVE:
- case META_BUTTON_TYPE_UNSTICK:
- return 2;
-
- default:
- meta_warning("Unknown button %d\n", type);
- return 1;
- }
-}
diff --git a/src/ui/theme.h b/src/ui/theme.h
deleted file mode 100644
index 737f30a8..00000000
--- a/src/ui/theme.h
+++ /dev/null
@@ -1,1139 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity Theme Rendering */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_THEME_H
-#define META_THEME_H
-
-#include "boxes.h"
-#include "gradient.h"
-#include "common.h"
-#include <gtk/gtk.h>
-
-typedef struct _MetaFrameStyle MetaFrameStyle;
-typedef struct _MetaFrameStyleSet MetaFrameStyleSet;
-typedef struct _MetaDrawOp MetaDrawOp;
-typedef struct _MetaDrawOpList MetaDrawOpList;
-typedef struct _MetaGradientSpec MetaGradientSpec;
-typedef struct _MetaAlphaGradientSpec MetaAlphaGradientSpec;
-typedef struct _MetaColorSpec MetaColorSpec;
-typedef struct _MetaFrameLayout MetaFrameLayout;
-typedef struct _MetaButtonSpace MetaButtonSpace;
-typedef struct _MetaFrameGeometry MetaFrameGeometry;
-typedef struct _MetaTheme MetaTheme;
-typedef struct _MetaPositionExprEnv MetaPositionExprEnv;
-typedef struct _MetaDrawInfo MetaDrawInfo;
-
-#define META_THEME_ERROR (g_quark_from_static_string ("meta-theme-error"))
-
-typedef enum
-{
- META_THEME_ERROR_FRAME_GEOMETRY,
- META_THEME_ERROR_BAD_CHARACTER,
- META_THEME_ERROR_BAD_PARENS,
- META_THEME_ERROR_UNKNOWN_VARIABLE,
- META_THEME_ERROR_DIVIDE_BY_ZERO,
- META_THEME_ERROR_MOD_ON_FLOAT,
- META_THEME_ERROR_FAILED
-} MetaThemeError;
-
-/**
- * Whether a button's size is calculated from the area around it (aspect
- * sizing) or is given as a fixed height and width in pixels (fixed sizing).
- *
- * \bug This could be done away with; see the comment at the top of
- * MetaFrameLayout.
- */
-typedef enum
-{
- META_BUTTON_SIZING_ASPECT,
- META_BUTTON_SIZING_FIXED,
- META_BUTTON_SIZING_LAST
-} MetaButtonSizing;
-
-/**
- * Various parameters used to calculate the geometry of a frame.
- * They are used inside a MetaFrameStyle.
- * This corresponds closely to the <frame_geometry> tag in a theme file.
- *
- * \bug button_sizing isn't really necessary, because we could easily say
- * that if button_aspect is zero, the height and width are fixed values.
- * This would also mean that MetaButtonSizing didn't need to exist, and
- * save code.
- **/
-struct _MetaFrameLayout
-{
- /** Reference count. */
- int refcount;
-
- /** Size of left side */
- int left_width;
- /** Size of right side */
- int right_width;
- /** Size of bottom side */
- int bottom_height;
-
- /** Border of blue title region
- * \bug (blue?!)
- **/
- GtkBorder title_border;
-
- /** Extra height for inside of title region, above the font height */
- int title_vertical_pad;
-
- /** Right indent of buttons from edges of frame */
- int right_titlebar_edge;
- /** Left indent of buttons from edges of frame */
- int left_titlebar_edge;
-
- /**
- * Sizing rule of buttons, either META_BUTTON_SIZING_ASPECT
- * (in which case button_aspect will be honoured, and
- * button_width and button_height set from it), or
- * META_BUTTON_SIZING_FIXED (in which case we read the width
- * and height directly).
- */
- MetaButtonSizing button_sizing;
-
- /**
- * Ratio of height/width. Honoured only if
- * button_sizing==META_BUTTON_SIZING_ASPECT.
- * Otherwise we figure out the height from the button_border.
- */
- double button_aspect;
-
- /** Width of a button; set even when we are using aspect sizing */
- int button_width;
-
- /** Height of a button; set even when we are using aspect sizing */
- int button_height;
-
- /** Space around buttons */
- GtkBorder button_border;
-
- /** scale factor for title text */
- double title_scale;
-
- /** Whether title text will be displayed */
- guint has_title : 1;
-
- /** Whether we should hide the buttons */
- guint hide_buttons : 1;
-
- /** Radius of the top left-hand corner; 0 if not rounded */
- guint top_left_corner_rounded_radius;
- /** Radius of the top right-hand corner; 0 if not rounded */
- guint top_right_corner_rounded_radius;
- /** Radius of the bottom left-hand corner; 0 if not rounded */
- guint bottom_left_corner_rounded_radius;
- /** Radius of the bottom right-hand corner; 0 if not rounded */
- guint bottom_right_corner_rounded_radius;
-};
-
-/**
- * The computed size of a button (really just a way of tying its
- * visible and clickable areas together).
- * The reason for two different rectangles here is Fitts' law & maximized
- * windows; see bug #97703 for more details.
- */
-struct _MetaButtonSpace
-{
- /** The screen area where the button's image is drawn */
- GdkRectangle visible;
- /** The screen area where the button can be activated by clicking */
- GdkRectangle clickable;
-};
-
-/**
- * Calculated actual geometry of the frame
- */
-struct _MetaFrameGeometry
-{
- int left_width;
- int right_width;
- int top_height;
- int bottom_height;
-
- int width;
- int height;
-
- GdkRectangle title_rect;
-
- int left_titlebar_edge;
- int right_titlebar_edge;
- int top_titlebar_edge;
- int bottom_titlebar_edge;
-
- /* used for a memset hack */
-#define ADDRESS_OF_BUTTON_RECTS(fgeom) (((char*)(fgeom)) + G_STRUCT_OFFSET (MetaFrameGeometry, close_rect))
-#define LENGTH_OF_BUTTON_RECTS (G_STRUCT_OFFSET (MetaFrameGeometry, right_right_background) + sizeof (GdkRectangle) - G_STRUCT_OFFSET (MetaFrameGeometry, close_rect))
-
- /* The button rects (if changed adjust memset hack) */
- MetaButtonSpace close_rect;
- MetaButtonSpace max_rect;
- MetaButtonSpace min_rect;
- MetaButtonSpace menu_rect;
- MetaButtonSpace shade_rect;
- MetaButtonSpace above_rect;
- MetaButtonSpace stick_rect;
- MetaButtonSpace unshade_rect;
- MetaButtonSpace unabove_rect;
- MetaButtonSpace unstick_rect;
-
-#define MAX_MIDDLE_BACKGROUNDS (MAX_BUTTONS_PER_CORNER - 2)
- GdkRectangle left_left_background;
- GdkRectangle left_middle_backgrounds[MAX_MIDDLE_BACKGROUNDS];
- GdkRectangle left_right_background;
- GdkRectangle right_left_background;
- GdkRectangle right_middle_backgrounds[MAX_MIDDLE_BACKGROUNDS];
- GdkRectangle right_right_background;
- /* End of button rects (if changed adjust memset hack) */
-
- /* Round corners */
- guint top_left_corner_rounded_radius;
- guint top_right_corner_rounded_radius;
- guint bottom_left_corner_rounded_radius;
- guint bottom_right_corner_rounded_radius;
-};
-
-typedef enum
-{
- META_IMAGE_FILL_SCALE, /* default, needs to be all-bits-zero for g_new0 */
- META_IMAGE_FILL_TILE
-} MetaImageFillType;
-
-typedef enum
-{
- META_COLOR_SPEC_BASIC,
- META_COLOR_SPEC_GTK,
- META_COLOR_SPEC_BLEND,
- META_COLOR_SPEC_SHADE
-} MetaColorSpecType;
-
-typedef enum
-{
- META_GTK_COLOR_FG,
- META_GTK_COLOR_BG,
- META_GTK_COLOR_LIGHT,
- META_GTK_COLOR_DARK,
- META_GTK_COLOR_MID,
- META_GTK_COLOR_TEXT,
- META_GTK_COLOR_BASE,
- META_GTK_COLOR_TEXT_AA,
- META_GTK_COLOR_LAST
-} MetaGtkColorComponent;
-
-struct _MetaColorSpec
-{
- MetaColorSpecType type;
- union
- {
- struct {
- GdkColor color;
- } basic;
- struct {
- MetaGtkColorComponent component;
- GtkStateType state;
- } gtk;
- struct {
- MetaColorSpec *foreground;
- MetaColorSpec *background;
- double alpha;
-
- GdkColor color;
- } blend;
- struct {
- MetaColorSpec *base;
- double factor;
-
- GdkColor color;
- } shade;
- } data;
-};
-
-struct _MetaGradientSpec
-{
- MetaGradientType type;
- GSList *color_specs;
-};
-
-struct _MetaAlphaGradientSpec
-{
- MetaGradientType type;
- unsigned char *alphas;
- int n_alphas;
-};
-
-struct _MetaDrawInfo
-{
- GdkPixbuf *mini_icon;
- GdkPixbuf *icon;
- PangoLayout *title_layout;
- int title_layout_width;
- int title_layout_height;
- const MetaFrameGeometry *fgeom;
-};
-
-/**
- * A drawing operation in our simple vector drawing language.
- */
-typedef enum
-{
- /** Basic drawing-- line */
- META_DRAW_LINE,
- /** Basic drawing-- rectangle */
- META_DRAW_RECTANGLE,
- /** Basic drawing-- arc */
- META_DRAW_ARC,
-
- /** Clip to a rectangle */
- META_DRAW_CLIP,
-
- /* Texture thingies */
-
- /** Just a filled rectangle with alpha */
- META_DRAW_TINT,
- META_DRAW_GRADIENT,
- META_DRAW_IMAGE,
-
- /** GTK theme engine stuff */
- META_DRAW_GTK_ARROW,
- META_DRAW_GTK_BOX,
- META_DRAW_GTK_VLINE,
-
- /** App's window icon */
- META_DRAW_ICON,
- /** App's window title */
- META_DRAW_TITLE,
- /** a draw op list */
- META_DRAW_OP_LIST,
- /** tiled draw op list */
- META_DRAW_TILE
-} MetaDrawType;
-
-typedef enum
-{
- POS_TOKEN_INT,
- POS_TOKEN_DOUBLE,
- POS_TOKEN_OPERATOR,
- POS_TOKEN_VARIABLE,
- POS_TOKEN_OPEN_PAREN,
- POS_TOKEN_CLOSE_PAREN
-} PosTokenType;
-
-typedef enum
-{
- POS_OP_NONE,
- POS_OP_ADD,
- POS_OP_SUBTRACT,
- POS_OP_MULTIPLY,
- POS_OP_DIVIDE,
- POS_OP_MOD,
- POS_OP_MAX,
- POS_OP_MIN
-} PosOperatorType;
-
-/**
- * A token, as output by the tokeniser.
- *
- * \ingroup tokenizer
- */
-typedef struct
-{
- PosTokenType type;
-
- union
- {
- struct {
- int val;
- } i;
-
- struct {
- double val;
- } d;
-
- struct {
- PosOperatorType op;
- } o;
-
- struct {
- char *name;
- GQuark name_quark;
- } v;
-
- } d;
-} PosToken;
-
-/**
- * A computed expression in our simple vector drawing language.
- * While it appears to take the form of a tree, this is actually
- * merely a list; concerns such as precedence of operators are
- * currently recomputed on every recalculation.
- *
- * Created by meta_draw_spec_new(), destroyed by meta_draw_spec_free().
- * pos_eval() fills this with ...FIXME. Are tokens a tree or a list?
- * \ingroup parser
- */
-typedef struct _MetaDrawSpec
-{
- /**
- * If this spec is constant, this is the value of the constant;
- * otherwise it is zero.
- */
- int value;
-
- /** A list of tokens in the expression. */
- PosToken *tokens;
-
- /** How many tokens are in the tokens list. */
- int n_tokens;
-
- /** Does the expression contain any variables? */
- gboolean constant : 1;
-} MetaDrawSpec;
-
-/**
- * A single drawing operation in our simple vector drawing language.
- */
-struct _MetaDrawOp
-{
- MetaDrawType type;
-
- /* Positions are strings because they can be expressions */
- union
- {
- struct {
- MetaColorSpec *color_spec;
- int dash_on_length;
- int dash_off_length;
- int width;
- MetaDrawSpec *x1;
- MetaDrawSpec *y1;
- MetaDrawSpec *x2;
- MetaDrawSpec *y2;
- } line;
-
- struct {
- MetaColorSpec *color_spec;
- gboolean filled;
- MetaDrawSpec *x;
- MetaDrawSpec *y;
- MetaDrawSpec *width;
- MetaDrawSpec *height;
- } rectangle;
-
- struct {
- MetaColorSpec *color_spec;
- gboolean filled;
- MetaDrawSpec *x;
- MetaDrawSpec *y;
- MetaDrawSpec *width;
- MetaDrawSpec *height;
- double start_angle;
- double extent_angle;
- } arc;
-
- struct {
- MetaDrawSpec *x;
- MetaDrawSpec *y;
- MetaDrawSpec *width;
- MetaDrawSpec *height;
- } clip;
-
- struct {
- MetaColorSpec *color_spec;
- MetaAlphaGradientSpec *alpha_spec;
- MetaDrawSpec *x;
- MetaDrawSpec *y;
- MetaDrawSpec *width;
- MetaDrawSpec *height;
- } tint;
-
- struct {
- MetaGradientSpec *gradient_spec;
- MetaAlphaGradientSpec *alpha_spec;
- MetaDrawSpec *x;
- MetaDrawSpec *y;
- MetaDrawSpec *width;
- MetaDrawSpec *height;
- } gradient;
-
- struct {
- MetaColorSpec *colorize_spec;
- MetaAlphaGradientSpec *alpha_spec;
- GdkPixbuf *pixbuf;
- MetaDrawSpec *x;
- MetaDrawSpec *y;
- MetaDrawSpec *width;
- MetaDrawSpec *height;
-
- guint32 colorize_cache_pixel;
- GdkPixbuf *colorize_cache_pixbuf;
- MetaImageFillType fill_type;
- unsigned int vertical_stripes : 1;
- unsigned int horizontal_stripes : 1;
- } image;
-
- struct {
- GtkStateType state;
- GtkShadowType shadow;
- GtkArrowType arrow;
- gboolean filled;
-
- MetaDrawSpec *x;
- MetaDrawSpec *y;
- MetaDrawSpec *width;
- MetaDrawSpec *height;
- } gtk_arrow;
-
- struct {
- GtkStateType state;
- GtkShadowType shadow;
- MetaDrawSpec *x;
- MetaDrawSpec *y;
- MetaDrawSpec *width;
- MetaDrawSpec *height;
- } gtk_box;
-
- struct {
- GtkStateType state;
- MetaDrawSpec *x;
- MetaDrawSpec *y1;
- MetaDrawSpec *y2;
- } gtk_vline;
-
- struct {
- MetaAlphaGradientSpec *alpha_spec;
- MetaDrawSpec *x;
- MetaDrawSpec *y;
- MetaDrawSpec *width;
- MetaDrawSpec *height;
- MetaImageFillType fill_type;
- } icon;
-
- struct {
- MetaColorSpec *color_spec;
- MetaDrawSpec *x;
- MetaDrawSpec *y;
- } title;
-
- struct {
- MetaDrawOpList *op_list;
- MetaDrawSpec *x;
- MetaDrawSpec *y;
- MetaDrawSpec *width;
- MetaDrawSpec *height;
- } op_list;
-
- struct {
- MetaDrawOpList *op_list;
- MetaDrawSpec *x;
- MetaDrawSpec *y;
- MetaDrawSpec *width;
- MetaDrawSpec *height;
- MetaDrawSpec *tile_xoffset;
- MetaDrawSpec *tile_yoffset;
- MetaDrawSpec *tile_width;
- MetaDrawSpec *tile_height;
- } tile;
-
- } data;
-};
-
-/**
- * A list of MetaDrawOp objects. Maintains a reference count.
- * Grows as necessary and allows the allocation of unused spaces
- * to keep reallocations to a minimum.
- *
- * \bug Do we really win anything from not using the equivalent
- * GLib structures?
- */
-struct _MetaDrawOpList
-{
- int refcount;
- MetaDrawOp **ops;
- int n_ops;
- int n_allocated;
-};
-
-typedef enum
-{
- META_BUTTON_STATE_NORMAL,
- META_BUTTON_STATE_PRESSED,
- META_BUTTON_STATE_PRELIGHT,
- META_BUTTON_STATE_LAST
-} MetaButtonState;
-
-typedef enum
-{
- /* Ordered so that background is drawn first */
- META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND,
- META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND,
- META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND,
- META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND,
- META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND,
- META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND,
- META_BUTTON_TYPE_CLOSE,
- META_BUTTON_TYPE_MAXIMIZE,
- META_BUTTON_TYPE_MINIMIZE,
- META_BUTTON_TYPE_MENU,
- META_BUTTON_TYPE_SHADE,
- META_BUTTON_TYPE_ABOVE,
- META_BUTTON_TYPE_STICK,
- META_BUTTON_TYPE_UNSHADE,
- META_BUTTON_TYPE_UNABOVE,
- META_BUTTON_TYPE_UNSTICK,
- META_BUTTON_TYPE_LAST
-} MetaButtonType;
-
-typedef enum
-{
- META_MENU_ICON_TYPE_CLOSE,
- META_MENU_ICON_TYPE_MAXIMIZE,
- META_MENU_ICON_TYPE_UNMAXIMIZE,
- META_MENU_ICON_TYPE_MINIMIZE,
- META_MENU_ICON_TYPE_LAST
-} MetaMenuIconType;
-
-typedef enum
-{
- /* Listed in the order in which the textures are drawn.
- * (though this only matters for overlaps of course.)
- * Buttons are drawn after the frame textures.
- *
- * On the corners, horizontal pieces are arbitrarily given the
- * corner area:
- *
- * ===== |====
- * | |
- * | rather than |
- *
- */
-
- /* entire frame */
- META_FRAME_PIECE_ENTIRE_BACKGROUND,
- /* entire titlebar background */
- META_FRAME_PIECE_TITLEBAR,
- /* portion of the titlebar background inside the titlebar
- * background edges
- */
- META_FRAME_PIECE_TITLEBAR_MIDDLE,
- /* left end of titlebar */
- META_FRAME_PIECE_LEFT_TITLEBAR_EDGE,
- /* right end of titlebar */
- META_FRAME_PIECE_RIGHT_TITLEBAR_EDGE,
- /* top edge of titlebar */
- META_FRAME_PIECE_TOP_TITLEBAR_EDGE,
- /* bottom edge of titlebar */
- META_FRAME_PIECE_BOTTOM_TITLEBAR_EDGE,
- /* render over title background (text area) */
- META_FRAME_PIECE_TITLE,
- /* left edge of the frame */
- META_FRAME_PIECE_LEFT_EDGE,
- /* right edge of the frame */
- META_FRAME_PIECE_RIGHT_EDGE,
- /* bottom edge of the frame */
- META_FRAME_PIECE_BOTTOM_EDGE,
- /* place over entire frame, after drawing everything else */
- META_FRAME_PIECE_OVERLAY,
- /* Used to get size of the enum */
- META_FRAME_PIECE_LAST
-} MetaFramePiece;
-
-#define N_GTK_STATES 5
-
-/**
- * How to draw a frame in a particular state (say, a focussed, non-maximised,
- * resizable frame). This corresponds closely to the <frame_style> tag
- * in a theme file.
- */
-struct _MetaFrameStyle
-{
- /** Reference count. */
- int refcount;
- /**
- * Parent style.
- * Settings which are unspecified here will be taken from there.
- */
- MetaFrameStyle *parent;
- /** Operations for drawing each kind of button in each state. */
- MetaDrawOpList *buttons[META_BUTTON_TYPE_LAST][META_BUTTON_STATE_LAST];
- /** Operations for drawing each piece of the frame. */
- MetaDrawOpList *pieces[META_FRAME_PIECE_LAST];
- /**
- * Details such as the height and width of each edge, the corner rounding,
- * and the aspect ratio of the buttons.
- */
- MetaFrameLayout *layout;
- /**
- * Background colour of the window. Only present in theme formats
- * 2 and above. Can be NULL to use the standard GTK theme engine.
- */
- MetaColorSpec *window_background_color;
- /**
- * Transparency of the window background. 0=transparent; 255=opaque.
- */
- guint8 window_background_alpha;
-};
-
-/* Kinds of frame...
- *
- * normal -> noresize / vert only / horz only / both
- * focused / unfocused
- * max -> focused / unfocused
- * shaded -> focused / unfocused
- * max/shaded -> focused / unfocused
- *
- * so 4 states with 8 sub-states in one, 2 sub-states in the other 3,
- * meaning 14 total
- *
- * 14 window states times 7 or 8 window types. Except some
- * window types never get a frame so that narrows it down a bit.
- *
- */
-typedef enum
-{
- META_FRAME_STATE_NORMAL,
- META_FRAME_STATE_MAXIMIZED,
- META_FRAME_STATE_SHADED,
- META_FRAME_STATE_MAXIMIZED_AND_SHADED,
- META_FRAME_STATE_LAST
-} MetaFrameState;
-
-typedef enum
-{
- META_FRAME_RESIZE_NONE,
- META_FRAME_RESIZE_VERTICAL,
- META_FRAME_RESIZE_HORIZONTAL,
- META_FRAME_RESIZE_BOTH,
- META_FRAME_RESIZE_LAST
-} MetaFrameResize;
-
-typedef enum
-{
- META_FRAME_FOCUS_NO,
- META_FRAME_FOCUS_YES,
- META_FRAME_FOCUS_LAST
-} MetaFrameFocus;
-
-/**
- * How to draw frames at different times: when it's maximised or not, shaded
- * or not, when it's focussed or not, and (for non-maximised windows), when
- * it can be horizontally or vertically resized, both, or neither.
- * Not all window types actually get a frame.
- *
- * A theme contains one of these objects for each type of window (each
- * MetaFrameType), that is, normal, dialogue (modal and non-modal), etc.
- *
- * This corresponds closely to the <frame_style_set> tag in a theme file.
- */
-struct _MetaFrameStyleSet
-{
- int refcount;
- MetaFrameStyleSet *parent;
- MetaFrameStyle *normal_styles[META_FRAME_RESIZE_LAST][META_FRAME_FOCUS_LAST];
- MetaFrameStyle *maximized_styles[META_FRAME_FOCUS_LAST];
- MetaFrameStyle *shaded_styles[META_FRAME_RESIZE_LAST][META_FRAME_FOCUS_LAST];
- MetaFrameStyle *maximized_and_shaded_styles[META_FRAME_FOCUS_LAST];
-};
-
-/**
- * A theme. This is a singleton class which groups all settings from a theme
- * on disk together.
- *
- * \bug It is rather useless to keep the metadata fields in core, I think.
- */
-struct _MetaTheme
-{
- /** Name of the theme (on disk), e.g. "Crux" */
- char *name;
- /** Path to the files associated with the theme */
- char *dirname;
- /**
- * Filename of the XML theme file.
- * \bug Kept lying around for no discernable reason.
- */
- char *filename;
- /** Metadata: Human-readable name of the theme. */
- char *readable_name;
- /** Metadata: Author of the theme. */
- char *author;
- /** Metadata: Copyright holder. */
- char *copyright;
- /** Metadata: Date of the theme. */
- char *date;
- /** Metadata: Description of the theme. */
- char *description;
- /** Version of the theme format. Older versions cannot use the features
- * of newer versions even if they think they can (this is to allow forward
- * and backward compatibility.
- */
- guint format_version;
-
- /** Symbol table of integer constants. */
- GHashTable *integer_constants;
- /** Symbol table of float constants. */
- GHashTable *float_constants;
- /**
- * Symbol table of colour constants (hex triples, and triples
- * plus alpha).
- * */
- GHashTable *color_constants;
- GHashTable *images_by_filename;
- GHashTable *layouts_by_name;
- GHashTable *draw_op_lists_by_name;
- GHashTable *styles_by_name;
- GHashTable *style_sets_by_name;
- MetaFrameStyleSet *style_sets_by_type[META_FRAME_TYPE_LAST];
-
- GQuark quark_width;
- GQuark quark_height;
- GQuark quark_object_width;
- GQuark quark_object_height;
- GQuark quark_left_width;
- GQuark quark_right_width;
- GQuark quark_top_height;
- GQuark quark_bottom_height;
- GQuark quark_mini_icon_width;
- GQuark quark_mini_icon_height;
- GQuark quark_icon_width;
- GQuark quark_icon_height;
- GQuark quark_title_width;
- GQuark quark_title_height;
-};
-
-struct _MetaPositionExprEnv
-{
- MetaRectangle rect;
- /* size of an object being drawn, if it has a natural size */
- int object_width;
- int object_height;
- /* global object sizes, always available */
- int left_width;
- int right_width;
- int top_height;
- int bottom_height;
- int title_width;
- int title_height;
- int mini_icon_width;
- int mini_icon_height;
- int icon_width;
- int icon_height;
- /* Theme so we can look up constants */
- MetaTheme *theme;
-};
-
-MetaFrameLayout* meta_frame_layout_new (void);
-MetaFrameLayout* meta_frame_layout_copy (const MetaFrameLayout *src);
-void meta_frame_layout_ref (MetaFrameLayout *layout);
-void meta_frame_layout_unref (MetaFrameLayout *layout);
-void meta_frame_layout_get_borders (const MetaFrameLayout *layout,
- int text_height,
- MetaFrameFlags flags,
- int *top_height,
- int *bottom_height,
- int *left_width,
- int *right_width);
-void meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
- int text_height,
- MetaFrameFlags flags,
- int client_width,
- int client_height,
- const MetaButtonLayout *button_layout,
- MetaFrameGeometry *fgeom,
- MetaTheme *theme);
-
-gboolean meta_frame_layout_validate (const MetaFrameLayout *layout,
- GError **error);
-
-gboolean meta_parse_position_expression (MetaDrawSpec *spec,
- const MetaPositionExprEnv *env,
- int *x_return,
- int *y_return,
- GError **err);
-gboolean meta_parse_size_expression (MetaDrawSpec *spec,
- const MetaPositionExprEnv *env,
- int *val_return,
- GError **err);
-
-MetaDrawSpec* meta_draw_spec_new (MetaTheme *theme,
- const char *expr,
- GError **error);
-void meta_draw_spec_free (MetaDrawSpec *spec);
-
-MetaColorSpec* meta_color_spec_new (MetaColorSpecType type);
-MetaColorSpec* meta_color_spec_new_from_string (const char *str,
- GError **err);
-MetaColorSpec* meta_color_spec_new_gtk (MetaGtkColorComponent component,
- GtkStateType state);
-void meta_color_spec_free (MetaColorSpec *spec);
-void meta_color_spec_render (MetaColorSpec *spec,
- GtkWidget *widget,
- GdkColor *color);
-
-
-MetaDrawOp* meta_draw_op_new (MetaDrawType type);
-void meta_draw_op_free (MetaDrawOp *op);
-void meta_draw_op_draw (const MetaDrawOp *op,
- GtkWidget *widget,
- GdkDrawable *drawable,
- const GdkRectangle *clip,
- const MetaDrawInfo *info,
- /* logical region being drawn */
- MetaRectangle logical_region);
-
-MetaDrawOpList* meta_draw_op_list_new (int n_preallocs);
-void meta_draw_op_list_ref (MetaDrawOpList *op_list);
-void meta_draw_op_list_unref (MetaDrawOpList *op_list);
-void meta_draw_op_list_draw (const MetaDrawOpList *op_list,
- GtkWidget *widget,
- GdkDrawable *drawable,
- const GdkRectangle *clip,
- const MetaDrawInfo *info,
- MetaRectangle rect);
-void meta_draw_op_list_append (MetaDrawOpList *op_list,
- MetaDrawOp *op);
-gboolean meta_draw_op_list_validate (MetaDrawOpList *op_list,
- GError **error);
-gboolean meta_draw_op_list_contains (MetaDrawOpList *op_list,
- MetaDrawOpList *child);
-
-MetaGradientSpec* meta_gradient_spec_new (MetaGradientType type);
-void meta_gradient_spec_free (MetaGradientSpec *desc);
-GdkPixbuf* meta_gradient_spec_render (const MetaGradientSpec *desc,
- GtkWidget *widget,
- int width,
- int height);
-gboolean meta_gradient_spec_validate (MetaGradientSpec *spec,
- GError **error);
-
-MetaAlphaGradientSpec* meta_alpha_gradient_spec_new (MetaGradientType type,
- int n_alphas);
-void meta_alpha_gradient_spec_free (MetaAlphaGradientSpec *spec);
-
-
-MetaFrameStyle* meta_frame_style_new (MetaFrameStyle *parent);
-void meta_frame_style_ref (MetaFrameStyle *style);
-void meta_frame_style_unref (MetaFrameStyle *style);
-
-void meta_frame_style_draw (MetaFrameStyle *style,
- GtkWidget *widget,
- GdkDrawable *drawable,
- int x_offset,
- int y_offset,
- const GdkRectangle *clip,
- const MetaFrameGeometry *fgeom,
- int client_width,
- int client_height,
- PangoLayout *title_layout,
- int text_height,
- MetaButtonState button_states[META_BUTTON_TYPE_LAST],
- GdkPixbuf *mini_icon,
- GdkPixbuf *icon);
-
-
-gboolean meta_frame_style_validate (MetaFrameStyle *style,
- guint current_theme_version,
- GError **error);
-
-MetaFrameStyleSet* meta_frame_style_set_new (MetaFrameStyleSet *parent);
-void meta_frame_style_set_ref (MetaFrameStyleSet *style_set);
-void meta_frame_style_set_unref (MetaFrameStyleSet *style_set);
-
-gboolean meta_frame_style_set_validate (MetaFrameStyleSet *style_set,
- GError **error);
-
-MetaTheme* meta_theme_get_current (void);
-void meta_theme_set_current (const char *name,
- gboolean force_reload);
-
-MetaTheme* meta_theme_new (void);
-void meta_theme_free (MetaTheme *theme);
-gboolean meta_theme_validate (MetaTheme *theme,
- GError **error);
-GdkPixbuf* meta_theme_load_image (MetaTheme *theme,
- const char *filename,
- guint size_of_theme_icons,
- GError **error);
-
-MetaFrameStyle* meta_theme_get_frame_style (MetaTheme *theme,
- MetaFrameType type,
- MetaFrameFlags flags);
-
-double meta_theme_get_title_scale (MetaTheme *theme,
- MetaFrameType type,
- MetaFrameFlags flags);
-
-void meta_theme_draw_frame (MetaTheme *theme,
- GtkWidget *widget,
- GdkDrawable *drawable,
- const GdkRectangle *clip,
- int x_offset,
- int y_offset,
- MetaFrameType type,
- MetaFrameFlags flags,
- int client_width,
- int client_height,
- PangoLayout *title_layout,
- int text_height,
- const MetaButtonLayout *button_layout,
- MetaButtonState button_states[META_BUTTON_TYPE_LAST],
- GdkPixbuf *mini_icon,
- GdkPixbuf *icon);
-
-void meta_theme_draw_frame_by_name (MetaTheme *theme,
- GtkWidget *widget,
- GdkDrawable *drawable,
- const GdkRectangle *clip,
- int x_offset,
- int y_offset,
- const gchar *style_name,
- MetaFrameFlags flags,
- int client_width,
- int client_height,
- PangoLayout *title_layout,
- int text_height,
- const MetaButtonLayout *button_layout,
- MetaButtonState button_states[META_BUTTON_TYPE_LAST],
- GdkPixbuf *mini_icon,
- GdkPixbuf *icon);
-
-void meta_theme_get_frame_borders (MetaTheme *theme,
- MetaFrameType type,
- int text_height,
- MetaFrameFlags flags,
- int *top_height,
- int *bottom_height,
- int *left_width,
- int *right_width);
-void meta_theme_calc_geometry (MetaTheme *theme,
- MetaFrameType type,
- int text_height,
- MetaFrameFlags flags,
- int client_width,
- int client_height,
- const MetaButtonLayout *button_layout,
- MetaFrameGeometry *fgeom);
-
-MetaFrameLayout* meta_theme_lookup_layout (MetaTheme *theme,
- const char *name);
-void meta_theme_insert_layout (MetaTheme *theme,
- const char *name,
- MetaFrameLayout *layout);
-MetaDrawOpList* meta_theme_lookup_draw_op_list (MetaTheme *theme,
- const char *name);
-void meta_theme_insert_draw_op_list (MetaTheme *theme,
- const char *name,
- MetaDrawOpList *op_list);
-MetaFrameStyle* meta_theme_lookup_style (MetaTheme *theme,
- const char *name);
-void meta_theme_insert_style (MetaTheme *theme,
- const char *name,
- MetaFrameStyle *style);
-MetaFrameStyleSet* meta_theme_lookup_style_set (MetaTheme *theme,
- const char *name);
-void meta_theme_insert_style_set (MetaTheme *theme,
- const char *name,
- MetaFrameStyleSet *style_set);
-gboolean meta_theme_define_int_constant (MetaTheme *theme,
- const char *name,
- int value,
- GError **error);
-gboolean meta_theme_lookup_int_constant (MetaTheme *theme,
- const char *name,
- int *value);
-gboolean meta_theme_define_float_constant (MetaTheme *theme,
- const char *name,
- double value,
- GError **error);
-gboolean meta_theme_lookup_float_constant (MetaTheme *theme,
- const char *name,
- double *value);
-
-gboolean meta_theme_define_color_constant (MetaTheme *theme,
- const char *name,
- const char *value,
- GError **error);
-gboolean meta_theme_lookup_color_constant (MetaTheme *theme,
- const char *name,
- char **value);
-
-gboolean meta_theme_replace_constants (MetaTheme *theme,
- PosToken *tokens,
- int n_tokens,
- GError **err);
-
-/* random stuff */
-
-PangoFontDescription* meta_gtk_widget_get_font_desc (GtkWidget *widget,
- double scale,
- const PangoFontDescription *override);
-int meta_pango_font_desc_get_text_height (const PangoFontDescription *font_desc,
- PangoContext *context);
-
-
-/* Enum converters */
-MetaGtkColorComponent meta_color_component_from_string (const char *str);
-const char* meta_color_component_to_string (MetaGtkColorComponent component);
-MetaButtonState meta_button_state_from_string (const char *str);
-const char* meta_button_state_to_string (MetaButtonState state);
-MetaButtonType meta_button_type_from_string (const char *str,
- MetaTheme *theme);
-const char* meta_button_type_to_string (MetaButtonType type);
-MetaFramePiece meta_frame_piece_from_string (const char *str);
-const char* meta_frame_piece_to_string (MetaFramePiece piece);
-MetaFrameState meta_frame_state_from_string (const char *str);
-const char* meta_frame_state_to_string (MetaFrameState state);
-MetaFrameResize meta_frame_resize_from_string (const char *str);
-const char* meta_frame_resize_to_string (MetaFrameResize resize);
-MetaFrameFocus meta_frame_focus_from_string (const char *str);
-const char* meta_frame_focus_to_string (MetaFrameFocus focus);
-MetaFrameType meta_frame_type_from_string (const char *str);
-const char* meta_frame_type_to_string (MetaFrameType type);
-MetaGradientType meta_gradient_type_from_string (const char *str);
-const char* meta_gradient_type_to_string (MetaGradientType type);
-GtkStateType meta_gtk_state_from_string (const char *str);
-const char* meta_gtk_state_to_string (GtkStateType state);
-GtkShadowType meta_gtk_shadow_from_string (const char *str);
-const char* meta_gtk_shadow_to_string (GtkShadowType shadow);
-GtkArrowType meta_gtk_arrow_from_string (const char *str);
-const char* meta_gtk_arrow_to_string (GtkArrowType arrow);
-MetaImageFillType meta_image_fill_type_from_string (const char *str);
-const char* meta_image_fill_type_to_string (MetaImageFillType fill_type);
-
-guint meta_theme_earliest_version_with_button (MetaButtonType type);
-
-
-#define META_THEME_ALLOWS(theme, feature) (theme->format_version >= feature)
-
-/* What version of the theme file format were various features introduced in? */
-#define META_THEME_SHADE_STICK_ABOVE_BUTTONS 2
-#define META_THEME_UBIQUITOUS_CONSTANTS 2
-#define META_THEME_VARIED_ROUND_CORNERS 2
-#define META_THEME_IMAGES_FROM_ICON_THEMES 2
-#define META_THEME_UNRESIZABLE_SHADED_STYLES 2
-#define META_THEME_DEGREES_IN_ARCS 2
-#define META_THEME_HIDDEN_BUTTONS 2
-#define META_THEME_COLOR_CONSTANTS 2
-#define META_THEME_FRAME_BACKGROUNDS 2
-
-#endif
diff --git a/src/ui/themewidget.c b/src/ui/themewidget.c
deleted file mode 100644
index 1cbcb8e2..00000000
--- a/src/ui/themewidget.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity theme widget (displays themed draw operations) */
-
-/*
- * Copyright (C) 2002 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "themewidget.h"
-#include <math.h>
-
-static void meta_area_class_init (MetaAreaClass *klass);
-static void meta_area_init (MetaArea *area);
-static void meta_area_size_request (GtkWidget *widget,
- GtkRequisition *req);
-static gint meta_area_expose (GtkWidget *widget,
- GdkEventExpose *event);
-static void meta_area_finalize (GObject *object);
-
-
-static GtkMiscClass *parent_class;
-
-GtkType
-meta_area_get_type (void)
-{
- static GtkType area_type = 0;
-
- if (!area_type)
- {
- static const GtkTypeInfo area_info =
- {
- "MetaArea",
- sizeof (MetaArea),
- sizeof (MetaAreaClass),
- (GtkClassInitFunc) meta_area_class_init,
- (GtkObjectInitFunc) meta_area_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- area_type = gtk_type_unique (GTK_TYPE_MISC, &area_info);
- }
-
- return area_type;
-}
-
-static void
-meta_area_class_init (MetaAreaClass *class)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (class);
- GtkObjectClass *object_class;
- GtkWidgetClass *widget_class;
-
- object_class = (GtkObjectClass*) class;
- widget_class = (GtkWidgetClass*) class;
- parent_class = gtk_type_class (gtk_misc_get_type ());
-
- gobject_class->finalize = meta_area_finalize;
-
- widget_class->expose_event = meta_area_expose;
- widget_class->size_request = meta_area_size_request;
-}
-
-static void
-meta_area_init (MetaArea *area)
-{
- GTK_WIDGET_SET_FLAGS (area, GTK_NO_WINDOW);
-}
-
-GtkWidget*
-meta_area_new (void)
-{
- MetaArea *area;
-
- area = gtk_type_new (META_TYPE_AREA);
-
- return GTK_WIDGET (area);
-}
-
-static void
-meta_area_finalize (GObject *object)
-{
- MetaArea *area;
-
- area = META_AREA (object);
-
- if (area->dnotify)
- (* area->dnotify) (area->user_data);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static gint
-meta_area_expose (GtkWidget *widget,
- GdkEventExpose *event)
-{
- MetaArea *area;
- GtkMisc *misc;
- gint x, y;
- gfloat xalign;
-
- g_return_val_if_fail (META_IS_AREA (widget), FALSE);
- g_return_val_if_fail (event != NULL, FALSE);
-
- if (GTK_WIDGET_DRAWABLE (widget))
- {
- area = META_AREA (widget);
- misc = GTK_MISC (widget);
-
- if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
- xalign = misc->xalign;
- else
- xalign = 1.0 - misc->xalign;
-
- x = floor (widget->allocation.x + misc->xpad
- + ((widget->allocation.width - widget->requisition.width) * xalign)
- + 0.5);
- y = floor (widget->allocation.y + misc->ypad
- + ((widget->allocation.height - widget->requisition.height) * misc->yalign)
- + 0.5);
-
- if (area->expose_func)
- {
- (* area->expose_func) (area, event, x, y,
- area->user_data);
- }
- }
-
- return FALSE;
-}
-
-static void
-meta_area_size_request (GtkWidget *widget,
- GtkRequisition *req)
-{
- MetaArea *area;
-
- area = META_AREA (widget);
-
- req->width = 0;
- req->height = 0;
-
- if (area->size_func)
- {
- (* area->size_func) (area, &req->width, &req->height,
- area->user_data);
- }
-}
-
-void
-meta_area_setup (MetaArea *area,
- MetaAreaSizeFunc size_func,
- MetaAreaExposeFunc expose_func,
- void *user_data,
- GDestroyNotify dnotify)
-{
- if (area->dnotify)
- (* area->dnotify) (area->user_data);
-
- area->size_func = size_func;
- area->expose_func = expose_func;
- area->user_data = user_data;
- area->dnotify = dnotify;
-
- gtk_widget_queue_resize (GTK_WIDGET (area));
-}
-
diff --git a/src/ui/themewidget.h b/src/ui/themewidget.h
deleted file mode 100644
index 1568aa86..00000000
--- a/src/ui/themewidget.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity theme widget (displays themed draw operations) */
-
-/*
- * Copyright (C) 2002 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "theme.h"
-#include <gtk/gtk.h>
-
-#ifndef META_THEME_WIDGET_H
-#define META_THEME_WIDGET_H
-
-#define META_TYPE_AREA (meta_area_get_type ())
-#define META_AREA(obj) (GTK_CHECK_CAST ((obj), META_TYPE_AREA, MetaArea))
-#define META_AREA_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), META_TYPE_AREA, MetaAreaClass))
-#define META_IS_AREA(obj) (GTK_CHECK_TYPE ((obj), META_TYPE_AREA))
-#define META_IS_AREA_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), META_TYPE_AREA))
-#define META_AREA_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), META_TYPE_AREA, MetaAreaClass))
-
-typedef struct _MetaArea MetaArea;
-typedef struct _MetaAreaClass MetaAreaClass;
-
-
-typedef void (* MetaAreaSizeFunc) (MetaArea *area,
- int *width,
- int *height,
- void *user_data);
-
-typedef void (* MetaAreaExposeFunc) (MetaArea *area,
- GdkEventExpose *event,
- int x_offset,
- int y_offset,
- void *user_data);
-
-struct _MetaArea
-{
- GtkMisc misc;
-
- MetaAreaSizeFunc size_func;
- MetaAreaExposeFunc expose_func;
- void *user_data;
- GDestroyNotify dnotify;
-};
-
-struct _MetaAreaClass
-{
- GtkMiscClass parent_class;
-};
-
-
-GtkType meta_area_get_type (void) G_GNUC_CONST;
-GtkWidget* meta_area_new (void);
-
-void meta_area_setup (MetaArea *area,
- MetaAreaSizeFunc size_func,
- MetaAreaExposeFunc expose_func,
- void *user_data,
- GDestroyNotify dnotify);
-
-
-#endif
diff --git a/src/ui/ui.c b/src/ui/ui.c
deleted file mode 100644
index 010130c0..00000000
--- a/src/ui/ui.c
+++ /dev/null
@@ -1,999 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity interface for talking to GTK+ UI module */
-
-/*
- * Copyright (C) 2002 Havoc Pennington
- * stock icon code Copyright (C) 2002 Jorn Baayen <jorn@nl.linux.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "prefs.h"
-#include "ui.h"
-#include "frames.h"
-#include "util.h"
-#include "menu.h"
-#include "core.h"
-#include "theme.h"
-
-#include "inlinepixbufs.h"
-
-#include <string.h>
-#include <stdlib.h>
-
-static void meta_stock_icons_init (void);
-static void meta_ui_accelerator_parse (const char *accel,
- guint *keysym,
- guint *keycode,
- GdkModifierType *keymask);
-
-struct _MetaUI
-{
- Display *xdisplay;
- Screen *xscreen;
- MetaFrames *frames;
-};
-
-void
-meta_ui_init (int *argc, char ***argv)
-{
- if (!gtk_init_check (argc, argv))
- meta_fatal ("Unable to open X display %s\n", XDisplayName (NULL));
-
- meta_stock_icons_init ();
-}
-
-Display*
-meta_ui_get_display (void)
-{
- return gdk_display;
-}
-
-typedef struct _EventFunc EventFunc;
-
-struct _EventFunc
-{
- MetaEventFunc func;
- gpointer data;
-};
-
-static EventFunc *ef = NULL;
-
-static GdkFilterReturn
-filter_func (GdkXEvent *xevent,
- GdkEvent *event,
- gpointer data)
-{
- g_return_val_if_fail (ef != NULL, GDK_FILTER_CONTINUE);
-
- if ((* ef->func) (xevent, ef->data))
- return GDK_FILTER_REMOVE;
- else
- return GDK_FILTER_CONTINUE;
-}
-
-void
-meta_ui_add_event_func (Display *xdisplay,
- MetaEventFunc func,
- gpointer data)
-{
- g_return_if_fail (ef == NULL);
-
- ef = g_new (EventFunc, 1);
- ef->func = func;
- ef->data = data;
-
- gdk_window_add_filter (NULL, filter_func, ef);
-}
-
-/* removal is by data due to proxy function */
-void
-meta_ui_remove_event_func (Display *xdisplay,
- MetaEventFunc func,
- gpointer data)
-{
- g_return_if_fail (ef != NULL);
-
- gdk_window_remove_filter (NULL, filter_func, ef);
-
- g_free (ef);
- ef = NULL;
-}
-
-MetaUI*
-meta_ui_new (Display *xdisplay,
- Screen *screen)
-{
- MetaUI *ui;
-
- ui = g_new (MetaUI, 1);
- ui->xdisplay = xdisplay;
- ui->xscreen = screen;
-
- g_assert (xdisplay == gdk_display);
- ui->frames = meta_frames_new (XScreenNumberOfScreen (screen));
- gtk_widget_realize (GTK_WIDGET (ui->frames));
-
- return ui;
-}
-
-void
-meta_ui_free (MetaUI *ui)
-{
- gtk_widget_destroy (GTK_WIDGET (ui->frames));
-
- g_free (ui);
-}
-
-void
-meta_ui_get_frame_geometry (MetaUI *ui,
- Window frame_xwindow,
- int *top_height, int *bottom_height,
- int *left_width, int *right_width)
-{
- meta_frames_get_geometry (ui->frames, frame_xwindow,
- top_height, bottom_height,
- left_width, right_width);
-}
-
-Window
-meta_ui_create_frame_window (MetaUI *ui,
- Display *xdisplay,
- Visual *xvisual,
- gint x,
- gint y,
- gint width,
- gint height,
- gint screen_no)
-{
- GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay);
- GdkScreen *screen = gdk_display_get_screen (display, screen_no);
- GdkWindowAttr attrs;
- gint attributes_mask;
- GdkWindow *window;
- GdkVisual *visual;
- GdkColormap *cmap = gdk_screen_get_default_colormap (screen);
-
- /* Default depth/visual handles clients with weird visuals; they can
- * always be children of the root depth/visual obviously, but
- * e.g. DRI games can't be children of a parent that has the same
- * visual as the client.
- */
- if (!xvisual)
- visual = gdk_screen_get_system_visual (screen);
- else
- {
- visual = gdk_x11_screen_lookup_visual (screen,
- XVisualIDFromVisual (xvisual));
- cmap = gdk_colormap_new (visual, FALSE);
- }
-
- attrs.title = NULL;
-
- /* frame.c is going to replace the event mask immediately, but
- * we still have to set it here to let GDK know what it is.
- */
- attrs.event_mask =
- GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
- GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK |
- GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK;
- attrs.x = x;
- attrs.y = y;
- attrs.wclass = GDK_INPUT_OUTPUT;
- attrs.visual = visual;
- attrs.colormap = cmap;
- attrs.window_type = GDK_WINDOW_CHILD;
- attrs.cursor = NULL;
- attrs.wmclass_name = NULL;
- attrs.wmclass_class = NULL;
- attrs.override_redirect = FALSE;
-
- attrs.width = width;
- attrs.height = height;
-
- attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-
- window =
- gdk_window_new (gdk_screen_get_root_window(screen),
- &attrs, attributes_mask);
-
- gdk_window_resize (window, width, height);
-
- meta_frames_manage_window (ui->frames, GDK_WINDOW_XID (window), window);
-
- return GDK_WINDOW_XID (window);
-}
-
-void
-meta_ui_destroy_frame_window (MetaUI *ui,
- Window xwindow)
-{
- meta_frames_unmanage_window (ui->frames, xwindow);
-}
-
-void
-meta_ui_move_resize_frame (MetaUI *ui,
- Window frame,
- int x,
- int y,
- int width,
- int height)
-{
- meta_frames_move_resize_frame (ui->frames, frame, x, y, width, height);
-}
-
-void
-meta_ui_map_frame (MetaUI *ui,
- Window xwindow)
-{
- GdkWindow *window;
-
- window = gdk_xid_table_lookup (xwindow);
-
- if (window)
- gdk_window_show_unraised (window);
-}
-
-void
-meta_ui_unmap_frame (MetaUI *ui,
- Window xwindow)
-{
- GdkWindow *window;
-
- window = gdk_xid_table_lookup (xwindow);
-
- if (window)
- gdk_window_hide (window);
-}
-
-void
-meta_ui_unflicker_frame_bg (MetaUI *ui,
- Window xwindow,
- int target_width,
- int target_height)
-{
- meta_frames_unflicker_bg (ui->frames, xwindow,
- target_width, target_height);
-}
-
-void
-meta_ui_repaint_frame (MetaUI *ui,
- Window xwindow)
-{
- meta_frames_repaint_frame (ui->frames, xwindow);
-}
-
-void
-meta_ui_reset_frame_bg (MetaUI *ui,
- Window xwindow)
-{
- meta_frames_reset_bg (ui->frames, xwindow);
-}
-
-void
-meta_ui_apply_frame_shape (MetaUI *ui,
- Window xwindow,
- int new_window_width,
- int new_window_height,
- gboolean window_has_shape)
-{
- meta_frames_apply_shapes (ui->frames, xwindow,
- new_window_width, new_window_height,
- window_has_shape);
-}
-
-void
-meta_ui_queue_frame_draw (MetaUI *ui,
- Window xwindow)
-{
- meta_frames_queue_draw (ui->frames, xwindow);
-}
-
-
-void
-meta_ui_set_frame_title (MetaUI *ui,
- Window xwindow,
- const char *title)
-{
- meta_frames_set_title (ui->frames, xwindow, title);
-}
-
-MetaWindowMenu*
-meta_ui_window_menu_new (MetaUI *ui,
- Window client_xwindow,
- MetaMenuOp ops,
- MetaMenuOp insensitive,
- unsigned long active_workspace,
- int n_workspaces,
- MetaWindowMenuFunc func,
- gpointer data)
-{
- return meta_window_menu_new (ui->frames,
- ops, insensitive,
- client_xwindow,
- active_workspace,
- n_workspaces,
- func, data);
-}
-
-void
-meta_ui_window_menu_popup (MetaWindowMenu *menu,
- int root_x,
- int root_y,
- int button,
- guint32 timestamp)
-{
- meta_window_menu_popup (menu, root_x, root_y, button, timestamp);
-}
-
-void
-meta_ui_window_menu_free (MetaWindowMenu *menu)
-{
- meta_window_menu_free (menu);
-}
-
-struct _MetaImageWindow
-{
- GtkWidget *window;
- GdkPixmap *pixmap;
-};
-
-MetaImageWindow*
-meta_image_window_new (Display *xdisplay,
- int screen_number,
- int max_width,
- int max_height)
-{
- MetaImageWindow *iw;
- GdkDisplay *gdisplay;
- GdkScreen *gscreen;
-
- iw = g_new (MetaImageWindow, 1);
- iw->window = gtk_window_new (GTK_WINDOW_POPUP);
-
- gdisplay = gdk_x11_lookup_xdisplay (xdisplay);
- gscreen = gdk_display_get_screen (gdisplay, screen_number);
-
- gtk_window_set_screen (GTK_WINDOW (iw->window), gscreen);
-
- gtk_widget_realize (iw->window);
- iw->pixmap = gdk_pixmap_new (iw->window->window,
- max_width, max_height,
- -1);
-
- gtk_widget_set_size_request (iw->window, 1, 1);
- gtk_widget_set_double_buffered (iw->window, FALSE);
- gtk_widget_set_app_paintable (iw->window, TRUE);
-
- return iw;
-}
-
-void
-meta_image_window_free (MetaImageWindow *iw)
-{
- gtk_widget_destroy (iw->window);
- g_object_unref (G_OBJECT (iw->pixmap));
- g_free (iw);
-}
-
-void
-meta_image_window_set_showing (MetaImageWindow *iw,
- gboolean showing)
-{
- if (showing)
- gtk_widget_show_all (iw->window);
- else
- {
- gtk_widget_hide (iw->window);
- meta_core_increment_event_serial (gdk_display);
- }
-}
-
-void
-meta_image_window_set (MetaImageWindow *iw,
- GdkPixbuf *pixbuf,
- int x,
- int y)
-{
- /* We use a back pixmap to avoid having to handle exposes, because
- * it's really too slow for large clients being minimized, etc.
- * and this way flicker is genuinely zero.
- */
-
- gdk_draw_pixbuf (iw->pixmap,
- iw->window->style->black_gc,
- pixbuf,
- 0, 0,
- 0, 0,
- gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf),
- GDK_RGB_DITHER_NORMAL,
- 0, 0);
-
- gdk_window_set_back_pixmap (iw->window->window,
- iw->pixmap,
- FALSE);
-
- gdk_window_move_resize (iw->window->window,
- x, y,
- gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf));
-
- gdk_window_clear (iw->window->window);
-}
-
-static GdkColormap*
-get_cmap (GdkPixmap *pixmap)
-{
- GdkColormap *cmap;
-
- cmap = gdk_drawable_get_colormap (pixmap);
- if (cmap)
- g_object_ref (G_OBJECT (cmap));
-
- if (cmap == NULL)
- {
- if (gdk_drawable_get_depth (pixmap) == 1)
- {
- meta_verbose ("Using NULL colormap for snapshotting bitmap\n");
- cmap = NULL;
- }
- else
- {
- meta_verbose ("Using system cmap to snapshot pixmap\n");
- cmap = gdk_screen_get_system_colormap (gdk_drawable_get_screen (pixmap));
-
- g_object_ref (G_OBJECT (cmap));
- }
- }
-
- /* Be sure we aren't going to blow up due to visual mismatch */
- if (cmap &&
- (gdk_colormap_get_visual (cmap)->depth !=
- gdk_drawable_get_depth (pixmap)))
- {
- cmap = NULL;
- meta_verbose ("Switching back to NULL cmap because of depth mismatch\n");
- }
-
- return cmap;
-}
-
-GdkPixbuf*
-meta_gdk_pixbuf_get_from_window (GdkPixbuf *dest,
- Window xwindow,
- int src_x,
- int src_y,
- int dest_x,
- int dest_y,
- int width,
- int height)
-{
- GdkDrawable *drawable;
- GdkPixbuf *retval;
- GdkColormap *cmap;
-
- retval = NULL;
-
- drawable = gdk_xid_table_lookup (xwindow);
-
- if (drawable)
- g_object_ref (G_OBJECT (drawable));
- else
- drawable = gdk_window_foreign_new (xwindow);
-
- cmap = get_cmap (drawable);
-
- retval = gdk_pixbuf_get_from_drawable (dest,
- drawable,
- cmap,
- src_x, src_y,
- dest_x, dest_y,
- width, height);
-
- if (cmap)
- g_object_unref (G_OBJECT (cmap));
- g_object_unref (G_OBJECT (drawable));
-
- return retval;
-}
-
-GdkPixbuf*
-meta_gdk_pixbuf_get_from_pixmap (GdkPixbuf *dest,
- Pixmap xpixmap,
- int src_x,
- int src_y,
- int dest_x,
- int dest_y,
- int width,
- int height)
-{
- GdkDrawable *drawable;
- GdkPixbuf *retval;
- GdkColormap *cmap;
-
- retval = NULL;
- cmap = NULL;
-
- drawable = gdk_xid_table_lookup (xpixmap);
-
- if (drawable)
- g_object_ref (G_OBJECT (drawable));
- else
- drawable = gdk_pixmap_foreign_new (xpixmap);
-
- if (drawable)
- {
- cmap = get_cmap (drawable);
-
- retval = gdk_pixbuf_get_from_drawable (dest,
- drawable,
- cmap,
- src_x, src_y,
- dest_x, dest_y,
- width, height);
- }
- if (cmap)
- g_object_unref (G_OBJECT (cmap));
- if (drawable)
- g_object_unref (G_OBJECT (drawable));
-
- return retval;
-}
-
-void
-meta_ui_push_delay_exposes (MetaUI *ui)
-{
- meta_frames_push_delay_exposes (ui->frames);
-}
-
-void
-meta_ui_pop_delay_exposes (MetaUI *ui)
-{
- meta_frames_pop_delay_exposes (ui->frames);
-}
-
-GdkPixbuf*
-meta_ui_get_default_window_icon (MetaUI *ui)
-{
- static GdkPixbuf *default_icon = NULL;
-
- if (default_icon == NULL)
- {
- GtkIconTheme *theme;
- gboolean icon_exists;
-
- theme = gtk_icon_theme_get_default ();
-
- icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME);
-
- if (icon_exists)
- default_icon = gtk_icon_theme_load_icon (theme,
- META_DEFAULT_ICON_NAME,
- META_ICON_WIDTH,
- 0,
- NULL);
- else
- default_icon = gtk_icon_theme_load_icon (theme,
- "gtk-missing-image",
- META_ICON_WIDTH,
- 0,
- NULL);
-
- g_assert (default_icon);
- }
-
- g_object_ref (G_OBJECT (default_icon));
-
- return default_icon;
-}
-
-GdkPixbuf*
-meta_ui_get_default_mini_icon (MetaUI *ui)
-{
- static GdkPixbuf *default_icon = NULL;
-
- if (default_icon == NULL)
- {
- GtkIconTheme *theme;
- gboolean icon_exists;
-
- theme = gtk_icon_theme_get_default ();
-
- icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME);
-
- if (icon_exists)
- default_icon = gtk_icon_theme_load_icon (theme,
- META_DEFAULT_ICON_NAME,
- META_MINI_ICON_WIDTH,
- 0,
- NULL);
- else
- default_icon = gtk_icon_theme_load_icon (theme,
- "gtk-missing-image",
- META_MINI_ICON_WIDTH,
- 0,
- NULL);
-
- g_assert (default_icon);
- }
-
- g_object_ref (G_OBJECT (default_icon));
-
- return default_icon;
-}
-
-gboolean
-meta_ui_window_should_not_cause_focus (Display *xdisplay,
- Window xwindow)
-{
- GdkWindow *window;
-
- window = gdk_xid_table_lookup (xwindow);
-
- /* we shouldn't cause focus if we're an override redirect
- * toplevel which is not foreign
- */
- if (window && gdk_window_get_type (window) == GDK_WINDOW_TEMP)
- return TRUE;
- else
- return FALSE;
-}
-
-char*
-meta_text_property_to_utf8 (Display *xdisplay,
- const XTextProperty *prop)
-{
- char **list;
- int count;
- char *retval;
-
- list = NULL;
-
- count = gdk_text_property_to_utf8_list (gdk_x11_xatom_to_atom (prop->encoding),
- prop->format,
- prop->value,
- prop->nitems,
- &list);
-
- if (count == 0)
- return NULL;
-
- retval = list[0];
- list[0] = g_strdup (""); /* something to free */
-
- g_strfreev (list);
-
- return retval;
-}
-
-void
-meta_ui_theme_get_frame_borders (MetaUI *ui,
- MetaFrameType type,
- MetaFrameFlags flags,
- int *top_height,
- int *bottom_height,
- int *left_width,
- int *right_width)
-{
- int text_height;
- PangoContext *context;
- const PangoFontDescription *font_desc;
- GtkStyle *default_style;
-
- if (meta_ui_have_a_theme ())
- {
- context = gtk_widget_get_pango_context (GTK_WIDGET (ui->frames));
- font_desc = meta_prefs_get_titlebar_font ();
-
- if (!font_desc)
- {
- default_style = gtk_widget_get_default_style ();
- font_desc = default_style->font_desc;
- }
-
- text_height = meta_pango_font_desc_get_text_height (font_desc, context);
-
- meta_theme_get_frame_borders (meta_theme_get_current (),
- type, text_height, flags,
- top_height, bottom_height,
- left_width, right_width);
- }
- else
- {
- *top_height = *bottom_height = *left_width = *right_width = 0;
- }
-}
-
-void
-meta_ui_set_current_theme (const char *name,
- gboolean force_reload)
-{
- meta_theme_set_current (name, force_reload);
- meta_invalidate_default_icons ();
-}
-
-gboolean
-meta_ui_have_a_theme (void)
-{
- return meta_theme_get_current () != NULL;
-}
-
-static void
-meta_ui_accelerator_parse (const char *accel,
- guint *keysym,
- guint *keycode,
- GdkModifierType *keymask)
-{
- if (accel[0] == '0' && accel[1] == 'x')
- {
- *keysym = 0;
- *keycode = (guint) strtoul (accel, NULL, 16);
- *keymask = 0;
- }
- else
- gtk_accelerator_parse (accel, keysym, keymask);
-}
-
-gboolean
-meta_ui_parse_accelerator (const char *accel,
- unsigned int *keysym,
- unsigned int *keycode,
- MetaVirtualModifier *mask)
-{
- GdkModifierType gdk_mask = 0;
- guint gdk_sym = 0;
- guint gdk_code = 0;
-
- *keysym = 0;
- *keycode = 0;
- *mask = 0;
-
- if (strcmp (accel, "disabled") == 0)
- return TRUE;
-
- meta_ui_accelerator_parse (accel, &gdk_sym, &gdk_code, &gdk_mask);
- if (gdk_mask == 0 && gdk_sym == 0 && gdk_code == 0)
- return FALSE;
-
- if (gdk_sym == None && gdk_code == 0)
- return FALSE;
-
- if (gdk_mask & GDK_RELEASE_MASK) /* we don't allow this */
- return FALSE;
-
- *keysym = gdk_sym;
- *keycode = gdk_code;
-
- if (gdk_mask & GDK_SHIFT_MASK)
- *mask |= META_VIRTUAL_SHIFT_MASK;
- if (gdk_mask & GDK_CONTROL_MASK)
- *mask |= META_VIRTUAL_CONTROL_MASK;
- if (gdk_mask & GDK_MOD1_MASK)
- *mask |= META_VIRTUAL_ALT_MASK;
- if (gdk_mask & GDK_MOD2_MASK)
- *mask |= META_VIRTUAL_MOD2_MASK;
- if (gdk_mask & GDK_MOD3_MASK)
- *mask |= META_VIRTUAL_MOD3_MASK;
- if (gdk_mask & GDK_MOD4_MASK)
- *mask |= META_VIRTUAL_MOD4_MASK;
- if (gdk_mask & GDK_MOD5_MASK)
- *mask |= META_VIRTUAL_MOD5_MASK;
- if (gdk_mask & GDK_SUPER_MASK)
- *mask |= META_VIRTUAL_SUPER_MASK;
- if (gdk_mask & GDK_HYPER_MASK)
- *mask |= META_VIRTUAL_HYPER_MASK;
- if (gdk_mask & GDK_META_MASK)
- *mask |= META_VIRTUAL_META_MASK;
-
- return TRUE;
-}
-
-/* Caller responsible for freeing return string of meta_ui_accelerator_name! */
-gchar*
-meta_ui_accelerator_name (unsigned int keysym,
- MetaVirtualModifier mask)
-{
- GdkModifierType mods = 0;
-
- if (keysym == 0 && mask == 0)
- {
- return g_strdup ("disabled");
- }
-
- if (mask & META_VIRTUAL_SHIFT_MASK)
- mods |= GDK_SHIFT_MASK;
- if (mask & META_VIRTUAL_CONTROL_MASK)
- mods |= GDK_CONTROL_MASK;
- if (mask & META_VIRTUAL_ALT_MASK)
- mods |= GDK_MOD1_MASK;
- if (mask & META_VIRTUAL_MOD2_MASK)
- mods |= GDK_MOD2_MASK;
- if (mask & META_VIRTUAL_MOD3_MASK)
- mods |= GDK_MOD3_MASK;
- if (mask & META_VIRTUAL_MOD4_MASK)
- mods |= GDK_MOD4_MASK;
- if (mask & META_VIRTUAL_MOD5_MASK)
- mods |= GDK_MOD5_MASK;
- if (mask & META_VIRTUAL_SUPER_MASK)
- mods |= GDK_SUPER_MASK;
- if (mask & META_VIRTUAL_HYPER_MASK)
- mods |= GDK_HYPER_MASK;
- if (mask & META_VIRTUAL_META_MASK)
- mods |= GDK_META_MASK;
-
- return gtk_accelerator_name (keysym, mods);
-
-}
-
-gboolean
-meta_ui_parse_modifier (const char *accel,
- MetaVirtualModifier *mask)
-{
- GdkModifierType gdk_mask = 0;
- guint gdk_sym = 0;
- guint gdk_code = 0;
-
- *mask = 0;
-
- if (accel == NULL || strcmp (accel, "disabled") == 0)
- return TRUE;
-
- meta_ui_accelerator_parse (accel, &gdk_sym, &gdk_code, &gdk_mask);
- if (gdk_mask == 0 && gdk_sym == 0 && gdk_code == 0)
- return FALSE;
-
- if (gdk_sym != None || gdk_code != 0)
- return FALSE;
-
- if (gdk_mask & GDK_RELEASE_MASK) /* we don't allow this */
- return FALSE;
-
- if (gdk_mask & GDK_SHIFT_MASK)
- *mask |= META_VIRTUAL_SHIFT_MASK;
- if (gdk_mask & GDK_CONTROL_MASK)
- *mask |= META_VIRTUAL_CONTROL_MASK;
- if (gdk_mask & GDK_MOD1_MASK)
- *mask |= META_VIRTUAL_ALT_MASK;
- if (gdk_mask & GDK_MOD2_MASK)
- *mask |= META_VIRTUAL_MOD2_MASK;
- if (gdk_mask & GDK_MOD3_MASK)
- *mask |= META_VIRTUAL_MOD3_MASK;
- if (gdk_mask & GDK_MOD4_MASK)
- *mask |= META_VIRTUAL_MOD4_MASK;
- if (gdk_mask & GDK_MOD5_MASK)
- *mask |= META_VIRTUAL_MOD5_MASK;
- if (gdk_mask & GDK_SUPER_MASK)
- *mask |= META_VIRTUAL_SUPER_MASK;
- if (gdk_mask & GDK_HYPER_MASK)
- *mask |= META_VIRTUAL_HYPER_MASK;
- if (gdk_mask & GDK_META_MASK)
- *mask |= META_VIRTUAL_META_MASK;
-
- return TRUE;
-}
-
-gboolean
-meta_ui_window_is_widget (MetaUI *ui,
- Window xwindow)
-{
- GdkWindow *window;
-
- window = gdk_xid_table_lookup (xwindow);
-
- if (window)
- {
- void *user_data = NULL;
- gdk_window_get_user_data (window, &user_data);
- return user_data != NULL && user_data != ui->frames;
- }
- else
- return FALSE;
-}
-
-/* stock icon code Copyright (C) 2002 Jorn Baayen <jorn@nl.linux.org> */
-typedef struct
-{
- char *stock_id;
- const guint8 *icon_data;
-} MetaStockIcon;
-
-static void
-meta_stock_icons_init (void)
-{
- GtkIconFactory *factory;
- int i;
-
- MetaStockIcon items[] =
- {
- { METACITY_STOCK_DELETE, stock_delete_data },
- { METACITY_STOCK_MINIMIZE, stock_minimize_data },
- { METACITY_STOCK_MAXIMIZE, stock_maximize_data }
- };
-
- factory = gtk_icon_factory_new ();
- gtk_icon_factory_add_default (factory);
-
- for (i = 0; i < (gint) G_N_ELEMENTS (items); i++)
- {
- GtkIconSet *icon_set;
- GdkPixbuf *pixbuf;
-
- pixbuf = gdk_pixbuf_new_from_inline (-1, items[i].icon_data,
- FALSE,
- NULL);
-
- icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
- gtk_icon_factory_add (factory, items[i].stock_id, icon_set);
- gtk_icon_set_unref (icon_set);
-
- g_object_unref (G_OBJECT (pixbuf));
- }
-
- g_object_unref (G_OBJECT (factory));
-}
-
-int
-meta_ui_get_drag_threshold (MetaUI *ui)
-{
- GtkSettings *settings;
- int threshold;
-
- settings = gtk_widget_get_settings (GTK_WIDGET (ui->frames));
-
- threshold = 8;
- g_object_get (G_OBJECT (settings), "gtk-dnd-drag-threshold", &threshold, NULL);
-
- return threshold;
-}
-
-MetaUIDirection
-meta_ui_get_direction (void)
-{
- if (gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL)
- return META_UI_DIRECTION_RTL;
-
- return META_UI_DIRECTION_LTR;
-}
-
-GdkPixbuf *
-meta_ui_get_pixbuf_from_pixmap (Pixmap pmap)
-{
- GdkPixmap *gpmap;
- GdkScreen *screen;
- GdkPixbuf *pixbuf;
- GdkColormap *cmap;
- int width, height, depth;
-
- gpmap = gdk_pixmap_foreign_new (pmap);
- screen = gdk_drawable_get_screen (gpmap);
-
- gdk_drawable_get_size (GDK_DRAWABLE (gpmap), &width, &height);
-
- depth = gdk_drawable_get_depth (GDK_DRAWABLE (gpmap));
- if (depth <= 24)
- cmap = gdk_screen_get_rgb_colormap (screen);
- else
- cmap = gdk_screen_get_rgba_colormap (screen);
-
- pixbuf = gdk_pixbuf_get_from_drawable (NULL, gpmap, cmap, 0, 0, 0, 0,
- width, height);
-
- g_object_unref (gpmap);
-
- return pixbuf;
-}
diff --git a/src/wm-tester/.cvsignore b/src/wm-tester/.cvsignore
deleted file mode 100644
index 0bca29e8..00000000
--- a/src/wm-tester/.cvsignore
+++ /dev/null
@@ -1,7 +0,0 @@
-Makefile
-Makefile.in
-focus-window
-test-gravity
-test-resizing
-wm-tester
-test-size-hints
diff --git a/src/wm-tester/Makefile.am b/src/wm-tester/Makefile.am
deleted file mode 100644
index e0c3048e..00000000
--- a/src/wm-tester/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-
-INCLUDES=@METACITY_CFLAGS@
-
-wm_tester_SOURCES= \
- main.c
-
-test_gravity_SOURCES= \
- test-gravity.c
-
-focus_window_SOURCES= \
- focus-window.c
-
-test_resizing_SOURCES= \
- test-resizing.c
-
-test_size_hints_SOURCES= \
- test-size-hints.c
-
-noinst_PROGRAMS=wm-tester test-gravity test-resizing focus-window test-size-hints
-
-wm_tester_LDADD= @METACITY_LIBS@
-test_gravity_LDADD= @METACITY_LIBS@
-test_resizing_LDADD= @METACITY_LIBS@
-test_size_hints_LDADD= @METACITY_LIBS@
-focus_window_LDADD= @METACITY_LIBS@ \ No newline at end of file
diff --git a/src/wm-tester/focus-window.c b/src/wm-tester/focus-window.c
deleted file mode 100644
index dc33bd25..00000000
--- a/src/wm-tester/focus-window.c
+++ /dev/null
@@ -1,37 +0,0 @@
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-int main (int argc, char **argv)
-{
- Display *d;
- Window w;
- const char *w_str;
- char *end;
-
- if (argc != 2)
- {
- fprintf (stderr, "Usage: focus-window WINDOWID\n");
- exit (1);
- }
-
- d = XOpenDisplay (NULL);
-
- w_str = argv[1];
- end = NULL;
-
- w = strtoul (w_str, &end, 16);
- if (end == w_str)
- {
- fprintf (stderr, "Usage: focus-window WINDOWID\n");
- exit (1);
- }
-
- printf ("Setting input focus to 0x%lx\n", w);
- XSetInputFocus (d, w, RevertToPointerRoot, CurrentTime);
- XFlush (d);
-
- return 0;
-}
-
diff --git a/src/wm-tester/main.c b/src/wm-tester/main.c
deleted file mode 100644
index e56d6606..00000000
--- a/src/wm-tester/main.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/* WM tester main() */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <gtk/gtk.h>
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-static void set_up_the_evil (void);
-static void set_up_icon_windows (void);
-
-static void
-usage (void)
-{
- g_print ("wm-tester [--evil] [--icon-windows]\n");
- exit (0);
-}
-
-int
-main (int argc, char **argv)
-{
- int i;
- gboolean do_evil;
- gboolean do_icon_windows;
-
- gtk_init (&argc, &argv);
-
- do_evil = FALSE;
- do_icon_windows = FALSE;
-
- i = 1;
- while (i < argc)
- {
- const char *arg = argv[i];
-
- if (strcmp (arg, "--help") == 0 ||
- strcmp (arg, "-h") == 0 ||
- strcmp (arg, "-?") == 0)
- usage ();
- else if (strcmp (arg, "--evil") == 0)
- do_evil = TRUE;
- else if (strcmp (arg, "--icon-windows") == 0)
- do_icon_windows = TRUE;
- else
- usage ();
-
- ++i;
- }
-
- /* Be sure some option was provided */
- if (! (do_evil || do_icon_windows))
- return 1;
-
- if (do_evil)
- set_up_the_evil ();
-
- if (do_icon_windows)
- set_up_icon_windows ();
-
- gtk_main ();
-
- return 0;
-}
-
-static GSList *evil_windows = NULL;
-
-static gint
-evil_timeout (gpointer data)
-{
- int i;
- int n_windows;
- int len;
- int create_count;
- int destroy_count;
-
- len = g_slist_length (evil_windows);
-
- if (len > 35)
- {
- create_count = 2;
- destroy_count = 5;
- }
- else
- {
- create_count = 5;
- destroy_count = 5;
- }
-
- /* Create some windows */
- n_windows = g_random_int_range (0, create_count);
-
- i = 0;
- while (i < n_windows)
- {
- GtkWidget *w;
- GtkWidget *c;
- int t;
- GtkWidget *parent;
-
- w = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-
- gtk_widget_set_uposition (w,
- g_random_int_range (0,
- gdk_screen_width ()),
- g_random_int_range (0,
- gdk_screen_height ()));
-
- parent = NULL;
-
- /* set transient for random window (may create all kinds of weird cycles) */
- if (len > 0)
- {
- t = g_random_int_range (- (len / 3), len);
- if (t >= 0)
- {
- parent = g_slist_nth_data (evil_windows, t);
-
- if (parent != NULL)
- gtk_window_set_transient_for (GTK_WINDOW (w), GTK_WINDOW (parent));
- }
- }
-
- if (parent != NULL)
- c = gtk_button_new_with_label ("Evil Transient!");
- else
- c = gtk_button_new_with_label ("Evil Window!");
- gtk_container_add (GTK_CONTAINER (w), c);
-
- gtk_widget_show_all (w);
-
- evil_windows = g_slist_prepend (evil_windows, w);
-
- ++i;
- }
-
- /* Destroy some windows */
- if (len > destroy_count)
- {
- n_windows = g_random_int_range (0, destroy_count);
- i = 0;
- while (i < n_windows)
- {
- GtkWidget *w;
-
- w = g_slist_nth_data (evil_windows,
- g_random_int_range (0, len));
- if (w)
- {
- --len;
- evil_windows = g_slist_remove (evil_windows, w);
- gtk_widget_destroy (w);
- }
-
- ++i;
- }
- }
-
- return TRUE;
-}
-
-static void
-set_up_the_evil (void)
-{
- g_timeout_add (400, evil_timeout, NULL);
-}
-
-static void
-set_up_icon_windows (void)
-{
- int i;
- int n_windows;
-
- /* Create some windows */
- n_windows = 9;
-
- i = 0;
- while (i < n_windows)
- {
- GtkWidget *w;
- GtkWidget *c;
- GList *icons;
- GdkPixbuf *pix;
-
- w = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- c = gtk_button_new_with_label ("Icon window");
- gtk_container_add (GTK_CONTAINER (w), c);
-
- icons = NULL;
-
- pix = gtk_widget_render_icon (w,
- GTK_STOCK_SAVE,
- GTK_ICON_SIZE_LARGE_TOOLBAR,
- NULL);
-
- icons = g_list_append (icons, pix);
-
- if (i % 2)
- {
- pix = gtk_widget_render_icon (w,
- GTK_STOCK_SAVE,
- GTK_ICON_SIZE_DIALOG,
- NULL);
- icons = g_list_append (icons, pix);
- }
-
- if (i % 3)
- {
- pix = gtk_widget_render_icon (w,
- GTK_STOCK_SAVE,
- GTK_ICON_SIZE_MENU,
- NULL);
- icons = g_list_append (icons, pix);
- }
-
- gtk_window_set_icon_list (GTK_WINDOW (w), icons);
-
- g_list_foreach (icons, (GFunc) g_object_unref, NULL);
- g_list_free (icons);
-
- gtk_widget_show_all (w);
-
- ++i;
- }
-}
diff --git a/src/wm-tester/test-gravity.c b/src/wm-tester/test-gravity.c
deleted file mode 100644
index 8e5b581c..00000000
--- a/src/wm-tester/test-gravity.c
+++ /dev/null
@@ -1,308 +0,0 @@
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <stdio.h>
-#include <string.h>
-
-static int gravities[10] = {
- NorthWestGravity,
- NorthGravity,
- NorthEastGravity,
- WestGravity,
- CenterGravity,
- EastGravity,
- SouthWestGravity,
- SouthGravity,
- SouthEastGravity,
- StaticGravity
-};
-
-typedef struct
-{
- int x, y, width, height;
-} Rectangle;
-
-static Window windows[10];
-static int doubled[10] = { 0, };
-static Rectangle window_rects[10];
-
-#define WINDOW_WIDTH 100
-#define WINDOW_HEIGHT 100
-
-static int x_offset[3] = { 0, - WINDOW_WIDTH/2, -WINDOW_WIDTH };
-static int y_offset[3] = { 0, - WINDOW_HEIGHT/2, -WINDOW_HEIGHT };
-static double screen_x_fraction[3] = { 0, 0.5, 1.0 };
-static double screen_y_fraction[3] = { 0, 0.5, 1.0 };
-static int screen_width;
-static int screen_height;
-
-static const char*
-window_gravity_to_string (int gravity)
-{
- switch (gravity)
- {
- case NorthWestGravity:
- return "NorthWestGravity";
- case NorthGravity:
- return "NorthGravity";
- case NorthEastGravity:
- return "NorthEastGravity";
- case WestGravity:
- return "WestGravity";
- case CenterGravity:
- return "CenterGravity";
- case EastGravity:
- return "EastGravity";
- case SouthWestGravity:
- return "SouthWestGravity";
- case SouthGravity:
- return "SouthGravity";
- case SouthEastGravity:
- return "SouthEastGravity";
- case StaticGravity:
- return "StaticGravity";
- default:
- return "NorthWestGravity";
- }
-}
-
-static void
-calculate_position (int i, int doubled, int *x, int *y)
-{
- if (i == 9)
- {
- *x = 150;
- *y = 150;
- }
- else
- {
- int xoff = x_offset[i % 3];
- int yoff = y_offset[i / 3];
- if (doubled)
- {
- xoff *= 2;
- yoff *= 2;
- }
-
- *x = screen_x_fraction[i % 3] * screen_width + xoff;
- *y = screen_y_fraction[i / 3] * screen_height + yoff;
- }
-}
-
-static int
-find_window (Window window)
-{
- int i;
- for (i=0; i<10; i++)
- {
- if (windows[i] == window)
- return i;
- }
-
- return -1;
-}
-
-typedef struct {
- unsigned long flags;
- unsigned long functions;
- unsigned long decorations;
- long input_mode;
- unsigned long status;
-} MotifWmHints, MwmHints;
-
-#define MWM_HINTS_FUNCTIONS (1L << 0)
-#define MWM_HINTS_DECORATIONS (1L << 1)
-#define MWM_HINTS_INPUT_MODE (1L << 2)
-#define MWM_HINTS_STATUS (1L << 3)
-
-int main (int argc, char **argv)
-{
- Display *d;
- Window w;
- XSizeHints hints;
- int i;
- int screen;
- XEvent ev;
- int noframes;
-
- if (argc > 1 && strcmp (argv[1], "--noframes") == 0)
- noframes = 1;
- else
- noframes = 0;
-
- d = XOpenDisplay (NULL);
-
- screen = DefaultScreen (d);
- screen_width = DisplayWidth (d, screen);
- screen_height = DisplayHeight (d, screen);
-
- for (i=0; i<10; i++)
- {
- int x, y;
-
- calculate_position (i, doubled[i], &x, &y);
-
- w = XCreateSimpleWindow (d, RootWindow (d, screen),
- x, y, WINDOW_WIDTH, WINDOW_HEIGHT, 0,
- WhitePixel (d, screen), WhitePixel (d, screen));
-
- windows[i] = w;
- window_rects[i].x = x;
- window_rects[i].y = y;
- window_rects[i].width = WINDOW_WIDTH;
- window_rects[i].height = WINDOW_HEIGHT;
-
- XSelectInput (d, w, ButtonPressMask | ExposureMask | StructureNotifyMask);
-
- hints.flags = USPosition | PMinSize | PMaxSize | PWinGravity;
-
- hints.min_width = WINDOW_WIDTH / 2;
- hints.min_height = WINDOW_HEIGHT / 2;
-
-#if 1
- /* we constrain max size below the "doubled" size so that
- * the WM will have to deal with constraints
- * at the same time it's dealing with configure request
- */
- hints.max_width = WINDOW_WIDTH * 2 - WINDOW_WIDTH / 2;
- hints.max_height = WINDOW_HEIGHT * 2 - WINDOW_HEIGHT / 2;
-#else
- hints.max_width = WINDOW_WIDTH * 2 + WINDOW_WIDTH / 2;
- hints.max_height = WINDOW_HEIGHT * 2 + WINDOW_HEIGHT / 2;
-#endif
- hints.win_gravity = gravities[i];
-
- XSetWMNormalHints (d, w, &hints);
-
- XStoreName (d, w, window_gravity_to_string (hints.win_gravity));
-
- if (noframes)
- {
- MotifWmHints mwm;
- Atom mwm_atom;
-
- mwm.decorations = 0;
- mwm.flags = MWM_HINTS_DECORATIONS;
-
- mwm_atom = XInternAtom (d, "_MOTIF_WM_HINTS", False);
-
- XChangeProperty (d, w, mwm_atom, mwm_atom,
- 32, PropModeReplace,
- (unsigned char *)&mwm,
- sizeof (MotifWmHints)/sizeof (long));
- }
-
- XMapWindow (d, w);
- }
-
- while (1)
- {
- XNextEvent (d, &ev);
-
- if (ev.xany.type == ConfigureNotify)
- {
- i = find_window (ev.xconfigure.window);
-
- if (i >= 0)
- {
- Window ignored;
-
- window_rects[i].width = ev.xconfigure.width;
- window_rects[i].height = ev.xconfigure.height;
-
- XClearArea (d, windows[i], 0, 0,
- ev.xconfigure.width,
- ev.xconfigure.height,
- True);
-
- if (!ev.xconfigure.send_event)
- XTranslateCoordinates (d, windows[i], DefaultRootWindow (d),
- 0, 0,
- &window_rects[i].x, &window_rects[i].y,
- &ignored);
- else
- {
- window_rects[i].x = ev.xconfigure.x;
- window_rects[i].y = ev.xconfigure.y;
- }
- }
- }
- else if (ev.xany.type == Expose)
- {
- i = find_window (ev.xexpose.window);
-
- if (i >= 0)
- {
- GC gc;
- XGCValues values;
- char buf[256];
-
- values.foreground = BlackPixel (d, screen);
-
- gc = XCreateGC (d, windows[i],
- GCForeground, &values);
-
- sprintf (buf,
- "%d,%d",
- window_rects[i].x,
- window_rects[i].y);
-
- XDrawString (d, windows[i], gc, 10, 15,
- buf, strlen (buf));
-
- sprintf (buf,
- "%dx%d",
- window_rects[i].width,
- window_rects[i].height);
-
- XDrawString (d, windows[i], gc, 10, 35,
- buf, strlen (buf));
-
- XFreeGC (d, gc);
- }
- }
- else if (ev.xany.type == ButtonPress)
- {
- i = find_window (ev.xbutton.window);
-
- if (i >= 0)
- {
- /* Button 1 = move, 2 = resize, 3 = both at once */
-
- if (ev.xbutton.button == Button1)
- {
- int x, y;
-
- calculate_position (i, doubled[i], &x, &y);
- XMoveWindow (d, windows[i], x, y);
- }
- else if (ev.xbutton.button == Button2)
- {
- if (doubled[i])
- XResizeWindow (d, windows[i], WINDOW_WIDTH, WINDOW_HEIGHT);
- else
- XResizeWindow (d, windows[i], WINDOW_WIDTH*2, WINDOW_HEIGHT*2);
-
- doubled[i] = !doubled[i];
- }
- else if (ev.xbutton.button == Button3)
- {
- int x, y;
-
- calculate_position (i, !doubled[i], &x, &y);
-
- if (doubled[i])
- XMoveResizeWindow (d, windows[i], x, y, WINDOW_WIDTH, WINDOW_HEIGHT);
- else
- XMoveResizeWindow (d, windows[i], x, y, WINDOW_WIDTH*2, WINDOW_HEIGHT*2);
-
- doubled[i] = !doubled[i];
- }
- }
- }
- }
-
- /* This program has an infinite loop above so a return statement would
- * just cause compiler warnings.
- */
-}
-
diff --git a/src/wm-tester/test-resizing.c b/src/wm-tester/test-resizing.c
deleted file mode 100644
index f9481004..00000000
--- a/src/wm-tester/test-resizing.c
+++ /dev/null
@@ -1,257 +0,0 @@
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <stdlib.h>
-#include <glib.h>
-
-static void
-calc_rects (XRectangle *rects, int width, int height)
-{
- int w = (width - 21) / 3;
- int h = (height - 21) / 3;
- int i;
-
- i = 0;
- while (i < 9)
- {
- rects[i].width = w;
- rects[i].height = h;
- ++i;
- }
-
- /* NW */
- rects[0].x = 0;
- rects[0].y = 0;
-
- /* N */
- rects[1].x = width / 2 - w / 2;
- rects[1].y = 0;
-
- /* NE */
- rects[2].x = width - w;
- rects[2].y = 0;
-
- /* E */
- rects[3].x = width - w;
- rects[3].y = height / 2 - h / 2;
-
- /* SE */
- rects[4].x = width - w;
- rects[4].y = height - h;
-
- /* S */
- rects[5].x = width / 2 - w / 2;
- rects[5].y = height - h;
-
- /* SW */
- rects[6].x = 0;
- rects[6].y = height - h;
-
- /* W */
- rects[7].x = 0;
- rects[7].y = height / 2 - h / 2;
-
- /* Center */
- rects[8].x = width / 2 - w / 2;
- rects[8].y = height / 2 - h / 2;
-}
-
-static Bool
-all_events (Display *display,
- XEvent *event,
- XPointer arg)
-{
- return True;
-}
-
-static void
-get_size (Display *d, Drawable draw,
- int *xp, int *yp, int *widthp, int *heightp)
-{
- int x, y;
- unsigned int width=0, height=0, border=0, depth=0;
- Window root;
-
- XGetGeometry (d, draw, &root, &x, &y, &width, &height, &border, &depth);
-
- if (xp)
- *xp = x;
- if (yp)
- *yp = y;
- if (widthp)
- *widthp = width;
- if (*heightp)
- *heightp = height;
-}
-
-int
-main (int argc, char **argv)
-{
- Display *d;
- Window w, cw;
- XSizeHints hints;
- int screen;
- XEvent ev;
- int x, y, width, height;
- Pixmap pix;
- GC gc;
- XGCValues gc_vals;
- XSetWindowAttributes set_attrs;
- XWindowChanges changes;
- XRectangle rects[9];
- gboolean redraw_pending;
- unsigned int mask;
-
- d = XOpenDisplay (NULL);
-
- screen = DefaultScreen (d);
-
- /* Print some debug spew to show how StaticGravity works */
- w = XCreateSimpleWindow (d, RootWindow (d, screen),
- 0, 0, 100, 100, 0,
- WhitePixel (d, screen),
- WhitePixel (d, screen));
- cw = XCreateSimpleWindow (d, w,
- 0, 0, 100, 100, 0,
- WhitePixel (d, screen),
- WhitePixel (d, screen));
- set_attrs.win_gravity = StaticGravity;
-
- XChangeWindowAttributes (d, cw,
- CWWinGravity,
- &set_attrs);
-
- get_size (d, w, &x, &y, &width, &height);
-
- g_print ("Parent is %d,%d %d x %d before configuring parent\n",
- x, y, width, height);
-
- get_size (d, cw, &x, &y, &width, &height);
-
- g_print ("Child is %d,%d %d x %d before configuring parent\n",
- x, y, width, height);
-
- changes.x = 10;
- changes.y = 10;
- changes.width = 110;
- changes.height = 110;
- /* last mask wins */
- mask = CWX | CWY;
- mask = CWWidth | CWHeight;
- mask = CWX | CWY | CWWidth | CWHeight;
-
- XConfigureWindow (d, w, mask, &changes);
- XSync (d, False);
-
- get_size (d, w, &x, &y, &width, &height);
-
- g_print ("Parent is %d,%d %d x %d after configuring parent\n",
- x, y, width, height);
-
- get_size (d, cw, &x, &y, &width, &height);
-
- g_print ("Child is %d,%d %d x %d after configuring parent\n",
- x, y, width, height);
-
- XDestroyWindow (d, w);
-
- /* The window that gets displayed */
-
- x = 20;
- y = 20;
- width = 100;
- height = 100;
-
- calc_rects (rects, width, height);
-
- w = XCreateSimpleWindow (d, RootWindow (d, screen),
- x, y, width, height, 0,
- WhitePixel (d, screen),
- WhitePixel (d, screen));
-
- set_attrs.bit_gravity = StaticGravity;
-
- XChangeWindowAttributes (d, w,
- CWBitGravity,
- &set_attrs);
-
- XSelectInput (d, w,
- ButtonPressMask | ExposureMask | StructureNotifyMask);
-
- hints.flags = PMinSize;
-
- hints.min_width = 100;
- hints.min_height = 100;
-
- XSetWMNormalHints (d, w, &hints);
- XMapWindow (d, w);
-
- redraw_pending = FALSE;
- while (1)
- {
- XNextEvent (d, &ev);
-
- switch (ev.xany.type)
- {
- case ButtonPress:
- if (ev.xbutton.button == 3)
- {
- g_print ("Exiting on button 3 press\n");
- exit (0);
- }
- break;
-
- case ConfigureNotify:
- x = ev.xconfigure.x;
- y = ev.xconfigure.y;
- width = ev.xconfigure.width;
- height = ev.xconfigure.height;
-
- redraw_pending = TRUE;
- break;
-
- case Expose:
- redraw_pending = TRUE;
- break;
-
- default:
- break;
- }
-
- /* Primitive event compression */
- if (XCheckIfEvent (d, &ev, all_events, NULL))
- {
- XPutBackEvent (d, &ev);
- }
- else if (redraw_pending)
- {
- calc_rects (rects, width, height);
-
- pix = XCreatePixmap (d, w, width, height,
- DefaultDepth (d, screen));
-
- gc_vals.foreground = WhitePixel (d, screen);
-
- gc = XCreateGC (d, pix, GCForeground, &gc_vals);
-
- XFillRectangle (d, pix, gc, 0, 0, width, height);
-
- /* Draw rectangles at each gravity point */
- gc_vals.foreground = BlackPixel (d, screen);
- XChangeGC (d, gc, GCForeground, &gc_vals);
-
- XFillRectangles (d, pix, gc, rects, G_N_ELEMENTS (rects));
-
- XCopyArea (d, pix, w, gc, 0, 0, width, height, 0, 0);
-
- XFreePixmap (d, pix);
- XFreeGC (d, gc);
-
- redraw_pending = FALSE;
- }
- }
-
- /* This program has an infinite loop above so a return statement would
- * just cause compiler warnings.
- */
-}
-
diff --git a/src/wm-tester/test-size-hints.c b/src/wm-tester/test-size-hints.c
deleted file mode 100644
index 72f1b486..00000000
--- a/src/wm-tester/test-size-hints.c
+++ /dev/null
@@ -1,136 +0,0 @@
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <stdlib.h>
-#include <glib.h>
-
-static Bool
-all_events (Display *display,
- XEvent *event,
- XPointer arg)
-{
- return True;
-}
-
-#if 0
-static void
-get_size (Display *d, Drawable draw,
- int *xp, int *yp, int *widthp, int *heightp)
-{
- int x, y;
- unsigned int width, height, border, depth;
- Window root;
-
- XGetGeometry (d, draw, &root, &x, &y, &width, &height, &border, &depth);
-
- if (xp)
- *xp = x;
- if (yp)
- *yp = y;
- if (widthp)
- *widthp = width;
- if (*heightp)
- *heightp = height;
-}
-#endif
-
-int
-main (int argc, char **argv)
-{
- Display *d;
- Window zero_min_size;
- XSizeHints hints;
- int screen;
- XEvent ev;
- int x, y, width, height;
- Pixmap pix;
- GC gc;
- XGCValues gc_vals;
- gboolean redraw_pending;
-
- d = XOpenDisplay (NULL);
-
- screen = DefaultScreen (d);
-
- x = 0;
- y = 0;
- width = 100;
- height = 100;
-
- zero_min_size = XCreateSimpleWindow (d, RootWindow (d, screen),
- x, y, width, height, 0,
- WhitePixel (d, screen),
- WhitePixel (d, screen));
-
- XSelectInput (d, zero_min_size,
- ButtonPressMask | ExposureMask | StructureNotifyMask);
-
- hints.flags = PMinSize;
-
- hints.min_width = 0;
- hints.min_height = 0;
-
- XSetWMNormalHints (d, zero_min_size, &hints);
- XMapWindow (d, zero_min_size);
-
- redraw_pending = FALSE;
- while (1)
- {
- XNextEvent (d, &ev);
-
- switch (ev.xany.type)
- {
- case ButtonPress:
- if (ev.xbutton.button == 1)
- {
- g_print ("Exiting on button 1 press\n");
- exit (0);
- }
- break;
-
- case ConfigureNotify:
- x = ev.xconfigure.x;
- y = ev.xconfigure.y;
- width = ev.xconfigure.width;
- height = ev.xconfigure.height;
-
- redraw_pending = TRUE;
- break;
-
- case Expose:
- redraw_pending = TRUE;
- break;
-
- default:
- break;
- }
-
- /* Primitive event compression */
- if (XCheckIfEvent (d, &ev, all_events, NULL))
- {
- XPutBackEvent (d, &ev);
- }
- else if (redraw_pending)
- {
- pix = XCreatePixmap (d, zero_min_size, width, height,
- DefaultDepth (d, screen));
-
- gc_vals.foreground = WhitePixel (d, screen);
-
- gc = XCreateGC (d, pix, GCForeground, &gc_vals);
-
- XFillRectangle (d, pix, gc, 0, 0, width, height);
-
- XCopyArea (d, pix, zero_min_size, gc, 0, 0, width, height, 0, 0);
-
- XFreePixmap (d, pix);
- XFreeGC (d, gc);
-
- redraw_pending = FALSE;
- }
- }
-
- /* This program has an infinite loop above so a return statement would
- * just cause compiler warnings.
- */
-}
-